@macrulez/devtoolz 0.1.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +262 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +330 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/case-check/core.d.ts +17 -0
  7. package/dist/commands/case-check/core.js +46 -0
  8. package/dist/commands/case-check/core.js.map +1 -0
  9. package/dist/commands/case-check/parse.d.ts +10 -0
  10. package/dist/commands/case-check/parse.js +52 -0
  11. package/dist/commands/case-check/parse.js.map +1 -0
  12. package/dist/commands/case-check/report.d.ts +3 -0
  13. package/dist/commands/case-check/report.js +38 -0
  14. package/dist/commands/case-check/report.js.map +1 -0
  15. package/dist/commands/case-check/resolve-case.d.ts +14 -0
  16. package/dist/commands/case-check/resolve-case.js +163 -0
  17. package/dist/commands/case-check/resolve-case.js.map +1 -0
  18. package/dist/commands/case-check/run.d.ts +31 -0
  19. package/dist/commands/case-check/run.js +72 -0
  20. package/dist/commands/case-check/run.js.map +1 -0
  21. package/dist/commands/case-check/tsconfig-paths.d.ts +19 -0
  22. package/dist/commands/case-check/tsconfig-paths.js +119 -0
  23. package/dist/commands/case-check/tsconfig-paths.js.map +1 -0
  24. package/dist/commands/case-check/vue.d.ts +8 -0
  25. package/dist/commands/case-check/vue.js +26 -0
  26. package/dist/commands/case-check/vue.js.map +1 -0
  27. package/dist/commands/console-strip/core.d.ts +23 -0
  28. package/dist/commands/console-strip/core.js +104 -0
  29. package/dist/commands/console-strip/core.js.map +1 -0
  30. package/dist/commands/console-strip/report.d.ts +3 -0
  31. package/dist/commands/console-strip/report.js +47 -0
  32. package/dist/commands/console-strip/report.js.map +1 -0
  33. package/dist/commands/console-strip/run.d.ts +30 -0
  34. package/dist/commands/console-strip/run.js +55 -0
  35. package/dist/commands/console-strip/run.js.map +1 -0
  36. package/dist/commands/console-strip/vue.d.ts +8 -0
  37. package/dist/commands/console-strip/vue.js +28 -0
  38. package/dist/commands/console-strip/vue.js.map +1 -0
  39. package/dist/commands/dead-exports/core.d.ts +19 -0
  40. package/dist/commands/dead-exports/core.js +136 -0
  41. package/dist/commands/dead-exports/core.js.map +1 -0
  42. package/dist/commands/dead-exports/entry.d.ts +2 -0
  43. package/dist/commands/dead-exports/entry.js +93 -0
  44. package/dist/commands/dead-exports/entry.js.map +1 -0
  45. package/dist/commands/dead-exports/parse.d.ts +30 -0
  46. package/dist/commands/dead-exports/parse.js +174 -0
  47. package/dist/commands/dead-exports/parse.js.map +1 -0
  48. package/dist/commands/dead-exports/report.d.ts +3 -0
  49. package/dist/commands/dead-exports/report.js +27 -0
  50. package/dist/commands/dead-exports/report.js.map +1 -0
  51. package/dist/commands/dead-exports/resolve.d.ts +10 -0
  52. package/dist/commands/dead-exports/resolve.js +58 -0
  53. package/dist/commands/dead-exports/resolve.js.map +1 -0
  54. package/dist/commands/dead-exports/run.d.ts +21 -0
  55. package/dist/commands/dead-exports/run.js +51 -0
  56. package/dist/commands/dead-exports/run.js.map +1 -0
  57. package/dist/commands/dead-exports/workspace.d.ts +14 -0
  58. package/dist/commands/dead-exports/workspace.js +99 -0
  59. package/dist/commands/dead-exports/workspace.js.map +1 -0
  60. package/dist/commands/exports-doctor/core.d.ts +13 -0
  61. package/dist/commands/exports-doctor/core.js +85 -0
  62. package/dist/commands/exports-doctor/core.js.map +1 -0
  63. package/dist/commands/exports-doctor/parse.d.ts +20 -0
  64. package/dist/commands/exports-doctor/parse.js +80 -0
  65. package/dist/commands/exports-doctor/parse.js.map +1 -0
  66. package/dist/commands/exports-doctor/report.d.ts +3 -0
  67. package/dist/commands/exports-doctor/report.js +36 -0
  68. package/dist/commands/exports-doctor/report.js.map +1 -0
  69. package/dist/commands/exports-doctor/resolve-path.d.ts +10 -0
  70. package/dist/commands/exports-doctor/resolve-path.js +46 -0
  71. package/dist/commands/exports-doctor/resolve-path.js.map +1 -0
  72. package/dist/commands/exports-doctor/run.d.ts +13 -0
  73. package/dist/commands/exports-doctor/run.js +25 -0
  74. package/dist/commands/exports-doctor/run.js.map +1 -0
  75. package/dist/commands/readme-check/core.d.ts +22 -0
  76. package/dist/commands/readme-check/core.js +92 -0
  77. package/dist/commands/readme-check/core.js.map +1 -0
  78. package/dist/commands/readme-check/extract.d.ts +9 -0
  79. package/dist/commands/readme-check/extract.js +48 -0
  80. package/dist/commands/readme-check/extract.js.map +1 -0
  81. package/dist/commands/readme-check/lang.d.ts +8 -0
  82. package/dist/commands/readme-check/lang.js +21 -0
  83. package/dist/commands/readme-check/lang.js.map +1 -0
  84. package/dist/commands/readme-check/report.d.ts +3 -0
  85. package/dist/commands/readme-check/report.js +31 -0
  86. package/dist/commands/readme-check/report.js.map +1 -0
  87. package/dist/commands/readme-check/run.d.ts +19 -0
  88. package/dist/commands/readme-check/run.js +34 -0
  89. package/dist/commands/readme-check/run.js.map +1 -0
  90. package/dist/commands/readme-check/tsconfig.d.ts +9 -0
  91. package/dist/commands/readme-check/tsconfig.js +26 -0
  92. package/dist/commands/readme-check/tsconfig.js.map +1 -0
  93. package/dist/commands/readme-check/typecheck.d.ts +31 -0
  94. package/dist/commands/readme-check/typecheck.js +82 -0
  95. package/dist/commands/readme-check/typecheck.js.map +1 -0
  96. package/dist/commands/strip-comments/apply-deletions.d.ts +17 -0
  97. package/dist/commands/strip-comments/apply-deletions.js +74 -0
  98. package/dist/commands/strip-comments/apply-deletions.js.map +1 -0
  99. package/dist/commands/strip-comments/core.d.ts +15 -0
  100. package/dist/commands/strip-comments/core.js +111 -0
  101. package/dist/commands/strip-comments/core.js.map +1 -0
  102. package/dist/commands/strip-comments/report.d.ts +6 -0
  103. package/dist/commands/strip-comments/report.js +30 -0
  104. package/dist/commands/strip-comments/report.js.map +1 -0
  105. package/dist/commands/strip-comments/run.d.ts +28 -0
  106. package/dist/commands/strip-comments/run.js +50 -0
  107. package/dist/commands/strip-comments/run.js.map +1 -0
  108. package/dist/commands/strip-comments/vue.d.ts +6 -0
  109. package/dist/commands/strip-comments/vue.js +65 -0
  110. package/dist/commands/strip-comments/vue.js.map +1 -0
  111. package/dist/format/colors.d.ts +8 -0
  112. package/dist/format/colors.js +14 -0
  113. package/dist/format/colors.js.map +1 -0
  114. package/dist/format/diff-render.d.ts +2 -0
  115. package/dist/format/diff-render.js +35 -0
  116. package/dist/format/diff-render.js.map +1 -0
  117. package/dist/format/file-list.d.ts +14 -0
  118. package/dist/format/file-list.js +26 -0
  119. package/dist/format/file-list.js.map +1 -0
  120. package/dist/format/findings-list.d.ts +14 -0
  121. package/dist/format/findings-list.js +23 -0
  122. package/dist/format/findings-list.js.map +1 -0
  123. package/dist/format/vibes.d.ts +10 -0
  124. package/dist/format/vibes.js +67 -0
  125. package/dist/format/vibes.js.map +1 -0
  126. package/dist/index.d.ts +47 -0
  127. package/dist/index.js +29 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/utils/diff.d.ts +1 -0
  130. package/dist/utils/diff.js +13 -0
  131. package/dist/utils/diff.js.map +1 -0
  132. package/dist/utils/walk.d.ts +19 -0
  133. package/dist/utils/walk.js +96 -0
  134. package/dist/utils/walk.js.map +1 -0
  135. package/package.json +57 -0
