knip 5.44.0 → 5.44.2
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.js +3 -3
- package/dist/DependencyDeputy.d.ts +1 -1
- package/dist/DependencyDeputy.js +4 -4
- package/dist/IssueCollector.js +1 -1
- package/dist/ProjectPrincipal.d.ts +2 -2
- package/dist/WorkspaceWorker.js +5 -1
- package/dist/graph/analyze.d.ts +30 -0
- package/dist/graph/analyze.js +232 -0
- package/dist/graph/build.d.ts +40 -0
- package/dist/graph/build.js +268 -0
- package/dist/index.js +46 -484
- package/dist/plugins/react-router/index.js +1 -1
- package/dist/plugins/stylelint/index.js +1 -1
- package/dist/plugins/stylelint/types.d.ts +1 -1
- package/dist/{ConfigurationValidator.d.ts → schema/configuration.d.ts} +1 -1
- package/dist/{ConfigurationValidator.js → schema/configuration.js} +2 -2
- package/dist/types/config.d.ts +2 -2
- package/dist/types/{dependency-graph.d.ts → module-graph.d.ts} +1 -1
- package/dist/typescript/find-internal-references.d.ts +1 -1
- package/dist/typescript/get-imports-and-exports.d.ts +1 -1
- package/dist/typescript/get-imports-and-exports.js +1 -1
- package/dist/util/has-strictly-ns-references.d.ts +2 -2
- package/dist/util/is-identifier-referenced.d.ts +2 -2
- package/dist/util/{dependency-graph.d.ts → module-graph.d.ts} +3 -3
- package/dist/util/trace.d.ts +2 -2
- package/dist/util/watch.d.ts +4 -4
- package/dist/util/watch.js +3 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- /package/dist/types/{dependency-graph.js → module-graph.js} +0 -0
- /package/dist/{issues/initializers.d.ts → util/issue-initializers.d.ts} +0 -0
- /package/dist/{issues/initializers.js → util/issue-initializers.js} +0 -0
- /package/dist/util/{dependency-graph.js → module-graph.js} +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { WorkspaceWorker } from '../WorkspaceWorker.js';
|
|
2
|
+
import { _getInputsFromScripts } from '../binaries/index.js';
|
|
3
|
+
import { getCompilerExtensions, getIncludedCompilers } from '../compilers/index.js';
|
|
4
|
+
import { debugLog, debugLogArray } from '../util/debug.js';
|
|
5
|
+
import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
|
|
6
|
+
import { _glob, negate } from '../util/glob.js';
|
|
7
|
+
import { isConfigPattern, isEntry, isProductionEntry, toProductionEntry } from '../util/input.js';
|
|
8
|
+
import { getOrCreateFileNode, updateImportMap } from '../util/module-graph.js';
|
|
9
|
+
import { getEntryPathsFromManifest } from '../util/package-json.js';
|
|
10
|
+
import { dirname, isAbsolute, join, relative } from '../util/path.js';
|
|
11
|
+
import {} from '../util/tag.js';
|
|
12
|
+
import { augmentWorkspace, getToSourcePathHandler } from '../util/to-source-path.js';
|
|
13
|
+
import { loadTSConfig } from '../util/tsconfig-loader.js';
|
|
14
|
+
export async function build({ cacheLocation, chief, collector, cwd, deputy, factory, gitignore, isCache, isFixExports, isFixTypes, isGitIgnored, isIsolateWorkspaces, isProduction, isSkipLibs, isStrict, isWatch, report, streamer, tags, tsConfigFile, workspaces, }) {
|
|
15
|
+
const allConfigFilePaths = new Set();
|
|
16
|
+
const enabledPluginsStore = new Map();
|
|
17
|
+
const toSourceFilePath = getToSourcePathHandler(chief);
|
|
18
|
+
const getReferencedInternalFilePath = getReferencedInputsHandler(collector, deputy, chief, isGitIgnored);
|
|
19
|
+
const isReportClassMembers = report.classMembers;
|
|
20
|
+
for (const workspace of workspaces) {
|
|
21
|
+
const { name, dir, manifestPath, manifestStr } = workspace;
|
|
22
|
+
const manifest = chief.getManifestForWorkspace(name);
|
|
23
|
+
if (!manifest)
|
|
24
|
+
continue;
|
|
25
|
+
deputy.addWorkspace({ name, cwd, dir, manifestPath, manifestStr, manifest, ...chief.getIgnores(name) });
|
|
26
|
+
}
|
|
27
|
+
for (const workspace of workspaces) {
|
|
28
|
+
const { name, dir, ancestors, pkgName } = workspace;
|
|
29
|
+
streamer.cast(`Analyzing workspace ${name}...`);
|
|
30
|
+
const manifest = chief.getManifestForWorkspace(name);
|
|
31
|
+
if (!manifest) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const dependencies = deputy.getDependencies(name);
|
|
35
|
+
const compilers = getIncludedCompilers(chief.config.syncCompilers, chief.config.asyncCompilers, dependencies);
|
|
36
|
+
const extensions = getCompilerExtensions(compilers);
|
|
37
|
+
const config = chief.getConfigForWorkspace(name, extensions);
|
|
38
|
+
const tsConfigFilePath = join(dir, tsConfigFile ?? 'tsconfig.json');
|
|
39
|
+
const { isFile, compilerOptions, definitionPaths } = await loadTSConfig(tsConfigFilePath);
|
|
40
|
+
if (isFile)
|
|
41
|
+
augmentWorkspace(workspace, dir, compilerOptions);
|
|
42
|
+
const worker = new WorkspaceWorker({
|
|
43
|
+
name,
|
|
44
|
+
dir,
|
|
45
|
+
cwd,
|
|
46
|
+
config,
|
|
47
|
+
manifest,
|
|
48
|
+
dependencies,
|
|
49
|
+
getReferencedInternalFilePath: (input) => getReferencedInternalFilePath(input, workspace),
|
|
50
|
+
isProduction,
|
|
51
|
+
isStrict,
|
|
52
|
+
rootIgnore: chief.config.ignore,
|
|
53
|
+
negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
|
|
54
|
+
ignoredWorkspacePatterns: chief.getIgnoredWorkspacesFor(name),
|
|
55
|
+
enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
|
|
56
|
+
isCache,
|
|
57
|
+
cacheLocation,
|
|
58
|
+
allConfigFilePaths,
|
|
59
|
+
});
|
|
60
|
+
await worker.init();
|
|
61
|
+
const deps = new Set();
|
|
62
|
+
if (definitionPaths.length > 0) {
|
|
63
|
+
debugLogArray(name, 'Definition paths', definitionPaths);
|
|
64
|
+
for (const id of definitionPaths)
|
|
65
|
+
deps.add(toProductionEntry(id, { containingFilePath: tsConfigFilePath }));
|
|
66
|
+
}
|
|
67
|
+
const ignore = worker.getIgnorePatterns();
|
|
68
|
+
const sharedGlobOptions = { cwd, dir, gitignore };
|
|
69
|
+
collector.addIgnorePatterns(ignore.map(pattern => join(cwd, pattern)));
|
|
70
|
+
const entryPathsFromManifest = await getEntryPathsFromManifest(manifest, { ...sharedGlobOptions, ignore });
|
|
71
|
+
for (const id of entryPathsFromManifest.map(id => toProductionEntry(id)))
|
|
72
|
+
deps.add(id);
|
|
73
|
+
const dependenciesFromPlugins = await worker.findDependenciesByPlugins();
|
|
74
|
+
for (const id of dependenciesFromPlugins)
|
|
75
|
+
deps.add(id);
|
|
76
|
+
enabledPluginsStore.set(name, worker.enabledPlugins);
|
|
77
|
+
const principal = factory.createPrincipal({
|
|
78
|
+
cwd: dir,
|
|
79
|
+
paths: config.paths,
|
|
80
|
+
isFile,
|
|
81
|
+
compilerOptions,
|
|
82
|
+
compilers,
|
|
83
|
+
pkgName,
|
|
84
|
+
isIsolateWorkspaces,
|
|
85
|
+
isSkipLibs,
|
|
86
|
+
isWatch,
|
|
87
|
+
toSourceFilePath,
|
|
88
|
+
isCache,
|
|
89
|
+
cacheLocation,
|
|
90
|
+
});
|
|
91
|
+
const entryFilePatterns = new Set();
|
|
92
|
+
const productionEntryFilePatterns = new Set();
|
|
93
|
+
for (const dependency of deps) {
|
|
94
|
+
const s = dependency.specifier;
|
|
95
|
+
if (isEntry(dependency)) {
|
|
96
|
+
entryFilePatterns.add(isAbsolute(s) ? relative(dir, s) : s);
|
|
97
|
+
}
|
|
98
|
+
else if (isProductionEntry(dependency)) {
|
|
99
|
+
productionEntryFilePatterns.add(isAbsolute(s) ? relative(dir, s) : s);
|
|
100
|
+
}
|
|
101
|
+
else if (!isConfigPattern(dependency)) {
|
|
102
|
+
const ws = (dependency.containingFilePath && chief.findWorkspaceByFilePath(dependency.containingFilePath)) || workspace;
|
|
103
|
+
const specifierFilePath = getReferencedInternalFilePath(dependency, ws);
|
|
104
|
+
if (specifierFilePath)
|
|
105
|
+
principal.addEntryPath(specifierFilePath, { skipExportsAnalysis: true });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (isProduction) {
|
|
109
|
+
const negatedEntryPatterns = Array.from(entryFilePatterns).map(negate);
|
|
110
|
+
{
|
|
111
|
+
const label = 'entry';
|
|
112
|
+
const patterns = worker.getProductionEntryFilePatterns(negatedEntryPatterns);
|
|
113
|
+
const workspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, gitignore: false, label });
|
|
114
|
+
principal.addEntryPaths(workspaceEntryPaths);
|
|
115
|
+
}
|
|
116
|
+
{
|
|
117
|
+
const label = 'production plugin entry';
|
|
118
|
+
const patterns = Array.from(productionEntryFilePatterns);
|
|
119
|
+
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
120
|
+
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
121
|
+
}
|
|
122
|
+
{
|
|
123
|
+
const label = 'project';
|
|
124
|
+
const patterns = worker.getProductionProjectFilePatterns(negatedEntryPatterns);
|
|
125
|
+
const workspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
126
|
+
for (const projectPath of workspaceProjectPaths)
|
|
127
|
+
principal.addProjectPath(projectPath);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
{
|
|
132
|
+
const label = 'entry';
|
|
133
|
+
const patterns = worker.getEntryFilePatterns();
|
|
134
|
+
const workspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, gitignore: false, label });
|
|
135
|
+
principal.addEntryPaths(workspaceEntryPaths);
|
|
136
|
+
}
|
|
137
|
+
{
|
|
138
|
+
const label = 'project';
|
|
139
|
+
const patterns = worker.getProjectFilePatterns([...productionEntryFilePatterns]);
|
|
140
|
+
const workspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
141
|
+
for (const projectPath of workspaceProjectPaths)
|
|
142
|
+
principal.addProjectPath(projectPath);
|
|
143
|
+
}
|
|
144
|
+
{
|
|
145
|
+
const label = 'plugin entry';
|
|
146
|
+
const patterns = worker.getPluginEntryFilePatterns([...entryFilePatterns, ...productionEntryFilePatterns]);
|
|
147
|
+
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
148
|
+
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
149
|
+
}
|
|
150
|
+
{
|
|
151
|
+
const label = 'plugin project';
|
|
152
|
+
const patterns = worker.getPluginProjectFilePatterns();
|
|
153
|
+
const pluginWorkspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
154
|
+
for (const projectPath of pluginWorkspaceProjectPaths)
|
|
155
|
+
principal.addProjectPath(projectPath);
|
|
156
|
+
}
|
|
157
|
+
{
|
|
158
|
+
const label = 'plugin configuration';
|
|
159
|
+
const patterns = worker.getPluginConfigPatterns();
|
|
160
|
+
const configurationEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
161
|
+
principal.addEntryPaths(configurationEntryPaths, { skipExportsAnalysis: true });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (chief.resolvedConfigFilePath) {
|
|
165
|
+
principal.addEntryPath(chief.resolvedConfigFilePath, { skipExportsAnalysis: true });
|
|
166
|
+
}
|
|
167
|
+
worker.onDispose();
|
|
168
|
+
}
|
|
169
|
+
const principals = factory.getPrincipals();
|
|
170
|
+
debugLog('*', `Created ${principals.length} programs for ${workspaces.length} workspaces`);
|
|
171
|
+
const graph = new Map();
|
|
172
|
+
const analyzedFiles = new Set();
|
|
173
|
+
const unreferencedFiles = new Set();
|
|
174
|
+
const entryPaths = new Set();
|
|
175
|
+
const isPackageNameInternalWorkspace = (packageName) => chief.availableWorkspacePkgNames.has(packageName);
|
|
176
|
+
const getPrincipalByFilePath = (filePath) => {
|
|
177
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
178
|
+
if (workspace)
|
|
179
|
+
return factory.getPrincipalByPackageName(workspace.pkgName);
|
|
180
|
+
};
|
|
181
|
+
const analyzeSourceFile = (filePath, principal) => {
|
|
182
|
+
if (!isWatch && analyzedFiles.has(filePath))
|
|
183
|
+
return;
|
|
184
|
+
analyzedFiles.add(filePath);
|
|
185
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
186
|
+
if (workspace) {
|
|
187
|
+
const { imports, exports, duplicates, scripts, traceRefs } = principal.analyzeSourceFile(filePath, {
|
|
188
|
+
skipTypeOnly: isStrict,
|
|
189
|
+
isFixExports,
|
|
190
|
+
isFixTypes,
|
|
191
|
+
ignoreExportsUsedInFile: chief.config.ignoreExportsUsedInFile,
|
|
192
|
+
isReportClassMembers,
|
|
193
|
+
tags,
|
|
194
|
+
}, isGitIgnored, isPackageNameInternalWorkspace, getPrincipalByFilePath);
|
|
195
|
+
const node = getOrCreateFileNode(graph, filePath);
|
|
196
|
+
node.imports = imports;
|
|
197
|
+
node.exports = exports;
|
|
198
|
+
node.duplicates = duplicates;
|
|
199
|
+
node.scripts = scripts;
|
|
200
|
+
node.traceRefs = traceRefs;
|
|
201
|
+
updateImportMap(node, imports.internal, graph);
|
|
202
|
+
node.internalImportCache = imports.internal;
|
|
203
|
+
graph.set(filePath, node);
|
|
204
|
+
if (scripts && scripts.size > 0) {
|
|
205
|
+
const dependencies = deputy.getDependencies(workspace.name);
|
|
206
|
+
const manifestScriptNames = new Set(Object.keys(chief.getManifestForWorkspace(workspace.name)?.scripts ?? {}));
|
|
207
|
+
const dir = dirname(filePath);
|
|
208
|
+
const options = {
|
|
209
|
+
cwd: dir,
|
|
210
|
+
rootCwd: cwd,
|
|
211
|
+
containingFilePath: filePath,
|
|
212
|
+
dependencies,
|
|
213
|
+
manifestScriptNames,
|
|
214
|
+
};
|
|
215
|
+
const inputs = _getInputsFromScripts(scripts, options);
|
|
216
|
+
for (const input of inputs) {
|
|
217
|
+
input.containingFilePath ??= filePath;
|
|
218
|
+
input.dir ??= dir;
|
|
219
|
+
const specifierFilePath = getReferencedInternalFilePath(input, workspace);
|
|
220
|
+
if (specifierFilePath)
|
|
221
|
+
analyzeSourceFile(specifierFilePath, principal);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
for (let i = 0; i < principals.length; ++i) {
|
|
227
|
+
const principal = principals[i];
|
|
228
|
+
if (!principal)
|
|
229
|
+
continue;
|
|
230
|
+
principal.init();
|
|
231
|
+
streamer.cast('Running async compilers...');
|
|
232
|
+
await principal.runAsyncCompilers();
|
|
233
|
+
streamer.cast('Analyzing source files...');
|
|
234
|
+
let size = principal.entryPaths.size;
|
|
235
|
+
let round = 0;
|
|
236
|
+
do {
|
|
237
|
+
size = principal.entryPaths.size;
|
|
238
|
+
const resolvedFiles = principal.getUsedResolvedFiles();
|
|
239
|
+
const files = resolvedFiles.filter(filePath => !analyzedFiles.has(filePath));
|
|
240
|
+
debugLogArray('*', `Analyzing used resolved files [P${i + 1}/${++round}]`, files);
|
|
241
|
+
for (const filePath of files)
|
|
242
|
+
analyzeSourceFile(filePath, principal);
|
|
243
|
+
} while (size !== principal.entryPaths.size);
|
|
244
|
+
for (const filePath of principal.getUnreferencedFiles())
|
|
245
|
+
unreferencedFiles.add(filePath);
|
|
246
|
+
for (const filePath of principal.entryPaths)
|
|
247
|
+
entryPaths.add(filePath);
|
|
248
|
+
principal.reconcileCache(graph);
|
|
249
|
+
if (!isIsolateWorkspaces && isSkipLibs && !isWatch) {
|
|
250
|
+
factory.deletePrincipal(principal);
|
|
251
|
+
principals[i] = undefined;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (isIsolateWorkspaces) {
|
|
255
|
+
for (const principal of principals) {
|
|
256
|
+
if (principal)
|
|
257
|
+
factory.deletePrincipal(principal);
|
|
258
|
+
}
|
|
259
|
+
principals.length = 0;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
graph,
|
|
263
|
+
entryPaths,
|
|
264
|
+
analyzedFiles,
|
|
265
|
+
unreferencedFiles,
|
|
266
|
+
analyzeSourceFile,
|
|
267
|
+
};
|
|
268
|
+
}
|