@samchon/openapi
Version:
OpenAPI definitions and converters for 'typia' and 'nestia'.
125 lines (121 loc) • 7 kB
JavaScript
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