@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,3 +1,33 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ const __ΩPartial = ['T', 'Partial', 'l+e#!e"!fRb!Pde"!gN#"w"y'];
8
+ const __ΩRecord = ['K', 'T', 'Record', 'l\'e#"Rb!b"Pde"!N#!w#y'];
9
+ /*@ts-ignore*/
10
+ import { __ΩSerializationOptions } from '@deepkit/type';
11
+ /*@ts-ignore*/
12
+ import { __ΩClassType } from '@deepkit/core';
13
+ /*@ts-ignore*/
14
+ import { __ΩMiddlewareRegistryEntry } from '@deepkit/app';
15
+ /*@ts-ignore*/
16
+ import { __ΩHttpDecorator } from './decorator.js';
17
+ /*@ts-ignore*/
18
+ import { __ΩLoggerInterface } from '@deepkit/logger';
19
+ /*@ts-ignore*/
20
+ import { __ΩHttpRequestPositionedParameters } from './model.js';
21
+ /*@ts-ignore*/
22
+ import { __ΩHttpMiddlewareFn } from './middleware.js';
23
+ /*@ts-ignore*/
24
+ import { __ΩHttpRequestQuery } from './model.js';
25
+ /*@ts-ignore*/
26
+ import { __ΩHttpRequestResolvedParameters } from './model.js';
27
+ function __assignType(fn, args) {
28
+ fn.__type = args;
29
+ return fn;
30
+ }
1
31
  /*
2
32
  * Deepkit Framework
3
33
  * Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
@@ -7,96 +37,95 @@
7
37
  *
8
38
  * You should have received a copy of the MIT License along with this program.
9
39
  */
10
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
- return c > 3 && r && Object.defineProperty(target, key, r), r;
15
- };
16
- var __metadata = (this && this.__metadata) || function (k, v) {
17
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
18
- };
19
- import { asyncOperation, CompilerContext } from '@deepkit/core';
20
- import { getClassSchema, getPropertyXtoClassFunction, jitValidateProperty, jsonSerializer, ValidationFailed } from '@deepkit/type';
21
- // @ts-ignore
22
- import formidable from 'formidable';
23
- import { join } from 'path';
24
- import querystring from 'querystring';
25
- import { httpClass } from './decorator';
26
- import { injectable, Tag } from '@deepkit/injector';
40
+ import { CompilerContext, getClassName, isArray, isClass, urlJoin } from '@deepkit/core';
41
+ import { entity, ReflectionClass, ReflectionFunction, ReflectionKind, ReflectionParameter, serializer, Serializer, ValidationError, } from '@deepkit/type';
42
+ import { getActions, HttpAction, httpClass, HttpController } from './decorator.js';
43
+ import { HttpRequest } from './model.js';
44
+ import { InjectorContext, InjectorModule } from '@deepkit/injector';
27
45
  import { Logger } from '@deepkit/logger';
