knip 5.70.1 → 5.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DependencyDeputy.js +2 -2
- package/dist/ProjectPrincipal.js +1 -1
- package/dist/WorkspaceWorker.js +32 -35
- package/dist/binaries/bash-parser.js +14 -1
- package/dist/compilers/index.js +1 -1
- package/dist/constants.js +1 -0
- package/dist/graph/analyze.js +21 -16
- package/dist/graph/build.js +71 -87
- package/dist/graph-explorer/constants.d.ts +2 -0
- package/dist/graph-explorer/constants.js +2 -0
- package/dist/graph-explorer/explorer.d.ts +11 -0
- package/dist/graph-explorer/explorer.js +10 -0
- package/dist/graph-explorer/operations/build-trace-tree.d.ts +12 -0
- package/dist/graph-explorer/operations/build-trace-tree.js +51 -0
- package/dist/graph-explorer/operations/has-strictly-ns-references.d.ts +2 -0
- package/dist/graph-explorer/operations/has-strictly-ns-references.js +98 -0
- package/dist/graph-explorer/operations/is-referenced.d.ts +4 -0
- package/dist/graph-explorer/operations/is-referenced.js +89 -0
- package/dist/graph-explorer/utils.d.ts +4 -0
- package/dist/graph-explorer/utils.js +28 -0
- package/dist/graph-explorer/visitors.d.ts +12 -0
- package/dist/graph-explorer/visitors.js +30 -0
- package/dist/graph-explorer/walk-down.d.ts +4 -0
- package/dist/graph-explorer/walk-down.js +119 -0
- package/dist/index.js +2 -98
- package/dist/plugins/angular/index.js +3 -3
- package/dist/plugins/astro/index.js +0 -2
- package/dist/plugins/next/index.js +4 -3
- package/dist/plugins/next/resolveFromAST.d.ts +1 -0
- package/dist/plugins/next/resolveFromAST.js +42 -1
- package/dist/plugins/vite/helpers.js +1 -1
- package/dist/reporters/codeclimate.js +3 -7
- package/dist/reporters/util/util.d.ts +2 -1
- package/dist/reporters/util/util.js +1 -0
- package/dist/reporters/watch.js +1 -1
- package/dist/run.d.ts +25 -0
- package/dist/run.js +107 -0
- package/dist/types/issues.d.ts +4 -4
- package/dist/types/module-graph.d.ts +14 -12
- package/dist/typescript/ast-helpers.d.ts +4 -0
- package/dist/typescript/ast-helpers.js +48 -0
- package/dist/typescript/get-imports-and-exports.js +18 -3
- package/dist/typescript/visitors/dynamic-imports/importCall.js +5 -19
- package/dist/typescript/visitors/dynamic-imports/jsDocType.js +7 -5
- package/dist/typescript/visitors/imports/importDeclaration.js +5 -4
- package/dist/util/create-options.js +1 -1
- package/dist/util/file-entry-cache.js +1 -1
- package/dist/util/graph-sequencer.js +1 -1
- package/dist/util/input.d.ts +1 -0
- package/dist/util/module-graph.js +7 -7
- package/dist/util/plugin.d.ts +1 -1
- package/dist/util/plugin.js +4 -3
- package/dist/util/trace.d.ts +3 -13
- package/dist/util/trace.js +10 -41
- package/dist/util/watch.d.ts +19 -3
- package/dist/util/watch.js +28 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/vendor/bash-parser/index.d.ts +6 -1
- package/dist/util/has-strictly-ns-references.d.ts +0 -4
- package/dist/util/has-strictly-ns-references.js +0 -103
- package/dist/util/is-identifier-referenced.d.ts +0 -9
- package/dist/util/is-identifier-referenced.js +0 -145
package/dist/DependencyDeputy.js
CHANGED
|
@@ -174,7 +174,7 @@ export class DependencyDeputy {
|
|
|
174
174
|
const dependencyIssues = [];
|
|
175
175
|
const devDependencyIssues = [];
|
|
176
176
|
const optionalPeerDependencyIssues = [];
|
|
177
|
-
for (const [workspace, { manifestPath: filePath, manifestStr }] of this._manifests
|
|
177
|
+
for (const [workspace, { manifestPath: filePath, manifestStr }] of this._manifests) {
|
|
178
178
|
const referencedDependencies = this.referencedDependencies.get(workspace);
|
|
179
179
|
const hasTypesIncluded = this.getHasTypesIncluded(workspace);
|
|
180
180
|
const peeker = new PackagePeeker(manifestStr);
|
|
@@ -342,7 +342,7 @@ export class DependencyDeputy {
|
|
|
342
342
|
}
|
|
343
343
|
getConfigurationHints() {
|
|
344
344
|
const configurationHints = new Set();
|
|
345
|
-
for (const [workspaceName, manifest] of this._manifests
|
|
345
|
+
for (const [workspaceName, manifest] of this._manifests) {
|
|
346
346
|
for (const identifier of manifest.unusedIgnoreDependencies) {
|
|
347
347
|
configurationHints.add({ workspaceName, identifier, type: 'ignoreDependencies' });
|
|
348
348
|
}
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -217,7 +217,7 @@ export class ProjectPrincipal {
|
|
|
217
217
|
return externalRefs.length > 0;
|
|
218
218
|
}
|
|
219
219
|
reconcileCache(graph) {
|
|
220
|
-
for (const [filePath, file] of graph
|
|
220
|
+
for (const [filePath, file] of graph) {
|
|
221
221
|
const fd = this.cache.getFileDescriptor(filePath);
|
|
222
222
|
if (!fd?.meta)
|
|
223
223
|
continue;
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -89,15 +89,7 @@ export class WorkspaceWorker {
|
|
|
89
89
|
if (project.length === 0)
|
|
90
90
|
return [];
|
|
91
91
|
const excludeProductionNegations = project.filter(pattern => !(pattern.startsWith('!') && pattern.endsWith('!')));
|
|
92
|
-
|
|
93
|
-
const negatedPluginProjectFilePatterns = this.getPluginProjectFilePatterns().map(negate);
|
|
94
|
-
return [
|
|
95
|
-
excludeProductionNegations,
|
|
96
|
-
negatedPluginConfigPatterns,
|
|
97
|
-
negatedPluginProjectFilePatterns,
|
|
98
|
-
projectFilePatterns,
|
|
99
|
-
this.negatedWorkspacePatterns,
|
|
100
|
-
].flat();
|
|
92
|
+
return [excludeProductionNegations, projectFilePatterns, this.negatedWorkspacePatterns].flat();
|
|
101
93
|
}
|
|
102
94
|
getPluginProjectFilePatterns(patterns = []) {
|
|
103
95
|
for (const [pluginName, plugin] of PluginEntries) {
|
|
@@ -175,18 +167,10 @@ export class WorkspaceWorker {
|
|
|
175
167
|
const createGetInputsFromScripts = (containingFilePath) => (scripts, options) => _getInputsFromScripts(scripts, { ...baseOptions, ...options, containingFilePath });
|
|
176
168
|
const inputs = [];
|
|
177
169
|
const remainingPlugins = new Set(this.enabledPlugins);
|
|
178
|
-
const addInput = (input, containingFilePath = input.containingFilePath) => {
|
|
179
|
-
if (isConfig(input)) {
|
|
180
|
-
handleConfigInput(input.pluginName, { ...input, containingFilePath });
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
inputs.push({ ...input, containingFilePath });
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
170
|
const configFilesMap = this.configFilesMap;
|
|
187
171
|
const configFiles = this.configFilesMap.get(wsName);
|
|
188
172
|
const seen = new Map();
|
|
189
|
-
const
|
|
173
|
+
const storeConfigFilePath = (pluginName, input) => {
|
|
190
174
|
const configFilePath = this.getReferencedInternalFilePath(input);
|
|
191
175
|
if (configFilePath) {
|
|
192
176
|
const workspace = this.findWorkspaceByFilePath(configFilePath);
|
|
@@ -202,20 +186,26 @@ export class WorkspaceWorker {
|
|
|
202
186
|
};
|
|
203
187
|
for (const input of [...inputsFromManifest, ...productionInputsFromManifest]) {
|
|
204
188
|
if (isConfig(input)) {
|
|
205
|
-
|
|
189
|
+
storeConfigFilePath(input.pluginName, { ...input, containingFilePath });
|
|
206
190
|
}
|
|
207
|
-
else {
|
|
208
|
-
|
|
209
|
-
addInput(input, containingFilePath);
|
|
210
|
-
else if (isProduction && (input.production || hasProductionInput(input)))
|
|
211
|
-
addInput(input, containingFilePath);
|
|
191
|
+
else if (!isProduction || (isProduction && (input.production || hasProductionInput(input)))) {
|
|
192
|
+
inputs.push({ ...input, containingFilePath });
|
|
212
193
|
}
|
|
213
194
|
}
|
|
214
195
|
const runPlugin = async (pluginName, patterns) => {
|
|
215
196
|
const plugin = Plugins[pluginName];
|
|
216
197
|
const config = this.getConfigForPlugin(pluginName);
|
|
217
198
|
if (!config)
|
|
218
|
-
return;
|
|
199
|
+
return [];
|
|
200
|
+
const inputs = [];
|
|
201
|
+
const addInput = (input, containingFilePath = input.containingFilePath) => {
|
|
202
|
+
if (isConfig(input)) {
|
|
203
|
+
storeConfigFilePath(input.pluginName, { ...input, containingFilePath });
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
inputs.push(Object.assign(input, { containingFilePath }));
|
|
207
|
+
}
|
|
208
|
+
};
|
|
219
209
|
const label = 'config file';
|
|
220
210
|
const configFilePaths = await _glob({ patterns, cwd: rootCwd, dir: cwd, gitignore: false, label });
|
|
221
211
|
const options = {
|
|
@@ -229,7 +219,7 @@ export class WorkspaceWorker {
|
|
|
229
219
|
if (config.entry) {
|
|
230
220
|
const toInput = isProduction && plugin.production && plugin.production.length > 0 ? toProductionEntry : toEntry;
|
|
231
221
|
for (const id of config.entry)
|
|
232
|
-
|
|
222
|
+
inputs.push(toInput(id));
|
|
233
223
|
}
|
|
234
224
|
else if ((!plugin.resolveConfig && !plugin.resolveFromAST) ||
|
|
235
225
|
(configFilePaths.filter(path => basename(path) !== 'package.json').length === 0 &&
|
|
@@ -237,10 +227,10 @@ export class WorkspaceWorker {
|
|
|
237
227
|
this.configFilesMap.get(wsName)?.get(pluginName)?.size === 0))) {
|
|
238
228
|
if (plugin.entry)
|
|
239
229
|
for (const id of plugin.entry)
|
|
240
|
-
|
|
230
|
+
inputs.push(toEntry(id));
|
|
241
231
|
if (plugin.production)
|
|
242
232
|
for (const id of plugin.production)
|
|
243
|
-
|
|
233
|
+
inputs.push(toProductionEntry(id));
|
|
244
234
|
}
|
|
245
235
|
for (const configFilePath of configFilePaths) {
|
|
246
236
|
const isManifest = basename(configFilePath) === 'package.json';
|
|
@@ -295,8 +285,8 @@ export class WorkspaceWorker {
|
|
|
295
285
|
}
|
|
296
286
|
}
|
|
297
287
|
if (!isManifest) {
|
|
298
|
-
|
|
299
|
-
|
|
288
|
+
inputs.push(toEntry(configFilePath));
|
|
289
|
+
storeConfigFilePath(pluginName, toConfig(pluginName, configFilePath));
|
|
300
290
|
cache.configFile = toEntry(configFilePath);
|
|
301
291
|
if (fd?.changed && fd.meta && !seen.get(key)?.has(configFilePath)) {
|
|
302
292
|
fd.meta.data = cache;
|
|
@@ -311,26 +301,33 @@ export class WorkspaceWorker {
|
|
|
311
301
|
for (const id of dependencies)
|
|
312
302
|
addInput(id, containingFilePath);
|
|
313
303
|
}
|
|
304
|
+
if (inputs.some(input => input.specifier.startsWith('!')))
|
|
305
|
+
for (const input of inputs)
|
|
306
|
+
input.group = pluginName;
|
|
307
|
+
return inputs;
|
|
314
308
|
};
|
|
315
309
|
const enabledPluginTitles = this.enabledPlugins.map(name => Plugins[name].title);
|
|
316
310
|
debugLogObject(this.name, 'Enabled plugins', enabledPluginTitles);
|
|
317
311
|
for (const pluginName of this.enabledPlugins) {
|
|
318
312
|
const patterns = [...this.getConfigurationFilePatterns(pluginName), ...(configFiles?.get(pluginName) ?? [])];
|
|
319
313
|
configFiles?.delete(pluginName);
|
|
320
|
-
await runPlugin(pluginName, compact(patterns))
|
|
314
|
+
for (const input of await runPlugin(pluginName, compact(patterns)))
|
|
315
|
+
inputs.push(input);
|
|
321
316
|
remainingPlugins.delete(pluginName);
|
|
322
317
|
}
|
|
323
318
|
{
|
|
324
319
|
const configFiles = this.configFilesMap.get(wsName);
|
|
325
320
|
if (configFiles) {
|
|
326
321
|
do {
|
|
327
|
-
for (const [pluginName, dependencies] of configFiles
|
|
322
|
+
for (const [pluginName, dependencies] of configFiles) {
|
|
328
323
|
configFiles.delete(pluginName);
|
|
329
|
-
if (this.enabledPlugins.includes(pluginName))
|
|
330
|
-
await runPlugin(pluginName, Array.from(dependencies))
|
|
324
|
+
if (this.enabledPlugins.includes(pluginName)) {
|
|
325
|
+
for (const input of await runPlugin(pluginName, Array.from(dependencies)))
|
|
326
|
+
inputs.push(input);
|
|
327
|
+
}
|
|
331
328
|
else
|
|
332
329
|
for (const id of dependencies)
|
|
333
|
-
|
|
330
|
+
inputs.push(toEntry(id));
|
|
334
331
|
}
|
|
335
332
|
} while (remainingPlugins.size > 0 && configFiles.size > 0);
|
|
336
333
|
}
|
|
@@ -25,6 +25,12 @@ export const getDependenciesFromScript = (script, options) => {
|
|
|
25
25
|
knownBinsOnly: false,
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
|
+
const definedFunctions = new Set();
|
|
29
|
+
const collectFunctionNames = (nodes) => {
|
|
30
|
+
for (const node of nodes)
|
|
31
|
+
if (node.type === 'Function')
|
|
32
|
+
definedFunctions.add(node.name.text);
|
|
33
|
+
};
|
|
28
34
|
const getDependenciesFromNodes = (nodes) => nodes.flatMap(node => {
|
|
29
35
|
switch (node.type) {
|
|
30
36
|
case 'Command': {
|
|
@@ -41,6 +47,8 @@ export const getDependenciesFromScript = (script, options) => {
|
|
|
41
47
|
return [];
|
|
42
48
|
if (binary.startsWith('-') || binary.startsWith('"') || binary.startsWith('..'))
|
|
43
49
|
return [];
|
|
50
|
+
if (definedFunctions.has(binary))
|
|
51
|
+
return [];
|
|
44
52
|
const args = node.suffix?.map(arg => arg.text) ?? [];
|
|
45
53
|
if (['!', 'test'].includes(binary))
|
|
46
54
|
return fromArgs(args);
|
|
@@ -82,13 +90,18 @@ export const getDependenciesFromScript = (script, options) => {
|
|
|
82
90
|
return getDependenciesFromNodes(node.commands);
|
|
83
91
|
case 'Function':
|
|
84
92
|
return getDependenciesFromNodes(node.body.commands);
|
|
93
|
+
case 'Subshell':
|
|
94
|
+
return getDependenciesFromNodes(node.list.commands);
|
|
85
95
|
default:
|
|
86
96
|
return [];
|
|
87
97
|
}
|
|
88
98
|
});
|
|
89
99
|
try {
|
|
90
100
|
const parsed = parse(script);
|
|
91
|
-
|
|
101
|
+
if (!parsed?.commands)
|
|
102
|
+
return [];
|
|
103
|
+
collectFunctionNames(parsed.commands);
|
|
104
|
+
return getDependenciesFromNodes(parsed.commands);
|
|
92
105
|
}
|
|
93
106
|
catch (error) {
|
|
94
107
|
const msg = `Warning: failed to parse and ignoring script in ${relative(options.cwd, options.containingFilePath)} (${truncate(script, 30)})`;
|
package/dist/compilers/index.js
CHANGED
|
@@ -38,7 +38,7 @@ const compilers = new Map([
|
|
|
38
38
|
]);
|
|
39
39
|
export const getIncludedCompilers = (syncCompilers, asyncCompilers, dependencies) => {
|
|
40
40
|
const hasDependency = (packageName) => dependencies.has(packageName);
|
|
41
|
-
for (const [extension, { condition, compiler }] of compilers
|
|
41
|
+
for (const [extension, { condition, compiler }] of compilers) {
|
|
42
42
|
if (extension === '.mdx' && AstroMDX.condition(hasDependency)) {
|
|
43
43
|
syncCompilers.set(extension, AstroMDX.compiler);
|
|
44
44
|
}
|
package/dist/constants.js
CHANGED
package/dist/graph/analyze.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createGraphExplorer } from '../graph-explorer/explorer.js';
|
|
2
|
+
import { getIssueType, hasStrictlyEnumReferences } from '../graph-explorer/utils.js';
|
|
3
3
|
import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
|
|
4
4
|
import { findMatch } from '../util/regex.js';
|
|
5
5
|
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler } from '../util/tag.js';
|
|
6
|
-
import {
|
|
6
|
+
import { printTraceNode } from '../util/trace.js';
|
|
7
7
|
export const analyze = async ({ analyzedFiles, counselor, chief, collector, deputy, entryPaths, factory, graph, streamer, unreferencedFiles, options, }) => {
|
|
8
8
|
const shouldIgnore = getShouldIgnoreHandler(options.isProduction);
|
|
9
9
|
const shouldIgnoreTags = getShouldIgnoreTagHandler(options.tags);
|
|
10
|
-
const
|
|
10
|
+
const explorer = createGraphExplorer(graph, entryPaths);
|
|
11
11
|
const ignoreExportsUsedInFile = chief.config.ignoreExportsUsedInFile;
|
|
12
12
|
const isExportedItemReferenced = (exportedItem) => exportedItem.refs[1] ||
|
|
13
13
|
(exportedItem.refs[0] > 0 &&
|
|
@@ -17,7 +17,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
17
17
|
const analyzeGraph = async () => {
|
|
18
18
|
if (options.isReportValues || options.isReportTypes) {
|
|
19
19
|
streamer.cast('Connecting the dots');
|
|
20
|
-
for (const [filePath, file] of graph
|
|
20
|
+
for (const [filePath, file] of graph) {
|
|
21
21
|
const exportItems = file.exports;
|
|
22
22
|
if (!exportItems || exportItems.size === 0)
|
|
23
23
|
continue;
|
|
@@ -27,16 +27,17 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
27
27
|
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
28
28
|
const isEntry = entryPaths.has(filePath);
|
|
29
29
|
if (!isIncludeEntryExports && isEntry) {
|
|
30
|
-
createAndPrintTrace(filePath, options, { isEntry });
|
|
31
30
|
continue;
|
|
32
31
|
}
|
|
33
32
|
const importsForExport = file.imported;
|
|
34
|
-
for (const [identifier, exportedItem] of exportItems
|
|
33
|
+
for (const [identifier, exportedItem] of exportItems) {
|
|
35
34
|
if (shouldIgnore(exportedItem.jsDocTags))
|
|
36
35
|
continue;
|
|
37
36
|
const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags);
|
|
38
37
|
if (importsForExport) {
|
|
39
|
-
const
|
|
38
|
+
const [isReferenced, reExportingEntryFile] = explorer.isReferenced(filePath, identifier, {
|
|
39
|
+
includeEntryExports: isIncludeEntryExports,
|
|
40
|
+
});
|
|
40
41
|
if ((isReferenced || exportedItem.refs[1]) && isIgnored) {
|
|
41
42
|
for (const tagName of exportedItem.jsDocTags) {
|
|
42
43
|
if (options.tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
@@ -48,15 +49,12 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
48
49
|
continue;
|
|
49
50
|
if (reExportingEntryFile) {
|
|
50
51
|
if (!isIncludeEntryExports) {
|
|
51
|
-
createAndPrintTrace(filePath, options, { identifier, isEntry, hasRef: isReferenced });
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
54
|
const reExportedItem = graph.get(reExportingEntryFile)?.exports.get(identifier);
|
|
55
55
|
if (reExportedItem && shouldIgnore(reExportedItem.jsDocTags))
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
-
if (traceNode)
|
|
59
|
-
printTrace(traceNode, filePath, options, identifier);
|
|
60
58
|
if (isReferenced) {
|
|
61
59
|
if (options.includedIssueTypes.enumMembers && exportedItem.type === 'enum') {
|
|
62
60
|
if (!options.includedIssueTypes.nsTypes && importsForExport.refs.has(identifier))
|
|
@@ -70,9 +68,11 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
70
68
|
continue;
|
|
71
69
|
if (member.refs[0] === 0) {
|
|
72
70
|
const id = `${identifier}.${member.identifier}`;
|
|
73
|
-
const
|
|
71
|
+
const [isMemberReferenced] = explorer.isReferenced(filePath, id, {
|
|
72
|
+
includeEntryExports: true,
|
|
73
|
+
});
|
|
74
74
|
const isIgnored = shouldIgnoreTags(member.jsDocTags);
|
|
75
|
-
if (!
|
|
75
|
+
if (!isMemberReferenced) {
|
|
76
76
|
if (isIgnored)
|
|
77
77
|
continue;
|
|
78
78
|
collector.addIssue({
|
|
@@ -125,7 +125,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
125
125
|
continue;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
const [hasStrictlyNsRefs, namespace] = hasStrictlyNsReferences(
|
|
128
|
+
const [hasStrictlyNsRefs, namespace] = explorer.hasStrictlyNsReferences(filePath, identifier);
|
|
129
129
|
const isType = ['enum', 'type', 'interface'].includes(exportedItem.type);
|
|
130
130
|
if (hasStrictlyNsRefs &&
|
|
131
131
|
((!options.includedIssueTypes.nsTypes && isType) || !(options.includedIssueTypes.nsExports || isType)))
|
|
@@ -135,7 +135,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
135
135
|
continue;
|
|
136
136
|
if (!options.isSkipLibs && principal?.hasExternalReferences(filePath, exportedItem))
|
|
137
137
|
continue;
|
|
138
|
-
const type =
|
|
138
|
+
const type = getIssueType(hasStrictlyNsRefs, isType);
|
|
139
139
|
collector.addIssue({
|
|
140
140
|
type,
|
|
141
141
|
filePath,
|
|
@@ -153,7 +153,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
for (const [filePath, file] of graph
|
|
156
|
+
for (const [filePath, file] of graph) {
|
|
157
157
|
const ws = chief.findWorkspaceByFilePath(filePath);
|
|
158
158
|
if (ws) {
|
|
159
159
|
if (file.duplicates && options.includedIssueTypes.duplicates) {
|
|
@@ -227,5 +227,10 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
227
227
|
collector.addConfigurationHint(hint);
|
|
228
228
|
};
|
|
229
229
|
await analyzeGraph();
|
|
230
|
+
if (options.isTrace) {
|
|
231
|
+
const nodes = explorer.buildExportsTree({ filePath: options.traceFile, identifier: options.traceExport });
|
|
232
|
+
for (const node of nodes)
|
|
233
|
+
printTraceNode(node, options);
|
|
234
|
+
}
|
|
230
235
|
return analyzeGraph;
|
|
231
236
|
};
|
package/dist/graph/build.js
CHANGED
|
@@ -106,33 +106,34 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
106
106
|
for (const id of inputsFromPlugins)
|
|
107
107
|
inputs.add(Object.assign(id, { skipExportsAnalysis: !id.allowIncludeExports }));
|
|
108
108
|
enabledPluginsStore.set(name, worker.enabledPlugins);
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
109
|
+
const DEFAULT_GROUP = 'default';
|
|
110
|
+
const createPatternMap = () => new Map([[DEFAULT_GROUP, new Set()]]);
|
|
111
|
+
const groups = new Set([DEFAULT_GROUP]);
|
|
112
|
+
const entryPatterns = createPatternMap();
|
|
113
|
+
const entryPatternsSkipExports = createPatternMap();
|
|
114
|
+
const productionPatterns = createPatternMap();
|
|
115
|
+
const productionPatternsSkipExports = createPatternMap();
|
|
113
116
|
const projectFilePatterns = new Set();
|
|
117
|
+
const addPattern = (map, input, pattern) => {
|
|
118
|
+
if (input.group && !map.has(input.group))
|
|
119
|
+
map.set(input.group, new Set());
|
|
120
|
+
map.get(input.group ?? DEFAULT_GROUP).add(pattern);
|
|
121
|
+
};
|
|
122
|
+
const toWorkspaceRelative = (path) => (isAbsolute(path) ? relative(dir, path) : path);
|
|
114
123
|
for (const input of inputs) {
|
|
124
|
+
if (input.group)
|
|
125
|
+
groups.add(input.group);
|
|
115
126
|
const specifier = input.specifier;
|
|
116
127
|
if (isEntry(input)) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
entryPatterns.add(relativePath);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
entryPatternsSkipExports.add(relativePath);
|
|
123
|
-
}
|
|
128
|
+
const targetMap = input.skipExportsAnalysis ? entryPatternsSkipExports : entryPatterns;
|
|
129
|
+
addPattern(targetMap, input, toWorkspaceRelative(specifier));
|
|
124
130
|
}
|
|
125
131
|
else if (isProductionEntry(input)) {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
productionPatterns.add(relativePath);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
productionPatternsSkipExports.add(relativePath);
|
|
132
|
-
}
|
|
132
|
+
const targetMap = input.skipExportsAnalysis ? productionPatternsSkipExports : productionPatterns;
|
|
133
|
+
addPattern(targetMap, input, toWorkspaceRelative(specifier));
|
|
133
134
|
}
|
|
134
135
|
else if (isProject(input)) {
|
|
135
|
-
projectFilePatterns.add(
|
|
136
|
+
projectFilePatterns.add(toWorkspaceRelative(specifier));
|
|
136
137
|
}
|
|
137
138
|
else if (isAlias(input)) {
|
|
138
139
|
principal.addPaths({ [input.specifier]: input.prefixes }, input.dir ?? dir);
|
|
@@ -150,11 +151,11 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
150
151
|
const resolvedFilePath = getReferencedInternalFilePath(input, ws);
|
|
151
152
|
if (resolvedFilePath) {
|
|
152
153
|
if (isDeferResolveProductionEntry(input)) {
|
|
153
|
-
productionPatternsSkipExports
|
|
154
|
+
addPattern(productionPatternsSkipExports, input, resolvedFilePath);
|
|
154
155
|
}
|
|
155
156
|
else if (isDeferResolveEntry(input)) {
|
|
156
157
|
if (!options.isProduction || !input.optional)
|
|
157
|
-
entryPatternsSkipExports
|
|
158
|
+
addPattern(entryPatternsSkipExports, input, resolvedFilePath);
|
|
158
159
|
}
|
|
159
160
|
else {
|
|
160
161
|
principal.addEntryPath(resolvedFilePath, { skipExportsAnalysis: true });
|
|
@@ -162,82 +163,63 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
}
|
|
166
|
+
const negatedEntryPatterns = [];
|
|
165
167
|
if (options.isProduction) {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const workspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, gitignore: false, label });
|
|
171
|
-
principal.addEntryPaths(workspaceEntryPaths);
|
|
168
|
+
for (const map of [entryPatterns, entryPatternsSkipExports]) {
|
|
169
|
+
for (const patterns of map.values())
|
|
170
|
+
for (const pattern of patterns)
|
|
171
|
+
negatedEntryPatterns.push(negate(pattern));
|
|
172
172
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
}
|
|
174
|
+
{
|
|
175
|
+
const patterns = options.isProduction
|
|
176
|
+
? worker.getProductionEntryFilePatterns(negatedEntryPatterns)
|
|
177
|
+
: worker.getEntryFilePatterns();
|
|
178
|
+
const entryPaths = await _glob({ ...sharedGlobOptions, patterns, gitignore: false, label: 'entry paths' });
|
|
179
|
+
if (!options.isProduction) {
|
|
180
|
+
const hints = worker.getConfigurationHints('entry', patterns, entryPaths, principal.entryPaths);
|
|
181
|
+
for (const hint of hints)
|
|
182
|
+
collector.addConfigurationHint(hint);
|
|
178
183
|
}
|
|
184
|
+
principal.addEntryPaths(entryPaths);
|
|
185
|
+
}
|
|
186
|
+
for (const group of groups) {
|
|
179
187
|
{
|
|
180
|
-
const
|
|
181
|
-
|
|
188
|
+
const patterns = worker.getPluginEntryFilePatterns([
|
|
189
|
+
...((!options.isProduction && entryPatterns.get(group)) || []),
|
|
190
|
+
...((!options.isProduction && group === DEFAULT_GROUP && worker.getPluginConfigPatterns()) || []),
|
|
191
|
+
...(productionPatterns.get(group) ?? []),
|
|
192
|
+
]);
|
|
193
|
+
const label = `entry paths from plugins${group !== DEFAULT_GROUP ? ` - ${group}` : ''}`;
|
|
182
194
|
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
183
195
|
principal.addEntryPaths(pluginWorkspaceEntryPaths);
|
|
184
196
|
}
|
|
185
197
|
{
|
|
186
|
-
const label = 'project paths';
|
|
187
|
-
const patterns = worker.getProductionProjectFilePatterns(negatedEntryPatterns);
|
|
188
|
-
const workspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
189
|
-
for (const projectPath of workspaceProjectPaths)
|
|
190
|
-
principal.addProjectPath(projectPath);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
{
|
|
195
|
-
const label = 'entry paths from plugins (ignore exports)';
|
|
196
198
|
const patterns = worker.getPluginEntryFilePatterns([
|
|
197
|
-
...entryPatternsSkipExports,
|
|
198
|
-
...productionPatternsSkipExports,
|
|
199
|
+
...((!options.isProduction && entryPatternsSkipExports.get(group)) || []),
|
|
200
|
+
...(productionPatternsSkipExports.get(group) ?? []),
|
|
199
201
|
]);
|
|
202
|
+
const label = `entry paths from plugins (ignore exports)${group !== DEFAULT_GROUP ? ` - ${group}` : ''}`;
|
|
200
203
|
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
201
204
|
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
202
205
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
for (const hint of hints)
|
|
215
|
-
collector.addConfigurationHint(hint);
|
|
216
|
-
principal.addEntryPaths(entryPaths);
|
|
217
|
-
}
|
|
218
|
-
{
|
|
219
|
-
const label = 'project paths from plugins';
|
|
220
|
-
const patterns = worker.getPluginProjectFilePatterns();
|
|
221
|
-
const pluginWorkspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
222
|
-
for (const projectPath of pluginWorkspaceProjectPaths)
|
|
223
|
-
principal.addProjectPath(projectPath);
|
|
224
|
-
}
|
|
225
|
-
{
|
|
226
|
-
const label = 'plugin configuration paths (ignore exports)';
|
|
227
|
-
const patterns = worker.getPluginConfigPatterns();
|
|
228
|
-
const configurationEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
229
|
-
principal.addEntryPaths(configurationEntryPaths, { skipExportsAnalysis: true });
|
|
230
|
-
}
|
|
231
|
-
{
|
|
232
|
-
const label = 'project paths';
|
|
233
|
-
const patterns = worker.getProjectFilePatterns([...productionPatternsSkipExports, ...projectFilePatterns]);
|
|
234
|
-
const projectPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
206
|
+
}
|
|
207
|
+
{
|
|
208
|
+
const patterns = options.isProduction
|
|
209
|
+
? worker.getProductionProjectFilePatterns(negatedEntryPatterns)
|
|
210
|
+
: worker.getProjectFilePatterns([
|
|
211
|
+
...(productionPatternsSkipExports.get(DEFAULT_GROUP) ?? []),
|
|
212
|
+
...projectFilePatterns,
|
|
213
|
+
...worker.getPluginProjectFilePatterns(),
|
|
214
|
+
]);
|
|
215
|
+
const projectPaths = await _glob({ ...sharedGlobOptions, patterns, label: 'project paths' });
|
|
216
|
+
if (!options.isProduction) {
|
|
235
217
|
const hints = worker.getConfigurationHints('project', config.project, projectPaths, principal.projectPaths);
|
|
236
218
|
for (const hint of hints)
|
|
237
219
|
collector.addConfigurationHint(hint);
|
|
238
|
-
for (const projectPath of projectPaths)
|
|
239
|
-
principal.addProjectPath(projectPath);
|
|
240
220
|
}
|
|
221
|
+
for (const projectPath of projectPaths)
|
|
222
|
+
principal.addProjectPath(projectPath);
|
|
241
223
|
}
|
|
242
224
|
if (options.configFilePath) {
|
|
243
225
|
factory.getPrincipals().at(0)?.addEntryPath(options.configFilePath, { skipExportsAnalysis: true });
|
|
@@ -294,13 +276,15 @@ export async function build({ chief, collector, counselor, deputy, factory, isGi
|
|
|
294
276
|
if (!isIgnored)
|
|
295
277
|
principal.addEntryPath(filePath, { skipExportsAnalysis: true });
|
|
296
278
|
}
|
|
297
|
-
for (const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
principal.
|
|
279
|
+
for (const _import of file.imports.imports) {
|
|
280
|
+
if (_import.filePath) {
|
|
281
|
+
const packageName = getPackageNameFromModuleSpecifier(_import.specifier);
|
|
282
|
+
if (packageName && isInternalWorkspace(packageName)) {
|
|
283
|
+
file.imports.external.add({ ..._import, specifier: packageName });
|
|
284
|
+
const principal = getPrincipalByFilePath(_import.filePath);
|
|
285
|
+
if (principal && !isGitIgnored(_import.filePath)) {
|
|
286
|
+
principal.addNonEntryPath(_import.filePath);
|
|
287
|
+
}
|
|
304
288
|
}
|
|
305
289
|
}
|
|
306
290
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ModuleGraph } from '../types/module-graph.js';
|
|
2
|
+
export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<string>) => {
|
|
3
|
+
isReferenced: (filePath: string, identifier: string, options: {
|
|
4
|
+
includeEntryExports: boolean;
|
|
5
|
+
}) => [boolean, string | undefined];
|
|
6
|
+
hasStrictlyNsReferences: (filePath: string, identifier: string) => [boolean, (string | undefined)?];
|
|
7
|
+
buildExportsTree: (options: {
|
|
8
|
+
filePath?: string;
|
|
9
|
+
identifier?: string;
|
|
10
|
+
}) => import("./operations/build-trace-tree.js").TreeNode[];
|
|
11
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { buildExportsTree } from './operations/build-trace-tree.js';
|
|
2
|
+
import { hasStrictlyNsReferences } from './operations/has-strictly-ns-references.js';
|
|
3
|
+
import { isReferenced } from './operations/is-referenced.js';
|
|
4
|
+
export const createGraphExplorer = (graph, entryPaths) => {
|
|
5
|
+
return {
|
|
6
|
+
isReferenced: (filePath, identifier, options) => isReferenced(graph, entryPaths, filePath, identifier, options),
|
|
7
|
+
hasStrictlyNsReferences: (filePath, identifier) => hasStrictlyNsReferences(graph, graph.get(filePath)?.imported, identifier),
|
|
8
|
+
buildExportsTree: (options) => buildExportsTree(graph, entryPaths, options),
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Identifier, ModuleGraph } from '../../types/module-graph.js';
|
|
2
|
+
export interface TreeNode {
|
|
3
|
+
filePath: string;
|
|
4
|
+
identifier: string;
|
|
5
|
+
hasRef: boolean;
|
|
6
|
+
isEntry: boolean;
|
|
7
|
+
children: TreeNode[];
|
|
8
|
+
}
|
|
9
|
+
export declare const buildExportsTree: (graph: ModuleGraph, entryPaths: Set<string>, options: {
|
|
10
|
+
filePath?: string;
|
|
11
|
+
identifier?: Identifier;
|
|
12
|
+
}) => TreeNode[];
|