vite-plus 0.1.22 → 0.1.23

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/binding/index.cjs +119 -52
  2. package/binding/index.d.cts +3222 -2
  3. package/dist/agent-aSGY0osq.js +2461 -0
  4. package/dist/bin.js +6 -5
  5. package/dist/cli-truncate-CWsmbK3p.js +867 -0
  6. package/dist/{compat-OlmU9EQz.js → compat-DXZgnEyq.js} +1 -1
  7. package/dist/config/bin.js +18 -5
  8. package/dist/{constants-kDaYqyWd.js → constants-DCBWlNrn.js} +7 -2
  9. package/dist/create/bin.js +135 -64
  10. package/dist/{define-config-IMCGDS2K.d.ts → define-config-COdn-tsn.d.ts} +7 -5
  11. package/dist/define-config.cjs +1 -1
  12. package/dist/define-config.d.ts +1 -1
  13. package/dist/define-config.js +1 -1
  14. package/dist/dist-Bapm49IR.js +3 -0
  15. package/dist/{dist-owlRxmBM.js → dist-BgQuvbtq.js} +136 -110
  16. package/dist/fmt.d.ts +1 -1
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/is-fullwidth-code-point-BUNlIICg.js +8 -0
  21. package/dist/lint.d.ts +1 -1
  22. package/dist/{log-update-NRrY6krx.js → log-update-lyIiuflf.js} +111 -24
  23. package/dist/migration/bin.js +71 -30
  24. package/dist/{oxlint-plugin-config-BkQeR4FR.js → oxlint-plugin-config-B89iKTKN.js} +1 -1
  25. package/dist/oxlint-plugin.d.ts +2 -4
  26. package/dist/oxlint-plugin.js +1 -1
  27. package/dist/pack-bin.js +1 -1
  28. package/dist/pack.d.ts +1 -1
  29. package/dist/{package-BoLLED6j.js → package-PmBUZ-ve.js} +2 -2
  30. package/dist/staged/bin.js +10 -10
  31. package/dist/strip-ansi-C3wrWz9t.js +853 -0
  32. package/dist/{agent-BWLe0i9g.js → tsconfig-DlUVXT3J.js} +648 -2089
  33. package/dist/version.js +5 -5
  34. package/dist/versions.js +6 -6
  35. package/dist/{workspace-Bi_9spVt.js → workspace-DElv730L.js} +13 -12
  36. package/dist/wrap-ansi-CeQuiQ31.js +2 -0
  37. package/dist/{wrap-ansi-DtUeUCjE.js → wrap-ansi-k7Dn4VtV.js} +1 -1
  38. package/docs/config/run.md +39 -4
  39. package/docs/guide/cache.md +10 -1
  40. package/docs/guide/env.md +3 -0
  41. package/docs/guide/ide-integration.md +2 -2
  42. package/docs/guide/install.md +2 -0
  43. package/docs/guide/run.md +2 -0
  44. package/docs/guide/troubleshooting.md +5 -2
  45. package/package.json +18 -18
  46. package/templates/monorepo/_gitignore +1 -0
  47. package/dist/cli-truncate-B62YnW2m.js +0 -138
  48. package/dist/dist-DZfItHAr.js +0 -3
  49. package/dist/slice-ansi-e4todZeH.js +0 -113
  50. package/dist/strip-ansi-D-eYYcD2.js +0 -198
  51. package/dist/tsconfig-BVyzXJ_o.js +0 -517
  52. package/dist/wrap-ansi-3S3qJ7j8.js +0 -2
  53. /package/dist/{chunk-q7NCDQ7-.js → chunk-DnnnRqeS.js} +0 -0
  54. /package/dist/{define-config-GqLoRwH9.cjs → define-config-BR1Y88zz.cjs} +0 -0
  55. /package/dist/{define-config-CzWdQTt2.js → define-config-BRC7qPNE.js} +0 -0
  56. /package/dist/{help-DK5wuu34.js → help-YP84FSEz.js} +0 -0
  57. /package/dist/{lib-DpwyUJWo.js → lib-L3DWSRQp.js} +0 -0
  58. /package/dist/{main-DhsO6ndq.js → main-DpJl3LoU.js} +0 -0
  59. /package/dist/{pack-K7H72Cum.d.ts → pack-Ciiho0Tq.d.ts} +0 -0
  60. /package/dist/{report-CYPv1VK1.js → report-DgSBQUdz.js} +0 -0
  61. /package/dist/{resolve-vite-config-C5AjksTj.js → resolve-vite-config-TTvhycU1.js} +0 -0
  62. /package/dist/{terminal-D_Kg-AA6.js → terminal-uTv0ZaMr.js} +0 -0
@@ -1,20 +1,460 @@
1
- import { r as __toESM, t as __commonJSMin } from "./chunk-q7NCDQ7-.js";
2
- import { a as VITE_PLUS_VERSION, i as VITE_PLUS_OVERRIDE_PACKAGES, o as isForceOverrideMode, r as VITE_PLUS_NAME, t as BASEURL_TSCONFIG_WARNING } from "./constants-kDaYqyWd.js";
3
- import { i as ensureVitePlusImportRuleDefaults, r as createDefaultVitePlusLintConfig } from "./oxlint-plugin-config-BkQeR4FR.js";
4
- import { i as rewriteTypesInTsconfig, n as hasBaseUrlInTsconfig, o as runCommandSilently, r as removeDeprecatedTsconfigFalseOption, s as require_cross_spawn, t as findTsconfigFiles } from "./tsconfig-BVyzXJ_o.js";
5
- import { t as accent } from "./terminal-D_Kg-AA6.js";
6
- import { t as require_dist } from "./dist-owlRxmBM.js";
7
- import { c as editJsonFile, l as isJsonFile, n as detectPackageMetadata, u as readJsonFile } from "./package-BoLLED6j.js";
8
- import { n as addMigrationWarning, t as addManualStep } from "./report-CYPv1VK1.js";
1
+ import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-DnnnRqeS.js";
2
+ import { s as createBaseUrlTsconfigFixArgs, t as BASEURL_TSCONFIG_FIX_PACKAGE } from "./constants-DCBWlNrn.js";
3
+ import { t as accent } from "./terminal-uTv0ZaMr.js";
4
+ import { n as modify, r as parse, t as applyEdits } from "./main-DpJl3LoU.js";
9
5
  import path from "node:path";
10
- import { downloadPackageManager, hasConfigKey, mergeJsonConfig, mergeTsdownConfig, rewriteEslint, rewriteImportsInDirectory, rewritePrettier, rewriteScripts } from "../binding/index.js";
6
+ import { downloadPackageManager } from "../binding/index.js";
11
7
  import fs from "node:fs";
12
8
  import { styleText } from "node:util";
13
9
  import process$1, { stdin, stdout } from "node:process";
14
10
  import * as b from "node:readline";
15
11
  import E from "node:readline";
16
12
  import { ReadStream } from "node:tty";
17
- import fsPromises from "node:fs/promises";
13
+ //#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js
14
+ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15
+ module.exports = isexe;
16
+ isexe.sync = sync;
17
+ var fs$3 = __require("fs");
18
+ function checkPathExt(path, options) {
19
+ var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
20
+ if (!pathext) return true;
21
+ pathext = pathext.split(";");
22
+ if (pathext.indexOf("") !== -1) return true;
23
+ for (var i = 0; i < pathext.length; i++) {
24
+ var p = pathext[i].toLowerCase();
25
+ if (p && path.substr(-p.length).toLowerCase() === p) return true;
26
+ }
27
+ return false;
28
+ }
29
+ function checkStat(stat, path, options) {
30
+ if (!stat.isSymbolicLink() && !stat.isFile()) return false;
31
+ return checkPathExt(path, options);
32
+ }
33
+ function isexe(path, options, cb) {
34
+ fs$3.stat(path, function(er, stat) {
35
+ cb(er, er ? false : checkStat(stat, path, options));
36
+ });
37
+ }
38
+ function sync(path, options) {
39
+ return checkStat(fs$3.statSync(path), path, options);
40
+ }
41
+ }));
42
+ //#endregion
43
+ //#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js
44
+ var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
45
+ module.exports = isexe;
46
+ isexe.sync = sync;
47
+ var fs$2 = __require("fs");
48
+ function isexe(path, options, cb) {
49
+ fs$2.stat(path, function(er, stat) {
50
+ cb(er, er ? false : checkStat(stat, options));
51
+ });
52
+ }
53
+ function sync(path, options) {
54
+ return checkStat(fs$2.statSync(path), options);
55
+ }
56
+ function checkStat(stat, options) {
57
+ return stat.isFile() && checkMode(stat, options);
58
+ }
59
+ function checkMode(stat, options) {
60
+ var mod = stat.mode;
61
+ var uid = stat.uid;
62
+ var gid = stat.gid;
63
+ var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
64
+ var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
65
+ var u = parseInt("100", 8);
66
+ var g = parseInt("010", 8);
67
+ var o = parseInt("001", 8);
68
+ var ug = u | g;
69
+ return mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
70
+ }
71
+ }));
72
+ //#endregion
73
+ //#region ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
74
+ var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
75
+ __require("fs");
76
+ var core;
77
+ if (process.platform === "win32" || global.TESTING_WINDOWS) core = require_windows();
78
+ else core = require_mode();
79
+ module.exports = isexe;
80
+ isexe.sync = sync;
81
+ function isexe(path, options, cb) {
82
+ if (typeof options === "function") {
83
+ cb = options;
84
+ options = {};
85
+ }
86
+ if (!cb) {
87
+ if (typeof Promise !== "function") throw new TypeError("callback not provided");
88
+ return new Promise(function(resolve, reject) {
89
+ isexe(path, options || {}, function(er, is) {
90
+ if (er) reject(er);
91
+ else resolve(is);
92
+ });
93
+ });
94
+ }
95
+ core(path, options || {}, function(er, is) {
96
+ if (er) {
97
+ if (er.code === "EACCES" || options && options.ignoreErrors) {
98
+ er = null;
99
+ is = false;
100
+ }
101
+ }
102
+ cb(er, is);
103
+ });
104
+ }
105
+ function sync(path, options) {
106
+ try {
107
+ return core.sync(path, options || {});
108
+ } catch (er) {
109
+ if (options && options.ignoreErrors || er.code === "EACCES") return false;
110
+ else throw er;
111
+ }
112
+ }
113
+ }));
114
+ //#endregion
115
+ //#region ../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
116
+ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
117
+ const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
118
+ const path$3 = __require("path");
119
+ const COLON = isWindows ? ";" : ":";
120
+ const isexe = require_isexe();
121
+ const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
122
+ const getPathInfo = (cmd, opt) => {
123
+ const colon = opt.colon || COLON;
124
+ const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [...isWindows ? [process.cwd()] : [], ...(opt.path || process.env.PATH || "").split(colon)];
125
+ const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
126
+ const pathExt = isWindows ? pathExtExe.split(colon) : [""];
127
+ if (isWindows) {
128
+ if (cmd.indexOf(".") !== -1 && pathExt[0] !== "") pathExt.unshift("");
129
+ }
130
+ return {
131
+ pathEnv,
132
+ pathExt,
133
+ pathExtExe
134
+ };
135
+ };
136
+ const which = (cmd, opt, cb) => {
137
+ if (typeof opt === "function") {
138
+ cb = opt;
139
+ opt = {};
140
+ }
141
+ if (!opt) opt = {};
142
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
143
+ const found = [];
144
+ const step = (i) => new Promise((resolve, reject) => {
145
+ if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
146
+ const ppRaw = pathEnv[i];
147
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
148
+ const pCmd = path$3.join(pathPart, cmd);
149
+ resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
150
+ });
151
+ const subStep = (p, i, ii) => new Promise((resolve, reject) => {
152
+ if (ii === pathExt.length) return resolve(step(i + 1));
153
+ const ext = pathExt[ii];
154
+ isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
155
+ if (!er && is) if (opt.all) found.push(p + ext);
156
+ else return resolve(p + ext);
157
+ return resolve(subStep(p, i, ii + 1));
158
+ });
159
+ });
160
+ return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
161
+ };
162
+ const whichSync = (cmd, opt) => {
163
+ opt = opt || {};
164
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
165
+ const found = [];
166
+ for (let i = 0; i < pathEnv.length; i++) {
167
+ const ppRaw = pathEnv[i];
168
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
169
+ const pCmd = path$3.join(pathPart, cmd);
170
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
171
+ for (let j = 0; j < pathExt.length; j++) {
172
+ const cur = p + pathExt[j];
173
+ try {
174
+ if (isexe.sync(cur, { pathExt: pathExtExe })) if (opt.all) found.push(cur);
175
+ else return cur;
176
+ } catch (ex) {}
177
+ }
178
+ }
179
+ if (opt.all && found.length) return found;
180
+ if (opt.nothrow) return null;
181
+ throw getNotFoundError(cmd);
182
+ };
183
+ module.exports = which;
184
+ which.sync = whichSync;
185
+ }));
186
+ //#endregion
187
+ //#region ../../node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js
188
+ var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
189
+ const pathKey = (options = {}) => {
190
+ const environment = options.env || process.env;
191
+ if ((options.platform || process.platform) !== "win32") return "PATH";
192
+ return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
193
+ };
194
+ module.exports = pathKey;
195
+ module.exports.default = pathKey;
196
+ }));
197
+ //#endregion
198
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
199
+ var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
200
+ const path$2 = __require("path");
201
+ const which = require_which();
202
+ const getPathKey = require_path_key();
203
+ function resolveCommandAttempt(parsed, withoutPathExt) {
204
+ const env = parsed.options.env || process.env;
205
+ const cwd = process.cwd();
206
+ const hasCustomCwd = parsed.options.cwd != null;
207
+ const shouldSwitchCwd = hasCustomCwd && process.chdir !== void 0 && !process.chdir.disabled;
208
+ if (shouldSwitchCwd) try {
209
+ process.chdir(parsed.options.cwd);
210
+ } catch (err) {}
211
+ let resolved;
212
+ try {
213
+ resolved = which.sync(parsed.command, {
214
+ path: env[getPathKey({ env })],
215
+ pathExt: withoutPathExt ? path$2.delimiter : void 0
216
+ });
217
+ } catch (e) {} finally {
218
+ if (shouldSwitchCwd) process.chdir(cwd);
219
+ }
220
+ if (resolved) resolved = path$2.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
221
+ return resolved;
222
+ }
223
+ function resolveCommand(parsed) {
224
+ return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
225
+ }
226
+ module.exports = resolveCommand;
227
+ }));
228
+ //#endregion
229
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
230
+ var require_escape = /* @__PURE__ */ __commonJSMin(((exports, module) => {
231
+ const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
232
+ function escapeCommand(arg) {
233
+ arg = arg.replace(metaCharsRegExp, "^$1");
234
+ return arg;
235
+ }
236
+ function escapeArgument(arg, doubleEscapeMetaChars) {
237
+ arg = `${arg}`;
238
+ arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
239
+ arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
240
+ arg = `"${arg}"`;
241
+ arg = arg.replace(metaCharsRegExp, "^$1");
242
+ if (doubleEscapeMetaChars) arg = arg.replace(metaCharsRegExp, "^$1");
243
+ return arg;
244
+ }
245
+ module.exports.command = escapeCommand;
246
+ module.exports.argument = escapeArgument;
247
+ }));
248
+ //#endregion
249
+ //#region ../../node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
250
+ var require_shebang_regex = /* @__PURE__ */ __commonJSMin(((exports, module) => {
251
+ module.exports = /^#!(.*)/;
252
+ }));
253
+ //#endregion
254
+ //#region ../../node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js
255
+ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) => {
256
+ const shebangRegex = require_shebang_regex();
257
+ module.exports = (string = "") => {
258
+ const match = string.match(shebangRegex);
259
+ if (!match) return null;
260
+ const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
261
+ const binary = path.split("/").pop();
262
+ if (binary === "env") return argument;
263
+ return argument ? `${binary} ${argument}` : binary;
264
+ };
265
+ }));
266
+ //#endregion
267
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
268
+ var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
269
+ const fs$1 = __require("fs");
270
+ const shebangCommand = require_shebang_command();
271
+ function readShebang(command) {
272
+ const size = 150;
273
+ const buffer = Buffer.alloc(size);
274
+ let fd;
275
+ try {
276
+ fd = fs$1.openSync(command, "r");
277
+ fs$1.readSync(fd, buffer, 0, size, 0);
278
+ fs$1.closeSync(fd);
279
+ } catch (e) {}
280
+ return shebangCommand(buffer.toString());
281
+ }
282
+ module.exports = readShebang;
283
+ }));
284
+ //#endregion
285
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
286
+ var require_parse$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
287
+ const path$1 = __require("path");
288
+ const resolveCommand = require_resolveCommand();
289
+ const escape = require_escape();
290
+ const readShebang = require_readShebang();
291
+ const isWin = process.platform === "win32";
292
+ const isExecutableRegExp = /\.(?:com|exe)$/i;
293
+ const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
294
+ function detectShebang(parsed) {
295
+ parsed.file = resolveCommand(parsed);
296
+ const shebang = parsed.file && readShebang(parsed.file);
297
+ if (shebang) {
298
+ parsed.args.unshift(parsed.file);
299
+ parsed.command = shebang;
300
+ return resolveCommand(parsed);
301
+ }
302
+ return parsed.file;
303
+ }
304
+ function parseNonShell(parsed) {
305
+ if (!isWin) return parsed;
306
+ const commandFile = detectShebang(parsed);
307
+ const needsShell = !isExecutableRegExp.test(commandFile);
308
+ if (parsed.options.forceShell || needsShell) {
309
+ const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
310
+ parsed.command = path$1.normalize(parsed.command);
311
+ parsed.command = escape.command(parsed.command);
312
+ parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
313
+ parsed.args = [
314
+ "/d",
315
+ "/s",
316
+ "/c",
317
+ `"${[parsed.command].concat(parsed.args).join(" ")}"`
318
+ ];
319
+ parsed.command = process.env.comspec || "cmd.exe";
320
+ parsed.options.windowsVerbatimArguments = true;
321
+ }
322
+ return parsed;
323
+ }
324
+ function parse(command, args, options) {
325
+ if (args && !Array.isArray(args)) {
326
+ options = args;
327
+ args = null;
328
+ }
329
+ args = args ? args.slice(0) : [];
330
+ options = Object.assign({}, options);
331
+ const parsed = {
332
+ command,
333
+ args,
334
+ options,
335
+ file: void 0,
336
+ original: {
337
+ command,
338
+ args
339
+ }
340
+ };
341
+ return options.shell ? parsed : parseNonShell(parsed);
342
+ }
343
+ module.exports = parse;
344
+ }));
345
+ //#endregion
346
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
347
+ var require_enoent = /* @__PURE__ */ __commonJSMin(((exports, module) => {
348
+ const isWin = process.platform === "win32";
349
+ function notFoundError(original, syscall) {
350
+ return Object.assign(/* @__PURE__ */ new Error(`${syscall} ${original.command} ENOENT`), {
351
+ code: "ENOENT",
352
+ errno: "ENOENT",
353
+ syscall: `${syscall} ${original.command}`,
354
+ path: original.command,
355
+ spawnargs: original.args
356
+ });
357
+ }
358
+ function hookChildProcess(cp, parsed) {
359
+ if (!isWin) return;
360
+ const originalEmit = cp.emit;
361
+ cp.emit = function(name, arg1) {
362
+ if (name === "exit") {
363
+ const err = verifyENOENT(arg1, parsed);
364
+ if (err) return originalEmit.call(cp, "error", err);
365
+ }
366
+ return originalEmit.apply(cp, arguments);
367
+ };
368
+ }
369
+ function verifyENOENT(status, parsed) {
370
+ if (isWin && status === 1 && !parsed.file) return notFoundError(parsed.original, "spawn");
371
+ return null;
372
+ }
373
+ function verifyENOENTSync(status, parsed) {
374
+ if (isWin && status === 1 && !parsed.file) return notFoundError(parsed.original, "spawnSync");
375
+ return null;
376
+ }
377
+ module.exports = {
378
+ hookChildProcess,
379
+ verifyENOENT,
380
+ verifyENOENTSync,
381
+ notFoundError
382
+ };
383
+ }));
384
+ //#endregion
385
+ //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
386
+ var require_cross_spawn = /* @__PURE__ */ __commonJSMin(((exports, module) => {
387
+ const cp = __require("child_process");
388
+ const parse = require_parse$1();
389
+ const enoent = require_enoent();
390
+ function spawn(command, args, options) {
391
+ const parsed = parse(command, args, options);
392
+ const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
393
+ enoent.hookChildProcess(spawned, parsed);
394
+ return spawned;
395
+ }
396
+ function spawnSync(command, args, options) {
397
+ const parsed = parse(command, args, options);
398
+ const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
399
+ result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
400
+ return result;
401
+ }
402
+ module.exports = spawn;
403
+ module.exports.spawn = spawn;
404
+ module.exports.sync = spawnSync;
405
+ module.exports._parse = parse;
406
+ module.exports._enoent = enoent;
407
+ }));
408
+ //#endregion
409
+ //#region src/utils/command.ts
410
+ var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
411
+ async function runCommandSilently(options) {
412
+ const child = (0, import_cross_spawn.default)(options.command, options.args, {
413
+ stdio: [
414
+ "ignore",
415
+ "pipe",
416
+ "pipe"
417
+ ],
418
+ cwd: options.cwd,
419
+ env: options.envs
420
+ });
421
+ return await new Promise((resolve, reject) => {
422
+ const stdout = [];
423
+ const stderr = [];
424
+ child.stdout?.on("data", (data) => {
425
+ stdout.push(data);
426
+ });
427
+ child.stderr?.on("data", (data) => {
428
+ stderr.push(data);
429
+ });
430
+ child.on("close", (code) => {
431
+ resolve({
432
+ exitCode: code ?? 0,
433
+ stdout: Buffer.concat(stdout),
434
+ stderr: Buffer.concat(stderr)
435
+ });
436
+ });
437
+ child.on("error", (err) => {
438
+ reject(err);
439
+ });
440
+ });
441
+ }
442
+ async function runCommand$1(options) {
443
+ const child = (0, import_cross_spawn.default)(options.command, options.args, {
444
+ stdio: "inherit",
445
+ cwd: options.cwd,
446
+ env: options.envs
447
+ });
448
+ return new Promise((resolve, reject) => {
449
+ child.on("close", (code) => {
450
+ resolve({ exitCode: code ?? 0 });
451
+ });
452
+ child.on("error", (err) => {
453
+ reject(err);
454
+ });
455
+ });
456
+ }
457
+ //#endregion
18
458
  //#region ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
