@tsed/platform-http 8.0.1 → 8.0.2

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 (100) hide show
  1. package/package.json +18 -16
  2. package/src/common/builder/PlatformBuilder.spec.ts +331 -0
  3. package/src/common/builder/PlatformBuilder.ts +426 -0
  4. package/src/common/builder/__fixtures__/PlatformCustom.ts +39 -0
  5. package/src/common/config/interfaces/PlatformJsonMapperSettings.ts +11 -0
  6. package/src/common/config/interfaces/PlatformMulterSettings.ts +21 -0
  7. package/src/common/config/interfaces/PlatformRouterSettings.ts +11 -0
  8. package/src/common/config/interfaces/PlatformStaticsSettings.ts +23 -0
  9. package/src/common/config/services/PlatformConfiguration.spec.ts +181 -0
  10. package/src/common/config/services/PlatformConfiguration.ts +157 -0
  11. package/src/common/constants/routerOptions.ts +1 -0
  12. package/src/common/decorators/PlatformProvider.ts +14 -0
  13. package/src/common/decorators/multer/multerFileSize.spec.ts +22 -0
  14. package/src/common/decorators/multer/multerFileSize.ts +32 -0
  15. package/src/common/decorators/multer/multerOptions.spec.ts +21 -0
  16. package/src/common/decorators/multer/multerOptions.ts +53 -0
  17. package/src/common/decorators/multer/multipartFile.spec.ts +259 -0
  18. package/src/common/decorators/multer/multipartFile.ts +88 -0
  19. package/src/common/decorators/params/error.spec.ts +15 -0
  20. package/src/common/decorators/params/error.ts +16 -0
  21. package/src/common/decorators/params/next.spec.ts +15 -0
  22. package/src/common/decorators/params/next.ts +31 -0
  23. package/src/common/decorators/params/request.spec.ts +49 -0
  24. package/src/common/decorators/params/request.ts +85 -0
  25. package/src/common/decorators/params/response.spec.ts +36 -0
  26. package/src/common/decorators/params/response.ts +73 -0
  27. package/src/common/domain/AnyToPromiseWithCtx.spec.ts +20 -0
  28. package/src/common/domain/AnyToPromiseWithCtx.ts +30 -0
  29. package/src/common/domain/EndpointMetadata.ts +1 -0
  30. package/src/common/domain/PlatformContext.spec.ts +124 -0
  31. package/src/common/domain/PlatformContext.ts +135 -0
  32. package/src/common/domain/PlatformRouteDetails.ts +7 -0
  33. package/src/common/exports.ts +4 -0
  34. package/src/common/fn/adapter.ts +23 -0
  35. package/src/common/fn/application.ts +11 -0
  36. package/src/common/index.ts +62 -0
  37. package/src/common/interfaces/AfterInit.ts +3 -0
  38. package/src/common/interfaces/AfterListen.ts +3 -0
  39. package/src/common/interfaces/AfterRoutesInit.ts +3 -0
  40. package/src/common/interfaces/BeforeInit.ts +3 -0
  41. package/src/common/interfaces/BeforeListen.ts +3 -0
  42. package/src/common/interfaces/BeforeRoutesInit.ts +3 -0
  43. package/src/common/interfaces/HandlerType.ts +12 -0
  44. package/src/common/interfaces/IncomingEvent.ts +6 -0
  45. package/src/common/interfaces/OnReady.ts +3 -0
  46. package/src/common/interfaces/OnRequest.ts +5 -0
  47. package/src/common/interfaces/OnResponse.ts +5 -0
  48. package/src/common/interfaces/OnRoutesInit.ts +3 -0
  49. package/src/common/interfaces/PlatformRouteOptions.ts +17 -0
  50. package/src/common/interfaces/ResponseErrorObject.ts +8 -0
  51. package/src/common/interfaces/Route.ts +12 -0
  52. package/src/common/middlewares/PlatformAcceptMimesMiddleware.spec.ts +215 -0
  53. package/src/common/middlewares/PlatformAcceptMimesMiddleware.ts +24 -0
  54. package/src/common/middlewares/PlatformMulterMiddleware.spec.ts +97 -0
  55. package/src/common/middlewares/PlatformMulterMiddleware.ts +59 -0
  56. package/src/common/services/Platform.spec.ts +145 -0
  57. package/src/common/services/Platform.ts +79 -0
  58. package/src/common/services/PlatformAdapter.ts +89 -0
  59. package/src/common/services/PlatformApplication.spec.ts +101 -0
  60. package/src/common/services/PlatformApplication.ts +54 -0
  61. package/src/common/services/PlatformHandler.spec.ts +152 -0
  62. package/src/common/services/PlatformHandler.ts +140 -0
  63. package/src/common/services/PlatformMiddlewaresChain.spec.ts +96 -0
  64. package/src/common/services/PlatformMiddlewaresChain.ts +55 -0
  65. package/src/common/services/PlatformRequest.spec.ts +185 -0
  66. package/src/common/services/PlatformRequest.ts +181 -0
  67. package/src/common/services/PlatformResponse.spec.ts +344 -0
  68. package/src/common/services/PlatformResponse.ts +388 -0
  69. package/src/common/utils/closeServer.spec.ts +11 -0
  70. package/src/common/utils/closeServer.ts +7 -0
  71. package/src/common/utils/createContext.spec.ts +111 -0
  72. package/src/common/utils/createContext.ts +52 -0
  73. package/src/common/utils/createHttpServer.spec.ts +74 -0
  74. package/src/common/utils/createHttpServer.ts +15 -0
  75. package/src/common/utils/createHttpsServer.spec.ts +73 -0
  76. package/src/common/utils/createHttpsServer.ts +16 -0
  77. package/src/common/utils/createInjector.spec.ts +42 -0
  78. package/src/common/utils/createInjector.ts +55 -0
  79. package/src/common/utils/createServer.ts +51 -0
  80. package/src/common/utils/ensureContext.spec.ts +41 -0
  81. package/src/common/utils/ensureContext.ts +17 -0
  82. package/src/common/utils/getConfiguration.spec.ts +163 -0
  83. package/src/common/utils/getConfiguration.ts +34 -0
  84. package/src/common/utils/getStaticsOptions.spec.ts +27 -0
  85. package/src/common/utils/getStaticsOptions.ts +24 -0
  86. package/src/common/utils/listenServer.ts +17 -0
  87. package/src/common/utils/mapReturnedResponse.spec.ts +35 -0
  88. package/src/common/utils/mapReturnedResponse.ts +10 -0
  89. package/src/common/utils/printRoutes.spec.ts +19 -0
  90. package/src/common/utils/printRoutes.ts +40 -0
  91. package/src/common/utils/resolveControllers.spec.ts +40 -0
  92. package/src/common/utils/resolveControllers.ts +54 -0
  93. package/src/common/utils/setResponseHeaders.spec.ts +84 -0
  94. package/src/common/utils/setResponseHeaders.ts +31 -0
  95. package/src/index.ts +2 -0
  96. package/src/testing/FakeAdapter.ts +69 -0
  97. package/src/testing/FakeResponse.ts +72 -0
  98. package/src/testing/PlatformTest.spec.ts +53 -0
  99. package/src/testing/PlatformTest.ts +157 -0
  100. package/src/testing/index.ts +5 -0
