@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,181 @@
1
+ import {Env} from "@tsed/core";
2
+ import {ProviderScope, ProviderType} from "@tsed/di";
3
+
4
+ import {PlatformConfiguration} from "./PlatformConfiguration.js";
5
+
6
+ describe("PlatformConfiguration", () => {
7
+ let settings: any;
8
+
9
+ describe("Test ENV", () => {
10
+ beforeAll(() => {
11
+ settings = new PlatformConfiguration();
12
+
13
+ Object.entries({
14
+ rootDir: process.cwd(),
15
+ env: (process.env.NODE_ENV as Env) || Env.DEV,
16
+ port: 8080,
17
+ httpPort: 8080,
18
+ httpsPort: 8000,
19
+ version: "1.0.0",
20
+ scopes: {
21
+ [ProviderType.CONTROLLER]: ProviderScope.SINGLETON
22
+ },
23
+ logger: {
24
+ debug: false,
25
+ level: "info",
26
+ logRequest: true,
27
+ jsonIndentation: process.env.NODE_ENV === Env.PROD ? 0 : 2
28
+ },
29
+ errors: {
30
+ headerName: "errors"
31
+ },
32
+ mount: {},
33
+ controllerScope: ProviderScope.SINGLETON
34
+ }).forEach(([key, value]) => {
35
+ settings[key] = value;
36
+ });
37
+
38
+ settings.env = Env.TEST;
39
+
40
+ settings.set("ownConfig", "test");
41
+ settings.set({ownConfig2: "test"} as any);
42
+ settings.version = "1.0.0";
43
+ settings.httpsOptions = {test: "/rest"} as any;
44
+ settings.acceptMimes = ["application/json"];
45
+ settings.statics = {"/": "/public"};
46
+ settings.routers = {mergeParams: true};
47
+ settings.exclude = ["./**/*.spec.ts"];
48
+ settings.debug = true;
49
+ //settings.jsonMapper = {};
50
+
51
+ settings.setHttpPort({address: "address", port: 8081});
52
+ settings.setHttpsPort({address: "address", port: 8080});
53
+ });
54
+
55
+ it("should return rootDir", () => {
56
+ expect(settings.rootDir).toEqual(process.cwd());
57
+ });
58
+
59
+ it("should return custom keys", () => {
60
+ expect(settings.get("ownConfig")).toEqual("test");
61
+ });
62
+
63
+ it("should return env", () => {
64
+ expect(settings.env).toEqual(Env.TEST);
65
+ });
66
+
67
+ it("should have logging jsonIndentaion set to 2", () => {
68
+ expect(settings.logger.jsonIndentation).toEqual(2);
69
+ });
70
+
71
+ it("should return httpsPort", () => {
72
+ expect(settings.httpsPort).toEqual("address:8080");
73
+ });
74
+
75
+ it("should return httpPort", () => {
76
+ expect(settings.httpPort).toEqual("address:8081");
77
+ });
78
+
79
+ it("should return the best host", () => {
80
+ const info = settings.getHttpsPort();
81
+ expect(info).toEqual({
82
+ protocol: "https",
83
+ address: "address",
84
+ port: 8080,
85
+ toString: info.toString
86
+ });
87
+ expect(settings.getBestHost().toString()).toEqual("https://address:8080");
88
+ });
89
+
90
+ it("should return httpPort multiple usecase", () => {
91
+ const info = settings.getHttpPort();
92
+ expect(info).toEqual({
93
+ protocol: "http",
94
+ address: "address",
95
+ port: 8081,
96
+ toString: info.toString
97
+ });
98
+ expect(settings.getBestHost().toString()).toEqual("https://address:8080");
99
+
100
+ settings.set("httpsPort", false);
101
+ expect(settings.getBestHost().toString()).toEqual("http://address:8081");
102
+
103
+ settings.set("httpPort", false);
104
+ expect(settings.getBestHost().toString()).toEqual("/");
105
+ });
106
+
107
+ it("should return httpsOptions", () => {
108
+ expect((settings.httpsOptions as any).test).toEqual("/rest");
109
+ });
110
+
111
+ it("should return acceptMimes", () => {
112
+ expect(settings.acceptMimes[0]).toEqual("application/json");
113
+ });
114
+
115
+ it("should return statics", () => {
116
+ expect(settings.statics).toEqual({"/": "/public"});
117
+ });
118
+
119
+ describe("debug", () => {
120
+ it("should expose debug as initialized", () => {
121
+ expect(settings.debug).toEqual(true);
122
+ });
123
+
124
+ it("debug should be equal to the last set value", () => {
125
+ settings.debug = false;
126
+ expect(settings.debug).toEqual(false);
127
+ });
128
+ });
129
+
130
+ it("should return additionalProperties", () => {
131
+ expect(settings.additionalProperties).toEqual(false);
132
+ });
133
+
134
+ it("should return version", () => {
135
+ expect(settings.version).toEqual("1.0.0");
136
+ });
137
+
138
+ it("should return errors", () => {
139
+ expect(settings.errors).toEqual({headerName: "errors"});
140
+ });
141
+
142
+ it("should return routers", () => {
143
+ expect(settings.routers).toEqual({mergeParams: true});
144
+ });
145
+
146
+ it("should return jsonMapper settings", () => {
147
+ expect(settings.jsonMapper).toEqual({
148
+ disableUnsecureConstructor: true,
149
+ additionalProperties: false,
150
+ strictGroups: false
151
+ });
152
+ });
153
+
154
+ it("should return controllerScope", () => {
155
+ expect(settings.controllerScope).toEqual("singleton");
156
+ });
157
+
158
+ it("should return excluded patterns", () => {
159
+ expect(settings.exclude).toEqual(["./**/*.spec.ts"]);
160
+ });
161
+
162
+ describe("forEach()", () => {
163
+ it("should loop on items", () => {
164
+ const result = [];
165
+ settings.forEach((o: any) => result.push(o));
166
+ expect(!!result.length).toEqual(true);
167
+ });
168
+ });
169
+
170
+ describe("port", () => {
171
+ it("should set port", () => {
172
+ const settings = new PlatformConfiguration();
173
+
174
+ settings.set({port: 8081});
175
+
176
+ expect(settings.httpPort).toEqual(8081);
177
+ expect(settings.port).toEqual(8081);
178
+ });
179
+ });
180
+ });
181
+ });
@@ -0,0 +1,157 @@
1
+ import {getHostInfoFromPort, isBoolean} from "@tsed/core";
2
+ import {DIConfiguration, Injectable, ProviderScope, TokenProvider} from "@tsed/di";
3
+ import {JsonMapperSettings} from "@tsed/json-mapper";
4
+ import Https from "https";
5
+
6
+ import {PlatformJsonMapperSettings} from "../interfaces/PlatformJsonMapperSettings.js";
7
+
8
+ const rootDir = process.cwd();
9
+
10
+ /**
11
+ * `PlatformConfiguration` contains all information about your Server configuration.
12
+ */
13
+ @Injectable({
14
+ scope: ProviderScope.SINGLETON,
15
+ global: true
16
+ })
17
+ export class PlatformConfiguration extends DIConfiguration {
18
+ constructor() {
19
+ super({rootDir});
20
+ }
21
+
22
+ get port(): string | number | false {
23
+ return this.httpPort;
24
+ }
25
+
26
+ set port(value: string | number | false) {
27
+ this.httpPort = value;
28
+ }
29
+
30
+ get httpsOptions(): Https.ServerOptions {
31
+ return this.getRaw("httpsOptions");
32
+ }
33
+
34
+ set httpsOptions(value: Https.ServerOptions) {
35
+ this.setRaw("httpsOptions", value);
36
+ }
37
+
38
+ get httpPort(): string | number | false {
39
+ return this.getRaw("httpPort");
40
+ }
41
+
42
+ set httpPort(value: string | number | false) {
43
+ this.setRaw("httpPort", value);
44
+ }
45
+
46
+ get httpsPort(): string | number | false {
47
+ return this.getRaw("httpsPort");
48
+ }
49
+
50
+ set httpsPort(value: string | number | false) {
51
+ this.setRaw("httpsPort", value);
52
+ }
53
+
54
+ get mount(): Record<string, TokenProvider[]> {
55
+ return this.get("mount");
56
+ }
57
+
58
+ set mount(value: Record<string, TokenProvider[]>) {
59
+ this.setRaw("mount", value);
60
+ }
61
+
62
+ get statics(): Record<string, (any | string)[]> {
63
+ return this.getRaw("statics") || this.getRaw("serveStatic") || {};
64
+ }
65
+
66
+ set statics(value: Record<string, (any | string)[]>) {
67
+ this.setRaw("statics", value);
68
+ }
69
+
70
+ get acceptMimes(): string[] {
71
+ return this.getRaw("acceptMimes");
72
+ }
73
+
74
+ set acceptMimes(value: string[]) {
75
+ this.setRaw("acceptMimes", value || []);
76
+ }
77
+
78
+ get jsonMapper(): Partial<PlatformJsonMapperSettings> {
79
+ return {
80
+ ...JsonMapperSettings
81
+ };
82
+ }
83
+
84
+ set jsonMapper(options: Partial<PlatformJsonMapperSettings>) {
85
+ JsonMapperSettings.strictGroups = Boolean(options.strictGroups);
86
+ JsonMapperSettings.disableUnsecureConstructor = Boolean(options.disableUnsecureConstructor);
87
+ JsonMapperSettings.additionalProperties = Boolean(
88
+ isBoolean(options.additionalProperties) ? options.additionalProperties : options.additionalProperties === "accept"
89
+ );
90
+ }
91
+
92
+ get additionalProperties() {
93
+ return this.get("converter.additionalProperties") === "accept";
94
+ }
95
+
96
+ /**
97
+ *
98
+ * @returns {string|number}
99
+ */
100
+ getHttpPort(): ReturnType<typeof getHostInfoFromPort> {
101
+ return getHostInfoFromPort("http", this.getRaw("httpPort"));
102
+ }
103
+
104
+ /**
105
+ *
106
+ * @param settings
107
+ */
108
+ setHttpPort(settings: {address: string; port: number}) {
109
+ this.setRaw("httpPort", `${settings.address}:${settings.port}`);
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @returns {string|number}
115
+ */
116
+ getHttpsPort() {
117
+ return getHostInfoFromPort("https", this.getRaw("httpsPort"));
118
+ }
119
+
120
+ /**
121
+ *
122
+ * @param settings
123
+ */
124
+ setHttpsPort(settings: {address: string; port: number}) {
125
+ this.setRaw("httpsPort", `${settings.address}:${settings.port}`);
126
+ }
127
+
128
+ getBestHost() {
129
+ const {httpsPort, httpPort} = this;
130
+
131
+ if (httpsPort) {
132
+ return this.getHttpsPort();
133
+ }
134
+
135
+ if (httpPort) {
136
+ return this.getHttpPort();
137
+ }
138
+
139
+ return {
140
+ toString() {
141
+ return "/";
142
+ }
143
+ };
144
+ }
145
+ }
146
+
147
+ declare global {
148
+ namespace TsED {
149
+ // @ts-ignore
150
+ interface Context {}
151
+
152
+ /**
153
+ * Here to allow extension on DIConfiguration base service
154
+ */
155
+ interface DIConfiguration extends PlatformConfiguration {}
156
+ }
157
+ }
@@ -0,0 +1 @@
1
+ export const ROUTER_OPTIONS = Symbol.for("ROUTER_OPTIONS");
@@ -0,0 +1,14 @@
1
+ import {Type} from "@tsed/core";
2
+
3
+ import {adapter} from "../fn/adapter.js";
4
+ import {PlatformAdapter} from "../services/PlatformAdapter.js";
5
+
6
+ /**
7
+ * Register a new platform adapter.
8
+ * @decorator
9
+ */
10
+ export function PlatformProvider() {
11
+ return (klass: Type<PlatformAdapter>) => {
12
+ adapter(klass);
13
+ };
14
+ }
@@ -0,0 +1,22 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware.js";
4
+ import {MulterFileSize} from "./multerFileSize.js";
5
+
6
+ describe("MulterFileSize", () => {
7
+ it("should set the file size", () => {
8
+ class Test {
9
+ @MulterFileSize(100)
10
+ file() {}
11
+ }
12
+
13
+ const store = Store.fromMethod(Test, "file");
14
+ expect(store.get(PlatformMulterMiddleware)).toEqual({
15
+ options: {
16
+ limits: {
17
+ fileSize: 100
18
+ }
19
+ }
20
+ });
21
+ });
22
+ });
@@ -0,0 +1,32 @@
1
+ import {MulterOptions} from "./multerOptions.js";
2
+
3
+ /**
4
+ * Define file size limit.
5
+ *
6
+ * ```typescript
7
+ * import {Post} from "@tsed/schema";
8
+ * import {MulterOptions, MultipartFile} from "@tsed/platform-http";
9
+ * import {Controller} from "@tsed/di";
10
+ * import {Multer} from "@types/multer";
11
+ *
12
+ * type MulterFile = Express.Multer.File;
13
+ *
14
+ * @Controller('/')
15
+ * class MyCtrl {
16
+ * @Post('/file2')
17
+ * @MulterFileSize(1024) // (Ko). Applied for all fields
18
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
19
+ *
20
+ * }
21
+ * }
22
+ * ```
23
+ *
24
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
25
+ * @param fileSize
26
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
27
+ * @decorator
28
+ * @multer
29
+ */
30
+ export function MulterFileSize(fileSize: number): MethodDecorator {
31
+ return MulterOptions({limits: {fileSize}});
32
+ }
@@ -0,0 +1,21 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware.js";
4
+ import {MulterOptions} from "./multerOptions.js";
5
+
6
+ describe("@MulterOptions()", () => {
7
+ it("should store metadata", () => {
8
+ class Test {
9
+ @MulterOptions({dest: "/"})
10
+ test() {}
11
+ }
12
+
13
+ const store = Store.fromMethod(Test.prototype, "test");
14
+
15
+ expect(store.get(PlatformMulterMiddleware)).toEqual({
16
+ options: {
17
+ dest: "/"
18
+ }
19
+ });
20
+ });
21
+ });
@@ -0,0 +1,53 @@
1
+ import {StoreMerge} from "@tsed/core";
2
+
3
+ import {PlatformMulterSettings} from "../../config/interfaces/PlatformMulterSettings.js";
4
+ import {PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware.js";
5
+
6
+ /**
7
+ * Define multer option for all MultipartFile
8
+ *
9
+ * ```typescript
10
+ * import {PlatformMulterFile, MultipartFile, MulterOptions} from "@tsed/platform-http";
11
+ * import {Controller} from "@tsed/di";
12
+ * import {Post} from "@tsed/schema";
13
+ *
14
+ * @Controller('/')
15
+ * class MyCtrl {
16
+ * @Post('/file')
17
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
18
+ *
19
+ * }
20
+ *
21
+ * @Post('/file')
22
+ * @MulterOptions({dest: "/other-dir"})
23
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
24
+ *
25
+ * }
26
+ *
27
+ * @Post('/file2')
28
+ * @MulterOptions({dest: "/other-dir"})
29
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile, @MultipartFile("file2") file2: PlatformMulterFile) {
30
+ *
31
+ * }
32
+ *
33
+ * @Post('/files')
34
+ * private uploadFile(@MultipartFile("file1") files: PlatformMulterFile[]) {
35
+ *
36
+ * }
37
+ * }
38
+ * ```
39
+ *
40
+ * See the tutorial on the [multer configuration](/docs/upload-files.md).
41
+ *
42
+ * @param {multer.Options} options
43
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
44
+ * @decorator
45
+ * @multer
46
+ */
47
+ export function MulterOptions(options: PlatformMulterSettings): MethodDecorator {
48
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
49
+ StoreMerge(PlatformMulterMiddleware, {options})(target, propertyKey, descriptor);
50
+
51
+ return descriptor;
52
+ };
53
+ }