knip 6.39.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 (55) hide show
  1. package/dist/ConfigurationChief.d.ts +12 -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/graph/build.js +17 -10
  6. package/dist/plugins/capacitor/index.js +1 -1
  7. package/dist/plugins/commitlint/index.js +34 -9
  8. package/dist/plugins/eslint/resolveFromAST.d.ts +0 -1
  9. package/dist/plugins/eslint/resolveFromAST.js +1 -1
  10. package/dist/plugins/index.d.ts +2 -0
  11. package/dist/plugins/index.js +4 -0
  12. package/dist/plugins/jasmine/index.d.ts +3 -0
  13. package/dist/plugins/jasmine/index.js +55 -0
  14. package/dist/plugins/jasmine/types.d.ts +7 -0
  15. package/dist/plugins/jasmine/types.js +1 -0
  16. package/dist/plugins/jest/helpers.d.ts +1 -0
  17. package/dist/plugins/jest/helpers.js +2 -0
  18. package/dist/plugins/jest/index.js +20 -11
  19. package/dist/plugins/osls/index.d.ts +3 -0
  20. package/dist/plugins/osls/index.js +13 -0
  21. package/dist/plugins/oxlint/index.d.ts +3 -0
  22. package/dist/plugins/oxlint/index.js +4 -31
  23. package/dist/plugins/oxlint/types.d.ts +1 -0
  24. package/dist/plugins/playwright/index.js +17 -0
  25. package/dist/plugins/playwright/types.d.ts +5 -0
  26. package/dist/plugins/postcss/index.js +5 -1
  27. package/dist/plugins/rsbuild/index.js +42 -4
  28. package/dist/plugins/rsbuild/types.d.ts +18 -1
  29. package/dist/plugins/rspack/index.d.ts +3 -1
  30. package/dist/plugins/rspack/index.js +1 -1
  31. package/dist/plugins/serverless-framework/index.d.ts +4 -1
  32. package/dist/plugins/serverless-framework/index.js +40 -7
  33. package/dist/plugins/serverless-framework/types.d.ts +4 -2
  34. package/dist/plugins/simple-git-hooks/index.js +1 -1
  35. package/dist/plugins/vitest/index.js +16 -2
  36. package/dist/plugins/vitest/types.d.ts +2 -0
  37. package/dist/schema/configuration.d.ts +30 -0
  38. package/dist/schema/plugins.d.ts +10 -0
  39. package/dist/schema/plugins.js +2 -0
  40. package/dist/types/PluginNames.d.ts +2 -2
  41. package/dist/types/PluginNames.js +2 -0
  42. package/dist/typescript/ast-nodes.js +291 -0
  43. package/dist/typescript/resolve-module-names.js +15 -4
  44. package/dist/typescript/visitors/walk.js +12 -0
  45. package/dist/util/create-options.d.ts +20 -0
  46. package/dist/util/filter-transitive-dependencies.d.ts +2 -0
  47. package/dist/util/filter-transitive-dependencies.js +38 -0
  48. package/dist/util/package-json.d.ts +1 -354
  49. package/dist/util/package-json.js +56 -10
  50. package/dist/util/to-source-path.d.ts +1 -1
  51. package/dist/util/to-source-path.js +7 -5
  52. package/dist/version.d.ts +1 -1
  53. package/dist/version.js +1 -1
  54. package/package.json +1 -1
  55. package/schema.json +8 -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;
