whyinstall 0.1.1 → 0.2.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/dist/analyzer.d.ts +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +8 -2
- package/dist/analyzer.js.map +1 -1
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -1
- package/dist/fileFinder.d.ts +9 -0
- package/dist/fileFinder.d.ts.map +1 -1
- package/dist/fileFinder.js +95 -0
- package/dist/fileFinder.js.map +1 -1
- package/dist/formatter.d.ts +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +49 -1
- package/dist/formatter.js.map +1 -1
- package/dist/impactAnalyzer.d.ts +3 -0
- package/dist/impactAnalyzer.d.ts.map +1 -0
- package/dist/impactAnalyzer.js +117 -0
- package/dist/impactAnalyzer.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/analyzer.ts +9 -2
- package/src/cli.ts +5 -4
- package/src/fileFinder.ts +112 -1
- package/src/formatter.ts +56 -1
- package/src/impactAnalyzer.ts +139 -0
- package/src/types.ts +15 -0
package/dist/analyzer.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AnalyzeResult } from './types';
|
|
2
|
-
export declare function analyzePackage(packageName: string, cwd?: string): AnalyzeResult;
|
|
2
|
+
export declare function analyzePackage(packageName: string, cwd?: string, includeImpact?: boolean): AnalyzeResult;
|
|
3
3
|
//# sourceMappingURL=analyzer.d.ts.map
|
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,aAAa,EAAE,MAAM,SAAS,CAAC;AAgMrE,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,EAAE,aAAa,GAAE,OAAe,GAAG,aAAa,CAmE9H"}
|
package/dist/analyzer.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.analyzePackage = analyzePackage;
|
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const fileFinder_1 = require("./fileFinder");
|
|
7
|
+
const impactAnalyzer_1 = require("./impactAnalyzer");
|
|
7
8
|
function readPackageJson(path) {
|
|
8
9
|
try {
|
|
9
10
|
if ((0, fs_1.existsSync)(path)) {
|
|
@@ -160,7 +161,7 @@ function formatSize(bytes) {
|
|
|
160
161
|
return `${(bytes / 1024).toFixed(0)} KB`;
|
|
161
162
|
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
162
163
|
}
|
|
163
|
-
function analyzePackage(packageName, cwd = process.cwd()) {
|
|
164
|
+
function analyzePackage(packageName, cwd = process.cwd(), includeImpact = false) {
|
|
164
165
|
const rootPackageJson = (0, path_1.join)(cwd, 'package.json');
|
|
165
166
|
const packageJsonPath = findPackageJsonPath(packageName, cwd);
|
|
166
167
|
if (!packageJsonPath) {
|
|
@@ -201,6 +202,10 @@ function analyzePackage(packageName, cwd = process.cwd()) {
|
|
|
201
202
|
}
|
|
202
203
|
}
|
|
203
204
|
const sourceFiles = (0, fileFinder_1.findFilesUsingPackage)(packageName, cwd);
|
|
205
|
+
let impact;
|
|
206
|
+
if (includeImpact) {
|
|
207
|
+
impact = (0, impactAnalyzer_1.analyzeImpact)(packageName, cwd);
|
|
208
|
+
}
|
|
204
209
|
return {
|
|
205
210
|
package: {
|
|
206
211
|
name: packageName,
|
|
@@ -208,7 +213,8 @@ function analyzePackage(packageName, cwd = process.cwd()) {
|
|
|
208
213
|
description,
|
|
209
214
|
size,
|
|
210
215
|
paths,
|
|
211
|
-
sourceFiles: sourceFiles.length > 0 ? sourceFiles : undefined
|
|
216
|
+
sourceFiles: sourceFiles.length > 0 ? sourceFiles : undefined,
|
|
217
|
+
impact
|
|
212
218
|
},
|
|
213
219
|
suggestions
|
|
214
220
|
};
|
package/dist/analyzer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -13,10 +13,11 @@ const program = new commander_1.Command();
|
|
|
13
13
|
program
|
|
14
14
|
.name('whyinstall')
|
|
15
15
|
.description('Find why a dependency exists in your JS/TS project')
|
|
16
|
-
.version('0.
|
|
16
|
+
.version('0.2.0')
|
|
17
17
|
.argument('<package-name>', 'Package name to analyze')
|
|
18
18
|
.option('-j, --json', 'Output as JSON')
|
|
19
19
|
.option('-c, --cwd <path>', 'Working directory', process.cwd())
|
|
20
|
+
.option('--impact', 'Show impact analysis for removing this dependency')
|
|
20
21
|
.action((packageName, options) => {
|
|
21
22
|
try {
|
|
22
23
|
const cwd = options.cwd || process.cwd();
|
|
@@ -24,8 +25,8 @@ program
|
|
|
24
25
|
if (!options.json) {
|
|
25
26
|
console.log(`\n${chalk_1.default.gray(`Detected package manager: ${pm}`)}\n`);
|
|
26
27
|
}
|
|
27
|
-
const result = (0, analyzer_1.analyzePackage)(packageName, cwd);
|
|
28
|
-
const output = (0, formatter_1.formatOutput)(result, options.json);
|
|
28
|
+
const result = (0, analyzer_1.analyzePackage)(packageName, cwd, options.impact);
|
|
29
|
+
const output = (0, formatter_1.formatOutput)(result, options.json, options.impact);
|
|
29
30
|
console.log(output);
|
|
30
31
|
process.exit(0);
|
|
31
32
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,yCAA4C;AAC5C,2CAA2C;AAC3C,qDAAwD;AAExD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC;KACtC,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC9D,MAAM,CAAC,CAAC,WAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,yCAA4C;AAC5C,2CAA2C;AAC3C,qDAAwD;AAExD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC;KACtC,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC9D,MAAM,CAAC,UAAU,EAAE,mDAAmD,CAAC;KACvE,MAAM,CAAC,CAAC,WAAmB,EAAE,OAA2D,EAAE,EAAE;IAC3F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,IAAA,qCAAoB,EAAC,GAAG,CAAC,CAAC;QAErC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,yBAAc,EAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAA,wBAAY,EAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/fileFinder.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
export declare function findSourceFiles(dir: string, maxDepth?: number, currentDepth?: number): string[];
|
|
2
|
+
export interface FileUsage {
|
|
3
|
+
file: string;
|
|
4
|
+
lines: number[];
|
|
5
|
+
methods: string[];
|
|
6
|
+
context?: string[];
|
|
7
|
+
purpose?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function analyzeFileUsage(filePath: string, packageName: string, cwd: string): FileUsage | null;
|
|
1
10
|
export declare function findFilesUsingPackage(packageName: string, cwd: string): string[];
|
|
2
11
|
//# sourceMappingURL=fileFinder.d.ts.map
|
package/dist/fileFinder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileFinder.d.ts","sourceRoot":"","sources":["../src/fileFinder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fileFinder.d.ts","sourceRoot":"","sources":["../src/fileFinder.ts"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM,EAAE,CAgCrG;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmBD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAqGrG;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAYhF"}
|
package/dist/fileFinder.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findSourceFiles = findSourceFiles;
|
|
4
|
+
exports.analyzeFileUsage = analyzeFileUsage;
|
|
3
5
|
exports.findFilesUsingPackage = findFilesUsingPackage;
|
|
4
6
|
const fs_1 = require("fs");
|
|
5
7
|
const path_1 = require("path");
|
|
@@ -56,6 +58,99 @@ function fileContainsPackage(filePath, packageName) {
|
|
|
56
58
|
return false;
|
|
57
59
|
}
|
|
58
60
|
}
|
|
61
|
+
function analyzeFileUsage(filePath, packageName, cwd) {
|
|
62
|
+
try {
|
|
63
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
64
|
+
const lines = content.split('\n');
|
|
65
|
+
const relativePath = filePath.replace(cwd + '/', '');
|
|
66
|
+
const importPatterns = [
|
|
67
|
+
new RegExp(`require\\(['"]${packageName}(/.*)?['"]\\)`, 'g'),
|
|
68
|
+
new RegExp(`from\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
69
|
+
new RegExp(`import\\s+.*\\s+from\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
70
|
+
new RegExp(`import\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
71
|
+
];
|
|
72
|
+
const usageLines = [];
|
|
73
|
+
const methods = new Set();
|
|
74
|
+
const context = [];
|
|
75
|
+
// Find import lines
|
|
76
|
+
lines.forEach((line, index) => {
|
|
77
|
+
const lineNum = index + 1;
|
|
78
|
+
if (importPatterns.some(pattern => pattern.test(line))) {
|
|
79
|
+
usageLines.push(lineNum);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// Find method usage patterns:
|
|
83
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
84
|
+
// 1. Direct: packageName.method() or packageName.method
|
|
85
|
+
const directMethodPattern = new RegExp('\\b' + escapedPackageName + '\\.(\\w+)', 'g');
|
|
86
|
+
const directMatches = content.matchAll(directMethodPattern);
|
|
87
|
+
for (const match of directMatches) {
|
|
88
|
+
methods.add(match[1]);
|
|
89
|
+
}
|
|
90
|
+
// 2. Destructured imports: const { red, bold } = require('chalk')
|
|
91
|
+
const destructurePattern = new RegExp('(?:const|let|var)\\s*\\{[^}]*\\}\\s*=\\s*(?:require|import)\\s*\\(?[\'"]' + escapedPackageName, 'g');
|
|
92
|
+
if (destructurePattern.test(content)) {
|
|
93
|
+
const destructureMatch = content.match(/(?:const|let|var)\s*\{([^}]+)\}/);
|
|
94
|
+
if (destructureMatch) {
|
|
95
|
+
destructureMatch[1].split(',').forEach(m => {
|
|
96
|
+
const method = m.trim().split(':')[0].trim();
|
|
97
|
+
if (method)
|
|
98
|
+
methods.add(method);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// 3. Default import assigned to variable: const program = new Command(); program.method()
|
|
103
|
+
// Find named imports: import { Command } from 'commander'
|
|
104
|
+
const namedImportMatch = content.match(/import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/i);
|
|
105
|
+
if (namedImportMatch && namedImportMatch[2] === packageName) {
|
|
106
|
+
const namedImports = namedImportMatch[1].split(',').map(i => i.trim().split('as')[0].trim());
|
|
107
|
+
namedImports.forEach(importName => {
|
|
108
|
+
// Find instances: const program = new Command()
|
|
109
|
+
const escapedImportName = importName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
110
|
+
const instancePattern = new RegExp('(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*=\\s*new\\s+' + escapedImportName, 'g');
|
|
111
|
+
const instanceMatches = content.matchAll(instancePattern);
|
|
112
|
+
for (const instanceMatch of instanceMatches) {
|
|
113
|
+
const instanceName = instanceMatch[1];
|
|
114
|
+
// Find methods on this instance: program.command()
|
|
115
|
+
const instanceMethodPattern = new RegExp('\\b' + instanceName + '\\.(\\w+)\\s*\\(', 'g');
|
|
116
|
+
const methodMatches = content.matchAll(instanceMethodPattern);
|
|
117
|
+
for (const methodMatch of methodMatches) {
|
|
118
|
+
methods.add(methodMatch[1]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// 4. Default import: import Command from 'commander' or const Command = require('commander')
|
|
124
|
+
const defaultImportMatch = content.match(new RegExp('(?:import|const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*(?:=|from)\\s*[\'"]' + escapedPackageName, 'i'));
|
|
125
|
+
if (defaultImportMatch) {
|
|
126
|
+
const importedName = defaultImportMatch[1];
|
|
127
|
+
// Find all method calls on this imported name: program.method()
|
|
128
|
+
const instanceMethodPattern = new RegExp('\\b' + importedName + '\\.(\\w+)\\s*\\(', 'g');
|
|
129
|
+
const instanceMatches = content.matchAll(instanceMethodPattern);
|
|
130
|
+
for (const match of instanceMatches) {
|
|
131
|
+
methods.add(match[1]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Capture context (lines around usage)
|
|
135
|
+
if (usageLines.length > 0) {
|
|
136
|
+
const firstLine = Math.max(0, usageLines[0] - 3);
|
|
137
|
+
const lastLine = Math.min(lines.length, usageLines[usageLines.length - 1] + 3);
|
|
138
|
+
context.push(...lines.slice(firstLine, lastLine));
|
|
139
|
+
}
|
|
140
|
+
if (usageLines.length > 0) {
|
|
141
|
+
return {
|
|
142
|
+
file: relativePath,
|
|
143
|
+
lines: usageLines,
|
|
144
|
+
methods: Array.from(methods),
|
|
145
|
+
context: context.slice(0, 10) // Limit context
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
59
154
|
function findFilesUsingPackage(packageName, cwd) {
|
|
60
155
|
const sourceFiles = findSourceFiles(cwd);
|
|
61
156
|
const matchingFiles = [];
|
package/dist/fileFinder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileFinder.js","sourceRoot":"","sources":["../src/fileFinder.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"fileFinder.js","sourceRoot":"","sources":["../src/fileFinder.ts"],"names":[],"mappings":"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"}
|
package/dist/formatter.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AnalyzeResult } from './types';
|
|
2
|
-
export declare function formatOutput(result: AnalyzeResult, json?: boolean): string;
|
|
2
|
+
export declare function formatOutput(result: AnalyzeResult, json?: boolean, showImpact?: boolean): string;
|
|
3
3
|
//# sourceMappingURL=formatter.d.ts.map
|
package/dist/formatter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAkB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAkB,MAAM,SAAS,CAAC;AA0ExD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,GAAE,OAAe,EAAE,UAAU,GAAE,OAAe,GAAG,MAAM,CAmF9G"}
|
package/dist/formatter.js
CHANGED
|
@@ -58,7 +58,23 @@ function getTypeLabel(type) {
|
|
|
58
58
|
};
|
|
59
59
|
return labels[type] || type;
|
|
60
60
|
}
|
|
61
|
-
function
|
|
61
|
+
function getRiskEmoji(risk) {
|
|
62
|
+
const emojis = {
|
|
63
|
+
Low: '🟢',
|
|
64
|
+
Medium: '🟡',
|
|
65
|
+
High: '🔴'
|
|
66
|
+
};
|
|
67
|
+
return emojis[risk] || '⚪';
|
|
68
|
+
}
|
|
69
|
+
function getRiskColor(risk) {
|
|
70
|
+
const colors = {
|
|
71
|
+
Low: chalk_1.default.green,
|
|
72
|
+
Medium: chalk_1.default.yellow,
|
|
73
|
+
High: chalk_1.default.red
|
|
74
|
+
};
|
|
75
|
+
return colors[risk] || chalk_1.default.gray;
|
|
76
|
+
}
|
|
77
|
+
function formatOutput(result, json = false, showImpact = false) {
|
|
62
78
|
if (json) {
|
|
63
79
|
return JSON.stringify(result, null, 2);
|
|
64
80
|
}
|
|
@@ -90,6 +106,38 @@ function formatOutput(result, json = false) {
|
|
|
90
106
|
output += ` ${chalk_1.default.blue(file)}\n`;
|
|
91
107
|
});
|
|
92
108
|
}
|
|
109
|
+
if (showImpact && pkg.impact) {
|
|
110
|
+
const impact = pkg.impact;
|
|
111
|
+
output += '\n' + chalk_1.default.bold('Impact analysis:') + '\n\n';
|
|
112
|
+
if (impact.files.length > 0) {
|
|
113
|
+
output += chalk_1.default.bold('Used in ') + chalk_1.default.bold(`${impact.files.length} file${impact.files.length !== 1 ? 's' : ''}:`) + '\n\n';
|
|
114
|
+
impact.files.forEach((file, index) => {
|
|
115
|
+
const fileUsage = file;
|
|
116
|
+
const lineRange = fileUsage.lines.length === 1
|
|
117
|
+
? `Line ${fileUsage.lines[0]}`
|
|
118
|
+
: `Lines ${Math.min(...fileUsage.lines)}–${Math.max(...fileUsage.lines)}`;
|
|
119
|
+
output += `${index + 1}. ${chalk_1.default.blue(fileUsage.file)}\n`;
|
|
120
|
+
output += ` ${chalk_1.default.gray(lineRange)}\n`;
|
|
121
|
+
if (fileUsage.purpose) {
|
|
122
|
+
output += ` ${chalk_1.default.dim(`Purpose: ${fileUsage.purpose}`)}\n`;
|
|
123
|
+
}
|
|
124
|
+
if (fileUsage.methods.length > 0) {
|
|
125
|
+
output += ` ${chalk_1.default.dim(`Methods: ${fileUsage.methods.slice(0, 5).join(', ')}${fileUsage.methods.length > 5 ? '...' : ''}`)}\n`;
|
|
126
|
+
}
|
|
127
|
+
output += '\n';
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
output += chalk_1.default.yellow(' No direct usage found in source files\n\n');
|
|
132
|
+
}
|
|
133
|
+
output += chalk_1.default.bold('Estimated removal impact:') + '\n';
|
|
134
|
+
impact.impacts.forEach((impactText) => {
|
|
135
|
+
output += ` ${chalk_1.default.gray('-')} ${chalk_1.default.gray(impactText)}\n`;
|
|
136
|
+
});
|
|
137
|
+
output += '\n';
|
|
138
|
+
const riskColor = getRiskColor(impact.riskLevel);
|
|
139
|
+
output += chalk_1.default.bold('Risk level: ') + getRiskEmoji(impact.riskLevel) + ' ' + riskColor(impact.riskLevel) + '\n';
|
|
140
|
+
}
|
|
93
141
|
if (suggestions.length > 0) {
|
|
94
142
|
output += '\n' + chalk_1.default.bold('Suggested actions:') + '\n';
|
|
95
143
|
suggestions.forEach((suggestion, index) => {
|
package/dist/formatter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impactAnalyzer.d.ts","sourceRoot":"","sources":["../src/impactAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAqGzC,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAqC9E"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeImpact = analyzeImpact;
|
|
4
|
+
const fileFinder_1 = require("./fileFinder");
|
|
5
|
+
function analyzeUsageContext(usage, content) {
|
|
6
|
+
// Analyze actual usage patterns in THIS codebase, not generic assumptions
|
|
7
|
+
const lines = content.split('\n');
|
|
8
|
+
const contextLines = [];
|
|
9
|
+
// Get context around usage lines
|
|
10
|
+
usage.lines.forEach(lineNum => {
|
|
11
|
+
const start = Math.max(0, lineNum - 2);
|
|
12
|
+
const end = Math.min(lines.length, lineNum + 2);
|
|
13
|
+
contextLines.push(...lines.slice(start, end));
|
|
14
|
+
});
|
|
15
|
+
const context = contextLines.join('\n').toLowerCase();
|
|
16
|
+
// Simple heuristics based on actual code patterns, not package names
|
|
17
|
+
if (context.includes('console.') || context.includes('process.stdout') || context.includes('process.stderr')) {
|
|
18
|
+
return 'Console/output';
|
|
19
|
+
}
|
|
20
|
+
if (context.includes('response') || context.includes('res.') || context.includes('req.')) {
|
|
21
|
+
return 'HTTP/API';
|
|
22
|
+
}
|
|
23
|
+
if (context.includes('database') || context.includes('db.') || context.includes('query')) {
|
|
24
|
+
return 'Database';
|
|
25
|
+
}
|
|
26
|
+
if (context.includes('test') || context.includes('spec') || context.includes('describe')) {
|
|
27
|
+
return 'Testing';
|
|
28
|
+
}
|
|
29
|
+
return 'General usage';
|
|
30
|
+
}
|
|
31
|
+
function computeRiskLevel(files, contexts) {
|
|
32
|
+
// Risk assessment based on WHERE it's used, not WHAT package it is
|
|
33
|
+
const hasDatabase = contexts.some(c => c === 'Database');
|
|
34
|
+
const hasHTTP = contexts.some(c => c === 'HTTP/API');
|
|
35
|
+
const hasTesting = contexts.every(c => c === 'Testing');
|
|
36
|
+
const hasConsole = contexts.every(c => c === 'Console/output');
|
|
37
|
+
// High risk: Database, HTTP/API (core functionality)
|
|
38
|
+
if (hasDatabase || hasHTTP) {
|
|
39
|
+
return 'High';
|
|
40
|
+
}
|
|
41
|
+
// Low risk: Only in tests, or only console output
|
|
42
|
+
if (hasTesting || (hasConsole && files.length === 1)) {
|
|
43
|
+
return 'Low';
|
|
44
|
+
}
|
|
45
|
+
// Medium: Everything else (could be important, needs review)
|
|
46
|
+
return 'Medium';
|
|
47
|
+
}
|
|
48
|
+
function generateImpacts(files, contexts, packageName) {
|
|
49
|
+
const impacts = [];
|
|
50
|
+
const uniqueContexts = [...new Set(contexts)];
|
|
51
|
+
// Base impacts on actual usage in THIS codebase
|
|
52
|
+
if (files.length === 0) {
|
|
53
|
+
impacts.push(`No direct usage found in source files`);
|
|
54
|
+
impacts.push(`May be a transitive dependency or unused`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const totalMethods = new Set(files.flatMap(f => f.methods));
|
|
58
|
+
if (totalMethods.size > 0) {
|
|
59
|
+
impacts.push(`Methods used: ${Array.from(totalMethods).slice(0, 8).join(', ')}${totalMethods.size > 8 ? ` (+${totalMethods.size - 8} more)` : ''}`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
impacts.push(`Package imported but no method calls detected`);
|
|
63
|
+
impacts.push(`May be used as default export or namespace`);
|
|
64
|
+
}
|
|
65
|
+
impacts.push(`Used in ${files.length} file${files.length !== 1 ? 's' : ''}: ${uniqueContexts.join(', ')}`);
|
|
66
|
+
// Context-specific guidance (based on actual usage, not package name)
|
|
67
|
+
if (uniqueContexts.includes('Database')) {
|
|
68
|
+
impacts.push(`⚠️ Used in database operations - removal may break data access`);
|
|
69
|
+
}
|
|
70
|
+
if (uniqueContexts.includes('HTTP/API')) {
|
|
71
|
+
impacts.push(`⚠️ Used in API/HTTP layer - removal may break endpoints`);
|
|
72
|
+
}
|
|
73
|
+
if (uniqueContexts.includes('Testing')) {
|
|
74
|
+
impacts.push(`✓ Only used in tests - safe to remove from production dependencies`);
|
|
75
|
+
}
|
|
76
|
+
if (uniqueContexts.includes('Console/output') && files.length === 1) {
|
|
77
|
+
impacts.push(`✓ Only used for console output - low impact, can be replaced`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
impacts.push(`\n💡 Review the files above to assess actual impact in your codebase`);
|
|
81
|
+
return impacts;
|
|
82
|
+
}
|
|
83
|
+
function analyzeImpact(packageName, cwd) {
|
|
84
|
+
const sourceFiles = (0, fileFinder_1.findSourceFiles)(cwd);
|
|
85
|
+
const fileUsages = [];
|
|
86
|
+
for (const file of sourceFiles) {
|
|
87
|
+
const usage = (0, fileFinder_1.analyzeFileUsage)(file, packageName, cwd);
|
|
88
|
+
if (usage) {
|
|
89
|
+
fileUsages.push(usage);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Analyze actual usage context in THIS codebase
|
|
93
|
+
const contexts = fileUsages.map(usage => {
|
|
94
|
+
try {
|
|
95
|
+
const fs = require('fs');
|
|
96
|
+
const path = require('path');
|
|
97
|
+
const fullPath = usage.file.startsWith(cwd) ? usage.file : path.join(cwd, usage.file);
|
|
98
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
99
|
+
return analyzeUsageContext(usage, content);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return 'Unknown';
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
const riskLevel = computeRiskLevel(fileUsages, contexts);
|
|
106
|
+
const impacts = generateImpacts(fileUsages, contexts, packageName);
|
|
107
|
+
// Add contexts to file usages
|
|
108
|
+
fileUsages.forEach((usage, index) => {
|
|
109
|
+
usage.purpose = contexts[index];
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
files: fileUsages,
|
|
113
|
+
riskLevel,
|
|
114
|
+
impacts
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=impactAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impactAnalyzer.js","sourceRoot":"","sources":["../src/impactAnalyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,6 +3,18 @@ export interface DependencyPath {
|
|
|
3
3
|
type: 'prod' | 'dev' | 'peer' | 'optional';
|
|
4
4
|
packageJsonPath?: string;
|
|
5
5
|
}
|
|
6
|
+
export interface FileUsage {
|
|
7
|
+
file: string;
|
|
8
|
+
lines: number[];
|
|
9
|
+
methods: string[];
|
|
10
|
+
context?: string[];
|
|
11
|
+
purpose?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ImpactAnalysis {
|
|
14
|
+
files: FileUsage[];
|
|
15
|
+
riskLevel: 'Low' | 'Medium' | 'High';
|
|
16
|
+
impacts: string[];
|
|
17
|
+
}
|
|
6
18
|
export interface PackageInfo {
|
|
7
19
|
name: string;
|
|
8
20
|
version: string;
|
|
@@ -10,6 +22,7 @@ export interface PackageInfo {
|
|
|
10
22
|
size?: number;
|
|
11
23
|
paths: DependencyPath[];
|
|
12
24
|
sourceFiles?: string[];
|
|
25
|
+
impact?: ImpactAnalysis;
|
|
13
26
|
}
|
|
14
27
|
export interface AnalyzeResult {
|
|
15
28
|
package: PackageInfo;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC"}
|
package/package.json
CHANGED
package/src/analyzer.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { join, dirname } from 'path';
|
|
|
3
3
|
import { PackageInfo, DependencyPath, AnalyzeResult } from './types';
|
|
4
4
|
import { detectPackageManager } from './packageManager';
|
|
5
5
|
import { findFilesUsingPackage } from './fileFinder';
|
|
6
|
+
import { analyzeImpact } from './impactAnalyzer';
|
|
6
7
|
|
|
7
8
|
interface PackageJson {
|
|
8
9
|
name?: string;
|
|
@@ -191,7 +192,7 @@ function formatSize(bytes: number | undefined): string {
|
|
|
191
192
|
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
export function analyzePackage(packageName: string, cwd: string = process.cwd()): AnalyzeResult {
|
|
195
|
+
export function analyzePackage(packageName: string, cwd: string = process.cwd(), includeImpact: boolean = false): AnalyzeResult {
|
|
195
196
|
const rootPackageJson = join(cwd, 'package.json');
|
|
196
197
|
const packageJsonPath = findPackageJsonPath(packageName, cwd);
|
|
197
198
|
if (!packageJsonPath) {
|
|
@@ -241,6 +242,11 @@ export function analyzePackage(packageName: string, cwd: string = process.cwd())
|
|
|
241
242
|
|
|
242
243
|
const sourceFiles = findFilesUsingPackage(packageName, cwd);
|
|
243
244
|
|
|
245
|
+
let impact;
|
|
246
|
+
if (includeImpact) {
|
|
247
|
+
impact = analyzeImpact(packageName, cwd);
|
|
248
|
+
}
|
|
249
|
+
|
|
244
250
|
return {
|
|
245
251
|
package: {
|
|
246
252
|
name: packageName,
|
|
@@ -248,7 +254,8 @@ export function analyzePackage(packageName: string, cwd: string = process.cwd())
|
|
|
248
254
|
description,
|
|
249
255
|
size,
|
|
250
256
|
paths,
|
|
251
|
-
sourceFiles: sourceFiles.length > 0 ? sourceFiles : undefined
|
|
257
|
+
sourceFiles: sourceFiles.length > 0 ? sourceFiles : undefined,
|
|
258
|
+
impact
|
|
252
259
|
},
|
|
253
260
|
suggestions
|
|
254
261
|
};
|
package/src/cli.ts
CHANGED
|
@@ -11,11 +11,12 @@ const program = new Command();
|
|
|
11
11
|
program
|
|
12
12
|
.name('whyinstall')
|
|
13
13
|
.description('Find why a dependency exists in your JS/TS project')
|
|
14
|
-
.version('0.
|
|
14
|
+
.version('0.2.0')
|
|
15
15
|
.argument('<package-name>', 'Package name to analyze')
|
|
16
16
|
.option('-j, --json', 'Output as JSON')
|
|
17
17
|
.option('-c, --cwd <path>', 'Working directory', process.cwd())
|
|
18
|
-
.
|
|
18
|
+
.option('--impact', 'Show impact analysis for removing this dependency')
|
|
19
|
+
.action((packageName: string, options: { json?: boolean; cwd?: string; impact?: boolean }) => {
|
|
19
20
|
try {
|
|
20
21
|
const cwd = options.cwd || process.cwd();
|
|
21
22
|
const pm = detectPackageManager(cwd);
|
|
@@ -24,8 +25,8 @@ program
|
|
|
24
25
|
console.log(`\n${chalk.gray(`Detected package manager: ${pm}`)}\n`);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
const result = analyzePackage(packageName, cwd);
|
|
28
|
-
const output = formatOutput(result, options.json);
|
|
28
|
+
const result = analyzePackage(packageName, cwd, options.impact);
|
|
29
|
+
const output = formatOutput(result, options.json, options.impact);
|
|
29
30
|
console.log(output);
|
|
30
31
|
|
|
31
32
|
process.exit(0);
|
package/src/fileFinder.ts
CHANGED
|
@@ -12,7 +12,7 @@ function isSourceFile(filePath: string): boolean {
|
|
|
12
12
|
return SOURCE_EXTENSIONS.includes(extname(filePath));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function findSourceFiles(dir: string, maxDepth: number = 5, currentDepth: number = 0): string[] {
|
|
15
|
+
export function findSourceFiles(dir: string, maxDepth: number = 5, currentDepth: number = 0): string[] {
|
|
16
16
|
if (currentDepth > maxDepth) {
|
|
17
17
|
return [];
|
|
18
18
|
}
|
|
@@ -46,6 +46,14 @@ function findSourceFiles(dir: string, maxDepth: number = 5, currentDepth: number
|
|
|
46
46
|
return files;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface FileUsage {
|
|
50
|
+
file: string;
|
|
51
|
+
lines: number[];
|
|
52
|
+
methods: string[];
|
|
53
|
+
context?: string[];
|
|
54
|
+
purpose?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
function fileContainsPackage(filePath: string, packageName: string): boolean {
|
|
50
58
|
try {
|
|
51
59
|
const content = readFileSync(filePath, 'utf-8');
|
|
@@ -63,6 +71,109 @@ function fileContainsPackage(filePath: string, packageName: string): boolean {
|
|
|
63
71
|
}
|
|
64
72
|
}
|
|
65
73
|
|
|
74
|
+
export function analyzeFileUsage(filePath: string, packageName: string, cwd: string): FileUsage | null {
|
|
75
|
+
try {
|
|
76
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
77
|
+
const lines = content.split('\n');
|
|
78
|
+
const relativePath = filePath.replace(cwd + '/', '');
|
|
79
|
+
|
|
80
|
+
const importPatterns = [
|
|
81
|
+
new RegExp(`require\\(['"]${packageName}(/.*)?['"]\\)`, 'g'),
|
|
82
|
+
new RegExp(`from\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
83
|
+
new RegExp(`import\\s+.*\\s+from\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
84
|
+
new RegExp(`import\\s+['"]${packageName}(/.*)?['"]`, 'g'),
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const usageLines: number[] = [];
|
|
88
|
+
const methods = new Set<string>();
|
|
89
|
+
const context: string[] = [];
|
|
90
|
+
|
|
91
|
+
// Find import lines
|
|
92
|
+
lines.forEach((line, index) => {
|
|
93
|
+
const lineNum = index + 1;
|
|
94
|
+
if (importPatterns.some(pattern => pattern.test(line))) {
|
|
95
|
+
usageLines.push(lineNum);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Find method usage patterns:
|
|
100
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
101
|
+
|
|
102
|
+
// 1. Direct: packageName.method() or packageName.method
|
|
103
|
+
const directMethodPattern = new RegExp('\\b' + escapedPackageName + '\\.(\\w+)', 'g');
|
|
104
|
+
const directMatches = content.matchAll(directMethodPattern);
|
|
105
|
+
for (const match of directMatches) {
|
|
106
|
+
methods.add(match[1]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. Destructured imports: const { red, bold } = require('chalk')
|
|
110
|
+
const destructurePattern = new RegExp('(?:const|let|var)\\s*\\{[^}]*\\}\\s*=\\s*(?:require|import)\\s*\\(?[\'"]' + escapedPackageName, 'g');
|
|
111
|
+
if (destructurePattern.test(content)) {
|
|
112
|
+
const destructureMatch = content.match(/(?:const|let|var)\s*\{([^}]+)\}/);
|
|
113
|
+
if (destructureMatch) {
|
|
114
|
+
destructureMatch[1].split(',').forEach(m => {
|
|
115
|
+
const method = m.trim().split(':')[0].trim();
|
|
116
|
+
if (method) methods.add(method);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 3. Default import assigned to variable: const program = new Command(); program.method()
|
|
122
|
+
// Find named imports: import { Command } from 'commander'
|
|
123
|
+
const namedImportMatch = content.match(/import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/i);
|
|
124
|
+
if (namedImportMatch && namedImportMatch[2] === packageName) {
|
|
125
|
+
const namedImports = namedImportMatch[1].split(',').map(i => i.trim().split('as')[0].trim());
|
|
126
|
+
namedImports.forEach(importName => {
|
|
127
|
+
// Find instances: const program = new Command()
|
|
128
|
+
const escapedImportName = importName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
129
|
+
const instancePattern = new RegExp('(?:const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*=\\s*new\\s+' + escapedImportName, 'g');
|
|
130
|
+
const instanceMatches = content.matchAll(instancePattern);
|
|
131
|
+
for (const instanceMatch of instanceMatches) {
|
|
132
|
+
const instanceName = instanceMatch[1];
|
|
133
|
+
// Find methods on this instance: program.command()
|
|
134
|
+
const instanceMethodPattern = new RegExp('\\b' + instanceName + '\\.(\\w+)\\s*\\(', 'g');
|
|
135
|
+
const methodMatches = content.matchAll(instanceMethodPattern);
|
|
136
|
+
for (const methodMatch of methodMatches) {
|
|
137
|
+
methods.add(methodMatch[1]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 4. Default import: import Command from 'commander' or const Command = require('commander')
|
|
144
|
+
const defaultImportMatch = content.match(new RegExp('(?:import|const|let|var)\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*(?:=|from)\\s*[\'"]' + escapedPackageName, 'i'));
|
|
145
|
+
if (defaultImportMatch) {
|
|
146
|
+
const importedName = defaultImportMatch[1];
|
|
147
|
+
// Find all method calls on this imported name: program.method()
|
|
148
|
+
const instanceMethodPattern = new RegExp('\\b' + importedName + '\\.(\\w+)\\s*\\(', 'g');
|
|
149
|
+
const instanceMatches = content.matchAll(instanceMethodPattern);
|
|
150
|
+
for (const match of instanceMatches) {
|
|
151
|
+
methods.add(match[1]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Capture context (lines around usage)
|
|
156
|
+
if (usageLines.length > 0) {
|
|
157
|
+
const firstLine = Math.max(0, usageLines[0] - 3);
|
|
158
|
+
const lastLine = Math.min(lines.length, usageLines[usageLines.length - 1] + 3);
|
|
159
|
+
context.push(...lines.slice(firstLine, lastLine));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (usageLines.length > 0) {
|
|
163
|
+
return {
|
|
164
|
+
file: relativePath,
|
|
165
|
+
lines: usageLines,
|
|
166
|
+
methods: Array.from(methods),
|
|
167
|
+
context: context.slice(0, 10) // Limit context
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return null;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
66
177
|
export function findFilesUsingPackage(packageName: string, cwd: string): string[] {
|
|
67
178
|
const sourceFiles = findSourceFiles(cwd);
|
|
68
179
|
const matchingFiles: string[] = [];
|
package/src/formatter.ts
CHANGED
|
@@ -55,7 +55,25 @@ function getTypeLabel(type: DependencyPath['type']): string {
|
|
|
55
55
|
return labels[type] || type;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
function getRiskEmoji(risk: 'Low' | 'Medium' | 'High'): string {
|
|
59
|
+
const emojis = {
|
|
60
|
+
Low: '🟢',
|
|
61
|
+
Medium: '🟡',
|
|
62
|
+
High: '🔴'
|
|
63
|
+
};
|
|
64
|
+
return emojis[risk] || '⚪';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getRiskColor(risk: 'Low' | 'Medium' | 'High'): (text: string) => string {
|
|
68
|
+
const colors = {
|
|
69
|
+
Low: chalk.green,
|
|
70
|
+
Medium: chalk.yellow,
|
|
71
|
+
High: chalk.red
|
|
72
|
+
};
|
|
73
|
+
return colors[risk] || chalk.gray;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function formatOutput(result: AnalyzeResult, json: boolean = false, showImpact: boolean = false): string {
|
|
59
77
|
if (json) {
|
|
60
78
|
return JSON.stringify(result, null, 2);
|
|
61
79
|
}
|
|
@@ -93,6 +111,43 @@ export function formatOutput(result: AnalyzeResult, json: boolean = false): stri
|
|
|
93
111
|
});
|
|
94
112
|
}
|
|
95
113
|
|
|
114
|
+
if (showImpact && pkg.impact) {
|
|
115
|
+
const impact = pkg.impact;
|
|
116
|
+
output += '\n' + chalk.bold('Impact analysis:') + '\n\n';
|
|
117
|
+
|
|
118
|
+
if (impact.files.length > 0) {
|
|
119
|
+
output += chalk.bold('Used in ') + chalk.bold(`${impact.files.length} file${impact.files.length !== 1 ? 's' : ''}:`) + '\n\n';
|
|
120
|
+
|
|
121
|
+
impact.files.forEach((file, index) => {
|
|
122
|
+
const fileUsage = file as any;
|
|
123
|
+
const lineRange = fileUsage.lines.length === 1
|
|
124
|
+
? `Line ${fileUsage.lines[0]}`
|
|
125
|
+
: `Lines ${Math.min(...fileUsage.lines)}–${Math.max(...fileUsage.lines)}`;
|
|
126
|
+
|
|
127
|
+
output += `${index + 1}. ${chalk.blue(fileUsage.file)}\n`;
|
|
128
|
+
output += ` ${chalk.gray(lineRange)}\n`;
|
|
129
|
+
if (fileUsage.purpose) {
|
|
130
|
+
output += ` ${chalk.dim(`Purpose: ${fileUsage.purpose}`)}\n`;
|
|
131
|
+
}
|
|
132
|
+
if (fileUsage.methods.length > 0) {
|
|
133
|
+
output += ` ${chalk.dim(`Methods: ${fileUsage.methods.slice(0, 5).join(', ')}${fileUsage.methods.length > 5 ? '...' : ''}`)}\n`;
|
|
134
|
+
}
|
|
135
|
+
output += '\n';
|
|
136
|
+
});
|
|
137
|
+
} else {
|
|
138
|
+
output += chalk.yellow(' No direct usage found in source files\n\n');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
output += chalk.bold('Estimated removal impact:') + '\n';
|
|
142
|
+
impact.impacts.forEach((impactText) => {
|
|
143
|
+
output += ` ${chalk.gray('-')} ${chalk.gray(impactText)}\n`;
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
output += '\n';
|
|
147
|
+
const riskColor = getRiskColor(impact.riskLevel);
|
|
148
|
+
output += chalk.bold('Risk level: ') + getRiskEmoji(impact.riskLevel) + ' ' + riskColor(impact.riskLevel) + '\n';
|
|
149
|
+
}
|
|
150
|
+
|
|
96
151
|
if (suggestions.length > 0) {
|
|
97
152
|
output += '\n' + chalk.bold('Suggested actions:') + '\n';
|
|
98
153
|
suggestions.forEach((suggestion, index) => {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { ImpactAnalysis } from './types';
|
|
2
|
+
import { FileUsage, findSourceFiles, analyzeFileUsage } from './fileFinder';
|
|
3
|
+
|
|
4
|
+
function analyzeUsageContext(usage: FileUsage, content: string): string {
|
|
5
|
+
// Analyze actual usage patterns in THIS codebase, not generic assumptions
|
|
6
|
+
const lines = content.split('\n');
|
|
7
|
+
const contextLines: string[] = [];
|
|
8
|
+
|
|
9
|
+
// Get context around usage lines
|
|
10
|
+
usage.lines.forEach(lineNum => {
|
|
11
|
+
const start = Math.max(0, lineNum - 2);
|
|
12
|
+
const end = Math.min(lines.length, lineNum + 2);
|
|
13
|
+
contextLines.push(...lines.slice(start, end));
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const context = contextLines.join('\n').toLowerCase();
|
|
17
|
+
|
|
18
|
+
// Simple heuristics based on actual code patterns, not package names
|
|
19
|
+
if (context.includes('console.') || context.includes('process.stdout') || context.includes('process.stderr')) {
|
|
20
|
+
return 'Console/output';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (context.includes('response') || context.includes('res.') || context.includes('req.')) {
|
|
24
|
+
return 'HTTP/API';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (context.includes('database') || context.includes('db.') || context.includes('query')) {
|
|
28
|
+
return 'Database';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (context.includes('test') || context.includes('spec') || context.includes('describe')) {
|
|
32
|
+
return 'Testing';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return 'General usage';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function computeRiskLevel(files: FileUsage[], contexts: string[]): 'Low' | 'Medium' | 'High' {
|
|
39
|
+
// Risk assessment based on WHERE it's used, not WHAT package it is
|
|
40
|
+
const hasDatabase = contexts.some(c => c === 'Database');
|
|
41
|
+
const hasHTTP = contexts.some(c => c === 'HTTP/API');
|
|
42
|
+
const hasTesting = contexts.every(c => c === 'Testing');
|
|
43
|
+
const hasConsole = contexts.every(c => c === 'Console/output');
|
|
44
|
+
|
|
45
|
+
// High risk: Database, HTTP/API (core functionality)
|
|
46
|
+
if (hasDatabase || hasHTTP) {
|
|
47
|
+
return 'High';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Low risk: Only in tests, or only console output
|
|
51
|
+
if (hasTesting || (hasConsole && files.length === 1)) {
|
|
52
|
+
return 'Low';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Medium: Everything else (could be important, needs review)
|
|
56
|
+
return 'Medium';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function generateImpacts(files: FileUsage[], contexts: string[], packageName: string): string[] {
|
|
60
|
+
const impacts: string[] = [];
|
|
61
|
+
const uniqueContexts = [...new Set(contexts)];
|
|
62
|
+
|
|
63
|
+
// Base impacts on actual usage in THIS codebase
|
|
64
|
+
if (files.length === 0) {
|
|
65
|
+
impacts.push(`No direct usage found in source files`);
|
|
66
|
+
impacts.push(`May be a transitive dependency or unused`);
|
|
67
|
+
} else {
|
|
68
|
+
const totalMethods = new Set(files.flatMap(f => f.methods));
|
|
69
|
+
|
|
70
|
+
if (totalMethods.size > 0) {
|
|
71
|
+
impacts.push(`Methods used: ${Array.from(totalMethods).slice(0, 8).join(', ')}${totalMethods.size > 8 ? ` (+${totalMethods.size - 8} more)` : ''}`);
|
|
72
|
+
} else {
|
|
73
|
+
impacts.push(`Package imported but no method calls detected`);
|
|
74
|
+
impacts.push(`May be used as default export or namespace`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
impacts.push(`Used in ${files.length} file${files.length !== 1 ? 's' : ''}: ${uniqueContexts.join(', ')}`);
|
|
78
|
+
|
|
79
|
+
// Context-specific guidance (based on actual usage, not package name)
|
|
80
|
+
if (uniqueContexts.includes('Database')) {
|
|
81
|
+
impacts.push(`⚠️ Used in database operations - removal may break data access`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (uniqueContexts.includes('HTTP/API')) {
|
|
85
|
+
impacts.push(`⚠️ Used in API/HTTP layer - removal may break endpoints`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (uniqueContexts.includes('Testing')) {
|
|
89
|
+
impacts.push(`✓ Only used in tests - safe to remove from production dependencies`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (uniqueContexts.includes('Console/output') && files.length === 1) {
|
|
93
|
+
impacts.push(`✓ Only used for console output - low impact, can be replaced`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
impacts.push(`\n💡 Review the files above to assess actual impact in your codebase`);
|
|
98
|
+
|
|
99
|
+
return impacts;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function analyzeImpact(packageName: string, cwd: string): ImpactAnalysis {
|
|
103
|
+
const sourceFiles = findSourceFiles(cwd);
|
|
104
|
+
const fileUsages: FileUsage[] = [];
|
|
105
|
+
|
|
106
|
+
for (const file of sourceFiles) {
|
|
107
|
+
const usage = analyzeFileUsage(file, packageName, cwd);
|
|
108
|
+
if (usage) {
|
|
109
|
+
fileUsages.push(usage);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Analyze actual usage context in THIS codebase
|
|
114
|
+
const contexts = fileUsages.map(usage => {
|
|
115
|
+
try {
|
|
116
|
+
const fs = require('fs');
|
|
117
|
+
const path = require('path');
|
|
118
|
+
const fullPath = usage.file.startsWith(cwd) ? usage.file : path.join(cwd, usage.file);
|
|
119
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
120
|
+
return analyzeUsageContext(usage, content);
|
|
121
|
+
} catch {
|
|
122
|
+
return 'Unknown';
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const riskLevel = computeRiskLevel(fileUsages, contexts);
|
|
127
|
+
const impacts = generateImpacts(fileUsages, contexts, packageName);
|
|
128
|
+
|
|
129
|
+
// Add contexts to file usages
|
|
130
|
+
fileUsages.forEach((usage, index) => {
|
|
131
|
+
(usage as any).purpose = contexts[index];
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
files: fileUsages,
|
|
136
|
+
riskLevel,
|
|
137
|
+
impacts
|
|
138
|
+
};
|
|
139
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -4,6 +4,20 @@ export interface DependencyPath {
|
|
|
4
4
|
packageJsonPath?: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
export interface FileUsage {
|
|
8
|
+
file: string;
|
|
9
|
+
lines: number[];
|
|
10
|
+
methods: string[];
|
|
11
|
+
context?: string[];
|
|
12
|
+
purpose?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ImpactAnalysis {
|
|
16
|
+
files: FileUsage[];
|
|
17
|
+
riskLevel: 'Low' | 'Medium' | 'High';
|
|
18
|
+
impacts: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
export interface PackageInfo {
|
|
8
22
|
name: string;
|
|
9
23
|
version: string;
|
|
@@ -11,6 +25,7 @@ export interface PackageInfo {
|
|
|
11
25
|
size?: number;
|
|
12
26
|
paths: DependencyPath[];
|
|
13
27
|
sourceFiles?: string[];
|
|
28
|
+
impact?: ImpactAnalysis;
|
|
14
29
|
}
|
|
15
30
|
|
|
16
31
|
export interface AnalyzeResult {
|