vite-plus 0.2.7 → 0.2.9

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 (89) hide show
  1. package/AGENTS.md +7 -0
  2. package/LICENSE +5 -1
  3. package/README.md +9 -3
  4. package/bin/vpr +3 -2
  5. package/binding/index.cjs +193 -80
  6. package/binding/index.d.cts +106 -11
  7. package/dist/agent-DQU8uS6P.js +416 -0
  8. package/dist/bin.js +1388 -23
  9. package/dist/{cli-truncate-BVOlIIPy.js → cli-truncate-Bg3RDXpi.js} +0 -2
  10. package/dist/client/bundledDevClient.mjs +1 -0
  11. package/dist/config/bin.js +32 -133
  12. package/dist/{constants-BsuzPowC.js → constants-CG513DRa.js} +10 -2
  13. package/dist/create/bin.js +255 -268
  14. package/dist/{define-config-C2KfLHpC.js → define-config-CV4bQG_8.js} +3 -3
  15. package/dist/{define-config-eLQH9us2.d.ts → define-config-DWoAkNdp.d.ts} +16 -0
  16. package/dist/{define-config-DLh9fE95.cjs → define-config-DyNLA_f0.cjs} +1 -1
  17. package/dist/define-config.cjs +1 -1
  18. package/dist/define-config.d.ts +1 -1
  19. package/dist/define-config.js +1 -1
  20. package/dist/{dist-CKz3vcoG.js → dist-BDYZP12R.js} +196 -157
  21. package/dist/dist-Dqv1-Clg.js +3 -0
  22. package/dist/{agent-CPwWJ4qf.js → editor-g4PosU99.js} +819 -628
  23. package/dist/hooks/bin.d.ts +1 -0
  24. package/dist/hooks/bin.js +130 -0
  25. package/dist/hooks-pNCBWtFT.js +570 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/{json-DiRs8ceZ.js → json-qlK6UH0r.js} +40 -38
  30. package/dist/migration/bin.js +65 -58
  31. package/dist/{oxlint-plugin-config-Bxgc4cwF.js → oxlint-plugin-config-BEZ9IUf7.js} +1 -1
  32. package/dist/oxlint-plugin.js +1 -1
  33. package/dist/pack-bin.js +1 -1
  34. package/dist/{package-Ds3uThLb.js → package-B4T8RGMG.js} +2 -2
  35. package/dist/{tsconfig-Jia2vgMG.js → prompts-CHz_98bJ.js} +169 -219
  36. package/dist/{resolve-vite-config-BiuLZnn8.js → resolve-vite-config-Dmeyeyj-.js} +2 -9
  37. package/dist/{rolldown-runtime-C7HZzL1F.js → rolldown-runtime-CMFfr-1z.js} +1 -1
  38. package/dist/staged/bin.js +241 -226
  39. package/dist/terminal-Bz-ps6rJ.js +128 -0
  40. package/dist/test/browser/providers/playwright/context.d.ts +1 -1
  41. package/dist/test/browser/providers/playwright.d.ts +6 -6
  42. package/dist/test/browser/providers/preview/context.d.ts +1 -1
  43. package/dist/test/browser/providers/preview.d.ts +4 -4
  44. package/dist/test/browser/providers/webdriverio/context.d.ts +1 -1
  45. package/dist/test/browser/providers/webdriverio.d.ts +6 -6
  46. package/dist/test/browser-playwright/context.d.ts +1 -1
  47. package/dist/test/browser-playwright.d.ts +6 -6
  48. package/dist/test/browser-preview/context.d.ts +1 -1
  49. package/dist/test/browser-preview.d.ts +4 -4
  50. package/dist/test/browser-webdriverio/context.d.ts +1 -1
  51. package/dist/test/browser-webdriverio.d.ts +6 -6
  52. package/dist/test/context.d.ts +3 -3
  53. package/dist/test/locators.d.ts +1 -1
  54. package/dist/toolchain.d.ts +25 -0
  55. package/dist/toolchain.js +194 -0
  56. package/dist/toolchain.json +193 -0
  57. package/dist/tsconfig-7v_BHagU.js +151 -0
  58. package/dist/{tsgolint-path-B-yOos8p.js → tsgolint-path-CbDReEOx.js} +5 -3
  59. package/dist/tsgolint-path.js +1 -1
  60. package/dist/version.js +6 -6
  61. package/dist/versions.d.ts +3 -3
  62. package/dist/versions.js +6 -6
  63. package/docs/config/index.md +13 -0
  64. package/docs/config/staged.md +2 -1
  65. package/docs/guide/ci.md +37 -4
  66. package/docs/guide/commit-hooks.md +112 -21
  67. package/docs/guide/create.md +7 -4
  68. package/docs/guide/env.md +8 -4
  69. package/docs/guide/fmt.md +2 -2
  70. package/docs/guide/github-actions-cache.md +5 -1
  71. package/docs/guide/ide-integration.md +61 -2
  72. package/docs/guide/index.md +4 -2
  73. package/docs/guide/install.md +27 -0
  74. package/docs/guide/installer-env-vars.md +14 -3
  75. package/docs/guide/lint.md +3 -1
  76. package/docs/guide/migrate.md +49 -4
  77. package/docs/guide/monorepo.md +98 -10
  78. package/docs/guide/troubleshooting.md +12 -3
  79. package/docs/guide/upgrade.md +27 -4
  80. package/docs/package.json +1 -1
  81. package/docs/pnpm-workspace.yaml +7 -0
  82. package/docs/vite.config.ts +3 -0
  83. package/package.json +21 -23
  84. package/rules/vite-tools.yml +0 -7
  85. package/dist/dist-CtM2JRbM.js +0 -3
  86. package/dist/editor-BbT1lTNc.js +0 -675
  87. package/dist/help-YP84FSEz.js +0 -61
  88. package/dist/terminal-uTv0ZaMr.js +0 -33
  89. package/dist/{log-update-DHZRyJ2m.js → log-update-CoW8Z4Dl.js} +1 -1
