UNPKG

@samchon/openapi

Version:

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

125 lines (121 loc) 7 kB
import { MapUtil } from "./MapUtil.mjs"; var ChatGptTypeChecker; (function(ChatGptTypeChecker) { ChatGptTypeChecker.isNull = schema => schema.type === "null"; ChatGptTypeChecker.isUnknown = schema => schema.type === undefined && !ChatGptTypeChecker.isAnyOf(schema) && !ChatGptTypeChecker.isReference(schema); ChatGptTypeChecker.isBoolean = schema => schema.type === "boolean"; ChatGptTypeChecker.isInteger = schema => schema.type === "integer"; ChatGptTypeChecker.isNumber = schema => schema.type === "number"; ChatGptTypeChecker.isString = schema => schema.type === "string"; ChatGptTypeChecker.isArray = schema => schema.type === "array" && schema.items !== undefined; ChatGptTypeChecker.isObject = schema => schema.type === "object"; ChatGptTypeChecker.isReference = schema => schema.$ref !== undefined; ChatGptTypeChecker.isAnyOf = schema => schema.anyOf !== undefined; ChatGptTypeChecker.visit = props => { const already = new Set; const refAccessor = props.refAccessor ?? "$input.$defs"; const next = (schema, accessor) => { props.closure(schema, accessor); if (ChatGptTypeChecker.isReference(schema)) { const key = schema.$ref.split("#/$defs/").pop(); if (already.has(key) === true) return; already.add(key); const found = props.$defs?.[key]; if (found !== undefined) next(found, `${refAccessor}[${key}]`); } else if (ChatGptTypeChecker.isAnyOf(schema)) schema.anyOf.forEach(((s, i) => next(s, `${accessor}.anyOf[${i}]`))); else if (ChatGptTypeChecker.isObject(schema)) { for (const [key, value] of Object.entries(schema.properties)) next(value, `${accessor}.properties[${JSON.stringify(key)}]`); if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null) next(schema.additionalProperties, `${accessor}.additionalProperties`); } else if (ChatGptTypeChecker.isArray(schema)) next(schema.items, `${accessor}.items`); }; next(props.schema, props.accessor ?? "$input.schemas"); }; ChatGptTypeChecker.covers = props => coverStation({ $defs: props.$defs, x: props.x, y: props.y, visited: new Map }); const coverStation = p => { const cache = p.visited.get(p.x)?.get(p.y); if (cache !== undefined) return cache; const nested = MapUtil.take(p.visited)(p.x)((() => new Map)); nested.set(p.y, true); const result = coverSchema(p); nested.set(p.y, result); return result; }; const coverSchema = p => { if (p.x === p.y) return true; else if (ChatGptTypeChecker.isReference(p.x) && ChatGptTypeChecker.isReference(p.y) && p.x.$ref === p.y.$ref) return true; const alpha = flatSchema(p.$defs, p.x); const beta = flatSchema(p.$defs, p.y); if (alpha.some((x => ChatGptTypeChecker.isUnknown(x)))) return true; else if (beta.some((x => ChatGptTypeChecker.isUnknown(x)))) return false; return beta.every((b => alpha.some((a => coverEscapedSchema({ $defs: p.$defs, visited: p.visited, x: a, y: b }))))); }; const coverEscapedSchema = p => { if (p.x === p.y) return true; else if (ChatGptTypeChecker.isUnknown(p.x)) return true; else if (ChatGptTypeChecker.isUnknown(p.y)) return false; else if (ChatGptTypeChecker.isNull(p.x)) return ChatGptTypeChecker.isNull(p.y); else if (ChatGptTypeChecker.isBoolean(p.x)) return ChatGptTypeChecker.isBoolean(p.y) && coverBoolean(p.x, p.y); else if (ChatGptTypeChecker.isInteger(p.x)) return ChatGptTypeChecker.isInteger(p.y) && coverInteger(p.x, p.y); else if (ChatGptTypeChecker.isNumber(p.x)) return ChatGptTypeChecker.isNumber(p.y) && coverNumber(p.x, p.y); else if (ChatGptTypeChecker.isString(p.x)) return ChatGptTypeChecker.isString(p.y) && coverString(p.x, p.y); else if (ChatGptTypeChecker.isArray(p.x)) return ChatGptTypeChecker.isArray(p.y) && coverArray({ $defs: p.$defs, visited: p.visited, x: p.x, y: p.y }); else if (ChatGptTypeChecker.isObject(p.x)) return ChatGptTypeChecker.isObject(p.y) && coverObject({ $defs: p.$defs, visited: p.visited, x: p.x, y: p.y }); else if (ChatGptTypeChecker.isReference(p.x)) return ChatGptTypeChecker.isReference(p.y) && p.x.$ref === p.y.$ref; return false; }; const coverArray = p => coverStation({ $defs: p.$defs, visited: p.visited, x: p.x.items, y: p.y.items }); const coverObject = p => { if (!p.x.additionalProperties && !!p.y.additionalProperties) return false; else if (!!p.x.additionalProperties && !!p.y.additionalProperties && (typeof p.x.additionalProperties === "object" && p.y.additionalProperties === true || typeof p.x.additionalProperties === "object" && typeof p.y.additionalProperties === "object" && !coverStation({ $defs: p.$defs, visited: p.visited, x: p.x.additionalProperties, y: p.y.additionalProperties }))) return false; return Object.entries(p.y.properties ?? {}).every((([key, b]) => { const a = p.x.properties?.[key]; if (a === undefined) return false; else if ((p.x.required?.includes(key) ?? false) === true && (p.y.required?.includes(key) ?? false) === false) return false; return coverStation({ $defs: p.$defs, visited: p.visited, x: a, y: b }); })); }; const coverBoolean = (x, y) => { if (!!x.enum?.length) return !!y.enum?.length && y.enum.every((v => x.enum.includes(v))); return true; }; const coverInteger = (x, y) => { if (!!x.enum?.length) return !!y.enum?.length && y.enum.every((v => x.enum.includes(v))); return x.type === y.type; }; const coverNumber = (x, y) => { if (!!x.enum?.length) return !!y.enum?.length && y.enum.every((v => x.enum.includes(v))); return x.type === y.type || x.type === "number" && y.type === "integer"; }; const coverString = (x, y) => { if (!!x.enum?.length) return !!y.enum?.length && y.enum.every((v => x.enum.includes(v))); return x.type === y.type; }; const flatSchema = ($defs, schema) => { schema = escapeReference($defs, schema); if (ChatGptTypeChecker.isAnyOf(schema)) return schema.anyOf.map((v => flatSchema($defs, v))).flat(); return [ schema ]; }; const escapeReference = ($defs, schema) => ChatGptTypeChecker.isReference(schema) ? escapeReference($defs, $defs[schema.$ref.replace("#/$defs/", "")]) : schema; })(ChatGptTypeChecker || (ChatGptTypeChecker = {})); export { ChatGptTypeChecker }; //# sourceMappingURL=ChatGptTypeChecker.mjs.map