vite-plus 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -0
- package/LICENSE +5 -1
- package/README.md +9 -3
- package/bin/vpr +3 -2
- package/binding/index.cjs +193 -80
- package/binding/index.d.cts +106 -11
- package/dist/agent-DQU8uS6P.js +416 -0
- package/dist/bin.js +1388 -23
- package/dist/{cli-truncate-BVOlIIPy.js → cli-truncate-Bg3RDXpi.js} +0 -2
- package/dist/client/bundledDevClient.mjs +1 -0
- package/dist/config/bin.js +32 -133
- package/dist/{constants-BsuzPowC.js → constants-CG513DRa.js} +10 -2
- package/dist/create/bin.js +255 -268
- package/dist/{define-config-C2KfLHpC.js → define-config-CV4bQG_8.js} +3 -3
- package/dist/{define-config-eLQH9us2.d.ts → define-config-DWoAkNdp.d.ts} +16 -0
- package/dist/{define-config-DLh9fE95.cjs → define-config-DyNLA_f0.cjs} +1 -1
- package/dist/define-config.cjs +1 -1
- package/dist/define-config.d.ts +1 -1
- package/dist/define-config.js +1 -1
- package/dist/{dist-CKz3vcoG.js → dist-BDYZP12R.js} +196 -157
- package/dist/dist-Dqv1-Clg.js +3 -0
- package/dist/{agent-CPwWJ4qf.js → editor-g4PosU99.js} +819 -628
- package/dist/hooks/bin.d.ts +1 -0
- package/dist/hooks/bin.js +130 -0
- package/dist/hooks-pNCBWtFT.js +570 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{json-DiRs8ceZ.js → json-qlK6UH0r.js} +40 -38
- package/dist/migration/bin.js +65 -58
- package/dist/{oxlint-plugin-config-Bxgc4cwF.js → oxlint-plugin-config-BEZ9IUf7.js} +1 -1
- package/dist/oxlint-plugin.js +1 -1
- package/dist/pack-bin.js +1 -1
- package/dist/{package-Ds3uThLb.js → package-B4T8RGMG.js} +2 -2
- package/dist/{tsconfig-Jia2vgMG.js → prompts-CHz_98bJ.js} +169 -219
- package/dist/{resolve-vite-config-BiuLZnn8.js → resolve-vite-config-Dmeyeyj-.js} +2 -9
- package/dist/{rolldown-runtime-C7HZzL1F.js → rolldown-runtime-CMFfr-1z.js} +1 -1
- package/dist/staged/bin.js +241 -226
- package/dist/terminal-Bz-ps6rJ.js +128 -0
- package/dist/test/browser/providers/playwright/context.d.ts +1 -1
- package/dist/test/browser/providers/playwright.d.ts +6 -6
- package/dist/test/browser/providers/preview/context.d.ts +1 -1
- package/dist/test/browser/providers/preview.d.ts +4 -4
- package/dist/test/browser/providers/webdriverio/context.d.ts +1 -1
- package/dist/test/browser/providers/webdriverio.d.ts +6 -6
- package/dist/test/browser-playwright/context.d.ts +1 -1
- package/dist/test/browser-playwright.d.ts +6 -6
- package/dist/test/browser-preview/context.d.ts +1 -1
- package/dist/test/browser-preview.d.ts +4 -4
- package/dist/test/browser-webdriverio/context.d.ts +1 -1
- package/dist/test/browser-webdriverio.d.ts +6 -6
- package/dist/test/context.d.ts +3 -3
- package/dist/test/locators.d.ts +1 -1
- package/dist/toolchain.d.ts +25 -0
- package/dist/toolchain.js +194 -0
- package/dist/toolchain.json +193 -0
- package/dist/tsconfig-7v_BHagU.js +151 -0
- package/dist/{tsgolint-path-B-yOos8p.js → tsgolint-path-CbDReEOx.js} +5 -3
- package/dist/tsgolint-path.js +1 -1
- package/dist/version.js +6 -6
- package/dist/versions.d.ts +3 -3
- package/dist/versions.js +6 -6
- package/docs/config/index.md +13 -0
- package/docs/config/staged.md +2 -1
- package/docs/guide/ci.md +37 -4
- package/docs/guide/commit-hooks.md +112 -21
- package/docs/guide/create.md +7 -4
- package/docs/guide/env.md +8 -4
- package/docs/guide/fmt.md +2 -2
- package/docs/guide/github-actions-cache.md +5 -1
- package/docs/guide/ide-integration.md +61 -2
- package/docs/guide/index.md +4 -2
- package/docs/guide/install.md +27 -0
- package/docs/guide/installer-env-vars.md +14 -3
- package/docs/guide/lint.md +3 -1
- package/docs/guide/migrate.md +49 -4
- package/docs/guide/monorepo.md +98 -10
- package/docs/guide/troubleshooting.md +12 -3
- package/docs/guide/upgrade.md +27 -4
- package/docs/package.json +1 -1
- package/docs/pnpm-workspace.yaml +7 -0
- package/docs/vite.config.ts +3 -0
- package/package.json +21 -23
- package/rules/vite-tools.yml +0 -7
- package/dist/dist-CtM2JRbM.js +0 -3
- package/dist/editor-BbT1lTNc.js +0 -675
- package/dist/help-YP84FSEz.js +0 -61
- package/dist/terminal-uTv0ZaMr.js +0 -33
- package/dist/{log-update-DHZRyJ2m.js → log-update-CoW8Z4Dl.js} +1 -1
|
@@ -1,40 +1,27 @@
|
|
|
1
|
-
import { r as __toESM } from "./rolldown-runtime-
|
|
2
|
-
import { a as VITEST_AGE_GATE_EXEMPT_PACKAGES, c as
|
|
3
|
-
import { i as ensureVitePlusImportRuleDefaults, r as createDefaultVitePlusLintConfig } from "./oxlint-plugin-config-
|
|
4
|
-
import {
|
|
5
|
-
import { a as writeJsonFile, i as readJsonFile, n as editJsonFile, r as isJsonFile } from "./json-
|
|
6
|
-
import { t as require_dist } from "./dist-
|
|
7
|
-
import { n as
|
|
1
|
+
import { r as __toESM } from "./rolldown-runtime-CMFfr-1z.js";
|
|
2
|
+
import { a as VITEST_AGE_GATE_EXEMPT_PACKAGES, c as VITE_PLUS_NAME, f as isForceOverrideMode, l as VITE_PLUS_OVERRIDE_PACKAGES, n as BASEURL_TSCONFIG_WARNING, o as VITEST_VERSION, s as VITE_CONFIG_FILES, u as VITE_PLUS_VERSION } from "./constants-CG513DRa.js";
|
|
3
|
+
import { i as ensureVitePlusImportRuleDefaults, r as createDefaultVitePlusLintConfig } from "./oxlint-plugin-config-BEZ9IUf7.js";
|
|
4
|
+
import { A as isCancel, C as log, E as select, M as runCommandSilently, N as require_cross_spawn, _ as getSpinner, b as require_semver, d as readYamlFile, f as scalarString, g as getSilentSpinner, t as cancelAndExit, u as editYamlFile, w as multiselect, x as confirm, y as PackageManager } from "./prompts-CHz_98bJ.js";
|
|
5
|
+
import { a as writeJsonFile, c as parse, i as readJsonFile, n as editJsonFile, o as applyEdits, r as isJsonFile, s as modify, t as detectFormattingOptions } from "./json-qlK6UH0r.js";
|
|
6
|
+
import { t as require_dist } from "./dist-BDYZP12R.js";
|
|
7
|
+
import { a as hasTypesToRewriteInTsconfig, c as rewriteTypesInTsconfig, i as hasBaseUrlInTsconfig, n as findTsconfigFiles, o as hasVitestTypesInTsconfig, s as removeDeprecatedTsconfigFalseOption } from "./tsconfig-7v_BHagU.js";
|
|
8
|
+
import { n as detectPackageMetadata, r as getScopeFromPackageName } from "./package-B4T8RGMG.js";
|
|
9
|
+
import { l as displayRelative, u as rulesDir } from "./agent-DQU8uS6P.js";
|
|
8
10
|
import { n as addMigrationWarning, t as addManualStep } from "./report-BS7ULx7A.js";
|
|
11
|
+
import { a as findUnsafeHookInstallPath, n as SUPPORTED_GIT_HOOK_NAMES } from "./hooks-pNCBWtFT.js";
|
|
9
12
|
import path, { posix, win32 } from "node:path";
|
|
10
|
-
import {
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { detectWorkspace, hasConfigKey, mergeJsonConfig, mergeTsdownConfig, rewriteEslint, rewriteImportsInDirectory, rewritePrettier, rewriteScripts, wrapLazyPlugins } from "../binding/index.js";
|
|
15
|
+
import { styleText } from "node:util";
|
|
11
16
|
import * as actualFS from "node:fs";
|
|
12
17
|
import fs from "node:fs";
|
|
13
|
-
import { lstatSync, readdir, readdirSync, readlinkSync, realpathSync as realpathSync$1 } from "fs";
|
|
14
|
-
import { styleText } from "node:util";
|
|
15
|
-
import { fileURLToPath } from "node:url";
|
|
16
18
|
import os from "node:os";
|
|
19
|
+
import { lstatSync as lstatSync$1, readdir, readdirSync as readdirSync$1, readlinkSync, realpathSync as realpathSync$1 } from "fs";
|
|
17
20
|
import "oxlint";
|
|
18
21
|
import fsPromises, { lstat, readdir as readdir$1, readlink, realpath } from "node:fs/promises";
|
|
19
22
|
import { EventEmitter } from "node:events";
|
|
20
23
|
import Stream from "node:stream";
|
|
21
24
|
import { StringDecoder } from "node:string_decoder";
|
|
22
|
-
//#region src/utils/path.ts
|
|
23
|
-
function findPkgRoot() {
|
|
24
|
-
let dir = import.meta.dirname;
|
|
25
|
-
while (dir !== path.dirname(dir)) {
|
|
26
|
-
if (fs.existsSync(path.join(dir, "package.json"))) return dir;
|
|
27
|
-
dir = path.dirname(dir);
|
|
28
|
-
}
|
|
29
|
-
return dir;
|
|
30
|
-
}
|
|
31
|
-
const pkgRoot = findPkgRoot();
|
|
32
|
-
const templatesDir = path.join(pkgRoot, "templates");
|
|
33
|
-
const rulesDir = path.join(pkgRoot, "rules");
|
|
34
|
-
function displayRelative(to, from = process.cwd()) {
|
|
35
|
-
return path.relative(from, to).replaceAll("\\", "/");
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
25
|
//#region src/migration/migrator/shared.ts
|
|
39
26
|
var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
|
|
40
27
|
const LINT_STAGED_JSON_CONFIG_FILES = [".lintstagedrc.json", ".lintstagedrc"];
|
|
@@ -167,14 +154,7 @@ const PRETTIER_CONFIG_FILES = [
|
|
|
167
154
|
];
|
|
168
155
|
function detectConfigs(projectPath) {
|
|
169
156
|
const configs = {};
|
|
170
|
-
for (const config of
|
|
171
|
-
"vite.config.ts",
|
|
172
|
-
"vite.config.mts",
|
|
173
|
-
"vite.config.cts",
|
|
174
|
-
"vite.config.js",
|
|
175
|
-
"vite.config.mjs",
|
|
176
|
-
"vite.config.cjs"
|
|
177
|
-
]) if (fs.existsSync(path.join(projectPath, config))) {
|
|
157
|
+
for (const config of VITE_CONFIG_FILES) if (fs.existsSync(path.join(projectPath, config))) {
|
|
178
158
|
configs.viteConfig = config;
|
|
179
159
|
break;
|
|
180
160
|
}
|
|
@@ -322,17 +302,7 @@ async function runOxlintMigrateStep(vpBin, cwd, migratePackage, args, spinner, f
|
|
|
322
302
|
}
|
|
323
303
|
async function migrateEslintToOxlint(projectPath, interactive, eslintConfigFile, packages, options) {
|
|
324
304
|
const vpBin = process.env.VP_CLI_BIN ?? "vp";
|
|
325
|
-
const spinner = options?.silent ?
|
|
326
|
-
start: () => {},
|
|
327
|
-
stop: () => {},
|
|
328
|
-
pause: () => {},
|
|
329
|
-
resume: () => {},
|
|
330
|
-
cancel: () => {},
|
|
331
|
-
error: () => {},
|
|
332
|
-
clear: () => {},
|
|
333
|
-
message: () => {},
|
|
334
|
-
isCancelled: false
|
|
335
|
-
} : getSpinner(interactive);
|
|
305
|
+
const spinner = options?.silent ? getSilentSpinner() : getSpinner(interactive);
|
|
336
306
|
if (eslintConfigFile) {
|
|
337
307
|
const { versions } = await import("./versions.js");
|
|
338
308
|
const migratePackage = `@oxlint/migrate@${versions.oxlint}`;
|
|
@@ -743,6 +713,174 @@ async function promptEslintMigration(projectPath, interactive, packages) {
|
|
|
743
713
|
return true;
|
|
744
714
|
}
|
|
745
715
|
//#endregion
|
|
716
|
+
//#region src/migration/migrator/prettier.ts
|
|
717
|
+
function detectPrettierProject(projectPath, packages) {
|
|
718
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
719
|
+
if (!fs.existsSync(packageJsonPath)) return { hasDependency: false };
|
|
720
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
721
|
+
let hasDependency = !!(pkg.devDependencies?.prettier || pkg.dependencies?.prettier);
|
|
722
|
+
const configFile = detectConfigs(projectPath).prettierConfig;
|
|
723
|
+
if (!hasDependency && packages) for (const wp of packages) {
|
|
724
|
+
const pkgJsonPath = path.join(projectPath, wp.path, "package.json");
|
|
725
|
+
if (!fs.existsSync(pkgJsonPath)) continue;
|
|
726
|
+
const wpPkg = readJsonFile(pkgJsonPath);
|
|
727
|
+
if (wpPkg.devDependencies?.prettier || wpPkg.dependencies?.prettier) {
|
|
728
|
+
hasDependency = true;
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return {
|
|
733
|
+
hasDependency,
|
|
734
|
+
configFile
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Run `vp fmt --migrate=prettier` step with graceful error handling.
|
|
739
|
+
* Returns true on success, false on failure.
|
|
740
|
+
*/
|
|
741
|
+
async function runPrettierMigrateStep(vpBin, cwd, spinner, failMessage, manualHint) {
|
|
742
|
+
try {
|
|
743
|
+
const result = await runCommandSilently({
|
|
744
|
+
command: vpBin,
|
|
745
|
+
args: ["fmt", "--migrate=prettier"],
|
|
746
|
+
cwd,
|
|
747
|
+
envs: process.env
|
|
748
|
+
});
|
|
749
|
+
if (result.exitCode !== 0) {
|
|
750
|
+
spinner.stop(failMessage);
|
|
751
|
+
const stderr = result.stderr.toString().trim();
|
|
752
|
+
if (stderr) log.warn(`⚠ ${stderr}`);
|
|
753
|
+
log.info(manualHint);
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
return true;
|
|
757
|
+
} catch {
|
|
758
|
+
spinner.stop(failMessage);
|
|
759
|
+
log.info(manualHint);
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
async function migratePrettierToOxfmt(projectPath, interactive, prettierConfigFile, packages, options) {
|
|
764
|
+
const vpBin = process.env.VP_CLI_BIN ?? "vp";
|
|
765
|
+
const spinner = options?.silent ? getSilentSpinner() : getSpinner(interactive);
|
|
766
|
+
if (prettierConfigFile) {
|
|
767
|
+
let tempPrettierConfig;
|
|
768
|
+
if (prettierConfigFile === "package.json#prettier") {
|
|
769
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
770
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
771
|
+
if (pkg.prettier) {
|
|
772
|
+
tempPrettierConfig = path.join(projectPath, ".prettierrc.json");
|
|
773
|
+
fs.writeFileSync(tempPrettierConfig, JSON.stringify(pkg.prettier, null, 2));
|
|
774
|
+
} else return true;
|
|
775
|
+
}
|
|
776
|
+
try {
|
|
777
|
+
spinner.start("Migrating Prettier config to Oxfmt...");
|
|
778
|
+
if (!await runPrettierMigrateStep(vpBin, projectPath, spinner, "Prettier migration failed", "You can run `vp fmt --migrate=prettier` manually later")) return false;
|
|
779
|
+
spinner.stop("Prettier config migrated to .oxfmtrc.json");
|
|
780
|
+
} finally {
|
|
781
|
+
if (tempPrettierConfig) try {
|
|
782
|
+
fs.unlinkSync(tempPrettierConfig);
|
|
783
|
+
} catch {}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (options?.report) options.report.prettierMigrated = true;
|
|
787
|
+
deletePrettierConfigFiles(projectPath, options?.report, options?.silent);
|
|
788
|
+
rewritePrettierPackageJson(path.join(projectPath, "package.json"));
|
|
789
|
+
if (packages) for (const pkg of packages) rewritePrettierPackageJson(path.join(projectPath, pkg.path, "package.json"));
|
|
790
|
+
rewritePrettierLintStagedConfigFiles(projectPath, options?.report);
|
|
791
|
+
const prettierIgnorePath = path.join(projectPath, ".prettierignore");
|
|
792
|
+
if (fs.existsSync(prettierIgnorePath)) warnMigration(`${displayRelative(prettierIgnorePath)} found — Oxfmt supports .prettierignore, but using the \`ignorePatterns\` option is recommended.`, options?.report);
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
function deletePrettierConfigFiles(basePath, report, silent = false) {
|
|
796
|
+
const configs = detectConfigs(basePath);
|
|
797
|
+
if (configs.prettierConfig && configs.prettierConfig !== "package.json#prettier") {
|
|
798
|
+
const configPath = path.join(basePath, configs.prettierConfig);
|
|
799
|
+
if (fs.existsSync(configPath)) {
|
|
800
|
+
fs.unlinkSync(configPath);
|
|
801
|
+
if (report) report.removedConfigCount++;
|
|
802
|
+
if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
for (const file of PRETTIER_CONFIG_FILES) {
|
|
806
|
+
if (file === configs.prettierConfig) continue;
|
|
807
|
+
const configPath = path.join(basePath, file);
|
|
808
|
+
if (fs.existsSync(configPath)) {
|
|
809
|
+
fs.unlinkSync(configPath);
|
|
810
|
+
if (report) report.removedConfigCount++;
|
|
811
|
+
if (!silent) log.success(`✔ Removed ${displayRelative(configPath)}`);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
editJsonFile(path.join(basePath, "package.json"), (pkg) => {
|
|
815
|
+
if (pkg.prettier) {
|
|
816
|
+
delete pkg.prettier;
|
|
817
|
+
return pkg;
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
function rewritePrettierPackageJson(packageJsonPath) {
|
|
822
|
+
if (!fs.existsSync(packageJsonPath)) return;
|
|
823
|
+
editJsonFile(packageJsonPath, (pkg) => {
|
|
824
|
+
let changed = false;
|
|
825
|
+
if (pkg.devDependencies) {
|
|
826
|
+
for (const dep of Object.keys(pkg.devDependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
|
|
827
|
+
delete pkg.devDependencies[dep];
|
|
828
|
+
changed = true;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (pkg.dependencies) {
|
|
832
|
+
for (const dep of Object.keys(pkg.dependencies)) if (dep === "prettier" || dep.startsWith("prettier-plugin-")) {
|
|
833
|
+
delete pkg.dependencies[dep];
|
|
834
|
+
changed = true;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
if (pkg.scripts) {
|
|
838
|
+
const updated = rewritePrettier(JSON.stringify(pkg.scripts));
|
|
839
|
+
if (updated) {
|
|
840
|
+
pkg.scripts = JSON.parse(updated);
|
|
841
|
+
changed = true;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
if (pkg["lint-staged"]) {
|
|
845
|
+
const updated = rewritePrettier(JSON.stringify(pkg["lint-staged"]));
|
|
846
|
+
if (updated) {
|
|
847
|
+
pkg["lint-staged"] = JSON.parse(updated);
|
|
848
|
+
changed = true;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
return changed ? pkg : void 0;
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
function rewritePrettierLintStagedConfigFiles(projectPath, report) {
|
|
855
|
+
rewriteToolLintStagedConfigFiles(projectPath, rewritePrettier, "prettier", report);
|
|
856
|
+
}
|
|
857
|
+
function warnPackageLevelPrettier() {
|
|
858
|
+
log.warn("Prettier detected in workspace packages but no root config found. Package-level Prettier must be migrated manually.");
|
|
859
|
+
}
|
|
860
|
+
async function confirmPrettierMigration(interactive) {
|
|
861
|
+
if (interactive) {
|
|
862
|
+
const confirmed = await confirm({
|
|
863
|
+
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."),
|
|
864
|
+
initialValue: true
|
|
865
|
+
});
|
|
866
|
+
if (isCancel(confirmed)) cancelAndExit();
|
|
867
|
+
return confirmed;
|
|
868
|
+
}
|
|
869
|
+
log.info("Prettier configuration detected. Auto-migrating to Oxfmt...");
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
async function promptPrettierMigration(projectPath, interactive, packages) {
|
|
873
|
+
const prettierProject = detectPrettierProject(projectPath, packages);
|
|
874
|
+
if (!prettierProject.hasDependency) return false;
|
|
875
|
+
if (!prettierProject.configFile) {
|
|
876
|
+
warnPackageLevelPrettier();
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
if (!await confirmPrettierMigration(interactive)) return false;
|
|
880
|
+
if (!await migratePrettierToOxfmt(projectPath, interactive, prettierProject.configFile, packages)) cancelAndExit("Prettier migration failed.", 1);
|
|
881
|
+
return true;
|
|
882
|
+
}
|
|
883
|
+
//#endregion
|
|
746
884
|
//#region src/migration/migrator/tsconfig.ts
|
|
747
885
|
function cleanupDeprecatedTsconfigOptions(projectPath, silent = false, report) {
|
|
748
886
|
const deprecatedOptions = ["esModuleInterop", "allowSyntheticDefaultImports"];
|
|
@@ -767,6 +905,66 @@ function hasTsconfigTypesToRewrite(projectPath) {
|
|
|
767
905
|
return findTsconfigFiles(projectPath).some((filePath) => hasTypesToRewriteInTsconfig(filePath));
|
|
768
906
|
}
|
|
769
907
|
//#endregion
|
|
908
|
+
//#region src/migration/migrator/framework-shim.ts
|
|
909
|
+
const FRAMEWORK_SHIMS = {
|
|
910
|
+
vue: [
|
|
911
|
+
"declare module '*.vue' {",
|
|
912
|
+
" import type { DefineComponent } from 'vue';",
|
|
913
|
+
" const component: DefineComponent<{}, {}, unknown>;",
|
|
914
|
+
" export default component;",
|
|
915
|
+
"}"
|
|
916
|
+
].join("\n"),
|
|
917
|
+
astro: "/// <reference types=\"astro/client\" />"
|
|
918
|
+
};
|
|
919
|
+
function detectFramework(projectPath) {
|
|
920
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
921
|
+
if (!fs.existsSync(packageJsonPath)) return [];
|
|
922
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
923
|
+
const allDeps = {
|
|
924
|
+
...pkg.dependencies,
|
|
925
|
+
...pkg.devDependencies
|
|
926
|
+
};
|
|
927
|
+
return ["vue", "astro"].filter((framework) => !!allDeps[framework]);
|
|
928
|
+
}
|
|
929
|
+
function getEnvDtsPath(projectPath) {
|
|
930
|
+
const srcEnvDts = path.join(projectPath, "src", "env.d.ts");
|
|
931
|
+
const rootEnvDts = path.join(projectPath, "env.d.ts");
|
|
932
|
+
for (const candidate of [srcEnvDts, rootEnvDts]) if (fs.existsSync(candidate)) return candidate;
|
|
933
|
+
return fs.existsSync(path.join(projectPath, "src")) ? srcEnvDts : rootEnvDts;
|
|
934
|
+
}
|
|
935
|
+
function hasFrameworkShim(projectPath, framework) {
|
|
936
|
+
const dirsToScan = [projectPath, path.join(projectPath, "src")];
|
|
937
|
+
for (const dir of dirsToScan) {
|
|
938
|
+
if (!fs.existsSync(dir)) continue;
|
|
939
|
+
let entries;
|
|
940
|
+
try {
|
|
941
|
+
entries = fs.readdirSync(dir);
|
|
942
|
+
} catch {
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
for (const entry of entries) {
|
|
946
|
+
if (!entry.endsWith(".d.ts")) continue;
|
|
947
|
+
const content = fs.readFileSync(path.join(dir, entry), "utf-8");
|
|
948
|
+
if (framework === "astro") {
|
|
949
|
+
if (content.includes("astro/client")) return true;
|
|
950
|
+
} else if (content.includes(`'*.${framework}'`) || content.includes(`"*.${framework}"`)) return true;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
function addFrameworkShim(projectPath, framework, report) {
|
|
956
|
+
const envDtsPath = getEnvDtsPath(projectPath);
|
|
957
|
+
const shim = FRAMEWORK_SHIMS[framework];
|
|
958
|
+
if (fs.existsSync(envDtsPath)) {
|
|
959
|
+
const existing = fs.readFileSync(envDtsPath, "utf-8");
|
|
960
|
+
fs.writeFileSync(envDtsPath, `${existing.trimEnd()}\n\n${shim}\n`, "utf-8");
|
|
961
|
+
} else {
|
|
962
|
+
fs.mkdirSync(path.dirname(envDtsPath), { recursive: true });
|
|
963
|
+
fs.writeFileSync(envDtsPath, `${shim}\n`, "utf-8");
|
|
964
|
+
}
|
|
965
|
+
if (report) report.frameworkShimAdded = true;
|
|
966
|
+
}
|
|
967
|
+
//#endregion
|
|
770
968
|
//#region src/migration/migrator/vitest-ecosystem.ts
|
|
771
969
|
var import_dist = require_dist();
|
|
772
970
|
const VITEST_ALIGN_EXCLUDED = /* @__PURE__ */ new Set(["@vitest/eslint-plugin", "@vitest/coverage-c8"]);
|
|
@@ -1251,7 +1449,7 @@ function expand_(str, max, isTop) {
|
|
|
1251
1449
|
}
|
|
1252
1450
|
//#endregion
|
|
1253
1451
|
//#region ../../node_modules/.pnpm/minimatch@10.2.4/node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
1254
|
-
const MAX_PATTERN_LENGTH =
|
|
1452
|
+
const MAX_PATTERN_LENGTH = 65536;
|
|
1255
1453
|
const assertValidPattern = (pattern) => {
|
|
1256
1454
|
if (typeof pattern !== "string") throw new TypeError("invalid pattern");
|
|
1257
1455
|
if (pattern.length > MAX_PATTERN_LENGTH) throw new TypeError("pattern is too long");
|
|
@@ -2487,9 +2685,10 @@ var Minimatch = class {
|
|
|
2487
2685
|
const next = pp[i + 1];
|
|
2488
2686
|
const prev = pp[i - 1];
|
|
2489
2687
|
if (p !== GLOBSTAR || prev === GLOBSTAR) return;
|
|
2490
|
-
if (prev === void 0)
|
|
2491
|
-
|
|
2492
|
-
|
|
2688
|
+
if (prev === void 0) {
|
|
2689
|
+
if (next !== void 0 && next !== GLOBSTAR) pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next;
|
|
2690
|
+
else pp[i] = twoStar;
|
|
2691
|
+
} else if (next === void 0) pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
|
|
2493
2692
|
else if (next !== GLOBSTAR) {
|
|
2494
2693
|
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
|
|
2495
2694
|
pp[i + 1] = GLOBSTAR;
|
|
@@ -2556,7 +2755,6 @@ minimatch.escape = escape;
|
|
|
2556
2755
|
minimatch.unescape = unescape;
|
|
2557
2756
|
//#endregion
|
|
2558
2757
|
//#region ../../node_modules/.pnpm/lru-cache@11.2.7/node_modules/lru-cache/dist/esm/index.min.js
|
|
2559
|
-
var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
|
|
2560
2758
|
var x = typeof performance == "object" && performance && typeof performance.now == "function" ? performance : Date;
|
|
2561
2759
|
var I = /* @__PURE__ */ new Set();
|
|
2562
2760
|
var R = typeof process == "object" && process ? process : {};
|
|
@@ -2748,7 +2946,7 @@ var L = class c {
|
|
|
2748
2946
|
}
|
|
2749
2947
|
}
|
|
2750
2948
|
getRemainingTTL(t) {
|
|
2751
|
-
return this.#s.has(t) ?
|
|
2949
|
+
return this.#s.has(t) ? 1 / 0 : 0;
|
|
2752
2950
|
}
|
|
2753
2951
|
#j() {
|
|
2754
2952
|
let t = new z(this.#o), e = new z(this.#o);
|
|
@@ -2788,7 +2986,7 @@ var L = class c {
|
|
|
2788
2986
|
let r = this.#s.get(h);
|
|
2789
2987
|
if (r === void 0) return 0;
|
|
2790
2988
|
let a = t[r], w = e[r];
|
|
2791
|
-
if (!a || !w) return
|
|
2989
|
+
if (!a || !w) return 1 / 0;
|
|
2792
2990
|
return a - ((n || o()) - w);
|
|
2793
2991
|
}, this.#p = (h) => {
|
|
2794
2992
|
let r = e[h], a = t[h];
|
|
@@ -3982,12 +4180,15 @@ while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length);
|
|
|
3982
4180
|
return isStream;
|
|
3983
4181
|
}
|
|
3984
4182
|
};
|
|
4183
|
+
//#endregion
|
|
4184
|
+
//#region ../../node_modules/.pnpm/path-scurry@2.0.1/node_modules/path-scurry/dist/esm/index.js
|
|
4185
|
+
const realpathSync$2 = realpathSync$1.native;
|
|
3985
4186
|
const defaultFS = {
|
|
3986
|
-
lstatSync,
|
|
4187
|
+
lstatSync: lstatSync$1,
|
|
3987
4188
|
readdir,
|
|
3988
|
-
readdirSync,
|
|
4189
|
+
readdirSync: readdirSync$1,
|
|
3989
4190
|
readlinkSync,
|
|
3990
|
-
realpathSync: realpathSync$
|
|
4191
|
+
realpathSync: realpathSync$2,
|
|
3991
4192
|
promises: {
|
|
3992
4193
|
lstat,
|
|
3993
4194
|
readdir: readdir$1,
|
|
@@ -4025,7 +4226,7 @@ const ENOREALPATH = 512;
|
|
|
4025
4226
|
const ENOCHILD = 704;
|
|
4026
4227
|
const TYPEMASK = 1023;
|
|
4027
4228
|
const entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
|
|
4028
|
-
const normalizeCache = new L({ max:
|
|
4229
|
+
const normalizeCache = new L({ max: 4096 });
|
|
4029
4230
|
const normalize$1 = (s) => {
|
|
4030
4231
|
const c = normalizeCache.get(s);
|
|
4031
4232
|
if (c) return c;
|
|
@@ -4033,7 +4234,7 @@ const normalize$1 = (s) => {
|
|
|
4033
4234
|
normalizeCache.set(s, n);
|
|
4034
4235
|
return n;
|
|
4035
4236
|
};
|
|
4036
|
-
const normalizeNocaseCache = new L({ max:
|
|
4237
|
+
const normalizeNocaseCache = new L({ max: 4096 });
|
|
4037
4238
|
const normalizeNocase = (s) => {
|
|
4038
4239
|
const c = normalizeNocaseCache.get(s);
|
|
4039
4240
|
if (c) return c;
|
|
@@ -4055,7 +4256,7 @@ var ResolveCache = class extends L {
|
|
|
4055
4256
|
* @internal
|
|
4056
4257
|
*/
|
|
4057
4258
|
var ChildrenCache = class extends L {
|
|
4058
|
-
constructor(maxSize =
|
|
4259
|
+
constructor(maxSize = 16384) {
|
|
4059
4260
|
super({
|
|
4060
4261
|
maxSize,
|
|
4061
4262
|
sizeCalculation: (a) => a.length + 1
|
|
@@ -4388,7 +4589,7 @@ var PathBase = class {
|
|
|
4388
4589
|
return this[`is${type}`]();
|
|
4389
4590
|
}
|
|
4390
4591
|
getType() {
|
|
4391
|
-
return this.isUnknown() ? "Unknown" : this.isDirectory() ? "Directory" : this.isFile() ? "File" : this.isSymbolicLink() ? "SymbolicLink" : this.isFIFO() ? "FIFO" : this.isCharacterDevice() ? "CharacterDevice" : this.isBlockDevice() ? "BlockDevice" :
|
|
4592
|
+
return this.isUnknown() ? "Unknown" : this.isDirectory() ? "Directory" : this.isFile() ? "File" : this.isSymbolicLink() ? "SymbolicLink" : this.isFIFO() ? "FIFO" : this.isCharacterDevice() ? "CharacterDevice" : this.isBlockDevice() ? "BlockDevice" : /* c8 ignore start */ this.isSocket() ? "Socket" : "Unknown";
|
|
4392
4593
|
/* c8 ignore stop */
|
|
4393
4594
|
}
|
|
4394
4595
|
/**
|
|
@@ -5013,7 +5214,7 @@ var PathScurryBase = class {
|
|
|
5013
5214
|
*
|
|
5014
5215
|
* @internal
|
|
5015
5216
|
*/
|
|
5016
|
-
constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize =
|
|
5217
|
+
constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize = 16384, fs = defaultFS } = {}) {
|
|
5017
5218
|
this.#fs = fsFromOption(fs);
|
|
5018
5219
|
if (cwd instanceof URL || cwd.startsWith("file://")) cwd = fileURLToPath(cwd);
|
|
5019
5220
|
const cwdPath = pathImpl.resolve(cwd);
|
|
@@ -5753,8 +5954,10 @@ var Ignore = class {
|
|
|
5753
5954
|
const absolute = p.isAbsolute();
|
|
5754
5955
|
if (absolute) this.absolute.push(m);
|
|
5755
5956
|
else this.relative.push(m);
|
|
5756
|
-
if (children)
|
|
5757
|
-
|
|
5957
|
+
if (children) {
|
|
5958
|
+
if (absolute) this.absoluteChildren.push(m);
|
|
5959
|
+
else this.relativeChildren.push(m);
|
|
5960
|
+
}
|
|
5758
5961
|
}
|
|
5759
5962
|
}
|
|
5760
5963
|
ignored(p) {
|
|
@@ -6504,6 +6707,96 @@ const glob = Object.assign(glob_, {
|
|
|
6504
6707
|
});
|
|
6505
6708
|
glob.glob = glob;
|
|
6506
6709
|
//#endregion
|
|
6710
|
+
//#region src/utils/workspace.ts
|
|
6711
|
+
async function detectWorkspace$1(rootDir) {
|
|
6712
|
+
const bindingResult = await detectWorkspace(rootDir);
|
|
6713
|
+
const result = {
|
|
6714
|
+
rootDir,
|
|
6715
|
+
packageManager: void 0,
|
|
6716
|
+
packageManagerVersion: "latest",
|
|
6717
|
+
isMonorepo: false,
|
|
6718
|
+
monorepoScope: "",
|
|
6719
|
+
workspacePatterns: [],
|
|
6720
|
+
parentDirs: [],
|
|
6721
|
+
packages: []
|
|
6722
|
+
};
|
|
6723
|
+
if (bindingResult.packageManagerName) result.packageManager = bindingResult.packageManagerName;
|
|
6724
|
+
if (bindingResult.packageManagerVersion) result.packageManagerVersion = bindingResult.packageManagerVersion;
|
|
6725
|
+
if (bindingResult.isMonorepo) result.isMonorepo = bindingResult.isMonorepo;
|
|
6726
|
+
if (bindingResult.root) result.rootDir = bindingResult.root;
|
|
6727
|
+
if (result.isMonorepo) {
|
|
6728
|
+
const pnpmWorkspaceFile = path.join(result.rootDir, "pnpm-workspace.yaml");
|
|
6729
|
+
const packageJsonFile = path.join(result.rootDir, "package.json");
|
|
6730
|
+
if (fs.existsSync(pnpmWorkspaceFile)) {
|
|
6731
|
+
const workspaceConfig = readYamlFile(pnpmWorkspaceFile);
|
|
6732
|
+
if (Array.isArray(workspaceConfig.packages)) result.workspacePatterns = workspaceConfig.packages;
|
|
6733
|
+
} else if (fs.existsSync(packageJsonFile)) {
|
|
6734
|
+
const pkg = readJsonFile(packageJsonFile);
|
|
6735
|
+
if (Array.isArray(pkg.workspaces)) result.workspacePatterns = pkg.workspaces;
|
|
6736
|
+
else if (pkg.workspaces && Array.isArray(pkg.workspaces.packages)) result.workspacePatterns = pkg.workspaces.packages;
|
|
6737
|
+
}
|
|
6738
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
6739
|
+
for (const pattern of result.workspacePatterns) {
|
|
6740
|
+
if (!pattern.endsWith("*")) continue;
|
|
6741
|
+
const dir = pattern.replace(/\/\*{1,2}$/, "");
|
|
6742
|
+
if (dir) dirs.add(dir);
|
|
6743
|
+
}
|
|
6744
|
+
result.parentDirs = Array.from(dirs).sort();
|
|
6745
|
+
const pkg = readJsonFile(packageJsonFile);
|
|
6746
|
+
if (pkg.name) result.monorepoScope = getScopeFromPackageName(pkg.name);
|
|
6747
|
+
result.packages = discoverWorkspacePackages(result.workspacePatterns, result.rootDir);
|
|
6748
|
+
}
|
|
6749
|
+
return result;
|
|
6750
|
+
}
|
|
6751
|
+
function isBingoTemplate(pkg) {
|
|
6752
|
+
return !!pkg.dependencies?.bingo;
|
|
6753
|
+
}
|
|
6754
|
+
function discoverWorkspacePackages(workspacePatterns, rootDir) {
|
|
6755
|
+
const packages = [];
|
|
6756
|
+
if (workspacePatterns.length === 0) return packages;
|
|
6757
|
+
const packageJsonRelativePaths = globSync(workspacePatterns.map((pattern) => `${pattern}/package.json`), {
|
|
6758
|
+
absolute: false,
|
|
6759
|
+
cwd: rootDir,
|
|
6760
|
+
ignore: ["**/node_modules/**"]
|
|
6761
|
+
});
|
|
6762
|
+
for (const packageJsonRelativePath of packageJsonRelativePaths) {
|
|
6763
|
+
const packageJsonPath = path.join(rootDir, packageJsonRelativePath);
|
|
6764
|
+
const pkg = readJsonFile(packageJsonPath);
|
|
6765
|
+
if (!pkg.name) continue;
|
|
6766
|
+
packages.push({
|
|
6767
|
+
name: pkg.name,
|
|
6768
|
+
path: path.dirname(packageJsonRelativePath).split(path.sep).join("/"),
|
|
6769
|
+
description: pkg.description,
|
|
6770
|
+
version: pkg.version
|
|
6771
|
+
});
|
|
6772
|
+
}
|
|
6773
|
+
return packages;
|
|
6774
|
+
}
|
|
6775
|
+
function updatePackageJsonWithDeps(rootDir, projectDir, dependencies, dependencyType) {
|
|
6776
|
+
const packageJsonPath = path.join(rootDir, projectDir, "package.json");
|
|
6777
|
+
editJsonFile(packageJsonPath, (pkg) => {
|
|
6778
|
+
if (!pkg[dependencyType]) pkg[dependencyType] = {};
|
|
6779
|
+
for (const dep of dependencies) pkg[dependencyType][dep] = "workspace:*";
|
|
6780
|
+
return pkg;
|
|
6781
|
+
});
|
|
6782
|
+
}
|
|
6783
|
+
function updateWorkspaceConfig(projectPath, workspaceInfo) {
|
|
6784
|
+
for (const pattern of workspaceInfo.workspacePatterns) if (minimatch(projectPath, pattern)) return;
|
|
6785
|
+
const parentDir = path.dirname(projectPath);
|
|
6786
|
+
const pattern = parentDir === "." ? projectPath : `${parentDir}/*`;
|
|
6787
|
+
if (workspaceInfo.packageManager === PackageManager.pnpm) editYamlFile(path.join(workspaceInfo.rootDir, "pnpm-workspace.yaml"), (doc) => {
|
|
6788
|
+
let packages = doc.getIn(["packages"]);
|
|
6789
|
+
if (!packages) packages = new import_dist.YAMLSeq();
|
|
6790
|
+
packages.add(new import_dist.Scalar(pattern));
|
|
6791
|
+
doc.setIn(["packages"], packages);
|
|
6792
|
+
});
|
|
6793
|
+
else editJsonFile(path.join(workspaceInfo.rootDir, "package.json"), (pkg) => {
|
|
6794
|
+
if (pkg.workspaces && !Array.isArray(pkg.workspaces)) pkg.workspaces.packages = [...pkg.workspaces.packages || [], pattern];
|
|
6795
|
+
else pkg.workspaces = [...pkg.workspaces || [], pattern];
|
|
6796
|
+
return pkg;
|
|
6797
|
+
});
|
|
6798
|
+
}
|
|
6799
|
+
//#endregion
|
|
6507
6800
|
//#region src/migration/migrator/catalog.ts
|
|
6508
6801
|
const BROWSER_PROVIDER_POSTINSTALL_PACKAGES = ["edgedriver", "geckodriver"];
|
|
6509
6802
|
const PUBLIC_PEER_DEPENDENCY_FALLBACKS = {
|
|
@@ -6684,7 +6977,8 @@ function rewritePnpmWorkspaceYaml(projectPath, pnpmMajorVersion, shouldAllowBrow
|
|
|
6684
6977
|
* so all overrides must live in pnpm-workspace.yaml.
|
|
6685
6978
|
*/
|
|
6686
6979
|
function migratePnpmOverridesToWorkspaceYaml(projectPath, overrides) {
|
|
6687
|
-
|
|
6980
|
+
const pnpmWorkspaceYamlPath = path.join(projectPath, "pnpm-workspace.yaml");
|
|
6981
|
+
editYamlFile(pnpmWorkspaceYamlPath, (doc) => {
|
|
6688
6982
|
for (const [key, value] of Object.entries(overrides)) doc.setIn(["overrides", scalarString(key)], scalarString(value));
|
|
6689
6983
|
});
|
|
6690
6984
|
}
|
|
@@ -7801,20 +8095,21 @@ function ensureVitePlusBootstrap(workspaceInfo, report) {
|
|
|
7801
8095
|
});
|
|
7802
8096
|
result.packageJson = result.packageJson || childChanged;
|
|
7803
8097
|
}
|
|
7804
|
-
if (workspaceInfo.packageManager === PackageManager.pnpm)
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
8098
|
+
if (workspaceInfo.packageManager === PackageManager.pnpm) {
|
|
8099
|
+
if (usePnpmWorkspaceYaml) {
|
|
8100
|
+
const before = readTextFileIfExists(pnpmWorkspaceYamlPath);
|
|
8101
|
+
migratePnpmSettingsToWorkspaceYaml(projectPath, movedPnpmSettings);
|
|
8102
|
+
const catalogDependencyResolver = readPnpmWorkspaceCatalogDependencyResolver(projectPath);
|
|
8103
|
+
if (movedPnpmSettings !== void 0 || result.packageJson || ecosystemCatalogReferencesPending || !pnpmWorkspaceExoticSubdepsSettingSatisfied(projectPath) || pnpmWorkspaceMinimumReleaseAgeExemptionsPending(projectPath) || workspaceCatalogVitePlusDependencyPending(projectPath, workspaceInfo.packages, catalogDependencyResolver) || !overridesSatisfyVitePlus(readPnpmWorkspaceOverrides(projectPath), usesVitest, catalogDependencyResolver) || !pnpmPeerDependencyRulesSatisfyVitePlus(readPnpmWorkspacePeerDependencyRules(projectPath), usesVitest)) rewritePnpmWorkspaceYaml(projectPath, pnpmMajorVersion, shouldAllowBrowserBuilds, usesVitest, vitestEcosystemPackages, true, providerCatalogAdditions);
|
|
8104
|
+
if (fs.existsSync(pnpmWorkspaceYamlPath)) ensurePnpmWorkspacePackages(projectPath, workspaceInfo.workspacePatterns);
|
|
8105
|
+
result.packageManagerConfig = before !== readTextFileIfExists(pnpmWorkspaceYamlPath);
|
|
8106
|
+
} else {
|
|
8107
|
+
const exoticChanged = ensurePnpmWorkspaceExoticSubdepsSetting(projectPath);
|
|
8108
|
+
if (fs.existsSync(pnpmWorkspaceYamlPath)) ensurePnpmWorkspacePackages(projectPath, workspaceInfo.workspacePatterns);
|
|
8109
|
+
const after = readTextFileIfExists(pnpmWorkspaceYamlPath);
|
|
8110
|
+
result.packageManagerConfig = exoticChanged || pnpmWorkspaceCatalogBefore !== after;
|
|
8111
|
+
}
|
|
8112
|
+
} else if (workspaceInfo.packageManager === PackageManager.yarn) {
|
|
7818
8113
|
const yarnrcYmlPath = path.join(projectPath, ".yarnrc.yml");
|
|
7819
8114
|
const before = readTextFileIfExists(yarnrcYmlPath);
|
|
7820
8115
|
rewriteYarnrcYml(projectPath, usesVitest, vitestEcosystemPackages, providerCatalogAdditions, supportCatalog);
|
|
@@ -8143,7 +8438,8 @@ function mergeTsdownConfigFile(projectPath, silent = false, report) {
|
|
|
8143
8438
|
mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.tsdownConfig, "pack", silent, report);
|
|
8144
8439
|
return;
|
|
8145
8440
|
}
|
|
8146
|
-
const
|
|
8441
|
+
const tsdownRelativePath = `./${configs.tsdownConfig}`;
|
|
8442
|
+
const result = mergeTsdownConfig(fullViteConfigPath, tsdownRelativePath);
|
|
8147
8443
|
if (result.updated) {
|
|
8148
8444
|
fs.writeFileSync(fullViteConfigPath, result.content);
|
|
8149
8445
|
if (report) report.tsdownImportCount++;
|
|
@@ -8168,7 +8464,8 @@ function mergeViteConfigFiles(projectPath, silent = false, report, packages, wor
|
|
|
8168
8464
|
} else warnMigration(BASEURL_TSCONFIG_WARNING, report);
|
|
8169
8465
|
sanitizeMigratedOxlintConfig(oxlintJson, collectInstalledPackageNames(workspaceRoot ?? projectPath, packages), report);
|
|
8170
8466
|
ensureSvelteRuneGlobals(oxlintJson);
|
|
8171
|
-
|
|
8467
|
+
const normalizedOxlintConfig = ensureVitePlusImportRuleDefaults(oxlintJson);
|
|
8468
|
+
writeJsonFile(fullOxlintPath, normalizedOxlintConfig);
|
|
8172
8469
|
mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.oxlintConfig, "lint", silent, report);
|
|
8173
8470
|
}
|
|
8174
8471
|
if (configs.oxfmtConfig) mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.oxfmtConfig, "fmt", silent, report);
|
|
@@ -8306,107 +8603,114 @@ function rewriteAllImports(projectPath, silent = false, report, preserveNuxtVite
|
|
|
8306
8603
|
log.success(`Rewrote imports in ${modified === 1 ? "one file" : `${modified} files`}`);
|
|
8307
8604
|
log.info(result.modifiedFiles.map((file) => ` ${displayRelative(file)}`).join("\n"));
|
|
8308
8605
|
}
|
|
8309
|
-
if (errors > 0)
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8606
|
+
if (errors > 0) {
|
|
8607
|
+
if (report) warnMigration(`${errors === 1 ? "one file had an error" : `${errors} files had errors`} while rewriting imports`, report);
|
|
8608
|
+
else {
|
|
8609
|
+
log.warn(`⚠ ${errors === 1 ? "one file had an error" : `${errors} files had errors`}:`);
|
|
8610
|
+
for (const error of result.errors) log.error(` ${displayRelative(error.path)}: ${error.message}`);
|
|
8611
|
+
}
|
|
8313
8612
|
}
|
|
8314
8613
|
return modified > 0;
|
|
8315
8614
|
}
|
|
8316
8615
|
//#endregion
|
|
8317
|
-
//#region src/
|
|
8616
|
+
//#region src/utils/git.ts
|
|
8617
|
+
var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
|
|
8318
8618
|
/**
|
|
8319
|
-
*
|
|
8320
|
-
*
|
|
8321
|
-
* When the specifier is a catalog reference (e.g. `"catalog:"`), resolves
|
|
8322
|
-
* it from the active package manager's catalog first — a `catalog:` spec is
|
|
8323
|
-
* only meaningful to the manager that owns the workspace, so we never read a
|
|
8324
|
-
* leftover/foreign catalog file. When it is still not coercible (e.g.
|
|
8325
|
-
* `"latest"`), falls back to the installed version in node_modules via
|
|
8326
|
-
* `detectPackageMetadata`.
|
|
8327
|
-
* Returns a reason string if hooks migration should be skipped, or null
|
|
8328
|
-
* if husky is absent or compatible.
|
|
8619
|
+
* Walk up from `startPath` looking for `.git` (directory or file — submodules
|
|
8620
|
+
* use a `.git` file). Returns the directory that contains `.git`, or `null`.
|
|
8329
8621
|
*/
|
|
8330
|
-
function
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
}
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8622
|
+
function findGitRoot(startPath) {
|
|
8623
|
+
let dir = startPath;
|
|
8624
|
+
while (true) {
|
|
8625
|
+
if (fs.existsSync(path.join(dir, ".git"))) return dir;
|
|
8626
|
+
const parent = path.dirname(dir);
|
|
8627
|
+
if (parent === dir) return null;
|
|
8628
|
+
dir = parent;
|
|
8629
|
+
}
|
|
8630
|
+
}
|
|
8631
|
+
async function initGitRepository(cwd) {
|
|
8632
|
+
return (await runCommandSilently({
|
|
8633
|
+
command: "git",
|
|
8634
|
+
args: ["init"],
|
|
8635
|
+
cwd,
|
|
8636
|
+
envs: process.env
|
|
8637
|
+
})).exitCode === 0;
|
|
8345
8638
|
}
|
|
8639
|
+
//#endregion
|
|
8640
|
+
//#region src/migration/migrator/git-hooks.ts
|
|
8346
8641
|
const OTHER_HOOK_TOOLS = [
|
|
8347
8642
|
"simple-git-hooks",
|
|
8348
8643
|
"lefthook",
|
|
8349
8644
|
"yorkie"
|
|
8350
8645
|
];
|
|
8351
|
-
const
|
|
8352
|
-
function
|
|
8646
|
+
const SUPPORTED_GIT_HOOK_NAME_SET = new Set(SUPPORTED_GIT_HOOK_NAMES);
|
|
8647
|
+
function removeReplacedStagedPackage(packageJsonPath) {
|
|
8353
8648
|
editJsonFile(packageJsonPath, (pkg) => {
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
if (pkg.dependencies?.[name]) delete pkg.dependencies[name];
|
|
8357
|
-
}
|
|
8649
|
+
if (pkg.devDependencies?.["lint-staged"]) delete pkg.devDependencies["lint-staged"];
|
|
8650
|
+
if (pkg.dependencies?.["lint-staged"]) delete pkg.dependencies["lint-staged"];
|
|
8358
8651
|
return pkg;
|
|
8359
8652
|
});
|
|
8360
8653
|
}
|
|
8361
8654
|
function detectLegacyGitHooksMigrationCandidate(projectPath) {
|
|
8362
8655
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
8363
8656
|
if (!fs.existsSync(packageJsonPath)) return false;
|
|
8364
|
-
|
|
8365
|
-
return getOldHooksDir(projectPath) !== void 0 || pkg["lint-staged"] !== void 0;
|
|
8657
|
+
return readJsonFile(packageJsonPath)["lint-staged"] !== void 0;
|
|
8366
8658
|
}
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
* use a `.git` file). Returns the directory that contains `.git`, or `null`.
|
|
8370
|
-
*/
|
|
8371
|
-
function findGitRoot(startPath) {
|
|
8372
|
-
let dir = startPath;
|
|
8373
|
-
while (true) {
|
|
8374
|
-
if (fs.existsSync(path.join(dir, ".git"))) return dir;
|
|
8375
|
-
const parent = path.dirname(dir);
|
|
8376
|
-
if (parent === dir) return null;
|
|
8377
|
-
dir = parent;
|
|
8378
|
-
}
|
|
8659
|
+
function hasHuskySetup(projectPath, pkg) {
|
|
8660
|
+
return pkg.devDependencies?.husky !== void 0 || pkg.dependencies?.husky !== void 0 || pkg.optionalDependencies?.husky !== void 0 || pkg.peerDependencies?.husky !== void 0 || pkg.husky !== void 0 || (pkg.scripts?.prepare ? /\bhusky\b/.test(pkg.scripts.prepare) : false) || fs.existsSync(path.join(projectPath, ".husky"));
|
|
8379
8661
|
}
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
function collapseHuskyInstall(script) {
|
|
8385
|
-
return script.replace("husky install ", "husky ").replace("husky install", "husky");
|
|
8662
|
+
function hasExistingViteHooksPolicy(projectPath) {
|
|
8663
|
+
const hooksDir = path.join(projectPath, ".vite-hooks");
|
|
8664
|
+
if (!fs.lstatSync(hooksDir, { throwIfNoEntry: false })?.isDirectory()) return false;
|
|
8665
|
+
return fs.readdirSync(hooksDir, { withFileTypes: true }).some((entry) => entry.isFile() && SUPPORTED_GIT_HOOK_NAME_SET.has(entry.name));
|
|
8386
8666
|
}
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
if (setupGitHooks(projectPath, getOldHooksDir(projectPath), silent, report, packageManager)) {
|
|
8393
|
-
rewritePrepareScript(projectPath);
|
|
8394
|
-
return true;
|
|
8667
|
+
function findNonRegularViteHookPath(projectPath) {
|
|
8668
|
+
for (const hookName of SUPPORTED_GIT_HOOK_NAMES) {
|
|
8669
|
+
const hookPath = path.join(projectPath, ".vite-hooks", hookName);
|
|
8670
|
+
const stats = fs.lstatSync(hookPath, { throwIfNoEntry: false });
|
|
8671
|
+
if (stats && !stats.isFile()) return path.join(".vite-hooks", hookName);
|
|
8395
8672
|
}
|
|
8396
|
-
return
|
|
8673
|
+
return null;
|
|
8674
|
+
}
|
|
8675
|
+
function findWorkspacePackageHookPolicy(workspaceRoot, packages) {
|
|
8676
|
+
for (const pkg of packages) {
|
|
8677
|
+
const packagePath = path.join(workspaceRoot, pkg.path);
|
|
8678
|
+
if (hasExistingViteHooksPolicy(packagePath)) return `Detected project-owned Vite+ hooks in workspace package "${pkg.path}" — leaving the existing hook setup unchanged.`;
|
|
8679
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
8680
|
+
const pkgContent = fs.existsSync(packageJsonPath) ? readJsonFile(packageJsonPath) : {};
|
|
8681
|
+
if (hasHuskySetup(packagePath, pkgContent)) return `Detected Husky in workspace package "${pkg.path}" — leaving its hooks, configuration, and dependencies unchanged.`;
|
|
8682
|
+
const deps = pkgContent.devDependencies;
|
|
8683
|
+
const prodDeps = pkgContent.dependencies;
|
|
8684
|
+
for (const tool of OTHER_HOOK_TOOLS) if (deps?.[tool] || prodDeps?.[tool] || pkgContent[tool]) return `Detected ${tool} in workspace package "${pkg.path}" — leaving the existing hook setup unchanged.`;
|
|
8685
|
+
const gitRoot = findGitRoot(packagePath);
|
|
8686
|
+
if (gitRoot && path.resolve(packagePath) === path.resolve(gitRoot)) {
|
|
8687
|
+
const configuredHooksPath = getConfiguredHooksPath(packagePath);
|
|
8688
|
+
const normalizedHooksPath = normalizeGitHooksPath(configuredHooksPath);
|
|
8689
|
+
if (configuredHooksPath && normalizedHooksPath !== ".vite-hooks/_") return `core.hooksPath is already set to "${configuredHooksPath}" in workspace package "${pkg.path}" — leaving the existing hook setup unchanged.`;
|
|
8690
|
+
}
|
|
8691
|
+
}
|
|
8692
|
+
return null;
|
|
8693
|
+
}
|
|
8694
|
+
function getConfiguredHooksPath(projectPath) {
|
|
8695
|
+
const result = import_cross_spawn.default.sync("git", [
|
|
8696
|
+
"config",
|
|
8697
|
+
"--get",
|
|
8698
|
+
"core.hooksPath"
|
|
8699
|
+
], {
|
|
8700
|
+
cwd: projectPath,
|
|
8701
|
+
stdio: "pipe"
|
|
8702
|
+
});
|
|
8703
|
+
return result.status === 0 ? result.stdout?.toString().trim() ?? "" : "";
|
|
8704
|
+
}
|
|
8705
|
+
function normalizeGitHooksPath(hooksPath) {
|
|
8706
|
+
return path.posix.normalize(hooksPath.replaceAll("\\", "/")).replace(/\/$/, "");
|
|
8397
8707
|
}
|
|
8398
8708
|
/**
|
|
8399
|
-
*
|
|
8400
|
-
*
|
|
8709
|
+
* High-level helper that sets up Vite+ hooks when no other hook tool owns the
|
|
8710
|
+
* project. Husky setups are deliberately preserved for a dedicated migration.
|
|
8401
8711
|
*/
|
|
8402
|
-
function
|
|
8403
|
-
|
|
8404
|
-
if (!fs.existsSync(packageJsonPath)) return;
|
|
8405
|
-
const pkg = readJsonFile(packageJsonPath);
|
|
8406
|
-
if (!pkg.scripts?.prepare) return;
|
|
8407
|
-
const match = collapseHuskyInstall(pkg.scripts.prepare).match(/\bhusky(?:\s+([\w./-]+))?/);
|
|
8408
|
-
if (!match) return;
|
|
8409
|
-
return match[1] ?? ".husky";
|
|
8712
|
+
function installGitHooks(projectPath, silent = false, report, packageManager, packages = []) {
|
|
8713
|
+
return setupGitHooks(projectPath, silent, report, packageManager, packages);
|
|
8410
8714
|
}
|
|
8411
8715
|
/**
|
|
8412
8716
|
* Pre-flight check: verify that git hooks can be set up for this project.
|
|
@@ -8416,10 +8720,9 @@ function getOldHooksDir(rootDir) {
|
|
|
8416
8720
|
* These checks are deterministic and read-only — they do not modify
|
|
8417
8721
|
* the project in any way, making them safe to call before migration.
|
|
8418
8722
|
*
|
|
8419
|
-
*
|
|
8420
|
-
* resolution to that manager's catalog so a foreign catalog file is ignored.
|
|
8723
|
+
* The package manager argument remains for API compatibility with callers.
|
|
8421
8724
|
*/
|
|
8422
|
-
function preflightGitHooksSetup(projectPath,
|
|
8725
|
+
function preflightGitHooksSetup(projectPath, _packageManager, packages = []) {
|
|
8423
8726
|
const gitRoot = findGitRoot(projectPath);
|
|
8424
8727
|
if (gitRoot && path.resolve(projectPath) !== path.resolve(gitRoot)) return "Subdirectory project detected — skipping git hooks setup. Configure hooks at the repository root.";
|
|
8425
8728
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
@@ -8427,19 +8730,41 @@ function preflightGitHooksSetup(projectPath, packageManager) {
|
|
|
8427
8730
|
const pkgContent = readJsonFile(packageJsonPath);
|
|
8428
8731
|
const deps = pkgContent.devDependencies;
|
|
8429
8732
|
const prodDeps = pkgContent.dependencies;
|
|
8733
|
+
const configuredHooksPath = gitRoot ? getConfiguredHooksPath(projectPath) : "";
|
|
8734
|
+
const normalizedHooksPath = normalizeGitHooksPath(configuredHooksPath);
|
|
8735
|
+
if (hasHuskySetup(projectPath, pkgContent) || normalizedHooksPath === ".husky" || normalizedHooksPath.startsWith(".husky/")) return "Detected Husky — leaving its hooks, configuration, and dependencies unchanged. Migrate Husky manually before enabling Vite+ hooks.";
|
|
8430
8736
|
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, see https://viteplus.dev/guide/migrate#git-hook-tools`;
|
|
8431
|
-
const
|
|
8432
|
-
if (
|
|
8737
|
+
const workspacePackageReason = findWorkspacePackageHookPolicy(projectPath, packages);
|
|
8738
|
+
if (workspacePackageReason) return workspacePackageReason;
|
|
8739
|
+
const disabledHooksEnvironment = [
|
|
8740
|
+
"HUSKY",
|
|
8741
|
+
"VP_GIT_HOOKS",
|
|
8742
|
+
"VITE_GIT_HOOKS"
|
|
8743
|
+
].find((name) => process.env[name] === "0");
|
|
8744
|
+
if (disabledHooksEnvironment) return `Git hooks are disabled through ${disabledHooksEnvironment}=0 — skipping git hooks setup.`;
|
|
8745
|
+
if (configuredHooksPath && normalizedHooksPath !== ".vite-hooks/_") return `core.hooksPath is already set to "${configuredHooksPath}" — leaving the existing hook setup unchanged.`;
|
|
8746
|
+
const unsafeInstallPath = findUnsafeHookInstallPath(projectPath, ".vite-hooks");
|
|
8747
|
+
if (unsafeInstallPath) return `Git hook dispatcher path "${unsafeInstallPath.relativePath}" is unsafe — leaving the existing hook setup unchanged.`;
|
|
8748
|
+
const nonRegularHookPath = findNonRegularViteHookPath(projectPath);
|
|
8749
|
+
if (nonRegularHookPath) return `Git hook path "${nonRegularHookPath}" is not a regular file — leaving the existing hook setup unchanged.`;
|
|
8433
8750
|
if (hasUnsupportedLintStagedConfig(projectPath)) return "Unsupported lint-staged config format — skipping git hooks setup. Please configure git hooks manually.";
|
|
8434
8751
|
return null;
|
|
8435
8752
|
}
|
|
8436
8753
|
/**
|
|
8754
|
+
* Decide whether config rewriting must leave lint-staged configuration in
|
|
8755
|
+
* place. Call this after scaffolding but before rewriting the project so an
|
|
8756
|
+
* existing hook owner never observes a partially migrated configuration.
|
|
8757
|
+
*/
|
|
8758
|
+
function shouldSkipStagedMigrationForHooks(projectPath, shouldSetupHooks, packageManager, packages = []) {
|
|
8759
|
+
return !shouldSetupHooks || hasExistingViteHooksPolicy(projectPath) || preflightGitHooksSetup(projectPath, packageManager, packages) !== null;
|
|
8760
|
+
}
|
|
8761
|
+
/**
|
|
8437
8762
|
* Set up git hooks with husky + lint-staged via vp commands.
|
|
8438
8763
|
* Skips if another hook tool is detected (warns user).
|
|
8439
8764
|
* Returns true if hooks were successfully set up, false if skipped.
|
|
8440
8765
|
*/
|
|
8441
|
-
function setupGitHooks(projectPath,
|
|
8442
|
-
const reason = preflightGitHooksSetup(projectPath, packageManager);
|
|
8766
|
+
function setupGitHooks(projectPath, silent = false, report, packageManager, packages = []) {
|
|
8767
|
+
const reason = preflightGitHooksSetup(projectPath, packageManager, packages);
|
|
8443
8768
|
if (reason) {
|
|
8444
8769
|
warnMigration(reason, report);
|
|
8445
8770
|
return false;
|
|
@@ -8447,73 +8772,29 @@ function setupGitHooks(projectPath, oldHooksDir, silent = false, report, package
|
|
|
8447
8772
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
8448
8773
|
if (!fs.existsSync(packageJsonPath)) return false;
|
|
8449
8774
|
const gitRoot = findGitRoot(projectPath);
|
|
8450
|
-
const
|
|
8451
|
-
const
|
|
8775
|
+
const hooksDir = ".vite-hooks";
|
|
8776
|
+
const hasExistingHookPolicy = hasExistingViteHooksPolicy(projectPath);
|
|
8452
8777
|
editJsonFile(packageJsonPath, (pkg) => {
|
|
8453
8778
|
if (!pkg.scripts) pkg.scripts = {};
|
|
8454
8779
|
if (!pkg.scripts.prepare) pkg.scripts.prepare = "vp config";
|
|
8455
|
-
else if (!pkg.scripts.prepare.includes("vp config")
|
|
8780
|
+
else if (!pkg.scripts.prepare.includes("vp config")) pkg.scripts.prepare = `vp config && ${pkg.scripts.prepare}`;
|
|
8456
8781
|
return pkg;
|
|
8457
8782
|
});
|
|
8458
8783
|
let stagedMerged = hasStagedConfigInViteConfig(projectPath);
|
|
8459
8784
|
const hasStandaloneConfig = hasStandaloneLintStagedConfig(projectPath);
|
|
8460
|
-
if (!stagedMerged && !hasStandaloneConfig) {
|
|
8785
|
+
if (!hasExistingHookPolicy && !stagedMerged && !hasStandaloneConfig) {
|
|
8461
8786
|
const stagedConfig = readJsonFile(packageJsonPath)?.["lint-staged"] ?? DEFAULT_STAGED_CONFIG;
|
|
8462
8787
|
const updated = rewriteScripts(JSON.stringify(stagedConfig), readRulesYaml());
|
|
8463
8788
|
stagedMerged = mergeStagedConfigToViteConfig(projectPath, updated ? JSON.parse(updated) : stagedConfig, silent, report);
|
|
8464
8789
|
}
|
|
8465
|
-
if (stagedMerged) removeLintStagedFromPackageJson(packageJsonPath);
|
|
8466
|
-
if (
|
|
8467
|
-
const oldDir = path.join(projectPath, oldHooksDir);
|
|
8468
|
-
if (fs.existsSync(oldDir)) {
|
|
8469
|
-
const targetDir = path.join(projectPath, hooksDir);
|
|
8470
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
8471
|
-
for (const entry of fs.readdirSync(oldDir, { withFileTypes: true })) {
|
|
8472
|
-
if (entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
8473
|
-
const src = path.join(oldDir, entry.name);
|
|
8474
|
-
const dest = path.join(targetDir, entry.name);
|
|
8475
|
-
fs.copyFileSync(src, dest);
|
|
8476
|
-
fs.chmodSync(dest, 493);
|
|
8477
|
-
}
|
|
8478
|
-
fs.rmSync(oldDir, {
|
|
8479
|
-
recursive: true,
|
|
8480
|
-
force: true
|
|
8481
|
-
});
|
|
8482
|
-
}
|
|
8483
|
-
}
|
|
8484
|
-
if (stagedMerged) createPreCommitHook(projectPath, hooksDir);
|
|
8790
|
+
if (!hasExistingHookPolicy && stagedMerged) removeLintStagedFromPackageJson(packageJsonPath);
|
|
8791
|
+
if (!hasExistingHookPolicy && stagedMerged) createPreCommitHook(projectPath, hooksDir);
|
|
8485
8792
|
if (!gitRoot) {
|
|
8486
|
-
|
|
8793
|
+
if (!hasExistingHookPolicy && stagedMerged) removeReplacedStagedPackage(packageJsonPath);
|
|
8487
8794
|
return true;
|
|
8488
8795
|
}
|
|
8489
|
-
if (oldHooksDir) {
|
|
8490
|
-
const checkResult = import_cross_spawn.default.sync("git", [
|
|
8491
|
-
"config",
|
|
8492
|
-
"--local",
|
|
8493
|
-
"core.hooksPath"
|
|
8494
|
-
], {
|
|
8495
|
-
cwd: projectPath,
|
|
8496
|
-
stdio: "pipe"
|
|
8497
|
-
});
|
|
8498
|
-
const existingPath = checkResult.status === 0 ? checkResult.stdout?.toString().trim() : "";
|
|
8499
|
-
if (existingPath === `${oldHooksDir}/_` || existingPath === oldHooksDir) import_cross_spawn.default.sync("git", [
|
|
8500
|
-
"config",
|
|
8501
|
-
"--local",
|
|
8502
|
-
"--unset",
|
|
8503
|
-
"core.hooksPath"
|
|
8504
|
-
], {
|
|
8505
|
-
cwd: projectPath,
|
|
8506
|
-
stdio: "pipe"
|
|
8507
|
-
});
|
|
8508
|
-
}
|
|
8509
8796
|
const vpBin = process.env.VP_CLI_BIN ?? "vp";
|
|
8510
|
-
const
|
|
8511
|
-
"config",
|
|
8512
|
-
"--no-agent",
|
|
8513
|
-
"--hooks-dir",
|
|
8514
|
-
hooksDir
|
|
8515
|
-
] : ["config", "--no-agent"];
|
|
8516
|
-
const configResult = import_cross_spawn.default.sync(vpBin, configArgs, {
|
|
8797
|
+
const configResult = import_cross_spawn.default.sync(vpBin, ["config", "--no-agent"], {
|
|
8517
8798
|
cwd: projectPath,
|
|
8518
8799
|
stdio: "pipe"
|
|
8519
8800
|
});
|
|
@@ -8523,7 +8804,7 @@ function setupGitHooks(projectPath, oldHooksDir, silent = false, report, package
|
|
|
8523
8804
|
warnMigration(`Git hooks not configured — ${stdout}`, report);
|
|
8524
8805
|
return false;
|
|
8525
8806
|
}
|
|
8526
|
-
|
|
8807
|
+
if (!hasExistingHookPolicy && stagedMerged) removeReplacedStagedPackage(packageJsonPath);
|
|
8527
8808
|
if (report) report.gitHooksConfigured = true;
|
|
8528
8809
|
if (!silent) log.success("✔ Git hooks configured");
|
|
8529
8810
|
return true;
|
|
@@ -8548,85 +8829,14 @@ function hasUnsupportedLintStagedConfig(projectPath) {
|
|
|
8548
8829
|
if (fs.existsSync(lintstagedrcPath) && !isJsonFile(lintstagedrcPath)) return true;
|
|
8549
8830
|
return false;
|
|
8550
8831
|
}
|
|
8551
|
-
/**
|
|
8552
|
-
* Create pre-commit hook file in the hooks directory.
|
|
8553
|
-
*/
|
|
8554
|
-
const STALE_LINT_STAGED_PATTERNS = [/^((?:[A-Z_][A-Z0-9_]*(?:=\S*)?\s+)*)(pnpm|pnpm exec|npx|yarn|yarn run|npm exec|npm run|bunx|bun run|bun x)\s+lint-staged\b/, /^((?:[A-Z_][A-Z0-9_]*(?:=\S*)?\s+)*)lint-staged\b/];
|
|
8555
8832
|
const DEFAULT_STAGED_CONFIG = { "*": "vp check --fix" };
|
|
8556
|
-
/**
|
|
8557
|
-
* Ensure the pre-commit hook exists with `vp staged`, and that
|
|
8558
|
-
* vite.config.ts contains a `staged` block (using the default config
|
|
8559
|
-
* if none is present). Called by `vp config` after hook installation.
|
|
8560
|
-
*/
|
|
8561
|
-
function ensurePreCommitHook(projectPath, dir = ".vite-hooks") {
|
|
8562
|
-
if (!hasStagedConfigInViteConfig(projectPath)) mergeStagedConfigToViteConfig(projectPath, DEFAULT_STAGED_CONFIG, true);
|
|
8563
|
-
createPreCommitHook(projectPath, dir);
|
|
8564
|
-
}
|
|
8565
8833
|
function createPreCommitHook(projectPath, dir = ".vite-hooks") {
|
|
8566
8834
|
const huskyDir = path.join(projectPath, dir);
|
|
8567
8835
|
fs.mkdirSync(huskyDir, { recursive: true });
|
|
8568
8836
|
const hookPath = path.join(huskyDir, "pre-commit");
|
|
8569
|
-
if (fs.existsSync(hookPath))
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
const lines = existing.split("\n");
|
|
8573
|
-
let replaced = false;
|
|
8574
|
-
const result = [];
|
|
8575
|
-
for (const line of lines) {
|
|
8576
|
-
const trimmed = line.trim();
|
|
8577
|
-
if (!replaced) {
|
|
8578
|
-
let matched = false;
|
|
8579
|
-
for (const pattern of STALE_LINT_STAGED_PATTERNS) {
|
|
8580
|
-
const match = pattern.exec(trimmed);
|
|
8581
|
-
if (match) {
|
|
8582
|
-
const parts = [
|
|
8583
|
-
match[1]?.trim() ?? "",
|
|
8584
|
-
"vp staged",
|
|
8585
|
-
trimmed.slice(match[0].length).trim()
|
|
8586
|
-
].filter(Boolean);
|
|
8587
|
-
result.push(parts.join(" "));
|
|
8588
|
-
replaced = true;
|
|
8589
|
-
matched = true;
|
|
8590
|
-
break;
|
|
8591
|
-
}
|
|
8592
|
-
}
|
|
8593
|
-
if (matched) continue;
|
|
8594
|
-
}
|
|
8595
|
-
result.push(line);
|
|
8596
|
-
}
|
|
8597
|
-
if (!replaced) fs.writeFileSync(hookPath, `${result.join("\n").trimEnd()}\nvp staged\n`);
|
|
8598
|
-
else fs.writeFileSync(hookPath, result.join("\n"));
|
|
8599
|
-
} else {
|
|
8600
|
-
fs.writeFileSync(hookPath, "vp staged\n");
|
|
8601
|
-
fs.chmodSync(hookPath, 493);
|
|
8602
|
-
}
|
|
8603
|
-
}
|
|
8604
|
-
/**
|
|
8605
|
-
* Rewrite only `scripts.prepare` in the root package.json using vite-prepare.yml rules.
|
|
8606
|
-
* Collapses "husky install" → "husky" before applying ast-grep so that the
|
|
8607
|
-
* replace-husky rule produces "vp config" with any directory argument preserved.
|
|
8608
|
-
* Returns the old husky hooks dir (if any) for migration to .vite-hooks.
|
|
8609
|
-
* Called only when hooks are being set up (not with --no-hooks).
|
|
8610
|
-
*/
|
|
8611
|
-
function rewritePrepareScript(rootDir) {
|
|
8612
|
-
const packageJsonPath = path.join(rootDir, "package.json");
|
|
8613
|
-
if (!fs.existsSync(packageJsonPath)) return;
|
|
8614
|
-
let oldDir;
|
|
8615
|
-
editJsonFile(packageJsonPath, (pkg) => {
|
|
8616
|
-
if (!pkg.scripts?.prepare) return pkg;
|
|
8617
|
-
const prepare = collapseHuskyInstall(pkg.scripts.prepare);
|
|
8618
|
-
const updated = rewriteScripts(JSON.stringify({ prepare }), readPrepareRulesYaml());
|
|
8619
|
-
if (updated) {
|
|
8620
|
-
let newPrepare = JSON.parse(updated).prepare;
|
|
8621
|
-
newPrepare = newPrepare.replace(/\bvp config(?:\s+(?!-)([\w./-]+))?/, (_match, dir) => {
|
|
8622
|
-
oldDir = dir ?? ".husky";
|
|
8623
|
-
return dir ? `vp config --hooks-dir ${dir}` : "vp config";
|
|
8624
|
-
});
|
|
8625
|
-
pkg.scripts.prepare = newPrepare;
|
|
8626
|
-
} else if (prepare !== pkg.scripts.prepare) pkg.scripts.prepare = prepare;
|
|
8627
|
-
return pkg;
|
|
8628
|
-
});
|
|
8629
|
-
return oldDir;
|
|
8837
|
+
if (fs.existsSync(hookPath)) return;
|
|
8838
|
+
fs.writeFileSync(hookPath, "vp staged\n");
|
|
8839
|
+
fs.chmodSync(hookPath, 493);
|
|
8630
8840
|
}
|
|
8631
8841
|
//#endregion
|
|
8632
8842
|
//#region src/migration/migrator/setup.ts
|
|
@@ -8769,24 +8979,35 @@ function migrateNodeVersionManagerFile(projectPath, detection, report) {
|
|
|
8769
8979
|
//#endregion
|
|
8770
8980
|
//#region src/migration/migrator/core-finalization.ts
|
|
8771
8981
|
const RULES_YAML_PATH = path.join(rulesDir, "vite-tools.yml");
|
|
8772
|
-
|
|
8982
|
+
path.join(rulesDir, "vite-prepare.yml");
|
|
8773
8983
|
let cachedRulesYaml;
|
|
8774
8984
|
let cachedRulesYamlNoLintStaged;
|
|
8775
|
-
let cachedPrepareRulesYaml;
|
|
8776
8985
|
function readRulesYaml() {
|
|
8777
8986
|
cachedRulesYaml ??= fs.readFileSync(RULES_YAML_PATH, "utf8");
|
|
8778
8987
|
return cachedRulesYaml;
|
|
8779
8988
|
}
|
|
8989
|
+
function splitRuleDocuments(yaml) {
|
|
8990
|
+
const lines = yaml.split("\n");
|
|
8991
|
+
const documents = [];
|
|
8992
|
+
let start = 0;
|
|
8993
|
+
for (const [index, line] of lines.entries()) {
|
|
8994
|
+
if (line.trimEnd() !== "---") continue;
|
|
8995
|
+
let documentStart = index;
|
|
8996
|
+
while (documentStart > start && lines[documentStart - 1].trimStart().startsWith("#")) documentStart--;
|
|
8997
|
+
if (documentStart > start) {
|
|
8998
|
+
documents.push(lines.slice(start, documentStart).join("\n"));
|
|
8999
|
+
start = documentStart;
|
|
9000
|
+
}
|
|
9001
|
+
}
|
|
9002
|
+
documents.push(lines.slice(start).join("\n"));
|
|
9003
|
+
return documents;
|
|
9004
|
+
}
|
|
8780
9005
|
function getScriptRulesYaml(skipStagedMigration) {
|
|
8781
9006
|
const yaml = readRulesYaml();
|
|
8782
9007
|
if (!skipStagedMigration) return yaml;
|
|
8783
|
-
cachedRulesYamlNoLintStaged ??= yaml
|
|
9008
|
+
cachedRulesYamlNoLintStaged ??= splitRuleDocuments(yaml).filter((document) => !document.includes("id: replace-lint-staged")).join("\n");
|
|
8784
9009
|
return cachedRulesYamlNoLintStaged;
|
|
8785
9010
|
}
|
|
8786
|
-
function readPrepareRulesYaml() {
|
|
8787
|
-
cachedPrepareRulesYaml ??= fs.readFileSync(PREPARE_RULES_YAML_PATH, "utf8");
|
|
8788
|
-
return cachedPrepareRulesYaml;
|
|
8789
|
-
}
|
|
8790
9011
|
function getCoreMigrationProjectPaths(workspaceInfo) {
|
|
8791
9012
|
return [workspaceInfo.rootDir, ...(workspaceInfo.packages ?? []).map((pkg) => path.join(workspaceInfo.rootDir, pkg.path))];
|
|
8792
9013
|
}
|
|
@@ -9014,300 +9235,235 @@ function rewriteMonorepoProject(projectPath, packageManager, skipStagedMigration
|
|
|
9014
9235
|
if (!deferLazyPluginWrapping) wrapLazyPluginsInViteConfig(projectPath, silent, report);
|
|
9015
9236
|
}
|
|
9016
9237
|
//#endregion
|
|
9017
|
-
//#region src/utils/
|
|
9018
|
-
const
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
"
|
|
9035
|
-
"
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
aliases: ["claude.md", "claude-code"]
|
|
9044
|
-
},
|
|
9045
|
-
{
|
|
9046
|
-
id: "gemini",
|
|
9047
|
-
label: "GEMINI.md",
|
|
9048
|
-
targetPath: "GEMINI.md",
|
|
9049
|
-
hint: "Gemini CLI",
|
|
9050
|
-
aliases: ["gemini.md", "gemini-cli"]
|
|
9238
|
+
//#region src/utils/editor.ts
|
|
9239
|
+
const VSCODE_SETTINGS = {
|
|
9240
|
+
"editor.defaultFormatter": "oxc.oxc-vscode",
|
|
9241
|
+
"[javascript]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
|
|
9242
|
+
"[javascriptreact]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
|
|
9243
|
+
"[typescript]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
|
|
9244
|
+
"[typescriptreact]": { "editor.defaultFormatter": "oxc.oxc-vscode" },
|
|
9245
|
+
"oxc.disableNestedConfig": true,
|
|
9246
|
+
"oxc.fmt.disableNestedConfig": true,
|
|
9247
|
+
"editor.formatOnSave": true,
|
|
9248
|
+
"editor.formatOnSaveMode": "file",
|
|
9249
|
+
"editor.codeActionsOnSave": { "source.fixAll.oxc": "explicit" }
|
|
9250
|
+
};
|
|
9251
|
+
const VSCODE_EXTENSIONS = { recommendations: ["VoidZero.vite-plus-extension-pack"] };
|
|
9252
|
+
const ZED_SETTINGS = {
|
|
9253
|
+
lsp: {
|
|
9254
|
+
oxlint: { initialization_options: { settings: {
|
|
9255
|
+
run: "onType",
|
|
9256
|
+
fixKind: "safe_fix",
|
|
9257
|
+
typeAware: true,
|
|
9258
|
+
unusedDisableDirectives: "deny"
|
|
9259
|
+
} } },
|
|
9260
|
+
oxfmt: { initialization_options: { settings: {
|
|
9261
|
+
"fmt.configPath": "./vite.config.ts",
|
|
9262
|
+
run: "onSave"
|
|
9263
|
+
} } }
|
|
9051
9264
|
},
|
|
9265
|
+
languages: Object.fromEntries([
|
|
9266
|
+
"CSS",
|
|
9267
|
+
"GraphQL",
|
|
9268
|
+
"Handlebars",
|
|
9269
|
+
"HTML",
|
|
9270
|
+
"JavaScript",
|
|
9271
|
+
"JSX",
|
|
9272
|
+
"JSON",
|
|
9273
|
+
"JSON5",
|
|
9274
|
+
"JSONC",
|
|
9275
|
+
"Less",
|
|
9276
|
+
"Markdown",
|
|
9277
|
+
"MDX",
|
|
9278
|
+
"SCSS",
|
|
9279
|
+
"TypeScript",
|
|
9280
|
+
"TSX",
|
|
9281
|
+
"Vue.js",
|
|
9282
|
+
"YAML"
|
|
9283
|
+
].map((language) => [language, {
|
|
9284
|
+
format_on_save: "on",
|
|
9285
|
+
prettier: { allowed: false },
|
|
9286
|
+
formatter: [{ language_server: { name: "oxfmt" } }],
|
|
9287
|
+
...language === "JavaScript" ? { code_action: "source.fixAll.oxc" } : {}
|
|
9288
|
+
}]))
|
|
9289
|
+
};
|
|
9290
|
+
const JETBRAINS_EXTERNAL_DEPENDENCIES = `<?xml version="1.0" encoding="UTF-8"?>
|
|
9291
|
+
<project version="4">
|
|
9292
|
+
<component name="ExternalDependencies">
|
|
9293
|
+
<plugin id="com.github.oxc.project.oxcintellijplugin" />
|
|
9294
|
+
</component>
|
|
9295
|
+
</project>
|
|
9296
|
+
`;
|
|
9297
|
+
function jetbrainsWorkspaceConfig(packageManager) {
|
|
9298
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
9299
|
+
<project version="4">
|
|
9300
|
+
<component name="PropertiesComponent">
|
|
9301
|
+
<![CDATA[${JSON.stringify({ keyToString: {
|
|
9302
|
+
"javascript.preferred.runtime.type.id": "node",
|
|
9303
|
+
nodejs_interpreter_path: "$USER_HOME$/.vite-plus/bin/node.exe",
|
|
9304
|
+
nodejs_package_manager_path: packageManager
|
|
9305
|
+
} }, null, 2)}]]>
|
|
9306
|
+
</component>
|
|
9307
|
+
</project>
|
|
9308
|
+
`;
|
|
9309
|
+
}
|
|
9310
|
+
const EDITORS = [
|
|
9052
9311
|
{
|
|
9053
|
-
id: "
|
|
9054
|
-
label: "
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9312
|
+
id: "vscode",
|
|
9313
|
+
label: "VSCode",
|
|
9314
|
+
targetDir: ".vscode",
|
|
9315
|
+
files: {
|
|
9316
|
+
"settings.json": VSCODE_SETTINGS,
|
|
9317
|
+
"extensions.json": VSCODE_EXTENSIONS
|
|
9318
|
+
}
|
|
9058
9319
|
},
|
|
9059
9320
|
{
|
|
9060
|
-
id: "
|
|
9061
|
-
label: "
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
aliases: ["viteplus.mdc"]
|
|
9321
|
+
id: "zed",
|
|
9322
|
+
label: "Zed",
|
|
9323
|
+
targetDir: ".zed",
|
|
9324
|
+
files: { "settings.json": ZED_SETTINGS }
|
|
9065
9325
|
},
|
|
9066
9326
|
{
|
|
9067
9327
|
id: "jetbrains",
|
|
9068
|
-
label: "
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
"
|
|
9073
|
-
"
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9328
|
+
label: "JetBrains (IntelliJ, WebStorm, etc)",
|
|
9329
|
+
targetDir: ".idea",
|
|
9330
|
+
files: {
|
|
9331
|
+
"externalDependencies.xml": JETBRAINS_EXTERNAL_DEPENDENCIES,
|
|
9332
|
+
"workspace.xml": jetbrainsWorkspaceConfig(PackageManager.pnpm),
|
|
9333
|
+
"OxfmtSettings.xml": `<?xml version="1.0" encoding="UTF-8"?>
|
|
9334
|
+
<project version="4">
|
|
9335
|
+
<component name="OxfmtSettings">
|
|
9336
|
+
<option name="preferOxfmtCodeStyleSettings" value="true" />
|
|
9337
|
+
</component>
|
|
9338
|
+
</project>
|
|
9339
|
+
`
|
|
9340
|
+
}
|
|
9077
9341
|
}
|
|
9078
9342
|
];
|
|
9079
|
-
const
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
};
|
|
9120
|
-
if (interactive && !agent) {
|
|
9121
|
-
const selectedAgentIds = await multiselect({
|
|
9122
|
-
message: "Which coding agent instruction files should Vite+ create?",
|
|
9123
|
-
options: AGENTS.map((option) => ({
|
|
9343
|
+
const EDITOR_ALIASES = [{
|
|
9344
|
+
id: "intellij",
|
|
9345
|
+
alias: "jetbrains"
|
|
9346
|
+
}, {
|
|
9347
|
+
id: "webstorm",
|
|
9348
|
+
alias: "jetbrains"
|
|
9349
|
+
}];
|
|
9350
|
+
async function selectEditor({ interactive, editor, onCancel }) {
|
|
9351
|
+
if (editor === false) return;
|
|
9352
|
+
if (interactive && !editor) {
|
|
9353
|
+
const editorOptions = EDITORS.map((option) => ({
|
|
9354
|
+
label: option.label,
|
|
9355
|
+
value: option.id,
|
|
9356
|
+
hint: option.targetDir
|
|
9357
|
+
}));
|
|
9358
|
+
const otherOption = {
|
|
9359
|
+
label: "Other",
|
|
9360
|
+
value: null,
|
|
9361
|
+
hint: "Skip writing editor configs"
|
|
9362
|
+
};
|
|
9363
|
+
const selectedEditor = await select({
|
|
9364
|
+
message: "Which editor are you using?\n " + styleText("gray", "Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations."),
|
|
9365
|
+
options: [...editorOptions, otherOption],
|
|
9366
|
+
initialValue: "vscode"
|
|
9367
|
+
});
|
|
9368
|
+
if (isCancel(selectedEditor)) {
|
|
9369
|
+
onCancel();
|
|
9370
|
+
return;
|
|
9371
|
+
}
|
|
9372
|
+
if (selectedEditor === null) return;
|
|
9373
|
+
return resolveEditorId(selectedEditor);
|
|
9374
|
+
}
|
|
9375
|
+
if (editor) return resolveEditorId(editor);
|
|
9376
|
+
}
|
|
9377
|
+
async function selectEditors({ interactive, editor, onCancel }) {
|
|
9378
|
+
if (editor === false) return;
|
|
9379
|
+
if (interactive && !editor) {
|
|
9380
|
+
const selectedEditors = await multiselect({
|
|
9381
|
+
message: "Which editors are you using?\n " + styleText("gray", "Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations."),
|
|
9382
|
+
options: EDITORS.map((option) => ({
|
|
9124
9383
|
label: option.label,
|
|
9125
9384
|
value: option.id,
|
|
9126
|
-
hint: option.
|
|
9385
|
+
hint: option.targetDir
|
|
9127
9386
|
})),
|
|
9128
|
-
initialValues: [
|
|
9387
|
+
initialValues: ["vscode"],
|
|
9129
9388
|
required: false
|
|
9130
9389
|
});
|
|
9131
|
-
if (isCancel(
|
|
9390
|
+
if (isCancel(selectedEditors)) {
|
|
9132
9391
|
onCancel();
|
|
9133
|
-
return
|
|
9134
|
-
targetPaths: void 0,
|
|
9135
|
-
selectedAgents: []
|
|
9136
|
-
};
|
|
9392
|
+
return;
|
|
9137
9393
|
}
|
|
9138
|
-
|
|
9139
|
-
targetPaths: void 0,
|
|
9140
|
-
selectedAgents: []
|
|
9141
|
-
};
|
|
9142
|
-
const selectedAgents = resolveAgentOptions(selectedAgentIds);
|
|
9143
|
-
return {
|
|
9144
|
-
targetPaths: getAgentTargetPaths(selectedAgents),
|
|
9145
|
-
selectedAgents
|
|
9146
|
-
};
|
|
9394
|
+
return selectedEditors.length === 0 ? void 0 : resolveEditorIds(selectedEditors);
|
|
9147
9395
|
}
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
selectedAgents
|
|
9152
|
-
};
|
|
9153
|
-
}
|
|
9154
|
-
async function selectAgentTargetPaths({ interactive, agent, onCancel }) {
|
|
9155
|
-
return (await selectAgentTargets({
|
|
9156
|
-
interactive,
|
|
9157
|
-
agent,
|
|
9158
|
-
onCancel
|
|
9159
|
-
})).targetPaths;
|
|
9160
|
-
}
|
|
9161
|
-
function detectExistingAgentTargetPaths(projectRoot) {
|
|
9162
|
-
const detectedPaths = [];
|
|
9163
|
-
const seenTargetPaths = /* @__PURE__ */ new Set();
|
|
9164
|
-
for (const option of AGENTS) {
|
|
9165
|
-
if (seenTargetPaths.has(option.targetPath)) continue;
|
|
9166
|
-
seenTargetPaths.add(option.targetPath);
|
|
9167
|
-
const targetPath = path.join(projectRoot, option.targetPath);
|
|
9168
|
-
if (fs.existsSync(targetPath) && !fs.lstatSync(targetPath).isSymbolicLink()) detectedPaths.push(option.targetPath);
|
|
9396
|
+
if (editor) {
|
|
9397
|
+
const editorId = resolveEditorId(editor);
|
|
9398
|
+
return editorId ? [editorId] : void 0;
|
|
9169
9399
|
}
|
|
9170
|
-
return detectedPaths.length > 0 ? detectedPaths : void 0;
|
|
9171
|
-
}
|
|
9172
|
-
/**
|
|
9173
|
-
* Silently update agent instruction files that contain Vite+ markers.
|
|
9174
|
-
* - No agent files → no writes
|
|
9175
|
-
* - No Vite+ markers → no writes
|
|
9176
|
-
* - Markers present, content up to date → no writes
|
|
9177
|
-
* - Markers present, content outdated → update marked section
|
|
9178
|
-
*/
|
|
9179
|
-
function updateExistingAgentInstructions(projectRoot) {
|
|
9180
|
-
const targetPaths = detectExistingAgentTargetPaths(projectRoot);
|
|
9181
|
-
if (!targetPaths) return;
|
|
9182
|
-
const templatePath = path.join(pkgRoot, "AGENTS.md");
|
|
9183
|
-
if (!fs.existsSync(templatePath)) return;
|
|
9184
|
-
const templateContent = fs.readFileSync(templatePath, "utf-8");
|
|
9185
|
-
for (const targetPath of targetPaths) try {
|
|
9186
|
-
const fullPath = path.join(projectRoot, targetPath);
|
|
9187
|
-
const existing = fs.readFileSync(fullPath, "utf-8");
|
|
9188
|
-
const updated = replaceMarkedAgentInstructionsSection(existing, templateContent);
|
|
9189
|
-
if (updated !== void 0 && updated !== existing) fs.writeFileSync(fullPath, updated);
|
|
9190
|
-
} catch {}
|
|
9191
9400
|
}
|
|
9192
|
-
function
|
|
9193
|
-
const
|
|
9194
|
-
const
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
}
|
|
9203
|
-
return dedupedAgents;
|
|
9204
|
-
}
|
|
9205
|
-
function getAgentTargetPaths(agents) {
|
|
9206
|
-
const dedupedTargetPaths = [];
|
|
9207
|
-
const seenTargetPaths = /* @__PURE__ */ new Set();
|
|
9208
|
-
for (const agent of agents) {
|
|
9209
|
-
if (seenTargetPaths.has(agent.targetPath)) continue;
|
|
9210
|
-
seenTargetPaths.add(agent.targetPath);
|
|
9211
|
-
dedupedTargetPaths.push(agent.targetPath);
|
|
9212
|
-
}
|
|
9213
|
-
return dedupedTargetPaths;
|
|
9214
|
-
}
|
|
9215
|
-
function parseAgentNames(agent) {
|
|
9216
|
-
if (!agent) return [];
|
|
9217
|
-
return (Array.isArray(agent) ? agent : [agent]).filter((value) => typeof value === "string").flatMap((value) => value.split(",")).map((value) => value.trim()).filter((value) => value.length > 0);
|
|
9218
|
-
}
|
|
9219
|
-
function resolveSingleAgentOption(agent) {
|
|
9220
|
-
const normalized = normalizeAgentName(agent);
|
|
9221
|
-
const alias = AGENT_ALIASES[normalized];
|
|
9222
|
-
const resolved = alias ? normalizeAgentName(alias) : normalized;
|
|
9223
|
-
return AGENTS.find((option) => normalizeAgentName(option.id) === resolved || normalizeAgentName(option.label) === resolved || normalizeAgentName(option.targetPath) === resolved || option.aliases?.some((candidate) => normalizeAgentName(candidate) === resolved)) ?? AGENTS.find((option) => option.id === AGENT_DEFAULT_ID);
|
|
9401
|
+
function detectExistingEditors(projectRoot) {
|
|
9402
|
+
const editors = [];
|
|
9403
|
+
for (const option of EDITORS) for (const fileName of Object.keys(option.files)) {
|
|
9404
|
+
const filePath = path.join(projectRoot, option.targetDir, fileName);
|
|
9405
|
+
if (fs.existsSync(filePath)) {
|
|
9406
|
+
editors.push(option.id);
|
|
9407
|
+
break;
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
9410
|
+
return editors.length === 0 ? void 0 : editors;
|
|
9224
9411
|
}
|
|
9225
9412
|
/**
|
|
9226
|
-
* Detect
|
|
9227
|
-
* Returns only files that need a user decision (append or skip).
|
|
9413
|
+
* Detect editor config files that would conflict (already exist).
|
|
9228
9414
|
* Read-only — does not write or modify any files.
|
|
9229
9415
|
*/
|
|
9230
|
-
|
|
9231
|
-
if (!
|
|
9232
|
-
const
|
|
9233
|
-
if (!
|
|
9234
|
-
const incomingContent = await fsPromises.readFile(sourcePath, "utf-8");
|
|
9235
|
-
const shouldLinkToAgents = targetPaths.includes(AGENT_STANDARD_PATH);
|
|
9236
|
-
const orderedPaths = shouldLinkToAgents ? [AGENT_STANDARD_PATH, ...targetPaths.filter((p) => p !== AGENT_STANDARD_PATH)] : targetPaths;
|
|
9416
|
+
function detectEditorConflicts({ projectRoot, editorId }) {
|
|
9417
|
+
if (!editorId) return [];
|
|
9418
|
+
const editorConfig = EDITORS.find((e) => e.id === editorId);
|
|
9419
|
+
if (!editorConfig) return [];
|
|
9237
9420
|
const conflicts = [];
|
|
9238
|
-
const
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
seenDestinationPaths.add(destinationKey);
|
|
9245
|
-
if (shouldLinkToAgents && targetPathToCheck !== AGENT_STANDARD_PATH) {
|
|
9246
|
-
if (await getExistingPathKind(destinationPath) !== "file") continue;
|
|
9247
|
-
}
|
|
9248
|
-
if (fs.existsSync(destinationPath)) {
|
|
9249
|
-
if (fs.lstatSync(destinationPath).isSymbolicLink()) continue;
|
|
9250
|
-
const destinationRealPath = await fsPromises.realpath(destinationPath);
|
|
9251
|
-
if (seenRealPaths.has(destinationRealPath)) continue;
|
|
9252
|
-
if (replaceMarkedAgentInstructionsSection(await fsPromises.readFile(destinationPath, "utf-8"), incomingContent) !== void 0) {
|
|
9253
|
-
seenRealPaths.add(destinationRealPath);
|
|
9254
|
-
continue;
|
|
9255
|
-
}
|
|
9256
|
-
conflicts.push({ targetPath: targetPathToCheck });
|
|
9257
|
-
seenRealPaths.add(destinationRealPath);
|
|
9258
|
-
}
|
|
9421
|
+
for (const fileName of Object.keys(editorConfig.files)) {
|
|
9422
|
+
const filePath = path.join(projectRoot, editorConfig.targetDir, fileName);
|
|
9423
|
+
if (fs.existsSync(filePath)) conflicts.push({
|
|
9424
|
+
fileName,
|
|
9425
|
+
displayPath: `${editorConfig.targetDir}/${fileName}`
|
|
9426
|
+
});
|
|
9259
9427
|
}
|
|
9260
9428
|
return conflicts;
|
|
9261
9429
|
}
|
|
9262
|
-
async function
|
|
9263
|
-
const
|
|
9264
|
-
if (
|
|
9265
|
-
const
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
}
|
|
9289
|
-
const destinationRealPath = await fsPromises.realpath(destinationPath);
|
|
9290
|
-
if (seenRealPaths.has(destinationRealPath)) {
|
|
9291
|
-
if (!silent) log.info(`Skipped writing ${targetPathToWrite} (duplicate target)`);
|
|
9292
|
-
continue;
|
|
9293
|
-
}
|
|
9294
|
-
const existingContent = await fsPromises.readFile(destinationPath, "utf-8");
|
|
9295
|
-
const updatedContent = replaceMarkedAgentInstructionsSection(existingContent, incomingContent);
|
|
9296
|
-
if (updatedContent !== void 0) {
|
|
9297
|
-
if (updatedContent !== existingContent) await fsPromises.writeFile(destinationPath, updatedContent);
|
|
9298
|
-
seenRealPaths.add(destinationRealPath);
|
|
9299
|
-
continue;
|
|
9300
|
-
}
|
|
9430
|
+
async function writeEditorConfigs({ projectRoot, editorId, interactive, conflictDecisions, silent = false, extraVsCodeSettings, packageManager = PackageManager.pnpm }) {
|
|
9431
|
+
const editorIds = normalizeEditorSelection(editorId);
|
|
9432
|
+
if (editorIds.length === 0) return;
|
|
9433
|
+
for (const currentEditorId of editorIds) await writeEditorConfig({
|
|
9434
|
+
projectRoot,
|
|
9435
|
+
editorId: currentEditorId,
|
|
9436
|
+
interactive,
|
|
9437
|
+
conflictDecisions,
|
|
9438
|
+
silent,
|
|
9439
|
+
extraVsCodeSettings,
|
|
9440
|
+
packageManager
|
|
9441
|
+
});
|
|
9442
|
+
}
|
|
9443
|
+
async function writeEditorConfig({ projectRoot, editorId, interactive, conflictDecisions, silent, extraVsCodeSettings, packageManager }) {
|
|
9444
|
+
const editorConfig = EDITORS.find((e) => e.id === editorId);
|
|
9445
|
+
if (!editorConfig) return;
|
|
9446
|
+
const targetDir = path.join(projectRoot, editorConfig.targetDir);
|
|
9447
|
+
await fsPromises.mkdir(targetDir, { recursive: true });
|
|
9448
|
+
for (const [fileName, baseIncoming] of Object.entries(editorConfig.files)) {
|
|
9449
|
+
const incoming = editorId === "vscode" && fileName === "settings.json" && extraVsCodeSettings ? {
|
|
9450
|
+
...extraVsCodeSettings,
|
|
9451
|
+
...baseIncoming
|
|
9452
|
+
} : editorId === "jetbrains" && fileName === "workspace.xml" ? jetbrainsWorkspaceConfig(packageManager) : baseIncoming;
|
|
9453
|
+
const filePath = path.join(targetDir, fileName);
|
|
9454
|
+
const jsonFormat = isJsonLikeFile(fileName);
|
|
9455
|
+
if (fs.existsSync(filePath)) {
|
|
9456
|
+
const displayPath = `${editorConfig.targetDir}/${fileName}`;
|
|
9301
9457
|
let conflictAction;
|
|
9302
|
-
const preResolved = conflictDecisions?.get(
|
|
9458
|
+
const preResolved = conflictDecisions?.get(displayPath) ?? conflictDecisions?.get(fileName);
|
|
9303
9459
|
if (preResolved) conflictAction = preResolved;
|
|
9304
9460
|
else if (interactive) {
|
|
9305
9461
|
const action = await select({
|
|
9306
|
-
message:
|
|
9462
|
+
message: `${displayPath} already exists.\n ` + styleText("gray", jsonFormat ? `Vite+ adds ${editorConfig.label} settings for the built-in linter and formatter. Merge adds new keys without overwriting existing ones.` : `Vite+ adds ${editorConfig.label} settings for the built-in linter and formatter. Overwrite replaces the existing file with the generated config.`),
|
|
9307
9463
|
options: [{
|
|
9308
|
-
label: "
|
|
9309
|
-
value: "
|
|
9310
|
-
hint: "
|
|
9464
|
+
label: jsonFormat ? "Merge" : "Overwrite",
|
|
9465
|
+
value: "merge",
|
|
9466
|
+
hint: jsonFormat ? "Merge new settings into existing file" : "Replace existing file with generated config"
|
|
9311
9467
|
}, {
|
|
9312
9468
|
label: "Skip",
|
|
9313
9469
|
value: "skip",
|
|
@@ -9315,86 +9471,121 @@ async function writeAgentInstructions({ projectRoot, targetPath, targetPaths, in
|
|
|
9315
9471
|
}],
|
|
9316
9472
|
initialValue: "skip"
|
|
9317
9473
|
});
|
|
9318
|
-
conflictAction = isCancel(action) || action === "skip" ? "skip" : "
|
|
9319
|
-
} else conflictAction = "skip";
|
|
9320
|
-
if (conflictAction === "
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9474
|
+
conflictAction = isCancel(action) || action === "skip" ? "skip" : "merge";
|
|
9475
|
+
} else conflictAction = jsonFormat ? "merge" : "skip";
|
|
9476
|
+
if (conflictAction === "merge") {
|
|
9477
|
+
if (jsonFormat) {
|
|
9478
|
+
if (!isPlainObject(incoming)) throw new Error(`Cannot merge editor config: ${displayPath} incoming value is not JSON`);
|
|
9479
|
+
mergeAndWriteEditorConfig(filePath, incoming, fileName, displayPath, silent);
|
|
9480
|
+
} else writeTextEditorConfig(filePath, incoming, displayPath, silent);
|
|
9481
|
+
} else if (!silent) log.info(`Skipped writing ${displayPath}`);
|
|
9326
9482
|
continue;
|
|
9327
9483
|
}
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9484
|
+
if (jsonFormat) {
|
|
9485
|
+
if (!isPlainObject(incoming)) throw new Error(`Cannot write editor config: ${editorConfig.targetDir}/${fileName} must be JSON`);
|
|
9486
|
+
writeJsonFile(filePath, incoming);
|
|
9487
|
+
} else writeTextEditorConfig(filePath, incoming, `${editorConfig.targetDir}/${fileName}`, silent);
|
|
9488
|
+
if (!silent) log.success(`Wrote editor config to ${editorConfig.targetDir}/${fileName}`);
|
|
9331
9489
|
}
|
|
9332
9490
|
}
|
|
9333
|
-
|
|
9334
|
-
const
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9491
|
+
function isJsonLikeFile(fileName) {
|
|
9492
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
9493
|
+
return ext === ".json" || ext === ".jsonc";
|
|
9494
|
+
}
|
|
9495
|
+
function writeTextEditorConfig(filePath, incoming, displayPath, silent = false) {
|
|
9496
|
+
if (typeof incoming !== "string") throw new Error(`Cannot write editor config: ${displayPath} must be text content`);
|
|
9497
|
+
if ((fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf-8") : void 0) === incoming) {
|
|
9498
|
+
if (!silent) log.info(`No changes needed for ${displayPath}`);
|
|
9338
9499
|
return;
|
|
9339
9500
|
}
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
const
|
|
9355
|
-
if (!
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
const symlinkTarget = path.relative(path.dirname(destinationPath), agentsPath);
|
|
9362
|
-
const existing = await getExistingPathKind(destinationPath);
|
|
9363
|
-
if (existing === "file") return false;
|
|
9364
|
-
if (existing === "symlink") {
|
|
9365
|
-
const currentLink = await fsPromises.readlink(destinationPath);
|
|
9366
|
-
if (path.resolve(path.dirname(destinationPath), currentLink) === agentsPath) {
|
|
9367
|
-
if (!silent) log.info(`Skipped linking ${targetPath} (already linked to ${AGENT_STANDARD_PATH})`);
|
|
9368
|
-
return true;
|
|
9369
|
-
}
|
|
9370
|
-
await fsPromises.unlink(destinationPath);
|
|
9501
|
+
fs.writeFileSync(filePath, incoming, "utf-8");
|
|
9502
|
+
}
|
|
9503
|
+
function normalizeEditorSelection(editorId) {
|
|
9504
|
+
if (!editorId) return [];
|
|
9505
|
+
return [...new Set(Array.isArray(editorId) ? editorId : [editorId])];
|
|
9506
|
+
}
|
|
9507
|
+
/**
|
|
9508
|
+
* Merge incoming settings into an existing editor JSON/JSONC file by patching the
|
|
9509
|
+
* original text with `jsonc-parser` instead of re-serializing a merged object.
|
|
9510
|
+
* This preserves comments, key order, trailing commas, and untouched formatting.
|
|
9511
|
+
* Existing values always win; only missing keys/branches are inserted.
|
|
9512
|
+
*/
|
|
9513
|
+
function mergeAndWriteEditorConfig(filePath, incoming, fileName, displayPath, silent = false) {
|
|
9514
|
+
const originalText = fs.readFileSync(filePath, "utf-8");
|
|
9515
|
+
const existing = parse(originalText);
|
|
9516
|
+
if (!isPlainObject(existing)) throw new Error(`Cannot merge editor config: ${displayPath} is not a JSON object`);
|
|
9517
|
+
const formattingOptions = detectFormattingOptions(originalText);
|
|
9518
|
+
const newText = fileName === "extensions.json" ? mergeExtensionsText(originalText, existing, incoming, formattingOptions) : mergeSettingsText(originalText, existing, incoming, formattingOptions);
|
|
9519
|
+
if (newText === originalText) {
|
|
9520
|
+
if (!silent) log.info(`No changes needed for ${displayPath}`);
|
|
9521
|
+
return;
|
|
9371
9522
|
}
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9523
|
+
fs.writeFileSync(filePath, newText, "utf-8");
|
|
9524
|
+
if (!silent) log.success(`Merged editor config into ${displayPath}`);
|
|
9525
|
+
}
|
|
9526
|
+
function isPlainObject(value) {
|
|
9527
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9528
|
+
}
|
|
9529
|
+
/** Apply a single `jsonc-parser` modification to `text` and return the patched text. */
|
|
9530
|
+
function applyJsoncEdit(text, path, value, options) {
|
|
9531
|
+
return applyEdits(text, modify(text, path, value, options));
|
|
9532
|
+
}
|
|
9533
|
+
/**
|
|
9534
|
+
* Deep-merge missing keys from `incoming` into the existing text. Inserts a whole
|
|
9535
|
+
* branch when it is absent, and recurses only when both sides are non-array objects
|
|
9536
|
+
* so comments inside existing branches are preserved.
|
|
9537
|
+
*/
|
|
9538
|
+
function mergeSettingsText(text, existing, incoming, formattingOptions) {
|
|
9539
|
+
let currentText = text;
|
|
9540
|
+
const insertMissing = (existingNode, incomingNode, basePath) => {
|
|
9541
|
+
for (const [key, value] of Object.entries(incomingNode)) {
|
|
9542
|
+
const fullPath = [...basePath, key];
|
|
9543
|
+
if (!(key in existingNode)) currentText = applyJsoncEdit(currentText, fullPath, value, { formattingOptions });
|
|
9544
|
+
else if (isPlainObject(existingNode[key]) && isPlainObject(value)) insertMissing(existingNode[key], value, fullPath);
|
|
9379
9545
|
}
|
|
9380
|
-
|
|
9546
|
+
};
|
|
9547
|
+
insertMissing(existing, incoming, []);
|
|
9548
|
+
return currentText;
|
|
9549
|
+
}
|
|
9550
|
+
/**
|
|
9551
|
+
* For `extensions.json`, append missing recommendations without rebuilding the array,
|
|
9552
|
+
* so comments inside the array survive. Existing entries always win.
|
|
9553
|
+
*/
|
|
9554
|
+
function mergeExtensionsText(text, existing, incoming, formattingOptions) {
|
|
9555
|
+
const incomingRecs = Array.isArray(incoming["recommendations"]) ? incoming["recommendations"] : [];
|
|
9556
|
+
const existingValue = existing["recommendations"];
|
|
9557
|
+
if (!("recommendations" in existing)) return applyJsoncEdit(text, ["recommendations"], incomingRecs, { formattingOptions });
|
|
9558
|
+
if (!Array.isArray(existingValue)) return text;
|
|
9559
|
+
const existingRecs = new Set(existingValue);
|
|
9560
|
+
let currentText = text;
|
|
9561
|
+
let nextIndex = existingValue.length;
|
|
9562
|
+
for (const rec of incomingRecs) {
|
|
9563
|
+
if (existingRecs.has(rec)) continue;
|
|
9564
|
+
currentText = applyJsoncEdit(currentText, ["recommendations", nextIndex], rec, {
|
|
9565
|
+
formattingOptions,
|
|
9566
|
+
isArrayInsertion: true
|
|
9567
|
+
});
|
|
9568
|
+
nextIndex++;
|
|
9381
9569
|
}
|
|
9382
|
-
|
|
9383
|
-
return true;
|
|
9570
|
+
return currentText;
|
|
9384
9571
|
}
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9572
|
+
function resolveEditorId(editor) {
|
|
9573
|
+
const normalized = editor.trim().toLowerCase();
|
|
9574
|
+
const match = EDITORS.find((option) => option.id === normalized || option.label.toLowerCase() === normalized);
|
|
9575
|
+
if (match) return match.id;
|
|
9576
|
+
const aliasMatch = EDITOR_ALIASES.find((option) => option.id === normalized);
|
|
9577
|
+
if (aliasMatch) {
|
|
9578
|
+
log.warn(`--editor ${aliasMatch.id} was passed; use --editor ${aliasMatch.alias} instead, as it's the canonical ID for that editor.`);
|
|
9579
|
+
return aliasMatch.alias;
|
|
9580
|
+
}
|
|
9388
9581
|
}
|
|
9389
|
-
function
|
|
9390
|
-
const
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
end: endMarkerIndex + endMarker.length
|
|
9397
|
-
};
|
|
9582
|
+
function resolveEditorIds(editors) {
|
|
9583
|
+
const editorIds = editors.flatMap((editor) => {
|
|
9584
|
+
const editorId = resolveEditorId(editor);
|
|
9585
|
+
return editorId ? [editorId] : [];
|
|
9586
|
+
});
|
|
9587
|
+
const uniqueEditorIds = [...new Set(editorIds)];
|
|
9588
|
+
return uniqueEditorIds.length === 0 ? void 0 : uniqueEditorIds;
|
|
9398
9589
|
}
|
|
9399
9590
|
//#endregion
|
|
9400
|
-
export {
|
|
9591
|
+
export { isBingoTemplate as A, warnPackageLevelPrettier as B, mergeViteConfigFiles as C, configureYarnNodeModulesMode as D, ensureVitePlusBootstrap as E, hasFrameworkShim as F, promptEslintMigration as G, detectEslintProject as H, confirmPrettierMigration as I, warnPackageLevelEslint as J, warnIncompatibleEslintIntegration as K, detectPrettierProject as L, updateWorkspaceConfig as M, addFrameworkShim as N, detectYarnPnpMode as O, detectFramework as P, migratePrettierToOxfmt as R, injectLintTypeCheckDefaults as S, detectVitePlusBootstrapPending as T, detectIncompatibleEslintIntegration as U, confirmEslintMigration as V, migrateEslintToOxlint as W, checkVitestVersion as X, checkViteVersion as Y, preflightGitHooksSetup as _, selectEditors as a, initGitRepository as b, rewriteMonorepoProject as c, finalizeCoreMigrationForExistingVitePlus as d, detectNodeVersionManagerFile as f, installGitHooks as g, detectLegacyGitHooksMigrationCandidate as h, selectEditor as i, updatePackageJsonWithDeps as j, detectWorkspace$1 as k, rewriteStandaloneProject as l, setPackageManager as m, detectExistingEditors as n, writeEditorConfigs as o, migrateNodeVersionManagerFile as p, warnLegacyEslintConfig as q, isJsonLikeFile as r, rewriteMonorepo as s, detectEditorConflicts as t, detectPendingCoreMigration as u, shouldSkipStagedMigrationForHooks as v, collectToolchainVersionChanges as w, injectCreateDefaultTemplate as x, findGitRoot as y, promptPrettierMigration as z };
|