@futdevpro/nts-dynamo 1.9.14 → 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 (142) hide show
  1. package/.copilot/patterns.json +7 -7
  2. package/.eslintrc.json +1 -1
  3. package/.github/workflows/main.yml +206 -0
  4. package/HOWTO.md +15 -15
  5. package/README.md +140 -140
  6. package/build/_constants/mocks/auth-service.mock.d.ts +1 -1
  7. package/build/_constants/mocks/auth-service.mock.d.ts.map +1 -1
  8. package/build/_constants/mocks/auth-service.mock.js +1 -1
  9. package/build/_constants/mocks/auth-service.mock.js.map +1 -1
  10. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  11. package/build/_models/control-models/endpoint-params.control-model.js +2 -0
  12. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  13. package/build/_models/control-models/socket-event.control-model.js +1 -1
  14. package/build/_modules/usage/usage.controller.js +1 -1
  15. package/build/_modules/usage/usage.controller.js.map +1 -1
  16. package/build/_services/base/db.service.js +3 -3
  17. package/build/_services/base/db.service.js.map +1 -1
  18. package/build/_services/core/auth.service.d.ts +3 -3
  19. package/build/_services/core/auth.service.d.ts.map +1 -1
  20. package/build/_services/core/global.service.d.ts.map +1 -1
  21. package/build/_services/core/global.service.js +1 -0
  22. package/build/_services/core/global.service.js.map +1 -1
  23. package/build/_services/route/controller.service.d.ts +3 -3
  24. package/build/_services/route/controller.service.js +2 -2
  25. package/build/_services/route/routing-module.service.d.ts +1 -0
  26. package/build/_services/route/routing-module.service.d.ts.map +1 -1
  27. package/build/_services/route/routing-module.service.js +17 -23
  28. package/build/_services/route/routing-module.service.js.map +1 -1
  29. package/build/_services/server/app.server.d.ts.map +1 -1
  30. package/build/_services/server/app.server.js +4 -1
  31. package/build/_services/server/app.server.js.map +1 -1
  32. package/build/_services/socket/socket-client.service.d.ts.map +1 -1
  33. package/build/_services/socket/socket-client.service.js +1 -0
  34. package/build/_services/socket/socket-client.service.js.map +1 -1
  35. package/nodemon.json +17 -15
  36. package/package.json +6 -6
  37. package/src/_constants/global-settings.const.ts +27 -27
  38. package/src/_constants/index.ts +2 -2
  39. package/src/_constants/mocks/app-extended-server.mock.ts +198 -198
  40. package/src/_constants/mocks/app-params.mock.ts +9 -9
  41. package/src/_constants/mocks/app-server.mock.ts +185 -185
  42. package/src/_constants/mocks/auth-service.mock.ts +28 -28
  43. package/src/_constants/mocks/controller.mock.ts +16 -16
  44. package/src/_constants/mocks/data-model.mock.ts +83 -83
  45. package/src/_constants/mocks/email-service-collection.mock.ts +13 -13
  46. package/src/_constants/mocks/email-service.mock.ts +19 -19
  47. package/src/_constants/mocks/email-template.mock.html +14 -14
  48. package/src/_constants/mocks/endpoint.mock.ts +90 -90
  49. package/src/_constants/mocks/socket-client.mock.ts +43 -43
  50. package/src/_constants/mocks/socket-server.mock.ts +43 -43
  51. package/src/_enums/data-model-type.enum.ts +14 -14
  52. package/src/_enums/data-service-function.enum.ts +15 -15
  53. package/src/_enums/http/http-call-type.enum.ts +12 -12
  54. package/src/_enums/http/http-response-type.enum.ts +7 -7
  55. package/src/_enums/http/socket-event-type.enum.ts +18 -18
  56. package/src/_enums/index.ts +13 -13
  57. package/src/_enums/predefined-data-types.enum.ts +27 -27
  58. package/src/_enums/route-security.enum.ts +12 -12
  59. package/src/_enums/socket-security.enum.ts +11 -11
  60. package/src/_models/control-models/api-call-params.control-model.ts +126 -126
  61. package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
  62. package/src/_models/control-models/app-params.control-model.ts +45 -45
  63. package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
  64. package/src/_models/control-models/endpoint-params.control-model.ts +309 -307
  65. package/src/_models/control-models/http-settings.control-model.ts +29 -29
  66. package/src/_models/control-models/index.ts +13 -13
  67. package/src/_models/control-models/socket-client-service-params.control-model.ts +28 -28
  68. package/src/_models/control-models/socket-event.control-model.ts +150 -150
  69. package/src/_models/control-models/socket-presence.control-model.ts +207 -207
  70. package/src/_models/control-models/socket-server-service-params.control-model.ts +20 -20
  71. package/src/_models/control-models/system-control.control-model.ts +12 -12
  72. package/src/_models/index.ts +9 -9
  73. package/src/_models/interfaces/certification-settings.interface.ts +7 -7
  74. package/src/_models/interfaces/global-service-settings.interface.ts +45 -45
  75. package/src/_models/interfaces/global-settings.interface.ts +83 -83
  76. package/src/_models/interfaces/index.ts +7 -7
  77. package/src/_models/interfaces/routing-module-settings.interface.ts +20 -20
  78. package/src/_models/types/db-filter.type.ts +108 -108
  79. package/src/_models/types/db-update.type.ts +100 -100
  80. package/src/_models/types/index.ts +5 -5
  81. package/src/_modules/api-service.index.ts +12 -12
  82. package/src/_modules/app-extended.index.ts +28 -28
  83. package/src/_modules/app.index.ts +24 -24
  84. package/src/_modules/auth.index.ts +7 -7
  85. package/src/_modules/constants.index.ts +2 -2
  86. package/src/_modules/controller.index.ts +10 -10
  87. package/src/_modules/custom-data/custom-data.controller.ts +69 -69
  88. package/src/_modules/custom-data/custom-data.data-service.ts +20 -20
  89. package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +23 -23
  90. package/src/_modules/custom-data/index.ts +6 -6
  91. package/src/_modules/custom-data-module.index.ts +2 -2
  92. package/src/_modules/data-service.index.ts +9 -9
  93. package/src/_modules/email.index.ts +8 -8
  94. package/src/_modules/enums.index.ts +2 -2
  95. package/src/_modules/extended.index.ts +8 -8
  96. package/src/_modules/models.index.ts +2 -2
  97. package/src/_modules/services.index.ts +2 -2
  98. package/src/_modules/test/get-test-routing-module.util.ts +23 -23
  99. package/src/_modules/test/index.ts +5 -5
  100. package/src/_modules/test/test.controller.ts +115 -115
  101. package/src/_modules/test-module.index.ts +2 -2
  102. package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
  103. package/src/_modules/usage/index.ts +7 -7
  104. package/src/_modules/usage/usage.controller.ts +120 -120
  105. package/src/_modules/usage/usage.data-service.ts +172 -172
  106. package/src/_modules/usage-module.index.ts +2 -2
  107. package/src/_services/base/data.service.ts +921 -921
  108. package/src/_services/base/db.service.spec.ts +32 -32
  109. package/src/_services/base/db.service.ts +1063 -1063
  110. package/src/_services/base/singleton.service.ts +21 -21
  111. package/src/_services/core/api.service.ts +453 -453
  112. package/src/_services/core/auth.service.ts +172 -172
  113. package/src/_services/core/email.service.ts +678 -678
  114. package/src/_services/core/global.service.ts +270 -269
  115. package/src/_services/core/service-collection.service.ts +5 -5
  116. package/src/_services/index.ts +23 -23
  117. package/src/_services/route/controller.service.ts +129 -129
  118. package/src/_services/route/routing-module.service.ts +293 -273
  119. package/src/_services/server/app-extended.server.spec.ts +76 -76
  120. package/src/_services/server/app-extended.server.ts +520 -520
  121. package/src/_services/server/app.server.spec.ts +67 -67
  122. package/src/_services/server/app.server.ts +1181 -1179
  123. package/src/_services/shared.service.spec.ts +19 -19
  124. package/src/_services/shared.static-service.ts +73 -73
  125. package/src/_services/socket/socket-client.service.ts +236 -235
  126. package/src/_services/socket/socket-server.service.spec.ts +11 -11
  127. package/src/_services/socket/socket-server.service.ts +761 -761
  128. package/src/index.ts +18 -18
  129. package/tsconfig.json +41 -46
  130. package/build/tsconfig.tsbuildinfo +0 -1
  131. package/src/_enums/http/http-call-type.enum.d.ts +0 -12
  132. package/src/_enums/http/http-call-type.enum.d.ts.map +0 -1
  133. package/src/_enums/http/http-call-type.enum.js +0 -16
  134. package/src/_enums/http/http-call-type.enum.js.map +0 -1
  135. package/src/_enums/http/http-response-type.enum.d.ts +0 -7
  136. package/src/_enums/http/http-response-type.enum.d.ts.map +0 -1
  137. package/src/_enums/http/http-response-type.enum.js +0 -11
  138. package/src/_enums/http/http-response-type.enum.js.map +0 -1
  139. package/src/_enums/http/socket-event-type.enum.d.ts +0 -15
  140. package/src/_enums/http/socket-event-type.enum.d.ts.map +0 -1
  141. package/src/_enums/http/socket-event-type.enum.js +0 -19
  142. package/src/_enums/http/socket-event-type.enum.js.map +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
+ }