@xrystal/core 3.23.2 → 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
@@ -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.3",
5
5
  "description": "Project core for xrystal",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -49,10 +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
- private parseMessage;
53
- schema<T = any>({ checks, logic, response }: {
52
+ schema({ checks, logic, response }: {
54
53
  checks?: (args: any) => Promise<any>;
55
- logic?: (args: any) => Promise<T | boolean | string | any[]>;
54
+ logic?: (args: any) => Promise<any>;
56
55
  response?: (args: any) => Promise<any>;
57
56
  }): Promise<any>;
58
57
  }
@@ -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,16 +8,25 @@ 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() { return this.currentStore?.protocol || ProtocolEnum.HTTP; }
13
- get currentStore() { return getControllerCtx(); }
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;
19
+ const identityT = (k) => k;
16
20
  const ctx = store?.ctx || {};
17
- const query = typeof ctx.query === 'string' ? qs.parse(ctx.query) : (ctx.query || {});
18
21
  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
+ url: ctx.url || '',
23
+ method: ctx.method || '',
24
+ headers: ctx.headers || {},
25
+ body: ctx.body || {},
26
+ query: ctx.query || {},
27
+ params: ctx.params || {},
28
+ lang: ctx.lang || 'en',
29
+ t: ctx.t || identityT,
22
30
  accounts: ctx.accounts || store?.req?.accounts
23
31
  };
24
32
  }
@@ -44,90 +52,117 @@ export class BaseController {
44
52
  send(data) {
45
53
  if (self.protocol === ProtocolEnum.WEBSOCKET)
46
54
  return data;
55
+ if (data instanceof Response)
56
+ return data;
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';
62
+ }
47
63
  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
- }
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
+ });
71
+ },
72
+ json(data) { return this.send(data); }
51
73
  };
52
74
  }
53
75
  }
54
76
  export default class Controller extends BaseController {
55
- constructor() { super(); }
77
+ constructor() {
78
+ super();
79
+ }
56
80
  async onInit() {
57
81
  const protocols = this.system?.tmp?.configs?.loaders?.controller?.protocols;
58
82
  this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols || ProtocolEnum.HTTP];
59
83
  }
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);
73
- }
74
84
  async schema({ checks, logic, response }) {
75
85
  try {
76
86
  const currentReq = this.req;
77
87
  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 };
88
+ const p = {
89
+ req: currentReq,
90
+ res: currentRes,
91
+ body: currentReq.body,
92
+ query: currentReq.query,
93
+ params: currentReq.params,
94
+ t: currentReq.t
95
+ };
81
96
  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({
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({
92
101
  status: false,
93
- message: this.parseMessage(rawMsg, t),
94
- payload: (coreData !== undefined || Object.keys(extras).length > 0) ? { data: coreData, extraData: extras } : undefined,
95
- code
102
+ message: checkResult?.message || '',
103
+ code: checkCode
96
104
  }).getResponse);
97
105
  }
98
106
  }
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);
107
+ let logicResult = logic ? await logic(p) : null;
108
+ if (logicResult && typeof logicResult === 'object' && typeof logicResult.response === 'function') {
109
+ logicResult = await logicResult.response();
102
110
  }
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 };
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;
125
+ }
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;
138
+ }
139
+ else {
140
+ finalMessage = responseMessageHelper.successFully(messageSource, '', currentReq.t);
141
+ rawMessageValue = messageSource;
142
+ }
143
+ }
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
+ }
124
150
  }
125
- responseData.code = finalCode;
126
- return currentRes.status(finalCode).send(new ResponseSchema(responseData).getResponse);
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);
127
158
  }
128
159
  catch (error) {
129
160
  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);
161
+ return this.res.status(500).send(new ResponseSchema({
162
+ status: false,
163
+ message: error.message,
164
+ code: 500
165
+ }).getResponse);
131
166
  }
132
167
  }
133
168
  }