UNPKG

@nestia/sdk

Version:

Nestia SDK and Swagger generator

111 lines (102 loc) 3.98 kB
import { OpenApi } from "@samchon/openapi"; import { VariadicSingleton } from "tstl"; import { Metadata } from "typia/lib/schemas/metadata/Metadata"; import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute"; import { StringUtil } from "../../utils/StringUtil"; import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer"; export namespace SwaggerOperationResponseComposer { export const compose = (props: { schema: (metadata: Metadata) => OpenApi.IJsonSchema | undefined; route: ITypedHttpRoute; }): Record<string, OpenApi.IOperation.IResponse> => { const output: Record<string, OpenApi.IOperation.IResponse> = {}; // FROM DECORATOR for (const [status, error] of Object.entries(props.route.exceptions)) output[status] = { description: error.description ?? undefined, content: { "application/json": { schema: props.schema(error.metadata), example: error.example, examples: error.examples, }, }, }; // FROM COMMENTS for (const tag of props.route.jsDocTags) { if (tag.name !== "throw" && tag.name !== "throws") continue; const text: string | undefined = tag.text?.find( (elem) => elem.kind === "text", )?.text; if (text === undefined) continue; const elements: string[] = text.split(" ").map((str) => str.trim()); const status: string = elements[0]; if ( isNaN(Number(status)) && status !== "2XX" && status !== "3XX" && status !== "4XX" && status !== "5XX" ) continue; const description: string | undefined = elements.length === 1 ? undefined : elements.slice(1).join(" "); const oldbie = output[status]; if (description && oldbie !== undefined) oldbie.description ??= description; else if (oldbie === undefined) output[status] = { description: description, content: { "application/json": { schema: {}, }, }, }; } // SUCCESS const description: string | undefined = SwaggerDescriptionComposer.descriptionFromJsDocTag({ jsDocTags: props.route.jsDocTags, tag: "returns", }) ?? SwaggerDescriptionComposer.descriptionFromJsDocTag({ jsDocTags: props.route.jsDocTags, tag: "return", }); output[ props.route.success.status ?? (props.route.method.toLowerCase() === "post" ? 201 : 200) ] = { description: props.route.success.encrypted ? `${warning.get(!!description, props.route.method)}${description ?? ""}` : (description ?? ""), content: props.route.success.contentType ? { [props.route.success.contentType]: { schema: props.schema(props.route.success.metadata), example: props.route.success.example, examples: props.route.success.examples, }, } : undefined, ...(props.route.success.encrypted ? { "x-nestia-encrypted": true } : {}), }; return output; }; } const warning = new VariadicSingleton((described: boolean, method: string) => { const summary: string = "Response data have been encrypted."; const component: string = `[EncryptedRoute.${StringUtil.capitalize(method)}](https://github.com/samchon/@nestia/core#encryptedroute)`; const content: string[] = [ "## Warning", "", summary, "", `The response body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`, "", `Therefore, just utilize this swagger editor only for referencing. If you need to call the real API, using [SDK](https://github.com/samchon/nestia#software-development-kit) would be much better.`, ]; if (described === true) content.push("", "----------------", "", ""); return content.join("\n"); });