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