@vercel/build-utils 14.9.3 → 14.10.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 14.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f9d0e90: Add experimental Cloud Native Buildpacks lifecycle support with isolated source
8
+ staging, pinned lifecycle and buildpack archives, and runtime-owned image
9
+ resolution. Ruby images are selected from `.ruby-version`, `.tool-versions`, or
10
+ the `tools.ruby` entry in `mise.toml`, then an exact Gemfile declaration,
11
+ defaulting to Ruby 3.4. Unsupported version declarations fail with configuration
12
+ guidance. Nothing selects a buildpack yet.
13
+ - 8a277e4: Fix `bun install` silently discarding `bun.lock` files with `lockfileVersion: 2` (written by Bun >= 1.4). The install step now selects the Bun 1.4 binary whenever the lockfile requires it, mirroring how the pnpm version is already inferred from its lockfile version, instead of always running the container's default Bun 1.3.x install.
14
+ - 66e443e: Fix native CLI build/dev worker dispatch, preserve the system Node executable for shell commands, resolve project analytics versions outside the binary snapshot, pair dynamically installed builders with compatible build-utils versions, and lazily materialize the packaged esbuild executable for JavaScript and TypeScript configuration files.
15
+ - 08b0be2: Require maxConcurrency to be an integer from 1 to 8192.
16
+
17
+ ## 14.10.0
18
+
19
+ ### Minor Changes
20
+
21
+ - 54a6d73: Require schedule jitter to be an integer from 1 to 15 minutes in vercel.json and Build Output API config, matching the maximum SQS message delay. Duration strings are no longer accepted.
22
+ - 3d16792: Add an optional IANA `timezone` to schedules in `vercel.json` and Build Output API config. Omitted timezones use UTC. Validate configured timezones before building.
23
+
24
+ ### Patch Changes
25
+
26
+ - 2a57243: More robust Next.js framework version detection
27
+
3
28
  ## 14.9.3
4
29
 
5
30
  ### Patch Changes
@@ -21,8 +21,10 @@ __export(container_image_exports, {
21
21
  ContainerImage: () => ContainerImage
22
22
  });
23
23
  module.exports = __toCommonJS(container_image_exports);
24
+ var import_max_concurrency = require("./max-concurrency");
24
25
  class ContainerImage {
25
26
  constructor(params) {
27
+ (0, import_max_concurrency.validateMaxConcurrency)(params.maxConcurrency);
26
28
  this.type = "ContainerImage";
27
29
  this.files = params.files;
28
30
  this.handler = params.handler;
@@ -114,19 +114,24 @@ function spawnAsync(command, args, opts = {}) {
114
114
  });
115
115
  });
116
116
  }
117
+ function getShellCommand(command) {
118
+ return process.env.VERCEL_VC_NATIVE === "1" ? ` ${command}` : command;
119
+ }
117
120
  function spawnCommand(command, options = {}) {
118
121
  const opts = { ...options, prettyCommand: command };
122
+ const shellCommand = getShellCommand(command);
119
123
  if (process.platform === "win32") {
120
- return (0, import_cross_spawn.default)("cmd.exe", ["/C", command], opts);
124
+ return (0, import_cross_spawn.default)("cmd.exe", ["/C", shellCommand], opts);
121
125
  }
122
- return (0, import_cross_spawn.default)("sh", ["-c", command], opts);
126
+ return (0, import_cross_spawn.default)("sh", ["-c", shellCommand], opts);
123
127
  }
124
128
  async function execCommand(command, options = {}) {
125
129
  const opts = { ...options, prettyCommand: command };
130
+ const shellCommand = getShellCommand(command);
126
131
  if (process.platform === "win32") {
127
- await spawnAsync("cmd.exe", ["/C", command], opts);
132
+ await spawnAsync("cmd.exe", ["/C", shellCommand], opts);
128
133
  } else {
129
- await spawnAsync("sh", ["-c", command], opts);
134
+ await spawnAsync("sh", ["-c", shellCommand], opts);
130
135
  }
131
136
  return true;
132
137
  }
