@vercel/build-utils 14.0.5 → 14.1.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,17 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 14.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - b4f09c1: Support selecting Bun 1.4.x as an explicit runtime and build-time package manager, including local Bun servers.
8
+
9
+ ## 14.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 852e1a0: Move middleware matcher utils from node builder to general build utils.
14
+
3
15
  ## 14.0.5
4
16
 
5
17
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  import type { BuildResultV2Typical, BuildResultV3, BuilderFunctions, Config } from '../types';
2
- export declare const SUPPORTED_AL2023_RUNTIMES: readonly ["nodejs20.x", "nodejs22.x", "nodejs24.x", "provided.al2023", "python3.12", "python3.13", "python3.14", "ruby3.3", "bun1.x", "executable"];
2
+ export declare const SUPPORTED_AL2023_RUNTIMES: readonly ["nodejs20.x", "nodejs22.x", "nodejs24.x", "provided.al2023", "python3.12", "python3.13", "python3.14", "ruby3.3", "bun1.4.x", "bun1.x", "executable"];
3
3
  type BuildConfigWithVercelConfig = Config & {
4
4
  vercelConfig?: {
5
5
  functions?: BuilderFunctions;
@@ -43,6 +43,7 @@ const SUPPORTED_AL2023_RUNTIMES = [
43
43
  "python3.13",
44
44
  "python3.14",
45
45
  "ruby3.3",
46
+ "bun1.4.x",
46
47
  "bun1.x",
47
48
  "executable"
48
49
  ];
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns the Bun binary, installing it with the official installer when it is
3
+ * not already available in PATH or Bun's default installation directory.
4
+ */
5
+ export declare function getOrCreateBunBinary(): Promise<string>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var bun_helpers_exports = {};
30
+ __export(bun_helpers_exports, {
31
+ getOrCreateBunBinary: () => getOrCreateBunBinary
32
+ });
33
+ module.exports = __toCommonJS(bun_helpers_exports);
34
+ var import_os = require("os");
35
+ var import_path = require("path");
36
+ var import_child_process = require("child_process");
37
+ var import_debug = __toESM(require("../debug"));
38
+ function spawnAsync(command, args, options) {
39
+ return new Promise((resolve, reject) => {
40
+ const child = (0, import_child_process.spawn)(command, args, options);
41
+ child.once("error", reject);
42
+ child.once("close", resolve);
43
+ });
44
+ }
45
+ async function getOrCreateBunBinary() {
46
+ const bunCommand = process.platform === "win32" ? "bun.exe" : "bun";
47
+ const installPath = (0, import_path.join)((0, import_os.homedir)(), ".bun", "bin", bunCommand);
48
+ try {
49
+ if (await spawnAsync(bunCommand, ["--version"], { stdio: "ignore" }) === 0) {
50
+ (0, import_debug.default)("Bun already installed and available in PATH");
51
+ return bunCommand;
52
+ }
53
+ } catch {
54
+ (0, import_debug.default)("Bun not found in PATH");
55
+ }
56
+ try {
57
+ if (await spawnAsync(installPath, ["--version"], { stdio: "ignore" }) === 0) {
58
+ (0, import_debug.default)("Bun already installed in default location");
59
+ return installPath;
60
+ }
61
+ } catch {
62
+ (0, import_debug.default)("Bun not found in default location");
63
+ }
64
+ console.log("Installing Bun...");
65
+ try {
66
+ const exitCode = process.platform === "win32" ? await spawnAsync(
67
+ "powershell",
68
+ ["-c", "irm bun.sh/install.ps1 | iex"],
69
+ { stdio: "inherit" }
70
+ ) : await spawnAsync(
71
+ "bash",
72
+ ["-c", "curl -fsSL https://bun.sh/install | bash"],
73
+ { stdio: "inherit" }
74
+ );
75
+ if (exitCode !== 0) {
76
+ throw new Error(`Installation script exited with code ${exitCode}`);
77
+ }
78
+ } catch (error) {
79
+ throw new Error(`Failed to install Bun: ${error}`);
80
+ }
81
+ try {
82
+ if (await spawnAsync(installPath, ["--version"], { stdio: "ignore" }) === 0) {
83
+ (0, import_debug.default)("Bun was installed successfully");
84
+ return installPath;
85
+ }
86
+ } catch {
87
+ }
88
+ throw new Error(
89
+ "Bun installation failed. Please install manually and try again."
90
+ );
91
+ }
92
+ // Annotate the CommonJS export names for ESM import in node:
93
+ 0 && (module.exports = {
94
+ getOrCreateBunBinary
95
+ });
@@ -99,6 +99,12 @@ const NODE_VERSIONS = [
99
99
  })
100
100
  ];
