knip 5.75.1 → 5.76.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/README.md +22 -21
- package/dist/DependencyDeputy.d.ts +1 -1
- package/dist/DependencyDeputy.js +3 -3
- package/dist/WorkspaceWorker.d.ts +4 -4
- package/dist/WorkspaceWorker.js +5 -9
- package/dist/binaries/fallback.js +1 -1
- package/dist/cli.js +14 -14
- package/dist/graph/analyze.js +3 -17
- package/dist/graph/build.js +17 -6
- package/dist/graph-explorer/explorer.d.ts +2 -1
- package/dist/graph-explorer/explorer.js +2 -0
- package/dist/graph-explorer/operations/build-exports-tree.d.ts +3 -3
- package/dist/graph-explorer/operations/get-dependency-usage.d.ts +14 -0
- package/dist/graph-explorer/operations/get-dependency-usage.js +38 -0
- package/dist/plugins/sst/resolveFromAST.js +4 -4
- package/dist/reporters/githubActions.js +3 -1
- package/dist/reporters/trace.d.ts +11 -0
- package/dist/reporters/trace.js +45 -0
- package/dist/session/file-descriptor.d.ts +1 -1
- package/dist/session/file-descriptor.js +1 -1
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +1 -0
- package/dist/session/package-json-descriptor.d.ts +6 -0
- package/dist/session/package-json-descriptor.js +7 -0
- package/dist/session/session.d.ts +3 -1
- package/dist/session/session.js +2 -0
- package/dist/types/config.d.ts +1 -2
- package/dist/types/module-graph.d.ts +5 -0
- package/dist/typescript/get-imports-and-exports.js +2 -2
- package/dist/util/catalog.js +4 -2
- package/dist/util/cli-arguments.d.ts +2 -1
- package/dist/util/cli-arguments.js +3 -1
- package/dist/util/create-input-handler.d.ts +8 -0
- package/dist/util/{get-referenced-inputs.js → create-input-handler.js} +19 -5
- package/dist/util/create-options.d.ts +2 -1
- package/dist/util/create-options.js +41 -40
- package/dist/util/module-graph.d.ts +1 -0
- package/dist/util/module-graph.js +2 -1
- package/dist/util/trace.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/util/get-referenced-inputs.d.ts +0 -5
package/README.md
CHANGED
|
@@ -21,28 +21,28 @@ performance, less maintenance and easier refactorings.
|
|
|
21
21
|
- GitHub repo: [webpro-nl/knip][4]
|
|
22
22
|
- npm package: [knip][1]
|
|
23
23
|
- [Contributing Guide][7]
|
|
24
|
-
- Follow [@webpro.nl on Bluesky][
|
|
25
|
-
- [Sponsor Knip!][
|
|
24
|
+
- Follow [@webpro.nl on Bluesky][8] for updates
|
|
25
|
+
- [Sponsor Knip!][9]
|
|
26
26
|
|
|
27
27
|
## Contributors
|
|
28
28
|
|
|
29
|
-
Special thanks to [the wonderful people who have contributed to Knip][
|
|
29
|
+
Special thanks to [the wonderful people who have contributed to Knip][10]!
|
|
30
30
|
|
|
31
31
|
## Knip
|
|
32
32
|
|
|
33
|
-
/'knɪp/ means "(to) cut" and is [pronounced with a hard "K"][
|
|
33
|
+
/'knɪp/ means "(to) cut" and is [pronounced with a hard "K"][11] 🇳🇱
|
|
34
34
|
|
|
35
35
|
## License
|
|
36
36
|
|
|
37
|
-
Knip is free and open-source software licensed under the [ISC License][
|
|
37
|
+
Knip is free and open-source software licensed under the [ISC License][12].
|
|
38
38
|
|
|
39
39
|
Parts of Knip have been inspired by and/or partially copy code from the
|
|
40
40
|
following projects:
|
|
41
41
|
|
|
42
|
-
- [@npmcli/package-json][
|
|
43
|
-
- [@pnpm/deps.graph-sequencer][
|
|
44
|
-
- [file-entry-cache][
|
|
45
|
-
- [json-parse-even-better-errors][
|
|
42
|
+
- [@npmcli/package-json][13] ([ISC][14])
|
|
43
|
+
- [@pnpm/deps.graph-sequencer][15] ([MIT][16])
|
|
44
|
+
- [file-entry-cache][17] ([MIT][18])
|
|
45
|
+
- [json-parse-even-better-errors][19] ([MIT][20])
|
|
46
46
|
|
|
47
47
|
[1]: https://www.npmjs.com/package/knip
|
|
48
48
|
[2]: https://img.shields.io/npm/v/knip?color=f56e0f
|
|
@@ -52,16 +52,17 @@ following projects:
|
|
|
52
52
|
https://img.shields.io/github/stars/webpro-nl/knip?style=flat-square&color=f56e0f
|
|
53
53
|
[6]: https://knip.dev
|
|
54
54
|
[7]: https://github.com/webpro-nl/knip/blob/main/.github/CONTRIBUTING.md
|
|
55
|
-
[8]: https://
|
|
56
|
-
[9]: https://knip.dev
|
|
57
|
-
[10]: https://
|
|
58
|
-
[11]:
|
|
59
|
-
[12]:
|
|
60
|
-
[13]: https://github.com/npm/package-json
|
|
61
|
-
[14]: https://github.com/
|
|
62
|
-
[15]: https://github.com/pnpm/pnpm/
|
|
63
|
-
[16]: https://github.com/
|
|
64
|
-
[17]:
|
|
55
|
+
[8]: https://bsky.app/profile/webpro.nl
|
|
56
|
+
[9]: https://knip.dev/sponsors
|
|
57
|
+
[10]: https://knip.dev/#created-by-awesome-contributors
|
|
58
|
+
[11]: https://www.youtube.com/watch?v=PE7h7KvQoUI&t=9s
|
|
59
|
+
[12]: ./license
|
|
60
|
+
[13]: https://github.com/npm/package-json
|
|
61
|
+
[14]: https://github.com/npm/package-json/blob/main/LICENSE
|
|
62
|
+
[15]: https://github.com/pnpm/pnpm/tree/main/deps/graph-sequencer
|
|
63
|
+
[16]: https://github.com/pnpm/pnpm/blob/main/LICENSE
|
|
64
|
+
[17]: https://github.com/jaredwray/cacheable/tree/main/packages/file-entry-cache
|
|
65
|
+
[18]:
|
|
65
66
|
https://github.com/jaredwray/cacheable/blob/main/packages/file-entry-cache/LICENSE
|
|
66
|
-
[
|
|
67
|
-
[
|
|
67
|
+
[19]: https://github.com/npm/json-parse-even-better-errors
|
|
68
|
+
[20]: https://github.com/npm/json-parse-even-better-errors/blob/main/LICENSE.md
|
|
@@ -56,7 +56,7 @@ export declare class DependencyDeputy {
|
|
|
56
56
|
}[];
|
|
57
57
|
getOptionalPeerDependencies(workspaceName: string): DependencyArray;
|
|
58
58
|
maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string): boolean;
|
|
59
|
-
maybeAddReferencedBinary(workspace: Workspace, binaryName: string):
|
|
59
|
+
maybeAddReferencedBinary(workspace: Workspace, binaryName: string): Set<string> | undefined;
|
|
60
60
|
private isInDependencies;
|
|
61
61
|
settleDependencyIssues(): {
|
|
62
62
|
dependencyIssues: Issue[];
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -146,7 +146,7 @@ export class DependencyDeputy {
|
|
|
146
146
|
}
|
|
147
147
|
maybeAddReferencedBinary(workspace, binaryName) {
|
|
148
148
|
if (IGNORED_GLOBAL_BINARIES.has(binaryName))
|
|
149
|
-
return
|
|
149
|
+
return new Set();
|
|
150
150
|
this.addReferencedBinary(workspace.name, binaryName);
|
|
151
151
|
const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
|
|
152
152
|
for (const name of workspaceNames) {
|
|
@@ -156,11 +156,11 @@ export class DependencyDeputy {
|
|
|
156
156
|
if (dependencies?.size) {
|
|
157
157
|
for (const dependency of dependencies)
|
|
158
158
|
this.addReferencedDependency(name, dependency);
|
|
159
|
-
return
|
|
159
|
+
return dependencies;
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
return
|
|
163
|
+
return;
|
|
164
164
|
}
|
|
165
165
|
isInDependencies(workspaceName, packageName) {
|
|
166
166
|
const manifest = this._manifests.get(workspaceName);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CacheConsultant } from './CacheConsultant.js';
|
|
2
2
|
import { type Workspace } from './ConfigurationChief.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { GetSourceFile, HandleInput, WorkspaceConfiguration } from './types/config.js';
|
|
4
4
|
import type { ConfigurationHint } from './types/issues.js';
|
|
5
5
|
import type { PluginName } from './types/PluginNames.js';
|
|
6
6
|
import type { PackageJson } from './types/package-json.js';
|
|
@@ -13,7 +13,7 @@ type WorkspaceManagerOptions = {
|
|
|
13
13
|
config: WorkspaceConfiguration;
|
|
14
14
|
manifest: PackageJson;
|
|
15
15
|
dependencies: DependencySet;
|
|
16
|
-
|
|
16
|
+
handleInput: HandleInput;
|
|
17
17
|
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
|
|
18
18
|
getSourceFile: GetSourceFile;
|
|
19
19
|
negatedWorkspacePatterns: string[];
|
|
@@ -33,7 +33,7 @@ export declare class WorkspaceWorker {
|
|
|
33
33
|
config: WorkspaceConfiguration;
|
|
34
34
|
manifest: PackageJson;
|
|
35
35
|
dependencies: DependencySet;
|
|
36
|
-
|
|
36
|
+
handleInput: HandleInput;
|
|
37
37
|
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
|
|
38
38
|
getSourceFile: GetSourceFile;
|
|
39
39
|
negatedWorkspacePatterns: string[];
|
|
@@ -44,7 +44,7 @@ export declare class WorkspaceWorker {
|
|
|
44
44
|
enabledPluginsInAncestors: string[];
|
|
45
45
|
cache: CacheConsultant<CacheItem>;
|
|
46
46
|
configFilesMap: Map<string, Map<PluginName, Set<string>>>;
|
|
47
|
-
constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors,
|
|
47
|
+
constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }: WorkspaceManagerOptions);
|
|
48
48
|
init(): Promise<void>;
|
|
49
49
|
private determineEnabledPlugins;
|
|
50
50
|
private getConfigForPlugin;
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -22,7 +22,7 @@ export class WorkspaceWorker {
|
|
|
22
22
|
config;
|
|
23
23
|
manifest;
|
|
24
24
|
dependencies;
|
|
25
|
-
|
|
25
|
+
handleInput;
|
|
26
26
|
findWorkspaceByFilePath;
|
|
27
27
|
getSourceFile;
|
|
28
28
|
negatedWorkspacePatterns = [];
|
|
@@ -33,7 +33,7 @@ export class WorkspaceWorker {
|
|
|
33
33
|
enabledPluginsInAncestors;
|
|
34
34
|
cache;
|
|
35
35
|
configFilesMap;
|
|
36
|
-
constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors,
|
|
36
|
+
constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }) {
|
|
37
37
|
this.name = name;
|
|
38
38
|
this.dir = dir;
|
|
39
39
|
this.config = config;
|
|
@@ -43,7 +43,7 @@ export class WorkspaceWorker {
|
|
|
43
43
|
this.ignoredWorkspacePatterns = ignoredWorkspacePatterns;
|
|
44
44
|
this.enabledPluginsInAncestors = enabledPluginsInAncestors;
|
|
45
45
|
this.configFilesMap = configFilesMap;
|
|
46
|
-
this.
|
|
46
|
+
this.handleInput = handleInput;
|
|
47
47
|
this.findWorkspaceByFilePath = findWorkspaceByFilePath;
|
|
48
48
|
this.getSourceFile = getSourceFile;
|
|
49
49
|
this.options = options;
|
|
@@ -171,7 +171,7 @@ export class WorkspaceWorker {
|
|
|
171
171
|
const configFiles = this.configFilesMap.get(wsName);
|
|
172
172
|
const seen = new Map();
|
|
173
173
|
const storeConfigFilePath = (pluginName, input) => {
|
|
174
|
-
const configFilePath = this.
|
|
174
|
+
const configFilePath = this.handleInput(input);
|
|
175
175
|
if (configFilePath) {
|
|
176
176
|
const workspace = this.findWorkspaceByFilePath(configFilePath);
|
|
177
177
|
if (workspace) {
|
|
@@ -272,11 +272,7 @@ export class WorkspaceWorker {
|
|
|
272
272
|
}
|
|
273
273
|
if (plugin.resolveFromAST) {
|
|
274
274
|
const sourceFile = this.getSourceFile(configFilePath);
|
|
275
|
-
const resolveASTOpts = {
|
|
276
|
-
...resolveOpts,
|
|
277
|
-
getSourceFile: this.getSourceFile,
|
|
278
|
-
getReferencedInternalFilePath: this.getReferencedInternalFilePath,
|
|
279
|
-
};
|
|
275
|
+
const resolveASTOpts = { ...resolveOpts, getSourceFile: this.getSourceFile };
|
|
280
276
|
if (sourceFile) {
|
|
281
277
|
const inputs = plugin.resolveFromAST(sourceFile, resolveASTOpts);
|
|
282
278
|
for (const input of inputs)
|
|
@@ -3,7 +3,7 @@ import { compact } from '../util/array.js';
|
|
|
3
3
|
import { toBinary, toDeferResolve, toEntry } from '../util/input.js';
|
|
4
4
|
import { isValidBinary } from './bash-parser.js';
|
|
5
5
|
const spawningBinaries = ['cross-env', 'retry-cli'];
|
|
6
|
-
const endOfCommandBinaries = ['dotenvx', 'env-cmd'];
|
|
6
|
+
const endOfCommandBinaries = ['dotenvx', 'env-cmd', 'op'];
|
|
7
7
|
const positionals = new Set(['babel-node', 'esbuild', 'execa', 'jiti', 'oxnode', 'vite-node', 'zx']);
|
|
8
8
|
const positionalBinaries = new Set(['concurrently']);
|
|
9
9
|
export const resolve = (binary, args, { fromArgs }) => {
|
package/dist/cli.js
CHANGED
|
@@ -7,9 +7,9 @@ import { perfObserver } from './util/Performance.js';
|
|
|
7
7
|
import { runPreprocessors, runReporters } from './util/reporter.js';
|
|
8
8
|
import { prettyMilliseconds } from './util/string.js';
|
|
9
9
|
import { version } from './version.js';
|
|
10
|
-
let
|
|
10
|
+
let args = {};
|
|
11
11
|
try {
|
|
12
|
-
|
|
12
|
+
args = parseArgs();
|
|
13
13
|
}
|
|
14
14
|
catch (error) {
|
|
15
15
|
if (error instanceof Error) {
|
|
@@ -21,12 +21,12 @@ catch (error) {
|
|
|
21
21
|
}
|
|
22
22
|
const run = async () => {
|
|
23
23
|
try {
|
|
24
|
-
const options = await createOptions({
|
|
25
|
-
if (
|
|
24
|
+
const options = await createOptions({ args });
|
|
25
|
+
if (args.help) {
|
|
26
26
|
console.log(helpText);
|
|
27
27
|
process.exit(0);
|
|
28
28
|
}
|
|
29
|
-
if (
|
|
29
|
+
if (args.version) {
|
|
30
30
|
console.log(version);
|
|
31
31
|
process.exit(0);
|
|
32
32
|
}
|
|
@@ -46,12 +46,12 @@ const run = async () => {
|
|
|
46
46
|
isProduction: options.isProduction,
|
|
47
47
|
isShowProgress: options.isShowProgress,
|
|
48
48
|
isTreatConfigHintsAsErrors: options.isTreatConfigHintsAsErrors,
|
|
49
|
-
maxShowIssues:
|
|
50
|
-
options:
|
|
51
|
-
preprocessorOptions:
|
|
49
|
+
maxShowIssues: args['max-show-issues'] ? Number(args['max-show-issues']) : undefined,
|
|
50
|
+
options: args['reporter-options'] ?? '',
|
|
51
|
+
preprocessorOptions: args['preprocessor-options'] ?? '',
|
|
52
52
|
};
|
|
53
|
-
const finalData = await runPreprocessors(
|
|
54
|
-
await runReporters(
|
|
53
|
+
const finalData = await runPreprocessors(args.preprocessor ?? [], initialData);
|
|
54
|
+
await runReporters(args.reporter ?? ['symbols'], finalData);
|
|
55
55
|
const totalErrorCount = Object.keys(finalData.report)
|
|
56
56
|
.filter(reportGroup => finalData.report[reportGroup] && options.rules[reportGroup] === 'error')
|
|
57
57
|
.reduce((errorCount, reportGroup) => errorCount + finalData.counters[reportGroup], 0);
|
|
@@ -59,27 +59,27 @@ const run = async () => {
|
|
|
59
59
|
await perfObserver.finalize();
|
|
60
60
|
if (perfObserver.isTimerifyFunctions)
|
|
61
61
|
console.log(`\n${perfObserver.getTimerifiedFunctionsTable()}`);
|
|
62
|
-
if (perfObserver.isMemoryUsageEnabled && !
|
|
62
|
+
if (perfObserver.isMemoryUsageEnabled && !args['memory-realtime'])
|
|
63
63
|
console.log(`\n${perfObserver.getMemoryUsageTable()}`);
|
|
64
64
|
if (perfObserver.isEnabled) {
|
|
65
65
|
const duration = perfObserver.getCurrentDurationInMs();
|
|
66
66
|
console.log('\nTotal running time:', prettyMilliseconds(duration));
|
|
67
67
|
perfObserver.reset();
|
|
68
68
|
}
|
|
69
|
-
if (
|
|
69
|
+
if (args['experimental-tags'] && args['experimental-tags'].length > 0) {
|
|
70
70
|
logWarning('DEPRECATION WARNING', '--experimental-tags is deprecated, please start using --tags instead');
|
|
71
71
|
}
|
|
72
72
|
if (options.isIsolateWorkspaces && options.includedIssueTypes.classMembers) {
|
|
73
73
|
logWarning('WARNING', 'Class members are not tracked when using the --isolate-workspaces flag');
|
|
74
74
|
}
|
|
75
|
-
if ((!
|
|
75
|
+
if ((!args['no-exit-code'] && totalErrorCount > Number(args['max-issues'] ?? 0)) ||
|
|
76
76
|
(!options.isDisableConfigHints && options.isTreatConfigHintsAsErrors && configurationHints.size > 0)) {
|
|
77
77
|
process.exit(1);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
catch (error) {
|
|
81
81
|
process.exitCode = 2;
|
|
82
|
-
if (!
|
|
82
|
+
if (!args.debug && error instanceof Error && isKnownError(error)) {
|
|
83
83
|
const knownErrors = getKnownErrors(error);
|
|
84
84
|
for (const knownError of knownErrors)
|
|
85
85
|
logError('ERROR', knownError.message);
|
package/dist/graph/analyze.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { createGraphExplorer } from '../graph-explorer/explorer.js';
|
|
2
2
|
import { getIssueType, hasStrictlyEnumReferences } from '../graph-explorer/utils.js';
|
|
3
|
+
import traceReporter from '../reporters/trace.js';
|
|
3
4
|
import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
|
|
4
|
-
import { toRelative } from '../util/path.js';
|
|
5
5
|
import { findMatch } from '../util/regex.js';
|
|
6
6
|
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler } from '../util/tag.js';
|
|
7
|
-
import { formatTrace } from '../util/trace.js';
|
|
8
7
|
export const analyze = async ({ analyzedFiles, counselor, chief, collector, deputy, entryPaths, factory, graph, streamer, unreferencedFiles, options, }) => {
|
|
9
8
|
const shouldIgnore = getShouldIgnoreHandler(options.isProduction);
|
|
10
9
|
const shouldIgnoreTags = getShouldIgnoreTagHandler(options.tags);
|
|
@@ -228,20 +227,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
228
227
|
collector.addConfigurationHint(hint);
|
|
229
228
|
};
|
|
230
229
|
await analyzeGraph();
|
|
231
|
-
if (options.isTrace)
|
|
232
|
-
|
|
233
|
-
nodes.sort((a, b) => a.filePath.localeCompare(b.filePath) || a.identifier.localeCompare(b.identifier));
|
|
234
|
-
const toRel = (path) => toRelative(path, options.cwd);
|
|
235
|
-
const isReferenced = (node) => {
|
|
236
|
-
if (explorer.isReferenced(node.filePath, node.identifier, { includeEntryExports: false })[0])
|
|
237
|
-
return true;
|
|
238
|
-
if (explorer.hasStrictlyNsReferences(node.filePath, node.identifier)[0])
|
|
239
|
-
return true;
|
|
240
|
-
const exportItem = graph.get(node.filePath)?.exports.get(node.identifier);
|
|
241
|
-
return exportItem ? isExportReferencedInFile(exportItem) : false;
|
|
242
|
-
};
|
|
243
|
-
for (const node of nodes)
|
|
244
|
-
console.log(formatTrace(node, toRel, isReferenced(node)));
|
|
245
|
-
}
|
|
230
|
+
if (options.isTrace)
|
|
231
|
+
traceReporter({ graph, explorer, options, isExportReferencedInFile });
|
|
246
232
|
return analyzeGraph;
|
|
247
233
|
};
|
package/dist/graph/build.js
CHANGED
|
@@ -2,12 +2,12 @@ import { _getInputsFromScripts } from '../binaries/index.js';
|
|
|
2
2
|
import { getCompilerExtensions, getIncludedCompilers } from '../compilers/index.js';
|
|
3
3
|
import { DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS, IS_DTS } from '../constants.js';
|
|
4
4
|
import { partition } from '../util/array.js';
|
|
5
|
+
import { createInputHandler } from '../util/create-input-handler.js';
|
|
5
6
|
import { debugLog, debugLogArray } from '../util/debug.js';
|
|
6
|
-
import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
|
|
7
7
|
import { _glob, _syncGlob, negate, prependDirToPattern } from '../util/glob.js';
|
|
8
8
|
import { isAlias, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toProductionEntry, } from '../util/input.js';
|
|
9
9
|
import { loadTSConfig } from '../util/load-tsconfig.js';
|
|
10
|
-
import { updateImportMap } from '../util/module-graph.js';
|
|
10
|
+
import { createFileNode, updateImportMap } from '../util/module-graph.js';
|
|
11
11
|
import { getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
|
|
12
12
|
import { perfObserver } from '../util/Performance.js';
|
|
13
13
|
import { getEntrySpecifiersFromManifest, getManifestImportDependencies } from '../util/package-json.js';
|
|
@@ -20,7 +20,8 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
20
20
|
const toModuleSourceFilePath = getModuleSourcePathHandler(chief);
|
|
21
21
|
const toSourceFilePaths = getToSourcePathsHandler(chief);
|
|
22
22
|
const addIssue = (issue) => collector.addIssue(issue) && options.isWatch && collector.retainIssue(issue);
|
|
23
|
-
const
|
|
23
|
+
const externalRefsFromInputs = new Map();
|
|
24
|
+
const handleInput = createInputHandler(deputy, chief, isGitIgnored, addIssue, externalRefsFromInputs, options);
|
|
24
25
|
for (const workspace of workspaces) {
|
|
25
26
|
const { name, dir, manifestPath, manifestStr } = workspace;
|
|
26
27
|
const manifest = chief.getManifestForWorkspace(name);
|
|
@@ -61,7 +62,7 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
61
62
|
config,
|
|
62
63
|
manifest,
|
|
63
64
|
dependencies,
|
|
64
|
-
|
|
65
|
+
handleInput: (input) => handleInput(input, workspace),
|
|
65
66
|
findWorkspaceByFilePath: chief.findWorkspaceByFilePath.bind(chief),
|
|
66
67
|
negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
|
|
67
68
|
ignoredWorkspacePatterns: chief.getIgnoredWorkspacesFor(name),
|
|
@@ -150,7 +151,7 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
150
151
|
}
|
|
151
152
|
else if (!isConfig(input)) {
|
|
152
153
|
const ws = (input.containingFilePath && chief.findWorkspaceByFilePath(input.containingFilePath)) || workspace;
|
|
153
|
-
const resolvedFilePath =
|
|
154
|
+
const resolvedFilePath = handleInput(input, ws);
|
|
154
155
|
if (resolvedFilePath) {
|
|
155
156
|
if (isDeferResolveProductionEntry(input)) {
|
|
156
157
|
addPattern(productionPatternsSkipExports, input, resolvedFilePath);
|
|
@@ -320,12 +321,16 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
320
321
|
for (const input of inputs) {
|
|
321
322
|
input.containingFilePath ??= filePath;
|
|
322
323
|
input.dir ??= dir;
|
|
323
|
-
const specifierFilePath =
|
|
324
|
+
const specifierFilePath = handleInput(input, workspace);
|
|
324
325
|
if (specifierFilePath)
|
|
325
326
|
principal.addEntryPath(specifierFilePath, { skipExportsAnalysis: true });
|
|
326
327
|
}
|
|
327
328
|
}
|
|
328
329
|
file.imports.unresolved = unresolvedImports;
|
|
330
|
+
const pluginRefs = externalRefsFromInputs.get(filePath);
|
|
331
|
+
if (pluginRefs)
|
|
332
|
+
for (const ref of pluginRefs)
|
|
333
|
+
file.imports.externalRefs.add(ref);
|
|
329
334
|
const node = graph.get(filePath);
|
|
330
335
|
if (node) {
|
|
331
336
|
node.imports = file.imports;
|
|
@@ -380,6 +385,12 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
380
385
|
}
|
|
381
386
|
principals.length = 0;
|
|
382
387
|
}
|
|
388
|
+
for (const [filePath, refs] of externalRefsFromInputs) {
|
|
389
|
+
if (!graph.has(filePath))
|
|
390
|
+
graph.set(filePath, createFileNode());
|
|
391
|
+
for (const ref of refs)
|
|
392
|
+
graph.get(filePath).imports.externalRefs.add(ref);
|
|
393
|
+
}
|
|
383
394
|
return {
|
|
384
395
|
graph,
|
|
385
396
|
entryPaths,
|
|
@@ -7,7 +7,8 @@ export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<s
|
|
|
7
7
|
buildExportsTree: (options: {
|
|
8
8
|
filePath?: string;
|
|
9
9
|
identifier?: string;
|
|
10
|
-
}) => import("./operations/build-exports-tree.js").
|
|
10
|
+
}) => import("./operations/build-exports-tree.js").ExportsTreeNode[];
|
|
11
|
+
getDependencyUsage: (pattern?: string | RegExp) => Map<string, import("./operations/get-dependency-usage.js").DependencyNodes>;
|
|
11
12
|
resolveDefinition: (filePath: string, identifier: string) => import("./operations/resolve-definition.js").DefinitionResult | null;
|
|
12
13
|
getUsage: (filePath: string, identifier: string) => import("./operations/get-usage.js").UsageResult;
|
|
13
14
|
findCycles: (filePath: string, maxDepth?: number) => import("../session/types.js").Cycle[];
|
|
@@ -2,6 +2,7 @@ import { invalidateCache as invalidateCacheInternal } from './cache.js';
|
|
|
2
2
|
import { buildExportsTree } from './operations/build-exports-tree.js';
|
|
3
3
|
import { findCycles } from './operations/find-cycles.js';
|
|
4
4
|
import { getContention } from './operations/get-contention.js';
|
|
5
|
+
import { getDependencyUsage } from './operations/get-dependency-usage.js';
|
|
5
6
|
import { getUsage } from './operations/get-usage.js';
|
|
6
7
|
import { hasStrictlyNsReferences } from './operations/has-strictly-ns-references.js';
|
|
7
8
|
import { isReferenced } from './operations/is-referenced.js';
|
|
@@ -11,6 +12,7 @@ export const createGraphExplorer = (graph, entryPaths) => {
|
|
|
11
12
|
isReferenced: (filePath, identifier, options) => isReferenced(graph, entryPaths, filePath, identifier, options),
|
|
12
13
|
hasStrictlyNsReferences: (filePath, identifier) => hasStrictlyNsReferences(graph, graph.get(filePath)?.imported, identifier),
|
|
13
14
|
buildExportsTree: (options) => buildExportsTree(graph, entryPaths, options),
|
|
15
|
+
getDependencyUsage: (pattern) => getDependencyUsage(graph, pattern),
|
|
14
16
|
resolveDefinition: (filePath, identifier) => resolveDefinition(graph, filePath, identifier),
|
|
15
17
|
getUsage: (filePath, identifier) => getUsage(graph, entryPaths, filePath, identifier),
|
|
16
18
|
findCycles: (filePath, maxDepth) => findCycles(graph, filePath, maxDepth),
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { Identifier, ModuleGraph } from '../../types/module-graph.js';
|
|
2
2
|
import type { Via } from '../walk-down.js';
|
|
3
|
-
export interface
|
|
3
|
+
export interface ExportsTreeNode {
|
|
4
4
|
filePath: string;
|
|
5
5
|
identifier: string;
|
|
6
6
|
originalId: string | undefined;
|
|
7
7
|
via: Via | undefined;
|
|
8
8
|
refs: string[];
|
|
9
9
|
isEntry: boolean;
|
|
10
|
-
children:
|
|
10
|
+
children: ExportsTreeNode[];
|
|
11
11
|
}
|
|
12
12
|
export declare const buildExportsTree: (graph: ModuleGraph, entryPaths: Set<string>, options: {
|
|
13
13
|
filePath?: string;
|
|
14
14
|
identifier?: Identifier;
|
|
15
|
-
}) =>
|
|
15
|
+
}) => ExportsTreeNode[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ModuleGraph } from '../../types/module-graph.js';
|
|
2
|
+
export interface DependencyNode {
|
|
3
|
+
filePath: string;
|
|
4
|
+
specifier: string;
|
|
5
|
+
binaryName: string | undefined;
|
|
6
|
+
pos: number | undefined;
|
|
7
|
+
line: number | undefined;
|
|
8
|
+
col: number | undefined;
|
|
9
|
+
}
|
|
10
|
+
export interface DependencyNodes {
|
|
11
|
+
packageName: string;
|
|
12
|
+
imports: DependencyNode[];
|
|
13
|
+
}
|
|
14
|
+
export declare const getDependencyUsage: (graph: ModuleGraph, pattern?: string | RegExp) => Map<string, DependencyNodes>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getPackageNameFromModuleSpecifier } from '../../util/modules.js';
|
|
2
|
+
export const getDependencyUsage = (graph, pattern) => {
|
|
3
|
+
const result = new Map();
|
|
4
|
+
const isMatch = (packageName, binaryName) => {
|
|
5
|
+
if (!pattern)
|
|
6
|
+
return true;
|
|
7
|
+
if (typeof pattern === 'string')
|
|
8
|
+
return packageName === pattern || binaryName === pattern;
|
|
9
|
+
return pattern.test(packageName) || (binaryName !== undefined && pattern.test(binaryName));
|
|
10
|
+
};
|
|
11
|
+
const addEntry = (packageName, filePath, specifier, binaryName, pos, line, col) => {
|
|
12
|
+
let entry = result.get(packageName);
|
|
13
|
+
if (!entry) {
|
|
14
|
+
entry = { packageName, imports: [] };
|
|
15
|
+
result.set(packageName, entry);
|
|
16
|
+
}
|
|
17
|
+
entry.imports.push({ filePath, specifier, binaryName, pos, line, col });
|
|
18
|
+
};
|
|
19
|
+
for (const [filePath, file] of graph) {
|
|
20
|
+
if (file.imports?.external) {
|
|
21
|
+
for (const _import of file.imports.external) {
|
|
22
|
+
const packageName = getPackageNameFromModuleSpecifier(_import.specifier);
|
|
23
|
+
if (packageName && isMatch(packageName)) {
|
|
24
|
+
addEntry(packageName, filePath, _import.specifier, undefined, _import.pos, _import.line, _import.col);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (file.imports?.externalRefs) {
|
|
29
|
+
for (const ref of file.imports.externalRefs) {
|
|
30
|
+
const packageName = getPackageNameFromModuleSpecifier(ref.specifier);
|
|
31
|
+
if (packageName && isMatch(packageName, ref.identifier)) {
|
|
32
|
+
addEntry(packageName, filePath, ref.specifier, ref.identifier, undefined, undefined, undefined);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { getImportMap, getPropertyValues } from '../../typescript/ast-helpers.js';
|
|
3
3
|
import { toDeferResolveProductionEntry } from '../../util/input.js';
|
|
4
|
+
import { dirname } from '../../util/path.js';
|
|
5
|
+
import { _resolveSync } from '../../util/resolve.js';
|
|
4
6
|
export const getInputsFromHandlers = (sourceFile, options) => {
|
|
5
|
-
const { getSourceFile, getReferencedInternalFilePath } = options;
|
|
6
7
|
const entries = new Set();
|
|
7
8
|
const importMap = getImportMap(sourceFile);
|
|
8
9
|
function addHandlerSpecifiers(node) {
|
|
@@ -21,10 +22,9 @@ export const getInputsFromHandlers = (sourceFile, options) => {
|
|
|
21
22
|
if (ts.isIdentifier(arg)) {
|
|
22
23
|
const importPath = importMap.get(arg.text);
|
|
23
24
|
if (importPath) {
|
|
24
|
-
const
|
|
25
|
-
const resolvedPath = getReferencedInternalFilePath(input);
|
|
25
|
+
const resolvedPath = _resolveSync(importPath, dirname(options.configFilePath));
|
|
26
26
|
if (resolvedPath) {
|
|
27
|
-
const stackFile = getSourceFile(resolvedPath);
|
|
27
|
+
const stackFile = options.getSourceFile(resolvedPath);
|
|
28
28
|
if (stackFile)
|
|
29
29
|
ts.forEachChild(stackFile, addHandlerSpecifiers);
|
|
30
30
|
}
|
|
@@ -33,6 +33,7 @@ export default ({ report, issues, cwd, configurationHints, isDisableConfigHints,
|
|
|
33
33
|
if (isReportType) {
|
|
34
34
|
const title = reportMultipleGroups && getIssueTypeTitle(reportType);
|
|
35
35
|
const issuesForType = Object.values(issues[reportType]).flatMap(Object.values);
|
|
36
|
+
issuesForType.sort((a, b) => a.filePath.localeCompare(b.filePath) || (a.line ?? 0) - (b.line ?? 0));
|
|
36
37
|
if (issuesForType.length > 0) {
|
|
37
38
|
title && core.info(`${title} (${issuesForType.length})`);
|
|
38
39
|
for (const issue of issuesForType) {
|
|
@@ -56,7 +57,8 @@ export default ({ report, issues, cwd, configurationHints, isDisableConfigHints,
|
|
|
56
57
|
if (!isDisableConfigHints && configurationHints.size > 0) {
|
|
57
58
|
const CONFIG_HINTS_TITLE = 'Configuration hints';
|
|
58
59
|
core.info(`${CONFIG_HINTS_TITLE} (${configurationHints.size})`);
|
|
59
|
-
|
|
60
|
+
const sortedHints = [...configurationHints].sort((a, b) => (a.filePath ?? '').localeCompare(b.filePath ?? ''));
|
|
61
|
+
for (const hint of sortedHints) {
|
|
60
62
|
const hintPrinter = hintPrinters.get(hint.type);
|
|
61
63
|
const message = hintPrinter?.print({
|
|
62
64
|
...hint,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GraphExplorer } from '../graph-explorer/explorer.js';
|
|
2
|
+
import type { Export, ExportMember, ModuleGraph } from '../types/module-graph.js';
|
|
3
|
+
import type { MainOptions } from '../util/create-options.js';
|
|
4
|
+
interface TraceReporterOptions {
|
|
5
|
+
graph: ModuleGraph;
|
|
6
|
+
explorer: GraphExplorer;
|
|
7
|
+
options: MainOptions;
|
|
8
|
+
isExportReferencedInFile: (exportedItem: Export | ExportMember) => boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: ({ graph, explorer, options, isExportReferencedInFile }: TraceReporterOptions) => void;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
import { join, toRelative } from '../util/path.js';
|
|
3
|
+
import { toRegexOrString } from '../util/regex.js';
|
|
4
|
+
import { Table } from '../util/table.js';
|
|
5
|
+
import { formatTrace } from '../util/trace.js';
|
|
6
|
+
export default ({ graph, explorer, options, isExportReferencedInFile }) => {
|
|
7
|
+
if (options.traceDependency) {
|
|
8
|
+
const pattern = toRegexOrString(options.traceDependency);
|
|
9
|
+
const workspaceDir = options.workspace ? join(options.cwd, options.workspace) : undefined;
|
|
10
|
+
const toRel = (path) => toRelative(path, options.cwd);
|
|
11
|
+
const table = new Table({ truncateStart: ['filePath'] });
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
for (const [packageName, { imports }] of explorer.getDependencyUsage(pattern)) {
|
|
14
|
+
const filtered = workspaceDir ? imports.filter(i => i.filePath.startsWith(workspaceDir)) : imports;
|
|
15
|
+
filtered.sort((a, b) => a.filePath.localeCompare(b.filePath) || (a.line ?? 0) - (b.line ?? 0));
|
|
16
|
+
for (const _import of filtered) {
|
|
17
|
+
const pos = _import.line ? `:${_import.line}:${_import.col}` : '';
|
|
18
|
+
const key = `${_import.filePath}${pos}:${packageName}`;
|
|
19
|
+
if (seen.has(key))
|
|
20
|
+
continue;
|
|
21
|
+
seen.add(key);
|
|
22
|
+
table.row();
|
|
23
|
+
table.cell('filePath', pc.whiteBright(`${toRel(_import.filePath)}${pos}`));
|
|
24
|
+
table.cell('package', pc.cyanBright(packageName));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const line of table.toRows())
|
|
28
|
+
console.log(line);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const nodes = explorer.buildExportsTree({ filePath: options.traceFile, identifier: options.traceExport });
|
|
32
|
+
nodes.sort((a, b) => a.filePath.localeCompare(b.filePath) || a.identifier.localeCompare(b.identifier));
|
|
33
|
+
const toRel = (path) => toRelative(path, options.cwd);
|
|
34
|
+
const isReferenced = (node) => {
|
|
35
|
+
if (explorer.isReferenced(node.filePath, node.identifier, { includeEntryExports: false })[0])
|
|
36
|
+
return true;
|
|
37
|
+
if (explorer.hasStrictlyNsReferences(node.filePath, node.identifier)[0])
|
|
38
|
+
return true;
|
|
39
|
+
const exportItem = graph.get(node.filePath)?.exports.get(node.identifier);
|
|
40
|
+
return exportItem ? isExportReferencedInFile(exportItem) : false;
|
|
41
|
+
};
|
|
42
|
+
for (const node of nodes)
|
|
43
|
+
console.log(formatTrace(node, toRel, isReferenced(node)));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -3,4 +3,4 @@ import type { File } from './types.js';
|
|
|
3
3
|
export interface FileDescriptorOptions {
|
|
4
4
|
isShowContention?: boolean;
|
|
5
5
|
}
|
|
6
|
-
export declare const buildFileDescriptor: (filePath: string, cwd: string, graph: ModuleGraph, entryPaths: Set<string>, options?: FileDescriptorOptions) => File |
|
|
6
|
+
export declare const buildFileDescriptor: (filePath: string, cwd: string, graph: ModuleGraph, entryPaths: Set<string>, options?: FileDescriptorOptions) => File | undefined;
|
|
@@ -5,7 +5,7 @@ export const buildFileDescriptor = (filePath, cwd, graph, entryPaths, options =
|
|
|
5
5
|
const absolutePath = toAbsolute(filePath, cwd);
|
|
6
6
|
const node = graph.get(absolutePath);
|
|
7
7
|
if (!node)
|
|
8
|
-
return
|
|
8
|
+
return;
|
|
9
9
|
const explorer = createGraphExplorer(graph, entryPaths);
|
|
10
10
|
const metrics = { imports: 0, exports: 0, cycles: 0, contention: 0 };
|
|
11
11
|
let t0 = performance.now();
|
package/dist/session/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { IMPORT_STAR, KNIP_CONFIG_LOCATIONS, SIDE_EFFECTS } from '../constants.js';
|
|
2
|
+
export type { DependencyNode, DependencyNodes } from '../graph-explorer/operations/get-dependency-usage.js';
|
|
2
3
|
export { finalizeConfigurationHints } from '../reporters/util/configuration-hints.js';
|
|
3
4
|
export { getIssuePrefix } from '../reporters/util/util.js';
|
|
4
5
|
export type { Results } from '../run.js';
|
|
@@ -6,5 +7,6 @@ export type { Issue, Issues, IssueType, Rules } from '../types/issues.js';
|
|
|
6
7
|
export type { PackageJson } from '../types/package-json.js';
|
|
7
8
|
export { createOptions, type MainOptions } from '../util/create-options.js';
|
|
8
9
|
export { buildFileDescriptor, type FileDescriptorOptions } from './file-descriptor.js';
|
|
10
|
+
export { buildPackageJsonDescriptor, type PackageJsonFile } from './package-json-descriptor.js';
|
|
9
11
|
export { createSession, type Session } from './session.js';
|
|
10
12
|
export type { ContentionDetails, Export, File, SourceLocation } from './types.js';
|
package/dist/session/index.js
CHANGED
|
@@ -3,4 +3,5 @@ export { finalizeConfigurationHints } from '../reporters/util/configuration-hint
|
|
|
3
3
|
export { getIssuePrefix } from '../reporters/util/util.js';
|
|
4
4
|
export { createOptions } from '../util/create-options.js';
|
|
5
5
|
export { buildFileDescriptor } from './file-descriptor.js';
|
|
6
|
+
export { buildPackageJsonDescriptor } from './package-json-descriptor.js';
|
|
6
7
|
export { createSession } from './session.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DependencyNodes } from '../graph-explorer/operations/get-dependency-usage.js';
|
|
2
|
+
import type { ModuleGraph } from '../types/module-graph.js';
|
|
3
|
+
export interface PackageJsonFile {
|
|
4
|
+
dependenciesUsage: Map<string, DependencyNodes>;
|
|
5
|
+
}
|
|
6
|
+
export declare const buildPackageJsonDescriptor: (graph: ModuleGraph, entryPaths: Set<string>) => PackageJsonFile;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createGraphExplorer } from '../graph-explorer/explorer.js';
|
|
2
|
+
export const buildPackageJsonDescriptor = (graph, entryPaths) => {
|
|
3
|
+
const explorer = createGraphExplorer(graph, entryPaths);
|
|
4
|
+
return {
|
|
5
|
+
dependenciesUsage: explorer.getDependencyUsage(),
|
|
6
|
+
};
|
|
7
|
+
};
|
|
@@ -4,6 +4,7 @@ import { type Results } from '../run.js';
|
|
|
4
4
|
import type { MainOptions } from '../util/create-options.js';
|
|
5
5
|
import type { WatchChange } from '../util/watch.js';
|
|
6
6
|
import { type FileDescriptorOptions } from './file-descriptor.js';
|
|
7
|
+
import { type PackageJsonFile } from './package-json-descriptor.js';
|
|
7
8
|
import type { File } from './types.js';
|
|
8
9
|
type WatchUpdate = {
|
|
9
10
|
duration: number;
|
|
@@ -14,7 +15,8 @@ export interface Session {
|
|
|
14
15
|
getIssues(): CollectorIssues;
|
|
15
16
|
getResults(): Results;
|
|
16
17
|
getConfigurationHints(): ProcessedHint[];
|
|
17
|
-
describeFile(filePath: string, options?: FileDescriptorOptions): File |
|
|
18
|
+
describeFile(filePath: string, options?: FileDescriptorOptions): File | undefined;
|
|
19
|
+
describePackageJson(): PackageJsonFile;
|
|
18
20
|
}
|
|
19
21
|
export declare const createSession: (options: MainOptions) => Promise<Session>;
|
|
20
22
|
export {};
|
package/dist/session/session.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { finalizeConfigurationHints } from '../reporters/util/configuration-hints.js';
|
|
2
2
|
import { run } from '../run.js';
|
|
3
3
|
import { buildFileDescriptor } from './file-descriptor.js';
|
|
4
|
+
import { buildPackageJsonDescriptor } from './package-json-descriptor.js';
|
|
4
5
|
export const createSession = async (options) => {
|
|
5
6
|
const { session, results } = await run(options);
|
|
6
7
|
if (!session)
|
|
@@ -14,5 +15,6 @@ const createSessionAdapter = (session, results, options) => {
|
|
|
14
15
|
getResults: () => results,
|
|
15
16
|
getConfigurationHints: () => finalizeConfigurationHints(results, options),
|
|
16
17
|
describeFile: (filePath, opts) => buildFileDescriptor(filePath, options.cwd, session.getGraph(), session.getEntryPaths(), opts),
|
|
18
|
+
describePackageJson: () => buildPackageJsonDescriptor(session.getGraph(), session.getEntryPaths()),
|
|
17
19
|
};
|
|
18
20
|
};
|
package/dist/types/config.d.ts
CHANGED
|
@@ -96,10 +96,9 @@ export type IsLoadConfig = (options: PluginOptions, dependencies: Set<string>) =
|
|
|
96
96
|
export type ResolveConfig<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];
|
|
97
97
|
export type Resolve = (options: PluginOptions) => Promise<Input[]> | Input[];
|
|
98
98
|
export type GetSourceFile = (filePath: string) => ts.SourceFile | undefined;
|
|
99
|
-
export type
|
|
99
|
+
export type HandleInput = (input: Input) => string | undefined;
|
|
100
100
|
export type ResolveFromAST = (sourceFile: ts.SourceFile, options: PluginOptions & {
|
|
101
101
|
getSourceFile: GetSourceFile;
|
|
102
|
-
getReferencedInternalFilePath: GetReferencedInternalFilePath;
|
|
103
102
|
}) => Input[];
|
|
104
103
|
export interface Plugin {
|
|
105
104
|
title: string;
|
|
@@ -30,6 +30,10 @@ export interface Import extends Position {
|
|
|
30
30
|
readonly identifier: string | undefined;
|
|
31
31
|
readonly isTypeOnly: boolean;
|
|
32
32
|
}
|
|
33
|
+
export interface ExternalRef {
|
|
34
|
+
readonly specifier: string;
|
|
35
|
+
readonly identifier: string | undefined;
|
|
36
|
+
}
|
|
33
37
|
export interface Export extends Position {
|
|
34
38
|
readonly identifier: Identifier;
|
|
35
39
|
readonly type: SymbolType;
|
|
@@ -58,6 +62,7 @@ export type FileNode = {
|
|
|
58
62
|
imports: {
|
|
59
63
|
readonly internal: ImportMap;
|
|
60
64
|
readonly external: Set<Import>;
|
|
65
|
+
readonly externalRefs: Set<ExternalRef>;
|
|
61
66
|
unresolved: Set<Import>;
|
|
62
67
|
readonly programFiles: Set<FilePath>;
|
|
63
68
|
readonly entryFiles: Set<FilePath>;
|
|
@@ -164,7 +164,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
|
|
|
164
164
|
filePath,
|
|
165
165
|
specifier: sanitizedSpecifier,
|
|
166
166
|
identifier: opts.identifier ?? SIDE_EFFECTS,
|
|
167
|
-
pos
|
|
167
|
+
pos,
|
|
168
168
|
line: line + 1,
|
|
169
169
|
col: character + 2,
|
|
170
170
|
isTypeOnly: !!(opts.modifiers & IMPORT_FLAGS.TYPE_ONLY),
|
|
@@ -445,7 +445,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
|
|
|
445
445
|
item.symbol = undefined;
|
|
446
446
|
}
|
|
447
447
|
return {
|
|
448
|
-
imports: { internal, external, programFiles, entryFiles, imports, unresolved },
|
|
448
|
+
imports: { internal, external, externalRefs: new Set(), programFiles, entryFiles, imports, unresolved },
|
|
449
449
|
exports,
|
|
450
450
|
duplicates: [...aliasedExports.values()],
|
|
451
451
|
scripts,
|
package/dist/util/catalog.js
CHANGED
|
@@ -24,8 +24,10 @@ const extractNamedEntries = (catalogs) => {
|
|
|
24
24
|
const entries = new Set();
|
|
25
25
|
if (catalogs && typeof catalogs === 'object') {
|
|
26
26
|
for (const [catalogName, catalog] of Object.entries(catalogs)) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (catalog && typeof catalog === 'object') {
|
|
28
|
+
for (const name of Object.keys(catalog))
|
|
29
|
+
entries.add(`${catalogName}:${name}`);
|
|
30
|
+
}
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
return entries;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved,catalog\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --format Format modified files after --fix using the local formatter\n --allow-remove-files Allow Knip to remove files (with --fix)\n --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n --use-tsconfig-files Use tsconfig.json to define project files (override `project` patterns)\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, github-actions, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of total issues before non-zero exit code (default: 0)\n --max-show-issues
|
|
1
|
+
export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved,catalog\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --format Format modified files after --fix using the local formatter\n --allow-remove-files Allow Knip to remove files (with --fix)\n --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n --use-tsconfig-files Use tsconfig.json to define project files (override `project` patterns)\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, github-actions, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of total issues before non-zero exit code (default: 0)\n --max-show-issues Maximum number of issues to display per type\n -d, --debug Show debug output\n --trace Show trace output\n --trace-dependency [name] Show files that import the named dependency\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n --performance Measure count and running time of key functions and display stats table\n --performance-fn [name] Measure only function [name]\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates, catalog\n(2) Fixable issue types: dependencies, exports, types, catalog\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
|
|
2
2
|
export type ParsedCLIArgs = ReturnType<typeof parseCLIArgs>;
|
|
3
3
|
export default function parseCLIArgs(): {
|
|
4
4
|
cache?: boolean | undefined;
|
|
@@ -39,6 +39,7 @@ export default function parseCLIArgs(): {
|
|
|
39
39
|
'reporter-options'?: string | undefined;
|
|
40
40
|
strict?: boolean | undefined;
|
|
41
41
|
trace?: boolean | undefined;
|
|
42
|
+
'trace-dependency'?: string | undefined;
|
|
42
43
|
'trace-export'?: string | undefined;
|
|
43
44
|
'trace-file'?: string | undefined;
|
|
44
45
|
'treat-config-hints-as-errors'?: boolean | undefined;
|
|
@@ -37,9 +37,10 @@ Options:
|
|
|
37
37
|
--treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints
|
|
38
38
|
--no-exit-code Always exit with code zero (0)
|
|
39
39
|
--max-issues Maximum number of total issues before non-zero exit code (default: 0)
|
|
40
|
-
--max-show-issues
|
|
40
|
+
--max-show-issues Maximum number of issues to display per type
|
|
41
41
|
-d, --debug Show debug output
|
|
42
42
|
--trace Show trace output
|
|
43
|
+
--trace-dependency [name] Show files that import the named dependency
|
|
43
44
|
--trace-export [name] Show trace output for named export(s)
|
|
44
45
|
--trace-file [file] Show trace output for exports in file
|
|
45
46
|
--performance Measure count and running time of key functions and display stats table
|
|
@@ -103,6 +104,7 @@ export default function parseCLIArgs() {
|
|
|
103
104
|
'reporter-options': { type: 'string' },
|
|
104
105
|
strict: { type: 'boolean' },
|
|
105
106
|
trace: { type: 'boolean' },
|
|
107
|
+
'trace-dependency': { type: 'string' },
|
|
106
108
|
'trace-export': { type: 'string' },
|
|
107
109
|
'trace-file': { type: 'string' },
|
|
108
110
|
'treat-config-hints-as-errors': { type: 'boolean' },
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ConfigurationChief, Workspace } from '../ConfigurationChief.js';
|
|
2
|
+
import type { DependencyDeputy } from '../DependencyDeputy.js';
|
|
3
|
+
import type { Issue } from '../types/issues.js';
|
|
4
|
+
import type { ExternalRef } from '../types/module-graph.js';
|
|
5
|
+
import type { MainOptions } from './create-options.js';
|
|
6
|
+
import { type Input } from './input.js';
|
|
7
|
+
export type ExternalRefsFromInputs = Map<string, Set<ExternalRef>>;
|
|
8
|
+
export declare const createInputHandler: (deputy: DependencyDeputy, chief: ConfigurationChief, isGitIgnored: (filePath: string) => boolean, addIssue: (issue: Issue) => void, externalRefs: ExternalRefsFromInputs, options: MainOptions) => (input: Input, workspace: Workspace) => string | undefined;
|
|
@@ -7,15 +7,26 @@ import { _resolveSync } from './resolve.js';
|
|
|
7
7
|
const getWorkspaceFor = (input, chief, workspace) => (input.dir && chief.findWorkspaceByFilePath(`${input.dir}/`)) ||
|
|
8
8
|
(input.containingFilePath && chief.findWorkspaceByFilePath(input.containingFilePath)) ||
|
|
9
9
|
workspace;
|
|
10
|
-
|
|
10
|
+
const addExternalRef = (map, containingFilePath, ref) => {
|
|
11
|
+
if (!map.has(containingFilePath))
|
|
12
|
+
map.set(containingFilePath, new Set());
|
|
13
|
+
map.get(containingFilePath).add(ref);
|
|
14
|
+
};
|
|
15
|
+
export const createInputHandler = (deputy, chief, isGitIgnored, addIssue, externalRefs, options) => (input, workspace) => {
|
|
11
16
|
const { specifier, containingFilePath } = input;
|
|
12
17
|
if (!containingFilePath || IGNORED_RUNTIME_DEPENDENCIES.has(specifier))
|
|
13
18
|
return;
|
|
14
19
|
if (isBinary(input)) {
|
|
15
20
|
const binaryName = fromBinary(input);
|
|
16
21
|
const inputWorkspace = getWorkspaceFor(input, chief, workspace);
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
22
|
+
const dependencies = deputy.maybeAddReferencedBinary(inputWorkspace, binaryName);
|
|
23
|
+
if (dependencies) {
|
|
24
|
+
for (const dependency of dependencies) {
|
|
25
|
+
addExternalRef(externalRefs, containingFilePath, { specifier: dependency, identifier: binaryName });
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (dependencies || input.optional)
|
|
19
30
|
return;
|
|
20
31
|
addIssue({
|
|
21
32
|
type: 'binaries',
|
|
@@ -33,9 +44,12 @@ export const getReferencedInputsHandler = (deputy, chief, isGitIgnored, addIssue
|
|
|
33
44
|
const inputWorkspace = getWorkspaceFor(input, chief, workspace);
|
|
34
45
|
if (inputWorkspace) {
|
|
35
46
|
const isHandled = deputy.maybeAddReferencedExternalDependency(inputWorkspace, packageName);
|
|
47
|
+
if (!isWorkspace) {
|
|
48
|
+
addExternalRef(externalRefs, containingFilePath, { specifier: packageName, identifier: undefined });
|
|
49
|
+
}
|
|
36
50
|
if (isWorkspace || isDependency(input)) {
|
|
37
51
|
if (!isHandled) {
|
|
38
|
-
if (!input.optional && ((
|
|
52
|
+
if (!input.optional && ((options.isProduction && input.production) || !options.isProduction)) {
|
|
39
53
|
addIssue({
|
|
40
54
|
type: 'unlisted',
|
|
41
55
|
filePath: containingFilePath,
|
|
@@ -87,7 +101,7 @@ export const getReferencedInputsHandler = (deputy, chief, isGitIgnored, addIssue
|
|
|
87
101
|
});
|
|
88
102
|
}
|
|
89
103
|
else {
|
|
90
|
-
debugLog(workspace.name, `Unable to resolve ${toDebugString(input,
|
|
104
|
+
debugLog(workspace.name, `Unable to resolve ${toDebugString(input, options.cwd)}`);
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Options } from '../types/options.js';
|
|
2
2
|
import type { ParsedCLIArgs } from './cli-arguments.js';
|
|
3
3
|
interface CreateOptions extends Partial<Options> {
|
|
4
|
-
|
|
4
|
+
args?: ParsedCLIArgs;
|
|
5
5
|
}
|
|
6
6
|
export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
7
7
|
cacheLocation: string;
|
|
@@ -1327,6 +1327,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1327
1327
|
_files: import("../types/issues.js").IssueSeverity;
|
|
1328
1328
|
};
|
|
1329
1329
|
tags: import("../types/options.js").Tags;
|
|
1330
|
+
traceDependency: string | undefined;
|
|
1330
1331
|
traceExport: string | undefined;
|
|
1331
1332
|
traceFile: string | undefined;
|
|
1332
1333
|
tsConfigFile: string | undefined;
|
|
@@ -13,25 +13,25 @@ import { isAbsolute, join, normalize, toAbsolute, toPosix } from './path.js';
|
|
|
13
13
|
import { splitTags } from './tag.js';
|
|
14
14
|
const pcwd = process.cwd();
|
|
15
15
|
export const createOptions = async (options) => {
|
|
16
|
-
const {
|
|
17
|
-
const cwd = normalize(toPosix(toAbsolute(options.cwd ??
|
|
16
|
+
const { args = {} } = options;
|
|
17
|
+
const cwd = normalize(toPosix(toAbsolute(options.cwd ?? args.directory ?? pcwd, pcwd)));
|
|
18
18
|
const manifestPath = findFile(cwd, 'package.json');
|
|
19
19
|
const manifest = manifestPath && (await loadJSON(manifestPath));
|
|
20
20
|
if (!(manifestPath && manifest)) {
|
|
21
21
|
throw new ConfigurationError('Unable to find package.json');
|
|
22
22
|
}
|
|
23
23
|
let configFilePath;
|
|
24
|
-
for (const configPath of
|
|
24
|
+
for (const configPath of args.config ? [args.config] : KNIP_CONFIG_LOCATIONS) {
|
|
25
25
|
const resolvedConfigFilePath = isAbsolute(configPath) ? configPath : findFile(cwd, configPath);
|
|
26
26
|
if (resolvedConfigFilePath) {
|
|
27
27
|
configFilePath = resolvedConfigFilePath;
|
|
28
28
|
break;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
if (
|
|
32
|
-
throw new ConfigurationError(`Unable to find ${
|
|
31
|
+
if (args.config && !configFilePath && !manifest.knip) {
|
|
32
|
+
throw new ConfigurationError(`Unable to find ${args.config} or package.json#knip`);
|
|
33
33
|
}
|
|
34
|
-
const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath,
|
|
34
|
+
const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath, args) : {});
|
|
35
35
|
const parsedConfig = knipConfigurationSchema.parse(partitionCompilers(loadedConfig));
|
|
36
36
|
if (!configFilePath && manifest.knip)
|
|
37
37
|
configFilePath = manifestPath;
|
|
@@ -43,58 +43,58 @@ export const createOptions = async (options) => {
|
|
|
43
43
|
? manifest.workspaces
|
|
44
44
|
: (manifest.workspaces.packages ?? [])
|
|
45
45
|
: []);
|
|
46
|
-
const isStrict = options.isStrict ??
|
|
47
|
-
const isProduction = options.isProduction ??
|
|
48
|
-
const isDebug =
|
|
49
|
-
const isTrace = Boolean(
|
|
46
|
+
const isStrict = options.isStrict ?? args.strict ?? false;
|
|
47
|
+
const isProduction = options.isProduction ?? args.production ?? isStrict;
|
|
48
|
+
const isDebug = args.debug ?? false;
|
|
49
|
+
const isTrace = Boolean(args.trace ?? args['trace-file'] ?? args['trace-export'] ?? args['trace-dependency']);
|
|
50
50
|
const rules = { ...defaultRules, ...parsedConfig.rules };
|
|
51
51
|
const excludesFromRules = getKeysByValue(rules, 'off');
|
|
52
52
|
const includedIssueTypes = getIncludedIssueTypes({
|
|
53
53
|
isProduction,
|
|
54
54
|
exclude: [...excludesFromRules, ...(parsedConfig.exclude ?? [])],
|
|
55
55
|
include: parsedConfig.include ?? [],
|
|
56
|
-
excludeOverrides: options.excludedIssueTypes ??
|
|
56
|
+
excludeOverrides: options.excludedIssueTypes ?? args.exclude ?? [],
|
|
57
57
|
includeOverrides: [
|
|
58
|
-
...(options.includedIssueTypes ??
|
|
59
|
-
...(
|
|
60
|
-
...(
|
|
61
|
-
...(
|
|
58
|
+
...(options.includedIssueTypes ?? args.include ?? []),
|
|
59
|
+
...(args.dependencies ? shorthandDeps : []),
|
|
60
|
+
...(args.exports ? shorthandExports : []),
|
|
61
|
+
...(args.files ? shorthandFiles : []),
|
|
62
62
|
],
|
|
63
63
|
});
|
|
64
64
|
for (const [key, value] of Object.entries(includedIssueTypes)) {
|
|
65
65
|
if (!value)
|
|
66
66
|
rules[key] = 'off';
|
|
67
67
|
}
|
|
68
|
-
const fixTypes = options.fixTypes ??
|
|
69
|
-
const isFixFiles =
|
|
70
|
-
const isIncludeLibs =
|
|
68
|
+
const fixTypes = options.fixTypes ?? args['fix-type'] ?? [];
|
|
69
|
+
const isFixFiles = args['allow-remove-files'] && (fixTypes.length === 0 || fixTypes.includes('files'));
|
|
70
|
+
const isIncludeLibs = args['include-libs'] ?? options.isIncludeLibs ?? false;
|
|
71
71
|
const isReportClassMembers = includedIssueTypes.classMembers;
|
|
72
|
-
const tags = splitTags(
|
|
72
|
+
const tags = splitTags(args.tags ?? options.tags ?? parsedConfig.tags ?? args['experimental-tags'] ?? []);
|
|
73
73
|
return {
|
|
74
|
-
cacheLocation:
|
|
74
|
+
cacheLocation: args['cache-location'] ?? join(cwd, 'node_modules', '.cache', 'knip'),
|
|
75
75
|
catalog: await getCatalogContainer(cwd, manifest, manifestPath, pnpmWorkspacePath, pnpmWorkspace),
|
|
76
|
-
config:
|
|
76
|
+
config: args.config,
|
|
77
77
|
configFilePath,
|
|
78
78
|
cwd,
|
|
79
|
-
dependencies:
|
|
79
|
+
dependencies: args.dependencies ?? false,
|
|
80
80
|
experimentalTags: tags,
|
|
81
|
-
exports:
|
|
82
|
-
files:
|
|
81
|
+
exports: args.exports ?? false,
|
|
82
|
+
files: args.files ?? false,
|
|
83
83
|
fixTypes,
|
|
84
|
-
gitignore:
|
|
84
|
+
gitignore: args['no-gitignore'] ? false : (options.gitignore ?? true),
|
|
85
85
|
includedIssueTypes,
|
|
86
|
-
isCache:
|
|
86
|
+
isCache: args.cache ?? false,
|
|
87
87
|
isDebug,
|
|
88
|
-
isDisableConfigHints:
|
|
89
|
-
isFix:
|
|
88
|
+
isDisableConfigHints: args['no-config-hints'] || isProduction || Boolean(args.workspace),
|
|
89
|
+
isFix: args.fix ?? options.isFix ?? isFixFiles ?? fixTypes.length > 0,
|
|
90
90
|
isFixCatalog: fixTypes.length === 0 || fixTypes.includes('catalog'),
|
|
91
91
|
isFixDependencies: fixTypes.length === 0 || fixTypes.includes('dependencies'),
|
|
92
92
|
isFixFiles,
|
|
93
93
|
isFixUnusedExports: fixTypes.length === 0 || fixTypes.includes('exports'),
|
|
94
94
|
isFixUnusedTypes: fixTypes.length === 0 || fixTypes.includes('types'),
|
|
95
|
-
isFormat:
|
|
96
|
-
isIncludeEntryExports:
|
|
97
|
-
isIsolateWorkspaces: options.isIsolateWorkspaces ??
|
|
95
|
+
isFormat: args.format ?? options.isFormat ?? false,
|
|
96
|
+
isIncludeEntryExports: args['include-entry-exports'] ?? options.isIncludeEntryExports ?? false,
|
|
97
|
+
isIsolateWorkspaces: options.isIsolateWorkspaces ?? args['isolate-workspaces'] ?? false,
|
|
98
98
|
isProduction,
|
|
99
99
|
isReportClassMembers,
|
|
100
100
|
isReportDependencies: includedIssueTypes.dependencies ||
|
|
@@ -106,24 +106,25 @@ export const createOptions = async (options) => {
|
|
|
106
106
|
isSession: options.isSession ?? false,
|
|
107
107
|
isShowProgress: !isDebug &&
|
|
108
108
|
!isTrace &&
|
|
109
|
-
|
|
109
|
+
args['no-progress'] !== true &&
|
|
110
110
|
options.isShowProgress !== false &&
|
|
111
111
|
process.stdout.isTTY &&
|
|
112
112
|
typeof process.stdout.cursorTo === 'function',
|
|
113
113
|
isSkipLibs: !(isIncludeLibs || includedIssueTypes.classMembers),
|
|
114
114
|
isStrict,
|
|
115
115
|
isTrace,
|
|
116
|
-
isTreatConfigHintsAsErrors:
|
|
117
|
-
isUseTscFiles: options.isUseTscFiles ??
|
|
118
|
-
isWatch:
|
|
119
|
-
maxShowIssues:
|
|
116
|
+
isTreatConfigHintsAsErrors: args['treat-config-hints-as-errors'] ?? parsedConfig.treatConfigHintsAsErrors ?? false,
|
|
117
|
+
isUseTscFiles: options.isUseTscFiles ?? args['use-tsconfig-files'] ?? (options.isSession && !configFilePath),
|
|
118
|
+
isWatch: args.watch ?? options.isWatch ?? false,
|
|
119
|
+
maxShowIssues: args['max-show-issues'] ? Number(args['max-show-issues']) : undefined,
|
|
120
120
|
parsedConfig,
|
|
121
121
|
rules,
|
|
122
122
|
tags,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
traceDependency: args['trace-dependency'],
|
|
124
|
+
traceExport: args['trace-export'],
|
|
125
|
+
traceFile: args['trace-file'] ? toAbsolute(args['trace-file'], cwd) : undefined,
|
|
126
|
+
tsConfigFile: args.tsConfig,
|
|
127
|
+
workspace: options.workspace ?? args.workspace,
|
|
127
128
|
workspaces,
|
|
128
129
|
};
|
|
129
130
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FileNode, IdToFileMap, IdToNsToFileMap, ImportMap, ImportMaps, ModuleGraph } from '../types/module-graph.js';
|
|
2
2
|
export declare const updateImportMap: (file: FileNode, importMap: ImportMap, graph: ModuleGraph) => void;
|
|
3
|
+
export declare const createFileNode: () => FileNode;
|
|
3
4
|
export declare const createImports: () => ImportMaps;
|
|
4
5
|
export declare const addValue: (map: IdToFileMap, id: string, value: string) => void;
|
|
5
6
|
export declare const addNsValue: (map: IdToNsToFileMap, id: string, ns: string, value: string) => void;
|
|
@@ -28,10 +28,11 @@ export const updateImportMap = (file, importMap, graph) => {
|
|
|
28
28
|
graph.set(importedFilePath, importedFile);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
const createFileNode = () => ({
|
|
31
|
+
export const createFileNode = () => ({
|
|
32
32
|
imports: {
|
|
33
33
|
internal: new Map(),
|
|
34
34
|
external: new Set(),
|
|
35
|
+
externalRefs: new Set(),
|
|
35
36
|
unresolved: new Set(),
|
|
36
37
|
programFiles: new Set(),
|
|
37
38
|
entryFiles: new Set(),
|
package/dist/util/trace.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const formatTrace: (node:
|
|
1
|
+
import type { ExportsTreeNode } from '../graph-explorer/operations/build-exports-tree.js';
|
|
2
|
+
export declare const formatTrace: (node: ExportsTreeNode, toRelative: (path: string) => string, isReferenced: boolean) => string;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.76.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.76.0';
|
package/package.json
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ConfigurationChief, Workspace } from '../ConfigurationChief.js';
|
|
2
|
-
import type { DependencyDeputy } from '../DependencyDeputy.js';
|
|
3
|
-
import type { Issue } from '../types/issues.js';
|
|
4
|
-
import { type Input } from './input.js';
|
|
5
|
-
export declare const getReferencedInputsHandler: (deputy: DependencyDeputy, chief: ConfigurationChief, isGitIgnored: (s: string) => boolean, addIssue: (issue: Issue) => void) => (input: Input, workspace: Workspace) => string | undefined;
|