@vercel/python 6.51.0 → 6.52.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.
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var require_windows = __commonJS({
48
48
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module2) {
49
49
  module2.exports = isexe;
50
50
  isexe.sync = sync;
51
- var fs16 = require("fs");
51
+ var fs18 = require("fs");
52
52
  function checkPathExt(path, options) {
53
53
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
54
54
  if (!pathext) {
@@ -73,12 +73,12 @@ var require_windows = __commonJS({
73
73
  return checkPathExt(path, options);
74
74
  }
75
75
  function isexe(path, options, cb) {
76
- fs16.stat(path, function(er, stat) {
76
+ fs18.stat(path, function(er, stat) {
77
77
  cb(er, er ? false : checkStat(stat, path, options));
78
78
  });
79
79
  }
80
80
  function sync(path, options) {
81
- return checkStat(fs16.statSync(path), path, options);
81
+ return checkStat(fs18.statSync(path), path, options);
82
82
  }
83
83
  }
84
84
  });
@@ -88,14 +88,14 @@ var require_mode = __commonJS({
88
88
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module2) {
89
89
  module2.exports = isexe;
90
90
  isexe.sync = sync;
91
- var fs16 = require("fs");
91
+ var fs18 = require("fs");
92
92
  function isexe(path, options, cb) {
93
- fs16.stat(path, function(er, stat) {
93
+ fs18.stat(path, function(er, stat) {
94
94
  cb(er, er ? false : checkStat(stat, options));
95
95
  });
96
96
  }
97
97
  function sync(path, options) {
98
- return checkStat(fs16.statSync(path), options);
98
+ return checkStat(fs18.statSync(path), options);
99
99
  }
100
100
  function checkStat(stat, options) {
101
101
  return stat.isFile() && checkMode(stat, options);
@@ -119,7 +119,7 @@ var require_mode = __commonJS({
119
119
  // ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
120
120
  var require_isexe = __commonJS({
121
121
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module2) {
122
- var fs16 = require("fs");
122
+ var fs18 = require("fs");
123
123
  var core;
124
124
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
125
125
  core = require_windows();
@@ -395,7 +395,7 @@ var require_shebang_command = __commonJS({
395
395
  var require_readShebang = __commonJS({
396
396
  "../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module2) {
397
397
  "use strict";
398
- var fs16 = require("fs");
398
+ var fs18 = require("fs");
399
399
  var shebangCommand = require_shebang_command();
400
400
  function readShebang(command) {
401
401
  const size = 150;
@@ -408,9 +408,9 @@ var require_readShebang = __commonJS({
408
408
  }
409
409
  let fd;
410
410
  try {
411
- fd = fs16.openSync(command, "r");
412
- fs16.readSync(fd, buffer, 0, size, 0);
413
- fs16.closeSync(fd);
411
+ fd = fs18.openSync(command, "r");
412
+ fs18.readSync(fd, buffer, 0, size, 0);
413
+ fs18.closeSync(fd);
414
414
  } catch (e) {
415
415
  }
416
416
  return shebangCommand(buffer.toString());
@@ -423,15 +423,15 @@ var require_readShebang = __commonJS({
423
423
  var require_semver = __commonJS({
424
424
  "../../node_modules/.pnpm/semver@5.7.2/node_modules/semver/semver.js"(exports, module2) {
425
425
  exports = module2.exports = SemVer;
426
- var debug13;
426
+ var debug15;
427
427
  if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
428
- debug13 = function() {
428
+ debug15 = function() {
429
429
  var args = Array.prototype.slice.call(arguments, 0);
430
430
  args.unshift("SEMVER");
431
431
  console.log.apply(console, args);
432
432
  };
433
433
  } else {
434
- debug13 = function() {
434
+ debug15 = function() {
435
435
  };
436
436
  }
437
437
  exports.SEMVER_SPEC_VERSION = "2.0.0";
@@ -540,7 +540,7 @@ var require_semver = __commonJS({
540
540
  var STAR = R++;
541
541
  src[STAR] = "(<|>)?=?\\s*\\*";
542
542
  for (i = 0; i < R; i++) {
543
- debug13(i, src[i]);
543
+ debug15(i, src[i]);
544
544
  if (!re[i]) {
545
545
  re[i] = new RegExp(src[i]);
546
546
  safeRe[i] = new RegExp(makeSafeRe(src[i]));
@@ -607,7 +607,7 @@ var require_semver = __commonJS({
607
607
  if (!(this instanceof SemVer)) {
608
608
  return new SemVer(version2, options);
609
609
  }
610
- debug13("SemVer", version2, options);
610
+ debug15("SemVer", version2, options);
611
611
  this.options = options;
612
612
  this.loose = !!options.loose;
613
613
  var m = version2.trim().match(options.loose ? safeRe[LOOSE] : safeRe[FULL]);
@@ -654,7 +654,7 @@ var require_semver = __commonJS({
654
654
  return this.version;
655
655
  };
656
656
  SemVer.prototype.compare = function(other) {
657
- debug13("SemVer.compare", this.version, this.options, other);
657
+ debug15("SemVer.compare", this.version, this.options, other);
658
658
  if (!(other instanceof SemVer)) {
659
659
  other = new SemVer(other, this.options);
660
660
  }
@@ -681,7 +681,7 @@ var require_semver = __commonJS({
681
681
  do {
682
682
  var a = this.prerelease[i2];
683
683
  var b = other.prerelease[i2];
684
- debug13("prerelease compare", i2, a, b);
684
+ debug15("prerelease compare", i2, a, b);
685
685
  if (a === void 0 && b === void 0) {
686
686
  return 0;
687
687
  } else if (b === void 0) {
@@ -935,7 +935,7 @@ var require_semver = __commonJS({
935
935
  return new Comparator(comp, options);
936
936
  }
937
937
  comp = comp.trim().split(/\s+/).join(" ");
938
- debug13("comparator", comp, options);
938
+ debug15("comparator", comp, options);
939
939
  this.options = options;
940
940
  this.loose = !!options.loose;
941
941
  this.parse(comp);
@@ -944,7 +944,7 @@ var require_semver = __commonJS({
944
944
  } else {
945
945
  this.value = this.operator + this.semver.version;
946
946
  }
947
- debug13("comp", this);
947
+ debug15("comp", this);
948
948
  }
949
949
  var ANY = {};
950
950
  Comparator.prototype.parse = function(comp) {
@@ -967,7 +967,7 @@ var require_semver = __commonJS({
967
967
  return this.value;
968
968
  };
969
969
  Comparator.prototype.test = function(version2) {
970
- debug13("Comparator.test", version2, this.options.loose);
970
+ debug15("Comparator.test", version2, this.options.loose);
971
971
  if (this.semver === ANY) {
972
972
  return true;
973
973
  }
@@ -1050,9 +1050,9 @@ var require_semver = __commonJS({
1050
1050
  var loose = this.options.loose;
1051
1051
  var hr = loose ? safeRe[HYPHENRANGELOOSE] : safeRe[HYPHENRANGE];
1052
1052
  range = range.replace(hr, hyphenReplace);
1053
- debug13("hyphen replace", range);
1053
+ debug15("hyphen replace", range);
1054
1054
  range = range.replace(safeRe[COMPARATORTRIM], comparatorTrimReplace);
1055
- debug13("comparator trim", range, safeRe[COMPARATORTRIM]);
1055
+ debug15("comparator trim", range, safeRe[COMPARATORTRIM]);
1056
1056
  range = range.replace(safeRe[TILDETRIM], tildeTrimReplace);
1057
1057
  range = range.replace(safeRe[CARETTRIM], caretTrimReplace);
1058
1058
  var compRe = loose ? safeRe[COMPARATORLOOSE] : safeRe[COMPARATOR];
@@ -1092,15 +1092,15 @@ var require_semver = __commonJS({
1092
1092
  });
1093
1093
  }
1094
1094
  function parseComparator(comp, options) {
1095
- debug13("comp", comp, options);
1095
+ debug15("comp", comp, options);
1096
1096
  comp = replaceCarets(comp, options);
1097
- debug13("caret", comp);
1097
+ debug15("caret", comp);
1098
1098
  comp = replaceTildes(comp, options);
1099
- debug13("tildes", comp);
1099
+ debug15("tildes", comp);
1100
1100
  comp = replaceXRanges(comp, options);
1101
- debug13("xrange", comp);
1101
+ debug15("xrange", comp);
1102
1102
  comp = replaceStars(comp, options);
1103
- debug13("stars", comp);
1103
+ debug15("stars", comp);
1104
1104
  return comp;
1105
1105
  }
1106
1106
  function isX(id) {
@@ -1114,7 +1114,7 @@ var require_semver = __commonJS({
1114
1114
  function replaceTilde(comp, options) {
1115
1115
  var r = options.loose ? safeRe[TILDELOOSE] : safeRe[TILDE];
1116
1116
  return comp.replace(r, function(_, M, m, p, pr) {
1117
- debug13("tilde", comp, _, M, m, p, pr);
1117
+ debug15("tilde", comp, _, M, m, p, pr);
1118
1118
  var ret;
1119
1119
  if (isX(M)) {
1120
1120
  ret = "";
@@ -1123,12 +1123,12 @@ var require_semver = __commonJS({
1123
1123
  } else if (isX(p)) {
1124
1124
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
1125
1125
  } else if (pr) {
1126
- debug13("replaceTilde pr", pr);
1126
+ debug15("replaceTilde pr", pr);
1127
1127
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + (+m + 1) + ".0";
1128
1128
  } else {
1129
1129
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + (+m + 1) + ".0";
1130
1130
  }
1131
- debug13("tilde return", ret);
1131
+ debug15("tilde return", ret);
1132
1132
  return ret;
1133
1133
  });
1134
1134
  }
@@ -1138,10 +1138,10 @@ var require_semver = __commonJS({
1138
1138
  }).join(" ");
1139
1139
  }
1140
1140
  function replaceCaret(comp, options) {
1141
- debug13("caret", comp, options);
1141
+ debug15("caret", comp, options);
1142
1142
  var r = options.loose ? safeRe[CARETLOOSE] : safeRe[CARET];
1143
1143
  return comp.replace(r, function(_, M, m, p, pr) {
1144
- debug13("caret", comp, _, M, m, p, pr);
1144
+ debug15("caret", comp, _, M, m, p, pr);
1145
1145
  var ret;
1146
1146
  if (isX(M)) {
1147
1147
  ret = "";
@@ -1154,7 +1154,7 @@ var require_semver = __commonJS({
1154
1154
  ret = ">=" + M + "." + m + ".0 <" + (+M + 1) + ".0.0";
1155
1155
  }
1156
1156
  } else if (pr) {
1157
- debug13("replaceCaret pr", pr);
1157
+ debug15("replaceCaret pr", pr);
1158
1158
  if (M === "0") {
1159
1159
  if (m === "0") {
1160
1160
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + m + "." + (+p + 1);
@@ -1165,7 +1165,7 @@ var require_semver = __commonJS({
1165
1165
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
1166
1166
  }
1167
1167
  } else {
1168
- debug13("no pr");
1168
+ debug15("no pr");
1169
1169
  if (M === "0") {
1170
1170
  if (m === "0") {
1171
1171
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + m + "." + (+p + 1);
@@ -1176,12 +1176,12 @@ var require_semver = __commonJS({
1176
1176
  ret = ">=" + M + "." + m + "." + p + " <" + (+M + 1) + ".0.0";
1177
1177
  }
1178
1178
  }
1179
- debug13("caret return", ret);
1179
+ debug15("caret return", ret);
1180
1180
  return ret;
1181
1181
  });
1182
1182
  }
1183
1183
  function replaceXRanges(comp, options) {
1184
- debug13("replaceXRanges", comp, options);
1184
+ debug15("replaceXRanges", comp, options);
1185
1185
  return comp.split(/\s+/).map(function(comp2) {
1186
1186
  return replaceXRange(comp2, options);
1187
1187
  }).join(" ");
@@ -1190,7 +1190,7 @@ var require_semver = __commonJS({
1190
1190
  comp = comp.trim();
1191
1191
  var r = options.loose ? safeRe[XRANGELOOSE] : safeRe[XRANGE];
1192
1192
  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
1193
- debug13("xRange", comp, ret, gtlt, M, m, p, pr);
1193
+ debug15("xRange", comp, ret, gtlt, M, m, p, pr);
1194
1194
  var xM = isX(M);
1195
1195
  var xm = xM || isX(m);
1196
1196
  var xp = xm || isX(p);
@@ -1233,12 +1233,12 @@ var require_semver = __commonJS({
1233
1233
  } else if (xp) {
1234
1234
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
1235
1235
  }
1236
- debug13("xRange return", ret);
1236
+ debug15("xRange return", ret);
1237
1237
  return ret;
1238
1238
  });
1239
1239
  }
1240
1240
  function replaceStars(comp, options) {
1241
- debug13("replaceStars", comp, options);
1241
+ debug15("replaceStars", comp, options);
1242
1242
  return comp.trim().replace(safeRe[STAR], "");
1243
1243
  }
1244
1244
  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
@@ -1286,7 +1286,7 @@ var require_semver = __commonJS({
1286
1286
  }
1287
1287
  if (version2.prerelease.length && !options.includePrerelease) {
1288
1288
  for (i2 = 0; i2 < set.length; i2++) {
1289
- debug13(set[i2].semver);
1289
+ debug15(set[i2].semver);
1290
1290
  if (set[i2].semver === ANY) {
1291
1291
  continue;
1292
1292
  }
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
1895
1895
  "../../node_modules/.pnpm/pump@3.0.4/node_modules/pump/index.js"(exports, module2) {
1896
1896
  var once = require_once();
1897
1897
  var eos = require_end_of_stream();
1898
- var fs16;
1898
+ var fs18;
1899
1899
  try {
1900
- fs16 = require("fs");
1900
+ fs18 = require("fs");
1901
1901
  } catch (e) {
1902
1902
  }
1903
1903
  var noop = function() {
@@ -1909,9 +1909,9 @@ var require_pump = __commonJS({
1909
1909
  var isFS = function(stream) {
1910
1910
  if (!ancient)
1911
1911
  return false;
1912
- if (!fs16)
1912
+ if (!fs18)
1913
1913
  return false;
1914
- return (stream instanceof (fs16.ReadStream || noop) || stream instanceof (fs16.WriteStream || noop)) && isFn(stream.close);
1914
+ return (stream instanceof (fs18.ReadStream || noop) || stream instanceof (fs18.WriteStream || noop)) && isFn(stream.close);
1915
1915
  };
1916
1916
  var isRequest = function(stream) {
1917
1917
  return stream.setHeader && isFn(stream.abort);
@@ -2651,7 +2651,7 @@ ${stderr}${stdout}`;
2651
2651
  var require_lib = __commonJS({
2652
2652
  "../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
2653
2653
  var isexe = require_isexe();
2654
- var { join: join17, delimiter: delimiter2, sep: sep3, posix } = require("path");
2654
+ var { join: join19, delimiter: delimiter2, sep: sep3, posix } = require("path");
2655
2655
  var isWindows = process.platform === "win32";
2656
2656
  var rSlash = new RegExp(`[${posix.sep}${sep3 === posix.sep ? "" : sep3}]`.replace(/(\\)/g, "\\$1"));
2657
2657
  var rRel = new RegExp(`^\\.${rSlash.source}`);
@@ -2680,7 +2680,7 @@ var require_lib = __commonJS({
2680
2680
  var getPathPart = (raw, cmd) => {
2681
2681
  const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
2682
2682
  const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
2683
- return prefix + join17(pathPart, cmd);
2683
+ return prefix + join19(pathPart, cmd);
2684
2684
  };
2685
2685
  var which2 = async (cmd, opt = {}) => {
2686
2686
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
@@ -2739,15 +2739,15 @@ var require_lib = __commonJS({
2739
2739
  var require_semver2 = __commonJS({
2740
2740
  "../../node_modules/.pnpm/semver@6.3.1/node_modules/semver/semver.js"(exports, module2) {
2741
2741
  exports = module2.exports = SemVer;
2742
- var debug13;
2742
+ var debug15;
2743
2743
  if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
2744
- debug13 = function() {
2744
+ debug15 = function() {
2745
2745
  var args = Array.prototype.slice.call(arguments, 0);
2746
2746
  args.unshift("SEMVER");
2747
2747
  console.log.apply(console, args);
2748
2748
  };
2749
2749
  } else {
2750
- debug13 = function() {
2750
+ debug15 = function() {
2751
2751
  };
2752
2752
  }
2753
2753
  exports.SEMVER_SPEC_VERSION = "2.0.0";
@@ -2865,7 +2865,7 @@ var require_semver2 = __commonJS({
2865
2865
  tok("STAR");
2866
2866
  src[t.STAR] = "(<|>)?=?\\s*\\*";
2867
2867
  for (i = 0; i < R; i++) {
2868
- debug13(i, src[i]);
2868
+ debug15(i, src[i]);
2869
2869
  if (!re[i]) {
2870
2870
  re[i] = new RegExp(src[i]);
2871
2871
  safeRe[i] = new RegExp(makeSafeRe(src[i]));
@@ -2932,7 +2932,7 @@ var require_semver2 = __commonJS({
2932
2932
  if (!(this instanceof SemVer)) {
2933
2933
  return new SemVer(version2, options);
2934
2934
  }
2935
- debug13("SemVer", version2, options);
2935
+ debug15("SemVer", version2, options);
2936
2936
  this.options = options;
2937
2937
  this.loose = !!options.loose;
2938
2938
  var m = version2.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]);
@@ -2979,7 +2979,7 @@ var require_semver2 = __commonJS({
2979
2979
  return this.version;
2980
2980
  };
2981
2981
  SemVer.prototype.compare = function(other) {
2982
- debug13("SemVer.compare", this.version, this.options, other);
2982
+ debug15("SemVer.compare", this.version, this.options, other);
2983
2983
  if (!(other instanceof SemVer)) {
2984
2984
  other = new SemVer(other, this.options);
2985
2985
  }
@@ -3006,7 +3006,7 @@ var require_semver2 = __commonJS({
3006
3006
  do {
3007
3007
  var a = this.prerelease[i2];
3008
3008
  var b = other.prerelease[i2];
3009
- debug13("prerelease compare", i2, a, b);
3009
+ debug15("prerelease compare", i2, a, b);
3010
3010
  if (a === void 0 && b === void 0) {
3011
3011
  return 0;
3012
3012
  } else if (b === void 0) {
@@ -3028,7 +3028,7 @@ var require_semver2 = __commonJS({
3028
3028
  do {
3029
3029
  var a = this.build[i2];
3030
3030
  var b = other.build[i2];
3031
- debug13("prerelease compare", i2, a, b);
3031
+ debug15("prerelease compare", i2, a, b);
3032
3032
  if (a === void 0 && b === void 0) {
3033
3033
  return 0;
3034
3034
  } else if (b === void 0) {
@@ -3288,7 +3288,7 @@ var require_semver2 = __commonJS({
3288
3288
  return new Comparator(comp, options);
3289
3289
  }
3290
3290
  comp = comp.trim().split(/\s+/).join(" ");
3291
- debug13("comparator", comp, options);
3291
+ debug15("comparator", comp, options);
3292
3292
  this.options = options;
3293
3293
  this.loose = !!options.loose;
3294
3294
  this.parse(comp);
@@ -3297,7 +3297,7 @@ var require_semver2 = __commonJS({
3297
3297
  } else {
3298
3298
  this.value = this.operator + this.semver.version;
3299
3299
  }
3300
- debug13("comp", this);
3300
+ debug15("comp", this);
3301
3301
  }
3302
3302
  var ANY = {};
3303
3303
  Comparator.prototype.parse = function(comp) {
@@ -3320,7 +3320,7 @@ var require_semver2 = __commonJS({
3320
3320
  return this.value;
3321
3321
  };
3322
3322
  Comparator.prototype.test = function(version2) {
3323
- debug13("Comparator.test", version2, this.options.loose);
3323
+ debug15("Comparator.test", version2, this.options.loose);
3324
3324
  if (this.semver === ANY || version2 === ANY) {
3325
3325
  return true;
3326
3326
  }
@@ -3413,9 +3413,9 @@ var require_semver2 = __commonJS({
3413
3413
  var loose = this.options.loose;
3414
3414
  var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE];
3415
3415
  range = range.replace(hr, hyphenReplace);
3416
- debug13("hyphen replace", range);
3416
+ debug15("hyphen replace", range);
3417
3417
  range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace);
3418
- debug13("comparator trim", range, safeRe[t.COMPARATORTRIM]);
3418
+ debug15("comparator trim", range, safeRe[t.COMPARATORTRIM]);
3419
3419
  range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace);
3420
3420
  range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace);
3421
3421
  range = range.split(/\s+/).join(" ");
@@ -3468,15 +3468,15 @@ var require_semver2 = __commonJS({
3468
3468
  });
3469
3469
  }
3470
3470
  function parseComparator(comp, options) {
3471
- debug13("comp", comp, options);
3471
+ debug15("comp", comp, options);
3472
3472
  comp = replaceCarets(comp, options);
3473
- debug13("caret", comp);
3473
+ debug15("caret", comp);
3474
3474
  comp = replaceTildes(comp, options);
3475
- debug13("tildes", comp);
3475
+ debug15("tildes", comp);
3476
3476
  comp = replaceXRanges(comp, options);
3477
- debug13("xrange", comp);
3477
+ debug15("xrange", comp);
3478
3478
  comp = replaceStars(comp, options);
3479
- debug13("stars", comp);
3479
+ debug15("stars", comp);
3480
3480
  return comp;
3481
3481
  }
3482
3482
  function isX(id) {
@@ -3490,7 +3490,7 @@ var require_semver2 = __commonJS({
3490
3490
  function replaceTilde(comp, options) {
3491
3491
  var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE];
3492
3492
  return comp.replace(r, function(_, M, m, p, pr) {
3493
- debug13("tilde", comp, _, M, m, p, pr);
3493
+ debug15("tilde", comp, _, M, m, p, pr);
3494
3494
  var ret;
3495
3495
  if (isX(M)) {
3496
3496
  ret = "";
@@ -3499,12 +3499,12 @@ var require_semver2 = __commonJS({
3499
3499
  } else if (isX(p)) {
3500
3500
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
3501
3501
  } else if (pr) {
3502
- debug13("replaceTilde pr", pr);
3502
+ debug15("replaceTilde pr", pr);
3503
3503
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + (+m + 1) + ".0";
3504
3504
  } else {
3505
3505
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + (+m + 1) + ".0";
3506
3506
  }
3507
- debug13("tilde return", ret);
3507
+ debug15("tilde return", ret);
3508
3508
  return ret;
3509
3509
  });
3510
3510
  }
@@ -3514,10 +3514,10 @@ var require_semver2 = __commonJS({
3514
3514
  }).join(" ");
3515
3515
  }
3516
3516
  function replaceCaret(comp, options) {
3517
- debug13("caret", comp, options);
3517
+ debug15("caret", comp, options);
3518
3518
  var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET];
3519
3519
  return comp.replace(r, function(_, M, m, p, pr) {
3520
- debug13("caret", comp, _, M, m, p, pr);
3520
+ debug15("caret", comp, _, M, m, p, pr);
3521
3521
  var ret;
3522
3522
  if (isX(M)) {
3523
3523
  ret = "";
@@ -3530,7 +3530,7 @@ var require_semver2 = __commonJS({
3530
3530
  ret = ">=" + M + "." + m + ".0 <" + (+M + 1) + ".0.0";
3531
3531
  }
3532
3532
  } else if (pr) {
3533
- debug13("replaceCaret pr", pr);
3533
+ debug15("replaceCaret pr", pr);
3534
3534
  if (M === "0") {
3535
3535
  if (m === "0") {
3536
3536
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + m + "." + (+p + 1);
@@ -3541,7 +3541,7 @@ var require_semver2 = __commonJS({
3541
3541
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
3542
3542
  }
3543
3543
  } else {
3544
- debug13("no pr");
3544
+ debug15("no pr");
3545
3545
  if (M === "0") {
3546
3546
  if (m === "0") {
3547
3547
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + m + "." + (+p + 1);
@@ -3552,12 +3552,12 @@ var require_semver2 = __commonJS({
3552
3552
  ret = ">=" + M + "." + m + "." + p + " <" + (+M + 1) + ".0.0";
3553
3553
  }
3554
3554
  }
3555
- debug13("caret return", ret);
3555
+ debug15("caret return", ret);
3556
3556
  return ret;
3557
3557
  });
3558
3558
  }
3559
3559
  function replaceXRanges(comp, options) {
3560
- debug13("replaceXRanges", comp, options);
3560
+ debug15("replaceXRanges", comp, options);
3561
3561
  return comp.split(/\s+/).map(function(comp2) {
3562
3562
  return replaceXRange(comp2, options);
3563
3563
  }).join(" ");
@@ -3566,7 +3566,7 @@ var require_semver2 = __commonJS({
3566
3566
  comp = comp.trim();
3567
3567
  var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE];
3568
3568
  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
3569
- debug13("xRange", comp, ret, gtlt, M, m, p, pr);
3569
+ debug15("xRange", comp, ret, gtlt, M, m, p, pr);
3570
3570
  var xM = isX(M);
3571
3571
  var xm = xM || isX(m);
3572
3572
  var xp = xm || isX(p);
@@ -3610,12 +3610,12 @@ var require_semver2 = __commonJS({
3610
3610
  } else if (xp) {
3611
3611
  ret = ">=" + M + "." + m + ".0" + pr + " <" + M + "." + (+m + 1) + ".0" + pr;
3612
3612
  }
3613
- debug13("xRange return", ret);
3613
+ debug15("xRange return", ret);
3614
3614
  return ret;
3615
3615
  });
3616
3616
  }
3617
3617
  function replaceStars(comp, options) {
3618
- debug13("replaceStars", comp, options);
3618
+ debug15("replaceStars", comp, options);
3619
3619
  return comp.trim().replace(safeRe[t.STAR], "");
3620
3620
  }
3621
3621
  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
@@ -3667,7 +3667,7 @@ var require_semver2 = __commonJS({
3667
3667
  }
3668
3668
  if (version2.prerelease.length && !options.includePrerelease) {
3669
3669
  for (i2 = 0; i2 < set.length; i2++) {
3670
- debug13(set[i2].semver);
3670
+ debug15(set[i2].semver);
3671
3671
  if (set[i2].semver === ANY) {
3672
3672
  continue;
3673
3673
  }
@@ -3912,27 +3912,27 @@ var require_process = __commonJS({
3912
3912
  var require_filesystem = __commonJS({
3913
3913
  "../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/filesystem.js"(exports, module2) {
3914
3914
  "use strict";
3915
- var fs16 = require("fs");
3915
+ var fs18 = require("fs");
3916
3916
  var LDD_PATH = "/usr/bin/ldd";
3917
3917
  var SELF_PATH = "/proc/self/exe";
3918
3918
  var MAX_LENGTH = 2048;
3919
3919
  var readFileSync2 = (path) => {
3920
- const fd = fs16.openSync(path, "r");
3920
+ const fd = fs18.openSync(path, "r");
3921
3921
  const buffer = Buffer.alloc(MAX_LENGTH);
3922
- const bytesRead = fs16.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3923
- fs16.close(fd, () => {
3922
+ const bytesRead = fs18.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3923
+ fs18.close(fd, () => {
3924
3924
  });
3925
3925
  return buffer.subarray(0, bytesRead);
3926
3926
  };
3927
3927
  var readFile2 = (path) => new Promise((resolve3, reject) => {
3928
- fs16.open(path, "r", (err, fd) => {
3928
+ fs18.open(path, "r", (err, fd) => {
3929
3929
  if (err) {
3930
3930
  reject(err);
3931
3931
  } else {
3932
3932
  const buffer = Buffer.alloc(MAX_LENGTH);
3933
- fs16.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3933
+ fs18.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3934
3934
  resolve3(buffer.subarray(0, bytesRead));
3935
- fs16.close(fd, () => {
3935
+ fs18.close(fd, () => {
3936
3936
  });
3937
3937
  });
3938
3938
  }
@@ -4379,15 +4379,15 @@ __export(src_exports, {
4379
4379
  });
4380
4380
  module.exports = __toCommonJS(src_exports);
4381
4381
  var import_assert = __toESM(require("assert"));
4382
- var import_fs17 = __toESM(require("fs"));
4383
- var import_path17 = require("path");
4382
+ var import_fs19 = __toESM(require("fs"));
4383
+ var import_path19 = require("path");
4384
4384
 
4385
4385
  // src/package-versions.ts
4386
4386
  var VERCEL_RUNTIME_VERSION = "0.16.0";
4387
4387
  var VERCEL_WORKERS_VERSION = "0.0.25";
4388
4388
 
4389
4389
  // src/index.ts
4390
- var import_build_utils20 = require("@vercel/build-utils");
4390
+ var import_build_utils22 = require("@vercel/build-utils");
4391
4391
 
4392
4392
  // src/install.ts
4393
4393
  var import_execa3 = __toESM(require_execa());
@@ -5641,230 +5641,11 @@ async function installRequirementsFile({
5641
5641
  }
5642
5642
 
5643
5643
  // src/dependency-externalizer.ts
5644
- var import_fs6 = __toESM(require("fs"));
5645
- var import_util = require("util");
5646
- var import_path7 = require("path");
5647
- var import_build_utils7 = require("@vercel/build-utils");
5648
- var import_python_analysis3 = require("@vercel/python-analysis");
5649
-
5650
- // src/compileall.ts
5651
- var import_execa4 = __toESM(require_execa());
5652
- var import_build_utils6 = require("@vercel/build-utils");
5653
5644
  var import_fs5 = __toESM(require("fs"));
5645
+ var import_util = require("util");
5654
5646
  var import_path6 = require("path");
5655
- var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
5656
- var PYCACHE_PREFIX_DIR = "_vc_pycache";
5657
- var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
5658
- function isCompileAllFlagEnabled() {
5659
- const val = process.env.VERCEL_PYTHON_COMPILEALL;
5660
- if (val === void 0 || val === "")
5661
- return false;
5662
- const lower = val.toLowerCase();
5663
- return lower === "1" || lower === "true";
5664
- }
5665
- function shouldCompileAll({
5666
- isDev,
5667
- hasCustomCommand,
5668
- hasPreDeployCommand
5669
- }) {
5670
- if (isDev)
5671
- return false;
5672
- if (hasCustomCommand)
5673
- return false;
5674
- if (hasPreDeployCommand)
5675
- return false;
5676
- return isCompileAllFlagEnabled();
5677
- }
5678
- async function runCompileAll({
5679
- pythonBin,
5680
- filesOrDirectories,
5681
- env,
5682
- excludeRegex,
5683
- pycachePrefix
5684
- }) {
5685
- if (filesOrDirectories.length === 0)
5686
- return;
5687
- const args = [
5688
- "-m",
5689
- "compileall",
5690
- "-q",
5691
- "-j",
5692
- "0",
5693
- "-f",
5694
- "--invalidation-mode",
5695
- "unchecked-hash",
5696
- ...excludeRegex ? ["-x", excludeRegex] : [],
5697
- ...filesOrDirectories
5698
- ];
5699
- const baseEnv = env || process.env;
5700
- const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
5701
- try {
5702
- await (0, import_execa4.default)(pythonBin, args, {
5703
- env: subprocessEnv,
5704
- timeout: COMPILEALL_TIMEOUT_MS
5705
- });
5706
- } catch (err) {
5707
- (0, import_build_utils6.debug)(`compileall error details: ${JSON.stringify(err)}`);
5708
- }
5709
- }
5710
- function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
5711
- if (!pyRelPath.endsWith(".py"))
5712
- return null;
5713
- const lastSlash = pyRelPath.lastIndexOf("/");
5714
- const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
5715
- const baseName = pyRelPath.slice(lastSlash + 1, -3);
5716
- return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
5717
- }
5718
- function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
5719
- if (!pyRelPath.endsWith(".py"))
5720
- return null;
5721
- return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
5722
- }
5723
- function stripPycachePrefixRoot(head) {
5724
- const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
5725
- if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
5726
- head = head.slice(2);
5727
- }
5728
- let start = 0;
5729
- while (start < head.length && pycachePathSeparators.has(head[start])) {
5730
- start++;
5731
- }
5732
- return head.slice(start);
5733
- }
5734
- function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
5735
- const rel = derivePrefixPycRelPath(
5736
- stripPycachePrefixRoot(srcAbsPath),
5737
- pythonMajor,
5738
- pythonMinor
5739
- );
5740
- if (!rel)
5741
- return null;
5742
- return (0, import_path6.join)(stagingDir, rel.replaceAll("/", import_path6.sep));
5743
- }
5744
- function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
5745
- const rel = derivePrefixPycRelPath(
5746
- stripPycachePrefixRoot(runtimeAbsPath),
5747
- pythonMajor,
5748
- pythonMinor
5749
- );
5750
- if (!rel)
5751
- return null;
5752
- return `${PYCACHE_PREFIX_DIR}/${rel}`;
5753
- }
5754
- var COMPILEALL_APP_EXCLUDED_DIRS = [
5755
- ".git",
5756
- ".vercel",
5757
- ".pnpm-store",
5758
- "node_modules",
5759
- ".next",
5760
- ".nuxt",
5761
- ".venv",
5762
- "venv",
5763
- "__pycache__",
5764
- ".mypy_cache",
5765
- ".ruff_cache",
5766
- "public"
5767
- ];
5768
- function escapePythonRegex(value) {
5769
- return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
5770
- }
5771
- function getCompileAllAppExcludeRegex(workPath) {
5772
- const excludedDirs = COMPILEALL_APP_EXCLUDED_DIRS.map(escapePythonRegex).join("|");
5773
- return `${escapePythonRegex(workPath)}[/\\\\](?:${excludedDirs})(?:[/\\\\]|$)`;
5774
- }
5775
- async function collectAppPrefixBytecodeFiles({
5776
- stagingDir,
5777
- workPath,
5778
- files: appFiles,
5779
- runtimeTaskRoot,
5780
- pythonMajor,
5781
- pythonMinor
5782
- }) {
5783
- const pending = [];
5784
- for (const bundlePath of Object.keys(appFiles)) {
5785
- if (!bundlePath.endsWith(".py"))
5786
- continue;
5787
- const stagedFsPath = deriveStagedPycFsPath(
5788
- stagingDir,
5789
- (0, import_path6.join)(workPath, bundlePath.replaceAll("/", import_path6.sep)),
5790
- pythonMajor,
5791
- pythonMinor
5792
- );
5793
- const pycBundlePath = derivePrefixPycBundlePath(
5794
- `${runtimeTaskRoot}/${bundlePath}`,
5795
- pythonMajor,
5796
- pythonMinor
5797
- );
5798
- if (!stagedFsPath || !pycBundlePath)
5799
- continue;
5800
- pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
5801
- }
5802
- const results = await Promise.all(
5803
- pending.map(async ({ bundlePath, srcFsPath }) => {
5804
- try {
5805
- const stats = await import_fs5.default.promises.stat(srcFsPath);
5806
- return { bundlePath, srcFsPath, size: stats.size };
5807
- } catch {
5808
- return null;
5809
- }
5810
- })
5811
- );
5812
- const files = {};
5813
- const perItemSizes = /* @__PURE__ */ new Map();
5814
- let totalSize = 0;
5815
- for (const result of results) {
5816
- if (!result)
5817
- continue;
5818
- files[result.bundlePath] = new import_build_utils6.FileFsRef({
5819
- fsPath: result.srcFsPath,
5820
- size: result.size
5821
- });
5822
- perItemSizes.set(result.bundlePath, result.size);
5823
- totalSize += result.size;
5824
- }
5825
- return { files, totalSize, perItemSizes };
5826
- }
5827
- async function collectAppBytecodeFiles({
5828
- workPath,
5829
- files: appFiles,
5830
- pythonMajor,
5831
- pythonMinor
5832
- }) {
5833
- const pending = [];
5834
- for (const bundlePath of Object.keys(appFiles)) {
5835
- const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
5836
- if (!pycRel)
5837
- continue;
5838
- pending.push({
5839
- bundlePath: pycRel,
5840
- srcFsPath: (0, import_path6.join)(workPath, pycRel.replaceAll("/", import_path6.sep))
5841
- });
5842
- }
5843
- const results = await Promise.all(
5844
- pending.map(async ({ bundlePath, srcFsPath }) => {
5845
- try {
5846
- const stats = await import_fs5.default.promises.stat(srcFsPath);
5847
- return { bundlePath, srcFsPath, size: stats.size };
5848
- } catch {
5849
- return null;
5850
- }
5851
- })
5852
- );
5853
- const files = {};
5854
- const perItemSizes = /* @__PURE__ */ new Map();
5855
- let totalSize = 0;
5856
- for (const result of results) {
5857
- if (!result)
5858
- continue;
5859
- files[result.bundlePath] = new import_build_utils6.FileFsRef({
5860
- fsPath: result.srcFsPath,
5861
- size: result.size
5862
- });
5863
- perItemSizes.set(result.bundlePath, result.size);
5864
- totalSize += result.size;
5865
- }
5866
- return { files, totalSize, perItemSizes };
5867
- }
5647
+ var import_build_utils6 = require("@vercel/build-utils");
5648
+ var import_python_analysis3 = require("@vercel/python-analysis");
5868
5649
 
5869
5650
  // src/large-functions.ts
5870
5651
  function isLargeFunctionsEnabled() {
@@ -5873,24 +5654,7 @@ function isLargeFunctionsEnabled() {
5873
5654
  }
5874
5655
 
5875
5656
  // src/dependency-externalizer.ts
5876
- var readFile = (0, import_util.promisify)(import_fs6.default.readFile);
5877
- var STRIP_BASENAMES = /* @__PURE__ */ new Set([
5878
- "py.typed",
5879
- "WHEEL",
5880
- "INSTALLER",
5881
- "direct_url.json"
5882
- ]);
5883
- function shouldStripVendorFile(filePath) {
5884
- const segments = filePath.split(import_path7.sep);
5885
- if (segments.includes("__pycache__"))
5886
- return true;
5887
- const name = segments[segments.length - 1] ?? "";
5888
- if (name.endsWith(".pyc") || name.endsWith(".pyi"))
5889
- return true;
5890
- if (STRIP_BASENAMES.has(name))
5891
- return true;
5892
- return false;
5893
- }
5657
+ var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
5894
5658
  var LAMBDA_SIZE_THRESHOLD_BYTES = 225 * 1024 * 1024;
5895
5659
  var BYTECODE_FILL_MARGIN_BYTES = 5 * 1024 * 1024;
5896
5660
  var BYTECODE_FILL_CEILING_BYTES = LAMBDA_SIZE_THRESHOLD_BYTES - BYTECODE_FILL_MARGIN_BYTES;
@@ -5902,21 +5666,16 @@ var LARGE_FUNCTION_FILL_CEILING_BYTES = MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE - B
5902
5666
  var BUNDLING_DOCS_LINK = "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled";
5903
5667
  var PythonDependencyExternalizer = class {
5904
5668
  constructor(options) {
5905
- // Populated by analyze()
5906
- this.sitePackageDirs = [];
5907
- this.distributions = /* @__PURE__ */ new Map();
5908
5669
  this.allVendorFiles = {};
5909
5670
  this.totalBundleSize = 0;
5910
5671
  this.analyzed = false;
5911
- this.venvPath = options.venvPath;
5672
+ this.installedDistributions = options.installedDistributions;
5912
5673
  this.vendorDir = options.vendorDir;
5913
5674
  this.workPath = options.workPath;
5914
5675
  this.uvLockPath = options.uvLockPath;
5915
5676
  this.uvProjectDir = options.uvProjectDir;
5916
5677
  this.projectName = options.projectName;
5917
- this.pythonMajor = options.pythonMajor;
5918
- this.pythonMinor = options.pythonMinor;
5919
- this.pythonPath = options.pythonPath;
5678
+ this.pythonVersion = options.pythonVersion;
5920
5679
  this.hasCustomCommand = options.hasCustomCommand;
5921
5680
  this.alwaysBundlePackages = options.alwaysBundlePackages ?? [];
5922
5681
  }
@@ -5938,17 +5697,7 @@ var PythonDependencyExternalizer = class {
5938
5697
  * Must be called before generateBundle().
5939
5698
  */
5940
5699
  async analyze(files, options = {}) {
5941
- this.sitePackageDirs = await getVenvSitePackagesDirs(this.venvPath);
5942
- this.distributions = /* @__PURE__ */ new Map();
5943
- for (const dir of this.sitePackageDirs) {
5944
- try {
5945
- await import_fs6.default.promises.access(dir);
5946
- } catch {
5947
- continue;
5948
- }
5949
- this.distributions.set(dir, await (0, import_python_analysis3.scanDistributions)(dir));
5950
- }
5951
- this.allVendorFiles = await this.mirrorPackagesIntoVendor({
5700
+ this.allVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
5952
5701
  vendorDirName: this.vendorDir
5953
5702
  });
5954
5703
  const tempFilesForSizing = { ...files };
@@ -5958,7 +5707,7 @@ var PythonDependencyExternalizer = class {
5958
5707
  this.totalBundleSize = await calculateBundleSize(tempFilesForSizing);
5959
5708
  this.analyzed = true;
5960
5709
  const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
5961
- (0, import_build_utils7.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
5710
+ (0, import_build_utils6.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
5962
5711
  const runtimeInstallEnabled = this.shouldEnableRuntimeInstall();
5963
5712
  const largeFunctionsEnabled = isLargeFunctionsEnabled();
5964
5713
  options.onSized?.({
@@ -5967,7 +5716,7 @@ var PythonDependencyExternalizer = class {
5967
5716
  });
5968
5717
  if (this.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && this.hasCustomCommand && !largeFunctionsEnabled) {
5969
5718
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
5970
- throw new import_build_utils7.NowBuildError({
5719
+ throw new import_build_utils6.NowBuildError({
5971
5720
  code: "LAMBDA_SIZE_EXCEEDED",
5972
5721
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
5973
5722
 
@@ -5982,7 +5731,7 @@ function bundle size automatically. To fix this, you can:
5982
5731
  }
5983
5732
  if (largeFunctionsEnabled && this.totalBundleSize >= MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE) {
5984
5733
  const limitMB = (MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE / (1024 * 1024)).toFixed(0);
5985
- throw new import_build_utils7.NowBuildError({
5734
+ throw new import_build_utils6.NowBuildError({
5986
5735
  code: "LAMBDA_SIZE_EXCEEDED",
5987
5736
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the extended function size limit (${limitMB} MB).
5988
5737
 
@@ -6028,7 +5777,7 @@ application into smaller functions.`,
6028
5777
  const limitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(
6029
5778
  0
6030
5779
  );
6031
- throw new import_build_utils7.NowBuildError({
5780
+ throw new import_build_utils6.NowBuildError({
6032
5781
  code: "LAMBDA_SIZE_EXCEEDED",
6033
5782
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
6034
5783
 
@@ -6038,15 +5787,15 @@ smaller functions.`,
6038
5787
  action: "Learn More"
6039
5788
  });
6040
5789
  }
6041
- const relLockPath = (0, import_path7.relative)(this.workPath, this.uvLockPath);
5790
+ const relLockPath = (0, import_path6.relative)(this.workPath, this.uvLockPath);
6042
5791
  let lockContent;
6043
5792
  try {
6044
5793
  lockContent = await readFile(this.uvLockPath, "utf8");
6045
5794
  } catch (error) {
6046
- (0, import_build_utils7.debug)(
5795
+ (0, import_build_utils6.debug)(
6047
5796
  `Failed to read uv.lock at ${this.uvLockPath}: ${error instanceof Error ? error.message : String(error)}`
6048
5797
  );
6049
- throw new import_build_utils7.NowBuildError({
5798
+ throw new import_build_utils6.NowBuildError({
6050
5799
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6051
5800
  message: `Failed to read the uv.lock file at "${relLockPath}".`
6052
5801
  });
@@ -6057,12 +5806,12 @@ smaller functions.`,
6057
5806
  } catch (error) {
6058
5807
  if (error instanceof import_python_analysis3.PythonAnalysisError) {
6059
5808
  if (error.fileContent) {
6060
- (0, import_build_utils7.debug)(
5809
+ (0, import_build_utils6.debug)(
6061
5810
  `Failed to parse "${error.path}". File content:
6062
5811
  ${error.fileContent}`
6063
5812
  );
6064
5813
  }
6065
- throw new import_build_utils7.NowBuildError({
5814
+ throw new import_build_utils6.NowBuildError({
6066
5815
  code: error.code,
6067
5816
  message: error.message
6068
5817
  });
@@ -6072,7 +5821,7 @@ ${error.fileContent}`
6072
5821
  const excludePackages = [];
6073
5822
  if (this.projectName) {
6074
5823
  excludePackages.push(this.projectName);
6075
- (0, import_build_utils7.debug)(
5824
+ (0, import_build_utils6.debug)(
6076
5825
  `Excluding project package "${this.projectName}" from runtime installation`
6077
5826
  );
6078
5827
  }
@@ -6080,7 +5829,7 @@ ${error.fileContent}`
6080
5829
  lockFile,
6081
5830
  excludePackages
6082
5831
  });
6083
- (0, import_build_utils7.debug)(
5832
+ (0, import_build_utils6.debug)(
6084
5833
  `Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
6085
5834
  );
6086
5835
  const forceBundledDueToWheels = await this.findPackagesWithoutCompatibleWheels(
@@ -6102,7 +5851,7 @@ ${error.fileContent}`
6102
5851
  if (largeFunctionsEnabled) {
6103
5852
  return this.bundleAllForHive(files);
6104
5853
  }
6105
- throw new import_build_utils7.NowBuildError({
5854
+ throw new import_build_utils6.NowBuildError({
6106
5855
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6107
5856
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size and
6108
5857
  can't be optimized automatically because some dependencies don't
@@ -6113,7 +5862,7 @@ To fix this, either:
6113
5862
  2. Replace the packages that don't provide a pre-built wheel.`
6114
5863
  });
6115
5864
  }
6116
- const packageSizes = await this.calculatePerPackageSizes();
5865
+ const packageSizes = await this.installedDistributions.calculatePerPackageSizes();
6117
5866
  const alwaysBundled = [
6118
5867
  ...classification.privatePackages,
6119
5868
  "vercel-runtime",
@@ -6121,7 +5870,7 @@ To fix this, either:
6121
5870
  ...this.alwaysBundlePackages,
6122
5871
  ...forceBundledDueToWheels
6123
5872
  ];
6124
- const alwaysBundledFiles = await this.mirrorPackagesIntoVendor({
5873
+ const alwaysBundledFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
6125
5874
  vendorDirName: this.vendorDir,
6126
5875
  includePackages: alwaysBundled
6127
5876
  });
@@ -6133,26 +5882,26 @@ To fix this, either:
6133
5882
  let runtimeToolingOverhead = 0;
6134
5883
  try {
6135
5884
  const uvBinaryPath = await this.resolveUvBinaryForBundling();
6136
- const uvStats = await import_fs6.default.promises.stat(uvBinaryPath);
5885
+ const uvStats = await import_fs5.default.promises.stat(uvBinaryPath);
6137
5886
  runtimeToolingOverhead = uvStats.size;
6138
5887
  } catch {
6139
5888
  runtimeToolingOverhead = 50 * 1024 * 1024;
6140
5889
  }
6141
5890
  runtimeToolingOverhead += 4 * 1024;
6142
- const projectDirRel = (0, import_path7.relative)(this.workPath, this.uvProjectDir);
6143
- const uvLockRel = (0, import_path7.relative)(this.workPath, this.uvLockPath);
5891
+ const projectDirRel = (0, import_path6.relative)(this.workPath, this.uvProjectDir);
5892
+ const uvLockRel = (0, import_path6.relative)(this.workPath, this.uvLockPath);
6144
5893
  const isOutsideWorkPath = projectDirRel.startsWith("..") || uvLockRel.startsWith("..");
6145
5894
  if (isOutsideWorkPath) {
6146
- const pyprojectPath = (0, import_path7.join)(this.uvProjectDir, "pyproject.toml");
6147
- const pyprojectStats = await import_fs6.default.promises.stat(pyprojectPath).catch(() => null);
6148
- const uvLockStats = await import_fs6.default.promises.stat(this.uvLockPath).catch(() => null);
5895
+ const pyprojectPath = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
5896
+ const pyprojectStats = await import_fs5.default.promises.stat(pyprojectPath).catch(() => null);
5897
+ const uvLockStats = await import_fs5.default.promises.stat(this.uvLockPath).catch(() => null);
6149
5898
  if (pyprojectStats)
6150
5899
  runtimeToolingOverhead += pyprojectStats.size;
6151
5900
  if (uvLockStats)
6152
5901
  runtimeToolingOverhead += uvLockStats.size;
6153
5902
  }
6154
5903
  const remainingCapacity = LAMBDA_SIZE_THRESHOLD_BYTES - fixedOverhead - runtimeToolingOverhead;
6155
- (0, import_build_utils7.debug)(
5904
+ (0, import_build_utils6.debug)(
6156
5905
  `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`
6157
5906
  );
6158
5907
  if (largeFunctionsEnabled && remainingCapacity < 0) {
@@ -6175,7 +5924,7 @@ To fix this, either:
6175
5924
  bytecodeFirst: options.bytecodeFirst ?? false
6176
5925
  });
6177
5926
  if (options.bytecodeFirst && packingMode === "knapsack") {
6178
- (0, import_build_utils7.debug)(
5927
+ (0, import_build_utils6.debug)(
6179
5928
  `bytecode-first packing disabled: the public package set exceeds the ephemeral install budget (${(EPHEMERAL_INSTALL_BUDGET_BYTES / (1024 * 1024)).toFixed(2)} MB); falling back to knapsack packing`
6180
5929
  );
6181
5930
  }
@@ -6184,7 +5933,7 @@ To fix this, either:
6184
5933
  (name) => !bundledPublicSet.has((0, import_python_analysis3.normalizePackageName)(name))
6185
5934
  );
6186
5935
  const allBundledPackages = [...alwaysBundled, ...bundledPublic];
6187
- const selectedVendorFiles = await this.mirrorPackagesIntoVendor({
5936
+ const selectedVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
6188
5937
  vendorDirName: this.vendorDir,
6189
5938
  includePackages: allBundledPackages
6190
5939
  });
@@ -6198,11 +5947,11 @@ To fix this, either:
6198
5947
  ...forceBundledDueToWheels
6199
5948
  ];
6200
5949
  if (isOutsideWorkPath) {
6201
- const srcPyproject = (0, import_path7.join)(this.uvProjectDir, "pyproject.toml");
6202
- files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils7.FileFsRef({
5950
+ const srcPyproject = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
5951
+ files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils6.FileFsRef({
6203
5952
  fsPath: srcPyproject
6204
5953
  });
6205
- files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils7.FileFsRef({
5954
+ files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils6.FileFsRef({
6206
5955
  fsPath: this.uvLockPath
6207
5956
  });
6208
5957
  }
@@ -6210,27 +5959,27 @@ To fix this, either:
6210
5959
  projectDir: isOutsideWorkPath ? UV_BUNDLE_DIR : projectDirRel,
6211
5960
  bundledPackages: bundledPackagesForConfig
6212
5961
  });
6213
- files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils7.FileBlob({
5962
+ files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils6.FileBlob({
6214
5963
  data: runtimeConfigData
6215
5964
  });
6216
5965
  try {
6217
5966
  const uvBinaryPath = await this.resolveUvBinaryForBundling();
6218
- const uvBundleDir = (0, import_path7.join)(this.workPath, UV_BUNDLE_DIR);
6219
- const uvLocalPath = (0, import_path7.join)(uvBundleDir, "uv");
6220
- await import_fs6.default.promises.mkdir(uvBundleDir, { recursive: true });
6221
- await import_fs6.default.promises.copyFile(uvBinaryPath, uvLocalPath);
6222
- await import_fs6.default.promises.chmod(uvLocalPath, 493);
5967
+ const uvBundleDir = (0, import_path6.join)(this.workPath, UV_BUNDLE_DIR);
5968
+ const uvLocalPath = (0, import_path6.join)(uvBundleDir, "uv");
5969
+ await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
5970
+ await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
5971
+ await import_fs5.default.promises.chmod(uvLocalPath, 493);
6223
5972
  const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
6224
- files[uvBundlePath] = new import_build_utils7.FileFsRef({
5973
+ files[uvBundlePath] = new import_build_utils6.FileFsRef({
6225
5974
  fsPath: uvLocalPath,
6226
5975
  mode: 33261
6227
5976
  });
6228
- (0, import_build_utils7.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
5977
+ (0, import_build_utils6.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
6229
5978
  } catch (err) {
6230
- (0, import_build_utils7.debug)(
5979
+ (0, import_build_utils6.debug)(
6231
5980
  `Failed to bundle uv binary: ${err instanceof Error ? err.message : String(err)}`
6232
5981
  );
6233
- throw new import_build_utils7.NowBuildError({
5982
+ throw new import_build_utils6.NowBuildError({
6234
5983
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6235
5984
  message: "Failed to prepare dependency tooling."
6236
5985
  });
@@ -6242,7 +5991,7 @@ To fix this, either:
6242
5991
  }
6243
5992
  const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
6244
5993
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
6245
- throw new import_build_utils7.NowBuildError({
5994
+ throw new import_build_utils6.NowBuildError({
6246
5995
  code: "LAMBDA_SIZE_EXCEEDED",
6247
5996
  message: `Total bundle size (${finalSizeMB} MB) exceeds the maximum function size (${limitMB} MB) even after
6248
5997
  optimizing dependencies.
@@ -6279,7 +6028,7 @@ functions.`,
6279
6028
  for (const [p, f] of Object.entries(this.allVendorFiles)) {
6280
6029
  files[p] = f;
6281
6030
  }
6282
- (0, import_build_utils7.debug)("Bundling all dependencies for the large functions path.");
6031
+ (0, import_build_utils6.debug)("Bundling all dependencies for the large functions path.");
6283
6032
  return { fellBackToFullBundle: true };
6284
6033
  }
6285
6034
  /**
@@ -6294,15 +6043,15 @@ functions.`,
6294
6043
  */
6295
6044
  async findPackagesWithoutCompatibleWheels(lockFile, publicPackageNames) {
6296
6045
  const platform = detectTargetPlatform();
6297
- if (this.pythonMajor === void 0 || this.pythonMinor === void 0) {
6298
- (0, import_build_utils7.debug)("Skipping wheel compatibility check: dev mode");
6046
+ if (this.pythonVersion.major === void 0 || this.pythonVersion.minor === void 0) {
6047
+ (0, import_build_utils6.debug)("Skipping wheel compatibility check: dev mode");
6299
6048
  return [];
6300
6049
  }
6301
6050
  const reachable = await getPackagesReachableOnPlatform(
6302
6051
  lockFile,
6303
6052
  this.projectName,
6304
- this.pythonMajor,
6305
- this.pythonMinor,
6053
+ this.pythonVersion.major,
6054
+ this.pythonVersion.minor,
6306
6055
  platform.sysPlatform,
6307
6056
  platform.archName
6308
6057
  );
@@ -6310,7 +6059,7 @@ functions.`,
6310
6059
  (name) => reachable.has((0, import_python_analysis3.normalizePackageName)(name))
6311
6060
  ) : publicPackageNames;
6312
6061
  if (relevantPackages.length < publicPackageNames.length) {
6313
- (0, import_build_utils7.debug)(
6062
+ (0, import_build_utils6.debug)(
6314
6063
  `Skipping wheel check for ${publicPackageNames.length - relevantPackages.length} package(s) not reachable on the target platform`
6315
6064
  );
6316
6065
  }
@@ -6338,8 +6087,8 @@ functions.`,
6338
6087
  try {
6339
6088
  const compatible = await (0, import_python_analysis3.isWheelCompatible)(
6340
6089
  filename,
6341
- this.pythonMajor,
6342
- this.pythonMinor,
6090
+ this.pythonVersion.major,
6091
+ this.pythonVersion.minor,
6343
6092
  platform.osName,
6344
6093
  platform.archName,
6345
6094
  platform.osMajor,
@@ -6350,7 +6099,7 @@ functions.`,
6350
6099
  break;
6351
6100
  }
6352
6101
  } catch (err) {
6353
- (0, import_build_utils7.debug)(
6102
+ (0, import_build_utils6.debug)(
6354
6103
  `Failed to check wheel compatibility for ${filename}: ${err instanceof Error ? err.message : String(err)}`
6355
6104
  );
6356
6105
  }
@@ -6364,340 +6113,51 @@ functions.`,
6364
6113
  /** Resolve the uv binary for bundling (host binary on build image, downloaded on local). */
6365
6114
  async resolveUvBinaryForBundling() {
6366
6115
  if (process.env.VERCEL_BUILD_IMAGE) {
6367
- return getUvBinaryForBundling(this.pythonPath);
6116
+ return getUvBinaryForBundling(this.pythonVersion.pythonPath);
6368
6117
  }
6369
6118
  return downloadUvBinaryForTarget(
6370
- (0, import_path7.join)(this.workPath, ".vercel", "python", "cache")
6119
+ (0, import_path6.join)(this.workPath, ".vercel", "python", "cache")
6371
6120
  );
6372
6121
  }
6373
- /**
6374
- * Mirror packages from site-packages into the _vendor directory.
6375
- *
6376
- * When `includePackages` is provided, only distributions whose normalized
6377
- * name is in the list are included. When omitted, every distribution is
6378
- * included.
6379
- *
6380
- * Reads `this.sitePackageDirs` and `this.distributions` which are
6381
- * resolved once at the start of `analyze()`.
6382
- */
6383
- async mirrorPackagesIntoVendor({
6384
- vendorDirName,
6385
- includePackages
6386
- }) {
6387
- const vendorFiles = {};
6388
- if (includePackages && includePackages.length === 0) {
6389
- return vendorFiles;
6390
- }
6391
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6392
- const pending = [];
6393
- for (const dir of this.sitePackageDirs) {
6394
- const dirDistributions = this.distributions.get(dir);
6395
- if (!dirDistributions)
6122
+ };
6123
+ async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor, pythonMinor, sysPlatform, platformMachine) {
6124
+ if (!projectName)
6125
+ return null;
6126
+ const rootNormalized = (0, import_python_analysis3.normalizePackageName)(projectName);
6127
+ const packageMap = /* @__PURE__ */ new Map();
6128
+ for (const pkg of lockFile.packages) {
6129
+ packageMap.set((0, import_python_analysis3.normalizePackageName)(pkg.name), pkg);
6130
+ }
6131
+ const rootPkg = packageMap.get(rootNormalized);
6132
+ if (!rootPkg)
6133
+ return null;
6134
+ const visited = /* @__PURE__ */ new Set();
6135
+ const queue = [];
6136
+ let queueHead = 0;
6137
+ async function enqueueDeps(pkg) {
6138
+ if (!pkg.dependencies)
6139
+ return;
6140
+ for (const dep of pkg.dependencies) {
6141
+ const normalized = (0, import_python_analysis3.normalizePackageName)(dep.name);
6142
+ if (visited.has(normalized))
6396
6143
  continue;
6397
- const resolvedDir = (0, import_path7.resolve)(dir);
6398
- const dirPrefix = resolvedDir + import_path7.sep;
6399
- for (const [name, dist] of dirDistributions) {
6400
- if (includeSet && !includeSet.has(name))
6401
- continue;
6402
- for (const { path: rawPath, size: recordSize } of dist.files) {
6403
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6404
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6405
- continue;
6406
- }
6407
- if (shouldStripVendorFile(filePath)) {
6408
- continue;
6409
- }
6410
- const srcFsPath = (0, import_path7.join)(dir, filePath);
6411
- const bundlePath = (0, import_path7.join)(vendorDirName, filePath).replace(/\\/g, "/");
6412
- pending.push({
6413
- bundlePath,
6414
- srcFsPath,
6415
- // RECORD sizes are bigint; convert to number for FileFsRef.
6416
- recordSize: recordSize !== void 0 && recordSize !== null ? Number(recordSize) : void 0
6417
- });
6418
- }
6419
- }
6420
- }
6421
- const results = await Promise.all(
6422
- pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
6423
- if (recordSize !== void 0) {
6424
- try {
6425
- await import_fs6.default.promises.access(srcFsPath);
6426
- return { bundlePath, srcFsPath, size: recordSize };
6427
- } catch {
6428
- return null;
6429
- }
6430
- } else {
6431
- try {
6432
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6433
- return { bundlePath, srcFsPath, size: stats.size };
6434
- } catch {
6435
- return null;
6436
- }
6437
- }
6438
- })
6439
- );
6440
- for (const result of results) {
6441
- if (result) {
6442
- vendorFiles[result.bundlePath] = new import_build_utils7.FileFsRef({
6443
- fsPath: result.srcFsPath,
6444
- size: result.size
6445
- });
6446
- }
6447
- }
6448
- (0, import_build_utils7.debug)(
6449
- `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
6450
- );
6451
- return vendorFiles;
6452
- }
6453
- /**
6454
- * Calculate the uncompressed size of each installed distribution.
6455
- *
6456
- * Returns a map of normalized package name to total size in bytes.
6457
- * Uses RECORD sizes when available, falling back to stat for files
6458
- * without a recorded size. All stat calls run in parallel.
6459
- */
6460
- async calculatePerPackageSizes() {
6461
- const sizes = /* @__PURE__ */ new Map();
6462
- for (const dir of this.sitePackageDirs) {
6463
- const dirDistributions = this.distributions.get(dir);
6464
- if (!dirDistributions)
6465
- continue;
6466
- const resolvedDir = (0, import_path7.resolve)(dir);
6467
- const dirPrefix = resolvedDir + import_path7.sep;
6468
- for (const [name, dist] of dirDistributions) {
6469
- let knownSize = 0;
6470
- const statPromises = [];
6471
- for (const { path: rawPath, size: recordSize } of dist.files) {
6472
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6473
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6474
- continue;
6475
- }
6476
- if (shouldStripVendorFile(filePath)) {
6477
- continue;
6478
- }
6479
- if (recordSize !== void 0 && recordSize !== null) {
6480
- knownSize += Number(recordSize);
6481
- } else {
6482
- statPromises.push(
6483
- import_fs6.default.promises.stat((0, import_path7.join)(dir, filePath)).then((stats) => stats.size).catch(() => 0)
6484
- );
6485
- }
6486
- }
6487
- const statSizes = await Promise.all(statPromises);
6488
- let totalSize = knownSize;
6489
- for (const s of statSizes) {
6490
- totalSize += s;
6491
- }
6492
- sizes.set(name, totalSize);
6493
- }
6494
- }
6495
- return sizes;
6496
- }
6497
- /**
6498
- * Collect pre-compiled `.pyc` bytecode files for vendor packages.
6499
- *
6500
- * For each `.py` file listed in a package's RECORD, derives the expected
6501
- * `__pycache__/*.cpython-XY.pyc` path and checks whether it exists on
6502
- * disk (i.e. whether `compileall` produced it). Files that do not exist
6503
- * are silently skipped.
6504
- *
6505
- * Must be called after `analyze()` which populates `sitePackageDirs` and
6506
- * `distributions`.
6507
- */
6508
- async collectBytecodeFiles({
6509
- vendorDirName,
6510
- includePackages
6511
- }) {
6512
- if (!this.sitePackageDirs || !this.distributions) {
6513
- throw new Error("collectBytecodeFiles() must be called after analyze()");
6514
- }
6515
- if (this.pythonMajor == null || this.pythonMinor == null) {
6516
- return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
6517
- }
6518
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6519
- const pending = [];
6520
- for (const dir of this.sitePackageDirs) {
6521
- const dirDistributions = this.distributions.get(dir);
6522
- if (!dirDistributions)
6523
- continue;
6524
- for (const [name, dist] of dirDistributions) {
6525
- if (includeSet && !includeSet.has(name))
6526
- continue;
6527
- for (const { path: rawPath } of dist.files) {
6528
- const pycRel = derivePycPath(
6529
- rawPath,
6530
- this.pythonMajor,
6531
- this.pythonMinor
6532
- );
6533
- if (!pycRel)
6534
- continue;
6535
- const pycFilePath = pycRel.replaceAll("/", import_path7.sep);
6536
- const srcFsPath = (0, import_path7.join)(dir, pycFilePath);
6537
- const bundlePath = (0, import_path7.join)(vendorDirName, pycFilePath).replace(
6538
- /\\/g,
6539
- "/"
6540
- );
6541
- pending.push({ bundlePath, srcFsPath, packageName: name });
6542
- }
6543
- }
6544
- }
6545
- const results = await Promise.all(
6546
- pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
6547
- try {
6548
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6549
- return { bundlePath, srcFsPath, size: stats.size, packageName };
6550
- } catch {
6551
- return null;
6552
- }
6553
- })
6554
- );
6555
- const files = {};
6556
- let totalSize = 0;
6557
- const perItemSizes = /* @__PURE__ */ new Map();
6558
- for (const result of results) {
6559
- if (!result)
6560
- continue;
6561
- files[result.bundlePath] = new import_build_utils7.FileFsRef({
6562
- fsPath: result.srcFsPath,
6563
- size: result.size
6564
- });
6565
- totalSize += result.size;
6566
- perItemSizes.set(
6567
- result.packageName,
6568
- (perItemSizes.get(result.packageName) ?? 0) + result.size
6569
- );
6570
- }
6571
- (0, import_build_utils7.debug)(
6572
- `Collected ${Object.keys(files).length} bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
6573
- );
6574
- return { files, totalSize, perItemSizes };
6575
- }
6576
- /**
6577
- * Collect staged prefix `.pyc` files for vendor packages, keyed under
6578
- * `_vc_pycache/<runtimeRoot>/...` (`runtimeRoot` = `/var/task/_vendor`
6579
- * for bundled packages, the /tmp site-packages dir for externalized
6580
- * ones). Missing staged files are silently skipped. Must be called after
6581
- * `analyze()`.
6582
- */
6583
- async collectPrefixBytecodeFiles({
6584
- stagingDir,
6585
- runtimeRoot,
6586
- includePackages
6587
- }) {
6588
- if (!this.sitePackageDirs || !this.distributions) {
6589
- throw new Error(
6590
- "collectPrefixBytecodeFiles() must be called after analyze()"
6591
- );
6592
- }
6593
- if (this.pythonMajor == null || this.pythonMinor == null) {
6594
- return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
6595
- }
6596
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6597
- const pending = [];
6598
- for (const dir of this.sitePackageDirs) {
6599
- const dirDistributions = this.distributions.get(dir);
6600
- if (!dirDistributions)
6601
- continue;
6602
- const resolvedDir = (0, import_path7.resolve)(dir);
6603
- const dirPrefix = resolvedDir + import_path7.sep;
6604
- for (const [name, dist] of dirDistributions) {
6605
- if (includeSet && !includeSet.has(name))
6606
- continue;
6607
- for (const { path: rawPath } of dist.files) {
6608
- if (!rawPath.endsWith(".py"))
6609
- continue;
6610
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6611
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6612
- continue;
6613
- }
6614
- const srcFsPath = deriveStagedPycFsPath(
6615
- stagingDir,
6616
- (0, import_path7.join)(dir, filePath),
6617
- this.pythonMajor,
6618
- this.pythonMinor
6619
- );
6620
- const bundlePath = derivePrefixPycBundlePath(
6621
- `${runtimeRoot}/${rawPath}`,
6622
- this.pythonMajor,
6623
- this.pythonMinor
6624
- );
6625
- if (!srcFsPath || !bundlePath)
6626
- continue;
6627
- pending.push({ bundlePath, srcFsPath, packageName: name });
6628
- }
6629
- }
6630
- }
6631
- const results = await Promise.all(
6632
- pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
6633
- try {
6634
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6635
- return { bundlePath, srcFsPath, size: stats.size, packageName };
6636
- } catch {
6637
- return null;
6638
- }
6639
- })
6640
- );
6641
- const files = {};
6642
- let totalSize = 0;
6643
- const perItemSizes = /* @__PURE__ */ new Map();
6644
- for (const result of results) {
6645
- if (!result)
6646
- continue;
6647
- files[result.bundlePath] = new import_build_utils7.FileFsRef({
6648
- fsPath: result.srcFsPath,
6649
- size: result.size
6650
- });
6651
- totalSize += result.size;
6652
- perItemSizes.set(
6653
- result.packageName,
6654
- (perItemSizes.get(result.packageName) ?? 0) + result.size
6655
- );
6656
- }
6657
- (0, import_build_utils7.debug)(
6658
- `Collected ${Object.keys(files).length} prefix bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
6659
- );
6660
- return { files, totalSize, perItemSizes };
6661
- }
6662
- };
6663
- async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor, pythonMinor, sysPlatform, platformMachine) {
6664
- if (!projectName)
6665
- return null;
6666
- const rootNormalized = (0, import_python_analysis3.normalizePackageName)(projectName);
6667
- const packageMap = /* @__PURE__ */ new Map();
6668
- for (const pkg of lockFile.packages) {
6669
- packageMap.set((0, import_python_analysis3.normalizePackageName)(pkg.name), pkg);
6670
- }
6671
- const rootPkg = packageMap.get(rootNormalized);
6672
- if (!rootPkg)
6673
- return null;
6674
- const visited = /* @__PURE__ */ new Set();
6675
- const queue = [];
6676
- let queueHead = 0;
6677
- async function enqueueDeps(pkg) {
6678
- if (!pkg.dependencies)
6679
- return;
6680
- for (const dep of pkg.dependencies) {
6681
- const normalized = (0, import_python_analysis3.normalizePackageName)(dep.name);
6682
- if (visited.has(normalized))
6683
- continue;
6684
- if (dep.marker) {
6685
- try {
6686
- const compatible = await (0, import_python_analysis3.evaluateMarker)(
6687
- dep.marker,
6688
- pythonMajor,
6689
- pythonMinor,
6690
- sysPlatform,
6691
- platformMachine
6692
- );
6693
- if (!compatible) {
6694
- (0, import_build_utils7.debug)(
6695
- `Skipping dependency ${dep.name}: marker "${dep.marker}" not satisfied on ${sysPlatform}`
6696
- );
6144
+ if (dep.marker) {
6145
+ try {
6146
+ const compatible = await (0, import_python_analysis3.evaluateMarker)(
6147
+ dep.marker,
6148
+ pythonMajor,
6149
+ pythonMinor,
6150
+ sysPlatform,
6151
+ platformMachine
6152
+ );
6153
+ if (!compatible) {
6154
+ (0, import_build_utils6.debug)(
6155
+ `Skipping dependency ${dep.name}: marker "${dep.marker}" not satisfied on ${sysPlatform}`
6156
+ );
6697
6157
  continue;
6698
6158
  }
6699
6159
  } catch (err) {
6700
- (0, import_build_utils7.debug)(
6160
+ (0, import_build_utils6.debug)(
6701
6161
  `Failed to evaluate marker "${dep.marker}" for ${dep.name}, including conservatively: ${err instanceof Error ? err.message : String(err)}`
6702
6162
  );
6703
6163
  }
@@ -6731,7 +6191,7 @@ async function calculateBundleSize(files, filter) {
6731
6191
  knownSize += fsRef.size;
6732
6192
  } else {
6733
6193
  statPromises.push(
6734
- import_fs6.default.promises.stat(fsRef.fsPath).then((stats) => {
6194
+ import_fs5.default.promises.stat(fsRef.fsPath).then((stats) => {
6735
6195
  fsRef.size = stats.size;
6736
6196
  return stats.size;
6737
6197
  }).catch((err) => {
@@ -6788,8 +6248,8 @@ function planPublicPackagePacking({
6788
6248
  }
6789
6249
 
6790
6250
  // src/diagnostics.ts
6791
- var import_fs7 = __toESM(require("fs"));
6792
- var import_build_utils8 = require("@vercel/build-utils");
6251
+ var import_fs6 = __toESM(require("fs"));
6252
+ var import_build_utils7 = require("@vercel/build-utils");
6793
6253
  var import_python_analysis4 = require("@vercel/python-analysis");
6794
6254
  function isDependencyGroupInclude(entry) {
6795
6255
  return typeof entry === "object" && "include-group" in entry;
@@ -6903,7 +6363,7 @@ async function generateProjectManifest({
6903
6363
  const directEntries = [];
6904
6364
  const transitiveEntries = [];
6905
6365
  {
6906
- const content = await import_fs7.default.promises.readFile(uvLockPath, "utf-8");
6366
+ const content = await import_fs6.default.promises.readFile(uvLockPath, "utf-8");
6907
6367
  const uvLock = (0, import_python_analysis4.parseUvLock)(content, uvLockPath);
6908
6368
  const projectName = project?.name;
6909
6369
  const excludeSet = new Set(
@@ -6994,7 +6454,7 @@ async function generateProjectManifest({
6994
6454
  }
6995
6455
  }
6996
6456
  const manifest = {
6997
- version: import_build_utils8.MANIFEST_VERSION,
6457
+ version: import_build_utils7.MANIFEST_VERSION,
6998
6458
  runtime: "python",
6999
6459
  ...framework ? { framework } : {},
7000
6460
  ...serviceType ? { serviceType } : {},
@@ -7008,22 +6468,22 @@ async function generateProjectManifest({
7008
6468
  ...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
7009
6469
  ]
7010
6470
  };
7011
- await (0, import_build_utils8.writeProjectManifest)(manifest, workPath, "python");
6471
+ await (0, import_build_utils7.writeProjectManifest)(manifest, workPath, "python");
7012
6472
  }
7013
- var diagnostics = (0, import_build_utils8.createDiagnostics)("python");
6473
+ var diagnostics = (0, import_build_utils7.createDiagnostics)("python");
7014
6474
 
7015
6475
  // src/crons.ts
7016
- var import_fs9 = __toESM(require("fs"));
7017
- var import_path9 = require("path");
7018
- var import_execa5 = __toESM(require_execa());
7019
- var import_build_utils12 = require("@vercel/build-utils");
7020
-
7021
- // src/entrypoint.ts
7022
6476
  var import_fs8 = __toESM(require("fs"));
7023
6477
  var import_path8 = require("path");
6478
+ var import_execa4 = __toESM(require_execa());
6479
+ var import_build_utils11 = require("@vercel/build-utils");
6480
+
6481
+ // src/entrypoint.ts
6482
+ var import_fs7 = __toESM(require("fs"));
6483
+ var import_path7 = require("path");
6484
+ var import_build_utils8 = require("@vercel/build-utils");
7024
6485
  var import_build_utils9 = require("@vercel/build-utils");
7025
6486
  var import_build_utils10 = require("@vercel/build-utils");
7026
- var import_build_utils11 = require("@vercel/build-utils");
7027
6487
  var import_python_analysis5 = require("@vercel/python-analysis");
7028
6488
  var PYTHON_ENTRYPOINT_FILENAMES = [
7029
6489
  "app",
@@ -7042,13 +6502,13 @@ var SKIP_DIRS = /* @__PURE__ */ new Set(["__pycache__", "node_modules"]);
7042
6502
  function getCandidateEntrypointsInDirs(dirs) {
7043
6503
  return dirs.flatMap(
7044
6504
  (dir) => PYTHON_ENTRYPOINT_FILENAMES.map(
7045
- (filename) => import_path8.posix.join(dir, `${filename}.py`)
6505
+ (filename) => import_path7.posix.join(dir, `${filename}.py`)
7046
6506
  )
7047
6507
  );
7048
6508
  }
7049
6509
  async function fileExists(filePath) {
7050
6510
  try {
7051
- const stat = await import_fs8.default.promises.stat(filePath);
6511
+ const stat = await import_fs7.default.promises.stat(filePath);
7052
6512
  return stat.isFile();
7053
6513
  } catch {
7054
6514
  return false;
@@ -7103,28 +6563,28 @@ function entrypointToModule(entrypoint) {
7103
6563
  return entrypoint.replace(/\\/g, "/").replace(/\.py$/i, "").replace(/\/__init__$/i, "").replace(/\//g, ".");
7104
6564
  }
7105
6565
  async function checkEntrypoint(workPath, relPath) {
7106
- const absPath = (0, import_path8.join)(workPath, relPath);
6566
+ const absPath = (0, import_path7.join)(workPath, relPath);
7107
6567
  if (!await fileExists(absPath))
7108
6568
  return null;
7109
- const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
6569
+ const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
7110
6570
  return (0, import_python_analysis5.findAppOrHandler)(content);
7111
6571
  }
7112
6572
  async function findPythonFilesRecursive(dir, rootDir) {
7113
6573
  const results = [];
7114
6574
  let entries;
7115
6575
  try {
7116
- entries = await import_fs8.default.promises.readdir(dir, { withFileTypes: true });
6576
+ entries = await import_fs7.default.promises.readdir(dir, { withFileTypes: true });
7117
6577
  } catch {
7118
6578
  return results;
7119
6579
  }
7120
6580
  for (const entry of entries) {
7121
6581
  if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
7122
6582
  continue;
7123
- const fullPath = (0, import_path8.join)(dir, entry.name);
6583
+ const fullPath = (0, import_path7.join)(dir, entry.name);
7124
6584
  if (entry.isDirectory()) {
7125
6585
  results.push(...await findPythonFilesRecursive(fullPath, rootDir));
7126
6586
  } else if (entry.isFile() && entry.name.endsWith(".py")) {
7127
- results.push((0, import_path8.relative)(rootDir, fullPath).replace(/\\/g, "/"));
6587
+ results.push((0, import_path7.relative)(rootDir, fullPath).replace(/\\/g, "/"));
7128
6588
  }
7129
6589
  }
7130
6590
  return results;
@@ -7134,8 +6594,8 @@ async function findEntrypointCandidates(workPath) {
7134
6594
  const candidates = [];
7135
6595
  for (const relPath of pyFiles) {
7136
6596
  try {
7137
- const content = await import_fs8.default.promises.readFile(
7138
- (0, import_path8.join)(workPath, relPath),
6597
+ const content = await import_fs7.default.promises.readFile(
6598
+ (0, import_path7.join)(workPath, relPath),
7139
6599
  "utf-8"
7140
6600
  );
7141
6601
  const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
@@ -7170,24 +6630,24 @@ async function resolveModuleAttrEntrypoint(workPath, value) {
7170
6630
  const relPath = modulePath.replace(/\./g, "/");
7171
6631
  const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
7172
6632
  for (const candidate of candidates) {
7173
- if (await fileExists((0, import_path8.join)(workPath, candidate))) {
6633
+ if (await fileExists((0, import_path7.join)(workPath, candidate))) {
7174
6634
  return { entrypoint: candidate, variableName };
7175
6635
  }
7176
6636
  }
7177
6637
  return null;
7178
6638
  }
7179
6639
  async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7180
- const pyprojectPath = (0, import_path8.join)(workPath, "pyproject.toml");
7181
- const pyprojectData = await (0, import_build_utils11.readConfigFile)(pyprojectPath);
6640
+ const pyprojectPath = (0, import_path7.join)(workPath, "pyproject.toml");
6641
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)(pyprojectPath);
7182
6642
  if (!pyprojectData)
7183
6643
  return null;
7184
6644
  const vercelEntrypoint = pyprojectData.tool?.vercel?.entrypoint;
7185
6645
  if (vercelEntrypoint === void 0)
7186
6646
  return null;
7187
- const relPyprojectPath = (0, import_path8.relative)(repoRootPath ?? workPath, pyprojectPath);
6647
+ const relPyprojectPath = (0, import_path7.relative)(repoRootPath ?? workPath, pyprojectPath);
7188
6648
  const displayPath = !relPyprojectPath || relPyprojectPath.startsWith("..") ? pyprojectPath : relPyprojectPath;
7189
6649
  if (typeof vercelEntrypoint !== "string") {
7190
- throw new import_build_utils9.NowBuildError({
6650
+ throw new import_build_utils8.NowBuildError({
7191
6651
  code: "PYTHON_INVALID_ENTRYPOINT",
7192
6652
  message: `"tool.vercel.entrypoint" in "${displayPath}" must be a string in "module:object" format (e.g. "main:app").`,
7193
6653
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7199,7 +6659,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7199
6659
  vercelEntrypoint
7200
6660
  );
7201
6661
  if (!resolved) {
7202
- throw new import_build_utils9.NowBuildError({
6662
+ throw new import_build_utils8.NowBuildError({
7203
6663
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7204
6664
  message: `"tool.vercel.entrypoint" in "${displayPath}" is "${vercelEntrypoint}" but no matching module file was found. Use "module:object" format (e.g. "main:app") and ensure the module file exists, or remove the setting to use automatic entrypoint detection.`,
7205
6665
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7209,7 +6669,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7209
6669
  return resolved;
7210
6670
  }
7211
6671
  async function getPyprojectEntrypointWithDiagnostics(workPath) {
7212
- const pyprojectData = await (0, import_build_utils11.readConfigFile)((0, import_path8.join)(workPath, "pyproject.toml"));
6672
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
7213
6673
  if (!pyprojectData)
7214
6674
  return { entrypoint: null };
7215
6675
  const scripts = pyprojectData.project?.scripts;
@@ -7224,7 +6684,7 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
7224
6684
  const relPath = modulePath.replace(/\./g, "/");
7225
6685
  const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
7226
6686
  for (const candidate of candidates) {
7227
- if (await fileExists((0, import_path8.join)(workPath, candidate))) {
6687
+ if (await fileExists((0, import_path7.join)(workPath, candidate))) {
7228
6688
  return { entrypoint: { entrypoint: candidate, variableName } };
7229
6689
  }
7230
6690
  }
@@ -7233,13 +6693,13 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
7233
6693
  async function findValidEntrypoint(workPath, candidates) {
7234
6694
  const existingWithoutEntrypoint = [];
7235
6695
  for (const candidate of candidates) {
7236
- const absPath = (0, import_path8.join)(workPath, candidate);
6696
+ const absPath = (0, import_path7.join)(workPath, candidate);
7237
6697
  if (!await fileExists(absPath))
7238
6698
  continue;
7239
- const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
6699
+ const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
7240
6700
  const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
7241
6701
  if (varName) {
7242
- (0, import_build_utils10.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
6702
+ (0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
7243
6703
  return {
7244
6704
  entrypoint: { entrypoint: candidate, variableName: varName },
7245
6705
  existingWithoutEntrypoint
@@ -7250,12 +6710,12 @@ async function findValidEntrypoint(workPath, candidates) {
7250
6710
  return { entrypoint: null, existingWithoutEntrypoint };
7251
6711
  }
7252
6712
  async function checkDjangoManage(workPath) {
7253
- const managePath = (0, import_path8.join)(workPath, "manage.py");
6713
+ const managePath = (0, import_path7.join)(workPath, "manage.py");
7254
6714
  try {
7255
- const content = await import_fs8.default.promises.readFile(managePath, "utf-8");
6715
+ const content = await import_fs7.default.promises.readFile(managePath, "utf-8");
7256
6716
  if (!content.includes("DJANGO_SETTINGS_MODULE"))
7257
6717
  return false;
7258
- (0, import_build_utils10.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
6718
+ (0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
7259
6719
  return true;
7260
6720
  } catch {
7261
6721
  return false;
@@ -7263,7 +6723,7 @@ async function checkDjangoManage(workPath) {
7263
6723
  }
7264
6724
  async function getSubdirectories(workPath) {
7265
6725
  try {
7266
- const entries = await import_fs8.default.promises.readdir(workPath, {
6726
+ const entries = await import_fs7.default.promises.readdir(workPath, {
7267
6727
  withFileTypes: true
7268
6728
  });
7269
6729
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
@@ -7308,7 +6768,7 @@ ${suggestion}`;
7308
6768
  const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
7309
6769
  message = `No ${displayName} entrypoint found. Set "tool.vercel.entrypoint" in pyproject.toml or define an entrypoint in one of: ${searchedList}.`;
7310
6770
  }
7311
- return new import_build_utils9.NowBuildError({ code, message, link, action });
6771
+ return new import_build_utils8.NowBuildError({ code, message, link, action });
7312
6772
  }
7313
6773
  async function detectGenericPythonEntrypoint(workPath) {
7314
6774
  try {
@@ -7321,7 +6781,7 @@ async function detectGenericPythonEntrypoint(workPath) {
7321
6781
  findDiagnostics: result
7322
6782
  };
7323
6783
  } catch {
7324
- (0, import_build_utils10.debug)("Failed to discover Python entrypoint");
6784
+ (0, import_build_utils9.debug)("Failed to discover Python entrypoint");
7325
6785
  return {
7326
6786
  detected: null,
7327
6787
  findDiagnostics: { entrypoint: null, existingWithoutEntrypoint: [] }
@@ -7340,7 +6800,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
7340
6800
  const subdirs = await getSubdirectories(workPath);
7341
6801
  const rootDirs = ["", ...subdirs];
7342
6802
  for (const rootDir of rootDirs) {
7343
- const currPath = (0, import_path8.join)(workPath, rootDir);
6803
+ const currPath = (0, import_path7.join)(workPath, rootDir);
7344
6804
  const isDjango = await checkDjangoManage(currPath);
7345
6805
  if (isDjango) {
7346
6806
  return {
@@ -7356,7 +6816,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
7356
6816
  findDiagnostics: result
7357
6817
  };
7358
6818
  } catch {
7359
- (0, import_build_utils10.debug)("Failed to discover Django Python entrypoint");
6819
+ (0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
7360
6820
  return emptyResult;
7361
6821
  }
7362
6822
  }
@@ -7364,10 +6824,10 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
7364
6824
  if (configuredEntrypoint) {
7365
6825
  const { filePath: configEntryFile, varName: configEntryVar } = configuredEntrypoint;
7366
6826
  const entrypoint = configEntryFile.endsWith(".py") ? configEntryFile : `${configEntryFile}.py`;
7367
- const entrypointExists = await fileExists((0, import_path8.join)(workPath, entrypoint));
6827
+ const entrypointExists = await fileExists((0, import_path7.join)(workPath, entrypoint));
7368
6828
  if (!entrypointExists) {
7369
6829
  return {
7370
- error: new import_build_utils9.NowBuildError({
6830
+ error: new import_build_utils8.NowBuildError({
7371
6831
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7372
6832
  message: `Configured Python entrypoint "${entrypoint}" was not found.`,
7373
6833
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7377,17 +6837,17 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
7377
6837
  }
7378
6838
  let varName = configEntryVar ?? await checkEntrypoint(workPath, entrypoint);
7379
6839
  if (!varName) {
7380
- const needsDynamicApp = !!service && ((0, import_build_utils9.isScheduleTriggeredService)(service) || (0, import_build_utils9.isQueueTriggeredService)(service) || (0, import_build_utils9.isWorkflowTriggeredService)(service));
6840
+ const needsDynamicApp = !!service && ((0, import_build_utils8.isScheduleTriggeredService)(service) || (0, import_build_utils8.isQueueTriggeredService)(service) || (0, import_build_utils8.isWorkflowTriggeredService)(service));
7381
6841
  if (needsDynamicApp) {
7382
6842
  varName = "app";
7383
6843
  }
7384
6844
  }
7385
6845
  if (varName) {
7386
- (0, import_build_utils10.debug)(`Using configured Python entrypoint: ${entrypoint}`);
6846
+ (0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
7387
6847
  return { entrypoint: { entrypoint, variableName: varName } };
7388
6848
  } else {
7389
6849
  return {
7390
- error: new import_build_utils9.NowBuildError({
6850
+ error: new import_build_utils8.NowBuildError({
7391
6851
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7392
6852
  message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
7393
6853
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7437,7 +6897,7 @@ var detectEntrypoint = async ({
7437
6897
  workPath,
7438
6898
  framework
7439
6899
  }) => {
7440
- if (!(0, import_build_utils9.isPythonFramework)(framework))
6900
+ if (!(0, import_build_utils8.isPythonFramework)(framework))
7441
6901
  return null;
7442
6902
  let detected;
7443
6903
  try {
@@ -7446,7 +6906,7 @@ var detectEntrypoint = async ({
7446
6906
  workPath
7447
6907
  );
7448
6908
  } catch (err) {
7449
- (0, import_build_utils10.debug)(
6909
+ (0, import_build_utils9.debug)(
7450
6910
  `Python entrypoint detection failed for ${workPath}: ${err instanceof Error ? err.message : String(err)}`
7451
6911
  );
7452
6912
  return null;
@@ -7462,8 +6922,8 @@ var detectEntrypoint = async ({
7462
6922
 
7463
6923
  // src/crons.ts
7464
6924
  var DYNAMIC_SCHEDULE = "<dynamic>";
7465
- var scriptPath = (0, import_path9.join)(__dirname, "..", "templates", "vc_cron_detect.py");
7466
- var script = import_fs9.default.readFileSync(scriptPath, "utf-8");
6925
+ var scriptPath = (0, import_path8.join)(__dirname, "..", "templates", "vc_cron_detect.py");
6926
+ var script = import_fs8.default.readFileSync(scriptPath, "utf-8");
7467
6927
  function buildCronRouteTable(crons) {
7468
6928
  const table = {};
7469
6929
  for (const cron of crons) {
@@ -7473,13 +6933,13 @@ function buildCronRouteTable(crons) {
7473
6933
  }
7474
6934
  async function getServiceCrons(opts) {
7475
6935
  const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
7476
- const isScheduledService = !!service && (0, import_build_utils12.isScheduleTriggeredService)(service);
6936
+ const isScheduledService = !!service && (0, import_build_utils11.isScheduleTriggeredService)(service);
7477
6937
  if (!isScheduledService || !service.name || typeof service.schedule !== "string" && !Array.isArray(service.schedule)) {
7478
6938
  return void 0;
7479
6939
  }
7480
6940
  const cronEntrypoint = entrypoint || rawEntrypoint;
7481
6941
  if (!cronEntrypoint) {
7482
- throw new import_build_utils12.NowBuildError({
6942
+ throw new import_build_utils11.NowBuildError({
7483
6943
  code: "PYTHON_CRON_NO_ENTRYPOINT",
7484
6944
  message: "Cron service is missing an entrypoint."
7485
6945
  });
@@ -7494,7 +6954,7 @@ async function getServiceCrons(opts) {
7494
6954
  workPath: opts.workPath
7495
6955
  });
7496
6956
  }
7497
- const cronPath = (0, import_build_utils12.getInternalServiceCronPath)(
6957
+ const cronPath = (0, import_build_utils11.getInternalServiceCronPath)(
7498
6958
  service.name,
7499
6959
  cronEntrypoint,
7500
6960
  handlerFunction || "cron"
@@ -7518,7 +6978,7 @@ async function getServiceCronsDynamic(opts) {
7518
6978
  workPath
7519
6979
  } = opts;
7520
6980
  if (!handlerFunction) {
7521
- throw new import_build_utils12.NowBuildError({
6981
+ throw new import_build_utils11.NowBuildError({
7522
6982
  code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
7523
6983
  message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
7524
6984
  });
@@ -7535,7 +6995,7 @@ async function getServiceCronsDynamic(opts) {
7535
6995
  `Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
7536
6996
  );
7537
6997
  if (entries.length === 0) {
7538
- throw new import_build_utils12.NowBuildError({
6998
+ throw new import_build_utils11.NowBuildError({
7539
6999
  code: "PYTHON_DYNAMIC_CRON_EMPTY",
7540
7000
  message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
7541
7001
  });
@@ -7556,7 +7016,7 @@ async function detectDynamicCrons(opts) {
7556
7016
  const { pythonBin, env, workPath, moduleName, attrName } = opts;
7557
7017
  let stdout;
7558
7018
  try {
7559
- const result = await (0, import_execa5.default)(
7019
+ const result = await (0, import_execa4.default)(
7560
7020
  pythonBin,
7561
7021
  ["-c", script, moduleName, attrName],
7562
7022
  { env, cwd: workPath }
@@ -7570,7 +7030,7 @@ async function detectDynamicCrons(opts) {
7570
7030
  detail = parsed2.error;
7571
7031
  } catch {
7572
7032
  }
7573
- throw new import_build_utils12.NowBuildError({
7033
+ throw new import_build_utils11.NowBuildError({
7574
7034
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
7575
7035
  message: `Failed to detect dynamic cron entries: ${detail}`
7576
7036
  });
@@ -7579,7 +7039,7 @@ async function detectDynamicCrons(opts) {
7579
7039
  try {
7580
7040
  parsed = JSON.parse(stdout);
7581
7041
  } catch {
7582
- throw new import_build_utils12.NowBuildError({
7042
+ throw new import_build_utils11.NowBuildError({
7583
7043
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
7584
7044
  message: `Dynamic cron detection returned invalid JSON: ${stdout}`
7585
7045
  });
@@ -7589,7 +7049,7 @@ async function detectDynamicCrons(opts) {
7589
7049
  function moduleColonFuncToCronPath(serviceName, moduleFunction) {
7590
7050
  const colonIdx = moduleFunction.indexOf(":");
7591
7051
  if (colonIdx === -1) {
7592
- throw new import_build_utils12.NowBuildError({
7052
+ throw new import_build_utils11.NowBuildError({
7593
7053
  code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
7594
7054
  message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
7595
7055
  });
@@ -7597,14 +7057,14 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
7597
7057
  const modulePart = moduleFunction.slice(0, colonIdx);
7598
7058
  const funcPart = moduleFunction.slice(colonIdx + 1);
7599
7059
  const entrypointPath = modulePart.replace(/\./g, "/");
7600
- return (0, import_build_utils12.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
7060
+ return (0, import_build_utils11.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
7601
7061
  }
7602
7062
 
7603
7063
  // src/start-dev-server.ts
7604
7064
  var import_child_process2 = require("child_process");
7605
- var import_fs10 = require("fs");
7606
- var import_path10 = require("path");
7607
- var import_build_utils13 = require("@vercel/build-utils");
7065
+ var import_fs9 = require("fs");
7066
+ var import_path9 = require("path");
7067
+ var import_build_utils12 = require("@vercel/build-utils");
7608
7068
  var import_get_port = __toESM(require_get_port());
7609
7069
  var import_is_port_reachable = __toESM(require_is_port_reachable());
7610
7070
  var import_python_analysis6 = require("@vercel/python-analysis");
@@ -7710,17 +7170,17 @@ async function syncDependencies({
7710
7170
  let { manifestPath } = installInfo;
7711
7171
  const manifest = pythonPackage.manifest;
7712
7172
  if (!manifestType || !manifestPath) {
7713
- (0, import_build_utils13.debug)("No Python project manifest found, skipping dependency sync");
7173
+ (0, import_build_utils12.debug)("No Python project manifest found, skipping dependency sync");
7714
7174
  return;
7715
7175
  }
7716
7176
  if (manifest?.origin && manifestType === "pyproject.toml") {
7717
- const syncDir = (0, import_path10.join)(workPath, ".vercel", "python", "sync");
7718
- (0, import_fs10.mkdirSync)(syncDir, { recursive: true });
7719
- const tempPyproject = (0, import_path10.join)(syncDir, "pyproject.toml");
7177
+ const syncDir = (0, import_path9.join)(workPath, ".vercel", "python", "sync");
7178
+ (0, import_fs9.mkdirSync)(syncDir, { recursive: true });
7179
+ const tempPyproject = (0, import_path9.join)(syncDir, "pyproject.toml");
7720
7180
  const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
7721
- (0, import_fs10.writeFileSync)(tempPyproject, content, "utf8");
7181
+ (0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
7722
7182
  manifestPath = tempPyproject;
7723
- (0, import_build_utils13.debug)(
7183
+ (0, import_build_utils12.debug)(
7724
7184
  `Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
7725
7185
  );
7726
7186
  }
@@ -7753,7 +7213,7 @@ async function syncDependencies({
7753
7213
  for (const [channel, chunk] of captured) {
7754
7214
  (channel === "stdout" ? writeOut : writeErr)(chunk.toString());
7755
7215
  }
7756
- throw new import_build_utils13.NowBuildError({
7216
+ throw new import_build_utils12.NowBuildError({
7757
7217
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
7758
7218
  message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
7759
7219
  });
@@ -7768,14 +7228,14 @@ async function runSync({
7768
7228
  onStdout,
7769
7229
  onStderr
7770
7230
  }) {
7771
- const projectDir = (0, import_path10.dirname)(manifestPath);
7231
+ const projectDir = (0, import_path9.dirname)(manifestPath);
7772
7232
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
7773
7233
  let spawnCmd;
7774
7234
  let spawnArgs;
7775
7235
  switch (manifestType) {
7776
7236
  case "uv.lock": {
7777
7237
  if (!uvPath) {
7778
- throw new import_build_utils13.NowBuildError({
7238
+ throw new import_build_utils12.NowBuildError({
7779
7239
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
7780
7240
  message: "uv is required to install dependencies from uv.lock.",
7781
7241
  link: "https://docs.astral.sh/uv/getting-started/installation/",
@@ -7797,11 +7257,11 @@ async function runSync({
7797
7257
  break;
7798
7258
  }
7799
7259
  default:
7800
- (0, import_build_utils13.debug)(`Unknown manifest type: ${manifestType}`);
7260
+ (0, import_build_utils12.debug)(`Unknown manifest type: ${manifestType}`);
7801
7261
  return;
7802
7262
  }
7803
7263
  await new Promise((resolve3, reject) => {
7804
- (0, import_build_utils13.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
7264
+ (0, import_build_utils12.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
7805
7265
  const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
7806
7266
  cwd: projectDir,
7807
7267
  env: getProtectedUvEnv(env),
@@ -7840,7 +7300,7 @@ var COMPLETED_INSTALLS = /* @__PURE__ */ new Set();
7840
7300
  function hasInstalledDistribution(targetDir, packageName) {
7841
7301
  const prefix = `${packageName.replace("-", "_")}-`;
7842
7302
  try {
7843
- return (0, import_fs10.readdirSync)(targetDir).some(
7303
+ return (0, import_fs9.readdirSync)(targetDir).some(
7844
7304
  (entry) => entry.startsWith(prefix) && entry.endsWith(".dist-info")
7845
7305
  );
7846
7306
  } catch {
@@ -7848,7 +7308,7 @@ function hasInstalledDistribution(targetDir, packageName) {
7848
7308
  }
7849
7309
  }
7850
7310
  async function installInjectedDevPackage(pkg, opts) {
7851
- const targetDir = (0, import_path10.join)(opts.workPath, ".vercel", "python");
7311
+ const targetDir = (0, import_path9.join)(opts.workPath, ".vercel", "python");
7852
7312
  const source = pkg.envOverride || pkg.pinnedVersion;
7853
7313
  const key = `${targetDir}:${pkg.name}:${source}`;
7854
7314
  if (COMPLETED_INSTALLS.has(key) && hasInstalledDistribution(targetDir, pkg.name)) {
@@ -7862,22 +7322,22 @@ async function installInjectedDevPackage(pkg, opts) {
7862
7322
  }
7863
7323
  async function doInstallInjectedDevPackage(pkg, opts) {
7864
7324
  const { targetDir, workPath, uvPath, pythonBin, env, onStdout, onStderr } = opts;
7865
- (0, import_fs10.mkdirSync)(targetDir, { recursive: true });
7866
- const localDir = (0, import_path10.join)(__dirname, "..", "..", "..", "python", pkg.name);
7867
- const isLocalDev = (0, import_fs10.existsSync)((0, import_path10.join)(localDir, "pyproject.toml"));
7325
+ (0, import_fs9.mkdirSync)(targetDir, { recursive: true });
7326
+ const localDir = (0, import_path9.join)(__dirname, "..", "..", "..", "python", pkg.name);
7327
+ const isLocalDev = (0, import_fs9.existsSync)((0, import_path9.join)(localDir, "pyproject.toml"));
7868
7328
  const dep = pkg.envOverride || (isLocalDev ? localDir : `${pkg.name}==${pkg.pinnedVersion}`);
7869
7329
  if (!isLocalDev && !pkg.envOverride) {
7870
7330
  const distInfoName = pkg.name.replace("-", "_");
7871
- const distInfo = (0, import_path10.join)(
7331
+ const distInfo = (0, import_path9.join)(
7872
7332
  targetDir,
7873
7333
  `${distInfoName}-${pkg.pinnedVersion}.dist-info`
7874
7334
  );
7875
- if ((0, import_fs10.existsSync)(distInfo)) {
7876
- (0, import_build_utils13.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
7335
+ if ((0, import_fs9.existsSync)(distInfo)) {
7336
+ (0, import_build_utils12.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
7877
7337
  return;
7878
7338
  }
7879
7339
  }
7880
- (0, import_build_utils13.debug)(
7340
+ (0, import_build_utils12.debug)(
7881
7341
  `Installing ${pkg.name} into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${dep})`
7882
7342
  );
7883
7343
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
@@ -7899,14 +7359,14 @@ async function doInstallInjectedDevPackage(pkg, opts) {
7899
7359
  if (onStdout) {
7900
7360
  onStdout(data);
7901
7361
  } else {
7902
- (0, import_build_utils13.debug)(data.toString());
7362
+ (0, import_build_utils12.debug)(data.toString());
7903
7363
  }
7904
7364
  });
7905
7365
  child.stderr?.on("data", (data) => {
7906
7366
  if (onStderr) {
7907
7367
  onStderr(data);
7908
7368
  } else {
7909
- (0, import_build_utils13.debug)(data.toString());
7369
+ (0, import_build_utils12.debug)(data.toString());
7910
7370
  }
7911
7371
  });
7912
7372
  child.on("error", reject);
@@ -7936,12 +7396,12 @@ function installGlobalCleanupHandlers() {
7936
7396
  try {
7937
7397
  process.kill(info.pid, "SIGTERM");
7938
7398
  } catch (err) {
7939
- (0, import_build_utils13.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
7399
+ (0, import_build_utils12.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
7940
7400
  }
7941
7401
  try {
7942
7402
  process.kill(info.pid, "SIGKILL");
7943
7403
  } catch (err) {
7944
- (0, import_build_utils13.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
7404
+ (0, import_build_utils12.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
7945
7405
  }
7946
7406
  PERSISTENT_SERVERS.delete(key);
7947
7407
  }
@@ -7949,7 +7409,7 @@ function installGlobalCleanupHandlers() {
7949
7409
  try {
7950
7410
  restoreWarnings();
7951
7411
  } catch (err) {
7952
- (0, import_build_utils13.debug)(`Error restoring warnings: ${err}`);
7412
+ (0, import_build_utils12.debug)(`Error restoring warnings: ${err}`);
7953
7413
  }
7954
7414
  restoreWarnings = null;
7955
7415
  }
@@ -7966,46 +7426,46 @@ function installGlobalCleanupHandlers() {
7966
7426
  }
7967
7427
  function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
7968
7428
  try {
7969
- const vercelPythonDir = serviceName ? (0, import_path10.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path10.join)(workPath, ".vercel", "python");
7970
- (0, import_fs10.mkdirSync)(vercelPythonDir, { recursive: true });
7429
+ const vercelPythonDir = serviceName ? (0, import_path9.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path9.join)(workPath, ".vercel", "python");
7430
+ (0, import_fs9.mkdirSync)(vercelPythonDir, { recursive: true });
7971
7431
  let qualifiedModule = modulePath;
7972
7432
  let extraPythonPath;
7973
- if ((0, import_fs10.existsSync)((0, import_path10.join)(workPath, "__init__.py"))) {
7974
- const pkgName = (0, import_path10.basename)(workPath);
7433
+ if ((0, import_fs9.existsSync)((0, import_path9.join)(workPath, "__init__.py"))) {
7434
+ const pkgName = (0, import_path9.basename)(workPath);
7975
7435
  qualifiedModule = `${pkgName}.${modulePath}`;
7976
- extraPythonPath = (0, import_path10.dirname)(workPath);
7436
+ extraPythonPath = (0, import_path9.dirname)(workPath);
7977
7437
  }
7978
- const entryAbs = (0, import_path10.join)(workPath, entry);
7979
- const shimPath = (0, import_path10.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
7980
- const templatePath = (0, import_path10.join)(
7438
+ const entryAbs = (0, import_path9.join)(workPath, entry);
7439
+ const shimPath = (0, import_path9.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
7440
+ const templatePath = (0, import_path9.join)(
7981
7441
  __dirname,
7982
7442
  "..",
7983
7443
  "templates",
7984
7444
  `${DEV_SHIM_MODULE}.py`
7985
7445
  );
7986
- const template = (0, import_fs10.readFileSync)(templatePath, "utf8");
7446
+ const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
7987
7447
  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);
7988
- (0, import_fs10.writeFileSync)(shimPath, shimSource, "utf8");
7989
- (0, import_build_utils13.debug)(`Prepared Python dev shim at ${shimPath}`);
7448
+ (0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
7449
+ (0, import_build_utils12.debug)(`Prepared Python dev shim at ${shimPath}`);
7990
7450
  return {
7991
7451
  module: DEV_SHIM_MODULE,
7992
7452
  extraPythonPath,
7993
7453
  shimDir: vercelPythonDir
7994
7454
  };
7995
7455
  } catch (err) {
7996
- (0, import_build_utils13.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
7456
+ (0, import_build_utils12.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
7997
7457
  return null;
7998
7458
  }
7999
7459
  }
8000
7460
  async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
8001
- const venvPath = (0, import_path10.join)(workPath, ".venv");
7461
+ const venvPath = (0, import_path9.join)(workPath, ".venv");
8002
7462
  const pendingCreation = PENDING_MANAGED_VENV_CREATIONS.get(venvPath);
8003
7463
  if (pendingCreation) {
8004
7464
  await pendingCreation;
8005
7465
  }
8006
7466
  const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
8007
7467
  if (venvRoot) {
8008
- (0, import_build_utils13.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
7468
+ (0, import_build_utils12.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
8009
7469
  return { command: pythonCmd, args: [] };
8010
7470
  }
8011
7471
  await dedupePendingOperation(
@@ -8018,11 +7478,11 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
8018
7478
  quiet: true
8019
7479
  })
8020
7480
  );
8021
- (0, import_build_utils13.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
7481
+ (0, import_build_utils12.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
8022
7482
  const pythonBin = getVenvPythonBin(venvPath);
8023
7483
  const binDir = getVenvBinDir(venvPath);
8024
7484
  env.VIRTUAL_ENV = venvPath;
8025
- env.PATH = `${binDir}${import_path10.delimiter}${env.PATH || ""}`;
7485
+ env.PATH = `${binDir}${import_path9.delimiter}${env.PATH || ""}`;
8026
7486
  return { command: pythonBin, args: [] };
8027
7487
  }
8028
7488
  var startDevServer = async (opts) => {
@@ -8085,7 +7545,7 @@ var startDevServer = async (opts) => {
8085
7545
  filePath: entrypoint,
8086
7546
  // Schedule-triggered services create their own "app" wrapper dynamically.
8087
7547
  // Other services use handlerFunction as the entrypoint variable name.
8088
- varName: service && (0, import_build_utils13.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
7548
+ varName: service && (0, import_build_utils12.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
8089
7549
  } : void 0,
8090
7550
  service,
8091
7551
  opts.repoRootPath
@@ -8107,7 +7567,7 @@ var startDevServer = async (opts) => {
8107
7567
  if (detected?.error) {
8108
7568
  throw detected.error;
8109
7569
  }
8110
- throw new import_build_utils13.NowBuildError({
7570
+ throw new import_build_utils12.NowBuildError({
8111
7571
  code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
8112
7572
  message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
8113
7573
  });
@@ -8139,7 +7599,7 @@ var startDevServer = async (opts) => {
8139
7599
  const yellow = "\x1B[33m";
8140
7600
  const white = "\x1B[1m";
8141
7601
  const reset = "\x1B[0m";
8142
- throw new import_build_utils13.NowBuildError({
7602
+ throw new import_build_utils12.NowBuildError({
8143
7603
  code: "PYTHON_EXTERNAL_VENV_DETECTED",
8144
7604
  message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
8145
7605
  Run ${white}deactivate${reset} and try again.`
@@ -8156,11 +7616,11 @@ Run ${white}deactivate${reset} and try again.`
8156
7616
  );
8157
7617
  spawnCommand = runner.command;
8158
7618
  spawnArgsPrefix = runner.args;
8159
- (0, import_build_utils13.debug)(
7619
+ (0, import_build_utils12.debug)(
8160
7620
  `Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
8161
7621
  );
8162
7622
  } else if (venv) {
8163
- (0, import_build_utils13.debug)(`Running in virtualenv at ${venv}`);
7623
+ (0, import_build_utils12.debug)(`Running in virtualenv at ${venv}`);
8164
7624
  } else {
8165
7625
  const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
8166
7626
  workPath,
@@ -8169,9 +7629,9 @@ Run ${white}deactivate${reset} and try again.`
8169
7629
  );
8170
7630
  spawnCommand = venvPythonCmd;
8171
7631
  if (venvRoot) {
8172
- (0, import_build_utils13.debug)(`Using virtualenv at ${venvRoot}`);
7632
+ (0, import_build_utils12.debug)(`Using virtualenv at ${venvRoot}`);
8173
7633
  } else {
8174
- (0, import_build_utils13.debug)("No virtualenv found");
7634
+ (0, import_build_utils12.debug)("No virtualenv found");
8175
7635
  try {
8176
7636
  const yellow = "\x1B[33m";
8177
7637
  const reset = "\x1B[0m";
@@ -8242,7 +7702,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
8242
7702
  const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
8243
7703
  env.PORT = `${port}`;
8244
7704
  if (entry) {
8245
- env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path10.join)(workPath, entry);
7705
+ env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path9.join)(workPath, entry);
8246
7706
  }
8247
7707
  const devShim = createDevShim(
8248
7708
  workPath,
@@ -8253,8 +7713,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
8253
7713
  variableName ?? ""
8254
7714
  );
8255
7715
  if (devShim) {
8256
- const shimDir = devShim.shimDir || (0, import_path10.join)(workPath, ".vercel", "python");
8257
- const runtimeDir = (0, import_path10.join)(workPath, ".vercel", "python");
7716
+ const shimDir = devShim.shimDir || (0, import_path9.join)(workPath, ".vercel", "python");
7717
+ const runtimeDir = (0, import_path9.join)(workPath, ".vercel", "python");
8258
7718
  const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
8259
7719
  if (devShim.extraPythonPath) {
8260
7720
  pathParts.push(devShim.extraPythonPath);
@@ -8266,12 +7726,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
8266
7726
  if (existingPythonPath) {
8267
7727
  pathParts.push(existingPythonPath);
8268
7728
  }
8269
- env.PYTHONPATH = pathParts.join(import_path10.delimiter);
7729
+ env.PYTHONPATH = pathParts.join(import_path9.delimiter);
8270
7730
  }
8271
7731
  const moduleToRun = devShim?.module || modulePath;
8272
7732
  const pythonArgs = ["-u", "-m", moduleToRun];
8273
7733
  const argv = [...spawnArgsPrefix, ...pythonArgs];
8274
- (0, import_build_utils13.debug)(
7734
+ (0, import_build_utils12.debug)(
8275
7735
  `Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
8276
7736
  );
8277
7737
  if (process.stdout.columns) {
@@ -8325,7 +7785,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
8325
7785
  };
8326
7786
 
8327
7787
  // src/quirks/index.ts
8328
- var import_build_utils16 = require("@vercel/build-utils");
7788
+ var import_build_utils15 = require("@vercel/build-utils");
8329
7789
  var import_python_analysis8 = require("@vercel/python-analysis");
8330
7790
 
8331
7791
  // src/quirks/matplotlib.ts
@@ -8339,9 +7799,9 @@ var matplotlibQuirk = {
8339
7799
  };
8340
7800
 
8341
7801
  // src/quirks/litellm.ts
8342
- var import_fs11 = __toESM(require("fs"));
8343
- var import_path11 = require("path");
8344
- var import_build_utils14 = require("@vercel/build-utils");
7802
+ var import_fs10 = __toESM(require("fs"));
7803
+ var import_path10 = require("path");
7804
+ var import_build_utils13 = require("@vercel/build-utils");
8345
7805
  var LAMBDA_ROOT = "/var/task";
8346
7806
  var CONFIG_CANDIDATES = [
8347
7807
  "litellm_config.yaml",
@@ -8351,9 +7811,9 @@ var CONFIG_CANDIDATES = [
8351
7811
  ];
8352
7812
  async function findConfigFile(workPath) {
8353
7813
  for (const name of CONFIG_CANDIDATES) {
8354
- const candidate = (0, import_path11.join)(workPath, name);
7814
+ const candidate = (0, import_path10.join)(workPath, name);
8355
7815
  try {
8356
- await import_fs11.default.promises.access(candidate);
7816
+ await import_fs10.default.promises.access(candidate);
8357
7817
  return name;
8358
7818
  } catch {
8359
7819
  }
@@ -8368,32 +7828,32 @@ var litellmQuirk = {
8368
7828
  const env = {};
8369
7829
  const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
8370
7830
  for (const sitePackages of sitePackagesDirs) {
8371
- const schemaPath = (0, import_path11.join)(
7831
+ const schemaPath = (0, import_path10.join)(
8372
7832
  sitePackages,
8373
7833
  "litellm",
8374
7834
  "proxy",
8375
7835
  "schema.prisma"
8376
7836
  );
8377
7837
  try {
8378
- await import_fs11.default.promises.access(schemaPath);
8379
- (0, import_build_utils14.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
7838
+ await import_fs10.default.promises.access(schemaPath);
7839
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
8380
7840
  buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
8381
7841
  break;
8382
7842
  } catch {
8383
7843
  }
8384
7844
  }
8385
7845
  if (!buildEnv.PRISMA_SCHEMA_PATH) {
8386
- (0, import_build_utils14.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
7846
+ (0, import_build_utils13.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
8387
7847
  }
8388
7848
  if (!process.env.CONFIG_FILE_PATH) {
8389
7849
  const configName = await findConfigFile(ctx.workPath);
8390
7850
  if (configName) {
8391
- (0, import_build_utils14.debug)(`LiteLLM quirk: found config at ${configName}`);
8392
- buildEnv.CONFIG_FILE_PATH = (0, import_path11.join)(ctx.workPath, configName);
8393
- env.CONFIG_FILE_PATH = (0, import_path11.join)(LAMBDA_ROOT, configName);
7851
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found config at ${configName}`);
7852
+ buildEnv.CONFIG_FILE_PATH = (0, import_path10.join)(ctx.workPath, configName);
7853
+ env.CONFIG_FILE_PATH = (0, import_path10.join)(LAMBDA_ROOT, configName);
8394
7854
  }
8395
7855
  } else {
8396
- (0, import_build_utils14.debug)(
7856
+ (0, import_build_utils13.debug)(
8397
7857
  `LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
8398
7858
  );
8399
7859
  }
@@ -8402,10 +7862,10 @@ var litellmQuirk = {
8402
7862
  };
8403
7863
 
8404
7864
  // src/quirks/prisma.ts
8405
- var import_fs12 = __toESM(require("fs"));
8406
- var import_path12 = require("path");
8407
- var import_execa6 = __toESM(require_execa());
8408
- var import_build_utils15 = require("@vercel/build-utils");
7865
+ var import_fs11 = __toESM(require("fs"));
7866
+ var import_path11 = require("path");
7867
+ var import_execa5 = __toESM(require_execa());
7868
+ var import_build_utils14 = require("@vercel/build-utils");
8409
7869
  var import_python_analysis7 = require("@vercel/python-analysis");
8410
7870
  function execErrorMessage(err) {
8411
7871
  if (err != null && typeof err === "object" && "stderr" in err) {
@@ -8443,22 +7903,22 @@ model DummyModel {
8443
7903
  async function findUserSchema(workPath) {
8444
7904
  const envPath = process.env.PRISMA_SCHEMA_PATH;
8445
7905
  if (envPath) {
8446
- const resolved = (0, import_path12.isAbsolute)(envPath) ? envPath : (0, import_path12.join)(workPath, envPath);
7906
+ const resolved = (0, import_path11.isAbsolute)(envPath) ? envPath : (0, import_path11.join)(workPath, envPath);
8447
7907
  try {
8448
- await import_fs12.default.promises.access(resolved);
7908
+ await import_fs11.default.promises.access(resolved);
8449
7909
  return resolved;
8450
7910
  } catch {
8451
- (0, import_build_utils15.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
7911
+ (0, import_build_utils14.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
8452
7912
  return null;
8453
7913
  }
8454
7914
  }
8455
7915
  const candidates = [
8456
- (0, import_path12.join)(workPath, "schema.prisma"),
8457
- (0, import_path12.join)(workPath, "prisma", "schema.prisma")
7916
+ (0, import_path11.join)(workPath, "schema.prisma"),
7917
+ (0, import_path11.join)(workPath, "prisma", "schema.prisma")
8458
7918
  ];
8459
7919
  for (const candidate of candidates) {
8460
7920
  try {
8461
- await import_fs12.default.promises.access(candidate);
7921
+ await import_fs11.default.promises.access(candidate);
8462
7922
  return candidate;
8463
7923
  } catch {
8464
7924
  }
@@ -8469,32 +7929,32 @@ async function collectFiles(dir, base) {
8469
7929
  const result = [];
8470
7930
  let entries;
8471
7931
  try {
8472
- entries = await import_fs12.default.promises.readdir(dir, { withFileTypes: true });
7932
+ entries = await import_fs11.default.promises.readdir(dir, { withFileTypes: true });
8473
7933
  } catch {
8474
7934
  return result;
8475
7935
  }
8476
7936
  for (const entry of entries) {
8477
7937
  if (entry.name === "__pycache__")
8478
7938
  continue;
8479
- const full = (0, import_path12.join)(dir, entry.name);
7939
+ const full = (0, import_path11.join)(dir, entry.name);
8480
7940
  if (entry.isDirectory()) {
8481
7941
  result.push(...await collectFiles(full, base));
8482
7942
  } else {
8483
- result.push((0, import_path12.relative)(base, full));
7943
+ result.push((0, import_path11.relative)(base, full));
8484
7944
  }
8485
7945
  }
8486
7946
  return result;
8487
7947
  }
8488
7948
  async function cleanCacheArtifacts(cacheDir, extras = []) {
8489
7949
  const paths = [
8490
- (0, import_path12.join)(cacheDir, "node_modules"),
8491
- (0, import_path12.join)(cacheDir, "package.json"),
8492
- (0, import_path12.join)(cacheDir, "package-lock.json"),
7950
+ (0, import_path11.join)(cacheDir, "node_modules"),
7951
+ (0, import_path11.join)(cacheDir, "package.json"),
7952
+ (0, import_path11.join)(cacheDir, "package-lock.json"),
8493
7953
  ...extras
8494
7954
  ];
8495
7955
  for (const p of paths) {
8496
7956
  try {
8497
- await import_fs12.default.promises.rm(p, { recursive: true, force: true });
7957
+ await import_fs11.default.promises.rm(p, { recursive: true, force: true });
8498
7958
  } catch (err) {
8499
7959
  console.warn(
8500
7960
  `could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
@@ -8504,7 +7964,7 @@ async function cleanCacheArtifacts(cacheDir, extras = []) {
8504
7964
  }
8505
7965
  async function isClientGenerated(pythonPath, env) {
8506
7966
  try {
8507
- await (0, import_execa6.default)(pythonPath, ["-c", "import prisma.client"], {
7967
+ await (0, import_execa5.default)(pythonPath, ["-c", "import prisma.client"], {
8508
7968
  env,
8509
7969
  stdio: "pipe"
8510
7970
  });
@@ -8518,7 +7978,7 @@ var prismaQuirk = {
8518
7978
  async run(ctx) {
8519
7979
  const { venvPath, pythonEnv, workPath } = ctx;
8520
7980
  const pythonPath = getVenvPythonBin(venvPath);
8521
- const runtimeCacheDir = (0, import_path12.join)(
7981
+ const runtimeCacheDir = (0, import_path11.join)(
8522
7982
  LAMBDA_ROOT2,
8523
7983
  resolveVendorDir(),
8524
7984
  "prisma",
@@ -8528,7 +7988,7 @@ var prismaQuirk = {
8528
7988
  let sitePackages;
8529
7989
  for (const dir of sitePackagesDirs) {
8530
7990
  try {
8531
- await import_fs12.default.promises.access((0, import_path12.join)(dir, "prisma"));
7991
+ await import_fs11.default.promises.access((0, import_path11.join)(dir, "prisma"));
8532
7992
  sitePackages = dir;
8533
7993
  break;
8534
7994
  } catch {
@@ -8540,21 +8000,21 @@ var prismaQuirk = {
8540
8000
  );
8541
8001
  return {};
8542
8002
  }
8543
- const cacheDir = (0, import_path12.join)(sitePackages, "prisma", "__bincache__");
8544
- await import_fs12.default.promises.mkdir(cacheDir, { recursive: true });
8003
+ const cacheDir = (0, import_path11.join)(sitePackages, "prisma", "__bincache__");
8004
+ await import_fs11.default.promises.mkdir(cacheDir, { recursive: true });
8545
8005
  const generateEnv = {
8546
8006
  ...pythonEnv,
8547
8007
  PRISMA_BINARY_CACHE_DIR: cacheDir
8548
8008
  };
8549
- const generatedDir = (0, import_path12.join)(workPath, "_prisma_generated");
8550
- const dummySchemaPath = (0, import_path12.join)(workPath, DUMMY_SCHEMA_NAME);
8551
- await import_fs12.default.promises.writeFile(
8009
+ const generatedDir = (0, import_path11.join)(workPath, "_prisma_generated");
8010
+ const dummySchemaPath = (0, import_path11.join)(workPath, DUMMY_SCHEMA_NAME);
8011
+ await import_fs11.default.promises.writeFile(
8552
8012
  dummySchemaPath,
8553
8013
  buildDummySchema(generatedDir)
8554
8014
  );
8555
- (0, import_build_utils15.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
8015
+ (0, import_build_utils14.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
8556
8016
  try {
8557
- const dummyResult = await (0, import_execa6.default)(
8017
+ const dummyResult = await (0, import_execa5.default)(
8558
8018
  pythonPath,
8559
8019
  ["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
8560
8020
  {
@@ -8564,11 +8024,11 @@ var prismaQuirk = {
8564
8024
  }
8565
8025
  );
8566
8026
  if (dummyResult.stdout)
8567
- (0, import_build_utils15.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
8027
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
8568
8028
  if (dummyResult.stderr)
8569
- (0, import_build_utils15.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
8029
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
8570
8030
  } catch (err) {
8571
- throw new import_build_utils15.NowBuildError({
8031
+ throw new import_build_utils14.NowBuildError({
8572
8032
  code: "PRISMA_GENERATE_FAILED",
8573
8033
  message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
8574
8034
  ` + execErrorMessage(err)
@@ -8576,47 +8036,47 @@ var prismaQuirk = {
8576
8036
  }
8577
8037
  const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
8578
8038
  const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
8579
- const nodeModulesDir = (0, import_path12.join)(cacheDir, "node_modules", "prisma");
8039
+ const nodeModulesDir = (0, import_path11.join)(cacheDir, "node_modules", "prisma");
8580
8040
  let engineCopied = false;
8581
8041
  try {
8582
- const entries = await import_fs12.default.promises.readdir(nodeModulesDir);
8042
+ const entries = await import_fs11.default.promises.readdir(nodeModulesDir);
8583
8043
  for (const entry of entries) {
8584
8044
  if (!entry.startsWith(srcBinaryPrefix))
8585
8045
  continue;
8586
- const srcPath = (0, import_path12.join)(nodeModulesDir, entry);
8587
- const destPath = (0, import_path12.join)(cacheDir, runtimeName);
8046
+ const srcPath = (0, import_path11.join)(nodeModulesDir, entry);
8047
+ const destPath = (0, import_path11.join)(cacheDir, runtimeName);
8588
8048
  try {
8589
- await import_fs12.default.promises.access(destPath);
8590
- (0, import_build_utils15.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
8049
+ await import_fs11.default.promises.access(destPath);
8050
+ (0, import_build_utils14.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
8591
8051
  } catch {
8592
- (0, import_build_utils15.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
8593
- await import_fs12.default.promises.copyFile(srcPath, destPath);
8052
+ (0, import_build_utils14.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
8053
+ await import_fs11.default.promises.copyFile(srcPath, destPath);
8594
8054
  }
8595
8055
  engineCopied = true;
8596
8056
  }
8597
8057
  } catch (err) {
8598
- throw new import_build_utils15.NowBuildError({
8058
+ throw new import_build_utils14.NowBuildError({
8599
8059
  code: "PRISMA_ENGINE_NOT_FOUND",
8600
8060
  message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
8601
8061
  ` + (err instanceof Error ? err.message : String(err))
8602
8062
  });
8603
8063
  }
8604
8064
  if (!engineCopied) {
8605
- throw new import_build_utils15.NowBuildError({
8065
+ throw new import_build_utils14.NowBuildError({
8606
8066
  code: "PRISMA_ENGINE_NOT_FOUND",
8607
8067
  message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
8608
8068
  });
8609
8069
  }
8610
- const shimPath = (0, import_path12.join)(cacheDir, "openssl");
8611
- await import_fs12.default.promises.writeFile(
8070
+ const shimPath = (0, import_path11.join)(cacheDir, "openssl");
8071
+ await import_fs11.default.promises.writeFile(
8612
8072
  shimPath,
8613
8073
  `#!/bin/sh
8614
8074
  echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
8615
8075
  `
8616
8076
  );
8617
- await import_fs12.default.promises.chmod(shimPath, 493);
8077
+ await import_fs11.default.promises.chmod(shimPath, 493);
8618
8078
  for (const p of [generatedDir, dummySchemaPath]) {
8619
- await import_fs12.default.promises.rm(p, { recursive: true, force: true });
8079
+ await import_fs11.default.promises.rm(p, { recursive: true, force: true });
8620
8080
  }
8621
8081
  await cleanCacheArtifacts(cacheDir);
8622
8082
  const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
@@ -8629,16 +8089,16 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8629
8089
  pythonEnv
8630
8090
  );
8631
8091
  if (clientAlreadyGenerated) {
8632
- (0, import_build_utils15.debug)(
8092
+ (0, import_build_utils14.debug)(
8633
8093
  "Prisma quirk: client already generated, skipping user schema generate"
8634
8094
  );
8635
8095
  shouldGenerate = false;
8636
8096
  }
8637
8097
  }
8638
8098
  if (shouldGenerate) {
8639
- (0, import_build_utils15.debug)(`Running prisma generate with user schema: ${userSchema}`);
8099
+ (0, import_build_utils14.debug)(`Running prisma generate with user schema: ${userSchema}`);
8640
8100
  try {
8641
- const userResult = await (0, import_execa6.default)(
8101
+ const userResult = await (0, import_execa5.default)(
8642
8102
  pythonPath,
8643
8103
  ["-m", "prisma", "generate", `--schema=${userSchema}`],
8644
8104
  {
@@ -8648,11 +8108,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8648
8108
  }
8649
8109
  );
8650
8110
  if (userResult.stdout)
8651
- (0, import_build_utils15.debug)(`prisma generate stdout: ${userResult.stdout}`);
8111
+ (0, import_build_utils14.debug)(`prisma generate stdout: ${userResult.stdout}`);
8652
8112
  if (userResult.stderr)
8653
- (0, import_build_utils15.debug)(`prisma generate stderr: ${userResult.stderr}`);
8113
+ (0, import_build_utils14.debug)(`prisma generate stderr: ${userResult.stderr}`);
8654
8114
  } catch (err) {
8655
- throw new import_build_utils15.NowBuildError({
8115
+ throw new import_build_utils14.NowBuildError({
8656
8116
  code: "PRISMA_GENERATE_FAILED",
8657
8117
  message: `\`prisma generate\` failed for schema "${userSchema}".
8658
8118
  ` + execErrorMessage(err)
@@ -8663,12 +8123,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8663
8123
  }
8664
8124
  try {
8665
8125
  const allFiles = await collectFiles(
8666
- (0, import_path12.join)(sitePackages, "prisma"),
8126
+ (0, import_path11.join)(sitePackages, "prisma"),
8667
8127
  sitePackages
8668
8128
  );
8669
8129
  const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
8670
8130
  if (count > 0) {
8671
- (0, import_build_utils15.debug)(`Appended ${count} entries to prisma RECORD`);
8131
+ (0, import_build_utils14.debug)(`Appended ${count} entries to prisma RECORD`);
8672
8132
  }
8673
8133
  } catch (err) {
8674
8134
  console.warn(
@@ -8762,13 +8222,13 @@ async function runQuirks(ctx) {
8762
8222
  (0, import_python_analysis8.normalizePackageName)(quirk.dependency)
8763
8223
  );
8764
8224
  if (!installed) {
8765
- (0, import_build_utils16.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
8225
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
8766
8226
  }
8767
8227
  return installed;
8768
8228
  });
8769
8229
  const sorted = toposortQuirks(activated);
8770
8230
  for (const quirk of sorted) {
8771
- (0, import_build_utils16.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
8231
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
8772
8232
  const result = await quirk.run(ctx);
8773
8233
  if (result.env) {
8774
8234
  Object.assign(mergedEnv, result.env);
@@ -8789,14 +8249,14 @@ async function runQuirks(ctx) {
8789
8249
  }
8790
8250
 
8791
8251
  // src/django.ts
8792
- var import_fs13 = __toESM(require("fs"));
8793
- var import_path13 = require("path");
8794
- var import_execa7 = __toESM(require_execa());
8795
- var import_build_utils17 = require("@vercel/build-utils");
8796
- var scriptPath2 = (0, import_path13.join)(__dirname, "..", "templates", "vc_django_settings.py");
8797
- var script2 = import_fs13.default.readFileSync(scriptPath2, "utf-8");
8252
+ var import_fs12 = __toESM(require("fs"));
8253
+ var import_path12 = require("path");
8254
+ var import_execa6 = __toESM(require_execa());
8255
+ var import_build_utils16 = require("@vercel/build-utils");
8256
+ var scriptPath2 = (0, import_path12.join)(__dirname, "..", "templates", "vc_django_settings.py");
8257
+ var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
8798
8258
  async function getDjangoSettings(projectDir, env) {
8799
- const { stdout } = await (0, import_execa7.default)("python", ["-c", script2], {
8259
+ const { stdout } = await (0, import_execa6.default)("python", ["-c", script2], {
8800
8260
  env,
8801
8261
  cwd: projectDir
8802
8262
  });
@@ -8822,21 +8282,21 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8822
8282
  const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
8823
8283
  const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
8824
8284
  const staticSourceDirs = [
8825
- ...installedApps.map((app) => (0, import_path13.join)(djangoPath, ...app.split("."), "static")),
8285
+ ...installedApps.map((app) => (0, import_path12.join)(djangoPath, ...app.split("."), "static")),
8826
8286
  // TODO: Deal with optional prefixes in STATICFILES_DIRS.
8827
8287
  ...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
8828
- ].filter((d) => import_fs13.default.existsSync(d));
8288
+ ].filter((d) => import_fs12.default.existsSync(d));
8829
8289
  if (storageBackend.startsWith("storages.backends.")) {
8830
8290
  console.log(
8831
8291
  "django-storages detected \u2014 running collectstatic with original settings"
8832
8292
  );
8833
- await (0, import_execa7.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8293
+ await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8834
8294
  env: { ...env, DJANGO_SETTINGS_MODULE: settingsModule },
8835
8295
  cwd: djangoPath
8836
8296
  });
8837
8297
  return {
8838
8298
  staticSourceDirs,
8839
- staticRoot: staticRoot ? (0, import_path13.resolve)(djangoPath, staticRoot) : null,
8299
+ staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
8840
8300
  cdnOutputDir: null,
8841
8301
  manifestRelPath: null
8842
8302
  };
@@ -8848,9 +8308,9 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8848
8308
  return null;
8849
8309
  }
8850
8310
  const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
8851
- const staticOutputDir = (0, import_path13.join)(outputStaticDir, staticUrlPath);
8852
- await import_fs13.default.promises.mkdir(staticOutputDir, { recursive: true });
8853
- const shimPath = (0, import_path13.join)(djangoPath, "_vercel_collectstatic_settings.py");
8311
+ const staticOutputDir = (0, import_path12.join)(outputStaticDir, staticUrlPath);
8312
+ await import_fs12.default.promises.mkdir(staticOutputDir, { recursive: true });
8313
+ const shimPath = (0, import_path12.join)(djangoPath, "_vercel_collectstatic_settings.py");
8854
8314
  const shimLines = [
8855
8315
  `from ${settingsModule} import *`,
8856
8316
  `STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
@@ -8858,10 +8318,10 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8858
8318
  if (whitenoiseUseFinders) {
8859
8319
  shimLines.push(`WHITENOISE_USE_FINDERS = False`);
8860
8320
  }
8861
- await import_fs13.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
8321
+ await import_fs12.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
8862
8322
  try {
8863
8323
  console.log("Running collectstatic...");
8864
- await (0, import_execa7.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8324
+ await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8865
8325
  env: {
8866
8326
  ...env,
8867
8327
  DJANGO_SETTINGS_MODULE: "_vercel_collectstatic_settings"
@@ -8869,7 +8329,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8869
8329
  cwd: djangoPath
8870
8330
  });
8871
8331
  } finally {
8872
- await import_fs13.default.promises.unlink(shimPath).catch(() => {
8332
+ await import_fs12.default.promises.unlink(shimPath).catch(() => {
8873
8333
  });
8874
8334
  }
8875
8335
  const MANIFEST_STORAGE_BACKENDS = [
@@ -8878,44 +8338,613 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8878
8338
  ];
8879
8339
  let manifestRelPath = null;
8880
8340
  if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
8881
- const manifestSrc = (0, import_path13.join)(staticOutputDir, "staticfiles.json");
8882
- const resolvedStaticRoot = (0, import_path13.resolve)(djangoPath, staticRoot);
8883
- const manifestDest = (0, import_path13.join)(resolvedStaticRoot, "staticfiles.json");
8884
- await import_fs13.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
8885
- await import_fs13.default.promises.copyFile(manifestSrc, manifestDest);
8886
- manifestRelPath = (0, import_path13.relative)(workPath, manifestDest);
8887
- (0, import_build_utils17.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
8341
+ const manifestSrc = (0, import_path12.join)(staticOutputDir, "staticfiles.json");
8342
+ const resolvedStaticRoot = (0, import_path12.resolve)(djangoPath, staticRoot);
8343
+ const manifestDest = (0, import_path12.join)(resolvedStaticRoot, "staticfiles.json");
8344
+ await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
8345
+ await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
8346
+ manifestRelPath = (0, import_path12.relative)(workPath, manifestDest);
8347
+ (0, import_build_utils16.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
8888
8348
  }
8889
8349
  return {
8890
8350
  staticSourceDirs,
8891
- staticRoot: staticRoot ? (0, import_path13.resolve)(djangoPath, staticRoot) : null,
8351
+ staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
8892
8352
  cdnOutputDir: outputStaticDir,
8893
8353
  manifestRelPath
8894
8354
  };
8895
8355
  }
8896
8356
 
8897
- // src/index.ts
8898
- var import_python_analysis9 = require("@vercel/python-analysis");
8899
-
8900
- // src/subscribers.ts
8901
- var import_path15 = require("path");
8902
- var import_fs15 = __toESM(require("fs"));
8903
- var import_build_utils18 = require("@vercel/build-utils");
8904
-
8905
- // src/module-entrypoint.ts
8906
- var import_path14 = require("path");
8907
- var import_fs14 = __toESM(require("fs"));
8908
- var MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
8909
- function parseModuleEntrypoint(value) {
8910
- const match = MODULE_ATTR_RE.exec(value);
8911
- if (!match) {
8912
- return null;
8913
- }
8914
- return {
8915
- moduleName: match[1],
8916
- variableName: match[2],
8917
- filePath: `${match[1].replace(/\./g, "/")}.py`
8918
- };
8357
+ // src/fastapi.ts
8358
+ var import_fs13 = __toESM(require("fs"));
8359
+ var import_path13 = require("path");
8360
+ var import_execa7 = __toESM(require_execa());
8361
+ var import_build_utils17 = require("@vercel/build-utils");
8362
+ var scriptPath3 = (0, import_path13.join)(__dirname, "..", "templates", "vc_fastapi_static.py");
8363
+ var _STATIC_FILE_COLLECTION_ERROR_MESSAGE = "Warning: FastAPI static file collection failed. Static files will not be served from the CDN.";
8364
+ async function getFastAPIStaticMounts(venvPath, entrypointAbs, variableName, env, workPath) {
8365
+ const pythonPath = getVenvPythonBin(venvPath);
8366
+ const outputPath = (0, import_path13.join)(
8367
+ workPath,
8368
+ ".vercel",
8369
+ "python",
8370
+ "vc_fastapi_static_output.json"
8371
+ );
8372
+ await import_fs13.default.promises.mkdir((0, import_path13.join)(workPath, ".vercel", "python"), {
8373
+ recursive: true
8374
+ });
8375
+ try {
8376
+ const { stderr } = await (0, import_execa7.default)(
8377
+ pythonPath,
8378
+ [scriptPath3, entrypointAbs, variableName, outputPath],
8379
+ { env, cwd: workPath }
8380
+ );
8381
+ if (stderr) {
8382
+ (0, import_build_utils17.debug)(`FastAPI shim stderr:
8383
+ ${stderr}`);
8384
+ }
8385
+ } catch (err) {
8386
+ console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
8387
+ (0, import_build_utils17.debug)(
8388
+ `FastAPI: could not discover static mounts: ${err?.stderr ?? err?.message ?? err}`
8389
+ );
8390
+ return [];
8391
+ }
8392
+ try {
8393
+ const raw = await import_fs13.default.promises.readFile(outputPath, "utf8");
8394
+ const parsed = JSON.parse(raw);
8395
+ (0, import_build_utils17.debug)(`FastAPI: discovered mounts: ${JSON.stringify(parsed)}`);
8396
+ return parsed;
8397
+ } catch {
8398
+ console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
8399
+ (0, import_build_utils17.debug)(`FastAPI: could not read shim output file: ${outputPath}`);
8400
+ return [];
8401
+ } finally {
8402
+ await import_fs13.default.promises.rm(outputPath, { force: true });
8403
+ }
8404
+ }
8405
+ async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir, entrypointAbs, variableName) {
8406
+ const mounts = await getFastAPIStaticMounts(
8407
+ venvPath,
8408
+ entrypointAbs,
8409
+ variableName,
8410
+ env,
8411
+ workPath
8412
+ );
8413
+ if (mounts.length === 0) {
8414
+ (0, import_build_utils17.debug)("FastAPI: no StaticFiles mounts found, skipping");
8415
+ return null;
8416
+ }
8417
+ (0, import_build_utils17.debug)(
8418
+ `Found ${mounts.length} FastAPI static mount(s): ${mounts.map((m) => m.urlPath).join(", ")}`
8419
+ );
8420
+ for (const mount of mounts) {
8421
+ const urlSubPath = mount.urlPath.replace(/^\/|\/$/g, "");
8422
+ const dest = (0, import_path13.join)(outputStaticDir, urlSubPath);
8423
+ await import_fs13.default.promises.mkdir(dest, { recursive: true });
8424
+ await import_fs13.default.promises.cp(mount.directory, dest, { recursive: true });
8425
+ (0, import_build_utils17.debug)(`copied ${mount.directory} -> ${dest}`);
8426
+ }
8427
+ return {
8428
+ collectedMounts: mounts.map((m) => m.urlPath),
8429
+ cdnOutputDir: outputStaticDir
8430
+ };
8431
+ }
8432
+
8433
+ // src/index.ts
8434
+ var import_python_analysis10 = require("@vercel/python-analysis");
8435
+
8436
+ // src/compileall.ts
8437
+ var import_execa8 = __toESM(require_execa());
8438
+ var import_build_utils18 = require("@vercel/build-utils");
8439
+ var import_fs14 = __toESM(require("fs"));
8440
+ var import_os3 = require("os");
8441
+ var import_path14 = require("path");
8442
+ var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
8443
+ var PYCACHE_PREFIX_DIR = "_vc_pycache";
8444
+ var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
8445
+ function isCompileAllFlagEnabled() {
8446
+ const val = process.env.VERCEL_PYTHON_COMPILEALL;
8447
+ if (val === void 0 || val === "")
8448
+ return false;
8449
+ const lower = val.toLowerCase();
8450
+ return lower === "1" || lower === "true";
8451
+ }
8452
+ function shouldCompileAll({
8453
+ isDev,
8454
+ hasCustomCommand,
8455
+ hasPreDeployCommand
8456
+ }) {
8457
+ if (isDev)
8458
+ return false;
8459
+ if (hasCustomCommand)
8460
+ return false;
8461
+ if (hasPreDeployCommand)
8462
+ return false;
8463
+ return isCompileAllFlagEnabled();
8464
+ }
8465
+ async function runCompileAll({
8466
+ pythonBin,
8467
+ sourceFiles,
8468
+ env,
8469
+ pycachePrefix
8470
+ }) {
8471
+ const uniqueSourceFiles = [...new Set(sourceFiles)];
8472
+ if (uniqueSourceFiles.length === 0) {
8473
+ return false;
8474
+ }
8475
+ let tempDir;
8476
+ try {
8477
+ tempDir = await import_fs14.default.promises.mkdtemp(
8478
+ (0, import_path14.join)((0, import_os3.tmpdir)(), "vercel-python-compileall-")
8479
+ );
8480
+ const listPath = (0, import_path14.join)(tempDir, "pysources.json");
8481
+ await import_fs14.default.promises.writeFile(listPath, JSON.stringify(uniqueSourceFiles));
8482
+ const scriptPath4 = (0, import_path14.join)(__dirname, "..", "templates", "vc_compileall.py");
8483
+ const baseEnv = env || process.env;
8484
+ const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
8485
+ await (0, import_execa8.default)(pythonBin, [scriptPath4, listPath], {
8486
+ env: subprocessEnv,
8487
+ timeout: COMPILEALL_TIMEOUT_MS
8488
+ });
8489
+ return true;
8490
+ } catch (err) {
8491
+ (0, import_build_utils18.debug)(`compileall error details: ${JSON.stringify(err)}`);
8492
+ return false;
8493
+ } finally {
8494
+ if (tempDir) {
8495
+ try {
8496
+ await import_fs14.default.promises.rm(tempDir, { recursive: true, force: true });
8497
+ } catch (err) {
8498
+ (0, import_build_utils18.debug)(`compileall temporary file cleanup error: ${String(err)}`);
8499
+ }
8500
+ }
8501
+ }
8502
+ }
8503
+ function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
8504
+ if (!pyRelPath.endsWith(".py"))
8505
+ return null;
8506
+ const lastSlash = pyRelPath.lastIndexOf("/");
8507
+ const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
8508
+ const baseName = pyRelPath.slice(lastSlash + 1, -3);
8509
+ return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
8510
+ }
8511
+ function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
8512
+ if (!pyRelPath.endsWith(".py"))
8513
+ return null;
8514
+ return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
8515
+ }
8516
+ function stripPycachePrefixRoot(head) {
8517
+ const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
8518
+ if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
8519
+ head = head.slice(2);
8520
+ }
8521
+ let start = 0;
8522
+ while (start < head.length && pycachePathSeparators.has(head[start])) {
8523
+ start++;
8524
+ }
8525
+ return head.slice(start);
8526
+ }
8527
+ function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
8528
+ const rel = derivePrefixPycRelPath(
8529
+ stripPycachePrefixRoot(srcAbsPath),
8530
+ pythonMajor,
8531
+ pythonMinor
8532
+ );
8533
+ if (!rel)
8534
+ return null;
8535
+ return (0, import_path14.join)(stagingDir, rel.replaceAll("/", import_path14.sep));
8536
+ }
8537
+ function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
8538
+ const rel = derivePrefixPycRelPath(
8539
+ stripPycachePrefixRoot(runtimeAbsPath),
8540
+ pythonMajor,
8541
+ pythonMinor
8542
+ );
8543
+ if (!rel)
8544
+ return null;
8545
+ return `${PYCACHE_PREFIX_DIR}/${rel}`;
8546
+ }
8547
+ async function collectAppPrefixBytecodeFiles({
8548
+ stagingDir,
8549
+ workPath,
8550
+ files: appFiles,
8551
+ runtimeTaskRoot,
8552
+ pythonMajor,
8553
+ pythonMinor
8554
+ }) {
8555
+ const pending = [];
8556
+ for (const bundlePath of Object.keys(appFiles)) {
8557
+ if (!bundlePath.endsWith(".py"))
8558
+ continue;
8559
+ const stagedFsPath = deriveStagedPycFsPath(
8560
+ stagingDir,
8561
+ (0, import_path14.join)(workPath, bundlePath.replaceAll("/", import_path14.sep)),
8562
+ pythonMajor,
8563
+ pythonMinor
8564
+ );
8565
+ const pycBundlePath = derivePrefixPycBundlePath(
8566
+ `${runtimeTaskRoot}/${bundlePath}`,
8567
+ pythonMajor,
8568
+ pythonMinor
8569
+ );
8570
+ if (!stagedFsPath || !pycBundlePath)
8571
+ continue;
8572
+ pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
8573
+ }
8574
+ const results = await Promise.all(
8575
+ pending.map(async ({ bundlePath, srcFsPath }) => {
8576
+ try {
8577
+ const stats = await import_fs14.default.promises.stat(srcFsPath);
8578
+ return { bundlePath, srcFsPath, size: stats.size };
8579
+ } catch {
8580
+ return null;
8581
+ }
8582
+ })
8583
+ );
8584
+ const files = {};
8585
+ const perItemSizes = /* @__PURE__ */ new Map();
8586
+ let totalSize = 0;
8587
+ for (const result of results) {
8588
+ if (!result)
8589
+ continue;
8590
+ files[result.bundlePath] = new import_build_utils18.FileFsRef({
8591
+ fsPath: result.srcFsPath,
8592
+ size: result.size
8593
+ });
8594
+ perItemSizes.set(result.bundlePath, result.size);
8595
+ totalSize += result.size;
8596
+ }
8597
+ return { files, totalSize, perItemSizes };
8598
+ }
8599
+ async function collectAppBytecodeFiles({
8600
+ workPath,
8601
+ files: appFiles,
8602
+ pythonMajor,
8603
+ pythonMinor
8604
+ }) {
8605
+ const pending = [];
8606
+ for (const bundlePath of Object.keys(appFiles)) {
8607
+ const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
8608
+ if (!pycRel)
8609
+ continue;
8610
+ pending.push({
8611
+ bundlePath: pycRel,
8612
+ srcFsPath: (0, import_path14.join)(workPath, pycRel.replaceAll("/", import_path14.sep))
8613
+ });
8614
+ }
8615
+ const results = await Promise.all(
8616
+ pending.map(async ({ bundlePath, srcFsPath }) => {
8617
+ try {
8618
+ const stats = await import_fs14.default.promises.stat(srcFsPath);
8619
+ return { bundlePath, srcFsPath, size: stats.size };
8620
+ } catch {
8621
+ return null;
8622
+ }
8623
+ })
8624
+ );
8625
+ const files = {};
8626
+ const perItemSizes = /* @__PURE__ */ new Map();
8627
+ let totalSize = 0;
8628
+ for (const result of results) {
8629
+ if (!result)
8630
+ continue;
8631
+ files[result.bundlePath] = new import_build_utils18.FileFsRef({
8632
+ fsPath: result.srcFsPath,
8633
+ size: result.size
8634
+ });
8635
+ perItemSizes.set(result.bundlePath, result.size);
8636
+ totalSize += result.size;
8637
+ }
8638
+ return { files, totalSize, perItemSizes };
8639
+ }
8640
+
8641
+ // src/installed-distributions.ts
8642
+ var import_fs15 = __toESM(require("fs"));
8643
+ var import_path15 = require("path");
8644
+ var import_build_utils19 = require("@vercel/build-utils");
8645
+ var import_python_analysis9 = require("@vercel/python-analysis");
8646
+ var STRIP_BASENAMES = /* @__PURE__ */ new Set([
8647
+ "py.typed",
8648
+ "WHEEL",
8649
+ "INSTALLER",
8650
+ "direct_url.json"
8651
+ ]);
8652
+ function shouldStripVendorFile(filePath) {
8653
+ const segments = filePath.split(import_path15.sep);
8654
+ if (segments.includes("__pycache__"))
8655
+ return true;
8656
+ const name = segments[segments.length - 1] ?? "";
8657
+ if (name.endsWith(".pyc") || name.endsWith(".pyi"))
8658
+ return true;
8659
+ if (STRIP_BASENAMES.has(name))
8660
+ return true;
8661
+ return false;
8662
+ }
8663
+ function getDistributionFileGroups({
8664
+ sitePackageDirs,
8665
+ distributions,
8666
+ includePackages
8667
+ }) {
8668
+ if (includePackages?.length === 0) {
8669
+ return [];
8670
+ }
8671
+ const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis9.normalizePackageName)) : null;
8672
+ const groups = [];
8673
+ for (const dir of sitePackageDirs) {
8674
+ const dirDistributions = distributions.get(dir);
8675
+ if (!dirDistributions)
8676
+ continue;
8677
+ const sitePackagesDir = (0, import_path15.resolve)(dir);
8678
+ for (const [name, distribution] of dirDistributions) {
8679
+ const packageName = (0, import_python_analysis9.normalizePackageName)(name);
8680
+ if (includeSet && !includeSet.has(packageName))
8681
+ continue;
8682
+ const files = [];
8683
+ for (const record of distribution.files) {
8684
+ const absolutePath = (0, import_path15.resolve)(
8685
+ sitePackagesDir,
8686
+ record.path.replaceAll("/", import_path15.sep)
8687
+ );
8688
+ const relativePath = (0, import_path15.relative)(sitePackagesDir, absolutePath);
8689
+ if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path15.sep}`) || (0, import_path15.isAbsolute)(relativePath)) {
8690
+ continue;
8691
+ }
8692
+ files.push({ absolutePath, relativePath, record });
8693
+ }
8694
+ groups.push({ packageName, sitePackagesDir, files });
8695
+ }
8696
+ }
8697
+ return groups;
8698
+ }
8699
+ var InstalledPythonDistributions = class _InstalledPythonDistributions {
8700
+ static async load({
8701
+ venvPath,
8702
+ pythonMajor,
8703
+ pythonMinor
8704
+ }) {
8705
+ const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
8706
+ const distributions = /* @__PURE__ */ new Map();
8707
+ for (const dir of sitePackageDirs) {
8708
+ try {
8709
+ await import_fs15.default.promises.access(dir);
8710
+ } catch {
8711
+ continue;
8712
+ }
8713
+ distributions.set(dir, await (0, import_python_analysis9.scanDistributions)(dir));
8714
+ }
8715
+ return new _InstalledPythonDistributions({
8716
+ sitePackageDirs,
8717
+ distributions,
8718
+ pythonMajor,
8719
+ pythonMinor
8720
+ });
8721
+ }
8722
+ constructor(options) {
8723
+ this.sitePackageDirs = options.sitePackageDirs;
8724
+ this.distributions = options.distributions;
8725
+ this.pythonMajor = options.pythonMajor;
8726
+ this.pythonMinor = options.pythonMinor;
8727
+ }
8728
+ async mirrorPackagesIntoVendor({
8729
+ vendorDirName,
8730
+ includePackages
8731
+ }) {
8732
+ const pending = [];
8733
+ const distributionGroups = getDistributionFileGroups({
8734
+ sitePackageDirs: this.sitePackageDirs,
8735
+ distributions: this.distributions,
8736
+ includePackages
8737
+ });
8738
+ for (const { files } of distributionGroups) {
8739
+ for (const { absolutePath, relativePath, record } of files) {
8740
+ if (shouldStripVendorFile(relativePath))
8741
+ continue;
8742
+ pending.push({
8743
+ bundlePath: (0, import_path15.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
8744
+ srcFsPath: absolutePath,
8745
+ recordSize: record.size != null ? Number(record.size) : void 0
8746
+ });
8747
+ }
8748
+ }
8749
+ const results = await Promise.all(
8750
+ pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
8751
+ try {
8752
+ if (recordSize === void 0) {
8753
+ const stats = await import_fs15.default.promises.stat(srcFsPath);
8754
+ return { bundlePath, srcFsPath, size: stats.size };
8755
+ }
8756
+ await import_fs15.default.promises.access(srcFsPath);
8757
+ return { bundlePath, srcFsPath, size: recordSize };
8758
+ } catch {
8759
+ return null;
8760
+ }
8761
+ })
8762
+ );
8763
+ const vendorFiles = {};
8764
+ for (const result of results) {
8765
+ if (!result)
8766
+ continue;
8767
+ vendorFiles[result.bundlePath] = new import_build_utils19.FileFsRef({
8768
+ fsPath: result.srcFsPath,
8769
+ size: result.size
8770
+ });
8771
+ }
8772
+ (0, import_build_utils19.debug)(
8773
+ `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
8774
+ );
8775
+ return vendorFiles;
8776
+ }
8777
+ async calculatePerPackageSizes() {
8778
+ const sizes = /* @__PURE__ */ new Map();
8779
+ const distributionGroups = getDistributionFileGroups({
8780
+ sitePackageDirs: this.sitePackageDirs,
8781
+ distributions: this.distributions
8782
+ });
8783
+ for (const { packageName, files } of distributionGroups) {
8784
+ let knownSize = 0;
8785
+ const statPromises = [];
8786
+ for (const { absolutePath, relativePath, record } of files) {
8787
+ if (shouldStripVendorFile(relativePath))
8788
+ continue;
8789
+ if (record.size != null) {
8790
+ knownSize += Number(record.size);
8791
+ } else {
8792
+ statPromises.push(
8793
+ import_fs15.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
8794
+ );
8795
+ }
8796
+ }
8797
+ const statSizes = await Promise.all(statPromises);
8798
+ sizes.set(
8799
+ packageName,
8800
+ statSizes.reduce((total, size) => total + size, knownSize)
8801
+ );
8802
+ }
8803
+ return sizes;
8804
+ }
8805
+ getPythonSourceFiles(includePackages) {
8806
+ const sourceFiles = /* @__PURE__ */ new Set();
8807
+ const distributionGroups = getDistributionFileGroups({
8808
+ sitePackageDirs: this.sitePackageDirs,
8809
+ distributions: this.distributions,
8810
+ includePackages
8811
+ });
8812
+ for (const { files } of distributionGroups) {
8813
+ for (const { absolutePath, relativePath } of files) {
8814
+ if (relativePath.endsWith(".py")) {
8815
+ sourceFiles.add(absolutePath);
8816
+ }
8817
+ }
8818
+ }
8819
+ return [...sourceFiles].sort();
8820
+ }
8821
+ async collectBytecodeFiles({
8822
+ vendorDirName,
8823
+ includePackages
8824
+ }) {
8825
+ if (this.pythonMajor == null || this.pythonMinor == null) {
8826
+ return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
8827
+ }
8828
+ const pending = [];
8829
+ const distributionGroups = getDistributionFileGroups({
8830
+ sitePackageDirs: this.sitePackageDirs,
8831
+ distributions: this.distributions,
8832
+ includePackages
8833
+ });
8834
+ for (const { packageName, sitePackagesDir, files } of distributionGroups) {
8835
+ for (const { relativePath } of files) {
8836
+ const pycRelativePath = derivePycPath(
8837
+ relativePath.replaceAll(import_path15.sep, "/"),
8838
+ this.pythonMajor,
8839
+ this.pythonMinor
8840
+ );
8841
+ if (!pycRelativePath)
8842
+ continue;
8843
+ const pycFilePath = pycRelativePath.replaceAll("/", import_path15.sep);
8844
+ pending.push({
8845
+ bundlePath: (0, import_path15.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
8846
+ srcFsPath: (0, import_path15.join)(sitePackagesDir, pycFilePath),
8847
+ packageName
8848
+ });
8849
+ }
8850
+ }
8851
+ const result = await this.collectExistingBytecode(pending);
8852
+ (0, import_build_utils19.debug)(
8853
+ `Collected ${Object.keys(result.files).length} bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
8854
+ );
8855
+ return result;
8856
+ }
8857
+ async collectPrefixBytecodeFiles({
8858
+ stagingDir,
8859
+ runtimeRoot,
8860
+ includePackages
8861
+ }) {
8862
+ if (this.pythonMajor == null || this.pythonMinor == null) {
8863
+ return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
8864
+ }
8865
+ const pending = [];
8866
+ const distributionGroups = getDistributionFileGroups({
8867
+ sitePackageDirs: this.sitePackageDirs,
8868
+ distributions: this.distributions,
8869
+ includePackages
8870
+ });
8871
+ for (const { packageName, files } of distributionGroups) {
8872
+ for (const { absolutePath, relativePath } of files) {
8873
+ if (!relativePath.endsWith(".py"))
8874
+ continue;
8875
+ const recordPath = relativePath.replaceAll(import_path15.sep, "/");
8876
+ const srcFsPath = deriveStagedPycFsPath(
8877
+ stagingDir,
8878
+ absolutePath,
8879
+ this.pythonMajor,
8880
+ this.pythonMinor
8881
+ );
8882
+ const bundlePath = derivePrefixPycBundlePath(
8883
+ `${runtimeRoot}/${recordPath}`,
8884
+ this.pythonMajor,
8885
+ this.pythonMinor
8886
+ );
8887
+ if (!srcFsPath || !bundlePath)
8888
+ continue;
8889
+ pending.push({ bundlePath, srcFsPath, packageName });
8890
+ }
8891
+ }
8892
+ const result = await this.collectExistingBytecode(pending);
8893
+ (0, import_build_utils19.debug)(
8894
+ `Collected ${Object.keys(result.files).length} prefix bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
8895
+ );
8896
+ return result;
8897
+ }
8898
+ async collectExistingBytecode(pending) {
8899
+ const results = await Promise.all(
8900
+ pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
8901
+ try {
8902
+ const stats = await import_fs15.default.promises.stat(srcFsPath);
8903
+ return { bundlePath, srcFsPath, size: stats.size, packageName };
8904
+ } catch {
8905
+ return null;
8906
+ }
8907
+ })
8908
+ );
8909
+ const files = {};
8910
+ let totalSize = 0;
8911
+ const perItemSizes = /* @__PURE__ */ new Map();
8912
+ for (const result of results) {
8913
+ if (!result)
8914
+ continue;
8915
+ files[result.bundlePath] = new import_build_utils19.FileFsRef({
8916
+ fsPath: result.srcFsPath,
8917
+ size: result.size
8918
+ });
8919
+ totalSize += result.size;
8920
+ perItemSizes.set(
8921
+ result.packageName,
8922
+ (perItemSizes.get(result.packageName) ?? 0) + result.size
8923
+ );
8924
+ }
8925
+ return { files, totalSize, perItemSizes };
8926
+ }
8927
+ };
8928
+
8929
+ // src/subscribers.ts
8930
+ var import_path17 = require("path");
8931
+ var import_fs17 = __toESM(require("fs"));
8932
+ var import_build_utils20 = require("@vercel/build-utils");
8933
+
8934
+ // src/module-entrypoint.ts
8935
+ var import_path16 = require("path");
8936
+ var import_fs16 = __toESM(require("fs"));
8937
+ var MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
8938
+ function parseModuleEntrypoint(value) {
8939
+ const match = MODULE_ATTR_RE.exec(value);
8940
+ if (!match) {
8941
+ return null;
8942
+ }
8943
+ return {
8944
+ moduleName: match[1],
8945
+ variableName: match[2],
8946
+ filePath: `${match[1].replace(/\./g, "/")}.py`
8947
+ };
8919
8948
  }
8920
8949
  function getModuleEntrypointName({
8921
8950
  moduleName,
@@ -8935,7 +8964,7 @@ async function resolveExistingEntrypoint(workPath, filePath) {
8935
8964
  const candidates = [filePath, filePath.replace(/\.py$/i, "/__init__.py")];
8936
8965
  for (const candidate of candidates) {
8937
8966
  try {
8938
- const stat = await import_fs14.default.promises.stat((0, import_path14.join)(workPath, candidate));
8967
+ const stat = await import_fs16.default.promises.stat((0, import_path16.join)(workPath, candidate));
8939
8968
  if (stat.isFile()) {
8940
8969
  return candidate;
8941
8970
  }
@@ -8982,14 +9011,14 @@ function getSubscriberOutputPath(subscriberName) {
8982
9011
  return `${SUBSCRIBER_OUTPUT_DIR}/${safePathSegment(subscriberName)}`;
8983
9012
  }
8984
9013
  function getSubscriberConsumerName(subscriberName) {
8985
- return (0, import_build_utils18.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
9014
+ return (0, import_build_utils20.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
8986
9015
  }
8987
9016
  async function getPyprojectSubscribers(workPath) {
8988
- const pyprojectPath = (0, import_path15.join)(workPath, "pyproject.toml");
8989
- if (!import_fs15.default.existsSync(pyprojectPath)) {
9017
+ const pyprojectPath = (0, import_path17.join)(workPath, "pyproject.toml");
9018
+ if (!import_fs17.default.existsSync(pyprojectPath)) {
8990
9019
  return [];
8991
9020
  }
8992
- const pyproject = await (0, import_build_utils18.readConfigFile)(pyprojectPath);
9021
+ const pyproject = await (0, import_build_utils20.readConfigFile)(pyprojectPath);
8993
9022
  const subscribers = pyproject?.tool?.vercel?.subscribers;
8994
9023
  if (!subscribers) {
8995
9024
  return [];
@@ -9081,16 +9110,16 @@ function parseTriggerDefaults(subscriber, config) {
9081
9110
  return defaults;
9082
9111
  }
9083
9112
  function subscriberError(message) {
9084
- return new import_build_utils18.NowBuildError({
9113
+ return new import_build_utils20.NowBuildError({
9085
9114
  code: "PYTHON_INVALID_SUBSCRIBER_CONFIG",
9086
9115
  message
9087
9116
  });
9088
9117
  }
9089
9118
 
9090
9119
  // src/workflows.ts
9091
- var import_path16 = require("path");
9092
- var import_fs16 = __toESM(require("fs"));
9093
- var import_build_utils19 = require("@vercel/build-utils");
9120
+ var import_path18 = require("path");
9121
+ var import_fs18 = __toESM(require("fs"));
9122
+ var import_build_utils21 = require("@vercel/build-utils");
9094
9123
  var WORKFLOW_OUTPUT_DIR = "_py_workflows";
9095
9124
  var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
9096
9125
  var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
@@ -9098,14 +9127,14 @@ function getWorkflowOutputPath(workflowName) {
9098
9127
  return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
9099
9128
  }
9100
9129
  function getWorkflowConsumerName(workflowName) {
9101
- return (0, import_build_utils19.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
9130
+ return (0, import_build_utils21.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
9102
9131
  }
9103
9132
  async function getPyprojectWorkflows(workPath) {
9104
- const pyprojectPath = (0, import_path16.join)(workPath, "pyproject.toml");
9105
- if (!import_fs16.default.existsSync(pyprojectPath)) {
9133
+ const pyprojectPath = (0, import_path18.join)(workPath, "pyproject.toml");
9134
+ if (!import_fs18.default.existsSync(pyprojectPath)) {
9106
9135
  return [];
9107
9136
  }
9108
- const pyproject = await (0, import_build_utils19.readConfigFile)(pyprojectPath);
9137
+ const pyproject = await (0, import_build_utils21.readConfigFile)(pyprojectPath);
9109
9138
  const workflows = pyproject?.tool?.vercel?.workflows;
9110
9139
  if (!workflows) {
9111
9140
  return [];
@@ -9159,14 +9188,14 @@ async function parseWorkflow(workPath, index, config) {
9159
9188
  };
9160
9189
  }
9161
9190
  function workflowError(message) {
9162
- return new import_build_utils19.NowBuildError({
9191
+ return new import_build_utils21.NowBuildError({
9163
9192
  code: "PYTHON_INVALID_WORKFLOW_CONFIG",
9164
9193
  message
9165
9194
  });
9166
9195
  }
9167
9196
 
9168
9197
  // src/index.ts
9169
- var writeFile = import_fs17.default.promises.writeFile;
9198
+ var writeFile = import_fs19.default.promises.writeFile;
9170
9199
  var PYTHON_ENTRYPOINT_DOCS_URL2 = "https://vercel.com/docs/functions/runtimes/python#python-entrypoints";
9171
9200
  var version = -1;
9172
9201
  function getDevSubscriberTopics(subscriber) {
@@ -9183,9 +9212,9 @@ async function getDevSidecars({
9183
9212
  service
9184
9213
  }) {
9185
9214
  const framework = build2.config?.framework;
9186
- const isPyprojectEntrypoint = (0, import_path17.basename)(build2.src ?? "") === "pyproject.toml";
9187
- const isPyprojectService = service !== void 0 && (0, import_path17.basename)(service.entrypoint ?? "") === "pyproject.toml";
9188
- if (build2.config?.middleware === true || service !== void 0 && !isPyprojectService || service === void 0 && !isPyprojectEntrypoint && (typeof framework !== "string" || !(0, import_build_utils20.isPythonFramework)(framework))) {
9215
+ const isPyprojectEntrypoint = (0, import_path19.basename)(build2.src ?? "") === "pyproject.toml";
9216
+ const isPyprojectService = service !== void 0 && (0, import_path19.basename)(service.entrypoint ?? "") === "pyproject.toml";
9217
+ if (build2.config?.middleware === true || service !== void 0 && !isPyprojectService || service === void 0 && !isPyprojectEntrypoint && (typeof framework !== "string" || !(0, import_build_utils22.isPythonFramework)(framework))) {
9189
9218
  return [];
9190
9219
  }
9191
9220
  const subscribers = await getPyprojectSubscribers(workPath);
@@ -9255,7 +9284,7 @@ function addBytecodeWithinCapacity(files, bytecodeInfo, capacity) {
9255
9284
  }
9256
9285
  async function addVendorBytecodeWithinCapacity({
9257
9286
  files,
9258
- depExternalizer,
9287
+ installedDistributions,
9259
9288
  vendorDir,
9260
9289
  bytecodeInfo,
9261
9290
  capacity
@@ -9270,7 +9299,7 @@ async function addVendorBytecodeWithinCapacity({
9270
9299
  const selectedPkgs = lambdaKnapsack(bytecodeInfo.perItemSizes, capacity);
9271
9300
  if (selectedPkgs.length === 0)
9272
9301
  return capacity;
9273
- const selectedBytecode = await depExternalizer.collectBytecodeFiles({
9302
+ const selectedBytecode = await installedDistributions.collectBytecodeFiles({
9274
9303
  vendorDirName: vendorDir,
9275
9304
  includePackages: selectedPkgs
9276
9305
  });
@@ -9279,7 +9308,7 @@ async function addVendorBytecodeWithinCapacity({
9279
9308
  }
9280
9309
  async function addVendorBytecodeInTiers({
9281
9310
  files,
9282
- depExternalizer,
9311
+ installedDistributions,
9283
9312
  vendorDir,
9284
9313
  capacity,
9285
9314
  vendorPackageTiers
@@ -9290,13 +9319,13 @@ async function addVendorBytecodeInTiers({
9290
9319
  break;
9291
9320
  if (tier && tier.length === 0)
9292
9321
  continue;
9293
- const bytecodeInfo = await depExternalizer.collectBytecodeFiles({
9322
+ const bytecodeInfo = await installedDistributions.collectBytecodeFiles({
9294
9323
  vendorDirName: vendorDir,
9295
9324
  includePackages: tier
9296
9325
  });
9297
9326
  remainingCapacity = await addVendorBytecodeWithinCapacity({
9298
9327
  files,
9299
- depExternalizer,
9328
+ installedDistributions,
9300
9329
  vendorDir,
9301
9330
  bytecodeInfo,
9302
9331
  capacity: remainingCapacity
@@ -9338,13 +9367,13 @@ var frameworkHooks = {
9338
9367
  }) => {
9339
9368
  let baseDir = detected?.baseDir;
9340
9369
  if (baseDir === void 0) {
9341
- if (!import_fs17.default.existsSync((0, import_path17.join)(workPath, "manage.py"))) {
9342
- (0, import_build_utils20.debug)("Django hook: no manage.py detected, skipping");
9370
+ if (!import_fs19.default.existsSync((0, import_path19.join)(workPath, "manage.py"))) {
9371
+ (0, import_build_utils22.debug)("Django hook: no manage.py detected, skipping");
9343
9372
  return;
9344
9373
  }
9345
9374
  baseDir = "";
9346
9375
  }
9347
- const djangoPath = (0, import_path17.join)(workPath, baseDir);
9376
+ const djangoPath = (0, import_path19.join)(workPath, baseDir);
9348
9377
  let settingsResult;
9349
9378
  try {
9350
9379
  settingsResult = await getDjangoSettings(djangoPath, pythonEnv);
@@ -9356,13 +9385,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
9356
9385
  } else {
9357
9386
  detail = err?.stderr || err?.message || String(err);
9358
9387
  }
9359
- throw new import_build_utils20.NowBuildError({
9388
+ throw new import_build_utils22.NowBuildError({
9360
9389
  code: "DJANGO_SETTINGS_FAILED",
9361
9390
  message: `Failed to read Django application settings from ${djangoPath}/manage.py:
9362
9391
  ${detail}`
9363
9392
  });
9364
9393
  }
9365
- (0, import_build_utils20.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
9394
+ (0, import_build_utils22.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
9366
9395
  const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
9367
9396
  if (djangoVersion) {
9368
9397
  console.log(`Django ${djangoVersion.join(".")} detected`);
@@ -9374,7 +9403,7 @@ ${detail}`
9374
9403
  const variableName = parts.at(-1);
9375
9404
  const rel = `${parts.slice(0, -1).join("/")}.py`;
9376
9405
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
9377
- (0, import_build_utils20.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
9406
+ (0, import_build_utils22.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
9378
9407
  resolvedEntrypoint = { entrypoint: ep, variableName };
9379
9408
  } else {
9380
9409
  const wsgiApp = djangoSettings["WSGI_APPLICATION"];
@@ -9383,7 +9412,7 @@ ${detail}`
9383
9412
  const variableName = parts.at(-1);
9384
9413
  const rel = `${parts.slice(0, -1).join("/")}.py`;
9385
9414
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
9386
- (0, import_build_utils20.debug)(
9415
+ (0, import_build_utils22.debug)(
9387
9416
  `Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
9388
9417
  );
9389
9418
  resolvedEntrypoint = { entrypoint: ep, variableName };
@@ -9391,7 +9420,7 @@ ${detail}`
9391
9420
  }
9392
9421
  let djangoStatic = null;
9393
9422
  if (workPath && venvPath) {
9394
- const outputStaticDir = (0, import_path17.join)(workPath, ".vercel", "output", "static");
9423
+ const outputStaticDir = (0, import_path19.join)(workPath, ".vercel", "output", "static");
9395
9424
  djangoStatic = await runDjangoCollectStatic(
9396
9425
  venvPath,
9397
9426
  workPath,
@@ -9406,8 +9435,45 @@ ${detail}`
9406
9435
  return {
9407
9436
  entrypoint: resolvedEntrypoint,
9408
9437
  djangoStatic,
9409
- extraPythonPath: baseDir ? (0, import_path17.join)(workPath, baseDir) : void 0
9438
+ extraPythonPath: baseDir ? (0, import_path19.join)(workPath, baseDir) : void 0
9410
9439
  };
9440
+ },
9441
+ fastapi: async ({
9442
+ pythonEnv,
9443
+ detected,
9444
+ workPath,
9445
+ venvPath
9446
+ }) => {
9447
+ if (!detected?.entrypoint || !workPath || !venvPath) {
9448
+ (0, import_build_utils22.debug)(
9449
+ `FastAPI hook: skipping \u2014 detected.entrypoint=${JSON.stringify(detected?.entrypoint)}, workPath=${workPath}, venvPath=${venvPath}`
9450
+ );
9451
+ return;
9452
+ }
9453
+ const { entrypoint: entrypointRel, variableName } = detected.entrypoint;
9454
+ (0, import_build_utils22.debug)(
9455
+ `FastAPI hook: entrypoint=${entrypointRel}, variableName=${variableName}`
9456
+ );
9457
+ const entrypointAbs = (0, import_path19.join)(workPath, entrypointRel);
9458
+ const outputStaticDir = (0, import_path19.join)(workPath, ".vercel", "output", "static");
9459
+ const cdnEnv = process.env.VERCEL_FASTAPI_STATIC_CDN?.toLowerCase();
9460
+ if (cdnEnv !== "1" && cdnEnv !== "true") {
9461
+ (0, import_build_utils22.debug)(
9462
+ "FastAPI: VERCEL_FASTAPI_STATIC_CDN not set, skipping static CDN collection"
9463
+ );
9464
+ return;
9465
+ }
9466
+ const fastapiStatic = await runFastAPICollectStatic(
9467
+ venvPath,
9468
+ workPath,
9469
+ pythonEnv,
9470
+ outputStaticDir,
9471
+ entrypointAbs,
9472
+ variableName
9473
+ );
9474
+ if (!fastapiStatic)
9475
+ return;
9476
+ return { fastapiStatic };
9411
9477
  }
9412
9478
  };
9413
9479
  function createRuntimeTrampoline({
@@ -9465,23 +9531,23 @@ async function downloadFilesInWorkPath({
9465
9531
  files,
9466
9532
  meta = {}
9467
9533
  }) {
9468
- (0, import_build_utils20.debug)("Downloading user files...");
9469
- let downloadedFiles = await (0, import_build_utils20.download)(files, workPath, meta);
9534
+ (0, import_build_utils22.debug)("Downloading user files...");
9535
+ let downloadedFiles = await (0, import_build_utils22.download)(files, workPath, meta);
9470
9536
  if (meta.isDev && entrypoint) {
9471
9537
  const normalizedEntrypoint = entrypoint.endsWith(".py") ? entrypoint : `${entrypoint}.py`;
9472
9538
  if (!hasProp(downloadedFiles, entrypoint) && !hasProp(downloadedFiles, normalizedEntrypoint)) {
9473
- throw new import_build_utils20.NowBuildError({
9539
+ throw new import_build_utils22.NowBuildError({
9474
9540
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
9475
9541
  message: `Configured Python entrypoint "${normalizedEntrypoint}" was not found.`,
9476
9542
  link: PYTHON_ENTRYPOINT_DOCS_URL2,
9477
9543
  action: "Learn More"
9478
9544
  });
9479
9545
  }
9480
- const { devCacheDir = (0, import_path17.join)(workPath, ".now", "cache") } = meta;
9481
- const cacheKey = (0, import_path17.basename)(entrypoint).replace(/\./g, "_");
9482
- const destCache = (0, import_path17.join)(devCacheDir, cacheKey);
9483
- await (0, import_build_utils20.download)(downloadedFiles, destCache);
9484
- downloadedFiles = await (0, import_build_utils20.glob)("**", destCache);
9546
+ const { devCacheDir = (0, import_path19.join)(workPath, ".now", "cache") } = meta;
9547
+ const cacheKey = (0, import_path19.basename)(entrypoint).replace(/\./g, "_");
9548
+ const destCache = (0, import_path19.join)(devCacheDir, cacheKey);
9549
+ await (0, import_build_utils22.download)(downloadedFiles, destCache);
9550
+ downloadedFiles = await (0, import_build_utils22.glob)("**", destCache);
9485
9551
  workPath = destCache;
9486
9552
  }
9487
9553
  return workPath;
@@ -9517,7 +9583,7 @@ async function getPythonLambdaOptions({
9517
9583
  sources.add(entrypoint.slice(0, -".py".length));
9518
9584
  }
9519
9585
  for (const sourceFile of sources) {
9520
- const lambdaOptions = await (0, import_build_utils20.getLambdaOptionsFromFunction)({
9586
+ const lambdaOptions = await (0, import_build_utils22.getLambdaOptionsFromFunction)({
9521
9587
  sourceFile,
9522
9588
  config
9523
9589
  });
@@ -9537,11 +9603,11 @@ async function installInjectedPackage({
9537
9603
  projectDir,
9538
9604
  pipPlatformArgs
9539
9605
  }) {
9540
- const localDir = (0, import_path17.join)(__dirname, "..", "..", "..", "python", name);
9541
- const isLocalDev = import_fs17.default.existsSync((0, import_path17.join)(localDir, "pyproject.toml"));
9606
+ const localDir = (0, import_path19.join)(__dirname, "..", "..", "..", "python", name);
9607
+ const isLocalDev = import_fs19.default.existsSync((0, import_path19.join)(localDir, "pyproject.toml"));
9542
9608
  const dep = envOverride || (isLocalDev ? localDir : pinned);
9543
9609
  const noExclude = ["--exclude-newer-package", `${name}=false`];
9544
- (0, import_build_utils20.debug)(`Installing ${dep}`);
9610
+ (0, import_build_utils22.debug)(`Installing ${dep}`);
9545
9611
  await uv.pip({
9546
9612
  venvPath,
9547
9613
  projectDir,
@@ -9567,14 +9633,14 @@ var build = async ({
9567
9633
  registerPreDeploy
9568
9634
  }) => {
9569
9635
  let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
9570
- const isPyprojectEntrypoint = entrypoint !== void 0 && (0, import_path17.basename)(entrypoint) === "pyproject.toml";
9636
+ const isPyprojectEntrypoint = entrypoint !== void 0 && (0, import_path19.basename)(entrypoint) === "pyproject.toml";
9571
9637
  if (isPyprojectEntrypoint && entrypoint !== "pyproject.toml") {
9572
- throw new import_build_utils20.NowBuildError({
9638
+ throw new import_build_utils22.NowBuildError({
9573
9639
  code: "PYTHON_INVALID_PYPROJECT_ENTRYPOINT",
9574
- message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0, import_path17.dirname)(entrypoint)}" and use entrypoint "pyproject.toml".`
9640
+ message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0, import_path19.dirname)(entrypoint)}" and use entrypoint "pyproject.toml".`
9575
9641
  });
9576
9642
  }
9577
- const builderSpan = parentSpan ?? new import_build_utils20.Span({ name: "vc.builder" });
9643
+ const builderSpan = parentSpan ?? new import_build_utils22.Span({ name: "vc.builder" });
9578
9644
  const framework = config?.framework;
9579
9645
  let shouldInstallVercelWorkers = config?.hasWorkerServices === true;
9580
9646
  let subscribers = [];
@@ -9583,21 +9649,21 @@ var build = async ({
9583
9649
  let projectInstallCommand;
9584
9650
  let hasCustomCommand = false;
9585
9651
  const target = getTargetPlatform(meta.isDev ?? false);
9586
- (0, import_build_utils20.debug)(`workPath: ${workPath}`);
9652
+ (0, import_build_utils22.debug)(`workPath: ${workPath}`);
9587
9653
  workPath = await downloadFilesInWorkPath({
9588
9654
  workPath,
9589
9655
  files: originalFiles,
9590
9656
  entrypoint,
9591
9657
  meta
9592
9658
  });
9593
- if (isPyprojectEntrypoint || !service && (0, import_build_utils20.isPythonFramework)(framework)) {
9659
+ if (isPyprojectEntrypoint || !service && (0, import_build_utils22.isPythonFramework)(framework)) {
9594
9660
  subscribers = await getPyprojectSubscribers(workPath);
9595
9661
  workflows = await getPyprojectWorkflows(workPath);
9596
9662
  shouldInstallVercelWorkers ||= subscribers.length > 0 || workflows.length > 0;
9597
9663
  }
9598
9664
  try {
9599
9665
  if (meta.isDev) {
9600
- const setupCfg = (0, import_path17.join)(workPath, "setup.cfg");
9666
+ const setupCfg = (0, import_path19.join)(workPath, "setup.cfg");
9601
9667
  await writeFile(setupCfg, "[install]\nprefix=\n");
9602
9668
  }
9603
9669
  } catch (err) {
@@ -9611,7 +9677,7 @@ var build = async ({
9611
9677
  if (declared) {
9612
9678
  detected = { entrypoint: declared };
9613
9679
  } else if (subscribers.length === 0 && workflows.length === 0) {
9614
- throw new import_build_utils20.NowBuildError({
9680
+ throw new import_build_utils22.NowBuildError({
9615
9681
  code: "PYTHON_PYPROJECT_NOTHING_TO_BUILD",
9616
9682
  message: 'Entrypoint "pyproject.toml" declares nothing to build. Set "tool.vercel.entrypoint" for a web app and/or declare "[[tool.vercel.subscribers]]" or "[[tool.vercel.workflows]]" entries in pyproject.toml.'
9617
9683
  });
@@ -9625,7 +9691,7 @@ var build = async ({
9625
9691
  filePath: entrypoint,
9626
9692
  // For schedule-triggered jobs, the WSGI variable is always 'app' (created dynamically).
9627
9693
  // For other services, handlerFunction is used as the entrypoint variable name.
9628
- varName: service && (0, import_build_utils20.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9694
+ varName: service && (0, import_build_utils22.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9629
9695
  } : void 0,
9630
9696
  service,
9631
9697
  repoRootPath
@@ -9634,8 +9700,8 @@ var build = async ({
9634
9700
  if (detected?.error && detected?.baseDir === void 0) {
9635
9701
  throw detected?.error;
9636
9702
  }
9637
- const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path17.dirname)(entrypoint) : ".");
9638
- const entrypointAbsDir = (0, import_path17.join)(workPath, entryDirectory);
9703
+ const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path19.dirname)(entrypoint) : ".");
9704
+ const entrypointAbsDir = (0, import_path19.join)(workPath, entryDirectory);
9639
9705
  const rootDir = repoRootPath ?? workPath;
9640
9706
  const pythonPackage = await builderSpan.child("vc.builder.python.discover").trace(
9641
9707
  () => discoverPackage({
@@ -9676,12 +9742,12 @@ var build = async ({
9676
9742
  }
9677
9743
  const uvVersion = checkUvBinaryVersion(uv.getPath());
9678
9744
  console.log(`Using ${uvVersion}`);
9679
- const venvPath = service?.name ? (0, import_path17.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path17.join)(workPath, ".vercel", "python", ".venv");
9680
- const hasCachedVenv = import_fs17.default.existsSync((0, import_path17.join)(venvPath, "pyvenv.cfg"));
9681
- const hasCachedUv = import_fs17.default.existsSync(uvCacheDir);
9745
+ const venvPath = service?.name ? (0, import_path19.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path19.join)(workPath, ".vercel", "python", ".venv");
9746
+ const hasCachedVenv = import_fs19.default.existsSync((0, import_path19.join)(venvPath, "pyvenv.cfg"));
9747
+ const hasCachedUv = import_fs19.default.existsSync(uvCacheDir);
9682
9748
  const restoredCache = hasCachedVenv && hasCachedUv ? "both" : hasCachedVenv ? "venv" : hasCachedUv ? "uv" : "none";
9683
9749
  if (hasCachedVenv || hasCachedUv) {
9684
- (0, import_build_utils20.debug)(
9750
+ (0, import_build_utils22.debug)(
9685
9751
  `Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
9686
9752
  );
9687
9753
  }
@@ -9693,14 +9759,14 @@ var build = async ({
9693
9759
  uvCacheDir
9694
9760
  });
9695
9761
  });
9696
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
9762
+ if ((0, import_build_utils22.isPythonFramework)(framework)) {
9697
9763
  const {
9698
9764
  cliType,
9699
9765
  lockfileVersion,
9700
9766
  packageJsonPackageManager,
9701
9767
  turboSupportsCorepackHome
9702
- } = await (0, import_build_utils20.scanParentDirs)(workPath, true);
9703
- spawnEnv = (0, import_build_utils20.getEnvForPackageManager)({
9768
+ } = await (0, import_build_utils22.scanParentDirs)(workPath, true);
9769
+ spawnEnv = (0, import_build_utils22.getEnvForPackageManager)({
9704
9770
  cliType,
9705
9771
  lockfileVersion,
9706
9772
  packageJsonPackageManager,
@@ -9725,13 +9791,13 @@ var build = async ({
9725
9791
  let uvLockPath = null;
9726
9792
  let uvProjectDir = null;
9727
9793
  let projectName;
9728
- await builderSpan.child(import_build_utils20.BUILDER_INSTALLER_STEP, {
9794
+ await builderSpan.child(import_build_utils22.BUILDER_INSTALLER_STEP, {
9729
9795
  installCommand: projectInstallCommand || void 0,
9730
9796
  runtime: "python",
9731
9797
  "python.cache.restored": restoredCache
9732
9798
  }).trace(async () => {
9733
9799
  if (projectInstallCommand) {
9734
- await import_fs17.default.promises.rm(venvPath, { recursive: true, force: true });
9800
+ await import_fs19.default.promises.rm(venvPath, { recursive: true, force: true });
9735
9801
  await ensureVenv({
9736
9802
  pythonVersion,
9737
9803
  venvPath,
@@ -9742,7 +9808,7 @@ var build = async ({
9742
9808
  console.log(
9743
9809
  `Running "install" command: \`${projectInstallCommand}\`...`
9744
9810
  );
9745
- await (0, import_build_utils20.execCommand)(projectInstallCommand, {
9811
+ await (0, import_build_utils22.execCommand)(projectInstallCommand, {
9746
9812
  env: pythonEnv,
9747
9813
  cwd: workPath
9748
9814
  });
@@ -9763,7 +9829,7 @@ var build = async ({
9763
9829
  }
9764
9830
  if (!assumeDepsInstalled) {
9765
9831
  const lockCacheKey = service?.name ? `uv.lock.${service.name}` : "uv.lock";
9766
- const cachedLockPath = (0, import_path17.join)(uvCacheDir, lockCacheKey);
9832
+ const cachedLockPath = (0, import_path19.join)(uvCacheDir, lockCacheKey);
9767
9833
  const { projectDir, lockPath, lockFileProvidedByUser } = await ensureUvProject({
9768
9834
  workPath,
9769
9835
  rootDir,
@@ -9784,21 +9850,21 @@ var build = async ({
9784
9850
  locked: !lockFileProvidedByUser,
9785
9851
  pythonPlatform: target.uvPlatform
9786
9852
  });
9787
- if (lockPath && import_fs17.default.existsSync(lockPath)) {
9788
- await import_fs17.default.promises.mkdir(uvCacheDir, { recursive: true });
9789
- await import_fs17.default.promises.copyFile(lockPath, cachedLockPath);
9853
+ if (lockPath && import_fs19.default.existsSync(lockPath)) {
9854
+ await import_fs19.default.promises.mkdir(uvCacheDir, { recursive: true });
9855
+ await import_fs19.default.promises.copyFile(lockPath, cachedLockPath);
9790
9856
  }
9791
9857
  }
9792
9858
  });
9793
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
9859
+ if ((0, import_build_utils22.isPythonFramework)(framework)) {
9794
9860
  const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
9795
9861
  config?.buildCommand;
9796
- await builderSpan.child(import_build_utils20.BUILDER_COMPILE_STEP, {
9862
+ await builderSpan.child(import_build_utils22.BUILDER_COMPILE_STEP, {
9797
9863
  buildCommand: projectBuildCommand || void 0
9798
9864
  }).trace(async () => {
9799
9865
  if (projectBuildCommand) {
9800
9866
  console.log(`Running "${projectBuildCommand}"`);
9801
- await (0, import_build_utils20.execCommand)(projectBuildCommand, {
9867
+ await (0, import_build_utils22.execCommand)(projectBuildCommand, {
9802
9868
  env: pythonEnv,
9803
9869
  cwd: workPath
9804
9870
  });
@@ -9825,12 +9891,14 @@ var build = async ({
9825
9891
  entrypoint = resolved?.entrypoint;
9826
9892
  const isWorkersOnly = !entrypoint && isPyprojectEntrypoint && (subscribers.length > 0 || workflows.length > 0);
9827
9893
  if (!entrypoint && !isWorkersOnly) {
9828
- throw new import_build_utils20.NowBuildError({
9894
+ throw new import_build_utils22.NowBuildError({
9829
9895
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
9830
9896
  message: "No Python entrypoint could be detected. Please specify an entrypoint file."
9831
9897
  });
9832
9898
  }
9833
9899
  const djangoStatic = hookResult?.djangoStatic ?? null;
9900
+ const fastapiStatic = hookResult?.fastapiStatic ?? null;
9901
+ const cdnOutputDir = djangoStatic?.cdnOutputDir ?? fastapiStatic?.cdnOutputDir ?? null;
9834
9902
  const pipPlatformArgs = target.uvPlatform ? ["--python-platform", target.uvPlatform] : [];
9835
9903
  await installInjectedPackage({
9836
9904
  name: "vercel-runtime",
@@ -9838,7 +9906,7 @@ var build = async ({
9838
9906
  envOverride: baseEnv.VERCEL_RUNTIME_PYTHON,
9839
9907
  uv,
9840
9908
  venvPath,
9841
- projectDir: (0, import_path17.join)(workPath, entryDirectory),
9909
+ projectDir: (0, import_path19.join)(workPath, entryDirectory),
9842
9910
  pipPlatformArgs
9843
9911
  });
9844
9912
  if (shouldInstallVercelWorkers) {
@@ -9848,7 +9916,7 @@ var build = async ({
9848
9916
  envOverride: baseEnv.VERCEL_WORKERS_PYTHON,
9849
9917
  uv,
9850
9918
  venvPath,
9851
- projectDir: (0, import_path17.join)(workPath, entryDirectory),
9919
+ projectDir: (0, import_path19.join)(workPath, entryDirectory),
9852
9920
  pipPlatformArgs
9853
9921
  });
9854
9922
  }
@@ -9861,11 +9929,11 @@ var build = async ({
9861
9929
  const capturedEnv = { ...pythonEnv };
9862
9930
  const capturedCwd = workPath;
9863
9931
  registerPreDeploy(async () => {
9864
- await builderSpan.child(import_build_utils20.BUILDER_PRE_DEPLOY_STEP, {
9932
+ await builderSpan.child(import_build_utils22.BUILDER_PRE_DEPLOY_STEP, {
9865
9933
  preDeployCommand
9866
9934
  }).trace(async () => {
9867
9935
  console.log(`Running pre-deploy command: \`${preDeployCommand}\``);
9868
- await (0, import_build_utils20.execCommand)(preDeployCommand, {
9936
+ await (0, import_build_utils22.execCommand)(preDeployCommand, {
9869
9937
  env: capturedEnv,
9870
9938
  cwd: capturedCwd
9871
9939
  });
@@ -9876,14 +9944,14 @@ var build = async ({
9876
9944
  let crons;
9877
9945
  let runtimeTrampoline;
9878
9946
  if (entrypoint) {
9879
- (0, import_build_utils20.debug)("Entrypoint is", entrypoint);
9947
+ (0, import_build_utils22.debug)("Entrypoint is", entrypoint);
9880
9948
  const moduleName = entrypointToModule(entrypoint);
9881
9949
  if (handlerFunction) {
9882
- const entrypointPath = (0, import_path17.join)(workPath, entrypoint);
9883
- const source = await import_fs17.default.promises.readFile(entrypointPath, "utf-8");
9884
- const found = await (0, import_python_analysis9.containsTopLevelCallable)(source, handlerFunction);
9950
+ const entrypointPath = (0, import_path19.join)(workPath, entrypoint);
9951
+ const source = await import_fs19.default.promises.readFile(entrypointPath, "utf-8");
9952
+ const found = await (0, import_python_analysis10.containsTopLevelCallable)(source, handlerFunction);
9885
9953
  if (!found) {
9886
- throw new import_build_utils20.NowBuildError({
9954
+ throw new import_build_utils22.NowBuildError({
9887
9955
  code: "PYTHON_HANDLER_NOT_FOUND",
9888
9956
  message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
9889
9957
  });
@@ -9891,7 +9959,7 @@ var build = async ({
9891
9959
  }
9892
9960
  const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
9893
9961
  const entrypointWithSuffix = `${entrypoint}${suffix}`;
9894
- (0, import_build_utils20.debug)("Entrypoint with suffix is", entrypointWithSuffix);
9962
+ (0, import_build_utils22.debug)("Entrypoint with suffix is", entrypointWithSuffix);
9895
9963
  crons = await getServiceCrons({
9896
9964
  service,
9897
9965
  entrypoint,
@@ -9952,34 +10020,38 @@ var build = async ({
9952
10020
  cwd: workPath,
9953
10021
  ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
9954
10022
  };
9955
- const files = await (0, import_build_utils20.glob)("**", globOptions);
10023
+ const files = await (0, import_build_utils22.glob)("**", globOptions);
10024
+ const appPythonSourceFiles = Object.keys(files).filter((file) => file.endsWith(".py")).map((file) => (0, import_path19.join)(workPath, file)).sort();
9956
10025
  if (djangoStatic?.manifestRelPath) {
9957
- files[djangoStatic.manifestRelPath] = new import_build_utils20.FileFsRef({
9958
- fsPath: (0, import_path17.join)(workPath, djangoStatic.manifestRelPath)
10026
+ files[djangoStatic.manifestRelPath] = new import_build_utils22.FileFsRef({
10027
+ fsPath: (0, import_path19.join)(workPath, djangoStatic.manifestRelPath)
9959
10028
  });
9960
10029
  }
9961
10030
  const handlerPyFilename = "vc__handler__python";
9962
10031
  if (config.framework === "fasthtml") {
9963
10032
  const { SESSKEY = "" } = process.env;
9964
- files[".sesskey"] = new import_build_utils20.FileBlob({ data: `"${SESSKEY}"` });
10033
+ files[".sesskey"] = new import_build_utils22.FileBlob({ data: `"${SESSKEY}"` });
9965
10034
  }
9966
- const depExternalizer = new PythonDependencyExternalizer({
9967
- venvPath,
9968
- vendorDir,
9969
- workPath,
9970
- uvLockPath,
9971
- uvProjectDir,
9972
- projectName,
9973
- pythonMajor: pythonVersion.major,
9974
- pythonMinor: pythonVersion.minor,
9975
- pythonPath: pythonVersion.pythonPath,
9976
- hasCustomCommand,
9977
- alwaysBundlePackages: [
9978
- ...quirksResult.alwaysBundlePackages ?? [],
9979
- ...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
9980
- ]
9981
- });
9982
10035
  await builderSpan.child("vc.builder.python.bundle").trace(async (bundleSpan) => {
10036
+ const installedDistributions = await InstalledPythonDistributions.load({
10037
+ venvPath,
10038
+ pythonMajor: pythonVersion.major,
10039
+ pythonMinor: pythonVersion.minor
10040
+ });
10041
+ const depExternalizer = new PythonDependencyExternalizer({
10042
+ installedDistributions,
10043
+ vendorDir,
10044
+ workPath,
10045
+ uvLockPath,
10046
+ uvProjectDir,
10047
+ projectName,
10048
+ pythonVersion,
10049
+ hasCustomCommand,
10050
+ alwaysBundlePackages: [
10051
+ ...quirksResult.alwaysBundlePackages ?? [],
10052
+ ...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
10053
+ ]
10054
+ });
9983
10055
  const depAnalysis = await depExternalizer.analyze(files, {
9984
10056
  onSized: ({ totalSizeBytes, runtimeInstallEnabled }) => {
9985
10057
  bundleSpan.setAttributes({
@@ -9990,29 +10062,39 @@ var build = async ({
9990
10062
  });
9991
10063
  }
9992
10064
  });
10065
+ const compileAllOptions = compileAllEnabled ? {
10066
+ pythonBin: getVenvPythonBin(venvPath),
10067
+ env: pythonEnv
10068
+ } : null;
10069
+ const compileSources = async ({
10070
+ includePackages,
10071
+ pycachePrefix
10072
+ }) => {
10073
+ if (!compileAllOptions)
10074
+ return;
10075
+ const vendorSourceFiles = installedDistributions.getPythonSourceFiles(includePackages);
10076
+ await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
10077
+ console.log("Compiling Python bytecode...");
10078
+ await runCompileAll({
10079
+ ...compileAllOptions,
10080
+ sourceFiles: [...appPythonSourceFiles, ...vendorSourceFiles],
10081
+ pycachePrefix
10082
+ });
10083
+ compileSpan.setAttributes({
10084
+ "python.compileall.enabled": "true",
10085
+ "python.compileall.appSourceFileCount": String(
10086
+ appPythonSourceFiles.length
10087
+ ),
10088
+ "python.compileall.vendorSourceFileCount": String(
10089
+ vendorSourceFiles.length
10090
+ )
10091
+ });
10092
+ });
10093
+ };
9993
10094
  const runCompileAllAndFillBytecode = async (capacityBytes, vendorPackageTiers) => {
9994
10095
  try {
9995
- await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
9996
- const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs17.default.existsSync(d));
9997
- const pythonBin = getVenvPythonBin(venvPath);
9998
- console.log("Compiling Python bytecode...");
9999
- await runCompileAll({
10000
- pythonBin,
10001
- filesOrDirectories: [workPath],
10002
- env: pythonEnv,
10003
- excludeRegex: getCompileAllAppExcludeRegex(workPath)
10004
- });
10005
- await runCompileAll({
10006
- pythonBin,
10007
- filesOrDirectories: sitePackageDirs,
10008
- env: pythonEnv
10009
- });
10010
- compileSpan.setAttributes({
10011
- "python.compileall.enabled": "true",
10012
- "python.compileall.sitePackageDirectoryCount": String(
10013
- sitePackageDirs.length
10014
- )
10015
- });
10096
+ await compileSources({
10097
+ includePackages: vendorPackageTiers?.flat()
10016
10098
  });
10017
10099
  const currentSize = await calculateBundleSize(files);
10018
10100
  let remainingCapacity = capacityBytes - currentSize;
@@ -10031,7 +10113,7 @@ var build = async ({
10031
10113
  }
10032
10114
  await addVendorBytecodeInTiers({
10033
10115
  files,
10034
- depExternalizer,
10116
+ installedDistributions,
10035
10117
  vendorDir,
10036
10118
  capacity: remainingCapacity,
10037
10119
  vendorPackageTiers: vendorPackageTiers ?? [void 0]
@@ -10040,7 +10122,7 @@ var build = async ({
10040
10122
  console.log(
10041
10123
  "Bytecode precompilation failed; continuing without precompiled bytecode."
10042
10124
  );
10043
- (0, import_build_utils20.debug)(`bytecode precompilation error details: ${err}`);
10125
+ (0, import_build_utils22.debug)(`bytecode precompilation error details: ${err}`);
10044
10126
  }
10045
10127
  };
10046
10128
  const runPrefixCompileAndFill = async (bundleResult) => {
@@ -10052,38 +10134,21 @@ var build = async ({
10052
10134
  const currentSize = await calculateBundleSize(files);
10053
10135
  let remainingCapacity = BYTECODE_FILL_CEILING_BYTES - currentSize;
10054
10136
  if (remainingCapacity <= 0) {
10055
- (0, import_build_utils20.debug)(
10137
+ (0, import_build_utils22.debug)(
10056
10138
  `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
10057
10139
  );
10058
10140
  return;
10059
10141
  }
10060
- const stagingDir = (0, import_path17.join)(workPath, ".vercel", "python", "pycache");
10061
- await import_fs17.default.promises.rm(stagingDir, { recursive: true, force: true });
10062
- await import_fs17.default.promises.mkdir(stagingDir, { recursive: true });
10063
- await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
10064
- const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs17.default.existsSync(d));
10065
- const pythonBin = getVenvPythonBin(venvPath);
10066
- console.log("Compiling Python bytecode...");
10067
- await runCompileAll({
10068
- pythonBin,
10069
- filesOrDirectories: [workPath],
10070
- env: pythonEnv,
10071
- excludeRegex: getCompileAllAppExcludeRegex(workPath),
10072
- pycachePrefix: stagingDir
10073
- });
10074
- await runCompileAll({
10075
- pythonBin,
10076
- filesOrDirectories: sitePackageDirs,
10077
- env: pythonEnv,
10078
- pycachePrefix: stagingDir
10079
- });
10080
- compileSpan.setAttributes({
10081
- "python.compileall.enabled": "true",
10082
- "python.compileall.mode": "pycache-prefix",
10083
- "python.compileall.sitePackageDirectoryCount": String(
10084
- sitePackageDirs.length
10085
- )
10086
- });
10142
+ const stagingDir = (0, import_path19.join)(workPath, ".vercel", "python", "pycache");
10143
+ await import_fs19.default.promises.rm(stagingDir, { recursive: true, force: true });
10144
+ await import_fs19.default.promises.mkdir(stagingDir, { recursive: true });
10145
+ await compileSources({
10146
+ includePackages: [
10147
+ ...bundleResult.alwaysBundledPackages ?? [],
10148
+ ...bundleResult.bundledPublicPackages ?? [],
10149
+ ...bundleResult.externalizedPublicPackages ?? []
10150
+ ],
10151
+ pycachePrefix: stagingDir
10087
10152
  });
10088
10153
  const beforeCount = Object.keys(files).length;
10089
10154
  const appInfo = await collectAppPrefixBytecodeFiles({
@@ -10103,7 +10168,7 @@ var build = async ({
10103
10168
  remainingCapacity = await addCollectedVendorBytecode({
10104
10169
  files,
10105
10170
  capacity: remainingCapacity,
10106
- collect: (include) => depExternalizer.collectPrefixBytecodeFiles({
10171
+ collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
10107
10172
  stagingDir,
10108
10173
  runtimeRoot: `/var/task/${vendorDir}`,
10109
10174
  includePackages: include ?? alwaysBundled
@@ -10113,7 +10178,7 @@ var build = async ({
10113
10178
  await addCollectedVendorBytecode({
10114
10179
  files,
10115
10180
  capacity: remainingCapacity,
10116
- collect: (include) => depExternalizer.collectPrefixBytecodeFiles({
10181
+ collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
10117
10182
  stagingDir,
10118
10183
  runtimeRoot: `${RUNTIME_DEPS_DIR}/lib/python${pyMajor}.${pyMinor}/site-packages`,
10119
10184
  includePackages: include ?? externalized
@@ -10126,7 +10191,7 @@ var build = async ({
10126
10191
  console.log(
10127
10192
  "Bytecode precompilation failed; continuing without precompiled bytecode."
10128
10193
  );
10129
- (0, import_build_utils20.debug)(`bytecode precompilation error details: ${err}`);
10194
+ (0, import_build_utils22.debug)(`bytecode precompilation error details: ${err}`);
10130
10195
  }
10131
10196
  };
10132
10197
  const announceLargeFunction = () => console.log(
@@ -10158,7 +10223,7 @@ var build = async ({
10158
10223
  bundleResult.bundledPublicPackages ?? []
10159
10224
  ]);
10160
10225
  } else {
10161
- (0, import_build_utils20.debug)(
10226
+ (0, import_build_utils22.debug)(
10162
10227
  `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
10163
10228
  );
10164
10229
  }
@@ -10182,7 +10247,7 @@ var build = async ({
10182
10247
  if (capacity > 0) {
10183
10248
  await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES);
10184
10249
  } else {
10185
- (0, import_build_utils20.debug)(
10250
+ (0, import_build_utils22.debug)(
10186
10251
  `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(depAnalysis.totalBundleSize / (1024 * 1024)).toFixed(2)} MB)`
10187
10252
  );
10188
10253
  }
@@ -10200,13 +10265,13 @@ var build = async ({
10200
10265
  if (entrypoint && runtimeTrampoline) {
10201
10266
  const webFiles = {
10202
10267
  ...files,
10203
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({ data: runtimeTrampoline })
10268
+ [`${handlerPyFilename}.py`]: new import_build_utils22.FileBlob({ data: runtimeTrampoline })
10204
10269
  };
10205
10270
  const lambdaOptions = await getPythonLambdaOptions({
10206
10271
  config,
10207
10272
  entrypoint
10208
10273
  });
10209
- output = new import_build_utils20.Lambda({
10274
+ output = new import_build_utils22.Lambda({
10210
10275
  files: webFiles,
10211
10276
  handler: `${handlerPyFilename}.vc_handler`,
10212
10277
  runtime: pythonVersion.runtime,
@@ -10228,10 +10293,10 @@ var build = async ({
10228
10293
  ...subscriber.triggerDefaults
10229
10294
  })
10230
10295
  );
10231
- subscriberLambdas[outputPath] = new import_build_utils20.Lambda({
10296
+ subscriberLambdas[outputPath] = new import_build_utils22.Lambda({
10232
10297
  files: {
10233
10298
  ...files,
10234
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({
10299
+ [`${handlerPyFilename}.py`]: new import_build_utils22.FileBlob({
10235
10300
  data: createRuntimeTrampoline({
10236
10301
  moduleName: subscriber.moduleName,
10237
10302
  entrypoint: subscriber.entrypoint,
@@ -10263,10 +10328,10 @@ var build = async ({
10263
10328
  consumer: getWorkflowConsumerName(workflow.name)
10264
10329
  }
10265
10330
  ];
10266
- workflowLambdas[outputPath] = new import_build_utils20.Lambda({
10331
+ workflowLambdas[outputPath] = new import_build_utils22.Lambda({
10267
10332
  files: {
10268
10333
  ...files,
10269
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({
10334
+ [`${handlerPyFilename}.py`]: new import_build_utils22.FileBlob({
10270
10335
  data: createRuntimeTrampoline({
10271
10336
  moduleName: workflow.moduleName,
10272
10337
  entrypoint: workflow.entrypoint,
@@ -10296,24 +10361,38 @@ var build = async ({
10296
10361
  pythonVersion,
10297
10362
  uvLockPath,
10298
10363
  framework,
10299
- serviceType: service ? (0, import_build_utils20.getReportedServiceType)(service) : void 0
10364
+ serviceType: service ? (0, import_build_utils22.getReportedServiceType)(service) : void 0
10300
10365
  });
10301
10366
  } catch (err) {
10302
- (0, import_build_utils20.debug)(
10367
+ (0, import_build_utils22.debug)(
10303
10368
  `Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
10304
10369
  );
10305
10370
  }
10306
10371
  }
10307
- if (!(0, import_build_utils20.isPythonFramework)(framework) && !service?.name && !isPyprojectEntrypoint) {
10372
+ if (!(0, import_build_utils22.isPythonFramework)(framework) && !service?.name && !isPyprojectEntrypoint) {
10308
10373
  (0, import_assert.default)(output, "web Lambda must exist for non-service builds");
10309
10374
  return { resultVersion: 3, result: { output } };
10310
10375
  }
10311
- const lambdaPath = service?.name && service.type ? `_svc/${service.name}/index` : "index";
10312
- const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils20.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
10376
+ const frameworkLambdaName = framework ?? "python";
10377
+ const lambdaPath = service?.name && service.type ? `_svc/${service.name}/index` : frameworkLambdaName;
10378
+ const staticFiles = cdnOutputDir ? await (0, import_build_utils22.glob)("**", { cwd: cdnOutputDir }) : {};
10313
10379
  const isNonWebService = service?.name && service.type && service.type !== "web";
10314
10380
  const routes = isNonWebService || !output ? void 0 : [
10315
10381
  { handle: "filesystem" },
10316
- { src: "/(.*)", dest: `/${lambdaPath}` }
10382
+ // This route matches the resolved destination after rewrites. Copy
10383
+ // that path into the runtime request before dispatching the shared
10384
+ // framework Lambda so application routing observes the rewrite.
10385
+ {
10386
+ src: "/(.*)",
10387
+ dest: `/${lambdaPath}`,
10388
+ transforms: [
10389
+ {
10390
+ type: "request.path",
10391
+ op: "set",
10392
+ args: "/$1"
10393
+ }
10394
+ ]
10395
+ }
10317
10396
  ];
10318
10397
  return {
10319
10398
  resultVersion: 2,
@@ -10344,14 +10423,14 @@ var prepareCache = async ({
10344
10423
  }
10345
10424
  } catch {
10346
10425
  }
10347
- return (0, import_build_utils20.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
10426
+ return (0, import_build_utils22.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
10348
10427
  cwd: root,
10349
10428
  ignore
10350
10429
  });
10351
10430
  };
10352
10431
  var shouldServe = (opts) => {
10353
10432
  const framework = opts.config.framework;
10354
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
10433
+ if ((0, import_build_utils22.isPythonFramework)(framework)) {
10355
10434
  const requestPath = opts.requestPath.replace(/\/$/, "");
10356
10435
  if (requestPath.startsWith("api") && opts.hasMatched) {
10357
10436
  return false;
@@ -10370,7 +10449,7 @@ var defaultShouldServe = ({
10370
10449
  if (entrypoint === requestPath && hasProp(files, entrypoint)) {
10371
10450
  return true;
10372
10451
  }
10373
- const { dir, name } = (0, import_path17.parse)(entrypoint);
10452
+ const { dir, name } = (0, import_path19.parse)(entrypoint);
10374
10453
  if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
10375
10454
  return true;
10376
10455
  }