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).

91 lines 2.88 kB
import isString from 'lodash/isString.js'; import { AllOfSchema, AtomicSchemaObject, NotSchema, } from '../atomic-schema/index.js'; import {} from '../plugin/index.js'; import { allJSONSchemaTypes, filterJSONSchemaTypes, isJSONSchemaType, getOtherJSONSchemaTypes, } from '../json-schema-type/index.js'; export class MultipleOfAtomicSchema extends AtomicSchemaObject { multipleOf; constructor(multipleOf) { super(); this.multipleOf = multipleOf; } negate() { return new AllOfSchema([ new NotSchema(this), /* actually redundant, but makes checking for contradictions easier */ new TypeAtomicSchema('number'), ]); } toJSONSchema() { return { multipleOf: this.multipleOf }; } } export class TypeAtomicSchema extends AtomicSchemaObject { type; constructor(type) { super(); if (Array.isArray(type)) { const validTypes = filterJSONSchemaTypes(type); if (validTypes.length === 0) { /* invalid input => no restriction */ this.type = allJSONSchemaTypes; } else { this.type = validTypes; } } else if (isJSONSchemaType(type)) { this.type = [type]; } else { /* invalid input => no restriction */ this.type = allJSONSchemaTypes; } } negate() { const otherTypes = getOtherJSONSchemaTypes(this.type); if (otherTypes.length === 0) { return false; } return new TypeAtomicSchema(otherTypes); } toJSONSchema() { return { type: [...this.type] }; } } export function getTypeArray(schema) { if (Array.isArray(schema.type)) { return schema.type.filter(isString); } else if (typeof schema.type === 'string') { return [schema.type]; } else { return []; } } export function typeArrayToLogicalCombination(typeArray) { if (typeArray.length === 0) { return true; } if (typeArray.includes('integer')) { return new AllOfSchema([ new TypeAtomicSchema([...typeArray, 'number']), new MultipleOfAtomicSchema(1), ]); } return new TypeAtomicSchema(typeArray); } export const typeExtraction = { extract: ({ schema }) => { const typeArray = getTypeArray(schema); /* This feature used to be a separate plugin, and it doesn't feel right to * always include it, but since this project currently uses ajv under the * hood, it should behave the same way, even if `nullable` is non standard. */ if (schema.nullable === true) { typeArray.push('null'); } return typeArrayToLogicalCombination(typeArray); }, }; //# sourceMappingURL=type.js.map