knip 6.43.0 → 6.44.1

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 (168) hide show
  1. package/README.md +2 -4
  2. package/dist/CacheConsultant.d.ts +1 -0
  3. package/dist/CacheConsultant.js +2 -0
  4. package/dist/CatalogCounselor.d.ts +1 -3
  5. package/dist/CatalogCounselor.js +18 -15
  6. package/dist/ConfigurationChief.d.ts +24 -0
  7. package/dist/DependencyDeputy.d.ts +2 -1
  8. package/dist/DependencyDeputy.js +11 -6
  9. package/dist/IssueCollector.js +1 -0
  10. package/dist/ProjectPrincipal.d.ts +4 -2
  11. package/dist/ProjectPrincipal.js +32 -10
  12. package/dist/WorkspaceWorker.d.ts +5 -2
  13. package/dist/WorkspaceWorker.js +20 -7
  14. package/dist/binaries/resolvers/bun.js +7 -2
  15. package/dist/binaries/util.js +2 -1
  16. package/dist/cli.js +6 -1
  17. package/dist/compilers/index.d.ts +5 -0
  18. package/dist/compilers/index.js +1 -1
  19. package/dist/constants.d.ts +2 -0
  20. package/dist/constants.js +2 -0
  21. package/dist/graph/analyze.js +3 -2
  22. package/dist/graph/build.d.ts +2 -0
  23. package/dist/graph/build.js +37 -22
  24. package/dist/graph-explorer/cache.d.ts +2 -1
  25. package/dist/graph-explorer/cache.js +5 -1
  26. package/dist/graph-explorer/explorer.d.ts +3 -5
  27. package/dist/graph-explorer/explorer.js +24 -3
  28. package/dist/plugins/babel/index.js +6 -1
  29. package/dist/plugins/biome/index.js +1 -1
  30. package/dist/plugins/cspell/index.js +10 -2
  31. package/dist/plugins/dependency-cruiser/index.js +2 -2
  32. package/dist/plugins/docusaurus/helpers.js +4 -4
  33. package/dist/plugins/electron-vite/index.js +2 -2
  34. package/dist/plugins/eleventy/index.js +2 -2
  35. package/dist/plugins/expressive-code/index.d.ts +1 -1
  36. package/dist/plugins/expressive-code/index.js +2 -2
  37. package/dist/plugins/gatsby/index.js +6 -6
  38. package/dist/plugins/gatsby/types.d.ts +1 -1
  39. package/dist/plugins/github-actions/index.js +1 -1
  40. package/dist/plugins/i18next-parser/index.js +2 -2
  41. package/dist/plugins/index.d.ts +5 -1
  42. package/dist/plugins/index.js +8 -0
  43. package/dist/plugins/jasmine/index.js +2 -2
  44. package/dist/plugins/karma/index.js +4 -4
  45. package/dist/plugins/kysely-codegen/index.d.ts +3 -0
  46. package/dist/plugins/kysely-codegen/index.js +20 -0
  47. package/dist/plugins/lefthook/index.js +2 -2
  48. package/dist/plugins/lingui/index.d.ts +3 -0
  49. package/dist/plugins/lingui/index.js +16 -0
  50. package/dist/plugins/lockfile-lint/index.js +2 -2
  51. package/dist/plugins/lost-pixel/index.js +2 -2
  52. package/dist/plugins/lunaria/index.js +2 -2
  53. package/dist/plugins/marko/index.js +5 -6
  54. package/dist/plugins/mastra/index.d.ts +3 -0
  55. package/dist/plugins/mastra/index.js +57 -0
  56. package/dist/plugins/mcp/index.js +1 -1
  57. package/dist/plugins/mise/index.js +0 -3
  58. package/dist/plugins/mocha/index.js +43 -4
  59. package/dist/plugins/mocha/types.d.ts +1 -0
  60. package/dist/plugins/npm-package-json-lint/index.js +1 -1
  61. package/dist/plugins/npm-package-json-lint/types.d.ts +1 -1
  62. package/dist/plugins/nx/index.js +3 -8
  63. package/dist/plugins/nyc/index.js +1 -1
  64. package/dist/plugins/openapi-ts/index.js +2 -2
  65. package/dist/plugins/oxfmt/index.js +2 -2
  66. package/dist/plugins/playwright/index.js +6 -11
  67. package/dist/plugins/pnpm/index.js +2 -4
  68. package/dist/plugins/purgecss/index.d.ts +3 -0
  69. package/dist/plugins/purgecss/index.js +16 -0
  70. package/dist/plugins/railway/index.js +1 -4
  71. package/dist/plugins/relay/index.js +1 -1
  72. package/dist/plugins/release-it/index.js +1 -1
  73. package/dist/plugins/remix/index.js +1 -1
  74. package/dist/plugins/rsbuild/index.js +29 -1
  75. package/dist/plugins/rsbuild/types.d.ts +8 -0
  76. package/dist/plugins/rstest/index.js +2 -2
  77. package/dist/plugins/serverless-framework/index.js +1 -1
  78. package/dist/plugins/storybook/index.js +5 -5
  79. package/dist/plugins/sveltekit/resolveFromAST.js +1 -1
  80. package/dist/plugins/svgr/index.js +2 -1
  81. package/dist/plugins/swc/index.js +8 -3
  82. package/dist/plugins/syncpack/index.js +2 -2
  83. package/dist/plugins/tanstack-router/index.js +3 -2
  84. package/dist/plugins/taskfile/index.js +4 -7
  85. package/dist/plugins/textlint/helpers.js +2 -2
  86. package/dist/plugins/typescript/index.js +7 -3
  87. package/dist/plugins/unocss/index.js +2 -2
  88. package/dist/plugins/vite-plugin-pwa/index.js +1 -4
  89. package/dist/plugins/vite-plugin-pwa/resolveFromAST.d.ts +0 -2
  90. package/dist/plugins/vite-plugin-pwa/resolveFromAST.js +2 -2
  91. package/dist/plugins/vite-pwa-assets-generator/index.js +2 -2
  92. package/dist/plugins/vitest/helpers.js +4 -7
  93. package/dist/plugins/vitest/index.js +1 -1
  94. package/dist/plugins/webpack/index.d.ts +2 -0
  95. package/dist/plugins/webpack/index.js +11 -6
  96. package/dist/plugins/yarn/index.js +2 -4
  97. package/dist/reporters/codeclimate.d.ts +2 -2
  98. package/dist/reporters/codeclimate.js +2 -4
  99. package/dist/reporters/codeowners.d.ts +2 -2
  100. package/dist/reporters/codeowners.js +9 -9
  101. package/dist/reporters/compact.d.ts +2 -2
  102. package/dist/reporters/compact.js +8 -7
  103. package/dist/reporters/cycles.d.ts +2 -2
  104. package/dist/reporters/cycles.js +7 -6
  105. package/dist/reporters/disclosure.d.ts +2 -2
  106. package/dist/reporters/disclosure.js +6 -4
  107. package/dist/reporters/github-actions.d.ts +2 -2
  108. package/dist/reporters/github-actions.js +7 -5
  109. package/dist/reporters/index.d.ts +10 -10
  110. package/dist/reporters/json.d.ts +2 -2
  111. package/dist/reporters/json.js +2 -4
  112. package/dist/reporters/markdown.d.ts +2 -2
  113. package/dist/reporters/markdown.js +11 -9
  114. package/dist/reporters/sarif.d.ts +2 -2
  115. package/dist/reporters/sarif.js +2 -3
  116. package/dist/reporters/symbols.d.ts +2 -2
  117. package/dist/reporters/symbols.js +6 -4
  118. package/dist/run.d.ts +1 -1
  119. package/dist/run.js +3 -10
  120. package/dist/schema/configuration.d.ts +60 -0
  121. package/dist/schema/plugins.d.ts +20 -0
  122. package/dist/schema/plugins.js +4 -0
  123. package/dist/session/configuration.d.ts +15 -0
  124. package/dist/session/configuration.js +62 -0
  125. package/dist/session/incremental.d.ts +54 -0
  126. package/dist/session/incremental.js +49 -0
  127. package/dist/session/session.d.ts +1 -1
  128. package/dist/session/session.js +63 -27
  129. package/dist/session/watch.d.ts +2 -0
  130. package/dist/session/watch.js +41 -0
  131. package/dist/types/PluginNames.d.ts +2 -2
  132. package/dist/types/PluginNames.js +4 -0
  133. package/dist/types/config.d.ts +1 -0
  134. package/dist/types/issues.d.ts +4 -0
  135. package/dist/types/package-json.d.ts +0 -3
  136. package/dist/typescript/get-imports-and-exports.js +2 -0
  137. package/dist/typescript/visitors/calls.js +15 -11
  138. package/dist/typescript/visitors/imports.d.ts +3 -1
  139. package/dist/typescript/visitors/imports.js +77 -53
  140. package/dist/typescript/visitors/members.js +23 -26
  141. package/dist/typescript/visitors/walk.d.ts +3 -0
  142. package/dist/typescript/visitors/walk.js +43 -2
  143. package/dist/util/cli-arguments.d.ts +2 -1
  144. package/dist/util/cli-arguments.js +3 -0
  145. package/dist/util/create-input-handler.js +1 -1
  146. package/dist/util/create-options.d.ts +43 -2
  147. package/dist/util/create-options.js +17 -4
  148. package/dist/util/file-entry-cache.d.ts +2 -0
  149. package/dist/util/file-entry-cache.js +19 -1
  150. package/dist/util/gitignore-cache.d.ts +1 -0
  151. package/dist/util/gitignore-cache.js +1 -0
  152. package/dist/util/glob-core.js +4 -2
  153. package/dist/util/glob.d.ts +1 -0
  154. package/dist/util/glob.js +6 -0
  155. package/dist/util/input.d.ts +2 -0
  156. package/dist/util/loader.d.ts +1 -0
  157. package/dist/util/loader.js +29 -1
  158. package/dist/util/modules.js +5 -2
  159. package/dist/util/path.d.ts +1 -0
  160. package/dist/util/path.js +1 -0
  161. package/dist/util/reporter.d.ts +1 -1
  162. package/dist/util/reporter.js +53 -9
  163. package/dist/util/watch.d.ts +5 -11
  164. package/dist/util/watch.js +84 -68
  165. package/dist/version.d.ts +1 -1
  166. package/dist/version.js +1 -1
  167. package/package.json +1 -1
  168. package/schema.json +16 -0
