@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.
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/decorator.js +0 -1
- package/dist/cjs/src/decorator.js.map +1 -1
- package/dist/cjs/src/http.js +11 -3
- package/dist/cjs/src/http.js.map +1 -1
- package/dist/cjs/src/kernel.js +4 -2
- package/dist/cjs/src/kernel.js.map +1 -1
- package/dist/cjs/src/model.d.ts +7 -0
- package/dist/cjs/src/model.js +4 -4
- package/dist/cjs/src/model.js.map +1 -1
- package/dist/cjs/src/module.config.d.ts +0 -1
- package/dist/cjs/src/module.config.js +0 -1
- package/dist/cjs/src/module.config.js.map +1 -1
- package/dist/cjs/src/module.d.ts +0 -2
- package/dist/cjs/src/module.js +8 -2
- package/dist/cjs/src/module.js.map +1 -1
- package/dist/cjs/src/router.d.ts +1 -1
- package/dist/cjs/src/router.js +27 -32
- package/dist/cjs/src/router.js.map +1 -1
- package/dist/cjs/tests/model.spec.d.ts +1 -0
- package/dist/cjs/tests/model.spec.js +23 -0
- package/dist/cjs/tests/model.spec.js.map +1 -0
- package/dist/cjs/tests/router.spec.js +68 -0
- package/dist/cjs/tests/router.spec.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/src/decorator.js +0 -1
- package/dist/esm/src/decorator.js.map +1 -1
- package/dist/esm/src/http.js +11 -3
- package/dist/esm/src/http.js.map +1 -1
- package/dist/esm/src/kernel.js +4 -2
- package/dist/esm/src/kernel.js.map +1 -1
- package/dist/esm/src/model.d.ts +7 -0
- package/dist/esm/src/model.js +4 -4
- package/dist/esm/src/model.js.map +1 -1
- package/dist/esm/src/module.config.d.ts +0 -1
- package/dist/esm/src/module.config.js +0 -1
- package/dist/esm/src/module.config.js.map +1 -1
- package/dist/esm/src/module.d.ts +0 -2
- package/dist/esm/src/module.js +8 -2
- package/dist/esm/src/module.js.map +1 -1
- package/dist/esm/src/router.d.ts +1 -1
- package/dist/esm/src/router.js +27 -32
- package/dist/esm/src/router.js.map +1 -1
- package/dist/esm/tests/model.spec.d.ts +1 -0
- package/dist/esm/tests/model.spec.js +21 -0
- package/dist/esm/tests/model.spec.js.map +1 -0
- package/dist/esm/tests/router.spec.js +68 -0
- package/dist/esm/tests/router.spec.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/index.ts +1 -0
- package/package.json +11 -11
- package/src/decorator.ts +0 -2
- package/src/http.ts +11 -3
- package/src/kernel.ts +4 -2
- package/src/model.ts +10 -3
- package/src/module.config.ts +0 -1
- package/src/module.ts +8 -2
- package/src/router.ts +27 -33
- package/tests/model.spec.ts +26 -0
- 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
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|
|
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.
|
|
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.
|
|
740
|
-
const _url = request.
|
|
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
|
-
|
|
783
|
-
|
|
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
|
+
});
|
package/tests/router.spec.ts
CHANGED
|
@@ -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
|
+
});
|