@jirutka/ajv-cli
Version:
CLI for Ajv JSON Schema Validator with human-friendly error messages
50 lines • 1.98 kB
JavaScript
// This is a workaround for https://github.com/ajv-validator/ajv/issues/512
import _traverse from '@json-schema-tools/traverse';
import { deepClone } from './utils.js';
// Workaround to make it work both directly and in bundle.
const traverse = 'default' in _traverse ? _traverse.default : _traverse;
const SchemaPathSymbol = Symbol('schemaPath');
/**
* Adds {@link SchemaPathSymbol} property with JSON Path to each schema object
* in the given `jsonSchema`. This function **mutates** the given `jsonSchema`!
*/
export function injectPathToSchemas(jsonSchema, prefix) {
prefix ??= `${jsonSchema.$id || ''}#`;
traverse(jsonSchema, (schema, _isCycle, path) => {
if (!('$ref' in schema) && !(SchemaPathSymbol in schema)) {
schema[SchemaPathSymbol] = `${prefix}${jsonPathToPointer(path)}`;
}
return schema;
}, { mutable: true });
if (typeof jsonSchema.$defs === 'object') {
for (const [key, schema] of Object.entries(jsonSchema.$defs ?? jsonSchema.definitions)) {
injectPathToSchemas(schema, `${prefix}/$defs/${key}`);
}
}
}
/** @internal */
export function rewriteSchemaPathInErrors(errors, verbose) {
return errors.map(error => {
// The main purpose of this is to remove SchemaPathSymbol key.
const copy = deepClone(error);
if (error.parentSchema && SchemaPathSymbol in error.parentSchema) {
copy.schemaPath = `${error.parentSchema[SchemaPathSymbol]}/${error.keyword}`;
if (!verbose) {
delete copy.parentSchema;
delete copy.schema;
delete copy.data;
}
}
return copy;
});
}
function jsonPathToPointer(jsonPath) {
if (jsonPath.startsWith('$')) {
jsonPath = jsonPath.slice(1);
}
return jsonPath
.split('.')
.map(s => s.replaceAll(/\[(\d+)\]/g, '/$1'))
.join('/');
}
//# sourceMappingURL=ajv-schema-path-workaround.js.map