@nestia/core 3.17.0 → 4.0.0-dev.20241010

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 (87) hide show
  1. package/README.md +0 -1
  2. package/lib/options/INestiaTransformProject.d.ts +2 -2
  3. package/lib/programmers/PlainBodyProgrammer.d.ts +6 -2
  4. package/lib/programmers/PlainBodyProgrammer.js +31 -13
  5. package/lib/programmers/PlainBodyProgrammer.js.map +1 -1
  6. package/lib/programmers/TypedBodyProgrammer.d.ts +6 -2
  7. package/lib/programmers/TypedBodyProgrammer.js +32 -13
  8. package/lib/programmers/TypedBodyProgrammer.js.map +1 -1
  9. package/lib/programmers/TypedFormDataBodyProgrammer.d.ts +6 -2
  10. package/lib/programmers/TypedFormDataBodyProgrammer.js +30 -17
  11. package/lib/programmers/TypedFormDataBodyProgrammer.js.map +1 -1
  12. package/lib/programmers/TypedHeadersProgrammer.d.ts +6 -2
  13. package/lib/programmers/TypedHeadersProgrammer.js +12 -7
  14. package/lib/programmers/TypedHeadersProgrammer.js.map +1 -1
  15. package/lib/programmers/TypedParamProgrammer.d.ts +7 -2
  16. package/lib/programmers/TypedParamProgrammer.js +12 -7
  17. package/lib/programmers/TypedParamProgrammer.js.map +1 -1
  18. package/lib/programmers/TypedQueryBodyProgrammer.d.ts +6 -2
  19. package/lib/programmers/TypedQueryBodyProgrammer.js +12 -7
  20. package/lib/programmers/TypedQueryBodyProgrammer.js.map +1 -1
  21. package/lib/programmers/TypedQueryProgrammer.d.ts +6 -2
  22. package/lib/programmers/TypedQueryProgrammer.js +13 -7
  23. package/lib/programmers/TypedQueryProgrammer.js.map +1 -1
  24. package/lib/programmers/TypedQueryRouteProgrammer.d.ts +6 -2
  25. package/lib/programmers/TypedQueryRouteProgrammer.js +10 -6
  26. package/lib/programmers/TypedQueryRouteProgrammer.js.map +1 -1
  27. package/lib/programmers/TypedRouteProgrammer.d.ts +6 -2
  28. package/lib/programmers/TypedRouteProgrammer.js +14 -9
  29. package/lib/programmers/TypedRouteProgrammer.js.map +1 -1
  30. package/lib/programmers/http/HttpAssertQuerifyProgrammer.d.ts +6 -2
  31. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js +22 -3
  32. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js.map +1 -1
  33. package/lib/programmers/http/HttpIsQuerifyProgrammer.d.ts +6 -2
  34. package/lib/programmers/http/HttpIsQuerifyProgrammer.js +21 -3
  35. package/lib/programmers/http/HttpIsQuerifyProgrammer.js.map +1 -1
  36. package/lib/programmers/http/HttpQuerifyProgrammer.d.ts +6 -2
  37. package/lib/programmers/http/HttpQuerifyProgrammer.js +27 -15
  38. package/lib/programmers/http/HttpQuerifyProgrammer.js.map +1 -1
  39. package/lib/programmers/http/HttpValidateQuerifyProgrammer.d.ts +6 -2
  40. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js +25 -4
  41. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js.map +1 -1
  42. package/lib/transform.d.ts +2 -2
  43. package/lib/transform.js.map +1 -1
  44. package/lib/transformers/FileTransformer.d.ts +2 -2
  45. package/lib/transformers/FileTransformer.js +24 -10
  46. package/lib/transformers/FileTransformer.js.map +1 -1
  47. package/lib/transformers/MethodTransformer.d.ts +5 -2
  48. package/lib/transformers/MethodTransformer.js +21 -14
  49. package/lib/transformers/MethodTransformer.js.map +1 -1
  50. package/lib/transformers/NodeTransformer.d.ts +5 -2
  51. package/lib/transformers/NodeTransformer.js +11 -5
  52. package/lib/transformers/NodeTransformer.js.map +1 -1
  53. package/lib/transformers/ParameterDecoratorTransformer.d.ts +6 -2
  54. package/lib/transformers/ParameterDecoratorTransformer.js +49 -40
  55. package/lib/transformers/ParameterDecoratorTransformer.js.map +1 -1
  56. package/lib/transformers/ParameterTransformer.d.ts +5 -2
  57. package/lib/transformers/ParameterTransformer.js +17 -9
  58. package/lib/transformers/ParameterTransformer.js.map +1 -1
  59. package/lib/transformers/TypedRouteTransformer.d.ts +6 -2
  60. package/lib/transformers/TypedRouteTransformer.js +20 -16
  61. package/lib/transformers/TypedRouteTransformer.js.map +1 -1
  62. package/lib/transformers/WebSocketRouteTransformer.d.ts +6 -2
  63. package/lib/transformers/WebSocketRouteTransformer.js +11 -11
  64. package/lib/transformers/WebSocketRouteTransformer.js.map +1 -1
  65. package/package.json +5 -5
  66. package/src/options/INestiaTransformProject.ts +3 -2
  67. package/src/programmers/PlainBodyProgrammer.ts +32 -13
  68. package/src/programmers/TypedBodyProgrammer.ts +106 -82
  69. package/src/programmers/TypedFormDataBodyProgrammer.ts +87 -77
  70. package/src/programmers/TypedHeadersProgrammer.ts +48 -41
  71. package/src/programmers/TypedParamProgrammer.ts +21 -15
  72. package/src/programmers/TypedQueryBodyProgrammer.ts +48 -41
  73. package/src/programmers/TypedQueryProgrammer.ts +50 -45
  74. package/src/programmers/TypedQueryRouteProgrammer.ts +44 -39
  75. package/src/programmers/TypedRouteProgrammer.ts +63 -61
  76. package/src/programmers/http/HttpAssertQuerifyProgrammer.ts +54 -40
  77. package/src/programmers/http/HttpIsQuerifyProgrammer.ts +54 -41
  78. package/src/programmers/http/HttpQuerifyProgrammer.ts +60 -48
  79. package/src/programmers/http/HttpValidateQuerifyProgrammer.ts +54 -41
  80. package/src/transform.ts +2 -2
  81. package/src/transformers/FileTransformer.ts +68 -46
  82. package/src/transformers/MethodTransformer.ts +56 -51
  83. package/src/transformers/NodeTransformer.ts +16 -9
  84. package/src/transformers/ParameterDecoratorTransformer.ts +100 -91
  85. package/src/transformers/ParameterTransformer.ts +47 -38
  86. package/src/transformers/TypedRouteTransformer.ts +58 -55
  87. package/src/transformers/WebSocketRouteTransformer.ts +81 -78
