mblabs-roccato-backend-commons 1.0.8 → 1.1.0

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 (102) hide show
  1. package/bitbucket-pipelines.yml +6 -48
  2. package/dist/database/entities/account.d.ts +1 -2
  3. package/dist/database/entities/account.js +2 -7
  4. package/dist/database/entities/address.d.ts +2 -1
  5. package/dist/database/entities/address.js +6 -5
  6. package/dist/database/entities/company-address.d.ts +10 -0
  7. package/dist/database/entities/company-address.js +51 -0
  8. package/dist/database/entities/company.d.ts +13 -0
  9. package/dist/database/entities/company.js +68 -0
  10. package/dist/database/entities/index.d.ts +3 -1
  11. package/dist/database/entities/index.js +5 -1
  12. package/dist/database/migrations/1748448589934-CreateAccountsTable.js +1 -6
  13. package/dist/database/migrations/1750432386920-CreateAddressTable.js +0 -5
  14. package/dist/database/migrations/{1750691840822-CreateAccountDetailsTable.d.ts → 1750437883213-CreateCompanyTable.d.ts} +1 -1
  15. package/dist/database/migrations/{1750691840822-CreateAccountDetailsTable.js → 1750437883213-CreateCompanyTable.js} +35 -23
  16. package/dist/database/migrations/{1750690818577-CreateAccountAddressTable.d.ts → 1750440116105-CreateCompanyAddressTable.d.ts} +1 -1
  17. package/dist/database/migrations/{1750690818577-CreateAccountAddressTable.js → 1750440116105-CreateCompanyAddressTable.js} +14 -21
  18. package/dist/database/migrations/index.d.ts +1 -29
  19. package/dist/database/migrations/index.js +18 -18
  20. package/dist/interfaces/aws.d.ts +41 -67
  21. package/dist/interfaces/azure.d.ts +38 -61
  22. package/dist/interfaces/firebase.d.ts +3 -7
  23. package/dist/interfaces/gcp.d.ts +5 -11
  24. package/dist/interfaces/grafana.d.ts +2 -6
  25. package/dist/interfaces/keycloak.d.ts +4 -171
  26. package/dist/interfaces/nodemailer.d.ts +16 -20
  27. package/dist/interfaces/redis.d.ts +8 -49
  28. package/dist/interfaces/sendgrid.d.ts +13 -15
  29. package/dist/services/aws/cloudwatch.d.ts +1 -1
  30. package/dist/services/aws/cloudwatch.js +38 -38
  31. package/dist/services/aws/pinpoint.d.ts +3 -3
  32. package/dist/services/aws/pinpoint.js +29 -29
  33. package/dist/services/aws/s3.d.ts +5 -5
  34. package/dist/services/aws/s3.js +55 -59
  35. package/dist/services/aws/secret-manager.d.ts +1 -1
  36. package/dist/services/aws/secret-manager.js +5 -5
  37. package/dist/services/aws/sqs.d.ts +3 -3
  38. package/dist/services/aws/sqs.js +16 -16
  39. package/dist/services/azure/application-insights.d.ts +4 -4
  40. package/dist/services/azure/application-insights.js +12 -12
  41. package/dist/services/azure/communication.d.ts +3 -3
  42. package/dist/services/azure/communication.js +17 -17
  43. package/dist/services/azure/keyvault.d.ts +1 -1
  44. package/dist/services/azure/keyvault.js +3 -3
  45. package/dist/services/azure/storage-blob.d.ts +3 -3
  46. package/dist/services/azure/storage-blob.js +22 -22
  47. package/dist/services/firebase.d.ts +2 -2
  48. package/dist/services/firebase.js +10 -12
  49. package/dist/services/gcp/drive.d.ts +1 -1
  50. package/dist/services/gcp/drive.js +4 -4
  51. package/dist/services/gcp/secrets.d.ts +1 -1
  52. package/dist/services/gcp/secrets.js +8 -6
  53. package/dist/services/gcp/sheets.d.ts +1 -1
  54. package/dist/services/gcp/sheets.js +6 -6
  55. package/dist/services/grafana.d.ts +2 -2
  56. package/dist/services/grafana.js +12 -12
  57. package/dist/services/keycloak.d.ts +2 -14
  58. package/dist/services/keycloak.js +24 -300
  59. package/dist/services/nodemailer.d.ts +2 -2
  60. package/dist/services/nodemailer.js +109 -19
  61. package/dist/services/redis.d.ts +8 -6
  62. package/dist/services/redis.js +24 -53
  63. package/dist/services/sendgrid.d.ts +1 -1
  64. package/dist/services/sendgrid.js +10 -10
  65. package/package.json +1 -1
  66. package/src/database/entities/account.ts +3 -5
  67. package/src/database/entities/address.ts +7 -4
  68. package/src/database/entities/company-address.ts +27 -0
  69. package/src/database/entities/company.ts +36 -0
  70. package/src/database/entities/index.ts +4 -0
  71. package/src/database/migrations/1748448589934-CreateAccountsTable.ts +1 -6
  72. package/src/database/migrations/1750432386920-CreateAddressTable.ts +0 -5
  73. package/src/database/migrations/{1750691840822-CreateAccountDetailsTable.ts → 1750437883213-CreateCompanyTable.ts} +35 -21
  74. package/src/database/migrations/{1750690818577-CreateAccountAddressTable.ts → 1750440116105-CreateCompanyAddressTable.ts} +14 -24
  75. package/src/database/migrations/index.ts +6 -6
  76. package/src/interfaces/aws.ts +55 -81
  77. package/src/interfaces/azure.ts +50 -71
  78. package/src/interfaces/firebase.ts +6 -10
  79. package/src/interfaces/gcp.ts +8 -14
  80. package/src/interfaces/grafana.ts +5 -9
  81. package/src/interfaces/keycloak.ts +7 -190
  82. package/src/interfaces/nodemailer.ts +18 -22
  83. package/src/interfaces/redis.ts +8 -54
  84. package/src/interfaces/sendgrid.ts +14 -16
  85. package/src/services/aws/cloudwatch.ts +39 -39
  86. package/src/services/aws/pinpoint.ts +30 -30
  87. package/src/services/aws/s3.ts +55 -59
  88. package/src/services/aws/secret-manager.ts +7 -8
  89. package/src/services/aws/sqs.ts +17 -23
  90. package/src/services/azure/application-insights.ts +12 -12
  91. package/src/services/azure/communication.ts +18 -18
  92. package/src/services/azure/keyvault.ts +3 -3
  93. package/src/services/azure/storage-blob.ts +30 -34
  94. package/src/services/firebase.ts +11 -21
  95. package/src/services/gcp/drive.ts +5 -8
  96. package/src/services/gcp/secrets.ts +10 -9
  97. package/src/services/gcp/sheets.ts +7 -10
  98. package/src/services/grafana.ts +12 -18
  99. package/src/services/keycloak.ts +25 -381
  100. package/src/services/nodemailer.ts +110 -19
  101. package/src/services/redis.ts +22 -58
  102. package/src/services/sendgrid.ts +11 -11
