@vercel/python 6.14.1 → 6.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +499 -383
- package/package.json +5 -4
- package/vc_init_dev_asgi.py +82 -4
- package/vc_init_dev_wsgi.py +60 -0
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
|
|
51
|
+
var fs6 = 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
|
-
|
|
76
|
+
fs6.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(
|
|
81
|
+
return checkStat(fs6.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
|
|
91
|
+
var fs6 = require("fs");
|
|
92
92
|
function isexe(path, options, cb) {
|
|
93
|
-
|
|
93
|
+
fs6.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(
|
|
98
|
+
return checkStat(fs6.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
|
|
122
|
+
var fs6 = 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
|
|
398
|
+
var fs6 = 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 =
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
fd = fs6.openSync(command, "r");
|
|
412
|
+
fs6.readSync(fd, buffer, 0, size, 0);
|
|
413
|
+
fs6.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
|
|
426
|
+
var debug7;
|
|
427
427
|
if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
|
|
428
|
-
|
|
428
|
+
debug7 = 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
|
-
|
|
434
|
+
debug7 = 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
|
-
|
|
543
|
+
debug7(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
|
-
|
|
610
|
+
debug7("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
|
-
|
|
657
|
+
debug7("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
|
-
|
|
684
|
+
debug7("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
|
-
|
|
938
|
+
debug7("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
|
-
|
|
947
|
+
debug7("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
|
-
|
|
970
|
+
debug7("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
|
-
|
|
1053
|
+
debug7("hyphen replace", range);
|
|
1054
1054
|
range = range.replace(safeRe[COMPARATORTRIM], comparatorTrimReplace);
|
|
1055
|
-
|
|
1055
|
+
debug7("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
|
-
|
|
1095
|
+
debug7("comp", comp, options);
|
|
1096
1096
|
comp = replaceCarets(comp, options);
|
|
1097
|
-
|
|
1097
|
+
debug7("caret", comp);
|
|
1098
1098
|
comp = replaceTildes(comp, options);
|
|
1099
|
-
|
|
1099
|
+
debug7("tildes", comp);
|
|
1100
1100
|
comp = replaceXRanges(comp, options);
|
|
1101
|
-
|
|
1101
|
+
debug7("xrange", comp);
|
|
1102
1102
|
comp = replaceStars(comp, options);
|
|
1103
|
-
|
|
1103
|
+
debug7("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
|
-
|
|
1117
|
+
debug7("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
|
-
|
|
1126
|
+
debug7("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
|
-
|
|
1131
|
+
debug7("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
|
-
|
|
1141
|
+
debug7("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
|
-
|
|
1144
|
+
debug7("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
|
-
|
|
1157
|
+
debug7("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
|
-
|
|
1168
|
+
debug7("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
|
-
|
|
1179
|
+
debug7("caret return", ret);
|
|
1180
1180
|
return ret;
|
|
1181
1181
|
});
|
|
1182
1182
|
}
|
|
1183
1183
|
function replaceXRanges(comp, options) {
|
|
1184
|
-
|
|
1184
|
+
debug7("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
|
-
|
|
1193
|
+
debug7("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
|
-
|
|
1236
|
+
debug7("xRange return", ret);
|
|
1237
1237
|
return ret;
|
|
1238
1238
|
});
|
|
1239
1239
|
}
|
|
1240
1240
|
function replaceStars(comp, options) {
|
|
1241
|
-
|
|
1241
|
+
debug7("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
|
-
|
|
1289
|
+
debug7(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
|
|
1898
|
+
var fs6;
|
|
1899
1899
|
try {
|
|
1900
|
-
|
|
1900
|
+
fs6 = 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 (!
|
|
1912
|
+
if (!fs6)
|
|
1913
1913
|
return false;
|
|
1914
|
-
return (stream instanceof (
|
|
1914
|
+
return (stream instanceof (fs6.ReadStream || noop) || stream instanceof (fs6.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:
|
|
2654
|
+
var { join: join8, 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 +
|
|
2683
|
+
return prefix + join8(pathPart, cmd);
|
|
2684
2684
|
};
|
|
2685
2685
|
var which2 = async (cmd, opt = {}) => {
|
|
2686
2686
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -2743,21 +2743,20 @@ __export(src_exports, {
|
|
|
2743
2743
|
downloadFilesInWorkPath: () => downloadFilesInWorkPath,
|
|
2744
2744
|
installRequirement: () => installRequirement,
|
|
2745
2745
|
installRequirementsFile: () => installRequirementsFile,
|
|
2746
|
-
shouldEnableRuntimeInstall: () => shouldEnableRuntimeInstall,
|
|
2747
2746
|
shouldServe: () => shouldServe,
|
|
2748
2747
|
startDevServer: () => startDevServer,
|
|
2749
2748
|
version: () => version
|
|
2750
2749
|
});
|
|
2751
2750
|
module.exports = __toCommonJS(src_exports);
|
|
2752
|
-
var
|
|
2753
|
-
var
|
|
2754
|
-
var
|
|
2751
|
+
var import_fs6 = __toESM(require("fs"));
|
|
2752
|
+
var import_util2 = require("util");
|
|
2753
|
+
var import_path8 = require("path");
|
|
2755
2754
|
|
|
2756
2755
|
// src/runtime-version.ts
|
|
2757
|
-
var VERCEL_RUNTIME_VERSION = "0.
|
|
2756
|
+
var VERCEL_RUNTIME_VERSION = "0.5.1";
|
|
2758
2757
|
|
|
2759
2758
|
// src/index.ts
|
|
2760
|
-
var
|
|
2759
|
+
var import_build_utils9 = require("@vercel/build-utils");
|
|
2761
2760
|
|
|
2762
2761
|
// src/install.ts
|
|
2763
2762
|
var import_execa3 = __toESM(require_execa());
|
|
@@ -3418,8 +3417,6 @@ function isInstalled({ version: version2 }) {
|
|
|
3418
3417
|
}
|
|
3419
3418
|
|
|
3420
3419
|
// src/install.ts
|
|
3421
|
-
var LAMBDA_SIZE_THRESHOLD_BYTES = 249 * 1024 * 1024;
|
|
3422
|
-
var LAMBDA_EPHEMERAL_STORAGE_BYTES = 500 * 1024 * 1024;
|
|
3423
3420
|
var makeDependencyCheckCode = (dependency) => `
|
|
3424
3421
|
from importlib import util
|
|
3425
3422
|
dep = '${dependency}'.replace('-', '_')
|
|
@@ -3739,38 +3736,305 @@ async function installRequirementsFile({
|
|
|
3739
3736
|
targetDir
|
|
3740
3737
|
);
|
|
3741
3738
|
}
|
|
3742
|
-
|
|
3739
|
+
|
|
3740
|
+
// src/dependency-externalizer.ts
|
|
3741
|
+
var import_fs4 = __toESM(require("fs"));
|
|
3742
|
+
var import_util = require("util");
|
|
3743
|
+
var import_path5 = require("path");
|
|
3744
|
+
var import_build_utils5 = require("@vercel/build-utils");
|
|
3745
|
+
var import_python_analysis2 = require("@vercel/python-analysis");
|
|
3746
|
+
var readFile = (0, import_util.promisify)(import_fs4.default.readFile);
|
|
3747
|
+
var LAMBDA_SIZE_THRESHOLD_BYTES = 249 * 1024 * 1024;
|
|
3748
|
+
var LAMBDA_PACKING_TARGET_BYTES = 245 * 1024 * 1024;
|
|
3749
|
+
var LAMBDA_EPHEMERAL_STORAGE_BYTES = 500 * 1024 * 1024;
|
|
3750
|
+
var PythonDependencyExternalizer = class {
|
|
3751
|
+
constructor(options) {
|
|
3752
|
+
// Populated by analyze()
|
|
3753
|
+
this.allVendorFiles = {};
|
|
3754
|
+
this.totalBundleSize = 0;
|
|
3755
|
+
this.analyzed = false;
|
|
3756
|
+
this.venvPath = options.venvPath;
|
|
3757
|
+
this.vendorDir = options.vendorDir;
|
|
3758
|
+
this.workPath = options.workPath;
|
|
3759
|
+
this.uvLockPath = options.uvLockPath;
|
|
3760
|
+
this.uvProjectDir = options.uvProjectDir;
|
|
3761
|
+
this.projectName = options.projectName;
|
|
3762
|
+
this.noBuildCheckFailed = options.noBuildCheckFailed;
|
|
3763
|
+
this.pythonPath = options.pythonPath;
|
|
3764
|
+
}
|
|
3765
|
+
/**
|
|
3766
|
+
* Analyze the bundle: mirror all vendor files, calculate total size,
|
|
3767
|
+
* and determine whether runtime installation is needed.
|
|
3768
|
+
* Must be called before generateBundle().
|
|
3769
|
+
*/
|
|
3770
|
+
async analyze(files) {
|
|
3771
|
+
this.allVendorFiles = await mirrorPackagesIntoVendor({
|
|
3772
|
+
venvPath: this.venvPath,
|
|
3773
|
+
vendorDirName: this.vendorDir
|
|
3774
|
+
});
|
|
3775
|
+
const tempFilesForSizing = { ...files };
|
|
3776
|
+
for (const [p, f] of Object.entries(this.allVendorFiles)) {
|
|
3777
|
+
tempFilesForSizing[p] = f;
|
|
3778
|
+
}
|
|
3779
|
+
this.totalBundleSize = await calculateBundleSize(tempFilesForSizing);
|
|
3780
|
+
this.analyzed = true;
|
|
3781
|
+
const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
|
|
3782
|
+
(0, import_build_utils5.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
|
|
3783
|
+
const overLambdaLimit = shouldEnableRuntimeInstall({
|
|
3784
|
+
totalBundleSize: this.totalBundleSize,
|
|
3785
|
+
uvLockPath: this.uvLockPath
|
|
3786
|
+
});
|
|
3787
|
+
return { overLambdaLimit, allVendorFiles: this.allVendorFiles };
|
|
3788
|
+
}
|
|
3789
|
+
/**
|
|
3790
|
+
* Generate the optimally-packed Lambda bundle.
|
|
3791
|
+
* Mutates `files` in place: adds vendor files (private + knapsack-selected
|
|
3792
|
+
* public), runtime config, and uv binary.
|
|
3793
|
+
* Must be called after analyze().
|
|
3794
|
+
*/
|
|
3795
|
+
async generateBundle(files) {
|
|
3796
|
+
if (!this.analyzed) {
|
|
3797
|
+
throw new Error(
|
|
3798
|
+
"PythonDependencyExternalizer.analyze() must be called before generateBundle()"
|
|
3799
|
+
);
|
|
3800
|
+
}
|
|
3801
|
+
if (!this.uvLockPath || !this.uvProjectDir) {
|
|
3802
|
+
throw new import_build_utils5.NowBuildError({
|
|
3803
|
+
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
3804
|
+
message: "Runtime dependency installation requires a uv.lock file and project directory."
|
|
3805
|
+
});
|
|
3806
|
+
}
|
|
3807
|
+
const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
|
|
3808
|
+
console.log(
|
|
3809
|
+
`Bundle size (${totalBundleSizeMB} MB) exceeds limit. Enabling runtime dependency installation.`
|
|
3810
|
+
);
|
|
3811
|
+
if (this.totalBundleSize > LAMBDA_EPHEMERAL_STORAGE_BYTES) {
|
|
3812
|
+
const ephemeralLimitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(0);
|
|
3813
|
+
throw new import_build_utils5.NowBuildError({
|
|
3814
|
+
code: "LAMBDA_SIZE_EXCEEDED",
|
|
3815
|
+
message: `Total dependency size (${totalBundleSizeMB} MB) exceeds Lambda ephemeral storage limit (${ephemeralLimitMB} MB). Even with runtime dependency installation, all packages must fit within the ${ephemeralLimitMB} MB ephemeral storage available to Lambda functions. Consider removing unused dependencies or splitting your application into smaller functions.`
|
|
3816
|
+
});
|
|
3817
|
+
}
|
|
3818
|
+
if (this.noBuildCheckFailed) {
|
|
3819
|
+
throw new import_build_utils5.NowBuildError({
|
|
3820
|
+
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
3821
|
+
message: `Bundle size exceeds the Lambda limit and requires runtime dependency installation, but some packages in your uv.lock file do not have pre-built binary wheels available.
|
|
3822
|
+
Runtime dependency installation requires all public packages to have binary wheels.
|
|
3823
|
+
|
|
3824
|
+
To fix this, either:
|
|
3825
|
+
1. Regenerate your lock file with: uv lock --upgrade --no-build, or
|
|
3826
|
+
2. Switch the problematic packages to ones that have pre-built wheels available`
|
|
3827
|
+
});
|
|
3828
|
+
}
|
|
3829
|
+
let lockContent;
|
|
3830
|
+
try {
|
|
3831
|
+
lockContent = await readFile(this.uvLockPath, "utf8");
|
|
3832
|
+
} catch (error) {
|
|
3833
|
+
if (error instanceof Error) {
|
|
3834
|
+
console.log(
|
|
3835
|
+
`Failed to read uv.lock file at "${this.uvLockPath}": ${error.message}`
|
|
3836
|
+
);
|
|
3837
|
+
} else {
|
|
3838
|
+
console.log(
|
|
3839
|
+
`Failed to read uv.lock file at "${this.uvLockPath}": ${String(error)}`
|
|
3840
|
+
);
|
|
3841
|
+
}
|
|
3842
|
+
throw new import_build_utils5.NowBuildError({
|
|
3843
|
+
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
3844
|
+
message: `Failed to read uv.lock file at "${this.uvLockPath}"`
|
|
3845
|
+
});
|
|
3846
|
+
}
|
|
3847
|
+
let lockFile;
|
|
3848
|
+
try {
|
|
3849
|
+
lockFile = (0, import_python_analysis2.parseUvLock)(lockContent, this.uvLockPath);
|
|
3850
|
+
} catch (error) {
|
|
3851
|
+
if (error instanceof import_python_analysis2.PythonAnalysisError) {
|
|
3852
|
+
if (error.fileContent) {
|
|
3853
|
+
console.log(
|
|
3854
|
+
`Failed to parse "${error.path}". File content:
|
|
3855
|
+
${error.fileContent}`
|
|
3856
|
+
);
|
|
3857
|
+
}
|
|
3858
|
+
throw new import_build_utils5.NowBuildError({
|
|
3859
|
+
code: error.code,
|
|
3860
|
+
message: error.message
|
|
3861
|
+
});
|
|
3862
|
+
}
|
|
3863
|
+
throw error;
|
|
3864
|
+
}
|
|
3865
|
+
const excludePackages = [];
|
|
3866
|
+
if (this.projectName) {
|
|
3867
|
+
excludePackages.push(this.projectName);
|
|
3868
|
+
(0, import_build_utils5.debug)(
|
|
3869
|
+
`Excluding project package "${this.projectName}" from runtime installation`
|
|
3870
|
+
);
|
|
3871
|
+
}
|
|
3872
|
+
const classification = (0, import_python_analysis2.classifyPackages)({
|
|
3873
|
+
lockFile,
|
|
3874
|
+
excludePackages
|
|
3875
|
+
});
|
|
3876
|
+
(0, import_build_utils5.debug)(
|
|
3877
|
+
`Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
|
|
3878
|
+
);
|
|
3879
|
+
if (classification.publicPackages.length === 0) {
|
|
3880
|
+
throw new import_build_utils5.NowBuildError({
|
|
3881
|
+
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
3882
|
+
message: "Bundle size exceeds limit but no public packages found for runtime installation."
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3885
|
+
const packageSizes = await calculatePerPackageSizes(this.venvPath);
|
|
3886
|
+
const alwaysBundled = [
|
|
3887
|
+
...classification.privatePackages,
|
|
3888
|
+
"vercel-runtime",
|
|
3889
|
+
"vercel_runtime"
|
|
3890
|
+
];
|
|
3891
|
+
const alwaysBundledFiles = await mirrorPackagesIntoVendor({
|
|
3892
|
+
venvPath: this.venvPath,
|
|
3893
|
+
vendorDirName: this.vendorDir,
|
|
3894
|
+
includePackages: alwaysBundled
|
|
3895
|
+
});
|
|
3896
|
+
const baseFiles = { ...files };
|
|
3897
|
+
for (const [p, f] of Object.entries(alwaysBundledFiles)) {
|
|
3898
|
+
baseFiles[p] = f;
|
|
3899
|
+
}
|
|
3900
|
+
const fixedOverhead = await calculateBundleSize(baseFiles);
|
|
3901
|
+
let runtimeToolingOverhead = 0;
|
|
3902
|
+
if (process.env.VERCEL_BUILD_IMAGE) {
|
|
3903
|
+
try {
|
|
3904
|
+
const uvBinaryPath = await getUvBinaryForBundling(this.pythonPath);
|
|
3905
|
+
const uvStats = await import_fs4.default.promises.stat(uvBinaryPath);
|
|
3906
|
+
runtimeToolingOverhead = uvStats.size;
|
|
3907
|
+
} catch {
|
|
3908
|
+
runtimeToolingOverhead = 50 * 1024 * 1024;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
const remainingCapacity = LAMBDA_PACKING_TARGET_BYTES - fixedOverhead - runtimeToolingOverhead;
|
|
3912
|
+
(0, import_build_utils5.debug)(
|
|
3913
|
+
`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`
|
|
3914
|
+
);
|
|
3915
|
+
const publicPackageSizes = new Map(
|
|
3916
|
+
[...packageSizes].filter(
|
|
3917
|
+
([name]) => classification.publicPackages.includes(name)
|
|
3918
|
+
)
|
|
3919
|
+
);
|
|
3920
|
+
const bundledPublic = lambdaKnapsack(publicPackageSizes, remainingCapacity);
|
|
3921
|
+
const allBundledPackages = [...alwaysBundled, ...bundledPublic];
|
|
3922
|
+
const selectedVendorFiles = await mirrorPackagesIntoVendor({
|
|
3923
|
+
venvPath: this.venvPath,
|
|
3924
|
+
vendorDirName: this.vendorDir,
|
|
3925
|
+
includePackages: allBundledPackages
|
|
3926
|
+
});
|
|
3927
|
+
for (const [p, f] of Object.entries(selectedVendorFiles)) {
|
|
3928
|
+
files[p] = f;
|
|
3929
|
+
}
|
|
3930
|
+
const bundledPackagesForConfig = [
|
|
3931
|
+
...classification.privatePackages,
|
|
3932
|
+
...bundledPublic
|
|
3933
|
+
];
|
|
3934
|
+
const projectDirRel = (0, import_path5.relative)(this.workPath, this.uvProjectDir);
|
|
3935
|
+
const uvLockRel = (0, import_path5.relative)(this.workPath, this.uvLockPath);
|
|
3936
|
+
const isOutsideWorkPath = projectDirRel.startsWith("..") || uvLockRel.startsWith("..");
|
|
3937
|
+
if (isOutsideWorkPath) {
|
|
3938
|
+
const srcPyproject = (0, import_path5.join)(this.uvProjectDir, "pyproject.toml");
|
|
3939
|
+
files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils5.FileFsRef({
|
|
3940
|
+
fsPath: srcPyproject
|
|
3941
|
+
});
|
|
3942
|
+
files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils5.FileFsRef({
|
|
3943
|
+
fsPath: this.uvLockPath
|
|
3944
|
+
});
|
|
3945
|
+
}
|
|
3946
|
+
const runtimeConfigData = JSON.stringify({
|
|
3947
|
+
projectDir: isOutsideWorkPath ? UV_BUNDLE_DIR : projectDirRel,
|
|
3948
|
+
bundledPackages: bundledPackagesForConfig
|
|
3949
|
+
});
|
|
3950
|
+
files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils5.FileBlob({
|
|
3951
|
+
data: runtimeConfigData
|
|
3952
|
+
});
|
|
3953
|
+
if (process.env.VERCEL_BUILD_IMAGE) {
|
|
3954
|
+
try {
|
|
3955
|
+
const uvBinaryPath = await getUvBinaryForBundling(this.pythonPath);
|
|
3956
|
+
const uvBundleDir = (0, import_path5.join)(this.workPath, UV_BUNDLE_DIR);
|
|
3957
|
+
const uvLocalPath = (0, import_path5.join)(uvBundleDir, "uv");
|
|
3958
|
+
await import_fs4.default.promises.mkdir(uvBundleDir, { recursive: true });
|
|
3959
|
+
await import_fs4.default.promises.copyFile(uvBinaryPath, uvLocalPath);
|
|
3960
|
+
await import_fs4.default.promises.chmod(uvLocalPath, 493);
|
|
3961
|
+
const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
|
|
3962
|
+
files[uvBundlePath] = new import_build_utils5.FileFsRef({
|
|
3963
|
+
fsPath: uvLocalPath,
|
|
3964
|
+
mode: 33261
|
|
3965
|
+
// Regular file + executable
|
|
3966
|
+
});
|
|
3967
|
+
(0, import_build_utils5.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
|
|
3968
|
+
} catch (err) {
|
|
3969
|
+
throw new import_build_utils5.NowBuildError({
|
|
3970
|
+
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
3971
|
+
message: `Failed to bundle uv binary for runtime installation: ${err instanceof Error ? err.message : String(err)}`
|
|
3972
|
+
});
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
const finalBundleSize = await calculateBundleSize(files);
|
|
3976
|
+
if (finalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES) {
|
|
3977
|
+
const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
|
|
3978
|
+
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
3979
|
+
throw new import_build_utils5.NowBuildError({
|
|
3980
|
+
code: "LAMBDA_SIZE_EXCEEDED",
|
|
3981
|
+
message: `Bundle size (${finalSizeMB} MB) exceeds Lambda limit (${limitMB} MB) even after deferring public packages to runtime installation. This usually means your private packages or source code are too large. Consider reducing the size of private dependencies or splitting your application.`
|
|
3982
|
+
});
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
};
|
|
3986
|
+
function shouldEnableRuntimeInstall({
|
|
3987
|
+
totalBundleSize,
|
|
3988
|
+
uvLockPath
|
|
3989
|
+
}) {
|
|
3990
|
+
const pythonOnHiveEnabled = process.env.VERCEL_PYTHON_ON_HIVE === "1" || process.env.VERCEL_PYTHON_ON_HIVE === "true";
|
|
3991
|
+
if (pythonOnHiveEnabled) {
|
|
3992
|
+
return false;
|
|
3993
|
+
} else if (totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && uvLockPath !== null) {
|
|
3994
|
+
return true;
|
|
3995
|
+
}
|
|
3996
|
+
return false;
|
|
3997
|
+
}
|
|
3998
|
+
async function mirrorPackagesIntoVendor({
|
|
3743
3999
|
venvPath,
|
|
3744
|
-
vendorDirName
|
|
4000
|
+
vendorDirName,
|
|
4001
|
+
includePackages
|
|
3745
4002
|
}) {
|
|
3746
4003
|
const vendorFiles = {};
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
4004
|
+
if (includePackages && includePackages.length === 0) {
|
|
4005
|
+
return vendorFiles;
|
|
4006
|
+
}
|
|
4007
|
+
const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis2.normalizePackageName)) : null;
|
|
4008
|
+
const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
|
|
4009
|
+
for (const dir of sitePackageDirs) {
|
|
4010
|
+
if (!import_fs4.default.existsSync(dir))
|
|
4011
|
+
continue;
|
|
4012
|
+
const resolvedDir = (0, import_path5.resolve)(dir);
|
|
4013
|
+
const dirPrefix = resolvedDir + import_path5.sep;
|
|
4014
|
+
const distributions = await (0, import_python_analysis2.scanDistributions)(dir);
|
|
4015
|
+
for (const [name, dist] of distributions) {
|
|
4016
|
+
if (includeSet && !includeSet.has(name))
|
|
3751
4017
|
continue;
|
|
3752
|
-
const
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
continue;
|
|
3760
|
-
}
|
|
3761
|
-
if (filePath.endsWith(".pyc") || filePath.split(import_path4.sep).includes("__pycache__")) {
|
|
3762
|
-
continue;
|
|
3763
|
-
}
|
|
3764
|
-
const srcFsPath = (0, import_path4.join)(dir, filePath);
|
|
3765
|
-
const bundlePath = (0, import_path4.join)(vendorDirName, filePath).replace(/\\/g, "/");
|
|
3766
|
-
vendorFiles[bundlePath] = new import_build_utils4.FileFsRef({ fsPath: srcFsPath });
|
|
4018
|
+
for (const { path: rawPath } of dist.files) {
|
|
4019
|
+
const filePath = rawPath.replaceAll("/", import_path5.sep);
|
|
4020
|
+
if (!(0, import_path5.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
|
|
4021
|
+
continue;
|
|
4022
|
+
}
|
|
4023
|
+
if (filePath.endsWith(".pyc") || filePath.split(import_path5.sep).includes("__pycache__")) {
|
|
4024
|
+
continue;
|
|
3767
4025
|
}
|
|
4026
|
+
const srcFsPath = (0, import_path5.join)(dir, filePath);
|
|
4027
|
+
if (!import_fs4.default.existsSync(srcFsPath)) {
|
|
4028
|
+
continue;
|
|
4029
|
+
}
|
|
4030
|
+
const bundlePath = (0, import_path5.join)(vendorDirName, filePath).replace(/\\/g, "/");
|
|
4031
|
+
vendorFiles[bundlePath] = new import_build_utils5.FileFsRef({ fsPath: srcFsPath });
|
|
3768
4032
|
}
|
|
3769
4033
|
}
|
|
3770
|
-
} catch (err) {
|
|
3771
|
-
console.log("Failed to collect site-packages from virtual environment");
|
|
3772
|
-
throw err;
|
|
3773
4034
|
}
|
|
4035
|
+
(0, import_build_utils5.debug)(
|
|
4036
|
+
`Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
4037
|
+
);
|
|
3774
4038
|
return vendorFiles;
|
|
3775
4039
|
}
|
|
3776
4040
|
async function calculateBundleSize(files) {
|
|
@@ -3779,7 +4043,7 @@ async function calculateBundleSize(files) {
|
|
|
3779
4043
|
const file = files[filePath];
|
|
3780
4044
|
if ("fsPath" in file && file.fsPath) {
|
|
3781
4045
|
try {
|
|
3782
|
-
const stats = await
|
|
4046
|
+
const stats = await import_fs4.default.promises.stat(file.fsPath);
|
|
3783
4047
|
totalSize += stats.size;
|
|
3784
4048
|
} catch (err) {
|
|
3785
4049
|
console.warn(
|
|
@@ -3793,66 +4057,65 @@ async function calculateBundleSize(files) {
|
|
|
3793
4057
|
}
|
|
3794
4058
|
return totalSize;
|
|
3795
4059
|
}
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
privatePackages
|
|
3800
|
-
}) {
|
|
3801
|
-
const vendorFiles = {};
|
|
3802
|
-
if (privatePackages.length === 0) {
|
|
3803
|
-
(0, import_build_utils4.debug)("No private packages to bundle");
|
|
3804
|
-
return vendorFiles;
|
|
4060
|
+
function lambdaKnapsack(packages, capacity) {
|
|
4061
|
+
if (capacity <= 0) {
|
|
4062
|
+
return [];
|
|
3805
4063
|
}
|
|
3806
|
-
const
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
4064
|
+
const sorted = [...packages.entries()].sort(([, a], [, b]) => b - a);
|
|
4065
|
+
const bundled = [];
|
|
4066
|
+
let remaining = capacity;
|
|
4067
|
+
for (const [name, size] of sorted) {
|
|
4068
|
+
if (size <= remaining) {
|
|
4069
|
+
bundled.push(name);
|
|
4070
|
+
remaining -= size;
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4073
|
+
return bundled;
|
|
4074
|
+
}
|
|
4075
|
+
async function calculatePerPackageSizes(venvPath) {
|
|
4076
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
4077
|
+
const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
|
|
4078
|
+
for (const dir of sitePackageDirs) {
|
|
4079
|
+
if (!import_fs4.default.existsSync(dir))
|
|
4080
|
+
continue;
|
|
4081
|
+
const resolvedDir = (0, import_path5.resolve)(dir);
|
|
4082
|
+
const dirPrefix = resolvedDir + import_path5.sep;
|
|
4083
|
+
const distributions = await (0, import_python_analysis2.scanDistributions)(dir);
|
|
4084
|
+
for (const [name, dist] of distributions) {
|
|
4085
|
+
let totalSize = 0;
|
|
4086
|
+
for (const { path: rawPath } of dist.files) {
|
|
4087
|
+
const filePath = rawPath.replaceAll("/", import_path5.sep);
|
|
4088
|
+
if (!(0, import_path5.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
|
|
4089
|
+
continue;
|
|
4090
|
+
}
|
|
4091
|
+
if (filePath.endsWith(".pyc") || filePath.split(import_path5.sep).includes("__pycache__")) {
|
|
3817
4092
|
continue;
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
if (filePath.endsWith(".pyc") || filePath.split(import_path4.sep).includes("__pycache__")) {
|
|
3824
|
-
continue;
|
|
3825
|
-
}
|
|
3826
|
-
const srcFsPath = (0, import_path4.join)(dir, filePath);
|
|
3827
|
-
const bundlePath = (0, import_path4.join)(vendorDirName, filePath).replace(/\\/g, "/");
|
|
3828
|
-
vendorFiles[bundlePath] = new import_build_utils4.FileFsRef({ fsPath: srcFsPath });
|
|
4093
|
+
}
|
|
4094
|
+
try {
|
|
4095
|
+
const stats = await import_fs4.default.promises.stat((0, import_path5.join)(dir, filePath));
|
|
4096
|
+
totalSize += stats.size;
|
|
4097
|
+
} catch {
|
|
3829
4098
|
}
|
|
3830
4099
|
}
|
|
4100
|
+
sizes.set(name, totalSize);
|
|
3831
4101
|
}
|
|
3832
|
-
(0, import_build_utils4.debug)(
|
|
3833
|
-
`Bundled ${Object.keys(vendorFiles).length} files from private packages`
|
|
3834
|
-
);
|
|
3835
|
-
} catch (err) {
|
|
3836
|
-
console.log("Failed to collect private packages from virtual environment");
|
|
3837
|
-
throw err;
|
|
3838
4102
|
}
|
|
3839
|
-
return
|
|
4103
|
+
return sizes;
|
|
3840
4104
|
}
|
|
3841
4105
|
|
|
3842
4106
|
// src/index.ts
|
|
3843
|
-
var
|
|
3844
|
-
var import_build_utils9 = require("@vercel/build-utils");
|
|
4107
|
+
var import_build_utils10 = require("@vercel/build-utils");
|
|
3845
4108
|
|
|
3846
4109
|
// src/start-dev-server.ts
|
|
3847
4110
|
var import_child_process2 = require("child_process");
|
|
3848
|
-
var
|
|
3849
|
-
var
|
|
3850
|
-
var
|
|
4111
|
+
var import_fs5 = require("fs");
|
|
4112
|
+
var import_path7 = require("path");
|
|
4113
|
+
var import_build_utils8 = require("@vercel/build-utils");
|
|
3851
4114
|
|
|
3852
4115
|
// src/entrypoint.ts
|
|
3853
|
-
var
|
|
3854
|
-
var import_build_utils5 = require("@vercel/build-utils");
|
|
4116
|
+
var import_path6 = require("path");
|
|
3855
4117
|
var import_build_utils6 = require("@vercel/build-utils");
|
|
4118
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
3856
4119
|
var PYTHON_ENTRYPOINT_FILENAMES = [
|
|
3857
4120
|
"app",
|
|
3858
4121
|
"index",
|
|
@@ -3864,11 +4127,11 @@ var PYTHON_ENTRYPOINT_FILENAMES = [
|
|
|
3864
4127
|
var PYTHON_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
|
|
3865
4128
|
var PYTHON_CANDIDATE_ENTRYPOINTS = PYTHON_ENTRYPOINT_FILENAMES.flatMap(
|
|
3866
4129
|
(filename) => PYTHON_ENTRYPOINT_DIRS.map(
|
|
3867
|
-
(dir) =>
|
|
4130
|
+
(dir) => import_path6.posix.join(dir, `${filename}.py`)
|
|
3868
4131
|
)
|
|
3869
4132
|
);
|
|
3870
4133
|
async function getPyprojectEntrypoint(workPath) {
|
|
3871
|
-
const pyprojectData = await (0,
|
|
4134
|
+
const pyprojectData = await (0, import_build_utils7.readConfigFile)((0, import_path6.join)(workPath, "pyproject.toml"));
|
|
3872
4135
|
if (!pyprojectData)
|
|
3873
4136
|
return null;
|
|
3874
4137
|
const scripts = pyprojectData.project?.scripts;
|
|
@@ -3881,7 +4144,7 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
3881
4144
|
const modulePath = match[1];
|
|
3882
4145
|
const relPath = modulePath.replace(/\./g, "/");
|
|
3883
4146
|
try {
|
|
3884
|
-
const fsFiles = await (0,
|
|
4147
|
+
const fsFiles = await (0, import_build_utils6.glob)("**", workPath);
|
|
3885
4148
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
3886
4149
|
for (const candidate of candidates) {
|
|
3887
4150
|
if (fsFiles[candidate])
|
|
@@ -3889,18 +4152,18 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
3889
4152
|
}
|
|
3890
4153
|
return null;
|
|
3891
4154
|
} catch {
|
|
3892
|
-
(0,
|
|
4155
|
+
(0, import_build_utils6.debug)("Failed to discover Python entrypoint from pyproject.toml");
|
|
3893
4156
|
return null;
|
|
3894
4157
|
}
|
|
3895
4158
|
}
|
|
3896
4159
|
async function detectGenericPythonEntrypoint(workPath, configuredEntrypoint) {
|
|
3897
4160
|
const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
|
|
3898
4161
|
try {
|
|
3899
|
-
const fsFiles = await (0,
|
|
4162
|
+
const fsFiles = await (0, import_build_utils6.glob)("**", workPath);
|
|
3900
4163
|
if (fsFiles[entry]) {
|
|
3901
|
-
const isValid = await (0,
|
|
4164
|
+
const isValid = await (0, import_build_utils6.isPythonEntrypoint)(fsFiles[entry]);
|
|
3902
4165
|
if (isValid) {
|
|
3903
|
-
(0,
|
|
4166
|
+
(0, import_build_utils6.debug)(`Using configured Python entrypoint: ${entry}`);
|
|
3904
4167
|
return entry;
|
|
3905
4168
|
}
|
|
3906
4169
|
}
|
|
@@ -3908,15 +4171,15 @@ async function detectGenericPythonEntrypoint(workPath, configuredEntrypoint) {
|
|
|
3908
4171
|
(c) => !!fsFiles[c]
|
|
3909
4172
|
);
|
|
3910
4173
|
for (const candidate of candidates) {
|
|
3911
|
-
const isValid = await (0,
|
|
4174
|
+
const isValid = await (0, import_build_utils6.isPythonEntrypoint)(fsFiles[candidate]);
|
|
3912
4175
|
if (isValid) {
|
|
3913
|
-
(0,
|
|
4176
|
+
(0, import_build_utils6.debug)(`Detected Python entrypoint: ${candidate}`);
|
|
3914
4177
|
return candidate;
|
|
3915
4178
|
}
|
|
3916
4179
|
}
|
|
3917
4180
|
return null;
|
|
3918
4181
|
} catch {
|
|
3919
|
-
(0,
|
|
4182
|
+
(0, import_build_utils6.debug)("Failed to discover Python entrypoint");
|
|
3920
4183
|
return null;
|
|
3921
4184
|
}
|
|
3922
4185
|
}
|
|
@@ -3931,7 +4194,7 @@ async function detectPythonEntrypoint(_framework, workPath, configuredEntrypoint
|
|
|
3931
4194
|
}
|
|
3932
4195
|
|
|
3933
4196
|
// src/start-dev-server.ts
|
|
3934
|
-
var
|
|
4197
|
+
var import_python_analysis3 = require("@vercel/python-analysis");
|
|
3935
4198
|
function silenceNodeWarnings() {
|
|
3936
4199
|
const original = process.emitWarning.bind(
|
|
3937
4200
|
process
|
|
@@ -3990,17 +4253,17 @@ async function syncDependencies({
|
|
|
3990
4253
|
let { manifestType, manifestPath } = installInfo;
|
|
3991
4254
|
const manifest = installInfo.pythonPackage?.manifest;
|
|
3992
4255
|
if (!manifestType || !manifestPath) {
|
|
3993
|
-
(0,
|
|
4256
|
+
(0, import_build_utils8.debug)("No Python project manifest found, skipping dependency sync");
|
|
3994
4257
|
return;
|
|
3995
4258
|
}
|
|
3996
4259
|
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
3997
|
-
const syncDir = (0,
|
|
3998
|
-
(0,
|
|
3999
|
-
const tempPyproject = (0,
|
|
4000
|
-
const content = (0,
|
|
4001
|
-
(0,
|
|
4260
|
+
const syncDir = (0, import_path7.join)(workPath, ".vercel", "python", "sync");
|
|
4261
|
+
(0, import_fs5.mkdirSync)(syncDir, { recursive: true });
|
|
4262
|
+
const tempPyproject = (0, import_path7.join)(syncDir, "pyproject.toml");
|
|
4263
|
+
const content = (0, import_python_analysis3.stringifyManifest)(manifest.data);
|
|
4264
|
+
(0, import_fs5.writeFileSync)(tempPyproject, content, "utf8");
|
|
4002
4265
|
manifestPath = tempPyproject;
|
|
4003
|
-
(0,
|
|
4266
|
+
(0, import_build_utils8.debug)(
|
|
4004
4267
|
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
4005
4268
|
);
|
|
4006
4269
|
}
|
|
@@ -4033,7 +4296,7 @@ async function syncDependencies({
|
|
|
4033
4296
|
for (const [channel, chunk] of captured) {
|
|
4034
4297
|
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
4035
4298
|
}
|
|
4036
|
-
throw new
|
|
4299
|
+
throw new import_build_utils8.NowBuildError({
|
|
4037
4300
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
4038
4301
|
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
4039
4302
|
});
|
|
@@ -4048,14 +4311,14 @@ async function runSync({
|
|
|
4048
4311
|
onStdout,
|
|
4049
4312
|
onStderr
|
|
4050
4313
|
}) {
|
|
4051
|
-
const projectDir = (0,
|
|
4314
|
+
const projectDir = (0, import_path7.dirname)(manifestPath);
|
|
4052
4315
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
4053
4316
|
let spawnCmd;
|
|
4054
4317
|
let spawnArgs;
|
|
4055
4318
|
switch (manifestType) {
|
|
4056
4319
|
case "uv.lock": {
|
|
4057
4320
|
if (!uvPath) {
|
|
4058
|
-
throw new
|
|
4321
|
+
throw new import_build_utils8.NowBuildError({
|
|
4059
4322
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
4060
4323
|
message: "uv is required to install dependencies from uv.lock.",
|
|
4061
4324
|
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
@@ -4077,11 +4340,11 @@ async function runSync({
|
|
|
4077
4340
|
break;
|
|
4078
4341
|
}
|
|
4079
4342
|
default:
|
|
4080
|
-
(0,
|
|
4343
|
+
(0, import_build_utils8.debug)(`Unknown manifest type: ${manifestType}`);
|
|
4081
4344
|
return;
|
|
4082
4345
|
}
|
|
4083
4346
|
await new Promise((resolve2, reject) => {
|
|
4084
|
-
(0,
|
|
4347
|
+
(0, import_build_utils8.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
4085
4348
|
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
4086
4349
|
cwd: projectDir,
|
|
4087
4350
|
env: getProtectedUvEnv(env),
|
|
@@ -4128,12 +4391,12 @@ function installGlobalCleanupHandlers() {
|
|
|
4128
4391
|
try {
|
|
4129
4392
|
process.kill(info.pid, "SIGTERM");
|
|
4130
4393
|
} catch (err) {
|
|
4131
|
-
(0,
|
|
4394
|
+
(0, import_build_utils8.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
|
|
4132
4395
|
}
|
|
4133
4396
|
try {
|
|
4134
4397
|
process.kill(info.pid, "SIGKILL");
|
|
4135
4398
|
} catch (err) {
|
|
4136
|
-
(0,
|
|
4399
|
+
(0, import_build_utils8.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
|
|
4137
4400
|
}
|
|
4138
4401
|
PERSISTENT_SERVERS.delete(key);
|
|
4139
4402
|
}
|
|
@@ -4141,7 +4404,7 @@ function installGlobalCleanupHandlers() {
|
|
|
4141
4404
|
try {
|
|
4142
4405
|
restoreWarnings();
|
|
4143
4406
|
} catch (err) {
|
|
4144
|
-
(0,
|
|
4407
|
+
(0, import_build_utils8.debug)(`Error restoring warnings: ${err}`);
|
|
4145
4408
|
}
|
|
4146
4409
|
restoreWarnings = null;
|
|
4147
4410
|
}
|
|
@@ -4158,49 +4421,49 @@ function installGlobalCleanupHandlers() {
|
|
|
4158
4421
|
}
|
|
4159
4422
|
function createDevAsgiShim(workPath, modulePath) {
|
|
4160
4423
|
try {
|
|
4161
|
-
const vercelPythonDir = (0,
|
|
4162
|
-
(0,
|
|
4163
|
-
const shimPath = (0,
|
|
4164
|
-
const templatePath = (0,
|
|
4165
|
-
const template = (0,
|
|
4424
|
+
const vercelPythonDir = (0, import_path7.join)(workPath, ".vercel", "python");
|
|
4425
|
+
(0, import_fs5.mkdirSync)(vercelPythonDir, { recursive: true });
|
|
4426
|
+
const shimPath = (0, import_path7.join)(vercelPythonDir, `${ASGI_SHIM_MODULE}.py`);
|
|
4427
|
+
const templatePath = (0, import_path7.join)(__dirname, "..", `${ASGI_SHIM_MODULE}.py`);
|
|
4428
|
+
const template = (0, import_fs5.readFileSync)(templatePath, "utf8");
|
|
4166
4429
|
const shimSource = template.replace(/__VC_DEV_MODULE_PATH__/g, modulePath);
|
|
4167
|
-
(0,
|
|
4168
|
-
(0,
|
|
4430
|
+
(0, import_fs5.writeFileSync)(shimPath, shimSource, "utf8");
|
|
4431
|
+
(0, import_build_utils8.debug)(`Prepared Python dev static shim at ${shimPath}`);
|
|
4169
4432
|
return ASGI_SHIM_MODULE;
|
|
4170
4433
|
} catch (err) {
|
|
4171
|
-
(0,
|
|
4434
|
+
(0, import_build_utils8.debug)(`Failed to prepare dev static shim: ${err?.message || err}`);
|
|
4172
4435
|
return null;
|
|
4173
4436
|
}
|
|
4174
4437
|
}
|
|
4175
4438
|
function createDevWsgiShim(workPath, modulePath) {
|
|
4176
4439
|
try {
|
|
4177
|
-
const vercelPythonDir = (0,
|
|
4178
|
-
(0,
|
|
4179
|
-
const shimPath = (0,
|
|
4180
|
-
const templatePath = (0,
|
|
4181
|
-
const template = (0,
|
|
4440
|
+
const vercelPythonDir = (0, import_path7.join)(workPath, ".vercel", "python");
|
|
4441
|
+
(0, import_fs5.mkdirSync)(vercelPythonDir, { recursive: true });
|
|
4442
|
+
const shimPath = (0, import_path7.join)(vercelPythonDir, `${WSGI_SHIM_MODULE}.py`);
|
|
4443
|
+
const templatePath = (0, import_path7.join)(__dirname, "..", `${WSGI_SHIM_MODULE}.py`);
|
|
4444
|
+
const template = (0, import_fs5.readFileSync)(templatePath, "utf8");
|
|
4182
4445
|
const shimSource = template.replace(/__VC_DEV_MODULE_PATH__/g, modulePath);
|
|
4183
|
-
(0,
|
|
4184
|
-
(0,
|
|
4446
|
+
(0, import_fs5.writeFileSync)(shimPath, shimSource, "utf8");
|
|
4447
|
+
(0, import_build_utils8.debug)(`Prepared Python dev WSGI shim at ${shimPath}`);
|
|
4185
4448
|
return WSGI_SHIM_MODULE;
|
|
4186
4449
|
} catch (err) {
|
|
4187
|
-
(0,
|
|
4450
|
+
(0, import_build_utils8.debug)(`Failed to prepare dev WSGI shim: ${err?.message || err}`);
|
|
4188
4451
|
return null;
|
|
4189
4452
|
}
|
|
4190
4453
|
}
|
|
4191
4454
|
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
4192
4455
|
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
4193
4456
|
if (venvRoot) {
|
|
4194
|
-
(0,
|
|
4457
|
+
(0, import_build_utils8.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
4195
4458
|
return { command: pythonCmd, args: [] };
|
|
4196
4459
|
}
|
|
4197
|
-
const venvPath = (0,
|
|
4460
|
+
const venvPath = (0, import_path7.join)(workPath, ".venv");
|
|
4198
4461
|
await ensureVenv({ pythonPath: systemPython, venvPath, uvPath, quiet: true });
|
|
4199
|
-
(0,
|
|
4462
|
+
(0, import_build_utils8.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
4200
4463
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
4201
4464
|
const binDir = getVenvBinDir(venvPath);
|
|
4202
4465
|
env.VIRTUAL_ENV = venvPath;
|
|
4203
|
-
env.PATH = `${binDir}${
|
|
4466
|
+
env.PATH = `${binDir}${import_path7.delimiter}${env.PATH || ""}`;
|
|
4204
4467
|
return { command: pythonBin, args: [] };
|
|
4205
4468
|
}
|
|
4206
4469
|
var startDevServer = async (opts) => {
|
|
@@ -4226,7 +4489,7 @@ var startDevServer = async (opts) => {
|
|
|
4226
4489
|
);
|
|
4227
4490
|
if (!entry) {
|
|
4228
4491
|
const searched = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
4229
|
-
throw new
|
|
4492
|
+
throw new import_build_utils8.NowBuildError({
|
|
4230
4493
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
4231
4494
|
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searched}.`,
|
|
4232
4495
|
link: `https://vercel.com/docs/frameworks/backend/${framework?.toLowerCase()}#exporting-the-${framework?.toLowerCase()}-application`,
|
|
@@ -4279,7 +4542,7 @@ var startDevServer = async (opts) => {
|
|
|
4279
4542
|
const yellow = "\x1B[33m";
|
|
4280
4543
|
const white = "\x1B[1m";
|
|
4281
4544
|
const reset = "\x1B[0m";
|
|
4282
|
-
throw new
|
|
4545
|
+
throw new import_build_utils8.NowBuildError({
|
|
4283
4546
|
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
4284
4547
|
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
4285
4548
|
Run ${white}deactivate${reset} and try again.`
|
|
@@ -4296,11 +4559,11 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
4296
4559
|
);
|
|
4297
4560
|
spawnCommand = runner.command;
|
|
4298
4561
|
spawnArgsPrefix = runner.args;
|
|
4299
|
-
(0,
|
|
4562
|
+
(0, import_build_utils8.debug)(
|
|
4300
4563
|
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
4301
4564
|
);
|
|
4302
4565
|
} else if (venv) {
|
|
4303
|
-
(0,
|
|
4566
|
+
(0, import_build_utils8.debug)(`Running in virtualenv at ${venv}`);
|
|
4304
4567
|
} else {
|
|
4305
4568
|
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
4306
4569
|
workPath,
|
|
@@ -4309,9 +4572,9 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
4309
4572
|
);
|
|
4310
4573
|
spawnCommand = venvPythonCmd;
|
|
4311
4574
|
if (venvRoot) {
|
|
4312
|
-
(0,
|
|
4575
|
+
(0, import_build_utils8.debug)(`Using virtualenv at ${venvRoot}`);
|
|
4313
4576
|
} else {
|
|
4314
|
-
(0,
|
|
4577
|
+
(0, import_build_utils8.debug)("No virtualenv found");
|
|
4315
4578
|
try {
|
|
4316
4579
|
const yellow = "\x1B[33m";
|
|
4317
4580
|
const reset = "\x1B[0m";
|
|
@@ -4349,14 +4612,14 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4349
4612
|
if (framework !== "flask") {
|
|
4350
4613
|
const devShimModule = createDevAsgiShim(workPath, modulePath);
|
|
4351
4614
|
if (devShimModule) {
|
|
4352
|
-
const vercelPythonDir = (0,
|
|
4615
|
+
const vercelPythonDir = (0, import_path7.join)(workPath, ".vercel", "python");
|
|
4353
4616
|
const existingPythonPath = env.PYTHONPATH || "";
|
|
4354
4617
|
env.PYTHONPATH = existingPythonPath ? `${vercelPythonDir}:${existingPythonPath}` : vercelPythonDir;
|
|
4355
4618
|
}
|
|
4356
4619
|
const moduleToRun = devShimModule || modulePath;
|
|
4357
4620
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
4358
4621
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
4359
|
-
(0,
|
|
4622
|
+
(0, import_build_utils8.debug)(
|
|
4360
4623
|
`Starting ASGI dev server (${framework}): ${spawnCommand} ${argv.join(" ")}`
|
|
4361
4624
|
);
|
|
4362
4625
|
const child = (0, import_child_process2.spawn)(spawnCommand, argv, {
|
|
@@ -4416,14 +4679,14 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4416
4679
|
} else {
|
|
4417
4680
|
const devShimModule = createDevWsgiShim(workPath, modulePath);
|
|
4418
4681
|
if (devShimModule) {
|
|
4419
|
-
const vercelPythonDir = (0,
|
|
4682
|
+
const vercelPythonDir = (0, import_path7.join)(workPath, ".vercel", "python");
|
|
4420
4683
|
const existingPythonPath = env.PYTHONPATH || "";
|
|
4421
4684
|
env.PYTHONPATH = existingPythonPath ? `${vercelPythonDir}:${existingPythonPath}` : vercelPythonDir;
|
|
4422
4685
|
}
|
|
4423
4686
|
const moduleToRun = devShimModule || modulePath;
|
|
4424
4687
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
4425
4688
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
4426
|
-
(0,
|
|
4689
|
+
(0, import_build_utils8.debug)(`Starting Flask dev server: ${spawnCommand} ${argv.join(" ")}`);
|
|
4427
4690
|
const child = (0, import_child_process2.spawn)(spawnCommand, argv, {
|
|
4428
4691
|
cwd: workPath,
|
|
4429
4692
|
env,
|
|
@@ -4496,20 +4759,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4496
4759
|
};
|
|
4497
4760
|
|
|
4498
4761
|
// src/index.ts
|
|
4499
|
-
var
|
|
4500
|
-
var writeFile = (0,
|
|
4501
|
-
function shouldEnableRuntimeInstall({
|
|
4502
|
-
totalBundleSize,
|
|
4503
|
-
uvLockPath
|
|
4504
|
-
}) {
|
|
4505
|
-
const pythonOnHiveEnabled = process.env.VERCEL_PYTHON_ON_HIVE === "1" || process.env.VERCEL_PYTHON_ON_HIVE === "true";
|
|
4506
|
-
if (pythonOnHiveEnabled) {
|
|
4507
|
-
return false;
|
|
4508
|
-
} else if (totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && uvLockPath !== null) {
|
|
4509
|
-
return true;
|
|
4510
|
-
}
|
|
4511
|
-
return false;
|
|
4512
|
-
}
|
|
4762
|
+
var readFile2 = (0, import_util2.promisify)(import_fs6.default.readFile);
|
|
4763
|
+
var writeFile = (0, import_util2.promisify)(import_fs6.default.writeFile);
|
|
4513
4764
|
var version = 3;
|
|
4514
4765
|
async function downloadFilesInWorkPath({
|
|
4515
4766
|
entrypoint,
|
|
@@ -4517,13 +4768,13 @@ async function downloadFilesInWorkPath({
|
|
|
4517
4768
|
files,
|
|
4518
4769
|
meta = {}
|
|
4519
4770
|
}) {
|
|
4520
|
-
(0,
|
|
4521
|
-
let downloadedFiles = await (0,
|
|
4771
|
+
(0, import_build_utils9.debug)("Downloading user files...");
|
|
4772
|
+
let downloadedFiles = await (0, import_build_utils9.download)(files, workPath, meta);
|
|
4522
4773
|
if (meta.isDev) {
|
|
4523
|
-
const { devCacheDir = (0,
|
|
4524
|
-
const destCache = (0,
|
|
4525
|
-
await (0,
|
|
4526
|
-
downloadedFiles = await (0,
|
|
4774
|
+
const { devCacheDir = (0, import_path8.join)(workPath, ".now", "cache") } = meta;
|
|
4775
|
+
const destCache = (0, import_path8.join)(devCacheDir, (0, import_path8.basename)(entrypoint, ".py"));
|
|
4776
|
+
await (0, import_build_utils9.download)(downloadedFiles, destCache);
|
|
4777
|
+
downloadedFiles = await (0, import_build_utils9.glob)("**", destCache);
|
|
4527
4778
|
workPath = destCache;
|
|
4528
4779
|
}
|
|
4529
4780
|
return workPath;
|
|
@@ -4539,7 +4790,7 @@ var build = async ({
|
|
|
4539
4790
|
const framework = config?.framework;
|
|
4540
4791
|
let spawnEnv;
|
|
4541
4792
|
let projectInstallCommand;
|
|
4542
|
-
(0,
|
|
4793
|
+
(0, import_build_utils9.debug)(`workPath: ${workPath}`);
|
|
4543
4794
|
workPath = await downloadFilesInWorkPath({
|
|
4544
4795
|
workPath,
|
|
4545
4796
|
files: originalFiles,
|
|
@@ -4548,21 +4799,21 @@ var build = async ({
|
|
|
4548
4799
|
});
|
|
4549
4800
|
try {
|
|
4550
4801
|
if (meta.isDev) {
|
|
4551
|
-
const setupCfg = (0,
|
|
4802
|
+
const setupCfg = (0, import_path8.join)(workPath, "setup.cfg");
|
|
4552
4803
|
await writeFile(setupCfg, "[install]\nprefix=\n");
|
|
4553
4804
|
}
|
|
4554
4805
|
} catch (err) {
|
|
4555
4806
|
console.log('Failed to create "setup.cfg" file');
|
|
4556
4807
|
throw err;
|
|
4557
4808
|
}
|
|
4558
|
-
if ((0,
|
|
4809
|
+
if ((0, import_build_utils9.isPythonFramework)(framework)) {
|
|
4559
4810
|
const {
|
|
4560
4811
|
cliType,
|
|
4561
4812
|
lockfileVersion,
|
|
4562
4813
|
packageJsonPackageManager,
|
|
4563
4814
|
turboSupportsCorepackHome
|
|
4564
|
-
} = await (0,
|
|
4565
|
-
spawnEnv = (0,
|
|
4815
|
+
} = await (0, import_build_utils9.scanParentDirs)(workPath, true);
|
|
4816
|
+
spawnEnv = (0, import_build_utils9.getEnvForPackageManager)({
|
|
4566
4817
|
cliType,
|
|
4567
4818
|
lockfileVersion,
|
|
4568
4819
|
packageJsonPackageManager,
|
|
@@ -4583,7 +4834,7 @@ var build = async ({
|
|
|
4583
4834
|
config?.buildCommand;
|
|
4584
4835
|
if (projectBuildCommand) {
|
|
4585
4836
|
console.log(`Running "${projectBuildCommand}"`);
|
|
4586
|
-
await (0,
|
|
4837
|
+
await (0, import_build_utils9.execCommand)(projectBuildCommand, {
|
|
4587
4838
|
env: spawnEnv,
|
|
4588
4839
|
cwd: workPath
|
|
4589
4840
|
});
|
|
@@ -4595,21 +4846,21 @@ var build = async ({
|
|
|
4595
4846
|
);
|
|
4596
4847
|
}
|
|
4597
4848
|
}
|
|
4598
|
-
let fsFiles = await (0,
|
|
4599
|
-
if ((0,
|
|
4849
|
+
let fsFiles = await (0, import_build_utils9.glob)("**", workPath);
|
|
4850
|
+
if ((0, import_build_utils9.isPythonFramework)(framework) && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
|
|
4600
4851
|
const detected = await detectPythonEntrypoint(
|
|
4601
4852
|
config.framework,
|
|
4602
4853
|
workPath,
|
|
4603
4854
|
entrypoint
|
|
4604
4855
|
);
|
|
4605
4856
|
if (detected) {
|
|
4606
|
-
(0,
|
|
4857
|
+
(0, import_build_utils9.debug)(
|
|
4607
4858
|
`Resolved Python entrypoint to "${detected}" (configured "${entrypoint}" not found).`
|
|
4608
4859
|
);
|
|
4609
4860
|
entrypoint = detected;
|
|
4610
4861
|
} else {
|
|
4611
4862
|
const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
4612
|
-
throw new
|
|
4863
|
+
throw new import_build_utils9.NowBuildError({
|
|
4613
4864
|
code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
|
|
4614
4865
|
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
|
|
4615
4866
|
link: `https://vercel.com/docs/frameworks/backend/${framework}#exporting-the-${framework}-application`,
|
|
@@ -4617,7 +4868,7 @@ var build = async ({
|
|
|
4617
4868
|
});
|
|
4618
4869
|
}
|
|
4619
4870
|
}
|
|
4620
|
-
const entryDirectory = (0,
|
|
4871
|
+
const entryDirectory = (0, import_path8.dirname)(entrypoint);
|
|
4621
4872
|
const pyprojectDir = findDir({
|
|
4622
4873
|
file: "pyproject.toml",
|
|
4623
4874
|
entryDirectory,
|
|
@@ -4639,40 +4890,40 @@ var build = async ({
|
|
|
4639
4890
|
let declaredPythonVersion;
|
|
4640
4891
|
if (pythonVersionFileDir) {
|
|
4641
4892
|
try {
|
|
4642
|
-
const content = await
|
|
4643
|
-
(0,
|
|
4893
|
+
const content = await readFile2(
|
|
4894
|
+
(0, import_path8.join)(pythonVersionFileDir, ".python-version"),
|
|
4644
4895
|
"utf8"
|
|
4645
4896
|
);
|
|
4646
4897
|
const version2 = parsePythonVersionFile(content);
|
|
4647
4898
|
if (version2) {
|
|
4648
4899
|
declaredPythonVersion = { version: version2, source: ".python-version" };
|
|
4649
|
-
(0,
|
|
4900
|
+
(0, import_build_utils9.debug)(`Found Python version ${version2} in .python-version`);
|
|
4650
4901
|
}
|
|
4651
4902
|
} catch (err) {
|
|
4652
|
-
(0,
|
|
4903
|
+
(0, import_build_utils9.debug)("Failed to read .python-version file", err);
|
|
4653
4904
|
}
|
|
4654
4905
|
}
|
|
4655
4906
|
if (!declaredPythonVersion && pyprojectDir) {
|
|
4656
4907
|
let requiresPython;
|
|
4657
4908
|
try {
|
|
4658
|
-
const pyproject = await (0,
|
|
4909
|
+
const pyproject = await (0, import_build_utils10.readConfigFile)((0, import_path8.join)(pyprojectDir, "pyproject.toml"));
|
|
4659
4910
|
requiresPython = pyproject?.project?.["requires-python"];
|
|
4660
4911
|
} catch (err) {
|
|
4661
|
-
(0,
|
|
4912
|
+
(0, import_build_utils9.debug)("Failed to parse pyproject.toml", err);
|
|
4662
4913
|
}
|
|
4663
4914
|
if (typeof requiresPython === "string" && requiresPython.trim()) {
|
|
4664
4915
|
declaredPythonVersion = {
|
|
4665
4916
|
version: requiresPython.trim(),
|
|
4666
4917
|
source: "pyproject.toml"
|
|
4667
4918
|
};
|
|
4668
|
-
(0,
|
|
4919
|
+
(0, import_build_utils9.debug)(`Found requires-python "${requiresPython}" in pyproject.toml`);
|
|
4669
4920
|
}
|
|
4670
4921
|
}
|
|
4671
4922
|
if (!declaredPythonVersion && pipfileLockDir) {
|
|
4672
4923
|
let lock = {};
|
|
4673
|
-
const pipfileLockPath = (0,
|
|
4924
|
+
const pipfileLockPath = (0, import_path8.join)(pipfileLockDir, "Pipfile.lock");
|
|
4674
4925
|
try {
|
|
4675
|
-
const pipfileLockContent = await
|
|
4926
|
+
const pipfileLockContent = await readFile2(pipfileLockPath, "utf8");
|
|
4676
4927
|
try {
|
|
4677
4928
|
lock = JSON.parse(pipfileLockContent);
|
|
4678
4929
|
} catch (err) {
|
|
@@ -4683,7 +4934,7 @@ ${pipfileLockContent}`
|
|
|
4683
4934
|
throw err;
|
|
4684
4935
|
}
|
|
4685
4936
|
} catch (err) {
|
|
4686
|
-
throw new
|
|
4937
|
+
throw new import_build_utils9.NowBuildError({
|
|
4687
4938
|
code: "INVALID_PIPFILE_LOCK",
|
|
4688
4939
|
message: "Unable to parse Pipfile.lock"
|
|
4689
4940
|
});
|
|
@@ -4691,7 +4942,7 @@ ${pipfileLockContent}`
|
|
|
4691
4942
|
const pyFromLock = lock?._meta?.requires?.python_version;
|
|
4692
4943
|
if (pyFromLock) {
|
|
4693
4944
|
declaredPythonVersion = { version: pyFromLock, source: "Pipfile.lock" };
|
|
4694
|
-
(0,
|
|
4945
|
+
(0, import_build_utils9.debug)(`Found Python version ${pyFromLock} in Pipfile.lock`);
|
|
4695
4946
|
}
|
|
4696
4947
|
}
|
|
4697
4948
|
const pythonVersion = getSupportedPythonVersion({
|
|
@@ -4701,15 +4952,15 @@ ${pipfileLockContent}`
|
|
|
4701
4952
|
const selectedVersionTuple = parseVersionTuple(pythonVersion.version);
|
|
4702
4953
|
const defaultVersionTuple = parseVersionTuple(DEFAULT_PYTHON_VERSION);
|
|
4703
4954
|
if (!pythonVersionFileDir && pyprojectDir && declaredPythonVersion?.source === "pyproject.toml" && selectedVersionTuple && defaultVersionTuple && compareTuples(selectedVersionTuple, defaultVersionTuple) <= 0) {
|
|
4704
|
-
const pythonVersionFilePath = (0,
|
|
4955
|
+
const pythonVersionFilePath = (0, import_path8.join)(pyprojectDir, ".python-version");
|
|
4705
4956
|
await writeFile(pythonVersionFilePath, `${pythonVersion.version}
|
|
4706
4957
|
`);
|
|
4707
4958
|
console.log(
|
|
4708
4959
|
`Writing .python-version file with version ${pythonVersion.version}`
|
|
4709
4960
|
);
|
|
4710
4961
|
}
|
|
4711
|
-
fsFiles = await (0,
|
|
4712
|
-
const venvPath = (0,
|
|
4962
|
+
fsFiles = await (0, import_build_utils9.glob)("**", workPath);
|
|
4963
|
+
const venvPath = (0, import_path8.join)(workPath, ".vercel", "python", ".venv");
|
|
4713
4964
|
await ensureVenv({
|
|
4714
4965
|
pythonPath: pythonVersion.pythonPath,
|
|
4715
4966
|
venvPath
|
|
@@ -4720,7 +4971,7 @@ ${pipfileLockContent}`
|
|
|
4720
4971
|
let assumeDepsInstalled = false;
|
|
4721
4972
|
if (projectInstallCommand) {
|
|
4722
4973
|
console.log(`Running "install" command: \`${projectInstallCommand}\`...`);
|
|
4723
|
-
await (0,
|
|
4974
|
+
await (0, import_build_utils9.execCommand)(projectInstallCommand, {
|
|
4724
4975
|
env: pythonEnv,
|
|
4725
4976
|
cwd: workPath
|
|
4726
4977
|
});
|
|
@@ -4777,7 +5028,7 @@ ${pipfileLockContent}`
|
|
|
4777
5028
|
});
|
|
4778
5029
|
} catch (err) {
|
|
4779
5030
|
noBuildCheckFailed = true;
|
|
4780
|
-
(0,
|
|
5031
|
+
(0, import_build_utils9.debug)(
|
|
4781
5032
|
`--no-build check failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4782
5033
|
);
|
|
4783
5034
|
}
|
|
@@ -4790,18 +5041,18 @@ ${pipfileLockContent}`
|
|
|
4790
5041
|
});
|
|
4791
5042
|
}
|
|
4792
5043
|
const runtimeDep = baseEnv.VERCEL_RUNTIME_PYTHON || `vercel-runtime==${VERCEL_RUNTIME_VERSION}`;
|
|
4793
|
-
(0,
|
|
5044
|
+
(0, import_build_utils9.debug)(`Installing ${runtimeDep}`);
|
|
4794
5045
|
await uv.pip({
|
|
4795
5046
|
venvPath,
|
|
4796
|
-
projectDir: (0,
|
|
5047
|
+
projectDir: (0, import_path8.join)(workPath, entryDirectory),
|
|
4797
5048
|
args: ["install", runtimeDep]
|
|
4798
5049
|
});
|
|
4799
|
-
(0,
|
|
5050
|
+
(0, import_build_utils9.debug)("Entrypoint is", entrypoint);
|
|
4800
5051
|
const moduleName = entrypoint.replace(/\//g, ".").replace(/\.py$/i, "");
|
|
4801
5052
|
const vendorDir = resolveVendorDir();
|
|
4802
5053
|
const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
|
|
4803
5054
|
const entrypointWithSuffix = `${entrypoint}${suffix}`;
|
|
4804
|
-
(0,
|
|
5055
|
+
(0, import_build_utils9.debug)("Entrypoint with suffix is", entrypointWithSuffix);
|
|
4805
5056
|
const runtimeTrampoline = `
|
|
4806
5057
|
import importlib
|
|
4807
5058
|
import os
|
|
@@ -4864,166 +5115,32 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
4864
5115
|
cwd: workPath,
|
|
4865
5116
|
ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
|
|
4866
5117
|
};
|
|
4867
|
-
const files = await (0,
|
|
4868
|
-
const
|
|
5118
|
+
const files = await (0, import_build_utils9.glob)("**", globOptions);
|
|
5119
|
+
const depExternalizer = new PythonDependencyExternalizer({
|
|
4869
5120
|
venvPath,
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
const totalBundleSizeMB = (totalBundleSize / (1024 * 1024)).toFixed(2);
|
|
4878
|
-
(0, import_build_utils8.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
|
|
4879
|
-
const runtimeInstallEnabled = shouldEnableRuntimeInstall({
|
|
4880
|
-
totalBundleSize,
|
|
4881
|
-
uvLockPath
|
|
5121
|
+
vendorDir,
|
|
5122
|
+
workPath,
|
|
5123
|
+
uvLockPath,
|
|
5124
|
+
uvProjectDir,
|
|
5125
|
+
projectName,
|
|
5126
|
+
noBuildCheckFailed,
|
|
5127
|
+
pythonPath: pythonVersion.pythonPath
|
|
4882
5128
|
});
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
);
|
|
4887
|
-
if (totalBundleSize > LAMBDA_EPHEMERAL_STORAGE_BYTES) {
|
|
4888
|
-
const ephemeralLimitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(0);
|
|
4889
|
-
throw new import_build_utils8.NowBuildError({
|
|
4890
|
-
code: "LAMBDA_SIZE_EXCEEDED",
|
|
4891
|
-
message: `Total dependency size (${totalBundleSizeMB} MB) exceeds Lambda ephemeral storage limit (${ephemeralLimitMB} MB). Even with runtime dependency installation, all packages must fit within the ${ephemeralLimitMB} MB ephemeral storage available to Lambda functions. Consider removing unused dependencies or splitting your application into smaller functions.`
|
|
4892
|
-
});
|
|
4893
|
-
}
|
|
4894
|
-
if (noBuildCheckFailed) {
|
|
4895
|
-
throw new import_build_utils8.NowBuildError({
|
|
4896
|
-
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
4897
|
-
message: `Bundle size exceeds the Lambda limit and requires runtime dependency installation, but some packages in your uv.lock file do not have pre-built binary wheels available.
|
|
4898
|
-
Runtime dependency installation requires all public packages to have binary wheels.
|
|
4899
|
-
|
|
4900
|
-
To fix this, either:
|
|
4901
|
-
1. Regenerate your lock file with: uv lock --upgrade --no-build, or
|
|
4902
|
-
2. Switch the problematic packages to ones that have pre-built wheels available`
|
|
4903
|
-
});
|
|
4904
|
-
}
|
|
4905
|
-
let lockContent;
|
|
4906
|
-
try {
|
|
4907
|
-
lockContent = await readFile(uvLockPath, "utf8");
|
|
4908
|
-
} catch (error) {
|
|
4909
|
-
if (error instanceof Error) {
|
|
4910
|
-
console.log(
|
|
4911
|
-
`Failed to read uv.lock file at "${uvLockPath}": ${error.message}`
|
|
4912
|
-
);
|
|
4913
|
-
} else {
|
|
4914
|
-
console.log(
|
|
4915
|
-
`Failed to read uv.lock file at "${uvLockPath}": ${String(error)}`
|
|
4916
|
-
);
|
|
4917
|
-
}
|
|
4918
|
-
throw new import_build_utils8.NowBuildError({
|
|
4919
|
-
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
4920
|
-
message: `Failed to read uv.lock file at "${uvLockPath}"`
|
|
4921
|
-
});
|
|
4922
|
-
}
|
|
4923
|
-
let lockFile;
|
|
4924
|
-
try {
|
|
4925
|
-
lockFile = (0, import_python_analysis3.parseUvLock)(lockContent, uvLockPath);
|
|
4926
|
-
} catch (error) {
|
|
4927
|
-
if (error instanceof import_python_analysis3.PythonAnalysisError) {
|
|
4928
|
-
if (error.fileContent) {
|
|
4929
|
-
console.log(
|
|
4930
|
-
`Failed to parse "${error.path}". File content:
|
|
4931
|
-
${error.fileContent}`
|
|
4932
|
-
);
|
|
4933
|
-
}
|
|
4934
|
-
throw new import_build_utils8.NowBuildError({
|
|
4935
|
-
code: error.code,
|
|
4936
|
-
message: error.message
|
|
4937
|
-
});
|
|
4938
|
-
}
|
|
4939
|
-
throw error;
|
|
4940
|
-
}
|
|
4941
|
-
const excludePackages = [];
|
|
4942
|
-
if (projectName) {
|
|
4943
|
-
excludePackages.push(projectName);
|
|
4944
|
-
(0, import_build_utils8.debug)(
|
|
4945
|
-
`Excluding project package "${projectName}" from runtime installation`
|
|
4946
|
-
);
|
|
4947
|
-
}
|
|
4948
|
-
const classification = (0, import_python_analysis3.classifyPackages)({
|
|
4949
|
-
lockFile,
|
|
4950
|
-
excludePackages
|
|
4951
|
-
});
|
|
4952
|
-
(0, import_build_utils8.debug)(
|
|
4953
|
-
`Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
|
|
4954
|
-
);
|
|
4955
|
-
if (classification.publicPackages.length > 0) {
|
|
4956
|
-
const privatePackagesWithRuntime = [
|
|
4957
|
-
...classification.privatePackages,
|
|
4958
|
-
"vercel-runtime",
|
|
4959
|
-
"vercel_runtime"
|
|
4960
|
-
];
|
|
4961
|
-
const privateVendorFiles = await mirrorPrivatePackagesIntoVendor({
|
|
4962
|
-
venvPath,
|
|
4963
|
-
vendorDirName: vendorDir,
|
|
4964
|
-
privatePackages: privatePackagesWithRuntime
|
|
4965
|
-
});
|
|
4966
|
-
for (const [p, f] of Object.entries(privateVendorFiles)) {
|
|
4967
|
-
files[p] = f;
|
|
4968
|
-
}
|
|
4969
|
-
const runtimeRequirementsContent = (0, import_python_analysis3.generateRuntimeRequirements)(classification);
|
|
4970
|
-
const runtimeRequirementsPath = `${UV_BUNDLE_DIR}/_runtime_requirements.txt`;
|
|
4971
|
-
files[runtimeRequirementsPath] = new import_build_utils8.FileBlob({
|
|
4972
|
-
data: runtimeRequirementsContent
|
|
4973
|
-
});
|
|
4974
|
-
if (process.env.VERCEL_BUILD_IMAGE) {
|
|
4975
|
-
try {
|
|
4976
|
-
const uvBinaryPath = await getUvBinaryForBundling(
|
|
4977
|
-
pythonVersion.pythonPath
|
|
4978
|
-
);
|
|
4979
|
-
const uvBundleDir = (0, import_path7.join)(workPath, UV_BUNDLE_DIR);
|
|
4980
|
-
const uvLocalPath = (0, import_path7.join)(uvBundleDir, "uv");
|
|
4981
|
-
await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
|
|
4982
|
-
await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
|
|
4983
|
-
await import_fs5.default.promises.chmod(uvLocalPath, 493);
|
|
4984
|
-
const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
|
|
4985
|
-
files[uvBundlePath] = new import_build_utils8.FileFsRef({
|
|
4986
|
-
fsPath: uvLocalPath,
|
|
4987
|
-
mode: 33261
|
|
4988
|
-
// Regular file + executable
|
|
4989
|
-
});
|
|
4990
|
-
(0, import_build_utils8.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
|
|
4991
|
-
} catch (err) {
|
|
4992
|
-
throw new import_build_utils8.NowBuildError({
|
|
4993
|
-
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
4994
|
-
message: `Failed to bundle uv binary for runtime installation: ${err instanceof Error ? err.message : String(err)}`
|
|
4995
|
-
});
|
|
4996
|
-
}
|
|
4997
|
-
}
|
|
4998
|
-
} else {
|
|
4999
|
-
throw new import_build_utils8.NowBuildError({
|
|
5000
|
-
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
5001
|
-
message: "Bundle size exceeds limit but no public packages found for runtime installation."
|
|
5002
|
-
});
|
|
5003
|
-
}
|
|
5129
|
+
const { overLambdaLimit, allVendorFiles } = await depExternalizer.analyze(files);
|
|
5130
|
+
if (overLambdaLimit) {
|
|
5131
|
+
await depExternalizer.generateBundle(files);
|
|
5004
5132
|
} else {
|
|
5005
5133
|
for (const [p, f] of Object.entries(allVendorFiles)) {
|
|
5006
5134
|
files[p] = f;
|
|
5007
5135
|
}
|
|
5008
5136
|
}
|
|
5009
5137
|
const handlerPyFilename = "vc__handler__python";
|
|
5010
|
-
files[`${handlerPyFilename}.py`] = new
|
|
5138
|
+
files[`${handlerPyFilename}.py`] = new import_build_utils9.FileBlob({ data: runtimeTrampoline });
|
|
5011
5139
|
if (config.framework === "fasthtml") {
|
|
5012
5140
|
const { SESSKEY = "" } = process.env;
|
|
5013
|
-
files[".sesskey"] = new
|
|
5014
|
-
}
|
|
5015
|
-
if (runtimeInstallEnabled) {
|
|
5016
|
-
const finalBundleSize = await calculateBundleSize(files);
|
|
5017
|
-
if (finalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES) {
|
|
5018
|
-
const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
|
|
5019
|
-
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
5020
|
-
throw new import_build_utils8.NowBuildError({
|
|
5021
|
-
code: "LAMBDA_SIZE_EXCEEDED",
|
|
5022
|
-
message: `Bundle size (${finalSizeMB} MB) exceeds Lambda limit (${limitMB} MB) even after deferring public packages to runtime installation. This usually means your private packages or source code are too large. Consider reducing the size of private dependencies or splitting your application.`
|
|
5023
|
-
});
|
|
5024
|
-
}
|
|
5141
|
+
files[".sesskey"] = new import_build_utils9.FileBlob({ data: `"${SESSKEY}"` });
|
|
5025
5142
|
}
|
|
5026
|
-
const output = new
|
|
5143
|
+
const output = new import_build_utils9.Lambda({
|
|
5027
5144
|
files,
|
|
5028
5145
|
handler: `${handlerPyFilename}.vc_handler`,
|
|
5029
5146
|
runtime: pythonVersion.runtime,
|
|
@@ -5059,7 +5176,7 @@ var defaultShouldServe = ({
|
|
|
5059
5176
|
if (entrypoint === requestPath && hasProp(files, entrypoint)) {
|
|
5060
5177
|
return true;
|
|
5061
5178
|
}
|
|
5062
|
-
const { dir, name } = (0,
|
|
5179
|
+
const { dir, name } = (0, import_path8.parse)(entrypoint);
|
|
5063
5180
|
if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
|
|
5064
5181
|
return true;
|
|
5065
5182
|
}
|
|
@@ -5085,7 +5202,6 @@ function parsePythonVersionFile(content) {
|
|
|
5085
5202
|
downloadFilesInWorkPath,
|
|
5086
5203
|
installRequirement,
|
|
5087
5204
|
installRequirementsFile,
|
|
5088
|
-
shouldEnableRuntimeInstall,
|
|
5089
5205
|
shouldServe,
|
|
5090
5206
|
startDevServer,
|
|
5091
5207
|
version
|