UNPKG

@canard/schema-form-ajv8-plugin

Version:

AJV 8.x validator plugin for @canard/schema-form providing JSON Schema validation with latest Draft 2020-12 and Draft 2019-09 support

73 lines (67 loc) 2.02 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), schemaPath: ajvError.schemaPath, keyword: ajvError.keyword, message: ajvError.message, details: ajvError.params, source: ajvError, }; } return result; }; const transformDataPath = (error) => { const instancePath = error.instancePath; const missingProperty = error.params?.missingProperty; const hasMissingProperty = error.keyword === 'required' && missingProperty; if (instancePath) return hasMissingProperty ? instancePath + JSON_POINTER_SEPARATOR + missingProperty : instancePath; 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, strictSchema: 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 };