@@ -1,400 +1,44 @@
1
- import { IKeycloakService, Keycloak, Roles } from '../interfaces/keycloak';
1
+ import { IKeycloakService, Keycloak } from '../interfaces/keycloak';
2
2
  import HttpService from './http';
3
3
 
4
4
  class KeycloakService implements IKeycloakService {
5
- async authenticate ({
6
- credentials,
7
- data,
8
- url,
9
- }: Keycloak.Authenticate.Request): Promise<Keycloak.Authenticate.Response> {
10
- const { data: response } = await HttpService.request<Keycloak.Authenticate.Response>({
11
- baseURL: url,
12
- method: 'post',
13
- resourcePath: `/auth/realms/${credentials.realm}/protocol/openid-connect/token/`,
14
- headers: {
15
- 'Cache-Control': 'no-cache',
16
- 'Content-Type': 'application/x-www-form-urlencoded',
17
- },
18
- body: new URLSearchParams({
19
- client_id: credentials.clientId,
20
- client_secret: credentials.clientSecret,
21
- grant_type: credentials.grantType,
22
- username: data.username,
23
- password: data.password,
24
- }),
5
+ async authenticate (req: Keycloak.Authenticate.Request): Promise<Keycloak.Authenticate.Response> {
6
+ const query = new URLSearchParams({
7
+ client_id: req.credentials.clientId,
8
+ client_secret: req.credentials.clientSecret,
9
+ grant_type: req.credentials.grantType,
10
+ username: req.username,
11
+ password: req.password,
25
12
  });
26
13
 
27
- return response;
28
- }
29
-
30
- async authenticateServer ({
31
- credentials,
32
- url,
33
- }: Keycloak.AuthenticateServer.Request): Promise<Keycloak.AuthenticateServer.Response> {
34
- const { data: response } = await HttpService.request<Keycloak.AuthenticateServer.Response>({
35
- baseURL: url,
36
- method: 'post',
37
- resourcePath: `/auth/realms/${credentials.realm}/protocol/openid-connect/token/`,
38
- headers: {
39
- 'Cache-Control': 'no-cache',
40
- 'Content-Type': 'application/x-www-form-urlencoded',
41
- },
42
- body: new URLSearchParams({
43
- client_id: credentials.clientId,
44
- client_secret: credentials.clientSecret,
45
- grant_type: credentials.grantType,
46
- }),
47
- });
48
-
49
- return response;
50
- }
51
-
52
- async refreshAccess ({
53
- credentials,
54
- data,
55
- url,
56
- }: Keycloak.RefreshAccess.Request): Promise<Keycloak.RefreshAccess.Response> {
57
- const { data: response } = await HttpService.request<Keycloak.RefreshAccess.Response>({
58
- baseURL: url,
59
- method: 'post',
60
- resourcePath: `/auth/realms/${credentials.realm}/protocol/openid-connect/token`,
61
- headers: {
62
- 'Cache-Control': 'no-cache',
63
- 'Content-Type': 'application/x-www-form-urlencoded',
64
- },
65
- body: new URLSearchParams({
66
- client_id: credentials.clientId,
67
- client_secret: credentials.clientSecret,
68
- grant_type: 'refresh_token',
69
- refresh_token: data.refreshToken,
70
- }),
71
- });
72
-
73
- return response;
74
- }
75
-
76
- async revokeAccess ({
77
- credentials,
78
- data,
79
- url,
80
- }: Keycloak.RevokeAccess.Request): Promise<void> {
81
- await HttpService.request<void>({
82
- baseURL: url,
83
- method: 'post',
84
- resourcePath: `/auth/realms/${credentials.realm}/protocol/openid-connect/revoke`,
85
- headers: {
86
- 'Cache-Control': 'no-cache',
87
- 'Content-Type': 'application/x-www-form-urlencoded',
88
- },
89
- body: new URLSearchParams({
90
- client_id: credentials.clientId,
91
- client_secret: credentials.clientSecret,
92
- token: data.accessToken,
93
- }),
94
- });
95
- }
96
-
97
- async createUser ({
98
- credentials,
99
- data,
100
- url,
101
- }: Keycloak.CreateUser.Request): Promise<void> {
102
- const { access_token } = await this.authenticateServer({
103
- credentials,
104
- url,
105
- });
106
-
107
- await HttpService.request<void>({
108
- baseURL: url,
14
+ const { data } = await HttpService.request<Keycloak.Authenticate.Response>({
15
+ baseURL: req.url,
109
16
  method: 'post',
110
17
  resourcePath: '/',
111
- headers: {
112
- 'Cache-Control': 'no-cache',
113
- 'Content-Type': 'application/json',
114
- 'Authorization': `Bearer ${access_token}`,
115
- },
116
- body: {
117
- email: data.email,
118
- username: data.username,
119
- firstName: data.firstName,
120
- lastName: data.lastName ?? '',
121
- enabled: true,
122
- emailVerified: true,
123
- credentials: [
124
- {
125
- type: 'password',
126
- value: data.password,
127
- temporary: data.isTemporaryPassword ?? false,
128
- },
129
- ],
130
- groups: data.groups,
131
- attributes: {
132
- isFirstAccess: true,
133
- },
134
- },
135
- });
136
-
137
- }
138
-
139
- async updateUser ({
140
- credentials,
141
- data,
142
- url,
143
- }: Keycloak.UpdateUser.Request): Promise<void> {
144
- const { access_token } = await this.authenticateServer({
145
- credentials,
146
- url,
147
- });
148
-
149
- await HttpService.request<void>({
150
- baseURL: url,
151
- method: 'put',
152
- resourcePath: `/auth/admin/realms/${credentials.realm}/users/${data.id}`,
153
- headers: {
154
- 'Cache-Control': 'no-cache',
155
- 'Content-Type': 'application/json',
156
- 'Authorization': `Bearer ${access_token}`,
157
- },
158
- body: {
159
- email: data.email,
160
- username: data.username,
161
- firstName: data.firstName,
162
- lastName: data.lastName ?? '',
163
- enabled: true,
164
- emailVerified: true,
165
- ...(data.password && {
166
- credentials: [
167
- {
168
- type: 'password',
169
- value: data.password,
170
- temporary: data.isTemporaryPassword ?? false,
171
- },
172
- ],
173
- }),
174
- groups: data.groups,
175
- attributes: {
176
- isFirstAccess: false,
177
- },
178
- },
179
- });
180
- }
181
-
182
- async getUser ({
183
- credentials,
184
- data,
185
- url,
186
- }: Keycloak.GetUser.Request): Promise<Keycloak.GetUser.Response> {
187
- const { access_token } = await this.authenticateServer({
188
- credentials,
189
- url,
190
- });
191
-
192
- const { data: response } = await HttpService.request<Keycloak.GetUser.Response>({
193
- baseURL: url,
194
- method: 'get',
195
- resourcePath: `/auth/admin/realms/${credentials.realm}/users/${data.id}`,
196
- headers: {
197
- 'Cache-Control': 'no-cache',
198
- 'Content-Type': 'application/json',
199
- 'Authorization': `Bearer ${access_token}`,
200
- },
18
+ headers: {},
19
+ query: query as unknown as Record<string, unknown>,
201
20
  });
202
21
 
203
- return response;
22
+ return data;
204
23
  }
205
24
 
206
- async deleteUser ({
207
- credentials,
208
- data,
209
- url,
210
- }: Keycloak.DeleteUser.Request): Promise<void> {
211
- const { access_token } = await this.authenticateServer({
212
- credentials,
213
- url,
214
- });
215
-
216
- await HttpService.request<void>({
217
- baseURL: url,
218
- method: 'delete',
219
- resourcePath: `/auth/admin/realms/${credentials.realm}/users/${data.id}`,
220
- headers: {
221
- 'Cache-Control': 'no-cache',
222
- 'Content-Type': 'application/json',
223
- 'Authorization': `Bearer ${access_token}`,
224
- },
25
+ async refreshAccess (req: Keycloak.RefreshAccess.Request): Promise<Keycloak.RefreshAccess.Response> {
26
+ const query = new URLSearchParams({
27
+ client_id: req.credentials.clientId,
28
+ client_secret: req.credentials.clientSecret,
29
+ grant_type: 'refresh_token',
30
+ refresh_token: req.refreshToken,
225
31
  });
226
- }
227
32
 
228
- async changeUserPassword ({
229
- credentials,
230
- data,
231
- url,
232
- }: Keycloak.ChangeUserPassword.Request): Promise<void> {
233
- const { access_token } = await this.authenticateServer({
234
- credentials,
235
- url,
236
- });
237
-
238
- await HttpService.request<void>({
239
- baseURL: url,
240
- method: 'put',
241
- resourcePath: `/auth/admin/realms/${credentials.realm}/users/${data.id}/reset-password`,
242
- headers: {
243
- 'Cache-Control': 'no-cache',
244
- 'Content-Type': 'application/json',
245
- 'Authorization': `Bearer ${access_token}`,
246
- },
247
- body: {
248
- type: 'password',
249
- value: data.password,
250
- temporary: data.isTemporaryPassword ?? false,
251
- },
252
- });
253
- }
254
-
255
- async addRealm ({
256
- url,
257
- data,
258
- credentials,
259
- }: Keycloak.AddRealm.Request): Promise<void> {
260
- const { access_token } = await this.authenticateServer({
261
- credentials,
262
- url,
263
- });
264
-
265
- await HttpService.request<void>({
266
- baseURL: url,
267
- method: 'post',
268
- resourcePath: '/auth/admin/realms',
269
- headers: {
270
- 'Cache-Control': 'no-cache',
271
- 'Content-Type': 'application/json',
272
- 'Authorization': `Bearer ${access_token}`,
273
- },
274
- body: {
275
- id: data.name,
276
- realm: data.name,
277
- enabled: data.enabled ?? false,
278
- loginWithEmailAllowed: false,
279
- duplicateEmailsAllowed: true,
280
- resetPasswordAllowed: false,
281
- editUsernameAllowed: true,
282
- bruteForceProtected: true,
283
- permanentLockout: false,
284
- maxFailureWaitSeconds: 900,
285
- minimumQuickLoginWaitSeconds: 60,
286
- waitIncrementSeconds: 60,
287
- quickLoginCheckMilliSeconds: 1000,
288
- maxDeltaTimeSeconds: 43200,
289
- failureFactor: 5,
290
- },
291
- });
292
- }
293
-
294
- async addRole ({
295
- url,
296
- data,
297
- credentials,
298
- }: Keycloak.AddRole.Request): Promise<void> {
299
- const { access_token } = await this.authenticateServer({
300
- credentials,
301
- url,
302
- });
303
-
304
- await HttpService.request<void>({
305
- baseURL: url,
306
- method: 'post',
307
- resourcePath: `/auth/admin/realms/${credentials.realm}/roles`,
308
- headers: {
309
- 'Cache-Control': 'no-cache',
310
- 'Content-Type': 'application/json',
311
- 'Authorization': `Bearer ${access_token}`,
312
- },
313
- body: {
314
- name: data.name,
315
- description: data.description,
316
- },
317
- });
318
- }
319
-
320
- async associateUserRole ({
321
- url,
322
- data,
323
- credentials,
324
- }: Keycloak.AssociateUserRole.Request): Promise<void> {
325
- const { access_token } = await this.authenticateServer({
326
- credentials,
327
- url,
328
- });
329
-
330
- const { roles } = await this.getRoles({
331
- url,
332
- data: {
333
- search: data.role,
334
- },
335
- credentials,
336
- });
337
-
338
- await HttpService.request<void>({
339
- baseURL: url,
33
+ const { data } = await HttpService.request<Keycloak.RefreshAccess.Response>({
34
+ baseURL: req.url,
340
35
  method: 'post',
341
- resourcePath: `/auth/admin/realms/${credentials.realm}/users/${data.user}/role-mappings/realm`,
342
- headers: {
343
- 'Cache-Control': 'no-cache',
344
- 'Content-Type': 'application/json',
345
- 'Authorization': `Bearer ${access_token}`,
346
- },
347
- body: roles,
348
- });
349
- }
350
-
351
- async getRoles ({
352
- url,
353
- data,
354
- credentials,
355
- }: Keycloak.GetRoles.Request): Promise<Keycloak.GetRoles.Response> {
356
- const { access_token } = await this.authenticateServer({
357
- credentials,
358
- url,
359
- });
360
-
361
- const { data: response } = await HttpService.request<Roles[]>({
362
- baseURL: url,
363
- method: 'get',
364
- resourcePath: `/auth/admin/realms/${credentials.realm}/roles`,
365
- headers: {
366
- 'Cache-Control': 'no-cache',
367
- 'Content-Type': 'application/json',
368
- 'Authorization': `Bearer ${access_token}`,
369
- },
370
- query: data as unknown as Record<string, unknown>,
371
- });
372
-
373
- return {
374
- roles: response,
375
- };
376
- }
377
-
378
- async deleteRole ({
379
- url,
380
- data,
381
- credentials,
382
- }: Keycloak.DeleteRole.Request): Promise<void> {
383
- const { access_token } = await this.authenticateServer({
384
- credentials,
385
- url,
36
+ resourcePath: '/',
37
+ headers: {},
38
+ query: query as unknown as Record<string, unknown>,
386
39
  });
387
40
 
388
- await HttpService.request<void>({
389
- baseURL: url,
390
- method: 'delete',
391
- resourcePath: `/auth/admin/realms/${credentials.realm}/roles-by-id/${data.id}`,
392
- headers: {
393
- 'Cache-Control': 'no-cache',
394
- 'Content-Type': 'application/json',
395
- 'Authorization': `Bearer ${access_token}`,
396
- },
397
- });
41
+ return data;
398
42
  }
399
43
  }
400
44
 
@@ -3,45 +3,45 @@ import nodemailer from 'nodemailer';
3
3
  import { INodeMailerService, NodeMailer } from '../interfaces/nodemailer';
4
4
 
5
5
  class NodeMailerService implements INodeMailerService {
6
- async send ({ credentials, data }: NodeMailer.Send.Request): Promise<void> {
6
+ async send (req: NodeMailer.Send.Request): Promise<void> {
7
7
  const transporter = nodemailer.createTransport({
8
- host: credentials.host,
9
- port: credentials.port,
10
- secure: credentials.secure,
11
- auth: credentials.auth,
8
+ host: req.credentials.host,
9
+ port: req.credentials.port,
10
+ secure: req.credentials.secure,
11
+ auth: req.credentials.auth,
12
12
  tls: {
13
13
  rejectUnauthorized: false,
14
14
  },
15
15
  });
16
16
 
17
17
  const options = {
18
- from: data.from,
19
- to: data.to,
20
- subject: data.subject,
21
- text: data.text,
18
+ from: req.from,
19
+ to: req.to,
20
+ subject: req.subject,
21
+ text: req.text,
22
22
  };
23
23
 
24
24
  await transporter.sendMail(options);
25
25
  transporter.close();
26
26
  }
27
27
 
28
- async sendWithTemplate ({ credentials, data }: NodeMailer.SendWithTemplate.Request): Promise<void> {
28
+ async sendWithTemplate (req: NodeMailer.SendWithTemplate.Request): Promise<void> {
29
29
  const transporter = nodemailer.createTransport({
30
- host: credentials.host,
31
- port: credentials.port,
32
- secure: credentials.secure,
33
- auth: credentials.auth,
30
+ host: req.credentials.host,
31
+ port: req.credentials.port,
32
+ secure: req.credentials.secure,
33
+ auth: req.credentials.auth,
34
34
  tls: {
35
35
  rejectUnauthorized: false,
36
36
  },
37
37
  });
38
38
 
39
39
  const options = {
40
- from: data.from,
41
- to: data.to,
42
- subject: data.subject,
43
- html: data.html,
44
- attachments: data.attachments,
40
+ from: req.from,
41
+ to: req.to,
42
+ subject: req.subject,
43
+ html: req.html,
44
+ attachments: req.attachments,
45
45
  };
46
46
 
47
47
  await transporter.sendMail(options);
@@ -50,3 +50,94 @@ class NodeMailerService implements INodeMailerService {
50
50
  }
51
51
 
52
52
  export default new NodeMailerService();
53
+
54
+ /* import { ISMTPTemplateMail, ISMTPTextMail } from '@shared/mechanisms/smtp/interfaces';
55
+ import { readTemplate, stringReplace } from '@shared/utils';
56
+ import mjml from 'mjml';
57
+ import nodemailer, { SendMailOptions, Transporter } from 'nodemailer';
58
+ import { join } from 'path';
59
+
60
+ class SMTPService {
61
+ static getTransporter (): Transporter {
62
+ const { host, auth, port, secure } = getEnv().mailing.smtp;
63
+
64
+ return nodemailer.createTransport({
65
+ host,
66
+ port,
67
+ secure,
68
+ auth,
69
+ tls: {
70
+ rejectUnauthorized: false,
71
+ },
72
+ });
73
+ }
74
+
75
+ static async send (params: ISMTPTextMail): Promise<void> {
76
+ const transporter = SMTPService.getTransporter();
77
+
78
+ const options: SendMailOptions = {
79
+ from: {
80
+ name: params.from.name,
81
+ address: params.from.address,
82
+ },
83
+ to: params.to,
84
+ subject: params.subject,
85
+ text: params.text,
86
+ };
87
+
88
+ await transporter.sendMail(options);
89
+ transporter.close();
90
+ }
91
+
92
+ static async sendWithTemplate (params: ISMTPTemplateMail): Promise<void> {
93
+ const transporter = SMTPService.getTransporter();
94
+
95
+ const options: SendMailOptions = {
96
+ from: {
97
+ name: params.from.name,
98
+ address: params.from.address,
99
+ },
100
+ to: params.to,
101
+ subject: params.subject,
102
+ html: params.template,
103
+ attachments: params.attachments,
104
+ };
105
+
106
+ await transporter.sendMail(options);
107
+ transporter.close();
108
+ }
109
+
110
+ static async getTemplate (filename: string, options?: Dictionary<string | number>) {
111
+ let template = null;
112
+
113
+ const path = join(__dirname, `./templates/${filename}`);
114
+
115
+ try {
116
+ template = await readTemplate(path, 'utf8');
117
+
118
+ if (!template) throw new BusinessError(BusinessErrorCodes.TEMPLATE_NOT_FOUND);
119
+
120
+ } catch (err) {
121
+ throw new BusinessError(BusinessErrorCodes.TEMPLATE_NOT_FOUND);
122
+ }
123
+
124
+ if (options) {
125
+ template = stringReplace(template, options);
126
+ }
127
+
128
+ if (filename.includes('.mjml')) {
129
+ const { html, errors } = mjml(template);
130
+
131
+ if (errors && errors.length) {
132
+ throw new BusinessError(BusinessErrorCodes.TEMPLATE_NOT_FOUND);
133
+ }
134
+
135
+ template = html;
136
+ }
137
+
138
+ return template;
139
+ }
140
+ }
141
+
142
+ export default SMTPService;
143
+ */
@@ -1,11 +1,12 @@
1
- import { createClient, SetOptions } from 'redis';
1
+ import { createClient, RedisClientType } from 'redis';
2
2
 
3
3
  import { IRedisService, Redis } from '../interfaces/redis';
4
4
 
5
5
  class RedisService implements IRedisService {
6
+ private client: RedisClientType;
6
7
 
7
- public async set ({ credentials, data }: Redis.Set.Request): Promise<void> {
8
- const client = createClient({
8
+ constructor (private credentials: Redis.Credentials) {
9
+ this.client = createClient({
9
10
  socket: {
10
11
  host: credentials.host,
11
12
  port: credentials.port,
@@ -13,69 +14,32 @@ class RedisService implements IRedisService {
13
14
  password: credentials.password,
14
15
  });
15
16
 
16
- const options: SetOptions = {
17
- ...data.ttl && {
18
- expiration: {
19
- type: 'EX',
20
- value: data.ttl,
21
- },
22
- },
23
- };
24
-
25
- await client.connect();
26
- await client.set(data.key, JSON.stringify(data.value), options);
27
- await client.close();
17
+ this.client.connect();
28
18
  }
29
19
 
30
- public async get<T> ({ credentials, data }: Redis.Get.Request): Promise<Redis.Get.Response<T>> {
31
- const client = createClient({
32
- socket: {
33
- host: credentials.host,
34
- port: credentials.port,
35
- },
36
- password: credentials.password,
37
- });
38
-
39
- await client.connect();
40
- const response = await client.get(data.key);
41
- await client.close();
20
+ public async set (key: string, value: unknown, ttl?: number): Promise<void> {
21
+ const data = JSON.stringify(value);
42
22
 
43
- return {
44
- data: typeof response === 'string' ? (JSON.parse(response) as T) : null,
45
- };
23
+ if (ttl) {
24
+ await this.client.set(key, data, { EX: ttl });
25
+ } else {
26
+ await this.client.set(key, data);
27
+ }
46
28
  }
47
29
 
48
- public async del ({ credentials, data }: Redis.Get.Request): Promise<void> {
49
- const client = createClient({
50
- socket: {
51
- host: credentials.host,
52
- port: credentials.port,
53
- },
54
- password: credentials.password,
55
- });
56
-
57
- await client.connect();
58
- await client.del(data.key);
59
- await client.close();
30
+ public async get<T> (key: string): Promise<T | null> {
31
+ const data = await this.client.get(key);
32
+ return typeof data === 'string' ? (JSON.parse(data) as T) : null;
60
33
  }
61
34
 
62
- public async exists ({ credentials, data }: Redis.Get.Request): Promise<Redis.Exists.Response> {
63
- const client = createClient({
64
- socket: {
65
- host: credentials.host,
66
- port: credentials.port,
67
- },
68
- password: credentials.password,
69
- });
70
-
71
- await client.connect();
72
- const exists = await client.exists(data.key);
73
- await client.close();
35
+ public async del (key: string): Promise<void> {
36
+ await this.client.del(key);
37
+ }
74
38
 
75
- return {
76
- exists: !!exists,
77
- };
39
+ public async exists (key: string): Promise<boolean> {
40
+ const exists = await this.client.exists(key);
41
+ return exists === 1;
78
42
  }
79
43
  }
80
44
 
81
- export default new RedisService();
45
+ export default RedisService;