@vercel/python 6.50.0 → 6.51.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 +1066 -1085
- package/package.json +6 -6
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 fs17 = 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
|
+
fs17.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(fs17.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 fs17 = require("fs");
|
|
92
92
|
function isexe(path, options, cb) {
|
|
93
|
-
|
|
93
|
+
fs17.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(fs17.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 fs17 = 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 fs17 = 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 = fs17.openSync(command, "r");
|
|
412
|
+
fs17.readSync(fd, buffer, 0, size, 0);
|
|
413
|
+
fs17.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 debug14;
|
|
427
427
|
if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
|
|
428
|
-
|
|
428
|
+
debug14 = 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
|
+
debug14 = 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
|
+
debug14(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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("hyphen replace", range);
|
|
1054
1054
|
range = range.replace(safeRe[COMPARATORTRIM], comparatorTrimReplace);
|
|
1055
|
-
|
|
1055
|
+
debug14("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
|
+
debug14("comp", comp, options);
|
|
1096
1096
|
comp = replaceCarets(comp, options);
|
|
1097
|
-
|
|
1097
|
+
debug14("caret", comp);
|
|
1098
1098
|
comp = replaceTildes(comp, options);
|
|
1099
|
-
|
|
1099
|
+
debug14("tildes", comp);
|
|
1100
1100
|
comp = replaceXRanges(comp, options);
|
|
1101
|
-
|
|
1101
|
+
debug14("xrange", comp);
|
|
1102
1102
|
comp = replaceStars(comp, options);
|
|
1103
|
-
|
|
1103
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("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
|
+
debug14("caret return", ret);
|
|
1180
1180
|
return ret;
|
|
1181
1181
|
});
|
|
1182
1182
|
}
|
|
1183
1183
|
function replaceXRanges(comp, options) {
|
|
1184
|
-
|
|
1184
|
+
debug14("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
|
+
debug14("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
|
+
debug14("xRange return", ret);
|
|
1237
1237
|
return ret;
|
|
1238
1238
|
});
|
|
1239
1239
|
}
|
|
1240
1240
|
function replaceStars(comp, options) {
|
|
1241
|
-
|
|
1241
|
+
debug14("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
|
+
debug14(set[i2].semver);
|
|
1290
1290
|
if (set[i2].semver === ANY) {
|
|
1291
1291
|
continue;
|
|
1292
1292
|
}
|
|
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
|
|
|
1895
1895
|
"../../node_modules/.pnpm/pump@3.0.4/node_modules/pump/index.js"(exports, module2) {
|
|
1896
1896
|
var once = require_once();
|
|
1897
1897
|
var eos = require_end_of_stream();
|
|
1898
|
-
var
|
|
1898
|
+
var fs17;
|
|
1899
1899
|
try {
|
|
1900
|
-
|
|
1900
|
+
fs17 = 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 (!fs17)
|
|
1913
1913
|
return false;
|
|
1914
|
-
return (stream instanceof (
|
|
1914
|
+
return (stream instanceof (fs17.ReadStream || noop) || stream instanceof (fs17.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: join18, delimiter: delimiter2, sep: sep3, posix } = require("path");
|
|
2655
2655
|
var isWindows = process.platform === "win32";
|
|
2656
2656
|
var rSlash = new RegExp(`[${posix.sep}${sep3 === posix.sep ? "" : sep3}]`.replace(/(\\)/g, "\\$1"));
|
|
2657
2657
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -2680,7 +2680,7 @@ var require_lib = __commonJS({
|
|
|
2680
2680
|
var getPathPart = (raw, cmd) => {
|
|
2681
2681
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
2682
2682
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
2683
|
-
return prefix +
|
|
2683
|
+
return prefix + join18(pathPart, cmd);
|
|
2684
2684
|
};
|
|
2685
2685
|
var which2 = async (cmd, opt = {}) => {
|
|
2686
2686
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -2739,15 +2739,15 @@ var require_lib = __commonJS({
|
|
|
2739
2739
|
var require_semver2 = __commonJS({
|
|
2740
2740
|
"../../node_modules/.pnpm/semver@6.3.1/node_modules/semver/semver.js"(exports, module2) {
|
|
2741
2741
|
exports = module2.exports = SemVer;
|
|
2742
|
-
var
|
|
2742
|
+
var debug14;
|
|
2743
2743
|
if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
|
|
2744
|
-
|
|
2744
|
+
debug14 = function() {
|
|
2745
2745
|
var args = Array.prototype.slice.call(arguments, 0);
|
|
2746
2746
|
args.unshift("SEMVER");
|
|
2747
2747
|
console.log.apply(console, args);
|
|
2748
2748
|
};
|
|
2749
2749
|
} else {
|
|
2750
|
-
|
|
2750
|
+
debug14 = function() {
|
|
2751
2751
|
};
|
|
2752
2752
|
}
|
|
2753
2753
|
exports.SEMVER_SPEC_VERSION = "2.0.0";
|
|
@@ -2865,7 +2865,7 @@ var require_semver2 = __commonJS({
|
|
|
2865
2865
|
tok("STAR");
|
|
2866
2866
|
src[t.STAR] = "(<|>)?=?\\s*\\*";
|
|
2867
2867
|
for (i = 0; i < R; i++) {
|
|
2868
|
-
|
|
2868
|
+
debug14(i, src[i]);
|
|
2869
2869
|
if (!re[i]) {
|
|
2870
2870
|
re[i] = new RegExp(src[i]);
|
|
2871
2871
|
safeRe[i] = new RegExp(makeSafeRe(src[i]));
|
|
@@ -2932,7 +2932,7 @@ var require_semver2 = __commonJS({
|
|
|
2932
2932
|
if (!(this instanceof SemVer)) {
|
|
2933
2933
|
return new SemVer(version2, options);
|
|
2934
2934
|
}
|
|
2935
|
-
|
|
2935
|
+
debug14("SemVer", version2, options);
|
|
2936
2936
|
this.options = options;
|
|
2937
2937
|
this.loose = !!options.loose;
|
|
2938
2938
|
var m = version2.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]);
|
|
@@ -2979,7 +2979,7 @@ var require_semver2 = __commonJS({
|
|
|
2979
2979
|
return this.version;
|
|
2980
2980
|
};
|
|
2981
2981
|
SemVer.prototype.compare = function(other) {
|
|
2982
|
-
|
|
2982
|
+
debug14("SemVer.compare", this.version, this.options, other);
|
|
2983
2983
|
if (!(other instanceof SemVer)) {
|
|
2984
2984
|
other = new SemVer(other, this.options);
|
|
2985
2985
|
}
|
|
@@ -3006,7 +3006,7 @@ var require_semver2 = __commonJS({
|
|
|
3006
3006
|
do {
|
|
3007
3007
|
var a = this.prerelease[i2];
|
|
3008
3008
|
var b = other.prerelease[i2];
|
|
3009
|
-
|
|
3009
|
+
debug14("prerelease compare", i2, a, b);
|
|
3010
3010
|
if (a === void 0 && b === void 0) {
|
|
3011
3011
|
return 0;
|
|
3012
3012
|
} else if (b === void 0) {
|
|
@@ -3028,7 +3028,7 @@ var require_semver2 = __commonJS({
|
|
|
3028
3028
|
do {
|
|
3029
3029
|
var a = this.build[i2];
|
|
3030
3030
|
var b = other.build[i2];
|
|
3031
|
-
|
|
3031
|
+
debug14("prerelease compare", i2, a, b);
|
|
3032
3032
|
if (a === void 0 && b === void 0) {
|
|
3033
3033
|
return 0;
|
|
3034
3034
|
} else if (b === void 0) {
|
|
@@ -3288,7 +3288,7 @@ var require_semver2 = __commonJS({
|
|
|
3288
3288
|
return new Comparator(comp, options);
|
|
3289
3289
|
}
|
|
3290
3290
|
comp = comp.trim().split(/\s+/).join(" ");
|
|
3291
|
-
|
|
3291
|
+
debug14("comparator", comp, options);
|
|
3292
3292
|
this.options = options;
|
|
3293
3293
|
this.loose = !!options.loose;
|
|
3294
3294
|
this.parse(comp);
|
|
@@ -3297,7 +3297,7 @@ var require_semver2 = __commonJS({
|
|
|
3297
3297
|
} else {
|
|
3298
3298
|
this.value = this.operator + this.semver.version;
|
|
3299
3299
|
}
|
|
3300
|
-
|
|
3300
|
+
debug14("comp", this);
|
|
3301
3301
|
}
|
|
3302
3302
|
var ANY = {};
|
|
3303
3303
|
Comparator.prototype.parse = function(comp) {
|
|
@@ -3320,7 +3320,7 @@ var require_semver2 = __commonJS({
|
|
|
3320
3320
|
return this.value;
|
|
3321
3321
|
};
|
|
3322
3322
|
Comparator.prototype.test = function(version2) {
|
|
3323
|
-
|
|
3323
|
+
debug14("Comparator.test", version2, this.options.loose);
|
|
3324
3324
|
if (this.semver === ANY || version2 === ANY) {
|
|
3325
3325
|
return true;
|
|
3326
3326
|
}
|
|
@@ -3413,9 +3413,9 @@ var require_semver2 = __commonJS({
|
|
|
3413
3413
|
var loose = this.options.loose;
|
|
3414
3414
|
var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE];
|
|
3415
3415
|
range = range.replace(hr, hyphenReplace);
|
|
3416
|
-
|
|
3416
|
+
debug14("hyphen replace", range);
|
|
3417
3417
|
range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace);
|
|
3418
|
-
|
|
3418
|
+
debug14("comparator trim", range, safeRe[t.COMPARATORTRIM]);
|
|
3419
3419
|
range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace);
|
|
3420
3420
|
range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace);
|
|
3421
3421
|
range = range.split(/\s+/).join(" ");
|
|
@@ -3468,15 +3468,15 @@ var require_semver2 = __commonJS({
|
|
|
3468
3468
|
});
|
|
3469
3469
|
}
|
|
3470
3470
|
function parseComparator(comp, options) {
|
|
3471
|
-
|
|
3471
|
+
debug14("comp", comp, options);
|
|
3472
3472
|
comp = replaceCarets(comp, options);
|
|
3473
|
-
|
|
3473
|
+
debug14("caret", comp);
|
|
3474
3474
|
comp = replaceTildes(comp, options);
|
|
3475
|
-
|
|
3475
|
+
debug14("tildes", comp);
|
|
3476
3476
|
comp = replaceXRanges(comp, options);
|
|
3477
|
-
|
|
3477
|
+
debug14("xrange", comp);
|
|
3478
3478
|
comp = replaceStars(comp, options);
|
|
3479
|
-
|
|
3479
|
+
debug14("stars", comp);
|
|
3480
3480
|
return comp;
|
|
3481
3481
|
}
|
|
3482
3482
|
function isX(id) {
|
|
@@ -3490,7 +3490,7 @@ var require_semver2 = __commonJS({
|
|
|
3490
3490
|
function replaceTilde(comp, options) {
|
|
3491
3491
|
var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE];
|
|
3492
3492
|
return comp.replace(r, function(_, M, m, p, pr) {
|
|
3493
|
-
|
|
3493
|
+
debug14("tilde", comp, _, M, m, p, pr);
|
|
3494
3494
|
var ret;
|
|
3495
3495
|
if (isX(M)) {
|
|
3496
3496
|
ret = "";
|
|
@@ -3499,12 +3499,12 @@ var require_semver2 = __commonJS({
|
|
|
3499
3499
|
} else if (isX(p)) {
|
|
3500
3500
|
ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
|
|
3501
3501
|
} else if (pr) {
|
|
3502
|
-
|
|
3502
|
+
debug14("replaceTilde pr", pr);
|
|
3503
3503
|
ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + (+m + 1) + ".0";
|
|
3504
3504
|
} else {
|
|
3505
3505
|
ret = ">=" + M + "." + m + "." + p + " <" + M + "." + (+m + 1) + ".0";
|
|
3506
3506
|
}
|
|
3507
|
-
|
|
3507
|
+
debug14("tilde return", ret);
|
|
3508
3508
|
return ret;
|
|
3509
3509
|
});
|
|
3510
3510
|
}
|
|
@@ -3514,10 +3514,10 @@ var require_semver2 = __commonJS({
|
|
|
3514
3514
|
}).join(" ");
|
|
3515
3515
|
}
|
|
3516
3516
|
function replaceCaret(comp, options) {
|
|
3517
|
-
|
|
3517
|
+
debug14("caret", comp, options);
|
|
3518
3518
|
var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET];
|
|
3519
3519
|
return comp.replace(r, function(_, M, m, p, pr) {
|
|
3520
|
-
|
|
3520
|
+
debug14("caret", comp, _, M, m, p, pr);
|
|
3521
3521
|
var ret;
|
|
3522
3522
|
if (isX(M)) {
|
|
3523
3523
|
ret = "";
|
|
@@ -3530,7 +3530,7 @@ var require_semver2 = __commonJS({
|
|
|
3530
3530
|
ret = ">=" + M + "." + m + ".0 <" + (+M + 1) + ".0.0";
|
|
3531
3531
|
}
|
|
3532
3532
|
} else if (pr) {
|
|
3533
|
-
|
|
3533
|
+
debug14("replaceCaret pr", pr);
|
|
3534
3534
|
if (M === "0") {
|
|
3535
3535
|
if (m === "0") {
|
|
3536
3536
|
ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + m + "." + (+p + 1);
|
|
@@ -3541,7 +3541,7 @@ var require_semver2 = __commonJS({
|
|
|
3541
3541
|
ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
|
|
3542
3542
|
}
|
|
3543
3543
|
} else {
|
|
3544
|
-
|
|
3544
|
+
debug14("no pr");
|
|
3545
3545
|
if (M === "0") {
|
|
3546
3546
|
if (m === "0") {
|
|
3547
3547
|
ret = ">=" + M + "." + m + "." + p + " <" + M + "." + m + "." + (+p + 1);
|
|
@@ -3552,12 +3552,12 @@ var require_semver2 = __commonJS({
|
|
|
3552
3552
|
ret = ">=" + M + "." + m + "." + p + " <" + (+M + 1) + ".0.0";
|
|
3553
3553
|
}
|
|
3554
3554
|
}
|
|
3555
|
-
|
|
3555
|
+
debug14("caret return", ret);
|
|
3556
3556
|
return ret;
|
|
3557
3557
|
});
|
|
3558
3558
|
}
|
|
3559
3559
|
function replaceXRanges(comp, options) {
|
|
3560
|
-
|
|
3560
|
+
debug14("replaceXRanges", comp, options);
|
|
3561
3561
|
return comp.split(/\s+/).map(function(comp2) {
|
|
3562
3562
|
return replaceXRange(comp2, options);
|
|
3563
3563
|
}).join(" ");
|
|
@@ -3566,7 +3566,7 @@ var require_semver2 = __commonJS({
|
|
|
3566
3566
|
comp = comp.trim();
|
|
3567
3567
|
var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE];
|
|
3568
3568
|
return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
|
|
3569
|
-
|
|
3569
|
+
debug14("xRange", comp, ret, gtlt, M, m, p, pr);
|
|
3570
3570
|
var xM = isX(M);
|
|
3571
3571
|
var xm = xM || isX(m);
|
|
3572
3572
|
var xp = xm || isX(p);
|
|
@@ -3610,12 +3610,12 @@ var require_semver2 = __commonJS({
|
|
|
3610
3610
|
} else if (xp) {
|
|
3611
3611
|
ret = ">=" + M + "." + m + ".0" + pr + " <" + M + "." + (+m + 1) + ".0" + pr;
|
|
3612
3612
|
}
|
|
3613
|
-
|
|
3613
|
+
debug14("xRange return", ret);
|
|
3614
3614
|
return ret;
|
|
3615
3615
|
});
|
|
3616
3616
|
}
|
|
3617
3617
|
function replaceStars(comp, options) {
|
|
3618
|
-
|
|
3618
|
+
debug14("replaceStars", comp, options);
|
|
3619
3619
|
return comp.trim().replace(safeRe[t.STAR], "");
|
|
3620
3620
|
}
|
|
3621
3621
|
function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
|
|
@@ -3667,7 +3667,7 @@ var require_semver2 = __commonJS({
|
|
|
3667
3667
|
}
|
|
3668
3668
|
if (version2.prerelease.length && !options.includePrerelease) {
|
|
3669
3669
|
for (i2 = 0; i2 < set.length; i2++) {
|
|
3670
|
-
|
|
3670
|
+
debug14(set[i2].semver);
|
|
3671
3671
|
if (set[i2].semver === ANY) {
|
|
3672
3672
|
continue;
|
|
3673
3673
|
}
|
|
@@ -3912,27 +3912,27 @@ var require_process = __commonJS({
|
|
|
3912
3912
|
var require_filesystem = __commonJS({
|
|
3913
3913
|
"../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/filesystem.js"(exports, module2) {
|
|
3914
3914
|
"use strict";
|
|
3915
|
-
var
|
|
3915
|
+
var fs17 = require("fs");
|
|
3916
3916
|
var LDD_PATH = "/usr/bin/ldd";
|
|
3917
3917
|
var SELF_PATH = "/proc/self/exe";
|
|
3918
3918
|
var MAX_LENGTH = 2048;
|
|
3919
3919
|
var readFileSync2 = (path) => {
|
|
3920
|
-
const fd =
|
|
3920
|
+
const fd = fs17.openSync(path, "r");
|
|
3921
3921
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
3922
|
-
const bytesRead =
|
|
3923
|
-
|
|
3922
|
+
const bytesRead = fs17.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
3923
|
+
fs17.close(fd, () => {
|
|
3924
3924
|
});
|
|
3925
3925
|
return buffer.subarray(0, bytesRead);
|
|
3926
3926
|
};
|
|
3927
3927
|
var readFile2 = (path) => new Promise((resolve3, reject) => {
|
|
3928
|
-
|
|
3928
|
+
fs17.open(path, "r", (err, fd) => {
|
|
3929
3929
|
if (err) {
|
|
3930
3930
|
reject(err);
|
|
3931
3931
|
} else {
|
|
3932
3932
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
3933
|
-
|
|
3933
|
+
fs17.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
3934
3934
|
resolve3(buffer.subarray(0, bytesRead));
|
|
3935
|
-
|
|
3935
|
+
fs17.close(fd, () => {
|
|
3936
3936
|
});
|
|
3937
3937
|
});
|
|
3938
3938
|
}
|
|
@@ -4379,15 +4379,15 @@ __export(src_exports, {
|
|
|
4379
4379
|
});
|
|
4380
4380
|
module.exports = __toCommonJS(src_exports);
|
|
4381
4381
|
var import_assert = __toESM(require("assert"));
|
|
4382
|
-
var
|
|
4383
|
-
var
|
|
4382
|
+
var import_fs18 = __toESM(require("fs"));
|
|
4383
|
+
var import_path18 = require("path");
|
|
4384
4384
|
|
|
4385
4385
|
// src/package-versions.ts
|
|
4386
4386
|
var VERCEL_RUNTIME_VERSION = "0.16.0";
|
|
4387
4387
|
var VERCEL_WORKERS_VERSION = "0.0.25";
|
|
4388
4388
|
|
|
4389
4389
|
// src/index.ts
|
|
4390
|
-
var
|
|
4390
|
+
var import_build_utils21 = require("@vercel/build-utils");
|
|
4391
4391
|
|
|
4392
4392
|
// src/install.ts
|
|
4393
4393
|
var import_execa3 = __toESM(require_execa());
|
|
@@ -5641,230 +5641,11 @@ async function installRequirementsFile({
|
|
|
5641
5641
|
}
|
|
5642
5642
|
|
|
5643
5643
|
// src/dependency-externalizer.ts
|
|
5644
|
-
var import_fs6 = __toESM(require("fs"));
|
|
5645
|
-
var import_util = require("util");
|
|
5646
|
-
var import_path7 = require("path");
|
|
5647
|
-
var import_build_utils7 = require("@vercel/build-utils");
|
|
5648
|
-
var import_python_analysis3 = require("@vercel/python-analysis");
|
|
5649
|
-
|
|
5650
|
-
// src/compileall.ts
|
|
5651
|
-
var import_execa4 = __toESM(require_execa());
|
|
5652
|
-
var import_build_utils6 = require("@vercel/build-utils");
|
|
5653
5644
|
var import_fs5 = __toESM(require("fs"));
|
|
5645
|
+
var import_util = require("util");
|
|
5654
5646
|
var import_path6 = require("path");
|
|
5655
|
-
var
|
|
5656
|
-
var
|
|
5657
|
-
var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
|
|
5658
|
-
function isCompileAllFlagEnabled() {
|
|
5659
|
-
const val = process.env.VERCEL_PYTHON_COMPILEALL;
|
|
5660
|
-
if (val === void 0 || val === "")
|
|
5661
|
-
return false;
|
|
5662
|
-
const lower = val.toLowerCase();
|
|
5663
|
-
return lower === "1" || lower === "true";
|
|
5664
|
-
}
|
|
5665
|
-
function shouldCompileAll({
|
|
5666
|
-
isDev,
|
|
5667
|
-
hasCustomCommand,
|
|
5668
|
-
hasPreDeployCommand
|
|
5669
|
-
}) {
|
|
5670
|
-
if (isDev)
|
|
5671
|
-
return false;
|
|
5672
|
-
if (hasCustomCommand)
|
|
5673
|
-
return false;
|
|
5674
|
-
if (hasPreDeployCommand)
|
|
5675
|
-
return false;
|
|
5676
|
-
return isCompileAllFlagEnabled();
|
|
5677
|
-
}
|
|
5678
|
-
async function runCompileAll({
|
|
5679
|
-
pythonBin,
|
|
5680
|
-
filesOrDirectories,
|
|
5681
|
-
env,
|
|
5682
|
-
excludeRegex,
|
|
5683
|
-
pycachePrefix
|
|
5684
|
-
}) {
|
|
5685
|
-
if (filesOrDirectories.length === 0)
|
|
5686
|
-
return;
|
|
5687
|
-
const args = [
|
|
5688
|
-
"-m",
|
|
5689
|
-
"compileall",
|
|
5690
|
-
"-q",
|
|
5691
|
-
"-j",
|
|
5692
|
-
"0",
|
|
5693
|
-
"-f",
|
|
5694
|
-
"--invalidation-mode",
|
|
5695
|
-
"unchecked-hash",
|
|
5696
|
-
...excludeRegex ? ["-x", excludeRegex] : [],
|
|
5697
|
-
...filesOrDirectories
|
|
5698
|
-
];
|
|
5699
|
-
const baseEnv = env || process.env;
|
|
5700
|
-
const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
|
|
5701
|
-
try {
|
|
5702
|
-
await (0, import_execa4.default)(pythonBin, args, {
|
|
5703
|
-
env: subprocessEnv,
|
|
5704
|
-
timeout: COMPILEALL_TIMEOUT_MS
|
|
5705
|
-
});
|
|
5706
|
-
} catch (err) {
|
|
5707
|
-
(0, import_build_utils6.debug)(`compileall error details: ${JSON.stringify(err)}`);
|
|
5708
|
-
}
|
|
5709
|
-
}
|
|
5710
|
-
function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
|
|
5711
|
-
if (!pyRelPath.endsWith(".py"))
|
|
5712
|
-
return null;
|
|
5713
|
-
const lastSlash = pyRelPath.lastIndexOf("/");
|
|
5714
|
-
const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
|
|
5715
|
-
const baseName = pyRelPath.slice(lastSlash + 1, -3);
|
|
5716
|
-
return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
|
|
5717
|
-
}
|
|
5718
|
-
function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
|
|
5719
|
-
if (!pyRelPath.endsWith(".py"))
|
|
5720
|
-
return null;
|
|
5721
|
-
return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
|
|
5722
|
-
}
|
|
5723
|
-
function stripPycachePrefixRoot(head) {
|
|
5724
|
-
const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
|
|
5725
|
-
if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
|
|
5726
|
-
head = head.slice(2);
|
|
5727
|
-
}
|
|
5728
|
-
let start = 0;
|
|
5729
|
-
while (start < head.length && pycachePathSeparators.has(head[start])) {
|
|
5730
|
-
start++;
|
|
5731
|
-
}
|
|
5732
|
-
return head.slice(start);
|
|
5733
|
-
}
|
|
5734
|
-
function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
|
|
5735
|
-
const rel = derivePrefixPycRelPath(
|
|
5736
|
-
stripPycachePrefixRoot(srcAbsPath),
|
|
5737
|
-
pythonMajor,
|
|
5738
|
-
pythonMinor
|
|
5739
|
-
);
|
|
5740
|
-
if (!rel)
|
|
5741
|
-
return null;
|
|
5742
|
-
return (0, import_path6.join)(stagingDir, rel.replaceAll("/", import_path6.sep));
|
|
5743
|
-
}
|
|
5744
|
-
function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
|
|
5745
|
-
const rel = derivePrefixPycRelPath(
|
|
5746
|
-
stripPycachePrefixRoot(runtimeAbsPath),
|
|
5747
|
-
pythonMajor,
|
|
5748
|
-
pythonMinor
|
|
5749
|
-
);
|
|
5750
|
-
if (!rel)
|
|
5751
|
-
return null;
|
|
5752
|
-
return `${PYCACHE_PREFIX_DIR}/${rel}`;
|
|
5753
|
-
}
|
|
5754
|
-
var COMPILEALL_APP_EXCLUDED_DIRS = [
|
|
5755
|
-
".git",
|
|
5756
|
-
".vercel",
|
|
5757
|
-
".pnpm-store",
|
|
5758
|
-
"node_modules",
|
|
5759
|
-
".next",
|
|
5760
|
-
".nuxt",
|
|
5761
|
-
".venv",
|
|
5762
|
-
"venv",
|
|
5763
|
-
"__pycache__",
|
|
5764
|
-
".mypy_cache",
|
|
5765
|
-
".ruff_cache",
|
|
5766
|
-
"public"
|
|
5767
|
-
];
|
|
5768
|
-
function escapePythonRegex(value) {
|
|
5769
|
-
return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
5770
|
-
}
|
|
5771
|
-
function getCompileAllAppExcludeRegex(workPath) {
|
|
5772
|
-
const excludedDirs = COMPILEALL_APP_EXCLUDED_DIRS.map(escapePythonRegex).join("|");
|
|
5773
|
-
return `${escapePythonRegex(workPath)}[/\\\\](?:${excludedDirs})(?:[/\\\\]|$)`;
|
|
5774
|
-
}
|
|
5775
|
-
async function collectAppPrefixBytecodeFiles({
|
|
5776
|
-
stagingDir,
|
|
5777
|
-
workPath,
|
|
5778
|
-
files: appFiles,
|
|
5779
|
-
runtimeTaskRoot,
|
|
5780
|
-
pythonMajor,
|
|
5781
|
-
pythonMinor
|
|
5782
|
-
}) {
|
|
5783
|
-
const pending = [];
|
|
5784
|
-
for (const bundlePath of Object.keys(appFiles)) {
|
|
5785
|
-
if (!bundlePath.endsWith(".py"))
|
|
5786
|
-
continue;
|
|
5787
|
-
const stagedFsPath = deriveStagedPycFsPath(
|
|
5788
|
-
stagingDir,
|
|
5789
|
-
(0, import_path6.join)(workPath, bundlePath.replaceAll("/", import_path6.sep)),
|
|
5790
|
-
pythonMajor,
|
|
5791
|
-
pythonMinor
|
|
5792
|
-
);
|
|
5793
|
-
const pycBundlePath = derivePrefixPycBundlePath(
|
|
5794
|
-
`${runtimeTaskRoot}/${bundlePath}`,
|
|
5795
|
-
pythonMajor,
|
|
5796
|
-
pythonMinor
|
|
5797
|
-
);
|
|
5798
|
-
if (!stagedFsPath || !pycBundlePath)
|
|
5799
|
-
continue;
|
|
5800
|
-
pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
|
|
5801
|
-
}
|
|
5802
|
-
const results = await Promise.all(
|
|
5803
|
-
pending.map(async ({ bundlePath, srcFsPath }) => {
|
|
5804
|
-
try {
|
|
5805
|
-
const stats = await import_fs5.default.promises.stat(srcFsPath);
|
|
5806
|
-
return { bundlePath, srcFsPath, size: stats.size };
|
|
5807
|
-
} catch {
|
|
5808
|
-
return null;
|
|
5809
|
-
}
|
|
5810
|
-
})
|
|
5811
|
-
);
|
|
5812
|
-
const files = {};
|
|
5813
|
-
const perItemSizes = /* @__PURE__ */ new Map();
|
|
5814
|
-
let totalSize = 0;
|
|
5815
|
-
for (const result of results) {
|
|
5816
|
-
if (!result)
|
|
5817
|
-
continue;
|
|
5818
|
-
files[result.bundlePath] = new import_build_utils6.FileFsRef({
|
|
5819
|
-
fsPath: result.srcFsPath,
|
|
5820
|
-
size: result.size
|
|
5821
|
-
});
|
|
5822
|
-
perItemSizes.set(result.bundlePath, result.size);
|
|
5823
|
-
totalSize += result.size;
|
|
5824
|
-
}
|
|
5825
|
-
return { files, totalSize, perItemSizes };
|
|
5826
|
-
}
|
|
5827
|
-
async function collectAppBytecodeFiles({
|
|
5828
|
-
workPath,
|
|
5829
|
-
files: appFiles,
|
|
5830
|
-
pythonMajor,
|
|
5831
|
-
pythonMinor
|
|
5832
|
-
}) {
|
|
5833
|
-
const pending = [];
|
|
5834
|
-
for (const bundlePath of Object.keys(appFiles)) {
|
|
5835
|
-
const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
|
|
5836
|
-
if (!pycRel)
|
|
5837
|
-
continue;
|
|
5838
|
-
pending.push({
|
|
5839
|
-
bundlePath: pycRel,
|
|
5840
|
-
srcFsPath: (0, import_path6.join)(workPath, pycRel.replaceAll("/", import_path6.sep))
|
|
5841
|
-
});
|
|
5842
|
-
}
|
|
5843
|
-
const results = await Promise.all(
|
|
5844
|
-
pending.map(async ({ bundlePath, srcFsPath }) => {
|
|
5845
|
-
try {
|
|
5846
|
-
const stats = await import_fs5.default.promises.stat(srcFsPath);
|
|
5847
|
-
return { bundlePath, srcFsPath, size: stats.size };
|
|
5848
|
-
} catch {
|
|
5849
|
-
return null;
|
|
5850
|
-
}
|
|
5851
|
-
})
|
|
5852
|
-
);
|
|
5853
|
-
const files = {};
|
|
5854
|
-
const perItemSizes = /* @__PURE__ */ new Map();
|
|
5855
|
-
let totalSize = 0;
|
|
5856
|
-
for (const result of results) {
|
|
5857
|
-
if (!result)
|
|
5858
|
-
continue;
|
|
5859
|
-
files[result.bundlePath] = new import_build_utils6.FileFsRef({
|
|
5860
|
-
fsPath: result.srcFsPath,
|
|
5861
|
-
size: result.size
|
|
5862
|
-
});
|
|
5863
|
-
perItemSizes.set(result.bundlePath, result.size);
|
|
5864
|
-
totalSize += result.size;
|
|
5865
|
-
}
|
|
5866
|
-
return { files, totalSize, perItemSizes };
|
|
5867
|
-
}
|
|
5647
|
+
var import_build_utils6 = require("@vercel/build-utils");
|
|
5648
|
+
var import_python_analysis3 = require("@vercel/python-analysis");
|
|
5868
5649
|
|
|
5869
5650
|
// src/large-functions.ts
|
|
5870
5651
|
function isLargeFunctionsEnabled() {
|
|
@@ -5873,24 +5654,7 @@ function isLargeFunctionsEnabled() {
|
|
|
5873
5654
|
}
|
|
5874
5655
|
|
|
5875
5656
|
// src/dependency-externalizer.ts
|
|
5876
|
-
var readFile = (0, import_util.promisify)(
|
|
5877
|
-
var STRIP_BASENAMES = /* @__PURE__ */ new Set([
|
|
5878
|
-
"py.typed",
|
|
5879
|
-
"WHEEL",
|
|
5880
|
-
"INSTALLER",
|
|
5881
|
-
"direct_url.json"
|
|
5882
|
-
]);
|
|
5883
|
-
function shouldStripVendorFile(filePath) {
|
|
5884
|
-
const segments = filePath.split(import_path7.sep);
|
|
5885
|
-
if (segments.includes("__pycache__"))
|
|
5886
|
-
return true;
|
|
5887
|
-
const name = segments[segments.length - 1] ?? "";
|
|
5888
|
-
if (name.endsWith(".pyc") || name.endsWith(".pyi"))
|
|
5889
|
-
return true;
|
|
5890
|
-
if (STRIP_BASENAMES.has(name))
|
|
5891
|
-
return true;
|
|
5892
|
-
return false;
|
|
5893
|
-
}
|
|
5657
|
+
var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
|
|
5894
5658
|
var LAMBDA_SIZE_THRESHOLD_BYTES = 225 * 1024 * 1024;
|
|
5895
5659
|
var BYTECODE_FILL_MARGIN_BYTES = 5 * 1024 * 1024;
|
|
5896
5660
|
var BYTECODE_FILL_CEILING_BYTES = LAMBDA_SIZE_THRESHOLD_BYTES - BYTECODE_FILL_MARGIN_BYTES;
|
|
@@ -5898,24 +5662,20 @@ var LAMBDA_EPHEMERAL_STORAGE_BYTES = 500 * 1024 * 1024;
|
|
|
5898
5662
|
var EPHEMERAL_INSTALL_BUDGET_BYTES = LAMBDA_EPHEMERAL_STORAGE_BYTES - 50 * 1024 * 1024;
|
|
5899
5663
|
var RUNTIME_DEPS_DIR = "/tmp/_vc_deps";
|
|
5900
5664
|
var MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE = 5 * 1024 * 1024 * 1024;
|
|
5665
|
+
var LARGE_FUNCTION_FILL_CEILING_BYTES = MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE - BYTECODE_FILL_MARGIN_BYTES;
|
|
5901
5666
|
var BUNDLING_DOCS_LINK = "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled";
|
|
5902
5667
|
var PythonDependencyExternalizer = class {
|
|
5903
5668
|
constructor(options) {
|
|
5904
|
-
// Populated by analyze()
|
|
5905
|
-
this.sitePackageDirs = [];
|
|
5906
|
-
this.distributions = /* @__PURE__ */ new Map();
|
|
5907
5669
|
this.allVendorFiles = {};
|
|
5908
5670
|
this.totalBundleSize = 0;
|
|
5909
5671
|
this.analyzed = false;
|
|
5910
|
-
this.
|
|
5672
|
+
this.installedDistributions = options.installedDistributions;
|
|
5911
5673
|
this.vendorDir = options.vendorDir;
|
|
5912
5674
|
this.workPath = options.workPath;
|
|
5913
5675
|
this.uvLockPath = options.uvLockPath;
|
|
5914
5676
|
this.uvProjectDir = options.uvProjectDir;
|
|
5915
5677
|
this.projectName = options.projectName;
|
|
5916
|
-
this.
|
|
5917
|
-
this.pythonMinor = options.pythonMinor;
|
|
5918
|
-
this.pythonPath = options.pythonPath;
|
|
5678
|
+
this.pythonVersion = options.pythonVersion;
|
|
5919
5679
|
this.hasCustomCommand = options.hasCustomCommand;
|
|
5920
5680
|
this.alwaysBundlePackages = options.alwaysBundlePackages ?? [];
|
|
5921
5681
|
}
|
|
@@ -5937,17 +5697,7 @@ var PythonDependencyExternalizer = class {
|
|
|
5937
5697
|
* Must be called before generateBundle().
|
|
5938
5698
|
*/
|
|
5939
5699
|
async analyze(files, options = {}) {
|
|
5940
|
-
this.
|
|
5941
|
-
this.distributions = /* @__PURE__ */ new Map();
|
|
5942
|
-
for (const dir of this.sitePackageDirs) {
|
|
5943
|
-
try {
|
|
5944
|
-
await import_fs6.default.promises.access(dir);
|
|
5945
|
-
} catch {
|
|
5946
|
-
continue;
|
|
5947
|
-
}
|
|
5948
|
-
this.distributions.set(dir, await (0, import_python_analysis3.scanDistributions)(dir));
|
|
5949
|
-
}
|
|
5950
|
-
this.allVendorFiles = await this.mirrorPackagesIntoVendor({
|
|
5700
|
+
this.allVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
|
|
5951
5701
|
vendorDirName: this.vendorDir
|
|
5952
5702
|
});
|
|
5953
5703
|
const tempFilesForSizing = { ...files };
|
|
@@ -5957,7 +5707,7 @@ var PythonDependencyExternalizer = class {
|
|
|
5957
5707
|
this.totalBundleSize = await calculateBundleSize(tempFilesForSizing);
|
|
5958
5708
|
this.analyzed = true;
|
|
5959
5709
|
const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
|
|
5960
|
-
(0,
|
|
5710
|
+
(0, import_build_utils6.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
|
|
5961
5711
|
const runtimeInstallEnabled = this.shouldEnableRuntimeInstall();
|
|
5962
5712
|
const largeFunctionsEnabled = isLargeFunctionsEnabled();
|
|
5963
5713
|
options.onSized?.({
|
|
@@ -5966,7 +5716,7 @@ var PythonDependencyExternalizer = class {
|
|
|
5966
5716
|
});
|
|
5967
5717
|
if (this.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && this.hasCustomCommand && !largeFunctionsEnabled) {
|
|
5968
5718
|
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
5969
|
-
throw new
|
|
5719
|
+
throw new import_build_utils6.NowBuildError({
|
|
5970
5720
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
5971
5721
|
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
|
|
5972
5722
|
|
|
@@ -5981,7 +5731,7 @@ function bundle size automatically. To fix this, you can:
|
|
|
5981
5731
|
}
|
|
5982
5732
|
if (largeFunctionsEnabled && this.totalBundleSize >= MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE) {
|
|
5983
5733
|
const limitMB = (MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE / (1024 * 1024)).toFixed(0);
|
|
5984
|
-
throw new
|
|
5734
|
+
throw new import_build_utils6.NowBuildError({
|
|
5985
5735
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
5986
5736
|
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the extended function size limit (${limitMB} MB).
|
|
5987
5737
|
|
|
@@ -6027,7 +5777,7 @@ application into smaller functions.`,
|
|
|
6027
5777
|
const limitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(
|
|
6028
5778
|
0
|
|
6029
5779
|
);
|
|
6030
|
-
throw new
|
|
5780
|
+
throw new import_build_utils6.NowBuildError({
|
|
6031
5781
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
6032
5782
|
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
|
|
6033
5783
|
|
|
@@ -6037,15 +5787,15 @@ smaller functions.`,
|
|
|
6037
5787
|
action: "Learn More"
|
|
6038
5788
|
});
|
|
6039
5789
|
}
|
|
6040
|
-
const relLockPath = (0,
|
|
5790
|
+
const relLockPath = (0, import_path6.relative)(this.workPath, this.uvLockPath);
|
|
6041
5791
|
let lockContent;
|
|
6042
5792
|
try {
|
|
6043
5793
|
lockContent = await readFile(this.uvLockPath, "utf8");
|
|
6044
5794
|
} catch (error) {
|
|
6045
|
-
(0,
|
|
5795
|
+
(0, import_build_utils6.debug)(
|
|
6046
5796
|
`Failed to read uv.lock at ${this.uvLockPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
6047
5797
|
);
|
|
6048
|
-
throw new
|
|
5798
|
+
throw new import_build_utils6.NowBuildError({
|
|
6049
5799
|
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
6050
5800
|
message: `Failed to read the uv.lock file at "${relLockPath}".`
|
|
6051
5801
|
});
|
|
@@ -6056,12 +5806,12 @@ smaller functions.`,
|
|
|
6056
5806
|
} catch (error) {
|
|
6057
5807
|
if (error instanceof import_python_analysis3.PythonAnalysisError) {
|
|
6058
5808
|
if (error.fileContent) {
|
|
6059
|
-
(0,
|
|
5809
|
+
(0, import_build_utils6.debug)(
|
|
6060
5810
|
`Failed to parse "${error.path}". File content:
|
|
6061
5811
|
${error.fileContent}`
|
|
6062
5812
|
);
|
|
6063
5813
|
}
|
|
6064
|
-
throw new
|
|
5814
|
+
throw new import_build_utils6.NowBuildError({
|
|
6065
5815
|
code: error.code,
|
|
6066
5816
|
message: error.message
|
|
6067
5817
|
});
|
|
@@ -6071,7 +5821,7 @@ ${error.fileContent}`
|
|
|
6071
5821
|
const excludePackages = [];
|
|
6072
5822
|
if (this.projectName) {
|
|
6073
5823
|
excludePackages.push(this.projectName);
|
|
6074
|
-
(0,
|
|
5824
|
+
(0, import_build_utils6.debug)(
|
|
6075
5825
|
`Excluding project package "${this.projectName}" from runtime installation`
|
|
6076
5826
|
);
|
|
6077
5827
|
}
|
|
@@ -6079,7 +5829,7 @@ ${error.fileContent}`
|
|
|
6079
5829
|
lockFile,
|
|
6080
5830
|
excludePackages
|
|
6081
5831
|
});
|
|
6082
|
-
(0,
|
|
5832
|
+
(0, import_build_utils6.debug)(
|
|
6083
5833
|
`Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
|
|
6084
5834
|
);
|
|
6085
5835
|
const forceBundledDueToWheels = await this.findPackagesWithoutCompatibleWheels(
|
|
@@ -6101,7 +5851,7 @@ ${error.fileContent}`
|
|
|
6101
5851
|
if (largeFunctionsEnabled) {
|
|
6102
5852
|
return this.bundleAllForHive(files);
|
|
6103
5853
|
}
|
|
6104
|
-
throw new
|
|
5854
|
+
throw new import_build_utils6.NowBuildError({
|
|
6105
5855
|
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
6106
5856
|
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size and
|
|
6107
5857
|
can't be optimized automatically because some dependencies don't
|
|
@@ -6112,7 +5862,7 @@ To fix this, either:
|
|
|
6112
5862
|
2. Replace the packages that don't provide a pre-built wheel.`
|
|
6113
5863
|
});
|
|
6114
5864
|
}
|
|
6115
|
-
const packageSizes = await this.calculatePerPackageSizes();
|
|
5865
|
+
const packageSizes = await this.installedDistributions.calculatePerPackageSizes();
|
|
6116
5866
|
const alwaysBundled = [
|
|
6117
5867
|
...classification.privatePackages,
|
|
6118
5868
|
"vercel-runtime",
|
|
@@ -6120,7 +5870,7 @@ To fix this, either:
|
|
|
6120
5870
|
...this.alwaysBundlePackages,
|
|
6121
5871
|
...forceBundledDueToWheels
|
|
6122
5872
|
];
|
|
6123
|
-
const alwaysBundledFiles = await this.mirrorPackagesIntoVendor({
|
|
5873
|
+
const alwaysBundledFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
|
|
6124
5874
|
vendorDirName: this.vendorDir,
|
|
6125
5875
|
includePackages: alwaysBundled
|
|
6126
5876
|
});
|
|
@@ -6132,26 +5882,26 @@ To fix this, either:
|
|
|
6132
5882
|
let runtimeToolingOverhead = 0;
|
|
6133
5883
|
try {
|
|
6134
5884
|
const uvBinaryPath = await this.resolveUvBinaryForBundling();
|
|
6135
|
-
const uvStats = await
|
|
5885
|
+
const uvStats = await import_fs5.default.promises.stat(uvBinaryPath);
|
|
6136
5886
|
runtimeToolingOverhead = uvStats.size;
|
|
6137
5887
|
} catch {
|
|
6138
5888
|
runtimeToolingOverhead = 50 * 1024 * 1024;
|
|
6139
5889
|
}
|
|
6140
5890
|
runtimeToolingOverhead += 4 * 1024;
|
|
6141
|
-
const projectDirRel = (0,
|
|
6142
|
-
const uvLockRel = (0,
|
|
5891
|
+
const projectDirRel = (0, import_path6.relative)(this.workPath, this.uvProjectDir);
|
|
5892
|
+
const uvLockRel = (0, import_path6.relative)(this.workPath, this.uvLockPath);
|
|
6143
5893
|
const isOutsideWorkPath = projectDirRel.startsWith("..") || uvLockRel.startsWith("..");
|
|
6144
5894
|
if (isOutsideWorkPath) {
|
|
6145
|
-
const pyprojectPath = (0,
|
|
6146
|
-
const pyprojectStats = await
|
|
6147
|
-
const uvLockStats = await
|
|
5895
|
+
const pyprojectPath = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
|
|
5896
|
+
const pyprojectStats = await import_fs5.default.promises.stat(pyprojectPath).catch(() => null);
|
|
5897
|
+
const uvLockStats = await import_fs5.default.promises.stat(this.uvLockPath).catch(() => null);
|
|
6148
5898
|
if (pyprojectStats)
|
|
6149
5899
|
runtimeToolingOverhead += pyprojectStats.size;
|
|
6150
5900
|
if (uvLockStats)
|
|
6151
5901
|
runtimeToolingOverhead += uvLockStats.size;
|
|
6152
5902
|
}
|
|
6153
5903
|
const remainingCapacity = LAMBDA_SIZE_THRESHOLD_BYTES - fixedOverhead - runtimeToolingOverhead;
|
|
6154
|
-
(0,
|
|
5904
|
+
(0, import_build_utils6.debug)(
|
|
6155
5905
|
`Fixed overhead: ${(fixedOverhead / (1024 * 1024)).toFixed(2)} MB, runtime tooling: ${(runtimeToolingOverhead / (1024 * 1024)).toFixed(2)} MB, remaining capacity for public packages: ${(remainingCapacity / (1024 * 1024)).toFixed(2)} MB`
|
|
6156
5906
|
);
|
|
6157
5907
|
if (largeFunctionsEnabled && remainingCapacity < 0) {
|
|
@@ -6174,7 +5924,7 @@ To fix this, either:
|
|
|
6174
5924
|
bytecodeFirst: options.bytecodeFirst ?? false
|
|
6175
5925
|
});
|
|
6176
5926
|
if (options.bytecodeFirst && packingMode === "knapsack") {
|
|
6177
|
-
(0,
|
|
5927
|
+
(0, import_build_utils6.debug)(
|
|
6178
5928
|
`bytecode-first packing disabled: the public package set exceeds the ephemeral install budget (${(EPHEMERAL_INSTALL_BUDGET_BYTES / (1024 * 1024)).toFixed(2)} MB); falling back to knapsack packing`
|
|
6179
5929
|
);
|
|
6180
5930
|
}
|
|
@@ -6183,7 +5933,7 @@ To fix this, either:
|
|
|
6183
5933
|
(name) => !bundledPublicSet.has((0, import_python_analysis3.normalizePackageName)(name))
|
|
6184
5934
|
);
|
|
6185
5935
|
const allBundledPackages = [...alwaysBundled, ...bundledPublic];
|
|
6186
|
-
const selectedVendorFiles = await this.mirrorPackagesIntoVendor({
|
|
5936
|
+
const selectedVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
|
|
6187
5937
|
vendorDirName: this.vendorDir,
|
|
6188
5938
|
includePackages: allBundledPackages
|
|
6189
5939
|
});
|
|
@@ -6197,11 +5947,11 @@ To fix this, either:
|
|
|
6197
5947
|
...forceBundledDueToWheels
|
|
6198
5948
|
];
|
|
6199
5949
|
if (isOutsideWorkPath) {
|
|
6200
|
-
const srcPyproject = (0,
|
|
6201
|
-
files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new
|
|
5950
|
+
const srcPyproject = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
|
|
5951
|
+
files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils6.FileFsRef({
|
|
6202
5952
|
fsPath: srcPyproject
|
|
6203
5953
|
});
|
|
6204
|
-
files[`${UV_BUNDLE_DIR}/uv.lock`] = new
|
|
5954
|
+
files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils6.FileFsRef({
|
|
6205
5955
|
fsPath: this.uvLockPath
|
|
6206
5956
|
});
|
|
6207
5957
|
}
|
|
@@ -6209,27 +5959,27 @@ To fix this, either:
|
|
|
6209
5959
|
projectDir: isOutsideWorkPath ? UV_BUNDLE_DIR : projectDirRel,
|
|
6210
5960
|
bundledPackages: bundledPackagesForConfig
|
|
6211
5961
|
});
|
|
6212
|
-
files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new
|
|
5962
|
+
files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils6.FileBlob({
|
|
6213
5963
|
data: runtimeConfigData
|
|
6214
5964
|
});
|
|
6215
5965
|
try {
|
|
6216
5966
|
const uvBinaryPath = await this.resolveUvBinaryForBundling();
|
|
6217
|
-
const uvBundleDir = (0,
|
|
6218
|
-
const uvLocalPath = (0,
|
|
6219
|
-
await
|
|
6220
|
-
await
|
|
6221
|
-
await
|
|
5967
|
+
const uvBundleDir = (0, import_path6.join)(this.workPath, UV_BUNDLE_DIR);
|
|
5968
|
+
const uvLocalPath = (0, import_path6.join)(uvBundleDir, "uv");
|
|
5969
|
+
await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
|
|
5970
|
+
await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
|
|
5971
|
+
await import_fs5.default.promises.chmod(uvLocalPath, 493);
|
|
6222
5972
|
const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
|
|
6223
|
-
files[uvBundlePath] = new
|
|
5973
|
+
files[uvBundlePath] = new import_build_utils6.FileFsRef({
|
|
6224
5974
|
fsPath: uvLocalPath,
|
|
6225
5975
|
mode: 33261
|
|
6226
5976
|
});
|
|
6227
|
-
(0,
|
|
5977
|
+
(0, import_build_utils6.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
|
|
6228
5978
|
} catch (err) {
|
|
6229
|
-
(0,
|
|
5979
|
+
(0, import_build_utils6.debug)(
|
|
6230
5980
|
`Failed to bundle uv binary: ${err instanceof Error ? err.message : String(err)}`
|
|
6231
5981
|
);
|
|
6232
|
-
throw new
|
|
5982
|
+
throw new import_build_utils6.NowBuildError({
|
|
6233
5983
|
code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
|
|
6234
5984
|
message: "Failed to prepare dependency tooling."
|
|
6235
5985
|
});
|
|
@@ -6241,7 +5991,7 @@ To fix this, either:
|
|
|
6241
5991
|
}
|
|
6242
5992
|
const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
|
|
6243
5993
|
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
6244
|
-
throw new
|
|
5994
|
+
throw new import_build_utils6.NowBuildError({
|
|
6245
5995
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
6246
5996
|
message: `Total bundle size (${finalSizeMB} MB) exceeds the maximum function size (${limitMB} MB) even after
|
|
6247
5997
|
optimizing dependencies.
|
|
@@ -6278,7 +6028,7 @@ functions.`,
|
|
|
6278
6028
|
for (const [p, f] of Object.entries(this.allVendorFiles)) {
|
|
6279
6029
|
files[p] = f;
|
|
6280
6030
|
}
|
|
6281
|
-
(0,
|
|
6031
|
+
(0, import_build_utils6.debug)("Bundling all dependencies for the large functions path.");
|
|
6282
6032
|
return { fellBackToFullBundle: true };
|
|
6283
6033
|
}
|
|
6284
6034
|
/**
|
|
@@ -6293,15 +6043,15 @@ functions.`,
|
|
|
6293
6043
|
*/
|
|
6294
6044
|
async findPackagesWithoutCompatibleWheels(lockFile, publicPackageNames) {
|
|
6295
6045
|
const platform = detectTargetPlatform();
|
|
6296
|
-
if (this.
|
|
6297
|
-
(0,
|
|
6046
|
+
if (this.pythonVersion.major === void 0 || this.pythonVersion.minor === void 0) {
|
|
6047
|
+
(0, import_build_utils6.debug)("Skipping wheel compatibility check: dev mode");
|
|
6298
6048
|
return [];
|
|
6299
6049
|
}
|
|
6300
6050
|
const reachable = await getPackagesReachableOnPlatform(
|
|
6301
6051
|
lockFile,
|
|
6302
6052
|
this.projectName,
|
|
6303
|
-
this.
|
|
6304
|
-
this.
|
|
6053
|
+
this.pythonVersion.major,
|
|
6054
|
+
this.pythonVersion.minor,
|
|
6305
6055
|
platform.sysPlatform,
|
|
6306
6056
|
platform.archName
|
|
6307
6057
|
);
|
|
@@ -6309,7 +6059,7 @@ functions.`,
|
|
|
6309
6059
|
(name) => reachable.has((0, import_python_analysis3.normalizePackageName)(name))
|
|
6310
6060
|
) : publicPackageNames;
|
|
6311
6061
|
if (relevantPackages.length < publicPackageNames.length) {
|
|
6312
|
-
(0,
|
|
6062
|
+
(0, import_build_utils6.debug)(
|
|
6313
6063
|
`Skipping wheel check for ${publicPackageNames.length - relevantPackages.length} package(s) not reachable on the target platform`
|
|
6314
6064
|
);
|
|
6315
6065
|
}
|
|
@@ -6337,8 +6087,8 @@ functions.`,
|
|
|
6337
6087
|
try {
|
|
6338
6088
|
const compatible = await (0, import_python_analysis3.isWheelCompatible)(
|
|
6339
6089
|
filename,
|
|
6340
|
-
this.
|
|
6341
|
-
this.
|
|
6090
|
+
this.pythonVersion.major,
|
|
6091
|
+
this.pythonVersion.minor,
|
|
6342
6092
|
platform.osName,
|
|
6343
6093
|
platform.archName,
|
|
6344
6094
|
platform.osMajor,
|
|
@@ -6349,7 +6099,7 @@ functions.`,
|
|
|
6349
6099
|
break;
|
|
6350
6100
|
}
|
|
6351
6101
|
} catch (err) {
|
|
6352
|
-
(0,
|
|
6102
|
+
(0, import_build_utils6.debug)(
|
|
6353
6103
|
`Failed to check wheel compatibility for ${filename}: ${err instanceof Error ? err.message : String(err)}`
|
|
6354
6104
|
);
|
|
6355
6105
|
}
|
|
@@ -6363,301 +6113,12 @@ functions.`,
|
|
|
6363
6113
|
/** Resolve the uv binary for bundling (host binary on build image, downloaded on local). */
|
|
6364
6114
|
async resolveUvBinaryForBundling() {
|
|
6365
6115
|
if (process.env.VERCEL_BUILD_IMAGE) {
|
|
6366
|
-
return getUvBinaryForBundling(this.pythonPath);
|
|
6116
|
+
return getUvBinaryForBundling(this.pythonVersion.pythonPath);
|
|
6367
6117
|
}
|
|
6368
6118
|
return downloadUvBinaryForTarget(
|
|
6369
|
-
(0,
|
|
6119
|
+
(0, import_path6.join)(this.workPath, ".vercel", "python", "cache")
|
|
6370
6120
|
);
|
|
6371
6121
|
}
|
|
6372
|
-
/**
|
|
6373
|
-
* Mirror packages from site-packages into the _vendor directory.
|
|
6374
|
-
*
|
|
6375
|
-
* When `includePackages` is provided, only distributions whose normalized
|
|
6376
|
-
* name is in the list are included. When omitted, every distribution is
|
|
6377
|
-
* included.
|
|
6378
|
-
*
|
|
6379
|
-
* Reads `this.sitePackageDirs` and `this.distributions` which are
|
|
6380
|
-
* resolved once at the start of `analyze()`.
|
|
6381
|
-
*/
|
|
6382
|
-
async mirrorPackagesIntoVendor({
|
|
6383
|
-
vendorDirName,
|
|
6384
|
-
includePackages
|
|
6385
|
-
}) {
|
|
6386
|
-
const vendorFiles = {};
|
|
6387
|
-
if (includePackages && includePackages.length === 0) {
|
|
6388
|
-
return vendorFiles;
|
|
6389
|
-
}
|
|
6390
|
-
const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
|
|
6391
|
-
const pending = [];
|
|
6392
|
-
for (const dir of this.sitePackageDirs) {
|
|
6393
|
-
const dirDistributions = this.distributions.get(dir);
|
|
6394
|
-
if (!dirDistributions)
|
|
6395
|
-
continue;
|
|
6396
|
-
const resolvedDir = (0, import_path7.resolve)(dir);
|
|
6397
|
-
const dirPrefix = resolvedDir + import_path7.sep;
|
|
6398
|
-
for (const [name, dist] of dirDistributions) {
|
|
6399
|
-
if (includeSet && !includeSet.has(name))
|
|
6400
|
-
continue;
|
|
6401
|
-
for (const { path: rawPath, size: recordSize } of dist.files) {
|
|
6402
|
-
const filePath = rawPath.replaceAll("/", import_path7.sep);
|
|
6403
|
-
if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
|
|
6404
|
-
continue;
|
|
6405
|
-
}
|
|
6406
|
-
if (shouldStripVendorFile(filePath)) {
|
|
6407
|
-
continue;
|
|
6408
|
-
}
|
|
6409
|
-
const srcFsPath = (0, import_path7.join)(dir, filePath);
|
|
6410
|
-
const bundlePath = (0, import_path7.join)(vendorDirName, filePath).replace(/\\/g, "/");
|
|
6411
|
-
pending.push({
|
|
6412
|
-
bundlePath,
|
|
6413
|
-
srcFsPath,
|
|
6414
|
-
// RECORD sizes are bigint; convert to number for FileFsRef.
|
|
6415
|
-
recordSize: recordSize !== void 0 && recordSize !== null ? Number(recordSize) : void 0
|
|
6416
|
-
});
|
|
6417
|
-
}
|
|
6418
|
-
}
|
|
6419
|
-
}
|
|
6420
|
-
const results = await Promise.all(
|
|
6421
|
-
pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
|
|
6422
|
-
if (recordSize !== void 0) {
|
|
6423
|
-
try {
|
|
6424
|
-
await import_fs6.default.promises.access(srcFsPath);
|
|
6425
|
-
return { bundlePath, srcFsPath, size: recordSize };
|
|
6426
|
-
} catch {
|
|
6427
|
-
return null;
|
|
6428
|
-
}
|
|
6429
|
-
} else {
|
|
6430
|
-
try {
|
|
6431
|
-
const stats = await import_fs6.default.promises.stat(srcFsPath);
|
|
6432
|
-
return { bundlePath, srcFsPath, size: stats.size };
|
|
6433
|
-
} catch {
|
|
6434
|
-
return null;
|
|
6435
|
-
}
|
|
6436
|
-
}
|
|
6437
|
-
})
|
|
6438
|
-
);
|
|
6439
|
-
for (const result of results) {
|
|
6440
|
-
if (result) {
|
|
6441
|
-
vendorFiles[result.bundlePath] = new import_build_utils7.FileFsRef({
|
|
6442
|
-
fsPath: result.srcFsPath,
|
|
6443
|
-
size: result.size
|
|
6444
|
-
});
|
|
6445
|
-
}
|
|
6446
|
-
}
|
|
6447
|
-
(0, import_build_utils7.debug)(
|
|
6448
|
-
`Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
6449
|
-
);
|
|
6450
|
-
return vendorFiles;
|
|
6451
|
-
}
|
|
6452
|
-
/**
|
|
6453
|
-
* Calculate the uncompressed size of each installed distribution.
|
|
6454
|
-
*
|
|
6455
|
-
* Returns a map of normalized package name to total size in bytes.
|
|
6456
|
-
* Uses RECORD sizes when available, falling back to stat for files
|
|
6457
|
-
* without a recorded size. All stat calls run in parallel.
|
|
6458
|
-
*/
|
|
6459
|
-
async calculatePerPackageSizes() {
|
|
6460
|
-
const sizes = /* @__PURE__ */ new Map();
|
|
6461
|
-
for (const dir of this.sitePackageDirs) {
|
|
6462
|
-
const dirDistributions = this.distributions.get(dir);
|
|
6463
|
-
if (!dirDistributions)
|
|
6464
|
-
continue;
|
|
6465
|
-
const resolvedDir = (0, import_path7.resolve)(dir);
|
|
6466
|
-
const dirPrefix = resolvedDir + import_path7.sep;
|
|
6467
|
-
for (const [name, dist] of dirDistributions) {
|
|
6468
|
-
let knownSize = 0;
|
|
6469
|
-
const statPromises = [];
|
|
6470
|
-
for (const { path: rawPath, size: recordSize } of dist.files) {
|
|
6471
|
-
const filePath = rawPath.replaceAll("/", import_path7.sep);
|
|
6472
|
-
if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
|
|
6473
|
-
continue;
|
|
6474
|
-
}
|
|
6475
|
-
if (shouldStripVendorFile(filePath)) {
|
|
6476
|
-
continue;
|
|
6477
|
-
}
|
|
6478
|
-
if (recordSize !== void 0 && recordSize !== null) {
|
|
6479
|
-
knownSize += Number(recordSize);
|
|
6480
|
-
} else {
|
|
6481
|
-
statPromises.push(
|
|
6482
|
-
import_fs6.default.promises.stat((0, import_path7.join)(dir, filePath)).then((stats) => stats.size).catch(() => 0)
|
|
6483
|
-
);
|
|
6484
|
-
}
|
|
6485
|
-
}
|
|
6486
|
-
const statSizes = await Promise.all(statPromises);
|
|
6487
|
-
let totalSize = knownSize;
|
|
6488
|
-
for (const s of statSizes) {
|
|
6489
|
-
totalSize += s;
|
|
6490
|
-
}
|
|
6491
|
-
sizes.set(name, totalSize);
|
|
6492
|
-
}
|
|
6493
|
-
}
|
|
6494
|
-
return sizes;
|
|
6495
|
-
}
|
|
6496
|
-
/**
|
|
6497
|
-
* Collect pre-compiled `.pyc` bytecode files for vendor packages.
|
|
6498
|
-
*
|
|
6499
|
-
* For each `.py` file listed in a package's RECORD, derives the expected
|
|
6500
|
-
* `__pycache__/*.cpython-XY.pyc` path and checks whether it exists on
|
|
6501
|
-
* disk (i.e. whether `compileall` produced it). Files that do not exist
|
|
6502
|
-
* are silently skipped.
|
|
6503
|
-
*
|
|
6504
|
-
* Must be called after `analyze()` which populates `sitePackageDirs` and
|
|
6505
|
-
* `distributions`.
|
|
6506
|
-
*/
|
|
6507
|
-
async collectBytecodeFiles({
|
|
6508
|
-
vendorDirName,
|
|
6509
|
-
includePackages
|
|
6510
|
-
}) {
|
|
6511
|
-
if (!this.sitePackageDirs || !this.distributions) {
|
|
6512
|
-
throw new Error("collectBytecodeFiles() must be called after analyze()");
|
|
6513
|
-
}
|
|
6514
|
-
if (this.pythonMajor == null || this.pythonMinor == null) {
|
|
6515
|
-
return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
|
|
6516
|
-
}
|
|
6517
|
-
const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
|
|
6518
|
-
const pending = [];
|
|
6519
|
-
for (const dir of this.sitePackageDirs) {
|
|
6520
|
-
const dirDistributions = this.distributions.get(dir);
|
|
6521
|
-
if (!dirDistributions)
|
|
6522
|
-
continue;
|
|
6523
|
-
for (const [name, dist] of dirDistributions) {
|
|
6524
|
-
if (includeSet && !includeSet.has(name))
|
|
6525
|
-
continue;
|
|
6526
|
-
for (const { path: rawPath } of dist.files) {
|
|
6527
|
-
const pycRel = derivePycPath(
|
|
6528
|
-
rawPath,
|
|
6529
|
-
this.pythonMajor,
|
|
6530
|
-
this.pythonMinor
|
|
6531
|
-
);
|
|
6532
|
-
if (!pycRel)
|
|
6533
|
-
continue;
|
|
6534
|
-
const pycFilePath = pycRel.replaceAll("/", import_path7.sep);
|
|
6535
|
-
const srcFsPath = (0, import_path7.join)(dir, pycFilePath);
|
|
6536
|
-
const bundlePath = (0, import_path7.join)(vendorDirName, pycFilePath).replace(
|
|
6537
|
-
/\\/g,
|
|
6538
|
-
"/"
|
|
6539
|
-
);
|
|
6540
|
-
pending.push({ bundlePath, srcFsPath, packageName: name });
|
|
6541
|
-
}
|
|
6542
|
-
}
|
|
6543
|
-
}
|
|
6544
|
-
const results = await Promise.all(
|
|
6545
|
-
pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
|
|
6546
|
-
try {
|
|
6547
|
-
const stats = await import_fs6.default.promises.stat(srcFsPath);
|
|
6548
|
-
return { bundlePath, srcFsPath, size: stats.size, packageName };
|
|
6549
|
-
} catch {
|
|
6550
|
-
return null;
|
|
6551
|
-
}
|
|
6552
|
-
})
|
|
6553
|
-
);
|
|
6554
|
-
const files = {};
|
|
6555
|
-
let totalSize = 0;
|
|
6556
|
-
const perItemSizes = /* @__PURE__ */ new Map();
|
|
6557
|
-
for (const result of results) {
|
|
6558
|
-
if (!result)
|
|
6559
|
-
continue;
|
|
6560
|
-
files[result.bundlePath] = new import_build_utils7.FileFsRef({
|
|
6561
|
-
fsPath: result.srcFsPath,
|
|
6562
|
-
size: result.size
|
|
6563
|
-
});
|
|
6564
|
-
totalSize += result.size;
|
|
6565
|
-
perItemSizes.set(
|
|
6566
|
-
result.packageName,
|
|
6567
|
-
(perItemSizes.get(result.packageName) ?? 0) + result.size
|
|
6568
|
-
);
|
|
6569
|
-
}
|
|
6570
|
-
(0, import_build_utils7.debug)(
|
|
6571
|
-
`Collected ${Object.keys(files).length} bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
6572
|
-
);
|
|
6573
|
-
return { files, totalSize, perItemSizes };
|
|
6574
|
-
}
|
|
6575
|
-
/**
|
|
6576
|
-
* Collect staged prefix `.pyc` files for vendor packages, keyed under
|
|
6577
|
-
* `_vc_pycache/<runtimeRoot>/...` (`runtimeRoot` = `/var/task/_vendor`
|
|
6578
|
-
* for bundled packages, the /tmp site-packages dir for externalized
|
|
6579
|
-
* ones). Missing staged files are silently skipped. Must be called after
|
|
6580
|
-
* `analyze()`.
|
|
6581
|
-
*/
|
|
6582
|
-
async collectPrefixBytecodeFiles({
|
|
6583
|
-
stagingDir,
|
|
6584
|
-
runtimeRoot,
|
|
6585
|
-
includePackages
|
|
6586
|
-
}) {
|
|
6587
|
-
if (!this.sitePackageDirs || !this.distributions) {
|
|
6588
|
-
throw new Error(
|
|
6589
|
-
"collectPrefixBytecodeFiles() must be called after analyze()"
|
|
6590
|
-
);
|
|
6591
|
-
}
|
|
6592
|
-
if (this.pythonMajor == null || this.pythonMinor == null) {
|
|
6593
|
-
return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
|
|
6594
|
-
}
|
|
6595
|
-
const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
|
|
6596
|
-
const pending = [];
|
|
6597
|
-
for (const dir of this.sitePackageDirs) {
|
|
6598
|
-
const dirDistributions = this.distributions.get(dir);
|
|
6599
|
-
if (!dirDistributions)
|
|
6600
|
-
continue;
|
|
6601
|
-
const resolvedDir = (0, import_path7.resolve)(dir);
|
|
6602
|
-
const dirPrefix = resolvedDir + import_path7.sep;
|
|
6603
|
-
for (const [name, dist] of dirDistributions) {
|
|
6604
|
-
if (includeSet && !includeSet.has(name))
|
|
6605
|
-
continue;
|
|
6606
|
-
for (const { path: rawPath } of dist.files) {
|
|
6607
|
-
if (!rawPath.endsWith(".py"))
|
|
6608
|
-
continue;
|
|
6609
|
-
const filePath = rawPath.replaceAll("/", import_path7.sep);
|
|
6610
|
-
if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
|
|
6611
|
-
continue;
|
|
6612
|
-
}
|
|
6613
|
-
const srcFsPath = deriveStagedPycFsPath(
|
|
6614
|
-
stagingDir,
|
|
6615
|
-
(0, import_path7.join)(dir, filePath),
|
|
6616
|
-
this.pythonMajor,
|
|
6617
|
-
this.pythonMinor
|
|
6618
|
-
);
|
|
6619
|
-
const bundlePath = derivePrefixPycBundlePath(
|
|
6620
|
-
`${runtimeRoot}/${rawPath}`,
|
|
6621
|
-
this.pythonMajor,
|
|
6622
|
-
this.pythonMinor
|
|
6623
|
-
);
|
|
6624
|
-
if (!srcFsPath || !bundlePath)
|
|
6625
|
-
continue;
|
|
6626
|
-
pending.push({ bundlePath, srcFsPath, packageName: name });
|
|
6627
|
-
}
|
|
6628
|
-
}
|
|
6629
|
-
}
|
|
6630
|
-
const results = await Promise.all(
|
|
6631
|
-
pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
|
|
6632
|
-
try {
|
|
6633
|
-
const stats = await import_fs6.default.promises.stat(srcFsPath);
|
|
6634
|
-
return { bundlePath, srcFsPath, size: stats.size, packageName };
|
|
6635
|
-
} catch {
|
|
6636
|
-
return null;
|
|
6637
|
-
}
|
|
6638
|
-
})
|
|
6639
|
-
);
|
|
6640
|
-
const files = {};
|
|
6641
|
-
let totalSize = 0;
|
|
6642
|
-
const perItemSizes = /* @__PURE__ */ new Map();
|
|
6643
|
-
for (const result of results) {
|
|
6644
|
-
if (!result)
|
|
6645
|
-
continue;
|
|
6646
|
-
files[result.bundlePath] = new import_build_utils7.FileFsRef({
|
|
6647
|
-
fsPath: result.srcFsPath,
|
|
6648
|
-
size: result.size
|
|
6649
|
-
});
|
|
6650
|
-
totalSize += result.size;
|
|
6651
|
-
perItemSizes.set(
|
|
6652
|
-
result.packageName,
|
|
6653
|
-
(perItemSizes.get(result.packageName) ?? 0) + result.size
|
|
6654
|
-
);
|
|
6655
|
-
}
|
|
6656
|
-
(0, import_build_utils7.debug)(
|
|
6657
|
-
`Collected ${Object.keys(files).length} prefix bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
6658
|
-
);
|
|
6659
|
-
return { files, totalSize, perItemSizes };
|
|
6660
|
-
}
|
|
6661
6122
|
};
|
|
6662
6123
|
async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor, pythonMinor, sysPlatform, platformMachine) {
|
|
6663
6124
|
if (!projectName)
|
|
@@ -6690,13 +6151,13 @@ async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor
|
|
|
6690
6151
|
platformMachine
|
|
6691
6152
|
);
|
|
6692
6153
|
if (!compatible) {
|
|
6693
|
-
(0,
|
|
6154
|
+
(0, import_build_utils6.debug)(
|
|
6694
6155
|
`Skipping dependency ${dep.name}: marker "${dep.marker}" not satisfied on ${sysPlatform}`
|
|
6695
6156
|
);
|
|
6696
6157
|
continue;
|
|
6697
6158
|
}
|
|
6698
6159
|
} catch (err) {
|
|
6699
|
-
(0,
|
|
6160
|
+
(0, import_build_utils6.debug)(
|
|
6700
6161
|
`Failed to evaluate marker "${dep.marker}" for ${dep.name}, including conservatively: ${err instanceof Error ? err.message : String(err)}`
|
|
6701
6162
|
);
|
|
6702
6163
|
}
|
|
@@ -6730,7 +6191,7 @@ async function calculateBundleSize(files, filter) {
|
|
|
6730
6191
|
knownSize += fsRef.size;
|
|
6731
6192
|
} else {
|
|
6732
6193
|
statPromises.push(
|
|
6733
|
-
|
|
6194
|
+
import_fs5.default.promises.stat(fsRef.fsPath).then((stats) => {
|
|
6734
6195
|
fsRef.size = stats.size;
|
|
6735
6196
|
return stats.size;
|
|
6736
6197
|
}).catch((err) => {
|
|
@@ -6753,12 +6214,6 @@ async function calculateBundleSize(files, filter) {
|
|
|
6753
6214
|
}
|
|
6754
6215
|
return totalSize;
|
|
6755
6216
|
}
|
|
6756
|
-
var PYC_TO_PY_RATIO = 1.2;
|
|
6757
|
-
var BYTECODE_COVERAGE_FLOOR = 0.5;
|
|
6758
|
-
async function estimateBytecodeSize(files) {
|
|
6759
|
-
const pyBytes = await calculateBundleSize(files, (p) => p.endsWith(".py"));
|
|
6760
|
-
return PYC_TO_PY_RATIO * pyBytes;
|
|
6761
|
-
}
|
|
6762
6217
|
function lambdaKnapsack(packages, capacity) {
|
|
6763
6218
|
if (capacity <= 0) {
|
|
6764
6219
|
return [];
|
|
@@ -6793,8 +6248,8 @@ function planPublicPackagePacking({
|
|
|
6793
6248
|
}
|
|
6794
6249
|
|
|
6795
6250
|
// src/diagnostics.ts
|
|
6796
|
-
var
|
|
6797
|
-
var
|
|
6251
|
+
var import_fs6 = __toESM(require("fs"));
|
|
6252
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
6798
6253
|
var import_python_analysis4 = require("@vercel/python-analysis");
|
|
6799
6254
|
function isDependencyGroupInclude(entry) {
|
|
6800
6255
|
return typeof entry === "object" && "include-group" in entry;
|
|
@@ -6908,7 +6363,7 @@ async function generateProjectManifest({
|
|
|
6908
6363
|
const directEntries = [];
|
|
6909
6364
|
const transitiveEntries = [];
|
|
6910
6365
|
{
|
|
6911
|
-
const content = await
|
|
6366
|
+
const content = await import_fs6.default.promises.readFile(uvLockPath, "utf-8");
|
|
6912
6367
|
const uvLock = (0, import_python_analysis4.parseUvLock)(content, uvLockPath);
|
|
6913
6368
|
const projectName = project?.name;
|
|
6914
6369
|
const excludeSet = new Set(
|
|
@@ -6999,7 +6454,7 @@ async function generateProjectManifest({
|
|
|
6999
6454
|
}
|
|
7000
6455
|
}
|
|
7001
6456
|
const manifest = {
|
|
7002
|
-
version:
|
|
6457
|
+
version: import_build_utils7.MANIFEST_VERSION,
|
|
7003
6458
|
runtime: "python",
|
|
7004
6459
|
...framework ? { framework } : {},
|
|
7005
6460
|
...serviceType ? { serviceType } : {},
|
|
@@ -7013,22 +6468,22 @@ async function generateProjectManifest({
|
|
|
7013
6468
|
...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
|
|
7014
6469
|
]
|
|
7015
6470
|
};
|
|
7016
|
-
await (0,
|
|
6471
|
+
await (0, import_build_utils7.writeProjectManifest)(manifest, workPath, "python");
|
|
7017
6472
|
}
|
|
7018
|
-
var diagnostics = (0,
|
|
6473
|
+
var diagnostics = (0, import_build_utils7.createDiagnostics)("python");
|
|
7019
6474
|
|
|
7020
6475
|
// src/crons.ts
|
|
7021
|
-
var import_fs9 = __toESM(require("fs"));
|
|
7022
|
-
var import_path9 = require("path");
|
|
7023
|
-
var import_execa5 = __toESM(require_execa());
|
|
7024
|
-
var import_build_utils12 = require("@vercel/build-utils");
|
|
7025
|
-
|
|
7026
|
-
// src/entrypoint.ts
|
|
7027
6476
|
var import_fs8 = __toESM(require("fs"));
|
|
7028
6477
|
var import_path8 = require("path");
|
|
6478
|
+
var import_execa4 = __toESM(require_execa());
|
|
6479
|
+
var import_build_utils11 = require("@vercel/build-utils");
|
|
6480
|
+
|
|
6481
|
+
// src/entrypoint.ts
|
|
6482
|
+
var import_fs7 = __toESM(require("fs"));
|
|
6483
|
+
var import_path7 = require("path");
|
|
6484
|
+
var import_build_utils8 = require("@vercel/build-utils");
|
|
7029
6485
|
var import_build_utils9 = require("@vercel/build-utils");
|
|
7030
6486
|
var import_build_utils10 = require("@vercel/build-utils");
|
|
7031
|
-
var import_build_utils11 = require("@vercel/build-utils");
|
|
7032
6487
|
var import_python_analysis5 = require("@vercel/python-analysis");
|
|
7033
6488
|
var PYTHON_ENTRYPOINT_FILENAMES = [
|
|
7034
6489
|
"app",
|
|
@@ -7047,13 +6502,13 @@ var SKIP_DIRS = /* @__PURE__ */ new Set(["__pycache__", "node_modules"]);
|
|
|
7047
6502
|
function getCandidateEntrypointsInDirs(dirs) {
|
|
7048
6503
|
return dirs.flatMap(
|
|
7049
6504
|
(dir) => PYTHON_ENTRYPOINT_FILENAMES.map(
|
|
7050
|
-
(filename) =>
|
|
6505
|
+
(filename) => import_path7.posix.join(dir, `${filename}.py`)
|
|
7051
6506
|
)
|
|
7052
6507
|
);
|
|
7053
6508
|
}
|
|
7054
6509
|
async function fileExists(filePath) {
|
|
7055
6510
|
try {
|
|
7056
|
-
const stat = await
|
|
6511
|
+
const stat = await import_fs7.default.promises.stat(filePath);
|
|
7057
6512
|
return stat.isFile();
|
|
7058
6513
|
} catch {
|
|
7059
6514
|
return false;
|
|
@@ -7108,28 +6563,28 @@ function entrypointToModule(entrypoint) {
|
|
|
7108
6563
|
return entrypoint.replace(/\\/g, "/").replace(/\.py$/i, "").replace(/\/__init__$/i, "").replace(/\//g, ".");
|
|
7109
6564
|
}
|
|
7110
6565
|
async function checkEntrypoint(workPath, relPath) {
|
|
7111
|
-
const absPath = (0,
|
|
6566
|
+
const absPath = (0, import_path7.join)(workPath, relPath);
|
|
7112
6567
|
if (!await fileExists(absPath))
|
|
7113
6568
|
return null;
|
|
7114
|
-
const content = await
|
|
6569
|
+
const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
|
|
7115
6570
|
return (0, import_python_analysis5.findAppOrHandler)(content);
|
|
7116
6571
|
}
|
|
7117
6572
|
async function findPythonFilesRecursive(dir, rootDir) {
|
|
7118
6573
|
const results = [];
|
|
7119
6574
|
let entries;
|
|
7120
6575
|
try {
|
|
7121
|
-
entries = await
|
|
6576
|
+
entries = await import_fs7.default.promises.readdir(dir, { withFileTypes: true });
|
|
7122
6577
|
} catch {
|
|
7123
6578
|
return results;
|
|
7124
6579
|
}
|
|
7125
6580
|
for (const entry of entries) {
|
|
7126
6581
|
if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
|
|
7127
6582
|
continue;
|
|
7128
|
-
const fullPath = (0,
|
|
6583
|
+
const fullPath = (0, import_path7.join)(dir, entry.name);
|
|
7129
6584
|
if (entry.isDirectory()) {
|
|
7130
6585
|
results.push(...await findPythonFilesRecursive(fullPath, rootDir));
|
|
7131
6586
|
} else if (entry.isFile() && entry.name.endsWith(".py")) {
|
|
7132
|
-
results.push((0,
|
|
6587
|
+
results.push((0, import_path7.relative)(rootDir, fullPath).replace(/\\/g, "/"));
|
|
7133
6588
|
}
|
|
7134
6589
|
}
|
|
7135
6590
|
return results;
|
|
@@ -7139,8 +6594,8 @@ async function findEntrypointCandidates(workPath) {
|
|
|
7139
6594
|
const candidates = [];
|
|
7140
6595
|
for (const relPath of pyFiles) {
|
|
7141
6596
|
try {
|
|
7142
|
-
const content = await
|
|
7143
|
-
(0,
|
|
6597
|
+
const content = await import_fs7.default.promises.readFile(
|
|
6598
|
+
(0, import_path7.join)(workPath, relPath),
|
|
7144
6599
|
"utf-8"
|
|
7145
6600
|
);
|
|
7146
6601
|
const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
|
|
@@ -7175,24 +6630,24 @@ async function resolveModuleAttrEntrypoint(workPath, value) {
|
|
|
7175
6630
|
const relPath = modulePath.replace(/\./g, "/");
|
|
7176
6631
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
7177
6632
|
for (const candidate of candidates) {
|
|
7178
|
-
if (await fileExists((0,
|
|
6633
|
+
if (await fileExists((0, import_path7.join)(workPath, candidate))) {
|
|
7179
6634
|
return { entrypoint: candidate, variableName };
|
|
7180
6635
|
}
|
|
7181
6636
|
}
|
|
7182
6637
|
return null;
|
|
7183
6638
|
}
|
|
7184
6639
|
async function getVercelToolsEntrypoint(workPath, repoRootPath) {
|
|
7185
|
-
const pyprojectPath = (0,
|
|
7186
|
-
const pyprojectData = await (0,
|
|
6640
|
+
const pyprojectPath = (0, import_path7.join)(workPath, "pyproject.toml");
|
|
6641
|
+
const pyprojectData = await (0, import_build_utils10.readConfigFile)(pyprojectPath);
|
|
7187
6642
|
if (!pyprojectData)
|
|
7188
6643
|
return null;
|
|
7189
6644
|
const vercelEntrypoint = pyprojectData.tool?.vercel?.entrypoint;
|
|
7190
6645
|
if (vercelEntrypoint === void 0)
|
|
7191
6646
|
return null;
|
|
7192
|
-
const relPyprojectPath = (0,
|
|
6647
|
+
const relPyprojectPath = (0, import_path7.relative)(repoRootPath ?? workPath, pyprojectPath);
|
|
7193
6648
|
const displayPath = !relPyprojectPath || relPyprojectPath.startsWith("..") ? pyprojectPath : relPyprojectPath;
|
|
7194
6649
|
if (typeof vercelEntrypoint !== "string") {
|
|
7195
|
-
throw new
|
|
6650
|
+
throw new import_build_utils8.NowBuildError({
|
|
7196
6651
|
code: "PYTHON_INVALID_ENTRYPOINT",
|
|
7197
6652
|
message: `"tool.vercel.entrypoint" in "${displayPath}" must be a string in "module:object" format (e.g. "main:app").`,
|
|
7198
6653
|
link: PYTHON_ENTRYPOINT_DOCS_URL,
|
|
@@ -7204,7 +6659,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
|
|
|
7204
6659
|
vercelEntrypoint
|
|
7205
6660
|
);
|
|
7206
6661
|
if (!resolved) {
|
|
7207
|
-
throw new
|
|
6662
|
+
throw new import_build_utils8.NowBuildError({
|
|
7208
6663
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
7209
6664
|
message: `"tool.vercel.entrypoint" in "${displayPath}" is "${vercelEntrypoint}" but no matching module file was found. Use "module:object" format (e.g. "main:app") and ensure the module file exists, or remove the setting to use automatic entrypoint detection.`,
|
|
7210
6665
|
link: PYTHON_ENTRYPOINT_DOCS_URL,
|
|
@@ -7214,7 +6669,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
|
|
|
7214
6669
|
return resolved;
|
|
7215
6670
|
}
|
|
7216
6671
|
async function getPyprojectEntrypointWithDiagnostics(workPath) {
|
|
7217
|
-
const pyprojectData = await (0,
|
|
6672
|
+
const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
|
|
7218
6673
|
if (!pyprojectData)
|
|
7219
6674
|
return { entrypoint: null };
|
|
7220
6675
|
const scripts = pyprojectData.project?.scripts;
|
|
@@ -7229,7 +6684,7 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
|
|
|
7229
6684
|
const relPath = modulePath.replace(/\./g, "/");
|
|
7230
6685
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
7231
6686
|
for (const candidate of candidates) {
|
|
7232
|
-
if (await fileExists((0,
|
|
6687
|
+
if (await fileExists((0, import_path7.join)(workPath, candidate))) {
|
|
7233
6688
|
return { entrypoint: { entrypoint: candidate, variableName } };
|
|
7234
6689
|
}
|
|
7235
6690
|
}
|
|
@@ -7238,13 +6693,13 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
|
|
|
7238
6693
|
async function findValidEntrypoint(workPath, candidates) {
|
|
7239
6694
|
const existingWithoutEntrypoint = [];
|
|
7240
6695
|
for (const candidate of candidates) {
|
|
7241
|
-
const absPath = (0,
|
|
6696
|
+
const absPath = (0, import_path7.join)(workPath, candidate);
|
|
7242
6697
|
if (!await fileExists(absPath))
|
|
7243
6698
|
continue;
|
|
7244
|
-
const content = await
|
|
6699
|
+
const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
|
|
7245
6700
|
const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
|
|
7246
6701
|
if (varName) {
|
|
7247
|
-
(0,
|
|
6702
|
+
(0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
|
|
7248
6703
|
return {
|
|
7249
6704
|
entrypoint: { entrypoint: candidate, variableName: varName },
|
|
7250
6705
|
existingWithoutEntrypoint
|
|
@@ -7255,12 +6710,12 @@ async function findValidEntrypoint(workPath, candidates) {
|
|
|
7255
6710
|
return { entrypoint: null, existingWithoutEntrypoint };
|
|
7256
6711
|
}
|
|
7257
6712
|
async function checkDjangoManage(workPath) {
|
|
7258
|
-
const managePath = (0,
|
|
6713
|
+
const managePath = (0, import_path7.join)(workPath, "manage.py");
|
|
7259
6714
|
try {
|
|
7260
|
-
const content = await
|
|
6715
|
+
const content = await import_fs7.default.promises.readFile(managePath, "utf-8");
|
|
7261
6716
|
if (!content.includes("DJANGO_SETTINGS_MODULE"))
|
|
7262
6717
|
return false;
|
|
7263
|
-
(0,
|
|
6718
|
+
(0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
|
|
7264
6719
|
return true;
|
|
7265
6720
|
} catch {
|
|
7266
6721
|
return false;
|
|
@@ -7268,7 +6723,7 @@ async function checkDjangoManage(workPath) {
|
|
|
7268
6723
|
}
|
|
7269
6724
|
async function getSubdirectories(workPath) {
|
|
7270
6725
|
try {
|
|
7271
|
-
const entries = await
|
|
6726
|
+
const entries = await import_fs7.default.promises.readdir(workPath, {
|
|
7272
6727
|
withFileTypes: true
|
|
7273
6728
|
});
|
|
7274
6729
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
@@ -7313,7 +6768,7 @@ ${suggestion}`;
|
|
|
7313
6768
|
const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
7314
6769
|
message = `No ${displayName} entrypoint found. Set "tool.vercel.entrypoint" in pyproject.toml or define an entrypoint in one of: ${searchedList}.`;
|
|
7315
6770
|
}
|
|
7316
|
-
return new
|
|
6771
|
+
return new import_build_utils8.NowBuildError({ code, message, link, action });
|
|
7317
6772
|
}
|
|
7318
6773
|
async function detectGenericPythonEntrypoint(workPath) {
|
|
7319
6774
|
try {
|
|
@@ -7326,7 +6781,7 @@ async function detectGenericPythonEntrypoint(workPath) {
|
|
|
7326
6781
|
findDiagnostics: result
|
|
7327
6782
|
};
|
|
7328
6783
|
} catch {
|
|
7329
|
-
(0,
|
|
6784
|
+
(0, import_build_utils9.debug)("Failed to discover Python entrypoint");
|
|
7330
6785
|
return {
|
|
7331
6786
|
detected: null,
|
|
7332
6787
|
findDiagnostics: { entrypoint: null, existingWithoutEntrypoint: [] }
|
|
@@ -7345,7 +6800,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
7345
6800
|
const subdirs = await getSubdirectories(workPath);
|
|
7346
6801
|
const rootDirs = ["", ...subdirs];
|
|
7347
6802
|
for (const rootDir of rootDirs) {
|
|
7348
|
-
const currPath = (0,
|
|
6803
|
+
const currPath = (0, import_path7.join)(workPath, rootDir);
|
|
7349
6804
|
const isDjango = await checkDjangoManage(currPath);
|
|
7350
6805
|
if (isDjango) {
|
|
7351
6806
|
return {
|
|
@@ -7361,7 +6816,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
7361
6816
|
findDiagnostics: result
|
|
7362
6817
|
};
|
|
7363
6818
|
} catch {
|
|
7364
|
-
(0,
|
|
6819
|
+
(0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
|
|
7365
6820
|
return emptyResult;
|
|
7366
6821
|
}
|
|
7367
6822
|
}
|
|
@@ -7369,10 +6824,10 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
|
|
|
7369
6824
|
if (configuredEntrypoint) {
|
|
7370
6825
|
const { filePath: configEntryFile, varName: configEntryVar } = configuredEntrypoint;
|
|
7371
6826
|
const entrypoint = configEntryFile.endsWith(".py") ? configEntryFile : `${configEntryFile}.py`;
|
|
7372
|
-
const entrypointExists = await fileExists((0,
|
|
6827
|
+
const entrypointExists = await fileExists((0, import_path7.join)(workPath, entrypoint));
|
|
7373
6828
|
if (!entrypointExists) {
|
|
7374
6829
|
return {
|
|
7375
|
-
error: new
|
|
6830
|
+
error: new import_build_utils8.NowBuildError({
|
|
7376
6831
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
7377
6832
|
message: `Configured Python entrypoint "${entrypoint}" was not found.`,
|
|
7378
6833
|
link: PYTHON_ENTRYPOINT_DOCS_URL,
|
|
@@ -7382,17 +6837,17 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
|
|
|
7382
6837
|
}
|
|
7383
6838
|
let varName = configEntryVar ?? await checkEntrypoint(workPath, entrypoint);
|
|
7384
6839
|
if (!varName) {
|
|
7385
|
-
const needsDynamicApp = !!service && ((0,
|
|
6840
|
+
const needsDynamicApp = !!service && ((0, import_build_utils8.isScheduleTriggeredService)(service) || (0, import_build_utils8.isQueueTriggeredService)(service) || (0, import_build_utils8.isWorkflowTriggeredService)(service));
|
|
7386
6841
|
if (needsDynamicApp) {
|
|
7387
6842
|
varName = "app";
|
|
7388
6843
|
}
|
|
7389
6844
|
}
|
|
7390
6845
|
if (varName) {
|
|
7391
|
-
(0,
|
|
6846
|
+
(0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
|
|
7392
6847
|
return { entrypoint: { entrypoint, variableName: varName } };
|
|
7393
6848
|
} else {
|
|
7394
6849
|
return {
|
|
7395
|
-
error: new
|
|
6850
|
+
error: new import_build_utils8.NowBuildError({
|
|
7396
6851
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
7397
6852
|
message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
|
|
7398
6853
|
link: PYTHON_ENTRYPOINT_DOCS_URL,
|
|
@@ -7442,7 +6897,7 @@ var detectEntrypoint = async ({
|
|
|
7442
6897
|
workPath,
|
|
7443
6898
|
framework
|
|
7444
6899
|
}) => {
|
|
7445
|
-
if (!(0,
|
|
6900
|
+
if (!(0, import_build_utils8.isPythonFramework)(framework))
|
|
7446
6901
|
return null;
|
|
7447
6902
|
let detected;
|
|
7448
6903
|
try {
|
|
@@ -7451,7 +6906,7 @@ var detectEntrypoint = async ({
|
|
|
7451
6906
|
workPath
|
|
7452
6907
|
);
|
|
7453
6908
|
} catch (err) {
|
|
7454
|
-
(0,
|
|
6909
|
+
(0, import_build_utils9.debug)(
|
|
7455
6910
|
`Python entrypoint detection failed for ${workPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
7456
6911
|
);
|
|
7457
6912
|
return null;
|
|
@@ -7467,8 +6922,8 @@ var detectEntrypoint = async ({
|
|
|
7467
6922
|
|
|
7468
6923
|
// src/crons.ts
|
|
7469
6924
|
var DYNAMIC_SCHEDULE = "<dynamic>";
|
|
7470
|
-
var scriptPath = (0,
|
|
7471
|
-
var script =
|
|
6925
|
+
var scriptPath = (0, import_path8.join)(__dirname, "..", "templates", "vc_cron_detect.py");
|
|
6926
|
+
var script = import_fs8.default.readFileSync(scriptPath, "utf-8");
|
|
7472
6927
|
function buildCronRouteTable(crons) {
|
|
7473
6928
|
const table = {};
|
|
7474
6929
|
for (const cron of crons) {
|
|
@@ -7478,13 +6933,13 @@ function buildCronRouteTable(crons) {
|
|
|
7478
6933
|
}
|
|
7479
6934
|
async function getServiceCrons(opts) {
|
|
7480
6935
|
const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
|
|
7481
|
-
const isScheduledService = !!service && (0,
|
|
6936
|
+
const isScheduledService = !!service && (0, import_build_utils11.isScheduleTriggeredService)(service);
|
|
7482
6937
|
if (!isScheduledService || !service.name || typeof service.schedule !== "string" && !Array.isArray(service.schedule)) {
|
|
7483
6938
|
return void 0;
|
|
7484
6939
|
}
|
|
7485
6940
|
const cronEntrypoint = entrypoint || rawEntrypoint;
|
|
7486
6941
|
if (!cronEntrypoint) {
|
|
7487
|
-
throw new
|
|
6942
|
+
throw new import_build_utils11.NowBuildError({
|
|
7488
6943
|
code: "PYTHON_CRON_NO_ENTRYPOINT",
|
|
7489
6944
|
message: "Cron service is missing an entrypoint."
|
|
7490
6945
|
});
|
|
@@ -7499,7 +6954,7 @@ async function getServiceCrons(opts) {
|
|
|
7499
6954
|
workPath: opts.workPath
|
|
7500
6955
|
});
|
|
7501
6956
|
}
|
|
7502
|
-
const cronPath = (0,
|
|
6957
|
+
const cronPath = (0, import_build_utils11.getInternalServiceCronPath)(
|
|
7503
6958
|
service.name,
|
|
7504
6959
|
cronEntrypoint,
|
|
7505
6960
|
handlerFunction || "cron"
|
|
@@ -7523,7 +6978,7 @@ async function getServiceCronsDynamic(opts) {
|
|
|
7523
6978
|
workPath
|
|
7524
6979
|
} = opts;
|
|
7525
6980
|
if (!handlerFunction) {
|
|
7526
|
-
throw new
|
|
6981
|
+
throw new import_build_utils11.NowBuildError({
|
|
7527
6982
|
code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
|
|
7528
6983
|
message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
|
|
7529
6984
|
});
|
|
@@ -7540,7 +6995,7 @@ async function getServiceCronsDynamic(opts) {
|
|
|
7540
6995
|
`Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
|
|
7541
6996
|
);
|
|
7542
6997
|
if (entries.length === 0) {
|
|
7543
|
-
throw new
|
|
6998
|
+
throw new import_build_utils11.NowBuildError({
|
|
7544
6999
|
code: "PYTHON_DYNAMIC_CRON_EMPTY",
|
|
7545
7000
|
message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
|
|
7546
7001
|
});
|
|
@@ -7561,7 +7016,7 @@ async function detectDynamicCrons(opts) {
|
|
|
7561
7016
|
const { pythonBin, env, workPath, moduleName, attrName } = opts;
|
|
7562
7017
|
let stdout;
|
|
7563
7018
|
try {
|
|
7564
|
-
const result = await (0,
|
|
7019
|
+
const result = await (0, import_execa4.default)(
|
|
7565
7020
|
pythonBin,
|
|
7566
7021
|
["-c", script, moduleName, attrName],
|
|
7567
7022
|
{ env, cwd: workPath }
|
|
@@ -7575,7 +7030,7 @@ async function detectDynamicCrons(opts) {
|
|
|
7575
7030
|
detail = parsed2.error;
|
|
7576
7031
|
} catch {
|
|
7577
7032
|
}
|
|
7578
|
-
throw new
|
|
7033
|
+
throw new import_build_utils11.NowBuildError({
|
|
7579
7034
|
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
7580
7035
|
message: `Failed to detect dynamic cron entries: ${detail}`
|
|
7581
7036
|
});
|
|
@@ -7584,7 +7039,7 @@ async function detectDynamicCrons(opts) {
|
|
|
7584
7039
|
try {
|
|
7585
7040
|
parsed = JSON.parse(stdout);
|
|
7586
7041
|
} catch {
|
|
7587
|
-
throw new
|
|
7042
|
+
throw new import_build_utils11.NowBuildError({
|
|
7588
7043
|
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
7589
7044
|
message: `Dynamic cron detection returned invalid JSON: ${stdout}`
|
|
7590
7045
|
});
|
|
@@ -7594,7 +7049,7 @@ async function detectDynamicCrons(opts) {
|
|
|
7594
7049
|
function moduleColonFuncToCronPath(serviceName, moduleFunction) {
|
|
7595
7050
|
const colonIdx = moduleFunction.indexOf(":");
|
|
7596
7051
|
if (colonIdx === -1) {
|
|
7597
|
-
throw new
|
|
7052
|
+
throw new import_build_utils11.NowBuildError({
|
|
7598
7053
|
code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
|
|
7599
7054
|
message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
|
|
7600
7055
|
});
|
|
@@ -7602,14 +7057,14 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
|
|
|
7602
7057
|
const modulePart = moduleFunction.slice(0, colonIdx);
|
|
7603
7058
|
const funcPart = moduleFunction.slice(colonIdx + 1);
|
|
7604
7059
|
const entrypointPath = modulePart.replace(/\./g, "/");
|
|
7605
|
-
return (0,
|
|
7060
|
+
return (0, import_build_utils11.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
|
|
7606
7061
|
}
|
|
7607
7062
|
|
|
7608
7063
|
// src/start-dev-server.ts
|
|
7609
7064
|
var import_child_process2 = require("child_process");
|
|
7610
|
-
var
|
|
7611
|
-
var
|
|
7612
|
-
var
|
|
7065
|
+
var import_fs9 = require("fs");
|
|
7066
|
+
var import_path9 = require("path");
|
|
7067
|
+
var import_build_utils12 = require("@vercel/build-utils");
|
|
7613
7068
|
var import_get_port = __toESM(require_get_port());
|
|
7614
7069
|
var import_is_port_reachable = __toESM(require_is_port_reachable());
|
|
7615
7070
|
var import_python_analysis6 = require("@vercel/python-analysis");
|
|
@@ -7715,17 +7170,17 @@ async function syncDependencies({
|
|
|
7715
7170
|
let { manifestPath } = installInfo;
|
|
7716
7171
|
const manifest = pythonPackage.manifest;
|
|
7717
7172
|
if (!manifestType || !manifestPath) {
|
|
7718
|
-
(0,
|
|
7173
|
+
(0, import_build_utils12.debug)("No Python project manifest found, skipping dependency sync");
|
|
7719
7174
|
return;
|
|
7720
7175
|
}
|
|
7721
7176
|
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
7722
|
-
const syncDir = (0,
|
|
7723
|
-
(0,
|
|
7724
|
-
const tempPyproject = (0,
|
|
7177
|
+
const syncDir = (0, import_path9.join)(workPath, ".vercel", "python", "sync");
|
|
7178
|
+
(0, import_fs9.mkdirSync)(syncDir, { recursive: true });
|
|
7179
|
+
const tempPyproject = (0, import_path9.join)(syncDir, "pyproject.toml");
|
|
7725
7180
|
const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
|
|
7726
|
-
(0,
|
|
7181
|
+
(0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
|
|
7727
7182
|
manifestPath = tempPyproject;
|
|
7728
|
-
(0,
|
|
7183
|
+
(0, import_build_utils12.debug)(
|
|
7729
7184
|
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
7730
7185
|
);
|
|
7731
7186
|
}
|
|
@@ -7758,7 +7213,7 @@ async function syncDependencies({
|
|
|
7758
7213
|
for (const [channel, chunk] of captured) {
|
|
7759
7214
|
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
7760
7215
|
}
|
|
7761
|
-
throw new
|
|
7216
|
+
throw new import_build_utils12.NowBuildError({
|
|
7762
7217
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
7763
7218
|
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
7764
7219
|
});
|
|
@@ -7773,14 +7228,14 @@ async function runSync({
|
|
|
7773
7228
|
onStdout,
|
|
7774
7229
|
onStderr
|
|
7775
7230
|
}) {
|
|
7776
|
-
const projectDir = (0,
|
|
7231
|
+
const projectDir = (0, import_path9.dirname)(manifestPath);
|
|
7777
7232
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
7778
7233
|
let spawnCmd;
|
|
7779
7234
|
let spawnArgs;
|
|
7780
7235
|
switch (manifestType) {
|
|
7781
7236
|
case "uv.lock": {
|
|
7782
7237
|
if (!uvPath) {
|
|
7783
|
-
throw new
|
|
7238
|
+
throw new import_build_utils12.NowBuildError({
|
|
7784
7239
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
7785
7240
|
message: "uv is required to install dependencies from uv.lock.",
|
|
7786
7241
|
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
@@ -7802,11 +7257,11 @@ async function runSync({
|
|
|
7802
7257
|
break;
|
|
7803
7258
|
}
|
|
7804
7259
|
default:
|
|
7805
|
-
(0,
|
|
7260
|
+
(0, import_build_utils12.debug)(`Unknown manifest type: ${manifestType}`);
|
|
7806
7261
|
return;
|
|
7807
7262
|
}
|
|
7808
7263
|
await new Promise((resolve3, reject) => {
|
|
7809
|
-
(0,
|
|
7264
|
+
(0, import_build_utils12.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
7810
7265
|
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
7811
7266
|
cwd: projectDir,
|
|
7812
7267
|
env: getProtectedUvEnv(env),
|
|
@@ -7845,7 +7300,7 @@ var COMPLETED_INSTALLS = /* @__PURE__ */ new Set();
|
|
|
7845
7300
|
function hasInstalledDistribution(targetDir, packageName) {
|
|
7846
7301
|
const prefix = `${packageName.replace("-", "_")}-`;
|
|
7847
7302
|
try {
|
|
7848
|
-
return (0,
|
|
7303
|
+
return (0, import_fs9.readdirSync)(targetDir).some(
|
|
7849
7304
|
(entry) => entry.startsWith(prefix) && entry.endsWith(".dist-info")
|
|
7850
7305
|
);
|
|
7851
7306
|
} catch {
|
|
@@ -7853,7 +7308,7 @@ function hasInstalledDistribution(targetDir, packageName) {
|
|
|
7853
7308
|
}
|
|
7854
7309
|
}
|
|
7855
7310
|
async function installInjectedDevPackage(pkg, opts) {
|
|
7856
|
-
const targetDir = (0,
|
|
7311
|
+
const targetDir = (0, import_path9.join)(opts.workPath, ".vercel", "python");
|
|
7857
7312
|
const source = pkg.envOverride || pkg.pinnedVersion;
|
|
7858
7313
|
const key = `${targetDir}:${pkg.name}:${source}`;
|
|
7859
7314
|
if (COMPLETED_INSTALLS.has(key) && hasInstalledDistribution(targetDir, pkg.name)) {
|
|
@@ -7867,22 +7322,22 @@ async function installInjectedDevPackage(pkg, opts) {
|
|
|
7867
7322
|
}
|
|
7868
7323
|
async function doInstallInjectedDevPackage(pkg, opts) {
|
|
7869
7324
|
const { targetDir, workPath, uvPath, pythonBin, env, onStdout, onStderr } = opts;
|
|
7870
|
-
(0,
|
|
7871
|
-
const localDir = (0,
|
|
7872
|
-
const isLocalDev = (0,
|
|
7325
|
+
(0, import_fs9.mkdirSync)(targetDir, { recursive: true });
|
|
7326
|
+
const localDir = (0, import_path9.join)(__dirname, "..", "..", "..", "python", pkg.name);
|
|
7327
|
+
const isLocalDev = (0, import_fs9.existsSync)((0, import_path9.join)(localDir, "pyproject.toml"));
|
|
7873
7328
|
const dep = pkg.envOverride || (isLocalDev ? localDir : `${pkg.name}==${pkg.pinnedVersion}`);
|
|
7874
7329
|
if (!isLocalDev && !pkg.envOverride) {
|
|
7875
7330
|
const distInfoName = pkg.name.replace("-", "_");
|
|
7876
|
-
const distInfo = (0,
|
|
7331
|
+
const distInfo = (0, import_path9.join)(
|
|
7877
7332
|
targetDir,
|
|
7878
7333
|
`${distInfoName}-${pkg.pinnedVersion}.dist-info`
|
|
7879
7334
|
);
|
|
7880
|
-
if ((0,
|
|
7881
|
-
(0,
|
|
7335
|
+
if ((0, import_fs9.existsSync)(distInfo)) {
|
|
7336
|
+
(0, import_build_utils12.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
|
|
7882
7337
|
return;
|
|
7883
7338
|
}
|
|
7884
7339
|
}
|
|
7885
|
-
(0,
|
|
7340
|
+
(0, import_build_utils12.debug)(
|
|
7886
7341
|
`Installing ${pkg.name} into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${dep})`
|
|
7887
7342
|
);
|
|
7888
7343
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -7904,14 +7359,14 @@ async function doInstallInjectedDevPackage(pkg, opts) {
|
|
|
7904
7359
|
if (onStdout) {
|
|
7905
7360
|
onStdout(data);
|
|
7906
7361
|
} else {
|
|
7907
|
-
(0,
|
|
7362
|
+
(0, import_build_utils12.debug)(data.toString());
|
|
7908
7363
|
}
|
|
7909
7364
|
});
|
|
7910
7365
|
child.stderr?.on("data", (data) => {
|
|
7911
7366
|
if (onStderr) {
|
|
7912
7367
|
onStderr(data);
|
|
7913
7368
|
} else {
|
|
7914
|
-
(0,
|
|
7369
|
+
(0, import_build_utils12.debug)(data.toString());
|
|
7915
7370
|
}
|
|
7916
7371
|
});
|
|
7917
7372
|
child.on("error", reject);
|
|
@@ -7941,12 +7396,12 @@ function installGlobalCleanupHandlers() {
|
|
|
7941
7396
|
try {
|
|
7942
7397
|
process.kill(info.pid, "SIGTERM");
|
|
7943
7398
|
} catch (err) {
|
|
7944
|
-
(0,
|
|
7399
|
+
(0, import_build_utils12.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
|
|
7945
7400
|
}
|
|
7946
7401
|
try {
|
|
7947
7402
|
process.kill(info.pid, "SIGKILL");
|
|
7948
7403
|
} catch (err) {
|
|
7949
|
-
(0,
|
|
7404
|
+
(0, import_build_utils12.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
|
|
7950
7405
|
}
|
|
7951
7406
|
PERSISTENT_SERVERS.delete(key);
|
|
7952
7407
|
}
|
|
@@ -7954,7 +7409,7 @@ function installGlobalCleanupHandlers() {
|
|
|
7954
7409
|
try {
|
|
7955
7410
|
restoreWarnings();
|
|
7956
7411
|
} catch (err) {
|
|
7957
|
-
(0,
|
|
7412
|
+
(0, import_build_utils12.debug)(`Error restoring warnings: ${err}`);
|
|
7958
7413
|
}
|
|
7959
7414
|
restoreWarnings = null;
|
|
7960
7415
|
}
|
|
@@ -7971,46 +7426,46 @@ function installGlobalCleanupHandlers() {
|
|
|
7971
7426
|
}
|
|
7972
7427
|
function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
|
|
7973
7428
|
try {
|
|
7974
|
-
const vercelPythonDir = serviceName ? (0,
|
|
7975
|
-
(0,
|
|
7429
|
+
const vercelPythonDir = serviceName ? (0, import_path9.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path9.join)(workPath, ".vercel", "python");
|
|
7430
|
+
(0, import_fs9.mkdirSync)(vercelPythonDir, { recursive: true });
|
|
7976
7431
|
let qualifiedModule = modulePath;
|
|
7977
7432
|
let extraPythonPath;
|
|
7978
|
-
if ((0,
|
|
7979
|
-
const pkgName = (0,
|
|
7433
|
+
if ((0, import_fs9.existsSync)((0, import_path9.join)(workPath, "__init__.py"))) {
|
|
7434
|
+
const pkgName = (0, import_path9.basename)(workPath);
|
|
7980
7435
|
qualifiedModule = `${pkgName}.${modulePath}`;
|
|
7981
|
-
extraPythonPath = (0,
|
|
7436
|
+
extraPythonPath = (0, import_path9.dirname)(workPath);
|
|
7982
7437
|
}
|
|
7983
|
-
const entryAbs = (0,
|
|
7984
|
-
const shimPath = (0,
|
|
7985
|
-
const templatePath = (0,
|
|
7438
|
+
const entryAbs = (0, import_path9.join)(workPath, entry);
|
|
7439
|
+
const shimPath = (0, import_path9.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
|
|
7440
|
+
const templatePath = (0, import_path9.join)(
|
|
7986
7441
|
__dirname,
|
|
7987
7442
|
"..",
|
|
7988
7443
|
"templates",
|
|
7989
7444
|
`${DEV_SHIM_MODULE}.py`
|
|
7990
7445
|
);
|
|
7991
|
-
const template = (0,
|
|
7446
|
+
const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
|
|
7992
7447
|
const shimSource = template.replace(/__VC_DEV_MODULE_NAME__/g, qualifiedModule).replace(/__VC_DEV_ENTRY_ABS__/g, entryAbs).replace(/__VC_DEV_FRAMEWORK__/g, framework).replace(/__VC_DEV_VARIABLE_NAME__/g, variableName);
|
|
7993
|
-
(0,
|
|
7994
|
-
(0,
|
|
7448
|
+
(0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
|
|
7449
|
+
(0, import_build_utils12.debug)(`Prepared Python dev shim at ${shimPath}`);
|
|
7995
7450
|
return {
|
|
7996
7451
|
module: DEV_SHIM_MODULE,
|
|
7997
7452
|
extraPythonPath,
|
|
7998
7453
|
shimDir: vercelPythonDir
|
|
7999
7454
|
};
|
|
8000
7455
|
} catch (err) {
|
|
8001
|
-
(0,
|
|
7456
|
+
(0, import_build_utils12.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
|
|
8002
7457
|
return null;
|
|
8003
7458
|
}
|
|
8004
7459
|
}
|
|
8005
7460
|
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
8006
|
-
const venvPath = (0,
|
|
7461
|
+
const venvPath = (0, import_path9.join)(workPath, ".venv");
|
|
8007
7462
|
const pendingCreation = PENDING_MANAGED_VENV_CREATIONS.get(venvPath);
|
|
8008
7463
|
if (pendingCreation) {
|
|
8009
7464
|
await pendingCreation;
|
|
8010
7465
|
}
|
|
8011
7466
|
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
8012
7467
|
if (venvRoot) {
|
|
8013
|
-
(0,
|
|
7468
|
+
(0, import_build_utils12.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
8014
7469
|
return { command: pythonCmd, args: [] };
|
|
8015
7470
|
}
|
|
8016
7471
|
await dedupePendingOperation(
|
|
@@ -8023,11 +7478,11 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
|
|
|
8023
7478
|
quiet: true
|
|
8024
7479
|
})
|
|
8025
7480
|
);
|
|
8026
|
-
(0,
|
|
7481
|
+
(0, import_build_utils12.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
8027
7482
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
8028
7483
|
const binDir = getVenvBinDir(venvPath);
|
|
8029
7484
|
env.VIRTUAL_ENV = venvPath;
|
|
8030
|
-
env.PATH = `${binDir}${
|
|
7485
|
+
env.PATH = `${binDir}${import_path9.delimiter}${env.PATH || ""}`;
|
|
8031
7486
|
return { command: pythonBin, args: [] };
|
|
8032
7487
|
}
|
|
8033
7488
|
var startDevServer = async (opts) => {
|
|
@@ -8072,24 +7527,34 @@ var startDevServer = async (opts) => {
|
|
|
8072
7527
|
installGlobalCleanupHandlers();
|
|
8073
7528
|
const env = { ...process.env, ...meta.env || {} };
|
|
8074
7529
|
const entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
|
|
7530
|
+
const isPyprojectEntrypoint = entrypoint === "pyproject.toml";
|
|
8075
7531
|
let resolved;
|
|
8076
7532
|
const handlerFunction = typeof config?.handlerFunction === "string" ? config.handlerFunction : void 0;
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
7533
|
+
let detected;
|
|
7534
|
+
if (isPyprojectEntrypoint) {
|
|
7535
|
+
const declaredEntrypoint = await getVercelToolsEntrypoint(
|
|
7536
|
+
workPath,
|
|
7537
|
+
opts.repoRootPath
|
|
7538
|
+
);
|
|
7539
|
+
detected = declaredEntrypoint ? { entrypoint: declaredEntrypoint } : null;
|
|
7540
|
+
} else {
|
|
7541
|
+
detected = await detectPythonEntrypoint(
|
|
7542
|
+
framework,
|
|
7543
|
+
workPath,
|
|
7544
|
+
entrypoint ? {
|
|
7545
|
+
filePath: entrypoint,
|
|
7546
|
+
// Schedule-triggered services create their own "app" wrapper dynamically.
|
|
7547
|
+
// Other services use handlerFunction as the entrypoint variable name.
|
|
7548
|
+
varName: service && (0, import_build_utils12.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
|
|
7549
|
+
} : void 0,
|
|
7550
|
+
service,
|
|
7551
|
+
opts.repoRootPath
|
|
7552
|
+
);
|
|
7553
|
+
}
|
|
8089
7554
|
let hookResult;
|
|
8090
7555
|
if (detected?.entrypoint) {
|
|
8091
7556
|
resolved = detected.entrypoint;
|
|
8092
|
-
} else {
|
|
7557
|
+
} else if (!isPyprojectEntrypoint) {
|
|
8093
7558
|
hookResult = await runFrameworkHook(framework, {
|
|
8094
7559
|
pythonEnv: env,
|
|
8095
7560
|
workPath,
|
|
@@ -8102,9 +7567,9 @@ var startDevServer = async (opts) => {
|
|
|
8102
7567
|
if (detected?.error) {
|
|
8103
7568
|
throw detected.error;
|
|
8104
7569
|
}
|
|
8105
|
-
throw new
|
|
8106
|
-
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
8107
|
-
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
7570
|
+
throw new import_build_utils12.NowBuildError({
|
|
7571
|
+
code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
7572
|
+
message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
8108
7573
|
});
|
|
8109
7574
|
}
|
|
8110
7575
|
const { entrypoint: entry, variableName } = resolved;
|
|
@@ -8134,7 +7599,7 @@ var startDevServer = async (opts) => {
|
|
|
8134
7599
|
const yellow = "\x1B[33m";
|
|
8135
7600
|
const white = "\x1B[1m";
|
|
8136
7601
|
const reset = "\x1B[0m";
|
|
8137
|
-
throw new
|
|
7602
|
+
throw new import_build_utils12.NowBuildError({
|
|
8138
7603
|
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
8139
7604
|
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
8140
7605
|
Run ${white}deactivate${reset} and try again.`
|
|
@@ -8151,11 +7616,11 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
8151
7616
|
);
|
|
8152
7617
|
spawnCommand = runner.command;
|
|
8153
7618
|
spawnArgsPrefix = runner.args;
|
|
8154
|
-
(0,
|
|
7619
|
+
(0, import_build_utils12.debug)(
|
|
8155
7620
|
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
8156
7621
|
);
|
|
8157
7622
|
} else if (venv) {
|
|
8158
|
-
(0,
|
|
7623
|
+
(0, import_build_utils12.debug)(`Running in virtualenv at ${venv}`);
|
|
8159
7624
|
} else {
|
|
8160
7625
|
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
8161
7626
|
workPath,
|
|
@@ -8164,9 +7629,9 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
8164
7629
|
);
|
|
8165
7630
|
spawnCommand = venvPythonCmd;
|
|
8166
7631
|
if (venvRoot) {
|
|
8167
|
-
(0,
|
|
7632
|
+
(0, import_build_utils12.debug)(`Using virtualenv at ${venvRoot}`);
|
|
8168
7633
|
} else {
|
|
8169
|
-
(0,
|
|
7634
|
+
(0, import_build_utils12.debug)("No virtualenv found");
|
|
8170
7635
|
try {
|
|
8171
7636
|
const yellow = "\x1B[33m";
|
|
8172
7637
|
const reset = "\x1B[0m";
|
|
@@ -8237,7 +7702,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
8237
7702
|
const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
|
|
8238
7703
|
env.PORT = `${port}`;
|
|
8239
7704
|
if (entry) {
|
|
8240
|
-
env.__VC_HANDLER_ENTRYPOINT_ABS = (0,
|
|
7705
|
+
env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path9.join)(workPath, entry);
|
|
8241
7706
|
}
|
|
8242
7707
|
const devShim = createDevShim(
|
|
8243
7708
|
workPath,
|
|
@@ -8248,8 +7713,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
8248
7713
|
variableName ?? ""
|
|
8249
7714
|
);
|
|
8250
7715
|
if (devShim) {
|
|
8251
|
-
const shimDir = devShim.shimDir || (0,
|
|
8252
|
-
const runtimeDir = (0,
|
|
7716
|
+
const shimDir = devShim.shimDir || (0, import_path9.join)(workPath, ".vercel", "python");
|
|
7717
|
+
const runtimeDir = (0, import_path9.join)(workPath, ".vercel", "python");
|
|
8253
7718
|
const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
|
|
8254
7719
|
if (devShim.extraPythonPath) {
|
|
8255
7720
|
pathParts.push(devShim.extraPythonPath);
|
|
@@ -8261,12 +7726,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
8261
7726
|
if (existingPythonPath) {
|
|
8262
7727
|
pathParts.push(existingPythonPath);
|
|
8263
7728
|
}
|
|
8264
|
-
env.PYTHONPATH = pathParts.join(
|
|
7729
|
+
env.PYTHONPATH = pathParts.join(import_path9.delimiter);
|
|
8265
7730
|
}
|
|
8266
7731
|
const moduleToRun = devShim?.module || modulePath;
|
|
8267
7732
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
8268
7733
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
8269
|
-
(0,
|
|
7734
|
+
(0, import_build_utils12.debug)(
|
|
8270
7735
|
`Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
|
|
8271
7736
|
);
|
|
8272
7737
|
if (process.stdout.columns) {
|
|
@@ -8320,7 +7785,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
8320
7785
|
};
|
|
8321
7786
|
|
|
8322
7787
|
// src/quirks/index.ts
|
|
8323
|
-
var
|
|
7788
|
+
var import_build_utils15 = require("@vercel/build-utils");
|
|
8324
7789
|
var import_python_analysis8 = require("@vercel/python-analysis");
|
|
8325
7790
|
|
|
8326
7791
|
// src/quirks/matplotlib.ts
|
|
@@ -8334,9 +7799,9 @@ var matplotlibQuirk = {
|
|
|
8334
7799
|
};
|
|
8335
7800
|
|
|
8336
7801
|
// src/quirks/litellm.ts
|
|
8337
|
-
var
|
|
8338
|
-
var
|
|
8339
|
-
var
|
|
7802
|
+
var import_fs10 = __toESM(require("fs"));
|
|
7803
|
+
var import_path10 = require("path");
|
|
7804
|
+
var import_build_utils13 = require("@vercel/build-utils");
|
|
8340
7805
|
var LAMBDA_ROOT = "/var/task";
|
|
8341
7806
|
var CONFIG_CANDIDATES = [
|
|
8342
7807
|
"litellm_config.yaml",
|
|
@@ -8346,9 +7811,9 @@ var CONFIG_CANDIDATES = [
|
|
|
8346
7811
|
];
|
|
8347
7812
|
async function findConfigFile(workPath) {
|
|
8348
7813
|
for (const name of CONFIG_CANDIDATES) {
|
|
8349
|
-
const candidate = (0,
|
|
7814
|
+
const candidate = (0, import_path10.join)(workPath, name);
|
|
8350
7815
|
try {
|
|
8351
|
-
await
|
|
7816
|
+
await import_fs10.default.promises.access(candidate);
|
|
8352
7817
|
return name;
|
|
8353
7818
|
} catch {
|
|
8354
7819
|
}
|
|
@@ -8363,32 +7828,32 @@ var litellmQuirk = {
|
|
|
8363
7828
|
const env = {};
|
|
8364
7829
|
const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
|
|
8365
7830
|
for (const sitePackages of sitePackagesDirs) {
|
|
8366
|
-
const schemaPath = (0,
|
|
7831
|
+
const schemaPath = (0, import_path10.join)(
|
|
8367
7832
|
sitePackages,
|
|
8368
7833
|
"litellm",
|
|
8369
7834
|
"proxy",
|
|
8370
7835
|
"schema.prisma"
|
|
8371
7836
|
);
|
|
8372
7837
|
try {
|
|
8373
|
-
await
|
|
8374
|
-
(0,
|
|
7838
|
+
await import_fs10.default.promises.access(schemaPath);
|
|
7839
|
+
(0, import_build_utils13.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
|
|
8375
7840
|
buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
|
|
8376
7841
|
break;
|
|
8377
7842
|
} catch {
|
|
8378
7843
|
}
|
|
8379
7844
|
}
|
|
8380
7845
|
if (!buildEnv.PRISMA_SCHEMA_PATH) {
|
|
8381
|
-
(0,
|
|
7846
|
+
(0, import_build_utils13.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
|
|
8382
7847
|
}
|
|
8383
7848
|
if (!process.env.CONFIG_FILE_PATH) {
|
|
8384
7849
|
const configName = await findConfigFile(ctx.workPath);
|
|
8385
7850
|
if (configName) {
|
|
8386
|
-
(0,
|
|
8387
|
-
buildEnv.CONFIG_FILE_PATH = (0,
|
|
8388
|
-
env.CONFIG_FILE_PATH = (0,
|
|
7851
|
+
(0, import_build_utils13.debug)(`LiteLLM quirk: found config at ${configName}`);
|
|
7852
|
+
buildEnv.CONFIG_FILE_PATH = (0, import_path10.join)(ctx.workPath, configName);
|
|
7853
|
+
env.CONFIG_FILE_PATH = (0, import_path10.join)(LAMBDA_ROOT, configName);
|
|
8389
7854
|
}
|
|
8390
7855
|
} else {
|
|
8391
|
-
(0,
|
|
7856
|
+
(0, import_build_utils13.debug)(
|
|
8392
7857
|
`LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
|
|
8393
7858
|
);
|
|
8394
7859
|
}
|
|
@@ -8397,10 +7862,10 @@ var litellmQuirk = {
|
|
|
8397
7862
|
};
|
|
8398
7863
|
|
|
8399
7864
|
// src/quirks/prisma.ts
|
|
8400
|
-
var
|
|
8401
|
-
var
|
|
8402
|
-
var
|
|
8403
|
-
var
|
|
7865
|
+
var import_fs11 = __toESM(require("fs"));
|
|
7866
|
+
var import_path11 = require("path");
|
|
7867
|
+
var import_execa5 = __toESM(require_execa());
|
|
7868
|
+
var import_build_utils14 = require("@vercel/build-utils");
|
|
8404
7869
|
var import_python_analysis7 = require("@vercel/python-analysis");
|
|
8405
7870
|
function execErrorMessage(err) {
|
|
8406
7871
|
if (err != null && typeof err === "object" && "stderr" in err) {
|
|
@@ -8438,22 +7903,22 @@ model DummyModel {
|
|
|
8438
7903
|
async function findUserSchema(workPath) {
|
|
8439
7904
|
const envPath = process.env.PRISMA_SCHEMA_PATH;
|
|
8440
7905
|
if (envPath) {
|
|
8441
|
-
const resolved = (0,
|
|
7906
|
+
const resolved = (0, import_path11.isAbsolute)(envPath) ? envPath : (0, import_path11.join)(workPath, envPath);
|
|
8442
7907
|
try {
|
|
8443
|
-
await
|
|
7908
|
+
await import_fs11.default.promises.access(resolved);
|
|
8444
7909
|
return resolved;
|
|
8445
7910
|
} catch {
|
|
8446
|
-
(0,
|
|
7911
|
+
(0, import_build_utils14.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
|
|
8447
7912
|
return null;
|
|
8448
7913
|
}
|
|
8449
7914
|
}
|
|
8450
7915
|
const candidates = [
|
|
8451
|
-
(0,
|
|
8452
|
-
(0,
|
|
7916
|
+
(0, import_path11.join)(workPath, "schema.prisma"),
|
|
7917
|
+
(0, import_path11.join)(workPath, "prisma", "schema.prisma")
|
|
8453
7918
|
];
|
|
8454
7919
|
for (const candidate of candidates) {
|
|
8455
7920
|
try {
|
|
8456
|
-
await
|
|
7921
|
+
await import_fs11.default.promises.access(candidate);
|
|
8457
7922
|
return candidate;
|
|
8458
7923
|
} catch {
|
|
8459
7924
|
}
|
|
@@ -8464,32 +7929,32 @@ async function collectFiles(dir, base) {
|
|
|
8464
7929
|
const result = [];
|
|
8465
7930
|
let entries;
|
|
8466
7931
|
try {
|
|
8467
|
-
entries = await
|
|
7932
|
+
entries = await import_fs11.default.promises.readdir(dir, { withFileTypes: true });
|
|
8468
7933
|
} catch {
|
|
8469
7934
|
return result;
|
|
8470
7935
|
}
|
|
8471
7936
|
for (const entry of entries) {
|
|
8472
7937
|
if (entry.name === "__pycache__")
|
|
8473
7938
|
continue;
|
|
8474
|
-
const full = (0,
|
|
7939
|
+
const full = (0, import_path11.join)(dir, entry.name);
|
|
8475
7940
|
if (entry.isDirectory()) {
|
|
8476
7941
|
result.push(...await collectFiles(full, base));
|
|
8477
7942
|
} else {
|
|
8478
|
-
result.push((0,
|
|
7943
|
+
result.push((0, import_path11.relative)(base, full));
|
|
8479
7944
|
}
|
|
8480
7945
|
}
|
|
8481
7946
|
return result;
|
|
8482
7947
|
}
|
|
8483
7948
|
async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
8484
7949
|
const paths = [
|
|
8485
|
-
(0,
|
|
8486
|
-
(0,
|
|
8487
|
-
(0,
|
|
7950
|
+
(0, import_path11.join)(cacheDir, "node_modules"),
|
|
7951
|
+
(0, import_path11.join)(cacheDir, "package.json"),
|
|
7952
|
+
(0, import_path11.join)(cacheDir, "package-lock.json"),
|
|
8488
7953
|
...extras
|
|
8489
7954
|
];
|
|
8490
7955
|
for (const p of paths) {
|
|
8491
7956
|
try {
|
|
8492
|
-
await
|
|
7957
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
8493
7958
|
} catch (err) {
|
|
8494
7959
|
console.warn(
|
|
8495
7960
|
`could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -8499,7 +7964,7 @@ async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
|
8499
7964
|
}
|
|
8500
7965
|
async function isClientGenerated(pythonPath, env) {
|
|
8501
7966
|
try {
|
|
8502
|
-
await (0,
|
|
7967
|
+
await (0, import_execa5.default)(pythonPath, ["-c", "import prisma.client"], {
|
|
8503
7968
|
env,
|
|
8504
7969
|
stdio: "pipe"
|
|
8505
7970
|
});
|
|
@@ -8513,7 +7978,7 @@ var prismaQuirk = {
|
|
|
8513
7978
|
async run(ctx) {
|
|
8514
7979
|
const { venvPath, pythonEnv, workPath } = ctx;
|
|
8515
7980
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
8516
|
-
const runtimeCacheDir = (0,
|
|
7981
|
+
const runtimeCacheDir = (0, import_path11.join)(
|
|
8517
7982
|
LAMBDA_ROOT2,
|
|
8518
7983
|
resolveVendorDir(),
|
|
8519
7984
|
"prisma",
|
|
@@ -8523,7 +7988,7 @@ var prismaQuirk = {
|
|
|
8523
7988
|
let sitePackages;
|
|
8524
7989
|
for (const dir of sitePackagesDirs) {
|
|
8525
7990
|
try {
|
|
8526
|
-
await
|
|
7991
|
+
await import_fs11.default.promises.access((0, import_path11.join)(dir, "prisma"));
|
|
8527
7992
|
sitePackages = dir;
|
|
8528
7993
|
break;
|
|
8529
7994
|
} catch {
|
|
@@ -8535,21 +8000,21 @@ var prismaQuirk = {
|
|
|
8535
8000
|
);
|
|
8536
8001
|
return {};
|
|
8537
8002
|
}
|
|
8538
|
-
const cacheDir = (0,
|
|
8539
|
-
await
|
|
8003
|
+
const cacheDir = (0, import_path11.join)(sitePackages, "prisma", "__bincache__");
|
|
8004
|
+
await import_fs11.default.promises.mkdir(cacheDir, { recursive: true });
|
|
8540
8005
|
const generateEnv = {
|
|
8541
8006
|
...pythonEnv,
|
|
8542
8007
|
PRISMA_BINARY_CACHE_DIR: cacheDir
|
|
8543
8008
|
};
|
|
8544
|
-
const generatedDir = (0,
|
|
8545
|
-
const dummySchemaPath = (0,
|
|
8546
|
-
await
|
|
8009
|
+
const generatedDir = (0, import_path11.join)(workPath, "_prisma_generated");
|
|
8010
|
+
const dummySchemaPath = (0, import_path11.join)(workPath, DUMMY_SCHEMA_NAME);
|
|
8011
|
+
await import_fs11.default.promises.writeFile(
|
|
8547
8012
|
dummySchemaPath,
|
|
8548
8013
|
buildDummySchema(generatedDir)
|
|
8549
8014
|
);
|
|
8550
|
-
(0,
|
|
8015
|
+
(0, import_build_utils14.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
|
|
8551
8016
|
try {
|
|
8552
|
-
const dummyResult = await (0,
|
|
8017
|
+
const dummyResult = await (0, import_execa5.default)(
|
|
8553
8018
|
pythonPath,
|
|
8554
8019
|
["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
|
|
8555
8020
|
{
|
|
@@ -8559,11 +8024,11 @@ var prismaQuirk = {
|
|
|
8559
8024
|
}
|
|
8560
8025
|
);
|
|
8561
8026
|
if (dummyResult.stdout)
|
|
8562
|
-
(0,
|
|
8027
|
+
(0, import_build_utils14.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
|
|
8563
8028
|
if (dummyResult.stderr)
|
|
8564
|
-
(0,
|
|
8029
|
+
(0, import_build_utils14.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
|
|
8565
8030
|
} catch (err) {
|
|
8566
|
-
throw new
|
|
8031
|
+
throw new import_build_utils14.NowBuildError({
|
|
8567
8032
|
code: "PRISMA_GENERATE_FAILED",
|
|
8568
8033
|
message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
|
|
8569
8034
|
` + execErrorMessage(err)
|
|
@@ -8571,47 +8036,47 @@ var prismaQuirk = {
|
|
|
8571
8036
|
}
|
|
8572
8037
|
const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
|
|
8573
8038
|
const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
|
|
8574
|
-
const nodeModulesDir = (0,
|
|
8039
|
+
const nodeModulesDir = (0, import_path11.join)(cacheDir, "node_modules", "prisma");
|
|
8575
8040
|
let engineCopied = false;
|
|
8576
8041
|
try {
|
|
8577
|
-
const entries = await
|
|
8042
|
+
const entries = await import_fs11.default.promises.readdir(nodeModulesDir);
|
|
8578
8043
|
for (const entry of entries) {
|
|
8579
8044
|
if (!entry.startsWith(srcBinaryPrefix))
|
|
8580
8045
|
continue;
|
|
8581
|
-
const srcPath = (0,
|
|
8582
|
-
const destPath = (0,
|
|
8046
|
+
const srcPath = (0, import_path11.join)(nodeModulesDir, entry);
|
|
8047
|
+
const destPath = (0, import_path11.join)(cacheDir, runtimeName);
|
|
8583
8048
|
try {
|
|
8584
|
-
await
|
|
8585
|
-
(0,
|
|
8049
|
+
await import_fs11.default.promises.access(destPath);
|
|
8050
|
+
(0, import_build_utils14.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
|
|
8586
8051
|
} catch {
|
|
8587
|
-
(0,
|
|
8588
|
-
await
|
|
8052
|
+
(0, import_build_utils14.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
|
|
8053
|
+
await import_fs11.default.promises.copyFile(srcPath, destPath);
|
|
8589
8054
|
}
|
|
8590
8055
|
engineCopied = true;
|
|
8591
8056
|
}
|
|
8592
8057
|
} catch (err) {
|
|
8593
|
-
throw new
|
|
8058
|
+
throw new import_build_utils14.NowBuildError({
|
|
8594
8059
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
8595
8060
|
message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
|
|
8596
8061
|
` + (err instanceof Error ? err.message : String(err))
|
|
8597
8062
|
});
|
|
8598
8063
|
}
|
|
8599
8064
|
if (!engineCopied) {
|
|
8600
|
-
throw new
|
|
8065
|
+
throw new import_build_utils14.NowBuildError({
|
|
8601
8066
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
8602
8067
|
message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
|
|
8603
8068
|
});
|
|
8604
8069
|
}
|
|
8605
|
-
const shimPath = (0,
|
|
8606
|
-
await
|
|
8070
|
+
const shimPath = (0, import_path11.join)(cacheDir, "openssl");
|
|
8071
|
+
await import_fs11.default.promises.writeFile(
|
|
8607
8072
|
shimPath,
|
|
8608
8073
|
`#!/bin/sh
|
|
8609
8074
|
echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
|
|
8610
8075
|
`
|
|
8611
8076
|
);
|
|
8612
|
-
await
|
|
8077
|
+
await import_fs11.default.promises.chmod(shimPath, 493);
|
|
8613
8078
|
for (const p of [generatedDir, dummySchemaPath]) {
|
|
8614
|
-
await
|
|
8079
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
8615
8080
|
}
|
|
8616
8081
|
await cleanCacheArtifacts(cacheDir);
|
|
8617
8082
|
const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
|
|
@@ -8624,16 +8089,16 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
8624
8089
|
pythonEnv
|
|
8625
8090
|
);
|
|
8626
8091
|
if (clientAlreadyGenerated) {
|
|
8627
|
-
(0,
|
|
8092
|
+
(0, import_build_utils14.debug)(
|
|
8628
8093
|
"Prisma quirk: client already generated, skipping user schema generate"
|
|
8629
8094
|
);
|
|
8630
8095
|
shouldGenerate = false;
|
|
8631
8096
|
}
|
|
8632
8097
|
}
|
|
8633
8098
|
if (shouldGenerate) {
|
|
8634
|
-
(0,
|
|
8099
|
+
(0, import_build_utils14.debug)(`Running prisma generate with user schema: ${userSchema}`);
|
|
8635
8100
|
try {
|
|
8636
|
-
const userResult = await (0,
|
|
8101
|
+
const userResult = await (0, import_execa5.default)(
|
|
8637
8102
|
pythonPath,
|
|
8638
8103
|
["-m", "prisma", "generate", `--schema=${userSchema}`],
|
|
8639
8104
|
{
|
|
@@ -8643,11 +8108,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
8643
8108
|
}
|
|
8644
8109
|
);
|
|
8645
8110
|
if (userResult.stdout)
|
|
8646
|
-
(0,
|
|
8111
|
+
(0, import_build_utils14.debug)(`prisma generate stdout: ${userResult.stdout}`);
|
|
8647
8112
|
if (userResult.stderr)
|
|
8648
|
-
(0,
|
|
8113
|
+
(0, import_build_utils14.debug)(`prisma generate stderr: ${userResult.stderr}`);
|
|
8649
8114
|
} catch (err) {
|
|
8650
|
-
throw new
|
|
8115
|
+
throw new import_build_utils14.NowBuildError({
|
|
8651
8116
|
code: "PRISMA_GENERATE_FAILED",
|
|
8652
8117
|
message: `\`prisma generate\` failed for schema "${userSchema}".
|
|
8653
8118
|
` + execErrorMessage(err)
|
|
@@ -8658,12 +8123,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
8658
8123
|
}
|
|
8659
8124
|
try {
|
|
8660
8125
|
const allFiles = await collectFiles(
|
|
8661
|
-
(0,
|
|
8126
|
+
(0, import_path11.join)(sitePackages, "prisma"),
|
|
8662
8127
|
sitePackages
|
|
8663
8128
|
);
|
|
8664
8129
|
const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
|
|
8665
8130
|
if (count > 0) {
|
|
8666
|
-
(0,
|
|
8131
|
+
(0, import_build_utils14.debug)(`Appended ${count} entries to prisma RECORD`);
|
|
8667
8132
|
}
|
|
8668
8133
|
} catch (err) {
|
|
8669
8134
|
console.warn(
|
|
@@ -8757,13 +8222,13 @@ async function runQuirks(ctx) {
|
|
|
8757
8222
|
(0, import_python_analysis8.normalizePackageName)(quirk.dependency)
|
|
8758
8223
|
);
|
|
8759
8224
|
if (!installed) {
|
|
8760
|
-
(0,
|
|
8225
|
+
(0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
|
|
8761
8226
|
}
|
|
8762
8227
|
return installed;
|
|
8763
8228
|
});
|
|
8764
8229
|
const sorted = toposortQuirks(activated);
|
|
8765
8230
|
for (const quirk of sorted) {
|
|
8766
|
-
(0,
|
|
8231
|
+
(0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
|
|
8767
8232
|
const result = await quirk.run(ctx);
|
|
8768
8233
|
if (result.env) {
|
|
8769
8234
|
Object.assign(mergedEnv, result.env);
|
|
@@ -8784,14 +8249,14 @@ async function runQuirks(ctx) {
|
|
|
8784
8249
|
}
|
|
8785
8250
|
|
|
8786
8251
|
// src/django.ts
|
|
8787
|
-
var
|
|
8788
|
-
var
|
|
8789
|
-
var
|
|
8790
|
-
var
|
|
8791
|
-
var scriptPath2 = (0,
|
|
8792
|
-
var script2 =
|
|
8252
|
+
var import_fs12 = __toESM(require("fs"));
|
|
8253
|
+
var import_path12 = require("path");
|
|
8254
|
+
var import_execa6 = __toESM(require_execa());
|
|
8255
|
+
var import_build_utils16 = require("@vercel/build-utils");
|
|
8256
|
+
var scriptPath2 = (0, import_path12.join)(__dirname, "..", "templates", "vc_django_settings.py");
|
|
8257
|
+
var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
|
|
8793
8258
|
async function getDjangoSettings(projectDir, env) {
|
|
8794
|
-
const { stdout } = await (0,
|
|
8259
|
+
const { stdout } = await (0, import_execa6.default)("python", ["-c", script2], {
|
|
8795
8260
|
env,
|
|
8796
8261
|
cwd: projectDir
|
|
8797
8262
|
});
|
|
@@ -8817,21 +8282,21 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
8817
8282
|
const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
|
|
8818
8283
|
const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
|
|
8819
8284
|
const staticSourceDirs = [
|
|
8820
|
-
...installedApps.map((app) => (0,
|
|
8285
|
+
...installedApps.map((app) => (0, import_path12.join)(djangoPath, ...app.split("."), "static")),
|
|
8821
8286
|
// TODO: Deal with optional prefixes in STATICFILES_DIRS.
|
|
8822
8287
|
...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
|
|
8823
|
-
].filter((d) =>
|
|
8288
|
+
].filter((d) => import_fs12.default.existsSync(d));
|
|
8824
8289
|
if (storageBackend.startsWith("storages.backends.")) {
|
|
8825
8290
|
console.log(
|
|
8826
8291
|
"django-storages detected \u2014 running collectstatic with original settings"
|
|
8827
8292
|
);
|
|
8828
|
-
await (0,
|
|
8293
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
8829
8294
|
env: { ...env, DJANGO_SETTINGS_MODULE: settingsModule },
|
|
8830
8295
|
cwd: djangoPath
|
|
8831
8296
|
});
|
|
8832
8297
|
return {
|
|
8833
8298
|
staticSourceDirs,
|
|
8834
|
-
staticRoot: staticRoot ? (0,
|
|
8299
|
+
staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
|
|
8835
8300
|
cdnOutputDir: null,
|
|
8836
8301
|
manifestRelPath: null
|
|
8837
8302
|
};
|
|
@@ -8843,9 +8308,9 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
8843
8308
|
return null;
|
|
8844
8309
|
}
|
|
8845
8310
|
const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
|
|
8846
|
-
const staticOutputDir = (0,
|
|
8847
|
-
await
|
|
8848
|
-
const shimPath = (0,
|
|
8311
|
+
const staticOutputDir = (0, import_path12.join)(outputStaticDir, staticUrlPath);
|
|
8312
|
+
await import_fs12.default.promises.mkdir(staticOutputDir, { recursive: true });
|
|
8313
|
+
const shimPath = (0, import_path12.join)(djangoPath, "_vercel_collectstatic_settings.py");
|
|
8849
8314
|
const shimLines = [
|
|
8850
8315
|
`from ${settingsModule} import *`,
|
|
8851
8316
|
`STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
|
|
@@ -8853,10 +8318,10 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
8853
8318
|
if (whitenoiseUseFinders) {
|
|
8854
8319
|
shimLines.push(`WHITENOISE_USE_FINDERS = False`);
|
|
8855
8320
|
}
|
|
8856
|
-
await
|
|
8321
|
+
await import_fs12.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
|
|
8857
8322
|
try {
|
|
8858
8323
|
console.log("Running collectstatic...");
|
|
8859
|
-
await (0,
|
|
8324
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
8860
8325
|
env: {
|
|
8861
8326
|
...env,
|
|
8862
8327
|
DJANGO_SETTINGS_MODULE: "_vercel_collectstatic_settings"
|
|
@@ -8864,7 +8329,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
8864
8329
|
cwd: djangoPath
|
|
8865
8330
|
});
|
|
8866
8331
|
} finally {
|
|
8867
|
-
await
|
|
8332
|
+
await import_fs12.default.promises.unlink(shimPath).catch(() => {
|
|
8868
8333
|
});
|
|
8869
8334
|
}
|
|
8870
8335
|
const MANIFEST_STORAGE_BACKENDS = [
|
|
@@ -8873,64 +8338,555 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
8873
8338
|
];
|
|
8874
8339
|
let manifestRelPath = null;
|
|
8875
8340
|
if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
|
|
8876
|
-
const manifestSrc = (0,
|
|
8877
|
-
const resolvedStaticRoot = (0,
|
|
8878
|
-
const manifestDest = (0,
|
|
8879
|
-
await
|
|
8880
|
-
await
|
|
8881
|
-
manifestRelPath = (0,
|
|
8882
|
-
(0,
|
|
8341
|
+
const manifestSrc = (0, import_path12.join)(staticOutputDir, "staticfiles.json");
|
|
8342
|
+
const resolvedStaticRoot = (0, import_path12.resolve)(djangoPath, staticRoot);
|
|
8343
|
+
const manifestDest = (0, import_path12.join)(resolvedStaticRoot, "staticfiles.json");
|
|
8344
|
+
await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
|
|
8345
|
+
await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
|
|
8346
|
+
manifestRelPath = (0, import_path12.relative)(workPath, manifestDest);
|
|
8347
|
+
(0, import_build_utils16.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
|
|
8883
8348
|
}
|
|
8884
8349
|
return {
|
|
8885
8350
|
staticSourceDirs,
|
|
8886
|
-
staticRoot: staticRoot ? (0,
|
|
8351
|
+
staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
|
|
8887
8352
|
cdnOutputDir: outputStaticDir,
|
|
8888
8353
|
manifestRelPath
|
|
8889
8354
|
};
|
|
8890
8355
|
}
|
|
8891
8356
|
|
|
8892
8357
|
// src/index.ts
|
|
8893
|
-
var
|
|
8358
|
+
var import_python_analysis10 = require("@vercel/python-analysis");
|
|
8894
8359
|
|
|
8895
|
-
// src/
|
|
8896
|
-
var
|
|
8897
|
-
var
|
|
8898
|
-
var
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
var
|
|
8902
|
-
var
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
}
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8360
|
+
// src/compileall.ts
|
|
8361
|
+
var import_execa7 = __toESM(require_execa());
|
|
8362
|
+
var import_build_utils17 = require("@vercel/build-utils");
|
|
8363
|
+
var import_fs13 = __toESM(require("fs"));
|
|
8364
|
+
var import_path13 = require("path");
|
|
8365
|
+
var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
8366
|
+
var PYCACHE_PREFIX_DIR = "_vc_pycache";
|
|
8367
|
+
var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
|
|
8368
|
+
function isCompileAllFlagEnabled() {
|
|
8369
|
+
const val = process.env.VERCEL_PYTHON_COMPILEALL;
|
|
8370
|
+
if (val === void 0 || val === "")
|
|
8371
|
+
return false;
|
|
8372
|
+
const lower = val.toLowerCase();
|
|
8373
|
+
return lower === "1" || lower === "true";
|
|
8374
|
+
}
|
|
8375
|
+
function shouldCompileAll({
|
|
8376
|
+
isDev,
|
|
8377
|
+
hasCustomCommand,
|
|
8378
|
+
hasPreDeployCommand
|
|
8379
|
+
}) {
|
|
8380
|
+
if (isDev)
|
|
8381
|
+
return false;
|
|
8382
|
+
if (hasCustomCommand)
|
|
8383
|
+
return false;
|
|
8384
|
+
if (hasPreDeployCommand)
|
|
8385
|
+
return false;
|
|
8386
|
+
return isCompileAllFlagEnabled();
|
|
8387
|
+
}
|
|
8388
|
+
async function runCompileAll({
|
|
8389
|
+
pythonBin,
|
|
8390
|
+
filesOrDirectories,
|
|
8391
|
+
env,
|
|
8392
|
+
excludeRegex,
|
|
8393
|
+
pycachePrefix
|
|
8394
|
+
}) {
|
|
8395
|
+
if (filesOrDirectories.length === 0)
|
|
8396
|
+
return;
|
|
8397
|
+
const args = [
|
|
8398
|
+
"-m",
|
|
8399
|
+
"compileall",
|
|
8400
|
+
"-q",
|
|
8401
|
+
"-j",
|
|
8402
|
+
"0",
|
|
8403
|
+
"-f",
|
|
8404
|
+
"--invalidation-mode",
|
|
8405
|
+
"unchecked-hash",
|
|
8406
|
+
...excludeRegex ? ["-x", excludeRegex] : [],
|
|
8407
|
+
...filesOrDirectories
|
|
8408
|
+
];
|
|
8409
|
+
const baseEnv = env || process.env;
|
|
8410
|
+
const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
|
|
8411
|
+
try {
|
|
8412
|
+
await (0, import_execa7.default)(pythonBin, args, {
|
|
8413
|
+
env: subprocessEnv,
|
|
8414
|
+
timeout: COMPILEALL_TIMEOUT_MS
|
|
8415
|
+
});
|
|
8416
|
+
} catch (err) {
|
|
8417
|
+
(0, import_build_utils17.debug)(`compileall error details: ${JSON.stringify(err)}`);
|
|
8418
|
+
}
|
|
8419
|
+
}
|
|
8420
|
+
function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
|
|
8421
|
+
if (!pyRelPath.endsWith(".py"))
|
|
8422
|
+
return null;
|
|
8423
|
+
const lastSlash = pyRelPath.lastIndexOf("/");
|
|
8424
|
+
const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
|
|
8425
|
+
const baseName = pyRelPath.slice(lastSlash + 1, -3);
|
|
8426
|
+
return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
|
|
8427
|
+
}
|
|
8428
|
+
function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
|
|
8429
|
+
if (!pyRelPath.endsWith(".py"))
|
|
8430
|
+
return null;
|
|
8431
|
+
return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
|
|
8432
|
+
}
|
|
8433
|
+
function stripPycachePrefixRoot(head) {
|
|
8434
|
+
const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
|
|
8435
|
+
if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
|
|
8436
|
+
head = head.slice(2);
|
|
8437
|
+
}
|
|
8438
|
+
let start = 0;
|
|
8439
|
+
while (start < head.length && pycachePathSeparators.has(head[start])) {
|
|
8440
|
+
start++;
|
|
8441
|
+
}
|
|
8442
|
+
return head.slice(start);
|
|
8443
|
+
}
|
|
8444
|
+
function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
|
|
8445
|
+
const rel = derivePrefixPycRelPath(
|
|
8446
|
+
stripPycachePrefixRoot(srcAbsPath),
|
|
8447
|
+
pythonMajor,
|
|
8448
|
+
pythonMinor
|
|
8449
|
+
);
|
|
8450
|
+
if (!rel)
|
|
8451
|
+
return null;
|
|
8452
|
+
return (0, import_path13.join)(stagingDir, rel.replaceAll("/", import_path13.sep));
|
|
8453
|
+
}
|
|
8454
|
+
function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
|
|
8455
|
+
const rel = derivePrefixPycRelPath(
|
|
8456
|
+
stripPycachePrefixRoot(runtimeAbsPath),
|
|
8457
|
+
pythonMajor,
|
|
8458
|
+
pythonMinor
|
|
8459
|
+
);
|
|
8460
|
+
if (!rel)
|
|
8461
|
+
return null;
|
|
8462
|
+
return `${PYCACHE_PREFIX_DIR}/${rel}`;
|
|
8463
|
+
}
|
|
8464
|
+
var COMPILEALL_APP_EXCLUDED_DIRS = [
|
|
8465
|
+
".git",
|
|
8466
|
+
".vercel",
|
|
8467
|
+
".pnpm-store",
|
|
8468
|
+
"node_modules",
|
|
8469
|
+
".next",
|
|
8470
|
+
".nuxt",
|
|
8471
|
+
".venv",
|
|
8472
|
+
"venv",
|
|
8473
|
+
"__pycache__",
|
|
8474
|
+
".mypy_cache",
|
|
8475
|
+
".ruff_cache",
|
|
8476
|
+
"public"
|
|
8477
|
+
];
|
|
8478
|
+
function escapePythonRegex(value) {
|
|
8479
|
+
return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
8480
|
+
}
|
|
8481
|
+
function getCompileAllAppExcludeRegex(workPath) {
|
|
8482
|
+
const excludedDirs = COMPILEALL_APP_EXCLUDED_DIRS.map(escapePythonRegex).join("|");
|
|
8483
|
+
return `${escapePythonRegex(workPath)}[/\\\\](?:${excludedDirs})(?:[/\\\\]|$)`;
|
|
8484
|
+
}
|
|
8485
|
+
async function collectAppPrefixBytecodeFiles({
|
|
8486
|
+
stagingDir,
|
|
8487
|
+
workPath,
|
|
8488
|
+
files: appFiles,
|
|
8489
|
+
runtimeTaskRoot,
|
|
8490
|
+
pythonMajor,
|
|
8491
|
+
pythonMinor
|
|
8492
|
+
}) {
|
|
8493
|
+
const pending = [];
|
|
8494
|
+
for (const bundlePath of Object.keys(appFiles)) {
|
|
8495
|
+
if (!bundlePath.endsWith(".py"))
|
|
8496
|
+
continue;
|
|
8497
|
+
const stagedFsPath = deriveStagedPycFsPath(
|
|
8498
|
+
stagingDir,
|
|
8499
|
+
(0, import_path13.join)(workPath, bundlePath.replaceAll("/", import_path13.sep)),
|
|
8500
|
+
pythonMajor,
|
|
8501
|
+
pythonMinor
|
|
8502
|
+
);
|
|
8503
|
+
const pycBundlePath = derivePrefixPycBundlePath(
|
|
8504
|
+
`${runtimeTaskRoot}/${bundlePath}`,
|
|
8505
|
+
pythonMajor,
|
|
8506
|
+
pythonMinor
|
|
8507
|
+
);
|
|
8508
|
+
if (!stagedFsPath || !pycBundlePath)
|
|
8509
|
+
continue;
|
|
8510
|
+
pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
|
|
8511
|
+
}
|
|
8512
|
+
const results = await Promise.all(
|
|
8513
|
+
pending.map(async ({ bundlePath, srcFsPath }) => {
|
|
8514
|
+
try {
|
|
8515
|
+
const stats = await import_fs13.default.promises.stat(srcFsPath);
|
|
8516
|
+
return { bundlePath, srcFsPath, size: stats.size };
|
|
8517
|
+
} catch {
|
|
8518
|
+
return null;
|
|
8519
|
+
}
|
|
8520
|
+
})
|
|
8521
|
+
);
|
|
8522
|
+
const files = {};
|
|
8523
|
+
const perItemSizes = /* @__PURE__ */ new Map();
|
|
8524
|
+
let totalSize = 0;
|
|
8525
|
+
for (const result of results) {
|
|
8526
|
+
if (!result)
|
|
8527
|
+
continue;
|
|
8528
|
+
files[result.bundlePath] = new import_build_utils17.FileFsRef({
|
|
8529
|
+
fsPath: result.srcFsPath,
|
|
8530
|
+
size: result.size
|
|
8531
|
+
});
|
|
8532
|
+
perItemSizes.set(result.bundlePath, result.size);
|
|
8533
|
+
totalSize += result.size;
|
|
8534
|
+
}
|
|
8535
|
+
return { files, totalSize, perItemSizes };
|
|
8536
|
+
}
|
|
8537
|
+
async function collectAppBytecodeFiles({
|
|
8538
|
+
workPath,
|
|
8539
|
+
files: appFiles,
|
|
8540
|
+
pythonMajor,
|
|
8541
|
+
pythonMinor
|
|
8542
|
+
}) {
|
|
8543
|
+
const pending = [];
|
|
8544
|
+
for (const bundlePath of Object.keys(appFiles)) {
|
|
8545
|
+
const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
|
|
8546
|
+
if (!pycRel)
|
|
8547
|
+
continue;
|
|
8548
|
+
pending.push({
|
|
8549
|
+
bundlePath: pycRel,
|
|
8550
|
+
srcFsPath: (0, import_path13.join)(workPath, pycRel.replaceAll("/", import_path13.sep))
|
|
8551
|
+
});
|
|
8552
|
+
}
|
|
8553
|
+
const results = await Promise.all(
|
|
8554
|
+
pending.map(async ({ bundlePath, srcFsPath }) => {
|
|
8555
|
+
try {
|
|
8556
|
+
const stats = await import_fs13.default.promises.stat(srcFsPath);
|
|
8557
|
+
return { bundlePath, srcFsPath, size: stats.size };
|
|
8558
|
+
} catch {
|
|
8559
|
+
return null;
|
|
8560
|
+
}
|
|
8561
|
+
})
|
|
8562
|
+
);
|
|
8563
|
+
const files = {};
|
|
8564
|
+
const perItemSizes = /* @__PURE__ */ new Map();
|
|
8565
|
+
let totalSize = 0;
|
|
8566
|
+
for (const result of results) {
|
|
8567
|
+
if (!result)
|
|
8568
|
+
continue;
|
|
8569
|
+
files[result.bundlePath] = new import_build_utils17.FileFsRef({
|
|
8570
|
+
fsPath: result.srcFsPath,
|
|
8571
|
+
size: result.size
|
|
8572
|
+
});
|
|
8573
|
+
perItemSizes.set(result.bundlePath, result.size);
|
|
8574
|
+
totalSize += result.size;
|
|
8575
|
+
}
|
|
8576
|
+
return { files, totalSize, perItemSizes };
|
|
8577
|
+
}
|
|
8578
|
+
|
|
8579
|
+
// src/installed-distributions.ts
|
|
8580
|
+
var import_fs14 = __toESM(require("fs"));
|
|
8581
|
+
var import_path14 = require("path");
|
|
8582
|
+
var import_build_utils18 = require("@vercel/build-utils");
|
|
8583
|
+
var import_python_analysis9 = require("@vercel/python-analysis");
|
|
8584
|
+
var STRIP_BASENAMES = /* @__PURE__ */ new Set([
|
|
8585
|
+
"py.typed",
|
|
8586
|
+
"WHEEL",
|
|
8587
|
+
"INSTALLER",
|
|
8588
|
+
"direct_url.json"
|
|
8589
|
+
]);
|
|
8590
|
+
function shouldStripVendorFile(filePath) {
|
|
8591
|
+
const segments = filePath.split(import_path14.sep);
|
|
8592
|
+
if (segments.includes("__pycache__"))
|
|
8593
|
+
return true;
|
|
8594
|
+
const name = segments[segments.length - 1] ?? "";
|
|
8595
|
+
if (name.endsWith(".pyc") || name.endsWith(".pyi"))
|
|
8596
|
+
return true;
|
|
8597
|
+
if (STRIP_BASENAMES.has(name))
|
|
8598
|
+
return true;
|
|
8599
|
+
return false;
|
|
8600
|
+
}
|
|
8601
|
+
function getDistributionFileGroups({
|
|
8602
|
+
sitePackageDirs,
|
|
8603
|
+
distributions,
|
|
8604
|
+
includePackages
|
|
8605
|
+
}) {
|
|
8606
|
+
if (includePackages?.length === 0) {
|
|
8607
|
+
return [];
|
|
8608
|
+
}
|
|
8609
|
+
const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis9.normalizePackageName)) : null;
|
|
8610
|
+
const groups = [];
|
|
8611
|
+
for (const dir of sitePackageDirs) {
|
|
8612
|
+
const dirDistributions = distributions.get(dir);
|
|
8613
|
+
if (!dirDistributions)
|
|
8614
|
+
continue;
|
|
8615
|
+
const sitePackagesDir = (0, import_path14.resolve)(dir);
|
|
8616
|
+
for (const [name, distribution] of dirDistributions) {
|
|
8617
|
+
const packageName = (0, import_python_analysis9.normalizePackageName)(name);
|
|
8618
|
+
if (includeSet && !includeSet.has(packageName))
|
|
8619
|
+
continue;
|
|
8620
|
+
const files = [];
|
|
8621
|
+
for (const record of distribution.files) {
|
|
8622
|
+
const absolutePath = (0, import_path14.resolve)(
|
|
8623
|
+
sitePackagesDir,
|
|
8624
|
+
record.path.replaceAll("/", import_path14.sep)
|
|
8625
|
+
);
|
|
8626
|
+
const relativePath = (0, import_path14.relative)(sitePackagesDir, absolutePath);
|
|
8627
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path14.sep}`) || (0, import_path14.isAbsolute)(relativePath)) {
|
|
8628
|
+
continue;
|
|
8629
|
+
}
|
|
8630
|
+
files.push({ absolutePath, relativePath, record });
|
|
8631
|
+
}
|
|
8632
|
+
groups.push({ packageName, sitePackagesDir, files });
|
|
8633
|
+
}
|
|
8634
|
+
}
|
|
8635
|
+
return groups;
|
|
8636
|
+
}
|
|
8637
|
+
var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
8638
|
+
static async load({
|
|
8639
|
+
venvPath,
|
|
8640
|
+
pythonMajor,
|
|
8641
|
+
pythonMinor
|
|
8642
|
+
}) {
|
|
8643
|
+
const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
|
|
8644
|
+
const distributions = /* @__PURE__ */ new Map();
|
|
8645
|
+
for (const dir of sitePackageDirs) {
|
|
8646
|
+
try {
|
|
8647
|
+
await import_fs14.default.promises.access(dir);
|
|
8648
|
+
} catch {
|
|
8649
|
+
continue;
|
|
8650
|
+
}
|
|
8651
|
+
distributions.set(dir, await (0, import_python_analysis9.scanDistributions)(dir));
|
|
8652
|
+
}
|
|
8653
|
+
return new _InstalledPythonDistributions({
|
|
8654
|
+
sitePackageDirs,
|
|
8655
|
+
distributions,
|
|
8656
|
+
pythonMajor,
|
|
8657
|
+
pythonMinor
|
|
8658
|
+
});
|
|
8659
|
+
}
|
|
8660
|
+
constructor(options) {
|
|
8661
|
+
this.sitePackageDirs = options.sitePackageDirs;
|
|
8662
|
+
this.distributions = options.distributions;
|
|
8663
|
+
this.pythonMajor = options.pythonMajor;
|
|
8664
|
+
this.pythonMinor = options.pythonMinor;
|
|
8665
|
+
}
|
|
8666
|
+
async mirrorPackagesIntoVendor({
|
|
8667
|
+
vendorDirName,
|
|
8668
|
+
includePackages
|
|
8669
|
+
}) {
|
|
8670
|
+
const pending = [];
|
|
8671
|
+
const distributionGroups = getDistributionFileGroups({
|
|
8672
|
+
sitePackageDirs: this.sitePackageDirs,
|
|
8673
|
+
distributions: this.distributions,
|
|
8674
|
+
includePackages
|
|
8675
|
+
});
|
|
8676
|
+
for (const { files } of distributionGroups) {
|
|
8677
|
+
for (const { absolutePath, relativePath, record } of files) {
|
|
8678
|
+
if (shouldStripVendorFile(relativePath))
|
|
8679
|
+
continue;
|
|
8680
|
+
pending.push({
|
|
8681
|
+
bundlePath: (0, import_path14.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
|
|
8682
|
+
srcFsPath: absolutePath,
|
|
8683
|
+
recordSize: record.size != null ? Number(record.size) : void 0
|
|
8684
|
+
});
|
|
8685
|
+
}
|
|
8686
|
+
}
|
|
8687
|
+
const results = await Promise.all(
|
|
8688
|
+
pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
|
|
8689
|
+
try {
|
|
8690
|
+
if (recordSize === void 0) {
|
|
8691
|
+
const stats = await import_fs14.default.promises.stat(srcFsPath);
|
|
8692
|
+
return { bundlePath, srcFsPath, size: stats.size };
|
|
8693
|
+
}
|
|
8694
|
+
await import_fs14.default.promises.access(srcFsPath);
|
|
8695
|
+
return { bundlePath, srcFsPath, size: recordSize };
|
|
8696
|
+
} catch {
|
|
8697
|
+
return null;
|
|
8698
|
+
}
|
|
8699
|
+
})
|
|
8700
|
+
);
|
|
8701
|
+
const vendorFiles = {};
|
|
8702
|
+
for (const result of results) {
|
|
8703
|
+
if (!result)
|
|
8704
|
+
continue;
|
|
8705
|
+
vendorFiles[result.bundlePath] = new import_build_utils18.FileFsRef({
|
|
8706
|
+
fsPath: result.srcFsPath,
|
|
8707
|
+
size: result.size
|
|
8708
|
+
});
|
|
8709
|
+
}
|
|
8710
|
+
(0, import_build_utils18.debug)(
|
|
8711
|
+
`Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
8712
|
+
);
|
|
8713
|
+
return vendorFiles;
|
|
8714
|
+
}
|
|
8715
|
+
async calculatePerPackageSizes() {
|
|
8716
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
8717
|
+
const distributionGroups = getDistributionFileGroups({
|
|
8718
|
+
sitePackageDirs: this.sitePackageDirs,
|
|
8719
|
+
distributions: this.distributions
|
|
8720
|
+
});
|
|
8721
|
+
for (const { packageName, files } of distributionGroups) {
|
|
8722
|
+
let knownSize = 0;
|
|
8723
|
+
const statPromises = [];
|
|
8724
|
+
for (const { absolutePath, relativePath, record } of files) {
|
|
8725
|
+
if (shouldStripVendorFile(relativePath))
|
|
8726
|
+
continue;
|
|
8727
|
+
if (record.size != null) {
|
|
8728
|
+
knownSize += Number(record.size);
|
|
8729
|
+
} else {
|
|
8730
|
+
statPromises.push(
|
|
8731
|
+
import_fs14.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
|
|
8732
|
+
);
|
|
8733
|
+
}
|
|
8734
|
+
}
|
|
8735
|
+
const statSizes = await Promise.all(statPromises);
|
|
8736
|
+
sizes.set(
|
|
8737
|
+
packageName,
|
|
8738
|
+
statSizes.reduce((total, size) => total + size, knownSize)
|
|
8739
|
+
);
|
|
8740
|
+
}
|
|
8741
|
+
return sizes;
|
|
8742
|
+
}
|
|
8743
|
+
async collectBytecodeFiles({
|
|
8744
|
+
vendorDirName,
|
|
8745
|
+
includePackages
|
|
8746
|
+
}) {
|
|
8747
|
+
if (this.pythonMajor == null || this.pythonMinor == null) {
|
|
8748
|
+
return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
|
|
8749
|
+
}
|
|
8750
|
+
const pending = [];
|
|
8751
|
+
const distributionGroups = getDistributionFileGroups({
|
|
8752
|
+
sitePackageDirs: this.sitePackageDirs,
|
|
8753
|
+
distributions: this.distributions,
|
|
8754
|
+
includePackages
|
|
8755
|
+
});
|
|
8756
|
+
for (const { packageName, sitePackagesDir, files } of distributionGroups) {
|
|
8757
|
+
for (const { relativePath } of files) {
|
|
8758
|
+
const pycRelativePath = derivePycPath(
|
|
8759
|
+
relativePath.replaceAll(import_path14.sep, "/"),
|
|
8760
|
+
this.pythonMajor,
|
|
8761
|
+
this.pythonMinor
|
|
8762
|
+
);
|
|
8763
|
+
if (!pycRelativePath)
|
|
8764
|
+
continue;
|
|
8765
|
+
const pycFilePath = pycRelativePath.replaceAll("/", import_path14.sep);
|
|
8766
|
+
pending.push({
|
|
8767
|
+
bundlePath: (0, import_path14.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
|
|
8768
|
+
srcFsPath: (0, import_path14.join)(sitePackagesDir, pycFilePath),
|
|
8769
|
+
packageName
|
|
8770
|
+
});
|
|
8771
|
+
}
|
|
8772
|
+
}
|
|
8773
|
+
const result = await this.collectExistingBytecode(pending);
|
|
8774
|
+
(0, import_build_utils18.debug)(
|
|
8775
|
+
`Collected ${Object.keys(result.files).length} bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
8776
|
+
);
|
|
8777
|
+
return result;
|
|
8778
|
+
}
|
|
8779
|
+
async collectPrefixBytecodeFiles({
|
|
8780
|
+
stagingDir,
|
|
8781
|
+
runtimeRoot,
|
|
8782
|
+
includePackages
|
|
8783
|
+
}) {
|
|
8784
|
+
if (this.pythonMajor == null || this.pythonMinor == null) {
|
|
8785
|
+
return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
|
|
8786
|
+
}
|
|
8787
|
+
const pending = [];
|
|
8788
|
+
const distributionGroups = getDistributionFileGroups({
|
|
8789
|
+
sitePackageDirs: this.sitePackageDirs,
|
|
8790
|
+
distributions: this.distributions,
|
|
8791
|
+
includePackages
|
|
8792
|
+
});
|
|
8793
|
+
for (const { packageName, files } of distributionGroups) {
|
|
8794
|
+
for (const { absolutePath, relativePath } of files) {
|
|
8795
|
+
if (!relativePath.endsWith(".py"))
|
|
8796
|
+
continue;
|
|
8797
|
+
const recordPath = relativePath.replaceAll(import_path14.sep, "/");
|
|
8798
|
+
const srcFsPath = deriveStagedPycFsPath(
|
|
8799
|
+
stagingDir,
|
|
8800
|
+
absolutePath,
|
|
8801
|
+
this.pythonMajor,
|
|
8802
|
+
this.pythonMinor
|
|
8803
|
+
);
|
|
8804
|
+
const bundlePath = derivePrefixPycBundlePath(
|
|
8805
|
+
`${runtimeRoot}/${recordPath}`,
|
|
8806
|
+
this.pythonMajor,
|
|
8807
|
+
this.pythonMinor
|
|
8808
|
+
);
|
|
8809
|
+
if (!srcFsPath || !bundlePath)
|
|
8810
|
+
continue;
|
|
8811
|
+
pending.push({ bundlePath, srcFsPath, packageName });
|
|
8812
|
+
}
|
|
8813
|
+
}
|
|
8814
|
+
const result = await this.collectExistingBytecode(pending);
|
|
8815
|
+
(0, import_build_utils18.debug)(
|
|
8816
|
+
`Collected ${Object.keys(result.files).length} prefix bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
8817
|
+
);
|
|
8818
|
+
return result;
|
|
8819
|
+
}
|
|
8820
|
+
async collectExistingBytecode(pending) {
|
|
8821
|
+
const results = await Promise.all(
|
|
8822
|
+
pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
|
|
8823
|
+
try {
|
|
8824
|
+
const stats = await import_fs14.default.promises.stat(srcFsPath);
|
|
8825
|
+
return { bundlePath, srcFsPath, size: stats.size, packageName };
|
|
8826
|
+
} catch {
|
|
8827
|
+
return null;
|
|
8828
|
+
}
|
|
8829
|
+
})
|
|
8830
|
+
);
|
|
8831
|
+
const files = {};
|
|
8832
|
+
let totalSize = 0;
|
|
8833
|
+
const perItemSizes = /* @__PURE__ */ new Map();
|
|
8834
|
+
for (const result of results) {
|
|
8835
|
+
if (!result)
|
|
8836
|
+
continue;
|
|
8837
|
+
files[result.bundlePath] = new import_build_utils18.FileFsRef({
|
|
8838
|
+
fsPath: result.srcFsPath,
|
|
8839
|
+
size: result.size
|
|
8840
|
+
});
|
|
8841
|
+
totalSize += result.size;
|
|
8842
|
+
perItemSizes.set(
|
|
8843
|
+
result.packageName,
|
|
8844
|
+
(perItemSizes.get(result.packageName) ?? 0) + result.size
|
|
8845
|
+
);
|
|
8846
|
+
}
|
|
8847
|
+
return { files, totalSize, perItemSizes };
|
|
8848
|
+
}
|
|
8849
|
+
};
|
|
8850
|
+
|
|
8851
|
+
// src/subscribers.ts
|
|
8852
|
+
var import_path16 = require("path");
|
|
8853
|
+
var import_fs16 = __toESM(require("fs"));
|
|
8854
|
+
var import_build_utils19 = require("@vercel/build-utils");
|
|
8855
|
+
|
|
8856
|
+
// src/module-entrypoint.ts
|
|
8857
|
+
var import_path15 = require("path");
|
|
8858
|
+
var import_fs15 = __toESM(require("fs"));
|
|
8859
|
+
var MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
|
|
8860
|
+
function parseModuleEntrypoint(value) {
|
|
8861
|
+
const match = MODULE_ATTR_RE.exec(value);
|
|
8862
|
+
if (!match) {
|
|
8863
|
+
return null;
|
|
8864
|
+
}
|
|
8865
|
+
return {
|
|
8866
|
+
moduleName: match[1],
|
|
8867
|
+
variableName: match[2],
|
|
8868
|
+
filePath: `${match[1].replace(/\./g, "/")}.py`
|
|
8869
|
+
};
|
|
8870
|
+
}
|
|
8871
|
+
function getModuleEntrypointName({
|
|
8872
|
+
moduleName,
|
|
8873
|
+
variableName
|
|
8874
|
+
}) {
|
|
8875
|
+
return `${moduleName.replace(/\./g, "-")}_${variableName}`;
|
|
8876
|
+
}
|
|
8877
|
+
function safePathSegment(value) {
|
|
8878
|
+
return [...value].map((char) => {
|
|
8879
|
+
if (char === "_") {
|
|
8880
|
+
return "__";
|
|
8881
|
+
}
|
|
8882
|
+
return /[A-Za-z0-9-]/.test(char) ? char : `_${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`;
|
|
8927
8883
|
}).join("");
|
|
8928
8884
|
}
|
|
8929
8885
|
async function resolveExistingEntrypoint(workPath, filePath) {
|
|
8930
8886
|
const candidates = [filePath, filePath.replace(/\.py$/i, "/__init__.py")];
|
|
8931
8887
|
for (const candidate of candidates) {
|
|
8932
8888
|
try {
|
|
8933
|
-
const stat = await
|
|
8889
|
+
const stat = await import_fs15.default.promises.stat((0, import_path15.join)(workPath, candidate));
|
|
8934
8890
|
if (stat.isFile()) {
|
|
8935
8891
|
return candidate;
|
|
8936
8892
|
}
|
|
@@ -8977,14 +8933,14 @@ function getSubscriberOutputPath(subscriberName) {
|
|
|
8977
8933
|
return `${SUBSCRIBER_OUTPUT_DIR}/${safePathSegment(subscriberName)}`;
|
|
8978
8934
|
}
|
|
8979
8935
|
function getSubscriberConsumerName(subscriberName) {
|
|
8980
|
-
return (0,
|
|
8936
|
+
return (0, import_build_utils19.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
|
|
8981
8937
|
}
|
|
8982
8938
|
async function getPyprojectSubscribers(workPath) {
|
|
8983
|
-
const pyprojectPath = (0,
|
|
8984
|
-
if (!
|
|
8939
|
+
const pyprojectPath = (0, import_path16.join)(workPath, "pyproject.toml");
|
|
8940
|
+
if (!import_fs16.default.existsSync(pyprojectPath)) {
|
|
8985
8941
|
return [];
|
|
8986
8942
|
}
|
|
8987
|
-
const pyproject = await (0,
|
|
8943
|
+
const pyproject = await (0, import_build_utils19.readConfigFile)(pyprojectPath);
|
|
8988
8944
|
const subscribers = pyproject?.tool?.vercel?.subscribers;
|
|
8989
8945
|
if (!subscribers) {
|
|
8990
8946
|
return [];
|
|
@@ -9076,16 +9032,16 @@ function parseTriggerDefaults(subscriber, config) {
|
|
|
9076
9032
|
return defaults;
|
|
9077
9033
|
}
|
|
9078
9034
|
function subscriberError(message) {
|
|
9079
|
-
return new
|
|
9035
|
+
return new import_build_utils19.NowBuildError({
|
|
9080
9036
|
code: "PYTHON_INVALID_SUBSCRIBER_CONFIG",
|
|
9081
9037
|
message
|
|
9082
9038
|
});
|
|
9083
9039
|
}
|
|
9084
9040
|
|
|
9085
9041
|
// src/workflows.ts
|
|
9086
|
-
var
|
|
9087
|
-
var
|
|
9088
|
-
var
|
|
9042
|
+
var import_path17 = require("path");
|
|
9043
|
+
var import_fs17 = __toESM(require("fs"));
|
|
9044
|
+
var import_build_utils20 = require("@vercel/build-utils");
|
|
9089
9045
|
var WORKFLOW_OUTPUT_DIR = "_py_workflows";
|
|
9090
9046
|
var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
|
|
9091
9047
|
var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
|
|
@@ -9093,14 +9049,14 @@ function getWorkflowOutputPath(workflowName) {
|
|
|
9093
9049
|
return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
|
|
9094
9050
|
}
|
|
9095
9051
|
function getWorkflowConsumerName(workflowName) {
|
|
9096
|
-
return (0,
|
|
9052
|
+
return (0, import_build_utils20.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
|
|
9097
9053
|
}
|
|
9098
9054
|
async function getPyprojectWorkflows(workPath) {
|
|
9099
|
-
const pyprojectPath = (0,
|
|
9100
|
-
if (!
|
|
9055
|
+
const pyprojectPath = (0, import_path17.join)(workPath, "pyproject.toml");
|
|
9056
|
+
if (!import_fs17.default.existsSync(pyprojectPath)) {
|
|
9101
9057
|
return [];
|
|
9102
9058
|
}
|
|
9103
|
-
const pyproject = await (0,
|
|
9059
|
+
const pyproject = await (0, import_build_utils20.readConfigFile)(pyprojectPath);
|
|
9104
9060
|
const workflows = pyproject?.tool?.vercel?.workflows;
|
|
9105
9061
|
if (!workflows) {
|
|
9106
9062
|
return [];
|
|
@@ -9154,14 +9110,14 @@ async function parseWorkflow(workPath, index, config) {
|
|
|
9154
9110
|
};
|
|
9155
9111
|
}
|
|
9156
9112
|
function workflowError(message) {
|
|
9157
|
-
return new
|
|
9113
|
+
return new import_build_utils20.NowBuildError({
|
|
9158
9114
|
code: "PYTHON_INVALID_WORKFLOW_CONFIG",
|
|
9159
9115
|
message
|
|
9160
9116
|
});
|
|
9161
9117
|
}
|
|
9162
9118
|
|
|
9163
9119
|
// src/index.ts
|
|
9164
|
-
var writeFile =
|
|
9120
|
+
var writeFile = import_fs18.default.promises.writeFile;
|
|
9165
9121
|
var PYTHON_ENTRYPOINT_DOCS_URL2 = "https://vercel.com/docs/functions/runtimes/python#python-entrypoints";
|
|
9166
9122
|
var version = -1;
|
|
9167
9123
|
function getDevSubscriberTopics(subscriber) {
|
|
@@ -9174,10 +9130,13 @@ function getDevSubscriberTopics(subscriber) {
|
|
|
9174
9130
|
}
|
|
9175
9131
|
async function getDevSidecars({
|
|
9176
9132
|
workPath,
|
|
9177
|
-
build: build2
|
|
9133
|
+
build: build2,
|
|
9134
|
+
service
|
|
9178
9135
|
}) {
|
|
9179
9136
|
const framework = build2.config?.framework;
|
|
9180
|
-
|
|
9137
|
+
const isPyprojectEntrypoint = (0, import_path18.basename)(build2.src ?? "") === "pyproject.toml";
|
|
9138
|
+
const isPyprojectService = service !== void 0 && (0, import_path18.basename)(service.entrypoint ?? "") === "pyproject.toml";
|
|
9139
|
+
if (build2.config?.middleware === true || service !== void 0 && !isPyprojectService || service === void 0 && !isPyprojectEntrypoint && (typeof framework !== "string" || !(0, import_build_utils21.isPythonFramework)(framework))) {
|
|
9181
9140
|
return [];
|
|
9182
9141
|
}
|
|
9183
9142
|
const subscribers = await getPyprojectSubscribers(workPath);
|
|
@@ -9189,7 +9148,7 @@ async function getDevSidecars({
|
|
|
9189
9148
|
name: subscriber.name,
|
|
9190
9149
|
consumer: getSubscriberConsumerName(subscriber.name),
|
|
9191
9150
|
workspace: ".",
|
|
9192
|
-
framework,
|
|
9151
|
+
framework: typeof framework === "string" ? framework : void 0,
|
|
9193
9152
|
runtime: "python",
|
|
9194
9153
|
builder: {
|
|
9195
9154
|
use: build2.use,
|
|
@@ -9207,7 +9166,7 @@ async function getDevSidecars({
|
|
|
9207
9166
|
name: workflow.name,
|
|
9208
9167
|
consumer: getWorkflowConsumerName(workflow.name),
|
|
9209
9168
|
workspace: ".",
|
|
9210
|
-
framework,
|
|
9169
|
+
framework: typeof framework === "string" ? framework : void 0,
|
|
9211
9170
|
runtime: "python",
|
|
9212
9171
|
builder: {
|
|
9213
9172
|
use: build2.use,
|
|
@@ -9247,7 +9206,7 @@ function addBytecodeWithinCapacity(files, bytecodeInfo, capacity) {
|
|
|
9247
9206
|
}
|
|
9248
9207
|
async function addVendorBytecodeWithinCapacity({
|
|
9249
9208
|
files,
|
|
9250
|
-
|
|
9209
|
+
installedDistributions,
|
|
9251
9210
|
vendorDir,
|
|
9252
9211
|
bytecodeInfo,
|
|
9253
9212
|
capacity
|
|
@@ -9262,7 +9221,7 @@ async function addVendorBytecodeWithinCapacity({
|
|
|
9262
9221
|
const selectedPkgs = lambdaKnapsack(bytecodeInfo.perItemSizes, capacity);
|
|
9263
9222
|
if (selectedPkgs.length === 0)
|
|
9264
9223
|
return capacity;
|
|
9265
|
-
const selectedBytecode = await
|
|
9224
|
+
const selectedBytecode = await installedDistributions.collectBytecodeFiles({
|
|
9266
9225
|
vendorDirName: vendorDir,
|
|
9267
9226
|
includePackages: selectedPkgs
|
|
9268
9227
|
});
|
|
@@ -9271,7 +9230,7 @@ async function addVendorBytecodeWithinCapacity({
|
|
|
9271
9230
|
}
|
|
9272
9231
|
async function addVendorBytecodeInTiers({
|
|
9273
9232
|
files,
|
|
9274
|
-
|
|
9233
|
+
installedDistributions,
|
|
9275
9234
|
vendorDir,
|
|
9276
9235
|
capacity,
|
|
9277
9236
|
vendorPackageTiers
|
|
@@ -9282,13 +9241,13 @@ async function addVendorBytecodeInTiers({
|
|
|
9282
9241
|
break;
|
|
9283
9242
|
if (tier && tier.length === 0)
|
|
9284
9243
|
continue;
|
|
9285
|
-
const bytecodeInfo = await
|
|
9244
|
+
const bytecodeInfo = await installedDistributions.collectBytecodeFiles({
|
|
9286
9245
|
vendorDirName: vendorDir,
|
|
9287
9246
|
includePackages: tier
|
|
9288
9247
|
});
|
|
9289
9248
|
remainingCapacity = await addVendorBytecodeWithinCapacity({
|
|
9290
9249
|
files,
|
|
9291
|
-
|
|
9250
|
+
installedDistributions,
|
|
9292
9251
|
vendorDir,
|
|
9293
9252
|
bytecodeInfo,
|
|
9294
9253
|
capacity: remainingCapacity
|
|
@@ -9330,13 +9289,13 @@ var frameworkHooks = {
|
|
|
9330
9289
|
}) => {
|
|
9331
9290
|
let baseDir = detected?.baseDir;
|
|
9332
9291
|
if (baseDir === void 0) {
|
|
9333
|
-
if (!
|
|
9334
|
-
(0,
|
|
9292
|
+
if (!import_fs18.default.existsSync((0, import_path18.join)(workPath, "manage.py"))) {
|
|
9293
|
+
(0, import_build_utils21.debug)("Django hook: no manage.py detected, skipping");
|
|
9335
9294
|
return;
|
|
9336
9295
|
}
|
|
9337
9296
|
baseDir = "";
|
|
9338
9297
|
}
|
|
9339
|
-
const djangoPath = (0,
|
|
9298
|
+
const djangoPath = (0, import_path18.join)(workPath, baseDir);
|
|
9340
9299
|
let settingsResult;
|
|
9341
9300
|
try {
|
|
9342
9301
|
settingsResult = await getDjangoSettings(djangoPath, pythonEnv);
|
|
@@ -9348,13 +9307,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
|
|
|
9348
9307
|
} else {
|
|
9349
9308
|
detail = err?.stderr || err?.message || String(err);
|
|
9350
9309
|
}
|
|
9351
|
-
throw new
|
|
9310
|
+
throw new import_build_utils21.NowBuildError({
|
|
9352
9311
|
code: "DJANGO_SETTINGS_FAILED",
|
|
9353
9312
|
message: `Failed to read Django application settings from ${djangoPath}/manage.py:
|
|
9354
9313
|
${detail}`
|
|
9355
9314
|
});
|
|
9356
9315
|
}
|
|
9357
|
-
(0,
|
|
9316
|
+
(0, import_build_utils21.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
|
|
9358
9317
|
const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
|
|
9359
9318
|
if (djangoVersion) {
|
|
9360
9319
|
console.log(`Django ${djangoVersion.join(".")} detected`);
|
|
@@ -9366,7 +9325,7 @@ ${detail}`
|
|
|
9366
9325
|
const variableName = parts.at(-1);
|
|
9367
9326
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
9368
9327
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
9369
|
-
(0,
|
|
9328
|
+
(0, import_build_utils21.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
|
|
9370
9329
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
9371
9330
|
} else {
|
|
9372
9331
|
const wsgiApp = djangoSettings["WSGI_APPLICATION"];
|
|
@@ -9375,7 +9334,7 @@ ${detail}`
|
|
|
9375
9334
|
const variableName = parts.at(-1);
|
|
9376
9335
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
9377
9336
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
9378
|
-
(0,
|
|
9337
|
+
(0, import_build_utils21.debug)(
|
|
9379
9338
|
`Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
|
|
9380
9339
|
);
|
|
9381
9340
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
@@ -9383,7 +9342,7 @@ ${detail}`
|
|
|
9383
9342
|
}
|
|
9384
9343
|
let djangoStatic = null;
|
|
9385
9344
|
if (workPath && venvPath) {
|
|
9386
|
-
const outputStaticDir = (0,
|
|
9345
|
+
const outputStaticDir = (0, import_path18.join)(workPath, ".vercel", "output", "static");
|
|
9387
9346
|
djangoStatic = await runDjangoCollectStatic(
|
|
9388
9347
|
venvPath,
|
|
9389
9348
|
workPath,
|
|
@@ -9398,7 +9357,7 @@ ${detail}`
|
|
|
9398
9357
|
return {
|
|
9399
9358
|
entrypoint: resolvedEntrypoint,
|
|
9400
9359
|
djangoStatic,
|
|
9401
|
-
extraPythonPath: baseDir ? (0,
|
|
9360
|
+
extraPythonPath: baseDir ? (0, import_path18.join)(workPath, baseDir) : void 0
|
|
9402
9361
|
};
|
|
9403
9362
|
}
|
|
9404
9363
|
};
|
|
@@ -9457,23 +9416,23 @@ async function downloadFilesInWorkPath({
|
|
|
9457
9416
|
files,
|
|
9458
9417
|
meta = {}
|
|
9459
9418
|
}) {
|
|
9460
|
-
(0,
|
|
9461
|
-
let downloadedFiles = await (0,
|
|
9419
|
+
(0, import_build_utils21.debug)("Downloading user files...");
|
|
9420
|
+
let downloadedFiles = await (0, import_build_utils21.download)(files, workPath, meta);
|
|
9462
9421
|
if (meta.isDev && entrypoint) {
|
|
9463
9422
|
const normalizedEntrypoint = entrypoint.endsWith(".py") ? entrypoint : `${entrypoint}.py`;
|
|
9464
9423
|
if (!hasProp(downloadedFiles, entrypoint) && !hasProp(downloadedFiles, normalizedEntrypoint)) {
|
|
9465
|
-
throw new
|
|
9424
|
+
throw new import_build_utils21.NowBuildError({
|
|
9466
9425
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
9467
9426
|
message: `Configured Python entrypoint "${normalizedEntrypoint}" was not found.`,
|
|
9468
9427
|
link: PYTHON_ENTRYPOINT_DOCS_URL2,
|
|
9469
9428
|
action: "Learn More"
|
|
9470
9429
|
});
|
|
9471
9430
|
}
|
|
9472
|
-
const { devCacheDir = (0,
|
|
9473
|
-
const cacheKey = (0,
|
|
9474
|
-
const destCache = (0,
|
|
9475
|
-
await (0,
|
|
9476
|
-
downloadedFiles = await (0,
|
|
9431
|
+
const { devCacheDir = (0, import_path18.join)(workPath, ".now", "cache") } = meta;
|
|
9432
|
+
const cacheKey = (0, import_path18.basename)(entrypoint).replace(/\./g, "_");
|
|
9433
|
+
const destCache = (0, import_path18.join)(devCacheDir, cacheKey);
|
|
9434
|
+
await (0, import_build_utils21.download)(downloadedFiles, destCache);
|
|
9435
|
+
downloadedFiles = await (0, import_build_utils21.glob)("**", destCache);
|
|
9477
9436
|
workPath = destCache;
|
|
9478
9437
|
}
|
|
9479
9438
|
return workPath;
|
|
@@ -9509,7 +9468,7 @@ async function getPythonLambdaOptions({
|
|
|
9509
9468
|
sources.add(entrypoint.slice(0, -".py".length));
|
|
9510
9469
|
}
|
|
9511
9470
|
for (const sourceFile of sources) {
|
|
9512
|
-
const lambdaOptions = await (0,
|
|
9471
|
+
const lambdaOptions = await (0, import_build_utils21.getLambdaOptionsFromFunction)({
|
|
9513
9472
|
sourceFile,
|
|
9514
9473
|
config
|
|
9515
9474
|
});
|
|
@@ -9529,11 +9488,11 @@ async function installInjectedPackage({
|
|
|
9529
9488
|
projectDir,
|
|
9530
9489
|
pipPlatformArgs
|
|
9531
9490
|
}) {
|
|
9532
|
-
const localDir = (0,
|
|
9533
|
-
const isLocalDev =
|
|
9491
|
+
const localDir = (0, import_path18.join)(__dirname, "..", "..", "..", "python", name);
|
|
9492
|
+
const isLocalDev = import_fs18.default.existsSync((0, import_path18.join)(localDir, "pyproject.toml"));
|
|
9534
9493
|
const dep = envOverride || (isLocalDev ? localDir : pinned);
|
|
9535
9494
|
const noExclude = ["--exclude-newer-package", `${name}=false`];
|
|
9536
|
-
(0,
|
|
9495
|
+
(0, import_build_utils21.debug)(`Installing ${dep}`);
|
|
9537
9496
|
await uv.pip({
|
|
9538
9497
|
venvPath,
|
|
9539
9498
|
projectDir,
|
|
@@ -9559,14 +9518,14 @@ var build = async ({
|
|
|
9559
9518
|
registerPreDeploy
|
|
9560
9519
|
}) => {
|
|
9561
9520
|
let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
|
|
9562
|
-
const isPyprojectEntrypoint = entrypoint !== void 0 && (0,
|
|
9521
|
+
const isPyprojectEntrypoint = entrypoint !== void 0 && (0, import_path18.basename)(entrypoint) === "pyproject.toml";
|
|
9563
9522
|
if (isPyprojectEntrypoint && entrypoint !== "pyproject.toml") {
|
|
9564
|
-
throw new
|
|
9523
|
+
throw new import_build_utils21.NowBuildError({
|
|
9565
9524
|
code: "PYTHON_INVALID_PYPROJECT_ENTRYPOINT",
|
|
9566
|
-
message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0,
|
|
9525
|
+
message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0, import_path18.dirname)(entrypoint)}" and use entrypoint "pyproject.toml".`
|
|
9567
9526
|
});
|
|
9568
9527
|
}
|
|
9569
|
-
const builderSpan = parentSpan ?? new
|
|
9528
|
+
const builderSpan = parentSpan ?? new import_build_utils21.Span({ name: "vc.builder" });
|
|
9570
9529
|
const framework = config?.framework;
|
|
9571
9530
|
let shouldInstallVercelWorkers = config?.hasWorkerServices === true;
|
|
9572
9531
|
let subscribers = [];
|
|
@@ -9575,21 +9534,21 @@ var build = async ({
|
|
|
9575
9534
|
let projectInstallCommand;
|
|
9576
9535
|
let hasCustomCommand = false;
|
|
9577
9536
|
const target = getTargetPlatform(meta.isDev ?? false);
|
|
9578
|
-
(0,
|
|
9537
|
+
(0, import_build_utils21.debug)(`workPath: ${workPath}`);
|
|
9579
9538
|
workPath = await downloadFilesInWorkPath({
|
|
9580
9539
|
workPath,
|
|
9581
9540
|
files: originalFiles,
|
|
9582
9541
|
entrypoint,
|
|
9583
9542
|
meta
|
|
9584
9543
|
});
|
|
9585
|
-
if (isPyprojectEntrypoint || !service && (0,
|
|
9544
|
+
if (isPyprojectEntrypoint || !service && (0, import_build_utils21.isPythonFramework)(framework)) {
|
|
9586
9545
|
subscribers = await getPyprojectSubscribers(workPath);
|
|
9587
9546
|
workflows = await getPyprojectWorkflows(workPath);
|
|
9588
9547
|
shouldInstallVercelWorkers ||= subscribers.length > 0 || workflows.length > 0;
|
|
9589
9548
|
}
|
|
9590
9549
|
try {
|
|
9591
9550
|
if (meta.isDev) {
|
|
9592
|
-
const setupCfg = (0,
|
|
9551
|
+
const setupCfg = (0, import_path18.join)(workPath, "setup.cfg");
|
|
9593
9552
|
await writeFile(setupCfg, "[install]\nprefix=\n");
|
|
9594
9553
|
}
|
|
9595
9554
|
} catch (err) {
|
|
@@ -9603,7 +9562,7 @@ var build = async ({
|
|
|
9603
9562
|
if (declared) {
|
|
9604
9563
|
detected = { entrypoint: declared };
|
|
9605
9564
|
} else if (subscribers.length === 0 && workflows.length === 0) {
|
|
9606
|
-
throw new
|
|
9565
|
+
throw new import_build_utils21.NowBuildError({
|
|
9607
9566
|
code: "PYTHON_PYPROJECT_NOTHING_TO_BUILD",
|
|
9608
9567
|
message: 'Entrypoint "pyproject.toml" declares nothing to build. Set "tool.vercel.entrypoint" for a web app and/or declare "[[tool.vercel.subscribers]]" or "[[tool.vercel.workflows]]" entries in pyproject.toml.'
|
|
9609
9568
|
});
|
|
@@ -9617,7 +9576,7 @@ var build = async ({
|
|
|
9617
9576
|
filePath: entrypoint,
|
|
9618
9577
|
// For schedule-triggered jobs, the WSGI variable is always 'app' (created dynamically).
|
|
9619
9578
|
// For other services, handlerFunction is used as the entrypoint variable name.
|
|
9620
|
-
varName: service && (0,
|
|
9579
|
+
varName: service && (0, import_build_utils21.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
|
|
9621
9580
|
} : void 0,
|
|
9622
9581
|
service,
|
|
9623
9582
|
repoRootPath
|
|
@@ -9626,8 +9585,8 @@ var build = async ({
|
|
|
9626
9585
|
if (detected?.error && detected?.baseDir === void 0) {
|
|
9627
9586
|
throw detected?.error;
|
|
9628
9587
|
}
|
|
9629
|
-
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0,
|
|
9630
|
-
const entrypointAbsDir = (0,
|
|
9588
|
+
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path18.dirname)(entrypoint) : ".");
|
|
9589
|
+
const entrypointAbsDir = (0, import_path18.join)(workPath, entryDirectory);
|
|
9631
9590
|
const rootDir = repoRootPath ?? workPath;
|
|
9632
9591
|
const pythonPackage = await builderSpan.child("vc.builder.python.discover").trace(
|
|
9633
9592
|
() => discoverPackage({
|
|
@@ -9668,12 +9627,12 @@ var build = async ({
|
|
|
9668
9627
|
}
|
|
9669
9628
|
const uvVersion = checkUvBinaryVersion(uv.getPath());
|
|
9670
9629
|
console.log(`Using ${uvVersion}`);
|
|
9671
|
-
const venvPath = service?.name ? (0,
|
|
9672
|
-
const hasCachedVenv =
|
|
9673
|
-
const hasCachedUv =
|
|
9630
|
+
const venvPath = service?.name ? (0, import_path18.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path18.join)(workPath, ".vercel", "python", ".venv");
|
|
9631
|
+
const hasCachedVenv = import_fs18.default.existsSync((0, import_path18.join)(venvPath, "pyvenv.cfg"));
|
|
9632
|
+
const hasCachedUv = import_fs18.default.existsSync(uvCacheDir);
|
|
9674
9633
|
const restoredCache = hasCachedVenv && hasCachedUv ? "both" : hasCachedVenv ? "venv" : hasCachedUv ? "uv" : "none";
|
|
9675
9634
|
if (hasCachedVenv || hasCachedUv) {
|
|
9676
|
-
(0,
|
|
9635
|
+
(0, import_build_utils21.debug)(
|
|
9677
9636
|
`Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
|
|
9678
9637
|
);
|
|
9679
9638
|
}
|
|
@@ -9685,14 +9644,14 @@ var build = async ({
|
|
|
9685
9644
|
uvCacheDir
|
|
9686
9645
|
});
|
|
9687
9646
|
});
|
|
9688
|
-
if ((0,
|
|
9647
|
+
if ((0, import_build_utils21.isPythonFramework)(framework)) {
|
|
9689
9648
|
const {
|
|
9690
9649
|
cliType,
|
|
9691
9650
|
lockfileVersion,
|
|
9692
9651
|
packageJsonPackageManager,
|
|
9693
9652
|
turboSupportsCorepackHome
|
|
9694
|
-
} = await (0,
|
|
9695
|
-
spawnEnv = (0,
|
|
9653
|
+
} = await (0, import_build_utils21.scanParentDirs)(workPath, true);
|
|
9654
|
+
spawnEnv = (0, import_build_utils21.getEnvForPackageManager)({
|
|
9696
9655
|
cliType,
|
|
9697
9656
|
lockfileVersion,
|
|
9698
9657
|
packageJsonPackageManager,
|
|
@@ -9717,13 +9676,13 @@ var build = async ({
|
|
|
9717
9676
|
let uvLockPath = null;
|
|
9718
9677
|
let uvProjectDir = null;
|
|
9719
9678
|
let projectName;
|
|
9720
|
-
await builderSpan.child(
|
|
9679
|
+
await builderSpan.child(import_build_utils21.BUILDER_INSTALLER_STEP, {
|
|
9721
9680
|
installCommand: projectInstallCommand || void 0,
|
|
9722
9681
|
runtime: "python",
|
|
9723
9682
|
"python.cache.restored": restoredCache
|
|
9724
9683
|
}).trace(async () => {
|
|
9725
9684
|
if (projectInstallCommand) {
|
|
9726
|
-
await
|
|
9685
|
+
await import_fs18.default.promises.rm(venvPath, { recursive: true, force: true });
|
|
9727
9686
|
await ensureVenv({
|
|
9728
9687
|
pythonVersion,
|
|
9729
9688
|
venvPath,
|
|
@@ -9734,7 +9693,7 @@ var build = async ({
|
|
|
9734
9693
|
console.log(
|
|
9735
9694
|
`Running "install" command: \`${projectInstallCommand}\`...`
|
|
9736
9695
|
);
|
|
9737
|
-
await (0,
|
|
9696
|
+
await (0, import_build_utils21.execCommand)(projectInstallCommand, {
|
|
9738
9697
|
env: pythonEnv,
|
|
9739
9698
|
cwd: workPath
|
|
9740
9699
|
});
|
|
@@ -9755,7 +9714,7 @@ var build = async ({
|
|
|
9755
9714
|
}
|
|
9756
9715
|
if (!assumeDepsInstalled) {
|
|
9757
9716
|
const lockCacheKey = service?.name ? `uv.lock.${service.name}` : "uv.lock";
|
|
9758
|
-
const cachedLockPath = (0,
|
|
9717
|
+
const cachedLockPath = (0, import_path18.join)(uvCacheDir, lockCacheKey);
|
|
9759
9718
|
const { projectDir, lockPath, lockFileProvidedByUser } = await ensureUvProject({
|
|
9760
9719
|
workPath,
|
|
9761
9720
|
rootDir,
|
|
@@ -9776,21 +9735,21 @@ var build = async ({
|
|
|
9776
9735
|
locked: !lockFileProvidedByUser,
|
|
9777
9736
|
pythonPlatform: target.uvPlatform
|
|
9778
9737
|
});
|
|
9779
|
-
if (lockPath &&
|
|
9780
|
-
await
|
|
9781
|
-
await
|
|
9738
|
+
if (lockPath && import_fs18.default.existsSync(lockPath)) {
|
|
9739
|
+
await import_fs18.default.promises.mkdir(uvCacheDir, { recursive: true });
|
|
9740
|
+
await import_fs18.default.promises.copyFile(lockPath, cachedLockPath);
|
|
9782
9741
|
}
|
|
9783
9742
|
}
|
|
9784
9743
|
});
|
|
9785
|
-
if ((0,
|
|
9744
|
+
if ((0, import_build_utils21.isPythonFramework)(framework)) {
|
|
9786
9745
|
const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
|
|
9787
9746
|
config?.buildCommand;
|
|
9788
|
-
await builderSpan.child(
|
|
9747
|
+
await builderSpan.child(import_build_utils21.BUILDER_COMPILE_STEP, {
|
|
9789
9748
|
buildCommand: projectBuildCommand || void 0
|
|
9790
9749
|
}).trace(async () => {
|
|
9791
9750
|
if (projectBuildCommand) {
|
|
9792
9751
|
console.log(`Running "${projectBuildCommand}"`);
|
|
9793
|
-
await (0,
|
|
9752
|
+
await (0, import_build_utils21.execCommand)(projectBuildCommand, {
|
|
9794
9753
|
env: pythonEnv,
|
|
9795
9754
|
cwd: workPath
|
|
9796
9755
|
});
|
|
@@ -9817,7 +9776,7 @@ var build = async ({
|
|
|
9817
9776
|
entrypoint = resolved?.entrypoint;
|
|
9818
9777
|
const isWorkersOnly = !entrypoint && isPyprojectEntrypoint && (subscribers.length > 0 || workflows.length > 0);
|
|
9819
9778
|
if (!entrypoint && !isWorkersOnly) {
|
|
9820
|
-
throw new
|
|
9779
|
+
throw new import_build_utils21.NowBuildError({
|
|
9821
9780
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
9822
9781
|
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
9823
9782
|
});
|
|
@@ -9830,7 +9789,7 @@ var build = async ({
|
|
|
9830
9789
|
envOverride: baseEnv.VERCEL_RUNTIME_PYTHON,
|
|
9831
9790
|
uv,
|
|
9832
9791
|
venvPath,
|
|
9833
|
-
projectDir: (0,
|
|
9792
|
+
projectDir: (0, import_path18.join)(workPath, entryDirectory),
|
|
9834
9793
|
pipPlatformArgs
|
|
9835
9794
|
});
|
|
9836
9795
|
if (shouldInstallVercelWorkers) {
|
|
@@ -9840,7 +9799,7 @@ var build = async ({
|
|
|
9840
9799
|
envOverride: baseEnv.VERCEL_WORKERS_PYTHON,
|
|
9841
9800
|
uv,
|
|
9842
9801
|
venvPath,
|
|
9843
|
-
projectDir: (0,
|
|
9802
|
+
projectDir: (0, import_path18.join)(workPath, entryDirectory),
|
|
9844
9803
|
pipPlatformArgs
|
|
9845
9804
|
});
|
|
9846
9805
|
}
|
|
@@ -9853,11 +9812,11 @@ var build = async ({
|
|
|
9853
9812
|
const capturedEnv = { ...pythonEnv };
|
|
9854
9813
|
const capturedCwd = workPath;
|
|
9855
9814
|
registerPreDeploy(async () => {
|
|
9856
|
-
await builderSpan.child(
|
|
9815
|
+
await builderSpan.child(import_build_utils21.BUILDER_PRE_DEPLOY_STEP, {
|
|
9857
9816
|
preDeployCommand
|
|
9858
9817
|
}).trace(async () => {
|
|
9859
9818
|
console.log(`Running pre-deploy command: \`${preDeployCommand}\``);
|
|
9860
|
-
await (0,
|
|
9819
|
+
await (0, import_build_utils21.execCommand)(preDeployCommand, {
|
|
9861
9820
|
env: capturedEnv,
|
|
9862
9821
|
cwd: capturedCwd
|
|
9863
9822
|
});
|
|
@@ -9868,14 +9827,14 @@ var build = async ({
|
|
|
9868
9827
|
let crons;
|
|
9869
9828
|
let runtimeTrampoline;
|
|
9870
9829
|
if (entrypoint) {
|
|
9871
|
-
(0,
|
|
9830
|
+
(0, import_build_utils21.debug)("Entrypoint is", entrypoint);
|
|
9872
9831
|
const moduleName = entrypointToModule(entrypoint);
|
|
9873
9832
|
if (handlerFunction) {
|
|
9874
|
-
const entrypointPath = (0,
|
|
9875
|
-
const source = await
|
|
9876
|
-
const found = await (0,
|
|
9833
|
+
const entrypointPath = (0, import_path18.join)(workPath, entrypoint);
|
|
9834
|
+
const source = await import_fs18.default.promises.readFile(entrypointPath, "utf-8");
|
|
9835
|
+
const found = await (0, import_python_analysis10.containsTopLevelCallable)(source, handlerFunction);
|
|
9877
9836
|
if (!found) {
|
|
9878
|
-
throw new
|
|
9837
|
+
throw new import_build_utils21.NowBuildError({
|
|
9879
9838
|
code: "PYTHON_HANDLER_NOT_FOUND",
|
|
9880
9839
|
message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
|
|
9881
9840
|
});
|
|
@@ -9883,7 +9842,7 @@ var build = async ({
|
|
|
9883
9842
|
}
|
|
9884
9843
|
const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
|
|
9885
9844
|
const entrypointWithSuffix = `${entrypoint}${suffix}`;
|
|
9886
|
-
(0,
|
|
9845
|
+
(0, import_build_utils21.debug)("Entrypoint with suffix is", entrypointWithSuffix);
|
|
9887
9846
|
crons = await getServiceCrons({
|
|
9888
9847
|
service,
|
|
9889
9848
|
entrypoint,
|
|
@@ -9944,34 +9903,37 @@ var build = async ({
|
|
|
9944
9903
|
cwd: workPath,
|
|
9945
9904
|
ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
|
|
9946
9905
|
};
|
|
9947
|
-
const files = await (0,
|
|
9906
|
+
const files = await (0, import_build_utils21.glob)("**", globOptions);
|
|
9948
9907
|
if (djangoStatic?.manifestRelPath) {
|
|
9949
|
-
files[djangoStatic.manifestRelPath] = new
|
|
9950
|
-
fsPath: (0,
|
|
9908
|
+
files[djangoStatic.manifestRelPath] = new import_build_utils21.FileFsRef({
|
|
9909
|
+
fsPath: (0, import_path18.join)(workPath, djangoStatic.manifestRelPath)
|
|
9951
9910
|
});
|
|
9952
9911
|
}
|
|
9953
9912
|
const handlerPyFilename = "vc__handler__python";
|
|
9954
9913
|
if (config.framework === "fasthtml") {
|
|
9955
9914
|
const { SESSKEY = "" } = process.env;
|
|
9956
|
-
files[".sesskey"] = new
|
|
9915
|
+
files[".sesskey"] = new import_build_utils21.FileBlob({ data: `"${SESSKEY}"` });
|
|
9957
9916
|
}
|
|
9958
|
-
const depExternalizer = new PythonDependencyExternalizer({
|
|
9959
|
-
venvPath,
|
|
9960
|
-
vendorDir,
|
|
9961
|
-
workPath,
|
|
9962
|
-
uvLockPath,
|
|
9963
|
-
uvProjectDir,
|
|
9964
|
-
projectName,
|
|
9965
|
-
pythonMajor: pythonVersion.major,
|
|
9966
|
-
pythonMinor: pythonVersion.minor,
|
|
9967
|
-
pythonPath: pythonVersion.pythonPath,
|
|
9968
|
-
hasCustomCommand,
|
|
9969
|
-
alwaysBundlePackages: [
|
|
9970
|
-
...quirksResult.alwaysBundlePackages ?? [],
|
|
9971
|
-
...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
|
|
9972
|
-
]
|
|
9973
|
-
});
|
|
9974
9917
|
await builderSpan.child("vc.builder.python.bundle").trace(async (bundleSpan) => {
|
|
9918
|
+
const installedDistributions = await InstalledPythonDistributions.load({
|
|
9919
|
+
venvPath,
|
|
9920
|
+
pythonMajor: pythonVersion.major,
|
|
9921
|
+
pythonMinor: pythonVersion.minor
|
|
9922
|
+
});
|
|
9923
|
+
const depExternalizer = new PythonDependencyExternalizer({
|
|
9924
|
+
installedDistributions,
|
|
9925
|
+
vendorDir,
|
|
9926
|
+
workPath,
|
|
9927
|
+
uvLockPath,
|
|
9928
|
+
uvProjectDir,
|
|
9929
|
+
projectName,
|
|
9930
|
+
pythonVersion,
|
|
9931
|
+
hasCustomCommand,
|
|
9932
|
+
alwaysBundlePackages: [
|
|
9933
|
+
...quirksResult.alwaysBundlePackages ?? [],
|
|
9934
|
+
...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
|
|
9935
|
+
]
|
|
9936
|
+
});
|
|
9975
9937
|
const depAnalysis = await depExternalizer.analyze(files, {
|
|
9976
9938
|
onSized: ({ totalSizeBytes, runtimeInstallEnabled }) => {
|
|
9977
9939
|
bundleSpan.setAttributes({
|
|
@@ -9985,7 +9947,7 @@ var build = async ({
|
|
|
9985
9947
|
const runCompileAllAndFillBytecode = async (capacityBytes, vendorPackageTiers) => {
|
|
9986
9948
|
try {
|
|
9987
9949
|
await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
|
|
9988
|
-
const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) =>
|
|
9950
|
+
const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs18.default.existsSync(d));
|
|
9989
9951
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
9990
9952
|
console.log("Compiling Python bytecode...");
|
|
9991
9953
|
await runCompileAll({
|
|
@@ -10023,7 +9985,7 @@ var build = async ({
|
|
|
10023
9985
|
}
|
|
10024
9986
|
await addVendorBytecodeInTiers({
|
|
10025
9987
|
files,
|
|
10026
|
-
|
|
9988
|
+
installedDistributions,
|
|
10027
9989
|
vendorDir,
|
|
10028
9990
|
capacity: remainingCapacity,
|
|
10029
9991
|
vendorPackageTiers: vendorPackageTiers ?? [void 0]
|
|
@@ -10032,7 +9994,7 @@ var build = async ({
|
|
|
10032
9994
|
console.log(
|
|
10033
9995
|
"Bytecode precompilation failed; continuing without precompiled bytecode."
|
|
10034
9996
|
);
|
|
10035
|
-
(0,
|
|
9997
|
+
(0, import_build_utils21.debug)(`bytecode precompilation error details: ${err}`);
|
|
10036
9998
|
}
|
|
10037
9999
|
};
|
|
10038
10000
|
const runPrefixCompileAndFill = async (bundleResult) => {
|
|
@@ -10044,16 +10006,16 @@ var build = async ({
|
|
|
10044
10006
|
const currentSize = await calculateBundleSize(files);
|
|
10045
10007
|
let remainingCapacity = BYTECODE_FILL_CEILING_BYTES - currentSize;
|
|
10046
10008
|
if (remainingCapacity <= 0) {
|
|
10047
|
-
(0,
|
|
10009
|
+
(0, import_build_utils21.debug)(
|
|
10048
10010
|
`skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
|
|
10049
10011
|
);
|
|
10050
10012
|
return;
|
|
10051
10013
|
}
|
|
10052
|
-
const stagingDir = (0,
|
|
10053
|
-
await
|
|
10054
|
-
await
|
|
10014
|
+
const stagingDir = (0, import_path18.join)(workPath, ".vercel", "python", "pycache");
|
|
10015
|
+
await import_fs18.default.promises.rm(stagingDir, { recursive: true, force: true });
|
|
10016
|
+
await import_fs18.default.promises.mkdir(stagingDir, { recursive: true });
|
|
10055
10017
|
await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
|
|
10056
|
-
const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) =>
|
|
10018
|
+
const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs18.default.existsSync(d));
|
|
10057
10019
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
10058
10020
|
console.log("Compiling Python bytecode...");
|
|
10059
10021
|
await runCompileAll({
|
|
@@ -10095,7 +10057,7 @@ var build = async ({
|
|
|
10095
10057
|
remainingCapacity = await addCollectedVendorBytecode({
|
|
10096
10058
|
files,
|
|
10097
10059
|
capacity: remainingCapacity,
|
|
10098
|
-
collect: (include) =>
|
|
10060
|
+
collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
|
|
10099
10061
|
stagingDir,
|
|
10100
10062
|
runtimeRoot: `/var/task/${vendorDir}`,
|
|
10101
10063
|
includePackages: include ?? alwaysBundled
|
|
@@ -10105,7 +10067,7 @@ var build = async ({
|
|
|
10105
10067
|
await addCollectedVendorBytecode({
|
|
10106
10068
|
files,
|
|
10107
10069
|
capacity: remainingCapacity,
|
|
10108
|
-
collect: (include) =>
|
|
10070
|
+
collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
|
|
10109
10071
|
stagingDir,
|
|
10110
10072
|
runtimeRoot: `${RUNTIME_DEPS_DIR}/lib/python${pyMajor}.${pyMinor}/site-packages`,
|
|
10111
10073
|
includePackages: include ?? externalized
|
|
@@ -10118,22 +10080,25 @@ var build = async ({
|
|
|
10118
10080
|
console.log(
|
|
10119
10081
|
"Bytecode precompilation failed; continuing without precompiled bytecode."
|
|
10120
10082
|
);
|
|
10121
|
-
(0,
|
|
10083
|
+
(0, import_build_utils21.debug)(`bytecode precompilation error details: ${err}`);
|
|
10122
10084
|
}
|
|
10123
10085
|
};
|
|
10124
10086
|
const announceLargeFunction = () => console.log(
|
|
10125
10087
|
`Function "${entrypoint ?? rawEntrypoint}" exceeds the standard size limit; enabling large functions (beta).`
|
|
10126
10088
|
);
|
|
10089
|
+
let packingMode;
|
|
10127
10090
|
if (depAnalysis.runtimeInstallEnabled) {
|
|
10091
|
+
packingMode = "runtime-install";
|
|
10128
10092
|
const bytecodeFirst = compileAllEnabled && pythonVersion.major != null && pythonVersion.minor != null;
|
|
10129
10093
|
const bundleResult = await depExternalizer.generateBundle(files, {
|
|
10130
10094
|
bytecodeFirst
|
|
10131
10095
|
});
|
|
10132
10096
|
if (bundleResult.fellBackToFullBundle) {
|
|
10097
|
+
packingMode = "hive";
|
|
10133
10098
|
announceLargeFunction();
|
|
10134
10099
|
if (compileAllEnabled) {
|
|
10135
10100
|
await runCompileAllAndFillBytecode(
|
|
10136
|
-
|
|
10101
|
+
LARGE_FUNCTION_FILL_CEILING_BYTES
|
|
10137
10102
|
);
|
|
10138
10103
|
}
|
|
10139
10104
|
} else if (bundleResult.packingMode === "bytecode-first") {
|
|
@@ -10141,45 +10106,61 @@ var build = async ({
|
|
|
10141
10106
|
} else if (compileAllEnabled) {
|
|
10142
10107
|
const currentSize = await calculateBundleSize(files);
|
|
10143
10108
|
const capacity = BYTECODE_FILL_CEILING_BYTES - currentSize;
|
|
10144
|
-
|
|
10145
|
-
if (capacity >= BYTECODE_COVERAGE_FLOOR * estimate) {
|
|
10109
|
+
if (capacity > 0) {
|
|
10146
10110
|
await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES, [
|
|
10147
10111
|
bundleResult.alwaysBundledPackages ?? [],
|
|
10148
10112
|
bundleResult.bundledPublicPackages ?? []
|
|
10149
10113
|
]);
|
|
10114
|
+
} else {
|
|
10115
|
+
(0, import_build_utils21.debug)(
|
|
10116
|
+
`skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
|
|
10117
|
+
);
|
|
10150
10118
|
}
|
|
10151
10119
|
}
|
|
10152
10120
|
} else {
|
|
10153
10121
|
addFiles(files, depAnalysis.allVendorFiles);
|
|
10154
10122
|
if (depAnalysis.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES) {
|
|
10123
|
+
packingMode = "hive";
|
|
10155
10124
|
if (isLargeFunctionsEnabled()) {
|
|
10156
10125
|
announceLargeFunction();
|
|
10157
10126
|
}
|
|
10158
10127
|
if (compileAllEnabled) {
|
|
10159
10128
|
await runCompileAllAndFillBytecode(
|
|
10160
|
-
|
|
10129
|
+
LARGE_FUNCTION_FILL_CEILING_BYTES
|
|
10161
10130
|
);
|
|
10162
10131
|
}
|
|
10163
|
-
} else
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10132
|
+
} else {
|
|
10133
|
+
packingMode = "standard";
|
|
10134
|
+
if (compileAllEnabled) {
|
|
10135
|
+
const capacity = BYTECODE_FILL_CEILING_BYTES - depAnalysis.totalBundleSize;
|
|
10136
|
+
if (capacity > 0) {
|
|
10137
|
+
await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES);
|
|
10138
|
+
} else {
|
|
10139
|
+
(0, import_build_utils21.debug)(
|
|
10140
|
+
`skipping bytecode precompilation: no zip capacity remaining (bundle is ${(depAnalysis.totalBundleSize / (1024 * 1024)).toFixed(2)} MB)`
|
|
10141
|
+
);
|
|
10142
|
+
}
|
|
10168
10143
|
}
|
|
10169
10144
|
}
|
|
10170
10145
|
}
|
|
10146
|
+
bundleSpan.setAttributes({
|
|
10147
|
+
"python.bundle.totalSizeBytes": String(
|
|
10148
|
+
await calculateBundleSize(files)
|
|
10149
|
+
),
|
|
10150
|
+
"python.bundle.packingMode": packingMode
|
|
10151
|
+
});
|
|
10171
10152
|
});
|
|
10172
10153
|
let output;
|
|
10173
10154
|
if (entrypoint && runtimeTrampoline) {
|
|
10174
10155
|
const webFiles = {
|
|
10175
10156
|
...files,
|
|
10176
|
-
[`${handlerPyFilename}.py`]: new
|
|
10157
|
+
[`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({ data: runtimeTrampoline })
|
|
10177
10158
|
};
|
|
10178
10159
|
const lambdaOptions = await getPythonLambdaOptions({
|
|
10179
10160
|
config,
|
|
10180
10161
|
entrypoint
|
|
10181
10162
|
});
|
|
10182
|
-
output = new
|
|
10163
|
+
output = new import_build_utils21.Lambda({
|
|
10183
10164
|
files: webFiles,
|
|
10184
10165
|
handler: `${handlerPyFilename}.vc_handler`,
|
|
10185
10166
|
runtime: pythonVersion.runtime,
|
|
@@ -10201,10 +10182,10 @@ var build = async ({
|
|
|
10201
10182
|
...subscriber.triggerDefaults
|
|
10202
10183
|
})
|
|
10203
10184
|
);
|
|
10204
|
-
subscriberLambdas[outputPath] = new
|
|
10185
|
+
subscriberLambdas[outputPath] = new import_build_utils21.Lambda({
|
|
10205
10186
|
files: {
|
|
10206
10187
|
...files,
|
|
10207
|
-
[`${handlerPyFilename}.py`]: new
|
|
10188
|
+
[`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({
|
|
10208
10189
|
data: createRuntimeTrampoline({
|
|
10209
10190
|
moduleName: subscriber.moduleName,
|
|
10210
10191
|
entrypoint: subscriber.entrypoint,
|
|
@@ -10236,10 +10217,10 @@ var build = async ({
|
|
|
10236
10217
|
consumer: getWorkflowConsumerName(workflow.name)
|
|
10237
10218
|
}
|
|
10238
10219
|
];
|
|
10239
|
-
workflowLambdas[outputPath] = new
|
|
10220
|
+
workflowLambdas[outputPath] = new import_build_utils21.Lambda({
|
|
10240
10221
|
files: {
|
|
10241
10222
|
...files,
|
|
10242
|
-
[`${handlerPyFilename}.py`]: new
|
|
10223
|
+
[`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({
|
|
10243
10224
|
data: createRuntimeTrampoline({
|
|
10244
10225
|
moduleName: workflow.moduleName,
|
|
10245
10226
|
entrypoint: workflow.entrypoint,
|
|
@@ -10269,20 +10250,20 @@ var build = async ({
|
|
|
10269
10250
|
pythonVersion,
|
|
10270
10251
|
uvLockPath,
|
|
10271
10252
|
framework,
|
|
10272
|
-
serviceType: service ? (0,
|
|
10253
|
+
serviceType: service ? (0, import_build_utils21.getReportedServiceType)(service) : void 0
|
|
10273
10254
|
});
|
|
10274
10255
|
} catch (err) {
|
|
10275
|
-
(0,
|
|
10256
|
+
(0, import_build_utils21.debug)(
|
|
10276
10257
|
`Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
|
|
10277
10258
|
);
|
|
10278
10259
|
}
|
|
10279
10260
|
}
|
|
10280
|
-
if (!(0,
|
|
10261
|
+
if (!(0, import_build_utils21.isPythonFramework)(framework) && !service?.name && !isPyprojectEntrypoint) {
|
|
10281
10262
|
(0, import_assert.default)(output, "web Lambda must exist for non-service builds");
|
|
10282
10263
|
return { resultVersion: 3, result: { output } };
|
|
10283
10264
|
}
|
|
10284
10265
|
const lambdaPath = service?.name && service.type ? `_svc/${service.name}/index` : "index";
|
|
10285
|
-
const staticFiles = djangoStatic?.cdnOutputDir ? await (0,
|
|
10266
|
+
const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils21.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
|
|
10286
10267
|
const isNonWebService = service?.name && service.type && service.type !== "web";
|
|
10287
10268
|
const routes = isNonWebService || !output ? void 0 : [
|
|
10288
10269
|
{ handle: "filesystem" },
|
|
@@ -10317,14 +10298,14 @@ var prepareCache = async ({
|
|
|
10317
10298
|
}
|
|
10318
10299
|
} catch {
|
|
10319
10300
|
}
|
|
10320
|
-
return (0,
|
|
10301
|
+
return (0, import_build_utils21.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
|
|
10321
10302
|
cwd: root,
|
|
10322
10303
|
ignore
|
|
10323
10304
|
});
|
|
10324
10305
|
};
|
|
10325
10306
|
var shouldServe = (opts) => {
|
|
10326
10307
|
const framework = opts.config.framework;
|
|
10327
|
-
if ((0,
|
|
10308
|
+
if ((0, import_build_utils21.isPythonFramework)(framework)) {
|
|
10328
10309
|
const requestPath = opts.requestPath.replace(/\/$/, "");
|
|
10329
10310
|
if (requestPath.startsWith("api") && opts.hasMatched) {
|
|
10330
10311
|
return false;
|
|
@@ -10343,7 +10324,7 @@ var defaultShouldServe = ({
|
|
|
10343
10324
|
if (entrypoint === requestPath && hasProp(files, entrypoint)) {
|
|
10344
10325
|
return true;
|
|
10345
10326
|
}
|
|
10346
|
-
const { dir, name } = (0,
|
|
10327
|
+
const { dir, name } = (0, import_path18.parse)(entrypoint);
|
|
10347
10328
|
if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
|
|
10348
10329
|
return true;
|
|
10349
10330
|
}
|