vercel 59.5.0 → 59.6.2

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 (113) hide show
  1. package/dist/chunks/{add-W3FFMTX4.js → add-4GQZ22ZN.js} +11 -11
  2. package/dist/chunks/{add-MH3WV6PV.js → add-HJSEM4YJ.js} +11 -11
  3. package/dist/chunks/{add-Z5FM6TFI.js → add-SIGUSM3Y.js} +12 -12
  4. package/dist/chunks/{build-VYYFBJL7.js → build-XOMJDX4M.js} +11 -11
  5. package/dist/chunks/{chunk-NSU2BTRS.js → chunk-2O5J3KMT.js} +4 -4
  6. package/dist/chunks/{chunk-RZ5NP6HN.js → chunk-2YRAWYGE.js} +1 -1
  7. package/dist/chunks/{chunk-JNU3DTEV.js → chunk-37V5P4VO.js} +9 -9
  8. package/dist/chunks/{chunk-LLM3ZNXJ.js → chunk-3F5EGINT.js} +2 -2
  9. package/dist/chunks/{chunk-KQRVZWJU.js → chunk-3T7WSWZH.js} +1 -1
  10. package/dist/chunks/{chunk-R6IGDGX3.js → chunk-5XECIWME.js} +1 -1
  11. package/dist/chunks/{chunk-AWSLWAOC.js → chunk-6JPVTPTU.js} +3 -3
  12. package/dist/chunks/{chunk-M3OSDZPY.js → chunk-6M2KZUED.js} +16 -7
  13. package/dist/chunks/{chunk-HT2XWSAJ.js → chunk-7AEEQOD4.js} +2 -29
  14. package/dist/chunks/{chunk-QG4PCM45.js → chunk-7HE63HCR.js} +102 -15
  15. package/dist/chunks/{chunk-V4YLY44R.js → chunk-7R6M3BHM.js} +2 -2
  16. package/dist/chunks/{chunk-XBN2O34P.js → chunk-7ST552E3.js} +17 -4
  17. package/dist/chunks/{chunk-CV4S27SS.js → chunk-ASBP32T6.js} +1 -1
  18. package/dist/chunks/{chunk-CQJRLNTX.js → chunk-AYLY3ZVL.js} +2 -2
  19. package/dist/chunks/{chunk-AWCID36T.js → chunk-BMKU5KEL.js} +1 -1
  20. package/dist/chunks/{chunk-UUVMIXT4.js → chunk-DE7MBNHQ.js} +4 -4
  21. package/dist/chunks/{chunk-YIHOS3ZF.js → chunk-FRAXI2WT.js} +1 -1
  22. package/dist/chunks/{chunk-FA3MO56Q.js → chunk-FRZULOVH.js} +5 -5
  23. package/dist/chunks/{chunk-7XX4ZEOV.js → chunk-FWKSJYDV.js} +1 -1
  24. package/dist/chunks/{chunk-OHER4DGX.js → chunk-FXD67VN5.js} +25 -9
  25. package/dist/chunks/{chunk-TIWAL2YU.js → chunk-GISTGGBO.js} +6 -6
  26. package/dist/chunks/{chunk-CSCSGSQG.js → chunk-GZQQNLF5.js} +5 -5
  27. package/dist/chunks/{chunk-PIMIKY4X.js → chunk-IJ4X426J.js} +1 -1
  28. package/dist/chunks/{chunk-TDXNNIZ6.js → chunk-JH4WQRIU.js} +2 -2
  29. package/dist/chunks/{chunk-TVXCXIRO.js → chunk-L3UXB2CW.js} +1 -1
  30. package/dist/chunks/{chunk-4JTF6RD7.js → chunk-LXZVOR6F.js} +4 -4
  31. package/dist/chunks/{chunk-L7CEMAJG.js → chunk-NGGLYKNU.js} +27 -5
  32. package/dist/chunks/{chunk-VWYNSJXI.js → chunk-NGNN6WF2.js} +8 -8
  33. package/dist/chunks/{chunk-GGPE5377.js → chunk-O26N2UPI.js} +1 -1
  34. package/dist/chunks/{chunk-5LX2JDZP.js → chunk-O75LSD3C.js} +1 -1
  35. package/dist/chunks/{chunk-MRMNMFMD.js → chunk-PRH6KRUT.js} +1 -1
  36. package/dist/chunks/{chunk-OX7KI3LF.js → chunk-QFAS4OVW.js} +18 -0
  37. package/dist/chunks/{chunk-PBHBX6UL.js → chunk-R5PULMHT.js} +3 -3
  38. package/dist/chunks/{chunk-PPUWG2UB.js → chunk-SF3AYAIF.js} +58 -25
  39. package/dist/chunks/{chunk-TAZ5ZAKG.js → chunk-SWI6F4X3.js} +2 -2
  40. package/dist/chunks/{chunk-ZKUHCL6O.js → chunk-V3MDDR2X.js} +5 -5
  41. package/dist/chunks/{chunk-E6LFKMI2.js → chunk-VJ5NAOWB.js} +791 -122
  42. package/dist/chunks/{chunk-G75NFPIT.js → chunk-WNAKOXGK.js} +1 -1
  43. package/dist/chunks/{chunk-JJQP3PYM.js → chunk-WZ2S3A2A.js} +5 -5
  44. package/dist/chunks/{chunk-CYNB6LL4.js → chunk-XNFHNTS2.js} +1 -1
  45. package/dist/chunks/{chunk-47VQ6H2S.js → chunk-YJKZQEHS.js} +2 -2
  46. package/dist/chunks/{chunk-GUWPUX2Y.js → chunk-ZNMTDLYH.js} +4 -4
  47. package/dist/chunks/{chunk-VLPLCJZC.js → chunk-ZSFEACZU.js} +1 -1
  48. package/dist/chunks/{clear-TNGRDA7D.js → clear-BWT2FJY4.js} +11 -11
  49. package/dist/chunks/{compile-vercel-config-ERLXKKWW.js → compile-vercel-config-DGM4NISW.js} +7 -7
  50. package/dist/chunks/{config-H22EE765.js → config-NJAN3RMU.js} +11 -11
  51. package/dist/chunks/{config-7EDKML5Q.js → config-RSE6Z4LB.js} +9 -9
  52. package/dist/chunks/{constants-YMCRE6IG.js → constants-WEQVJSYS.js} +1 -1
  53. package/dist/chunks/{delete-Q4S5F2AI.js → delete-LROBRBAH.js} +9 -9
  54. package/dist/chunks/{delete-LORYIZHY.js → delete-SSL2PK2F.js} +8 -8
  55. package/dist/chunks/{disable-HKWCBDJC.js → disable-ASG5JDZR.js} +8 -8
  56. package/dist/chunks/{discard-UCCRF2JQ.js → discard-PV47B6IL.js} +8 -8
  57. package/dist/chunks/{edit-AWL35PYQ.js → edit-5ATYIOLX.js} +10 -10
  58. package/dist/chunks/{edit-6IM6VRBR.js → edit-REI7HXGG.js} +10 -10
  59. package/dist/chunks/{enable-GN3D3L3V.js → enable-LZXL7XAG.js} +8 -8
  60. package/dist/chunks/{exec-CNBOV577.js → exec-XH4K34JM.js} +3 -3
  61. package/dist/chunks/{export-HHRVFALV.js → export-ZAZFQU2E.js} +8 -8
  62. package/dist/chunks/{image-4DCU4VPP.js → image-QPHN5V7L.js} +6 -6
  63. package/dist/chunks/{import-builders-DVG3HOTF.js → import-builders-W3YE2V6A.js} +9 -9
  64. package/dist/chunks/{inspect-TUW67CFZ.js → inspect-BFGK72WY.js} +10 -10
  65. package/dist/chunks/{inspect-TGOJDKIT.js → inspect-FRXJRM6T.js} +9 -9
  66. package/dist/chunks/{inspect-B3OWUFLH.js → inspect-RDMC2Z3Q.js} +11 -11
  67. package/dist/chunks/{inspect-VPME6UC7.js → inspect-SJEZVGPK.js} +11 -11
  68. package/dist/chunks/{inspect-VLGKNHJW.js → inspect-SSOM3FXS.js} +11 -11
  69. package/dist/chunks/{list-K552ITMK.js → list-2HTR7Q3J.js} +9 -9
  70. package/dist/chunks/{list-TK2JO7BK.js → list-PHDUZVMR.js} +8 -8
  71. package/dist/chunks/{list-2DPKDHRV.js → list-W33GXKDA.js} +10 -10
  72. package/dist/chunks/{login-HRWEKW5P.js → login-JWAFHVDG.js} +21 -12
  73. package/dist/chunks/{ls-M5TYGFP5.js → ls-3AN2DZHN.js} +11 -11
  74. package/dist/chunks/{ls-YIF3KLF3.js → ls-3MH2OCP3.js} +11 -11
  75. package/dist/chunks/{ls-TM6NTZEB.js → ls-D2POUHI7.js} +9 -9
  76. package/dist/chunks/{ls-JSV2WZVF.js → ls-KDFU224B.js} +11 -11
  77. package/dist/chunks/{ls-IOXGXEY4.js → ls-KX2VBOGV.js} +10 -10
  78. package/dist/chunks/{ls-O2WYF5UL.js → ls-RWKNJQNT.js} +11 -11
  79. package/dist/chunks/{open-FWAVEWGU.js → open-IEYRB6RL.js} +9 -9
  80. package/dist/chunks/{permissions-DPFYL47Z.js → permissions-ZWZUMEHR.js} +7 -7
  81. package/dist/chunks/{publish-63CGFKQR.js → publish-UWZYBDHK.js} +8 -8
  82. package/dist/chunks/{push-T5ZTBW3P.js → push-IAEQ3FBF.js} +11 -11
  83. package/dist/chunks/{query-B6O3EMEV.js → query-NNOZYSED.js} +11 -11
  84. package/dist/chunks/{reorder-ANV4NMKH.js → reorder-TKBM244W.js} +8 -8
  85. package/dist/chunks/{reply-C73KGOCG.js → reply-FLBSBMTW.js} +10 -10
  86. package/dist/chunks/{resolve-IHSIVPEE.js → resolve-GJYPMWUE.js} +9 -9
  87. package/dist/chunks/{restore-GSUNXP2O.js → restore-PNI3TM3U.js} +8 -8
  88. package/dist/chunks/{rm-4O74PS4Q.js → rm-76CSSSSV.js} +11 -11
  89. package/dist/chunks/{rm-M7IJC2WZ.js → rm-FN7LTIIL.js} +11 -11
  90. package/dist/chunks/{rm-YDTK5ESZ.js → rm-FTE33UHE.js} +10 -10
  91. package/dist/chunks/{rm-RV5SQFQA.js → rm-FXA5DLXQ.js} +11 -13
  92. package/dist/chunks/{rm-PRINF4OU.js → rm-PGJ4KR6U.js} +11 -11
  93. package/dist/chunks/{routes-SZI2G4SE.js → routes-2OLIBRYX.js} +3 -3
  94. package/dist/chunks/{rule-inspect-ZZC53FLP.js → rule-inspect-LJIGPTWS.js} +10 -10
  95. package/dist/chunks/{rules-SAOSSGFI.js → rules-6BMNO6M5.js} +10 -10
  96. package/dist/chunks/{schema-23ZFAKDU.js → schema-45SJNY5L.js} +4 -4
  97. package/dist/chunks/{schema-2Q3QRMRO.js → schema-HATXEQDP.js} +9 -9
  98. package/dist/chunks/{set-L47ZCZBJ.js → set-C3UQUQ42.js} +9 -9
  99. package/dist/chunks/{tags-2TWLM77N.js → tags-BTVDROFG.js} +5 -5
  100. package/dist/chunks/{types-G3PEUIJH.js → types-JGANJ5EQ.js} +3 -3
  101. package/dist/chunks/{update-SZH2VBD6.js → update-B6PSOHUW.js} +12 -12
  102. package/dist/commands/build/builder-worker.cjs +281 -0
  103. package/dist/commands/build/index.js +690 -235
  104. package/dist/commands/deploy/index.js +103 -31
  105. package/dist/commands/dev/index.js +669 -140
  106. package/dist/commands/env/index.js +1167 -542
  107. package/dist/commands/link/index.js +10 -10
  108. package/dist/commands/list/index.js +10 -10
  109. package/dist/commands-bulk.js +1978 -953
  110. package/dist/index.js +18 -18
  111. package/dist/version.mjs +1 -1
  112. package/package.json +47 -47
  113. package/dist/chunks/chunk-HGRWPPYB.js +0 -18
