deslop-cli 0.0.20 → 0.0.21

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 (3) hide show
  1. package/README.md +30 -29
  2. package/dist/cli.mjs +20 -1
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -49,40 +49,41 @@ deslop ./my-app --fail-on-cycles
49
49
 
50
50
  The default scan emits the following finding categories (each grouped in human output, fully detailed in `--json`):
51
51
 
52
- | Category | What it catches |
53
- | ------------------------- | -------------------------------------------------------------------------------- |
54
- | `unusedFiles` | Files unreachable from any entry point |
55
- | `unusedExports` | Exported symbols never imported anywhere |
56
- | `unusedDependencies` | `package.json` deps not imported |
57
- | `circularDependencies` | Import cycles |
58
- | `redundantAliases` | `import { x as x }`, useless re-export renames |
59
- | `duplicateExports` | Same name exported twice from one module |
60
- | `duplicateImports` | Same specifier imported on multiple lines (merge them) |
61
- | `redundantTypePatterns` | `T & {}`, `Partial<Partial<T>>`, `Pick<T, keyof T>`, empty `extends` |
62
- | `identityWrappers` | `const wrap = (x) => fn(x)`, calls without transforming |
63
- | `duplicateTypeDefinitions`| Same structural type declared in multiple files |
64
- | `duplicateInlineTypes` | Anonymous `{ a, b, c }` shapes repeated across modules |
65
- | `simplifiableFunctions` | `(x) => { return f(x) }`, `await x; return x;`, useless `async` |
66
- | `simplifiableExpressions` | `!!x`, `x ? x : y`, `cond ? true : false`, `x !== null && x !== undefined` |
67
- | `duplicateConstants` | Same literal value used in N files under different names |
68
- | `analysisErrors` | Structured info / warning / error notes (parse failures, skipped files, etc.) |
52
+ | Category | What it catches |
53
+ | -------------------------- | ----------------------------------------------------------------------------- |
54
+ | `unusedFiles` | Files unreachable from any entry point |
55
+ | `unusedExports` | Exported symbols never imported anywhere |
56
+ | `unusedDependencies` | `package.json` deps not imported |
57
+ | `circularDependencies` | Import cycles |
58
+ | `redundantAliases` | `import { x as x }`, useless re-export renames |
59
+ | `duplicateExports` | Same name exported twice from one module |
60
+ | `duplicateImports` | Same specifier imported on multiple lines (merge them) |
61
+ | `redundantTypePatterns` | `T & {}`, `Partial<Partial<T>>`, `Pick<T, keyof T>`, empty `extends` |
62
+ | `identityWrappers` | `const wrap = (x) => fn(x)`, calls without transforming |
63
+ | `duplicateTypeDefinitions` | Same structural type declared in multiple files |
64
+ | `duplicateInlineTypes` | Anonymous `{ a, b, c }` shapes repeated across modules |
65
+ | `simplifiableFunctions` | `(x) => { return f(x) }`, `await x; return x;`, useless `async` |
66
+ | `simplifiableExpressions` | `!!x`, `x ? x : y`, `cond ? true : false`, `x !== null && x !== undefined` |
67
+ | `duplicateConstants` | Same literal value used in N files under different names |
68
+ | `analysisErrors` | Structured info / warning / error notes (parse failures, skipped files, etc.) |
69
69
 
70
70
  Type-aware findings (`unusedTypes`, `unusedClassMembers`, `misclassifiedDependencies`, etc.) require enabling the semantic layer programmatically. See the [`deslop-js` README](https://github.com/aidenybai/deslop-js#semantic-type-aware-analysis). They are not exposed via CLI flags yet.
71
71
 
72
72
  ### Options
73
73
 
74
- | Option | Description |
75
- | ------------------------- | ----------------------------------------------------------------- |
76
- | `[root]` | Project root directory (default: `.`; must exist) |
77
- | `-e, --entry <pattern>` | Entry point glob patterns |
78
- | `-i, --ignore <pattern>` | Glob patterns to exclude |
79
- | `--extensions <ext>` | File extensions to scan (e.g. `.ts` `.vue`) |
80
- | `--tsconfig <path>` | Path to tsconfig.json for alias resolution |
81
- | `--report-types` | Include type-only exports in results |
82
- | `--include-entry-exports` | Report unused exports from entry files |
83
- | `--json` | Output results as JSON |
84
- | `--fail-on-issues` | Exit 1 when unused files, exports, or dependencies are found |
85
- | `--fail-on-cycles` | Exit 1 when circular imports are found |
74
+ | Option | Description |
75
+ | ------------------------- | ------------------------------------------------------------ |
76
+ | `[root]` | Project root directory (default: `.`; must exist) |
77
+ | `-e, --entry <pattern>` | Entry point glob patterns |
78
+ | `-i, --ignore <pattern>` | Glob patterns to exclude |
79
+ | `--extensions <ext>` | File extensions to scan (e.g. `.ts` `.vue`) |
80
+ | `--tsconfig <path>` | Path to tsconfig.json for alias resolution |
81
+ | `--paths <alias=target>` | Explicit path-alias mappings (e.g. `@app/*=src/*`), repeatable |
82
+ | `--report-types` | Include type-only exports in results |
83
+ | `--include-entry-exports` | Report unused exports from entry files |
84
+ | `--json` | Output results as JSON |
85
+ | `--fail-on-issues` | Exit 1 when unused files, exports, or dependencies are found |
86
+ | `--fail-on-cycles` | Exit 1 when circular imports are found |
86
87
 
87
88
  ### Exit codes
88
89
 
package/dist/cli.mjs CHANGED
@@ -206,6 +206,7 @@ const runAnalyze = async (options, output = defaultAnalyzeOutput()) => {
206
206
  ignorePatterns: options.ignore ?? [],
207
207
  includeExtensions: options.extensions,
208
208
  tsConfigPath: options.tsconfig,
209
+ paths: options.paths,
209
210
  reportTypes: options.reportTypes,
210
211
  includeEntryExports: options.includeEntryExports
211
212
  }));
