knip 6.13.0 → 6.14.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 (53) hide show
  1. package/dist/CacheConsultant.d.ts +3 -3
  2. package/dist/CacheConsultant.js +13 -16
  3. package/dist/ConfigurationChief.d.ts +1 -0
  4. package/dist/ConfigurationChief.js +11 -2
  5. package/dist/DependencyDeputy.d.ts +3 -0
  6. package/dist/DependencyDeputy.js +28 -8
  7. package/dist/ProjectPrincipal.d.ts +1 -0
  8. package/dist/ProjectPrincipal.js +43 -52
  9. package/dist/WorkspaceWorker.js +3 -3
  10. package/dist/cli.js +1 -1
  11. package/dist/graph/analyze.js +4 -3
  12. package/dist/graph/build.js +1 -0
  13. package/dist/graph-explorer/explorer.d.ts +2 -1
  14. package/dist/graph-explorer/operations/is-referenced.d.ts +2 -1
  15. package/dist/graph-explorer/operations/is-referenced.js +6 -3
  16. package/dist/plugins/docusaurus/helpers.js +12 -5
  17. package/dist/plugins/docusaurus/index.js +2 -1
  18. package/dist/plugins/hardhat/index.js +1 -1
  19. package/dist/plugins/jest/index.js +1 -1
  20. package/dist/plugins/nitro/index.js +1 -1
  21. package/dist/plugins/nuxt/helpers.js +3 -3
  22. package/dist/plugins/nuxt/index.js +1 -1
  23. package/dist/plugins/nx/index.js +8 -2
  24. package/dist/plugins/sst/resolveFromAST.js +2 -2
  25. package/dist/plugins/tailwind/index.js +1 -1
  26. package/dist/plugins/wxt/index.js +1 -1
  27. package/dist/reporters/trace.js +6 -2
  28. package/dist/run.js +7 -2
  29. package/dist/typescript/ast-helpers.js +2 -2
  30. package/dist/typescript/ast-nodes.d.ts +1 -1
  31. package/dist/typescript/ast-nodes.js +3 -1
  32. package/dist/typescript/get-imports-and-exports.js +4 -4
  33. package/dist/typescript/visitors/walk.d.ts +2 -1
  34. package/dist/typescript/visitors/walk.js +3 -1
  35. package/dist/util/Performance.d.ts +3 -1
  36. package/dist/util/Performance.js +6 -2
  37. package/dist/util/cli-arguments.d.ts +2 -1
  38. package/dist/util/cli-arguments.js +52 -50
  39. package/dist/util/disk-cache.d.ts +10 -0
  40. package/dist/util/disk-cache.js +62 -0
  41. package/dist/util/file-entry-cache.d.ts +0 -7
  42. package/dist/util/file-entry-cache.js +15 -53
  43. package/dist/util/gitignore-cache.d.ts +12 -0
  44. package/dist/util/gitignore-cache.js +77 -0
  45. package/dist/util/glob-cache.d.ts +2 -2
  46. package/dist/util/glob-cache.js +9 -57
  47. package/dist/util/glob-core.d.ts +4 -0
  48. package/dist/util/glob-core.js +14 -1
  49. package/dist/util/glob.js +12 -6
  50. package/dist/util/module-graph.js +17 -13
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  import type { MainOptions } from './util/create-options.ts';
2
2
  import { type FileDescriptor } from './util/file-entry-cache.ts';
3
3
  export declare class CacheConsultant<T> {
4
- private isEnabled;
5
4
  private cache;
5
+ getFileDescriptor: (filePath: string) => FileDescriptor<T>;
6
+ reconcile: () => void;
6
7
  constructor(name: string, options: MainOptions);
7
- getFileDescriptor(filePath: string): FileDescriptor<T>;
8
- reconcile(): void;
8
+ getCachedFile(filePath: string): T | undefined;
9
9
  }
@@ -3,24 +3,21 @@ import { timerify } from './util/Performance.js';
3
3
  import { version } from './version.js';
4
4
  const dummyFileDescriptor = { key: '', changed: true, notFound: true };
