@deepkit/http 1.0.1-alpha.59 → 1.0.1-alpha.63
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/coverage/clover.xml +1086 -0
- package/coverage/coverage-final.json +12 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +126 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov-report/src/controllers.ts.html +113 -0
- package/coverage/lcov-report/src/decorator.ts.html +1280 -0
- package/coverage/lcov-report/src/filter.ts.html +734 -0
- package/coverage/lcov-report/src/http.ts.html +2192 -0
- package/coverage/lcov-report/src/index.html +246 -0
- package/coverage/lcov-report/src/kernel.ts.html +260 -0
- package/coverage/lcov-report/src/middleware.ts.html +428 -0
- package/coverage/lcov-report/src/model.ts.html +937 -0
- package/coverage/lcov-report/src/module.config.ts.html +89 -0
- package/coverage/lcov-report/src/module.ts.html +245 -0
- package/coverage/lcov-report/src/router.ts.html +2318 -0
- package/coverage/lcov-report/tests/index.html +111 -0
- package/coverage/lcov-report/tests/utils.ts.html +176 -0
- package/coverage/lcov.info +2225 -0
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/controllers.d.ts +4 -4
- package/dist/cjs/src/controllers.js +3 -0
- package/dist/cjs/src/controllers.js.map +1 -1
- package/dist/cjs/src/decorator.d.ts +29 -94
- package/dist/cjs/src/decorator.js +53 -118
- package/dist/cjs/src/decorator.js.map +1 -1
- package/dist/cjs/src/filter.d.ts +1 -0
- package/dist/cjs/src/filter.js +11 -17
- package/dist/cjs/src/filter.js.map +1 -1
- package/dist/cjs/src/http.d.ts +5 -3
- package/dist/cjs/src/http.js +91 -55
- package/dist/cjs/src/http.js.map +1 -1
- package/dist/cjs/src/kernel.d.ts +3 -3
- package/dist/cjs/src/kernel.js +5 -25
- package/dist/cjs/src/kernel.js.map +1 -1
- package/dist/cjs/src/logger.d.ts +2 -2
- package/dist/cjs/src/logger.js +4 -8
- package/dist/cjs/src/logger.js.map +1 -1
- package/dist/cjs/src/middleware.d.ts +5 -1
- package/dist/cjs/src/middleware.js +15 -3
- package/dist/cjs/src/middleware.js.map +1 -1
- package/dist/cjs/src/model.d.ts +62 -2
- package/dist/cjs/src/model.js +101 -26
- package/dist/cjs/src/model.js.map +1 -1
- package/dist/cjs/src/module.config.d.ts +3 -4
- package/dist/cjs/src/module.config.js +8 -6
- package/dist/cjs/src/module.config.js.map +1 -1
- package/dist/cjs/src/module.d.ts +2 -3
- package/dist/cjs/src/module.js +4 -2
- package/dist/cjs/src/module.js.map +1 -1
- package/dist/cjs/src/router.d.ts +24 -53
- package/dist/cjs/src/router.js +140 -159
- package/dist/cjs/src/router.js.map +1 -1
- package/dist/cjs/src/static-serving.d.ts +1 -0
- package/dist/cjs/src/static-serving.js +46 -39
- package/dist/cjs/src/static-serving.js.map +1 -1
- package/dist/cjs/src/utils.js +1 -0
- package/dist/cjs/tests/filter.spec.js +61 -47
- package/dist/cjs/tests/filter.spec.js.map +1 -1
- package/dist/cjs/tests/middleware.spec.d.ts +1 -1
- package/dist/cjs/tests/middleware.spec.js +157 -145
- package/dist/cjs/tests/middleware.spec.js.map +1 -1
- package/dist/cjs/tests/model.spec.js +4 -4
- package/dist/cjs/tests/model.spec.js.map +1 -1
- package/dist/cjs/tests/module.spec.js +4 -3
- package/dist/cjs/tests/module.spec.js.map +1 -1
- package/dist/cjs/tests/router.spec.d.ts +1 -1
- package/dist/cjs/tests/router.spec.js +298 -333
- package/dist/cjs/tests/router.spec.js.map +1 -1
- package/dist/cjs/tests/utils.js +5 -2
- package/dist/cjs/tests/utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/src/controllers.d.ts +4 -4
- package/dist/esm/src/controllers.js +3 -0
- package/dist/esm/src/controllers.js.map +1 -1
- package/dist/esm/src/decorator.d.ts +29 -94
- package/dist/esm/src/decorator.js +49 -114
- package/dist/esm/src/decorator.js.map +1 -1
- package/dist/esm/src/filter.d.ts +1 -0
- package/dist/esm/src/filter.js +11 -18
- package/dist/esm/src/filter.js.map +1 -1
- package/dist/esm/src/http.d.ts +5 -3
- package/dist/esm/src/http.js +89 -55
- package/dist/esm/src/http.js.map +1 -1
- package/dist/esm/src/kernel.d.ts +3 -3
- package/dist/esm/src/kernel.js +6 -27
- package/dist/esm/src/kernel.js.map +1 -1
- package/dist/esm/src/logger.d.ts +2 -2
- package/dist/esm/src/logger.js +4 -9
- package/dist/esm/src/logger.js.map +1 -1
- package/dist/esm/src/middleware.d.ts +5 -1
- package/dist/esm/src/middleware.js +12 -0
- package/dist/esm/src/middleware.js.map +1 -1
- package/dist/esm/src/model.d.ts +62 -2
- package/dist/esm/src/model.js +92 -24
- package/dist/esm/src/model.js.map +1 -1
- package/dist/esm/src/module.config.d.ts +3 -4
- package/dist/esm/src/module.config.js +6 -5
- package/dist/esm/src/module.config.js.map +1 -1
- package/dist/esm/src/module.d.ts +2 -3
- package/dist/esm/src/module.js +5 -3
- package/dist/esm/src/module.js.map +1 -1
- package/dist/esm/src/router.d.ts +24 -53
- package/dist/esm/src/router.js +136 -155
- package/dist/esm/src/router.js.map +1 -1
- package/dist/esm/src/static-serving.d.ts +1 -0
- package/dist/esm/src/static-serving.js +39 -32
- package/dist/esm/src/static-serving.js.map +1 -1
- package/dist/esm/src/utils.js +1 -0
- package/dist/esm/tests/filter.spec.js +14 -0
- package/dist/esm/tests/filter.spec.js.map +1 -1
- package/dist/esm/tests/middleware.spec.d.ts +1 -1
- package/dist/esm/tests/middleware.spec.js +60 -48
- package/dist/esm/tests/middleware.spec.js.map +1 -1
- package/dist/esm/tests/module.spec.js +1 -0
- package/dist/esm/tests/module.spec.js.map +1 -1
- package/dist/esm/tests/router.spec.d.ts +1 -1
- package/dist/esm/tests/router.spec.js +167 -202
- package/dist/esm/tests/router.spec.js.map +1 -1
- package/dist/esm/tests/utils.js +4 -1
- package/dist/esm/tests/utils.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +14 -15
- package/src/controllers.ts +3 -3
- package/src/decorator.ts +42 -131
- package/src/filter.ts +0 -2
- package/src/http.ts +35 -36
- package/src/kernel.ts +4 -5
- package/src/logger.ts +2 -4
- package/src/middleware.ts +2 -1
- package/src/model.ts +80 -8
- package/src/module.config.ts +3 -6
- package/src/module.ts +2 -2
- package/src/router.ts +121 -161
- package/src/static-serving.ts +14 -12
- package/tests/middleware.spec.ts +0 -1
- package/tests/router.spec.ts +131 -133
- package/tsconfig.json +2 -1
package/tests/router.spec.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { expect, test } from '@jest/globals';
|
|
2
|
-
import '
|
|
3
|
-
import { dotToUrlPath, RouteParameterResolverContext, Router } from '../src/router';
|
|
2
|
+
import { dotToUrlPath, RouteParameterResolverContext, Router, UploadedFile } from '../src/router';
|
|
4
3
|
import { http, httpClass } from '../src/decorator';
|
|
5
|
-
import {
|
|
6
|
-
import { httpWorkflow, JSONResponse } from '../src/http';
|
|
4
|
+
import { HttpBadRequestError, httpWorkflow, JSONResponse } from '../src/http';
|
|
7
5
|
import { eventDispatcher } from '@deepkit/event';
|
|
8
|
-
import {
|
|
9
|
-
import { HttpRequest } from '../src/model';
|
|
6
|
+
import { HttpBody, HttpBodyValidation, HttpQueries, HttpQuery, HttpRegExp, HttpRequest } from '../src/model';
|
|
10
7
|
import { getClassName, sleep } from '@deepkit/core';
|
|
11
8
|
import { createHttpKernel } from './utils';
|
|
9
|
+
import { Group, MinLength } from '@deepkit/type';
|
|
12
10
|
|
|
13
11
|
test('router', async () => {
|
|
14
12
|
class Controller {
|
|
@@ -62,7 +60,6 @@ test('any', async () => {
|
|
|
62
60
|
expect((await router.resolve('OPTIONS', '/any'))!.routeConfig.action.methodName).toEqual('any');
|
|
63
61
|
});
|
|
64
62
|
|
|
65
|
-
|
|
66
63
|
test('router parameters', async () => {
|
|
67
64
|
class Controller {
|
|
68
65
|
@http.GET('/user/:name')
|
|
@@ -80,8 +77,8 @@ test('router parameters', async () => {
|
|
|
80
77
|
return new JSONResponse(yes);
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
@http.GET(':path')
|
|
84
|
-
any(path: string) {
|
|
80
|
+
@http.GET(':path')
|
|
81
|
+
any(path: HttpRegExp<string, '.*'>) {
|
|
85
82
|
return new JSONResponse(path);
|
|
86
83
|
}
|
|
87
84
|
}
|
|
@@ -93,7 +90,7 @@ test('router parameters', async () => {
|
|
|
93
90
|
|
|
94
91
|
expect((await httpKernel.request(HttpRequest.GET('/user/peter'))).json).toBe('peter');
|
|
95
92
|
expect((await httpKernel.request(HttpRequest.GET('/user-id/123'))).json).toBe(123);
|
|
96
|
-
expect((await httpKernel.request(HttpRequest.GET('/user-id/asd'))).json).toMatchObject({ message: 'Validation
|
|
93
|
+
expect((await httpKernel.request(HttpRequest.GET('/user-id/asd'))).json).toMatchObject({ message: 'Validation error:\nid(type): Cannot convert asd to number' });
|
|
97
94
|
expect((await httpKernel.request(HttpRequest.GET('/boolean/1'))).json).toBe(true);
|
|
98
95
|
expect((await httpKernel.request(HttpRequest.GET('/boolean/false'))).json).toBe(false);
|
|
99
96
|
|
|
@@ -103,8 +100,8 @@ test('router parameters', async () => {
|
|
|
103
100
|
|
|
104
101
|
test('router HttpRequest', async () => {
|
|
105
102
|
class Controller {
|
|
106
|
-
@http.GET(':path')
|
|
107
|
-
anyReq(req: HttpRequest, path: string) {
|
|
103
|
+
@http.GET(':path')
|
|
104
|
+
anyReq(req: HttpRequest, path: HttpRegExp<string, '.*'>) {
|
|
108
105
|
return [req.url, path];
|
|
109
106
|
}
|
|
110
107
|
}
|
|
@@ -246,14 +243,14 @@ test('router parameter resolver by name', async () => {
|
|
|
246
243
|
expect((await httpKernel.request(HttpRequest.GET('/nonClass'))).json).toEqual(['auth', 'MyAuth']);
|
|
247
244
|
});
|
|
248
245
|
|
|
249
|
-
test('router body', async () => {
|
|
246
|
+
test('router body class', async () => {
|
|
250
247
|
class Body {
|
|
251
|
-
|
|
248
|
+
username!: string;
|
|
252
249
|
}
|
|
253
250
|
|
|
254
251
|
class Controller {
|
|
255
252
|
@http.POST()
|
|
256
|
-
anyReq(
|
|
253
|
+
anyReq(body: HttpBody<Body>, req: HttpRequest) {
|
|
257
254
|
return [body.username, body instanceof Body, req.url];
|
|
258
255
|
}
|
|
259
256
|
}
|
|
@@ -265,12 +262,12 @@ test('router body', async () => {
|
|
|
265
262
|
|
|
266
263
|
test('router body is safe for simultaneous requests', async () => {
|
|
267
264
|
class Body {
|
|
268
|
-
|
|
265
|
+
username!: string;
|
|
269
266
|
}
|
|
270
267
|
|
|
271
268
|
class Controller {
|
|
272
269
|
@http.POST()
|
|
273
|
-
anyReq(
|
|
270
|
+
anyReq(body: HttpBody<Body>, req: HttpRequest) {
|
|
274
271
|
return [body.username, body instanceof Body, req.url];
|
|
275
272
|
}
|
|
276
273
|
}
|
|
@@ -286,15 +283,31 @@ test('router body is safe for simultaneous requests', async () => {
|
|
|
286
283
|
)
|
|
287
284
|
});
|
|
288
285
|
|
|
286
|
+
test('router body interface', async () => {
|
|
287
|
+
interface Body {
|
|
288
|
+
username: string;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
class Controller {
|
|
292
|
+
@http.POST()
|
|
293
|
+
anyReq(body: HttpBody<Body>, req: HttpRequest) {
|
|
294
|
+
return [body.username, typeof body.username, req.url];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const httpKernel = createHttpKernel([Controller]);
|
|
299
|
+
|
|
300
|
+
expect((await httpKernel.request(HttpRequest.POST('/').json({ username: 'Peter' }))).json).toEqual(['Peter', 'string', '/']);
|
|
301
|
+
});
|
|
289
302
|
|
|
290
303
|
test('router body double', async () => {
|
|
291
304
|
class Body {
|
|
292
|
-
|
|
305
|
+
username!: string;
|
|
293
306
|
}
|
|
294
307
|
|
|
295
308
|
class Controller {
|
|
296
309
|
@http.POST()
|
|
297
|
-
anyReq(
|
|
310
|
+
anyReq(body: HttpBody<Body>, body2: HttpBody<Body>, req: HttpRequest) {
|
|
298
311
|
return [body2.username, body2 instanceof Body && body instanceof Body, req.url];
|
|
299
312
|
}
|
|
300
313
|
}
|
|
@@ -304,10 +317,6 @@ test('router body double', async () => {
|
|
|
304
317
|
const action = [...httpData.getActions()][0];
|
|
305
318
|
expect(action.methodName).toBe('anyReq');
|
|
306
319
|
expect(action.httpMethods).toEqual(['POST']);
|
|
307
|
-
expect(action.parameters['body']).not.toBeUndefined();
|
|
308
|
-
expect(action.parameters['body'].name).toBe('body');
|
|
309
|
-
expect(action.parameters['body2']).not.toBeUndefined();
|
|
310
|
-
expect(action.parameters['body2'].name).toBe('body2');
|
|
311
320
|
|
|
312
321
|
const httpKernel = createHttpKernel([Controller]);
|
|
313
322
|
|
|
@@ -364,7 +373,7 @@ test('router groups', async () => {
|
|
|
364
373
|
test('router query', async () => {
|
|
365
374
|
class Controller {
|
|
366
375
|
@http.GET('my-action')
|
|
367
|
-
anyReq(
|
|
376
|
+
anyReq(test?: HttpQuery<number>) {
|
|
368
377
|
return test;
|
|
369
378
|
}
|
|
370
379
|
}
|
|
@@ -374,9 +383,6 @@ test('router query', async () => {
|
|
|
374
383
|
const action = [...httpData.getActions()][0];
|
|
375
384
|
expect(action.methodName).toBe('anyReq');
|
|
376
385
|
expect(action.httpMethods).toEqual(['GET']);
|
|
377
|
-
expect(action.parameters['test']).not.toBeUndefined();
|
|
378
|
-
expect(action.parameters['test'].name).toBe('test');
|
|
379
|
-
expect(action.parameters['test'].type).toBe('query');
|
|
380
386
|
|
|
381
387
|
const httpKernel = createHttpKernel([Controller]);
|
|
382
388
|
|
|
@@ -386,14 +392,14 @@ test('router query', async () => {
|
|
|
386
392
|
|
|
387
393
|
test('router query all', async () => {
|
|
388
394
|
class AnyReqQuery {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
395
|
+
test?: string;
|
|
396
|
+
filter?: string;
|
|
397
|
+
page?: number;
|
|
392
398
|
}
|
|
393
399
|
|
|
394
400
|
class Controller {
|
|
395
401
|
@http.GET('my-action')
|
|
396
|
-
anyReq(
|
|
402
|
+
anyReq(anyReqQuery: HttpQueries<AnyReqQuery>) {
|
|
397
403
|
return anyReqQuery;
|
|
398
404
|
}
|
|
399
405
|
}
|
|
@@ -407,14 +413,13 @@ test('router query all', async () => {
|
|
|
407
413
|
|
|
408
414
|
test('serializer options', async () => {
|
|
409
415
|
class User {
|
|
410
|
-
|
|
411
|
-
|
|
416
|
+
username!: string;
|
|
417
|
+
password!: string & Group<'sensitive'>;
|
|
412
418
|
}
|
|
413
419
|
|
|
414
420
|
class Controller {
|
|
415
421
|
@http.GET().serialization({ groupsExclude: ['sensitive'] })
|
|
416
|
-
|
|
417
|
-
anyReq() {
|
|
422
|
+
anyReq(): User {
|
|
418
423
|
return { username: 'Peter', password: 'secret' };
|
|
419
424
|
}
|
|
420
425
|
}
|
|
@@ -426,14 +431,13 @@ test('serializer options', async () => {
|
|
|
426
431
|
|
|
427
432
|
test('hook after serializer', async () => {
|
|
428
433
|
class User {
|
|
429
|
-
|
|
430
|
-
|
|
434
|
+
username!: string;
|
|
435
|
+
password!: string & Group<'sensitive'>;
|
|
431
436
|
}
|
|
432
437
|
|
|
433
438
|
class Controller {
|
|
434
439
|
@http.GET().serialization({ groupsExclude: ['sensitive'] })
|
|
435
|
-
|
|
436
|
-
async anyReq() {
|
|
440
|
+
async anyReq(): Promise<User> {
|
|
437
441
|
await sleep(0.1);
|
|
438
442
|
return { username: 'Peter', password: 'secret' };
|
|
439
443
|
}
|
|
@@ -461,10 +465,9 @@ test('invalid route definition', async () => {
|
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
const httpKernel = createHttpKernel([Controller]);
|
|
464
|
-
expect((await httpKernel.request(HttpRequest.GET('/'))).bodyString).toEqual('
|
|
468
|
+
expect((await httpKernel.request(HttpRequest.GET('/'))).bodyString).toEqual('Internal error');
|
|
465
469
|
});
|
|
466
470
|
|
|
467
|
-
|
|
468
471
|
test('inject request storage ClassType', async () => {
|
|
469
472
|
class User {
|
|
470
473
|
constructor(public username: string) {
|
|
@@ -478,7 +481,7 @@ test('inject request storage ClassType', async () => {
|
|
|
478
481
|
}
|
|
479
482
|
|
|
480
483
|
@http.GET('optional')
|
|
481
|
-
doItOptional(
|
|
484
|
+
doItOptional(user?: User) {
|
|
482
485
|
return { isUser: user instanceof User };
|
|
483
486
|
}
|
|
484
487
|
}
|
|
@@ -494,7 +497,7 @@ test('inject request storage ClassType', async () => {
|
|
|
494
497
|
|
|
495
498
|
const httpKernel = createHttpKernel([Controller], [
|
|
496
499
|
{
|
|
497
|
-
provide: User, scope: 'http',
|
|
500
|
+
provide: User, scope: 'http', useFactory(request: HttpRequest) {
|
|
498
501
|
return request.store.user;
|
|
499
502
|
}
|
|
500
503
|
}
|
|
@@ -506,40 +509,6 @@ test('inject request storage ClassType', async () => {
|
|
|
506
509
|
expect((await httpKernel.request(HttpRequest.GET('/optional').headers({ authorization: 'no' }))).json).toEqual({ isUser: false });
|
|
507
510
|
});
|
|
508
511
|
|
|
509
|
-
|
|
510
|
-
test('inject request storage @inject', async () => {
|
|
511
|
-
class User {
|
|
512
|
-
constructor(public username: string) {
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
class Controller {
|
|
517
|
-
@http.GET()
|
|
518
|
-
doIt(@inject('user') user: any) {
|
|
519
|
-
return { isUser: user instanceof User, username: user.username };
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
class Listener {
|
|
524
|
-
@eventDispatcher.listen(httpWorkflow.onAuth)
|
|
525
|
-
onAuth(event: typeof httpWorkflow.onAuth.event) {
|
|
526
|
-
event.request.store.user = new User('bar');
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const httpKernel = createHttpKernel([Controller], [
|
|
531
|
-
{
|
|
532
|
-
provide: 'user', scope: 'http', deps: [HttpRequest], useFactory(request: HttpRequest) {
|
|
533
|
-
return request.store.user;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
], [Listener]);
|
|
537
|
-
|
|
538
|
-
const result = (await httpKernel.request(HttpRequest.GET('/'))).json;
|
|
539
|
-
expect(result.isUser).toBe(true);
|
|
540
|
-
expect(result.username).toBe('bar');
|
|
541
|
-
});
|
|
542
|
-
|
|
543
512
|
test('custom request handling', async () => {
|
|
544
513
|
class Listener {
|
|
545
514
|
@eventDispatcher.listen(httpWorkflow.onRouteNotFound)
|
|
@@ -613,9 +582,8 @@ test('promise serializer', async () => {
|
|
|
613
582
|
}
|
|
614
583
|
|
|
615
584
|
@http.GET('2')
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
return 1;
|
|
585
|
+
async anyReq2(): Promise<string> {
|
|
586
|
+
return 1 as any;
|
|
619
587
|
}
|
|
620
588
|
}
|
|
621
589
|
|
|
@@ -625,20 +593,31 @@ test('promise serializer', async () => {
|
|
|
625
593
|
expect((await httpKernel.request(HttpRequest.GET('/2'))).json).toBe('1');
|
|
626
594
|
});
|
|
627
595
|
|
|
628
|
-
|
|
629
596
|
test('unions', async () => {
|
|
630
597
|
class Controller {
|
|
631
598
|
@http.GET('/list')
|
|
632
|
-
list(
|
|
599
|
+
list(page: HttpQuery<number | boolean>) {
|
|
633
600
|
return page;
|
|
634
601
|
}
|
|
635
602
|
}
|
|
636
603
|
|
|
637
604
|
const httpKernel = createHttpKernel([Controller]);
|
|
638
605
|
|
|
606
|
+
expect((await httpKernel.request(HttpRequest.GET('/list?page=0'))).json).toEqual(0);
|
|
639
607
|
expect((await httpKernel.request(HttpRequest.GET('/list?page=1'))).json).toEqual(1);
|
|
640
608
|
expect((await httpKernel.request(HttpRequest.GET('/list?page=2222'))).json).toEqual(2222);
|
|
641
609
|
expect((await httpKernel.request(HttpRequest.GET('/list?page=false'))).json).toEqual(false);
|
|
610
|
+
expect((await httpKernel.request(HttpRequest.GET('/list?page=true'))).json).toEqual(true);
|
|
611
|
+
|
|
612
|
+
expect((await httpKernel.request(HttpRequest.GET('/list?page=asdasdc'))).json).toMatchObject({
|
|
613
|
+
'errors': [
|
|
614
|
+
{
|
|
615
|
+
'code': 'type',
|
|
616
|
+
'message': 'No value given',
|
|
617
|
+
'path': 'page'
|
|
618
|
+
}
|
|
619
|
+
],
|
|
620
|
+
});
|
|
642
621
|
});
|
|
643
622
|
|
|
644
623
|
test('router dotToUrlPath', () => {
|
|
@@ -650,9 +629,9 @@ test('router dotToUrlPath', () => {
|
|
|
650
629
|
|
|
651
630
|
test('router url resolve', async () => {
|
|
652
631
|
class AnyReqQuery {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
632
|
+
test?: string;
|
|
633
|
+
filter?: string;
|
|
634
|
+
page?: number;
|
|
656
635
|
}
|
|
657
636
|
|
|
658
637
|
class Controller {
|
|
@@ -667,22 +646,22 @@ test('router url resolve', async () => {
|
|
|
667
646
|
}
|
|
668
647
|
|
|
669
648
|
@http.GET('').name('secondQuery')
|
|
670
|
-
secondQuery(
|
|
649
|
+
secondQuery(peter: HttpQuery<string>) {
|
|
671
650
|
return '';
|
|
672
651
|
}
|
|
673
652
|
|
|
674
653
|
@http.GET('').name('secondQuery2')
|
|
675
|
-
secondQuery2(
|
|
654
|
+
secondQuery2(peter: HttpQuery<string, { name: 'changed' }>) {
|
|
676
655
|
return '';
|
|
677
656
|
}
|
|
678
657
|
|
|
679
658
|
@http.GET('third').name('third')
|
|
680
|
-
third(
|
|
659
|
+
third(params: HttpQueries<AnyReqQuery>) {
|
|
681
660
|
return params;
|
|
682
661
|
}
|
|
683
662
|
|
|
684
663
|
@http.GET('third2').name('third2')
|
|
685
|
-
third2(
|
|
664
|
+
third2(params: HttpQueries<AnyReqQuery, { name: 'deep' }>) {
|
|
686
665
|
return params;
|
|
687
666
|
}
|
|
688
667
|
}
|
|
@@ -703,15 +682,14 @@ test('router url resolve', async () => {
|
|
|
703
682
|
});
|
|
704
683
|
|
|
705
684
|
test('destructing params', async () => {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
@t.required title!: string;
|
|
685
|
+
interface DTO {
|
|
686
|
+
name: string;
|
|
687
|
+
title: string;
|
|
710
688
|
}
|
|
711
689
|
|
|
712
690
|
class Controller {
|
|
713
691
|
@http.GET('')
|
|
714
|
-
first(
|
|
692
|
+
first({ name, title }: HttpBody<DTO>) {
|
|
715
693
|
return [name, title];
|
|
716
694
|
}
|
|
717
695
|
}
|
|
@@ -721,63 +699,83 @@ test('destructing params', async () => {
|
|
|
721
699
|
expect((await httpKernel.request(HttpRequest.GET('/').json({ name: 'Peter', title: 'CTO' }))).json).toEqual(['Peter', 'CTO']);
|
|
722
700
|
});
|
|
723
701
|
|
|
724
|
-
test('
|
|
725
|
-
|
|
702
|
+
test('use http.response for serialization', async () => {
|
|
703
|
+
interface DefaultResponse {
|
|
704
|
+
title: string;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
interface ErrorResponse {
|
|
708
|
+
message: string;
|
|
709
|
+
}
|
|
710
|
+
|
|
726
711
|
class Controller {
|
|
727
|
-
@http.GET('
|
|
728
|
-
|
|
729
|
-
return [
|
|
712
|
+
@http.GET('/action1')
|
|
713
|
+
action1(): DefaultResponse[] {
|
|
714
|
+
return [{ title: 'a' }, { title: '1' }];
|
|
730
715
|
}
|
|
731
716
|
|
|
732
|
-
@http.GET('
|
|
733
|
-
|
|
734
|
-
return [
|
|
717
|
+
@http.GET('/action2').response<DefaultResponse[]>(200, `List`)
|
|
718
|
+
action2() {
|
|
719
|
+
return [{ title: 'a' }, { title: 1 }];
|
|
735
720
|
}
|
|
736
|
-
}
|
|
737
721
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
722
|
+
@http.GET('/action3')
|
|
723
|
+
.response<DefaultResponse[]>(200, `List`)
|
|
724
|
+
.response<ErrorResponse[]>(400, `Error`)
|
|
725
|
+
action3() {
|
|
726
|
+
return new JSONResponse([{ message: 'error' }, { message: 1 }]).status(400);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
742
729
|
|
|
743
730
|
const httpKernel = createHttpKernel([Controller]);
|
|
744
|
-
|
|
745
|
-
expect((await httpKernel.request(HttpRequest.GET('/
|
|
746
|
-
expect((await httpKernel.request(HttpRequest.GET('/
|
|
731
|
+
expect((await httpKernel.request(HttpRequest.GET('/action1'))).json).toEqual([{ title: 'a' }, { title: '1' }]);
|
|
732
|
+
expect((await httpKernel.request(HttpRequest.GET('/action2'))).json).toEqual([{ title: 'a' }, { title: '1' }]);
|
|
733
|
+
expect((await httpKernel.request(HttpRequest.GET('/action3'))).json).toEqual([{ message: 'error' }, { message: '1' }]);
|
|
747
734
|
});
|
|
748
735
|
|
|
736
|
+
test('BodyValidation', async () => {
|
|
737
|
+
class User {
|
|
738
|
+
username!: string & MinLength<3>;
|
|
739
|
+
}
|
|
749
740
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
});
|
|
754
|
-
|
|
755
|
-
const errorSchema = t.schema({
|
|
756
|
-
message: t.string
|
|
757
|
-
});
|
|
741
|
+
class AddUserDto extends User {
|
|
742
|
+
imageUpload?: UploadedFile;
|
|
743
|
+
}
|
|
758
744
|
|
|
759
745
|
class Controller {
|
|
760
|
-
@http.
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
return [{title: 'a'}, {title: 1}];
|
|
746
|
+
@http.POST('/action1')
|
|
747
|
+
action1(user: HttpBody<User>): any {
|
|
748
|
+
return user;
|
|
764
749
|
}
|
|
765
750
|
|
|
766
|
-
@http.
|
|
767
|
-
action2() {
|
|
768
|
-
|
|
751
|
+
@http.POST('/action2')
|
|
752
|
+
action2(user: HttpBodyValidation<User>): User {
|
|
753
|
+
if (user.valid()) {
|
|
754
|
+
return user.value;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
throw new HttpBadRequestError('Invalid: ' + user.error.getErrorMessageForPath('username'));
|
|
769
758
|
}
|
|
770
759
|
|
|
771
|
-
@http.
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
760
|
+
@http.POST('/action3')
|
|
761
|
+
action3(user: HttpBodyValidation<AddUserDto>): User {
|
|
762
|
+
if (user.valid()) {
|
|
763
|
+
return user.value;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
throw new HttpBadRequestError('Invalid: ' + user.error.getErrorMessageForPath('username'));
|
|
776
767
|
}
|
|
777
768
|
}
|
|
778
769
|
|
|
779
770
|
const httpKernel = createHttpKernel([Controller]);
|
|
780
|
-
expect((await httpKernel.request(HttpRequest.
|
|
781
|
-
expect((await httpKernel.request(HttpRequest.
|
|
782
|
-
|
|
771
|
+
expect((await httpKernel.request(HttpRequest.POST('/action1').json({ username: 'Peter' }))).json).toEqual({ username: 'Peter' });
|
|
772
|
+
expect((await httpKernel.request(HttpRequest.POST('/action1').json({ username: 'Pe' }))).json).toEqual({
|
|
773
|
+
errors: [{ code: 'minLength', message: 'Min length is 3', path: 'username' }], message: 'Validation error:\nusername(minLength): Min length is 3'
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
expect((await httpKernel.request(HttpRequest.POST('/action2').json({ username: 'Peter' }))).json).toEqual({ username: 'Peter' });
|
|
777
|
+
expect((await httpKernel.request(HttpRequest.POST('/action2').json({ username: 'Pe' }))).bodyString).toEqual(`{"message":"Invalid: Min length is 3"}`);
|
|
778
|
+
|
|
779
|
+
expect((await httpKernel.request(HttpRequest.POST('/action3').json({ username: 'Peter' }))).json).toEqual({ username: 'Peter' });
|
|
780
|
+
expect((await httpKernel.request(HttpRequest.POST('/action3').json({ username: 'Pe' }))).bodyString).toEqual(`{"message":"Invalid: Min length is 3"}`);
|
|
783
781
|
});
|