@@ -226,12 +227,30 @@ const readPackageVersion = (moduleUrl) => {
226
227
 
227
228
  //#endregion
228
229
  //#region src/cli.ts
230
+ const parsePathsOption = (rawPaths) => {
231
+ if (!rawPaths || rawPaths.length === 0) return void 0;
232
+ const pathMap = {};
233
+ for (const entry of rawPaths) {
234
+ const separatorIndex = entry.indexOf("=");
235
+ const pattern = separatorIndex === -1 ? "" : entry.slice(0, separatorIndex);
236
+ const target = separatorIndex === -1 ? "" : entry.slice(separatorIndex + 1);
237
+ if (!pattern || !target) {
238
+ process.stderr.write(`deslop: ignoring malformed --paths entry "${entry}" (expected "alias=target", e.g. "@app/*=src/*")\n`);
239
+ continue;
240
+ }
241
+ const existing = pathMap[pattern];
242
+ if (existing) existing.push(target);
243
+ else pathMap[pattern] = [target];
244
+ }
245
+ return Object.keys(pathMap).length > 0 ? pathMap : void 0;
246
+ };
229
247
  const toAnalyzeOptions = (root, optionValues) => ({
230
248
  root: root ?? ".",
231
249
  entry: optionValues.entry,
232
250
  ignore: optionValues.ignore,
233
251
  extensions: optionValues.extensions,
234
252
  tsconfig: optionValues.tsconfig,
253
+ paths: parsePathsOption(optionValues.paths),
235
254
  reportTypes: Boolean(optionValues.reportTypes),
236
255
  includeEntryExports: Boolean(optionValues.includeEntryExports),
237
256
  json: Boolean(optionValues.json),
@@ -242,7 +261,7 @@ const runAnalyzeAction = async (root, optionValues) => {
242
261
  const exitCode = await runAnalyze(toAnalyzeOptions(root, optionValues));
243
262
  process.exitCode = exitCode;
244
263
  };
245
- const addAnalyzeOptions = (command) => command.argument("[root]", "project root directory", ".").option("-e, --entry <pattern...>", "entry point glob patterns").option("-i, --ignore <pattern...>", "glob patterns to exclude from analysis").option("--extensions <extension...>", "file extensions to scan (e.g. .ts .vue)").option("--tsconfig <path>", "path to tsconfig.json for path alias resolution").option("--report-types", "include type-only exports in results").option("--include-entry-exports", "report unused exports from entry files").option("--json", "output results as JSON").option("--fail-on-issues", "exit with code 1 when unused files, exports, or dependencies are found").option("--fail-on-cycles", "exit with code 1 when circular imports are found");
264
+ const addAnalyzeOptions = (command) => command.argument("[root]", "project root directory", ".").option("-e, --entry <pattern...>", "entry point glob patterns").option("-i, --ignore <pattern...>", "glob patterns to exclude from analysis").option("--extensions <extension...>", "file extensions to scan (e.g. .ts .vue)").option("--tsconfig <path>", "path to tsconfig.json for path alias resolution").option("--paths <alias=target...>", "path alias mappings (e.g. @lib/*=src/lib/*)").option("--report-types", "include type-only exports in results").option("--include-entry-exports", "report unused exports from entry files").option("--json", "output results as JSON").option("--fail-on-issues", "exit with code 1 when unused files, exports, or dependencies are found").option("--fail-on-cycles", "exit with code 1 when circular imports are found");
246
265
  const program = new Command();
247
266
  program.name("deslop").description("Find unused files, exports, dependencies, and circular imports in JavaScript projects").version(readPackageVersion(import.meta.url));
248
267
  addAnalyzeOptions(program).action(runAnalyzeAction);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deslop-cli",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "CLI for deslop-js — find unused files, exports, and dependencies",
5
5
  "keywords": [
6
6
  "cli",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "commander": "^14.0.3",
43
- "deslop-js": "0.0.20"
43
+ "deslop-js": "0.0.21"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^25.6.0"