@optiprune/cli 1.2.5 → 1.2.7
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.js +44 -90
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ const program = new Command();
|
|
|
6
6
|
// Using @ts-ignore for core imports as CI environments sometimes struggle
|
|
7
7
|
// with subpath exports resolution in strict NodeNext mode.
|
|
8
8
|
// @ts-ignore
|
|
9
|
-
import { analyze, shouldFail } from "@optiprune/core";
|
|
9
|
+
import { analyze, shouldFail, exportCache, importCache } from "@optiprune/core";
|
|
10
10
|
// @ts-ignore
|
|
11
11
|
import { formatTerminal, formatSarif } from "@optiprune/core/reporters";
|
|
12
12
|
/** ANSI colour helpers */
|
|
@@ -67,6 +67,10 @@ function formatTerminalExtended(report) {
|
|
|
67
67
|
program
|
|
68
68
|
.name("optiprune")
|
|
69
69
|
.description("Finds dead code in TypeScript/JavaScript projects.")
|
|
70
|
+
.version(getCoreVersion(process.cwd()));
|
|
71
|
+
program
|
|
72
|
+
.command("analyze", { isDefault: true })
|
|
73
|
+
.description("Perform full analysis of the project")
|
|
70
74
|
.option("-r, --rootDir <path>", "Root directory of the project", process.cwd())
|
|
71
75
|
.option("-e, --entry <patterns...>", "Entry point patterns (glob or file paths)", [])
|
|
72
76
|
.option("-x, --extensions <exts...>", "File extensions to analyze", [".ts", ".tsx", ".js", ".jsx"])
|
|
@@ -79,10 +83,14 @@ program
|
|
|
79
83
|
.option("--skip-3", "Skip Layer 3 (SMT Constraint Solver)")
|
|
80
84
|
.option("--skip-4", "Skip Layer 4 (Concolic Execution Proofs)")
|
|
81
85
|
.option("-v, --verbose", "Show verbose output and internal graph state")
|
|
86
|
+
.option("--fix", "Automatically remove unused exports, dependencies, and unreachable files")
|
|
87
|
+
.option("--cache-from <path>", "Path to a JSON file to import cache from before analysis")
|
|
88
|
+
.option("--cache-to <path>", "Path to export the resulting cache to after analysis")
|
|
82
89
|
.action(async (options) => {
|
|
83
90
|
try {
|
|
84
91
|
const rootDir = options.rootDir ?? process.cwd();
|
|
85
|
-
|
|
92
|
+
// We cast to any here because the locally resolved @optiprune/core/types might
|
|
93
|
+
// be out of sync with the actual HeadLess API implementation during development.
|
|
86
94
|
const analyzerOptions = {
|
|
87
95
|
rootDir: rootDir,
|
|
88
96
|
entry: options.entry ?? [],
|
|
@@ -95,95 +103,11 @@ program
|
|
|
95
103
|
skip3: options.skip3,
|
|
96
104
|
skip4: options.skip4,
|
|
97
105
|
verbose: options.verbose,
|
|
106
|
+
fix: options.fix,
|
|
107
|
+
cacheFrom: options.cacheFrom,
|
|
108
|
+
cacheTo: options.cacheTo,
|
|
98
109
|
};
|
|
99
110
|
const report = await analyze(analyzerOptions);
|
|
100
|
-
// --- DEPENDENCY AUDIT INJECTION WITH BUILT-IN NORMALIZATION ---
|
|
101
|
-
try {
|
|
102
|
-
const pkgPath = path.join(rootDir, "package.json");
|
|
103
|
-
if (fs.existsSync(pkgPath)) {
|
|
104
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
105
|
-
const deps = (pkg.dependencies || {});
|
|
106
|
-
const devDeps = (pkg.devDependencies || {});
|
|
107
|
-
const allDeclared = new Set([...Object.keys(deps), ...Object.keys(devDeps)]);
|
|
108
|
-
const builtinModules = new Set([
|
|
109
|
-
'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console', 'constants',
|
|
110
|
-
'crypto', 'dgram', 'diagnostics_channel', 'dns', 'domain', 'events', 'fs', 'http', 'http2',
|
|
111
|
-
'https', 'inspector', 'module', 'net', 'os', 'path', 'perf_hooks',
|
|
112
|
-
'process', 'punycode', 'querystring', 'readline', 'repl', 'stream',
|
|
113
|
-
'string_decoder', 'sys', 'timers', 'tls', 'trace_events', 'tty',
|
|
114
|
-
'url', 'util', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'
|
|
115
|
-
]);
|
|
116
|
-
const usedExternals = new Set();
|
|
117
|
-
for (const module of report.modules) {
|
|
118
|
-
for (const edge of module.edges) {
|
|
119
|
-
if (edge.resolution === 'external') {
|
|
120
|
-
const specifier = edge.specifier;
|
|
121
|
-
if (!specifier)
|
|
122
|
-
continue;
|
|
123
|
-
// Normalize node: protocol
|
|
124
|
-
const cleanSpec = specifier.startsWith('node:') ? specifier.slice(5) : specifier;
|
|
125
|
-
let pkgName = cleanSpec.startsWith('@')
|
|
126
|
-
? cleanSpec.split('/').slice(0, 2).join('/')
|
|
127
|
-
: cleanSpec.split('/')[0];
|
|
128
|
-
if (pkgName && !builtinModules.has(pkgName)) {
|
|
129
|
-
usedExternals.add(pkgName);
|
|
130
|
-
if (!allDeclared.has(pkgName)) {
|
|
131
|
-
const alreadyReported = report.findings.some((f) => f.rule === "missing-dependency" && f.evidence?.package === pkgName);
|
|
132
|
-
if (!alreadyReported) {
|
|
133
|
-
report.findings.push({
|
|
134
|
-
rule: "missing-dependency",
|
|
135
|
-
severity: "error",
|
|
136
|
-
confidence: "high",
|
|
137
|
-
message: `Package '${pkgName}' is used in '${module.path}' but not declared in package.json.`,
|
|
138
|
-
file: "package.json",
|
|
139
|
-
evidence: { package: pkgName, type: "missing" }
|
|
140
|
-
});
|
|
141
|
-
report.summary.findings++;
|
|
142
|
-
report.summary.errors++;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
for (const depName of Object.keys(deps)) {
|
|
150
|
-
if (!usedExternals.has(depName)) {
|
|
151
|
-
const alreadyReported = report.findings.some((f) => f.rule === "unused-dependency" && f.evidence?.package === depName);
|
|
152
|
-
if (!alreadyReported) {
|
|
153
|
-
report.findings.push({
|
|
154
|
-
rule: "unused-dependency",
|
|
155
|
-
severity: "warning",
|
|
156
|
-
confidence: "high",
|
|
157
|
-
message: `Package '${depName}' is declared as a dependency but never imported.`,
|
|
158
|
-
file: "package.json",
|
|
159
|
-
evidence: { package: depName, type: "dependency" }
|
|
160
|
-
});
|
|
161
|
-
report.summary.findings++;
|
|
162
|
-
report.summary.warnings++;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
const skipList = new Set(['knip', 'husky', 'lint-staged', '@optiprune/cli', '@optiprune/core', 'typescript', 'vite', 'vitest', 'jest', 'eslint', 'prettier', '@types/node', 'ts-node', 'tsx']);
|
|
167
|
-
for (const devDepName of Object.keys(devDeps)) {
|
|
168
|
-
if (!usedExternals.has(devDepName) && !skipList.has(devDepName)) {
|
|
169
|
-
const alreadyReported = report.findings.some((f) => f.rule === "unused-dev-dependency" && f.evidence?.package === devDepName);
|
|
170
|
-
if (!alreadyReported) {
|
|
171
|
-
report.findings.push({
|
|
172
|
-
rule: "unused-dev-dependency",
|
|
173
|
-
severity: "info",
|
|
174
|
-
confidence: "medium",
|
|
175
|
-
message: `DevDependency '${devDepName}' appears unused.`,
|
|
176
|
-
file: "package.json",
|
|
177
|
-
evidence: { package: devDepName, type: "devDependency" }
|
|
178
|
-
});
|
|
179
|
-
report.summary.findings++;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
catch (e) { }
|
|
186
|
-
// --- END OF INJECTION ---
|
|
187
111
|
if (options.sarif) {
|
|
188
112
|
console.log(formatSarif(report));
|
|
189
113
|
}
|
|
@@ -197,7 +121,37 @@ program
|
|
|
197
121
|
process.exit(1);
|
|
198
122
|
}
|
|
199
123
|
catch (error) {
|
|
200
|
-
console.error("An unexpected error occurred:", error);
|
|
124
|
+
console.error("An unexpected error occurred during analysis:", error);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
program
|
|
129
|
+
.command("export-cache <targetPath>")
|
|
130
|
+
.description("Export the current analysis cache to a JSON file")
|
|
131
|
+
.option("-r, --rootDir <path>", "Root directory of the project", process.cwd())
|
|
132
|
+
.action(async (targetPath, options) => {
|
|
133
|
+
try {
|
|
134
|
+
const rootDir = options.rootDir ?? process.cwd();
|
|
135
|
+
await exportCache(rootDir, targetPath);
|
|
136
|
+
console.log(`${yellow("✔")} Cache exported to ${bold(targetPath)}`);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
console.error("Failed to export cache:", error);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
program
|
|
144
|
+
.command("import-cache <sourcePath>")
|
|
145
|
+
.description("Import an external cache JSON file into the local directory")
|
|
146
|
+
.option("-r, --rootDir <path>", "Root directory of the project", process.cwd())
|
|
147
|
+
.action(async (sourcePath, options) => {
|
|
148
|
+
try {
|
|
149
|
+
const rootDir = options.rootDir ?? process.cwd();
|
|
150
|
+
await importCache(rootDir, sourcePath);
|
|
151
|
+
console.log(`${yellow("✔")} Cache imported from ${bold(sourcePath)}`);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error("Failed to import cache:", error);
|
|
201
155
|
process.exit(1);
|
|
202
156
|
}
|
|
203
157
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,IAAI,MAAM,OAAO,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,2EAA2E;AAC3E,2DAA2D;AAC3D,aAAa;AACb,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|