@deepkit/http 1.0.1-alpha.16 → 1.0.1-alpha.160
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/CHANGELOG.md +236 -0
- package/dist/cjs/index.d.ts +14 -10
- package/dist/cjs/index.js +19 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/controllers.d.ts +10 -3
- package/dist/cjs/src/controllers.js +7 -3
- package/dist/cjs/src/controllers.js.map +1 -1
- package/dist/cjs/src/decorator.d.ts +144 -70
- package/dist/cjs/src/decorator.js +277 -102
- package/dist/cjs/src/decorator.js.map +1 -1
- package/dist/cjs/src/filter.d.ts +49 -0
- package/dist/cjs/src/filter.js +215 -0
- package/dist/cjs/src/filter.js.map +1 -0
- package/dist/cjs/src/http-app.d.ts +8 -0
- package/dist/cjs/src/http-app.js +16 -0
- package/dist/cjs/src/http-app.js.map +1 -0
- package/dist/cjs/src/http.d.ts +131 -32
- package/dist/cjs/src/http.js +523 -122
- package/dist/cjs/src/http.js.map +1 -1
- package/dist/cjs/src/kernel.d.ts +50 -9
- package/dist/cjs/src/kernel.js +109 -98
- package/dist/cjs/src/kernel.js.map +1 -1
- package/dist/cjs/src/logger.d.ts +3 -3
- package/dist/cjs/src/logger.js +9 -12
- package/dist/cjs/src/logger.js.map +1 -1
- package/dist/cjs/src/middleware.d.ts +61 -0
- package/dist/cjs/src/middleware.js +95 -0
- package/dist/cjs/src/middleware.js.map +1 -0
- package/dist/cjs/src/model.d.ts +270 -4
- package/dist/cjs/src/model.js +401 -3
- package/dist/cjs/src/model.js.map +1 -1
- package/dist/cjs/src/module.config.d.ts +149 -4
- package/dist/cjs/src/module.config.js +11 -6
- package/dist/cjs/src/module.config.js.map +1 -1
- package/dist/cjs/src/module.d.ts +14 -32
- package/dist/cjs/src/module.js +122 -7
- package/dist/cjs/src/module.js.map +1 -1
- package/dist/cjs/src/request-parser.d.ts +37 -0
- package/dist/cjs/src/request-parser.js +382 -0
- package/dist/cjs/src/request-parser.js.map +1 -0
- package/dist/cjs/src/router.d.ts +174 -75
- package/dist/cjs/src/router.js +469 -288
- package/dist/cjs/src/router.js.map +1 -1
- package/dist/cjs/src/static-serving.d.ts +32 -4
- package/dist/cjs/src/static-serving.js +115 -71
- package/dist/cjs/src/static-serving.js.map +1 -1
- package/dist/cjs/src/utils.js +2 -2
- package/dist/cjs/src/utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -2916
- package/dist/esm/index.d.ts +14 -10
- package/dist/esm/index.js +14 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/src/controllers.d.ts +10 -3
- package/dist/esm/src/controllers.js +7 -3
- package/dist/esm/src/controllers.js.map +1 -1
- package/dist/esm/src/decorator.d.ts +144 -70
- package/dist/esm/src/decorator.js +272 -99
- package/dist/esm/src/decorator.js.map +1 -1
- package/dist/esm/src/filter.d.ts +49 -0
- package/dist/esm/src/filter.js +209 -0
- package/dist/esm/src/filter.js.map +1 -0
- package/dist/esm/src/http-app.d.ts +8 -0
- package/dist/esm/src/http-app.js +12 -0
- package/dist/esm/src/http-app.js.map +1 -0
- package/dist/esm/src/http.d.ts +131 -32
- package/dist/esm/src/http.js +504 -121
- package/dist/esm/src/http.js.map +1 -1
- package/dist/esm/src/kernel.d.ts +50 -9
- package/dist/esm/src/kernel.js +110 -100
- package/dist/esm/src/kernel.js.map +1 -1
- package/dist/esm/src/logger.d.ts +3 -3
- package/dist/esm/src/logger.js +7 -11
- package/dist/esm/src/logger.js.map +1 -1
- package/dist/esm/src/middleware.d.ts +61 -0
- package/dist/esm/src/middleware.js +90 -0
- package/dist/esm/src/middleware.js.map +1 -0
- package/dist/esm/src/model.d.ts +270 -4
- package/dist/esm/src/model.js +357 -1
- package/dist/esm/src/model.js.map +1 -1
- package/dist/esm/src/module.config.d.ts +149 -4
- package/dist/esm/src/module.config.js +9 -5
- package/dist/esm/src/module.config.js.map +1 -1
- package/dist/esm/src/module.d.ts +14 -32
- package/dist/esm/src/module.js +121 -7
- package/dist/esm/src/module.js.map +1 -1
- package/dist/esm/src/request-parser.d.ts +37 -0
- package/dist/esm/src/request-parser.js +372 -0
- package/dist/esm/src/request-parser.js.map +1 -0
- package/dist/esm/src/router.d.ts +174 -75
- package/dist/esm/src/router.js +463 -285
- package/dist/esm/src/router.js.map +1 -1
- package/dist/esm/src/static-serving.d.ts +32 -4
- package/dist/esm/src/static-serving.js +107 -65
- package/dist/esm/src/static-serving.js.map +1 -1
- package/dist/esm/src/utils.js +1 -0
- package/dist/esm/src/utils.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -2916
- package/index.ts +14 -10
- package/package.json +30 -19
- package/src/controllers.ts +4 -3
- package/src/decorator.ts +242 -104
- package/src/filter.ts +224 -0
- package/src/http-app.ts +11 -0
- package/src/http.ts +501 -100
- package/src/kernel.ts +128 -80
- package/src/logger.ts +4 -6
- package/src/middleware.ts +116 -0
- package/src/model.ts +516 -5
- package/src/module.config.ts +168 -5
- package/src/module.ts +120 -7
- package/src/request-parser.ts +430 -0
- package/src/router.ts +546 -317
- package/src/static-serving.ts +120 -50
- package/src/utils.ts +0 -2
- package/tsconfig.esm.json +7 -7
- package/tsconfig.json +18 -11
- package/tsconfig.spec.json +8 -0
- package/dist/cjs/tests/router.spec.d.ts +0 -1
- package/dist/cjs/tests/router.spec.js +0 -481
- package/dist/cjs/tests/router.spec.js.map +0 -1
- package/dist/esm/tests/router.spec.d.ts +0 -1
- package/dist/esm/tests/router.spec.js +0 -479
- package/dist/esm/tests/router.spec.js.map +0 -1
- package/tests/router.spec.ts +0 -347
package/dist/esm/src/http.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Deepkit Framework
|
|
3
|
-
* Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
|
|
4
|
-
*
|
|
5
|
-
* This program is free software: you can redistribute it and/or modify
|
|
6
|
-
* it under the terms of the MIT License.
|
|
7
|
-
*
|
|
8
|
-
* You should have received a copy of the MIT License along with this program.
|
|
9
|
-
*/
|
|
10
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
11
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
12
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -16,16 +7,51 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
16
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
17
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
18
9
|
};
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
const __ΩError = ['name', 'message', 'stack', 'Error', 'P&4!&4"&4#8Mw$y'];
|
|
11
|
+
/*@ts-ignore*/
|
|
12
|
+
import { __ΩClassType } from '@deepkit/core';
|
|
13
|
+
/*@ts-ignore*/
|
|
14
|
+
import { __ΩRouteParameterResolverForInjector } from './router.js';
|
|
15
|
+
/*@ts-ignore*/
|
|
16
|
+
import { __ΩHttpRequestPositionedParameters } from './model.js';
|
|
17
|
+
/*@ts-ignore*/
|
|
18
|
+
import { __ΩLoggerInterface } from '@deepkit/logger';
|
|
19
|
+
function __assignType(fn, args) {
|
|
20
|
+
fn.__type = args;
|
|
21
|
+
return fn;
|
|
22
|
+
}
|
|
23
|
+
/*
|
|
24
|
+
* Deepkit Framework
|
|
25
|
+
* Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
|
|
26
|
+
*
|
|
27
|
+
* This program is free software: you can redistribute it and/or modify
|
|
28
|
+
* it under the terms of the MIT License.
|
|
29
|
+
*
|
|
30
|
+
* You should have received a copy of the MIT License along with this program.
|
|
31
|
+
*/
|
|
32
|
+
import { asyncOperation, CustomError, getClassName, getClassTypeFromInstance, isArray, isClassInstance, isObject, } from '@deepkit/core';
|
|
21
33
|
import { ServerResponse } from 'http';
|
|
22
34
|
import { eventDispatcher } from '@deepkit/event';
|
|
23
|
-
import { HttpResponse } from './model';
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { Router } from './router';
|
|
35
|
+
import { HttpRequest, HttpResponse } from './model.js';
|
|
36
|
+
import { InjectorContext } from '@deepkit/injector';
|
|
37
|
+
import { HttpRouter, RouteConfig } from './router.js';
|
|
27
38
|
import { createWorkflow, WorkflowEvent } from '@deepkit/workflow';
|
|
28
|
-
import {
|
|
39
|
+
import { FrameCategory, Stopwatch } from '@deepkit/stopwatch';
|
|
40
|
+
import { getSerializeFunction, hasTypeInformation, ReflectionKind, resolveReceiveType, SerializationError, serialize, serializer, typeSettings, UnpopulatedCheck, ValidationError, } from '@deepkit/type';
|
|
41
|
+
import stream from 'stream';
|
|
42
|
+
export function isElementStruct(v) {
|
|
43
|
+
return isObject(v) && 'hasOwnProperty' in v && v.hasOwnProperty('render') && v.hasOwnProperty('attributes');
|
|
44
|
+
}
|
|
45
|
+
isElementStruct.__type = ['v', 'isElementStruct', 'P"2!!/"'];
|
|
46
|
+
let templateRender;
|
|
47
|
+
function getTemplateRender() {
|
|
48
|
+
if (!templateRender) {
|
|
49
|
+
const template = require('@deepkit/template');
|
|
50
|
+
templateRender = template.render;
|
|
51
|
+
}
|
|
52
|
+
return templateRender;
|
|
53
|
+
}
|
|
54
|
+
getTemplateRender.__type = [() => render, 'getTemplateRender', 'Pi!/"'];
|
|
29
55
|
export class Redirect {
|
|
30
56
|
constructor(statusCode = 302) {
|
|
31
57
|
this.statusCode = statusCode;
|
|
@@ -42,34 +68,69 @@ export class Redirect {
|
|
|
42
68
|
return redirect;
|
|
43
69
|
}
|
|
44
70
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
Redirect.__type = ['routeName', 'routeParameters', 'url', 'statusCode', () => 302, 'constructor', 'parameters', () => ({}), () => 302, () => Redirect, 'toRoute', () => 302, () => Redirect, 'toUrl', 'Redirect', '&3!8P&"LM3"8&3#8P\'2$:>%"0&P&2!P&"LM2\'>(\'2$>)P7*0+sP&2#\'2$>,P7-0.s5w/'];
|
|
72
|
+
export class HttpError extends CustomError {
|
|
73
|
+
constructor(message, httpCode) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.message = message;
|
|
76
|
+
this.httpCode = httpCode;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
HttpError.__type = ['T', () => CustomError, 'message', 'httpCode', 'constructor', 'HttpError', 'b!P7"P&2#:e"!2$:"0%5w&'];
|
|
80
|
+
export function createHttpError(code, defaultMessage = '') {
|
|
81
|
+
var _a;
|
|
82
|
+
return _a = class extends HttpError {
|
|
83
|
+
constructor(message = defaultMessage) {
|
|
84
|
+
super(message, code);
|
|
85
|
+
this.message = message;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
_a.__type = [() => code, () => HttpError, 'message', () => defaultMessage, 'constructor', () => code, 'PPdi!h!!qe!!!j7"P&2#:>$"0%5Pdi&h!!qe!!!j6"'],
|
|
89
|
+
_a;
|
|
90
|
+
}
|
|
91
|
+
createHttpError.__type = ['code', 'defaultMessage', () => "", () => __ΩClassType, () => HttpError, 'createHttpError', 'P"2!&2">#P"7%o$"/&'];
|
|
92
|
+
export class HttpBadRequestError extends createHttpError(400, 'Bad request') {
|
|
93
|
+
}
|
|
94
|
+
HttpBadRequestError.__type = [() => createHttpError(400, "Bad request"), 'HttpBadRequestError', 'P7!5w"'];
|
|
95
|
+
export class HttpUnauthorizedError extends createHttpError(401, 'Unauthorized') {
|
|
96
|
+
}
|
|
97
|
+
HttpUnauthorizedError.__type = [() => createHttpError(401, "Unauthorized"), 'HttpUnauthorizedError', 'P7!5w"'];
|
|
98
|
+
export class HttpAccessDeniedError extends createHttpError(403, 'Access denied') {
|
|
99
|
+
}
|
|
100
|
+
HttpAccessDeniedError.__type = [() => createHttpError(403, "Access denied"), 'HttpAccessDeniedError', 'P7!5w"'];
|
|
101
|
+
export class HttpNotFoundError extends createHttpError(404, 'Not found') {
|
|
102
|
+
}
|
|
103
|
+
HttpNotFoundError.__type = [() => createHttpError(404, "Not found"), 'HttpNotFoundError', 'P7!5w"'];
|
|
104
|
+
export class HttpMethodNotAllowedError extends createHttpError(405, 'Method not allowed') {
|
|
105
|
+
}
|
|
106
|
+
HttpMethodNotAllowedError.__type = [() => createHttpError(405, "Method not allowed"), 'HttpMethodNotAllowedError', 'P7!5w"'];
|
|
107
|
+
export class HttpNotAcceptableError extends createHttpError(406, 'Not acceptable') {
|
|
54
108
|
}
|
|
55
|
-
|
|
109
|
+
HttpNotAcceptableError.__type = [() => createHttpError(406, "Not acceptable"), 'HttpNotAcceptableError', 'P7!5w"'];
|
|
110
|
+
export class HttpTimeoutError extends createHttpError(408, 'Request timeout') {
|
|
56
111
|
}
|
|
57
|
-
|
|
112
|
+
HttpTimeoutError.__type = [() => createHttpError(408, "Request timeout"), 'HttpTimeoutError', 'P7!5w"'];
|
|
113
|
+
export class HttpConflictError extends createHttpError(409, 'Conflict') {
|
|
58
114
|
}
|
|
59
|
-
|
|
115
|
+
HttpConflictError.__type = [() => createHttpError(409, "Conflict"), 'HttpConflictError', 'P7!5w"'];
|
|
116
|
+
export class HttpGoneError extends createHttpError(410, 'Gone') {
|
|
60
117
|
}
|
|
118
|
+
HttpGoneError.__type = [() => createHttpError(410, "Gone"), 'HttpGoneError', 'P7!5w"'];
|
|
119
|
+
export class HttpTooManyRequestsError extends createHttpError(429, 'Too many requests') {
|
|
120
|
+
}
|
|
121
|
+
HttpTooManyRequestsError.__type = [() => createHttpError(429, "Too many requests"), 'HttpTooManyRequestsError', 'P7!5w"'];
|
|
122
|
+
export class HttpInternalServerError extends createHttpError(500, 'Internal server error') {
|
|
123
|
+
}
|
|
124
|
+
HttpInternalServerError.__type = [() => createHttpError(500, "Internal server error"), 'HttpInternalServerError', 'P7!5w"'];
|
|
125
|
+
export class HttpNotImplementedError extends createHttpError(501, 'Not implemented') {
|
|
126
|
+
}
|
|
127
|
+
HttpNotImplementedError.__type = [() => createHttpError(501, "Not implemented"), 'HttpNotImplementedError', 'P7!5w"'];
|
|
61
128
|
export class HttpWorkflowEvent {
|
|
62
|
-
constructor(injectorContext, request, response) {
|
|
63
|
-
this.injectorContext = injectorContext;
|
|
64
|
-
this.request = request;
|
|
65
|
-
this.response = response;
|
|
66
|
-
this.stopped = false;
|
|
67
|
-
}
|
|
68
129
|
stopPropagation() {
|
|
69
|
-
this.
|
|
130
|
+
this.propagationStopped = true;
|
|
70
131
|
}
|
|
71
|
-
|
|
72
|
-
return this.
|
|
132
|
+
isPropagationStopped() {
|
|
133
|
+
return this.propagationStopped;
|
|
73
134
|
}
|
|
74
135
|
clearNext() {
|
|
75
136
|
this.nextState = undefined;
|
|
@@ -82,9 +143,18 @@ export class HttpWorkflowEvent {
|
|
|
82
143
|
this.nextState = nextState;
|
|
83
144
|
this.nextStateEvent = event;
|
|
84
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Whether already a next workflow state has been scheduled.
|
|
148
|
+
*/
|
|
85
149
|
hasNext() {
|
|
86
150
|
return this.nextState !== undefined;
|
|
87
151
|
}
|
|
152
|
+
constructor(injectorContext, request, response) {
|
|
153
|
+
this.injectorContext = injectorContext;
|
|
154
|
+
this.request = request;
|
|
155
|
+
this.response = response;
|
|
156
|
+
this.propagationStopped = false;
|
|
157
|
+
}
|
|
88
158
|
get url() {
|
|
89
159
|
return this.request.url || '/';
|
|
90
160
|
}
|
|
@@ -98,6 +168,7 @@ export class HttpWorkflowEvent {
|
|
|
98
168
|
this.next('response', new HttpResponseEvent(this.injectorContext, this.request, this.response, response));
|
|
99
169
|
}
|
|
100
170
|
}
|
|
171
|
+
HttpWorkflowEvent.__type = ['propagationStopped', function () { return false; }, 'stopPropagation', 'isPropagationStopped', 'nextState', 'nextStateEvent', 'clearNext', 'event', 'next', 'hasNext', () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', 'constructor', 'send', 'HttpWorkflowEvent', ')3!>"P"0#P"0$"3%8"3&8P"0\'P&2%"2(8"0)P)0*PP7+2,:P7-2.:P7/20:"01!!P"20"025w3'];
|
|
101
172
|
export const HttpRequestEvent = HttpWorkflowEvent;
|
|
102
173
|
export const HttpRouteNotFoundEvent = HttpWorkflowEvent;
|
|
103
174
|
export class HttpWorkflowEventWithRoute extends HttpWorkflowEvent {
|
|
@@ -111,7 +182,11 @@ export class HttpWorkflowEventWithRoute extends HttpWorkflowEvent {
|
|
|
111
182
|
send(response) {
|
|
112
183
|
this.next('response', new HttpResponseEvent(this.injectorContext, this.request, this.response, response, this.route));
|
|
113
184
|
}
|
|
185
|
+
accessDenied(error) {
|
|
186
|
+
this.next('accessDenied', new HttpAccessDeniedEvent(this.injectorContext, this.request, this.response, this.route, error));
|
|
187
|
+
}
|
|
114
188
|
}
|
|
189
|
+
HttpWorkflowEventWithRoute.__type = [() => HttpWorkflowEvent, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => RouteConfig, 'route', 'constructor', 'send', () => __ΩError, 'error', 'accessDenied', 'HttpWorkflowEventWithRoute', 'P7!PP7"2#:P7$2%:P7&2\':P7(2):"0*P"2\'"0+Pn,2-8"0.5w/'];
|
|
115
190
|
export class HttpRouteEvent extends HttpWorkflowEvent {
|
|
116
191
|
constructor(injectorContext, request, response, parameterResolver, route) {
|
|
117
192
|
super(injectorContext, request, response);
|
|
@@ -129,6 +204,7 @@ export class HttpRouteEvent extends HttpWorkflowEvent {
|
|
|
129
204
|
this.next('routeNotFound', new HttpRouteNotFoundEvent(this.injectorContext, this.request, this.response));
|
|
130
205
|
}
|
|
131
206
|
}
|
|
207
|
+
HttpRouteEvent.__type = [() => HttpWorkflowEvent, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => __ΩRouteParameterResolverForInjector, 'parameterResolver', () => RouteConfig, 'route', 'constructor', () => RouteConfig, () => __ΩRouteParameterResolverForInjector, 'routeFound', 'notFound', 'HttpRouteEvent', 'P7!PP7"2#:P7$2%:P7&2\':n(2)8:P7*2+8:"0,PP7-2+n.2)"0/P"005w1'];
|
|
132
208
|
export class HttpAuthEvent extends HttpWorkflowEventWithRoute {
|
|
133
209
|
constructor(injectorContext, request, response, route, parameterResolver) {
|
|
134
210
|
super(injectorContext, request, response, route);
|
|
@@ -141,33 +217,37 @@ export class HttpAuthEvent extends HttpWorkflowEventWithRoute {
|
|
|
141
217
|
success() {
|
|
142
218
|
this.next('resolveParameters', new HttpResolveParametersEvent(this.injectorContext, this.request, this.response, this.parameterResolver, this.route));
|
|
143
219
|
}
|
|
144
|
-
accessDenied() {
|
|
145
|
-
this.next('accessDenied', new HttpAccessDeniedEvent(this.injectorContext, this.request, this.response, this.route));
|
|
146
|
-
}
|
|
147
220
|
}
|
|
221
|
+
HttpAuthEvent.__type = [() => HttpWorkflowEventWithRoute, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => RouteConfig, 'route', () => __ΩRouteParameterResolverForInjector, 'parameterResolver', 'constructor', 'success', 'HttpAuthEvent', 'P7!PP7"2#:P7$2%:P7&2\':P7(2):n*2+:"0,P"0-5w.'];
|
|
148
222
|
export class HttpAccessDeniedEvent extends HttpWorkflowEvent {
|
|
149
|
-
constructor(injectorContext, request, response, route) {
|
|
223
|
+
constructor(injectorContext, request, response, route, error) {
|
|
150
224
|
super(injectorContext, request, response);
|
|
151
225
|
this.injectorContext = injectorContext;
|
|
152
226
|
this.request = request;
|
|
153
227
|
this.response = response;
|
|
154
228
|
this.route = route;
|
|
229
|
+
this.error = error;
|
|
155
230
|
}
|
|
156
231
|
}
|
|
157
|
-
|
|
232
|
+
HttpAccessDeniedEvent.__type = [() => HttpWorkflowEvent, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => RouteConfig, 'route', () => __ΩError, 'error', 'constructor', 'HttpAccessDeniedEvent', 'P7!PP7"2#:P7$2%:P7&2\':P7(2):n*2+8:"0,5w-'];
|
|
233
|
+
export class HttpResolveParametersEvent extends HttpWorkflowEventWithRoute {
|
|
158
234
|
constructor(injectorContext, request, response, parameterResolver, route) {
|
|
159
|
-
super(injectorContext, request, response);
|
|
235
|
+
super(injectorContext, request, response, route);
|
|
160
236
|
this.injectorContext = injectorContext;
|
|
161
237
|
this.request = request;
|
|
162
238
|
this.response = response;
|
|
163
239
|
this.parameterResolver = parameterResolver;
|
|
164
240
|
this.route = route;
|
|
165
|
-
this.parameters = [];
|
|
241
|
+
this.parameters = { arguments: [], parameters: {} };
|
|
242
|
+
}
|
|
243
|
+
accessDenied() {
|
|
244
|
+
this.next('accessDenied', new HttpAccessDeniedEvent(this.injectorContext, this.request, this.response, this.route));
|
|
166
245
|
}
|
|
167
246
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
247
|
+
HttpResolveParametersEvent.__type = [() => HttpWorkflowEventWithRoute, () => __ΩHttpRequestPositionedParameters, 'parameters', function () { return { arguments: [], parameters: {} }; }, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => __ΩRouteParameterResolverForInjector, 'parameterResolver', () => RouteConfig, 'route', 'constructor', 'accessDenied', 'HttpResolveParametersEvent', 'P7!n"3#>$PP7%2&:P7\'2(:P7)2*:n+2,:P7-2.:"0/P"005w1'];
|
|
248
|
+
export class HttpControllerEvent extends HttpWorkflowEventWithRoute {
|
|
249
|
+
constructor(injectorContext, request, response, parameters = { arguments: [], parameters: {} }, route) {
|
|
250
|
+
super(injectorContext, request, response, route);
|
|
171
251
|
this.injectorContext = injectorContext;
|
|
172
252
|
this.request = request;
|
|
173
253
|
this.response = response;
|
|
@@ -175,6 +255,7 @@ export class HttpControllerEvent extends HttpWorkflowEvent {
|
|
|
175
255
|
this.route = route;
|
|
176
256
|
}
|
|
177
257
|
}
|
|
258
|
+
HttpControllerEvent.__type = [() => HttpWorkflowEventWithRoute, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => __ΩHttpRequestPositionedParameters, 'parameters', () => ({ arguments: [], parameters: {} }), () => RouteConfig, 'route', 'constructor', 'HttpControllerEvent', 'P7!PP7"2#:P7$2%:P7&2\':n(2):>*P7+2,:"0-5w.'];
|
|
178
259
|
export class HttpResponseEvent extends WorkflowEvent {
|
|
179
260
|
constructor(injectorContext, request, response, result, route) {
|
|
180
261
|
super();
|
|
@@ -183,18 +264,28 @@ export class HttpResponseEvent extends WorkflowEvent {
|
|
|
183
264
|
this.response = response;
|
|
184
265
|
this.result = result;
|
|
185
266
|
this.route = route;
|
|
267
|
+
/**
|
|
268
|
+
* The time it took to call the controller action in milliseconds.
|
|
269
|
+
*/
|
|
270
|
+
this.controllerActionTime = 0;
|
|
186
271
|
}
|
|
187
272
|
}
|
|
188
|
-
|
|
273
|
+
HttpResponseEvent.__type = [() => WorkflowEvent, 'controllerActionTime', function () { return 0; }, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', 'result', () => RouteConfig, 'route', 'constructor', 'HttpResponseEvent', 'P7!\'3">#PP7$2%:P7&2\':P7(2):"2*:P7+2,8:"0-5w.'];
|
|
274
|
+
export class HttpControllerErrorEvent extends HttpWorkflowEventWithRoute {
|
|
189
275
|
constructor(injectorContext, request, response, route, error) {
|
|
190
|
-
super(injectorContext, request, response);
|
|
276
|
+
super(injectorContext, request, response, route);
|
|
191
277
|
this.injectorContext = injectorContext;
|
|
192
278
|
this.request = request;
|
|
193
279
|
this.response = response;
|
|
194
280
|
this.route = route;
|
|
195
281
|
this.error = error;
|
|
282
|
+
/**
|
|
283
|
+
* The time it took to call the controller action in milliseconds.
|
|
284
|
+
*/
|
|
285
|
+
this.controllerActionTime = 0;
|
|
196
286
|
}
|
|
197
287
|
}
|
|
288
|
+
HttpControllerErrorEvent.__type = [() => HttpWorkflowEventWithRoute, 'controllerActionTime', function () { return 0; }, () => InjectorContext, 'injectorContext', () => HttpRequest, 'request', () => HttpResponse, 'response', () => RouteConfig, 'route', () => __ΩError, 'error', 'constructor', 'HttpControllerErrorEvent', 'P7!\'3">#PP7$2%:P7&2\':P7(2):P7*2+:n,2-:"0.5w/'];
|
|
198
289
|
export const httpWorkflow = createWorkflow('http', {
|
|
199
290
|
start: WorkflowEvent,
|
|
200
291
|
request: HttpRequestEvent,
|
|
@@ -219,22 +310,195 @@ export const httpWorkflow = createWorkflow('http', {
|
|
|
219
310
|
parametersFailed: 'response',
|
|
220
311
|
routeNotFound: 'response',
|
|
221
312
|
});
|
|
222
|
-
export class
|
|
313
|
+
export class BaseResponse {
|
|
314
|
+
constructor(_statusCode, _headers = {}) {
|
|
315
|
+
this._statusCode = _statusCode;
|
|
316
|
+
this._headers = _headers;
|
|
317
|
+
this.autoSerializing = true;
|
|
318
|
+
}
|
|
319
|
+
status(code) {
|
|
320
|
+
this._statusCode = code;
|
|
321
|
+
return this;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Per default a JSONResponse is serialized using the return type specified at the route.
|
|
325
|
+
* This disables that behaviour so that JSON.stringify is run on the result directly.
|
|
326
|
+
*/
|
|
327
|
+
disableAutoSerializing() {
|
|
328
|
+
this.autoSerializing = false;
|
|
329
|
+
return this;
|
|
330
|
+
}
|
|
331
|
+
header(name, value) {
|
|
332
|
+
this._headers[name] = value;
|
|
333
|
+
return this;
|
|
334
|
+
}
|
|
335
|
+
headers(headers) {
|
|
336
|
+
this._headers = headers;
|
|
337
|
+
return this;
|
|
338
|
+
}
|
|
339
|
+
contentType(type) {
|
|
340
|
+
this._headers['content-type'] = type;
|
|
341
|
+
return this;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
BaseResponse.__type = ['autoSerializing', function () { return true; }, '_statusCode', '_headers', () => ({}), 'constructor', 'code', 'status', 'disableAutoSerializing', 'name', 'value', 'header', 'headers', 'type', 'contentType', 'BaseResponse', ')3!>"P\'2#8:!2$:>%"0&P\'2\'!0(P"0)P&2*P&\'J2+!0,P!2-!0-P&2.!0/5w0'];
|
|
345
|
+
export class Response extends BaseResponse {
|
|
346
|
+
constructor(content, contentType, statusCode) {
|
|
347
|
+
super(statusCode);
|
|
348
|
+
this.content = content;
|
|
349
|
+
this.contentType(contentType);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
Response.__type = [() => BaseResponse, 'content', 'contentType', 'statusCode', 'constructor', 'Response', 'P7!PP&WJ2":&2#\'2$8"0%5w&'];
|
|
353
|
+
export class HtmlResponse extends BaseResponse {
|
|
223
354
|
constructor(html, statusCode) {
|
|
355
|
+
super(statusCode);
|
|
224
356
|
this.html = html;
|
|
225
|
-
this.statusCode = statusCode;
|
|
226
357
|
}
|
|
227
358
|
}
|
|
228
|
-
|
|
359
|
+
HtmlResponse.__type = [() => BaseResponse, 'html', 'statusCode', 'constructor', 'HtmlResponse', 'P7!P&2":\'2#8"0$5w%'];
|
|
360
|
+
export class JSONResponse extends BaseResponse {
|
|
229
361
|
constructor(json, statusCode) {
|
|
362
|
+
super(statusCode);
|
|
230
363
|
this.json = json;
|
|
231
|
-
this.statusCode = statusCode;
|
|
232
364
|
}
|
|
233
365
|
}
|
|
234
|
-
|
|
235
|
-
|
|
366
|
+
JSONResponse.__type = [() => BaseResponse, 'json', 'statusCode', 'constructor', 'JSONResponse', 'P7!P"2":\'2#8"0$5w%'];
|
|
367
|
+
const __ΩSupportedHttpResult = [() => Response, () => JSONResponse, () => HtmlResponse, () => HttpResponse, () => Redirect, () => __ΩError, 'SupportedHttpResult', 'P-,\'&P7!P7"P7#P7$!!P7%Wn&Jw\'y'];
|
|
368
|
+
export { __ΩSupportedHttpResult as __ΩSupportedHttpResult };
|
|
369
|
+
const __ΩHttpResultFormatterContext = [() => HttpRequest, 'request', () => HttpResponse, 'response', () => RouteConfig, 'route', 'HttpResultFormatterContext', 'PP7!4"P7#4$P7%4&8Mw\'y'];
|
|
370
|
+
export { __ΩHttpResultFormatterContext as __ΩHttpResultFormatterContext };
|
|
371
|
+
export class HttpResultFormatter {
|
|
372
|
+
constructor(router) {
|
|
373
|
+
this.router = router;
|
|
374
|
+
this.jsonContentType = 'application/json; charset=utf-8';
|
|
375
|
+
this.htmlContentType = 'text/html; charset=utf-8';
|
|
376
|
+
}
|
|
377
|
+
setContentTypeIfNotSetAlready(response, contentType) {
|
|
378
|
+
if (response.hasHeader('Content-Type'))
|
|
379
|
+
return;
|
|
380
|
+
response.setHeader('Content-Type', contentType);
|
|
381
|
+
}
|
|
382
|
+
handleError(error, context) {
|
|
383
|
+
}
|
|
384
|
+
handleUndefined(result, context) {
|
|
385
|
+
context.response.end(result);
|
|
386
|
+
}
|
|
387
|
+
handleRedirect(result, context) {
|
|
388
|
+
if (result.routeName) {
|
|
389
|
+
context.response.writeHead(result.statusCode, {
|
|
390
|
+
Location: this.router.resolveUrl(result.routeName, result.routeParameters)
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
context.response.writeHead(result.statusCode, {
|
|
395
|
+
Location: result.url
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
context.response.end();
|
|
399
|
+
}
|
|
400
|
+
handleUnknown(result, context) {
|
|
401
|
+
const oldCheck = typeSettings.unpopulatedCheck;
|
|
402
|
+
try {
|
|
403
|
+
typeSettings.unpopulatedCheck = UnpopulatedCheck.None;
|
|
404
|
+
this.setContentTypeIfNotSetAlready(context.response, this.jsonContentType);
|
|
405
|
+
context.response.end(JSON.stringify(result));
|
|
406
|
+
}
|
|
407
|
+
finally {
|
|
408
|
+
typeSettings.unpopulatedCheck = oldCheck;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
handleHtmlResponse(result, context) {
|
|
412
|
+
this.setContentTypeIfNotSetAlready(context.response, this.htmlContentType);
|
|
413
|
+
context.response.writeHead(result._statusCode || 200, result._headers);
|
|
414
|
+
context.response.end(result.html);
|
|
415
|
+
}
|
|
416
|
+
handleGenericResponse(result, context) {
|
|
417
|
+
context.response.writeHead(result._statusCode || 200, result._headers);
|
|
418
|
+
context.response.end(result.content);
|
|
419
|
+
}
|
|
420
|
+
handleJSONResponse(result, context) {
|
|
421
|
+
this.setContentTypeIfNotSetAlready(context.response, this.jsonContentType);
|
|
422
|
+
context.response.writeHead(result._statusCode || 200, result._headers);
|
|
423
|
+
context.response.end(JSON.stringify(result.json));
|
|
424
|
+
}
|
|
425
|
+
handleTypeEntity(classType, instance, context, route) {
|
|
426
|
+
this.handleType(resolveReceiveType(classType), instance, context, route);
|
|
427
|
+
}
|
|
428
|
+
handleType(type, instance, context, route) {
|
|
429
|
+
this.setContentTypeIfNotSetAlready(context.response, this.jsonContentType);
|
|
430
|
+
const serializerToUse = route && route?.serializer ? route.serializer : serializer;
|
|
431
|
+
context.response.end(JSON.stringify(serialize(instance, route ? route.serializationOptions : undefined, serializerToUse, undefined, type)));
|
|
432
|
+
}
|
|
433
|
+
handleStream(stream, context) {
|
|
434
|
+
stream.pipe(context.response);
|
|
435
|
+
}
|
|
436
|
+
handleBinary(result, context) {
|
|
437
|
+
context.response.end(result);
|
|
438
|
+
}
|
|
439
|
+
handleResponse(context) {
|
|
440
|
+
}
|
|
441
|
+
handle(result, context) {
|
|
442
|
+
if (result === null || result === undefined) {
|
|
443
|
+
this.handleUndefined(result, context);
|
|
444
|
+
}
|
|
445
|
+
else if (result instanceof Error) {
|
|
446
|
+
this.handleError(result, context);
|
|
447
|
+
}
|
|
448
|
+
else if (result instanceof Redirect) {
|
|
449
|
+
this.handleRedirect(result, context);
|
|
450
|
+
}
|
|
451
|
+
else if (result instanceof ServerResponse) {
|
|
452
|
+
this.handleResponse(context);
|
|
453
|
+
}
|
|
454
|
+
else if (result instanceof HtmlResponse) {
|
|
455
|
+
this.handleHtmlResponse(result, context);
|
|
456
|
+
}
|
|
457
|
+
else if (result instanceof stream.Readable) {
|
|
458
|
+
this.handleStream(result, context);
|
|
459
|
+
}
|
|
460
|
+
else if (result instanceof Uint8Array) {
|
|
461
|
+
this.handleBinary(result, context);
|
|
462
|
+
}
|
|
463
|
+
else if (result instanceof JSONResponse) {
|
|
464
|
+
this.handleJSONResponse(result, context);
|
|
465
|
+
}
|
|
466
|
+
else if (result instanceof Response) {
|
|
467
|
+
this.handleGenericResponse(result, context);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
if (isClassInstance(result)) {
|
|
471
|
+
const classType = getClassTypeFromInstance(result);
|
|
472
|
+
if (hasTypeInformation(classType)) {
|
|
473
|
+
this.handleTypeEntity(classType, result, context);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else if (isArray(result) && result.length > 0 && isClassInstance(result[0])) {
|
|
478
|
+
const firstClassType = getClassTypeFromInstance(result[0]);
|
|
479
|
+
let allSameType = true;
|
|
480
|
+
for (const item of result) {
|
|
481
|
+
if (!isClassInstance(item) || getClassTypeFromInstance(item) !== firstClassType) {
|
|
482
|
+
allSameType = false;
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (allSameType && hasTypeInformation(firstClassType)) {
|
|
487
|
+
this.handleType({ kind: ReflectionKind.array, type: resolveReceiveType(firstClassType) }, result, context);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
this.handleUnknown(result, context);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
HttpResultFormatter.__type = ['jsonContentType', function () { return 'application/json; charset=utf-8'; }, 'htmlContentType', function () { return 'text/html; charset=utf-8'; }, () => HttpRouter, 'router', 'constructor', () => HttpResponse, 'response', 'contentType', 'setContentTypeIfNotSetAlready', () => __ΩError, 'error', () => __ΩHttpResultFormatterContext, 'context', 'handleError', 'result', () => __ΩHttpResultFormatterContext, 'handleUndefined', () => Redirect, () => __ΩHttpResultFormatterContext, 'handleRedirect', () => __ΩHttpResultFormatterContext, 'handleUnknown', () => HtmlResponse, () => __ΩHttpResultFormatterContext, 'handleHtmlResponse', () => Response, () => __ΩHttpResultFormatterContext, 'handleGenericResponse', () => JSONResponse, () => __ΩHttpResultFormatterContext, 'handleJSONResponse', () => __ΩClassType, 'classType', 'instance', () => __ΩHttpResultFormatterContext, () => RouteConfig, 'route', 'handleTypeEntity', 'Type', 'type', () => __ΩHttpResultFormatterContext, () => RouteConfig, 'handleType', 'stream', () => __ΩHttpResultFormatterContext, 'handleStream', () => __ΩHttpResultFormatterContext, 'handleBinary', () => __ΩHttpResultFormatterContext, 'handleResponse', () => __ΩSupportedHttpResult, () => __ΩHttpResultFormatterContext, 'handle', 'HttpResultFormatter', '&3!<>"&3#<>$PP7%2&<"0\'PP7(2)&2*$0+<Pn,2-n.2/$00PP-,J21n22/$03PP7421n52/$06P"21n72/$08PP7921n:2/$0;PP7<21n=2/$0>PP7?21n@2/$0AP"oB"2C"2DnE2/P7F2G8$0HP"wI2J"2DnK2/P7L2G8$0MP!2NnO2/$0PPW21nQ2/$0RPnS2/"0TPnU21nV2/$0W5wX'];
|
|
496
|
+
export class HttpListener {
|
|
497
|
+
constructor(router, logger, resultFormatter, stopwatch) {
|
|
236
498
|
this.router = router;
|
|
237
499
|
this.logger = logger;
|
|
500
|
+
this.resultFormatter = resultFormatter;
|
|
501
|
+
this.stopwatch = stopwatch;
|
|
238
502
|
}
|
|
239
503
|
onRequest(event) {
|
|
240
504
|
if (event.sent)
|
|
@@ -243,14 +507,73 @@ let HttpListener = class HttpListener {
|
|
|
243
507
|
return;
|
|
244
508
|
event.next('route', new HttpRouteEvent(event.injectorContext, event.request, event.response));
|
|
245
509
|
}
|
|
246
|
-
onRoute(event) {
|
|
510
|
+
async onRoute(event) {
|
|
247
511
|
if (event.sent)
|
|
248
512
|
return;
|
|
249
513
|
if (event.hasNext())
|
|
250
514
|
return;
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
515
|
+
const logger = this.logger;
|
|
516
|
+
try {
|
|
517
|
+
const resolved = this.router.resolveRequest(event.request);
|
|
518
|
+
if (resolved) {
|
|
519
|
+
event.request.uploadedFiles = resolved.uploadedFiles;
|
|
520
|
+
//todo: embed that into the generated router code.
|
|
521
|
+
if (resolved.middlewares) {
|
|
522
|
+
const middlewares = resolved.middlewares(event.injectorContext);
|
|
523
|
+
if (middlewares.length) {
|
|
524
|
+
await asyncOperation(__assignType(async (resolve, reject) => {
|
|
525
|
+
let lastTimer = undefined;
|
|
526
|
+
function finish() {
|
|
527
|
+
clearTimeout(lastTimer);
|
|
528
|
+
resolve(undefined);
|
|
529
|
+
//middleware finished the request. We end the workflow transition
|
|
530
|
+
}
|
|
531
|
+
finish.__type = ['finish', 'P"/!'];
|
|
532
|
+
event.response.once('finish', finish);
|
|
533
|
+
let i = -1;
|
|
534
|
+
async function next() {
|
|
535
|
+
i++;
|
|
536
|
+
if (i >= middlewares.length) {
|
|
537
|
+
event.response.off('finish', finish);
|
|
538
|
+
resolve(undefined);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
const timeout = middlewares[i].timeout;
|
|
542
|
+
if (timeout !== undefined && timeout > 0) {
|
|
543
|
+
lastTimer = setTimeout(() => {
|
|
544
|
+
logger.warn(`Middleware timed out. Increase the timeout or fix the middleware. (${middlewares[i].fn})`);
|
|
545
|
+
next();
|
|
546
|
+
}, timeout);
|
|
547
|
+
}
|
|
548
|
+
try {
|
|
549
|
+
await middlewares[i].fn(event.request, event.response, __assignType((error) => {
|
|
550
|
+
if (lastTimer)
|
|
551
|
+
clearTimeout(lastTimer);
|
|
552
|
+
if (error) {
|
|
553
|
+
event.response.off('finish', finish);
|
|
554
|
+
reject(error);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
next();
|
|
558
|
+
}
|
|
559
|
+
}, ['error', '', 'P"2!8"/"']));
|
|
560
|
+
}
|
|
561
|
+
catch (error) {
|
|
562
|
+
reject(error);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
next.__type = ['next', 'P"/!'];
|
|
566
|
+
await next();
|
|
567
|
+
}, ['resolve', 'reject', '', 'P"2!"2""/#']));
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
event.injectorContext.set(RouteConfig, resolved.routeConfig);
|
|
571
|
+
event.routeFound(resolved.routeConfig, resolved.parameters);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
catch (error) {
|
|
575
|
+
this.logger.error('Could not resolve request', error);
|
|
576
|
+
event.notFound();
|
|
254
577
|
}
|
|
255
578
|
}
|
|
256
579
|
onRouteForward(event) {
|
|
@@ -267,7 +590,12 @@ let HttpListener = class HttpListener {
|
|
|
267
590
|
return;
|
|
268
591
|
if (event.hasNext())
|
|
269
592
|
return;
|
|
270
|
-
event.
|
|
593
|
+
if (event.request.throwErrorOnNotFound) {
|
|
594
|
+
throw new HttpNotFoundError;
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
event.send(new HtmlResponse('Not found', 404));
|
|
598
|
+
}
|
|
271
599
|
}
|
|
272
600
|
onAuth(event) {
|
|
273
601
|
if (event.sent)
|
|
@@ -301,33 +629,82 @@ let HttpListener = class HttpListener {
|
|
|
301
629
|
return;
|
|
302
630
|
if (event.hasNext())
|
|
303
631
|
return;
|
|
304
|
-
const
|
|
632
|
+
const start = Date.now();
|
|
633
|
+
const stopWatchLabel = event.route.action.type === 'controller'
|
|
634
|
+
? getClassName(event.route.action.controller) + '.' + event.route.action.methodName
|
|
635
|
+
: event.route.action.fn.name;
|
|
636
|
+
const frame = this.stopwatch ? this.stopwatch.start(stopWatchLabel, FrameCategory.httpController) : undefined;
|
|
305
637
|
try {
|
|
306
|
-
|
|
307
|
-
|
|
638
|
+
let result;
|
|
639
|
+
if (event.route.action.type === 'controller') {
|
|
640
|
+
const controllerInstance = event.injectorContext.get(event.route.action.controller, event.route.action.module);
|
|
641
|
+
const method = controllerInstance[event.route.action.methodName];
|
|
642
|
+
result = await method.apply(controllerInstance, event.parameters.arguments);
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
result = await event.route.action.fn(...event.parameters.arguments);
|
|
646
|
+
}
|
|
647
|
+
if (isElementStruct(result)) {
|
|
648
|
+
const html = await getTemplateRender()(event.injectorContext.getRootInjector(), result, this.stopwatch ? this.stopwatch : undefined);
|
|
649
|
+
result = new HtmlResponse(html, 200).header('Content-Type', 'text/html; charset=utf-8');
|
|
650
|
+
}
|
|
651
|
+
if (result instanceof stream.Readable) {
|
|
652
|
+
const stream = result;
|
|
653
|
+
await new Promise(__assignType((resolve, reject) => {
|
|
654
|
+
stream.once('readable', resolve);
|
|
655
|
+
stream.once('error', reject);
|
|
656
|
+
}, ['resolve', 'reject', '', 'P"2!"2""/#']));
|
|
657
|
+
}
|
|
658
|
+
const responseEvent = new HttpResponseEvent(event.injectorContext, event.request, event.response, result, event.route);
|
|
659
|
+
responseEvent.controllerActionTime = Date.now() - start;
|
|
660
|
+
event.next('response', responseEvent);
|
|
308
661
|
}
|
|
309
662
|
catch (error) {
|
|
663
|
+
if (frame)
|
|
664
|
+
frame.end();
|
|
310
665
|
if (error instanceof HttpAccessDeniedError) {
|
|
311
|
-
event.next('accessDenied', new HttpAccessDeniedEvent(event.injectorContext, event.request, event.response, event.route));
|
|
666
|
+
event.next('accessDenied', new HttpAccessDeniedEvent(event.injectorContext, event.request, event.response, event.route, error));
|
|
312
667
|
}
|
|
313
668
|
else {
|
|
314
|
-
|
|
669
|
+
const errorEvent = new HttpControllerErrorEvent(event.injectorContext, event.request, event.response, event.route, error);
|
|
670
|
+
errorEvent.controllerActionTime = Date.now() - start;
|
|
671
|
+
event.next('controllerError', errorEvent);
|
|
315
672
|
}
|
|
316
673
|
}
|
|
674
|
+
finally {
|
|
675
|
+
if (frame)
|
|
676
|
+
frame.end();
|
|
677
|
+
}
|
|
317
678
|
}
|
|
318
679
|
onParametersFailed(event) {
|
|
319
680
|
if (event.response.finished)
|
|
320
681
|
return;
|
|
321
682
|
if (event.sent)
|
|
322
683
|
return;
|
|
323
|
-
|
|
324
|
-
|
|
684
|
+
if (event.error instanceof SerializationError) {
|
|
685
|
+
event.send(new JSONResponse({
|
|
686
|
+
message: event.error.message,
|
|
687
|
+
errors: [{
|
|
688
|
+
path: event.error.path,
|
|
689
|
+
code: 'serialization',
|
|
690
|
+
message: event.error.originalMessage,
|
|
691
|
+
}]
|
|
692
|
+
}, 400).disableAutoSerializing());
|
|
693
|
+
}
|
|
694
|
+
else if (event.error instanceof ValidationError) {
|
|
325
695
|
event.send(new JSONResponse({
|
|
326
696
|
message: event.error.message,
|
|
327
697
|
errors: event.error.errors
|
|
328
|
-
},
|
|
698
|
+
}, 400).disableAutoSerializing());
|
|
699
|
+
}
|
|
700
|
+
else if (event.error instanceof HttpError) {
|
|
701
|
+
event.send(new JSONResponse({
|
|
702
|
+
message: event.error.message
|
|
703
|
+
}, event.error.httpCode).disableAutoSerializing());
|
|
704
|
+
return;
|
|
329
705
|
}
|
|
330
706
|
else {
|
|
707
|
+
this.logger.error(`Controller for route ${event.route.getFullPath()} parameter resolving error:`, event.error);
|
|
331
708
|
event.send(new HtmlResponse('Internal error', 500));
|
|
332
709
|
}
|
|
333
710
|
}
|
|
@@ -336,61 +713,67 @@ let HttpListener = class HttpListener {
|
|
|
336
713
|
return;
|
|
337
714
|
if (event.sent)
|
|
338
715
|
return;
|
|
716
|
+
if (event.error instanceof ValidationError) {
|
|
717
|
+
event.send(new JSONResponse({
|
|
718
|
+
message: event.error.message,
|
|
719
|
+
errors: event.error.errors
|
|
720
|
+
}, 400).disableAutoSerializing());
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
else if (event.error instanceof HttpError) {
|
|
724
|
+
if (event.request.throwErrorOnNotFound && event.error.httpCode === 404) {
|
|
725
|
+
throw event.error;
|
|
726
|
+
}
|
|
727
|
+
event.send(new JSONResponse({
|
|
728
|
+
message: event.error.message
|
|
729
|
+
}, event.error.httpCode).disableAutoSerializing());
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
339
732
|
this.logger.error('Controller error', event.error);
|
|
340
733
|
event.send(new HtmlResponse('Internal error', 500));
|
|
341
734
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
event.response.writeHead(response.statusCode, {
|
|
358
|
-
Location: response.url
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
event.response.end();
|
|
362
|
-
}
|
|
363
|
-
else if (response instanceof ServerResponse || response instanceof HttpResponse) {
|
|
364
|
-
}
|
|
365
|
-
else if (response instanceof HtmlResponse) {
|
|
366
|
-
event.response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
367
|
-
if (response.statusCode)
|
|
368
|
-
event.response.writeHead(response.statusCode);
|
|
369
|
-
event.response.end(response.html);
|
|
370
|
-
}
|
|
371
|
-
else if (isElementStruct(response)) {
|
|
372
|
-
event.response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
373
|
-
event.response.end(await render(event.injectorContext, response));
|
|
374
|
-
}
|
|
375
|
-
else if (isClassInstance(response) && isRegisteredEntity(getClassTypeFromInstance(response))) {
|
|
376
|
-
event.response.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
377
|
-
event.response.end(JSON.stringify(jsonSerializer.for(getClassTypeFromInstance(response)).serialize(response)));
|
|
735
|
+
/**
|
|
736
|
+
* This happens before the result is sent.
|
|
737
|
+
*/
|
|
738
|
+
async onResultSerialization(event) {
|
|
739
|
+
if (!event.route)
|
|
740
|
+
return;
|
|
741
|
+
if (event.response.headersSent)
|
|
742
|
+
return;
|
|
743
|
+
if (event.result === undefined || event.result === null)
|
|
744
|
+
return;
|
|
745
|
+
if (event.result instanceof HtmlResponse || event.result instanceof Response || event.result instanceof ServerResponse || event.result instanceof Redirect || event.result instanceof stream.Readable) {
|
|
746
|
+
// don't do anything
|
|
378
747
|
}
|
|
379
|
-
else if (
|
|
380
|
-
event.
|
|
748
|
+
else if (event.result instanceof JSONResponse) {
|
|
749
|
+
const schema = (event.result._statusCode && event.route.getSchemaForResponse(event.result._statusCode)) || event.route.returnType;
|
|
750
|
+
if (!schema || !event.result.autoSerializing)
|
|
751
|
+
return;
|
|
752
|
+
const serializerToUse = event.route && event.route.serializer ? event.route.serializer : serializer;
|
|
753
|
+
const serialize = getSerializeFunction(schema, serializerToUse.serializeRegistry);
|
|
754
|
+
event.result.json = serialize(event.result.json, event.route.serializationOptions);
|
|
381
755
|
}
|
|
382
|
-
else if (
|
|
383
|
-
event.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
event.response.end(JSON.stringify(response.json));
|
|
756
|
+
else if (event.route.returnType && event.route.returnType.kind !== ReflectionKind.any) {
|
|
757
|
+
const serializerToUse = event.route && event.route.serializer ? event.route.serializer : serializer;
|
|
758
|
+
const serialize = getSerializeFunction(event.route.returnType, serializerToUse.serializeRegistry);
|
|
759
|
+
event.result = serialize(event.result, event.route.serializationOptions);
|
|
387
760
|
}
|
|
388
761
|
else {
|
|
389
|
-
event.
|
|
390
|
-
|
|
762
|
+
const schema = event.route.getSchemaForResponse(200);
|
|
763
|
+
if (!schema)
|
|
764
|
+
return;
|
|
765
|
+
const serializerToUse = event.route && event.route.serializer ? event.route.serializer : serializer;
|
|
766
|
+
const serialize = getSerializeFunction(schema, serializerToUse.serializeRegistry);
|
|
767
|
+
event.result = serialize(event.result, event.route.serializationOptions);
|
|
391
768
|
}
|
|
392
769
|
}
|
|
393
|
-
|
|
770
|
+
async onResponse(event) {
|
|
771
|
+
if (event.response.headersSent)
|
|
772
|
+
return;
|
|
773
|
+
this.resultFormatter.handle(event.result, event);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
HttpListener.__type = [() => HttpRouter, 'router', () => __ΩLoggerInterface, 'logger', () => HttpResultFormatter, 'resultFormatter', () => Stopwatch, 'stopwatch', 'constructor', () => httpWorkflow.onRequest.event, 'event', 'onRequest', () => httpWorkflow.onRoute.event, 'onRoute', () => httpWorkflow.onRoute.event, 'onRouteForward', () => httpWorkflow.onRouteNotFound.event, 'routeNotFound', () => httpWorkflow.onAuth.event, 'onAuth', () => httpWorkflow.onResolveParameters.event, 'onResolveParameters', () => httpWorkflow.onAccessDenied.event, 'onAccessDenied', () => httpWorkflow.onController.event, 'onController', () => httpWorkflow.onParametersFailed.event, 'onParametersFailed', () => httpWorkflow.onControllerError.event, 'onControllerError', () => httpWorkflow.onResponse.event, 'onResultSerialization', () => httpWorkflow.onResponse.event, 'onResponse', 'HttpListener', 'PP7!2"<n#2$<P7%2&<P7\'2(8<"0)Pi*2+$0,Pi-2+"0.Pi/2+"00Pi12+$`02Pi32+$04Pi52+"06Pi72+$08Pi92+"0:Pi;2+$0<Pi=2+$0>Pi?2+"0@PiA2+"0B5wC'];
|
|
394
777
|
__decorate([
|
|
395
778
|
eventDispatcher.listen(httpWorkflow.onRequest, 100),
|
|
396
779
|
__metadata("design:type", Function),
|
|
@@ -401,7 +784,7 @@ __decorate([
|
|
|
401
784
|
eventDispatcher.listen(httpWorkflow.onRoute, 100),
|
|
402
785
|
__metadata("design:type", Function),
|
|
403
786
|
__metadata("design:paramtypes", [Object]),
|
|
404
|
-
__metadata("design:returntype",
|
|
787
|
+
__metadata("design:returntype", Promise)
|
|
405
788
|
], HttpListener.prototype, "onRoute", null);
|
|
406
789
|
__decorate([
|
|
407
790
|
eventDispatcher.listen(httpWorkflow.onRoute, 1000),
|
|
@@ -451,16 +834,16 @@ __decorate([
|
|
|
451
834
|
__metadata("design:paramtypes", [Object]),
|
|
452
835
|
__metadata("design:returntype", void 0)
|
|
453
836
|
], HttpListener.prototype, "onControllerError", null);
|
|
837
|
+
__decorate([
|
|
838
|
+
eventDispatcher.listen(httpWorkflow.onResponse, -100),
|
|
839
|
+
__metadata("design:type", Function),
|
|
840
|
+
__metadata("design:paramtypes", [Object]),
|
|
841
|
+
__metadata("design:returntype", Promise)
|
|
842
|
+
], HttpListener.prototype, "onResultSerialization", null);
|
|
454
843
|
__decorate([
|
|
455
844
|
eventDispatcher.listen(httpWorkflow.onResponse, 100),
|
|
456
845
|
__metadata("design:type", Function),
|
|
457
846
|
__metadata("design:paramtypes", [Object]),
|
|
458
847
|
__metadata("design:returntype", Promise)
|
|
459
848
|
], HttpListener.prototype, "onResponse", null);
|
|
460
|
-
HttpListener = __decorate([
|
|
461
|
-
injectable(),
|
|
462
|
-
__metadata("design:paramtypes", [Router,
|
|
463
|
-
Logger])
|
|
464
|
-
], HttpListener);
|
|
465
|
-
export { HttpListener };
|
|
466
849
|
//# sourceMappingURL=http.js.map
|