@@ -23,7 +23,7 @@ import {
23
23
  toRule,
24
24
  writeConfigJson,
25
25
  writeSamplingRules
26
- } from "./chunk-ZKUHCL6O.js";
26
+ } from "./chunk-V3MDDR2X.js";
27
27
  import "./chunk-5GGUB4EO.js";
28
28
  import {
29
29
  validateJsonOutput
@@ -36,22 +36,22 @@ import {
36
36
  } from "./chunk-GY5I4AYD.js";
37
37
  import {
38
38
  help
39
- } from "./chunk-RZ5NP6HN.js";
40
- import "./chunk-E6LFKMI2.js";
41
- import "./chunk-OHER4DGX.js";
39
+ } from "./chunk-2YRAWYGE.js";
40
+ import "./chunk-VJ5NAOWB.js";
41
+ import "./chunk-FXD67VN5.js";
42
42
  import {
43
43
  TelemetryClient
44
- } from "./chunk-CYNB6LL4.js";
45
- import "./chunk-L7CEMAJG.js";
44
+ } from "./chunk-XNFHNTS2.js";
45
+ import "./chunk-NGGLYKNU.js";
46
46
  import "./chunk-GGP5R3FU.js";
47
47
  import {
48
48
  printError
49
- } from "./chunk-CQJRLNTX.js";
49
+ } from "./chunk-AYLY3ZVL.js";
50
50
  import {
51
51
  parseArguments
52
52
  } from "./chunk-57RHXXXG.js";
