UNPKG

@nestia/sdk

Version:

Nestia SDK and Swagger generator

118 lines (108 loc) 3.82 kB
import ts from "typescript"; import { IJsDocTagInfo } from "typia"; import { INestiaProject } from "../../structures/INestiaProject"; import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute"; import { FilePrinter } from "./FilePrinter"; import { ImportDictionary } from "./ImportDictionary"; import { SdkHttpFunctionProgrammer } from "./SdkHttpFunctionProgrammer"; import { SdkHttpNamespaceProgrammer } from "./SdkHttpNamespaceProgrammer"; export namespace SdkHttpRouteProgrammer { export const write = (project: INestiaProject) => (importer: ImportDictionary) => (route: ITypedHttpRoute): ts.Statement[] => { const props = { headers: route.parameters .filter((p) => p.category === "headers") .find((p) => p.field === null), query: route.parameters .filter((p) => p.category === "query") .find((p) => p.field === null), input: route.parameters.find((p) => p.category === "body"), }; return [ FilePrinter.description( SdkHttpFunctionProgrammer.write(project)(importer)(route, props), describe(route), ), SdkHttpNamespaceProgrammer.write(project)(importer)(route, props), ]; }; const describe = (route: ITypedHttpRoute): string => { // MAIN DESCRIPTION const descriptionComments: string[] = route.description ? route.description.split("\n") : []; const tagComments: string[] = []; // PARAMETERS for (const p of route.parameters) { if (p.category === "headers") continue; const description: string | undefined = p.description ?? p.jsDocTags.find((tag) => tag.name === "description")?.text?.[0].text ?? route.jsDocTags .find((tag) => tag.name === "param" && tag.text?.[0].text === p.name) ?.text?.map((e) => e.text) .join("") .substring(p.name.length); if (!description?.length) continue; tagComments.push( `@param ${p.name} ${description .split("\n") .map((str) => str.trim()) .map((str, i) => { if (i === 0) return str; const rpad: number = p.name.length + 8; return `${" ".repeat(rpad)}${str}`; }) .join("\n")}`, ); } // COMMENT TAGS const tags: IJsDocTagInfo[] = route.jsDocTags.filter( (tag) => tag.name !== "param", ); if (tags.length !== 0) { const content: string[] = tags.map((t) => t.text?.length ? `@${t.name} ${t.text .map((e) => e.text) .join("") .split("\n") .map((str) => str.trim()) .map((str, i) => { if (i === 0) return str; return `${" ".repeat(t.name.length + 1)} ${str}`; }) .join("\n")}` : `@${t.name}`, ); tagComments.push(...new Set(content)); } // EXCEPTIONS for (const [key, value] of Object.entries(route.exceptions)) { if ( tagComments.some( (str) => str.startsWith(`@throw ${key}`) || str.startsWith(`@throws ${key}`), ) ) continue; tagComments.push( value.description?.length ? `@throws ${key} ${value.description.split("\n")[0]}` : `@throws ${key}`, ); } // POSTFIX return [ ...descriptionComments, ...(descriptionComments.length && tagComments.length ? [""] : []), ...tagComments, ...(descriptionComments.length && tagComments.length ? [""] : []), `@controller ${route.controller.class.name}.${route.name}`, `@path ${route.method} ${route.path}`, `@nestia Generated by Nestia - https://github.com/samchon/nestia`, ].join("\n"); }; }