@manojkmfsi/monodog 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/package.json +1 -1
  4. package/src/config/swagger-config.ts +0 -344
  5. package/src/config-loader.ts +0 -97
  6. package/src/constants/index.ts +0 -13
  7. package/src/constants/middleware.ts +0 -83
  8. package/src/constants/port.ts +0 -20
  9. package/src/constants/security.ts +0 -78
  10. package/src/controllers/commit-controller.ts +0 -31
  11. package/src/controllers/config-controller.ts +0 -42
  12. package/src/controllers/health-controller.ts +0 -24
  13. package/src/controllers/package-controller.ts +0 -67
  14. package/src/get-db-url.ts +0 -9
  15. package/src/index.ts +0 -9
  16. package/src/middleware/dashboard-startup.ts +0 -161
  17. package/src/middleware/error-handler.ts +0 -50
  18. package/src/middleware/index.ts +0 -20
  19. package/src/middleware/logger.ts +0 -65
  20. package/src/middleware/security.ts +0 -90
  21. package/src/middleware/server-startup.ts +0 -153
  22. package/src/middleware/swagger-middleware.ts +0 -58
  23. package/src/repositories/commit-repository.ts +0 -108
  24. package/src/repositories/dependency-repository.ts +0 -110
  25. package/src/repositories/index.ts +0 -10
  26. package/src/repositories/package-health-repository.ts +0 -75
  27. package/src/repositories/package-repository.ts +0 -142
  28. package/src/repositories/prisma-client.ts +0 -25
  29. package/src/routes/commit-routes.ts +0 -10
  30. package/src/routes/config-routes.ts +0 -14
  31. package/src/routes/health-routes.ts +0 -14
  32. package/src/routes/package-routes.ts +0 -22
  33. package/src/serve.ts +0 -41
  34. package/src/services/commit-service.ts +0 -44
  35. package/src/services/config-service.ts +0 -391
  36. package/src/services/git-service.ts +0 -140
  37. package/src/services/health-service.ts +0 -162
  38. package/src/services/package-service.ts +0 -228
  39. package/src/setup.ts +0 -78
  40. package/src/types/ci.ts +0 -122
  41. package/src/types/config.ts +0 -22
  42. package/src/types/database.ts +0 -67
  43. package/src/types/git.ts +0 -33
  44. package/src/types/health.ts +0 -11
  45. package/src/types/index.ts +0 -23
  46. package/src/types/package.ts +0 -39
  47. package/src/types/scanner.ts +0 -31
  48. package/src/types/swagger-jsdoc.d.ts +0 -15
  49. package/src/utils/ci-status.ts +0 -535
  50. package/src/utils/db-utils.ts +0 -92
  51. package/src/utils/health-utils.ts +0 -67
  52. package/src/utils/monorepo-scanner.ts +0 -576
  53. package/src/utils/utilities.ts +0 -427