53
53
  import "./chunk-RKDCNQ4S.js";
54
- import "./chunk-AWCID36T.js";
54
+ import "./chunk-BMKU5KEL.js";
55
55
  import {
56
56
  getCommandName,
57
57
  getCommandNamePlain,
@@ -61,7 +61,7 @@ import "./chunk-P4QNYOFB.js";
61
61
  import "./chunk-52QYYTM5.js";
62
62
  import {
63
63
  output_manager_default
64
- } from "./chunk-OX7KI3LF.js";
64
+ } from "./chunk-QFAS4OVW.js";
65
65
  import {
66
66
  require_source
67
67
  } from "./chunk-S7KYDPEM.js";
@@ -14,13 +14,13 @@ import {
14
14
  AGENT_REASON,
15
15
  buildCommandWithGlobalFlags,
16
16
  outputAgentError
17
- } from "./chunk-L7CEMAJG.js";
18
- import "./chunk-AWCID36T.js";
17
+ } from "./chunk-NGGLYKNU.js";
18
+ import "./chunk-BMKU5KEL.js";
19
19
  import "./chunk-Q2DGFCO7.js";
20
20
  import "./chunk-P4QNYOFB.js";
21
21
  import {
22
22
  output_manager_default
23
- } from "./chunk-OX7KI3LF.js";
23
+ } from "./chunk-QFAS4OVW.js";
24
24
  import "./chunk-S7KYDPEM.js";
