@deepkit/http 1.0.1-alpha.54 → 1.0.1-alpha.59

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 (65) hide show
  1. package/dist/cjs/index.d.ts +1 -0
  2. package/dist/cjs/index.js +1 -0
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/src/decorator.js +0 -1
  5. package/dist/cjs/src/decorator.js.map +1 -1
  6. package/dist/cjs/src/http.js +11 -3
  7. package/dist/cjs/src/http.js.map +1 -1
  8. package/dist/cjs/src/kernel.js +4 -2
  9. package/dist/cjs/src/kernel.js.map +1 -1
  10. package/dist/cjs/src/model.d.ts +7 -0
  11. package/dist/cjs/src/model.js +4 -4
  12. package/dist/cjs/src/model.js.map +1 -1
  13. package/dist/cjs/src/module.config.d.ts +0 -1
  14. package/dist/cjs/src/module.config.js +0 -1
  15. package/dist/cjs/src/module.config.js.map +1 -1
  16. package/dist/cjs/src/module.d.ts +0 -2
  17. package/dist/cjs/src/module.js +8 -2
  18. package/dist/cjs/src/module.js.map +1 -1
  19. package/dist/cjs/src/router.d.ts +1 -1
  20. package/dist/cjs/src/router.js +27 -32
  21. package/dist/cjs/src/router.js.map +1 -1
  22. package/dist/cjs/tests/model.spec.d.ts +1 -0
  23. package/dist/cjs/tests/model.spec.js +23 -0
  24. package/dist/cjs/tests/model.spec.js.map +1 -0
  25. package/dist/cjs/tests/router.spec.js +68 -0
  26. package/dist/cjs/tests/router.spec.js.map +1 -1
  27. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  28. package/dist/esm/index.d.ts +1 -0
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/src/decorator.js +0 -1
  32. package/dist/esm/src/decorator.js.map +1 -1
  33. package/dist/esm/src/http.js +11 -3
  34. package/dist/esm/src/http.js.map +1 -1
  35. package/dist/esm/src/kernel.js +4 -2
  36. package/dist/esm/src/kernel.js.map +1 -1
  37. package/dist/esm/src/model.d.ts +7 -0
  38. package/dist/esm/src/model.js +4 -4
  39. package/dist/esm/src/model.js.map +1 -1
  40. package/dist/esm/src/module.config.d.ts +0 -1
  41. package/dist/esm/src/module.config.js +0 -1
  42. package/dist/esm/src/module.config.js.map +1 -1
  43. package/dist/esm/src/module.d.ts +0 -2
  44. package/dist/esm/src/module.js +8 -2
  45. package/dist/esm/src/module.js.map +1 -1
  46. package/dist/esm/src/router.d.ts +1 -1
  47. package/dist/esm/src/router.js +27 -32
  48. package/dist/esm/src/router.js.map +1 -1
  49. package/dist/esm/tests/model.spec.d.ts +1 -0
  50. package/dist/esm/tests/model.spec.js +21 -0
  51. package/dist/esm/tests/model.spec.js.map +1 -0
  52. package/dist/esm/tests/router.spec.js +68 -0
  53. package/dist/esm/tests/router.spec.js.map +1 -1
  54. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  55. package/index.ts +1 -0
  56. package/package.json +11 -11
  57. package/src/decorator.ts +0 -2
  58. package/src/http.ts +11 -3
  59. package/src/kernel.ts +4 -2
  60. package/src/model.ts +10 -3
  61. package/src/module.config.ts +0 -1
  62. package/src/module.ts +8 -2
  63. package/src/router.ts +27 -33
  64. package/tests/model.spec.ts +26 -0
  65. package/tests/router.spec.ts +59 -0
package/src/router.ts CHANGED
@@ -77,18 +77,6 @@ export class UploadedFile {
77
77
  // @t.string.required.nullable hash!: string | 'sha1' | 'md5' | 'sha256' | null;
78
78
  }
79
79
 
