@manojkmfsi/monodog 1.0.23 → 1.0.25

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 (74) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/controllers/{commitController.js → commit-controller.js} +5 -4
  4. package/dist/controllers/{configController.js → config-controller.js} +3 -3
  5. package/dist/controllers/{healthController.js → health-controller.js} +3 -3
  6. package/dist/controllers/{packageController.js → package-controller.js} +6 -6
  7. package/dist/index.js +11 -236
  8. package/dist/middleware/dashboard-startup.js +124 -0
  9. package/dist/middleware/error-handler.js +36 -0
  10. package/dist/middleware/index.js +23 -0
  11. package/dist/middleware/logger.js +63 -0
  12. package/dist/middleware/security.js +78 -0
  13. package/dist/middleware/server-startup.js +117 -0
  14. package/dist/repositories/commit-repository.js +97 -0
  15. package/dist/repositories/dependency-repository.js +97 -0
  16. package/dist/repositories/index.js +18 -0
  17. package/dist/repositories/package-health-repository.js +65 -0
  18. package/dist/repositories/package-repository.js +126 -0
  19. package/dist/repositories/prisma-client.js +57 -0
  20. package/dist/routes/{commitRoutes.js → commit-routes.js} +2 -2
  21. package/dist/routes/{configRoutes.js → config-routes.js} +3 -3
  22. package/dist/routes/{healthRoutes.js → health-routes.js} +3 -3
  23. package/dist/routes/{packageRoutes.js → package-routes.js} +5 -5
  24. package/dist/serve.js +15 -2
  25. package/dist/services/{commitService.js → commit-service.js} +2 -2
  26. package/dist/services/{configService.js → config-service.js} +2 -40
  27. package/dist/services/{healthService.js → health-service.js} +11 -63
  28. package/dist/services/{packageService.js → package-service.js} +80 -54
  29. package/dist/types/git.js +11 -0
  30. package/dist/types/index.js +1 -0
  31. package/package.json +10 -3
  32. package/prisma/schema/commit.prisma +11 -0
  33. package/prisma/schema/dependency-info.prisma +12 -0
  34. package/prisma/schema/health-status.prisma +14 -0
  35. package/prisma/schema/package-health.prisma +15 -0
  36. package/prisma/schema/package.prisma +21 -0
  37. package/prisma/schema/schema.prisma +15 -0
  38. package/src/controllers/{commitController.ts → commit-controller.ts} +7 -5
  39. package/src/controllers/{configController.ts → config-controller.ts} +4 -3
  40. package/src/controllers/{healthController.ts → health-controller.ts} +4 -3
  41. package/src/controllers/{packageController.ts → package-controller.ts} +7 -6
  42. package/src/index.ts +9 -281
  43. package/src/middleware/dashboard-startup.ts +149 -0
  44. package/src/middleware/error-handler.ts +50 -0
  45. package/src/middleware/index.ts +20 -0
  46. package/src/middleware/logger.ts +58 -0
  47. package/src/middleware/security.ts +81 -0
  48. package/src/middleware/server-startup.ts +142 -0
  49. package/src/repositories/commit-repository.ts +107 -0
  50. package/src/repositories/dependency-repository.ts +109 -0
  51. package/src/repositories/index.ts +10 -0
  52. package/src/repositories/package-health-repository.ts +75 -0
  53. package/src/repositories/package-repository.ts +142 -0
  54. package/src/repositories/prisma-client.ts +25 -0
  55. package/src/routes/{commitRoutes.ts → commit-routes.ts} +1 -1
  56. package/src/routes/{configRoutes.ts → config-routes.ts} +1 -1
  57. package/src/routes/{healthRoutes.ts → health-routes.ts} +1 -1
  58. package/src/routes/{packageRoutes.ts → package-routes.ts} +1 -1
  59. package/src/serve.ts +19 -3
  60. package/src/services/{commitService.ts → commit-service.ts} +1 -1
  61. package/src/services/{configService.ts → config-service.ts} +22 -9
  62. package/src/services/{gitService.ts → git-service.ts} +4 -4
  63. package/src/services/{healthService.ts → health-service.ts} +17 -35
  64. package/src/services/package-service.ts +201 -0
  65. package/src/types/database.ts +57 -1
  66. package/src/types/git.ts +8 -8
  67. package/src/types/index.ts +1 -1
  68. package/dist/utils/db-utils.js +0 -227
  69. package/prisma/schema.prisma +0 -116
  70. package/src/services/packageService.ts +0 -115
  71. package/src/types/monorepo-scanner.d.ts +0 -32
  72. package/src/utils/db-utils.ts +0 -220
  73. /package/dist/services/{gitService.js → git-service.js} +0 -0
  74. /package/prisma/migrations/{20251219074511_create_unique_composite_key_for_commits → 20251219090102_composite_key_for_table_commits}/migration.sql +0 -0