@@ -1,675 +0,0 @@
1
- import { B as runCommandSilently, E as PackageManager, M as multiselect, P as select, R as isCancel, j as log, k as confirm, l as cancelAndExit, v as editYamlFile, w as getSpinner, y as readYamlFile } from "./tsconfig-Jia2vgMG.js";
2
- import { a as writeJsonFile, c as parse, i as readJsonFile, n as editJsonFile, o as applyEdits, s as modify, t as detectFormattingOptions } from "./json-DiRs8ceZ.js";
3
- import { t as require_dist } from "./dist-CKz3vcoG.js";
4
- import { r as getScopeFromPackageName } from "./package-Ds3uThLb.js";
5
- import { A as globSync, K as warnMigration, L as rewriteToolLintStagedConfigFiles, U as detectConfigs, V as PRETTIER_CONFIG_FILES, j as minimatch, q as displayRelative } from "./agent-CPwWJ4qf.js";
6
- import path from "node:path";
7
- import { detectWorkspace, rewritePrettier } from "../binding/index.js";
8
- import fs from "node:fs";
9
- import { styleText } from "node:util";
10
- import fsPromises from "node:fs/promises";
11
- //#region src/migration/migrator/prettier.ts
12
- function detectPrettierProject(projectPath, packages) {
13
- const packageJsonPath = path.join(projectPath, "package.json");
14
- if (!fs.existsSync(packageJsonPath)) return { hasDependency: false };
15
- const pkg = readJsonFile(packageJsonPath);
16
- let hasDependency = !!(pkg.devDependencies?.prettier || pkg.dependencies?.prettier);
17
- const configFile = detectConfigs(projectPath).prettierConfig;
18
- if (!hasDependency && packages) for (const wp of packages) {
19
- const pkgJsonPath = path.join(projectPath, wp.path, "package.json");
20
- if (!fs.existsSync(pkgJsonPath)) continue;
21
- const wpPkg = readJsonFile(pkgJsonPath);
22
- if (wpPkg.devDependencies?.prettier || wpPkg.dependencies?.prettier) {
23
- hasDependency = true;
24
- break;
25
- }
26
- }
27
- return {
28
- hasDependency,
29
- configFile
30
- };
31
- }
32
- /**
33
- * Run `vp fmt --migrate=prettier` step with graceful error handling.
34
- * Returns true on success, false on failure.
35
- */
36
- async function runPrettierMigrateStep(vpBin, cwd, spinner, failMessage, manualHint) {
37
- try {
38
- const result = await runCommandSilently({
39
- command: vpBin,
40
- args: ["fmt", "--migrate=prettier"],
41
- cwd,
42
- envs: process.env
43
- });
44
- if (result.exitCode !== 0) {
45
- spinner.stop(failMessage);
46
- const stderr = result.stderr.toString().trim();
47
- if (stderr) log.warn(`⚠ ${stderr}`);
48
- log.info(manualHint);
49
- return false;
50
- }
51
- return true;
52
- } catch {
53
- spinner.stop(failMessage);
54
- log.info(manualHint);
55
- return false;
56
- }
57
- }
58
- async function migratePrettierToOxfmt(projectPath, interactive, prettierConfigFile, packages, options) {
59
- const vpBin = process.env.VP_CLI_BIN ?? "vp";
60
- const spinner = options?.silent ? {
61
- start: () => {},
62
- stop: () => {},
63
- pause: () => {},
64
- resume: () => {},
65
- cancel: () => {},
66
- error: () => {},
67
- clear: () => {},
68
- message: () => {},
69
- isCancelled: false
70
- } : getSpinner(interactive);
71
- if (prettierConfigFile) {
72
- let tempPrettierConfig;
73
- if (prettierConfigFile === "package.json#prettier") {
74
- const pkg = readJsonFile(path.join(projectPath, "package.json"));
75
- if (pkg.prettier) {
76
- tempPrettierConfig = path.join(projectPath, ".prettierrc.json");
77
- fs.writeFileSync(tempPrettierConfig, JSON.stringify(pkg.prettier, null, 2));
78
- } else return true;
79
- }
80
- try {
81
- spinner.start("Migrating Prettier config to Oxfmt...");
82
- if (!await runPrettierMigrateStep(vpBin, projectPath, spinner, "Prettier migration failed", "You can run `vp fmt --migrate=prettier` manually later")) return false;
83
- spinner.stop("Prettier config migrated to .oxfmtrc.json");
84
- } finally {
85
- if (tempPrettierConfig) try {
86
- fs.unlinkSync(tempPrettierConfig);
87
- } catch {}
88
- }
89
- }
90
- if (options?.report) options.report.prettierMigrated = true;
91
- deletePrettierConfigFiles(projectPath, options?.report, options?.silent);
92
- rewritePrettierPackageJson(path.join(projectPath, "package.json"));
93
- if (packages) for (const pkg of packages) rewritePrettierPackageJson(path.join(projectPath, pkg.path, "package.json"));
94
- rewritePrettierLintStagedConfigFiles(projectPath, options?.report);
95
- const prettierIgnorePath = path.join(projectPath, ".prettierignore");
96
- if (fs.existsSync(prettierIgnorePath)) warnMigration(`${displayRelative(prettierIgnorePath)} found — Oxfmt supports .prettierignore, but using the \`ignorePatterns\` option is recommended.`, options?.report);
97
- return true;
98
- }
99
- function deletePrettierConfigFiles(basePath, report, silent = false) {
100
- const configs = detectConfigs(basePath);
101
- if (configs.prettierConfig && configs.prettierConfig !== "package.json#prettier") {
102
- const configPath = path.join(basePath, configs.prettierConfig);
103
- if (fs.existsSync(configPath)) {
104
- fs.unlinkSync(configPath);
105
- if (report) report.removedConfigCount++;
106
- if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
107
- }
108
- }
109
- for (const file of PRETTIER_CONFIG_FILES) {
110
- if (file === configs.prettierConfig) continue;
111
- const configPath = path.join(basePath, file);
112
- if (fs.existsSync(configPath)) {
113
- fs.unlinkSync(configPath);
114
- if (report) report.removedConfigCount++;
115
- if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
116
- }
117
- }
118
- editJsonFile(path.join(basePath, "package.json"), (pkg) => {
119
- if (pkg.prettier) {
120
- delete pkg.prettier;
121
- return pkg;
122
- }
123
- });
124
- }
125
- function rewritePrettierPackageJson(packageJsonPath) {
126
- if (!fs.existsSync(packageJsonPath)) return;
127
- editJsonFile(packageJsonPath, (pkg) => {
128
- let changed = false;
129
- if (pkg.devDependencies) {
130
- for (const dep of Object.keys(pkg.devDependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
131
- delete pkg.devDependencies[dep];
132
- changed = true;
133
- }
134
- }
135
- if (pkg.dependencies) {
136
- for (const dep of Object.keys(pkg.dependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
137
- delete pkg.dependencies[dep];
138
- changed = true;
139
- }
140
- }
141
- if (pkg.scripts) {
142
- const updated = rewritePrettier(JSON.stringify(pkg.scripts));
143
- if (updated) {
144
- pkg.scripts = JSON.parse(updated);
145
- changed = true;
146
- }
147
- }
148
- if (pkg["lint-staged"]) {
149
- const updated = rewritePrettier(JSON.stringify(pkg["lint-staged"]));
150
- if (updated) {
151
- pkg["lint-staged"] = JSON.parse(updated);
152
- changed = true;
153
- }
154
- }
155
- return changed ? pkg : void 0;
156
- });
157
- }
158
- function rewritePrettierLintStagedConfigFiles(projectPath, report) {
159
- rewriteToolLintStagedConfigFiles(projectPath, rewritePrettier, "prettier", report);
160
- }
161
- function warnPackageLevelPrettier() {
162
- log.warn("Prettier detected in workspace packages but no root config found. Package-level Prettier must be migrated manually.");
163
- }
164
- async function confirmPrettierMigration(interactive) {
165
- if (interactive) {
166
- const confirmed = await confirm({
167
- message: "Migrate Prettier to Oxfmt?\n " + styleText("gray", "Oxfmt is Vite+'s built-in formatter that replaces Prettier with faster performance. Your configuration will be converted automatically."),
168
- initialValue: true
169
- });
170
- if (isCancel(confirmed)) cancelAndExit();
171
- return confirmed;
172
- }
173
- log.info("Prettier configuration detected. Auto-migrating to Oxfmt...");
174
- return true;
175
- }
176
- async function promptPrettierMigration(projectPath, interactive, packages) {
177
- const prettierProject = detectPrettierProject(projectPath, packages);
178
- if (!prettierProject.hasDependency) return false;
179
- if (!prettierProject.configFile) {
180
- warnPackageLevelPrettier();
181
- return false;
182
- }
183
- if (!await confirmPrettierMigration(interactive)) return false;
184
- if (!await migratePrettierToOxfmt(projectPath, interactive, prettierProject.configFile, packages)) cancelAndExit("Prettier migration failed.", 1);
185
- return true;
186
- }
187
- //#endregion
188
- //#region src/migration/migrator/framework-shim.ts
189
- const FRAMEWORK_SHIMS = {
190
- vue: [
191
- "declare module '*.vue' {",
192
- " import type { DefineComponent } from 'vue';",
193
- " const component: DefineComponent<{}, {}, unknown>;",
194
- " export default component;",
195
- "}"
196
- ].join("\n"),
197
- astro: "/// <reference types=\"astro/client\" />"
198
- };
199
- function detectFramework(projectPath) {
200
- const packageJsonPath = path.join(projectPath, "package.json");
201
- if (!fs.existsSync(packageJsonPath)) return [];
202
- const pkg = readJsonFile(packageJsonPath);
203
- const allDeps = {
204
- ...pkg.dependencies,
205
- ...pkg.devDependencies
206
- };
207
- return ["vue", "astro"].filter((framework) => !!allDeps[framework]);
208
- }
209
- function getEnvDtsPath(projectPath) {
210
- const srcEnvDts = path.join(projectPath, "src", "env.d.ts");
211
- const rootEnvDts = path.join(projectPath, "env.d.ts");
212
- for (const candidate of [srcEnvDts, rootEnvDts]) if (fs.existsSync(candidate)) return candidate;
213
- return fs.existsSync(path.join(projectPath, "src")) ? srcEnvDts : rootEnvDts;
214
- }
215
- function hasFrameworkShim(projectPath, framework) {
216
- const dirsToScan = [projectPath, path.join(projectPath, "src")];
217
- for (const dir of dirsToScan) {
218
- if (!fs.existsSync(dir)) continue;
219
- let entries;
220
- try {
221
- entries = fs.readdirSync(dir);
222
- } catch {
223
- continue;
224
- }
225
- for (const entry of entries) {
226
- if (!entry.endsWith(".d.ts")) continue;
227
- const content = fs.readFileSync(path.join(dir, entry), "utf-8");
228
- if (framework === "astro") {
229
- if (content.includes("astro/client")) return true;
230
- } else if (content.includes(`'*.${framework}'`) || content.includes(`"*.${framework}"`)) return true;
231
- }
232
- }
233
- return false;
234
- }
235
- function addFrameworkShim(projectPath, framework, report) {
236
- const envDtsPath = getEnvDtsPath(projectPath);
237
- const shim = FRAMEWORK_SHIMS[framework];
238
- if (fs.existsSync(envDtsPath)) {
239
- const existing = fs.readFileSync(envDtsPath, "utf-8");
240
- fs.writeFileSync(envDtsPath, `${existing.trimEnd()}\n\n${shim}\n`, "utf-8");
241
- } else {
242
- fs.mkdirSync(path.dirname(envDtsPath), { recursive: true });
243
- fs.writeFileSync(envDtsPath, `${shim}\n`, "utf-8");
244
- }
245
- if (report) report.frameworkShimAdded = true;
246
- }
247
- //#endregion
248
- //#region src/utils/workspace.ts
249
- var import_dist = require_dist();
250
- async function detectWorkspace$1(rootDir) {
251
- const bindingResult = await detectWorkspace(rootDir);
252
- const result = {
253
- rootDir,
254
- packageManager: void 0,
255
- packageManagerVersion: "latest",
256
- isMonorepo: false,
257
- monorepoScope: "",
258
- workspacePatterns: [],
259
- parentDirs: [],
260
- packages: []
261
- };
262
- if (bindingResult.packageManagerName) result.packageManager = bindingResult.packageManagerName;
263
- if (bindingResult.packageManagerVersion) result.packageManagerVersion = bindingResult.packageManagerVersion;
264
- if (bindingResult.isMonorepo) result.isMonorepo = bindingResult.isMonorepo;
265
- if (bindingResult.root) result.rootDir = bindingResult.root;
266
- if (result.isMonorepo) {
267
- const pnpmWorkspaceFile = path.join(result.rootDir, "pnpm-workspace.yaml");
268
- const packageJsonFile = path.join(result.rootDir, "package.json");
269
- if (fs.existsSync(pnpmWorkspaceFile)) {
270
- const workspaceConfig = readYamlFile(pnpmWorkspaceFile);
271
- if (Array.isArray(workspaceConfig.packages)) result.workspacePatterns = workspaceConfig.packages;
272
- } else if (fs.existsSync(packageJsonFile)) {
273
- const pkg = readJsonFile(packageJsonFile);
274
- if (Array.isArray(pkg.workspaces)) result.workspacePatterns = pkg.workspaces;
275
- else if (pkg.workspaces && Array.isArray(pkg.workspaces.packages)) result.workspacePatterns = pkg.workspaces.packages;
276
- }
277
- const dirs = /* @__PURE__ */ new Set();
278
- for (const pattern of result.workspacePatterns) {
279
- if (!pattern.endsWith("*")) continue;
280
- const dir = pattern.replace(/\/\*{1,2}$/, "");
281
- if (dir) dirs.add(dir);
282
- }
283
- result.parentDirs = Array.from(dirs).sort();
284
- const pkg = readJsonFile(packageJsonFile);
285
- if (pkg.name) result.monorepoScope = getScopeFromPackageName(pkg.name);
286
- result.packages = discoverWorkspacePackages(result.workspacePatterns, result.rootDir);
287
- }
288
- return result;
289
- }
290
- function isBingoTemplate(pkg) {
291
- return !!pkg.dependencies?.bingo;
292
- }
293
- function discoverWorkspacePackages(workspacePatterns, rootDir) {
294
- const packages = [];
295
- if (workspacePatterns.length === 0) return packages;
296
- const packageJsonRelativePaths = globSync(workspacePatterns.map((pattern) => `${pattern}/package.json`), {
297
- absolute: false,
298
- cwd: rootDir,
299
- ignore: ["**/node_modules/**"]
300
- });
301
- for (const packageJsonRelativePath of packageJsonRelativePaths) {
302
- const pkg = readJsonFile(path.join(rootDir, packageJsonRelativePath));
303
- if (!pkg.name) continue;
304
- packages.push({
305
- name: pkg.name,
306
- path: path.dirname(packageJsonRelativePath).split(path.sep).join("/"),
307
- description: pkg.description,
308
- version: pkg.version
309
- });
310
- }
311
- return packages;
312
- }
313
- function updatePackageJsonWithDeps(rootDir, projectDir, dependencies, dependencyType) {
314
- editJsonFile(path.join(rootDir, projectDir, "package.json"), (pkg) => {
315
- if (!pkg[dependencyType]) pkg[dependencyType] = {};
316
- for (const dep of dependencies) pkg[dependencyType][dep] = "workspace:*";
317
- return pkg;
318
- });
319
- }
320
- function updateWorkspaceConfig(projectPath, workspaceInfo) {
321
- for (const pattern of workspaceInfo.workspacePatterns) if (minimatch(projectPath, pattern)) return;
322
- const parentDir = path.dirname(projectPath);
323
- const pattern = parentDir === "." ? projectPath : `${parentDir}/*`;
324
- if (workspaceInfo.packageManager === PackageManager.pnpm) editYamlFile(path.join(workspaceInfo.rootDir, "pnpm-workspace.yaml"), (doc) => {
325
- let packages = doc.getIn(["packages"]);
326
- if (!packages) packages = new import_dist.YAMLSeq();
327
- packages.add(new import_dist.Scalar(pattern));
328
- doc.setIn(["packages"], packages);
329
- });
330
- else editJsonFile(path.join(workspaceInfo.rootDir, "package.json"), (pkg) => {
331
- if (pkg.workspaces && !Array.isArray(pkg.workspaces)) pkg.workspaces.packages = [...pkg.workspaces.packages || [], pattern];
332
- else pkg.workspaces = [...pkg.workspaces || [], pattern];
333
- return pkg;
334
- });
335
- }
336
- const EDITORS = [{
337
- id: "vscode",
338
- label: "VSCode",
339
- targetDir: ".vscode",
340
- files: {
341
- "settings.json": {
342
- "editor.defaultFormatter": "oxc.oxc-vscode",
343
- "[javascript]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
344
- "[javascriptreact]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
345
- "[typescript]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
346
- "[typescriptreact]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
347
- "oxc.fmt.configPath": "./vite.config.ts",
348
- "editor.formatOnSave": true,
349
- "editor.formatOnSaveMode": "file",
350
- "editor.codeActionsOnSave": { "source.fixAll.oxc": "explicit" }
351
- },
352
- "extensions.json": { recommendations: ["VoidZero.vite-plus-extension-pack"] }
353
- }
354
- }, {
355
- id: "zed",
356
- label: "Zed",
357
- targetDir: ".zed",
358
- files: { "settings.json": {
359
- lsp: {
360
- oxlint: { initialization_options: { settings: {
361
- run: "onType",
362
- fixKind: "safe_fix",
363
- typeAware: true,
364
- unusedDisableDirectives: "deny"
365
- } } },
366
- oxfmt: { initialization_options: { settings: {
367
- "fmt.configPath": "./vite.config.ts",
368
- run: "onSave"
369
- } } }
370
- },
371
- languages: {
372
- CSS: {
373
- format_on_save: "on",
374
- prettier: { allowed: false },
375
- formatter: [{ language_server: { name: "oxfmt" } }]
376
- },
377
- GraphQL: {
378
- format_on_save: "on",
379
- prettier: { allowed: false },
380
- formatter: [{ language_server: { name: "oxfmt" } }]
381
- },
382
- Handlebars: {
383
- format_on_save: "on",
384
- prettier: { allowed: false },
385
- formatter: [{ language_server: { name: "oxfmt" } }]
386
- },
387
- HTML: {
388
- format_on_save: "on",
389
- prettier: { allowed: false },
390
- formatter: [{ language_server: { name: "oxfmt" } }]
391
- },
392
- JavaScript: {
393
- format_on_save: "on",
394
- prettier: { allowed: false },
395
- formatter: [{ language_server: { name: "oxfmt" } }],
396
- code_action: "source.fixAll.oxc"
397
- },
398
- JSX: {
399
- format_on_save: "on",
400
- prettier: { allowed: false },
401
- formatter: [{ language_server: { name: "oxfmt" } }]
402
- },
403
- JSON: {
404
- format_on_save: "on",
405
- prettier: { allowed: false },
406
- formatter: [{ language_server: { name: "oxfmt" } }]
407
- },
408
- JSON5: {
409
- format_on_save: "on",
410
- prettier: { allowed: false },
411
- formatter: [{ language_server: { name: "oxfmt" } }]
412
- },
413
- JSONC: {
414
- format_on_save: "on",
415
- prettier: { allowed: false },
416
- formatter: [{ language_server: { name: "oxfmt" } }]
417
- },
418
- Less: {
419
- format_on_save: "on",
420
- prettier: { allowed: false },
421
- formatter: [{ language_server: { name: "oxfmt" } }]
422
- },
423
- Markdown: {
424
- format_on_save: "on",
425
- prettier: { allowed: false },
426
- formatter: [{ language_server: { name: "oxfmt" } }]
427
- },
428
- MDX: {
429
- format_on_save: "on",
430
- prettier: { allowed: false },
431
- formatter: [{ language_server: { name: "oxfmt" } }]
432
- },
433
- SCSS: {
434
- format_on_save: "on",
435
- prettier: { allowed: false },
436
- formatter: [{ language_server: { name: "oxfmt" } }]
437
- },
438
- TypeScript: {
439
- format_on_save: "on",
440
- prettier: { allowed: false },
441
- formatter: [{ language_server: { name: "oxfmt" } }]
442
- },
443
- TSX: {
444
- format_on_save: "on",
445
- prettier: { allowed: false },
446
- formatter: [{ language_server: { name: "oxfmt" } }]
447
- },
448
- "Vue.js": {
449
- format_on_save: "on",
450
- prettier: { allowed: false },
451
- formatter: [{ language_server: { name: "oxfmt" } }]
452
- },
453
- YAML: {
454
- format_on_save: "on",
455
- prettier: { allowed: false },
456
- formatter: [{ language_server: { name: "oxfmt" } }]
457
- }
458
- }
459
- } }
460
- }];
461
- async function selectEditor({ interactive, editor, onCancel }) {
462
- if (editor === false) return;
463
- if (interactive && !editor) {
464
- const editorOptions = EDITORS.map((option) => ({
465
- label: option.label,
466
- value: option.id,
467
- hint: option.targetDir
468
- }));
469
- const otherOption = {
470
- label: "Other",
471
- value: null,
472
- hint: "Skip writing editor configs"
473
- };
474
- const selectedEditor = await select({
475
- message: "Which editor are you using?\n " + styleText("gray", "Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations."),
476
- options: [...editorOptions, otherOption],
477
- initialValue: "vscode"
478
- });
479
- if (isCancel(selectedEditor)) {
480
- onCancel();
481
- return;
482
- }
483
- if (selectedEditor === null) return;
484
- return resolveEditorId(selectedEditor);
485
- }
486
- if (editor) return resolveEditorId(editor);
487
- }
488
- async function selectEditors({ interactive, editor, onCancel }) {
489
- if (editor === false) return;
490
- if (interactive && !editor) {
491
- const selectedEditors = await multiselect({
492
- message: "Which editors are you using?\n " + styleText("gray", "Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations."),
493
- options: EDITORS.map((option) => ({
494
- label: option.label,
495
- value: option.id,
496
- hint: option.targetDir
497
- })),
498
- initialValues: ["vscode"],
499
- required: false
500
- });
501
- if (isCancel(selectedEditors)) {
502
- onCancel();
503
- return;
504
- }
505
- return selectedEditors.length === 0 ? void 0 : resolveEditorIds(selectedEditors);
506
- }
507
- if (editor) {
508
- const editorId = resolveEditorId(editor);
509
- return editorId ? [editorId] : void 0;
510
- }
511
- }
512
- function detectExistingEditors(projectRoot) {
513
- const editors = [];
514
- for (const option of EDITORS) for (const fileName of Object.keys(option.files)) {
515
- const filePath = path.join(projectRoot, option.targetDir, fileName);
516
- if (fs.existsSync(filePath)) {
517
- editors.push(option.id);
518
- break;
519
- }
520
- }
521
- return editors.length === 0 ? void 0 : editors;
522
- }
523
- /**
524
- * Detect editor config files that would conflict (already exist).
525
- * Read-only — does not write or modify any files.
526
- */
527
- function detectEditorConflicts({ projectRoot, editorId }) {
528
- if (!editorId) return [];
529
- const editorConfig = EDITORS.find((e) => e.id === editorId);
530
- if (!editorConfig) return [];
531
- const conflicts = [];
532
- for (const fileName of Object.keys(editorConfig.files)) {
533
- const filePath = path.join(projectRoot, editorConfig.targetDir, fileName);
534
- if (fs.existsSync(filePath)) conflicts.push({
535
- fileName,
536
- displayPath: `${editorConfig.targetDir}/${fileName}`
537
- });
538
- }
539
- return conflicts;
540
- }
541
- async function writeEditorConfigs({ projectRoot, editorId, interactive, conflictDecisions, silent = false, extraVsCodeSettings }) {
542
- const editorIds = normalizeEditorSelection(editorId);
543
- if (editorIds.length === 0) return;
544
- for (const currentEditorId of editorIds) await writeEditorConfig({
545
- projectRoot,
546
- editorId: currentEditorId,
547
- interactive,
548
- conflictDecisions,
549
- silent,
550
- extraVsCodeSettings
551
- });
552
- }
553
- async function writeEditorConfig({ projectRoot, editorId, interactive, conflictDecisions, silent, extraVsCodeSettings }) {
554
- const editorConfig = EDITORS.find((e) => e.id === editorId);
555
- if (!editorConfig) return;
556
- const targetDir = path.join(projectRoot, editorConfig.targetDir);
557
- await fsPromises.mkdir(targetDir, { recursive: true });
558
- for (const [fileName, baseIncoming] of Object.entries(editorConfig.files)) {
559
- const incoming = editorId === "vscode" && fileName === "settings.json" && extraVsCodeSettings ? {
560
- ...extraVsCodeSettings,
561
- ...baseIncoming
562
- } : baseIncoming;
563
- const filePath = path.join(targetDir, fileName);
564
- if (fs.existsSync(filePath)) {
565
- const displayPath = `${editorConfig.targetDir}/${fileName}`;
566
- let conflictAction;
567
- const preResolved = conflictDecisions?.get(displayPath) ?? conflictDecisions?.get(fileName);
568
- if (preResolved) conflictAction = preResolved;
569
- else if (interactive) {
570
- const action = await select({
571
- message: `${displayPath} already exists.\n ` + styleText("gray", `Vite+ adds ${editorConfig.label} settings for the built-in linter and formatter. Merge adds new keys without overwriting existing ones.`),
572
- options: [{
573
- label: "Merge",
574
- value: "merge",
575
- hint: "Merge new settings into existing file"
576
- }, {
577
- label: "Skip",
578
- value: "skip",
579
- hint: "Leave existing file unchanged"
580
- }],
581
- initialValue: "skip"
582
- });
583
- conflictAction = isCancel(action) || action === "skip" ? "skip" : "merge";
584
- } else conflictAction = "merge";
585
- if (conflictAction === "merge") mergeAndWriteEditorConfig(filePath, incoming, fileName, displayPath, silent);
586
- else if (!silent) log.info(`Skipped writing ${displayPath}`);
587
- continue;
588
- }
589
- writeJsonFile(filePath, incoming);
590
- if (!silent) log.success(`Wrote editor config to ${editorConfig.targetDir}/${fileName}`);
591
- }
592
- }
593
- function normalizeEditorSelection(editorId) {
594
- if (!editorId) return [];
595
- return [...new Set(Array.isArray(editorId) ? editorId : [editorId])];
596
- }
597
- /**
598
- * Merge incoming settings into an existing editor JSON/JSONC file by patching the
599
- * original text with `jsonc-parser` instead of re-serializing a merged object.
600
- * This preserves comments, key order, trailing commas, and untouched formatting.
601
- * Existing values always win; only missing keys/branches are inserted.
602
- */
603
- function mergeAndWriteEditorConfig(filePath, incoming, fileName, displayPath, silent = false) {
604
- const originalText = fs.readFileSync(filePath, "utf-8");
605
- const existing = parse(originalText);
606
- if (!isPlainObject(existing)) throw new Error(`Cannot merge editor config: ${displayPath} is not a JSON object`);
607
- const formattingOptions = detectFormattingOptions(originalText);
608
- const newText = fileName === "extensions.json" ? mergeExtensionsText(originalText, existing, incoming, formattingOptions) : mergeSettingsText(originalText, existing, incoming, formattingOptions);
609
- if (newText === originalText) {
610
- if (!silent) log.info(`No changes needed for ${displayPath}`);
611
- return;
612
- }
613
- fs.writeFileSync(filePath, newText, "utf-8");
614
- if (!silent) log.success(`Merged editor config into ${displayPath}`);
615
- }
616
- function isPlainObject(value) {
617
- return typeof value === "object" && value !== null && !Array.isArray(value);
618
- }
619
- /** Apply a single `jsonc-parser` modification to `text` and return the patched text. */
620
- function applyJsoncEdit(text, path, value, options) {
621
- return applyEdits(text, modify(text, path, value, options));
622
- }
623
- /**
624
- * Deep-merge missing keys from `incoming` into the existing text. Inserts a whole
625
- * branch when it is absent, and recurses only when both sides are non-array objects
626
- * so comments inside existing branches are preserved.
627
- */
628
- function mergeSettingsText(text, existing, incoming, formattingOptions) {
629
- let currentText = text;
630
- const insertMissing = (existingNode, incomingNode, basePath) => {
631
- for (const [key, value] of Object.entries(incomingNode)) {
632
- const fullPath = [...basePath, key];
633
- if (!(key in existingNode)) currentText = applyJsoncEdit(currentText, fullPath, value, { formattingOptions });
634
- else if (isPlainObject(existingNode[key]) && isPlainObject(value)) insertMissing(existingNode[key], value, fullPath);
635
- }
636
- };
637
- insertMissing(existing, incoming, []);
638
- return currentText;
639
- }
640
- /**
641
- * For `extensions.json`, append missing recommendations without rebuilding the array,
642
- * so comments inside the array survive. Existing entries always win.
643
- */
644
- function mergeExtensionsText(text, existing, incoming, formattingOptions) {
645
- const incomingRecs = Array.isArray(incoming["recommendations"]) ? incoming["recommendations"] : [];
646
- const existingValue = existing["recommendations"];
647
- if (!("recommendations" in existing)) return applyJsoncEdit(text, ["recommendations"], incomingRecs, { formattingOptions });
648
- if (!Array.isArray(existingValue)) return text;
649
- const existingRecs = new Set(existingValue);
650
- let currentText = text;
651
- let nextIndex = existingValue.length;
652
- for (const rec of incomingRecs) {
653
- if (existingRecs.has(rec)) continue;
654
- currentText = applyJsoncEdit(currentText, ["recommendations", nextIndex], rec, {
655
- formattingOptions,
656
- isArrayInsertion: true
657
- });
658
- nextIndex++;
659
- }
660
- return currentText;
661
- }
662
- function resolveEditorId(editor) {
663
- const normalized = editor.trim().toLowerCase();
664
- return EDITORS.find((option) => option.id === normalized || option.label.toLowerCase() === normalized)?.id;
665
- }
666
- function resolveEditorIds(editors) {
667
- const editorIds = editors.flatMap((editor) => {
668
- const editorId = resolveEditorId(editor);
669
- return editorId ? [editorId] : [];
670
- });
671
- const uniqueEditorIds = [...new Set(editorIds)];
672
- return uniqueEditorIds.length === 0 ? void 0 : uniqueEditorIds;
673
- }
674
- //#endregion
675
- export { warnPackageLevelPrettier as _, writeEditorConfigs as a, updatePackageJsonWithDeps as c, detectFramework as d, hasFrameworkShim as f, promptPrettierMigration as g, migratePrettierToOxfmt as h, selectEditors as i, updateWorkspaceConfig as l, detectPrettierProject as m, detectExistingEditors as n, detectWorkspace$1 as o, confirmPrettierMigration as p, selectEditor as r, isBingoTemplate as s, detectEditorConflicts as t, addFrameworkShim as u };