@manojkmfsi/monodog 1.0.25 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
 
2
- > @manojkmfsi/monodog@1.0.25 build /home/runner/work/monodog/monodog/packages/monoapp
2
+ > @manojkmfsi/monodog@1.1.0 build /home/runner/work/monodog/monodog/packages/monoapp
3
3
  > rm -rf dist && tsc
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @manojkmfsi/monoapp
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added Swagger doc, updated req type for resfresh
8
+
3
9
  ## 1.0.25
4
10
 
5
11
  ### Patch Changes
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.swaggerOptions = exports.swaggerDefinition = void 0;
4
+ /**
5
+ * Swagger API Documentation Configuration
6
+ * Defines OpenAPI specification for MonoDog API
7
+ */
8
+ const config_loader_1 = require("../config-loader");
9
+ exports.swaggerDefinition = {
10
+ openapi: '3.0.0',
11
+ info: {
12
+ title: 'MonoDog API',
13
+ version: '1.0.0',
14
+ description: 'Monorepo Analytics and Health Dashboard API',
15
+ contact: {
16
+ name: 'MonoDog Team',
17
+ url: 'https://github.com/mindfiredigital/monodog',
18
+ },
19
+ license: {
20
+ name: 'MIT',
21
+ url: 'https://opensource.org/licenses/MIT',
22
+ },
23
+ },
24
+ servers: [
25
+ {
26
+ url: `http://${config_loader_1.appConfig.server.host}:${config_loader_1.appConfig.server.port}/api`,
27
+ description: 'Development server',
28
+ },
29
+ ],
30
+ paths: {
31
+ '/packages': {
32
+ get: {
33
+ tags: ['Packages'],
34
+ summary: 'Get all packages',
35
+ operationId: 'getPackages',
36
+ responses: {
37
+ '200': {
38
+ description: 'List of packages',
39
+ content: {
40
+ 'application/json': {
41
+ schema: { type: 'array', items: { $ref: '#/components/schemas/Package' } },
42
+ },
43
+ },
44
+ },
45
+ '500': { description: 'Internal server error' },
46
+ },
47
+ },
48
+ },
49
+ '/packages/{name}': {
50
+ get: {
51
+ tags: ['Packages'],
52
+ summary: 'Get package by name',
53
+ operationId: 'getPackageByName',
54
+ parameters: [{ name: 'name', in: 'path', required: true, schema: { type: 'string' } }],
55
+ responses: {
56
+ '200': {
57
+ description: 'Package details',
58
+ content: {
59
+ 'application/json': {
60
+ schema: { $ref: '#/components/schemas/Package' },
61
+ },
62
+ },
63
+ },
64
+ '404': { description: 'Package not found' },
65
+ },
66
+ },
67
+ },
68
+ '/packages/refresh': {
69
+ post: {
70
+ tags: ['Packages'],
71
+ summary: 'Refresh packages',
72
+ operationId: 'refreshPackages',
73
+ responses: {
74
+ '200': { description: 'Packages refreshed successfully' },
75
+ },
76
+ },
77
+ },
78
+ '/packages/update-config': {
79
+ put: {
80
+ tags: ['Packages'],
81
+ summary: 'Update package configuration',
82
+ operationId: 'updatePackageConfig',
83
+ requestBody: {
84
+ required: true,
85
+ content: {
86
+ 'application/json': {
87
+ schema: { $ref: '#/components/schemas/Package' },
88
+ },
89
+ },
90
+ },
91
+ responses: {
92
+ '200': { description: 'Package configuration updated successfully' },
93
+ '400': { description: 'Invalid request' },
94
+ '404': { description: 'Package not found' },
95
+ },
96
+ },
97
+ },
98
+ '/health/packages': {
99
+ get: {
100
+ tags: ['Health'],
101
+ summary: 'Get packages health status',
102
+ operationId: 'getPackagesHealth',
103
+ responses: {
104
+ '200': {
105
+ description: 'Health status of all packages',
106
+ content: {
107
+ 'application/json': {
108
+ schema: { type: 'array', items: { $ref: '#/components/schemas/PackageHealth' } },
109
+ },
110
+ },
111
+ },
112
+ },
113
+ },
114
+ },
115
+ '/health/refresh': {
116
+ post: {
117
+ tags: ['Health'],
118
+ summary: 'Refresh health status',
119
+ operationId: 'refreshHealth',
120
+ responses: {
121
+ '200': { description: 'Health status refreshed successfully' },
122
+ },
123
+ },
124
+ },
125
+ '/commits/{packagePath}': {
126
+ get: {
127
+ tags: ['Commits'],
128
+ summary: 'Get commits for a package',
129
+ operationId: 'getCommits',
130
+ parameters: [{ name: 'packagePath', in: 'path', required: true, schema: { type: 'string' } }],
131
+ responses: {
132
+ '200': {
133
+ description: 'List of commits',
134
+ content: {
135
+ 'application/json': {
136
+ schema: { type: 'array', items: { $ref: '#/components/schemas/Commit' } },
137
+ },
138
+ },
139
+ },
140
+ },
141
+ },
142
+ },
143
+ '/config/files': {
144
+ get: {
145
+ tags: ['Configuration'],
146
+ summary: 'Get configuration files',
147
+ operationId: 'getConfigFiles',
148
+ responses: {
149
+ '200': {
150
+ description: 'List of configuration files',
151
+ content: {
152
+ 'application/json': {
153
+ schema: { type: 'array', items: { $ref: '#/components/schemas/ConfigFile' } },
154
+ },
155
+ },
156
+ },
157
+ },
158
+ },
159
+ },
160
+ '/config/files/{id}': {
161
+ put: {
162
+ tags: ['Configuration'],
163
+ summary: 'Update configuration file',
164
+ operationId: 'updateConfigFile',
165
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
166
+ requestBody: {
167
+ required: true,
168
+ content: {
169
+ 'application/json': {
170
+ schema: { $ref: '#/components/schemas/ConfigFile' },
171
+ },
172
+ },
173
+ },
174
+ responses: {
175
+ '200': { description: 'Configuration file updated successfully' },
176
+ '400': { description: 'Invalid request' },
177
+ '404': { description: 'Configuration file not found' },
178
+ },
179
+ },
180
+ },
181
+ },
182
+ tags: [
183
+ {
184
+ name: 'Packages',
185
+ description: 'Package management and analysis endpoints',
186
+ },
187
+ {
188
+ name: 'Health',
189
+ description: 'Health monitoring and status endpoints',
190
+ },
191
+ {
192
+ name: 'Commits',
193
+ description: 'Git commit history and analysis endpoints',
194
+ },
195
+ {
196
+ name: 'Configuration',
197
+ description: 'Configuration file management endpoints',
198
+ },
199
+ ],
200
+ components: {
201
+ schemas: {
202
+ Package: {
203
+ type: 'object',
204
+ properties: {
205
+ name: {
206
+ type: 'string',
207
+ description: 'Package name',
208
+ },
209
+ path: {
210
+ type: 'string',
211
+ description: 'Package path in monorepo',
212
+ },
213
+ version: {
214
+ type: 'string',
215
+ description: 'Package version',
216
+ },
217
+ size: {
218
+ type: 'number',
219
+ description: 'Package size in bytes',
220
+ },
221
+ dependencies: {
222
+ type: 'array',
223
+ items: {
224
+ type: 'string',
225
+ },
226
+ description: 'List of package dependencies',
227
+ },
228
+ },
229
+ },
230
+ PackageHealth: {
231
+ type: 'object',
232
+ properties: {
233
+ packageName: {
234
+ type: 'string',
235
+ description: 'Name of the package',
236
+ },
237
+ healthScore: {
238
+ type: 'number',
239
+ description: 'Health score (0-100)',
240
+ minimum: 0,
241
+ maximum: 100,
242
+ },
243
+ lintStatus: {
244
+ type: 'string',
245
+ enum: ['pass', 'warning', 'fail'],
246
+ description: 'Linting status',
247
+ },
248
+ buildStatus: {
249
+ type: 'string',
250
+ enum: ['success', 'failed', 'pending'],
251
+ description: 'Build status',
252
+ },
253
+ securityStatus: {
254
+ type: 'string',
255
+ enum: ['secure', 'warning', 'vulnerable'],
256
+ description: 'Security status',
257
+ },
258
+ testCoverage: {
259
+ type: 'number',
260
+ description: 'Test coverage percentage',
261
+ },
262
+ },
263
+ },
264
+ Commit: {
265
+ type: 'object',
266
+ properties: {
267
+ hash: {
268
+ type: 'string',
269
+ description: 'Commit hash',
270
+ },
271
+ author: {
272
+ type: 'string',
273
+ description: 'Commit author',
274
+ },
275
+ message: {
276
+ type: 'string',
277
+ description: 'Commit message',
278
+ },
279
+ date: {
280
+ type: 'string',
281
+ format: 'date-time',
282
+ description: 'Commit date',
283
+ },
284
+ filesChanged: {
285
+ type: 'number',
286
+ description: 'Number of files changed',
287
+ },
288
+ },
289
+ },
290
+ ConfigFile: {
291
+ type: 'object',
292
+ properties: {
293
+ id: {
294
+ type: 'string',
295
+ description: 'Configuration file ID',
296
+ },
297
+ name: {
298
+ type: 'string',
299
+ description: 'Configuration file name',
300
+ },
301
+ path: {
302
+ type: 'string',
303
+ description: 'Configuration file path',
304
+ },
305
+ content: {
306
+ type: 'string',
307
+ description: 'Configuration file content',
308
+ },
309
+ },
310
+ },
311
+ Error: {
312
+ type: 'object',
313
+ properties: {
314
+ error: {
315
+ type: 'string',
316
+ description: 'Error message',
317
+ },
318
+ message: {
319
+ type: 'string',
320
+ description: 'Detailed error message',
321
+ },
322
+ code: {
323
+ type: 'string',
324
+ description: 'Error code',
325
+ },
326
+ },
327
+ },
328
+ },
329
+ responses: {
330
+ UnauthorizedError: {
331
+ description: 'Unauthorized access',
332
+ },
333
+ NotFoundError: {
334
+ description: 'Resource not found',
335
+ },
336
+ InternalServerError: {
337
+ description: 'Internal server error',
338
+ },
339
+ },
340
+ },
341
+ };
342
+ exports.swaggerOptions = {
343
+ definition: exports.swaggerDefinition,
344
+ apis: [], // Using only definition, no JSDoc file scanning
345
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * Constants Index
4
+ * Centralized export of all application constants
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ // Port constants
22
+ __exportStar(require("./port"), exports);
23
+ // Security constants
24
+ __exportStar(require("./security"), exports);
25
+ // Middleware constants
26
+ __exportStar(require("./middleware"), exports);
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Middleware Constants
4
+ * Defines constants used across middleware modules
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.MESSAGE_SHUTDOWN_INSTRUCTION = exports.ERROR_SERVING_INDEX_HTML = exports.CONTENT_TYPE_JAVASCRIPT = exports.MESSAGE_DASHBOARD_CLOSED = exports.MESSAGE_DASHBOARD_GRACEFUL_SHUTDOWN = exports.MESSAGE_SERVER_CLOSED = exports.MESSAGE_GRACEFUL_SHUTDOWN = exports.SUCCESS_DASHBOARD_START = exports.SUCCESS_SERVER_START = exports.ERROR_INTERNAL_SERVER = exports.ERROR_PERMISSION_DENIED = exports.ERROR_PORT_IN_USE = exports.HTTP_STATUS_BAD_REQUEST = exports.HTTP_STATUS_NOT_FOUND = exports.HTTP_STATUS_INTERNAL_SERVER_ERROR = void 0;
8
+ /**
9
+ * HTTP status code for internal server error
10
+ */
11
+ exports.HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
12
+ /**
13
+ * HTTP status code for not found
14
+ */
15
+ exports.HTTP_STATUS_NOT_FOUND = 404;
16
+ /**
17
+ * HTTP status code for bad request
18
+ */
19
+ exports.HTTP_STATUS_BAD_REQUEST = 400;
20
+ /**
21
+ * Error message for port already in use
22
+ */
23
+ const ERROR_PORT_IN_USE = (port) => `Port ${port} is already in use. Please specify a different port.`;
24
+ exports.ERROR_PORT_IN_USE = ERROR_PORT_IN_USE;
25
+ /**
26
+ * Error message for permission denied
27
+ */
28
+ const ERROR_PERMISSION_DENIED = (port) => `Permission denied to listen on port ${port}. Use a port above 1024.`;
29
+ exports.ERROR_PERMISSION_DENIED = ERROR_PERMISSION_DENIED;
30
+ /**
31
+ * Error message for internal server error
32
+ */
33
+ exports.ERROR_INTERNAL_SERVER = 'Internal server error';
34
+ /**
35
+ * Success message for server start
36
+ */
37
+ const SUCCESS_SERVER_START = (host, port) => `Backend server listening on http://${host}:${port}`;
38
+ exports.SUCCESS_SERVER_START = SUCCESS_SERVER_START;
39
+ /**
40
+ * Success message for dashboard start
41
+ */
42
+ const SUCCESS_DASHBOARD_START = (host, port) => `Dashboard listening on http://${host}:${port}`;
43
+ exports.SUCCESS_DASHBOARD_START = SUCCESS_DASHBOARD_START;
44
+ /**
45
+ * Message for graceful shutdown
46
+ */
47
+ exports.MESSAGE_GRACEFUL_SHUTDOWN = 'SIGTERM signal received: closing HTTP server';
48
+ /**
49
+ * Message for server closed
50
+ */
51
+ exports.MESSAGE_SERVER_CLOSED = 'HTTP server closed';
52
+ /**
53
+ * Message for dashboard graceful shutdown
54
+ */
55
+ exports.MESSAGE_DASHBOARD_GRACEFUL_SHUTDOWN = 'SIGTERM signal received: closing dashboard server';
56
+ /**
57
+ * Message for dashboard closed
58
+ */
59
+ exports.MESSAGE_DASHBOARD_CLOSED = 'Dashboard server closed';
60
+ /**
61
+ * Content-Type header for JavaScript
62
+ */
63
+ exports.CONTENT_TYPE_JAVASCRIPT = 'application/javascript';
64
+ /**
65
+ * Error serving index.html message
66
+ */
67
+ exports.ERROR_SERVING_INDEX_HTML = 'Error serving index.html:';
68
+ /**
69
+ * Shutdown instruction message
70
+ */
71
+ exports.MESSAGE_SHUTDOWN_INSTRUCTION = 'Press Ctrl+C to quit.';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * Port Constants
4
+ * Defines valid port range and port-related configuration
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PORT_VALIDATION_ERROR_MESSAGE = exports.PORT_MAX = exports.PORT_MIN = void 0;
8
+ /**
9
+ * Minimum valid port number (above system reserved ports)
10
+ */
11
+ exports.PORT_MIN = 1024;
12
+ /**
13
+ * Maximum valid port number
14
+ */
15
+ exports.PORT_MAX = 65535;
16
+ /**
17
+ * Port validation error message
18
+ */
19
+ const PORT_VALIDATION_ERROR_MESSAGE = (min, max) => `Port must be between ${min} and ${max}`;
20
+ exports.PORT_VALIDATION_ERROR_MESSAGE = PORT_VALIDATION_ERROR_MESSAGE;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /**
3
+ * Security Constants
4
+ * Defines security-related configuration and constants
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PRAGMA_HEADER = exports.EXPIRES_HEADER = exports.STATIC_FILE_PATTERN = exports.CSP_DIRECTIVES = exports.HTTP_PROTOCOL = exports.WILDCARD_ADDRESS = exports.DEFAULT_LOCALHOST = exports.CACHE_CONTROL_STATIC = exports.CACHE_CONTROL_NO_CACHE = exports.BODY_PARSER_LIMIT = exports.CORS_ALLOWED_HEADERS = exports.CORS_API_METHODS = exports.RESPONSE_TIMEOUT = exports.REQUEST_TIMEOUT = void 0;
8
+ /**
9
+ * Request timeout duration in milliseconds (30 seconds)
10
+ */
11
+ exports.REQUEST_TIMEOUT = 30000;
12
+ /**
13
+ * Response timeout duration in milliseconds (30 seconds)
14
+ */
15
+ exports.RESPONSE_TIMEOUT = 30000;
16
+ /**
17
+ * CORS methods allowed for API
18
+ */
19
+ exports.CORS_API_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];
20
+ /**
21
+ * CORS headers allowed
22
+ */
23
+ exports.CORS_ALLOWED_HEADERS = ['Content-Type', 'Authorization'];
24
+ /**
25
+ * Body parser JSON size limit
26
+ */
27
+ exports.BODY_PARSER_LIMIT = '1mb';
28
+ /**
29
+ * Cache control header for no-cache responses
30
+ */
31
+ exports.CACHE_CONTROL_NO_CACHE = 'private, no-cache, no-store, must-revalidate';
32
+ /**
33
+ * Cache control header for static assets
34
+ */
35
+ exports.CACHE_CONTROL_STATIC = '1d';
36
+ /**
37
+ * Default localhost hostname
38
+ */
39
+ exports.DEFAULT_LOCALHOST = 'localhost';
40
+ /**
41
+ * Wildcard address for listening on all interfaces
42
+ */
43
+ exports.WILDCARD_ADDRESS = '0.0.0.0';
44
+ /**
45
+ * HTTP protocol prefix
46
+ */
47
+ exports.HTTP_PROTOCOL = 'http://';
48
+ /**
49
+ * CSP directives for Helmet
50
+ */
51
+ exports.CSP_DIRECTIVES = {
52
+ defaultSrc: ["'self'"],
53
+ scriptSrc: ["'self'"],
54
+ imgSrc: ["'self'", 'data:', 'https:'],
55
+ };
56
+ /**
57
+ * Static file extensions pattern
58
+ */
59
+ exports.STATIC_FILE_PATTERN = /(.ico|.js|.css|.jpg|.png|.map|.woff|.woff2|.ttf)$/i;
60
+ /**
61
+ * Expires header for no-cache responses
62
+ */
63
+ exports.EXPIRES_HEADER = '-1';
64
+ /**
65
+ * Pragma header for no-cache responses
66
+ */
67
+ exports.PRAGMA_HEADER = 'no-cache';
@@ -13,16 +13,14 @@ const logger_1 = require("./logger");
13
13
  const config_loader_1 = require("../config-loader");
