@xrystal/core 3.16.4 → 3.16.8
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/package.json
CHANGED
|
@@ -5,14 +5,24 @@ export declare const controllerContextStorage: AsyncLocalStorage<{
|
|
|
5
5
|
ctx?: any;
|
|
6
6
|
req?: any;
|
|
7
7
|
res?: any;
|
|
8
|
-
metadata?:
|
|
8
|
+
metadata?: {
|
|
9
|
+
locals: Record<string, any>;
|
|
10
|
+
_code?: number;
|
|
11
|
+
_contentType?: string;
|
|
12
|
+
_isRaw?: boolean;
|
|
13
|
+
};
|
|
9
14
|
}>;
|
|
10
15
|
export declare const getControllerCtx: () => {
|
|
11
16
|
protocol?: ProtocolEnum;
|
|
12
17
|
ctx?: any;
|
|
13
18
|
req?: any;
|
|
14
19
|
res?: any;
|
|
15
|
-
metadata?:
|
|
20
|
+
metadata?: {
|
|
21
|
+
locals: Record<string, any>;
|
|
22
|
+
_code?: number;
|
|
23
|
+
_contentType?: string;
|
|
24
|
+
_isRaw?: boolean;
|
|
25
|
+
};
|
|
16
26
|
};
|
|
17
27
|
export interface CustomRequest {
|
|
18
28
|
accounts?: any;
|
|
@@ -22,7 +32,8 @@ export interface CustomRequest {
|
|
|
22
32
|
body?: any;
|
|
23
33
|
params: Record<string, any>;
|
|
24
34
|
query: Record<string, any>;
|
|
25
|
-
|
|
35
|
+
lang: string;
|
|
36
|
+
t: (k: string, args?: any) => string;
|
|
26
37
|
}
|
|
27
38
|
export interface CustomResponse {
|
|
28
39
|
status: (code: number) => CustomResponse;
|
|
@@ -34,20 +45,25 @@ declare abstract class Controller {
|
|
|
34
45
|
protected loggerService: any;
|
|
35
46
|
protected supportedProtocols: ProtocolEnum[];
|
|
36
47
|
constructor({ loggerService }: any);
|
|
48
|
+
protected get protocol(): ProtocolEnum;
|
|
37
49
|
protected get currentStore(): {
|
|
38
50
|
protocol?: ProtocolEnum;
|
|
39
51
|
ctx?: any;
|
|
40
52
|
req?: any;
|
|
41
53
|
res?: any;
|
|
42
|
-
metadata?:
|
|
54
|
+
metadata?: {
|
|
55
|
+
locals: Record<string, any>;
|
|
56
|
+
_code?: number;
|
|
57
|
+
_contentType?: string;
|
|
58
|
+
_isRaw?: boolean;
|
|
59
|
+
};
|
|
43
60
|
};
|
|
44
|
-
protected get protocol(): ProtocolEnum;
|
|
45
61
|
protected get req(): CustomRequest;
|
|
46
62
|
protected get res(): CustomResponse;
|
|
47
|
-
protected responseProtocolSwitch: ({ res, resStatus, context }: any) => Promise<any>;
|
|
48
63
|
protected parsedQuerys: (url: string) => Record<string, any>;
|
|
49
64
|
}
|
|
50
65
|
export declare abstract class ControllerService extends Controller {
|
|
66
|
+
constructor({ loggerService }: any);
|
|
51
67
|
load(props?: {
|
|
52
68
|
type?: ProtocolEnum | ProtocolEnum[];
|
|
53
69
|
}): Promise<void>;
|
|
@@ -9,86 +9,79 @@ class Controller {
|
|
|
9
9
|
constructor({ loggerService }) {
|
|
10
10
|
this.loggerService = loggerService;
|
|
11
11
|
}
|
|
12
|
-
get currentStore() { return getControllerCtx(); }
|
|
13
12
|
get protocol() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return incomingProtocol;
|
|
13
|
+
return this.currentStore?.protocol || ProtocolEnum.HTTP;
|
|
14
|
+
}
|
|
15
|
+
get currentStore() {
|
|
16
|
+
return getControllerCtx();
|
|
19
17
|
}
|
|
20
18
|
get req() {
|
|
21
19
|
const store = this.currentStore;
|
|
22
20
|
const identityT = (k) => k;
|
|
23
21
|
if (!store)
|
|
24
|
-
return { url: '', method: '', headers: {}, params: {}, query: {}, t: identityT };
|
|
22
|
+
return { url: '', method: '', headers: {}, params: {}, query: {}, lang: 'en', t: identityT };
|
|
25
23
|
const { ctx, req: nativeReq } = store;
|
|
26
|
-
const
|
|
24
|
+
const source = nativeReq || ctx?.request || ctx;
|
|
27
25
|
return {
|
|
28
|
-
url:
|
|
29
|
-
method:
|
|
30
|
-
headers:
|
|
31
|
-
? Object.fromEntries(
|
|
32
|
-
: (
|
|
33
|
-
body: ctx?.body || nativeReq?.body,
|
|
34
|
-
params: ctx?.params || nativeReq?.params || {},
|
|
35
|
-
query: ctx?.query || nativeReq?.query || {},
|
|
36
|
-
accounts: ctx?.user ||
|
|
37
|
-
|
|
26
|
+
url: source?.url || '',
|
|
27
|
+
method: source?.method || 'GET',
|
|
28
|
+
headers: source?.headers && typeof source.headers.entries === 'function'
|
|
29
|
+
? Object.fromEntries(source.headers.entries())
|
|
30
|
+
: (source?.headers || {}),
|
|
31
|
+
body: ctx?.body || nativeReq?.body || source?.body,
|
|
32
|
+
params: ctx?.params || nativeReq?.params || source?.params || {},
|
|
33
|
+
query: ctx?.query || nativeReq?.query || source?.query || {},
|
|
34
|
+
accounts: ctx?.user || nativeReq?.accounts || source?.accounts,
|
|
35
|
+
lang: ctx?.lang || nativeReq?.lang || 'en',
|
|
36
|
+
t: ctx?.t || nativeReq?.t || identityT
|
|
38
37
|
};
|
|
39
38
|
}
|
|
40
39
|
get res() {
|
|
41
40
|
const store = this.currentStore;
|
|
41
|
+
const self = this;
|
|
42
42
|
const fallbackRes = {
|
|
43
43
|
status: function () { return this; },
|
|
44
|
-
send: (d) =>
|
|
44
|
+
send: (d) => d instanceof Response ? d : new Response(JSON.stringify(d), { status: 500 }),
|
|
45
45
|
json: function (d) { return this.send(d); },
|
|
46
46
|
locals: {}
|
|
47
47
|
};
|
|
48
48
|
if (!store)
|
|
49
49
|
return fallbackRes;
|
|
50
|
-
if (store.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return store.res || fallbackRes;
|
|
50
|
+
if (!store.metadata)
|
|
51
|
+
store.metadata = { locals: {} };
|
|
52
|
+
return {
|
|
53
|
+
get locals() { return store.metadata.locals; },
|
|
54
|
+
status(code) {
|
|
55
|
+
store.metadata._code = code;
|
|
56
|
+
return this;
|
|
57
|
+
},
|
|
58
|
+
send(data) {
|
|
59
|
+
if (self.protocol === ProtocolEnum.WEBSOCKET)
|
|
60
|
+
return data;
|
|
61
|
+
if (data instanceof Response)
|
|
62
|
+
return data;
|
|
63
|
+
const isBinary = data instanceof Blob || data instanceof Uint8Array || data instanceof ArrayBuffer;
|
|
64
|
+
const isRaw = store.metadata?._isRaw || isBinary;
|
|
65
|
+
let contentType = store.metadata?._contentType;
|
|
66
|
+
if (!contentType) {
|
|
67
|
+
contentType = isRaw ? 'application/octet-stream' : 'application/json';
|
|
68
|
+
}
|
|
69
|
+
const status = store.metadata?._code || 200;
|
|
70
|
+
const body = isRaw || typeof data === 'string'
|
|
71
|
+
? data
|
|
72
|
+
: JSON.stringify(data?.getResponse ? data.getResponse : data);
|
|
73
|
+
return new Response(body, {
|
|
74
|
+
status,
|
|
75
|
+
headers: { 'content-type': contentType }
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
json(data) { return this.send(data); }
|
|
79
|
+
};
|
|
83
80
|
}
|
|
84
|
-
responseProtocolSwitch = async ({ res, resStatus = 200, context }) => {
|
|
85
|
-
const responseData = context({ localeLanguageConverter: this.req?.t });
|
|
86
|
-
return res.status(resStatus).send(responseData);
|
|
87
|
-
};
|
|
88
81
|
parsedQuerys = (url) => {
|
|
89
82
|
try {
|
|
90
|
-
const
|
|
91
|
-
return
|
|
83
|
+
const queryPart = url.split('?')[1];
|
|
84
|
+
return queryPart ? qs.parse(queryPart, { decoder: decodeURIComponent }) : {};
|
|
92
85
|
}
|
|
93
86
|
catch {
|
|
94
87
|
return {};
|
|
@@ -96,43 +89,49 @@ class Controller {
|
|
|
96
89
|
};
|
|
97
90
|
}
|
|
98
91
|
export class ControllerService extends Controller {
|
|
92
|
+
constructor({ loggerService }) {
|
|
93
|
+
super({ loggerService });
|
|
94
|
+
}
|
|
99
95
|
async load(props = {}) {
|
|
100
96
|
if (props.type)
|
|
101
97
|
this.supportedProtocols = Array.isArray(props.type) ? props.type : [props.type];
|
|
102
98
|
}
|
|
103
99
|
async schema({ checks, logic, response }) {
|
|
104
100
|
try {
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const payload = { req: currentReq, res: currentRes };
|
|
110
|
-
const convertedPayload = { ...payload, parsedQuerys: this.parsedQuerys(currentReq.url) };
|
|
101
|
+
const req = this.req;
|
|
102
|
+
const res = this.res;
|
|
103
|
+
const payload = { req, res };
|
|
104
|
+
const convertedPayload = { ...payload, query: this.parsedQuerys(req.url) };
|
|
111
105
|
if (checks) {
|
|
112
106
|
const checkResult = await checks({ payload, convertedPayload });
|
|
113
|
-
if (checkResult
|
|
114
|
-
return
|
|
107
|
+
if (checkResult) {
|
|
108
|
+
return res.status(checkResult.code || 400).send(new ResponseSchema(checkResult).getResponse);
|
|
115
109
|
}
|
|
116
110
|
}
|
|
117
111
|
const logicResult = await logic({ payload, convertedPayload });
|
|
118
112
|
if (logicResult?.response instanceof Function)
|
|
119
113
|
return logicResult.response(logicResult.payload);
|
|
120
|
-
if (logicResult
|
|
121
|
-
return
|
|
122
|
-
}
|
|
114
|
+
if (logicResult instanceof Response)
|
|
115
|
+
return logicResult;
|
|
123
116
|
if (response) {
|
|
124
117
|
const resResult = await response({ payload, convertedPayload, logicResult });
|
|
125
118
|
const successObj = {
|
|
126
119
|
status: true,
|
|
127
|
-
message: Array.isArray(resResult.message)
|
|
128
|
-
|
|
120
|
+
message: Array.isArray(resResult.message)
|
|
121
|
+
? responseMessageHelper.successFully(resResult.message[0], resResult.message[1], req.lang)
|
|
122
|
+
: resResult.message,
|
|
123
|
+
payload: logicResult?.payload !== undefined ? logicResult.payload : logicResult
|
|
129
124
|
};
|
|
130
|
-
return
|
|
125
|
+
return res.status(200).send(new ResponseSchema(successObj).getResponse);
|
|
131
126
|
}
|
|
132
|
-
return
|
|
127
|
+
return res.send(logicResult?.payload !== undefined ? logicResult.payload : logicResult);
|
|
133
128
|
}
|
|
134
129
|
catch (error) {
|
|
135
|
-
|
|
130
|
+
this.loggerService.error(`Controller Error: ${error.message}`, { stack: error.stack });
|
|
131
|
+
return this.res.status(500).send({
|
|
132
|
+
status: false,
|
|
133
|
+
message: error.message || "Internal Server Error"
|
|
134
|
+
});
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
}
|