@nestia/core 2.4.3 → 3.0.0-dev.20231209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/lib/decorators/EncryptedBody.js +13 -11
  2. package/lib/decorators/EncryptedBody.js.map +1 -1
  3. package/lib/decorators/EncryptedRoute.js +29 -12
  4. package/lib/decorators/EncryptedRoute.js.map +1 -1
  5. package/lib/decorators/internal/get_binary_body.d.ts +1 -0
  6. package/lib/decorators/internal/get_binary_body.js +66 -0
  7. package/lib/decorators/internal/get_binary_body.js.map +1 -0
  8. package/package.json +3 -3
  9. package/src/decorators/DynamicModule.ts +39 -39
  10. package/src/decorators/EncryptedBody.ts +17 -12
  11. package/src/decorators/EncryptedController.ts +38 -38
  12. package/src/decorators/EncryptedModule.ts +79 -79
  13. package/src/decorators/EncryptedRoute.ts +38 -14
  14. package/src/decorators/PlainBody.ts +72 -72
  15. package/src/decorators/TypedBody.ts +59 -59
  16. package/src/decorators/TypedException.ts +89 -89
  17. package/src/decorators/TypedHeaders.ts +69 -69
  18. package/src/decorators/TypedParam.ts +65 -65
  19. package/src/decorators/TypedQuery.ts +246 -246
  20. package/src/decorators/TypedRoute.ts +144 -144
  21. package/src/decorators/internal/EncryptedConstant.ts +4 -4
  22. package/src/decorators/internal/NoTransformConfigureError.ts +8 -8
  23. package/src/decorators/internal/get_binary_body.ts +18 -0
  24. package/src/decorators/internal/get_path_and_querify.ts +103 -103
  25. package/src/decorators/internal/get_path_and_stringify.ts +91 -91
  26. package/src/decorators/internal/get_text_body.ts +20 -20
  27. package/src/decorators/internal/headers_to_object.ts +13 -13
  28. package/src/decorators/internal/load_controller.ts +51 -51
  29. package/src/decorators/internal/route_error.ts +45 -45
  30. package/src/decorators/internal/validate_request_body.ts +57 -57
  31. package/src/decorators/internal/validate_request_headers.ts +68 -68
  32. package/src/decorators/internal/validate_request_query.ts +56 -56
  33. package/src/index.ts +5 -5
  34. package/src/module.ts +14 -14
  35. package/src/options/INestiaTransformOptions.ts +17 -17
  36. package/src/options/INestiaTransformProject.ts +7 -7
  37. package/src/options/IRequestBodyValidator.ts +20 -20
  38. package/src/options/IRequestHeadersValidator.ts +22 -22
  39. package/src/options/IRequestQueryValidator.ts +20 -20
  40. package/src/options/IResponseBodyQuerifier.ts +25 -25
  41. package/src/options/IResponseBodyStringifier.ts +25 -25
  42. package/src/programmers/PlainBodyProgrammer.ts +52 -52
  43. package/src/programmers/TypedBodyProgrammer.ts +108 -108
  44. package/src/programmers/TypedExceptionProgrammer.ts +72 -72
  45. package/src/programmers/TypedHeadersProgrammer.ts +56 -56
  46. package/src/programmers/TypedParamProgrammer.ts +24 -24
  47. package/src/programmers/TypedQueryBodyProgrammer.ts +56 -56
  48. package/src/programmers/TypedQueryProgrammer.ts +56 -56
  49. package/src/programmers/TypedQueryRouteProgrammer.ts +51 -51
  50. package/src/programmers/TypedRouteProgrammer.ts +51 -51
  51. package/src/programmers/http/HttpAssertQuerifyProgrammer.ts +58 -58
  52. package/src/programmers/http/HttpIsQuerifyProgrammer.ts +62 -62
  53. package/src/programmers/http/HttpQuerifyProgrammer.ts +96 -96
  54. package/src/programmers/http/HttpValidateQuerifyProgrammer.ts +63 -63
  55. package/src/programmers/internal/CoreMetadataUtil.ts +21 -21
  56. package/src/transform.ts +35 -35
  57. package/src/transformers/FileTransformer.ts +66 -66
  58. package/src/transformers/MethodTransformer.ts +94 -94
  59. package/src/transformers/NodeTransformer.ts +16 -16
  60. package/src/transformers/ParameterDecoratorTransformer.ts +121 -121
  61. package/src/transformers/ParameterTransformer.ts +48 -48
  62. package/src/transformers/TypedExceptionTransformer.ts +49 -49
  63. package/src/transformers/TypedRouteTransformer.ts +95 -95
  64. package/src/typings/Creator.ts +3 -3
  65. package/src/utils/ExceptionManager.ts +112 -112
  66. package/src/utils/Singleton.ts +20 -20
  67. package/src/utils/SourceFinder.ts +57 -57
