@futdevpro/nts-dynamo 1.9.15 → 1.9.17

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 (132) hide show
  1. package/.copilot/patterns.json +7 -7
  2. package/.github/workflows/main.yml +221 -0
  3. package/HOWTO.md +15 -15
  4. package/README.md +140 -140
  5. package/build/_constants/mocks/auth-service.mock.d.ts.map +1 -1
  6. package/build/_models/control-models/app-params.control-model.d.ts +1 -0
  7. package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
  8. package/build/_models/control-models/app-params.control-model.js.map +1 -1
  9. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  10. package/build/_models/control-models/endpoint-params.control-model.js +2 -0
  11. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  12. package/build/_models/control-models/socket-event.control-model.js +1 -1
  13. package/build/_models/interfaces/certification-settings.interface.d.ts +0 -1
  14. package/build/_models/interfaces/certification-settings.interface.d.ts.map +1 -1
  15. package/build/_models/interfaces/global-service-settings.interface.d.ts +1 -1
  16. package/build/_models/interfaces/global-service-settings.interface.d.ts.map +1 -1
  17. package/build/_modules/custom-data/get-custom-data-routing-module.util.js +1 -2
  18. package/build/_modules/custom-data/get-custom-data-routing-module.util.js.map +1 -1
  19. package/build/_modules/test/get-test-routing-module.util.js +1 -2
  20. package/build/_modules/test/get-test-routing-module.util.js.map +1 -1
  21. package/build/_modules/usage/get-usage-routing-module.util.js +1 -2
  22. package/build/_modules/usage/get-usage-routing-module.util.js.map +1 -1
  23. package/build/_services/core/global.service.d.ts.map +1 -1
  24. package/build/_services/core/global.service.js +14 -6
  25. package/build/_services/core/global.service.js.map +1 -1
  26. package/build/_services/route/routing-module.service.d.ts +1 -1
  27. package/build/_services/route/routing-module.service.d.ts.map +1 -1
  28. package/build/_services/route/routing-module.service.js +19 -25
  29. package/build/_services/route/routing-module.service.js.map +1 -1
  30. package/build/_services/server/app.server.d.ts +0 -2
  31. package/build/_services/server/app.server.d.ts.map +1 -1
  32. package/build/_services/server/app.server.js +4 -1
  33. package/build/_services/server/app.server.js.map +1 -1
  34. package/build/_services/socket/socket-client.service.d.ts.map +1 -1
  35. package/build/_services/socket/socket-client.service.js +1 -0
  36. package/build/_services/socket/socket-client.service.js.map +1 -1
  37. package/nodemon.json +17 -15
  38. package/package.json +5 -5
  39. package/src/_constants/global-settings.const.ts +27 -27
  40. package/src/_constants/index.ts +2 -2
  41. package/src/_constants/mocks/app-extended-server.mock.ts +198 -198
  42. package/src/_constants/mocks/app-params.mock.ts +9 -9
  43. package/src/_constants/mocks/app-server.mock.ts +185 -185
  44. package/src/_constants/mocks/auth-service.mock.ts +28 -28
  45. package/src/_constants/mocks/controller.mock.ts +16 -16
  46. package/src/_constants/mocks/data-model.mock.ts +83 -83
  47. package/src/_constants/mocks/email-service-collection.mock.ts +13 -13
  48. package/src/_constants/mocks/email-service.mock.ts +19 -19
  49. package/src/_constants/mocks/email-template.mock.html +14 -14
  50. package/src/_constants/mocks/endpoint.mock.ts +90 -90
  51. package/src/_constants/mocks/socket-client.mock.ts +43 -43
  52. package/src/_constants/mocks/socket-server.mock.ts +43 -43
  53. package/src/_enums/data-model-type.enum.ts +14 -14
  54. package/src/_enums/data-service-function.enum.ts +15 -15
  55. package/src/_enums/http/http-call-type.enum.ts +12 -12
  56. package/src/_enums/http/http-response-type.enum.ts +7 -7
  57. package/src/_enums/http/socket-event-type.enum.ts +18 -18
  58. package/src/_enums/index.ts +13 -13
  59. package/src/_enums/predefined-data-types.enum.ts +27 -27
  60. package/src/_enums/route-security.enum.ts +12 -12
  61. package/src/_enums/socket-security.enum.ts +11 -11
  62. package/src/_models/control-models/api-call-params.control-model.ts +126 -126
  63. package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
  64. package/src/_models/control-models/app-params.control-model.ts +46 -45
  65. package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
  66. package/src/_models/control-models/endpoint-params.control-model.ts +309 -307
  67. package/src/_models/control-models/http-settings.control-model.ts +29 -29
  68. package/src/_models/control-models/index.ts +13 -13
  69. package/src/_models/control-models/socket-client-service-params.control-model.ts +28 -28
  70. package/src/_models/control-models/socket-event.control-model.ts +150 -150
  71. package/src/_models/control-models/socket-presence.control-model.ts +207 -207
  72. package/src/_models/control-models/socket-server-service-params.control-model.ts +20 -20
  73. package/src/_models/control-models/system-control.control-model.ts +12 -12
  74. package/src/_models/index.ts +9 -9
  75. package/src/_models/interfaces/certification-settings.interface.ts +7 -7
  76. package/src/_models/interfaces/global-service-settings.interface.ts +45 -45
  77. package/src/_models/interfaces/global-settings.interface.ts +83 -83
  78. package/src/_models/interfaces/index.ts +7 -7
  79. package/src/_models/interfaces/routing-module-settings.interface.ts +20 -20
  80. package/src/_models/types/db-filter.type.ts +108 -108
  81. package/src/_models/types/db-update.type.ts +100 -100
  82. package/src/_models/types/index.ts +5 -5
  83. package/src/_modules/api-service.index.ts +12 -12
  84. package/src/_modules/app-extended.index.ts +28 -28
  85. package/src/_modules/app.index.ts +24 -24
  86. package/src/_modules/auth.index.ts +7 -7
  87. package/src/_modules/constants.index.ts +2 -2
  88. package/src/_modules/controller.index.ts +10 -10
  89. package/src/_modules/custom-data/custom-data.controller.ts +69 -69
  90. package/src/_modules/custom-data/custom-data.data-service.ts +20 -20
  91. package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +23 -23
  92. package/src/_modules/custom-data/index.ts +6 -6
  93. package/src/_modules/custom-data-module.index.ts +2 -2
  94. package/src/_modules/data-service.index.ts +9 -9
  95. package/src/_modules/email.index.ts +8 -8
  96. package/src/_modules/enums.index.ts +2 -2
  97. package/src/_modules/extended.index.ts +8 -8
  98. package/src/_modules/models.index.ts +2 -2
  99. package/src/_modules/services.index.ts +2 -2
  100. package/src/_modules/test/get-test-routing-module.util.ts +23 -23
  101. package/src/_modules/test/index.ts +5 -5
  102. package/src/_modules/test/test.controller.ts +115 -115
  103. package/src/_modules/test-module.index.ts +2 -2
  104. package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
  105. package/src/_modules/usage/index.ts +7 -7
  106. package/src/_modules/usage/usage.controller.ts +120 -120
  107. package/src/_modules/usage/usage.data-service.ts +172 -172
  108. package/src/_modules/usage-module.index.ts +2 -2
  109. package/src/_services/base/data.service.ts +921 -921
  110. package/src/_services/base/db.service.spec.ts +32 -32
  111. package/src/_services/base/db.service.ts +1063 -1063
  112. package/src/_services/base/singleton.service.ts +21 -21
  113. package/src/_services/core/api.service.ts +453 -453
  114. package/src/_services/core/auth.service.ts +172 -172
  115. package/src/_services/core/email.service.ts +678 -678
  116. package/src/_services/core/global.service.ts +275 -269
  117. package/src/_services/core/service-collection.service.ts +5 -5
  118. package/src/_services/index.ts +23 -23
  119. package/src/_services/route/controller.service.ts +129 -129
  120. package/src/_services/route/routing-module.service.ts +293 -273
  121. package/src/_services/server/app-extended.server.spec.ts +76 -76
  122. package/src/_services/server/app-extended.server.ts +520 -520
  123. package/src/_services/server/app.server.spec.ts +67 -67
  124. package/src/_services/server/app.server.ts +1181 -1179
  125. package/src/_services/shared.service.spec.ts +19 -19
  126. package/src/_services/shared.static-service.ts +73 -73
  127. package/src/_services/socket/socket-client.service.ts +236 -235
  128. package/src/_services/socket/socket-server.service.spec.ts +11 -11
  129. package/src/_services/socket/socket-server.service.ts +761 -761
  130. package/src/index.ts +18 -18
  131. package/tsconfig.json +41 -41
  132. package/build/tsconfig.tsbuildinfo +0 -1
