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
JavaScript
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