@canard/schema-form-ajv6-plugin
Version:
AJV 6.x validator plugin for @canard/schema-form providing JSON Schema validation with legacy Draft-04, Draft-06, and Draft-07 support
75 lines (68 loc) • 2.15 kB
JavaScript
;
const Ajv = require('ajv');
const pathCommon = require('@winglet/json/path-common');
const JSON_POINTER_SEPARATOR = '/';
const transformDataPath = (errors) => {
const result = new Array(errors.length);
for (let i = 0; i < errors.length; i++) {
const ajvError = errors[i];
const dataPath = ajvError.dataPath || '';
let convertedDataPath = pathCommon.convertJsonPathToPointer(dataPath);
if (ajvError.keyword === 'required' &&
ajvError.params &&
'missingProperty' in ajvError.params) {
const missingProperty = ajvError.params.missingProperty;
if (convertedDataPath === JSON_POINTER_SEPARATOR) {
convertedDataPath = JSON_POINTER_SEPARATOR + missingProperty;
}
else {
convertedDataPath =
convertedDataPath + JSON_POINTER_SEPARATOR + missingProperty;
}
}
result[i] = {
dataPath: convertedDataPath,
keyword: ajvError.keyword,
message: ajvError.message,
details: ajvError.params,
source: ajvError,
};
}
return result;
};
const createValidatorFactory = (ajv) => (jsonSchema) => {
const validate = ajv.compile({
...jsonSchema,
$async: true,
});
return async (data) => {
try {
await validate(data);
return null;
}
catch (thrown) {
if (Array.isArray(thrown?.errors))
return transformDataPath(thrown.errors);
throw thrown;
}
};
};
const defaultSettings = {
allErrors: true,
verbose: true,
format: false,
};
let ajvInstance = null;
const ajvValidatorPlugin = {
bind: (instance) => (ajvInstance = instance),
compile: (jsonSchema) => {
if (!ajvInstance)
ajvInstance = new Ajv(defaultSettings);
return createValidatorFactory(ajvInstance)(jsonSchema);
},
};
const plugin = {
validator: ajvValidatorPlugin,
};
exports.createValidatorFactory = createValidatorFactory;
exports.plugin = plugin;