80
- function parseBody(form: any, req: IncomingMessage, files: { [name: string]: UploadedFile }) {
81
- return asyncOperation((resolve, reject) => {
82
- form.parse(req, (err: any, fields: any, files: any) => {
83
- if (err) {
84
- reject(err);
85
- } else {
86
- resolve({ fields, files });
87
- }
88
- });
89
- });
90
- }
91
-
92
80
  export interface RouteControllerAction {
93
81
  //if not set, the root module is used
94
82
  module?: AppModule<any>;
@@ -413,12 +401,26 @@ export class Router {
413
401
 
414
402
  protected routes: RouteConfig[] = [];
415
403
 
416
- //todo, move some settings to KernelConfig
417
- protected form = formidable({
418
- multiples: true,
419
- hash: 'sha1',
420
- enabledPlugins: ['octetstream', 'querystring', 'json'],
421
- });
404
+ private parseBody(req: HttpRequest, files: { [name: string]: UploadedFile }) {
405
+ const form = formidable({
406
+ multiples: true,
407
+ hash: 'sha1',
408
+ enabledPlugins: ['octetstream', 'querystring', 'json'],
409
+ });
410
+ return asyncOperation((resolve, reject) => {
411
+ if (req.body) {
412
+ return resolve(req.body);
413
+ }
414
+ form.parse(req, (err: any, fields: any, files: any) => {
415
+ if (err) {
416
+ reject(err);
417
+ } else {
418
+ const body = req.body = { ...fields, ...files };
419
+ resolve(body);
420
+ }
421
+ });
422
+ });
423
+ }
422
424
 
423
425
  constructor(
424
426
  controllers: HttpControllers,
@@ -571,11 +573,9 @@ export class Router {
571
573
 
572
574
  let parseBodyLoading = '';
573
575
  if (enableParseBody) {
574
- const parseBodyVar = compiler.reserveVariable('parseBody', parseBody);
575
- const formVar = compiler.reserveVariable('form', this.form);
576
+ const parseBodyVar = compiler.reserveVariable('parseBody', this.parseBody.bind(this));
576
577
  parseBodyLoading = `
577
- const bodyParsed = (await ${parseBodyVar}(${formVar}, request, uploadedFiles));
578
- const bodyFields = {...bodyParsed.fields, ...bodyParsed.files};`;
578
+ const bodyFields = (await ${parseBodyVar}(request, uploadedFiles));`;
579
579
  requiresAsyncParameters = true;
580
580
  }
581
581
 
@@ -626,7 +626,7 @@ export class Router {
626
626
  let methodCheck = '';
627
627
  if (routeConfig.httpMethods.length) {
628
628
  methodCheck = '(' + routeConfig.httpMethods.map(v => {
629
- return `_method === '${v.toLowerCase()}'`;
629
+ return `_method === '${v.toUpperCase()}'`;
630
630
  }).join(' || ') + ') && ';
631
631
  }
632
632
 
@@ -736,8 +736,8 @@ export class Router {
736
736
 
737
737
  return compiler.build(`
738
738
  let _match;
739
- const _method = request.getMethod().toLowerCase();
740
- const _url = request.getUrl();
739
+ const _method = request.method || 'GET';
740
+ const _url = request.url || '/';
741
741
  const _qPosition = _url.indexOf('?');
742
742
  let uploadedFiles = {};
743
743
  const _path = _qPosition === -1 ? _url : _url.substr(0, _qPosition);
@@ -779,13 +779,7 @@ export class Router {
779
779
  }
780
780
 
781
781
  public resolve(method: string, url: string): ResolvedController | undefined {
782
- return this.resolveRequest({
783
- getUrl() {
784
- return url;
785
- },
786
- getMethod() {
787
- return method;
788
- },
789
- } as any);
782
+ method = method.toUpperCase();
783
+ return this.resolveRequest({url, method} as any);
790
784
  }
791
785
  }
@@ -0,0 +1,26 @@
1
+ import { expect, test } from '@jest/globals';
2
+ import { HttpRequest } from '../src/model';
3
+
4
+ test('request model json', async () => {
5
+ const request = HttpRequest.POST('/').json({ hello: 'world' }).build();
6
+ const buffers = [];
7
+
8
+ for await (const chunk of request) {
9
+ buffers.push(chunk);
10
+ }
11
+
12
+ const bodyBuffer = Buffer.concat(buffers).toString();
13
+ expect(bodyBuffer).toBe('{"hello":"world"}');
14
+ });
15
+
16
+ test('request model body', async () => {
17
+ const request = HttpRequest.POST('/').body("hello").build();
18
+ const buffers = [];
19
+
20
+ for await (const chunk of request) {
21
+ buffers.push(chunk);
22
+ }
23
+
24
+ const bodyBuffer = Buffer.concat(buffers).toString();
25
+ expect(bodyBuffer).toBe('hello');
26
+ });
@@ -263,6 +263,29 @@ test('router body', async () => {
263
263
  expect((await httpKernel.request(HttpRequest.POST('/').json({ username: 'Peter' }))).json).toEqual(['Peter', true, '/']);
264
264
  });
265
265
 
266
+ test('router body is safe for simultaneous requests', async () => {
267
+ class Body {
268
+ @t username!: string;
269
+ }
270
+
271
+ class Controller {
272
+ @http.POST()
273
+ anyReq(@http.body() body: Body, req: HttpRequest) {
274
+ return [body.username, body instanceof Body, req.url];
275
+ }
276
+ }
277
+
278
+ const httpKernel = createHttpKernel([Controller]);
279
+
280
+ const makeReq = () => httpKernel.request(HttpRequest.POST('/').json({ username: 'Peter' }));
281
+
282
+ const results = await Promise.all([...new Array(100)].map(() => makeReq().then(res => res.json)));
283
+
284
+ expect(results).toEqual(
285
+ results.map(() => ['Peter', true, '/']),
286
+ )
287
+ });
288
+
266
289
 
267
290
  test('router body double', async () => {
268
291
  class Body {
@@ -722,3 +745,39 @@ test('dynamic parameter name', async () => {
722
745
  expect((await httpKernel.request(HttpRequest.GET('/first/peter'))).json).toEqual(['peter']);
723
746
  expect((await httpKernel.request(HttpRequest.GET('/second/peter?second=true'))).json).toEqual(['peter', 'true']);
724
747
  });
748
+
749
+
750
+ test('use http.response for serialization', async () => {
751
+ const schemaString = t.schema({
752
+ title: t.string
753
+ });
754
+
755
+ const errorSchema = t.schema({
756
+ message: t.string
757
+ });
758
+
759
+ class Controller {
760
+ @http.GET('/action1')
761
+ @t.array(schemaString)
762
+ action1() {
763
+ return [{title: 'a'}, {title: 1}];
764
+ }
765
+
766
+ @http.GET('/action2').response(200, `List`, t.array(schemaString))
767
+ action2() {
768
+ return [{title: 'a'}, {title: 1}];
769
+ }
770
+
771
+ @http.GET('/action3')
772
+ .response(200, `List`, t.array(schemaString))
773
+ .response(400, `Error`, t.array(errorSchema))
774
+ action3() {
775
+ return new JSONResponse([{message: 'error'}, {message: 1}]).status(400);
776
+ }
777
+ }
778
+
779
+ const httpKernel = createHttpKernel([Controller]);
780
+ expect((await httpKernel.request(HttpRequest.GET('/action1'))).json).toEqual([{title: 'a'}, {title: '1'}]);
781
+ expect((await httpKernel.request(HttpRequest.GET('/action2'))).json).toEqual([{title: 'a'}, {title: '1'}]);
782
+ expect((await httpKernel.request(HttpRequest.GET('/action3'))).json).toEqual([{message: 'error'}, {message: '1'}]);
783
+ });