@vercel/python 6.41.0 → 6.43.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 (2) hide show
  1. package/dist/index.js +541 -344
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2647,6 +2647,94 @@ ${stderr}${stdout}`;
2647
2647
  }
2648
2648
  });
2649
2649
 
2650
+ // ../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js
2651
+ var require_lib = __commonJS({
2652
+ "../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
2653
+ var isexe = require_isexe();
2654
+ var { join: join13, delimiter: delimiter2, sep: sep2, posix } = require("path");
2655
+ var isWindows = process.platform === "win32";
2656
+ var rSlash = new RegExp(`[${posix.sep}${sep2 === posix.sep ? "" : sep2}]`.replace(/(\\)/g, "\\$1"));
2657
+ var rRel = new RegExp(`^\\.${rSlash.source}`);
2658
+ var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
2659
+ var getPathInfo = (cmd, {
2660
+ path: optPath = process.env.PATH,
2661
+ pathExt: optPathExt = process.env.PATHEXT,
2662
+ delimiter: optDelimiter = delimiter2
2663
+ }) => {
2664
+ const pathEnv = cmd.match(rSlash) ? [""] : [
2665
+ // windows always checks the cwd first
2666
+ ...isWindows ? [process.cwd()] : [],
2667
+ ...(optPath || /* istanbul ignore next: very unusual */
2668
+ "").split(optDelimiter)
2669
+ ];
2670
+ if (isWindows) {
2671
+ const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter);
2672
+ const pathExt = pathExtExe.split(optDelimiter);
2673
+ if (cmd.includes(".") && pathExt[0] !== "") {
2674
+ pathExt.unshift("");
2675
+ }
2676
+ return { pathEnv, pathExt, pathExtExe };
2677
+ }
2678
+ return { pathEnv, pathExt: [""] };
2679
+ };
2680
+ var getPathPart = (raw, cmd) => {
2681
+ const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
2682
+ const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
2683
+ return prefix + join13(pathPart, cmd);
2684
+ };
2685
+ var which2 = async (cmd, opt = {}) => {
2686
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
2687
+ const found = [];
2688
+ for (const envPart of pathEnv) {
2689
+ const p = getPathPart(envPart, cmd);
2690
+ for (const ext of pathExt) {
2691
+ const withExt = p + ext;
2692
+ const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true });
2693
+ if (is) {
2694
+ if (!opt.all) {
2695
+ return withExt;
2696
+ }
2697
+ found.push(withExt);
2698
+ }
2699
+ }
2700
+ }
2701
+ if (opt.all && found.length) {
2702
+ return found;
2703
+ }
2704
+ if (opt.nothrow) {
2705
+ return null;
2706
+ }
2707
+ throw getNotFoundError(cmd);
2708
+ };
2709
+ var whichSync = (cmd, opt = {}) => {
2710
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
2711
+ const found = [];
2712
+ for (const pathEnvPart of pathEnv) {
2713
+ const p = getPathPart(pathEnvPart, cmd);
2714
+ for (const ext of pathExt) {
2715
+ const withExt = p + ext;
2716
+ const is = isexe.sync(withExt, { pathExt: pathExtExe, ignoreErrors: true });
2717
+ if (is) {
2718
+ if (!opt.all) {
2719
+ return withExt;
2720
+ }
2721
+ found.push(withExt);
2722
+ }
2723
+ }
2724
+ }
2725
+ if (opt.all && found.length) {
2726
+ return found;
2727
+ }
2728
+ if (opt.nothrow) {
2729
+ return null;
2730
+ }
2731
+ throw getNotFoundError(cmd);
2732
+ };
2733
+ module2.exports = which2;
2734
+ which2.sync = whichSync;
2735
+ }
2736
+ });
2737
+
2650
2738
  // ../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/process.js
2651
2739
  var require_process = __commonJS({
2652
2740
  "../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/process.js"(exports, module2) {
@@ -2780,14 +2868,14 @@ var require_detect_libc = __commonJS({
2780
2868
  }
2781
2869
  return commandOut;
2782
2870
  };
2783
- var GLIBC2 = "glibc";
2871
+ var GLIBC = "glibc";
2784
2872
  var RE_GLIBC_VERSION = /LIBC[a-z0-9 \-).]*?(\d+\.\d+)/i;
2785
2873
  var MUSL2 = "musl";
2786
2874
  var isFileMusl = (f) => f.includes("libc.musl-") || f.includes("ld-musl-");
2787
2875
  var familyFromReport = () => {
2788
2876
  const report = getReport();
2789
2877
  if (report.header && report.header.glibcVersionRuntime) {
2790
- return GLIBC2;
2878
+ return GLIBC;
2791
2879
  }
2792
2880
  if (Array.isArray(report.sharedObjects)) {
2793
2881
  if (report.sharedObjects.some(isFileMusl)) {
@@ -2798,8 +2886,8 @@ var require_detect_libc = __commonJS({
2798
2886
  };
2799
2887
  var familyFromCommand = (out) => {
2800
2888
  const [getconf, ldd1] = out.split(/[\r\n]+/);
2801
- if (getconf && getconf.includes(GLIBC2)) {
2802
- return GLIBC2;
2889
+ if (getconf && getconf.includes(GLIBC)) {
2890
+ return GLIBC;
2803
2891
  }
2804
2892
  if (ldd1 && ldd1.includes(MUSL2)) {
2805
2893
  return MUSL2;
@@ -2811,7 +2899,7 @@ var require_detect_libc = __commonJS({
2811
2899
  if (path.includes("/ld-musl-")) {
2812
2900
  return MUSL2;
2813
2901
  } else if (path.includes("/ld-linux-")) {
2814
- return GLIBC2;
2902
+ return GLIBC;
2815
2903
  }
2816
2904
  }
2817
2905
  return null;
@@ -2822,7 +2910,7 @@ var require_detect_libc = __commonJS({
2822
2910
  return MUSL2;
2823
2911
  }
2824
2912
  if (content.includes("GNU C Library")) {
2825
- return GLIBC2;
2913
+ return GLIBC;
2826
2914
  }
2827
2915
  return null;
2828
2916
  };
@@ -2910,8 +2998,8 @@ var require_detect_libc = __commonJS({
2910
2998
  }
2911
2999
  return family2;
2912
3000
  };
2913
- var isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC2;
2914
- var isNonGlibcLinuxSync = () => isLinux() && familySync2() !== GLIBC2;
3001
+ var isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC;
3002
+ var isNonGlibcLinuxSync = () => isLinux() && familySync2() !== GLIBC;
2915
3003
  var versionFromFilesystem = async () => {
2916
3004
  if (cachedVersionFilesystem !== void 0) {
2917
3005
  return cachedVersionFilesystem;
@@ -2952,7 +3040,7 @@ var require_detect_libc = __commonJS({
2952
3040
  var versionSuffix = (s) => s.trim().split(/\s+/)[1];
2953
3041
  var versionFromCommand = (out) => {
2954
3042
  const [getconf, ldd1, ldd2] = out.split(/[\r\n]+/);
2955
- if (getconf && getconf.includes(GLIBC2)) {
3043
+ if (getconf && getconf.includes(GLIBC)) {
2956
3044
  return versionSuffix(getconf);
2957
3045
  }
2958
3046
  if (ldd1 && ldd2 && ldd1.includes(MUSL2)) {
@@ -2989,7 +3077,7 @@ var require_detect_libc = __commonJS({
2989
3077
  return version3;
2990
3078
  };
2991
3079
  module2.exports = {
2992
- GLIBC: GLIBC2,
3080
+ GLIBC,
2993
3081
  MUSL: MUSL2,
2994
3082
  family,
2995
3083
  familySync: familySync2,
@@ -3001,94 +3089,6 @@ var require_detect_libc = __commonJS({
3001
3089
  }
3002
3090
  });
3003
3091
 
3004
- // ../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js
3005
- var require_lib = __commonJS({
3006
- "../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
3007
- var isexe = require_isexe();
3008
- var { join: join13, delimiter: delimiter2, sep: sep2, posix } = require("path");
3009
- var isWindows = process.platform === "win32";
3010
- var rSlash = new RegExp(`[${posix.sep}${sep2 === posix.sep ? "" : sep2}]`.replace(/(\\)/g, "\\$1"));
3011
- var rRel = new RegExp(`^\\.${rSlash.source}`);
3012
- var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
3013
- var getPathInfo = (cmd, {
3014
- path: optPath = process.env.PATH,
3015
- pathExt: optPathExt = process.env.PATHEXT,
3016
- delimiter: optDelimiter = delimiter2
3017
- }) => {
3018
- const pathEnv = cmd.match(rSlash) ? [""] : [
3019
- // windows always checks the cwd first
3020
- ...isWindows ? [process.cwd()] : [],
3021
- ...(optPath || /* istanbul ignore next: very unusual */
3022
- "").split(optDelimiter)
3023
- ];
3024
- if (isWindows) {
3025
- const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter);
3026
- const pathExt = pathExtExe.split(optDelimiter);
3027
- if (cmd.includes(".") && pathExt[0] !== "") {
3028
- pathExt.unshift("");
3029
- }
3030
- return { pathEnv, pathExt, pathExtExe };
3031
- }
3032
- return { pathEnv, pathExt: [""] };
3033
- };
3034
- var getPathPart = (raw, cmd) => {
3035
- const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
3036
- const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
3037
- return prefix + join13(pathPart, cmd);
3038
- };
3039
- var which2 = async (cmd, opt = {}) => {
3040
- const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
3041
- const found = [];
3042
- for (const envPart of pathEnv) {
3043
- const p = getPathPart(envPart, cmd);
3044
- for (const ext of pathExt) {
3045
- const withExt = p + ext;
3046
- const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true });
3047
- if (is) {
3048
- if (!opt.all) {
3049
- return withExt;
3050
- }
3051
- found.push(withExt);
3052
- }
3053
- }
3054
- }
3055
- if (opt.all && found.length) {
3056
- return found;
3057
- }
3058
- if (opt.nothrow) {
3059
- return null;
3060
- }
3061
- throw getNotFoundError(cmd);
3062
- };
3063
- var whichSync = (cmd, opt = {}) => {
3064
- const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
3065
- const found = [];
3066
- for (const pathEnvPart of pathEnv) {
3067
- const p = getPathPart(pathEnvPart, cmd);
3068
- for (const ext of pathExt) {
3069
- const withExt = p + ext;
3070
- const is = isexe.sync(withExt, { pathExt: pathExtExe, ignoreErrors: true });
3071
- if (is) {
3072
- if (!opt.all) {
3073
- return withExt;
3074
- }
3075
- found.push(withExt);
3076
- }
3077
- }
3078
- }
3079
- if (opt.all && found.length) {
3080
- return found;
3081
- }
3082
- if (opt.nothrow) {
3083
- return null;
3084
- }
3085
- throw getNotFoundError(cmd);
3086
- };
3087
- module2.exports = which2;
3088
- which2.sync = whichSync;
3089
- }
3090
- });
3091
-
3092
3092
  // ../../node_modules/.pnpm/get-port@5.1.1/node_modules/get-port/index.js
3093
3093
  var require_get_port = __commonJS({
3094
3094
  "../../node_modules/.pnpm/get-port@5.1.1/node_modules/get-port/index.js"(exports, module2) {
@@ -3213,6 +3213,7 @@ var src_exports = {};
3213
3213
  __export(src_exports, {
3214
3214
  build: () => build,
3215
3215
  defaultShouldServe: () => defaultShouldServe,
3216
+ detectEntrypoint: () => detectEntrypoint,
3216
3217
  diagnostics: () => diagnostics,
3217
3218
  downloadFilesInWorkPath: () => downloadFilesInWorkPath,
3218
3219
  installRequirement: () => installRequirement,
@@ -3230,31 +3231,32 @@ var import_fs13 = __toESM(require("fs"));
3230
3231
  var import_path13 = require("path");
3231
3232
 
3232
3233
  // src/package-versions.ts
3233
- var VERCEL_RUNTIME_VERSION = "0.13.2";
3234
- var VERCEL_WORKERS_VERSION = "0.0.22";
3234
+ var VERCEL_RUNTIME_VERSION = "0.14.0";
3235
+ var VERCEL_WORKERS_VERSION = "0.0.24";
3235
3236
 
3236
3237
  // src/index.ts
3237
- var import_build_utils16 = require("@vercel/build-utils");
3238
+ var import_build_utils17 = require("@vercel/build-utils");
3238
3239
 
3239
3240
  // src/install.ts
3240
3241
  var import_execa3 = __toESM(require_execa());
3241
3242
  var import_fs4 = __toESM(require("fs"));
3242
3243
  var import_path5 = require("path");
3243
- var import_build_utils4 = require("@vercel/build-utils");
3244
+ var import_build_utils5 = require("@vercel/build-utils");
3244
3245
  var import_python_analysis2 = require("@vercel/python-analysis");
3245
3246
 
3246
3247
  // src/utils.ts
3247
3248
  var import_fs2 = __toESM(require("fs"));
3248
- var import_os2 = __toESM(require("os"));
3249
3249
  var import_path3 = require("path");
3250
3250
  var import_build_utils2 = require("@vercel/build-utils");
3251
- var detectLibc = __toESM(require_detect_libc());
3252
3251
  var import_execa2 = __toESM(require_execa());
3253
3252
 
3254
3253
  // src/uv.ts
3254
+ var import_crypto = require("crypto");
3255
3255
  var import_child_process = require("child_process");
3256
3256
  var import_path = require("path");
3257
3257
  var import_path2 = require("path");
3258
+ var import_stream = require("stream");
3259
+ var import_promises = require("stream/promises");
3258
3260
  var import_execa = __toESM(require_execa());
3259
3261
  var import_fs = __toESM(require("fs"));
3260
3262
  var import_os = __toESM(require("os"));
@@ -3264,6 +3266,7 @@ var UV_VERSION = "0.10.11";
3264
3266
  var UV_PYTHON_PATH_PREFIX = "/uv/python/";
3265
3267
  var UV_PYTHON_DOWNLOADS_MODE = "automatic";
3266
3268
  var UV_CACHE_DIR_SUBPATH = [".vercel", "python", "cache", "uv"];
3269
+ var UV_BINARY_CHECKSUM = "5a360b0de092ddf4131f5313d0411b48c4e95e8107e40c3f8f2e9fcb636b3583";
3267
3270
  var isWin = process.platform === "win32";
3268
3271
  var uvExec = isWin ? "uv.exe" : "uv";
3269
3272
  var KNOWN_UV_PATH = "/usr/local/bin/uv";
@@ -3293,9 +3296,14 @@ var UvRunner = class {
3293
3296
  listInstalledPythons() {
3294
3297
  let output;
3295
3298
  try {
3296
- output = (0, import_child_process.execSync)(
3297
- `${this.uvPath} python list --only-installed --output-format json`,
3298
- { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
3299
+ output = (0, import_child_process.execFileSync)(
3300
+ this.uvPath,
3301
+ ["python", "list", "--only-installed", "--output-format", "json"],
3302
+ {
3303
+ encoding: "utf8",
3304
+ stdio: ["pipe", "pipe", "pipe"],
3305
+ shell: isWin
3306
+ }
3299
3307
  );
3300
3308
  } catch (err) {
3301
3309
  throw new Error(
@@ -3329,7 +3337,15 @@ var UvRunner = class {
3329
3337
  );
3330
3338
  }
3331
3339
  async sync(options) {
3332
- const { venvPath, projectDir, locked, frozen, noBuild, noInstallProject } = options;
3340
+ const {
3341
+ venvPath,
3342
+ projectDir,
3343
+ locked,
3344
+ frozen,
3345
+ noBuild,
3346
+ noInstallProject,
3347
+ pythonPlatform
3348
+ } = options;
3333
3349
  const args = ["sync", "--active", "--no-dev", "--link-mode", "hardlink"];
3334
3350
  if (frozen) {
3335
3351
  args.push("--frozen");
@@ -3342,6 +3358,9 @@ var UvRunner = class {
3342
3358
  if (noInstallProject) {
3343
3359
  args.push("--no-install-project");
3344
3360
  }
3361
+ if (pythonPlatform) {
3362
+ args.push("--python-platform", pythonPlatform);
3363
+ }
3345
3364
  args.push("--no-editable");
3346
3365
  await this.runUvCmd(args, projectDir, venvPath);
3347
3366
  }
@@ -3554,6 +3573,98 @@ async function getUvBinaryForBundling(pythonPath) {
3554
3573
  const resolvedPath = await import_fs.default.promises.realpath(uvPath);
3555
3574
  return resolvedPath;
3556
3575
  }
3576
+ var UV_LINUX_TARGET = "x86_64-unknown-linux-gnu";
3577
+ async function downloadUvBinaryForTarget(cacheDir) {
3578
+ const destDir = (0, import_path.join)(cacheDir, `uv-${UV_VERSION}-${UV_LINUX_TARGET}`);
3579
+ const destBinary = (0, import_path.join)(destDir, "uv");
3580
+ try {
3581
+ await import_fs.default.promises.access(destBinary, import_fs.default.constants.X_OK);
3582
+ (0, import_build_utils.debug)(`Using cached uv binary at ${destBinary}`);
3583
+ return destBinary;
3584
+ } catch {
3585
+ }
3586
+ const tarballName = `uv-${UV_LINUX_TARGET}.tar.gz`;
3587
+ const url = `https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/${tarballName}`;
3588
+ (0, import_build_utils.debug)(`Downloading uv ${UV_VERSION} from ${url}`);
3589
+ console.log(
3590
+ `Downloading uv ${UV_VERSION} (linux x86_64) for runtime dependency installation...`
3591
+ );
3592
+ await import_fs.default.promises.mkdir(destDir, { recursive: true });
3593
+ const tarballPath = (0, import_path.join)(destDir, tarballName);
3594
+ await downloadUvTarball(url, tarballPath);
3595
+ const actualHash = await sha256File(tarballPath);
3596
+ if (actualHash !== UV_BINARY_CHECKSUM) {
3597
+ await import_fs.default.promises.unlink(tarballPath).catch(() => {
3598
+ });
3599
+ throw new import_build_utils.NowBuildError({
3600
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
3601
+ message: `checksum mismatch for ${tarballName}: expected ${UV_BINARY_CHECKSUM}, got ${actualHash}`
3602
+ });
3603
+ }
3604
+ try {
3605
+ await (0, import_execa.default)("tar", [
3606
+ "xzf",
3607
+ tarballPath,
3608
+ "--strip-components=1",
3609
+ "-C",
3610
+ destDir
3611
+ ]);
3612
+ } catch (err) {
3613
+ throw new import_build_utils.NowBuildError({
3614
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
3615
+ message: `could not extract ${tarballName}: ${err instanceof Error ? err.message : String(err)}`
3616
+ });
3617
+ }
3618
+ await import_fs.default.promises.chmod(destBinary, 493);
3619
+ await import_fs.default.promises.unlink(tarballPath).catch(() => {
3620
+ });
3621
+ (0, import_build_utils.debug)(`Downloaded uv binary to ${destBinary}`);
3622
+ return destBinary;
3623
+ }
3624
+ async function downloadUvTarball(url, dest) {
3625
+ const tmpDest = `${dest}.${process.pid}.${Date.now()}.tmp`;
3626
+ const controller = new AbortController();
3627
+ const timeout = setTimeout(() => controller.abort(), 6e4);
3628
+ try {
3629
+ const response = await fetch(url, {
3630
+ redirect: "follow",
3631
+ signal: controller.signal
3632
+ });
3633
+ if (!response.ok) {
3634
+ throw new import_build_utils.NowBuildError({
3635
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
3636
+ message: `could not download ${url}: HTTP ${response.status}`
3637
+ });
3638
+ }
3639
+ if (!response.body) {
3640
+ throw new import_build_utils.NowBuildError({
3641
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
3642
+ message: `could not download ${url}: response body was empty`
3643
+ });
3644
+ }
3645
+ await (0, import_promises.pipeline)(
3646
+ import_stream.Readable.fromWeb(response.body),
3647
+ import_fs.default.createWriteStream(tmpDest)
3648
+ );
3649
+ await import_fs.default.promises.rename(tmpDest, dest);
3650
+ } catch (err) {
3651
+ await import_fs.default.promises.unlink(tmpDest).catch(() => {
3652
+ });
3653
+ if (err instanceof import_build_utils.NowBuildError) {
3654
+ throw err;
3655
+ }
3656
+ throw new import_build_utils.NowBuildError({
3657
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
3658
+ message: `could not download ${url}: ${err instanceof Error ? err.message : String(err)}`
3659
+ });
3660
+ } finally {
3661
+ clearTimeout(timeout);
3662
+ }
3663
+ }
3664
+ async function sha256File(filePath) {
3665
+ const data = await import_fs.default.promises.readFile(filePath);
3666
+ return (0, import_crypto.createHash)("sha256").update(new Uint8Array(data)).digest("hex");
3667
+ }
3557
3668
 
3558
3669
  // src/utils.ts
3559
3670
  var isWin2 = process.platform === "win32";
@@ -3683,6 +3794,17 @@ async function runPyprojectScript(workPath, scriptNames, env, useUserVirtualEnv
3683
3794
  }
3684
3795
  return false;
3685
3796
  }
3797
+
3798
+ // src/version.ts
3799
+ var import_path4 = require("path");
3800
+ var import_fs3 = require("fs");
3801
+ var import_build_utils4 = require("@vercel/build-utils");
3802
+ var import_python_analysis = require("@vercel/python-analysis");
3803
+
3804
+ // src/platform-info.ts
3805
+ var import_os2 = __toESM(require("os"));
3806
+ var detectLibc = __toESM(require_detect_libc());
3807
+ var import_build_utils3 = require("@vercel/build-utils");
3686
3808
  var ARCH_MAP = {
3687
3809
  x64: "x86_64",
3688
3810
  arm64: "aarch64",
@@ -3692,58 +3814,73 @@ var ARCH_MAP = {
3692
3814
  s390x: "s390x"
3693
3815
  };
3694
3816
  function detectPlatform() {
3695
- const arch = import_os2.default.arch();
3696
- const archName = ARCH_MAP[arch] || arch;
3697
- const libcFamily = detectLibc.familySync();
3698
- const libcVersion = detectLibc.versionSync();
3699
- let osName;
3700
- let osMajor;
3701
- let osMinor;
3702
- if (libcFamily === detectLibc.MUSL) {
3703
- osName = "musllinux";
3704
- } else {
3705
- osName = "manylinux";
3706
- }
3707
- if (libcVersion) {
3708
- const parts = libcVersion.split(".");
3709
- osMajor = parseInt(parts[0], 10);
3710
- osMinor = parseInt(parts[1], 10) || 0;
3711
- } else if (libcFamily === detectLibc.GLIBC) {
3712
- osMajor = 2;
3713
- osMinor = 17;
3714
- } else {
3715
- osMajor = 2;
3716
- osMinor = 17;
3717
- }
3718
- const libc = libcFamily === detectLibc.MUSL ? "musl" : "gnu";
3719
3817
  const SYS_PLATFORM_MAP = {
3720
3818
  linux: "linux",
3721
3819
  win32: "win32",
3722
3820
  darwin: "darwin"
3723
3821
  };
3724
- const sysPlatform = SYS_PLATFORM_MAP[process.platform] || "linux";
3725
3822
  const OS_MAP = {
3726
3823
  linux: "linux",
3727
3824
  win32: "windows",
3728
3825
  darwin: "macos"
3729
3826
  };
3730
- const detectedOs = OS_MAP[process.platform] || "linux";
3731
- return {
3732
- osName,
3733
- archName,
3734
- osMajor,
3735
- osMinor,
3736
- os: detectedOs,
3737
- sysPlatform,
3738
- libc
3827
+ const arch = import_os2.default.arch();
3828
+ const libcFamily = detectLibc.familySync();
3829
+ const libcVersion = detectLibc.versionSync();
3830
+ const platform = {
3831
+ osName: "manylinux",
3832
+ archName: ARCH_MAP[arch] || arch,
3833
+ osMajor: 2,
3834
+ osMinor: 17,
3835
+ os: OS_MAP[process.platform] || "linux",
3836
+ sysPlatform: SYS_PLATFORM_MAP[process.platform] || "linux",
3837
+ libc: "gnu"
3739
3838
  };
3839
+ if (libcFamily === detectLibc.MUSL) {
3840
+ platform.osName = "musllinux";
3841
+ platform.libc = "musl";
3842
+ }
3843
+ if (libcVersion) {
3844
+ const parts = libcVersion.split(".");
3845
+ platform.osMajor = parseInt(parts[0], 10);
3846
+ platform.osMinor = parseInt(parts[1], 10) || 0;
3847
+ }
3848
+ return platform;
3849
+ }
3850
+ function validateBuildArch(arch) {
3851
+ switch (arch.toLowerCase()) {
3852
+ case "x86_64":
3853
+ return "x86_64";
3854
+ case "aarch64":
3855
+ return "aarch64";
3856
+ default:
3857
+ throw new import_build_utils3.NowBuildError({
3858
+ code: "INVALID_BUILD_ARCH",
3859
+ message: `Unrecognized VERCEL_BUILD_ARCH "${arch}". Expected "x86_64" or "aarch64".`
3860
+ });
3861
+ }
3862
+ }
3863
+ function detectTargetPlatform() {
3864
+ if (process.env.VERCEL_BUILD_IMAGE && process.platform === "linux") {
3865
+ return detectPlatform();
3866
+ }
3867
+ const arch = process.env.VERCEL_BUILD_ARCH;
3868
+ const platform = {
3869
+ osName: "manylinux",
3870
+ archName: "x86_64",
3871
+ osMajor: 2,
3872
+ osMinor: 17,
3873
+ os: "linux",
3874
+ sysPlatform: "linux",
3875
+ libc: "gnu"
3876
+ };
3877
+ if (arch) {
3878
+ platform.archName = validateBuildArch(arch);
3879
+ }
3880
+ return platform;
3740
3881
  }
3741
3882
 
3742
3883
  // src/version.ts
3743
- var import_path4 = require("path");
3744
- var import_fs3 = require("fs");
3745
- var import_build_utils3 = require("@vercel/build-utils");
3746
- var import_python_analysis = require("@vercel/python-analysis");
3747
3884
  function pythonVersionString(pv) {
3748
3885
  if (pv.major === void 0 || pv.minor === void 0)
3749
3886
  return void 0;
@@ -3793,7 +3930,7 @@ function getDefaultPythonVersion({
3793
3930
  }
3794
3931
  const selection = allOptions.find(isInstalled);
3795
3932
  if (!selection) {
3796
- throw new import_build_utils3.NowBuildError({
3933
+ throw new import_build_utils4.NowBuildError({
3797
3934
  code: "PYTHON_NOT_FOUND",
3798
3935
  link: "https://vercel.link/python-version",
3799
3936
  message: `Unable to find any supported Python versions.`
@@ -3893,7 +4030,7 @@ function resolvePythonVersion({
3893
4030
  } else if (result.notAvailable) {
3894
4031
  const npv = getPythonVersionForBuild(result.notAvailable.build);
3895
4032
  if (npv && isDiscontinued(npv)) {
3896
- throw new import_build_utils3.NowBuildError({
4033
+ throw new import_build_utils4.NowBuildError({
3897
4034
  code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
3898
4035
  link: "https://vercel.link/python-version",
3899
4036
  message: `Python version "${pythonVersionString(npv)}" detected in ${source} is discontinued and must be upgraded.`
@@ -3917,7 +4054,7 @@ function resolvePythonVersion({
3917
4054
  }
3918
4055
  }
3919
4056
  if (isDiscontinued(selection)) {
3920
- throw new import_build_utils3.NowBuildError({
4057
+ throw new import_build_utils4.NowBuildError({
3921
4058
  code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
3922
4059
  link: "https://vercel.link/python-version",
3923
4060
  message: `Python version "${pythonVersionString(selection)}" declared in project configuration is discontinued and must be upgraded.`
@@ -3975,7 +4112,7 @@ function getInstalledPythons() {
3975
4112
  }
3976
4113
  const uvPath = findUvInPath();
3977
4114
  if (!uvPath) {
3978
- throw new import_build_utils3.NowBuildError({
4115
+ throw new import_build_utils4.NowBuildError({
3979
4116
  code: "UV_ERROR",
3980
4117
  link: "https://vercel.link/python-version",
3981
4118
  message: "uv is required but was not found in PATH."
@@ -3993,7 +4130,7 @@ function isInstalled(pv) {
3993
4130
  return false;
3994
4131
  return installed.has(version2);
3995
4132
  } catch (err) {
3996
- throw new import_build_utils3.NowBuildError({
4133
+ throw new import_build_utils4.NowBuildError({
3997
4134
  code: "UV_ERROR",
3998
4135
  link: "https://vercel.link/python-version",
3999
4136
  message: err instanceof Error ? err.message : String(err)
@@ -4007,7 +4144,7 @@ async function restoreCachedLock(cachedLockPath, projectDir) {
4007
4144
  return;
4008
4145
  const targetLockPath = (0, import_path5.join)(projectDir, "uv.lock");
4009
4146
  if (import_fs4.default.existsSync(cachedLockPath) && !import_fs4.default.existsSync(targetLockPath)) {
4010
- (0, import_build_utils4.debug)("Restoring cached uv.lock");
4147
+ (0, import_build_utils5.debug)("Restoring cached uv.lock");
4011
4148
  await import_fs4.default.promises.copyFile(cachedLockPath, targetLockPath);
4012
4149
  }
4013
4150
  }
@@ -4074,7 +4211,7 @@ print(json.dumps(paths))
4074
4211
  return parsed.filter((p) => typeof p === "string");
4075
4212
  }
4076
4213
  } catch (err) {
4077
- (0, import_build_utils4.debug)("Failed to parse site-packages output", err);
4214
+ (0, import_build_utils5.debug)("Failed to parse site-packages output", err);
4078
4215
  }
4079
4216
  return [];
4080
4217
  }
@@ -4100,7 +4237,7 @@ async function discoverPackage({
4100
4237
  ${error.fileContent}`
