@xrystal/core 3.16.4 → 3.16.8

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