UNPKG

vercel

Version:

The command-line interface for Vercel

1,619 lines (1,608 loc) • 75.7 kB
import { createRequire as __createRequire } from 'node:module'; import { fileURLToPath as __fileURLToPath } from 'node:url'; import { dirname as __dirname_ } from 'node:path'; const require = __createRequire(import.meta.url); const __filename = __fileURLToPath(import.meta.url); const __dirname = __dirname_(__filename); import { FunctionsSizeLimitError, Now, UploadErrorMissingArchive, createCertForCns, displayBuildLogsUntilFinalError, printDeploymentStatus, purchaseDomainIfAvailable, require_cjs, setupDomain } from "../../chunks/chunk-V6RCNEUA.js"; import { readLocalConfig } from "../../chunks/chunk-F2UPASLT.js"; import { highlight } from "../../chunks/chunk-V5P25P7F.js"; import "../../chunks/chunk-LOS7HHU3.js"; import { parseMeta } from "../../chunks/chunk-EKPSCRJZ.js"; import { getDeployment, mapCertError } from "../../chunks/chunk-NYJXGEIR.js"; import { validateJsonOutput } from "../../chunks/chunk-XPKWKPWA.js"; import { getSubcommand } from "../../chunks/chunk-YPQSDAEW.js"; import { continueSubcommand, deployCommand, deprecatedArchiveSplitTgz, getCommandAliases, initSubcommand } from "../../chunks/chunk-UVFXUXOZ.js"; import "../../chunks/chunk-IFATV36R.js"; import "../../chunks/chunk-JFVGRFME.js"; import "../../chunks/chunk-TZMIHH5D.js"; import "../../chunks/chunk-XVAEOG4L.js"; import "../../chunks/chunk-ZAAKSLHC.js"; import "../../chunks/chunk-CQANJIEC.js"; import "../../chunks/chunk-KWDV5FZH.js"; import "../../chunks/chunk-4PSOOFYO.js"; import { AGENT_STATUS } from "../../chunks/chunk-E3NE4SKN.js"; import { pickOverrides } from "../../chunks/chunk-LVUE7LLE.js"; import "../../chunks/chunk-76ZNZKIN.js"; import { ensureLink } from "../../chunks/chunk-N4WFAZKO.js"; import { validatePaths, validateRootDirectory } from "../../chunks/chunk-UTXSTM52.js"; import "../../chunks/chunk-4VPRHRPA.js"; import "../../chunks/chunk-ZKKIBUCU.js"; import { help } from "../../chunks/chunk-MMF4BVAP.js"; import { compileVercelConfig, createGitMeta, param, parseEnv, parseTarget, printAlignedLabel, require_dist as require_dist2, require_lib } from "../../chunks/chunk-X775BOSL.js"; import { TelemetryClient } from "../../chunks/chunk-4OEA5ILS.js"; import { outputAgentError } from "../../chunks/chunk-ULXHXZCZ.js"; import { require_ms, stamp_default } from "../../chunks/chunk-CO5D46AG.js"; import "../../chunks/chunk-N2T234LO.js"; import "../../chunks/chunk-DKD6GTQT.js"; import { getCommandNameWithGlobalFlags, getFlagsSpecification, parseArguments, printError } from "../../chunks/chunk-4GQQJY5Y.js"; import { AliasDomainConfigured, BuildError, BuildsRateLimited, ConflictingConfigFiles, ConflictingFilePath, ConflictingPathSegment, DeploymentNotFound, DeploymentsRateLimited, DeprecatedNowJson, DomainNotFound, DomainNotVerified, DomainPermissionDenied, DomainVerificationFailed, InvalidDomain, MissingBuildScript, NotDomainOwner, NowError, SchemaValidationFailed, TooManyRequests, UserAborted, code, getCommandName, isAPIError, require_bytes } from "../../chunks/chunk-UGXBNJMO.js"; import "../../chunks/chunk-P4QNYOFB.js"; import { emoji, output_manager_default, prependEmoji, require_dist } from "../../chunks/chunk-ZQKJVHXY.js"; import { require_source } from "../../chunks/chunk-S7KYDPEM.js"; import { __toESM } from "../../chunks/chunk-TZ2YI2VH.js"; // src/commands/deploy/index.ts var import_client3 = __toESM(require_dist2(), 1); var import_error_utils = __toESM(require_dist(), 1); var import_bytes = __toESM(require_bytes(), 1); var import_chalk = __toESM(require_source(), 1); var import_fs_extra2 = __toESM(require_lib(), 1); var import_ms = __toESM(require_ms(), 1); import { getPrettyError, getSupportedNodeVersion, scanParentDirs, PYTHON_FRAMEWORKS } from "@vercel/build-utils"; import { join as join2, resolve } from "path"; // src/util/deploy/generate-cert-for-deploy.ts var import_tldts = __toESM(require_cjs(), 1); async function generateCertForDeploy(client, contextName, deployURL) { const parsedDomain = (0, import_tldts.parse)(deployURL); const { domain } = parsedDomain; if (!domain) { return new InvalidDomain(deployURL); } output_manager_default.spinner(`Setting custom suffix domain ${domain}`); const result = await setupDomain(client, domain, contextName); output_manager_default.stopSpinner(); if (result instanceof NowError) { return result; } output_manager_default.spinner(`Generating a wildcard certificate for ${domain}`); const cert = await createCertForCns( client, [domain, `*.${domain}`], contextName ); output_manager_default.stopSpinner(); if (cert instanceof NowError) { return cert; } } // src/util/deploy/create-deploy.ts async function createDeploy(client, now, contextName, path, createArgs, org, isSettingUpProject, archive) { try { return await now.create(path, createArgs, org, isSettingUpProject, archive); } catch (err) { if (isAPIError(err)) { if (err.code === "rate_limited") { throw new DeploymentsRateLimited(err.message); } if (err.code === "domain_missing") { throw new DomainNotFound(err.value); } if (err.code === "domain_not_found" && err.domain) { throw new DomainNotFound(err.domain); } if (err.code === "domain_not_verified" && err.domain) { throw new DomainNotVerified(err.domain); } if (err.code === "domain_not_verified" && err.value) { throw new DomainVerificationFailed(err.value); } if (err.code === "not_domain_owner") { throw new NotDomainOwner(err.message); } if (err.code === "builds_rate_limited") { throw new BuildsRateLimited(err.message); } if (err.code === "forbidden") { throw new DomainPermissionDenied(err.value, contextName); } if (err.code === "bad_request" && err.keyword) { throw new SchemaValidationFailed( err.message, err.keyword, err.dataPath, err.params ); } if (err.code === "domain_configured") { throw new AliasDomainConfigured(err); } if (err.code === "missing_build_script") { throw new MissingBuildScript(err); } if (err.code === "conflicting_file_path") { throw new ConflictingFilePath(err); } if (err.code === "conflicting_path_segment") { throw new ConflictingPathSegment(err); } if (err.code === "cert_missing") { const result = await generateCertForDeploy( client, contextName, err.value ); if (result instanceof NowError) { return result; } return createDeploy( client, now, contextName, path, createArgs, org, isSettingUpProject ); } if (err.code === "not_found") { throw new DeploymentNotFound({ context: contextName }); } const certError = mapCertError(err); if (certError) { return certError; } } throw err; } } // src/util/deploy/get-deployment-checks.ts async function getDeploymentChecks(client, deploymentId) { const checksResponse = await client.fetch( `/v1/deployments/${encodeURIComponent(deploymentId)}/checks` ); return checksResponse; } // src/util/deploy/get-deployment-check-runs.ts async function getDeploymentCheckRuns(client, deploymentId) { const response = await client.fetch( `/v2/deployments/${encodeURIComponent(deploymentId)}/check-runs` ); return response; } // src/util/deploy/get-deployment-check-run-logs.ts var MAX_ATTEMPTS = 5; var POLL_INTERVAL_MS = 2e3; function parseNdjson(text) { const entries = []; for (const line of text.split("\n")) { if (!line.trim()) continue; try { entries.push(JSON.parse(line)); } catch { } } return entries; } async function getDeploymentCheckRunLogs(client, deploymentId, checkRunId) { const url = `/v2/deployments/${encodeURIComponent(deploymentId)}/check-runs/${encodeURIComponent(checkRunId)}/logs`; await new Promise((resolve2) => setTimeout(resolve2, 1e3)); for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { if (attempt > 0) await new Promise((resolve2) => setTimeout(resolve2, POLL_INTERVAL_MS)); const res = await client.fetch(url, { json: false }); const text = typeof res === "string" ? res : await res.text(); const entries = parseNdjson(text); const hasEof = entries.some((e) => e.level === "eof"); if (hasEof) { return entries.filter((e) => e.level !== "eof" && e.level !== "debug").map(({ level, timestamp, message }) => ({ level, timestamp, message })); } } return []; } // src/util/deploy/get-prebuilt-json.ts var import_fs_extra = __toESM(require_lib(), 1); import { join } from "path"; async function getPrebuiltJson(directory) { try { return await import_fs_extra.default.readJSON(join(directory, "builds.json")); } catch (_error) { } return null; } // src/util/deploy/validate-archive-format.ts var import_client = __toESM(require_dist2(), 1); var validArchiveFormats = new Set(import_client.VALID_ARCHIVE_FORMATS); function isValidArchive(archive) { return validArchiveFormats.has(archive); } // src/util/get-project-name.ts import { basename } from "path"; function getProjectName({ nameParam, nowConfig = {}, paths = [] }) { if (nameParam) { return nameParam; } if (nowConfig.name) { return nowConfig.name; } return basename(paths[0] || ""); } // src/util/telemetry/commands/deploy/index.ts var import_client2 = __toESM(require_dist2(), 1); var DeployTelemetryClient = class extends TelemetryClient { trackCliArgumentProjectPath(projectPaths) { if (projectPaths) { this.trackCliArgument({ arg: "project-path", value: this.redactedValue }); } } trackCliOptionArchive(format) { if (format) { const allowedFormat = [ ...import_client2.VALID_ARCHIVE_FORMATS, deprecatedArchiveSplitTgz ].includes(format) ? format : this.redactedValue; this.trackCliOption({ option: "archive", value: allowedFormat }); } } trackCliOptionBuildEnv(buildEnv) { if (buildEnv && buildEnv.length > 0) { this.trackCliOption({ option: "build-env", value: this.redactedValue }); } } trackCliOptionEnv(env) { if (env && env.length > 0) { this.trackCliOption({ option: "env", value: this.redactedValue }); } } trackCliOptionMeta(meta) { if (meta && meta.length > 0) { this.trackCliOption({ option: "meta", value: this.redactedValue }); } } trackCliOptionName(name) { if (name) { this.trackCliOption({ option: "name", value: this.redactedValue }); } } trackCliOptionRegions(regions) { if (regions) { this.trackCliOption({ option: "regions", // consider revisiting once we come up with a way to query the list of regions value: this.redactedValue }); } } trackCliOptionTarget(target) { if (target) { this.trackCliOption({ option: "target", value: this.redactedTargetName(target) }); } } trackCliFlagConfirm(flag) { if (flag) { this.trackCliFlag("confirm"); } } trackCliFlagForce(flag) { if (flag) { this.trackCliFlag("force"); } } trackCliFlagLogs(flag) { if (flag) { this.trackCliFlag("logs"); } } trackCliFlagNoLogs(flag) { if (flag) { this.trackCliFlag("no-logs"); } } trackCliFlagGuidance(flag) { if (flag) { this.trackCliFlag("guidance"); } } trackCliFlagNoClipboard(flag) { if (flag) { this.trackCliFlag("no-clipboard"); } } trackCliFlagNoWait(flag) { if (flag) { this.trackCliFlag("no-wait"); } } trackCliFlagPrebuilt(flag) { if (flag) { this.trackCliFlag("prebuilt"); } } trackCliSubcommandInit(actual) { this.trackCliSubcommand({ subcommand: "init", value: actual }); } trackCliSubcommandContinue(actual) { this.trackCliSubcommand({ subcommand: "continue", value: actual }); } trackCliFlagProd(flag) { if (flag) { this.trackCliFlag("prod"); } } trackTargetEnvironment(target) { super.trackTargetEnvironment( target === "production" ? "production" : "preview" ); } trackCliFlagPublic(flag) { if (flag) { this.trackCliFlag("public"); } } trackCliFlagSkipDomain(flag) { if (flag) { this.trackCliFlag("skip-domain"); } } trackCliFlagWithCache(flag) { if (flag) { this.trackCliFlag("with-cache"); } } trackCliFlagYes(flag) { if (flag) { this.trackCliFlag("yes"); } } trackCliFlagJson(flag) { if (flag) { this.trackCliFlag("json"); } } trackCliOptionFormat(format) { if (format) { this.trackCliOption({ option: "format", value: format }); } } trackCliFlagFunctionsBeta(flag) { if (flag) { this.trackCliFlag("functions-beta"); } } trackCliFlagNoFunctionsBeta(flag) { if (flag) { this.trackCliFlag("no-functions-beta"); } } trackDeploymentId(id) { if (id) { this.trackCommandOutput({ key: "deployment-id", value: id }); } } }; // src/commands/deploy/index.ts import { determineAgent } from "@vercel/detect-agent"; var COMMAND_CONFIG = { init: getCommandAliases(initSubcommand), continue: getCommandAliases(continueSubcommand) }; var deploy_default = async (client) => { const telemetryClient = new DeployTelemetryClient({ opts: { store: client.telemetryEventStore } }); let parsedArguments = null; const flagsSpecification = getFlagsSpecification(deployCommand.options); try { parsedArguments = parseArguments(client.argv.slice(2), flagsSpecification, { permissive: true }); } catch (error) { printError(error); return 1; } const subArgs = parsedArguments.args[0] === deployCommand.name ? parsedArguments.args.slice(1) : parsedArguments.args; const { subcommand, subcommandOriginal } = getSubcommand( subArgs, COMMAND_CONFIG ); function printSubcommandHelp(command) { output_manager_default.print( help(command, { parent: deployCommand, columns: client.stderr.columns }) ); } switch (subcommand) { case "init": if (parsedArguments.flags["--help"]) { telemetryClient.trackCliFlagHelp("deploy", subcommandOriginal); printSubcommandHelp(initSubcommand); return 2; } telemetryClient.trackCliSubcommandInit(subcommandOriginal); return handleInitDeployment(client, telemetryClient); case "continue": if (parsedArguments.flags["--help"]) { telemetryClient.trackCliFlagHelp("deploy", subcommandOriginal); printSubcommandHelp(continueSubcommand); return 2; } telemetryClient.trackCliSubcommandContinue(subcommandOriginal); return handleContinueSubcommand(client, telemetryClient); default: if (parsedArguments.flags["--help"]) { telemetryClient.trackCliFlagHelp("deploy"); output_manager_default.print(help(deployCommand, { columns: client.stderr.columns })); return 2; } return handleDefaultDeploy(client, telemetryClient); } }; async function handleInitDeployment(client, telemetryClient) { const flagsSpecification = getFlagsSpecification(initSubcommand.options); let parsedArguments; try { parsedArguments = parseArguments(client.argv.slice(2), flagsSpecification); } catch (error2) { printError(error2); return 1; } telemetryClient.trackCliFlagJson(parsedArguments.flags["--json"]); telemetryClient.trackCliOptionFormat(parsedArguments.flags["--format"]); telemetryClient.trackCliFlagFunctionsBeta( parsedArguments.flags["--functions-beta"] ); telemetryClient.trackCliFlagNoFunctionsBeta( parsedArguments.flags["--no-functions-beta"] ); const functionsBeta = parsedArguments.flags["--functions-beta"]; const noFunctionsBeta = parsedArguments.flags["--no-functions-beta"]; if (functionsBeta && noFunctionsBeta) { output_manager_default.error( "Cannot use --functions-beta and --no-functions-beta together" ); return 1; } const formatResult = validateJsonOutput(parsedArguments.flags); if (!formatResult.valid) { output_manager_default.error(formatResult.error); return 1; } const asJson = formatResult.jsonOutput || client.nonInteractive; let args = parsedArguments.args; if (args[0] === "deploy") args = args.slice(1); if (args[0] === "init") args = args.slice(1); let paths; if (args.length > 0) { paths = args.map((item) => resolve(client.cwd, item)); telemetryClient.trackCliArgumentProjectPath(paths[0]); } else { paths = [client.cwd]; } const pathValidation = await validatePaths(client, paths); if (!pathValidation.valid) { return pathValidation.exitCode; } await compileVercelConfig(paths[0]); const shouldUseEarlyLocalConfig = paths[0] === client.cwd; let localConfig = shouldUseEarlyLocalConfig ? client.localConfig || readLocalConfig(paths[0]) : readLocalConfig(paths[0]); if (localConfig) { client.localConfig = localConfig; const { version } = localConfig; const file = highlight(localConfig[import_client3.fileNameSymbol]); const prop = code("version"); if (version) { if (typeof version === "number") { if (version !== 2) { const two = code(String(2)); output_manager_default.error( `The value of the ${prop} property within ${file} can only be ${two}.` ); return 1; } } else { output_manager_default.error( `The ${prop} property inside your ${file} file must be a number.` ); return 1; } } } const { log, debug, error } = output_manager_default; const quiet = !client.stdout.isTTY; let { path: cwd } = pathValidation; const autoConfirm = parsedArguments.flags["--yes"]; const target = parseTarget({ flagName: "target", flags: parsedArguments.flags }); telemetryClient.trackTargetEnvironment(target); const parsedArchive = parsedArguments.flags["--archive"]; if (typeof parsedArchive === "string" && !(isValidArchive(parsedArchive) || parsedArchive === deprecatedArchiveSplitTgz)) { output_manager_default.error(`Format must be one of: ${import_client3.VALID_ARCHIVE_FORMATS.join(", ")}`); return 1; } if (parsedArchive === deprecatedArchiveSplitTgz) { output_manager_default.print( `${prependEmoji( `${param("--archive=tgz")} now has the same behavior as ${param( "--archive=split-tgz" )}. Please use ${param("--archive=tgz")} instead.`, emoji("warning") )} ` ); } const cliMeta = parseMeta(parsedArguments.flags["--meta"]); const isV0 = cliMeta.v0 === "true"; const link = await ensureLink("deploy", client, cwd, { autoConfirm, setupMsg: "Set up", projectName: getProjectName({ nameParam: void 0, nowConfig: localConfig, paths }), v0: isV0 }); if (typeof link === "number") { return link; } const { org, project } = link; const rootDirectory = project.rootDirectory; const sourceFilesOutsideRootDirectory = project.sourceFilesOutsideRootDirectory ?? true; if (link.repoRoot) { cwd = link.repoRoot; } const contextName = org.slug; client.config.currentTeam = org.type === "team" ? org.id : void 0; if (functionsBeta || noFunctionsBeta) { const toggleResult = await applyFunctionsBetaToggle( client, project, functionsBeta, noFunctionsBeta ); if (toggleResult.error) { return toggleResult.exitCode; } } if (rootDirectory && await validateRootDirectory( cwd, join2(cwd, rootDirectory), project ? `To change your Project Settings, go to https://vercel.com/${org?.slug}/${project.name}/settings` : "" ) === false) { return 1; } if (rootDirectory) { const rootDirectoryPath = join2(cwd, rootDirectory); await compileVercelConfig(rootDirectoryPath); const rootDirectoryConfig = readLocalConfig(rootDirectoryPath); if (rootDirectoryConfig) { debug(`Read local config from root directory (${rootDirectory})`); localConfig = rootDirectoryConfig; } else if (localConfig) { output_manager_default.print( `${prependEmoji( `The ${highlight( localConfig[import_client3.fileNameSymbol] )} file should be inside of the provided root directory.`, emoji("warning") )} ` ); } } localConfig = localConfig || {}; if (localConfig.name) { output_manager_default.print( `${prependEmoji( `The ${code("name")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} is deprecated (https://vercel.link/name-prop)`, emoji("warning") )} ` ); } const isObject = (item) => Object.prototype.toString.call(item) === "[object Object]"; if (typeof localConfig.env !== "undefined" && !isObject(localConfig.env)) { error( `The ${code("env")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } if (typeof localConfig.build !== "undefined") { if (!isObject(localConfig.build)) { error( `The ${code("build")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } if (typeof localConfig.build.env !== "undefined" && !isObject(localConfig.build.env)) { error( `The ${code("build.env")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } } const meta = Object.assign({}, parseMeta(localConfig.meta), cliMeta); const gitMetadata = await createGitMeta(cwd, project); const deploymentEnv = Object.assign( {}, parseEnv(localConfig.env), parseEnv(parsedArguments.flags["--env"]) ); const deploymentBuildEnv = Object.assign( {}, parseEnv(localConfig.build && localConfig.build.env), parseEnv(parsedArguments.flags["--build-env"]) ); try { await addProcessEnv(log, deploymentEnv); await addProcessEnv(log, deploymentBuildEnv); } catch (err) { error((0, import_error_utils.errorToString)(err)); return 1; } const regionFlag = (parsedArguments.flags["--regions"] || "").split(",").map((s) => s.trim()).filter(Boolean); const regions = regionFlag.length > 0 ? regionFlag : localConfig.regions; const currentTeam = org.type === "team" ? org.id : void 0; const now = new Now({ client, currentTeam }); const deployStamp = stamp_default(); const localConfigurationOverrides = pickOverrides(localConfig); const name = project.name; if (!name) { throw new Error( "`name` not found on project or provided by existing project" ); } const noWait = true; try { const autoAssignCustomDomains = parsedArguments.flags["--skip-domain"] ? false : void 0; const createArgs = { name, env: deploymentEnv, build: { env: deploymentBuildEnv }, forceNew: parsedArguments.flags["--force"], withCache: parsedArguments.flags["--with-cache"], prebuilt: true, vercelOutputDir: void 0, rootDirectory, quiet, wantsPublic: Boolean( parsedArguments.flags["--public"] || localConfig.public ), nowConfig: { ...localConfig, images: void 0 }, regions, meta, gitMetadata, deployStamp, target, skipAutoDetectionConfirmation: autoConfirm, noWait, withFullLogs: false, autoAssignCustomDomains, manual: true, jsonOutput: asJson, functionsBeta: functionsBeta || void 0, linkedProject: project }; if (!localConfig.builds || localConfig.builds.length === 0) { createArgs.projectSettings = { sourceFilesOutsideRootDirectory, rootDirectory, ...localConfigurationOverrides }; } const { packageJson } = await scanParentDirs( join2(cwd, project?.rootDirectory ?? ""), true, cwd ); let nodeVersion; if (packageJson?.engines?.node) { try { const { range } = await getSupportedNodeVersion( packageJson.engines.node ); nodeVersion = range; } catch (error2) { if (error2 instanceof Error) { output_manager_default.warn(error2.message); } } } if (!createArgs.projectSettings) createArgs.projectSettings = {}; createArgs.projectSettings.nodeVersion = nodeVersion; const deployment = await createDeploy( client, now, contextName, cwd, createArgs, org, !project, parsedArchive ? "tgz" : void 0 ); if (deployment instanceof NotDomainOwner) { if (client.nonInteractive) { client.stdout.write( `${JSON.stringify( { status: AGENT_STATUS.ERROR, reason: "not_domain_owner", message: deployment.message, next: [ { command: getCommandNameWithGlobalFlags("deploy", client.argv), when: "retry deploy" } ] }, null, 2 )} ` ); return 1; } else { output_manager_default.error(deployment.message); return 1; } } if (deployment instanceof Error) { const msg = deployment.message || "An unexpected error occurred while deploying your project"; if (client.nonInteractive) { client.stdout.write( `${JSON.stringify( { status: AGENT_STATUS.ERROR, reason: "deploy_failed", message: msg, next: [ { command: getCommandNameWithGlobalFlags("deploy", client.argv), when: "retry deploy" } ] }, null, 2 )} ` ); return 1; } else { output_manager_default.error( msg, void 0, "https://vercel.link/help", "Contact Support" ); return 1; } } if (deployment.readyState === "CANCELED") { if (asJson) { output_manager_default.stopSpinner(); const deploymentJson = getDeploymentOutputJson( deployment, client.apiUrl, { name: "DEPLOYMENT_CANCELED", message: "The deployment has been canceled." } ); const payload = client.nonInteractive ? { status: AGENT_STATUS.ERROR, reason: "deployment_canceled", message: "The deployment has been canceled.", deployment: deploymentJson, next: [ { command: getCommandNameWithGlobalFlags("deploy", client.argv), when: "retry deploy" } ] } : deploymentJson; client.stdout.write(`${JSON.stringify(payload, null, 2)} `); } else { output_manager_default.print("The deployment has been canceled.\n"); } return 1; } if (deployment.checks?.["deployment-alias"]?.state === "failed") { return handleFailedCheckRuns(client, deployment, asJson); } if (deployment.checksConclusion === "failed") { const { checks } = await getDeploymentChecks(client, deployment.id); const counters = /* @__PURE__ */ new Map(); checks.forEach((c) => { counters.set(c.conclusion, (counters.get(c.conclusion) ?? 0) + 1); }); const counterList = Array.from(counters).map(([name2, no]) => `${no} ${name2}`).join(", "); if (asJson) { output_manager_default.stopSpinner(); const message = `Running Checks: ${counterList}`; const deploymentJson = getDeploymentOutputJson( deployment, client.apiUrl, { name: "CHECKS_FAILED", message } ); const payload = client.nonInteractive ? { status: AGENT_STATUS.ERROR, reason: "checks_failed", message, deployment: deploymentJson, next: [ { command: getCommandNameWithGlobalFlags("deploy", client.argv), when: "retry deploy" } ] } : deploymentJson; client.stdout.write(`${JSON.stringify(payload, null, 2)} `); } else { output_manager_default.error(`Running Checks: ${counterList}`); } return 1; } if (deployment === null) { if (client.nonInteractive) { client.stdout.write( `${JSON.stringify( { status: AGENT_STATUS.ERROR, reason: "upload_failed", message: "Uploading failed. Please try again.", next: [ { command: getCommandNameWithGlobalFlags("deploy", client.argv), when: "retry deploy" } ] }, null, 2 )} ` ); return 1; } else { error("Uploading failed. Please try again."); return 1; } } if (asJson) { output_manager_default.stopSpinner(); const deploymentJson = getDeploymentOutputJson(deployment, client.apiUrl); const payload = client.nonInteractive ? { status: AGENT_STATUS.OK, deployment: deploymentJson, message: `Deployment ${deployment.url} ready.`, next: [ { command: getCommandNameWithGlobalFlags( `inspect ${deployment.url}`, client.argv ), when: "Inspect deployment" }, { command: getCommandNameWithGlobalFlags( "deploy --prod", client.argv ), when: "Promote to production" } ] } : deploymentJson; client.stdout.write(`${JSON.stringify(payload, null, 2)} `); return 0; } return printDeploymentStatus( client, deployment, deployStamp, noWait, false, true ); } catch (err) { if ((0, import_error_utils.isError)(err)) { debug(`Error: ${err} ${err.stack}`); } if (err instanceof FunctionsSizeLimitError) { output_manager_default.prettyError(err); output_manager_default.log( 'Run "vercel deploy --functions-beta" to retry with extended function limits.' ); output_manager_default.log(`Learn More: ${err.link}`); return 1; } if (err instanceof UploadErrorMissingArchive) { output_manager_default.prettyError(err); return 1; } if (err instanceof NotDomainOwner) { output_manager_default.error(err.message); return 1; } if (err instanceof DomainNotFound || err instanceof DomainNotVerified || err instanceof NotDomainOwner || err instanceof DomainPermissionDenied || err instanceof DomainVerificationFailed || err instanceof SchemaValidationFailed || err instanceof InvalidDomain || err instanceof DeploymentNotFound || err instanceof BuildsRateLimited || err instanceof DeploymentsRateLimited || err instanceof AliasDomainConfigured || err instanceof MissingBuildScript || err instanceof ConflictingFilePath || err instanceof ConflictingPathSegment || err instanceof ConflictingConfigFiles || err instanceof DeprecatedNowJson) { handleCreateDeployError(err, localConfig); return 1; } if (isAPIError(err) && err.code === "size_limit_exceeded") { const { sizeLimit = 0 } = err; const message = `File size limit exceeded (${(0, import_bytes.default)(sizeLimit)})`; error(message); return 1; } printError(err); return 1; } } async function handleContinueSubcommand(client, telemetryClient) { const flagsSpecification = getFlagsSpecification(continueSubcommand.options); let parsedArguments; try { parsedArguments = parseArguments(client.argv.slice(2), flagsSpecification); } catch (error) { printError(error); return 1; } const idFlag = parsedArguments.flags["--id"]; const parsedArchive = parsedArguments.flags["--archive"]; const errorMessage = parsedArguments.flags["--error"]; if (typeof parsedArchive === "string" && !isValidArchive(parsedArchive)) { output_manager_default.error(`Format must be one of: ${import_client3.VALID_ARCHIVE_FORMATS.join(", ")}`); return 1; } telemetryClient.trackCliOptionArchive(parsedArchive); if (parsedArchive && errorMessage !== void 0) { output_manager_default.error(`Cannot use ${param("--archive")} with ${param("--error")}`); return 1; } if (errorMessage !== void 0 && errorMessage.trim() === "") { output_manager_default.error(`${param("--error")} requires an error message`); return 1; } if (!idFlag) { if (client.nonInteractive) { outputAgentError( client, { status: AGENT_STATUS.ERROR, reason: "missing_id", message: "Missing required --id flag. Provide the deployment ID to continue.", next: [ { command: getCommandNameWithGlobalFlags( "deploy continue --id <deployment-id>", client.argv ), when: "provide deployment ID" } ] }, 1 ); return 1; } else { output_manager_default.error( `Missing required ${param("--id")} flag. Usage: ${getCommandName("deploy continue --id <deployment-id>")}` ); return 1; } } const paths = [client.cwd]; const pathValidation = await validatePaths(client, paths); if (!pathValidation.valid) { return pathValidation.exitCode; } await compileVercelConfig(paths[0]); const localConfig = client.localConfig || readLocalConfig(paths[0]); if (localConfig) { client.localConfig = localConfig; } let { path: cwd } = pathValidation; const link = await ensureLink("deploy", client, cwd, { autoConfirm: true, setupMsg: "Set up", projectName: getProjectName({ nameParam: void 0, nowConfig: localConfig, paths }) }); if (typeof link === "number") { return link; } const { org } = link; if (link.repoRoot) { cwd = link.repoRoot; } client.config.currentTeam = org.type === "team" ? org.id : void 0; if (errorMessage !== void 0) { try { await client.fetch(`/deployments/${idFlag}/continue`, { method: "POST", body: { errorMessage } }); output_manager_default.success(`Marked deployment ${idFlag} as errored`); return 0; } catch (error) { printError(error); return 1; } } let vercelOutputDir = join2(cwd, ".vercel/output"); if (link.repoRoot && link.project.rootDirectory) { vercelOutputDir = join2(cwd, link.project.rootDirectory, ".vercel/output"); } const prebuiltExists = await import_fs_extra2.default.pathExists(vercelOutputDir); if (!prebuiltExists) { if (client.nonInteractive) { outputAgentError( client, { status: AGENT_STATUS.ERROR, reason: "prebuilt_not_found", message: 'No prebuilt output found in ".vercel/output". Run build first.', next: [ { command: getCommandNameWithGlobalFlags("build", client.argv), when: "generate prebuilt output" }, { command: getCommandNameWithGlobalFlags( `deploy continue --id ${idFlag}`, client.argv ), when: "deploy prebuilt output" } ] }, 1 ); return 1; } else { output_manager_default.error( `No prebuilt output found in ".vercel/output". Run ${getCommandName( "build" )} to generate a local build.` ); return 1; } } const deployStamp = stamp_default(); return handleContinueDeployment({ client, deploymentId: idFlag, cwd, deployStamp, noWait: false, org, vercelOutputDir, archive: parsedArchive ? "tgz" : void 0 }); } async function handleDefaultDeploy(client, telemetryClient) { const flagsSpecification = getFlagsSpecification(deployCommand.options); let parsedArguments; try { parsedArguments = parseArguments(client.argv.slice(2), flagsSpecification); } catch (error2) { printError(error2); return 1; } telemetryClient.trackCliOptionArchive(parsedArguments.flags["--archive"]); telemetryClient.trackCliOptionEnv(parsedArguments.flags["--env"]); telemetryClient.trackCliOptionBuildEnv(parsedArguments.flags["--build-env"]); telemetryClient.trackCliOptionMeta(parsedArguments.flags["--meta"]); telemetryClient.trackCliFlagPrebuilt(parsedArguments.flags["--prebuilt"]); telemetryClient.trackCliOptionRegions(parsedArguments.flags["--regions"]); telemetryClient.trackCliFlagNoWait(parsedArguments.flags["--no-wait"]); telemetryClient.trackCliFlagYes(parsedArguments.flags["--yes"]); telemetryClient.trackCliOptionTarget(parsedArguments.flags["--target"]); telemetryClient.trackCliFlagProd(parsedArguments.flags["--prod"]); telemetryClient.trackCliFlagSkipDomain( parsedArguments.flags["--skip-domain"] ); telemetryClient.trackCliFlagPublic(parsedArguments.flags["--public"]); telemetryClient.trackCliFlagLogs(parsedArguments.flags["--logs"]); telemetryClient.trackCliFlagNoLogs(parsedArguments.flags["--no-logs"]); telemetryClient.trackCliFlagGuidance(parsedArguments.flags["--guidance"]); telemetryClient.trackCliFlagForce(parsedArguments.flags["--force"]); telemetryClient.trackCliFlagWithCache(parsedArguments.flags["--with-cache"]); telemetryClient.trackCliFlagJson(parsedArguments.flags["--json"]); telemetryClient.trackCliOptionFormat(parsedArguments.flags["--format"]); telemetryClient.trackCliFlagFunctionsBeta( parsedArguments.flags["--functions-beta"] ); telemetryClient.trackCliFlagNoFunctionsBeta( parsedArguments.flags["--no-functions-beta"] ); const functionsBeta = parsedArguments.flags["--functions-beta"]; const noFunctionsBeta = parsedArguments.flags["--no-functions-beta"]; if (functionsBeta && noFunctionsBeta) { output_manager_default.error( "Cannot use --functions-beta and --no-functions-beta together" ); return 1; } const formatResult = validateJsonOutput(parsedArguments.flags); if (!formatResult.valid) { output_manager_default.error(formatResult.error); return 1; } const asJson = formatResult.jsonOutput || client.nonInteractive; if ("--confirm" in parsedArguments.flags) { telemetryClient.trackCliFlagConfirm(parsedArguments.flags["--confirm"]); output_manager_default.warn("`--confirm` is deprecated, please use `--yes` instead"); parsedArguments.flags["--yes"] = parsedArguments.flags["--confirm"]; } if ("--no-logs" in parsedArguments.flags) { output_manager_default.warn("`--no-logs` is deprecated and now the default behavior."); } if (parsedArguments.args[0] === deployCommand.name) { parsedArguments.args.shift(); } let paths; if (parsedArguments.args.length > 0) { paths = parsedArguments.args.map((item) => resolve(client.cwd, item)); telemetryClient.trackCliArgumentProjectPath(paths[0]); } else { paths = [client.cwd]; } const pathValidation = await validatePaths(client, paths); if (!pathValidation.valid) { return pathValidation.exitCode; } try { await compileVercelConfig(paths[0]); } catch (err) { if (err instanceof ConflictingConfigFiles || err instanceof DeprecatedNowJson) { output_manager_default.prettyError(err); return 1; } throw err; } const shouldUseEarlyLocalConfig = paths[0] === client.cwd; let localConfig = shouldUseEarlyLocalConfig ? client.localConfig || readLocalConfig(paths[0]) : readLocalConfig(paths[0]); if (localConfig) { client.localConfig = localConfig; const { version } = localConfig; const file = highlight(localConfig[import_client3.fileNameSymbol]); const prop = code("version"); if (version) { if (typeof version === "number") { if (version !== 2) { const two = code(String(2)); output_manager_default.error( `The value of the ${prop} property within ${file} can only be ${two}.` ); return 1; } } else { output_manager_default.error( `The ${prop} property inside your ${file} file must be a number.` ); return 1; } } } const { log, debug, error, prettyError } = output_manager_default; const quiet = !client.stdout.isTTY; let { path: cwd } = pathValidation; const autoConfirm = parsedArguments.flags["--yes"] || client.nonInteractive; if (parsedArguments.flags["--name"]) { output_manager_default.print( `${prependEmoji( `The ${param( "--name" )} option is deprecated (https://vercel.link/name-flag)`, emoji("warning") )} ` ); telemetryClient.trackCliOptionName(parsedArguments.flags["--name"]); } if (parsedArguments.flags["--no-clipboard"]) { output_manager_default.print( `${prependEmoji( `The ${param( "--no-clipboard" )} option was ignored because it is the default behavior. Please remove it.`, emoji("warning") )} ` ); telemetryClient.trackCliFlagNoClipboard(true); } const target = parseTarget({ flagName: "target", flags: parsedArguments.flags }); telemetryClient.trackTargetEnvironment(target); const skipDomain = parsedArguments.flags["--skip-domain"]; if (skipDomain && target !== "production") { output_manager_default.error( "The `--skip-domain` option can only be used with production deployments. Use `--prod` or `--target=production`." ); return 1; } const parsedArchive = parsedArguments.flags["--archive"]; if (typeof parsedArchive === "string" && !(isValidArchive(parsedArchive) || parsedArchive === deprecatedArchiveSplitTgz)) { output_manager_default.error(`Format must be one of: ${import_client3.VALID_ARCHIVE_FORMATS.join(", ")}`); return 1; } if (parsedArchive === deprecatedArchiveSplitTgz) { output_manager_default.print( `${prependEmoji( `${param("--archive=tgz")} now has the same behavior as ${param( "--archive=split-tgz" )}. Please use ${param("--archive=tgz")} instead.`, emoji("warning") )} ` ); } const cliMeta = parseMeta(parsedArguments.flags["--meta"]); const isV0 = cliMeta.v0 === "true"; const link = await ensureLink("deploy", client, cwd, { autoConfirm, setupMsg: "Set up", projectName: getProjectName({ nameParam: parsedArguments.flags["--name"], nowConfig: localConfig, paths }), v0: isV0 }); if (typeof link === "number") { return link; } const { org, project } = link; const rootDirectory = project.rootDirectory; const sourceFilesOutsideRootDirectory = project.sourceFilesOutsideRootDirectory ?? true; if (link.repoRoot) { cwd = link.repoRoot; } let vercelOutputDir; if (parsedArguments.flags["--prebuilt"]) { vercelOutputDir = join2(cwd, ".vercel/output"); if (link.repoRoot && link.project.rootDirectory) { vercelOutputDir = join2(cwd, link.project.rootDirectory, ".vercel/output"); } const prebuiltExists = await import_fs_extra2.default.pathExists(vercelOutputDir); if (!prebuiltExists) { error( `The ${param( "--prebuilt" )} option was used, but no prebuilt output found in ".vercel/output". Run ${getCommandName( "build" )} to generate a local build.` ); return 1; } const prebuiltBuild = await getPrebuiltJson(vercelOutputDir); const prebuiltError = prebuiltBuild?.error || prebuiltBuild?.builds?.find((build) => "error" in build)?.error; if (prebuiltError) { output_manager_default.log( `Prebuilt deployment cannot be created because ${getCommandName( "build" )} failed with error: ` ); prettyError(prebuiltError); return 1; } const assumedTarget = target || "preview"; if (prebuiltBuild?.target && prebuiltBuild.target !== assumedTarget) { let specifyTarget = ""; if (prebuiltBuild.target === "production") { specifyTarget = ` --prod`; } prettyError({ message: `The ${param( "--prebuilt" )} option was used with the target environment "${assumedTarget}", but the prebuilt output found in ".vercel/output" was built with target environment "${prebuiltBuild.target}". Please run ${getCommandName(`--prebuilt${specifyTarget}`)}.`, link: "https://vercel.link/prebuilt-environment-mismatch" }); return 1; } } const contextName = org.slug; client.config.currentTeam = org.type === "team" ? org.id : void 0; if (functionsBeta || noFunctionsBeta) { const toggleResult = await applyFunctionsBetaToggle( client, project, functionsBeta, noFunctionsBeta ); if (toggleResult.error) { return toggleResult.exitCode; } } if (rootDirectory && await validateRootDirectory( cwd, join2(cwd, rootDirectory), project ? `To change your Project Settings, go to https://vercel.com/${org?.slug}/${project.name}/settings` : "" ) === false) { return 1; } if (rootDirectory) { const rootDirectoryPath = join2(cwd, rootDirectory); await compileVercelConfig(rootDirectoryPath); const rootDirectoryConfig = readLocalConfig(rootDirectoryPath); if (rootDirectoryConfig) { debug(`Read local config from root directory (${rootDirectory})`); localConfig = rootDirectoryConfig; } else if (localConfig) { output_manager_default.print( `${prependEmoji( `The ${highlight( localConfig[import_client3.fileNameSymbol] )} file should be inside of the provided root directory.`, emoji("warning") )} ` ); } } localConfig = localConfig || {}; if (localConfig.name) { output_manager_default.print( `${prependEmoji( `The ${code("name")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} is deprecated (https://vercel.link/name-prop)`, emoji("warning") )} ` ); } const isObject = (item) => Object.prototype.toString.call(item) === "[object Object]"; if (typeof localConfig.env !== "undefined" && !isObject(localConfig.env)) { error( `The ${code("env")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } if (typeof localConfig.build !== "undefined") { if (!isObject(localConfig.build)) { error( `The ${code("build")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } if (typeof localConfig.build.env !== "undefined" && !isObject(localConfig.build.env)) { error( `The ${code("build.env")} property in ${highlight( localConfig[import_client3.fileNameSymbol] )} needs to be an object` ); return 1; } } const meta = Object.assign({}, parseMeta(localConfig.meta), cliMeta); const gitMetadata = await createGitMeta(cwd, project); const deploymentEnv = Object.assign( {}, parseEnv(localConfig.env), parseEnv(parsedArguments.flags["--env"]) ); const deploymentBuildEnv = Object.assign( {}, parseEnv(localConfig.build && localConfig.build.env), parseEnv(parsedArguments.flags["--build-env"]) ); try { await addProcessEnv(log, deploymentEnv); await addProcessEnv(log, deploymentBuildEnv); } catch (err) { error((0, import_error_utils.errorToString)(err)); return 1; } const regionFlag = (parsedArguments.flags["--regions"] || "").split(",").map((s) => s.trim()).filter(Boolean); const regions = regionFlag.length > 0 ? regionFlag : localConfig.regions; const currentTeam = org.type === "team" ? org.id : void 0; const now = new Now({ client, currentTeam }); const deployStamp = stamp_default(); let deployment = null; const noWait = !!parsedArguments.flags["--no-wait"]; const withFullLogs = !!parsedArguments.flags["--logs"]; const localConfigurationOverrides = pickOverrides(localConfig); const name = project.name; if (!name) { throw new Error( "`name` not found on project or provided by existing project" ); } try { const autoAssignCustomDomains = parsedArguments.flags["--skip-domain"] ? false : void 0; const createArgs = { name, env: deploymentEnv, build: { env: deploymentBuildEnv }, forceNew: parsedArguments.flags["--force"], withCache: parsedArguments.flags["--with-cache"], prebuilt: parsedArguments.flags["--prebuilt"], vercelOutputDir, rootDirectory, quiet, wantsPublic: Boolean( parsedArguments.flags["--public"] ||