@vercel/python 6.17.0 → 6.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +598 -138
  2. package/package.json +4 -4
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 fs6 = require("fs");
51
+ var fs8 = 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
- fs6.stat(path, function(er, stat) {
76
+ fs8.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(fs6.statSync(path), path, options);
81
+ return checkStat(fs8.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 fs6 = require("fs");
91
+ var fs8 = require("fs");
92
92
  function isexe(path, options, cb) {
93
- fs6.stat(path, function(er, stat) {
93
+ fs8.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(fs6.statSync(path), options);
98
+ return checkStat(fs8.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 fs6 = require("fs");
122
+ var fs8 = 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 fs6 = require("fs");
398
+ var fs8 = 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 = fs6.openSync(command, "r");
412
- fs6.readSync(fd, buffer, 0, size, 0);
413
- fs6.closeSync(fd);
411
+ fd = fs8.openSync(command, "r");
412
+ fs8.readSync(fd, buffer, 0, size, 0);
413
+ fs8.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 debug7;
426
+ var debug10;
427
427
  if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
428
- debug7 = function() {
428
+ debug10 = 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
- debug7 = function() {
434
+ debug10 = 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
- debug7(i, src[i]);
543
+ debug10(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
- debug7("SemVer", version2, options);
610
+ debug10("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
- debug7("SemVer.compare", this.version, this.options, other);
657
+ debug10("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
- debug7("prerelease compare", i2, a, b);
684
+ debug10("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
- debug7("comparator", comp, options);
938
+ debug10("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
- debug7("comp", this);
947
+ debug10("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
- debug7("Comparator.test", version2, this.options.loose);
970
+ debug10("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
- debug7("hyphen replace", range);
1053
+ debug10("hyphen replace", range);
1054
1054
  range = range.replace(safeRe[COMPARATORTRIM], comparatorTrimReplace);
1055
- debug7("comparator trim", range, safeRe[COMPARATORTRIM]);
1055
+ debug10("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
- debug7("comp", comp, options);
1095
+ debug10("comp", comp, options);
1096
1096
  comp = replaceCarets(comp, options);
1097
- debug7("caret", comp);
1097
+ debug10("caret", comp);
1098
1098
  comp = replaceTildes(comp, options);
1099
- debug7("tildes", comp);
1099
+ debug10("tildes", comp);
1100
1100
  comp = replaceXRanges(comp, options);
1101
- debug7("xrange", comp);
1101
+ debug10("xrange", comp);
1102
1102
  comp = replaceStars(comp, options);
1103
- debug7("stars", comp);
1103
+ debug10("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
- debug7("tilde", comp, _, M, m, p, pr);
1117
+ debug10("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
- debug7("replaceTilde pr", pr);
1126
+ debug10("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
- debug7("tilde return", ret);
1131
+ debug10("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
- debug7("caret", comp, options);
1141
+ debug10("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
- debug7("caret", comp, _, M, m, p, pr);
1144
+ debug10("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
- debug7("replaceCaret pr", pr);
1157
+ debug10("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
- debug7("no pr");
1168
+ debug10("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
- debug7("caret return", ret);
1179
+ debug10("caret return", ret);
1180
1180
  return ret;
1181
1181
  });
1182
1182
  }
1183
1183
  function replaceXRanges(comp, options) {
1184
- debug7("replaceXRanges", comp, options);
1184
+ debug10("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
- debug7("xRange", comp, ret, gtlt, M, m, p, pr);
1193
+ debug10("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
- debug7("xRange return", ret);
1236
+ debug10("xRange return", ret);
1237
1237
  return ret;
1238
1238
  });
1239
1239
  }
1240
1240
  function replaceStars(comp, options) {
1241
- debug7("replaceStars", comp, options);
1241
+ debug10("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
- debug7(set[i2].semver);
1289
+ debug10(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.2/node_modules/pump/index.js"(exports, module2) {
1896
1896
  var once = require_once();
1897
1897
  var eos = require_end_of_stream();
1898
- var fs6;
1898
+ var fs8;
1899
1899
  try {
1900
- fs6 = require("fs");
1900
+ fs8 = 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 (!fs6)
1912
+ if (!fs8)
1913
1913
  return false;
1914
- return (stream instanceof (fs6.ReadStream || noop) || stream instanceof (fs6.WriteStream || noop)) && isFn(stream.close);
1914
+ return (stream instanceof (fs8.ReadStream || noop) || stream instanceof (fs8.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: join8, delimiter: delimiter2, sep: sep2, posix } = require("path");
2654
+ var { join: join10, delimiter: delimiter2, sep: sep2, posix } = require("path");
2655
2655
  var isWindows = process.platform === "win32";
2656
2656
  var rSlash = new RegExp(`[${posix.sep}${sep2 === posix.sep ? "" : sep2}]`.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 + join8(pathPart, cmd);
2683
+ return prefix + join10(pathPart, cmd);
2684
2684
  };
2685
2685
  var which2 = async (cmd, opt = {}) => {
2686
2686
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
@@ -2867,15 +2867,15 @@ __export(src_exports, {
2867
2867
  version: () => version
2868
2868
  });
2869
2869
  module.exports = __toCommonJS(src_exports);
2870
- var import_fs6 = __toESM(require("fs"));
2870
+ var import_fs8 = __toESM(require("fs"));
2871
2871
  var import_util2 = require("util");
2872
- var import_path8 = require("path");
2872
+ var import_path10 = require("path");
2873
2873
 
2874
2874
  // src/package-versions.ts
2875
- var VERCEL_RUNTIME_VERSION = "0.5.2";
2875
+ var VERCEL_RUNTIME_VERSION = "0.5.3";
2876
2876
 
2877
2877
  // src/index.ts
2878
- var import_build_utils9 = require("@vercel/build-utils");
2878
+ var import_build_utils12 = require("@vercel/build-utils");
2879
2879
 
2880
2880
  // src/install.ts
2881
2881
  var import_execa3 = __toESM(require_execa());
@@ -3881,6 +3881,7 @@ var PythonDependencyExternalizer = class {
3881
3881
  this.noBuildCheckFailed = options.noBuildCheckFailed;
3882
3882
  this.pythonPath = options.pythonPath;
3883
3883
  this.hasCustomCommand = options.hasCustomCommand;
3884
+ this.alwaysBundlePackages = options.alwaysBundlePackages ?? [];
3884
3885
  }
3885
3886
  shouldEnableRuntimeInstall() {
3886
3887
  if (this.hasCustomCommand) {
@@ -4033,7 +4034,8 @@ ${error.fileContent}`
4033
4034
  const alwaysBundled = [
4034
4035
  ...classification.privatePackages,
4035
4036
  "vercel-runtime",
4036
- "vercel_runtime"
4037
+ "vercel_runtime",
4038
+ ...this.alwaysBundlePackages
4037
4039
  ];
4038
4040
  const alwaysBundledFiles = await mirrorPackagesIntoVendor({
4039
4041
  venvPath: this.venvPath,
@@ -4076,7 +4078,8 @@ ${error.fileContent}`
4076
4078
  }
4077
4079
  const bundledPackagesForConfig = [
4078
4080
  ...classification.privatePackages,
4079
- ...bundledPublic
4081
+ ...bundledPublic,
4082
+ ...this.alwaysBundlePackages
4080
4083
  ];
4081
4084
  const projectDirRel = (0, import_path5.relative)(this.workPath, this.uvProjectDir);
4082
4085
  const uvLockRel = (0, import_path5.relative)(this.workPath, this.uvLockPath);
@@ -4241,7 +4244,7 @@ async function calculatePerPackageSizes(venvPath) {
4241
4244
  }
4242
4245
 
4243
4246
  // src/index.ts
4244
- var import_build_utils10 = require("@vercel/build-utils");
4247
+ var import_build_utils13 = require("@vercel/build-utils");
4245
4248
 
4246
4249
  // src/start-dev-server.ts
4247
4250
  var import_child_process2 = require("child_process");
@@ -4877,9 +4880,462 @@ If you are using a virtual environment, activate it before running "vercel dev",
4877
4880
  }
4878
4881
  };
4879
4882
 
4883
+ // src/quirks/index.ts
4884
+ var import_build_utils11 = require("@vercel/build-utils");
4885
+ var import_python_analysis5 = require("@vercel/python-analysis");
4886
+
4887
+ // src/quirks/litellm.ts
4888
+ var import_fs6 = __toESM(require("fs"));
4889
+ var import_path8 = require("path");
4890
+ var import_build_utils9 = require("@vercel/build-utils");
4891
+ var LAMBDA_ROOT = "/var/task";
4892
+ var CONFIG_CANDIDATES = [
4893
+ "litellm_config.yaml",
4894
+ "litellm_config.yml",
4895
+ "litellm.yaml",
4896
+ "litellm.yml"
4897
+ ];
4898
+ async function findConfigFile(workPath) {
4899
+ for (const name of CONFIG_CANDIDATES) {
4900
+ const candidate = (0, import_path8.join)(workPath, name);
4901
+ try {
4902
+ await import_fs6.default.promises.access(candidate);
4903
+ return name;
4904
+ } catch {
4905
+ }
4906
+ }
4907
+ return null;
4908
+ }
4909
+ var litellmQuirk = {
4910
+ dependency: "litellm",
4911
+ runsBefore: ["prisma"],
4912
+ async run(ctx) {
4913
+ const buildEnv = {};
4914
+ const env = {};
4915
+ const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
4916
+ for (const sitePackages of sitePackagesDirs) {
4917
+ const schemaPath = (0, import_path8.join)(
4918
+ sitePackages,
4919
+ "litellm",
4920
+ "proxy",
4921
+ "schema.prisma"
4922
+ );
4923
+ try {
4924
+ await import_fs6.default.promises.access(schemaPath);
4925
+ (0, import_build_utils9.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
4926
+ buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
4927
+ break;
4928
+ } catch {
4929
+ }
4930
+ }
4931
+ if (!buildEnv.PRISMA_SCHEMA_PATH) {
4932
+ (0, import_build_utils9.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
4933
+ }
4934
+ if (!process.env.CONFIG_FILE_PATH) {
4935
+ const configName = await findConfigFile(ctx.workPath);
4936
+ if (configName) {
4937
+ (0, import_build_utils9.debug)(`LiteLLM quirk: found config at ${configName}`);
4938
+ buildEnv.CONFIG_FILE_PATH = (0, import_path8.join)(ctx.workPath, configName);
4939
+ env.CONFIG_FILE_PATH = (0, import_path8.join)(LAMBDA_ROOT, configName);
4940
+ }
4941
+ } else {
4942
+ (0, import_build_utils9.debug)(
4943
+ `LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
4944
+ );
4945
+ }
4946
+ return { buildEnv, env };
4947
+ }
4948
+ };
4949
+
4950
+ // src/quirks/prisma.ts
4951
+ var import_fs7 = __toESM(require("fs"));
4952
+ var import_path9 = require("path");
4953
+ var import_execa4 = __toESM(require_execa());
4954
+ var import_build_utils10 = require("@vercel/build-utils");
4955
+ var import_python_analysis4 = require("@vercel/python-analysis");
4956
+ function execErrorMessage(err) {
4957
+ if (err != null && typeof err === "object" && "stderr" in err) {
4958
+ const stderr = String(err.stderr);
4959
+ if (stderr)
4960
+ return stderr;
4961
+ }
4962
+ return err instanceof Error ? err.message : String(err);
4963
+ }
4964
+ var DUMMY_SCHEMA_NAME = "_prisma_dummy.prisma";
4965
+ var LAMBDA_ROOT2 = "/var/task";
4966
+ var RUNTIME_OPENSSL_VERSION = "3.2";
4967
+ function getLambdaBinaryTarget() {
4968
+ return process.arch === "arm64" ? "linux-arm64-openssl-3.0.x" : "rhel-openssl-3.0.x";
4969
+ }
4970
+ function buildDummySchema(generatedDir) {
4971
+ const lambdaTarget = getLambdaBinaryTarget();
4972
+ return `datasource db {
4973
+ provider = "sqlite"
4974
+ url = "file:dev.db"
4975
+ }
4976
+
4977
+ generator client {
4978
+ provider = "prisma-client-py"
4979
+ binaryTargets = ["native", "${lambdaTarget}"]
4980
+ output = "${generatedDir}"
4981
+ }
4982
+
4983
+ model DummyModel {
4984
+ id Int @id
4985
+ }
4986
+ `;
4987
+ }
4988
+ async function findUserSchema(workPath) {
4989
+ const envPath = process.env.PRISMA_SCHEMA_PATH;
4990
+ if (envPath) {
4991
+ const resolved = (0, import_path9.isAbsolute)(envPath) ? envPath : (0, import_path9.join)(workPath, envPath);
4992
+ try {
4993
+ await import_fs7.default.promises.access(resolved);
4994
+ return resolved;
4995
+ } catch {
4996
+ (0, import_build_utils10.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
4997
+ return null;
4998
+ }
4999
+ }
5000
+ const candidates = [
5001
+ (0, import_path9.join)(workPath, "schema.prisma"),
5002
+ (0, import_path9.join)(workPath, "prisma", "schema.prisma")
5003
+ ];
5004
+ for (const candidate of candidates) {
5005
+ try {
5006
+ await import_fs7.default.promises.access(candidate);
5007
+ return candidate;
5008
+ } catch {
5009
+ }
5010
+ }
5011
+ return null;
5012
+ }
5013
+ async function collectFiles(dir, base) {
5014
+ const result = [];
5015
+ let entries;
5016
+ try {
5017
+ entries = await import_fs7.default.promises.readdir(dir, { withFileTypes: true });
5018
+ } catch {
5019
+ return result;
5020
+ }
5021
+ for (const entry of entries) {
5022
+ if (entry.name === "__pycache__")
5023
+ continue;
5024
+ const full = (0, import_path9.join)(dir, entry.name);
5025
+ if (entry.isDirectory()) {
5026
+ result.push(...await collectFiles(full, base));
5027
+ } else {
5028
+ result.push((0, import_path9.relative)(base, full));
5029
+ }
5030
+ }
5031
+ return result;
5032
+ }
5033
+ async function cleanCacheArtifacts(cacheDir, extras = []) {
5034
+ const paths = [
5035
+ (0, import_path9.join)(cacheDir, "node_modules"),
5036
+ (0, import_path9.join)(cacheDir, "package.json"),
5037
+ (0, import_path9.join)(cacheDir, "package-lock.json"),
5038
+ ...extras
5039
+ ];
5040
+ for (const p of paths) {
5041
+ try {
5042
+ await import_fs7.default.promises.rm(p, { recursive: true, force: true });
5043
+ } catch (err) {
5044
+ console.warn(
5045
+ `could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
5046
+ );
5047
+ }
5048
+ }
5049
+ }
5050
+ async function isClientGenerated(pythonPath, env) {
5051
+ try {
5052
+ await (0, import_execa4.default)(pythonPath, ["-c", "import prisma.client"], {
5053
+ env,
5054
+ stdio: "pipe"
5055
+ });
5056
+ return true;
5057
+ } catch {
5058
+ return false;
5059
+ }
5060
+ }
5061
+ var prismaQuirk = {
5062
+ dependency: "prisma",
5063
+ async run(ctx) {
5064
+ const { venvPath, pythonEnv, workPath } = ctx;
5065
+ const pythonPath = getVenvPythonBin(venvPath);
5066
+ const runtimeCacheDir = (0, import_path9.join)(
5067
+ LAMBDA_ROOT2,
5068
+ resolveVendorDir(),
5069
+ "prisma",
5070
+ "__bincache__"
5071
+ );
5072
+ const sitePackagesDirs = await getVenvSitePackagesDirs(venvPath);
5073
+ let sitePackages;
5074
+ for (const dir of sitePackagesDirs) {
5075
+ try {
5076
+ await import_fs7.default.promises.access((0, import_path9.join)(dir, "prisma"));
5077
+ sitePackages = dir;
5078
+ break;
5079
+ } catch {
5080
+ }
5081
+ }
5082
+ if (!sitePackages) {
5083
+ console.warn(
5084
+ "prisma: could not find prisma in any site-packages directory"
5085
+ );
5086
+ return {};
5087
+ }
5088
+ const cacheDir = (0, import_path9.join)(sitePackages, "prisma", "__bincache__");
5089
+ await import_fs7.default.promises.mkdir(cacheDir, { recursive: true });
5090
+ const generateEnv = {
5091
+ ...pythonEnv,
5092
+ PRISMA_BINARY_CACHE_DIR: cacheDir
5093
+ };
5094
+ const generatedDir = (0, import_path9.join)(workPath, "_prisma_generated");
5095
+ const dummySchemaPath = (0, import_path9.join)(workPath, DUMMY_SCHEMA_NAME);
5096
+ await import_fs7.default.promises.writeFile(
5097
+ dummySchemaPath,
5098
+ buildDummySchema(generatedDir)
5099
+ );
5100
+ (0, import_build_utils10.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
5101
+ try {
5102
+ const dummyResult = await (0, import_execa4.default)(
5103
+ pythonPath,
5104
+ ["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
5105
+ {
5106
+ cwd: workPath,
5107
+ env: generateEnv,
5108
+ stdio: "pipe"
5109
+ }
5110
+ );
5111
+ if (dummyResult.stdout)
5112
+ (0, import_build_utils10.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
5113
+ if (dummyResult.stderr)
5114
+ (0, import_build_utils10.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
5115
+ } catch (err) {
5116
+ throw new import_build_utils10.NowBuildError({
5117
+ code: "PRISMA_GENERATE_FAILED",
5118
+ message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
5119
+ ` + execErrorMessage(err)
5120
+ });
5121
+ }
5122
+ const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
5123
+ const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
5124
+ const nodeModulesDir = (0, import_path9.join)(cacheDir, "node_modules", "prisma");
5125
+ let engineCopied = false;
5126
+ try {
5127
+ const entries = await import_fs7.default.promises.readdir(nodeModulesDir);
5128
+ for (const entry of entries) {
5129
+ if (!entry.startsWith(srcBinaryPrefix))
5130
+ continue;
5131
+ const srcPath = (0, import_path9.join)(nodeModulesDir, entry);
5132
+ const destPath = (0, import_path9.join)(cacheDir, runtimeName);
5133
+ try {
5134
+ await import_fs7.default.promises.access(destPath);
5135
+ (0, import_build_utils10.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
5136
+ } catch {
5137
+ (0, import_build_utils10.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
5138
+ await import_fs7.default.promises.copyFile(srcPath, destPath);
5139
+ }
5140
+ engineCopied = true;
5141
+ }
5142
+ } catch (err) {
5143
+ throw new import_build_utils10.NowBuildError({
5144
+ code: "PRISMA_ENGINE_NOT_FOUND",
5145
+ message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
5146
+ ` + (err instanceof Error ? err.message : String(err))
5147
+ });
5148
+ }
5149
+ if (!engineCopied) {
5150
+ throw new import_build_utils10.NowBuildError({
5151
+ code: "PRISMA_ENGINE_NOT_FOUND",
5152
+ message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
5153
+ });
5154
+ }
5155
+ const shimPath = (0, import_path9.join)(cacheDir, "openssl");
5156
+ await import_fs7.default.promises.writeFile(
5157
+ shimPath,
5158
+ `#!/bin/sh
5159
+ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
5160
+ `
5161
+ );
5162
+ await import_fs7.default.promises.chmod(shimPath, 493);
5163
+ for (const p of [generatedDir, dummySchemaPath]) {
5164
+ await import_fs7.default.promises.rm(p, { recursive: true, force: true });
5165
+ }
5166
+ await cleanCacheArtifacts(cacheDir);
5167
+ const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
5168
+ const userSchema = generateMode !== "never" ? await findUserSchema(workPath) : null;
5169
+ if (userSchema) {
5170
+ let shouldGenerate = true;
5171
+ if (generateMode === "auto") {
5172
+ const clientAlreadyGenerated = await isClientGenerated(
5173
+ pythonPath,
5174
+ pythonEnv
5175
+ );
5176
+ if (clientAlreadyGenerated) {
5177
+ (0, import_build_utils10.debug)(
5178
+ "Prisma quirk: client already generated, skipping user schema generate"
5179
+ );
5180
+ shouldGenerate = false;
5181
+ }
5182
+ }
5183
+ if (shouldGenerate) {
5184
+ (0, import_build_utils10.debug)(`Running prisma generate with user schema: ${userSchema}`);
5185
+ try {
5186
+ const userResult = await (0, import_execa4.default)(
5187
+ pythonPath,
5188
+ ["-m", "prisma", "generate", `--schema=${userSchema}`],
5189
+ {
5190
+ cwd: workPath,
5191
+ env: generateEnv,
5192
+ stdio: "pipe"
5193
+ }
5194
+ );
5195
+ if (userResult.stdout)
5196
+ (0, import_build_utils10.debug)(`prisma generate stdout: ${userResult.stdout}`);
5197
+ if (userResult.stderr)
5198
+ (0, import_build_utils10.debug)(`prisma generate stderr: ${userResult.stderr}`);
5199
+ } catch (err) {
5200
+ throw new import_build_utils10.NowBuildError({
5201
+ code: "PRISMA_GENERATE_FAILED",
5202
+ message: `\`prisma generate\` failed for schema "${userSchema}".
5203
+ ` + execErrorMessage(err)
5204
+ });
5205
+ }
5206
+ await cleanCacheArtifacts(cacheDir);
5207
+ }
5208
+ }
5209
+ try {
5210
+ const allFiles = await collectFiles(
5211
+ (0, import_path9.join)(sitePackages, "prisma"),
5212
+ sitePackages
5213
+ );
5214
+ const count = await (0, import_python_analysis4.extendDistRecord)(sitePackages, "prisma", allFiles);
5215
+ if (count > 0) {
5216
+ (0, import_build_utils10.debug)(`Appended ${count} entries to prisma RECORD`);
5217
+ }
5218
+ } catch (err) {
5219
+ console.warn(
5220
+ `could not patch prisma RECORD: ${err instanceof Error ? err.message : String(err)}`
5221
+ );
5222
+ }
5223
+ return {
5224
+ env: {
5225
+ PRISMA_BINARY_CACHE_DIR: runtimeCacheDir,
5226
+ VERCEL_RUNTIME_ENV_PATH_PREPEND: runtimeCacheDir
5227
+ },
5228
+ buildEnv: { PRISMA_BINARY_CACHE_DIR: cacheDir },
5229
+ alwaysBundlePackages: ["prisma"]
5230
+ };
5231
+ }
5232
+ };
5233
+
5234
+ // src/quirks/index.ts
5235
+ var quirks = [litellmQuirk, prismaQuirk];
5236
+ function toposortQuirks(activated) {
5237
+ const nameToQuirk = /* @__PURE__ */ new Map();
5238
+ for (const q of activated) {
5239
+ nameToQuirk.set((0, import_python_analysis5.normalizePackageName)(q.dependency), q);
5240
+ }
5241
+ const adj = /* @__PURE__ */ new Map();
5242
+ const inDegree = /* @__PURE__ */ new Map();
5243
+ for (const q of activated) {
5244
+ adj.set(q, /* @__PURE__ */ new Set());
5245
+ inDegree.set(q, 0);
5246
+ }
5247
+ for (const q of activated) {
5248
+ if (q.runsBefore) {
5249
+ for (const dep of q.runsBefore) {
5250
+ const target = nameToQuirk.get((0, import_python_analysis5.normalizePackageName)(dep));
5251
+ if (target) {
5252
+ adj.get(q).add(target);
5253
+ inDegree.set(target, inDegree.get(target) + 1);
5254
+ }
5255
+ }
5256
+ }
5257
+ if (q.runsAfter) {
5258
+ for (const dep of q.runsAfter) {
5259
+ const source = nameToQuirk.get((0, import_python_analysis5.normalizePackageName)(dep));
5260
+ if (source) {
5261
+ adj.get(source).add(q);
5262
+ inDegree.set(q, inDegree.get(q) + 1);
5263
+ }
5264
+ }
5265
+ }
5266
+ }
5267
+ const queue = [];
5268
+ for (const q of activated) {
5269
+ if (inDegree.get(q) === 0) {
5270
+ queue.push(q);
5271
+ }
5272
+ }
5273
+ const sorted = [];
5274
+ while (queue.length > 0) {
5275
+ const q = queue.shift();
5276
+ sorted.push(q);
5277
+ for (const neighbor of adj.get(q)) {
5278
+ const deg = inDegree.get(neighbor) - 1;
5279
+ inDegree.set(neighbor, deg);
5280
+ if (deg === 0) {
5281
+ queue.push(neighbor);
5282
+ }
5283
+ }
5284
+ }
5285
+ if (sorted.length !== activated.length) {
5286
+ const unsorted = activated.filter((q) => !sorted.includes(q)).map((q) => q.dependency);
5287
+ throw new Error(
5288
+ `Circular dependency detected among quirks: ${unsorted.join(", ")}`
5289
+ );
5290
+ }
5291
+ return sorted;
5292
+ }
5293
+ async function runQuirks(ctx) {
5294
+ const mergedEnv = {};
5295
+ const mergedBuildEnv = {};
5296
+ const mergedAlwaysBundle = [];
5297
+ const installedNames = /* @__PURE__ */ new Set();
5298
+ const sitePackageDirs = await getVenvSitePackagesDirs(ctx.venvPath);
5299
+ for (const dir of sitePackageDirs) {
5300
+ const distributions = await (0, import_python_analysis5.scanDistributions)(dir);
5301
+ for (const name of distributions.keys()) {
5302
+ installedNames.add((0, import_python_analysis5.normalizePackageName)(name));
5303
+ }
5304
+ }
5305
+ const activated = quirks.filter((quirk) => {
5306
+ const installed = installedNames.has(
5307
+ (0, import_python_analysis5.normalizePackageName)(quirk.dependency)
5308
+ );
5309
+ if (!installed) {
5310
+ (0, import_build_utils11.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
5311
+ }
5312
+ return installed;
5313
+ });
5314
+ const sorted = toposortQuirks(activated);
5315
+ for (const quirk of sorted) {
5316
+ (0, import_build_utils11.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
5317
+ const result = await quirk.run(ctx);
5318
+ if (result.env) {
5319
+ Object.assign(mergedEnv, result.env);
5320
+ }
5321
+ if (result.buildEnv) {
5322
+ Object.assign(mergedBuildEnv, result.buildEnv);
5323
+ Object.assign(process.env, result.buildEnv);
5324
+ }
5325
+ if (result.alwaysBundlePackages) {
5326
+ mergedAlwaysBundle.push(...result.alwaysBundlePackages);
5327
+ }
5328
+ }
5329
+ return {
5330
+ env: mergedEnv,
5331
+ buildEnv: mergedBuildEnv,
5332
+ alwaysBundlePackages: mergedAlwaysBundle
5333
+ };
5334
+ }
5335
+
4880
5336
  // src/index.ts
4881
- var readFile2 = (0, import_util2.promisify)(import_fs6.default.readFile);
4882
- var writeFile = (0, import_util2.promisify)(import_fs6.default.writeFile);
5337
+ var readFile2 = (0, import_util2.promisify)(import_fs8.default.readFile);
5338
+ var writeFile = (0, import_util2.promisify)(import_fs8.default.writeFile);
4883
5339
  var version = 3;
4884
5340
  async function downloadFilesInWorkPath({
4885
5341
  entrypoint,
@@ -4887,13 +5343,13 @@ async function downloadFilesInWorkPath({
4887
5343
  files,
4888
5344
  meta = {}
4889
5345
  }) {
4890
- (0, import_build_utils9.debug)("Downloading user files...");
4891
- let downloadedFiles = await (0, import_build_utils9.download)(files, workPath, meta);
5346
+ (0, import_build_utils12.debug)("Downloading user files...");
5347
+ let downloadedFiles = await (0, import_build_utils12.download)(files, workPath, meta);
4892
5348
  if (meta.isDev) {
4893
- const { devCacheDir = (0, import_path8.join)(workPath, ".now", "cache") } = meta;
4894
- const destCache = (0, import_path8.join)(devCacheDir, (0, import_path8.basename)(entrypoint, ".py"));
4895
- await (0, import_build_utils9.download)(downloadedFiles, destCache);
4896
- downloadedFiles = await (0, import_build_utils9.glob)("**", destCache);
5349
+ const { devCacheDir = (0, import_path10.join)(workPath, ".now", "cache") } = meta;
5350
+ const destCache = (0, import_path10.join)(devCacheDir, (0, import_path10.basename)(entrypoint, ".py"));
5351
+ await (0, import_build_utils12.download)(downloadedFiles, destCache);
5352
+ downloadedFiles = await (0, import_build_utils12.glob)("**", destCache);
4897
5353
  workPath = destCache;
4898
5354
  }
4899
5355
  return workPath;
@@ -4910,7 +5366,7 @@ var build = async ({
4910
5366
  let spawnEnv;
4911
5367
  let projectInstallCommand;
4912
5368
  let hasCustomCommand = false;
4913
- (0, import_build_utils9.debug)(`workPath: ${workPath}`);
5369
+ (0, import_build_utils12.debug)(`workPath: ${workPath}`);
4914
5370
  workPath = await downloadFilesInWorkPath({
4915
5371
  workPath,
4916
5372
  files: originalFiles,
@@ -4919,72 +5375,28 @@ var build = async ({
4919
5375
  });
4920
5376
  try {
4921
5377
  if (meta.isDev) {
4922
- const setupCfg = (0, import_path8.join)(workPath, "setup.cfg");
5378
+ const setupCfg = (0, import_path10.join)(workPath, "setup.cfg");
4923
5379
  await writeFile(setupCfg, "[install]\nprefix=\n");
4924
5380
  }
4925
5381
  } catch (err) {
4926
5382
  console.log('Failed to create "setup.cfg" file');
4927
5383
  throw err;
4928
5384
  }
4929
- if ((0, import_build_utils9.isPythonFramework)(framework)) {
4930
- const {
4931
- cliType,
4932
- lockfileVersion,
4933
- packageJsonPackageManager,
4934
- turboSupportsCorepackHome
4935
- } = await (0, import_build_utils9.scanParentDirs)(workPath, true);
4936
- spawnEnv = (0, import_build_utils9.getEnvForPackageManager)({
4937
- cliType,
4938
- lockfileVersion,
4939
- packageJsonPackageManager,
4940
- env: process.env,
4941
- turboSupportsCorepackHome,
4942
- projectCreatedAt: config?.projectSettings?.createdAt
4943
- });
4944
- const installCommand = config?.projectSettings?.installCommand;
4945
- if (typeof installCommand === "string") {
4946
- const trimmed = installCommand.trim();
4947
- if (trimmed) {
4948
- projectInstallCommand = trimmed;
4949
- } else {
4950
- console.log('Skipping "install" command...');
4951
- }
4952
- }
4953
- const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
4954
- config?.buildCommand;
4955
- if (projectBuildCommand) {
4956
- console.log(`Running "${projectBuildCommand}"`);
4957
- await (0, import_build_utils9.execCommand)(projectBuildCommand, {
4958
- env: spawnEnv,
4959
- cwd: workPath
4960
- });
4961
- hasCustomCommand = true;
4962
- } else {
4963
- const ranBuildScript = await runPyprojectScript(
4964
- workPath,
4965
- ["vercel-build", "now-build", "build"],
4966
- spawnEnv
4967
- );
4968
- if (ranBuildScript) {
4969
- hasCustomCommand = true;
4970
- }
4971
- }
4972
- }
4973
- let fsFiles = await (0, import_build_utils9.glob)("**", workPath);
4974
- if ((0, import_build_utils9.isPythonFramework)(framework) && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
5385
+ let fsFiles = await (0, import_build_utils12.glob)("**", workPath);
5386
+ if ((0, import_build_utils12.isPythonFramework)(framework) && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
4975
5387
  const detected = await detectPythonEntrypoint(
4976
5388
  config.framework,
4977
5389
  workPath,
4978
5390
  entrypoint
4979
5391
  );
4980
5392
  if (detected) {
4981
- (0, import_build_utils9.debug)(
5393
+ (0, import_build_utils12.debug)(
4982
5394
  `Resolved Python entrypoint to "${detected}" (configured "${entrypoint}" not found).`
4983
5395
  );
4984
5396
  entrypoint = detected;
4985
5397
  } else {
4986
5398
  const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
4987
- throw new import_build_utils9.NowBuildError({
5399
+ throw new import_build_utils12.NowBuildError({
4988
5400
  code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
4989
5401
  message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
4990
5402
  link: `https://vercel.com/docs/frameworks/backend/${framework}#exporting-the-${framework}-application`,
@@ -4992,7 +5404,7 @@ var build = async ({
4992
5404
  });
4993
5405
  }
4994
5406
  }
4995
- const entryDirectory = (0, import_path8.dirname)(entrypoint);
5407
+ const entryDirectory = (0, import_path10.dirname)(entrypoint);
4996
5408
  const pyprojectDir = findDir({
4997
5409
  file: "pyproject.toml",
4998
5410
  entryDirectory,
@@ -5015,37 +5427,37 @@ var build = async ({
5015
5427
  if (pythonVersionFileDir) {
5016
5428
  try {
5017
5429
  const content = await readFile2(
5018
- (0, import_path8.join)(pythonVersionFileDir, ".python-version"),
5430
+ (0, import_path10.join)(pythonVersionFileDir, ".python-version"),
5019
5431
  "utf8"
5020
5432
  );
5021
5433
  const version2 = parsePythonVersionFile(content);
5022
5434
  if (version2) {
5023
5435
  declaredPythonVersion = { version: version2, source: ".python-version" };
5024
- (0, import_build_utils9.debug)(`Found Python version ${version2} in .python-version`);
5436
+ (0, import_build_utils12.debug)(`Found Python version ${version2} in .python-version`);
5025
5437
  }
5026
5438
  } catch (err) {
5027
- (0, import_build_utils9.debug)("Failed to read .python-version file", err);
5439
+ (0, import_build_utils12.debug)("Failed to read .python-version file", err);
5028
5440
  }
5029
5441
  }
5030
5442
  if (!declaredPythonVersion && pyprojectDir) {
5031
5443
  let requiresPython;
5032
5444
  try {
5033
- const pyproject = await (0, import_build_utils10.readConfigFile)((0, import_path8.join)(pyprojectDir, "pyproject.toml"));
5445
+ const pyproject = await (0, import_build_utils13.readConfigFile)((0, import_path10.join)(pyprojectDir, "pyproject.toml"));
5034
5446
  requiresPython = pyproject?.project?.["requires-python"];
5035
5447
  } catch (err) {
5036
- (0, import_build_utils9.debug)("Failed to parse pyproject.toml", err);
5448
+ (0, import_build_utils12.debug)("Failed to parse pyproject.toml", err);
5037
5449
  }
5038
5450
  if (typeof requiresPython === "string" && requiresPython.trim()) {
5039
5451
  declaredPythonVersion = {
5040
5452
  version: requiresPython.trim(),
5041
5453
  source: "pyproject.toml"
5042
5454
  };
5043
- (0, import_build_utils9.debug)(`Found requires-python "${requiresPython}" in pyproject.toml`);
5455
+ (0, import_build_utils12.debug)(`Found requires-python "${requiresPython}" in pyproject.toml`);
5044
5456
  }
5045
5457
  }
5046
5458
  if (!declaredPythonVersion && pipfileLockDir) {
5047
5459
  let lock = {};
5048
- const pipfileLockPath = (0, import_path8.join)(pipfileLockDir, "Pipfile.lock");
5460
+ const pipfileLockPath = (0, import_path10.join)(pipfileLockDir, "Pipfile.lock");
5049
5461
  try {
5050
5462
  const pipfileLockContent = await readFile2(pipfileLockPath, "utf8");
5051
5463
  try {
@@ -5058,7 +5470,7 @@ ${pipfileLockContent}`
5058
5470
  throw err;
5059
5471
  }
5060
5472
  } catch (err) {
5061
- throw new import_build_utils9.NowBuildError({
5473
+ throw new import_build_utils12.NowBuildError({
5062
5474
  code: "INVALID_PIPFILE_LOCK",
5063
5475
  message: "Unable to parse Pipfile.lock"
5064
5476
  });
@@ -5066,7 +5478,7 @@ ${pipfileLockContent}`
5066
5478
  const pyFromLock = lock?._meta?.requires?.python_version;
5067
5479
  if (pyFromLock) {
5068
5480
  declaredPythonVersion = { version: pyFromLock, source: "Pipfile.lock" };
5069
- (0, import_build_utils9.debug)(`Found Python version ${pyFromLock} in Pipfile.lock`);
5481
+ (0, import_build_utils12.debug)(`Found Python version ${pyFromLock} in Pipfile.lock`);
5070
5482
  }
5071
5483
  }
5072
5484
  const pythonVersion = getSupportedPythonVersion({
@@ -5076,26 +5488,51 @@ ${pipfileLockContent}`
5076
5488
  const selectedVersionTuple = parseVersionTuple(pythonVersion.version);
5077
5489
  const defaultVersionTuple = parseVersionTuple(DEFAULT_PYTHON_VERSION);
5078
5490
  if (!pythonVersionFileDir && pyprojectDir && declaredPythonVersion?.source === "pyproject.toml" && selectedVersionTuple && defaultVersionTuple && compareTuples(selectedVersionTuple, defaultVersionTuple) <= 0) {
5079
- const pythonVersionFilePath = (0, import_path8.join)(pyprojectDir, ".python-version");
5491
+ const pythonVersionFilePath = (0, import_path10.join)(pyprojectDir, ".python-version");
5080
5492
  await writeFile(pythonVersionFilePath, `${pythonVersion.version}
5081
5493
  `);
5082
5494
  console.log(
5083
5495
  `Writing .python-version file with version ${pythonVersion.version}`
5084
5496
  );
5085
5497
  }
5086
- fsFiles = await (0, import_build_utils9.glob)("**", workPath);
5087
- const venvPath = (0, import_path8.join)(workPath, ".vercel", "python", ".venv");
5498
+ fsFiles = await (0, import_build_utils12.glob)("**", workPath);
5499
+ const venvPath = (0, import_path10.join)(workPath, ".vercel", "python", ".venv");
5088
5500
  await ensureVenv({
5089
5501
  pythonPath: pythonVersion.pythonPath,
5090
5502
  venvPath
5091
5503
  });
5504
+ if ((0, import_build_utils12.isPythonFramework)(framework)) {
5505
+ const {
5506
+ cliType,
5507
+ lockfileVersion,
5508
+ packageJsonPackageManager,
5509
+ turboSupportsCorepackHome
5510
+ } = await (0, import_build_utils12.scanParentDirs)(workPath, true);
5511
+ spawnEnv = (0, import_build_utils12.getEnvForPackageManager)({
5512
+ cliType,
5513
+ lockfileVersion,
5514
+ packageJsonPackageManager,
5515
+ env: process.env,
5516
+ turboSupportsCorepackHome,
5517
+ projectCreatedAt: config?.projectSettings?.createdAt
5518
+ });
5519
+ const installCommand = config?.projectSettings?.installCommand;
5520
+ if (typeof installCommand === "string") {
5521
+ const trimmed = installCommand.trim();
5522
+ if (trimmed) {
5523
+ projectInstallCommand = trimmed;
5524
+ } else {
5525
+ console.log('Skipping "install" command...');
5526
+ }
5527
+ }
5528
+ }
5092
5529
  const baseEnv = spawnEnv || process.env;
5093
5530
  const pythonEnv = createVenvEnv(venvPath, baseEnv);
5094
5531
  pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
5095
5532
  let assumeDepsInstalled = false;
5096
5533
  if (projectInstallCommand) {
5097
5534
  console.log(`Running "install" command: \`${projectInstallCommand}\`...`);
5098
- await (0, import_build_utils9.execCommand)(projectInstallCommand, {
5535
+ await (0, import_build_utils12.execCommand)(projectInstallCommand, {
5099
5536
  env: pythonEnv,
5100
5537
  cwd: workPath
5101
5538
  });
@@ -5156,7 +5593,7 @@ ${pipfileLockContent}`
5156
5593
  });
5157
5594
  } catch (err) {
5158
5595
  noBuildCheckFailed = true;
5159
- (0, import_build_utils9.debug)(
5596
+ (0, import_build_utils12.debug)(
5160
5597
  `--no-build check failed: ${err instanceof Error ? err.message : String(err)}`
5161
5598
  );
5162
5599
  }
@@ -5168,19 +5605,40 @@ ${pipfileLockContent}`
5168
5605
  locked: !lockFileProvidedByUser
5169
5606
  });
5170
5607
  }
5608
+ if ((0, import_build_utils12.isPythonFramework)(framework)) {
5609
+ const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
5610
+ config?.buildCommand;
5611
+ if (projectBuildCommand) {
5612
+ console.log(`Running "${projectBuildCommand}"`);
5613
+ await (0, import_build_utils12.execCommand)(projectBuildCommand, {
5614
+ env: pythonEnv,
5615
+ cwd: workPath
5616
+ });
5617
+ } else {
5618
+ await runPyprojectScript(
5619
+ workPath,
5620
+ ["vercel-build", "now-build", "build"],
5621
+ pythonEnv
5622
+ );
5623
+ }
5624
+ }
5171
5625
  const runtimeDep = baseEnv.VERCEL_RUNTIME_PYTHON || `vercel-runtime==${VERCEL_RUNTIME_VERSION}`;
5172
- (0, import_build_utils9.debug)(`Installing ${runtimeDep}`);
5626
+ (0, import_build_utils12.debug)(`Installing ${runtimeDep}`);
5173
5627
  await uv.pip({
5174
5628
  venvPath,
5175
- projectDir: (0, import_path8.join)(workPath, entryDirectory),
5629
+ projectDir: (0, import_path10.join)(workPath, entryDirectory),
5176
5630
  args: ["install", runtimeDep]
5177
5631
  });
5178
- (0, import_build_utils9.debug)("Entrypoint is", entrypoint);
5632
+ const quirksResult = await runQuirks({ venvPath, pythonEnv, workPath });
5633
+ if (quirksResult.buildEnv) {
5634
+ Object.assign(pythonEnv, quirksResult.buildEnv);
5635
+ }
5636
+ (0, import_build_utils12.debug)("Entrypoint is", entrypoint);
5179
5637
  const moduleName = entrypoint.replace(/\//g, ".").replace(/\.py$/i, "");
5180
5638
  const vendorDir = resolveVendorDir();
5181
5639
  const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
5182
5640
  const entrypointWithSuffix = `${entrypoint}${suffix}`;
5183
- (0, import_build_utils9.debug)("Entrypoint with suffix is", entrypointWithSuffix);
5641
+ (0, import_build_utils12.debug)("Entrypoint with suffix is", entrypointWithSuffix);
5184
5642
  const runtimeTrampoline = `
5185
5643
  import importlib
5186
5644
  import os
@@ -5239,11 +5697,12 @@ from vercel_runtime.vc_init import vc_handler
5239
5697
  ];
5240
5698
  const lambdaEnv = {};
5241
5699
  lambdaEnv.PYTHONPATH = vendorDir;
5700
+ Object.assign(lambdaEnv, quirksResult.env);
5242
5701
  const globOptions = {
5243
5702
  cwd: workPath,
5244
5703
  ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
5245
5704
  };
5246
- const files = await (0, import_build_utils9.glob)("**", globOptions);
5705
+ const files = await (0, import_build_utils12.glob)("**", globOptions);
5247
5706
  const depExternalizer = new PythonDependencyExternalizer({
5248
5707
  venvPath,
5249
5708
  vendorDir,
@@ -5253,7 +5712,8 @@ from vercel_runtime.vc_init import vc_handler
5253
5712
  projectName,
5254
5713
  noBuildCheckFailed,
5255
5714
  pythonPath: pythonVersion.pythonPath,
5256
- hasCustomCommand
5715
+ hasCustomCommand,
5716
+ alwaysBundlePackages: quirksResult.alwaysBundlePackages
5257
5717
  });
5258
5718
  const { runtimeInstallEnabled, allVendorFiles } = await depExternalizer.analyze(files);
5259
5719
  if (runtimeInstallEnabled) {
@@ -5264,12 +5724,12 @@ from vercel_runtime.vc_init import vc_handler
5264
5724
  }
5265
5725
  }
5266
5726
  const handlerPyFilename = "vc__handler__python";
5267
- files[`${handlerPyFilename}.py`] = new import_build_utils9.FileBlob({ data: runtimeTrampoline });
5727
+ files[`${handlerPyFilename}.py`] = new import_build_utils12.FileBlob({ data: runtimeTrampoline });
5268
5728
  if (config.framework === "fasthtml") {
5269
5729
  const { SESSKEY = "" } = process.env;
5270
- files[".sesskey"] = new import_build_utils9.FileBlob({ data: `"${SESSKEY}"` });
5730
+ files[".sesskey"] = new import_build_utils12.FileBlob({ data: `"${SESSKEY}"` });
5271
5731
  }
5272
- const output = new import_build_utils9.Lambda({
5732
+ const output = new import_build_utils12.Lambda({
5273
5733
  files,
5274
5734
  handler: `${handlerPyFilename}.vc_handler`,
5275
5735
  runtime: pythonVersion.runtime,
@@ -5280,7 +5740,7 @@ from vercel_runtime.vc_init import vc_handler
5280
5740
  };
5281
5741
  var shouldServe = (opts) => {
5282
5742
  const framework = opts.config.framework;
5283
- if ((0, import_build_utils9.isPythonFramework)(framework)) {
5743
+ if ((0, import_build_utils12.isPythonFramework)(framework)) {
5284
5744
  const requestPath = opts.requestPath.replace(/\/$/, "");
5285
5745
  if (requestPath.startsWith("api") && opts.hasMatched) {
5286
5746
  return false;
@@ -5299,7 +5759,7 @@ var defaultShouldServe = ({
5299
5759
  if (entrypoint === requestPath && hasProp(files, entrypoint)) {
5300
5760
  return true;
5301
5761
  }
5302
- const { dir, name } = (0, import_path8.parse)(entrypoint);
5762
+ const { dir, name } = (0, import_path10.parse)(entrypoint);
5303
5763
  if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
5304
5764
  return true;
5305
5765
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "6.17.0",
3
+ "version": "6.18.1",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -15,7 +15,7 @@
15
15
  "directory": "packages/python"
16
16
  },
17
17
  "dependencies": {
18
- "@vercel/python-analysis": "0.8.0"
18
+ "@vercel/python-analysis": "0.8.1"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@renovatebot/pep440": "4.2.1",
@@ -35,9 +35,9 @@
35
35
  "which": "3.0.0",
36
36
  "get-port": "5.1.1",
37
37
  "is-port-reachable": "3.1.0",
38
- "@vercel/build-utils": "13.6.0",
38
+ "@vercel/python-runtime": "0.5.3",
39
39
  "@vercel/error-utils": "2.0.3",
40
- "@vercel/python-runtime": "0.5.2"
40
+ "@vercel/build-utils": "13.6.1"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "node ../../utils/build-builder.mjs",