opticore-webapp 1.0.69 → 1.0.70
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.
- package/dist/index.cjs +154 -1103
- package/dist/index.d.cts +15 -494
- package/dist/index.d.ts +15 -494
- package/dist/index.js +158 -1115
- package/dist/utils/translations/message.translation.en.json +5 -3
- package/dist/utils/translations/message.translation.fr.json +2 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2,115 +2,25 @@
|
|
|
2
2
|
import * as path2 from "path";
|
|
3
3
|
import process4 from "process";
|
|
4
4
|
import corsOrigin from "cors";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
CEvent,
|
|
9
|
-
CEventNameError as eventName2,
|
|
10
|
-
ServerListenEventError as ServerListenEventError2
|
|
11
|
-
} from "opticore-catch-exception-error";
|
|
12
|
-
import { getEnvironmentValue } from "opticore-env-access";
|
|
13
|
-
import { requestCallsEvent } from "opticore-request-call-event";
|
|
14
|
-
import { SContainer as SContainer2 } from "opticore-dependency-inject";
|
|
5
|
+
import { CEventNameError as eventName2, ServerListenEventError as ServerListenEventError2 } from "opticore-catch-exception-error";
|
|
6
|
+
import { express as express2 } from "opticore-express";
|
|
7
|
+
import { getEnvironmentValue as getEnvironmentValue2 } from "opticore-env-access";
|
|
15
8
|
import { HttpStatusCode as HttpStatusCode3 } from "opticore-http-response";
|
|
16
9
|
import { TranslationLoader as TranslationLoader2 } from "opticore-translator";
|
|
10
|
+
import { requestCallsEvent } from "opticore-request-call-event";
|
|
17
11
|
|
|
18
12
|
// src/core/handlers/eventProcess.handler.ts
|
|
19
13
|
import process from "process";
|
|
20
14
|
import EventEmitter from "events";
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
CEvent as event
|
|
25
|
-
} from "opticore-catch-exception-error";
|
|
26
|
-
|
|
27
|
-
// src/utils/isTransformError.utils.ts
|
|
28
|
-
var isTransformErrorUtils = (error) => {
|
|
29
|
-
return error?.name === "TransformError" || error?.message?.includes("Transform failed") || error?.message?.includes("esbuild");
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// src/core/handlers/eventProcess.handler.ts
|
|
33
|
-
function eventProcessHandler(localeLanguage, expressApp) {
|
|
15
|
+
import { express } from "opticore-express";
|
|
16
|
+
import { ServerListenEventError, CEventNameError as eventName, CEvent as event } from "opticore-catch-exception-error";
|
|
17
|
+
function eventProcessHandler(localeLanguage) {
|
|
34
18
|
const errorEmitter = new EventEmitter();
|
|
19
|
+
const app = express();
|
|
35
20
|
const serverListenEvent = new ServerListenEventError(localeLanguage);
|
|
36
|
-
console.log("[Server] Setting up error event handlers...");
|
|
37
21
|
errorEmitter.on(eventName.error, (error) => {
|
|
38
|
-
console.error("[Server] EventEmitter error caught:", error.message);
|
|
39
|
-
if (isTransformErrorUtils(error)) {
|
|
40
|
-
handleTransformError(error);
|
|
41
|
-
}
|
|
42
22
|
serverListenEvent.listenerError(error);
|
|
43
23
|
});
|
|
44
|
-
function handleTransformError(error) {
|
|
45
|
-
console.error("[Server] ============================================");
|
|
46
|
-
console.error("[Server] TRANSFORM ERROR DETECTED");
|
|
47
|
-
console.error("[Server] ============================================");
|
|
48
|
-
console.error("[Server] Message:", error.message);
|
|
49
|
-
console.error("[Server] Stack:", error.stack);
|
|
50
|
-
if (error.errors && Array.isArray(error.errors)) {
|
|
51
|
-
error.errors.forEach((err, index) => {
|
|
52
|
-
console.error(`[Server] Error ${index + 1}:`, err.text);
|
|
53
|
-
if (err.location) {
|
|
54
|
-
console.error(`[Server] File: ${err.location.file}`);
|
|
55
|
-
console.error(`[Server] Line: ${err.location.line}, Column: ${err.location.column}`);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
const fileMatch = error.message.match(/([^:]+\.ts):(\d+):(\d+):/);
|
|
60
|
-
if (fileMatch) {
|
|
61
|
-
console.error("[Server] Problem file:", fileMatch[1]);
|
|
62
|
-
console.error("[Server] Line:", fileMatch[2], "Column:", fileMatch[3]);
|
|
63
|
-
}
|
|
64
|
-
const errorDetailMatch = error.message.match(/ERROR: (.+)$/m);
|
|
65
|
-
if (errorDetailMatch) {
|
|
66
|
-
console.error("[Server] Error detail:", errorDetailMatch[1]);
|
|
67
|
-
}
|
|
68
|
-
console.error("[Server] ============================================");
|
|
69
|
-
if (process.send) {
|
|
70
|
-
process.send({
|
|
71
|
-
type: "TRANSFORM_ERROR",
|
|
72
|
-
error: error.message,
|
|
73
|
-
stack: error.stack,
|
|
74
|
-
errorName: error.name,
|
|
75
|
-
details: error.errors,
|
|
76
|
-
timestamp: Date.now()
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
process.on(event.uncaughtException, (error) => {
|
|
81
|
-
console.error("[Server] UNCAUGHT EXCEPTION:", error.message);
|
|
82
|
-
console.error("[Server] Stack:", error.stack);
|
|
83
|
-
if (isTransformErrorUtils(error)) {
|
|
84
|
-
errorEmitter.emit("transformError", error);
|
|
85
|
-
}
|
|
86
|
-
serverListenEvent.uncaughtException(error);
|
|
87
|
-
if (process.send) {
|
|
88
|
-
const messageType = isTransformErrorUtils(error) ? "TRANSFORM_ERROR" : "HOT_RELOAD_ERROR";
|
|
89
|
-
process.send({
|
|
90
|
-
type: messageType,
|
|
91
|
-
error: error.message,
|
|
92
|
-
stack: error.stack,
|
|
93
|
-
errorName: error.name,
|
|
94
|
-
timestamp: Date.now()
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
process.on(event.unhandledRejection, (reason, promise) => {
|
|
99
|
-
console.error("[Server] UNHANDLED REJECTION:", reason);
|
|
100
|
-
if (isTransformErrorUtils(reason)) {
|
|
101
|
-
errorEmitter.emit("transformError", reason);
|
|
102
|
-
}
|
|
103
|
-
serverListenEvent.unhandledRejection(reason, promise);
|
|
104
|
-
if (process.send) {
|
|
105
|
-
const messageType = isTransformErrorUtils(reason) ? "TRANSFORM_ERROR" : "HOT_RELOAD_ERROR";
|
|
106
|
-
process.send({
|
|
107
|
-
type: messageType,
|
|
108
|
-
error: reason?.message || String(reason),
|
|
109
|
-
errorName: reason?.name,
|
|
110
|
-
timestamp: Date.now()
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
24
|
process.on(event.beforeExit, (code) => {
|
|
115
25
|
setTimeout(() => {
|
|
116
26
|
serverListenEvent.processBeforeExit(code);
|
|
@@ -125,20 +35,20 @@ function eventProcessHandler(localeLanguage, expressApp) {
|
|
|
125
35
|
process.on(event.rejectionHandled, (promise) => {
|
|
126
36
|
serverListenEvent.promiseRejectionHandled(promise);
|
|
127
37
|
});
|
|
38
|
+
process.on(event.uncaughtException, (error) => {
|
|
39
|
+
serverListenEvent.uncaughtException(error);
|
|
40
|
+
});
|
|
128
41
|
process.on(event.uncaughtExceptionMonitor, (error) => {
|
|
129
|
-
console.error("[Server] UNCAUGHT EXCEPTION MONITOR:", error.message);
|
|
130
|
-
if (isTransformErrorUtils(error)) {
|
|
131
|
-
errorEmitter.emit("transformError", error);
|
|
132
|
-
}
|
|
133
42
|
serverListenEvent.uncaughtExceptionMonitor(error);
|
|
134
43
|
});
|
|
44
|
+
process.on(event.unhandledRejection, (reason, promise) => {
|
|
45
|
+
serverListenEvent.unhandledRejection(reason, promise);
|
|
46
|
+
});
|
|
135
47
|
process.on(event.warning, (warning) => {
|
|
136
48
|
serverListenEvent.warning(warning);
|
|
137
49
|
});
|
|
138
50
|
process.on(event.message, (message) => {
|
|
139
|
-
|
|
140
|
-
serverListenEvent.message(message);
|
|
141
|
-
}
|
|
51
|
+
serverListenEvent.message(message);
|
|
142
52
|
});
|
|
143
53
|
process.on(event.multipleResolves, (type, promise, reason) => {
|
|
144
54
|
serverListenEvent.multipleResolves(type, promise, reason);
|
|
@@ -149,15 +59,9 @@ function eventProcessHandler(localeLanguage, expressApp) {
|
|
|
149
59
|
process.on(event.sigterm, (signal) => {
|
|
150
60
|
serverListenEvent.sigtermSignalReceived(signal);
|
|
151
61
|
});
|
|
152
|
-
|
|
153
|
-
console.error("[Server] Express error middleware triggered:", err.message);
|
|
154
|
-
console.error("[Server] Request URL:", req.url);
|
|
155
|
-
console.error("[Server] Request method:", req.method);
|
|
156
|
-
errorEmitter.emit(eventName.error, err);
|
|
62
|
+
app.use((err, req, res, next) => {
|
|
157
63
|
serverListenEvent.expressErrorHandlingMiddleware(errorEmitter, err, req, res, next);
|
|
158
64
|
});
|
|
159
|
-
console.log("[Server] Error event handlers configured successfully");
|
|
160
|
-
return errorEmitter;
|
|
161
65
|
}
|
|
162
66
|
|
|
163
67
|
// src/application/service/core.service.ts
|
|
@@ -168,7 +72,7 @@ import * as fs from "fs";
|
|
|
168
72
|
import colors from "ansi-colors";
|
|
169
73
|
import { HttpStatusCode, HttpStatusCode as status } from "opticore-http-response";
|
|
170
74
|
import { TranslationLoader } from "opticore-translator";
|
|
171
|
-
import {
|
|
75
|
+
import { getEnvironmentValue } from "opticore-env-access";
|
|
172
76
|
|
|
173
77
|
// src/utils/envPath.utils.ts
|
|
174
78
|
import process2 from "process";
|
|
@@ -208,21 +112,6 @@ var dependenciesContainerProvider = (localLang) => {
|
|
|
208
112
|
return new SContainer(localLang, dependencies);
|
|
209
113
|
};
|
|
210
114
|
|
|
211
|
-
// src/application/service/core.service.ts
|
|
212
|
-
import { LoggerCore as LoggerCore2 } from "opticore-logger";
|
|
213
|
-
|
|
214
|
-
// src/application/service/logger.service.ts
|
|
215
|
-
var SLogger = (localLang) => {
|
|
216
|
-
return {
|
|
217
|
-
get serverLog() {
|
|
218
|
-
return dependenciesContainerProvider(localLang).resolve("OpticoreLogger");
|
|
219
|
-
},
|
|
220
|
-
get logger() {
|
|
221
|
-
return dependenciesContainerProvider(localLang).resolve("LoggerCore");
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
};
|
|
225
|
-
|
|
226
115
|
// src/application/service/core.service.ts
|
|
227
116
|
var CoreService = class {
|
|
228
117
|
localLanguage;
|
|
@@ -230,9 +119,9 @@ var CoreService = class {
|
|
|
230
119
|
serverLog;
|
|
231
120
|
logger;
|
|
232
121
|
constructor(localLang, environmentPath) {
|
|
122
|
+
this.loadTranslationFiles();
|
|
233
123
|
this.environmentPath = environmentPath;
|
|
234
124
|
this.localLanguage = localLang;
|
|
235
|
-
loaderTranslationFile(this.localLanguage);
|
|
236
125
|
this.serverLog = dependenciesContainerProvider(localLang).resolve("OpticoreLogger");
|
|
237
126
|
this.logger = dependenciesContainerProvider(localLang).resolve("LoggerCore");
|
|
238
127
|
}
|
|
@@ -246,6 +135,41 @@ var CoreService = class {
|
|
|
246
135
|
formatMemoryUsage(data) {
|
|
247
136
|
return `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
|
|
248
137
|
}
|
|
138
|
+
loadTranslationFiles() {
|
|
139
|
+
loaderTranslationFile(this.localLanguage);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
*
|
|
143
|
+
* @param filePath
|
|
144
|
+
* @private
|
|
145
|
+
*
|
|
146
|
+
* Return void
|
|
147
|
+
*/
|
|
148
|
+
getEnvFileLoading(filePath) {
|
|
149
|
+
this.loadTranslationFiles();
|
|
150
|
+
try {
|
|
151
|
+
const fullPath = path.resolve(process3.cwd(), filePath);
|
|
152
|
+
if (fs.existsSync(fullPath)) {
|
|
153
|
+
const env = fs.readFileSync(fullPath, "utf-8");
|
|
154
|
+
const lines = env.split("\n");
|
|
155
|
+
lines.forEach((line) => {
|
|
156
|
+
const match = line.match(/^([^#=]+)=([^#]+)$/);
|
|
157
|
+
if (match) {
|
|
158
|
+
const key = match[1].trim();
|
|
159
|
+
process3.env[key] = match[2].trim();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
} catch (err) {
|
|
164
|
+
this.logger.error({
|
|
165
|
+
message: err.message,
|
|
166
|
+
title: TranslationLoader.t("EnvFileLoading", this.localLanguage),
|
|
167
|
+
errorType: err.code,
|
|
168
|
+
stackTrace: err.stack,
|
|
169
|
+
httpCodeValue: status.INTERNAL_SERVER_ERROR
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
249
173
|
/**
|
|
250
174
|
* Returns an Object containing a node version, openssl, and v0
|
|
251
175
|
*/
|
|
@@ -270,7 +194,7 @@ var CoreService = class {
|
|
|
270
194
|
* and Memory usage system
|
|
271
195
|
*/
|
|
272
196
|
getUsageMemory() {
|
|
273
|
-
|
|
197
|
+
this.loadTranslationFiles();
|
|
274
198
|
const memoryData = process3.memoryUsage();
|
|
275
199
|
const data = {
|
|
276
200
|
[TranslationLoader.t("totalMemoryAllocated", this.localLanguage)]: this.formatMemoryUsage(memoryData.rss),
|
|
@@ -302,37 +226,6 @@ var CoreService = class {
|
|
|
302
226
|
"startingTime": `${executionTime.toFixed(5)} ms`
|
|
303
227
|
};
|
|
304
228
|
}
|
|
305
|
-
/**
|
|
306
|
-
*
|
|
307
|
-
* @param filePath
|
|
308
|
-
* @private
|
|
309
|
-
*
|
|
310
|
-
* Return void
|
|
311
|
-
*/
|
|
312
|
-
getEnvFileLoading(filePath) {
|
|
313
|
-
try {
|
|
314
|
-
const fullPath = path.resolve(process3.cwd(), filePath);
|
|
315
|
-
if (fs.existsSync(fullPath)) {
|
|
316
|
-
const env = fs.readFileSync(fullPath, "utf-8");
|
|
317
|
-
const lines = env.split("\n");
|
|
318
|
-
lines.forEach((line) => {
|
|
319
|
-
const match = line.match(/^([^#=]+)=([^#]+)$/);
|
|
320
|
-
if (match) {
|
|
321
|
-
const key = match[1].trim();
|
|
322
|
-
process3.env[key] = match[2].trim();
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
} catch (err) {
|
|
327
|
-
this.logger.error({
|
|
328
|
-
message: err.message,
|
|
329
|
-
title: TranslationLoader.t("EnvFileLoading", this.localLanguage),
|
|
330
|
-
errorType: err.code,
|
|
331
|
-
stackTrace: err.stack,
|
|
332
|
-
httpCodeValue: status.INTERNAL_SERVER_ERROR
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
229
|
/**
|
|
337
230
|
*
|
|
338
231
|
* @param development
|
|
@@ -341,14 +234,15 @@ var CoreService = class {
|
|
|
341
234
|
* Return string
|
|
342
235
|
*/
|
|
343
236
|
getServerRunningMode(development, production) {
|
|
237
|
+
this.loadTranslationFiles();
|
|
344
238
|
try {
|
|
345
|
-
loaderTranslationFile(this.localLanguage);
|
|
346
239
|
this.getEnvFileLoading(".env");
|
|
347
|
-
const env =
|
|
348
|
-
const isDevelopment = env.devEnv === development
|
|
240
|
+
const env = getEnvironmentValue(path.join(envPath));
|
|
241
|
+
const isDevelopment = env.devEnv === development;
|
|
242
|
+
const isProd = env.prodEnv === production;
|
|
349
243
|
if (isDevelopment) {
|
|
350
244
|
return `${TranslationLoader.t("serverRunning", this.localLanguage)} ${colors.bgBlue(`${colors.bold(`${development}`)}`)} mode`;
|
|
351
|
-
} else if (
|
|
245
|
+
} else if (isProd) {
|
|
352
246
|
return `${TranslationLoader.t("serverRunning", this.localLanguage)} ${colors.bgBlue(`${colors.bold(`${production}`)}`)} mode`;
|
|
353
247
|
} else {
|
|
354
248
|
return `${TranslationLoader.t("serverRunning", this.localLanguage)} ${colors.bgBlue(`${colors.bold(`${development}`)}`)} mode`;
|
|
@@ -364,9 +258,9 @@ var CoreService = class {
|
|
|
364
258
|
}
|
|
365
259
|
}
|
|
366
260
|
infoServer(host, port) {
|
|
261
|
+
this.loadTranslationFiles();
|
|
367
262
|
try {
|
|
368
|
-
|
|
369
|
-
const getEnvironment = getEnvironnementValue(this.environmentPath);
|
|
263
|
+
const getEnvironment = getEnvironmentValue(this.environmentPath);
|
|
370
264
|
const msg5 = getEnvironment.protocolTransfert === "" ? colors.underline(`http://${host}:${port}`) : colors.underline(`${getEnvironment.protocolTransfert}://${host}:${port}`);
|
|
371
265
|
const messages = [
|
|
372
266
|
TranslationLoader.t("webServerListening", this.localLanguage),
|
|
@@ -387,12 +281,11 @@ var CoreService = class {
|
|
|
387
281
|
});
|
|
388
282
|
console.log(border);
|
|
389
283
|
console.log("\n");
|
|
390
|
-
|
|
391
|
-
logCore.success({
|
|
284
|
+
this.logger.success({
|
|
392
285
|
title: TranslationLoader.t("serverRunningTitle", this.localLanguage),
|
|
393
286
|
message: TranslationLoader.t("serverRunningAt", this.localLanguage, { server: msg5 })
|
|
394
287
|
});
|
|
395
|
-
|
|
288
|
+
this.serverLog.serverLog({
|
|
396
289
|
timestamp: (/* @__PURE__ */ new Date()).toString(),
|
|
397
290
|
level: "SERVER",
|
|
398
291
|
title: TranslationLoader.t("serverRunningTitle", this.localLanguage),
|
|
@@ -400,7 +293,7 @@ var CoreService = class {
|
|
|
400
293
|
message: TranslationLoader.t("serverRunningAt", this.localLanguage, { server: msg5 })
|
|
401
294
|
});
|
|
402
295
|
} catch (err) {
|
|
403
|
-
|
|
296
|
+
this.logger.error({
|
|
404
297
|
message: err.message,
|
|
405
298
|
title: TranslationLoader.t("server", this.localLanguage),
|
|
406
299
|
errorType: err.code,
|
|
@@ -419,6 +312,20 @@ import {
|
|
|
419
312
|
CCodeError,
|
|
420
313
|
CErrorName
|
|
421
314
|
} from "opticore-catch-exception-error";
|
|
315
|
+
|
|
316
|
+
// src/application/service/logger.service.ts
|
|
317
|
+
var SLogger = (localLang) => {
|
|
318
|
+
return {
|
|
319
|
+
get serverLog() {
|
|
320
|
+
return dependenciesContainerProvider(localLang).resolve("OpticoreLogger");
|
|
321
|
+
},
|
|
322
|
+
get logger() {
|
|
323
|
+
return dependenciesContainerProvider(localLang).resolve("LoggerCore");
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// src/application/service/serverStartError.service.ts
|
|
422
329
|
import { HttpStatusCode as HttpStatusCode2 } from "opticore-http-response";
|
|
423
330
|
var SServerStartError = (err, environmentPath) => {
|
|
424
331
|
if (err.name) {
|
|
@@ -451,390 +358,108 @@ var SServerStartError = (err, environmentPath) => {
|
|
|
451
358
|
};
|
|
452
359
|
|
|
453
360
|
// src/core/webServer.core.ts
|
|
361
|
+
import { SContainer as SContainer2 } from "opticore-dependency-inject";
|
|
454
362
|
var WebServerCore = class {
|
|
455
363
|
serverUtility;
|
|
456
|
-
expressApp;
|
|
364
|
+
expressApp = express2();
|
|
457
365
|
localLanguage;
|
|
458
366
|
loggerConfig;
|
|
459
|
-
|
|
367
|
+
routerExpressApp;
|
|
368
|
+
getEnvironmentValue;
|
|
460
369
|
environmentPath;
|
|
461
370
|
serverListenEvent;
|
|
462
|
-
|
|
463
|
-
currentRoutes = [];
|
|
464
|
-
currentDependencies = [];
|
|
465
|
-
server = void 0;
|
|
466
|
-
errorEmitter;
|
|
467
|
-
serverStatus = "STARTING";
|
|
468
|
-
serverStartTime = /* @__PURE__ */ new Date();
|
|
469
|
-
// HMR properties
|
|
470
|
-
fileWatcher = null;
|
|
471
|
-
hmrRestartPending = false;
|
|
472
|
-
hmrDebounceTimeout = null;
|
|
473
|
-
hmrRestartCount = 0;
|
|
474
|
-
lastHmrRestartTime = 0;
|
|
475
|
-
/**
|
|
476
|
-
* Creates a new WebServerCore instance.
|
|
477
|
-
*
|
|
478
|
-
* @constructor
|
|
479
|
-
* @param {WebServerConstructorInterface} paramsConstructor - Configuration parameters
|
|
480
|
-
*
|
|
481
|
-
* @param {express.Application} paramsConstructor.app - Express application instance
|
|
482
|
-
* @param {LoggerCore} paramsConstructor.loggerConfig - Logger configuration
|
|
483
|
-
* @param {string} paramsConstructor.environmentPath - Path to environment file
|
|
484
|
-
* @param {string} paramsConstructor.localLanguage - Default language for translations
|
|
485
|
-
* @param {CorsOptions} paramsConstructor.corsOriginOptions - CORS configuration
|
|
486
|
-
*
|
|
487
|
-
* @returns {WebServerCore} New WebServerCore instance
|
|
488
|
-
*
|
|
489
|
-
* @throws {Error} If environment file cannot be loaded
|
|
490
|
-
*
|
|
491
|
-
* @example
|
|
492
|
-
* ```typescript
|
|
493
|
-
* const server = new WebServerCore({
|
|
494
|
-
* app: express(),
|
|
495
|
-
* loggerConfig: new LoggerCore(config),
|
|
496
|
-
* environmentPath: ".env",
|
|
497
|
-
* localLanguage: "fr",
|
|
498
|
-
* corsOriginOptions: { origin: "http://localhost:3000" }
|
|
499
|
-
* });
|
|
500
|
-
* ```
|
|
501
|
-
*/
|
|
371
|
+
dependenciesRegistered = false;
|
|
502
372
|
constructor(paramsConstructor) {
|
|
503
|
-
this.
|
|
373
|
+
this.loadTranslationFiles();
|
|
374
|
+
this.stackTraceErrorHandling();
|
|
375
|
+
this.getEnvironmentValue = getEnvironmentValue2(paramsConstructor.environmentPath);
|
|
376
|
+
this.routerExpressApp = paramsConstructor.app;
|
|
504
377
|
this.loggerConfig = paramsConstructor.loggerConfig;
|
|
505
378
|
this.localLanguage = paramsConstructor.localLanguage;
|
|
506
379
|
this.environmentPath = paramsConstructor.environmentPath;
|
|
507
|
-
this.expressApp
|
|
508
|
-
this.
|
|
509
|
-
this.expressApp.use(
|
|
510
|
-
this.expressApp.use(
|
|
511
|
-
this.expressApp.use(express.text());
|
|
512
|
-
this.expressApp.use(express.urlencoded({ extended: true }));
|
|
380
|
+
this.expressApp.use(express2.json());
|
|
381
|
+
this.expressApp.use(express2.raw());
|
|
382
|
+
this.expressApp.use(express2.text());
|
|
383
|
+
this.expressApp.use(express2.urlencoded({ extended: true }));
|
|
513
384
|
this.expressApp.use(corsOrigin(paramsConstructor.corsOriginOptions));
|
|
385
|
+
this.serverListenEvent = new ServerListenEventError2(paramsConstructor.localLanguage);
|
|
514
386
|
this.serverUtility = new CoreService(paramsConstructor.localLanguage, paramsConstructor.environmentPath);
|
|
515
|
-
this.serverStatus = "STARTING";
|
|
516
|
-
this.serverStartTime = /* @__PURE__ */ new Date();
|
|
517
|
-
this.setupProcessEventListeners();
|
|
518
387
|
}
|
|
519
|
-
|
|
520
|
-
* Starts the HTTP server and initializes all components including HMR if enabled.
|
|
521
|
-
*
|
|
522
|
-
* @method onStartServer
|
|
523
|
-
* @public
|
|
524
|
-
*
|
|
525
|
-
* @param {TFeatureRoutes[]} routers - Array of feature routes to register
|
|
526
|
-
* @param {(env: IEnvVariables) => void} [databaseCallback] - Optional database connection callback
|
|
527
|
-
* @param {TDependency[]} [dependenciesProvider] - Optional dependency injection providers
|
|
528
|
-
*
|
|
529
|
-
* @returns {serverWebApp | undefined} HTTP server instance or undefined if startup fails
|
|
530
|
-
*
|
|
531
|
-
* @throws {ServerListenEventError} If port/host configuration is invalid
|
|
532
|
-
* @throws {Error} If server initialization fails
|
|
533
|
-
*
|
|
534
|
-
* @fires WebServerCore#startHttpServer - When server successfully starts
|
|
535
|
-
* @fires WebServerCore#startHMR - When HMR is started (if enabled)
|
|
536
|
-
* @fires WebServerCore#serverError - When server fails to start
|
|
537
|
-
*
|
|
538
|
-
* @example
|
|
539
|
-
* ```typescript
|
|
540
|
-
* const server = app.onStartServer(
|
|
541
|
-
* routes,
|
|
542
|
-
* (env) => connectToDatabase(env),
|
|
543
|
-
* dependencies
|
|
544
|
-
* );
|
|
545
|
-
*
|
|
546
|
-
* if (server) {
|
|
547
|
-
* console.log("Server started successfully");
|
|
548
|
-
* }
|
|
549
|
-
* ```
|
|
550
|
-
*/
|
|
551
|
-
onStartServer(routers, databaseCallback, dependenciesProvider) {
|
|
388
|
+
registerDependencies(dependencies2) {
|
|
552
389
|
try {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (this.getEnvironment.hmrEnabled) {
|
|
563
|
-
this.startHMR();
|
|
390
|
+
if (dependencies2 && dependencies2.length > 0) {
|
|
391
|
+
dependencies2.forEach((dependency) => {
|
|
392
|
+
return new SContainer2(this.localLanguage).register(dependency.key, dependency.factory, dependency.scope);
|
|
393
|
+
});
|
|
394
|
+
} else {
|
|
395
|
+
SLogger(this.environmentPath).logger.info({
|
|
396
|
+
message: TranslationLoader2.t("NO_REGISTER_DEPENDENCIES", this.localLanguage),
|
|
397
|
+
title: TranslationLoader2.t("REGISTER_DEPENDENCIES", this.localLanguage)
|
|
398
|
+
});
|
|
564
399
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
400
|
+
} catch (err) {
|
|
401
|
+
SLogger(this.environmentPath).logger.error({
|
|
402
|
+
message: err.message,
|
|
403
|
+
title: "Register Dependencies",
|
|
404
|
+
errorType: err.code,
|
|
405
|
+
stackTrace: err.stack,
|
|
406
|
+
httpCodeValue: HttpStatusCode3.INTERNAL_SERVER_ERROR
|
|
407
|
+
});
|
|
568
408
|
}
|
|
569
409
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
*
|
|
578
|
-
* @remarks
|
|
579
|
-
* Validates:
|
|
580
|
-
* - Port number is valid and positive
|
|
581
|
-
* - Host is not empty
|
|
582
|
-
* - Local language is specified
|
|
583
|
-
* - HMR configuration (if enabled)
|
|
584
|
-
*/
|
|
585
|
-
validateServerParameters() {
|
|
586
|
-
loaderTranslationFile(this.localLanguage);
|
|
587
|
-
const port = Number(this.getEnvironment.appPort);
|
|
588
|
-
if (isNaN(port) || port <= 0) {
|
|
410
|
+
onStartServer(routers, databaseCallback, dependenciesProvider) {
|
|
411
|
+
this.loadTranslationFiles();
|
|
412
|
+
if (this.getEnvironmentValue.appPort === "" && Number(this.getEnvironmentValue.appPort) === 0) {
|
|
413
|
+
this.serverListenEvent.hostPortUndefined(Number(this.getEnvironmentValue.appPort));
|
|
414
|
+
} else if (this.getEnvironmentValue.appHost === "") {
|
|
415
|
+
this.serverListenEvent.hostUndefined(this.getEnvironmentValue.appHost);
|
|
416
|
+
} else if (Number(this.getEnvironmentValue.appPort) === 0) {
|
|
589
417
|
this.serverListenEvent.portUndefined();
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (!this.getEnvironment.appHost || this.getEnvironment.appHost.trim() === "") {
|
|
593
|
-
this.serverListenEvent.hostUndefined(this.getEnvironment.appHost);
|
|
594
|
-
return false;
|
|
595
|
-
}
|
|
596
|
-
if (!this.localLanguage || this.localLanguage.trim() === "") {
|
|
597
|
-
SLogger(this.localLanguage).logger.error({
|
|
418
|
+
} else if (this.localLanguage === "") {
|
|
419
|
+
SLogger(this.environmentPath).logger.error({
|
|
598
420
|
message: TranslationLoader2.t("noDefaultLocalLang", this.localLanguage),
|
|
599
421
|
title: TranslationLoader2.t("noLocalLang", this.localLanguage),
|
|
600
422
|
errorType: TranslationLoader2.t("localLangMissing", this.localLanguage),
|
|
601
423
|
stackTrace: void 0,
|
|
602
424
|
httpCodeValue: HttpStatusCode3.NOT_FOUND
|
|
603
425
|
});
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
* Starts the HTTP server and sets up event listeners.
|
|
618
|
-
*
|
|
619
|
-
* @method startHttpServer
|
|
620
|
-
* @private
|
|
621
|
-
*
|
|
622
|
-
* @param {(env: IEnvVariables) => void} [databaseCallback] - Database connection callback
|
|
623
|
-
*
|
|
624
|
-
* @returns {serverWebApp | undefined} HTTP server instance or undefined if startup fails
|
|
625
|
-
*
|
|
626
|
-
* @throws {Error} If server fails to start
|
|
627
|
-
*/
|
|
628
|
-
startHttpServer(databaseCallback) {
|
|
629
|
-
try {
|
|
630
|
-
loaderTranslationFile(this.localLanguage);
|
|
631
|
-
const port = Number(this.getEnvironment.appPort);
|
|
632
|
-
const host = this.getEnvironment.appHost;
|
|
633
|
-
this.server = this.expressApp.listen(port, host, () => {
|
|
634
|
-
try {
|
|
635
|
-
this.configureServerComponents(databaseCallback);
|
|
636
|
-
this.serverStatus = "READY";
|
|
637
|
-
SLogger(this.localLanguage).logger.info({
|
|
638
|
-
title: TranslationLoader2.t("SERVER_RUNNING_TITLE", this.localLanguage),
|
|
639
|
-
message: TranslationLoader2.t("SERVER_RUNNING_AT", this.localLanguage, {
|
|
640
|
-
server: `${host}:${port}`,
|
|
641
|
-
hmrEnabled: this.getEnvironment.hmrEnabled ? "with HMR" : "without HMR"
|
|
642
|
-
})
|
|
643
|
-
});
|
|
644
|
-
} catch (err) {
|
|
645
|
-
this.handleServerConfigurationError(err);
|
|
646
|
-
}
|
|
647
|
-
});
|
|
648
|
-
this.setupServerEventListeners();
|
|
649
|
-
return this.server;
|
|
650
|
-
} catch (error) {
|
|
651
|
-
this.serverListenEvent.onEventError(
|
|
652
|
-
new Error(TranslationLoader2.t(
|
|
653
|
-
"HTTP_SERVER_FAILED",
|
|
654
|
-
this.localLanguage,
|
|
655
|
-
{ errorMessage: error.message }
|
|
656
|
-
))
|
|
657
|
-
);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Configures server components (database, dependencies, routes, etc.).
|
|
662
|
-
*
|
|
663
|
-
* @method configureServerComponents
|
|
664
|
-
* @private
|
|
665
|
-
*
|
|
666
|
-
* @param {(env: IEnvVariables) => void} [databaseCallback] - Database connection callback
|
|
667
|
-
*
|
|
668
|
-
* @returns {void}
|
|
669
|
-
*
|
|
670
|
-
* @throws {Error} If component configuration fails
|
|
671
|
-
*/
|
|
672
|
-
configureServerComponents(databaseCallback) {
|
|
673
|
-
try {
|
|
674
|
-
loaderTranslationFile(this.localLanguage);
|
|
675
|
-
if (databaseCallback && typeof databaseCallback === "function") {
|
|
676
|
-
try {
|
|
677
|
-
databaseCallback(this.getEnvironment);
|
|
678
|
-
} catch (dbError) {
|
|
679
|
-
this.serverListenEvent.listenerError(
|
|
680
|
-
new Error(TranslationLoader2.t("DB_CON_FAILED", this.localLanguage, { dbErrorMessage: dbError.message }))
|
|
681
|
-
);
|
|
426
|
+
} else {
|
|
427
|
+
return this.expressApp.listen(
|
|
428
|
+
Number(this.getEnvironmentValue.appPort),
|
|
429
|
+
() => {
|
|
430
|
+
this.loadTranslationFiles();
|
|
431
|
+
try {
|
|
432
|
+
databaseCallback(this.getEnvironmentValue);
|
|
433
|
+
new SContainer2(this.localLanguage, dependenciesProvider);
|
|
434
|
+
this.expressApp.use(express2.static(path2.join(process4.cwd(), "public/template")));
|
|
435
|
+
this.registerRoutes(routers);
|
|
436
|
+
} catch (err) {
|
|
437
|
+
SServerStartError(err, this.environmentPath);
|
|
438
|
+
}
|
|
682
439
|
}
|
|
683
|
-
}
|
|
684
|
-
try {
|
|
685
|
-
new SContainer2(this.localLanguage, this.currentDependencies);
|
|
686
|
-
} catch (depError) {
|
|
687
|
-
this.serverListenEvent.listenerError(
|
|
688
|
-
new Error(TranslationLoader2.t("DEPENDENCY_INJECTION_FAILED", this.localLanguage, { depErrorMessage: depError.message }))
|
|
689
|
-
);
|
|
690
|
-
}
|
|
691
|
-
this.expressApp.use(express.static(path2.join(process4.cwd(), "public/template")));
|
|
692
|
-
this.registerRoutes(this.currentRoutes);
|
|
693
|
-
this.setupErrorHandling();
|
|
694
|
-
this.infoWebApp();
|
|
695
|
-
} catch (error) {
|
|
696
|
-
this.serverListenEvent.listenerError(
|
|
697
|
-
new Error(TranslationLoader2.t("SERVER_COMPONENT_CONFIG_FAILED", this.localLanguage, { errorMessage: error.message }))
|
|
698
440
|
);
|
|
699
|
-
throw error;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Handles server configuration errors.
|
|
704
|
-
*
|
|
705
|
-
* @method handleServerConfigurationError
|
|
706
|
-
* @private
|
|
707
|
-
*
|
|
708
|
-
* @param {any} err - The error that occurred
|
|
709
|
-
*
|
|
710
|
-
* @returns {void}
|
|
711
|
-
*/
|
|
712
|
-
handleServerConfigurationError(err) {
|
|
713
|
-
loaderTranslationFile(this.localLanguage);
|
|
714
|
-
this.serverStatus = "ERROR";
|
|
715
|
-
this.serverListenEvent.onEventError(err);
|
|
716
|
-
try {
|
|
717
|
-
SServerStartError(err, this.environmentPath);
|
|
718
|
-
} catch (startError) {
|
|
719
|
-
this.serverListenEvent.listenerError(startError);
|
|
720
441
|
}
|
|
721
442
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
* @method handleStartupError
|
|
726
|
-
* @private
|
|
727
|
-
*
|
|
728
|
-
* @param {any} error - The startup error
|
|
729
|
-
*
|
|
730
|
-
* @returns {void}
|
|
731
|
-
*/
|
|
732
|
-
handleStartupError(error) {
|
|
733
|
-
loaderTranslationFile(this.localLanguage);
|
|
734
|
-
this.serverStatus = "ERROR";
|
|
735
|
-
this.serverListenEvent.listenerError(error);
|
|
736
|
-
SLogger(this.localLanguage).logger.error({
|
|
737
|
-
title: TranslationLoader2.t("GLOBAL_STARTUP_ERROR", this.localLanguage),
|
|
738
|
-
message: error.message,
|
|
739
|
-
errorType: error.name || "StartupError",
|
|
740
|
-
stackTrace: error.stack,
|
|
741
|
-
httpCodeValue: HttpStatusCode3.INTERNAL_SERVER_ERROR
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* Sets up Node.js process event listeners.
|
|
746
|
-
*
|
|
747
|
-
* @method setupProcessEventListeners
|
|
748
|
-
* @private
|
|
749
|
-
*
|
|
750
|
-
* @returns {void}
|
|
751
|
-
*
|
|
752
|
-
* @remarks
|
|
753
|
-
* Listens for:
|
|
754
|
-
* - Process exit events
|
|
755
|
-
* - Uncaught exceptions
|
|
756
|
-
* - Unhandled rejections
|
|
757
|
-
* - System signals (SIGINT, SIGTERM)
|
|
758
|
-
*/
|
|
759
|
-
setupProcessEventListeners() {
|
|
760
|
-
loaderTranslationFile(this.localLanguage);
|
|
761
|
-
process4.on(CEvent.beforeExit, (code) => {
|
|
762
|
-
this.serverListenEvent.processBeforeExit(code);
|
|
763
|
-
});
|
|
764
|
-
process4.on(CEvent.disconnect, () => {
|
|
765
|
-
this.serverListenEvent.processDisconnected();
|
|
766
|
-
});
|
|
767
|
-
process4.on(CEvent.exit, (code) => {
|
|
768
|
-
this.serverListenEvent.exited(code);
|
|
769
|
-
});
|
|
770
|
-
process4.on(CEvent.message, (message) => {
|
|
771
|
-
this.serverListenEvent.message(message);
|
|
772
|
-
});
|
|
773
|
-
process4.on(CEvent.multipleResolves, (type, promise, reason) => {
|
|
774
|
-
this.serverListenEvent.multipleResolves(type, promise, reason);
|
|
775
|
-
});
|
|
776
|
-
process4.on(CEvent.rejectionHandled, (promise) => {
|
|
777
|
-
this.serverListenEvent.promiseRejectionHandled(promise);
|
|
778
|
-
});
|
|
779
|
-
process4.on(CEvent.uncaughtException, (error) => {
|
|
780
|
-
this.serverListenEvent.uncaughtException(error);
|
|
781
|
-
});
|
|
782
|
-
process4.on(CEvent.uncaughtExceptionMonitor, (error) => {
|
|
783
|
-
this.serverListenEvent.uncaughtExceptionMonitor(error);
|
|
784
|
-
});
|
|
785
|
-
process4.on(CEvent.unhandledRejection, (reason, promise) => {
|
|
786
|
-
this.serverListenEvent.unhandledRejection(reason, promise);
|
|
787
|
-
});
|
|
788
|
-
process4.on(CEvent.warning, (warning) => {
|
|
789
|
-
this.serverListenEvent.warning(warning);
|
|
790
|
-
});
|
|
791
|
-
process4.on(CEvent.sigint, () => {
|
|
792
|
-
this.serverListenEvent.processInterrupted();
|
|
793
|
-
});
|
|
794
|
-
process4.on(CEvent.sigterm, (signal) => {
|
|
795
|
-
this.serverListenEvent.sigtermSignalReceived(signal);
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* Sets up HTTP server event listeners.
|
|
800
|
-
*
|
|
801
|
-
* @method setupServerEventListeners
|
|
802
|
-
* @private
|
|
803
|
-
*
|
|
804
|
-
* @returns {void}
|
|
805
|
-
*
|
|
806
|
-
* @remarks
|
|
807
|
-
* Configures listeners for:
|
|
808
|
-
* - Server errors
|
|
809
|
-
* - Connection closing
|
|
810
|
-
* - Connection dropping
|
|
811
|
-
* - HTTP requests (for logging)
|
|
812
|
-
*
|
|
813
|
-
* @listens Server#error - Server error events
|
|
814
|
-
* @listens Server#close - Server closing events
|
|
815
|
-
* @listens Server#drop - Connection drop events
|
|
816
|
-
* @listens Server#request - HTTP request events
|
|
817
|
-
*/
|
|
818
|
-
setupServerEventListeners() {
|
|
819
|
-
loaderTranslationFile(this.localLanguage);
|
|
820
|
-
if (!this.server) {
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
this.server.on(eventName2.error, (err) => {
|
|
443
|
+
onListeningOnServerEvent(serverWeb) {
|
|
444
|
+
this.loadTranslationFiles();
|
|
445
|
+
serverWeb.on(eventName2.error, (err) => {
|
|
824
446
|
this.serverListenEvent.onEventError(err);
|
|
825
|
-
})
|
|
826
|
-
this.server.on(eventName2.close, () => {
|
|
447
|
+
}).on(eventName2.close, () => {
|
|
827
448
|
this.serverListenEvent.serverClosing();
|
|
828
|
-
})
|
|
829
|
-
this.server.on(eventName2.drop, () => {
|
|
449
|
+
}).on(eventName2.drop, () => {
|
|
830
450
|
this.serverListenEvent.dropNewConnection();
|
|
451
|
+
}).on(eventName2.listening, () => {
|
|
452
|
+
this.infoWebApp();
|
|
831
453
|
});
|
|
832
|
-
|
|
454
|
+
}
|
|
455
|
+
onRequestOnServerEvent(serverWeb) {
|
|
456
|
+
this.loadTranslationFiles();
|
|
457
|
+
serverWeb.on(eventName2.request, (req, res) => {
|
|
833
458
|
requestCallsEvent(
|
|
834
459
|
req,
|
|
835
460
|
res,
|
|
836
|
-
this.
|
|
837
|
-
Number(this.
|
|
461
|
+
this.getEnvironmentValue.appHost,
|
|
462
|
+
Number(this.getEnvironmentValue.appPort),
|
|
838
463
|
dateTimeFormattedUtils,
|
|
839
464
|
this.environmentPath,
|
|
840
465
|
this.localLanguage
|
|
@@ -842,623 +467,41 @@ var WebServerCore = class {
|
|
|
842
467
|
});
|
|
843
468
|
}
|
|
844
469
|
/**
|
|
845
|
-
* Sets up error handling middleware and event emitters.
|
|
846
470
|
*
|
|
847
|
-
* @method setupErrorHandling
|
|
848
471
|
* @private
|
|
849
|
-
*
|
|
850
|
-
* @returns {void}
|
|
851
472
|
*/
|
|
852
|
-
|
|
473
|
+
loadTranslationFiles() {
|
|
853
474
|
loaderTranslationFile(this.localLanguage);
|
|
854
|
-
SLogger(this.localLanguage).logger.info({
|
|
855
|
-
title: TranslationLoader2.t("SETTING_UP", this.localLanguage),
|
|
856
|
-
message: TranslationLoader2.t("SETTING_UP_ERROR", this.localLanguage)
|
|
857
|
-
});
|
|
858
|
-
this.errorEmitter = eventProcessHandler(this.localLanguage, this.expressApp);
|
|
859
|
-
if (this.errorEmitter) {
|
|
860
|
-
this.expressApp.use((err, req, res, next) => {
|
|
861
|
-
this.serverListenEvent.expressErrorHandlingMiddleware(
|
|
862
|
-
this.errorEmitter,
|
|
863
|
-
err,
|
|
864
|
-
req,
|
|
865
|
-
res,
|
|
866
|
-
next
|
|
867
|
-
);
|
|
868
|
-
});
|
|
869
|
-
this.errorEmitter.on("transformError", (error) => {
|
|
870
|
-
this.serverListenEvent.listenerError(error);
|
|
871
|
-
});
|
|
872
|
-
this.errorEmitter.on("error", (error) => {
|
|
873
|
-
this.serverListenEvent.listenerError(error);
|
|
874
|
-
});
|
|
875
|
-
this.errorEmitter.on("hotReload", (data) => {
|
|
876
|
-
SLogger(this.localLanguage).logger.info({
|
|
877
|
-
title: TranslationLoader2.t("HOT_RELOAD_EVENT", this.localLanguage),
|
|
878
|
-
message: `Hot reload triggered for ${data.file}`
|
|
879
|
-
});
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
SLogger(this.localLanguage).logger.info({
|
|
883
|
-
title: TranslationLoader2.t("ERROR_HANDLING", this.localLanguage),
|
|
884
|
-
message: TranslationLoader2.t("ERROR_HANDLING_CONFIGURED", this.localLanguage)
|
|
885
|
-
});
|
|
886
475
|
}
|
|
887
476
|
/**
|
|
888
|
-
* Registers routes with the Express application.
|
|
889
477
|
*
|
|
890
|
-
* @
|
|
478
|
+
* @param allFeatureRoutes
|
|
891
479
|
* @private
|
|
892
|
-
*
|
|
893
|
-
* @param {any[]} allFeatureRoutes - Array of feature routes to register
|
|
894
|
-
*
|
|
895
|
-
* @returns {void}
|
|
896
480
|
*/
|
|
897
481
|
registerRoutes(allFeatureRoutes) {
|
|
898
|
-
allFeatureRoutes.
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
this.expressApp.use(route.path, route.handler);
|
|
902
|
-
});
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
/**
|
|
907
|
-
* Displays server information.
|
|
908
|
-
*
|
|
909
|
-
* @method infoWebApp
|
|
910
|
-
* @private
|
|
911
|
-
*
|
|
912
|
-
* @returns {void}
|
|
913
|
-
*/
|
|
914
|
-
infoWebApp() {
|
|
915
|
-
loaderTranslationFile(this.localLanguage);
|
|
916
|
-
this.serverUtility.infoServer(
|
|
917
|
-
this.getEnvironment.appHost,
|
|
918
|
-
Number(this.getEnvironment.appPort)
|
|
919
|
-
);
|
|
920
|
-
}
|
|
921
|
-
/**
|
|
922
|
-
* Starts the Hot Module Replacement (HMR) file watching system.
|
|
923
|
-
*
|
|
924
|
-
* @method startHMR
|
|
925
|
-
* @private
|
|
926
|
-
*
|
|
927
|
-
* @returns {void}
|
|
928
|
-
*
|
|
929
|
-
* @remarks
|
|
930
|
-
* Configures file watcher based on environment variables:
|
|
931
|
-
* - HMR_ENABLED: Enable/disable HMR
|
|
932
|
-
* - HMR_WATCH_PATTERNS: Files to watch
|
|
933
|
-
* - HMR_IGNORE_PATTERNS: Files to ignore
|
|
934
|
-
*
|
|
935
|
-
* @throws {Error} If HMR configuration is invalid
|
|
936
|
-
*/
|
|
937
|
-
startHMR() {
|
|
938
|
-
try {
|
|
939
|
-
loaderTranslationFile(this.localLanguage);
|
|
940
|
-
const hmrConfig = this.getEnvironment;
|
|
941
|
-
if (!hmrConfig.hmrEnabled) {
|
|
942
|
-
SLogger(this.localLanguage).logger.info({
|
|
943
|
-
title: TranslationLoader2.t("HMR_DISABLED", this.localLanguage),
|
|
944
|
-
message: "HMR is disabled in configuration"
|
|
945
|
-
});
|
|
946
|
-
return;
|
|
947
|
-
}
|
|
948
|
-
if (!hmrConfig.hmrWatchPatterns || hmrConfig.hmrWatchPatterns.length === 0) {
|
|
949
|
-
SLogger(this.localLanguage).logger.error({
|
|
950
|
-
title: TranslationLoader2.t("HMR_WATCH_PATTERNS_MISSING", this.localLanguage),
|
|
951
|
-
message: "No watch patterns defined for HMR",
|
|
952
|
-
errorType: "HMR Configuration Error",
|
|
953
|
-
httpCodeValue: HttpStatusCode3.BAD_REQUEST
|
|
954
|
-
});
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
const watchPatterns = hmrConfig.hmrWatchPatterns;
|
|
958
|
-
const ignorePatterns = hmrConfig.hmrIgnorePatterns || [
|
|
959
|
-
"node_modules/**",
|
|
960
|
-
"dist/**",
|
|
961
|
-
"build/**",
|
|
962
|
-
"*.log",
|
|
963
|
-
".git/**"
|
|
964
|
-
];
|
|
965
|
-
const allPatterns = [
|
|
966
|
-
...watchPatterns,
|
|
967
|
-
...ignorePatterns.map((pattern) => `!${pattern}`)
|
|
968
|
-
];
|
|
969
|
-
this.fileWatcher = chokidar.watch(allPatterns, {
|
|
970
|
-
ignored: /(^|[/\\])\../,
|
|
971
|
-
persistent: true,
|
|
972
|
-
ignoreInitial: true,
|
|
973
|
-
awaitWriteFinish: {
|
|
974
|
-
stabilityThreshold: 300,
|
|
975
|
-
pollInterval: 100
|
|
976
|
-
},
|
|
977
|
-
cwd: process4.cwd(),
|
|
978
|
-
depth: 10
|
|
482
|
+
allFeatureRoutes.map((router) => {
|
|
483
|
+
router.routes.map((route) => {
|
|
484
|
+
this.expressApp.use(route.path, route.handler);
|
|
979
485
|
});
|
|
980
|
-
this.fileWatcher.on("ready", () => this.onHMRWatcherReady(watchPatterns, ignorePatterns)).on("change", (filePath) => this.handleFileChange(filePath)).on("add", (filePath) => this.handleFileChange(filePath, "added")).on("unlink", (filePath) => this.handleFileChange(filePath, "deleted")).on("error", (error) => this.onHMRWatcherError(error));
|
|
981
|
-
this.hmrRestartCount = 0;
|
|
982
|
-
this.lastHmrRestartTime = Date.now();
|
|
983
|
-
SLogger(this.localLanguage).logger.info({
|
|
984
|
-
title: TranslationLoader2.t("HMR_STARTED", this.localLanguage),
|
|
985
|
-
message: TranslationLoader2.t("HMR_MONITORING_STARTED", this.localLanguage)
|
|
986
|
-
});
|
|
987
|
-
} catch (error) {
|
|
988
|
-
SLogger(this.localLanguage).logger.error({
|
|
989
|
-
title: TranslationLoader2.t("HMR_START_FAILED", this.localLanguage),
|
|
990
|
-
message: error.message,
|
|
991
|
-
errorType: "HMR Error",
|
|
992
|
-
stackTrace: error.stack
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Handles file change events with debouncing.
|
|
998
|
-
*
|
|
999
|
-
* @method handleFileChange
|
|
1000
|
-
* @private
|
|
1001
|
-
*
|
|
1002
|
-
* @param {string} filePath - Path of the changed file
|
|
1003
|
-
* @param {string} [action="modified"] - Type of file change (modified/added/deleted)
|
|
1004
|
-
*
|
|
1005
|
-
* @returns {void}
|
|
1006
|
-
*
|
|
1007
|
-
* @remarks
|
|
1008
|
-
* Uses debouncing to prevent multiple rapid reloads.
|
|
1009
|
-
* Debounce time configurable via HMR_DEBOUNCE_MS environment variable.
|
|
1010
|
-
*/
|
|
1011
|
-
handleFileChange(filePath, action = "modified") {
|
|
1012
|
-
const debounceMs = this.getEnvironment.hmrDebounceMs || 500;
|
|
1013
|
-
if (this.hmrDebounceTimeout) {
|
|
1014
|
-
clearTimeout(this.hmrDebounceTimeout);
|
|
1015
|
-
}
|
|
1016
|
-
this.hmrDebounceTimeout = setTimeout(async () => {
|
|
1017
|
-
await this.triggerHotReload(filePath, action);
|
|
1018
|
-
}, debounceMs);
|
|
1019
|
-
SLogger(this.localLanguage).logger.info({
|
|
1020
|
-
title: TranslationLoader2.t("FILE_CHANGE_DETECTED", this.localLanguage),
|
|
1021
|
-
message: `File ${action}: ${filePath}`
|
|
1022
486
|
});
|
|
1023
487
|
}
|
|
1024
488
|
/**
|
|
1025
|
-
* Triggers a hot reload operation.
|
|
1026
489
|
*
|
|
1027
|
-
* @method triggerHotReload
|
|
1028
490
|
* @private
|
|
1029
|
-
*
|
|
1030
|
-
* @param {string} filePath - Path of the changed file
|
|
1031
|
-
* @param {string} action - Type of file change
|
|
1032
|
-
*
|
|
1033
|
-
* @returns {Promise<void>}
|
|
1034
|
-
*
|
|
1035
|
-
* @remarks
|
|
1036
|
-
* - Checks if reload is already in progress
|
|
1037
|
-
* - Validates restart limits
|
|
1038
|
-
* - Performs appropriate reload actions based on file type
|
|
1039
|
-
* - Emits hotReload event
|
|
1040
|
-
*/
|
|
1041
|
-
async triggerHotReload(filePath, action) {
|
|
1042
|
-
if (this.hmrRestartPending) {
|
|
1043
|
-
return;
|
|
1044
|
-
}
|
|
1045
|
-
if (!this.canProceedWithHMRRestart()) {
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
this.hmrRestartPending = true;
|
|
1049
|
-
this.hmrRestartCount++;
|
|
1050
|
-
this.lastHmrRestartTime = Date.now();
|
|
1051
|
-
try {
|
|
1052
|
-
loaderTranslationFile(this.localLanguage);
|
|
1053
|
-
SLogger(this.localLanguage).logger.info({
|
|
1054
|
-
title: TranslationLoader2.t("HOT_RELOAD_STARTING", this.localLanguage),
|
|
1055
|
-
message: TranslationLoader2.t("RELOADING_APPLICATION", this.localLanguage, {
|
|
1056
|
-
file: filePath,
|
|
1057
|
-
action
|
|
1058
|
-
})
|
|
1059
|
-
});
|
|
1060
|
-
if (this.errorEmitter) {
|
|
1061
|
-
this.errorEmitter.emit("hotReload", {
|
|
1062
|
-
file: filePath,
|
|
1063
|
-
action,
|
|
1064
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1065
|
-
restartCount: this.hmrRestartCount
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
|
-
await this.performHotReloadActions(filePath);
|
|
1069
|
-
SLogger(this.localLanguage).logger.success({
|
|
1070
|
-
title: TranslationLoader2.t("HOT_RELOAD_COMPLETE", this.localLanguage),
|
|
1071
|
-
message: TranslationLoader2.t("APPLICATION_RELOADED", this.localLanguage, {
|
|
1072
|
-
file: filePath,
|
|
1073
|
-
restartCount: this.hmrRestartCount,
|
|
1074
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1075
|
-
})
|
|
1076
|
-
});
|
|
1077
|
-
} catch (error) {
|
|
1078
|
-
SLogger(this.localLanguage).logger.error({
|
|
1079
|
-
title: TranslationLoader2.t("HOT_RELOAD_FAILED", this.localLanguage),
|
|
1080
|
-
message: error.message,
|
|
1081
|
-
errorType: "HotReloadError",
|
|
1082
|
-
stackTrace: error.stack,
|
|
1083
|
-
httpCodeValue: HttpStatusCode3.INTERNAL_SERVER_ERROR
|
|
1084
|
-
});
|
|
1085
|
-
} finally {
|
|
1086
|
-
this.hmrRestartPending = false;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
/**
|
|
1090
|
-
* Performs appropriate hot reload actions based on file type.
|
|
1091
|
-
*
|
|
1092
|
-
* @method performHotReloadActions
|
|
1093
|
-
* @private
|
|
1094
|
-
*
|
|
1095
|
-
* @param {string} filePath - Path of the changed file
|
|
1096
|
-
*
|
|
1097
|
-
* @returns {Promise<void>}
|
|
1098
|
-
*
|
|
1099
|
-
* @remarks
|
|
1100
|
-
* Different actions for different file types:
|
|
1101
|
-
* - .json/.env: Reload translations
|
|
1102
|
-
* - routes/controller files: Reload routes
|
|
1103
|
-
* - config/.env files: Reload dependencies
|
|
1104
491
|
*/
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
loaderTranslationFile(this.localLanguage);
|
|
1108
|
-
}
|
|
1109
|
-
if (filePath.includes("routes") || filePath.includes("controller")) {
|
|
1110
|
-
await this.reloadRoutes();
|
|
1111
|
-
}
|
|
1112
|
-
if (filePath.includes("config") || filePath.includes(".env")) {
|
|
1113
|
-
await this.reloadDependencies();
|
|
1114
|
-
}
|
|
492
|
+
stackTraceErrorHandling() {
|
|
493
|
+
return eventProcessHandler(this.localLanguage);
|
|
1115
494
|
}
|
|
1116
495
|
/**
|
|
1117
|
-
* Reloads routes dynamically.
|
|
1118
496
|
*
|
|
1119
|
-
* @method reloadRoutes
|
|
1120
497
|
* @private
|
|
1121
|
-
*
|
|
1122
|
-
* @returns {Promise<void>}
|
|
1123
|
-
*
|
|
1124
|
-
* @throws {Error} If route reloading fails
|
|
1125
|
-
*
|
|
1126
|
-
* @remarks
|
|
1127
|
-
* This method should be implemented based on your architecture.
|
|
1128
|
-
* It should reload route modules from the filesystem.
|
|
1129
498
|
*/
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
} catch (error) {
|
|
1137
|
-
throw new Error(`Route reload failed: ${error.message}`);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
/**
|
|
1141
|
-
* Reloads dependencies dynamically.
|
|
1142
|
-
*
|
|
1143
|
-
* @method reloadDependencies
|
|
1144
|
-
* @private
|
|
1145
|
-
*
|
|
1146
|
-
* @returns {Promise<void>}
|
|
1147
|
-
*
|
|
1148
|
-
* @throws {Error} If dependency reloading fails
|
|
1149
|
-
*/
|
|
1150
|
-
async reloadDependencies() {
|
|
1151
|
-
try {
|
|
1152
|
-
if (this.currentDependencies.length > 0) {
|
|
1153
|
-
new SContainer2(this.localLanguage, this.currentDependencies);
|
|
1154
|
-
SLogger(this.localLanguage).logger.info({
|
|
1155
|
-
title: TranslationLoader2.t("DEPENDENCIES_RELOADED", this.localLanguage),
|
|
1156
|
-
message: "Dependencies reloaded"
|
|
1157
|
-
});
|
|
1158
|
-
}
|
|
1159
|
-
} catch (error) {
|
|
1160
|
-
throw new Error(`Dependency reload failed: ${error.message}`);
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
/**
|
|
1164
|
-
* Checks if HMR restart can proceed based on configuration limits.
|
|
1165
|
-
*
|
|
1166
|
-
* @method canProceedWithHMRRestart
|
|
1167
|
-
* @private
|
|
1168
|
-
*
|
|
1169
|
-
* @returns {boolean} True if restart can proceed, false otherwise
|
|
1170
|
-
*
|
|
1171
|
-
* @remarks
|
|
1172
|
-
* Checks:
|
|
1173
|
-
* - Auto-restart enabled/disabled
|
|
1174
|
-
* - Maximum restarts per minute limit
|
|
1175
|
-
*/
|
|
1176
|
-
canProceedWithHMRRestart() {
|
|
1177
|
-
const hmrConfig = this.getEnvironment;
|
|
1178
|
-
if (!hmrConfig.hmrAutoRestarts) {
|
|
1179
|
-
SLogger(this.localLanguage).logger.warn({
|
|
1180
|
-
title: TranslationLoader2.t("HMR_AUTO_RESTART_DISABLED", this.localLanguage),
|
|
1181
|
-
message: "HMR auto-restart disabled"
|
|
1182
|
-
});
|
|
1183
|
-
return false;
|
|
1184
|
-
}
|
|
1185
|
-
const maxRestarts = hmrConfig.hmrMaxRestarts || 5;
|
|
1186
|
-
const now = Date.now();
|
|
1187
|
-
const oneMinuteAgo = now - 6e4;
|
|
1188
|
-
if (this.lastHmrRestartTime < oneMinuteAgo) {
|
|
1189
|
-
this.hmrRestartCount = 0;
|
|
1190
|
-
}
|
|
1191
|
-
if (this.hmrRestartCount >= maxRestarts) {
|
|
1192
|
-
const nextReset = Math.ceil((this.lastHmrRestartTime + 6e4 - now) / 1e3);
|
|
1193
|
-
SLogger(this.localLanguage).logger.error({
|
|
1194
|
-
title: TranslationLoader2.t("HMR_RESTART_LIMIT_EXCEEDED", this.localLanguage),
|
|
1195
|
-
message: TranslationLoader2.t("HMR_RESTART_LIMIT_MESSAGE", this.localLanguage, {
|
|
1196
|
-
max: maxRestarts,
|
|
1197
|
-
nextReset
|
|
1198
|
-
})
|
|
1199
|
-
});
|
|
1200
|
-
return false;
|
|
1201
|
-
}
|
|
1202
|
-
return true;
|
|
1203
|
-
}
|
|
1204
|
-
/**
|
|
1205
|
-
* Called when the HMR watcher is ready.
|
|
1206
|
-
*
|
|
1207
|
-
* @method onHMRWatcherReady
|
|
1208
|
-
* @private
|
|
1209
|
-
*
|
|
1210
|
-
* @param {string[]} watchPatterns - Patterns being watched
|
|
1211
|
-
* @param {string[]} ignorePatterns - Patterns being ignored
|
|
1212
|
-
*
|
|
1213
|
-
* @returns {void}
|
|
1214
|
-
*/
|
|
1215
|
-
onHMRWatcherReady(watchPatterns, ignorePatterns) {
|
|
1216
|
-
SLogger(this.localLanguage).logger.info({
|
|
1217
|
-
title: TranslationLoader2.t("HMR_WATCHER_READY", this.localLanguage),
|
|
1218
|
-
message: TranslationLoader2.t("HMR_WATCHING_DETAILS", this.localLanguage, {
|
|
1219
|
-
watchCount: watchPatterns,
|
|
1220
|
-
ignoreCount: ignorePatterns
|
|
1221
|
-
})
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
/**
|
|
1225
|
-
* Handles HMR watcher errors.
|
|
1226
|
-
*
|
|
1227
|
-
* @method onHMRWatcherError
|
|
1228
|
-
* @private
|
|
1229
|
-
*
|
|
1230
|
-
* @param {Error} error - The watcher error
|
|
1231
|
-
*
|
|
1232
|
-
* @returns {void}
|
|
1233
|
-
*/
|
|
1234
|
-
onHMRWatcherError(error) {
|
|
1235
|
-
SLogger(this.localLanguage).logger.error({
|
|
1236
|
-
title: TranslationLoader2.t("HMR_WATCHER_ERROR", this.localLanguage),
|
|
1237
|
-
message: error.message,
|
|
1238
|
-
errorType: "FileWatcherError",
|
|
1239
|
-
stackTrace: error.stack
|
|
1240
|
-
});
|
|
1241
|
-
}
|
|
1242
|
-
/**
|
|
1243
|
-
* Stops the HMR system.
|
|
1244
|
-
*
|
|
1245
|
-
* @method stopHMR
|
|
1246
|
-
* @private
|
|
1247
|
-
*
|
|
1248
|
-
* @returns {void}
|
|
1249
|
-
*/
|
|
1250
|
-
stopHMR() {
|
|
1251
|
-
if (this.fileWatcher) {
|
|
1252
|
-
this.fileWatcher.close();
|
|
1253
|
-
this.fileWatcher = null;
|
|
1254
|
-
}
|
|
1255
|
-
if (this.hmrDebounceTimeout) {
|
|
1256
|
-
clearTimeout(this.hmrDebounceTimeout);
|
|
1257
|
-
this.hmrDebounceTimeout = null;
|
|
1258
|
-
}
|
|
1259
|
-
SLogger(this.localLanguage).logger.info({
|
|
1260
|
-
title: TranslationLoader2.t("HMR_STOPPED", this.localLanguage),
|
|
1261
|
-
message: TranslationLoader2.t("HMR_MONITORING_STOPPED", this.localLanguage)
|
|
1262
|
-
});
|
|
1263
|
-
}
|
|
1264
|
-
/**
|
|
1265
|
-
* Stops the server and HMR system cleanly.
|
|
1266
|
-
*
|
|
1267
|
-
* @method onStopServer
|
|
1268
|
-
* @public
|
|
1269
|
-
*
|
|
1270
|
-
* @returns {void}
|
|
1271
|
-
*/
|
|
1272
|
-
onStopServer() {
|
|
1273
|
-
this.stopHMR();
|
|
1274
|
-
if (this.server) {
|
|
1275
|
-
this.server.close(() => {
|
|
1276
|
-
SLogger(this.localLanguage).logger.info({
|
|
1277
|
-
title: TranslationLoader2.t("SERVER_STOPPED", this.localLanguage),
|
|
1278
|
-
message: "Server stopped cleanly"
|
|
1279
|
-
});
|
|
1280
|
-
});
|
|
1281
|
-
this.serverStatus = "STOPPED";
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
/**
|
|
1285
|
-
* Gets the current server state information.
|
|
1286
|
-
*
|
|
1287
|
-
* @method getServerState
|
|
1288
|
-
* @public
|
|
1289
|
-
*
|
|
1290
|
-
* @returns {IServerStateInfo} Server state information object
|
|
1291
|
-
*
|
|
1292
|
-
* @remarks
|
|
1293
|
-
* Includes:
|
|
1294
|
-
* - Status, host, port
|
|
1295
|
-
* - Route and dependency counts
|
|
1296
|
-
* - Uptime and memory usage
|
|
1297
|
-
* - HMR configuration and statistics
|
|
1298
|
-
*/
|
|
1299
|
-
getServerState() {
|
|
1300
|
-
const now = /* @__PURE__ */ new Date();
|
|
1301
|
-
const uptime = this.serverStartTime ? now.getTime() - this.serverStartTime.getTime() : 0;
|
|
1302
|
-
return {
|
|
1303
|
-
status: this.serverStatus,
|
|
1304
|
-
isRunning: this.server !== void 0 && this.serverStatus === "READY",
|
|
1305
|
-
host: this.getEnvironment.appHost,
|
|
1306
|
-
port: Number(this.getEnvironment.appPort),
|
|
1307
|
-
language: this.localLanguage,
|
|
1308
|
-
routesCount: this.currentRoutes.length,
|
|
1309
|
-
dependenciesCount: this.currentDependencies.length,
|
|
1310
|
-
startTime: this.serverStartTime,
|
|
1311
|
-
currentTime: now,
|
|
1312
|
-
uptime,
|
|
1313
|
-
uptimeFormatted: this.formatUptime(uptime),
|
|
1314
|
-
memoryUsage: process4.memoryUsage(),
|
|
1315
|
-
pid: process4.pid,
|
|
1316
|
-
platform: process4.platform,
|
|
1317
|
-
nodeVersion: process4.version,
|
|
1318
|
-
cwd: process4.cwd(),
|
|
1319
|
-
hmrEnabled: this.getEnvironment.hmrEnabled,
|
|
1320
|
-
hmrWatchingFiles: this.getEnvironment.hmrWatchPatterns?.length || 0,
|
|
1321
|
-
hmrRestartCount: this.hmrRestartCount
|
|
1322
|
-
};
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Gets the current server status.
|
|
1326
|
-
*
|
|
1327
|
-
* @method getServerStatus
|
|
1328
|
-
* @public
|
|
1329
|
-
*
|
|
1330
|
-
* @returns {TServerStatus} Current server status
|
|
1331
|
-
*/
|
|
1332
|
-
getServerStatus() {
|
|
1333
|
-
return this.serverStatus;
|
|
1334
|
-
}
|
|
1335
|
-
/**
|
|
1336
|
-
* Gets detailed server statistics.
|
|
1337
|
-
*
|
|
1338
|
-
* @method getServerStats
|
|
1339
|
-
* @public
|
|
1340
|
-
*
|
|
1341
|
-
* @returns {IServerStats} Server statistics object
|
|
1342
|
-
*
|
|
1343
|
-
* @remarks
|
|
1344
|
-
* Includes:
|
|
1345
|
-
* - Performance metrics (CPU, memory)
|
|
1346
|
-
* - Uptime information
|
|
1347
|
-
* - HMR statistics
|
|
1348
|
-
*/
|
|
1349
|
-
getServerStats() {
|
|
1350
|
-
const uptime = this.serverStartTime ? Date.now() - this.serverStartTime.getTime() : 0;
|
|
1351
|
-
const memory = process4.memoryUsage();
|
|
1352
|
-
return {
|
|
1353
|
-
status: this.serverStatus,
|
|
1354
|
-
uptime: this.formatUptime(uptime),
|
|
1355
|
-
memory: {
|
|
1356
|
-
rss: this.formatBytes(memory.rss),
|
|
1357
|
-
heapTotal: this.formatBytes(memory.heapTotal),
|
|
1358
|
-
heapUsed: this.formatBytes(memory.heapUsed),
|
|
1359
|
-
external: this.formatBytes(memory.external)
|
|
1360
|
-
},
|
|
1361
|
-
performance: {
|
|
1362
|
-
cpuUsage: process4.cpuUsage(),
|
|
1363
|
-
resourceUsage: process4.resourceUsage?.()
|
|
1364
|
-
},
|
|
1365
|
-
hmrStats: {
|
|
1366
|
-
enabled: this.getEnvironment.hmrEnabled,
|
|
1367
|
-
restartCount: this.hmrRestartCount,
|
|
1368
|
-
lastRestartTime: this.lastHmrRestartTime,
|
|
1369
|
-
watchingFiles: this.getEnvironment.hmrWatchPatterns?.length || 0
|
|
1370
|
-
}
|
|
1371
|
-
};
|
|
1372
|
-
}
|
|
1373
|
-
/**
|
|
1374
|
-
* Formats milliseconds into a human-readable uptime string.
|
|
1375
|
-
*
|
|
1376
|
-
* @method formatUptime
|
|
1377
|
-
* @private
|
|
1378
|
-
*
|
|
1379
|
-
* @param {number} ms - Milliseconds to format
|
|
1380
|
-
*
|
|
1381
|
-
* @returns {string} Formatted uptime string
|
|
1382
|
-
*
|
|
1383
|
-
* @example
|
|
1384
|
-
* formatUptime(3661000) // returns "1h 1m 1s"
|
|
1385
|
-
*/
|
|
1386
|
-
formatUptime(ms) {
|
|
1387
|
-
const seconds = Math.floor(ms / 1e3);
|
|
1388
|
-
const minutes = Math.floor(seconds / 60);
|
|
1389
|
-
const hours = Math.floor(minutes / 60);
|
|
1390
|
-
const days = Math.floor(hours / 24);
|
|
1391
|
-
if (days > 0) {
|
|
1392
|
-
return `${days}d ${hours % 24}h ${minutes % 60}m`;
|
|
1393
|
-
} else if (hours > 0) {
|
|
1394
|
-
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
1395
|
-
} else if (minutes > 0) {
|
|
1396
|
-
return `${minutes}m ${seconds % 60}s`;
|
|
1397
|
-
} else {
|
|
1398
|
-
return `${seconds}s`;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
/**
|
|
1402
|
-
* Formats bytes into a human-readable size string.
|
|
1403
|
-
*
|
|
1404
|
-
* @method formatBytes
|
|
1405
|
-
* @private
|
|
1406
|
-
*
|
|
1407
|
-
* @param {number} bytes - Bytes to format
|
|
1408
|
-
*
|
|
1409
|
-
* @returns {string} Formatted size string
|
|
1410
|
-
*
|
|
1411
|
-
* @example
|
|
1412
|
-
* formatBytes(1048576) // returns "1.00 MB"
|
|
1413
|
-
*/
|
|
1414
|
-
formatBytes(bytes) {
|
|
1415
|
-
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
1416
|
-
let value = bytes;
|
|
1417
|
-
let unitIndex = 0;
|
|
1418
|
-
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
1419
|
-
value /= 1024;
|
|
1420
|
-
unitIndex++;
|
|
1421
|
-
}
|
|
1422
|
-
return `${value.toFixed(2)} ${units[unitIndex]}`;
|
|
1423
|
-
}
|
|
1424
|
-
/**
|
|
1425
|
-
* Checks if HMR is currently active.
|
|
1426
|
-
*
|
|
1427
|
-
* @method isHMRActive
|
|
1428
|
-
* @public
|
|
1429
|
-
*
|
|
1430
|
-
* @returns {boolean} True if HMR is enabled and watching files, false otherwise
|
|
1431
|
-
*/
|
|
1432
|
-
isHMRActive() {
|
|
1433
|
-
return this.getEnvironment.hmrEnabled && this.fileWatcher !== null;
|
|
1434
|
-
}
|
|
1435
|
-
/**
|
|
1436
|
-
* Gets detailed HMR information and status.
|
|
1437
|
-
*
|
|
1438
|
-
* @method getHMRInfo
|
|
1439
|
-
* @public
|
|
1440
|
-
*
|
|
1441
|
-
* @returns {any} HMR information object
|
|
1442
|
-
*
|
|
1443
|
-
* @remarks
|
|
1444
|
-
* Includes:
|
|
1445
|
-
* - Configuration settings from .env
|
|
1446
|
-
* - Current restart count
|
|
1447
|
-
* - Watcher status
|
|
1448
|
-
*/
|
|
1449
|
-
getHMRInfo() {
|
|
1450
|
-
return {
|
|
1451
|
-
enabled: this.getEnvironment.hmrEnabled,
|
|
1452
|
-
watchPatterns: this.getEnvironment.hmrWatchPatterns,
|
|
1453
|
-
ignorePatterns: this.getEnvironment.hmrIgnorePatterns,
|
|
1454
|
-
debounceMs: this.getEnvironment.hmrDebounceMs,
|
|
1455
|
-
maxRestarts: this.getEnvironment.hmrMaxRestarts,
|
|
1456
|
-
autoRestart: this.getEnvironment.hmrAutoRestarts,
|
|
1457
|
-
currentRestartCount: this.hmrRestartCount,
|
|
1458
|
-
lastRestartTime: this.lastHmrRestartTime,
|
|
1459
|
-
isWatching: this.fileWatcher !== null,
|
|
1460
|
-
isRestartPending: this.hmrRestartPending
|
|
1461
|
-
};
|
|
499
|
+
infoWebApp() {
|
|
500
|
+
this.loadTranslationFiles();
|
|
501
|
+
this.serverUtility.infoServer(
|
|
502
|
+
this.getEnvironmentValue.appHost,
|
|
503
|
+
Number(this.getEnvironmentValue.appPort)
|
|
504
|
+
);
|
|
1462
505
|
}
|
|
1463
506
|
};
|
|
1464
507
|
export {
|