@ebowwa/dependency-graph 1.0.1 → 1.0.2
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/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/package.json +10 -3
- package/src/cli.ts +179 -0
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @ebowwa/dependency-graph CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* check-workspace - Check for workspace:* usage
|
|
7
|
+
* check-versions - Compare local versions with npm
|
|
8
|
+
* check-unused - Find unused packages
|
|
9
|
+
* graph - Output dependency graph
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @ebowwa/dependency-graph CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* check-workspace - Check for workspace:* usage
|
|
7
|
+
* check-versions - Compare local versions with npm
|
|
8
|
+
* check-unused - Find unused packages
|
|
9
|
+
* graph - Output dependency graph
|
|
10
|
+
*/
|
|
11
|
+
import { DependencyGraphBuilder, findUnusedPackages, formatGraph } from './index.js';
|
|
12
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
async function checkWorkspace() {
|
|
18
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
19
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
20
|
+
const issues = [];
|
|
21
|
+
// Find workspace:* in package.json files
|
|
22
|
+
for (const [name, node] of graph.nodes) {
|
|
23
|
+
if (node.type !== 'workspace')
|
|
24
|
+
continue;
|
|
25
|
+
const pkgPath = join(cwd, node.path, 'package.json');
|
|
26
|
+
if (!existsSync(pkgPath))
|
|
27
|
+
continue;
|
|
28
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
29
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
30
|
+
for (const depType of depTypes) {
|
|
31
|
+
const deps = pkg[depType];
|
|
32
|
+
if (!deps)
|
|
33
|
+
continue;
|
|
34
|
+
for (const [depName, version] of Object.entries(deps)) {
|
|
35
|
+
if (version.startsWith('workspace:')) {
|
|
36
|
+
issues.push({
|
|
37
|
+
package: name,
|
|
38
|
+
path: node.path,
|
|
39
|
+
dependency: depName,
|
|
40
|
+
version
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (issues.length === 0) {
|
|
47
|
+
console.log(JSON.stringify({ success: true, issues: [] }));
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
console.log(JSON.stringify({ success: false, issues }));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
async function checkVersions() {
|
|
54
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
55
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
56
|
+
const issues = [];
|
|
57
|
+
for (const [name, node] of graph.nodes) {
|
|
58
|
+
if (node.type !== 'workspace')
|
|
59
|
+
continue;
|
|
60
|
+
if (!node.version)
|
|
61
|
+
continue;
|
|
62
|
+
// Only check @ebowwa packages
|
|
63
|
+
if (!name.startsWith('@ebowwa/'))
|
|
64
|
+
continue;
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(`https://registry.npmjs.org/${name}/latest`);
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
// Package not published yet
|
|
69
|
+
issues.push({
|
|
70
|
+
package: name,
|
|
71
|
+
localVersion: node.version,
|
|
72
|
+
npmVersion: 'none',
|
|
73
|
+
needsPublish: true
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const data = await response.json();
|
|
78
|
+
const npmVersion = data.version;
|
|
79
|
+
if (node.version !== npmVersion) {
|
|
80
|
+
issues.push({
|
|
81
|
+
package: name,
|
|
82
|
+
localVersion: node.version,
|
|
83
|
+
npmVersion,
|
|
84
|
+
needsPublish: true
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Network error, skip
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (issues.length === 0) {
|
|
93
|
+
console.log(JSON.stringify({ success: true, issues: [] }));
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
console.log(JSON.stringify({ success: false, issues }));
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
async function checkUnused() {
|
|
100
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
101
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
102
|
+
const unused = findUnusedPackages(graph, false);
|
|
103
|
+
if (unused.length === 0) {
|
|
104
|
+
console.log(JSON.stringify({ success: true, unused: [] }));
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
console.log(JSON.stringify({ success: false, unused }));
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
async function outputGraph() {
|
|
111
|
+
const format = args[1] || 'json';
|
|
112
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
113
|
+
const graph = await builder.build({ analyzeImports: true });
|
|
114
|
+
const output = formatGraph(graph, format);
|
|
115
|
+
console.log(output);
|
|
116
|
+
}
|
|
117
|
+
async function main() {
|
|
118
|
+
switch (command) {
|
|
119
|
+
case 'check-workspace':
|
|
120
|
+
await checkWorkspace();
|
|
121
|
+
break;
|
|
122
|
+
case 'check-versions':
|
|
123
|
+
await checkVersions();
|
|
124
|
+
break;
|
|
125
|
+
case 'check-unused':
|
|
126
|
+
await checkUnused();
|
|
127
|
+
break;
|
|
128
|
+
case 'graph':
|
|
129
|
+
await outputGraph();
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
console.log(`Usage: dependency-graph <command>
|
|
133
|
+
|
|
134
|
+
Commands:
|
|
135
|
+
check-workspace Check for workspace:* usage (exits 1 if found)
|
|
136
|
+
check-versions Compare local versions with npm (exits 1 if mismatch)
|
|
137
|
+
check-unused Find unused packages (exits 1 if found)
|
|
138
|
+
graph [format] Output dependency graph (json, mermaid, dot, tree)
|
|
139
|
+
|
|
140
|
+
Output: JSON to stdout for programmatic use`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
main().catch(console.error);
|
|
145
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,EAAE,sBAAsB,EAA4B,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAgB1B,KAAK,UAAU,cAAc;IAC3B,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,yCAAyC;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAExC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,CAAU,CAAC;QAElF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA8B,CAAC,EAAE,CAAC;gBAChF,IAAI,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC;wBACV,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,UAAU,EAAE,OAAO;wBACnB,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACxC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,SAAS;QAE5B,8BAA8B;QAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QAE3C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,8BAA8B,IAAI,SAAS,CAAC,CAAC;YAC1E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,4BAA4B;gBAC5B,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,IAAI;oBACb,YAAY,EAAE,IAAI,CAAC,OAAO;oBAC1B,UAAU,EAAE,MAAM;oBAClB,YAAY,EAAE,IAAI;iBACnB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,UAAU,GAAI,IAA4B,CAAC,OAAO,CAAC;YAEzD,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,IAAI;oBACb,YAAY,EAAE,IAAI,CAAC,OAAO;oBAC1B,UAAU;oBACV,YAAY,EAAE,IAAI;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEhD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,MAA6C,CAAC,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,iBAAiB;YACpB,MAAM,cAAc,EAAE,CAAC;YACvB,MAAM;QACR,KAAK,gBAAgB;YACnB,MAAM,aAAa,EAAE,CAAC;YACtB,MAAM;QACR,KAAK,cAAc;YACjB,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,OAAO;YACV,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR;YACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;4CAQ0B,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebowwa/dependency-graph",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Core dependency graph analysis and visualization for monorepos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"dependency-graph": "./dist/cli.js"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"import": "./dist/index.js",
|
|
@@ -12,8 +15,12 @@
|
|
|
12
15
|
}
|
|
13
16
|
},
|
|
14
17
|
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
16
|
-
"dev": "tsc --watch"
|
|
18
|
+
"build": "tsc && chmod +x dist/cli.js",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"bump:patch": "npm version patch --no-git-tag-version && bun run build",
|
|
21
|
+
"bump:minor": "npm version minor --no-git-tag-version && bun run build",
|
|
22
|
+
"bump:major": "npm version major --no-git-tag-version && bun run build",
|
|
23
|
+
"prepublishOnly": "bun run build"
|
|
17
24
|
},
|
|
18
25
|
"files": [
|
|
19
26
|
"dist",
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @ebowwa/dependency-graph CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* check-workspace - Check for workspace:* usage
|
|
7
|
+
* check-versions - Compare local versions with npm
|
|
8
|
+
* check-unused - Find unused packages
|
|
9
|
+
* graph - Output dependency graph
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { DependencyGraphBuilder, findCircularDependencies, findUnusedPackages, formatGraph } from './index.js';
|
|
13
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const command = args[0];
|
|
18
|
+
const cwd = process.cwd();
|
|
19
|
+
|
|
20
|
+
interface WorkspaceIssue {
|
|
21
|
+
package: string;
|
|
22
|
+
path: string;
|
|
23
|
+
dependency: string;
|
|
24
|
+
version: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface VersionIssue {
|
|
28
|
+
package: string;
|
|
29
|
+
localVersion: string;
|
|
30
|
+
npmVersion: string;
|
|
31
|
+
needsPublish: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function checkWorkspace(): Promise<void> {
|
|
35
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
36
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
37
|
+
|
|
38
|
+
const issues: WorkspaceIssue[] = [];
|
|
39
|
+
|
|
40
|
+
// Find workspace:* in package.json files
|
|
41
|
+
for (const [name, node] of graph.nodes) {
|
|
42
|
+
if (node.type !== 'workspace') continue;
|
|
43
|
+
|
|
44
|
+
const pkgPath = join(cwd, node.path, 'package.json');
|
|
45
|
+
if (!existsSync(pkgPath)) continue;
|
|
46
|
+
|
|
47
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
48
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'] as const;
|
|
49
|
+
|
|
50
|
+
for (const depType of depTypes) {
|
|
51
|
+
const deps = pkg[depType];
|
|
52
|
+
if (!deps) continue;
|
|
53
|
+
|
|
54
|
+
for (const [depName, version] of Object.entries(deps as Record<string, string>)) {
|
|
55
|
+
if (version.startsWith('workspace:')) {
|
|
56
|
+
issues.push({
|
|
57
|
+
package: name,
|
|
58
|
+
path: node.path,
|
|
59
|
+
dependency: depName,
|
|
60
|
+
version
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (issues.length === 0) {
|
|
68
|
+
console.log(JSON.stringify({ success: true, issues: [] }));
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log(JSON.stringify({ success: false, issues }));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function checkVersions(): Promise<void> {
|
|
77
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
78
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
79
|
+
|
|
80
|
+
const issues: VersionIssue[] = [];
|
|
81
|
+
|
|
82
|
+
for (const [name, node] of graph.nodes) {
|
|
83
|
+
if (node.type !== 'workspace') continue;
|
|
84
|
+
if (!node.version) continue;
|
|
85
|
+
|
|
86
|
+
// Only check @ebowwa packages
|
|
87
|
+
if (!name.startsWith('@ebowwa/')) continue;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const response = await fetch(`https://registry.npmjs.org/${name}/latest`);
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
// Package not published yet
|
|
93
|
+
issues.push({
|
|
94
|
+
package: name,
|
|
95
|
+
localVersion: node.version,
|
|
96
|
+
npmVersion: 'none',
|
|
97
|
+
needsPublish: true
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const data = await response.json();
|
|
103
|
+
const npmVersion = (data as { version: string }).version;
|
|
104
|
+
|
|
105
|
+
if (node.version !== npmVersion) {
|
|
106
|
+
issues.push({
|
|
107
|
+
package: name,
|
|
108
|
+
localVersion: node.version,
|
|
109
|
+
npmVersion,
|
|
110
|
+
needsPublish: true
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
// Network error, skip
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (issues.length === 0) {
|
|
119
|
+
console.log(JSON.stringify({ success: true, issues: [] }));
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log(JSON.stringify({ success: false, issues }));
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function checkUnused(): Promise<void> {
|
|
128
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
129
|
+
const graph = await builder.build({ analyzeImports: false });
|
|
130
|
+
|
|
131
|
+
const unused = findUnusedPackages(graph, false);
|
|
132
|
+
|
|
133
|
+
if (unused.length === 0) {
|
|
134
|
+
console.log(JSON.stringify({ success: true, unused: [] }));
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(JSON.stringify({ success: false, unused }));
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function outputGraph(): Promise<void> {
|
|
143
|
+
const format = args[1] || 'json';
|
|
144
|
+
const builder = new DependencyGraphBuilder(cwd);
|
|
145
|
+
const graph = await builder.build({ analyzeImports: true });
|
|
146
|
+
|
|
147
|
+
const output = formatGraph(graph, format as 'json' | 'mermaid' | 'dot' | 'tree');
|
|
148
|
+
console.log(output);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function main(): Promise<void> {
|
|
152
|
+
switch (command) {
|
|
153
|
+
case 'check-workspace':
|
|
154
|
+
await checkWorkspace();
|
|
155
|
+
break;
|
|
156
|
+
case 'check-versions':
|
|
157
|
+
await checkVersions();
|
|
158
|
+
break;
|
|
159
|
+
case 'check-unused':
|
|
160
|
+
await checkUnused();
|
|
161
|
+
break;
|
|
162
|
+
case 'graph':
|
|
163
|
+
await outputGraph();
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
console.log(`Usage: dependency-graph <command>
|
|
167
|
+
|
|
168
|
+
Commands:
|
|
169
|
+
check-workspace Check for workspace:* usage (exits 1 if found)
|
|
170
|
+
check-versions Compare local versions with npm (exits 1 if mismatch)
|
|
171
|
+
check-unused Find unused packages (exits 1 if found)
|
|
172
|
+
graph [format] Output dependency graph (json, mermaid, dot, tree)
|
|
173
|
+
|
|
174
|
+
Output: JSON to stdout for programmatic use`);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
main().catch(console.error);
|