Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/three-planets-follow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'better-ajv-errors': minor
---

Add support for "unevaluatedProperties" keyword #182. Prints the same details as for the "additionalProperties" keyword.
5 changes: 5 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from './utils';
import {
AdditionalPropValidationError,
UnevaluatedPropValidationError,
RequiredValidationError,
EnumValidationError,
DefaultValidationError,
Expand Down Expand Up @@ -140,6 +141,10 @@ export function createErrorInstances(root, options) {
return ret.concat(
new AdditionalPropValidationError(error, options)
);
case 'unevaluatedProperties':
return ret.concat(
new UnevaluatedPropValidationError(error, options)
);
case 'required':
return ret.concat(new RequiredValidationError(error, options));
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"foo": "bar",
"bar": 2,
"baz": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "number" }
},
"required": [
"foo",
"bar"
],
"unevaluatedProperties": false
}
19 changes: 19 additions & 0 deletions src/validation-errors/__tests__/__snapshots__/main.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,22 @@ exports[`Main > should support js output format for required errors 1`] = `
},
]
`;

exports[`Main > should support js output format for unevaluatedProperties errors 1`] = `
[
{
"end": {
"column": 27,
"line": 1,
"offset": 26,
},
"error": " Property baz is not expected to be here",
"path": "",
"start": {
"column": 22,
"line": 1,
"offset": 21,
},
},
]
`;
18 changes: 18 additions & 0 deletions src/validation-errors/__tests__/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, it, expect } from 'vitest';
import Ajv from 'ajv';
import Ajv2020 from 'ajv/dist/2020';
import betterAjvErrors from '../../';
import { getSchemaAndData } from '../../test-helpers';

Expand Down Expand Up @@ -49,6 +50,23 @@ describe('Main', () => {
expect(res).toMatchSnapshot();
});

it('should support js output format for unevaluatedProperties errors', async () => {
const [schema, data] = await getSchemaAndData(
'unevaluatedProperties',
__dirname
);

const ajv = new Ajv2020();
const validate = ajv.compile(schema);
const valid = validate(data);
expect(valid).toBeFalsy();

const res = betterAjvErrors(schema, data, validate.errors, {
format: 'js',
});
expect(res).toMatchSnapshot();
});

it('should support js output format for enum errors', async () => {
const [schema, data] = await getSchemaAndData('enum', __dirname);

Expand Down
1 change: 1 addition & 0 deletions src/validation-errors/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as RequiredValidationError } from './required';
export { default as AdditionalPropValidationError } from './additional-prop';
export { default as UnevaluatedPropValidationError } from './unevaluated-prop';
export { default as EnumValidationError } from './enum';
export { default as DefaultValidationError } from './default';
33 changes: 33 additions & 0 deletions src/validation-errors/unevaluated-prop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import chalk from 'chalk';
import BaseValidationError from './base';

export default class UnevaluatedPropValidationError extends BaseValidationError {
constructor(...args) {
super(...args);
this.options.isIdentifierLocation = true;
}

print() {
const { message, params } = this.options;
const output = [chalk`{red {bold UNEVALUATED PROPERTY} ${message}}\n`];

return output.concat(
this.getCodeFrame(
chalk`😲 {magentaBright ${params.unevaluatedProperty}} is not expected to be here!`,
`${this.instancePath}/${params.unevaluatedProperty}`
)
);
}

getError() {
const { params } = this.options;

return {
...this.getLocation(`${this.instancePath}/${params.unevaluatedProperty}`),
error: `${this.getDecoratedPath()} Property ${
params.unevaluatedProperty
} is not expected to be here`,
path: this.instancePath,
};
}
}