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.
Files changed (64) hide show
  1. package/dist/DependencyDeputy.js +2 -2
  2. package/dist/ProjectPrincipal.js +1 -1
  3. package/dist/WorkspaceWorker.js +32 -35
  4. package/dist/binaries/bash-parser.js +14 -1
  5. package/dist/compilers/index.js +1 -1
  6. package/dist/constants.js +1 -0
  7. package/dist/graph/analyze.js +21 -16
  8. package/dist/graph/build.js +71 -87
  9. package/dist/graph-explorer/constants.d.ts +2 -0
  10. package/dist/graph-explorer/constants.js +2 -0
  11. package/dist/graph-explorer/explorer.d.ts +11 -0
  12. package/dist/graph-explorer/explorer.js +10 -0
  13. package/dist/graph-explorer/operations/build-trace-tree.d.ts +12 -0
  14. package/dist/graph-explorer/operations/build-trace-tree.js +51 -0
  15. package/dist/graph-explorer/operations/has-strictly-ns-references.d.ts +2 -0
  16. package/dist/graph-explorer/operations/has-strictly-ns-references.js +98 -0
  17. package/dist/graph-explorer/operations/is-referenced.d.ts +4 -0
  18. package/dist/graph-explorer/operations/is-referenced.js +89 -0
  19. package/dist/graph-explorer/utils.d.ts +4 -0
  20. package/dist/graph-explorer/utils.js +28 -0
  21. package/dist/graph-explorer/visitors.d.ts +12 -0
  22. package/dist/graph-explorer/visitors.js +30 -0
  23. package/dist/graph-explorer/walk-down.d.ts +4 -0
  24. package/dist/graph-explorer/walk-down.js +119 -0
  25. package/dist/index.js +2 -98
  26. package/dist/plugins/angular/index.js +3 -3
  27. package/dist/plugins/astro/index.js +0 -2
  28. package/dist/plugins/next/index.js +4 -3
  29. package/dist/plugins/next/resolveFromAST.d.ts +1 -0
  30. package/dist/plugins/next/resolveFromAST.js +42 -1
  31. package/dist/plugins/vite/helpers.js +1 -1
  32. package/dist/reporters/codeclimate.js +3 -7
  33. package/dist/reporters/util/util.d.ts +2 -1
  34. package/dist/reporters/util/util.js +1 -0
  35. package/dist/reporters/watch.js +1 -1
  36. package/dist/run.d.ts +25 -0
  37. package/dist/run.js +107 -0
  38. package/dist/types/issues.d.ts +4 -4
  39. package/dist/types/module-graph.d.ts +14 -12
  40. package/dist/typescript/ast-helpers.d.ts +4 -0
  41. package/dist/typescript/ast-helpers.js +48 -0
  42. package/dist/typescript/get-imports-and-exports.js +18 -3
  43. package/dist/typescript/visitors/dynamic-imports/importCall.js +5 -19
  44. package/dist/typescript/visitors/dynamic-imports/jsDocType.js +7 -5
  45. package/dist/typescript/visitors/imports/importDeclaration.js +5 -4
  46. package/dist/util/create-options.js +1 -1
  47. package/dist/util/file-entry-cache.js +1 -1
  48. package/dist/util/graph-sequencer.js +1 -1
  49. package/dist/util/input.d.ts +1 -0
  50. package/dist/util/module-graph.js +7 -7
  51. package/dist/util/plugin.d.ts +1 -1
  52. package/dist/util/plugin.js +4 -3
  53. package/dist/util/trace.d.ts +3 -13
  54. package/dist/util/trace.js +10 -41
  55. package/dist/util/watch.d.ts +19 -3
  56. package/dist/util/watch.js +28 -17
  57. package/dist/version.d.ts +1 -1
  58. package/dist/version.js +1 -1
  59. package/package.json +1 -1
  60. package/vendor/bash-parser/index.d.ts +6 -1
  61. package/dist/util/has-strictly-ns-references.d.ts +0 -4
  62. package/dist/util/has-strictly-ns-references.js +0 -103
  63. package/dist/util/is-identifier-referenced.d.ts +0 -9
  64. package/dist/util/is-identifier-referenced.js +0 -145
@@ -16,9 +16,8 @@ export const hasDependency = (dependencies, values) => values.some(value => {
16
16
  return false;
17
17
  });