101
101
  const BUN_VERSIONS = [
102
+ new import_types.BunVersion({
103
+ major: 1,
104
+ minor: 4,
105
+ range: "1.4.x",
106
+ runtime: "bun1.4.x"
107
+ }),
102
108
  new import_types.BunVersion({
103
109
  major: 1,
104
110
  range: "1.x",
@@ -191,11 +197,15 @@ async function getSupportedNodeVersion(engineRange, isAuto = false, availableVer
191
197
  function getSupportedBunVersion(engineRange) {
192
198
  if ((0, import_semver.validRange)(engineRange)) {
193
199
  const selected = BUN_VERSIONS.find((version) => {
194
- return (0, import_semver.intersects)(version.range, engineRange);
200
+ if (!(0, import_semver.intersects)(version.range, engineRange)) {
201
+ return false;
202
+ }
203
+ return version.minor === void 0 ? true : !(0, import_semver.intersects)(`<${version.major}.${version.minor}.0`, engineRange);
195
204
  });
196
205
  if (selected) {
197
206
  return new import_types.BunVersion({
198
207
  major: selected.major,
208
+ minor: selected.minor,
199
209
  range: selected.range,
200
210
  runtime: selected.runtime
201
211
  });
@@ -135,10 +135,11 @@ export declare function runNpmInstall(destPath: string, args?: string[], spawnOp
135
135
  * Prepares the input environment based on the used package manager and lockfile
136
136
  * versions.
137
137
  */
138
- export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, env, packageJsonEngines, turboSupportsCorepackHome, projectCreatedAt, }: {
138
+ export declare function getEnvForPackageManager({ cliType, lockfileVersion, packageJsonPackageManager, nodeVersion, env, packageJsonEngines, turboSupportsCorepackHome, projectCreatedAt, }: {
139
139
  cliType: CliType;
140
140
  lockfileVersion: number | undefined;
141
141
  packageJsonPackageManager?: string | undefined;
142
+ nodeVersion?: NodeVersion | BunVersion;
142
143
  env: {
143
144
  [x: string]: string | undefined;
144
145
  };
@@ -153,11 +154,12 @@ export declare const PNPM_10_PREFERRED_AT: Date;
153
154
  * Helper to get the binary paths that link to the used package manager.
154
155
  * Note: Make sure it doesn't contain any `console.log` calls.
155
156
  */
156
- export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, packageJsonEngines, projectCreatedAt, }: {
157
+ export declare function getPathOverrideForPackageManager({ cliType, lockfileVersion, corepackPackageManager, corepackEnabled, nodeVersion, packageJsonEngines, projectCreatedAt, }: {
157
158
  cliType: CliType;
158
159
  lockfileVersion: number | undefined;
159
160
  corepackPackageManager: string | undefined;
160
161
  corepackEnabled?: boolean;
162
+ nodeVersion?: NodeVersion | BunVersion;
161
163
  packageJsonEngines?: PackageJson.Engines;
162
164
  projectCreatedAt?: number;
163
165
  }): {
@@ -698,6 +698,7 @@ function getEnvForPackageManager({
698
698
  cliType,
699
699
  lockfileVersion,
700
700
  packageJsonPackageManager,
701
+ nodeVersion,
701
702
  env,
702
703
  packageJsonEngines,
703
704
  turboSupportsCorepackHome,
@@ -717,6 +718,7 @@ function getEnvForPackageManager({
717
718
  lockfileVersion,
718
719
  corepackPackageManager: packageJsonPackageManager,
719
720
  corepackEnabled,
721
+ nodeVersion,
720
722
  packageJsonEngines,
721
723
  projectCreatedAt
722
724
  });
@@ -732,14 +734,23 @@ function getEnvForPackageManager({
732
734
  const newEnv = {
733
735
  ...env
734
736
  };
737
+ const bunRuntimePath = nodeVersion && (0, import_node_version.isBunVersion)(nodeVersion) ? `/bun${nodeVersion.major}${nodeVersion.minor === void 0 ? "" : `.${nodeVersion.minor}`}` : void 0;
735
738
  const alreadyInPath = (newPath2) => {
736
739
  const oldPath = env.PATH ?? "";
737
740
  return oldPath.split(import_path.default.delimiter).includes(newPath2);
738
741
  };
739
- if (newPath && !alreadyInPath(newPath)) {
742
+ const hasSelectedBunPath = cliType === "bun" && nodeVersion === void 0 && (env.PATH ?? "").split(import_path.default.delimiter).some((segment) => /^\/bun\d+(?:\.\d+)?$/.test(segment));
743
+ const pathsToPrepend = Array.from(
744
+ new Set(
745
+ [newPath, bunRuntimePath].filter((value) => !!value)
746
+ )
747
+ ).filter(
748
+ (value) => !alreadyInPath(value) && !(hasSelectedBunPath && value === newPath)
749
+ );
750
+ if (pathsToPrepend.length > 0) {
740
751
  const oldPath = env.PATH + "";
741
- newEnv.PATH = `${newPath}${import_path.default.delimiter}${oldPath}`;
742
- if (detectedLockfile && detectedPackageManager) {
752
+ newEnv.PATH = `${pathsToPrepend.join(import_path.default.delimiter)}${oldPath ? import_path.default.delimiter : ""}${oldPath}`;
753
+ if (newPath && pathsToPrepend.includes(newPath) && detectedLockfile && detectedPackageManager) {
743
754
  const detectedV9PnpmLockfile = detectedLockfile === "pnpm-lock.yaml" && lockfileVersion === 9;
744
755
  const pnpm10UsingPackageJsonPackageManager = detectedPackageManager === "pnpm@10.x" && packageJsonPackageManager;
745
756
  if (pnpm10UsingPackageJsonPackageManager) {
@@ -835,6 +846,7 @@ function getPathOverrideForPackageManager({
835
846
  lockfileVersion,
836
847
  corepackPackageManager,
837
848
  corepackEnabled = true,
849
+ nodeVersion,
838
850
  packageJsonEngines,
839
851
  projectCreatedAt
840
852
  }) {
@@ -862,6 +874,14 @@ function getPathOverrideForPackageManager({
862
874
  );
863
875
  }
864
876
  }
877
+ if (cliType === "bun" && detectedPackageManger && nodeVersion && (0, import_node_version.isBunVersion)(nodeVersion)) {
878
+ const minor = nodeVersion.minor;
879
+ return {
880
+ ...detectedPackageManger,
881
+ path: `/bun${nodeVersion.major}${minor === void 0 ? "" : `.${minor}`}`,
882
+ detectedPackageManager: `bun@${nodeVersion.range}`
883
+ };
884
+ }
865
885
  return detectedPackageManger ?? NO_OVERRIDE;
866
886
  }
867
887
  function checkEnginesPnpmAgainstDetected(enginesPnpm, detectedPackageManger) {
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ import rename from './fs/rename';
11
11
  import { spawnAsync, execCommand, spawnCommand, walkParentDirs, getScriptName, installDependencies, runPackageJsonScript, runNpmInstall, runBundleInstall, runPipInstall, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, detectPackageManager, getSpawnOptions, getNodeBinPath, getNodeBinPaths, scanParentDirs, findPackageJson, traverseUpDirectories, PipInstallResult, NpmInstallOutput, type CliType } from './fs/run-user-scripts';
12
12
  import { getLatestNodeVersion, getDiscontinuedNodeVersions, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion } from './fs/node-version';
13
13
  import streamToBuffer, { streamToBufferChunks } from './fs/stream-to-buffer';
14
+ import { getOrCreateBunBinary } from './fs/bun-helpers';
14
15
  import debug from './debug';
15
16
  import getIgnoreFilter from './get-ignore-filter';
16
17
  import { getPlatformEnv } from './get-platform-env';
@@ -20,7 +21,7 @@ import { cloneEnv } from './clone-env';
20
21
  import { hardLinkDir } from './hard-link-dir';
21
22
  import { validateNpmrc } from './validate-npmrc';
22
23
  export type { NodejsLambdaOptions, PrerenderClassification };
23
- export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, downloadFile, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, getNodeBinPaths, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion, detectPackageManager, runNpmInstall, NpmInstallOutput, runBundleInstall, runPipInstall, PipInstallResult, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, getPrefixedEnvVars, getServiceUrlEnvVars, getExperimentalServiceUrlEnvVars, streamToBuffer, streamToBufferChunks, debug, isSymbolicLink, isDirectory, isExternalSymlink, isExternalSymlinkTarget, getSymlinkTarget, getLambdaOptionsFromFunction, sanitizeConsumerName, scanParentDirs, findPackageJson, getIgnoreFilter, cloneEnv, hardLinkDir, traverseUpDirectories, validateNpmrc, type CliType, };
24
+ export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, downloadFile, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, getNodeBinPaths, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion, getOrCreateBunBinary, detectPackageManager, runNpmInstall, NpmInstallOutput, runBundleInstall, runPipInstall, PipInstallResult, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, getPrefixedEnvVars, getServiceUrlEnvVars, getExperimentalServiceUrlEnvVars, streamToBuffer, streamToBufferChunks, debug, isSymbolicLink, isDirectory, isExternalSymlink, isExternalSymlinkTarget, getSymlinkTarget, getLambdaOptionsFromFunction, sanitizeConsumerName, scanParentDirs, findPackageJson, getIgnoreFilter, cloneEnv, hardLinkDir, traverseUpDirectories, validateNpmrc, type CliType, };
24
25
  export { EdgeFunction } from './edge-function';
25
26
  export { ContainerImage } from './container-image';
26
27
  export type { ContainerImageConfig } from './container-image';
@@ -42,6 +43,7 @@ export { getInstalledPackageVersion } from './get-installed-package-version';
42
43
  export { isPackageInstalled } from './is-package-installed';
43
44
  export { defaultCachePathGlob } from './default-cache-path-glob';
44
45
  export { generateNodeBuilderFunctions } from './generate-node-builder-functions';
46
+ export { getRegExpFromMatchers, resolveMiddlewareMatcher, } from './middleware-matcher';
45
47
  export { BACKEND_FRAMEWORKS, BACKEND_BUILDERS, UNIFIED_BACKEND_BUILDER, BackendFramework, isBackendFramework, isNodeBackendFramework, isBackendBuilder, isExperimentalBackendsEnabled, isExperimentalBackendsWithoutIntrospectionEnabled, shouldUseExperimentalBackends, PYTHON_FRAMEWORKS, PythonFramework, isPythonFramework, } from './framework-helpers';
46
48
  export * from './python';
47
49
  export * from './node-entrypoint';