knip 6.42.0 → 6.43.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 (62) hide show
  1. package/dist/ConfigurationChief.d.ts +18 -0
  2. package/dist/IssueFixer.js +10 -5
  3. package/dist/WorkspaceWorker.js +15 -10
  4. package/dist/binaries/resolvers/bun.js +1 -0
  5. package/dist/binaries/resolvers/npm.js +12 -2
  6. package/dist/binaries/resolvers/pnpm.js +5 -3
  7. package/dist/compilers/compilers.js +2 -2
  8. package/dist/compilers/scss.js +2 -22
  9. package/dist/compilers/shared.d.ts +1 -1
  10. package/dist/compilers/shared.js +24 -1
  11. package/dist/constants.js +2 -0
  12. package/dist/plugins/_vue/auto-import.js +31 -1
  13. package/dist/plugins/buf/index.d.ts +3 -0
  14. package/dist/plugins/buf/index.js +33 -0
  15. package/dist/plugins/buf/types.d.ts +8 -0
  16. package/dist/plugins/buf/types.js +1 -0
  17. package/dist/plugins/bun/index.js +13 -0
  18. package/dist/plugins/electron-forge/index.d.ts +3 -0
  19. package/dist/plugins/electron-forge/index.js +94 -0
  20. package/dist/plugins/eslint/helpers.d.ts +1 -0
  21. package/dist/plugins/eslint/helpers.js +1 -1
  22. package/dist/plugins/eslint/resolveFromAST.js +35 -10
  23. package/dist/plugins/expo/helpers.d.ts +1 -1
  24. package/dist/plugins/expo/helpers.js +15 -8
  25. package/dist/plugins/expo/types.d.ts +2 -1
  26. package/dist/plugins/index.d.ts +3 -0
  27. package/dist/plugins/index.js +6 -0
  28. package/dist/plugins/jest/index.js +11 -7
  29. package/dist/plugins/mcp/index.d.ts +3 -0
  30. package/dist/plugins/mcp/index.js +33 -0
  31. package/dist/plugins/mcp/types.d.ts +11 -0
  32. package/dist/plugins/mcp/types.js +1 -0
  33. package/dist/plugins/next/index.d.ts +3 -0
  34. package/dist/plugins/next/index.js +57 -9
  35. package/dist/plugins/next/types.d.ts +11 -0
  36. package/dist/plugins/next/types.js +1 -0
  37. package/dist/plugins/semantic-release/index.js +32 -3
  38. package/dist/plugins/semantic-release/types.d.ts +1 -0
  39. package/dist/plugins/tailwind/compiler.js +14 -2
  40. package/dist/plugins/travis/index.js +2 -2
  41. package/dist/plugins/typescript/index.js +2 -4
  42. package/dist/plugins/vitest/helpers.d.ts +1 -1
  43. package/dist/plugins/vitest/helpers.js +13 -3
  44. package/dist/plugins/vitest/index.js +54 -46
  45. package/dist/plugins/vitest/types.d.ts +11 -7
  46. package/dist/run.js +1 -1
  47. package/dist/schema/configuration.d.ts +45 -0
  48. package/dist/schema/plugins.d.ts +15 -0
  49. package/dist/schema/plugins.js +3 -0
  50. package/dist/types/PluginNames.d.ts +2 -2
  51. package/dist/types/PluginNames.js +3 -0
  52. package/dist/types/config.d.ts +1 -0
  53. package/dist/typescript/ast-nodes.js +3 -3
  54. package/dist/typescript/visitors/exports.js +5 -4
  55. package/dist/typescript/visitors/walk.js +13 -1
  56. package/dist/util/create-options.d.ts +30 -0
  57. package/dist/util/modules.js +2 -1
  58. package/dist/util/remove-export.js +3 -1
  59. package/dist/version.d.ts +1 -1
  60. package/dist/version.js +1 -1
  61. package/package.json +4 -4
  62. package/schema.json +12 -0
@@ -102,6 +102,11 @@ export declare class ConfigurationChief {
102
102
  entry?: string | string[] | undefined;
103
103
  project?: string | string[] | undefined;
104
104
  } | undefined;