@@ -1,16 +1,23 @@
1
1
  import ts from "typescript";
2
2
 
3
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
3
+ import { INestiaTransformContext } from "../options/INestiaTransformProject";
4
4
  import { MethodTransformer } from "./MethodTransformer";
5
5
  import { ParameterTransformer } from "./ParameterTransformer";
6
6
 
7
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;
8
+ export const transform = (props: {
9
+ context: INestiaTransformContext;
10
+ node: ts.Node;
11
+ }): ts.Node =>
12
+ ts.isMethodDeclaration(props.node)
13
+ ? MethodTransformer.transform({
14
+ context: props.context,
15
+ method: props.node,
16
+ })
17
+ : ts.isParameter(props.node)
18
+ ? ParameterTransformer.transform({
19
+ context: props.context,
20
+ param: props.node,
21
+ })
22
+ : props.node;
16
23
  }
@@ -1,7 +1,7 @@
1
1
  import path from "path";
2
2
  import ts from "typescript";
3
3
 
4
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
+ import { INestiaTransformContext } from "../options/INestiaTransformProject";
5
5
  import { PlainBodyProgrammer } from "../programmers/PlainBodyProgrammer";
6
6
  import { TypedBodyProgrammer } from "../programmers/TypedBodyProgrammer";
7
7
  import { TypedFormDataBodyProgrammer } from "../programmers/TypedFormDataBodyProgrammer";
