@xrystal/core 3.23.2 → 3.23.4

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "author": "Yusuf Yasir KAYGUSUZ",
3
3
  "name": "@xrystal/core",
4
- "version": "3.23.2",
4
+ "version": "3.23.4",
5
5
  "description": "Project core for xrystal",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -50,9 +50,9 @@ export default abstract class Controller extends BaseController implements IProv
50
50
  constructor();
51
51
  onInit(): Promise<void>;
52
52
  private parseMessage;
53
- schema<T = any>({ checks, logic, response }: {
53
+ schema({ checks, logic, response }: {
54
54
  checks?: (args: any) => Promise<any>;
55
- logic?: (args: any) => Promise<T | boolean | string | any[]>;
55
+ logic?: (args: any) => Promise<any>;
56
56
  response?: (args: any) => Promise<any>;
57
57
  }): Promise<any>;
58
58
  }
@@ -9,17 +9,31 @@ export class BaseController {
9
9
  system = x.get(System);
10
10
  logger = x.get(Logger);
11
11
  supportedProtocols = [ProtocolEnum.HTTP, ProtocolEnum.WEBSOCKET];
12
- get protocol() { return this.currentStore?.protocol || ProtocolEnum.HTTP; }
13
- get currentStore() { return getControllerCtx(); }
12
+ get protocol() {
13
+ return this.currentStore?.protocol || ProtocolEnum.HTTP;
14
+ }
15
+ get currentStore() {
16
+ return getControllerCtx();
17
+ }
14
18
  get req() {
15
19
  const store = this.currentStore;
16
20
  const ctx = store?.ctx || {};
17
- const query = typeof ctx.query === 'string' ? qs.parse(ctx.query) : (ctx.query || {});
21
+ const req = store?.req || {};
22
+ const identityT = (k) => k;
23
+ const body = ctx.body || req.body || {};
24
+ const query = ctx.query || req.query || (typeof req.url === 'string' && req.url.includes('?') ? qs.parse(req.url.split('?')[1]) : {});
25
+ const params = ctx.params || req.params || {};
26
+ const headers = ctx.headers || req.headers || {};
18
27
  return {
19
- url: ctx.url || '', method: ctx.method || '', headers: ctx.headers || {},
20
- body: ctx.body || {}, query: query, params: ctx.params || {},
21
- lang: ctx.lang || 'en', t: ctx.t || ((k) => k),
22
- accounts: ctx.accounts || store?.req?.accounts
28
+ url: ctx.url || req.url || '',
29
+ method: ctx.method || req.method || '',
30
+ headers,
31
+ body,
32
+ query,
33
+ params,
34
+ lang: ctx.lang || req.lang || 'en',
35
+ t: ctx.t || req.t || identityT,
36
+ accounts: ctx.accounts || req.accounts
23
37
  };
24
38
  }
25
39
  get res() {
@@ -44,90 +58,152 @@ export class BaseController {
44
58
  send(data) {
45
59
  if (self.protocol === ProtocolEnum.WEBSOCKET)
46
60
  return data;
61
+ if (data instanceof Response)
62
+ return data;
63
+ const isBinary = data instanceof Blob || data instanceof Uint8Array || data instanceof ArrayBuffer || (typeof data?.pipe === 'function');
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
+ }
47
69
  const status = store.metadata?._code || 200;
48
- const body = (store.metadata?._isRaw) ? data : JSON.stringify(data?.getResponse ? data.getResponse : data);
49
- return new Response(body, { status, headers: { 'content-type': 'application/json' } });
50
- }
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); }
51
79
  };
52
80
  }
53
81
  }
54
82
  export default class Controller extends BaseController {
55
- constructor() { super(); }
83
+ constructor() {
84
+ super();
85
+ }
56
86
  async onInit() {
57
87
  const protocols = this.system?.tmp?.configs?.loaders?.controller?.protocols;
58
88
  this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols || ProtocolEnum.HTTP];
59
89
  }
