sadrazam 0.1.10 → 0.1.12

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.
package/dist/plugins.js CHANGED
@@ -1,98 +1,76 @@
1
- import { access } from "node:fs/promises";
1
+ import { access, readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import fg from "fast-glob";
3
4
  const COMMAND_SPLIT_RE = /\s*(?:&&|\|\||;)\s*/;
4
5
  const TOKEN_RE = /"[^"]*"|'[^']*'|`[^`]*`|[^\s]+/g;
5
- function createConfigEntryPlugin(name, commands, flags) {
6
- return {
7
- name,
8
- supports(command) {
9
- return commands.includes(command);
10
- },
11
- async resolve(tokens, packageDir) {
12
- const fileEntries = new Set();
13
- for (let index = 0; index < tokens.length; index += 1) {
14
- const token = stripQuotes(tokens[index] ?? "");
15
- const next = stripQuotes(tokens[index + 1] ?? "");
16
- if (!flags.includes(token) || !next) {
17
- continue;
18
- }
19
- const configPath = path.resolve(packageDir, next);
20
- if (await fileExists(configPath)) {
21
- fileEntries.add(configPath);
22
- }
23
- index += 1;
24
- }
25
- return fileEntries.size > 0
26
- ? {
27
- fileEntries: [...fileEntries],
28
- }
29
- : null;
30
- },
31
- };
32
- }
6
+ const CONFIG_EXTENSIONS = "{js,cjs,mjs,ts,cts,mts,json,jsonc}";
7
+ const CONFIG_FLAG_ALIASES = ["--config", "-c"];
33
8
  const PLUGINS = [
34
- createConfigEntryPlugin("vite", ["vite"], ["--config"]),
35
- createConfigEntryPlugin("vitest", ["vitest"], ["--config"]),
36
- createConfigEntryPlugin("jest", ["jest"], ["--config"]),
9
+ createToolPlugin("vite", ["vite"], ["vite"], [`vite.config.${CONFIG_EXTENSIONS}`]),
10
+ createToolPlugin("vitest", ["vitest"], ["vitest"], [`vitest.config.${CONFIG_EXTENSIONS}`]),
11
+ createToolPlugin("jest", ["jest"], ["jest"], [
12
+ `jest.config.${CONFIG_EXTENSIONS}`,
13
+ "package.json",
14
+ ]),
15
+ createToolPlugin("playwright", ["playwright"], ["@playwright/test", "playwright"], [
16
+ `playwright.config.${CONFIG_EXTENSIONS}`,
17
+ ], ["tests/**", "e2e/**"]),
18
+ createToolPlugin("cypress", ["cypress"], ["cypress"], [
19
+ `cypress.config.${CONFIG_EXTENSIONS}`,
20
+ ], ["cypress/**"]),
21
+ createToolPlugin("storybook", ["storybook", "start-storybook", "build-storybook"], ["storybook", "@storybook/cli"], [
22
+ ".storybook/main.{js,cjs,mjs,ts,cts,mts}",
23
+ ".storybook/preview.{js,cjs,mjs,ts,cts,mts}",
24
+ ], [".storybook/**", "src/**/*.stories.{js,jsx,ts,tsx,mdx}"]),
25
+ createToolPlugin("next", ["next"], ["next"], [
26
+ "next.config.{js,cjs,mjs,ts}",
27
+ ], ["pages/**/*.{js,jsx,ts,tsx}", "app/**/*.{js,jsx,ts,tsx}", "src/pages/**/*.{js,jsx,ts,tsx}", "src/app/**/*.{js,jsx,ts,tsx}"]),
28
+ createToolPlugin("astro", ["astro"], ["astro"], [
29
+ "astro.config.{js,cjs,mjs,ts}",
30
+ ], ["src/pages/**/*.astro", "src/content/**/*.{md,mdx}"]),
31
+ createToolPlugin("sveltekit", ["svelte-kit"], ["@sveltejs/kit"], [
32
+ "svelte.config.{js,cjs,mjs,ts}",
33
+ "vite.config.{js,cjs,mjs,ts}",
34
+ ], ["src/routes/**/*.{js,ts,svelte}", "src/hooks.{js,ts}"]),
35
+ createToolPlugin("webpack", ["webpack", "webpack-cli"], ["webpack", "webpack-cli"], [
36
+ `webpack.config.${CONFIG_EXTENSIONS}`,
37
+ ]),
38
+ createToolPlugin("rollup", ["rollup"], ["rollup"], [
39
+ `rollup.config.${CONFIG_EXTENSIONS}`,
40
+ ]),
37
41
  {
38
- name: "prettier",
39
- supports(command) {
40
- return command === "prettier";
41
- },
42
- async resolve(tokens, packageDir) {
43
- const packages = new Set();
44
- const fileEntries = new Set();
45
- for (let index = 0; index < tokens.length; index += 1) {
46
- const token = stripQuotes(tokens[index] ?? "");
47
- const next = stripQuotes(tokens[index + 1] ?? "");
48
- if (token === "--plugin" && next) {
49
- packages.add(next);
50
- index += 1;
51
- continue;
52
- }
53
- if (token === "--config" && next) {
54
- const configPath = path.resolve(packageDir, next);
55
- if (await fileExists(configPath)) {
56
- fileEntries.add(configPath);
57
- }
58
- index += 1;
59
- }
60
- }
61
- if (packages.size === 0 && fileEntries.size === 0) {
62
- return null;
63
- }
64
- return {
65
- packages: [...packages],
66
- fileEntries: [...fileEntries],
67
- };
68
- },
42
+ ...createToolPlugin("eslint", ["eslint"], ["eslint"], [
43
+ ".eslintrc",
44
+ `.eslintrc.${CONFIG_EXTENSIONS}`,
45
+ `eslint.config.${CONFIG_EXTENSIONS}`,
46
+ ]),
47
+ packageFlags: [
48
+ { flag: "--parser" },
49
+ { flag: "--plugin", normalize: normalizeEslintPlugin },
50
+ ],
51
+ analyzeConfig: analyzeEslintConfig,
69
52
  },
70
53
  {
71
- name: "eslint",
72
- supports(command) {
73
- return command === "eslint";
74
- },
75
- async resolve(tokens) {
76
- const packages = new Set();
77
- for (let index = 0; index < tokens.length; index += 1) {
78
- const token = stripQuotes(tokens[index] ?? "");
79
- const next = stripQuotes(tokens[index + 1] ?? "");
80
- if (token === "--parser" && next) {
81
- packages.add(next);
82
- index += 1;
83
- continue;
84
- }
85
- if (token === "--plugin" && next) {
86
- packages.add(normalizeEslintPlugin(next));
87
- index += 1;
88
- }
89
- }
90
- return packages.size > 0
91
- ? {
92
- packages: [...packages],
93
- }
94
- : null;
95
- },
54
+ ...createToolPlugin("prettier", ["prettier"], ["prettier"], [
55
+ `.prettierrc.${CONFIG_EXTENSIONS}`,
56
+ "prettier.config.{js,cjs,mjs,ts,cts,mts}",
57
+ ".prettierrc",
58
+ ]),
59
+ packageFlags: [{ flag: "--plugin" }],
60
+ analyzePackageJson: analyzePrettierPackageJson,
61
+ },
62
+ {
63
+ ...createToolPlugin("tailwind", ["tailwindcss"], ["tailwindcss"], [
64
+ "tailwind.config.{js,cjs,mjs,ts}",
65
+ "postcss.config.{js,cjs,mjs,ts}",
66
+ ]),
67
+ },
68
+ {
69
+ ...createToolPlugin("typescript", ["tsc", "tsserver"], ["typescript"], [
70
+ "tsconfig.json",
71
+ "tsconfig.*.json",
72
+ ]),
73
+ analyzeConfig: analyzeTsConfig,
96
74
  },
97
75
  ];