@@ -11,105 +11,114 @@ import { TypedQueryBodyProgrammer } from "../programmers/TypedQueryBodyProgramme
11
11
  import { TypedQueryProgrammer } from "../programmers/TypedQueryProgrammer";
12
12
 
13
13
  export namespace ParameterDecoratorTransformer {
14
- export const transform =
15
- (project: INestiaTransformProject) =>
16
- (type: ts.Type) =>
17
- (decorator: ts.Decorator): ts.Decorator => {
18
- //----
19
- // VALIDATIONS
20
- //----
21
- // CHECK DECORATOR
22
- if (!ts.isCallExpression(decorator.expression)) return decorator;
14
+ export const transform = (props: {
15
+ context: INestiaTransformContext;
16
+ type: ts.Type;
17
+ decorator: ts.Decorator;
18
+ }): ts.Decorator => {
19
+ //----
20
+ // VALIDATIONS
21
+ //----
22
+ // CHECK DECORATOR
23
+ if (!ts.isCallExpression(props.decorator.expression))
24
+ return props.decorator;
23
25
 
24
- // SIGNATURE DECLARATION
25
- const declaration: ts.Declaration | undefined =
26
- project.checker.getResolvedSignature(decorator.expression)?.declaration;
27
- if (declaration === undefined) return decorator;
26
+ // SIGNATURE DECLARATION
27
+ const declaration: ts.Declaration | undefined =
28
+ props.context.checker.getResolvedSignature(
29
+ props.decorator.expression,
30
+ )?.declaration;
31
+ if (declaration === undefined) return props.decorator;
28
32
 
29
- // FILE PATH
30
- const file: string = path.resolve(declaration.getSourceFile().fileName);
31
- if (file.indexOf(LIB_PATH) === -1 && file.indexOf(SRC_PATH) === -1)
32
- return decorator;
33
+ // FILE PATH
34
+ const file: string = path.resolve(declaration.getSourceFile().fileName);
35
+ if (file.indexOf(LIB_PATH) === -1 && file.indexOf(SRC_PATH) === -1)
36
+ return props.decorator;
33
37
 
34
- //----
35
- // TRANSFORMATION
36
- //----
37
- // FIND PROGRAMMER
38
- const programmer: Programmer | undefined =
39
- FUNCTORS[
40
- getName(project.checker.getTypeAtLocation(declaration).symbol)
41
- ];
42
- if (programmer === undefined) return decorator;
38
+ //----
39
+ // TRANSFORMATION
40
+ //----
41
+ // FIND PROGRAMMER
42
+ const programmer: Programmer | undefined =
43
+ FUNCTORS[
44
+ getName(props.context.checker.getTypeAtLocation(declaration).symbol)
45
+ ];
46
+ if (programmer === undefined) return props.decorator;
43
47
 
44
- // GET TYPE INFO
45
- const typeNode: ts.TypeNode | undefined = project.checker.typeToTypeNode(
46
- type,
47
- undefined,
48
- undefined,
49
- );
50
- if (typeNode === undefined) return decorator;
48
+ // GET TYPE INFO
49
+ const typeNode: ts.TypeNode | undefined =
50
+ props.context.checker.typeToTypeNode(props.type, undefined, undefined);
51
+ if (typeNode === undefined) return props.decorator;
51
52
 
52
- // DO TRANSFORM
53
- return ts.factory.createDecorator(
54
- ts.factory.updateCallExpression(
55
- decorator.expression,
56
- decorator.expression.expression,
57
- decorator.expression.typeArguments,
58
- programmer(project)(decorator.expression.expression)(
59
- decorator.expression.arguments,
60
- )(type),
61
- ),
62
- );
63
- };
53
+ // DO TRANSFORM
54
+ return ts.factory.createDecorator(
55
+ ts.factory.updateCallExpression(
56
+ props.decorator.expression,
57
+ props.decorator.expression.expression,
58
+ props.decorator.expression.typeArguments,
59
+ programmer({
60
+ context: props.context,
61
+ modulo: props.decorator.expression.expression,
62
+ arguments: props.decorator.expression.arguments,
63
+ type: props.type,
64
+ }),
65
+ ),
66
+ );
67
+ };
64
68
  }
65
69
 