@@ -1,535 +0,0 @@
1
- import { AppLogger } from '../middleware/logger';
2
- import type { PackageInfo } from './utilities';
3
- import type {
4
- CIProvider,
5
- CIBuild,
6
- CIBuildStep,
7
- CIArtifact,
8
- CICoverage,
9
- CITestResults,
10
- CITestSuite,
11
- CITest,
12
- CIPackageStatus,
13
- CIMonorepoStatus,
14
- } from '../types';
15
-
16
- export class CIStatusManager {
17
- private providers: Map<string, CIProvider> = new Map();
18
- private cache: Map<string, any> = new Map();
19
- private cacheExpiry = 2 * 60 * 1000; // 2 minutes
20
-
21
- constructor() {
22
- this.initializeDefaultProviders();
23
- }
24
-
25
- /**
26
- * Initialize default CI providers
27
- */
28
- private initializeDefaultProviders(): void {
29
- // GitHub Actions
30
- this.addProvider({
31
- name: 'GitHub Actions',
32
- type: 'github',
33
- baseUrl: 'https://api.github.com',
34
- });
35
-
36
- // GitLab CI
37
- this.addProvider({
38
- name: 'GitLab CI',
39
- type: 'gitlab',
40
- baseUrl: 'https://gitlab.com/api/v4',
41
- });
42
-
43
- // CircleCI
44
- this.addProvider({
45
- name: 'CircleCI',
46
- type: 'circleci',
47
- baseUrl: 'https://circleci.com/api/v2',
48
- });
49
- }
50
-
51
- /**
52
- * Add a CI provider
53
- */
54
- addProvider(provider: CIProvider): void {
55
- this.providers.set(provider.name, provider);
56
- }
57
-
58
- /**
59
- * Remove a CI provider
60
- */
61
- removeProvider(name: string): void {
62
- this.providers.delete(name);
63
- }
64
-
65
- /**
66
- * Get all registered providers
67
- */
68
- getProviders(): CIProvider[] {
69
- return Array.from(this.providers.values());
70
- }
71
-
72
- /**
73
- * Fetch CI status for a specific package
74
- */
75
- async getPackageStatus(
76
- packageName: string,
77
- providerName?: string
78
- ): Promise<CIPackageStatus | null> {
79
- const cacheKey = `package-status-${packageName}-${providerName || 'all'}`;
80
- const cached = this.getFromCache(cacheKey);
81
- if (cached) {
82
- return cached;
83
- }
84
-
85
- try {
86
- let builds: CIBuild[] = [];
87
-
88
- if (providerName) {
89
- const provider = this.providers.get(providerName);
90
- if (provider) {
91
- builds = await this.fetchBuildsFromProvider(provider, packageName);
92
- }
93
- } else {
94
- // Fetch from all providers
95
- for (const provider of this.providers.values()) {
96
- const providerBuilds = await this.fetchBuildsFromProvider(
97
- provider,
98
- packageName
99
- );
100
- builds.push(...providerBuilds);
101
- }
102
- }
103
-
104
- if (builds.length === 0) {
105
- return null;
106
- }
107
-
108
- // Sort builds by start time (newest first)
109
- builds.sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
110
-
111
- const lastBuild = builds[0];
112
- const buildHistory = builds.slice(0, 10); // Last 10 builds
113
- const successRate = this.calculateSuccessRate(builds);
114
- const averageDuration = this.calculateAverageDuration(builds);
115
- const isHealthy = this.determinePackageHealth(builds);
116
- const issues = this.identifyIssues(builds);
117
-
118
- const status: CIPackageStatus = {
119
- packageName,
120
- lastBuild,
121
- buildHistory,
122
- successRate,
123
- averageDuration,
124
- lastCommit: lastBuild.commit,
125
- lastCommitDate: lastBuild.startTime,
126
- branch: lastBuild.branch,
127
- isHealthy,
128
- issues,
129
- };
130
-
131
- this.setCache(cacheKey, status);
132
- return status;
133
- } catch (error) {
134
- AppLogger.error(`Error fetching CI status for ${packageName}`, error as Error);
135
- return null;
136
- }
137
- }
138
-
139
- /**
140
- * Get overall monorepo CI status
141
- */
142
- async getMonorepoStatus(packages: PackageInfo[]): Promise<CIMonorepoStatus> {
143
- const cacheKey = 'monorepo-ci-status';
144
- const cached = this.getFromCache(cacheKey);
145
- if (cached) {
146
- return cached;
147
- }
148
-
149
- const packageStatuses: CIPackageStatus[] = [];
150
- const allBuilds: CIBuild[] = [];
151
- let totalTests = 0;
152
- let passedTests = 0;
153
- let failedTests = 0;
154
- const packageCoverage: Record<string, number> = {};
155
-
156
- // Get status for each package
157
- for (const pkg of packages) {
158
- const status = await this.getPackageStatus(pkg.name);
159
- if (status) {
160
- packageStatuses.push(status);
161
- allBuilds.push(...status.buildHistory);
162
-
163
- // Aggregate test results
164
- if (status.lastBuild?.tests) {
165
- totalTests += status.lastBuild.tests.total;
166
- passedTests += status.lastBuild.tests.passed;
167
- failedTests += status.lastBuild.tests.failed;
168
- }
169
-
170
- // Aggregate coverage
171
- if (status.lastBuild?.coverage) {
172
- packageCoverage[pkg.name] = status.lastBuild.coverage.percentage;
173
- }
174
- }
175
- }
176
-
177
- // Calculate overall metrics
178
- const totalPackages = packages.length;
179
- const healthyPackages = packageStatuses.filter(s => s.isHealthy).length;
180
- const warningPackages = packageStatuses.filter(
181
- s => !s.isHealthy && s.issues.length < 3
182
- ).length;
183
- const errorPackages = packageStatuses.filter(
184
- s => !s.isHealthy && s.issues.length >= 3
185
- ).length;
186
- const overallHealth = (healthyPackages / totalPackages) * 100;
187
-
188
- // Sort builds by time
189
- allBuilds.sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
190
- const recentBuilds = allBuilds.slice(0, 20);
191
- const failedBuilds = allBuilds.filter(b => b.status === 'failed');
192
-
193
- // Calculate overall coverage
194
- const coverageValues = Object.values(packageCoverage);
195
- const overallCoverage =
196
- coverageValues.length > 0
197
- ? coverageValues.reduce((sum, val) => sum + val, 0) /
198
- coverageValues.length
199
- : 0;
200
-
201
- const status: CIMonorepoStatus = {
202
- totalPackages,
203
- healthyPackages,
204
- warningPackages,
205
- errorPackages,
206
- overallHealth,
207
- packages: packageStatuses,
208
- recentBuilds,
209
- failedBuilds,
210
- coverage: {
211
- overall: overallCoverage,
212
- packages: packageCoverage,
213
- },
214
- tests: {
215
- total: totalTests,
216
- passed: passedTests,
217
- failed: failedTests,
218
- successRate: totalTests > 0 ? (passedTests / totalTests) * 100 : 0,
219
- },
220
- };
221
-
222
- this.setCache(cacheKey, status);
223
- return status;
224
- }
225
-
226
- /**
227
- * Fetch builds from a specific CI provider
228
- */
229
- private async fetchBuildsFromProvider(
230
- _provider: CIProvider,
231
- packageName: string
232
- ): Promise<CIBuild[]> {
233
- // This is a mock implementation
234
- // In a real implementation, you would make API calls to the CI provider
235
-
236
- const mockBuilds: CIBuild[] = [
237
- {
238
- id: `build-${Date.now()}-1`,
239
- status: 'success',
240
- branch: 'main',
241
- commit: 'abc1234',
242
- commitMessage: `feat: update ${packageName}`,
243
- author: 'developer@example.com',
244
- startTime: new Date(Date.now() - 1000 * 60 * 30), // 30 minutes ago
245
- endTime: new Date(Date.now() - 1000 * 60 * 25), // 25 minutes ago
246
- duration: 5 * 60 * 1000, // 5 minutes
247
- url: `https://ci.example.com/builds/build-${Date.now()}-1`,
248
- packageName,
249
- workflowName: 'Build and Test',
250
- jobName: 'test',
251
- steps: [
252
- {
253
- name: 'Install dependencies',
254
- status: 'success',
255
- duration: 30000,
256
- },
257
- {
258
- name: 'Run tests',
259
- status: 'success',
260
- duration: 120000,
261
- },
262
- {
263
- name: 'Build package',
264
- status: 'success',
265
- duration: 60000,
266
- },
267
- ],
268
- coverage: {
269
- percentage: 85,
270
- lines: 1000,
271
- functions: 50,
272
- branches: 200,
273
- statements: 1200,
274
- },
275
- tests: {
276
- total: 150,
277
- passed: 145,
278
- failed: 0,
279
- skipped: 5,
280
- duration: 120000,
281
- suites: [
282
- {
283
- name: 'Unit Tests',
284
- status: 'pass',
285
- tests: [],
286
- duration: 80000,
287
- },
288
- {
289
- name: 'Integration Tests',
290
- status: 'pass',
291
- tests: [],
292
- duration: 40000,
293
- },
294
- ],
295
- },
296
- },
297
- {
298
- id: `build-${Date.now()}-2`,
299
- status: 'failed',
300
- branch: 'feature/new-feature',
301
- commit: 'def5678',
302
- commitMessage: `fix: resolve issue in ${packageName}`,
303
- author: 'developer@example.com',
304
- startTime: new Date(Date.now() - 1000 * 60 * 60 * 2), // 2 hours ago
305
- endTime: new Date(Date.now() - 1000 * 60 * 60 * 1.5), // 1.5 hours ago
306
- duration: 30 * 60 * 1000, // 30 minutes
307
- url: `https://ci.example.com/builds/build-${Date.now()}-2`,
308
- packageName,
309
- workflowName: 'Build and Test',
310
- jobName: 'test',
311
- steps: [
312
- {
313
- name: 'Install dependencies',
314
- status: 'success',
315
- duration: 30000,
316
- },
317
- {
318
- name: 'Run tests',
319
- status: 'failed',
320
- duration: 120000,
321
- error: 'Test suite failed with 3 failing tests',
322
- },
323
- ],
324
- tests: {
325
- total: 150,
326
- passed: 147,
327
- failed: 3,
328
- skipped: 0,
329
- duration: 120000,
330
- suites: [
331
- {
332
- name: 'Unit Tests',
333
- status: 'pass',
334
- tests: [],
335
- duration: 80000,
336
- },
337
- {
338
- name: 'Integration Tests',
339
- status: 'fail',
340
- tests: [],
341
- duration: 40000,
342
- },
343
- ],
344
- },
345
- },
346
- ];
347
-
348
- return mockBuilds;
349
- }
350
-
351
- /**
352
- * Calculate success rate from builds
353
- */
354
- private calculateSuccessRate(builds: CIBuild[]): number {
355
- if (builds.length === 0) return 0;
356
-
357
- const successfulBuilds = builds.filter(b => b.status === 'success').length;
358
- return (successfulBuilds / builds.length) * 100;
359
- }
360
-
361
- /**
362
- * Calculate average build duration
363
- */
364
- private calculateAverageDuration(builds: CIBuild[]): number {
365
- if (builds.length === 0) return 0;
366
-
367
- const completedBuilds = builds.filter(b => b.duration !== undefined);
368
- if (completedBuilds.length === 0) return 0;
369
-
370
- const totalDuration = completedBuilds.reduce(
371
- (sum, b) => sum + (b.duration || 0),
372
- 0
373
- );
374
- return totalDuration / completedBuilds.length;
375
- }
376
-
377
- /**
378
- * Determine if a package is healthy based on CI results
379
- */
380
- private determinePackageHealth(builds: CIBuild[]): boolean {
381
- if (builds.length === 0) return true;
382
-
383
- const recentBuilds = builds.slice(0, 5); // Last 5 builds
384
- const successRate = this.calculateSuccessRate(recentBuilds);
385
-
386
- return successRate >= 80; // 80% success rate threshold
387
- }
388
-
389
- /**
390
- * Identify issues from build results
391
- */
392
- private identifyIssues(builds: CIBuild[]): string[] {
393
- const issues: string[] = [];
394
-
395
- if (builds.length === 0) return issues;
396
-
397
- const recentBuilds = builds.slice(0, 3); // Last 3 builds
398
- const successRate = this.calculateSuccessRate(recentBuilds);
399
-
400
- if (successRate < 50) {
401
- issues.push('High failure rate in recent builds');
402
- }
403
-
404
- const failedBuilds = recentBuilds.filter(b => b.status === 'failed');
405
- for (const build of failedBuilds) {
406
- const failedSteps = build.steps.filter(s => s.status === 'failed');
407
- for (const step of failedSteps) {
408
- if (step.error) {
409
- issues.push(`Build step '${step.name}' failed: ${step.error}`);
410
- }
411
- }
412
- }
413
-
414
- // Check for long build times
415
- const avgDuration = this.calculateAverageDuration(recentBuilds);
416
- if (avgDuration > 10 * 60 * 1000) {
417
- // 10 minutes
418
- issues.push('Builds are taking longer than expected');
419
- }
420
-
421
- return issues;
422
- }
423
-
424
- /**
425
- * Get cache value if not expired
426
- */
427
- private getFromCache(key: string): any {
428
- const cached = this.cache.get(key);
429
- if (cached && Date.now() - cached.timestamp < this.cacheExpiry) {
430
- return cached.data;
431
- }
432
- return null;
433
- }
434
-
435
- /**
436
- * Set cache value with timestamp
437
- */
438
- private setCache(key: string, data: any): void {
439
- this.cache.set(key, {
440
- data,
441
- timestamp: Date.now(),
442
- });
443
- }
444
-
445
- /**
446
- * Clear the cache
447
- */
448
- clearCache(): void {
449
- this.cache.clear();
450
- }
451
-
452
- /**
453
- * Get build logs for a specific build
454
- */
455
- async getBuildLogs(buildId: string, providerName: string): Promise<string> {
456
- // Mock implementation
457
- return `Build logs for ${buildId} from ${providerName}\n\nStep 1: Install dependencies\n✓ Dependencies installed successfully\n\nStep 2: Run tests\n✓ All tests passed\n\nStep 3: Build package\n✓ Package built successfully`;
458
- }
459
-
460
- /**
461
- * Trigger a new build for a package
462
- */
463
- async triggerBuild(
464
- packageName: string,
465
- providerName: string,
466
- branch: string = 'main'
467
- ): Promise<{ success: boolean; buildId?: string; error?: string }> {
468
- try {
469
- // Mock implementation
470
- const buildId = `build-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
471
-
472
- AppLogger.info(
473
- `Triggering build for ${packageName} on ${branch} via ${providerName}`
474
- );
475
-
476
- return {
477
- success: true,
478
- buildId,
479
- };
480
- } catch (error) {
481
- return {
482
- success: false,
483
- error: error instanceof Error ? error.message : 'Unknown error',
484
- };
485
- }
486
- }
487
-
488
- /**
489
- * Get build artifacts
490
- */
491
- async getBuildArtifacts(
492
- buildId: string,
493
- _providerName: string
494
- ): Promise<CIArtifact[]> {
495
- // Mock implementation
496
- return [
497
- {
498
- name: 'coverage-report.html',
499
- type: 'coverage',
500
- size: 1024 * 50, // 50KB
501
- url: `https://ci.example.com/artifacts/${buildId}/coverage-report.html`,
502
- },
503
- {
504
- name: 'test-results.xml',
505
- type: 'test',
506
- size: 1024 * 10, // 10KB
507
- url: `https://ci.example.com/artifacts/${buildId}/test-results.xml`,
508
- },
509
- ];
510
- }
511
- }
512
-
513
- // Export default instance
514
- export const ciStatusManager = new CIStatusManager();
515
-
516
- // Export convenience functions
517
- export async function getPackageCIStatus(
518
- packageName: string
519
- ): Promise<CIPackageStatus | null> {
520
- return ciStatusManager.getPackageStatus(packageName);
521
- }
522
-
523
- export async function getMonorepoCIStatus(
524
- packages: PackageInfo[]
525
- ): Promise<CIMonorepoStatus> {
526
- return ciStatusManager.getMonorepoStatus(packages);
527
- }
528
-
529
- export async function triggerPackageBuild(
530
- packageName: string,
531
- providerName: string,
532
- branch?: string
533
- ): Promise<{ success: boolean; buildId?: string; error?: string }> {
534
- return ciStatusManager.triggerBuild(packageName, providerName, branch);
535
- }
@@ -1,92 +0,0 @@
1
- import type { PackageInfo, DependencyInfo, Commit } from '../types';
2
- import { AppLogger } from '../middleware/logger';
3
- import { CommitRepository, DependencyRepository, PackageRepository } from '../repositories';
4
- import { appConfig } from '../config-loader';
5
-
6
- // Default settings
7
- const DEFAULT_PORT = 8999;
8
- const port = appConfig.server.port ?? DEFAULT_PORT; //Default port
9
- const host = appConfig.server.host ?? 'localhost'; //Default host
10
-
11
- const API_BASE = `http://${host}:${port}/api`;
12
-
13
- async function getCommits(path: string): Promise<Commit[]> {
14
- const res = await fetch(API_BASE + `/commits/` + encodeURIComponent(path));
15
- if (!res.ok) throw new Error('Failed to fetch commits');
16
- return (await res.json()) as Commit[];
17
- }
18
-
19
- /**
20
- * Get package dependencies
21
- */
22
- function getPackageDependenciesInfo(pkg: PackageInfo): DependencyInfo[] {
23
- const allDeps: DependencyInfo[] = [];
24
- Object.keys(pkg.dependencies || {}).forEach(depName => {
25
- allDeps.push({
26
- name: depName,
27
- version: pkg.dependencies[depName],
28
- type: 'dependency',
29
- latest: '',
30
- outdated: false,
31
- });
32
- });
33
- Object.keys(pkg.devDependencies || {}).forEach(depName => {
34
- allDeps.push({
35
- name: depName,
36
- version: pkg.devDependencies[depName],
37
- type: 'devDependency',
38
- latest: '',
39
- outdated: false,
40
- });
41
- });
42
- Object.keys(pkg.peerDependencies || {}).forEach(depName => {
43
- allDeps.push({
44
- name: depName,
45
- version: pkg.peerDependencies[depName]!,
46
- type: 'peerDependency',
47
- latest: '',
48
- outdated: false,
49
- });
50
- });
51
- return allDeps;
52
- }
53
-
54
- /**
55
- * Store packages in database using repository pattern
56
- */
57
- async function storePackage(pkg: PackageInfo): Promise<void> {
58
- try {
59
- // Create or update package using repository
60
- await PackageRepository.upsert({
61
- name: pkg.name,
62
- version: pkg.version,
63
- type: pkg.type,
64
- path: pkg.path,
65
- description: pkg.description,
66
- license: pkg.license,
67
- repository: pkg.repository,
68
- scripts: pkg.scripts,
69
- dependencies: pkg.dependencies,
70
- devDependencies: pkg.devDependencies,
71
- peerDependencies: pkg.peerDependencies,
72
- maintainers: pkg.maintainers.join(','),
73
- status: '',
74
- });
75
-
76
- // Store commits using repository
77
- const commits = await getCommits(pkg.path ?? '');
78
- if (commits.length) {
79
- await CommitRepository.storeMany(pkg.name, commits);
80
- }
81
-
82
- // Store dependencies using repository
83
- const dependenciesInfo = getPackageDependenciesInfo(pkg);
84
- if (dependenciesInfo.length) {
85
- await DependencyRepository.storeMany(pkg.name, dependenciesInfo);
86
- }
87
- } catch (error) {
88
- AppLogger.warn(`Failed to store report for ${pkg.name}`);
89
- }
90
- }
91
-
92
- export { storePackage };
@@ -1,67 +0,0 @@
1
- import type { PackageHealth } from '../types';
2
-
3
- /**
4
- * Calculates package health score based on various metrics
5
- */
6
- function calculatePackageHealth(
7
- buildStatus: PackageHealth['buildStatus'],
8
- testCoverage: number,
9
- lintStatus: PackageHealth['lintStatus'],
10
- securityAudit: PackageHealth['securityAudit']
11
- ): PackageHealth {
12
- let score = 0;
13
-
14
- // Build status (30 points)
15
- switch (buildStatus) {
16
- case 'success':
17
- score += 30;
18
- break;
19
- case 'running':
20
- score += 15;
21
- break;
22
- case 'failed':
23
- score += 0;
24
- break;
25
- default:
26
- score += 10;
27
- }
28
-
29
- // Test coverage (25 points)
30
- score += Math.min(25, (testCoverage / 100) * 25);
31
-
32
- // Lint status (25 points)
33
- switch (lintStatus) {
34
- case 'pass':
35
- score += 25;
36
- break;
37
- case 'fail':
38
- score += 0;
39
- break;
40
- default:
41
- score += 10;
42
- }
43
-
44
- // Security audit (20 points)
45
- switch (securityAudit) {
46
- case 'pass':
47
- score += 20;
48
- break;
49
- case 'fail':
50
- score += 0;
51
- break;
52
- default:
53
- score += 10;
54
- }
55
-
56
- return {
57
- buildStatus,
58
- testCoverage,
59
- lintStatus,
60
- securityAudit,
61
- overallScore: Math.round(score),
62
- };
63
- }
64
-
65
- export {
66
- calculatePackageHealth,
67
- };