vercel 50.29.0 → 50.31.1

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.
Files changed (53) hide show
  1. package/dist/chunks/{chunk-XCJJHUSH.js → chunk-2MDXGVZV.js} +1 -1
  2. package/dist/chunks/{chunk-5QC74A5F.js → chunk-43L4BNYM.js} +1 -1
  3. package/dist/chunks/{chunk-D6EWLYB6.js → chunk-4MTNDNUR.js} +139 -51
  4. package/dist/chunks/{chunk-E6ZQVOZ6.js → chunk-4QETQOUQ.js} +12 -6
  5. package/dist/chunks/{chunk-4RS5Z362.js → chunk-677KLOZL.js} +185 -55
  6. package/dist/chunks/{chunk-R64JN33C.js → chunk-7KHMGQNF.js} +4 -4
  7. package/dist/chunks/{chunk-4WJOWTHI.js → chunk-AABYT6JI.js} +4 -4
  8. package/dist/chunks/{chunk-AKR2DW6R.js → chunk-BQ3DXZNT.js} +4 -8
  9. package/dist/chunks/{chunk-YHX5HRA5.js → chunk-CUUJWNAY.js} +2 -2
  10. package/dist/chunks/{chunk-UZO6X2EJ.js → chunk-DOBFJJLK.js} +1 -1
  11. package/dist/chunks/{chunk-BSGCBDUW.js → chunk-F2FJ3QZG.js} +1 -1
  12. package/dist/chunks/{chunk-OPBISBKV.js → chunk-FTXIZBTY.js} +2 -2
  13. package/dist/chunks/{chunk-OG6DJHIZ.js → chunk-GEYBIZGF.js} +6 -6
  14. package/dist/chunks/{chunk-CO5D46AG.js → chunk-GGP5R3FU.js} +18 -38
  15. package/dist/chunks/{chunk-4RE2UMEL.js → chunk-GMKRSAXH.js} +9 -7
  16. package/dist/chunks/{chunk-OAI7OWE5.js → chunk-HXZPHN34.js} +3 -3
  17. package/dist/chunks/chunk-IE7MNZ56.js +149 -0
  18. package/dist/chunks/{chunk-SIXBAQRA.js → chunk-IGWOW3XS.js} +1 -1
  19. package/dist/chunks/{chunk-WS74BBTC.js → chunk-LF56WF3E.js} +2 -2
  20. package/dist/chunks/{chunk-YAEBC66C.js → chunk-MH27YRIK.js} +1 -1
  21. package/dist/chunks/{chunk-DTOQNQUH.js → chunk-NN6I6YMJ.js} +1 -1
  22. package/dist/chunks/chunk-P5Q6F5IA.js +107 -0
  23. package/dist/chunks/chunk-SOTR4CXR.js +34 -0
  24. package/dist/chunks/{chunk-OMLNL6HR.js → chunk-UEWMMW2T.js} +1 -1
  25. package/dist/chunks/{chunk-HN6HFP24.js → chunk-VKQV2LPP.js} +1 -1
  26. package/dist/chunks/{chunk-Q7PNQO77.js → chunk-XGUZYJXE.js} +4 -4
  27. package/dist/chunks/{chunk-NHGOGVX6.js → chunk-XIQUACWR.js} +1 -1
  28. package/dist/chunks/{compile-vercel-config-D3Y7XB5H.js → compile-vercel-config-VEZ3PRGB.js} +4 -3
  29. package/dist/chunks/{delete-O2MGI6R6.js → delete-DIL4SDG6.js} +4 -3
  30. package/dist/chunks/{disable-3KATYJW2.js → disable-PZO6GYWY.js} +4 -3
  31. package/dist/chunks/{discard-64N2QNW2.js → discard-SXBAOPZJ.js} +4 -3
  32. package/dist/chunks/{edit-YQDREXAR.js → edit-AB47LXEE.js} +5 -4
  33. package/dist/chunks/{enable-GKVVFUO5.js → enable-JU6NHQFS.js} +4 -3
  34. package/dist/chunks/{export-5N744CHF.js → export-ZKYFXNPW.js} +4 -3
  35. package/dist/chunks/{list-WM3BRYYI.js → list-AAASORP4.js} +21 -85
  36. package/dist/chunks/list-Y4UQAI2V.js +382 -0
  37. package/dist/chunks/{publish-WRLLEVIN.js → publish-UAISKZPC.js} +4 -3
  38. package/dist/chunks/{query-HBRN3QNG.js → query-DIK6TLAL.js} +10 -9
  39. package/dist/chunks/{reorder-NIRZM757.js → reorder-4VKIZJOA.js} +4 -3
  40. package/dist/chunks/{restore-GGQTC25V.js → restore-5VMKSP2J.js} +4 -3
  41. package/dist/chunks/{schema-IE2SAIEK.js → schema-PJKLO2K2.js} +3 -1
  42. package/dist/chunks/{stamp-ENIXDCRO.js → stamp-RTPE2EBB.js} +2 -1
  43. package/dist/commands/build/index.js +21 -14
  44. package/dist/commands/deploy/index.js +19 -16
  45. package/dist/commands/dev/index.js +32 -24
  46. package/dist/commands/env/index.js +12 -9
  47. package/dist/commands/link/index.js +12 -10
  48. package/dist/commands/list/index.js +9 -7
  49. package/dist/commands-bulk.js +2318 -1214
  50. package/dist/index.js +55 -16
  51. package/dist/version.mjs +1 -1
  52. package/package.json +25 -25
  53. package/dist/chunks/chunk-D63ZY6XZ.js +0 -38
