@monodog/backend 1.5.1 → 1.5.3
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/CHANGELOG.md +7 -0
- package/LICENCE +21 -0
- package/README.md +19 -19
- package/dist/cli.js +20 -20
- package/dist/config-loader.js +15 -15
- package/dist/index.js +59 -15
- package/dist/utils/helpers.js +50 -9
- package/monodog-conf.example.json +11 -11
- package/package.json +17 -16
- package/src/cli.ts +190 -154
- package/src/config-loader.ts +57 -50
- package/src/get-db-url.ts +0 -1
- package/src/index.ts +1366 -1331
- package/src/types/monorepo-scanner.d.ts +7 -8
- package/src/utils/helpers.js +169 -165
- package/src/utils/helpers.ts +82 -77
- package/tsconfig.json +0 -1
package/CHANGELOG.md
ADDED
package/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mindfire Digital LLP
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,14 +11,14 @@ This service is typically run locally or on a central server to power a dedicate
|
|
|
11
11
|
|
|
12
12
|
## 🛠 Technology Stack
|
|
13
13
|
|
|
14
|
-
| Component
|
|
15
|
-
|
|
16
|
-
| **Language**
|
|
17
|
-
| **Framework**
|
|
18
|
-
| **ORM**
|
|
19
|
-
| **Scanning**
|
|
20
|
-
| **VCS**
|
|
21
|
-
| **Networking** | cors, body-parser
|
|
14
|
+
| Component | Technology | Description |
|
|
15
|
+
| -------------- | ------------------------- | -------------------------------------------------------------------- |
|
|
16
|
+
| **Language** | TypeScript & Node.js | Core language for runtime execution. |
|
|
17
|
+
| **Framework** | Express.js | Handles all API routing and middleware. |
|
|
18
|
+
| **ORM** | Prisma | Database layer for managing package and health status records. |
|
|
19
|
+
| **Scanning** | @monodog/monorepo-scanner | Core logic for file system scanning and package metadata extraction. |
|
|
20
|
+
| **VCS** | GitService | Used to fetch and analyze commit history per package path. |
|
|
21
|
+
| **Networking** | cors, body-parser | Essential middleware for API connectivity. |
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
@@ -34,13 +34,13 @@ You must have the following installed to run the service:
|
|
|
34
34
|
|
|
35
35
|
## 🚀 Getting Started
|
|
36
36
|
|
|
37
|
-
###
|
|
37
|
+
### Installation
|
|
38
38
|
|
|
39
39
|
Clone the repository and install the dependencies:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# Clone the repository
|
|
43
|
-
git clone https://github.com/
|
|
43
|
+
git clone https://github.com/mindfiredigital/MonoDog.git
|
|
44
44
|
cd packages/backend
|
|
45
45
|
|
|
46
46
|
# Install dependencies
|
|
@@ -61,12 +61,12 @@ pnpm monodog-cli --serve --root .
|
|
|
61
61
|
|
|
62
62
|
### Key API Endpoints
|
|
63
63
|
|
|
64
|
-
| Method
|
|
65
|
-
|
|
66
|
-
| **GET** | `/api/packages`
|
|
67
|
-
| **GET** | `/api/packages/refresh`
|
|
68
|
-
| **GET** | `/api/packages/:name`
|
|
69
|
-
| **GET** | `/api/health/packages`
|
|
70
|
-
| **GET** | `/api/health/refresh`
|
|
71
|
-
| **GET** | `/api/commits/:packagePath` | Fetch Git commit history for a specific package directory.
|
|
72
|
-
| **GET** | `/api/config/files`
|
|
64
|
+
| Method | Route | Purpose | Persistence |
|
|
65
|
+
| ------- | --------------------------- | --------------------------------------------------------------------------------------- | ------------------- |
|
|
66
|
+
| **GET** | `/api/packages` | Retrieve all package metadata from the database. | Cached / Persistent |
|
|
67
|
+
| **GET** | `/api/packages/refresh` | Trigger a full file scan of the monorepo and update/sync the database. | Triggers write |
|
|
68
|
+
| **GET** | `/api/packages/:name` | Get detailed info, reports, and CI status for a package. | Cached / Persistent |
|
|
69
|
+
| **GET** | `/api/health/packages` | Fetch the latest health metrics (score, build status) for all packages. | Persistent |
|
|
70
|
+
| **GET** | `/api/health/refresh` | Recalculate all package health metrics (tests, lint, security) and update the database. | Triggers write |
|
|
71
|
+
| **GET** | `/api/commits/:packagePath` | Fetch Git commit history for a specific package directory. | Generated runtime |
|
|
72
|
+
| **GET** | `/api/config/files` | Scan the monorepo for essential configuration files (e.g., `tsconfig`, `.eslintrc`). | Generated runtime |
|
package/dist/cli.js
CHANGED
|
@@ -130,11 +130,11 @@ function copyPackageToWorkspace(rootDir) {
|
|
|
130
130
|
// The package name is expected as the first command-line argument (process.argv[2])
|
|
131
131
|
const packageName = process.argv[2];
|
|
132
132
|
if (!packageName || packageName.startsWith('--')) {
|
|
133
|
-
console.error(
|
|
134
|
-
console.log(
|
|
133
|
+
console.error('Error: Please provide the package name as an argument if you want to setup dashboard.');
|
|
134
|
+
console.log('Usage: pnpm monodog-cli @monodog/dashboard --serve --root .');
|
|
135
135
|
}
|
|
136
136
|
if (!(packageName == '@monodog/backend' || packageName == '@monodog/dashboard')) {
|
|
137
|
-
console.log(
|
|
137
|
+
console.log('\n--- Skipping workspace setup for @monodog/backend to avoid self-copying. ---');
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
// const rootDir = process.cwd();
|
|
@@ -156,7 +156,7 @@ function copyPackageToWorkspace(rootDir) {
|
|
|
156
156
|
// 3. Validate Destination existence (prevent accidental overwrite)
|
|
157
157
|
if (fs.existsSync(destinationPath)) {
|
|
158
158
|
console.error(`\n❌ Error: Destination directory already exists at ${destinationPath}.`);
|
|
159
|
-
console.error(
|
|
159
|
+
console.error('Please manually remove it or rename it before running the script.');
|
|
160
160
|
process.exit(1);
|
|
161
161
|
}
|
|
162
162
|
// Ensure the 'install_path' directory exists
|
|
@@ -177,12 +177,12 @@ function copyPackageToWorkspace(rootDir) {
|
|
|
177
177
|
});
|
|
178
178
|
console.log(`\n✅ Success! Contents of '${packageName}' copied to '${destinationPath}'`);
|
|
179
179
|
// Post-copy instructions
|
|
180
|
-
console.log(
|
|
181
|
-
console.log(
|
|
180
|
+
console.log('\n*** IMPORTANT NEXT STEPS (MANDATORY) ***');
|
|
181
|
+
console.log('1.Migrate Database:');
|
|
182
182
|
console.log(` - pnpm prisma migrate --schema ./node_modules/@monodog/backend/prisma/schema.prisma`);
|
|
183
|
-
console.log(
|
|
183
|
+
console.log('2. Generate Client:');
|
|
184
184
|
console.log(` - pnpm exec prisma generate --schema ./node_modules/@monodog/backend/prisma/schema.prisma`);
|
|
185
|
-
console.log(
|
|
185
|
+
console.log('3. Run Backend app server with dashboard setup');
|
|
186
186
|
console.log(` - pnpm monodog-cli @monodog/dashboard --serve --root .`);
|
|
187
187
|
}
|
|
188
188
|
catch (err) {
|
|
@@ -197,21 +197,21 @@ function createConfigFileIfMissing(rootPath) {
|
|
|
197
197
|
const configFilePath = path.resolve(rootPath, configFileName);
|
|
198
198
|
// The default content for the configuration file
|
|
199
199
|
const defaultContent = {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
workspace: {
|
|
201
|
+
root_dir: './', // Relative to where the config file is located
|
|
202
|
+
install_path: 'packages', // Where to install monodog packages
|
|
203
203
|
},
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
database: {
|
|
205
|
+
path: './monodog.db', // SQLite database file path, relative to prisma schema location
|
|
206
206
|
},
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
dashboard: {
|
|
208
|
+
host: '0.0.0.0',
|
|
209
|
+
port: '3010',
|
|
210
|
+
},
|
|
211
|
+
server: {
|
|
212
|
+
host: '0.0.0.0', // Default host for the API server
|
|
213
|
+
port: 4000, // Default port for the API server
|
|
210
214
|
},
|
|
211
|
-
"server": {
|
|
212
|
-
"host": "0.0.0.0", // Default host for the API server
|
|
213
|
-
"port": 4000 // Default port for the API server
|
|
214
|
-
}
|
|
215
215
|
};
|
|
216
216
|
const contentString = JSON.stringify(defaultContent, null, 2);
|
|
217
217
|
// ---------------------
|
package/dist/config-loader.js
CHANGED
|
@@ -50,8 +50,8 @@ function loadConfig() {
|
|
|
50
50
|
// 1. Determine the path to the config file
|
|
51
51
|
// We assume the backend package is running from the monorepo root (cwd is root)
|
|
52
52
|
// or that we can navigate up to the root from the current file's location.
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const rootPath = path.resolve(process.cwd(), '..', '..'); // Adjust based on your workspace folder depth from root if needed
|
|
54
|
+
const configPath = path.resolve(rootPath, 'monodog-conf.json');
|
|
55
55
|
createConfigFileIfMissing(rootPath);
|
|
56
56
|
if (!fs.existsSync(configPath)) {
|
|
57
57
|
console.error(`ERROR1: Configuration file not found at ${configPath}`);
|
|
@@ -68,7 +68,7 @@ function loadConfig() {
|
|
|
68
68
|
return config;
|
|
69
69
|
}
|
|
70
70
|
catch (error) {
|
|
71
|
-
console.error(
|
|
71
|
+
console.error('ERROR: Failed to read or parse monodog-conf.json.');
|
|
72
72
|
console.error(error);
|
|
73
73
|
process.exit(1);
|
|
74
74
|
}
|
|
@@ -79,21 +79,21 @@ function createConfigFileIfMissing(rootPath) {
|
|
|
79
79
|
const configFilePath = path.resolve(rootPath, configFileName);
|
|
80
80
|
// The default content for the configuration file
|
|
81
81
|
const defaultContent = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
workspace: {
|
|
83
|
+
root_dir: './', // Relative to where the config file is located
|
|
84
|
+
install_path: 'packages', // Where to install monodog packages
|
|
85
85
|
},
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
database: {
|
|
87
|
+
path: 'file:./monodog.db', // SQLite database file path, relative to prisma schema location
|
|
88
88
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
dashboard: {
|
|
90
|
+
host: '0.0.0.0',
|
|
91
|
+
port: '3010',
|
|
92
|
+
},
|
|
93
|
+
server: {
|
|
94
|
+
host: '0.0.0.0', // Default host for the API server
|
|
95
|
+
port: 4000, // Default port for the API server
|
|
92
96
|
},
|
|
93
|
-
"server": {
|
|
94
|
-
"host": "0.0.0.0", // Default host for the API server
|
|
95
|
-
"port": 4000 // Default port for the API server
|
|
96
|
-
}
|
|
97
97
|
};
|
|
98
98
|
const contentString = JSON.stringify(defaultContent, null, 2);
|
|
99
99
|
// ---------------------
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -16,11 +49,12 @@ exports.scanner = new monorepo_scanner_1.MonorepoScanner();
|
|
|
16
49
|
const ci_status_1 = require("@monodog/ci-status");
|
|
17
50
|
const helpers_1 = require("@monodog/utils/helpers");
|
|
18
51
|
const helpers_2 = require("./utils/helpers");
|
|
19
|
-
|
|
20
|
-
|
|
52
|
+
// Fallback import to handle environments where PrismaClient isn't a named export
|
|
53
|
+
const PrismaPkg = __importStar(require("@prisma/client"));
|
|
54
|
+
const PrismaClient = PrismaPkg.PrismaClient || PrismaPkg.default || PrismaPkg; // Import the validateConfig function from your utils
|
|
21
55
|
// import { validateConfig } from '../../apps/dashboard/src/components/modules/config-inspector/utils/config.utils';
|
|
22
56
|
const gitService_1 = require("./gitService");
|
|
23
|
-
const prisma = new
|
|
57
|
+
const prisma = new PrismaClient();
|
|
24
58
|
// The main function exported and called by the CLI
|
|
25
59
|
function startServer(rootPath, port, host) {
|
|
26
60
|
const app = (0, express_1.default)();
|
|
@@ -64,7 +98,7 @@ function startServer(rootPath, port, host) {
|
|
|
64
98
|
}
|
|
65
99
|
dbPackages = await prisma.package.findMany();
|
|
66
100
|
}
|
|
67
|
-
const transformedPackages = dbPackages.map(pkg => {
|
|
101
|
+
const transformedPackages = dbPackages.map((pkg) => {
|
|
68
102
|
// We create a new object 'transformedPkg' based on the database record 'pkg'
|
|
69
103
|
const transformedPkg = { ...pkg };
|
|
70
104
|
// 1. Maintainers (Your Logic)
|
|
@@ -473,7 +507,7 @@ function startServer(rootPath, port, host) {
|
|
|
473
507
|
const packageHealthData = await prisma.packageHealth.findMany();
|
|
474
508
|
console.log('packageHealthData -->', packageHealthData.length);
|
|
475
509
|
// Transform the data to match the expected frontend format
|
|
476
|
-
const packages = packageHealthData.map(pkg => {
|
|
510
|
+
const packages = packageHealthData.map((pkg) => {
|
|
477
511
|
const health = {
|
|
478
512
|
buildStatus: pkg.packageBuildStatus,
|
|
479
513
|
testCoverage: pkg.packageTestCoverage,
|
|
@@ -489,8 +523,8 @@ function startServer(rootPath, port, host) {
|
|
|
489
523
|
});
|
|
490
524
|
// Calculate summary statistics
|
|
491
525
|
const total = packages.length;
|
|
492
|
-
const healthy = packages.filter(pkg => pkg.isHealthy).length;
|
|
493
|
-
const unhealthy = packages.filter(pkg => !pkg.isHealthy).length;
|
|
526
|
+
const healthy = packages.filter((pkg) => pkg.isHealthy).length;
|
|
527
|
+
const unhealthy = packages.filter((pkg) => !pkg.isHealthy).length;
|
|
494
528
|
const averageScore = packages.length > 0
|
|
495
529
|
? packages.reduce((sum, pkg) => sum + pkg.health.overallScore, 0) /
|
|
496
530
|
packages.length
|
|
@@ -535,7 +569,11 @@ function startServer(rootPath, port, host) {
|
|
|
535
569
|
securityAudit: securityAudit,
|
|
536
570
|
overallScore: overallScore.overallScore,
|
|
537
571
|
};
|
|
538
|
-
const packageStatus = health.overallScore >= 80
|
|
572
|
+
const packageStatus = health.overallScore >= 80
|
|
573
|
+
? 'healthy'
|
|
574
|
+
: health.overallScore >= 60 && health.overallScore < 80
|
|
575
|
+
? 'warning'
|
|
576
|
+
: 'error';
|
|
539
577
|
console.log(pkg.name, '-->', health, packageStatus);
|
|
540
578
|
// FIX: Use upsert to handle existing packages and proper Prisma syntax
|
|
541
579
|
await prisma.packageHealth.upsert({
|
|
@@ -618,12 +656,12 @@ function startServer(rootPath, port, host) {
|
|
|
618
656
|
// Filter by search query
|
|
619
657
|
if (query) {
|
|
620
658
|
const searchTerm = query.toLowerCase();
|
|
621
|
-
filtered = filtered.filter(pkg => pkg.name.toLowerCase().includes(searchTerm) ||
|
|
659
|
+
filtered = filtered.filter((pkg) => pkg.name.toLowerCase().includes(searchTerm) ||
|
|
622
660
|
pkg.description?.toLowerCase().includes(searchTerm));
|
|
623
661
|
}
|
|
624
662
|
// Filter by type
|
|
625
663
|
if (type && type !== 'all') {
|
|
626
|
-
filtered = filtered.filter(pkg => pkg.type === type);
|
|
664
|
+
filtered = filtered.filter((pkg) => pkg.type === type);
|
|
627
665
|
}
|
|
628
666
|
// Filter by status (would need health data)
|
|
629
667
|
if (status && status !== 'all') {
|
|
@@ -1175,7 +1213,9 @@ function startServer(rootPath, port, host) {
|
|
|
1175
1213
|
maintainers: updatedPackage.maintainers
|
|
1176
1214
|
? JSON.parse(updatedPackage.maintainers)
|
|
1177
1215
|
: [],
|
|
1178
|
-
scripts: updatedPackage.scripts
|
|
1216
|
+
scripts: updatedPackage.scripts
|
|
1217
|
+
? JSON.parse(updatedPackage.scripts)
|
|
1218
|
+
: {},
|
|
1179
1219
|
repository: updatedPackage.repository
|
|
1180
1220
|
? JSON.parse(updatedPackage.repository)
|
|
1181
1221
|
: {},
|
|
@@ -1224,7 +1264,8 @@ function startServer(rootPath, port, host) {
|
|
|
1224
1264
|
});
|
|
1225
1265
|
});
|
|
1226
1266
|
const PORT = parseInt(port ? port.toString() : '4000');
|
|
1227
|
-
app
|
|
1267
|
+
app
|
|
1268
|
+
.listen(PORT, host, async () => {
|
|
1228
1269
|
const pcount = await prisma.package.count();
|
|
1229
1270
|
console.log(`[Database] Total packages found: ${pcount}`);
|
|
1230
1271
|
console.log(`🚀 Backend server running on http://${host}:${PORT}`);
|
|
@@ -1243,7 +1284,8 @@ function startServer(rootPath, port, host) {
|
|
|
1243
1284
|
console.log(` - GET /api/search`);
|
|
1244
1285
|
console.log(` - GET /api/activity`);
|
|
1245
1286
|
console.log(` - GET /api/system`);
|
|
1246
|
-
})
|
|
1287
|
+
})
|
|
1288
|
+
.on('error', err => {
|
|
1247
1289
|
// Handle common errors like EADDRINUSE (port already in use)
|
|
1248
1290
|
if (err.message.includes('EADDRINUSE')) {
|
|
1249
1291
|
console.error(`Error: Port ${port} is already in use. Please specify a different port via configuration file.`);
|
|
@@ -1329,14 +1371,16 @@ function serveDashboard(rootPath, port, host) {
|
|
|
1329
1371
|
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
|
|
1330
1372
|
res.header('Expires', '-1');
|
|
1331
1373
|
res.header('Pragma', 'no-cache');
|
|
1332
|
-
res.sendFile('index.html', {
|
|
1374
|
+
res.sendFile('index.html', {
|
|
1375
|
+
root: path_1.default.resolve(rootPath, 'monodog-dashboard', 'dist'),
|
|
1376
|
+
});
|
|
1333
1377
|
}
|
|
1334
1378
|
});
|
|
1335
1379
|
const staticPath = path_1.default.resolve(rootPath, 'monodog-dashboard', 'dist');
|
|
1336
1380
|
console.log('Serving static files from:', staticPath);
|
|
1337
1381
|
app.use(express_1.default.static(staticPath));
|
|
1338
1382
|
// Start the server
|
|
1339
|
-
const PORT = parseInt(port ? port.toString() : '
|
|
1383
|
+
const PORT = parseInt(port ? port.toString() : '8999');
|
|
1340
1384
|
app.listen(PORT, host, () => {
|
|
1341
1385
|
console.log(`App listening on ${host}:${port}`);
|
|
1342
1386
|
console.log('Press Ctrl+C to quit.');
|
package/dist/utils/helpers.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.getCommits = getCommits;
|
|
4
37
|
exports.storePackage = storePackage;
|
|
@@ -6,20 +39,26 @@ exports.storeCommits = storeCommits;
|
|
|
6
39
|
exports.getPackageDependenciesInfo = getPackageDependenciesInfo;
|
|
7
40
|
exports.storeDependencies = storeDependencies;
|
|
8
41
|
// dotenv.config({ path: path.resolve(__dirname, '../.env') });
|
|
9
|
-
|
|
42
|
+
// Fallback import to handle environments where PrismaClient isn't a named export
|
|
43
|
+
const PrismaPkg = __importStar(require("@prisma/client"));
|
|
44
|
+
const PrismaClient = PrismaPkg.PrismaClient || PrismaPkg.default || PrismaPkg;
|
|
45
|
+
// Provide a fallback reference to the Prisma namespace so errors like
|
|
46
|
+
// Prisma.PrismaClientKnownRequestError can be referenced safely.
|
|
47
|
+
const Prisma = PrismaPkg.Prisma || PrismaPkg.PrismaClient?.Prisma || PrismaPkg.default?.Prisma || PrismaPkg;
|
|
48
|
+
// Import the validateConfig function from your utils
|
|
10
49
|
const config_loader_1 = require("../config-loader");
|
|
11
50
|
const appConfig = (0, config_loader_1.loadConfig)();
|
|
12
51
|
// Default settings
|
|
13
52
|
const DEFAULT_PORT = 4000;
|
|
14
53
|
const port = appConfig.server.port ?? DEFAULT_PORT; //Default port
|
|
15
54
|
const host = appConfig.server.host ?? 'localhost'; //Default host
|
|
16
|
-
const prisma = new
|
|
55
|
+
const prisma = new PrismaClient();
|
|
17
56
|
const API_BASE = `http://${host}:${port}/api`;
|
|
18
57
|
async function getCommits(path) {
|
|
19
58
|
const res = await fetch(API_BASE + `/commits/` + encodeURIComponent(path));
|
|
20
59
|
if (!res.ok)
|
|
21
60
|
throw new Error('Failed to fetch commits');
|
|
22
|
-
return await res.json();
|
|
61
|
+
return (await res.json());
|
|
23
62
|
}
|
|
24
63
|
async function storeCommits(packageName, commits) {
|
|
25
64
|
console.log('💾 Storing commits for:' + packageName);
|
|
@@ -47,14 +86,15 @@ async function storeCommits(packageName, commits) {
|
|
|
47
86
|
});
|
|
48
87
|
}
|
|
49
88
|
catch (e) {
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
const err = e;
|
|
90
|
+
if (err instanceof Prisma.PrismaClientKnownRequestError &&
|
|
91
|
+
err.code === 'P2002') {
|
|
52
92
|
// Handle unique constraint violation (e.g., commit already exists)
|
|
53
93
|
console.warn(`Skipping commit: ${commit.hash} (Depenndency already exists)`);
|
|
54
94
|
}
|
|
55
95
|
else {
|
|
56
96
|
// Handle any other unexpected errors
|
|
57
|
-
console.error(`Failed to store commit: ${commit.hash}`,
|
|
97
|
+
console.error(`Failed to store commit: ${commit.hash}`, err);
|
|
58
98
|
}
|
|
59
99
|
}
|
|
60
100
|
}
|
|
@@ -185,14 +225,15 @@ async function storeDependencies(packageName, dependencies) {
|
|
|
185
225
|
console.log('💾 Dependencies stored in database:' + dep.name);
|
|
186
226
|
}
|
|
187
227
|
catch (e) {
|
|
188
|
-
|
|
189
|
-
|
|
228
|
+
const err = e;
|
|
229
|
+
if (err instanceof Prisma.PrismaClientKnownRequestError &&
|
|
230
|
+
err.code === 'P2002') {
|
|
190
231
|
// Handle unique constraint violation (e.g., depedency already exists)
|
|
191
232
|
console.warn(`Skipping dependency: ${dep.name} (Depenndency already exists)`);
|
|
192
233
|
}
|
|
193
234
|
else {
|
|
194
235
|
// Handle any other unexpected errors
|
|
195
|
-
console.error(`Failed to store dependency: ${dep.name}`,
|
|
236
|
+
console.error(`Failed to store dependency: ${dep.name}`, err);
|
|
196
237
|
}
|
|
197
238
|
}
|
|
198
239
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
"workspace": {
|
|
3
|
+
"root_dir": "./",
|
|
4
|
+
"install_path": "packages"
|
|
5
|
+
},
|
|
6
|
+
"database": {
|
|
7
|
+
"path": "file:./monodog.db"
|
|
8
|
+
},
|
|
9
|
+
"server": {
|
|
10
|
+
"host": "0.0.0.0",
|
|
11
|
+
"port": 4009
|
|
12
|
+
}
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monodog/backend",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "Backend API server for monodog monorepo dashboard",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
7
7
|
"monodog-cli": "dist/cli.js"
|
|
8
8
|
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"dev": "tsx watch src/index.ts",
|
|
11
|
-
"start": "tsx index.ts",
|
|
12
|
-
"prepublishOnly": "pnpm run build",
|
|
13
|
-
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
14
|
-
"prestart": "npm run build",
|
|
15
|
-
"cli": "pnpm run build && node dist/cli.js",
|
|
16
|
-
"clean": "rm -rf dist node_modules/.cache",
|
|
17
|
-
"lint": "eslint .",
|
|
18
|
-
"lint:fix": "eslint . --fix",
|
|
19
|
-
"db:url": "node dist/get-db-url.js",
|
|
20
|
-
"generate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma generate",
|
|
21
|
-
"migrate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma migrate dev",
|
|
22
|
-
"serve": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') node dist/cli.js --serve --root ../../" },
|
|
23
9
|
"dependencies": {
|
|
24
10
|
"@monodog/ci-status": "1.1.2",
|
|
25
11
|
"@monodog/monorepo-scanner": "1.0.7",
|
|
@@ -41,5 +27,20 @@
|
|
|
41
27
|
"ts-node": "^10.0.0",
|
|
42
28
|
"tsx": "^4.6.0",
|
|
43
29
|
"typescript": "^5.3.8"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"h": "tsx",
|
|
33
|
+
"dev": "tsx watch src/index.ts",
|
|
34
|
+
"start": "tsx index.ts",
|
|
35
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
36
|
+
"prestart": "npm run build",
|
|
37
|
+
"cli": "pnpm run build && node dist/cli.js",
|
|
38
|
+
"clean": "rm -rf dist node_modules/.cache",
|
|
39
|
+
"lint": "eslint .",
|
|
40
|
+
"lint:fix": "eslint . --fix",
|
|
41
|
+
"db:url": "node dist/get-db-url.js",
|
|
42
|
+
"generate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma generate",
|
|
43
|
+
"migrate": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') prisma migrate dev",
|
|
44
|
+
"serve": "DATABASE_URL=$(npm run db:url --silent 2>/dev/null | tr -d '\\n') node dist/cli.js --serve --root ../../"
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|