vercel 54.11.0 → 54.12.0

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 (51) hide show
  1. package/dist/chunks/{add-GWMRXCPO.js → add-4F6CBPSE.js} +4 -4
  2. package/dist/chunks/{chunk-DMKETFQS.js → chunk-2WND2XFN.js} +1 -1
  3. package/dist/chunks/{chunk-SASCGHJW.js → chunk-42PRZ45G.js} +4 -4
  4. package/dist/chunks/{chunk-FKD3R5S7.js → chunk-7IAMAKFC.js} +1 -1
  5. package/dist/chunks/{chunk-6ULI5CCZ.js → chunk-ADBU633H.js} +1 -1
  6. package/dist/chunks/{chunk-PB37FIFM.js → chunk-APC5GMBX.js} +1 -1
  7. package/dist/chunks/{chunk-RIDTMO6P.js → chunk-B744TFL4.js} +1 -1
  8. package/dist/chunks/{chunk-2QPZXMJE.js → chunk-DITVV3KE.js} +1 -1
  9. package/dist/chunks/{chunk-GVYAYUAT.js → chunk-FJP2X2TE.js} +2 -2
  10. package/dist/chunks/{chunk-4WWFHUVW.js → chunk-HVYPWTJQ.js} +2 -2
  11. package/dist/chunks/{chunk-Q3ZD22HR.js → chunk-HYFP6VVA.js} +2 -2
  12. package/dist/chunks/{chunk-T77OYIET.js → chunk-IDTFK3CR.js} +153 -96
  13. package/dist/chunks/{chunk-6YOW32LL.js → chunk-IOV7PLXQ.js} +4 -4
  14. package/dist/chunks/{chunk-HD23APLQ.js → chunk-JRPLGVXQ.js} +1 -1
  15. package/dist/chunks/{chunk-QUU263YC.js → chunk-LGWH2KFI.js} +20 -7
  16. package/dist/chunks/chunk-NLEBTR3S.js +181 -0
  17. package/dist/chunks/{chunk-OPAWD6UK.js → chunk-NZDGG7W3.js} +1 -1
  18. package/dist/chunks/{chunk-6UAZGWVF.js → chunk-OBWYK3NL.js} +1 -1
  19. package/dist/chunks/{chunk-5LI3PLS3.js → chunk-WNYUBBFH.js} +2 -2
  20. package/dist/chunks/{chunk-EMW6TUP2.js → chunk-ZYNF76YT.js} +10 -7
  21. package/dist/chunks/{compile-vercel-config-Y7NCY4TH.js → compile-vercel-config-CGU7GBYQ.js} +1 -1
  22. package/dist/chunks/{delete-53LWNN3R.js → delete-XKC6CE3R.js} +2 -2
  23. package/dist/chunks/{disable-PB4E5RT2.js → disable-F2RLDMXX.js} +2 -2
  24. package/dist/chunks/{discard-XJPKRCEX.js → discard-N4MILEID.js} +2 -2
  25. package/dist/chunks/{edit-LWDFUOJX.js → edit-PMIBPG7J.js} +3 -3
  26. package/dist/chunks/{enable-DBP5ARSO.js → enable-AON5KGOT.js} +2 -2
  27. package/dist/chunks/{export-LNTUARTL.js → export-OQKO5JVC.js} +2 -2
  28. package/dist/chunks/{inspect-MLAWEGMC.js → inspect-7TLOVORH.js} +3 -3
  29. package/dist/chunks/{list-FIZTMQ44.js → list-RJHF6SWM.js} +2 -2
  30. package/dist/chunks/{list-74DI6236.js → list-SCOE3N4I.js} +3 -3
  31. package/dist/chunks/{ls-3WF6K6R5.js → ls-CFTCULV5.js} +4 -4
  32. package/dist/chunks/{publish-BLJ4Z47H.js → publish-6VOT42HN.js} +2 -2
  33. package/dist/chunks/{query-N6O4SKZE.js → query-OHEBAPTS.js} +2 -2
  34. package/dist/chunks/{reorder-TGFBUZO6.js → reorder-GMIEF42H.js} +2 -2
  35. package/dist/chunks/{restore-RQB3RYLR.js → restore-JY2JCHOY.js} +2 -2
  36. package/dist/chunks/{rm-RY7JBRD5.js → rm-FQB3M5YP.js} +4 -4
  37. package/dist/chunks/{rule-inspect-ENVJZ4PJ.js → rule-inspect-2JWJRPGL.js} +4 -4
  38. package/dist/chunks/{rules-3SSZZT7O.js → rules-MULKOWZ5.js} +6 -6
  39. package/dist/chunks/{schema-F2RCHWJK.js → schema-4YC2WD3R.js} +2 -2
  40. package/dist/chunks/{update-QRLM425M.js → update-T4SXDA7F.js} +4 -4
  41. package/dist/commands/build/index.js +9 -9
  42. package/dist/commands/deploy/index.js +10 -10
  43. package/dist/commands/dev/index.js +369 -208
  44. package/dist/commands/env/index.js +4 -4
  45. package/dist/commands/link/index.js +7 -7
  46. package/dist/commands/list/index.js +3 -3
  47. package/dist/commands-bulk.js +31 -31
  48. package/dist/index.js +8 -8
  49. package/dist/version.mjs +1 -1
  50. package/package.json +21 -21
  51. package/dist/chunks/chunk-EAKQRHY6.js +0 -112
@@ -9,7 +9,7 @@ import {
9
9
  } from "../../chunks/chunk-2HSQ7YUK.js";
