@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.
Files changed (124) hide show
  1. package/CHANGELOG.md +236 -0
  2. package/dist/cjs/index.d.ts +14 -10
  3. package/dist/cjs/index.js +19 -11
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/src/controllers.d.ts +10 -3
  6. package/dist/cjs/src/controllers.js +7 -3
  7. package/dist/cjs/src/controllers.js.map +1 -1
  8. package/dist/cjs/src/decorator.d.ts +144 -70
  9. package/dist/cjs/src/decorator.js +277 -102
  10. package/dist/cjs/src/decorator.js.map +1 -1
  11. package/dist/cjs/src/filter.d.ts +49 -0
  12. package/dist/cjs/src/filter.js +215 -0
  13. package/dist/cjs/src/filter.js.map +1 -0
  14. package/dist/cjs/src/http-app.d.ts +8 -0
  15. package/dist/cjs/src/http-app.js +16 -0
  16. package/dist/cjs/src/http-app.js.map +1 -0
  17. package/dist/cjs/src/http.d.ts +131 -32
  18. package/dist/cjs/src/http.js +523 -122
  19. package/dist/cjs/src/http.js.map +1 -1
  20. package/dist/cjs/src/kernel.d.ts +50 -9
  21. package/dist/cjs/src/kernel.js +109 -98
  22. package/dist/cjs/src/kernel.js.map +1 -1
  23. package/dist/cjs/src/logger.d.ts +3 -3
  24. package/dist/cjs/src/logger.js +9 -12
  25. package/dist/cjs/src/logger.js.map +1 -1
  26. package/dist/cjs/src/middleware.d.ts +61 -0
  27. package/dist/cjs/src/middleware.js +95 -0
  28. package/dist/cjs/src/middleware.js.map +1 -0
  29. package/dist/cjs/src/model.d.ts +270 -4
  30. package/dist/cjs/src/model.js +401 -3
  31. package/dist/cjs/src/model.js.map +1 -1
  32. package/dist/cjs/src/module.config.d.ts +149 -4
  33. package/dist/cjs/src/module.config.js +11 -6
  34. package/dist/cjs/src/module.config.js.map +1 -1
  35. package/dist/cjs/src/module.d.ts +14 -32
  36. package/dist/cjs/src/module.js +122 -7
  37. package/dist/cjs/src/module.js.map +1 -1
  38. package/dist/cjs/src/request-parser.d.ts +37 -0
  39. package/dist/cjs/src/request-parser.js +382 -0
  40. package/dist/cjs/src/request-parser.js.map +1 -0
  41. package/dist/cjs/src/router.d.ts +174 -75
  42. package/dist/cjs/src/router.js +469 -288
  43. package/dist/cjs/src/router.js.map +1 -1
  44. package/dist/cjs/src/static-serving.d.ts +32 -4
  45. package/dist/cjs/src/static-serving.js +115 -71
  46. package/dist/cjs/src/static-serving.js.map +1 -1
  47. package/dist/cjs/src/utils.js +2 -2
  48. package/dist/cjs/src/utils.js.map +1 -1
  49. package/dist/cjs/tsconfig.tsbuildinfo +1 -2916
  50. package/dist/esm/index.d.ts +14 -10
  51. package/dist/esm/index.js +14 -10
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/esm/src/controllers.d.ts +10 -3
  54. package/dist/esm/src/controllers.js +7 -3
  55. package/dist/esm/src/controllers.js.map +1 -1
  56. package/dist/esm/src/decorator.d.ts +144 -70
  57. package/dist/esm/src/decorator.js +272 -99
  58. package/dist/esm/src/decorator.js.map +1 -1
  59. package/dist/esm/src/filter.d.ts +49 -0
  60. package/dist/esm/src/filter.js +209 -0
  61. package/dist/esm/src/filter.js.map +1 -0
  62. package/dist/esm/src/http-app.d.ts +8 -0
  63. package/dist/esm/src/http-app.js +12 -0
  64. package/dist/esm/src/http-app.js.map +1 -0
  65. package/dist/esm/src/http.d.ts +131 -32
  66. package/dist/esm/src/http.js +504 -121
  67. package/dist/esm/src/http.js.map +1 -1
  68. package/dist/esm/src/kernel.d.ts +50 -9
  69. package/dist/esm/src/kernel.js +110 -100
  70. package/dist/esm/src/kernel.js.map +1 -1
  71. package/dist/esm/src/logger.d.ts +3 -3
  72. package/dist/esm/src/logger.js +7 -11
  73. package/dist/esm/src/logger.js.map +1 -1
  74. package/dist/esm/src/middleware.d.ts +61 -0
  75. package/dist/esm/src/middleware.js +90 -0
  76. package/dist/esm/src/middleware.js.map +1 -0
  77. package/dist/esm/src/model.d.ts +270 -4
  78. package/dist/esm/src/model.js +357 -1
  79. package/dist/esm/src/model.js.map +1 -1
  80. package/dist/esm/src/module.config.d.ts +149 -4
  81. package/dist/esm/src/module.config.js +9 -5
  82. package/dist/esm/src/module.config.js.map +1 -1
  83. package/dist/esm/src/module.d.ts +14 -32
  84. package/dist/esm/src/module.js +121 -7
  85. package/dist/esm/src/module.js.map +1 -1
  86. package/dist/esm/src/request-parser.d.ts +37 -0
  87. package/dist/esm/src/request-parser.js +372 -0
  88. package/dist/esm/src/request-parser.js.map +1 -0
  89. package/dist/esm/src/router.d.ts +174 -75
  90. package/dist/esm/src/router.js +463 -285
  91. package/dist/esm/src/router.js.map +1 -1
  92. package/dist/esm/src/static-serving.d.ts +32 -4
  93. package/dist/esm/src/static-serving.js +107 -65
  94. package/dist/esm/src/static-serving.js.map +1 -1
  95. package/dist/esm/src/utils.js +1 -0
  96. package/dist/esm/src/utils.js.map +1 -1
  97. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -2916
  98. package/index.ts +14 -10
  99. package/package.json +30 -19
  100. package/src/controllers.ts +4 -3
  101. package/src/decorator.ts +242 -104
  102. package/src/filter.ts +224 -0
  103. package/src/http-app.ts +11 -0
  104. package/src/http.ts +501 -100
  105. package/src/kernel.ts +128 -80
  106. package/src/logger.ts +4 -6
  107. package/src/middleware.ts +116 -0
  108. package/src/model.ts +516 -5
  109. package/src/module.config.ts +168 -5
  110. package/src/module.ts +120 -7
  111. package/src/request-parser.ts +430 -0
  112. package/src/router.ts +546 -317
  113. package/src/static-serving.ts +120 -50
  114. package/src/utils.ts +0 -2
  115. package/tsconfig.esm.json +7 -7
  116. package/tsconfig.json +18 -11
  117. package/tsconfig.spec.json +8 -0
  118. package/dist/cjs/tests/router.spec.d.ts +0 -1
  119. package/dist/cjs/tests/router.spec.js +0 -481
  120. package/dist/cjs/tests/router.spec.js.map +0 -1
  121. package/dist/esm/tests/router.spec.d.ts +0 -1
  122. package/dist/esm/tests/router.spec.js +0 -479
  123. package/dist/esm/tests/router.spec.js.map +0 -1
  124. package/tests/router.spec.ts +0 -347
