@samchon/openapi
Version:
Universal OpenAPI to LLM function calling schemas. Transform any Swagger/OpenAPI document into type-safe schemas for OpenAI, Claude, Qwen, and more.
1 lines • 26.1 kB
Source Map (JSON)
{"version":3,"file":"HttpMigrateRouteComposer.mjs","sources":["../../src/composers/HttpMigrateRouteComposer.ts"],"sourcesContent":["import { OpenApi } from \"../OpenApi\";\nimport { IHttpMigrateRoute } from \"../structures/IHttpMigrateRoute\";\nimport { EndpointUtil } from \"../utils/EndpointUtil\";\nimport { Escaper } from \"../utils/Escaper\";\nimport { OpenApiTypeChecker } from \"../utils/OpenApiTypeChecker\";\n\nexport namespace HttpMigrateRouteComposer {\n export interface IProps {\n document: OpenApi.IDocument;\n method: \"head\" | \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n path: string;\n emendedPath: string;\n operation: OpenApi.IOperation;\n }\n export const compose = (props: IProps): IHttpMigrateRoute | string[] => {\n //----\n // REQUEST AND RESPONSE BODY\n //----\n const body: false | null | IHttpMigrateRoute.IBody = emplaceBodySchema(\n \"request\",\n )((schema) =>\n emplaceReference({\n document: props.document,\n name:\n EndpointUtil.pascal(`I/Api/${props.path}`) +\n \".\" +\n EndpointUtil.pascal(`${props.method}/Body`),\n schema,\n }),\n )(props.operation.requestBody);\n const success: false | null | IHttpMigrateRoute.ISuccess = (() => {\n const body = emplaceBodySchema(\"response\")((schema) =>\n emplaceReference({\n document: props.document,\n name:\n EndpointUtil.pascal(`I/Api/${props.path}`) +\n \".\" +\n EndpointUtil.pascal(`${props.method}/Response`),\n schema,\n }),\n )(\n props.operation.responses?.[\"201\"] ??\n props.operation.responses?.[\"200\"] ??\n props.operation.responses?.default,\n );\n return body\n ? {\n ...body,\n status: props.operation.responses?.[\"201\"]\n ? \"201\"\n : props.operation.responses?.[\"200\"]\n ? \"200\"\n : \"default\",\n }\n : body;\n })();\n\n const failures: string[] = [];\n if (body === false)\n failures.push(\n `supports only \"application/json\", \"application/x-www-form-urlencoded\", \"multipart/form-data\" and \"text/plain\" content type in the request body.`,\n );\n if (success === false)\n failures.push(\n `supports only \"application/json\", \"application/x-www-form-urlencoded\" and \"text/plain\" content type in the response body.`,\n );\n\n //----\n // HEADERS AND QUERY\n //---\n const [headers, query] = [\"header\", \"query\"].map((type) => {\n // FIND TARGET PARAMETERS\n const parameters: OpenApi.IOperation.IParameter[] = (\n props.operation.parameters ?? []\n ).filter((p) => p.in === type);\n if (parameters.length === 0) return null;\n\n // CHECK PARAMETER TYPES -> TO BE OBJECT\n const objects = parameters\n .map((p) =>\n OpenApiTypeChecker.isObject(p.schema)\n ? p.schema\n : OpenApiTypeChecker.isReference(p.schema) &&\n OpenApiTypeChecker.isObject(\n props.document.components.schemas?.[\n p.schema.$ref.replace(`#/components/schemas/`, ``)\n ] ?? {},\n )\n ? p.schema\n : null!,\n )\n .filter((s) => !!s);\n const primitives = parameters.filter(\n (p) =>\n OpenApiTypeChecker.isBoolean(p.schema) ||\n OpenApiTypeChecker.isInteger(p.schema) ||\n OpenApiTypeChecker.isNumber(p.schema) ||\n OpenApiTypeChecker.isString(p.schema) ||\n OpenApiTypeChecker.isArray(p.schema) ||\n OpenApiTypeChecker.isTuple(p.schema),\n );\n const out = (elem: {\n schema: OpenApi.IJsonSchema;\n title?: string;\n description?: string;\n example?: any;\n examples?: Record<string, any>;\n }) =>\n ({\n ...elem,\n name: type,\n key: type,\n title: () => elem.title,\n description: () => elem.description,\n example: () => elem.example,\n examples: () => elem.examples,\n }) satisfies IHttpMigrateRoute.IHeaders;\n\n if (objects.length === 1 && primitives.length === 0)\n return out(parameters[0]);\n else if (objects.length > 1) {\n failures.push(`${type} typed parameters must be only one object type`);\n return false;\n }\n\n // GATHER TO OBJECT TYPE\n const dto: OpenApi.IJsonSchema.IObject | null = objects[0]\n ? OpenApiTypeChecker.isObject(objects[0])\n ? objects[0]\n : ((props.document.components.schemas ?? {})[\n (objects[0] as OpenApi.IJsonSchema.IReference).$ref.replace(\n `#/components/schemas/`,\n ``,\n )\n ] as OpenApi.IJsonSchema.IObject)\n : null;\n const entire: OpenApi.IJsonSchema.IObject[] = [\n ...objects.map((o) =>\n OpenApiTypeChecker.isObject(o)\n ? o\n : (props.document.components.schemas?.[\n o.$ref.replace(`#/components/schemas/`, ``)\n ]! as OpenApi.IJsonSchema.IObject),\n ),\n {\n type: \"object\",\n properties: Object.fromEntries([\n ...primitives.map((p) => [\n p.name,\n {\n ...p.schema,\n description: p.schema.description ?? p.description,\n },\n ]),\n ...(dto ? Object.entries(dto.properties ?? {}) : []),\n ]),\n required: [\n ...new Set([\n ...primitives.filter((p) => p.required).map((p) => p.name!),\n ...(dto?.required ?? []),\n ]),\n ],\n },\n ];\n return parameters.length === 0\n ? null\n : out({\n schema: emplaceReference({\n document: props.document,\n name:\n EndpointUtil.pascal(`I/Api/${props.path}`) +\n \".\" +\n EndpointUtil.pascal(`${props.method}/${type}`),\n schema: {\n type: \"object\",\n properties: Object.fromEntries([\n ...new Map<string, OpenApi.IJsonSchema>(\n entire\n .map((o) =>\n Object.entries(o.properties ?? {}).map(\n ([name, schema]) =>\n [\n name,\n {\n ...schema,\n description:\n schema.description ?? schema.description,\n } as OpenApi.IJsonSchema,\n ] as const,\n ),\n )\n .flat(),\n ),\n ]),\n required: [\n ...new Set(entire.map((o) => o.required ?? []).flat()),\n ],\n } satisfies OpenApi.IJsonSchema.IObject,\n }),\n });\n });\n\n //----\n // PATH PARAMETERS\n //----\n const parameterNames: string[] = EndpointUtil.splitWithNormalization(\n props.emendedPath,\n )\n .filter((str) => str[0] === \":\")\n .map((str) => str.substring(1));\n const pathParameters: OpenApi.IOperation.IParameter[] = (\n props.operation.parameters ?? []\n ).filter((p) => p.in === \"path\");\n if (parameterNames.length !== pathParameters.length)\n if (\n pathParameters.length < parameterNames.length &&\n pathParameters.every(\n (p) => p.name !== undefined && parameterNames.includes(p.name),\n )\n ) {\n for (const name of parameterNames)\n if (pathParameters.find((p) => p.name === name) === undefined)\n pathParameters.push({\n name,\n in: \"path\",\n schema: { type: \"string\" },\n });\n pathParameters.sort(\n (a, b) =>\n parameterNames.indexOf(a.name!) - parameterNames.indexOf(b.name!),\n );\n props.operation.parameters = [\n ...pathParameters,\n ...(props.operation.parameters ?? []).filter((p) => p.in !== \"path\"),\n ];\n } else\n failures.push(\n \"number of path parameters are not matched with its full path.\",\n );\n if (failures.length) return failures;\n\n const parameters: IHttpMigrateRoute.IParameter[] = (\n props.operation.parameters ?? []\n )\n .filter((p) => p.in === \"path\")\n .map((p, i) => ({\n // FILL KEY NAME IF NOT EXISTS\n name: parameterNames[i],\n key: (() => {\n let key: string = EndpointUtil.normalize(parameterNames[i]);\n if (Escaper.variable(key)) return key;\n while (true) {\n key = \"_\" + key;\n if (!parameterNames.some((s) => s === key)) return key;\n }\n })(),\n schema: p.schema,\n parameter: () => p,\n }));\n return {\n method: props.method,\n path: props.path,\n emendedPath: props.emendedPath,\n accessor: [\"@lazy\"],\n parameters: (props.operation.parameters ?? [])\n .filter((p) => p.in === \"path\")\n .map((p, i) => ({\n // FILL KEY NAME IF NOT EXISTS\n name: parameterNames[i],\n key: (() => {\n let key: string = EndpointUtil.normalize(parameterNames[i]);\n if (Escaper.variable(key)) return key;\n while (true) {\n key = \"_\" + key;\n if (!parameterNames.some((s) => s === key)) return key;\n }\n })(),\n schema: p.schema,\n parameter: () => p,\n })),\n headers: headers || null,\n query: query || null,\n body: body || null,\n success: success || null,\n exceptions: Object.fromEntries(\n Object.entries(props.operation.responses ?? {})\n .filter(\n ([key]) => key !== \"200\" && key !== \"201\" && key !== \"default\",\n )\n .map(([status, response]) => [\n status,\n {\n schema: (response.content?.[\"application/json\"]?.schema ??\n {}) satisfies OpenApi.IJsonSchema,\n response: () => response,\n media: () =>\n (response.content?.[\"application/json\"] ??\n {}) satisfies OpenApi.IJsonSchema,\n } satisfies IHttpMigrateRoute.IException,\n ]),\n ),\n comment: () =>\n writeRouteComment({\n operation: props.operation,\n parameters,\n query: query || null,\n body: body || null,\n }),\n operation: () => props.operation,\n } satisfies IHttpMigrateRoute as IHttpMigrateRoute;\n };\n\n const writeRouteComment = (props: {\n operation: OpenApi.IOperation;\n parameters: IHttpMigrateRoute.IParameter[];\n query: IHttpMigrateRoute.IQuery | null;\n body: IHttpMigrateRoute.IBody | null;\n }): string => {\n const commentTags: string[] = [];\n const add = (text: string) => {\n if (commentTags.every((line) => line !== text)) commentTags.push(text);\n };\n\n let description: string = props.operation.description ?? \"\";\n if (!!props.operation.summary?.length) {\n const summary: string = props.operation.summary.endsWith(\".\")\n ? props.operation.summary\n : props.operation.summary + \".\";\n if (\n !!description.length &&\n !description.startsWith(props.operation.summary)\n )\n description = `${summary}\\n\\n${description}`;\n }\n description = description\n .split(\"\\n\")\n .map((s) => s.trim())\n .join(\"\\n\");\n\n add(\"@param connection\");\n for (const p of props.parameters ?? []) {\n const param = p.parameter();\n if (param.description) {\n const text: string = param.description!;\n add(`@param ${p.name} ${writeIndented(text, p.name.length + 8)}`);\n }\n }\n if (props.body?.description()?.length)\n add(`@param body ${writeIndented(props.body.description()!, 12)}`);\n for (const security of props.operation.security ?? [])\n for (const [name, scopes] of Object.entries(security))\n add(`@security ${[name, ...scopes].join(\"\")}`);\n if (props.operation.tags)\n props.operation.tags.forEach((name) => add(`@tag ${name}`));\n if (props.operation.deprecated) add(\"@deprecated\");\n description = description.length\n ? commentTags.length\n ? `${description}\\n\\n${commentTags.join(\"\\n\")}`\n : description\n : commentTags.join(\"\\n\");\n description = description.split(\"*/\").join(\"*\\\\/\");\n return description;\n };\n\n const writeIndented = (text: string, spaces: number): string =>\n text\n .split(\"\\n\")\n .map((s) => s.trim())\n .map((s, i) => (i === 0 ? s : `${\" \".repeat(spaces)}${s}`))\n .join(\"\\n\");\n\n const emplaceBodySchema =\n (from: \"request\" | \"response\") =>\n (\n emplacer: (schema: OpenApi.IJsonSchema) => OpenApi.IJsonSchema.IReference,\n ) =>\n (meta?: {\n description?: string;\n content?: Partial<Record<string, OpenApi.IOperation.IMediaType>>; // ISwaggerRouteBodyContent;\n \"x-nestia-encrypted\"?: boolean;\n }): false | null | IHttpMigrateRoute.IBody => {\n if (!meta?.content) return null;\n\n const entries: [string, OpenApi.IOperation.IMediaType][] = Object.entries(\n meta.content,\n ).filter(([_, v]) => !!v) as [string, OpenApi.IOperation.IMediaType][];\n const json = entries.find((e) =>\n meta[\"x-nestia-encrypted\"] === true\n ? e[0].includes(\"text/plain\") || e[0].includes(\"application/json\")\n : e[0].includes(\"application/json\") || e[0].includes(\"*/*\"),\n );\n if (json) {\n const { schema } = json[1];\n return schema || from === \"response\"\n ? {\n type: \"application/json\",\n name: \"body\",\n key: \"body\",\n schema: schema\n ? isNotObjectLiteral(schema)\n ? schema\n : emplacer(schema)\n : {},\n description: () => meta.description,\n media: () => json[1],\n \"x-nestia-encrypted\": meta[\"x-nestia-encrypted\"],\n }\n : null;\n }\n\n const query = entries.find((e) =>\n e[0].includes(\"application/x-www-form-urlencoded\"),\n );\n if (query) {\n const { schema } = query[1];\n return schema || from === \"response\"\n ? {\n type: \"application/x-www-form-urlencoded\",\n name: \"body\",\n key: \"body\",\n schema: schema\n ? isNotObjectLiteral(schema)\n ? schema\n : emplacer(schema)\n : {},\n description: () => meta.description,\n media: () => query[1],\n }\n : null;\n }\n\n const text = entries.find((e) => e[0].includes(\"text/plain\"));\n if (text)\n return {\n type: \"text/plain\",\n name: \"body\",\n key: \"body\",\n schema: { type: \"string\" },\n description: () => meta.description,\n media: () => text[1],\n };\n\n if (from === \"request\") {\n const multipart = entries.find((e) =>\n e[0].includes(\"multipart/form-data\"),\n );\n if (multipart) {\n const { schema } = multipart[1];\n return {\n type: \"multipart/form-data\",\n name: \"body\",\n key: \"body\",\n schema: schema\n ? isNotObjectLiteral(schema)\n ? schema\n : emplacer(schema)\n : {},\n description: () => meta.description,\n media: () => multipart[1],\n };\n }\n }\n return false;\n };\n\n const emplaceReference = (props: {\n document: OpenApi.IDocument;\n name: string;\n schema: OpenApi.IJsonSchema;\n }): OpenApi.IJsonSchema.IReference => {\n props.document.components.schemas ??= {};\n props.document.components.schemas[props.name] = props.schema;\n return {\n $ref: `#/components/schemas/${props.name}`,\n } satisfies OpenApi.IJsonSchema.IReference;\n };\n\n const isNotObjectLiteral = (schema: OpenApi.IJsonSchema): boolean =>\n OpenApiTypeChecker.isReference(schema) ||\n OpenApiTypeChecker.isBoolean(schema) ||\n OpenApiTypeChecker.isNumber(schema) ||\n OpenApiTypeChecker.isString(schema) ||\n OpenApiTypeChecker.isUnknown(schema) ||\n (OpenApiTypeChecker.isOneOf(schema) &&\n schema.oneOf.every(isNotObjectLiteral)) ||\n (OpenApiTypeChecker.isArray(schema) && isNotObjectLiteral(schema.items));\n}\n"],"names":["HttpMigrateRouteComposer","compose","props","body","emplaceBodySchema","schema","emplaceReference","document","name","EndpointUtil","pascal","path","method","operation","requestBody","success","responses","default","status","failures","push","headers","query","map","type","parameters","filter","p","in","length","objects","OpenApiTypeChecker","isObject","isReference","components","schemas","$ref","replace","s","primitives","isBoolean","isInteger","isNumber","isString","isArray","isTuple","out","elem","key","title","description","example","examples","dto","entire","o","properties","Object","fromEntries","entries","required","Set","Map","flat","parameterNames","splitWithNormalization","emendedPath","str","substring","pathParameters","every","undefined","includes","find","sort","a","b","indexOf","i","normalize","Escaper","variable","some","parameter","accessor","exceptions","response","content","media","comment","writeRouteComment","commentTags","add","text","line","summary","endsWith","startsWith","split","trim","join","param","writeIndented","security","scopes","tags","forEach","deprecated","spaces","repeat","from","emplacer","meta","_","v","json","e","isNotObjectLiteral","multipart","_a","isUnknown","isOneOf","oneOf","items"],"mappings":"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"}