18
18
  export const normalizePluginConfig = (pluginConfig) => {
19
- if (typeof pluginConfig === 'boolean') {
19
+ if (typeof pluginConfig === 'boolean')
20
20
  return pluginConfig;
21
- }
22
21
  const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
23
22
  const config = isObject
24
23
  ? 'config' in pluginConfig
@@ -28,7 +27,9 @@ export const normalizePluginConfig = (pluginConfig) => {
28
27
  ? arrayify(pluginConfig)
29
28
  : null;
30
29
  const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
31
- const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
30
+ const project = isObject && 'project' in pluginConfig
31
+ ? arrayify(pluginConfig.project)
32
+ : (entry ?? []).filter(pattern => !pattern.startsWith('!'));
32
33
  return { config, entry, project };
33
34
  };
34
35
  export const loadConfigForPlugin = async (configFilePath, plugin, options, pluginName) => {
@@ -1,20 +1,10 @@
1
- import type { ModuleGraph } from '../types/module-graph.js';
2
1
  import type { MainOptions } from './create-options.js';
3
- type CreateNodeOpts = {
4
- identifier?: string;
5
- hasRef?: boolean;
6
- isEntry?: boolean;
7
- };
8
- type Create = (filePath: string, options?: CreateNodeOpts) => TraceNode;
9
- export type TraceNode = {
2
+ type ExplorerTraceNode = {
10
3
  filePath: string;
11
4
  identifier?: string;
12
5
  hasRef: boolean;
13
6
  isEntry: boolean;
14
- children: Set<TraceNode>;
7
+ children: ExplorerTraceNode[];
15
8
  };
16
- export declare const printTrace: (node: TraceNode, filePath: string, options: MainOptions, identifier?: string) => void;
17
- export declare const createNode: Create;
18
- export declare const addNodes: (node: TraceNode, id: string, importedSymbols: ModuleGraph, filePaths?: Set<string>) => void;
19
- export declare const createAndPrintTrace: (filePath: string, options: MainOptions, opts?: CreateNodeOpts) => void;
9
+ export declare const printTraceNode: (node: ExplorerTraceNode, options: MainOptions) => void;
20
10
  export {};
@@ -1,5 +1,5 @@
1
1
  import picocolors from 'picocolors';
2
- import { toAbsolute, toRelative } from './path.js';
2
+ import { toRelative } from './path.js';
3
3
  const IS_ENTRY = ' ◯';
4
4
  const HAS_REF = ' ✓';
5
5
  const HAS_NO_REF = ' x';
@@ -9,62 +9,31 @@ const getPadding = (level, levels) => {
9
9
  padding += levels.has(i) ? `${picocolors.dim('│')} ` : ' ';
10
10
  return padding;
11
11
  };
12
- const renderTrace = (node, options, level = 0, levels = new Set()) => {
12
+ const renderExplorerTrace = (node, options, level = 0, levels = new Set()) => {
13
13
  let index = 0;
14
- const size = node.children.size;
14
+ const size = node.children.length;
15
15
  const padding = getPadding(level, levels);
16
16
  for (const child of node.children) {
17
17
  const isLast = ++index === size;
18
18
  const hasRef = child.hasRef === true;
19
19
  const rel = toRelative(child.filePath, options.cwd);
20
20
  const file = hasRef ? rel : picocolors.dim(rel);
21
- const suffix = (hasRef ? HAS_REF : '') + (child.isEntry ? IS_ENTRY : '');
21
+ const suffix = hasRef ? HAS_REF : '';
22
22
  const text = `${padding}${picocolors.dim(isLast ? '└─' : '├─')} ${file}${suffix}`;
23
23
  console.log(text);
24
- if (child.children.size > 0) {
24
+ if (child.children.length > 0) {
25
25
  if (!isLast)
26
26
  levels.add(level);
27
27
  if (isLast)
28
28
  levels.delete(level);
29
- renderTrace(child, options, level + 1, levels);
29
+ renderExplorerTrace(child, options, level + 1, levels);
30
30
  }
31
31
  }
32
32
  };
33
- export const printTrace = (node, filePath, options, identifier) => {
34
- if (!options.isTrace)
35
- return;
36
- if (options.traceExport && identifier !== options.traceExport)
37
- return;
38
- if (options.traceFile && filePath !== toAbsolute(options.traceFile, options.cwd))
39
- return;
40
- const suffix = (node.isEntry ? IS_ENTRY : '') + (node.children.size === 0 ? HAS_NO_REF : '');
41
- const header = `${toRelative(filePath, options.cwd)}${identifier ? `:${identifier}` : ''}${suffix}`;
33
+ export const printTraceNode = (node, options) => {
34
+ const suffix = (node.isEntry ? IS_ENTRY : '') + (node.children.length === 0 ? HAS_NO_REF : '');
35
+ const header = `${toRelative(node.filePath, options.cwd)}${node.identifier ? `:${node.identifier}` : ''}${suffix}`;
42
36
  console.log(header);
43
- renderTrace(node, options);
37
+ renderExplorerTrace(node, options);
44
38
  console.log();
45
39
  };
46
- export const createNode = (filePath, { hasRef = false, isEntry = false, identifier } = {}) => ({
47
- filePath,
48
- identifier,
49
- hasRef,
50
- isEntry,
51
- children: new Set(),
52
- });
53
- const addNode = (parent, filePath, { hasRef = false, isEntry = false }) => {
54
- const node = createNode(filePath, { hasRef, isEntry });
55
- parent.children.add(node);
56
- return node;
57
- };
58
- export const addNodes = (node, id, importedSymbols, filePaths) => {
59
- if (!filePaths)
60
- return;
61
- for (const filePath of filePaths) {
62
- addNode(node, filePath, { hasRef: Boolean(importedSymbols.get(filePath)?.traceRefs?.has(id)) });
63
- }
64
- };
65
- export const createAndPrintTrace = (filePath, options, opts = {}) => {
66
- if (!options.isTrace)
67
- return;
68
- const traceNode = createNode(filePath, opts);
69
- printTrace(traceNode, filePath, options, opts.identifier);
70
- };
@@ -6,10 +6,16 @@ import type { ProjectPrincipal } from '../ProjectPrincipal.js';
6
6
  import type { Issues } from '../types/issues.js';
7
7
  import type { ModuleGraph } from '../types/module-graph.js';
8
8
  import type { MainOptions } from './create-options.js';
9
- export type OnUpdate = (options: {
9
+ export type OnFileChange = (options: {
10
10
  issues: Issues;
11
11
  duration?: number;
12
+ mem?: number;
12
13
  }) => void;
14
+ type WatchChange = {
15
+ type: 'added' | 'deleted' | 'modified';
16
+ filePath: string;
17
+ };
18
+ export type WatchHandler = Awaited<ReturnType<typeof getWatchHandler>>;
13
19
  type Watch = {
14
20
  analyzedFiles: Set<string>;
15
21
  analyzeSourceFile: (filePath: string, principal: ProjectPrincipal) => void;
@@ -19,8 +25,18 @@ type Watch = {
19
25
  factory: PrincipalFactory;
20
26
  graph: ModuleGraph;
21
27
  isIgnored: (path: string) => boolean;
22
- onUpdate: OnUpdate;
28
+ onFileChange?: OnFileChange;
23
29
  unreferencedFiles: Set<string>;
30
+ entryPaths: Set<string>;
24
31
  };
25
- export declare const getWatchHandler: (options: MainOptions, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onUpdate, unreferencedFiles, }: Watch) => Promise<WatchListener<string | Buffer<ArrayBufferLike>>>;
32
+ export declare const getWatchHandler: (options: MainOptions, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onFileChange, unreferencedFiles, entryPaths, }: Watch) => Promise<{
33
+ listener: WatchListener<string | Buffer<ArrayBufferLike>>;
34
+ handleFileChanges: (changes: WatchChange[]) => Promise<{
35
+ duration: number;
36
+ mem: number;
37
+ }>;
38
+ getEntryPaths: () => Set<string>;
39
+ getGraph: () => ModuleGraph;
40
+ getIssues: () => Issues;
41
+ }>;
26
42
  export {};
@@ -2,18 +2,23 @@ import { debugLog } from './debug.js';
2
2
  import { isFile } from './fs.js';
3
3
  import { updateImportMap } from './module-graph.js';
4
4
  import { join, toAbsolute, toRelative } from './path.js';
5
- export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onUpdate, unreferencedFiles, }) => {
5
+ const createUpdate = (options) => {
6
+ const duration = performance.now() - options.startTime;
7
+ const mem = process.memoryUsage().heapUsed;
8
+ return { duration, mem };
9
+ };
10
+ export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onFileChange, unreferencedFiles, entryPaths, }) => {
6
11
  const getIssues = () => collector.getIssues().issues;
7
- const processBatch = async (changes) => {
12
+ const handleFileChanges = async (changes) => {
8
13
  const startTime = performance.now();
9
14
  const added = new Set();
10
15
  const deleted = new Set();
11
16
  const modified = new Set();
12
- for (const [type, _path] of changes) {
13
- const filePath = toAbsolute(_path, options.cwd);
14
- const relativePath = toRelative(_path, options.cwd);
17
+ for (const change of changes) {
18
+ const filePath = toAbsolute(change.filePath, options.cwd);
19
+ const relativePath = toRelative(change.filePath, options.cwd);
15
20
  if (isIgnored(filePath)) {
16
- debugLog('*', `ignoring ${type} ${relativePath}`);
21
+ debugLog('*', `ignoring ${change.type} ${relativePath}`);
17
22
  continue;
18
23
  }
19
24
  const workspace = chief.findWorkspaceByFilePath(filePath);
@@ -22,7 +27,7 @@ export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFil
22
27
  const principal = factory.getPrincipalByPackageName(workspace.pkgName);
23
28
  if (!principal)
24
29
  continue;
25
- switch (type) {
30
+ switch (change.type) {
26
31
  case 'added':
27
32
  added.add(filePath);
28
33
  principal.addProjectPath(filePath);
@@ -35,7 +40,7 @@ export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFil
35
40
  principal.removeProjectPath(filePath);
36
41
  debugLog(workspace.name, `Watcher: - ${relativePath}`);
37
42
  break;
38
- case 'modified':
43
+ default:
39
44
  modified.add(filePath);
40
45
  debugLog(workspace.name, `Watcher: ± ${relativePath}`);
41
46
  break;
@@ -43,7 +48,7 @@ export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFil
43
48
  principal.invalidateFile(filePath);
44
49
  }
45
50
  if (added.size === 0 && deleted.size === 0 && modified.size === 0)
46
- return;
51
+ return createUpdate({ startTime });
47
52
  unreferencedFiles.clear();
48
53
  const cachedUnusedFiles = collector.purge();
49
54
  for (const filePath of added)
@@ -110,15 +115,21 @@ export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFil
110
115
  collector.addFileCounts({ processed: analyzedFiles.size, unused: unusedFiles.length });
111
116
  for (const issue of collector.getRetainedIssues())
112
117
  collector.addIssue(issue);
113
- onUpdate({ issues: getIssues(), duration: performance.now() - startTime });
118
+ const update = createUpdate({ startTime });
119
+ if (onFileChange)
120
+ onFileChange(Object.assign({ issues: getIssues() }, update));
121
+ return update;
114
122
  };
115
- const listener = (eventType, filename) => {
116
- debugLog('*', `(raw) ${eventType} ${filename}`);
117
- if (typeof filename === 'string') {
118
- const event = eventType === 'rename' ? (isFile(join(options.cwd, filename)) ? 'added' : 'deleted') : 'modified';
119
- processBatch([[event, filename]]);
123
+ const listener = (eventType, filePath) => {
124
+ debugLog('*', `(raw) ${eventType} ${filePath}`);
125
+ if (typeof filePath === 'string') {
126
+ const type = eventType === 'rename' ? (isFile(join(options.cwd, filePath)) ? 'added' : 'deleted') : 'modified';
127
+ handleFileChanges([{ type, filePath }]);
120
128
  }
121
129
  };
122
- onUpdate({ issues: getIssues() });
123
- return listener;
130
+ if (onFileChange)
131
+ onFileChange({ issues: getIssues() });
132
+ const getEntryPaths = () => entryPaths;
133
+ const getGraph = () => graph;
134
+ return { listener, handleFileChanges, getEntryPaths, getGraph, getIssues };
124
135
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.70.1";
1
+ export declare const version = "5.71.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.70.1';
1
+ export const version = '5.71.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.70.1",
3
+ "version": "5.71.0",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {
@@ -43,6 +43,11 @@ type Function_ = {
43
43
  body: CompoundList;
44
44
  };
45
45
 
46
+ type Subshell = {
47
+ type: 'Subshell';
48
+ list: CompoundList;
49
+ };
50
+
46
51
  export type ExpansionNode = {
47
52
  expansion: Expansion[];
48
53
  };
@@ -62,7 +67,7 @@ export type Assignment = {
62
67
  text: string;
63
68
  };
64
69
 
65
- export type Node = CompoundList | Command | LogicalExpression | If | For | Function_ | Pipeline;
70
+ export type Node = CompoundList | Command | LogicalExpression | If | For | Function_ | Pipeline | Subshell;
66
71
 
67
72
  export type AST = {
68
73
  type: 'Script';
@@ -1,4 +0,0 @@
1
- import type { ImportMaps, ModuleGraph } from '../types/module-graph.js';
2
- export declare const hasStrictlyEnumReferences: (importsForExport: ImportMaps | undefined, id: string) => boolean;
3
- export declare const hasStrictlyNsReferences: (graph: ModuleGraph, importsForExport: ImportMaps | undefined, id: string) => [boolean, string?];
4
- export declare const getType: (hasOnlyNsReference: boolean, isType: boolean) => "exports" | "nsExports" | "types" | "nsTypes";
@@ -1,103 +0,0 @@
1
- import { IMPORT_STAR } from '../constants.js';
2
- export const hasStrictlyEnumReferences = (importsForExport, id) => {
3
- if (!importsForExport || !importsForExport.refs.has(id))
4
- return false;
5
- for (const ref of importsForExport.refs)
6
- if (ref.startsWith(`${id}.`))
7
- return false;
8
- return true;
9
- };
10
- export const hasStrictlyNsReferences = (graph, importsForExport, id) => {
11
- if (!importsForExport)
12
- return [false];
13
- let namespace;
14
- for (const ns of importsForExport.importedNs.keys()) {
15
- const hasNs = importsForExport.refs.has(ns);
16
- if (!hasNs)
17
- return [false, ns];
18
- for (const id of importsForExport.refs)
19
- if (id.startsWith(`${ns}.`))
20
- return [false, ns];
21
- const byFilePaths = importsForExport.reExportedNs.get(ns);
22
- if (byFilePaths) {
23
- for (const filePath of byFilePaths) {
24
- const file = graph.get(filePath);
25
- if (file?.imported) {
26
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, id);
27
- if (hasStrictlyNsRefs[0] === false)
28
- return hasStrictlyNsRefs;
29
- }
30
- }
31
- }
32
- const reExportedAs = importsForExport.reExportedAs.get(ns);
33
- if (reExportedAs) {
34
- for (const byFilePaths of reExportedAs.values()) {
35
- for (const filePath of byFilePaths) {
36
- const file = graph.get(filePath);
37
- if (file?.imported) {
38
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, id);
39
- if (hasStrictlyNsRefs[0] === false)
40
- return hasStrictlyNsRefs;
41
- }
42
- }
43
- }
44
- }
45
- namespace = ns;
46
- }
47
- const byFilePaths = importsForExport.reExported.get(id);
48
- if (byFilePaths) {
49
- for (const filePath of byFilePaths) {
50
- const file = graph.get(filePath);
51
- if (file?.imported) {
52
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, id);
53
- if (hasStrictlyNsRefs[0] === false)
54
- return hasStrictlyNsRefs;
55
- namespace = hasStrictlyNsRefs[1];
56
- }
57
- }
58
- }
59
- {
60
- const byFilePaths = importsForExport.reExported.get(IMPORT_STAR);
61
- if (byFilePaths) {
62
- for (const filePath of byFilePaths) {
63
- const file = graph.get(filePath);
64
- if (file?.imported) {
65
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, id);
66
- if (hasStrictlyNsRefs[0] === false)
67
- return hasStrictlyNsRefs;
68
- namespace = hasStrictlyNsRefs[1];
69
- }
70
- }
71
- }
72
- }
73
- const [identifier, ...rest] = id.split('.');
74
- const reExportedAs = importsForExport.reExportedAs.get(identifier);
75
- if (reExportedAs) {
76
- for (const [alias, filePaths] of reExportedAs.entries()) {
77
- for (const filePath of filePaths) {
78
- const file = graph.get(filePath);
79
- if (file?.imported) {
80
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, [alias, ...rest].join('.'));
81
- if (hasStrictlyNsRefs[0] === false)
82
- return hasStrictlyNsRefs;
83
- namespace = hasStrictlyNsRefs[1];
84
- }
85
- }
86
- }
87
- }
88
- for (const [ns, filePaths] of importsForExport.reExportedNs.entries()) {
89
- for (const filePath of filePaths) {
90
- const file = graph.get(filePath);
91
- if (file?.imported) {
92
- const hasStrictlyNsRefs = hasStrictlyNsReferences(graph, file.imported, `${ns}.${id}`);
93
- if (hasStrictlyNsRefs[0] === false)
94
- return hasStrictlyNsRefs;
95
- namespace = hasStrictlyNsRefs[1];
96
- }
97
- }
98
- }
99
- if (namespace)
100
- return [true, namespace];
101
- return [false];
102
- };
103
- export const getType = (hasOnlyNsReference, isType) => hasOnlyNsReference ? (isType ? 'nsTypes' : 'nsExports') : isType ? 'types' : 'exports';
@@ -1,9 +0,0 @@
1
- import type { ModuleGraph } from '../types/module-graph.js';
2
- import { type TraceNode } from './trace.js';
3
- type Result = {
4
- isReferenced: boolean;
5
- reExportingEntryFile: undefined | string;
6
- traceNode: TraceNode;
7
- };
8
- export declare const getIsIdentifierReferencedHandler: (graph: ModuleGraph, entryPaths: Set<string>, isTrace: boolean) => (filePath: string, id: string, isIncludeEntryExports?: boolean, traceNode?: TraceNode, seen?: Set<string>) => Result;
9
- export {};
@@ -1,145 +0,0 @@
1
- import { IMPORT_STAR, OPAQUE } from '../constants.js';
2
- import { addNodes, createNode } from './trace.js';
3
- export const getIsIdentifierReferencedHandler = (graph, entryPaths, isTrace) => {
4
- const isIdentifierReferenced = (filePath, id, isIncludeEntryExports = false, traceNode = createNode(filePath), seen = new Set()) => {
5
- let isReferenced = false;
6
- let reExportingEntryFile = entryPaths.has(filePath) ? filePath : undefined;
7
- if (reExportingEntryFile)
8
- traceNode.isEntry = true;
9
- if (!isIncludeEntryExports && reExportingEntryFile)
10
- return { isReferenced, reExportingEntryFile, traceNode };
11
- seen.add(filePath);
12
- const restIds = id.split('.');
13
- const identifier = restIds.shift();
14
- const file = graph.get(filePath)?.imported;
15
- if (!identifier || !file)
16
- return { isReferenced, reExportingEntryFile, traceNode };
17
- if (file.imported.get(OPAQUE) ||
18
- ((identifier === id || (identifier !== id && file.refs.has(id))) &&
19
- (file.imported.has(identifier) || file.importedAs.has(identifier)))) {
20
- isReferenced = true;
21
- if (!isTrace)
22
- return { isReferenced, reExportingEntryFile, traceNode };
23
- if (file.importedAs.has(identifier)) {
24
- for (const aliases of file.importedAs.values()) {
25
- for (const alias of aliases.keys())
26
- addNodes(traceNode, alias, graph, aliases.get(alias));
27
- }
28
- }
29
- else
30
- addNodes(traceNode, id, graph, file.imported.get(identifier));
31
- }
32
- for (const [exportId, aliases] of file.importedAs.entries()) {
33
- if (identifier === exportId) {
34
- for (const alias of aliases.keys()) {
35
- const aliasedRef = [alias, ...restIds].join('.');
36
- if (file.refs.has(aliasedRef)) {
37
- isReferenced = true;
38
- if (!isTrace)
39
- return { isReferenced, reExportingEntryFile, traceNode };
40
- addNodes(traceNode, aliasedRef, graph, aliases.get(alias));
41
- }
42
- }
43
- }
44
- }
45
- for (const [namespace, byFilePaths] of file.importedNs) {
46
- if (file.refs.has(`${namespace}.${id}`)) {
47
- isReferenced = true;
48
- if (!isTrace)
49
- return { isReferenced, reExportingEntryFile, traceNode };
50
- addNodes(traceNode, `${namespace}.${id}`, graph, byFilePaths);
51
- }
52
- const reExportedAs = file.reExportedAs.get(namespace);
53
- if (reExportedAs) {
54
- for (const [alias, byFilePaths] of reExportedAs) {
55
- for (const byFilePath of byFilePaths) {
56
- if (!seen.has(byFilePath)) {
57
- const child = createNode(byFilePath);
58
- traceNode.children.add(child);
59
- const result = isIdentifierReferenced(byFilePath, `${alias}.${id}`, isIncludeEntryExports, child, seen);
60
- if (result.reExportingEntryFile)
61
- reExportingEntryFile = result.reExportingEntryFile;
62
- if (result.isReferenced) {
63
- isReferenced = true;
64
- if (!isTrace)
65
- return { isReferenced, reExportingEntryFile, traceNode };
66
- }
67
- }
68
- }
69
- }
70
- }
71
- const reExportedNs = file.reExportedNs.get(namespace);
72
- if (reExportedNs) {
73
- for (const byFilePath of reExportedNs) {
74
- if (!seen.has(byFilePath)) {
75
- const child = createNode(byFilePath);
76
- traceNode.children.add(child);
77
- const result = isIdentifierReferenced(byFilePath, `${namespace}.${id}`, isIncludeEntryExports, child, seen);
78
- if (result.reExportingEntryFile)
79
- reExportingEntryFile = result.reExportingEntryFile;
80
- if (result.isReferenced) {
81
- isReferenced = true;
82
- if (!isTrace)
83
- return { isReferenced, reExportingEntryFile, traceNode };
84
- }
85
- }
86
- }
87
- }
88
- }
89
- const reExportedAs = file.reExportedAs.get(identifier);
90
- if (reExportedAs) {
91
- for (const [alias, byFilePaths] of reExportedAs) {
92
- for (const byFilePath of byFilePaths) {
93
- if (!seen.has(byFilePath)) {
94
- const child = createNode(byFilePath);
95
- traceNode.children.add(child);
96
- const ref = [alias, ...restIds].join('.');
97
- const result = isIdentifierReferenced(byFilePath, ref, isIncludeEntryExports, child, seen);
98
- if (result.reExportingEntryFile)
99
- reExportingEntryFile = result.reExportingEntryFile;
100
- if (result.isReferenced) {
101
- isReferenced = true;
102
- if (!isTrace)
103
- return { isReferenced, reExportingEntryFile, traceNode };
104
- }
105
- }
106
- }
107
- }
108
- }
109
- const reExported = file.reExported.get(identifier) ?? file.reExported.get(IMPORT_STAR);
110
- if (reExported) {
111
- for (const byFilePath of reExported) {
112
- if (!seen.has(byFilePath)) {
113
- const child = createNode(byFilePath);
114
- traceNode.children.add(child);
115
- const result = isIdentifierReferenced(byFilePath, id, isIncludeEntryExports, child, seen);
116
- if (result.reExportingEntryFile)
117
- reExportingEntryFile = result.reExportingEntryFile;
118
- if (result.isReferenced) {
119
- isReferenced = true;
120
- if (!isTrace)
121
- return { isReferenced, reExportingEntryFile, traceNode };
122
- }
123
- }
124
- }
125
- }
126
- for (const [namespace, byFilePaths] of file.reExportedNs.entries()) {
127
- for (const byFilePath of byFilePaths) {
128
- if (!seen.has(byFilePath)) {
129
- const child = createNode(byFilePath);
130
- traceNode.children.add(child);
131
- const result = isIdentifierReferenced(byFilePath, `${namespace}.${id}`, isIncludeEntryExports, child, seen);
132
- if (result.reExportingEntryFile)
133
- reExportingEntryFile = result.reExportingEntryFile;
134
- if (result.isReferenced) {
135
- isReferenced = true;
136
- if (!isTrace)
137
- return { isReferenced, reExportingEntryFile, traceNode };
138
- }
139
- }
140
- }
141
- }
142
- return { isReferenced, reExportingEntryFile, traceNode };
143
- };
144
- return isIdentifierReferenced;
145
- };