25
25
  import "./chunk-TZ2YI2VH.js";
26
26
 
@@ -53,9 +53,9 @@ async function tags(client, argv, telemetry) {
53
53
  }
54
54
  switch (subcommand) {
55
55
  case "ls":
56
- return (await import("./ls-YIF3KLF3.js")).default(client, args, telemetry);
56
+ return (await import("./ls-3MH2OCP3.js")).default(client, args, telemetry);
57
57
  case "inspect":
58
- return (await import("./inspect-B3OWUFLH.js")).default(client, args, telemetry);
58
+ return (await import("./inspect-RDMC2Z3Q.js")).default(client, args, telemetry);
59
59
  default:
60
60
  output_manager_default.error(`Unhandled tags subcommand: ${subcommand}`);
61
61
  return 1;
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-4KD5BYHB.js";
13
13
  import {
14
14
  printError
15
- } from "./chunk-CQJRLNTX.js";
15
+ } from "./chunk-AYLY3ZVL.js";
16
16
  import {
17
17
  parseArguments
18
18
  } from "./chunk-57RHXXXG.js";
@@ -21,14 +21,14 @@ import {
21
21
  } from "./chunk-RKDCNQ4S.js";
22
22
  import {
23
23
  isAPIError
24
- } from "./chunk-AWCID36T.js";
24
+ } from "./chunk-BMKU5KEL.js";
25
25
  import {
26
26
  getFlagsSpecification
27
27
  } from "./chunk-Q2DGFCO7.js";
