UNPKG

@samchon/openapi

Version:

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

237 lines (236 loc) 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LlmSchemaV3Composer = void 0; const OpenApiV3Downgrader_1 = require("../../converters/OpenApiV3Downgrader"); const OpenApiV3Upgrader_1 = require("../../converters/OpenApiV3Upgrader"); const LlmTypeCheckerV3_1 = require("../../utils/LlmTypeCheckerV3"); const OpenApiConstraintShifter_1 = require("../../utils/OpenApiConstraintShifter"); const OpenApiTypeChecker_1 = require("../../utils/OpenApiTypeChecker"); const OpenApiValidator_1 = require("../../utils/OpenApiValidator"); const LlmDescriptionInverter_1 = require("./LlmDescriptionInverter"); const LlmParametersComposer_1 = require("./LlmParametersComposer"); var LlmSchemaV3Composer; (function (LlmSchemaV3Composer) { /** * @internal */ LlmSchemaV3Composer.IS_DEFS = false; /* ----------------------------------------------------------- CONVERTERS ----------------------------------------------------------- */ LlmSchemaV3Composer.parameters = (props) => { const entity = LlmParametersComposer_1.LlmParametersFinder.parameters(Object.assign(Object.assign({}, props), { method: "LlmSchemaV3Composer.parameters" })); if (entity.success === false) return entity; const result = LlmSchemaV3Composer.schema(props); if (result.success === false) return result; return { success: true, value: Object.assign(Object.assign({}, result.value), { additionalProperties: false }), }; }; LlmSchemaV3Composer.schema = (props) => { // CHECK TUPLE TYPE const reasons = []; OpenApiTypeChecker_1.OpenApiTypeChecker.visit({ closure: (next, accessor) => { var _a; if (props.validate) reasons.push(...props.validate(next, accessor)); if (OpenApiTypeChecker_1.OpenApiTypeChecker.isTuple(next)) reasons.push({ accessor: accessor, schema: next, message: "LLM does not allow tuple type.", }); else if (OpenApiTypeChecker_1.OpenApiTypeChecker.isReference(next)) { // UNABLE TO FIND MATCHED REFERENCE const key = next.$ref.split("#/components/schemas/")[1]; if (((_a = props.components.schemas) === null || _a === void 0 ? void 0 : _a[key]) === undefined) { reasons.push({ schema: next, message: `${accessor}: unable to find reference type ${JSON.stringify(key)}.`, accessor: accessor, }); } } }, components: props.components, schema: props.schema, accessor: props.accessor, refAccessor: props.refAccessor, }); // if ((valid as boolean) === false) return null; if (reasons.length > 0) return { success: false, error: { method: "LlmSchemaV3Composer.schema", message: "Failed to compose LLM schema of v3", reasons, }, }; // CHECK MISMATCHES const escaped = OpenApiTypeChecker_1.OpenApiTypeChecker.escape(Object.assign(Object.assign({}, props), { recursive: props.config.recursive })); if (escaped.success === false) // UNREACHABLE return { success: false, error: { method: "LlmSchemaV3Composer.schema", message: "Failed to compose LLM schema of v3", reasons: escaped.error.reasons, }, }; // SPECIALIZATIONS const downgraded = OpenApiV3Downgrader_1.OpenApiV3Downgrader.downgradeSchema({ original: { schemas: {}, }, downgraded: {}, })(escaped.value); LlmTypeCheckerV3_1.LlmTypeCheckerV3.visit({ closure: (next) => { var _a, _b; if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isOneOf(next) && next.discriminator !== undefined) delete next.discriminator; else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isObject(next)) { (_a = next.properties) !== null && _a !== void 0 ? _a : (next.properties = {}); (_b = next.required) !== null && _b !== void 0 ? _b : (next.required = []); } if (props.config.constraint === false) { if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isInteger(next) || LlmTypeCheckerV3_1.LlmTypeCheckerV3.isNumber(next)) OpenApiConstraintShifter_1.OpenApiConstraintShifter.shiftNumeric(next); else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isString(next)) OpenApiConstraintShifter_1.OpenApiConstraintShifter.shiftString(next); else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isArray(next)) OpenApiConstraintShifter_1.OpenApiConstraintShifter.shiftArray(next); } }, schema: downgraded, }); return { success: true, value: downgraded, }; }; /* ----------------------------------------------------------- SEPARATORS ----------------------------------------------------------- */ LlmSchemaV3Composer.separateParameters = (props) => { var _a; const [llm, human] = separateObject({ predicate: props.predicate, schema: props.parameters, }); return { llm: (_a = llm) !== null && _a !== void 0 ? _a : { type: "object", properties: {}, additionalProperties: false, required: [], }, human: human, validate: llm ? OpenApiValidator_1.OpenApiValidator.create({ components: {}, schema: LlmSchemaV3Composer.invert({ schema: llm }), required: true, }) : undefined, }; }; const separateStation = (props) => { if (props.predicate(props.schema) === true) return [null, props.schema]; else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isUnknown(props.schema) || LlmTypeCheckerV3_1.LlmTypeCheckerV3.isOneOf(props.schema)) return [props.schema, null]; else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isObject(props.schema)) return separateObject({ predicate: props.predicate, schema: props.schema, }); else if (LlmTypeCheckerV3_1.LlmTypeCheckerV3.isArray(props.schema)) return separateArray({ predicate: props.predicate, schema: props.schema, }); return [props.schema, null]; }; const separateArray = (props) => { const [x, y] = separateStation({ predicate: props.predicate, schema: props.schema.items, }); return [ x !== null ? Object.assign(Object.assign({}, props.schema), { items: x }) : null, y !== null ? Object.assign(Object.assign({}, props.schema), { items: y }) : null, ]; }; const separateObject = (props) => { var _a, _b; // EMPTY OBJECT if (Object.keys((_a = props.schema.properties) !== null && _a !== void 0 ? _a : {}).length === 0 && !!props.schema.additionalProperties === false) return [props.schema, null]; const llm = Object.assign(Object.assign({}, props.schema), { properties: {}, additionalProperties: props.schema.additionalProperties }); const human = Object.assign(Object.assign({}, props.schema), { properties: {}, additionalProperties: props.schema.additionalProperties }); for (const [key, value] of Object.entries((_b = props.schema.properties) !== null && _b !== void 0 ? _b : {})) { const [x, y] = separateStation({ predicate: props.predicate, schema: value, }); if (x !== null) llm.properties[key] = x; if (y !== null) human.properties[key] = y; } if (typeof props.schema.additionalProperties === "object" && props.schema.additionalProperties !== null) { const [dx, dy] = separateStation({ predicate: props.predicate, schema: props.schema.additionalProperties, }); llm.additionalProperties = dx !== null && dx !== void 0 ? dx : false; human.additionalProperties = dy !== null && dy !== void 0 ? dy : false; } return [ !!Object.keys(llm.properties).length || !!llm.additionalProperties ? shrinkRequired(llm) : null, !!Object.keys(human.properties).length || !!human.additionalProperties ? shrinkRequired(human) : null, ]; }; const shrinkRequired = (s) => { s.required = s.required.filter((key) => s.properties[key] !== undefined); return s; }; /* ----------------------------------------------------------- INVERTERS ----------------------------------------------------------- */ LlmSchemaV3Composer.invert = (props) => { const upgraded = OpenApiV3Upgrader_1.OpenApiV3Upgrader.convertSchema({})(props.schema); OpenApiTypeChecker_1.OpenApiTypeChecker.visit({ closure: (schema) => { if (OpenApiTypeChecker_1.OpenApiTypeChecker.isArray(schema)) Object.assign(schema, Object.assign(Object.assign({}, schema), LlmDescriptionInverter_1.LlmDescriptionInverter.array(schema.description))); else if (OpenApiTypeChecker_1.OpenApiTypeChecker.isInteger(schema) || OpenApiTypeChecker_1.OpenApiTypeChecker.isNumber(schema)) Object.assign(schema, Object.assign(Object.assign({}, schema), LlmDescriptionInverter_1.LlmDescriptionInverter.numeric(schema.description))); else if (OpenApiTypeChecker_1.OpenApiTypeChecker.isString(schema)) Object.assign(schema, Object.assign(Object.assign({}, schema), LlmDescriptionInverter_1.LlmDescriptionInverter.string(schema.description))); }, components: {}, schema: upgraded, }); return upgraded; }; })(LlmSchemaV3Composer || (exports.LlmSchemaV3Composer = LlmSchemaV3Composer = {}));