@futdevpro/nts-dynamo 1.9.15 → 1.9.16

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 (117) hide show
  1. package/.copilot/patterns.json +7 -7
  2. package/.github/workflows/main.yml +206 -0
  3. package/HOWTO.md +15 -15
  4. package/README.md +140 -140
  5. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  6. package/build/_models/control-models/endpoint-params.control-model.js +2 -0
  7. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  8. package/build/_models/control-models/socket-event.control-model.js +1 -1
  9. package/build/_services/core/global.service.d.ts.map +1 -1
  10. package/build/_services/core/global.service.js +1 -0
  11. package/build/_services/core/global.service.js.map +1 -1
  12. package/build/_services/route/routing-module.service.d.ts +1 -0
  13. package/build/_services/route/routing-module.service.d.ts.map +1 -1
  14. package/build/_services/route/routing-module.service.js +17 -23
  15. package/build/_services/route/routing-module.service.js.map +1 -1
  16. package/build/_services/server/app.server.d.ts.map +1 -1
  17. package/build/_services/server/app.server.js +4 -1
  18. package/build/_services/server/app.server.js.map +1 -1
  19. package/build/_services/socket/socket-client.service.d.ts.map +1 -1
  20. package/build/_services/socket/socket-client.service.js +1 -0
  21. package/build/_services/socket/socket-client.service.js.map +1 -1
  22. package/nodemon.json +17 -15
  23. package/package.json +5 -5
  24. package/src/_constants/global-settings.const.ts +27 -27
  25. package/src/_constants/index.ts +2 -2
  26. package/src/_constants/mocks/app-extended-server.mock.ts +198 -198
  27. package/src/_constants/mocks/app-params.mock.ts +9 -9
  28. package/src/_constants/mocks/app-server.mock.ts +185 -185
  29. package/src/_constants/mocks/auth-service.mock.ts +28 -28
  30. package/src/_constants/mocks/controller.mock.ts +16 -16
  31. package/src/_constants/mocks/data-model.mock.ts +83 -83
  32. package/src/_constants/mocks/email-service-collection.mock.ts +13 -13
  33. package/src/_constants/mocks/email-service.mock.ts +19 -19
  34. package/src/_constants/mocks/email-template.mock.html +14 -14
  35. package/src/_constants/mocks/endpoint.mock.ts +90 -90
  36. package/src/_constants/mocks/socket-client.mock.ts +43 -43
  37. package/src/_constants/mocks/socket-server.mock.ts +43 -43
  38. package/src/_enums/data-model-type.enum.ts +14 -14
  39. package/src/_enums/data-service-function.enum.ts +15 -15
  40. package/src/_enums/http/http-call-type.enum.ts +12 -12
  41. package/src/_enums/http/http-response-type.enum.ts +7 -7
  42. package/src/_enums/http/socket-event-type.enum.ts +18 -18
  43. package/src/_enums/index.ts +13 -13
  44. package/src/_enums/predefined-data-types.enum.ts +27 -27
  45. package/src/_enums/route-security.enum.ts +12 -12
  46. package/src/_enums/socket-security.enum.ts +11 -11
  47. package/src/_models/control-models/api-call-params.control-model.ts +126 -126
  48. package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
  49. package/src/_models/control-models/app-params.control-model.ts +45 -45
  50. package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
  51. package/src/_models/control-models/endpoint-params.control-model.ts +309 -307
  52. package/src/_models/control-models/http-settings.control-model.ts +29 -29
  53. package/src/_models/control-models/index.ts +13 -13
  54. package/src/_models/control-models/socket-client-service-params.control-model.ts +28 -28
  55. package/src/_models/control-models/socket-event.control-model.ts +150 -150
  56. package/src/_models/control-models/socket-presence.control-model.ts +207 -207
  57. package/src/_models/control-models/socket-server-service-params.control-model.ts +20 -20
  58. package/src/_models/control-models/system-control.control-model.ts +12 -12
  59. package/src/_models/index.ts +9 -9
  60. package/src/_models/interfaces/certification-settings.interface.ts +7 -7
  61. package/src/_models/interfaces/global-service-settings.interface.ts +45 -45
  62. package/src/_models/interfaces/global-settings.interface.ts +83 -83
  63. package/src/_models/interfaces/index.ts +7 -7
  64. package/src/_models/interfaces/routing-module-settings.interface.ts +20 -20
  65. package/src/_models/types/db-filter.type.ts +108 -108
  66. package/src/_models/types/db-update.type.ts +100 -100
  67. package/src/_models/types/index.ts +5 -5
  68. package/src/_modules/api-service.index.ts +12 -12
  69. package/src/_modules/app-extended.index.ts +28 -28
  70. package/src/_modules/app.index.ts +24 -24
  71. package/src/_modules/auth.index.ts +7 -7
  72. package/src/_modules/constants.index.ts +2 -2
  73. package/src/_modules/controller.index.ts +10 -10
  74. package/src/_modules/custom-data/custom-data.controller.ts +69 -69
  75. package/src/_modules/custom-data/custom-data.data-service.ts +20 -20
  76. package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +23 -23
  77. package/src/_modules/custom-data/index.ts +6 -6
  78. package/src/_modules/custom-data-module.index.ts +2 -2
  79. package/src/_modules/data-service.index.ts +9 -9
  80. package/src/_modules/email.index.ts +8 -8
  81. package/src/_modules/enums.index.ts +2 -2
  82. package/src/_modules/extended.index.ts +8 -8
  83. package/src/_modules/models.index.ts +2 -2
  84. package/src/_modules/services.index.ts +2 -2
  85. package/src/_modules/test/get-test-routing-module.util.ts +23 -23
  86. package/src/_modules/test/index.ts +5 -5
  87. package/src/_modules/test/test.controller.ts +115 -115
  88. package/src/_modules/test-module.index.ts +2 -2
  89. package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
  90. package/src/_modules/usage/index.ts +7 -7
  91. package/src/_modules/usage/usage.controller.ts +120 -120
  92. package/src/_modules/usage/usage.data-service.ts +172 -172
  93. package/src/_modules/usage-module.index.ts +2 -2
  94. package/src/_services/base/data.service.ts +921 -921
  95. package/src/_services/base/db.service.spec.ts +32 -32
  96. package/src/_services/base/db.service.ts +1063 -1063
  97. package/src/_services/base/singleton.service.ts +21 -21
  98. package/src/_services/core/api.service.ts +453 -453
  99. package/src/_services/core/auth.service.ts +172 -172
  100. package/src/_services/core/email.service.ts +678 -678
  101. package/src/_services/core/global.service.ts +270 -269
  102. package/src/_services/core/service-collection.service.ts +5 -5
  103. package/src/_services/index.ts +23 -23
  104. package/src/_services/route/controller.service.ts +129 -129
  105. package/src/_services/route/routing-module.service.ts +293 -273
  106. package/src/_services/server/app-extended.server.spec.ts +76 -76
  107. package/src/_services/server/app-extended.server.ts +520 -520
  108. package/src/_services/server/app.server.spec.ts +67 -67
  109. package/src/_services/server/app.server.ts +1181 -1179
  110. package/src/_services/shared.service.spec.ts +19 -19
  111. package/src/_services/shared.static-service.ts +73 -73
  112. package/src/_services/socket/socket-client.service.ts +236 -235
  113. package/src/_services/socket/socket-server.service.spec.ts +11 -11
  114. package/src/_services/socket/socket-server.service.ts +761 -761
  115. package/src/index.ts +18 -18
  116. package/tsconfig.json +41 -41
  117. package/build/tsconfig.tsbuildinfo +0 -1