@@ -6,7 +6,7 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __dirname_(__filename);
7
7
  import {
8
8
  require_lib
9
- } from "./chunk-D6EWLYB6.js";
9
+ } from "./chunk-4MTNDNUR.js";
10
10
  import {
11
11
  packageName
12
12
  } from "./chunk-ZLCMHY2G.js";
@@ -6,7 +6,7 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __dirname_(__filename);
7
7
  import {
8
8
  getEnvTargetPlaceholder
9
- } from "./chunk-D6EWLYB6.js";
9
+ } from "./chunk-4MTNDNUR.js";
10
10
  import {
11
11
  packageName,
12
12
  yesOption
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-XB2KZC2B.js";
11
11
  import {
12
12
  stamp_default
13
- } from "./chunk-CO5D46AG.js";
13
+ } from "./chunk-SOTR4CXR.js";
14
14
  import {
15
15
  require_pluralize
16
16
  } from "./chunk-7EHTK7LP.js";
@@ -10316,7 +10316,6 @@ var require_frameworks = __commonJS({
10316
10316
  {
10317
10317
  name: "Django",
10318
10318
  slug: "django",
10319
- experimental: true,
10320
10319
  logo: "https://api-frameworks.vercel.sh/framework-logos/django.svg",
10321
10320
  tagline: "Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. ",
10322
10321
  description: "A Django project served via the Python Runtime.",
@@ -11937,7 +11936,6 @@ var require_frameworks = __commonJS({
11937
11936
  {
11938
11937
  name: "Python",
11939
11938
  slug: "python",
11940
- experimental: true,
11941
11939
  runtimeFramework: true,
11942
11940
  logo: "https://api-frameworks.vercel.sh/framework-logos/python.svg",
11943
11941
  tagline: "Python is a programming language that lets you work quickly and integrate systems more effectively.",
@@ -17344,6 +17342,7 @@ var require_resolve = __commonJS({
17344
17342
  };
17345
17343
  }
17346
17344
  var SERVICE_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
17345
+ var DNS_LABEL_RE = /^(?!-)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
17347
17346
  function normalizeServiceEntrypoint(entrypoint) {
17348
17347
  const normalized = import_path11.posix.normalize(entrypoint);
17349
17348
  return normalized === "" ? "." : normalized;
@@ -17474,10 +17473,19 @@ var require_resolve = __commonJS({
17474
17473
  };
17475
17474
  }
17476
17475
  const serviceType = config.type || "web";
17477
- if (serviceType === "web" && !config.routePrefix) {
17476
+ const hasRoutePrefix = typeof config.routePrefix === "string";
17477
+ const hasSubdomain = typeof config.subdomain === "string";
17478
+ if (hasSubdomain && !DNS_LABEL_RE.test(config.subdomain)) {
17479
+ return {
17480
+ code: "INVALID_SUBDOMAIN",
17481
+ message: `Web service "${name}" has invalid subdomain "${config.subdomain}". Use a single DNS label such as "api".`,
17482
+ serviceName: name
17483
+ };
17484
+ }
17485
+ if (serviceType === "web" && !hasRoutePrefix && !hasSubdomain) {
17478
17486
  return {
17479
17487
  code: "MISSING_ROUTE_PREFIX",
17480
- message: `Web service "${name}" must specify "routePrefix".`,
17488
+ message: `Web service "${name}" must specify at least one of "routePrefix" or "subdomain".`,
17481
17489
  serviceName: name
17482
17490
  };
17483
17491
  }
@@ -17495,6 +17503,13 @@ var require_resolve = __commonJS({
17495
17503
  serviceName: name
17496
17504
  };
17497
17505
  }
17506
+ if ((serviceType === "worker" || serviceType === "cron") && hasSubdomain) {
17507
+ return {
17508
+ code: "INVALID_HOST_ROUTING_CONFIG",
17509
+ message: `${serviceType === "worker" ? "Worker" : "Cron"} service "${name}" cannot have "subdomain". Only web services should specify subdomain routing.`,
17510
+ serviceName: name
17511
+ };
17512
+ }
17498
17513
  if (serviceType === "cron" && !config.schedule) {
17499
17514
  return {
17500
17515
  code: "MISSING_CRON_SCHEDULE",
@@ -17629,7 +17644,10 @@ var require_resolve = __commonJS({
17629
17644
  builderUse = (0, import_utils4.getBuilderForRuntime)(inferredRuntime);
17630
17645
  builderSrc = resolvedEntrypointFile;
17631
17646
  }
17632
- const routePrefix = type === "web" && config.routePrefix ? config.routePrefix.startsWith("/") ? config.routePrefix : `/${config.routePrefix}` : void 0;
17647
+ const normalizedSubdomain = type === "web" && typeof config.subdomain === "string" ? config.subdomain.toLowerCase() : void 0;
17648
+ const defaultRoutePrefix = type === "web" && normalizedSubdomain ? `/_/${name}` : void 0;
17649
+ const routePrefix = type === "web" && (config.routePrefix || defaultRoutePrefix) ? (config.routePrefix || defaultRoutePrefix).startsWith("/") ? config.routePrefix || defaultRoutePrefix : `/${config.routePrefix || defaultRoutePrefix}` : void 0;
17650
+ const resolvedRoutePrefixSource = type === "web" && typeof routePrefix === "string" ? config.routePrefix ? routePrefixSource : "generated" : void 0;
17633
17651
  const isRoot = workspace === ".";
17634
17652
  if (!isRoot) {
17635
17653
  builderSrc = import_path11.posix.join(workspace, builderSrc);
@@ -17665,7 +17683,8 @@ var require_resolve = __commonJS({
17665
17683
  workspace,
17666
17684
  entrypoint: resolvedEntrypointFile,
17667
17685
  routePrefix,
17668
- routePrefixSource: type === "web" && typeof routePrefix === "string" ? routePrefixSource : void 0,
17686
+ routePrefixSource: resolvedRoutePrefixSource,
17687
+ subdomain: normalizedSubdomain,
17669
17688
  framework: config.framework,
17670
17689
  builder: {
17671
17690
  src: builderSrc,
@@ -18068,6 +18087,10 @@ var require_detect_services = __commonJS({
18068
18087
  var import_utils4 = require_utils3();
18069
18088
  var import_resolve = require_resolve();
18070
18089
  var import_auto_detect = require_auto_detect();
18090
+ var PREVIEW_DOMAIN_MISSING = [
18091
+ { type: "host", value: { suf: ".vercel.app" } },
18092
+ { type: "host", value: { suf: ".vercel.dev" } }
18093
+ ];
18071
18094
  async function detectServices3(options) {
18072
18095
  const { fs: fs5, workPath } = options;
18073
18096
  const scopedFs = workPath ? fs5.chdir(workPath) : fs5;
@@ -18076,7 +18099,13 @@ var require_detect_services = __commonJS({
18076
18099
  return {
18077
18100
  services: [],
18078
18101
  source: "configured",
18079
- routes: { rewrites: [], defaults: [], crons: [], workers: [] },
18102
+ routes: {
18103
+ hostRewrites: [],
18104
+ rewrites: [],
18105
+ defaults: [],
18106
+ crons: [],
18107
+ workers: []
18108
+ },
18080
18109
  errors: [configError],
18081
18110
  warnings: []
18082
18111
  };
@@ -18089,7 +18118,13 @@ var require_detect_services = __commonJS({
18089
18118
  return {
18090
18119
  services: [],
18091
18120
  source: "auto-detected",
18092
- routes: { rewrites: [], defaults: [], crons: [], workers: [] },
18121
+ routes: {
18122
+ hostRewrites: [],
18123
+ rewrites: [],
18124
+ defaults: [],
18125
+ crons: [],
18126
+ workers: []
18127
+ },
18093
18128
  errors: autoResult.errors,
18094
18129
  warnings: []
18095
18130
  };
@@ -18112,7 +18147,13 @@ var require_detect_services = __commonJS({
18112
18147
  return {
18113
18148
  services: [],
18114
18149
  source: "auto-detected",
18115
- routes: { rewrites: [], defaults: [], crons: [], workers: [] },
18150
+ routes: {
18151
+ hostRewrites: [],
18152
+ rewrites: [],
18153
+ defaults: [],
18154
+ crons: [],
18155
+ workers: []
18156
+ },
18116
18157
  errors: [
18117
18158
  {
18118
18159
  code: "NO_SERVICES_CONFIGURED",
@@ -18137,6 +18178,7 @@ var require_detect_services = __commonJS({
18137
18178
  };
18138
18179
  }
18139
18180
  function generateServicesRoutes2(services) {
18181
+ const hostRewrites = [];
18140
18182
  const rewrites = [];
18141
18183
  const defaults = [];
18142
18184
  const crons = [];
@@ -18149,6 +18191,25 @@ var require_detect_services = __commonJS({
18149
18191
  const { routePrefix } = service;
18150
18192
  const normalizedPrefix = routePrefix.slice(1);
18151
18193
  const ownershipGuard = (0, import_routing_utils.getOwnershipGuard)(routePrefix, allWebPrefixes);
18194
+ const hostCondition = getHostCondition(service);
18195
+ if (hostCondition && routePrefix !== "/") {
18196
+ const normalizedRoutePrefix = (0, import_routing_utils.normalizeRoutePrefix)(routePrefix);
18197
+ const escapedPrefix = escapeRegex(normalizedRoutePrefix.slice(1));
18198
+ hostRewrites.push({
18199
+ src: "^/$",
18200
+ dest: normalizedRoutePrefix,
18201
+ has: hostCondition,
18202
+ missing: PREVIEW_DOMAIN_MISSING,
18203
+ check: true
18204
+ });
18205
+ hostRewrites.push({
18206
+ src: `^/(?!${escapedPrefix}(?:/|$))(.*)$`,
18207
+ dest: `${normalizedRoutePrefix}/$1`,
18208
+ has: hostCondition,
18209
+ missing: PREVIEW_DOMAIN_MISSING,
18210
+ check: true
18211
+ });
18212
+ }
18152
18213
  if ((0, import_utils4.isRouteOwningBuilder)(service)) {
18153
18214
  continue;
18154
18215
  }
@@ -18218,7 +18279,7 @@ var require_detect_services = __commonJS({
18218
18279
  check: true
18219
18280
  });
18220
18281
  }
18221
- return { rewrites, defaults, crons, workers };
18282
+ return { hostRewrites, rewrites, defaults, crons, workers };
18222
18283
  }
18223
18284
  function escapeRegex(str) {
18224
18285
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -18233,6 +18294,15 @@ var require_detect_services = __commonJS({
18233
18294
  }
18234
18295
  return Array.from(unique);
18235
18296
  }
18297
+ function getHostCondition(service) {
18298
+ if (service.type !== "web") {
18299
+ return void 0;
18300
+ }
18301
+ if (typeof service.subdomain === "string" && service.subdomain.length > 0) {
18302
+ return [{ type: "host", value: { pre: `${service.subdomain}.` } }];
18303
+ }
18304
+ return void 0;
18305
+ }
18236
18306
  }
18237
18307
  });
18238
18308
 
@@ -18473,6 +18543,7 @@ var require_get_services_builders = __commonJS({
18473
18543
  }
18474
18544
  ],
18475
18545
  warnings: [],
18546
+ hostRewriteRoutes: null,
18476
18547
  defaultRoutes: null,
18477
18548
  redirectRoutes: null,
18478
18549
  rewriteRoutes: null,
@@ -18493,6 +18564,7 @@ var require_get_services_builders = __commonJS({
18493
18564
  message: e.message
18494
18565
  })),
18495
18566
  warnings: warningResponses,
18567
+ hostRewriteRoutes: null,
18496
18568
  defaultRoutes: null,
18497
18569
  redirectRoutes: null,
18498
18570
  rewriteRoutes: null,
@@ -18509,6 +18581,7 @@ var require_get_services_builders = __commonJS({
18509
18581
  }
18510
18582
  ],
18511
18583
  warnings: warningResponses,
18584
+ hostRewriteRoutes: null,
18512
18585
  defaultRoutes: null,
18513
18586
  redirectRoutes: null,
18514
18587
  rewriteRoutes: null,
@@ -18520,6 +18593,7 @@ var require_get_services_builders = __commonJS({
18520
18593
  builders: builders.length > 0 ? builders : null,
18521
18594
  errors: null,
18522
18595
  warnings: warningResponses,
18596
+ hostRewriteRoutes: result.routes.hostRewrites.length > 0 ? result.routes.hostRewrites : null,
18523
18597
  defaultRoutes: result.routes.defaults.length > 0 ? result.routes.defaults : null,
18524
18598
  redirectRoutes: [],
18525
18599
  rewriteRoutes: result.routes.rewrites.length > 0 || result.routes.workers.length > 0 || result.routes.crons.length > 0 ? [
@@ -18999,10 +19073,10 @@ var require_detect_builders = __commonJS({
18999
19073
  message: "Function must contain at least one property."
19000
19074
  };
19001
19075
  }
19002
- if (func.maxDuration !== void 0 && (func.maxDuration < 1 || func.maxDuration > 900 || !Number.isInteger(func.maxDuration))) {
19076
+ if (func.maxDuration !== void 0 && func.maxDuration !== "max" && (func.maxDuration < 1 || func.maxDuration > 900 || !Number.isInteger(func.maxDuration))) {
19003
19077
  return {
19004
19078
  code: "invalid_function_duration",
19005
- message: "Functions must have a duration between 1 and 900."
19079
+ message: 'Functions must have a maxDuration between 1 and 900, or "max".'
19006
19080
  };
19007
19081
  }
19008
19082
  if (func.memory !== void 0 && (func.memory < 128 || func.memory > 10240)) {
@@ -37125,27 +37199,23 @@ function findChanges(oldEnv, newEnv) {
37125
37199
  } else if (oldEnv[key] !== newEnv[key]) {
37126
37200
  changed.push(key);
37127
37201
  }
37128
- delete oldEnv[key];
37129
37202
  }
37130
- const removed = Object.keys(oldEnv);
37131
37203
  return {
37132
37204
  added,
37133
- changed,
37134
- removed
37205
+ changed
37135
37206
  };
37136
37207
  }
37137
37208
  function buildDeltaString(oldEnv, newEnv) {
37138
- const { added, changed, removed } = findChanges(oldEnv, newEnv);
37209
+ const { added, changed } = findChanges(oldEnv, newEnv);
37139
37210
  let deltaString = "";
37140
- deltaString += import_chalk5.default.green(addDeltaSection("+", changed, true));
37211
+ deltaString += import_chalk5.default.yellow(addDeltaSection("M", changed));
37141
37212
  deltaString += import_chalk5.default.green(addDeltaSection("+", added));
37142
- deltaString += import_chalk5.default.red(addDeltaSection("-", removed));
37143
37213
  return deltaString ? import_chalk5.default.gray("Changes:\n") + deltaString + "\n" : deltaString;
37144
37214
  }
37145
- function addDeltaSection(prefix, arr, changed = false) {
37215
+ function addDeltaSection(prefix, arr) {
37146
37216
  if (arr.length === 0)
37147
37217
  return "";
37148
- return arr.sort().map((item) => `${prefix} ${item}${changed ? " (Updated)" : ""}`).join("\n") + "\n";
37218
+ return arr.sort().map((item) => `${prefix} ${item}`).join("\n") + "\n";
37149
37219
  }
37150
37220
 
37151
37221
  // src/commands/env/pull.ts
@@ -37512,33 +37582,26 @@ async function envPullCommandLogic(client, filename, skipConfirmation, environme
37512
37582
  const fullPath = resolve2(cwd, filename);
37513
37583
  const head = tryReadHeadSync(fullPath, Buffer.byteLength(CONTENTS_PREFIX));
37514
37584
  const exists = typeof head !== "undefined";
37585
+ const requiresConfirmation = exists && head !== CONTENTS_PREFIX && !skipConfirmation && !client.nonInteractive;
37515
37586
  if (head === CONTENTS_PREFIX) {
37516
37587
  output_manager_default.log(`Overwriting existing ${import_chalk7.default.bold(filename)} file`);
37517
- } else if (exists && !skipConfirmation) {
37518
- if (client.nonInteractive) {
37519
- outputActionRequired(client, {
37520
- status: "action_required",
37521
- reason: "env_file_exists",
37522
- message: `File ${param(filename)} already exists and was not created by Vercel CLI. Use --yes to overwrite or specify a different filename.`,
37523
- next: [
37524
- {
37525
- command: getCommandNamePlain(`env pull ${filename} --yes`),
37526
- when: "Overwrite this file"
37527
- },
37528
- {
37529
- command: getCommandNamePlain("env pull <filename>"),
37530
- when: "Use a different filename"
37531
- }
37532
- ]
37533
- });
37534
- }
37535
- if (!await client.input.confirm(
37536
- `Found existing file ${param(filename)}. Do you want to overwrite?`,
37537
- false
37538
- )) {
37539
- output_manager_default.log("Canceled");
37540
- return;
37541
- }
37588
+ } else if (exists && !skipConfirmation && client.nonInteractive) {
37589
+ outputActionRequired(client, {
37590
+ status: "action_required",
37591
+ reason: "env_file_exists",
37592
+ message: `File ${param(filename)} already exists and was not created by Vercel CLI. Use --yes to apply the downloaded changes or specify a different filename.`,
37593
+ next: [
37594
+ {
37595
+ command: getCommandNamePlain(`env pull ${filename} --yes`),
37596
+ when: "Apply the downloaded changes to this file"
37597
+ },
37598
+ {
37599
+ command: getCommandNamePlain("env pull <filename>"),
37600
+ when: "Use a different filename"
37601
+ }
37602
+ ]
37603
+ });
37604
+ return;
37542
37605
  }
37543
37606
  const projectSlugLink = formatProject(link.org.slug, link.project.name);
37544
37607
  const downloadMessage = gitBranch ? `Downloading \`${import_chalk7.default.cyan(
@@ -37557,20 +37620,34 @@ async function envPullCommandLogic(client, filename, skipConfirmation, environme
37557
37620
  })).env;
37558
37621
  let deltaString = "";
37559
37622
  let oldEnv;
37623
+ const downloadedEnv = getDownloadedEnv(records);
37560
37624
  if (exists) {
37561
37625
  oldEnv = await createEnvObject(fullPath);
37562
37626
  if (oldEnv) {
37563
- const newEnv = (0, import_json_parse_better_errors.default)(JSON.stringify(records).replace(/\\"/g, ""));
37564
- deltaString = buildDeltaString(oldEnv, newEnv);
37627
+ deltaString = buildDeltaString(oldEnv, {
37628
+ ...oldEnv,
37629
+ ...downloadedEnv
37630
+ });
37565
37631
  }
37566
37632
  }
37567
- const contents = CONTENTS_PREFIX + Object.keys(records).sort().filter((key) => !VARIABLES_TO_IGNORE.includes(key)).map((key) => `${key}="${escapeValue(records[key])}"`).join("\n") + "\n";
37568
- await (0, import_fs_extra4.outputFile)(fullPath, contents, "utf8");
37633
+ const envToWrite = oldEnv ? {
37634
+ ...oldEnv,
37635
+ ...downloadedEnv
37636
+ } : downloadedEnv;
37569
37637
  if (deltaString) {
37570
37638
  output_manager_default.print("\n" + deltaString);
37571
37639
  } else if (oldEnv && exists) {
37572
37640
  output_manager_default.log("No changes found.");
37573
37641
  }
37642
+ if (requiresConfirmation && deltaString !== "" && !await client.input.confirm(
37643
+ `Apply these changes to ${param(filename)}?`,
37644
+ false
37645
+ )) {
37646
+ output_manager_default.log("Canceled");
37647
+ return;
37648
+ }
37649
+ const contents = CONTENTS_PREFIX + Object.keys(envToWrite).sort().map((key) => `${key}="${escapeValue(envToWrite[key])}"`).join("\n") + "\n";
37650
+ await (0, import_fs_extra4.outputFile)(fullPath, contents, "utf8");
37574
37651
  let isGitIgnoreUpdated = false;
37575
37652
  if (filename === ".env.local") {
37576
37653
  const rootPath = link.repoRoot ?? cwd;
@@ -37587,6 +37664,17 @@ async function envPullCommandLogic(client, filename, skipConfirmation, environme
37587
37664
  function escapeValue(value) {
37588
37665
  return value ? value.replace(new RegExp("\n", "g"), "\\n").replace(new RegExp("\r", "g"), "\\r") : "";
37589
37666
  }
37667
+ function getDownloadedEnv(records) {
37668
+ return (0, import_json_parse_better_errors.default)(
37669
+ JSON.stringify(
37670
+ Object.fromEntries(
37671
+ Object.entries(records).filter(
37672
+ ([key]) => !VARIABLES_TO_IGNORE.includes(key)
37673
+ )
37674
+ )
37675
+ ).replace(/\\"/g, "")
37676
+ );
37677
+ }
37590
37678
 
37591
37679
  // src/util/projects/find-project-root.ts
37592
37680
  var import_chalk8 = __toESM(require_source(), 1);
@@ -9,10 +9,10 @@ import {
9
9
  } from "./chunk-IB5L4LKZ.js";
10
10
  import {
11
11
  require_dist as require_dist2
12
- } from "./chunk-Q7PNQO77.js";
12
+ } from "./chunk-XGUZYJXE.js";
13
13
  import {
14
14
  require_execa
15
- } from "./chunk-YHX5HRA5.js";
15
+ } from "./chunk-CUUJWNAY.js";
16
16
  import {
17
17
  VERCEL_DIR,
18
18
  readJSONFile,
@@ -21,7 +21,7 @@ import {
21
21
  require_dist2 as require_dist4,
22
22
  require_lib,
23
23
  require_minimatch2 as require_minimatch
24
- } from "./chunk-D6EWLYB6.js";
24
+ } from "./chunk-4MTNDNUR.js";
25
25
  import {
26
26
  require_pluralize
27
27
  } from "./chunk-7EHTK7LP.js";
@@ -11060,6 +11060,11 @@ var serviceConfigSchema = {
11060
11060
  minLength: 1,
11061
11061
  maxLength: 512
11062
11062
  },
11063
+ subdomain: {
11064
+ type: "string",
11065
+ minLength: 1,
11066
+ maxLength: 63
11067
+ },
11063
11068
  framework: {
11064
11069
  type: "string",
11065
11070
  minLength: 1,
@@ -11091,9 +11096,10 @@ var serviceConfigSchema = {
11091
11096
  maximum: 10240
11092
11097
  },
11093
11098
  maxDuration: {
11094
- type: "integer",
11095
- minimum: 1,
11096
- maximum: 900
11099
+ oneOf: [
11100
+ { type: "integer", minimum: 1, maximum: 900 },
11101
+ { type: "string", enum: ["max"] }
11102
+ ]
11097
11103
  },
11098
11104
  includeFiles: {
11099
11105
  oneOf: [