@manojkmfsi/monodog 1.0.24 → 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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +12 -0
- package/dist/config/swagger-config.js +345 -0
- package/dist/constants/index.js +26 -0
- package/dist/constants/middleware.js +71 -0
- package/dist/constants/port.js +20 -0
- package/dist/constants/security.js +67 -0
- package/dist/middleware/dashboard-startup.js +20 -21
- package/dist/middleware/error-handler.js +3 -10
- package/dist/middleware/index.js +4 -2
- package/dist/middleware/logger.js +63 -0
- package/dist/middleware/security.js +11 -10
- package/dist/middleware/server-startup.js +32 -25
- package/dist/middleware/swagger-middleware.js +54 -0
- package/dist/routes/health-routes.js +1 -1
- package/dist/routes/package-routes.js +1 -1
- package/dist/serve.js +15 -2
- package/dist/services/health-service.js +84 -64
- package/dist/services/package-service.js +23 -1
- package/monodog-dashboard/dist/assets/{index-746f6c13.js → index-45e19f29.js} +1 -1
- package/monodog-dashboard/dist/index.html +1 -1
- package/package.json +14 -4
- package/prisma/schema/commit.prisma +11 -0
- package/prisma/schema/dependency-info.prisma +12 -0
- package/prisma/schema/health-status.prisma +14 -0
- package/prisma/schema/package-health.prisma +15 -0
- package/prisma/schema/package.prisma +21 -0
- package/prisma/schema/schema.prisma +15 -0
- package/src/config/swagger-config.ts +344 -0
- package/src/constants/index.ts +13 -0
- package/src/constants/middleware.ts +83 -0
- package/src/constants/port.ts +20 -0
- package/src/constants/security.ts +78 -0
- package/src/middleware/dashboard-startup.ts +35 -24
- package/src/middleware/error-handler.ts +2 -15
- package/src/middleware/index.ts +3 -1
- package/src/middleware/logger.ts +58 -0
- package/src/middleware/security.ts +19 -10
- package/src/middleware/server-startup.ts +43 -30
- package/src/middleware/swagger-middleware.ts +57 -0
- package/src/routes/health-routes.ts +1 -1
- package/src/routes/package-routes.ts +1 -1
- package/src/serve.ts +19 -3
- package/src/services/health-service.ts +103 -79
- package/src/services/package-service.ts +27 -1
- package/src/types/swagger-jsdoc.d.ts +15 -0
- package/prisma/schema.prisma +0 -116
- /package/prisma/migrations/{20251219074511_create_unique_composite_key_for_commits → 20251219090102_composite_key_for_table_commits}/migration.sql +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>MonoDog Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-45e19f29.js"></script>
|
|
8
8
|
<link rel="stylesheet" href="/assets/index-504dc418.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body class="bg-gray-100 text-gray-900">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manojkmfsi/monodog",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "App for monodog monorepo",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"helmet": "^7.1.0",
|
|
15
15
|
"init": "^0.1.2",
|
|
16
16
|
"js-yaml": "^4.1.0",
|
|
17
|
-
"prisma": "^5.22.0"
|
|
17
|
+
"prisma": "^5.22.0",
|
|
18
|
+
"swagger-jsdoc": "^6.2.8",
|
|
19
|
+
"swagger-ui-express": "^5.0.1"
|
|
18
20
|
},
|
|
19
21
|
"devDependencies": {
|
|
20
22
|
"@types/body-parser": "^1.19.6",
|
|
@@ -22,25 +24,33 @@
|
|
|
22
24
|
"@types/express": "^4.17.25",
|
|
23
25
|
"@types/jest": "^29.5.14",
|
|
24
26
|
"@types/js-yaml": "^4.0.9",
|
|
27
|
+
"@types/morgan": "^1.9.10",
|
|
25
28
|
"@types/node": "^20.19.27",
|
|
29
|
+
"@types/swagger-ui-express": "^4.1.6",
|
|
26
30
|
"cross-env": "^10.1.0",
|
|
27
31
|
"jest": "^29.7.0",
|
|
28
32
|
"jest-environment-jsdom": "^30.2.0",
|
|
33
|
+
"morgan": "^1.10.1",
|
|
29
34
|
"ts-jest": "^29.4.6",
|
|
30
35
|
"ts-node": "^10.9.2",
|
|
31
36
|
"tsx": "^4.21.0",
|
|
32
37
|
"typescript": "^5.9.3"
|
|
33
38
|
},
|
|
39
|
+
"prisma": {
|
|
40
|
+
"schema": "./prisma/schema"
|
|
41
|
+
},
|
|
34
42
|
"scripts": {
|
|
35
|
-
"dev": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') tsx watch src/serve.
|
|
43
|
+
"dev": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') tsx watch src/serve.ts --dev --debug",
|
|
36
44
|
"serve": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') tsx dist/serve.js",
|
|
37
45
|
"build": "rm -rf dist && tsc",
|
|
38
|
-
"test:coverage": "jest --coverage",
|
|
46
|
+
"test:coverage": "jest --coverage --silent",
|
|
39
47
|
"prestart": "npm run build",
|
|
40
48
|
"clean": "rm -rf dist node_modules/.cache",
|
|
41
49
|
"lint": "eslint .",
|
|
42
50
|
"lint:fix": "eslint . --fix",
|
|
43
51
|
"db:url": "node dist/get-db-url.js",
|
|
52
|
+
"schema:format": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma format",
|
|
53
|
+
"schema:validate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma validate",
|
|
44
54
|
"generate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma generate",
|
|
45
55
|
"migrate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma migrate dev",
|
|
46
56
|
"migrate:reset": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma migrate reset --force"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
model DependencyInfo {
|
|
2
|
+
name String
|
|
3
|
+
packageName String
|
|
4
|
+
version String
|
|
5
|
+
type String @default("")
|
|
6
|
+
status String @default("")
|
|
7
|
+
latest String?
|
|
8
|
+
outdated Boolean @default(false)
|
|
9
|
+
package Package @relation(fields: [packageName], references: [name], onDelete: Cascade)
|
|
10
|
+
|
|
11
|
+
@@unique([name, packageName]) // Composite unique constraint
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
model HealthStatus {
|
|
2
|
+
id Int @id @default(autoincrement())
|
|
3
|
+
packageName String @unique
|
|
4
|
+
overallScore Float // Overall health score (0-100)
|
|
5
|
+
buildStatus String // e.g., "passing", "failing", "unknown"
|
|
6
|
+
testCoverage Float // Test coverage percentage (0-100)
|
|
7
|
+
lintStatus String // e.g., "passing", "warning", "failing"
|
|
8
|
+
security String // e.g., "secure", "vulnerabilities", "unknown"
|
|
9
|
+
dependencies String // e.g., "up-to-date", "outdated", "vulnerable"
|
|
10
|
+
createdAt DateTime @default(now())
|
|
11
|
+
updatedAt DateTime @updatedAt
|
|
12
|
+
|
|
13
|
+
@@map("health_status")
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
model PackageHealth {
|
|
2
|
+
id Int @id @default(autoincrement())
|
|
3
|
+
packageName String @unique
|
|
4
|
+
packageOverallScore Float
|
|
5
|
+
packageBuildStatus String
|
|
6
|
+
packageTestCoverage Float?
|
|
7
|
+
packageLintStatus String
|
|
8
|
+
packageSecurity String // Changed from securityAudit to packageSecurity
|
|
9
|
+
packageDependencies String // Changed from dependencies to packageDependencies
|
|
10
|
+
createdAt DateTime @default(now())
|
|
11
|
+
updatedAt DateTime @updatedAt
|
|
12
|
+
package Package @relation(fields: [packageName], references: [name], onDelete: Cascade)
|
|
13
|
+
|
|
14
|
+
@@map("package_health")
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
model Package {
|
|
2
|
+
// Primary Key and Identity Field (using the package name as the unique ID): Example: '@monodog/dashboard'
|
|
3
|
+
name String @id @unique
|
|
4
|
+
version String
|
|
5
|
+
type String // e.g., 'app', 'package'
|
|
6
|
+
createdAt DateTime @default(now())
|
|
7
|
+
lastUpdated DateTime @default(now())
|
|
8
|
+
dependencies String?
|
|
9
|
+
maintainers String
|
|
10
|
+
path String // The relative path in the file system, e.g., 'packages/monoapp'
|
|
11
|
+
description String
|
|
12
|
+
license String
|
|
13
|
+
repository String?
|
|
14
|
+
scripts String?
|
|
15
|
+
status String @default("")
|
|
16
|
+
devDependencies String?
|
|
17
|
+
peerDependencies String?
|
|
18
|
+
dependenciesInfo DependencyInfo[]
|
|
19
|
+
commits Commit[]
|
|
20
|
+
packageHealth PackageHealth?
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// This is your Prisma schema file,
|
|
2
|
+
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
|
5
|
+
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
|
6
|
+
|
|
7
|
+
generator client {
|
|
8
|
+
provider = "prisma-client-js"
|
|
9
|
+
previewFeatures = ["prismaSchemaFolder"]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
datasource db {
|
|
13
|
+
provider = "sqlite"
|
|
14
|
+
url = env("DATABASE_URL")
|
|
15
|
+
}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swagger API Documentation Configuration
|
|
3
|
+
* Defines OpenAPI specification for MonoDog API
|
|
4
|
+
*/
|
|
5
|
+
import { appConfig } from "../config-loader";
|
|
6
|
+
export const swaggerDefinition = {
|
|
7
|
+
openapi: '3.0.0',
|
|
8
|
+
info: {
|
|
9
|
+
title: 'MonoDog API',
|
|
10
|
+
version: '1.0.0',
|
|
11
|
+
description: 'Monorepo Analytics and Health Dashboard API',
|
|
12
|
+
contact: {
|
|
13
|
+
name: 'MonoDog Team',
|
|
14
|
+
url: 'https://github.com/mindfiredigital/monodog',
|
|
15
|
+
},
|
|
16
|
+
license: {
|
|
17
|
+
name: 'MIT',
|
|
18
|
+
url: 'https://opensource.org/licenses/MIT',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
servers: [
|
|
22
|
+
{
|
|
23
|
+
url: `http://${appConfig.server.host}:${appConfig.server.port}/api`,
|
|
24
|
+
description: 'Development server',
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
],
|
|
28
|
+
paths: {
|
|
29
|
+
'/packages': {
|
|
30
|
+
get: {
|
|
31
|
+
tags: ['Packages'],
|
|
32
|
+
summary: 'Get all packages',
|
|
33
|
+
operationId: 'getPackages',
|
|
34
|
+
responses: {
|
|
35
|
+
'200': {
|
|
36
|
+
description: 'List of packages',
|
|
37
|
+
content: {
|
|
38
|
+
'application/json': {
|
|
39
|
+
schema: { type: 'array', items: { $ref: '#/components/schemas/Package' } },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
'500': { description: 'Internal server error' },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
'/packages/{name}': {
|
|
48
|
+
get: {
|
|
49
|
+
tags: ['Packages'],
|
|
50
|
+
summary: 'Get package by name',
|
|
51
|
+
operationId: 'getPackageByName',
|
|
52
|
+
parameters: [{ name: 'name', in: 'path', required: true, schema: { type: 'string' } }],
|
|
53
|
+
responses: {
|
|
54
|
+
'200': {
|
|
55
|
+
description: 'Package details',
|
|
56
|
+
content: {
|
|
57
|
+
'application/json': {
|
|
58
|
+
schema: { $ref: '#/components/schemas/Package' },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
'404': { description: 'Package not found' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
'/packages/refresh': {
|
|
67
|
+
post: {
|
|
68
|
+
tags: ['Packages'],
|
|
69
|
+
summary: 'Refresh packages',
|
|
70
|
+
operationId: 'refreshPackages',
|
|
71
|
+
responses: {
|
|
72
|
+
'200': { description: 'Packages refreshed successfully' },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
'/packages/update-config': {
|
|
77
|
+
put: {
|
|
78
|
+
tags: ['Packages'],
|
|
79
|
+
summary: 'Update package configuration',
|
|
80
|
+
operationId: 'updatePackageConfig',
|
|
81
|
+
requestBody: {
|
|
82
|
+
required: true,
|
|
83
|
+
content: {
|
|
84
|
+
'application/json': {
|
|
85
|
+
schema: { $ref: '#/components/schemas/Package' },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
responses: {
|
|
90
|
+
'200': { description: 'Package configuration updated successfully' },
|
|
91
|
+
'400': { description: 'Invalid request' },
|
|
92
|
+
'404': { description: 'Package not found' },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
'/health/packages': {
|
|
97
|
+
get: {
|
|
98
|
+
tags: ['Health'],
|
|
99
|
+
summary: 'Get packages health status',
|
|
100
|
+
operationId: 'getPackagesHealth',
|
|
101
|
+
responses: {
|
|
102
|
+
'200': {
|
|
103
|
+
description: 'Health status of all packages',
|
|
104
|
+
content: {
|
|
105
|
+
'application/json': {
|
|
106
|
+
schema: { type: 'array', items: { $ref: '#/components/schemas/PackageHealth' } },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
'/health/refresh': {
|
|
114
|
+
post: {
|
|
115
|
+
tags: ['Health'],
|
|
116
|
+
summary: 'Refresh health status',
|
|
117
|
+
operationId: 'refreshHealth',
|
|
118
|
+
responses: {
|
|
119
|
+
'200': { description: 'Health status refreshed successfully' },
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
'/commits/{packagePath}': {
|
|
124
|
+
get: {
|
|
125
|
+
tags: ['Commits'],
|
|
126
|
+
summary: 'Get commits for a package',
|
|
127
|
+
operationId: 'getCommits',
|
|
128
|
+
parameters: [{ name: 'packagePath', in: 'path', required: true, schema: { type: 'string' } }],
|
|
129
|
+
responses: {
|
|
130
|
+
'200': {
|
|
131
|
+
description: 'List of commits',
|
|
132
|
+
content: {
|
|
133
|
+
'application/json': {
|
|
134
|
+
schema: { type: 'array', items: { $ref: '#/components/schemas/Commit' } },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
'/config/files': {
|
|
142
|
+
get: {
|
|
143
|
+
tags: ['Configuration'],
|
|
144
|
+
summary: 'Get configuration files',
|
|
145
|
+
operationId: 'getConfigFiles',
|
|
146
|
+
responses: {
|
|
147
|
+
'200': {
|
|
148
|
+
description: 'List of configuration files',
|
|
149
|
+
content: {
|
|
150
|
+
'application/json': {
|
|
151
|
+
schema: { type: 'array', items: { $ref: '#/components/schemas/ConfigFile' } },
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
'/config/files/{id}': {
|
|
159
|
+
put: {
|
|
160
|
+
tags: ['Configuration'],
|
|
161
|
+
summary: 'Update configuration file',
|
|
162
|
+
operationId: 'updateConfigFile',
|
|
163
|
+
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
164
|
+
requestBody: {
|
|
165
|
+
required: true,
|
|
166
|
+
content: {
|
|
167
|
+
'application/json': {
|
|
168
|
+
schema: { $ref: '#/components/schemas/ConfigFile' },
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
responses: {
|
|
173
|
+
'200': { description: 'Configuration file updated successfully' },
|
|
174
|
+
'400': { description: 'Invalid request' },
|
|
175
|
+
'404': { description: 'Configuration file not found' },
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
tags: [
|
|
181
|
+
{
|
|
182
|
+
name: 'Packages',
|
|
183
|
+
description: 'Package management and analysis endpoints',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'Health',
|
|
187
|
+
description: 'Health monitoring and status endpoints',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'Commits',
|
|
191
|
+
description: 'Git commit history and analysis endpoints',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: 'Configuration',
|
|
195
|
+
description: 'Configuration file management endpoints',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
components: {
|
|
199
|
+
schemas: {
|
|
200
|
+
Package: {
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
name: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'Package name',
|
|
206
|
+
},
|
|
207
|
+
path: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
description: 'Package path in monorepo',
|
|
210
|
+
},
|
|
211
|
+
version: {
|
|
212
|
+
type: 'string',
|
|
213
|
+
description: 'Package version',
|
|
214
|
+
},
|
|
215
|
+
size: {
|
|
216
|
+
type: 'number',
|
|
217
|
+
description: 'Package size in bytes',
|
|
218
|
+
},
|
|
219
|
+
dependencies: {
|
|
220
|
+
type: 'array',
|
|
221
|
+
items: {
|
|
222
|
+
type: 'string',
|
|
223
|
+
},
|
|
224
|
+
description: 'List of package dependencies',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
PackageHealth: {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: {
|
|
231
|
+
packageName: {
|
|
232
|
+
type: 'string',
|
|
233
|
+
description: 'Name of the package',
|
|
234
|
+
},
|
|
235
|
+
healthScore: {
|
|
236
|
+
type: 'number',
|
|
237
|
+
description: 'Health score (0-100)',
|
|
238
|
+
minimum: 0,
|
|
239
|
+
maximum: 100,
|
|
240
|
+
},
|
|
241
|
+
lintStatus: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
enum: ['pass', 'warning', 'fail'],
|
|
244
|
+
description: 'Linting status',
|
|
245
|
+
},
|
|
246
|
+
buildStatus: {
|
|
247
|
+
type: 'string',
|
|
248
|
+
enum: ['success', 'failed', 'pending'],
|
|
249
|
+
description: 'Build status',
|
|
250
|
+
},
|
|
251
|
+
securityStatus: {
|
|
252
|
+
type: 'string',
|
|
253
|
+
enum: ['secure', 'warning', 'vulnerable'],
|
|
254
|
+
description: 'Security status',
|
|
255
|
+
},
|
|
256
|
+
testCoverage: {
|
|
257
|
+
type: 'number',
|
|
258
|
+
description: 'Test coverage percentage',
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
Commit: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: {
|
|
265
|
+
hash: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
description: 'Commit hash',
|
|
268
|
+
},
|
|
269
|
+
author: {
|
|
270
|
+
type: 'string',
|
|
271
|
+
description: 'Commit author',
|
|
272
|
+
},
|
|
273
|
+
message: {
|
|
274
|
+
type: 'string',
|
|
275
|
+
description: 'Commit message',
|
|
276
|
+
},
|
|
277
|
+
date: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
format: 'date-time',
|
|
280
|
+
description: 'Commit date',
|
|
281
|
+
},
|
|
282
|
+
filesChanged: {
|
|
283
|
+
type: 'number',
|
|
284
|
+
description: 'Number of files changed',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
ConfigFile: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {
|
|
291
|
+
id: {
|
|
292
|
+
type: 'string',
|
|
293
|
+
description: 'Configuration file ID',
|
|
294
|
+
},
|
|
295
|
+
name: {
|
|
296
|
+
type: 'string',
|
|
297
|
+
description: 'Configuration file name',
|
|
298
|
+
},
|
|
299
|
+
path: {
|
|
300
|
+
type: 'string',
|
|
301
|
+
description: 'Configuration file path',
|
|
302
|
+
},
|
|
303
|
+
content: {
|
|
304
|
+
type: 'string',
|
|
305
|
+
description: 'Configuration file content',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
Error: {
|
|
310
|
+
type: 'object',
|
|
311
|
+
properties: {
|
|
312
|
+
error: {
|
|
313
|
+
type: 'string',
|
|
314
|
+
description: 'Error message',
|
|
315
|
+
},
|
|
316
|
+
message: {
|
|
317
|
+
type: 'string',
|
|
318
|
+
description: 'Detailed error message',
|
|
319
|
+
},
|
|
320
|
+
code: {
|
|
321
|
+
type: 'string',
|
|
322
|
+
description: 'Error code',
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
responses: {
|
|
328
|
+
UnauthorizedError: {
|
|
329
|
+
description: 'Unauthorized access',
|
|
330
|
+
},
|
|
331
|
+
NotFoundError: {
|
|
332
|
+
description: 'Resource not found',
|
|
333
|
+
},
|
|
334
|
+
InternalServerError: {
|
|
335
|
+
description: 'Internal server error',
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
export const swaggerOptions = {
|
|
342
|
+
definition: swaggerDefinition,
|
|
343
|
+
apis: [], // Using only definition, no JSDoc file scanning
|
|
344
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Constants
|
|
3
|
+
* Defines constants used across middleware modules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* HTTP status code for internal server error
|
|
8
|
+
*/
|
|
9
|
+
export const HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* HTTP status code for not found
|
|
13
|
+
*/
|
|
14
|
+
export const HTTP_STATUS_NOT_FOUND = 404;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* HTTP status code for bad request
|
|
18
|
+
*/
|
|
19
|
+
export const HTTP_STATUS_BAD_REQUEST = 400;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Error message for port already in use
|
|
23
|
+
*/
|
|
24
|
+
export const ERROR_PORT_IN_USE = (port: number): string =>
|
|
25
|
+
`Port ${port} is already in use. Please specify a different port.`;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Error message for permission denied
|
|
29
|
+
*/
|
|
30
|
+
export const ERROR_PERMISSION_DENIED = (port: number): string =>
|
|
31
|
+
`Permission denied to listen on port ${port}. Use a port above 1024.`;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Error message for internal server error
|
|
35
|
+
*/
|
|
36
|
+
export const ERROR_INTERNAL_SERVER = 'Internal server error';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Success message for server start
|
|
40
|
+
*/
|
|
41
|
+
export const SUCCESS_SERVER_START = (host: string, port: number): string =>
|
|
42
|
+
`Backend server listening on http://${host}:${port}`;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Success message for dashboard start
|
|
46
|
+
*/
|
|
47
|
+
export const SUCCESS_DASHBOARD_START = (host: string, port: number): string =>
|
|
48
|
+
`Dashboard listening on http://${host}:${port}`;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Message for graceful shutdown
|
|
52
|
+
*/
|
|
53
|
+
export const MESSAGE_GRACEFUL_SHUTDOWN = 'SIGTERM signal received: closing HTTP server';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Message for server closed
|
|
57
|
+
*/
|
|
58
|
+
export const MESSAGE_SERVER_CLOSED = 'HTTP server closed';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Message for dashboard graceful shutdown
|
|
62
|
+
*/
|
|
63
|
+
export const MESSAGE_DASHBOARD_GRACEFUL_SHUTDOWN = 'SIGTERM signal received: closing dashboard server';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Message for dashboard closed
|
|
67
|
+
*/
|
|
68
|
+
export const MESSAGE_DASHBOARD_CLOSED = 'Dashboard server closed';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Content-Type header for JavaScript
|
|
72
|
+
*/
|
|
73
|
+
export const CONTENT_TYPE_JAVASCRIPT = 'application/javascript';
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Error serving index.html message
|
|
77
|
+
*/
|
|
78
|
+
export const ERROR_SERVING_INDEX_HTML = 'Error serving index.html:';
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Shutdown instruction message
|
|
82
|
+
*/
|
|
83
|
+
export const MESSAGE_SHUTDOWN_INSTRUCTION = 'Press Ctrl+C to quit.';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port Constants
|
|
3
|
+
* Defines valid port range and port-related configuration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Minimum valid port number (above system reserved ports)
|
|
8
|
+
*/
|
|
9
|
+
export const PORT_MIN = 1024;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Maximum valid port number
|
|
13
|
+
*/
|
|
14
|
+
export const PORT_MAX = 65535;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Port validation error message
|
|
18
|
+
*/
|
|
19
|
+
export const PORT_VALIDATION_ERROR_MESSAGE = (min: number, max: number): string =>
|
|
20
|
+
`Port must be between ${min} and ${max}`;
|