66
- type Programmer = (
67
- project: INestiaTransformProject,
68
- ) => (
69
- modulo: ts.LeftHandSideExpression,
70
- ) => (
71
- parameters: readonly ts.Expression[],
72
- ) => (type: ts.Type) => readonly ts.Expression[];
70
+ type Programmer = (props: {
71
+ context: INestiaTransformContext;
72
+ modulo: ts.LeftHandSideExpression;
73
+ arguments: readonly ts.Expression[];
74
+ type: ts.Type;
75
+ }) => readonly ts.Expression[];
73
76
 
74
77
  const FUNCTORS: Record<string, Programmer> = {
75
- EncryptedBody: (project) => (modulo) => (parameters) => (type) =>
76
- parameters.length
77
- ? parameters
78
- : [TypedBodyProgrammer.generate(project)(modulo)(type)],
79
- TypedBody: (project) => (modulo) => (parameters) => (type) =>
80
- parameters.length
81
- ? parameters
82
- : [TypedBodyProgrammer.generate(project)(modulo)(type)],
83
- TypedHeaders: (project) => (modulo) => (parameters) => (type) =>
84
- parameters.length
85
- ? parameters
86
- : [TypedHeadersProgrammer.generate(project)(modulo)(type)],
87
- TypedParam: (project) => TypedParamProgrammer.generate(project),
88
- TypedQuery: (project) => (modulo) => (parameters) => (type) =>
89
- parameters.length
90
- ? parameters
91
- : [TypedQueryProgrammer.generate(project)(modulo)(type)],
92
- "TypedQuery.Body": (project) => (modulo) => (parameters) => (type) =>
93
- parameters.length
94
- ? parameters
95
- : [TypedQueryBodyProgrammer.generate(project)(modulo)(type)],
96
- "TypedFormData.Body": (project) => (modulo) => (parameters) => (type) =>
97
- parameters.length
98
- ? parameters
99
- : [TypedFormDataBodyProgrammer.generate(project)(modulo)(type)],
100
- PlainBody: (project) => (modulo) => (parameters) => (type) =>
101
- parameters.length
102
- ? parameters
103
- : [PlainBodyProgrammer.generate(project)(modulo)(type)],
104
- "WebSocketRoute.Header": (project) => (modulo) => (parameters) => (type) =>
105
- parameters.length
106
- ? parameters
107
- : [TypedBodyProgrammer.generate(project)(modulo)(type)],
108
- "WebSocketRoute.Param": (project) => TypedParamProgrammer.generate(project),
109
- "WebSocketRoute.Query": (project) => (modulo) => (parameters) => (type) =>
110
- parameters.length
111
- ? parameters
112
- : [TypedQueryProgrammer.generate(project)(modulo)(type)],
78
+ EncryptedBody: (props) =>
79
+ props.arguments.length
80
+ ? props.arguments
81
+ : [TypedBodyProgrammer.generate(props)],
82
+ TypedBody: (props) =>
83
+ props.arguments.length
84
+ ? props.arguments
85
+ : [TypedBodyProgrammer.generate(props)],
86
+ TypedHeaders: (props) =>
87
+ props.arguments.length
88
+ ? props.arguments
89
+ : [TypedHeadersProgrammer.generate(props)],
90
+ TypedParam: (props) =>
91
+ props.arguments.length !== 1
92
+ ? props.arguments
93
+ : TypedParamProgrammer.generate(props),
94
+ TypedQuery: (props) =>
95
+ props.arguments.length
96
+ ? props.arguments
97
+ : [TypedQueryProgrammer.generate(props)],
98
+ "TypedQuery.Body": (props) =>
99
+ props.arguments.length
100
+ ? props.arguments
101
+ : [TypedQueryBodyProgrammer.generate(props)],
102
+ "TypedFormData.Body": (props) =>
103
+ props.arguments.length
104
+ ? props.arguments
105
+ : [TypedFormDataBodyProgrammer.generate(props)],
106
+ PlainBody: (props) =>
107
+ props.arguments.length
108
+ ? props.arguments
109
+ : [PlainBodyProgrammer.generate(props)],
110
+ "WebSocketRoute.Header": (props) =>
111
+ props.arguments.length
112
+ ? props.arguments
113
+ : [TypedBodyProgrammer.generate(props)],
114
+ "WebSocketRoute.Param": (props) =>
115
+ props.arguments.length !== 1
116
+ ? props.arguments
117
+ : TypedParamProgrammer.generate(props),
118
+ "WebSocketRoute.Query": (props) =>
119
+ props.arguments.length
120
+ ? props.arguments
121
+ : [TypedQueryProgrammer.generate(props)],
113
122
  };
