{"id":17797,"library":"metalman-schema","title":"metalman-schema","description":"metalman-schema is a JSON schema validation middleware specifically designed for the `metalman` module. It leverages the `ajv` library for robust JSON schema validation. The current stable version is 4.0.2, released in November 2023, indicating an active but not rapid release cadence, with previous major updates in 2021. This library differentiates itself by providing a `metalman`-compatible middleware, allowing schema definitions to be integrated directly into `metalman` commands for streamlined request validation. It acts as a factory function that returns the actual middleware, providing flexibility to configure the underlying `ajv` instance.","status":"active","version":"4.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/marcbachmann/metalman-schema","tags":["javascript","metalman","middleware","json","schema","json schema","validation","validate"],"install":[{"cmd":"npm install metalman-schema","lang":"bash","label":"npm"},{"cmd":"yarn add metalman-schema","lang":"bash","label":"yarn"},{"cmd":"pnpm add metalman-schema","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core middleware framework this package is built for. Requires `metalman@v3` or higher since `metalman-schema@v3.0.0`.","package":"metalman","optional":false},{"reason":"Underlying JSON schema validator. Requires `ajv@v7` or higher since `metalman-schema@v4.0.0`.","package":"ajv","optional":false},{"reason":"Provides format validation for `ajv` schemas. Automatically added by default if no custom `AJV` instance is passed to the factory since `metalman-schema@v4.0.1`.","package":"ajv-formats","optional":true}],"imports":[{"note":"The default export is a factory function that creates the validation middleware. The example in the README is slightly misleading, implying `metalman-schema` directly exports the middleware rather than a factory for it.","wrong":"import { createSchemaMiddleware } from 'metalman-schema';","symbol":"createSchemaMiddleware","correct":"import createSchemaMiddleware from 'metalman-schema';"},{"note":"For CommonJS, the default export is the factory function. While the source uses a named `factory` function internally, `module.exports` is set directly to this function, making it the default export.","wrong":"const { factory } = require('metalman-schema');","symbol":"createSchemaMiddleware","correct":"const createSchemaMiddleware = require('metalman-schema');"},{"note":"The actual middleware function used by `metalman` is returned by calling the `createSchemaMiddleware` factory function. This allows for optional configuration of the underlying AJV instance.","wrong":"const validate = require('metalman-schema'); // This gets the factory, not the middleware itself","symbol":"middleware","correct":"const validate = createSchemaMiddleware();"}],"quickstart":{"code":"import metalman from 'metalman';\nimport createSchemaMiddleware from 'metalman-schema';\n\n// Create the validation middleware using the factory\n// You can pass ajvOptions or a custom ajv instance here: createSchemaMiddleware({ ajvOptions: { allErrors: true } })\nconst validate = createSchemaMiddleware();\n\n// Define a metalman command with the validation middleware\nconst commandFactory = metalman([validate]);\n\nconst validateUser = commandFactory({\n  schema: {\n    type: 'object',\n    required: ['name', 'age'],\n    additionalProperties: false,\n    properties: {\n      name: { type: 'string', minLength: 1 },\n      age: { type: 'number', minimum: 18 }\n    }\n  }\n});\n\n// Valid case\nvalidateUser({ name: 'Alice', age: 30 }, (err) => {\n  if (err) {\n    console.error('Validation failed for Alice:', err.message);\n  } else {\n    console.log('Validation successful for Alice.');\n  }\n});\n\n// Invalid case (age too low)\nvalidateUser({ name: 'Bob', age: 16 }, (err) => {\n  if (err) {\n    console.error('Validation failed for Bob:', err.name, '-', err.message);\n  } else {\n    console.log('Validation successful for Bob.');\n  }\n});\n\n// Invalid case (missing required field)\nvalidateUser({ age: 25 }, (err) => {\n  if (err) {\n    console.error('Validation failed (missing name):', err.name, '-', err.message);\n  } else {\n    console.log('Validation successful (missing name).');\n  }\n});","lang":"javascript","description":"This quickstart demonstrates how to set up `metalman-schema` as a middleware with `metalman` to validate incoming command data against a JSON schema, showing both valid and invalid scenarios."},"warnings":[{"fix":"Review AJV v7 release notes for schema migration guidelines, especially regarding `$id` vs `id` and format validation changes (now requiring `ajv-formats`). Update schemas to comply with JSON Schema draft-06 or later.","message":"Version 4.0.0 introduced a breaking change by upgrading the underlying JSON schema validator to AJV v7. This might break existing schemas, particularly those using older draft specifications (like draft-04, which is no longer supported by AJV v7) or relying on removed keywords.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure your project uses `metalman@v3` or newer and a Node.js version compatible with ES2015+ features. Update `require` statements to `const` for improved code style.","message":"Version 3.0.0 dropped support for `metalman@v2` and older Node.js versions, requiring an upgrade to `metalman@v3`. This version also mandates ES2015 features (e.g., `const` declarations).","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"If type coercion is undesirable, you may need to configure the AJV instance passed to `createSchemaMiddleware` to disable this behavior (e.g., `{ coerceTypes: false }`). Refer to AJV documentation for exact options.","message":"Since version 3.0.0, the middleware automatically coerces types by default. This changes validation behavior, as values might be converted (e.g., '123' to 123) instead of failing validation for incorrect types.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"If you need to control format validation explicitly, pass a custom `AJV` instance to the `createSchemaMiddleware` factory and configure `ajv-formats` (or omit it) as per your requirements.","message":"Since version 4.0.1, `ajv-formats` is automatically added by default if no custom `AJV` instance is passed to `createSchemaMiddleware`. If you were relying on a minimal AJV setup without format validation, this might introduce new validation rules for properties like `format: 'email'`.","severity":"gotcha","affected_versions":">=4.0.1"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Inspect `err.errors` (if available) or `err.message` for details on which part of the input failed validation. Adjust the input data or refine the JSON schema definition.","cause":"Input data to the metalman command does not conform to the defined JSON schema.","error":"err.name equals 'ValidationError'"},{"fix":"Ensure that the `metalman` command function, when called, receives an options object that includes a `schema` property with a valid JSON schema definition, e.g., `commandFactory({ schema: { type: 'object', ... } })`.","cause":"The `metalman-schema` middleware expects the schema to be present on the `command` object (e.g., `command.schema`). This error occurs if the `schema` property is missing from the command options.","error":"TypeError: Cannot read properties of undefined (reading 'schema')"},{"fix":"For `ajv` v7+, use `const Ajv = require('ajv').default;` for CommonJS or `import Ajv from 'ajv';` for ESM, then instantiate with `new Ajv()`. Ensure `ajv` is correctly installed.","cause":"This usually indicates an incorrect import or version mismatch of `ajv`, especially after the v7 upgrade where `new Ajv()` syntax became mandatory and `require('ajv')` directly returns the constructor (or `require('ajv').default` for some setups).","error":"Ajv is not a constructor"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}