@@ -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
- import { CustomError } from '@deepkit/core';
20
- import { getClassTypeFromInstance, isClassInstance, isRegisteredEntity, jsonSerializer, ValidationFailed } from '@deepkit/type';
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 { injectable } from '@deepkit/injector';
25
- import { Logger } from '@deepkit/logger';
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 { isElementStruct, render } from '@deepkit/template';
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
- export function HttpError(code, defaultMessage = '') {
46
- return class extends CustomError {
47
- constructor(message = defaultMessage) {
48
- super(message);
49
- }
50
- static getHttpCode() {
51
- return code;
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
- export class HttpNotFoundError extends HttpError(404, 'Not found') {
109
+ HttpNotAcceptableError.__type = [() => createHttpError(406, "Not acceptable"), 'HttpNotAcceptableError', 'P7!5w"'];
110
+ export class HttpTimeoutError extends createHttpError(408, 'Request timeout') {
56
111
  }
57
- export class HttpBadRequestError extends HttpError(400, 'Bad request') {
112
+ HttpTimeoutError.__type = [() => createHttpError(408, "Request timeout"), 'HttpTimeoutError', 'P7!5w"'];
113
+ export class HttpConflictError extends createHttpError(409, 'Conflict') {
58
114
  }
59
- export class HttpAccessDeniedError extends HttpError(403, 'Access denied') {
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.stopped = true;
130
+ this.propagationStopped = true;
70
131
  }
71
- isStopped() {
72
- return this.stopped;
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
- export class HttpResolveParametersEvent extends HttpWorkflowEvent {
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
- export class HttpControllerEvent extends HttpWorkflowEvent {
169
- constructor(injectorContext, request, response, parameters = [], route) {
170
- super(injectorContext, request, response);
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
- export class HttpControllerErrorEvent extends HttpWorkflowEvent {
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 HtmlResponse {
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
- export class JSONResponse {
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
- let HttpListener = class HttpListener {
235
- constructor(router, logger) {
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 resolved = this.router.resolveRequest(event.request);
252
- if (resolved) {
253
- event.routeFound(resolved.routeConfig, resolved.parameters);
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.send(new HtmlResponse('Not found', 404));
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 controllerInstance = event.injectorContext.get(event.route.action.controller);
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
- const method = controllerInstance[event.route.action.methodName];
307
- event.next('response', new HttpResponseEvent(event.injectorContext, event.request, event.response, await method.apply(controllerInstance, event.parameters), event.route));
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
- event.next('controllerError', new HttpControllerErrorEvent(event.injectorContext, event.request, event.response, event.route, error));
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
- this.logger.error('Controller parameter resolving error:', event.error);
324
- if (event.error instanceof ValidationFailed) {
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
- }, 500));
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
- async onResponse(event) {
343
- const response = event.result;
344
- if (response === null || response === undefined) {
345
- event.response.end(response);
346
- }
347
- else if ('string' === typeof response) {
348
- event.response.end(response);
349
- }
350
- else if (response instanceof Redirect) {
351
- if (response.routeName) {
352
- event.response.writeHead(response.statusCode, {
353
- Location: this.router.resolveUrl(response.routeName, response.routeParameters)
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 (response instanceof Uint8Array) {
380
- event.response.end(response);
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 (response instanceof JSONResponse) {
383
- event.response.setHeader('Content-Type', 'application/json; charset=utf-8');
384
- if (response.statusCode)
385
- event.response.writeHead(response.statusCode);
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.response.setHeader('Content-Type', 'application/json; charset=utf-8');
390
- event.response.end(JSON.stringify(response));
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", void 0)
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