28
- import { TagProviders } from '@deepkit/app';
29
- import { HttpControllers } from './controllers';
30
- function parseBody(form, req) {
31
- return asyncOperation((resolve, reject) => {
32
- form.parse(req, (err, fields, files) => {
33
- if (err) {
34
- reject(err);
35
- }
36
- else {
37
- resolve({ fields, files });
38
- }
39
- });
40
- });
46
+ import { HttpControllers } from './controllers.js';
47
+ import { MiddlewareRegistry } from '@deepkit/app';
48
+ import { HttpMiddlewareConfig } from './middleware.js';
49
+ //@ts-ignore
50
+ import qs from 'qs';
51
+ import { HtmlResponse, JSONResponse, Response } from './http.js';
52
+ import { getRequestParserCodeForParameters, ParameterForRequestParser, parseRoutePathToRegex } from './request-parser.js';
53
+ import { HttpConfig } from './module.config.js';
54
+ const __ΩRouteParameterResolverForInjector = [() => InjectorContext, 'injector', () => __ΩHttpRequestPositionedParameters, () => __ΩHttpRequestPositionedParameters, '', 'RouteParameterResolverForInjector', 'PP7!2"Pn#n$`J/%w&y'];
55
+ export { __ΩRouteParameterResolverForInjector as __ΩRouteParameterResolverForInjector };
56
+ const __ΩResolvedController = [() => __ΩRouteParameterResolverForInjector, 'parameters', () => RouteConfig, 'routeConfig', () => UploadedFile, 'uploadedFiles', () => InjectorContext, 'injector', () => __ΩHttpMiddlewareFn, 'fn', 'timeout', '', 'middlewares', 'ResolvedController', 'Pn!4"P7#4$P&P7%LM4&PP7\'2(Pn)4*\'4+8MF/,4-8Mw.y'];
57
+ export const UploadedFileSymbol = Symbol('UploadedFile');
58
+ let UploadedFile = class UploadedFile {
59
+ };
60
+ UploadedFile.__type = [() => UploadedFileSymbol, 'validator', 'size', 'path', 'name', 'type', 'lastModifiedDate', 'UploadedFile', 'Pi!,J3"\'3#&3$P&,J3%P&,J3&PT,J3\'5w('];
61
+ UploadedFile = __decorate([
62
+ entity.name('@deepkit/UploadedFile')
63
+ ], UploadedFile);
64
+ export { UploadedFile };
65
+ serializer.typeGuards.getRegistry(1).registerClass(UploadedFile, __assignType((type, state) => {
66
+ state.setContext({ UploadedFileSymbol });
67
+ state.addSetterAndReportErrorIfInvalid('uploadSecurity', 'Not an uploaded file', `typeof ${state.accessor} === 'object' && ${state.accessor} !== null && ${state.accessor}.validator === UploadedFileSymbol`);
68
+ }, ['type', 'state', '', 'P"2!"2""/#']));
69
+ const __ΩRouteFunctionControllerAction = ["function", 'type', () => InjectorModule, 'module', 'args', '', 'fn', 'RouteFunctionControllerAction', 'P.!4"P"7#4$8P"@2%"/&4\'Mw(y'];
70
+ export { __ΩRouteFunctionControllerAction as __ΩRouteFunctionControllerAction };
71
+ const __ΩRouteClassControllerAction = ["controller", 'type', () => InjectorModule, 'module', () => __ΩClassType, 'controller', 'methodName', 'RouteClassControllerAction', 'P.!4"P"7#4$8n%4&&4\'Mw(y'];
72
+ export { __ΩRouteClassControllerAction as __ΩRouteClassControllerAction };
73
+ export function getRouteActionLabel(action) {
74
+ if (action.type === 'controller')
75
+ return `${getClassName(action.controller)}.${action.methodName}`;
76
+ return action.fn.name;
41
77
  }
78
+ getRouteActionLabel.__type = [() => __ΩRouteClassControllerAction, () => __ΩRouteFunctionControllerAction, 'action', 'getRouteActionLabel', 'PPn!n"J2#&/$'];
42
79
  export class RouteConfig {
43
- constructor(name, httpMethod, path, action) {
80
+ constructor(name, httpMethods, path, action, internal = false) {
44
81
  this.name = name;
45
- this.httpMethod = httpMethod;
82
+ this.httpMethods = httpMethods;
46
83
  this.path = path;
47
84
  this.action = action;
85
+ this.internal = internal;
48
86
  this.baseUrl = '';
49
- this.parameterRegularExpressions = {};
50
- this.throws = [];
87
+ this.responses = [];
51
88
  this.description = '';
52
89
  this.groups = [];
53
90
  this.category = '';
91
+ this.resolverForToken = new Map();
92
+ this.middlewares = [];
93
+ this.resolverForParameterName = new Map();
54
94
  /**
55
95
  * An arbitrary data container the user can use to store app specific settings/values.
56
96
  */
57
- this.data = new Map();
58
- this.parameters = {};
97
+ this.data = (Map.Ω = [['"'], ['"']], new Map());
98
+ }
99
+ getReflectionFunction() {
100
+ return this.action.type === 'controller' ?
101
+ ReflectionClass.from(this.action.controller).getMethod(this.action.methodName)
102
+ : ReflectionFunction.from(this.action.fn);
103
+ }
104
+ getSchemaForResponse(statusCode) {
105
+ if (!this.responses.length)
106
+ return;
107
+ for (const response of this.responses) {
108
+ if (response.statusCode === statusCode)
109
+ return response.type;
110
+ }
111
+ return;
59
112
  }
60
113
  getFullPath() {
61
- let path = this.baseUrl ? join(this.baseUrl, this.path) : this.path;
114
+ let path = this.baseUrl ? urlJoin(this.baseUrl, this.path) : this.path;
62
115
  if (!path.startsWith('/'))
63
116
  path = '/' + path;
64
117
  return path;
65
118
  }
66
119
  }
67
- /**
68
- * When this class is injected into a route, then validation errors are not automatically thrown (using onHttpControllerValidationError event),
69
- * but injected to the route itself. The user is then responsible to handle the errors.
70
- *
71
- * Note: The body parameter is still passed, however it might contain now invalid data. The BodyValidation tells what data is invalid.
72
- */
73
- export class BodyValidation {
74
- constructor(errors = []) {
75
- this.errors = errors;
76
- }
77
- hasErrors(prefix) {
78
- return this.getErrors(prefix).length > 0;
79
- }
80
- getErrors(prefix) {
81
- if (prefix)
82
- return this.errors.filter(v => v.path.startsWith(prefix));
83
- return this.errors;
84
- }
85
- getErrorsForPath(path) {
86
- return this.errors.filter(v => v.path === path);
87
- }
88
- getErrorMessageForPath(path) {
89
- return this.getErrorsForPath(path).map(v => v.message).join(', ');
90
- }
91
- }
92
- class ParsedRoute {
120
+ RouteConfig.__type = ['baseUrl', function () { return ''; }, 'statusCode', 'description', 'Type', 'type', 'responses', function () { return []; }, function () { return ''; }, 'groups', function () { return []; }, 'category', function () { return ''; }, 'returnType', () => __ΩSerializationOptions, 'serializationOptions', () => Serializer, 'serializer', () => InjectorModule, 'module', () => __ΩClassType, 'resolverForToken', function () { return new Map(); }, () => HttpMiddlewareConfig, 'config', () => InjectorModule, 'middlewares', function () { return []; }, () => __ΩClassType, 'resolverForParameterName', function () { return new Map(); }, 'data', function () { return (Map.Ω = [['"'], ['"']], new Map()); }, 'name', 'httpMethods', 'path', () => __ΩRouteClassControllerAction, () => __ΩRouteFunctionControllerAction, 'action', 'internal', () => false, 'constructor', () => ReflectionFunction, 'getReflectionFunction', 'getSchemaForResponse', 'getFullPath', 'RouteConfig', '&3!>"P\'4#&4$"w%4&8MF3\'>(&3$>)&F3*>+&3,>-"w%3.8n/308P71328P"73348"n5E36>7PP7849P"7:448MF3;><&n=E3>>?!3@>AP&2B:9&F2C:9&2D:9PnEnFJ2G:9)2H:>I"0JPP7K0LP\'2#P"w%-J0MP&0N5wO'];
121
+ export class ParsedRoute {
93
122
  constructor(routeConfig) {
94
123
  this.routeConfig = routeConfig;
95
124
  this.pathParameterNames = {};
96
125
  this.parameters = [];
97
126
  }
98
- addParameter(property, config) {
99
- const parameter = new ParsedRouteParameter(property, config);
127
+ addParameter(property) {
128
+ const parameter = new ParameterForRequestParser(property);
100
129
  this.parameters.push(parameter);
101
130
  return parameter;
102
131
  }
@@ -111,220 +140,396 @@ class ParsedRoute {
111
140
  throw new Error(`No route parameter with name ${name} defined.`);
112
141
  }
113
142
  }
114
- class ParsedRouteParameter {
115
- constructor(property, config) {
116
- this.property = property;
117
- this.config = config;
118
- }
119
- get body() {
120
- return this.config ? this.config.type === 'body' : false;
121
- }
122
- get query() {
123
- return this.config ? this.config.type === 'query' : false;
124
- }
125
- get typePath() {
126
- return this.config ? this.config.typePath : undefined;
127
- }
128
- getName() {
129
- return this.property.name;
130
- }
131
- isPartOfPath() {
132
- return this.regexPosition !== undefined;
133
- }
134
- }
135
- function parseRoutePathToRegex(routeConfig) {
136
- const parameterNames = {};
137
- let path = routeConfig.getFullPath();
138
- let argumentIndex = 0;
139
- path = path.replace(/:(\w+)/g, (a, name) => {
140
- parameterNames[name] = argumentIndex;
141
- argumentIndex++;
142
- return routeConfig.parameterRegularExpressions[name] ? '(' + routeConfig.parameterRegularExpressions[name] + ')' : String.raw `([^/]+)`;
143
- });
144
- return { regex: path, parameterNames };
145
- }
143
+ ParsedRoute.__type = ['regex', 'pathParameterNames', function () { return {}; }, () => ParameterForRequestParser, 'parameters', function () { return []; }, () => RouteConfig, 'routeConfig', 'constructor', () => ReflectionParameter, 'property', () => ParameterForRequestParser, 'addParameter', () => ParameterForRequestParser, 'getParameters', 'name', () => ParameterForRequestParser, 'getParameter', 'ParsedRoute', '&3!8P&\'LM3">#P7$F3%<>&PP7\'2(:"0)PP7*2+P7,0-PP7.F0/P&20P71025w3'];
146
144
  export function parseRouteControllerAction(routeConfig) {
147
- const schema = getClassSchema(routeConfig.action.controller);
148
145
  const parsedRoute = new ParsedRoute(routeConfig);
149
- const methodArgumentProperties = schema.getMethodProperties(routeConfig.action.methodName);
150
- const parsedPath = parseRoutePathToRegex(routeConfig);
146
+ const parameters = routeConfig.getReflectionFunction().getParameters();
147
+ const parsedPath = parseRoutePathToRegex(routeConfig.getFullPath(), parameters);
151
148
  parsedRoute.regex = parsedPath.regex;
152
149
  parsedRoute.pathParameterNames = parsedPath.parameterNames;
153
- for (const property of methodArgumentProperties) {
154
- const decoratorData = routeConfig.parameters[property.name];
155
- const parsedParameter = parsedRoute.addParameter(property, decoratorData);
156
- if (decoratorData && decoratorData.optional)
157
- property.isOptional = true;
158
- if (property.type === 'class' && property.classType === BodyValidation) {
159
- parsedRoute.customValidationErrorHandling = parsedParameter;
160
- }
150
+ for (const property of parameters) {
151
+ const parsedParameter = parsedRoute.addParameter(property);
161
152
  parsedParameter.regexPosition = parsedPath.parameterNames[property.name];
162
153
  }
163
154
  return parsedRoute;
164
155
  }
156
+ parseRouteControllerAction.__type = [() => RouteConfig, 'routeConfig', () => ParsedRoute, 'parseRouteControllerAction', 'PP7!2"P7#/$'];
165
157
  export function dotToUrlPath(dotPath) {
166
158
  if (-1 === dotPath.indexOf('.'))
167
159
  return dotPath;
168
160
  return dotPath.replace(/\./g, '][').replace('][', '[') + ']';
169
161
  }
170
- export class RouteParameterResolverTag extends Tag {
171
- constructor(provider) {
172
- super(provider);
173
- this.provider = provider;
174
- this.classTypes = [];
175
- if (!this.provider.scope)
176
- provider.scope = 'http';
177
- }
178
- forClassType(...classTypes) {
179
- this.classTypes = classTypes;
180
- return this;
162
+ dotToUrlPath.__type = ['dotPath', 'dotToUrlPath', 'P&2!&/"'];
163
+ const __ΩRouteParameterResolver = [() => __ΩRouteParameterResolverContext, 'context', 'resolve', 'RouteParameterResolver', 'PPn!2"P""`J1#Mw$y'];
164
+ export { __ΩRouteParameterResolver as __ΩRouteParameterResolver };
165
+ const __ΩRouteParameterResolverContext = [() => __ΩClassType, 'token', () => RouteConfig, 'route', () => HttpRequest, 'request', 'name', 'value', () => __ΩHttpRequestQuery, 'query', () => __ΩHttpRequestResolvedParameters, 'parameters', () => ReflectionParameter, 'type', 'RouteParameterResolverContext', 'PPn!&+"J4"P7#4$P7%4&"4\'"4(n)4*n+4,P7-4.Mw/y'];
166
+ export { __ΩRouteParameterResolverContext as __ΩRouteParameterResolverContext };
167
+ function filterMiddlewaresForRoute(middlewareRawConfigs, routeConfig, fullPath) {
168
+ const middlewares = middlewareRawConfigs.slice(0);
169
+ middlewares.push(...routeConfig.middlewares);
170
+ const middlewareConfigs = middlewares.filter(__assignType((v) => {
171
+ if (!(v.config instanceof HttpMiddlewareConfig))
172
+ return false;
173
+ if (v.config.controllers.length && routeConfig.action.type === 'controller' && !v.config.controllers.includes(routeConfig.action.controller)) {
174
+ return false;
175
+ }
176
+ if (v.config.excludeControllers.length && routeConfig.action.type === 'controller' && v.config.excludeControllers.includes(routeConfig.action.controller)) {
177
+ return false;
178
+ }
179
+ if (v.config.modules.length && (!routeConfig.module || !v.config.modules.includes(routeConfig.module))) {
180
+ if (!routeConfig.module)
181
+ return false;
182
+ for (const module of v.config.modules) {
183
+ if (routeConfig.module.id !== module.id)
184
+ return false;
185
+ }
186
+ }
187
+ if (v.config.selfModule && v.module.id !== routeConfig.module?.id)
188
+ return false;
189
+ if (v.config.routeNames.length) {
190
+ let found = false;
191
+ for (const name of v.config.routeNames) {
192
+ if (name.includes('*')) {
193
+ const regex = new RegExp('^' + name.replace(/\*/g, '.*') + '$');
194
+ if (regex.test(routeConfig.name)) {
195
+ found = true;
196
+ break;
197
+ }
198
+ }
199
+ else if (name === routeConfig.name) {
200
+ found = true;
201
+ break;
202
+ }
203
+ }
204
+ if (!found)
205
+ return false;
206
+ }
207
+ if (v.config.excludeRouteNames.length) {
208
+ for (const name of v.config.excludeRouteNames) {
209
+ if (name.includes('*')) {
210
+ const regex = new RegExp('^' + name.replace(/\*/g, '.*') + '$');
211
+ if (regex.test(routeConfig.name))
212
+ return false;
213
+ }
214
+ else if (name == routeConfig.name) {
215
+ return false;
216
+ }
217
+ }
218
+ }
219
+ for (const route of v.config.routes) {
220
+ if (route.httpMethod && !routeConfig.httpMethods.includes(route.httpMethod))
221
+ return false;
222
+ if (route.category && route.category !== routeConfig.category)
223
+ return false;
224
+ if (route.excludeCategory && route.excludeCategory === routeConfig.category)
225
+ return false;
226
+ if (route.group && !routeConfig.groups.includes(route.group))
227
+ return false;
228
+ if (route.excludeGroup && routeConfig.groups.includes(route.excludeGroup))
229
+ return false;
230
+ if (route.path || route.pathRegExp) {
231
+ if (!route.pathRegExp && route.path)
232
+ route.pathRegExp = new RegExp('^' + route.path.replace(/\*/g, '.*') + '$');
233
+ if (route.pathRegExp && !route.pathRegExp.test(fullPath))
234
+ return false;
235
+ }
236
+ }
237
+ return true;
238
+ }, ['v', '', 'P"2!"/"']));
239
+ middlewareConfigs.sort(__assignType((a, b) => {
240
+ return a.config.order - b.config.order;
241
+ }, ['a', 'b', '', 'P"2!"2""/#']));
242
+ return middlewareConfigs;
243
+ }
244
+ filterMiddlewaresForRoute.__type = [() => __ΩMiddlewareRegistryEntry, 'middlewareRawConfigs', () => RouteConfig, 'routeConfig', 'fullPath', () => HttpMiddlewareConfig, 'config', () => InjectorModule, 'module', 'filterMiddlewaresForRoute', 'Pn!F2"P7#2$&2%PP7&4\'P"7(4)MF/*'];
245
+ const __ΩHttpRouterFunctionOptions = ['path', 'name', 'methods', 'description', 'category', 'groups', () => __ΩRecord, 'data', 'baseUrl', () => HttpMiddlewareConfig, '', 'middlewares', () => Serializer, 'serializer', () => __ΩSerializationOptions, 'serializationOptions', () => __ΩClassType, 'resolverForToken', () => __ΩClassType, 'resolverForParameterName', 'statusCode', 'Type', 'type', 'responses', 'HttpRouterFunctionOptions', 'P&4!&4"8&F4#8&4$8&4%8&F4&8""o\'#4(8&4)8PP7*/+F4,8P7-4.8n/408"n1E428&n3E448P\'45&4$"w6478MF488Mw9y'];
246
+ export { __ΩHttpRouterFunctionOptions as __ΩHttpRouterFunctionOptions };
247
+ function convertOptions(methods, pathOrOptions, defaultOptions) {
248
+ const options = 'string' === typeof pathOrOptions ? { path: pathOrOptions } : pathOrOptions;
249
+ if (options.methods)
250
+ return options;
251
+ return { ...options, methods };
252
+ }
253
+ convertOptions.__type = ['methods', () => __ΩHttpRouterFunctionOptions, 'pathOrOptions', () => __ΩPartial, () => __ΩHttpRouterFunctionOptions, 'defaultOptions', () => __ΩHttpRouterFunctionOptions, 'convertOptions', 'P&F2!P&n"J2#n%o$"2&n\'/('];
254
+ /**
255
+ * Annotated types like HTMLResponse/JSONResponse are not used for serialization.
256
+ */
257
+ function filterValidReturnType(type) {
258
+ if (type.kind === ReflectionKind.class && (type.classType === HtmlResponse || type.classType === JSONResponse || type.classType === Response))
259
+ return;
260
+ return type;
261
+ }
262
+ filterValidReturnType.__type = ['Type', 'type', 'filterValidReturnType', 'P"w!2"P"w!-J/#'];
263
+ export class HttpRouterRegistryFunctionRegistrar {
264
+ constructor() {
265
+ this.defaultOptions = {};
266
+ }
267
+ /**
268
+ * Returns a new registrar object with default options that apply to each registered route through this registrar.
269
+ *
270
+ * ```typescript
271
+ * const registry: HttpRouterRegistry = ...;
272
+ *
273
+ * const secretRegistry = registry.forOptions({groups: ['secret']});
274
+ *
275
+ * secretRegistry.get('/admin/groups', () => {
276
+ * });
277
+ *
278
+ * secretRegistry.get('/admin/users', () => {
279
+ * });
280
+ * ```
281
+ */
282
+ forOptions(options) {
283
+ var _a;
284
+ const that = this;
285
+ return new (_a = class extends HttpRouterRegistryFunctionRegistrar {
286
+ constructor() {
287
+ super(...arguments);
288
+ this.defaultOptions = options;
289
+ }
290
+ addRoute(routeConfig) {
291
+ that.addRoute(routeConfig);
292
+ }
293
+ },
294
+ _a.__type = [() => HttpRouterRegistryFunctionRegistrar, 'defaultOptions', function () { return options; }, () => RouteConfig, 'routeConfig', 'addRoute', 'P7!!3">#PP7$2%"0&5'],
295
+ _a);
296
+ }
297
+ any(pathOrOptions, callback) {
298
+ this.register(convertOptions([], pathOrOptions, this.defaultOptions), callback);
299
+ }
300
+ add(decorator, callback) {
301
+ const data = decorator(Object, '_');
302
+ const action = isArray(data) ? data.find(__assignType(v => v instanceof HttpAction, ['v', '', 'P"2!"/"'])) : undefined;
303
+ if (!action)
304
+ throw new Error('No HttpAction available');
305
+ const fn = ReflectionFunction.from(callback);
306
+ const routeConfig = createRouteConfigFromHttpAction({
307
+ type: 'function',
308
+ fn: callback,
309
+ }, action);
310
+ routeConfig.returnType = filterValidReturnType(fn.getReturnType());
311
+ this.addRoute(routeConfig);
312
+ }
313
+ get(pathOrOptions, callback) {
314
+ this.register(convertOptions(['GET'], pathOrOptions, this.defaultOptions), callback);
315
+ }
316
+ post(pathOrOptions, callback) {
317
+ this.register(convertOptions(['POST'], pathOrOptions, this.defaultOptions), callback);
318
+ }
319
+ put(pathOrOptions, callback) {
320
+ this.register(convertOptions(['PUT'], pathOrOptions, this.defaultOptions), callback);
321
+ }
322
+ patch(pathOrOptions, callback) {
323
+ this.register(convertOptions(['PATCH'], pathOrOptions, this.defaultOptions), callback);
324
+ }
325
+ delete(pathOrOptions, callback) {
326
+ this.register(convertOptions(['DELETE'], pathOrOptions, this.defaultOptions), callback);
327
+ }
328
+ options(pathOrOptions, callback) {
329
+ this.register(convertOptions(['OPTIONS'], pathOrOptions, this.defaultOptions), callback);
330
+ }
331
+ trace(pathOrOptions, callback) {
332
+ this.register(convertOptions(['TRACE'], pathOrOptions, this.defaultOptions), callback);
333
+ }
334
+ head(pathOrOptions, callback) {
335
+ this.register(convertOptions(['HEAD'], pathOrOptions, this.defaultOptions), callback);
336
+ }
337
+ register(options, callback, module) {
338
+ const fn = ReflectionFunction.from(callback);
339
+ const routeConfig = new RouteConfig(options.name || '', options.methods || [], options.path, {
340
+ type: 'function',
341
+ fn: callback,
342
+ });
343
+ routeConfig.module = module;
344
+ if (options.responses)
345
+ routeConfig.responses = options.responses;
346
+ if (options.description)
347
+ routeConfig.description = options.description;
348
+ if (options.category)
349
+ routeConfig.category = options.category;
350
+ if (options.groups)
351
+ routeConfig.groups = options.groups;
352
+ if (options.data)
353
+ routeConfig.data = new Map(Object.entries(options.data));
354
+ if (options.baseUrl)
355
+ routeConfig.baseUrl = options.baseUrl;
356
+ if (options.middlewares) {
357
+ routeConfig.middlewares = options.middlewares.map(__assignType(v => {
358
+ return { config: v(), module };
359
+ }, ['v', '', 'P"2!"/"']));
360
+ }
361
+ if (options.resolverForToken) {
362
+ for (const item of options.resolverForToken)
363
+ routeConfig.resolverForToken.set(...item);
364
+ }
365
+ if (options.resolverForToken) {
366
+ for (const item of options.resolverForToken)
367
+ routeConfig.resolverForToken.set(...item);
368
+ }
369
+ if (options.resolverForParameterName) {
370
+ for (const item of options.resolverForParameterName)
371
+ routeConfig.resolverForParameterName.set(...item);
372
+ }
373
+ routeConfig.serializer = options.serializer;
374
+ routeConfig.serializationOptions = options.serializationOptions;
375
+ routeConfig.returnType = filterValidReturnType(fn.getReturnType());
376
+ this.addRoute(routeConfig);
181
377
  }
182
378
  }
183
- let Router = class Router {
184
- constructor(controllers, logger, tagProviders) {
185
- this.logger = logger;
379
+ HttpRouterRegistryFunctionRegistrar.__type = [() => __ΩPartial, () => __ΩHttpRouterFunctionOptions, 'defaultOptions', function () { return {}; }, () => RouteConfig, 'routeConfig', 'addRoute', () => __ΩPartial, () => __ΩHttpRouterFunctionOptions, 'options', () => HttpRouterRegistryFunctionRegistrar, 'forOptions', () => __ΩHttpRouterFunctionOptions, 'pathOrOptions', 'args', '', 'callback', 'any', () => __ΩHttpDecorator, 'decorator', 'add', () => __ΩHttpRouterFunctionOptions, 'get', () => __ΩHttpRouterFunctionOptions, 'post', () => __ΩHttpRouterFunctionOptions, 'put', () => __ΩHttpRouterFunctionOptions, 'patch', () => __ΩHttpRouterFunctionOptions, 'delete', () => __ΩHttpRouterFunctionOptions, () => __ΩHttpRouterFunctionOptions, 'trace', () => __ΩHttpRouterFunctionOptions, 'head', () => __ΩHttpRouterFunctionOptions, () => InjectorModule, 'module', 'register', 'HttpRouterRegistryFunctionRegistrar', 'n"o!"3#<>$PP7%2&$0\'=Pn)o("2*P7+0,PP&n-J2.P"@2/"/021"02Pn324P"@2/"/021"05PP&n6J2.P"@2/"/021"07PP&n8J2.P"@2/"/021"09PP&n:J2.P"@2/"/021"0;PP&n<J2.P"@2/"/021"0=PP&n>J2.P"@2/"/021"0?PP&n@J2.P"@2/"/021"0*PP&nAJ2.P"@2/"/021"0BPP&nCJ2.P"@2/"/021"0DPnE2*P"@2/"/021P"7F2G8"0H;5wI'];
380
+ function createRouteConfigFromHttpAction(routeAction, action, module, controller) {
381
+ const routeConfig = new RouteConfig(action.name, action.httpMethods, action.path, routeAction);
382
+ routeConfig.responses = action.responses;
383
+ routeConfig.description = action.description;
384
+ routeConfig.category = action.category;
385
+ routeConfig.groups = action.groups;
386
+ routeConfig.data = new Map(action.data);
387
+ if (controller) {
388
+ routeConfig.baseUrl = controller.baseUrl;
389
+ routeConfig.middlewares = controller.middlewares.map(__assignType(v => {
390
+ return { config: v(), module };
391
+ }, ['v', '', 'P"2!"/"']));
392
+ routeConfig.resolverForToken = new Map(controller.resolverForToken);
393
+ routeConfig.resolverForParameterName = new Map(controller.resolverForParameterName);
394
+ }
395
+ routeConfig.middlewares.push(...action.middlewares.map(__assignType(v => {
396
+ return { config: v(), module };
397
+ }, ['v', '', 'P"2!"/"'])));
398
+ for (const item of action.resolverForToken)
399
+ routeConfig.resolverForToken.set(...item);
400
+ for (const item of action.resolverForParameterName)
401
+ routeConfig.resolverForParameterName.set(...item);
402
+ routeConfig.serializer = action.serializer;
403
+ routeConfig.serializationOptions = action.serializationOptions;
404
+ return routeConfig;
405
+ }
406
+ createRouteConfigFromHttpAction.__type = [() => __ΩRouteClassControllerAction, () => __ΩRouteFunctionControllerAction, 'routeAction', () => HttpAction, 'action', () => InjectorModule, 'module', () => HttpController, 'controller', 'createRouteConfigFromHttpAction', 'PPn!n"J2#P7$2%P"7&2\'8P7(2)8"/*'];
407
+ export class HttpRouterRegistry extends HttpRouterRegistryFunctionRegistrar {
408
+ constructor() {
409
+ super(...arguments);
186
410
  this.routes = [];
187
- this.parameterResolverTags = [];
188
- //todo, move some settings to KernelConfig
189
- this.form = formidable({
190
- multiples: true,
191
- hash: 'sha1',
192
- enabledPlugins: ['octetstream', 'querystring', 'json'],
193
- });
194
- this.parameterResolverTags = tagProviders.getProviders(RouteParameterResolverTag);
195
- for (const controller of controllers.controllers)
196
- this.addRouteForController(controller);
411
+ this.buildId = 1;
412
+ }
413
+ getBuildId() {
414
+ return this.buildId;
197
415
  }
198
416
  getRoutes() {
199
417
  return this.routes;
200
418
  }
201
- static forControllers(controllers, tagProviders = new TagProviders()) {
202
- return new this(new HttpControllers(controllers), new Logger([], []), tagProviders);
419
+ addRouteForController(controller, module) {
420
+ const controllerData = httpClass._fetch(controller);
421
+ if (!controllerData)
422
+ throw new Error(`Http controller class ${getClassName(controller)} has no @http.controller decorator.`);
423
+ const schema = ReflectionClass.from(controller);
424
+ for (const action of getActions(controller)) {
425
+ const routeAction = {
426
+ type: 'controller',
427
+ controller,
428
+ module,
429
+ methodName: action.methodName
430
+ };
431
+ const routeConfig = createRouteConfigFromHttpAction(routeAction, action, module, controllerData);
432
+ routeConfig.module = module;
433
+ if (schema.hasMethod(action.methodName))
434
+ routeConfig.returnType = filterValidReturnType(schema.getMethod(action.methodName).getReturnType());
435
+ this.addRoute(routeConfig);
436
+ }
437
+ }
438
+ addRoute(routeConfig) {
439
+ this.routes.push(routeConfig);
440
+ this.buildId++;
441
+ }
442
+ }
443
+ HttpRouterRegistry.__type = [() => HttpRouterRegistryFunctionRegistrar, () => RouteConfig, 'routes', function () { return []; }, 'buildId', function () { return 1; }, 'getBuildId', () => RouteConfig, 'getRoutes', () => __ΩClassType, 'controller', () => InjectorModule, 'module', 'addRouteForController', () => RouteConfig, 'routeConfig', 'addRoute', 'HttpRouterRegistry', 'P7!P7"F3#<>$\'3%;>&P\'0\'PP7(F0)Pn*2+P"7,2-"0.PP7/20"015w2'];
444
+ export class HttpRouter {
445
+ constructor(controllers, logger, config, middlewareRegistry = new MiddlewareRegistry, registry = new HttpRouterRegistry) {
446
+ this.logger = logger;
447
+ this.config = config;
448
+ this.middlewareRegistry = middlewareRegistry;
449
+ this.registry = registry;
450
+ this.buildId = 0;
451
+ for (const controller of controllers.controllers) {
452
+ this.addRouteForController(controller.controller, controller.module);
453
+ }
454
+ }
455
+ getRoutes() {
456
+ return this.registry.getRoutes();
457
+ }
458
+ static forControllers(controllers, middlewareRegistry = new MiddlewareRegistry(), module = new InjectorModule(), config = new HttpConfig()) {
459
+ return new this(new HttpControllers(controllers.map(__assignType(v => {
460
+ return isClass(v) ? { controller: v, module } : v;
461
+ }, ['v', '', 'P"2!"/"']))), new Logger([], []), config, middlewareRegistry);
203
462
  }
204
463
  getRouteCode(compiler, routeConfig) {
205
- const routeConfigVar = compiler.reserveVariable('routeConfigVar', routeConfig);
206
464
  const parsedRoute = parseRouteControllerAction(routeConfig);
207
465
  const path = routeConfig.getFullPath();
208
- const prefix = path.substr(0, path.indexOf(':'));
466
+ const pathParamStarter = path.indexOf(':');
467
+ const prefix = path.substr(0, pathParamStarter);
209
468
  const regexVar = compiler.reserveVariable('regex', new RegExp('^' + parsedRoute.regex + '$'));
210
- const setParameters = [];
211
- const parameterNames = [];
212
- const parameterValidator = [];
213
- let bodyValidationErrorHandling = `if (bodyErrors.length) throw ValidationFailed.from(bodyErrors);`;
214
- let enableParseBody = false;
215
- const hasParameters = parsedRoute.getParameters().length > 0;
216
- let requiresAsyncParameters = false;
217
- let setParametersFromPath = '';
218
- params: for (const parameter of parsedRoute.getParameters()) {
219
- if (parameter.isPartOfPath()) {
220
- const converted = parameter.property.type === 'any' ? (v) => v : getPropertyXtoClassFunction(parameter.property, jsonSerializer);
221
- const validator = parameter.property.type === 'any' ? (v) => undefined : jitValidateProperty(parameter.property);
222
- const converterVar = compiler.reserveVariable('argumentConverter', converted);
223
- const validatorVar = compiler.reserveVariable('argumentValidator', validator);
224
- setParameters.push(`parameters.${parameter.property.name} = ${converterVar}(_match[${1 + (parameter.regexPosition || 0)}]);`);
225
- parameterValidator.push(`${validatorVar}(_match[1 + ${parameter.regexPosition}], ${JSON.stringify(parameter.getName())}, validationErrors);`);
226
- parameterNames.push(`parameters.${parameter.property.name}`);
227
- }
228
- else {
229
- if (parsedRoute.customValidationErrorHandling === parameter) {
230
- compiler.context.set('BodyValidation', BodyValidation);
231
- bodyValidationErrorHandling = '';
232
- setParameters.push(`parameters.${parameter.property.name} = new BodyValidation(bodyErrors);`);
233
- parameterNames.push(`parameters.${parameter.property.name}`);
234
- }
235
- else if (parameter.body) {
236
- const bodyVar = compiler.reserveVariable('body');
237
- const validatorVar = compiler.reserveVariable('argumentValidator', jitValidateProperty(parameter.property));
238
- const converterVar = compiler.reserveVariable('argumentConverter', getPropertyXtoClassFunction(parameter.property, jsonSerializer));
239
- enableParseBody = true;
240
- parameterValidator.push(`
241
- ${bodyVar} = ${converterVar}(bodyFields);
242
- ${validatorVar}(${bodyVar}, ${JSON.stringify(parameter.typePath || '')}, bodyErrors);
243
- `);
244
- setParameters.push(`parameters.${parameter.property.name} = ${bodyVar};`);
245
- parameterNames.push(`parameters.${parameter.property.name}`);
246
- }
247
- else if (parameter.query) {
248
- const converted = parameter.property.type === 'any' ? (v) => v : getPropertyXtoClassFunction(parameter.property, jsonSerializer);
249
- const validator = parameter.property.type === 'any' ? (v) => undefined : jitValidateProperty(parameter.property);
250
- const converterVar = compiler.reserveVariable('argumentConverter', converted);
251
- const validatorVar = compiler.reserveVariable('argumentValidator', validator);
252
- const queryPath = parameter.typePath === undefined ? parameter.property.name : parameter.typePath;
253
- const accessor = queryPath ? `['` + (queryPath.replace(/\./g, `']['`)) + `']` : '';
254
- const queryAccessor = queryPath ? `_query${accessor}` : '_query';
255
- setParameters.push(`parameters.${parameter.property.name} = ${converterVar}(${queryAccessor});`);
256
- parameterNames.push(`parameters.${parameter.property.name}`);
257
- parameterValidator.push(`${validatorVar}(${queryAccessor}, ${JSON.stringify(parameter.typePath)}, validationErrors);`);
258
- }
259
- else {
260
- const classType = parameter.property.getResolvedClassType();
261
- const classTypeVar = compiler.reserveVariable('classType', classType);
262
- for (const resolverTag of this.parameterResolverTags) {
263
- if (resolverTag.classTypes.includes(classType)) {
264
- const resolverProvideTokenVar = compiler.reserveVariable('resolverProvideToken', resolverTag.provider.provide);
265
- requiresAsyncParameters = true;
266
- if (!setParametersFromPath) {
267
- for (const i in parsedRoute.pathParameterNames) {
268
- setParametersFromPath += `parameters.${i} = _match[${1 + parsedRoute.pathParameterNames[i]}];`;
269
- }
270
- }
271
- setParameters.push(`parameters.${parameter.property.name} = await _injector.get(${resolverProvideTokenVar}).resolve(
272
- {classType: ${classTypeVar}, routeConfig: ${routeConfigVar}, request: request, query: _query, parameters: parameters}
273
- );`);
274
- parameterNames.push(`parameters.${parameter.property.name}`);
275
- continue params;
276
- }
277
- }
278
- setParameters.push(`parameters.${parameter.property.name} = _injector.get(${classTypeVar});`);
279
- parameterNames.push(`parameters.${parameter.property.name}`);
280
- }
281
- }
282
- }
283
- let parseBodyLoading = '';
284
- if (enableParseBody) {
285
- const parseBodyVar = compiler.reserveVariable('parseBody', parseBody);
286
- const formVar = compiler.reserveVariable('form', this.form);
287
- parseBodyLoading = `const bodyFields = (await ${parseBodyVar}(${formVar}, request)).fields;`;
288
- requiresAsyncParameters = true;
289
- }
469
+ const hasParameters = pathParamStarter !== -1 || parsedRoute.getParameters().length > 0;
470
+ const fullPath = routeConfig.getFullPath();
471
+ const middlewareConfigs = filterMiddlewaresForRoute(this.middlewareRegistry.configs, routeConfig, fullPath);
472
+ const parameters = [...parsedRoute.getParameters()];
473
+ //look through all http listeners and check if they need any http parameters.
474
+ //the router then parses
290
475
  let matcher = `_path.startsWith(${JSON.stringify(prefix)}) && (_match = _path.match(${regexVar}))`;
291
476
  if (!hasParameters) {
292
477
  matcher = `_path === ${JSON.stringify(path)}`;
293
478
  }
294
- let parameters = '() => []';
295
- if (setParameters.length) {
296
- parameters = `${requiresAsyncParameters ? 'async' : ''} function(_injector){
297
- const validationErrors = [];
298
- const bodyErrors = [];
299
- const parameters = {};
300
- ${setParametersFromPath}
301
- ${parseBodyLoading}
302
- ${parameterValidator.join('\n')}
303
- ${bodyValidationErrorHandling}
304
- ${setParameters.join('\n')}
305
- if (validationErrors.length) throw ValidationFailed.from(validationErrors);
306
- return [${parameterNames.join(',')}];
307
- }`;
479
+ let middlewares = 'undefined';
480
+ if (middlewareConfigs.length) {
481
+ const middlewareItems = [];
482
+ for (const middlewareConfig of middlewareConfigs) {
483
+ const moduleVar = middlewareConfig.module ? ', ' + compiler.reserveVariable('module', middlewareConfig.module) : '';
484
+ for (const middleware of middlewareConfig.config.middlewares) {
485
+ if (isClass(middleware)) {
486
+ const classVar = compiler.reserveVariable('middlewareClassType', middleware);
487
+ middlewareItems.push(`{fn: function() {return _injector.get(${classVar}${moduleVar}).execute(...arguments) }, timeout: ${middlewareConfig.config.timeout}}`);
488
+ }
489
+ else {
490
+ middlewareItems.push(`{fn: ${compiler.reserveVariable('middlewareFn', middleware)}, timeout: ${middlewareConfig.config.timeout}}`);
491
+ }
492
+ }
493
+ }
494
+ middlewares = `
495
+ function(_injector) {
496
+ return [${middlewareItems.join(', ')}];
497
+ }
498
+ `;
308
499
  }
500
+ const parametersLoader = getRequestParserCodeForParameters(compiler, this.config.parser, parameters, {
501
+ module: routeConfig.module,
502
+ resolverForToken: routeConfig.resolverForToken,
503
+ resolverForParameterName: routeConfig.resolverForParameterName,
504
+ pathParameterNames: parsedRoute.pathParameterNames,
505
+ routeConfig
506
+ });
507
+ let methodCheck = '';
508
+ if (routeConfig.httpMethods.length) {
509
+ methodCheck = '(' + routeConfig.httpMethods.map(__assignType(v => {
510
+ return `_method === '${v.toUpperCase()}'`;
511
+ }, ['v', '', 'P"2!"/"'])).join(' || ') + ') && ';
512
+ }
513
+ const routeConfigVar = compiler.reserveVariable('routeConfigVar', routeConfig);
309
514
  return `
310
- //=> ${path}
311
- if (_method === '${routeConfig.httpMethod.toLowerCase()}' && ${matcher}) {
312
- return {routeConfig: ${routeConfigVar}, parameters: ${parameters}};
515
+ //=> ${routeConfig.httpMethods.join(',')} ${path}
516
+ if (${methodCheck}${matcher}) {
517
+ return {routeConfig: ${routeConfigVar}, parameters: ${parametersLoader}, uploadedFiles: uploadedFiles, middlewares: ${middlewares}};
313
518
  }
314
519
  `;
315
520
  }
316
521
  getRouteUrlResolveCode(compiler, routeConfig) {
317
522
  const parsedRoute = parseRouteControllerAction(routeConfig);
318
523
  let url = routeConfig.getFullPath();
319
- url = url.replace(/:(\w+)/g, (a, name) => {
524
+ url = url.replace(/:(\w+)/g, __assignType((a, name) => {
320
525
  return `\${parameters.${name}}`;
321
- });
526
+ }, ['a', 'name', '', 'P"2!"2""/#']));
322
527
  const modify = [];
323
528
  for (const parameter of parsedRoute.getParameters()) {
324
- if (parameter.query) {
325
- const queryPath = parameter.typePath === undefined ? parameter.property.name : parameter.typePath;
326
- if (parameter.property.type === 'class') {
327
- for (const property of parameter.property.getResolvedClassSchema().getProperties()) {
529
+ if (parameter.query || parameter.queries) {
530
+ const queryPath = parameter.typePath === undefined && parameter.query ? parameter.parameter.name : parameter.typePath || '';
531
+ if (parameter.parameter.type.kind === ReflectionKind.class || parameter.parameter.type.kind === ReflectionKind.objectLiteral) {
532
+ for (const property of ReflectionClass.from(parameter.parameter.type).getProperties()) {
328
533
  const accessor = `parameters.${parameter.getName()}?.${property.name}`;
329
534
  const thisPath = queryPath ? queryPath + '.' + property.name : property.name;
330
535
  modify.push(`${accessor} !== undefined && query.push(${JSON.stringify(dotToUrlPath(thisPath))} + '=' + encodeURIComponent(${accessor}))`);
@@ -345,51 +550,36 @@ let Router = class Router {
345
550
  `;
346
551
  }
347
552
  addRoute(routeConfig) {
348
- this.routes.push(routeConfig);
349
- this.fn = undefined;
553
+ this.registry.addRoute(routeConfig);
350
554
  }
351
- addRouteForController(controller) {
352
- const data = httpClass._fetch(controller);
353
- if (!data)
354
- return;
355
- for (const action of data.getActions()) {
356
- const routeConfig = new RouteConfig(action.name, action.httpMethod, action.path, {
357
- controller,
358
- methodName: action.methodName
359
- });
360
- routeConfig.parameterRegularExpressions = action.parameterRegularExpressions;
361
- routeConfig.throws = action.throws;
362
- routeConfig.description = action.description;
363
- routeConfig.category = action.category;
364
- routeConfig.groups = action.groups;
365
- routeConfig.data = new Map(action.data);
366
- routeConfig.baseUrl = data.baseUrl;
367
- routeConfig.parameters = { ...action.parameters };
368
- this.addRoute(routeConfig);
369
- }
555
+ addRouteForController(controller, module) {
556
+ this.registry.addRouteForController(controller, module);
370
557
  }
371
558
  build() {
559
+ this.buildId = this.registry.getBuildId();
372
560
  const compiler = new CompilerContext;
373
- compiler.context.set('_match', null);
374
- compiler.context.set('ValidationFailed', ValidationFailed);
375
- compiler.context.set('parseQueryString', querystring.parse);
561
+ compiler.context.set('ValidationError', ValidationError);
562
+ compiler.context.set('qs', qs);
376
563
  const code = [];
377
- for (const route of this.routes) {
564
+ for (const route of this.getRoutes()) {
378
565
  code.push(this.getRouteCode(compiler, route));
379
566
  }
380
567
  return compiler.build(`
381
- const _method = request.getMethod().toLowerCase();
382
- const _url = request.getUrl();
568
+ let _match;
569
+ const _method = request.method || 'GET';
570
+ const _url = request.url || '/';
571
+ const _headers = request.headers || {};
383
572
  const _qPosition = _url.indexOf('?');
573
+ let uploadedFiles = {};
384
574
  const _path = _qPosition === -1 ? _url : _url.substr(0, _qPosition);
385
- const _query = _qPosition === -1 ? {} : parseQueryString(_url.substr(_qPosition + 1));
575
+ const _query = _qPosition === -1 ? {} : qs.parse(_url.substr(_qPosition + 1));
386
576
  ${code.join('\n')}
387
577
  `, 'request');
388
578
  }
389
579
  buildUrlResolver() {
390
580
  const compiler = new CompilerContext;
391
581
  const code = [];
392
- for (const route of this.routes) {
582
+ for (const route of this.getRoutes()) {
393
583
  code.push(this.getRouteUrlResolveCode(compiler, route));
394
584
  }
395
585
  return compiler.build(`
@@ -406,27 +596,15 @@ let Router = class Router {
406
596
  return this.resolveFn(routeName, parameters);
407
597
  }
408
598
  resolveRequest(request) {
409
- if (!this.fn) {
599
+ if (!this.fn || this.buildId !== this.registry.getBuildId()) {
410
600
  this.fn = this.build();
411
601
  }
412
602
  return this.fn(request);
413
603
  }
414
604
  resolve(method, url) {
415
- return this.resolveRequest({
416
- getUrl() {
417
- return url;
418
- },
419
- getMethod() {
420
- return method;
421
- },
422
- });
605
+ method = method.toUpperCase();
606
+ return this.resolveRequest({ url, method });
423
607
  }
424
- };
425
- Router = __decorate([
426
- injectable(),
427
- __metadata("design:paramtypes", [HttpControllers,
428
- Logger,
429
- TagProviders])
430
- ], Router);
431
- export { Router };
608
+ }
609
+ HttpRouter.__type = [() => HttpRequest, 'request', () => __ΩResolvedController, '', 'fn', 'buildId', function () { return 0; }, 'name', 'parameters', 'resolveFn', () => HttpControllers, 'controllers', () => __ΩLoggerInterface, 'logger', () => HttpConfig, 'config', () => MiddlewareRegistry, 'middlewareRegistry', () => new MiddlewareRegistry, () => HttpRouterRegistry, 'registry', () => new HttpRouterRegistry, 'constructor', () => RouteConfig, 'getRoutes', () => __ΩClassType, () => InjectorModule, 'module', () => __ΩClassType, 'controller', () => MiddlewareRegistry, () => new MiddlewareRegistry(), () => InjectorModule, () => new InjectorModule(), () => HttpConfig, () => new HttpConfig(), () => HttpRouter, 'forControllers', () => CompilerContext, 'compiler', () => RouteConfig, 'routeConfig', 'getRouteCode', () => CompilerContext, () => RouteConfig, 'getRouteUrlResolveCode', () => RouteConfig, 'addRoute', () => __ΩClassType, () => InjectorModule, 'addRouteForController', () => HttpRequest, () => __ΩResolvedController, 'build', 'buildUrlResolver', 'routeName', () => ({}), 'resolveUrl', () => HttpRequest, () => __ΩResolvedController, 'resolveRequest', 'method', 'url', () => __ΩResolvedController, 'resolve', 'HttpRouter', 'PP7!2"Pn#-J/$3%8<\'3&<>\'P&2(P&"LM2)&/$3*8<PP7+2,n-2.;P7/20;P7122;>3P7425;>6"07PP78F09PPn:PP"7;4<n=4>MJF2,P7?22>@P"7A2<>BP7C20>DP7E0FsPP7G2HP7I2J&0K<PP7L2HP7M2J&0N<PP7O2J"0PPnQ2>P"7R2<"0SPPP7T2"PnU-J/$0V<P"0W<P&2XP&"LM2)>Y&0ZPP7[2"Pn\\-J0]P&2^&2_Pn`-J0a5wb'];
432
610
  //# sourceMappingURL=router.js.map