@@ -331,7 +336,7 @@ async function scanParentDirs(destPath, readPackageJson = false, base = "/") {
331
336
  if (bunLock && yarnLock) {
332
337
  cliType = "bun";
333
338
  lockfilePath = bunLockPath;
334
- lockfileVersion = bunLockTextPath ? 1 : 0;
339
+ lockfileVersion = bunLockTextPath ? resolveBunTextLockfileVersion(bunLock.toString("utf8")) : 0;
335
340
  } else if (yarnLock) {
336
341
  cliType = "yarn";
337
342
  lockfilePath = yarnLockPath;
@@ -347,7 +352,7 @@ async function scanParentDirs(destPath, readPackageJson = false, base = "/") {
347
352
  } else if (bunLock) {
348
353
  cliType = "bun";
349
354
  lockfilePath = bunLockPath;
350
- lockfileVersion = bunLockTextPath ? 1 : 0;
355
+ lockfileVersion = bunLockTextPath ? resolveBunTextLockfileVersion(bunLock.toString("utf8")) : 0;
351
356
  } else if (vltLock) {
352
357
  cliType = "vlt";
353
358
  lockfilePath = vltLockPath;
@@ -380,6 +385,25 @@ function parseYarnLockVersion(yarnLock) {
380
385
  return void 0;
381
386
  }
382
387
  }
388
+ function resolveBunTextLockfileVersion(bunLockText) {
389
+ const parsed = parseBunLockVersion(bunLockText);
390
+ return parsed !== void 0 && parsed >= 2 ? parsed : 1;
391
+ }
392
+ function parseBunLockVersion(bunLockText) {
393
+ try {
394
+ const parsed = import_json5.default.parse(bunLockText);
395
+ const version = Number(parsed?.lockfileVersion);
396
+ return Number.isFinite(version) ? version : void 0;
397
+ } catch {
398
+ return void 0;
399
+ }
400
+ }
401
+ function lockfileRequiresBun14(lockfileVersion) {
402
+ return typeof lockfileVersion === "number" && lockfileVersion >= 2;
403
+ }
404
+ function bunBinaryDir(version) {
405
+ return `/bun${version.major}${version.minor === void 0 ? "" : `.${version.minor}`}`;
406
+ }
383
407
  async function checkTurboSupportsCorepack(turboVersionRange, rootDir) {
384
408
  if (turboVersionSpecifierSupportsCorepack(turboVersionRange)) {
385
409
  return true;
@@ -663,6 +687,10 @@ async function runNpmInstall(destPath, args = [], spawnOpts, meta, projectCreate
663
687
  runNpmInstallSema.release();
664
688
  }
665
689
  }
690
+ function resolveEffectiveBunVersion(nodeVersion, lockfileVersion) {
691
+ const requiresBun14 = lockfileRequiresBun14(lockfileVersion) && (nodeVersion.minor === void 0 || nodeVersion.minor < 4);
692
+ return requiresBun14 ? (0, import_node_version.getSupportedBunVersion)("1.4.x") : nodeVersion;
693
+ }
666
694
  function getEnvForPackageManager({
667
695
  cliType,
668
696
  lockfileVersion,
@@ -705,7 +733,7 @@ function getEnvForPackageManager({
705
733
  const newEnv = {
706
734
  ...env
707
735
  };
708
- const bunRuntimePath = nodeVersion && (0, import_node_version.isBunVersion)(nodeVersion) ? `/bun${nodeVersion.major}${nodeVersion.minor === void 0 ? "" : `.${nodeVersion.minor}`}` : void 0;
736
+ const bunRuntimePath = nodeVersion && (0, import_node_version.isBunVersion)(nodeVersion) ? bunBinaryDir(resolveEffectiveBunVersion(nodeVersion, lockfileVersion)) : void 0;
709
737
  const alreadyInPath = (newPath2) => {
710
738
  const oldPath = env.PATH ?? "";
711
739
  return oldPath.split(import_path.default.delimiter).includes(newPath2);
@@ -963,11 +991,14 @@ function getPathOverrideForPackageManager({
963
991
  });
964
992
  }
965
993
  if (cliType === "bun" && detectedPackageManger && nodeVersion && (0, import_node_version.isBunVersion)(nodeVersion)) {
966
- const minor = nodeVersion.minor;
994
+ const effectiveBunVersion = resolveEffectiveBunVersion(
995
+ nodeVersion,
996
+ lockfileVersion
997
+ );
967
998
  return {
968
999
  ...detectedPackageManger,
969
- path: `/bun${nodeVersion.major}${minor === void 0 ? "" : `.${minor}`}`,
970
- detectedPackageManager: `bun@${nodeVersion.range}`
1000
+ path: bunBinaryDir(effectiveBunVersion),
1001
+ detectedPackageManager: `bun@${effectiveBunVersion.range}`
971
1002
  };
972
1003
  }
973
1004
  return selected ?? NO_OVERRIDE;
@@ -1113,12 +1144,20 @@ function detectPackageManager(cliType, lockfileVersion, projectCreatedAt, nodeVe
1113
1144
  return void 0;
1114
1145
  }
1115
1146
  }
1116
- case "bun":
1147
+ case "bun": {
1148
+ if (lockfileRequiresBun14(lockfileVersion)) {
1149
+ return {
1150
+ path: "/bun1.4",
1151
+ detectedLockfile: "bun.lock",
1152
+ detectedPackageManager: "bun@1.4.x"
1153
+ };
1154
+ }
1117
1155
  return {
1118
1156
  path: "/bun1",
1119
1157
  detectedLockfile: lockfileVersion === 0 ? "bun.lockb" : "bun.lock",
1120
1158
  detectedPackageManager: "bun@1.x"
1121
1159
  };
1160
+ }
1122
1161
  case "yarn":
1123
1162
  return {
1124
1163
  path: void 0,
@@ -31,21 +31,28 @@ __export(get_installed_package_version_exports, {
31
31
  getInstalledPackageVersion: () => getInstalledPackageVersion
32
32
  });
33
33
  module.exports = __toCommonJS(get_installed_package_version_exports);
34
+ var import_promises = require("node:fs/promises");
35
+ var import_node_module = require("node:module");
36
+ var import_node_path = require("node:path");
34
37
  var import_debug = __toESM(require("./debug"));
35
38
  async function getInstalledPackageVersion(packageName, path) {
36
- try {
37
- const resolved = require.resolve(`${packageName}/package.json`, {
38
- paths: path ? Array.isArray(path) ? path : [path] : [process.cwd()]
39
- });
40
- const version = require(resolved).version;
41
- return version;
42
- } catch (err) {
43
- (0, import_debug.default)(
44
- `Could not resolve package "${packageName}". Package is not installed.`,
45
- err
46
- );
47
- return void 0;
39
+ const paths = path ? Array.isArray(path) ? path : [path] : [process.cwd()];
40
+ for (const searchPath of paths) {
41
+ try {
42
+ const projectRequire = (0, import_node_module.createRequire)(
43
+ (0, import_node_path.join)((0, import_node_path.resolve)(searchPath), "package.json")
44
+ );
45
+ const resolved = projectRequire.resolve(`${packageName}/package.json`);
46
+ const { version } = JSON.parse(await (0, import_promises.readFile)(resolved, "utf8"));
47
+ return version;
48
+ } catch (err) {
49
+ (0, import_debug.default)(
50
+ `Could not resolve package "${packageName}". Package is not installed.`,
51
+ err
52
+ );
53
+ }
48
54
  }
55
+ return void 0;
49
56
  }
50
57
  // Annotate the CommonJS export names for ESM import in node:
51
58
  0 && (module.exports = {