19
459
  const getCodePointsLength = (() => {
20
460
  const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
@@ -297,7 +737,7 @@ function wrapAnsi$1(string, columns, options) {
297
737
  return String(string).normalize().split(CRLF_OR_LF$1).map((line) => exec$1(line, columns, options)).join("\n");
298
738
  }
299
739
  //#endregion
300
- //#region ../../node_modules/.pnpm/@clack+core@1.3.0/node_modules/@clack/core/dist/index.mjs
740
+ //#region ../../node_modules/.pnpm/@clack+core@1.3.1/node_modules/@clack/core/dist/index.mjs
301
741
  var import_src = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
302
742
  const ESC = "\x1B";
303
743
  const CSI = `${ESC}[`;
@@ -350,10 +790,10 @@ var import_src = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
350
790
  beep
351
791
  };
352
792
  })))();
353
- function d(r, t, s) {
793
+ function f(r, t, s) {
354
794
  if (!s.some((o) => !o.disabled)) return r;
355
795
  const e = r + t, i = Math.max(s.length - 1, 0), n = e < 0 ? i : e > i ? 0 : e;
356
- return s[n].disabled ? d(n, t < 0 ? -1 : 1, s) : n;
796
+ return s[n].disabled ? f(n, t < 0 ? -1 : 1, s) : n;
357
797
  }
358
798
  const h = {
359
799
  actions: new Set([
@@ -446,8 +886,8 @@ function R({ input: r = stdin, output: t = stdout, overwrite: s = !0, hideCursor
446
886
  return;
447
887
  }
448
888
  if (!s) return;
449
- const f = u === "return" ? 0 : -1, y = u === "return" ? -1 : 0;
450
- b.moveCursor(t, f, y, () => {
889
+ const c = u === "return" ? 0 : -1, y = u === "return" ? -1 : 0;
890
+ b.moveCursor(t, c, y, () => {
451
891
  b.clearLine(t, 1, () => {
452
892
  r.once("keypress", n);
453
893
  });
@@ -458,18 +898,18 @@ function R({ input: r = stdin, output: t = stdout, overwrite: s = !0, hideCursor
458
898
  };
459
899
  }
460
900
  const A = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80, L = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
461
- function W(r, t, s, e = s, i) {
901
+ function W(r, t, s, e = s, i = s, n) {
462
902
  return wrapAnsi$1(t, A(r ?? stdout) - s.length, {
463
903
  hard: !0,
464
904
  trim: !1
465
905
  }).split(`
466
- `).map((o, u) => {
467
- const a = i ? i(o, u) : o;
468
- return `${u === 0 ? e : s}${a}`;
906
+ `).map((u, a, l) => {
907
+ const c = n ? n(u, a) : u;
908
+ return a === 0 ? `${e}${c}` : a === l.length - 1 ? `${i}${c}` : `${s}${c}`;
469
909
  }).join(`
470
910
  `);
471
911
  }
472
- let p = class {
912
+ let m = class {
473
913
  input;
474
914
  output;
475
915
  _abortSignal;
@@ -619,7 +1059,7 @@ let p = class {
619
1059
  }
620
1060
  }
621
1061
  };
622
- var X = class extends p {
1062
+ var X = class extends m {
623
1063
  get cursor() {
624
1064
  return this.value ? 0 : 1;
625
1065
  }
@@ -636,7 +1076,7 @@ var X = class extends p {
636
1076
  });
637
1077
  }
638
1078
  };
639
- let nt = class extends p {
1079
+ let nt = class extends m {
640
1080
  options;
641
1081
  cursor = 0;
642
1082
  get _value() {
@@ -663,17 +1103,17 @@ let nt = class extends p {
663
1103
  constructor(t) {
664
1104
  super(t, !1), this.options = t.options, this.value = [...t.initialValues ?? []];
665
1105
  const s = Math.max(this.options.findIndex(({ value: e }) => e === t.cursorAt), 0);
666
- this.cursor = this.options[s].disabled ? d(s, 1, this.options) : s, this.on("key", (e) => {
1106
+ this.cursor = this.options[s].disabled ? f(s, 1, this.options) : s, this.on("key", (e) => {
667
1107
  e === "a" && this.toggleAll(), e === "i" && this.toggleInvert();
668
1108
  }), this.on("cursor", (e) => {
669
1109
  switch (e) {
670
1110
  case "left":
671
1111
  case "up":
672
- this.cursor = d(this.cursor, -1, this.options);
1112
+ this.cursor = f(this.cursor, -1, this.options);
673
1113
  break;
674
1114
  case "down":
675
1115
  case "right":
676
- this.cursor = d(this.cursor, 1, this.options);
1116
+ this.cursor = f(this.cursor, 1, this.options);
677
1117
  break;
678
1118
  case "space":
679
1119
  this.toggleValue();
@@ -682,7 +1122,7 @@ let nt = class extends p {
682
1122
  });
683
1123
  }
684
1124
  };
685
- var ut = class extends p {
1125
+ var ut = class extends m {
686
1126
  options;
687
1127
  cursor = 0;
688
1128
  get _selectedValue() {
@@ -694,22 +1134,22 @@ var ut = class extends p {
694
1134
  constructor(t) {
695
1135
  super(t, !1), this.options = t.options;
696
1136
  const s = this.options.findIndex(({ value: i }) => i === t.initialValue), e = s === -1 ? 0 : s;
697
- this.cursor = this.options[e].disabled ? d(e, 1, this.options) : e, this.changeValue(), this.on("cursor", (i) => {
1137
+ this.cursor = this.options[e].disabled ? f(e, 1, this.options) : e, this.changeValue(), this.on("cursor", (i) => {
698
1138
  switch (i) {
699
1139
  case "left":
700
1140
  case "up":
701
- this.cursor = d(this.cursor, -1, this.options);
1141
+ this.cursor = f(this.cursor, -1, this.options);
702
1142
  break;
703
1143
  case "down":
704
1144
  case "right":
705
- this.cursor = d(this.cursor, 1, this.options);
1145
+ this.cursor = f(this.cursor, 1, this.options);
706
1146
  break;
707
1147
  }
708
1148
  this.changeValue();
709
1149
  });
710
1150
  }
711
1151
  };
712
- var ht = class extends p {
1152
+ var ht = class extends m {
713
1153
  get userInputWithCursor() {
714
1154
  if (this.state === "submit") return this.userInput;
715
1155
  const t = this.userInput;
@@ -1673,7 +2113,7 @@ const text = (opts) => {
1673
2113
  }).prompt();
1674
2114
  };
1675
2115
  //#endregion
1676
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/constants.js
2116
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/constants.js
1677
2117
  var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1678
2118
  const SEMVER_SPEC_VERSION = "2.0.0";
1679
2119
  const MAX_LENGTH = 256;
@@ -1698,12 +2138,12 @@ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1698
2138
  };
1699
2139
  }));
1700
2140
  //#endregion
1701
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/debug.js
2141
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/debug.js
1702
2142
  var require_debug = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1703
2143
  module.exports = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {};
1704
2144
  }));
1705
2145
  //#endregion
1706
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/re.js
2146
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/re.js
1707
2147
  var require_re = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1708
2148
  const { MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH, MAX_LENGTH } = require_constants();
1709
2149
  const debug = require_debug();
@@ -1782,7 +2222,7 @@ var require_re = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1782
2222
  createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
1783
2223
  }));
1784
2224
  //#endregion
1785
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/parse-options.js
2225
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/parse-options.js
1786
2226
  var require_parse_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1787
2227
  const looseOption = Object.freeze({ loose: true });
1788
2228
  const emptyOpts = Object.freeze({});
@@ -1794,7 +2234,7 @@ var require_parse_options = /* @__PURE__ */ __commonJSMin(((exports, module) =>
1794
2234
  module.exports = parseOptions;
1795
2235
  }));
1796
2236
  //#endregion
1797
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/identifiers.js
2237
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/identifiers.js
1798
2238
  var require_identifiers = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1799
2239
  const numeric = /^[0-9]+$/;
1800
2240
  const compareIdentifiers = (a, b) => {
@@ -1814,7 +2254,7 @@ var require_identifiers = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1814
2254
  };
1815
2255
  }));
1816
2256
  //#endregion
1817
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/classes/semver.js
2257
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/classes/semver.js
1818
2258
  var require_semver$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1819
2259
  const debug = require_debug();
1820
2260
  const { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
@@ -1992,7 +2432,7 @@ var require_semver$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1992
2432
  };
1993
2433
  }));
1994
2434
  //#endregion
1995
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/parse.js
2435
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/parse.js
1996
2436
  var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1997
2437
  const SemVer = require_semver$1();
1998
2438
  const parse = (version, options, throwErrors = false) => {
@@ -2007,7 +2447,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2007
2447
  module.exports = parse;
2008
2448
  }));
2009
2449
  //#endregion
2010
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/valid.js
2450
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/valid.js
2011
2451
  var require_valid$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2012
2452
  const parse = require_parse();
2013
2453
  const valid = (version, options) => {
@@ -2017,7 +2457,7 @@ var require_valid$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2017
2457
  module.exports = valid;
2018
2458
  }));
2019
2459
  //#endregion
2020
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/clean.js
2460
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/clean.js
2021
2461
  var require_clean = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2022
2462
  const parse = require_parse();
2023
2463
  const clean = (version, options) => {
@@ -2027,7 +2467,7 @@ var require_clean = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2027
2467
  module.exports = clean;
2028
2468
  }));
2029
2469
  //#endregion
2030
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/inc.js
2470
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/inc.js
2031
2471
  var require_inc = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2032
2472
  const SemVer = require_semver$1();
2033
2473
  const inc = (version, release, options, identifier, identifierBase) => {
@@ -2045,7 +2485,7 @@ var require_inc = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2045
2485
  module.exports = inc;
2046
2486
  }));
2047
2487
  //#endregion
2048
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/diff.js
2488
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/diff.js
2049
2489
  var require_diff = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2050
2490
  const parse = require_parse();
2051
2491
  const diff = (version1, version2) => {
@@ -2073,28 +2513,28 @@ var require_diff = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2073
2513
  module.exports = diff;
2074
2514
  }));
2075
2515
  //#endregion
2076
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/major.js
2516
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/major.js
2077
2517
  var require_major = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2078
2518
  const SemVer = require_semver$1();
2079
2519
  const major = (a, loose) => new SemVer(a, loose).major;
2080
2520
  module.exports = major;
2081
2521
  }));
2082
2522
  //#endregion
2083
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/minor.js
2523
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/minor.js
2084
2524
  var require_minor = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2085
2525
  const SemVer = require_semver$1();
2086
2526
  const minor = (a, loose) => new SemVer(a, loose).minor;
2087
2527
  module.exports = minor;
2088
2528
  }));
2089
2529
  //#endregion
2090
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/patch.js
2530
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/patch.js
2091
2531
  var require_patch = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2092
2532
  const SemVer = require_semver$1();
2093
2533
  const patch = (a, loose) => new SemVer(a, loose).patch;
2094
2534
  module.exports = patch;
2095
2535
  }));
2096
2536
  //#endregion
2097
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/prerelease.js
2537
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/prerelease.js
2098
2538
  var require_prerelease = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2099
2539
  const parse = require_parse();
2100
2540
  const prerelease = (version, options) => {
@@ -2104,28 +2544,28 @@ var require_prerelease = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2104
2544
  module.exports = prerelease;
2105
2545
  }));
2106
2546
  //#endregion
2107
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/compare.js
2547
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/compare.js
2108
2548
  var require_compare = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2109
2549
  const SemVer = require_semver$1();
2110
2550
  const compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
2111
2551
  module.exports = compare;
2112
2552
  }));
2113
2553
  //#endregion
2114
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/rcompare.js
2554
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/rcompare.js
2115
2555
  var require_rcompare = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2116
2556
  const compare = require_compare();
2117
2557
  const rcompare = (a, b, loose) => compare(b, a, loose);
2118
2558
  module.exports = rcompare;
2119
2559
  }));
2120
2560
  //#endregion
2121
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/compare-loose.js
2561
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/compare-loose.js
2122
2562
  var require_compare_loose = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2123
2563
  const compare = require_compare();
2124
2564
  const compareLoose = (a, b) => compare(a, b, true);
2125
2565
  module.exports = compareLoose;
2126
2566
  }));
2127
2567
  //#endregion
2128
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/compare-build.js
2568
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/compare-build.js
2129
2569
  var require_compare_build = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2130
2570
  const SemVer = require_semver$1();
2131
2571
  const compareBuild = (a, b, loose) => {
@@ -2136,63 +2576,63 @@ var require_compare_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
2136
2576
  module.exports = compareBuild;
2137
2577
  }));
2138
2578
  //#endregion
2139
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/sort.js
2579
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/sort.js
2140
2580
  var require_sort = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2141
2581
  const compareBuild = require_compare_build();
2142
2582
  const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose));
2143
2583
  module.exports = sort;
2144
2584
  }));
2145
2585
  //#endregion
2146
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/rsort.js
2586
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/rsort.js
2147
2587
  var require_rsort = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2148
2588
  const compareBuild = require_compare_build();
2149
2589
  const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose));
2150
2590
  module.exports = rsort;
2151
2591
  }));
2152
2592
  //#endregion
2153
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/gt.js
2593
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/gt.js
2154
2594
  var require_gt = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2155
2595
  const compare = require_compare();
2156
2596
  const gt = (a, b, loose) => compare(a, b, loose) > 0;
2157
2597
  module.exports = gt;
2158
2598
  }));
2159
2599
  //#endregion
2160
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/lt.js
2600
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/lt.js
2161
2601
  var require_lt = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2162
2602
  const compare = require_compare();
2163
2603
  const lt = (a, b, loose) => compare(a, b, loose) < 0;
2164
2604
  module.exports = lt;
2165
2605
  }));
2166
2606
  //#endregion
2167
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/eq.js
2607
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/eq.js
2168
2608
  var require_eq = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2169
2609
  const compare = require_compare();
2170
2610
  const eq = (a, b, loose) => compare(a, b, loose) === 0;
2171
2611
  module.exports = eq;
2172
2612
  }));
2173
2613
  //#endregion
2174
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/neq.js
2614
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/neq.js
2175
2615
  var require_neq = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2176
2616
  const compare = require_compare();
2177
2617
  const neq = (a, b, loose) => compare(a, b, loose) !== 0;
2178
2618
  module.exports = neq;
2179
2619
  }));
2180
2620
  //#endregion
2181
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/gte.js
2621
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/gte.js
2182
2622
  var require_gte = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2183
2623
  const compare = require_compare();
2184
2624
  const gte = (a, b, loose) => compare(a, b, loose) >= 0;
2185
2625
  module.exports = gte;
2186
2626
  }));
2187
2627
  //#endregion
2188
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/lte.js
2628
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/lte.js
2189
2629
  var require_lte = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2190
2630
  const compare = require_compare();
2191
2631
  const lte = (a, b, loose) => compare(a, b, loose) <= 0;
2192
2632
  module.exports = lte;
2193
2633
  }));
2194
2634
  //#endregion
2195
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/cmp.js
2635
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/cmp.js
2196
2636
  var require_cmp = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2197
2637
  const eq = require_eq();
2198
2638
  const neq = require_neq();
@@ -2224,7 +2664,7 @@ var require_cmp = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2224
2664
  module.exports = cmp;
2225
2665
  }));
2226
2666
  //#endregion
2227
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/coerce.js
2667
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/coerce.js
2228
2668
  var require_coerce = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2229
2669
  const SemVer = require_semver$1();
2230
2670
  const parse = require_parse();
@@ -2252,7 +2692,40 @@ var require_coerce = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2252
2692
  module.exports = coerce;
2253
2693
  }));
2254
2694
  //#endregion
2255
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/lrucache.js
2695
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/truncate.js
2696
+ var require_truncate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2697
+ const parse = require_parse();
2698
+ const constants = require_constants();
2699
+ const SemVer = require_semver$1();
2700
+ const truncate = (version, truncation, options) => {
2701
+ if (!constants.RELEASE_TYPES.includes(truncation)) return null;
2702
+ const clonedVersion = cloneInputVersion(version, options);
2703
+ return clonedVersion && doTruncation(clonedVersion, truncation);
2704
+ };
2705
+ const cloneInputVersion = (version, options) => {
2706
+ return parse(version instanceof SemVer ? version.version : version, options);
2707
+ };
2708
+ const doTruncation = (version, truncation) => {
2709
+ if (isPrerelease(truncation)) return version.version;
2710
+ version.prerelease = [];
2711
+ switch (truncation) {
2712
+ case "major":
2713
+ version.minor = 0;
2714
+ version.patch = 0;
2715
+ break;
2716
+ case "minor":
2717
+ version.patch = 0;
2718
+ break;
2719
+ }
2720
+ return version.format();
2721
+ };
2722
+ const isPrerelease = (type) => {
2723
+ return type.startsWith("pre");
2724
+ };
2725
+ module.exports = truncate;
2726
+ }));
2727
+ //#endregion
2728
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/internal/lrucache.js
2256
2729
  var require_lrucache = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2257
2730
  var LRUCache = class {
2258
2731
  constructor() {
@@ -2285,7 +2758,7 @@ var require_lrucache = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2285
2758
  module.exports = LRUCache;
2286
2759
  }));
2287
2760
  //#endregion
2288
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/classes/range.js
2761
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/classes/range.js
2289
2762
  var require_range = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2290
2763
  const SPACE_CHARACTERS = /\s+/g;
2291
2764
  module.exports = class Range {
@@ -2557,7 +3030,7 @@ var require_range = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2557
3030
  };
2558
3031
  }));
2559
3032
  //#endregion
2560
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/classes/comparator.js
3033
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/classes/comparator.js
2561
3034
  var require_comparator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2562
3035
  const ANY = Symbol("SemVer ANY");
2563
3036
  module.exports = class Comparator {
@@ -2627,7 +3100,7 @@ var require_comparator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2627
3100
  const Range = require_range();
2628
3101
  }));
2629
3102
  //#endregion
2630
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/satisfies.js
3103
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/functions/satisfies.js
2631
3104
  var require_satisfies = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2632
3105
  const Range = require_range();
2633
3106
  const satisfies = (version, range, options) => {
@@ -2641,14 +3114,14 @@ var require_satisfies = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2641
3114
  module.exports = satisfies;
2642
3115
  }));
2643
3116
  //#endregion
2644
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/to-comparators.js
3117
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/to-comparators.js
2645
3118
  var require_to_comparators = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2646
3119
  const Range = require_range();
2647
3120
  const toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" "));
2648
3121
  module.exports = toComparators;
2649
3122
  }));
2650
3123
  //#endregion
2651
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/max-satisfying.js
3124
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/max-satisfying.js
2652
3125
  var require_max_satisfying = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2653
3126
  const SemVer = require_semver$1();
2654
3127
  const Range = require_range();
@@ -2674,7 +3147,7 @@ var require_max_satisfying = /* @__PURE__ */ __commonJSMin(((exports, module) =>
2674
3147
  module.exports = maxSatisfying;
2675
3148
  }));
2676
3149
  //#endregion
2677
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/min-satisfying.js
3150
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/min-satisfying.js
2678
3151
  var require_min_satisfying = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2679
3152
  const SemVer = require_semver$1();
2680
3153
  const Range = require_range();
@@ -2700,7 +3173,7 @@ var require_min_satisfying = /* @__PURE__ */ __commonJSMin(((exports, module) =>
2700
3173
  module.exports = minSatisfying;
2701
3174
  }));
2702
3175
  //#endregion
2703
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/min-version.js
3176
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/min-version.js
2704
3177
  var require_min_version = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2705
3178
  const SemVer = require_semver$1();
2706
3179
  const Range = require_range();
@@ -2740,7 +3213,7 @@ var require_min_version = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2740
3213
  module.exports = minVersion;
2741
3214
  }));
2742
3215
  //#endregion
2743
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/valid.js
3216
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/valid.js
2744
3217
  var require_valid = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2745
3218
  const Range = require_range();
2746
3219
  const validRange = (range, options) => {
@@ -2753,7 +3226,7 @@ var require_valid = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2753
3226
  module.exports = validRange;
2754
3227
  }));
2755
3228
  //#endregion
2756
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/outside.js
3229
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/outside.js
2757
3230
  var require_outside = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2758
3231
  const SemVer = require_semver$1();
2759
3232
  const Comparator = require_comparator();
@@ -2806,21 +3279,21 @@ var require_outside = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2806
3279
  module.exports = outside;
2807
3280
  }));
2808
3281
  //#endregion
2809
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/gtr.js
3282
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/gtr.js
2810
3283
  var require_gtr = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2811
3284
  const outside = require_outside();
2812
3285
  const gtr = (version, range, options) => outside(version, range, ">", options);
2813
3286
  module.exports = gtr;
2814
3287
  }));
2815
3288
  //#endregion
2816
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/ltr.js
3289
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/ltr.js
2817
3290
  var require_ltr = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2818
3291
  const outside = require_outside();
2819
3292
  const ltr = (version, range, options) => outside(version, range, "<", options);
2820
3293
  module.exports = ltr;
2821
3294
  }));
2822
3295
  //#endregion
2823
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/intersects.js
3296
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/intersects.js
2824
3297
  var require_intersects = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2825
3298
  const Range = require_range();
2826
3299
  const intersects = (r1, r2, options) => {
@@ -2831,7 +3304,7 @@ var require_intersects = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2831
3304
  module.exports = intersects;
2832
3305
  }));
2833
3306
  //#endregion
2834
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/simplify.js
3307
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/simplify.js
2835
3308
  var require_simplify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2836
3309
  const satisfies = require_satisfies();
2837
3310
  const compare = require_compare();
@@ -2861,7 +3334,7 @@ var require_simplify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2861
3334
  };
2862
3335
  }));
2863
3336
  //#endregion
2864
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/ranges/subset.js
3337
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/ranges/subset.js
2865
3338
  var require_subset = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2866
3339
  const Range = require_range();
2867
3340
  const Comparator = require_comparator();
@@ -2956,7 +3429,7 @@ var require_subset = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2956
3429
  module.exports = subset;
2957
3430
  }));
2958
3431
  //#endregion
2959
- //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/index.js
3432
+ //#region ../../node_modules/.pnpm/semver@7.8.0/node_modules/semver/index.js
2960
3433
  var require_semver = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2961
3434
  const internalRe = require_re();
2962
3435
  const constants = require_constants();
@@ -2986,6 +3459,7 @@ var require_semver = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2986
3459
  lte: require_lte(),
2987
3460
  cmp: require_cmp(),
2988
3461
  coerce: require_coerce(),
3462
+ truncate: require_truncate(),
2989
3463
  Comparator: require_comparator(),
2990
3464
  Range: require_range(),
2991
3465
  satisfies: require_satisfies(),
@@ -3025,26 +3499,8 @@ const DependencyType = {
3025
3499
  optionalDependencies: "optionalDependencies"
3026
3500
  };
3027
3501
  //#endregion
3028
- //#region src/utils/path.ts
3029
- var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
3030
- var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
3031
- var import_dist = require_dist();
3032
- function findPkgRoot() {
3033
- let dir = import.meta.dirname;
3034
- while (dir !== path.dirname(dir)) {
3035
- if (fs.existsSync(path.join(dir, "package.json"))) return dir;
3036
- dir = path.dirname(dir);
3037
- }
3038
- return dir;
3039
- }
3040
- const pkgRoot = findPkgRoot();
3041
- const templatesDir = path.join(pkgRoot, "templates");
3042
- const rulesDir = path.join(pkgRoot, "rules");
3043
- function displayRelative(to, from = process.cwd()) {
3044
- return path.relative(from, to).replaceAll("\\", "/");
3045
- }
3046
- //#endregion
3047
3502
  //#region src/utils/prompts.ts
3503
+ var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
3048
3504
  /**
3049
3505
  * pnpm v11 promoted `ERR_PNPM_IGNORED_BUILDS` from a warning to a hard
3050
3506
  * exit-1. Auto-installs run by `vp migrate` / `vp create` happen before the
@@ -3206,7 +3662,7 @@ async function promptGitInit(options) {
3206
3662
  if (options.interactive) {
3207
3663
  const selected = await confirm({
3208
3664
  message: "Initialize a git repository with an initial commit?",
3209
- initialValue: false
3665
+ initialValue: true
3210
3666
  });
3211
3667
  if (q(selected)) {
3212
3668
  cancelAndExit();
@@ -3241,2027 +3697,130 @@ function getSilentSpinner() {
3241
3697
  };
3242
3698
  }
3243
3699
  //#endregion
3244
- //#region src/utils/yaml.ts
3245
- function readYamlFile(file) {
3246
- return (0, import_dist.parse)(fs.readFileSync(file, "utf-8"));
3247
- }
3248
- function editYamlFile(file, callback) {
3249
- const doc = (0, import_dist.parseDocument)(fs.readFileSync(file, "utf-8"));
3250
- callback(doc);
3251
- fs.writeFileSync(file, doc.toString({ singleQuote: true }), "utf-8");
3252
- }
3253
- function scalarString(value) {
3254
- return new import_dist.Scalar(value);
3255
- }
3256
- //#endregion
3257
- //#region src/migration/detector.ts
3258
- const PRETTIER_PACKAGE_JSON_CONFIG = "package.json#prettier";
3259
- const PRETTIER_CONFIG_FILES = [
3260
- ".prettierrc",
3261
- ".prettierrc.json",
3262
- ".prettierrc.jsonc",
3263
- ".prettierrc.yaml",
3264
- ".prettierrc.yml",
3265
- ".prettierrc.toml",
3266
- ".prettierrc.js",
3267
- ".prettierrc.cjs",
3268
- ".prettierrc.mjs",
3269
- ".prettierrc.ts",
3270
- ".prettierrc.cts",
3271
- ".prettierrc.mts",
3272
- "prettier.config.js",
3273
- "prettier.config.cjs",
3274
- "prettier.config.mjs",
3275
- "prettier.config.ts",
3276
- "prettier.config.cts",
3277
- "prettier.config.mts"
3278
- ];
3279
- function detectConfigs(projectPath) {
3280
- const configs = {};
3281
- for (const config of [
3282
- "vite.config.ts",
3283
- "vite.config.mts",
3284
- "vite.config.cts",
3285
- "vite.config.js",
3286
- "vite.config.mjs",
3287
- "vite.config.cjs"
3288
- ]) if (fs.existsSync(path.join(projectPath, config))) {
3289
- configs.viteConfig = config;
3290
- break;
3291
- }
3292
- for (const config of [
3293
- "vitest.config.ts",
3294
- "vitest.config.mts",
3295
- "vitest.config.cts",
3296
- "vitest.config.js",
3297
- "vitest.config.mjs",
3298
- "vitest.config.cjs"
3299
- ]) if (fs.existsSync(path.join(projectPath, config))) {
3300
- configs.vitestConfig = config;
3301
- break;
3302
- }
3303
- for (const config of [
3304
- "tsdown.config.ts",
3305
- "tsdown.config.mts",
3306
- "tsdown.config.cts",
3307
- "tsdown.config.js",
3308
- "tsdown.config.mjs",
3309
- "tsdown.config.cjs",
3310
- "tsdown.config.json",
3311
- "tsdown.config"
3312
- ]) if (fs.existsSync(path.join(projectPath, config))) {
3313
- configs.tsdownConfig = config;
3314
- break;
3315
- }
3316
- for (const config of [".oxlintrc.json", ".oxlintrc.jsonc"]) if (fs.existsSync(path.join(projectPath, config))) {
3317
- configs.oxlintConfig = config;
3318
- break;
3319
- }
3320
- for (const config of [".oxfmtrc.json", ".oxfmtrc.jsonc"]) if (fs.existsSync(path.join(projectPath, config))) {
3321
- configs.oxfmtConfig = config;
3322
- break;
3323
- }
3324
- for (const config of [
3325
- "eslint.config.js",
3326
- "eslint.config.mjs",
3327
- "eslint.config.cjs",
3328
- "eslint.config.ts",
3329
- "eslint.config.mts",
3330
- "eslint.config.cts"
3331
- ]) if (fs.existsSync(path.join(projectPath, config))) {
3332
- configs.eslintConfig = config;
3333
- break;
3334
- }
3335
- for (const config of [
3336
- ".eslintrc",
3337
- ".eslintrc.json",
3338
- ".eslintrc.js",
3339
- ".eslintrc.cjs",
3340
- ".eslintrc.yaml",
3341
- ".eslintrc.yml"
3342
- ]) if (fs.existsSync(path.join(projectPath, config))) {
3343
- configs.eslintLegacyConfig = config;
3344
- break;
3345
- }
3346
- for (const config of PRETTIER_CONFIG_FILES) if (fs.existsSync(path.join(projectPath, config))) {
3347
- configs.prettierConfig = config;
3348
- break;
3349
- }
3350
- if (fs.existsSync(path.join(projectPath, ".prettierignore"))) configs.prettierIgnore = true;
3351
- if (fs.existsSync(path.join(projectPath, ".nvmrc"))) configs.nvmrcFile = true;
3352
- const packageJsonPath = path.join(projectPath, "package.json");
3353
- if (fs.existsSync(packageJsonPath)) try {
3354
- const content = fs.readFileSync(packageJsonPath, "utf8");
3355
- const pkg = JSON.parse(content);
3356
- if (!configs.prettierConfig && pkg.prettier) configs.prettierConfig = PRETTIER_PACKAGE_JSON_CONFIG;
3357
- const voltaNode = pkg.volta?.node;
3358
- if (typeof voltaNode === "string") configs.voltaNode = voltaNode;
3359
- } catch {}
3360
- return configs;
3361
- }
3362
- //#endregion
3363
- //#region src/migration/migrator.ts
3364
- const LINT_STAGED_JSON_CONFIG_FILES = [".lintstagedrc.json", ".lintstagedrc"];
3365
- const LINT_STAGED_OTHER_CONFIG_FILES = [
3366
- ".lintstagedrc.yaml",
3367
- ".lintstagedrc.yml",
3368
- ".lintstagedrc.mjs",
3369
- "lint-staged.config.mjs",
3370
- ".lintstagedrc.cjs",
3371
- "lint-staged.config.cjs",
3372
- ".lintstagedrc.js",
3373
- "lint-staged.config.js",
3374
- ".lintstagedrc.ts",
3375
- "lint-staged.config.ts",
3376
- ".lintstagedrc.mts",
3377
- "lint-staged.config.mts",
3378
- ".lintstagedrc.cts",
3379
- "lint-staged.config.cts"
3380
- ];
3381
- const LINT_STAGED_ALL_CONFIG_FILES = [...LINT_STAGED_JSON_CONFIG_FILES, ...LINT_STAGED_OTHER_CONFIG_FILES];
3382
- const REMOVE_PACKAGES = [
3383
- "oxlint",
3384
- "oxlint-tsgolint",
3385
- "oxfmt",
3386
- "tsdown",
3387
- "@vitest/browser",
3388
- "@vitest/browser-preview",
3389
- "@vitest/browser-playwright",
3390
- "@vitest/browser-webdriverio"
3391
- ];
3392
- const BROWSER_PROVIDER_PEER_DEPS = {
3393
- "@vitest/browser-playwright": "playwright",
3394
- "@vitest/browser-webdriverio": "webdriverio"
3395
- };
3396
- const PUBLIC_PEER_DEPENDENCY_FALLBACKS = {
3397
- vite: "*",
3398
- vitest: "*"
3399
- };
3400
- function warnMigration(message, report) {
3401
- addMigrationWarning(report, message);
3402
- if (!report) log.warn(message);
3403
- }
3404
- function infoMigration(message, report) {
3405
- addManualStep(report, message);
3406
- if (!report) log.info(message);
3407
- }
3408
- function checkViteVersion(projectPath) {
3409
- return checkPackageVersion(projectPath, "vite", "7.0.0");
3410
- }
3411
- function checkVitestVersion(projectPath) {
3412
- return checkPackageVersion(projectPath, "vitest", "4.0.0");
3413
- }
3414
- /**
3415
- * Check the package version is supported by auto migration
3416
- * @param projectPath - The path to the project
3417
- * @param name - The name of the package
3418
- * @param minVersion - The minimum version of the package
3419
- * @returns true if the package version is supported by auto migration
3420
- */
3421
- function checkPackageVersion(projectPath, name, minVersion) {
3422
- const metadata = detectPackageMetadata(projectPath, name);
3423
- if (!metadata || metadata.name !== name) return true;
3424
- if (import_semver.default.satisfies(metadata.version, `<${minVersion}`)) {
3425
- const packageJsonFilePath = path.join(projectPath, "package.json");
3426
- log.error(`✘ ${name}@${metadata.version} in ${displayRelative(packageJsonFilePath)} is not supported by auto migration`);
3427
- log.info(`Please upgrade ${name} to version >=${minVersion} first`);
3428
- return false;
3429
- }
3430
- return true;
3431
- }
3432
- function detectEslintProject(projectPath, packages) {
3433
- const packageJsonPath = path.join(projectPath, "package.json");
3434
- if (!fs.existsSync(packageJsonPath)) return { hasDependency: false };
3435
- const pkg = readJsonFile(packageJsonPath);
3436
- let hasDependency = !!(pkg.devDependencies?.eslint || pkg.dependencies?.eslint);
3437
- const configs = detectConfigs(projectPath);
3438
- let configFile = configs.eslintConfig;
3439
- const legacyConfigFile = configs.eslintLegacyConfig;
3440
- if (!hasDependency && packages) for (const wp of packages) {
3441
- const pkgJsonPath = path.join(projectPath, wp.path, "package.json");
3442
- if (!fs.existsSync(pkgJsonPath)) continue;
3443
- const wpPkg = readJsonFile(pkgJsonPath);
3444
- if (wpPkg.devDependencies?.eslint || wpPkg.dependencies?.eslint) {
3445
- hasDependency = true;
3446
- break;
3447
- }
3448
- }
3449
- return {
3450
- hasDependency,
3451
- configFile,
3452
- legacyConfigFile
3453
- };
3454
- }
3700
+ //#region src/utils/tsconfig.ts
3455
3701
  /**
3456
- * Run a `vp dlx @oxlint/migrate` step with graceful error handling.
3457
- * Returns true on success, false on failure (spawn error or non-zero exit).
3702
+ * Check if tsconfig.json has compilerOptions.baseUrl set.
3703
+ * oxlint's TypeScript checker (tsgolint) does not support baseUrl,
3704
+ * so typeAware/typeCheck must be disabled when it is present.
3458
3705
  */
3459
- async function runOxlintMigrateStep(vpBin, cwd, migratePackage, args, spinner, failMessage, manualHint) {
3706
+ function hasBaseUrlInTsconfigFile(filePath) {
3460
3707
  try {
3461
- const result = await runCommandSilently({
3462
- command: vpBin,
3463
- args: [
3464
- "dlx",
3465
- migratePackage,
3466
- ...args
3467
- ],
3468
- cwd,
3469
- envs: process.env
3470
- });
3471
- if (result.exitCode !== 0) {
3472
- spinner.stop(failMessage);
3473
- const stderr = result.stderr.toString().trim();
3474
- if (stderr) log.warn(`⚠ ${stderr}`);
3475
- log.info(manualHint);
3476
- return false;
3477
- }
3478
- return true;
3708
+ return parse(fs.readFileSync(filePath, "utf-8"))?.compilerOptions?.baseUrl != null;
3479
3709
  } catch {
3480
- spinner.stop(failMessage);
3481
- log.info(manualHint);
3482
3710
  return false;
3483
3711
  }
3484
3712
  }
3485
- async function migrateEslintToOxlint(projectPath, interactive, eslintConfigFile, packages, options) {
3486
- const vpBin = process.env.VP_CLI_BIN ?? "vp";
3487
- const spinner = options?.silent ? {
3488
- start: () => {},
3489
- stop: () => {},
3490
- pause: () => {},
3491
- resume: () => {},
3492
- cancel: () => {},
3493
- error: () => {},
3494
- clear: () => {},
3495
- message: () => {},
3496
- isCancelled: false
3497
- } : getSpinner(interactive);
3498
- if (eslintConfigFile) {
3499
- const { versions } = await import("./versions.js");
3500
- const migratePackage = `@oxlint/migrate@${versions.oxlint}`;
3501
- spinner.start("Migrating ESLint config to Oxlint...");
3502
- if (!await runOxlintMigrateStep(vpBin, projectPath, migratePackage, [
3503
- "--merge",
3504
- "--type-aware",
3505
- "--with-nursery",
3506
- "--details"
3507
- ], spinner, "ESLint migration failed", `You can run \`vp dlx ${migratePackage} --merge --type-aware --with-nursery --details\` manually later`)) return false;
3508
- spinner.stop("ESLint config migrated to .oxlintrc.json");
3509
- spinner.start("Replacing ESLint comments with Oxlint equivalents...");
3510
- if (await runOxlintMigrateStep(vpBin, projectPath, migratePackage, ["--replace-eslint-comments"], spinner, "ESLint comment replacement failed", `You can run \`vp dlx ${migratePackage} --replace-eslint-comments\` manually later`)) spinner.stop("ESLint comments replaced");
3511
- }
3512
- if (options?.report) options.report.eslintMigrated = true;
3513
- deleteEslintConfigFiles(projectPath, options?.report, options?.silent);
3514
- rewriteEslintPackageJson(path.join(projectPath, "package.json"));
3515
- if (packages) for (const pkg of packages) rewriteEslintPackageJson(path.join(projectPath, pkg.path, "package.json"));
3516
- rewriteEslintLintStagedConfigFiles(projectPath, options?.report);
3517
- return true;
3518
- }
3519
- function deleteEslintConfigFiles(basePath, report, silent = false) {
3520
- const configs = detectConfigs(basePath);
3521
- for (const file of [configs.eslintConfig, configs.eslintLegacyConfig]) if (file) {
3522
- const configPath = path.join(basePath, file);
3523
- if (fs.existsSync(configPath)) {
3524
- fs.unlinkSync(configPath);
3525
- if (report) report.removedConfigCount++;
3526
- if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
3527
- }
3528
- }
3529
- }
3530
- function rewriteEslintPackageJson(packageJsonPath) {
3531
- editJsonFile(packageJsonPath, (pkg) => {
3532
- let changed = false;
3533
- if (pkg.devDependencies?.eslint) {
3534
- delete pkg.devDependencies.eslint;
3535
- changed = true;
3536
- }
3537
- if (pkg.dependencies?.eslint) {
3538
- delete pkg.dependencies.eslint;
3539
- changed = true;
3540
- }
3541
- if (pkg.scripts) {
3542
- const updated = rewriteEslint(JSON.stringify(pkg.scripts));
3543
- if (updated) {
3544
- pkg.scripts = JSON.parse(updated);
3545
- changed = true;
3546
- }
3547
- }
3548
- if (pkg["lint-staged"]) {
3549
- const updated = rewriteEslint(JSON.stringify(pkg["lint-staged"]));
3550
- if (updated) {
3551
- pkg["lint-staged"] = JSON.parse(updated);
3552
- changed = true;
3553
- }
3554
- }
3555
- return changed ? pkg : void 0;
3556
- });
3557
- }
3558
- /**
3559
- * Rewrite tool references in lint-staged config files (JSON ones are rewritten,
3560
- * non-JSON ones get a warning).
3561
- */
3562
- function rewriteToolLintStagedConfigFiles(projectPath, rewriteFn, toolName, report) {
3563
- for (const filename of LINT_STAGED_JSON_CONFIG_FILES) {
3564
- const configPath = path.join(projectPath, filename);
3565
- if (!fs.existsSync(configPath)) continue;
3566
- if (filename === ".lintstagedrc" && !isJsonFile(configPath)) {
3567
- warnMigration(`${displayRelative(configPath)} is not JSON — please update ${toolName} references manually`, report);
3568
- continue;
3569
- }
3570
- editJsonFile(configPath, (config) => {
3571
- const updated = rewriteFn(JSON.stringify(config));
3572
- if (updated) return JSON.parse(updated);
3573
- });
3574
- }
3575
- for (const filename of LINT_STAGED_OTHER_CONFIG_FILES) {
3576
- const configPath = path.join(projectPath, filename);
3577
- if (!fs.existsSync(configPath)) continue;
3578
- warnMigration(`${displayRelative(configPath)} — please update ${toolName} references manually`, report);
3579
- }
3580
- }
3581
- function rewriteEslintLintStagedConfigFiles(projectPath, report) {
3582
- rewriteToolLintStagedConfigFiles(projectPath, rewriteEslint, "eslint", report);
3583
- }
3584
- function detectPrettierProject(projectPath, packages) {
3585
- const packageJsonPath = path.join(projectPath, "package.json");
3586
- if (!fs.existsSync(packageJsonPath)) return { hasDependency: false };
3587
- const pkg = readJsonFile(packageJsonPath);
3588
- let hasDependency = !!(pkg.devDependencies?.prettier || pkg.dependencies?.prettier);
3589
- const configFile = detectConfigs(projectPath).prettierConfig;
3590
- if (!hasDependency && packages) for (const wp of packages) {
3591
- const pkgJsonPath = path.join(projectPath, wp.path, "package.json");
3592
- if (!fs.existsSync(pkgJsonPath)) continue;
3593
- const wpPkg = readJsonFile(pkgJsonPath);
3594
- if (wpPkg.devDependencies?.prettier || wpPkg.dependencies?.prettier) {
3595
- hasDependency = true;
3596
- break;
3597
- }
3598
- }
3599
- return {
3600
- hasDependency,
3601
- configFile
3602
- };
3603
- }
3604
- /**
3605
- * Run `vp fmt --migrate=prettier` step with graceful error handling.
3606
- * Returns true on success, false on failure.
3607
- */
3608
- async function runPrettierMigrateStep(vpBin, cwd, spinner, failMessage, manualHint) {
3713
+ const TSCONFIG_FILE_RE = /^tsconfig(\.[\w-]+)?\.json$/i;
3714
+ function findTsconfigFiles(projectPath) {
3609
3715
  try {
3610
- const result = await runCommandSilently({
3611
- command: vpBin,
3612
- args: ["fmt", "--migrate=prettier"],
3613
- cwd,
3614
- envs: process.env
3615
- });
3616
- if (result.exitCode !== 0) {
3617
- spinner.stop(failMessage);
3618
- const stderr = result.stderr.toString().trim();
3619
- if (stderr) log.warn(`⚠ ${stderr}`);
3620
- log.info(manualHint);
3621
- return false;
3622
- }
3623
- return true;
3716
+ return fs.readdirSync(projectPath).filter((name) => TSCONFIG_FILE_RE.test(name)).map((name) => path.join(projectPath, name));
3624
3717
  } catch {
3625
- spinner.stop(failMessage);
3626
- log.info(manualHint);
3627
- return false;
3718
+ return [];
3628
3719
  }
3629
3720
  }
3630
- async function migratePrettierToOxfmt(projectPath, interactive, prettierConfigFile, packages, options) {
3631
- const vpBin = process.env.VP_CLI_BIN ?? "vp";
3632
- const spinner = options?.silent ? {
3633
- start: () => {},
3634
- stop: () => {},
3635
- pause: () => {},
3636
- resume: () => {},
3637
- cancel: () => {},
3638
- error: () => {},
3639
- clear: () => {},
3640
- message: () => {},
3641
- isCancelled: false
3642
- } : getSpinner(interactive);
3643
- if (prettierConfigFile) {
3644
- let tempPrettierConfig;
3645
- if (prettierConfigFile === "package.json#prettier") {
3646
- const pkg = readJsonFile(path.join(projectPath, "package.json"));
3647
- if (pkg.prettier) {
3648
- tempPrettierConfig = path.join(projectPath, ".prettierrc.json");
3649
- fs.writeFileSync(tempPrettierConfig, JSON.stringify(pkg.prettier, null, 2));
3650
- } else return true;
3651
- }
3652
- try {
3653
- spinner.start("Migrating Prettier config to Oxfmt...");
3654
- if (!await runPrettierMigrateStep(vpBin, projectPath, spinner, "Prettier migration failed", "You can run `vp fmt --migrate=prettier` manually later")) return false;
3655
- spinner.stop("Prettier config migrated to .oxfmtrc.json");
3656
- } finally {
3657
- if (tempPrettierConfig) try {
3658
- fs.unlinkSync(tempPrettierConfig);
3659
- } catch {}
3660
- }
3661
- }
3662
- if (options?.report) options.report.prettierMigrated = true;
3663
- deletePrettierConfigFiles(projectPath, options?.report, options?.silent);
3664
- rewritePrettierPackageJson(path.join(projectPath, "package.json"));
3665
- if (packages) for (const pkg of packages) rewritePrettierPackageJson(path.join(projectPath, pkg.path, "package.json"));
3666
- rewritePrettierLintStagedConfigFiles(projectPath, options?.report);
3667
- const prettierIgnorePath = path.join(projectPath, ".prettierignore");
3668
- if (fs.existsSync(prettierIgnorePath)) warnMigration(`${displayRelative(prettierIgnorePath)} found — Oxfmt supports .prettierignore, but using the \`ignorePatterns\` option is recommended.`, options?.report);
3669
- return true;
3721
+ function hasBaseUrlInTsconfig(projectPath) {
3722
+ return findTsconfigFiles(projectPath).some((filePath) => hasBaseUrlInTsconfigFile(filePath));
3670
3723
  }
3671
- function deletePrettierConfigFiles(basePath, report, silent = false) {
3672
- const configs = detectConfigs(basePath);
3673
- if (configs.prettierConfig && configs.prettierConfig !== "package.json#prettier") {
3674
- const configPath = path.join(basePath, configs.prettierConfig);
3675
- if (fs.existsSync(configPath)) {
3676
- fs.unlinkSync(configPath);
3677
- if (report) report.removedConfigCount++;
3678
- if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
3679
- }
3680
- }
3681
- for (const file of PRETTIER_CONFIG_FILES) {
3682
- if (file === configs.prettierConfig) continue;
3683
- const configPath = path.join(basePath, file);
3684
- if (fs.existsSync(configPath)) {
3685
- fs.unlinkSync(configPath);
3686
- if (report) report.removedConfigCount++;
3687
- if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
3688
- }
3689
- }
3690
- editJsonFile(path.join(basePath, "package.json"), (pkg) => {
3691
- if (pkg.prettier) {
3692
- delete pkg.prettier;
3693
- return pkg;
3694
- }
3695
- });
3724
+ function findTsconfigFilesWithBaseUrl(projectPath) {
3725
+ return findTsconfigFiles(projectPath).filter((filePath) => hasBaseUrlInTsconfigFile(filePath));
3696
3726
  }
3697
- function rewritePrettierPackageJson(packageJsonPath) {
3698
- if (!fs.existsSync(packageJsonPath)) return;
3699
- editJsonFile(packageJsonPath, (pkg) => {
3700
- let changed = false;
3701
- if (pkg.devDependencies) {
3702
- for (const dep of Object.keys(pkg.devDependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
3703
- delete pkg.devDependencies[dep];
3704
- changed = true;
3705
- }
3706
- }
3707
- if (pkg.dependencies) {
3708
- for (const dep of Object.keys(pkg.dependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
3709
- delete pkg.dependencies[dep];
3710
- changed = true;
3711
- }
3712
- }
3713
- if (pkg.scripts) {
3714
- const updated = rewritePrettier(JSON.stringify(pkg.scripts));
3715
- if (updated) {
3716
- pkg.scripts = JSON.parse(updated);
3717
- changed = true;
3718
- }
3719
- }
3720
- if (pkg["lint-staged"]) {
3721
- const updated = rewritePrettier(JSON.stringify(pkg["lint-staged"]));
3722
- if (updated) {
3723
- pkg["lint-staged"] = JSON.parse(updated);
3724
- changed = true;
3725
- }
3726
- }
3727
- return changed ? pkg : void 0;
3727
+ async function confirmBaseUrlFix(interactive) {
3728
+ if (!interactive) return true;
3729
+ const command = [BASEURL_TSCONFIG_FIX_PACKAGE, ...createBaseUrlTsconfigFixArgs("<tsconfig path>")].join(" ");
3730
+ const confirmed = await confirm({
3731
+ message: "Your tsconfig contains `baseUrl`, which prevents enabling type-aware linting.\n " + styleText("gray", "`baseUrl` is deprecated in TypeScript 6.0 and removed in TypeScript 7.0.") + `\n Download and run the external \`${BASEURL_TSCONFIG_FIX_PACKAGE}\` fixer now?\n ` + styleText("gray", `Equivalent command: \`vp dlx ${command}\``),
3732
+ initialValue: true
3728
3733
  });
3734
+ if (q(confirmed)) cancelAndExit();
3735
+ return confirmed;
3729
3736
  }
3730
- function rewritePrettierLintStagedConfigFiles(projectPath, report) {
3731
- rewriteToolLintStagedConfigFiles(projectPath, rewritePrettier, "prettier", report);
3732
- }
3733
- function cleanupDeprecatedTsconfigOptions(projectPath, silent = false, report) {
3734
- const deprecatedOptions = ["esModuleInterop", "allowSyntheticDefaultImports"];
3735
- const files = findTsconfigFiles(projectPath);
3736
- for (const filePath of files) for (const name of deprecatedOptions) if (removeDeprecatedTsconfigFalseOption(filePath, name)) {
3737
- if (report) report.removedConfigCount++;
3738
- if (!silent) log.success(`✔ Removed ${name}: false from ${displayRelative(filePath)}`);
3739
- warnMigration(`Removed \`"${name}": false\` from ${displayRelative(filePath)} — this option has been deprecated. See https://github.com/oxc-project/tsgolint/issues/351, https://github.com/microsoft/TypeScript/issues/62529`, report);
3740
- }
3741
- }
3742
- function rewriteTsconfigTypes(projectPath, silent = false, report) {
3743
- const files = findTsconfigFiles(projectPath);
3744
- for (const filePath of files) if (rewriteTypesInTsconfig(filePath)) {
3745
- if (report) report.removedConfigCount++;
3746
- if (!silent) log.success(`✔ Rewrote types in ${displayRelative(filePath)}`);
3747
- }
3748
- }
3749
- const FRAMEWORK_SHIMS = {
3750
- vue: [
3751
- "declare module '*.vue' {",
3752
- " import type { DefineComponent } from 'vue';",
3753
- " const component: DefineComponent<{}, {}, unknown>;",
3754
- " export default component;",
3755
- "}"
3756
- ].join("\n"),
3757
- astro: "/// <reference types=\"astro/client\" />"
3758
- };
3759
- function detectFramework(projectPath) {
3760
- const packageJsonPath = path.join(projectPath, "package.json");
3761
- if (!fs.existsSync(packageJsonPath)) return [];
3762
- const pkg = readJsonFile(packageJsonPath);
3763
- const allDeps = {
3764
- ...pkg.dependencies,
3765
- ...pkg.devDependencies
3766
- };
3767
- return ["vue", "astro"].filter((framework) => !!allDeps[framework]);
3768
- }
3769
- function getEnvDtsPath(projectPath) {
3770
- const srcEnvDts = path.join(projectPath, "src", "env.d.ts");
3771
- const rootEnvDts = path.join(projectPath, "env.d.ts");
3772
- for (const candidate of [srcEnvDts, rootEnvDts]) if (fs.existsSync(candidate)) return candidate;
3773
- return fs.existsSync(path.join(projectPath, "src")) ? srcEnvDts : rootEnvDts;
3774
- }
3775
- function hasFrameworkShim(projectPath, framework) {
3776
- const dirsToScan = [projectPath, path.join(projectPath, "src")];
3777
- for (const dir of dirsToScan) {
3778
- if (!fs.existsSync(dir)) continue;
3779
- let entries;
3780
- try {
3781
- entries = fs.readdirSync(dir);
3782
- } catch {
3783
- continue;
3784
- }
3785
- for (const entry of entries) {
3786
- if (!entry.endsWith(".d.ts")) continue;
3787
- const content = fs.readFileSync(path.join(dir, entry), "utf-8");
3788
- if (framework === "astro") {
3789
- if (content.includes("astro/client")) return true;
3790
- } else if (content.includes(`'*.${framework}'`) || content.includes(`"*.${framework}"`)) return true;
3791
- }
3792
- }
3793
- return false;
3794
- }
3795
- function addFrameworkShim(projectPath, framework, report) {
3796
- const envDtsPath = getEnvDtsPath(projectPath);
3797
- const shim = FRAMEWORK_SHIMS[framework];
3798
- if (fs.existsSync(envDtsPath)) {
3799
- const existing = fs.readFileSync(envDtsPath, "utf-8");
3800
- fs.writeFileSync(envDtsPath, `${existing.trimEnd()}\n\n${shim}\n`, "utf-8");
3801
- } else {
3802
- fs.mkdirSync(path.dirname(envDtsPath), { recursive: true });
3803
- fs.writeFileSync(envDtsPath, `${shim}\n`, "utf-8");
3737
+ async function fixBaseUrlInTsconfig(projectPath, options) {
3738
+ const files = findTsconfigFilesWithBaseUrl(projectPath);
3739
+ if (files.length === 0) return "not-needed";
3740
+ if (!(options?.confirmed ?? await confirmBaseUrlFix(options?.interactive ?? false))) {
3741
+ options?.onStatus?.("declined", projectPath);
3742
+ return "declined";
3804
3743
  }
3805
- if (report) report.frameworkShimAdded = true;
3806
- }
3807
- /**
3808
- * Rewrite standalone project to add vite-plus dependencies
3809
- * @param projectPath - The path to the project
3810
- */
3811
- function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigration, silent = false, report) {
3812
- const packageJsonPath = path.join(projectPath, "package.json");
3813
- if (!fs.existsSync(packageJsonPath)) return;
3814
- const packageManager = workspaceInfo.packageManager;
3815
- const catalogDependencyResolver = createCatalogDependencyResolver(projectPath, packageManager);
3816
- let extractedStagedConfig = null;
3817
- let remainingPnpmOverrides;
3818
- let shouldRewritePnpmWorkspaceYaml = false;
3819
- let shouldAddPnpmWorkspaceVitePlusOverride = false;
3820
- let usePnpmWorkspaceYaml = false;
3821
- editJsonFile(packageJsonPath, (pkg) => {
3822
- if (packageManager === PackageManager.yarn) pkg.resolutions = {
3823
- ...pkg.resolutions,
3824
- ...VITE_PLUS_OVERRIDE_PACKAGES
3825
- };
3826
- else if (packageManager === PackageManager.npm || packageManager === PackageManager.bun) pkg.overrides = {
3827
- ...pkg.overrides,
3828
- ...VITE_PLUS_OVERRIDE_PACKAGES
3829
- };
3830
- else if (packageManager === PackageManager.pnpm) {
3831
- usePnpmWorkspaceYaml = !pkg.pnpm;
3832
- if (usePnpmWorkspaceYaml) {
3833
- shouldRewritePnpmWorkspaceYaml = true;
3834
- shouldAddPnpmWorkspaceVitePlusOverride = isForceOverrideMode();
3835
- }
3836
- const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
3837
- if (!usePnpmWorkspaceYaml) pkg.pnpm = {
3838
- ...pkg.pnpm,
3839
- overrides: {
3840
- ...pkg.pnpm?.overrides,
3841
- ...VITE_PLUS_OVERRIDE_PACKAGES,
3842
- ...isForceOverrideMode() ? { [VITE_PLUS_NAME]: VITE_PLUS_VERSION } : {}
3843
- },
3844
- peerDependencyRules: {
3845
- ...pkg.pnpm?.peerDependencyRules,
3846
- allowAny: [...new Set([...pkg.pnpm?.peerDependencyRules?.allowAny ?? [], ...overrideKeys])],
3847
- allowedVersions: {
3848
- ...pkg.pnpm?.peerDependencyRules?.allowedVersions,
3849
- ...Object.fromEntries(overrideKeys.map((key) => [key, "*"]))
3850
- }
3744
+ try {
3745
+ for (const filePath of files) {
3746
+ const fixArgs = createBaseUrlTsconfigFixArgs(path.relative(projectPath, filePath) || filePath);
3747
+ if (!options?.silent) log.info(`Running vp dlx ${BASEURL_TSCONFIG_FIX_PACKAGE} ${fixArgs.join(" ")}`);
3748
+ const result = await runCommandSilently({
3749
+ command: process.env.VP_CLI_BIN ?? "vp",
3750
+ args: [
3751
+ "dlx",
3752
+ BASEURL_TSCONFIG_FIX_PACKAGE,
3753
+ ...fixArgs
3754
+ ],
3755
+ cwd: projectPath,
3756
+ envs: process.env
3757
+ });
3758
+ if (result.exitCode !== 0) {
3759
+ if (!options?.silent) {
3760
+ const output = `${result.stdout.toString()}${result.stderr.toString()}`.trim();
3761
+ if (output) log.warn(output);
3851
3762
  }
3852
- };
3853
- else remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
3854
- for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
3855
- const splits = key.split(">");
3856
- if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
3763
+ options?.onStatus?.("failed", projectPath);
3764
+ return "failed";
3857
3765
  }
3858
- for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
3859
3766
  }
3860
- extractedStagedConfig = rewritePackageJson(pkg, packageManager, usePnpmWorkspaceYaml, skipStagedMigration, catalogDependencyResolver);
3861
- if (!pkg.devDependencies?.["vite-plus"] || isForceOverrideMode()) {
3862
- const version = usePnpmWorkspaceYaml && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
3863
- pkg.devDependencies = {
3864
- ...pkg.devDependencies,
3865
- [VITE_PLUS_NAME]: version
3866
- };
3767
+ if (hasBaseUrlInTsconfig(projectPath)) {
3768
+ if (!options?.silent) log.warn("tsconfig still contains baseUrl after running the fixer.");
3769
+ options?.onStatus?.("failed", projectPath);
3770
+ return "failed";
3867
3771
  }
3868
- return pkg;
3869
- });
3870
- if (shouldRewritePnpmWorkspaceYaml) rewritePnpmWorkspaceYaml(projectPath);
3871
- if (remainingPnpmOverrides) migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
3872
- if (shouldAddPnpmWorkspaceVitePlusOverride) migratePnpmOverridesToWorkspaceYaml(projectPath, { [VITE_PLUS_NAME]: VITE_PLUS_VERSION });
3873
- if (packageManager === PackageManager.yarn) rewriteYarnrcYml(projectPath);
3874
- if (extractedStagedConfig) {
3875
- if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) removeLintStagedFromPackageJson(packageJsonPath);
3772
+ } catch (error) {
3773
+ if (!options?.silent && error instanceof Error) log.warn(error.message);
3774
+ options?.onStatus?.("failed", projectPath);
3775
+ return "failed";
3876
3776
  }
3877
- if (!skipStagedMigration) rewriteLintStagedConfigFile(projectPath, report);
3878
- cleanupDeprecatedTsconfigOptions(projectPath, silent, report);
3879
- rewriteTsconfigTypes(projectPath, silent, report);
3880
- mergeViteConfigFiles(projectPath, silent, report);
3881
- injectLintTypeCheckDefaults(projectPath, silent, report);
3882
- injectFmtDefaults(projectPath, silent, report);
3883
- mergeTsdownConfigFile(projectPath, silent, report);
3884
- rewriteAllImports(projectPath, silent, report);
3885
- setPackageManager(projectPath, workspaceInfo.downloadPackageManager);
3777
+ options?.onStatus?.("fixed", projectPath);
3778
+ return "fixed";
3886
3779
  }
3887
- /**
3888
- * Rewrite monorepo to add vite-plus dependencies
3889
- * @param workspaceInfo - The workspace info
3890
- */
3891
- function rewriteMonorepo(workspaceInfo, skipStagedMigration, silent = false, report) {
3892
- const catalogDependencyResolver = createCatalogDependencyResolver(workspaceInfo.rootDir, workspaceInfo.packageManager);
3893
- if (workspaceInfo.packageManager === PackageManager.pnpm) rewritePnpmWorkspaceYaml(workspaceInfo.rootDir);
3894
- else if (workspaceInfo.packageManager === PackageManager.yarn) rewriteYarnrcYml(workspaceInfo.rootDir);
3895
- else if (workspaceInfo.packageManager === PackageManager.bun) rewriteBunCatalog(workspaceInfo.rootDir);
3896
- rewriteRootWorkspacePackageJson(workspaceInfo.rootDir, workspaceInfo.packageManager, skipStagedMigration, catalogDependencyResolver);
3897
- for (const pkg of workspaceInfo.packages) rewriteMonorepoProject(path.join(workspaceInfo.rootDir, pkg.path), workspaceInfo.packageManager, skipStagedMigration, silent, report, catalogDependencyResolver);
3898
- if (!skipStagedMigration) rewriteLintStagedConfigFile(workspaceInfo.rootDir, report);
3899
- cleanupDeprecatedTsconfigOptions(workspaceInfo.rootDir, silent, report);
3900
- rewriteTsconfigTypes(workspaceInfo.rootDir, silent, report);
3901
- mergeViteConfigFiles(workspaceInfo.rootDir, silent, report);
3902
- injectLintTypeCheckDefaults(workspaceInfo.rootDir, silent, report);
3903
- injectFmtDefaults(workspaceInfo.rootDir, silent, report);
3904
- mergeTsdownConfigFile(workspaceInfo.rootDir, silent, report);
3905
- rewriteAllImports(workspaceInfo.rootDir, silent, report);
3906
- setPackageManager(workspaceInfo.rootDir, workspaceInfo.downloadPackageManager);
3907
- }
3908
- /**
3909
- * Rewrite monorepo project to add vite-plus dependencies
3910
- * @param projectPath - The path to the project
3911
- */
3912
- function rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration, silent = false, report, catalogDependencyResolver) {
3913
- cleanupDeprecatedTsconfigOptions(projectPath, silent, report);
3914
- rewriteTsconfigTypes(projectPath, silent, report);
3915
- mergeViteConfigFiles(projectPath, silent, report);
3916
- mergeTsdownConfigFile(projectPath, silent, report);
3917
- const packageJsonPath = path.join(projectPath, "package.json");
3918
- if (!fs.existsSync(packageJsonPath)) return;
3919
- let extractedStagedConfig = null;
3920
- editJsonFile(packageJsonPath, (pkg) => {
3921
- extractedStagedConfig = rewritePackageJson(pkg, packageManager, true, skipStagedMigration, catalogDependencyResolver);
3922
- return pkg;
3923
- });
3924
- if (extractedStagedConfig) {
3925
- if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) removeLintStagedFromPackageJson(packageJsonPath);
3780
+ function removeDeprecatedTsconfigFalseOption(filePath, optionName) {
3781
+ let text;
3782
+ try {
3783
+ text = fs.readFileSync(filePath, "utf-8");
3784
+ } catch {
3785
+ return false;
3926
3786
  }
3787
+ if (parse(text)?.compilerOptions?.[optionName] !== false) return false;
3788
+ const edits = modify(text, ["compilerOptions", optionName], void 0, {});
3789
+ if (edits.length === 0) return false;
3790
+ const newText = applyEdits(text, edits);
3791
+ fs.writeFileSync(filePath, newText);
3792
+ return true;
3927
3793
  }
3928
- /**
3929
- * Rewrite pnpm-workspace.yaml to add vite-plus dependencies
3930
- * @param projectPath - The path to the project
3931
- */
3932
- function rewritePnpmWorkspaceYaml(projectPath) {
3933
- const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
3934
- if (!fs.existsSync(pnpmWorkspaceYamlPath)) fs.writeFileSync(pnpmWorkspaceYamlPath, "");
3935
- editYamlFile(pnpmWorkspaceYamlPath, (doc) => {
3936
- rewriteCatalog(doc);
3937
- const overrides = doc.getIn(["overrides"]);
3938
- for (const key of Object.keys(VITE_PLUS_OVERRIDE_PACKAGES)) {
3939
- const version = getCatalogDependencySpec(getYamlMapScalarStringValue(overrides, key), VITE_PLUS_OVERRIDE_PACKAGES[key], true);
3940
- doc.setIn(["overrides", scalarString(key)], scalarString(version));
3941
- }
3942
- const updatedOverrides = doc.getIn(["overrides"]);
3943
- for (const item of updatedOverrides.items) if (item.key.value.includes(">")) {
3944
- const splits = item.key.value.split(">");
3945
- if (splits[splits.length - 1].trim() === "vite") updatedOverrides.delete(item.key);
3946
- }
3947
- let allowAny = doc.getIn(["peerDependencyRules", "allowAny"]);
3948
- if (!allowAny) allowAny = new import_dist.YAMLSeq();
3949
- const existing = new Set(allowAny.items.map((n) => n.value));
3950
- for (const key of Object.keys(VITE_PLUS_OVERRIDE_PACKAGES)) if (!existing.has(key)) allowAny.add(scalarString(key));
3951
- doc.setIn(["peerDependencyRules", "allowAny"], allowAny);
3952
- let allowedVersions = doc.getIn(["peerDependencyRules", "allowedVersions"]);
3953
- if (!allowedVersions) allowedVersions = new import_dist.YAMLMap();
3954
- for (const key of Object.keys(VITE_PLUS_OVERRIDE_PACKAGES)) allowedVersions.set(scalarString(key), scalarString("*"));
3955
- doc.setIn(["peerDependencyRules", "allowedVersions"], allowedVersions);
3956
- if (doc.has("minimumReleaseAge")) {
3957
- const excludes = [
3958
- "vite-plus",
3959
- "@voidzero-dev/*",
3960
- "oxlint",
3961
- "@oxlint/*",
3962
- "oxlint-tsgolint",
3963
- "@oxlint-tsgolint/*",
3964
- "oxfmt",
3965
- "@oxfmt/*"
3966
- ];
3967
- let minimumReleaseAgeExclude = doc.getIn(["minimumReleaseAgeExclude"]);
3968
- if (!minimumReleaseAgeExclude) minimumReleaseAgeExclude = new import_dist.YAMLSeq();
3969
- const existing = new Set(minimumReleaseAgeExclude.items.map((n) => n.value));
3970
- for (const exclude of excludes) if (!existing.has(exclude)) minimumReleaseAgeExclude.add(scalarString(exclude));
3971
- doc.setIn(["minimumReleaseAgeExclude"], minimumReleaseAgeExclude);
3972
- }
3973
- });
3974
- }
3975
- /**
3976
- * Clean up pnpm.overrides and peerDependencyRules from package.json when migrating
3977
- * to pnpm-workspace.yaml. Returns any remaining non-Vite overrides that need to be
3978
- * moved to pnpm-workspace.yaml.
3979
- */
3980
- function cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys) {
3981
- const catalogOverrides = {};
3982
- const overrides = pkg.pnpm?.overrides;
3983
- for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) {
3984
- const value = overrides?.[key];
3985
- if (value) {
3986
- if (overrideKeys.includes(key) && value.startsWith("catalog:")) catalogOverrides[key] = value;
3987
- delete overrides[key];
3988
- }
3989
- }
3990
- for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
3991
- const splits = key.split(">");
3992
- if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
3993
- }
3994
- let remaining;
3995
- if (Object.keys(catalogOverrides).length > 0) remaining = { ...catalogOverrides };
3996
- if (pkg.pnpm?.overrides && Object.keys(pkg.pnpm.overrides).length > 0) remaining = {
3997
- ...remaining,
3998
- ...pkg.pnpm.overrides
3999
- };
4000
- delete pkg.pnpm?.overrides;
4001
- cleanupPeerDependencyRules(pkg.pnpm?.peerDependencyRules, overrideKeys);
4002
- if (pkg.pnpm?.peerDependencyRules && Object.keys(pkg.pnpm.peerDependencyRules).length === 0) delete pkg.pnpm.peerDependencyRules;
4003
- if (pkg.pnpm && Object.keys(pkg.pnpm).length === 0) delete pkg.pnpm;
4004
- return remaining;
4005
- }
4006
- /**
4007
- * Move remaining non-Vite pnpm.overrides from package.json to pnpm-workspace.yaml.
4008
- * pnpm ignores workspace-level overrides when pnpm.overrides exists in package.json,
4009
- * so all overrides must live in pnpm-workspace.yaml.
4010
- */
4011
- function migratePnpmOverridesToWorkspaceYaml(projectPath, overrides) {
4012
- editYamlFile(path.join(projectPath, "pnpm-workspace.yaml"), (doc) => {
4013
- for (const [key, value] of Object.entries(overrides)) doc.setIn(["overrides", scalarString(key)], scalarString(value));
4014
- });
4015
- }
4016
- /**
4017
- * Remove only Vite-managed entries from peerDependencyRules, preserving custom ones.
4018
- */
4019
- function cleanupPeerDependencyRules(peerDependencyRules, overrideKeys) {
4020
- if (!peerDependencyRules) return;
4021
- if (Array.isArray(peerDependencyRules.allowAny)) {
4022
- peerDependencyRules.allowAny = peerDependencyRules.allowAny.filter((key) => !overrideKeys.includes(key));
4023
- if (peerDependencyRules.allowAny.length === 0) delete peerDependencyRules.allowAny;
4024
- }
4025
- if (peerDependencyRules.allowedVersions) {
4026
- for (const key of overrideKeys) delete peerDependencyRules.allowedVersions[key];
4027
- if (Object.keys(peerDependencyRules.allowedVersions).length === 0) delete peerDependencyRules.allowedVersions;
4028
- }
4029
- }
4030
- /**
4031
- * Rewrite .yarnrc.yml to add vite-plus dependencies
4032
- * @param projectPath - The path to the project
4033
- */
4034
- function rewriteYarnrcYml(projectPath) {
4035
- const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
4036
- if (!fs.existsSync(yarnrcYmlPath)) fs.writeFileSync(yarnrcYmlPath, "");
4037
- editYamlFile(yarnrcYmlPath, (doc) => {
4038
- if (!doc.has("nodeLinker")) doc.set("nodeLinker", "node-modules");
4039
- rewriteCatalog(doc);
4040
- });
4041
- }
4042
- /**
4043
- * Rewrite catalog in pnpm-workspace.yaml or .yarnrc.yml
4044
- * @param doc - The document to rewrite
4045
- */
4046
- function getCatalogDependencySpec(currentValue, version, supportCatalog, options) {
4047
- if (options?.dependencyField === "peerDependencies") {
4048
- if (currentValue?.startsWith("catalog:") && options.dependencyName) {
4049
- const resolved = options.catalogDependencyResolver?.(currentValue, options.dependencyName);
4050
- if (resolved && !isVitePlusOverrideSpec(resolved)) return resolved;
4051
- return PUBLIC_PEER_DEPENDENCY_FALLBACKS[options.dependencyName] ?? currentValue;
4052
- }
4053
- return currentValue ?? version;
4054
- }
4055
- if (options?.dependencyField === "optionalDependencies" && options?.packageManager === PackageManager.yarn) return version;
4056
- if (!supportCatalog || version.startsWith("file:")) return version;
4057
- return currentValue?.startsWith("catalog:") ? currentValue : "catalog:";
4058
- }
4059
- function isVitePlusOverrideSpec(value) {
4060
- return Object.values(VITE_PLUS_OVERRIDE_PACKAGES).includes(value) || value.startsWith("npm:@voidzero-dev/vite-plus-");
4061
- }
4062
- function createCatalogDependencyResolver(projectPath, packageManager) {
4063
- if (packageManager === PackageManager.pnpm) {
4064
- const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
4065
- if (!fs.existsSync(pnpmWorkspaceYamlPath)) return;
4066
- const doc = readYamlFile(pnpmWorkspaceYamlPath);
4067
- return createCatalogDependencyResolverFromCatalogs(doc?.catalog, doc?.catalogs);
4068
- }
4069
- if (packageManager === PackageManager.yarn) {
4070
- const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
4071
- if (!fs.existsSync(yarnrcYmlPath)) return;
4072
- const doc = readYamlFile(yarnrcYmlPath);
4073
- return createCatalogDependencyResolverFromCatalogs(doc?.catalog, doc?.catalogs);
4074
- }
4075
- if (packageManager === PackageManager.bun) {
4076
- const packageJsonPath = path.join(projectPath, "package.json");
4077
- if (!fs.existsSync(packageJsonPath)) return;
4078
- const pkg = readJsonFile(packageJsonPath);
4079
- const workspacesObj = pkg.workspaces && !Array.isArray(pkg.workspaces) ? pkg.workspaces : void 0;
4080
- return (catalogSpec, dependencyName) => {
4081
- const catalogName = catalogSpec.slice(8);
4082
- if (catalogName) return workspacesObj?.catalogs?.[catalogName]?.[dependencyName] ?? pkg.catalogs?.[catalogName]?.[dependencyName];
4083
- return workspacesObj?.catalog?.[dependencyName] ?? pkg.catalog?.[dependencyName];
4084
- };
4085
- }
4086
- }
4087
- function createCatalogDependencyResolverFromCatalogs(catalog, catalogs) {
4088
- return (catalogSpec, dependencyName) => {
4089
- const catalogName = catalogSpec.slice(8);
4090
- if (catalogName) return catalogs?.[catalogName]?.[dependencyName];
4091
- return catalog?.[dependencyName];
4092
- };
4093
- }
4094
- function getYamlMapScalarStringValue(map, key) {
4095
- if (!(map instanceof import_dist.YAMLMap)) return;
4096
- for (const item of map.items) if (item.key instanceof import_dist.Scalar && item.key.value === key && item.value instanceof import_dist.Scalar && typeof item.value.value === "string") return item.value.value;
4097
- }
4098
- function rewriteCatalog(doc) {
4099
- for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) {
4100
- if (value.startsWith("file:")) continue;
4101
- doc.setIn(["catalog", key], scalarString(value));
4102
- }
4103
- if (!VITE_PLUS_VERSION.startsWith("file:")) doc.setIn(["catalog", VITE_PLUS_NAME], scalarString(VITE_PLUS_VERSION));
4104
- for (const name of REMOVE_PACKAGES) {
4105
- const path = ["catalog", name];
4106
- if (doc.hasIn(path)) doc.deleteIn(path);
4107
- }
4108
- const catalogs = doc.getIn(["catalogs"]);
4109
- if (!(catalogs instanceof import_dist.YAMLMap)) return;
4110
- for (const item of catalogs.items) {
4111
- const catalogName = item.key instanceof import_dist.Scalar ? item.key.value : void 0;
4112
- if (typeof catalogName !== "string" || !(item.value instanceof import_dist.YAMLMap)) continue;
4113
- for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) {
4114
- const catalogPath = [
4115
- "catalogs",
4116
- catalogName,
4117
- key
4118
- ];
4119
- if (!value.startsWith("file:") && doc.hasIn(catalogPath)) doc.setIn(catalogPath, scalarString(value));
4120
- }
4121
- const vitePlusPath = [
4122
- "catalogs",
4123
- catalogName,
4124
- VITE_PLUS_NAME
4125
- ];
4126
- if (!VITE_PLUS_VERSION.startsWith("file:") && doc.hasIn(vitePlusPath)) doc.setIn(vitePlusPath, scalarString(VITE_PLUS_VERSION));
4127
- for (const name of REMOVE_PACKAGES) {
4128
- const catalogPath = [
4129
- "catalogs",
4130
- catalogName,
4131
- name
4132
- ];
4133
- if (doc.hasIn(catalogPath)) doc.deleteIn(catalogPath);
4134
- }
4135
- }
4136
- }
4137
- function rewriteCatalogObject(catalog, addMissing) {
4138
- for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) {
4139
- if (value.startsWith("file:") || !addMissing && !(key in catalog)) continue;
4140
- catalog[key] = value;
4141
- }
4142
- if (!VITE_PLUS_VERSION.startsWith("file:") && (addMissing || "vite-plus" in catalog)) catalog[VITE_PLUS_NAME] = VITE_PLUS_VERSION;
4143
- for (const name of REMOVE_PACKAGES) delete catalog[name];
4144
- }
4145
- function rewriteCatalogsObject(catalogs) {
4146
- for (const catalog of Object.values(catalogs)) rewriteCatalogObject(catalog, false);
4147
- }
4148
- /**
4149
- * Write catalog entries to root package.json for bun.
4150
- * Bun stores catalogs in package.json under the `catalog` key,
4151
- * unlike pnpm which uses pnpm-workspace.yaml.
4152
- * @see https://bun.sh/docs/pm/catalogs
4153
- */
4154
- function rewriteBunCatalog(projectPath) {
4155
- const packageJsonPath = path.join(projectPath, "package.json");
4156
- if (!fs.existsSync(packageJsonPath)) return;
4157
- editJsonFile(packageJsonPath, (pkg) => {
4158
- const workspacesObj = pkg.workspaces && !Array.isArray(pkg.workspaces) ? pkg.workspaces : void 0;
4159
- const useWorkspacesCatalog = workspacesObj?.catalog != null || pkg.catalog == null && workspacesObj?.catalogs != null;
4160
- const catalog = { ...useWorkspacesCatalog ? workspacesObj?.catalog : pkg.catalog };
4161
- rewriteCatalogObject(catalog, true);
4162
- if (useWorkspacesCatalog) {
4163
- workspacesObj.catalog = catalog;
4164
- if (pkg.catalog) rewriteCatalogObject(pkg.catalog, false);
4165
- } else {
4166
- pkg.catalog = catalog;
4167
- if (workspacesObj?.catalog) rewriteCatalogObject(workspacesObj.catalog, false);
4168
- }
4169
- if (workspacesObj?.catalogs) rewriteCatalogsObject(workspacesObj.catalogs);
4170
- if (pkg.catalogs) rewriteCatalogsObject(pkg.catalogs);
4171
- const overrides = { ...pkg.overrides };
4172
- for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) overrides[key] = getCatalogDependencySpec(overrides[key], value, true);
4173
- pkg.overrides = overrides;
4174
- return pkg;
4175
- });
4176
- }
4177
- /**
4178
- * Rewrite root workspace package.json to add vite-plus dependencies
4179
- * @param projectPath - The path to the project
4180
- */
4181
- function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStagedMigration, catalogDependencyResolver) {
4182
- const packageJsonPath = path.join(projectPath, "package.json");
4183
- if (!fs.existsSync(packageJsonPath)) return;
4184
- let remainingPnpmOverrides;
4185
- editJsonFile(packageJsonPath, (pkg) => {
4186
- if (packageManager === PackageManager.yarn) pkg.resolutions = {
4187
- ...pkg.resolutions,
4188
- ...VITE_PLUS_OVERRIDE_PACKAGES
4189
- };
4190
- else if (packageManager === PackageManager.npm) pkg.overrides = {
4191
- ...pkg.overrides,
4192
- ...VITE_PLUS_OVERRIDE_PACKAGES
4193
- };
4194
- else if (packageManager === PackageManager.bun) {} else if (packageManager === PackageManager.pnpm) {
4195
- const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
4196
- if (isForceOverrideMode()) pkg.pnpm = {
4197
- ...pkg.pnpm,
4198
- overrides: {
4199
- ...pkg.pnpm?.overrides,
4200
- ...VITE_PLUS_OVERRIDE_PACKAGES,
4201
- [VITE_PLUS_NAME]: VITE_PLUS_VERSION
4202
- }
4203
- };
4204
- else {
4205
- for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
4206
- remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
4207
- }
4208
- for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
4209
- const splits = key.split(">");
4210
- if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
4211
- }
4212
- }
4213
- if (!pkg.devDependencies?.["vite-plus"]) pkg.devDependencies = {
4214
- ...pkg.devDependencies,
4215
- [VITE_PLUS_NAME]: packageManager === PackageManager.npm || VITE_PLUS_VERSION.startsWith("file:") ? VITE_PLUS_VERSION : "catalog:"
4216
- };
4217
- return pkg;
4218
- });
4219
- if (remainingPnpmOverrides) migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
4220
- rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration, void 0, void 0, catalogDependencyResolver);
4221
- }
4222
- const RULES_YAML_PATH = path.join(rulesDir, "vite-tools.yml");
4223
- const PREPARE_RULES_YAML_PATH = path.join(rulesDir, "vite-prepare.yml");
4224
- let cachedRulesYaml;
4225
- let cachedRulesYamlNoLintStaged;
4226
- let cachedPrepareRulesYaml;
4227
- function readRulesYaml() {
4228
- cachedRulesYaml ??= fs.readFileSync(RULES_YAML_PATH, "utf8");
4229
- return cachedRulesYaml;
4230
- }
4231
- function getScriptRulesYaml(skipStagedMigration) {
4232
- const yaml = readRulesYaml();
4233
- if (!skipStagedMigration) return yaml;
4234
- cachedRulesYamlNoLintStaged ??= yaml.split("\n\n\n").filter((block) => !block.includes("id: replace-lint-staged")).join("\n\n\n");
4235
- return cachedRulesYamlNoLintStaged;
4236
- }
4237
- function readPrepareRulesYaml() {
4238
- cachedPrepareRulesYaml ??= fs.readFileSync(PREPARE_RULES_YAML_PATH, "utf8");
4239
- return cachedPrepareRulesYaml;
4240
- }
4241
- function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration, catalogDependencyResolver) {
4242
- if (pkg.scripts) {
4243
- const updated = rewriteScripts(JSON.stringify(pkg.scripts), getScriptRulesYaml(skipStagedMigration));
4244
- if (updated) pkg.scripts = JSON.parse(updated);
4245
- }
4246
- let extractedStagedConfig = null;
4247
- if (!skipStagedMigration && pkg["lint-staged"]) {
4248
- const config = pkg["lint-staged"];
4249
- const updated = rewriteScripts(JSON.stringify(config), readRulesYaml());
4250
- extractedStagedConfig = updated ? JSON.parse(updated) : config;
4251
- }
4252
- const supportCatalog = !!isMonorepo && packageManager !== PackageManager.npm;
4253
- let needVitePlus = false;
4254
- const dependencyGroups = [
4255
- {
4256
- dependencyField: "devDependencies",
4257
- dependencies: pkg.devDependencies
4258
- },
4259
- {
4260
- dependencyField: "dependencies",
4261
- dependencies: pkg.dependencies
4262
- },
4263
- {
4264
- dependencyField: "peerDependencies",
4265
- dependencies: pkg.peerDependencies
4266
- },
4267
- {
4268
- dependencyField: "optionalDependencies",
4269
- dependencies: pkg.optionalDependencies
4270
- }
4271
- ];
4272
- for (const [key, version] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) for (const { dependencyField, dependencies } of dependencyGroups) if (dependencies?.[key]) {
4273
- dependencies[key] = getCatalogDependencySpec(dependencies[key], version, supportCatalog, {
4274
- dependencyField,
4275
- dependencyName: key,
4276
- packageManager,
4277
- catalogDependencyResolver
4278
- });
4279
- needVitePlus = true;
4280
- }
4281
- for (const name of REMOVE_PACKAGES) {
4282
- let wasRemoved = false;
4283
- for (const { dependencies } of dependencyGroups) if (dependencies?.[name]) {
4284
- delete dependencies[name];
4285
- wasRemoved = true;
4286
- }
4287
- if (wasRemoved) needVitePlus = true;
4288
- const peerDep = BROWSER_PROVIDER_PEER_DEPS[name];
4289
- if (wasRemoved && peerDep && !pkg.devDependencies?.[peerDep] && !pkg.dependencies?.[peerDep] && !pkg.peerDependencies?.[peerDep] && !pkg.optionalDependencies?.[peerDep]) {
4290
- pkg.devDependencies ??= {};
4291
- pkg.devDependencies[peerDep] = "*";
4292
- }
4293
- }
4294
- if (needVitePlus) {
4295
- const version = supportCatalog && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
4296
- pkg.devDependencies = {
4297
- ...pkg.devDependencies,
4298
- [VITE_PLUS_NAME]: version
4299
- };
4300
- const installableDeps = {
4301
- ...pkg.dependencies,
4302
- ...pkg.devDependencies,
4303
- ...pkg.optionalDependencies
4304
- };
4305
- if (!installableDeps.vitest && Object.keys(installableDeps).some((name) => name.includes("vitest"))) {
4306
- const ver = VITE_PLUS_OVERRIDE_PACKAGES.vitest;
4307
- pkg.devDependencies.vitest = getCatalogDependencySpec(void 0, ver, supportCatalog);
4308
- }
4309
- }
4310
- return extractedStagedConfig;
4311
- }
4312
- function removeLintStagedFromPackageJson(packageJsonPath) {
4313
- editJsonFile(packageJsonPath, (pkg) => {
4314
- if (pkg["lint-staged"]) {
4315
- delete pkg["lint-staged"];
4316
- return pkg;
4317
- }
4318
- });
4319
- }
4320
- function rewriteLintStagedConfigFile(projectPath, report) {
4321
- let hasUnsupported = false;
4322
- for (const filename of LINT_STAGED_JSON_CONFIG_FILES) {
4323
- const configPath = path.join(projectPath, filename);
4324
- if (!fs.existsSync(configPath)) continue;
4325
- if (filename === ".lintstagedrc" && !isJsonFile(configPath)) {
4326
- warnMigration(`${displayRelative(configPath)} is not JSON format — please migrate to "staged" in vite.config.ts manually`, report);
4327
- hasUnsupported = true;
4328
- continue;
4329
- }
4330
- if (!hasStagedConfigInViteConfig(projectPath)) {
4331
- const config = readJsonFile(configPath);
4332
- const updated = rewriteScripts(JSON.stringify(config), readRulesYaml());
4333
- if (!mergeStagedConfigToViteConfig(projectPath, updated ? JSON.parse(updated) : config, true, report)) continue;
4334
- fs.unlinkSync(configPath);
4335
- if (report) report.inlinedLintStagedConfigCount++;
4336
- } else warnMigration(`${displayRelative(configPath)} found but "staged" already exists in vite.config.ts — please merge manually`, report);
4337
- }
4338
- for (const filename of LINT_STAGED_OTHER_CONFIG_FILES) {
4339
- const configPath = path.join(projectPath, filename);
4340
- if (!fs.existsSync(configPath)) continue;
4341
- warnMigration(`${displayRelative(configPath)} — please migrate to "staged" in vite.config.ts manually`, report);
4342
- hasUnsupported = true;
4343
- }
4344
- if (hasUnsupported) infoMigration("Only \"staged\" in vite.config.ts is supported. See https://viteplus.dev/guide/migrate#lint-staged", report);
4345
- }
4346
- /**
4347
- * Ensure vite.config.ts exists, create it if not
4348
- * @returns The vite config filename
4349
- */
4350
- function ensureViteConfig(projectPath, configs, silent = false, report) {
4351
- if (!configs.viteConfig) {
4352
- configs.viteConfig = "vite.config.ts";
4353
- const viteConfigPath = path.join(projectPath, "vite.config.ts");
4354
- fs.writeFileSync(viteConfigPath, `import { defineConfig } from '${VITE_PLUS_NAME}';
4355
-
4356
- export default defineConfig({});
4357
- `);
4358
- if (report) report.createdViteConfigCount++;
4359
- if (!silent) log.success(`✔ Created vite.config.ts in ${displayRelative(viteConfigPath)}`);
4360
- }
4361
- return configs.viteConfig;
4362
- }
4363
- /**
4364
- * Merge tsdown.config.* into vite.config.ts
4365
- * - For JSON files: merge content directly into `pack` field and delete the JSON file
4366
- * - For TS/JS files: import the config file
4367
- */
4368
- function mergeTsdownConfigFile(projectPath, silent = false, report) {
4369
- const configs = detectConfigs(projectPath);
4370
- if (!configs.tsdownConfig) return;
4371
- const viteConfig = ensureViteConfig(projectPath, configs, silent, report);
4372
- const fullViteConfigPath = path.join(projectPath, viteConfig);
4373
- const fullTsdownConfigPath = path.join(projectPath, configs.tsdownConfig);
4374
- if (configs.tsdownConfig.endsWith(".json")) {
4375
- mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.tsdownConfig, "pack", silent, report);
4376
- return;
4377
- }
4378
- const result = mergeTsdownConfig(fullViteConfigPath, `./${configs.tsdownConfig}`);
4379
- if (result.updated) {
4380
- fs.writeFileSync(fullViteConfigPath, result.content);
4381
- if (report) report.tsdownImportCount++;
4382
- if (!silent) log.success(`✔ Added import for ${displayRelative(fullTsdownConfigPath)} in ${displayRelative(fullViteConfigPath)}`);
4383
- }
4384
- infoMigration(`Please manually merge ${displayRelative(fullTsdownConfigPath)} into ${displayRelative(fullViteConfigPath)}, see https://viteplus.dev/guide/migrate#tsdown`, report);
4385
- }
4386
- /**
4387
- * Merge oxlint and oxfmt config into vite.config.ts
4388
- */
4389
- function mergeViteConfigFiles(projectPath, silent = false, report) {
4390
- const configs = detectConfigs(projectPath);
4391
- if (!configs.oxfmtConfig && !configs.oxlintConfig) return;
4392
- const viteConfig = ensureViteConfig(projectPath, configs, silent, report);
4393
- if (configs.oxlintConfig) {
4394
- const fullOxlintPath = path.join(projectPath, configs.oxlintConfig);
4395
- const oxlintJson = readJsonFile(fullOxlintPath, true);
4396
- if (!oxlintJson.options) oxlintJson.options = {};
4397
- if (!hasBaseUrlInTsconfig(projectPath)) {
4398
- if (oxlintJson.options.typeAware === void 0) oxlintJson.options.typeAware = true;
4399
- if (oxlintJson.options.typeCheck === void 0) oxlintJson.options.typeCheck = true;
4400
- } else warnMigration(BASEURL_TSCONFIG_WARNING, report);
4401
- const normalizedOxlintConfig = ensureVitePlusImportRuleDefaults(oxlintJson);
4402
- fs.writeFileSync(fullOxlintPath, JSON.stringify(normalizedOxlintConfig, null, 2));
4403
- mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.oxlintConfig, "lint", silent, report);
4404
- }
4405
- if (configs.oxfmtConfig) mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.oxfmtConfig, "fmt", silent, report);
4406
- }
4407
- /**
4408
- * Inject typeAware and typeCheck defaults into vite.config.ts lint config.
4409
- * Called after mergeViteConfigFiles() to handle the case where no .oxlintrc.json exists
4410
- * (e.g., newly created projects from create-vite templates).
4411
- */
4412
- function injectLintTypeCheckDefaults(projectPath, silent = false, report) {
4413
- if (hasBaseUrlInTsconfig(projectPath)) return;
4414
- injectConfigDefaults(projectPath, "lint", ".vite-plus-lint-init.oxlintrc.json", JSON.stringify(createDefaultVitePlusLintConfig({ includeTypeAwareDefaults: true })), silent, report);
4415
- }
4416
- function injectFmtDefaults(projectPath, silent = false, report) {
4417
- injectConfigDefaults(projectPath, "fmt", ".vite-plus-fmt-init.oxfmtrc.json", JSON.stringify({}), silent, report);
4418
- }
4419
- /**
4420
- * Wire `create.defaultTemplate: '<scope>'` into the new monorepo's
4421
- * `vite.config.ts`. The caller is `bin.ts`, only when scaffolding a
4422
- * monorepo from a bundled `@org` manifest entry — that's the case where
4423
- * the user just picked a template from a specific org and naturally
4424
- * wants subsequent `vp create` invocations from the workspace to default
4425
- * to that same org's picker.
4426
- */
4427
- function injectCreateDefaultTemplate(projectPath, scope, silent = false, report) {
4428
- if (!scope) return;
4429
- injectConfigDefaults(projectPath, "create", ".vite-plus-create-init.json", JSON.stringify({ defaultTemplate: scope }), silent, report);
4430
- }
4431
- function injectConfigDefaults(projectPath, configKey, tempFileName, tempFileContent, silent, report) {
4432
- const configs = detectConfigs(projectPath);
4433
- if (configs.viteConfig && hasConfigKey(path.join(projectPath, configs.viteConfig), configKey)) return;
4434
- const viteConfig = ensureViteConfig(projectPath, configs, silent, report);
4435
- const tempConfigPath = path.join(projectPath, tempFileName);
4436
- fs.writeFileSync(tempConfigPath, tempFileContent);
4437
- const fullViteConfigPath = path.join(projectPath, viteConfig);
4438
- let result;
3794
+ function rewriteTypesInTsconfig(filePath) {
3795
+ let text;
4439
3796
  try {
4440
- result = mergeJsonConfig(fullViteConfigPath, tempConfigPath, configKey);
4441
- } finally {
4442
- fs.rmSync(tempConfigPath, { force: true });
4443
- }
4444
- if (result.updated) fs.writeFileSync(fullViteConfigPath, result.content);
4445
- }
4446
- function mergeAndRemoveJsonConfig(projectPath, viteConfigPath, jsonConfigPath, configKey, silent = false, report) {
4447
- const fullViteConfigPath = path.join(projectPath, viteConfigPath);
4448
- const fullJsonConfigPath = path.join(projectPath, jsonConfigPath);
4449
- if (hasConfigKey(fullViteConfigPath, configKey)) {
4450
- fs.unlinkSync(fullJsonConfigPath);
4451
- if (!silent) log.info(`${configKey} config already present in ${displayRelative(fullViteConfigPath)} — removed redundant ${displayRelative(fullJsonConfigPath)}`);
4452
- return;
4453
- }
4454
- const result = mergeJsonConfig(fullViteConfigPath, fullJsonConfigPath, configKey);
4455
- if (result.updated) {
4456
- fs.writeFileSync(fullViteConfigPath, result.content);
4457
- fs.unlinkSync(fullJsonConfigPath);
4458
- if (report) report.mergedConfigCount++;
4459
- if (!silent) log.success(`✔ Merged ${displayRelative(fullJsonConfigPath)} into ${displayRelative(fullViteConfigPath)}`);
4460
- } else {
4461
- warnMigration(`Failed to merge ${displayRelative(fullJsonConfigPath)} into ${displayRelative(fullViteConfigPath)}`, report);
4462
- infoMigration("Please complete the merge manually and follow the instructions in the documentation: https://viteplus.dev/config/", report);
4463
- }
4464
- }
4465
- /**
4466
- * Merge a staged config object into vite.config.ts as `staged: { ... }`.
4467
- * Writes the config to a temp JSON file, calls mergeJsonConfig NAPI, then cleans up.
4468
- */
4469
- function mergeStagedConfigToViteConfig(projectPath, stagedConfig, silent = false, report) {
4470
- const viteConfig = ensureViteConfig(projectPath, detectConfigs(projectPath), silent, report);
4471
- const fullViteConfigPath = path.join(projectPath, viteConfig);
4472
- const tempJsonPath = path.join(projectPath, ".staged-config-temp.json");
4473
- fs.writeFileSync(tempJsonPath, JSON.stringify(stagedConfig, null, 2));
4474
- let result;
4475
- try {
4476
- result = mergeJsonConfig(fullViteConfigPath, tempJsonPath, "staged");
4477
- } finally {
4478
- fs.unlinkSync(tempJsonPath);
4479
- }
4480
- if (result.updated) {
4481
- fs.writeFileSync(fullViteConfigPath, result.content);
4482
- if (report) report.mergedStagedConfigCount++;
4483
- if (!silent) log.success(`✔ Merged staged config into ${displayRelative(fullViteConfigPath)}`);
4484
- return true;
4485
- } else {
4486
- warnMigration(`Failed to merge staged config into ${displayRelative(fullViteConfigPath)}`, report);
4487
- infoMigration(`Please add staged config to ${displayRelative(fullViteConfigPath)} manually, see https://viteplus.dev/guide/migrate#lint-staged`, report);
4488
- return false;
4489
- }
4490
- }
4491
- /**
4492
- * Check if vite.config.ts already has a `staged` config key.
4493
- */
4494
- function hasStagedConfigInViteConfig(projectPath) {
4495
- const configs = detectConfigs(projectPath);
4496
- if (!configs.viteConfig) return false;
4497
- const viteConfigPath = path.join(projectPath, configs.viteConfig);
4498
- const content = fs.readFileSync(viteConfigPath, "utf8");
4499
- return /\bstaged\s*:/.test(content);
4500
- }
4501
- /**
4502
- * Rewrite imports in all TypeScript/JavaScript files under a directory
4503
- * This rewrites vite/vitest imports to @voidzero-dev/vite-plus
4504
- * @param projectPath - The root directory to search for files
4505
- */
4506
- function rewriteAllImports(projectPath, silent = false, report) {
4507
- const result = rewriteImportsInDirectory(projectPath);
4508
- const modified = result.modifiedFiles.length;
4509
- const errors = result.errors.length;
4510
- if (report) {
4511
- report.rewrittenImportFileCount += modified;
4512
- report.rewrittenImportErrors.push(...result.errors.map((error) => ({
4513
- path: displayRelative(error.path),
4514
- message: error.message
4515
- })));
4516
- }
4517
- if (!silent && modified > 0) {
4518
- log.success(`Rewrote imports in ${modified === 1 ? "one file" : `${modified} files`}`);
4519
- log.info(result.modifiedFiles.map((file) => ` ${displayRelative(file)}`).join("\n"));
4520
- }
4521
- if (errors > 0) if (report) warnMigration(`${errors === 1 ? "one file had an error" : `${errors} files had errors`} while rewriting imports`, report);
4522
- else {
4523
- log.warn(`⚠ ${errors === 1 ? "one file had an error" : `${errors} files had errors`}:`);
4524
- for (const error of result.errors) log.error(` ${displayRelative(error.path)}: ${error.message}`);
4525
- }
4526
- }
4527
- /**
4528
- * Check if the project has an unsupported husky version (<9.0.0).
4529
- * Uses `semver.coerce` to handle ranges like `^8.0.0` → `8.0.0`.
4530
- * When the specifier is not coercible (e.g. `"latest"`), falls back to
4531
- * the installed version in node_modules via `detectPackageMetadata`.
4532
- * Returns a reason string if hooks migration should be skipped, or null
4533
- * if husky is absent or compatible.
4534
- */
4535
- function checkUnsupportedHuskyVersion(projectPath, deps, prodDeps) {
4536
- const huskyVersion = deps?.husky ?? prodDeps?.husky;
4537
- if (!huskyVersion) return null;
4538
- let coerced = import_semver.default.coerce(huskyVersion);
4539
- if (coerced == null) {
4540
- const installed = detectPackageMetadata(projectPath, "husky");
4541
- if (installed) coerced = import_semver.default.coerce(installed.version);
4542
- if (coerced == null) return `Could not determine husky version from "${huskyVersion}" — please specify a semver-compatible version (e.g., "^9.0.0") and re-run migration.`;
4543
- }
4544
- if (import_semver.default.satisfies(coerced, "<9.0.0")) return "Detected husky <9.0.0 — please upgrade to husky v9+ first, then re-run migration.";
4545
- return null;
4546
- }
4547
- const OTHER_HOOK_TOOLS = [
4548
- "simple-git-hooks",
4549
- "lefthook",
4550
- "yorkie"
4551
- ];
4552
- const REPLACED_HOOK_PACKAGES = ["husky", "lint-staged"];
4553
- function removeReplacedHookPackages(packageJsonPath) {
4554
- editJsonFile(packageJsonPath, (pkg) => {
4555
- for (const name of REPLACED_HOOK_PACKAGES) {
4556
- if (pkg.devDependencies?.[name]) delete pkg.devDependencies[name];
4557
- if (pkg.dependencies?.[name]) delete pkg.dependencies[name];
4558
- }
4559
- return pkg;
4560
- });
4561
- }
4562
- /**
4563
- * Walk up from `startPath` looking for `.git` (directory or file — submodules
4564
- * use a `.git` file). Returns the directory that contains `.git`, or `null`.
4565
- */
4566
- function findGitRoot(startPath) {
4567
- let dir = startPath;
4568
- while (true) {
4569
- if (fs.existsSync(path.join(dir, ".git"))) return dir;
4570
- const parent = path.dirname(dir);
4571
- if (parent === dir) return null;
4572
- dir = parent;
4573
- }
4574
- }
4575
- /**
4576
- * Normalize "husky install [dir]" → "husky [dir]" so downstream regex
4577
- * and ast-grep rules can match a single pattern.
4578
- */
4579
- function collapseHuskyInstall(script) {
4580
- return script.replace("husky install ", "husky ").replace("husky install", "husky");
4581
- }
4582
- /**
4583
- * High-level helper: detect old hooks dir, set up git hooks, and rewrite
4584
- * the prepare script. Returns true if hooks were successfully installed.
4585
- */
4586
- function installGitHooks(projectPath, silent = false, report) {
4587
- if (setupGitHooks(projectPath, getOldHooksDir(projectPath), silent, report)) {
4588
- rewritePrepareScript(projectPath);
4589
- return true;
4590
- }
4591
- return false;
4592
- }
4593
- /**
4594
- * Read-only probe: extract the old husky hooks directory from `scripts.prepare`
4595
- * without modifying package.json. Returns undefined when no husky reference is found.
4596
- */
4597
- function getOldHooksDir(rootDir) {
4598
- const packageJsonPath = path.join(rootDir, "package.json");
4599
- if (!fs.existsSync(packageJsonPath)) return;
4600
- const pkg = readJsonFile(packageJsonPath);
4601
- if (!pkg.scripts?.prepare) return;
4602
- const match = collapseHuskyInstall(pkg.scripts.prepare).match(/\bhusky(?:\s+([\w./-]+))?/);
4603
- if (!match) return;
4604
- return match[1] ?? ".husky";
4605
- }
4606
- /**
4607
- * Pre-flight check: verify that git hooks can be set up for this project.
4608
- * Returns `null` if hooks setup can proceed, or a warning reason string
4609
- * explaining why hooks setup should be skipped.
4610
- *
4611
- * These checks are deterministic and read-only — they do not modify
4612
- * the project in any way, making them safe to call before migration.
4613
- */
4614
- function preflightGitHooksSetup(projectPath) {
4615
- const gitRoot = findGitRoot(projectPath);
4616
- if (gitRoot && path.resolve(projectPath) !== path.resolve(gitRoot)) return "Subdirectory project detected — skipping git hooks setup. Configure hooks at the repository root.";
4617
- const packageJsonPath = path.join(projectPath, "package.json");
4618
- if (!fs.existsSync(packageJsonPath)) return null;
4619
- const pkgContent = readJsonFile(packageJsonPath);
4620
- const deps = pkgContent.devDependencies;
4621
- const prodDeps = pkgContent.dependencies;
4622
- for (const tool of OTHER_HOOK_TOOLS) if (deps?.[tool] || prodDeps?.[tool] || pkgContent[tool]) return `Detected ${tool} — skipping git hooks setup. Please configure git hooks manually.`;
4623
- const huskyReason = checkUnsupportedHuskyVersion(projectPath, deps, prodDeps);
4624
- if (huskyReason) return huskyReason;
4625
- if (hasUnsupportedLintStagedConfig(projectPath)) return "Unsupported lint-staged config format — skipping git hooks setup. Please configure git hooks manually.";
4626
- return null;
4627
- }
4628
- /**
4629
- * Set up git hooks with husky + lint-staged via vp commands.
4630
- * Skips if another hook tool is detected (warns user).
4631
- * Returns true if hooks were successfully set up, false if skipped.
4632
- */
4633
- function setupGitHooks(projectPath, oldHooksDir, silent = false, report) {
4634
- const reason = preflightGitHooksSetup(projectPath);
4635
- if (reason) {
4636
- warnMigration(reason, report);
4637
- return false;
4638
- }
4639
- const packageJsonPath = path.join(projectPath, "package.json");
4640
- if (!fs.existsSync(packageJsonPath)) return false;
4641
- const gitRoot = findGitRoot(projectPath);
4642
- const isCustomDir = oldHooksDir != null && oldHooksDir !== ".husky";
4643
- const hooksDir = isCustomDir ? oldHooksDir : ".vite-hooks";
4644
- editJsonFile(packageJsonPath, (pkg) => {
4645
- if (!pkg.scripts) pkg.scripts = {};
4646
- if (!pkg.scripts.prepare) pkg.scripts.prepare = "vp config";
4647
- else if (!pkg.scripts.prepare.includes("vp config") && !/\bhusky\b/.test(pkg.scripts.prepare)) pkg.scripts.prepare = `vp config && ${pkg.scripts.prepare}`;
4648
- return pkg;
4649
- });
4650
- let stagedMerged = hasStagedConfigInViteConfig(projectPath);
4651
- const hasStandaloneConfig = hasStandaloneLintStagedConfig(projectPath);
4652
- if (!stagedMerged && !hasStandaloneConfig) {
4653
- const stagedConfig = readJsonFile(packageJsonPath)?.["lint-staged"] ?? DEFAULT_STAGED_CONFIG;
4654
- const updated = rewriteScripts(JSON.stringify(stagedConfig), readRulesYaml());
4655
- stagedMerged = mergeStagedConfigToViteConfig(projectPath, updated ? JSON.parse(updated) : stagedConfig, silent, report);
4656
- }
4657
- if (stagedMerged) removeLintStagedFromPackageJson(packageJsonPath);
4658
- if (oldHooksDir && !isCustomDir) {
4659
- const oldDir = path.join(projectPath, oldHooksDir);
4660
- if (fs.existsSync(oldDir)) {
4661
- const targetDir = path.join(projectPath, hooksDir);
4662
- fs.mkdirSync(targetDir, { recursive: true });
4663
- for (const entry of fs.readdirSync(oldDir, { withFileTypes: true })) {
4664
- if (entry.isDirectory() || entry.name.startsWith(".")) continue;
4665
- const src = path.join(oldDir, entry.name);
4666
- const dest = path.join(targetDir, entry.name);
4667
- fs.copyFileSync(src, dest);
4668
- fs.chmodSync(dest, 493);
4669
- }
4670
- fs.rmSync(oldDir, {
4671
- recursive: true,
4672
- force: true
4673
- });
4674
- }
4675
- }
4676
- if (stagedMerged) createPreCommitHook(projectPath, hooksDir);
4677
- if (!gitRoot) {
4678
- removeReplacedHookPackages(packageJsonPath);
4679
- return true;
4680
- }
4681
- if (oldHooksDir) {
4682
- const checkResult = import_cross_spawn.default.sync("git", [
4683
- "config",
4684
- "--local",
4685
- "core.hooksPath"
4686
- ], {
4687
- cwd: projectPath,
4688
- stdio: "pipe"
4689
- });
4690
- const existingPath = checkResult.status === 0 ? checkResult.stdout?.toString().trim() : "";
4691
- if (existingPath === `${oldHooksDir}/_` || existingPath === oldHooksDir) import_cross_spawn.default.sync("git", [
4692
- "config",
4693
- "--local",
4694
- "--unset",
4695
- "core.hooksPath"
4696
- ], {
4697
- cwd: projectPath,
4698
- stdio: "pipe"
4699
- });
4700
- }
4701
- const vpBin = process.env.VP_CLI_BIN ?? "vp";
4702
- const configArgs = isCustomDir ? [
4703
- "config",
4704
- "--hooks-only",
4705
- "--hooks-dir",
4706
- hooksDir
4707
- ] : ["config", "--hooks-only"];
4708
- const configResult = import_cross_spawn.default.sync(vpBin, configArgs, {
4709
- cwd: projectPath,
4710
- stdio: "pipe"
4711
- });
4712
- if (configResult.status === 0) {
4713
- const stdout = configResult.stdout?.toString().trim() ?? "";
4714
- if (stdout) {
4715
- warnMigration(`Git hooks not configured — ${stdout}`, report);
4716
- return false;
4717
- }
4718
- removeReplacedHookPackages(packageJsonPath);
4719
- if (report) report.gitHooksConfigured = true;
4720
- if (!silent) log.success("✔ Git hooks configured");
4721
- return true;
4722
- }
4723
- warnMigration("Failed to install git hooks", report);
4724
- return false;
4725
- }
4726
- /**
4727
- * Check if a standalone lint-staged config file exists
4728
- */
4729
- function hasStandaloneLintStagedConfig(projectPath) {
4730
- return LINT_STAGED_ALL_CONFIG_FILES.some((file) => fs.existsSync(path.join(projectPath, file)));
4731
- }
4732
- /**
4733
- * Check if a standalone lint-staged config exists in a format that can't be
4734
- * auto-migrated to "staged" in vite.config.ts (non-JSON files like .yaml,
4735
- * .mjs, .cjs, .js, or a non-JSON .lintstagedrc).
4736
- */
4737
- function hasUnsupportedLintStagedConfig(projectPath) {
4738
- for (const filename of LINT_STAGED_OTHER_CONFIG_FILES) if (fs.existsSync(path.join(projectPath, filename))) return true;
4739
- const lintstagedrcPath = path.join(projectPath, ".lintstagedrc");
4740
- if (fs.existsSync(lintstagedrcPath) && !isJsonFile(lintstagedrcPath)) return true;
4741
- return false;
4742
- }
4743
- /**
4744
- * Create pre-commit hook file in the hooks directory.
4745
- */
4746
- const STALE_LINT_STAGED_PATTERNS = [/^((?:[A-Z_][A-Z0-9_]*(?:=\S*)?\s+)*)(pnpm|pnpm exec|npx|yarn|yarn run|npm exec|npm run|bunx|bun run|bun x)\s+lint-staged\b/, /^((?:[A-Z_][A-Z0-9_]*(?:=\S*)?\s+)*)lint-staged\b/];
4747
- const DEFAULT_STAGED_CONFIG = { "*": "vp check --fix" };
4748
- /**
4749
- * Ensure the pre-commit hook exists with `vp staged`, and that
4750
- * vite.config.ts contains a `staged` block (using the default config
4751
- * if none is present). Called by `vp config` after hook installation.
4752
- */
4753
- function ensurePreCommitHook(projectPath, dir = ".vite-hooks") {
4754
- if (!hasStagedConfigInViteConfig(projectPath)) mergeStagedConfigToViteConfig(projectPath, DEFAULT_STAGED_CONFIG, true);
4755
- createPreCommitHook(projectPath, dir);
4756
- }
4757
- function createPreCommitHook(projectPath, dir = ".vite-hooks") {
4758
- const huskyDir = path.join(projectPath, dir);
4759
- fs.mkdirSync(huskyDir, { recursive: true });
4760
- const hookPath = path.join(huskyDir, "pre-commit");
4761
- if (fs.existsSync(hookPath)) {
4762
- const existing = fs.readFileSync(hookPath, "utf8");
4763
- if (existing.includes("vp staged")) return;
4764
- const lines = existing.split("\n");
4765
- let replaced = false;
4766
- const result = [];
4767
- for (const line of lines) {
4768
- const trimmed = line.trim();
4769
- if (!replaced) {
4770
- let matched = false;
4771
- for (const pattern of STALE_LINT_STAGED_PATTERNS) {
4772
- const match = pattern.exec(trimmed);
4773
- if (match) {
4774
- const parts = [
4775
- match[1]?.trim() ?? "",
4776
- "vp staged",
4777
- trimmed.slice(match[0].length).trim()
4778
- ].filter(Boolean);
4779
- result.push(parts.join(" "));
4780
- replaced = true;
4781
- matched = true;
4782
- break;
4783
- }
4784
- }
4785
- if (matched) continue;
4786
- }
4787
- result.push(line);
4788
- }
4789
- if (!replaced) fs.writeFileSync(hookPath, `${result.join("\n").trimEnd()}\nvp staged\n`);
4790
- else fs.writeFileSync(hookPath, result.join("\n"));
4791
- } else {
4792
- fs.writeFileSync(hookPath, "vp staged\n");
4793
- fs.chmodSync(hookPath, 493);
4794
- }
4795
- }
4796
- /**
4797
- * Rewrite only `scripts.prepare` in the root package.json using vite-prepare.yml rules.
4798
- * Collapses "husky install" → "husky" before applying ast-grep so that the
4799
- * replace-husky rule produces "vp config" with any directory argument preserved.
4800
- * Returns the old husky hooks dir (if any) for migration to .vite-hooks.
4801
- * Called only when hooks are being set up (not with --no-hooks).
4802
- */
4803
- function rewritePrepareScript(rootDir) {
4804
- const packageJsonPath = path.join(rootDir, "package.json");
4805
- if (!fs.existsSync(packageJsonPath)) return;
4806
- let oldDir;
4807
- editJsonFile(packageJsonPath, (pkg) => {
4808
- if (!pkg.scripts?.prepare) return pkg;
4809
- const prepare = collapseHuskyInstall(pkg.scripts.prepare);
4810
- const updated = rewriteScripts(JSON.stringify({ prepare }), readPrepareRulesYaml());
4811
- if (updated) {
4812
- let newPrepare = JSON.parse(updated).prepare;
4813
- newPrepare = newPrepare.replace(/\bvp config(?:\s+(?!-)([\w./-]+))?/, (_match, dir) => {
4814
- oldDir = dir ?? ".husky";
4815
- return dir ? `vp config --hooks-dir ${dir}` : "vp config";
4816
- });
4817
- pkg.scripts.prepare = newPrepare;
4818
- } else if (prepare !== pkg.scripts.prepare) pkg.scripts.prepare = prepare;
4819
- return pkg;
4820
- });
4821
- return oldDir;
4822
- }
4823
- function setPackageManager(projectDir, downloadPackageManager) {
4824
- editJsonFile(path.join(projectDir, "package.json"), (pkg) => {
4825
- if (!pkg.packageManager) pkg.packageManager = `${downloadPackageManager.name}@${downloadPackageManager.version}`;
4826
- return pkg;
4827
- });
4828
- }
4829
- /**
4830
- * Detect a .nvmrc file in the project directory.
4831
- * If not found, check for a Volta node version in package.json.
4832
- * If either is found, return the relevant info for migration.
4833
- * Returns undefined if not found or .node-version already exists.
4834
- */
4835
- function detectNodeVersionManagerFile(projectPath) {
4836
- if (fs.existsSync(path.join(projectPath, ".node-version"))) return;
4837
- const configs = detectConfigs(projectPath);
4838
- if (configs.nvmrcFile) return configs.voltaNode ? {
4839
- file: ".nvmrc",
4840
- voltaPresent: true
4841
- } : { file: ".nvmrc" };
4842
- if (configs.voltaNode) return {
4843
- file: "package.json",
4844
- voltaNodeVersion: configs.voltaNode
4845
- };
4846
- }
4847
- /**
4848
- * Parse a version alias from a .nvmrc file into a .node-version compatible string.
4849
- * Accepts the first line of .nvmrc (pre-trimmed).
4850
- * Returns null for unsupported aliases like "system", "default", "iojs".
4851
- */
4852
- function parseNvmrcVersion(alias) {
4853
- const version = alias.trim();
4854
- if (!version) return null;
4855
- if (version === "node" || version === "stable") return "lts/*";
4856
- if (version === "iojs" || version === "system" || version === "default") return null;
4857
- if (version.startsWith("lts/")) return version;
4858
- const normalized = version.startsWith("v") ? version.slice(1) : version;
4859
- if (!normalized || !import_semver.default.validRange(normalized)) return null;
4860
- return normalized;
4861
- }
4862
- /**
4863
- * Migrate .nvmrc or Volta node version from package.json to .node-version.
4864
- * - For .nvmrc: the source file is removed after migration.
4865
- * - For package.json (Volta): the volta field is left as-is; removal is left to the user's discretion.
4866
- * Returns true on success, false if migration was skipped or failed.
4867
- */
4868
- function migrateNodeVersionManagerFile(projectPath, detection, report) {
4869
- const nodeVersionPath = path.join(projectPath, ".node-version");
4870
- if (detection.file === "package.json") {
4871
- const { voltaNodeVersion } = detection;
4872
- const resolvedVersion = voltaNodeVersion === "lts" ? "lts/*" : voltaNodeVersion;
4873
- if (!import_semver.default.valid(resolvedVersion) && resolvedVersion !== "lts/*") {
4874
- warnMigration(`package.json volta.node "${voltaNodeVersion}" is not an exact version. Pin an exact version (e.g. ${voltaNodeVersion}.0 or run \`volta pin node@${voltaNodeVersion}\`) then re-run migration.`, report);
4875
- return false;
4876
- }
4877
- fs.writeFileSync(nodeVersionPath, `${resolvedVersion}\n`);
4878
- if (report) {
4879
- report.manualSteps.push("Remove the \"volta\" field from package.json");
4880
- report.nodeVersionFileMigrated = true;
4881
- } else log.info("You can now remove the \"volta\" field from package.json manually.");
4882
- return true;
4883
- }
4884
- const sourcePath = path.join(projectPath, ".nvmrc");
4885
- const originalAlias = fs.readFileSync(sourcePath, "utf8").split("\n")[0]?.trim() ?? "";
4886
- const version = parseNvmrcVersion(originalAlias);
4887
- if (!version) {
4888
- warnMigration(".nvmrc contains an unsupported version alias. Create .node-version manually with your desired Node.js version.", report);
4889
- return false;
4890
- }
4891
- if (version === "lts/*" && (originalAlias === "node" || originalAlias === "stable")) log.info(`"${originalAlias}" in .nvmrc is not a specific version; automatically mapping to "lts/*"`);
4892
- fs.writeFileSync(nodeVersionPath, `${version}\n`);
4893
- fs.unlinkSync(sourcePath);
4894
- if (report) {
4895
- report.nodeVersionFileMigrated = true;
4896
- if (detection.voltaPresent) report.manualSteps.push("Remove the \"volta\" field from package.json");
4897
- } else if (detection.voltaPresent) log.info("You can now remove the \"volta\" field from package.json manually.");
4898
- return true;
4899
- }
4900
- function warnPackageLevelEslint() {
4901
- log.warn("ESLint detected in workspace packages but no root config found. Package-level ESLint must be migrated manually.");
4902
- }
4903
- function warnLegacyEslintConfig(legacyConfigFile) {
4904
- log.warn(`Legacy ESLint configuration detected (${legacyConfigFile}). Automatic migration to Oxlint requires ESLint v9+ with flat config format (eslint.config.*). Please upgrade to ESLint v9 first: https://eslint.org/docs/latest/use/migrate-to-9.0.0`);
4905
- }
4906
- async function confirmEslintMigration(interactive) {
4907
- if (interactive) {
4908
- const confirmed = await confirm({
4909
- message: "Migrate ESLint rules to Oxlint using @oxlint/migrate?\n " + styleText("gray", "Oxlint is Vite+'s built-in linter — significantly faster than ESLint with compatible rule support. @oxlint/migrate converts your existing rules automatically."),
4910
- initialValue: true
4911
- });
4912
- if (q(confirmed)) cancelAndExit();
4913
- return confirmed;
4914
- }
4915
- return true;
4916
- }
4917
- async function promptEslintMigration(projectPath, interactive, packages) {
4918
- const eslintProject = detectEslintProject(projectPath, packages);
4919
- if (eslintProject.hasDependency && !eslintProject.configFile && eslintProject.legacyConfigFile) {
4920
- warnLegacyEslintConfig(eslintProject.legacyConfigFile);
4921
- return false;
4922
- }
4923
- if (!eslintProject.hasDependency) return false;
4924
- if (!eslintProject.configFile) {
4925
- warnPackageLevelEslint();
4926
- return false;
4927
- }
4928
- if (!await confirmEslintMigration(interactive)) return false;
4929
- if (!await migrateEslintToOxlint(projectPath, interactive, eslintProject.configFile, packages)) cancelAndExit("ESLint migration failed.", 1);
4930
- return true;
4931
- }
4932
- function warnPackageLevelPrettier() {
4933
- log.warn("Prettier detected in workspace packages but no root config found. Package-level Prettier must be migrated manually.");
4934
- }
4935
- async function confirmPrettierMigration(interactive) {
4936
- if (interactive) {
4937
- const confirmed = await confirm({
4938
- 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."),
4939
- initialValue: true
4940
- });
4941
- if (q(confirmed)) cancelAndExit();
4942
- return confirmed;
4943
- }
4944
- log.info("Prettier configuration detected. Auto-migrating to Oxfmt...");
4945
- return true;
4946
- }
4947
- async function promptPrettierMigration(projectPath, interactive, packages) {
4948
- const prettierProject = detectPrettierProject(projectPath, packages);
4949
- if (!prettierProject.hasDependency) return false;
4950
- if (!prettierProject.configFile) {
4951
- warnPackageLevelPrettier();
3797
+ text = fs.readFileSync(filePath, "utf-8");
3798
+ } catch {
4952
3799
  return false;
4953
3800
  }
4954
- if (!await confirmPrettierMigration(interactive)) return false;
4955
- if (!await migratePrettierToOxfmt(projectPath, interactive, prettierProject.configFile, packages)) cancelAndExit("Prettier migration failed.", 1);
4956
- return true;
4957
- }
4958
- //#endregion
4959
- //#region src/utils/agent.ts
4960
- const AGENTS = [
4961
- {
4962
- id: "agents",
4963
- label: "AGENTS.md",
4964
- targetPath: "AGENTS.md",
4965
- hint: "Codex, Amp, OpenCode, and similar agents",
4966
- aliases: [
4967
- "agents.md",
4968
- "chatgpt",
4969
- "chatgpt-codex",
4970
- "codex",
4971
- "amp",
4972
- "kilo",
4973
- "kilo-code",
4974
- "kiro",
4975
- "kiro-cli",
4976
- "opencode",
4977
- "other"
4978
- ]
4979
- },
4980
- {
4981
- id: "claude",
4982
- label: "CLAUDE.md",
4983
- targetPath: "CLAUDE.md",
4984
- hint: "Claude Code",
4985
- aliases: ["claude.md", "claude-code"]
4986
- },
4987
- {
4988
- id: "gemini",
4989
- label: "GEMINI.md",
4990
- targetPath: "GEMINI.md",
4991
- hint: "Gemini CLI",
4992
- aliases: ["gemini.md", "gemini-cli"]
4993
- },
4994
- {
4995
- id: "copilot",
4996
- label: ".github/copilot-instructions.md",
4997
- targetPath: ".github/copilot-instructions.md",
4998
- hint: "GitHub Copilot",
4999
- aliases: ["github-copilot", "copilot-instructions.md"]
5000
- },
5001
- {
5002
- id: "cursor",
5003
- label: ".cursor/rules/viteplus.mdc",
5004
- targetPath: ".cursor/rules/viteplus.mdc",
5005
- hint: "Cursor",
5006
- aliases: ["viteplus.mdc"]
5007
- },
5008
- {
5009
- id: "jetbrains",
5010
- label: ".aiassistant/rules/viteplus.md",
5011
- targetPath: ".aiassistant/rules/viteplus.md",
5012
- hint: "JetBrains AI Assistant",
5013
- aliases: [
5014
- "jetbrains",
5015
- "jetbrains-ai-assistant",
5016
- "aiassistant",
5017
- "viteplus.md"
5018
- ]
5019
- }
5020
- ];
5021
- const AGENT_DEFAULT_ID = "agents";
5022
- const AGENT_STANDARD_PATH = "AGENTS.md";
5023
- const AGENT_INSTRUCTIONS_START_MARKER = "<!--VITE PLUS START-->";
5024
- const AGENT_INSTRUCTIONS_END_MARKER = "<!--VITE PLUS END-->";
5025
- const AGENT_ALIASES = Object.fromEntries(AGENTS.flatMap((option) => (option.aliases ?? []).map((alias) => [normalizeAgentName(alias), option.id])));
5026
- async function selectAgentTargetPaths({ interactive, agent, onCancel }) {
5027
- if (agent === false) return;
5028
- if (interactive && !agent) {
5029
- const selectedAgents = await multiselect({
5030
- message: "Which coding agent instruction files should Vite+ create?",
5031
- options: AGENTS.map((option) => ({
5032
- label: option.label,
5033
- value: option.id,
5034
- hint: option.hint
5035
- })),
5036
- initialValues: [AGENT_DEFAULT_ID],
5037
- required: false
5038
- });
5039
- if (q(selectedAgents)) {
5040
- onCancel();
5041
- return;
5042
- }
5043
- if (selectedAgents.length === 0) return;
5044
- return resolveAgentTargetPaths(selectedAgents);
5045
- }
5046
- return resolveAgentTargetPaths(agent ?? AGENT_DEFAULT_ID);
5047
- }
5048
- function detectExistingAgentTargetPaths(projectRoot) {
5049
- const detectedPaths = [];
5050
- const seenTargetPaths = /* @__PURE__ */ new Set();
5051
- for (const option of AGENTS) {
5052
- if (seenTargetPaths.has(option.targetPath)) continue;
5053
- seenTargetPaths.add(option.targetPath);
5054
- const targetPath = path.join(projectRoot, option.targetPath);
5055
- if (fs.existsSync(targetPath) && !fs.lstatSync(targetPath).isSymbolicLink()) detectedPaths.push(option.targetPath);
5056
- }
5057
- return detectedPaths.length > 0 ? detectedPaths : void 0;
5058
- }
5059
- /**
5060
- * Silently update agent instruction files that contain Vite+ markers.
5061
- * - No agent files → no writes
5062
- * - No Vite+ markers → no writes
5063
- * - Markers present, content up to date → no writes
5064
- * - Markers present, content outdated → update marked section
5065
- */
5066
- function updateExistingAgentInstructions(projectRoot) {
5067
- const targetPaths = detectExistingAgentTargetPaths(projectRoot);
5068
- if (!targetPaths) return;
5069
- const templatePath = path.join(pkgRoot, "AGENTS.md");
5070
- if (!fs.existsSync(templatePath)) return;
5071
- const templateContent = fs.readFileSync(templatePath, "utf-8");
5072
- for (const targetPath of targetPaths) try {
5073
- const fullPath = path.join(projectRoot, targetPath);
5074
- const existing = fs.readFileSync(fullPath, "utf-8");
5075
- const updated = replaceMarkedAgentInstructionsSection(existing, templateContent);
5076
- if (updated !== void 0 && updated !== existing) fs.writeFileSync(fullPath, updated);
5077
- } catch {}
5078
- }
5079
- function resolveAgentTargetPaths(agent) {
5080
- const agentNames = parseAgentNames(agent);
5081
- const resolvedAgentNames = agentNames.length > 0 ? agentNames : ["other"];
5082
- const dedupedTargetPaths = [];
5083
- const seenTargetPaths = /* @__PURE__ */ new Set();
5084
- for (const name of resolvedAgentNames) {
5085
- const targetPath = resolveSingleAgentTargetPath(name);
5086
- if (seenTargetPaths.has(targetPath)) continue;
5087
- seenTargetPaths.add(targetPath);
5088
- dedupedTargetPaths.push(targetPath);
5089
- }
5090
- return dedupedTargetPaths;
5091
- }
5092
- function parseAgentNames(agent) {
5093
- if (!agent) return [];
5094
- return (Array.isArray(agent) ? agent : [agent]).filter((value) => typeof value === "string").flatMap((value) => value.split(",")).map((value) => value.trim()).filter((value) => value.length > 0);
5095
- }
5096
- function resolveSingleAgentTargetPath(agent) {
5097
- const normalized = normalizeAgentName(agent);
5098
- const alias = AGENT_ALIASES[normalized];
5099
- const resolved = alias ? normalizeAgentName(alias) : normalized;
5100
- return AGENTS.find((option) => normalizeAgentName(option.id) === resolved || normalizeAgentName(option.label) === resolved || normalizeAgentName(option.targetPath) === resolved || option.aliases?.some((candidate) => normalizeAgentName(candidate) === resolved))?.targetPath ?? AGENT_STANDARD_PATH;
5101
- }
5102
- /**
5103
- * Detect agent instruction files that would conflict (exist without markers).
5104
- * Returns only files that need a user decision (append or skip).
5105
- * Read-only — does not write or modify any files.
5106
- */
5107
- async function detectAgentConflicts({ projectRoot, targetPaths }) {
5108
- if (!targetPaths || targetPaths.length === 0) return [];
5109
- const sourcePath = path.join(pkgRoot, "AGENTS.md");
5110
- if (!fs.existsSync(sourcePath)) return [];
5111
- const incomingContent = await fsPromises.readFile(sourcePath, "utf-8");
5112
- const shouldLinkToAgents = targetPaths.includes(AGENT_STANDARD_PATH);
5113
- const orderedPaths = shouldLinkToAgents ? [AGENT_STANDARD_PATH, ...targetPaths.filter((p) => p !== AGENT_STANDARD_PATH)] : targetPaths;
5114
- const conflicts = [];
5115
- const seenDestinationPaths = /* @__PURE__ */ new Set();
5116
- const seenRealPaths = /* @__PURE__ */ new Set();
5117
- for (const targetPathToCheck of orderedPaths) {
5118
- const destinationPath = path.join(projectRoot, targetPathToCheck);
5119
- const destinationKey = path.resolve(destinationPath);
5120
- if (seenDestinationPaths.has(destinationKey)) continue;
5121
- seenDestinationPaths.add(destinationKey);
5122
- if (shouldLinkToAgents && targetPathToCheck !== AGENT_STANDARD_PATH) {
5123
- if (await getExistingPathKind(destinationPath) !== "file") continue;
5124
- }
5125
- if (fs.existsSync(destinationPath)) {
5126
- if (fs.lstatSync(destinationPath).isSymbolicLink()) continue;
5127
- const destinationRealPath = await fsPromises.realpath(destinationPath);
5128
- if (seenRealPaths.has(destinationRealPath)) continue;
5129
- if (replaceMarkedAgentInstructionsSection(await fsPromises.readFile(destinationPath, "utf-8"), incomingContent) !== void 0) {
5130
- seenRealPaths.add(destinationRealPath);
5131
- continue;
5132
- }
5133
- conflicts.push({ targetPath: targetPathToCheck });
5134
- seenRealPaths.add(destinationRealPath);
5135
- }
5136
- }
5137
- return conflicts;
5138
- }
5139
- async function writeAgentInstructions({ projectRoot, targetPath, targetPaths, interactive, conflictDecisions, silent = false }) {
5140
- const paths = [...targetPaths ?? [], ...targetPath ? [targetPath] : []];
5141
- if (paths.length === 0) return;
5142
- const sourcePath = path.join(pkgRoot, "AGENTS.md");
5143
- if (!fs.existsSync(sourcePath)) {
5144
- if (!silent) log.warn("Agent instructions template not found; skipping.");
5145
- return;
5146
- }
5147
- const seenDestinationPaths = /* @__PURE__ */ new Set();
5148
- const seenRealPaths = /* @__PURE__ */ new Set();
5149
- const incomingContent = await fsPromises.readFile(sourcePath, "utf-8");
5150
- const shouldLinkToAgents = paths.includes(AGENT_STANDARD_PATH);
5151
- const orderedPaths = shouldLinkToAgents ? [AGENT_STANDARD_PATH, ...paths.filter((p) => p !== AGENT_STANDARD_PATH)] : paths;
5152
- for (const targetPathToWrite of orderedPaths) {
5153
- const destinationPath = path.join(projectRoot, targetPathToWrite);
5154
- const destinationKey = path.resolve(destinationPath);
5155
- if (seenDestinationPaths.has(destinationKey)) continue;
5156
- seenDestinationPaths.add(destinationKey);
5157
- await fsPromises.mkdir(path.dirname(destinationPath), { recursive: true });
5158
- if (shouldLinkToAgents && targetPathToWrite !== AGENT_STANDARD_PATH) {
5159
- if (await tryLinkTargetToAgents(projectRoot, targetPathToWrite, silent)) continue;
5160
- }
5161
- if (fs.existsSync(destinationPath)) {
5162
- if (fs.lstatSync(destinationPath).isSymbolicLink()) {
5163
- if (!silent) log.info(`Skipped writing ${targetPathToWrite} (symlink)`);
5164
- continue;
5165
- }
5166
- const destinationRealPath = await fsPromises.realpath(destinationPath);
5167
- if (seenRealPaths.has(destinationRealPath)) {
5168
- if (!silent) log.info(`Skipped writing ${targetPathToWrite} (duplicate target)`);
5169
- continue;
5170
- }
5171
- const existingContent = await fsPromises.readFile(destinationPath, "utf-8");
5172
- const updatedContent = replaceMarkedAgentInstructionsSection(existingContent, incomingContent);
5173
- if (updatedContent !== void 0) {
5174
- if (updatedContent !== existingContent) await fsPromises.writeFile(destinationPath, updatedContent);
5175
- seenRealPaths.add(destinationRealPath);
5176
- continue;
5177
- }
5178
- let conflictAction;
5179
- const preResolved = conflictDecisions?.get(targetPathToWrite);
5180
- if (preResolved) conflictAction = preResolved;
5181
- else if (interactive) {
5182
- const action = await select({
5183
- message: `Agent instructions already exist at ${targetPathToWrite}.\n ` + styleText("gray", "The Vite+ template includes guidance on `vp` commands, the build pipeline, and project conventions."),
5184
- options: [{
5185
- label: "Append",
5186
- value: "append",
5187
- hint: "Add template content to the end"
5188
- }, {
5189
- label: "Skip",
5190
- value: "skip",
5191
- hint: "Leave existing file unchanged"
5192
- }],
5193
- initialValue: "skip"
5194
- });
5195
- conflictAction = q(action) || action === "skip" ? "skip" : "append";
5196
- } else conflictAction = "skip";
5197
- if (conflictAction === "append") await appendAgentContent(destinationPath, targetPathToWrite, existingContent, incomingContent, silent);
5198
- else {
5199
- const suffix = !preResolved && !interactive ? " (already exists)" : "";
5200
- if (!silent) log.info(`Skipped writing ${targetPathToWrite}${suffix}`);
5201
- }
5202
- seenRealPaths.add(destinationRealPath);
5203
- continue;
5204
- }
5205
- await fsPromises.writeFile(destinationPath, incomingContent);
5206
- if (!silent) log.success(`Wrote agent instructions to ${targetPathToWrite}`);
5207
- seenRealPaths.add(await fsPromises.realpath(destinationPath));
5208
- }
5209
- }
5210
- async function appendAgentContent(destinationPath, targetPath, existingContent, incomingContent, silent = false) {
5211
- const separator = existingContent.endsWith("\n") ? "" : "\n";
5212
- await fsPromises.appendFile(destinationPath, `${separator}\n${incomingContent}`);
5213
- if (!silent) log.success(`Appended agent instructions to ${targetPath}`);
5214
- }
5215
- function normalizeAgentName(value) {
5216
- return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
5217
- }
5218
- function replaceMarkedAgentInstructionsSection(existing, incoming) {
5219
- const existingRange = getMarkedRange(existing, AGENT_INSTRUCTIONS_START_MARKER, AGENT_INSTRUCTIONS_END_MARKER);
5220
- if (!existingRange) return;
5221
- const incomingRange = getMarkedRange(incoming, AGENT_INSTRUCTIONS_START_MARKER, AGENT_INSTRUCTIONS_END_MARKER);
5222
- if (!incomingRange) return;
5223
- return `${existing.slice(0, existingRange.start)}${incoming.slice(incomingRange.start, incomingRange.end)}${existing.slice(existingRange.end)}`;
5224
- }
5225
- async function tryLinkTargetToAgents(projectRoot, targetPath, silent = false) {
5226
- const destinationPath = path.join(projectRoot, targetPath);
5227
- const agentsPath = path.join(projectRoot, AGENT_STANDARD_PATH);
5228
- const symlinkTarget = path.relative(path.dirname(destinationPath), agentsPath);
5229
- const existing = await getExistingPathKind(destinationPath);
5230
- if (existing === "file") return false;
5231
- if (existing === "symlink") {
5232
- const currentLink = await fsPromises.readlink(destinationPath);
5233
- if (path.resolve(path.dirname(destinationPath), currentLink) === agentsPath) {
5234
- if (!silent) log.info(`Skipped linking ${targetPath} (already linked to ${AGENT_STANDARD_PATH})`);
5235
- return true;
5236
- }
5237
- await fsPromises.unlink(destinationPath);
5238
- }
5239
- try {
5240
- await fsPromises.symlink(symlinkTarget, destinationPath);
5241
- } catch (err) {
5242
- if (err.code === "EPERM") {
5243
- await fsPromises.copyFile(agentsPath, destinationPath);
5244
- if (!silent) log.success(`Copied ${AGENT_STANDARD_PATH} to ${targetPath}`);
5245
- return true;
5246
- }
5247
- throw err;
5248
- }
5249
- if (!silent) log.success(`Linked ${targetPath} to ${AGENT_STANDARD_PATH}`);
3801
+ const types = parse(text)?.compilerOptions?.types;
3802
+ if (!Array.isArray(types)) return false;
3803
+ const REPLACEMENTS = {
3804
+ "tsdown/client": "vite-plus/pack/client",
3805
+ "vite/client": "vite-plus/client"
3806
+ };
3807
+ const toReplace = types.map((t, i) => typeof t === "string" && t in REPLACEMENTS ? {
3808
+ i,
3809
+ newVal: REPLACEMENTS[t]
3810
+ } : null).filter((x) => x !== null);
3811
+ if (toReplace.length === 0) return false;
3812
+ let currentText = text;
3813
+ for (let j = toReplace.length - 1; j >= 0; j--) {
3814
+ const { i, newVal } = toReplace[j];
3815
+ const edits = modify(currentText, [
3816
+ "compilerOptions",
3817
+ "types",
3818
+ i
3819
+ ], newVal, {});
3820
+ if (edits.length > 0) currentText = applyEdits(currentText, edits);
3821
+ }
3822
+ fs.writeFileSync(filePath, currentText);
5250
3823
  return true;
5251
3824
  }
5252
- async function getExistingPathKind(filePath) {
5253
- if (!fs.existsSync(filePath)) return "missing";
5254
- return (await fsPromises.lstat(filePath)).isSymbolicLink() ? "symlink" : "file";
5255
- }
5256
- function getMarkedRange(content, startMarker, endMarker) {
5257
- const start = content.indexOf(startMarker);
5258
- if (start === -1) return;
5259
- const endMarkerIndex = content.indexOf(endMarker, start + startMarker.length);
5260
- if (endMarkerIndex === -1) return;
5261
- return {
5262
- start,
5263
- end: endMarkerIndex + endMarker.length
5264
- };
5265
- }
5266
3825
  //#endregion
5267
- export { log as $, setPackageManager as A, promptGitInit as B, migratePrettierToOxfmt as C, rewriteMonorepo as D, promptPrettierMigration as E, readYamlFile as F, displayRelative as G, runViteInstall as H, cancelAndExit as I, PackageManager as J, templatesDir as K, defaultInteractive as L, warnPackageLevelEslint as M, warnPackageLevelPrettier as N, rewriteMonorepoProject as O, editYamlFile as P, intro as Q, downloadPackageManager$1 as R, migrateNodeVersionManagerFile as S, promptEslintMigration as T, selectPackageManager as U, runViteFmt as V, upgradeYarn as W, cancel as X, require_semver as Y, confirm as Z, hasStagedConfigInViteConfig as _, writeAgentInstructions as a, require_picocolors as at, mergeViteConfigFiles as b, checkVitestVersion as c, detectEslintProject as d, multiselect as et, detectFramework as f, hasFrameworkShim as g, ensurePreCommitHook as h, updateExistingAgentInstructions as i, text as it, warnLegacyEslintConfig as j, rewriteStandaloneProject as k, confirmEslintMigration as l, detectPrettierProject as m, detectExistingAgentTargetPaths as n, select as nt, addFrameworkShim as o, q as ot, detectNodeVersionManagerFile as p, DependencyType as q, selectAgentTargetPaths as r, spinner as rt, checkViteVersion as s, detectAgentConflicts as t, outro as tt, confirmPrettierMigration as u, injectCreateDefaultTemplate as v, preflightGitHooksSetup as w, migrateEslintToOxlint as x, installGitHooks as y, promptGitHooks as z };
3826
+ export { q as A, log as C, spinner as D, select as E, runCommandSilently as M, require_cross_spawn as N, text as O, intro as S, outro as T, DependencyType as _, removeDeprecatedTsconfigFalseOption as a, cancel as b, defaultInteractive as c, promptGitHooks as d, promptGitInit as f, upgradeYarn as g, selectPackageManager as h, hasBaseUrlInTsconfig as i, runCommand$1 as j, require_picocolors as k, downloadPackageManager$1 as l, runViteInstall as m, findTsconfigFiles as n, rewriteTypesInTsconfig as o, runViteFmt as p, fixBaseUrlInTsconfig as r, cancelAndExit as s, confirmBaseUrlFix as t, getSpinner as u, PackageManager as v, multiselect as w, confirm as x, require_semver as y };