knip 6.6.2 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConsoleStreamer.d.ts +4 -0
- package/dist/ConsoleStreamer.js +18 -0
- package/dist/IssueFixer.js +7 -2
- package/dist/WorkspaceWorker.js +23 -9
- package/dist/cli.js +6 -4
- package/dist/graph/analyze.js +8 -4
- package/dist/plugins/nuxt/types.d.ts +4 -3
- package/dist/plugins/raycast/types.d.ts +3 -2
- package/dist/plugins/vitest/helpers.js +2 -0
- package/dist/reporters/markdown.js +5 -3
- package/dist/reporters/trace.js +1 -1
- package/dist/reporters/util/configuration-hints.js +1 -1
- package/dist/reporters/util/util.js +1 -1
- package/dist/types/config.d.ts +3 -3
- package/dist/types/module-graph.d.ts +1 -1
- package/dist/typescript/visitors/walk.d.ts +1 -1
- package/dist/typescript/visitors/walk.js +10 -20
- package/dist/util/Performance.js +1 -1
- package/dist/util/create-options.js +2 -2
- package/dist/util/errors.d.ts +1 -0
- package/dist/util/errors.js +6 -0
- package/dist/util/fs.js +1 -1
- package/dist/util/log.d.ts +2 -2
- package/dist/util/log.js +4 -4
- package/dist/util/map-workspaces.js +8 -2
- package/dist/util/table.d.ts +7 -5
- package/dist/util/table.js +85 -49
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -3,9 +3,13 @@ export declare class ConsoleStreamer {
|
|
|
3
3
|
isEnabled: boolean;
|
|
4
4
|
isWatch: boolean;
|
|
5
5
|
private lines;
|
|
6
|
+
private stdoutBaseline;
|
|
7
|
+
private stderrBaseline;
|
|
6
8
|
constructor(options: MainOptions);
|
|
7
9
|
private clearLines;
|
|
8
10
|
private clearScreen;
|
|
11
|
+
private snapshot;
|
|
12
|
+
private hadExternalWrites;
|
|
9
13
|
private update;
|
|
10
14
|
cast(message: string | string[], sub?: string): void;
|
|
11
15
|
clear(): void;
|
package/dist/ConsoleStreamer.js
CHANGED
|
@@ -2,9 +2,12 @@ export class ConsoleStreamer {
|
|
|
2
2
|
isEnabled = false;
|
|
3
3
|
isWatch = false;
|
|
4
4
|
lines = 0;
|
|
5
|
+
stdoutBaseline = 0;
|
|
6
|
+
stderrBaseline = 0;
|
|
5
7
|
constructor(options) {
|
|
6
8
|
this.isEnabled = options.isShowProgress;
|
|
7
9
|
this.isWatch = options.isWatch;
|
|
10
|
+
this.snapshot();
|
|
8
11
|
}
|
|
9
12
|
clearLines(count) {
|
|
10
13
|
if (count > 0) {
|
|
@@ -18,6 +21,14 @@ export class ConsoleStreamer {
|
|
|
18
21
|
clearScreen() {
|
|
19
22
|
process.stdout.write('\x1b[2J\x1b[1;1f');
|
|
20
23
|
}
|
|
24
|
+
snapshot() {
|
|
25
|
+
this.stdoutBaseline = process.stdout.bytesWritten ?? 0;
|
|
26
|
+
this.stderrBaseline = process.stderr.bytesWritten ?? 0;
|
|
27
|
+
}
|
|
28
|
+
hadExternalWrites() {
|
|
29
|
+
return ((process.stdout.bytesWritten ?? 0) > this.stdoutBaseline ||
|
|
30
|
+
(process.stderr.bytesWritten ?? 0) > this.stderrBaseline);
|
|
31
|
+
}
|
|
21
32
|
update(messages) {
|
|
22
33
|
this.clear();
|
|
23
34
|
process.stdout.write(`${messages.join('\n')}\n`);
|
|
@@ -26,17 +37,24 @@ export class ConsoleStreamer {
|
|
|
26
37
|
cast(message, sub) {
|
|
27
38
|
if (!this.isEnabled)
|
|
28
39
|
return;
|
|
40
|
+
if (this.hadExternalWrites())
|
|
41
|
+
this.lines = 0;
|
|
29
42
|
if (Array.isArray(message))
|
|
30
43
|
this.update(message);
|
|
31
44
|
else
|
|
32
45
|
this.update([`${message}${!sub || sub === '.' ? '' : ` (${sub})`}…`]);
|
|
46
|
+
this.snapshot();
|
|
33
47
|
}
|
|
34
48
|
clear() {
|
|
35
49
|
if (!this.isEnabled)
|
|
36
50
|
return;
|
|
51
|
+
if (this.hadExternalWrites())
|
|
52
|
+
this.lines = 0;
|
|
37
53
|
if (this.isWatch)
|
|
38
54
|
this.clearScreen();
|
|
39
55
|
else
|
|
40
56
|
this.clearLines(this.lines);
|
|
57
|
+
this.lines = 0;
|
|
58
|
+
this.snapshot();
|
|
41
59
|
}
|
|
42
60
|
}
|
package/dist/IssueFixer.js
CHANGED
|
@@ -5,6 +5,7 @@ import { debugLogArray, debugLogObject } from './util/debug.js';
|
|
|
5
5
|
import { load, save } from './util/package-json.js';
|
|
6
6
|
import { extname, join } from './util/path.js';
|
|
7
7
|
import { removeExport } from './util/remove-export.js';
|
|
8
|
+
const MODULE_MARKER = /^[ \t]*(import|export)\b/m;
|
|
8
9
|
export const fix = async (issues, counters, options) => {
|
|
9
10
|
const fixer = new IssueFixer(options);
|
|
10
11
|
const touchedFiles = await fixer.fixIssues(issues);
|
|
@@ -73,9 +74,13 @@ class IssueFixer {
|
|
|
73
74
|
if (fixes.length === 0)
|
|
74
75
|
continue;
|
|
75
76
|
const absFilePath = join(this.options.cwd, filePath);
|
|
76
|
-
const
|
|
77
|
+
const originalSource = await readFile(absFilePath, 'utf-8');
|
|
78
|
+
let sourceFileText = fixes
|
|
77
79
|
.sort((a, b) => b[0] - a[0])
|
|
78
|
-
.reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }),
|
|
80
|
+
.reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }), originalSource);
|
|
81
|
+
if (MODULE_MARKER.test(originalSource) && !MODULE_MARKER.test(sourceFileText)) {
|
|
82
|
+
sourceFileText = `${sourceFileText.trimEnd()}\n\nexport {};\n`;
|
|
83
|
+
}
|
|
79
84
|
await writeFile(absFilePath, sourceFileText);
|
|
80
85
|
touchedFiles.add(absFilePath);
|
|
81
86
|
for (const type of types) {
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -15,8 +15,10 @@ import { isConfig, isDeferResolve, isDependency, toConfig, toDebugString, toEntr
|
|
|
15
15
|
import { getPackageNameFromSpecifier } from './util/modules.js';
|
|
16
16
|
import { getKeysByValue } from './util/object.js';
|
|
17
17
|
import { timerify } from './util/Performance.js';
|
|
18
|
-
import { basename, dirname, isInternal, join } from './util/path.js';
|
|
18
|
+
import { basename, dirname, isInternal, join, toRelative } from './util/path.js';
|
|
19
19
|
import { extractPatternExtensions } from './util/pattern-extensions.js';
|
|
20
|
+
import { formatCauseMessage } from './util/errors.js';
|
|
21
|
+
import { logError } from './util/log.js';
|
|
20
22
|
import { loadConfigForPlugin } from './util/plugin.js';
|
|
21
23
|
import { ELLIPSIS } from './util/string.js';
|
|
22
24
|
const nullConfig = { config: null, entry: null, project: null };
|
|
@@ -327,15 +329,27 @@ export class WorkspaceWorker {
|
|
|
327
329
|
}
|
|
328
330
|
if (!cache.resolveConfig) {
|
|
329
331
|
const isLoad = typeof plugin.isLoadConfig === 'function' ? plugin.isLoadConfig(resolveOpts, this.dependencies) : true;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
332
|
+
if (isLoad) {
|
|
333
|
+
try {
|
|
334
|
+
const localConfig = await loadConfigForPlugin(configFilePath, plugin, resolveOpts, pluginName);
|
|
335
|
+
if (localConfig) {
|
|
336
|
+
const inputs = await plugin.resolveConfig(localConfig, resolveOpts);
|
|
337
|
+
if (plugin.isFilterTransitiveDependencies && !isManifest) {
|
|
338
|
+
this.filterTransitiveDependencies(inputs, configFilePath);
|
|
339
|
+
}
|
|
340
|
+
for (const input of inputs)
|
|
341
|
+
addInput(input, configFilePath);
|
|
342
|
+
cache.resolveConfig = inputs;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
if (!(error instanceof Error))
|
|
347
|
+
throw error;
|
|
348
|
+
const relPath = toRelative(configFilePath, this.options.cwd);
|
|
349
|
+
const cause = formatCauseMessage(error, this.options.cwd);
|
|
350
|
+
logError(`Error loading ${relPath} (${cause})`);
|
|
351
|
+
logError('Please fix or visit https://knip.dev/reference/known-issues');
|
|
335
352
|
}
|
|
336
|
-
for (const input of inputs)
|
|
337
|
-
addInput(input, configFilePath);
|
|
338
|
-
cache.resolveConfig = inputs;
|
|
339
353
|
}
|
|
340
354
|
}
|
|
341
355
|
}
|
package/dist/cli.js
CHANGED
|
@@ -74,7 +74,8 @@ const main = async () => {
|
|
|
74
74
|
}
|
|
75
75
|
if ((!args['no-exit-code'] && totalErrorCount > Number(args['max-issues'] ?? 0)) ||
|
|
76
76
|
(!options.isDisableConfigHints && options.isTreatConfigHintsAsErrors && configurationHints.length > 0)) {
|
|
77
|
-
process.
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
catch (error) {
|
|
@@ -82,7 +83,7 @@ const main = async () => {
|
|
|
82
83
|
if (!args.debug && error instanceof Error && isKnownError(error)) {
|
|
83
84
|
const knownErrors = getKnownErrors(error);
|
|
84
85
|
for (const knownError of knownErrors)
|
|
85
|
-
logError(
|
|
86
|
+
logError(knownError.message);
|
|
86
87
|
if (hasErrorCause(knownErrors[0])) {
|
|
87
88
|
console.error('Reason:', knownErrors[0].cause.message);
|
|
88
89
|
if (isModuleNotFoundError(knownErrors[0].cause))
|
|
@@ -92,10 +93,11 @@ const main = async () => {
|
|
|
92
93
|
}
|
|
93
94
|
if (isConfigurationError(knownErrors[0]))
|
|
94
95
|
console.log('\nRun `knip --help` or visit https://knip.dev for help');
|
|
95
|
-
process.
|
|
96
|
+
process.exitCode = 2;
|
|
97
|
+
return;
|
|
96
98
|
}
|
|
97
99
|
throw error;
|
|
98
100
|
}
|
|
99
|
-
process.
|
|
101
|
+
process.exitCode = 0;
|
|
100
102
|
};
|
|
101
103
|
await main();
|
package/dist/graph/analyze.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createGraphExplorer } from '../graph-explorer/explorer.js';
|
|
2
2
|
import { getIssueType, hasStrictlyEnumReferences } from '../graph-explorer/utils.js';
|
|
3
3
|
import traceReporter from '../reporters/trace.js';
|
|
4
|
+
import { shouldCountRefs } from '../typescript/visitors/helpers.js';
|
|
4
5
|
import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
|
|
5
6
|
import { perfObserver } from '../util/Performance.js';
|
|
6
7
|
import { findMatch } from '../util/regex.js';
|
|
@@ -9,6 +10,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
9
10
|
const shouldIgnore = getShouldIgnoreHandler(options.isProduction);
|
|
10
11
|
const shouldIgnoreTags = getShouldIgnoreTagHandler(options.tags);
|
|
11
12
|
const explorer = createGraphExplorer(graph, entryPaths);
|
|
13
|
+
const ignoreExportsUsedInFile = chief.config.ignoreExportsUsedInFile;
|
|
12
14
|
const isReferencedInUsedExport = (exportedItem, filePath, includeEntryExports, visited) => {
|
|
13
15
|
if (!exportedItem.referencedIn)
|
|
14
16
|
return false;
|
|
@@ -16,13 +18,15 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
16
18
|
if (!file)
|
|
17
19
|
return false;
|
|
18
20
|
for (const containingExport of exportedItem.referencedIn) {
|
|
19
|
-
if (explorer.isReferenced(filePath, containingExport, { includeEntryExports })[0])
|
|
20
|
-
return true;
|
|
21
21
|
const inExport = file.exports.get(containingExport);
|
|
22
22
|
if (!inExport)
|
|
23
23
|
continue;
|
|
24
|
-
if (
|
|
25
|
-
|
|
24
|
+
if (shouldCountRefs(ignoreExportsUsedInFile, inExport.type)) {
|
|
25
|
+
if (inExport.hasRefsInFile)
|
|
26
|
+
return true;
|
|
27
|
+
if (explorer.isReferenced(filePath, containingExport, { includeEntryExports })[0])
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
26
30
|
if (inExport.referencedIn) {
|
|
27
31
|
const v = visited ?? new Set();
|
|
28
32
|
if (!v.has(containingExport)) {
|
|
@@ -25,11 +25,11 @@ export interface NuxtConfig {
|
|
|
25
25
|
css?: string[];
|
|
26
26
|
alias?: Record<string, string>;
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
interface TemplateExpressionNode {
|
|
29
29
|
content: string;
|
|
30
30
|
isStatic: boolean;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
interface TemplateAstProp {
|
|
33
33
|
type: number;
|
|
34
34
|
exp?: TemplateExpressionNode;
|
|
35
35
|
arg?: TemplateExpressionNode;
|
|
@@ -41,7 +41,7 @@ export interface TemplateAstNode {
|
|
|
41
41
|
content?: TemplateExpressionNode;
|
|
42
42
|
children?: TemplateAstNode[];
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
interface Descriptor {
|
|
45
45
|
script: {
|
|
46
46
|
content: string;
|
|
47
47
|
} | null;
|
|
@@ -58,3 +58,4 @@ export type VueSfc = {
|
|
|
58
58
|
descriptor: Descriptor;
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
|
+
export {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
type RaycastManifestCommand = {
|
|
2
2
|
name?: unknown;
|
|
3
3
|
};
|
|
4
|
-
|
|
4
|
+
type RaycastManifestTool = {
|
|
5
5
|
name?: unknown;
|
|
6
6
|
};
|
|
7
7
|
export type RaycastManifest = {
|
|
8
8
|
commands?: RaycastManifestCommand[];
|
|
9
9
|
tools?: RaycastManifestTool[];
|
|
10
10
|
};
|
|
11
|
+
export {};
|
|
@@ -17,6 +17,7 @@ export const getEnvSpecifier = (env) => {
|
|
|
17
17
|
return `vitest-environment-${env}`;
|
|
18
18
|
};
|
|
19
19
|
const builtInReporters = [
|
|
20
|
+
'agent',
|
|
20
21
|
'basic',
|
|
21
22
|
'blob',
|
|
22
23
|
'default',
|
|
@@ -26,6 +27,7 @@ const builtInReporters = [
|
|
|
26
27
|
'html',
|
|
27
28
|
'json',
|
|
28
29
|
'junit',
|
|
30
|
+
'minimal',
|
|
29
31
|
'tap',
|
|
30
32
|
'tap-flat',
|
|
31
33
|
'tree',
|
|
@@ -18,10 +18,12 @@ export default ({ report, issues, cwd }) => {
|
|
|
18
18
|
const longestSymbol = issuesForType.sort(sortLongestSymbol)[0].symbol.length;
|
|
19
19
|
const sortedByFilePath = issuesForType.sort(sortLongestFilePath);
|
|
20
20
|
const longestFilePath = getFilePath(sortedByFilePath[0]).length;
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const nameWidth = Math.max(longestSymbol, 'Name'.length);
|
|
22
|
+
const locationWidth = Math.max(longestFilePath, 'Location'.length);
|
|
23
|
+
console.log(`| ${'Name'.padEnd(nameWidth)} | ${'Location'.padEnd(locationWidth)} | Severity |`);
|
|
24
|
+
console.log(`| :${'-'.repeat(nameWidth - 1)} | :${'-'.repeat(locationWidth - 1)} | :------- |`);
|
|
23
25
|
for (const issue of sortedByFilePath) {
|
|
24
|
-
console.log(`| ${issue.symbol.padEnd(
|
|
26
|
+
console.log(`| ${issue.symbol.padEnd(nameWidth)} | ${getFilePath(issue).padEnd(locationWidth)} | ${(issue.severity ?? '').padEnd(8)} |`);
|
|
25
27
|
}
|
|
26
28
|
console.log('');
|
|
27
29
|
}
|
package/dist/reporters/trace.js
CHANGED
|
@@ -7,7 +7,7 @@ export default ({ graph, explorer, options, workspaceFilePathFilter }) => {
|
|
|
7
7
|
if (options.traceDependency) {
|
|
8
8
|
const pattern = toRegexOrString(options.traceDependency);
|
|
9
9
|
const toRel = (path) => toRelative(path, options.cwd);
|
|
10
|
-
const table = new Table({
|
|
10
|
+
const table = new Table({ truncate: { filePath: 'start' } });
|
|
11
11
|
const seen = new Set();
|
|
12
12
|
for (const [packageName, { imports }] of explorer.getDependencyUsage(pattern)) {
|
|
13
13
|
const filtered = imports.filter(i => workspaceFilePathFilter(i.filePath));
|
|
@@ -17,7 +17,7 @@ const getIdentifier = (hint) => {
|
|
|
17
17
|
return hint.identifier.toString();
|
|
18
18
|
};
|
|
19
19
|
const getTableForHints = (hints) => {
|
|
20
|
-
const table = new Table({
|
|
20
|
+
const table = new Table({ truncate: { identifier: 'start', workspace: 'start', filePath: 'start' } });
|
|
21
21
|
for (const hint of hints) {
|
|
22
22
|
table.row();
|
|
23
23
|
table.cell('identifier', getIdentifier(hint));
|
|
@@ -41,7 +41,7 @@ const highlightSymbol = (issue) => (_) => {
|
|
|
41
41
|
return symbol;
|
|
42
42
|
};
|
|
43
43
|
export const getTableForType = (issues, cwd, options = { isUseColors: true }) => {
|
|
44
|
-
const table = new Table({
|
|
44
|
+
const table = new Table({ truncate: { filePath: 'start', symbolType: 'none' } });
|
|
45
45
|
for (const issue of issues.sort(sortByPos)) {
|
|
46
46
|
table.row();
|
|
47
47
|
const print = options.isUseColors && (issue.isFixed || issue.severity === 'warn') ? dim : plain;
|
package/dist/types/config.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ export type SourceMap = {
|
|
|
100
100
|
srcDir: string;
|
|
101
101
|
outDir: string;
|
|
102
102
|
};
|
|
103
|
-
|
|
103
|
+
interface ResolveSourceMapOptions {
|
|
104
104
|
cwd: string;
|
|
105
105
|
manifest: Manifest;
|
|
106
106
|
dependencies: Set<string>;
|
|
@@ -109,7 +109,7 @@ export interface ResolveSourceMapOptions {
|
|
|
109
109
|
}
|
|
110
110
|
export type ResolveSourceMap = (options: ResolveSourceMapOptions) => Promise<SourceMap[]> | SourceMap[];
|
|
111
111
|
export type HandleInput = (input: Input) => string | undefined;
|
|
112
|
-
|
|
112
|
+
type RegisterCompilerInput = {
|
|
113
113
|
extension: string;
|
|
114
114
|
compiler: CompilerSync;
|
|
115
115
|
};
|
|
@@ -117,7 +117,7 @@ export type RegisterCompiler = (input: RegisterCompilerInput) => void;
|
|
|
117
117
|
export type ResolveFromAST = (program: Program, options: PluginOptions & {
|
|
118
118
|
readFile: (filePath: string) => string;
|
|
119
119
|
}) => Input[];
|
|
120
|
-
|
|
120
|
+
type RegisterCompilersOptions = {
|
|
121
121
|
cwd: string;
|
|
122
122
|
hasDependency: HasDependency;
|
|
123
123
|
registerCompiler: RegisterCompiler;
|
|
@@ -52,7 +52,7 @@ export interface ExportMember extends Position {
|
|
|
52
52
|
readonly flags: number;
|
|
53
53
|
hasRefsInFile: boolean;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
type ExportMap = Map<Identifier, Export>;
|
|
56
56
|
export type Imports = Set<Import>;
|
|
57
57
|
export type FileNode = {
|
|
58
58
|
imports: {
|
|
@@ -63,7 +63,7 @@ export interface WalkState extends WalkContext {
|
|
|
63
63
|
addExport: (identifier: string, type: SymbolType, pos: number, members: ExportMember[], fix: Fix, isReExport: boolean, jsDocTags: Set<string>) => void;
|
|
64
64
|
getFix: (start: number, end: number, flags?: number) => Fix;
|
|
65
65
|
getTypeFix: (start: number, end: number) => Fix;
|
|
66
|
-
collectRefsInType: (node: any, exportName: string, signatureOnly: boolean
|
|
66
|
+
collectRefsInType: (node: any, exportName: string, signatureOnly: boolean) => void;
|
|
67
67
|
addRefInExport: (name: string, exportName: string) => void;
|
|
68
68
|
isInNamespace: (node: Span) => boolean;
|
|
69
69
|
}
|
|
@@ -47,26 +47,17 @@ const _addExport = (identifier, type, pos, members, fix, isReExport, jsDocTags)
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
|
-
const
|
|
51
|
-
'TSPropertySignature',
|
|
52
|
-
'TSMethodSignature',
|
|
53
|
-
'TSIndexSignature',
|
|
54
|
-
'TSCallSignatureDeclaration',
|
|
55
|
-
'TSConstructSignatureDeclaration',
|
|
56
|
-
]);
|
|
57
|
-
const _collectRefsInType = (node, exportName, signatureOnly, inMember = false) => {
|
|
50
|
+
const _collectRefsInType = (node, exportName, signatureOnly) => {
|
|
58
51
|
if (!node || typeof node !== 'object')
|
|
59
52
|
return;
|
|
60
53
|
if (node.type === 'TSTypeQuery') {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
state.referencedInExport.set(name, new Set([exportName]));
|
|
69
|
-
}
|
|
54
|
+
const name = node.exprName.type === 'Identifier' ? node.exprName.name : undefined;
|
|
55
|
+
if (name) {
|
|
56
|
+
const refs = state.referencedInExport.get(name);
|
|
57
|
+
if (refs)
|
|
58
|
+
refs.add(exportName);
|
|
59
|
+
else
|
|
60
|
+
state.referencedInExport.set(name, new Set([exportName]));
|
|
70
61
|
}
|
|
71
62
|
return;
|
|
72
63
|
}
|
|
@@ -80,7 +71,6 @@ const _collectRefsInType = (node, exportName, signatureOnly, inMember = false) =
|
|
|
80
71
|
else
|
|
81
72
|
state.referencedInExport.set(name, new Set([exportName]));
|
|
82
73
|
}
|
|
83
|
-
const nextInMember = inMember || MEMBER_CONTAINERS.has(node.type);
|
|
84
74
|
for (const key in node) {
|
|
85
75
|
if (key === 'type' || key === 'parent')
|
|
86
76
|
continue;
|
|
@@ -88,11 +78,11 @@ const _collectRefsInType = (node, exportName, signatureOnly, inMember = false) =
|
|
|
88
78
|
if (Array.isArray(val)) {
|
|
89
79
|
for (const item of val) {
|
|
90
80
|
if (item && typeof item === 'object' && item.type)
|
|
91
|
-
_collectRefsInType(item, exportName, signatureOnly
|
|
81
|
+
_collectRefsInType(item, exportName, signatureOnly);
|
|
92
82
|
}
|
|
93
83
|
}
|
|
94
84
|
else if (val && typeof val === 'object' && val.type) {
|
|
95
|
-
_collectRefsInType(val, exportName, signatureOnly
|
|
85
|
+
_collectRefsInType(val, exportName, signatureOnly);
|
|
96
86
|
}
|
|
97
87
|
}
|
|
98
88
|
};
|
package/dist/util/Performance.js
CHANGED
|
@@ -111,7 +111,7 @@ class Performance {
|
|
|
111
111
|
table.cell('sum', stats.sum, twoFixed);
|
|
112
112
|
table.cell('%', (stats.sum / totalDuration) * 100, v => (typeof v === 'number' ? `${v.toFixed(0)}%` : ''));
|
|
113
113
|
}
|
|
114
|
-
table.sort('sum
|
|
114
|
+
table.sort('sum', 'desc');
|
|
115
115
|
return table.toString();
|
|
116
116
|
}
|
|
117
117
|
addMemoryMark(label) {
|
|
@@ -43,14 +43,14 @@ export const createOptions = async (options) => {
|
|
|
43
43
|
if (invalid.length > 0) {
|
|
44
44
|
loadedConfig[key] = value.filter((v) => validIssueTypes.has(v));
|
|
45
45
|
for (const name of invalid)
|
|
46
|
-
logWarning(
|
|
46
|
+
logWarning(`Ignored unknown issue type "${name}" in ${key}`);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
else if (typeof value === 'object') {
|
|
50
50
|
for (const name in value) {
|
|
51
51
|
if (!validIssueTypes.has(name)) {
|
|
52
52
|
delete value[name];
|
|
53
|
-
logWarning(
|
|
53
|
+
logWarning(`Ignored unknown issue type "${name}" in ${key}`);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
package/dist/util/errors.d.ts
CHANGED
|
@@ -11,5 +11,6 @@ export declare const hasErrorCause: (error: Error) => error is ErrorWithCause;
|
|
|
11
11
|
export declare const isConfigurationError: (error: Error) => error is ConfigurationError;
|
|
12
12
|
export declare const isModuleNotFoundError: (error: Error) => boolean;
|
|
13
13
|
export declare const isLoaderError: (error: Error) => error is LoaderError;
|
|
14
|
+
export declare const formatCauseMessage: (error: Error, cwd: string) => string;
|
|
14
15
|
export declare const getKnownErrors: (error: Error) => Error[];
|
|
15
16
|
export {};
|
package/dist/util/errors.js
CHANGED
|
@@ -9,6 +9,12 @@ export const hasErrorCause = (error) => !isZodErrorLike(error) && error.cause in
|
|
|
9
9
|
export const isConfigurationError = (error) => error instanceof ConfigurationError;
|
|
10
10
|
export const isModuleNotFoundError = (error) => 'code' in error && error.code === 'MODULE_NOT_FOUND';
|
|
11
11
|
export const isLoaderError = (error) => error instanceof LoaderError;
|
|
12
|
+
export const formatCauseMessage = (error, cwd) => {
|
|
13
|
+
let root = error;
|
|
14
|
+
while (root.cause instanceof Error)
|
|
15
|
+
root = root.cause;
|
|
16
|
+
return root.message.split('\n', 1)[0].replace(`${cwd}/`, '');
|
|
17
|
+
};
|
|
12
18
|
export const getKnownErrors = (error) => {
|
|
13
19
|
if (isZodErrorLike(error))
|
|
14
20
|
return [...error.issues].map(error => {
|
package/dist/util/fs.js
CHANGED
|
@@ -54,7 +54,7 @@ export const hasFileWithExtension = (cwd, dirName, extensions) => {
|
|
|
54
54
|
return false;
|
|
55
55
|
};
|
|
56
56
|
export const loadJSON = async (filePath) => {
|
|
57
|
-
const contents = await loadFile(filePath);
|
|
57
|
+
const contents = (await loadFile(filePath)).replace(/^/, '');
|
|
58
58
|
try {
|
|
59
59
|
return JSON.parse(contents);
|
|
60
60
|
}
|
package/dist/util/log.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const logWarning: (
|
|
2
|
-
export declare const logError: (
|
|
1
|
+
export declare const logWarning: (message: string) => void;
|
|
2
|
+
export declare const logError: (message: string) => void;
|
package/dist/util/log.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import st from './colors.js';
|
|
2
|
-
export const logWarning = (
|
|
3
|
-
console.warn(`${st.yellow(
|
|
2
|
+
export const logWarning = (message) => {
|
|
3
|
+
console.warn(`${st.yellow('WARNING')}: ${message}`);
|
|
4
4
|
};
|
|
5
|
-
export const logError = (
|
|
6
|
-
console.error(`${st.red(
|
|
5
|
+
export const logError = (message) => {
|
|
6
|
+
console.error(`${st.red('ERROR')}: ${message}`);
|
|
7
7
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { glob } from 'tinyglobby';
|
|
3
3
|
import { partition } from './array.js';
|
|
4
|
+
import { debugLog } from './debug.js';
|
|
4
5
|
import { ConfigurationError } from './errors.js';
|
|
6
|
+
import { logWarning } from './log.js';
|
|
5
7
|
import { getPackageName } from './package-name.js';
|
|
6
8
|
import { join } from './path.js';
|
|
7
9
|
export default async function mapWorkspaces(cwd, workspaces) {
|
|
@@ -20,7 +22,7 @@ export default async function mapWorkspaces(cwd, workspaces) {
|
|
|
20
22
|
const dir = join(cwd, name);
|
|
21
23
|
const manifestPath = join(cwd, match);
|
|
22
24
|
try {
|
|
23
|
-
const manifestStr = await readFile(manifestPath, 'utf8');
|
|
25
|
+
const manifestStr = (await readFile(manifestPath, 'utf8')).replace(/^/, '');
|
|
24
26
|
const manifest = JSON.parse(manifestStr);
|
|
25
27
|
const pkgName = getPackageName(manifest, dir);
|
|
26
28
|
const pkg = { dir, name, pkgName, manifestPath, manifestStr, manifest };
|
|
@@ -31,8 +33,12 @@ export default async function mapWorkspaces(cwd, workspaces) {
|
|
|
31
33
|
throw new ConfigurationError(`Missing package name in ${manifestPath}`);
|
|
32
34
|
}
|
|
33
35
|
catch (error) {
|
|
34
|
-
if (error
|
|
36
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
35
37
|
debugLog('*', `Unable to load package.json for ${name}`);
|
|
38
|
+
}
|
|
39
|
+
else if (error instanceof SyntaxError) {
|
|
40
|
+
logWarning(`Skipping workspace ${name}: invalid JSON in ${manifestPath} (${error.message})`);
|
|
41
|
+
}
|
|
36
42
|
else
|
|
37
43
|
throw error;
|
|
38
44
|
}
|
package/dist/util/table.d.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
type Value = string | number | undefined | false | null;
|
|
2
|
+
type TruncateMode = 'start' | 'end' | 'none';
|
|
3
|
+
type SortOrder = 'asc' | 'desc';
|
|
2
4
|
export declare class Table {
|
|
3
5
|
private columns;
|
|
4
6
|
private rows;
|
|
5
7
|
private header;
|
|
6
8
|
private maxWidth;
|
|
7
|
-
private
|
|
8
|
-
private noTruncate;
|
|
9
|
+
private truncateModes;
|
|
9
10
|
constructor(options?: {
|
|
10
11
|
maxWidth?: number;
|
|
11
12
|
header?: boolean;
|
|
12
|
-
|
|
13
|
-
noTruncate?: string[];
|
|
13
|
+
truncate?: Record<string, TruncateMode>;
|
|
14
14
|
});
|
|
15
15
|
row(): this;
|
|
16
16
|
cell(column: string, value: Value, formatter?: (value: Value) => string): this;
|
|
17
|
-
sort(column: string): this;
|
|
17
|
+
sort(column: string, order?: SortOrder): this;
|
|
18
|
+
private modeFor;
|
|
19
|
+
private distributeWidths;
|
|
18
20
|
toCells(): string[][];
|
|
19
21
|
toRows(): string[];
|
|
20
22
|
toString(): string;
|
package/dist/util/table.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { stripVTControlCharacters } from 'node:util';
|
|
2
2
|
import { pad, truncate, truncateStart } from './string.js';
|
|
3
|
-
const DEFAULT_MAX_WIDTH = process.stdout.columns || 120;
|
|
4
3
|
const MIN_TRUNCATED_WIDTH = 4;
|
|
5
4
|
const COLUMN_SEPARATOR = ' ';
|
|
5
|
+
const visibleLength = (text) => stripVTControlCharacters(text).length;
|
|
6
|
+
const isPrintable = (value) => typeof value === 'string' || typeof value === 'number';
|
|
7
|
+
const toDisplay = (value) => (isPrintable(value) ? String(value) : '');
|
|
6
8
|
export class Table {
|
|
7
9
|
columns = [];
|
|
8
10
|
rows = [];
|
|
9
11
|
header;
|
|
10
12
|
maxWidth;
|
|
11
|
-
|
|
12
|
-
noTruncate = [];
|
|
13
|
+
truncateModes;
|
|
13
14
|
constructor(options) {
|
|
14
15
|
this.header = options?.header ?? false;
|
|
15
|
-
this.maxWidth = options?.maxWidth ||
|
|
16
|
-
this.
|
|
17
|
-
this.noTruncate = options?.noTruncate || [];
|
|
16
|
+
this.maxWidth = options?.maxWidth || process.stdout.columns || 120;
|
|
17
|
+
this.truncateModes = options?.truncate ?? {};
|
|
18
18
|
}
|
|
19
19
|
row() {
|
|
20
20
|
this.rows.push({});
|
|
@@ -25,67 +25,103 @@ export class Table {
|
|
|
25
25
|
this.columns.push(column);
|
|
26
26
|
const row = this.rows[this.rows.length - 1];
|
|
27
27
|
const align = typeof value === 'number' ? 'right' : 'left';
|
|
28
|
-
const formatted = formatter
|
|
29
|
-
|
|
28
|
+
const formatted = formatter?.(value);
|
|
29
|
+
const display = formatted ?? toDisplay(value);
|
|
30
|
+
row[column] = { value, formatted, align, width: visibleLength(display) };
|
|
30
31
|
return this;
|
|
31
32
|
}
|
|
32
|
-
sort(column) {
|
|
33
|
+
sort(column, order = 'asc') {
|
|
34
|
+
const dir = order === 'desc' ? -1 : 1;
|
|
33
35
|
this.rows.sort((a, b) => {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const vB = b[columnName].value;
|
|
36
|
+
const vA = a[column]?.value;
|
|
37
|
+
const vB = b[column]?.value;
|
|
37
38
|
if (typeof vA === 'string' && typeof vB === 'string')
|
|
38
|
-
return
|
|
39
|
+
return dir * vA.localeCompare(vB);
|
|
39
40
|
if (typeof vA === 'number' && typeof vB === 'number')
|
|
40
|
-
return
|
|
41
|
-
return !vA ? 1 : !vB ? -1 : 0;
|
|
41
|
+
return dir * (vA - vB);
|
|
42
|
+
return !isPrintable(vA) ? 1 : !isPrintable(vB) ? -1 : 0;
|
|
42
43
|
});
|
|
43
44
|
return this;
|
|
44
45
|
}
|
|
46
|
+
modeFor(column) {
|
|
47
|
+
return this.truncateModes[column] ?? 'end';
|
|
48
|
+
}
|
|
49
|
+
distributeWidths(columns, widths, separatorWidth) {
|
|
50
|
+
const truncatable = columns.filter(col => this.modeFor(col) !== 'none');
|
|
51
|
+
if (truncatable.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
const reserved = columns.filter(col => this.modeFor(col) === 'none').reduce((sum, col) => sum + widths[col], 0);
|
|
54
|
+
const budget = Math.max(0, this.maxWidth - separatorWidth - reserved);
|
|
55
|
+
const original = {};
|
|
56
|
+
for (const col of truncatable)
|
|
57
|
+
original[col] = widths[col];
|
|
58
|
+
const unresolved = new Set(truncatable);
|
|
59
|
+
let remainingBudget = budget;
|
|
60
|
+
let changed = true;
|
|
61
|
+
while (changed && unresolved.size > 0) {
|
|
62
|
+
changed = false;
|
|
63
|
+
const share = Math.floor(remainingBudget / unresolved.size);
|
|
64
|
+
for (const col of unresolved) {
|
|
65
|
+
if (original[col] <= share) {
|
|
66
|
+
widths[col] = original[col];
|
|
67
|
+
remainingBudget -= original[col];
|
|
68
|
+
unresolved.delete(col);
|
|
69
|
+
changed = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (unresolved.size === 0)
|
|
74
|
+
return;
|
|
75
|
+
const overMin = [...unresolved].reduce((sum, col) => sum + (original[col] - MIN_TRUNCATED_WIDTH), 0);
|
|
76
|
+
const excess = Math.max(0, remainingBudget - unresolved.size * MIN_TRUNCATED_WIDTH);
|
|
77
|
+
let distributed = 0;
|
|
78
|
+
for (const col of unresolved) {
|
|
79
|
+
const share = overMin > 0 ? Math.floor(((original[col] - MIN_TRUNCATED_WIDTH) * excess) / overMin) : 0;
|
|
80
|
+
widths[col] = MIN_TRUNCATED_WIDTH + share;
|
|
81
|
+
distributed += share;
|
|
82
|
+
}
|
|
83
|
+
const leftover = excess - distributed;
|
|
84
|
+
if (leftover > 0)
|
|
85
|
+
widths[[...unresolved][0]] += leftover;
|
|
86
|
+
}
|
|
45
87
|
toCells() {
|
|
46
|
-
const columns = this.columns.filter(col => this.rows.some(row =>
|
|
47
|
-
|
|
88
|
+
const columns = this.columns.filter(col => this.rows.some(row => isPrintable(row[col]?.value)));
|
|
89
|
+
const rows = [];
|
|
90
|
+
if (this.header && this.rows.length > 0) {
|
|
48
91
|
const headerRow = {};
|
|
49
92
|
const linesRow = {};
|
|
50
93
|
for (const col of columns) {
|
|
51
|
-
|
|
52
|
-
|
|
94
|
+
const align = this.rows[0][col]?.align === 'right' ? 'center' : 'left';
|
|
95
|
+
headerRow[col] = { value: col, align, width: col.length };
|
|
96
|
+
linesRow[col] = { value: '', fill: '-', width: 0 };
|
|
53
97
|
}
|
|
54
|
-
|
|
55
|
-
this.rows.unshift(headerRow);
|
|
98
|
+
rows.push(headerRow, linesRow);
|
|
56
99
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.filter(col => this.noTruncate.includes(col))
|
|
66
|
-
.reduce((sum, col) => sum + columnWidths[col], 0);
|
|
67
|
-
const truncatableColumns = columns.filter(col => !this.noTruncate.includes(col));
|
|
68
|
-
const minWidth = truncatableColumns.length * 4;
|
|
69
|
-
const availableWidth = this.maxWidth - separatorWidth - reservedWidth - minWidth;
|
|
70
|
-
const truncatableWidth = truncatableColumns.reduce((sum, col) => sum + columnWidths[col], 0) - minWidth;
|
|
71
|
-
const reduction = availableWidth / truncatableWidth;
|
|
72
|
-
let roundingDiff = availableWidth;
|
|
73
|
-
for (const col of truncatableColumns) {
|
|
74
|
-
const reducedWidth = MIN_TRUNCATED_WIDTH + Math.floor((columnWidths[col] - MIN_TRUNCATED_WIDTH) * reduction);
|
|
75
|
-
columnWidths[col] = reducedWidth;
|
|
76
|
-
roundingDiff -= reducedWidth - MIN_TRUNCATED_WIDTH;
|
|
77
|
-
}
|
|
78
|
-
if (roundingDiff > 0) {
|
|
79
|
-
columnWidths[truncatableColumns.length > 0 ? truncatableColumns[0] : columns[0]] += roundingDiff;
|
|
100
|
+
rows.push(...this.rows);
|
|
101
|
+
const columnWidths = {};
|
|
102
|
+
for (const col of columns) {
|
|
103
|
+
let max = 0;
|
|
104
|
+
for (const row of rows) {
|
|
105
|
+
const w = row[col]?.width ?? 0;
|
|
106
|
+
if (w > max)
|
|
107
|
+
max = w;
|
|
80
108
|
}
|
|
109
|
+
columnWidths[col] = max;
|
|
110
|
+
}
|
|
111
|
+
const separatorWidth = columns.length > 1 ? (columns.length - 1) * COLUMN_SEPARATOR.length : 0;
|
|
112
|
+
const totalWidth = columns.reduce((sum, col) => sum + columnWidths[col], 0) + separatorWidth;
|
|
113
|
+
if (totalWidth > this.maxWidth) {
|
|
114
|
+
this.distributeWidths(columns, columnWidths, separatorWidth);
|
|
81
115
|
}
|
|
82
|
-
return
|
|
116
|
+
return rows.map(row => columns.map((col, index) => {
|
|
83
117
|
const cell = row[col];
|
|
84
118
|
const width = columnWidths[col];
|
|
85
|
-
const fill = cell
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
119
|
+
const fill = cell?.fill || ' ';
|
|
120
|
+
const display = cell?.formatted ?? toDisplay(cell?.value);
|
|
121
|
+
const padded = pad(display, width, fill, cell?.align);
|
|
122
|
+
const mode = this.modeFor(col);
|
|
123
|
+
const rendered = mode === 'none' ? padded : mode === 'start' ? truncateStart(padded, width) : truncate(padded, width);
|
|
124
|
+
return index === 0 ? rendered : COLUMN_SEPARATOR + rendered;
|
|
89
125
|
}));
|
|
90
126
|
}
|
|
91
127
|
toRows() {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "6.
|
|
1
|
+
export declare const version = "6.7.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.
|
|
1
|
+
export const version = '6.7.0';
|