quantum-flow 1.3.10 → 1.5.0
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/README.md +22 -15
- package/dist/app/aws/lambda.d.ts +0 -3
- package/dist/app/aws/lambda.js +25 -112
- package/dist/app/aws/utils/helpers.d.ts +4 -0
- package/dist/app/aws/utils/helpers.js +83 -0
- package/dist/app/aws/utils/index.d.ts +3 -0
- package/dist/app/aws/utils/index.js +19 -0
- package/dist/app/aws/utils/request.d.ts +23 -0
- package/dist/app/aws/utils/request.js +96 -0
- package/dist/app/aws/utils/response.d.ts +14 -0
- package/dist/app/aws/utils/response.js +37 -0
- package/dist/app/http/Application.d.ts +1 -1
- package/dist/app/http/Application.js +36 -21
- package/dist/app/http/decorators.js +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/core/Controller.d.ts +6 -25
- package/dist/core/Controller.js +84 -118
- package/dist/core/Endpoint.js +1 -2
- package/dist/core/index.d.ts +1 -1
- package/dist/core/utils/index.d.ts +0 -2
- package/dist/core/utils/index.js +0 -2
- package/dist/examples/app.d.ts +0 -1
- package/dist/examples/app.js +70 -5
- package/dist/examples/controllers/user.js +44 -8
- package/dist/examples/controllers/userMetadata.d.ts +1 -1
- package/dist/examples/controllers/userMetadata.js +59 -9
- package/dist/middlewares/catch.d.ts +2 -0
- package/dist/middlewares/catch.js +10 -0
- package/dist/middlewares/cors.d.ts +2 -0
- package/dist/middlewares/cors.js +21 -0
- package/dist/middlewares/index.d.ts +5 -0
- package/dist/middlewares/index.js +21 -0
- package/dist/middlewares/sanitize.d.ts +2 -0
- package/dist/middlewares/sanitize.js +15 -0
- package/dist/{core/utils/helpers.js → middlewares/status.js} +1 -1
- package/dist/middlewares/use.d.ts +2 -0
- package/dist/middlewares/use.js +11 -0
- package/dist/types/common.d.ts +15 -32
- package/dist/types/controller.d.ts +7 -5
- package/dist/types/cors.d.ts +10 -0
- package/dist/types/cors.js +2 -0
- package/dist/types/http.d.ts +4 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +3 -0
- package/dist/types/lambda.d.ts +7 -17
- package/dist/types/multipart.d.ts +8 -0
- package/dist/types/multipart.js +2 -0
- package/dist/types/sanitize.d.ts +8 -0
- package/dist/types/sanitize.js +2 -0
- package/dist/utils/controller.d.ts +27 -3
- package/dist/utils/controller.js +122 -23
- package/dist/utils/cors.d.ts +8 -0
- package/dist/utils/cors.js +127 -0
- package/dist/utils/headers.d.ts +2 -0
- package/dist/utils/headers.js +9 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/multipart.d.ts +2 -8
- package/dist/utils/multipart.js +98 -2
- package/dist/utils/sanitize.d.ts +30 -0
- package/dist/utils/sanitize.js +134 -0
- package/dist/utils/server.js +5 -0
- package/package.json +9 -2
- package/dist/core/utils/middlewares.d.ts +0 -3
- package/dist/core/utils/middlewares.js +0 -22
- /package/dist/{core/utils/helpers.d.ts → middlewares/status.d.ts} +0 -0
|
@@ -85,7 +85,6 @@ class HttpServer extends Socket_1.Socket {
|
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
87
|
this.isRunning = false;
|
|
88
|
-
console.log(_constants_1.STOPPED);
|
|
89
88
|
resolve();
|
|
90
89
|
}
|
|
91
90
|
});
|
|
@@ -97,23 +96,39 @@ class HttpServer extends Socket_1.Socket {
|
|
|
97
96
|
config: this.config,
|
|
98
97
|
};
|
|
99
98
|
}
|
|
100
|
-
async requestHandler(req,
|
|
99
|
+
async requestHandler(req, response) {
|
|
101
100
|
const startTime = Date.now();
|
|
101
|
+
let request;
|
|
102
102
|
try {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
request = await this.createRequest(req);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
return this.sendResponse(response, { status: 500, message: err.message }, startTime);
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
let handledCors = { permitted: true, continue: true };
|
|
110
|
+
if (this.config.cors) {
|
|
111
|
+
handledCors = (0, _utils_1.handleCORS)(request, response, this.config.cors);
|
|
112
|
+
}
|
|
113
|
+
if (!handledCors.permitted) {
|
|
114
|
+
return this.sendResponse(response, { status: 403, message: 'CORS: Origin not allowed' }, startTime);
|
|
115
|
+
}
|
|
116
|
+
if (!handledCors.continue && handledCors.permitted) {
|
|
117
|
+
return this.sendResponse(response, { status: 204 }, startTime);
|
|
118
|
+
}
|
|
119
|
+
await this.beforeRequest(request, response);
|
|
120
|
+
let data = await this.findController(request, response);
|
|
106
121
|
const isError = !_constants_1.OK_STATUSES.includes(data.status);
|
|
107
122
|
if (isError) {
|
|
108
|
-
return this.handleError(data,
|
|
123
|
+
return this.handleError(data, request, response, startTime);
|
|
109
124
|
}
|
|
110
125
|
if (this.config.interceptor) {
|
|
111
|
-
data = await this.config.interceptor(data,
|
|
126
|
+
data = await this.config.interceptor(data, request, response);
|
|
112
127
|
}
|
|
113
|
-
return this.sendResponse(
|
|
128
|
+
return this.sendResponse(response, data, startTime);
|
|
114
129
|
}
|
|
115
130
|
catch (error) {
|
|
116
|
-
return this.handleError(error,
|
|
131
|
+
return this.handleError(error, request, response, startTime);
|
|
117
132
|
}
|
|
118
133
|
}
|
|
119
134
|
async createRequest(req) {
|
|
@@ -127,33 +142,33 @@ class HttpServer extends Socket_1.Socket {
|
|
|
127
142
|
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
|
128
143
|
const host = req.headers.host || 'localhost';
|
|
129
144
|
const fullUrl = `${protocol}://${host}${req.url}`;
|
|
130
|
-
const
|
|
131
|
-
|
|
145
|
+
const requestUrl = new URL(fullUrl);
|
|
146
|
+
const parsedRequest = {
|
|
132
147
|
method: req.method?.toUpperCase(),
|
|
133
|
-
|
|
148
|
+
requestUrl,
|
|
134
149
|
headers: req.headers,
|
|
135
150
|
body: parsedBody,
|
|
136
151
|
rawBody: rawBody,
|
|
137
|
-
query: (0, _utils_1.ParseQuery)(
|
|
152
|
+
query: (0, _utils_1.ParseQuery)(requestUrl),
|
|
138
153
|
params: {},
|
|
139
154
|
cookies: (0, _utils_1.ParseCookies)(req),
|
|
140
155
|
isBase64Encoded: false,
|
|
141
156
|
_startTime: Date.now(),
|
|
142
157
|
};
|
|
158
|
+
Object.assign(req, parsedRequest);
|
|
159
|
+
return req;
|
|
143
160
|
}
|
|
144
|
-
async
|
|
145
|
-
|
|
161
|
+
async beforeRequest(request, response) {
|
|
162
|
+
(0, _utils_1.sanitizeRequest)(request, this.config.sanitizers ?? []);
|
|
146
163
|
for (const middleware of this.config.middlewares?.reverse() || []) {
|
|
147
|
-
|
|
148
|
-
processed = result ?? processed;
|
|
164
|
+
await middleware(request, response, _utils_1.NextFN);
|
|
149
165
|
}
|
|
150
|
-
return processed;
|
|
151
166
|
}
|
|
152
|
-
async findController(
|
|
167
|
+
async findController(request, response) {
|
|
153
168
|
for (const ControllerClass of this.config.controllers || []) {
|
|
154
169
|
const instance = new ControllerClass();
|
|
155
170
|
if (typeof instance.handleRequest === 'function') {
|
|
156
|
-
const data = await instance.handleRequest(
|
|
171
|
+
const data = await instance.handleRequest(request, response);
|
|
157
172
|
if (data && data.status !== 404) {
|
|
158
173
|
return data;
|
|
159
174
|
}
|
|
@@ -161,7 +176,7 @@ class HttpServer extends Socket_1.Socket {
|
|
|
161
176
|
}
|
|
162
177
|
return {
|
|
163
178
|
status: 404,
|
|
164
|
-
data: { message: `Route ${
|
|
179
|
+
data: { message: `Route ${request.method} ${request.requestUrl.pathname} not found` },
|
|
165
180
|
};
|
|
166
181
|
}
|
|
167
182
|
async sendResponse(res, data, startTime) {
|
|
@@ -12,6 +12,7 @@ function Server(config = {}) {
|
|
|
12
12
|
...config,
|
|
13
13
|
controllers: [...(existingConfig.controllers || []), ...(config.controllers || [])],
|
|
14
14
|
middlewares: [...(existingConfig.middlewares ?? []), ...(config.middlewares ?? [])],
|
|
15
|
+
cors: config.cors,
|
|
15
16
|
interceptors: existingConfig.interceptor ?? config.interceptor,
|
|
16
17
|
};
|
|
17
18
|
Reflect.defineMetadata(_constants_1.SERVER_CONFIG_KEY, mergedConfig, target);
|
package/dist/constants.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export declare const WS_TOPIC_KEY = "websocket:topic";
|
|
|
15
15
|
export declare const WS_SERVICE_KEY = "websocket:service";
|
|
16
16
|
export declare const INTECEPT = "server:intercept";
|
|
17
17
|
export declare const CATCH = "server:catch";
|
|
18
|
+
export declare const SANITIZE = "action:sanitize";
|
|
18
19
|
export declare const STOPPED = "\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\u2551 \uD83D\uDC4B Server stopped \u2551\n\u2551 \uD83D\uDCCA Status: STOPPED \u2551\n\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n ";
|
|
19
20
|
export declare const OK_STATUSES: number[];
|
|
20
21
|
export declare const TO_VALIDATE: string[];
|
|
21
22
|
export declare const STATISTIC: Record<'controllers' | 'routes', number>;
|
|
22
23
|
export declare const INCREMENT_STATISTIC: (prop: "controllers" | "routes") => void;
|
|
24
|
+
export declare const CORS_METADATA = "cors:config";
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.INCREMENT_STATISTIC = exports.STATISTIC = exports.TO_VALIDATE = exports.OK_STATUSES = exports.STOPPED = exports.CATCH = exports.INTECEPT = exports.WS_SERVICE_KEY = exports.WS_TOPIC_KEY = exports.WS_METADATA_KEY = exports.USE_MIDDLEWARE = exports.SERVER_MODULES_KEY = exports.SERVER_CONFIG_KEY = exports.OK_METADATA_KEY = exports.ENDPOINT = exports.INTERCEPTOR = exports.CONTROLLERS = exports.MIDDLEWARES = exports.ROUTE_MIDDLEWARES = exports.ROUTE_PREFIX = exports.APP_METADATA_KEY = exports.PARAM_METADATA_KEY = void 0;
|
|
3
|
+
exports.CORS_METADATA = exports.INCREMENT_STATISTIC = exports.STATISTIC = exports.TO_VALIDATE = exports.OK_STATUSES = exports.STOPPED = exports.SANITIZE = exports.CATCH = exports.INTECEPT = exports.WS_SERVICE_KEY = exports.WS_TOPIC_KEY = exports.WS_METADATA_KEY = exports.USE_MIDDLEWARE = exports.SERVER_MODULES_KEY = exports.SERVER_CONFIG_KEY = exports.OK_METADATA_KEY = exports.ENDPOINT = exports.INTERCEPTOR = exports.CONTROLLERS = exports.MIDDLEWARES = exports.ROUTE_MIDDLEWARES = exports.ROUTE_PREFIX = exports.APP_METADATA_KEY = exports.PARAM_METADATA_KEY = void 0;
|
|
4
4
|
exports.PARAM_METADATA_KEY = 'design:parameters';
|
|
5
5
|
exports.APP_METADATA_KEY = 'app:configuration';
|
|
6
6
|
exports.ROUTE_PREFIX = 'route:prefix';
|
|
@@ -18,6 +18,7 @@ exports.WS_TOPIC_KEY = 'websocket:topic';
|
|
|
18
18
|
exports.WS_SERVICE_KEY = 'websocket:service';
|
|
19
19
|
exports.INTECEPT = 'server:intercept';
|
|
20
20
|
exports.CATCH = 'server:catch';
|
|
21
|
+
exports.SANITIZE = 'action:sanitize';
|
|
21
22
|
exports.STOPPED = `
|
|
22
23
|
╔════════════════════════════════════════╗
|
|
23
24
|
║ 👋 Server stopped ║
|
|
@@ -34,3 +35,4 @@ const INCREMENT_STATISTIC = (prop) => {
|
|
|
34
35
|
exports.STATISTIC[prop] = exports.STATISTIC[prop] + 1;
|
|
35
36
|
};
|
|
36
37
|
exports.INCREMENT_STATISTIC = INCREMENT_STATISTIC;
|
|
38
|
+
exports.CORS_METADATA = 'cors:config';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AppRequest, ControllerClass, ControllerConfig,
|
|
2
|
-
import {
|
|
1
|
+
import { AppRequest, ControllerClass, ControllerConfig, InterceptorCB, RouteContext } from '../types/index.js';
|
|
2
|
+
import { ServerResponse } from 'http';
|
|
3
3
|
import 'reflect-metadata';
|
|
4
4
|
/**
|
|
5
5
|
* Class decorator to define a controller with optional configuration.
|
|
@@ -25,28 +25,9 @@ import 'reflect-metadata';
|
|
|
25
25
|
export declare function Controller(config: string | ControllerConfig, middlewares?: Array<InterceptorCB>): <T extends ControllerClass>(constructor: T) => {
|
|
26
26
|
new (...args: any[]): {
|
|
27
27
|
[x: string]: any;
|
|
28
|
-
executeControllerMethod: (controller: ControllerInstance, propertyName: string,
|
|
29
|
-
getControllerMethods: (controller: ControllerInstance) => import("../types/index.js").ControllerMethods;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
name: string;
|
|
33
|
-
payload: any;
|
|
34
|
-
interceptors: InterceptorCB[];
|
|
35
|
-
request?: IncomingMessage;
|
|
36
|
-
response?: ServerResponse;
|
|
37
|
-
}): Promise<{
|
|
38
|
-
status: any;
|
|
39
|
-
data: any;
|
|
40
|
-
}>;
|
|
41
|
-
handleRequest: (appRequest: AppRequest, request?: IncomingMessage, response?: ServerResponse) => Promise<any>;
|
|
42
|
-
routeWalker(context: RouteContext): Promise<any>;
|
|
43
|
-
getAllMethods(obj: any): string[];
|
|
44
|
-
findRouteInController(instance: any, path: string, route: string, method: string): {
|
|
45
|
-
name: string;
|
|
46
|
-
pathParams: Record<string, string>;
|
|
47
|
-
priority: number;
|
|
48
|
-
methodMiddlewares: MiddlewareCB[];
|
|
49
|
-
methodInterceptors: InterceptorCB[];
|
|
50
|
-
};
|
|
28
|
+
executeControllerMethod: (controller: import("../types/index.js").ControllerInstance, propertyName: string, request: AppRequest, response: ServerResponse) => Promise<any>;
|
|
29
|
+
getControllerMethods: (controller: import("../types/index.js").ControllerInstance) => import("../types/index.js").ControllerMethods;
|
|
30
|
+
handleRequest: (request: AppRequest, response: ServerResponse) => Promise<any>;
|
|
31
|
+
routeWalker(context: RouteContext, request: AppRequest, response: ServerResponse): Promise<any>;
|
|
51
32
|
};
|
|
52
33
|
} & T;
|
package/dist/core/Controller.js
CHANGED
|
@@ -69,170 +69,136 @@ function Controller(config, middlewares = []) {
|
|
|
69
69
|
constructor(...args) {
|
|
70
70
|
super(...args);
|
|
71
71
|
}
|
|
72
|
-
async
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const interceptors = data.interceptors.reverse();
|
|
78
|
-
for (let index = 0; index < interceptors?.length && !isError; index++) {
|
|
79
|
-
const interceptor = interceptors[index];
|
|
80
|
-
appResponse = await interceptor(appResponse, data.request, data.response);
|
|
81
|
-
}
|
|
82
|
-
const propertyName = data.name;
|
|
83
|
-
const prototype = Object.getPrototypeOf(data.controllerInstance);
|
|
84
|
-
const methodOkStatus = Reflect.getMetadata(_constants_1.OK_METADATA_KEY, data.controllerInstance, propertyName);
|
|
85
|
-
if (methodOkStatus) {
|
|
86
|
-
!isError && (status = methodOkStatus);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
const classOkStatus = Reflect.getMetadata(_constants_1.OK_METADATA_KEY, prototype);
|
|
90
|
-
!isError && classOkStatus && (status = classOkStatus);
|
|
91
|
-
}
|
|
92
|
-
return { status, data: appResponse };
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
throw err;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
handleRequest = async (appRequest, request, response) => {
|
|
72
|
+
handleRequest = async (request, response) => {
|
|
73
|
+
const middlewares = []
|
|
74
|
+
.concat(Reflect.getMetadata(_constants_1.MIDDLEWARES, proto))
|
|
75
|
+
.concat(Reflect.getMetadata(_constants_1.USE_MIDDLEWARE, constructor))
|
|
76
|
+
.filter((el) => !!el);
|
|
99
77
|
const context = {
|
|
100
78
|
controllerInstance: this,
|
|
101
79
|
controllerMeta: {
|
|
102
80
|
routePrefix: Reflect.getMetadata(_constants_1.ROUTE_PREFIX, proto) || '',
|
|
103
|
-
middlewares
|
|
81
|
+
middlewares,
|
|
104
82
|
interceptor: Reflect.getMetadata(_constants_1.INTERCEPTOR, proto),
|
|
105
83
|
subControllers: Reflect.getMetadata(_constants_1.CONTROLLERS, proto) || [],
|
|
106
|
-
errorHandler: Reflect.getMetadata(_constants_1.CATCH,
|
|
84
|
+
errorHandler: Reflect.getMetadata(_constants_1.CATCH, constructor),
|
|
85
|
+
cors: Reflect.getMetadata(_constants_1.CORS_METADATA, proto),
|
|
86
|
+
sanitizers: Reflect.getMetadata(_constants_1.SANITIZE, proto) || [],
|
|
107
87
|
},
|
|
108
|
-
path: (
|
|
109
|
-
method:
|
|
110
|
-
appRequest,
|
|
111
|
-
request,
|
|
112
|
-
response,
|
|
88
|
+
path: (request.requestUrl.pathname ?? '').replace(/^\/+/g, ''),
|
|
89
|
+
method: request.method.toUpperCase(),
|
|
113
90
|
middlewareChain: [],
|
|
114
91
|
interceptorChain: [],
|
|
92
|
+
sanitizersChain: [],
|
|
93
|
+
corsChain: [Reflect.getMetadata(_constants_1.CORS_METADATA, proto)],
|
|
115
94
|
errorHandlerChain: [Reflect.getMetadata(_constants_1.CATCH, proto)],
|
|
116
95
|
subPath: Reflect.getMetadata(_constants_1.ROUTE_PREFIX, proto) || '',
|
|
117
96
|
};
|
|
118
|
-
const result = await this.routeWalker(context);
|
|
97
|
+
const result = await this.routeWalker(context, request, response);
|
|
119
98
|
return result || { status: 404, message: 'Method Not Found' };
|
|
120
99
|
};
|
|
121
|
-
async routeWalker(context) {
|
|
100
|
+
async routeWalker(context, request, response) {
|
|
122
101
|
const { controllerInstance, controllerMeta, path, method, subPath } = context;
|
|
123
102
|
for (const SubController of controllerMeta.subControllers) {
|
|
124
103
|
const subInstance = new SubController();
|
|
104
|
+
const middlewares = []
|
|
105
|
+
.concat(Reflect.getMetadata(_constants_1.MIDDLEWARES, SubController.prototype))
|
|
106
|
+
.concat(Reflect.getMetadata(_constants_1.USE_MIDDLEWARE, SubController))
|
|
107
|
+
.filter((el) => !!el);
|
|
108
|
+
const sanitizers = []
|
|
109
|
+
.concat(Reflect.getMetadata(_constants_1.SANITIZE, SubController.prototype))
|
|
110
|
+
.concat(Reflect.getMetadata(_constants_1.SANITIZE, SubController))
|
|
111
|
+
.filter((el) => !!el);
|
|
125
112
|
const subMeta = {
|
|
126
113
|
routePrefix: Reflect.getMetadata(_constants_1.ROUTE_PREFIX, SubController.prototype) || '',
|
|
127
|
-
middlewares
|
|
114
|
+
middlewares,
|
|
128
115
|
interceptor: Reflect.getMetadata(_constants_1.INTERCEPTOR, SubController.prototype),
|
|
129
116
|
errorHandler: Reflect.getMetadata(_constants_1.CATCH, SubController),
|
|
130
117
|
subControllers: Reflect.getMetadata(_constants_1.CONTROLLERS, SubController.prototype) || [],
|
|
118
|
+
cors: Reflect.getMetadata(_constants_1.CORS_METADATA, SubController.prototype) || [],
|
|
119
|
+
sanitizers,
|
|
131
120
|
};
|
|
132
121
|
const fullSubPath = [subPath, subMeta.routePrefix]
|
|
133
122
|
.filter(Boolean)
|
|
134
123
|
.join('/')
|
|
135
124
|
.replace(/\/+/g, '/');
|
|
136
125
|
if (path.startsWith(fullSubPath)) {
|
|
137
|
-
const
|
|
126
|
+
const walkerData = {
|
|
138
127
|
...context,
|
|
139
128
|
subPath: fullSubPath,
|
|
140
129
|
controllerInstance: subInstance,
|
|
141
130
|
controllerMeta: subMeta,
|
|
142
131
|
path,
|
|
143
132
|
middlewareChain: [...context.middlewareChain, ...controllerMeta.middlewares],
|
|
133
|
+
sanitizersChain: [...context.sanitizersChain, ...controllerMeta.sanitizers],
|
|
144
134
|
errorHandlerChain: [...context.errorHandlerChain, subMeta.errorHandler].filter((el) => !!el),
|
|
145
135
|
interceptorChain: [...context.interceptorChain, controllerMeta.interceptor].filter((el) => !!el),
|
|
146
|
-
|
|
136
|
+
corsChain: [...context.corsChain, subMeta.cors].filter((el) => !!el),
|
|
137
|
+
};
|
|
138
|
+
const subResult = await this.routeWalker(walkerData, request, response);
|
|
147
139
|
if (subResult && subResult.status !== 404) {
|
|
148
140
|
return subResult;
|
|
149
141
|
}
|
|
150
142
|
}
|
|
151
143
|
}
|
|
152
|
-
const routeMatch =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
payload,
|
|
170
|
-
response: context.response,
|
|
171
|
-
request: context.request,
|
|
172
|
-
}).catch((err) => err);
|
|
173
|
-
const isError = !_constants_1.OK_STATUSES.includes(apiResponse.status);
|
|
174
|
-
if (isError) {
|
|
175
|
-
for (const handler of context.errorHandlerChain?.reverse() || []) {
|
|
176
|
-
apiResponse = handler(apiResponse);
|
|
144
|
+
const routeMatch = (0, _utils_1.findRouteInController)(controllerInstance, subPath, path, method);
|
|
145
|
+
try {
|
|
146
|
+
if (routeMatch) {
|
|
147
|
+
const { name, pathParams, middlewares, cors, sanitizers } = routeMatch;
|
|
148
|
+
Object.assign(request, { params: pathParams });
|
|
149
|
+
const handledCors = context.corsChain
|
|
150
|
+
.concat(cors ?? [])
|
|
151
|
+
.flat()
|
|
152
|
+
.reduce((acc, conf) => {
|
|
153
|
+
const cors = (0, _utils_1.handleCORS)(request, response, conf);
|
|
154
|
+
return {
|
|
155
|
+
permitted: acc.permitted && cors.permitted,
|
|
156
|
+
continue: acc.continue && cors.continue,
|
|
157
|
+
};
|
|
158
|
+
}, { permitted: true, continue: true });
|
|
159
|
+
if (!handledCors.permitted) {
|
|
160
|
+
return { status: 403, message: 'Cors: Origin not allowed' };
|
|
177
161
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
getAllMethods(obj) {
|
|
184
|
-
let methods = new Set();
|
|
185
|
-
let current = Object.getPrototypeOf(obj);
|
|
186
|
-
while (current && current !== Object.prototype) {
|
|
187
|
-
Object.getOwnPropertyNames(current).forEach((name) => {
|
|
188
|
-
if (name !== 'constructor' && typeof current[name] === 'function') {
|
|
189
|
-
methods.add(name);
|
|
162
|
+
if (!handledCors.continue && handledCors.permitted) {
|
|
163
|
+
return { status: 204 };
|
|
190
164
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
'constructor',
|
|
203
|
-
'getResponse',
|
|
204
|
-
'routeWalker',
|
|
205
|
-
'getAllMethods',
|
|
206
|
-
'findRouteInController',
|
|
207
|
-
].includes(name))
|
|
208
|
-
continue;
|
|
209
|
-
const endpointMeta = Reflect.getMetadata(_constants_1.ENDPOINT, prototype, name) || [];
|
|
210
|
-
if (endpointMeta.length === 0)
|
|
211
|
-
continue;
|
|
212
|
-
const [httpMethod, routePattern] = endpointMeta;
|
|
213
|
-
if (httpMethod !== method && httpMethod !== 'USE') {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
if (httpMethod === 'USE') {
|
|
217
|
-
let useRoute = route.split('/');
|
|
218
|
-
useRoute.pop();
|
|
219
|
-
route = useRoute.join('/');
|
|
220
|
-
}
|
|
221
|
-
const current = [path, routePattern].join('/').replace(/\/+/g, '/');
|
|
222
|
-
const pathParams = (0, _utils_1.matchRoute)(current, route);
|
|
223
|
-
if (pathParams) {
|
|
224
|
-
const priority = httpMethod === 'USE' ? 0 : Object.keys(pathParams).length > 0 ? 1 : 2;
|
|
225
|
-
matches.push({
|
|
226
|
-
name,
|
|
227
|
-
pathParams,
|
|
228
|
-
priority,
|
|
229
|
-
methodMiddlewares: Reflect.getMetadata(_constants_1.MIDDLEWARES, prototype, name) || [],
|
|
230
|
-
methodInterceptors: Reflect.getMetadata(_constants_1.INTERCEPTOR, prototype, name) || [],
|
|
165
|
+
const controllerMiddlewares = [
|
|
166
|
+
...context.middlewareChain,
|
|
167
|
+
...controllerMeta.middlewares,
|
|
168
|
+
];
|
|
169
|
+
const controllerSanitizers = [
|
|
170
|
+
...context.sanitizersChain,
|
|
171
|
+
...controllerMeta.sanitizers,
|
|
172
|
+
].filter((el) => !!el);
|
|
173
|
+
await (0, _utils_1.applyMiddlewaresVsSanitizers)(request, response, {
|
|
174
|
+
sanitizers: [controllerSanitizers, sanitizers],
|
|
175
|
+
middlewares: [controllerMiddlewares, middlewares],
|
|
231
176
|
});
|
|
177
|
+
let apiResponse = await (0, _utils_1.getResponse)({
|
|
178
|
+
interceptors: [...context.interceptorChain, controllerMeta.interceptor].filter((el) => !!el),
|
|
179
|
+
controllerInstance,
|
|
180
|
+
name,
|
|
181
|
+
response: response,
|
|
182
|
+
request: request,
|
|
183
|
+
}).catch((err) => err);
|
|
184
|
+
const isError = !_constants_1.OK_STATUSES.includes(apiResponse.status);
|
|
185
|
+
if (isError) {
|
|
186
|
+
for (const handler of context.errorHandlerChain?.reverse() || []) {
|
|
187
|
+
apiResponse = handler(apiResponse, request, response);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return apiResponse;
|
|
232
191
|
}
|
|
233
192
|
}
|
|
234
|
-
|
|
235
|
-
|
|
193
|
+
catch (errror) {
|
|
194
|
+
let data = { status: 500, ...errror };
|
|
195
|
+
for (const handler of context.errorHandlerChain?.reverse() || []) {
|
|
196
|
+
const res = await handler(errror, request, response);
|
|
197
|
+
Object.assign(data, res);
|
|
198
|
+
}
|
|
199
|
+
return data;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
236
202
|
}
|
|
237
203
|
};
|
|
238
204
|
};
|
package/dist/core/Endpoint.js
CHANGED
|
@@ -27,8 +27,7 @@ function Endpoint(method, pathPattern, middlewares) {
|
|
|
27
27
|
return descriptor;
|
|
28
28
|
}
|
|
29
29
|
if (method && pathPattern) {
|
|
30
|
-
Reflect.defineMetadata(_constants_1.ENDPOINT, [method, pathPattern], target, propertyKey);
|
|
31
|
-
Reflect.defineMetadata('middlewares', middlewares || [], target, propertyKey);
|
|
30
|
+
Reflect.defineMetadata(_constants_1.ENDPOINT, [method, pathPattern, middlewares], target, propertyKey);
|
|
32
31
|
}
|
|
33
32
|
(0, _constants_1.INCREMENT_STATISTIC)('routes');
|
|
34
33
|
return descriptor;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This module provides centralized exports for controller and endpoint decorators,
|
|
5
5
|
* as well as related types and utility functions used throughout the core framework.
|
|
6
6
|
*/
|
|
7
|
-
export { AppRequest, EndpointResponse, ErrorCB, HttpError, IController, InterceptorCB, IWebSocketService, MiddlewareCB,
|
|
7
|
+
export { AppRequest, CORSConfig, EndpointResponse, ErrorCB, HttpError, IController, InterceptorCB, IWebSocketService, MiddlewareCB, MultipartFile, ResponseWithStatus, WebSocketClient, WebSocketEvent, WebSocketMessage, } from '../types/index.js';
|
|
8
8
|
export * from './Controller';
|
|
9
9
|
export * from './Endpoint';
|
|
10
10
|
export * from './utils';
|
package/dist/core/utils/index.js
CHANGED
|
@@ -15,6 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./extractors"), exports);
|
|
18
|
-
__exportStar(require("./helpers"), exports);
|
|
19
|
-
__exportStar(require("./middlewares"), exports);
|
|
20
18
|
__exportStar(require("./websocket"), exports);
|
package/dist/examples/app.d.ts
CHANGED
package/dist/examples/app.js
CHANGED
|
@@ -1,21 +1,75 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
2
18
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
19
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
20
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
21
|
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;
|
|
6
22
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
23
|
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
8
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
42
|
exports.App = exports.Root = void 0;
|
|
43
|
+
const Joi = __importStar(require("joi"));
|
|
10
44
|
const core_1 = require("quantum-flow/core");
|
|
11
45
|
const http_1 = require("quantum-flow/http");
|
|
12
|
-
require("
|
|
46
|
+
const middlewares_1 = require("quantum-flow/middlewares");
|
|
13
47
|
const user_1 = require("./controllers/user");
|
|
14
48
|
let Root = class Root {
|
|
15
49
|
};
|
|
16
50
|
exports.Root = Root;
|
|
17
51
|
exports.Root = Root = __decorate([
|
|
18
|
-
(0, core_1.Controller)({
|
|
52
|
+
(0, core_1.Controller)({
|
|
53
|
+
prefix: 'api',
|
|
54
|
+
controllers: [user_1.User],
|
|
55
|
+
middlewares: [function Global(req, res, next) { }],
|
|
56
|
+
}),
|
|
57
|
+
(0, middlewares_1.Cors)({ origin: '*' }),
|
|
58
|
+
(0, middlewares_1.Use)(function Global1(req, res, next) {
|
|
59
|
+
return next();
|
|
60
|
+
}),
|
|
61
|
+
(0, middlewares_1.Catch)(function GLOBALCATCH(err) {
|
|
62
|
+
return { status: 400 };
|
|
63
|
+
}),
|
|
64
|
+
(0, middlewares_1.Sanitize)({
|
|
65
|
+
schema: Joi.object({
|
|
66
|
+
name: Joi.string().trim().min(2).max(50).required(),
|
|
67
|
+
}),
|
|
68
|
+
action: 'both',
|
|
69
|
+
options: { abortEarly: false },
|
|
70
|
+
stripUnknown: true,
|
|
71
|
+
type: 'body',
|
|
72
|
+
})
|
|
19
73
|
], Root);
|
|
20
74
|
let App = class App {
|
|
21
75
|
};
|
|
@@ -26,9 +80,20 @@ exports.App = App = __decorate([
|
|
|
26
80
|
websocket: { enabled: true },
|
|
27
81
|
interceptor: (data) => data,
|
|
28
82
|
errorHandler: (err) => err,
|
|
83
|
+
cors: { origin: '*' },
|
|
84
|
+
middlewares: [() => { }, () => { }],
|
|
29
85
|
}),
|
|
30
86
|
(0, http_1.Port)(3000),
|
|
31
|
-
(0,
|
|
32
|
-
(0,
|
|
33
|
-
(0,
|
|
87
|
+
(0, middlewares_1.Use)(() => { }),
|
|
88
|
+
(0, middlewares_1.Use)([() => { }, () => { }]),
|
|
89
|
+
(0, middlewares_1.Catch)((err) => err),
|
|
90
|
+
(0, middlewares_1.Sanitize)({
|
|
91
|
+
schema: Joi.object({
|
|
92
|
+
name: Joi.string().trim().min(2).max(50).required(),
|
|
93
|
+
}),
|
|
94
|
+
action: 'both',
|
|
95
|
+
options: { abortEarly: false },
|
|
96
|
+
stripUnknown: true,
|
|
97
|
+
type: 'headers',
|
|
98
|
+
})
|
|
34
99
|
], App);
|