vite-plus 0.1.15-alpha.5 → 0.1.15-alpha.7

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.
@@ -1,36 +1,34 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defineConfig = defineConfig;
4
- const config_1 = require("@voidzero-dev/vite-plus-test/config");
5
- function defineConfig(config) {
2
+ import { defineConfig as viteDefineConfig, } from '@voidzero-dev/vite-plus-test/config';
3
+ export function defineConfig(config) {
6
4
  if (typeof config === 'object') {
7
5
  if (config instanceof Promise) {
8
6
  return config.then((config) => {
9
7
  if (config.lazy) {
10
- return config.lazy().then(({ plugins }) => (0, config_1.defineConfig)({
8
+ return config.lazy().then(({ plugins }) => viteDefineConfig({
11
9
  ...config,
12
10
  plugins: [...(config.plugins || []), ...(plugins || [])],
13
11
  }));
14
12
  }
15
- return (0, config_1.defineConfig)(config);
13
+ return viteDefineConfig(config);
16
14
  });
17
15
  }
18
16
  else if (config.lazy) {
19
- return config.lazy().then(({ plugins }) => (0, config_1.defineConfig)({
17
+ return config.lazy().then(({ plugins }) => viteDefineConfig({
20
18
  ...config,
21
19
  plugins: [...(config.plugins || []), ...(plugins || [])],
22
20
  }));
23
21
  }
24
22
  }
25
23
  else if (typeof config === 'function') {
26
- return (0, config_1.defineConfig)((env) => {
24
+ return viteDefineConfig((env) => {
27
25
  const c = config(env);
28
26
  if (c instanceof Promise) {
29
27
  return c.then((v) => {
30
28
  if (v.lazy) {
31
29
  return v
32
30
  .lazy()
33
- .then(({ plugins }) => (0, config_1.defineConfig)({ ...v, plugins: [...(v.plugins || []), ...(plugins || [])] }));
31
+ .then(({ plugins }) => viteDefineConfig({ ...v, plugins: [...(v.plugins || []), ...(plugins || [])] }));
34
32
  }
35
33
  return v;
36
34
  });
@@ -43,5 +41,5 @@ function defineConfig(config) {
43
41
  return c;
44
42
  });
45
43
  }
46
- return (0, config_1.defineConfig)(config);
44
+ return viteDefineConfig(config);
47
45
  }
@@ -1,5 +1,5 @@
1
1
  import { type ConfigEnv } from '@voidzero-dev/vite-plus-test/config';
2
- import type { UserConfig } from './index';
2
+ import type { UserConfig } from './index.js';
3
3
  type ViteUserConfigFnObject = (env: ConfigEnv) => UserConfig;
4
4
  type ViteUserConfigFnPromise = (env: ConfigEnv) => Promise<UserConfig>;
5
5
  type ViteUserConfigFn = (env: ConfigEnv) => UserConfig | Promise<UserConfig>;
package/dist/fmt.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { format } from 'oxfmt';
2
+ export type * from 'oxfmt';
package/dist/fmt.js ADDED
@@ -0,0 +1 @@
1
+ export { format } from 'oxfmt';
@@ -1,6 +1,6 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./chunk-BoAXSpZd.js";
2
2
  import { _ as YAMLMap, g as YAMLSeq, i as parseDocument, n as parse, y as Scalar } from "./browser-09BZLUYM.js";
3
- import { _ as isForceOverrideMode, c as readJsonFile, d as modify, f as parse$1, g as VITE_PLUS_VERSION, h as VITE_PLUS_OVERRIDE_PACKAGES, m as VITE_PLUS_NAME, n as detectPackageMetadata, o as editJsonFile, p as BASEURL_TSCONFIG_WARNING, s as isJsonFile, u as applyEdits } from "./package-CnlCtq4D.js";
3
+ import { _ as isForceOverrideMode, c as readJsonFile, d as modify, f as parse$1, g as VITE_PLUS_VERSION, h as VITE_PLUS_OVERRIDE_PACKAGES, m as VITE_PLUS_NAME, n as detectPackageMetadata, o as editJsonFile, p as BASEURL_TSCONFIG_WARNING, s as isJsonFile, u as applyEdits } from "./package-2ArHHFnA.js";
4
4
  import { n as accent } from "./help-HviKaKAU.js";
5
5
  import { n as addMigrationWarning, t as addManualStep } from "./report-DGaKL5VQ.js";
6
6
  import path from "node:path";
@@ -2921,7 +2921,7 @@ async function downloadPackageManager$1(packageManager, version, interactive, si
2921
2921
  return downloadResult;
2922
2922
  }
2923
2923
  async function runViteInstall(cwd, interactive, extraArgs, options) {
2924
- if (process.env.VITE_PLUS_SKIP_INSTALL) return {
2924
+ if (process.env.VP_SKIP_INSTALL) return {
2925
2925
  durationMs: 0,
2926
2926
  status: "skipped"
2927
2927
  };
@@ -2929,7 +2929,7 @@ async function runViteInstall(cwd, interactive, extraArgs, options) {
2929
2929
  const startTime = Date.now();
2930
2930
  spinner.start(`Installing dependencies...`);
2931
2931
  const { exitCode, stderr, stdout } = await runCommandSilently({
2932
- command: process.env.VITE_PLUS_CLI_BIN ?? "vp",
2932
+ command: process.env.VP_CLI_BIN ?? "vp",
2933
2933
  args: ["install", ...extraArgs ?? []],
2934
2934
  cwd,
2935
2935
  envs: process.env
@@ -2958,7 +2958,7 @@ async function runViteFmt(cwd, interactive, paths, options) {
2958
2958
  const startTime = Date.now();
2959
2959
  spinner.start(`Formatting code...`);
2960
2960
  const { exitCode, stderr, stdout } = await runCommandSilently({
2961
- command: process.env.VITE_PLUS_CLI_BIN ?? "vp",
2961
+ command: process.env.VP_CLI_BIN ?? "vp",
2962
2962
  args: [
2963
2963
  "fmt",
2964
2964
  "--write",
@@ -3156,7 +3156,7 @@ function detectConfigs(projectPath) {
3156
3156
  configs.tsdownConfig = config;
3157
3157
  break;
3158
3158
  }
3159
- for (const config of [".oxlintrc.json"]) if (fs.existsSync(path.join(projectPath, config))) {
3159
+ for (const config of [".oxlintrc.json", ".oxlintrc.jsonc"]) if (fs.existsSync(path.join(projectPath, config))) {
3160
3160
  configs.oxlintConfig = config;
3161
3161
  break;
3162
3162
  }
@@ -3232,6 +3232,10 @@ const REMOVE_PACKAGES = [
3232
3232
  "@vitest/browser-playwright",
3233
3233
  "@vitest/browser-webdriverio"
3234
3234
  ];
3235
+ const BROWSER_PROVIDER_PEER_DEPS = {
3236
+ "@vitest/browser-playwright": "playwright",
3237
+ "@vitest/browser-webdriverio": "webdriverio"
3238
+ };
3235
3239
  function warnMigration(message, report) {
3236
3240
  addMigrationWarning(report, message);
3237
3241
  if (!report) log.warn(message);
@@ -3318,7 +3322,7 @@ async function runOxlintMigrateStep(vpBin, cwd, migratePackage, args, spinner, f
3318
3322
  }
3319
3323
  }
3320
3324
  async function migrateEslintToOxlint(projectPath, interactive, eslintConfigFile, packages, options) {
3321
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? "vp";
3325
+ const vpBin = process.env.VP_CLI_BIN ?? "vp";
3322
3326
  const spinner = options?.silent ? {
3323
3327
  start: () => {},
3324
3328
  stop: () => {},
@@ -3331,7 +3335,8 @@ async function migrateEslintToOxlint(projectPath, interactive, eslintConfigFile,
3331
3335
  isCancelled: false
3332
3336
  } : getSpinner(interactive);
3333
3337
  if (eslintConfigFile) {
3334
- const migratePackage = "@oxlint/migrate";
3338
+ const { versions } = await import("../versions.js");
3339
+ const migratePackage = `@oxlint/migrate@${versions.oxlint}`;
3335
3340
  spinner.start("Migrating ESLint config to Oxlint...");
3336
3341
  if (!await runOxlintMigrateStep(vpBin, projectPath, migratePackage, [
3337
3342
  "--merge",
@@ -3462,7 +3467,7 @@ async function runPrettierMigrateStep(vpBin, cwd, spinner, failMessage, manualHi
3462
3467
  }
3463
3468
  }
3464
3469
  async function migratePrettierToOxfmt(projectPath, interactive, prettierConfigFile, packages, options) {
3465
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? "vp";
3470
+ const vpBin = process.env.VP_CLI_BIN ?? "vp";
3466
3471
  const spinner = options?.silent ? {
3467
3472
  start: () => {},
3468
3473
  stop: () => {},
@@ -3582,6 +3587,8 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
3582
3587
  if (!fs.existsSync(packageJsonPath)) return;
3583
3588
  const packageManager = workspaceInfo.packageManager;
3584
3589
  let extractedStagedConfig = null;
3590
+ let remainingPnpmOverrides;
3591
+ let usePnpmWorkspaceYaml = false;
3585
3592
  editJsonFile(packageJsonPath, (pkg) => {
3586
3593
  if (packageManager === PackageManager.yarn) pkg.resolutions = {
3587
3594
  ...pkg.resolutions,
@@ -3592,23 +3599,46 @@ function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedMigratio
3592
3599
  ...VITE_PLUS_OVERRIDE_PACKAGES
3593
3600
  };
3594
3601
  else if (packageManager === PackageManager.pnpm) {
3595
- pkg.pnpm = {
3602
+ usePnpmWorkspaceYaml = !pkg.pnpm;
3603
+ if (usePnpmWorkspaceYaml) {
3604
+ rewritePnpmWorkspaceYaml(projectPath);
3605
+ if (isForceOverrideMode()) migratePnpmOverridesToWorkspaceYaml(projectPath, { [VITE_PLUS_NAME]: VITE_PLUS_VERSION });
3606
+ }
3607
+ const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
3608
+ if (!usePnpmWorkspaceYaml) pkg.pnpm = {
3596
3609
  ...pkg.pnpm,
3597
3610
  overrides: {
3598
3611
  ...pkg.pnpm?.overrides,
3599
3612
  ...VITE_PLUS_OVERRIDE_PACKAGES,
3600
3613
  ...isForceOverrideMode() ? { [VITE_PLUS_NAME]: VITE_PLUS_VERSION } : {}
3614
+ },
3615
+ peerDependencyRules: {
3616
+ ...pkg.pnpm?.peerDependencyRules,
3617
+ allowAny: [...new Set([...pkg.pnpm?.peerDependencyRules?.allowAny ?? [], ...overrideKeys])],
3618
+ allowedVersions: {
3619
+ ...pkg.pnpm?.peerDependencyRules?.allowedVersions,
3620
+ ...Object.fromEntries(overrideKeys.map((key) => [key, "*"]))
3621
+ }
3601
3622
  }
3602
3623
  };
3603
- for (const key of [...Object.keys(VITE_PLUS_OVERRIDE_PACKAGES), ...REMOVE_PACKAGES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
3624
+ else remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
3625
+ for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
3626
+ const splits = key.split(">");
3627
+ if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
3628
+ }
3629
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
3630
+ }
3631
+ extractedStagedConfig = rewritePackageJson(pkg, packageManager, usePnpmWorkspaceYaml, skipStagedMigration);
3632
+ if (!pkg.devDependencies?.["vite-plus"] || isForceOverrideMode()) {
3633
+ const version = usePnpmWorkspaceYaml && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
3634
+ pkg.devDependencies = {
3635
+ ...pkg.devDependencies,
3636
+ [VITE_PLUS_NAME]: version
3637
+ };
3604
3638
  }
3605
- extractedStagedConfig = rewritePackageJson(pkg, packageManager, false, skipStagedMigration);
3606
- if (!pkg.devDependencies?.["vite-plus"] || isForceOverrideMode()) pkg.devDependencies = {
3607
- ...pkg.devDependencies,
3608
- [VITE_PLUS_NAME]: VITE_PLUS_VERSION
3609
- };
3610
3639
  return pkg;
3611
3640
  });
3641
+ if (remainingPnpmOverrides) migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
3612
3642
  if (extractedStagedConfig) {
3613
3643
  if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) removeLintStagedFromPackageJson(packageJsonPath);
3614
3644
  }
@@ -3707,6 +3737,49 @@ function rewritePnpmWorkspaceYaml(projectPath) {
3707
3737
  });
3708
3738
  }
3709
3739
  /**
3740
+ * Clean up pnpm.overrides and peerDependencyRules from package.json when migrating
3741
+ * to pnpm-workspace.yaml. Returns any remaining non-Vite overrides that need to be
3742
+ * moved to pnpm-workspace.yaml.
3743
+ */
3744
+ function cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys) {
3745
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) if (pkg.pnpm?.overrides?.[key]) delete pkg.pnpm.overrides[key];
3746
+ for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
3747
+ const splits = key.split(">");
3748
+ if (splits[splits.length - 1].trim() === "vite") delete pkg.pnpm.overrides[key];
3749
+ }
3750
+ let remaining;
3751
+ if (pkg.pnpm?.overrides && Object.keys(pkg.pnpm.overrides).length > 0) remaining = { ...pkg.pnpm.overrides };
3752
+ delete pkg.pnpm?.overrides;
3753
+ cleanupPeerDependencyRules(pkg.pnpm?.peerDependencyRules, overrideKeys);
3754
+ if (pkg.pnpm?.peerDependencyRules && Object.keys(pkg.pnpm.peerDependencyRules).length === 0) delete pkg.pnpm.peerDependencyRules;
3755
+ if (pkg.pnpm && Object.keys(pkg.pnpm).length === 0) delete pkg.pnpm;
3756
+ return remaining;
3757
+ }
3758
+ /**
3759
+ * Move remaining non-Vite pnpm.overrides from package.json to pnpm-workspace.yaml.
3760
+ * pnpm ignores workspace-level overrides when pnpm.overrides exists in package.json,
3761
+ * so all overrides must live in pnpm-workspace.yaml.
3762
+ */
3763
+ function migratePnpmOverridesToWorkspaceYaml(projectPath, overrides) {
3764
+ editYamlFile(path.join(projectPath, "pnpm-workspace.yaml"), (doc) => {
3765
+ for (const [key, value] of Object.entries(overrides)) doc.setIn(["overrides", scalarString(key)], scalarString(value));
3766
+ });
3767
+ }
3768
+ /**
3769
+ * Remove only Vite-managed entries from peerDependencyRules, preserving custom ones.
3770
+ */
3771
+ function cleanupPeerDependencyRules(peerDependencyRules, overrideKeys) {
3772
+ if (!peerDependencyRules) return;
3773
+ if (Array.isArray(peerDependencyRules.allowAny)) {
3774
+ peerDependencyRules.allowAny = peerDependencyRules.allowAny.filter((key) => !overrideKeys.includes(key));
3775
+ if (peerDependencyRules.allowAny.length === 0) delete peerDependencyRules.allowAny;
3776
+ }
3777
+ if (peerDependencyRules.allowedVersions) {
3778
+ for (const key of overrideKeys) delete peerDependencyRules.allowedVersions[key];
3779
+ if (Object.keys(peerDependencyRules.allowedVersions).length === 0) delete peerDependencyRules.allowedVersions;
3780
+ }
3781
+ }
3782
+ /**
3710
3783
  * Rewrite .yarnrc.yml to add vite-plus dependencies
3711
3784
  * @param projectPath - The path to the project
3712
3785
  */
@@ -3760,6 +3833,7 @@ function rewriteBunCatalog(projectPath) {
3760
3833
  function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStagedMigration) {
3761
3834
  const packageJsonPath = path.join(projectPath, "package.json");
3762
3835
  if (!fs.existsSync(packageJsonPath)) return;
3836
+ let remainingPnpmOverrides;
3763
3837
  editJsonFile(packageJsonPath, (pkg) => {
3764
3838
  if (packageManager === PackageManager.yarn) pkg.resolutions = {
3765
3839
  ...pkg.resolutions,
@@ -3770,6 +3844,7 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
3770
3844
  ...VITE_PLUS_OVERRIDE_PACKAGES
3771
3845
  };
3772
3846
  else if (packageManager === PackageManager.bun) {} else if (packageManager === PackageManager.pnpm) {
3847
+ const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
3773
3848
  if (isForceOverrideMode()) pkg.pnpm = {
3774
3849
  ...pkg.pnpm,
3775
3850
  overrides: {
@@ -3778,9 +3853,9 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
3778
3853
  [VITE_PLUS_NAME]: VITE_PLUS_VERSION
3779
3854
  }
3780
3855
  };
3781
- else for (const key of [...Object.keys(VITE_PLUS_OVERRIDE_PACKAGES), ...REMOVE_PACKAGES]) {
3782
- if (pkg.pnpm?.overrides?.[key]) delete pkg.pnpm.overrides[key];
3783
- if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
3856
+ else {
3857
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) if (pkg.resolutions?.[key]) delete pkg.resolutions[key];
3858
+ remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
3784
3859
  }
3785
3860
  for (const key in pkg.pnpm?.overrides) if (key.includes(">")) {
3786
3861
  const splits = key.split(">");
@@ -3793,6 +3868,7 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
3793
3868
  };
3794
3869
  return pkg;
3795
3870
  });
3871
+ if (remainingPnpmOverrides) migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
3796
3872
  rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration);
3797
3873
  }
3798
3874
  const RULES_YAML_PATH = path.join(rulesDir, "vite-tools.yml");
@@ -3839,14 +3915,21 @@ function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMigration
3839
3915
  }
3840
3916
  }
3841
3917
  for (const name of REMOVE_PACKAGES) {
3842
- if (pkg.devDependencies?.[name]) {
3918
+ const wasInDevDeps = !!pkg.devDependencies?.[name];
3919
+ const wasInDeps = !!pkg.dependencies?.[name];
3920
+ if (wasInDevDeps) {
3843
3921
  delete pkg.devDependencies[name];
3844
3922
  needVitePlus = true;
3845
3923
  }
3846
- if (pkg.dependencies?.[name]) {
3924
+ if (wasInDeps) {
3847
3925
  delete pkg.dependencies[name];
3848
3926
  needVitePlus = true;
3849
3927
  }
3928
+ const peerDep = BROWSER_PROVIDER_PEER_DEPS[name];
3929
+ if ((wasInDevDeps || wasInDeps) && peerDep && !pkg.devDependencies?.[peerDep] && !pkg.dependencies?.[peerDep]) {
3930
+ pkg.devDependencies ??= {};
3931
+ pkg.devDependencies[peerDep] = "*";
3932
+ }
3850
3933
  }
3851
3934
  if (needVitePlus) {
3852
3935
  const version = supportCatalog && !VITE_PLUS_VERSION.startsWith("file:") ? "catalog:" : VITE_PLUS_VERSION;
@@ -3940,7 +4023,7 @@ function mergeViteConfigFiles(projectPath, silent = false, report) {
3940
4023
  const viteConfig = ensureViteConfig(projectPath, configs, silent, report);
3941
4024
  if (configs.oxlintConfig) {
3942
4025
  const fullOxlintPath = path.join(projectPath, configs.oxlintConfig);
3943
- const oxlintJson = JSON.parse(fs.readFileSync(fullOxlintPath, "utf8"));
4026
+ const oxlintJson = readJsonFile(fullOxlintPath, true);
3944
4027
  if (!oxlintJson.options) oxlintJson.options = {};
3945
4028
  if (!hasBaseUrlInTsconfig(projectPath)) {
3946
4029
  if (oxlintJson.options.typeAware === void 0) oxlintJson.options.typeAware = true;
@@ -4234,7 +4317,7 @@ function setupGitHooks(projectPath, oldHooksDir, silent = false, report) {
4234
4317
  stdio: "pipe"
4235
4318
  });
4236
4319
  }
4237
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? "vp";
4320
+ const vpBin = process.env.VP_CLI_BIN ?? "vp";
4238
4321
  const configArgs = isCustomDir ? [
4239
4322
  "config",
4240
4323
  "--hooks-only",
@@ -1,4 +1,4 @@
1
- import { D as promptGitHooks, T as defaultInteractive, d as ensurePreCommitHook, f as hasStagedConfigInViteConfig, i as updateExistingAgentInstructions } from "./agent-CmMz9vxG.js";
1
+ import { D as promptGitHooks, T as defaultInteractive, d as ensurePreCommitHook, f as hasStagedConfigInViteConfig, i as updateExistingAgentInstructions } from "./agent-CWLDLdxX.js";
2
2
  import { t as lib_default } from "./lib-DxappLRQ.js";
3
3
  import { i as log, t as renderCliDoc } from "./help-HviKaKAU.js";
4
4
  import { join } from "node:path";
@@ -1,9 +1,9 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./chunk-BoAXSpZd.js";
2
- import { A as selectPackageManager, B as log, D as promptGitHooks, E as downloadPackageManager$1, F as PackageManager, G as text, K as Ct, L as cancel, M as displayRelative, N as templatesDir, O as runViteFmt, P as DependencyType, R as confirm, T as defaultInteractive, U as select, V as multiselect, W as spinner, a as writeAgentInstructions, b as rewriteMonorepoProject, k as runViteInstall, n as detectExistingAgentTargetPaths, p as installGitHooks, r as selectAgentTargetPaths, x as rewriteStandaloneProject, y as rewriteMonorepo, z as intro } from "./agent-CmMz9vxG.js";
2
+ import { A as selectPackageManager, B as log, D as promptGitHooks, E as downloadPackageManager$1, F as PackageManager, G as text, K as Ct, L as cancel, M as displayRelative, N as templatesDir, O as runViteFmt, P as DependencyType, R as confirm, T as defaultInteractive, U as select, V as multiselect, W as spinner, a as writeAgentInstructions, b as rewriteMonorepoProject, k as runViteInstall, n as detectExistingAgentTargetPaths, p as installGitHooks, r as selectAgentTargetPaths, x as rewriteStandaloneProject, y as rewriteMonorepo, z as intro } from "./agent-CWLDLdxX.js";
3
3
  import { t as lib_default } from "./lib-DxappLRQ.js";
4
- import { c as readJsonFile, o as editJsonFile, t as checkNpmPackageExists } from "./package-CnlCtq4D.js";
4
+ import { c as readJsonFile, o as editJsonFile, t as checkNpmPackageExists } from "./package-2ArHHFnA.js";
5
5
  import { a as muted, i as log$1, n as accent, o as success, t as renderCliDoc } from "./help-HviKaKAU.js";
6
- import { a as detectExistingEditor, n as updatePackageJsonWithDeps, o as selectEditor, r as updateWorkspaceConfig, s as writeEditorConfigs, t as detectWorkspace$1 } from "./workspace-CWMon7nr.js";
6
+ import { a as detectExistingEditor, n as updatePackageJsonWithDeps, o as selectEditor, r as updateWorkspaceConfig, s as writeEditorConfigs, t as detectWorkspace$1 } from "./workspace-bFOexoT6.js";
7
7
  import path from "node:path";
8
8
  import { styleText } from "node:util";
9
9
  import color from "picocolors";
@@ -3156,7 +3156,7 @@ function getRandomWord() {
3156
3156
  }
3157
3157
  //#endregion
3158
3158
  //#region src/create/random-name.ts
3159
- const isTest = process.env.VITE_PLUS_CLI_TEST === "1";
3159
+ const isTest = process.env.VP_CLI_TEST === "1";
3160
3160
  function getRandomWords() {
3161
3161
  const first = getRandomWord();
3162
3162
  let second;
@@ -1,10 +1,10 @@
1
1
  import { r as __toESM } from "./chunk-BoAXSpZd.js";
2
- import { A as selectPackageManager, B as log, D as promptGitHooks, E as downloadPackageManager$1, F as PackageManager, H as outro, I as require_semver, K as Ct, M as displayRelative, R as confirm, T as defaultInteractive, U as select, W as spinner, _ as migratePrettierToOxfmt, a as writeAgentInstructions, c as detectEslintProject, g as migrateNodeVersionManagerFile, h as migrateEslintToOxlint, j as upgradeYarn, k as runViteInstall, l as detectNodeVersionManagerFile, m as mergeViteConfigFiles, n as detectExistingAgentTargetPaths, o as checkViteVersion, p as installGitHooks, r as selectAgentTargetPaths, s as checkVitestVersion, t as detectAgentConflicts, u as detectPrettierProject, v as preflightGitHooksSetup, w as cancelAndExit, x as rewriteStandaloneProject, y as rewriteMonorepo } from "./agent-CmMz9vxG.js";
2
+ import { A as selectPackageManager, B as log, D as promptGitHooks, E as downloadPackageManager$1, F as PackageManager, H as outro, I as require_semver, K as Ct, M as displayRelative, R as confirm, T as defaultInteractive, U as select, W as spinner, _ as migratePrettierToOxfmt, a as writeAgentInstructions, c as detectEslintProject, g as migrateNodeVersionManagerFile, h as migrateEslintToOxlint, j as upgradeYarn, k as runViteInstall, l as detectNodeVersionManagerFile, m as mergeViteConfigFiles, n as detectExistingAgentTargetPaths, o as checkViteVersion, p as installGitHooks, r as selectAgentTargetPaths, s as checkVitestVersion, t as detectAgentConflicts, u as detectPrettierProject, v as preflightGitHooksSetup, w as cancelAndExit, x as rewriteStandaloneProject, y as rewriteMonorepo } from "./agent-CWLDLdxX.js";
3
3
  import { t as lib_default } from "./lib-DxappLRQ.js";
4
- import { _ as isForceOverrideMode, a as readNearestPackageJson, i as hasVitePlusDependency } from "./package-CnlCtq4D.js";
4
+ import { _ as isForceOverrideMode, a as readNearestPackageJson, i as hasVitePlusDependency } from "./package-2ArHHFnA.js";
5
5
  import { a as muted, i as log$1, n as accent, t as renderCliDoc } from "./help-HviKaKAU.js";
6
6
  import { r as createMigrationReport } from "./report-DGaKL5VQ.js";
7
- import { i as detectEditorConflicts, o as selectEditor, s as writeEditorConfigs, t as detectWorkspace$1 } from "./workspace-CWMon7nr.js";
7
+ import { i as detectEditorConflicts, o as selectEditor, s as writeEditorConfigs, t as detectWorkspace$1 } from "./workspace-bFOexoT6.js";
8
8
  import path from "node:path";
9
9
  import { styleText } from "node:util";
10
10
  import { vitePlusHeader } from "../../binding/index.js";
@@ -3,18 +3,18 @@ import fs from "node:fs";
3
3
  import { createRequire } from "node:module";
4
4
  //#region src/utils/constants.ts
5
5
  const VITE_PLUS_NAME = "vite-plus";
6
- const VITE_PLUS_VERSION = process.env.VITE_PLUS_VERSION || "latest";
7
- const VITE_PLUS_OVERRIDE_PACKAGES = process.env.VITE_PLUS_OVERRIDE_PACKAGES ? JSON.parse(process.env.VITE_PLUS_OVERRIDE_PACKAGES) : {
6
+ const VITE_PLUS_VERSION = process.env.VP_VERSION || "latest";
7
+ const VITE_PLUS_OVERRIDE_PACKAGES = process.env.VP_OVERRIDE_PACKAGES ? JSON.parse(process.env.VP_OVERRIDE_PACKAGES) : {
8
8
  vite: "npm:@voidzero-dev/vite-plus-core@latest",
9
9
  vitest: "npm:@voidzero-dev/vite-plus-test@latest"
10
10
  };
11
11
  /**
12
- * When VITE_PLUS_FORCE_MIGRATE is set, force full dependency rewriting
12
+ * When VP_FORCE_MIGRATE is set, force full dependency rewriting
13
13
  * even for projects already using vite-plus. Used by ecosystem CI to
14
14
  * override dependencies with locally built tgz packages.
15
15
  */
16
16
  function isForceOverrideMode() {
17
- return process.env.VITE_PLUS_FORCE_MIGRATE === "1";
17
+ return process.env.VP_FORCE_MIGRATE === "1";
18
18
  }
19
19
  createRequire(import.meta.url);
20
20
  const BASEURL_TSCONFIG_WARNING = "Skipped typeAware/typeCheck: tsconfig.json contains baseUrl which is not yet supported by the oxlint type checker.\n Run `npx @andrewbranch/ts5to6 --fixBaseUrl .` to remove baseUrl from your tsconfig.";
@@ -1,16 +1,27 @@
1
- import { i as hasVitePlusDependency, m as VITE_PLUS_NAME, n as detectPackageMetadata } from "./package-CnlCtq4D.js";
1
+ import { i as hasVitePlusDependency, n as detectPackageMetadata } from "./package-2ArHHFnA.js";
2
2
  import { i as log, n as accent, t as renderCliDoc } from "./help-HviKaKAU.js";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs";
5
5
  import { vitePlusHeader } from "../../binding/index.js";
6
- import { createRequire } from "node:module";
6
+ //#region package.json
7
+ var version = "0.0.0";
8
+ //#endregion
7
9
  //#region src/version.ts
8
- const require = createRequire(import.meta.url);
10
+ /** Tool display names in the order shown by `vp --version`. */
11
+ const TOOL_DISPLAY_ORDER = [
12
+ "vite",
13
+ "rolldown",
14
+ "vitest",
15
+ "oxfmt",
16
+ "oxlint",
17
+ "oxlint-tsgolint",
18
+ "tsdown"
19
+ ];
9
20
  function getGlobalVersion() {
10
- return process.env.VITE_PLUS_GLOBAL_VERSION ?? null;
21
+ return process.env.VP_GLOBAL_VERSION ?? null;
11
22
  }
12
23
  function getCliVersion() {
13
- return resolvePackageJson(VITE_PLUS_NAME, process.cwd())?.version ?? null;
24
+ return version ?? null;
14
25
  }
15
26
  function getLocalMetadata(cwd) {
16
27
  if (!isVitePlusDeclaredInAncestors(cwd)) return null;
@@ -19,45 +30,26 @@ function getLocalMetadata(cwd) {
19
30
  function isVitePlusDeclaredInAncestors(cwd) {
20
31
  let currentDir = path.resolve(cwd);
21
32
  while (true) {
22
- const pkg = readPackageJsonFromPath(path.join(currentDir, "package.json"));
23
- if (pkg && hasVitePlusDependency(pkg)) return true;
33
+ const packageJsonPath = path.join(currentDir, "package.json");
34
+ try {
35
+ if (hasVitePlusDependency(JSON.parse(fs.readFileSync(packageJsonPath, "utf8")))) return true;
36
+ } catch {}
24
37
  const parentDir = path.dirname(currentDir);
25
38
  if (parentDir === currentDir) break;
26
39
  currentDir = parentDir;
27
40
  }
28
41
  return false;
29
42
  }
30
- function readPackageJsonFromPath(packageJsonPath) {
31
- try {
32
- return JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
33
- } catch {
34
- return null;
35
- }
36
- }
37
- function resolvePackageJson(packageName, baseDir) {
43
+ /**
44
+ * Resolve all tool versions from the locally installed vite-plus package.
45
+ * Uses the `vite-plus/versions` export generated by `syncVersionsExport()`.
46
+ */
47
+ async function resolveToolVersions(localPackagePath) {
38
48
  try {
39
- return readPackageJsonFromPath(require.resolve(`${packageName}/package.json`, { paths: [baseDir] }));
40
- } catch {
41
- try {
42
- const mainPath = require.resolve(packageName, { paths: [baseDir] });
43
- let dir = path.dirname(mainPath);
44
- while (dir !== path.dirname(dir)) {
45
- const pkg = readPackageJsonFromPath(path.join(dir, "package.json"));
46
- if (pkg) return pkg;
47
- dir = path.dirname(dir);
48
- }
49
- } catch {}
50
- return null;
51
- }
52
- }
53
- function resolveToolVersion(tool, localPackagePath) {
54
- const pkg = resolvePackageJson(tool.packageName, localPackagePath);
55
- const bundledVersion = tool.bundledVersionKey ? pkg?.bundledVersions?.[tool.bundledVersionKey] ?? null : null;
56
- if (bundledVersion) return bundledVersion;
57
- const version = pkg?.version ?? null;
58
- if (version) return version;
59
- if (tool.fallbackPackageJson) return readPackageJsonFromPath(path.join(localPackagePath, tool.fallbackPackageJson))?.version ?? null;
60
- return null;
49
+ const mod = await import(`${localPackagePath}/dist/versions.js`);
50
+ if (mod.versions && typeof mod.versions === "object") return mod.versions;
51
+ } catch {}
52
+ return {};
61
53
  }
62
54
  /**
63
55
  * Print version information
@@ -78,50 +70,13 @@ async function printVersion(cwd) {
78
70
  description: localVersion ? `v${localVersion}` : "Not found"
79
71
  }]
80
72
  }];
81
- const tools = [
82
- {
83
- displayName: "vite",
84
- packageName: "@voidzero-dev/vite-plus-core",
85
- bundledVersionKey: "vite"
86
- },
87
- {
88
- displayName: "rolldown",
89
- packageName: "@voidzero-dev/vite-plus-core",
90
- bundledVersionKey: "rolldown"
91
- },
92
- {
93
- displayName: "vitest",
94
- packageName: "@voidzero-dev/vite-plus-test",
95
- bundledVersionKey: "vitest"
96
- },
97
- {
98
- displayName: "oxfmt",
99
- packageName: "oxfmt"
100
- },
101
- {
102
- displayName: "oxlint",
103
- packageName: "oxlint"
104
- },
105
- {
106
- displayName: "oxlint-tsgolint",
107
- packageName: "oxlint-tsgolint"
108
- },
109
- {
110
- displayName: "tsdown",
111
- packageName: "@voidzero-dev/vite-plus-core",
112
- bundledVersionKey: "tsdown"
113
- }
114
- ];
115
73
  if (localMetadata) {
116
- const resolvedTools = tools.map((tool) => ({
117
- tool,
118
- version: resolveToolVersion(tool, localMetadata.path)
119
- }));
74
+ const versions = await resolveToolVersions(localMetadata.path);
120
75
  sections.push({
121
76
  title: "Tools",
122
- rows: resolvedTools.map(({ tool, version }) => ({
123
- label: accent(tool.displayName),
124
- description: version ? `v${version}` : "Not found"
77
+ rows: TOOL_DISPLAY_ORDER.map((name) => ({
78
+ label: accent(name),
79
+ description: versions[name] ? `v${versions[name]}` : "Not found"
125
80
  }))
126
81
  });
127
82
  }
@@ -1,6 +1,6 @@
1
- import { B as log, C as readYamlFile, F as PackageManager, K as Ct, S as editYamlFile, U as select } from "./agent-CmMz9vxG.js";
1
+ import { B as log, C as readYamlFile, F as PackageManager, K as Ct, S as editYamlFile, U as select } from "./agent-CWLDLdxX.js";
2
2
  import { g as YAMLSeq, y as Scalar } from "./browser-09BZLUYM.js";
3
- import { c as readJsonFile, l as writeJsonFile, o as editJsonFile, r as getScopeFromPackageName } from "./package-CnlCtq4D.js";
3
+ import { c as readJsonFile, l as writeJsonFile, o as editJsonFile, r as getScopeFromPackageName } from "./package-2ArHHFnA.js";
4
4
  import path, { posix, win32 } from "node:path";
5
5
  import * as actualFS from "node:fs";
6
6
  import fs from "node:fs";
@@ -23,9 +23,7 @@ const VSCODE_EXTENSIONS = { recommendations: ["VoidZero.vite-plus-extension-pack
23
23
  const ZED_SETTINGS = {
24
24
  lsp: {
25
25
  oxlint: { initialization_options: { settings: {
26
- configPath: "./.oxlintrc.json",
27
26
  run: "onType",
28
- disableNestedConfig: false,
29
27
  fixKind: "safe_fix",
30
28
  typeAware: true,
31
29
  unusedDisableDirectives: "deny"
package/dist/index.cjs CHANGED
@@ -1,3 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
1
3
  const vite = require('@voidzero-dev/vite-plus-core');
2
4
  const vitest = require('@voidzero-dev/vite-plus-test/config');
3
5
  const { defineConfig } = require('./define-config');
package/dist/index.d.ts CHANGED
@@ -2,9 +2,9 @@ import { type Plugin as VitestPlugin } from '@voidzero-dev/vite-plus-test/config
2
2
  import type { OxfmtConfig } from 'oxfmt';
3
3
  import type { OxlintConfig } from 'oxlint';
4
4
  import { defineConfig } from './define-config.js';
5
- import type { PackUserConfig } from './pack';
6
- import type { RunConfig } from './run-config';
7
- import type { StagedConfig } from './staged-config';
5
+ import type { PackUserConfig } from './pack.js';
6
+ import type { RunConfig } from './run-config.js';
7
+ import type { StagedConfig } from './staged-config.js';
8
8
  declare module '@voidzero-dev/vite-plus-core' {
9
9
  interface UserConfig {
10
10
  /**
package/dist/lint.d.ts CHANGED
@@ -1 +1 @@
1
- export { type AllowWarnDeny, type DummyRule, type DummyRuleMap, type ExternalPluginEntry, type ExternalPluginsConfig, type OxlintConfig, type OxlintEnv, type OxlintGlobals, type OxlintOverride, type RuleCategories, defineConfig, } from 'oxlint';
1
+ export type * from 'oxlint';
package/dist/lint.js CHANGED
@@ -1 +1,3 @@
1
- export { defineConfig, } from 'oxlint';
1
+ // For now, `defineConfig()` is the only non-type exports from `oxlint`,
2
+ // but in Vite+, users should use `defineConfig()` from 'vite-plus`.
3
+ export {};
@@ -79,7 +79,7 @@ export function detectConfigs(projectPath) {
79
79
  }
80
80
  // Check for oxlint configs
81
81
  // https://oxc.rs/docs/guide/usage/linter/config.html#configuration-file-format
82
- const oxlintConfigs = ['.oxlintrc.json'];
82
+ const oxlintConfigs = ['.oxlintrc.json', '.oxlintrc.jsonc'];
83
83
  for (const config of oxlintConfigs) {
84
84
  if (fs.existsSync(path.join(projectPath, config))) {
85
85
  configs.oxlintConfig = config;
@@ -50,6 +50,12 @@ const REMOVE_PACKAGES = [
50
50
  '@vitest/browser-playwright',
51
51
  '@vitest/browser-webdriverio',
52
52
  ];
53
+ // When a browser provider package is removed, its runtime peer dependency
54
+ // must be preserved in devDependencies so browser tests continue to work.
55
+ const BROWSER_PROVIDER_PEER_DEPS = {
56
+ '@vitest/browser-playwright': 'playwright',
57
+ '@vitest/browser-webdriverio': 'webdriverio',
58
+ };
53
59
  function warnMigration(message, report) {
54
60
  addMigrationWarning(report, message);
55
61
  if (!report) {
@@ -144,7 +150,7 @@ async function runOxlintMigrateStep(vpBin, cwd, migratePackage, args, spinner, f
144
150
  }
145
151
  }
146
152
  export async function migrateEslintToOxlint(projectPath, interactive, eslintConfigFile, packages, options) {
147
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? 'vp';
153
+ const vpBin = process.env.VP_CLI_BIN ?? 'vp';
148
154
  const spinner = options?.silent
149
155
  ? {
150
156
  start: () => { },
@@ -160,7 +166,10 @@ export async function migrateEslintToOxlint(projectPath, interactive, eslintConf
160
166
  : getSpinner(interactive);
161
167
  // Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root
162
168
  if (eslintConfigFile) {
163
- const migratePackage = '@oxlint/migrate';
169
+ // Pin @oxlint/migrate to the bundled oxlint version.
170
+ // @ts-expect-error — resolved at runtime from dist/global/ → dist/versions.js
171
+ const { versions } = await import('../versions.js');
172
+ const migratePackage = `@oxlint/migrate@${versions.oxlint}`;
164
173
  // Step 1: Generate .oxlintrc.json from ESLint config
165
174
  spinner.start('Migrating ESLint config to Oxlint...');
166
175
  const migrateOk = await runOxlintMigrateStep(vpBin, projectPath, migratePackage, ['--merge', '--type-aware', '--with-nursery', '--details'], spinner, 'ESLint migration failed', `You can run \`vp dlx ${migratePackage} --merge --type-aware --with-nursery --details\` manually later`);
@@ -326,7 +335,7 @@ async function runPrettierMigrateStep(vpBin, cwd, spinner, failMessage, manualHi
326
335
  }
327
336
  }
328
337
  export async function migratePrettierToOxfmt(projectPath, interactive, prettierConfigFile, packages, options) {
329
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? 'vp';
338
+ const vpBin = process.env.VP_CLI_BIN ?? 'vp';
330
339
  const spinner = options?.silent
331
340
  ? {
332
341
  start: () => { },
@@ -508,6 +517,9 @@ export function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedM
508
517
  }
509
518
  const packageManager = workspaceInfo.packageManager;
510
519
  let extractedStagedConfig = null;
520
+ let remainingPnpmOverrides;
521
+ // Determined inside editJsonFile callback to avoid a redundant file read
522
+ let usePnpmWorkspaceYaml = false;
511
523
  editJsonFile(packageJsonPath, (pkg) => {
512
524
  if (packageManager === PackageManager.yarn) {
513
525
  pkg.resolutions = {
@@ -522,32 +534,78 @@ export function rewriteStandaloneProject(projectPath, workspaceInfo, skipStagedM
522
534
  };
523
535
  }
524
536
  else if (packageManager === PackageManager.pnpm) {
525
- pkg.pnpm = {
526
- ...pkg.pnpm,
527
- overrides: {
528
- ...pkg.pnpm?.overrides,
529
- ...VITE_PLUS_OVERRIDE_PACKAGES,
530
- ...(isForceOverrideMode() ? { [VITE_PLUS_NAME]: VITE_PLUS_VERSION } : {}),
531
- },
532
- };
537
+ // If package.json already has a "pnpm" field, keep using it;
538
+ // otherwise use pnpm-workspace.yaml.
539
+ usePnpmWorkspaceYaml = !pkg.pnpm;
540
+ if (usePnpmWorkspaceYaml) {
541
+ rewritePnpmWorkspaceYaml(projectPath);
542
+ // In force-override mode, also override vite-plus itself so transitive
543
+ // deps resolve to the local tgz instead of the published version.
544
+ if (isForceOverrideMode()) {
545
+ migratePnpmOverridesToWorkspaceYaml(projectPath, {
546
+ [VITE_PLUS_NAME]: VITE_PLUS_VERSION,
547
+ });
548
+ }
549
+ }
550
+ const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
551
+ if (!usePnpmWorkspaceYaml) {
552
+ // Project already has pnpm config in package.json -- keep using it.
553
+ pkg.pnpm = {
554
+ ...pkg.pnpm,
555
+ overrides: {
556
+ ...pkg.pnpm?.overrides,
557
+ ...VITE_PLUS_OVERRIDE_PACKAGES,
558
+ ...(isForceOverrideMode() ? { [VITE_PLUS_NAME]: VITE_PLUS_VERSION } : {}),
559
+ },
560
+ peerDependencyRules: {
561
+ ...pkg.pnpm?.peerDependencyRules,
562
+ allowAny: [
563
+ ...new Set([...(pkg.pnpm?.peerDependencyRules?.allowAny ?? []), ...overrideKeys]),
564
+ ],
565
+ allowedVersions: {
566
+ ...pkg.pnpm?.peerDependencyRules?.allowedVersions,
567
+ ...Object.fromEntries(overrideKeys.map((key) => [key, '*'])),
568
+ },
569
+ },
570
+ };
571
+ }
572
+ else {
573
+ remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
574
+ }
575
+ // remove dependency selectors targeting vite (e.g. "vite-plugin-svgr>vite")
576
+ for (const key in pkg.pnpm?.overrides) {
577
+ if (key.includes('>')) {
578
+ const splits = key.split('>');
579
+ if (splits[splits.length - 1].trim() === 'vite') {
580
+ delete pkg.pnpm.overrides[key];
581
+ }
582
+ }
583
+ }
533
584
  // remove packages from `resolutions` field if they exist
534
585
  // https://pnpm.io/9.x/package_json#resolutions
535
- for (const key of [...Object.keys(VITE_PLUS_OVERRIDE_PACKAGES), ...REMOVE_PACKAGES]) {
586
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) {
536
587
  if (pkg.resolutions?.[key]) {
537
588
  delete pkg.resolutions[key];
538
589
  }
539
590
  }
540
591
  }
541
- extractedStagedConfig = rewritePackageJson(pkg, packageManager, false, skipStagedMigration);
592
+ extractedStagedConfig = rewritePackageJson(pkg, packageManager, usePnpmWorkspaceYaml, skipStagedMigration);
542
593
  // ensure vite-plus is in devDependencies
543
594
  if (!pkg.devDependencies?.[VITE_PLUS_NAME] || isForceOverrideMode()) {
595
+ const version = usePnpmWorkspaceYaml && !VITE_PLUS_VERSION.startsWith('file:')
596
+ ? 'catalog:'
597
+ : VITE_PLUS_VERSION;
544
598
  pkg.devDependencies = {
545
599
  ...pkg.devDependencies,
546
- [VITE_PLUS_NAME]: VITE_PLUS_VERSION,
600
+ [VITE_PLUS_NAME]: version,
547
601
  };
548
602
  }
549
603
  return pkg;
550
604
  });
605
+ // Move remaining non-Vite pnpm.overrides to pnpm-workspace.yaml
606
+ if (remainingPnpmOverrides) {
607
+ migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
608
+ }
551
609
  // Merge extracted staged config into vite.config.ts, then remove lint-staged from package.json
552
610
  if (extractedStagedConfig) {
553
611
  if (mergeStagedConfigToViteConfig(projectPath, extractedStagedConfig, silent, report)) {
@@ -704,6 +762,81 @@ function rewritePnpmWorkspaceYaml(projectPath) {
704
762
  }
705
763
  });
706
764
  }
765
+ /**
766
+ * Clean up pnpm.overrides and peerDependencyRules from package.json when migrating
767
+ * to pnpm-workspace.yaml. Returns any remaining non-Vite overrides that need to be
768
+ * moved to pnpm-workspace.yaml.
769
+ */
770
+ function cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys) {
771
+ // Remove Vite-managed keys from pnpm.overrides
772
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) {
773
+ if (pkg.pnpm?.overrides?.[key]) {
774
+ delete pkg.pnpm.overrides[key];
775
+ }
776
+ }
777
+ // Remove dependency selectors targeting vite
778
+ for (const key in pkg.pnpm?.overrides) {
779
+ if (key.includes('>')) {
780
+ const splits = key.split('>');
781
+ if (splits[splits.length - 1].trim() === 'vite') {
782
+ delete pkg.pnpm.overrides[key];
783
+ }
784
+ }
785
+ }
786
+ // Collect remaining overrides to move to pnpm-workspace.yaml then delete all
787
+ // (pnpm ignores workspace-level overrides when pnpm.overrides exists in package.json)
788
+ let remaining;
789
+ if (pkg.pnpm?.overrides && Object.keys(pkg.pnpm.overrides).length > 0) {
790
+ remaining = { ...pkg.pnpm.overrides };
791
+ }
792
+ delete pkg.pnpm?.overrides;
793
+ // Only remove Vite-managed peerDependencyRules entries, preserve custom ones
794
+ cleanupPeerDependencyRules(pkg.pnpm?.peerDependencyRules, overrideKeys);
795
+ if (pkg.pnpm?.peerDependencyRules && Object.keys(pkg.pnpm.peerDependencyRules).length === 0) {
796
+ delete pkg.pnpm.peerDependencyRules;
797
+ }
798
+ if (pkg.pnpm && Object.keys(pkg.pnpm).length === 0) {
799
+ delete pkg.pnpm;
800
+ }
801
+ return remaining;
802
+ }
803
+ /**
804
+ * Move remaining non-Vite pnpm.overrides from package.json to pnpm-workspace.yaml.
805
+ * pnpm ignores workspace-level overrides when pnpm.overrides exists in package.json,
806
+ * so all overrides must live in pnpm-workspace.yaml.
807
+ */
808
+ function migratePnpmOverridesToWorkspaceYaml(projectPath, overrides) {
809
+ const pnpmWorkspaceYamlPath = path.join(projectPath, 'pnpm-workspace.yaml');
810
+ editYamlFile(pnpmWorkspaceYamlPath, (doc) => {
811
+ for (const [key, value] of Object.entries(overrides)) {
812
+ // Always overwrite: package.json value was the effective one before migration
813
+ // (pnpm ignores workspace overrides when pnpm.overrides exists in package.json)
814
+ doc.setIn(['overrides', scalarString(key)], scalarString(value));
815
+ }
816
+ });
817
+ }
818
+ /**
819
+ * Remove only Vite-managed entries from peerDependencyRules, preserving custom ones.
820
+ */
821
+ function cleanupPeerDependencyRules(peerDependencyRules, overrideKeys) {
822
+ if (!peerDependencyRules) {
823
+ return;
824
+ }
825
+ if (Array.isArray(peerDependencyRules.allowAny)) {
826
+ peerDependencyRules.allowAny = peerDependencyRules.allowAny.filter((key) => !overrideKeys.includes(key));
827
+ if (peerDependencyRules.allowAny.length === 0) {
828
+ delete peerDependencyRules.allowAny;
829
+ }
830
+ }
831
+ if (peerDependencyRules.allowedVersions) {
832
+ for (const key of overrideKeys) {
833
+ delete peerDependencyRules.allowedVersions[key];
834
+ }
835
+ if (Object.keys(peerDependencyRules.allowedVersions).length === 0) {
836
+ delete peerDependencyRules.allowedVersions;
837
+ }
838
+ }
839
+ }
707
840
  /**
708
841
  * Rewrite .yarnrc.yml to add vite-plus dependencies
709
842
  * @param projectPath - The path to the project
@@ -787,6 +920,7 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
787
920
  if (!fs.existsSync(packageJsonPath)) {
788
921
  return;
789
922
  }
923
+ let remainingPnpmOverrides;
790
924
  editJsonFile(packageJsonPath, (pkg) => {
791
925
  if (packageManager === PackageManager.yarn) {
792
926
  pkg.resolutions = {
@@ -806,6 +940,7 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
806
940
  // bun overrides are handled in rewriteBunCatalog() with catalog: references
807
941
  }
808
942
  else if (packageManager === PackageManager.pnpm) {
943
+ const overrideKeys = Object.keys(VITE_PLUS_OVERRIDE_PACKAGES);
809
944
  if (isForceOverrideMode()) {
810
945
  // In force-override mode, keep overrides in package.json pnpm.overrides
811
946
  // because pnpm ignores pnpm-workspace.yaml overrides when pnpm.overrides
@@ -820,20 +955,14 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
820
955
  };
821
956
  }
822
957
  else {
823
- // pnpm use overrides field at pnpm-workspace.yaml
824
- // so we don't need to set overrides field at package.json
825
- // remove packages from `resolutions` field and `pnpm.overrides` field if they exist
826
- // https://pnpm.io/9.x/package_json#resolutions
827
- for (const key of [...Object.keys(VITE_PLUS_OVERRIDE_PACKAGES), ...REMOVE_PACKAGES]) {
828
- if (pkg.pnpm?.overrides?.[key]) {
829
- delete pkg.pnpm.overrides[key];
830
- }
958
+ for (const key of [...overrideKeys, ...REMOVE_PACKAGES]) {
831
959
  if (pkg.resolutions?.[key]) {
832
960
  delete pkg.resolutions[key];
833
961
  }
834
962
  }
963
+ remainingPnpmOverrides = cleanupPnpmOverridesForWorkspaceYaml(pkg, overrideKeys);
835
964
  }
836
- // remove dependency selector from vite, e.g. "vite-plugin-svgr>vite": "npm:vite@7.0.12"
965
+ // remove dependency selectors targeting vite (e.g. "vite-plugin-svgr>vite")
837
966
  for (const key in pkg.pnpm?.overrides) {
838
967
  if (key.includes('>')) {
839
968
  const splits = key.split('>');
@@ -854,6 +983,10 @@ function rewriteRootWorkspacePackageJson(projectPath, packageManager, skipStaged
854
983
  }
855
984
  return pkg;
856
985
  });
986
+ // Move remaining non-Vite pnpm.overrides to pnpm-workspace.yaml
987
+ if (remainingPnpmOverrides) {
988
+ migratePnpmOverridesToWorkspaceYaml(projectPath, remainingPnpmOverrides);
989
+ }
857
990
  // rewrite package.json
858
991
  rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration);
859
992
  }
@@ -913,14 +1046,25 @@ export function rewritePackageJson(pkg, packageManager, isMonorepo, skipStagedMi
913
1046
  }
914
1047
  // remove packages that are replaced with vite-plus
915
1048
  for (const name of REMOVE_PACKAGES) {
916
- if (pkg.devDependencies?.[name]) {
1049
+ const wasInDevDeps = !!pkg.devDependencies?.[name];
1050
+ const wasInDeps = !!pkg.dependencies?.[name];
1051
+ if (wasInDevDeps) {
917
1052
  delete pkg.devDependencies[name];
918
1053
  needVitePlus = true;
919
1054
  }
920
- if (pkg.dependencies?.[name]) {
1055
+ if (wasInDeps) {
921
1056
  delete pkg.dependencies[name];
922
1057
  needVitePlus = true;
923
1058
  }
1059
+ // e.g., removing @vitest/browser-playwright should keep `playwright` in devDeps
1060
+ const peerDep = BROWSER_PROVIDER_PEER_DEPS[name];
1061
+ if ((wasInDevDeps || wasInDeps) &&
1062
+ peerDep &&
1063
+ !pkg.devDependencies?.[peerDep] &&
1064
+ !pkg.dependencies?.[peerDep]) {
1065
+ pkg.devDependencies ??= {};
1066
+ pkg.devDependencies[peerDep] = '*';
1067
+ }
924
1068
  }
925
1069
  if (needVitePlus) {
926
1070
  // add vite-plus to devDependencies
@@ -1055,7 +1199,7 @@ export function mergeViteConfigFiles(projectPath, silent = false, report) {
1055
1199
  if (configs.oxlintConfig) {
1056
1200
  // Inject options.typeAware and options.typeCheck defaults before merging
1057
1201
  const fullOxlintPath = path.join(projectPath, configs.oxlintConfig);
1058
- const oxlintJson = JSON.parse(fs.readFileSync(fullOxlintPath, 'utf8'));
1202
+ const oxlintJson = readJsonFile(fullOxlintPath, true);
1059
1203
  if (!oxlintJson.options) {
1060
1204
  oxlintJson.options = {};
1061
1205
  }
@@ -1448,7 +1592,7 @@ export function setupGitHooks(projectPath, oldHooksDir, silent = false, report)
1448
1592
  });
1449
1593
  }
1450
1594
  }
1451
- const vpBin = process.env.VITE_PLUS_CLI_BIN ?? 'vp';
1595
+ const vpBin = process.env.VP_CLI_BIN ?? 'vp';
1452
1596
  // Install git hooks via vp config (--hooks-only to skip agent setup, handled by migration)
1453
1597
  const configArgs = isCustomDir
1454
1598
  ? ['config', '--hooks-only', '--hooks-dir', hooksDir]
@@ -14,7 +14,7 @@ export type GlobWithBase = {
14
14
  */
15
15
  base: InputBase;
16
16
  };
17
- export type InputBase = 'package' | 'workspace';
17
+ export type InputBase = "package" | "workspace";
18
18
  export type Task = {
19
19
  /**
20
20
  * The command to run for the task.
@@ -1 +1,2 @@
1
1
  // This file is auto-generated by `cargo test`. Do not edit manually.
2
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -2,7 +2,7 @@ export declare const VITE_PLUS_NAME = "vite-plus";
2
2
  export declare const VITE_PLUS_VERSION: string;
3
3
  export declare const VITE_PLUS_OVERRIDE_PACKAGES: Record<string, string>;
4
4
  /**
5
- * When VITE_PLUS_FORCE_MIGRATE is set, force full dependency rewriting
5
+ * When VP_FORCE_MIGRATE is set, force full dependency rewriting
6
6
  * even for projects already using vite-plus. Used by ecosystem CI to
7
7
  * override dependencies with locally built tgz packages.
8
8
  */
@@ -1,20 +1,19 @@
1
1
  import { createRequire } from 'node:module';
2
2
  export const VITE_PLUS_NAME = 'vite-plus';
3
- export const VITE_PLUS_VERSION = process.env.VITE_PLUS_VERSION || 'latest';
4
- export const VITE_PLUS_OVERRIDE_PACKAGES = process.env
5
- .VITE_PLUS_OVERRIDE_PACKAGES
6
- ? JSON.parse(process.env.VITE_PLUS_OVERRIDE_PACKAGES)
3
+ export const VITE_PLUS_VERSION = process.env.VP_VERSION || 'latest';
4
+ export const VITE_PLUS_OVERRIDE_PACKAGES = process.env.VP_OVERRIDE_PACKAGES
5
+ ? JSON.parse(process.env.VP_OVERRIDE_PACKAGES)
7
6
  : {
8
7
  vite: 'npm:@voidzero-dev/vite-plus-core@latest',
9
8
  vitest: 'npm:@voidzero-dev/vite-plus-test@latest',
10
9
  };
11
10
  /**
12
- * When VITE_PLUS_FORCE_MIGRATE is set, force full dependency rewriting
11
+ * When VP_FORCE_MIGRATE is set, force full dependency rewriting
13
12
  * even for projects already using vite-plus. Used by ecosystem CI to
14
13
  * override dependencies with locally built tgz packages.
15
14
  */
16
15
  export function isForceOverrideMode() {
17
- return process.env.VITE_PLUS_FORCE_MIGRATE === '1';
16
+ return process.env.VP_FORCE_MIGRATE === '1';
18
17
  }
19
18
  const require = createRequire(import.meta.url);
20
19
  export function resolve(path) {
@@ -22,9 +22,7 @@ const ZED_SETTINGS = {
22
22
  oxlint: {
23
23
  initialization_options: {
24
24
  settings: {
25
- configPath: './.oxlintrc.json',
26
25
  run: 'onType',
27
- disableNestedConfig: false,
28
26
  fixKind: 'safe_fix',
29
27
  typeAware: true,
30
28
  unusedDisableDirectives: 'deny',
@@ -44,14 +44,14 @@ export async function downloadPackageManager(packageManager, version, interactiv
44
44
  }
45
45
  export async function runViteInstall(cwd, interactive, extraArgs, options) {
46
46
  // install dependencies on non-CI environment
47
- if (process.env.VITE_PLUS_SKIP_INSTALL) {
47
+ if (process.env.VP_SKIP_INSTALL) {
48
48
  return { durationMs: 0, status: 'skipped' };
49
49
  }
50
50
  const spinner = options?.silent ? getSilentSpinner() : getSpinner(interactive);
51
51
  const startTime = Date.now();
52
52
  spinner.start(`Installing dependencies...`);
53
53
  const { exitCode, stderr, stdout } = await runCommandSilently({
54
- command: process.env.VITE_PLUS_CLI_BIN ?? 'vp',
54
+ command: process.env.VP_CLI_BIN ?? 'vp',
55
55
  args: ['install', ...(extraArgs ?? [])],
56
56
  cwd,
57
57
  envs: process.env,
@@ -81,7 +81,7 @@ export async function runViteFmt(cwd, interactive, paths, options) {
81
81
  const startTime = Date.now();
82
82
  spinner.start(`Formatting code...`);
83
83
  const { exitCode, stderr, stdout } = await runCommandSilently({
84
- command: process.env.VITE_PLUS_CLI_BIN ?? 'vp',
84
+ command: process.env.VP_CLI_BIN ?? 'vp',
85
85
  args: ['fmt', '--write', ...(paths ?? [])],
86
86
  cwd,
87
87
  envs: process.env,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ export declare const versions: {
2
+ readonly 'vite': string;
3
+ readonly 'rolldown': string;
4
+ readonly 'tsdown': string;
5
+ readonly 'vitest': string;
6
+ readonly 'oxlint': string;
7
+ readonly 'oxfmt': string;
8
+ readonly 'oxlint-tsgolint': string;
9
+ };
@@ -0,0 +1,9 @@
1
+ export const versions = {
2
+ "vite": "8.0.3",
3
+ "rolldown": "1.0.0-rc.12",
4
+ "tsdown": "0.21.7",
5
+ "vitest": "4.1.2",
6
+ "oxlint": "1.58.0",
7
+ "oxfmt": "0.43.0",
8
+ "oxlint-tsgolint": "0.18.1"
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plus",
3
- "version": "0.1.15-alpha.5",
3
+ "version": "0.1.15-alpha.7",
4
4
  "description": "The Unified Toolchain for the Web",
5
5
  "homepage": "https://viteplus.dev/guide",
6
6
  "bugs": {
@@ -66,6 +66,10 @@
66
66
  "import": "./binding/index.cjs",
67
67
  "require": "./binding/index.cjs"
68
68
  },
69
+ "./fmt": {
70
+ "types": "./dist/fmt.d.ts",
71
+ "import": "./dist/fmt.js"
72
+ },
69
73
  "./lint": {
70
74
  "types": "./dist/lint.d.ts",
71
75
  "import": "./dist/lint.js"
@@ -75,6 +79,10 @@
75
79
  "types": "./dist/pack.d.ts",
76
80
  "import": "./dist/pack.js"
77
81
  },
82
+ "./versions": {
83
+ "types": "./dist/versions.d.ts",
84
+ "default": "./dist/versions.js"
85
+ },
78
86
  "./test": {
79
87
  "import": {
80
88
  "types": "./dist/test/index.d.ts",
@@ -314,12 +322,12 @@
314
322
  "cac": "^7.0.0",
315
323
  "cross-spawn": "^7.0.5",
316
324
  "jsonc-parser": "^3.3.1",
317
- "oxfmt": "=0.42.0",
318
- "oxlint": "=1.57.0",
319
- "oxlint-tsgolint": "=0.17.4",
325
+ "oxfmt": "=0.43.0",
326
+ "oxlint": "=1.58.0",
327
+ "oxlint-tsgolint": "=0.18.1",
320
328
  "picocolors": "^1.1.1",
321
- "@voidzero-dev/vite-plus-test": "0.1.15-alpha.5",
322
- "@voidzero-dev/vite-plus-core": "0.1.15-alpha.5"
329
+ "@voidzero-dev/vite-plus-core": "0.1.15-alpha.7",
330
+ "@voidzero-dev/vite-plus-test": "0.1.15-alpha.7"
323
331
  },
324
332
  "devDependencies": {
325
333
  "@napi-rs/cli": "^3.4.1",
@@ -337,11 +345,11 @@
337
345
  "mri": "^1.2.0",
338
346
  "rolldown-plugin-dts": "^0.22.0",
339
347
  "semver": "^7.7.3",
340
- "tsdown": "^0.21.5",
348
+ "tsdown": "^0.21.7",
341
349
  "validate-npm-package-name": "^7.0.2",
342
350
  "yaml": "^2.8.1",
343
351
  "@voidzero-dev/vite-plus-prompts": "0.0.0",
344
- "vite": "npm:@voidzero-dev/vite-plus-core@0.1.15-alpha.5",
352
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.1.15-alpha.7",
345
353
  "rolldown": "1.0.0-rc.12"
346
354
  },
347
355
  "napi": {
@@ -362,14 +370,14 @@
362
370
  "node": "^20.19.0 || >=22.12.0"
363
371
  },
364
372
  "optionalDependencies": {
365
- "@voidzero-dev/vite-plus-darwin-arm64": "0.1.15-alpha.5",
366
- "@voidzero-dev/vite-plus-darwin-x64": "0.1.15-alpha.5",
367
- "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.1.15-alpha.5",
368
- "@voidzero-dev/vite-plus-linux-arm64-musl": "0.1.15-alpha.5",
369
- "@voidzero-dev/vite-plus-linux-x64-gnu": "0.1.15-alpha.5",
370
- "@voidzero-dev/vite-plus-linux-x64-musl": "0.1.15-alpha.5",
371
- "@voidzero-dev/vite-plus-win32-x64-msvc": "0.1.15-alpha.5",
372
- "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.1.15-alpha.5"
373
+ "@voidzero-dev/vite-plus-darwin-arm64": "0.1.15-alpha.7",
374
+ "@voidzero-dev/vite-plus-darwin-x64": "0.1.15-alpha.7",
375
+ "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.1.15-alpha.7",
376
+ "@voidzero-dev/vite-plus-linux-arm64-musl": "0.1.15-alpha.7",
377
+ "@voidzero-dev/vite-plus-linux-x64-gnu": "0.1.15-alpha.7",
378
+ "@voidzero-dev/vite-plus-linux-x64-musl": "0.1.15-alpha.7",
379
+ "@voidzero-dev/vite-plus-win32-x64-msvc": "0.1.15-alpha.7",
380
+ "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.1.15-alpha.7"
373
381
  },
374
382
  "scripts": {
375
383
  "build": "oxnode -C dev ./build.ts",
@@ -171,7 +171,7 @@ A set of common environment variables are automatically passed through to all ta
171
171
 
172
172
  ### `input`
173
173
 
174
- - **Type:** `Array<string | { auto: boolean }>`
174
+ - **Type:** `Array<string | { auto: boolean } | { pattern: string, base: "workspace" | "package" }>`
175
175
  - **Default:** `[{ auto: true }]` (auto-inferred)
176
176
 
177
177
  Vite Task automatically detects which files are used by a command (see [Automatic File Tracking](/guide/cache#automatic-file-tracking)). The `input` option can be used to explicitly include or exclude certain files.
@@ -199,6 +199,24 @@ tasks: {
199
199
  }
200
200
  ```
201
201
 
202
+ **Resolve patterns relative to the workspace root** using the object form:
203
+
204
+ ```ts
205
+ tasks: {
206
+ build: {
207
+ command: 'vp build',
208
+ input: [
209
+ { auto: true },
210
+ { pattern: 'shared-config/**', base: 'workspace' },
211
+ ],
212
+ },
213
+ }
214
+ ```
215
+
216
+ The `base` field is required and controls how the glob pattern is resolved:
217
+ - `"package"`: relative to the package directory
218
+ - `"workspace"`: relative to the workspace root
219
+
202
220
  **Disable file tracking** entirely and cache only on command/env changes:
203
221
 
204
222
  ```ts
@@ -211,7 +229,7 @@ tasks: {
211
229
  ```
212
230
 
213
231
  ::: tip
214
- Glob patterns are resolved relative to the package directory, not the task's `cwd`.
232
+ String glob patterns are resolved relative to the package directory by default. Use the object form with `base: "workspace"` to resolve relative to the workspace root.
215
233
  :::
216
234
 
217
235
  ### `cwd`
@@ -6,7 +6,7 @@
6
6
 
7
7
  Managed mode is on by default, so `node`, `npm`, and related shims resolve through Vite+ and pick the right Node.js version for the current project.
8
8
 
9
- By default, Vite+ stores its managed runtime and related files in `~/.vite-plus`. If needed, you can override that location with `VITE_PLUS_HOME`.
9
+ By default, Vite+ stores its managed runtime and related files in `~/.vite-plus`. If needed, you can override that location with `VP_HOME`.
10
10
 
11
11
  If you want to keep that behavior, run:
12
12
 
@@ -28,7 +28,7 @@ This switches to system-first mode, where the shims prefer your system Node.js a
28
28
 
29
29
  ### Setup
30
30
 
31
- - `vp env setup` creates or updates shims in `VITE_PLUS_HOME/bin`
31
+ - `vp env setup` creates or updates shims in `VP_HOME/bin`
32
32
  - `vp env on` enables managed mode so shims always use Vite+-managed Node.js
33
33
  - `vp env off` enables system-first mode so shims prefer system Node.js first
34
34
  - `vp env print` prints the shell snippet for the current session
@@ -287,6 +287,34 @@ Use `--last-details` to show the summary from the last run without running tasks
287
287
  vp run --last-details
288
288
  ```
289
289
 
290
+ ## Concurrency
291
+
292
+ By default, up to 4 tasks run at the same time. Use `--concurrency-limit` to change this:
293
+
294
+ ```bash
295
+ # Run up to 8 tasks at once
296
+ vp run -r --concurrency-limit 8 build
297
+
298
+ # Run tasks one at a time
299
+ vp run -r --concurrency-limit 1 build
300
+ ```
301
+
302
+ The limit can also be set via the `VP_RUN_CONCURRENCY_LIMIT` environment variable. The `--concurrency-limit` flag takes priority over the environment variable.
303
+
304
+ ### Parallel Mode
305
+
306
+ Use `--parallel` to ignore task dependencies and run all tasks at once with unlimited concurrency:
307
+
308
+ ```bash
309
+ vp run -r --parallel dev
310
+ ```
311
+
312
+ This is useful when tasks are independent and you want maximum throughput. You can combine `--parallel` with `--concurrency-limit` to run tasks without dependency ordering but still cap the number of concurrent tasks:
313
+
314
+ ```bash
315
+ vp run -r --parallel --concurrency-limit 4 dev
316
+ ```
317
+
290
318
  ## Additional Arguments
291
319
 
292
320
  Arguments after the task name are passed through to the task command:
@@ -2,6 +2,6 @@
2
2
 
3
3
  import { runTemplateCLI } from 'bingo';
4
4
 
5
- import template from '../src/template.ts';
5
+ import template from '../src/template.js';
6
6
 
7
7
  process.exitCode = await runTemplateCLI(template);
@@ -1,3 +1,7 @@
1
- import { defineConfig } from 'vite';
1
+ import { defineConfig } from 'vite-plus';
2
2
 
3
- export default defineConfig({});
3
+ export default defineConfig({
4
+ run: {
5
+ cache: true,
6
+ },
7
+ });