28
28
  import "./chunk-P4QNYOFB.js";
29
29
  import {
30
30
  output_manager_default
31
- } from "./chunk-OX7KI3LF.js";
31
+ } from "./chunk-QFAS4OVW.js";
32
32
  import {
33
33
  require_source
34
34
  } from "./chunk-S7KYDPEM.js";
@@ -8,16 +8,16 @@ import {
8
8
  parseCustomAlertQueryBody,
9
9
  resolveCustomAlertProjectName,
10
10
  setMissingCustomAlertProjectScope
11
- } from "./chunk-CSCSGSQG.js";
11
+ } from "./chunk-GZQQNLF5.js";
12
12
  import {
13
13
  emitRulesArgParseError,
14
14
  handleRulesApiError,
15
15
  parseRulesFlagsAndScope,
16
16
  rulesItemPath
17
- } from "./chunk-PBHBX6UL.js";
18
- import "./chunk-NSU2BTRS.js";
19
- import "./chunk-KQRVZWJU.js";
20
- import "./chunk-4JTF6RD7.js";
17
+ } from "./chunk-R5PULMHT.js";
18
+ import "./chunk-2O5J3KMT.js";
19
+ import "./chunk-3T7WSWZH.js";
20
+ import "./chunk-LXZVOR6F.js";
21
21
  import "./chunk-AINIBIP4.js";
22
22
  import {
23
23
  validateJsonOutput
@@ -25,25 +25,25 @@ import {
25
25
  import {
26
26
  rulesUpdateSubcommand
27
27
  } from "./chunk-XM3LOQIX.js";
28
- import "./chunk-E6LFKMI2.js";
29
- import "./chunk-OHER4DGX.js";
30
- import "./chunk-CYNB6LL4.js";
28
+ import "./chunk-VJ5NAOWB.js";
29
+ import "./chunk-FXD67VN5.js";
30
+ import "./chunk-XNFHNTS2.js";
31
31
  import {
32
32
  AGENT_REASON,
33
33
  buildCommandWithGlobalFlags,
34
34
  outputAgentError
35
- } from "./chunk-L7CEMAJG.js";
35
+ } from "./chunk-NGGLYKNU.js";
36
36
  import "./chunk-GGP5R3FU.js";
37
37
  import {
38
38
  printError
39
- } from "./chunk-CQJRLNTX.js";
39
+ } from "./chunk-AYLY3ZVL.js";
40
40
  import {
41
41
  parseArguments
42
42
  } from "./chunk-57RHXXXG.js";
43
43
  import "./chunk-RKDCNQ4S.js";
44
44
  import {
45
45
  isAPIError
46
- } from "./chunk-AWCID36T.js";
46
+ } from "./chunk-BMKU5KEL.js";
47
47
  import {
48
48
  getFlagsSpecification,
49
49
  packageName
@@ -52,7 +52,7 @@ import "./chunk-P4QNYOFB.js";
52
52
  import "./chunk-52QYYTM5.js";
53
53
  import {
54
54
  output_manager_default
55
- } from "./chunk-OX7KI3LF.js";
55
+ } from "./chunk-QFAS4OVW.js";
56
56
  import "./chunk-S7KYDPEM.js";
57
57
  import "./chunk-TZ2YI2VH.js";