@@ -0,0 +1,30 @@
1
+ export interface ExportedName {
2
+ name: string;
3
+ isType: boolean;
4
+ isDefault: boolean;
5
+ line: number;
6
+ }
7
+ export interface ReexportEntry {
8
+ /** the raw specifier, e.g. './core.js' */
9
+ from: string;
10
+ /** the name as exported by the SOURCE module, or '*' for `export * from`/`export * as x from` */
11
+ imported: string;
12
+ /** the name this file re-exports it as (may differ via `as`); '*' mirrors `imported` */
13
+ exportedAs: string;
14
+ isType: boolean;
15
+ }
16
+ export interface ImportedName {
17
+ /** the raw specifier */
18
+ from: string;
19
+ /** the name as exported by the source module, 'default', or '*' for a namespace import */
20
+ imported: string;
21
+ isType: boolean;
22
+ }
23
+ export interface FileAnalysis {
24
+ exports: ExportedName[];
25
+ reexports: ReexportEntry[];
26
+ imports: ImportedName[];
27
+ /** a dynamic import() whose argument isn't a string literal — can't be resolved, worth flagging */
28
+ hasUnresolvableDynamicImport: boolean;
29
+ }
30
+ export declare function analyzeFile(text: string, file: string): FileAnalysis;
@@ -0,0 +1,174 @@
1
+ // Per-file extraction of exports/imports via a real TS parse — no regex
2
+ // guessing at `export`/`import` keywords, so a string/comment containing
3
+ // those words is never mistaken for the real thing.
4
+ import ts from 'typescript';
5
+ function scriptKindFor(file) {
6
+ return file.endsWith('.tsx')
7
+ ? ts.ScriptKind.TSX
8
+ : file.endsWith('.jsx')
9
+ ? ts.ScriptKind.JSX
10
+ : ts.ScriptKind.TS;
11
+ }
12
+ function hasExportModifier(node) {
13
+ return (ts.canHaveModifiers(node) &&
14
+ (ts.getModifiers(node)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false));
15
+ }
16
+ function hasDefaultModifier(node) {
17
+ return (ts.canHaveModifiers(node) &&
18
+ (ts.getModifiers(node)?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) ?? false));
19
+ }
20
+ // Not `ts.isImportCall` — that helper exists at runtime but isn't part of
21
+ // this TypeScript version's typed public API. A dynamic `import(...)`
22
+ // parses as a CallExpression whose callee is the `import` keyword itself
23
+ // used as an expression; checking that structurally is exactly what the
24
+ // untyped helper does internally.
25
+ function isDynamicImportCall(node) {
26
+ return ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword;
27
+ }
28
+ function collectBindingNames(name, out) {
29
+ // Only plain identifiers are attributed — `export const { a, b } = obj`
30
+ // (destructured) is a rare enough pattern for a top-level export that
31
+ // skipping it (rather than guessing) is the safer default.
32
+ if (ts.isIdentifier(name))
33
+ out.push(name.text);
34
+ }
35
+ export function analyzeFile(text, file) {
36
+ const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, scriptKindFor(file));
37
+ function lineOf(node) {
38
+ return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
39
+ }
40
+ const exports = [];
41
+ const reexports = [];
42
+ const imports = [];
43
+ let hasUnresolvableDynamicImport = false;
44
+ for (const stmt of sf.statements) {
45
+ if (ts.isExportDeclaration(stmt)) {
46
+ const isTypeOnly = stmt.isTypeOnly;
47
+ const moduleSpecifier = stmt.moduleSpecifier && ts.isStringLiteral(stmt.moduleSpecifier)
48
+ ? stmt.moduleSpecifier.text
49
+ : null;
50
+ if (stmt.exportClause) {
51
+ if (ts.isNamedExports(stmt.exportClause)) {
52
+ for (const el of stmt.exportClause.elements) {
53
+ const importedName = (el.propertyName ?? el.name).text;
54
+ const exportedAs = el.name.text;
55
+ const elIsType = isTypeOnly || el.isTypeOnly;
56
+ if (moduleSpecifier) {
57
+ reexports.push({
58
+ from: moduleSpecifier,
59
+ imported: importedName,
60
+ exportedAs,
61
+ isType: elIsType,
62
+ });
63
+ }
64
+ else {
65
+ exports.push({
66
+ name: exportedAs,
67
+ isType: elIsType,
68
+ isDefault: false,
69
+ line: lineOf(el),
70
+ });
71
+ }
72
+ }
73
+ }
74
+ else if (ts.isNamespaceExport(stmt.exportClause) && moduleSpecifier) {
75
+ // `export * as ns from './y'` — ns itself is a real named export
76
+ // of THIS file (a namespace object), not traced further.
77
+ exports.push({
78
+ name: stmt.exportClause.name.text,
79
+ isType: isTypeOnly,
80
+ isDefault: false,
81
+ line: lineOf(stmt.exportClause),
82
+ });
83
+ }
84
+ }
85
+ else if (moduleSpecifier) {
86
+ // `export * from './y'` — every name './y' exports becomes
87
+ // reachable through this file too; resolved in core.ts once every
88
+ // file's own export list is known.
89
+ reexports.push({
90
+ from: moduleSpecifier,
91
+ imported: '*',
92
+ exportedAs: '*',
93
+ isType: isTypeOnly,
94
+ });
95
+ }
96
+ continue;
97
+ }
98
+ if (ts.isExportAssignment(stmt)) {
99
+ // `export default expr` and legacy `export = expr` both surface as
100
+ // this file's default-like export — see FileAnalysis' isDefault
101
+ // doc: usage detection for it is intentionally loose.
102
+ exports.push({ name: 'default', isType: false, isDefault: true, line: lineOf(stmt) });
103
+ continue;
104
+ }
105
+ if (ts.isImportDeclaration(stmt) && ts.isStringLiteral(stmt.moduleSpecifier)) {
106
+ const from = stmt.moduleSpecifier.text;
107
+ const clause = stmt.importClause;
108
+ if (!clause)
109
+ continue; // bare `import './x'` — side-effect only, not a usage of any named export
110
+ if (clause.name)
111
+ imports.push({ from, imported: 'default', isType: clause.isTypeOnly });
112
+ if (clause.namedBindings) {
113
+ if (ts.isNamespaceImport(clause.namedBindings)) {
114
+ imports.push({ from, imported: '*', isType: clause.isTypeOnly });
115
+ }
116
+ else if (ts.isNamedImports(clause.namedBindings)) {
117
+ for (const el of clause.namedBindings.elements) {
118
+ const importedName = (el.propertyName ?? el.name).text;
119
+ imports.push({
120
+ from,
121
+ imported: importedName,
122
+ isType: clause.isTypeOnly || el.isTypeOnly,
123
+ });
124
+ }
125
+ }
126
+ }
127
+ continue;
128
+ }
129
+ if (hasExportModifier(stmt)) {
130
+ const isType = ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt);
131
+ const isDefault = hasDefaultModifier(stmt);
132
+ if (ts.isVariableStatement(stmt)) {
133
+ for (const decl of stmt.declarationList.declarations) {
134
+ const names = [];
135
+ collectBindingNames(decl.name, names);
136
+ for (const name of names) {
137
+ exports.push({ name, isType: false, isDefault: false, line: lineOf(decl) });
138
+ }
139
+ }
140
+ }
141
+ else if ((ts.isFunctionDeclaration(stmt) ||
142
+ ts.isClassDeclaration(stmt) ||
143
+ ts.isInterfaceDeclaration(stmt) ||
144
+ ts.isTypeAliasDeclaration(stmt) ||
145
+ ts.isEnumDeclaration(stmt) ||
146
+ ts.isModuleDeclaration(stmt)) &&
147
+ stmt.name) {
148
+ const name = ts.isIdentifier(stmt.name) ? stmt.name.text : stmt.name.text;
149
+ exports.push({ name: isDefault ? 'default' : name, isType, isDefault, line: lineOf(stmt) });
150
+ }
151
+ }
152
+ }
153
+ // Dynamic import() calls can appear anywhere in an expression, not just
154
+ // at the top level — a full walk (not just top-level statements) is
155
+ // needed to find them all.
156
+ function visit(node) {
157
+ if (isDynamicImportCall(node)) {
158
+ const arg = node.arguments[0];
159
+ if (arg && ts.isStringLiteral(arg)) {
160
+ // A literal path we can resolve — conservatively treat the whole
161
+ // target module as used (see core.ts) rather than trying to trace
162
+ // which bindings a `const { x } = await import(...)` destructures.
163
+ imports.push({ from: arg.text, imported: '*', isType: false });
164
+ }
165
+ else {
166
+ hasUnresolvableDynamicImport = true;
167
+ }
168
+ }
169
+ ts.forEachChild(node, visit);
170
+ }
171
+ visit(sf);
172
+ return { exports, reexports, imports, hasUnresolvableDynamicImport };
173
+ }
174
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type VibesOptions } from '../../format/vibes.js';
2
+ import type { DeadExportsReport } from './run.js';
3
+ export declare function renderDeadExportsReport(report: DeadExportsReport, options?: VibesOptions): string;
@@ -0,0 +1,27 @@
1
+ import { banner, cleanCelebration } from '../../format/vibes.js';
2
+ import { formatFindingsRows } from '../../format/findings-list.js';
3
+ export function renderDeadExportsReport(report, options = {}) {
4
+ const isClean = report.findings.length === 0;
5
+ if (options.quiet && isClean && !report.hasUnresolvableDynamicImports)
6
+ return '';
7
+ const lines = [];
8
+ if (!options.quiet && !options.plain)
9
+ lines.push(banner(), '');
10
+ lines.push(`Scanned ${report.filesScanned} file${report.filesScanned === 1 ? '' : 's'}.`, '');
11
+ if (isClean) {
12
+ lines.push(cleanCelebration(options));
13
+ }
14
+ else {
15
+ lines.push(`${report.findings.length} dead export${report.findings.length === 1 ? '' : 's'} found:`);
16
+ lines.push(...formatFindingsRows(report.findings.map((f) => ({
17
+ location: `${f.file}:${f.line}`,
18
+ name: f.name,
19
+ tag: f.isDefault ? '(default)' : f.isType ? '(type)' : '',
20
+ })), options));
21
+ }
22
+ if (report.hasUnresolvableDynamicImports) {
23
+ lines.push('', "Note: found a dynamic import() whose path isn't a plain string literal — it could not be resolved, so results here may include false positives.");
24
+ }
25
+ return lines.join('\n');
26
+ }
27
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAqB,MAAM,uBAAuB,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAGlE,MAAM,UAAU,uBAAuB,CACrC,MAAyB,EACzB,UAAwB,EAAE;IAE1B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,6BAA6B;QAAE,OAAO,EAAE,CAAA;IAEhF,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;IAE9D,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,YAAY,QAAQ,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAA;IAE7F,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAA;IACvC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,eAAe,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,CACzF,CAAA;QACD,KAAK,CAAC,IAAI,CACR,GAAG,kBAAkB,CACnB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1B,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE;YAC/B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;SAC1D,CAAC,CAAC,EACH,OAAO,CACR,CACF,CAAA;IACH,CAAC;IAED,IAAI,MAAM,CAAC,6BAA6B,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iJAAiJ,CAClJ,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Resolves a relative import specifier (`./foo`, `../bar/baz`) against
3
+ * the file that contains it to a real, existing file on disk — or `null`
4
+ * if nothing matches any of the conventions this project's commands rely
5
+ * on elsewhere (extensionless imports, NodeNext `.js`-means-`.ts`,
6
+ * directory-with-index). Only ever called with specifiers that already
7
+ * look relative (`.`/`..`-prefixed) — bare package specifiers go through
8
+ * workspace.ts instead.
9
+ */
10
+ export declare function resolveRelativeSpecifier(fromFile: string, specifier: string): string | null;
@@ -0,0 +1,58 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ const CANDIDATE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
4
+ // A NodeNext-style project writes `import { x } from './core.js'` in a
5
+ // .ts file even though the real file on disk is `./core.ts` — the
6
+ // specifier names the file's post-build extension, not its source one
7
+ // (devtoolz's own codebase does exactly this — see src/cli.ts). When the
8
+ // literal specifier doesn't resolve, each of these swaps is tried too.
9
+ const NODENEXT_SWAPS = {
10
+ '.js': ['.ts', '.tsx'],
11
+ '.mjs': ['.mts'],
12
+ '.cjs': ['.cts'],
13
+ };
14
+ function tryFile(path) {
15
+ return existsSync(path) ? path : null;
16
+ }
17
+ /**
18
+ * Resolves a relative import specifier (`./foo`, `../bar/baz`) against
19
+ * the file that contains it to a real, existing file on disk — or `null`
20
+ * if nothing matches any of the conventions this project's commands rely
21
+ * on elsewhere (extensionless imports, NodeNext `.js`-means-`.ts`,
22
+ * directory-with-index). Only ever called with specifiers that already
23
+ * look relative (`.`/`..`-prefixed) — bare package specifiers go through
24
+ * workspace.ts instead.
25
+ */
26
+ export function resolveRelativeSpecifier(fromFile, specifier) {
27
+ const base = resolve(dirname(fromFile), specifier);
28
+ const direct = tryFile(base);
29
+ if (direct)
30
+ return direct;
31
+ const lastDot = base.lastIndexOf('.');
32
+ const lastSlash = Math.max(base.lastIndexOf('/'), base.lastIndexOf('\\'));
33
+ const hasExt = lastDot > lastSlash;
34
+ if (hasExt) {
35
+ const ext = base.slice(lastDot);
36
+ const withoutExt = base.slice(0, lastDot);
37
+ for (const swap of NODENEXT_SWAPS[ext] ?? []) {
38
+ const swapped = tryFile(withoutExt + swap);
39
+ if (swapped)
40
+ return swapped;
41
+ }
42
+ // Had an extension that didn't match anything above — don't also
43
+ // try appending a second extension or treating it as a directory.
44
+ return null;
45
+ }
46
+ for (const ext of CANDIDATE_EXTENSIONS) {
47
+ const withExt = tryFile(base + ext);
48
+ if (withExt)
49
+ return withExt;
50
+ }
51
+ for (const ext of CANDIDATE_EXTENSIONS) {
52
+ const withIndex = tryFile(join(base, `index${ext}`));
53
+ if (withIndex)
54
+ return withIndex;
55
+ }
56
+ return null;
57
+ }
58
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAElD,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAE3E,uEAAuE;AACvE,kEAAkE;AAClE,sEAAsE;AACtE,yEAAyE;AACzE,uEAAuE;AACvE,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,MAAM,CAAC;CACjB,CAAA;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB,EAAE,SAAiB;IAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAA;IAElD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;IACzE,MAAM,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QACzC,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;YAC1C,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAA;QAC7B,CAAC;QACD,iEAAiE;QACjE,kEAAkE;QAClE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAA;QACnC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAA;IAC7B,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAA;QACpD,IAAI,SAAS;YAAE,OAAO,SAAS,CAAA;IACjC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type DeadExportFinding } from './core.js';
2
+ export interface DeadExportsRunOptions {
3
+ paths: string[];
4
+ cwd: string;
5
+ extensions?: string[];
6
+ ignoreGlobs?: string[];
7
+ respectGitignore?: boolean;
8
+ /** extra public-entry files, on top of the auto-detected ones (--entry) */
9
+ entry?: string[];
10
+ /** also flag exports from public entry points. default false */
11
+ strict?: boolean;
12
+ /** auto-detect a pnpm/npm/yarn workspace for cross-package resolution. default true */
13
+ workspace?: boolean;
14
+ }
15
+ export interface DeadExportsReport {
16
+ filesScanned: number;
17
+ findings: DeadExportFinding[];
18
+ hasUnresolvableDynamicImports: boolean;
19
+ exitCode: number;
20
+ }
21
+ export declare function runDeadExports(options: DeadExportsRunOptions): DeadExportsReport;
@@ -0,0 +1,51 @@
1
+ import { relative } from 'node:path';
2
+ import { walk } from '../../utils/walk.js';
3
+ import { analyzeDeadExports } from './core.js';
4
+ import { findNearestPackageDir, resolvePublicEntries } from './entry.js';
5
+ import { detectWorkspace } from './workspace.js';
6
+ const DEFAULT_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
7
+ // Build-tool config files (tsup.config.ts, vitest.config.ts, ...) are
8
+ // loaded by that tool's own CLI via filename convention, never through a
9
+ // same-repo `import` — no static analysis can see that consumer, so their
10
+ // default export always looks unused. Confirmed against a real project
11
+ // (inview's own packages/*/tsup.config.ts) rather than assumed. Excluded
12
+ // from the scan entirely, same as `--ignore` would, rather than special-
13
+ // cased per-finding — a config file has essentially nothing else in it
14
+ // worth dead-code-checking anyway.
15
+ const DEFAULT_CONFIG_IGNORES = ['*.config.ts', '*.config.js', '*.config.mjs', '*.config.cjs'];
16
+ export function runDeadExports(options) {
17
+ const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
18
+ const files = walk(options.paths, {
19
+ cwd: options.cwd,
20
+ extensions,
21
+ ignoreGlobs: [...DEFAULT_CONFIG_IGNORES, ...(options.ignoreGlobs ?? [])],
22
+ ...(options.respectGitignore !== undefined
23
+ ? { respectGitignore: options.respectGitignore }
24
+ : {}),
25
+ });
26
+ const packageDir = findNearestPackageDir(options.cwd) ?? options.cwd;
27
+ const publicEntries = new Set(resolvePublicEntries(packageDir, options.entry ?? []));
28
+ const workspace = options.workspace !== false ? detectWorkspace(options.cwd) : null;
29
+ if (workspace) {
30
+ for (const pkg of workspace.packages) {
31
+ for (const entry of resolvePublicEntries(pkg.rootDir))
32
+ publicEntries.add(entry);
33
+ }
34
+ }
35
+ const analysis = analyzeDeadExports(files, {
36
+ publicEntries,
37
+ strict: options.strict ?? false,
38
+ workspace,
39
+ });
40
+ const findings = analysis.findings
41
+ .map((f) => ({ ...f, file: relative(options.cwd, f.file).split('\\').join('/') }))
42
+ .sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
43
+ const exitCode = findings.length > 0 ? 1 : 0;
44
+ return {
45
+ filesScanned: analysis.filesAnalyzed,
46
+ findings,
47
+ hasUnresolvableDynamicImports: analysis.hasUnresolvableDynamicImports,
48
+ exitCode,
49
+ };
50
+ }
51
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface WorkspacePackage {
2
+ name: string;
3
+ rootDir: string;
4
+ packageJson: Record<string, unknown>;
5
+ }
6
+ export interface WorkspaceInfo {
7
+ root: string;
8
+ packages: WorkspacePackage[];
9
+ }
10
+ /**
11
+ * Walks up from `startDir` looking for a pnpm/npm/yarn workspace root.
12
+ * Returns `null` if none is found — a plain single-package project.
13
+ */
14
+ export declare function detectWorkspace(startDir: string): WorkspaceInfo | null;
@@ -0,0 +1,99 @@
1
+ // Detects a pnpm/npm/yarn workspace so a sibling package's import of
2
+ // another package's export (e.g. `@macrulez/inview-vue` importing from
3
+ // `@macrulez/inview-core`, as it really does) doesn't read as a false
4
+ // "dead export" just because the reference lives in a different package
5
+ // directory than the one being checked — the exact case features.md's
6
+ // contract calls out.
7
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
8
+ import { dirname, join, resolve } from 'node:path';
9
+ function readPackageJson(dir) {
10
+ try {
11
+ return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ // Only the one shape pnpm-workspace.yaml realistically uses in practice —
18
+ // a top-level `packages:` key followed by `- 'glob'` list items. Not a
19
+ // general YAML parser; anything fancier (anchors, nested maps) isn't
20
+ // recognized and the file is treated as if it weren't there.
21
+ function parsePnpmWorkspaceYaml(text) {
22
+ const lines = text.split('\n');
23
+ const globs = [];
24
+ let inPackages = false;
25
+ for (const line of lines) {
26
+ if (/^packages:\s*$/.test(line)) {
27
+ inPackages = true;
28
+ continue;
29
+ }
30
+ if (inPackages) {
31
+ const item = line.match(/^\s*-\s*['"]?([^'"#]+)['"]?\s*(#.*)?$/);
32
+ if (item) {
33
+ globs.push(item[1].trim());
34
+ continue;
35
+ }
36
+ if (/^\S/.test(line))
37
+ break; // dedented past the packages: block
38
+ }
39
+ }
40
+ return globs;
41
+ }
42
+ function expandGlob(root, glob) {
43
+ // Only "dir/*" (one trailing wildcard segment) is supported — the
44
+ // overwhelming common case for a workspace's packages list. A glob
45
+ // without a wildcard is just a literal directory.
46
+ if (!glob.includes('*')) {
47
+ const dir = resolve(root, glob);
48
+ return existsSync(dir) && statSync(dir).isDirectory() ? [dir] : [];
49
+ }
50
+ const starIndex = glob.indexOf('*');
51
+ const prefix = glob.slice(0, starIndex).replace(/\/$/, '');
52
+ const parentDir = resolve(root, prefix);
53
+ if (!existsSync(parentDir))
54
+ return [];
55
+ return readdirSync(parentDir, { withFileTypes: true })
56
+ .filter((e) => e.isDirectory())
57
+ .map((e) => join(parentDir, e.name));
58
+ }
59
+ function packagesFromGlobs(root, globs) {
60
+ const packages = [];
61
+ for (const glob of globs) {
62
+ for (const dir of expandGlob(root, glob)) {
63
+ const pkgJson = readPackageJson(dir);
64
+ const name = pkgJson && typeof pkgJson.name === 'string' ? pkgJson.name : null;
65
+ if (pkgJson && name)
66
+ packages.push({ name, rootDir: dir, packageJson: pkgJson });
67
+ }
68
+ }
69
+ return packages;
70
+ }
71
+ /**
72
+ * Walks up from `startDir` looking for a pnpm/npm/yarn workspace root.
73
+ * Returns `null` if none is found — a plain single-package project.
74
+ */
75
+ export function detectWorkspace(startDir) {
76
+ let dir = resolve(startDir);
77
+ for (;;) {
78
+ const pnpmWorkspacePath = join(dir, 'pnpm-workspace.yaml');
79
+ if (existsSync(pnpmWorkspacePath)) {
80
+ const globs = parsePnpmWorkspaceYaml(readFileSync(pnpmWorkspacePath, 'utf8'));
81
+ return { root: dir, packages: packagesFromGlobs(dir, globs) };
82
+ }
83
+ const pkgJson = readPackageJson(dir);
84
+ if (pkgJson?.workspaces) {
85
+ const raw = pkgJson.workspaces;
86
+ const globs = Array.isArray(raw)
87
+ ? raw.filter((g) => typeof g === 'string')
88
+ : Array.isArray(raw?.packages)
89
+ ? raw.packages.filter((g) => typeof g === 'string')
90
+ : [];
91
+ return { root: dir, packages: packagesFromGlobs(dir, globs) };
92
+ }
93
+ const parent = dirname(dir);
94
+ if (parent === dir)
95
+ return null;
96
+ dir = parent;
97
+ }
98
+ }
99
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/workspace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type FindingKind = 'missing' | 'case-mismatch' | 'missing-shebang' | 'types-missing';
2
+ export interface ExportsDoctorFinding {
3
+ location: string;
4
+ path: string;
5
+ kind: FindingKind;
6
+ /** the real on-disk case, only for kind: 'case-mismatch' */
7
+ realPath?: string;
8
+ }
9
+ export interface ExportsDoctorResult {
10
+ packageName: string | null;
11
+ findings: ExportsDoctorFinding[];
12
+ }
13
+ export declare function checkPackage(pkg: Record<string, unknown>, packageDir: string): ExportsDoctorResult;
@@ -0,0 +1,85 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { collectDeclaredPaths, isBinLocation, isTypesLocation } from './parse.js';
3
+ import { checkDeclaredPath, resolveDeclaredPath } from './resolve-path.js';
4
+ function hasShebang(absolutePath) {
5
+ try {
6
+ const fd = readFileSync(absolutePath, { encoding: 'utf8' });
7
+ return fd.startsWith('#!');
8
+ }
9
+ catch {
10
+ return false; // unreadable — already reported as missing/case-mismatch by the caller, not a second finding
11
+ }
12
+ }
13
+ export function checkPackage(pkg, packageDir) {
14
+ const declared = collectDeclaredPaths(pkg);
15
+ const findings = [];
16
+ // Grouped by exports subpath key (the part inside `exports["..."]`), so
17
+ // the types-vs-runtime pairing check below only compares conditions
18
+ // that actually belong together, not e.g. `exports["."].types` against
19
+ // `exports["./cdn"].import`.
20
+ const okByExportsKey = new Map();
21
+ for (const entry of declared) {
22
+ const result = checkDeclaredPath(packageDir, entry.path);
23
+ if (result.status === 'missing') {
24
+ findings.push({ location: entry.location, path: entry.path, kind: 'missing' });
25
+ continue;
26
+ }
27
+ if (result.status === 'case-mismatch') {
28
+ findings.push({
29
+ location: entry.location,
30
+ path: entry.path,
31
+ kind: 'case-mismatch',
32
+ realPath: result.realPath,
33
+ });
34
+ continue;
35
+ }
36
+ // status: 'ok' from here on
37
+ const exportsKeyMatch = entry.location.match(/^exports\["([^"]+)"\]/);
38
+ if (exportsKeyMatch) {
39
+ const key = exportsKeyMatch[1];
40
+ const conditions = okByExportsKey.get(key) ?? new Set();
41
+ conditions.add(entry.location);
42
+ okByExportsKey.set(key, conditions);
43
+ }
44
+ if (isBinLocation(entry.location)) {
45
+ const absolute = resolveDeclaredPath(packageDir, entry.path);
46
+ if (!hasShebang(absolute)) {
47
+ findings.push({ location: entry.location, path: entry.path, kind: 'missing-shebang' });
48
+ }
49
+ }
50
+ }
51
+ // types-vs-runtime pairing: a `types` condition that's missing is
52
+ // already reported above via kind: 'missing' — this second pass instead
53
+ // looks for the OTHER direction, the one that's actually dangerous:
54
+ // every non-types condition under a subpath resolved fine (the package
55
+ // works at runtime), but `types` for that SAME subpath is nowhere in
56
+ // the declared paths at all (not just missing-on-disk — never even
57
+ // written), so TypeScript consumers get no types with no warning
58
+ // anywhere in a normal build.
59
+ const flaggedKeys = new Set();
60
+ for (const entry of declared) {
61
+ // Only entries declared inside a real conditions object are eligible —
62
+ // a bare string/array subpath value has no siblings at all, and
63
+ // TypeScript falls back to a colocated `.d.ts` file for those, so
64
+ // flagging them here would be a false positive.
65
+ if (!entry.isConditionEntry || isTypesLocation(entry.location))
66
+ continue;
67
+ const exportsKeyMatch = entry.location.match(/^exports\["([^"]+)"\]/);
68
+ if (!exportsKeyMatch)
69
+ continue;
70
+ const key = exportsKeyMatch[1];
71
+ if (flaggedKeys.has(key))
72
+ continue; // one finding per subpath, not one per condition under it
73
+ const hasAnyTypesDeclared = declared.some((d) => d.location.startsWith(`exports["${key}"]`) && isTypesLocation(d.location));
74
+ const runtimeResolvedOk = okByExportsKey.get(key)?.has(entry.location);
75
+ if (!hasAnyTypesDeclared && runtimeResolvedOk) {
76
+ findings.push({ location: `exports["${key}"]`, path: entry.path, kind: 'types-missing' });
77
+ flaggedKeys.add(key);
78
+ }
79
+ }
80
+ return {
81
+ packageName: typeof pkg.name === 'string' ? pkg.name : null,
82
+ findings,
83
+ };
84
+ }
85
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/commands/exports-doctor/core.ts"],"names":[],"mappings":"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"}