@deepkit/http 1.0.1-alpha.16 → 1.0.1-alpha.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +236 -0
- package/dist/cjs/index.d.ts +14 -10
- package/dist/cjs/index.js +19 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/controllers.d.ts +10 -3
- package/dist/cjs/src/controllers.js +7 -3
- package/dist/cjs/src/controllers.js.map +1 -1
- package/dist/cjs/src/decorator.d.ts +144 -70
- package/dist/cjs/src/decorator.js +277 -102
- package/dist/cjs/src/decorator.js.map +1 -1
- package/dist/cjs/src/filter.d.ts +49 -0
- package/dist/cjs/src/filter.js +215 -0
- package/dist/cjs/src/filter.js.map +1 -0
- package/dist/cjs/src/http-app.d.ts +8 -0
- package/dist/cjs/src/http-app.js +16 -0
- package/dist/cjs/src/http-app.js.map +1 -0
- package/dist/cjs/src/http.d.ts +131 -32
- package/dist/cjs/src/http.js +523 -122
- package/dist/cjs/src/http.js.map +1 -1
- package/dist/cjs/src/kernel.d.ts +50 -9
- package/dist/cjs/src/kernel.js +109 -98
- package/dist/cjs/src/kernel.js.map +1 -1
- package/dist/cjs/src/logger.d.ts +3 -3
- package/dist/cjs/src/logger.js +9 -12
- package/dist/cjs/src/logger.js.map +1 -1
- package/dist/cjs/src/middleware.d.ts +61 -0
- package/dist/cjs/src/middleware.js +95 -0
- package/dist/cjs/src/middleware.js.map +1 -0
- package/dist/cjs/src/model.d.ts +270 -4
- package/dist/cjs/src/model.js +401 -3
- package/dist/cjs/src/model.js.map +1 -1
- package/dist/cjs/src/module.config.d.ts +149 -4
- package/dist/cjs/src/module.config.js +11 -6
- package/dist/cjs/src/module.config.js.map +1 -1
- package/dist/cjs/src/module.d.ts +14 -32
- package/dist/cjs/src/module.js +122 -7
- package/dist/cjs/src/module.js.map +1 -1
- package/dist/cjs/src/request-parser.d.ts +37 -0
- package/dist/cjs/src/request-parser.js +382 -0
- package/dist/cjs/src/request-parser.js.map +1 -0
- package/dist/cjs/src/router.d.ts +174 -75
- package/dist/cjs/src/router.js +469 -288
- package/dist/cjs/src/router.js.map +1 -1
- package/dist/cjs/src/static-serving.d.ts +32 -4
- package/dist/cjs/src/static-serving.js +115 -71
- package/dist/cjs/src/static-serving.js.map +1 -1
- package/dist/cjs/src/utils.js +2 -2
- package/dist/cjs/src/utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -2916
- package/dist/esm/index.d.ts +14 -10
- package/dist/esm/index.js +14 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/src/controllers.d.ts +10 -3
- package/dist/esm/src/controllers.js +7 -3
- package/dist/esm/src/controllers.js.map +1 -1
- package/dist/esm/src/decorator.d.ts +144 -70
- package/dist/esm/src/decorator.js +272 -99
- package/dist/esm/src/decorator.js.map +1 -1
- package/dist/esm/src/filter.d.ts +49 -0
- package/dist/esm/src/filter.js +209 -0
- package/dist/esm/src/filter.js.map +1 -0
- package/dist/esm/src/http-app.d.ts +8 -0
- package/dist/esm/src/http-app.js +12 -0
- package/dist/esm/src/http-app.js.map +1 -0
- package/dist/esm/src/http.d.ts +131 -32
- package/dist/esm/src/http.js +504 -121
- package/dist/esm/src/http.js.map +1 -1
- package/dist/esm/src/kernel.d.ts +50 -9
- package/dist/esm/src/kernel.js +110 -100
- package/dist/esm/src/kernel.js.map +1 -1
- package/dist/esm/src/logger.d.ts +3 -3
- package/dist/esm/src/logger.js +7 -11
- package/dist/esm/src/logger.js.map +1 -1
- package/dist/esm/src/middleware.d.ts +61 -0
- package/dist/esm/src/middleware.js +90 -0
- package/dist/esm/src/middleware.js.map +1 -0
- package/dist/esm/src/model.d.ts +270 -4
- package/dist/esm/src/model.js +357 -1
- package/dist/esm/src/model.js.map +1 -1
- package/dist/esm/src/module.config.d.ts +149 -4
- package/dist/esm/src/module.config.js +9 -5
- package/dist/esm/src/module.config.js.map +1 -1
- package/dist/esm/src/module.d.ts +14 -32
- package/dist/esm/src/module.js +121 -7
- package/dist/esm/src/module.js.map +1 -1
- package/dist/esm/src/request-parser.d.ts +37 -0
- package/dist/esm/src/request-parser.js +372 -0
- package/dist/esm/src/request-parser.js.map +1 -0
- package/dist/esm/src/router.d.ts +174 -75
- package/dist/esm/src/router.js +463 -285
- package/dist/esm/src/router.js.map +1 -1
- package/dist/esm/src/static-serving.d.ts +32 -4
- package/dist/esm/src/static-serving.js +107 -65
- package/dist/esm/src/static-serving.js.map +1 -1
- package/dist/esm/src/utils.js +1 -0
- package/dist/esm/src/utils.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -2916
- package/index.ts +14 -10
- package/package.json +30 -19
- package/src/controllers.ts +4 -3
- package/src/decorator.ts +242 -104
- package/src/filter.ts +224 -0
- package/src/http-app.ts +11 -0
- package/src/http.ts +501 -100
- package/src/kernel.ts +128 -80
- package/src/logger.ts +4 -6
- package/src/middleware.ts +116 -0
- package/src/model.ts +516 -5
- package/src/module.config.ts +168 -5
- package/src/module.ts +120 -7
- package/src/request-parser.ts +430 -0
- package/src/router.ts +546 -317
- package/src/static-serving.ts +120 -50
- package/src/utils.ts +0 -2
- package/tsconfig.esm.json +7 -7
- package/tsconfig.json +18 -11
- package/tsconfig.spec.json +8 -0
- package/dist/cjs/tests/router.spec.d.ts +0 -1
- package/dist/cjs/tests/router.spec.js +0 -481
- package/dist/cjs/tests/router.spec.js.map +0 -1
- package/dist/esm/tests/router.spec.d.ts +0 -1
- package/dist/esm/tests/router.spec.js +0 -479
- package/dist/esm/tests/router.spec.js.map +0 -1
- package/tests/router.spec.ts +0 -347
package/dist/esm/src/router.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 {
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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,
|
|
80
|
+
constructor(name, httpMethods, path, action, internal = false) {
|
|
44
81
|
this.name = name;
|
|
45
|
-
this.
|
|
82
|
+
this.httpMethods = httpMethods;
|
|
46
83
|
this.path = path;
|
|
47
84
|
this.action = action;
|
|
85
|
+
this.internal = internal;
|
|
48
86
|
this.baseUrl = '';
|
|
49
|
-
this.
|
|
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
|
-
|
|
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 ?
|
|
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
|
-
|
|
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
|
|
99
|
-
const parameter = new
|
|
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
|
-
|
|
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
|
|
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
|
|
154
|
-
const
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
202
|
-
|
|
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
|
|
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
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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 (
|
|
312
|
-
return {routeConfig: ${routeConfigVar}, 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.
|
|
326
|
-
if (parameter.
|
|
327
|
-
for (const property of parameter.
|
|
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.
|
|
349
|
-
this.fn = undefined;
|
|
553
|
+
this.registry.addRoute(routeConfig);
|
|
350
554
|
}
|
|
351
|
-
addRouteForController(controller) {
|
|
352
|
-
|
|
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('
|
|
374
|
-
compiler.context.set('
|
|
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.
|
|
564
|
+
for (const route of this.getRoutes()) {
|
|
378
565
|
code.push(this.getRouteCode(compiler, route));
|
|
379
566
|
}
|
|
380
567
|
return compiler.build(`
|
|
381
|
-
|
|
382
|
-
const
|
|
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 ? {} :
|
|
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.
|
|
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
|
-
|
|
416
|
-
|
|
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
|
-
|
|
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
|