@@ -1,66 +1,66 @@
1
- import ts from "typescript";
2
- import { TransformerError } from "typia/lib/transformers/TransformerError";
3
-
4
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
5
- import { NodeTransformer } from "./NodeTransformer";
6
-
7
- export namespace FileTransformer {
8
- export const transform =
9
- (project: Omit<INestiaTransformProject, "context">) =>
10
- (context: ts.TransformationContext) =>
11
- (file: ts.SourceFile): ts.SourceFile =>
12
- file.isDeclarationFile
13
- ? file
14
- : ts.visitEachChild(
15
- file,
16
- (node) =>
17
- iterate_node({
18
- ...project,
19
- context,
20
- })(context)(file)(node),
21
- context,
22
- );
23
-
24
- const iterate_node =
25
- (project: INestiaTransformProject) =>
26
- (context: ts.TransformationContext) =>
27
- (file: ts.SourceFile) =>
28
- (node: ts.Node): ts.Node =>
29
- ts.visitEachChild(
30
- try_transform_node(project)(file)(node) ?? node,
31
- (child) => iterate_node(project)(context)(file)(child),
32
- context,
33
- );
34
-
35
- const try_transform_node =
36
- (project: INestiaTransformProject) =>
37
- (file: ts.SourceFile) =>
38
- (node: ts.Node): ts.Node | null => {
39
- try {
40
- return NodeTransformer.transform(project)(node);
41
- } catch (exp) {
42
- // ONLY ACCEPT TRANSFORMER-ERROR
43
- if (!isTransformerError(exp)) throw exp;
44
-
45
- // AVOID SPECIAL BUG OF TYPESCRIPT COMPILER API
46
- (node as any).parent ??= file;
47
-
48
- // REPORT DIAGNOSTIC
49
- const diagnostic = ts.createDiagnosticForNode(node, {
50
- key: exp.code,
51
- category: ts.DiagnosticCategory.Error,
52
- message: exp.message,
53
- code: `(${exp.code})` as any,
54
- });
55
- project.extras.addDiagnostic(diagnostic);
56
- return null;
57
- }
58
- };
59
- }
60
-
61
- const isTransformerError = (error: any): error is TransformerError =>
62
- typeof error === "object" &&
63
- error !== null &&
64
- error.constructor.name === "TransformerError" &&
65
- typeof error.code === "string" &&
66
- typeof error.message === "string";
1
+ import ts from "typescript";
2
+ import { TransformerError } from "typia/lib/transformers/TransformerError";
3
+
4
+ import { INestiaTransformProject } from "../options/INestiaTransformProject";
5
+ import { NodeTransformer } from "./NodeTransformer";
6
+
7
+ export namespace FileTransformer {
8
+ export const transform =
9
+ (project: Omit<INestiaTransformProject, "context">) =>
10
+ (context: ts.TransformationContext) =>
11
+ (file: ts.SourceFile): ts.SourceFile =>
12
+ file.isDeclarationFile
13
+ ? file
14
+ : ts.visitEachChild(
15
+ file,
16
+ (node) =>
17
+ iterate_node({
18
+ ...project,
19
+ context,
20
+ })(context)(file)(node),
21
+ context,
22
+ );
23
+
24
+ const iterate_node =
25
+ (project: INestiaTransformProject) =>
26
+ (context: ts.TransformationContext) =>
27
+ (file: ts.SourceFile) =>
28
+ (node: ts.Node): ts.Node =>
29
+ ts.visitEachChild(
30
+ try_transform_node(project)(file)(node) ?? node,
31
+ (child) => iterate_node(project)(context)(file)(child),
32
+ context,
33
+ );
34
+
35
+ const try_transform_node =
36
+ (project: INestiaTransformProject) =>
37
+ (file: ts.SourceFile) =>
38
+ (node: ts.Node): ts.Node | null => {
39
+ try {
40
+ return NodeTransformer.transform(project)(node);
41
+ } catch (exp) {
42
+ // ONLY ACCEPT TRANSFORMER-ERROR
43
+ if (!isTransformerError(exp)) throw exp;
44
+
45
+ // AVOID SPECIAL BUG OF TYPESCRIPT COMPILER API
46
+ (node as any).parent ??= file;
47
+
48
+ // REPORT DIAGNOSTIC
49
+ const diagnostic = ts.createDiagnosticForNode(node, {
50
+ key: exp.code,
51
+ category: ts.DiagnosticCategory.Error,
52
+ message: exp.message,
53
+ code: `(${exp.code})` as any,
54
+ });
55
+ project.extras.addDiagnostic(diagnostic);
56
+ return null;
57
+ }
58
+ };
59
+ }
60
+
61
+ const isTransformerError = (error: any): error is TransformerError =>
62
+ typeof error === "object" &&
63
+ error !== null &&
64
+ error.constructor.name === "TransformerError" &&
65
+ typeof error.code === "string" &&
66
+ typeof error.message === "string";
@@ -1,94 +1,94 @@
1
- import ts from "typescript";
2
-
3
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
- import { TypedExceptionTransformer } from "./TypedExceptionTransformer";
5
- import { TypedRouteTransformer } from "./TypedRouteTransformer";
6
-
7
- export namespace MethodTransformer {
8
- export const transform =
9
- (project: INestiaTransformProject) =>
10
- (method: ts.MethodDeclaration): ts.MethodDeclaration => {
11
- const decorators: readonly ts.Decorator[] | undefined = ts.getDecorators
12
- ? ts.getDecorators(method)
13
- : (method as any).decorators;
14
- if (!decorators?.length) return method;
15
-
16
- const signature: ts.Signature | undefined =
17
- project.checker.getSignatureFromDeclaration(method);
18
- const original: ts.Type | undefined =
19
- signature && project.checker.getReturnTypeOfSignature(signature);
20
- const escaped: ts.Type | undefined =
21
- original && get_escaped_type(project.checker)(original);
22
-
23
- if (escaped === undefined) return method;
24
-
25
- const operator = (deco: ts.Decorator): ts.Decorator => {
26
- deco = TypedExceptionTransformer.transform(project)(deco);
27
- deco = TypedRouteTransformer.transform(project)(escaped)(deco);
28
- return deco;
29
- };
30
- if (ts.getDecorators !== undefined)
31
- return ts.factory.updateMethodDeclaration(
32
- method,
33
- (method.modifiers || []).map((mod) =>
34
- ts.isDecorator(mod) ? operator(mod) : mod,
35
- ),
36
- method.asteriskToken,
37
- method.name,
38
- method.questionToken,
39
- method.typeParameters,
40
- method.parameters,
41
- method.type,
42
- method.body,
43
- );
44
- // eslint-disable-next-line
45
- return (ts.factory.updateMethodDeclaration as any)(
46
- method,
47
- decorators.map(operator),
48
- (method as any).modifiers,
49
- method.asteriskToken,
50
- method.name,
51
- method.questionToken,
52
- method.typeParameters,
53
- method.parameters,
54
- method.type,
55
- method.body,
56
- );
57
- };
58
- }
59
-
60
- const get_escaped_type =
61
- (checker: ts.TypeChecker) =>
62
- (type: ts.Type): ts.Type => {
63
- const symbol: ts.Symbol | undefined = type.getSymbol() || type.aliasSymbol;
64
- return symbol && get_name(symbol) === "Promise"
65
- ? escape_promise(checker)(type)
66
- : type;
67
- };
68
-
69
- const escape_promise =
70
- (checker: ts.TypeChecker) =>
71
- (type: ts.Type): ts.Type => {
72
- const generic: readonly ts.Type[] = checker.getTypeArguments(
73
- type as ts.TypeReference,
74
- );
75
- if (generic.length !== 1)
76
- throw new Error(
77
- "Error on ImportAnalyzer.analyze(): invalid promise type.",
78
- );
79
- return generic[0];
80
- };
81
-
82
- const get_name = (symbol: ts.Symbol): string =>
83
- explore_name(symbol.getDeclarations()![0].parent)(
84
- symbol.escapedName.toString(),
85
- );
86
-
87
- const explore_name =
88
- (decl: ts.Node) =>
89
- (name: string): string =>
90
- ts.isModuleBlock(decl)
91
- ? explore_name(decl.parent.parent)(
92
- `${decl.parent.name.getFullText().trim()}.${name}`,
93
- )
94
- : name;
1
+ import ts from "typescript";
2
+
3
+ import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
+ import { TypedExceptionTransformer } from "./TypedExceptionTransformer";
5
+ import { TypedRouteTransformer } from "./TypedRouteTransformer";
6
+
7
+ export namespace MethodTransformer {
8
+ export const transform =
9
+ (project: INestiaTransformProject) =>
10
+ (method: ts.MethodDeclaration): ts.MethodDeclaration => {
11
+ const decorators: readonly ts.Decorator[] | undefined = ts.getDecorators
12
+ ? ts.getDecorators(method)
13
+ : (method as any).decorators;
14
+ if (!decorators?.length) return method;
15
+
16
+ const signature: ts.Signature | undefined =
17
+ project.checker.getSignatureFromDeclaration(method);
18
+ const original: ts.Type | undefined =
19
+ signature && project.checker.getReturnTypeOfSignature(signature);
20
+ const escaped: ts.Type | undefined =
21
+ original && get_escaped_type(project.checker)(original);
22
+
23
+ if (escaped === undefined) return method;
24
+
25
+ const operator = (deco: ts.Decorator): ts.Decorator => {
26
+ deco = TypedExceptionTransformer.transform(project)(deco);
27
+ deco = TypedRouteTransformer.transform(project)(escaped)(deco);
28
+ return deco;
29
+ };
30
+ if (ts.getDecorators !== undefined)
31
+ return ts.factory.updateMethodDeclaration(
32
+ method,
33
+ (method.modifiers || []).map((mod) =>
34
+ ts.isDecorator(mod) ? operator(mod) : mod,
35
+ ),
36
+ method.asteriskToken,
37
+ method.name,
38
+ method.questionToken,
39
+ method.typeParameters,
40
+ method.parameters,
41
+ method.type,
42
+ method.body,
43
+ );
44
+ // eslint-disable-next-line
45
+ return (ts.factory.updateMethodDeclaration as any)(
46
+ method,
47
+ decorators.map(operator),
48
+ (method as any).modifiers,
49
+ method.asteriskToken,
50
+ method.name,
51
+ method.questionToken,
52
+ method.typeParameters,
53
+ method.parameters,
54
+ method.type,
55
+ method.body,
56
+ );
57
+ };
58
+ }
59
+
60
+ const get_escaped_type =
61
+ (checker: ts.TypeChecker) =>
62
+ (type: ts.Type): ts.Type => {
63
+ const symbol: ts.Symbol | undefined = type.getSymbol() || type.aliasSymbol;
64
+ return symbol && get_name(symbol) === "Promise"
65
+ ? escape_promise(checker)(type)
66
+ : type;
67
+ };
68
+
69
+ const escape_promise =
70
+ (checker: ts.TypeChecker) =>
71
+ (type: ts.Type): ts.Type => {
72
+ const generic: readonly ts.Type[] = checker.getTypeArguments(
73
+ type as ts.TypeReference,
74
+ );
75
+ if (generic.length !== 1)
76
+ throw new Error(
77
+ "Error on ImportAnalyzer.analyze(): invalid promise type.",
78
+ );
79
+ return generic[0];
80
+ };
81
+
82
+ const get_name = (symbol: ts.Symbol): string =>
83
+ explore_name(symbol.getDeclarations()![0].parent)(
84
+ symbol.escapedName.toString(),
85
+ );
86
+
87
+ const explore_name =
88
+ (decl: ts.Node) =>
89
+ (name: string): string =>
90
+ ts.isModuleBlock(decl)
91
+ ? explore_name(decl.parent.parent)(
92
+ `${decl.parent.name.getFullText().trim()}.${name}`,
93
+ )
94
+ : name;
@@ -1,16 +1,16 @@
1
- import ts from "typescript";
2
-
3
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
- import { MethodTransformer } from "./MethodTransformer";
5
- import { ParameterTransformer } from "./ParameterTransformer";
6
-
7
- export namespace NodeTransformer {
8
- export const transform =
9
- (project: INestiaTransformProject) =>
10
- (node: ts.Node): ts.Node =>
11
- ts.isMethodDeclaration(node)
12
- ? MethodTransformer.transform(project)(node)
13
- : ts.isParameter(node)
14
- ? ParameterTransformer.transform(project)(node)
15
- : node;
16
- }
1
+ import ts from "typescript";
2
+
3
+ import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
+ import { MethodTransformer } from "./MethodTransformer";
5
+ import { ParameterTransformer } from "./ParameterTransformer";
6
+
7
+ export namespace NodeTransformer {
8
+ export const transform =
9
+ (project: INestiaTransformProject) =>
10
+ (node: ts.Node): ts.Node =>
11
+ ts.isMethodDeclaration(node)
12
+ ? MethodTransformer.transform(project)(node)
13
+ : ts.isParameter(node)
14
+ ? ParameterTransformer.transform(project)(node)
15
+ : node;
16
+ }
@@ -1,121 +1,121 @@
1
- import path from "path";
2
- import ts from "typescript";
3
-
4
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
5
- import { PlainBodyProgrammer } from "../programmers/PlainBodyProgrammer";
6
- import { TypedBodyProgrammer } from "../programmers/TypedBodyProgrammer";
7
- import { TypedHeadersProgrammer } from "../programmers/TypedHeadersProgrammer";
8
- import { TypedParamProgrammer } from "../programmers/TypedParamProgrammer";
9
- import { TypedQueryBodyProgrammer } from "../programmers/TypedQueryBodyProgrammer";
10
- import { TypedQueryProgrammer } from "../programmers/TypedQueryProgrammer";
11
-
12
- export namespace ParameterDecoratorTransformer {
13
- export const transform =
14
- (project: INestiaTransformProject) =>
15
- (type: ts.Type) =>
16
- (decorator: ts.Decorator): ts.Decorator => {
17
- //----
18
- // VALIDATIONS
19
- //----
20
- // CHECK DECORATOR
21
- if (!ts.isCallExpression(decorator.expression)) return decorator;
22
-
23
- // SIGNATURE DECLARATION
24
- const declaration: ts.Declaration | undefined =
25
- project.checker.getResolvedSignature(decorator.expression)?.declaration;
26
- if (declaration === undefined) return decorator;
27
-
28
- // FILE PATH
29
- const file: string = path.resolve(declaration.getSourceFile().fileName);
30
- if (file.indexOf(LIB_PATH) === -1 && file.indexOf(SRC_PATH) === -1)
31
- return decorator;
32
-
33
- //----
34
- // TRANSFORMATION
35
- //----
36
- // FIND PROGRAMMER
37
- const programmer: Programmer | undefined =
38
- FUNCTORS[
39
- getName(project.checker.getTypeAtLocation(declaration).symbol)
40
- ];
41
- if (programmer === undefined) return decorator;
42
-
43
- // GET TYPE INFO
44
- const typeNode: ts.TypeNode | undefined = project.checker.typeToTypeNode(
45
- type,
46
- undefined,
47
- undefined,
48
- );
49
- if (typeNode === undefined) return decorator;
50
-
51
- // DO TRANSFORM
52
- return ts.factory.createDecorator(
53
- ts.factory.updateCallExpression(
54
- decorator.expression,
55
- decorator.expression.expression,
56
- decorator.expression.typeArguments,
57
- programmer(project)(decorator.expression.expression)(
58
- decorator.expression.arguments,
59
- )(type),
60
- ),
61
- );
62
- };
63
- }
64
-
65
- type Programmer = (
66
- project: INestiaTransformProject,
67
- ) => (
68
- modulo: ts.LeftHandSideExpression,
69
- ) => (
70
- parameters: readonly ts.Expression[],
71
- ) => (type: ts.Type) => readonly ts.Expression[];
72
-
73
- const FUNCTORS: Record<string, Programmer> = {
74
- EncryptedBody: (project) => (modulo) => (parameters) => (type) =>
75
- parameters.length
76
- ? parameters
77
- : [TypedBodyProgrammer.generate(project)(modulo)(type)],
78
- TypedBody: (project) => (modulo) => (parameters) => (type) =>
79
- parameters.length
80
- ? parameters
81
- : [TypedBodyProgrammer.generate(project)(modulo)(type)],
82
- TypedHeaders: (project) => (modulo) => (parameters) => (type) =>
83
- parameters.length
84
- ? parameters
85
- : [TypedHeadersProgrammer.generate(project)(modulo)(type)],
86
- TypedParam: (project) => TypedParamProgrammer.generate(project),
87
- TypedQuery: (project) => (modulo) => (parameters) => (type) =>
88
- parameters.length
89
- ? parameters
90
- : [TypedQueryProgrammer.generate(project)(modulo)(type)],
91
- "TypedQuery.Body": (project) => (modulo) => (parameters) => (type) =>
92
- parameters.length
93
- ? parameters
94
- : [TypedQueryBodyProgrammer.generate(project)(modulo)(type)],
95
- PlainBody: (project) => (modulo) => (parameters) => (type) =>
96
- parameters.length
97
- ? parameters
98
- : [PlainBodyProgrammer.generate(project)(modulo)(type)],
99
- };
100
-
101
- const LIB_PATH = path.join(
102
- "node_modules",
103
- "@nestia",
104
- "core",
105
- "lib",
106
- "decorators",
107
- );
108
- const SRC_PATH = path.resolve(path.join(__dirname, "..", "decorators"));
109
-
110
- const getName = (symbol: ts.Symbol): string => {
111
- const parent = symbol.getDeclarations()?.[0]?.parent;
112
- return parent ? exploreName(parent)(symbol.escapedName.toString()) : "__type";
113
- };
114
- const exploreName =
115
- (decl: ts.Node) =>
116
- (name: string): string =>
117
- ts.isModuleBlock(decl)
118
- ? exploreName(decl.parent.parent)(
119
- `${decl.parent.name.getFullText().trim()}.${name}`,
120
- )
121
- : name;
1
+ import path from "path";
2
+ import ts from "typescript";
3
+
4
+ import { INestiaTransformProject } from "../options/INestiaTransformProject";
5
+ import { PlainBodyProgrammer } from "../programmers/PlainBodyProgrammer";
6
+ import { TypedBodyProgrammer } from "../programmers/TypedBodyProgrammer";
7
+ import { TypedHeadersProgrammer } from "../programmers/TypedHeadersProgrammer";
8
+ import { TypedParamProgrammer } from "../programmers/TypedParamProgrammer";
9
+ import { TypedQueryBodyProgrammer } from "../programmers/TypedQueryBodyProgrammer";
10
+ import { TypedQueryProgrammer } from "../programmers/TypedQueryProgrammer";
11
+
12
+ export namespace ParameterDecoratorTransformer {
13
+ export const transform =
14
+ (project: INestiaTransformProject) =>
15
+ (type: ts.Type) =>
16
+ (decorator: ts.Decorator): ts.Decorator => {
17
+ //----
18
+ // VALIDATIONS
19
+ //----
20
+ // CHECK DECORATOR
21
+ if (!ts.isCallExpression(decorator.expression)) return decorator;
22
+
23
+ // SIGNATURE DECLARATION
24
+ const declaration: ts.Declaration | undefined =
25
+ project.checker.getResolvedSignature(decorator.expression)?.declaration;
26
+ if (declaration === undefined) return decorator;
27
+
28
+ // FILE PATH
29
+ const file: string = path.resolve(declaration.getSourceFile().fileName);
30
+ if (file.indexOf(LIB_PATH) === -1 && file.indexOf(SRC_PATH) === -1)
31
+ return decorator;
32
+
33
+ //----
34
+ // TRANSFORMATION
35
+ //----
36
+ // FIND PROGRAMMER
37
+ const programmer: Programmer | undefined =
38
+ FUNCTORS[
39
+ getName(project.checker.getTypeAtLocation(declaration).symbol)
40
+ ];
41
+ if (programmer === undefined) return decorator;
42
+
43
+ // GET TYPE INFO
44
+ const typeNode: ts.TypeNode | undefined = project.checker.typeToTypeNode(
45
+ type,
46
+ undefined,
47
+ undefined,
48
+ );
49
+ if (typeNode === undefined) return decorator;
50
+
51
+ // DO TRANSFORM
52
+ return ts.factory.createDecorator(
53
+ ts.factory.updateCallExpression(
54
+ decorator.expression,
55
+ decorator.expression.expression,
56
+ decorator.expression.typeArguments,
57
+ programmer(project)(decorator.expression.expression)(
58
+ decorator.expression.arguments,
59
+ )(type),
60
+ ),
61
+ );
62
+ };
63
+ }
64
+
65
+ type Programmer = (
66
+ project: INestiaTransformProject,
67
+ ) => (
68
+ modulo: ts.LeftHandSideExpression,
69
+ ) => (
70
+ parameters: readonly ts.Expression[],
71
+ ) => (type: ts.Type) => readonly ts.Expression[];
72
+
73
+ const FUNCTORS: Record<string, Programmer> = {
74
+ EncryptedBody: (project) => (modulo) => (parameters) => (type) =>
75
+ parameters.length
76
+ ? parameters
77
+ : [TypedBodyProgrammer.generate(project)(modulo)(type)],
78
+ TypedBody: (project) => (modulo) => (parameters) => (type) =>
79
+ parameters.length
80
+ ? parameters
81
+ : [TypedBodyProgrammer.generate(project)(modulo)(type)],
82
+ TypedHeaders: (project) => (modulo) => (parameters) => (type) =>
83
+ parameters.length
84
+ ? parameters
85
+ : [TypedHeadersProgrammer.generate(project)(modulo)(type)],
86
+ TypedParam: (project) => TypedParamProgrammer.generate(project),
87
+ TypedQuery: (project) => (modulo) => (parameters) => (type) =>
88
+ parameters.length
89
+ ? parameters
90
+ : [TypedQueryProgrammer.generate(project)(modulo)(type)],
91
+ "TypedQuery.Body": (project) => (modulo) => (parameters) => (type) =>
92
+ parameters.length
93
+ ? parameters
94
+ : [TypedQueryBodyProgrammer.generate(project)(modulo)(type)],
95
+ PlainBody: (project) => (modulo) => (parameters) => (type) =>
96
+ parameters.length
97
+ ? parameters
98
+ : [PlainBodyProgrammer.generate(project)(modulo)(type)],
99
+ };
100
+
101
+ const LIB_PATH = path.join(
102
+ "node_modules",
103
+ "@nestia",
104
+ "core",
105
+ "lib",
106
+ "decorators",
107
+ );
108
+ const SRC_PATH = path.resolve(path.join(__dirname, "..", "decorators"));
109
+
110
+ const getName = (symbol: ts.Symbol): string => {
111
+ const parent = symbol.getDeclarations()?.[0]?.parent;
112
+ return parent ? exploreName(parent)(symbol.escapedName.toString()) : "__type";
113
+ };
114
+ const exploreName =
115
+ (decl: ts.Node) =>
116
+ (name: string): string =>
117
+ ts.isModuleBlock(decl)
118
+ ? exploreName(decl.parent.parent)(
119
+ `${decl.parent.name.getFullText().trim()}.${name}`,
120
+ )
121
+ : name;