knip 2.32.2 → 2.32.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConfigurationChief.d.ts +17 -5
- package/dist/ConfigurationChief.js +58 -18
- package/dist/DependencyDeputy.js +9 -7
- package/dist/IssueCollector.d.ts +6 -1
- package/dist/IssueCollector.js +12 -6
- package/dist/ProjectPrincipal.d.ts +1 -1
- package/dist/WorkspaceWorker.js +2 -1
- package/dist/index.js +10 -18
- package/dist/plugins/ava/index.js +11 -9
- package/dist/plugins/ava/types.d.ts +4 -1
- package/dist/typescript/resolveModuleNames.js +22 -9
- package/dist/util/loader.d.ts +1 -0
- package/dist/util/loader.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { createPkgGraph } from '@pnpm/workspace.pkgs-graph';
|
|
2
2
|
import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
|
|
3
3
|
import type { Configuration, WorkspaceConfiguration } from './types/config.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PackageJsonWithPlugins } from './types/plugins.js';
|
|
5
5
|
type ConfigurationManagerOptions = {
|
|
6
6
|
cwd: string;
|
|
7
7
|
isProduction: boolean;
|
|
@@ -12,26 +12,38 @@ export type Workspace = {
|
|
|
12
12
|
dir: string;
|
|
13
13
|
ancestors: string[];
|
|
14
14
|
config: WorkspaceConfiguration;
|
|
15
|
+
manifestPath: string;
|
|
16
|
+
manifest: PackageJsonWithPlugins;
|
|
15
17
|
};
|
|
16
18
|
export declare class ConfigurationChief {
|
|
17
19
|
cwd: string;
|
|
18
20
|
isProduction: boolean;
|
|
19
21
|
config: Configuration;
|
|
20
22
|
manifestPath?: string;
|
|
21
|
-
manifest?:
|
|
23
|
+
manifest?: PackageJsonWithPlugins;
|
|
22
24
|
ignoredWorkspacePatterns: string[];
|
|
23
25
|
manifestWorkspaces: Map<string, string>;
|
|
24
26
|
additionalWorkspaceNames: Set<string>;
|
|
25
27
|
availableWorkspaceNames: string[];
|
|
28
|
+
availableWorkspacePkgNames: Set<string | undefined>;
|
|
26
29
|
availableWorkspaceDirs: string[];
|
|
30
|
+
availableWorkspaceManifests: {
|
|
31
|
+
dir: string;
|
|
32
|
+
manifest: PackageJsonWithPlugins;
|
|
33
|
+
}[];
|
|
34
|
+
workspacesGraph: ReturnType<typeof createPkgGraph> | undefined;
|
|
27
35
|
enabledWorkspaces: Workspace[];
|
|
28
|
-
localWorkspaces: Set<string>;
|
|
29
36
|
resolvedConfigFilePath?: string;
|
|
30
37
|
rawConfig?: any;
|
|
31
38
|
constructor({ cwd, isProduction }: ConfigurationManagerOptions);
|
|
32
39
|
init(): Promise<void>;
|
|
33
40
|
getCompilers(): [SyncCompilers, AsyncCompilers];
|
|
34
41
|
getRules(): import("./types/issues.js").Rules;
|
|
42
|
+
getFilters(): {
|
|
43
|
+
dir: string;
|
|
44
|
+
} | {
|
|
45
|
+
dir?: undefined;
|
|
46
|
+
};
|
|
35
47
|
private normalize;
|
|
36
48
|
private setWorkspaces;
|
|
37
49
|
private getListedWorkspaces;
|
|
@@ -40,6 +52,7 @@ export declare class ConfigurationChief {
|
|
|
40
52
|
private getConfiguredWorkspaceKeys;
|
|
41
53
|
private getAdditionalWorkspaceNames;
|
|
42
54
|
private getAvailableWorkspaceNames;
|
|
55
|
+
private getAvailableWorkspaceManifests;
|
|
43
56
|
private getEnabledWorkspaces;
|
|
44
57
|
getWorkspaces(): Workspace[];
|
|
45
58
|
private getDescendentWorkspaces;
|
|
@@ -49,7 +62,6 @@ export declare class ConfigurationChief {
|
|
|
49
62
|
private getConfigForWorkspace;
|
|
50
63
|
getIssueTypesToReport(): import("./types/issues.js").Report;
|
|
51
64
|
findWorkspaceByFilePath(filePath: string): Workspace | undefined;
|
|
52
|
-
findWorkspaceByPackageName(packageName: string): Workspace | undefined;
|
|
53
65
|
getUnusedIgnoredWorkspaces(): string[];
|
|
54
66
|
}
|
|
55
67
|
export {};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import mapWorkspaces from '@npmcli/map-workspaces';
|
|
3
|
+
import { createPkgGraph } from '@pnpm/workspace.pkgs-graph';
|
|
3
4
|
import micromatch from 'micromatch';
|
|
4
5
|
import { ConfigurationValidator } from './ConfigurationValidator.js';
|
|
5
6
|
import { ROOT_WORKSPACE_NAME, DEFAULT_EXTENSIONS, KNIP_CONFIG_LOCATIONS } from './constants.js';
|
|
6
7
|
import { defaultRules } from './issues/initializers.js';
|
|
7
8
|
import * as plugins from './plugins/index.js';
|
|
8
|
-
import { arrayify
|
|
9
|
+
import { arrayify } from './util/array.js';
|
|
9
10
|
import parsedArgValues from './util/cli-arguments.js';
|
|
10
11
|
import { partitionCompilers } from './util/compilers.js';
|
|
11
|
-
import { ConfigurationError } from './util/errors.js';
|
|
12
|
+
import { ConfigurationError, LoaderError } from './util/errors.js';
|
|
12
13
|
import { findFile, loadJSON } from './util/fs.js';
|
|
13
14
|
import { getIncludedIssueTypes } from './util/get-included-issue-types.js';
|
|
14
15
|
import { _dirGlob } from './util/glob.js';
|
|
@@ -16,6 +17,7 @@ import { _load } from './util/loader.js';
|
|
|
16
17
|
import { getKeysByValue } from './util/object.js';
|
|
17
18
|
import { join, relative, toPosix } from './util/path.js';
|
|
18
19
|
import { normalizePluginConfig, toCamelCase } from './util/plugin.js';
|
|
20
|
+
import { _require } from './util/require.js';
|
|
19
21
|
import { byPathDepth } from './util/workspace.js';
|
|
20
22
|
const { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [], dependencies = false, exports = false, } = parsedArgValues;
|
|
21
23
|
const workspaceArg = rawWorkspaceArg ? toPosix(rawWorkspaceArg).replace(/^\.\//, '').replace(/\/$/, '') : undefined;
|
|
@@ -55,9 +57,11 @@ export class ConfigurationChief {
|
|
|
55
57
|
manifestWorkspaces = new Map();
|
|
56
58
|
additionalWorkspaceNames = new Set();
|
|
57
59
|
availableWorkspaceNames = [];
|
|
60
|
+
availableWorkspacePkgNames = new Set();
|
|
58
61
|
availableWorkspaceDirs = [];
|
|
62
|
+
availableWorkspaceManifests = [];
|
|
63
|
+
workspacesGraph;
|
|
59
64
|
enabledWorkspaces = [];
|
|
60
|
-
localWorkspaces = new Set();
|
|
61
65
|
resolvedConfigFilePath;
|
|
62
66
|
rawConfig;
|
|
63
67
|
constructor({ cwd, isProduction }) {
|
|
@@ -97,6 +101,11 @@ export class ConfigurationChief {
|
|
|
97
101
|
getRules() {
|
|
98
102
|
return this.config.rules;
|
|
99
103
|
}
|
|
104
|
+
getFilters() {
|
|
105
|
+
if (this.workspacesGraph?.graph && workspaceArg)
|
|
106
|
+
return { dir: join(this.cwd, workspaceArg) };
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
100
109
|
normalize(rawConfig) {
|
|
101
110
|
const rules = { ...defaultRules, ...rawConfig.rules };
|
|
102
111
|
const include = rawConfig.include ?? defaultConfig.include;
|
|
@@ -140,8 +149,10 @@ export class ConfigurationChief {
|
|
|
140
149
|
.sort(byPathDepth)
|
|
141
150
|
.reverse()
|
|
142
151
|
.map(dir => join(this.cwd, dir));
|
|
152
|
+
this.availableWorkspaceManifests = this.getAvailableWorkspaceManifests(this.availableWorkspaceDirs);
|
|
153
|
+
this.availableWorkspacePkgNames = new Set(this.availableWorkspaceManifests.map(w => w.manifest.name));
|
|
154
|
+
this.workspacesGraph = createPkgGraph(this.availableWorkspaceManifests);
|
|
143
155
|
this.enabledWorkspaces = this.getEnabledWorkspaces();
|
|
144
|
-
this.localWorkspaces = new Set(compact(this.enabledWorkspaces.map(w => w.pkgName)));
|
|
145
156
|
}
|
|
146
157
|
getListedWorkspaces() {
|
|
147
158
|
return this.manifest?.workspaces
|
|
@@ -186,6 +197,14 @@ export class ConfigurationChief {
|
|
|
186
197
|
getAvailableWorkspaceNames() {
|
|
187
198
|
return [ROOT_WORKSPACE_NAME, ...this.manifestWorkspaces.keys(), ...this.additionalWorkspaceNames].filter(name => !micromatch.isMatch(name, this.ignoredWorkspacePatterns));
|
|
188
199
|
}
|
|
200
|
+
getAvailableWorkspaceManifests(availableWorkspaceDirs) {
|
|
201
|
+
return availableWorkspaceDirs.map(dir => {
|
|
202
|
+
const manifest = _require(join(dir, 'package.json'));
|
|
203
|
+
if (!manifest)
|
|
204
|
+
throw new LoaderError(`Unable to load package.json for ${dir}`);
|
|
205
|
+
return { dir, manifest };
|
|
206
|
+
});
|
|
207
|
+
}
|
|
189
208
|
getEnabledWorkspaces() {
|
|
190
209
|
if (workspaceArg && !existsSync(workspaceArg)) {
|
|
191
210
|
throw new ConfigurationError(`Directory does not exist: ${workspaceArg}`);
|
|
@@ -198,18 +217,42 @@ export class ConfigurationChief {
|
|
|
198
217
|
return ancestors;
|
|
199
218
|
};
|
|
200
219
|
const workspaceNames = workspaceArg
|
|
201
|
-
? [
|
|
202
|
-
...this.availableWorkspaceNames.reduce(getAncestors(workspaceArg), []),
|
|
203
|
-
...this.availableWorkspaceNames.filter(name => name === workspaceArg),
|
|
204
|
-
]
|
|
220
|
+
? [...this.availableWorkspaceNames.reduce(getAncestors(workspaceArg), []), workspaceArg]
|
|
205
221
|
: this.availableWorkspaceNames;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
const graph = this.workspacesGraph?.graph;
|
|
223
|
+
const ws = new Set();
|
|
224
|
+
if (graph && workspaceArg) {
|
|
225
|
+
const seen = new Set();
|
|
226
|
+
const initialWorkspaces = new Set(workspaceNames.map(name => join(this.cwd, name)));
|
|
227
|
+
const workspaceDirsWithDependants = new Set(initialWorkspaces);
|
|
228
|
+
const addDependents = (dir) => {
|
|
229
|
+
seen.add(dir);
|
|
230
|
+
const deps = graph[dir]?.dependencies ?? [];
|
|
231
|
+
if (deps.length > 0 && Array.from(initialWorkspaces).some(dir => deps.includes(dir))) {
|
|
232
|
+
workspaceDirsWithDependants.add(dir);
|
|
233
|
+
}
|
|
234
|
+
deps.filter(dir => !seen.has(dir)).forEach(addDependents);
|
|
235
|
+
};
|
|
236
|
+
this.availableWorkspaceNames.map(name => join(this.cwd, name)).forEach(addDependents);
|
|
237
|
+
workspaceDirsWithDependants.forEach(dir => ws.add(relative(this.cwd, dir) || ROOT_WORKSPACE_NAME));
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
workspaceNames.forEach(name => ws.add(name));
|
|
241
|
+
}
|
|
242
|
+
return Array.from(ws)
|
|
243
|
+
.sort(byPathDepth)
|
|
244
|
+
.map((name) => {
|
|
245
|
+
const dir = join(this.cwd, name);
|
|
246
|
+
return {
|
|
247
|
+
name,
|
|
248
|
+
pkgName: this.manifestWorkspaces.get(name) ?? this.manifest?.name ?? `NOT_FOUND_${name}`,
|
|
249
|
+
dir,
|
|
250
|
+
config: this.getConfigForWorkspace(name),
|
|
251
|
+
ancestors: this.availableWorkspaceNames.reduce(getAncestors(name), []),
|
|
252
|
+
manifestPath: join(dir, 'package.json'),
|
|
253
|
+
manifest: this.availableWorkspaceManifests?.find(item => item.dir === dir)?.manifest ?? {},
|
|
254
|
+
};
|
|
255
|
+
});
|
|
213
256
|
}
|
|
214
257
|
getWorkspaces() {
|
|
215
258
|
return this.enabledWorkspaces;
|
|
@@ -281,9 +324,6 @@ export class ConfigurationChief {
|
|
|
281
324
|
const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(workspaceDir + '/'));
|
|
282
325
|
return this.enabledWorkspaces.find(workspace => workspace.dir === workspaceDir);
|
|
283
326
|
}
|
|
284
|
-
findWorkspaceByPackageName(packageName) {
|
|
285
|
-
return this.enabledWorkspaces.find(workspace => workspace.pkgName === packageName);
|
|
286
|
-
}
|
|
287
327
|
getUnusedIgnoredWorkspaces() {
|
|
288
328
|
const ignoredWorkspaceNames = this.config.ignoreWorkspaces;
|
|
289
329
|
const workspaceNames = [...this.manifestWorkspaces.keys(), ...this.additionalWorkspaceNames];
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -233,9 +233,10 @@ export class DependencyDeputy {
|
|
|
233
233
|
const installedBinaries = this.getInstalledBinaries(workspaceName);
|
|
234
234
|
referencedDependencies?.forEach(pkg => pkg in rootIgnoreDependencies && rootIgnoreDependencies[pkg]++);
|
|
235
235
|
referencedBinaries?.forEach(binaryName => binaryName in rootIgnoreBinaries && rootIgnoreBinaries[binaryName]++);
|
|
236
|
-
const dependencies =
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
const dependencies = [
|
|
237
|
+
...this.getProductionDependencies(workspaceName),
|
|
238
|
+
...this.getDevDependencies(workspaceName),
|
|
239
|
+
];
|
|
239
240
|
const peerDependencies = this.getPeerDependencies(workspaceName);
|
|
240
241
|
const isReferencedDep = (name) => referencedDependencies?.has(name) && dependencies.includes(name);
|
|
241
242
|
const isReferencedBin = (name) => referencedBinaries?.has(name) && installedBinaries?.has(name);
|
|
@@ -251,16 +252,17 @@ export class DependencyDeputy {
|
|
|
251
252
|
.forEach(identifier => configurationHints.add({ workspaceName, identifier, type: 'ignoreBinaries' }));
|
|
252
253
|
}
|
|
253
254
|
const installedBinaries = this.getInstalledBinaries(ROOT_WORKSPACE_NAME);
|
|
254
|
-
const dependencies =
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
const dependencies = [
|
|
256
|
+
...this.getProductionDependencies(ROOT_WORKSPACE_NAME),
|
|
257
|
+
...this.getDevDependencies(ROOT_WORKSPACE_NAME),
|
|
258
|
+
];
|
|
257
259
|
const peerDependencies = this.getPeerDependencies(ROOT_WORKSPACE_NAME);
|
|
258
260
|
Object.keys(rootIgnoreBinaries)
|
|
259
261
|
.filter(key => IGNORED_GLOBAL_BINARIES.includes(key) || (rootIgnoreBinaries[key] !== 0 && installedBinaries?.has(key)))
|
|
260
262
|
.forEach(identifier => configurationHints.add({ workspaceName: ROOT_WORKSPACE_NAME, identifier, type: 'ignoreBinaries' }));
|
|
261
263
|
Object.keys(rootIgnoreDependencies)
|
|
262
264
|
.filter(key => IGNORED_DEPENDENCIES.includes(key) ||
|
|
263
|
-
(rootIgnoreDependencies[key]
|
|
265
|
+
(rootIgnoreDependencies[key] === 0 && !peerDependencies.includes(key) && !dependencies.includes(key)))
|
|
264
266
|
.forEach(identifier => configurationHints.add({ workspaceName: ROOT_WORKSPACE_NAME, identifier, type: 'ignoreDependencies' }));
|
|
265
267
|
return { configurationHints };
|
|
266
268
|
}
|
package/dist/IssueCollector.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import type { ConfigurationHint, Issue, Rules } from './types/issues.js';
|
|
2
|
+
type Filters = Partial<{
|
|
3
|
+
dir: string;
|
|
4
|
+
}>;
|
|
2
5
|
type IssueCollectorOptions = {
|
|
3
6
|
cwd: string;
|
|
4
7
|
rules: Rules;
|
|
8
|
+
filters: Filters;
|
|
5
9
|
};
|
|
6
10
|
export declare class IssueCollector {
|
|
7
11
|
private cwd;
|
|
8
12
|
private rules;
|
|
13
|
+
private filters;
|
|
9
14
|
private issues;
|
|
10
15
|
private counters;
|
|
11
16
|
private referencedFiles;
|
|
12
17
|
private configurationHints;
|
|
13
|
-
constructor({ cwd, rules }: IssueCollectorOptions);
|
|
18
|
+
constructor({ cwd, rules, filters }: IssueCollectorOptions);
|
|
14
19
|
addFileCounts({ processed, unused }: {
|
|
15
20
|
processed: number;
|
|
16
21
|
unused: number;
|
package/dist/IssueCollector.js
CHANGED
|
@@ -7,13 +7,15 @@ function objectInSet(set, obj) {
|
|
|
7
7
|
export class IssueCollector {
|
|
8
8
|
cwd;
|
|
9
9
|
rules;
|
|
10
|
+
filters;
|
|
10
11
|
issues = initIssues();
|
|
11
12
|
counters = initCounters();
|
|
12
13
|
referencedFiles = new Set();
|
|
13
14
|
configurationHints = new Set();
|
|
14
|
-
constructor({ cwd, rules }) {
|
|
15
|
+
constructor({ cwd, rules, filters }) {
|
|
15
16
|
this.cwd = cwd;
|
|
16
17
|
this.rules = rules;
|
|
18
|
+
this.filters = filters;
|
|
17
19
|
}
|
|
18
20
|
addFileCounts({ processed, unused }) {
|
|
19
21
|
this.counters.processed += processed;
|
|
@@ -21,14 +23,18 @@ export class IssueCollector {
|
|
|
21
23
|
}
|
|
22
24
|
addFilesIssues(filePaths) {
|
|
23
25
|
filePaths.forEach(filePath => {
|
|
24
|
-
if (!this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (this.filters.dir && !filePath.startsWith(this.filters.dir + '/'))
|
|
27
|
+
return;
|
|
28
|
+
if (this.referencedFiles.has(filePath))
|
|
29
|
+
return;
|
|
30
|
+
this.issues.files.add(filePath);
|
|
31
|
+
this.counters.files++;
|
|
32
|
+
this.counters.processed++;
|
|
29
33
|
});
|
|
30
34
|
}
|
|
31
35
|
addIssue(issue) {
|
|
36
|
+
if (this.filters.dir && !issue.filePath.startsWith(this.filters.dir + '/'))
|
|
37
|
+
return;
|
|
32
38
|
const key = relative(this.cwd, issue.filePath);
|
|
33
39
|
issue.severity = this.rules[issue.type];
|
|
34
40
|
this.issues[issue.type][key] = this.issues[issue.type][key] ?? {};
|
|
@@ -53,7 +53,7 @@ export declare class ProjectPrincipal {
|
|
|
53
53
|
};
|
|
54
54
|
scripts: Set<string>;
|
|
55
55
|
};
|
|
56
|
-
|
|
56
|
+
resolveModule(specifier: string, filePath?: string): ts.ResolvedModuleFull | undefined;
|
|
57
57
|
getHasReferences(filePath: string, exportedItem: ExportItem): {
|
|
58
58
|
external: boolean;
|
|
59
59
|
internal: boolean;
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as npm from './manifest/index.js';
|
|
|
2
2
|
import * as plugins from './plugins/index.js';
|
|
3
3
|
import { debugLogArray, debugLogObject } from './util/debug.js';
|
|
4
4
|
import { _pureGlob, negate, hasProductionSuffix, hasNoProductionSuffix, prependDirToPattern } from './util/glob.js';
|
|
5
|
+
import { FAKE_PATH } from './util/loader.js';
|
|
5
6
|
import { get, getKeysByValue } from './util/object.js';
|
|
6
7
|
import { join, toPosix } from './util/path.js';
|
|
7
8
|
import { fromEntryPattern, fromProductionEntryPattern, isEntryPattern, isProductionEntryPattern, } from './util/protocols.js';
|
|
@@ -184,7 +185,7 @@ export class WorkspaceWorker {
|
|
|
184
185
|
if (patterns.length > 0 && configFilePaths.length === 0)
|
|
185
186
|
continue;
|
|
186
187
|
if (patterns.length === 0)
|
|
187
|
-
configFilePaths.push(
|
|
188
|
+
configFilePaths.push(FAKE_PATH);
|
|
188
189
|
const pluginDependencies = new Set();
|
|
189
190
|
for (const configFilePath of configFilePaths) {
|
|
190
191
|
const dependencies = await plugin.findDependencies(configFilePath, {
|
package/dist/index.js
CHANGED
|
@@ -2,21 +2,17 @@ import micromatch from 'micromatch';
|
|
|
2
2
|
import { _getDependenciesFromScripts } from './binaries/index.js';
|
|
3
3
|
import { ConfigurationChief } from './ConfigurationChief.js';
|
|
4
4
|
import { ConsoleStreamer } from './ConsoleStreamer.js';
|
|
5
|
-
import { ROOT_WORKSPACE_NAME } from './constants.js';
|
|
6
5
|
import { DependencyDeputy } from './DependencyDeputy.js';
|
|
7
6
|
import { IssueCollector } from './IssueCollector.js';
|
|
8
7
|
import { PrincipalFactory } from './PrincipalFactory.js';
|
|
9
8
|
import { ProjectPrincipal } from './ProjectPrincipal.js';
|
|
10
9
|
import { compact } from './util/array.js';
|
|
11
10
|
import { debugLogObject, debugLogArray, debugLog } from './util/debug.js';
|
|
12
|
-
import { LoaderError } from './util/errors.js';
|
|
13
|
-
import { findFile } from './util/fs.js';
|
|
14
11
|
import { _glob, negate } from './util/glob.js';
|
|
15
12
|
import { getEntryPathFromManifest, getPackageNameFromFilePath, getPackageNameFromModuleSpecifier, } from './util/modules.js';
|
|
16
|
-
import { dirname, isInNodeModules, join, isInternal
|
|
13
|
+
import { dirname, isInNodeModules, join, isInternal } from './util/path.js';
|
|
17
14
|
import { fromBinary, isBinary } from './util/protocols.js';
|
|
18
|
-
import { _resolveSpecifier
|
|
19
|
-
import { _require } from './util/require.js';
|
|
15
|
+
import { _resolveSpecifier } from './util/require.js';
|
|
20
16
|
import { loadTSConfig } from './util/tsconfig-loader.js';
|
|
21
17
|
import { WorkspaceWorker } from './WorkspaceWorker.js';
|
|
22
18
|
export const main = async (unresolvedConfiguration) => {
|
|
@@ -32,17 +28,18 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
32
28
|
const workspaces = chief.getWorkspaces();
|
|
33
29
|
const report = chief.getIssueTypesToReport();
|
|
34
30
|
const rules = chief.getRules();
|
|
31
|
+
const filters = chief.getFilters();
|
|
35
32
|
const isReportDependencies = report.dependencies || report.unlisted || report.unresolved;
|
|
36
33
|
const isReportValues = report.exports || report.nsExports || report.classMembers;
|
|
37
34
|
const isReportTypes = report.types || report.nsTypes || report.enumMembers;
|
|
38
|
-
const collector = new IssueCollector({ cwd, rules });
|
|
35
|
+
const collector = new IssueCollector({ cwd, rules, filters });
|
|
39
36
|
const enabledPluginsStore = new Map();
|
|
40
37
|
deputy.addIgnored(chief.config.ignoreBinaries, chief.config.ignoreDependencies);
|
|
41
|
-
debugLogObject('Included workspaces', workspaces);
|
|
38
|
+
debugLogObject('Included workspaces', workspaces.map(w => w.pkgName));
|
|
39
|
+
debugLogObject('Included workspace configs', workspaces.map(w => ({ name: w.name, pkgName: w.pkgName, config: w.config, ancestors: w.ancestors })));
|
|
42
40
|
const handleReferencedDependency = ({ specifier, containingFilePath, principal, workspace, }) => {
|
|
43
41
|
if (isInternal(specifier)) {
|
|
44
|
-
const
|
|
45
|
-
const filePath = _tryResolve(absSpecifier, containingFilePath);
|
|
42
|
+
const filePath = principal.resolveModule(specifier, containingFilePath)?.resolvedFileName;
|
|
46
43
|
if (filePath) {
|
|
47
44
|
const ignorePatterns = workspace.config.ignore.map(pattern => join(dirname(containingFilePath), pattern));
|
|
48
45
|
const isIgnored = micromatch.isMatch(filePath, ignorePatterns);
|
|
@@ -68,7 +65,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
68
65
|
if (!isHandled)
|
|
69
66
|
collector.addIssue({ type: 'unlisted', filePath: containingFilePath, symbol: specifier });
|
|
70
67
|
if (packageName && specifier !== packageName) {
|
|
71
|
-
const otherWorkspace = chief.
|
|
68
|
+
const otherWorkspace = chief.availableWorkspaceManifests.find(w => w.manifest.name === packageName);
|
|
72
69
|
if (otherWorkspace) {
|
|
73
70
|
const filePath = _resolveSpecifier(otherWorkspace.dir, specifier);
|
|
74
71
|
if (filePath) {
|
|
@@ -83,14 +80,9 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
83
80
|
}
|
|
84
81
|
};
|
|
85
82
|
for (const workspace of workspaces) {
|
|
86
|
-
const { name, dir, config, ancestors, pkgName } = workspace;
|
|
83
|
+
const { name, dir, config, ancestors, pkgName, manifestPath, manifest } = workspace;
|
|
87
84
|
const { paths, ignoreDependencies, ignoreBinaries } = config;
|
|
88
|
-
const isRoot = name === ROOT_WORKSPACE_NAME;
|
|
89
85
|
streamer.cast(`Analyzing workspace (${name})...`);
|
|
90
|
-
const manifestPath = isRoot ? chief.manifestPath : findFile(dir, 'package.json');
|
|
91
|
-
const manifest = isRoot ? chief.manifest : manifestPath && _require(manifestPath);
|
|
92
|
-
if (!manifestPath || !manifest)
|
|
93
|
-
throw new LoaderError(`Unable to load package.json for ${name}`);
|
|
94
86
|
deputy.addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, ignoreBinaries });
|
|
95
87
|
const { compilerOptions, definitionPaths } = await loadTSConfig(join(dir, tsConfigFile ?? 'tsconfig.json'));
|
|
96
88
|
const principal = factory.getPrincipal({ cwd: dir, paths, compilerOptions, compilers, pkgName });
|
|
@@ -195,7 +187,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
195
187
|
exportedSymbols.set(filePath, exported);
|
|
196
188
|
for (const [specifierFilePath, importItems] of internal.entries()) {
|
|
197
189
|
const packageName = getPackageNameFromModuleSpecifier(importItems.specifier);
|
|
198
|
-
if (packageName && chief.
|
|
190
|
+
if (packageName && chief.availableWorkspacePkgNames.has(packageName)) {
|
|
199
191
|
external.add(packageName);
|
|
200
192
|
if (_principal === principal) {
|
|
201
193
|
const workspace = chief.findWorkspaceByFilePath(specifierFilePath);
|
|
@@ -7,19 +7,21 @@ export const ENABLERS = ['ava'];
|
|
|
7
7
|
export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
|
|
8
8
|
export const CONFIG_FILE_PATTERNS = ['ava.config.{js,cjs,mjs}', 'package.json'];
|
|
9
9
|
export const ENTRY_FILE_PATTERNS = [
|
|
10
|
-
`test.{js,cjs,mjs}`,
|
|
11
|
-
`{src,source}/test.{js,cjs,mjs}`,
|
|
12
|
-
`**/__tests__/**/*.{js,cjs,mjs}`,
|
|
13
|
-
`**/*.spec.{js,cjs,mjs}`,
|
|
14
|
-
`**/*.test.{js,cjs,mjs}`,
|
|
15
|
-
`**/test-*.{js,cjs,mjs}`,
|
|
16
|
-
`**/test/**/*.{js,cjs,mjs}`,
|
|
17
|
-
`**/tests/**/*.{js,cjs,mjs}`,
|
|
10
|
+
`test.{js,cjs,mjs,ts}`,
|
|
11
|
+
`{src,source}/test.{js,cjs,mjs,ts}`,
|
|
12
|
+
`**/__tests__/**/*.{js,cjs,mjs,ts}`,
|
|
13
|
+
`**/*.spec.{js,cjs,mjs,ts}`,
|
|
14
|
+
`**/*.test.{js,cjs,mjs,ts}`,
|
|
15
|
+
`**/test-*.{js,cjs,mjs,ts}`,
|
|
16
|
+
`**/test/**/*.{js,cjs,mjs,ts}`,
|
|
17
|
+
`**/tests/**/*.{js,cjs,mjs,ts}`,
|
|
18
18
|
'!**/__tests__/**/__{helper,fixture}?(s)__/**/*',
|
|
19
19
|
'!**/test?(s)/**/{helper,fixture}?(s)/**/*',
|
|
20
20
|
];
|
|
21
21
|
const findAvaDependencies = async (configFilePath, { cwd, manifest, isProduction }) => {
|
|
22
|
-
|
|
22
|
+
let config = configFilePath.endsWith('package.json') ? manifest.ava : await load(configFilePath);
|
|
23
|
+
if (typeof config === 'function')
|
|
24
|
+
config = config();
|
|
23
25
|
const entryPatterns = (config?.files ?? ENTRY_FILE_PATTERNS).map(toEntryPattern);
|
|
24
26
|
if (isProduction)
|
|
25
27
|
return entryPatterns;
|
|
@@ -2,7 +2,19 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import ts from 'typescript';
|
|
3
3
|
import { sanitizeSpecifier } from '../util/modules.js';
|
|
4
4
|
import { dirname, extname, isInternal, join } from '../util/path.js';
|
|
5
|
+
import { isDeclarationFileExtension } from './ast-helpers.js';
|
|
5
6
|
import { ensureRealFilePath, isVirtualFilePath } from './utils.js';
|
|
7
|
+
const simpleResolver = (name, containingFile) => {
|
|
8
|
+
const resolvedFileName = join(dirname(containingFile), name);
|
|
9
|
+
if (existsSync(resolvedFileName)) {
|
|
10
|
+
return {
|
|
11
|
+
resolvedFileName,
|
|
12
|
+
extension: extname(resolvedFileName),
|
|
13
|
+
isExternalLibraryImport: false,
|
|
14
|
+
resolvedUsingTsExtension: false,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
};
|
|
6
18
|
export function createCustomModuleResolver(customSys, compilerOptions, virtualFileExtensions) {
|
|
7
19
|
function resolveModuleNames(moduleNames, containingFile) {
|
|
8
20
|
return moduleNames.map(moduleName => resolveModuleName(moduleName, containingFile));
|
|
@@ -13,17 +25,18 @@ export function createCustomModuleResolver(customSys, compilerOptions, virtualFi
|
|
|
13
25
|
if (!tsResolvedModule) {
|
|
14
26
|
const extension = extname(sanitizedSpecifier);
|
|
15
27
|
if (extension && isInternal(sanitizedSpecifier) && !virtualFileExtensions.includes(extension)) {
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
18
|
-
return
|
|
19
|
-
resolvedFileName,
|
|
20
|
-
extension,
|
|
21
|
-
isExternalLibraryImport: false,
|
|
22
|
-
resolvedUsingTsExtension: false,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
28
|
+
const module = simpleResolver(sanitizedSpecifier, containingFile);
|
|
29
|
+
if (module)
|
|
30
|
+
return module;
|
|
25
31
|
}
|
|
26
32
|
}
|
|
33
|
+
if (tsResolvedModule &&
|
|
34
|
+
isDeclarationFileExtension(tsResolvedModule?.extension) &&
|
|
35
|
+
isInternal(tsResolvedModule.resolvedFileName)) {
|
|
36
|
+
const module = simpleResolver(sanitizedSpecifier, containingFile);
|
|
37
|
+
if (module)
|
|
38
|
+
return module;
|
|
39
|
+
}
|
|
27
40
|
if (virtualFileExtensions.length === 0)
|
|
28
41
|
return tsResolvedModule;
|
|
29
42
|
if (tsResolvedModule && !isVirtualFilePath(tsResolvedModule.resolvedFileName, virtualFileExtensions)) {
|
package/dist/util/loader.d.ts
CHANGED
package/dist/util/loader.js
CHANGED
|
@@ -4,7 +4,10 @@ import { loadJSON, loadYAML, loadFile, parseJSON, parseYAML } from './fs.js';
|
|
|
4
4
|
import { extname } from './path.js';
|
|
5
5
|
import { timerify } from './Performance.js';
|
|
6
6
|
import { jiti } from './register.js';
|
|
7
|
+
export const FAKE_PATH = '__FAKE__';
|
|
7
8
|
const load = async (filePath) => {
|
|
9
|
+
if (filePath === FAKE_PATH)
|
|
10
|
+
return;
|
|
8
11
|
try {
|
|
9
12
|
const ext = extname(filePath);
|
|
10
13
|
if (/rc$/.test(filePath)) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.32.
|
|
1
|
+
export declare const version = "2.32.4";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.32.
|
|
1
|
+
export const version = '2.32.4';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "2.32.
|
|
3
|
+
"version": "2.32.4",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://github.com/webpro/knip",
|
|
6
6
|
"repository": "github:webpro/knip",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"knip": "node ./dist/cli.js",
|
|
21
21
|
"knip:production": "node ./dist/cli.js --production --strict --ignore-internal",
|
|
22
|
-
"lint": "eslint scripts src
|
|
23
|
-
"lint:fix": "eslint scripts src
|
|
24
|
-
"format": "prettier scripts src
|
|
25
|
-
"pretest": "node rmdir.js tmp && swc src -d tmp/src && swc
|
|
22
|
+
"lint": "eslint scripts src test",
|
|
23
|
+
"lint:fix": "eslint scripts src test --fix",
|
|
24
|
+
"format": "prettier scripts src test schema.json --with-node-modules --write --config .prettierrc",
|
|
25
|
+
"pretest": "node rmdir.js tmp && swc src -d tmp/src && swc test -d tmp/test",
|
|
26
26
|
"test": "node --no-warnings --test tmp",
|
|
27
|
-
"coverage": "c8 --reporter html node --no-warnings --loader tsx --test
|
|
27
|
+
"coverage": "c8 --reporter html node --no-warnings --loader tsx --test test/*.test.ts test/*/*.test.ts",
|
|
28
28
|
"watch": "rm $(which knip); npm link && tsc --watch",
|
|
29
29
|
"prebuild": "node rmdir.js dist",
|
|
30
30
|
"build": "tsc",
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@ericcornelissen/bash-parser": "^0.5.2",
|
|
46
46
|
"@npmcli/map-workspaces": "^3.0.4",
|
|
47
|
+
"@pnpm/logger": "5.0.0",
|
|
48
|
+
"@pnpm/workspace.pkgs-graph": "2.0.6",
|
|
47
49
|
"@snyk/github-codeowners": "^1.1.0",
|
|
48
50
|
"chalk": "^5.2.0",
|
|
49
51
|
"easy-table": "^1.2.0",
|