UNPKG

json-schema-describes-subset

Version:

Tools for static JSON schema analysis, including functions to determine if one schema describes a subset of another or if a schema describes the empty set or to convert a schema to its disjunctive normal form (DNF).

55 lines 2.04 kB
import { Ajv2020 as Ajv } from 'ajv/dist/2020.js'; import isObject from 'lodash/isObject.js'; /** * Setting for {@link Ajv}'s options. Fixed opinionated value, that should work * for the vast majority of cases. Rounding errors should usually be smaller * than this. Setting this option in ajv will have a minor influence on * performance, but since this tool is designed for static schema analysis, this * is tolerable. * */ export const multipleOfPrecision = 7; export const multipleOfEpsilon = 10 ** -multipleOfPrecision; export function enhanceSchema(schema, definitions) { if (typeof schema === 'boolean') { return schema; } const $defs = isObject(schema.$defs) ? { ...schema.$defs } : {}; const defaultKeyBase = 'def'; const startIndex = 0; for (const definition of definitions) { let keyBase = defaultKeyBase; if (typeof definition.$id === 'string') { keyBase = definition.$id; } // eslint-disable-next-line no-constant-condition for (let i = startIndex; true; i++) { const key = i === startIndex && keyBase !== defaultKeyBase ? keyBase : `${keyBase} ${String(i)}`; if (!(key in $defs)) { $defs[key] = definition; break; } } } return { ...schema, $defs }; } export function createValidate(plugins, definitions) { return function (schema, data) { /* always create a new Ajv instance so that previous calls * don't save any schema data that might be invalid with * later calls */ const ajv = new Ajv({ strict: false, multipleOfPrecision, validateSchema: false, }); plugins.forEach((plugin) => plugin.modifyAjv(ajv)); const validationSchema = (definitions.length === 0 ? schema : enhanceSchema(schema, definitions)); return ajv.validate(validationSchema, data); }; } //# sourceMappingURL=validate.js.map