98
76
  export async function analyzePlugins(context) {
@@ -100,63 +78,331 @@ export async function analyzePlugins(context) {
100
78
  const commandPackages = new Set();
101
79
  const fileEntries = new Set();
102
80
  const commandUsage = new Map();
103
- for (const [scriptName, script] of Object.entries(context.scripts)) {
104
- const segments = script.split(COMMAND_SPLIT_RE);
105
- for (const segment of segments) {
106
- const tokens = tokenize(segment);
107
- if (tokens.length === 0) {
108
- continue;
109
- }
110
- const command = resolveCommandName(tokens);
111
- if (!command) {
112
- continue;
113
- }
114
- for (const plugin of PLUGINS) {
115
- if (!plugin.supports(command)) {
116
- continue;
117
- }
118
- const contribution = await plugin.resolve(tokens, context.packageDir);
119
- if (!contribution) {
120
- continue;
121
- }
122
- activePlugins.add(plugin.name);
123
- for (const packageName of contribution.packages ?? []) {
124
- commandPackages.add(packageName);
125
- addUsage(commandUsage, packageName, `script:${scriptName}`);
126
- }
127
- for (const filePath of contribution.fileEntries ?? []) {
128
- fileEntries.add(filePath);
129
- }
130
- for (const [packageName, sources] of Object.entries(contribution.packageUsage ?? {})) {
131
- commandPackages.add(packageName);
132
- for (const source of sources) {
133
- addUsage(commandUsage, packageName, source);
134
- }
135
- }
136
- }
81
+ const details = [];
82
+ const scripts = collectScriptInvocations(context.scripts);
83
+ for (const plugin of PLUGINS) {
84
+ const override = context.config?.[plugin.name];
85
+ if (override === false) {
86
+ continue;
87
+ }
88
+ const scriptInvocations = scripts.filter((script) => plugin.commands.includes(script.command));
89
+ const isForced = override === true || isPluginConfigObject(override);
90
+ const isDeclared = plugin.packages.some((packageName) => context.dependencyNames.has(packageName));
91
+ if (!isForced && !isDeclared && scriptInvocations.length === 0) {
92
+ continue;
93
+ }
94
+ const contribution = await collectPluginContribution(plugin, context, scriptInvocations, override);
95
+ if (!hasContribution(contribution) && !isDeclared && !isForced) {
96
+ continue;
137
97
  }
98
+ activePlugins.add(plugin.name);
99
+ mergeContribution(contribution, commandPackages, fileEntries, commandUsage);
100
+ details.push({
101
+ name: plugin.name,
102
+ activation: [
103
+ isDeclared ? "dependency" : null,
104
+ scriptInvocations.length > 0 ? "script" : null,
105
+ isForced ? "config" : null,
106
+ ].filter((value) => Boolean(value)),
107
+ packages: contribution.packages ?? [],
108
+ fileEntries: contribution.fileEntries ?? [],
109
+ });
138
110
  }
139
111
  return {
140
112
  activePlugins: [...activePlugins].sort(),
141
113
  commandPackages: [...commandPackages].sort(),
142
114
  fileEntries: [...fileEntries].sort(),
115
+ details: details.sort((left, right) => left.name.localeCompare(right.name)),
143
116
  commandUsage: Object.fromEntries([...commandUsage.entries()]
144
117
  .map(([packageName, sources]) => [packageName, [...sources].sort()])
145
118
  .sort(([left], [right]) => left.localeCompare(right))),
146
119
  };
147
120
  }
121
+ export async function analyzePluginInputs(packageDir, config) {
122
+ const commandPackages = new Set();
123
+ const fileEntries = new Set();
124
+ const commandUsage = new Map();
125
+ for (const packageName of config?.packageNames ?? []) {
126
+ commandPackages.add(packageName);
127
+ addUsage(commandUsage, packageName, "config:inputs.packageNames");
128
+ }
129
+ for (const entry of config?.entryFiles ?? []) {
130
+ const filePath = path.resolve(packageDir, entry);
131
+ if (await fileExists(filePath)) {
132
+ fileEntries.add(filePath);
133
+ }
134
+ }
135
+ return {
136
+ activePlugins: commandPackages.size > 0 || fileEntries.size > 0 ? ["inputs"] : [],
137
+ commandPackages: [...commandPackages].sort(),
138
+ fileEntries: [...fileEntries].sort(),
139
+ details: commandPackages.size > 0 || fileEntries.size > 0
140
+ ? [{
141
+ name: "inputs",
142
+ activation: ["config"],
143
+ packages: [...commandPackages].sort(),
144
+ fileEntries: [...fileEntries].sort(),
145
+ }]
146
+ : [],
147
+ commandUsage: Object.fromEntries([...commandUsage.entries()]
148
+ .map(([packageName, sources]) => [packageName, [...sources].sort()])
149
+ .sort(([left], [right]) => left.localeCompare(right))),
150
+ };
151
+ }
152
+ function createToolPlugin(name, commands, packages, configPatterns = [], entryPatterns = []) {
153
+ return {
154
+ name,
155
+ commands,
156
+ packages,
157
+ configPatterns,
158
+ entryPatterns,
159
+ configFlags: CONFIG_FLAG_ALIASES,
160
+ };
161
+ }
162
+ async function collectPluginContribution(plugin, context, scriptInvocations, override) {
163
+ const packages = new Set();
164
+ const fileEntries = new Set();
165
+ const packageUsage = new Map();
166
+ for (const invocation of scriptInvocations) {
167
+ if (plugin.packages[0]) {
168
+ packages.add(plugin.packages[0]);
169
+ addUsage(packageUsage, plugin.packages[0], `script:${invocation.scriptName}`);
170
+ }
171
+ for (const packageName of collectPackagesFromFlags(invocation.tokens, plugin.packageFlags ?? [])) {
172
+ packages.add(packageName.name);
173
+ addUsage(packageUsage, packageName.name, `script:${invocation.scriptName}`);
174
+ }
175
+ for (const filePath of await collectFilesFromFlags(context.packageDir, invocation.tokens, plugin.configFlags ?? [])) {
176
+ fileEntries.add(filePath);
177
+ }
178
+ for (const filePath of await collectPositionalFiles(context.packageDir, invocation.tokens.slice(1))) {
179
+ fileEntries.add(filePath);
180
+ }
181
+ }
182
+ const configPatterns = isPluginConfigObject(override)
183
+ ? toArray(override.config ?? plugin.configPatterns ?? [])
184
+ : plugin.configPatterns ?? [];
185
+ const entryPatterns = isPluginConfigObject(override)
186
+ ? toArray(override.entry ?? plugin.entryPatterns ?? [])
187
+ : plugin.entryPatterns ?? [];
188
+ for (const filePath of await collectFilesFromPatterns(context.packageDir, configPatterns)) {
189
+ fileEntries.add(filePath);
190
+ const configContribution = plugin.analyzeConfig ? await plugin.analyzeConfig(filePath) : null;
191
+ mergeContribution(configContribution, packages, fileEntries, packageUsage);
192
+ }
193
+ for (const filePath of await collectFilesFromPatterns(context.packageDir, entryPatterns)) {
194
+ fileEntries.add(filePath);
195
+ }
196
+ mergeContribution(plugin.analyzePackageJson?.(context) ?? null, packages, fileEntries, packageUsage);
197
+ return {
198
+ packages: [...packages].sort(),
199
+ fileEntries: [...fileEntries].sort(),
200
+ packageUsage: Object.fromEntries([...packageUsage.entries()].map(([packageName, sources]) => [packageName, [...sources].sort()])),
201
+ };
202
+ }
203
+ function collectScriptInvocations(scripts) {
204
+ const invocations = [];
205
+ for (const [scriptName, script] of Object.entries(scripts)) {
206
+ for (const segment of script.split(COMMAND_SPLIT_RE)) {
207
+ const tokens = tokenize(segment);
208
+ const command = resolveCommandName(tokens);
209
+ if (command) {
210
+ invocations.push({ scriptName, command, tokens });
211
+ }
212
+ }
213
+ }
214
+ return invocations;
215
+ }
216
+ function collectPackagesFromFlags(tokens, flags) {
217
+ const packages = [];
218
+ for (let index = 0; index < tokens.length; index += 1) {
219
+ const token = stripQuotes(tokens[index] ?? "");
220
+ const flag = flags.find((candidate) => candidate.flag === token);
221
+ const next = stripQuotes(tokens[index + 1] ?? "");
222
+ if (!flag || !next) {
223
+ continue;
224
+ }
225
+ packages.push({ name: flag.normalize ? flag.normalize(next) : next });
226
+ index += 1;
227
+ }
228
+ return packages;
229
+ }
230
+ async function collectFilesFromFlags(packageDir, tokens, flags) {
231
+ const fileEntries = new Set();
232
+ for (let index = 0; index < tokens.length; index += 1) {
233
+ const token = stripQuotes(tokens[index] ?? "");
234
+ const next = stripQuotes(tokens[index + 1] ?? "");
235
+ if (!flags.includes(token) || !next) {
236
+ continue;
237
+ }
238
+ for (const filePath of await resolveEntryPattern(packageDir, next)) {
239
+ fileEntries.add(filePath);
240
+ }
241
+ index += 1;
242
+ }
243
+ return [...fileEntries];
244
+ }
245
+ async function collectPositionalFiles(packageDir, tokens) {
246
+ const entries = new Set();
247
+ for (const rawToken of tokens) {
248
+ const token = stripQuotes(rawToken);
249
+ if (!token || token.startsWith("-") || looksLikePackageSpecifier(token)) {
250
+ continue;
251
+ }
252
+ for (const filePath of await resolveEntryPattern(packageDir, token)) {
253
+ entries.add(filePath);
254
+ }
255
+ }
256
+ return [...entries];
257
+ }
258
+ async function collectFilesFromPatterns(packageDir, patterns) {
259
+ const entries = new Set();
260
+ for (const pattern of patterns) {
261
+ for (const filePath of await resolveEntryPattern(packageDir, pattern)) {
262
+ entries.add(filePath);
263
+ }
264
+ }
265
+ return [...entries];
266
+ }
267
+ async function resolveEntryPattern(packageDir, pattern) {
268
+ const cleanPattern = stripQuotes(pattern);
269
+ const absolutePath = path.resolve(packageDir, cleanPattern);
270
+ if (!hasGlobMagic(cleanPattern) && await fileExists(absolutePath)) {
271
+ return [absolutePath];
272
+ }
273
+ return fg(cleanPattern, {
274
+ cwd: packageDir,
275
+ absolute: true,
276
+ dot: true,
277
+ onlyFiles: true,
278
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**"],
279
+ });
280
+ }
281
+ async function analyzeEslintConfig(filePath) {
282
+ if (!filePath.endsWith(".json") && !filePath.endsWith(".eslintrc")) {
283
+ return null;
284
+ }
285
+ const config = await readJsonFile(filePath);
286
+ if (!isRecord(config)) {
287
+ return null;
288
+ }
289
+ const packages = new Set();
290
+ for (const value of toArray(config.extends)) {
291
+ if (typeof value === "string" && !value.startsWith(".") && !path.isAbsolute(value)) {
292
+ packages.add(normalizeEslintConfig(value));
293
+ }
294
+ }
295
+ if (typeof config.parser === "string") {
296
+ packages.add(config.parser);
297
+ }
298
+ for (const value of toArray(config.plugins)) {
299
+ if (typeof value === "string") {
300
+ packages.add(normalizeEslintPlugin(value));
301
+ }
302
+ }
303
+ return packages.size > 0 ? { packages: [...packages] } : null;
304
+ }
305
+ function analyzePrettierPackageJson(context) {
306
+ const prettierConfig = context.packageJson.prettier;
307
+ if (!prettierConfig) {
308
+ return null;
309
+ }
310
+ if (typeof prettierConfig === "string") {
311
+ return {
312
+ fileEntries: [path.resolve(context.packageDir, prettierConfig)],
313
+ };
314
+ }
315
+ return {
316
+ packages: [...new Set(prettierConfig.plugins ?? [])],
317
+ };
318
+ }
319
+ async function analyzeTsConfig(filePath) {
320
+ const config = await readJsonFile(filePath);
321
+ if (!isRecord(config)) {
322
+ return null;
323
+ }
324
+ const fileEntries = new Set();
325
+ const packages = new Set();
326
+ const baseDir = path.dirname(filePath);
327
+ if (typeof config.extends === "string") {
328
+ if (config.extends.startsWith(".") || config.extends.startsWith("/")) {
329
+ const extendedPath = resolveTsConfigReference(baseDir, config.extends);
330
+ if (await fileExists(extendedPath)) {
331
+ fileEntries.add(extendedPath);
332
+ }
333
+ }
334
+ else {
335
+ packages.add(getPackageName(config.extends));
336
+ }
337
+ }
338
+ for (const reference of toUnknownArray(config.references)) {
339
+ if (!isRecord(reference) || typeof reference.path !== "string") {
340
+ continue;
341
+ }
342
+ const referencePath = resolveTsConfigReference(baseDir, reference.path);
343
+ if (await fileExists(referencePath)) {
344
+ fileEntries.add(referencePath);
345
+ }
346
+ }
347
+ const compilerOptions = isRecord(config.compilerOptions) ? config.compilerOptions : {};
348
+ for (const plugin of toUnknownArray(compilerOptions.plugins)) {
349
+ if (isRecord(plugin) && typeof plugin.name === "string") {
350
+ packages.add(plugin.name);
351
+ }
352
+ }
353
+ return fileEntries.size > 0 || packages.size > 0
354
+ ? { fileEntries: [...fileEntries], packages: [...packages] }
355
+ : null;
356
+ }
357
+ function resolveTsConfigReference(baseDir, value) {
358
+ const resolved = path.resolve(baseDir, value);
359
+ return path.extname(resolved) ? resolved : path.join(resolved, "tsconfig.json");
360
+ }
361
+ async function readJsonFile(filePath) {
362
+ try {
363
+ return JSON.parse(await readFile(filePath, "utf8"));
364
+ }
365
+ catch {
366
+ return null;
367
+ }
368
+ }
369
+ function mergeContribution(contribution, packages, fileEntries, packageUsage) {
370
+ if (!contribution) {
371
+ return;
372
+ }
373
+ for (const packageName of contribution.packages ?? []) {
374
+ packages.add(packageName);
375
+ }
376
+ for (const filePath of contribution.fileEntries ?? []) {
377
+ fileEntries.add(filePath);
378
+ }
379
+ for (const [packageName, sources] of Object.entries(contribution.packageUsage ?? {})) {
380
+ packages.add(packageName);
381
+ for (const source of sources) {
382
+ addUsage(packageUsage, packageName, source);
383
+ }
384
+ }
385
+ }
386
+ function hasContribution(contribution) {
387
+ return Boolean((contribution.packages?.length ?? 0) > 0
388
+ || (contribution.fileEntries?.length ?? 0) > 0
389
+ || Object.keys(contribution.packageUsage ?? {}).length > 0);
390
+ }
148
391
  function tokenize(command) {
149
392
  return command.match(TOKEN_RE)?.map((token) => token.trim()).filter(Boolean) ?? [];
150
393
  }
151
394
  function resolveCommandName(tokens) {
152
- const [first, second] = tokens;
395
+ const [first, second, third] = tokens;
153
396
  const command = stripQuotes(first ?? "");
154
397
  if (!command) {
155
398
  return null;
156
399
  }
157
- if (command === "npx" || command === "pnpx") {
400
+ if (command === "npx" || command === "pnpx" || command === "bunx") {
158
401
  return stripQuotes(second ?? "") || null;
159
402
  }
403
+ if ((command === "npm" || command === "pnpm" || command === "yarn") && stripQuotes(second ?? "") === "exec") {
404
+ return stripQuotes(third ?? "") || null;
405
+ }
160
406
  return command;
161
407
  }
162
408
  function normalizeEslintPlugin(value) {
@@ -169,9 +415,52 @@ function normalizeEslintPlugin(value) {
169
415
  }
170
416
  return value.startsWith("eslint-plugin-") ? value : `eslint-plugin-${value}`;
171
417
  }
418
+ function normalizeEslintConfig(value) {
419
+ if (value.startsWith("@")) {
420
+ if (value.includes("/eslint-config")) {
421
+ return value;
422
+ }
423
+ const [scope, name] = value.split("/");
424
+ return name ? `${scope}/eslint-config-${name}` : value;
425
+ }
426
+ return value.startsWith("eslint-config-") ? value : `eslint-config-${value}`;
427
+ }
428
+ function getPackageName(specifier) {
429
+ if (specifier.startsWith("@")) {
430
+ const [scope, name] = specifier.split("/");
431
+ return name ? `${scope}/${name}` : specifier;
432
+ }
433
+ return specifier.split("/")[0] ?? specifier;
434
+ }
435
+ function addUsage(usage, packageName, source) {
436
+ const sources = usage.get(packageName) ?? new Set();
437
+ sources.add(source);
438
+ usage.set(packageName, sources);
439
+ }
440
+ function isPluginConfigObject(value) {
441
+ return isRecord(value);
442
+ }
443
+ function isRecord(value) {
444
+ return typeof value === "object" && value !== null && !Array.isArray(value);
445
+ }
446
+ function toArray(value) {
447
+ if (Array.isArray(value)) {
448
+ return value.filter((item) => typeof item === "string");
449
+ }
450
+ return typeof value === "string" ? [value] : [];
451
+ }
452
+ function toUnknownArray(value) {
453
+ return Array.isArray(value) ? value : [];
454
+ }
172
455
  function stripQuotes(value) {
173
456
  return value.replace(/^['"`]|['"`]$/g, "");
174
457
  }
458
+ function hasGlobMagic(value) {
459
+ return /[*?[\]{}()!+@]/.test(value);
460
+ }
461
+ function looksLikePackageSpecifier(value) {
462
+ return !value.startsWith(".") && !value.startsWith("/") && !value.includes("*") && !/\.[cm]?[jt]sx?$/.test(value);
463
+ }
175
464
  async function fileExists(filePath) {
176
465
  try {
177
466
  await access(filePath);
@@ -181,33 +470,4 @@ async function fileExists(filePath) {
181
470
  return false;
182
471
  }
183
472
  }
184
- function addUsage(usageMap, packageName, source) {
185
- const entries = usageMap.get(packageName) ?? new Set();
186
- entries.add(source);
187
- usageMap.set(packageName, entries);
188
- }
189
- export async function analyzePluginInputs(packageDir, inputs) {
190
- const entryFiles = new Set();
191
- const commandPackages = new Set();
192
- const commandUsage = new Map();
193
- for (const entryFile of inputs?.entryFiles ?? []) {
194
- const absolutePath = path.resolve(packageDir, entryFile);
195
- if (await fileExists(absolutePath)) {
196
- entryFiles.add(absolutePath);
197
- }
198
- }
199
- for (const packageName of inputs?.packageNames ?? []) {
200
- commandPackages.add(packageName);
201
- addUsage(commandUsage, packageName, "input:config");
202
- }
203
- const activePlugins = entryFiles.size > 0 || commandPackages.size > 0 ? ["inputs"] : [];
204
- return {
205
- activePlugins,
206
- commandPackages: [...commandPackages].sort(),
207
- fileEntries: [...entryFiles].sort(),
208
- commandUsage: Object.fromEntries([...commandUsage.entries()]
209
- .map(([packageName, sources]) => [packageName, [...sources].sort()])
210
- .sort(([left], [right]) => left.localeCompare(right))),
211
- };
212
- }
213
473
  //# sourceMappingURL=plugins.js.map