@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.
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +330 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/case-check/core.d.ts +17 -0
- package/dist/commands/case-check/core.js +46 -0
- package/dist/commands/case-check/core.js.map +1 -0
- package/dist/commands/case-check/parse.d.ts +10 -0
- package/dist/commands/case-check/parse.js +52 -0
- package/dist/commands/case-check/parse.js.map +1 -0
- package/dist/commands/case-check/report.d.ts +3 -0
- package/dist/commands/case-check/report.js +38 -0
- package/dist/commands/case-check/report.js.map +1 -0
- package/dist/commands/case-check/resolve-case.d.ts +14 -0
- package/dist/commands/case-check/resolve-case.js +163 -0
- package/dist/commands/case-check/resolve-case.js.map +1 -0
- package/dist/commands/case-check/run.d.ts +31 -0
- package/dist/commands/case-check/run.js +72 -0
- package/dist/commands/case-check/run.js.map +1 -0
- package/dist/commands/case-check/tsconfig-paths.d.ts +19 -0
- package/dist/commands/case-check/tsconfig-paths.js +119 -0
- package/dist/commands/case-check/tsconfig-paths.js.map +1 -0
- package/dist/commands/case-check/vue.d.ts +8 -0
- package/dist/commands/case-check/vue.js +26 -0
- package/dist/commands/case-check/vue.js.map +1 -0
- package/dist/commands/console-strip/core.d.ts +23 -0
- package/dist/commands/console-strip/core.js +104 -0
- package/dist/commands/console-strip/core.js.map +1 -0
- package/dist/commands/console-strip/report.d.ts +3 -0
- package/dist/commands/console-strip/report.js +47 -0
- package/dist/commands/console-strip/report.js.map +1 -0
- package/dist/commands/console-strip/run.d.ts +30 -0
- package/dist/commands/console-strip/run.js +55 -0
- package/dist/commands/console-strip/run.js.map +1 -0
- package/dist/commands/console-strip/vue.d.ts +8 -0
- package/dist/commands/console-strip/vue.js +28 -0
- package/dist/commands/console-strip/vue.js.map +1 -0
- package/dist/commands/dead-exports/core.d.ts +19 -0
- package/dist/commands/dead-exports/core.js +136 -0
- package/dist/commands/dead-exports/core.js.map +1 -0
- package/dist/commands/dead-exports/entry.d.ts +2 -0
- package/dist/commands/dead-exports/entry.js +93 -0
- package/dist/commands/dead-exports/entry.js.map +1 -0
- package/dist/commands/dead-exports/parse.d.ts +30 -0
- package/dist/commands/dead-exports/parse.js +174 -0
- package/dist/commands/dead-exports/parse.js.map +1 -0
- package/dist/commands/dead-exports/report.d.ts +3 -0
- package/dist/commands/dead-exports/report.js +27 -0
- package/dist/commands/dead-exports/report.js.map +1 -0
- package/dist/commands/dead-exports/resolve.d.ts +10 -0
- package/dist/commands/dead-exports/resolve.js +58 -0
- package/dist/commands/dead-exports/resolve.js.map +1 -0
- package/dist/commands/dead-exports/run.d.ts +21 -0
- package/dist/commands/dead-exports/run.js +51 -0
- package/dist/commands/dead-exports/run.js.map +1 -0
- package/dist/commands/dead-exports/workspace.d.ts +14 -0
- package/dist/commands/dead-exports/workspace.js +99 -0
- package/dist/commands/dead-exports/workspace.js.map +1 -0
- package/dist/commands/exports-doctor/core.d.ts +13 -0
- package/dist/commands/exports-doctor/core.js +85 -0
- package/dist/commands/exports-doctor/core.js.map +1 -0
- package/dist/commands/exports-doctor/parse.d.ts +20 -0
- package/dist/commands/exports-doctor/parse.js +80 -0
- package/dist/commands/exports-doctor/parse.js.map +1 -0
- package/dist/commands/exports-doctor/report.d.ts +3 -0
- package/dist/commands/exports-doctor/report.js +36 -0
- package/dist/commands/exports-doctor/report.js.map +1 -0
- package/dist/commands/exports-doctor/resolve-path.d.ts +10 -0
- package/dist/commands/exports-doctor/resolve-path.js +46 -0
- package/dist/commands/exports-doctor/resolve-path.js.map +1 -0
- package/dist/commands/exports-doctor/run.d.ts +13 -0
- package/dist/commands/exports-doctor/run.js +25 -0
- package/dist/commands/exports-doctor/run.js.map +1 -0
- package/dist/commands/readme-check/core.d.ts +22 -0
- package/dist/commands/readme-check/core.js +92 -0
- package/dist/commands/readme-check/core.js.map +1 -0
- package/dist/commands/readme-check/extract.d.ts +9 -0
- package/dist/commands/readme-check/extract.js +48 -0
- package/dist/commands/readme-check/extract.js.map +1 -0
- package/dist/commands/readme-check/lang.d.ts +8 -0
- package/dist/commands/readme-check/lang.js +21 -0
- package/dist/commands/readme-check/lang.js.map +1 -0
- package/dist/commands/readme-check/report.d.ts +3 -0
- package/dist/commands/readme-check/report.js +31 -0
- package/dist/commands/readme-check/report.js.map +1 -0
- package/dist/commands/readme-check/run.d.ts +19 -0
- package/dist/commands/readme-check/run.js +34 -0
- package/dist/commands/readme-check/run.js.map +1 -0
- package/dist/commands/readme-check/tsconfig.d.ts +9 -0
- package/dist/commands/readme-check/tsconfig.js +26 -0
- package/dist/commands/readme-check/tsconfig.js.map +1 -0
- package/dist/commands/readme-check/typecheck.d.ts +31 -0
- package/dist/commands/readme-check/typecheck.js +82 -0
- package/dist/commands/readme-check/typecheck.js.map +1 -0
- package/dist/commands/strip-comments/apply-deletions.d.ts +17 -0
- package/dist/commands/strip-comments/apply-deletions.js +74 -0
- package/dist/commands/strip-comments/apply-deletions.js.map +1 -0
- package/dist/commands/strip-comments/core.d.ts +15 -0
- package/dist/commands/strip-comments/core.js +111 -0
- package/dist/commands/strip-comments/core.js.map +1 -0
- package/dist/commands/strip-comments/report.d.ts +6 -0
- package/dist/commands/strip-comments/report.js +30 -0
- package/dist/commands/strip-comments/report.js.map +1 -0
- package/dist/commands/strip-comments/run.d.ts +28 -0
- package/dist/commands/strip-comments/run.js +50 -0
- package/dist/commands/strip-comments/run.js.map +1 -0
- package/dist/commands/strip-comments/vue.d.ts +6 -0
- package/dist/commands/strip-comments/vue.js +65 -0
- package/dist/commands/strip-comments/vue.js.map +1 -0
- package/dist/format/colors.d.ts +8 -0
- package/dist/format/colors.js +14 -0
- package/dist/format/colors.js.map +1 -0
- package/dist/format/diff-render.d.ts +2 -0
- package/dist/format/diff-render.js +35 -0
- package/dist/format/diff-render.js.map +1 -0
- package/dist/format/file-list.d.ts +14 -0
- package/dist/format/file-list.js +26 -0
- package/dist/format/file-list.js.map +1 -0
- package/dist/format/findings-list.d.ts +14 -0
- package/dist/format/findings-list.js +23 -0
- package/dist/format/findings-list.js.map +1 -0
- package/dist/format/vibes.d.ts +10 -0
- package/dist/format/vibes.js +67 -0
- package/dist/format/vibes.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/diff.d.ts +1 -0
- package/dist/utils/diff.js +13 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/walk.d.ts +19 -0
- package/dist/utils/walk.js +96 -0
- package/dist/utils/walk.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { findSpecifiers } from './parse.js';
|
|
2
|
+
const SCRIPT_RE = /<script[^>]*>/;
|
|
3
|
+
/**
|
|
4
|
+
* Same as `findSpecifiers`, but for a `.vue` file's `<script>` block —
|
|
5
|
+
* positions are offset by the block's real start in the full file, so a
|
|
6
|
+
* fix computed against them still lands correctly when applied to the
|
|
7
|
+
* whole file's text, not just the extracted body.
|
|
8
|
+
*/
|
|
9
|
+
export function findSpecifiersInVue(text, file) {
|
|
10
|
+
const openMatch = text.match(SCRIPT_RE);
|
|
11
|
+
if (!openMatch || openMatch.index === undefined)
|
|
12
|
+
return [];
|
|
13
|
+
const closeIndex = text.indexOf('</script>', openMatch.index);
|
|
14
|
+
if (closeIndex === -1)
|
|
15
|
+
return [];
|
|
16
|
+
const bodyStart = openMatch.index + openMatch[0].length;
|
|
17
|
+
const body = text.slice(bodyStart, closeIndex);
|
|
18
|
+
const lineOffset = (text.slice(0, bodyStart).match(/\n/g) ?? []).length;
|
|
19
|
+
return findSpecifiers(body, file).map((occ) => ({
|
|
20
|
+
...occ,
|
|
21
|
+
start: occ.start + bodyStart,
|
|
22
|
+
end: occ.end + bodyStart,
|
|
23
|
+
line: occ.line + lineOffset,
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../../../src/commands/case-check/vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA4B,MAAM,YAAY,CAAA;AAErE,MAAM,SAAS,GAAG,eAAe,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,IAAY;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACvC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAE1D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7D,IAAI,UAAU,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IAEhC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;IAEvE,OAAO,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9C,GAAG,GAAG;QACN,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,SAAS;QAC5B,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,SAAS;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,UAAU;KAC5B,CAAC,CAAC,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
export interface StripConsoleOptions {
|
|
3
|
+
scriptKind?: ts.ScriptKind;
|
|
4
|
+
/** console.<method> names to remove. default ['log', 'debug'] */
|
|
5
|
+
methods?: string[];
|
|
6
|
+
/** also remove bare `debugger;` statements. default true */
|
|
7
|
+
debugger?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type SkipReason = 'embedded-in-expression' | 'braceless-body';
|
|
10
|
+
export interface SkippedCall {
|
|
11
|
+
line: number;
|
|
12
|
+
column: number;
|
|
13
|
+
snippet: string;
|
|
14
|
+
reason: SkipReason;
|
|
15
|
+
}
|
|
16
|
+
export interface StripConsoleResult {
|
|
17
|
+
text: string;
|
|
18
|
+
changed: boolean;
|
|
19
|
+
/** how many console.* / debugger statements were actually removed */
|
|
20
|
+
count: number;
|
|
21
|
+
skipped: SkippedCall[];
|
|
22
|
+
}
|
|
23
|
+
export declare function stripConsole(text: string, options?: StripConsoleOptions): StripConsoleResult;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Finds console.*/debugger statements via a real AST walk (not text
|
|
2
|
+
// matching, so a string/template/regex containing the literal text
|
|
3
|
+
// "console.log(" is never touched — same non-negotiable requirement as
|
|
4
|
+
// strip-comments, just naturally satisfied here since we only ever act on
|
|
5
|
+
// real CallExpression/DebuggerStatement nodes, no masking trick needed).
|
|
6
|
+
//
|
|
7
|
+
// Only removes a console.*/debugger call when it's the WHOLE statement —
|
|
8
|
+
// see features.md's console-strip edge cases for why: `x || console.log(y)`
|
|
9
|
+
// or `if (x) console.log(y)` (braceless body) can't be deleted without
|
|
10
|
+
// either breaking the expression's value or leaving `if (x) ;` behind.
|
|
11
|
+
// Both are left in place and reported separately instead of guessed at.
|
|
12
|
+
//
|
|
13
|
+
// Scope note: only matches a bare `console.<method>(...)` call (callee is
|
|
14
|
+
// exactly the identifier `console`) — `window.console.log(...)` or a
|
|
15
|
+
// locally-shadowed `console` variable aren't recognized. Rare enough in
|
|
16
|
+
// practice not to be worth the extra complexity for this command.
|
|
17
|
+
import ts from 'typescript';
|
|
18
|
+
import { applyDeletions, collapseBlankLineRuns, } from '../strip-comments/apply-deletions.js';
|
|
19
|
+
function isConsoleCall(node, methods) {
|
|
20
|
+
if (!ts.isCallExpression(node))
|
|
21
|
+
return false;
|
|
22
|
+
const callee = node.expression;
|
|
23
|
+
if (!ts.isPropertyAccessExpression(callee))
|
|
24
|
+
return false;
|
|
25
|
+
if (!ts.isIdentifier(callee.expression) || callee.expression.text !== 'console')
|
|
26
|
+
return false;
|
|
27
|
+
return methods.has(callee.name.text);
|
|
28
|
+
}
|
|
29
|
+
// A single-statement (braceless) if/while/do/for body — deleting the
|
|
30
|
+
// statement text would leave `if (x) ;` or similar behind, so these are
|
|
31
|
+
// reported instead of touched.
|
|
32
|
+
function isBracelessSingleStatementBody(node) {
|
|
33
|
+
const parent = node.parent;
|
|
34
|
+
if (!parent)
|
|
35
|
+
return false;
|
|
36
|
+
if (ts.isIfStatement(parent)) {
|
|
37
|
+
return ((parent.thenStatement === node && !ts.isBlock(node)) ||
|
|
38
|
+
(parent.elseStatement === node && !ts.isBlock(node)));
|
|
39
|
+
}
|
|
40
|
+
if (ts.isWhileStatement(parent) ||
|
|
41
|
+
ts.isDoStatement(parent) ||
|
|
42
|
+
ts.isForStatement(parent) ||
|
|
43
|
+
ts.isForInStatement(parent) ||
|
|
44
|
+
ts.isForOfStatement(parent)) {
|
|
45
|
+
return parent.statement === node && !ts.isBlock(node);
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
function snippetFor(sf, node) {
|
|
50
|
+
const full = node.getText(sf).replace(/\s+/g, ' ').trim();
|
|
51
|
+
return full.length > 60 ? `${full.slice(0, 57)}...` : full;
|
|
52
|
+
}
|
|
53
|
+
export function stripConsole(text, options = {}) {
|
|
54
|
+
const scriptKind = options.scriptKind ?? ts.ScriptKind.TS;
|
|
55
|
+
const methods = new Set(options.methods ?? ['log', 'debug']);
|
|
56
|
+
const includeDebugger = options.debugger ?? true;
|
|
57
|
+
const sf = ts.createSourceFile('f.ts', text, ts.ScriptTarget.Latest, true, scriptKind);
|
|
58
|
+
const ranges = [];
|
|
59
|
+
const skipped = [];
|
|
60
|
+
function reportSkip(node, reason) {
|
|
61
|
+
const pos = sf.getLineAndCharacterOfPosition(node.getStart(sf));
|
|
62
|
+
skipped.push({
|
|
63
|
+
line: pos.line + 1,
|
|
64
|
+
column: pos.character + 1,
|
|
65
|
+
snippet: snippetFor(sf, node),
|
|
66
|
+
reason,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function visit(node) {
|
|
70
|
+
if (includeDebugger && ts.isDebuggerStatement(node)) {
|
|
71
|
+
if (isBracelessSingleStatementBody(node)) {
|
|
72
|
+
reportSkip(node, 'braceless-body');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
ranges.push([node.getStart(sf), node.getEnd()]);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (isConsoleCall(node, methods)) {
|
|
80
|
+
const parent = node.parent;
|
|
81
|
+
const isWholeStatement = parent !== undefined && ts.isExpressionStatement(parent) && parent.expression === node;
|
|
82
|
+
if (!isWholeStatement) {
|
|
83
|
+
reportSkip(node, 'embedded-in-expression');
|
|
84
|
+
}
|
|
85
|
+
else if (isBracelessSingleStatementBody(parent)) {
|
|
86
|
+
reportSkip(parent, 'braceless-body');
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
ranges.push([parent.getStart(sf), parent.getEnd()]);
|
|
90
|
+
}
|
|
91
|
+
// Don't descend into a console call's own arguments — a
|
|
92
|
+
// console.log(console.log(x)) nested case is vanishingly unlikely
|
|
93
|
+
// and descending would double-report/double-delete.
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
ts.forEachChild(node, visit);
|
|
97
|
+
}
|
|
98
|
+
visit(sf);
|
|
99
|
+
if (ranges.length === 0)
|
|
100
|
+
return { text, changed: false, count: 0, skipped };
|
|
101
|
+
const out = collapseBlankLineRuns(applyDeletions(text, ranges));
|
|
102
|
+
return { text: out, changed: true, count: ranges.length, skipped };
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/commands/console-strip/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { banner, cleanCelebration } from '../../format/vibes.js';
|
|
2
|
+
import { formatFileCountRows } from '../../format/file-list.js';
|
|
3
|
+
import { renderDiffForHumans } from '../../format/diff-render.js';
|
|
4
|
+
const REASON_LABEL = {
|
|
5
|
+
'embedded-in-expression': 'part of a larger expression, not its own statement',
|
|
6
|
+
'braceless-body': 'inside a single-statement body without braces',
|
|
7
|
+
};
|
|
8
|
+
export function renderConsoleStripReport(report, options = {}) {
|
|
9
|
+
const isClean = report.changes.length === 0 && report.skipped.length === 0;
|
|
10
|
+
if (options.quiet && isClean)
|
|
11
|
+
return '';
|
|
12
|
+
const lines = [];
|
|
13
|
+
if (!options.quiet && !options.plain)
|
|
14
|
+
lines.push(banner(), '');
|
|
15
|
+
lines.push(`Scanned ${report.filesScanned} file${report.filesScanned === 1 ? '' : 's'}.`, '');
|
|
16
|
+
if (isClean) {
|
|
17
|
+
lines.push(cleanCelebration(options));
|
|
18
|
+
return lines.join('\n');
|
|
19
|
+
}
|
|
20
|
+
if (report.changes.length > 0) {
|
|
21
|
+
const verb = report.applied
|
|
22
|
+
? 'Stripped console/debugger statements in'
|
|
23
|
+
: 'Would strip console/debugger statements in';
|
|
24
|
+
lines.push(`${verb} ${report.changes.length} file(s):`);
|
|
25
|
+
lines.push(...formatFileCountRows(report.changes, (n) => `statement${n === 1 ? '' : 's'}`, options));
|
|
26
|
+
if (!report.applied) {
|
|
27
|
+
const diffHint = report.changes.some((c) => c.diff) ? '' : ', or --diff to see exactly what';
|
|
28
|
+
lines.push('', `(nothing written — pass -y to apply${diffHint}, or --dry-run to keep previewing)`);
|
|
29
|
+
}
|
|
30
|
+
for (const change of report.changes) {
|
|
31
|
+
if (!change.diff)
|
|
32
|
+
continue;
|
|
33
|
+
const unit = `statement${change.count === 1 ? '' : 's'}`;
|
|
34
|
+
lines.push('', renderDiffForHumans(change.file, change.count, unit, change.diff, options));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (report.skipped.length > 0) {
|
|
38
|
+
if (report.changes.length > 0)
|
|
39
|
+
lines.push('');
|
|
40
|
+
lines.push(`${report.skipped.length} left in place, needs a manual look:`);
|
|
41
|
+
for (const s of report.skipped) {
|
|
42
|
+
lines.push(` - ${s.file}:${s.line}:${s.column} — ${REASON_LABEL[s.reason] ?? s.reason} — ${s.snippet}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return lines.join('\n');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/commands/console-strip/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SkippedCall } from './core.js';
|
|
2
|
+
export interface ConsoleStripRunOptions {
|
|
3
|
+
paths: string[];
|
|
4
|
+
cwd: string;
|
|
5
|
+
extensions?: string[];
|
|
6
|
+
ignoreGlobs?: string[];
|
|
7
|
+
respectGitignore?: boolean;
|
|
8
|
+
methods?: string[];
|
|
9
|
+
debugger?: boolean;
|
|
10
|
+
dryRun?: boolean;
|
|
11
|
+
yes?: boolean;
|
|
12
|
+
diff?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface ConsoleStripFileChange {
|
|
15
|
+
file: string;
|
|
16
|
+
/** how many console.* / debugger statements were removed from this file */
|
|
17
|
+
count: number;
|
|
18
|
+
diff?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ConsoleStripSkipped extends SkippedCall {
|
|
21
|
+
file: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ConsoleStripReport {
|
|
24
|
+
filesScanned: number;
|
|
25
|
+
changes: ConsoleStripFileChange[];
|
|
26
|
+
skipped: ConsoleStripSkipped[];
|
|
27
|
+
applied: boolean;
|
|
28
|
+
exitCode: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function runConsoleStrip(options: ConsoleStripRunOptions): ConsoleStripReport;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { relative } from 'node:path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import { walk } from '../../utils/walk.js';
|
|
5
|
+
import { unifiedDiff } from '../../utils/diff.js';
|
|
6
|
+
import { stripConsole } from './core.js';
|
|
7
|
+
import { stripConsoleVue } from './vue.js';
|
|
8
|
+
const DEFAULT_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.cjs', '.mjs', '.vue'];
|
|
9
|
+
function scriptKindFor(file) {
|
|
10
|
+
return file.endsWith('.ts') || file.endsWith('.tsx') ? ts.ScriptKind.TS : ts.ScriptKind.JS;
|
|
11
|
+
}
|
|
12
|
+
export function runConsoleStrip(options) {
|
|
13
|
+
const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
|
|
14
|
+
const files = walk(options.paths, {
|
|
15
|
+
cwd: options.cwd,
|
|
16
|
+
extensions,
|
|
17
|
+
...(options.ignoreGlobs ? { ignoreGlobs: options.ignoreGlobs } : {}),
|
|
18
|
+
...(options.respectGitignore !== undefined
|
|
19
|
+
? { respectGitignore: options.respectGitignore }
|
|
20
|
+
: {}),
|
|
21
|
+
});
|
|
22
|
+
const willApply = options.yes === true && options.dryRun !== true;
|
|
23
|
+
const changes = [];
|
|
24
|
+
const skipped = [];
|
|
25
|
+
const coreOptions = {
|
|
26
|
+
...(options.methods !== undefined ? { methods: options.methods } : {}),
|
|
27
|
+
...(options.debugger !== undefined ? { debugger: options.debugger } : {}),
|
|
28
|
+
};
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const before = readFileSync(file, 'utf8');
|
|
31
|
+
const result = file.endsWith('.vue')
|
|
32
|
+
? stripConsoleVue(before, coreOptions)
|
|
33
|
+
: stripConsole(before, { ...coreOptions, scriptKind: scriptKindFor(file) });
|
|
34
|
+
const relFile = relative(options.cwd, file).split('\\').join('/');
|
|
35
|
+
for (const s of result.skipped)
|
|
36
|
+
skipped.push({ ...s, file: relFile });
|
|
37
|
+
if (!result.changed)
|
|
38
|
+
continue;
|
|
39
|
+
const change = { file: relFile, count: result.count };
|
|
40
|
+
if (options.diff)
|
|
41
|
+
change.diff = unifiedDiff(relFile, before, result.text);
|
|
42
|
+
changes.push(change);
|
|
43
|
+
if (willApply)
|
|
44
|
+
writeFileSync(file, result.text);
|
|
45
|
+
}
|
|
46
|
+
const exitCode = (!willApply && changes.length > 0) || skipped.length > 0 ? 1 : 0;
|
|
47
|
+
return {
|
|
48
|
+
filesScanned: files.length,
|
|
49
|
+
changes,
|
|
50
|
+
skipped,
|
|
51
|
+
applied: willApply,
|
|
52
|
+
exitCode,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/console-strip/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SkippedCall, type StripConsoleOptions } from './core.js';
|
|
2
|
+
export interface StripConsoleVueResult {
|
|
3
|
+
text: string;
|
|
4
|
+
changed: boolean;
|
|
5
|
+
count: number;
|
|
6
|
+
skipped: SkippedCall[];
|
|
7
|
+
}
|
|
8
|
+
export declare function stripConsoleVue(text: string, options?: StripConsoleOptions): StripConsoleVueResult;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { stripConsole } from './core.js';
|
|
3
|
+
const SCRIPT_RE = /(<script[^>]*>)([\s\S]*?)(<\/script>)/;
|
|
4
|
+
export function stripConsoleVue(text, options = {}) {
|
|
5
|
+
const scriptMatch = text.match(SCRIPT_RE);
|
|
6
|
+
if (!scriptMatch)
|
|
7
|
+
return { text, changed: false, count: 0, skipped: [] };
|
|
8
|
+
const [whole, open, body, close] = scriptMatch;
|
|
9
|
+
const result = stripConsole(body, { ...options, scriptKind: ts.ScriptKind.TS });
|
|
10
|
+
if (!result.changed && result.skipped.length === 0) {
|
|
11
|
+
return { text, changed: false, count: 0, skipped: [] };
|
|
12
|
+
}
|
|
13
|
+
// Skipped-entry line numbers are relative to the <script> body alone
|
|
14
|
+
// (that's all core.ts ever sees) — offset by however many lines come
|
|
15
|
+
// before it in the real file, so a report against the whole .vue file
|
|
16
|
+
// points at the right line.
|
|
17
|
+
const lineOffset = (text.slice(0, scriptMatch.index).match(/\n/g) ?? []).length;
|
|
18
|
+
const skipped = result.skipped.map((s) => ({ ...s, line: s.line + lineOffset }));
|
|
19
|
+
if (!result.changed)
|
|
20
|
+
return { text, changed: false, count: 0, skipped };
|
|
21
|
+
const newText = text.slice(0, scriptMatch.index) +
|
|
22
|
+
open +
|
|
23
|
+
result.text +
|
|
24
|
+
close +
|
|
25
|
+
text.slice(scriptMatch.index + whole.length);
|
|
26
|
+
return { text: newText, changed: true, count: result.count, skipped };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../../../src/commands/console-strip/vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,EAAE,YAAY,EAA8C,MAAM,WAAW,CAAA;AAEpF,MAAM,SAAS,GAAG,uCAAuC,CAAA;AASzD,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,UAA+B,EAAE;IAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACzC,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IAExE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,WAA+C,CAAA;IAClF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;IAC/E,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IACxD,CAAC;IAED,qEAAqE;IACrE,qEAAqE;IACrE,sEAAsE;IACtE,4BAA4B;IAC5B,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;IAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;IAEhF,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAA;IAEvE,MAAM,OAAO,GACX,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI;QACJ,MAAM,CAAC,IAAI;QACX,KAAK;QACL,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,CAAA;AACvE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WorkspaceInfo } from './workspace.js';
|
|
2
|
+
export interface DeadExportFinding {
|
|
3
|
+
name: string;
|
|
4
|
+
file: string;
|
|
5
|
+
line: number;
|
|
6
|
+
isType: boolean;
|
|
7
|
+
isDefault: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface DeadExportsAnalysis {
|
|
10
|
+
findings: DeadExportFinding[];
|
|
11
|
+
filesAnalyzed: number;
|
|
12
|
+
hasUnresolvableDynamicImports: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface AnalyzeOptions {
|
|
15
|
+
publicEntries: Set<string>;
|
|
16
|
+
strict: boolean;
|
|
17
|
+
workspace: WorkspaceInfo | null;
|
|
18
|
+
}
|
|
19
|
+
export declare function analyzeDeadExports(files: string[], options: AnalyzeOptions): DeadExportsAnalysis;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { analyzeFile } from './parse.js';
|
|
3
|
+
import { resolveRelativeSpecifier } from './resolve.js';
|
|
4
|
+
import { resolvePublicEntries } from './entry.js';
|
|
5
|
+
function specifierKey(file, name) {
|
|
6
|
+
return `${file}::${name}`;
|
|
7
|
+
}
|
|
8
|
+
export function analyzeDeadExports(files, options) {
|
|
9
|
+
const analyses = new Map();
|
|
10
|
+
let hasUnresolvableDynamicImports = false;
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
const text = readFileSync(file, 'utf8');
|
|
13
|
+
const analysis = analyzeFile(text, file);
|
|
14
|
+
analyses.set(file, analysis);
|
|
15
|
+
if (analysis.hasUnresolvableDynamicImport)
|
|
16
|
+
hasUnresolvableDynamicImports = true;
|
|
17
|
+
}
|
|
18
|
+
const workspaceEntryCache = new Map();
|
|
19
|
+
function resolveWorkspaceBareSpecifier(specifier) {
|
|
20
|
+
if (!options.workspace)
|
|
21
|
+
return null;
|
|
22
|
+
if (workspaceEntryCache.has(specifier))
|
|
23
|
+
return workspaceEntryCache.get(specifier);
|
|
24
|
+
const pkg = options.workspace.packages.find((p) => p.name === specifier || specifier.startsWith(`${p.name}/`));
|
|
25
|
+
let result = null;
|
|
26
|
+
if (pkg && specifier === pkg.name) {
|
|
27
|
+
const entries = resolvePublicEntries(pkg.rootDir);
|
|
28
|
+
result = entries[0] ?? null;
|
|
29
|
+
}
|
|
30
|
+
// A subpath import (`@scope/pkg/sub`) isn't resolved — out of scope
|
|
31
|
+
// for this command; left unresolved rather than guessed at.
|
|
32
|
+
workspaceEntryCache.set(specifier, result);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function resolveSpecifier(fromFile, specifier) {
|
|
36
|
+
if (specifier.startsWith('.'))
|
|
37
|
+
return resolveRelativeSpecifier(fromFile, specifier);
|
|
38
|
+
return resolveWorkspaceBareSpecifier(specifier);
|
|
39
|
+
}
|
|
40
|
+
function resolveExportOrigin(file, name, visited = new Set()) {
|
|
41
|
+
if (visited.has(file))
|
|
42
|
+
return null;
|
|
43
|
+
visited.add(file);
|
|
44
|
+
const analysis = analyses.get(file);
|
|
45
|
+
if (!analysis)
|
|
46
|
+
return null;
|
|
47
|
+
if (analysis.exports.some((e) => e.name === name))
|
|
48
|
+
return { file, name };
|
|
49
|
+
for (const r of analysis.reexports) {
|
|
50
|
+
if (r.imported === '*' || r.exportedAs !== name)
|
|
51
|
+
continue;
|
|
52
|
+
const nextFile = resolveSpecifier(file, r.from);
|
|
53
|
+
if (!nextFile)
|
|
54
|
+
return null; // reexported from something we can't see into (external package) — don't guess
|
|
55
|
+
return (resolveExportOrigin(nextFile, r.imported, visited) ?? { file: nextFile, name: r.imported });
|
|
56
|
+
}
|
|
57
|
+
for (const r of analysis.reexports) {
|
|
58
|
+
if (r.imported !== '*')
|
|
59
|
+
continue;
|
|
60
|
+
const nextFile = resolveSpecifier(file, r.from);
|
|
61
|
+
if (!nextFile)
|
|
62
|
+
continue;
|
|
63
|
+
const found = resolveExportOrigin(nextFile, name, visited);
|
|
64
|
+
if (found)
|
|
65
|
+
return found;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
// Reused for two different purposes below: marking everything a
|
|
70
|
+
// namespace/dynamic import can reach as USED, and (separately) marking
|
|
71
|
+
// everything reachable from a public entry point's own export surface
|
|
72
|
+
// as PUBLIC — an `index.ts` that's nothing but `export { x } from
|
|
73
|
+
// './x.js'` re-exports is the normal shape for a library barrel, and
|
|
74
|
+
// the symbols it re-exports are just as public as ones declared
|
|
75
|
+
// directly in the entry file itself, even though this walk is what
|
|
76
|
+
// discovers that, not the file's own literal declaration list.
|
|
77
|
+
function markAllReachable(file, target, visited = new Set()) {
|
|
78
|
+
if (visited.has(file))
|
|
79
|
+
return;
|
|
80
|
+
visited.add(file);
|
|
81
|
+
const analysis = analyses.get(file);
|
|
82
|
+
if (!analysis)
|
|
83
|
+
return;
|
|
84
|
+
for (const e of analysis.exports)
|
|
85
|
+
target.add(specifierKey(file, e.name));
|
|
86
|
+
for (const r of analysis.reexports) {
|
|
87
|
+
const nextFile = resolveSpecifier(file, r.from);
|
|
88
|
+
if (!nextFile)
|
|
89
|
+
continue;
|
|
90
|
+
if (r.imported === '*') {
|
|
91
|
+
// `export * from './y'` genuinely re-exports everything in './y'.
|
|
92
|
+
markAllReachable(nextFile, target, visited);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// `export { x } from './y'` re-exports ONLY x — walking into './y'
|
|
96
|
+
// and marking its entire export list reachable (the old behavior)
|
|
97
|
+
// wrongly exempted every OTHER unrelated export in that file too,
|
|
98
|
+
// hiding genuinely dead ones behind an unrelated barrel re-export.
|
|
99
|
+
const origin = resolveExportOrigin(nextFile, r.imported);
|
|
100
|
+
target.add(origin ? specifierKey(origin.file, origin.name) : specifierKey(nextFile, r.imported));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const usedSymbols = new Set();
|
|
105
|
+
for (const [file, analysis] of analyses) {
|
|
106
|
+
for (const imp of analysis.imports) {
|
|
107
|
+
const target = resolveSpecifier(file, imp.from);
|
|
108
|
+
if (!target)
|
|
109
|
+
continue;
|
|
110
|
+
if (imp.imported === '*') {
|
|
111
|
+
markAllReachable(target, usedSymbols);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const origin = resolveExportOrigin(target, imp.imported);
|
|
115
|
+
usedSymbols.add(origin ? specifierKey(origin.file, origin.name) : specifierKey(target, imp.imported));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const publiclyReachable = new Set();
|
|
119
|
+
if (!options.strict) {
|
|
120
|
+
for (const entry of options.publicEntries)
|
|
121
|
+
markAllReachable(entry, publiclyReachable);
|
|
122
|
+
}
|
|
123
|
+
const findings = [];
|
|
124
|
+
for (const [file, analysis] of analyses) {
|
|
125
|
+
for (const e of analysis.exports) {
|
|
126
|
+
const key = specifierKey(file, e.name);
|
|
127
|
+
if (usedSymbols.has(key))
|
|
128
|
+
continue;
|
|
129
|
+
if (publiclyReachable.has(key))
|
|
130
|
+
continue;
|
|
131
|
+
findings.push({ name: e.name, file, line: e.line, isType: e.isType, isDefault: e.isDefault });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { findings, filesAnalyzed: files.length, hasUnresolvableDynamicImports };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Determines which files count as a package's PUBLIC API — exports from
|
|
2
|
+
// these are exempt from the dead-export check by default (see
|
|
3
|
+
// features.md: "не используется внутри репо" ≠ "мёртвый код" for a
|
|
4
|
+
// published library's own entry points).
|
|
5
|
+
//
|
|
6
|
+
// package.json's main/module/exports/bin/types point at BUILT output
|
|
7
|
+
// (dist/index.js), not the source this command actually analyzes — there
|
|
8
|
+
// is no guaranteed link back to the source file. The heuristic here (swap
|
|
9
|
+
// the first build-output-looking directory segment for `src`, swap the
|
|
10
|
+
// extension for a TS one, keep only what actually exists on disk) covers
|
|
11
|
+
// the common tsc/tsup/vite-library-mode layout this project's own
|
|
12
|
+
// packages use. `--entry` exists specifically to override this when it
|
|
13
|
+
// guesses wrong.
|
|
14
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
15
|
+
import { dirname, join, resolve } from 'node:path';
|
|
16
|
+
const BUILD_DIR_NAMES = new Set(['dist', 'build', 'lib', 'out']);
|
|
17
|
+
const SOURCE_EXTENSIONS = ['.ts', '.tsx'];
|
|
18
|
+
function readPackageJson(dir) {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function collectExportsMapValues(node, out) {
|
|
27
|
+
if (typeof node === 'string') {
|
|
28
|
+
out.push(node);
|
|
29
|
+
}
|
|
30
|
+
else if (node && typeof node === 'object') {
|
|
31
|
+
for (const value of Object.values(node))
|
|
32
|
+
collectExportsMapValues(value, out);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function guessSourcePath(packageDir, distRelativePath) {
|
|
36
|
+
const segments = distRelativePath.replace(/^\.\//, '').split(/[\\/]/);
|
|
37
|
+
const buildIndex = segments.findIndex((s) => BUILD_DIR_NAMES.has(s));
|
|
38
|
+
if (buildIndex === -1)
|
|
39
|
+
return null;
|
|
40
|
+
const srcSegments = [...segments.slice(0, buildIndex), 'src', ...segments.slice(buildIndex + 1)];
|
|
41
|
+
const withoutExt = srcSegments.join('/').replace(/\.(js|cjs|mjs|d\.ts)$/, '');
|
|
42
|
+
for (const ext of SOURCE_EXTENSIONS) {
|
|
43
|
+
const candidate = resolve(packageDir, withoutExt + ext);
|
|
44
|
+
if (existsSync(candidate))
|
|
45
|
+
return candidate;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
export function resolvePublicEntries(packageDir, extraEntries = []) {
|
|
50
|
+
const entries = new Set();
|
|
51
|
+
for (const ext of SOURCE_EXTENSIONS) {
|
|
52
|
+
const defaultEntry = resolve(packageDir, 'src', `index${ext}`);
|
|
53
|
+
if (existsSync(defaultEntry))
|
|
54
|
+
entries.add(defaultEntry);
|
|
55
|
+
}
|
|
56
|
+
const pkg = readPackageJson(packageDir);
|
|
57
|
+
if (pkg) {
|
|
58
|
+
const distCandidates = [];
|
|
59
|
+
for (const field of ['main', 'module', 'types', 'typings']) {
|
|
60
|
+
if (typeof pkg[field] === 'string')
|
|
61
|
+
distCandidates.push(pkg[field]);
|
|
62
|
+
}
|
|
63
|
+
if (pkg.exports)
|
|
64
|
+
collectExportsMapValues(pkg.exports, distCandidates);
|
|
65
|
+
if (pkg.bin)
|
|
66
|
+
collectExportsMapValues(pkg.bin, distCandidates);
|
|
67
|
+
for (const dist of distCandidates) {
|
|
68
|
+
const guessed = guessSourcePath(packageDir, dist);
|
|
69
|
+
if (guessed)
|
|
70
|
+
entries.add(guessed);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
for (const extra of extraEntries) {
|
|
74
|
+
const resolved = resolve(packageDir, extra);
|
|
75
|
+
if (existsSync(resolved))
|
|
76
|
+
entries.add(resolved);
|
|
77
|
+
}
|
|
78
|
+
return [...entries];
|
|
79
|
+
}
|
|
80
|
+
// Exposed only so entry.ts doesn't need a second "does this dir have a
|
|
81
|
+
// package.json" check duplicated in core.ts.
|
|
82
|
+
export function findNearestPackageDir(startDir) {
|
|
83
|
+
let dir = resolve(startDir);
|
|
84
|
+
for (;;) {
|
|
85
|
+
if (existsSync(join(dir, 'package.json')))
|
|
86
|
+
return dir;
|
|
87
|
+
const parent = dirname(dir);
|
|
88
|
+
if (parent === dir)
|
|
89
|
+
return null;
|
|
90
|
+
dir = parent;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/commands/dead-exports/entry.ts"],"names":[],"mappings":"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"}
|