@nestia/core 3.0.5 → 3.1.0-dev.20240426

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 (139) hide show
  1. package/lib/adaptors/WebSocketAdaptor.d.ts +21 -0
  2. package/lib/adaptors/WebSocketAdaptor.js +277 -0
  3. package/lib/adaptors/WebSocketAdaptor.js.map +1 -0
  4. package/lib/decorators/DynamicModule.js +12 -59
  5. package/lib/decorators/DynamicModule.js.map +1 -1
  6. package/lib/decorators/EncryptedBody.js +36 -73
  7. package/lib/decorators/EncryptedBody.js.map +1 -1
  8. package/lib/decorators/EncryptedController.js +2 -2
  9. package/lib/decorators/EncryptedController.js.map +1 -1
  10. package/lib/decorators/EncryptedModule.js +24 -107
  11. package/lib/decorators/EncryptedModule.js.map +1 -1
  12. package/lib/decorators/EncryptedRoute.js +43 -119
  13. package/lib/decorators/EncryptedRoute.js.map +1 -1
  14. package/lib/decorators/PlainBody.js +24 -61
  15. package/lib/decorators/PlainBody.js.map +1 -1
  16. package/lib/decorators/SwaggerCustomizer.js +2 -2
  17. package/lib/decorators/SwaggerCustomizer.js.map +1 -1
  18. package/lib/decorators/TypedBody.js +12 -14
  19. package/lib/decorators/TypedBody.js.map +1 -1
  20. package/lib/decorators/TypedException.js +5 -5
  21. package/lib/decorators/TypedException.js.map +1 -1
  22. package/lib/decorators/TypedFormData.js +88 -291
  23. package/lib/decorators/TypedFormData.js.map +1 -1
  24. package/lib/decorators/TypedHeaders.js +6 -6
  25. package/lib/decorators/TypedHeaders.js.map +1 -1
  26. package/lib/decorators/TypedParam.d.ts +5 -6
  27. package/lib/decorators/TypedParam.js +14 -15
  28. package/lib/decorators/TypedParam.js.map +1 -1
  29. package/lib/decorators/TypedQuery.d.ts +2 -2
  30. package/lib/decorators/TypedQuery.js +52 -129
  31. package/lib/decorators/TypedQuery.js.map +1 -1
  32. package/lib/decorators/TypedRoute.js +31 -107
  33. package/lib/decorators/TypedRoute.js.map +1 -1
  34. package/lib/decorators/WebSocketRoute.d.ts +120 -0
  35. package/lib/decorators/WebSocketRoute.js +202 -0
  36. package/lib/decorators/WebSocketRoute.js.map +1 -0
  37. package/lib/decorators/internal/IWebSocketRouteReflect.d.ts +25 -0
  38. package/lib/decorators/internal/IWebSocketRouteReflect.js +3 -0
  39. package/lib/decorators/internal/IWebSocketRouteReflect.js.map +1 -0
  40. package/lib/decorators/internal/NoTransformConfigureError.js +1 -1
  41. package/lib/decorators/internal/NoTransformConfigureError.js.map +1 -1
  42. package/lib/decorators/internal/get_path_and_querify.js +67 -131
  43. package/lib/decorators/internal/get_path_and_querify.js.map +1 -1
  44. package/lib/decorators/internal/get_path_and_stringify.js +57 -71
  45. package/lib/decorators/internal/get_path_and_stringify.js.map +1 -1
  46. package/lib/decorators/internal/get_text_body.js +7 -46
  47. package/lib/decorators/internal/get_text_body.js.map +1 -1
  48. package/lib/decorators/internal/headers_to_object.js +3 -42
  49. package/lib/decorators/internal/headers_to_object.js.map +1 -1
  50. package/lib/decorators/internal/load_controller.js +29 -106
  51. package/lib/decorators/internal/load_controller.js.map +1 -1
  52. package/lib/decorators/internal/route_error.js +15 -65
  53. package/lib/decorators/internal/route_error.js.map +1 -1
  54. package/lib/decorators/internal/validate_request_body.js +44 -54
  55. package/lib/decorators/internal/validate_request_body.js.map +1 -1
  56. package/lib/decorators/internal/validate_request_form_data.js +36 -44
  57. package/lib/decorators/internal/validate_request_form_data.js.map +1 -1
  58. package/lib/decorators/internal/validate_request_headers.js +36 -44
  59. package/lib/decorators/internal/validate_request_headers.js.map +1 -1
  60. package/lib/decorators/internal/validate_request_query.js +36 -44
  61. package/lib/decorators/internal/validate_request_query.js.map +1 -1
  62. package/lib/index.js +1 -1
  63. package/lib/index.js.map +1 -1
  64. package/lib/module.d.ts +10 -9
  65. package/lib/module.js +10 -9
  66. package/lib/module.js.map +1 -1
  67. package/lib/programmers/PlainBodyProgrammer.js +29 -44
  68. package/lib/programmers/PlainBodyProgrammer.js.map +1 -1
  69. package/lib/programmers/TypedBodyProgrammer.js +57 -82
  70. package/lib/programmers/TypedBodyProgrammer.js.map +1 -1
  71. package/lib/programmers/TypedExceptionProgrammer.js +51 -54
  72. package/lib/programmers/TypedExceptionProgrammer.js.map +1 -1
  73. package/lib/programmers/TypedFormDataBodyProgrammer.js +50 -73
  74. package/lib/programmers/TypedFormDataBodyProgrammer.js.map +1 -1
  75. package/lib/programmers/TypedHeadersProgrammer.js +24 -43
  76. package/lib/programmers/TypedHeadersProgrammer.js.map +1 -1
  77. package/lib/programmers/TypedParamProgrammer.js +11 -28
  78. package/lib/programmers/TypedParamProgrammer.js.map +1 -1
  79. package/lib/programmers/TypedQueryBodyProgrammer.js +24 -43
  80. package/lib/programmers/TypedQueryBodyProgrammer.js.map +1 -1
  81. package/lib/programmers/TypedQueryProgrammer.js +24 -43
  82. package/lib/programmers/TypedQueryProgrammer.js.map +1 -1
  83. package/lib/programmers/TypedQueryRouteProgrammer.js +22 -39
  84. package/lib/programmers/TypedQueryRouteProgrammer.js.map +1 -1
  85. package/lib/programmers/TypedRouteProgrammer.js +22 -39
  86. package/lib/programmers/TypedRouteProgrammer.js.map +1 -1
  87. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js +12 -29
  88. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js.map +1 -1
  89. package/lib/programmers/http/HttpIsQuerifyProgrammer.js +10 -27
  90. package/lib/programmers/http/HttpIsQuerifyProgrammer.js.map +1 -1
  91. package/lib/programmers/http/HttpQuerifyProgrammer.js +33 -69
  92. package/lib/programmers/http/HttpQuerifyProgrammer.js.map +1 -1
  93. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js +11 -28
  94. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js.map +1 -1
  95. package/lib/programmers/internal/CoreMetadataUtil.js +12 -37
  96. package/lib/programmers/internal/CoreMetadataUtil.js.map +1 -1
  97. package/lib/transform.js +8 -8
  98. package/lib/transform.js.map +1 -1
  99. package/lib/transformers/FileTransformer.js +35 -66
  100. package/lib/transformers/FileTransformer.js.map +1 -1
  101. package/lib/transformers/MethodTransformer.js +36 -50
  102. package/lib/transformers/MethodTransformer.js.map +1 -1
  103. package/lib/transformers/NodeTransformer.js +8 -12
  104. package/lib/transformers/NodeTransformer.js.map +1 -1
  105. package/lib/transformers/ParameterDecoratorTransformer.js +75 -90
  106. package/lib/transformers/ParameterDecoratorTransformer.js.map +1 -1
  107. package/lib/transformers/ParameterTransformer.js +18 -24
  108. package/lib/transformers/ParameterTransformer.js.map +1 -1
  109. package/lib/transformers/TypedExceptionTransformer.js +25 -27
  110. package/lib/transformers/TypedExceptionTransformer.js.map +1 -1
  111. package/lib/transformers/TypedRouteTransformer.js +52 -88
  112. package/lib/transformers/TypedRouteTransformer.js.map +1 -1
  113. package/lib/utils/ArrayUtil.d.ts +3 -0
  114. package/lib/utils/ArrayUtil.js +11 -0
  115. package/lib/utils/ArrayUtil.js.map +1 -0
  116. package/lib/utils/ExceptionManager.js +9 -31
  117. package/lib/utils/ExceptionManager.js.map +1 -1
  118. package/lib/utils/Singleton.js +6 -7
  119. package/lib/utils/Singleton.js.map +1 -1
  120. package/lib/utils/SourceFinder.js +38 -215
  121. package/lib/utils/SourceFinder.js.map +1 -1
  122. package/lib/utils/VersioningStrategy.d.ts +9 -0
  123. package/lib/utils/VersioningStrategy.js +17 -0
  124. package/lib/utils/VersioningStrategy.js.map +1 -0
  125. package/package.json +9 -5
  126. package/src/adaptors/WebSocketAdaptor.ts +414 -0
  127. package/src/decorators/TypedParam.ts +5 -6
  128. package/src/decorators/TypedQuery.ts +251 -251
  129. package/src/decorators/WebSocketRoute.ts +249 -0
  130. package/src/decorators/internal/IWebSocketRouteReflect.ts +23 -0
  131. package/src/decorators/internal/validate_request_body.ts +72 -72
  132. package/src/decorators/internal/validate_request_form_data.ts +75 -75
  133. package/src/decorators/internal/validate_request_headers.ts +83 -83
  134. package/src/decorators/internal/validate_request_query.ts +71 -71
  135. package/src/module.ts +20 -16
  136. package/src/transformers/ParameterDecoratorTransformer.ts +129 -120
  137. package/src/typings/get-function-location.d.ts +7 -0
  138. package/src/utils/ArrayUtil.ts +7 -0
  139. package/src/utils/VersioningStrategy.ts +27 -0