105
+ buf?: string | boolean | string[] | {
106
+ config?: string | string[] | undefined;
107
+ entry?: string | string[] | undefined;
108
+ project?: string | string[] | undefined;
109
+ } | undefined;
105
110
  bumpp?: string | boolean | string[] | {
106
111
  config?: string | string[] | undefined;
107
112
  entry?: string | string[] | undefined;
@@ -202,6 +207,11 @@ export declare class ConfigurationChief {
202
207
  entry?: string | string[] | undefined;
203
208
  project?: string | string[] | undefined;
204
209
  } | undefined;
210
+ 'electron-forge'?: string | boolean | string[] | {
211
+ config?: string | string[] | undefined;
212
+ entry?: string | string[] | undefined;
213
+ project?: string | string[] | undefined;
214
+ } | undefined;
205
215
  'electron-vite'?: string | boolean | string[] | {
206
216
  config?: string | string[] | undefined;
207
217
  entry?: string | string[] | undefined;
@@ -382,6 +392,11 @@ export declare class ConfigurationChief {
382
392
  entry?: string | string[] | undefined;
383
393
  project?: string | string[] | undefined;
384
394
  } | undefined;
395
+ mcp?: string | boolean | string[] | {
396
+ config?: string | string[] | undefined;
397
+ entry?: string | string[] | undefined;
398
+ project?: string | string[] | undefined;
399
+ } | undefined;
385
400
  mdx?: string | boolean | string[] | {
386
401
  config?: string | string[] | undefined;
387
402
  entry?: string | string[] | undefined;
@@ -1074,6 +1089,7 @@ export declare class ConfigurationChief {
1074
1089
  babel?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1075
1090
  biome?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1076
1091
  borp?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1092
+ buf?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1077
1093
  bumpp?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1078
1094
  bun?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1079
1095
  c8?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1094,6 +1110,7 @@ export declare class ConfigurationChief {
1094
1110
  docusaurus?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1095
1111
  dotenv?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1096
1112
  drizzle?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1113
+ "electron-forge"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1097
1114
  "electron-vite"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1098
1115
  eleventy?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1099
1116
  esbuild?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1130,6 +1147,7 @@ export declare class ConfigurationChief {
1130
1147
  lunaria?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1131
1148
  markdownlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1132
1149
  marko?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1150
+ mcp?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1133
1151
  mdx?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1134
1152
  mdxlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1135
1153
  metro?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -75,9 +75,12 @@ class IssueFixer {
75
75
  continue;
76
76
  const absFilePath = join(this.options.cwd, filePath);
77
77
  const originalSource = await readFile(absFilePath, 'utf-8');
78
- let sourceFileText = fixes
79
- .sort((a, b) => b[0] - a[0])
80
- .reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }), originalSource);
78
+ const disjointFixes = [];
79
+ for (const fix of fixes.sort((a, b) => a[0] - b[0] || b[1] - a[1])) {
80
+ if (fix[0] >= (disjointFixes.at(-1)?.[1] ?? 0))
81
+ disjointFixes.push(fix);
82
+ }
83
+ let sourceFileText = disjointFixes.reduceRight((text, [start, end, flags]) => removeExport({ text, start, end, flags }), originalSource);
81
84
  if (MODULE_MARKER.test(originalSource) && !MODULE_MARKER.test(sourceFileText)) {
82
85
  sourceFileText = `${sourceFileText.trimEnd()}\n\nexport {};\n`;
83
86
  }
@@ -87,7 +90,8 @@ class IssueFixer {
87
90
  const issueMap = issues[type]?.[filePath];
88
91
  if (issueMap)
89
92
  for (const issue of Object.values(issueMap))
90
- issue.isFixed = true;
93
+ if (issue.fixes.length > 0)
94
+ issue.isFixed = true;
91
95
  }
92
96
  }
93
97
  return touchedFiles;
@@ -131,7 +135,8 @@ class IssueFixer {
131
135
  const keep = (_, i) => !remove.has(i + 1);
132
136
  await writeFile(absFilePath, fileContent.split('\n').filter(keep).join('\n'));
133
137
  for (const issue of issuesForFile)
134
- issue.isFixed = true;
138
+ if (issue.fixes.length > 0)
139
+ issue.isFixed = true;
135
140
  touchedFiles.add(filePath);
136
141
  }
137
142
  else {
@@ -9,12 +9,12 @@ import { createManifest } from './util/package-json.js';
9
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
- import { debugLogArray, debugLogObject } from './util/debug.js';
12
+ import { debugLog, debugLogArray, debugLogObject } from './util/debug.js';
13
13
  import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './util/glob.js';
14
14
  import { isCatalog, isConfig, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
15
15
  import { filterTransitiveDependencies } from './util/filter-transitive-dependencies.js';
16
16
  import { timerify } from './util/Performance.js';
17
- import { basename, dirname, join, relative, toRelative } from './util/path.js';
17
+ import { basename, dirname, extname, join, relative, 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';
@@ -378,14 +378,17 @@ export class WorkspaceWorker {
378
378
  }
379
379
  }
380
380
  catch (error) {
381
- if (!(error instanceof Error))
382
- throw error;
383
381
  hasLoadConfigError = true;
384
- this.handleConfigLoadError();
385
382
  const relPath = toRelative(configFilePath, this.options.cwd);
386
- const cause = formatCauseMessage(error, this.options.cwd);
387
- logError(`Error loading ${relPath} (${cause})`);
388
- logError('Please fix or visit https://knip.dev/reference/known-issues');
383
+ const cause = formatCauseMessage(error instanceof Error ? error : new Error(String(error)), this.options.cwd);
384
+ if (plugin.isLoadConfigOptional) {
385
+ debugLog(wsName, `Error loading ${relPath} (${cause})`);
386
+ }
387
+ else {
388
+ this.handleConfigLoadError();
389
+ logError(`Error loading ${relPath} (${cause})`);
390
+ logError('Please fix or visit https://knip.dev/reference/known-issues');
391
+ }
389
392
  }
390
393
  }
391
394
  }
@@ -398,9 +401,11 @@ export class WorkspaceWorker {
398
401
  cache.resolveFromAST = inputs;
399
402
  }
400
403
  if (!isManifest) {
401
- inputs.push(toEntry(configFilePath));
404
+ if (extname(configFilePath)) {
405
+ inputs.push(toEntry(configFilePath));
406
+ cache.configFile = toEntry(configFilePath);
407
+ }
402
408
  storeConfigFilePath(pluginName, toConfig(pluginName, configFilePath));
403
- cache.configFile = toEntry(configFilePath);
404
409
  if (hasLoadConfigError) {
405
410
  this.cache.removeEntry(configFilePath);
406
411
  }
@@ -21,6 +21,7 @@ const commands = new Set([
21
21
  'discord',
22
22
  'exec',
23
23
  'feedback',
24
+ 'fmt',
24
25
  'fuzzilli',
25
26
  'getcompletes',
26
27
  'help',
@@ -3,6 +3,15 @@ import { isBinary, toBinary, toDependency } from '../../util/input.js';
3
3
  import { extractBinary, isValidBinary, stripVersionFromSpecifier } from '../../util/modules.js';
4
4
  import { isInternal } from '../../util/path.js';
5
5
  import { argsAfter, expandScript } from '../util.js';
6
+ const runCommands = new Set(['run', 'run-script', 'rum', 'urn']);
7
+ const lifecycleScripts = new Map([
8
+ ['start', 'start'],
9
+ ['stop', 'stop'],
10
+ ['restart', 'restart'],
11
+ ['test', 'test'],
12
+ ['t', 'test'],
13
+ ['tst', 'test'],
14
+ ]);
6
15
  export const resolve = (_binary, words, options) => {
7
16
  const { fromArgs, manifest } = options;
8
17
  const parsed = parseArgs(words, {
@@ -49,8 +58,9 @@ export const resolve = (_binary, words, options) => {
49
58
  return [...packageInputs, ...inputs];
50
59
  }
51
60
  const _childArgs = parsed['--'] && parsed['--'].length > 0 ? fromArgs(argsAfter(words, '--'), { isForwardedArgs: true }) : [];
52
- if (command === 'run' && manifest.scriptNames.has(script)) {
53
- return expandScript(script, argsAfter(words, '--'), manifest.scripts, options) ?? _childArgs;
61
+ const name = runCommands.has(command) ? script : lifecycleScripts.get(command);
62
+ if (name && manifest.scriptNames.has(name)) {
63
+ return expandScript(name, argsAfter(words, '--'), manifest.scripts, options) ?? _childArgs;
54
64
  }
55
65
  return [];
56
66
  };
@@ -89,6 +89,7 @@ const commands = [
89
89
  'with',
90
90
  ];
91
91
  const recursiveCommands = ['recursive', 'multi', 'm'];
92
+ const testAliases = new Set(['t', 'tst']);
92
93
  export const resolve = (_binary, words, options) => {
93
94
  const parseOptions = {
94
95
  isStorePositions: true,
@@ -120,16 +121,17 @@ export const resolve = (_binary, words, options) => {
120
121
  if (parsed.filter && !parsed.recursive)
121
122
  return [];
122
123
  const childInputs = parsed['--'] && parsed['--'].length > 0 ? fromArgs(argsAfter(words, '--'), { isForwardedArgs: true }) : [];
123
- if (command === 'run') {
124
+ if (command === 'run' || command === 'run-script') {
124
125
  const script = parsed._[1];
125
126
  if (script && manifest.scriptNames.has(script)) {
126
127
  return expandScript(script, argsAfter(words, script), manifest.scripts, options) ?? childInputs;
127
128
  }
128
129
  return childInputs;
129
130
  }
130
- const isScript = manifest.scriptNames.has(command);
131
+ const name = testAliases.has(command) ? 'test' : command;
132
+ const isScript = manifest.scriptNames.has(name);
131
133
  if (isScript)
132
- return expandScript(command, argsAfter(words, command), manifest.scripts, options) ?? childInputs;
134
+ return expandScript(name, argsAfter(words, command), manifest.scripts, options) ?? childInputs;
133
135
  if (commands.includes(command))
134
136
  return childInputs;
135
137
  return command && isValidBinary(command) ? [toBinary(command)] : [];
@@ -1,7 +1,7 @@
1
1
  export const fencedCodeBlockMatcher = /```[\s\S]*?```/g;
2
2
  export const inlineCodeMatcher = /`[^`]+`/g;
3
- export const scriptExtractor = /<script\b((?:[^>"']|"[^"]*"|'[^']*')*)(?<!\/)>([\s\S]*?)<\/script>/gi;
4
- export const styleExtractor = /<style\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/style>/gi;
3
+ export const scriptExtractor = /<script(?=[\s/>])((?:[^>"']|"[^"]*"|'[^']*')*)(?<!\/)>([\s\S]*?)<\/script>/gi;
4
+ export const styleExtractor = /<style(?![\w-])((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/style>/gi;
5
5
  const langAttrMatcher = /\blang\s*=\s*["']([^"']+)["']/i;
6
6
  export const blockCommentMatcher = /\/\*[\s\S]*?\*\//g;
7
7
  export const lineCommentMatcher = /^[ \t]*\/\/.*$/gm;
@@ -1,26 +1,6 @@
1
- import { ensureRelative, isScopedPackage, isTildePackage, splitSpec } from './shared.js';
2
- import { hasUrlScheme } from '../util/url.js';
1
+ import { getUrlSpecifier, isScopedPackage, isTildePackage, splitSpec } from './shared.js';
3
2
  const dependencies = ['sass', 'sass-embedded', 'node-sass'];
4
- const dependencyMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|\/\/[^\r\n]*(?:[\r\n]|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]|url\(\s*(?:["']([^"']*)["']|([^'")\s]+))\s*\)/g;
5
- const getUrlSpecifier = (url) => {
6
- if (!url ||
7
- url.startsWith('//') ||
8
- url.startsWith('/') ||
9
- url.startsWith('#') ||
10
- hasUrlScheme(url) ||
11
- url.includes('$') ||
12
- url.includes('#{'))
13
- return;
14
- let end = url.length;
15
- const queryIndex = url.indexOf('?');
16
- if (queryIndex !== -1)
17
- end = queryIndex;
18
- const fragmentIndex = url.indexOf('#');
19
- if (fragmentIndex !== -1 && fragmentIndex < end)
20
- end = fragmentIndex;
21
- const path = url.slice(0, end);
22
- return path ? ensureRelative(path) : undefined;
23
- };
3
+ const dependencyMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|\/\/[^\r\n]*(?:[\r\n]|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]|url\(\s*(?:["']([^"'\r\n]*)["']|([^'")\s]+))\s*\)/g;
24
4
  const candidates = (specifier) => {
25
5
  const { dir, name } = splitSpec(specifier);
26
6
  const hasExt = name.endsWith('.scss') || name.endsWith('.sass');
@@ -1,6 +1,6 @@
1
1
  export declare const isScopedPackage: (s: string) => boolean;
2
2
  export declare const isTildePackage: (s: string) => boolean;
3
- export declare const ensureRelative: (spec: string) => string;
3
+ export declare const getUrlSpecifier: (url: string) => string | undefined;
4
4
  export declare const splitSpec: (specifier: string) => {
5
5
  dir: string;
6
6
  name: string;
@@ -1,8 +1,31 @@
1
1
  import { basename, dirname } from '../util/path.js';
2
+ import { hasUrlScheme } from '../util/url.js';
2
3
  const isAlias = (s) => (s.charCodeAt(0) === 64 && s.charCodeAt(1) === 47) || s.charCodeAt(0) === 126 || s.charCodeAt(0) === 35;
3
4
  export const isScopedPackage = (s) => s.charCodeAt(0) === 64 && s.charCodeAt(1) !== 47;
4
5
  export const isTildePackage = (s) => s.charCodeAt(0) === 126 && s.charCodeAt(1) !== 47;
5
- export const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
6
+ export const getUrlSpecifier = (url) => {
7
+ if (!url ||
8
+ url.startsWith('//') ||
9
+ url.startsWith('/') ||
10
+ url.startsWith('#') ||
11
+ hasUrlScheme(url) ||
12
+ url.includes('$') ||
13
+ url.includes('#{') ||
14
+ url.includes('('))
15
+ return;
16
+ let end = url.length;
17
+ const queryIndex = url.indexOf('?');
18
+ if (queryIndex !== -1)
19
+ end = queryIndex;
20
+ const fragmentIndex = url.indexOf('#');
21
+ if (fragmentIndex !== -1 && fragmentIndex < end)
22
+ end = fragmentIndex;
23
+ const path = url.slice(0, end);
24
+ if (!path)
25
+ return;
26
+ return isScopedPackage(path) ? path : ensureRelative(path);
27
+ };
28
+ const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
6
29
  export const splitSpec = (specifier) => {
7
30
  const spec = ensureRelative(specifier);
8
31
  return { dir: dirname(spec), name: basename(spec) };
package/dist/constants.js CHANGED
@@ -101,6 +101,7 @@ export const IGNORED_GLOBAL_BINARIES = new Set([
101
101
  'nub',
102
102
  'nubx',
103
103
  'open',
104
+ 'osascript',
104
105
  'paste',
105
106
  'pnpm',
106
107
  'pnpx',
@@ -186,6 +187,7 @@ export const FOREIGN_FILE_EXTENSIONS = new Set([
186
187
  '.jpg',
187
188
  '.less',
188
189
  '.mp3',
190
+ '.otf',
189
191
  '.png',
190
192
  '.sass',
191
193
  '.scss',
@@ -250,9 +250,36 @@ const getImportedComponentImports = (maps, names) => {
250
250
  }
251
251
  return imports;
252
252
  };
253
+ const srcBlockMatcher = /<!--[\s\S]*?-->|<(script|style)(?=[\s/>])((?:[^>"']|"[^"]*"|'[^']*')*?)(?:\/>|>[\s\S]*?<\/\1\s*>)/g;
254
+ const attributeMatcher = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
255
+ const getSrc = (attrs) => {
256
+ for (const [, name, double, single, unquoted] of attrs.matchAll(attributeMatcher)) {
257
+ if (name === 'src')
258
+ return double ?? single ?? unquoted;
259
+ }
260
+ };
261
+ const getSrcImports = (source) => {
262
+ if (!source.includes('src'))
263
+ return '';
264
+ const imports = [];
265
+ for (const [, tag, attrs] of source.matchAll(srcBlockMatcher)) {
266
+ const src = tag && getSrc(attrs);
267
+ if (!src)
268
+ continue;
269
+ const specifier = JSON.stringify(src);
270
+ if (tag === 'script') {
271
+ imports.push(`import _sfc_main from ${specifier};\nexport * from ${specifier};\nexport default _sfc_main;`);
272
+ }
273
+ else
274
+ imports.push(`import ${specifier};`);
275
+ }
276
+ return imports.join('\n');
277
+ };
253
278
  const compileVueSfc = (source, path, maps, root) => {
254
279
  if (maps.importMap.size === 0 && maps.componentMap.size === 0) {
255
- return [scriptBodies(source, path), stylePreprocessorImports(source, path)].filter(Boolean).join(';\n');
280
+ return [scriptBodies(source, path), getSrcImports(source), stylePreprocessorImports(source, path)]
281
+ .filter(Boolean)
282
+ .join(';\n');
256
283
  }
257
284
  const sfc = sfcForRoot(root);
258
285
  const { descriptor } = sfc.parse(source, path);
@@ -284,6 +311,9 @@ const compileVueSfc = (source, path, maps, root) => {
284
311
  }
285
312
  scripts.push(...getSyntheticImports(maps, identifiers, path, templateTags));
286
313
  scripts.push(...getImportedComponentImports(maps, importedComponents));
314
+ const srcImports = getSrcImports(source);
315
+ if (srcImports)
316
+ scripts.push(srcImports);
287
317
  const styles = stylePreprocessorImports(source, path);
288
318
  if (styles)
289
319
  scripts.push(styles);
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,33 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ import { toShellCommand } from '../../util/scripts.js';
3
+ const title = 'Buf';
4
+ const enablers = ['@bufbuild/buf', '@bufbuild/protoc-gen-es'];
5
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
+ const config = ['buf.gen.yaml'];
7
+ const args = {
8
+ config: ['template'],
9
+ };
10
+ const resolveConfig = (config, options) => {
11
+ const inputs = [];
12
+ for (const plugin of config.plugins ?? []) {
13
+ const name = plugin.plugin ?? plugin.name;
14
+ const command = plugin.local ?? plugin.path ?? (name && !name.includes('/') ? `protoc-gen-${name}` : undefined);
15
+ if (!command)
16
+ continue;
17
+ const script = toShellCommand(typeof command === 'string' ? [command] : command);
18
+ for (const input of options.getInputsFromScripts(script, { optionalBinaries: true })) {
19
+ input.dir ??= options.cwd;
20
+ inputs.push(input);
21
+ }
22
+ }
23
+ return inputs;
24
+ };
25
+ const plugin = {
26
+ title,
27
+ enablers,
28
+ isEnabled,
29
+ config,
30
+ args,
31
+ resolveConfig,
32
+ };
33
+ export default plugin;
@@ -0,0 +1,8 @@
1
+ export interface BufGenConfig {
2
+ plugins?: Array<{
3
+ local?: string | string[];
4
+ path?: string | string[];
5
+ plugin?: string;
6
+ name?: string;
7
+ }>;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -21,9 +21,22 @@ const resolveConfig = localConfig => {
21
21
  const preload = localConfig.test?.preload ?? [];
22
22
  return preload.map(specifier => toDeferResolve(specifier));
23
23
  };
24
+ const isPath = (arg) => /^\.{0,2}\//.test(arg);
25
+ const toFilterPatterns = (filter) => {
26
+ if (filter === '.')
27
+ return patterns;
28
+ if (/\.[cm]?[jt]sx?$/.test(filter))
29
+ return [`**/*${filter}`];
30
+ return [
31
+ ...patterns.map(pattern => `**/*${filter}*/${pattern}`),
32
+ ...patterns.map(pattern => pattern.replace('**/*', `**/*${filter}*`)),
33
+ ];
34
+ };
24
35
  const toPatterns = (arg) => {
25
36
  if (/[*{?]/.test(arg))
26
37
  return [arg];
38
+ if (!isPath(arg))
39
+ return toFilterPatterns(arg);
27
40
  if (/\.\w+$/.test(arg))
28
41
  return [arg];
29
42
  const dir = arg.replace(/\/+$/, '');
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,94 @@
1
+ import { toConfig, toDependency, toProductionEntry } from '../../util/input.js';
2
+ import { toAbsolute } from '../../util/path.js';
3
+ import { hasDependency } from '../../util/plugin.js';
4
+ import { findWebpackDependenciesFromConfig } from '../webpack/index.js';
5
+ const title = 'Electron Forge';
6
+ const enablers = ['@electron-forge/cli'];
7
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
8
+ const packageJsonPath = 'config.forge';
9
+ const config = ['package.json', 'forge.config.{js,mjs,cjs,ts,mts,cts}'];
10
+ const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
11
+ const isPlainObject = (value) => isObject(value) && Object.getPrototypeOf(value) === Object.prototype;
12
+ const toArray = (value) => (Array.isArray(value) ? value : value === undefined ? [] : [value]);
13
+ const toStrings = (value) => {
14
+ const values = [];
15
+ for (const item of isObject(value) ? Object.values(value) : toArray(value)) {
16
+ if (typeof item === 'string')
17
+ values.push(item);
18
+ }
19
+ return values;
20
+ };
21
+ const getPluginInputs = async (name, opts, options) => {
22
+ if (!isObject(opts))
23
+ return [];
24
+ const { cwd, configFilePath } = options;
25
+ const inputs = [];
26
+ const addEntry = (value) => {
27
+ for (const id of toStrings(value))
28
+ inputs.push(toProductionEntry(toAbsolute(id, cwd)));
29
+ };
30
+ const addConfig = async (pluginName, value) => {
31
+ if (typeof value === 'string') {
32
+ inputs.push(toConfig(pluginName, value, { dir: cwd, containingFilePath: configFilePath }));
33
+ }
34
+ else if (pluginName === 'webpack' && isObject(value)) {
35
+ for (const input of await findWebpackDependenciesFromConfig(value, options))
36
+ inputs.push(input);
37
+ }
38
+ };
39
+ if (name === 'vite' || name === '@electron-forge/plugin-vite') {
40
+ for (const build of toArray(opts.build)) {
41
+ if (!isObject(build))
42
+ continue;
43
+ addEntry(build.entry);
44
+ await addConfig('vite', build.config);
45
+ }
46
+ for (const renderer of toArray(opts.renderer))
47
+ if (isObject(renderer))
48
+ await addConfig('vite', renderer.config);
49
+ }
50
+ else if (name === 'webpack' || name === '@electron-forge/plugin-webpack') {
51
+ await addConfig('webpack', opts.mainConfig);
52
+ for (const renderer of toArray(opts.renderer)) {
53
+ if (!isObject(renderer))
54
+ continue;
55
+ await addConfig('webpack', renderer.config);
56
+ for (const entryPoint of toArray(renderer.entryPoints)) {
57
+ if (!isObject(entryPoint))
58
+ continue;
59
+ addEntry(entryPoint.js);
60
+ if (!isObject(entryPoint.preload))
61
+ continue;
62
+ addEntry(entryPoint.preload.js);
63
+ await addConfig('webpack', entryPoint.preload.config);
64
+ }
65
+ }
66
+ }
67
+ return inputs;
68
+ };
69
+ const resolveConfig = async (localConfig, options) => {
70
+ if (typeof localConfig === 'string') {
71
+ return [toConfig('electron-forge', localConfig, { containingFilePath: options.configFilePath })];
72
+ }
73
+ if (!isObject(localConfig))
74
+ return [];
75
+ const inputs = [];
76
+ for (const item of [localConfig.makers, localConfig.publishers, localConfig.plugins].flatMap(toArray)) {
77
+ if (!isObject(item))
78
+ continue;
79
+ if (isPlainObject(item) && typeof item.name === 'string')
80
+ inputs.push(toDependency(item.name));
81
+ for (const input of await getPluginInputs(item.name, item.config, options))
82
+ inputs.push(input);
83
+ }
84
+ return inputs;
85
+ };
86
+ const plugin = {
87
+ title,
88
+ enablers,
89
+ isEnabled,
90
+ packageJsonPath,
91
+ config,
92
+ resolveConfig,
93
+ };
94
+ export default plugin;
@@ -4,6 +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 declare const toParser: (name: string) => Input;
7
8
  export type ImportSettingKind = 'resolver' | 'parsers';
8
9
  export declare const importSettingKinds: Map<string, ImportSettingKind>;
9
10
  export declare const getInputsFromSettings: (settings?: Settings) => Input[];
@@ -33,7 +33,7 @@ const getInputsDeprecated = (config, options) => {
33
33
  return [...extendConfigs, ...deferred, ...parsers, ...babelDependencies, ...overrides];
34
34
  };
35
35
  const isParserObject = (value) => typeof value.parseForESLint === 'function' || typeof value.parse === 'function';
36
- const toParser = (name) => toDeferResolve(name, name === 'espree' ? { optional: true } : {});
36
+ export const toParser = (name) => toDeferResolve(name, name === 'espree' ? { optional: true } : {});
37
37
  const getParsers = ({ parser, parserOptions }) => {
38
38
  const inputs = [];
39
39
  for (const value of [parser, parserOptions?.parser]) {
@@ -3,7 +3,17 @@ 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
+ import { importSettingKinds, toParser } from './helpers.js';
7
+ const isParserObjectExpression = (node) => {
8
+ for (const prop of node.properties) {
9
+ if (prop.type === 'SpreadElement')
10
+ return true;
11
+ const key = getPropertyKey(prop);
12
+ if (key === 'parse' || key === 'parseForESLint')
13
+ return true;
14
+ }
15
+ return false;
16
+ };
7
17
  const getInputsFromSettingsAST = (program) => {
8
18
  const inputs = [];
9
19
  const addResolver = (kind, resolver) => {
@@ -12,6 +22,10 @@ const getInputsFromSettingsAST = (program) => {
12
22
  const dep = kind === 'resolver' ? `eslint-import-resolver-${resolver}` : resolver;
13
23
  inputs.push(toDeferResolve(dep, { optional: true }));
14
24
  };
25
+ const addParser = (name) => {
26
+ if (name)
27
+ inputs.push(toParser(name));
28
+ };
15
29
  const addResolvers = (kind, node) => {
16
30
  if (node?.type === 'ArrayExpression') {
17
31
  for (const element of node.elements)
@@ -32,15 +46,26 @@ const getInputsFromSettingsAST = (program) => {
32
46
  const visitor = new Visitor({
33
47
  ObjectExpression(node) {
34
48
  const settingsNode = findProperty(node, 'settings');
35
- if (!settingsNode || settingsNode.type !== 'ObjectExpression')
36
- return;
37
- for (const prop of settingsNode.properties ?? []) {
38
- if (prop.type !== 'Property')
39
- continue;
40
- const key = getPropertyKey(prop);
41
- const kind = key && importSettingKinds.get(key);
42
- if (kind)
43
- addResolvers(kind, prop.value);
49
+ if (settingsNode?.type === 'ObjectExpression') {
50
+ for (const prop of settingsNode.properties ?? []) {
51
+ if (prop.type !== 'Property')
52
+ continue;
53
+ const key = getPropertyKey(prop);
54
+ const kind = key && importSettingKinds.get(key);
55
+ if (kind)
56
+ addResolvers(kind, prop.value);
57
+ }
58
+ }
59
+ const parser = findProperty(findProperty(node, 'parserOptions'), 'parser');
60
+ if (parser?.type === 'ObjectExpression') {
61
+ if (isParserObjectExpression(parser))
62
+ return;
63
+ for (const prop of parser.properties)
64
+ if (prop.type === 'Property')
65
+ addParser(getStringValue(prop.value));
66
+ }
67
+ else {
68
+ addParser(getStringValue(parser));
44
69
  }
45
70
  },
46
71
  });
@@ -15,6 +15,6 @@ export declare const getConfig: (localConfig: ExpoConfig, options: PluginOptions
15
15
  userInterfaceStyle?: 'automatic' | 'light' | 'dark';
16
16
  };
17
17
  androidNavigationBar?: Record<string, unknown>;
18
- plugins?: (string | [string, Record<string, unknown>])[];
18
+ plugins?: (string | ((config: unknown) => unknown) | [string | ((config: unknown) => unknown), Record<string, unknown>])[];
19
19
  };
20
20
  export declare const getDependencies: ResolveConfig<ExpoConfig>;