knip 6.37.0 → 6.39.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 (61) hide show
  1. package/dist/ConfigurationChief.d.ts +18 -0
  2. package/dist/compilers/compilers.js +1 -1
  3. package/dist/constants.js +1 -0
  4. package/dist/graph/analyze.js +30 -17
  5. package/dist/graph-explorer/explorer.d.ts +1 -1
  6. package/dist/graph-explorer/operations/is-referenced.d.ts +1 -1
  7. package/dist/graph-explorer/operations/is-referenced.js +8 -4
  8. package/dist/plugins/_vue/auto-import.js +17 -10
  9. package/dist/plugins/angular/index.js +1 -1
  10. package/dist/plugins/cucumber/index.js +36 -4
  11. package/dist/plugins/cucumber/types.d.ts +2 -1
  12. package/dist/plugins/eslint/helpers.d.ts +2 -0
  13. package/dist/plugins/eslint/helpers.js +14 -3
  14. package/dist/plugins/eslint/resolveFromAST.js +12 -8
  15. package/dist/plugins/eve/index.js +26 -8
  16. package/dist/plugins/index.d.ts +3 -0
  17. package/dist/plugins/index.js +6 -0
  18. package/dist/plugins/mdx/index.d.ts +3 -0
  19. package/dist/plugins/mdx/index.js +16 -6
  20. package/dist/plugins/mocha/index.js +3 -1
  21. package/dist/plugins/mocha/types.d.ts +1 -0
  22. package/dist/plugins/oxlint/index.js +24 -8
  23. package/dist/plugins/oxlint/types.d.ts +1 -0
  24. package/dist/plugins/playwright/index.js +3 -3
  25. package/dist/plugins/plop/index.js +2 -2
  26. package/dist/plugins/railway/index.d.ts +3 -0
  27. package/dist/plugins/railway/index.js +129 -0
  28. package/dist/plugins/rstest/index.js +116 -17
  29. package/dist/plugins/rstest/types.d.ts +29 -5
  30. package/dist/plugins/rstest/visitors/mock.d.ts +2 -0
  31. package/dist/plugins/rstest/visitors/mock.js +52 -0
  32. package/dist/plugins/turbo/index.d.ts +3 -0
  33. package/dist/plugins/turbo/index.js +23 -0
  34. package/dist/plugins/typescript/content-mappers.d.ts +4 -0
  35. package/dist/plugins/typescript/content-mappers.js +4 -0
  36. package/dist/plugins/typescript/index.js +14 -18
  37. package/dist/plugins/typescript-content-mapper/index.d.ts +3 -0
  38. package/dist/plugins/typescript-content-mapper/index.js +23 -0
  39. package/dist/plugins/typescript-content-mapper/types.d.ts +3 -0
  40. package/dist/plugins/typescript-content-mapper/types.js +1 -0
  41. package/dist/plugins/vite/helpers.d.ts +1 -1
  42. package/dist/plugins/vite/helpers.js +7 -8
  43. package/dist/plugins/vitest/index.js +15 -5
  44. package/dist/plugins/vitest/types.d.ts +10 -0
  45. package/dist/schema/configuration.d.ts +45 -0
  46. package/dist/schema/plugins.d.ts +15 -0
  47. package/dist/schema/plugins.js +3 -0
  48. package/dist/types/PluginNames.d.ts +2 -2
  49. package/dist/types/PluginNames.js +3 -0
  50. package/dist/types/package-json.d.ts +5 -0
  51. package/dist/types/tsconfig-json.d.ts +1 -3
  52. package/dist/util/create-options.d.ts +30 -0
  53. package/dist/util/git.d.ts +1 -0
  54. package/dist/util/git.js +23 -1
  55. package/dist/util/package-json.d.ts +8 -0
  56. package/dist/util/tag.d.ts +1 -0
  57. package/dist/util/tag.js +1 -1
  58. package/dist/version.d.ts +1 -1
  59. package/dist/version.js +1 -1
  60. package/package.json +1 -1
  61. package/schema.json +12 -0
@@ -592,6 +592,11 @@ export declare class ConfigurationChief {
592
592
  entry?: string | string[] | undefined;
593
593
  project?: string | string[] | undefined;
594
594
  } | undefined;