@@ -7,7 +7,7 @@ import { relative } from '../util/path.js';
7
7
  import { perfObserver, timerify } from '../util/Performance.js';
8
8
  import { findMatch } from '../util/regex.js';
9
9
  import { getShouldIgnoreHandler, getShouldIgnoreTagHandler, hasTag, isAlwaysIgnored } from '../util/tag.js';
10
- import { INTERNAL_TAG } from '../constants.js';
10
+ import { IMPORT_FLAGS, INTERNAL_TAG } from '../constants.js';
11
11
  const toCyclePathKey = (path) => {
12
12
  const length = path.length > 1 && path[0] === path[path.length - 1] ? path.length - 1 : path.length;
13
13
  return path.slice(0, length).join('\0');
@@ -25,7 +25,7 @@ const isAllowedCycle = (symbols, paths) => paths?.has(toCyclePathKey(symbols.map
25
25
  export const analyze = async ({ analyzedFiles, counselor, chief, collector, deputy, entryPaths, graph, streamer, unreferencedFiles, options, }) => {
26
26
  const shouldIgnore = getShouldIgnoreHandler(options.isProduction);
27
27
  const shouldIgnoreTags = getShouldIgnoreTagHandler(options.tags);
28
- const explorer = createGraphExplorer(graph, entryPaths);
28
+ const explorer = createGraphExplorer(graph, entryPaths, options.isSession);
29
29
  const isReferencedInUsedExport = (exportedItem, filePath, includeEntryExports, ignoreExportsUsedInFile, visited) => {
30
30
  if (!exportedItem.referencedIn)
31
31
  return false;
@@ -230,6 +230,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
230
230
  specifier: extImport.specifier,
231
231
  isTypeOnly: extImport.isTypeOnly,
232
232
  isResolved: extImport.filePath !== undefined,
233
+ isCaught: !!(extImport.modifiers & IMPORT_FLAGS.CAUGHT),
233
234
  });
234
235
  if (!isHandled && !(extImport.jsDocTags?.size && shouldIgnoreTags(extImport.jsDocTags)))
235
236
  collector.addIssue({
@@ -7,6 +7,7 @@ import type { IssueCollector } from '../IssueCollector.ts';
7
7
  import type { ProjectPrincipal } from '../ProjectPrincipal.ts';
8
8
  import type { ModuleGraph } from '../types/module-graph.ts';
9
9
  import type { MainOptions } from '../util/create-options.ts';
10
+ import { ConfigurationFiles } from '../session/configuration.ts';
10
11
  interface BuildOptions {
11
12
  chief: ConfigurationChief;
12
13
  collector: IssueCollector;
@@ -21,6 +22,7 @@ interface BuildOptions {
21
22
  }
22
23
  export declare function build({ chief, collector, counselor, deputy, principal, isGitIgnored, scriptParserContext, streamer, workspaces, options, }: BuildOptions): Promise<{
23
24
  graph: ModuleGraph;
25
+ configurationFiles: ConfigurationFiles | undefined;
24
26
  entryPaths: Set<string>;
25
27
  analyzedFiles: Set<string>;
26
28
  unreferencedFiles: Set<string>;
@@ -4,12 +4,13 @@ import { getIncludedCompilers, normalizeCompilerExtension } from '../compilers/i
4
4
  import { DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS, IS_DTS, ROOT_WORKSPACE_NAME } from '../constants.js';
5
5
  import { partition } from '../util/array.js';
6
6
  import { createInputHandler } from '../util/create-input-handler.js';
7
+ import { ConfigurationFiles } from '../session/configuration.js';
7
8
  import { debugLog, debugLogArray } from '../util/debug.js';
8
9
  import { existsSync } from 'node:fs';
9
10
  import picomatch from 'picomatch';
10
11
  import { tryRealpath } from '../util/fs.js';
11
12
  import { createManifest } from '../util/package-json.js';
12
- import { _glob, _syncGlob, prependDirToPattern as prependDir, removeProductionSuffix } from '../util/glob.js';
13
+ import { _glob, _syncGlob, prependDirToPattern as prependDir, rebasePattern, removeProductionSuffix, } from '../util/glob.js';
13
14
  import { isAlias, isCatalog, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toDeferResolveEntry, toDependency, toProductionEntry, } from '../util/input.js';
14
15
  import { isAmbientDeclarationFile } from '../typescript/ast-nodes.js';
15
16
  import { resolveImportGlobs } from '../typescript/glob-imports.js';
@@ -26,10 +27,11 @@ import { augmentWorkspace, getToSourcePathsHandler, toSourceMappedSpecifiers } f
26
27
  import { WorkspaceWorker } from '../WorkspaceWorker.js';
27
28
  export async function build({ chief, collector, counselor, deputy, principal, isGitIgnored, scriptParserContext, streamer, workspaces, options, }) {
28
29
  const configFilesMap = new Map();
30
+ const configurationFiles = options.isSession ? new ConfigurationFiles(options) : undefined;
29
31
  const enabledPluginsStore = new Map();
30
32
  const registeredVisitorPlugins = new Set();
31
33
  const toSourceFilePaths = getToSourcePathsHandler(chief);
32
- const addIssue = (issue) => collector.addIssue(issue) && options.isWatch && collector.retainIssue(issue);
34
+ const addIssue = (issue) => collector.addIssue(issue) && options.isSession && collector.retainIssue(issue);
33
35
  const externalRefsFromInputs = options.isSession ? new Map() : undefined;
34
36
  const handleInput = createInputHandler(deputy, chief, isGitIgnored, addIssue, externalRefsFromInputs, options);
35
37
  const getPublishedTypeDependencies = options.isReportDependencies
@@ -79,6 +81,8 @@ export async function build({ chief, collector, counselor, deputy, principal, is
79
81
  continue;
80
82
  const dependencies = deputy.getDependencies(name);
81
83
  const tsConfigFilePath = join(dir, options.tsConfigFile ?? 'tsconfig.json');
84
+ configurationFiles?.paths.add(filePath);
85
+ configurationFiles?.paths.add(tsConfigFilePath);
82
86
  const { isFile, compilerOptions, fileNames, include, exclude, sourceMapPairs, paths: tsConfigPaths, } = await loadTSConfig(tsConfigFilePath, options.isUseTscFiles);
83
87
  const [definitionPaths, tscSourcePaths] = partition(fileNames, filePath => IS_DTS.test(filePath));
84
88
  const worker = new WorkspaceWorker({
@@ -97,6 +101,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
97
101
  enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
98
102
  readRawFile: (filePath) => principal.fileManager.readRawFile(filePath) ?? '',
99
103
  configFilesMap,
104
+ configurationFiles,
100
105
  options,
101
106
  });
102
107
  await worker.init();
@@ -189,32 +194,42 @@ export async function build({ chief, collector, counselor, deputy, principal, is
189
194
  });
190
195
  const DEFAULT_GROUP = 'default';
191
196
  const createPatternMap = () => new Map([[DEFAULT_GROUP, new Set()]]);
192
- const groups = new Set([DEFAULT_GROUP]);
197
+ const groups = new Map([[DEFAULT_GROUP, undefined]]);
193
198
  const entryPatterns = createPatternMap();
194
199
  const entryPatternsSkipExports = createPatternMap();
195
200
  const productionPatterns = createPatternMap();
196
201
  const productionPatternsSkipExports = createPatternMap();
197
202
  const projectFilePatterns = new Set();
198
- const addPattern = (map, input, pattern) => {
199
- if (input.group && !map.has(input.group))
200
- map.set(input.group, new Set());
201
- map.get(input.group ?? DEFAULT_GROUP).add(pattern);
203
+ const addPattern = (map, group, pattern) => {
204
+ let patterns = map.get(group);
205
+ if (!patterns)
206
+ map.set(group, (patterns = new Set()));
207
+ patterns.add(pattern);
202
208
  };
203
209
  const toWorkspaceRelative = (path) => (isAbsolute(path) ? relative(dir, path) : path);
210
+ const addEntryPattern = (map, input) => {
211
+ const base = input.dir;
212
+ if (base && base !== dir) {
213
+ const group = `${input.group ?? DEFAULT_GROUP}:${base}`;
214
+ groups.set(group, base);
215
+ addPattern(map, group, rebasePattern(input.specifier, base, dir));
216
+ }
217
+ else {
218
+ addPattern(map, input.group ?? DEFAULT_GROUP, toWorkspaceRelative(input.specifier));
219
+ }
220
+ };
204
221
  for (const input of inputs) {
205
222
  if (input.group)
206
- groups.add(input.group);
223
+ groups.set(input.group, undefined);
207
224
  const specifier = input.specifier;
208
225
  if (isCatalog(input)) {
209
226
  counselor.addReference({ catalogName: input.catalogName, packageName: specifier });
210
227
  }
211
228
  else if (isEntry(input)) {
212
- const targetMap = input.skipExportsAnalysis ? entryPatternsSkipExports : entryPatterns;
213
- addPattern(targetMap, input, toWorkspaceRelative(specifier));
229
+ addEntryPattern(input.skipExportsAnalysis ? entryPatternsSkipExports : entryPatterns, input);
214
230
  }
215
231
  else if (isProductionEntry(input)) {
216
- const targetMap = input.skipExportsAnalysis ? productionPatternsSkipExports : productionPatterns;
217
- addPattern(targetMap, input, toWorkspaceRelative(specifier));
232
+ addEntryPattern(input.skipExportsAnalysis ? productionPatternsSkipExports : productionPatterns, input);
218
233
  }
219
234
  else if (isProject(input)) {
220
235
  projectFilePatterns.add(toWorkspaceRelative(specifier));
@@ -239,7 +254,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
239
254
  if (resolvedFilePath) {
240
255
  if (isDeferResolveEntry(input) && options.isProduction && !isDeferResolveProductionEntry(input)) {
241
256
  if (!input.optional)
242
- addPattern(entryPatternsSkipExports, input, resolvedFilePath);
257
+ addPattern(entryPatternsSkipExports, input.group ?? DEFAULT_GROUP, resolvedFilePath);
243
258
  }
244
259
  else {
245
260
  principal.addEntryPath(resolvedFilePath, { skipExportsAnalysis: true });
@@ -278,13 +293,9 @@ export async function build({ chief, collector, counselor, deputy, principal, is
278
293
  gitignore: false,
279
294
  label: 'entry paths',
280
295
  });
281
- for (const group of groups) {
296
+ for (const [group, base] of groups) {
282
297
  {
283
- const patterns = worker.getPluginEntryFilePatterns([
284
- ...((!options.isProduction && entryPatterns.get(group)) || []),
285
- ...((!options.isProduction && group === DEFAULT_GROUP && worker.getPluginConfigPatterns()) || []),
286
- ...(productionPatterns.get(group) ?? []),
287
- ]);
298
+ const patterns = worker.getPluginEntryFilePatterns([...((!options.isProduction && entryPatterns.get(group)) || []), ...(productionPatterns.get(group) ?? [])], base);
288
299
  const label = `entry paths from plugins${group !== DEFAULT_GROUP ? ` - ${group}` : ''}`;
289
300
  const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
290
301
  principal.addEntryPaths(productionPaths(pluginWorkspaceEntryPaths));
@@ -293,7 +304,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
293
304
  const patterns = worker.getPluginEntryFilePatterns([
294
305
  ...((!options.isProduction && entryPatternsSkipExports.get(group)) || []),
295
306
  ...(productionPatternsSkipExports.get(group) ?? []),
296
- ]);
307
+ ], base);
297
308
  const label = `entry paths from plugins (ignore exports)${group !== DEFAULT_GROUP ? ` - ${group}` : ''}`;
298
309
  const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
299
310
  principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
@@ -368,7 +379,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
368
379
  tags: options.tags,
369
380
  };
370
381
  const analyzeSourceFile = (filePath, sourceText, parseResult, cachedFile) => {
371
- if (!options.isWatch && !options.isSession && analyzedFiles.has(filePath))
382
+ if (!options.isSession && analyzedFiles.has(filePath))
372
383
  return;
373
384
  analyzedFiles.add(filePath);
374
385
  const workspace = chief.findWorkspaceByFilePath(filePath);
@@ -433,6 +444,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
433
444
  const dir = dirname(filePath);
434
445
  const opts = {
435
446
  cwd: dir,
447
+ manifestDir: workspace.dir,
436
448
  rootCwd: options.cwd,
437
449
  containingFilePath: filePath,
438
450
  dependencies,
@@ -448,6 +460,8 @@ export async function build({ chief, collector, counselor, deputy, principal, is
448
460
  }
449
461
  input.containingFilePath ??= filePath;
450
462
  input.dir ??= dir;
463
+ if (options.isProduction)
464
+ input.production = true;
451
465
  const specifierFilePath = handleInput(input, workspace);
452
466
  if (specifierFilePath)
453
467
  principal.addEntryPath(specifierFilePath, { skipExportsAnalysis: true });
@@ -515,7 +529,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
515
529
  }
516
530
  for (const filePath of principal.entryPaths)
517
531
  entryPaths.add(filePath);
518
- principal.reconcileCache(graph);
532
+ principal.reconcileCache();
519
533
  perfObserver.addMemoryMark('build');
520
534
  if (externalRefsFromInputs) {
521
535
  for (const [filePath, refs] of externalRefsFromInputs) {
@@ -527,6 +541,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
527
541
  }
528
542
  return {
529
543
  graph,
544
+ configurationFiles,
530
545
  entryPaths,
531
546
  analyzedFiles,
532
547
  unreferencedFiles,
@@ -2,7 +2,8 @@ import type { ModuleGraph } from '../types/module-graph.ts';
2
2
  import type { UsageResult } from './operations/get-usage.ts';
3
3
  import type { DefinitionResult } from './operations/resolve-definition.ts';
4
4
  import type { ExportTableCache } from './operations/resolve-export-origins.ts';
5
- export declare const invalidateCache: (graph: ModuleGraph) => void;
5
+ export declare const getTopologyGeneration: (graph: ModuleGraph) => number;
6
+ export declare const invalidateCache: (graph: ModuleGraph, topologyUnchanged?: boolean) => void;
6
7
  export declare const getCachedDefinition: (graph: ModuleGraph, filePath: string, identifier: string) => DefinitionResult | null | undefined;
7
8
  export declare const setCachedDefinition: (graph: ModuleGraph, filePath: string, identifier: string, result: DefinitionResult | null) => void;
8
9
  export declare const getCachedUsage: (graph: ModuleGraph, filePath: string, identifier: string) => UsageResult | undefined;
@@ -6,6 +6,7 @@ const createEmptyCache = () => ({
6
6
  exportedIdentifiers: new Map(),
7
7
  exportTables: new Map(),
8
8
  generation: 0,
9
+ topologyGeneration: 0,
9
10
  });
10
11
  const getCache = (graph) => {
11
12
  let cache = caches.get(graph);
@@ -15,7 +16,8 @@ const getCache = (graph) => {
15
16
  }
16
17
  return cache;
17
18
  };
18
- export const invalidateCache = (graph) => {
19
+ export const getTopologyGeneration = (graph) => getCache(graph).topologyGeneration;
20
+ export const invalidateCache = (graph, topologyUnchanged = false) => {
19
21
  const cache = caches.get(graph);
20
22
  if (cache) {
21
23
  cache.definitions.clear();
@@ -24,6 +26,8 @@ export const invalidateCache = (graph) => {
24
26
  cache.exportedIdentifiers.clear();
25
27
  cache.exportTables.clear();
26
28
  cache.generation++;
29
+ if (!topologyUnchanged)
30
+ cache.topologyGeneration++;
27
31
  }
28
32
  };
29
33
  export const getCachedDefinition = (graph, filePath, identifier) => {
@@ -1,9 +1,7 @@
1
1
  import type { ModuleGraph } from '../types/module-graph.ts';
2
- export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<string>) => {
3
- isReferenced: (filePath: string, identifier: string, options: {
4
- traverseEntries: boolean;
5
- treatStarAtEntryAsReferenced?: boolean;
6
- }) => readonly [false, string | undefined, Set<string> | undefined];
2
+ import { isReferenced } from './operations/is-referenced.ts';
3
+ export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<string>, cacheUsage?: boolean) => {
4
+ isReferenced: (filePath: string, identifier: string, options: Parameters<typeof isReferenced>[4]) => readonly [false, string | undefined, Set<string> | undefined];
7
5
  hasStrictlyNsReferences: (filePath: string, identifier: string) => [boolean, (string | undefined)?];
8
6
  isEnumerated: (filePath: string, identifier: string) => boolean;
9
7
  buildExportsTree: (options: {
@@ -1,4 +1,4 @@
1
- import { invalidateCache as invalidateCacheInternal } from './cache.js';
1
+ import { getTopologyGeneration, invalidateCache as invalidateCacheInternal } from './cache.js';
2
2
  import { buildExportsTree } from './operations/build-exports-tree.js';
3
3
  import { findAllCycles } from './operations/find-all-cycles.js';
4
4
  import { findCycles } from './operations/find-cycles.js';
@@ -10,9 +10,30 @@ import { isEnumerated } from './operations/is-enumerated.js';
10
10
  import { isReferenced } from './operations/is-referenced.js';
11
11
  import { resolveDefinition } from './operations/resolve-definition.js';
12
12
  import { resolveExportOrigins } from './operations/resolve-export-origins.js';
13
- export const createGraphExplorer = (graph, entryPaths) => {
13
+ export const createGraphExplorer = (graph, entryPaths, cacheUsage = false) => {
14
+ const references = new Map();
15
+ let generation = getTopologyGeneration(graph);
16
+ const reference = (filePath, identifier, options) => {
17
+ if (!cacheUsage)
18
+ return isReferenced(graph, entryPaths, filePath, identifier, options);
19
+ const current = getTopologyGeneration(graph);
20
+ if (current !== generation) {
21
+ references.clear();
22
+ generation = current;
23
+ }
24
+ let file = references.get(filePath);
25
+ if (!file)
26
+ references.set(filePath, (file = new Map()));
27
+ const key = `${options.traverseEntries ? 1 : 0}${options.treatStarAtEntryAsReferenced ? 1 : 0}:${identifier}`;
28
+ const cached = file.get(key);
29
+ if (cached)
30
+ return cached;
31
+ const result = isReferenced(graph, entryPaths, filePath, identifier, options);
32
+ file.set(key, result);
33
+ return result;
34
+ };
14
35
  return {
15
- isReferenced: (filePath, identifier, options) => isReferenced(graph, entryPaths, filePath, identifier, options),
36
+ isReferenced: reference,
16
37
  hasStrictlyNsReferences: (filePath, identifier) => hasStrictlyNsReferences(graph, filePath, graph.get(filePath)?.importedBy, identifier),
17
38
  isEnumerated: (filePath, identifier) => isEnumerated(graph, filePath, graph.get(filePath)?.importedBy, identifier),
18
39
  buildExportsTree: (options) => buildExportsTree(graph, entryPaths, options),
@@ -5,7 +5,12 @@ import { api, resolveName } from './helpers.js';
5
5
  const title = 'Babel';
6
6
  const enablers = [/^@babel\//];
7
7
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
8
- const config = ['babel.config.{json,js,cjs,mjs,cts,ts}', '.babelrc.{json,js,cjs,mjs,cts}', '.babelrc', 'package.json'];
8
+ const config = [
9
+ 'babel.config.{json,js,cjs,mjs,cts,ts,mts}',
10
+ '.babelrc.{json,js,cjs,mjs,cts}',
11
+ '.babelrc',
12
+ 'package.json',
13
+ ];
9
14
  const getName = (value) => [Array.isArray(value) ? value[0] : value].filter(name => typeof name === 'string');
10
15
  export const getDependenciesFromConfig = (config) => {
11
16
  const presets = config.presets?.flatMap(getName).map(name => resolveName(name, 'preset')) ?? [];
@@ -5,7 +5,7 @@ import { hasDependency } from '../../util/plugin.js';
5
5
  const title = 'Biome';
6
6
  const enablers = ['@biomejs/biome'];
7
7
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
8
- const config = ['biome.json', 'biome.jsonc'];
8
+ const config = ['biome.json', 'biome.jsonc', '.biome.json', '.biome.jsonc'];
9
9
  const isRootConfigReference = (specifier) => specifier === '//';
10
10
  const resolveExtends = (extendsArray, options) => {
11
11
  return extendsArray.map(specifier => {
@@ -4,10 +4,18 @@ const title = 'CSpell';
4
4
  const enablers = ['cspell'];
5
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
6
  const config = [
7
- 'cspell.config.{js,cjs,mjs,ts,mts,json,yaml,yml}',
8
- 'cspell.{json,yaml,yml}',
7
+ 'package.json',
8
+ '{.,}cspell.config.{js,cjs,mjs,ts,cts,mts,json,jsonc,yaml,yml,toml}',
9
+ '{.,}cspell.{jsonc,yaml,yml}',
9
10
  '.c{s,S}pell.json',
10
11
  'c{s,S}pell.json',
12
+ '.vscode/c{s,S}pell.json',
13
+ '.vscode/.cspell.json',
14
+ '.config/{.,}cspell.config.{js,cjs,mjs,ts,cts,mts,json,jsonc,yaml,yml,toml}',
15
+ '.config/.c{s,S}pell.json',
16
+ '.config/c{s,S}pell.json',
17
+ '.config/{.,}cspell.jsonc',
18
+ '.config/cspell.{yaml,yml}',
11
19
  ];
12
20
  const resolveConfig = config => {
13
21
  return [config?.import ?? []].flat().map(id => toDeferResolve(id));
@@ -2,7 +2,7 @@ import { hasDependency } from '../../util/plugin.js';
2
2
  const title = 'dependency-cruiser';
3
3
  const enablers = ['dependency-cruiser'];
4
4
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
- const config = ['.dependency-cruiser.{js,cjs,mjs,json}'];
5
+ const entry = ['.dependency-cruiser.{js,cjs,mjs,json}'];
6
6
  const args = {
7
7
  binaries: ['depcruise', 'dependency-cruise', 'dependency-cruiser', 'depcruise-baseline'],
8
8
  config: true,
@@ -11,7 +11,7 @@ const plugin = {
11
11
  title,
12
12
  enablers,
13
13
  isEnabled,
14
- config,
14
+ entry,
15
15
  args,
16
16
  };
17
17
  export default plugin;
@@ -1,7 +1,7 @@
1
1
  import { toDeferResolve, toProductionEntry } from '../../util/input.js';
2
- import { join } from '../../util/path.js';
2
+ import { isAbsolute, toAbsolute } from '../../util/path.js';
3
3
  import { findWebpackDependenciesFromConfig } from '../webpack/index.js';
4
- const isLocalPath = (name) => name.startsWith('.') || name.startsWith('/');
4
+ const isLocalPath = (name) => name.startsWith('.') || isAbsolute(name);
5
5
  const FIRST_PARTY_MODULES = new Set([
6
6
  'content-docs',
7
7
  'content-blog',
@@ -63,7 +63,7 @@ const resolveArrayConfig = ([name, config], type, cwd) => {
63
63
  const sidebarPath = type !== 'theme' ? resolveSidebarPath(config) : undefined;
64
64
  const sidebar = sidebarPath ? [toProductionEntry(sidebarPath)] : [];
65
65
  if (isLocalPath(name))
66
- return [toProductionEntry(join(cwd, name)), ...sidebar];
66
+ return [toProductionEntry(toAbsolute(name, cwd)), ...sidebar];
67
67
  return [toDeferResolve(resolveModuleName(name, type)), ...sidebar];
68
68
  };
69
69
  export const resolveConfigItems = async (items, type, options) => {
@@ -75,7 +75,7 @@ export const resolveConfigItems = async (items, type, options) => {
75
75
  continue;
76
76
  if (typeof item === 'string') {
77
77
  if (isLocalPath(item))
78
- inputs.add(toProductionEntry(join(options.cwd, item)));
78
+ inputs.add(toProductionEntry(toAbsolute(item, options.cwd)));
79
79
  else
80
80
  inputs.add(toDeferResolve(resolveModuleName(item, type)));
81
81
  }
@@ -1,5 +1,5 @@
1
1
  import { toProductionEntry } from '../../util/input.js';
2
- import { isAbsolute, join } from '../../util/path.js';
2
+ import { toAbsolute } from '../../util/path.js';
3
3
  import { hasDependency } from '../../util/plugin.js';
4
4
  import { getHtmlScriptEntries } from '../vite/helpers.js';
5
5
  const title = 'electron-vite';
@@ -30,7 +30,7 @@ const resolveConfig = async (localConfig, options) => {
30
30
  }
31
31
  const patterns = ids.length > 0 ? ids : [defaultEntry[name]];
32
32
  for (const id of patterns) {
33
- const resolved = isAbsolute(id) ? id : join(configFileDir, id);
33
+ const resolved = toAbsolute(id, configFileDir);
34
34
  inputs.push(toProductionEntry(resolved));
35
35
  if (name === 'renderer' && resolved.endsWith('.html')) {
36
36
  for (const input of await getHtmlScriptEntries(resolved))
@@ -8,7 +8,7 @@ const title = 'Eleventy';
8
8
  const enablers = ['@11ty/eleventy'];
9
9
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
10
10
  const config = ['.eleventy.js', 'eleventy.config.{js,cjs,mjs}'];
11
- const production = ['posts/**/*.11tydata.js', '_data/**/*.{js,cjs,mjs}'];
11
+ const production = ['posts/**/*.11tydata.{js,cjs,mjs}', '_data/**/*.{js,cjs,mjs}'];
12
12
  const resolveConfig = async (localConfig, options) => {
13
13
  const { configFileDir } = options;
14
14
  const dummyUserConfig = new DummyEleventyConfig();
@@ -38,7 +38,7 @@ const resolveConfig = async (localConfig, options) => {
38
38
  .concat([
39
39
  join(inputDir, dataDir, '**/*.{js,cjs,mjs}'),
40
40
  join(inputDir, `**/*.{${typeof templateFormats === 'string' ? templateFormats : templateFormats.join(',')}}`),
41
- join(inputDir, '**/*.11tydata.js'),
41
+ join(inputDir, '**/*.11tydata.{js,cjs,mjs}'),
42
42
  ...copiedEntries,
43
43
  ].map(id => toProductionEntry(id)));
44
44
  };
@@ -3,6 +3,6 @@ declare const _default: {
3
3
  title: string;
4
4
  enablers: string[];
5
5
  isEnabled: IsPluginEnabled;
6
- config: string[];
6
+ entry: string[];
7
7
  };
8
8
  export default _default;
@@ -6,10 +6,10 @@ const enablers = [
6
6
  '@astrojs/starlight',
7
7
  ];
8
8
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
9
- const config = ['ec.config.{js,mjs,cjs,ts}'];
9
+ const entry = ['ec.config.{js,mjs,cjs,ts}'];
10
10
  export default {
11
11
  title,
12
12
  enablers,
13
13
  isEnabled,
14
- config,
14
+ entry,
15
15
  };
@@ -1,4 +1,4 @@
1
- import { toDeferResolve, toDependency } from '../../util/input.js';
1
+ import { toDeferResolve, toDependency, toProductionEntry } from '../../util/input.js';
2
2
  import { hasDependency } from '../../util/plugin.js';
3
3
  const title = 'Gatsby';
4
4
  const enablers = ['gatsby', 'gatsby-cli'];
@@ -14,10 +14,10 @@ const production = [
14
14
  ];
15
15
  const resolveConfig = async (localConfig, options) => {
16
16
  const { configFileName } = options;
17
+ const entries = production.map(id => toProductionEntry(id));
17
18
  if (configFileName.includes('gatsby-config')) {
18
- return localConfig.plugins
19
- .map(plugin => (typeof plugin === 'string' ? plugin : plugin.resolve))
20
- .map(id => toDeferResolve(id));
19
+ const plugins = localConfig.plugins ?? [];
20
+ return [...entries, ...plugins.map(plugin => toDeferResolve(typeof plugin === 'string' ? plugin : plugin.resolve))];
21
21
  }
22
22
  if (configFileName.includes('gatsby-node')) {
23
23
  const plugins = new Set();
@@ -26,9 +26,9 @@ const resolveConfig = async (localConfig, options) => {
26
26
  if (typeof _config.onCreateBabelConfig === 'function') {
27
27
  _config.onCreateBabelConfig({ actions });
28
28
  }
29
- return Array.from(plugins).map(id => toDependency(id));
29
+ return [...entries, ...Array.from(plugins, id => toDependency(id))];
30
30
  }
31
- return [];
31
+ return entries;
32
32
  };
33
33
  const plugin = {
34
34
  title,
@@ -1,5 +1,5 @@
1
1
  export type GatsbyConfig = {
2
- plugins: (string | {
2
+ plugins?: (string | {
3
3
  resolve: string;
4
4
  })[];
5
5
  };
@@ -34,7 +34,7 @@ const resolveConfig = async (config, options) => {
34
34
  const manifest = getManifest(dir) ?? options.manifest;
35
35
  const actionPath = relative(dir, configFileDir);
36
36
  const run = step.run.replace(ACTION_PATH_VAR, actionPath ? `./${actionPath}` : '.');
37
- for (const input of getInputsFromScripts([run], { optionalBinaries: true, manifest })) {
37
+ for (const input of getInputsFromScripts([run], { optionalBinaries: true, manifest, cwd: dir })) {
38
38
  if (isDeferResolveEntry(input) && path && !workingDir) {
39
39
  input.specifier = relative(join(dir, path), join(rootCwd, input.specifier));
40
40
  }
@@ -2,7 +2,7 @@ import { hasDependency } from '../../util/plugin.js';
2
2
  const title = 'i18next Parser';
3
3
  const enablers = ['i18next-parser'];
4
4
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
- const config = ['i18next-parser.config.{js,mjs,json,ts,yaml,yml}'];
5
+ const entry = ['i18next-parser.config.{js,mjs,json,ts,yaml,yml}'];
6
6
  const args = {
7
7
  binaries: ['i18next'],
8
8
  config: true,
@@ -11,7 +11,7 @@ const plugin = {
11
11
  title,
12
12
  enablers,
13
13
  isEnabled,
14
- config,
14
+ entry,
15
15
  args,
16
16
  };
17
17
  export default plugin;
@@ -42,7 +42,7 @@ export declare const Plugins: {
42
42
  title: string;
43
43
  enablers: string[];
44
44
  isEnabled: import("../types/config.ts").IsPluginEnabled;
45
- config: string[];
45
+ entry: string[];
46
46
  };
47
47
  fast: import("../types/config.ts").Plugin;
48
48
  'filesystem-routing': import("../types/config.ts").Plugin;
@@ -60,9 +60,11 @@ export declare const Plugins: {
60
60
  jest: import("../types/config.ts").Plugin;
61
61
  karma: import("../types/config.ts").Plugin;
62
62
  knex: import("../types/config.ts").Plugin;
63
+ 'kysely-codegen': import("../types/config.ts").Plugin;
63
64
  ladle: import("../types/config.ts").Plugin;
64
65
  'laravel-vite-plugin': import("../types/config.ts").Plugin;
65
66
  lefthook: import("../types/config.ts").Plugin;
67
+ lingui: import("../types/config.ts").Plugin;
66
68
  'lint-staged': import("../types/config.ts").Plugin;
67
69
  linthtml: import("../types/config.ts").Plugin;
68
70
  lit: import("../types/config.ts").Plugin;
@@ -71,6 +73,7 @@ export declare const Plugins: {
71
73
  lunaria: import("../types/config.ts").Plugin;
72
74
  markdownlint: import("../types/config.ts").Plugin;
73
75
  marko: import("../types/config.ts").Plugin;
76
+ mastra: import("../types/config.ts").Plugin;
74
77
  mcp: import("../types/config.ts").Plugin;
75
78
  mdx: import("../types/config.ts").Plugin;
76
79
  mdxlint: import("../types/config.ts").Plugin;
@@ -117,6 +120,7 @@ export declare const Plugins: {
117
120
  preconstruct: import("../types/config.ts").Plugin;
118
121
  prettier: import("../types/config.ts").Plugin;
119
122
  prisma: import("../types/config.ts").Plugin;
123
+ purgecss: import("../types/config.ts").Plugin;
120
124
  quasar: import("../types/config.ts").Plugin;
121
125
  qwik: import("../types/config.ts").Plugin;
122
126
  railway: import("../types/config.ts").Plugin;
@@ -54,9 +54,11 @@ import { default as jasmine } from './jasmine/index.js';
54
54
  import { default as jest } from './jest/index.js';
55
55
  import { default as karma } from './karma/index.js';
56
56
  import { default as knex } from './knex/index.js';
57
+ import { default as kyselyCodegen } from './kysely-codegen/index.js';
57
58
  import { default as ladle } from './ladle/index.js';
58
59
  import { default as laravelVitePlugin } from './laravel-vite-plugin/index.js';
59
60
  import { default as lefthook } from './lefthook/index.js';
61
+ import { default as lingui } from './lingui/index.js';
60
62
  import { default as lintStaged } from './lint-staged/index.js';
61
63
  import { default as linthtml } from './linthtml/index.js';
62
64
  import { default as lit } from './lit/index.js';
@@ -65,6 +67,7 @@ import { default as lostPixel } from './lost-pixel/index.js';
65
67
  import { default as lunaria } from './lunaria/index.js';
66
68
  import { default as markdownlint } from './markdownlint/index.js';
67
69
  import { default as marko } from './marko/index.js';
70
+ import { default as mastra } from './mastra/index.js';
68
71
  import { default as mcp } from './mcp/index.js';
69
72
  import { default as mdx } from './mdx/index.js';
70
73
  import { default as mdxlint } from './mdxlint/index.js';
@@ -111,6 +114,7 @@ import { default as preCommit } from './pre-commit/index.js';
111
114
  import { default as preconstruct } from './preconstruct/index.js';
112
115
  import { default as prettier } from './prettier/index.js';
113
116
  import { default as prisma } from './prisma/index.js';
117
+ import { default as purgecss } from './purgecss/index.js';
114
118
  import { default as quasar } from './quasar/index.js';
115
119
  import { default as qwik } from './qwik/index.js';
116
120
  import { default as railway } from './railway/index.js';
@@ -253,9 +257,11 @@ export const Plugins = {
253
257
  jest,
254
258
  karma,
255
259
  knex,
260
+ 'kysely-codegen': kyselyCodegen,
256
261
  ladle,
257
262
  'laravel-vite-plugin': laravelVitePlugin,
258
263
  lefthook,
264
+ lingui,
259
265
  'lint-staged': lintStaged,
260
266
  linthtml,
261
267
  lit,
@@ -264,6 +270,7 @@ export const Plugins = {
264
270
  lunaria,
265
271
  markdownlint,
266
272
  marko,
273
+ mastra,
267
274
  mcp,
268
275
  mdx,
269
276
  mdxlint,
@@ -310,6 +317,7 @@ export const Plugins = {
310
317
  preconstruct,
311
318
  prettier,
312
319
  prisma,
320
+ purgecss,
313
321
  quasar,
314
322
  qwik,
315
323
  railway,
@@ -1,5 +1,5 @@
1
1
  import { toDeferResolve, toEntry } from '../../util/input.js';
2
- import { isAbsolute, join } from '../../util/path.js';
2
+ import { toAbsolute } from '../../util/path.js';
3
3
  import { hasDependency } from '../../util/plugin.js';
4
4
  const title = 'Jasmine';
5
5
  const enablers = ['jasmine'];
@@ -10,7 +10,7 @@ const entry = [defaultSpecFiles, 'spec/helpers/**/*.{js,mjs}'];
10
10
  const toSpecDirPattern = (specDir, pattern) => {
11
11
  const isNegated = pattern.startsWith('!');
12
12
  const id = isNegated ? pattern.slice(1) : pattern;
13
- const resolved = isAbsolute(id) ? id : join(specDir, id);
13
+ const resolved = toAbsolute(id, specDir);
14
14
  return isNegated ? `!${resolved}` : resolved;
15
15
  };
16
16
  const resolveConfig = (localConfig, options) => {