4101
4238
  );
4102
4239
  }
4103
- throw new import_build_utils4.NowBuildError({
4240
+ throw new import_build_utils5.NowBuildError({
4104
4241
  code: error.code,
4105
4242
  message: error.message,
4106
4243
  link: error.link,
@@ -4239,7 +4376,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
4239
4376
  ...filterUnsafeUvPipArgs(args)
4240
4377
  ];
4241
4378
  const prettyUv = `${uvPath} ${uvArgs.join(" ")}`;
4242
- (0, import_build_utils4.debug)(`Running "${prettyUv}"...`);
4379
+ (0, import_build_utils5.debug)(`Running "${prettyUv}"...`);
4243
4380
  try {
4244
4381
  await (0, import_execa3.default)(uvPath, uvArgs, {
4245
4382
  cwd: workPath,
@@ -4248,7 +4385,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
4248
4385
  return;
4249
4386
  } catch (err) {
4250
4387
  console.log(`Failed to run "${prettyUv}", falling back to pip`);
4251
- (0, import_build_utils4.debug)(`error: ${err}`);
4388
+ (0, import_build_utils5.debug)(`error: ${err}`);
4252
4389
  }
4253
4390
  }
4254
4391
  const cmdArgs = [
@@ -4261,14 +4398,14 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
4261
4398
  ...args
4262
4399
  ];
4263
4400
  const pretty = `${pipPath} ${cmdArgs.join(" ")}`;
4264
- (0, import_build_utils4.debug)(`Running "${pretty}"...`);
4401
+ (0, import_build_utils5.debug)(`Running "${pretty}"...`);
4265
4402
  try {
4266
4403
  await (0, import_execa3.default)(pipPath, cmdArgs, {
4267
4404
  cwd: workPath
4268
4405
  });
4269
4406
  } catch (err) {
4270
4407
  console.log(`Failed to run "${pretty}"`);
4271
- (0, import_build_utils4.debug)(`error: ${err}`);
4408
+ (0, import_build_utils5.debug)(`error: ${err}`);
4272
4409
  throw err;
4273
4410
  }
4274
4411
  }
@@ -4285,7 +4422,7 @@ async function installRequirement({
4285
4422
  }) {
4286
4423
  const actualTargetDir = targetDir || workPath;
4287
4424
  if (meta.isDev && await isInstalled2(pythonPath, dependency, actualTargetDir)) {
4288
- (0, import_build_utils4.debug)(
4425
+ (0, import_build_utils5.debug)(
4289
4426
  `Skipping ${dependency} dependency installation, already installed in ${actualTargetDir}`
4290
4427
  );
4291
4428
  return;
@@ -4305,7 +4442,7 @@ async function installRequirementsFile({
4305
4442
  }) {
4306
4443
  const actualTargetDir = targetDir || workPath;
4307
4444
  if (meta.isDev && await areRequirementsInstalled(pythonPath, filePath, actualTargetDir)) {
4308
- (0, import_build_utils4.debug)(`Skipping requirements file installation, already installed`);
4445
+ (0, import_build_utils5.debug)(`Skipping requirements file installation, already installed`);
4309
4446
  return;
4310
4447
  }
4311
4448
  await pipInstall(
@@ -4321,7 +4458,7 @@ async function installRequirementsFile({
4321
4458
  var import_fs5 = __toESM(require("fs"));
4322
4459
  var import_util = require("util");
4323
4460
  var import_path6 = require("path");
4324
- var import_build_utils5 = require("@vercel/build-utils");
4461
+ var import_build_utils6 = require("@vercel/build-utils");
4325
4462
  var import_python_analysis3 = require("@vercel/python-analysis");
4326
4463
  var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
4327
4464
  var LAMBDA_SIZE_THRESHOLD_BYTES = 245 * 1024 * 1024;
@@ -4338,14 +4475,11 @@ function shouldShowFunctionsBetaHint() {
4338
4475
  var PythonDependencyExternalizer = class {
4339
4476
  constructor(options) {
4340
4477
  // Populated by analyze()
4478
+ this.sitePackageDirs = [];
4479
+ this.distributions = /* @__PURE__ */ new Map();
4341
4480
  this.allVendorFiles = {};
4342
4481
  this.totalBundleSize = 0;
4343
4482
  this.analyzed = false;
4344
- // Resolved once at the start of analyze(). The venv is immutable
4345
- // after construction (quirks run before the bundle span) so these
4346
- // do not change between analyze() and generateBundle().
4347
- this.sitePackageDirs = null;
4348
- this.distributions = null;
4349
4483
  this.venvPath = options.venvPath;
4350
4484
  this.vendorDir = options.vendorDir;
4351
4485
  this.workPath = options.workPath;
@@ -4396,12 +4530,12 @@ var PythonDependencyExternalizer = class {
4396
4530
  this.totalBundleSize = await calculateBundleSize(tempFilesForSizing);
4397
4531
  this.analyzed = true;
4398
4532
  const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
4399
- (0, import_build_utils5.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
4533
+ (0, import_build_utils6.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
4400
4534
  const runtimeInstallEnabled = this.shouldEnableRuntimeInstall();
4401
4535
  const pythonOnHiveEnabled = process.env.VERCEL_PYTHON_ON_HIVE === "1" || process.env.VERCEL_PYTHON_ON_HIVE === "true";
4402
4536
  if (this.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && this.hasCustomCommand && !pythonOnHiveEnabled) {
4403
4537
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
4404
- throw new import_build_utils5.NowBuildError({
4538
+ throw new import_build_utils6.NowBuildError({
4405
4539
  code: "LAMBDA_SIZE_EXCEEDED",
4406
4540
  message: shouldShowFunctionsBetaHint() ? `Total bundle size (${totalBundleSizeMB} MB) exceeds the size limit (${limitMB} MB).
4407
4541
 
@@ -4419,7 +4553,7 @@ dependencies, you can:
4419
4553
  }
4420
4554
  if (pythonOnHiveEnabled && this.totalBundleSize > HIVE_LAMBDA_SIZE_BYTES) {
4421
4555
  const limitMB = (HIVE_LAMBDA_SIZE_BYTES / (1024 * 1024)).toFixed(0);
4422
- throw new import_build_utils5.NowBuildError({
4556
+ throw new import_build_utils6.NowBuildError({
4423
4557
  code: "LAMBDA_SIZE_EXCEEDED",
4424
4558
  message: shouldShowFunctionsBetaHint() ? `Total bundle size (${totalBundleSizeMB} MB) exceeds the extended function size limit (${limitMB} MB).
4425
4559
 
@@ -4450,7 +4584,7 @@ application into smaller functions.`,
4450
4584
  );
4451
4585
  }
4452
4586
  if (!this.uvLockPath || !this.uvProjectDir) {
4453
- throw new import_build_utils5.NowBuildError({
4587
+ throw new import_build_utils6.NowBuildError({
4454
4588
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
4455
4589
  message: "Runtime dependency installation requires a uv.lock file and project directory."
4456
4590
  });
@@ -4461,7 +4595,7 @@ application into smaller functions.`,
4461
4595
  );
4462
4596
  if (this.totalBundleSize > LAMBDA_EPHEMERAL_STORAGE_BYTES) {
4463
4597
  const ephemeralLimitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(0);
4464
- throw new import_build_utils5.NowBuildError({
4598
+ throw new import_build_utils6.NowBuildError({
4465
4599
  code: "LAMBDA_SIZE_EXCEEDED",
4466
4600
  message: shouldShowFunctionsBetaHint() ? `Total bundle size (${totalBundleSizeMB} MB) exceeds the ephemeral storage limit (${ephemeralLimitMB} MB).
4467
4601
 
@@ -4488,7 +4622,7 @@ your application into smaller functions.`,
4488
4622
  `Failed to read uv.lock file at "${this.uvLockPath}": ${String(error)}`
4489
4623
  );
4490
4624
  }
4491
- throw new import_build_utils5.NowBuildError({
4625
+ throw new import_build_utils6.NowBuildError({
4492
4626
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
4493
4627
  message: `Failed to read uv.lock file at "${this.uvLockPath}"`
4494
4628
  });
@@ -4504,7 +4638,7 @@ your application into smaller functions.`,
4504
4638
  ${error.fileContent}`
4505
4639
  );
4506
4640
  }
4507
- throw new import_build_utils5.NowBuildError({
4641
+ throw new import_build_utils6.NowBuildError({
4508
4642
  code: error.code,
4509
4643
  message: error.message
4510
4644
  });
@@ -4514,7 +4648,7 @@ ${error.fileContent}`
4514
4648
  const excludePackages = [];
4515
4649
  if (this.projectName) {
4516
4650
  excludePackages.push(this.projectName);
4517
- (0, import_build_utils5.debug)(
4651
+ (0, import_build_utils6.debug)(
4518
4652
  `Excluding project package "${this.projectName}" from runtime installation`
4519
4653
  );
4520
4654
  }
@@ -4522,7 +4656,7 @@ ${error.fileContent}`
4522
4656
  lockFile,
4523
4657
  excludePackages
4524
4658
  });
4525
- (0, import_build_utils5.debug)(
4659
+ (0, import_build_utils6.debug)(
4526
4660
  `Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
4527
4661
  );
4528
4662
  const forceBundledDueToWheels = await this.findPackagesWithoutCompatibleWheels(
@@ -4541,7 +4675,7 @@ ${error.fileContent}`
4541
4675
  (name) => !forceBundledSet.has((0, import_python_analysis3.normalizePackageName)(name))
4542
4676
  );
4543
4677
  if (externalizablePublic.length === 0) {
4544
- throw new import_build_utils5.NowBuildError({
4678
+ throw new import_build_utils6.NowBuildError({
4545
4679
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
4546
4680
  message: `Bundle size exceeds the Lambda limit and requires runtime
4547
4681
  dependency installation, but no public packages have compatible
@@ -4574,14 +4708,12 @@ To fix this, either:
4574
4708
  }
4575
4709
  const fixedOverhead = await calculateBundleSize(baseFiles);
4576
4710
  let runtimeToolingOverhead = 0;
4577
- if (process.env.VERCEL_BUILD_IMAGE) {
4578
- try {
4579
- const uvBinaryPath = await getUvBinaryForBundling(this.pythonPath);
4580
- const uvStats = await import_fs5.default.promises.stat(uvBinaryPath);
4581
- runtimeToolingOverhead = uvStats.size;
4582
- } catch {
4583
- runtimeToolingOverhead = 50 * 1024 * 1024;
4584
- }
4711
+ try {
4712
+ const uvBinaryPath = await this.resolveUvBinaryForBundling();
4713
+ const uvStats = await import_fs5.default.promises.stat(uvBinaryPath);
4714
+ runtimeToolingOverhead = uvStats.size;
4715
+ } catch {
4716
+ runtimeToolingOverhead = 50 * 1024 * 1024;
4585
4717
  }
4586
4718
  runtimeToolingOverhead += 4 * 1024;
4587
4719
  const projectDirRel = (0, import_path6.relative)(this.workPath, this.uvProjectDir);
@@ -4597,7 +4729,7 @@ To fix this, either:
4597
4729
  runtimeToolingOverhead += uvLockStats.size;
4598
4730
  }
4599
4731
  const remainingCapacity = LAMBDA_SIZE_THRESHOLD_BYTES - fixedOverhead - runtimeToolingOverhead;
4600
- (0, import_build_utils5.debug)(
4732
+ (0, import_build_utils6.debug)(
4601
4733
  `Fixed overhead: ${(fixedOverhead / (1024 * 1024)).toFixed(2)} MB, runtime tooling: ${(runtimeToolingOverhead / (1024 * 1024)).toFixed(2)} MB, remaining capacity for public packages: ${(remainingCapacity / (1024 * 1024)).toFixed(2)} MB`
4602
4734
  );
4603
4735
  const externalizableSet = new Set(
@@ -4625,10 +4757,10 @@ To fix this, either:
4625
4757
  ];
4626
4758
  if (isOutsideWorkPath) {
4627
4759
  const srcPyproject = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
4628
- files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils5.FileFsRef({
4760
+ files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils6.FileFsRef({
4629
4761
  fsPath: srcPyproject
4630
4762
  });
4631
- files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils5.FileFsRef({
4763
+ files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils6.FileFsRef({
4632
4764
  fsPath: this.uvLockPath
4633
4765
  });
4634
4766
  }
@@ -4636,36 +4768,33 @@ To fix this, either:
4636
4768
  projectDir: isOutsideWorkPath ? UV_BUNDLE_DIR : projectDirRel,
4637
4769
  bundledPackages: bundledPackagesForConfig
4638
4770
  });
4639
- files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils5.FileBlob({
4771
+ files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils6.FileBlob({
4640
4772
  data: runtimeConfigData
4641
4773
  });
4642
- if (process.env.VERCEL_BUILD_IMAGE) {
4643
- try {
4644
- const uvBinaryPath = await getUvBinaryForBundling(this.pythonPath);
4645
- const uvBundleDir = (0, import_path6.join)(this.workPath, UV_BUNDLE_DIR);
4646
- const uvLocalPath = (0, import_path6.join)(uvBundleDir, "uv");
4647
- await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
4648
- await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
4649
- await import_fs5.default.promises.chmod(uvLocalPath, 493);
4650
- const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
4651
- files[uvBundlePath] = new import_build_utils5.FileFsRef({
4652
- fsPath: uvLocalPath,
4653
- mode: 33261
4654
- // Regular file + executable
4655
- });
4656
- (0, import_build_utils5.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
4657
- } catch (err) {
4658
- throw new import_build_utils5.NowBuildError({
4659
- code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
4660
- message: `Failed to bundle uv binary for runtime installation: ${err instanceof Error ? err.message : String(err)}`
4661
- });
4662
- }
4774
+ try {
4775
+ const uvBinaryPath = await this.resolveUvBinaryForBundling();
4776
+ const uvBundleDir = (0, import_path6.join)(this.workPath, UV_BUNDLE_DIR);
4777
+ const uvLocalPath = (0, import_path6.join)(uvBundleDir, "uv");
4778
+ await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
4779
+ await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
4780
+ await import_fs5.default.promises.chmod(uvLocalPath, 493);
4781
+ const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
4782
+ files[uvBundlePath] = new import_build_utils6.FileFsRef({
4783
+ fsPath: uvLocalPath,
4784
+ mode: 33261
4785
+ });
4786
+ (0, import_build_utils6.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
4787
+ } catch (err) {
4788
+ throw new import_build_utils6.NowBuildError({
4789
+ code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
4790
+ message: `Failed to bundle uv binary for runtime installation: ${err instanceof Error ? err.message : String(err)}`
4791
+ });
4663
4792
  }
4664
4793
  const finalBundleSize = await calculateBundleSize(files);
4665
4794
  if (finalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES + 100 * 1024) {
4666
4795
  const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
4667
4796
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
4668
- throw new import_build_utils5.NowBuildError({
4797
+ throw new import_build_utils6.NowBuildError({
4669
4798
  code: "LAMBDA_SIZE_EXCEEDED",
4670
4799
  message: shouldShowFunctionsBetaHint() ? `Total bundle size (${finalSizeMB} MB) exceeds the size limit (${limitMB} MB).
4671
4800
 
@@ -4691,9 +4820,9 @@ splitting your application.`,
4691
4820
  * irrelevant.
4692
4821
  */
4693
4822
  async findPackagesWithoutCompatibleWheels(lockFile, publicPackageNames) {
4694
- const platform = detectPlatform();
4823
+ const platform = detectTargetPlatform();
4695
4824
  if (this.pythonMajor === void 0 || this.pythonMinor === void 0) {
4696
- (0, import_build_utils5.debug)("Skipping wheel compatibility check: dev mode");
4825
+ (0, import_build_utils6.debug)("Skipping wheel compatibility check: dev mode");
4697
4826
  return [];
4698
4827
  }
4699
4828
  const reachable = await getPackagesReachableOnPlatform(
@@ -4708,7 +4837,7 @@ splitting your application.`,
4708
4837
  (name) => reachable.has((0, import_python_analysis3.normalizePackageName)(name))
4709
4838
  ) : publicPackageNames;
4710
4839
  if (relevantPackages.length < publicPackageNames.length) {
4711
- (0, import_build_utils5.debug)(
4840
+ (0, import_build_utils6.debug)(
4712
4841
  `Skipping wheel check for ${publicPackageNames.length - relevantPackages.length} package(s) not reachable on the target platform`
4713
4842
  );
4714
4843
  }
@@ -4748,7 +4877,7 @@ splitting your application.`,
4748
4877
  break;
4749
4878
  }
4750
4879
  } catch (err) {
4751
- (0, import_build_utils5.debug)(
4880
+ (0, import_build_utils6.debug)(
4752
4881
  `Failed to check wheel compatibility for ${filename}: ${err instanceof Error ? err.message : String(err)}`
4753
4882
  );
4754
4883
  }
@@ -4759,6 +4888,15 @@ splitting your application.`,
4759
4888
  }
4760
4889
  return incompatible;
4761
4890
  }
4891
+ /** Resolve the uv binary for bundling (host binary on build image, downloaded on local). */
4892
+ async resolveUvBinaryForBundling() {
4893
+ if (process.env.VERCEL_BUILD_IMAGE) {
4894
+ return getUvBinaryForBundling(this.pythonPath);
4895
+ }
4896
+ return downloadUvBinaryForTarget(
4897
+ (0, import_path6.join)(this.workPath, ".vercel", "python", "cache")
4898
+ );
4899
+ }
4762
4900
  /**
4763
4901
  * Mirror packages from site-packages into the _vendor directory.
4764
4902
  *
@@ -4828,13 +4966,13 @@ splitting your application.`,
4828
4966
  );
4829
4967
  for (const result of results) {
4830
4968
  if (result) {
4831
- vendorFiles[result.bundlePath] = new import_build_utils5.FileFsRef({
4969
+ vendorFiles[result.bundlePath] = new import_build_utils6.FileFsRef({
4832
4970
  fsPath: result.srcFsPath,
4833
4971
  size: result.size
4834
4972
  });
4835
4973
  }
4836
4974
  }
4837
- (0, import_build_utils5.debug)(
4975
+ (0, import_build_utils6.debug)(
4838
4976
  `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
4839
4977
  );
4840
4978
  return vendorFiles;
@@ -4915,13 +5053,13 @@ async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor
4915
5053
  platformMachine
4916
5054
  );
4917
5055
  if (!compatible) {
4918
- (0, import_build_utils5.debug)(
5056
+ (0, import_build_utils6.debug)(
4919
5057
  `Skipping dependency ${dep.name}: marker "${dep.marker}" not satisfied on ${sysPlatform}`
4920
5058
  );
4921
5059
  continue;
4922
5060
  }
4923
5061
  } catch (err) {
4924
- (0, import_build_utils5.debug)(
5062
+ (0, import_build_utils6.debug)(
4925
5063
  `Failed to evaluate marker "${dep.marker}" for ${dep.name}, including conservatively: ${err instanceof Error ? err.message : String(err)}`
4926
5064
  );
4927
5065
  }
@@ -4991,7 +5129,7 @@ function lambdaKnapsack(packages, capacity) {
4991
5129
 
4992
5130
  // src/diagnostics.ts
4993
5131
  var import_fs6 = __toESM(require("fs"));
4994
- var import_build_utils6 = require("@vercel/build-utils");
5132
+ var import_build_utils7 = require("@vercel/build-utils");
4995
5133
  var import_python_analysis4 = require("@vercel/python-analysis");
4996
5134
  function isDependencyGroupInclude(entry) {
4997
5135
  return typeof entry === "object" && "include-group" in entry;
@@ -5196,7 +5334,7 @@ async function generateProjectManifest({
5196
5334
  }
5197
5335
  }
5198
5336
  const manifest = {
5199
- version: import_build_utils6.MANIFEST_VERSION,
5337
+ version: import_build_utils7.MANIFEST_VERSION,
5200
5338
  runtime: "python",
5201
5339
  ...framework ? { framework } : {},
5202
5340
  ...serviceType ? { serviceType } : {},
@@ -5210,22 +5348,22 @@ async function generateProjectManifest({
5210
5348
  ...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
5211
5349
  ]
5212
5350
  };
5213
- await (0, import_build_utils6.writeProjectManifest)(manifest, workPath, "python");
5351
+ await (0, import_build_utils7.writeProjectManifest)(manifest, workPath, "python");
5214
5352
  }
5215
- var diagnostics = (0, import_build_utils6.createDiagnostics)("python");
5353
+ var diagnostics = (0, import_build_utils7.createDiagnostics)("python");
5216
5354
 
5217
5355
  // src/crons.ts
5218
5356
  var import_fs8 = __toESM(require("fs"));
5219
5357
  var import_path8 = require("path");
5220
5358
  var import_execa4 = __toESM(require_execa());
5221
- var import_build_utils10 = require("@vercel/build-utils");
5359
+ var import_build_utils11 = require("@vercel/build-utils");
5222
5360
 
5223
5361
  // src/entrypoint.ts
5224
5362
  var import_fs7 = __toESM(require("fs"));
5225
5363
  var import_path7 = require("path");
5226
- var import_build_utils7 = require("@vercel/build-utils");
5227
5364
  var import_build_utils8 = require("@vercel/build-utils");
5228
5365
  var import_build_utils9 = require("@vercel/build-utils");
5366
+ var import_build_utils10 = require("@vercel/build-utils");
5229
5367
  var import_python_analysis5 = require("@vercel/python-analysis");
5230
5368
  var PYTHON_ENTRYPOINT_FILENAMES = [
5231
5369
  "app",
@@ -5379,7 +5517,7 @@ async function resolveModuleAttrEntrypoint(workPath, value) {
5379
5517
  return null;
5380
5518
  }
5381
5519
  async function getVercelToolsEntrypoint(workPath) {
5382
- const pyprojectData = await (0, import_build_utils9.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
5520
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
5383
5521
  if (!pyprojectData)
5384
5522
  return null;
5385
5523
  const vercelEntrypoint = pyprojectData.tool?.vercel?.entrypoint;
@@ -5388,7 +5526,7 @@ async function getVercelToolsEntrypoint(workPath) {
5388
5526
  return resolveModuleAttrEntrypoint(workPath, vercelEntrypoint);
5389
5527
  }
5390
5528
  async function getPyprojectEntrypointWithDiagnostics(workPath) {
5391
- const pyprojectData = await (0, import_build_utils9.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
5529
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
5392
5530
  if (!pyprojectData)
5393
5531
  return { entrypoint: null };
5394
5532
  const scripts = pyprojectData.project?.scripts;
@@ -5418,7 +5556,7 @@ async function findValidEntrypoint(workPath, candidates) {
5418
5556
  const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
5419
5557
  const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
5420
5558
  if (varName) {
5421
- (0, import_build_utils8.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
5559
+ (0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
5422
5560
  return {
5423
5561
  entrypoint: { entrypoint: candidate, variableName: varName },
5424
5562
  existingWithoutEntrypoint
@@ -5434,7 +5572,7 @@ async function checkDjangoManage(workPath) {
5434
5572
  const content = await import_fs7.default.promises.readFile(managePath, "utf-8");
5435
5573
  if (!content.includes("DJANGO_SETTINGS_MODULE"))
5436
5574
  return false;
5437
- (0, import_build_utils8.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
5575
+ (0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
5438
5576
  return true;
5439
5577
  } catch {
5440
5578
  return false;
@@ -5487,7 +5625,7 @@ ${suggestion}`;
5487
5625
  const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
5488
5626
  message = `No ${displayName} entrypoint found. Set "tool.vercel.entrypoint" in pyproject.toml or define an entrypoint in one of: ${searchedList}.`;
5489
5627
  }
5490
- return new import_build_utils7.NowBuildError({ code, message, link, action });
5628
+ return new import_build_utils8.NowBuildError({ code, message, link, action });
5491
5629
  }
5492
5630
  async function detectGenericPythonEntrypoint(workPath) {
5493
5631
  try {
@@ -5500,7 +5638,7 @@ async function detectGenericPythonEntrypoint(workPath) {
5500
5638
  findDiagnostics: result
5501
5639
  };
5502
5640
  } catch {
5503
- (0, import_build_utils8.debug)("Failed to discover Python entrypoint");
5641
+ (0, import_build_utils9.debug)("Failed to discover Python entrypoint");
5504
5642
  return {
5505
5643
  detected: null,
5506
5644
  findDiagnostics: { entrypoint: null, existingWithoutEntrypoint: [] }
@@ -5535,7 +5673,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
5535
5673
  findDiagnostics: result
5536
5674
  };
5537
5675
  } catch {
5538
- (0, import_build_utils8.debug)("Failed to discover Django Python entrypoint");
5676
+ (0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
5539
5677
  return emptyResult;
5540
5678
  }
5541
5679
  }
@@ -5546,7 +5684,7 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
5546
5684
  const entrypointExists = await fileExists((0, import_path7.join)(workPath, entrypoint));
5547
5685
  if (!entrypointExists) {
5548
5686
  return {
5549
- error: new import_build_utils7.NowBuildError({
5687
+ error: new import_build_utils8.NowBuildError({
5550
5688
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
5551
5689
  message: `Configured Python entrypoint "${entrypoint}" was not found.`,
5552
5690
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -5556,17 +5694,17 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
5556
5694
  }
5557
5695
  let varName = configEntryVar ?? await checkEntrypoint(workPath, entrypoint);
5558
5696
  if (!varName) {
5559
- const needsDynamicApp = !!service && ((0, import_build_utils7.isScheduleTriggeredService)(service) || (0, import_build_utils7.isQueueTriggeredService)(service));
5697
+ const needsDynamicApp = !!service && ((0, import_build_utils8.isScheduleTriggeredService)(service) || (0, import_build_utils8.isQueueTriggeredService)(service));
5560
5698
  if (needsDynamicApp) {
5561
5699
  varName = "app";
5562
5700
  }
5563
5701
  }
5564
5702
  if (varName) {
5565
- (0, import_build_utils8.debug)(`Using configured Python entrypoint: ${entrypoint}`);
5703
+ (0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
5566
5704
  return { entrypoint: { entrypoint, variableName: varName } };
5567
5705
  } else {
5568
5706
  return {
5569
- error: new import_build_utils7.NowBuildError({
5707
+ error: new import_build_utils8.NowBuildError({
5570
5708
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
5571
5709
  message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
5572
5710
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -5612,6 +5750,24 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
5612
5750
  const error = makeDiagnosticError(framework, diagnostics2);
5613
5751
  return djangoManageBaseDir !== void 0 ? { baseDir: djangoManageBaseDir, error } : { error };
5614
5752
  }
5753
+ var detectEntrypoint = async ({
5754
+ workPath,
5755
+ framework
5756
+ }) => {
5757
+ if (!(0, import_build_utils8.isPythonFramework)(framework))
5758
+ return null;
5759
+ const detected = await detectPythonEntrypoint(
5760
+ framework,
5761
+ workPath
5762
+ );
5763
+ if (!detected?.entrypoint)
5764
+ return null;
5765
+ const { entrypoint, variableName } = detected.entrypoint;
5766
+ return {
5767
+ kind: "py-module:attr",
5768
+ entrypoint: `${entrypointToModule(entrypoint)}:${variableName}`
5769
+ };
5770
+ };
5615
5771
 
5616
5772
  // src/crons.ts
5617
5773
  var DYNAMIC_SCHEDULE = "<dynamic>";
@@ -5626,13 +5782,13 @@ function buildCronRouteTable(crons) {
5626
5782
  }
5627
5783
  async function getServiceCrons(opts) {
5628
5784
  const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
5629
- const isScheduledService = !!service && (0, import_build_utils10.isScheduleTriggeredService)(service);
5785
+ const isScheduledService = !!service && (0, import_build_utils11.isScheduleTriggeredService)(service);
5630
5786
  if (!isScheduledService || !service.name || typeof service.schedule !== "string" && !Array.isArray(service.schedule)) {
5631
5787
  return void 0;
5632
5788
  }
5633
5789
  const cronEntrypoint = entrypoint || rawEntrypoint;
5634
5790
  if (!cronEntrypoint) {
5635
- throw new import_build_utils10.NowBuildError({
5791
+ throw new import_build_utils11.NowBuildError({
5636
5792
  code: "PYTHON_CRON_NO_ENTRYPOINT",
5637
5793
  message: "Cron service is missing an entrypoint."
5638
5794
  });
@@ -5647,7 +5803,7 @@ async function getServiceCrons(opts) {
5647
5803
  workPath: opts.workPath
5648
5804
  });
5649
5805
  }
5650
- const cronPath = (0, import_build_utils10.getInternalServiceCronPath)(
5806
+ const cronPath = (0, import_build_utils11.getInternalServiceCronPath)(
5651
5807
  service.name,
5652
5808
  cronEntrypoint,
5653
5809
  handlerFunction || "cron"
@@ -5671,7 +5827,7 @@ async function getServiceCronsDynamic(opts) {
5671
5827
  workPath
5672
5828
  } = opts;
5673
5829
  if (!handlerFunction) {
5674
- throw new import_build_utils10.NowBuildError({
5830
+ throw new import_build_utils11.NowBuildError({
5675
5831
  code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
5676
5832
  message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
5677
5833
  });
@@ -5688,7 +5844,7 @@ async function getServiceCronsDynamic(opts) {
5688
5844
  `Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
5689
5845
  );
5690
5846
  if (entries.length === 0) {
5691
- throw new import_build_utils10.NowBuildError({
5847
+ throw new import_build_utils11.NowBuildError({
5692
5848
  code: "PYTHON_DYNAMIC_CRON_EMPTY",
5693
5849
  message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
5694
5850
  });
@@ -5723,7 +5879,7 @@ async function detectDynamicCrons(opts) {
5723
5879
  detail = parsed2.error;
5724
5880
  } catch {
5725
5881
  }
5726
- throw new import_build_utils10.NowBuildError({
5882
+ throw new import_build_utils11.NowBuildError({
5727
5883
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
5728
5884
  message: `Failed to detect dynamic cron entries: ${detail}`
5729
5885
  });
@@ -5732,7 +5888,7 @@ async function detectDynamicCrons(opts) {
5732
5888
  try {
5733
5889
  parsed = JSON.parse(stdout);
5734
5890
  } catch {
5735
- throw new import_build_utils10.NowBuildError({
5891
+ throw new import_build_utils11.NowBuildError({
5736
5892
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
5737
5893
  message: `Dynamic cron detection returned invalid JSON: ${stdout}`
5738
5894
  });
@@ -5742,7 +5898,7 @@ async function detectDynamicCrons(opts) {
5742
5898
  function moduleColonFuncToCronPath(serviceName, moduleFunction) {
5743
5899
  const colonIdx = moduleFunction.indexOf(":");
5744
5900
  if (colonIdx === -1) {
5745
- throw new import_build_utils10.NowBuildError({
5901
+ throw new import_build_utils11.NowBuildError({
5746
5902
  code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
5747
5903
  message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
5748
5904
  });
@@ -5750,14 +5906,14 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
5750
5906
  const modulePart = moduleFunction.slice(0, colonIdx);
5751
5907
  const funcPart = moduleFunction.slice(colonIdx + 1);
5752
5908
  const entrypointPath = modulePart.replace(/\./g, "/");
5753
- return (0, import_build_utils10.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
5909
+ return (0, import_build_utils11.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
5754
5910
  }
5755
5911
 
5756
5912
  // src/start-dev-server.ts
5757
5913
  var import_child_process2 = require("child_process");
5758
5914
  var import_fs9 = require("fs");
5759
5915
  var import_path9 = require("path");
5760
- var import_build_utils11 = require("@vercel/build-utils");
5916
+ var import_build_utils12 = require("@vercel/build-utils");
5761
5917
  var import_get_port = __toESM(require_get_port());
5762
5918
  var import_is_port_reachable = __toESM(require_is_port_reachable());
5763
5919
  var import_python_analysis6 = require("@vercel/python-analysis");
@@ -5846,7 +6002,7 @@ async function syncDependencies({
5846
6002
  let { manifestPath } = installInfo;
5847
6003
  const manifest = pythonPackage.manifest;
5848
6004
  if (!manifestType || !manifestPath) {
5849
- (0, import_build_utils11.debug)("No Python project manifest found, skipping dependency sync");
6005
+ (0, import_build_utils12.debug)("No Python project manifest found, skipping dependency sync");
5850
6006
  return;
5851
6007
  }
5852
6008
  if (manifest?.origin && manifestType === "pyproject.toml") {
@@ -5856,7 +6012,7 @@ async function syncDependencies({
5856
6012
  const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
5857
6013
  (0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
5858
6014
  manifestPath = tempPyproject;
5859
- (0, import_build_utils11.debug)(
6015
+ (0, import_build_utils12.debug)(
5860
6016
  `Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
5861
6017
  );
5862
6018
  }
@@ -5889,7 +6045,7 @@ async function syncDependencies({
5889
6045
  for (const [channel, chunk] of captured) {
5890
6046
  (channel === "stdout" ? writeOut : writeErr)(chunk.toString());
5891
6047
  }
5892
- throw new import_build_utils11.NowBuildError({
6048
+ throw new import_build_utils12.NowBuildError({
5893
6049
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
5894
6050
  message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
5895
6051
  });
@@ -5911,7 +6067,7 @@ async function runSync({
5911
6067
  switch (manifestType) {
5912
6068
  case "uv.lock": {
5913
6069
  if (!uvPath) {
5914
- throw new import_build_utils11.NowBuildError({
6070
+ throw new import_build_utils12.NowBuildError({
5915
6071
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
5916
6072
  message: "uv is required to install dependencies from uv.lock.",
5917
6073
  link: "https://docs.astral.sh/uv/getting-started/installation/",
@@ -5933,11 +6089,11 @@ async function runSync({
5933
6089
  break;
5934
6090
  }
5935
6091
  default:
5936
- (0, import_build_utils11.debug)(`Unknown manifest type: ${manifestType}`);
6092
+ (0, import_build_utils12.debug)(`Unknown manifest type: ${manifestType}`);
5937
6093
  return;
5938
6094
  }
5939
6095
  await new Promise((resolve3, reject) => {
5940
- (0, import_build_utils11.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
6096
+ (0, import_build_utils12.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
5941
6097
  const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
5942
6098
  cwd: projectDir,
5943
6099
  env: getProtectedUvEnv(env),
@@ -6024,13 +6180,13 @@ async function doInstallVercelRuntime({
6024
6180
  `vercel_runtime-${VERCEL_RUNTIME_VERSION}.dist-info`
6025
6181
  );
6026
6182
  if ((0, import_fs9.existsSync)(distInfo)) {
6027
- (0, import_build_utils11.debug)(
6183
+ (0, import_build_utils12.debug)(
6028
6184
  `vercel-runtime ${VERCEL_RUNTIME_VERSION} already installed, skipping`
6029
6185
  );
6030
6186
  return;
6031
6187
  }
6032
6188
  }
6033
- (0, import_build_utils11.debug)(
6189
+ (0, import_build_utils12.debug)(
6034
6190
  `Installing vercel-runtime into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${runtimeDep})`
6035
6191
  );
6036
6192
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
@@ -6045,14 +6201,14 @@ async function doInstallVercelRuntime({
6045
6201
  if (onStdout) {
6046
6202
  onStdout(data);
6047
6203
  } else {
6048
- (0, import_build_utils11.debug)(data.toString());
6204
+ (0, import_build_utils12.debug)(data.toString());
6049
6205
  }
6050
6206
  });
6051
6207
  child.stderr?.on("data", (data) => {
6052
6208
  if (onStderr) {
6053
6209
  onStderr(data);
6054
6210
  } else {
6055
- (0, import_build_utils11.debug)(data.toString());
6211
+ (0, import_build_utils12.debug)(data.toString());
6056
6212
  }
6057
6213
  });
6058
6214
  child.on("error", reject);
@@ -6120,13 +6276,13 @@ async function doInstallVercelWorkers({
6120
6276
  `vercel_workers-${VERCEL_WORKERS_VERSION}.dist-info`
6121
6277
  );
6122
6278
  if ((0, import_fs9.existsSync)(distInfo)) {
6123
- (0, import_build_utils11.debug)(
6279
+ (0, import_build_utils12.debug)(
6124
6280
  `vercel-workers ${VERCEL_WORKERS_VERSION} already installed, skipping`
6125
6281
  );
6126
6282
  return;
6127
6283
  }
6128
6284
  }
6129
- (0, import_build_utils11.debug)(
6285
+ (0, import_build_utils12.debug)(
6130
6286
  `Installing vercel-workers into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${workersDep})`
6131
6287
  );
6132
6288
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
@@ -6141,14 +6297,14 @@ async function doInstallVercelWorkers({
6141
6297
  if (onStdout) {
6142
6298
  onStdout(data);
6143
6299
  } else {
6144
- (0, import_build_utils11.debug)(data.toString());
6300
+ (0, import_build_utils12.debug)(data.toString());
6145
6301
  }
6146
6302
  });
6147
6303
  child.stderr?.on("data", (data) => {
6148
6304
  if (onStderr) {
6149
6305
  onStderr(data);
6150
6306
  } else {
6151
- (0, import_build_utils11.debug)(data.toString());
6307
+ (0, import_build_utils12.debug)(data.toString());
6152
6308
  }
6153
6309
  });
6154
6310
  child.on("error", reject);
@@ -6178,12 +6334,12 @@ function installGlobalCleanupHandlers() {
6178
6334
  try {
6179
6335
  process.kill(info.pid, "SIGTERM");
6180
6336
  } catch (err) {
6181
- (0, import_build_utils11.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
6337
+ (0, import_build_utils12.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
6182
6338
  }
6183
6339
  try {
6184
6340
  process.kill(info.pid, "SIGKILL");
6185
6341
  } catch (err) {
6186
- (0, import_build_utils11.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
6342
+ (0, import_build_utils12.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
6187
6343
  }
6188
6344
  PERSISTENT_SERVERS.delete(key);
6189
6345
  }
@@ -6191,7 +6347,7 @@ function installGlobalCleanupHandlers() {
6191
6347
  try {
6192
6348
  restoreWarnings();
6193
6349
  } catch (err) {
6194
- (0, import_build_utils11.debug)(`Error restoring warnings: ${err}`);
6350
+ (0, import_build_utils12.debug)(`Error restoring warnings: ${err}`);
6195
6351
  }
6196
6352
  restoreWarnings = null;
6197
6353
  }
@@ -6228,21 +6384,21 @@ function createDevShim(workPath, entry, modulePath, serviceName, framework, vari
6228
6384
  const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
6229
6385
  const shimSource = template.replace(/__VC_DEV_MODULE_NAME__/g, qualifiedModule).replace(/__VC_DEV_ENTRY_ABS__/g, entryAbs).replace(/__VC_DEV_FRAMEWORK__/g, framework).replace(/__VC_DEV_VARIABLE_NAME__/g, variableName);
6230
6386
  (0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
6231
- (0, import_build_utils11.debug)(`Prepared Python dev shim at ${shimPath}`);
6387
+ (0, import_build_utils12.debug)(`Prepared Python dev shim at ${shimPath}`);
6232
6388
  return {
6233
6389
  module: DEV_SHIM_MODULE,
6234
6390
  extraPythonPath,
6235
6391
  shimDir: vercelPythonDir
6236
6392
  };
6237
6393
  } catch (err) {
6238
- (0, import_build_utils11.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
6394
+ (0, import_build_utils12.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
6239
6395
  return null;
6240
6396
  }
6241
6397
  }
6242
6398
  async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
6243
6399
  const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
6244
6400
  if (venvRoot) {
6245
- (0, import_build_utils11.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
6401
+ (0, import_build_utils12.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
6246
6402
  return { command: pythonCmd, args: [] };
6247
6403
  }
6248
6404
  const venvPath = (0, import_path9.join)(workPath, ".venv");
@@ -6252,7 +6408,7 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
6252
6408
  uvPath,
6253
6409
  quiet: true
6254
6410
  });
6255
- (0, import_build_utils11.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
6411
+ (0, import_build_utils12.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
6256
6412
  const pythonBin = getVenvPythonBin(venvPath);
6257
6413
  const binDir = getVenvBinDir(venvPath);
6258
6414
  env.VIRTUAL_ENV = venvPath;
@@ -6310,7 +6466,7 @@ var startDevServer = async (opts) => {
6310
6466
  filePath: entrypoint,
6311
6467
  // Schedule-triggered services create their own "app" wrapper dynamically.
6312
6468
  // Other services use handlerFunction as the entrypoint variable name.
6313
- varName: service && (0, import_build_utils11.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
6469
+ varName: service && (0, import_build_utils12.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
6314
6470
  } : void 0,
6315
6471
  service
6316
6472
  );
@@ -6330,7 +6486,7 @@ var startDevServer = async (opts) => {
6330
6486
  if (detected?.error) {
6331
6487
  throw detected.error;
6332
6488
  }
6333
- throw new import_build_utils11.NowBuildError({
6489
+ throw new import_build_utils12.NowBuildError({
6334
6490
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
6335
6491
  message: "No Python entrypoint could be detected. Please specify an entrypoint file."
6336
6492
  });
@@ -6359,7 +6515,7 @@ var startDevServer = async (opts) => {
6359
6515
  const yellow = "\x1B[33m";
6360
6516
  const white = "\x1B[1m";
6361
6517
  const reset = "\x1B[0m";
6362
- throw new import_build_utils11.NowBuildError({
6518
+ throw new import_build_utils12.NowBuildError({
6363
6519
  code: "PYTHON_EXTERNAL_VENV_DETECTED",
6364
6520
  message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
6365
6521
  Run ${white}deactivate${reset} and try again.`
@@ -6376,11 +6532,11 @@ Run ${white}deactivate${reset} and try again.`
6376
6532
  );
6377
6533
  spawnCommand = runner.command;
6378
6534
  spawnArgsPrefix = runner.args;
6379
- (0, import_build_utils11.debug)(
6535
+ (0, import_build_utils12.debug)(
6380
6536
  `Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
6381
6537
  );
6382
6538
  } else if (venv) {
6383
- (0, import_build_utils11.debug)(`Running in virtualenv at ${venv}`);
6539
+ (0, import_build_utils12.debug)(`Running in virtualenv at ${venv}`);
6384
6540
  } else {
6385
6541
  const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
6386
6542
  workPath,
@@ -6389,9 +6545,9 @@ Run ${white}deactivate${reset} and try again.`
6389
6545
  );
6390
6546
  spawnCommand = venvPythonCmd;
6391
6547
  if (venvRoot) {
6392
- (0, import_build_utils11.debug)(`Using virtualenv at ${venvRoot}`);
6548
+ (0, import_build_utils12.debug)(`Using virtualenv at ${venvRoot}`);
6393
6549
  } else {
6394
- (0, import_build_utils11.debug)("No virtualenv found");
6550
+ (0, import_build_utils12.debug)("No virtualenv found");
6395
6551
  try {
6396
6552
  const yellow = "\x1B[33m";
6397
6553
  const reset = "\x1B[0m";
@@ -6481,7 +6637,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
6481
6637
  const moduleToRun = devShim?.module || modulePath;
6482
6638
  const pythonArgs = ["-u", "-m", moduleToRun];
6483
6639
  const argv = [...spawnArgsPrefix, ...pythonArgs];
6484
- (0, import_build_utils11.debug)(
6640
+ (0, import_build_utils12.debug)(
6485
6641
  `Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
6486
6642
  );
6487
6643
  if (process.stdout.columns) {
@@ -6535,7 +6691,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
6535
6691
  };
6536
6692
 
6537
6693
  // src/quirks/index.ts
6538
- var import_build_utils14 = require("@vercel/build-utils");
6694
+ var import_build_utils15 = require("@vercel/build-utils");
6539
6695
  var import_python_analysis8 = require("@vercel/python-analysis");
6540
6696
 
6541
6697
  // src/quirks/matplotlib.ts
@@ -6551,7 +6707,7 @@ var matplotlibQuirk = {
6551
6707
  // src/quirks/litellm.ts
6552
6708
  var import_fs10 = __toESM(require("fs"));
6553
6709
  var import_path10 = require("path");
6554
- var import_build_utils12 = require("@vercel/build-utils");
6710
+ var import_build_utils13 = require("@vercel/build-utils");
6555
6711
  var LAMBDA_ROOT = "/var/task";
6556
6712
  var CONFIG_CANDIDATES = [
6557
6713
  "litellm_config.yaml",
@@ -6586,24 +6742,24 @@ var litellmQuirk = {
6586
6742
  );
6587
6743
  try {
6588
6744
  await import_fs10.default.promises.access(schemaPath);
6589
- (0, import_build_utils12.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
6745
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
6590
6746
  buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
6591
6747
  break;
6592
6748
  } catch {
6593
6749
  }
6594
6750
  }
6595
6751
  if (!buildEnv.PRISMA_SCHEMA_PATH) {
6596
- (0, import_build_utils12.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
6752
+ (0, import_build_utils13.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
6597
6753
  }
6598
6754
  if (!process.env.CONFIG_FILE_PATH) {
6599
6755
  const configName = await findConfigFile(ctx.workPath);
6600
6756
  if (configName) {
6601
- (0, import_build_utils12.debug)(`LiteLLM quirk: found config at ${configName}`);
6757
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found config at ${configName}`);
6602
6758
  buildEnv.CONFIG_FILE_PATH = (0, import_path10.join)(ctx.workPath, configName);
6603
6759
  env.CONFIG_FILE_PATH = (0, import_path10.join)(LAMBDA_ROOT, configName);
6604
6760
  }
6605
6761
  } else {
6606
- (0, import_build_utils12.debug)(
6762
+ (0, import_build_utils13.debug)(
6607
6763
  `LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
6608
6764
  );
6609
6765
  }
@@ -6615,7 +6771,7 @@ var litellmQuirk = {
6615
6771
  var import_fs11 = __toESM(require("fs"));
6616
6772
  var import_path11 = require("path");
6617
6773
  var import_execa5 = __toESM(require_execa());
6618
- var import_build_utils13 = require("@vercel/build-utils");
6774
+ var import_build_utils14 = require("@vercel/build-utils");
6619
6775
  var import_python_analysis7 = require("@vercel/python-analysis");
6620
6776
  function execErrorMessage(err) {
6621
6777
  if (err != null && typeof err === "object" && "stderr" in err) {
@@ -6629,7 +6785,7 @@ var DUMMY_SCHEMA_NAME = "_prisma_dummy.prisma";
6629
6785
  var LAMBDA_ROOT2 = "/var/task";
6630
6786
  var RUNTIME_OPENSSL_VERSION = "3.2";
6631
6787
  function getLambdaBinaryTarget() {
6632
- const platform = detectPlatform();
6788
+ const platform = detectTargetPlatform();
6633
6789
  return platform.archName === "aarch64" ? "linux-arm64-openssl-3.0.x" : "rhel-openssl-3.0.x";
6634
6790
  }
6635
6791
  function buildDummySchema(generatedDir) {
@@ -6658,7 +6814,7 @@ async function findUserSchema(workPath) {
6658
6814
  await import_fs11.default.promises.access(resolved);
6659
6815
  return resolved;
6660
6816
  } catch {
6661
- (0, import_build_utils13.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
6817
+ (0, import_build_utils14.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
6662
6818
  return null;
6663
6819
  }
6664
6820
  }
@@ -6762,7 +6918,7 @@ var prismaQuirk = {
6762
6918
  dummySchemaPath,
6763
6919
  buildDummySchema(generatedDir)
6764
6920
  );
6765
- (0, import_build_utils13.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
6921
+ (0, import_build_utils14.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
6766
6922
  try {
6767
6923
  const dummyResult = await (0, import_execa5.default)(
6768
6924
  pythonPath,
@@ -6774,11 +6930,11 @@ var prismaQuirk = {
6774
6930
  }
6775
6931
  );
6776
6932
  if (dummyResult.stdout)
6777
- (0, import_build_utils13.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
6933
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
6778
6934
  if (dummyResult.stderr)
6779
- (0, import_build_utils13.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
6935
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
6780
6936
  } catch (err) {
6781
- throw new import_build_utils13.NowBuildError({
6937
+ throw new import_build_utils14.NowBuildError({
6782
6938
  code: "PRISMA_GENERATE_FAILED",
6783
6939
  message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
6784
6940
  ` + execErrorMessage(err)
@@ -6797,22 +6953,22 @@ var prismaQuirk = {
6797
6953
  const destPath = (0, import_path11.join)(cacheDir, runtimeName);
6798
6954
  try {
6799
6955
  await import_fs11.default.promises.access(destPath);
6800
- (0, import_build_utils13.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
6956
+ (0, import_build_utils14.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
6801
6957
  } catch {
6802
- (0, import_build_utils13.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
6958
+ (0, import_build_utils14.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
6803
6959
  await import_fs11.default.promises.copyFile(srcPath, destPath);
6804
6960
  }
6805
6961
  engineCopied = true;
6806
6962
  }
6807
6963
  } catch (err) {
6808
- throw new import_build_utils13.NowBuildError({
6964
+ throw new import_build_utils14.NowBuildError({
6809
6965
  code: "PRISMA_ENGINE_NOT_FOUND",
6810
6966
  message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
6811
6967
  ` + (err instanceof Error ? err.message : String(err))
6812
6968
  });
6813
6969
  }
6814
6970
  if (!engineCopied) {
6815
- throw new import_build_utils13.NowBuildError({
6971
+ throw new import_build_utils14.NowBuildError({
6816
6972
  code: "PRISMA_ENGINE_NOT_FOUND",
6817
6973
  message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
6818
6974
  });
@@ -6839,14 +6995,14 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
6839
6995
  pythonEnv
6840
6996
  );
6841
6997
  if (clientAlreadyGenerated) {
6842
- (0, import_build_utils13.debug)(
6998
+ (0, import_build_utils14.debug)(
6843
6999
  "Prisma quirk: client already generated, skipping user schema generate"
6844
7000
  );
6845
7001
  shouldGenerate = false;
6846
7002
  }
6847
7003
  }
6848
7004
  if (shouldGenerate) {
6849
- (0, import_build_utils13.debug)(`Running prisma generate with user schema: ${userSchema}`);
7005
+ (0, import_build_utils14.debug)(`Running prisma generate with user schema: ${userSchema}`);
6850
7006
  try {
6851
7007
  const userResult = await (0, import_execa5.default)(
6852
7008
  pythonPath,
@@ -6858,11 +7014,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
6858
7014
  }
6859
7015
  );
6860
7016
  if (userResult.stdout)
6861
- (0, import_build_utils13.debug)(`prisma generate stdout: ${userResult.stdout}`);
7017
+ (0, import_build_utils14.debug)(`prisma generate stdout: ${userResult.stdout}`);
6862
7018
  if (userResult.stderr)
6863
- (0, import_build_utils13.debug)(`prisma generate stderr: ${userResult.stderr}`);
7019
+ (0, import_build_utils14.debug)(`prisma generate stderr: ${userResult.stderr}`);
6864
7020
  } catch (err) {
6865
- throw new import_build_utils13.NowBuildError({
7021
+ throw new import_build_utils14.NowBuildError({
6866
7022
  code: "PRISMA_GENERATE_FAILED",
6867
7023
  message: `\`prisma generate\` failed for schema "${userSchema}".
6868
7024
  ` + execErrorMessage(err)
@@ -6878,7 +7034,7 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
6878
7034
  );
6879
7035
  const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
6880
7036
  if (count > 0) {
6881
- (0, import_build_utils13.debug)(`Appended ${count} entries to prisma RECORD`);
7037
+ (0, import_build_utils14.debug)(`Appended ${count} entries to prisma RECORD`);
6882
7038
  }
6883
7039
  } catch (err) {
6884
7040
  console.warn(
@@ -6972,13 +7128,13 @@ async function runQuirks(ctx) {
6972
7128
  (0, import_python_analysis8.normalizePackageName)(quirk.dependency)
6973
7129
  );
6974
7130
  if (!installed) {
6975
- (0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
7131
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
6976
7132
  }
6977
7133
  return installed;
6978
7134
  });
6979
7135
  const sorted = toposortQuirks(activated);
6980
7136
  for (const quirk of sorted) {
6981
- (0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
7137
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
6982
7138
  const result = await quirk.run(ctx);
6983
7139
  if (result.env) {
6984
7140
  Object.assign(mergedEnv, result.env);
@@ -7002,7 +7158,7 @@ async function runQuirks(ctx) {
7002
7158
  var import_fs12 = __toESM(require("fs"));
7003
7159
  var import_path12 = require("path");
7004
7160
  var import_execa6 = __toESM(require_execa());
7005
- var import_build_utils15 = require("@vercel/build-utils");
7161
+ var import_build_utils16 = require("@vercel/build-utils");
7006
7162
  var scriptPath2 = (0, import_path12.join)(__dirname, "..", "templates", "vc_django_settings.py");
7007
7163
  var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
7008
7164
  async function getDjangoSettings(projectDir, env) {
@@ -7094,7 +7250,7 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
7094
7250
  await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
7095
7251
  await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
7096
7252
  manifestRelPath = (0, import_path12.relative)(workPath, manifestDest);
7097
- (0, import_build_utils15.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
7253
+ (0, import_build_utils16.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
7098
7254
  }
7099
7255
  return {
7100
7256
  staticSourceDirs,
@@ -7122,7 +7278,7 @@ var frameworkHooks = {
7122
7278
  detected
7123
7279
  }) => {
7124
7280
  if (detected?.baseDir === void 0) {
7125
- (0, import_build_utils16.debug)("Django hook: no manage.py detected, skipping");
7281
+ (0, import_build_utils17.debug)("Django hook: no manage.py detected, skipping");
7126
7282
  return;
7127
7283
  }
7128
7284
  let settingsResult;
@@ -7136,13 +7292,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
7136
7292
  } else {
7137
7293
  detail = err?.stderr || err?.message || String(err);
7138
7294
  }
7139
- throw new import_build_utils16.NowBuildError({
7295
+ throw new import_build_utils17.NowBuildError({
7140
7296
  code: "DJANGO_SETTINGS_FAILED",
7141
7297
  message: `Failed to read Django application settings from ${projectDir}/manage.py:
7142
7298
  ${detail}`
7143
7299
  });
7144
7300
  }
7145
- (0, import_build_utils16.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
7301
+ (0, import_build_utils17.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
7146
7302
  const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
7147
7303
  if (djangoVersion) {
7148
7304
  console.log(`Django ${djangoVersion.join(".")} detected`);
@@ -7155,7 +7311,7 @@ ${detail}`
7155
7311
  const variableName = parts.at(-1);
7156
7312
  const rel = `${parts.slice(0, -1).join("/")}.py`;
7157
7313
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
7158
- (0, import_build_utils16.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
7314
+ (0, import_build_utils17.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
7159
7315
  resolvedEntrypoint = { entrypoint: ep, variableName };
7160
7316
  } else {
7161
7317
  const wsgiApp = djangoSettings["WSGI_APPLICATION"];
@@ -7164,7 +7320,7 @@ ${detail}`
7164
7320
  const variableName = parts.at(-1);
7165
7321
  const rel = `${parts.slice(0, -1).join("/")}.py`;
7166
7322
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
7167
- (0, import_build_utils16.debug)(
7323
+ (0, import_build_utils17.debug)(
7168
7324
  `Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
7169
7325
  );
7170
7326
  resolvedEntrypoint = { entrypoint: ep, variableName };
@@ -7192,12 +7348,12 @@ async function downloadFilesInWorkPath({
7192
7348
  files,
7193
7349
  meta = {}
7194
7350
  }) {
7195
- (0, import_build_utils16.debug)("Downloading user files...");
7196
- let downloadedFiles = await (0, import_build_utils16.download)(files, workPath, meta);
7351
+ (0, import_build_utils17.debug)("Downloading user files...");
7352
+ let downloadedFiles = await (0, import_build_utils17.download)(files, workPath, meta);
7197
7353
  if (meta.isDev && entrypoint) {
7198
7354
  const normalizedEntrypoint = entrypoint.endsWith(".py") ? entrypoint : `${entrypoint}.py`;
7199
7355
  if (!hasProp(downloadedFiles, entrypoint) && !hasProp(downloadedFiles, normalizedEntrypoint)) {
7200
- throw new import_build_utils16.NowBuildError({
7356
+ throw new import_build_utils17.NowBuildError({
7201
7357
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7202
7358
  message: `Configured Python entrypoint "${normalizedEntrypoint}" was not found.`,
7203
7359
  link: PYTHON_ENTRYPOINT_DOCS_URL2,
@@ -7207,12 +7363,31 @@ async function downloadFilesInWorkPath({
7207
7363
  const { devCacheDir = (0, import_path13.join)(workPath, ".now", "cache") } = meta;
7208
7364
  const cacheKey = (0, import_path13.basename)(entrypoint).replace(/\./g, "_");
7209
7365
  const destCache = (0, import_path13.join)(devCacheDir, cacheKey);
7210
- await (0, import_build_utils16.download)(downloadedFiles, destCache);
7211
- downloadedFiles = await (0, import_build_utils16.glob)("**", destCache);
7366
+ await (0, import_build_utils17.download)(downloadedFiles, destCache);
7367
+ downloadedFiles = await (0, import_build_utils17.glob)("**", destCache);
7212
7368
  workPath = destCache;
7213
7369
  }
7214
7370
  return workPath;
7215
7371
  }
7372
+ function archToUvPlatform(arch) {
7373
+ return `${validateBuildArch(arch)}-unknown-linux-gnu`;
7374
+ }
7375
+ function archToLambdaArch(arch) {
7376
+ return validateBuildArch(arch) === "aarch64" ? "arm64" : "x86_64";
7377
+ }
7378
+ function getTargetPlatform(isDev) {
7379
+ const arch = process.env.VERCEL_BUILD_ARCH;
7380
+ if (arch) {
7381
+ return {
7382
+ uvPlatform: archToUvPlatform(arch),
7383
+ architecture: archToLambdaArch(arch)
7384
+ };
7385
+ }
7386
+ if (isDev || process.env.VERCEL_BUILD_IMAGE) {
7387
+ return { uvPlatform: void 0, architecture: void 0 };
7388
+ }
7389
+ return { uvPlatform: UV_LINUX_TARGET, architecture: "x86_64" };
7390
+ }
7216
7391
  var build = async ({
7217
7392
  workPath,
7218
7393
  repoRootPath,
@@ -7221,16 +7396,18 @@ var build = async ({
7221
7396
  meta = {},
7222
7397
  config,
7223
7398
  span: parentSpan,
7224
- service
7399
+ service,
7400
+ registerPreDeploy
7225
7401
  }) => {
7226
7402
  let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
7227
- const builderSpan = parentSpan ?? new import_build_utils16.Span({ name: "vc.builder" });
7403
+ const builderSpan = parentSpan ?? new import_build_utils17.Span({ name: "vc.builder" });
7228
7404
  const framework = config?.framework;
7229
7405
  const shouldInstallVercelWorkers = config?.hasWorkerServices === true;
7230
7406
  let spawnEnv;
7231
7407
  let projectInstallCommand;
7232
7408
  let hasCustomCommand = false;
7233
- (0, import_build_utils16.debug)(`workPath: ${workPath}`);
7409
+ const target = getTargetPlatform(meta.isDev ?? false);
7410
+ (0, import_build_utils17.debug)(`workPath: ${workPath}`);
7234
7411
  workPath = await downloadFilesInWorkPath({
7235
7412
  workPath,
7236
7413
  files: originalFiles,
@@ -7255,7 +7432,7 @@ var build = async ({
7255
7432
  filePath: entrypoint,
7256
7433
  // For schedule-triggered jobs, the WSGI variable is always 'app' (created dynamically).
7257
7434
  // For other services, handlerFunction is used as the entrypoint variable name.
7258
- varName: service && (0, import_build_utils16.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
7435
+ varName: service && (0, import_build_utils17.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
7259
7436
  } : void 0,
7260
7437
  service
7261
7438
  ) ?? void 0;
@@ -7311,7 +7488,7 @@ var build = async ({
7311
7488
  const hasCachedUv = import_fs13.default.existsSync(uvCacheDir);
7312
7489
  const restoredCache = hasCachedVenv && hasCachedUv ? "both" : hasCachedVenv ? "venv" : hasCachedUv ? "uv" : "none";
7313
7490
  if (hasCachedVenv || hasCachedUv) {
7314
- (0, import_build_utils16.debug)(
7491
+ (0, import_build_utils17.debug)(
7315
7492
  `Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
7316
7493
  );
7317
7494
  }
@@ -7323,14 +7500,14 @@ var build = async ({
7323
7500
  uvCacheDir
7324
7501
  });
7325
7502
  });
7326
- if ((0, import_build_utils16.isPythonFramework)(framework)) {
7503
+ if ((0, import_build_utils17.isPythonFramework)(framework)) {
7327
7504
  const {
7328
7505
  cliType,
7329
7506
  lockfileVersion,
7330
7507
  packageJsonPackageManager,
7331
7508
  turboSupportsCorepackHome
7332
- } = await (0, import_build_utils16.scanParentDirs)(workPath, true);
7333
- spawnEnv = (0, import_build_utils16.getEnvForPackageManager)({
7509
+ } = await (0, import_build_utils17.scanParentDirs)(workPath, true);
7510
+ spawnEnv = (0, import_build_utils17.getEnvForPackageManager)({
7334
7511
  cliType,
7335
7512
  lockfileVersion,
7336
7513
  packageJsonPackageManager,
@@ -7355,7 +7532,7 @@ var build = async ({
7355
7532
  let uvLockPath = null;
7356
7533
  let uvProjectDir = null;
7357
7534
  let projectName;
7358
- await builderSpan.child(import_build_utils16.BUILDER_INSTALLER_STEP, {
7535
+ await builderSpan.child(import_build_utils17.BUILDER_INSTALLER_STEP, {
7359
7536
  installCommand: projectInstallCommand || void 0,
7360
7537
  runtime: "python",
7361
7538
  "python.cache.restored": restoredCache
@@ -7372,7 +7549,7 @@ var build = async ({
7372
7549
  console.log(
7373
7550
  `Running "install" command: \`${projectInstallCommand}\`...`
7374
7551
  );
7375
- await (0, import_build_utils16.execCommand)(projectInstallCommand, {
7552
+ await (0, import_build_utils17.execCommand)(projectInstallCommand, {
7376
7553
  env: pythonEnv,
7377
7554
  cwd: workPath
7378
7555
  });
@@ -7411,7 +7588,8 @@ var build = async ({
7411
7588
  venvPath,
7412
7589
  projectDir,
7413
7590
  frozen: lockFileProvidedByUser,
7414
- locked: !lockFileProvidedByUser
7591
+ locked: !lockFileProvidedByUser,
7592
+ pythonPlatform: target.uvPlatform
7415
7593
  });
7416
7594
  if (lockPath && import_fs13.default.existsSync(lockPath)) {
7417
7595
  await import_fs13.default.promises.mkdir(uvCacheDir, { recursive: true });
@@ -7419,15 +7597,15 @@ var build = async ({
7419
7597
  }
7420
7598
  }
7421
7599
  });
7422
- if ((0, import_build_utils16.isPythonFramework)(framework)) {
7600
+ if ((0, import_build_utils17.isPythonFramework)(framework)) {
7423
7601
  const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
7424
7602
  config?.buildCommand;
7425
- await builderSpan.child(import_build_utils16.BUILDER_COMPILE_STEP, {
7603
+ await builderSpan.child(import_build_utils17.BUILDER_COMPILE_STEP, {
7426
7604
  buildCommand: projectBuildCommand || void 0
7427
7605
  }).trace(async () => {
7428
7606
  if (projectBuildCommand) {
7429
7607
  console.log(`Running "${projectBuildCommand}"`);
7430
- await (0, import_build_utils16.execCommand)(projectBuildCommand, {
7608
+ await (0, import_build_utils17.execCommand)(projectBuildCommand, {
7431
7609
  env: pythonEnv,
7432
7610
  cwd: workPath
7433
7611
  });
@@ -7454,40 +7632,57 @@ var build = async ({
7454
7632
  }
7455
7633
  entrypoint = resolved?.entrypoint;
7456
7634
  if (!entrypoint) {
7457
- throw new import_build_utils16.NowBuildError({
7635
+ throw new import_build_utils17.NowBuildError({
7458
7636
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7459
7637
  message: "No Python entrypoint could be detected. Please specify an entrypoint file."
7460
7638
  });
7461
7639
  }
7462
7640
  const djangoStatic = hookResult?.djangoStatic ?? null;
7463
7641
  const runtimeDep = baseEnv.VERCEL_RUNTIME_PYTHON || `vercel-runtime==${VERCEL_RUNTIME_VERSION}`;
7464
- (0, import_build_utils16.debug)(`Installing ${runtimeDep}`);
7642
+ (0, import_build_utils17.debug)(`Installing ${runtimeDep}`);
7643
+ const pipPlatformArgs = target.uvPlatform ? ["--python-platform", target.uvPlatform] : [];
7465
7644
  await uv.pip({
7466
7645
  venvPath,
7467
7646
  projectDir: (0, import_path13.join)(workPath, entryDirectory),
7468
- args: ["install", "--link-mode", "copy", runtimeDep]
7647
+ args: ["install", "--link-mode", "copy", ...pipPlatformArgs, runtimeDep]
7469
7648
  });
7470
7649
  if (shouldInstallVercelWorkers) {
7471
7650
  const workersDep = baseEnv.VERCEL_WORKERS_PYTHON || `vercel-workers==${VERCEL_WORKERS_VERSION}`;
7472
- (0, import_build_utils16.debug)(`Installing ${workersDep}`);
7651
+ (0, import_build_utils17.debug)(`Installing ${workersDep}`);
7473
7652
  await uv.pip({
7474
7653
  venvPath,
7475
7654
  projectDir: (0, import_path13.join)(workPath, entryDirectory),
7476
- args: ["install", "--link-mode", "copy", workersDep]
7655
+ args: ["install", "--link-mode", "copy", ...pipPlatformArgs, workersDep]
7477
7656
  });
7478
7657
  }
7479
7658
  const quirksResult = await runQuirks({ venvPath, pythonEnv, workPath });
7480
7659
  if (quirksResult.buildEnv) {
7481
7660
  Object.assign(pythonEnv, quirksResult.buildEnv);
7482
7661
  }
7483
- (0, import_build_utils16.debug)("Entrypoint is", entrypoint);
7662
+ const preDeployCommand = config?.preDeployCommand;
7663
+ if (registerPreDeploy && typeof preDeployCommand === "string") {
7664
+ const capturedEnv = { ...pythonEnv };
7665
+ const capturedCwd = workPath;
7666
+ registerPreDeploy(async () => {
7667
+ await builderSpan.child(import_build_utils17.BUILDER_PRE_DEPLOY_STEP, {
7668
+ preDeployCommand
7669
+ }).trace(async () => {
7670
+ console.log(`Running pre-deploy command: \`${preDeployCommand}\``);
7671
+ await (0, import_build_utils17.execCommand)(preDeployCommand, {
7672
+ env: capturedEnv,
7673
+ cwd: capturedCwd
7674
+ });
7675
+ });
7676
+ });
7677
+ }
7678
+ (0, import_build_utils17.debug)("Entrypoint is", entrypoint);
7484
7679
  const moduleName = entrypointToModule(entrypoint);
7485
7680
  if (handlerFunction) {
7486
7681
  const entrypointPath = (0, import_path13.join)(workPath, entrypoint);
7487
7682
  const source = await import_fs13.default.promises.readFile(entrypointPath, "utf-8");
7488
7683
  const found = await (0, import_python_analysis9.containsTopLevelCallable)(source, handlerFunction);
7489
7684
  if (!found) {
7490
- throw new import_build_utils16.NowBuildError({
7685
+ throw new import_build_utils17.NowBuildError({
7491
7686
  code: "PYTHON_HANDLER_NOT_FOUND",
7492
7687
  message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
7493
7688
  });
@@ -7496,7 +7691,7 @@ var build = async ({
7496
7691
  const vendorDir = resolveVendorDir();
7497
7692
  const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
7498
7693
  const entrypointWithSuffix = `${entrypoint}${suffix}`;
7499
- (0, import_build_utils16.debug)("Entrypoint with suffix is", entrypointWithSuffix);
7694
+ (0, import_build_utils17.debug)("Entrypoint with suffix is", entrypointWithSuffix);
7500
7695
  const crons = await getServiceCrons({
7501
7696
  service,
7502
7697
  entrypoint,
@@ -7581,9 +7776,9 @@ from vercel_runtime.vc_init import vc_handler
7581
7776
  cwd: workPath,
7582
7777
  ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
7583
7778
  };
7584
- const files = await (0, import_build_utils16.glob)("**", globOptions);
7779
+ const files = await (0, import_build_utils17.glob)("**", globOptions);
7585
7780
  if (djangoStatic?.manifestRelPath) {
7586
- files[djangoStatic.manifestRelPath] = new import_build_utils16.FileFsRef({
7781
+ files[djangoStatic.manifestRelPath] = new import_build_utils17.FileFsRef({
7587
7782
  fsPath: (0, import_path13.join)(workPath, djangoStatic.manifestRelPath)
7588
7783
  });
7589
7784
  }
@@ -7620,15 +7815,16 @@ from vercel_runtime.vc_init import vc_handler
7620
7815
  }
7621
7816
  });
7622
7817
  const handlerPyFilename = "vc__handler__python";
7623
- files[`${handlerPyFilename}.py`] = new import_build_utils16.FileBlob({ data: runtimeTrampoline });
7818
+ files[`${handlerPyFilename}.py`] = new import_build_utils17.FileBlob({ data: runtimeTrampoline });
7624
7819
  if (config.framework === "fasthtml") {
7625
7820
  const { SESSKEY = "" } = process.env;
7626
- files[".sesskey"] = new import_build_utils16.FileBlob({ data: `"${SESSKEY}"` });
7821
+ files[".sesskey"] = new import_build_utils17.FileBlob({ data: `"${SESSKEY}"` });
7627
7822
  }
7628
- const output = new import_build_utils16.Lambda({
7823
+ const output = new import_build_utils17.Lambda({
7629
7824
  files,
7630
7825
  handler: `${handlerPyFilename}.vc_handler`,
7631
7826
  runtime: pythonVersion.runtime,
7827
+ architecture: target.architecture,
7632
7828
  environment: lambdaEnv,
7633
7829
  supportsResponseStreaming: true
7634
7830
  });
@@ -7640,19 +7836,19 @@ from vercel_runtime.vc_init import vc_handler
7640
7836
  pythonVersion,
7641
7837
  uvLockPath,
7642
7838
  framework,
7643
- serviceType: service ? (0, import_build_utils16.getReportedServiceType)(service) : void 0
7839
+ serviceType: service ? (0, import_build_utils17.getReportedServiceType)(service) : void 0
7644
7840
  });
7645
7841
  } catch (err) {
7646
- (0, import_build_utils16.debug)(
7842
+ (0, import_build_utils17.debug)(
7647
7843
  `Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
7648
7844
  );
7649
7845
  }
7650
7846
  }
7651
- if (!(0, import_build_utils16.isPythonFramework)(framework) && !service?.name) {
7847
+ if (!(0, import_build_utils17.isPythonFramework)(framework) && !service?.name) {
7652
7848
  return { resultVersion: 3, result: { output } };
7653
7849
  }
7654
7850
  const lambdaPath = service?.name ? `_svc/${service.name}/index` : "index";
7655
- const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils16.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
7851
+ const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils17.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
7656
7852
  const routes = service?.name ? void 0 : [{ handle: "filesystem" }, { src: "/(.*)", dest: `/${lambdaPath}` }];
7657
7853
  return {
7658
7854
  resultVersion: 2,
@@ -7681,14 +7877,14 @@ var prepareCache = async ({
7681
7877
  }
7682
7878
  } catch {
7683
7879
  }
7684
- return (0, import_build_utils16.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
7880
+ return (0, import_build_utils17.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
7685
7881
  cwd: root,
7686
7882
  ignore
7687
7883
  });
7688
7884
  };
7689
7885
  var shouldServe = (opts) => {
7690
7886
  const framework = opts.config.framework;
7691
- if ((0, import_build_utils16.isPythonFramework)(framework)) {
7887
+ if ((0, import_build_utils17.isPythonFramework)(framework)) {
7692
7888
  const requestPath = opts.requestPath.replace(/\/$/, "");
7693
7889
  if (requestPath.startsWith("api") && opts.hasMatched) {
7694
7890
  return false;
@@ -7720,6 +7916,7 @@ function hasProp(obj, key) {
7720
7916
  0 && (module.exports = {
7721
7917
  build,
7722
7918
  defaultShouldServe,
7919
+ detectEntrypoint,
7723
7920
  diagnostics,
7724
7921
  downloadFilesInWorkPath,
7725
7922
  installRequirement,