knip 6.38.0 → 6.40.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 (77) hide show
  1. package/dist/ConfigurationChief.d.ts +18 -0
  2. package/dist/WorkspaceWorker.d.ts +3 -4
  3. package/dist/WorkspaceWorker.js +12 -38
  4. package/dist/compilers/compilers.js +1 -1
  5. package/dist/constants.js +1 -0
  6. package/dist/graph/analyze.js +14 -5
  7. package/dist/graph/build.js +17 -10
  8. package/dist/graph-explorer/explorer.d.ts +1 -1
  9. package/dist/graph-explorer/operations/is-referenced.d.ts +1 -1
  10. package/dist/graph-explorer/operations/is-referenced.js +8 -4
  11. package/dist/plugins/_vue/auto-import.js +17 -10
  12. package/dist/plugins/angular/index.js +1 -1
  13. package/dist/plugins/capacitor/index.js +1 -1
  14. package/dist/plugins/commitlint/index.js +34 -9
  15. package/dist/plugins/cucumber/index.js +36 -4
  16. package/dist/plugins/cucumber/types.d.ts +2 -1
  17. package/dist/plugins/eslint/resolveFromAST.d.ts +0 -1
  18. package/dist/plugins/eslint/resolveFromAST.js +1 -1
  19. package/dist/plugins/index.d.ts +3 -0
  20. package/dist/plugins/index.js +6 -0
  21. package/dist/plugins/jasmine/index.d.ts +3 -0
  22. package/dist/plugins/jasmine/index.js +55 -0
  23. package/dist/plugins/jasmine/types.d.ts +7 -0
  24. package/dist/plugins/jasmine/types.js +1 -0
  25. package/dist/plugins/jest/helpers.d.ts +1 -0
  26. package/dist/plugins/jest/helpers.js +2 -0
  27. package/dist/plugins/jest/index.js +20 -11
  28. package/dist/plugins/osls/index.d.ts +3 -0
  29. package/dist/plugins/osls/index.js +13 -0
  30. package/dist/plugins/oxlint/index.d.ts +3 -0
  31. package/dist/plugins/oxlint/index.js +4 -31
  32. package/dist/plugins/oxlint/types.d.ts +1 -0
  33. package/dist/plugins/playwright/index.js +20 -3
  34. package/dist/plugins/playwright/types.d.ts +5 -0
  35. package/dist/plugins/postcss/index.js +5 -1
  36. package/dist/plugins/railway/index.d.ts +3 -0
  37. package/dist/plugins/railway/index.js +129 -0
  38. package/dist/plugins/rsbuild/index.js +42 -4
  39. package/dist/plugins/rsbuild/types.d.ts +18 -1
  40. package/dist/plugins/rspack/index.d.ts +3 -1
  41. package/dist/plugins/rspack/index.js +1 -1
  42. package/dist/plugins/rstest/index.js +116 -17
  43. package/dist/plugins/rstest/types.d.ts +29 -5
  44. package/dist/plugins/rstest/visitors/mock.d.ts +2 -0
  45. package/dist/plugins/rstest/visitors/mock.js +52 -0
  46. package/dist/plugins/serverless-framework/index.d.ts +4 -1
  47. package/dist/plugins/serverless-framework/index.js +40 -7
  48. package/dist/plugins/serverless-framework/types.d.ts +4 -2
  49. package/dist/plugins/simple-git-hooks/index.js +1 -1
  50. package/dist/plugins/vite/helpers.d.ts +1 -1
  51. package/dist/plugins/vite/helpers.js +7 -8
  52. package/dist/plugins/vitest/index.js +31 -7
  53. package/dist/plugins/vitest/types.d.ts +12 -0
  54. package/dist/schema/configuration.d.ts +45 -0
  55. package/dist/schema/plugins.d.ts +15 -0
  56. package/dist/schema/plugins.js +3 -0
  57. package/dist/types/PluginNames.d.ts +2 -2
  58. package/dist/types/PluginNames.js +3 -0
  59. package/dist/types/package-json.d.ts +5 -0
  60. package/dist/typescript/ast-nodes.js +291 -0
  61. package/dist/typescript/resolve-module-names.js +15 -4
  62. package/dist/typescript/visitors/walk.js +12 -0
  63. package/dist/util/create-options.d.ts +30 -0
  64. package/dist/util/filter-transitive-dependencies.d.ts +2 -0
  65. package/dist/util/filter-transitive-dependencies.js +38 -0
  66. package/dist/util/git.d.ts +1 -0
  67. package/dist/util/git.js +23 -1
  68. package/dist/util/package-json.d.ts +1 -348
  69. package/dist/util/package-json.js +56 -10
  70. package/dist/util/tag.d.ts +1 -0
  71. package/dist/util/tag.js +1 -1
  72. package/dist/util/to-source-path.d.ts +1 -1
  73. package/dist/util/to-source-path.js +7 -5
  74. package/dist/version.d.ts +1 -1
  75. package/dist/version.js +1 -1
  76. package/package.json +1 -1
  77. package/schema.json +12 -0
