@nestia/sdk
Version:
Nestia SDK and Swagger generator
118 lines (108 loc) • 3.82 kB
text/typescript
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");
};
}