14
14
  const error_handler_1 = require("./error-handler");
15
15
  const security_1 = require("./security");
16
- // Security constants
17
- const PORT_MIN = 1024;
18
- const PORT_MAX = 65535;
16
+ const constants_1 = require("../constants");
19
17
  /**
20
18
  * Validate port number
21
19
  */
22
20
  function validatePort(port) {
23
21
  const portNum = typeof port === 'string' ? parseInt(port, 10) : port;
24
- if (isNaN(portNum) || portNum < PORT_MIN || portNum > PORT_MAX) {
25
- throw new Error(`Port must be between ${PORT_MIN} and ${PORT_MAX}`);
22
+ if (isNaN(portNum) || portNum < constants_1.PORT_MIN || portNum > constants_1.PORT_MAX) {
23
+ throw new Error((0, constants_1.PORT_VALIDATION_ERROR_MESSAGE)(constants_1.PORT_MIN, constants_1.PORT_MAX));
26
24
  }
27
25
  return portNum;
28
26
  }
@@ -42,27 +40,26 @@ function createDashboardApp() {
42
40
  app.use((0, security_1.createDashboardCorsMiddleware)());
43
41
  // Environment config endpoint
44
42
  app.get('/env-config.js', (_req, res) => {
45
- res.setHeader('Content-Type', 'application/javascript');
46
- res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate');
43
+ res.setHeader('Content-Type', constants_1.CONTENT_TYPE_JAVASCRIPT);
44
+ res.setHeader('Cache-Control', constants_1.CACHE_CONTROL_NO_CACHE);
47
45
  res.send(`window.ENV = { API_URL: "${apiUrl}" };`);
48
46
  });
49
47
  // Request logging
50
48
  app.use(logger_1.httpLogger);
51
- // app.use(requestLogger);
52
49
  // SPA routing: serve index.html for non-static routes
53
50
  app.use((_req, _res, next) => {
54
- if (/(.ico|.js|.css|.jpg|.png|.map|.woff|.woff2|.ttf)$/i.test(_req.path)) {
51
+ if (constants_1.STATIC_FILE_PATTERN.test(_req.path)) {
55
52
  next();
56
53
  }
57
54
  else {
58
- _res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
59
- _res.header('Expires', '-1');
60
- _res.header('Pragma', 'no-cache');
55
+ _res.header('Cache-Control', constants_1.CACHE_CONTROL_NO_CACHE);
56
+ _res.header('Expires', constants_1.EXPIRES_HEADER);
57
+ _res.header('Pragma', constants_1.PRAGMA_HEADER);
61
58
  _res.sendFile('index.html', {
62
59
  root: path_1.default.resolve(__dirname, '..', '..', 'monodog-dashboard', 'dist'),
63
60
  }, (err) => {
64
61
  if (err) {
65
- logger_1.AppLogger.error('Error serving index.html:', err);
62
+ logger_1.AppLogger.error(constants_1.ERROR_SERVING_INDEX_HTML, err);
66
63
  _res.status(500).json({ error: 'Internal server error' });
67
64
  }
68
65
  });
@@ -90,16 +87,16 @@ function serveDashboard(rootPath) {
90
87
  const validatedPort = validatePort(port);
91
88
  const app = createDashboardApp();
92
89
  const server = app.listen(validatedPort, host, () => {
93
- console.log(`Dashboard listening on http://${host}:${validatedPort}`);
90
+ console.log((0, constants_1.SUCCESS_DASHBOARD_START)(host, validatedPort));
94
91
  console.log('Press Ctrl+C to quit.');
95
92
  });
96
93
  server.on('error', (err) => {
97
94
  if (err.code === 'EADDRINUSE') {
98
- logger_1.AppLogger.error(`Port ${validatedPort} is already in use.`, err);
95
+ logger_1.AppLogger.error((0, constants_1.ERROR_PORT_IN_USE)(validatedPort), err);
99
96
  process.exit(1);
100
97
  }
101
98
  else if (err.code === 'EACCES') {
102
- logger_1.AppLogger.error(`Permission denied to listen on port ${validatedPort}.`, err);
99
+ logger_1.AppLogger.error((0, constants_1.ERROR_PERMISSION_DENIED)(validatedPort), err);
103
100
  process.exit(1);
104
101
  }
105
102
  else {
@@ -109,9 +106,9 @@ function serveDashboard(rootPath) {
109
106
  });
110
107
  // Graceful shutdown
111
108
  process.on('SIGTERM', () => {
112
- logger_1.AppLogger.info('SIGTERM signal received: closing dashboard server');
109
+ logger_1.AppLogger.info(constants_1.MESSAGE_DASHBOARD_GRACEFUL_SHUTDOWN);
113
110
  server.close(() => {
114
- logger_1.AppLogger.info('Dashboard server closed');
111
+ logger_1.AppLogger.info(constants_1.MESSAGE_DASHBOARD_CLOSED);
115
112
  process.exit(0);
116
113
  });
117
114
  });