595
+ railway?: string | boolean | string[] | {
596
+ config?: string | string[] | undefined;
597
+ entry?: string | string[] | undefined;
598
+ project?: string | string[] | undefined;
599
+ } | undefined;
595
600
  raycast?: string | boolean | string[] | {
596
601
  config?: string | string[] | undefined;
597
602
  entry?: string | string[] | undefined;
@@ -822,6 +827,11 @@ export declare class ConfigurationChief {
822
827
  entry?: string | string[] | undefined;
823
828
  project?: string | string[] | undefined;
824
829
  } | undefined;
830
+ turbo?: string | boolean | string[] | {
831
+ config?: string | string[] | undefined;
832
+ entry?: string | string[] | undefined;
833
+ project?: string | string[] | undefined;
834
+ } | undefined;
825
835
  typedoc?: string | boolean | string[] | {
826
836
  config?: string | string[] | undefined;
827
837
  entry?: string | string[] | undefined;
@@ -832,6 +842,11 @@ export declare class ConfigurationChief {
832
842
  entry?: string | string[] | undefined;
833
843
  project?: string | string[] | undefined;
834
844
  } | undefined;
845
+ 'typescript-content-mapper'?: string | boolean | string[] | {
846
+ config?: string | string[] | undefined;
847
+ entry?: string | string[] | undefined;
848
+ project?: string | string[] | undefined;
849
+ } | undefined;
835
850
  unbuild?: string | boolean | string[] | {
836
851
  config?: string | string[] | undefined;
837
852
  entry?: string | string[] | undefined;
@@ -1122,6 +1137,7 @@ export declare class ConfigurationChief {
1122
1137
  prisma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1123
1138
  quasar?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1124
1139
  qwik?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1140
+ railway?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1125
1141
  raycast?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1126
1142
  "react-cosmos"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1127
1143
  "react-email"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1168,8 +1184,10 @@ export declare class ConfigurationChief {
1168
1184
  tsdown?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1169
1185
  tsup?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1170
1186
  tsx?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1187
+ turbo?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1171
1188
  typedoc?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1172
1189
  typescript?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1190
+ "typescript-content-mapper"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1173
1191
  unbuild?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1174
1192
  unocss?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1175
1193
  "unplugin-auto-import"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -5,7 +5,7 @@ export const styleExtractor = /<style\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<
5
5
  const langAttrMatcher = /\blang\s*=\s*["']([^"']+)["']/i;
6
6
  export const blockCommentMatcher = /\/\*[\s\S]*?\*\//g;
7
7
  export const lineCommentMatcher = /^[ \t]*\/\/.*$/gm;
8
- export const importMatcher = /(?<![.\w$#])import\b(?:\s*\(\s*['"][^'"]+['"][^)]*\)|(?!\s*\()[^'"]+['"][^'"]+['"])/g;
8
+ export const importMatcher = /(?<![.\w$#])import\b(?!\s*\.)(?:\s*\(\s*['"][^'"]+['"][^)]*\)|(?!\s*\()[^'"]+['"][^'"]+['"])/g;
9
9
  export const collectImports = text => {
10
10
  if (!text.includes('import'))
11
11
  return '';
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;
@@ -70,7 +70,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
70
70
  return;
71
71
  const issueType = isEnumMembers ? 'enumMembers' : 'namespaceMembers';
72
72
  const unusedMembers = [];
73
- const ignoredMemberIds = [];
73
+ const ignoredMembers = [];
74
74
  for (const member of exportedItem.members) {
75
75
  if (findMatch(workspace.ignoreMembers, member.identifier))
76
76
  continue;
@@ -78,8 +78,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
78
78
  continue;
79
79
  if (member.hasRefsInFile)
80
80
  continue;
81
- const id = `${identifier}.${member.identifier}`;
82
- const [isMemberReferenced] = explorer.isReferenced(filePath, id, {
81
+ const [isMemberReferenced] = explorer.isReferenced(filePath, `${identifier}.${member.identifier}`, {
83
82
  traverseEntries: true,
84
83
  treatStarAtEntryAsReferenced: true,
85
84
  });
@@ -89,10 +88,19 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
89
88
  unusedMembers.push(member);
90
89
  }
91
90
  else if (isMemberIgnored) {
92
- ignoredMemberIds.push(id);
91
+ ignoredMembers.push(member);
92
+ }
93
+ }
94
+ return { issueType, unusedMembers, ignoredMembers };
95
+ };
96
+ const addMemberTagHints = (members, filePath, identifier) => {
97
+ for (const member of members) {
98
+ for (const tagName of member.jsDocTags) {
99
+ if (options.tags[1].includes(tagName)) {
100
+ collector.addTagHint({ type: 'tag', filePath, identifier: `${identifier}.${member.identifier}`, tagName });
101
+ }
93
102
  }
94
103
  }
95
- return { issueType, unusedMembers, ignoredMemberIds };
96
104
  };
97
105
  const analyzeGraph = async () => {
98
106
  if (options.isReportValues || options.isReportTypes) {
@@ -115,7 +123,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
115
123
  const isInternalProd = options.isProduction && exportedItem.jsDocTags.has(INTERNAL_TAG);
116
124
  const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags) || isInternalProd;
117
125
  if (importsForExport) {
118
- const [isReferenced, reExportingEntryFile] = explorer.isReferenced(filePath, identifier, {
126
+ const [isReferenced, reExportingEntryFile, reExportedIds] = explorer.isReferenced(filePath, identifier, {
119
127
  traverseEntries: isIncludeEntryExports,
120
128
  });
121
129
  if (isIgnored) {
@@ -124,6 +132,8 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
124
132
  const memberIssues = isReferenced
125
133
  ? getMemberIssues(exportedItem, filePath, identifier, workspace, importsForExport)
126
134
  : undefined;
135
+ if (memberIssues)
136
+ addMemberTagHints(memberIssues.ignoredMembers, filePath, identifier);
127
137
  if (!memberIssues || memberIssues.unusedMembers.length === 0) {
128
138
  for (const tagName of exportedItem.jsDocTags) {
129
139
  if (options.tags[1].includes(tagName) || (isInternalProd && tagName === INTERNAL_TAG)) {
@@ -138,9 +148,18 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
138
148
  if (!isIncludeEntryExports) {
139
149
  continue;
140
150
  }
141
- if (!isReferenced) {
142
- const reExportedItem = graph.get(reExportingEntryFile)?.exports.get(identifier);
143
- 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)
144
163
  continue;
145
164
  }
146
165
  }
@@ -160,13 +179,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
160
179
  fixes: member.fix ? [member.fix] : [],
161
180
  });
162
181
  }
163
- for (const id of memberIssues.ignoredMemberIds) {
164
- for (const tagName of exportedItem.jsDocTags) {
165
- if (options.tags[1].includes(tagName)) {
166
- collector.addTagHint({ type: 'tag', filePath, identifier: id, tagName });
167
- }
168
- }
169
- }
182
+ addMemberTagHints(memberIssues.ignoredMembers, filePath, identifier);
170
183
  }
171
184
  continue;
172
185
  }
@@ -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(':') : [];
@@ -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?];
@@ -4,5 +4,7 @@ import { type ConfigInput, type Input } from '../../util/input.ts';
4
4
  import type { ESLintConfig, ESLintConfigDeprecated, OverrideConfigDeprecated, Settings } from './types.ts';
5
5
  export declare const isFlatConfig: (fileName: string) => boolean;
6
6
  export declare const getInputs: (config: ESLintConfigDeprecated | OverrideConfigDeprecated | ESLintConfig, options: PluginOptions) => (Input | ConfigInput)[];
7
+ export type ImportSettingKind = 'resolver' | 'parsers';
8
+ export declare const importSettingKinds: Map<string, ImportSettingKind>;
7
9
  export declare const getInputsFromSettings: (settings?: Settings) => Input[];
8
10
  export declare const resolveFormatters: (formatters: string | string[], manifest: Manifest) => Set<Input>;
@@ -79,13 +79,24 @@ const getResolverNames = (value) => {
79
79
  return [value];
80
80
  if (Array.isArray(value))
81
81
  return value.flatMap(getResolverNames);
82
- if (value && typeof value === 'object')
82
+ if (value && typeof value === 'object') {
83
+ if ('name' in value && 'resolver' in value)
84
+ return [];
83
85
  return Object.keys(value);
86
+ }
84
87
  return [];
85
88
  };
89
+ export const importSettingKinds = new Map([
90
+ ['import/resolver', 'resolver'],
91
+ ['import-x/resolver', 'resolver'],
92
+ ['import-x/resolver-legacy', 'resolver'],
93
+ ['import/parsers', 'parsers'],
94
+ ['import-x/parsers', 'parsers'],
95
+ ]);
86
96
  const getDependenciesFromSettings = (settings = {}) => {
87
97
  return Object.entries(settings).flatMap(([settingKey, settings]) => {
88
- if (settingKey === 'import/resolver') {
98
+ const kind = importSettingKinds.get(settingKey);
99
+ if (kind === 'resolver') {
89
100
  return getResolverNames(settings)
90
101
  .filter(key => key !== 'node')
91
102
  .map(key => {
@@ -96,7 +107,7 @@ const getDependenciesFromSettings = (settings = {}) => {
96
107
  return `eslint-import-resolver-${key}`;
97
108
  });
98
109
  }
99
- if (settingKey === 'import/parsers') {
110
+ if (kind === 'parsers') {
100
111
  return (typeof settings === 'string' ? [settings] : Object.keys(settings)).map(key => {
101
112
  if (isAbsolute(key))
102
113
  return getPackageNameFromFilePath(key);
@@ -3,27 +3,30 @@ import { toDeferResolve } from '../../util/input.js';
3
3
  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
+ import { importSettingKinds } from './helpers.js';
6
7
  export const getInputsFromSettingsAST = (program) => {
7
8
  const inputs = [];
8
- const addResolver = (key, resolver) => {
9
+ const addResolver = (kind, resolver) => {
9
10
  if (!resolver || resolver === 'node' || isInternal(resolver))
10
11
  return;
11
- const dep = key === 'import/resolver' ? `eslint-import-resolver-${resolver}` : resolver;
12
+ const dep = kind === 'resolver' ? `eslint-import-resolver-${resolver}` : resolver;
12
13
  inputs.push(toDeferResolve(dep, { optional: true }));
13
14
  };
14
- const addResolvers = (key, node) => {
15
+ const addResolvers = (kind, node) => {
15
16
  if (node?.type === 'ArrayExpression') {
16
17
  for (const element of node.elements)
17
- addResolvers(key, element);
18
+ addResolvers(kind, element);
18
19
  }
19
20
  else if (node?.type === 'ObjectExpression') {
21
+ if (kind === 'resolver' && findProperty(node, 'name') && findProperty(node, 'resolver'))
22
+ return;
20
23
  for (const prop of node.properties) {
21
24
  if (prop.type === 'Property')
22
- addResolver(key, getPropertyKey(prop));
25
+ addResolver(kind, getPropertyKey(prop));
23
26
  }
24
27
  }
25
28
  else {
26
- addResolver(key, getStringValue(node));
29
+ addResolver(kind, getStringValue(node));
27
30
  }
28
31
  };
29
32
  const visitor = new Visitor({
@@ -35,8 +38,9 @@ export const getInputsFromSettingsAST = (program) => {
35
38
  if (prop.type !== 'Property')
36
39
  continue;
37
40
  const key = getPropertyKey(prop);
38
- if (key === 'import/resolver' || key === 'import/parsers')
39
- addResolvers(key, prop.value);
41
+ const kind = key && importSettingKinds.get(key);
42
+ if (kind)
43
+ addResolvers(kind, prop.value);
40
44
  }
41
45
  },
42
46
  });
@@ -3,20 +3,38 @@ const title = 'eve';
3
3
  const enablers = ['eve'];
4
4
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
5
  const extensions = '{js,jsx,ts,tsx,mjs,cjs,mts,cts}';
6
- const rootAgentFileNames = '{agent,instructions,instrumentation,sandbox}';
7
- const subagentFileNames = '{agent,instructions,sandbox}';
6
+ const agentRoots = '{,agent/,agents/*/,agents/*/agent/}';
7
+ const subagentRoots = `${agentRoots}+(subagents/*/|extensions/*/subagents/*/)`;
8
+ const extensionMounts = `{${agentRoots},${subagentRoots}}extensions/*`;
9
+ const rootAgentFileNames = '{agent,instructions,instrumentation,memory,sandbox}';
10
+ const rootAgentDirectories = '{channels,connections,hooks,skills,tools,schedules}';
11
+ const subagentFileNames = '{agent,instructions,memory,sandbox}';
12
+ const subagentDirectories = '{connections,hooks,skills,tools}';
13
+ const entry = ['{evals,agents/*/evals}/evals.config.ts', '{evals,agents/*/evals}/**/*.eval.ts'];
8
14
  const production = [
9
- `{,agent/}${rootAgentFileNames}.${extensions}`,
10
- `{,agent/}sandbox/sandbox.${extensions}`,
11
- `{,agent/}{channels,connections,hooks,skills,tools,schedules}/**/*.${extensions}`,
12
- `{,agent/}subagents/**/${subagentFileNames}.${extensions}`,
13
- `{,agent/}subagents/**/sandbox/sandbox.${extensions}`,
14
- `{,agent/}subagents/**/{connections,hooks,skills,tools}/**/*.${extensions}`,
15
+ `${agentRoots}${rootAgentFileNames}.${extensions}`,
16
+ `${agentRoots}{instructions,instrumentation,memory}/*.${extensions}`,
17
+ `${agentRoots}sandbox/sandbox.${extensions}`,
18
+ `${agentRoots}sandbox/workspace/**/*.${extensions}`,
19
+ `${agentRoots}${rootAgentDirectories}/**/*.${extensions}`,
20
+ `${agentRoots}subagents/*.${extensions}`,
21
+ `${subagentRoots}subagents/*.${extensions}`,
22
+ `${subagentRoots}${subagentFileNames}.${extensions}`,
23
+ `${subagentRoots}{instructions,memory}/*.${extensions}`,
24
+ `${subagentRoots}sandbox/sandbox.${extensions}`,
25
+ `${subagentRoots}sandbox/workspace/**/*.${extensions}`,
26
+ `${subagentRoots}${subagentDirectories}/**/*.${extensions}`,
27
+ `${extensionMounts}.${extensions}`,
28
+ `${extensionMounts}/{extension,instructions}.${extensions}`,
29
+ `${extensionMounts}/instructions/*.${extensions}`,
30
+ `${extensionMounts}/${rootAgentDirectories}/**/*.${extensions}`,
31
+ `${extensionMounts}/subagents/*.${extensions}`,
15
32
  ];
16
33
  const plugin = {
17
34
  title,
18
35
  enablers,
19
36
  isEnabled,
37
+ entry,
20
38
  production,
21
39
  };
22
40
  export default plugin;
@@ -111,6 +111,7 @@ export declare const Plugins: {
111
111
  prisma: import("../types/config.ts").Plugin;
112
112
  quasar: import("../types/config.ts").Plugin;
113
113
  qwik: import("../types/config.ts").Plugin;
114
+ railway: import("../types/config.ts").Plugin;
114
115
  raycast: import("../types/config.ts").Plugin;
115
116
  'react-cosmos': import("../types/config.ts").Plugin;
116
117
  'react-email': import("../types/config.ts").Plugin;
@@ -157,8 +158,10 @@ export declare const Plugins: {
157
158
  tsdown: import("../types/config.ts").Plugin;
158
159
  tsup: import("../types/config.ts").Plugin;
159
160
  tsx: import("../types/config.ts").Plugin;
161
+ turbo: import("../types/config.ts").Plugin;
160
162
  typedoc: import("../types/config.ts").Plugin;
161
163
  typescript: import("../types/config.ts").Plugin;
164
+ 'typescript-content-mapper': import("../types/config.ts").Plugin;
162
165
  unbuild: import("../types/config.ts").Plugin;
163
166
  unocss: import("../types/config.ts").Plugin;
164
167
  'unplugin-auto-import': import("../types/config.ts").Plugin;
@@ -105,6 +105,7 @@ import { default as prettier } from './prettier/index.js';
105
105
  import { default as prisma } from './prisma/index.js';
106
106
  import { default as quasar } from './quasar/index.js';
107
107
  import { default as qwik } from './qwik/index.js';
108
+ import { default as railway } from './railway/index.js';
108
109
  import { default as raycast } from './raycast/index.js';
109
110
  import { default as reactCosmos } from './react-cosmos/index.js';
110
111
  import { default as reactEmail } from './react-email/index.js';
@@ -151,8 +152,10 @@ import { default as tsd } from './tsd/index.js';
151
152
  import { default as tsdown } from './tsdown/index.js';
152
153
  import { default as tsup } from './tsup/index.js';
153
154
  import { default as tsx } from './tsx/index.js';
155
+ import { default as turbo } from './turbo/index.js';
154
156
  import { default as typedoc } from './typedoc/index.js';
155
157
  import { default as typescript } from './typescript/index.js';
158
+ import { default as typescriptContentMapper } from './typescript-content-mapper/index.js';
156
159
  import { default as unbuild } from './unbuild/index.js';
157
160
  import { default as unocss } from './unocss/index.js';
158
161
  import { default as unpluginAutoImport } from './unplugin-auto-import/index.js';
@@ -291,6 +294,7 @@ export const Plugins = {
291
294
  prisma,
292
295
  quasar,
293
296
  qwik,
297
+ railway,
294
298
  raycast,
295
299
  'react-cosmos': reactCosmos,
296
300
  'react-email': reactEmail,
@@ -337,8 +341,10 @@ export const Plugins = {
337
341
  tsdown,
338
342
  tsup,
339
343
  tsx,
344
+ turbo,
340
345
  typedoc,
341
346
  typescript,
347
+ 'typescript-content-mapper': typescriptContentMapper,
342
348
  unbuild,
343
349
  unocss,
344
350
  'unplugin-auto-import': unpluginAutoImport,
@@ -1,3 +1,6 @@
1
1
  import type { Plugin } from '../../types/config.ts';
2
+ import { type Input } from '../../util/input.ts';
3
+ export declare const contentMappers: string[];
4
+ export declare const resolveContentMapperOptions: (options: Record<string, unknown>) => Input[];
2
5
  declare const plugin: Plugin;
3
6
  export default plugin;