Demonstrates nested allOf with AJV:
node allOf.js
node nested.js
A non-zero exit code indicates a problem.
| node_modules |
| const Ajv = require("ajv/dist/2019"); | |
| const assert = require("assert") | |
| const validateJson = (schema, json) => { | |
| const ajv = new Ajv(); | |
| ajv.validate(schema, json); | |
| return ajv.errors || []; | |
| }; | |
| const schema = { | |
| type: "object", | |
| unevaluatedProperties: false, | |
| allOf: [ | |
| { | |
| type: "object", | |
| properties: { | |
| foo: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| { | |
| type: "object", | |
| properties: { | |
| bar: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| ], | |
| }; | |
| const validPayload = { | |
| foo: "bar", | |
| bar: "baz", | |
| }; | |
| const invalidPayload = { | |
| ...validPayload, | |
| baz: "qux" | |
| }; | |
| var errors = validateJson(schema, validPayload); | |
| console.log("valid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length === 0, "valid payload should not have errors"); | |
| console.log(""); | |
| var errors = validateJson(schema, invalidPayload); | |
| console.log("invalid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length === 1, "invalid payload should have errors"); | |
| console.log("✅ PASSED!"); |
| const Ajv = require("ajv/dist/2019"); | |
| const assert = require("assert") | |
| const validateJson = (schema, json) => { | |
| const ajv = new Ajv() | |
| ajv.validate(schema, json); | |
| return ajv.errors || []; | |
| }; | |
| const schema = { | |
| type: "object", | |
| unevaluatedProperties: false, | |
| allOf: [ | |
| { | |
| type: "object", | |
| properties: { | |
| foo: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| { | |
| unevaluatedProperties: false, // <- need to comment this out for the tests to pass | |
| allOf: [ | |
| { | |
| type: "object", | |
| properties: { | |
| bar: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| { | |
| type: "object", | |
| properties: { | |
| baz: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| ], | |
| }, | |
| ], | |
| }; | |
| const validPayload = { | |
| foo: "bar", | |
| bar: "baz", | |
| baz: "qux" | |
| }; | |
| const invalidPayload = { | |
| ...validPayload, | |
| qux: "quux" | |
| }; | |
| var errors = validateJson(schema, validPayload); | |
| console.log("valid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length === 0, "valid payload should not have errors"); | |
| console.log(""); | |
| var errors = validateJson(schema, invalidPayload); | |
| console.log("invalid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length === 1, "invalid payload should have errors"); | |
| console.log("✅ PASSED!"); |
| const Ajv = require("ajv/dist/2019"); | |
| const assert = require("assert"); | |
| const validateJson = (schema, json) => { | |
| const ajv = new Ajv() | |
| ajv.validate(schema, json); | |
| return ajv.errors || []; | |
| }; | |
| const schema = { | |
| type: "object", | |
| unevaluatedProperties: false, | |
| allOf: [ | |
| { | |
| type: "object", | |
| properties: { | |
| foo: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| { | |
| type: "object", | |
| properties: { | |
| bar: { | |
| unevaluatedProperties: false, | |
| allOf: [ | |
| { | |
| type: "object", | |
| properties: { | |
| baz: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| { | |
| type: "object", | |
| properties: { | |
| bat: { | |
| type: "string", | |
| }, | |
| }, | |
| }, | |
| ], | |
| }, | |
| }, | |
| }, | |
| ], | |
| }; | |
| const validPayload = { | |
| foo: "bar", | |
| bar: { | |
| baz: "bat", | |
| bat: "quz", | |
| }, | |
| }; | |
| const invalidPayload = { | |
| foo: "bar", | |
| bar: { | |
| baz: "bat", | |
| bat: "quz", | |
| qux: "quux", | |
| }, | |
| qux: "quux", | |
| }; | |
| var errors = validateJson(schema, validPayload); | |
| console.log("valid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length === 0, "valid payload should not have errors"); | |
| console.log(""); | |
| var errors = validateJson(schema, invalidPayload); | |
| console.log("invalid payload errors:"); | |
| console.dir(errors, { depth: 5 }); | |
| assert(errors.length > 0, "invalid payload should have errors"); | |
| console.log("✅ PASSED!"); |
| { | |
| "name": "allof-repro", | |
| "version": "1.0.0", | |
| "lockfileVersion": 3, | |
| "requires": true, | |
| "packages": { | |
| "": { | |
| "name": "allof-repro", | |
| "version": "1.0.0", | |
| "license": "ISC", | |
| "dependencies": { | |
| "ajv": "^8.12.0" | |
| } | |
| }, | |
| "node_modules/ajv": { | |
| "version": "8.12.0", | |
| "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", | |
| "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", | |
| "dependencies": { | |
| "fast-deep-equal": "^3.1.1", | |
| "json-schema-traverse": "^1.0.0", | |
| "require-from-string": "^2.0.2", | |
| "uri-js": "^4.2.2" | |
| }, | |
| "funding": { | |
| "type": "github", | |
| "url": "https://github.com/sponsors/epoberezkin" | |
| } | |
| }, | |
| "node_modules/fast-deep-equal": { | |
| "version": "3.1.3", | |
| "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", | |
| "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" | |
| }, | |
| "node_modules/json-schema-traverse": { | |
| "version": "1.0.0", | |
| "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", | |
| "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" | |
| }, | |
| "node_modules/punycode": { | |
| "version": "2.3.0", | |
| "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", | |
| "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", | |
| "engines": { | |
| "node": ">=6" | |
| } | |
| }, | |
| "node_modules/require-from-string": { | |
| "version": "2.0.2", | |
| "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", | |
| "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", | |
| "engines": { | |
| "node": ">=0.10.0" | |
| } | |
| }, | |
| "node_modules/uri-js": { | |
| "version": "4.4.1", | |
| "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", | |
| "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", | |
| "dependencies": { | |
| "punycode": "^2.1.0" | |
| } | |
| } | |
| } | |
| } |
| { | |
| "name": "allof-repro", | |
| "version": "1.0.0", | |
| "description": "Demonstrates nested `allOf` issue in AVJ.", | |
| "main": "index.js", | |
| "scripts": { | |
| "test": "echo \"Error: no test specified\" && exit 1" | |
| }, | |
| "keywords": [], | |
| "author": "", | |
| "license": "ISC", | |
| "dependencies": { | |
| "ajv": "^8.12.0" | |
| } | |
| } |