58
58
 
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Forked worker that runs a single builder's `build()` (and `diagnostics()`) in its own
3
+ * process for `vc build`. Running each build out-of-process gives it isolated stdout/stderr
4
+ * — which the parent pipes and can prefix per line with the service name — and isolated
5
+ * env, which is a prerequisite for running builds in parallel.
6
+ *
7
+ * This is modeled on the `vc dev` worker (../dev/builder-worker.cjs) and shares its IPC
8
+ * contract (`ready` / `build` / `buildResult`), but it serializes Lambda/EdgeFunction outputs
9
+ * by preserving their `files` map (as FileFsRef/FileBlob descriptors) instead of zipping them.
10
+ * `vc build`'s writeLambda relies on `lambda.files` for the FileFsRef-by-reference optimization,
11
+ * the `filePathMap`, and `standalone` symlink handling — all of which are lost if we ship only
12
+ * a `zipBuffer` the way the dev worker does.
13
+ *
14
+ * Like the dev worker, this file is copied verbatim into `dist` next to the compiled `build`
15
+ * command, so it must only `require` `@vercel/build-utils` and Node built-ins.
16
+ */
17
+ const { FileFsRef, Span } = require('@vercel/build-utils');
18
+ const fs = require('node:fs');
19
+ const path = require('node:path');
20
+ const os = require('node:os');
21
+ const crypto = require('node:crypto');
22
+
23
+ // Trace events produced by the builder's own spans (children of buildOptions.span) are collected
24
+ // here and shipped back to the parent, which reports them under its `vc.builder` span so forked
25
+ // builds keep full trace fidelity. Included on both success and error messages so a failed build
26
+ // still contributes the spans it managed to record. Emptied after each send so a later phase
27
+ // (the deferred pre-deploy step) ships only the events it newly recorded.
28
+ let collectedTraceEvents = [];
29
+ const traceReporter = { report: event => collectedTraceEvents.push(event) };
30
+ // Take the events collected so far and reset the buffer, so the next send starts fresh.
31
+ function drainTraceEvents() {
32
+ const events = collectedTraceEvents;
33
+ collectedTraceEvents = [];
34
+ return events;
35
+ }
36
+
37
+ // Above this size a FileBlob's Buffer is written to a temp file rather than sent inline over
38
+ // IPC. Even under structured-clone serialization the whole Buffer is copied into a single IPC
39
+ // message; spilling very large blobs to disk bounds that per-message memory spike.
40
+ const BLOB_FILE_THRESHOLD = 256 * 1024 * 1024; // 256MB
41
+
42
+ process.on('unhandledRejection', err => {
43
+ // biome-ignore lint/suspicious/noConsole: intentional console usage
44
+ console.error('Exiting builder due to build error:');
45
+ // biome-ignore lint/suspicious/noConsole: intentional console usage
46
+ console.error(err);
47
+ process.exit(1);
48
+ });
49
+
50
+ // A builder may register a pre-deploy callback during build(). The CLI runs pre-deploys only
51
+ // after every build succeeds, so we hold the callback here and run it when the parent sends a
52
+ // `runPreDeploy` message, keeping the builder-computed env the callback captured.
53
+ let preDeployCallback;
54
+
55
+ // Key under which processMessage stashes the diagnostics it collected for a build that threw, so
56
+ // the error path in onMessage can ship them. A Symbol, so `serializeError` (which copies own
57
+ // property *names*) can't fold it into the error the parent writes into builds.json.
58
+ const DIAGNOSTICS = Symbol('diagnostics');
59
+
60
+ process.on('message', onMessage);
61
+
62
+ // Convert an Error into a plain object with all its properties enumerable. Structured-clone IPC
63
+ // reconstructs a native Error but keeps only `name`/`message`/`stack` — custom props a builder
64
+ // sets (e.g. NowBuildError's `code`/`link`, which the parent writes into builds.json) would be
65
+ // dropped. A plain object clones losslessly; the parent rebuilds an Error from it.
66
+ function serializeError(err) {
67
+ if (!err || typeof err !== 'object') return err;
68
+ const plain = { name: err.name, message: err.message, stack: err.stack };
69
+ for (const key of Object.getOwnPropertyNames(err)) {
70
+ plain[key] = err[key];
71
+ }
72
+ return plain;
73
+ }
74
+
75
+ function onMessage(message) {
76
+ if (message && message.type === 'runPreDeploy') {
77
+ runPreDeploy();
78
+ return;
79
+ }
80
+ processMessage(message).catch(err => {
81
+ process.removeListener('message', onMessage);
82
+ process.send(
83
+ {
84
+ type: 'buildResult',
85
+ error: serializeError(err),
86
+ // A failed build is exactly when diagnostics matter most, so ship whatever the builder
87
+ // recorded before it threw. `processMessage` collects them in a `finally` and stashes
88
+ // them on the error (see DIAGNOSTICS) on its way out.
89
+ diagnostics: err?.[DIAGNOSTICS],
90
+ traceEvents: drainTraceEvents(),
91
+ },
92
+ () => process.exit(1)
93
+ );
94
+ });
95
+ }
96
+
97
+ function runPreDeploy() {
98
+ Promise.resolve()
99
+ .then(() => preDeployCallback?.())
100
+ .then(
101
+ () =>
102
+ process.send(
103
+ { type: 'preDeployResult', traceEvents: drainTraceEvents() },
104
+ () => process.exit(0)
105
+ ),
106
+ err => {
107
+ process.send(
108
+ {
109
+ type: 'preDeployResult',
110
+ error: serializeError(err),
111
+ traceEvents: drainTraceEvents(),
112
+ },
113
+ () => process.exit(1)
114
+ );
115
+ }
116
+ );
117
+ }
118
+
119
+ // Re-prototype a plain object sent over IPC back into a FileFsRef instance.
120
+ function rehydrateFile(obj) {
121
+ return Object.assign(Object.create(FileFsRef.prototype), obj);
122
+ }
123
+
124
+ // Serialize a Files map for transport. FileFsRef entries are cheap path references and pass
125
+ // through as-is; FileBlob entries carry a Buffer, which is left inline unless it exceeds the
126
+ // threshold, in which case it is spilled to a temp file the parent reads and unlinks.
127
+ function serializeFiles(files) {
128
+ if (!files) return files;
129
+ for (const name of Object.keys(files)) {
130
+ const file = files[name];
131
+ if (file && file.type === 'FileBlob' && Buffer.isBuffer(file.data)) {
132
+ if (file.data.length > BLOB_FILE_THRESHOLD) {
133
+ const tmp = path.join(
134
+ os.tmpdir(),
135
+ `vercel-build-blob-${crypto.randomBytes(8).toString('hex')}`
136
+ );
137
+ fs.writeFileSync(tmp, file.data);
138
+ file.dataPath = tmp;
139
+ delete file.data;
140
+ }
141
+ }
142
+ }
143
+ return files;
144
+ }
145
+
146
+ // Collect diagnostics from the same builder instance that just built. diagnostics() returns a
147
+ // Files map (e.g. { 'package-manifest.json': FileBlob }); serialize it like build outputs so the
148
+ // parent can validate/write it. Traced here in the worker (the span rides back with the rest), and
149
+ // failures must not propagate — diagnostics are best-effort and never fail (or mask) a build.
150
+ async function collectDiagnostics(builder, buildOptions) {
151
+ try {
152
+ const diagnostics = await buildOptions.span
153
+ .child('vc.builder.diagnostics')
154
+ .trace(
155
+ async () => (await builder.diagnostics?.(buildOptions)) || undefined
156
+ );
157
+ if (diagnostics) serializeFiles(diagnostics);
158
+ return diagnostics;
159
+ } catch (err) {
160
+ // Surface to the worker's stderr (piped/inherited to the parent) but don't fail the build.
161
+ // biome-ignore lint/suspicious/noConsole: intentional console usage
162
+ console.error(`[vc] collecting diagnostics failed: ${err}`);
163
+ return undefined;
164
+ }
165
+ }
166
+
167
+ async function processMessage(message) {
168
+ const { requirePath, buildOptions, expectsPreDeploy } = message;
169
+ const builder = require(requirePath);
170
+
171
+ // `files` arrive as plain objects — turn them back into FileFsRef instances the builder expects.
172
+ for (const name of Object.keys(buildOptions.files)) {
173
+ buildOptions.files[name] = rehydrateFile(buildOptions.files[name]);
174
+ }
175
+
176
+ // Give the builder a span backed by our collecting reporter so the child spans it records are
177
+ // shipped back to the parent. The parent dropped the real Span (a class instance can't cross
178
+ // IPC), so we reconstruct one here; it has no parent id — the parent reparents this root under
179
+ // its own `vc.builder` span via Span.reportChildEvents when the events are reported.
180
+ buildOptions.span = new Span({
181
+ name: 'vc.builder.worker',
182
+ reporter: traceReporter,
183
+ });
184
+
185
+ // Capture any pre-deploy callback the builder registers during build(); the parent triggers
186
+ // it later via a `runPreDeploy` message. Only wired when the parent said a pre-deploy command
187
+ // is configured for this build.
188
+ if (expectsPreDeploy) {
189
+ buildOptions.registerPreDeploy = callback => {
190
+ preDeployCallback = callback;
191
+ };
192
+ }
193
+
194
+ // Build in a try/finally so diagnostics are collected on both outcomes, mirroring `doBuild`'s
195
+ // handling on the in-process path: a build that threw is exactly when its diagnostics matter
196
+ // most.
197
+ let result;
198
+ let diagnostics;
199
+ let buildError;
200
+ try {
201
+ result = await builder.build(buildOptions);
202
+ } catch (err) {
203
+ buildError = err;
204
+ throw err;
205
+ } finally {
206
+ diagnostics = await collectDiagnostics(builder, buildOptions);
207
+ // A failed build has no result message to carry the diagnostics, so stash them on the error
208
+ // for `onMessage` to ship. Symbol-keyed, so `serializeError` (which copies own property
209
+ // *names*) can't fold them into the error the parent writes into builds.json.
210
+ if (buildError && typeof buildError === 'object') {
211
+ Object.defineProperty(buildError, DIAGNOSTICS, { value: diagnostics });
212
+ }
213
+ // Stop the worker root span so it (and its recorded children) are collected before the events
214
+ // are drained and shipped for the parent to report under its `vc.builder` span.
215
+ buildOptions.span.stop();
216
+ }
217
+
218
+ // Locate the concrete V2/V3 result and its version WITHOUT unwrapping the wire payload:
219
+ // the parent (and writeBuildResult) still expect a BuildResultVX wrapper for
220
+ // `builder.version === -1` builders, so we serialize the inner outputs in place and send
221
+ // the original `result` back untouched in shape.
222
+ let effectiveVersion = builder.version;
223
+ let concrete = result;
224
+ if (builder.version === -1) {
225
+ effectiveVersion = result.resultVersion;
226
+ concrete = result.result;
227
+ }
228
+
229
+ // The IPC channel uses `serialization: 'advanced'` (V8 structured clone), which preserves
230
+ // Buffers, cycles (e.g. `@vercel/next`'s `result.childProcesses`), and shared object identity
231
+ // — the same Lambda referenced by many V2 keys or many `Prerender.lambda` fields arrives as
232
+ // ONE instance, which writeBuildResult relies on for symlink dedup. So the only remaining job
233
+ // here is spilling oversized FileBlob Buffers to temp files (see serializeFiles). We still walk
234
+ // every reachable `files` map, using `seen` so a shared Lambda is spilled at most once.
235
+ const seen = new Set();
236
+ const serializeOutput = output => {
237
+ if (!output || typeof output !== 'object' || seen.has(output)) return;
238
+ seen.add(output);
239
+ if (output.type === 'Lambda' || output.type === 'EdgeFunction') {
240
+ serializeFiles(output.files);
241
+ } else if (output.type === 'Prerender') {
242
+ // Prerender wraps a `lambda` (with its own `files`) and a `fallback` file.
243
+ if (output.lambda) serializeOutput(output.lambda);
244
+ if (output.fallback) serializeFiles({ fallback: output.fallback });
245
+ }
246
+ };
247
+
248
+ // Build Output API results (`{ buildOutputPath }`) have no in-memory `output` to serialize —
249
+ // their outputs live on disk and the parent reads them from there.
250
+ if (concrete.output) {
251
+ if (effectiveVersion === 3) {
252
+ serializeOutput(concrete.output);
253
+ } else {
254
+ for (const value of Object.values(concrete.output)) {
255
+ serializeOutput(value);
256
+ }
257
+ }
258
+ }
259
+
260
+ // With a pending pre-deploy the worker stays alive to run the callback (which holds the
261
+ // builder-computed env) when the parent later sends `runPreDeploy`; the parent tears the
262
+ // worker down once done. Without one, the parent kills the worker as soon as it has the result.
263
+ // Drain the collected events here so the deferred pre-deploy step ships only what it records.
264
+ const hasPreDeploy = Boolean(preDeployCallback);
265
+ process.send({
266
+ type: 'buildResult',
267
+ result,
268
+ // The concrete result's shape (single V3 output vs. a V2 map of named outputs) can't be
269
+ // inferred reliably from the payload — a V2 map may legitimately hold a key named `type`
270
+ // — so tell the parent which one it is instead of making it guess.
271
+ outputVersion: effectiveVersion,
272
+ diagnostics,
273
+ hasPreDeploy,
274
+ // Builders share state through `meta` (e.g. runNpmInstall's dedup set). This worker had a
275
+ // structured-clone copy, so send it back for the parent to merge into the shared meta.
276
+ meta: buildOptions.meta,
277
+ traceEvents: drainTraceEvents(),
278
+ });
279
+ }
280
+
281
+ process.send({ type: 'ready' });