vite-plus 0.1.23 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +30 -0
- package/README.md +8 -6
- package/bin/oxfmt +5 -2
- package/bin/oxlint +12 -2
- package/binding/index.cjs +84 -67
- package/binding/index.d.cts +155 -4
- package/dist/{agent-aSGY0osq.js → agent-BD31CsvU.js} +969 -89
- package/dist/bin.js +29 -33
- package/dist/{compat-DXZgnEyq.js → compat-Cql3K40m.js} +1 -1
- package/dist/config/bin.js +30 -14
- package/dist/constants-CrfJQIUX.js +66 -0
- package/dist/create/bin.d.ts +7 -1
- package/dist/create/bin.js +578 -266
- package/dist/define-config-2tfJoXr1.d.ts +305 -0
- package/dist/define-config-BGSjF6Xp.cjs +488 -0
- package/dist/define-config-DJUehepE.js +445 -0
- package/dist/define-config.cjs +8 -1
- package/dist/define-config.d.ts +2 -2
- package/dist/define-config.js +2 -2
- package/dist/dist-DRJUd9bL.js +3 -0
- package/dist/{dist-BgQuvbtq.js → dist-Oxo16Y0q.js} +4 -4
- package/dist/index.cjs +9 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{main-DpJl3LoU.js → json-Dn87fvjk.js} +137 -1
- package/dist/migration/bin.js +301 -84
- package/dist/{oxlint-plugin-config-B89iKTKN.js → oxlint-plugin-config-q8a5PFch.js} +1 -1
- package/dist/oxlint-plugin.js +11 -3
- package/dist/pack-bin.js +44 -15
- package/dist/{package-PmBUZ-ve.js → package-BHirM1_v.js} +3 -138
- package/dist/{report-DgSBQUdz.js → report-BHSkWqRR.js} +2 -0
- package/dist/{resolve-vite-config-TTvhycU1.js → resolve-vite-config-CmdsfQzS.js} +13 -4
- package/dist/staged/bin.js +150 -417
- package/dist/test/_at-vitest-browser/context.d.ts +2 -0
- package/dist/test/_at-vitest-browser.d.ts +2 -0
- package/dist/test/browser/context.d.ts +2 -2
- package/dist/test/browser/context.js +1 -1
- package/dist/test/browser/providers/playwright/context.d.ts +1 -0
- package/dist/test/browser/providers/playwright/context.js +1 -0
- package/dist/test/browser/providers/playwright.d.ts +124 -2
- package/dist/test/browser/providers/playwright.js +1 -1
- package/dist/test/browser/providers/preview/context.d.ts +1 -0
- package/dist/test/browser/providers/preview/context.js +1 -0
- package/dist/test/browser/providers/preview.d.ts +32 -2
- package/dist/test/browser/providers/preview.js +1 -1
- package/dist/test/browser/providers/webdriverio/context.d.ts +1 -0
- package/dist/test/browser/providers/webdriverio/context.js +1 -0
- package/dist/test/browser/providers/webdriverio.d.ts +77 -2
- package/dist/test/browser/providers/webdriverio.js +1 -1
- package/dist/test/browser-compat.d.ts +2 -0
- package/dist/test/browser-compat.js +1 -1
- package/dist/test/browser-playwright/context.d.ts +1 -0
- package/dist/test/browser-playwright/context.js +1 -0
- package/dist/test/browser-playwright.d.ts +124 -2
- package/dist/test/browser-playwright.js +1 -1
- package/dist/test/browser-preview/context.d.ts +1 -0
- package/dist/test/browser-preview/context.js +1 -0
- package/dist/test/browser-preview.d.ts +32 -2
- package/dist/test/browser-preview.js +1 -1
- package/dist/test/browser-webdriverio/context.d.ts +1 -0
- package/dist/test/browser-webdriverio/context.js +1 -0
- package/dist/test/browser-webdriverio.d.ts +77 -2
- package/dist/test/browser-webdriverio.js +1 -1
- package/dist/test/browser.d.ts +2 -2
- package/dist/test/browser.js +1 -1
- package/dist/test/client.js +1 -1
- package/dist/test/config.cjs +1 -1
- package/dist/test/config.d.ts +2 -2
- package/dist/test/config.js +1 -1
- package/dist/test/context.d.ts +942 -2
- package/dist/test/context.js +1 -1
- package/dist/test/coverage.d.ts +2 -2
- package/dist/test/coverage.js +1 -1
- package/dist/test/environments.d.ts +2 -2
- package/dist/test/environments.js +1 -1
- package/dist/test/globals.d.ts +2 -2
- package/dist/test/import-meta.d.ts +2 -2
- package/dist/test/importMeta.d.ts +2 -2
- package/dist/test/index.cjs +1 -1
- package/dist/test/index.d.cts +2 -2
- package/dist/test/index.d.ts +2 -2
- package/dist/test/index.js +1 -1
- package/dist/test/internal/browser.d.ts +2 -2
- package/dist/test/internal/browser.js +1 -1
- package/dist/test/jsdom.d.ts +2 -2
- package/dist/test/locators.d.ts +294 -0
- package/dist/test/locators.js +1 -1
- package/dist/test/matchers.d.ts +29 -0
- package/dist/test/matchers.js +1 -1
- package/dist/test/node.d.ts +2 -2
- package/dist/test/node.js +1 -1
- package/dist/test/optional-runtime-types.js.d.ts +2 -2
- package/dist/test/optional-types.js.d.ts +2 -2
- package/dist/test/plugins/browser-client.js +1 -1
- package/dist/test/plugins/browser-context.js +1 -1
- package/dist/test/plugins/browser-locators.js +1 -1
- package/dist/test/plugins/browser-playwright.js +1 -1
- package/dist/test/plugins/browser-preview.js +1 -1
- package/dist/test/plugins/browser-webdriverio.js +1 -1
- package/dist/test/plugins/browser.js +1 -1
- package/dist/test/plugins/expect.js +1 -1
- package/dist/test/plugins/mocker-automock.js +1 -1
- package/dist/test/plugins/mocker-browser.js +1 -1
- package/dist/test/plugins/mocker-node.js +1 -1
- package/dist/test/plugins/mocker-redirect.js +1 -1
- package/dist/test/plugins/mocker-register.js +1 -1
- package/dist/test/plugins/mocker-transforms.js +1 -1
- package/dist/test/plugins/mocker.js +1 -1
- package/dist/test/plugins/pretty-format.js +1 -1
- package/dist/test/plugins/runner-types.js +1 -1
- package/dist/test/plugins/runner-utils.js +1 -1
- package/dist/test/plugins/runner.js +1 -1
- package/dist/test/plugins/snapshot-environment.js +1 -1
- package/dist/test/plugins/snapshot-manager.js +1 -1
- package/dist/test/plugins/snapshot.js +1 -1
- package/dist/test/plugins/spy.js +1 -1
- package/dist/test/plugins/utils-constants.js +1 -1
- package/dist/test/plugins/utils-diff.js +1 -1
- package/dist/test/plugins/utils-display.js +1 -1
- package/dist/test/plugins/utils-error.js +1 -1
- package/dist/test/plugins/utils-helpers.js +1 -1
- package/dist/test/plugins/utils-offset.js +1 -1
- package/dist/test/plugins/utils-resolver.js +1 -1
- package/dist/test/plugins/utils-serialize.js +1 -1
- package/dist/test/plugins/utils-source-map-node.js +1 -1
- package/dist/test/plugins/utils-source-map.js +1 -1
- package/dist/test/plugins/utils-timers.js +1 -1
- package/dist/test/plugins/utils.js +1 -1
- package/dist/test/reporters.d.ts +2 -2
- package/dist/test/reporters.js +1 -1
- package/dist/test/runners.d.ts +2 -2
- package/dist/test/runners.js +1 -1
- package/dist/test/runtime.d.ts +2 -2
- package/dist/test/runtime.js +1 -1
- package/dist/test/snapshot.d.ts +2 -2
- package/dist/test/snapshot.js +1 -1
- package/dist/test/suite.d.ts +2 -2
- package/dist/test/suite.js +1 -1
- package/dist/test/utils.js +1 -1
- package/dist/test/worker.d.ts +2 -2
- package/dist/test/worker.js +1 -1
- package/dist/{tsconfig-DlUVXT3J.js → tsconfig-CJ_StdFc.js} +605 -263
- package/dist/tsgolint-path-B-yOos8p.js +32 -0
- package/dist/tsgolint-path.d.ts +8 -0
- package/dist/tsgolint-path.js +2 -0
- package/dist/version.js +3 -3
- package/dist/versions.d.ts +1 -1
- package/dist/versions.js +7 -7
- package/dist/{workspace-DElv730L.js → workspace-Cjoc1c_A.js} +20 -18
- package/docs/_data/team.ts +5 -4
- package/docs/config/create.md +36 -1
- package/docs/config/index.md +7 -5
- package/docs/guide/commit-hooks.md +9 -0
- package/docs/guide/create.md +106 -2
- package/docs/guide/env.md +33 -5
- package/docs/guide/index.md +9 -3
- package/docs/guide/install.md +46 -10
- package/docs/guide/migrate.md +13 -3
- package/docs/guide/troubleshooting.md +3 -29
- package/docs/guide/upgrade.md +36 -6
- package/docs/package.json +3 -3
- package/docs/pnpm-lock.yaml +298 -395
- package/package.json +104 -56
- package/templates/generator/bin/index.ts +6 -3
- package/templates/generator/package.json +2 -3
- package/templates/generator/src/template.ts +0 -2
- package/templates/monorepo/package.json +1 -1
- package/dist/constants-DCBWlNrn.js +0 -33
- package/dist/define-config-BR1Y88zz.cjs +0 -84
- package/dist/define-config-BRC7qPNE.js +0 -21
- package/dist/define-config-COdn-tsn.d.ts +0 -177
- package/dist/dist-Bapm49IR.js +0 -3
- package/dist/test/plugins/utils-highlight.js +0 -1
- /package/dist/{chunk-DnnnRqeS.js → rolldown-runtime-DnnnRqeS.js} +0 -0
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { r as __toESM } from "./
|
|
2
|
-
import { a as
|
|
3
|
-
import { i as ensureVitePlusImportRuleDefaults, r as createDefaultVitePlusLintConfig } from "./oxlint-plugin-config-
|
|
4
|
-
import { A as
|
|
5
|
-
import { t as
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
1
|
+
import { r as __toESM } from "./rolldown-runtime-DnnnRqeS.js";
|
|
2
|
+
import { a as VITEST_VERSION, c as VITE_PLUS_VERSION, i as VITEST_AGE_GATE_EXEMPT_PACKAGES, n as BASEURL_TSCONFIG_WARNING, o as VITE_PLUS_NAME, s as VITE_PLUS_OVERRIDE_PACKAGES, u as isForceOverrideMode } from "./constants-CrfJQIUX.js";
|
|
3
|
+
import { i as ensureVitePlusImportRuleDefaults, r as createDefaultVitePlusLintConfig } from "./oxlint-plugin-config-q8a5PFch.js";
|
|
4
|
+
import { A as select, C as require_semver, D as log, I as runCommandSilently, L as require_cross_spawn, O as multiselect, P as R, S as PackageManager, T as confirm, a as hasTypesToRewriteInTsconfig, b as getSpinner, c as cancelAndExit, i as hasBaseUrlInTsconfig, n as findTsconfigFiles, o as removeDeprecatedTsconfigFalseOption, s as rewriteTypesInTsconfig } from "./tsconfig-CJ_StdFc.js";
|
|
5
|
+
import { n as isJsonFile, r as readJsonFile, t as editJsonFile } from "./json-Dn87fvjk.js";
|
|
6
|
+
import { t as require_dist } from "./dist-Oxo16Y0q.js";
|
|
7
|
+
import { n as detectPackageMetadata } from "./package-BHirM1_v.js";
|
|
8
|
+
import { n as addMigrationWarning, t as addManualStep } from "./report-BHSkWqRR.js";
|
|
8
9
|
import path from "node:path";
|
|
9
|
-
import { hasConfigKey, mergeJsonConfig, mergeTsdownConfig, rewriteEslint, rewriteImportsInDirectory, rewritePrettier, rewriteScripts } from "../binding/index.js";
|
|
10
|
+
import { hasConfigKey, mergeJsonConfig, mergeTsdownConfig, rewriteEslint, rewriteImportsInDirectory, rewritePrettier, rewriteScripts, wrapLazyPlugins } from "../binding/index.js";
|
|
10
11
|
import fs from "node:fs";
|
|
11
12
|
import { styleText } from "node:util";
|
|
13
|
+
import os from "node:os";
|
|
12
14
|
import fsPromises from "node:fs/promises";
|
|
13
15
|
//#region src/utils/path.ts
|
|
14
16
|
var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
|
|
@@ -173,14 +175,134 @@ const REMOVE_PACKAGES = [
|
|
|
173
175
|
"oxfmt",
|
|
174
176
|
"tsdown",
|
|
175
177
|
"@vitest/browser",
|
|
176
|
-
"@vitest/browser-preview"
|
|
177
|
-
"@vitest/browser-playwright",
|
|
178
|
-
"@vitest/browser-webdriverio"
|
|
178
|
+
"@vitest/browser-preview"
|
|
179
179
|
];
|
|
180
|
+
const WEBDRIVERIO_PROVIDER = "@vitest/browser-webdriverio";
|
|
181
|
+
const PLAYWRIGHT_PROVIDER = "@vitest/browser-playwright";
|
|
182
|
+
const OPT_IN_BROWSER_PROVIDERS = [WEBDRIVERIO_PROVIDER, PLAYWRIGHT_PROVIDER];
|
|
183
|
+
const PROVIDER_OVERRIDE_DROP_NAMES = [...REMOVE_PACKAGES, ...OPT_IN_BROWSER_PROVIDERS];
|
|
184
|
+
function extractOverrideTargetName(key) {
|
|
185
|
+
let target = key.trim();
|
|
186
|
+
for (let delim = target.search(/[^ |@]>/); delim !== -1; delim = target.search(/[^ |@]>/)) target = target.slice(delim + 2).trim();
|
|
187
|
+
if (!target) return target;
|
|
188
|
+
if (target.includes("/")) {
|
|
189
|
+
const segments = target.split("/");
|
|
190
|
+
const last = segments[segments.length - 1];
|
|
191
|
+
const scope = segments[segments.length - 2];
|
|
192
|
+
target = scope?.startsWith("@") ? `${scope}/${last}` : last;
|
|
193
|
+
}
|
|
194
|
+
const nameStart = target.startsWith("@") ? target.indexOf("/") + 1 : 0;
|
|
195
|
+
const versionAt = target.indexOf("@", nameStart);
|
|
196
|
+
if (versionAt > 0) target = target.slice(0, versionAt);
|
|
197
|
+
return target;
|
|
198
|
+
}
|
|
199
|
+
function isRemovePackageOverrideKey(key) {
|
|
200
|
+
return PROVIDER_OVERRIDE_DROP_NAMES.includes(extractOverrideTargetName(key));
|
|
201
|
+
}
|
|
202
|
+
function stripSegmentVersion(segment) {
|
|
203
|
+
const nameStart = segment.startsWith("@") ? segment.indexOf("/") + 1 : 0;
|
|
204
|
+
const versionAt = segment.indexOf("@", nameStart);
|
|
205
|
+
return versionAt > 0 ? segment.slice(0, versionAt) : segment;
|
|
206
|
+
}
|
|
207
|
+
function parentGlobMatchesName(glob, name) {
|
|
208
|
+
const pattern = glob.split("*").map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
209
|
+
return new RegExp(`^${pattern}$`).test(name);
|
|
210
|
+
}
|
|
211
|
+
function ancestorSegmentMatches(segment, name) {
|
|
212
|
+
return segment.includes("*") ? parentGlobMatchesName(segment, name) : segment === name;
|
|
213
|
+
}
|
|
214
|
+
const OWNED_PROVIDER_ANCESTOR_NAMES = REMOVE_PACKAGES.filter((name) => name.startsWith("@vitest/"));
|
|
215
|
+
function parentChainReachesVitePlus(segments) {
|
|
216
|
+
const concrete = segments.filter((segment) => segment !== "**");
|
|
217
|
+
let index = 0;
|
|
218
|
+
if (concrete.length > 0 && ancestorSegmentMatches(concrete[0], "vite-plus")) index = 1;
|
|
219
|
+
for (; index < concrete.length; index += 1) {
|
|
220
|
+
const segment = concrete[index];
|
|
221
|
+
if (!OWNED_PROVIDER_ANCESTOR_NAMES.some((name) => ancestorSegmentMatches(segment, name))) return false;
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
function extractOverrideParentSegments(key) {
|
|
226
|
+
let rest = key.trim();
|
|
227
|
+
const pnpmParents = [];
|
|
228
|
+
for (let delim = rest.search(/[^ |@]>/); delim !== -1; delim = rest.search(/[^ |@]>/)) {
|
|
229
|
+
pnpmParents.push(stripSegmentVersion(rest.slice(0, delim + 1).trim()));
|
|
230
|
+
rest = rest.slice(delim + 2).trim();
|
|
231
|
+
}
|
|
232
|
+
if (pnpmParents.length > 0) return pnpmParents;
|
|
233
|
+
if (!rest.includes("/")) return null;
|
|
234
|
+
const segments = rest.split("/");
|
|
235
|
+
const descriptorSegmentCount = segments[segments.length - 2]?.startsWith("@") ?? false ? 2 : 1;
|
|
236
|
+
const rawParents = segments.slice(0, segments.length - descriptorSegmentCount);
|
|
237
|
+
if (rawParents.length === 0) return null;
|
|
238
|
+
const parents = [];
|
|
239
|
+
for (let i = 0; i < rawParents.length; i += 1) {
|
|
240
|
+
const segment = rawParents[i];
|
|
241
|
+
if (segment.startsWith("@") && i + 1 < rawParents.length) {
|
|
242
|
+
parents.push(stripSegmentVersion(`${segment}/${rawParents[i + 1]}`));
|
|
243
|
+
i += 1;
|
|
244
|
+
} else parents.push(stripSegmentVersion(segment));
|
|
245
|
+
}
|
|
246
|
+
return parents;
|
|
247
|
+
}
|
|
248
|
+
function providerKeyReachesVitePlus(key, ancestorChain) {
|
|
249
|
+
if (!isRemovePackageOverrideKey(key)) return false;
|
|
250
|
+
const keyParents = extractOverrideParentSegments(key) ?? [];
|
|
251
|
+
return parentChainReachesVitePlus([...ancestorChain, ...keyParents]);
|
|
252
|
+
}
|
|
253
|
+
function shouldDropProviderOverrideKey(key) {
|
|
254
|
+
return providerKeyReachesVitePlus(key, []);
|
|
255
|
+
}
|
|
256
|
+
function childChainContribution(key) {
|
|
257
|
+
return [...extractOverrideParentSegments(key) ?? [], extractOverrideTargetName(key)];
|
|
258
|
+
}
|
|
259
|
+
// @vitest/provider`. Covers bare, versioned, global-glob and `vite-plus`-parent
|
|
260
|
+
function dropRemovePackageOverrideKeys(overrides, ancestorChain = []) {
|
|
261
|
+
if (!overrides) return false;
|
|
262
|
+
let removed = false;
|
|
263
|
+
for (const key of Object.keys(overrides)) {
|
|
264
|
+
const value = overrides[key];
|
|
265
|
+
const child = value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
266
|
+
if (providerKeyReachesVitePlus(key, ancestorChain)) {
|
|
267
|
+
if (child) {
|
|
268
|
+
let changed = false;
|
|
269
|
+
if ("." in child) {
|
|
270
|
+
delete child["."];
|
|
271
|
+
changed = true;
|
|
272
|
+
}
|
|
273
|
+
if (dropRemovePackageOverrideKeys(child, [...ancestorChain, ...childChainContribution(key)])) changed = true;
|
|
274
|
+
if (Object.keys(child).length === 0) {
|
|
275
|
+
delete overrides[key];
|
|
276
|
+
changed = true;
|
|
277
|
+
}
|
|
278
|
+
if (changed) removed = true;
|
|
279
|
+
} else {
|
|
280
|
+
delete overrides[key];
|
|
281
|
+
removed = true;
|
|
282
|
+
}
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (child) {
|
|
286
|
+
if (dropRemovePackageOverrideKeys(child, [...ancestorChain, ...childChainContribution(key)])) {
|
|
287
|
+
removed = true;
|
|
288
|
+
if (Object.keys(child).length === 0) delete overrides[key];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return removed;
|
|
293
|
+
}
|
|
180
294
|
const BROWSER_PROVIDER_PEER_DEPS = {
|
|
181
295
|
"@vitest/browser-playwright": "playwright",
|
|
182
296
|
"@vitest/browser-webdriverio": "webdriverio"
|
|
183
297
|
};
|
|
298
|
+
const BROWSER_PROVIDER_POSTINSTALL_PACKAGES = ["edgedriver", "geckodriver"];
|
|
299
|
+
const WEBDRIVERIO_ALLOW_SIGNAL_DEPS = ["webdriverio", WEBDRIVERIO_PROVIDER];
|
|
300
|
+
const VITEST_BROWSER_DEP_NAMES = [
|
|
301
|
+
"@vitest/browser",
|
|
302
|
+
"@vitest/browser-preview",
|
|
303
|
+
"@vitest/browser-playwright",
|
|
304
|
+
"@vitest/browser-webdriverio"
|
|
305
|
+
];
|
|
184
306
|
const PUBLIC_PEER_DEPENDENCY_FALLBACKS = {
|
|
185
307
|
vite: "*",
|
|
186
308
|
vitest: "*"
|
|
@@ -202,6 +324,46 @@ const OXLINT_NATIVE_PLUGINS = new Set([
|
|
|
202
324
|
"node",
|
|
203
325
|
"vue"
|
|
204
326
|
]);
|
|
327
|
+
const LEGACY_WRAPPER_PACKAGE_NAMES = ["@voidzero-dev/vite-plus-test"];
|
|
328
|
+
const LEGACY_WRAPPER_FALLBACK_VERSIONS = { vitest: VITEST_VERSION };
|
|
329
|
+
function isLegacyWrapperSpec(value) {
|
|
330
|
+
if (typeof value !== "string" || !value) return false;
|
|
331
|
+
for (const name of LEGACY_WRAPPER_PACKAGE_NAMES) if (value === `npm:${name}` || value.startsWith(`npm:${name}@`)) return true;
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Rewrite or remove keys whose value points at a deleted vite-plus wrapper.
|
|
336
|
+
* When a fallback exists for the key (e.g. `vitest`), the value is replaced
|
|
337
|
+
* so existing `catalog:` references continue to resolve. Otherwise the key
|
|
338
|
+
* is dropped entirely. Returns true iff any entry was changed.
|
|
339
|
+
*
|
|
340
|
+
* npm/bun `overrides` may nest an object of scoped overrides under a parent
|
|
341
|
+
* key (e.g. `{ "some-parent": { "vitest": "npm:@voidzero-dev/vite-plus-test@latest" } }`),
|
|
342
|
+
* so object values are recursed into; a parent emptied by pruning is dropped so
|
|
343
|
+
* no `{}` is left behind. Flat maps (pnpm `overrides`, yarn `resolutions`,
|
|
344
|
+
* catalogs) hold only string values, where the recursion is inert.
|
|
345
|
+
*/
|
|
346
|
+
function pruneLegacyWrapperAliases(record) {
|
|
347
|
+
if (!record) return false;
|
|
348
|
+
let mutated = false;
|
|
349
|
+
for (const key of Object.keys(record)) {
|
|
350
|
+
const value = record[key];
|
|
351
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
352
|
+
if (pruneLegacyWrapperAliases(value)) {
|
|
353
|
+
mutated = true;
|
|
354
|
+
if (Object.keys(value).length === 0) delete record[key];
|
|
355
|
+
}
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (isLegacyWrapperSpec(value)) {
|
|
359
|
+
const fallback = LEGACY_WRAPPER_FALLBACK_VERSIONS[key];
|
|
360
|
+
if (fallback !== void 0) record[key] = fallback;
|
|
361
|
+
else delete record[key];
|
|
362
|
+
mutated = true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return mutated;
|
|
366
|
+
}
|
|
205
367
|
function warnMigration(message, report) {
|
|
206
368
|
addMigrationWarning(report, message);
|
|
207
369
|
if (!report) log.warn(message);
|
|
@@ -643,11 +805,17 @@ function cleanupDeprecatedTsconfigOptions(projectPath, silent = false, report) {
|
|
|
643
805
|
}
|
|
644
806
|
}
|
|
645
807
|
function rewriteTsconfigTypes(projectPath, silent = false, report) {
|
|
808
|
+
let changed = false;
|
|
646
809
|
const files = findTsconfigFiles(projectPath);
|
|
647
810
|
for (const filePath of files) if (rewriteTypesInTsconfig(filePath)) {
|
|
811
|
+
changed = true;
|
|
648
812
|
if (report) report.removedConfigCount++;
|
|
649
813
|
if (!silent) log.success(`✔ Rewrote types in ${displayRelative(filePath)}`);
|
|
650
814
|
}
|
|
815
|
+
return changed;
|
|
816
|
+
}
|
|
817
|
+
function hasTsconfigTypesToRewrite(projectPath) {
|
|
818
|
+
return findTsconfigFiles(projectPath).some((filePath) => hasTypesToRewriteInTsconfig(filePath));
|
|
651
819
|
}
|
|
652
820
|
const FRAMEWORK_SHIMS = {
|
|
653
821
|
vue: [
|
|
@@ -716,51 +884,67 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
|
|
|
716
884
|
if (!fs.existsSync(packageJsonPath)) return;
|
|
717
885
|
const packageManager = workspaceInfo.packageManager;
|
|
718
886
|
const catalogDependencyResolver = createCatalogDependencyResolver(projectPath, packageManager);
|
|
887
|
+
const pnpmMajorVersion = pnpmMajor(workspaceInfo.downloadPackageManager.version);
|
|
719
888
|
let extractedStagedConfig = null;
|
|
720
889
|
let remainingPnpmOverrides;
|
|
721
890
|
let shouldRewritePnpmWorkspaceYaml = false;
|
|
722
891
|
let shouldAddPnpmWorkspaceVitePlusOverride = false;
|
|
892
|
+
let shouldAllowBrowserProviderBuilds = false;
|
|
723
893
|
let usePnpmWorkspaceYaml = false;
|
|
724
894
|
editJsonFile(packageJsonPath, (pkg) => {
|
|
895
|
+
shouldAllowBrowserProviderBuilds = hasOwnWebdriverioDependency(pkg) || usesWebdriverioProvider(projectPath);
|
|
896
|
+
pruneLegacyWrapperAliases(pkg.resolutions);
|
|
897
|
+
pruneLegacyWrapperAliases(pkg.overrides);
|
|
898
|
+
pruneLegacyWrapperAliases(pkg.pnpm?.overrides);
|
|
899
|
+
dropRemovePackageOverrideKeys(pkg.resolutions);
|
|
900
|
+
dropRemovePackageOverrideKeys(pkg.overrides);
|
|
725
901
|
if (packageManager === PackageManager.yarn) pkg.resolutions = {
|
|
726
902
|
...pkg.resolutions,
|
|
727
903
|
...VITE_PLUS_OVERRIDE_PACKAGES
|
|
728
904
|
};
|
|
729
|
-
else if (packageManager === PackageManager.npm || packageManager === PackageManager.bun)
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
905
|
+
else if (packageManager === PackageManager.npm || packageManager === PackageManager.bun) {
|
|
906
|
+
pkg.overrides = {
|
|
907
|
+
...pkg.overrides,
|
|
908
|
+
...VITE_PLUS_OVERRIDE_PACKAGES
|
|
909
|
+
};
|
|
910
|
+
if (packageManager === PackageManager.bun) pkg.devDependencies = {
|
|
911
|
+
...pkg.devDependencies,
|
|
912
|
+
vite: VITE_PLUS_OVERRIDE_PACKAGES.vite
|
|
913
|
+
};
|
|
914
|
+
} else if (packageManager === PackageManager.pnpm) {
|
|
734
915
|
usePnpmWorkspaceYaml = !pkg.pnpm;
|
|
735
916
|
if (usePnpmWorkspaceYaml) {
|
|
736
917
|
shouldRewritePnpmWorkspaceYaml = true;
|
|
737
918
|
shouldAddPnpmWorkspaceVitePlusOverride = isForceOverrideMode();
|
|
738
919
|
}
|
|
739
920
|
const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
|
|
740
|
-
if (!usePnpmWorkspaceYaml)
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
...pkg.pnpm
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
...pkg.pnpm?.peerDependencyRules?.
|
|
752
|
-
|
|
921
|
+
if (!usePnpmWorkspaceYaml) {
|
|
922
|
+
dropRemovePackageOverrideKeys(pkg.pnpm?.overrides);
|
|
923
|
+
pkg.pnpm = {
|
|
924
|
+
...pkg.pnpm,
|
|
925
|
+
overrides: {
|
|
926
|
+
...pkg.pnpm?.overrides,
|
|
927
|
+
...VITE_PLUS_OVERRIDE_PACKAGES,
|
|
928
|
+
...isForceOverrideMode() ? { [VITE_PLUS_NAME]: VITE_PLUS_VERSION } : {}
|
|
929
|
+
},
|
|
930
|
+
peerDependencyRules: {
|
|
931
|
+
...pkg.pnpm?.peerDependencyRules,
|
|
932
|
+
allowAny: [...new Set([...pkg.pnpm?.peerDependencyRules?.allowAny ?? [], ...overrideKeys])],
|
|
933
|
+
allowedVersions: {
|
|
934
|
+
...pkg.pnpm?.peerDependencyRules?.allowedVersions,
|
|
935
|
+
...Object.fromEntries(overrideKeys.map((key) => [key, "*"]))
|
|
936
|
+
}
|
|
753
937
|
}
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
else remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
|
|
938
|
+
};
|
|
939
|
+
} else remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
|
|
757
940
|
for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
|
|
758
941
|
const splits = key.split(">");
|
|
759
942
|
if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
|
|
760
943
|
}
|
|
761
|
-
for (const key of [...overrideKeys, ...
|
|
944
|
+
for (const key of [...overrideKeys, ...PROVIDER_OVERRIDE_DROP_NAMES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
|
|
945
|
+
if (!usePnpmWorkspaceYaml && pnpmMajorVersion !== void 0 && pkg.pnpm) applyBuildAllowanceToPackageJsonPnpm(pkg.pnpm, pnpmMajorVersion, shouldAllowBrowserProviderBuilds);
|
|
762
946
|
}
|
|
763
|
-
extractedStagedConfig = rewritePackageJson(pkg, packageManager, usePnpmWorkspaceYaml, skipStagedMigration, catalogDependencyResolver);
|
|
947
|
+
extractedStagedConfig = rewritePackageJson(pkg, packageManager, usePnpmWorkspaceYaml, skipStagedMigration, catalogDependencyResolver, usesVitestBrowserMode(projectPath), collectProviderSourceModes(projectPath));
|
|
764
948
|
if (!pkg.devDependencies?.["vite-plus"] || isForceOverrideMode()) {
|
|
765
949
|
const version = usePnpmWorkspaceYaml && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
|
|
766
950
|
pkg.devDependencies = {
|
|
@@ -770,10 +954,11 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
|
|
|
770
954
|
}
|
|
771
955
|
return pkg;
|
|
772
956
|
});
|
|
773
|
-
if (shouldRewritePnpmWorkspaceYaml) rewritePnpmWorkspaceYaml(projectPath);
|
|
957
|
+
if (shouldRewritePnpmWorkspaceYaml) rewritePnpmWorkspaceYaml(projectPath, pnpmMajorVersion, shouldAllowBrowserProviderBuilds);
|
|
774
958
|
if (remainingPnpmOverrides) migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
|
|
775
959
|
if (shouldAddPnpmWorkspaceVitePlusOverride) migratePnpmOverridesToWorkspaceYaml(projectPath, { [VITE_PLUS_NAME]: VITE_PLUS_VERSION });
|
|
776
960
|
if (packageManager === PackageManager.yarn) rewriteYarnrcYml(projectPath);
|
|
961
|
+
else if (packageManager === PackageManager.bun) ensureBunfigPeerSuppression(projectPath);
|
|
777
962
|
if (extractedStagedConfig) {
|
|
778
963
|
if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) removeLintStagedFromPackageJson(packageJsonPath);
|
|
779
964
|
}
|
|
@@ -785,6 +970,7 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
|
|
|
785
970
|
injectFmtDefaults(projectPath, silent, report);
|
|
786
971
|
mergeTsdownConfigFile(projectPath, silent, report);
|
|
787
972
|
rewriteAllImports(projectPath, silent, report);
|
|
973
|
+
wrapLazyPluginsInViteConfig(projectPath, silent, report);
|
|
788
974
|
setPackageManager(projectPath, workspaceInfo.downloadPackageManager);
|
|
789
975
|
}
|
|
790
976
|
/**
|
|
@@ -793,15 +979,17 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
|
|
|
793
979
|
*/
|
|
794
980
|
function rewriteMonorepo(workspaceInfo, skipStagedMigration, silent = false, report) {
|
|
795
981
|
const catalogDependencyResolver = createCatalogDependencyResolver(workspaceInfo.rootDir, workspaceInfo.packageManager);
|
|
796
|
-
|
|
982
|
+
const pnpmMajorVersion = pnpmMajor(workspaceInfo.downloadPackageManager.version);
|
|
983
|
+
const workspaceShouldAllowBrowserBuilds = workspaceUsesWebdriverio(workspaceInfo.rootDir, workspaceInfo.packages);
|
|
984
|
+
if (workspaceInfo.packageManager === PackageManager.pnpm) rewritePnpmWorkspaceYaml(workspaceInfo.rootDir, pnpmMajorVersion, workspaceShouldAllowBrowserBuilds);
|
|
797
985
|
else if (workspaceInfo.packageManager === PackageManager.yarn) rewriteYarnrcYml(workspaceInfo.rootDir);
|
|
798
986
|
else if (workspaceInfo.packageManager === PackageManager.bun) rewriteBunCatalog(workspaceInfo.rootDir);
|
|
799
|
-
rewriteRootWorkspacePackageJson(workspaceInfo.rootDir, workspaceInfo.packageManager, skipStagedMigration, catalogDependencyResolver, workspaceInfo.packages);
|
|
987
|
+
rewriteRootWorkspacePackageJson(workspaceInfo.rootDir, workspaceInfo.packageManager, skipStagedMigration, catalogDependencyResolver, workspaceInfo.packages, pnpmMajorVersion, workspaceShouldAllowBrowserBuilds);
|
|
800
988
|
const workspaceContext = {
|
|
801
989
|
rootDir: workspaceInfo.rootDir,
|
|
802
990
|
packages: workspaceInfo.packages
|
|
803
991
|
};
|
|
804
|
-
for (const pkg of workspaceInfo.packages) rewriteMonorepoProject(path.join(workspaceInfo.rootDir, pkg.path), workspaceInfo.packageManager, skipStagedMigration, silent, report, catalogDependencyResolver, workspaceContext);
|
|
992
|
+
for (const pkg of workspaceInfo.packages) rewriteMonorepoProject(path.join(workspaceInfo.rootDir, pkg.path), workspaceInfo.packageManager, skipStagedMigration, silent, report, catalogDependencyResolver, workspaceContext, true);
|
|
805
993
|
if (!skipStagedMigration) rewriteLintStagedConfigFile(workspaceInfo.rootDir, report);
|
|
806
994
|
cleanupDeprecatedTsconfigOptions(workspaceInfo.rootDir, silent, report);
|
|
807
995
|
rewriteTsconfigTypes(workspaceInfo.rootDir, silent, report);
|
|
@@ -810,6 +998,8 @@ function rewriteMonorepo(workspaceInfo, skipStagedMigration, silent = false, rep
|
|
|
810
998
|
injectFmtDefaults(workspaceInfo.rootDir, silent, report);
|
|
811
999
|
mergeTsdownConfigFile(workspaceInfo.rootDir, silent, report);
|
|
812
1000
|
rewriteAllImports(workspaceInfo.rootDir, silent, report);
|
|
1001
|
+
wrapLazyPluginsInViteConfig(workspaceInfo.rootDir, silent, report);
|
|
1002
|
+
for (const pkg of workspaceInfo.packages) wrapLazyPluginsInViteConfig(path.join(workspaceInfo.rootDir, pkg.path), silent, report);
|
|
813
1003
|
setPackageManager(workspaceInfo.rootDir, workspaceInfo.downloadPackageManager);
|
|
814
1004
|
}
|
|
815
1005
|
/**
|
|
@@ -821,32 +1011,41 @@ function rewriteMonorepo(workspaceInfo, skipStagedMigration, silent = false, rep
|
|
|
821
1011
|
* workspace root (paths in `packages` are relative to it); `packages`
|
|
822
1012
|
* is the workspace package list.
|
|
823
1013
|
*/
|
|
824
|
-
function rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration, silent = false, report, catalogDependencyResolver, workspaceContext) {
|
|
1014
|
+
function rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration, silent = false, report, catalogDependencyResolver, workspaceContext, deferLazyPluginWrapping = false) {
|
|
825
1015
|
cleanupDeprecatedTsconfigOptions(projectPath, silent, report);
|
|
826
1016
|
rewriteTsconfigTypes(projectPath, silent, report);
|
|
827
1017
|
mergeViteConfigFiles(projectPath, silent, report, workspaceContext?.packages, workspaceContext?.rootDir);
|
|
828
1018
|
mergeTsdownConfigFile(projectPath, silent, report);
|
|
829
1019
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
830
1020
|
if (!fs.existsSync(packageJsonPath)) return;
|
|
1021
|
+
const yarnHoisting = packageManager === PackageManager.yarn ? findYarnWorkspaceHoisting(workspaceContext?.rootDir ?? projectPath) : void 0;
|
|
831
1022
|
let extractedStagedConfig = null;
|
|
832
1023
|
editJsonFile(packageJsonPath, (pkg) => {
|
|
833
|
-
extractedStagedConfig = rewritePackageJson(pkg, packageManager, true, skipStagedMigration, catalogDependencyResolver);
|
|
1024
|
+
extractedStagedConfig = rewritePackageJson(pkg, packageManager, true, skipStagedMigration, catalogDependencyResolver, usesVitestBrowserMode(projectPath), collectProviderSourceModes(projectPath));
|
|
1025
|
+
if (yarnHoisting && path.resolve(projectPath) !== yarnHoisting.rootDir && pkg.devDependencies?.["vite-plus"]) applyYarnWorkspaceHoistingFix(pkg, yarnHoisting.limit, yarnHoisting.nodeLinker, path.relative(yarnHoisting.rootDir, projectPath) || projectPath, report);
|
|
834
1026
|
return pkg;
|
|
835
1027
|
});
|
|
836
1028
|
if (extractedStagedConfig) {
|
|
837
1029
|
if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) removeLintStagedFromPackageJson(packageJsonPath);
|
|
838
1030
|
}
|
|
1031
|
+
if (!deferLazyPluginWrapping) wrapLazyPluginsInViteConfig(projectPath, silent, report);
|
|
839
1032
|
}
|
|
840
1033
|
/**
|
|
841
1034
|
* Rewrite pnpm-workspace.yaml to add vite-plus dependencies
|
|
842
1035
|
* @param projectPath - The path to the project
|
|
843
1036
|
*/
|
|
844
|
-
function rewritePnpmWorkspaceYaml(projectPath) {
|
|
1037
|
+
function rewritePnpmWorkspaceYaml(projectPath, pnpmMajorVersion, shouldAllowBrowserBuilds) {
|
|
845
1038
|
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
846
1039
|
if (!fs.existsSync(pnpmWorkspaceYamlPath)) fs.writeFileSync(pnpmWorkspaceYamlPath, "");
|
|
847
1040
|
editYamlFile(pnpmWorkspaceYamlPath, (doc) => {
|
|
848
1041
|
rewriteCatalog(doc);
|
|
1042
|
+
if (pnpmMajorVersion !== void 0) applyBuildAllowanceToWorkspaceYaml(doc, pnpmMajorVersion, shouldAllowBrowserBuilds);
|
|
849
1043
|
const overrides = doc.getIn(["overrides"]);
|
|
1044
|
+
pruneYamlMapLegacyWrapperAliases(overrides);
|
|
1045
|
+
if (overrides instanceof import_dist.YAMLMap) {
|
|
1046
|
+
const keysSnapshot = overrides.items.map((item) => item.key);
|
|
1047
|
+
for (const keyNode of keysSnapshot) if (shouldDropProviderOverrideKey(keyNode instanceof import_dist.Scalar ? String(keyNode.value ?? "") : String(keyNode ?? ""))) overrides.delete(keyNode);
|
|
1048
|
+
}
|
|
850
1049
|
for (const key of Object.keys(VITE_PLUS_OVERRIDE_PACKAGES)) {
|
|
851
1050
|
const version = getCatalogDependencySpec(getYamlMapScalarStringValue(overrides, key), VITE_PLUS_OVERRIDE_PACKAGES[key], true);
|
|
852
1051
|
doc.setIn(["overrides", scalarString(key)], scalarString(version));
|
|
@@ -874,7 +1073,8 @@ function rewritePnpmWorkspaceYaml(projectPath) {
|
|
|
874
1073
|
"oxlint-tsgolint",
|
|
875
1074
|
"@oxlint-tsgolint/*",
|
|
876
1075
|
"oxfmt",
|
|
877
|
-
"@oxfmt/*"
|
|
1076
|
+
"@oxfmt/*",
|
|
1077
|
+
...VITEST_AGE_GATE_EXEMPT_PACKAGES
|
|
878
1078
|
];
|
|
879
1079
|
let minimumReleaseAgeExclude = doc.getIn(["minimumReleaseAgeExclude"]);
|
|
880
1080
|
if (!minimumReleaseAgeExclude) minimumReleaseAgeExclude = new import_dist.YAMLSeq();
|
|
@@ -890,9 +1090,10 @@ function rewritePnpmWorkspaceYaml(projectPath) {
|
|
|
890
1090
|
* moved to pnpm-workspace.yaml.
|
|
891
1091
|
*/
|
|
892
1092
|
function cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys) {
|
|
1093
|
+
dropRemovePackageOverrideKeys(pkg.pnpm?.overrides);
|
|
893
1094
|
const catalogOverrides = {};
|
|
894
1095
|
const overrides = pkg.pnpm?.overrides;
|
|
895
|
-
for (const key of [...overrideKeys, ...
|
|
1096
|
+
for (const key of [...overrideKeys, ...PROVIDER_OVERRIDE_DROP_NAMES]) {
|
|
896
1097
|
const value = overrides?.[key];
|
|
897
1098
|
if (value) {
|
|
898
1099
|
if (overrideKeys.includes(key) && value.startsWith("catalog:")) catalogOverrides[key] = value;
|
|
@@ -925,6 +1126,65 @@ function migratePnpmOverridesToWorkspaceYaml(projectPath, overrides) {
|
|
|
925
1126
|
for (const [key, value] of Object.entries(overrides)) doc.setIn(["overrides", scalarString(key)], scalarString(value));
|
|
926
1127
|
});
|
|
927
1128
|
}
|
|
1129
|
+
function hasOwnWebdriverioDependency(pkg) {
|
|
1130
|
+
for (const name of WEBDRIVERIO_ALLOW_SIGNAL_DEPS) if (pkg.dependencies?.[name] ?? pkg.devDependencies?.[name] ?? pkg.optionalDependencies?.[name] ?? pkg.peerDependencies?.[name]) return true;
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1133
|
+
function workspaceUsesWebdriverio(rootDir, packages) {
|
|
1134
|
+
const rootPkg = readPackageJsonIfExists(path.join(rootDir, "package.json"));
|
|
1135
|
+
if (rootPkg && hasOwnWebdriverioDependency(rootPkg)) return true;
|
|
1136
|
+
if (usesWebdriverioProvider(rootDir)) return true;
|
|
1137
|
+
if (!packages) return false;
|
|
1138
|
+
for (const pkg of packages) {
|
|
1139
|
+
const packageDir = path.join(rootDir, pkg.path);
|
|
1140
|
+
const subPkg = readPackageJsonIfExists(path.join(packageDir, "package.json"));
|
|
1141
|
+
if (subPkg && hasOwnWebdriverioDependency(subPkg)) return true;
|
|
1142
|
+
if (usesWebdriverioProvider(packageDir)) return true;
|
|
1143
|
+
}
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
function readPackageJsonIfExists(packageJsonPath) {
|
|
1147
|
+
if (!fs.existsSync(packageJsonPath)) return;
|
|
1148
|
+
try {
|
|
1149
|
+
return readJsonFile(packageJsonPath);
|
|
1150
|
+
} catch {
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function pnpmMajor(version) {
|
|
1155
|
+
const coerced = version ? import_semver.default.coerce(version)?.version : void 0;
|
|
1156
|
+
return coerced ? import_semver.default.major(coerced) : void 0;
|
|
1157
|
+
}
|
|
1158
|
+
function applyBuildAllowanceToPackageJsonPnpm(pnpm, major, shouldAllow) {
|
|
1159
|
+
if (major >= 10) {
|
|
1160
|
+
if (shouldAllow) for (const name of BROWSER_PROVIDER_POSTINSTALL_PACKAGES) (pnpm.allowBuilds ??= {})[name] = true;
|
|
1161
|
+
} else if (shouldAllow) {
|
|
1162
|
+
const list = pnpm.onlyBuiltDependencies ?? [];
|
|
1163
|
+
const existing = new Set(list);
|
|
1164
|
+
for (const name of BROWSER_PROVIDER_POSTINSTALL_PACKAGES) if (!existing.has(name)) {
|
|
1165
|
+
list.push(name);
|
|
1166
|
+
existing.add(name);
|
|
1167
|
+
}
|
|
1168
|
+
pnpm.onlyBuiltDependencies = list;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
function applyBuildAllowanceToWorkspaceYaml(doc, major, shouldAllow) {
|
|
1172
|
+
if (major >= 10) {
|
|
1173
|
+
if (shouldAllow) {
|
|
1174
|
+
const existing = doc.getIn(["allowBuilds"]);
|
|
1175
|
+
const isNew = !(existing instanceof import_dist.YAMLMap);
|
|
1176
|
+
const allowBuilds = isNew ? new import_dist.YAMLMap() : existing;
|
|
1177
|
+
for (const name of BROWSER_PROVIDER_POSTINSTALL_PACKAGES) allowBuilds.set(scalarString(name), new import_dist.Scalar(true));
|
|
1178
|
+
if (isNew) doc.setIn(["allowBuilds"], allowBuilds);
|
|
1179
|
+
}
|
|
1180
|
+
} else if (shouldAllow) {
|
|
1181
|
+
let onlyBuiltDependencies = doc.getIn(["onlyBuiltDependencies"]);
|
|
1182
|
+
if (!(onlyBuiltDependencies instanceof import_dist.YAMLSeq)) onlyBuiltDependencies = new import_dist.YAMLSeq();
|
|
1183
|
+
const existing = new Set(onlyBuiltDependencies.items.map((n) => n.value));
|
|
1184
|
+
for (const name of BROWSER_PROVIDER_POSTINSTALL_PACKAGES) if (!existing.has(name)) onlyBuiltDependencies.add(scalarString(name));
|
|
1185
|
+
doc.setIn(["onlyBuiltDependencies"], onlyBuiltDependencies);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
928
1188
|
/**
|
|
929
1189
|
* Remove only Vite-managed entries from peerDependencyRules, preserving custom ones.
|
|
930
1190
|
*/
|
|
@@ -943,11 +1203,78 @@ function cleanupPeerDependencyRules(peerDependencyRules, overrideKeys) {
|
|
|
943
1203
|
* Rewrite .yarnrc.yml to add vite-plus dependencies
|
|
944
1204
|
* @param projectPath - The path to the project
|
|
945
1205
|
*/
|
|
1206
|
+
function readYarnrcValue(dir, key) {
|
|
1207
|
+
const yarnrcYmlPath = path.join(dir, ".yarnrc.yml");
|
|
1208
|
+
if (!fs.existsSync(yarnrcYmlPath)) return;
|
|
1209
|
+
try {
|
|
1210
|
+
const value = readYamlFile(yarnrcYmlPath)?.[key];
|
|
1211
|
+
return typeof value === "string" ? value : void 0;
|
|
1212
|
+
} catch {
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
function resolveEffectiveYarnConfigValue(workspaceRootDir, key, envVar) {
|
|
1217
|
+
const fromEnv = process.env[envVar]?.trim();
|
|
1218
|
+
if (fromEnv) return fromEnv;
|
|
1219
|
+
let dir = path.resolve(workspaceRootDir);
|
|
1220
|
+
for (;;) {
|
|
1221
|
+
const value = readYarnrcValue(dir, key);
|
|
1222
|
+
if (value !== void 0) return value;
|
|
1223
|
+
const parent = path.dirname(dir);
|
|
1224
|
+
if (parent === dir) break;
|
|
1225
|
+
dir = parent;
|
|
1226
|
+
}
|
|
1227
|
+
const home = os.homedir();
|
|
1228
|
+
return home ? readYarnrcValue(home, key) : void 0;
|
|
1229
|
+
}
|
|
1230
|
+
function dirIsWorkspaceRoot(dir) {
|
|
1231
|
+
const pkgJsonPath = path.join(dir, "package.json");
|
|
1232
|
+
if (!fs.existsSync(pkgJsonPath)) return false;
|
|
1233
|
+
try {
|
|
1234
|
+
return readJsonFile(pkgJsonPath).workspaces != null;
|
|
1235
|
+
} catch {
|
|
1236
|
+
return false;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
function findYarnWorkspaceHoisting(startDir) {
|
|
1240
|
+
let dir = path.resolve(startDir);
|
|
1241
|
+
for (;;) {
|
|
1242
|
+
if (dirIsWorkspaceRoot(dir)) return {
|
|
1243
|
+
rootDir: dir,
|
|
1244
|
+
limit: resolveEffectiveYarnConfigValue(dir, "nmHoistingLimits", "YARN_NM_HOISTING_LIMITS"),
|
|
1245
|
+
nodeLinker: resolveEffectiveYarnConfigValue(dir, "nodeLinker", "YARN_NODE_LINKER")
|
|
1246
|
+
};
|
|
1247
|
+
const parent = path.dirname(dir);
|
|
1248
|
+
if (parent === dir) return;
|
|
1249
|
+
dir = parent;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
function setYarnWorkspaceHoistingOptOut(pkg) {
|
|
1253
|
+
if (pkg.installConfig?.hoistingLimits !== void 0) return;
|
|
1254
|
+
pkg.installConfig = {
|
|
1255
|
+
...pkg.installConfig,
|
|
1256
|
+
hoistingLimits: "none"
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
function applyYarnWorkspaceHoistingFix(pkg, rootLimit, nodeLinker, workspaceLabel, report) {
|
|
1260
|
+
if (nodeLinker !== "node-modules") return;
|
|
1261
|
+
if (rootLimit === "workspaces" && pkg.installConfig?.hoistingLimits === void 0) {
|
|
1262
|
+
setYarnWorkspaceHoistingOptOut(pkg);
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
const explicit = pkg.installConfig?.hoistingLimits;
|
|
1266
|
+
if (rootLimit === "dependencies" || explicit === "workspaces" || explicit === "dependencies") warnMigration(`Yarn workspace "${workspaceLabel}" isolates dependency hoisting (hoistingLimits: ${explicit ?? rootLimit}), so it keeps its own \`vitest\`/\`vite-plus\` copy and \`vp test\` may crash with a split \`@vitest/runner\`. Dedupe them to a single copy — relax this workspace's hoisting isolation or pin one \`vitest\` for the workspace.`, report);
|
|
1267
|
+
}
|
|
946
1268
|
function rewriteYarnrcYml(projectPath) {
|
|
947
1269
|
const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
|
|
948
1270
|
if (!fs.existsSync(yarnrcYmlPath)) fs.writeFileSync(yarnrcYmlPath, "");
|
|
949
1271
|
editYamlFile(yarnrcYmlPath, (doc) => {
|
|
950
1272
|
if (!doc.has("nodeLinker")) doc.set("nodeLinker", "node-modules");
|
|
1273
|
+
let npmPreapprovedPackages = doc.getIn(["npmPreapprovedPackages"]);
|
|
1274
|
+
if (!npmPreapprovedPackages) npmPreapprovedPackages = new import_dist.YAMLSeq();
|
|
1275
|
+
const existingPreapproved = new Set(npmPreapprovedPackages.items.map((n) => n.value));
|
|
1276
|
+
for (const pkg of VITEST_AGE_GATE_EXEMPT_PACKAGES) if (!existingPreapproved.has(pkg)) npmPreapprovedPackages.add(scalarString(pkg));
|
|
1277
|
+
doc.setIn(["npmPreapprovedPackages"], npmPreapprovedPackages);
|
|
951
1278
|
rewriteCatalog(doc);
|
|
952
1279
|
});
|
|
953
1280
|
}
|
|
@@ -989,17 +1316,15 @@ function createCatalogDependencyResolver(projectPath, packageManager) {
|
|
|
989
1316
|
if (!fs.existsSync(packageJsonPath)) return;
|
|
990
1317
|
const pkg = readJsonFile(packageJsonPath);
|
|
991
1318
|
const workspacesObj = pkg.workspaces && !Array.isArray(pkg.workspaces) ? pkg.workspaces : void 0;
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
return workspacesObj?.catalog?.[dependencyName] ?? pkg.catalog?.[dependencyName];
|
|
996
|
-
};
|
|
1319
|
+
const fromWorkspaces = createCatalogDependencyResolverFromCatalogs(workspacesObj?.catalog, workspacesObj?.catalogs);
|
|
1320
|
+
const fromPkg = createCatalogDependencyResolverFromCatalogs(pkg.catalog, pkg.catalogs);
|
|
1321
|
+
return (catalogSpec, dependencyName) => fromWorkspaces(catalogSpec, dependencyName) ?? fromPkg(catalogSpec, dependencyName);
|
|
997
1322
|
}
|
|
998
1323
|
}
|
|
999
1324
|
function createCatalogDependencyResolverFromCatalogs(catalog, catalogs) {
|
|
1000
1325
|
return (catalogSpec, dependencyName) => {
|
|
1001
1326
|
const catalogName = catalogSpec.slice(8);
|
|
1002
|
-
if (catalogName) return catalogs?.[catalogName]?.[dependencyName];
|
|
1327
|
+
if (catalogName && catalogName !== "default") return catalogs?.[catalogName]?.[dependencyName];
|
|
1003
1328
|
return catalog?.[dependencyName];
|
|
1004
1329
|
};
|
|
1005
1330
|
}
|
|
@@ -1007,6 +1332,19 @@ function getYamlMapScalarStringValue(map, key) {
|
|
|
1007
1332
|
if (!(map instanceof import_dist.YAMLMap)) return;
|
|
1008
1333
|
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;
|
|
1009
1334
|
}
|
|
1335
|
+
function pruneYamlMapLegacyWrapperAliases(map) {
|
|
1336
|
+
if (!(map instanceof import_dist.YAMLMap)) return;
|
|
1337
|
+
const stale = [];
|
|
1338
|
+
for (const item of map.items) {
|
|
1339
|
+
const value = item.value instanceof import_dist.Scalar ? item.value.value : void 0;
|
|
1340
|
+
if (typeof value === "string" && isLegacyWrapperSpec(value) && item.key instanceof import_dist.Scalar) stale.push({
|
|
1341
|
+
key: item.key,
|
|
1342
|
+
fallback: LEGACY_WRAPPER_FALLBACK_VERSIONS[item.key.value]
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
for (const { key, fallback } of stale) if (fallback !== void 0) map.set(key, scalarString(fallback));
|
|
1346
|
+
else map.delete(key);
|
|
1347
|
+
}
|
|
1010
1348
|
function rewriteCatalog(doc) {
|
|
1011
1349
|
for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) {
|
|
1012
1350
|
if (value.startsWith("file:")) continue;
|
|
@@ -1017,6 +1355,7 @@ function rewriteCatalog(doc) {
|
|
|
1017
1355
|
const path = ["catalog", name];
|
|
1018
1356
|
if (doc.hasIn(path)) doc.deleteIn(path);
|
|
1019
1357
|
}
|
|
1358
|
+
pruneYamlMapLegacyWrapperAliases(doc.getIn(["catalog"]));
|
|
1020
1359
|
const catalogs = doc.getIn(["catalogs"]);
|
|
1021
1360
|
if (!(catalogs instanceof import_dist.YAMLMap)) return;
|
|
1022
1361
|
for (const item of catalogs.items) {
|
|
@@ -1044,6 +1383,7 @@ function rewriteCatalog(doc) {
|
|
|
1044
1383
|
];
|
|
1045
1384
|
if (doc.hasIn(catalogPath)) doc.deleteIn(catalogPath);
|
|
1046
1385
|
}
|
|
1386
|
+
pruneYamlMapLegacyWrapperAliases(item.value);
|
|
1047
1387
|
}
|
|
1048
1388
|
}
|
|
1049
1389
|
function rewriteCatalogObject(catalog, addMissing) {
|
|
@@ -1058,6 +1398,34 @@ function rewriteCatalogsObject(catalogs) {
|
|
|
1058
1398
|
for (const catalog of Object.values(catalogs)) rewriteCatalogObject(catalog, false);
|
|
1059
1399
|
}
|
|
1060
1400
|
/**
|
|
1401
|
+
* Bun rejects vitest@4.1.9's `vite^6/^7/^8` peer-dep when the user's project
|
|
1402
|
+
* overrides `vite` to `@voidzero-dev/vite-plus-core` (whose package.json version
|
|
1403
|
+
* does not match those ranges). pnpm/yarn/npm all tolerate this redirect; bun
|
|
1404
|
+
* does not, and there is no `peerDependencyRules`-style escape hatch — only the
|
|
1405
|
+
* `[install] peer = false` setting in `bunfig.toml`.
|
|
1406
|
+
*
|
|
1407
|
+
* `vite-plus`/`@voidzero-dev/vite-plus-core` already provide the vite surface
|
|
1408
|
+
* the user needs, so disabling bun's auto-install of *missing* peers is safe in
|
|
1409
|
+
* this configuration: any vitest peer that's not already pulled in transitively
|
|
1410
|
+
* (jsdom, happy-dom, etc.) is marked optional upstream anyway.
|
|
1411
|
+
*
|
|
1412
|
+
* Writes/merges `bunfig.toml` at `projectPath` so the suppression applies on
|
|
1413
|
+
* the migration's reinstall AND every subsequent `bun install` the user runs.
|
|
1414
|
+
*/
|
|
1415
|
+
function ensureBunfigPeerSuppression(projectPath) {
|
|
1416
|
+
const bunfigPath = path.join(projectPath, "bunfig.toml");
|
|
1417
|
+
const block = "[install]\npeer = false\n";
|
|
1418
|
+
if (!fs.existsSync(bunfigPath)) {
|
|
1419
|
+
fs.writeFileSync(bunfigPath, block);
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const existing = fs.readFileSync(bunfigPath, "utf8");
|
|
1423
|
+
if (/^\s*peer\s*=\s*(true|false)\s*$/m.test(existing)) return;
|
|
1424
|
+
const installSectionRe = /^\[install\][^[]*/m;
|
|
1425
|
+
const next = installSectionRe.test(existing) ? existing.replace(installSectionRe, (section) => `${section.trimEnd()}\npeer = false\n`) : `${existing.trimEnd()}\n\n${block}`;
|
|
1426
|
+
fs.writeFileSync(bunfigPath, next);
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1061
1429
|
* Write catalog entries to root package.json for bun.
|
|
1062
1430
|
* Bun stores catalogs in package.json under the `catalog` key,
|
|
1063
1431
|
* unlike pnpm which uses pnpm-workspace.yaml.
|
|
@@ -1071,30 +1439,54 @@ function rewriteBunCatalog(projectPath) {
|
|
|
1071
1439
|
const useWorkspacesCatalog = workspacesObj?.catalog != null || pkg.catalog == null && workspacesObj?.catalogs != null;
|
|
1072
1440
|
const catalog = { ...useWorkspacesCatalog ? workspacesObj?.catalog : pkg.catalog };
|
|
1073
1441
|
rewriteCatalogObject(catalog, true);
|
|
1442
|
+
pruneLegacyWrapperAliases(catalog);
|
|
1074
1443
|
if (useWorkspacesCatalog) {
|
|
1075
1444
|
workspacesObj.catalog = catalog;
|
|
1076
|
-
if (pkg.catalog)
|
|
1445
|
+
if (pkg.catalog) {
|
|
1446
|
+
rewriteCatalogObject(pkg.catalog, false);
|
|
1447
|
+
pruneLegacyWrapperAliases(pkg.catalog);
|
|
1448
|
+
}
|
|
1077
1449
|
} else {
|
|
1078
1450
|
pkg.catalog = catalog;
|
|
1079
|
-
if (workspacesObj?.catalog)
|
|
1451
|
+
if (workspacesObj?.catalog) {
|
|
1452
|
+
rewriteCatalogObject(workspacesObj.catalog, false);
|
|
1453
|
+
pruneLegacyWrapperAliases(workspacesObj.catalog);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (workspacesObj?.catalogs) {
|
|
1457
|
+
rewriteCatalogsObject(workspacesObj.catalogs);
|
|
1458
|
+
for (const named of Object.values(workspacesObj.catalogs)) pruneLegacyWrapperAliases(named);
|
|
1459
|
+
}
|
|
1460
|
+
if (pkg.catalogs) {
|
|
1461
|
+
rewriteCatalogsObject(pkg.catalogs);
|
|
1462
|
+
for (const named of Object.values(pkg.catalogs)) pruneLegacyWrapperAliases(named);
|
|
1080
1463
|
}
|
|
1081
|
-
if (workspacesObj?.catalogs) rewriteCatalogsObject(workspacesObj.catalogs);
|
|
1082
|
-
if (pkg.catalogs) rewriteCatalogsObject(pkg.catalogs);
|
|
1083
1464
|
const overrides = { ...pkg.overrides };
|
|
1084
|
-
|
|
1465
|
+
pruneLegacyWrapperAliases(overrides);
|
|
1466
|
+
for (const [key, value] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) {
|
|
1467
|
+
const current = overrides[key];
|
|
1468
|
+
if (current !== void 0 && typeof current !== "string") continue;
|
|
1469
|
+
overrides[key] = getCatalogDependencySpec(current, value, true);
|
|
1470
|
+
}
|
|
1085
1471
|
pkg.overrides = overrides;
|
|
1086
1472
|
return pkg;
|
|
1087
1473
|
});
|
|
1474
|
+
ensureBunfigPeerSuppression(projectPath);
|
|
1088
1475
|
}
|
|
1089
1476
|
/**
|
|
1090
1477
|
* Rewrite root workspace package.json to add vite-plus dependencies
|
|
1091
1478
|
* @param projectPath - The path to the project
|
|
1092
1479
|
*/
|
|
1093
|
-
function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStagedMigration, catalogDependencyResolver, packages) {
|
|
1480
|
+
function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStagedMigration, catalogDependencyResolver, packages, pnpmMajorVersion, shouldAllowBrowserBuilds = false) {
|
|
1094
1481
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
1095
1482
|
if (!fs.existsSync(packageJsonPath)) return;
|
|
1096
1483
|
let remainingPnpmOverrides;
|
|
1097
1484
|
editJsonFile(packageJsonPath, (pkg) => {
|
|
1485
|
+
pruneLegacyWrapperAliases(pkg.resolutions);
|
|
1486
|
+
pruneLegacyWrapperAliases(pkg.overrides);
|
|
1487
|
+
pruneLegacyWrapperAliases(pkg.pnpm?.overrides);
|
|
1488
|
+
dropRemovePackageOverrideKeys(pkg.resolutions);
|
|
1489
|
+
dropRemovePackageOverrideKeys(pkg.overrides);
|
|
1098
1490
|
if (packageManager === PackageManager.yarn) pkg.resolutions = {
|
|
1099
1491
|
...pkg.resolutions,
|
|
1100
1492
|
...VITE_PLUS_OVERRIDE_PACKAGES
|
|
@@ -1103,24 +1495,31 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
|
|
|
1103
1495
|
...pkg.overrides,
|
|
1104
1496
|
...VITE_PLUS_OVERRIDE_PACKAGES
|
|
1105
1497
|
};
|
|
1106
|
-
else if (packageManager === PackageManager.bun)
|
|
1498
|
+
else if (packageManager === PackageManager.bun) pkg.devDependencies = {
|
|
1499
|
+
...pkg.devDependencies,
|
|
1500
|
+
vite: getCatalogDependencySpec(pkg.devDependencies?.vite, VITE_PLUS_OVERRIDE_PACKAGES.vite, true)
|
|
1501
|
+
};
|
|
1502
|
+
else if (packageManager === PackageManager.pnpm) {
|
|
1107
1503
|
const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
|
|
1108
|
-
if (isForceOverrideMode())
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
...pkg.pnpm
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1504
|
+
if (isForceOverrideMode()) {
|
|
1505
|
+
dropRemovePackageOverrideKeys(pkg.pnpm?.overrides);
|
|
1506
|
+
pkg.pnpm = {
|
|
1507
|
+
...pkg.pnpm,
|
|
1508
|
+
overrides: {
|
|
1509
|
+
...pkg.pnpm?.overrides,
|
|
1510
|
+
...VITE_PLUS_OVERRIDE_PACKAGES,
|
|
1511
|
+
[VITE_PLUS_NAME]: VITE_PLUS_VERSION
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
} else {
|
|
1515
|
+
for (const key of [...overrideKeys, ...PROVIDER_OVERRIDE_DROP_NAMES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
|
|
1118
1516
|
remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
|
|
1119
1517
|
}
|
|
1120
1518
|
for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
|
|
1121
1519
|
const splits = key.split(">");
|
|
1122
1520
|
if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
|
|
1123
1521
|
}
|
|
1522
|
+
if (pnpmMajorVersion !== void 0 && pkg.pnpm) applyBuildAllowanceToPackageJsonPnpm(pkg.pnpm, pnpmMajorVersion, shouldAllowBrowserBuilds);
|
|
1124
1523
|
}
|
|
1125
1524
|
if (!pkg.devDependencies?.["vite-plus"]) pkg.devDependencies = {
|
|
1126
1525
|
...pkg.devDependencies,
|
|
@@ -1132,7 +1531,7 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
|
|
|
1132
1531
|
rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration, void 0, void 0, catalogDependencyResolver, packages ? {
|
|
1133
1532
|
rootDir: projectPath,
|
|
1134
1533
|
packages
|
|
1135
|
-
} : void 0);
|
|
1534
|
+
} : void 0, true);
|
|
1136
1535
|
}
|
|
1137
1536
|
const RULES_YAML_PATH = path.join(rulesDir, "vite-tools.yml");
|
|
1138
1537
|
const PREPARE_RULES_YAML_PATH = path.join(rulesDir, "vite-prepare.yml");
|
|
@@ -1153,7 +1552,401 @@ function readPrepareRulesYaml() {
|
|
|
1153
1552
|
cachedPrepareRulesYaml ??= fs.readFileSync(PREPARE_RULES_YAML_PATH, "utf8");
|
|
1154
1553
|
return cachedPrepareRulesYaml;
|
|
1155
1554
|
}
|
|
1156
|
-
function
|
|
1555
|
+
function getCoreMigrationProjectPaths(workspaceInfo) {
|
|
1556
|
+
return [workspaceInfo.rootDir, ...(workspaceInfo.packages ?? []).map((pkg) => path.join(workspaceInfo.rootDir, pkg.path))];
|
|
1557
|
+
}
|
|
1558
|
+
function hasCorePackageScriptRewrites(projectPath) {
|
|
1559
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
1560
|
+
if (!fs.existsSync(packageJsonPath)) return false;
|
|
1561
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
1562
|
+
if (!pkg.scripts) return false;
|
|
1563
|
+
return !!rewriteScripts(JSON.stringify(pkg.scripts), getScriptRulesYaml(true));
|
|
1564
|
+
}
|
|
1565
|
+
function rewriteCorePackageScripts(projectPath) {
|
|
1566
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
1567
|
+
if (!fs.existsSync(packageJsonPath)) return false;
|
|
1568
|
+
let changed = false;
|
|
1569
|
+
editJsonFile(packageJsonPath, (pkg) => {
|
|
1570
|
+
if (!pkg.scripts) return;
|
|
1571
|
+
const updated = rewriteScripts(JSON.stringify(pkg.scripts), getScriptRulesYaml(true));
|
|
1572
|
+
if (!updated) return;
|
|
1573
|
+
pkg.scripts = JSON.parse(updated);
|
|
1574
|
+
changed = true;
|
|
1575
|
+
return pkg;
|
|
1576
|
+
});
|
|
1577
|
+
return changed;
|
|
1578
|
+
}
|
|
1579
|
+
function detectPendingCoreMigration(workspaceInfo) {
|
|
1580
|
+
const projectPaths = getCoreMigrationProjectPaths(workspaceInfo);
|
|
1581
|
+
return {
|
|
1582
|
+
scripts: projectPaths.some((projectPath) => hasCorePackageScriptRewrites(projectPath)),
|
|
1583
|
+
tsconfigTypes: projectPaths.some((projectPath) => hasTsconfigTypesToRewrite(projectPath))
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
function finalizeCoreMigrationForExistingVitePlus(workspaceInfo, silent = false, report, pending = detectPendingCoreMigration(workspaceInfo)) {
|
|
1587
|
+
const projectPaths = getCoreMigrationProjectPaths(workspaceInfo);
|
|
1588
|
+
const result = {
|
|
1589
|
+
scripts: false,
|
|
1590
|
+
tsconfigTypes: false,
|
|
1591
|
+
imports: false
|
|
1592
|
+
};
|
|
1593
|
+
if (pending.scripts) for (const projectPath of projectPaths) result.scripts = rewriteCorePackageScripts(projectPath) || result.scripts;
|
|
1594
|
+
if (pending.tsconfigTypes) for (const projectPath of projectPaths) result.tsconfigTypes = rewriteTsconfigTypes(projectPath, silent, report) || result.tsconfigTypes;
|
|
1595
|
+
result.imports = rewriteAllImports(workspaceInfo.rootDir, silent, report);
|
|
1596
|
+
return result;
|
|
1597
|
+
}
|
|
1598
|
+
function getVitePlusOverridePackageName(dependencyName) {
|
|
1599
|
+
if (dependencyName === "vite") return "@voidzero-dev/vite-plus-core";
|
|
1600
|
+
if (dependencyName === "vitest") return "@voidzero-dev/vite-plus-test";
|
|
1601
|
+
}
|
|
1602
|
+
function isSemanticVitePlusOverrideSpec(dependencyName, spec) {
|
|
1603
|
+
if (!spec) return false;
|
|
1604
|
+
if (isLegacyWrapperSpec(spec)) return false;
|
|
1605
|
+
if (spec === VITE_PLUS_OVERRIDE_PACKAGES[dependencyName]) return true;
|
|
1606
|
+
const packageName = getVitePlusOverridePackageName(dependencyName);
|
|
1607
|
+
return packageName !== void 0 && spec.includes(packageName);
|
|
1608
|
+
}
|
|
1609
|
+
function overrideSpecSatisfiesVitePlus(dependencyName, spec, catalogDependencyResolver) {
|
|
1610
|
+
if (!spec) return false;
|
|
1611
|
+
if (isSemanticVitePlusOverrideSpec(dependencyName, spec)) return true;
|
|
1612
|
+
if (!spec.startsWith("catalog:")) return false;
|
|
1613
|
+
return isSemanticVitePlusOverrideSpec(dependencyName, catalogDependencyResolver?.(spec, dependencyName));
|
|
1614
|
+
}
|
|
1615
|
+
function overridesSatisfyVitePlus(overrides, catalogDependencyResolver) {
|
|
1616
|
+
return Object.keys(VITE_PLUS_OVERRIDE_PACKAGES).every((dependencyName) => overrideSpecSatisfiesVitePlus(dependencyName, overrides?.[dependencyName], catalogDependencyResolver));
|
|
1617
|
+
}
|
|
1618
|
+
function hasPackageManagerPin(pkg) {
|
|
1619
|
+
return Boolean(pkg.packageManager || pkg.devEngines?.packageManager);
|
|
1620
|
+
}
|
|
1621
|
+
function vitePlusDependencyNeedsConcreteVersion(pkg) {
|
|
1622
|
+
return [
|
|
1623
|
+
pkg.devDependencies,
|
|
1624
|
+
pkg.dependencies,
|
|
1625
|
+
pkg.optionalDependencies
|
|
1626
|
+
].some((dependencies) => dependencies?.["vite-plus"]?.startsWith("catalog:") ?? false);
|
|
1627
|
+
}
|
|
1628
|
+
function defaultCatalogVitePlusDependencyPending(pkg, catalogDependencyResolver) {
|
|
1629
|
+
return [
|
|
1630
|
+
pkg.devDependencies,
|
|
1631
|
+
pkg.dependencies,
|
|
1632
|
+
pkg.optionalDependencies
|
|
1633
|
+
].some((dependencies) => {
|
|
1634
|
+
const spec = dependencies?.[VITE_PLUS_NAME];
|
|
1635
|
+
if (spec !== "catalog:" && spec !== "catalog:default") return false;
|
|
1636
|
+
return catalogDependencyResolver?.(spec, VITE_PLUS_NAME) !== VITE_PLUS_VERSION;
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
function pnpmPeerDependencyRulesSatisfyVitePlus(peerDependencyRules) {
|
|
1640
|
+
const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
|
|
1641
|
+
const allowAny = new Set(peerDependencyRules?.allowAny ?? []);
|
|
1642
|
+
const allowedVersions = peerDependencyRules?.allowedVersions ?? {};
|
|
1643
|
+
return overrideKeys.every((key) => allowAny.has(key) && allowedVersions[key] === "*");
|
|
1644
|
+
}
|
|
1645
|
+
function npmVitePlusManagedDependenciesPending(pkg) {
|
|
1646
|
+
const dependencyGroups = [
|
|
1647
|
+
pkg.devDependencies,
|
|
1648
|
+
pkg.dependencies,
|
|
1649
|
+
pkg.optionalDependencies
|
|
1650
|
+
];
|
|
1651
|
+
return Object.keys(VITE_PLUS_OVERRIDE_PACKAGES).some((dependencyName) => dependencyGroups.some((dependencies) => dependencies?.[dependencyName] !== void 0 && !overrideSpecSatisfiesVitePlus(dependencyName, dependencies[dependencyName])));
|
|
1652
|
+
}
|
|
1653
|
+
function readPnpmWorkspaceCatalogDependencyResolver(projectPath) {
|
|
1654
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
1655
|
+
if (!fs.existsSync(pnpmWorkspaceYamlPath)) return;
|
|
1656
|
+
const doc = readYamlFile(pnpmWorkspaceYamlPath);
|
|
1657
|
+
return createCatalogDependencyResolverFromCatalogs(doc?.catalog, doc?.catalogs);
|
|
1658
|
+
}
|
|
1659
|
+
function readPnpmWorkspaceOverrides(projectPath) {
|
|
1660
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
1661
|
+
if (!fs.existsSync(pnpmWorkspaceYamlPath)) return;
|
|
1662
|
+
return readYamlFile(pnpmWorkspaceYamlPath)?.overrides;
|
|
1663
|
+
}
|
|
1664
|
+
function readPnpmWorkspacePeerDependencyRules(projectPath) {
|
|
1665
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
1666
|
+
if (!fs.existsSync(pnpmWorkspaceYamlPath)) return;
|
|
1667
|
+
return readYamlFile(pnpmWorkspaceYamlPath)?.peerDependencyRules;
|
|
1668
|
+
}
|
|
1669
|
+
function yarnrcSatisfiesVitePlus(projectPath) {
|
|
1670
|
+
const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
|
|
1671
|
+
if (!fs.existsSync(yarnrcYmlPath)) return false;
|
|
1672
|
+
const doc = readYamlFile(yarnrcYmlPath);
|
|
1673
|
+
return !!doc && Object.hasOwn(doc, "nodeLinker") && overridesSatisfyVitePlus(doc.catalog) && (VITE_PLUS_VERSION.startsWith("file:") || doc.catalog?.["vite-plus"] === VITE_PLUS_VERSION);
|
|
1674
|
+
}
|
|
1675
|
+
function ensurePnpmWorkspacePackages(projectPath, workspacePatterns) {
|
|
1676
|
+
if (workspacePatterns.length === 0) return false;
|
|
1677
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
1678
|
+
let changed = false;
|
|
1679
|
+
editYamlFile(pnpmWorkspaceYamlPath, (doc) => {
|
|
1680
|
+
if (doc.has("packages")) return;
|
|
1681
|
+
const packages = new import_dist.YAMLSeq();
|
|
1682
|
+
for (const pattern of workspacePatterns) packages.add(scalarString(pattern));
|
|
1683
|
+
doc.set("packages", packages);
|
|
1684
|
+
changed = true;
|
|
1685
|
+
});
|
|
1686
|
+
return changed;
|
|
1687
|
+
}
|
|
1688
|
+
function readBunCatalogDependencyResolver(pkg) {
|
|
1689
|
+
const workspacesObj = pkg.workspaces && !Array.isArray(pkg.workspaces) ? pkg.workspaces : {};
|
|
1690
|
+
const fromWorkspaces = createCatalogDependencyResolverFromCatalogs(workspacesObj.catalog, workspacesObj.catalogs);
|
|
1691
|
+
const fromPkg = createCatalogDependencyResolverFromCatalogs(pkg.catalog, pkg.catalogs);
|
|
1692
|
+
return (catalogSpec, dependencyName) => fromWorkspaces(catalogSpec, dependencyName) ?? fromPkg(catalogSpec, dependencyName);
|
|
1693
|
+
}
|
|
1694
|
+
function detectVitePlusBootstrapPending(projectPath, packageManager) {
|
|
1695
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
1696
|
+
if (!fs.existsSync(packageJsonPath)) return false;
|
|
1697
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
1698
|
+
if (!pkg.devDependencies?.["vite-plus"] || !hasPackageManagerPin(pkg)) return true;
|
|
1699
|
+
if (packageManager === void 0) return true;
|
|
1700
|
+
if (packageManager === PackageManager.yarn) return !overridesSatisfyVitePlus(pkg.resolutions) || !yarnrcSatisfiesVitePlus(projectPath);
|
|
1701
|
+
if (packageManager === PackageManager.npm) return vitePlusDependencyNeedsConcreteVersion(pkg) || !overridesSatisfyVitePlus(pkg.overrides) || npmVitePlusManagedDependenciesPending(pkg);
|
|
1702
|
+
if (packageManager === PackageManager.bun) return !overridesSatisfyVitePlus(pkg.overrides, readBunCatalogDependencyResolver(pkg));
|
|
1703
|
+
if (packageManager === PackageManager.pnpm) {
|
|
1704
|
+
if (pkg.pnpm) return vitePlusDependencyNeedsConcreteVersion(pkg) || !overridesSatisfyVitePlus(pkg.pnpm.overrides) || !pnpmPeerDependencyRulesSatisfyVitePlus(pkg.pnpm.peerDependencyRules);
|
|
1705
|
+
const resolver = readPnpmWorkspaceCatalogDependencyResolver(projectPath);
|
|
1706
|
+
return defaultCatalogVitePlusDependencyPending(pkg, resolver) || !overridesSatisfyVitePlus(readPnpmWorkspaceOverrides(projectPath), resolver) || !pnpmPeerDependencyRulesSatisfyVitePlus(readPnpmWorkspacePeerDependencyRules(projectPath));
|
|
1707
|
+
}
|
|
1708
|
+
return false;
|
|
1709
|
+
}
|
|
1710
|
+
function ensureVitePlusDependencySpecs(pkg, version) {
|
|
1711
|
+
let changed = false;
|
|
1712
|
+
if (version !== "catalog:") {
|
|
1713
|
+
const dependencyGroups = [
|
|
1714
|
+
pkg.devDependencies,
|
|
1715
|
+
pkg.dependencies,
|
|
1716
|
+
pkg.optionalDependencies
|
|
1717
|
+
];
|
|
1718
|
+
for (const dependencies of dependencyGroups) if (dependencies?.["vite-plus"]?.startsWith("catalog:")) {
|
|
1719
|
+
dependencies[VITE_PLUS_NAME] = version;
|
|
1720
|
+
changed = true;
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
if (pkg.devDependencies?.["vite-plus"]) return changed;
|
|
1724
|
+
pkg.devDependencies = {
|
|
1725
|
+
...pkg.devDependencies,
|
|
1726
|
+
[VITE_PLUS_NAME]: version
|
|
1727
|
+
};
|
|
1728
|
+
return true;
|
|
1729
|
+
}
|
|
1730
|
+
function ensureOverrideEntries(overrides, catalogDependencyResolver) {
|
|
1731
|
+
const next = { ...overrides };
|
|
1732
|
+
let changed = false;
|
|
1733
|
+
for (const [dependencyName, overrideSpec] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) if (!overrideSpecSatisfiesVitePlus(dependencyName, next[dependencyName], catalogDependencyResolver)) {
|
|
1734
|
+
next[dependencyName] = overrideSpec;
|
|
1735
|
+
changed = true;
|
|
1736
|
+
}
|
|
1737
|
+
return {
|
|
1738
|
+
overrides: next,
|
|
1739
|
+
changed
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
function ensureNpmVitePlusManagedDependencies(pkg) {
|
|
1743
|
+
let changed = false;
|
|
1744
|
+
const dependencyGroups = [
|
|
1745
|
+
pkg.devDependencies,
|
|
1746
|
+
pkg.dependencies,
|
|
1747
|
+
pkg.optionalDependencies
|
|
1748
|
+
];
|
|
1749
|
+
for (const [dependencyName, version] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) for (const dependencies of dependencyGroups) if (dependencies?.[dependencyName] !== void 0 && !overrideSpecSatisfiesVitePlus(dependencyName, dependencies[dependencyName])) {
|
|
1750
|
+
dependencies[dependencyName] = version;
|
|
1751
|
+
changed = true;
|
|
1752
|
+
}
|
|
1753
|
+
return changed;
|
|
1754
|
+
}
|
|
1755
|
+
function ensurePnpmPeerDependencyRules(pkg) {
|
|
1756
|
+
const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
|
|
1757
|
+
pkg.pnpm ??= {};
|
|
1758
|
+
const peerDependencyRules = {
|
|
1759
|
+
...pkg.pnpm.peerDependencyRules,
|
|
1760
|
+
allowAny: [...new Set([...pkg.pnpm.peerDependencyRules?.allowAny ?? [], ...overrideKeys])],
|
|
1761
|
+
allowedVersions: {
|
|
1762
|
+
...pkg.pnpm.peerDependencyRules?.allowedVersions,
|
|
1763
|
+
...Object.fromEntries(overrideKeys.map((key) => [key, "*"]))
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
1766
|
+
const changed = JSON.stringify(pkg.pnpm.peerDependencyRules ?? {}) !== JSON.stringify(peerDependencyRules);
|
|
1767
|
+
pkg.pnpm.peerDependencyRules = peerDependencyRules;
|
|
1768
|
+
return changed;
|
|
1769
|
+
}
|
|
1770
|
+
function ensureVitePlusBootstrap(workspaceInfo, report) {
|
|
1771
|
+
const projectPath = workspaceInfo.rootDir;
|
|
1772
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
1773
|
+
const result = {
|
|
1774
|
+
changed: false,
|
|
1775
|
+
packageJson: false,
|
|
1776
|
+
packageManagerConfig: false,
|
|
1777
|
+
packageManagerField: false
|
|
1778
|
+
};
|
|
1779
|
+
if (!fs.existsSync(packageJsonPath)) return result;
|
|
1780
|
+
editJsonFile(packageJsonPath, (pkg) => {
|
|
1781
|
+
const usePnpmWorkspaceYaml = workspaceInfo.packageManager === PackageManager.pnpm && !pkg.pnpm;
|
|
1782
|
+
let packageJsonChanged = ensureVitePlusDependencySpecs(pkg, !VITE_PLUS_VERSION.startsWith("file:") && (usePnpmWorkspaceYaml || workspaceInfo.packageManager === PackageManager.bun) ? "catalog:" : VITE_PLUS_VERSION);
|
|
1783
|
+
if (workspaceInfo.packageManager === PackageManager.npm) packageJsonChanged = ensureNpmVitePlusManagedDependencies(pkg) || packageJsonChanged;
|
|
1784
|
+
if (workspaceInfo.packageManager === PackageManager.yarn) {
|
|
1785
|
+
const ensured = ensureOverrideEntries(pkg.resolutions);
|
|
1786
|
+
if (ensured.changed) {
|
|
1787
|
+
pkg.resolutions = ensured.overrides;
|
|
1788
|
+
packageJsonChanged = true;
|
|
1789
|
+
}
|
|
1790
|
+
} else if (workspaceInfo.packageManager === PackageManager.npm) {
|
|
1791
|
+
const ensured = ensureOverrideEntries(pkg.overrides);
|
|
1792
|
+
if (ensured.changed) {
|
|
1793
|
+
pkg.overrides = ensured.overrides;
|
|
1794
|
+
packageJsonChanged = true;
|
|
1795
|
+
}
|
|
1796
|
+
} else if (workspaceInfo.packageManager === PackageManager.bun) {
|
|
1797
|
+
const ensured = ensureOverrideEntries(pkg.overrides, readBunCatalogDependencyResolver(pkg));
|
|
1798
|
+
if (ensured.changed) {
|
|
1799
|
+
pkg.overrides = ensured.overrides;
|
|
1800
|
+
packageJsonChanged = true;
|
|
1801
|
+
}
|
|
1802
|
+
} else if (workspaceInfo.packageManager === PackageManager.pnpm && pkg.pnpm) {
|
|
1803
|
+
const ensured = ensureOverrideEntries(pkg.pnpm.overrides);
|
|
1804
|
+
if (ensured.changed) {
|
|
1805
|
+
pkg.pnpm.overrides = ensured.overrides;
|
|
1806
|
+
packageJsonChanged = true;
|
|
1807
|
+
}
|
|
1808
|
+
packageJsonChanged = ensurePnpmPeerDependencyRules(pkg) || packageJsonChanged;
|
|
1809
|
+
}
|
|
1810
|
+
result.packageJson = packageJsonChanged;
|
|
1811
|
+
return pkg;
|
|
1812
|
+
});
|
|
1813
|
+
if (workspaceInfo.packageManager === PackageManager.pnpm) {
|
|
1814
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
1815
|
+
if (!pkg.pnpm) {
|
|
1816
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
1817
|
+
const before = fs.existsSync(pnpmWorkspaceYamlPath) ? fs.readFileSync(pnpmWorkspaceYamlPath, "utf-8") : void 0;
|
|
1818
|
+
const catalogDependencyResolver = readPnpmWorkspaceCatalogDependencyResolver(projectPath);
|
|
1819
|
+
if (defaultCatalogVitePlusDependencyPending(pkg, catalogDependencyResolver) || !overridesSatisfyVitePlus(readPnpmWorkspaceOverrides(projectPath), catalogDependencyResolver) || !pnpmPeerDependencyRulesSatisfyVitePlus(readPnpmWorkspacePeerDependencyRules(projectPath))) rewritePnpmWorkspaceYaml(projectPath, void 0, false);
|
|
1820
|
+
if (fs.existsSync(pnpmWorkspaceYamlPath)) ensurePnpmWorkspacePackages(projectPath, workspaceInfo.workspacePatterns);
|
|
1821
|
+
result.packageManagerConfig = before !== (fs.existsSync(pnpmWorkspaceYamlPath) ? fs.readFileSync(pnpmWorkspaceYamlPath, "utf-8") : void 0);
|
|
1822
|
+
}
|
|
1823
|
+
} else if (workspaceInfo.packageManager === PackageManager.yarn) {
|
|
1824
|
+
const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
|
|
1825
|
+
const before = fs.existsSync(yarnrcYmlPath) ? fs.readFileSync(yarnrcYmlPath, "utf-8") : void 0;
|
|
1826
|
+
rewriteYarnrcYml(projectPath);
|
|
1827
|
+
result.packageManagerConfig = before !== fs.readFileSync(yarnrcYmlPath, "utf-8");
|
|
1828
|
+
} else if (workspaceInfo.packageManager === PackageManager.bun) {
|
|
1829
|
+
const before = fs.readFileSync(packageJsonPath, "utf-8");
|
|
1830
|
+
rewriteBunCatalog(projectPath);
|
|
1831
|
+
const after = fs.readFileSync(packageJsonPath, "utf-8");
|
|
1832
|
+
result.packageJson = result.packageJson || before !== after;
|
|
1833
|
+
}
|
|
1834
|
+
const beforePackageManager = fs.readFileSync(packageJsonPath, "utf-8");
|
|
1835
|
+
setPackageManager(projectPath, workspaceInfo.downloadPackageManager);
|
|
1836
|
+
result.packageManagerField = beforePackageManager !== fs.readFileSync(packageJsonPath, "utf-8");
|
|
1837
|
+
result.changed = result.packageJson || result.packageManagerConfig || result.packageManagerField;
|
|
1838
|
+
if (result.changed && report) report.packageManagerBootstrapConfigured = true;
|
|
1839
|
+
return result;
|
|
1840
|
+
}
|
|
1841
|
+
const VITEST_BROWSER_SPECIFIER_HINTS = [
|
|
1842
|
+
"@vitest/browser",
|
|
1843
|
+
"vite-plus/test/browser",
|
|
1844
|
+
"vite-plus/test/plugins/browser",
|
|
1845
|
+
"vite-plus/test/internal/browser",
|
|
1846
|
+
"vite-plus/test/client",
|
|
1847
|
+
"vite-plus/test/context",
|
|
1848
|
+
"vite-plus/test/locators",
|
|
1849
|
+
"vite-plus/test/matchers",
|
|
1850
|
+
"vite-plus/test/utils"
|
|
1851
|
+
];
|
|
1852
|
+
const WEBDRIVERIO_PROVIDER_SPECIFIER_HINTS = [
|
|
1853
|
+
"@vitest/browser-webdriverio",
|
|
1854
|
+
"vite-plus/test/browser-webdriverio",
|
|
1855
|
+
"vite-plus/test/browser/providers/webdriverio",
|
|
1856
|
+
"vite-plus/test/plugins/browser-webdriverio"
|
|
1857
|
+
];
|
|
1858
|
+
const PLAYWRIGHT_PROVIDER_SPECIFIER_HINTS = [
|
|
1859
|
+
"@vitest/browser-playwright",
|
|
1860
|
+
"vite-plus/test/browser-playwright",
|
|
1861
|
+
"vite-plus/test/browser/providers/playwright",
|
|
1862
|
+
"vite-plus/test/plugins/browser-playwright"
|
|
1863
|
+
];
|
|
1864
|
+
const BROWSER_PROVIDER_SPECIFIER_HINTS = {
|
|
1865
|
+
[WEBDRIVERIO_PROVIDER]: WEBDRIVERIO_PROVIDER_SPECIFIER_HINTS,
|
|
1866
|
+
[PLAYWRIGHT_PROVIDER]: PLAYWRIGHT_PROVIDER_SPECIFIER_HINTS
|
|
1867
|
+
};
|
|
1868
|
+
const VITEST_SCAN_EXTENSIONS = new Set([
|
|
1869
|
+
".ts",
|
|
1870
|
+
".mts",
|
|
1871
|
+
".cts",
|
|
1872
|
+
".tsx",
|
|
1873
|
+
".js",
|
|
1874
|
+
".mjs",
|
|
1875
|
+
".cjs",
|
|
1876
|
+
".jsx"
|
|
1877
|
+
]);
|
|
1878
|
+
const VITEST_SCAN_SKIP_DIRS = new Set([
|
|
1879
|
+
"node_modules",
|
|
1880
|
+
"dist",
|
|
1881
|
+
"build",
|
|
1882
|
+
"out",
|
|
1883
|
+
"coverage",
|
|
1884
|
+
".git",
|
|
1885
|
+
".next",
|
|
1886
|
+
".nuxt",
|
|
1887
|
+
".svelte-kit",
|
|
1888
|
+
".vite",
|
|
1889
|
+
".cache"
|
|
1890
|
+
]);
|
|
1891
|
+
/**
|
|
1892
|
+
* Detect whether a package uses vitest's browser mode.
|
|
1893
|
+
*
|
|
1894
|
+
* Upstream `@vitest/browser` injects `optimizeDeps.include` entries of the form
|
|
1895
|
+
* `vitest > expect-type` (and `vitest > @vitest/snapshot > magic-string`,
|
|
1896
|
+
* `vitest > @vitest/expect > chai`). Vite resolves the leading `vitest` segment
|
|
1897
|
+
* from the Vite config root, so `vitest` MUST be resolvable as a package from
|
|
1898
|
+
* the consuming package's directory. In a pnpm strict (non-hoisted) layout,
|
|
1899
|
+
* `vitest` pulled in only transitively via `vite-plus` is NOT reachable from the
|
|
1900
|
+
* package root — the optimizer then fails with `Failed to resolve dependency`
|
|
1901
|
+
* and the browser test page hangs forever.
|
|
1902
|
+
*
|
|
1903
|
+
* When this returns true the migration adds `vitest` as a direct
|
|
1904
|
+
* devDependency so it is hoisted next to the package and the optimizer chain
|
|
1905
|
+
* resolves. The signal is any of the package's TS/JS files (config, workspace
|
|
1906
|
+
* config under any name, or test file) referencing `@vitest/browser*` or
|
|
1907
|
+
* `vite-plus/test/browser*`. The scan recurses through the package directory
|
|
1908
|
+
* (skipping `node_modules`, build output, VCS metadata) so browser config in a
|
|
1909
|
+
* non-standard filename or browser imports in test files are all caught.
|
|
1910
|
+
*
|
|
1911
|
+
* Recursion stops at nested `package.json` boundaries: a workspace sub-package
|
|
1912
|
+
* is a separate package that the migration scans on its own pass, so the root
|
|
1913
|
+
* package must not inherit a browser-mode signal from a sub-package.
|
|
1914
|
+
*/
|
|
1915
|
+
function sourceTreeReferencesAny(projectPath, hints) {
|
|
1916
|
+
const matchesHint = (content) => hints.some((hint) => content.includes(hint));
|
|
1917
|
+
const scanDir = (dir, isRoot) => {
|
|
1918
|
+
let entries;
|
|
1919
|
+
try {
|
|
1920
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
1921
|
+
} catch {
|
|
1922
|
+
return false;
|
|
1923
|
+
}
|
|
1924
|
+
if (!isRoot && entries.some((e) => e.isFile() && e.name === "package.json")) return false;
|
|
1925
|
+
for (const entry of entries) {
|
|
1926
|
+
const entryPath = path.join(dir, entry.name);
|
|
1927
|
+
if (entry.isDirectory()) {
|
|
1928
|
+
if (VITEST_SCAN_SKIP_DIRS.has(entry.name)) continue;
|
|
1929
|
+
if (scanDir(entryPath, false)) return true;
|
|
1930
|
+
} else if (entry.isFile() && VITEST_SCAN_EXTENSIONS.has(path.extname(entry.name))) try {
|
|
1931
|
+
if (matchesHint(fs.readFileSync(entryPath, "utf8"))) return true;
|
|
1932
|
+
} catch {}
|
|
1933
|
+
}
|
|
1934
|
+
return false;
|
|
1935
|
+
};
|
|
1936
|
+
return scanDir(projectPath, true);
|
|
1937
|
+
}
|
|
1938
|
+
function usesVitestBrowserMode(projectPath) {
|
|
1939
|
+
return sourceTreeReferencesAny(projectPath, VITEST_BROWSER_SPECIFIER_HINTS);
|
|
1940
|
+
}
|
|
1941
|
+
function usesWebdriverioProvider(projectPath) {
|
|
1942
|
+
return sourceTreeReferencesAny(projectPath, WEBDRIVERIO_PROVIDER_SPECIFIER_HINTS);
|
|
1943
|
+
}
|
|
1944
|
+
function collectProviderSourceModes(projectPath) {
|
|
1945
|
+
const modes = {};
|
|
1946
|
+
for (const provider of OPT_IN_BROWSER_PROVIDERS) modes[provider] = sourceTreeReferencesAny(projectPath, BROWSER_PROVIDER_SPECIFIER_HINTS[provider]);
|
|
1947
|
+
return modes;
|
|
1948
|
+
}
|
|
1949
|
+
function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration, catalogDependencyResolver, vitestBrowserMode, providerSourceModes) {
|
|
1157
1950
|
if (pkg.scripts) {
|
|
1158
1951
|
const updated = rewriteScripts(JSON.stringify(pkg.scripts), getScriptRulesYaml(skipStagedMigration));
|
|
1159
1952
|
if (updated) pkg.scripts = JSON.parse(updated);
|
|
@@ -1184,6 +1977,7 @@ function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration
|
|
|
1184
1977
|
dependencies: pkg.optionalDependencies
|
|
1185
1978
|
}
|
|
1186
1979
|
];
|
|
1980
|
+
for (const { dependencies } of dependencyGroups) if (pruneLegacyWrapperAliases(dependencies)) needVitePlus = true;
|
|
1187
1981
|
for (const [key, version] of Object.entries(VITE_PLUS_OVERRIDE_PACKAGES)) for (const { dependencyField, dependencies } of dependencyGroups) if (dependencies?.[key]) {
|
|
1188
1982
|
dependencies[key] = getCatalogDependencySpec(dependencies[key], version, supportCatalog, {
|
|
1189
1983
|
dependencyField,
|
|
@@ -1193,6 +1987,13 @@ function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration
|
|
|
1193
1987
|
});
|
|
1194
1988
|
needVitePlus = true;
|
|
1195
1989
|
}
|
|
1990
|
+
if (isForceOverrideMode()) {
|
|
1991
|
+
for (const { dependencies } of dependencyGroups) if (dependencies?.["vite-plus"]) {
|
|
1992
|
+
dependencies[VITE_PLUS_NAME] = VITE_PLUS_VERSION;
|
|
1993
|
+
needVitePlus = true;
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
const hasBrowserDepSignal = VITEST_BROWSER_DEP_NAMES.some((name) => dependencyGroups.some(({ dependencies }) => dependencies?.[name] !== void 0));
|
|
1196
1997
|
for (const name of REMOVE_PACKAGES) {
|
|
1197
1998
|
let wasRemoved = false;
|
|
1198
1999
|
for (const { dependencies } of dependencyGroups) if (dependencies?.[name]) {
|
|
@@ -1206,23 +2007,63 @@ function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration
|
|
|
1206
2007
|
pkg.devDependencies[peerDep] = "*";
|
|
1207
2008
|
}
|
|
1208
2009
|
}
|
|
2010
|
+
let usesAnyOptInProvider = false;
|
|
2011
|
+
for (const provider of OPT_IN_BROWSER_PROVIDERS) {
|
|
2012
|
+
if (!(providerSourceModes?.[provider] || dependencyGroups.some(({ dependencies }) => dependencies?.[provider] !== void 0))) continue;
|
|
2013
|
+
usesAnyOptInProvider = true;
|
|
2014
|
+
const installGroup = [
|
|
2015
|
+
pkg.dependencies,
|
|
2016
|
+
pkg.devDependencies,
|
|
2017
|
+
pkg.optionalDependencies
|
|
2018
|
+
].find((deps) => deps?.[provider] !== void 0);
|
|
2019
|
+
if (installGroup) installGroup[provider] = VITEST_VERSION;
|
|
2020
|
+
else {
|
|
2021
|
+
pkg.devDependencies ??= {};
|
|
2022
|
+
pkg.devDependencies[provider] = VITEST_VERSION;
|
|
2023
|
+
}
|
|
2024
|
+
const peer = BROWSER_PROVIDER_PEER_DEPS[provider];
|
|
2025
|
+
const peerPresent = pkg.dependencies?.[peer] ?? pkg.devDependencies?.[peer] ?? pkg.peerDependencies?.[peer] ?? pkg.optionalDependencies?.[peer];
|
|
2026
|
+
if (peer && !peerPresent) {
|
|
2027
|
+
pkg.devDependencies ??= {};
|
|
2028
|
+
pkg.devDependencies[peer] = "*";
|
|
2029
|
+
}
|
|
2030
|
+
needVitePlus = true;
|
|
2031
|
+
}
|
|
2032
|
+
if (usesAnyOptInProvider && packageManager === PackageManager.npm) {
|
|
2033
|
+
const viteOverride = VITE_PLUS_OVERRIDE_PACKAGES.vite;
|
|
2034
|
+
const viteAlreadyDirect = pkg.dependencies?.vite ?? pkg.devDependencies?.vite ?? pkg.optionalDependencies?.vite;
|
|
2035
|
+
if (viteOverride && !viteAlreadyDirect) {
|
|
2036
|
+
pkg.devDependencies ??= {};
|
|
2037
|
+
pkg.devDependencies.vite = viteOverride;
|
|
2038
|
+
needVitePlus = true;
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
const effectiveBrowserMode = vitestBrowserMode || hasBrowserDepSignal;
|
|
2042
|
+
const installableNames = [
|
|
2043
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
2044
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
2045
|
+
...Object.keys(pkg.optionalDependencies ?? {})
|
|
2046
|
+
];
|
|
2047
|
+
const adjacentSignals = [...installableNames, ...Object.keys(pkg.peerDependencies ?? {})];
|
|
2048
|
+
const isVitestAdjacent = !installableNames.includes("vitest") && adjacentSignals.some((name) => name !== "vitest" && name.includes("vitest"));
|
|
1209
2049
|
const canonicalVitePlusSpec = supportCatalog && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
|
|
1210
2050
|
const existingVitePlus = pkg.devDependencies?.[VITE_PLUS_NAME];
|
|
1211
2051
|
const shouldNormalizeExistingVitePlus = !!existingVitePlus && supportCatalog && existingVitePlus !== canonicalVitePlusSpec && !isProtocolPinnedSpec(existingVitePlus);
|
|
2052
|
+
if (!existingVitePlus && (isVitestAdjacent || effectiveBrowserMode)) needVitePlus = true;
|
|
2053
|
+
const needDirectVitest = needVitePlus || effectiveBrowserMode || isVitestAdjacent;
|
|
1212
2054
|
if (needVitePlus || shouldNormalizeExistingVitePlus) pkg.devDependencies = {
|
|
1213
2055
|
...pkg.devDependencies,
|
|
1214
2056
|
[VITE_PLUS_NAME]: canonicalVitePlusSpec
|
|
1215
2057
|
};
|
|
1216
|
-
if (
|
|
2058
|
+
if (needDirectVitest) {
|
|
1217
2059
|
const installableDeps = {
|
|
1218
2060
|
...pkg.dependencies,
|
|
1219
2061
|
...pkg.devDependencies,
|
|
1220
2062
|
...pkg.optionalDependencies
|
|
1221
2063
|
};
|
|
1222
|
-
if (!installableDeps.vitest && Object.keys(installableDeps).some((name) => name.includes("vitest"))) {
|
|
1223
|
-
const ver = VITE_PLUS_OVERRIDE_PACKAGES.vitest;
|
|
2064
|
+
if (!installableDeps.vitest && (effectiveBrowserMode || Object.keys(installableDeps).some((name) => name.includes("vitest")))) {
|
|
1224
2065
|
pkg.devDependencies ??= {};
|
|
1225
|
-
pkg.devDependencies.vitest = getCatalogDependencySpec(void 0,
|
|
2066
|
+
pkg.devDependencies.vitest = getCatalogDependencySpec(void 0, VITEST_VERSION, supportCatalog);
|
|
1226
2067
|
}
|
|
1227
2068
|
}
|
|
1228
2069
|
return extractedStagedConfig;
|
|
@@ -1590,6 +2431,20 @@ function hasStagedConfigInViteConfig(projectPath) {
|
|
|
1590
2431
|
return /\bstaged\s*:/.test(content);
|
|
1591
2432
|
}
|
|
1592
2433
|
/**
|
|
2434
|
+
* Wrap safe inline Vite plugin arrays with lazyPlugins so check/lint/fmt do not
|
|
2435
|
+
* eagerly execute plugin factories while loading vite.config.ts.
|
|
2436
|
+
*/
|
|
2437
|
+
function wrapLazyPluginsInViteConfig(projectPath, silent = false, report) {
|
|
2438
|
+
const configs = detectConfigs(projectPath);
|
|
2439
|
+
if (!configs.viteConfig) return;
|
|
2440
|
+
const viteConfigPath = path.join(projectPath, configs.viteConfig);
|
|
2441
|
+
const result = wrapLazyPlugins(viteConfigPath);
|
|
2442
|
+
if (!result.updated) return;
|
|
2443
|
+
fs.writeFileSync(viteConfigPath, result.content);
|
|
2444
|
+
if (report) report.wrappedPluginConfigCount++;
|
|
2445
|
+
if (!silent) log.success(`✔ Wrapped inline Vite plugins with lazyPlugins in ${displayRelative(viteConfigPath)}`);
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
1593
2448
|
* Rewrite imports in all TypeScript/JavaScript files under a directory
|
|
1594
2449
|
* This rewrites vite/vitest imports to @voidzero-dev/vite-plus
|
|
1595
2450
|
* @param projectPath - The root directory to search for files
|
|
@@ -1614,19 +2469,28 @@ function rewriteAllImports(projectPath, silent = false, report) {
|
|
|
1614
2469
|
log.warn(`⚠ ${errors === 1 ? "one file had an error" : `${errors} files had errors`}:`);
|
|
1615
2470
|
for (const error of result.errors) log.error(` ${displayRelative(error.path)}: ${error.message}`);
|
|
1616
2471
|
}
|
|
2472
|
+
return modified > 0;
|
|
1617
2473
|
}
|
|
1618
2474
|
/**
|
|
1619
2475
|
* Check if the project has an unsupported husky version (<9.0.0).
|
|
1620
2476
|
* Uses `semver.coerce` to handle ranges like `^8.0.0` → `8.0.0`.
|
|
1621
|
-
* When the specifier is
|
|
1622
|
-
* the
|
|
2477
|
+
* When the specifier is a catalog reference (e.g. `"catalog:"`), resolves
|
|
2478
|
+
* it from the active package manager's catalog first — a `catalog:` spec is
|
|
2479
|
+
* only meaningful to the manager that owns the workspace, so we never read a
|
|
2480
|
+
* leftover/foreign catalog file. When it is still not coercible (e.g.
|
|
2481
|
+
* `"latest"`), falls back to the installed version in node_modules via
|
|
2482
|
+
* `detectPackageMetadata`.
|
|
1623
2483
|
* Returns a reason string if hooks migration should be skipped, or null
|
|
1624
2484
|
* if husky is absent or compatible.
|
|
1625
2485
|
*/
|
|
1626
|
-
function checkUnsupportedHuskyVersion(projectPath, deps, prodDeps) {
|
|
2486
|
+
function checkUnsupportedHuskyVersion(projectPath, deps, prodDeps, packageManager) {
|
|
1627
2487
|
const huskyVersion = deps?.husky ?? prodDeps?.husky;
|
|
1628
2488
|
if (!huskyVersion) return null;
|
|
1629
2489
|
let coerced = import_semver.default.coerce(huskyVersion);
|
|
2490
|
+
if (coerced == null && packageManager != null && huskyVersion.startsWith("catalog:")) {
|
|
2491
|
+
const resolved = createCatalogDependencyResolver(projectPath, packageManager)?.(huskyVersion, "husky");
|
|
2492
|
+
if (resolved) coerced = import_semver.default.coerce(resolved);
|
|
2493
|
+
}
|
|
1630
2494
|
if (coerced == null) {
|
|
1631
2495
|
const installed = detectPackageMetadata(projectPath, "husky");
|
|
1632
2496
|
if (installed) coerced = import_semver.default.coerce(installed.version);
|
|
@@ -1650,6 +2514,12 @@ function removeReplacedHookPackages(packageJsonPath) {
|
|
|
1650
2514
|
return pkg;
|
|
1651
2515
|
});
|
|
1652
2516
|
}
|
|
2517
|
+
function detectLegacyGitHooksMigrationCandidate(projectPath) {
|
|
2518
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
2519
|
+
if (!fs.existsSync(packageJsonPath)) return false;
|
|
2520
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
2521
|
+
return getOldHooksDir(projectPath) !== void 0 || pkg["lint-staged"] !== void 0;
|
|
2522
|
+
}
|
|
1653
2523
|
/**
|
|
1654
2524
|
* Walk up from `startPath` looking for `.git` (directory or file — submodules
|
|
1655
2525
|
* use a `.git` file). Returns the directory that contains `.git`, or `null`.
|
|
@@ -1674,8 +2544,8 @@ function collapseHuskyInstall(script) {
|
|
|
1674
2544
|
* High-level helper: detect old hooks dir, set up git hooks, and rewrite
|
|
1675
2545
|
* the prepare script. Returns true if hooks were successfully installed.
|
|
1676
2546
|
*/
|
|
1677
|
-
function installGitHooks(projectPath, silent = false, report) {
|
|
1678
|
-
if (setupGitHooks(projectPath, getOldHooksDir(projectPath), silent, report)) {
|
|
2547
|
+
function installGitHooks(projectPath, silent = false, report, packageManager) {
|
|
2548
|
+
if (setupGitHooks(projectPath, getOldHooksDir(projectPath), silent, report, packageManager)) {
|
|
1679
2549
|
rewritePrepareScript(projectPath);
|
|
1680
2550
|
return true;
|
|
1681
2551
|
}
|
|
@@ -1701,8 +2571,11 @@ function getOldHooksDir(rootDir) {
|
|
|
1701
2571
|
*
|
|
1702
2572
|
* These checks are deterministic and read-only — they do not modify
|
|
1703
2573
|
* the project in any way, making them safe to call before migration.
|
|
2574
|
+
*
|
|
2575
|
+
* `packageManager` is the project's detected manager; it scopes `catalog:`
|
|
2576
|
+
* resolution to that manager's catalog so a foreign catalog file is ignored.
|
|
1704
2577
|
*/
|
|
1705
|
-
function preflightGitHooksSetup(projectPath) {
|
|
2578
|
+
function preflightGitHooksSetup(projectPath, packageManager) {
|
|
1706
2579
|
const gitRoot = findGitRoot(projectPath);
|
|
1707
2580
|
if (gitRoot && path.resolve(projectPath) !== path.resolve(gitRoot)) return "Subdirectory project detected — skipping git hooks setup. Configure hooks at the repository root.";
|
|
1708
2581
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
@@ -1711,7 +2584,7 @@ function preflightGitHooksSetup(projectPath) {
|
|
|
1711
2584
|
const deps = pkgContent.devDependencies;
|
|
1712
2585
|
const prodDeps = pkgContent.dependencies;
|
|
1713
2586
|
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.`;
|
|
1714
|
-
const huskyReason = checkUnsupportedHuskyVersion(projectPath, deps, prodDeps);
|
|
2587
|
+
const huskyReason = checkUnsupportedHuskyVersion(projectPath, deps, prodDeps, packageManager);
|
|
1715
2588
|
if (huskyReason) return huskyReason;
|
|
1716
2589
|
if (hasUnsupportedLintStagedConfig(projectPath)) return "Unsupported lint-staged config format — skipping git hooks setup. Please configure git hooks manually.";
|
|
1717
2590
|
return null;
|
|
@@ -1721,8 +2594,8 @@ function preflightGitHooksSetup(projectPath) {
|
|
|
1721
2594
|
* Skips if another hook tool is detected (warns user).
|
|
1722
2595
|
* Returns true if hooks were successfully set up, false if skipped.
|
|
1723
2596
|
*/
|
|
1724
|
-
function setupGitHooks(projectPath, oldHooksDir, silent = false, report) {
|
|
1725
|
-
const reason = preflightGitHooksSetup(projectPath);
|
|
2597
|
+
function setupGitHooks(projectPath, oldHooksDir, silent = false, report, packageManager) {
|
|
2598
|
+
const reason = preflightGitHooksSetup(projectPath, packageManager);
|
|
1726
2599
|
if (reason) {
|
|
1727
2600
|
warnMigration(reason, report);
|
|
1728
2601
|
return false;
|
|
@@ -1792,10 +2665,10 @@ function setupGitHooks(projectPath, oldHooksDir, silent = false, report) {
|
|
|
1792
2665
|
const vpBin = process.env.VP_CLI_BIN ?? "vp";
|
|
1793
2666
|
const configArgs = isCustomDir ? [
|
|
1794
2667
|
"config",
|
|
1795
|
-
"--
|
|
2668
|
+
"--no-agent",
|
|
1796
2669
|
"--hooks-dir",
|
|
1797
2670
|
hooksDir
|
|
1798
|
-
] : ["config", "--
|
|
2671
|
+
] : ["config", "--no-agent"];
|
|
1799
2672
|
const configResult = import_cross_spawn.default.sync(vpBin, configArgs, {
|
|
1800
2673
|
cwd: projectPath,
|
|
1801
2674
|
stdio: "pipe"
|
|
@@ -1913,7 +2786,14 @@ function rewritePrepareScript(rootDir) {
|
|
|
1913
2786
|
}
|
|
1914
2787
|
function setPackageManager(projectDir, downloadPackageManager) {
|
|
1915
2788
|
editJsonFile(path.join(projectDir, "package.json"), (pkg) => {
|
|
1916
|
-
if (!pkg.packageManager
|
|
2789
|
+
if (!pkg.packageManager && !pkg.devEngines?.packageManager) pkg.devEngines = {
|
|
2790
|
+
...typeof pkg.devEngines === "object" && pkg.devEngines !== null && !Array.isArray(pkg.devEngines) ? pkg.devEngines : void 0,
|
|
2791
|
+
packageManager: {
|
|
2792
|
+
name: downloadPackageManager.name,
|
|
2793
|
+
version: downloadPackageManager.version,
|
|
2794
|
+
onFail: "download"
|
|
2795
|
+
}
|
|
2796
|
+
};
|
|
1917
2797
|
return pkg;
|
|
1918
2798
|
});
|
|
1919
2799
|
}
|
|
@@ -2023,7 +2903,7 @@ async function confirmEslintMigration(interactive) {
|
|
|
2023
2903
|
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."),
|
|
2024
2904
|
initialValue: true
|
|
2025
2905
|
});
|
|
2026
|
-
if (
|
|
2906
|
+
if (R(confirmed)) cancelAndExit();
|
|
2027
2907
|
return confirmed;
|
|
2028
2908
|
}
|
|
2029
2909
|
return true;
|
|
@@ -2057,7 +2937,7 @@ async function confirmPrettierMigration(interactive) {
|
|
|
2057
2937
|
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."),
|
|
2058
2938
|
initialValue: true
|
|
2059
2939
|
});
|
|
2060
|
-
if (
|
|
2940
|
+
if (R(confirmed)) cancelAndExit();
|
|
2061
2941
|
return confirmed;
|
|
2062
2942
|
}
|
|
2063
2943
|
log.info("Prettier configuration detected. Auto-migrating to Oxfmt...");
|
|
@@ -2189,7 +3069,7 @@ async function selectAgentTargets({ interactive, agent, onCancel }) {
|
|
|
2189
3069
|
initialValues: [AGENT_DEFAULT_ID],
|
|
2190
3070
|
required: false
|
|
2191
3071
|
});
|
|
2192
|
-
if (
|
|
3072
|
+
if (R(selectedAgentIds)) {
|
|
2193
3073
|
onCancel();
|
|
2194
3074
|
return {
|
|
2195
3075
|
targetPaths: void 0,
|
|
@@ -2376,7 +3256,7 @@ async function writeAgentInstructions({ projectRoot, targetPath, targetPaths, in
|
|
|
2376
3256
|
}],
|
|
2377
3257
|
initialValue: "skip"
|
|
2378
3258
|
});
|
|
2379
|
-
conflictAction =
|
|
3259
|
+
conflictAction = R(action) || action === "skip" ? "skip" : "append";
|
|
2380
3260
|
} else conflictAction = "skip";
|
|
2381
3261
|
if (conflictAction === "append") await appendAgentContent(destinationPath, targetPathToWrite, existingContent, incomingContent, silent);
|
|
2382
3262
|
else {
|
|
@@ -2458,4 +3338,4 @@ function getMarkedRange(content, startMarker, endMarker) {
|
|
|
2458
3338
|
};
|
|
2459
3339
|
}
|
|
2460
3340
|
//#endregion
|
|
2461
|
-
export {
|
|
3341
|
+
export { mergeViteConfigFiles as A, setPackageManager as B, ensureVitePlusBootstrap as C, injectCreateDefaultTemplate as D, hasStagedConfigInViteConfig as E, promptEslintMigration as F, editYamlFile as G, warnLegacyEslintConfig as H, promptPrettierMigration as I, templatesDir as J, readYamlFile as K, rewriteMonorepo as L, migrateNodeVersionManagerFile as M, migratePrettierToOxfmt as N, injectLintTypeCheckDefaults as O, preflightGitHooksSetup as P, rewriteMonorepoProject as R, ensurePreCommitHook as S, hasFrameworkShim as T, warnPackageLevelEslint as U, warnIncompatibleEslintIntegration as V, warnPackageLevelPrettier as W, detectLegacyGitHooksMigrationCandidate as _, selectAgentTargets as a, detectPrettierProject as b, writeCopilotSetupWorkflow as c, checkVitestVersion as d, confirmEslintMigration as f, detectIncompatibleEslintIntegration as g, detectFramework as h, selectAgentTargetPaths as i, migrateEslintToOxlint as j, installGitHooks as k, addFrameworkShim as l, detectEslintProject as m, detectAgentConflicts as n, updateExistingAgentInstructions as o, confirmPrettierMigration as p, displayRelative as q, detectExistingAgentTargetPaths as r, writeAgentInstructions as s, COPILOT_AGENT_ID as t, checkViteVersion as u, detectNodeVersionManagerFile as v, finalizeCoreMigrationForExistingVitePlus as w, detectVitePlusBootstrapPending as x, detectPendingCoreMigration as y, rewriteStandaloneProject as z };
|