@xrystal/core 3.23.1 → 3.23.3
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
|
@@ -49,11 +49,9 @@ export declare abstract class BaseController {
|
|
|
49
49
|
export default abstract class Controller extends BaseController implements IProvide<any> {
|
|
50
50
|
constructor();
|
|
51
51
|
onInit(): Promise<void>;
|
|
52
|
-
|
|
53
|
-
private parseMessage;
|
|
54
|
-
schema<T = any>({ checks, logic, response }: {
|
|
52
|
+
schema({ checks, logic, response }: {
|
|
55
53
|
checks?: (args: any) => Promise<any>;
|
|
56
|
-
logic?: (args: any) => Promise<
|
|
54
|
+
logic?: (args: any) => Promise<any>;
|
|
57
55
|
response?: (args: any) => Promise<any>;
|
|
58
56
|
}): Promise<any>;
|
|
59
57
|
}
|
|
@@ -64,13 +62,12 @@ export interface CustomRequest {
|
|
|
64
62
|
headers: Record<string, any>;
|
|
65
63
|
body?: any;
|
|
66
64
|
params: Record<string, any>;
|
|
67
|
-
query: any
|
|
65
|
+
query: Record<string, any>;
|
|
68
66
|
lang: string;
|
|
69
67
|
t: (k: string, args?: any) => string;
|
|
70
68
|
}
|
|
71
69
|
export interface CustomResponse {
|
|
72
70
|
status: (code: number) => CustomResponse;
|
|
73
|
-
setRaw: (isRaw?: boolean) => CustomResponse;
|
|
74
71
|
send: (data: any) => any;
|
|
75
72
|
json: (data: any) => any;
|
|
76
73
|
locals: Record<string, any>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import qs from 'qs';
|
|
2
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
2
|
import Logger from '../logger';
|
|
4
3
|
import System from '../system';
|
|
@@ -9,23 +8,26 @@ export class BaseController {
|
|
|
9
8
|
system = x.get(System);
|
|
10
9
|
logger = x.get(Logger);
|
|
11
10
|
supportedProtocols = [ProtocolEnum.HTTP, ProtocolEnum.WEBSOCKET];
|
|
12
|
-
get protocol() {
|
|
13
|
-
|
|
11
|
+
get protocol() {
|
|
12
|
+
return this.currentStore?.protocol || ProtocolEnum.HTTP;
|
|
13
|
+
}
|
|
14
|
+
get currentStore() {
|
|
15
|
+
return getControllerCtx();
|
|
16
|
+
}
|
|
14
17
|
get req() {
|
|
15
18
|
const store = this.currentStore;
|
|
16
19
|
const identityT = (k) => k;
|
|
17
20
|
const ctx = store?.ctx || {};
|
|
18
|
-
const query = typeof ctx.query === 'string' ? qs.parse(ctx.query) : (ctx.query || {});
|
|
19
21
|
return {
|
|
20
22
|
url: ctx.url || '',
|
|
21
23
|
method: ctx.method || '',
|
|
22
24
|
headers: ctx.headers || {},
|
|
23
25
|
body: ctx.body || {},
|
|
24
|
-
query: query,
|
|
26
|
+
query: ctx.query || {},
|
|
25
27
|
params: ctx.params || {},
|
|
26
28
|
lang: ctx.lang || 'en',
|
|
27
29
|
t: ctx.t || identityT,
|
|
28
|
-
accounts: ctx.accounts ||
|
|
30
|
+
accounts: ctx.accounts || store?.req?.accounts
|
|
29
31
|
};
|
|
30
32
|
}
|
|
31
33
|
get res() {
|
|
@@ -35,7 +37,6 @@ export class BaseController {
|
|
|
35
37
|
status: function () { return this; },
|
|
36
38
|
send: (d) => d,
|
|
37
39
|
json: function (d) { return this.send(d); },
|
|
38
|
-
setRaw: function () { return this; },
|
|
39
40
|
locals: {}
|
|
40
41
|
};
|
|
41
42
|
if (!store)
|
|
@@ -48,133 +49,120 @@ export class BaseController {
|
|
|
48
49
|
store.metadata._code = code;
|
|
49
50
|
return this;
|
|
50
51
|
},
|
|
51
|
-
setRaw(isRaw = true) {
|
|
52
|
-
store.metadata._isRaw = isRaw;
|
|
53
|
-
return this;
|
|
54
|
-
},
|
|
55
52
|
send(data) {
|
|
56
53
|
if (self.protocol === ProtocolEnum.WEBSOCKET)
|
|
57
54
|
return data;
|
|
58
55
|
if (data instanceof Response)
|
|
59
56
|
return data;
|
|
60
|
-
const
|
|
61
|
-
const isRaw = store.metadata?._isRaw;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const isBinary = data instanceof Blob || data instanceof Uint8Array || data instanceof ArrayBuffer;
|
|
58
|
+
const isRaw = store.metadata?._isRaw || isBinary;
|
|
59
|
+
let contentType = store.metadata?._contentType;
|
|
60
|
+
if (!contentType) {
|
|
61
|
+
contentType = isRaw ? 'application/octet-stream' : 'application/json';
|
|
65
62
|
}
|
|
66
|
-
const
|
|
67
|
-
|
|
63
|
+
const status = store.metadata?._code || 200;
|
|
64
|
+
const body = isRaw || typeof data === 'string'
|
|
65
|
+
? data
|
|
66
|
+
: JSON.stringify(data?.getResponse ? data.getResponse : data);
|
|
67
|
+
return new Response(body, {
|
|
68
|
+
status,
|
|
69
|
+
headers: { 'content-type': contentType }
|
|
70
|
+
});
|
|
68
71
|
},
|
|
69
72
|
json(data) { return this.send(data); }
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
export default class Controller extends BaseController {
|
|
74
|
-
constructor() {
|
|
77
|
+
constructor() {
|
|
78
|
+
super();
|
|
79
|
+
}
|
|
75
80
|
async onInit() {
|
|
76
81
|
const protocols = this.system?.tmp?.configs?.loaders?.controller?.protocols;
|
|
77
82
|
this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols || ProtocolEnum.HTTP];
|
|
78
83
|
}
|
|
79
|
-
smartTranslate(word, t) {
|
|
80
|
-
const keyPath = `keywords.${word}`;
|
|
81
|
-
const translated = t(keyPath);
|
|
82
|
-
if (translated !== keyPath)
|
|
83
|
-
return translated;
|
|
84
|
-
const direct = t(word);
|
|
85
|
-
return direct !== word ? direct : word;
|
|
86
|
-
}
|
|
87
|
-
parseMessage(input, t) {
|
|
88
|
-
if (!input || typeof input !== 'string' || !input.startsWith('@'))
|
|
89
|
-
return input;
|
|
90
|
-
const parts = input.substring(1).split(' ').filter(p => p !== '');
|
|
91
|
-
const maybeMethod = parts[0];
|
|
92
|
-
const hasMethod = typeof responseMessageHelper[maybeMethod] === 'function';
|
|
93
|
-
const methodName = hasMethod ? maybeMethod : 'successfully';
|
|
94
|
-
const rawArgs = hasMethod ? parts.slice(1) : parts;
|
|
95
|
-
const translatedArgs = rawArgs.map(arg => this.smartTranslate(arg, t));
|
|
96
|
-
return responseMessageHelper[methodName](translatedArgs[0] || '', translatedArgs.slice(1).join(' '), t);
|
|
97
|
-
}
|
|
98
84
|
async schema({ checks, logic, response }) {
|
|
99
85
|
try {
|
|
100
86
|
const currentReq = this.req;
|
|
101
|
-
const
|
|
102
|
-
const t = currentReq.t;
|
|
87
|
+
const currentRes = this.res;
|
|
103
88
|
const p = {
|
|
104
89
|
req: currentReq,
|
|
105
|
-
res:
|
|
90
|
+
res: currentRes,
|
|
106
91
|
body: currentReq.body,
|
|
107
92
|
query: currentReq.query,
|
|
108
93
|
params: currentReq.params,
|
|
109
|
-
|
|
110
|
-
t
|
|
94
|
+
t: currentReq.t
|
|
111
95
|
};
|
|
112
96
|
if (checks) {
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
const rawMsg = isObj ? checkRes.message : (typeof checkRes === 'string' ? checkRes : '@schemaMissingDataChecks');
|
|
118
|
-
const { message: _m, status: _s, code: _c, data, payload, ...rest } = isObj ? checkRes : {};
|
|
119
|
-
const errCoreData = data ?? payload ?? (Object.keys(rest).length > 0 ? rest : undefined);
|
|
120
|
-
const errRes = {
|
|
97
|
+
const checkResult = await checks(p);
|
|
98
|
+
if (checkResult === false || (checkResult && typeof checkResult === 'object' && !Array.isArray(checkResult))) {
|
|
99
|
+
const checkCode = checkResult?.code || 400;
|
|
100
|
+
return currentRes.status(checkCode).send(new ResponseSchema({
|
|
121
101
|
status: false,
|
|
122
|
-
message:
|
|
123
|
-
code
|
|
124
|
-
};
|
|
125
|
-
if (errCoreData !== undefined) {
|
|
126
|
-
errRes.payload = { data: errCoreData };
|
|
127
|
-
}
|
|
128
|
-
return this.res.status(code).send(new ResponseSchema(errRes).getResponse);
|
|
102
|
+
message: checkResult?.message || '',
|
|
103
|
+
code: checkCode
|
|
104
|
+
}).getResponse);
|
|
129
105
|
}
|
|
130
106
|
}
|
|
131
|
-
let
|
|
132
|
-
if (
|
|
133
|
-
|
|
107
|
+
let logicResult = logic ? await logic(p) : null;
|
|
108
|
+
if (logicResult && typeof logicResult === 'object' && typeof logicResult.response === 'function') {
|
|
109
|
+
logicResult = await logicResult.response();
|
|
110
|
+
}
|
|
111
|
+
if (logicResult instanceof Response || (logicResult?.constructor?.name === 'Response')) {
|
|
112
|
+
return logicResult;
|
|
113
|
+
}
|
|
114
|
+
if (logicResult?.status === false) {
|
|
115
|
+
const errorCode = logicResult.code || 400;
|
|
116
|
+
return currentRes.status(errorCode).send(new ResponseSchema({
|
|
117
|
+
status: false,
|
|
118
|
+
message: logicResult.message || '',
|
|
119
|
+
code: errorCode
|
|
120
|
+
}).getResponse);
|
|
121
|
+
}
|
|
122
|
+
const resResult = response ? await response({ ...p, logicResult }) : logicResult;
|
|
123
|
+
if (resResult instanceof Response || (resResult?.constructor?.name === 'Response')) {
|
|
124
|
+
return resResult;
|
|
134
125
|
}
|
|
135
|
-
let
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (finalRes && typeof finalRes === 'object' && !Array.isArray(finalRes)) {
|
|
148
|
-
const { message: _m, status: _s, code: _co, data, payload, ...rest } = finalRes;
|
|
149
|
-
coreData = data ?? payload;
|
|
150
|
-
if (coreData === undefined) {
|
|
151
|
-
coreData = Object.keys(rest).length > 0 ? rest : logicRes;
|
|
126
|
+
let finalMessage = '';
|
|
127
|
+
let rawMessageValue = '';
|
|
128
|
+
const messageSource = resResult?.message || (typeof resResult === 'string' || Array.isArray(resResult) ? resResult : '');
|
|
129
|
+
if (Array.isArray(messageSource)) {
|
|
130
|
+
finalMessage = responseMessageHelper.successFully(messageSource[0], messageSource[1], currentReq.t);
|
|
131
|
+
rawMessageValue = messageSource[0];
|
|
132
|
+
}
|
|
133
|
+
else if (typeof messageSource === 'string' && messageSource !== '') {
|
|
134
|
+
if (messageSource.startsWith('@')) {
|
|
135
|
+
const cleanMsg = messageSource.substring(1);
|
|
136
|
+
finalMessage = currentReq.t(cleanMsg, {});
|
|
137
|
+
rawMessageValue = cleanMsg;
|
|
152
138
|
}
|
|
153
139
|
else {
|
|
154
|
-
|
|
140
|
+
finalMessage = responseMessageHelper.successFully(messageSource, '', currentReq.t);
|
|
141
|
+
rawMessageValue = messageSource;
|
|
155
142
|
}
|
|
156
143
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
code: finalCode
|
|
164
|
-
};
|
|
165
|
-
const payloadContainer = {};
|
|
166
|
-
if (coreData !== undefined && coreData !== null)
|
|
167
|
-
payloadContainer.data = coreData;
|
|
168
|
-
if (Object.keys(extraData).length > 0)
|
|
169
|
-
payloadContainer.extraData = extraData;
|
|
170
|
-
if (Object.keys(payloadContainer).length > 0) {
|
|
171
|
-
responseData.payload = payloadContainer;
|
|
144
|
+
let finalPayload = undefined;
|
|
145
|
+
if (logic) {
|
|
146
|
+
finalPayload = logicResult?.payload !== undefined ? logicResult.payload : logicResult;
|
|
147
|
+
if (finalPayload === messageSource || (finalPayload && typeof finalPayload === 'object' && (finalPayload.message === rawMessageValue || finalPayload.message === finalMessage))) {
|
|
148
|
+
finalPayload = undefined;
|
|
149
|
+
}
|
|
172
150
|
}
|
|
173
|
-
|
|
151
|
+
const successCode = this.currentStore?.metadata?._code || 200;
|
|
152
|
+
return currentRes.status(successCode).send(new ResponseSchema({
|
|
153
|
+
status: true,
|
|
154
|
+
message: finalMessage,
|
|
155
|
+
...(finalPayload && { payload: finalPayload }),
|
|
156
|
+
code: successCode
|
|
157
|
+
}).getResponse);
|
|
174
158
|
}
|
|
175
159
|
catch (error) {
|
|
176
160
|
this.logger?.log(LoggerLayerEnum.ERROR, `Controller Error: ${error.message}`);
|
|
177
|
-
return this.res.status(500).send(new ResponseSchema({
|
|
161
|
+
return this.res.status(500).send(new ResponseSchema({
|
|
162
|
+
status: false,
|
|
163
|
+
message: error.message,
|
|
164
|
+
code: 500
|
|
165
|
+
}).getResponse);
|
|
178
166
|
}
|
|
179
167
|
}
|
|
180
168
|
}
|