@xrystal/core 3.16.4 → 3.16.7

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