@xitkov/core 2.4.9

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.
Files changed (98) hide show
  1. package/README.md +256 -0
  2. package/lib/app.d.ts +75 -0
  3. package/lib/app.js +143 -0
  4. package/lib/app.js.map +1 -0
  5. package/lib/errors/index.d.ts +25 -0
  6. package/lib/errors/index.js +41 -0
  7. package/lib/errors/index.js.map +1 -0
  8. package/lib/hooks/business.d.ts +1 -0
  9. package/lib/hooks/business.js +26 -0
  10. package/lib/hooks/business.js.map +1 -0
  11. package/lib/hooks/hooks.d.ts +4 -0
  12. package/lib/hooks/hooks.js +66 -0
  13. package/lib/hooks/hooks.js.map +1 -0
  14. package/lib/hooks/index.d.ts +3 -0
  15. package/lib/hooks/index.js +20 -0
  16. package/lib/hooks/index.js.map +1 -0
  17. package/lib/hooks/types.d.ts +9 -0
  18. package/lib/hooks/types.js +3 -0
  19. package/lib/hooks/types.js.map +1 -0
  20. package/lib/index.d.ts +17 -0
  21. package/lib/index.js +23 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/libs/cache.d.ts +7 -0
  24. package/lib/libs/cache.js +22 -0
  25. package/lib/libs/cache.js.map +1 -0
  26. package/lib/libs/index.d.ts +5 -0
  27. package/lib/libs/index.js +22 -0
  28. package/lib/libs/index.js.map +1 -0
  29. package/lib/libs/logs.d.ts +5 -0
  30. package/lib/libs/logs.js +26 -0
  31. package/lib/libs/logs.js.map +1 -0
  32. package/lib/libs/queue.d.ts +21 -0
  33. package/lib/libs/queue.js +49 -0
  34. package/lib/libs/queue.js.map +1 -0
  35. package/lib/libs/socket.d.ts +8 -0
  36. package/lib/libs/socket.js +26 -0
  37. package/lib/libs/socket.js.map +1 -0
  38. package/lib/libs/utils.d.ts +8 -0
  39. package/lib/libs/utils.js +28 -0
  40. package/lib/libs/utils.js.map +1 -0
  41. package/lib/logger/index.d.ts +11 -0
  42. package/lib/logger/index.js +50 -0
  43. package/lib/logger/index.js.map +1 -0
  44. package/lib/services/auth.d.ts +19 -0
  45. package/lib/services/auth.js +41 -0
  46. package/lib/services/auth.js.map +1 -0
  47. package/lib/services/databases/index.d.ts +3 -0
  48. package/lib/services/databases/index.js +20 -0
  49. package/lib/services/databases/index.js.map +1 -0
  50. package/lib/services/databases/mongo-service.d.ts +26 -0
  51. package/lib/services/databases/mongo-service.js +55 -0
  52. package/lib/services/databases/mongo-service.js.map +1 -0
  53. package/lib/services/databases/postgres-service.d.ts +28 -0
  54. package/lib/services/databases/postgres-service.js +126 -0
  55. package/lib/services/databases/postgres-service.js.map +1 -0
  56. package/lib/services/databases/types.d.ts +26 -0
  57. package/lib/services/databases/types.js +3 -0
  58. package/lib/services/databases/types.js.map +1 -0
  59. package/lib/services/index.d.ts +6 -0
  60. package/lib/services/index.js +23 -0
  61. package/lib/services/index.js.map +1 -0
  62. package/lib/services/micro-service.d.ts +60 -0
  63. package/lib/services/micro-service.js +146 -0
  64. package/lib/services/micro-service.js.map +1 -0
  65. package/lib/services/register-micro-services.d.ts +1 -0
  66. package/lib/services/register-micro-services.js +41 -0
  67. package/lib/services/register-micro-services.js.map +1 -0
  68. package/lib/services/register-services.d.ts +5 -0
  69. package/lib/services/register-services.js +272 -0
  70. package/lib/services/register-services.js.map +1 -0
  71. package/lib/services/service.d.ts +46 -0
  72. package/lib/services/service.js +63 -0
  73. package/lib/services/service.js.map +1 -0
  74. package/package.json +49 -0
  75. package/src/app.ts +182 -0
  76. package/src/errors/index.ts +37 -0
  77. package/src/hooks/business.ts +23 -0
  78. package/src/hooks/hooks.ts +60 -0
  79. package/src/hooks/index.ts +3 -0
  80. package/src/hooks/types.ts +9 -0
  81. package/src/index.ts +18 -0
  82. package/src/libs/cache.ts +25 -0
  83. package/src/libs/index.ts +5 -0
  84. package/src/libs/logs.ts +21 -0
  85. package/src/libs/queue.ts +48 -0
  86. package/src/libs/socket.ts +28 -0
  87. package/src/libs/utils.ts +28 -0
  88. package/src/logger/index.ts +49 -0
  89. package/src/services/auth.ts +48 -0
  90. package/src/services/databases/index.ts +3 -0
  91. package/src/services/databases/mongo-service.ts +75 -0
  92. package/src/services/databases/postgres-service.ts +149 -0
  93. package/src/services/databases/types.ts +29 -0
  94. package/src/services/index.ts +6 -0
  95. package/src/services/micro-service.ts +188 -0
  96. package/src/services/register-micro-services.ts +37 -0
  97. package/src/services/register-services.ts +268 -0
  98. package/src/services/service.ts +118 -0
