knip 5.62.0 → 5.63.1
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 -24
- package/dist/CacheConsultant.d.ts +3 -9
- package/dist/CacheConsultant.js +5 -5
- package/dist/ConfigurationChief.d.ts +588 -38
- package/dist/ConfigurationChief.js +43 -124
- package/dist/ConsoleStreamer.d.ts +2 -3
- package/dist/ConsoleStreamer.js +2 -2
- package/dist/DependencyDeputy.d.ts +2 -6
- package/dist/IssueCollector.d.ts +4 -12
- package/dist/IssueCollector.js +10 -10
- package/dist/IssueFixer.d.ts +3 -14
- package/dist/IssueFixer.js +11 -21
- package/dist/PrincipalFactory.d.ts +3 -2
- package/dist/PrincipalFactory.js +11 -11
- package/dist/ProjectPrincipal.d.ts +5 -3
- package/dist/ProjectPrincipal.js +17 -11
- package/dist/WorkspaceWorker.d.ts +4 -9
- package/dist/WorkspaceWorker.js +8 -12
- package/dist/binaries/bash-parser.js +1 -1
- package/dist/binaries/fallback.js +4 -2
- package/dist/binaries/package-manager/pnpm.js +6 -1
- package/dist/cli.js +43 -60
- package/dist/compilers/index.d.ts +34 -4
- package/dist/graph/analyze.d.ts +3 -8
- package/dist/graph/analyze.js +24 -27
- package/dist/graph/build.d.ts +3 -17
- package/dist/graph/build.js +60 -47
- package/dist/index.d.ts +3 -6
- package/dist/index.js +23 -62
- package/dist/plugins/astro/index.d.ts +1 -0
- package/dist/plugins/astro/index.js +4 -0
- package/dist/plugins/index.d.ts +24 -1
- package/dist/plugins/index.js +6 -0
- package/dist/plugins/lefthook/index.js +2 -0
- package/dist/plugins/node-modules-inspector/index.d.ts +12 -0
- package/dist/plugins/node-modules-inspector/index.js +17 -0
- package/dist/plugins/nuxt/index.js +4 -3
- package/dist/plugins/nuxt/types.d.ts +3 -2
- package/dist/plugins/playwright/index.js +8 -1
- package/dist/plugins/playwright/types.d.ts +20 -14
- package/dist/plugins/pnpm/index.d.ts +7 -0
- package/dist/plugins/pnpm/index.js +8 -0
- package/dist/plugins/preconstruct/index.js +2 -1
- package/dist/plugins/react-router/index.js +18 -8
- package/dist/plugins/rsbuild/index.js +28 -2
- package/dist/plugins/rsbuild/types.d.ts +11 -0
- package/dist/plugins/rslib/index.d.ts +10 -0
- package/dist/plugins/rslib/index.js +15 -0
- package/dist/plugins/rslib/types.d.ts +1 -0
- package/dist/plugins/rspack/index.js +1 -1
- package/dist/plugins/typescript/index.d.ts +1 -1
- package/dist/plugins.js +3 -2
- package/dist/reporters/codeclimate.d.ts +1 -1
- package/dist/reporters/codeclimate.js +10 -10
- package/dist/reporters/codeowners.d.ts +1 -1
- package/dist/reporters/codeowners.js +5 -5
- package/dist/reporters/compact.d.ts +1 -1
- package/dist/reporters/compact.js +7 -7
- package/dist/reporters/disclosure.d.ts +1 -1
- package/dist/reporters/disclosure.js +2 -2
- package/dist/reporters/index.d.ts +6 -6
- package/dist/reporters/json.d.ts +1 -1
- package/dist/reporters/json.js +3 -3
- package/dist/reporters/markdown.d.ts +1 -1
- package/dist/reporters/markdown.js +4 -4
- package/dist/reporters/symbols.js +4 -2
- package/dist/reporters/util/configuration-hints.d.ts +1 -1
- package/dist/reporters/util/configuration-hints.js +58 -23
- package/dist/reporters/util/util.d.ts +2 -4
- package/dist/reporters/util/util.js +6 -6
- package/dist/reporters/watch.d.ts +3 -4
- package/dist/reporters/watch.js +5 -5
- package/dist/schema/configuration.d.ts +176 -8
- package/dist/schema/plugins.d.ts +69 -0
- package/dist/schema/plugins.js +3 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +3 -0
- package/dist/types/config.d.ts +4 -10
- package/dist/types/entries.d.ts +3 -0
- package/dist/types/entries.js +1 -0
- package/dist/types/issues.d.ts +4 -3
- package/dist/types/{cli.d.ts → options.d.ts} +2 -2
- package/dist/types/options.js +1 -0
- package/dist/types/package-json.d.ts +5 -0
- package/dist/types/project.d.ts +1 -7
- package/dist/types/tsconfig-json.d.ts +14 -0
- package/dist/types/tsconfig-json.js +1 -0
- package/dist/typescript/ast-helpers.js +1 -1
- package/dist/typescript/get-imports-and-exports.d.ts +2 -2
- package/dist/typescript/get-imports-and-exports.js +9 -10
- package/dist/util/Performance.js +16 -6
- package/dist/util/cli-arguments.d.ts +1 -2
- package/dist/util/cli-arguments.js +3 -13
- package/dist/util/create-options.d.ts +1219 -0
- package/dist/util/create-options.js +112 -0
- package/dist/util/debug.js +3 -4
- package/dist/util/errors.d.ts +1 -1
- package/dist/util/file-entry-cache.js +3 -3
- package/dist/util/fs.d.ts +1 -1
- package/dist/util/get-included-issue-types.d.ts +9 -13
- package/dist/util/get-included-issue-types.js +10 -16
- package/dist/util/get-referenced-inputs.js +1 -1
- package/dist/util/glob-core.d.ts +1 -1
- package/dist/util/glob-core.js +8 -7
- package/dist/util/glob.d.ts +1 -0
- package/dist/util/glob.js +1 -1
- package/dist/util/input.d.ts +1 -1
- package/dist/util/input.js +1 -1
- package/dist/util/is-identifier-referenced.d.ts +1 -1
- package/dist/util/is-identifier-referenced.js +19 -19
- package/dist/util/load-config.d.ts +1 -0
- package/dist/util/load-config.js +24 -0
- package/dist/util/package-json.d.ts +2 -1
- package/dist/util/package-json.js +24 -12
- package/dist/util/parse-and-convert-gitignores.js +2 -0
- package/dist/util/path.d.ts +4 -4
- package/dist/util/path.js +5 -7
- package/dist/util/reporter.js +3 -3
- package/dist/util/require.js +1 -2
- package/dist/util/table.js +1 -3
- package/dist/util/tag.d.ts +1 -1
- package/dist/util/to-source-path.d.ts +1 -1
- package/dist/util/to-source-path.js +5 -5
- package/dist/util/trace.d.ts +6 -6
- package/dist/util/trace.js +18 -22
- package/dist/util/watch.d.ts +2 -5
- package/dist/util/watch.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -15
- package/schema.json +12 -0
- package/dist/util/unwrap-function.d.ts +0 -1
- package/dist/util/unwrap-function.js +0 -13
- /package/dist/{types/cli.js → plugins/rslib/types.js} +0 -0
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import picomatch from 'picomatch';
|
|
3
|
-
import {
|
|
4
|
-
import { DEFAULT_EXTENSIONS, KNIP_CONFIG_LOCATIONS, ROOT_WORKSPACE_NAME } from './constants.js';
|
|
5
|
-
import { knipConfigurationSchema } from './schema/configuration.js';
|
|
3
|
+
import { DEFAULT_EXTENSIONS, ROOT_WORKSPACE_NAME } from './constants.js';
|
|
6
4
|
import { pluginNames } from './types/PluginNames.js';
|
|
7
5
|
import { arrayify, compact, partition } from './util/array.js';
|
|
8
|
-
import parsedArgValues from './util/cli-arguments.js';
|
|
9
6
|
import { createWorkspaceGraph } from './util/create-workspace-graph.js';
|
|
10
7
|
import { ConfigurationError } from './util/errors.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { _dirGlob } from './util/glob.js';
|
|
8
|
+
import { isDirectory, isFile } from './util/fs.js';
|
|
9
|
+
import { _dirGlob, removeProductionSuffix } from './util/glob.js';
|
|
14
10
|
import { graphSequencer } from './util/graph-sequencer.js';
|
|
15
|
-
import { defaultRules } from './util/issue-initializers.js';
|
|
16
|
-
import { _load } from './util/loader.js';
|
|
17
11
|
import mapWorkspaces from './util/map-workspaces.js';
|
|
18
|
-
import {
|
|
19
|
-
import { isAbsolute, join, relative } from './util/path.js';
|
|
12
|
+
import { join, relative } from './util/path.js';
|
|
20
13
|
import { normalizePluginConfig } from './util/plugin.js';
|
|
21
14
|
import { toRegexOrString } from './util/regex.js';
|
|
22
15
|
import { ELLIPSIS } from './util/string.js';
|
|
23
|
-
import { splitTags } from './util/tag.js';
|
|
24
|
-
import { unwrapFunction } from './util/unwrap-function.js';
|
|
25
16
|
import { byPathDepth } from './util/workspace.js';
|
|
26
|
-
const { config: rawConfigArg } = parsedArgValues;
|
|
27
17
|
const defaultBaseFilenamePattern = '{index,cli,main}';
|
|
28
18
|
export const isDefaultPattern = (type, id) => {
|
|
29
19
|
if (type === 'project')
|
|
@@ -40,31 +30,27 @@ const getDefaultWorkspaceConfig = (extensions = []) => {
|
|
|
40
30
|
};
|
|
41
31
|
const isPluginName = (name) => pluginNames.includes(name);
|
|
42
32
|
const defaultConfig = {
|
|
43
|
-
rules: defaultRules,
|
|
44
|
-
include: [],
|
|
45
|
-
exclude: [],
|
|
46
33
|
ignore: [],
|
|
47
34
|
ignoreBinaries: [],
|
|
48
35
|
ignoreDependencies: [],
|
|
49
36
|
ignoreMembers: [],
|
|
50
|
-
|
|
37
|
+
ignoreUnresolved: [],
|
|
51
38
|
ignoreWorkspaces: [],
|
|
39
|
+
ignoreExportsUsedInFile: false,
|
|
52
40
|
isIncludeEntryExports: false,
|
|
53
|
-
isTreatConfigHintsAsErrors: false,
|
|
54
41
|
syncCompilers: new Map(),
|
|
55
42
|
asyncCompilers: new Map(),
|
|
56
43
|
rootPluginConfigs: {},
|
|
57
|
-
tags: [],
|
|
58
44
|
};
|
|
59
45
|
export class ConfigurationChief {
|
|
60
46
|
cwd;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
rawConfig;
|
|
48
|
+
isProduction;
|
|
49
|
+
isStrict;
|
|
50
|
+
isIncludeEntryExports;
|
|
64
51
|
config;
|
|
65
52
|
workspace;
|
|
66
|
-
|
|
67
|
-
manifest;
|
|
53
|
+
workspaces;
|
|
68
54
|
ignoredWorkspacePatterns = [];
|
|
69
55
|
workspacePackages = new Map();
|
|
70
56
|
workspacesByPkgName = new Map();
|
|
@@ -75,56 +61,26 @@ export class ConfigurationChief {
|
|
|
75
61
|
availableWorkspaceDirs = [];
|
|
76
62
|
workspaceGraph = new Map();
|
|
77
63
|
includedWorkspaces = [];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
86
|
-
this.config =
|
|
87
|
-
this.workspace = workspace;
|
|
88
|
-
}
|
|
89
|
-
async init() {
|
|
90
|
-
const manifestPath = findFile(this.cwd, 'package.json');
|
|
91
|
-
const manifest = manifestPath && (await loadJSON(manifestPath));
|
|
92
|
-
if (!(manifestPath && manifest)) {
|
|
93
|
-
throw new ConfigurationError('Unable to find package.json');
|
|
94
|
-
}
|
|
95
|
-
this.manifestPath = manifestPath;
|
|
96
|
-
this.manifest = manifest;
|
|
97
|
-
const pnpmWorkspacesPath = findFile(this.cwd, 'pnpm-workspace.yaml');
|
|
98
|
-
const pnpmWorkspaces = pnpmWorkspacesPath && (await _load(pnpmWorkspacesPath));
|
|
99
|
-
if (this.manifest && pnpmWorkspaces) {
|
|
100
|
-
this.manifest.workspaces = pnpmWorkspaces;
|
|
101
|
-
}
|
|
102
|
-
for (const configPath of rawConfigArg ? [rawConfigArg] : KNIP_CONFIG_LOCATIONS) {
|
|
103
|
-
this.resolvedConfigFilePath = isAbsolute(configPath) ? configPath : findFile(this.cwd, configPath);
|
|
104
|
-
if (this.resolvedConfigFilePath)
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
if (rawConfigArg && !this.resolvedConfigFilePath && !manifest.knip) {
|
|
108
|
-
throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`);
|
|
109
|
-
}
|
|
110
|
-
this.rawConfig = this.resolvedConfigFilePath
|
|
111
|
-
? await this.loadResolvedConfigurationFile(this.resolvedConfigFilePath)
|
|
112
|
-
: manifest.knip;
|
|
113
|
-
this.parsedConfig = this.rawConfig ? knipConfigurationSchema.parse(partitionCompilers(this.rawConfig)) : {};
|
|
114
|
-
this.config = this.normalize(this.parsedConfig);
|
|
115
|
-
await this.setWorkspaces();
|
|
64
|
+
constructor(options) {
|
|
65
|
+
this.cwd = options.cwd;
|
|
66
|
+
this.isProduction = options.isProduction;
|
|
67
|
+
this.isStrict = options.isStrict;
|
|
68
|
+
this.isIncludeEntryExports = options.isIncludeEntryExports;
|
|
69
|
+
this.workspace = options.workspace;
|
|
70
|
+
this.workspaces = options.workspaces;
|
|
71
|
+
this.rawConfig = options.parsedConfig;
|
|
72
|
+
this.config = this.normalize(options.parsedConfig ?? {});
|
|
116
73
|
}
|
|
117
74
|
getConfigurationHints() {
|
|
118
75
|
const hints = new Set();
|
|
119
|
-
|
|
120
|
-
if (config) {
|
|
76
|
+
if (this.rawConfig) {
|
|
121
77
|
if (this.workspacePackages.size > 1) {
|
|
122
|
-
const entry = arrayify(
|
|
78
|
+
const entry = arrayify(this.rawConfig.entry);
|
|
123
79
|
if (entry.length > 0) {
|
|
124
80
|
const identifier = `[${entry[0]}${entry.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
|
|
125
81
|
hints.add({ type: 'entry-top-level', identifier });
|
|
126
82
|
}
|
|
127
|
-
const project = arrayify(
|
|
83
|
+
const project = arrayify(this.rawConfig.project);
|
|
128
84
|
if (project.length > 0) {
|
|
129
85
|
const identifier = `[${project[0]}${project.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
|
|
130
86
|
hints.add({ type: 'project-top-level', identifier });
|
|
@@ -133,35 +89,15 @@ export class ConfigurationChief {
|
|
|
133
89
|
}
|
|
134
90
|
return hints;
|
|
135
91
|
}
|
|
136
|
-
async loadResolvedConfigurationFile(configPath) {
|
|
137
|
-
const loadedValue = await _load(configPath);
|
|
138
|
-
try {
|
|
139
|
-
return await unwrapFunction(loadedValue);
|
|
140
|
-
}
|
|
141
|
-
catch (_error) {
|
|
142
|
-
throw new ConfigurationError(`Error running the function from ${configPath}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
getRules() {
|
|
146
|
-
return this.config.rules;
|
|
147
|
-
}
|
|
148
|
-
getFilters() {
|
|
149
|
-
if (this.workspaceGraph && this.workspace)
|
|
150
|
-
return { dir: join(this.cwd, this.workspace) };
|
|
151
|
-
return {};
|
|
152
|
-
}
|
|
153
92
|
normalize(rawConfig) {
|
|
154
|
-
const rules = { ...defaultRules, ...rawConfig.rules };
|
|
155
|
-
const include = rawConfig.include ?? defaultConfig.include;
|
|
156
|
-
const exclude = rawConfig.exclude ?? defaultConfig.exclude;
|
|
157
93
|
const ignore = arrayify(rawConfig.ignore ?? defaultConfig.ignore);
|
|
158
94
|
const ignoreBinaries = rawConfig.ignoreBinaries ?? [];
|
|
159
95
|
const ignoreDependencies = rawConfig.ignoreDependencies ?? [];
|
|
160
96
|
const ignoreMembers = rawConfig.ignoreMembers ?? [];
|
|
97
|
+
const ignoreUnresolved = rawConfig.ignoreUnresolved ?? [];
|
|
161
98
|
const ignoreExportsUsedInFile = rawConfig.ignoreExportsUsedInFile ?? false;
|
|
162
99
|
const ignoreWorkspaces = rawConfig.ignoreWorkspaces ?? defaultConfig.ignoreWorkspaces;
|
|
163
100
|
const isIncludeEntryExports = rawConfig.includeEntryExports ?? this.isIncludeEntryExports;
|
|
164
|
-
const isTreatConfigHintsAsErrors = rawConfig.treatConfigHintsAsErrors ?? defaultConfig.isTreatConfigHintsAsErrors;
|
|
165
101
|
const { syncCompilers, asyncCompilers } = rawConfig;
|
|
166
102
|
const rootPluginConfigs = {};
|
|
167
103
|
for (const [pluginName, pluginConfig] of Object.entries(rawConfig)) {
|
|
@@ -170,24 +106,20 @@ export class ConfigurationChief {
|
|
|
170
106
|
}
|
|
171
107
|
}
|
|
172
108
|
return {
|
|
173
|
-
rules,
|
|
174
|
-
include,
|
|
175
|
-
exclude,
|
|
176
109
|
ignore,
|
|
177
110
|
ignoreBinaries,
|
|
178
111
|
ignoreDependencies,
|
|
179
112
|
ignoreMembers,
|
|
113
|
+
ignoreUnresolved,
|
|
180
114
|
ignoreExportsUsedInFile,
|
|
181
115
|
ignoreWorkspaces,
|
|
182
116
|
isIncludeEntryExports,
|
|
183
117
|
syncCompilers: new Map(Object.entries(syncCompilers ?? {})),
|
|
184
118
|
asyncCompilers: new Map(Object.entries(asyncCompilers ?? {})),
|
|
185
119
|
rootPluginConfigs,
|
|
186
|
-
tags: rawConfig.tags ?? [],
|
|
187
|
-
isTreatConfigHintsAsErrors,
|
|
188
120
|
};
|
|
189
121
|
}
|
|
190
|
-
async
|
|
122
|
+
async getWorkspaces() {
|
|
191
123
|
this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
|
|
192
124
|
this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
|
|
193
125
|
const workspaceNames = compact([...this.getListedWorkspaces(), ...this.additionalWorkspaceNames]);
|
|
@@ -205,26 +137,30 @@ export class ConfigurationChief {
|
|
|
205
137
|
this.workspacesByPkgName.set(workspace.pkgName, workspace);
|
|
206
138
|
this.workspacesByName.set(workspace.name, workspace);
|
|
207
139
|
}
|
|
140
|
+
const sorted = graphSequencer(this.workspaceGraph, this.includedWorkspaces.map(workspace => workspace.dir));
|
|
141
|
+
const [root, rest] = partition(sorted.chunks.flat(), dir => dir === this.cwd);
|
|
142
|
+
return [...root, ...rest.reverse()].map(dir => this.includedWorkspaces.find(w => w.dir === dir));
|
|
208
143
|
}
|
|
209
144
|
getListedWorkspaces() {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
145
|
+
return this.workspaces.map(pattern => pattern.replace(/(?<=!?)\.\//, ''));
|
|
146
|
+
}
|
|
147
|
+
getIgnoredWorkspaces() {
|
|
148
|
+
const ignoreWorkspaces = this.config.ignoreWorkspaces;
|
|
149
|
+
if (this.isProduction)
|
|
150
|
+
return ignoreWorkspaces.map(removeProductionSuffix);
|
|
151
|
+
return ignoreWorkspaces.filter(pattern => !pattern.endsWith('!'));
|
|
216
152
|
}
|
|
217
153
|
getIgnoredWorkspacePatterns() {
|
|
218
154
|
const ignoredWorkspacesManifest = this.getListedWorkspaces()
|
|
219
155
|
.filter(name => name.startsWith('!'))
|
|
220
156
|
.map(name => name.replace(/^!/, ''));
|
|
221
|
-
return [...ignoredWorkspacesManifest, ...this.
|
|
157
|
+
return [...ignoredWorkspacesManifest, ...this.getIgnoredWorkspaces()];
|
|
222
158
|
}
|
|
223
159
|
getConfiguredWorkspaceKeys() {
|
|
224
160
|
const initialWorkspaces = this.rawConfig?.workspaces
|
|
225
161
|
? Object.keys(this.rawConfig.workspaces)
|
|
226
162
|
: [ROOT_WORKSPACE_NAME];
|
|
227
|
-
const ignoreWorkspaces = this.
|
|
163
|
+
const ignoreWorkspaces = this.getIgnoredWorkspaces();
|
|
228
164
|
return initialWorkspaces.filter(workspaceName => !ignoreWorkspaces.includes(workspaceName));
|
|
229
165
|
}
|
|
230
166
|
async getAdditionalWorkspaceNames() {
|
|
@@ -301,7 +237,7 @@ export class ConfigurationChief {
|
|
|
301
237
|
const manifestPath = pkg?.manifestPath ?? join(dir, 'package.json');
|
|
302
238
|
const manifestStr = pkg?.manifestStr ?? '';
|
|
303
239
|
const workspaceConfig = this.getWorkspaceConfig(name);
|
|
304
|
-
const ignoreMembers =
|
|
240
|
+
const ignoreMembers = workspaceConfig.ignoreMembers?.map(toRegexOrString) ?? [];
|
|
305
241
|
return {
|
|
306
242
|
name,
|
|
307
243
|
pkgName,
|
|
@@ -317,11 +253,6 @@ export class ConfigurationChief {
|
|
|
317
253
|
getManifestForWorkspace(name) {
|
|
318
254
|
return this.workspacePackages.get(name)?.manifest;
|
|
319
255
|
}
|
|
320
|
-
getWorkspaces() {
|
|
321
|
-
const sorted = graphSequencer(this.workspaceGraph, this.includedWorkspaces.map(workspace => workspace.dir));
|
|
322
|
-
const [root, rest] = partition(sorted.chunks.flat(), dir => dir === this.cwd);
|
|
323
|
-
return [...root, ...rest.reverse()].map(dir => this.includedWorkspaces.find(w => w.dir === dir));
|
|
324
|
-
}
|
|
325
256
|
getDescendentWorkspaces(name) {
|
|
326
257
|
return this.availableWorkspaceNames
|
|
327
258
|
.filter(workspaceName => workspaceName !== name)
|
|
@@ -358,9 +289,9 @@ export class ConfigurationChief {
|
|
|
358
289
|
}
|
|
359
290
|
getIgnores(workspaceName) {
|
|
360
291
|
const workspaceConfig = this.getWorkspaceConfig(workspaceName);
|
|
361
|
-
const ignoreBinaries =
|
|
362
|
-
const ignoreDependencies =
|
|
363
|
-
const ignoreUnresolved =
|
|
292
|
+
const ignoreBinaries = workspaceConfig.ignoreBinaries ?? [];
|
|
293
|
+
const ignoreDependencies = workspaceConfig.ignoreDependencies ?? [];
|
|
294
|
+
const ignoreUnresolved = workspaceConfig.ignoreUnresolved ?? [];
|
|
364
295
|
if (workspaceName === ROOT_WORKSPACE_NAME) {
|
|
365
296
|
const { ignoreBinaries: rootIgnoreBinaries, ignoreDependencies: rootIgnoreDependencies, ignoreUnresolved: rootIgnoreUnresolved, } = this.rawConfig ?? {};
|
|
366
297
|
return {
|
|
@@ -391,21 +322,12 @@ export class ConfigurationChief {
|
|
|
391
322
|
}
|
|
392
323
|
return { entry, project, paths, ignore, isIncludeEntryExports, ...plugins };
|
|
393
324
|
}
|
|
394
|
-
getIncludedIssueTypes(cliArgs) {
|
|
395
|
-
const excludesFromRules = getKeysByValue(this.config.rules, 'off');
|
|
396
|
-
const config = {
|
|
397
|
-
include: this.config.include ?? [],
|
|
398
|
-
exclude: [...excludesFromRules, ...this.config.exclude],
|
|
399
|
-
isProduction: this.isProduction,
|
|
400
|
-
};
|
|
401
|
-
return getIncludedIssueTypes(cliArgs, config);
|
|
402
|
-
}
|
|
403
325
|
findWorkspaceByFilePath(filePath) {
|
|
404
326
|
const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(`${workspaceDir}/`));
|
|
405
327
|
return this.includedWorkspaces.find(workspace => workspace.dir === workspaceDir);
|
|
406
328
|
}
|
|
407
329
|
getUnusedIgnoredWorkspaces() {
|
|
408
|
-
const ignoredWorkspaceNames = this.config.ignoreWorkspaces;
|
|
330
|
+
const ignoredWorkspaceNames = this.config.ignoreWorkspaces.map(removeProductionSuffix);
|
|
409
331
|
const workspaceNames = [...this.workspacePackages.keys(), ...this.additionalWorkspaceNames];
|
|
410
332
|
return ignoredWorkspaceNames
|
|
411
333
|
.filter(ignoredWorkspaceName => !workspaceNames.some(name => picomatch.isMatch(name, ignoredWorkspaceName)))
|
|
@@ -414,7 +336,4 @@ export class ConfigurationChief {
|
|
|
414
336
|
return !isDirectory(dir) || isFile(join(dir, 'package.json'));
|
|
415
337
|
});
|
|
416
338
|
}
|
|
417
|
-
getTags() {
|
|
418
|
-
return splitTags(this.config.tags);
|
|
419
|
-
}
|
|
420
339
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import type { MainOptions } from './util/create-options.js';
|
|
1
2
|
export declare class ConsoleStreamer {
|
|
2
3
|
isEnabled: boolean;
|
|
3
4
|
private lines;
|
|
4
|
-
constructor(
|
|
5
|
-
isEnabled?: boolean | undefined;
|
|
6
|
-
});
|
|
5
|
+
constructor(options: MainOptions);
|
|
7
6
|
private clearLines;
|
|
8
7
|
private resetLines;
|
|
9
8
|
private update;
|
package/dist/ConsoleStreamer.js
CHANGED
|
@@ -2,10 +2,7 @@ import type { Workspace } from './ConfigurationChief.js';
|
|
|
2
2
|
import type { ConfigurationHints, Counters, Issue, Issues, SymbolIssueType } from './types/issues.js';
|
|
3
3
|
import type { PackageJson } from './types/package-json.js';
|
|
4
4
|
import type { DependencyArray, DependencySet, HostDependencies, InstalledBinaries, WorkspaceManifests } from './types/workspace.js';
|
|
5
|
-
type
|
|
6
|
-
isProduction: boolean;
|
|
7
|
-
isStrict: boolean;
|
|
8
|
-
};
|
|
5
|
+
import type { MainOptions } from './util/create-options.js';
|
|
9
6
|
export declare class DependencyDeputy {
|
|
10
7
|
isProduction: boolean;
|
|
11
8
|
isStrict: boolean;
|
|
@@ -15,7 +12,7 @@ export declare class DependencyDeputy {
|
|
|
15
12
|
hostDependencies: Map<string, HostDependencies>;
|
|
16
13
|
installedBinaries: Map<string, InstalledBinaries>;
|
|
17
14
|
hasTypesIncluded: Map<string, Set<string>>;
|
|
18
|
-
constructor({ isProduction, isStrict }:
|
|
15
|
+
constructor({ isProduction, isStrict }: MainOptions);
|
|
19
16
|
addWorkspace({ name, cwd, dir, manifestPath, manifestStr, manifest, ignoreDependencies: id, ignoreBinaries: ib, ignoreUnresolved: iu, }: {
|
|
20
17
|
name: string;
|
|
21
18
|
cwd: string;
|
|
@@ -77,4 +74,3 @@ export declare class DependencyDeputy {
|
|
|
77
74
|
addIgnoredDependencies(workspaceName: string, identifier: string): void;
|
|
78
75
|
addIgnoredBinaries(workspaceName: string, identifier: string): void;
|
|
79
76
|
}
|
|
80
|
-
export {};
|
package/dist/IssueCollector.d.ts
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import type { ConfigurationHint, Issue,
|
|
2
|
-
type
|
|
3
|
-
dir: string;
|
|
4
|
-
}>;
|
|
5
|
-
type IssueCollectorOptions = {
|
|
6
|
-
cwd: string;
|
|
7
|
-
rules: Rules;
|
|
8
|
-
filters: Filters;
|
|
9
|
-
};
|
|
1
|
+
import type { ConfigurationHint, Issue, TagHint } from './types/issues.js';
|
|
2
|
+
import type { MainOptions } from './util/create-options.js';
|
|
10
3
|
export declare class IssueCollector {
|
|
11
4
|
private cwd;
|
|
12
5
|
private rules;
|
|
13
|
-
private
|
|
6
|
+
private filter;
|
|
14
7
|
private issues;
|
|
15
8
|
private counters;
|
|
16
9
|
private referencedFiles;
|
|
@@ -18,7 +11,7 @@ export declare class IssueCollector {
|
|
|
18
11
|
private tagHints;
|
|
19
12
|
private ignorePatterns;
|
|
20
13
|
private isMatch;
|
|
21
|
-
constructor(
|
|
14
|
+
constructor(options: MainOptions);
|
|
22
15
|
addIgnorePatterns(patterns: string[]): void;
|
|
23
16
|
addFileCounts({ processed, unused }: {
|
|
24
17
|
processed: number;
|
|
@@ -36,4 +29,3 @@ export declare class IssueCollector {
|
|
|
36
29
|
configurationHints: Set<ConfigurationHint>;
|
|
37
30
|
};
|
|
38
31
|
}
|
|
39
|
-
export {};
|
package/dist/IssueCollector.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import picomatch from 'picomatch';
|
|
2
2
|
import { timerify } from './util/Performance.js';
|
|
3
3
|
import { initCounters, initIssues } from './util/issue-initializers.js';
|
|
4
|
-
import { relative } from './util/path.js';
|
|
4
|
+
import { join, relative } from './util/path.js';
|
|
5
5
|
const hasConfigurationHint = (hints, hint) => Array.from(hints).some(item => item.identifier === hint.identifier && item.type === hint.type && item.workspaceName === hint.workspaceName);
|
|
6
6
|
const isMatch = timerify(picomatch.isMatch, 'isMatch');
|
|
7
7
|
export class IssueCollector {
|
|
8
8
|
cwd;
|
|
9
9
|
rules;
|
|
10
|
-
|
|
10
|
+
filter;
|
|
11
11
|
issues = initIssues();
|
|
12
12
|
counters = initCounters();
|
|
13
13
|
referencedFiles = new Set();
|
|
@@ -15,10 +15,10 @@ export class IssueCollector {
|
|
|
15
15
|
tagHints = new Set();
|
|
16
16
|
ignorePatterns = new Set();
|
|
17
17
|
isMatch;
|
|
18
|
-
constructor(
|
|
19
|
-
this.cwd = cwd;
|
|
20
|
-
this.rules = rules;
|
|
21
|
-
this.
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.cwd = options.cwd;
|
|
20
|
+
this.rules = options.rules;
|
|
21
|
+
this.filter = options.workspace ? join(options.cwd, options.workspace) : undefined;
|
|
22
22
|
this.isMatch = () => false;
|
|
23
23
|
}
|
|
24
24
|
addIgnorePatterns(patterns) {
|
|
@@ -33,21 +33,21 @@ export class IssueCollector {
|
|
|
33
33
|
}
|
|
34
34
|
addFilesIssues(filePaths) {
|
|
35
35
|
for (const filePath of filePaths) {
|
|
36
|
-
if (this.
|
|
36
|
+
if (this.filter && !filePath.startsWith(`${this.filter}/`))
|
|
37
37
|
continue;
|
|
38
38
|
if (this.referencedFiles.has(filePath))
|
|
39
39
|
continue;
|
|
40
40
|
if (this.isMatch(filePath))
|
|
41
41
|
continue;
|
|
42
42
|
this.issues.files.add(filePath);
|
|
43
|
-
const symbol = relative(filePath);
|
|
43
|
+
const symbol = relative(this.cwd, filePath);
|
|
44
44
|
this.issues._files[symbol] = [{ type: 'files', filePath, symbol, severity: this.rules.files }];
|
|
45
45
|
this.counters.files++;
|
|
46
46
|
this.counters.processed++;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
addIssue(issue) {
|
|
50
|
-
if (this.
|
|
50
|
+
if (this.filter && !issue.filePath.startsWith(`${this.filter}/`))
|
|
51
51
|
return;
|
|
52
52
|
if (this.isMatch(issue.filePath))
|
|
53
53
|
return;
|
|
@@ -56,7 +56,7 @@ export class IssueCollector {
|
|
|
56
56
|
issue.severity = this.rules[type];
|
|
57
57
|
const issues = this.issues[type];
|
|
58
58
|
issues[key] = issues[key] ?? {};
|
|
59
|
-
const symbol =
|
|
59
|
+
const symbol = issue.parentSymbol ? `${issue.parentSymbol}.${issue.symbol}` : issue.symbol;
|
|
60
60
|
if (!issues[key][symbol]) {
|
|
61
61
|
issues[key][symbol] = issue;
|
|
62
62
|
this.counters[issue.type]++;
|
package/dist/IssueFixer.d.ts
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import type { Fix, Fixes } from './types/exports.js';
|
|
2
2
|
import type { Issues } from './types/issues.js';
|
|
3
|
-
|
|
4
|
-
isEnabled: boolean;
|
|
5
|
-
cwd: string;
|
|
6
|
-
fixTypes: string[];
|
|
7
|
-
isRemoveFiles: boolean;
|
|
8
|
-
}
|
|
3
|
+
import type { MainOptions } from './util/create-options.js';
|
|
9
4
|
export declare class IssueFixer {
|
|
10
|
-
|
|
11
|
-
cwd: string;
|
|
12
|
-
isFixFiles: boolean;
|
|
13
|
-
isFixDependencies: boolean;
|
|
14
|
-
isFixUnusedTypes: boolean;
|
|
15
|
-
isFixUnusedExports: boolean;
|
|
5
|
+
options: MainOptions;
|
|
16
6
|
unusedTypeNodes: Map<string, Set<Fix>>;
|
|
17
7
|
unusedExportNodes: Map<string, Set<Fix>>;
|
|
18
|
-
constructor(
|
|
8
|
+
constructor(options: MainOptions);
|
|
19
9
|
addUnusedTypeNode(filePath: string, fixes: Fixes | undefined): void;
|
|
20
10
|
addUnusedExportNode(filePath: string, fixes: Fixes | undefined): void;
|
|
21
11
|
fixIssues(issues: Issues): Promise<Set<string>>;
|
|
@@ -24,4 +14,3 @@ export declare class IssueFixer {
|
|
|
24
14
|
private removeUnusedExports;
|
|
25
15
|
private removeUnusedDependencies;
|
|
26
16
|
}
|
|
27
|
-
export {};
|
package/dist/IssueFixer.js
CHANGED
|
@@ -3,21 +3,11 @@ import { load, save } from './util/package-json.js';
|
|
|
3
3
|
import { join, relative } from './util/path.js';
|
|
4
4
|
import { removeExport } from './util/remove-export.js';
|
|
5
5
|
export class IssueFixer {
|
|
6
|
-
|
|
7
|
-
cwd = process.cwd();
|
|
8
|
-
isFixFiles = true;
|
|
9
|
-
isFixDependencies = true;
|
|
10
|
-
isFixUnusedTypes = true;
|
|
11
|
-
isFixUnusedExports = true;
|
|
6
|
+
options;
|
|
12
7
|
unusedTypeNodes = new Map();
|
|
13
8
|
unusedExportNodes = new Map();
|
|
14
|
-
constructor(
|
|
15
|
-
this.
|
|
16
|
-
this.cwd = cwd;
|
|
17
|
-
this.isFixFiles = isRemoveFiles && (fixTypes.length === 0 || fixTypes.includes('files'));
|
|
18
|
-
this.isFixDependencies = fixTypes.length === 0 || fixTypes.includes('dependencies');
|
|
19
|
-
this.isFixUnusedTypes = fixTypes.length === 0 || fixTypes.includes('types');
|
|
20
|
-
this.isFixUnusedExports = fixTypes.length === 0 || fixTypes.includes('exports');
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
21
11
|
}
|
|
22
12
|
addUnusedTypeNode(filePath, fixes) {
|
|
23
13
|
if (!fixes || fixes.length === 0)
|
|
@@ -47,10 +37,10 @@ export class IssueFixer {
|
|
|
47
37
|
return touchedFiles;
|
|
48
38
|
}
|
|
49
39
|
markExportFixed(issues, filePath) {
|
|
50
|
-
const relPath = relative(filePath);
|
|
40
|
+
const relPath = relative(this.options.cwd, filePath);
|
|
51
41
|
const types = [
|
|
52
|
-
...(this.isFixUnusedTypes ? ['types', 'nsTypes', 'classMembers', 'enumMembers'] : []),
|
|
53
|
-
...(this.isFixUnusedExports ? ['exports', 'nsExports'] : []),
|
|
42
|
+
...(this.options.isFixUnusedTypes ? ['types', 'nsTypes', 'classMembers', 'enumMembers'] : []),
|
|
43
|
+
...(this.options.isFixUnusedExports ? ['exports', 'nsExports'] : []),
|
|
54
44
|
];
|
|
55
45
|
for (const type of types) {
|
|
56
46
|
for (const id in issues[type][relPath]) {
|
|
@@ -59,7 +49,7 @@ export class IssueFixer {
|
|
|
59
49
|
}
|
|
60
50
|
}
|
|
61
51
|
async removeUnusedFiles(issues) {
|
|
62
|
-
if (!this.isFixFiles)
|
|
52
|
+
if (!this.options.isFixFiles)
|
|
63
53
|
return;
|
|
64
54
|
for (const issue of Object.values(issues._files).flatMap(Object.values)) {
|
|
65
55
|
await rm(issue.filePath);
|
|
@@ -70,8 +60,8 @@ export class IssueFixer {
|
|
|
70
60
|
const touchedFiles = new Set();
|
|
71
61
|
const filePaths = new Set([...this.unusedTypeNodes.keys(), ...this.unusedExportNodes.keys()]);
|
|
72
62
|
for (const filePath of filePaths) {
|
|
73
|
-
const types = (this.isFixUnusedTypes && this.unusedTypeNodes.get(filePath)) || [];
|
|
74
|
-
const exports = (this.isFixUnusedExports && this.unusedExportNodes.get(filePath)) || [];
|
|
63
|
+
const types = (this.options.isFixUnusedTypes && this.unusedTypeNodes.get(filePath)) || [];
|
|
64
|
+
const exports = (this.options.isFixUnusedExports && this.unusedExportNodes.get(filePath)) || [];
|
|
75
65
|
const exportPositions = [...types, ...exports].filter(fix => fix !== undefined).sort((a, b) => b[0] - a[0]);
|
|
76
66
|
if (exportPositions.length > 0) {
|
|
77
67
|
const sourceFileText = exportPositions.reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }), await readFile(filePath, 'utf-8'));
|
|
@@ -84,11 +74,11 @@ export class IssueFixer {
|
|
|
84
74
|
}
|
|
85
75
|
async removeUnusedDependencies(issues) {
|
|
86
76
|
const touchedFiles = new Set();
|
|
87
|
-
if (!this.isFixDependencies)
|
|
77
|
+
if (!this.options.isFixDependencies)
|
|
88
78
|
return touchedFiles;
|
|
89
79
|
const filePaths = new Set([...Object.keys(issues.dependencies), ...Object.keys(issues.devDependencies)]);
|
|
90
80
|
for (const filePath of filePaths) {
|
|
91
|
-
const absFilePath = join(this.cwd, filePath);
|
|
81
|
+
const absFilePath = join(this.options.cwd, filePath);
|
|
92
82
|
const pkg = await load(absFilePath);
|
|
93
83
|
if (filePath in issues.dependencies) {
|
|
94
84
|
for (const dependency of Object.keys(issues.dependencies[filePath])) {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ProjectPrincipal } from './ProjectPrincipal.js';
|
|
2
2
|
import type { PrincipalOptions } from './types/project.js';
|
|
3
|
+
import type { MainOptions } from './util/create-options.js';
|
|
3
4
|
export declare class PrincipalFactory {
|
|
4
5
|
private principals;
|
|
5
6
|
getPrincipalCount(): number;
|
|
6
|
-
createPrincipal(options: PrincipalOptions): ProjectPrincipal;
|
|
7
|
+
createPrincipal(options: MainOptions, opts: PrincipalOptions): ProjectPrincipal;
|
|
7
8
|
private findReusablePrincipal;
|
|
8
9
|
private linkPrincipal;
|
|
9
10
|
private addNewPrincipal;
|
|
10
11
|
getPrincipals(): ProjectPrincipal[];
|
|
11
12
|
getPrincipalByPackageName(packageName: string): ProjectPrincipal | undefined;
|
|
12
|
-
deletePrincipal(principal: ProjectPrincipal): void;
|
|
13
|
+
deletePrincipal(principal: ProjectPrincipal, cwd: string): void;
|
|
13
14
|
}
|
package/dist/PrincipalFactory.js
CHANGED
|
@@ -7,18 +7,18 @@ export class PrincipalFactory {
|
|
|
7
7
|
getPrincipalCount() {
|
|
8
8
|
return this.principals.size;
|
|
9
9
|
}
|
|
10
|
-
createPrincipal(options) {
|
|
11
|
-
const {
|
|
10
|
+
createPrincipal(options, opts) {
|
|
11
|
+
const { dir, compilerOptions, isFile, pkgName, compilers } = opts;
|
|
12
12
|
if (isFile && compilerOptions.module !== ts.ModuleKind.CommonJS)
|
|
13
13
|
compilerOptions.moduleResolution ??= ts.ModuleResolutionKind.Bundler;
|
|
14
|
-
if (!isIsolateWorkspaces) {
|
|
14
|
+
if (!options.isIsolateWorkspaces) {
|
|
15
15
|
const principal = this.findReusablePrincipal(compilerOptions);
|
|
16
16
|
if (principal) {
|
|
17
|
-
this.linkPrincipal(principal,
|
|
17
|
+
this.linkPrincipal(principal, dir, compilerOptions, pkgName, compilers);
|
|
18
18
|
return principal.principal;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
return this.addNewPrincipal(options);
|
|
21
|
+
return this.addNewPrincipal(options, opts);
|
|
22
22
|
}
|
|
23
23
|
findReusablePrincipal(compilerOptions) {
|
|
24
24
|
const workspacePaths = compilerOptions?.paths ? Object.keys(compilerOptions.paths) : [];
|
|
@@ -43,11 +43,11 @@ export class PrincipalFactory {
|
|
|
43
43
|
principal.wsDirs.add(cwd);
|
|
44
44
|
principal.pkgNames.add(pkgName);
|
|
45
45
|
}
|
|
46
|
-
addNewPrincipal(options) {
|
|
47
|
-
const {
|
|
46
|
+
addNewPrincipal(options, opts) {
|
|
47
|
+
const { dir, compilerOptions, pkgName } = opts;
|
|
48
48
|
const pathKeys = new Set(Object.keys(compilerOptions?.paths ?? {}));
|
|
49
|
-
const principal = new ProjectPrincipal(options);
|
|
50
|
-
this.principals.add({ principal, wsDirs: new Set([
|
|
49
|
+
const principal = new ProjectPrincipal(options, opts);
|
|
50
|
+
this.principals.add({ principal, wsDirs: new Set([dir]), pathKeys, pkgNames: new Set([pkgName]) });
|
|
51
51
|
return principal;
|
|
52
52
|
}
|
|
53
53
|
getPrincipals() {
|
|
@@ -56,10 +56,10 @@ export class PrincipalFactory {
|
|
|
56
56
|
getPrincipalByPackageName(packageName) {
|
|
57
57
|
return Array.from(this.principals).find(principal => principal.pkgNames.has(packageName))?.principal;
|
|
58
58
|
}
|
|
59
|
-
deletePrincipal(principal) {
|
|
59
|
+
deletePrincipal(principal, cwd) {
|
|
60
60
|
const p = Array.from(this.principals).find(p => p.principal === principal);
|
|
61
61
|
if (p) {
|
|
62
|
-
debugLog('*', `Deleting principal at ${[...p.wsDirs].map(
|
|
62
|
+
debugLog('*', `Deleting principal at ${[...p.wsDirs].map(dir => toRelative(dir, cwd) || '.')} (${[...p.pkgNames]})`);
|
|
63
63
|
this.principals.delete(p);
|
|
64
64
|
}
|
|
65
65
|
}
|