@@ -1,453 +1,453 @@
1
-
2
- import * as Axios from 'axios';
3
- import {
4
- DynamoFM_AnyError, DynamoFM_Error, DynamoFM_Error_Settings, DynamoFM_Log
5
- } from '@futdevpro/fsm-dynamo';
6
-
7
- import { DynamoNTS_HttpCallType } from '../../_enums/http/http-call-type.enum';
8
- import { DynamoNTS_HttpResponseType } from '../../_enums/http/http-response-type.enum';
9
- import {
10
- DynamoNTS_ApiCall_Params
11
- } from '../../_models/control-models/api-call-params.control-model';
12
- import { DynamoNTS_globalSettings } from '../../_constants';
13
-
14
- export interface DynamoNTS_ApiCallInput_Params<T_Body = any> {
15
- pathParams?: {
16
- /**
17
- * path params setted in endpoint
18
- */
19
- [param: string]: string;
20
- };
21
- /**
22
- * api call's body
23
- */
24
- body?: T_Body;
25
- }
26
-
27
- /**
28
- * This predefined Api service contains the basic API call function which can be used in various ways
29
- */
30
- export class DynamoNTS_ApiService {
31
-
32
- static defaultErrorUserMsg =
33
- `We encountered a BackEnd API Error, ` +
34
- `\nplease contact the responsible development team.\n` +
35
- `\n(Internal BE to BE error)`;
36
-
37
- /**
38
- * if the callParams.getFullResponse is set to true,
39
- * use the Axios.AxiosResponse type as T_Response
40
- *
41
- * @param callParams
42
- * @param inputParams
43
- * @returns
44
- */
45
- public static async startApiCall<T_Response, T_Body = any>(
46
- /**
47
- * you must setup the basic api call params with this.
48
- * follow the instructions in the constructor: new DynamoNTS_ApiCallParams({ ... })
49
- */
50
- callParams: DynamoNTS_ApiCall_Params,
51
- /**
52
- * you can pass data and other inputs in this section
53
- */
54
- inputParams?: DynamoNTS_ApiCallInput_Params<T_Body>
55
- ): Promise<T_Response /* | Axios.AxiosResponse */> {
56
- try {
57
- let a: T_Response;
58
- let url: string = callParams.baseUrl + callParams.endPoint;
59
- const axios = Axios.default.create();
60
-
61
- if (callParams?.httpOptions?.headers) {
62
- this.setupHeaders(callParams, axios);
63
- }
64
-
65
- if (inputParams?.pathParams) {
66
- url = this.setupPathParams(inputParams.pathParams, url);
67
- }
68
-
69
- /* if (inputParams?.queryParams) {
70
- this.setupQueryParams<T_Body>(inputParams, callParams);
71
- } */
72
-
73
- if (DynamoNTS_globalSettings.logApiEvents) {
74
- this.logEvent(url, inputParams, callParams);
75
- }
76
-
77
- switch (callParams.type) {
78
- case DynamoNTS_HttpCallType.get:
79
- if (inputParams?.body) {
80
- DynamoFM_Log.warn('WARNING you cant send body in get calls');
81
- }
82
-
83
- a = await this.get<T_Response>(axios, url, callParams);
84
- break;
85
-
86
- case DynamoNTS_HttpCallType.delete:
87
- if (inputParams?.body) {
88
- DynamoFM_Log.warn('WARNING you cant send body in delete calls');
89
- }
90
-
91
- a = await this.delete<T_Response>(axios, url, callParams);
92
- break;
93
-
94
- case DynamoNTS_HttpCallType.post:
95
- case DynamoNTS_HttpCallType.put:
96
- case DynamoNTS_HttpCallType.patch:
97
- if (!inputParams?.body) {
98
- if (!inputParams) {
99
- inputParams = {};
100
- }
101
-
102
- inputParams.body = {} as T_Body;
103
- }
104
-
105
- a = await this.postPutPatch<T_Response, T_Body>(axios, callParams, url, inputParams);
106
- break;
107
-
108
- default:
109
- throw new DynamoFM_Error({
110
- ...this._getDefaultErrorSettings(
111
- 'startApiCall',
112
- new Error('wrong api call type')
113
- ),
114
- errorCode: 'NTS-API-SAC0',
115
- additionalContent: {
116
- callParams,
117
- inputParams,
118
- },
119
- });
120
- //DynamoFM_Log.error('DYNAMO-NTS ERROR: \n wrong api call type'/* , '\n\n', new Error() */);
121
- break;
122
- }
123
-
124
- if (callParams.getFullResponse) {
125
- return a as T_Response /* Axios.AxiosResponse */;
126
-
127
- } else {
128
- return a as T_Response;
129
- }
130
- } catch (error) {
131
- this.handleError<T_Body>(callParams, error, inputParams);
132
- }
133
- }
134
-
135
- /* private static setupQueryParams<T_Body = any>(
136
- inputParams: DynamoNTS_ApiCallInputParams<T_Body>, callParams: DynamoNTS_ApiCallParams) {
137
- const httpParams = new HttpParams();
138
-
139
- for (const queryParamKey in inputParams.queryParams) {
140
- if (inputParams.queryParams[queryParamKey]) {
141
- switch (typeof inputParams.queryParams[queryParamKey]) {
142
- case 'number':
143
- httpParams.set(queryParamKey, inputParams.queryParams[queryParamKey].toString());
144
- break;
145
-
146
- case 'string':
147
- httpParams.set(queryParamKey, inputParams.queryParams[queryParamKey]);
148
- break;
149
-
150
- default:
151
- console.error('DYNAMO-NTS ERROR: \n wrong query param type', '\n\n', new Error());
152
- break;
153
- }
154
- }
155
- }
156
- callParams.httpOptions.params = httpParams;
157
- } */
158
-
159
- private static handleError<T_Body>(
160
- callParams: DynamoNTS_ApiCall_Params,
161
- error: any,
162
- inputParams: {
163
- pathParams?: { [param: string]: string; };
164
- /**
165
- * api call's body
166
- */
167
- body?: T_Body;
168
- }
169
- ): void {
170
- DynamoFM_Log.error(
171
- `\n---> API ERROR: '${callParams?.name}' failed...` +
172
- `\n${callParams?.baseUrl}${callParams?.endPoint}`
173
- );
174
-
175
- if (DynamoNTS_globalSettings.logDetailedErrors) {
176
- DynamoFM_Log.error(`\ncallParams:`, callParams);
177
- }
178
-
179
- if (error && callParams?.httpOptions?.responseType === DynamoNTS_HttpResponseType.text) {
180
- error.error = JSON.parse(error?.error);
181
- }
182
-
183
- if ((error?.response?.data as DynamoFM_Error)?.flag?.includes('DYNAMO')) {
184
- DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
185
-
186
- throw new DynamoFM_Error({
187
- ...this._getDefaultErrorSettings(
188
- callParams.name + ' startApiCall',
189
- error.response.data
190
- ),
191
-
192
- errorCode: 'NTS-API-SAC1',
193
- message: 'API call failed on the other end! error response found...',
194
- additionalContent: {
195
- callParams,
196
- inputParams,
197
- },
198
- });
199
-
200
- } else if (error.code === 'ENOTFOUND') {
201
- DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
202
-
203
- throw new DynamoFM_Error({
204
- ...this._getDefaultErrorSettings(
205
- callParams.name + ' startApiCall',
206
- error
207
- ),
208
-
209
- status: 404,
210
- errorCode: 'NTS-API-SAC2',
211
- message: 'DNS error; address cannot be resolved!',
212
- additionalContent: {
213
- callParams,
214
- inputParams,
215
- },
216
- });
217
-
218
- } else if (error.code === 'ECONNREFUSED') {
219
- DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
220
-
221
- throw new DynamoFM_Error({
222
- ...this._getDefaultErrorSettings(
223
- callParams.name + ' startApiCall',
224
- error
225
- ),
226
-
227
- status: 404,
228
- errorCode: 'NTS-API-SAC3',
229
- message: `Can't connect to the endpoint!`,
230
- additionalContent: {
231
- callParams,
232
- inputParams,
233
- },
234
- });
235
-
236
- } else if (error.config && error.message) {
237
-
238
- throw new DynamoFM_Error({
239
- ...this._getDefaultErrorSettings(
240
- callParams.name + ' startApiCall',
241
- error
242
- ),
243
-
244
- status: +error.message.substring(error.message.length - 4, 3),
245
- errorCode: 'NTS-API-SAC4',
246
- additionalContent: {
247
- callParams,
248
- inputParams,
249
- },
250
- });
251
- } else {
252
- DynamoFM_Log.error(
253
- `\n${callParams.name} was UNSUCCESSFUL`,
254
- error /*, '\n\n' , new Error() */
255
- );
256
-
257
- throw error;
258
- }
259
- }
260
-
261
- private static async postPutPatch<T_Response, T_Body>(
262
- axios: Axios.AxiosInstance,
263
- callParams: DynamoNTS_ApiCall_Params,
264
- url: string,
265
- inputParams: DynamoNTS_ApiCallInput_Params<T_Body>
266
- ): Promise<T_Response> {
267
- return await axios[callParams.type]<T_Response>(
268
- url,
269
- inputParams.body,
270
- callParams.httpOptions
271
- ).then((res: Axios.AxiosResponse): T_Response => {
272
- if (DynamoNTS_globalSettings.logApiEvents) {
273
- if (DynamoNTS_globalSettings.logApiResponseContents) {
274
- DynamoFM_Log.success(`---> '${callParams.name}' api call was successful`, res.data);
275
-
276
- } else {
277
- DynamoFM_Log.success(`---> '${callParams.name}' api call was successful`);
278
- }
279
- }
280
-
281
- if (callParams.getFullResponse) {
282
- return res as T_Response;
283
- } else {
284
- return res.data;
285
- }
286
- });
287
- }
288
-
289
- private static async delete<T_Response>(
290
- axios: Axios.AxiosInstance,
291
- url: string,
292
- callParams: DynamoNTS_ApiCall_Params
293
- ): Promise<T_Response> {
294
- return await axios.delete<T_Response>(url, callParams.httpOptions).then(
295
- (res: Axios.AxiosResponse): T_Response => {
296
- if (DynamoNTS_globalSettings.logApiEvents) {
297
- if (DynamoNTS_globalSettings.logApiResponseContents) {
298
- DynamoFM_Log.success(`'${callParams.name}' was successful`, res.data);
299
- } else {
300
- DynamoFM_Log.success(`'${callParams.name}' was successful`);
301
- }
302
- }
303
-
304
- if (callParams.getFullResponse) {
305
- return res as T_Response;
306
- }
307
- }
308
- );
309
- }
310
-
311
- private static async get<T_Response>(
312
- axios: Axios.AxiosInstance,
313
- url: string,
314
- callParams: DynamoNTS_ApiCall_Params
315
- ): Promise<T_Response> {
316
- return await axios.get<T_Response>(url, callParams.httpOptions).then(
317
- (res: Axios.AxiosResponse): T_Response => {
318
- if (DynamoNTS_globalSettings.logApiEvents) {
319
- if (DynamoNTS_globalSettings.logApiResponseContents) {
320
- DynamoFM_Log.success(`'${callParams.name}' was successful`, res.data);
321
- } else {
322
- DynamoFM_Log.success(`'${callParams.name}' was successful`);
323
- }
324
- }
325
-
326
- if (callParams.getFullResponse) {
327
- return res as T_Response;
328
- } else {
329
- return res.data;
330
- }
331
- }
332
- );
333
- }
334
-
335
- private static logEvent<T_Body>(
336
- url: string,
337
- inputParams: DynamoNTS_ApiCallInput_Params<T_Body>,
338
- callParams: DynamoNTS_ApiCall_Params
339
- ): void {
340
- if (DynamoNTS_globalSettings.logApiRequestContents) {
341
- DynamoFM_Log.log(
342
- `<--- outgoing API call: '${callParams?.name}' ` +
343
- `\n(${url})` +
344
- `\nbody:`, inputParams?.body
345
- );
346
-
347
- } else {
348
- DynamoFM_Log.log(`<--- outgoing API call: '${callParams?.name}'`);
349
- }
350
-
351
- if (DynamoNTS_globalSettings.logApiRequestSettings) {
352
- DynamoFM_Log.log(`callParams:`, callParams);
353
- DynamoFM_Log.log('inputParams:', {
354
- pathParams: inputParams.pathParams ?? {},
355
- body: inputParams.body ?? null,
356
- });
357
- }
358
- }
359
-
360
- private static setupHeaders(
361
- callParams: DynamoNTS_ApiCall_Params,
362
- axios: Axios.AxiosInstance
363
- ): void {
364
- for (const headerKey in callParams.httpOptions.headers) {
365
- if (callParams.httpOptions.headers[headerKey]) {
366
- axios.defaults.headers.common[headerKey] = callParams.httpOptions.headers[headerKey];
367
-
368
- } else {
369
- throw new DynamoFM_Error({
370
- ...this._getDefaultErrorSettings(
371
- 'setupHeaders',
372
- new Error(`missing header: ${headerKey}`)
373
- ),
374
- errorCode: 'NTS-API-SH0',
375
- });
376
- }
377
- }
378
- }
379
-
380
- private static setupPathParams(
381
- pathParams: { [param: string]: string; },
382
- url: string
383
- ): string {
384
- for (const pathParamKey in pathParams) {
385
- if (pathParams[pathParamKey]) {
386
- const paramType = typeof pathParams[pathParamKey];
387
-
388
- switch (paramType) {
389
- case 'number':
390
- url = url.replace(
391
- `:${pathParamKey}`,
392
- pathParams[pathParamKey].toString()
393
- );
394
- break;
395
-
396
- case 'string':
397
- url = url.replace(`:${pathParamKey}`, pathParams[pathParamKey]);
398
- break;
399
-
400
- default:
401
- /* DynamoFM_Log.error(
402
- `DYNAMO-NTS ERROR:`+
403
- `\nwrong path param type: (${pathParamKey}): ${paramType} ` +
404
- `\n${pathParams[pathParamKey]}` +
405
- `\nMUST BE string or number` +
406
- `\n\n`,
407
- new Error()
408
- ); */
409
- throw new DynamoFM_Error({
410
- ...this._getDefaultErrorSettings(
411
- 'setupPathParams',
412
- new Error(
413
- `wrong path param type: (${pathParamKey}): ${paramType}` +
414
- `\n${pathParams[pathParamKey]}`
415
- )
416
- ),
417
- errorCode: 'NTS-API-SP1',
418
- additionalContent: {
419
- pathParams: pathParams,
420
- url: url,
421
- },
422
- });
423
- break;
424
- }
425
- } else {
426
- throw new DynamoFM_Error({
427
- ...this._getDefaultErrorSettings(
428
- 'setupPathParams',
429
- new Error(`missing pathParam: ${pathParamKey}`)
430
- ),
431
- errorCode: 'NTS-API-SP0',
432
- });
433
- }
434
- }
435
-
436
- return url;
437
- }
438
-
439
- private static _getDefaultErrorSettings(
440
- fnName: string,
441
- error: DynamoFM_AnyError
442
- ): DynamoFM_Error_Settings {
443
- return {
444
- status: (error as DynamoFM_Error)?.___status ?? 500,
445
- message: (error as Error)?.message ?? `${fnName} was UNSUCCESFUL (NTS)`,
446
- addECToUserMsg: !(error as DynamoFM_Error)?.__userMessage,
447
- userMessage: (error as DynamoFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
448
- issuerService: `${this?.constructor?.name}-${this?.name}-DynamoNTS_ApiService`,
449
- error: error,
450
- };
451
- }
452
- }
453
-
1
+
2
+ import * as Axios from 'axios';
3
+ import {
4
+ DynamoFM_AnyError, DynamoFM_Error, DynamoFM_Error_Settings, DynamoFM_Log
5
+ } from '@futdevpro/fsm-dynamo';
6
+
7
+ import { DynamoNTS_HttpCallType } from '../../_enums/http/http-call-type.enum';
8
+ import { DynamoNTS_HttpResponseType } from '../../_enums/http/http-response-type.enum';
9
+ import {
10
+ DynamoNTS_ApiCall_Params
11
+ } from '../../_models/control-models/api-call-params.control-model';
12
+ import { DynamoNTS_globalSettings } from '../../_constants';
13
+
14
+ export interface DynamoNTS_ApiCallInput_Params<T_Body = any> {
15
+ pathParams?: {
16
+ /**
17
+ * path params setted in endpoint
18
+ */
19
+ [param: string]: string;
20
+ };
21
+ /**
22
+ * api call's body
23
+ */
24
+ body?: T_Body;
25
+ }
26
+
27
+ /**
28
+ * This predefined Api service contains the basic API call function which can be used in various ways
29
+ */
30
+ export class DynamoNTS_ApiService {
31
+
32
+ static defaultErrorUserMsg =
33
+ `We encountered a BackEnd API Error, ` +
34
+ `\nplease contact the responsible development team.\n` +
35
+ `\n(Internal BE to BE error)`;
36
+
37
+ /**
38
+ * if the callParams.getFullResponse is set to true,
39
+ * use the Axios.AxiosResponse type as T_Response
40
+ *
41
+ * @param callParams
42
+ * @param inputParams
43
+ * @returns
44
+ */
45
+ public static async startApiCall<T_Response, T_Body = any>(
46
+ /**
47
+ * you must setup the basic api call params with this.
48
+ * follow the instructions in the constructor: new DynamoNTS_ApiCallParams({ ... })
49
+ */
50
+ callParams: DynamoNTS_ApiCall_Params,
51
+ /**
52
+ * you can pass data and other inputs in this section
53
+ */
54
+ inputParams?: DynamoNTS_ApiCallInput_Params<T_Body>
55
+ ): Promise<T_Response /* | Axios.AxiosResponse */> {
56
+ try {
57
+ let a: T_Response;
58
+ let url: string = callParams.baseUrl + callParams.endPoint;
59
+ const axios = Axios.default.create();
60
+
61
+ if (callParams?.httpOptions?.headers) {
62
+ this.setupHeaders(callParams, axios);
63
+ }
64
+
65
+ if (inputParams?.pathParams) {
66
+ url = this.setupPathParams(inputParams.pathParams, url);
67
+ }
68
+
69
+ /* if (inputParams?.queryParams) {
70
+ this.setupQueryParams<T_Body>(inputParams, callParams);
71
+ } */
72
+
73
+ if (DynamoNTS_globalSettings.logApiEvents) {
74
+ this.logEvent(url, inputParams, callParams);
75
+ }
76
+
77
+ switch (callParams.type) {
78
+ case DynamoNTS_HttpCallType.get:
79
+ if (inputParams?.body) {
80
+ DynamoFM_Log.warn('WARNING you cant send body in get calls');
81
+ }
82
+
83
+ a = await this.get<T_Response>(axios, url, callParams);
84
+ break;
85
+
86
+ case DynamoNTS_HttpCallType.delete:
87
+ if (inputParams?.body) {
88
+ DynamoFM_Log.warn('WARNING you cant send body in delete calls');
89
+ }
90
+
91
+ a = await this.delete<T_Response>(axios, url, callParams);
92
+ break;
93
+
94
+ case DynamoNTS_HttpCallType.post:
95
+ case DynamoNTS_HttpCallType.put:
96
+ case DynamoNTS_HttpCallType.patch:
97
+ if (!inputParams?.body) {
98
+ if (!inputParams) {
99
+ inputParams = {};
100
+ }
101
+
102
+ inputParams.body = {} as T_Body;
103
+ }
104
+
105
+ a = await this.postPutPatch<T_Response, T_Body>(axios, callParams, url, inputParams);
106
+ break;
107
+
108
+ default:
109
+ throw new DynamoFM_Error({
110
+ ...this._getDefaultErrorSettings(
111
+ 'startApiCall',
112
+ new Error('wrong api call type')
113
+ ),
114
+ errorCode: 'NTS-API-SAC0',
115
+ additionalContent: {
116
+ callParams,
117
+ inputParams,
118
+ },
119
+ });
120
+ //DynamoFM_Log.error('DYNAMO-NTS ERROR: \n wrong api call type'/* , '\n\n', new Error() */);
121
+ break;
122
+ }
123
+
124
+ if (callParams.getFullResponse) {
125
+ return a as T_Response /* Axios.AxiosResponse */;
126
+
127
+ } else {
128
+ return a as T_Response;
129
+ }
130
+ } catch (error) {
131
+ this.handleError<T_Body>(callParams, error, inputParams);
132
+ }
133
+ }
134
+
135
+ /* private static setupQueryParams<T_Body = any>(
136
+ inputParams: DynamoNTS_ApiCallInputParams<T_Body>, callParams: DynamoNTS_ApiCallParams) {
137
+ const httpParams = new HttpParams();
138
+
139
+ for (const queryParamKey in inputParams.queryParams) {
140
+ if (inputParams.queryParams[queryParamKey]) {
141
+ switch (typeof inputParams.queryParams[queryParamKey]) {
142
+ case 'number':
143
+ httpParams.set(queryParamKey, inputParams.queryParams[queryParamKey].toString());
144
+ break;
145
+
146
+ case 'string':
147
+ httpParams.set(queryParamKey, inputParams.queryParams[queryParamKey]);
148
+ break;
149
+
150
+ default:
151
+ console.error('DYNAMO-NTS ERROR: \n wrong query param type', '\n\n', new Error());
152
+ break;
153
+ }
154
+ }
155
+ }
156
+ callParams.httpOptions.params = httpParams;
157
+ } */
158
+
159
+ private static handleError<T_Body>(
160
+ callParams: DynamoNTS_ApiCall_Params,
161
+ error: any,
162
+ inputParams: {
163
+ pathParams?: { [param: string]: string; };
164
+ /**
165
+ * api call's body
166
+ */
167
+ body?: T_Body;
168
+ }
169
+ ): void {
170
+ DynamoFM_Log.error(
171
+ `\n---> API ERROR: '${callParams?.name}' failed...` +
172
+ `\n${callParams?.baseUrl}${callParams?.endPoint}`
173
+ );
174
+
175
+ if (DynamoNTS_globalSettings.logDetailedErrors) {
176
+ DynamoFM_Log.error(`\ncallParams:`, callParams);
177
+ }
178
+
179
+ if (error && callParams?.httpOptions?.responseType === DynamoNTS_HttpResponseType.text) {
180
+ error.error = JSON.parse(error?.error);
181
+ }
182
+
183
+ if ((error?.response?.data as DynamoFM_Error)?.flag?.includes('DYNAMO')) {
184
+ DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
185
+
186
+ throw new DynamoFM_Error({
187
+ ...this._getDefaultErrorSettings(
188
+ callParams.name + ' startApiCall',
189
+ error.response.data
190
+ ),
191
+
192
+ errorCode: 'NTS-API-SAC1',
193
+ message: 'API call failed on the other end! error response found...',
194
+ additionalContent: {
195
+ callParams,
196
+ inputParams,
197
+ },
198
+ });
199
+
200
+ } else if (error.code === 'ENOTFOUND') {
201
+ DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
202
+
203
+ throw new DynamoFM_Error({
204
+ ...this._getDefaultErrorSettings(
205
+ callParams.name + ' startApiCall',
206
+ error
207
+ ),
208
+
209
+ status: 404,
210
+ errorCode: 'NTS-API-SAC2',
211
+ message: 'DNS error; address cannot be resolved!',
212
+ additionalContent: {
213
+ callParams,
214
+ inputParams,
215
+ },
216
+ });
217
+
218
+ } else if (error.code === 'ECONNREFUSED') {
219
+ DynamoFM_Log.error(`\n'${callParams.name}' was UNSUCCESSFUL` /* , new Error() */);
220
+
221
+ throw new DynamoFM_Error({
222
+ ...this._getDefaultErrorSettings(
223
+ callParams.name + ' startApiCall',
224
+ error
225
+ ),
226
+
227
+ status: 404,
228
+ errorCode: 'NTS-API-SAC3',
229
+ message: `Can't connect to the endpoint!`,
230
+ additionalContent: {
231
+ callParams,
232
+ inputParams,
233
+ },
234
+ });
235
+
236
+ } else if (error.config && error.message) {
237
+
238
+ throw new DynamoFM_Error({
239
+ ...this._getDefaultErrorSettings(
240
+ callParams.name + ' startApiCall',
241
+ error
242
+ ),
243
+
244
+ status: +error.message.substring(error.message.length - 4, 3),
245
+ errorCode: 'NTS-API-SAC4',
246
+ additionalContent: {
247
+ callParams,
248
+ inputParams,
249
+ },
250
+ });
251
+ } else {
252
+ DynamoFM_Log.error(
253
+ `\n${callParams.name} was UNSUCCESSFUL`,
254
+ error /*, '\n\n' , new Error() */
255
+ );
256
+
257
+ throw error;
258
+ }
259
+ }
260
+
261
+ private static async postPutPatch<T_Response, T_Body>(
262
+ axios: Axios.AxiosInstance,
263
+ callParams: DynamoNTS_ApiCall_Params,
264
+ url: string,
265
+ inputParams: DynamoNTS_ApiCallInput_Params<T_Body>
266
+ ): Promise<T_Response> {
267
+ return await axios[callParams.type]<T_Response>(
268
+ url,
269
+ inputParams.body,
270
+ callParams.httpOptions
271
+ ).then((res: Axios.AxiosResponse): T_Response => {
272
+ if (DynamoNTS_globalSettings.logApiEvents) {
273
+ if (DynamoNTS_globalSettings.logApiResponseContents) {
274
+ DynamoFM_Log.success(`---> '${callParams.name}' api call was successful`, res.data);
275
+
276
+ } else {
277
+ DynamoFM_Log.success(`---> '${callParams.name}' api call was successful`);
278
+ }
279
+ }
280
+
281
+ if (callParams.getFullResponse) {
282
+ return res as T_Response;
283
+ } else {
284
+ return res.data;
285
+ }
286
+ });
287
+ }
288
+
289
+ private static async delete<T_Response>(
290
+ axios: Axios.AxiosInstance,
291
+ url: string,
292
+ callParams: DynamoNTS_ApiCall_Params
293
+ ): Promise<T_Response> {
294
+ return await axios.delete<T_Response>(url, callParams.httpOptions).then(
295
+ (res: Axios.AxiosResponse): T_Response => {
296
+ if (DynamoNTS_globalSettings.logApiEvents) {
297
+ if (DynamoNTS_globalSettings.logApiResponseContents) {
298
+ DynamoFM_Log.success(`'${callParams.name}' was successful`, res.data);
299
+ } else {
300
+ DynamoFM_Log.success(`'${callParams.name}' was successful`);
301
+ }
302
+ }
303
+
304
+ if (callParams.getFullResponse) {
305
+ return res as T_Response;
306
+ }
307
+ }
308
+ );
309
+ }
310
+
311
+ private static async get<T_Response>(
312
+ axios: Axios.AxiosInstance,
313
+ url: string,
314
+ callParams: DynamoNTS_ApiCall_Params
315
+ ): Promise<T_Response> {
316
+ return await axios.get<T_Response>(url, callParams.httpOptions).then(
317
+ (res: Axios.AxiosResponse): T_Response => {
318
+ if (DynamoNTS_globalSettings.logApiEvents) {
319
+ if (DynamoNTS_globalSettings.logApiResponseContents) {
320
+ DynamoFM_Log.success(`'${callParams.name}' was successful`, res.data);
321
+ } else {
322
+ DynamoFM_Log.success(`'${callParams.name}' was successful`);
323
+ }
324
+ }
325
+
326
+ if (callParams.getFullResponse) {
327
+ return res as T_Response;
328
+ } else {
329
+ return res.data;
330
+ }
331
+ }
332
+ );
333
+ }
334
+
335
+ private static logEvent<T_Body>(
336
+ url: string,
337
+ inputParams: DynamoNTS_ApiCallInput_Params<T_Body>,
338
+ callParams: DynamoNTS_ApiCall_Params
339
+ ): void {
340
+ if (DynamoNTS_globalSettings.logApiRequestContents) {
341
+ DynamoFM_Log.log(
342
+ `<--- outgoing API call: '${callParams?.name}' ` +
343
+ `\n(${url})` +
344
+ `\nbody:`, inputParams?.body
345
+ );
346
+
347
+ } else {
348
+ DynamoFM_Log.log(`<--- outgoing API call: '${callParams?.name}'`);
349
+ }
350
+
351
+ if (DynamoNTS_globalSettings.logApiRequestSettings) {
352
+ DynamoFM_Log.log(`callParams:`, callParams);
353
+ DynamoFM_Log.log('inputParams:', {
354
+ pathParams: inputParams.pathParams ?? {},
355
+ body: inputParams.body ?? null,
356
+ });
357
+ }
358
+ }
359
+
360
+ private static setupHeaders(
361
+ callParams: DynamoNTS_ApiCall_Params,
362
+ axios: Axios.AxiosInstance
363
+ ): void {
364
+ for (const headerKey in callParams.httpOptions.headers) {
365
+ if (callParams.httpOptions.headers[headerKey]) {
366
+ axios.defaults.headers.common[headerKey] = callParams.httpOptions.headers[headerKey];
367
+
368
+ } else {
369
+ throw new DynamoFM_Error({
370
+ ...this._getDefaultErrorSettings(
371
+ 'setupHeaders',
372
+ new Error(`missing header: ${headerKey}`)
373
+ ),
374
+ errorCode: 'NTS-API-SH0',
375
+ });
376
+ }
377
+ }
378
+ }
379
+
380
+ private static setupPathParams(
381
+ pathParams: { [param: string]: string; },
382
+ url: string
383
+ ): string {
384
+ for (const pathParamKey in pathParams) {
385
+ if (pathParams[pathParamKey]) {
386
+ const paramType = typeof pathParams[pathParamKey];
387
+
388
+ switch (paramType) {
389
+ case 'number':
390
+ url = url.replace(
391
+ `:${pathParamKey}`,
392
+ pathParams[pathParamKey].toString()
393
+ );
394
+ break;
395
+
396
+ case 'string':
397
+ url = url.replace(`:${pathParamKey}`, pathParams[pathParamKey]);
398
+ break;
399
+
400
+ default:
401
+ /* DynamoFM_Log.error(
402
+ `DYNAMO-NTS ERROR:`+
403
+ `\nwrong path param type: (${pathParamKey}): ${paramType} ` +
404
+ `\n${pathParams[pathParamKey]}` +
405
+ `\nMUST BE string or number` +
406
+ `\n\n`,
407
+ new Error()
408
+ ); */
409
+ throw new DynamoFM_Error({
410
+ ...this._getDefaultErrorSettings(
411
+ 'setupPathParams',
412
+ new Error(
413
+ `wrong path param type: (${pathParamKey}): ${paramType}` +
414
+ `\n${pathParams[pathParamKey]}`
415
+ )
416
+ ),
417
+ errorCode: 'NTS-API-SP1',
418
+ additionalContent: {
419
+ pathParams: pathParams,
420
+ url: url,
421
+ },
422
+ });
423
+ break;
424
+ }
425
+ } else {
426
+ throw new DynamoFM_Error({
427
+ ...this._getDefaultErrorSettings(
428
+ 'setupPathParams',
429
+ new Error(`missing pathParam: ${pathParamKey}`)
430
+ ),
431
+ errorCode: 'NTS-API-SP0',
432
+ });
433
+ }
434
+ }
435
+
436
+ return url;
437
+ }
438
+
439
+ private static _getDefaultErrorSettings(
440
+ fnName: string,
441
+ error: DynamoFM_AnyError
442
+ ): DynamoFM_Error_Settings {
443
+ return {
444
+ status: (error as DynamoFM_Error)?.___status ?? 500,
445
+ message: (error as Error)?.message ?? `${fnName} was UNSUCCESFUL (NTS)`,
446
+ addECToUserMsg: !(error as DynamoFM_Error)?.__userMessage,
447
+ userMessage: (error as DynamoFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
448
+ issuerService: `${this?.constructor?.name}-${this?.name}-DynamoNTS_ApiService`,
449
+ error: error,
450
+ };
451
+ }
452
+ }
453
+