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