quantum-flow 1.3.5 → 1.3.7
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 +1 -1
- package/dist/app/http/Application.js +6 -2
- package/dist/core/Controller.js +11 -9
- package/dist/core/index.d.ts +1 -1
- package/dist/core/utils/extractors.d.ts +2 -2
- package/dist/core/utils/extractors.js +2 -2
- package/dist/examples/controllers/user.js +0 -3
- package/dist/examples/controllers/userMetadata.js +11 -2
- package/dist/examples/server.js +8 -3
- package/dist/types/common.d.ts +10 -1
- package/dist/types/controller.d.ts +1 -0
- package/dist/utils/controller.js +2 -2
- package/dist/utils/endpoint.js +0 -1
- package/package.json +1 -1
- package/dist/validators/Validate.d.ts +0 -3
- package/dist/validators/Validate.js +0 -40
- package/dist/validators/index.d.ts +0 -1
- package/dist/validators/index.js +0 -17
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ export class User {
|
|
|
66
66
|
@Body(UserDto) body: UserDto,
|
|
67
67
|
@Query() query: any,
|
|
68
68
|
@Headers() headers: any,
|
|
69
|
-
@Params() params: any,
|
|
69
|
+
@Params(ParamDTO, 'param') params: any,
|
|
70
70
|
@Request() req: any,
|
|
71
71
|
@Response() resp: any,
|
|
72
72
|
@InjectWS() ws: IWebSocketService,
|
|
@@ -103,13 +103,17 @@ class HttpServer extends Socket_1.Socket {
|
|
|
103
103
|
const request = await this.createRequest(req);
|
|
104
104
|
let appRequest = await this.applyMiddlewares(request, req, res);
|
|
105
105
|
let data = await this.findController(appRequest, req, res);
|
|
106
|
+
const isError = !_constants_1.OK_STATUSES.includes(data.status);
|
|
107
|
+
if (isError) {
|
|
108
|
+
return this.handleError(data, req, res, startTime);
|
|
109
|
+
}
|
|
106
110
|
if (this.config.interceptor) {
|
|
107
111
|
data = await this.config.interceptor(data, req, res);
|
|
108
112
|
}
|
|
109
|
-
|
|
113
|
+
return this.sendResponse(res, data, startTime);
|
|
110
114
|
}
|
|
111
115
|
catch (error) {
|
|
112
|
-
|
|
116
|
+
return this.handleError(error, req, res, startTime);
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
async createRequest(req) {
|
package/dist/core/Controller.js
CHANGED
|
@@ -70,7 +70,6 @@ function Controller(config, middlewares = []) {
|
|
|
70
70
|
super(...args);
|
|
71
71
|
}
|
|
72
72
|
async getResponse(data) {
|
|
73
|
-
let y;
|
|
74
73
|
try {
|
|
75
74
|
let appResponse = await this.executeControllerMethod(data.controllerInstance, data.name, data.payload, data.request, data.response);
|
|
76
75
|
let status = appResponse.status ?? 200;
|
|
@@ -93,7 +92,6 @@ function Controller(config, middlewares = []) {
|
|
|
93
92
|
return { status, data: appResponse };
|
|
94
93
|
}
|
|
95
94
|
catch (err) {
|
|
96
|
-
console.error(err);
|
|
97
95
|
throw err;
|
|
98
96
|
}
|
|
99
97
|
}
|
|
@@ -114,6 +112,7 @@ function Controller(config, middlewares = []) {
|
|
|
114
112
|
response,
|
|
115
113
|
middlewareChain: [],
|
|
116
114
|
interceptorChain: [],
|
|
115
|
+
errorHandlerChain: [Reflect.getMetadata(_constants_1.CATCH, proto)],
|
|
117
116
|
subPath: Reflect.getMetadata(_constants_1.ROUTE_PREFIX, proto) || '',
|
|
118
117
|
};
|
|
119
118
|
const result = await this.routeWalker(context);
|
|
@@ -127,7 +126,7 @@ function Controller(config, middlewares = []) {
|
|
|
127
126
|
routePrefix: Reflect.getMetadata(_constants_1.ROUTE_PREFIX, SubController.prototype) || '',
|
|
128
127
|
middlewares: Reflect.getMetadata(_constants_1.MIDDLEWARES, SubController.prototype) || [],
|
|
129
128
|
interceptor: Reflect.getMetadata(_constants_1.INTERCEPTOR, SubController.prototype),
|
|
130
|
-
errorHandler: Reflect.getMetadata(_constants_1.CATCH, SubController
|
|
129
|
+
errorHandler: Reflect.getMetadata(_constants_1.CATCH, SubController),
|
|
131
130
|
subControllers: Reflect.getMetadata(_constants_1.CONTROLLERS, SubController.prototype) || [],
|
|
132
131
|
};
|
|
133
132
|
const fullSubPath = [subPath, subMeta.routePrefix]
|
|
@@ -142,6 +141,7 @@ function Controller(config, middlewares = []) {
|
|
|
142
141
|
controllerMeta: subMeta,
|
|
143
142
|
path,
|
|
144
143
|
middlewareChain: [...context.middlewareChain, ...controllerMeta.middlewares],
|
|
144
|
+
errorHandlerChain: [...context.errorHandlerChain, subMeta.errorHandler].filter((el) => !!el),
|
|
145
145
|
interceptorChain: [...context.interceptorChain, controllerMeta.interceptor].filter((el) => !!el),
|
|
146
146
|
});
|
|
147
147
|
if (subResult && subResult.status !== 404) {
|
|
@@ -162,19 +162,21 @@ function Controller(config, middlewares = []) {
|
|
|
162
162
|
const mwResult = await mw(payload, context.request, context.response);
|
|
163
163
|
payload = mwResult ?? payload;
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
let apiResponse = await this.getResponse({
|
|
166
166
|
interceptors: [...context.interceptorChain, controllerMeta.interceptor].filter((el) => !!el),
|
|
167
167
|
controllerInstance,
|
|
168
168
|
name,
|
|
169
169
|
payload,
|
|
170
170
|
response: context.response,
|
|
171
171
|
request: context.request,
|
|
172
|
-
}).catch((
|
|
173
|
-
|
|
174
|
-
|
|
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);
|
|
175
177
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
}
|
|
179
|
+
return apiResponse;
|
|
178
180
|
}
|
|
179
181
|
return null;
|
|
180
182
|
}
|
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, IController, InterceptorCB, IWebSocketService, MiddlewareCB, ResponseWithStatus, Router, WebSocketClient, WebSocketEvent, WebSocketMessage, } from '../types/index.js';
|
|
7
|
+
export { AppRequest, EndpointResponse, ErrorCB, HttpError, IController, InterceptorCB, IWebSocketService, MiddlewareCB, ResponseWithStatus, Router, WebSocketClient, WebSocketEvent, WebSocketMessage, } from '../types/index.js';
|
|
8
8
|
export * from './Controller';
|
|
9
9
|
export * from './Endpoint';
|
|
10
10
|
export * from './utils';
|
|
@@ -7,12 +7,12 @@ export declare const Body: (dto?: any) => (target: any, propertyKey: string | sy
|
|
|
7
7
|
* Parameter decorator to extract route parameters.
|
|
8
8
|
* @param name Optional name of the parameter to extract.
|
|
9
9
|
*/
|
|
10
|
-
export declare const Params: (name?: string) => (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
10
|
+
export declare const Params: (dto?: any, name?: string) => (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
11
11
|
/**
|
|
12
12
|
* Parameter decorator to extract query parameters.
|
|
13
13
|
* @param name Optional name of the query parameter to extract.
|
|
14
14
|
*/
|
|
15
|
-
export declare const Query: (name?: string) => (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
15
|
+
export declare const Query: (dto?: any, name?: string) => (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
16
16
|
/**
|
|
17
17
|
* Parameter decorator to inject the entire request object.
|
|
18
18
|
*/
|
|
@@ -12,13 +12,13 @@ exports.Body = Body;
|
|
|
12
12
|
* Parameter decorator to extract route parameters.
|
|
13
13
|
* @param name Optional name of the parameter to extract.
|
|
14
14
|
*/
|
|
15
|
-
const Params = (name) => (0, _utils_1.createParamDecorator)('params', undefined, name);
|
|
15
|
+
const Params = (dto, name) => (0, _utils_1.createParamDecorator)('params', typeof dto == 'string' ? undefined : dto, typeof dto == 'string' ? dto : name);
|
|
16
16
|
exports.Params = Params;
|
|
17
17
|
/**
|
|
18
18
|
* Parameter decorator to extract query parameters.
|
|
19
19
|
* @param name Optional name of the query parameter to extract.
|
|
20
20
|
*/
|
|
21
|
-
const Query = (name) => (0, _utils_1.createParamDecorator)('query', undefined, name);
|
|
21
|
+
const Query = (dto, name) => (0, _utils_1.createParamDecorator)('query', typeof dto == 'string' ? undefined : dto, typeof dto == 'string' ? dto : name);
|
|
22
22
|
exports.Query = Query;
|
|
23
23
|
/**
|
|
24
24
|
* Parameter decorator to inject the entire request object.
|
|
@@ -13,7 +13,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.UserMetadata = void 0;
|
|
16
|
+
const class_validator_1 = require("class-validator");
|
|
16
17
|
const core_1 = require("quantum-flow/core");
|
|
18
|
+
class DTO {
|
|
19
|
+
constructor() { }
|
|
20
|
+
meta;
|
|
21
|
+
}
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, class_validator_1.IsString)(),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], DTO.prototype, "meta", void 0);
|
|
17
26
|
let UserMetadata = class UserMetadata {
|
|
18
27
|
async getUserMetadata(params) {
|
|
19
28
|
return params;
|
|
@@ -21,8 +30,8 @@ let UserMetadata = class UserMetadata {
|
|
|
21
30
|
};
|
|
22
31
|
exports.UserMetadata = UserMetadata;
|
|
23
32
|
__decorate([
|
|
24
|
-
(0, core_1.GET)('/:
|
|
25
|
-
__param(0, (0, core_1.Params)()),
|
|
33
|
+
(0, core_1.GET)('/:meta'),
|
|
34
|
+
__param(0, (0, core_1.Params)(DTO, 'meta')),
|
|
26
35
|
__metadata("design:type", Function),
|
|
27
36
|
__metadata("design:paramtypes", [Object]),
|
|
28
37
|
__metadata("design:returntype", Promise)
|
package/dist/examples/server.js
CHANGED
|
@@ -15,18 +15,23 @@ let Root = class Root {
|
|
|
15
15
|
Root = __decorate([
|
|
16
16
|
(0, core_1.Controller)({ prefix: 'api', controllers: [user_1.User] })
|
|
17
17
|
], Root);
|
|
18
|
-
let App =
|
|
18
|
+
let App =
|
|
19
|
+
// @Catch((error) => ({ status: 400, error }))
|
|
20
|
+
class App {
|
|
19
21
|
};
|
|
20
22
|
App = __decorate([
|
|
21
23
|
(0, http_1.Server)({
|
|
22
24
|
controllers: [Root],
|
|
23
25
|
websocket: { enabled: true },
|
|
24
26
|
interceptor: (data) => data,
|
|
27
|
+
errorHandler: (err) => {
|
|
28
|
+
return err;
|
|
29
|
+
},
|
|
25
30
|
}),
|
|
26
31
|
(0, http_1.Port)(3000),
|
|
27
32
|
(0, core_1.Use)((data) => data),
|
|
28
|
-
(0, core_1.Use)((data) => data)
|
|
29
|
-
|
|
33
|
+
(0, core_1.Use)((data) => data)
|
|
34
|
+
// @Catch((error) => ({ status: 400, error }))
|
|
30
35
|
], App);
|
|
31
36
|
const server = new http_1.HttpServer(App);
|
|
32
37
|
server.listen().catch(console.error);
|
package/dist/types/common.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http';
|
|
2
2
|
type P_Q = Record<string, string | undefined> | null | unknown;
|
|
3
|
+
export interface HttpError extends Error {
|
|
4
|
+
statusCode?: number;
|
|
5
|
+
status: number;
|
|
6
|
+
data?: any;
|
|
7
|
+
messages?: string[];
|
|
8
|
+
errors?: Array<{
|
|
9
|
+
message: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
3
12
|
export type AppRequest<B = unknown, Q extends P_Q = unknown, P extends P_Q = unknown> = {
|
|
4
13
|
method: HTTP_METHODS;
|
|
5
14
|
url: URL;
|
|
@@ -40,7 +49,7 @@ export interface IController {
|
|
|
40
49
|
}
|
|
41
50
|
export type MiddlewareCB = (appRequest: AppRequest, request?: IncomingMessage, response?: ServerResponse) => void | Promise<AppRequest> | AppRequest;
|
|
42
51
|
export type InterceptorCB = (data: any, req?: IncomingMessage, res?: ServerResponse) => Promise<unknown> | unknown;
|
|
43
|
-
export type ErrorCB = (error:
|
|
52
|
+
export type ErrorCB = (error: HttpError, req?: IncomingMessage, res?: ServerResponse) => Promise<ResponseWithStatus> | ResponseWithStatus;
|
|
44
53
|
export type ParamDecoratorType = 'body' | 'params' | 'query' | 'request' | 'headers' | 'cookies' | 'response' | 'multipart' | 'event' | 'context';
|
|
45
54
|
export interface ParamMetadata {
|
|
46
55
|
index: number;
|
package/dist/utils/controller.js
CHANGED
|
@@ -43,10 +43,10 @@ const executeControllerMethod = async (controller, propertyName, payload, reques
|
|
|
43
43
|
}
|
|
44
44
|
const prototype = Object.getPrototypeOf(controller);
|
|
45
45
|
const paramMetadata = Reflect.getMetadata(_constants_1.PARAM_METADATA_KEY, prototype, propertyName) || [];
|
|
46
|
-
const { body, multipart } = getBodyAndMultipart(payload);
|
|
47
46
|
if (paramMetadata.length === 0) {
|
|
48
47
|
return fn.call(controller, payload);
|
|
49
48
|
}
|
|
49
|
+
const { body, multipart } = getBodyAndMultipart(payload);
|
|
50
50
|
const args = [];
|
|
51
51
|
const wsParams = Reflect.getMetadata(_constants_1.WS_SERVICE_KEY, controller, propertyName) || [];
|
|
52
52
|
const totalParams = Math.max(paramMetadata.length ? Math.max(...paramMetadata.map((p) => p.index)) + 1 : 0, wsParams.length ? Math.max(...wsParams.map((p) => p.index)) + 1 : 0);
|
|
@@ -78,7 +78,7 @@ const executeControllerMethod = async (controller, propertyName, payload, reques
|
|
|
78
78
|
value = response;
|
|
79
79
|
}
|
|
80
80
|
if (_constants_1.TO_VALIDATE.includes(param.type)) {
|
|
81
|
-
value = await (0, validate_1.validate)(param.dto, value);
|
|
81
|
+
value = await (0, validate_1.validate)(param.dto, typeof value === 'string' ? { [param.name ?? '']: value } : value);
|
|
82
82
|
}
|
|
83
83
|
args[i] = value;
|
|
84
84
|
}
|
package/dist/utils/endpoint.js
CHANGED
|
@@ -8,6 +8,5 @@ function createParamDecorator(type, dto, name) {
|
|
|
8
8
|
existingParams.push({ index: parameterIndex, type, dto, name });
|
|
9
9
|
existingParams.sort((a, b) => a.index - b.index);
|
|
10
10
|
Reflect.defineMetadata(_constants_1.PARAM_METADATA_KEY, existingParams, target, propertyKey);
|
|
11
|
-
const saved = Reflect.getMetadata(_constants_1.PARAM_METADATA_KEY, target, propertyKey);
|
|
12
11
|
};
|
|
13
12
|
}
|
package/package.json
CHANGED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Validate = Validate;
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
-
const class_validator_1 = require("class-validator");
|
|
6
|
-
function Validate(param, dtoClass) {
|
|
7
|
-
return function (target, propertyKey, descriptor) {
|
|
8
|
-
// METHOD DECORATOR
|
|
9
|
-
if (descriptor) {
|
|
10
|
-
wrapMethod(descriptor, param, dtoClass);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
// CLASS DECORATOR
|
|
14
|
-
const prototype = target.prototype;
|
|
15
|
-
Object.getOwnPropertyNames(prototype).forEach((method) => {
|
|
16
|
-
if (method === 'constructor')
|
|
17
|
-
return;
|
|
18
|
-
const desc = Object.getOwnPropertyDescriptor(prototype, method);
|
|
19
|
-
if (!desc || typeof desc.value !== 'function')
|
|
20
|
-
return;
|
|
21
|
-
wrapMethod(desc, param, dtoClass);
|
|
22
|
-
Object.defineProperty(prototype, method, desc);
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function wrapMethod(descriptor, param, dtoClass) {
|
|
27
|
-
const originalMethod = descriptor.value;
|
|
28
|
-
descriptor.value = async function (...args) {
|
|
29
|
-
const value = args[0][param];
|
|
30
|
-
const instance = new dtoClass();
|
|
31
|
-
Object.entries(value || {}).forEach(([key, val]) => {
|
|
32
|
-
instance[key] = val;
|
|
33
|
-
});
|
|
34
|
-
const errors = await (0, class_validator_1.validate)(instance, { whitelist: true });
|
|
35
|
-
if (errors.length) {
|
|
36
|
-
throw { status: 422, message: 'Validation failed', data: errors };
|
|
37
|
-
}
|
|
38
|
-
return originalMethod.apply(this, args);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './Validate';
|
package/dist/validators/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./Validate"), exports);
|