10
10
  import {
11
11
  getUpdateCommand
12
- } from "../../chunks/chunk-EAKQRHY6.js";
12
+ } from "../../chunks/chunk-NLEBTR3S.js";
13
13
  import {
14
14
  highlight
15
15
  } from "../../chunks/chunk-V5P25P7F.js";
@@ -26,23 +26,23 @@ import {
26
26
  require_mime_types,
27
27
  require_npa,
28
28
  staticFiles
29
- } from "../../chunks/chunk-2QPZXMJE.js";
29
+ } from "../../chunks/chunk-DITVV3KE.js";
30
30
  import "../../chunks/chunk-IB5L4LKZ.js";
31
31
  import {
32
32
  pickOverrides
33
- } from "../../chunks/chunk-HD23APLQ.js";
33
+ } from "../../chunks/chunk-JRPLGVXQ.js";
34
34
  import "../../chunks/chunk-YI3JV6GM.js";
35
35
  import {
36
36
  displayDetectedServices,
37
37
  printProjectNotFoundError,
38
38
  readConfig,
39
39
  setupAndLink
40
- } from "../../chunks/chunk-QUU263YC.js";
40
+ } from "../../chunks/chunk-LGWH2KFI.js";
41
41
  import "../../chunks/chunk-LJ5WXXG6.js";
42
42
  import {
43
43
  getLocalPathConfig
44
- } from "../../chunks/chunk-PB37FIFM.js";
45
- import "../../chunks/chunk-6ULI5CCZ.js";
44
+ } from "../../chunks/chunk-APC5GMBX.js";
45
+ import "../../chunks/chunk-ADBU633H.js";
46
46
  import {
47
47
  help
48
48
  } from "../../chunks/chunk-VNUNCNPE.js";
@@ -69,7 +69,7 @@ import {
69
69
  resolveProjectCwd,
70
70
  tryDetectServices,
71
71
  validateConfig
72
- } from "../../chunks/chunk-T77OYIET.js";
72
+ } from "../../chunks/chunk-IDTFK3CR.js";
73
73
  import {
74
74
  TelemetryClient
75
75
  } from "../../chunks/chunk-J5273CSE.js";
@@ -16323,8 +16323,112 @@ var require_src2 = __commonJS({
16323
16323
  }
16324
16324
  });
16325
16325
 