114
123
 
115
124
  const LIB_PATH = path.join("@nestia", "core", "lib", "decorators");
@@ -1,48 +1,57 @@
1
1
  import ts from "typescript";
2
2
 
3
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
3
+ import { INestiaTransformContext } from "../options/INestiaTransformProject";
4
4
  import { ParameterDecoratorTransformer } from "./ParameterDecoratorTransformer";
5
5
 
6
6
  export namespace ParameterTransformer {
7
- export const transform =
8
- (project: INestiaTransformProject) =>
9
- (param: ts.ParameterDeclaration): ts.ParameterDeclaration => {
10
- // CHECK DECORATOR
11
- const decorators: readonly ts.Decorator[] | undefined = ts.getDecorators
12
- ? ts.getDecorators(param)
13
- : (param as any).decorators;
14
- if (!decorators?.length) return param;
7
+ export const transform = (props: {
8
+ context: INestiaTransformContext;
9
+ param: ts.ParameterDeclaration;
10
+ }): ts.ParameterDeclaration => {
11
+ // CHECK DECORATOR
12
+ const decorators: readonly ts.Decorator[] | undefined = ts.getDecorators
13
+ ? ts.getDecorators(props.param)
14
+ : (props.param as any).decorators;
15
+ if (!decorators?.length) return props.param;
15
16
 
16
- // GET TYPE INFO
17
- const type: ts.Type = project.checker.getTypeAtLocation(param);
17
+ // GET TYPE INFO
18
+ const type: ts.Type = props.context.checker.getTypeAtLocation(props.param);
18
19
 
19
- // WHEN LATEST TS VERSION
20
- if (ts.getDecorators !== undefined)
21
- return ts.factory.updateParameterDeclaration(
22
- param,
23
- (param.modifiers || []).map((mod) =>
24
- ts.isDecorator(mod)
25
- ? ParameterDecoratorTransformer.transform(project)(type)(mod)
26
- : mod,
27
- ),
28
- param.dotDotDotToken,
29
- param.name,
30
- param.questionToken,
31
- param.type,
32
- param.initializer,
33
- );
34
- // eslint-disable-next-line
35
- return (ts.factory.updateParameterDeclaration as any)(
36
- param,
37
- decorators.map((deco) =>
38
- ParameterDecoratorTransformer.transform(project)(type)(deco),
20
+ // WHEN LATEST TS VERSION
21
+ if (ts.getDecorators !== undefined)
22
+ return ts.factory.updateParameterDeclaration(
23
+ props.param,
24
+ (props.param.modifiers || []).map((mod) =>
25
+ ts.isDecorator(mod)
26
+ ? ParameterDecoratorTransformer.transform({
27
+ context: props.context,
28
+ decorator: mod,
29
+ type,
30
+ })
31
+ : mod,
39
32
  ),
40
- (param as any).modifiers,
41
- param.dotDotDotToken,
42
- param.name,
43
- param.questionToken,
44
- param.type,
45
- param.initializer,
33
+ props.param.dotDotDotToken,
34
+ props.param.name,
35
+ props.param.questionToken,
36
+ props.param.type,
37
+ props.param.initializer,
46
38
  );
47
- };
39
+ // eslint-disable-next-line
40
+ return (ts.factory.updateParameterDeclaration as any)(
41
+ props.param,
42
+ decorators.map((deco) =>
43
+ ParameterDecoratorTransformer.transform({
44
+ context: props.context,
45
+ decorator: deco,
46
+ type,
47
+ }),
48
+ ),
49
+ (props.param as any).modifiers,
50
+ props.param.dotDotDotToken,
51
+ props.param.name,
52
+ props.param.questionToken,
53
+ props.param.type,
54
+ props.param.initializer,
55
+ );
56
+ };
48
57
  }
@@ -1,70 +1,73 @@
1
1
  import path from "path";
2
2
  import ts from "typescript";
3
3
 
4
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
+ import { INestiaTransformContext } from "../options/INestiaTransformProject";
5
5
  import { TypedQueryRouteProgrammer } from "../programmers/TypedQueryRouteProgrammer";
6
6
  import { TypedRouteProgrammer } from "../programmers/TypedRouteProgrammer";
7
7
 
8
8
  export namespace TypedRouteTransformer {
9
- export const transform =
10
- (project: INestiaTransformProject) =>
11
- (type: ts.Type) =>
12
- (decorator: ts.Decorator): ts.Decorator => {
13
- if (!ts.isCallExpression(decorator.expression)) return decorator;
9
+ export const transform = (props: {
10
+ context: INestiaTransformContext;
11
+ decorator: ts.Decorator;
12
+ type: ts.Type;
13
+ }): ts.Decorator => {
14
+ if (!ts.isCallExpression(props.decorator.expression))
15
+ return props.decorator;
14
16
 
15
- // CHECK SIGNATURE
16
- const signature: ts.Signature | undefined =
17
- project.checker.getResolvedSignature(decorator.expression);
18
- if (!signature || !signature.declaration) return decorator;
17
+ // CHECK SIGNATURE
18
+ const signature: ts.Signature | undefined =
19
+ props.context.checker.getResolvedSignature(props.decorator.expression);
20
+ if (!signature || !signature.declaration) return props.decorator;
19
21
 
20
- // CHECK TO BE TRANSFORMED
21
- const modulo = (() => {
22
- // CHECK FILENAME
23
- const location: string = path.resolve(
24
- signature.declaration.getSourceFile().fileName,
25
- );
26
- if (LIB_PATHS.every((str) => location.indexOf(str) === -1)) return null;
22
+ // CHECK TO BE TRANSFORMED
23
+ const modulo = (() => {
24
+ // CHECK FILENAME
25
+ const location: string = path.resolve(
26
+ signature.declaration.getSourceFile().fileName,
27
+ );
28
+ if (LIB_PATHS.every((str) => location.indexOf(str) === -1)) return null;
27
29
 
28
- // CHECK DUPLICATE BOOSTER
29
- if (decorator.expression.arguments.length >= 2) return false;
30
- else if (decorator.expression.arguments.length === 1) {
31
- const last: ts.Expression =
32
- decorator.expression.arguments[
33
- decorator.expression.arguments.length - 1
34
- ];
35
- const type: ts.Type = project.checker.getTypeAtLocation(last);
36
- if (isObject(project.checker)(type)) return false;
37
- }
38
- return location.split(path.sep).at(-1)?.split(".")[0] === "TypedQuery"
39
- ? "TypedQuery"
40
- : "TypedRoute";
41
- })();
42
- if (modulo === null) return decorator;
30
+ // CHECK DUPLICATE BOOSTER
31
+ if (props.decorator.expression.arguments.length >= 2) return false;
32
+ else if (props.decorator.expression.arguments.length === 1) {
33
+ const last: ts.Expression =
34
+ props.decorator.expression.arguments[
35
+ props.decorator.expression.arguments.length - 1
36
+ ];
37
+ const type: ts.Type = props.context.checker.getTypeAtLocation(last);
38
+ if (isObject(props.context.checker)(type)) return false;
39
+ }
40
+ return location.split(path.sep).at(-1)?.split(".")[0] === "TypedQuery"
41
+ ? "TypedQuery"
42
+ : "TypedRoute";
43
+ })();
44
+ if (modulo === null) return props.decorator;
43
45
 
44
- // CHECK TYPE NODE
45
- const typeNode: ts.TypeNode | undefined = project.checker.typeToTypeNode(
46
- type,
47
- undefined,
48
- undefined,
49
- );
50
- if (typeNode === undefined) return decorator;
46
+ // CHECK TYPE NODE
47
+ const typeNode: ts.TypeNode | undefined =
48
+ props.context.checker.typeToTypeNode(props.type, undefined, undefined);
49
+ if (typeNode === undefined) return props.decorator;
51
50
 
52
- // DO TRANSFORM
53
- return ts.factory.createDecorator(
54
- ts.factory.updateCallExpression(
55
- decorator.expression,
56
- decorator.expression.expression,
57
- decorator.expression.typeArguments,
58
- [
59
- ...decorator.expression.arguments,
60
- (modulo === "TypedQuery"
61
- ? TypedQueryRouteProgrammer
62
- : TypedRouteProgrammer
63
- ).generate(project)(decorator.expression.expression)(type),
64
- ],
65
- ),
66
- );
67
- };
51
+ // DO TRANSFORM
52
+ return ts.factory.createDecorator(
53
+ ts.factory.updateCallExpression(
54
+ props.decorator.expression,
55
+ props.decorator.expression.expression,
56
+ props.decorator.expression.typeArguments,
57
+ [
58
+ ...props.decorator.expression.arguments,
59
+ (modulo === "TypedQuery"
60
+ ? TypedQueryRouteProgrammer
61
+ : TypedRouteProgrammer
62
+ ).generate({
63
+ context: props.context,
64
+ type: props.type,
65
+ modulo: props.decorator.expression.expression,
66
+ }),
67
+ ],
68
+ ),
69
+ );
70
+ };
68
71
 
69
72
  const isObject =
70
73
  (checker: ts.TypeChecker) =>
@@ -1,94 +1,97 @@
1
1
  import path from "path";
2
2
  import ts from "typescript";
3
3
 
4
- import { INestiaTransformProject } from "../options/INestiaTransformProject";
4
+ import { INestiaTransformContext } from "../options/INestiaTransformProject";
5
5
 
6
6
  export namespace WebSocketRouteTransformer {
7
- export const validate =
8
- (project: INestiaTransformProject) =>
9
- (decorator: ts.Decorator, method: ts.MethodDeclaration): ts.Decorator => {
10
- if (!ts.isCallExpression(decorator.expression)) return decorator;
7
+ export const validate = (props: {
8
+ context: INestiaTransformContext;
9
+ decorator: ts.Decorator;
10
+ method: ts.MethodDeclaration;
11
+ }): ts.Decorator => {
12
+ if (!ts.isCallExpression(props.decorator.expression))
13
+ return props.decorator;
11
14
 
12
- // CHECK SIGNATURE
13
- const signature: ts.Signature | undefined =
14
- project.checker.getResolvedSignature(decorator.expression);
15
- if (!signature || !signature.declaration) return decorator;
16
- else if (isLocated(signature) === false) return decorator;
15
+ // CHECK SIGNATURE
16
+ const signature: ts.Signature | undefined =
17
+ props.context.checker.getResolvedSignature(props.decorator.expression);
18
+ if (!signature || !signature.declaration) return props.decorator;
19
+ else if (isLocated(signature) === false) return props.decorator;
17
20
 
18
- const errors: ts.DiagnosticWithLocation[] = [];
19
- let accepted: boolean = false;
21
+ const errors: ts.DiagnosticWithLocation[] = [];
22
+ let accepted: boolean = false;
20
23
 
21
- const report = (node: ts.Node, message: string) => {
22
- errors.push(
23
- (ts as any).createDiagnosticForNode(node, {
24
- category: ts.DiagnosticCategory.Error,
25
- key: "nestia.core.WebSocketRoute",
26
- code: "(nestia.core.WebSocketRoute)" as any,
27
- message,
28
- }),
24
+ const report = (node: ts.Node, message: string) => {
25
+ errors.push(
26
+ (ts as any).createDiagnosticForNode(node, {
27
+ category: ts.DiagnosticCategory.Error,
28
+ key: "nestia.core.WebSocketRoute",
29
+ code: "(nestia.core.WebSocketRoute)" as any,
30
+ message,
31
+ }),
32
+ );
33
+ };
34
+ props.method.parameters.forEach((param) => {
35
+ const paramDecos: ts.Decorator[] = (param.modifiers ?? []).filter((m) =>
36
+ ts.isDecorator(m),
37
+ ) as ts.Decorator[];
38
+ const category: string | null = (() => {
39
+ if (paramDecos.length !== 1) return null;
40
+ const decorator: ts.Decorator = paramDecos[0];
41
+ const signature: ts.Signature | undefined = ts.isCallExpression(
42
+ decorator.expression,
43
+ )
44
+ ? props.context.checker.getResolvedSignature(decorator.expression)
45
+ : undefined;
46
+ if (signature === undefined || isLocated(signature) === false)
47
+ return null;
48
+ return (
49
+ decorator.expression.getText().split(".").at(-1)?.split("(")[0] ??
50
+ null
51
+ );
52
+ })();
53
+ if (category === null)
54
+ report(
55
+ param,
56
+ `parameter ${JSON.stringify(param.name.getText())} is not decorated with nested function of WebSocketRoute module.`,
29
57
  );
30
- };
31
- method.parameters.forEach((param) => {
32
- const paramDecos: ts.Decorator[] = (param.modifiers ?? []).filter((m) =>
33
- ts.isDecorator(m),
34
- ) as ts.Decorator[];
35
- const category: string | null = (() => {
36
- if (paramDecos.length !== 1) return null;
37
- const decorator: ts.Decorator = paramDecos[0];
38
- const signature: ts.Signature | undefined = ts.isCallExpression(
39
- decorator.expression,
40
- )
41
- ? project.checker.getResolvedSignature(decorator.expression)
42
- : undefined;
43
- if (signature === undefined || isLocated(signature) === false)
44
- return null;
45
- return (
46
- decorator.expression.getText().split(".").at(-1)?.split("(")[0] ??
47
- null
58
+ else if (category === "Acceptor") {
59
+ accepted = true;
60
+ if (
61
+ param.type
62
+ ?.getText()
63
+ .split("<")[0]
64
+ ?.split(".")
65
+ .at(-1)
66
+ ?.startsWith("WebSocketAcceptor") !== true
67
+ )
68
+ report(
69
+ param,
70
+ `parameter ${JSON.stringify(param.name.getText())} must have WebSocketAcceptor<Header, Provider, Listener> type.`,
48
71
  );
49
- })();
50
- if (category === null)
72
+ } else if (category === "Driver") {
73
+ if (
74
+ param.type
75
+ ?.getText()
76
+ .split("<")[0]
77
+ ?.split(".")
78
+ .at(-1)
79
+ ?.startsWith("Driver") !== true
80
+ )
51
81
  report(
52
82
  param,
53
- `parameter ${JSON.stringify(param.name.getText())} is not decorated with nested function of WebSocketRoute module.`,
83
+ `parameter ${JSON.stringify(param.name.getText())} must have Driver<Listener> type.`,
54
84
  );
55
- else if (category === "Acceptor") {
56
- accepted = true;
57
- if (
58
- param.type
59
- ?.getText()
60
- .split("<")[0]
61
- ?.split(".")
62
- .at(-1)
63
- ?.startsWith("WebSocketAcceptor") !== true
64
- )
65
- report(
66
- param,
67
- `parameter ${JSON.stringify(param.name.getText())} must have WebSocketAcceptor<Header, Provider, Listener> type.`,
68
- );
69
- } else if (category === "Driver") {
70
- if (
71
- param.type
72
- ?.getText()
73
- .split("<")[0]
74
- ?.split(".")
75
- .at(-1)
76
- ?.startsWith("Driver") !== true
77
- )
78
- report(
79
- param,
80
- `parameter ${JSON.stringify(param.name.getText())} must have Driver<Listener> type.`,
81
- );
82
- }
83
- });
84
- if (accepted === false)
85
- report(
86
- method,
87
- `method ${JSON.stringify(method.name.getText())} must have at least one parameter decorated by @WebSocketRoute.Acceptor().`,
88
- );
89
- for (const e of errors) project.extras.addDiagnostic(e);
90
- return decorator;
91
- };
85
+ }
86
+ });
87
+ if (accepted === false)
88
+ report(
89
+ props.method,
90
+ `method ${JSON.stringify(props.method.name.getText())} must have at least one parameter decorated by @WebSocketRoute.Acceptor().`,
91
+ );
92
+ for (const e of errors) props.context.extras.addDiagnostic(e);
93
+ return props.decorator;
94
+ };
92
95
  }
93
96
 
94
97
  const isLocated = (signature: ts.Signature) => {