@@ -1,520 +1,520 @@
1
-
2
- import * as SocketIO from 'socket.io';
3
- import * as Http from 'http';
4
-
5
- import { DynamoFM_Array, DynamoFM_Error, DynamoFM_Log, second, DynamoFM_wait } from '@futdevpro/fsm-dynamo';
6
-
7
- import { DynamoNTS_App } from './app.server';
8
- import { DynamoNTS_RouteSecurity } from '../../_enums/route-security.enum';
9
- import { DynamoNTS_SocketServerService } from '../socket/socket-server.service';
10
- import { DynamoNTS_SocketSecurity } from '../../_enums/socket-security.enum';
11
- import {
12
- DynamoNTS_AppExtSysControls
13
- } from '../../_models/control-models/app-ext-system-controls.control-model';
14
-
15
- /**
16
- * This will be the MAIN service of our server project,
17
- * follow the types and type instructions while setting up your project
18
- *
19
- * In this service, there are abstract functions that you will need to implement,
20
- * where you need to set up the main params for your application.
21
- *
22
- * The extended App is containing socket server tools
23
- *
24
- * You need to add socketService definitions to setupRoutingModules
25
- *
26
- * @example
27
- * export class App extends DynamoNTS_AppExtended {
28
- *
29
- * ...
30
- *
31
- * // Setting up App params, and preparing project global settings
32
- * setupAppParams(): void {
33
- * this.params = new DynamoNTS_AppParams({
34
- * name: 'Warbots Server',
35
- * title: warbotsTitleLog,
36
- * version: version,
37
- * dbName: 'warbots',
38
- * });
39
- *
40
- * // dynamoNTS_GlobalSettings.logRequestsContent = false;
41
- * }
42
- *
43
- * ...
44
- *
45
- * // Setting up DBServices
46
- * setGlobalServiceCollection(): void {
47
- * DynamoNTS_GlobalService.setServices({
48
- * authService: AuthService.getInstance(),
49
- * emailServiceCollection: EmailServiceCollectionService.getInstance(),
50
- * dbModels: [
51
- * userModelParams,
52
- * userDataModelParams,
53
- * userOptionsModelParams,
54
- * userStatisticsModelParams,
55
- * userAchievementsModelParams,
56
- * userNotificationsModelParams,
57
- *
58
- * matchStatisticsModelParams,
59
- * matchDataModelParams,
60
-
61
- * DynamoFM_usageSessionModel_params,
62
- * DynamoFM_customDataModel_params,
63
- * ]
64
- * });
65
- * }
66
- *
67
- * ...
68
- *
69
- * // Setting up Routes
70
- * setupRoutingModules(): void {
71
- * this.httpPort = env.port;
72
-
73
- * this.routingModules = [
74
- * new DynamoNTS_RoutingModule({
75
- * route: '/user',
76
- * controllers: [
77
- * UserController.getInstance(),
78
- * UserDataController.getInstance(),
79
- * UserOptionsController.getInstance(),
80
- * UserStatisticsController.getInstance(),
81
- * UserAchievementsController.getInstance(),
82
- * UserNotificationsController.getInstance()
83
- * ]
84
- * }),
85
- * new DynamoNTS_RoutingModule({
86
- * route: '/match',
87
- * controllers: [
88
- * MatchController.getInstance(),
89
- * MatchDistributionController.getInstance(),
90
- * MatchStatisticsController.getInstance(),
91
- * ]
92
- * }),
93
- * new DynamoNTS_RoutingModule({
94
- * route: '/server',
95
- * controllers: [
96
- * ServerController.getInstance(),
97
- * ]
98
- * }),
99
-
100
- * getTestRoutingModule(),
101
- * getUsageRoutingModule()
102
- * ];
103
- *
104
- * ...
105
- *
106
- * // Setting up Sockets
107
- * this.socketServices = [
108
- * NotificationService.getInstance(),
109
- * ChatService.getInstance(),
110
- * ...
111
- * ];
112
- * }
113
- * }
114
- */
115
- export abstract class DynamoNTS_AppExtended extends DynamoNTS_App {
116
-
117
- private systemControlsExt: DynamoNTS_AppExtSysControls = new DynamoNTS_AppExtSysControls();
118
- override get started(): boolean { return this.systemControlsExt.appExtended.started; }
119
- private httpsSocketSettingUpCount: number = 0;
120
- private httpSocketSettingUpCount: number = 0;
121
-
122
- private socketSecurity: DynamoNTS_RouteSecurity;
123
-
124
- private httpSocketServer: Http.Server;
125
-
126
- /**
127
- * @example
128
- * // Setting up Sockets
129
- * this.socketServices = [
130
- * NotificationService.getInstance(),
131
- * ChatService.getInstance(),
132
- * ...
133
- * ];
134
- */
135
- protected socketServices: DynamoNTS_SocketServerService<any>[];
136
- private allSocketServers: SocketIO.Server[] = [];
137
-
138
- constructor(){
139
- super(true);
140
-
141
- this.asyncConstructExt().catch((error: any): void => {
142
- DynamoFM_Log.H_error(
143
- `\nExtended Application: ${this.params?.name} start failed.` +
144
- `\n`, error,
145
- '\n'
146
- );
147
- });
148
- }
149
-
150
- private async asyncConstructExt(): Promise<void> {
151
- if (this.logFn && this.deepLog) console.log('\nfn:. asyncConstruct-extended');
152
- try {
153
- this.systemControlsExt.appExtended.init = true;
154
-
155
- this.socketServices = this.getSocketServices();
156
-
157
- if (this.socketServices?.length) {
158
- this.setSocketSecurity();
159
-
160
- await this.setupSocketServerServices();
161
-
162
- if (this.logSetup) console.log(
163
- `\nAll sockets setted up.... sockets using security: ${this.socketSecurity}`
164
- );
165
- } else {
166
- DynamoFM_Log.testWarn(
167
- 'No socketServices setted up while using Extended Application.',
168
- '\nYou should use DynamoNTS_App if you don`t need socket services.'
169
- );
170
- }
171
-
172
- await this.ready();
173
-
174
- if (this.params.title) {
175
- console.log(this.params.title);
176
- console.log(`Version: ${this.params.version}`);
177
- }
178
- DynamoFM_Log.H_success(`${this.params.name} started successfully.`);
179
-
180
- } catch (error) {
181
- DynamoFM_Log.H_error(
182
- `\nExtended Application: ${this.params?.name} start failed.` +
183
- `\n`, error,
184
- '\n'
185
- );
186
-
187
- throw new DynamoFM_Error({
188
- errorCode: 'NTS-AES-001',
189
- error: error,
190
- additionalContent: {
191
- constructErrors: this.constructErrors,
192
- systemControls: this.systemControls,
193
- systemControlsExt: this.systemControlsExt,
194
- systemReadies: {
195
- app: this.systemControls.app.getReady(),
196
- appExtended: this.systemControlsExt.appExtended.getReady(),
197
- mongoose: this.systemControls.mongoose.getReady(),
198
- httpServer: this.systemControls.httpServer.getReady(),
199
- httpsServer: this.systemControls.httpsServer.getReady(),
200
- httpSocketServer: this.systemControlsExt.httpSocketServer.getReady(),
201
- httpsSocketServer: this.systemControlsExt.httpsSocketServer.getReady(),
202
- },
203
- },
204
- });
205
- }
206
- }
207
-
208
- override async ready(timeout: number = 4 * second): Promise<void> {
209
- if (this.logFn) console.log('\nfn:. ready-extended');
210
- await super.ready(timeout);
211
-
212
- let ready: boolean = false;
213
- const start: number = +new Date();
214
-
215
- if (this.constructErrors.length) {
216
- DynamoFM_Log.H_error(
217
- `Extended Application: ${this.params?.name} start failed. ERRORS`,
218
- this.constructErrors,
219
- '\n'
220
- );
221
-
222
- throw new DynamoFM_Error({
223
- message: `${this.params?.name} start failed. ERRORS`,
224
- additionalContent: this.constructErrors,
225
- error: this.constructErrors?.[0] ?? new Error()
226
- });
227
- }
228
-
229
- while (!ready && +new Date() - start < timeout) {
230
- if (this.systemControlsExt.appExtended.init) {
231
- ready = (
232
- this.superStarted &&
233
- this.systemControlsExt.httpSocketServer.getReady() &&
234
- this.systemControlsExt.httpsSocketServer.getReady()
235
- );
236
- } else {
237
- DynamoFM_Log.error(`${this.params.name} APP NOT INITIALIZED while trying to get ready.`);
238
- }
239
-
240
- if (!ready) {
241
- await DynamoFM_wait(100);
242
- }
243
- }
244
-
245
- if (this.constructErrors.length) {
246
- DynamoFM_Log.H_error(
247
- `Extended Application: ${this.params?.name} start failed. TIMEOUT`,
248
- this.constructErrors,
249
- '\n'
250
- );
251
-
252
- throw new DynamoFM_Error({
253
- message: `${this.params?.name} start failed. TIMEOUT`,
254
- additionalContent: this.constructErrors,
255
- error: this.constructErrors?.[0] ?? new Error()
256
- });
257
- }
258
-
259
- if (ready) {
260
- this.systemControlsExt.appExtended.started = true;
261
-
262
- if (this.logFn && this.deepLog) console.log('\nfn:. ready-extended: return');
263
-
264
- return;
265
- } else {
266
- this.systemControlsExt.appExtended.started = false;
267
-
268
- let msg: string = `${this.params?.name} start failed. UNKNOWN`;
269
-
270
- if (
271
- this.systemControlsExt.httpSocketServer.init &&
272
- !this.systemControlsExt.httpSocketServer.started
273
- ) {
274
- msg += '\nhttpSocketServer start failed.';
275
- }
276
-
277
- if (
278
- this.systemControlsExt.httpsSocketServer.init &&
279
- !this.systemControlsExt.httpsSocketServer.started
280
- ) {
281
- msg += '\nhttpsSocketServer start failed.';
282
- }
283
-
284
- DynamoFM_Log.error(msg, this.constructErrors, '\n');
285
-
286
- throw new DynamoFM_Error({
287
- errorCode: 'NTS-AES-110',
288
- message: msg,
289
- additionalContent: {
290
- constructErrors: this.constructErrors,
291
- systemControls: this.systemControls,
292
- systemControlsExt: this.systemControlsExt,
293
- systemReadies: {
294
- app: this.systemControls.app.getReady(),
295
- appExtended: this.systemControlsExt.appExtended.getReady(),
296
- mongoose: this.systemControls.mongoose.getReady(),
297
- httpServer: this.systemControls.httpServer.getReady(),
298
- httpsServer: this.systemControls.httpsServer.getReady(),
299
- httpSocketServer: this.systemControlsExt.httpSocketServer.getReady(),
300
- httpsSocketServer: this.systemControlsExt.httpsSocketServer.getReady(),
301
- },
302
- },
303
- error: this.constructErrors?.[0] ?? new Error()
304
- });
305
- }
306
- }
307
-
308
- override async stop(): Promise<void> {
309
- if (this.logFn) console.log('\nfn:. stop-extended');
310
-
311
- if (this.started) {
312
- await super.stop(true);
313
-
314
- this.systemControlsExt.httpSocketServer.started = false;
315
- this.systemControlsExt.httpsSocketServer.started = false;
316
- await DynamoFM_Array.asyncForEach(
317
- this.allSocketServers,
318
- async (socketServer: SocketIO.Server): Promise<void> => {
319
- await new Promise<void>((resolve, reject): void => {
320
- socketServer.disconnectSockets(true);
321
- socketServer.close((err): void => {
322
- if (err) {
323
- DynamoFM_Log.error(`\nHTTP socket server close error`, err);
324
- reject(
325
- new DynamoFM_Error({
326
- errorCode: 'NTS-AES-120',
327
- message: `SocketServer close failed.`,
328
- error: err
329
- })
330
- );
331
- } else {
332
- resolve();
333
- }
334
- });
335
- });
336
- }
337
- );
338
- this.systemControlsExt.httpSocketServer.init = false;
339
- this.systemControlsExt.httpsSocketServer.init = false;
340
-
341
- DynamoFM_Log.H_info(`${this.params.name} stopped successfully.`);
342
- }
343
- }
344
-
345
- /**
346
- *
347
- */
348
- private setSocketSecurity(): void {
349
- if (this.logFn) console.log('\nfn:. setSocketSecurity');
350
- this.socketServices.forEach((service: DynamoNTS_SocketServerService<any>): void => {
351
- if (!this.socketSecurity) {
352
- this.socketSecurity = DynamoNTS_RouteSecurity[service.security];
353
- } else if (
354
- this.socketSecurity !== DynamoNTS_RouteSecurity.both &&
355
- this.socketSecurity !== DynamoNTS_RouteSecurity[service.security]
356
- ) {
357
- this.socketSecurity = DynamoNTS_RouteSecurity.both;
358
- }
359
- });
360
- }
361
-
362
- /**
363
- *
364
- */
365
- private async setupSocketServerServices(): Promise<void> {
366
- try {
367
- if (this.logFn) console.log('\nfn:. setupSocketServerServices');
368
- /* let httpServer: Http.Server; */
369
-
370
- if (this.socketSecurity !== DynamoNTS_RouteSecurity.secure) {
371
- if (!this.openExpress) {
372
- await this.initOpenExpress();
373
- }
374
-
375
- if (!this.httpSocketServer) {
376
- this.httpSocketServer = Http.createServer(this.openExpress);
377
- }
378
- }
379
-
380
- if (this.socketSecurity !== DynamoNTS_RouteSecurity.open) {
381
- if (!this.httpsServer) {
382
- if (this.cert) {
383
- await this.initSecureExpress();
384
- } else {
385
- let errorMsg: string =
386
- `\nYou have secure socket service, but the certification paths are not set!` +
387
- `\nset...` +
388
- `\n cert: {` +
389
- `\n keyPath: FileSystem.PathLike,` +
390
- `\n certPath: FileSystem.PathLike,` +
391
- `\n }` +
392
- `\nin DynamoBEServer - setupRoutingModules() to enable secure routes.`;
393
-
394
- errorMsg += '\n\nThe socket services setted to use secure server:';
395
- this.socketServices.forEach((service: DynamoNTS_SocketServerService<any>): void => {
396
- if (service.security != DynamoNTS_SocketSecurity.open) {
397
- errorMsg += `\n ${service?.name} (port: ${service.port})`;
398
- }
399
- });
400
-
401
- const error = new Error('Secure routes cannot be established!');
402
- const errorStack: string[] = error.stack.split('\n');
403
-
404
- errorStack.splice(1, 2);
405
- error.stack = errorStack.join('\n');
406
-
407
- DynamoFM_Log.error(errorMsg);
408
-
409
- throw error;
410
- }
411
- }
412
- }
413
-
414
- await DynamoFM_Array.asyncForEach(
415
- this.socketServices,
416
- async (service: DynamoNTS_SocketServerService<any>): Promise<void> => {
417
- try {
418
- this.systemControlsExt.httpSocketServer.init = true;
419
- const existingPorts: DynamoNTS_SocketServerService<any>[] = this.socketServices.filter(
420
- (mod: DynamoNTS_SocketServerService<any>): boolean => mod.port === service.port
421
- );
422
-
423
- if (
424
- 1 < existingPorts.length ||
425
- this.portSettings.httpPort === service.port ||
426
- this.portSettings.httpsPort === service.port
427
- ) {
428
- const error = new Error(`PORT DUPLICATION: ${service.port}`);
429
- const errorStack: string[] = error.stack.split('\n');
430
-
431
- errorStack.splice(1, 4);
432
- error.stack = errorStack.join('\n');
433
-
434
- DynamoFM_Log.error(`\n${error.message}`);
435
-
436
- throw error;
437
- }
438
-
439
- if (service.security === DynamoNTS_SocketSecurity.open) {
440
- if (this.logSetup) console.log(
441
- `\nsocket setup (open): ${service?.name}:${service.port}`
442
- );
443
- this.httpSocketSettingUpCount++;
444
- this.systemControlsExt.httpSocketServer.started = false;
445
-
446
- this.allSocketServers.push(
447
- await service.setupSocketServer(
448
- new SocketIO.Server(this.httpSocketServer),
449
- DynamoNTS_SocketSecurity.open,
450
- (): void => {
451
- this.httpSocketSettingUpCount--;
452
-
453
- if (this.httpSocketSettingUpCount === 0) {
454
- this.systemControlsExt.httpSocketServer.started = true;
455
- }
456
- }
457
- )
458
- );
459
-
460
- } else if (service.security === DynamoNTS_SocketSecurity.secure) {
461
- if (this.logSetup) console.log(
462
- `\nsocket setup (secure): ${service?.name}:${service.port}`
463
- );
464
- this.httpsSocketSettingUpCount++;
465
- this.systemControlsExt.httpsSocketServer.started = false;
466
-
467
- this.allSocketServers.push(
468
- await service.setupSocketServer(
469
- new SocketIO.Server(this.httpsServer),
470
- DynamoNTS_SocketSecurity.secure,
471
- (): void => {
472
- this.httpsSocketSettingUpCount--;
473
-
474
- if (this.httpsSocketSettingUpCount === 0) {
475
- this.systemControlsExt.httpsSocketServer.started = true;
476
- }
477
- }
478
- )
479
- );
480
-
481
- } else {
482
- const error = new Error(
483
- `INVALID Socket Service security: ${service.security} on ${service?.name}`
484
- );
485
- const errorStack: string[] = error.stack.split('\n');
486
-
487
- errorStack.splice(1, 4);
488
- error.stack = errorStack.join('\n');
489
-
490
- DynamoFM_Log.error(`\n${error.message}`);
491
-
492
- throw error;
493
- }
494
- } catch (error) {
495
- DynamoFM_Log.error(
496
- `\nSocket Server service setup failed. (${service?.name})\n`,
497
- error,
498
- '\n'
499
- );
500
-
501
- throw error;
502
- }
503
- }
504
- );
505
- } catch (error) {
506
- DynamoFM_Log.error(
507
- `\nSocket Server services setup failed. (${this.socketServices?.length} services)\n`,
508
- error,
509
- '\n'
510
- );
511
-
512
- throw error;
513
- }
514
- }
515
-
516
- /**
517
- * MISSING Description (TODO)
518
- */
519
- abstract getSocketServices(): DynamoNTS_SocketServerService<any>[];
520
- }
1
+
2
+ import * as SocketIO from 'socket.io';
3
+ import * as Http from 'http';
4
+
5
+ import { DynamoFM_Array, DynamoFM_Error, DynamoFM_Log, second, DynamoFM_wait } from '@futdevpro/fsm-dynamo';
6
+
7
+ import { DynamoNTS_App } from './app.server';
8
+ import { DynamoNTS_RouteSecurity } from '../../_enums/route-security.enum';
9
+ import { DynamoNTS_SocketServerService } from '../socket/socket-server.service';
10
+ import { DynamoNTS_SocketSecurity } from '../../_enums/socket-security.enum';
11
+ import {
12
+ DynamoNTS_AppExtSysControls
13
+ } from '../../_models/control-models/app-ext-system-controls.control-model';
14
+
15
+ /**
16
+ * This will be the MAIN service of our server project,
17
+ * follow the types and type instructions while setting up your project
18
+ *
19
+ * In this service, there are abstract functions that you will need to implement,
20
+ * where you need to set up the main params for your application.
21
+ *
22
+ * The extended App is containing socket server tools
23
+ *
24
+ * You need to add socketService definitions to setupRoutingModules
25
+ *
26
+ * @example
27
+ * export class App extends DynamoNTS_AppExtended {
28
+ *
29
+ * ...
30
+ *
31
+ * // Setting up App params, and preparing project global settings
32
+ * setupAppParams(): void {
33
+ * this.params = new DynamoNTS_AppParams({
34
+ * name: 'Warbots Server',
35
+ * title: warbotsTitleLog,
36
+ * version: version,
37
+ * dbName: 'warbots',
38
+ * });
39
+ *
40
+ * // dynamoNTS_GlobalSettings.logRequestsContent = false;
41
+ * }
42
+ *
43
+ * ...
44
+ *
45
+ * // Setting up DBServices
46
+ * setGlobalServiceCollection(): void {
47
+ * DynamoNTS_GlobalService.setServices({
48
+ * authService: AuthService.getInstance(),
49
+ * emailServiceCollection: EmailServiceCollectionService.getInstance(),
50
+ * dbModels: [
51
+ * userModelParams,
52
+ * userDataModelParams,
53
+ * userOptionsModelParams,
54
+ * userStatisticsModelParams,
55
+ * userAchievementsModelParams,
56
+ * userNotificationsModelParams,
57
+ *
58
+ * matchStatisticsModelParams,
59
+ * matchDataModelParams,
60
+
61
+ * DynamoFM_usageSessionModel_params,
62
+ * DynamoFM_customDataModel_params,
63
+ * ]
64
+ * });
65
+ * }
66
+ *
67
+ * ...
68
+ *
69
+ * // Setting up Routes
70
+ * setupRoutingModules(): void {
71
+ * this.httpPort = env.port;
72
+
73
+ * this.routingModules = [
74
+ * new DynamoNTS_RoutingModule({
75
+ * route: '/user',
76
+ * controllers: [
77
+ * UserController.getInstance(),
78
+ * UserDataController.getInstance(),
79
+ * UserOptionsController.getInstance(),
80
+ * UserStatisticsController.getInstance(),
81
+ * UserAchievementsController.getInstance(),
82
+ * UserNotificationsController.getInstance()
83
+ * ]
84
+ * }),
85
+ * new DynamoNTS_RoutingModule({
86
+ * route: '/match',
87
+ * controllers: [
88
+ * MatchController.getInstance(),
89
+ * MatchDistributionController.getInstance(),
90
+ * MatchStatisticsController.getInstance(),
91
+ * ]
92
+ * }),
93
+ * new DynamoNTS_RoutingModule({
94
+ * route: '/server',
95
+ * controllers: [
96
+ * ServerController.getInstance(),
97
+ * ]
98
+ * }),
99
+
100
+ * getTestRoutingModule(),
101
+ * getUsageRoutingModule()
102
+ * ];
103
+ *
104
+ * ...
105
+ *
106
+ * // Setting up Sockets
107
+ * this.socketServices = [
108
+ * NotificationService.getInstance(),
109
+ * ChatService.getInstance(),
110
+ * ...
111
+ * ];
112
+ * }
113
+ * }
114
+ */
115
+ export abstract class DynamoNTS_AppExtended extends DynamoNTS_App {
116
+
117
+ private systemControlsExt: DynamoNTS_AppExtSysControls = new DynamoNTS_AppExtSysControls();
118
+ override get started(): boolean { return this.systemControlsExt.appExtended.started; }
119
+ private httpsSocketSettingUpCount: number = 0;
120
+ private httpSocketSettingUpCount: number = 0;
121
+
122
+ private socketSecurity: DynamoNTS_RouteSecurity;
123
+
124
+ private httpSocketServer: Http.Server;
125
+
126
+ /**
127
+ * @example
128
+ * // Setting up Sockets
129
+ * this.socketServices = [
130
+ * NotificationService.getInstance(),
131
+ * ChatService.getInstance(),
132
+ * ...
133
+ * ];
134
+ */
135
+ protected socketServices: DynamoNTS_SocketServerService<any>[];
136
+ private allSocketServers: SocketIO.Server[] = [];
137
+
138
+ constructor(){
139
+ super(true);
140
+
141
+ this.asyncConstructExt().catch((error: any): void => {
142
+ DynamoFM_Log.H_error(
143
+ `\nExtended Application: ${this.params?.name} start failed.` +
144
+ `\n`, error,
145
+ '\n'
146
+ );
147
+ });
148
+ }
149
+
150
+ private async asyncConstructExt(): Promise<void> {
151
+ if (this.logFn && this.deepLog) console.log('\nfn:. asyncConstruct-extended');
152
+ try {
153
+ this.systemControlsExt.appExtended.init = true;
154
+
155
+ this.socketServices = this.getSocketServices();
156
+
157
+ if (this.socketServices?.length) {
158
+ this.setSocketSecurity();
159
+
160
+ await this.setupSocketServerServices();
161
+
162
+ if (this.logSetup) console.log(
163
+ `\nAll sockets setted up.... sockets using security: ${this.socketSecurity}`
164
+ );
165
+ } else {
166
+ DynamoFM_Log.testWarn(
167
+ 'No socketServices setted up while using Extended Application.',
168
+ '\nYou should use DynamoNTS_App if you don`t need socket services.'
169
+ );
170
+ }
171
+
172
+ await this.ready();
173
+
174
+ if (this.params.title) {
175
+ console.log(this.params.title);
176
+ console.log(`Version: ${this.params.version}`);
177
+ }
178
+ DynamoFM_Log.H_success(`${this.params.name} started successfully.`);
179
+
180
+ } catch (error) {
181
+ DynamoFM_Log.H_error(
182
+ `\nExtended Application: ${this.params?.name} start failed.` +
183
+ `\n`, error,
184
+ '\n'
185
+ );
186
+
187
+ throw new DynamoFM_Error({
188
+ errorCode: 'NTS-AES-001',
189
+ error: error,
190
+ additionalContent: {
191
+ constructErrors: this.constructErrors,
192
+ systemControls: this.systemControls,
193
+ systemControlsExt: this.systemControlsExt,
194
+ systemReadies: {
195
+ app: this.systemControls.app.getReady(),
196
+ appExtended: this.systemControlsExt.appExtended.getReady(),
197
+ mongoose: this.systemControls.mongoose.getReady(),
198
+ httpServer: this.systemControls.httpServer.getReady(),
199
+ httpsServer: this.systemControls.httpsServer.getReady(),
200
+ httpSocketServer: this.systemControlsExt.httpSocketServer.getReady(),
201
+ httpsSocketServer: this.systemControlsExt.httpsSocketServer.getReady(),
202
+ },
203
+ },
204
+ });
205
+ }
206
+ }
207
+
208
+ override async ready(timeout: number = 4 * second): Promise<void> {
209
+ if (this.logFn) console.log('\nfn:. ready-extended');
210
+ await super.ready(timeout);
211
+
212
+ let ready: boolean = false;
213
+ const start: number = +new Date();
214
+
215
+ if (this.constructErrors.length) {
216
+ DynamoFM_Log.H_error(
217
+ `Extended Application: ${this.params?.name} start failed. ERRORS`,
218
+ this.constructErrors,
219
+ '\n'
220
+ );
221
+
222
+ throw new DynamoFM_Error({
223
+ message: `${this.params?.name} start failed. ERRORS`,
224
+ additionalContent: this.constructErrors,
225
+ error: this.constructErrors?.[0] ?? new Error()
226
+ });
227
+ }
228
+
229
+ while (!ready && +new Date() - start < timeout) {
230
+ if (this.systemControlsExt.appExtended.init) {
231
+ ready = (
232
+ this.superStarted &&
233
+ this.systemControlsExt.httpSocketServer.getReady() &&
234
+ this.systemControlsExt.httpsSocketServer.getReady()
235
+ );
236
+ } else {
237
+ DynamoFM_Log.error(`${this.params.name} APP NOT INITIALIZED while trying to get ready.`);
238
+ }
239
+
240
+ if (!ready) {
241
+ await DynamoFM_wait(100);
242
+ }
243
+ }
244
+
245
+ if (this.constructErrors.length) {
246
+ DynamoFM_Log.H_error(
247
+ `Extended Application: ${this.params?.name} start failed. TIMEOUT`,
248
+ this.constructErrors,
249
+ '\n'
250
+ );
251
+
252
+ throw new DynamoFM_Error({
253
+ message: `${this.params?.name} start failed. TIMEOUT`,
254
+ additionalContent: this.constructErrors,
255
+ error: this.constructErrors?.[0] ?? new Error()
256
+ });
257
+ }
258
+
259
+ if (ready) {
260
+ this.systemControlsExt.appExtended.started = true;
261
+
262
+ if (this.logFn && this.deepLog) console.log('\nfn:. ready-extended: return');
263
+
264
+ return;
265
+ } else {
266
+ this.systemControlsExt.appExtended.started = false;
267
+
268
+ let msg: string = `${this.params?.name} start failed. UNKNOWN`;
269
+
270
+ if (
271
+ this.systemControlsExt.httpSocketServer.init &&
272
+ !this.systemControlsExt.httpSocketServer.started
273
+ ) {
274
+ msg += '\nhttpSocketServer start failed.';
275
+ }
276
+
277
+ if (
278
+ this.systemControlsExt.httpsSocketServer.init &&
279
+ !this.systemControlsExt.httpsSocketServer.started
280
+ ) {
281
+ msg += '\nhttpsSocketServer start failed.';
282
+ }
283
+
284
+ DynamoFM_Log.error(msg, this.constructErrors, '\n');
285
+
286
+ throw new DynamoFM_Error({
287
+ errorCode: 'NTS-AES-110',
288
+ message: msg,
289
+ additionalContent: {
290
+ constructErrors: this.constructErrors,
291
+ systemControls: this.systemControls,
292
+ systemControlsExt: this.systemControlsExt,
293
+ systemReadies: {
294
+ app: this.systemControls.app.getReady(),
295
+ appExtended: this.systemControlsExt.appExtended.getReady(),
296
+ mongoose: this.systemControls.mongoose.getReady(),
297
+ httpServer: this.systemControls.httpServer.getReady(),
298
+ httpsServer: this.systemControls.httpsServer.getReady(),
299
+ httpSocketServer: this.systemControlsExt.httpSocketServer.getReady(),
300
+ httpsSocketServer: this.systemControlsExt.httpsSocketServer.getReady(),
301
+ },
302
+ },
303
+ error: this.constructErrors?.[0] ?? new Error()
304
+ });
305
+ }
306
+ }
307
+
308
+ override async stop(): Promise<void> {
309
+ if (this.logFn) console.log('\nfn:. stop-extended');
310
+
311
+ if (this.started) {
312
+ await super.stop(true);
313
+
314
+ this.systemControlsExt.httpSocketServer.started = false;
315
+ this.systemControlsExt.httpsSocketServer.started = false;
316
+ await DynamoFM_Array.asyncForEach(
317
+ this.allSocketServers,
318
+ async (socketServer: SocketIO.Server): Promise<void> => {
319
+ await new Promise<void>((resolve, reject): void => {
320
+ socketServer.disconnectSockets(true);
321
+ socketServer.close((err): void => {
322
+ if (err) {
323
+ DynamoFM_Log.error(`\nHTTP socket server close error`, err);
324
+ reject(
325
+ new DynamoFM_Error({
326
+ errorCode: 'NTS-AES-120',
327
+ message: `SocketServer close failed.`,
328
+ error: err
329
+ })
330
+ );
331
+ } else {
332
+ resolve();
333
+ }
334
+ });
335
+ });
336
+ }
337
+ );
338
+ this.systemControlsExt.httpSocketServer.init = false;
339
+ this.systemControlsExt.httpsSocketServer.init = false;
340
+
341
+ DynamoFM_Log.H_info(`${this.params.name} stopped successfully.`);
342
+ }
343
+ }
344
+
345
+ /**
346
+ *
347
+ */
348
+ private setSocketSecurity(): void {
349
+ if (this.logFn) console.log('\nfn:. setSocketSecurity');
350
+ this.socketServices.forEach((service: DynamoNTS_SocketServerService<any>): void => {
351
+ if (!this.socketSecurity) {
352
+ this.socketSecurity = DynamoNTS_RouteSecurity[service.security];
353
+ } else if (
354
+ this.socketSecurity !== DynamoNTS_RouteSecurity.both &&
355
+ this.socketSecurity !== DynamoNTS_RouteSecurity[service.security]
356
+ ) {
357
+ this.socketSecurity = DynamoNTS_RouteSecurity.both;
358
+ }
359
+ });
360
+ }
361
+
362
+ /**
363
+ *
364
+ */
365
+ private async setupSocketServerServices(): Promise<void> {
366
+ try {
367
+ if (this.logFn) console.log('\nfn:. setupSocketServerServices');
368
+ /* let httpServer: Http.Server; */
369
+
370
+ if (this.socketSecurity !== DynamoNTS_RouteSecurity.secure) {
371
+ if (!this.openExpress) {
372
+ await this.initOpenExpress();
373
+ }
374
+
375
+ if (!this.httpSocketServer) {
376
+ this.httpSocketServer = Http.createServer(this.openExpress);
377
+ }
378
+ }
379
+
380
+ if (this.socketSecurity !== DynamoNTS_RouteSecurity.open) {
381
+ if (!this.httpsServer) {
382
+ if (this.cert) {
383
+ await this.initSecureExpress();
384
+ } else {
385
+ let errorMsg: string =
386
+ `\nYou have secure socket service, but the certification paths are not set!` +
387
+ `\nset...` +
388
+ `\n cert: {` +
389
+ `\n keyPath: FileSystem.PathLike,` +
390
+ `\n certPath: FileSystem.PathLike,` +
391
+ `\n }` +
392
+ `\nin DynamoBEServer - setupRoutingModules() to enable secure routes.`;
393
+
394
+ errorMsg += '\n\nThe socket services setted to use secure server:';
395
+ this.socketServices.forEach((service: DynamoNTS_SocketServerService<any>): void => {
396
+ if (service.security != DynamoNTS_SocketSecurity.open) {
397
+ errorMsg += `\n ${service?.name} (port: ${service.port})`;
398
+ }
399
+ });
400
+
401
+ const error = new Error('Secure routes cannot be established!');
402
+ const errorStack: string[] = error.stack.split('\n');
403
+
404
+ errorStack.splice(1, 2);
405
+ error.stack = errorStack.join('\n');
406
+
407
+ DynamoFM_Log.error(errorMsg);
408
+
409
+ throw error;
410
+ }
411
+ }
412
+ }
413
+
414
+ await DynamoFM_Array.asyncForEach(
415
+ this.socketServices,
416
+ async (service: DynamoNTS_SocketServerService<any>): Promise<void> => {
417
+ try {
418
+ this.systemControlsExt.httpSocketServer.init = true;
419
+ const existingPorts: DynamoNTS_SocketServerService<any>[] = this.socketServices.filter(
420
+ (mod: DynamoNTS_SocketServerService<any>): boolean => mod.port === service.port
421
+ );
422
+
423
+ if (
424
+ 1 < existingPorts.length ||
425
+ this.portSettings.httpPort === service.port ||
426
+ this.portSettings.httpsPort === service.port
427
+ ) {
428
+ const error = new Error(`PORT DUPLICATION: ${service.port}`);
429
+ const errorStack: string[] = error.stack.split('\n');
430
+
431
+ errorStack.splice(1, 4);
432
+ error.stack = errorStack.join('\n');
433
+
434
+ DynamoFM_Log.error(`\n${error.message}`);
435
+
436
+ throw error;
437
+ }
438
+
439
+ if (service.security === DynamoNTS_SocketSecurity.open) {
440
+ if (this.logSetup) console.log(
441
+ `\nsocket setup (open): ${service?.name}:${service.port}`
442
+ );
443
+ this.httpSocketSettingUpCount++;
444
+ this.systemControlsExt.httpSocketServer.started = false;
445
+
446
+ this.allSocketServers.push(
447
+ await service.setupSocketServer(
448
+ new SocketIO.Server(this.httpSocketServer),
449
+ DynamoNTS_SocketSecurity.open,
450
+ (): void => {
451
+ this.httpSocketSettingUpCount--;
452
+
453
+ if (this.httpSocketSettingUpCount === 0) {
454
+ this.systemControlsExt.httpSocketServer.started = true;
455
+ }
456
+ }
457
+ )
458
+ );
459
+
460
+ } else if (service.security === DynamoNTS_SocketSecurity.secure) {
461
+ if (this.logSetup) console.log(
462
+ `\nsocket setup (secure): ${service?.name}:${service.port}`
463
+ );
464
+ this.httpsSocketSettingUpCount++;
465
+ this.systemControlsExt.httpsSocketServer.started = false;
466
+
467
+ this.allSocketServers.push(
468
+ await service.setupSocketServer(
469
+ new SocketIO.Server(this.httpsServer),
470
+ DynamoNTS_SocketSecurity.secure,
471
+ (): void => {
472
+ this.httpsSocketSettingUpCount--;
473
+
474
+ if (this.httpsSocketSettingUpCount === 0) {
475
+ this.systemControlsExt.httpsSocketServer.started = true;
476
+ }
477
+ }
478
+ )
479
+ );
480
+
481
+ } else {
482
+ const error = new Error(
483
+ `INVALID Socket Service security: ${service.security} on ${service?.name}`
484
+ );
485
+ const errorStack: string[] = error.stack.split('\n');
486
+
487
+ errorStack.splice(1, 4);
488
+ error.stack = errorStack.join('\n');
489
+
490
+ DynamoFM_Log.error(`\n${error.message}`);
491
+
492
+ throw error;
493
+ }
494
+ } catch (error) {
495
+ DynamoFM_Log.error(
496
+ `\nSocket Server service setup failed. (${service?.name})\n`,
497
+ error,
498
+ '\n'
499
+ );
500
+
501
+ throw error;
502
+ }
503
+ }
504
+ );
505
+ } catch (error) {
506
+ DynamoFM_Log.error(
507
+ `\nSocket Server services setup failed. (${this.socketServices?.length} services)\n`,
508
+ error,
509
+ '\n'
510
+ );
511
+
512
+ throw error;
513
+ }
514
+ }
515
+
516
+ /**
517
+ * MISSING Description (TODO)
518
+ */
519
+ abstract getSocketServices(): DynamoNTS_SocketServerService<any>[];
520
+ }