16326
- // ../../node_modules/.pnpm/@tootallnate+once@1.1.2/node_modules/@tootallnate/once/dist/index.js
16326
+ // ../../node_modules/.pnpm/pcre-to-regexp@1.0.0/node_modules/pcre-to-regexp/dist/index.js
16327
16327
  var require_dist6 = __commonJS({
16328
+ "../../node_modules/.pnpm/pcre-to-regexp@1.0.0/node_modules/pcre-to-regexp/dist/index.js"(exports2, module2) {
16329
+ "use strict";
16330
+ var characterClasses = {
16331
+ alnum: "[A-Za-z0-9]",
16332
+ word: "[A-Za-z0-9_]",
16333
+ alpha: "[A-Za-z]",
16334
+ blank: "[ \\t]",
16335
+ cntrl: "[\\x00-\\x1F\\x7F]",
16336
+ digit: "\\d",
16337
+ graph: "[\\x21-\\x7E]",
16338
+ lower: "[a-z]",
16339
+ print: "[\\x20-\\x7E]",
16340
+ punct: "[\\]\\[!\"#$%&'()*+,./:;<=>?@\\\\^_`{|}~-]",
16341
+ space: "\\s",
16342
+ upper: "[A-Z]",
16343
+ xdigit: "[A-Fa-f0-9]"
16344
+ };
16345
+ function createPCRE(pattern, namedCaptures) {
16346
+ pattern = String(pattern || "").trim();
16347
+ let originalPattern = pattern;
16348
+ let delim;
16349
+ let flags = "";
16350
+ let hasDelim = /^[^a-zA-Z\\\s]/.test(pattern);
16351
+ if (hasDelim) {
16352
+ delim = pattern[0];
16353
+ let lastDelimIndex = pattern.lastIndexOf(delim);
16354
+ flags += pattern.substring(lastDelimIndex + 1);
16355
+ pattern = pattern.substring(1, lastDelimIndex);
16356
+ }
16357
+ let numGroups = 0;
16358
+ pattern = replaceCaptureGroups(pattern, (group) => {
16359
+ if (/^\(\?[P<']/.test(group)) {
16360
+ let match = /^\(\?P?[<']([^>']+)[>']/.exec(group);
16361
+ if (!match) {
16362
+ throw new Error(`Failed to extract named captures from ${JSON.stringify(group)}`);
16363
+ }
16364
+ let capture = group.substring(match[0].length, group.length - 1);
16365
+ if (namedCaptures) {
16366
+ namedCaptures[numGroups] = match[1];
16367
+ }
16368
+ numGroups++;
16369
+ return `(${capture})`;
16370
+ }
16371
+ if (group.substring(0, 3) === "(?:") {
16372
+ return group;
16373
+ }
16374
+ numGroups++;
16375
+ return group;
16376
+ });
16377
+ pattern = pattern.replace(/\[:([^:]+):\]/g, (characterClass, name) => {
16378
+ return characterClasses[name] || characterClass;
16379
+ });
16380
+ let regexp = new RegExp(pattern, flags);
16381
+ regexp.delimiter = delim;
16382
+ regexp.pcrePattern = originalPattern;
16383
+ regexp.pcreFlags = flags;
16384
+ return regexp;
16385
+ }
16386
+ function replaceCaptureGroups(pattern, fn2) {
16387
+ let start = 0;
16388
+ let depth = 0;
16389
+ let escaped = false;
16390
+ for (let i = 0; i < pattern.length; i++) {
16391
+ let cur = pattern[i];
16392
+ if (escaped) {
16393
+ escaped = false;
16394
+ continue;
16395
+ }
16396
+ switch (cur) {
16397
+ case "(":
16398
+ if (depth === 0) {
16399
+ start = i;
16400
+ }
16401
+ depth++;
16402
+ break;
16403
+ case ")":
16404
+ if (depth > 0) {
16405
+ depth--;
16406
+ if (depth === 0) {
16407
+ let end = i + 1;
16408
+ let l = start === 0 ? "" : pattern.substring(0, start);
16409
+ let r = pattern.substring(end);
16410
+ let v = String(fn2(pattern.substring(start, end)));
16411
+ pattern = l + v + r;
16412
+ i = start;
16413
+ }
16414
+ }
16415
+ break;
16416
+ case "\\":
16417
+ escaped = true;
16418
+ break;
16419
+ default:
16420
+ break;
16421
+ }
16422
+ }
16423
+ return pattern;
16424
+ }
16425
+ createPCRE.characterClasses = characterClasses;
16426
+ module2.exports = createPCRE;
16427
+ }
16428
+ });
16429
+
16430
+ // ../../node_modules/.pnpm/@tootallnate+once@1.1.2/node_modules/@tootallnate/once/dist/index.js
16431
+ var require_dist7 = __commonJS({
16328
16432
  "../../node_modules/.pnpm/@tootallnate+once@1.1.2/node_modules/@tootallnate/once/dist/index.js"(exports2, module2) {
16329
16433
  "use strict";
16330
16434
  function noop() {
@@ -16487,110 +16591,6 @@ var require_is_port_reachable = __commonJS({
16487
16591
  }
16488
16592
  });
16489
16593
 
16490
- // ../../node_modules/.pnpm/pcre-to-regexp@1.0.0/node_modules/pcre-to-regexp/dist/index.js
16491
- var require_dist7 = __commonJS({
16492
- "../../node_modules/.pnpm/pcre-to-regexp@1.0.0/node_modules/pcre-to-regexp/dist/index.js"(exports2, module2) {
16493
- "use strict";
16494
- var characterClasses = {
16495
- alnum: "[A-Za-z0-9]",
16496
- word: "[A-Za-z0-9_]",
16497
- alpha: "[A-Za-z]",
16498
- blank: "[ \\t]",
16499
- cntrl: "[\\x00-\\x1F\\x7F]",
16500
- digit: "\\d",
16501
- graph: "[\\x21-\\x7E]",
16502
- lower: "[a-z]",
16503
- print: "[\\x20-\\x7E]",
16504
- punct: "[\\]\\[!\"#$%&'()*+,./:;<=>?@\\\\^_`{|}~-]",
16505
- space: "\\s",
16506
- upper: "[A-Z]",
16507
- xdigit: "[A-Fa-f0-9]"
16508
- };
16509
- function createPCRE(pattern, namedCaptures) {
16510
- pattern = String(pattern || "").trim();
16511
- let originalPattern = pattern;
16512
- let delim;
16513
- let flags = "";
16514
- let hasDelim = /^[^a-zA-Z\\\s]/.test(pattern);
16515
- if (hasDelim) {
16516
- delim = pattern[0];
16517
- let lastDelimIndex = pattern.lastIndexOf(delim);
16518
- flags += pattern.substring(lastDelimIndex + 1);
16519
- pattern = pattern.substring(1, lastDelimIndex);
16520
- }
16521
- let numGroups = 0;
16522
- pattern = replaceCaptureGroups(pattern, (group) => {
16523
- if (/^\(\?[P<']/.test(group)) {
16524
- let match = /^\(\?P?[<']([^>']+)[>']/.exec(group);
16525
- if (!match) {
16526
- throw new Error(`Failed to extract named captures from ${JSON.stringify(group)}`);
16527
- }
16528
- let capture = group.substring(match[0].length, group.length - 1);
16529
- if (namedCaptures) {
16530
- namedCaptures[numGroups] = match[1];
16531
- }
16532
- numGroups++;
16533
- return `(${capture})`;
16534
- }
16535
- if (group.substring(0, 3) === "(?:") {
16536
- return group;
16537
- }
16538
- numGroups++;
16539
- return group;
16540
- });
16541
- pattern = pattern.replace(/\[:([^:]+):\]/g, (characterClass, name) => {
16542
- return characterClasses[name] || characterClass;
16543
- });
16544
- let regexp = new RegExp(pattern, flags);
16545
- regexp.delimiter = delim;
16546
- regexp.pcrePattern = originalPattern;
16547
- regexp.pcreFlags = flags;
16548
- return regexp;
16549
- }
16550
- function replaceCaptureGroups(pattern, fn2) {
16551
- let start = 0;
16552
- let depth = 0;
16553
- let escaped = false;
16554
- for (let i = 0; i < pattern.length; i++) {
16555
- let cur = pattern[i];
16556
- if (escaped) {
16557
- escaped = false;
16558
- continue;
16559
- }
16560
- switch (cur) {
16561
- case "(":
16562
- if (depth === 0) {
16563
- start = i;
16564
- }
16565
- depth++;
16566
- break;
16567
- case ")":
16568
- if (depth > 0) {
16569
- depth--;
16570
- if (depth === 0) {
16571
- let end = i + 1;
16572
- let l = start === 0 ? "" : pattern.substring(0, start);
16573
- let r = pattern.substring(end);
16574
- let v = String(fn2(pattern.substring(start, end)));
16575
- pattern = l + v + r;
16576
- i = start;
16577
- }
16578
- }
16579
- break;
16580
- case "\\":
16581
- escaped = true;
16582
- break;
16583
- default:
16584
- break;
16585
- }
16586
- }
16587
- return pattern;
16588
- }
16589
- createPCRE.characterClasses = characterClasses;
16590
- module2.exports = createPCRE;
16591
- }
16592
- });
16593
-
16594
16594
  // ../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js
16595
16595
  var require_tree_kill = __commonJS({
16596
16596
  "../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js"(exports2, module2) {
@@ -16752,7 +16752,6 @@ import path4 from "path";
16752
16752
  var import_chalk3 = __toESM(require_source(), 1);
16753
16753
  var import_ms6 = __toESM(require_ms(), 1);
16754
16754
  var import_fs_extra2 = __toESM(require_lib(), 1);
16755
- var import_fs_detectors4 = __toESM(require_dist4(), 1);
16756
16755
  import { resolve, join as join4 } from "path";
16757
16756
 
16758
16757
  // src/util/dev/server.ts
@@ -16766,8 +16765,9 @@ var import_async_listen = __toESM(require_dist5(), 1);
16766
16765
  var import_minimatch2 = __toESM(require_minimatch(), 1);
16767
16766
  var import_http_proxy_node16 = __toESM(require_http_proxy_node16(), 1);
16768
16767
  var import_serve_handler = __toESM(require_src2(), 1);
16768
+ var import_pcre_to_regexp2 = __toESM(require_dist6(), 1);
16769
16769
  var import_dotenv = __toESM(require_main(), 1);
16770
- var import_once = __toESM(require_dist6(), 1);
16770
+ var import_once = __toESM(require_dist7(), 1);
16771
16771
  var import_directory = __toESM(require_directory(), 1);
16772
16772
  var import_get_port2 = __toESM(require_get_port(), 1);
16773
16773
  var import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);
@@ -16830,7 +16830,7 @@ function relative2(a, b) {
16830
16830
  }
16831
16831
 
16832
16832
  // src/util/dev/router.ts
16833
- var import_pcre_to_regexp = __toESM(require_dist7(), 1);
16833
+ var import_pcre_to_regexp = __toESM(require_dist6(), 1);
16834
16834
  import url from "url";
16835
16835
 
16836
16836
  // src/util/dev/is-url.ts
@@ -17728,6 +17728,7 @@ function getNextCronDelay(expression, now = /* @__PURE__ */ new Date()) {
17728
17728
 
17729
17729
  // src/util/dev/services-orchestrator.ts
17730
17730
  import {
17731
+ isExperimentalService,
17731
17732
  isQueueBackedService,
17732
17733
  isQueueTriggeredService,
17733
17734
  isScheduleTriggeredService,
@@ -17819,6 +17820,16 @@ function getServiceRoutePrefixes(service) {
17819
17820
  }
17820
17821
  return [];
17821
17822
  }
17823
+ function getEntrypointForService(builderSrc, entrypoint, dir) {
17824
+ let resolved = builderSrc || entrypoint || "";
17825
+ if (dir && dir !== ".") {
17826
+ const prefix = dir.endsWith("/") ? dir : `${dir}/`;
17827
+ if (resolved.startsWith(prefix)) {
17828
+ resolved = resolved.slice(prefix.length);
17829
+ }
17830
+ }
17831
+ return resolved;
17832
+ }
17822
17833
  var FORCE_KILL_GRACE_MS = 2e3;
17823
17834
  var STOP_ALL_TIMEOUT_MS = 8e3;
17824
17835
  function killGroup(pid, signal) {
@@ -17885,7 +17896,7 @@ var ServicesOrchestrator = class {
17885
17896
  this.pythonServiceCount = options.services.filter(
17886
17897
  (s) => s.runtime === "python"
17887
17898
  ).length;
17888
- this.hasQueueServices = options.services.some(isQueueBackedService);
17899
+ this.hasQueueServices = options.services.filter(isExperimentalService).some(isQueueBackedService);
17889
17900
  }
17890
17901
  // Synchronously SIGKILL every tracked process group. Used from
17891
17902
  // `process.on('exit' | 'uncaughtException')` so that orphans are reaped even
@@ -18071,13 +18082,37 @@ var ServicesOrchestrator = class {
18071
18082
  return this.managedServices;
18072
18083
  }
18073
18084
  async startService(service, colorIndex) {
18074
- const workspacePath = path2.join(this.cwd, service.workspace || ".");
18075
- const framework = import_frameworks.frameworkList.find((f) => f.slug === service.framework);
18076
18085
  const logger = createServiceLogger(
18077
18086
  service.name,
18078
18087
  colorIndex,
18079
18088
  this.maxNameLength
18080
18089
  );
18090
+ const spec = (0, import_fs_detectors2.isExperimentalServiceV2)(service) ? this.getV2StartSpec(service) : this.getV1StartSpec(service);
18091
+ if (spec.builderSpec) {
18092
+ const result = await this.tryStartWithBuilder(service.name, spec, logger);
18093
+ if (result) {
18094
+ return result;
18095
+ }
18096
+ }
18097
+ const devCommand2 = spec.explicitDevCommand || spec.framework?.settings?.devCommand?.value;
18098
+ if (!devCommand2) {
18099
+ throw new Error(
18100
+ `No dev server available for service "${service.name}" (framework: ${service.framework ?? "none"}).`
18101
+ );
18102
+ }
18103
+ return this.spawnDevCommandProcess({
18104
+ name: service.name,
18105
+ devCommand: devCommand2,
18106
+ workspacePath: spec.rootPath,
18107
+ env: spec.env,
18108
+ logger,
18109
+ builderConfig: spec.builderConfig,
18110
+ routePrefixes: spec.routePrefixes,
18111
+ workspaceLabel: spec.rootLabel
18112
+ });
18113
+ }
18114
+ getV1StartSpec(service) {
18115
+ const framework = import_frameworks.frameworkList.find((f) => f.slug === service.framework);
18081
18116
  const effectiveProcessEnv = cloneEnv(this.envFilesValues, process.env);
18082
18117
  let perServiceEnv = {};
18083
18118
  if (this.useImplicitEnvInjection) {
@@ -18120,72 +18155,96 @@ var ServicesOrchestrator = class {
18120
18155
  env.VERCEL_SERVICE_ROUTE_PREFIX = service.routePrefix;
18121
18156
  env.VERCEL_SERVICE_ROUTE_PREFIX_STRIP = "1";
18122
18157
  }
18123
- const builderSpec = framework?.useRuntime?.use || service.builder?.use;
18124
- if (builderSpec) {
18125
- const result = await this.tryStartWithBuilder(
18126
- service,
18127
- builderSpec,
18128
- workspacePath,
18129
- env,
18130
- logger
18131
- );
18132
- if (result) {
18133
- return result;
18134
- }
18135
- }
18136
- return this.startServiceWithDevCommand(
18137
- service,
18158
+ const workspace = service.workspace || ".";
18159
+ return {
18160
+ rootPath: path2.join(this.cwd, workspace),
18161
+ rootLabel: workspace,
18138
18162
  framework,
18139
- workspacePath,
18140
- env,
18141
- logger
18163
+ // Prefer the framework's useRuntime, falling back to the resolved builder.
18164
+ builderSpec: framework?.useRuntime?.use || service.builder?.use,
18165
+ entrypoint: getEntrypointForService(
18166
+ service.builder?.src,
18167
+ service.entrypoint,
18168
+ workspace
18169
+ ),
18170
+ builderConfig: service.builder?.config,
18171
+ frameworkForDev: service.framework || "services",
18172
+ servicePayload: {
18173
+ name: service.name,
18174
+ type: service.type,
18175
+ trigger: service.trigger,
18176
+ routePrefix: service.routePrefix,
18177
+ subdomain: service.subdomain,
18178
+ workspace: service.workspace,
18179
+ schedule: service.schedule
18180
+ },
18181
+ routePrefixes: getServiceRoutePrefixes(service),
18182
+ env
18183
+ };
18184
+ }
18185
+ getV2StartSpec(service) {
18186
+ const framework = import_frameworks.frameworkList.find((f) => f.slug === service.framework);
18187
+ const env = cloneEnv(
18188
+ {
18189
+ FORCE_COLOR: process.stdout.isTTY ? "1" : "0",
18190
+ BROWSER: "none"
18191
+ },
18192
+ cloneEnv(this.envFilesValues, process.env)
18142
18193
  );
18194
+ const root = service.root || ".";
18195
+ return {
18196
+ rootPath: path2.join(this.cwd, root),
18197
+ rootLabel: root,
18198
+ framework,
18199
+ builderSpec: framework?.useRuntime?.use || service.builder?.use,
18200
+ entrypoint: getEntrypointForService(
18201
+ service.builder?.src,
18202
+ service.entrypoint,
18203
+ root
18204
+ ),
18205
+ builderConfig: service.builder?.config,
18206
+ frameworkForDev: service.framework || "services",
18207
+ servicePayload: { name: service.name, workspace: root },
18208
+ routePrefixes: [],
18209
+ env,
18210
+ explicitDevCommand: service.devCommand
18211
+ };
18143
18212
  }
18144
- async tryStartWithBuilder(service, builderSpec, workspacePath, env, logger) {
18213
+ // Start a service via its builder's `startDevServer`, if it exposes one.
18214
+ // Returns null to fall back to a dev command
18215
+ async tryStartWithBuilder(name, spec, logger) {
18216
+ if (!spec.builderSpec) {
18217
+ return null;
18218
+ }
18145
18219
  try {
18146
- const builders = await importBuilders(/* @__PURE__ */ new Set([builderSpec]), this.cwd);
18147
- const builderWithPkg = builders.get(builderSpec);
18148
- const builder = builderWithPkg?.builder;
18220
+ const builders = await importBuilders(
18221
+ /* @__PURE__ */ new Set([spec.builderSpec]),
18222
+ this.cwd
18223
+ );
18224
+ const builder = builders.get(spec.builderSpec)?.builder;
18149
18225
  if (!builder?.startDevServer) {
18150
18226
  return null;
18151
18227
  }
18152
18228
  output_manager_default.debug(
18153
- `Starting ${import_chalk.default.bold(service.name)} using ${import_chalk.default.cyan.bold(builderSpec)}`
18229
+ `Starting ${import_chalk.default.bold(name)} using ${import_chalk.default.cyan.bold(spec.builderSpec)}`
18154
18230
  );
18155
- let entrypoint = service.builder?.src || service.entrypoint || "";
18156
- const workspace = service.workspace || ".";
18157
- if (workspace !== ".") {
18158
- const wsPrefix = workspace + "/";
18159
- if (entrypoint.startsWith(wsPrefix)) {
18160
- entrypoint = entrypoint.slice(wsPrefix.length);
18161
- }
18162
- }
18163
- const frameworkForDev = service.framework || "services";
18164
18231
  const result = await builder.startDevServer({
18165
- entrypoint,
18166
- workPath: workspacePath,
18232
+ entrypoint: spec.entrypoint,
18233
+ workPath: spec.rootPath,
18167
18234
  repoRootPath: this.repoRoot,
18168
18235
  config: {
18169
- ...service.builder?.config || {},
18170
- framework: frameworkForDev
18236
+ ...spec.builderConfig || {},
18237
+ framework: spec.frameworkForDev
18171
18238
  },
18172
18239
  meta: {
18173
18240
  isDev: true,
18174
- env,
18241
+ env: spec.env,
18175
18242
  serviceCount: this.services.length,
18176
18243
  pythonServiceCount: this.pythonServiceCount,
18177
18244
  syncDependencies: true,
18178
- serviceName: service.name
18179
- },
18180
- service: {
18181
- name: service.name,
18182
- type: service.type,
18183
- trigger: service.trigger,
18184
- routePrefix: service.routePrefix,
18185
- subdomain: service.subdomain,
18186
- workspace: service.workspace,
18187
- schedule: service.schedule
18245
+ serviceName: name
18188
18246
  },
18247
+ service: spec.servicePayload,
18189
18248
  files: {},
18190
18249
  onStdout: (data) => logger.stdout.write(data),
18191
18250
  onStderr: (data) => logger.stderr.write(data)
@@ -18194,35 +18253,38 @@ var ServicesOrchestrator = class {
18194
18253
  return null;
18195
18254
  }
18196
18255
  const host = await checkForPort(result.port, STARTUP_TIMEOUT);
18197
- output_manager_default.debug(`Service ${service.name} started on ${host}:${result.port}`);
18256
+ output_manager_default.debug(`Service ${name} started on ${host}:${result.port}`);
18198
18257
  return {
18199
- name: service.name,
18258
+ name,
18200
18259
  host,
18201
18260
  port: result.port,
18202
18261
  pid: result.pid,
18203
18262
  shutdown: result.shutdown,
18204
- routePrefixes: getServiceRoutePrefixes(service),
18205
- workspace: service.workspace || ".",
18263
+ routePrefixes: spec.routePrefixes,
18264
+ workspace: spec.rootLabel,
18206
18265
  logger,
18207
18266
  crons: result.crons
18208
18267
  };
18209
18268
  } catch (err) {
18210
- output_manager_default.debug(`Failed to use startDevServer for ${service.name}: ${err}`);
18269
+ output_manager_default.debug(`Failed to use startDevServer for ${name}: ${err}`);
18211
18270
  if (err instanceof NowBuildError) {
18212
18271
  throw err;
18213
18272
  }
18214
18273
  return null;
18215
18274
  }
18216
18275
  }
18217
- // Adapted from DevServer
18218
- async startServiceWithDevCommand(service, framework, workspacePath, env, logger) {
18219
- const devCommand2 = framework?.settings?.devCommand?.value;
18220
- if (!devCommand2) {
18221
- throw new Error(
18222
- `No dev server available for service "${service.name}" (framework: ${service.framework})`
18223
- );
18224
- }
18225
- await this.syncDependencies(service.builder?.config, workspacePath, logger);
18276
+ async spawnDevCommandProcess(params) {
18277
+ const {
18278
+ name,
18279
+ devCommand: devCommand2,
18280
+ workspacePath,
18281
+ env,
18282
+ logger,
18283
+ builderConfig,
18284
+ routePrefixes,
18285
+ workspaceLabel
18286
+ } = params;
18287
+ await this.syncDependencies(builderConfig, workspacePath, logger);
18226
18288
  const port = await (0, import_get_port.default)();
18227
18289
  env.PORT = `${port}`;
18228
18290
  const nodeBinPaths = getNodeBinPaths({
@@ -18232,7 +18294,7 @@ var ServicesOrchestrator = class {
18232
18294
  const nodeBinPath = nodeBinPaths.join(path2.delimiter);
18233
18295
  env.PATH = `${nodeBinPath}${path2.delimiter}${env.PATH}`;
18234
18296
  output_manager_default.debug(
18235
- `Starting ${import_chalk.default.bold(service.name)} with ${import_chalk.default.cyan.bold(`"${devCommand2}"`)}`
18297
+ `Starting ${import_chalk.default.bold(name)} with ${import_chalk.default.cyan.bold(`"${devCommand2}"`)}`
18236
18298
  );
18237
18299
  if (process.stdout.columns) {
18238
18300
  env.COLUMNS = `${process.stdout.columns}`;
@@ -18244,15 +18306,13 @@ var ServicesOrchestrator = class {
18244
18306
  detached: true
18245
18307
  });
18246
18308
  if (!child.pid) {
18247
- throw new Error(
18248
- `Failed to start service "${service.name}": no PID returned`
18249
- );
18309
+ throw new Error(`Failed to start service "${name}": no PID returned`);
18250
18310
  } else if (!child.stdout || !child.stderr) {
18251
18311
  throw new Error(
18252
- `Failed to start service "${service.name}": expected child process to have stdout and stderr`
18312
+ `Failed to start service "${name}": expected child process to have stdout and stderr`
18253
18313
  );
18254
18314
  }
18255
- this.managedProcesses.set(service.name, child);
18315
+ this.managedProcesses.set(name, child);
18256
18316
  child.stdout?.on("data", (chunk) => {
18257
18317
  logger.stdout.write(chunk);
18258
18318
  });
@@ -18261,20 +18321,20 @@ var ServicesOrchestrator = class {
18261
18321
  });
18262
18322
  let host;
18263
18323
  try {
18264
- host = await this.waitForPort(child, service.name, port);
18324
+ host = await this.waitForPort(child, name, port);
18265
18325
  } catch (error2) {
18266
- this.managedProcesses.delete(service.name);
18326
+ this.managedProcesses.delete(name);
18267
18327
  throw error2;
18268
18328
  }
18269
- output_manager_default.debug(`Service ${service.name} listening on ${host}:${port}`);
18329
+ output_manager_default.debug(`Service ${name} listening on ${host}:${port}`);
18270
18330
  return {
18271
- name: service.name,
18331
+ name,
18272
18332
  host,
18273
18333
  port,
18274
18334
  pid: child.pid,
18275
18335
  process: child,
18276
- routePrefixes: getServiceRoutePrefixes(service),
18277
- workspace: service.workspace || ".",
18336
+ routePrefixes,
18337
+ workspace: workspaceLabel,
18278
18338
  logger
18279
18339
  };
18280
18340
  }
@@ -18384,7 +18444,7 @@ var ServicesOrchestrator = class {
18384
18444
  startCronSchedulers() {
18385
18445
  for (const [name, managed] of this.managedServices) {
18386
18446
  const service = this.services.find((candidate) => candidate.name === name);
18387
- const crons = managed.crons && managed.crons.length > 0 ? managed.crons : service && isScheduleTriggeredService(service) && service.schedule ? getStaticServiceSchedules(service.schedule).map((schedule) => ({
18447
+ const crons = managed.crons && managed.crons.length > 0 ? managed.crons : service && isExperimentalService(service) && isScheduleTriggeredService(service) && service.schedule ? getStaticServiceSchedules(service.schedule).map((schedule) => ({
18388
18448
  path: (0, import_fs_detectors2.getInternalServiceCronPath)(
18389
18449
  name,
18390
18450
  service.entrypoint || service.builder.src || "index",
@@ -19357,6 +19417,15 @@ Please ensure that ${cmd(err.path)} is properly installed`;
19357
19417
  prevHeaders = routeResult.headers;
19358
19418
  }
19359
19419
  }
19420
+ if (callLevel === 0 && this.orchestrator && !routeResult.continue && isServiceDestination(routeResult.matched_route)) {
19421
+ return this.delegateToService(
19422
+ req,
19423
+ res,
19424
+ requestId,
19425
+ routeResult.matched_route,
19426
+ vercelConfig
19427
+ );
19428
+ }
19360
19429
  if (routeResult.isDestUrl) {
19361
19430
  const destParsed = url2.parse(routeResult.dest);
19362
19431
  const destQuery = parseQueryString(destParsed.search);
@@ -20048,7 +20117,7 @@ Please ensure that ${cmd(err.path)} is properly installed`;
20048
20117
  return void 0;
20049
20118
  }
20050
20119
  async _getVercelConfig() {
20051
- const { compileVercelConfig } = await import("../../chunks/compile-vercel-config-Y7NCY4TH.js");
20120
+ const { compileVercelConfig } = await import("../../chunks/compile-vercel-config-CGU7GBYQ.js");
20052
20121
  await compileVercelConfig(this.cwd);
20053
20122
  const configPath = getLocalPathConfig(this.cwd);
20054
20123
  const [
@@ -20353,10 +20422,10 @@ Please ensure that ${cmd(err.path)} is properly installed`;
20353
20422
  });
20354
20423
  devCommandPromise = this.orchestrator.startAll();
20355
20424
  this.devProcessOrigin = void 0;
20356
- const queueServices = (this.services || []).filter(isQueueBackedService3);
20425
+ const queueServices = (this.services || []).filter(import_fs_detectors3.isExperimentalService).filter(isQueueBackedService3);
20357
20426
  if (queueServices.length > 0) {
20358
20427
  this.queueBroker = new QueueBroker(
20359
- this.services || [],
20428
+ queueServices,
20360
20429
  (name) => this.orchestrator.getServiceOrigin(name)
20361
20430
  );
20362
20431
  }
@@ -20366,12 +20435,16 @@ Please ensure that ${cmd(err.path)} is properly installed`;
20366
20435
  }
20367
20436
  output_manager_default.print(`${import_chalk2.default.cyan(">")} Available at:
20368
20437
  `);
20369
- for (const service of this.services || []) {
20370
- if (service.type !== "web")
20371
- continue;
20372
- const servicePath = service.routePrefix || "/";
20373
- const serviceUrl = `${addressFormatted}${servicePath === "/" ? "" : servicePath}`;
20374
- output_manager_default.print(` ${import_chalk2.default.bold(service.name)}: ${link_default(serviceUrl)}
20438
+ const v1WebServices = (this.services || []).filter(import_fs_detectors3.isExperimentalService).filter((service) => service.type === "web");
20439
+ if (v1WebServices.length > 0) {
20440
+ for (const service of v1WebServices) {
20441
+ const servicePath = service.routePrefix || "/";
20442
+ const serviceUrl = `${addressFormatted}${servicePath === "/" ? "" : servicePath}`;
20443
+ output_manager_default.print(` ${import_chalk2.default.bold(service.name)}: ${link_default(serviceUrl)}
20444
+ `);
20445
+ }
20446
+ } else {
20447
+ output_manager_default.print(` ${link_default(addressFormatted)}
20375
20448
  `);
20376
20449
  }
20377
20450
  } else {
@@ -20642,6 +20715,97 @@ ${error_code}
20642
20715
  }
20643
20716
  return headers;
20644
20717
  }
20718
+ getServiceRouteTable(serviceName) {
20719
+ if (!this.serviceRoutesTable) {
20720
+ this.serviceRoutesTable = /* @__PURE__ */ new Map();
20721
+ for (const service of this.services || []) {
20722
+ if (!(0, import_fs_detectors3.isExperimentalServiceV2)(service))
20723
+ continue;
20724
+ const { routes, error: error2 } = (0, import_routing_utils3.getTransformedRoutes)({
20725
+ routes: service.routes,
20726
+ rewrites: service.rewrites,
20727
+ redirects: service.redirects,
20728
+ headers: service.headers,
20729
+ cleanUrls: service.cleanUrls,
20730
+ trailingSlash: service.trailingSlash
20731
+ });
20732
+ if (error2) {
20733
+ output_manager_default.warn(
20734
+ `Invalid routes for service "${service.name}": ${error2.message}`
20735
+ );
20736
+ this.serviceRoutesTable.set(service.name, []);
20737
+ } else {
20738
+ this.serviceRoutesTable.set(service.name, routes || []);
20739
+ }
20740
+ }
20741
+ }
20742
+ return this.serviceRoutesTable.get(serviceName) || [];
20743
+ }
20744
+ async delegateToService(req, res, requestId, matchedRoute, vercelConfig) {
20745
+ const { debug } = output_manager_default;
20746
+ const { service: serviceName, path: destPath } = matchedRoute.destination;
20747
+ const origin = this.orchestrator?.getServiceOrigin(serviceName);
20748
+ if (!origin) {
20749
+ output_manager_default.error(
20750
+ `Cannot route to service ${cmd(serviceName)}: it is not running.`
20751
+ );
20752
+ await this.sendError(
20753
+ req,
20754
+ res,
20755
+ requestId,
20756
+ "FUNCTION_INVOCATION_FAILED",
20757
+ 502
20758
+ );
20759
+ return;
20760
+ }
20761
+ const parsed = url2.parse(req.url || "/");
20762
+ const originalPathname = parsed.pathname || "/";
20763
+ let lookupPath = originalPathname;
20764
+ if (typeof destPath === "string" && matchedRoute.src) {
20765
+ const keys = [];
20766
+ const matcher = (0, import_pcre_to_regexp2.default)(
20767
+ `%${matchedRoute.src}%${this.isCaseSensitive() ? "" : "i"}`,
20768
+ keys
20769
+ );
20770
+ const match = matcher.exec(originalPathname) || matcher.exec(originalPathname.substring(1));
20771
+ lookupPath = match ? resolveRouteParameters(destPath, match, keys) : destPath;
20772
+ }
20773
+ const serviceRoutes = this.getServiceRouteTable(serviceName);
20774
+ const proxyHeaders = this.getProxyHeaders(req, requestId, false);
20775
+ if (serviceRoutes.length > 0) {
20776
+ const serviceResult = await devRouter(
20777
+ `${lookupPath}${parsed.search || ""}`,
20778
+ req.method,
20779
+ serviceRoutes,
20780
+ this,
20781
+ vercelConfig
20782
+ );
20783
+ const location = serviceResult.headers?.location;
20784
+ if (location && typeof serviceResult.status === "number" && serviceResult.status >= 300 && serviceResult.status < 400) {
20785
+ await this.sendRedirect(
20786
+ req,
20787
+ res,
20788
+ requestId,
20789
+ location,
20790
+ serviceResult.status
20791
+ );
20792
+ return;
20793
+ }
20794
+ if (serviceResult.headers) {
20795
+ for (const [name, value] of Object.entries(serviceResult.headers)) {
20796
+ if (name === "location")
20797
+ continue;
20798
+ res.setHeader(name, value);
20799
+ }
20800
+ }
20801
+ }
20802
+ for (const [name, value] of Object.entries(proxyHeaders)) {
20803
+ req.headers[name] = value;
20804
+ }
20805
+ this.setResponseHeaders(res, requestId);
20806
+ debug(`Delegating to service "${serviceName}": ${origin}`);
20807
+ return proxyPass(req, res, origin, this, requestId, false);
20808
+ }
20645
20809
  async triggerBuild(match, requestPath, req, vercelConfig, previousBuildResult, filesChanged, filesRemoved) {
20646
20810
  const buildKey = requestPath === null ? match.entrypoint : `${match.entrypoint}-${requestPath}`;
20647
20811
  let buildPromise = this.inProgressBuilds.get(buildKey);
@@ -20853,6 +21017,9 @@ ${error_code}
20853
21017
  this.devProcessOrigin = `http://${devProcessHost}:${port}`;
20854
21018
  }
20855
21019
  };
21020
+ function isServiceDestination(route) {
21021
+ return !!route && !(0, import_routing_utils3.isHandler)(route) && typeof route.destination === "object" && route.destination !== null && route.destination.type === "service";
21022
+ }
20856
21023
  function proxyPass(req, res, dest, devServer, requestId, ignorePath = true) {
20857
21024
  devServer.proxy.web(
20858
21025
  req,
@@ -21339,13 +21506,7 @@ To link your project, run ${getCommandName("dev")} without \`-L\` or \`--local\`
21339
21506
  const servicesResult = await tryDetectServices(cwd);
21340
21507
  const foundServices = servicesResult && servicesResult.services.length > 0;
21341
21508
  if (foundServices) {
21342
- services = servicesResult.services.filter(import_fs_detectors4.isExperimentalService);
21343
- if (servicesResult.services.length !== services.length) {
21344
- output_manager_default.error(
21345
- `${getCommandName("dev")} supports only \`experimentalServices\`.`
21346
- );
21347
- return 1;
21348
- }
21509
+ services = servicesResult.services;
21349
21510
  displayDetectedServices(services);
21350
21511
  useImplicitServicesEnvInjection = servicesResult.useImplicitEnvInjection;
21351
21512
  }