UNPKG

@samchon/openapi

Version:

OpenAPI definitions and converters for 'typia' and 'nestia'.

252 lines (251 loc) 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LlmTypeCheckerV3 = void 0; const OpenApiTypeCheckerBase_1 = require("./internal/OpenApiTypeCheckerBase"); /** * Type checker for LLM type schema. * * `LlmSchemaTypeChecker` is a type checker of {@link ILlmSchemaV3}. * * @author Samchon */ var LlmTypeCheckerV3; (function (LlmTypeCheckerV3) { /* ----------------------------------------------------------- OPERATORS ----------------------------------------------------------- */ /** * Visit every nested schemas. * * Visit every nested schemas of the target, and apply the `props.closure` function. * * Here is the list of occurring nested visitings: * * - {@link ILlmSchemaV3.IOneOf.oneOf} * - {@link ILlmSchemaV3.IObject.additionalProperties} * - {@link ILlmSchemaV3.IArray.items} * * @param props Properties for visiting */ LlmTypeCheckerV3.visit = (props) => { var _a; const accessor = (_a = props.accessor) !== null && _a !== void 0 ? _a : "$input.schema"; props.closure(props.schema, accessor); if (LlmTypeCheckerV3.isOneOf(props.schema)) props.schema.oneOf.forEach((s, i) => LlmTypeCheckerV3.visit({ closure: props.closure, schema: s, accessor: `${accessor}.oneOf[${i}]`, })); else if (LlmTypeCheckerV3.isObject(props.schema)) { for (const [k, s] of Object.entries(props.schema.properties)) LlmTypeCheckerV3.visit({ closure: props.closure, schema: s, accessor: `${accessor}.properties[${JSON.stringify(k)}]`, }); if (typeof props.schema.additionalProperties === "object" && props.schema.additionalProperties !== null) LlmTypeCheckerV3.visit({ closure: props.closure, schema: props.schema.additionalProperties, accessor: `${accessor}.additionalProperties`, }); } else if (LlmTypeCheckerV3.isArray(props.schema)) LlmTypeCheckerV3.visit({ closure: props.closure, schema: props.schema.items, accessor: `${accessor}.items`, }); }; LlmTypeCheckerV3.covers = (x, y) => { const alpha = flatSchema(x); const beta = flatSchema(y); if (alpha.some((x) => LlmTypeCheckerV3.isUnknown(x))) return true; else if (beta.some((x) => LlmTypeCheckerV3.isUnknown(x))) return false; return beta.every((b) => alpha.some((a) => { // CHECK EQUALITY if (a === b) return true; else if (LlmTypeCheckerV3.isUnknown(a)) return true; else if (LlmTypeCheckerV3.isUnknown(b)) return false; else if (LlmTypeCheckerV3.isNullOnly(a)) return LlmTypeCheckerV3.isNullOnly(b); else if (LlmTypeCheckerV3.isNullOnly(b)) return LlmTypeCheckerV3.isNullable(a); else if (LlmTypeCheckerV3.isNullable(a) && !LlmTypeCheckerV3.isNullable(b)) return false; // ATOMIC CASE else if (LlmTypeCheckerV3.isBoolean(a)) return LlmTypeCheckerV3.isBoolean(b) && coverBoolean(a, b); else if (LlmTypeCheckerV3.isInteger(a)) return LlmTypeCheckerV3.isInteger(b) && coverInteger(a, b); else if (LlmTypeCheckerV3.isNumber(a)) return (LlmTypeCheckerV3.isNumber(b) || LlmTypeCheckerV3.isInteger(b)) && coverNumber(a, b); else if (LlmTypeCheckerV3.isString(a)) return LlmTypeCheckerV3.isString(b) && covertString(a, b); // INSTANCE CASE else if (LlmTypeCheckerV3.isArray(a)) return LlmTypeCheckerV3.isArray(b) && coverArray(a, b); else if (LlmTypeCheckerV3.isObject(a)) return LlmTypeCheckerV3.isObject(b) && coverObject(a, b); else if (LlmTypeCheckerV3.isOneOf(a)) return false; })); }; /** * @internal */ const coverBoolean = (x, y) => x.enum === undefined || (y.enum !== undefined && x.enum.every((v) => y.enum.includes(v))); /** * @internal */ const coverInteger = (x, y) => { if (x.enum !== undefined) return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v)); return x.type === y.type && OpenApiTypeCheckerBase_1.OpenApiTypeCheckerBase.coverNumericRange(x, y); }; /** * @internal */ const coverNumber = (x, y) => { if (x.enum !== undefined) return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v)); return ((x.type === y.type || (x.type === "number" && y.type === "integer")) && OpenApiTypeCheckerBase_1.OpenApiTypeCheckerBase.coverNumericRange(x, y)); }; /** * @internal */ const covertString = (x, y) => { if (x.enum !== undefined) return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v)); return [ x.type === y.type, x.format === undefined || (y.format !== undefined && coverFormat(x.format, y.format)), x.pattern === undefined || x.pattern === y.pattern, x.minLength === undefined || (y.minLength !== undefined && x.minLength <= y.minLength), x.maxLength === undefined || (y.maxLength !== undefined && x.maxLength >= y.maxLength), ].every((v) => v); }; const coverFormat = (x, y) => x === y || (x === "idn-email" && y === "email") || (x === "idn-hostname" && y === "hostname") || (["uri", "iri"].includes(x) && y === "url") || (x === "iri" && y === "uri") || (x === "iri-reference" && y === "uri-reference"); /** * @internal */ const coverArray = (x, y) => LlmTypeCheckerV3.covers(x.items, y.items); const coverObject = (x, y) => { var _a; if (!x.additionalProperties && !!y.additionalProperties) return false; else if ((!!x.additionalProperties && !!y.additionalProperties && typeof x.additionalProperties === "object" && y.additionalProperties === true) || (typeof x.additionalProperties === "object" && typeof y.additionalProperties === "object" && !LlmTypeCheckerV3.covers(x.additionalProperties, y.additionalProperties))) return false; return Object.entries((_a = y.properties) !== null && _a !== void 0 ? _a : {}).every(([key, b]) => { var _a, _b, _c, _d, _e; const a = (_a = x.properties) === null || _a === void 0 ? void 0 : _a[key]; if (a === undefined) return false; else if (((_c = (_b = x.required) === null || _b === void 0 ? void 0 : _b.includes(key)) !== null && _c !== void 0 ? _c : false) === true && ((_e = (_d = y.required) === null || _d === void 0 ? void 0 : _d.includes(key)) !== null && _e !== void 0 ? _e : false) === false) return false; return LlmTypeCheckerV3.covers(a, b); }); }; const flatSchema = (schema) => LlmTypeCheckerV3.isOneOf(schema) ? schema.oneOf.flatMap(flatSchema) : [schema]; /* ----------------------------------------------------------- TYPE CHECKERS ----------------------------------------------------------- */ /** * Test whether the schema is an union type. * * @param schema Target schema * @returns Whether union type or not */ LlmTypeCheckerV3.isOneOf = (schema) => schema.oneOf !== undefined; /** * Test whether the schema is an object type. * * @param schema Target schema * @returns Whether object type or not */ LlmTypeCheckerV3.isObject = (schema) => schema.type === "object"; /** * Test whether the schema is an array type. * * @param schema Target schema * @returns Whether array type or not */ LlmTypeCheckerV3.isArray = (schema) => schema.type === "array"; /** * Test whether the schema is a boolean type. * * @param schema Target schema * @returns Whether boolean type or not */ LlmTypeCheckerV3.isBoolean = (schema) => schema.type === "boolean"; /** * Test whether the schema is an integer type. * * @param schema Target schema * @returns Whether integer type or not */ LlmTypeCheckerV3.isInteger = (schema) => schema.type === "integer"; /** * Test whether the schema is a number type. * * @param schema Target schema * @returns Whether number type or not */ LlmTypeCheckerV3.isNumber = (schema) => schema.type === "number"; /** * Test whether the schema is a string type. * * @param schema Target schema * @returns Whether string type or not */ LlmTypeCheckerV3.isString = (schema) => schema.type === "string"; /** * Test whether the schema is a null type. * * @param schema Target schema * @returns Whether null type or not */ LlmTypeCheckerV3.isNullOnly = (schema) => schema.type === "null"; /** * Test whether the schema is a nullable type. * * @param schema Target schema * @returns Whether nullable type or not */ LlmTypeCheckerV3.isNullable = (schema) => !LlmTypeCheckerV3.isUnknown(schema) && (LlmTypeCheckerV3.isNullOnly(schema) || (LlmTypeCheckerV3.isOneOf(schema) ? schema.oneOf.some(LlmTypeCheckerV3.isNullable) : schema.nullable === true)); /** * Test whether the schema is an unknown type. * * @param schema Target schema * @returns Whether unknown type or not */ LlmTypeCheckerV3.isUnknown = (schema) => !LlmTypeCheckerV3.isOneOf(schema) && schema.type === undefined; })(LlmTypeCheckerV3 || (exports.LlmTypeCheckerV3 = LlmTypeCheckerV3 = {}));