@@ -0,0 +1,188 @@
1
+ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ import { BadRequest, InternalServer, NoContent, Unauthorized } from '../errors';
3
+ import { Logger } from '../logger';
4
+
5
+ export type MicroServiceQuery = {[key: string]: any};
6
+
7
+ export interface InternalMicroServiceMethods {
8
+ find<T = any>(query: MicroServiceQuery, config?: IConfig<T>): Promise<T[]>;
9
+ get<T = any>(id: string | null, query?: MicroServiceQuery, config?: IConfig<T>): Promise<T | null>;
10
+ create<T = any, U = any>(data: Partial<U>, query?: MicroServiceQuery, config?: IConfig<T>): Promise<T | null>;
11
+ update<T = any, U = any>(id: string, data: U, query?: MicroServiceQuery, config?: IConfig<T>): Promise<T | null>;
12
+ patch<T = any, U = any>(id: string, data: Partial<U>, query?: MicroServiceQuery, config?: IConfig<T>): Promise<T | null>;
13
+ remove<T = any>(id: string, query?: MicroServiceQuery, config?: IConfig<T>): Promise<T | T[] | null>;
14
+ readonly request: AxiosInstance;
15
+ readonly call: AxiosInstance
16
+ readonly name: string;
17
+ readonly baseURL: string;
18
+ readonly service: string
19
+ readonly url: string
20
+ }
21
+
22
+ export interface InternalMicroServiceOptions {
23
+ axiosConfig?: AxiosRequestConfig;
24
+ name: string;
25
+ baseURL: string;
26
+ service: string
27
+ }
28
+
29
+ interface IExceptionConfig<T = any> {
30
+ handle?: boolean;
31
+ defaultValue?: Partial<T> | null;
32
+ }
33
+
34
+ interface IConfig<T = any> {
35
+ axiosConfig?: AxiosRequestConfig;
36
+ exception?: IExceptionConfig<T>;
37
+ /** @deprecated typo alias, use `exception` */
38
+ execption?: IExceptionConfig<T>;
39
+ }
40
+
41
+ export class MicroService implements InternalMicroServiceMethods {
42
+ readonly request: AxiosInstance
43
+ readonly name: string
44
+ readonly baseURL: string
45
+ readonly service: string
46
+ readonly url: string
47
+
48
+ constructor({ axiosConfig, name, service, baseURL }: InternalMicroServiceOptions) {
49
+ const providedAxiosConfig = (axiosConfig ?? {})
50
+ this.request = axios.create({
51
+ baseURL,
52
+ headers: {
53
+ InternalToken: process.env.INTERNAL_TOKEN ?? 'internal_token',
54
+ ...providedAxiosConfig.headers,
55
+ },
56
+ ...providedAxiosConfig,
57
+ })
58
+ this.name = name
59
+ this.baseURL = baseURL;
60
+ this.service = service
61
+ this.url = `/${service}`
62
+ }
63
+
64
+ throwError(err: any): Error {
65
+ const message = err?.response?.data?.message
66
+ const status = err?.response?.status
67
+ if (message) {
68
+ switch(status) {
69
+ case 401: return new Unauthorized(message)
70
+ case 400: return new BadRequest(message)
71
+ case 500: return new InternalServer(message)
72
+ case 204: return new NoContent(message)
73
+ default: return new InternalServer(message)
74
+ }
75
+ }
76
+ return new InternalServer(err?.message ?? String(err))
77
+ }
78
+
79
+ async find<T = any>(query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T[]> {
80
+ const defaultValue: T[] = [];
81
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
82
+ try {
83
+ const { data } = await this.request.get(`${this.url}`, { ...axiosConfig, params: query });
84
+ return data?.data ?? data
85
+ }
86
+ catch (err) {
87
+ return this.handleException(exception, defaultValue, err);
88
+ }
89
+ }
90
+
91
+ async get<T = any>(id: string | null, query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T | null> {
92
+ const defaultValue = {};
93
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
94
+ try {
95
+ const { data } = await this.request.get(`${this.url}/${id}`, { ...axiosConfig, params: query });
96
+ return data?.data ?? data
97
+ }
98
+ catch (err) {
99
+ return this.handleException(exception, defaultValue, err);
100
+ }
101
+ }
102
+
103
+ async create<T = any, U = any>(payload: Partial<U>, query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T | null> {
104
+ const defaultValue = {};
105
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
106
+ try {
107
+ const { data } = await this.request.post(`${this.url}`, payload, { ...axiosConfig, params: query });
108
+ return data?.data ?? data
109
+ }
110
+ catch (err) {
111
+ return this.handleException(exception, defaultValue, err);
112
+ }
113
+ }
114
+
115
+ async update<T = any, U = any>(id: string, payload: U, query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T | null> {
116
+ const defaultValue = {};
117
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
118
+ try {
119
+ const { data } = await this.request.put(`${this.url}/${id}`, payload, { ...axiosConfig, params: query });
120
+ return data?.data ?? data
121
+ }
122
+ catch (err) {
123
+ return this.handleException(exception, defaultValue, err);
124
+ }
125
+ }
126
+
127
+ async patch<T = any, U = any>(id: string, payload: Partial<U>, query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T | null> {
128
+ const defaultValue = {};
129
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
130
+ try {
131
+ const { data } = await this.request.patch(`${this.url}/${id}`, payload, { ...axiosConfig, params: query });
132
+ return data?.data ?? data
133
+ }
134
+ catch (err) {
135
+ return this.handleException(exception, defaultValue, err);
136
+ }
137
+ }
138
+
139
+ async remove<T = any>(id: string, query?: MicroServiceQuery, config: IConfig<T> = {}): Promise<T | T[] | null> {
140
+ const defaultValue = {};
141
+ const { axiosConfig, exception } = this.getConfig(config, defaultValue);
142
+ try {
143
+ const { data } = await this.request.delete(`${this.url}/${id}`, { ...axiosConfig, params: query });
144
+ return data?.data ?? data
145
+ }
146
+ catch (err) {
147
+ return this.handleException(exception, defaultValue, err);
148
+ }
149
+ }
150
+
151
+ get call() {
152
+ return this.request
153
+ }
154
+
155
+ private getLog(err: any) {
156
+ const message = err?.response?.data?.message
157
+ const status = err?.response?.status
158
+ Logger.error(`Error ${this.name}`, {
159
+ message,
160
+ status,
161
+ url: this.url,
162
+ errorMessage: message ?? err?.message ?? err,
163
+ error: err?.response?.data ?? err?.response ?? err,
164
+ });
165
+ }
166
+
167
+ private getConfig(config: IConfig<any>, defaultValue: any) {
168
+ const src = config ?? {};
169
+ const axiosConfig = src.axiosConfig ?? {};
170
+ const exception = src.exception ?? src.execption ?? { defaultValue, handle: false };
171
+ return { axiosConfig, exception };
172
+ }
173
+ private handleException(exception: IExceptionConfig | undefined, defaultInitialValue: any, err: any) {
174
+ const { defaultValue = defaultInitialValue, handle = false } = exception ?? {};
175
+ if (handle) {
176
+ this.getLog(err);
177
+ return defaultValue;
178
+ }
179
+ throw this.throwError(err);
180
+ }
181
+ }
182
+
183
+ export interface IMicroService {
184
+ name: string;
185
+ baseURL: string;
186
+ config?: AxiosRequestConfig;
187
+ services: string[]
188
+ }
@@ -0,0 +1,37 @@
1
+ import {promises} from 'fs';
2
+ import path from 'path';
3
+ import { Logger } from '../logger';
4
+ import { MicroService } from './micro-service';
5
+
6
+ export async function registerMicroServices() {
7
+ if (require.main?.filename == undefined) {
8
+ throw new Error("Please provide service path")
9
+ }
10
+ const appDir = path.dirname(require.main?.filename as string);
11
+ const serviceDirPath = appDir + '/micro-services';
12
+
13
+ const servicesNames = (await promises.readdir(serviceDirPath)).filter(
14
+ file => !/^(index|types)\.(ts|js|d\.ts)$/.test(file) && !/\.map$/.test(file)
15
+ );
16
+
17
+ const services: any = {}
18
+
19
+ for (const serviceName of servicesNames) {
20
+ const servicePath = `${serviceDirPath}/${serviceName}`;
21
+ try {
22
+ const instance = new (require(servicePath).default)
23
+ if (instance) {
24
+ const { baseURL, name, services: subServicesNames, config } = instance
25
+ services[name] = services[name] ?? {}
26
+ subServicesNames?.forEach((subService: string) => {
27
+ services[name][subService] = new MicroService({ axiosConfig: config, name, service: subService, baseURL })
28
+ })
29
+ }
30
+ } catch(error) {
31
+ Logger.warn("No micro services", {
32
+ error
33
+ })
34
+ }
35
+ }
36
+ return services;
37
+ }
@@ -0,0 +1,268 @@
1
+ import type {Application, Request, Response} from 'express';
2
+ // eslint-disable-next-line node/no-unsupported-features/node-builtins
3
+ import {promises} from 'fs';
4
+ import path from 'path';
5
+ import {Router} from 'express';
6
+ import {Config, Dialect, IAuth, Logger, addQuerySupport} from '..';
7
+ import {PostgresInternalServiceOptions, MongoInternalServiceOptions} from '.';
8
+ import { BadRequest, Unauthorized } from '../errors';
9
+ import { AuthService } from './auth';
10
+
11
+ type Method = 'get' | 'post' | 'patch' | 'put' | 'delete';
12
+
13
+ type Functions = 'find' | 'get' | 'create' | 'update' | 'patch' | 'remove';
14
+
15
+ type InternalServiceOptions = (PostgresInternalServiceOptions | MongoInternalServiceOptions) & { dialect : Dialect };
16
+
17
+ interface Methods {
18
+ method: Method;
19
+ url: string;
20
+ func: Functions;
21
+ }
22
+
23
+ async function validate(Validator: any, func: string, value: any) {
24
+ const schema = await Validator[func]
25
+ if (schema) {
26
+ try {
27
+ const schemaValue = await schema().validateAsync(value);
28
+ return schemaValue;
29
+ } catch (err: any) {
30
+ throw new BadRequest(err.message)
31
+ }
32
+ }
33
+ return value
34
+ }
35
+
36
+ async function hooks(Hooks: any, func: string, parameters: any[], methodName: string) {
37
+ const allHooks = Hooks[func]
38
+
39
+ allHooks?.forEach?.((hook: any) => {
40
+ hook?.(...parameters, methodName)
41
+ });
42
+ return allHooks
43
+ }
44
+
45
+ function getJWTDecoded(accessToken: string) {
46
+ try {
47
+ const base64Url = accessToken.split('.')[1];
48
+ const decoded = Buffer.from(base64Url, 'base64').toString()
49
+ return JSON.parse(decoded)
50
+ } catch(error) {
51
+ Logger.error("getJWTDecoded", error)
52
+ return {}
53
+ }
54
+ }
55
+
56
+ export async function registerServices(app: Application, auth?: IAuth, database?: Config['database']) {
57
+ if (require.main?.filename == undefined) {
58
+ throw new Error("Please provide service path")
59
+ }
60
+ const appDir = path.dirname(require.main?.filename as string);
61
+ const serviceDirPath = appDir + '/services';
62
+
63
+ const servicesNames = (await promises.readdir(serviceDirPath)).filter(
64
+ file => !/^index\.(ts|js|d\.ts)$/.test(file) && !/\.map$/.test(file)
65
+ );
66
+
67
+ const methods: Methods[] = [
68
+ {
69
+ method: 'get',
70
+ url: '/',
71
+ func: 'find',
72
+ },
73
+ {
74
+ method: 'get',
75
+ url: '/:id',
76
+ func: 'get',
77
+ },
78
+ {
79
+ method: 'post',
80
+ url: '/',
81
+ func: 'create',
82
+ },
83
+ {
84
+ method: 'patch',
85
+ url: '/:id',
86
+ func: 'patch',
87
+ },
88
+ {
89
+ method: 'put',
90
+ url: '/:id',
91
+ func: 'update',
92
+ },
93
+ {
94
+ method: 'delete',
95
+ url: '/:id',
96
+ func: 'remove',
97
+ },
98
+ ];
99
+
100
+ const services: {[serviceName: string]: any} = {}
101
+
102
+ for (const serviceName of servicesNames) {
103
+ const servicePath = `${serviceDirPath}/${serviceName}/service`;
104
+ const modelPath = `${serviceDirPath}/${serviceName}/model`;
105
+ const validatorPath = `${serviceDirPath}/${serviceName}/validator`;
106
+ const hooksPath = `${serviceDirPath}/${serviceName}/hooks`;
107
+ let Model = null
108
+ let Validator: any = null
109
+ let Hooks: any = null
110
+ try {
111
+ if(database?.instance) {
112
+ Model = (await import(modelPath)).default(database.instance);
113
+ } else {
114
+ Model = (await import(modelPath)).default;
115
+ }
116
+ } catch(err) {
117
+ //
118
+ }
119
+
120
+ try {
121
+ Validator = new (await import(validatorPath)).default;
122
+ } catch(err) {
123
+ //
124
+ }
125
+
126
+ try {
127
+ Hooks = new (await import(hooksPath)).default;
128
+ } catch(err) {
129
+ //
130
+ }
131
+ const serviceConfig: Partial<InternalServiceOptions> = {}
132
+
133
+ if (Model) {
134
+ serviceConfig.Model = Model
135
+ }
136
+ serviceConfig.dialect = database?.dialect ?? 'mongodb'
137
+
138
+ const service = new (await import(servicePath)).default(serviceConfig);
139
+ services[serviceName] = service
140
+ const router = Router();
141
+ for (const {method, url, func} of methods) {
142
+ const callback = async (req: Request, res: Response) => {
143
+ const { required, baseURL } = auth ?? {}
144
+ const {params, query, body, baseUrl, ...rest} = req;
145
+
146
+ try {
147
+ if (service.auth !== false) {
148
+ // TODO: Temp will find the better solution later
149
+ if (req.headers['internaltoken'] !== (process.env.INTERNAL_TOKEN ?? 'internal_token')) {
150
+ if (required && baseURL) {
151
+ const authorization = req.headers['authorization']
152
+ if (!authorization) {
153
+ throw new Unauthorized("You don't have permission")
154
+ }
155
+
156
+ const authService = new AuthService({
157
+ baseURL: baseURL,
158
+ axiosConfig: {
159
+ headers: {
160
+ Authorization: authorization
161
+ }
162
+ }
163
+ })
164
+
165
+ const authData = await authService.verify()
166
+ const {businessId} = authData ?? {}
167
+ const decodedAccessToken = getJWTDecoded(authorization);
168
+ const { business } = decodedAccessToken;
169
+ const userBusinessId = businessId ?? business
170
+ if (!userBusinessId) {
171
+ throw new Unauthorized("You don't have permission")
172
+ }
173
+
174
+ const userData = ((req as any).user ?? {});
175
+ (req as any).user = { ...userData, userBusinessId }
176
+ }
177
+ }
178
+ }
179
+
180
+ const user = (req as any).user
181
+ const {id} = params;
182
+ let parameters: any[] = [];
183
+ let validatorValue
184
+ switch (func) {
185
+ case 'find':
186
+ parameters = [query, user, req];
187
+ validatorValue = query
188
+ break;
189
+ case 'get':
190
+ parameters = [id, query, user, req];
191
+ validatorValue = query
192
+ break;
193
+ case 'create':
194
+ parameters = [body, query, user, req];
195
+ validatorValue = body
196
+ break;
197
+ case 'patch':
198
+ parameters = [id, body, query, user, req];
199
+ validatorValue = body
200
+ break;
201
+ case 'update':
202
+ parameters = [id, body, query, user, req];
203
+ validatorValue = body
204
+ break;
205
+ case 'remove':
206
+ parameters = [id, query, user, req];
207
+ validatorValue = query
208
+ break;
209
+ }
210
+ if (Hooks) {
211
+ await hooks(Hooks, 'all', parameters, func)
212
+ await hooks(Hooks, func, parameters, func)
213
+ }
214
+ if (service.filtering !== false && func === 'find') {
215
+ parameters[0] = addQuerySupport(...parameters, func)
216
+ }
217
+
218
+ if(service[func] == undefined) {
219
+ return res.status(404).send({
220
+ message: "Not found"
221
+ });
222
+ }
223
+ if (Validator) {
224
+ await validate(Validator, func, validatorValue)
225
+ }
226
+
227
+ const response = await service[func](...parameters)
228
+ let data: any = response
229
+ let count: number | undefined = undefined
230
+
231
+ if (func === 'find' && data && !Array.isArray(data) && data.rows) {
232
+ count = data.count
233
+ data = data.rows
234
+ } else if (response == null) {
235
+ if (id) {
236
+ return res.status(400).send({message: `No record found for ${id}`});
237
+ }
238
+ return res.status(400).send({message: 'Bad Request'});
239
+ }
240
+
241
+ return res.send({
242
+ message: "ok",
243
+ data,
244
+ count
245
+ });
246
+ } catch (error: any) {
247
+ Logger.error('Error', {
248
+ baseUrl,
249
+ url,
250
+ error,
251
+ message: error?.message
252
+ });
253
+ const status = error?.status
254
+ const message = error?.message
255
+ if (typeof status === 'number' && message) {
256
+ return res.status(status).send({ message });
257
+ }
258
+ return res.status(500).send({ message: 'Something went wrong' });
259
+ }
260
+ };
261
+ router[method](url, callback);
262
+ }
263
+ app.set('services', services)
264
+
265
+ app.use(`/${serviceName}`, router);
266
+ }
267
+ return services;
268
+ }
@@ -0,0 +1,118 @@
1
+ import { Request, Response } from "express";
2
+ import { Model as MongoModel } from "mongoose";
3
+ import { ModelStatic as SequelizeModel} from 'sequelize'
4
+ import { Dialect } from "..";
5
+ import { FindResponse, InternalServiceMethods, MongoDBService, PostgreSQLService, Query, User } from './databases'
6
+
7
+ /**
8
+ * Augment via:
9
+ * declare module 'xitkov' {
10
+ * interface XitkovConfig { dialect: 'postgres' }
11
+ * }
12
+ */
13
+ export interface XitkovConfig {}
14
+
15
+ export type DefaultDialect = XitkovConfig extends { dialect: infer D }
16
+ ? D extends Dialect ? D : 'mongodb'
17
+ : 'mongodb';
18
+
19
+ type ServiceType<T, U> =
20
+ U extends 'postgres'
21
+ ? PostgreSQLService<T>
22
+ : U extends 'mongodb'
23
+ ? MongoDBService<T>
24
+ : any;
25
+
26
+ type ModelType<T, U> =
27
+ U extends 'postgres'
28
+ ? SequelizeModel<any>
29
+ : U extends "mongodb"
30
+ ? MongoModel<T>
31
+ : any
32
+
33
+ export interface IXitovServiceProps {
34
+ Model: any;
35
+ dialect?: Dialect;
36
+ pagination?: boolean
37
+ }
38
+
39
+ export class XitkovService<T, U extends Dialect = DefaultDialect> implements InternalServiceMethods<T> {
40
+ private service: ServiceType<T, U>;
41
+ private Model: ModelType<T, U>
42
+ pagination?: boolean;
43
+
44
+ static defaultDialect: Dialect = 'mongodb';
45
+
46
+ static setDefaultDialect(dialect: Dialect) {
47
+ XitkovService.defaultDialect = dialect;
48
+ }
49
+
50
+ constructor({Model, dialect, pagination}: IXitovServiceProps) {
51
+ this.Model = Model;
52
+ const resolved = dialect ?? XitkovService.defaultDialect;
53
+ switch(resolved) {
54
+ case 'postgres':
55
+ this.service = new PostgreSQLService({ Model, pagination }) as any;
56
+ break;
57
+ case 'mongodb':
58
+ default:
59
+ this.service = new MongoDBService({ Model }) as any;
60
+ }
61
+ }
62
+
63
+ async find(query: Query, user?: any, req?: Request, res?: Response): Promise<FindResponse<T>> {
64
+ return await this.service.find(query, user, req, res);
65
+ }
66
+
67
+ async get(id: string | null, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | null> {
68
+ return await this.service.get(id, query, user, req, res);
69
+ }
70
+
71
+ async create(data: Partial<T>, query?: Query, user?: User, req?: Request, res?: Response): Promise<T>;
72
+ async create(data: Partial<T>[], query?: Query, user?: User, req?: Request, res?: Response): Promise<T[]>;
73
+ async create(data: Partial<T> | Partial<T>[], query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[]> {
74
+ return this.service.create(data, query, user, req, res);
75
+ }
76
+
77
+ async update(id: string, data: T, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | null> {
78
+ return await this.service.update(id, data, query, user, req, res);
79
+ }
80
+
81
+ async patch(id: string, data: Partial<T>, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[] | null> {
82
+ return await this.service.patch(id, data, query, user, req, res);
83
+ }
84
+
85
+ async remove(id: string, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[] | null> {
86
+ return await this.service.remove(id, query, user, req, res);
87
+ }
88
+
89
+ get model(): ModelType<T, U> {
90
+ return this.Model
91
+ }
92
+
93
+ async _find(query: Query, user?: any, req?: Request, res?: Response): Promise<FindResponse<T>> {
94
+ return await this.service.find(query, user, req, res);
95
+ }
96
+
97
+ async _get(id: string | null, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | null> {
98
+ return await this.service.get(id, query, user, req, res);
99
+ }
100
+
101
+ async _create(data: Partial<T>, query?: Query, user?: User, req?: Request, res?: Response): Promise<T>;
102
+ async _create(data: Partial<T>[], query?: Query, user?: User, req?: Request, res?: Response): Promise<T[]>;
103
+ async _create(data: Partial<T> | Partial<T>[], query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[]> {
104
+ return this.service.create(data, query, user, req, res);
105
+ }
106
+
107
+ async _update(id: string, data: T, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | null> {
108
+ return await this.service.update(id, data, query, user, req, res);
109
+ }
110
+
111
+ async _patch(id: string, data: Partial<T>, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[] | null> {
112
+ return await this.service.patch(id, data, query, user, req, res);
113
+ }
114
+
115
+ async _remove(id: string, query?: Query, user?: User, req?: Request, res?: Response): Promise<T | T[] | null> {
116
+ return await this.service.remove(id, query, user, req, res);
117
+ }
118
+ }