@@ -1077,6 +1087,7 @@ export declare class ConfigurationChief {
1077
1087
  hardhat?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1078
1088
  husky?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1079
1089
  "i18next-parser"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1090
+ jasmine?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1080
1091
  jest?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1081
1092
  karma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1082
1093
  knex?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1118,6 +1129,7 @@ export declare class ConfigurationChief {
1118
1129
  "openapi-ts"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1119
1130
  openclaw?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1120
1131
  orval?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1132
+ osls?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1121
1133
  oxfmt?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1122
1134
  oxlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1123
1135
  "panda-css"?: (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;
@@ -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();
@@ -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,
@@ -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))
@@ -51,6 +51,7 @@ export declare const Plugins: {
51
51
  hardhat: import("../types/config.ts").Plugin;
52
52
  husky: import("../types/config.ts").Plugin;
53
53
  'i18next-parser': import("../types/config.ts").Plugin;
54
+ jasmine: import("../types/config.ts").Plugin;
54
55
  jest: import("../types/config.ts").Plugin;
55
56
  karma: import("../types/config.ts").Plugin;
56
57
  knex: import("../types/config.ts").Plugin;
@@ -92,6 +93,7 @@ export declare const Plugins: {
92
93
  'openapi-ts': import("../types/config.ts").Plugin;
93
94
  openclaw: import("../types/config.ts").Plugin;
94
95
  orval: import("../types/config.ts").Plugin;
96
+ osls: import("../types/config.ts").Plugin;
95
97
  oxfmt: import("../types/config.ts").Plugin;
96
98
  oxlint: import("../types/config.ts").Plugin;
97
99
  'panda-css': import("../types/config.ts").Plugin;
@@ -45,6 +45,7 @@ import { default as graphqlCodegen } from './graphql-codegen/index.js';
45
45
  import { default as hardhat } from './hardhat/index.js';
46
46
  import { default as husky } from './husky/index.js';
47
47
  import { default as i18nextParser } from './i18next-parser/index.js';
48
+ import { default as jasmine } from './jasmine/index.js';
48
49
  import { default as jest } from './jest/index.js';
49
50
  import { default as karma } from './karma/index.js';
50
51
  import { default as knex } from './knex/index.js';
@@ -86,6 +87,7 @@ import { default as oclif } from './oclif/index.js';
86
87
  import { default as openapiTs } from './openapi-ts/index.js';
87
88
  import { default as openclaw } from './openclaw/index.js';
88
89
  import { default as orval } from './orval/index.js';
90
+ import { default as osls } from './osls/index.js';
89
91
  import { default as oxfmt } from './oxfmt/index.js';
90
92
  import { default as oxlint } from './oxlint/index.js';
91
93
  import { default as pandaCss } from './panda-css/index.js';
@@ -234,6 +236,7 @@ export const Plugins = {
234
236
  hardhat,
235
237
  husky,
236
238
  'i18next-parser': i18nextParser,
239
+ jasmine,
237
240
  jest,
238
241
  karma,
239
242
  knex,
@@ -275,6 +278,7 @@ export const Plugins = {
275
278
  'openapi-ts': openapiTs,
276
279
  openclaw,
277
280
  orval,
281
+ osls,
278
282
  oxfmt,
279
283
  oxlint,
280
284
  'panda-css': pandaCss,
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,55 @@
1
+ import { toDeferResolve, toEntry } from '../../util/input.js';
2
+ import { isAbsolute, join } from '../../util/path.js';
3
+ import { hasDependency } from '../../util/plugin.js';
4
+ const title = 'Jasmine';
5
+ const enablers = ['jasmine'];
6
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
+ const config = ['spec/support/jasmine.{json,jsonc,js,cjs,mjs}'];
8
+ const defaultSpecFiles = 'spec/**/*[sS]pec.{js,mjs}';
9
+ const entry = [defaultSpecFiles, 'spec/helpers/**/*.{js,mjs}'];
10
+ const toSpecDirPattern = (specDir, pattern) => {
11
+ const isNegated = pattern.startsWith('!');
12
+ const id = isNegated ? pattern.slice(1) : pattern;
13
+ const resolved = isAbsolute(id) ? id : join(specDir, id);
14
+ return isNegated ? `!${resolved}` : resolved;
15
+ };
16
+ const resolveConfig = (localConfig, options) => {
17
+ const specDir = localConfig.spec_dir ?? '';
18
+ const specFiles = localConfig.spec_files?.map(pattern => toSpecDirPattern(specDir, pattern)) ?? [defaultSpecFiles];
19
+ const helpers = localConfig.helpers?.map(pattern => toSpecDirPattern(specDir, pattern)) ?? [];
20
+ const requires = localConfig.requires ?? [];
21
+ const inputs = [];
22
+ for (const id of [...specFiles, ...helpers])
23
+ inputs.push(toEntry(id));
24
+ for (const id of requires)
25
+ inputs.push(toDeferResolve(id, { dir: options.cwd }));
26
+ if (localConfig.loader)
27
+ inputs.push(toDeferResolve(localConfig.loader, { dir: options.cwd }));
28
+ return inputs;
29
+ };
30
+ const commands = new Set(['init', 'examples', 'help', 'version']);
31
+ const args = {
32
+ boolean: ['color', 'fail-fast', 'list-not-applicable', 'no-color'],
33
+ string: ['config', 'reporter', 'require'],
34
+ config: ['config'],
35
+ resolve: ['require', 'reporter'],
36
+ resolveInputs: (parsed) => {
37
+ const inputs = [];
38
+ for (const value of parsed._) {
39
+ if (commands.has(value) || /^\w+=/.test(value))
40
+ continue;
41
+ inputs.push(toEntry(value));
42
+ }
43
+ return inputs;
44
+ },
45
+ };
46
+ const plugin = {
47
+ title,
48
+ enablers,
49
+ isEnabled,
50
+ config,
51
+ entry,
52
+ resolveConfig,
53
+ args,
54
+ };
55
+ export default plugin;
@@ -0,0 +1,7 @@
1
+ export type JasmineConfig = {
2
+ spec_dir?: string;
3
+ spec_files?: string[];
4
+ helpers?: string[];
5
+ requires?: string[];
6
+ loader?: string;
7
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  import type { PluginOptions } from '../../types/config.ts';
2
2
  import type { JestInitialOptions } from './types.ts';
3
3
  export declare const resolveExtensibleConfig: (configFilePath: string) => Promise<any>;
4
+ export declare const resolveWithPrefix: (prefix: string, id: string, rootDir: string) => string;
4
5
  export declare const getReportersDependencies: (config: JestInitialOptions, options: PluginOptions) => string[];
@@ -1,5 +1,6 @@
1
1
  import { dirname, isInternal, join, toAbsolute } from '../../util/path.js';
2
2
  import { load } from '../../util/plugin.js';
3
+ import { _resolveSync } from '../../util/resolve.js';
3
4
  export const resolveExtensibleConfig = async (configFilePath) => {
4
5
  let config = await load(configFilePath);
5
6
  if (config?.preset) {
@@ -12,6 +13,7 @@ export const resolveExtensibleConfig = async (configFilePath) => {
12
13
  }
13
14
  return config;
14
15
  };
16
+ export const resolveWithPrefix = (prefix, id, rootDir) => _resolveSync(prefix + id, rootDir) ? prefix + id : id;
15
17
  const getStringPropOrFallback = (prop, fallback) => {
16
18
  return typeof prop === 'string' ? prop : fallback;
17
19
  };
@@ -1,10 +1,10 @@
1
1
  import { arrayify } from '../../util/array.js';
2
2
  import { _glob, _dirGlob } from '../../util/glob.js';
3
- import { toConfig, toDeferResolve, toEntry } from '../../util/input.js';
3
+ import { toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
4
4
  import { isInternal, join, normalize, toAbsolute } from '../../util/path.js';
5
5
  import { hasDependency } from '../../util/plugin.js';
6
6
  import { getDependenciesFromConfig } from '../babel/index.js';
7
- import { getReportersDependencies, resolveExtensibleConfig } from './helpers.js';
7
+ import { getReportersDependencies, resolveExtensibleConfig, resolveWithPrefix } from './helpers.js';
8
8
  const title = 'Jest';
9
9
  const enablers = ['jest'];
10
10
  const isEnabled = ({ dependencies, manifest }) => hasDependency(dependencies, enablers) || Boolean(manifest.name?.startsWith('jest-presets'));
@@ -38,16 +38,23 @@ const resolveDependencies = async (config, rootDir, options) => {
38
38
  projects.push(dependency);
39
39
  }
40
40
  }
41
- const runner = config.runner ? [typeof config.runner === 'string' ? config.runner : config.runner[0]] : [];
41
+ const runner = config.runner
42
+ ? [resolveWithPrefix('jest-runner-', typeof config.runner === 'string' ? config.runner : config.runner[0], rootDir)]
43
+ : [];
42
44
  const runtime = config.runtime && config.runtime !== 'jest-circus' ? [config.runtime] : [];
43
- const environments = config.testEnvironment === 'jsdom'
44
- ? ['jest-environment-jsdom']
45
- : config.testEnvironment
46
- ? [config.testEnvironment]
47
- : [];
45
+ const environments = [];
46
+ if (config.testEnvironment === 'node') {
47
+ environments.push(toDependency('jest-environment-node', { optional: true }));
48
+ }
49
+ else if (config.testEnvironment) {
50
+ const environment = config.testEnvironment === 'jsdom'
51
+ ? 'jest-environment-jsdom'
52
+ : resolveWithPrefix('jest-environment-', config.testEnvironment, rootDir);
53
+ environments.push(toDeferResolve(environment));
54
+ }
48
55
  const resolvers = config.resolver ? [config.resolver] : [];
49
56
  const reporters = getReportersDependencies(config, options);
50
- const watchPlugins = config.watchPlugins?.map(watchPlugin => (typeof watchPlugin === 'string' ? watchPlugin : watchPlugin[0])) ?? [];
57
+ const watchPlugins = config.watchPlugins?.map(watchPlugin => resolveWithPrefix('jest-watch-', typeof watchPlugin === 'string' ? watchPlugin : watchPlugin[0], rootDir)) ?? [];
51
58
  const transform = [];
52
59
  for (const transformer of config.transform ? Object.values(config.transform) : []) {
53
60
  if (typeof transformer === 'string') {
@@ -69,7 +76,9 @@ const resolveDependencies = async (config, rootDir, options) => {
69
76
  const testResultsProcessor = config.testResultsProcessor ? [config.testResultsProcessor] : [];
70
77
  const snapshotResolver = config.snapshotResolver ? [config.snapshotResolver] : [];
71
78
  const snapshotSerializers = config.snapshotSerializers ?? [];
72
- const testSequencer = config.testSequencer ? [config.testSequencer] : [];
79
+ const testSequencer = config.testSequencer
80
+ ? [resolveWithPrefix('jest-sequencer-', config.testSequencer, rootDir)]
81
+ : [];
73
82
  const setupFiles = config.setupFiles ?? [];
74
83
  const setupFilesAfterEnv = config.setupFilesAfterEnv ?? [];
75
84
  const globalSetup = config.globalSetup ? [config.globalSetup] : [];
@@ -99,7 +108,7 @@ const resolveConfig = async (localConfig, options) => {
99
108
  const { configFileDir } = options;
100
109
  if (typeof localConfig === 'function')
101
110
  localConfig = await localConfig();
102
- const rootDir = localConfig.rootDir ?? configFileDir;
111
+ const rootDir = toAbsolute(localConfig.rootDir ?? configFileDir, configFileDir);
103
112
  const replaceRootDir = (name) => name.replace(rootDirRe, rootDir);
104
113
  const inputs = await resolveDependencies(localConfig, rootDir, options);
105
114
  const entries = localConfig.testMatch
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,13 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ import { config, resolveConfig } from '../serverless-framework/index.js';
3
+ const title = 'osls';
4
+ const enablers = ['osls'];
5
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
+ const plugin = {
7
+ title,
8
+ enablers,
9
+ isEnabled,
10
+ config,
11
+ resolveConfig,
12
+ };
13
+ export default plugin;
@@ -1,3 +1,6 @@
1
1
  import type { Plugin } from '../../types/config.ts';
2
+ import { type Input } from '../../util/input.ts';
3
+ import type { OxlintConfig } from './types.ts';
4
+ export declare const resolveExtendedConfig: (config: OxlintConfig, configFilePath: string) => Input[];
2
5
  declare const plugin: Plugin;
3
6
  export default plugin;