@@ -0,0 +1,259 @@
1
+ import "../../index.js";
2
+
3
+ import {descriptorOf, Metadata, Store} from "@tsed/core";
4
+ import {ParamTypes} from "@tsed/platform-params";
5
+ import {getSpec, JsonParameterStore, Post, SpecTypes} from "@tsed/schema";
6
+
7
+ import {PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware.js";
8
+ import {MultipartFile} from "./multipartFile.js";
9
+
10
+ class Test {
11
+ test() {}
12
+ }
13
+
14
+ describe("@MultipartFile()", () => {
15
+ describe("one file", () => {
16
+ // WHEN
17
+ class TestController {
18
+ @Post("/")
19
+ test(@MultipartFile("file1", 1) file: any) {}
20
+ }
21
+
22
+ // THEN
23
+ const store = Store.fromMethod(TestController, "test");
24
+ const param = JsonParameterStore.get(TestController, "test", 0);
25
+
26
+ it("should set params properly", () => {
27
+ expect(store.get(PlatformMulterMiddleware)).toEqual({
28
+ fields: [
29
+ {
30
+ maxCount: 1,
31
+ name: "file1"
32
+ }
33
+ ]
34
+ });
35
+ expect(param.expression).toEqual("file1.0");
36
+ expect(param.paramType).toEqual(ParamTypes.FILES);
37
+ });
38
+
39
+ it("should set endpoint metadata - OS3", () => {
40
+ expect(getSpec(TestController, {specType: SpecTypes.OPENAPI})).toEqual({
41
+ paths: {
42
+ "/": {
43
+ post: {
44
+ operationId: "testControllerTest",
45
+ parameters: [],
46
+ responses: {
47
+ "400": {
48
+ content: {"application/json": {schema: {$ref: "#/components/schemas/BadRequest"}}},
49
+ description:
50
+ "<File too long | Too many parts | Too many files | Field name too long | Field value too long | Too many fields | Unexpected field> [fieldName] Example: File too long file1"
51
+ }
52
+ },
53
+ requestBody: {
54
+ required: false,
55
+ content: {
56
+ "multipart/form-data": {
57
+ schema: {
58
+ properties: {file1: {type: "string", format: "binary"}},
59
+ type: "object"
60
+ }
61
+ }
62
+ }
63
+ },
64
+ tags: ["TestController"]
65
+ }
66
+ }
67
+ },
68
+ tags: [{name: "TestController"}],
69
+ components: {
70
+ schemas: {
71
+ GenericError: {
72
+ additionalProperties: true,
73
+ properties: {
74
+ message: {
75
+ description: "An error message",
76
+ minLength: 1,
77
+ type: "string"
78
+ },
79
+ name: {
80
+ description: "The error name",
81
+ minLength: 1,
82
+ type: "string"
83
+ }
84
+ },
85
+ required: ["name", "message"],
86
+ type: "object"
87
+ },
88
+ BadRequest: {
89
+ type: "object",
90
+ properties: {
91
+ name: {
92
+ type: "string",
93
+ minLength: 1,
94
+ description: "The error name",
95
+ example: "BAD_REQUEST",
96
+ default: "BAD_REQUEST"
97
+ },
98
+ message: {type: "string", minLength: 1, description: "An error message"},
99
+ status: {type: "number", description: "The status code of the exception", example: 400, default: 400},
100
+ errors: {
101
+ type: "array",
102
+ items: {
103
+ $ref: "#/components/schemas/GenericError"
104
+ },
105
+ description: "A list of related errors"
106
+ },
107
+ stack: {
108
+ type: "string",
109
+ description: "The stack trace (only in development mode)"
110
+ }
111
+ },
112
+ required: ["name", "message", "status"]
113
+ }
114
+ }
115
+ }
116
+ });
117
+ });
118
+ });
119
+
120
+ describe("multiple file schema", () => {
121
+ // WHEN
122
+ class TestController {
123
+ @Post("/")
124
+ test(@MultipartFile("file1", 4) file: any[]) {}
125
+ }
126
+
127
+ // THEN
128
+ const store = Store.fromMethod(TestController, "test");
129
+ const param = JsonParameterStore.get(TestController, "test", 0);
130
+
131
+ it("should set params properly", () => {
132
+ expect(store.get(PlatformMulterMiddleware)).toEqual({
133
+ fields: [
134
+ {
135
+ maxCount: 4,
136
+ name: "file1"
137
+ }
138
+ ]
139
+ });
140
+ expect(param.expression).toEqual("file1");
141
+ expect(param.paramType).toEqual(ParamTypes.FILES);
142
+ });
143
+
144
+ it("should set endpoint metadata - OS3", () => {
145
+ expect(getSpec(TestController, {specType: SpecTypes.OPENAPI})).toEqual({
146
+ paths: {
147
+ "/": {
148
+ post: {
149
+ operationId: "testControllerTest",
150
+ parameters: [],
151
+ responses: {
152
+ "400": {
153
+ content: {"application/json": {schema: {$ref: "#/components/schemas/BadRequest"}}},
154
+ description:
155
+ "<File too long | Too many parts | Too many files | Field name too long | Field value too long | Too many fields | Unexpected field> [fieldName] Example: File too long file1"
156
+ }
157
+ },
158
+ requestBody: {
159
+ required: false,
160
+ content: {
161
+ "multipart/form-data": {
162
+ schema: {
163
+ properties: {file1: {type: "array", items: {type: "string", format: "binary"}}},
164
+ type: "object"
165
+ }
166
+ }
167
+ }
168
+ },
169
+ tags: ["TestController"]
170
+ }
171
+ }
172
+ },
173
+ tags: [{name: "TestController"}],
174
+ components: {
175
+ schemas: {
176
+ GenericError: {
177
+ additionalProperties: true,
178
+ properties: {
179
+ message: {
180
+ description: "An error message",
181
+ minLength: 1,
182
+ type: "string"
183
+ },
184
+ name: {
185
+ description: "The error name",
186
+ minLength: 1,
187
+ type: "string"
188
+ }
189
+ },
190
+ required: ["name", "message"],
191
+ type: "object"
192
+ },
193
+ BadRequest: {
194
+ type: "object",
195
+ properties: {
196
+ name: {
197
+ type: "string",
198
+ minLength: 1,
199
+ description: "The error name",
200
+ example: "BAD_REQUEST",
201
+ default: "BAD_REQUEST"
202
+ },
203
+ message: {
204
+ type: "string",
205
+ minLength: 1,
206
+ description: "An error message"
207
+ },
208
+ status: {type: "number", description: "The status code of the exception", example: 400, default: 400},
209
+ errors: {
210
+ type: "array",
211
+ items: {
212
+ $ref: "#/components/schemas/GenericError"
213
+ },
214
+ description: "A list of related errors"
215
+ },
216
+ stack: {
217
+ type: "string",
218
+ description: "The stack trace (only in development mode)"
219
+ }
220
+ },
221
+ required: ["name", "message", "status"]
222
+ }
223
+ }
224
+ }
225
+ });
226
+ });
227
+ });
228
+
229
+ describe("multiple files", () => {
230
+ afterAll(() => {
231
+ vi.clearAllMocks();
232
+ });
233
+
234
+ it("should set params metadata", () => {
235
+ const store = Store.from(Test.prototype, "test", descriptorOf(Test.prototype, "test"));
236
+ store.delete("multipartAdded");
237
+
238
+ // @ts-ignore
239
+ store.delete(PlatformMulterMiddleware);
240
+ vi.spyOn(Store, "fromMethod").mockReturnValue(store);
241
+ vi.spyOn(Metadata, "getParamTypes").mockReturnValue([Array]);
242
+
243
+ MultipartFile("file1", 8)(Test.prototype, "test", 0);
244
+
245
+ expect(store.get(PlatformMulterMiddleware)).toEqual({
246
+ fields: [
247
+ {
248
+ maxCount: 8,
249
+ name: "file1"
250
+ }
251
+ ]
252
+ });
253
+
254
+ const param = JsonParameterStore.get(Test, "test", 0);
255
+ expect(param.expression).toEqual("file1");
256
+ expect(param.paramType).toEqual(ParamTypes.FILES);
257
+ });
258
+ });
259
+ });
@@ -0,0 +1,88 @@
1
+ import {DecoratorParameters, Metadata, StoreMerge, useDecorators, useMethodDecorators} from "@tsed/core";
2
+ import {ParamTypes, UseParam} from "@tsed/platform-params";
3
+ import {InFile} from "@tsed/schema";
4
+
5
+ import {PlatformMulterFile} from "../../config/interfaces/PlatformMulterSettings.js";
6
+ import {MulterInputOptions, PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware.js";
7
+
8
+ function mapOptions(name: string, maxCount: number | undefined): MulterInputOptions {
9
+ return {
10
+ fields: [
11
+ {
12
+ name,
13
+ maxCount
14
+ }
15
+ ]
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Define a parameter as Multipart file.
21
+ *
22
+ * ```typescript
23
+ * import {Post} from "@tsed/schema";
24
+ * import {Controller, MulterOptions, MultipartFile} from "@tsed/platform-http";
25
+ * import {Controller} from "@tsed/di";
26
+ * import {Multer} from "@types/multer";
27
+ *
28
+ * type MulterFile = Express.Multer.File;
29
+ *
30
+ * @Controller('/')
31
+ * class MyCtrl {
32
+ * @Post('/file')
33
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
34
+ *
35
+ * }
36
+ *
37
+ * @Post('/file')
38
+ * @MulterOptions({dest: "/other-dir"})
39
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
40
+ *
41
+ * }
42
+ *
43
+ * @Post('/file2')
44
+ * @MulterOptions({dest: "/other-dir"})
45
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
46
+ *
47
+ * }
48
+ *
49
+ * @Post('/files')
50
+ * private uploadFile(@MultipartFile("file1") files: MulterFile[]) {
51
+ *
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
57
+ *
58
+ * @param name
59
+ * @param maxCount
60
+ * @returns Function
61
+ * @decorator
62
+ * @input
63
+ */
64
+ export function MultipartFile(name: string, maxCount?: number): ParameterDecorator {
65
+ return (...args: DecoratorParameters): void => {
66
+ const [target, propertyKey, index] = args;
67
+ const multiple = Metadata.getParamTypes(target, propertyKey)[index as number] === Array;
68
+
69
+ name = (typeof name === "object" ? undefined : name)!;
70
+
71
+ const expression = [name, !multiple && "0"].filter(Boolean).join(".");
72
+
73
+ const decorators = useDecorators(
74
+ InFile(name),
75
+ useMethodDecorators(StoreMerge(PlatformMulterMiddleware, mapOptions(name, maxCount))),
76
+ UseParam({
77
+ paramType: ParamTypes.FILES,
78
+ dataPath: "$ctx.request.files",
79
+ expression,
80
+ useValidation: true
81
+ })
82
+ );
83
+
84
+ decorators(...args);
85
+ };
86
+ }
87
+
88
+ export type MultipartFile = PlatformMulterFile;
@@ -0,0 +1,15 @@
1
+ import {ParamTypes} from "@tsed/platform-params";
2
+ import {JsonParameterStore} from "@tsed/schema";
3
+
4
+ import {Err} from "./error.js";
5
+
6
+ describe("@Err", () => {
7
+ it("should register a new parameter instance with the correct property", () => {
8
+ class Ctrl {
9
+ test(@Err() arg: unknown) {}
10
+ }
11
+
12
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
13
+ expect(param.paramType).toEqual(ParamTypes.ERR);
14
+ });
15
+ });
@@ -0,0 +1,16 @@
1
+ import {ParamTypes, UseParam} from "@tsed/platform-params";
2
+
3
+ /**
4
+ * @returns {Function}
5
+ * @decorator
6
+ * @operation
7
+ * @input
8
+ */
9
+ export function Err(): Function {
10
+ return UseParam({
11
+ paramType: ParamTypes.ERR,
12
+ dataPath: "$ctx.error",
13
+ useValidation: false,
14
+ useMapper: false
15
+ });
16
+ }
@@ -0,0 +1,15 @@
1
+ import {ParamTypes} from "@tsed/platform-params";
2
+ import {JsonParameterStore} from "@tsed/schema";
3
+
4
+ import {Next} from "./next.js";
5
+
6
+ describe("@Next", () => {
7
+ it("should register a new parameter instance with the correct property", () => {
8
+ class Ctrl {
9
+ test(@Next() arg: any) {}
10
+ }
11
+
12
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
13
+ expect(param.paramType).toEqual(ParamTypes.NEXT_FN);
14
+ });
15
+ });
@@ -0,0 +1,31 @@
1
+ import {ParamTypes, UseParam} from "@tsed/platform-params";
2
+
3
+ /**
4
+ * Get the Next function (for express application and middleware).
5
+ *
6
+ * @decorator
7
+ * @operation
8
+ * @input
9
+ */
10
+ export function Next(): ParameterDecorator {
11
+ return UseParam({
12
+ paramType: ParamTypes.NEXT_FN,
13
+ dataPath: "next",
14
+ useMapper: false,
15
+ useValidation: false
16
+ });
17
+ }
18
+
19
+ declare global {
20
+ namespace TsED {
21
+ export interface NextFunction extends Function {}
22
+ }
23
+ }
24
+ /**
25
+ * Get the Next function (for express application and middleware).
26
+ *
27
+ * @decorator
28
+ * @operation
29
+ * @input
30
+ */
31
+ export type Next = TsED.NextFunction;
@@ -0,0 +1,49 @@
1
+ import {ParamTypes} from "@tsed/platform-params";
2
+ import {JsonParameterStore} from "@tsed/schema";
3
+ import {IncomingMessage} from "http";
4
+
5
+ import {PlatformRequest} from "../../services/PlatformRequest.js";
6
+ import {Req, Request} from "./request.js";
7
+
8
+ describe("@Req", () => {
9
+ it("should register a new parameter instance with the correct property (RawRequest)", () => {
10
+ class Ctrl {
11
+ test(@Request() arg: Req) {}
12
+ }
13
+
14
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
15
+ expect(param.paramType).toEqual(ParamTypes.REQUEST);
16
+ expect(param.type).toEqual(Req);
17
+ });
18
+
19
+ it("should register a new parameter instance with the correct property (RawRequest with expression)", () => {
20
+ class Ctrl {
21
+ test(@Req("user") arg: Req) {}
22
+ }
23
+
24
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
25
+ expect(param.paramType).toEqual(ParamTypes.REQUEST);
26
+ expect(param.expression).toEqual("user");
27
+ expect(param.type).toEqual(Req);
28
+ });
29
+
30
+ it("should register a new parameter instance with the correct property (PlatformRequest)", () => {
31
+ class Ctrl {
32
+ test(@Req() arg: PlatformRequest) {}
33
+ }
34
+
35
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
36
+ expect(param.paramType).toEqual(ParamTypes.PLATFORM_REQUEST);
37
+ expect(param.type).toEqual(PlatformRequest);
38
+ });
39
+
40
+ it("should register a new parameter instance with the correct property (IncomingMessage)", () => {
41
+ class Ctrl {
42
+ test(@Req() arg: IncomingMessage) {}
43
+ }
44
+
45
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
46
+ expect(param.paramType).toEqual(ParamTypes.NODE_REQUEST);
47
+ expect(param.type).toEqual(IncomingMessage);
48
+ });
49
+ });
@@ -0,0 +1,85 @@
1
+ import {isClass, Metadata, nameOf, Type} from "@tsed/core";
2
+ import {mapParamsOptions, ParamOptions, ParamTypes, UseParam} from "@tsed/platform-params";
3
+ import {IncomingMessage} from "http";
4
+
5
+ function getParamType(target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) {
6
+ const type = Metadata.getOwnParamTypes(target, propertyKey)[parameterIndex];
7
+
8
+ if (isClass(type)) {
9
+ if (nameOf(type) === "PlatformRequest") {
10
+ return {paramType: ParamTypes.PLATFORM_REQUEST, dataPath: "$ctx.request"};
11
+ }
12
+
13
+ if (type === IncomingMessage) {
14
+ return {paramType: ParamTypes.NODE_REQUEST, dataPath: "$ctx.request.req"};
15
+ }
16
+ }
17
+
18
+ return {paramType: ParamTypes.REQUEST, dataPath: "$ctx.request.request"};
19
+ }
20
+
21
+ /**
22
+ * Request service.
23
+ *
24
+ * @decorator
25
+ * @operation
26
+ * @input
27
+ */
28
+ export function Request(expression: string, useType: Type<any>): ParameterDecorator;
29
+ export function Request(expression: string): ParameterDecorator;
30
+ export function Request(useType: Type<any>): ParameterDecorator;
31
+ export function Request(options: ParamOptions<any>): ParameterDecorator;
32
+ export function Request(): ParameterDecorator;
33
+ export function Request(...args: any[]): ParameterDecorator {
34
+ // @ts-ignore
35
+ return Req(...args);
36
+ }
37
+
38
+ /**
39
+ * Request service.
40
+ *
41
+ * @alias Request
42
+ * @decorator
43
+ * @operation
44
+ * @input
45
+ */
46
+ export function Req(expression: string, useType: Type<any>): ParameterDecorator;
47
+ export function Req(expression: string): ParameterDecorator;
48
+ export function Req(useType: Type<any>): ParameterDecorator;
49
+ export function Req(options: Partial<ParamOptions>): ParameterDecorator;
50
+ export function Req(): ParameterDecorator;
51
+ export function Req(...args: any[]): ParameterDecorator {
52
+ const {expression, useType, useMapper = false, useValidation = false} = mapParamsOptions(args);
53
+
54
+ return (target, propertyKey, parameterIndex) => {
55
+ const {paramType, dataPath} = getParamType(target, propertyKey, parameterIndex);
56
+
57
+ UseParam({
58
+ paramType,
59
+ dataPath,
60
+ expression,
61
+ useType,
62
+ useMapper,
63
+ useValidation
64
+ })(target, propertyKey, parameterIndex);
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Request service.
70
+ *
71
+ * @decorator
72
+ * @operation
73
+ * @input
74
+ */
75
+ export interface Request extends TsED.Request {}
76
+
77
+ /**
78
+ * Request service.
79
+ *
80
+ * @alias Request
81
+ * @decorator
82
+ * @operation
83
+ * @input
84
+ */
85
+ export interface Req extends Request {}
@@ -0,0 +1,36 @@
1
+ import {ParamTypes} from "@tsed/platform-params";
2
+ import {JsonParameterStore} from "@tsed/schema";
3
+ import {ServerResponse} from "http";
4
+
5
+ import {PlatformResponse} from "../../services/PlatformResponse.js";
6
+ import {Res, Response} from "./response.js";
7
+
8
+ describe("@Res", () => {
9
+ it("should register a new parameter instance with the correct property (RawRes)", () => {
10
+ class Ctrl {
11
+ test(@Response() arg: Response) {}
12
+ }
13
+
14
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
15
+ expect(param.paramType).toEqual(ParamTypes.RESPONSE);
16
+ expect(param.type).toEqual(Response);
17
+ });
18
+ it("should register a new parameter instance with the correct property (PlatformResponse)", () => {
19
+ class Ctrl {
20
+ test(@Response() arg: PlatformResponse) {}
21
+ }
22
+
23
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
24
+ expect(param.paramType).toEqual(ParamTypes.PLATFORM_RESPONSE);
25
+ expect(param.type).toEqual(PlatformResponse);
26
+ });
27
+ it("should register a new parameter instance with the correct property (ServerResponse)", () => {
28
+ class Ctrl {
29
+ test(@Response() arg: ServerResponse) {}
30
+ }
31
+
32
+ const param = JsonParameterStore.get(Ctrl, "test", 0);
33
+ expect(param.paramType).toEqual(ParamTypes.NODE_RESPONSE);
34
+ expect(param.type).toEqual(ServerResponse);
35
+ });
36
+ });
@@ -0,0 +1,73 @@
1
+ import {isClass, Metadata, nameOf} from "@tsed/core";
2
+ import {ParamTypes, UseParam} from "@tsed/platform-params";
3
+ import {ServerResponse} from "http";
4
+
5
+ function getParamType(target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) {
6
+ const type = Metadata.getOwnParamTypes(target, propertyKey)[parameterIndex];
7
+
8
+ if (isClass(type)) {
9
+ if (nameOf(type) === "PlatformResponse") {
10
+ return {paramType: ParamTypes.PLATFORM_RESPONSE, dataPath: "$ctx.response"};
11
+ }
12
+
13
+ if (type === ServerResponse) {
14
+ return {paramType: ParamTypes.NODE_RESPONSE, dataPath: "$ctx.response.res"};
15
+ }
16
+ }
17
+
18
+ return {paramType: ParamTypes.RESPONSE, dataPath: "$ctx.response.response"};
19
+ }
20
+
21
+ /**
22
+ * Response service.
23
+ *
24
+ * @decorator
25
+ * @operation
26
+ * @input
27
+ * @response
28
+ */
29
+ export function Response(): ParameterDecorator;
30
+ export function Response(): ParameterDecorator {
31
+ return Res();
32
+ }
33
+
34
+ /**
35
+ * Request service.
36
+ *
37
+ * @alias Response
38
+ * @decorator
39
+ * @operation
40
+ * @input
41
+ * @response
42
+ */
43
+ export function Res(): ParameterDecorator;
44
+ export function Res(): ParameterDecorator {
45
+ return (target, propertyKey, parameterIndex) => {
46
+ const {paramType, dataPath} = getParamType(target, propertyKey, parameterIndex);
47
+ UseParam({
48
+ paramType,
49
+ dataPath
50
+ })(target, propertyKey, parameterIndex);
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Response service.
56
+ *
57
+ * @decorator
58
+ * @operation
59
+ * @input
60
+ * @response
61
+ */
62
+ export interface Response extends TsED.Response {}
63
+
64
+ /**
65
+ * Response service.
66
+ *
67
+ * @alias Response
68
+ * @decorator
69
+ * @operation
70
+ * @input
71
+ * @response
72
+ */
73
+ export interface Res extends Response {}
@@ -0,0 +1,20 @@
1
+ import {PlatformTest} from "../../testing/PlatformTest.js";
2
+ import {AnyToPromiseWithCtx} from "./AnyToPromiseWithCtx.js";
3
+
4
+ describe("AnyToPromiseWithCtx", () => {
5
+ beforeEach(() => PlatformTest.create());
6
+ afterEach(() => PlatformTest.reset());
7
+
8
+ it("should return value", async () => {
9
+ const $ctx = PlatformTest.createRequestContext();
10
+ const resolver = new AnyToPromiseWithCtx($ctx);
11
+
12
+ const result = await resolver.call(() => "hello");
13
+
14
+ expect(result).toEqual({
15
+ data: "hello",
16
+ state: "RESOLVED",
17
+ type: "DATA"
18
+ });
19
+ });
20
+ });