5
5
  export class CacheConsultant {
6
- isEnabled;
7
6
  cache;
7
+ getFileDescriptor = () => dummyFileDescriptor;
8
+ reconcile = () => { };
8
9
  constructor(name, options) {
9
- this.isEnabled = options.isCache;
10
- if (this.isEnabled) {
11
- const cacheName = `${name.replace(/[^a-z0-9]/g, '-').replace(/-*$/, '')}-${options.isProduction ? '-prod' : ''}-${version}`;
12
- this.cache = new FileEntryCache(cacheName, options.cacheLocation);
13
- this.reconcile = timerify(this.cache.reconcile).bind(this.cache);
14
- this.getFileDescriptor = timerify(this.cache.getFileDescriptor).bind(this.cache);
15
- }
10
+ if (!options.isCache)
11
+ return;
12
+ const cacheName = `${name.replace(/[^a-z0-9]/g, '-').replace(/-*$/, '')}-${options.isProduction ? '-prod' : ''}-${version}`;
13
+ this.cache = new FileEntryCache(cacheName, options.cacheLocation);
14
+ this.getFileDescriptor = timerify(this.cache.getFileDescriptor.bind(this.cache));
15
+ this.reconcile = timerify(this.cache.reconcile.bind(this.cache));
16
16
  }
17
- getFileDescriptor(filePath) {
18
- if (this.isEnabled && this.cache)
19
- return this.cache.getFileDescriptor(filePath);
20
- return dummyFileDescriptor;
21
- }
22
- reconcile() {
23
- if (this.isEnabled && this.cache)
24
- this.cache.reconcile();
17
+ getCachedFile(filePath) {
18
+ if (!this.cache)
19
+ return undefined;
20
+ const fd = this.cache.getFileDescriptor(filePath);
21
+ return !fd.changed ? fd.meta?.data : undefined;
25
22
  }
26
23
  }
@@ -35,6 +35,7 @@ export declare class ConfigurationChief {
35
35
  availableWorkspaceNames: string[];
36
36
  availableWorkspacePkgNames: Set<string>;
37
37
  availableWorkspaceDirs: string[];
38
+ private availableWorkspaceDirsWithSlash;
38
39
  workspaceGraph: WorkspaceGraph;
39
40
  private workspaceByFileCache;
40
41
  constructor(options: MainOptions);
@@ -8,6 +8,7 @@ import { _dirGlob, removeProductionSuffix } from './util/glob.js';
8
8
  import { graphSequencer } from './util/graph-sequencer.js';
9
9
  import mapWorkspaces from './util/map-workspaces.js';
10
10
  import { join, relative } from './util/path.js';
11
+ import { timerify } from './util/Performance.js';
11
12
  import { normalizePluginConfig } from './util/plugin.js';
12
13
  import { toRegexOrString } from './util/regex.js';
13
14
  import { ELLIPSIS } from './util/string.js';
@@ -63,6 +64,7 @@ export class ConfigurationChief {
63
64
  availableWorkspaceNames = [];
64
65
  availableWorkspacePkgNames = new Set();
65
66
  availableWorkspaceDirs = [];
67
+ availableWorkspaceDirsWithSlash = [];
66
68
  workspaceGraph = new Map();
67
69
  workspaceByFileCache = new Map();
68
70
  constructor(options) {
@@ -74,6 +76,7 @@ export class ConfigurationChief {
74
76
  this.workspaces = options.workspaces;
75
77
  this.rawConfig = options.parsedConfig;
76
78
  this.config = this.normalize(options.parsedConfig ?? {});
79
+ this.findWorkspaceByFilePath = timerify(this.findWorkspaceByFilePath.bind(this), 'findWorkspaceByFilePath');
77
80
  }
78
81
  getConfigurationHints() {
79
82
  const hints = [];
@@ -139,6 +142,7 @@ export class ConfigurationChief {
139
142
  .sort(byPathDepth)
140
143
  .reverse()
141
144
  .map(dir => join(this.cwd, dir));
145
+ this.availableWorkspaceDirsWithSlash = this.availableWorkspaceDirs.map(dir => `${dir}/`);
142
146
  this.workspaceGraph = createWorkspaceGraph(this.cwd, this.availableWorkspaceNames, wsPkgNames, packages);
143
147
  this.selectedWorkspaces = this.getSelectedWorkspaces();
144
148
  this.workspaceFilePathFilter = createWorkspaceFilePathFilter(this.cwd, this.selectedWorkspaces, this.availableWorkspaceNames);
@@ -347,8 +351,13 @@ export class ConfigurationChief {
347
351
  findWorkspaceByFilePath(filePath) {
348
352
  if (this.workspaceByFileCache.has(filePath))
349
353
  return this.workspaceByFileCache.get(filePath);
350
- const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(`${workspaceDir}/`));
351
- const workspace = workspaceDir ? this.workspacesByDir.get(workspaceDir) : undefined;
354
+ let workspace;
355
+ for (let i = 0; i < this.availableWorkspaceDirsWithSlash.length; i++) {
356
+ if (filePath.startsWith(this.availableWorkspaceDirsWithSlash[i])) {
357
+ workspace = this.workspacesByDir.get(this.availableWorkspaceDirs[i]);
358
+ break;
359
+ }
360
+ }
352
361
  this.workspaceByFileCache.set(filePath, workspace);
353
362
  return workspace;
354
363
  }
@@ -8,6 +8,7 @@ export declare class DependencyDeputy {
8
8
  isStrict: boolean;
9
9
  isReportDependencies: boolean;
10
10
  _manifests: WorkspaceManifests;
11
+ workspacePkgNames: Set<string>;
11
12
  referencedDependencies: Map<string, Set<string>>;
12
13
  referencedBinaries: Map<string, Set<string>>;
13
14
  hostDependencies: Map<string, HostDependencies>;
@@ -43,8 +44,10 @@ export declare class DependencyDeputy {
43
44
  unusedIgnoreBinaries: Set<string | RegExp>;
44
45
  unusedIgnoreUnresolved: Set<string | RegExp>;
45
46
  } | undefined;
47
+ setWorkspacePkgNames(pkgNames: Iterable<string>): void;
46
48
  getProductionDependencies(workspaceName: string): DependencyArray;
47
49
  getDevDependencies(workspaceName: string): DependencyArray;
50
+ private dependencyCache;
48
51
  getDependencies(workspaceName: string): DependencySet;
49
52
  setInstalledBinaries(workspaceName: string, installedBinaries: Map<string, Set<string>>): void;
50
53
  getInstalledBinaries(workspaceName: string): InstalledBinaries | undefined;
@@ -10,6 +10,7 @@ export class DependencyDeputy {
10
10
  isStrict;
11
11
  isReportDependencies;
12
12
  _manifests = new Map();
13
+ workspacePkgNames = new Set();
13
14
  referencedDependencies;
14
15
  referencedBinaries;
15
16
  hostDependencies;
@@ -39,11 +40,7 @@ export class DependencyDeputy {
39
40
  const requiredPeerDependencies = peerDependencies.filter(dep => !optionalPeerDependencies.has(dep));
40
41
  const devDependencies = Object.keys(manifest.devDependencies ?? {});
41
42
  const allDependencies = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];
42
- const packageNames = [
43
- ...dependencies,
44
- ...(this.isStrict ? peerDependencies : []),
45
- ...(this.isProduction ? [] : devDependencies),
46
- ];
43
+ const packageNames = [...dependencies, ...peerDependencies, ...(this.isProduction ? [] : devDependencies)];
47
44
  if (this.isReportDependencies) {
48
45
  const { hostDependencies, installedBinaries, hasTypesIncluded } = getDependencyMetaData({
49
46
  packageNames,
@@ -79,6 +76,9 @@ export class DependencyDeputy {
79
76
  getWorkspaceManifest(workspaceName) {
80
77
  return this._manifests.get(workspaceName);
81
78
  }
79
+ setWorkspacePkgNames(pkgNames) {
80
+ this.workspacePkgNames = new Set(pkgNames);
81
+ }
82
82
  getProductionDependencies(workspaceName) {
83
83
  const manifest = this._manifests.get(workspaceName);
84
84
  if (!manifest)
@@ -90,11 +90,15 @@ export class DependencyDeputy {
90
90
  getDevDependencies(workspaceName) {
91
91
  return this._manifests.get(workspaceName)?.devDependencies ?? [];
92
92
  }
93
+ dependencyCache = new Map();
93
94
  getDependencies(workspaceName) {
95
+ let deps = this.dependencyCache.get(workspaceName);
96
+ if (deps)
97
+ return deps;
94
98
  const manifest = this._manifests.get(workspaceName);
95
- if (!manifest)
96
- return new Set();
97
- return new Set([...manifest.dependencies, ...manifest.devDependencies]);
99
+ deps = manifest ? new Set([...manifest.dependencies, ...manifest.devDependencies]) : new Set();
100
+ this.dependencyCache.set(workspaceName, deps);
101
+ return deps;
98
102
  }
99
103
  setInstalledBinaries(workspaceName, installedBinaries) {
100
104
  this.installedBinaries.set(workspaceName, installedBinaries);
@@ -153,6 +157,22 @@ export class DependencyDeputy {
153
157
  return true;
154
158
  if (this._manifests.get(workspace.name)?.engines[packageName])
155
159
  return true;
160
+ if (!this.isStrict && this.workspacePkgNames.has(packageName)) {
161
+ this.addReferencedDependency(workspace.name, packageName);
162
+ return true;
163
+ }
164
+ if (!this.isStrict) {
165
+ for (const name of workspaceNames) {
166
+ const hosts = this.getHostDependenciesFor(name, packageName);
167
+ if (hosts.length === 0)
168
+ continue;
169
+ const m = this._manifests.get(name);
170
+ if (m && hosts.some(h => m.allDependencies.has(h.name))) {
171
+ this.addReferencedDependency(name, packageName);
172
+ return true;
173
+ }
174
+ }
175
+ }
156
176
  this.addReferencedDependency(workspace.name, packageName);
157
177
  return false;
158
178
  }
@@ -27,6 +27,7 @@ export declare class ProjectPrincipal {
27
27
  private resolveModule;
28
28
  resolvedFiles: Set<string>;
29
29
  deletedFiles: Set<string>;
30
+ private onPathAdded;
30
31
  constructor(options: MainOptions, toSourceFilePath: ToSourceFilePath, findWorkspaceManifestImports?: WorkspaceManifestHandler);
31
32
  addCompilers(compilers: [SyncCompilers, AsyncCompilers]): void;
32
33
  addPaths(paths: Paths, basePath: string): void;
@@ -1,5 +1,5 @@
1
1
  import { extractSpecifiers } from './typescript/follow-imports.js';
2
- import { parseFile } from './typescript/ast-nodes.js';
2
+ import { _parseFile } from './typescript/ast-nodes.js';
3
3
  import { CacheConsultant } from './CacheConsultant.js';
4
4
  import { getCompilerExtensions } from './compilers/index.js';
5
5
  import { DEFAULT_EXTENSIONS } from './constants.js';
@@ -36,6 +36,7 @@ export class ProjectPrincipal {
36
36
  resolveModule = () => undefined;
37
37
  resolvedFiles = new Set();
38
38
  deletedFiles = new Set();
39
+ onPathAdded;
39
40
  constructor(options, toSourceFilePath, findWorkspaceManifestImports) {
40
41
  this.cache = new CacheConsultant('root', options);
41
42
  this.toSourceFilePath = toSourceFilePath;
@@ -44,6 +45,7 @@ export class ProjectPrincipal {
44
45
  this.fileManager = new SourceFileManager({
45
46
  compilers: [this.syncCompilers, this.asyncCompilers],
46
47
  });
48
+ this.walkAndAnalyze = timerify(this.walkAndAnalyze.bind(this), 'walkAndAnalyze');
47
49
  }
48
50
  addCompilers(compilers) {
49
51
  for (const [ext, compiler] of compilers[0]) {
@@ -100,6 +102,7 @@ export class ProjectPrincipal {
100
102
  this.projectPaths.add(filePath);
101
103
  if (options?.skipExportsAnalysis)
102
104
  this.skipExportsAnalysis.add(filePath);
105
+ this.onPathAdded?.(filePath);
103
106
  }
104
107
  }
105
108
  addEntryPaths(filePaths, options) {
@@ -109,6 +112,7 @@ export class ProjectPrincipal {
109
112
  addProgramPath(filePath) {
110
113
  if (!isInNodeModules(filePath) && this.hasAcceptedExtension(filePath)) {
111
114
  this.programPaths.add(filePath);
115
+ this.onPathAdded?.(filePath);
112
116
  }
113
117
  }
114
118
  addProjectPath(filePath) {
@@ -134,61 +138,48 @@ export class ProjectPrincipal {
134
138
  walkAndAnalyze(analyzeFile) {
135
139
  this.resolvedFiles.clear();
136
140
  const visited = new Set([...this.entryPaths, ...this.programPaths]);
137
- let lastEntrySize = this.entryPaths.size;
138
- let lastProgramSize = this.programPaths.size;
139
- const rescanFrontier = () => {
140
- if (this.entryPaths.size > lastEntrySize || this.programPaths.size > lastProgramSize) {
141
- for (const p of this.entryPaths)
142
- visited.add(p);
143
- for (const p of this.programPaths)
144
- visited.add(p);
145
- lastEntrySize = this.entryPaths.size;
146
- lastProgramSize = this.programPaths.size;
147
- }
148
- };
149
- for (const filePath of visited) {
150
- const isProjectPath = this.projectPaths.has(filePath);
151
- let cachedFile;
152
- if (isProjectPath) {
153
- const fd = this.cache.getFileDescriptor(filePath);
154
- if (!fd.changed && fd.meta?.data)
155
- cachedFile = fd.meta.data;
156
- }
157
- if (cachedFile) {
158
- const internalPaths = analyzeFile(filePath, undefined, '', cachedFile);
159
- if (internalPaths)
160
- for (const p of internalPaths)
161
- visited.add(p);
162
- rescanFrontier();
163
- continue;
164
- }
165
- const sourceText = this.fileManager.readFile(filePath);
166
- if (!sourceText) {
167
- if (isProjectPath)
168
- analyzeFile(filePath, undefined, '');
169
- continue;
170
- }
171
- try {
172
- const result = parseFile(filePath, sourceText);
173
- this.fileManager.sourceTextCache.delete(filePath);
174
- if (isProjectPath) {
175
- const internalPaths = analyzeFile(filePath, result, sourceText);
141
+ this.onPathAdded = p => visited.add(p);
142
+ try {
143
+ for (const filePath of visited) {
144
+ const isProjectPath = this.projectPaths.has(filePath);
145
+ const cachedFile = isProjectPath ? this.cache.getCachedFile(filePath) : undefined;
146
+ if (cachedFile) {
147
+ const internalPaths = analyzeFile(filePath, undefined, '', cachedFile);
176
148
  if (internalPaths)
177
149
  for (const p of internalPaths)
178
150
  visited.add(p);
151
+ continue;
152
+ }
153
+ const sourceText = this.fileManager.readFile(filePath);
154
+ if (!sourceText) {
155
+ if (isProjectPath)
156
+ analyzeFile(filePath, undefined, '');
157
+ continue;
179
158
  }
180
- else {
181
- for (const specifier of extractSpecifiers(result, sourceText, filePath)) {
182
- const resolved = this.resolveSpecifier(specifier, filePath);
183
- if (resolved && !isInNodeModules(resolved))
184
- visited.add(resolved);
159
+ try {
160
+ const result = _parseFile(filePath, sourceText);
161
+ this.fileManager.sourceTextCache.delete(filePath);
162
+ if (isProjectPath) {
163
+ const internalPaths = analyzeFile(filePath, result, sourceText);
164
+ if (internalPaths)
165
+ for (const p of internalPaths)
166
+ visited.add(p);
167
+ }
168
+ else {
169
+ for (const specifier of extractSpecifiers(result, sourceText, filePath)) {
170
+ const resolved = this.resolveSpecifier(specifier, filePath);
171
+ if (resolved && !isInNodeModules(resolved))
172
+ visited.add(resolved);
173
+ }
185
174
  }
186
175
  }
187
- rescanFrontier();
188
- }
189
- catch {
176
+ catch {
177
+ }
190
178
  }
191
179
  }
180
+ finally {
181
+ this.onPathAdded = undefined;
182
+ }
192
183
  this.resolvedFiles = visited;
193
184
  }
194
185
  getUsedResolvedFiles() {
@@ -199,7 +190,7 @@ export class ProjectPrincipal {
199
190
  if (!sourceText)
200
191
  continue;
201
192
  try {
202
- const result = parseFile(filePath, sourceText);
193
+ const result = _parseFile(filePath, sourceText);
203
194
  for (const specifier of extractSpecifiers(result, sourceText, filePath)) {
204
195
  const resolved = this.resolveSpecifier(specifier, filePath);
205
196
  if (resolved && !isInNodeModules(resolved))
@@ -221,9 +212,9 @@ export class ProjectPrincipal {
221
212
  analyzeSourceFile(filePath, options, ignoreExportsUsedInFile, parseResult, sourceText, cachedFile) {
222
213
  if (cachedFile)
223
214
  return cachedFile;
224
- const fd = this.cache.getFileDescriptor(filePath);
225
- if (!fd.changed && fd.meta?.data)
226
- return fd.meta.data;
215
+ const cached = this.cache.getCachedFile(filePath);
216
+ if (cached)
217
+ return cached;
227
218
  sourceText ??= this.fileManager.readFile(filePath);
228
219
  const skipExports = this.skipExportsAnalysis.has(filePath);
229
220
  if (options.isFixExports || options.isFixTypes) {
@@ -7,7 +7,7 @@ import { getFilteredScripts } from './manifest/helpers.js';
7
7
  import { PluginEntries, Plugins } from './plugins.js';
8
8
  import { createManifest } from './util/package-json.js';
9
9
  import { collectStringLiterals, isExternalReExportsOnly } from './typescript/ast-helpers.js';
10
- import { parseFile } from './typescript/ast-nodes.js';
10
+ import { _parseFile } from './typescript/ast-nodes.js';
11
11
  import { compact } from './util/array.js';
12
12
  import { debugLogArray, debugLogObject } from './util/debug.js';
13
13
  import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './util/glob.js';
@@ -57,7 +57,7 @@ export class WorkspaceWorker {
57
57
  this.readFile = readFile;
58
58
  this.options = options;
59
59
  this.cache = new CacheConsultant(`plugins-${name}`, options);
60
- this.getConfigurationHints = timerify(this.getConfigurationHints.bind(this), 'worker.getConfigurationHints');
60
+ this.getConfigurationHints = timerify(this.getConfigurationHints.bind(this), 'getConfigurationHints');
61
61
  }
62
62
  async init() {
63
63
  this.enabledPlugins = await this.determineEnabledPlugins();
@@ -310,7 +310,7 @@ export class WorkspaceWorker {
310
310
  }
311
311
  else {
312
312
  const sourceText = this.readFile(configFilePath);
313
- parsed = sourceText ? parseFile(configFilePath, sourceText) : undefined;
313
+ parsed = sourceText ? _parseFile(configFilePath, sourceText) : undefined;
314
314
  parsedConfigCache.set(configFilePath, parsed);
315
315
  }
316
316
  }
package/dist/cli.js CHANGED
@@ -68,7 +68,7 @@ const main = async () => {
68
68
  console.log(`\n${perfObserver.getTimerifiedFunctionsTable()}`);
69
69
  if (perfObserver.isMemoryUsageEnabled && !args['memory-realtime'])
70
70
  console.log(`\n${perfObserver.getMemoryUsageTable()}`);
71
- if (perfObserver.isEnabled) {
71
+ if (perfObserver.isEnabled || perfObserver.isDurationEnabled) {
72
72
  const duration = perfObserver.getCurrentDurationInMs();
73
73
  console.log('\nTotal running time:', prettyMilliseconds(duration));
74
74
  perfObserver.reset();
@@ -28,7 +28,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
28
28
  }
29
29
  if (inExport.hasRefsInFile)
30
30
  return true;
31
- if (explorer.isReferenced(filePath, containingExport, { includeEntryExports })[0])
31
+ if (explorer.isReferenced(filePath, containingExport, { traverseEntries: includeEntryExports })[0])
32
32
  return true;
33
33
  if (inExport.referencedIn) {
34
34
  const v = visited ?? new Set();
@@ -63,7 +63,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
63
63
  const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags) || isInternalProd;
64
64
  if (importsForExport) {
65
65
  const [isReferenced, reExportingEntryFile] = explorer.isReferenced(filePath, identifier, {
66
- includeEntryExports: isIncludeEntryExports,
66
+ traverseEntries: isIncludeEntryExports,
67
67
  });
68
68
  if (isIgnored &&
69
69
  (isReferenced || isReferencedInUsedExport(exportedItem, filePath, isIncludeEntryExports))) {
@@ -104,7 +104,8 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
104
104
  if (!member.hasRefsInFile) {
105
105
  const id = `${identifier}.${member.identifier}`;
106
106
  const [isMemberReferenced] = explorer.isReferenced(filePath, id, {
107
- includeEntryExports: true,
107
+ traverseEntries: true,
108
+ treatStarAtEntryAsReferenced: true,
108
109
  });
109
110
  const isIgnored = shouldIgnoreTags(member.jsDocTags);
110
111
  if (!isMemberReferenced) {
@@ -44,6 +44,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
44
44
  });
45
45
  counselor.addWorkspace(manifest);
46
46
  }
47
+ deputy.setWorkspacePkgNames(chief.availableWorkspacePkgNames);
47
48
  collector.addIgnorePatterns(chief.config.ignore.map(id => ({ pattern: prependDir(options.cwd, id), id })));
48
49
  collector.addIgnoreFilesPatterns(chief.config.ignoreFiles.map(id => ({ pattern: prependDir(options.cwd, id), id })));
49
50
  if (options.configFilePath) {
@@ -1,7 +1,8 @@
1
1
  import type { ModuleGraph } from '../types/module-graph.ts';
2
2
  export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<string>) => {
3
3
  isReferenced: (filePath: string, identifier: string, options: {
4
- includeEntryExports: boolean;
4
+ traverseEntries: boolean;
5
+ treatStarAtEntryAsReferenced?: boolean;
5
6
  }) => [boolean, string | undefined];
6
7
  hasStrictlyNsReferences: (filePath: string, identifier: string) => [boolean, (string | undefined)?];
7
8
  buildExportsTree: (options: {
@@ -1,4 +1,5 @@
1
1
  import type { Identifier, ModuleGraph } from '../../types/module-graph.ts';
2
2
  export declare const isReferenced: (graph: ModuleGraph, entryPaths: Set<string>, filePath: string, id: Identifier, options: {
3
- includeEntryExports: boolean;
3
+ traverseEntries: boolean;
4
+ treatStarAtEntryAsReferenced?: boolean;
4
5
  }) => [boolean, string | undefined];
@@ -23,9 +23,12 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
23
23
  seen.add(path);
24
24
  const restIds = id.split('.');
25
25
  const identifier = restIds.shift();
26
+ if (options.treatStarAtEntryAsReferenced && isEntryFile && viaStar && restIds.length > 0) {
27
+ return [true, reExportingEntryFile];
28
+ }
26
29
  const file = graph.get(path)?.importedBy;
27
30
  if (!identifier || !file) {
28
- return [isEntryFile && viaStar && restIds.length > 0, reExportingEntryFile];
31
+ return [false, reExportingEntryFile];
29
32
  }
30
33
  const follow = (sources, nextId, nextViaStar = viaStar) => {
31
34
  for (const byFilePath of sources) {
@@ -71,7 +74,7 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
71
74
  return [true, reExportingEntryFile];
72
75
  }
73
76
  }
74
- if (isEntryFile && !options.includeEntryExports)
77
+ if (isEntryFile && !options.traverseEntries)
75
78
  return [false, reExportingEntryFile];
76
79
  const aliasMap = getAliasReExportMap(file, identifier);
77
80
  if (aliasMap) {
@@ -91,7 +94,7 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
91
94
  return [true, reExportingEntryFile];
92
95
  }
93
96
  for (const [namespace, sources] of file.reExportNs) {
94
- if (follow(sources, `${namespace}.${id}`)) {
97
+ if (follow(sources, `${namespace}.${id}`, true)) {
95
98
  return [true, reExportingEntryFile];
96
99
  }
97
100
  }
@@ -1,5 +1,7 @@
1
1
  import { toDeferResolve, toProductionEntry } from '../../util/input.js';
2
+ import { join } from '../../util/path.js';
2
3
  import { findWebpackDependenciesFromConfig } from '../webpack/index.js';
4
+ const isLocalPath = (name) => name.startsWith('.') || name.startsWith('/');
3
5
  const FIRST_PARTY_MODULES = new Set([
4
6
  'content-docs',
5
7
  'content-blog',
@@ -55,12 +57,14 @@ const resolveSidebarPath = (config) => {
55
57
  const path = config?.sidebarPath ?? config?.docs?.sidebarPath;
56
58
  return typeof path === 'string' ? path : undefined;
57
59
  };
58
- const resolveArrayConfig = ([name, config], type) => {
60
+ const resolveArrayConfig = ([name, config], type, cwd) => {
59
61
  if (typeof name !== 'string')
60
62
  return [];
61
- const resolvedName = resolveModuleName(name, type);
62
63
  const sidebarPath = type !== 'theme' ? resolveSidebarPath(config) : undefined;
63
- return [toDeferResolve(resolvedName), ...(sidebarPath ? [toProductionEntry(sidebarPath)] : [])];
64
+ const sidebar = sidebarPath ? [toProductionEntry(sidebarPath)] : [];
65
+ if (isLocalPath(name))
66
+ return [toProductionEntry(join(cwd, name)), ...sidebar];
67
+ return [toDeferResolve(resolveModuleName(name, type)), ...sidebar];
64
68
  };
65
69
  export const resolveConfigItems = async (items, type, options) => {
66
70
  const inputs = new Set();
@@ -70,10 +74,13 @@ export const resolveConfigItems = async (items, type, options) => {
70
74
  if (!item)
71
75
  continue;
72
76
  if (typeof item === 'string') {
73
- inputs.add(toDeferResolve(resolveModuleName(item, type)));
77
+ if (isLocalPath(item))
78
+ inputs.add(toProductionEntry(join(options.cwd, item)));
79
+ else
80
+ inputs.add(toDeferResolve(resolveModuleName(item, type)));
74
81
  }
75
82
  else if (Array.isArray(item)) {
76
- for (const input of resolveArrayConfig(item, type))
83
+ for (const input of resolveArrayConfig(item, type, options.cwd))
77
84
  inputs.add(input);
78
85
  }
79
86
  else if (typeof item.configureWebpack === 'function') {
@@ -5,7 +5,7 @@ import { CORE_CLIENT_API, resolveConfigItems } from './helpers.js';
5
5
  const title = 'Docusaurus';
6
6
  const enablers = ['@docusaurus/core'];
7
7
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
8
- const config = ['docusaurus.config.{js,mjs,ts}'];
8
+ const config = ['docusaurus.config.{js,cjs,mjs,ts,cts,mts}'];
9
9
  const production = ['src/pages/**/*.{js,ts,jsx,tsx}', '{blog,docs}/**/*.mdx', 'versioned_docs/**/*.{mdx,jsx,tsx}'];
10
10
  const entry = ['babel.config.{js,cjs,mjs,cts}'];
11
11
  const resolveStaticAssets = (items, cwd) => {
@@ -30,6 +30,7 @@ const resolveConfig = async (config, options) => {
30
30
  toDependency('@docusaurus/module-type-aliases', { optional: true }),
31
31
  ...(hasClassicTheme ? [toIgnore('(@theme|@theme-init|@theme-original)/*', 'dependencies')] : []),
32
32
  toIgnore(`@docusaurus/(${CORE_CLIENT_API.join('|')})`, 'dependencies'),
33
+ toIgnore('@generated/.*', 'dependencies'),
33
34
  ...(config.future?.experimental_faster ? [toDependency('@docusaurus/faster')] : []),
34
35
  ...production.map(id => toProductionEntry(id)),
35
36
  ...entry.map(id => toEntry(id)),
@@ -3,7 +3,7 @@ import { hasDependency } from '../../util/plugin.js';
3
3
  const title = 'Hardhat';
4
4
  const enablers = ['hardhat'];
5
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
- const entry = ['hardhat.config.{js,cjs,mjs,ts}'];
6
+ const entry = ['hardhat.config.{js,cjs,mjs,ts,cts,mts}'];
7
7
  const resolve = async () => {
8
8
  return [toDependency('hardhat')];
9
9
  };
@@ -6,7 +6,7 @@ import { getReportersDependencies, resolveExtensibleConfig } from './helpers.js'
6
6
  const title = 'Jest';
7
7
  const enablers = ['jest'];
8
8
  const isEnabled = ({ dependencies, manifest }) => hasDependency(dependencies, enablers) || Boolean(manifest.name?.startsWith('jest-presets'));
9
- const config = ['jest.config.{js,ts,mjs,cjs,json}', 'package.json'];
9
+ const config = ['jest.config.{js,ts,mjs,cjs,mts,cts,json}', 'package.json'];
10
10
  const mocks = ['**/__mocks__/**/*.[jt]s?(x)'];
11
11
  const entry = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)', ...mocks];
12
12
  const rootDirRe = /<rootDir>/;
@@ -4,7 +4,7 @@ import { hasDependency } from '../../util/plugin.js';
4
4
  const title = 'Nitro';
5
5
  const enablers = ['nitropack', 'nitro'];
6
6
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
- const config = ['nitro.config.{js,mjs,ts}'];
7
+ const config = ['nitro.config.{js,cjs,mjs,ts,cts,mts}'];
8
8
  const production = [
9
9
  'server.{js,mjs,ts}',
10
10
  'api/**/*.ts',
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
3
  import { Visitor } from 'oxc-parser';
4
4
  import { scriptBodies } from '../../compilers/compilers.js';
5
- import { parseFile } from '../../typescript/ast-nodes.js';
5
+ import { _parseFile } from '../../typescript/ast-nodes.js';
6
6
  import { basename, dirname, isInNodeModules, join } from '../../util/path.js';
7
7
  export const getVueSfc = (cwd) => {
8
8
  try {
@@ -23,7 +23,7 @@ const readFile = (filePath) => {
23
23
  return '';
24
24
  }
25
25
  };
26
- export const readAndParseFile = (filePath) => parseFile(filePath, readFile(filePath));
26
+ export const readAndParseFile = (filePath) => _parseFile(filePath, readFile(filePath));
27
27
  export const collectIdentifiers = (source, fileName) => {
28
28
  const identifiers = new Set();
29
29
  const visitor = new Visitor({
@@ -31,7 +31,7 @@ export const collectIdentifiers = (source, fileName) => {
31
31
  identifiers.add(node.name);
32
32
  },
33
33
  });
34
- visitor.visit(parseFile(fileName, source).program);
34
+ visitor.visit(_parseFile(fileName, source).program);
35
35
  return identifiers;
36
36
  };
37
37
  export const collectTemplateInfo = (tree) => {
@@ -8,7 +8,7 @@ import { buildAutoImportMap, collectIdentifiers, collectLocalImportPaths, collec
8
8
  const title = 'Nuxt';
9
9
  const enablers = ['nuxt', 'nuxt-nightly'];
10
10
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
11
- const config = ['nuxt.config.{js,mjs,ts}'];
11
+ const config = ['nuxt.config.{js,cjs,mjs,ts,cts,mts}'];
12
12
  const entry = ['app.config.ts', '**/*.d.vue.ts'];
13
13
  const app = ['app.{vue,jsx,tsx}', 'error.{vue,jsx,tsx}', 'router.options.ts'];
14
14
  const layout = (dir = 'layouts') => join(dir, '**/*.{vue,jsx,tsx}');
@@ -35,6 +35,13 @@ const resolveConfig = async (localConfig, options) => {
35
35
  .map(target => target?.executor)
36
36
  .filter(executor => executor && !executor.startsWith('.'))
37
37
  .map(executor => executor?.split(':')[0]);
38
+ const expand = (value) => value.replaceAll('{projectRoot}', options.configFileDir).replaceAll('{workspaceRoot}', options.rootCwd);
39
+ const resolveTargetCwd = (targetCwd) => {
40
+ if (!targetCwd)
41
+ return options.cwd;
42
+ const expanded = expand(targetCwd);
43
+ return expanded === targetCwd ? join(options.cwd, targetCwd) : expanded;
44
+ };
38
45
  const inputs = targets
39
46
  .filter(target => target.executor === 'nx:run-commands' || target.command)
40
47
  .flatMap(target => {
@@ -45,8 +52,7 @@ const resolveConfig = async (localConfig, options) => {
45
52
  commands = [target.options.command];
46
53
  else if (target.options?.commands)
47
54
  commands = target.options.commands.map(commandConfig => typeof commandConfig === 'string' ? commandConfig : commandConfig.command);
48
- const cwd = target.options?.cwd ? join(options.cwd, target.options.cwd) : options.cwd;
49
- return options.getInputsFromScripts(commands, { cwd });
55
+ return options.getInputsFromScripts(commands.map(expand), { cwd: resolveTargetCwd(target.options?.cwd) });
50
56
  });
51
57
  const configInputs = targets.flatMap(target => {
52
58
  const opts = target.options;