UNPKG

@canard/schema-form-ajv7-plugin

Version:

AJV 7.x validator plugin for @canard/schema-form providing JSON Schema validation with Draft-07 and Draft 2019-09 support

72 lines (66 loc) 1.95 kB
import Ajv from 'ajv'; const JSON_POINTER_SEPARATOR = '/'; const transformErrors = (errors) => { if (!Array.isArray(errors)) return []; const result = new Array(errors.length); for (let i = 0, l = errors.length; i < l; i++) { const ajvError = errors[i]; result[i] = { dataPath: transformDataPath(ajvError), keyword: ajvError.keyword, message: ajvError.message, details: ajvError.params, source: ajvError, }; } return result; }; const transformDataPath = (error) => { const dataPath = error.dataPath; const missingProperty = error.params?.missingProperty; const hasMissingProperty = error.keyword === 'required' && missingProperty; if (dataPath) return hasMissingProperty ? dataPath + JSON_POINTER_SEPARATOR + missingProperty : dataPath; else return hasMissingProperty ? JSON_POINTER_SEPARATOR + missingProperty : JSON_POINTER_SEPARATOR; }; 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 transformErrors(thrown.errors); throw thrown; } }; }; const defaultSettings = { allErrors: true, strict: false, validateFormats: 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, }; export { createValidatorFactory, plugin };