quantum-flow 1.0.1 → 1.0.5
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 +245 -17
- package/dist/app/aws/lambda.d.ts +1 -1
- package/dist/app/aws/lambda.js +2 -2
- package/dist/app/http/Application.d.ts +1 -1
- package/dist/app/http/Application.js +2 -2
- package/dist/app/http/decorators.d.ts +1 -1
- package/dist/app/http/decorators.js +1 -1
- package/dist/app/http/websocket/WebsocetService.d.ts +1 -1
- package/dist/app/http/websocket/WebsocketServer.d.ts +1 -1
- package/dist/core/Controller.d.ts +24 -3
- package/dist/core/Controller.js +26 -5
- package/dist/core/Endpoint.d.ts +63 -7
- package/dist/core/Endpoint.js +69 -13
- package/dist/core/index.d.ts +7 -1
- package/dist/core/utils/extractors.d.ts +31 -1
- package/dist/core/utils/extractors.js +31 -1
- package/dist/core/utils/helpers.d.ts +13 -0
- package/dist/core/utils/helpers.js +14 -1
- package/dist/core/utils/websocket.d.ts +26 -1
- package/dist/core/utils/websocket.js +26 -1
- package/dist/examples/controllers/index.d.ts +2 -0
- package/dist/examples/controllers/index.js +18 -0
- package/dist/examples/controllers/socket.d.ts +24 -0
- package/dist/examples/controllers/socket.js +107 -0
- package/dist/examples/controllers/user.d.ts +3 -0
- package/dist/examples/controllers/user.js +55 -0
- package/dist/examples/server.d.ts +1 -0
- package/dist/examples/server.js +48 -0
- package/dist/utils/controller.d.ts +1 -1
- package/dist/utils/controller.js +2 -2
- package/dist/utils/server.d.ts +1 -1
- package/dist/utils/server.js +1 -1
- package/dist/utils/transform.js +0 -1
- package/package.json +20 -6
- package/.prettierrc.json +0 -9
- package/eslint.config.mjs +0 -84
- package/nodemon.json +0 -5
- package/src/app/aws/index.ts +0 -1
- package/src/app/aws/lambda.ts +0 -283
- package/src/app/http/Application.ts +0 -250
- package/src/app/http/Socket.ts +0 -38
- package/src/app/http/decorators.ts +0 -115
- package/src/app/http/index.ts +0 -3
- package/src/app/http/websocket/WebsocetService.ts +0 -44
- package/src/app/http/websocket/WebsocketServer.ts +0 -262
- package/src/constants.ts +0 -25
- package/src/core/Controller.ts +0 -229
- package/src/core/Endpoint.ts +0 -39
- package/src/core/index.ts +0 -14
- package/src/core/utils/extractors.ts +0 -32
- package/src/core/utils/helpers.ts +0 -22
- package/src/core/utils/index.ts +0 -3
- package/src/core/utils/websocket.ts +0 -45
- package/src/types/common.ts +0 -60
- package/src/types/controller.ts +0 -2
- package/src/types/http.ts +0 -19
- package/src/types/index.ts +0 -5
- package/src/types/lambda.ts +0 -28
- package/src/types/websocket.ts +0 -57
- package/src/utils/controller.ts +0 -143
- package/src/utils/helper.ts +0 -24
- package/src/utils/index.ts +0 -7
- package/src/utils/multipart.ts +0 -93
- package/src/utils/parsers.ts +0 -87
- package/src/utils/server.ts +0 -49
- package/src/utils/transform.ts +0 -24
- package/src/utils/validate.ts +0 -53
- package/src/validators/Validate.ts +0 -48
- package/src/validators/index.ts +0 -1
- package/tsconfig.json +0 -51
package/src/core/Endpoint.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { ENDPOINT } from '@constants';
|
|
2
|
-
import { Middleware } from '@types';
|
|
3
|
-
|
|
4
|
-
export function Endpoint(method: string, pathPattern?: string, middlewares?: Middleware[]) {
|
|
5
|
-
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
6
|
-
const originalMethod = descriptor.value;
|
|
7
|
-
|
|
8
|
-
if (!originalMethod) {
|
|
9
|
-
console.warn('❌ originalMethod is undefined!');
|
|
10
|
-
return descriptor;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (method && pathPattern) {
|
|
14
|
-
Reflect.defineMetadata(ENDPOINT, [method, pathPattern], target, propertyKey);
|
|
15
|
-
Reflect.defineMetadata('middlewares', middlewares || [], target, propertyKey);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return descriptor;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const GET = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
23
|
-
return Endpoint('GET', pathPattern, middelwares);
|
|
24
|
-
};
|
|
25
|
-
export const POST = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
26
|
-
return Endpoint('POST', pathPattern, middelwares);
|
|
27
|
-
};
|
|
28
|
-
export const PUT = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
29
|
-
return Endpoint('PUT', pathPattern, middelwares);
|
|
30
|
-
};
|
|
31
|
-
export const PATCH = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
32
|
-
return Endpoint('PATCH', pathPattern, middelwares);
|
|
33
|
-
};
|
|
34
|
-
export const DELETE = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
35
|
-
return Endpoint('DELETE', pathPattern, middelwares);
|
|
36
|
-
};
|
|
37
|
-
export const USE = (pathPattern?: string, middelwares?: Middleware[]) => {
|
|
38
|
-
return Endpoint('USE', pathPattern, middelwares);
|
|
39
|
-
};
|
package/src/core/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
EndpointResponse,
|
|
3
|
-
IController,
|
|
4
|
-
Interceptor,
|
|
5
|
-
Middleware,
|
|
6
|
-
Request,
|
|
7
|
-
Router,
|
|
8
|
-
WebSocketClient,
|
|
9
|
-
WebSocketEvent,
|
|
10
|
-
WebSocketMessage,
|
|
11
|
-
} from '@types';
|
|
12
|
-
export * from './Controller';
|
|
13
|
-
export * from './Endpoint';
|
|
14
|
-
export * from './utils';
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { PARAM_METADATA_KEY } from '@constants';
|
|
2
|
-
import { ParamDecoratorType } from '@types';
|
|
3
|
-
|
|
4
|
-
export interface ParamMetadata {
|
|
5
|
-
index: number;
|
|
6
|
-
type: ParamDecoratorType;
|
|
7
|
-
dto?: any;
|
|
8
|
-
name?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function createParamDecorator(type: ParamDecoratorType, dto?: any, name?: string) {
|
|
12
|
-
return function (target: any, propertyKey: string | symbol, parameterIndex: number) {
|
|
13
|
-
const existingParams: ParamMetadata[] =
|
|
14
|
-
Reflect.getMetadata(PARAM_METADATA_KEY, target, propertyKey) || [];
|
|
15
|
-
|
|
16
|
-
existingParams.push({ index: parameterIndex, type, dto, name });
|
|
17
|
-
existingParams.sort((a, b) => a.index - b.index);
|
|
18
|
-
|
|
19
|
-
Reflect.defineMetadata(PARAM_METADATA_KEY, existingParams, target, propertyKey);
|
|
20
|
-
|
|
21
|
-
const saved = Reflect.getMetadata(PARAM_METADATA_KEY, target, propertyKey);
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const Body = (dto?: any) => createParamDecorator('body', dto);
|
|
26
|
-
export const Params = (name?: string) => createParamDecorator('params', undefined, name);
|
|
27
|
-
export const Query = (name?: string) => createParamDecorator('query', undefined, name);
|
|
28
|
-
export const Request = () => createParamDecorator('request');
|
|
29
|
-
export const Headers = (name?: string) => createParamDecorator('headers', undefined, name);
|
|
30
|
-
export const Cookies = (name?: string) => createParamDecorator('cookies', undefined, name);
|
|
31
|
-
export const Multipart = (name?: string) => createParamDecorator('multipart', undefined, name);
|
|
32
|
-
export const Response = () => createParamDecorator('response');
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { OK_METADATA_KEY } from '@constants';
|
|
2
|
-
|
|
3
|
-
export function Status(status: number) {
|
|
4
|
-
return function (
|
|
5
|
-
target: any,
|
|
6
|
-
propertyKey?: string | symbol,
|
|
7
|
-
descriptor?: TypedPropertyDescriptor<any>,
|
|
8
|
-
): void {
|
|
9
|
-
if (!propertyKey) {
|
|
10
|
-
Reflect.defineMetadata(OK_METADATA_KEY, status, target.prototype || target);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (descriptor) {
|
|
15
|
-
Reflect.defineMetadata(OK_METADATA_KEY, status, target, propertyKey);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const Ok200 = () => Status(200);
|
|
21
|
-
export const Ok201 = () => Status(201);
|
|
22
|
-
export const Ok204 = () => Status(204);
|
package/src/core/utils/index.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { WS_METADATA_KEY, WS_SERVICE_KEY, WS_TOPIC_KEY } from '@constants';
|
|
2
|
-
|
|
3
|
-
import { WebSocketHandlerType } from '@types';
|
|
4
|
-
|
|
5
|
-
export function OnWS(type: WebSocketHandlerType, topic?: string) {
|
|
6
|
-
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
7
|
-
const handlers = Reflect.getMetadata(WS_METADATA_KEY, target.constructor) || [];
|
|
8
|
-
handlers.push({ type, topic, method: propertyKey });
|
|
9
|
-
Reflect.defineMetadata(WS_METADATA_KEY, handlers, target.constructor);
|
|
10
|
-
return descriptor;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function OnConnection() {
|
|
15
|
-
return OnWS('connection');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function OnMessage(topic?: string) {
|
|
19
|
-
return OnWS('message', topic);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function OnClose() {
|
|
23
|
-
return OnWS('close');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function OnError() {
|
|
27
|
-
return OnWS('error');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function Subscribe(topic: string) {
|
|
31
|
-
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
32
|
-
const topics = Reflect.getMetadata(WS_TOPIC_KEY, target.constructor) || [];
|
|
33
|
-
topics.push({ topic, method: propertyKey });
|
|
34
|
-
Reflect.defineMetadata(WS_TOPIC_KEY, topics, target.constructor);
|
|
35
|
-
return descriptor;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function InjectWS() {
|
|
40
|
-
return function (target: any, propertyKey: string, parameterIndex: number) {
|
|
41
|
-
const existingParams = Reflect.getMetadata(WS_SERVICE_KEY, target, propertyKey) || [];
|
|
42
|
-
existingParams.push({ index: parameterIndex });
|
|
43
|
-
Reflect.defineMetadata(WS_SERVICE_KEY, existingParams, target, propertyKey);
|
|
44
|
-
};
|
|
45
|
-
}
|
package/src/types/common.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { IncomingHttpHeaders, ServerResponse } from 'http';
|
|
3
|
-
|
|
4
|
-
type P_Q = Record<string, string | undefined> | null | unknown;
|
|
5
|
-
|
|
6
|
-
export type Request<B = unknown, Q extends P_Q = unknown, P extends P_Q = unknown> = {
|
|
7
|
-
method: string;
|
|
8
|
-
url: URL;
|
|
9
|
-
headers: IncomingHttpHeaders;
|
|
10
|
-
query?: Q;
|
|
11
|
-
params?: P;
|
|
12
|
-
body: B;
|
|
13
|
-
isBase64Encoded?: boolean;
|
|
14
|
-
};
|
|
15
|
-
export type Router = (
|
|
16
|
-
req: Request,
|
|
17
|
-
res?: ServerResponse,
|
|
18
|
-
) => Promise<{ status: number; data: any; message?: string }>;
|
|
19
|
-
|
|
20
|
-
export type EndpointResponse<T = any> = {
|
|
21
|
-
status: number;
|
|
22
|
-
data?: T;
|
|
23
|
-
error?: any;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type AxiosQuery = {
|
|
27
|
-
data?: { [key: string]: any };
|
|
28
|
-
headers?: { [key: string]: any };
|
|
29
|
-
params?: { [key: string]: any };
|
|
30
|
-
url: string;
|
|
31
|
-
method: 'POST' | 'GET' | 'PATCH' | 'DELETE';
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export interface IController {
|
|
35
|
-
handleRequest: Router;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type Middleware = (req: Request, res?: ServerResponse) => Promise<Request> | Request;
|
|
39
|
-
export type Interceptor = (
|
|
40
|
-
data: any,
|
|
41
|
-
req?: Request,
|
|
42
|
-
res?: ServerResponse,
|
|
43
|
-
) => Promise<unknown> | unknown;
|
|
44
|
-
|
|
45
|
-
export type ParamDecoratorType =
|
|
46
|
-
| 'body'
|
|
47
|
-
| 'params'
|
|
48
|
-
| 'query'
|
|
49
|
-
| 'request'
|
|
50
|
-
| 'headers'
|
|
51
|
-
| 'cookies'
|
|
52
|
-
| 'response'
|
|
53
|
-
| 'multipart';
|
|
54
|
-
|
|
55
|
-
export interface ParamMetadata {
|
|
56
|
-
index: number;
|
|
57
|
-
type: ParamDecoratorType;
|
|
58
|
-
dto?: any;
|
|
59
|
-
name?: string;
|
|
60
|
-
}
|
package/src/types/controller.ts
DELETED
package/src/types/http.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export interface ServerConfig {
|
|
2
|
-
port?: number;
|
|
3
|
-
host?: string;
|
|
4
|
-
globalMiddlewares?: any[];
|
|
5
|
-
globalInterceptors?: any[];
|
|
6
|
-
globalErrorHandler?: any;
|
|
7
|
-
controllers?: any[];
|
|
8
|
-
websocket?: {
|
|
9
|
-
enabled: boolean;
|
|
10
|
-
path?: string;
|
|
11
|
-
lazy?: boolean;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type Conf = ServerConfig & {
|
|
16
|
-
globalMiddlewares?: any[];
|
|
17
|
-
globalInterceptors?: any[];
|
|
18
|
-
globalErrorHandler?: any;
|
|
19
|
-
};
|
package/src/types/index.ts
DELETED
package/src/types/lambda.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { APIGatewayProxyEvent, Context } from 'aws-lambda';
|
|
2
|
-
|
|
3
|
-
export interface LambdaRequest {
|
|
4
|
-
method: string;
|
|
5
|
-
path: string;
|
|
6
|
-
headers: Record<string, string | string[]>;
|
|
7
|
-
query: Record<string, string | string[]>;
|
|
8
|
-
body: any;
|
|
9
|
-
params: Record<string, string>;
|
|
10
|
-
cookies: Record<string, string>;
|
|
11
|
-
raw: APIGatewayProxyEvent;
|
|
12
|
-
context: Context;
|
|
13
|
-
isBase64Encoded: boolean;
|
|
14
|
-
requestId: string;
|
|
15
|
-
stage: string;
|
|
16
|
-
sourceIp: string;
|
|
17
|
-
userAgent: string;
|
|
18
|
-
url: URL;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface LambdaResponse {
|
|
22
|
-
statusCode: number;
|
|
23
|
-
headers?: Record<string, string>;
|
|
24
|
-
body: string;
|
|
25
|
-
isBase64Encoded?: boolean;
|
|
26
|
-
multiValueHeaders?: Record<string, string[]>;
|
|
27
|
-
cookies?: string[];
|
|
28
|
-
}
|
package/src/types/websocket.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
|
|
3
|
-
export type WebSocketHandlerType = 'connection' | 'message' | 'close' | 'error';
|
|
4
|
-
|
|
5
|
-
export interface WebSocketMessage {
|
|
6
|
-
type: string;
|
|
7
|
-
topic?: string;
|
|
8
|
-
data: any;
|
|
9
|
-
clientId?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface WebSocketEvent {
|
|
13
|
-
type: WebSocketHandlerType;
|
|
14
|
-
client: WebSocketClient;
|
|
15
|
-
message?: WebSocketMessage;
|
|
16
|
-
data?: any;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface WebSocketClient {
|
|
20
|
-
id: string;
|
|
21
|
-
socket: WebSocket;
|
|
22
|
-
topics: Set<string>;
|
|
23
|
-
data: Record<string, any>;
|
|
24
|
-
connectedAt: Date;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface WebSocketMessage {
|
|
28
|
-
type: string;
|
|
29
|
-
topic?: string;
|
|
30
|
-
data: any;
|
|
31
|
-
clientId?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface WebSocketStats {
|
|
35
|
-
clients: number;
|
|
36
|
-
topics: Array<{
|
|
37
|
-
topic: string;
|
|
38
|
-
subscribers: number;
|
|
39
|
-
}>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface IWebSocketService {
|
|
43
|
-
sendToClient(clientId: string, message: any): boolean;
|
|
44
|
-
publishToTopic(topic: string, data: any, exclude?: string[]): void;
|
|
45
|
-
broadcast(message: any, excludeClientId?: string): void;
|
|
46
|
-
getStats(): { clients: number; topics: Array<{ topic: string; subscribers: number }> };
|
|
47
|
-
isAvailable(): boolean;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface IWebSocketServer {
|
|
51
|
-
sendToClient(clientId: string, message: any): boolean;
|
|
52
|
-
publishToTopic(topic: string, data: any, exclude: string[]): void;
|
|
53
|
-
broadcast(message: any, excludeClientId?: string): void;
|
|
54
|
-
getStats(): WebSocketStats;
|
|
55
|
-
subscribeToTopic(client: WebSocketClient, topic: string): void;
|
|
56
|
-
unsubscribeFromTopic(client: WebSocketClient, topic: string): void;
|
|
57
|
-
}
|
package/src/utils/controller.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { ControllerInstance, Middleware, ParamMetadata } from '@types';
|
|
2
|
-
import { MultipartProcessor } from '@utils';
|
|
3
|
-
import { WebSocketService } from '../app/http/websocket/WebsocetService';
|
|
4
|
-
import { validate } from './validate';
|
|
5
|
-
|
|
6
|
-
import { ENDPOINT, MIDDLEWARES, PARAM_METADATA_KEY, TO_VALIDATE, WS_SERVICE_KEY } from '@constants';
|
|
7
|
-
import { ServerResponse } from 'http';
|
|
8
|
-
|
|
9
|
-
const getBodyAndMultipart = (payload: any) => {
|
|
10
|
-
let body = payload.body;
|
|
11
|
-
let multipart;
|
|
12
|
-
if (MultipartProcessor.isMultipart({ headers: payload.headers })) {
|
|
13
|
-
try {
|
|
14
|
-
const { fields, files } = MultipartProcessor.parse({
|
|
15
|
-
body: payload.rawBody || payload.body,
|
|
16
|
-
headers: payload.headers,
|
|
17
|
-
isBase64Encoded: payload.isBase64Encoded,
|
|
18
|
-
});
|
|
19
|
-
multipart = files;
|
|
20
|
-
body = fields;
|
|
21
|
-
} catch (error) {
|
|
22
|
-
console.error('❌ Multipart parsing error:', error);
|
|
23
|
-
throw { status: 400, message: 'Invalid multipart data' };
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return { multipart, body };
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const executeControllerMethod = async (
|
|
31
|
-
controller: ControllerInstance,
|
|
32
|
-
propertyName: string,
|
|
33
|
-
payload: any,
|
|
34
|
-
response?: ServerResponse,
|
|
35
|
-
) => {
|
|
36
|
-
const fn = controller[propertyName];
|
|
37
|
-
if (typeof fn !== 'function') return null;
|
|
38
|
-
const endpointMeta = Reflect.getMetadata(ENDPOINT, controller, propertyName);
|
|
39
|
-
if (!endpointMeta) return null;
|
|
40
|
-
|
|
41
|
-
const methodMiddlewares: Middleware[] =
|
|
42
|
-
Reflect.getMetadata(MIDDLEWARES, controller, propertyName) || [];
|
|
43
|
-
|
|
44
|
-
for (let i = 0; i < methodMiddlewares.length; i++) {
|
|
45
|
-
const middleware = methodMiddlewares[i];
|
|
46
|
-
const result = await middleware(payload);
|
|
47
|
-
if (result) {
|
|
48
|
-
payload = { ...payload, ...result };
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const prototype = Object.getPrototypeOf(controller);
|
|
53
|
-
const paramMetadata: ParamMetadata[] =
|
|
54
|
-
Reflect.getMetadata(PARAM_METADATA_KEY, prototype, propertyName) || [];
|
|
55
|
-
|
|
56
|
-
const { body, multipart } = getBodyAndMultipart(payload);
|
|
57
|
-
if (paramMetadata.length === 0) {
|
|
58
|
-
return fn.call(controller, payload);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const args: any[] = [];
|
|
62
|
-
|
|
63
|
-
const wsParams = Reflect.getMetadata(WS_SERVICE_KEY, controller, propertyName) || [];
|
|
64
|
-
const totalParams = Math.max(
|
|
65
|
-
paramMetadata.length ? Math.max(...paramMetadata.map((p) => p.index)) + 1 : 0,
|
|
66
|
-
wsParams.length ? Math.max(...wsParams.map((p: any) => p.index)) + 1 : 0,
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
for (let i = 0; i < totalParams; i++) {
|
|
70
|
-
const wsParam = wsParams.find((p: any) => p.index === i);
|
|
71
|
-
if (wsParam) {
|
|
72
|
-
args[i] = WebSocketService.getInstance();
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const param = paramMetadata.find((p) => p.index === i);
|
|
77
|
-
if (!param) {
|
|
78
|
-
args[i] = undefined;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let value = param.name ? payload[param.type]?.[param.name] : payload[param.type];
|
|
83
|
-
|
|
84
|
-
if (param.type === 'multipart') {
|
|
85
|
-
value = multipart;
|
|
86
|
-
}
|
|
87
|
-
if (param.type === 'request') {
|
|
88
|
-
value = payload;
|
|
89
|
-
}
|
|
90
|
-
if (param.type === 'response') {
|
|
91
|
-
value = response;
|
|
92
|
-
}
|
|
93
|
-
if (param.type === 'response') {
|
|
94
|
-
value = response;
|
|
95
|
-
}
|
|
96
|
-
if (param.type === 'body') {
|
|
97
|
-
value = body;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (TO_VALIDATE.includes(param.type)) {
|
|
101
|
-
value = await validate(param.dto, value);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
args[i] = value;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return fn.apply(controller, args);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export const getControllerMethods = (controller: ControllerInstance) => {
|
|
111
|
-
const methods: Array<{
|
|
112
|
-
name: string;
|
|
113
|
-
httpMethod: string;
|
|
114
|
-
pattern: string;
|
|
115
|
-
middlewares?: Array<(req: any, res?: ServerResponse) => any>;
|
|
116
|
-
}> = [];
|
|
117
|
-
|
|
118
|
-
let proto = Object.getPrototypeOf(controller);
|
|
119
|
-
|
|
120
|
-
while (proto && proto !== Object.prototype) {
|
|
121
|
-
const propertyNames = Object.getOwnPropertyNames(proto);
|
|
122
|
-
for (const propertyName of propertyNames) {
|
|
123
|
-
if (propertyName === 'constructor') continue;
|
|
124
|
-
|
|
125
|
-
const endpointMeta = Reflect.getMetadata(ENDPOINT, proto, propertyName);
|
|
126
|
-
|
|
127
|
-
if (endpointMeta) {
|
|
128
|
-
const [httpMethod, pattern] = endpointMeta;
|
|
129
|
-
const methodMiddlewares = Reflect.getMetadata(MIDDLEWARES, proto, propertyName);
|
|
130
|
-
|
|
131
|
-
methods.push({
|
|
132
|
-
name: propertyName,
|
|
133
|
-
httpMethod,
|
|
134
|
-
pattern,
|
|
135
|
-
middlewares: methodMiddlewares,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
proto = Object.getPrototypeOf(proto);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return methods;
|
|
143
|
-
};
|
package/src/utils/helper.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
|
-
export const matchRoute = (routePattern: string, actualPath: string) => {
|
|
4
|
-
const routeParts = routePattern.split('/').filter(Boolean);
|
|
5
|
-
const pathParts = actualPath.split('/').filter(Boolean);
|
|
6
|
-
|
|
7
|
-
if (routeParts.length !== pathParts.length) return null;
|
|
8
|
-
|
|
9
|
-
const params: Record<string, string> = {};
|
|
10
|
-
|
|
11
|
-
for (let i = 0; i < routeParts.length; i++) {
|
|
12
|
-
const routePart = routeParts[i];
|
|
13
|
-
const pathPart = pathParts[i];
|
|
14
|
-
|
|
15
|
-
if (routePart.startsWith(':')) {
|
|
16
|
-
const paramName = routePart.slice(1);
|
|
17
|
-
params[paramName] = decodeURIComponent(pathPart);
|
|
18
|
-
} else if (routePart !== pathPart) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return params;
|
|
24
|
-
};
|
package/src/utils/index.ts
DELETED
package/src/utils/multipart.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
// utils/MultipartProcessor.ts
|
|
2
|
-
import * as multipart from 'parse-multipart-data';
|
|
3
|
-
|
|
4
|
-
export interface MultipartFile {
|
|
5
|
-
fieldname: string;
|
|
6
|
-
filename: string;
|
|
7
|
-
contentType: string;
|
|
8
|
-
data: Buffer;
|
|
9
|
-
size: number;
|
|
10
|
-
encoding?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class MultipartProcessor {
|
|
14
|
-
static parse(request: any): {
|
|
15
|
-
fields: Record<string, any>;
|
|
16
|
-
files: Record<string, MultipartFile | MultipartFile[]>;
|
|
17
|
-
} {
|
|
18
|
-
const { body, headers, isBase64Encoded } = request;
|
|
19
|
-
|
|
20
|
-
if (!body) {
|
|
21
|
-
return { fields: {}, files: {} };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
let contentType = headers['content-type'] ?? headers['Content-Type'] ?? '';
|
|
25
|
-
if (Array.isArray(contentType)) {
|
|
26
|
-
contentType = contentType[0];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!contentType.startsWith('multipart/form-data')) {
|
|
30
|
-
throw new Error('Not a multipart request');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const boundaryMatch = multipart.getBoundary(contentType);
|
|
34
|
-
if (!boundaryMatch) {
|
|
35
|
-
throw new Error('Invalid multipart boundary');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let bodyBuffer: Buffer;
|
|
39
|
-
if (Buffer.isBuffer(body)) {
|
|
40
|
-
bodyBuffer = body;
|
|
41
|
-
} else if (typeof body === 'string') {
|
|
42
|
-
bodyBuffer = isBase64Encoded ? Buffer.from(body, 'base64') : Buffer.from(body, 'binary');
|
|
43
|
-
} else {
|
|
44
|
-
bodyBuffer = Buffer.from(JSON.stringify(body));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const parts = multipart.parse(bodyBuffer, boundaryMatch);
|
|
48
|
-
|
|
49
|
-
const fields: Record<string, any> = {};
|
|
50
|
-
const files: Record<string, MultipartFile | MultipartFile[]> = {};
|
|
51
|
-
|
|
52
|
-
parts.forEach((part: any) => {
|
|
53
|
-
if (part.filename) {
|
|
54
|
-
const fieldName = part.name || 'file';
|
|
55
|
-
|
|
56
|
-
const fileData: MultipartFile = {
|
|
57
|
-
fieldname: fieldName,
|
|
58
|
-
filename: part.filename,
|
|
59
|
-
contentType: part.type,
|
|
60
|
-
data: part.data,
|
|
61
|
-
size: part.data.length,
|
|
62
|
-
encoding: part.encoding,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
if (files[fieldName]) {
|
|
66
|
-
if (Array.isArray(files[fieldName])) {
|
|
67
|
-
(files[fieldName] as MultipartFile[]).push(fileData);
|
|
68
|
-
} else {
|
|
69
|
-
files[fieldName] = [files[fieldName] as MultipartFile, fileData];
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
files[fieldName] = fileData;
|
|
73
|
-
}
|
|
74
|
-
} else if (part.name) {
|
|
75
|
-
const text = part.data.toString('utf-8').trim();
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
fields[part.name] = JSON.parse(text);
|
|
79
|
-
} catch {
|
|
80
|
-
fields[part.name] = text;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
return { fields, files };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
static isMultipart(request: any): boolean {
|
|
89
|
-
const contentType =
|
|
90
|
-
request.headers?.['content-type'] || request.headers?.['Content-Type'] || '';
|
|
91
|
-
return contentType.startsWith('multipart/form-data');
|
|
92
|
-
}
|
|
93
|
-
}
|