60
- parseMessage(input, t) {
61
- if (!input || typeof input !== 'string' || !input.startsWith('@'))
62
- return input;
63
- const parts = input.substring(1).split(' ').filter(p => p !== '');
64
- const maybeMethod = parts[0];
65
- const hasMethod = typeof responseMessageHelper[maybeMethod] === 'function';
66
- const methodName = hasMethod ? maybeMethod : 'successfully';
67
- const rawArgs = hasMethod ? parts.slice(1) : parts;
68
- const translatedArgs = rawArgs.map(arg => {
69
- const res = t(`keywords.${arg}`);
70
- return res !== `keywords.${arg}` ? res : (t(arg) !== arg ? t(arg) : arg);
71
- });
72
- return responseMessageHelper[methodName](translatedArgs[0] || '', translatedArgs.slice(1).join(' '), t);
90
+ parseMessage(msg, t, isError = false) {
91
+ if (!msg)
92
+ return '';
93
+ if (typeof msg !== 'string' && !Array.isArray(msg))
94
+ return '';
95
+ let cleanMsg = msg;
96
+ let useDirect = isError;
97
+ if (typeof cleanMsg === 'string' && cleanMsg.startsWith('@')) {
98
+ cleanMsg = cleanMsg.substring(1);
99
+ useDirect = true;
100
+ }
101
+ const parts = Array.isArray(cleanMsg) ? cleanMsg : cleanMsg.split(' ');
102
+ const key = parts[0];
103
+ const rawParams = parts.slice(1);
104
+ const translatedParams = rawParams.map((p) => t(p));
105
+ if (useDirect) {
106
+ return t(key, translatedParams);
107
+ }
108
+ else {
109
+ return responseMessageHelper.successFully(key, translatedParams.join(' '), t);
110
+ }
73
111
  }
74
112
  async schema({ checks, logic, response }) {
75
113
  try {
76
114
  const currentReq = this.req;
77
115
  const currentRes = this.res;
78
- const store = this.currentStore;
79
- const t = currentReq.t;
80
- const p = { req: currentReq, res: currentRes, body: currentReq.body, query: currentReq.query, params: currentReq.params, locals: store?.metadata?.locals || {}, t };
116
+ const p = {
117
+ req: currentReq,
118
+ res: currentRes,
119
+ body: currentReq.body,
120
+ query: currentReq.query,
121
+ params: currentReq.params,
122
+ t: currentReq.t,
123
+ accounts: currentReq.accounts
124
+ };
81
125
  if (checks) {
82
- const checkRes = await checks(p);
83
- if (checkRes !== true) {
84
- const isObj = checkRes && typeof checkRes === 'object';
85
- const code = isObj ? checkRes.code || 400 : 400;
86
- let rawMsg = isObj ? checkRes.message : (typeof checkRes === 'string' ? checkRes : '@schemaMissingDataChecks');
87
- if (typeof rawMsg === 'string' && !rawMsg.startsWith('@'))
88
- rawMsg = '@' + rawMsg;
89
- const { message, status, code: _c, data, payload, ...extras } = isObj ? checkRes : {};
90
- const coreData = data || payload;
91
- return currentRes.status(code).send(new ResponseSchema({
126
+ const checkResult = await checks(p);
127
+ if (checkResult !== true) {
128
+ const checkCode = checkResult?.code || 400;
129
+ const rawMsg = checkResult?.message || checkResult || 'error_validation';
130
+ const finalMsg = this.parseMessage(rawMsg, currentReq.t, true);
131
+ return currentRes.status(checkCode).send(new ResponseSchema({
92
132
  status: false,
93
- message: this.parseMessage(rawMsg, t),
94
- payload: (coreData !== undefined || Object.keys(extras).length > 0) ? { data: coreData, extraData: extras } : undefined,
95
- code
133
+ message: finalMsg,
134
+ code: checkCode
96
135
  }).getResponse);
97
136
  }
98
137
  }
99
- let logicRes = logic ? await logic(p) : null;
100
- if (logic && logicRes === false) {
101
- return currentRes.status(400).send(new ResponseSchema({ status: false, message: this.parseMessage('@unsuccessful logic', t), code: 400 }).getResponse);
138
+ let logicResult = logic ? await logic(p) : {};
139
+ if (logicResult instanceof Response || logicResult?.constructor?.name === 'Response') {
140
+ return logicResult;
102
141
  }
103
- let finalRes = response ? await response({ ...p, logicResult: logicRes }) : logicRes;
104
- if (typeof finalRes === 'function')
105
- finalRes = await finalRes(p);
106
- if (Array.isArray(finalRes))
107
- finalRes = { message: `@successfully ${finalRes.join(' ')}` };
108
- if (finalRes instanceof Response || finalRes?.constructor?.name === 'Response')
109
- return finalRes;
110
- const isSuccess = finalRes?.status !== false;
111
- const finalCode = finalRes?.code || store?.metadata?._code || 200;
112
- let msgSource = finalRes?.message || (typeof finalRes === 'string' ? finalRes : '@successfully');
113
- if (typeof msgSource === 'string' && !msgSource.startsWith('@'))
114
- msgSource = '@' + msgSource;
115
- const rawOutput = (finalRes && typeof finalRes === 'object' && !Array.isArray(finalRes)) ? finalRes : { data: finalRes };
116
- const { message, status, code, data, payload, ...extraData } = rawOutput;
117
- const coreData = data !== undefined ? data : payload;
118
- const responseData = {
119
- status: isSuccess,
120
- message: this.parseMessage(msgSource, t)
121
- };
122
- if (coreData !== undefined || Object.keys(extraData).length > 0) {
123
- responseData.payload = { data: coreData, extraData: Object.keys(extraData).length > 0 ? extraData : undefined };
142
+ if (logicResult && typeof logicResult === 'object' && typeof logicResult.response === 'function') {
143
+ logicResult = await logicResult.response();
144
+ }
145
+ if (logicResult?.status === false) {
146
+ const errorCode = logicResult.code || 400;
147
+ const finalMsg = this.parseMessage(logicResult.message, currentReq.t, true);
148
+ return currentRes.status(errorCode).send(new ResponseSchema({
149
+ status: false,
150
+ message: finalMsg,
151
+ code: errorCode
152
+ }).getResponse);
153
+ }
154
+ const resResult = response ? await response({ ...p, logicResult }) : logicResult;
155
+ if (resResult instanceof Response || resResult instanceof Blob || resResult instanceof Uint8Array || resResult instanceof ArrayBuffer) {
156
+ return currentRes.status(200).send(resResult);
157
+ }
158
+ let source = resResult;
159
+ if (source === undefined || source === null)
160
+ source = logicResult || {};
161
+ let messageSource = source?.message;
162
+ if (!messageSource) {
163
+ if (typeof source === 'string')
164
+ messageSource = source;
165
+ else if (Array.isArray(source))
166
+ messageSource = source;
167
+ else
168
+ messageSource = 'success_process';
169
+ }
170
+ if (messageSource === source) {
171
+ source = {};
172
+ }
173
+ let dataVal = source.data;
174
+ let extraDataVal = source.extraData;
175
+ if (source.payload) {
176
+ if (source.payload.data !== undefined)
177
+ dataVal = source.payload.data;
178
+ else if (!source.payload.extraData && !source.data)
179
+ dataVal = source.payload;
180
+ if (source.payload.extraData !== undefined)
181
+ extraDataVal = source.payload.extraData;
182
+ }
183
+ else {
184
+ if (dataVal === undefined && Object.keys(source).length > 0 && !source.status && !source.message && !source.code) {
185
+ dataVal = source;
186
+ }
124
187
  }
125
- responseData.code = finalCode;
126
- return currentRes.status(finalCode).send(new ResponseSchema(responseData).getResponse);
188
+ const finalPayload = (dataVal !== undefined || extraDataVal !== undefined)
189
+ ? { data: dataVal, extraData: extraDataVal }
190
+ : undefined;
191
+ const finalMessage = this.parseMessage(messageSource, currentReq.t, false);
192
+ const successCode = this.currentStore?.metadata?._code || source?.code || 200;
193
+ return currentRes.status(successCode).send(new ResponseSchema({
194
+ status: true,
195
+ message: finalMessage,
196
+ ...(finalPayload && { payload: finalPayload }),
197
+ code: successCode
198
+ }).getResponse);
127
199
  }
128
200
  catch (error) {
129
201
  this.logger?.log(LoggerLayerEnum.ERROR, `Controller Error: ${error.message}`);
130
- return this.res.status(500).send(new ResponseSchema({ status: false, message: error.message, code: 500 }).getResponse);
202
+ return this.res.status(500).send(new ResponseSchema({
203
+ status: false,
204
+ message: error.message || 'error_internal',
205
+ code: 500
206
+ }).getResponse);
131
207
  }
132
208
  }
133
209
  }