@nestia/sdk
Version:
Nestia SDK and Swagger generator
155 lines (142 loc) • 5.67 kB
text/typescript
// import path from "path";
// import ts from "typescript";
// import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
// import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
// import { Metadata } from "typia/lib/schemas/metadata/Metadata";
// import { INestiaProject } from "../structures/INestiaProject";
// import { IReflectController } from "../structures/IReflectController";
// import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
// import { ITypeTuple } from "../structures/ITypeTuple";
// import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
// import { GenericAnalyzer } from "./GenericAnalyzer";
// import { ImportAnalyzer } from "./ImportAnalyzer";
// export namespace ExceptionAnalyzer {
// export const analyze =
// (project: INestiaProject) =>
// (props: {
// generics: GenericAnalyzer.Dictionary;
// imports: ImportAnalyzer.Dictionary;
// controller: IReflectController;
// operation: IReflectHttpOperation;
// declaration: ts.MethodDeclaration;
// }): Record<
// number | "2XX" | "3XX" | "4XX" | "5XX",
// ITypedHttpRoute.IOutput
// > => {
// const output: Record<
// number | "2XX" | "3XX" | "4XX" | "5XX",
// ITypedHttpRoute.IOutput
// > = {} as any;
// for (const decorator of props.declaration.modifiers ?? [])
// if (ts.isDecorator(decorator))
// analyzeTyped(project)({
// ...props,
// output,
// decorator,
// });
// return output;
// };
// const analyzeTyped =
// (project: INestiaProject) =>
// (props: {
// generics: GenericAnalyzer.Dictionary;
// imports: ImportAnalyzer.Dictionary;
// controller: IReflectController;
// operation: IReflectHttpOperation;
// output: Record<
// number | "2XX" | "3XX" | "4XX" | "5XX",
// ITypedHttpRoute.IOutput
// >;
// decorator: ts.Decorator;
// }): boolean => {
// // CHECK DECORATOR
// if (!ts.isCallExpression(props.decorator.expression)) return false;
// else if ((props.decorator.expression.typeArguments ?? []).length !== 1)
// return false;
// // CHECK SIGNATURE
// const signature: ts.Signature | undefined =
// project.checker.getResolvedSignature(props.decorator.expression);
// if (!signature || !signature.declaration) return false;
// else if (
// path
// .resolve(signature.declaration.getSourceFile().fileName)
// .indexOf(TYPED_EXCEPTION_PATH) === -1
// )
// return false;
// // GET TYPE INFO
// const status: string | null = getStatus(project.checker)(
// props.decorator.expression.arguments[0] ?? null,
// );
// if (status === null) return false;
// const node: ts.TypeNode = props.decorator.expression.typeArguments![0];
// const type: ts.Type = project.checker.getTypeFromTypeNode(node);
// if (type.isTypeParameter()) {
// project.errors.push({
// file: props.controller.file,
// controller: props.controller.name,
// function: props.operation.name,
// message: "TypedException() without generic argument specification.",
// });
// return false;
// }
// const tuple: ITypeTuple | null = ImportAnalyzer.analyze(project.checker)({
// generics: props.generics,
// imports: props.imports,
// type,
// });
// if (tuple === null) {
// project.errors.push({
// file: props.controller.file,
// controller: props.controller.name,
// function: props.operation.name,
// message: `TypeException() with unknown type on ${status} status.`,
// });
// return false;
// }
// // DO ASSIGN
// const matched: IReflectHttpOperation.IException[] = Object.entries(
// props.operation.exceptions,
// )
// .filter(([key]) => status === key)
// .map(([_key, value]) => value);
// for (const m of matched)
// props.output[m.status] = {
// type: tuple.type,
// typeName: tuple.typeName,
// contentType: "application/json",
// description: m.description,
// };
// return true;
// };
// const getStatus =
// (checker: ts.TypeChecker) =>
// (expression: ts.Expression | null): string | null => {
// if (expression === null) return null;
// const type: ts.Type = checker.getTypeAtLocation(expression);
// const result = MetadataFactory.analyze(checker)({
// escape: true,
// constant: true,
// absorb: true,
// })(new MetadataCollection())(type);
// if (false === result.success) return null;
// const meta: Metadata = result.data;
// if (meta.constants.length === 1)
// return meta.constants[0].values[0].value.toString();
// else if (meta.escaped && meta.escaped.returns.constants.length === 1)
// return meta.escaped.returns.constants[0].values[0].value.toString();
// else if (ts.isStringLiteral(expression)) return expression.text;
// else if (ts.isNumericLiteral(expression)) {
// const value: number = Number(expression.text.split("_").join(""));
// if (false === isNaN(value)) return value.toString();
// }
// return null;
// };
// }
// const TYPED_EXCEPTION_PATH = path.join(
// "node_modules",
// "@nestia",
// "core",
// "lib",
// "decorators",
// "TypedException.d.ts",
// );