@@ -292,6 +292,11 @@ export declare class ConfigurationChief {
292
292
  entry?: string | string[] | undefined;
293
293
  project?: string | string[] | undefined;
294
294
  } | undefined;
295
+ jasmine?: string | boolean | string[] | {
296
+ config?: string | string[] | undefined;
297
+ entry?: string | string[] | undefined;
298
+ project?: string | string[] | undefined;
299
+ } | undefined;
295
300
  jest?: string | boolean | string[] | {
296
301
  config?: string | string[] | undefined;
297
302
  entry?: string | string[] | undefined;
@@ -497,6 +502,11 @@ export declare class ConfigurationChief {
497
502
  entry?: string | string[] | undefined;
498
503
  project?: string | string[] | undefined;
499
504
  } | undefined;
505
+ osls?: string | boolean | string[] | {
506
+ config?: string | string[] | undefined;
507
+ entry?: string | string[] | undefined;
508
+ project?: string | string[] | undefined;
509
+ } | undefined;
500
510
  oxfmt?: string | boolean | string[] | {
501
511
  config?: string | string[] | undefined;
502
512
  entry?: string | string[] | undefined;
@@ -592,6 +602,11 @@ export declare class ConfigurationChief {
592
602
  entry?: string | string[] | undefined;
593
603
  project?: string | string[] | undefined;
594
604
  } | undefined;
605
+ railway?: string | boolean | string[] | {
606
+ config?: string | string[] | undefined;
607
+ entry?: string | string[] | undefined;
608
+ project?: string | string[] | undefined;
609
+ } | undefined;
595
610
  raycast?: string | boolean | string[] | {
596
611
  config?: string | string[] | undefined;
597
612
  entry?: string | string[] | undefined;
@@ -1072,6 +1087,7 @@ export declare class ConfigurationChief {
1072
1087
  hardhat?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1073
1088
  husky?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1074
1089
  "i18next-parser"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1090
+ jasmine?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1075
1091
  jest?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1076
1092
  karma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1077
1093
  knex?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1113,6 +1129,7 @@ export declare class ConfigurationChief {
1113
1129
  "openapi-ts"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1114
1130
  openclaw?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1115
1131
  orval?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1132
+ osls?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1116
1133
  oxfmt?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1117
1134
  oxlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1118
1135
  "panda-css"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1132,6 +1149,7 @@ export declare class ConfigurationChief {
1132
1149
  prisma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1133
1150
  quasar?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1134
1151
  qwik?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1152
+ railway?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1135
1153
  raycast?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1136
1154
  "react-cosmos"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1137
1155
  "react-email"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -49,7 +49,7 @@ export declare class WorkspaceWorker {
49
49
  enabledPluginsMap: Partial<Record<PluginName, boolean>>;
50
50
  enabledPlugins: PluginName[];
51
51
  enabledPluginsInAncestors: string[];
52
- cache: CacheConsultant<CacheItem>;
52
+ cache: CacheConsultant<Partial<Record<PluginName, CacheItem>>>;
53
53
  configFilesMap: Map<string, Map<PluginName, Set<string>>>;
54
54
  constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, handleConfigLoadError, findWorkspaceByFilePath, getManifest, readRawFile, configFilesMap, options, }: WorkspaceManagerOptions);
55
55
  init(): Promise<void>;
@@ -61,14 +61,13 @@ export declare class WorkspaceWorker {
61
61
  private getPluginConfig;
62
62
  getPluginConfigPatterns(): string[];
63
63
  getPluginEntryFilePatterns(patterns: string[]): string[];
64
- getProductionEntryFilePatterns(negatedTestFilePatterns: string[]): string[];
65
- getProductionProjectFilePatterns(negatedTestFilePatterns: string[]): string[];
64
+ getProductionEntryFilePatterns(): string[];
65
+ getProductionProjectFilePatterns(): string[];
66
66
  private getConfigurationFilePatterns;
67
67
  registerCompilers(registerCompiler: RegisterCompiler): Promise<void>;
68
68
  resolveSourceMaps(): Promise<SourceMap[]>;
69
69
  registerVisitors(options: RegisterVisitorsOptions): void;
70
70
  runPlugins(): Promise<Input[]>;
71
- private filterTransitiveDependencies;
72
71
  getConfigurationHints(type: 'entry' | 'project', patterns: string[], filePaths: string[], includedPaths: Set<string>, compilerExtensions?: Set<string>): ConfigurationHint[];
73
72
  onDispose(): void;
74
73
  }
@@ -6,15 +6,15 @@ import { DEFAULT_EXTENSIONS, ROOT_WORKSPACE_NAME } from './constants.js';
6
6
  import { getFilteredScripts } from './manifest/helpers.js';
7
7
  import { PluginEntries, Plugins } from './plugins.js';
8
8
  import { createManifest } from './util/package-json.js';
9
- import { collectStringLiterals, isExternalReExportsOnly } from './typescript/ast-helpers.js';
9
+ import { isExternalReExportsOnly } from './typescript/ast-helpers.js';
10
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';
14
- import { isCatalog, isConfig, isDeferResolve, isDependency, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
15
- import { getPackageNameFromSpecifier } from './util/modules.js';
14
+ import { isCatalog, isConfig, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
15
+ import { filterTransitiveDependencies } from './util/filter-transitive-dependencies.js';
16
16
  import { timerify } from './util/Performance.js';
17
- import { basename, dirname, isInternal, join, toRelative } from './util/path.js';
17
+ import { basename, dirname, join, toRelative } from './util/path.js';
18
18
  import { extractPatternExtensions } from './util/pattern-extensions.js';
19
19
  import { formatCauseMessage } from './util/errors.js';
20
20
  import { logError } from './util/log.js';
@@ -132,17 +132,17 @@ export class WorkspaceWorker {
132
132
  const negateWorkspaces = patterns.some(pattern => pattern.startsWith('**/')) ? this.negatedWorkspacePatterns : [];
133
133
  return [patterns, negateWorkspaces, this.ignoredWorkspacePatterns.map(negate)].flat();
134
134
  }
135
- getProductionEntryFilePatterns(negatedTestFilePatterns) {
135
+ getProductionEntryFilePatterns() {
136
136
  const entry = this.config.entry.filter(hasProductionSuffix);
137
137
  if (entry.length === 0)
138
138
  return [];
139
139
  const negatedEntryFiles = this.config.entry.filter(hasNoProductionSuffix).map(negate);
140
- return [entry, negatedEntryFiles, negatedTestFilePatterns, this.negatedWorkspacePatterns].flat();
140
+ return [entry, negatedEntryFiles, this.negatedWorkspacePatterns].flat();
141
141
  }
142
- getProductionProjectFilePatterns(negatedTestFilePatterns) {
142
+ getProductionProjectFilePatterns() {
143
143
  const project = this.config.project;
144
144
  if (project.length === 0)
145
- return this.getProductionEntryFilePatterns(negatedTestFilePatterns);
145
+ return this.getProductionEntryFilePatterns();
146
146
  const _project = this.config.project.map(pattern => {
147
147
  if (!(pattern.endsWith('!') || pattern.startsWith('!')))
148
148
  return negate(pattern);
@@ -156,7 +156,6 @@ export class WorkspaceWorker {
156
156
  negatedEntryFiles,
157
157
  negatedPluginConfigPatterns,
158
158
  negatedPluginProjectFilePatterns,
159
- negatedTestFilePatterns,
160
159
  this.negatedWorkspacePatterns,
161
160
  ].flat();
162
161
  }
@@ -326,8 +325,8 @@ export class WorkspaceWorker {
326
325
  seenConfigFiles.add(configFilePath);
327
326
  const isManifest = basename(configFilePath) === 'package.json';
328
327
  const fd = isManifest ? undefined : this.cache.getFileDescriptor(configFilePath);
329
- if (fd?.meta?.data && !fd.changed) {
330
- const data = fd.meta.data;
328
+ const data = fd?.changed ? undefined : fd?.meta?.data?.[pluginName];
329
+ if (data) {
331
330
  if (data.resolveConfig)
332
331
  for (const id of data.resolveConfig)
333
332
  addInput(id, configFilePath);
@@ -370,7 +369,7 @@ export class WorkspaceWorker {
370
369
  if (localConfig) {
371
370
  const inputs = await plugin.resolveConfig(localConfig, resolveOpts);
372
371
  if (plugin.isFilterTransitiveDependencies && !isManifest) {
373
- this.filterTransitiveDependencies(inputs, configFilePath);
372
+ filterTransitiveDependencies(inputs, configFilePath, this.readRawFile);
374
373
  }
375
374
  for (const input of inputs)
376
375
  addInput(input, configFilePath);
@@ -405,7 +404,7 @@ export class WorkspaceWorker {
405
404
  this.cache.removeEntry(configFilePath);
406
405
  }
407
406
  else if (fd?.meta) {
408
- fd.meta.data = cache;
407
+ fd.meta.data = { ...fd.meta.data, [pluginName]: cache };
409
408
  }
410
409
  }
411
410
  }
@@ -458,31 +457,6 @@ export class WorkspaceWorker {
458
457
  debugLogArray(wsName, 'Plugin dependencies', () => compact(inputs.map(input => toDebugString(input, rootCwd))));
459
458
  return inputs;
460
459
  }
461
- filterTransitiveDependencies(inputs, configFilePath) {
462
- const literals = new Set();
463
- const visited = new Set();
464
- const collect = (filePath) => {
465
- if (visited.has(filePath))
466
- return;
467
- visited.add(filePath);
468
- const sourceText = this.readRawFile(filePath);
469
- if (!sourceText)
470
- return;
471
- for (const literal of collectStringLiterals(sourceText, filePath)) {
472
- literals.add(literal);
473
- if (isInternal(literal))
474
- collect(join(dirname(filePath), literal));
475
- }
476
- };
477
- collect(configFilePath);
478
- for (const input of inputs) {
479
- if (!input.optional && (isDeferResolve(input) || isDependency(input))) {
480
- const name = getPackageNameFromSpecifier(input.specifier);
481
- if (name && !literals.has(name))
482
- input.optional = true;
483
- }
484
- }
485
- }
486
460
  getConfigurationHints(type, patterns, filePaths, includedPaths, compilerExtensions) {
487
461
  const hints = [];
488
462
  const entries = this.config[type].filter(pattern => !pattern.startsWith('!'));
@@ -1,6 +1,6 @@
1
1
  export const fencedCodeBlockMatcher = /```[\s\S]*?```/g;
2
2
  export const inlineCodeMatcher = /`[^`]+`/g;
3
- export const scriptExtractor = /<script\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/script>/gi;
3
+ export const scriptExtractor = /<script\b((?:[^>"']|"[^"]*"|'[^']*')*)(?<!\/)>([\s\S]*?)<\/script>/gi;
4
4
  export const styleExtractor = /<style\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/style>/gi;
5
5
  const langAttrMatcher = /\blang\s*=\s*["']([^"']+)["']/i;
6
6
  export const blockCommentMatcher = /\/\*[\s\S]*?\*\//g;
package/dist/constants.js CHANGED
@@ -115,6 +115,7 @@ export const IGNORED_GLOBAL_BINARIES = new Set([
115
115
  'python',
116
116
  'python3',
117
117
  'raft',
118
+ 'railway',
118
119
  'rm',
119
120
  'rmdir',
120
121
  'rsync',
@@ -6,7 +6,7 @@ import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
6
6
  import { relative } from '../util/path.js';
7
7
  import { perfObserver, timerify } from '../util/Performance.js';
8
8
  import { findMatch } from '../util/regex.js';
9
- import { getShouldIgnoreHandler, getShouldIgnoreTagHandler, isAlwaysIgnored } from '../util/tag.js';
9
+ import { getShouldIgnoreHandler, getShouldIgnoreTagHandler, hasTag, isAlwaysIgnored } from '../util/tag.js';
10
10
  import { 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;
@@ -123,7 +123,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
123
123
  const isInternalProd = options.isProduction && exportedItem.jsDocTags.has(INTERNAL_TAG);
124
124
  const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags) || isInternalProd;
125
125
  if (importsForExport) {
126
- const [isReferenced, reExportingEntryFile] = explorer.isReferenced(filePath, identifier, {
126
+ const [isReferenced, reExportingEntryFile, reExportedIds] = explorer.isReferenced(filePath, identifier, {
127
127
  traverseEntries: isIncludeEntryExports,
128
128
  });
129
129
  if (isIgnored) {
@@ -148,9 +148,18 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
148
148
  if (!isIncludeEntryExports) {
149
149
  continue;
150
150
  }
151
- if (!isReferenced) {
152
- const reExportedItem = graph.get(reExportingEntryFile)?.exports.get(identifier);
153
- if (reExportedItem && shouldIgnore(reExportedItem.jsDocTags))
151
+ if (!isReferenced && reExportedIds) {
152
+ const entryExports = graph.get(reExportingEntryFile)?.exports;
153
+ let isTagged = false;
154
+ for (const id of reExportedIds) {
155
+ const reExportedItem = entryExports?.get(id);
156
+ if (reExportedItem &&
157
+ (shouldIgnore(reExportedItem.jsDocTags) || hasTag(options.tags[1], reExportedItem.jsDocTags))) {
158
+ isTagged = true;
159
+ break;
160
+ }
161
+ }
162
+ if (isTagged)
154
163
  continue;
155
164
  }
156
165
  }
@@ -9,7 +9,7 @@ import { existsSync } from 'node:fs';
9
9
  import picomatch from 'picomatch';
10
10
  import { tryRealpath } from '../util/fs.js';
11
11
  import { createManifest } from '../util/package-json.js';
12
- import { _glob, _syncGlob, negate, prependDirToPattern as prependDir } from '../util/glob.js';
12
+ import { _glob, _syncGlob, prependDirToPattern as prependDir, removeProductionSuffix } from '../util/glob.js';
13
13
  import { isAlias, isCatalog, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toDeferResolveEntry, toDependency, toProductionEntry, } from '../util/input.js';
14
14
  import { isAmbientDeclarationFile } from '../typescript/ast-nodes.js';
15
15
  import { resolveImportGlobs } from '../typescript/glob-imports.js';
@@ -19,6 +19,7 @@ import { createFileNode, updateImportMap } from '../util/module-graph.js';
19
19
  import { getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
20
20
  import { perfObserver } from '../util/Performance.js';
21
21
  import { getEntrySpecifiersFromManifest, getManifestImportDependencies } from '../util/package-json.js';
22
+ import { expandIgnorePatterns } from '../util/parse-and-convert-gitignores.js';
22
23
  import { dirname, extname, isAbsolute, isInNodeModules, isInternal, join, relative } from '../util/path.js';
23
24
  import { extensionAlias } from '../util/resolve.js';
24
25
  import { augmentWorkspace, getToSourcePathsHandler, toSourceMappedSpecifiers } from '../util/to-source-path.js';
@@ -246,16 +247,22 @@ export async function build({ chief, collector, counselor, deputy, principal, is
246
247
  }
247
248
  }
248
249
  }
249
- const negatedEntryPatterns = [];
250
+ const developmentMatchers = [];
250
251
  if (options.isProduction) {
252
+ const toPattern = (pattern) => join(isAbsolute(pattern) ? '' : dir, removeProductionSuffix(pattern));
251
253
  for (const map of [entryPatterns, entryPatternsSkipExports]) {
252
- for (const patterns of map.values())
253
- for (const pattern of patterns)
254
- negatedEntryPatterns.push(negate(pattern));
254
+ for (const patterns of map.values()) {
255
+ const [excluded, included] = partition(patterns, pattern => pattern.startsWith('!'));
256
+ if (included.length === 0)
257
+ continue;
258
+ const ignore = expandIgnorePatterns(excluded.map(pattern => removeProductionSuffix(pattern.slice(1))));
259
+ developmentMatchers.push(picomatch(included.map(toPattern), { ignore: ignore.map(toPattern), dot: true }));
260
+ }
255
261
  }
256
262
  }
263
+ const productionPaths = (paths) => developmentMatchers.length ? paths.filter(path => !developmentMatchers.some(match => match(path))) : paths;
257
264
  const userEntryPatterns = options.isProduction
258
- ? worker.getProductionEntryFilePatterns(negatedEntryPatterns)
265
+ ? worker.getProductionEntryFilePatterns()
259
266
  : worker.getEntryFilePatterns();
260
267
  const userEntryPaths = await _glob({
261
268
  ...sharedGlobOptions,
@@ -272,7 +279,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
272
279
  ]);
273
280
  const label = `entry paths from plugins${group !== DEFAULT_GROUP ? ` - ${group}` : ''}`;
274
281
  const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
275
- principal.addEntryPaths(pluginWorkspaceEntryPaths);
282
+ principal.addEntryPaths(productionPaths(pluginWorkspaceEntryPaths));
276
283
  }
277
284
  {
278
285
  const patterns = worker.getPluginEntryFilePatterns([
@@ -293,7 +300,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
293
300
  collector.addConfigurationHint(hint);
294
301
  }
295
302
  const hasExplicitEntries = config.entry.some(pattern => !isDefaultPattern('entry', pattern));
296
- principal.addEntryPaths(userEntryPaths, hasExplicitEntries ? { skipExportsAnalysis: false } : undefined);
303
+ principal.addEntryPaths(productionPaths(userEntryPaths), hasExplicitEntries ? { skipExportsAnalysis: false } : undefined);
297
304
  if (options.isUseTscFiles && isFile) {
298
305
  const isIgnoredWorkspace = chief.createIgnoredWorkspaceMatcher(name, dir);
299
306
  debugLogArray(name, 'Using tsconfig files as project files', tscSourcePaths);
@@ -320,7 +327,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
320
327
  }
321
328
  else {
322
329
  const patterns = options.isProduction
323
- ? worker.getProductionProjectFilePatterns(negatedEntryPatterns)
330
+ ? worker.getProductionProjectFilePatterns()
324
331
  : worker.getProjectFilePatterns([
325
332
  ...(productionPatternsSkipExports.get(DEFAULT_GROUP) ?? []),
326
333
  ...projectFilePatterns,
@@ -332,7 +339,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
332
339
  for (const hint of hints)
333
340
  collector.addConfigurationHint(hint);
334
341
  }
335
- for (const projectPath of projectPaths)
342
+ for (const projectPath of productionPaths(projectPaths))
336
343
  principal.addProjectPath(projectPath);
337
344
  }
338
345
  worker.onDispose();
@@ -3,7 +3,7 @@ export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<s
3
3
  isReferenced: (filePath: string, identifier: string, options: {
4
4
  traverseEntries: boolean;
5
5
  treatStarAtEntryAsReferenced?: boolean;
6
- }) => readonly [false, string | undefined];
6
+ }) => readonly [false, string | undefined, Set<string> | undefined];
7
7
  hasStrictlyNsReferences: (filePath: string, identifier: string) => [boolean, (string | undefined)?];
8
8
  isEnumerated: (filePath: string, identifier: string) => boolean;
9
9
  buildExportsTree: (options: {
@@ -2,4 +2,4 @@ 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
3
  traverseEntries: boolean;
4
4
  treatStarAtEntryAsReferenced?: boolean;
5
- }) => readonly [false, string | undefined];
5
+ }) => readonly [false, string | undefined, Set<string> | undefined];
@@ -17,18 +17,22 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
17
17
  const seen = new Set();
18
18
  let isReferenced = false;
19
19
  let reExportingEntryFile;
20
+ let reExportedIds;
20
21
  const hasCompleteResult = () => isReferenced && (options.traverseEntries || reExportingEntryFile !== undefined);
21
22
  const walkDown = (path, id, viaStar = false) => {
22
23
  const isEntryFile = entryPaths.has(path);
23
24
  if (isEntryFile && !reExportingEntryFile)
24
25
  reExportingEntryFile = path;
26
+ if (path === reExportingEntryFile)
27
+ (reExportedIds ??= new Set()).add(id);
25
28
  if (hasCompleteResult())
26
29
  return true;
27
- if (seen.has(path))
28
- return false;
29
- seen.add(path);
30
30
  const restIds = id.split('.');
31
31
  const identifier = restIds.shift();
32
+ const key = `${path}:${identifier}`;
33
+ if (seen.has(key))
34
+ return false;
35
+ seen.add(key);
32
36
  if (options.treatStarAtEntryAsReferenced && isEntryFile && viaStar && restIds.length > 0) {
33
37
  isReferenced = true;
34
38
  return hasCompleteResult();
@@ -117,5 +121,5 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
117
121
  return false;
118
122
  };
119
123
  walkDown(filePath, id);
120
- return [isReferenced, reExportingEntryFile];
124
+ return [isReferenced, reExportingEntryFile, reExportedIds];
121
125
  };
@@ -3,10 +3,12 @@ import { createRequire } from 'node:module';
3
3
  import { Visitor } from 'oxc-parser';
4
4
  import { scriptBodies } from '../../compilers/compilers.js';
5
5
  import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
6
+ import { DEFAULT_EXTENSIONS } from '../../constants.js';
6
7
  import { _parseFile } from '../../typescript/ast-nodes.js';
7
8
  import { isFile } from '../../util/fs.js';
8
9
  import { _syncGlob } from '../../util/glob.js';
9
10
  import { dirname, isInNodeModules, join } from '../../util/path.js';
11
+ import { _createSyncModuleResolver } from '../../util/resolve.js';
10
12
  const getVueSfc = (cwd) => {
11
13
  try {
12
14
  const sfc = createRequire(join(cwd, 'package.json'))('vue/compiler-sfc');
@@ -124,6 +126,7 @@ const collectVue2TemplateIdentifiers = (source) => {
124
126
  };
125
127
  const toKebabCase = (s) => s.replace(/[A-Z]/g, (m, i) => (i ? '-' : '') + m.toLowerCase());
126
128
  const isLocalSpecifier = (specifier) => specifier.startsWith('.') && !isInNodeModules(specifier);
129
+ const resolveModule = _createSyncModuleResolver([...DEFAULT_EXTENSIONS, '.vue']);
127
130
  export const collectLocalImportPaths = (filePath, result) => {
128
131
  const dir = dirname(filePath);
129
132
  const paths = new Set();
@@ -150,7 +153,7 @@ export function buildAutoImportMap(filePath, result, maps, isComponents) {
150
153
  const importType = importTypes.find(it => it.start >= start && it.end <= end);
151
154
  if (!importType || !isLocalSpecifier(importType.specifier))
152
155
  return;
153
- const absSpecifier = join(dir, importType.specifier);
156
+ const absSpecifier = resolveModule(importType.specifier, filePath) ?? join(dir, importType.specifier);
154
157
  if (isComponents) {
155
158
  const components = maps.componentMap.get(name);
156
159
  if (components) {
@@ -184,7 +187,7 @@ export function buildAutoImportMap(filePath, result, maps, isComponents) {
184
187
  const specifier = node.source.value;
185
188
  if (!isLocalSpecifier(specifier))
186
189
  return;
187
- const absSpecifier = join(dir, specifier);
190
+ const absSpecifier = resolveModule(specifier, filePath) ?? join(dir, specifier);
188
191
  for (const s of node.specifiers) {
189
192
  const name = s.exported.type === 'Identifier' ? s.exported.name : s.exported.value;
190
193
  if (name)
@@ -210,14 +213,15 @@ const getVueAutoImportMaps = (cwd) => {
210
213
  }
211
214
  return maps;
212
215
  };
213
- const getSyntheticImports = (maps, identifiers, templateTags) => {
216
+ const getSyntheticImports = (maps, identifiers, filePath, templateTags) => {
214
217
  const { importMap, componentMap } = maps;
215
218
  if (importMap.size === 0 && (!templateTags || componentMap.size === 0))
216
219
  return [];
217
220
  const syntheticImports = [];
218
221
  for (const [name, specifier] of importMap) {
219
- if (identifiers.has(name))
222
+ if (identifiers.has(name) && specifier !== filePath) {
220
223
  syntheticImports.push(`import { ${name} } from '${specifier}';`);
224
+ }
221
225
  }
222
226
  if (templateTags) {
223
227
  for (const [name, specifiers] of componentMap) {
@@ -226,9 +230,12 @@ const getSyntheticImports = (maps, identifiers, templateTags) => {
226
230
  templateTags.has(kebab) ||
227
231
  templateTags.has(`Lazy${name}`) ||
228
232
  templateTags.has(`lazy-${kebab}`)) {
229
- syntheticImports.push(`import { default as ${name} } from '${specifiers[0]}';`);
230
- for (let i = 1; i < specifiers.length; i++)
231
- syntheticImports.push(`import '${specifiers[i]}';`);
233
+ const targets = specifiers.filter(specifier => specifier !== filePath);
234
+ if (targets.length === 0)
235
+ continue;
236
+ syntheticImports.push(`import { default as ${name} } from '${targets[0]}';`);
237
+ for (let i = 1; i < targets.length; i++)
238
+ syntheticImports.push(`import '${targets[i]}';`);
232
239
  }
233
240
  }
234
241
  }
@@ -275,7 +282,7 @@ const compileVueSfc = (source, path, maps, root) => {
275
282
  for (const id of collectVue2TemplateIdentifiers(compiled.code))
276
283
  identifiers.add(id);
277
284
  }
278
- scripts.push(...getSyntheticImports(maps, identifiers, templateTags));
285
+ scripts.push(...getSyntheticImports(maps, identifiers, path, templateTags));
279
286
  scripts.push(...getImportedComponentImports(maps, importedComponents));
280
287
  const styles = stylePreprocessorImports(source, path);
281
288
  if (styles)
@@ -288,7 +295,7 @@ const compileTs = (source, path, maps) => {
288
295
  path.endsWith('.config.ts'))
289
296
  return source;
290
297
  const importedComponents = new Set();
291
- const syntheticImports = getSyntheticImports(maps, collectIdentifiers(source, path, importedComponents));
298
+ const syntheticImports = getSyntheticImports(maps, collectIdentifiers(source, path, importedComponents), path);
292
299
  syntheticImports.push(...getImportedComponentImports(maps, importedComponents));
293
300
  return syntheticImports.length === 0 ? source : `${source}\n${syntheticImports.join('\n')}`;
294
301
  };
@@ -305,7 +312,7 @@ const compileMarkdown = (source, path, maps) => {
305
312
  for (const [, tag] of code.matchAll(tagMatcher))
306
313
  tags.add(tag);
307
314
  const identifiers = scripts ? collectIdentifiers(scripts, path) : new Set();
308
- return [scripts, ...getSyntheticImports(maps, identifiers, tags)].filter(Boolean).join(';\n');
315
+ return [scripts, ...getSyntheticImports(maps, identifiers, path, tags)].filter(Boolean).join(';\n');
309
316
  };
310
317
  export const createVueCompiler = (maps, cwd) => (source, path) => compileVueSfc(source, path, maps, cwd);
311
318
  export const createTsCompiler = (maps) => (source, path) => compileTs(source, path, maps);
@@ -13,7 +13,7 @@ const resolveConfig = async (config, options) => {
13
13
  const inputs = new Set();
14
14
  for (const project of Object.values(config.projects)) {
15
15
  if (!project.architect)
16
- return [];
16
+ continue;
17
17
  for (const [targetName, target] of Object.entries(project.architect)) {
18
18
  const { options: opts, configurations: configs } = target;
19
19
  const [packageName] = typeof target.builder === 'string' ? target.builder.split(':') : [];
@@ -4,7 +4,7 @@ import { hasDependency } from '../../util/plugin.js';
4
4
  const title = 'Capacitor';
5
5
  const enablers = [/^@capacitor\//];
6
6
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
- const config = ['capacitor.config.{json,ts}'];
7
+ const config = ['capacitor.config.{json,js,ts}'];
8
8
  const resolveConfig = async (config, { configFileDir }) => {
9
9
  const plugins = config.includePlugins ?? [];
10
10
  const android = isFile(configFileDir, 'android/capacitor.settings.gradle') ? ['@capacitor/android'] : [];
@@ -1,4 +1,5 @@
1
- import { toDependency } from '../../util/input.js';
1
+ import { toConfig, toDependency } from '../../util/input.js';
2
+ import { isInternal } from '../../util/path.js';
2
3
  import { hasDependency } from '../../util/plugin.js';
3
4
  import { toCosmiconfig } from '../../util/plugin-config.js';
4
5
  const title = 'commitlint';
@@ -9,13 +10,35 @@ const config = [
9
10
  'package.yaml',
10
11
  ...toCosmiconfig('commitlint', { additionalExtensions: ['cts', 'mts'] }),
11
12
  ];
12
- const resolveConfig = async (config) => {
13
- const extendsConfigs = config.extends
14
- ? [config.extends]
15
- .flat()
16
- .map(id => (id.startsWith('@') || id.startsWith('commitlint-config-') ? id : `commitlint-config-${id}`))
17
- : [];
18
- const plugins = config.plugins ? [config.plugins].flat().filter(s => typeof s === 'string') : [];
13
+ const toExtendsSpecifier = (id) => {
14
+ if (id.startsWith('@'))
15
+ return id.includes('/') ? id : `${id}/commitlint-config`;
16
+ return id.startsWith('commitlint-config-') ? id : `commitlint-config-${id}`;
17
+ };
18
+ const toPluginSpecifier = (id) => {
19
+ if (!id.startsWith('@'))
20
+ return id.startsWith('commitlint-plugin-') ? id : `commitlint-plugin-${id}`;
21
+ const [scope, name] = id.split('/');
22
+ if (!name)
23
+ return `${scope}/commitlint-plugin`;
24
+ if (name === 'commitlint-plugin' || name.startsWith('commitlint-plugin-'))
25
+ return id;
26
+ return id.replace('/', '/commitlint-plugin-');
27
+ };
28
+ const resolveConfig = async (config, options) => {
29
+ const inputs = [];
30
+ const extendsConfigs = [];
31
+ for (const id of config.extends ? [config.extends].flat() : []) {
32
+ if (isInternal(id))
33
+ inputs.push(toConfig('commitlint', id, { containingFilePath: options.configFilePath }));
34
+ else
35
+ extendsConfigs.push(toExtendsSpecifier(id));
36
+ }
37
+ const plugins = [];
38
+ for (const id of config.plugins ? [config.plugins].flat() : []) {
39
+ if (typeof id === 'string')
40
+ plugins.push(toPluginSpecifier(id));
41
+ }
19
42
  const formatter = config.formatter ? [config.formatter] : [];
20
43
  const parserPreset = await config.parserPreset;
21
44
  const parserPresetPaths = parserPreset
@@ -25,7 +48,9 @@ const resolveConfig = async (config) => {
25
48
  ? [parserPreset.path ?? parserPreset]
26
49
  : []
27
50
  : [];
28
- return [...extendsConfigs, ...plugins, ...formatter, ...parserPresetPaths].map(id => toDependency(id));
51
+ for (const id of [...extendsConfigs, ...plugins, ...formatter, ...parserPresetPaths])
52
+ inputs.push(toDependency(id));
53
+ return inputs;
29
54
  };
30
55
  const plugin = {
31
56
  title,
@@ -5,11 +5,43 @@ const enablers = ['@cucumber/cucumber'];
5
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
6
  const config = ['cucumber.{json,yaml,yml,js,cjs,mjs}'];
7
7
  const entry = ['features/**/*.@(js|cjs|mjs)'];
8
- const resolveConfig = config => {
8
+ const builtinFormatters = new Set([
9
+ 'html',
10
+ 'json',
11
+ 'junit',
12
+ 'message',
13
+ 'pretty',
14
+ 'progress',
15
+ 'progress-bar',
16
+ 'rerun',
17
+ 'snippets',
18
+ 'summary',
19
+ 'usage',
20
+ 'usage-json',
21
+ ]);
22
+ const toFormatterName = (format) => {
23
+ if (Array.isArray(format))
24
+ return format[0];
25
+ const [name, quotedName] = format.match(/^"([^"]*)"|^[^:]*/) ?? [format];
26
+ return quotedName ?? name;
27
+ };
28
+ const resolveProfile = (config) => {
9
29
  const imports = (config?.import ? config.import : entry).map(id => toEntry(id));
10
- const formatters = config?.format ? config.format : [];
11
- const requires = config?.require ? config.require : [];
12
- return imports.concat([...formatters, ...requires].map(id => toDeferResolve(id)));
30
+ const requires = (config?.require ? config.require : []).map(id => toEntry(id));
31
+ const formatters = (config?.format ? config.format : [])
32
+ .map(toFormatterName)
33
+ .filter(name => !builtinFormatters.has(name))
34
+ .map(id => toDeferResolve(id));
35
+ return [...imports, ...requires, ...formatters];
36
+ };
37
+ const resolveConfig = (config, options) => {
38
+ if (typeof config !== 'object' || config === null)
39
+ return resolveProfile();
40
+ const isProfiles = /\.(json|ya?ml)$/.test(options.configFileName) || 'default' in config;
41
+ if (!isProfiles)
42
+ return resolveProfile(config);
43
+ const profiles = 'default' in config ? Object.values(config) : [undefined, ...Object.values(config)];
44
+ return profiles.flatMap(resolveProfile);
13
45
  };
14
46
  const plugin = {
15
47
  title,
@@ -2,6 +2,7 @@ export type CucumberConfig = {
2
2
  publishQuiet?: boolean;
3
3
  import?: string[];
4
4
  require?: string[];
5
- format?: string[];
5
+ format?: Format[];
6
6
  parallel?: number;
7
7
  };
8
+ export type Format = string | [string, string?];
@@ -1,4 +1,3 @@
1
1
  import type { Program } from 'oxc-parser';
2
2
  import { type Input } from '../../util/input.ts';
3
- export declare const getInputsFromSettingsAST: (program: Program) => Input[];
4
3
  export declare const getInputsFromFlatConfigAST: (program: Program) => Input[];
@@ -4,7 +4,7 @@ import { findProperty, getPropertyKey } from '../../typescript/ast-helpers.js';
4
4
  import { getStringValue } from '../../typescript/ast-nodes.js';
5
5
  import { isInternal } from '../../util/path.js';
6
6
  import { importSettingKinds } from './helpers.js';
7
- export const getInputsFromSettingsAST = (program) => {
7
+ const getInputsFromSettingsAST = (program) => {
8
8
  const inputs = [];
9
9
  const addResolver = (kind, resolver) => {
10
10
  if (!resolver || resolver === 'node' || isInternal(resolver))