@xrystal/core 3.25.5 → 3.26.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/package.json
CHANGED
|
@@ -21,10 +21,12 @@ export class BaseController {
|
|
|
21
21
|
const req = store?.req || {};
|
|
22
22
|
const identityT = (k) => k;
|
|
23
23
|
const body = ctx.body || req.body || ctx.request?.body || {};
|
|
24
|
-
let query = ctx.query || req.query || {};
|
|
24
|
+
let query = ctx.query || req.query || ctx.request?.query || {};
|
|
25
25
|
const urlStr = ctx.url || req.url || ctx.request?.url || '';
|
|
26
|
-
if (Object.keys(query).length === 0 && typeof urlStr === 'string' && urlStr.includes('?')) {
|
|
27
|
-
|
|
26
|
+
if ((!query || Object.keys(query).length === 0) && typeof urlStr === 'string' && urlStr.includes('?')) {
|
|
27
|
+
const parts = urlStr.split('?');
|
|
28
|
+
if (parts[1])
|
|
29
|
+
query = qs.parse(parts[1]);
|
|
28
30
|
}
|
|
29
31
|
const params = {
|
|
30
32
|
...(req.params || {}),
|
|
@@ -37,7 +39,7 @@ export class BaseController {
|
|
|
37
39
|
method: ctx.method || req.method || ctx.request?.method || '',
|
|
38
40
|
headers: ctx.headers || req.headers || ctx.request?.headers || {},
|
|
39
41
|
body,
|
|
40
|
-
query,
|
|
42
|
+
query: query || {},
|
|
41
43
|
params,
|
|
42
44
|
lang: ctx.lang || req.lang || 'en',
|
|
43
45
|
t: ctx.t || req.t || identityT,
|
|
@@ -104,41 +106,106 @@ export default class Controller extends BaseController {
|
|
|
104
106
|
return isError ? responseMessageHelper.unsuccessful(p1, p2, t) : responseMessageHelper.successfully(p1, p2, t);
|
|
105
107
|
}
|
|
106
108
|
async schema({ checks, logic, response }) {
|
|
107
|
-
const currentReq = this.req;
|
|
108
109
|
const currentRes = this.res;
|
|
109
110
|
const store = this.currentStore;
|
|
110
111
|
try {
|
|
111
|
-
let parsedBody = currentReq.body;
|
|
112
112
|
const rawReq = store?.req || store?.ctx?.request || store?.ctx?.req;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
let parsedBody = this.req.body;
|
|
114
|
+
let parsedQuery = this.req.query;
|
|
115
|
+
const contentType = (this.req.headers['content-type'] || '').toLowerCase();
|
|
116
|
+
const consumeBody = async (bodySource) => {
|
|
117
|
+
let text = '';
|
|
118
|
+
if (bodySource instanceof ReadableStream || (bodySource && typeof bodySource.getReader === 'function')) {
|
|
119
|
+
text = await new Response(bodySource).text();
|
|
116
120
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
else if (typeof bodySource === 'string') {
|
|
122
|
+
text = bodySource;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return bodySource;
|
|
126
|
+
}
|
|
127
|
+
if (!text)
|
|
128
|
+
return {};
|
|
129
|
+
if (contentType.includes('application/json')) {
|
|
130
|
+
try {
|
|
131
|
+
return JSON.parse(text);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return text;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
138
|
+
return qs.parse(text);
|
|
123
139
|
}
|
|
124
|
-
|
|
140
|
+
else {
|
|
125
141
|
try {
|
|
126
|
-
|
|
142
|
+
return JSON.parse(text);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
127
145
|
try {
|
|
128
|
-
|
|
146
|
+
return qs.parse(text);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return text;
|
|
129
150
|
}
|
|
130
|
-
catch (e) { }
|
|
131
151
|
}
|
|
132
|
-
|
|
133
|
-
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
if (this.protocol !== ProtocolEnum.WEBSOCKET) {
|
|
155
|
+
const isStream = parsedBody instanceof ReadableStream || (parsedBody && typeof parsedBody.getReader === 'function');
|
|
156
|
+
const isProcessed = !isStream && parsedBody && typeof parsedBody === 'object' && Object.keys(parsedBody).length > 0 && parsedBody.constructor?.name !== 'ReadableStream';
|
|
157
|
+
if (!isProcessed) {
|
|
158
|
+
if (isStream || typeof parsedBody === 'string') {
|
|
159
|
+
parsedBody = await consumeBody(parsedBody);
|
|
160
|
+
}
|
|
161
|
+
else if (rawReq) {
|
|
162
|
+
if (typeof rawReq.json === 'function') {
|
|
163
|
+
try {
|
|
164
|
+
const cloned = rawReq.clone ? rawReq.clone() : rawReq;
|
|
165
|
+
parsedBody = await consumeBody(await cloned.text());
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
parsedBody = {};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (typeof rawReq.on === 'function') {
|
|
172
|
+
parsedBody = await new Promise((resolve) => {
|
|
173
|
+
let bodyStr = '';
|
|
174
|
+
rawReq.on('data', (chunk) => { bodyStr += chunk; });
|
|
175
|
+
rawReq.on('end', async () => resolve(await consumeBody(bodyStr)));
|
|
176
|
+
rawReq.on('error', () => resolve({}));
|
|
177
|
+
});
|
|
178
|
+
}
|
|
134
179
|
}
|
|
135
180
|
}
|
|
136
181
|
}
|
|
137
|
-
else if (
|
|
182
|
+
else if (typeof parsedBody === 'string') {
|
|
183
|
+
try {
|
|
184
|
+
parsedBody = JSON.parse(parsedBody);
|
|
185
|
+
}
|
|
186
|
+
catch { }
|
|
187
|
+
}
|
|
188
|
+
if (parsedBody && typeof parsedBody === 'object' && parsedBody.constructor?.name === 'FormData') {
|
|
138
189
|
parsedBody = Object.fromEntries(parsedBody.entries());
|
|
139
190
|
}
|
|
140
|
-
|
|
141
|
-
const
|
|
191
|
+
const finalBody = parsedBody || {};
|
|
192
|
+
const finalQuery = parsedQuery || {};
|
|
193
|
+
if (store) {
|
|
194
|
+
if (store.ctx) {
|
|
195
|
+
store.ctx.body = finalBody;
|
|
196
|
+
store.ctx.query = finalQuery;
|
|
197
|
+
}
|
|
198
|
+
if (store.req) {
|
|
199
|
+
store.req.body = finalBody;
|
|
200
|
+
store.req.query = finalQuery;
|
|
201
|
+
}
|
|
202
|
+
if (store.ctx?.request) {
|
|
203
|
+
store.ctx.request.body = finalBody;
|
|
204
|
+
store.ctx.request.query = finalQuery;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const currentReq = this.req;
|
|
208
|
+
const p = { req: currentReq, res: currentRes, body: currentReq.body, query: currentReq.query, params: currentReq.params, t: currentReq.t, accounts: currentReq.accounts };
|
|
142
209
|
const extractMeta = (obj) => {
|
|
143
210
|
if (!obj || typeof obj !== 'object')
|
|
144
211
|
return;
|
|
@@ -220,7 +287,7 @@ export default class Controller extends BaseController {
|
|
|
220
287
|
}
|
|
221
288
|
catch (error) {
|
|
222
289
|
this.logger?.log(LoggerLayerEnum.ERROR, `Controller Error: ${error.message}`);
|
|
223
|
-
const t =
|
|
290
|
+
const t = this.req?.t || ((k) => k);
|
|
224
291
|
return this.res.status(500).send(new ResponseSchema({ status: false, message: this.parseMessage(error.message, t, true), code: 500 }).getResponse);
|
|
225
292
|
}
|
|
226
293
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const toExpress: (action: () => Promise<any>) => (req: any, res: any, next: any) => Promise<any>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { controllerContextStorage } from "source/loader/controller";
|
|
2
|
+
import { ProtocolEnum } from "source/utils/models";
|
|
3
|
+
// => Use case - app.post('/example', toExpress(() => exampleCtrl.example()))
|
|
4
|
+
export const toExpress = (action) => async (req, res, next) => {
|
|
5
|
+
try {
|
|
6
|
+
const result = await controllerContextStorage.run({
|
|
7
|
+
req,
|
|
8
|
+
res,
|
|
9
|
+
protocol: ProtocolEnum.HTTP,
|
|
10
|
+
metadata: { locals: res.locals || {} }
|
|
11
|
+
}, action);
|
|
12
|
+
if (result instanceof Response) {
|
|
13
|
+
res.status(result.status);
|
|
14
|
+
result.headers.forEach((v, k) => res.setHeader(k, v));
|
|
15
|
+
const contentType = result.headers.get('content-type') || '';
|
|
16
|
+
if (contentType.includes('application/json') || contentType.includes('text/')) {
|
|
17
|
+
return res.send(await result.text());
|
|
18
|
+
}
|
|
19
|
+
return res.send(Buffer.from(await result.arrayBuffer()));
|
|
20
|
+
}
|
|
21
|
+
return res.send(result);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
next(e);
|
|
25
|
+
}
|
|
26
|
+
};
|