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).
65 lines • 2.93 kB
JavaScript
import { ConstAtomicSchema } from '../../const.js';
import { TypeAtomicSchema } from '../../type.js';
import { PatternAtomicSchema } from '../../string.js';
import { groupLogicLiteralConjuncts } from '../../../dnf/group-logic-literal-conjuncts.js';
const validAtomicSchemaConstructors = [
TypeAtomicSchema,
PatternAtomicSchema,
];
/**
* Returns constant values and patterns that will satisfy the provided string
* schema. Returns null if the schema if such constant values or patterns could
* not be found.
*
*/
export function retrieveStringSchemaConstsAndPatterns({ schema, options, splitToRawDNF, }) {
return retrieveStringSchemaConstsAndPatternsFromRawDNF(splitToRawDNF(schema, options), options);
}
export function retrieveStringSchemaConstsAndPatternsFromRawDNF(dnf, options) {
const consts = new Set();
const patterns = new Set();
const validate = options.validate;
for (const conjunction of dnf.anyOf) {
const { booleanSchema, atomicSchemasByConstructor, negatedAtomicSchemasByConstructor, types, } = groupLogicLiteralConjuncts(conjunction.allOf);
if (booleanSchema !== undefined) {
return { isStringWithConstsOrPatterns: false };
}
const constSchema = atomicSchemasByConstructor.get(ConstAtomicSchema)[0];
if (constSchema !== undefined) {
if (validate(conjunction.toJSONSchema(), constSchema.const) &&
typeof constSchema.const === 'string') {
consts.add(constSchema.const);
continue;
}
else {
return { isStringWithConstsOrPatterns: false };
}
}
if ([...negatedAtomicSchemasByConstructor.getConstructors()].length > 0) {
return { isStringWithConstsOrPatterns: false };
}
if ([...atomicSchemasByConstructor.getConstructors()].some((constructor) => !validAtomicSchemaConstructors.includes(constructor))) {
return { isStringWithConstsOrPatterns: false };
}
if (types.length !== 1 || types[0] !== 'string') {
return { isStringWithConstsOrPatterns: false };
}
const patternSchemas = atomicSchemasByConstructor.get(PatternAtomicSchema);
const patternSchema = patternSchemas[0];
if (patternSchema && patternSchemas.length === 1) {
patterns.add(patternSchema.pattern);
continue;
}
return { isStringWithConstsOrPatterns: false };
}
if (consts.size === 0 && patterns.size === 0) {
return { isStringWithConstsOrPatterns: false };
}
const patternsArray = [...patterns];
return {
isStringWithConstsOrPatterns: true,
consts: [...consts].filter((constValue) => patternsArray.every((pattern) => !validate({ pattern }, constValue))),
patterns: patternsArray,
};
}
//# sourceMappingURL=retrieve-string-schema-consts-and-patterns.js.map