cmux/node_modules/@vercel/build-utils/dist/fs/run-user-scripts.js
2026-01-29 17:36:26 -08:00

1135 lines
39 KiB
JavaScript

"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var run_user_scripts_exports = {};
__export(run_user_scripts_exports, {
PNPM_10_PREFERRED_AT: () => PNPM_10_PREFERRED_AT,
detectPackageManager: () => detectPackageManager,
execCommand: () => execCommand,
findPackageJson: () => findPackageJson,
getEnvForPackageManager: () => getEnvForPackageManager,
getNodeBinPath: () => getNodeBinPath,
getNodeBinPaths: () => getNodeBinPaths,
getNodeVersion: () => getNodeVersion,
getPathForPackageManager: () => getPathForPackageManager,
getPathOverrideForPackageManager: () => getPathOverrideForPackageManager,
getScriptName: () => getScriptName,
getSpawnOptions: () => getSpawnOptions,
installDependencies: () => installDependencies,
resetCustomInstallCommandSet: () => resetCustomInstallCommandSet,
runBundleInstall: () => runBundleInstall,
runCustomInstallCommand: () => runCustomInstallCommand,
runNpmInstall: () => runNpmInstall,
runPackageJsonScript: () => runPackageJsonScript,
runPipInstall: () => runPipInstall,
runShellScript: () => runShellScript,
scanParentDirs: () => scanParentDirs,
spawnAsync: () => spawnAsync,
spawnCommand: () => spawnCommand,
traverseUpDirectories: () => traverseUpDirectories,
turboVersionSpecifierSupportsCorepack: () => turboVersionSpecifierSupportsCorepack,
usingCorepack: () => usingCorepack,
walkParentDirs: () => walkParentDirs
});
module.exports = __toCommonJS(run_user_scripts_exports);
var import_assert = __toESM(require("assert"));
var import_fs_extra = __toESM(require("fs-extra"));
var import_path = __toESM(require("path"));
var import_async_sema = __toESM(require("async-sema"));
var import_cross_spawn = __toESM(require("cross-spawn"));
var import_semver = require("semver");
var import_util = require("util");
var import_debug = __toESM(require("../debug"));
var import_errors = require("../errors");
var import_node_version = require("./node-version");
var import_read_config_file = require("./read-config-file");
var import_clone_env = require("../clone-env");
var import_json5 = __toESM(require("json5"));
var import_js_yaml = __toESM(require("js-yaml"));
const NO_OVERRIDE = {
detectedLockfile: void 0,
detectedPackageManager: void 0,
path: void 0
};
function spawnAsync(command, args, opts = {}) {
return new Promise((resolve, reject) => {
const stderrLogs = [];
opts = { stdio: "inherit", ...opts };
const child = (0, import_cross_spawn.default)(command, args, opts);
if (opts.stdio === "pipe" && child.stderr) {
child.stderr.on("data", (data) => stderrLogs.push(data));
}
child.on("error", reject);
child.on("close", (code, signal) => {
if (code === 0 || opts.ignoreNon0Exit) {
return resolve();
}
const cmd = opts.prettyCommand ? `Command "${opts.prettyCommand}"` : "Command";
reject(
new import_errors.NowBuildError({
code: `BUILD_UTILS_SPAWN_${code || signal}`,
message: opts.stdio === "inherit" ? `${cmd} exited with ${code || signal}` : stderrLogs.map((line) => line.toString()).join("")
})
);
});
});
}
function spawnCommand(command, options = {}) {
const opts = { ...options, prettyCommand: command };
if (process.platform === "win32") {
return (0, import_cross_spawn.default)("cmd.exe", ["/C", command], opts);
}
return (0, import_cross_spawn.default)("sh", ["-c", command], opts);
}
async function execCommand(command, options = {}) {
const opts = { ...options, prettyCommand: command };
if (process.platform === "win32") {
await spawnAsync("cmd.exe", ["/C", command], opts);
} else {
await spawnAsync("sh", ["-c", command], opts);
}
return true;
}
function* traverseUpDirectories({
start,
base
}) {
let current = import_path.default.normalize(start);
const normalizedRoot = base ? import_path.default.normalize(base) : void 0;
while (current) {
yield current;
if (current === normalizedRoot)
break;
const next = import_path.default.join(current, "..");
current = next === current ? void 0 : next;
}
}
async function readProjectRootInfo({
start,
base
}) {
let curRootPackageJsonPath;
for (const dir of traverseUpDirectories({ start, base })) {
const packageJsonPath = import_path.default.join(dir, "package.json");
if (await import_fs_extra.default.pathExists(packageJsonPath)) {
curRootPackageJsonPath = packageJsonPath;
}
}
return curRootPackageJsonPath ? {
packageJson: await import_fs_extra.default.readJson(curRootPackageJsonPath),
rootDir: import_path.default.dirname(curRootPackageJsonPath)
} : void 0;
}
async function getNodeBinPath({
cwd
}) {
const { lockfilePath } = await scanParentDirs(cwd);
const dir = import_path.default.dirname(lockfilePath || cwd);
return import_path.default.join(dir, "node_modules", ".bin");
}
function getNodeBinPaths({
start,
base
}) {
return Array.from(traverseUpDirectories({ start, base })).map(
(dir) => import_path.default.join(dir, "node_modules/.bin")
);
}
async function chmodPlusX(fsPath) {
const s = await import_fs_extra.default.stat(fsPath);
const newMode = s.mode | 64 | 8 | 1;
if (s.mode === newMode)
return;
const base8 = newMode.toString(8).slice(-3);
await import_fs_extra.default.chmod(fsPath, base8);
}
async function runShellScript(fsPath, args = [], spawnOpts) {
(0, import_assert.default)(import_path.default.isAbsolute(fsPath));
const destPath = import_path.default.dirname(fsPath);
await chmodPlusX(fsPath);
const command = `./${import_path.default.basename(fsPath)}`;
await spawnAsync(command, args, {
...spawnOpts,
cwd: destPath,
prettyCommand: command
});
return true;
}
function getSpawnOptions(meta, nodeVersion) {
const opts = {
env: (0, import_clone_env.cloneEnv)(process.env)
};
if ((0, import_node_version.isBunVersion)(nodeVersion)) {
return opts;
}
if (!meta.isDev) {
let found = false;
const oldPath = opts.env.PATH || process.env.PATH || "";
const pathSegments = oldPath.split(import_path.default.delimiter).map((segment) => {
if (/^\/node[0-9]+\/bin/.test(segment)) {
found = true;
return `/node${nodeVersion.major}/bin`;
}
return segment;
});
if (!found) {
pathSegments.unshift(`/node${nodeVersion.major}/bin`);
}
opts.env.PATH = pathSegments.filter(Boolean).join(import_path.default.delimiter);
}
return opts;
}
async function getNodeVersion(destPath, fallbackVersion = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION, config = {}, meta = {}, availableVersions = (0, import_node_version.getAvailableNodeVersions)()) {
if (config.bunVersion) {
return (0, import_node_version.getSupportedBunVersion)(config.bunVersion);
}
const latestVersion = (0, import_node_version.getLatestNodeVersion)(availableVersions);
if (meta.isDev) {
latestVersion.runtime = "nodejs";
return latestVersion;
}
const { packageJson } = await findPackageJson(destPath, true);
const configuredVersion = config.nodeVersion || fallbackVersion;
const packageJsonVersion = packageJson?.engines?.node;
const supportedNodeVersion = await (0, import_node_version.getSupportedNodeVersion)(
packageJsonVersion || configuredVersion,
!packageJsonVersion,
availableVersions
);
if (packageJson?.engines?.node) {
const { node } = packageJson.engines;
if (configuredVersion && !(0, import_semver.intersects)(configuredVersion, supportedNodeVersion.range)) {
console.warn(
`Warning: Due to "engines": { "node": "${node}" } in your \`package.json\` file, the Node.js Version defined in your Project Settings ("${configuredVersion}") will not apply, Node.js Version "${supportedNodeVersion.range}" will be used instead. Learn More: https://vercel.link/node-version`
);
}
if ((0, import_semver.coerce)(node)?.raw === node) {
console.warn(
`Warning: Detected "engines": { "node": "${node}" } in your \`package.json\` with major.minor.patch, but only major Node.js Version can be selected. Learn More: https://vercel.link/node-version`
);
} else if ((0, import_semver.validRange)(node) && (0, import_semver.intersects)(`${latestVersion.major + 1}.x`, node)) {
console.warn(
`Warning: Detected "engines": { "node": "${node}" } in your \`package.json\` that will automatically upgrade when a new major Node.js Version is released. Learn More: https://vercel.link/node-version`
);
}
}
return supportedNodeVersion;
}
async function findPackageJson(destPath, readPackageJson = false, base = "/") {
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
const pkgJsonPath = await walkParentDirs({
base,
start: destPath,
filename: "package.json"
});
let packageJson;
if (readPackageJson && pkgJsonPath) {
try {
packageJson = JSON.parse(await import_fs_extra.default.readFile(pkgJsonPath, "utf8"));
} catch (err) {
throw new Error(
`Could not read ${pkgJsonPath}: ${err.message}.`
);
}
}
return {
packageJsonPath: pkgJsonPath || void 0,
packageJson
};
}
async function scanParentDirs(destPath, readPackageJson = false, base = "/") {
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
const { packageJsonPath: pkgJsonPath, packageJson } = await findPackageJson(
destPath,
readPackageJson,
base
);
const {
paths: [
yarnLockPath,
npmLockPath,
pnpmLockPath,
bunLockTextPath,
bunLockBinPath,
vltLockPath
],
packageJsonPackageManager
} = await walkParentDirsMulti({
base,
start: destPath,
filenames: [
"yarn.lock",
"package-lock.json",
"pnpm-lock.yaml",
"bun.lock",
"bun.lockb",
"vlt-lock.json"
]
});
let lockfilePath;
let lockfileVersion;
let cliType;
const bunLockPath = bunLockTextPath ?? bunLockBinPath;
const [packageLockJson, pnpmLockYaml, bunLock, yarnLock, vltLock] = await Promise.all([
npmLockPath ? (0, import_read_config_file.readConfigFile)(npmLockPath) : null,
pnpmLockPath ? (0, import_read_config_file.readConfigFile)(pnpmLockPath) : null,
bunLockPath ? import_fs_extra.default.readFile(bunLockPath) : null,
yarnLockPath ? import_fs_extra.default.readFile(yarnLockPath, "utf8") : null,
vltLockPath ? (0, import_read_config_file.readConfigFile)(vltLockPath) : null
]);
const rootProjectInfo = readPackageJson ? await readProjectRootInfo({
base,
start: destPath
}) : void 0;
const turboVersionRange = rootProjectInfo?.packageJson?.devDependencies?.turbo;
const turboSupportsCorepackHome = turboVersionRange ? await checkTurboSupportsCorepack(
turboVersionRange,
rootProjectInfo?.rootDir
) : void 0;
if (bunLock && yarnLock) {
cliType = "bun";
lockfilePath = bunLockPath;
lockfileVersion = bunLockTextPath ? 1 : 0;
} else if (yarnLock) {
cliType = "yarn";
lockfilePath = yarnLockPath;
lockfileVersion = parseYarnLockVersion(yarnLock);
} else if (pnpmLockYaml) {
cliType = "pnpm";
lockfilePath = pnpmLockPath;
lockfileVersion = Number(pnpmLockYaml.lockfileVersion);
} else if (packageLockJson) {
cliType = "npm";
lockfilePath = npmLockPath;
lockfileVersion = packageLockJson.lockfileVersion;
} else if (bunLock) {
cliType = "bun";
lockfilePath = bunLockPath;
lockfileVersion = bunLockTextPath ? 1 : 0;
} else if (vltLock) {
cliType = "vlt";
lockfilePath = vltLockPath;
} else {
cliType = detectPackageManagerNameWithoutLockfile(
packageJsonPackageManager,
turboSupportsCorepackHome
);
}
const packageJsonPath = pkgJsonPath || void 0;
return {
cliType,
packageJson,
packageJsonPackageManager,
lockfilePath,
lockfileVersion,
packageJsonPath,
turboSupportsCorepackHome
};
}
function parseYarnLockVersion(yarnLock) {
if (!yarnLock.includes("__metadata:")) {
return 1;
}
try {
const metadata = import_js_yaml.default.load(yarnLock).__metadata;
return Number(metadata.version);
} catch {
return void 0;
}
}
async function checkTurboSupportsCorepack(turboVersionRange, rootDir) {
if (turboVersionSpecifierSupportsCorepack(turboVersionRange)) {
return true;
}
const turboJsonPath = import_path.default.join(rootDir, "turbo.json");
const turboJsoncPath = import_path.default.join(rootDir, "turbo.jsonc");
const [turboJsonExists, turboJsoncExists] = await Promise.all([
import_fs_extra.default.pathExists(turboJsonPath),
import_fs_extra.default.pathExists(turboJsoncPath)
]);
let turboJson = null;
let turboConfigPath = null;
if (turboJsonExists) {
turboConfigPath = turboJsonPath;
} else if (turboJsoncExists) {
turboConfigPath = turboJsoncPath;
}
if (turboConfigPath) {
try {
turboJson = import_json5.default.parse(await import_fs_extra.default.readFile(turboConfigPath, "utf8"));
} catch (err) {
console.warn(
`WARNING: Failed to parse ${import_path.default.basename(turboConfigPath)}`
);
}
}
const turboJsonIncludesCorepackHome = turboJson !== null && typeof turboJson === "object" && "globalPassThroughEnv" in turboJson && Array.isArray(turboJson.globalPassThroughEnv) && turboJson.globalPassThroughEnv.includes("COREPACK_HOME");
return turboJsonIncludesCorepackHome;
}
function turboVersionSpecifierSupportsCorepack(turboVersionSpecifier) {
if (!(0, import_semver.validRange)(turboVersionSpecifier)) {
return false;
}
const versionSupportingCorepack = "2.1.3";
const minTurboBeingUsed = (0, import_semver.minVersion)(turboVersionSpecifier);
if (!minTurboBeingUsed) {
return false;
}
return (0, import_semver.gte)(minTurboBeingUsed, versionSupportingCorepack);
}
function detectPackageManagerNameWithoutLockfile(packageJsonPackageManager, turboSupportsCorepackHome) {
if (usingCorepack(
process.env,
packageJsonPackageManager,
turboSupportsCorepackHome
)) {
const corepackPackageManager = validateVersionSpecifier(
packageJsonPackageManager
);
switch (corepackPackageManager?.packageName) {
case "npm":
case "pnpm":
case "yarn":
case "bun":
return corepackPackageManager.packageName;
case void 0:
return "npm";
default:
throw new Error(
`Unknown package manager "${corepackPackageManager?.packageName}". Change your package.json "packageManager" field to a known package manager: npm, pnpm, yarn, bun.`
);
}
}
return "npm";
}
function usingCorepack(env, packageJsonPackageManager, turboSupportsCorepackHome) {
if (env.ENABLE_EXPERIMENTAL_COREPACK !== "1" || packageJsonPackageManager === void 0) {
return false;
}
if (turboSupportsCorepackHome === false) {
console.warn(
"Warning: Disabling corepack because it may break your project. To use corepack, either upgrade to `turbo@2.1.3+` or include `COREPACK_HOME` in `turbo.json#globalPassThroughEnv`."
);
return false;
}
return true;
}
async function walkParentDirs({
base,
start,
filename
}) {
(0, import_assert.default)(import_path.default.isAbsolute(base), 'Expected "base" to be absolute path');
(0, import_assert.default)(import_path.default.isAbsolute(start), 'Expected "start" to be absolute path');
for (const dir of traverseUpDirectories({ start, base })) {
const fullPath = import_path.default.join(dir, filename);
if (await import_fs_extra.default.pathExists(fullPath)) {
return fullPath;
}
}
return null;
}
async function walkParentDirsMulti({
base,
start,
filenames
}) {
let packageManager;
for (const dir of traverseUpDirectories({ start, base })) {
const fullPaths = filenames.map((f) => import_path.default.join(dir, f));
const existResults = await Promise.all(
fullPaths.map((f) => import_fs_extra.default.pathExists(f))
);
const foundOneOrMore = existResults.some((b) => b);
const packageJsonPath = import_path.default.join(dir, "package.json");
const packageJson = await import_fs_extra.default.readJSON(packageJsonPath).catch(() => null);
if (packageJson?.packageManager) {
packageManager = packageJson.packageManager;
}
if (foundOneOrMore) {
return {
paths: fullPaths.map((f, i) => existResults[i] ? f : void 0),
packageJsonPackageManager: packageManager
};
}
}
return { paths: [], packageJsonPackageManager: packageManager };
}
function isSet(v) {
return v?.constructor?.name === "Set";
}
function getInstallCommandForPackageManager(packageManager, args) {
switch (packageManager) {
case "npm":
return {
prettyCommand: "npm install",
commandArguments: args.filter((a) => a !== "--prefer-offline").concat(["install", "--no-audit"])
};
case "pnpm":
return {
prettyCommand: "pnpm install",
// PNPM's install command is similar to NPM's but without the audit nonsense
// @see options https://pnpm.io/cli/install
commandArguments: args.filter((a) => a !== "--prefer-offline").concat(["install", "--unsafe-perm"])
};
case "bun":
return {
prettyCommand: "bun install",
// @see options https://bun.sh/docs/cli/install
commandArguments: ["install", ...args]
};
case "yarn":
return {
prettyCommand: "yarn install",
commandArguments: ["install", ...args]
};
case "vlt":
return {
prettyCommand: "vlt install",
commandArguments: ["install", ...args]
};
}
}
async function runInstallCommand({
packageManager,
args,
opts
}) {
const { commandArguments, prettyCommand } = getInstallCommandForPackageManager(packageManager, args);
opts.prettyCommand = prettyCommand;
if (process.env.NPM_ONLY_PRODUCTION) {
commandArguments.push("--production");
}
await spawnAsync(packageManager, commandArguments, opts);
}
function initializeSet(set) {
if (!isSet(set)) {
return /* @__PURE__ */ new Set();
}
return set;
}
function checkIfAlreadyInstalled(runNpmInstallSet, packageJsonPath) {
const initializedRunNpmInstallSet = initializeSet(runNpmInstallSet);
const alreadyInstalled = initializedRunNpmInstallSet.has(packageJsonPath);
initializedRunNpmInstallSet.add(packageJsonPath);
return { alreadyInstalled, runNpmInstallSet: initializedRunNpmInstallSet };
}
const runNpmInstallSema = new import_async_sema.default(1);
let customInstallCommandSet;
function resetCustomInstallCommandSet() {
customInstallCommandSet = void 0;
}
async function runNpmInstall(destPath, args = [], spawnOpts, meta, projectCreatedAt) {
if (meta?.isDev) {
(0, import_debug.default)("Skipping dependency installation because dev mode is enabled");
return false;
}
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
try {
await runNpmInstallSema.acquire();
const {
cliType,
packageJsonPath,
packageJson,
lockfileVersion,
packageJsonPackageManager,
turboSupportsCorepackHome
} = await scanParentDirs(destPath, true);
if (!packageJsonPath) {
(0, import_debug.default)(
`Skipping dependency installation because no package.json was found for ${destPath}`
);
return false;
}
const defaultInstall = args.length === 0;
if (meta && packageJsonPath && defaultInstall) {
const { alreadyInstalled, runNpmInstallSet } = checkIfAlreadyInstalled(
meta.runNpmInstallSet,
packageJsonPath
);
if (alreadyInstalled) {
return false;
}
if (process.env.VERCEL_INSTALL_COMPLETED === "1") {
(0, import_debug.default)(
`Skipping dependency installation for ${packageJsonPath} because VERCEL_INSTALL_COMPLETED is set`
);
runNpmInstallSet.add(packageJsonPath);
meta.runNpmInstallSet = runNpmInstallSet;
return false;
}
meta.runNpmInstallSet = runNpmInstallSet;
}
if (cliType === "yarn") {
const yarnVersion = detectYarnVersion(lockfileVersion);
if (["yarn@3.x", "yarn@4.x"].includes(yarnVersion)) {
await spawnAsync(
"yarn",
["config", "set", "enableGlobalCache", "false"],
{ cwd: destPath }
);
}
}
const installTime = Date.now();
console.log("Installing dependencies...");
(0, import_debug.default)(`Installing to ${destPath}`);
const opts = { cwd: destPath, ...spawnOpts };
const env = (0, import_clone_env.cloneEnv)(opts.env || process.env);
delete env.NODE_ENV;
opts.env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager,
env,
packageJsonEngines: packageJson?.engines,
turboSupportsCorepackHome,
projectCreatedAt
});
const maySeeDynamicRequireYarnBug = process.env?.ENABLE_EXPERIMENTAL_COREPACK && packageJson?.packageManager?.startsWith("yarn") && packageJson?.type === "module";
if (maySeeDynamicRequireYarnBug) {
console.warn(
`Warning: This project may see "Error: Dynamic require of "util" is not supported". To avoid this error, remove \`"type": "module"\` from your package.json file, or use \`yarnPath\` instead of Corepack. Learn more: https://vercel.com/docs/errors/error-list#yarn-dynamic-require-of-util-is-not-supported`
);
}
await runInstallCommand({
packageManager: cliType,
args,
opts
});
(0, import_debug.default)(`Install complete [${Date.now() - installTime}ms]`);
return true;
} finally {
runNpmInstallSema.release();
}
}
function getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager,
env,
packageJsonEngines,
turboSupportsCorepackHome,
projectCreatedAt
}) {
const corepackEnabled = usingCorepack(
env,
packageJsonPackageManager,
turboSupportsCorepackHome
);
const {
detectedLockfile,
detectedPackageManager,
path: newPath
} = getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackPackageManager: packageJsonPackageManager,
corepackEnabled,
packageJsonEngines,
projectCreatedAt
});
if (corepackEnabled) {
(0, import_debug.default)(
`Detected corepack use for "${packageJsonPackageManager}". Not overriding package manager version.`
);
} else {
(0, import_debug.default)(
`Detected ${detectedPackageManager}. Added "${newPath}" to path. Based on assumed package manager "${cliType}", lockfile "${detectedLockfile}", and lockfileVersion "${lockfileVersion}"`
);
}
const newEnv = {
...env
};
const alreadyInPath = (newPath2) => {
const oldPath = env.PATH ?? "";
return oldPath.split(import_path.default.delimiter).includes(newPath2);
};
if (newPath && !alreadyInPath(newPath)) {
const oldPath = env.PATH + "";
newEnv.PATH = `${newPath}${import_path.default.delimiter}${oldPath}`;
if (detectedLockfile && detectedPackageManager) {
const detectedV9PnpmLockfile = detectedLockfile === "pnpm-lock.yaml" && lockfileVersion === 9;
const pnpm10UsingPackageJsonPackageManager = detectedPackageManager === "pnpm@10.x" && packageJsonPackageManager;
if (pnpm10UsingPackageJsonPackageManager) {
const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
console.log(
`Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager} with package.json#packageManager ${packageJsonPackageManager}`
);
} else if (detectedV9PnpmLockfile) {
const otherVersion = detectedPackageManager === "pnpm@10.x" ? `pnpm@9.x` : `pnpm@10.x`;
console.log(
`Detected \`${detectedLockfile}\` ${lockfileVersion} which may be generated by pnpm@9.x or pnpm@10.x
Using ${detectedPackageManager} based on project creation date
To use ${otherVersion}, manually opt in using corepack (https://vercel.com/docs/deployments/configure-a-build#corepack)`
);
} else {
const versionString = cliType === "pnpm" ? `version ${lockfileVersion} ` : "";
console.log(
`Detected \`${detectedLockfile}\` ${versionString}generated by ${detectedPackageManager}`
);
}
}
}
if (cliType === "yarn" && !env.YARN_NODE_LINKER) {
newEnv.YARN_NODE_LINKER = "node-modules";
}
return newEnv;
}
const PNPM_10_PREFERRED_AT = /* @__PURE__ */ new Date("2025-02-27T20:00:00Z");
function detectPnpmVersion(lockfileVersion, projectCreatedAt) {
switch (true) {
case lockfileVersion === void 0:
return "not found";
case lockfileVersion === 5.3:
return "pnpm 6";
case lockfileVersion === 5.4:
return "pnpm 7";
case (lockfileVersion === 6 || lockfileVersion === 6.1):
return "pnpm 8";
case lockfileVersion === 7:
return "pnpm 9";
case lockfileVersion === 9: {
const projectPrefersPnpm10 = projectCreatedAt && projectCreatedAt >= PNPM_10_PREFERRED_AT.getTime();
return projectPrefersPnpm10 ? "pnpm 10" : "pnpm 9";
}
default:
return "not found";
}
}
function detectYarnVersion(lockfileVersion) {
if (lockfileVersion) {
if ([1].includes(lockfileVersion)) {
return "yarn@1.x";
} else if ([4, 5].includes(lockfileVersion)) {
return "yarn@2.x";
} else if ([6, 7].includes(lockfileVersion)) {
return "yarn@3.x";
} else if ([8].includes(lockfileVersion)) {
return "yarn@4.x";
}
}
return "unknown yarn";
}
function validLockfileForPackageManager(cliType, lockfileVersion, packageManagerVersion) {
const packageManagerMajorVersion = packageManagerVersion.major;
switch (cliType) {
case "npm":
case "bun":
case "yarn":
case "vlt":
return true;
case "pnpm":
switch (packageManagerMajorVersion) {
case 10:
return lockfileVersion === 9;
case 9:
if ("9.0.0" === packageManagerVersion.version && lockfileVersion === 6) {
return false;
}
return [6, 7, 9].includes(lockfileVersion);
case 8:
return [6, 6.1].includes(lockfileVersion);
case 7:
return [5.3, 5.4].includes(lockfileVersion);
case 6:
return [5.3, 5.4].includes(lockfileVersion);
default:
return true;
}
}
}
function getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackPackageManager,
corepackEnabled = true,
packageJsonEngines,
projectCreatedAt
}) {
const detectedPackageManger = detectPackageManager(
cliType,
lockfileVersion,
projectCreatedAt
);
const usingCorepack2 = corepackPackageManager && corepackEnabled;
if (usingCorepack2) {
validateCorepackPackageManager(
cliType,
lockfileVersion,
corepackPackageManager,
packageJsonEngines?.pnpm
);
return NO_OVERRIDE;
}
if (cliType === "pnpm" && packageJsonEngines?.pnpm) {
const usingDetected = detectedPackageManger?.pnpmVersionRange !== "10.x" || !corepackPackageManager;
if (usingDetected) {
checkEnginesPnpmAgainstDetected(
packageJsonEngines.pnpm,
detectedPackageManger
);
}
}
return detectedPackageManger ?? NO_OVERRIDE;
}
function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
if (detectedPackageManger?.pnpmVersionRange && (0, import_semver.validRange)(detectedPackageManger.pnpmVersionRange) && (0, import_semver.validRange)(enginesPnpm)) {
if (!(0, import_semver.intersects)(detectedPackageManger.pnpmVersionRange, enginesPnpm)) {
throw new Error(
`Detected pnpm "${detectedPackageManger.pnpmVersionRange}" is not compatible with the engines.pnpm "${enginesPnpm}" in your package.json. Either enable corepack with a valid package.json#packageManager value (https://vercel.com/docs/deployments/configure-a-build#corepack) or remove your package.json#engines.pnpm.`
);
}
}
console.warn(
`Using package.json#engines.pnpm without corepack and package.json#packageManager could lead to failed builds with ERR_PNPM_UNSUPPORTED_ENGINE. Learn more: https://vercel.com/docs/errors/error-list#pnpm-engine-unsupported`
);
}
function validateCorepackPackageManager(cliType, lockfileVersion, corepackPackageManager, enginesPnpmVersionRange) {
const validatedCorepackPackageManager = validateVersionSpecifier(
corepackPackageManager
);
if (!validatedCorepackPackageManager) {
throw new Error(
`Intended corepack defined package manager "${corepackPackageManager}" is not a valid semver value.`
);
}
if (cliType !== validatedCorepackPackageManager.packageName) {
throw new Error(
`Detected package manager "${cliType}" does not match intended corepack defined package manager "${validatedCorepackPackageManager.packageName}". Change your lockfile or "package.json#packageManager" value to match.`
);
}
if (cliType === "pnpm" && enginesPnpmVersionRange) {
const pnpmWithinEngineRange = (0, import_semver.satisfies)(
validatedCorepackPackageManager.packageVersion,
enginesPnpmVersionRange
);
if (!pnpmWithinEngineRange) {
throw new Error(
`The version of pnpm specified in package.json#packageManager (${validatedCorepackPackageManager.packageVersion}) must satisfy the version range in package.json#engines.pnpm (${enginesPnpmVersionRange}).`
);
}
}
if (lockfileVersion) {
const lockfileValid = validLockfileForPackageManager(
cliType,
lockfileVersion,
validatedCorepackPackageManager.packageVersion
);
if (!lockfileValid) {
throw new Error(
`Detected lockfile "${lockfileVersion}" which is not compatible with the intended corepack package manager "${corepackPackageManager}". Update your lockfile or change to a compatible corepack version.`
);
}
}
}
function validateVersionSpecifier(version) {
if (!version) {
return void 0;
}
const [before, after, ...extra] = version.split("@");
if (extra.length) {
return void 0;
}
if (!before) {
return void 0;
}
if (!after) {
return void 0;
}
const packageVersion = (0, import_semver.parse)(after);
if (!packageVersion) {
return void 0;
}
return {
packageName: before,
packageVersion
};
}
function detectPackageManager(cliType, lockfileVersion, projectCreatedAt) {
switch (cliType) {
case "npm":
return void 0;
case "pnpm":
switch (detectPnpmVersion(lockfileVersion, projectCreatedAt)) {
case "pnpm 7":
return {
path: "/pnpm7/node_modules/.bin",
detectedLockfile: "pnpm-lock.yaml",
detectedPackageManager: "pnpm@7.x",
pnpmVersionRange: "7.x"
};
case "pnpm 8":
return {
path: "/pnpm8/node_modules/.bin",
detectedLockfile: "pnpm-lock.yaml",
detectedPackageManager: "pnpm@8.x",
pnpmVersionRange: "8.x"
};
case "pnpm 9":
return {
path: "/pnpm9/node_modules/.bin",
detectedLockfile: "pnpm-lock.yaml",
detectedPackageManager: "pnpm@9.x",
pnpmVersionRange: "9.x"
};
case "pnpm 10":
return {
path: "/pnpm10/node_modules/.bin",
detectedLockfile: "pnpm-lock.yaml",
detectedPackageManager: "pnpm@10.x",
pnpmVersionRange: "10.x"
};
case "pnpm 6":
return {
path: "/pnpm6/node_modules/.bin",
detectedLockfile: "pnpm-lock.yaml",
detectedPackageManager: "pnpm@6.x",
pnpmVersionRange: "6.x"
};
default:
return void 0;
}
case "bun":
return {
path: "/bun1",
detectedLockfile: lockfileVersion === 0 ? "bun.lockb" : "bun.lock",
detectedPackageManager: "bun@1.x"
};
case "yarn":
return {
path: void 0,
detectedLockfile: "yarn.lock",
detectedPackageManager: detectYarnVersion(lockfileVersion)
};
case "vlt":
return {
path: void 0,
detectedLockfile: "vlt-lock.json",
detectedPackageManager: "vlt@0.x"
};
}
}
function getPathForPackageManager({
cliType,
lockfileVersion,
env
}) {
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === "1";
let overrides = getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackPackageManager: void 0
});
if (corepackEnabled) {
overrides = NO_OVERRIDE;
}
const alreadyInPath = (newPath) => {
const oldPath = env.PATH ?? "";
return oldPath.split(import_path.default.delimiter).includes(newPath);
};
switch (true) {
case (cliType === "yarn" && !env.YARN_NODE_LINKER):
return { ...overrides, yarnNodeLinker: "node-modules" };
case alreadyInPath(overrides.path ?? ""):
return {
detectedLockfile: void 0,
detectedPackageManager: void 0,
path: void 0,
yarnNodeLinker: void 0
};
default:
return { ...overrides, yarnNodeLinker: void 0 };
}
}
async function runCustomInstallCommand({
destPath,
installCommand,
spawnOpts,
projectCreatedAt
}) {
const normalizedPath = import_path.default.normalize(destPath);
const { alreadyInstalled, runNpmInstallSet } = checkIfAlreadyInstalled(
customInstallCommandSet,
normalizedPath
);
customInstallCommandSet = runNpmInstallSet;
if (alreadyInstalled) {
(0, import_debug.default)(
`Skipping custom install command for ${normalizedPath} because it was already run`
);
return false;
}
if (process.env.VERCEL_INSTALL_COMPLETED === "1") {
(0, import_debug.default)(
`Skipping custom install command for ${normalizedPath} because VERCEL_INSTALL_COMPLETED is set`
);
return false;
}
console.log(`Running "install" command: \`${installCommand}\`...`);
const {
cliType,
lockfileVersion,
packageJson,
packageJsonPackageManager,
turboSupportsCorepackHome
} = await scanParentDirs(destPath, true);
const env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager,
env: spawnOpts?.env || {},
packageJsonEngines: packageJson?.engines,
turboSupportsCorepackHome,
projectCreatedAt
});
(0, import_debug.default)(`Running with $PATH:`, env?.PATH || "");
await execCommand(installCommand, {
...spawnOpts,
env,
cwd: destPath
});
return true;
}
async function runPackageJsonScript(destPath, scriptNames, spawnOpts, projectCreatedAt) {
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
const {
packageJson,
cliType,
lockfileVersion,
packageJsonPackageManager,
turboSupportsCorepackHome
} = await scanParentDirs(destPath, true);
const scriptName = getScriptName(
packageJson,
typeof scriptNames === "string" ? [scriptNames] : scriptNames
);
if (!scriptName)
return false;
(0, import_debug.default)("Running user script...");
const runScriptTime = Date.now();
const opts = {
cwd: destPath,
...spawnOpts,
env: getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager,
env: (0, import_clone_env.cloneEnv)(process.env, spawnOpts?.env),
packageJsonEngines: packageJson?.engines,
turboSupportsCorepackHome,
projectCreatedAt
})
};
if (cliType === "npm") {
opts.prettyCommand = `npm run ${scriptName}`;
} else if (cliType === "pnpm") {
opts.prettyCommand = `pnpm run ${scriptName}`;
} else if (cliType === "bun") {
opts.prettyCommand = `bun run ${scriptName}`;
} else if (cliType === "vlt") {
opts.prettyCommand = `vlt run ${scriptName}`;
} else {
opts.prettyCommand = `yarn run ${scriptName}`;
}
console.log(`Running "${opts.prettyCommand}"`);
await spawnAsync(cliType, ["run", scriptName], opts);
(0, import_debug.default)(`Script complete [${Date.now() - runScriptTime}ms]`);
return true;
}
async function runBundleInstall(destPath, args = [], spawnOpts, meta) {
if (meta && meta.isDev) {
(0, import_debug.default)("Skipping dependency installation because dev mode is enabled");
return;
}
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: "bundle install" };
await spawnAsync("bundle", args.concat(["install"]), opts);
}
async function runPipInstall(destPath, args = [], spawnOpts, meta) {
if (meta && meta.isDev) {
(0, import_debug.default)("Skipping dependency installation because dev mode is enabled");
return { installed: false };
}
(0, import_assert.default)(import_path.default.isAbsolute(destPath));
const targetDir = import_path.default.join(destPath, ".vercel_python_packages");
const opts = {
...spawnOpts,
cwd: destPath,
prettyCommand: "uv pip install"
};
await spawnAsync(
"uv",
["pip", "install", "--target", targetDir, ...args],
opts
);
return { installed: true, targetDir };
}
function getScriptName(pkg, possibleNames) {
if (pkg?.scripts) {
for (const name of possibleNames) {
if (name in pkg.scripts) {
return name;
}
}
}
return void 0;
}
const installDependencies = (0, import_util.deprecate)(
runNpmInstall,
"installDependencies() is deprecated. Please use runNpmInstall() instead."
);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
PNPM_10_PREFERRED_AT,
detectPackageManager,
execCommand,
findPackageJson,
getEnvForPackageManager,
getNodeBinPath,
getNodeBinPaths,
getNodeVersion,
getPathForPackageManager,
getPathOverrideForPackageManager,
getScriptName,
getSpawnOptions,
installDependencies,
resetCustomInstallCommandSet,
runBundleInstall,
runCustomInstallCommand,
runNpmInstall,
runPackageJsonScript,
runPipInstall,
runShellScript,
scanParentDirs,
spawnAsync,
spawnCommand,
traverseUpDirectories,
turboVersionSpecifierSupportsCorepack,
usingCorepack,
walkParentDirs
});