@@ -1,83 +1,83 @@
1
- import { BadRequestException } from "@nestjs/common";
2
- import typia, { IValidation, TypeGuardError } from "typia";
3
-
4
- import { IRequestHeadersValidator } from "../../options/IRequestHeadersValidator";
5
- import { NoTransformConfigureError } from "./NoTransformConfigureError";
6
-
7
- /**
8
- * @internal
9
- */
10
- export const validate_request_headers = <T>(
11
- validator?: IRequestHeadersValidator<T>,
12
- ) => {
13
- if (!validator) return () => NoTransformConfigureError("TypedHeaders");
14
- else if (validator.type === "assert") return assert(validator.assert);
15
- else if (validator.type === "is") return is(validator.is);
16
- else if (validator.type === "validate") return validate(validator.validate);
17
- return () =>
18
- new Error(`Error on nestia.core.TypedHeaders(): invalid typed validator.`);
19
- };
20
-
21
- /**
22
- * @internal
23
- */
24
- const assert =
25
- <T>(closure: (input: Record<string, string | string[] | undefined>) => T) =>
26
- (
27
- input: Record<string, string | string[] | undefined>,
28
- ): T | BadRequestException => {
29
- try {
30
- return closure(input);
31
- } catch (exp) {
32
- if (typia.is<TypeGuardError>(exp)) {
33
- return new BadRequestException({
34
- path: exp.path,
35
- reason: exp.message,
36
- expected: exp.expected,
37
- value: exp.value,
38
- message: MESSAGE,
39
- });
40
- }
41
- throw exp;
42
- }
43
- };
44
-
45
- /**
46
- * @internal
47
- */
48
- const is =
49
- <T>(
50
- closure: (input: Record<string, string | string[] | undefined>) => T | null,
51
- ) =>
52
- (
53
- input: Record<string, string | string[] | undefined>,
54
- ): T | BadRequestException => {
55
- const result: T | null = closure(input);
56
- return result !== null ? result : new BadRequestException(MESSAGE);
57
- };
58
-
59
- /**
60
- * @internal
61
- */
62
- const validate =
63
- <T>(
64
- closure: (
65
- input: Record<string, string | string[] | undefined>,
66
- ) => IValidation<T>,
67
- ) =>
68
- (
69
- input: Record<string, string | string[] | undefined>,
70
- ): T | BadRequestException => {
71
- const result: IValidation<T> = closure(input);
72
- return result.success
73
- ? result.data
74
- : new BadRequestException({
75
- errors: result.errors,
76
- message: MESSAGE,
77
- });
78
- };
79
-
80
- /**
81
- * @internal
82
- */
83
- const MESSAGE = "Request headers data is not following the promised type.";
1
+ import { BadRequestException } from "@nestjs/common";
2
+ import typia, { IValidation, TypeGuardError } from "typia";
3
+
4
+ import { IRequestHeadersValidator } from "../../options/IRequestHeadersValidator";
5
+ import { NoTransformConfigureError } from "./NoTransformConfigureError";
6
+
7
+ /**
8
+ * @internal
9
+ */
10
+ export const validate_request_headers = <T>(
11
+ validator?: IRequestHeadersValidator<T>,
12
+ ) => {
13
+ if (!validator) throw NoTransformConfigureError("TypedHeaders");
14
+ else if (validator.type === "assert") return assert(validator.assert);
15
+ else if (validator.type === "is") return is(validator.is);
16
+ else if (validator.type === "validate") return validate(validator.validate);
17
+ return () =>
18
+ new Error(`Error on nestia.core.TypedHeaders(): invalid typed validator.`);
19
+ };
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ const assert =
25
+ <T>(closure: (input: Record<string, string | string[] | undefined>) => T) =>
26
+ (
27
+ input: Record<string, string | string[] | undefined>,
28
+ ): T | BadRequestException => {
29
+ try {
30
+ return closure(input);
31
+ } catch (exp) {
32
+ if (typia.is<TypeGuardError>(exp)) {
33
+ return new BadRequestException({
34
+ path: exp.path,
35
+ reason: exp.message,
36
+ expected: exp.expected,
37
+ value: exp.value,
38
+ message: MESSAGE,
39
+ });
40
+ }
41
+ throw exp;
42
+ }
43
+ };
44
+
45
+ /**
46
+ * @internal
47
+ */
48
+ const is =
49
+ <T>(
50
+ closure: (input: Record<string, string | string[] | undefined>) => T | null,
51
+ ) =>
52
+ (
53
+ input: Record<string, string | string[] | undefined>,
54
+ ): T | BadRequestException => {
55
+ const result: T | null = closure(input);
56
+ return result !== null ? result : new BadRequestException(MESSAGE);
57
+ };
58
+
59
+ /**
60
+ * @internal
61
+ */
62
+ const validate =
63
+ <T>(
64
+ closure: (
65
+ input: Record<string, string | string[] | undefined>,
66
+ ) => IValidation<T>,
67
+ ) =>
68
+ (
69
+ input: Record<string, string | string[] | undefined>,
70
+ ): T | BadRequestException => {
71
+ const result: IValidation<T> = closure(input);
72
+ return result.success
73
+ ? result.data
74
+ : new BadRequestException({
75
+ errors: result.errors,
76
+ message: MESSAGE,
77
+ });
78
+ };
79
+
80
+ /**
81
+ * @internal
82
+ */
83
+ const MESSAGE = "Request headers data is not following the promised type.";
@@ -1,71 +1,71 @@
1
- import { BadRequestException } from "@nestjs/common";
2
- import typia, { IValidation, TypeGuardError } from "typia";
3
-
4
- import { IRequestQueryValidator } from "../../options/IRequestQueryValidator";
5
- import { NoTransformConfigureError } from "./NoTransformConfigureError";
6
-
7
- /**
8
- * @internal
9
- */
10
- export const validate_request_query = <T>(
11
- validator?: IRequestQueryValidator<T>,
12
- ) => {
13
- if (!validator) return () => NoTransformConfigureError("TypedQuery");
14
- else if (validator.type === "assert") return assert(validator.assert);
15
- else if (validator.type === "is") return is(validator.is);
16
- else if (validator.type === "validate") return validate(validator.validate);
17
- return () =>
18
- new Error(`Error on nestia.core.TypedQuery(): invalid typed validator.`);
19
- };
20
-
21
- /**
22
- * @internal
23
- */
24
- const assert =
25
- <T>(closure: (input: URLSearchParams) => T) =>
26
- (input: URLSearchParams): T | BadRequestException => {
27
- try {
28
- return closure(input);
29
- } catch (exp) {
30
- if (typia.is<TypeGuardError>(exp)) {
31
- return new BadRequestException({
32
- path: exp.path,
33
- reason: exp.message,
34
- expected: exp.expected,
35
- value: exp.value,
36
- message: MESSAGE,
37
- });
38
- }
39
- throw exp;
40
- }
41
- };
42
-
43
- /**
44
- * @internal
45
- */
46
- const is =
47
- <T>(closure: (input: URLSearchParams) => T | null) =>
48
- (input: URLSearchParams): T | BadRequestException => {
49
- const result: T | null = closure(input);
50
- return result !== null ? result : new BadRequestException(MESSAGE);
51
- };
52
-
53
- /**
54
- * @internal
55
- */
56
- const validate =
57
- <T>(closure: (input: URLSearchParams) => IValidation<T>) =>
58
- (input: URLSearchParams): T | BadRequestException => {
59
- const result: IValidation<T> = closure(input);
60
- return result.success
61
- ? result.data
62
- : new BadRequestException({
63
- errors: result.errors,
64
- message: MESSAGE,
65
- });
66
- };
67
-
68
- /**
69
- * @internal
70
- */
71
- const MESSAGE = "Request query data is not following the promised type.";
1
+ import { BadRequestException } from "@nestjs/common";
2
+ import typia, { IValidation, TypeGuardError } from "typia";
3
+
4
+ import { IRequestQueryValidator } from "../../options/IRequestQueryValidator";
5
+ import { NoTransformConfigureError } from "./NoTransformConfigureError";
6
+
7
+ /**
8
+ * @internal
9
+ */
10
+ export const validate_request_query =
11
+ (method: string) =>
12
+ <T>(validator?: IRequestQueryValidator<T>) => {
13
+ if (!validator) throw NoTransformConfigureError(method);
14
+ else if (validator.type === "assert") return assert(validator.assert);
15
+ else if (validator.type === "is") return is(validator.is);
16
+ else if (validator.type === "validate") return validate(validator.validate);
17
+ return () =>
18
+ new Error(`Error on nestia.core.${method}(): invalid typed validator.`);
19
+ };
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ const assert =
25
+ <T>(closure: (input: URLSearchParams) => T) =>
26
+ (input: URLSearchParams): T | BadRequestException => {
27
+ try {
28
+ return closure(input);
29
+ } catch (exp) {
30
+ if (typia.is<TypeGuardError>(exp)) {
31
+ return new BadRequestException({
32
+ path: exp.path,
33
+ reason: exp.message,
34
+ expected: exp.expected,
35
+ value: exp.value,
36
+ message: MESSAGE,
37
+ });
38
+ }
39
+ throw exp;
40
+ }
41
+ };
42
+
43
+ /**
44
+ * @internal
45
+ */
46
+ const is =
47
+ <T>(closure: (input: URLSearchParams) => T | null) =>
48
+ (input: URLSearchParams): T | BadRequestException => {
49
+ const result: T | null = closure(input);
50
+ return result !== null ? result : new BadRequestException(MESSAGE);
51
+ };
52
+
53
+ /**
54
+ * @internal
55
+ */
56
+ const validate =
57
+ <T>(closure: (input: URLSearchParams) => IValidation<T>) =>
58
+ (input: URLSearchParams): T | BadRequestException => {
59
+ const result: IValidation<T> = closure(input);
60
+ return result.success
61
+ ? result.data
62
+ : new BadRequestException({
63
+ errors: result.errors,
64
+ message: MESSAGE,
65
+ });
66
+ };
67
+
68
+ /**
69
+ * @internal
70
+ */
71
+ const MESSAGE = "Request query data is not following the promised type.";
package/src/module.ts CHANGED
@@ -1,16 +1,20 @@
1
- export * from "./decorators/DynamicModule";
2
- export * from "./decorators/EncryptedBody";
3
- export * from "./decorators/EncryptedController";
4
- export * from "./decorators/EncryptedModule";
5
- export * from "./decorators/EncryptedRoute";
6
- export * from "./utils/ExceptionManager";
7
- export * from "./decorators/PlainBody";
8
- export * from "./decorators/SwaggerCustomizer";
9
- export * from "./decorators/TypedBody";
10
- export * from "./decorators/TypedException";
11
- export * from "./decorators/TypedHeaders";
12
- export * from "./decorators/TypedFormData";
13
- export * from "./decorators/TypedParam";
14
- export * from "./decorators/TypedRoute";
15
- export * from "./decorators/TypedQuery";
16
- export * from "./options/INestiaTransformOptions";
1
+ export * from "./decorators/DynamicModule";
2
+ export * from "./utils/ExceptionManager";
3
+
4
+ export * from "./decorators/TypedRoute";
5
+ export * from "./decorators/TypedBody";
6
+ export * from "./decorators/TypedQuery";
7
+ export * from "./decorators/TypedException";
8
+ export * from "./decorators/TypedHeaders";
9
+ export * from "./decorators/TypedFormData";
10
+ export * from "./decorators/TypedParam";
11
+
12
+ export * from "./decorators/EncryptedController";
13
+ export * from "./decorators/EncryptedRoute";
14
+ export * from "./decorators/EncryptedBody";
15
+ export * from "./decorators/EncryptedModule";
16
+ export * from "./decorators/PlainBody";
17
+ export * from "./decorators/SwaggerCustomizer";
18
+
19
+ export * from "./adaptors/WebSocketAdaptor";
20
+ export * from "./decorators/WebSocketRoute";
@@ -1,120 +1,129 @@
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 { TypedFormDataBodyProgrammer } from "../programmers/TypedFormDataBodyProgrammer";
8
- import { TypedHeadersProgrammer } from "../programmers/TypedHeadersProgrammer";
9
- import { TypedParamProgrammer } from "../programmers/TypedParamProgrammer";
10
- import { TypedQueryBodyProgrammer } from "../programmers/TypedQueryBodyProgrammer";
11
- import { TypedQueryProgrammer } from "../programmers/TypedQueryProgrammer";
12
-
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;
23
-
24
- // SIGNATURE DECLARATION
25
- const declaration: ts.Declaration | undefined =
26
- project.checker.getResolvedSignature(decorator.expression)?.declaration;
27
- if (declaration === undefined) return decorator;
28
-
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
-
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;
43
-
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;
51
-
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
- };
64
- }
65
-
66
- type Programmer = (
67
- project: INestiaTransformProject,
68
- ) => (
69
- modulo: ts.LeftHandSideExpression,
70
- ) => (
71
- parameters: readonly ts.Expression[],
72
- ) => (type: ts.Type) => readonly ts.Expression[];
73
-
74
- 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
- };
105
-
106
- const LIB_PATH = path.join("@nestia", "core", "lib", "decorators");
107
- const SRC_PATH = path.resolve(path.join(__dirname, "..", "decorators"));
108
-
109
- const getName = (symbol: ts.Symbol): string => {
110
- const parent = symbol.getDeclarations()?.[0]?.parent;
111
- return parent ? exploreName(parent)(symbol.escapedName.toString()) : "__type";
112
- };
113
- const exploreName =
114
- (decl: ts.Node) =>
115
- (name: string): string =>
116
- ts.isModuleBlock(decl)
117
- ? exploreName(decl.parent.parent)(
118
- `${decl.parent.name.getFullText().trim()}.${name}`,
119
- )
120
- : 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 { TypedFormDataBodyProgrammer } from "../programmers/TypedFormDataBodyProgrammer";
8
+ import { TypedHeadersProgrammer } from "../programmers/TypedHeadersProgrammer";
9
+ import { TypedParamProgrammer } from "../programmers/TypedParamProgrammer";
10
+ import { TypedQueryBodyProgrammer } from "../programmers/TypedQueryBodyProgrammer";
11
+ import { TypedQueryProgrammer } from "../programmers/TypedQueryProgrammer";
12
+
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;
23
+
24
+ // SIGNATURE DECLARATION
25
+ const declaration: ts.Declaration | undefined =
26
+ project.checker.getResolvedSignature(decorator.expression)?.declaration;
27
+ if (declaration === undefined) return decorator;
28
+
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
+
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;
43
+
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;
51
+
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
+ };
64
+ }
65
+
66
+ type Programmer = (
67
+ project: INestiaTransformProject,
68
+ ) => (
69
+ modulo: ts.LeftHandSideExpression,
70
+ ) => (
71
+ parameters: readonly ts.Expression[],
72
+ ) => (type: ts.Type) => readonly ts.Expression[];
73
+
74
+ 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)],
113
+ };
114
+
115
+ const LIB_PATH = path.join("@nestia", "core", "lib", "decorators");
116
+ const SRC_PATH = path.resolve(path.join(__dirname, "..", "decorators"));
117
+
118
+ const getName = (symbol: ts.Symbol): string => {
119
+ const parent = symbol.getDeclarations()?.[0]?.parent;
120
+ return parent ? exploreName(parent)(symbol.escapedName.toString()) : "__type";
121
+ };
122
+ const exploreName =
123
+ (decl: ts.Node) =>
124
+ (name: string): string =>
125
+ ts.isModuleBlock(decl)
126
+ ? exploreName(decl.parent.parent)(
127
+ `${decl.parent.name.getFullText().trim()}.${name}`,
128
+ )
129
+ : name;
@@ -0,0 +1,7 @@
1
+ declare module "get-function-location" {
2
+ export default function (func: any): Promise<{
3
+ source: string;
4
+ line: number;
5
+ column: number;
6
+ }>;
7
+ }
@@ -0,0 +1,7 @@
1
+ export namespace ArrayUtil {
2
+ export function has<T>(array: T[], ...items: T[]): boolean {
3
+ return items.every(
4
+ (elem) => array.find((org) => org === elem) !== undefined,
5
+ );
6
+ }
7
+ }
@@ -0,0 +1,27 @@
1
+ import { VERSION_NEUTRAL, VersionValue } from "@nestjs/common/interfaces";
2
+
3
+ export namespace VersioningStrategy {
4
+ export interface IConfig {
5
+ prefix: string;
6
+ defaultVersion?: VersionValue;
7
+ }
8
+
9
+ export const cast = (
10
+ value: VersionValue | undefined,
11
+ ): Array<string | typeof VERSION_NEUTRAL> =>
12
+ value === undefined ? [] : Array.isArray(value) ? value : [value];
13
+
14
+ export const merge =
15
+ (config: IConfig | undefined) =>
16
+ (values: Array<string | typeof VERSION_NEUTRAL>): string[] => {
17
+ if (config === undefined) return [""];
18
+ const set: Set<string | typeof VERSION_NEUTRAL> = new Set(values);
19
+ const array: Array<string | typeof VERSION_NEUTRAL> =
20
+ set.size === 0 ? cast(config.defaultVersion) : Array.from(set);
21
+ return !!array?.length
22
+ ? array.map((x) =>
23
+ typeof x === "symbol" ? "" : `${config.prefix}${x}`,
24
+ )
25
+ : [];
26
+ };
27
+ }