@@ -1,9 +1,25 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
 
4
- import * as PrismaPkg from '@prisma/client';
5
- const PrismaClient = (PrismaPkg as any).PrismaClient || (PrismaPkg as any).default || PrismaPkg;
6
- const prisma = new PrismaClient();
4
+ import { PackageRepository } from '../repositories';
5
+
6
+ /**
7
+ * Configuration file interface
8
+ */
9
+ interface ConfigFile {
10
+ id: string;
11
+ name: string;
12
+ path: string;
13
+ type: string;
14
+ content: string;
15
+ size: number;
16
+ lastModified: string;
17
+ hasSecrets: boolean;
18
+ }
19
+
20
+ interface TransformedConfigFile extends ConfigFile {
21
+ isEditable: boolean;
22
+ }
7
23
 
8
24
  // Helper function to scan for configuration files
9
25
  async function scanConfigFiles(rootDir: string): Promise<any[]> {
@@ -36,7 +52,7 @@ async function scanConfigFiles(rootDir: string): Promise<any[]> {
36
52
  'dockerfile*',
37
53
  ];
38
54
 
39
- const configFiles: any[] = [];
55
+ const configFiles: ConfigFile[] = [];
40
56
  const scannedPaths = new Set();
41
57
 
42
58
  function scanDirectory(dir: string, depth = 0) {
@@ -325,7 +341,7 @@ export const updatePackageConfigurationService = async (packagePath: string, pac
325
341
  await fs.promises.writeFile(packageJsonPath, formattedConfig, 'utf8');
326
342
 
327
343
  // Update the package in the database - use correct field names based on your Prisma schema
328
- const updateData: any = {
344
+ const updateData: Record<string, unknown> = {
329
345
  lastUpdated: new Date(),
330
346
  };
331
347
 
@@ -348,10 +364,7 @@ export const updatePackageConfigurationService = async (packagePath: string, pac
348
364
 
349
365
  console.log('Updating database with:', updateData);
350
366
 
351
- const updatedPackage = await prisma.package.update({
352
- where: { name: packageName },
353
- data: updateData,
354
- });
367
+ const updatedPackage = await PackageRepository.updateConfig(packageName, updateData);
355
368
 
356
369
  // Transform the response
357
370
  const transformedPackage = {
@@ -9,7 +9,7 @@ import { exec } from 'child_process';
9
9
  import { promisify } from 'util';
10
10
  import path from 'path';
11
11
 
12
- import type { GitCommit } from '../types';
12
+ import type { Commit } from '../types';
13
13
  import { VALID_COMMIT_TYPES } from '../types';
14
14
 
15
15
  // Promisify the standard 'exec' function for easy async/await usage
@@ -25,7 +25,7 @@ export class GitService {
25
25
  /**
26
26
  * Retrieves commit history for the repository, optionally filtered by a package path.
27
27
  */
28
- public async getAllCommits(pathFilter?: string): Promise<GitCommit[]> {
28
+ public async getAllCommits(pathFilter?: string): Promise<Commit[]> {
29
29
  try {
30
30
 
31
31
  let pathArgument = '';
@@ -60,14 +60,14 @@ export class GitService {
60
60
  }
61
61
 
62
62
  // Parse the output
63
- const commits: GitCommit[] = [];
63
+ const commits: Commit[] = [];
64
64
  const lines = stdout.trim().split('\n');
65
65
 
66
66
  for (const line of lines) {
67
67
  try {
68
68
  const [hash, author, date, message] = line.split('|');
69
69
 
70
- const commit: GitCommit = {
70
+ const commit: Commit = {
71
71
  hash: hash.trim(),
72
72
  author: author.trim(),
73
73
  packageName: pathFilter || 'root',
@@ -9,16 +9,15 @@ import {
9
9
  funCheckSecurityAudit,
10
10
  } from '../utils/monorepo-scanner';
11
11
 
12
- import * as PrismaPkg from '@prisma/client';
13
- const PrismaClient = (PrismaPkg as any).PrismaClient || (PrismaPkg as any).default || PrismaPkg;
14
- const prisma = new PrismaClient();
12
+ import { PackageHealthRepository, PackageRepository } from '../repositories';
13
+ import type { TransformedPackageHealth, HealthResponse, PackageHealthModel } from '../types/database';
15
14
 
16
- export const getHealthSummaryService = async () => {
17
- const packageHealthData = await prisma.packageHealth.findMany();
15
+ export const getHealthSummaryService = async (): Promise<HealthResponse> => {
16
+ const packageHealthData = await PackageHealthRepository.findAll() as PackageHealthModel[];
18
17
  console.log('packageHealthData -->', packageHealthData.length);
19
18
 
20
19
  // Transform the data to match the expected frontend format
21
- const packages = packageHealthData.map((pkg: any) => {
20
+ const packages = packageHealthData.map((pkg: PackageHealthModel) => {
22
21
  const health = {
23
22
  buildStatus: pkg.packageBuildStatus,
24
23
  testCoverage: pkg.packageTestCoverage,
@@ -36,11 +35,11 @@ export const getHealthSummaryService = async () => {
36
35
 
37
36
  // Calculate summary statistics
38
37
  const total = packages.length;
39
- const healthy = packages.filter((pkg: any) => pkg.isHealthy).length;
40
- const unhealthy = packages.filter((pkg: any) => !pkg.isHealthy).length;
38
+ const healthy = packages.filter((pkg: TransformedPackageHealth) => pkg.isHealthy).length;
39
+ const unhealthy = packages.filter((pkg: TransformedPackageHealth) => !pkg.isHealthy).length;
41
40
  const averageScore =
42
41
  packages.length > 0
43
- ? packages.reduce((sum: any, pkg: any) => sum + pkg.health.overallScore, 0) /
42
+ ? packages.reduce((sum: number, pkg: TransformedPackageHealth) => sum + pkg.health.overallScore, 0) /
44
43
  packages.length
45
44
  : 0;
46
45
 
@@ -90,34 +89,17 @@ export const healthRefreshService = async (rootDir: string) => {
90
89
 
91
90
  console.log(pkg.name, '-->', health, packageStatus);
92
91
 
93
- await prisma.packageHealth.upsert({
94
- where: {
95
- packageName: pkg.name,
96
- },
97
- update: {
98
- packageOverallScore: overallScore.overallScore,
99
- packageBuildStatus: buildStatus,
100
- packageTestCoverage: testCoverage,
101
- packageLintStatus: lintStatus,
102
- packageSecurity: securityAudit,
103
- packageDependencies: '',
104
- updatedAt: new Date()
105
- },
106
- create: {
107
- packageName: pkg.name,
108
- packageOverallScore: overallScore.overallScore,
109
- packageBuildStatus: buildStatus,
110
- packageTestCoverage: testCoverage,
111
- packageLintStatus: lintStatus,
112
- packageSecurity: securityAudit,
113
- packageDependencies: '',
114
- },
92
+ await PackageHealthRepository.upsert({
93
+ packageName: pkg.name,
94
+ packageOverallScore: overallScore.overallScore,
95
+ packageBuildStatus: buildStatus,
96
+ packageTestCoverage: testCoverage,
97
+ packageLintStatus: lintStatus,
98
+ packageSecurity: securityAudit,
99
+ packageDependencies: '',
115
100
  });
116
101
  // update related package status as well
117
- await prisma.package.update({
118
- where: { name: pkg.name },
119
- data: { status: packageStatus },
120
- });
102
+ await PackageRepository.updateStatus(pkg.name, packageStatus);
121
103
  return {
122
104
  packageName: pkg.name,
123
105
  health,
@@ -0,0 +1,201 @@
1
+ import { scanMonorepo } from '../utils/utilities';
2
+ import { generateReports } from '../utils/monorepo-scanner';
3
+ import { ciStatusManager } from '../utils/ci-status';
4
+ import { PackageRepository, CommitRepository, DependencyRepository } from '../repositories';
5
+ import type { PackageInfo, DependencyInfo, PackageReport } from '../types';
6
+ import { getCommitsByPathService } from './commit-service';
7
+ import type { PackageModel } from '../types/database';
8
+
9
+ interface TransformedPackage {
10
+ name: string;
11
+ version?: string;
12
+ type?: string;
13
+ path?: string;
14
+ description?: string;
15
+ license?: string;
16
+ repository: Record<string, unknown>;
17
+ scripts: Record<string, unknown>;
18
+ dependencies: Record<string, unknown>;
19
+ devDependencies: Record<string, unknown>;
20
+ peerDependencies: Record<string, unknown>;
21
+ maintainers: string[];
22
+ status?: string;
23
+ createdAt?: Date;
24
+ lastUpdated?: Date;
25
+ }
26
+
27
+ interface PackageDetail extends TransformedPackage {
28
+ report?: PackageReport;
29
+ ciStatus?: Record<string, unknown>;
30
+ }
31
+
32
+ /**
33
+ * Get package dependencies
34
+ */
35
+ function getPackageDependenciesInfo(pkg: PackageInfo): DependencyInfo[] {
36
+ const allDeps: DependencyInfo[] = [];
37
+ Object.keys(pkg.dependencies || {}).forEach(depName => {
38
+ allDeps.push({
39
+ name: depName,
40
+ version: pkg.dependencies[depName],
41
+ type: 'dependency',
42
+ latest: '',
43
+ outdated: false,
44
+ });
45
+ });
46
+ Object.keys(pkg.devDependencies || {}).forEach(depName => {
47
+ allDeps.push({
48
+ name: depName,
49
+ version: pkg.devDependencies[depName],
50
+ type: 'devDependency',
51
+ latest: '',
52
+ outdated: false,
53
+ });
54
+ });
55
+ Object.keys(pkg.peerDependencies || {}).forEach(depName => {
56
+ allDeps.push({
57
+ name: depName,
58
+ version: pkg.peerDependencies[depName]!,
59
+ type: 'peerDependency',
60
+ latest: '',
61
+ outdated: false,
62
+ });
63
+ });
64
+ return allDeps;
65
+ }
66
+
67
+ /**
68
+ * Store packages in database using repository pattern
69
+ */
70
+ async function storePackage(pkg: PackageInfo): Promise<void> {
71
+ try {
72
+ // Create or update package using repository
73
+ await PackageRepository.upsert({
74
+ name: pkg.name,
75
+ version: pkg.version,
76
+ type: pkg.type,
77
+ path: pkg.path,
78
+ description: pkg.description,
79
+ license: pkg.license,
80
+ repository: pkg.repository,
81
+ scripts: pkg.scripts,
82
+ dependencies: pkg.dependencies,
83
+ devDependencies: pkg.devDependencies,
84
+ peerDependencies: pkg.peerDependencies,
85
+ maintainers: pkg.maintainers.join(','),
86
+ status: '',
87
+ });
88
+
89
+ // Store commits using repository
90
+ const commits = await getCommitsByPathService(pkg.path ?? '');
91
+ if (commits.length) {
92
+ await CommitRepository.storeMany(pkg.name, commits);
93
+ }
94
+
95
+ // Store dependencies using repository
96
+ const dependenciesInfo = getPackageDependenciesInfo(pkg);
97
+ if (dependenciesInfo.length) {
98
+ await DependencyRepository.storeMany(pkg.name, dependenciesInfo);
99
+ }
100
+ } catch (error) {
101
+ console.warn(` Failed to store report for ${pkg.name}:`, error);
102
+ }
103
+ }
104
+
105
+ export const getPackagesService = async (rootPath: string) => {
106
+ let dbPackages = await PackageRepository.findAll();
107
+ if (!dbPackages.length) {
108
+ try {
109
+ const rootDir = rootPath;
110
+ console.log('rootDir -->', rootDir);
111
+ const packages = scanMonorepo(rootDir);
112
+ console.log('packages --> scan', packages.length);
113
+ for (const pkg of packages) {
114
+ await storePackage(pkg);
115
+ }
116
+ } catch (error) {
117
+ throw new Error('Error ' + error);
118
+ }
119
+ dbPackages = await PackageRepository.findAll();
120
+ }
121
+ const transformedPackages = dbPackages.map((pkg: PackageModel) => {
122
+ // We create a new object 'transformedPkg' based on the database record 'pkg'
123
+ const transformedPkg = { ...pkg };
124
+
125
+ // 1. Maintainers
126
+ transformedPkg.maintainers = pkg.maintainers
127
+ ? JSON.parse(pkg.maintainers)
128
+ : [];
129
+
130
+ // 2. Scripts/repository (should default to an object, not an array)
131
+ transformedPkg.scripts = pkg.scripts ? JSON.parse(pkg.scripts) : {};
132
+ transformedPkg.repository = pkg.repository
133
+ ? JSON.parse(pkg.repository)
134
+ : {};
135
+
136
+ // 3. Dependencies List
137
+ transformedPkg.dependencies = pkg.dependencies
138
+ ? JSON.parse(pkg.dependencies)
139
+ : [];
140
+ transformedPkg.devDependencies = pkg.devDependencies
141
+ ? JSON.parse(pkg.devDependencies)
142
+ : [];
143
+ transformedPkg.peerDependencies = pkg.peerDependencies
144
+ ? JSON.parse(pkg.peerDependencies)
145
+ : [];
146
+ return transformedPkg; // Return the fully transformed object
147
+ });
148
+
149
+ return transformedPackages;
150
+ }
151
+
152
+ export const refreshPackagesService = async (rootPath: string) => {
153
+ await PackageRepository.deleteAll();
154
+
155
+ const rootDir = rootPath;
156
+ const packages = scanMonorepo(rootDir);
157
+
158
+ console.log('packages -->', packages.length);
159
+ for (const pkg of packages) {
160
+ await storePackage(pkg);
161
+ }
162
+
163
+ return packages;
164
+ }
165
+
166
+ export const getPackageDetailService = async (name: string) => {
167
+
168
+ const pkg = await PackageRepository.findByNameWithRelations(name);
169
+ if (!pkg) {
170
+ return null;
171
+ }
172
+ const transformedPkg = { ...pkg };
173
+
174
+ transformedPkg.scripts = pkg.scripts ? JSON.parse(pkg.scripts) : {};
175
+ transformedPkg.repository = pkg.repository
176
+ ? JSON.parse(pkg.repository)
177
+ : {};
178
+
179
+ transformedPkg.dependencies = pkg.dependencies
180
+ ? JSON.parse(pkg.dependencies)
181
+ : [];
182
+ transformedPkg.devDependencies = pkg.devDependencies
183
+ ? JSON.parse(pkg.devDependencies)
184
+ : [];
185
+ transformedPkg.peerDependencies = pkg.peerDependencies
186
+ ? JSON.parse(pkg.peerDependencies)
187
+ : [];
188
+
189
+ // Get additional package information
190
+ const reports = (await generateReports()) as unknown as PackageReport[] | undefined;
191
+ const packageReport = reports?.find((r: PackageReport) => r.package?.name === name);
192
+
193
+ const result: PackageDetail = {
194
+ ...transformedPkg,
195
+ report: packageReport,
196
+ ciStatus: await ciStatusManager.getPackageStatus(name),
197
+ };
198
+
199
+ return result;
200
+
201
+ }
@@ -6,6 +6,62 @@ export interface Commit {
6
6
  hash: string;
7
7
  message?: string;
8
8
  author?: string;
9
- date?: string;
9
+ date: Date;
10
10
  type?: string;
11
+ packageName: string;
11
12
  }
13
+
14
+ export interface PackageHealthModel {
15
+ packageName: string;
16
+ packageOverallScore: number;
17
+ packageBuildStatus: string;
18
+ packageTestCoverage: number;
19
+ packageLintStatus: string;
20
+ packageSecurity: string;
21
+ packageDependencies?: string;
22
+ updatedAt?: Date;
23
+ }
24
+
25
+ export interface TransformedPackageHealth {
26
+ packageName: string;
27
+ health: {
28
+ buildStatus: string;
29
+ testCoverage: number;
30
+ lintStatus: string;
31
+ securityAudit: string;
32
+ overallScore: number;
33
+ };
34
+ isHealthy: boolean;
35
+ }
36
+
37
+ export interface HealthSummary {
38
+ total: number;
39
+ healthy: number;
40
+ unhealthy: number;
41
+ averageScore: number;
42
+ }
43
+
44
+ export interface HealthResponse {
45
+ packages: TransformedPackageHealth[];
46
+ summary: HealthSummary;
47
+ }
48
+
49
+ export interface PackageModel {
50
+ name: string;
51
+ version?: string;
52
+ type?: string;
53
+ path?: string;
54
+ description?: string;
55
+ license?: string;
56
+ repository?: string;
57
+ scripts?: string;
58
+ dependencies?: string;
59
+ devDependencies?: string;
60
+ peerDependencies?: string;
61
+ maintainers?: string;
62
+ status?: string;
63
+ createdAt?: Date;
64
+ lastUpdated?: Date;
65
+ }
66
+
67
+ export type ConfigUpdateData = Record<string, unknown>;
package/src/types/git.ts CHANGED
@@ -5,14 +5,14 @@
5
5
  /**
6
6
  * Interface representing a single commit object with key metadata.
7
7
  */
8
- export interface GitCommit {
9
- hash: string;
10
- author: string;
11
- packageName: string;
12
- date: Date;
13
- message: string;
14
- type: string;
15
- }
8
+ // export interface GitCommit {
9
+ // hash: string;
10
+ // author: string;
11
+ // packageName: string;
12
+ // date: Date;
13
+ // message: string;
14
+ // type: string;
15
+ // }
16
16
 
17
17
  /**
18
18
  * List of standard Conventional Commit types for validation.
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  export type { MonodogConfig } from './config';
6
- export type { GitCommit } from './git';
6
+ // export type { GitCommit } from './git';
7
7
  export { VALID_COMMIT_TYPES } from './git';
8
8
  export type { PackageInfo, DependencyInfo, MonorepoStats } from './package';
9
9
  export type { PackageHealth } from './health';