ajv
ajv copied to clipboard
Do not short-circuit anyOf with allErrors option
Problem
Allow some advanced logic for data validation based on annotation keywords etc.
Solution
Do not short-circuit anyOf keyword with allErrors: true option Provide a separate option to override this behaviour (e.g. shortCircuit) that would override the default behaviour for allOf any anyOf.
Logic when keywords are short-circuited after the change (changed behaviour in bold):
| allErrors → shortCircuit ↓ |
false | true |
|---|---|---|
| undefined | allOf: short anyOf: short |
allOf: full anyOf: full |
| false | allOf: full anyOf: full |
allOf: full anyOf: full |
| true | allOf: short anyOf: short |
allOf: short anyOf: short |
oneOf can never short-circuit, if/then/else should always short-circuit, so they are not affected.
Why do I get errors with this code? Using anyOf or oneOf - no difference...
const Ajv = require("ajv");
ajv = new Ajv({
removeAdditional: true,
useDefaults: true,
coerceTypes: "array",
allErrors: true,
});
var schema = {
type: "object",
required: ["service", "receipt", "credentials"],
additionalProperties: false,
properties: {
service: {
type: "string",
},
receipt: {
oneOf: [
{
type: "object",
required: ["data", "productId", "os"],
additionalProperties: false,
properties: {
data: {
type: "object",
required: ["productId", "purchaseToken", "packageName"],
additionalProperties: false,
properties: {
productId: {
type: "string",
},
purchaseToken: {
type: "string",
},
packageName: {
type: "string",
},
},
},
productId: {
type: "string",
},
os: {
enum: ["android"],
},
},
},
{
type: "object",
required: ["data", "productId", "os"],
additionalProperties: false,
properties: {
data: {
type: "object",
required: ["transactionId", "receiptData"],
additionalProperties: false,
properties: {
transactionId: {
type: "string",
},
receiptData: {
type: "string",
},
},
},
productId: {
type: "string",
},
os: {
enum: ["ios", "tvos"],
},
},
},
],
},
credentials: {
type: "object",
required: ["username", "password"],
additionalProperties: false,
properties: {
username: {
type: "string",
minLength: 3,
},
password: {
type: "string",
minLength: 1,
},
},
},
},
};
var data = {
service: "service name",
receipt: {
productId: "asd",
os: "ios",
data: {
transactionId: "asd",
receiptData: "asd",
},
},
credentials: {
username: "[email protected]",
password: "donuts",
},
};
var validate = ajv.compile(schema);
// console.log(validate.source.validateCode)
console.log(validate(data));
console.log(validate.errors);
I'm using the allErrors: true because I want to get all errors not just the first one. But (in my opinion) the code above should not have any errors ...
can this be setup to report all errors if schema fails but no errors and succeed with anyOf/oneOf?