@vercel/python 6.31.0 → 6.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +473 -294
- package/package.json +4 -4
- package/templates/vc_cron_detect.py +67 -0
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var require_windows = __commonJS({
|
|
|
48
48
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module2) {
|
|
49
49
|
module2.exports = isexe;
|
|
50
50
|
isexe.sync = sync;
|
|
51
|
-
var
|
|
51
|
+
var fs12 = 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
|
+
fs12.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(fs12.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 fs12 = require("fs");
|
|
92
92
|
function isexe(path, options, cb) {
|
|
93
|
-
|
|
93
|
+
fs12.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(fs12.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 fs12 = 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 fs12 = 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 = fs12.openSync(command, "r");
|
|
412
|
+
fs12.readSync(fd, buffer, 0, size, 0);
|
|
413
|
+
fs12.closeSync(fd);
|
|
414
414
|
} catch (e) {
|
|
415
415
|
}
|
|
416
416
|
return shebangCommand(buffer.toString());
|
|
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
|
|
|
1895
1895
|
"../../node_modules/.pnpm/pump@3.0.2/node_modules/pump/index.js"(exports, module2) {
|
|
1896
1896
|
var once = require_once();
|
|
1897
1897
|
var eos = require_end_of_stream();
|
|
1898
|
-
var
|
|
1898
|
+
var fs12;
|
|
1899
1899
|
try {
|
|
1900
|
-
|
|
1900
|
+
fs12 = 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 (!fs12)
|
|
1913
1913
|
return false;
|
|
1914
|
-
return (stream instanceof (
|
|
1914
|
+
return (stream instanceof (fs12.ReadStream || noop) || stream instanceof (fs12.WriteStream || noop)) && isFn(stream.close);
|
|
1915
1915
|
};
|
|
1916
1916
|
var isRequest = function(stream) {
|
|
1917
1917
|
return stream.setHeader && isFn(stream.abort);
|
|
@@ -2141,7 +2141,7 @@ var require_signal_exit = __commonJS({
|
|
|
2141
2141
|
};
|
|
2142
2142
|
};
|
|
2143
2143
|
} else {
|
|
2144
|
-
|
|
2144
|
+
assert2 = require("assert");
|
|
2145
2145
|
signals = require_signals();
|
|
2146
2146
|
isWin3 = /^win/i.test(process2.platform);
|
|
2147
2147
|
EE = require("events");
|
|
@@ -2164,7 +2164,7 @@ var require_signal_exit = __commonJS({
|
|
|
2164
2164
|
return function() {
|
|
2165
2165
|
};
|
|
2166
2166
|
}
|
|
2167
|
-
|
|
2167
|
+
assert2.equal(typeof cb, "function", "a callback must be provided for exit handler");
|
|
2168
2168
|
if (loaded === false) {
|
|
2169
2169
|
load();
|
|
2170
2170
|
}
|
|
@@ -2270,7 +2270,7 @@ var require_signal_exit = __commonJS({
|
|
|
2270
2270
|
}
|
|
2271
2271
|
};
|
|
2272
2272
|
}
|
|
2273
|
-
var
|
|
2273
|
+
var assert2;
|
|
2274
2274
|
var signals;
|
|
2275
2275
|
var isWin3;
|
|
2276
2276
|
var EE;
|
|
@@ -2674,27 +2674,27 @@ var require_process = __commonJS({
|
|
|
2674
2674
|
var require_filesystem = __commonJS({
|
|
2675
2675
|
"../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/filesystem.js"(exports, module2) {
|
|
2676
2676
|
"use strict";
|
|
2677
|
-
var
|
|
2677
|
+
var fs12 = require("fs");
|
|
2678
2678
|
var LDD_PATH = "/usr/bin/ldd";
|
|
2679
2679
|
var SELF_PATH = "/proc/self/exe";
|
|
2680
2680
|
var MAX_LENGTH = 2048;
|
|
2681
2681
|
var readFileSync2 = (path) => {
|
|
2682
|
-
const fd =
|
|
2682
|
+
const fd = fs12.openSync(path, "r");
|
|
2683
2683
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2684
|
-
const bytesRead =
|
|
2685
|
-
|
|
2684
|
+
const bytesRead = fs12.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
2685
|
+
fs12.close(fd, () => {
|
|
2686
2686
|
});
|
|
2687
2687
|
return buffer.subarray(0, bytesRead);
|
|
2688
2688
|
};
|
|
2689
2689
|
var readFile2 = (path) => new Promise((resolve3, reject) => {
|
|
2690
|
-
|
|
2690
|
+
fs12.open(path, "r", (err, fd) => {
|
|
2691
2691
|
if (err) {
|
|
2692
2692
|
reject(err);
|
|
2693
2693
|
} else {
|
|
2694
2694
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2695
|
-
|
|
2695
|
+
fs12.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
2696
2696
|
resolve3(buffer.subarray(0, bytesRead));
|
|
2697
|
-
|
|
2697
|
+
fs12.close(fd, () => {
|
|
2698
2698
|
});
|
|
2699
2699
|
});
|
|
2700
2700
|
}
|
|
@@ -3005,7 +3005,7 @@ var require_detect_libc = __commonJS({
|
|
|
3005
3005
|
var require_lib = __commonJS({
|
|
3006
3006
|
"../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
|
|
3007
3007
|
var isexe = require_isexe();
|
|
3008
|
-
var { join:
|
|
3008
|
+
var { join: join14, delimiter: delimiter2, sep: sep2, posix } = require("path");
|
|
3009
3009
|
var isWindows = process.platform === "win32";
|
|
3010
3010
|
var rSlash = new RegExp(`[${posix.sep}${sep2 === posix.sep ? "" : sep2}]`.replace(/(\\)/g, "\\$1"));
|
|
3011
3011
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -3034,7 +3034,7 @@ var require_lib = __commonJS({
|
|
|
3034
3034
|
var getPathPart = (raw, cmd) => {
|
|
3035
3035
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
3036
3036
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
3037
|
-
return prefix +
|
|
3037
|
+
return prefix + join14(pathPart, cmd);
|
|
3038
3038
|
};
|
|
3039
3039
|
var which2 = async (cmd, opt = {}) => {
|
|
3040
3040
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -3224,16 +3224,17 @@ __export(src_exports, {
|
|
|
3224
3224
|
version: () => version
|
|
3225
3225
|
});
|
|
3226
3226
|
module.exports = __toCommonJS(src_exports);
|
|
3227
|
+
var import_assert = __toESM(require("assert"));
|
|
3227
3228
|
var import_child_process3 = require("child_process");
|
|
3228
|
-
var
|
|
3229
|
-
var
|
|
3229
|
+
var import_fs13 = __toESM(require("fs"));
|
|
3230
|
+
var import_path14 = require("path");
|
|
3230
3231
|
|
|
3231
3232
|
// src/package-versions.ts
|
|
3232
|
-
var VERCEL_RUNTIME_VERSION = "0.
|
|
3233
|
+
var VERCEL_RUNTIME_VERSION = "0.13.0";
|
|
3233
3234
|
var VERCEL_WORKERS_VERSION = "0.0.16";
|
|
3234
3235
|
|
|
3235
3236
|
// src/index.ts
|
|
3236
|
-
var
|
|
3237
|
+
var import_build_utils16 = require("@vercel/build-utils");
|
|
3237
3238
|
|
|
3238
3239
|
// src/install.ts
|
|
3239
3240
|
var import_execa3 = __toESM(require_execa());
|
|
@@ -3636,7 +3637,7 @@ async function ensureVenv({
|
|
|
3636
3637
|
}
|
|
3637
3638
|
}
|
|
3638
3639
|
if (uvPath) {
|
|
3639
|
-
const args = ["venv", venvPath, "--allow-existing"];
|
|
3640
|
+
const args = ["venv", venvPath, "--allow-existing", "--seed"];
|
|
3640
3641
|
if (pythonVersion.major != null && pythonVersion.minor != null) {
|
|
3641
3642
|
args.push("--python", `${pythonVersion.major}.${pythonVersion.minor}`);
|
|
3642
3643
|
}
|
|
@@ -4312,6 +4313,7 @@ var import_python_analysis3 = require("@vercel/python-analysis");
|
|
|
4312
4313
|
var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
|
|
4313
4314
|
var LAMBDA_SIZE_THRESHOLD_BYTES = 245 * 1024 * 1024;
|
|
4314
4315
|
var LAMBDA_EPHEMERAL_STORAGE_BYTES = 500 * 1024 * 1024;
|
|
4316
|
+
var HIVE_LAMBDA_SIZE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
4315
4317
|
var PythonDependencyExternalizer = class {
|
|
4316
4318
|
constructor(options) {
|
|
4317
4319
|
// Populated by analyze()
|
|
@@ -4377,6 +4379,15 @@ To resolve this, either:
|
|
|
4377
4379
|
action: "Learn More"
|
|
4378
4380
|
});
|
|
4379
4381
|
}
|
|
4382
|
+
if (pythonOnHiveEnabled && this.totalBundleSize > HIVE_LAMBDA_SIZE_BYTES) {
|
|
4383
|
+
const limitMB = (HIVE_LAMBDA_SIZE_BYTES / (1024 * 1024)).toFixed(0);
|
|
4384
|
+
throw new import_build_utils5.NowBuildError({
|
|
4385
|
+
code: "LAMBDA_SIZE_EXCEEDED",
|
|
4386
|
+
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the extended function size limit (${limitMB} MB). Consider removing unused dependencies or splitting your application into smaller functions.`,
|
|
4387
|
+
link: "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled",
|
|
4388
|
+
action: "Learn More"
|
|
4389
|
+
});
|
|
4390
|
+
}
|
|
4380
4391
|
return {
|
|
4381
4392
|
runtimeInstallEnabled,
|
|
4382
4393
|
allVendorFiles: this.allVendorFiles,
|
|
@@ -5093,20 +5104,161 @@ var diagnostics = async ({
|
|
|
5093
5104
|
}
|
|
5094
5105
|
};
|
|
5095
5106
|
|
|
5107
|
+
// src/crons.ts
|
|
5108
|
+
var import_fs7 = __toESM(require("fs"));
|
|
5109
|
+
var import_path8 = require("path");
|
|
5110
|
+
var import_execa4 = __toESM(require_execa());
|
|
5111
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
5112
|
+
var DYNAMIC_SCHEDULE = "<dynamic>";
|
|
5113
|
+
function entrypointToModule(entrypoint) {
|
|
5114
|
+
return entrypoint.replace(/\\/g, "/").replace(/\.py$/i, "").replace(/\//g, ".");
|
|
5115
|
+
}
|
|
5116
|
+
var scriptPath = (0, import_path8.join)(__dirname, "..", "templates", "vc_cron_detect.py");
|
|
5117
|
+
var script = import_fs7.default.readFileSync(scriptPath, "utf-8");
|
|
5118
|
+
function buildCronRouteTable(crons) {
|
|
5119
|
+
const table = {};
|
|
5120
|
+
for (const cron of crons) {
|
|
5121
|
+
table[cron.path] = cron.resolvedHandler;
|
|
5122
|
+
}
|
|
5123
|
+
return table;
|
|
5124
|
+
}
|
|
5125
|
+
async function getServiceCrons(opts) {
|
|
5126
|
+
const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
|
|
5127
|
+
if (service?.type !== "cron" || !service.name || typeof service.schedule !== "string") {
|
|
5128
|
+
return void 0;
|
|
5129
|
+
}
|
|
5130
|
+
const cronEntrypoint = entrypoint || rawEntrypoint;
|
|
5131
|
+
if (!cronEntrypoint) {
|
|
5132
|
+
throw new import_build_utils7.NowBuildError({
|
|
5133
|
+
code: "PYTHON_CRON_NO_ENTRYPOINT",
|
|
5134
|
+
message: "Cron service is missing an entrypoint."
|
|
5135
|
+
});
|
|
5136
|
+
}
|
|
5137
|
+
if (service.schedule === DYNAMIC_SCHEDULE) {
|
|
5138
|
+
return getServiceCronsDynamic({
|
|
5139
|
+
serviceName: service.name,
|
|
5140
|
+
cronEntrypoint,
|
|
5141
|
+
handlerFunction,
|
|
5142
|
+
pythonBin: opts.pythonBin,
|
|
5143
|
+
env: opts.env,
|
|
5144
|
+
workPath: opts.workPath
|
|
5145
|
+
});
|
|
5146
|
+
}
|
|
5147
|
+
const cronPath = (0, import_build_utils7.getInternalServiceCronPath)(
|
|
5148
|
+
service.name,
|
|
5149
|
+
cronEntrypoint,
|
|
5150
|
+
handlerFunction || "cron"
|
|
5151
|
+
);
|
|
5152
|
+
const moduleName = entrypointToModule(cronEntrypoint);
|
|
5153
|
+
const resolvedHandler = handlerFunction ? `${moduleName}:${handlerFunction}` : moduleName;
|
|
5154
|
+
return [{ path: cronPath, schedule: service.schedule, resolvedHandler }];
|
|
5155
|
+
}
|
|
5156
|
+
async function getServiceCronsDynamic(opts) {
|
|
5157
|
+
const {
|
|
5158
|
+
serviceName,
|
|
5159
|
+
cronEntrypoint,
|
|
5160
|
+
handlerFunction,
|
|
5161
|
+
pythonBin,
|
|
5162
|
+
env,
|
|
5163
|
+
workPath
|
|
5164
|
+
} = opts;
|
|
5165
|
+
if (!handlerFunction) {
|
|
5166
|
+
throw new import_build_utils7.NowBuildError({
|
|
5167
|
+
code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
|
|
5168
|
+
message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
|
|
5169
|
+
});
|
|
5170
|
+
}
|
|
5171
|
+
const moduleName = entrypointToModule(cronEntrypoint);
|
|
5172
|
+
const entries = await detectDynamicCrons({
|
|
5173
|
+
pythonBin,
|
|
5174
|
+
env,
|
|
5175
|
+
workPath,
|
|
5176
|
+
moduleName,
|
|
5177
|
+
attrName: handlerFunction
|
|
5178
|
+
});
|
|
5179
|
+
console.log(
|
|
5180
|
+
`Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
|
|
5181
|
+
);
|
|
5182
|
+
if (entries.length === 0) {
|
|
5183
|
+
throw new import_build_utils7.NowBuildError({
|
|
5184
|
+
code: "PYTHON_DYNAMIC_CRON_EMPTY",
|
|
5185
|
+
message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
|
|
5186
|
+
});
|
|
5187
|
+
}
|
|
5188
|
+
return entries.map((entry) => {
|
|
5189
|
+
const cronPath = moduleColonFuncToCronPath(
|
|
5190
|
+
serviceName,
|
|
5191
|
+
entry.module_function
|
|
5192
|
+
);
|
|
5193
|
+
return {
|
|
5194
|
+
path: cronPath,
|
|
5195
|
+
schedule: entry.schedule,
|
|
5196
|
+
resolvedHandler: entry.module_function
|
|
5197
|
+
};
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
async function detectDynamicCrons(opts) {
|
|
5201
|
+
const { pythonBin, env, workPath, moduleName, attrName } = opts;
|
|
5202
|
+
let stdout;
|
|
5203
|
+
try {
|
|
5204
|
+
const result = await (0, import_execa4.default)(
|
|
5205
|
+
pythonBin,
|
|
5206
|
+
["-c", script, moduleName, attrName],
|
|
5207
|
+
{ env, cwd: workPath }
|
|
5208
|
+
);
|
|
5209
|
+
stdout = result.stdout;
|
|
5210
|
+
} catch (err) {
|
|
5211
|
+
let detail = err?.stderr || err?.message || String(err);
|
|
5212
|
+
try {
|
|
5213
|
+
const parsed2 = JSON.parse(err?.stdout);
|
|
5214
|
+
if (parsed2.error)
|
|
5215
|
+
detail = parsed2.error;
|
|
5216
|
+
} catch {
|
|
5217
|
+
}
|
|
5218
|
+
throw new import_build_utils7.NowBuildError({
|
|
5219
|
+
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
5220
|
+
message: `Failed to detect dynamic cron entries: ${detail}`
|
|
5221
|
+
});
|
|
5222
|
+
}
|
|
5223
|
+
let parsed;
|
|
5224
|
+
try {
|
|
5225
|
+
parsed = JSON.parse(stdout);
|
|
5226
|
+
} catch {
|
|
5227
|
+
throw new import_build_utils7.NowBuildError({
|
|
5228
|
+
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
5229
|
+
message: `Dynamic cron detection returned invalid JSON: ${stdout}`
|
|
5230
|
+
});
|
|
5231
|
+
}
|
|
5232
|
+
return parsed.entries || [];
|
|
5233
|
+
}
|
|
5234
|
+
function moduleColonFuncToCronPath(serviceName, moduleFunction) {
|
|
5235
|
+
const colonIdx = moduleFunction.indexOf(":");
|
|
5236
|
+
if (colonIdx === -1) {
|
|
5237
|
+
throw new import_build_utils7.NowBuildError({
|
|
5238
|
+
code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
|
|
5239
|
+
message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
|
|
5240
|
+
});
|
|
5241
|
+
}
|
|
5242
|
+
const modulePart = moduleFunction.slice(0, colonIdx);
|
|
5243
|
+
const funcPart = moduleFunction.slice(colonIdx + 1);
|
|
5244
|
+
const entrypointPath = modulePart.replace(/\./g, "/");
|
|
5245
|
+
return (0, import_build_utils7.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
|
|
5246
|
+
}
|
|
5247
|
+
|
|
5096
5248
|
// src/start-dev-server.ts
|
|
5097
5249
|
var import_child_process2 = require("child_process");
|
|
5098
|
-
var
|
|
5099
|
-
var
|
|
5100
|
-
var
|
|
5250
|
+
var import_fs9 = require("fs");
|
|
5251
|
+
var import_path10 = require("path");
|
|
5252
|
+
var import_build_utils11 = require("@vercel/build-utils");
|
|
5101
5253
|
var import_get_port = __toESM(require_get_port());
|
|
5102
5254
|
var import_is_port_reachable = __toESM(require_is_port_reachable());
|
|
5103
5255
|
|
|
5104
5256
|
// src/entrypoint.ts
|
|
5105
|
-
var
|
|
5106
|
-
var
|
|
5107
|
-
var import_build_utils7 = require("@vercel/build-utils");
|
|
5257
|
+
var import_fs8 = __toESM(require("fs"));
|
|
5258
|
+
var import_path9 = require("path");
|
|
5108
5259
|
var import_build_utils8 = require("@vercel/build-utils");
|
|
5109
5260
|
var import_build_utils9 = require("@vercel/build-utils");
|
|
5261
|
+
var import_build_utils10 = require("@vercel/build-utils");
|
|
5110
5262
|
var import_python_analysis5 = require("@vercel/python-analysis");
|
|
5111
5263
|
var PYTHON_ENTRYPOINT_FILENAMES = [
|
|
5112
5264
|
"app",
|
|
@@ -5123,27 +5275,27 @@ var PYTHON_CANDIDATE_ENTRYPOINTS = getCandidateEntrypointsInDirs(
|
|
|
5123
5275
|
function getCandidateEntrypointsInDirs(dirs) {
|
|
5124
5276
|
return dirs.flatMap(
|
|
5125
5277
|
(dir) => PYTHON_ENTRYPOINT_FILENAMES.map(
|
|
5126
|
-
(filename) =>
|
|
5278
|
+
(filename) => import_path9.posix.join(dir, `${filename}.py`)
|
|
5127
5279
|
)
|
|
5128
5280
|
);
|
|
5129
5281
|
}
|
|
5130
5282
|
async function fileExists(filePath) {
|
|
5131
5283
|
try {
|
|
5132
|
-
const stat = await
|
|
5284
|
+
const stat = await import_fs8.default.promises.stat(filePath);
|
|
5133
5285
|
return stat.isFile();
|
|
5134
5286
|
} catch {
|
|
5135
5287
|
return false;
|
|
5136
5288
|
}
|
|
5137
5289
|
}
|
|
5138
5290
|
async function checkEntrypoint(workPath, relPath) {
|
|
5139
|
-
const absPath = (0,
|
|
5291
|
+
const absPath = (0, import_path9.join)(workPath, relPath);
|
|
5140
5292
|
if (!await fileExists(absPath))
|
|
5141
5293
|
return null;
|
|
5142
|
-
const content = await
|
|
5294
|
+
const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
|
|
5143
5295
|
return (0, import_python_analysis5.findAppOrHandler)(content);
|
|
5144
5296
|
}
|
|
5145
5297
|
async function getPyprojectEntrypoint(workPath) {
|
|
5146
|
-
const pyprojectData = await (0,
|
|
5298
|
+
const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path9.join)(workPath, "pyproject.toml"));
|
|
5147
5299
|
if (!pyprojectData)
|
|
5148
5300
|
return null;
|
|
5149
5301
|
const scripts = pyprojectData.project?.scripts;
|
|
@@ -5158,7 +5310,7 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
5158
5310
|
const relPath = modulePath.replace(/\./g, "/");
|
|
5159
5311
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
5160
5312
|
for (const candidate of candidates) {
|
|
5161
|
-
if (await fileExists((0,
|
|
5313
|
+
if (await fileExists((0, import_path9.join)(workPath, candidate))) {
|
|
5162
5314
|
return { entrypoint: candidate, variableName };
|
|
5163
5315
|
}
|
|
5164
5316
|
}
|
|
@@ -5168,19 +5320,19 @@ async function findValidEntrypoint(workPath, candidates) {
|
|
|
5168
5320
|
for (const candidate of candidates) {
|
|
5169
5321
|
const varName = await checkEntrypoint(workPath, candidate);
|
|
5170
5322
|
if (varName) {
|
|
5171
|
-
(0,
|
|
5323
|
+
(0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
|
|
5172
5324
|
return { entrypoint: candidate, variableName: varName };
|
|
5173
5325
|
}
|
|
5174
5326
|
}
|
|
5175
5327
|
return null;
|
|
5176
5328
|
}
|
|
5177
5329
|
async function checkDjangoManage(workPath) {
|
|
5178
|
-
const managePath = (0,
|
|
5330
|
+
const managePath = (0, import_path9.join)(workPath, "manage.py");
|
|
5179
5331
|
try {
|
|
5180
|
-
const content = await
|
|
5332
|
+
const content = await import_fs8.default.promises.readFile(managePath, "utf-8");
|
|
5181
5333
|
if (!content.includes("DJANGO_SETTINGS_MODULE"))
|
|
5182
5334
|
return false;
|
|
5183
|
-
(0,
|
|
5335
|
+
(0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
|
|
5184
5336
|
return true;
|
|
5185
5337
|
} catch {
|
|
5186
5338
|
return false;
|
|
@@ -5188,7 +5340,7 @@ async function checkDjangoManage(workPath) {
|
|
|
5188
5340
|
}
|
|
5189
5341
|
async function getSubdirectories(workPath) {
|
|
5190
5342
|
try {
|
|
5191
|
-
const entries = await
|
|
5343
|
+
const entries = await import_fs8.default.promises.readdir(workPath, {
|
|
5192
5344
|
withFileTypes: true
|
|
5193
5345
|
});
|
|
5194
5346
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
@@ -5198,7 +5350,7 @@ async function getSubdirectories(workPath) {
|
|
|
5198
5350
|
}
|
|
5199
5351
|
function makeDetectError(framework) {
|
|
5200
5352
|
const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
5201
|
-
return new
|
|
5353
|
+
return new import_build_utils8.NowBuildError({
|
|
5202
5354
|
code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
|
|
5203
5355
|
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
|
|
5204
5356
|
link: `https://vercel.com/docs/frameworks/backend/${framework}#exporting-the-${framework}-application`,
|
|
@@ -5213,7 +5365,7 @@ async function detectGenericPythonEntrypoint(workPath) {
|
|
|
5213
5365
|
);
|
|
5214
5366
|
return found ? { entrypoint: found } : null;
|
|
5215
5367
|
} catch {
|
|
5216
|
-
(0,
|
|
5368
|
+
(0, import_build_utils9.debug)("Failed to discover Python entrypoint");
|
|
5217
5369
|
return null;
|
|
5218
5370
|
}
|
|
5219
5371
|
}
|
|
@@ -5222,7 +5374,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
5222
5374
|
const subdirs = await getSubdirectories(workPath);
|
|
5223
5375
|
const rootDirs = ["", ...subdirs];
|
|
5224
5376
|
for (const rootDir of rootDirs) {
|
|
5225
|
-
const currPath = (0,
|
|
5377
|
+
const currPath = (0, import_path9.join)(workPath, rootDir);
|
|
5226
5378
|
const isDjango = await checkDjangoManage(currPath);
|
|
5227
5379
|
if (isDjango) {
|
|
5228
5380
|
return { baseDir: rootDir, error: makeDetectError("django") };
|
|
@@ -5232,7 +5384,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
5232
5384
|
const found = await findValidEntrypoint(workPath, candidates);
|
|
5233
5385
|
return found ? { entrypoint: found } : null;
|
|
5234
5386
|
} catch {
|
|
5235
|
-
(0,
|
|
5387
|
+
(0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
|
|
5236
5388
|
return null;
|
|
5237
5389
|
}
|
|
5238
5390
|
}
|
|
@@ -5248,11 +5400,11 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
|
|
|
5248
5400
|
}
|
|
5249
5401
|
}
|
|
5250
5402
|
if (varName) {
|
|
5251
|
-
(0,
|
|
5403
|
+
(0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
|
|
5252
5404
|
return { entrypoint: { entrypoint, variableName: varName } };
|
|
5253
5405
|
} else {
|
|
5254
5406
|
return {
|
|
5255
|
-
error: new
|
|
5407
|
+
error: new import_build_utils8.NowBuildError({
|
|
5256
5408
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
5257
5409
|
message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
|
|
5258
5410
|
link: "https://vercel.com/docs/functions/serverless-functions/runtimes/python",
|
|
@@ -5358,17 +5510,17 @@ async function syncDependencies({
|
|
|
5358
5510
|
let { manifestPath } = installInfo;
|
|
5359
5511
|
const manifest = pythonPackage.manifest;
|
|
5360
5512
|
if (!manifestType || !manifestPath) {
|
|
5361
|
-
(0,
|
|
5513
|
+
(0, import_build_utils11.debug)("No Python project manifest found, skipping dependency sync");
|
|
5362
5514
|
return;
|
|
5363
5515
|
}
|
|
5364
5516
|
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
5365
|
-
const syncDir = (0,
|
|
5366
|
-
(0,
|
|
5367
|
-
const tempPyproject = (0,
|
|
5517
|
+
const syncDir = (0, import_path10.join)(workPath, ".vercel", "python", "sync");
|
|
5518
|
+
(0, import_fs9.mkdirSync)(syncDir, { recursive: true });
|
|
5519
|
+
const tempPyproject = (0, import_path10.join)(syncDir, "pyproject.toml");
|
|
5368
5520
|
const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
|
|
5369
|
-
(0,
|
|
5521
|
+
(0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
|
|
5370
5522
|
manifestPath = tempPyproject;
|
|
5371
|
-
(0,
|
|
5523
|
+
(0, import_build_utils11.debug)(
|
|
5372
5524
|
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
5373
5525
|
);
|
|
5374
5526
|
}
|
|
@@ -5401,7 +5553,7 @@ async function syncDependencies({
|
|
|
5401
5553
|
for (const [channel, chunk] of captured) {
|
|
5402
5554
|
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
5403
5555
|
}
|
|
5404
|
-
throw new
|
|
5556
|
+
throw new import_build_utils11.NowBuildError({
|
|
5405
5557
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
5406
5558
|
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
5407
5559
|
});
|
|
@@ -5416,14 +5568,14 @@ async function runSync({
|
|
|
5416
5568
|
onStdout,
|
|
5417
5569
|
onStderr
|
|
5418
5570
|
}) {
|
|
5419
|
-
const projectDir = (0,
|
|
5571
|
+
const projectDir = (0, import_path10.dirname)(manifestPath);
|
|
5420
5572
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
5421
5573
|
let spawnCmd;
|
|
5422
5574
|
let spawnArgs;
|
|
5423
5575
|
switch (manifestType) {
|
|
5424
5576
|
case "uv.lock": {
|
|
5425
5577
|
if (!uvPath) {
|
|
5426
|
-
throw new
|
|
5578
|
+
throw new import_build_utils11.NowBuildError({
|
|
5427
5579
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
5428
5580
|
message: "uv is required to install dependencies from uv.lock.",
|
|
5429
5581
|
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
@@ -5445,11 +5597,11 @@ async function runSync({
|
|
|
5445
5597
|
break;
|
|
5446
5598
|
}
|
|
5447
5599
|
default:
|
|
5448
|
-
(0,
|
|
5600
|
+
(0, import_build_utils11.debug)(`Unknown manifest type: ${manifestType}`);
|
|
5449
5601
|
return;
|
|
5450
5602
|
}
|
|
5451
5603
|
await new Promise((resolve3, reject) => {
|
|
5452
|
-
(0,
|
|
5604
|
+
(0, import_build_utils11.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
5453
5605
|
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
5454
5606
|
cwd: projectDir,
|
|
5455
5607
|
env: getProtectedUvEnv(env),
|
|
@@ -5493,7 +5645,7 @@ async function installVercelRuntime({
|
|
|
5493
5645
|
onStdout,
|
|
5494
5646
|
onStderr
|
|
5495
5647
|
}) {
|
|
5496
|
-
const targetDir = (0,
|
|
5648
|
+
const targetDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5497
5649
|
let pending = PENDING_RUNTIME_INSTALLS.get(targetDir);
|
|
5498
5650
|
if (!pending) {
|
|
5499
5651
|
pending = doInstallVercelRuntime({
|
|
@@ -5519,8 +5671,8 @@ async function doInstallVercelRuntime({
|
|
|
5519
5671
|
onStdout,
|
|
5520
5672
|
onStderr
|
|
5521
5673
|
}) {
|
|
5522
|
-
(0,
|
|
5523
|
-
const localRuntimeDir = (0,
|
|
5674
|
+
(0, import_fs9.mkdirSync)(targetDir, { recursive: true });
|
|
5675
|
+
const localRuntimeDir = (0, import_path10.join)(
|
|
5524
5676
|
__dirname,
|
|
5525
5677
|
"..",
|
|
5526
5678
|
"..",
|
|
@@ -5528,21 +5680,21 @@ async function doInstallVercelRuntime({
|
|
|
5528
5680
|
"python",
|
|
5529
5681
|
"vercel-runtime"
|
|
5530
5682
|
);
|
|
5531
|
-
const isLocalDev = (0,
|
|
5683
|
+
const isLocalDev = (0, import_fs9.existsSync)((0, import_path10.join)(localRuntimeDir, "pyproject.toml"));
|
|
5532
5684
|
const runtimeDep = env.VERCEL_RUNTIME_PYTHON || (isLocalDev ? localRuntimeDir : `vercel-runtime==${VERCEL_RUNTIME_VERSION}`);
|
|
5533
5685
|
if (!isLocalDev && !env.VERCEL_RUNTIME_PYTHON) {
|
|
5534
|
-
const distInfo = (0,
|
|
5686
|
+
const distInfo = (0, import_path10.join)(
|
|
5535
5687
|
targetDir,
|
|
5536
5688
|
`vercel_runtime-${VERCEL_RUNTIME_VERSION}.dist-info`
|
|
5537
5689
|
);
|
|
5538
|
-
if ((0,
|
|
5539
|
-
(0,
|
|
5690
|
+
if ((0, import_fs9.existsSync)(distInfo)) {
|
|
5691
|
+
(0, import_build_utils11.debug)(
|
|
5540
5692
|
`vercel-runtime ${VERCEL_RUNTIME_VERSION} already installed, skipping`
|
|
5541
5693
|
);
|
|
5542
5694
|
return;
|
|
5543
5695
|
}
|
|
5544
5696
|
}
|
|
5545
|
-
(0,
|
|
5697
|
+
(0, import_build_utils11.debug)(
|
|
5546
5698
|
`Installing vercel-runtime into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${runtimeDep})`
|
|
5547
5699
|
);
|
|
5548
5700
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -5557,14 +5709,14 @@ async function doInstallVercelRuntime({
|
|
|
5557
5709
|
if (onStdout) {
|
|
5558
5710
|
onStdout(data);
|
|
5559
5711
|
} else {
|
|
5560
|
-
(0,
|
|
5712
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5561
5713
|
}
|
|
5562
5714
|
});
|
|
5563
5715
|
child.stderr?.on("data", (data) => {
|
|
5564
5716
|
if (onStderr) {
|
|
5565
5717
|
onStderr(data);
|
|
5566
5718
|
} else {
|
|
5567
|
-
(0,
|
|
5719
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5568
5720
|
}
|
|
5569
5721
|
});
|
|
5570
5722
|
child.on("error", reject);
|
|
@@ -5589,7 +5741,7 @@ async function installVercelWorkers({
|
|
|
5589
5741
|
onStdout,
|
|
5590
5742
|
onStderr
|
|
5591
5743
|
}) {
|
|
5592
|
-
const targetDir = (0,
|
|
5744
|
+
const targetDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5593
5745
|
let pending = PENDING_WORKERS_INSTALLS.get(targetDir);
|
|
5594
5746
|
if (!pending) {
|
|
5595
5747
|
pending = doInstallVercelWorkers({
|
|
@@ -5615,8 +5767,8 @@ async function doInstallVercelWorkers({
|
|
|
5615
5767
|
onStdout,
|
|
5616
5768
|
onStderr
|
|
5617
5769
|
}) {
|
|
5618
|
-
(0,
|
|
5619
|
-
const localWorkersDir = (0,
|
|
5770
|
+
(0, import_fs9.mkdirSync)(targetDir, { recursive: true });
|
|
5771
|
+
const localWorkersDir = (0, import_path10.join)(
|
|
5620
5772
|
__dirname,
|
|
5621
5773
|
"..",
|
|
5622
5774
|
"..",
|
|
@@ -5624,21 +5776,21 @@ async function doInstallVercelWorkers({
|
|
|
5624
5776
|
"python",
|
|
5625
5777
|
"vercel-workers"
|
|
5626
5778
|
);
|
|
5627
|
-
const isLocalDev = (0,
|
|
5779
|
+
const isLocalDev = (0, import_fs9.existsSync)((0, import_path10.join)(localWorkersDir, "pyproject.toml"));
|
|
5628
5780
|
const workersDep = env.VERCEL_WORKERS_PYTHON || (isLocalDev ? localWorkersDir : `vercel-workers==${VERCEL_WORKERS_VERSION}`);
|
|
5629
5781
|
if (!isLocalDev && !env.VERCEL_WORKERS_PYTHON) {
|
|
5630
|
-
const distInfo = (0,
|
|
5782
|
+
const distInfo = (0, import_path10.join)(
|
|
5631
5783
|
targetDir,
|
|
5632
5784
|
`vercel_workers-${VERCEL_WORKERS_VERSION}.dist-info`
|
|
5633
5785
|
);
|
|
5634
|
-
if ((0,
|
|
5635
|
-
(0,
|
|
5786
|
+
if ((0, import_fs9.existsSync)(distInfo)) {
|
|
5787
|
+
(0, import_build_utils11.debug)(
|
|
5636
5788
|
`vercel-workers ${VERCEL_WORKERS_VERSION} already installed, skipping`
|
|
5637
5789
|
);
|
|
5638
5790
|
return;
|
|
5639
5791
|
}
|
|
5640
5792
|
}
|
|
5641
|
-
(0,
|
|
5793
|
+
(0, import_build_utils11.debug)(
|
|
5642
5794
|
`Installing vercel-workers into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${workersDep})`
|
|
5643
5795
|
);
|
|
5644
5796
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -5653,14 +5805,14 @@ async function doInstallVercelWorkers({
|
|
|
5653
5805
|
if (onStdout) {
|
|
5654
5806
|
onStdout(data);
|
|
5655
5807
|
} else {
|
|
5656
|
-
(0,
|
|
5808
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5657
5809
|
}
|
|
5658
5810
|
});
|
|
5659
5811
|
child.stderr?.on("data", (data) => {
|
|
5660
5812
|
if (onStderr) {
|
|
5661
5813
|
onStderr(data);
|
|
5662
5814
|
} else {
|
|
5663
|
-
(0,
|
|
5815
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5664
5816
|
}
|
|
5665
5817
|
});
|
|
5666
5818
|
child.on("error", reject);
|
|
@@ -5690,12 +5842,12 @@ function installGlobalCleanupHandlers() {
|
|
|
5690
5842
|
try {
|
|
5691
5843
|
process.kill(info.pid, "SIGTERM");
|
|
5692
5844
|
} catch (err) {
|
|
5693
|
-
(0,
|
|
5845
|
+
(0, import_build_utils11.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
|
|
5694
5846
|
}
|
|
5695
5847
|
try {
|
|
5696
5848
|
process.kill(info.pid, "SIGKILL");
|
|
5697
5849
|
} catch (err) {
|
|
5698
|
-
(0,
|
|
5850
|
+
(0, import_build_utils11.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
|
|
5699
5851
|
}
|
|
5700
5852
|
PERSISTENT_SERVERS.delete(key);
|
|
5701
5853
|
}
|
|
@@ -5703,7 +5855,7 @@ function installGlobalCleanupHandlers() {
|
|
|
5703
5855
|
try {
|
|
5704
5856
|
restoreWarnings();
|
|
5705
5857
|
} catch (err) {
|
|
5706
|
-
(0,
|
|
5858
|
+
(0, import_build_utils11.debug)(`Error restoring warnings: ${err}`);
|
|
5707
5859
|
}
|
|
5708
5860
|
restoreWarnings = null;
|
|
5709
5861
|
}
|
|
@@ -5720,55 +5872,55 @@ function installGlobalCleanupHandlers() {
|
|
|
5720
5872
|
}
|
|
5721
5873
|
function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
|
|
5722
5874
|
try {
|
|
5723
|
-
const vercelPythonDir = serviceName ? (0,
|
|
5724
|
-
(0,
|
|
5875
|
+
const vercelPythonDir = serviceName ? (0, import_path10.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5876
|
+
(0, import_fs9.mkdirSync)(vercelPythonDir, { recursive: true });
|
|
5725
5877
|
let qualifiedModule = modulePath;
|
|
5726
5878
|
let extraPythonPath;
|
|
5727
|
-
if ((0,
|
|
5728
|
-
const pkgName = (0,
|
|
5879
|
+
if ((0, import_fs9.existsSync)((0, import_path10.join)(workPath, "__init__.py"))) {
|
|
5880
|
+
const pkgName = (0, import_path10.basename)(workPath);
|
|
5729
5881
|
qualifiedModule = `${pkgName}.${modulePath}`;
|
|
5730
|
-
extraPythonPath = (0,
|
|
5882
|
+
extraPythonPath = (0, import_path10.dirname)(workPath);
|
|
5731
5883
|
}
|
|
5732
|
-
const entryAbs = (0,
|
|
5733
|
-
const shimPath = (0,
|
|
5734
|
-
const templatePath = (0,
|
|
5884
|
+
const entryAbs = (0, import_path10.join)(workPath, entry);
|
|
5885
|
+
const shimPath = (0, import_path10.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
|
|
5886
|
+
const templatePath = (0, import_path10.join)(
|
|
5735
5887
|
__dirname,
|
|
5736
5888
|
"..",
|
|
5737
5889
|
"templates",
|
|
5738
5890
|
`${DEV_SHIM_MODULE}.py`
|
|
5739
5891
|
);
|
|
5740
|
-
const template = (0,
|
|
5892
|
+
const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
|
|
5741
5893
|
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);
|
|
5742
|
-
(0,
|
|
5743
|
-
(0,
|
|
5894
|
+
(0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
|
|
5895
|
+
(0, import_build_utils11.debug)(`Prepared Python dev shim at ${shimPath}`);
|
|
5744
5896
|
return {
|
|
5745
5897
|
module: DEV_SHIM_MODULE,
|
|
5746
5898
|
extraPythonPath,
|
|
5747
5899
|
shimDir: vercelPythonDir
|
|
5748
5900
|
};
|
|
5749
5901
|
} catch (err) {
|
|
5750
|
-
(0,
|
|
5902
|
+
(0, import_build_utils11.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
|
|
5751
5903
|
return null;
|
|
5752
5904
|
}
|
|
5753
5905
|
}
|
|
5754
5906
|
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
5755
5907
|
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
5756
5908
|
if (venvRoot) {
|
|
5757
|
-
(0,
|
|
5909
|
+
(0, import_build_utils11.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
5758
5910
|
return { command: pythonCmd, args: [] };
|
|
5759
5911
|
}
|
|
5760
|
-
const venvPath = (0,
|
|
5912
|
+
const venvPath = (0, import_path10.join)(workPath, ".venv");
|
|
5761
5913
|
await ensureVenv({
|
|
5762
5914
|
pythonVersion: { pythonPath: systemPython },
|
|
5763
5915
|
venvPath,
|
|
5764
5916
|
uvPath,
|
|
5765
5917
|
quiet: true
|
|
5766
5918
|
});
|
|
5767
|
-
(0,
|
|
5919
|
+
(0, import_build_utils11.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
5768
5920
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
5769
5921
|
const binDir = getVenvBinDir(venvPath);
|
|
5770
5922
|
env.VIRTUAL_ENV = venvPath;
|
|
5771
|
-
env.PATH = `${binDir}${
|
|
5923
|
+
env.PATH = `${binDir}${import_path10.delimiter}${env.PATH || ""}`;
|
|
5772
5924
|
return { command: pythonBin, args: [] };
|
|
5773
5925
|
}
|
|
5774
5926
|
var startDevServer = async (opts) => {
|
|
@@ -5831,7 +5983,7 @@ var startDevServer = async (opts) => {
|
|
|
5831
5983
|
} else {
|
|
5832
5984
|
const hookResult = await runFrameworkHook(framework, {
|
|
5833
5985
|
pythonEnv: env,
|
|
5834
|
-
projectDir: (0,
|
|
5986
|
+
projectDir: (0, import_path10.join)(workPath, detected?.baseDir ?? ""),
|
|
5835
5987
|
workPath,
|
|
5836
5988
|
entrypoint,
|
|
5837
5989
|
detected: detected ?? void 0
|
|
@@ -5842,7 +5994,7 @@ var startDevServer = async (opts) => {
|
|
|
5842
5994
|
if (detected?.error) {
|
|
5843
5995
|
throw detected.error;
|
|
5844
5996
|
}
|
|
5845
|
-
throw new
|
|
5997
|
+
throw new import_build_utils11.NowBuildError({
|
|
5846
5998
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
5847
5999
|
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
5848
6000
|
});
|
|
@@ -5871,7 +6023,7 @@ var startDevServer = async (opts) => {
|
|
|
5871
6023
|
const yellow = "\x1B[33m";
|
|
5872
6024
|
const white = "\x1B[1m";
|
|
5873
6025
|
const reset = "\x1B[0m";
|
|
5874
|
-
throw new
|
|
6026
|
+
throw new import_build_utils11.NowBuildError({
|
|
5875
6027
|
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
5876
6028
|
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
5877
6029
|
Run ${white}deactivate${reset} and try again.`
|
|
@@ -5888,11 +6040,11 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
5888
6040
|
);
|
|
5889
6041
|
spawnCommand = runner.command;
|
|
5890
6042
|
spawnArgsPrefix = runner.args;
|
|
5891
|
-
(0,
|
|
6043
|
+
(0, import_build_utils11.debug)(
|
|
5892
6044
|
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
5893
6045
|
);
|
|
5894
6046
|
} else if (venv) {
|
|
5895
|
-
(0,
|
|
6047
|
+
(0, import_build_utils11.debug)(`Running in virtualenv at ${venv}`);
|
|
5896
6048
|
} else {
|
|
5897
6049
|
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
5898
6050
|
workPath,
|
|
@@ -5901,9 +6053,9 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
5901
6053
|
);
|
|
5902
6054
|
spawnCommand = venvPythonCmd;
|
|
5903
6055
|
if (venvRoot) {
|
|
5904
|
-
(0,
|
|
6056
|
+
(0, import_build_utils11.debug)(`Using virtualenv at ${venvRoot}`);
|
|
5905
6057
|
} else {
|
|
5906
|
-
(0,
|
|
6058
|
+
(0, import_build_utils11.debug)("No virtualenv found");
|
|
5907
6059
|
try {
|
|
5908
6060
|
const yellow = "\x1B[33m";
|
|
5909
6061
|
const reset = "\x1B[0m";
|
|
@@ -5952,13 +6104,22 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5952
6104
|
onStderr
|
|
5953
6105
|
});
|
|
5954
6106
|
}
|
|
6107
|
+
const crons = await getServiceCrons({
|
|
6108
|
+
service,
|
|
6109
|
+
entrypoint,
|
|
6110
|
+
rawEntrypoint,
|
|
6111
|
+
handlerFunction,
|
|
6112
|
+
pythonBin: spawnCommand,
|
|
6113
|
+
env,
|
|
6114
|
+
workPath
|
|
6115
|
+
});
|
|
6116
|
+
if (crons?.length) {
|
|
6117
|
+
env.__VC_CRON_ROUTES = JSON.stringify(buildCronRouteTable(crons));
|
|
6118
|
+
}
|
|
5955
6119
|
const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
|
|
5956
6120
|
env.PORT = `${port}`;
|
|
5957
|
-
if (config.handlerFunction && typeof config?.handlerFunction === "string") {
|
|
5958
|
-
env.__VC_HANDLER_FUNC_NAME = config.handlerFunction;
|
|
5959
|
-
}
|
|
5960
6121
|
if (entry) {
|
|
5961
|
-
env.__VC_HANDLER_ENTRYPOINT_ABS = (0,
|
|
6122
|
+
env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path10.join)(workPath, entry);
|
|
5962
6123
|
}
|
|
5963
6124
|
const devShim = createDevShim(
|
|
5964
6125
|
workPath,
|
|
@@ -5969,8 +6130,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5969
6130
|
variableName ?? ""
|
|
5970
6131
|
);
|
|
5971
6132
|
if (devShim) {
|
|
5972
|
-
const shimDir = devShim.shimDir || (0,
|
|
5973
|
-
const runtimeDir = (0,
|
|
6133
|
+
const shimDir = devShim.shimDir || (0, import_path10.join)(workPath, ".vercel", "python");
|
|
6134
|
+
const runtimeDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5974
6135
|
const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
|
|
5975
6136
|
if (devShim.extraPythonPath) {
|
|
5976
6137
|
pathParts.push(devShim.extraPythonPath);
|
|
@@ -5979,12 +6140,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5979
6140
|
if (existingPythonPath) {
|
|
5980
6141
|
pathParts.push(existingPythonPath);
|
|
5981
6142
|
}
|
|
5982
|
-
env.PYTHONPATH = pathParts.join(
|
|
6143
|
+
env.PYTHONPATH = pathParts.join(import_path10.delimiter);
|
|
5983
6144
|
}
|
|
5984
6145
|
const moduleToRun = devShim?.module || modulePath;
|
|
5985
6146
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
5986
6147
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
5987
|
-
(0,
|
|
6148
|
+
(0, import_build_utils11.debug)(
|
|
5988
6149
|
`Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
|
|
5989
6150
|
);
|
|
5990
6151
|
if (process.stdout.columns) {
|
|
@@ -6028,7 +6189,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
6028
6189
|
});
|
|
6029
6190
|
const shutdown = async () => {
|
|
6030
6191
|
};
|
|
6031
|
-
return { port, pid, shutdown };
|
|
6192
|
+
return { port, pid, shutdown, crons };
|
|
6032
6193
|
} catch (err) {
|
|
6033
6194
|
rejectChildReady(err);
|
|
6034
6195
|
throw err;
|
|
@@ -6038,7 +6199,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
6038
6199
|
};
|
|
6039
6200
|
|
|
6040
6201
|
// src/quirks/index.ts
|
|
6041
|
-
var
|
|
6202
|
+
var import_build_utils14 = require("@vercel/build-utils");
|
|
6042
6203
|
var import_python_analysis8 = require("@vercel/python-analysis");
|
|
6043
6204
|
|
|
6044
6205
|
// src/quirks/matplotlib.ts
|
|
@@ -6052,9 +6213,9 @@ var matplotlibQuirk = {
|
|
|
6052
6213
|
};
|
|
6053
6214
|
|
|
6054
6215
|
// src/quirks/litellm.ts
|
|
6055
|
-
var
|
|
6056
|
-
var
|
|
6057
|
-
var
|
|
6216
|
+
var import_fs10 = __toESM(require("fs"));
|
|
6217
|
+
var import_path11 = require("path");
|
|
6218
|
+
var import_build_utils12 = require("@vercel/build-utils");
|
|
6058
6219
|
var LAMBDA_ROOT = "/var/task";
|
|
6059
6220
|
var CONFIG_CANDIDATES = [
|
|
6060
6221
|
"litellm_config.yaml",
|
|
@@ -6064,9 +6225,9 @@ var CONFIG_CANDIDATES = [
|
|
|
6064
6225
|
];
|
|
6065
6226
|
async function findConfigFile(workPath) {
|
|
6066
6227
|
for (const name of CONFIG_CANDIDATES) {
|
|
6067
|
-
const candidate = (0,
|
|
6228
|
+
const candidate = (0, import_path11.join)(workPath, name);
|
|
6068
6229
|
try {
|
|
6069
|
-
await
|
|
6230
|
+
await import_fs10.default.promises.access(candidate);
|
|
6070
6231
|
return name;
|
|
6071
6232
|
} catch {
|
|
6072
6233
|
}
|
|
@@ -6081,32 +6242,32 @@ var litellmQuirk = {
|
|
|
6081
6242
|
const env = {};
|
|
6082
6243
|
const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
|
|
6083
6244
|
for (const sitePackages of sitePackagesDirs) {
|
|
6084
|
-
const schemaPath = (0,
|
|
6245
|
+
const schemaPath = (0, import_path11.join)(
|
|
6085
6246
|
sitePackages,
|
|
6086
6247
|
"litellm",
|
|
6087
6248
|
"proxy",
|
|
6088
6249
|
"schema.prisma"
|
|
6089
6250
|
);
|
|
6090
6251
|
try {
|
|
6091
|
-
await
|
|
6092
|
-
(0,
|
|
6252
|
+
await import_fs10.default.promises.access(schemaPath);
|
|
6253
|
+
(0, import_build_utils12.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
|
|
6093
6254
|
buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
|
|
6094
6255
|
break;
|
|
6095
6256
|
} catch {
|
|
6096
6257
|
}
|
|
6097
6258
|
}
|
|
6098
6259
|
if (!buildEnv.PRISMA_SCHEMA_PATH) {
|
|
6099
|
-
(0,
|
|
6260
|
+
(0, import_build_utils12.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
|
|
6100
6261
|
}
|
|
6101
6262
|
if (!process.env.CONFIG_FILE_PATH) {
|
|
6102
6263
|
const configName = await findConfigFile(ctx.workPath);
|
|
6103
6264
|
if (configName) {
|
|
6104
|
-
(0,
|
|
6105
|
-
buildEnv.CONFIG_FILE_PATH = (0,
|
|
6106
|
-
env.CONFIG_FILE_PATH = (0,
|
|
6265
|
+
(0, import_build_utils12.debug)(`LiteLLM quirk: found config at ${configName}`);
|
|
6266
|
+
buildEnv.CONFIG_FILE_PATH = (0, import_path11.join)(ctx.workPath, configName);
|
|
6267
|
+
env.CONFIG_FILE_PATH = (0, import_path11.join)(LAMBDA_ROOT, configName);
|
|
6107
6268
|
}
|
|
6108
6269
|
} else {
|
|
6109
|
-
(0,
|
|
6270
|
+
(0, import_build_utils12.debug)(
|
|
6110
6271
|
`LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
|
|
6111
6272
|
);
|
|
6112
6273
|
}
|
|
@@ -6115,10 +6276,10 @@ var litellmQuirk = {
|
|
|
6115
6276
|
};
|
|
6116
6277
|
|
|
6117
6278
|
// src/quirks/prisma.ts
|
|
6118
|
-
var
|
|
6119
|
-
var
|
|
6120
|
-
var
|
|
6121
|
-
var
|
|
6279
|
+
var import_fs11 = __toESM(require("fs"));
|
|
6280
|
+
var import_path12 = require("path");
|
|
6281
|
+
var import_execa5 = __toESM(require_execa());
|
|
6282
|
+
var import_build_utils13 = require("@vercel/build-utils");
|
|
6122
6283
|
var import_python_analysis7 = require("@vercel/python-analysis");
|
|
6123
6284
|
function execErrorMessage(err) {
|
|
6124
6285
|
if (err != null && typeof err === "object" && "stderr" in err) {
|
|
@@ -6156,22 +6317,22 @@ model DummyModel {
|
|
|
6156
6317
|
async function findUserSchema(workPath) {
|
|
6157
6318
|
const envPath = process.env.PRISMA_SCHEMA_PATH;
|
|
6158
6319
|
if (envPath) {
|
|
6159
|
-
const resolved = (0,
|
|
6320
|
+
const resolved = (0, import_path12.isAbsolute)(envPath) ? envPath : (0, import_path12.join)(workPath, envPath);
|
|
6160
6321
|
try {
|
|
6161
|
-
await
|
|
6322
|
+
await import_fs11.default.promises.access(resolved);
|
|
6162
6323
|
return resolved;
|
|
6163
6324
|
} catch {
|
|
6164
|
-
(0,
|
|
6325
|
+
(0, import_build_utils13.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
|
|
6165
6326
|
return null;
|
|
6166
6327
|
}
|
|
6167
6328
|
}
|
|
6168
6329
|
const candidates = [
|
|
6169
|
-
(0,
|
|
6170
|
-
(0,
|
|
6330
|
+
(0, import_path12.join)(workPath, "schema.prisma"),
|
|
6331
|
+
(0, import_path12.join)(workPath, "prisma", "schema.prisma")
|
|
6171
6332
|
];
|
|
6172
6333
|
for (const candidate of candidates) {
|
|
6173
6334
|
try {
|
|
6174
|
-
await
|
|
6335
|
+
await import_fs11.default.promises.access(candidate);
|
|
6175
6336
|
return candidate;
|
|
6176
6337
|
} catch {
|
|
6177
6338
|
}
|
|
@@ -6182,32 +6343,32 @@ async function collectFiles(dir, base) {
|
|
|
6182
6343
|
const result = [];
|
|
6183
6344
|
let entries;
|
|
6184
6345
|
try {
|
|
6185
|
-
entries = await
|
|
6346
|
+
entries = await import_fs11.default.promises.readdir(dir, { withFileTypes: true });
|
|
6186
6347
|
} catch {
|
|
6187
6348
|
return result;
|
|
6188
6349
|
}
|
|
6189
6350
|
for (const entry of entries) {
|
|
6190
6351
|
if (entry.name === "__pycache__")
|
|
6191
6352
|
continue;
|
|
6192
|
-
const full = (0,
|
|
6353
|
+
const full = (0, import_path12.join)(dir, entry.name);
|
|
6193
6354
|
if (entry.isDirectory()) {
|
|
6194
6355
|
result.push(...await collectFiles(full, base));
|
|
6195
6356
|
} else {
|
|
6196
|
-
result.push((0,
|
|
6357
|
+
result.push((0, import_path12.relative)(base, full));
|
|
6197
6358
|
}
|
|
6198
6359
|
}
|
|
6199
6360
|
return result;
|
|
6200
6361
|
}
|
|
6201
6362
|
async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
6202
6363
|
const paths = [
|
|
6203
|
-
(0,
|
|
6204
|
-
(0,
|
|
6205
|
-
(0,
|
|
6364
|
+
(0, import_path12.join)(cacheDir, "node_modules"),
|
|
6365
|
+
(0, import_path12.join)(cacheDir, "package.json"),
|
|
6366
|
+
(0, import_path12.join)(cacheDir, "package-lock.json"),
|
|
6206
6367
|
...extras
|
|
6207
6368
|
];
|
|
6208
6369
|
for (const p of paths) {
|
|
6209
6370
|
try {
|
|
6210
|
-
await
|
|
6371
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
6211
6372
|
} catch (err) {
|
|
6212
6373
|
console.warn(
|
|
6213
6374
|
`could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -6217,7 +6378,7 @@ async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
|
6217
6378
|
}
|
|
6218
6379
|
async function isClientGenerated(pythonPath, env) {
|
|
6219
6380
|
try {
|
|
6220
|
-
await (0,
|
|
6381
|
+
await (0, import_execa5.default)(pythonPath, ["-c", "import prisma.client"], {
|
|
6221
6382
|
env,
|
|
6222
6383
|
stdio: "pipe"
|
|
6223
6384
|
});
|
|
@@ -6231,7 +6392,7 @@ var prismaQuirk = {
|
|
|
6231
6392
|
async run(ctx) {
|
|
6232
6393
|
const { venvPath, pythonEnv, workPath } = ctx;
|
|
6233
6394
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
6234
|
-
const runtimeCacheDir = (0,
|
|
6395
|
+
const runtimeCacheDir = (0, import_path12.join)(
|
|
6235
6396
|
LAMBDA_ROOT2,
|
|
6236
6397
|
resolveVendorDir(),
|
|
6237
6398
|
"prisma",
|
|
@@ -6241,7 +6402,7 @@ var prismaQuirk = {
|
|
|
6241
6402
|
let sitePackages;
|
|
6242
6403
|
for (const dir of sitePackagesDirs) {
|
|
6243
6404
|
try {
|
|
6244
|
-
await
|
|
6405
|
+
await import_fs11.default.promises.access((0, import_path12.join)(dir, "prisma"));
|
|
6245
6406
|
sitePackages = dir;
|
|
6246
6407
|
break;
|
|
6247
6408
|
} catch {
|
|
@@ -6253,21 +6414,21 @@ var prismaQuirk = {
|
|
|
6253
6414
|
);
|
|
6254
6415
|
return {};
|
|
6255
6416
|
}
|
|
6256
|
-
const cacheDir = (0,
|
|
6257
|
-
await
|
|
6417
|
+
const cacheDir = (0, import_path12.join)(sitePackages, "prisma", "__bincache__");
|
|
6418
|
+
await import_fs11.default.promises.mkdir(cacheDir, { recursive: true });
|
|
6258
6419
|
const generateEnv = {
|
|
6259
6420
|
...pythonEnv,
|
|
6260
6421
|
PRISMA_BINARY_CACHE_DIR: cacheDir
|
|
6261
6422
|
};
|
|
6262
|
-
const generatedDir = (0,
|
|
6263
|
-
const dummySchemaPath = (0,
|
|
6264
|
-
await
|
|
6423
|
+
const generatedDir = (0, import_path12.join)(workPath, "_prisma_generated");
|
|
6424
|
+
const dummySchemaPath = (0, import_path12.join)(workPath, DUMMY_SCHEMA_NAME);
|
|
6425
|
+
await import_fs11.default.promises.writeFile(
|
|
6265
6426
|
dummySchemaPath,
|
|
6266
6427
|
buildDummySchema(generatedDir)
|
|
6267
6428
|
);
|
|
6268
|
-
(0,
|
|
6429
|
+
(0, import_build_utils13.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
|
|
6269
6430
|
try {
|
|
6270
|
-
const dummyResult = await (0,
|
|
6431
|
+
const dummyResult = await (0, import_execa5.default)(
|
|
6271
6432
|
pythonPath,
|
|
6272
6433
|
["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
|
|
6273
6434
|
{
|
|
@@ -6277,11 +6438,11 @@ var prismaQuirk = {
|
|
|
6277
6438
|
}
|
|
6278
6439
|
);
|
|
6279
6440
|
if (dummyResult.stdout)
|
|
6280
|
-
(0,
|
|
6441
|
+
(0, import_build_utils13.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
|
|
6281
6442
|
if (dummyResult.stderr)
|
|
6282
|
-
(0,
|
|
6443
|
+
(0, import_build_utils13.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
|
|
6283
6444
|
} catch (err) {
|
|
6284
|
-
throw new
|
|
6445
|
+
throw new import_build_utils13.NowBuildError({
|
|
6285
6446
|
code: "PRISMA_GENERATE_FAILED",
|
|
6286
6447
|
message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
|
|
6287
6448
|
` + execErrorMessage(err)
|
|
@@ -6289,47 +6450,47 @@ var prismaQuirk = {
|
|
|
6289
6450
|
}
|
|
6290
6451
|
const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
|
|
6291
6452
|
const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
|
|
6292
|
-
const nodeModulesDir = (0,
|
|
6453
|
+
const nodeModulesDir = (0, import_path12.join)(cacheDir, "node_modules", "prisma");
|
|
6293
6454
|
let engineCopied = false;
|
|
6294
6455
|
try {
|
|
6295
|
-
const entries = await
|
|
6456
|
+
const entries = await import_fs11.default.promises.readdir(nodeModulesDir);
|
|
6296
6457
|
for (const entry of entries) {
|
|
6297
6458
|
if (!entry.startsWith(srcBinaryPrefix))
|
|
6298
6459
|
continue;
|
|
6299
|
-
const srcPath = (0,
|
|
6300
|
-
const destPath = (0,
|
|
6460
|
+
const srcPath = (0, import_path12.join)(nodeModulesDir, entry);
|
|
6461
|
+
const destPath = (0, import_path12.join)(cacheDir, runtimeName);
|
|
6301
6462
|
try {
|
|
6302
|
-
await
|
|
6303
|
-
(0,
|
|
6463
|
+
await import_fs11.default.promises.access(destPath);
|
|
6464
|
+
(0, import_build_utils13.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
|
|
6304
6465
|
} catch {
|
|
6305
|
-
(0,
|
|
6306
|
-
await
|
|
6466
|
+
(0, import_build_utils13.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
|
|
6467
|
+
await import_fs11.default.promises.copyFile(srcPath, destPath);
|
|
6307
6468
|
}
|
|
6308
6469
|
engineCopied = true;
|
|
6309
6470
|
}
|
|
6310
6471
|
} catch (err) {
|
|
6311
|
-
throw new
|
|
6472
|
+
throw new import_build_utils13.NowBuildError({
|
|
6312
6473
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
6313
6474
|
message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
|
|
6314
6475
|
` + (err instanceof Error ? err.message : String(err))
|
|
6315
6476
|
});
|
|
6316
6477
|
}
|
|
6317
6478
|
if (!engineCopied) {
|
|
6318
|
-
throw new
|
|
6479
|
+
throw new import_build_utils13.NowBuildError({
|
|
6319
6480
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
6320
6481
|
message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
|
|
6321
6482
|
});
|
|
6322
6483
|
}
|
|
6323
|
-
const shimPath = (0,
|
|
6324
|
-
await
|
|
6484
|
+
const shimPath = (0, import_path12.join)(cacheDir, "openssl");
|
|
6485
|
+
await import_fs11.default.promises.writeFile(
|
|
6325
6486
|
shimPath,
|
|
6326
6487
|
`#!/bin/sh
|
|
6327
6488
|
echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
|
|
6328
6489
|
`
|
|
6329
6490
|
);
|
|
6330
|
-
await
|
|
6491
|
+
await import_fs11.default.promises.chmod(shimPath, 493);
|
|
6331
6492
|
for (const p of [generatedDir, dummySchemaPath]) {
|
|
6332
|
-
await
|
|
6493
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
6333
6494
|
}
|
|
6334
6495
|
await cleanCacheArtifacts(cacheDir);
|
|
6335
6496
|
const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
|
|
@@ -6342,16 +6503,16 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6342
6503
|
pythonEnv
|
|
6343
6504
|
);
|
|
6344
6505
|
if (clientAlreadyGenerated) {
|
|
6345
|
-
(0,
|
|
6506
|
+
(0, import_build_utils13.debug)(
|
|
6346
6507
|
"Prisma quirk: client already generated, skipping user schema generate"
|
|
6347
6508
|
);
|
|
6348
6509
|
shouldGenerate = false;
|
|
6349
6510
|
}
|
|
6350
6511
|
}
|
|
6351
6512
|
if (shouldGenerate) {
|
|
6352
|
-
(0,
|
|
6513
|
+
(0, import_build_utils13.debug)(`Running prisma generate with user schema: ${userSchema}`);
|
|
6353
6514
|
try {
|
|
6354
|
-
const userResult = await (0,
|
|
6515
|
+
const userResult = await (0, import_execa5.default)(
|
|
6355
6516
|
pythonPath,
|
|
6356
6517
|
["-m", "prisma", "generate", `--schema=${userSchema}`],
|
|
6357
6518
|
{
|
|
@@ -6361,11 +6522,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6361
6522
|
}
|
|
6362
6523
|
);
|
|
6363
6524
|
if (userResult.stdout)
|
|
6364
|
-
(0,
|
|
6525
|
+
(0, import_build_utils13.debug)(`prisma generate stdout: ${userResult.stdout}`);
|
|
6365
6526
|
if (userResult.stderr)
|
|
6366
|
-
(0,
|
|
6527
|
+
(0, import_build_utils13.debug)(`prisma generate stderr: ${userResult.stderr}`);
|
|
6367
6528
|
} catch (err) {
|
|
6368
|
-
throw new
|
|
6529
|
+
throw new import_build_utils13.NowBuildError({
|
|
6369
6530
|
code: "PRISMA_GENERATE_FAILED",
|
|
6370
6531
|
message: `\`prisma generate\` failed for schema "${userSchema}".
|
|
6371
6532
|
` + execErrorMessage(err)
|
|
@@ -6376,12 +6537,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6376
6537
|
}
|
|
6377
6538
|
try {
|
|
6378
6539
|
const allFiles = await collectFiles(
|
|
6379
|
-
(0,
|
|
6540
|
+
(0, import_path12.join)(sitePackages, "prisma"),
|
|
6380
6541
|
sitePackages
|
|
6381
6542
|
);
|
|
6382
6543
|
const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
|
|
6383
6544
|
if (count > 0) {
|
|
6384
|
-
(0,
|
|
6545
|
+
(0, import_build_utils13.debug)(`Appended ${count} entries to prisma RECORD`);
|
|
6385
6546
|
}
|
|
6386
6547
|
} catch (err) {
|
|
6387
6548
|
console.warn(
|
|
@@ -6475,13 +6636,13 @@ async function runQuirks(ctx) {
|
|
|
6475
6636
|
(0, import_python_analysis8.normalizePackageName)(quirk.dependency)
|
|
6476
6637
|
);
|
|
6477
6638
|
if (!installed) {
|
|
6478
|
-
(0,
|
|
6639
|
+
(0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
|
|
6479
6640
|
}
|
|
6480
6641
|
return installed;
|
|
6481
6642
|
});
|
|
6482
6643
|
const sorted = toposortQuirks(activated);
|
|
6483
6644
|
for (const quirk of sorted) {
|
|
6484
|
-
(0,
|
|
6645
|
+
(0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
|
|
6485
6646
|
const result = await quirk.run(ctx);
|
|
6486
6647
|
if (result.env) {
|
|
6487
6648
|
Object.assign(mergedEnv, result.env);
|
|
@@ -6502,14 +6663,14 @@ async function runQuirks(ctx) {
|
|
|
6502
6663
|
}
|
|
6503
6664
|
|
|
6504
6665
|
// src/django.ts
|
|
6505
|
-
var
|
|
6506
|
-
var
|
|
6507
|
-
var
|
|
6508
|
-
var
|
|
6509
|
-
var
|
|
6510
|
-
var
|
|
6666
|
+
var import_fs12 = __toESM(require("fs"));
|
|
6667
|
+
var import_path13 = require("path");
|
|
6668
|
+
var import_execa6 = __toESM(require_execa());
|
|
6669
|
+
var import_build_utils15 = require("@vercel/build-utils");
|
|
6670
|
+
var scriptPath2 = (0, import_path13.join)(__dirname, "..", "templates", "vc_django_settings.py");
|
|
6671
|
+
var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
|
|
6511
6672
|
async function getDjangoSettings(projectDir, env) {
|
|
6512
|
-
const { stdout } = await (0,
|
|
6673
|
+
const { stdout } = await (0, import_execa6.default)("python", ["-c", script2], {
|
|
6513
6674
|
env,
|
|
6514
6675
|
cwd: projectDir
|
|
6515
6676
|
});
|
|
@@ -6535,21 +6696,21 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6535
6696
|
const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
|
|
6536
6697
|
const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
|
|
6537
6698
|
const staticSourceDirs = [
|
|
6538
|
-
...installedApps.map((app) => (0,
|
|
6699
|
+
...installedApps.map((app) => (0, import_path13.join)(workPath, ...app.split("."), "static")),
|
|
6539
6700
|
// TODO: Deal with optional prefixes in STATICFILES_DIRS.
|
|
6540
6701
|
...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
|
|
6541
|
-
].filter((d) =>
|
|
6702
|
+
].filter((d) => import_fs12.default.existsSync(d));
|
|
6542
6703
|
if (storageBackend.startsWith("storages.backends.")) {
|
|
6543
6704
|
console.log(
|
|
6544
6705
|
"django-storages detected \u2014 running collectstatic with original settings"
|
|
6545
6706
|
);
|
|
6546
|
-
await (0,
|
|
6707
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
6547
6708
|
env: { ...env, DJANGO_SETTINGS_MODULE: settingsModule },
|
|
6548
6709
|
cwd: workPath
|
|
6549
6710
|
});
|
|
6550
6711
|
return {
|
|
6551
6712
|
staticSourceDirs,
|
|
6552
|
-
staticRoot: staticRoot ? (0,
|
|
6713
|
+
staticRoot: staticRoot ? (0, import_path13.resolve)(workPath, staticRoot) : null,
|
|
6553
6714
|
cdnOutputDir: null,
|
|
6554
6715
|
manifestRelPath: null
|
|
6555
6716
|
};
|
|
@@ -6561,9 +6722,9 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6561
6722
|
return null;
|
|
6562
6723
|
}
|
|
6563
6724
|
const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
|
|
6564
|
-
const staticOutputDir = (0,
|
|
6565
|
-
await
|
|
6566
|
-
const shimPath = (0,
|
|
6725
|
+
const staticOutputDir = (0, import_path13.join)(outputStaticDir, staticUrlPath);
|
|
6726
|
+
await import_fs12.default.promises.mkdir(staticOutputDir, { recursive: true });
|
|
6727
|
+
const shimPath = (0, import_path13.join)(workPath, "_vercel_collectstatic_settings.py");
|
|
6567
6728
|
const shimLines = [
|
|
6568
6729
|
`from ${settingsModule} import *`,
|
|
6569
6730
|
`STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
|
|
@@ -6571,10 +6732,10 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6571
6732
|
if (whitenoiseUseFinders) {
|
|
6572
6733
|
shimLines.push(`WHITENOISE_USE_FINDERS = False`);
|
|
6573
6734
|
}
|
|
6574
|
-
await
|
|
6735
|
+
await import_fs12.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
|
|
6575
6736
|
try {
|
|
6576
6737
|
console.log("Running collectstatic...");
|
|
6577
|
-
await (0,
|
|
6738
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
6578
6739
|
env: {
|
|
6579
6740
|
...env,
|
|
6580
6741
|
DJANGO_SETTINGS_MODULE: "_vercel_collectstatic_settings"
|
|
@@ -6582,7 +6743,7 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6582
6743
|
cwd: workPath
|
|
6583
6744
|
});
|
|
6584
6745
|
} finally {
|
|
6585
|
-
await
|
|
6746
|
+
await import_fs12.default.promises.unlink(shimPath).catch(() => {
|
|
6586
6747
|
});
|
|
6587
6748
|
}
|
|
6588
6749
|
const MANIFEST_STORAGE_BACKENDS = [
|
|
@@ -6591,17 +6752,17 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6591
6752
|
];
|
|
6592
6753
|
let manifestRelPath = null;
|
|
6593
6754
|
if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
|
|
6594
|
-
const manifestSrc = (0,
|
|
6595
|
-
const resolvedStaticRoot = (0,
|
|
6596
|
-
const manifestDest = (0,
|
|
6597
|
-
await
|
|
6598
|
-
await
|
|
6599
|
-
manifestRelPath = (0,
|
|
6600
|
-
(0,
|
|
6755
|
+
const manifestSrc = (0, import_path13.join)(staticOutputDir, "staticfiles.json");
|
|
6756
|
+
const resolvedStaticRoot = (0, import_path13.resolve)(workPath, staticRoot);
|
|
6757
|
+
const manifestDest = (0, import_path13.join)(resolvedStaticRoot, "staticfiles.json");
|
|
6758
|
+
await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
|
|
6759
|
+
await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
|
|
6760
|
+
manifestRelPath = (0, import_path13.relative)(workPath, manifestDest);
|
|
6761
|
+
(0, import_build_utils15.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
|
|
6601
6762
|
}
|
|
6602
6763
|
return {
|
|
6603
6764
|
staticSourceDirs,
|
|
6604
|
-
staticRoot: staticRoot ? (0,
|
|
6765
|
+
staticRoot: staticRoot ? (0, import_path13.resolve)(workPath, staticRoot) : null,
|
|
6605
6766
|
cdnOutputDir: outputStaticDir,
|
|
6606
6767
|
manifestRelPath
|
|
6607
6768
|
};
|
|
@@ -6609,7 +6770,7 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6609
6770
|
|
|
6610
6771
|
// src/index.ts
|
|
6611
6772
|
var import_python_analysis9 = require("@vercel/python-analysis");
|
|
6612
|
-
var writeFile =
|
|
6773
|
+
var writeFile = import_fs13.default.promises.writeFile;
|
|
6613
6774
|
var version = -1;
|
|
6614
6775
|
async function runFrameworkHook(framework, ctx) {
|
|
6615
6776
|
const hook = framework ? frameworkHooks[framework] : void 0;
|
|
@@ -6624,7 +6785,7 @@ var frameworkHooks = {
|
|
|
6624
6785
|
detected
|
|
6625
6786
|
}) => {
|
|
6626
6787
|
if (detected?.baseDir === void 0) {
|
|
6627
|
-
(0,
|
|
6788
|
+
(0, import_build_utils16.debug)("Django hook: no manage.py detected, skipping");
|
|
6628
6789
|
return;
|
|
6629
6790
|
}
|
|
6630
6791
|
let settingsResult;
|
|
@@ -6638,13 +6799,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
|
|
|
6638
6799
|
} else {
|
|
6639
6800
|
detail = err?.stderr || err?.message || String(err);
|
|
6640
6801
|
}
|
|
6641
|
-
throw new
|
|
6802
|
+
throw new import_build_utils16.NowBuildError({
|
|
6642
6803
|
code: "DJANGO_SETTINGS_FAILED",
|
|
6643
6804
|
message: `Failed to read Django application settings from ${projectDir}/manage.py:
|
|
6644
6805
|
${detail}`
|
|
6645
6806
|
});
|
|
6646
6807
|
}
|
|
6647
|
-
(0,
|
|
6808
|
+
(0, import_build_utils16.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
|
|
6648
6809
|
const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
|
|
6649
6810
|
if (djangoVersion) {
|
|
6650
6811
|
console.log(`Django ${djangoVersion.join(".")} detected`);
|
|
@@ -6657,7 +6818,7 @@ ${detail}`
|
|
|
6657
6818
|
const variableName = parts.at(-1);
|
|
6658
6819
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
6659
6820
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
6660
|
-
(0,
|
|
6821
|
+
(0, import_build_utils16.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
|
|
6661
6822
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
6662
6823
|
} else {
|
|
6663
6824
|
const wsgiApp = djangoSettings["WSGI_APPLICATION"];
|
|
@@ -6666,7 +6827,7 @@ ${detail}`
|
|
|
6666
6827
|
const variableName = parts.at(-1);
|
|
6667
6828
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
6668
6829
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
6669
|
-
(0,
|
|
6830
|
+
(0, import_build_utils16.debug)(
|
|
6670
6831
|
`Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
|
|
6671
6832
|
);
|
|
6672
6833
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
@@ -6674,7 +6835,7 @@ ${detail}`
|
|
|
6674
6835
|
}
|
|
6675
6836
|
let djangoStatic = null;
|
|
6676
6837
|
if (workPath && venvPath) {
|
|
6677
|
-
const outputStaticDir = (0,
|
|
6838
|
+
const outputStaticDir = (0, import_path14.join)(workPath, ".vercel", "output", "static");
|
|
6678
6839
|
djangoStatic = await runDjangoCollectStatic(
|
|
6679
6840
|
venvPath,
|
|
6680
6841
|
workPath,
|
|
@@ -6694,14 +6855,14 @@ async function downloadFilesInWorkPath({
|
|
|
6694
6855
|
files,
|
|
6695
6856
|
meta = {}
|
|
6696
6857
|
}) {
|
|
6697
|
-
(0,
|
|
6698
|
-
let downloadedFiles = await (0,
|
|
6858
|
+
(0, import_build_utils16.debug)("Downloading user files...");
|
|
6859
|
+
let downloadedFiles = await (0, import_build_utils16.download)(files, workPath, meta);
|
|
6699
6860
|
if (meta.isDev && entrypoint) {
|
|
6700
|
-
const { devCacheDir = (0,
|
|
6701
|
-
const cacheKey = (0,
|
|
6702
|
-
const destCache = (0,
|
|
6703
|
-
await (0,
|
|
6704
|
-
downloadedFiles = await (0,
|
|
6861
|
+
const { devCacheDir = (0, import_path14.join)(workPath, ".now", "cache") } = meta;
|
|
6862
|
+
const cacheKey = (0, import_path14.basename)(entrypoint).replace(/\./g, "_");
|
|
6863
|
+
const destCache = (0, import_path14.join)(devCacheDir, cacheKey);
|
|
6864
|
+
await (0, import_build_utils16.download)(downloadedFiles, destCache);
|
|
6865
|
+
downloadedFiles = await (0, import_build_utils16.glob)("**", destCache);
|
|
6705
6866
|
workPath = destCache;
|
|
6706
6867
|
}
|
|
6707
6868
|
return workPath;
|
|
@@ -6717,13 +6878,13 @@ var build = async ({
|
|
|
6717
6878
|
service
|
|
6718
6879
|
}) => {
|
|
6719
6880
|
let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
|
|
6720
|
-
const builderSpan = parentSpan ?? new
|
|
6881
|
+
const builderSpan = parentSpan ?? new import_build_utils16.Span({ name: "vc.builder" });
|
|
6721
6882
|
const framework = config?.framework;
|
|
6722
6883
|
const shouldInstallVercelWorkers = config?.hasWorkerServices === true;
|
|
6723
6884
|
let spawnEnv;
|
|
6724
6885
|
let projectInstallCommand;
|
|
6725
6886
|
let hasCustomCommand = false;
|
|
6726
|
-
(0,
|
|
6887
|
+
(0, import_build_utils16.debug)(`workPath: ${workPath}`);
|
|
6727
6888
|
workPath = await downloadFilesInWorkPath({
|
|
6728
6889
|
workPath,
|
|
6729
6890
|
files: originalFiles,
|
|
@@ -6732,7 +6893,7 @@ var build = async ({
|
|
|
6732
6893
|
});
|
|
6733
6894
|
try {
|
|
6734
6895
|
if (meta.isDev) {
|
|
6735
|
-
const setupCfg = (0,
|
|
6896
|
+
const setupCfg = (0, import_path14.join)(workPath, "setup.cfg");
|
|
6736
6897
|
await writeFile(setupCfg, "[install]\nprefix=\n");
|
|
6737
6898
|
}
|
|
6738
6899
|
} catch (err) {
|
|
@@ -6755,8 +6916,8 @@ var build = async ({
|
|
|
6755
6916
|
if (detected?.error && detected?.baseDir === void 0) {
|
|
6756
6917
|
throw detected?.error;
|
|
6757
6918
|
}
|
|
6758
|
-
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0,
|
|
6759
|
-
const entrypointAbsDir = (0,
|
|
6919
|
+
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path14.dirname)(entrypoint) : ".");
|
|
6920
|
+
const entrypointAbsDir = (0, import_path14.join)(workPath, entryDirectory);
|
|
6760
6921
|
const rootDir = repoRootPath ?? workPath;
|
|
6761
6922
|
const pythonPackage = await builderSpan.child("vc.builder.python.discover").trace(
|
|
6762
6923
|
() => discoverPackage({
|
|
@@ -6786,12 +6947,26 @@ var build = async ({
|
|
|
6786
6947
|
`
|
|
6787
6948
|
);
|
|
6788
6949
|
}
|
|
6789
|
-
const venvPath = service?.name ? (0, import_path13.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path13.join)(workPath, ".vercel", "python", ".venv");
|
|
6790
6950
|
const uvCacheDir = getUvCacheDir(workPath);
|
|
6791
|
-
|
|
6792
|
-
|
|
6951
|
+
let uv;
|
|
6952
|
+
try {
|
|
6953
|
+
const uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
|
|
6954
|
+
uv = new UvRunner(uvPath, uvCacheDir);
|
|
6955
|
+
const uvVersionOutput = (0, import_child_process3.execSync)(`${uvPath} --version`, {
|
|
6956
|
+
encoding: "utf8"
|
|
6957
|
+
}).trim();
|
|
6958
|
+
console.log(`Using ${uvVersionOutput}`);
|
|
6959
|
+
} catch (err) {
|
|
6960
|
+
console.log("Failed to install or locate uv");
|
|
6961
|
+
throw new Error(
|
|
6962
|
+
`uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
|
|
6963
|
+
);
|
|
6964
|
+
}
|
|
6965
|
+
const venvPath = service?.name ? (0, import_path14.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path14.join)(workPath, ".vercel", "python", ".venv");
|
|
6966
|
+
const hasCachedVenv = import_fs13.default.existsSync((0, import_path14.join)(venvPath, "pyvenv.cfg"));
|
|
6967
|
+
const hasCachedUv = import_fs13.default.existsSync(uvCacheDir);
|
|
6793
6968
|
if (hasCachedVenv || hasCachedUv) {
|
|
6794
|
-
(0,
|
|
6969
|
+
(0, import_build_utils16.debug)(
|
|
6795
6970
|
`Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
|
|
6796
6971
|
);
|
|
6797
6972
|
}
|
|
@@ -6799,17 +6974,18 @@ var build = async ({
|
|
|
6799
6974
|
await ensureVenv({
|
|
6800
6975
|
pythonVersion,
|
|
6801
6976
|
venvPath,
|
|
6977
|
+
uvPath: uv.getPath(),
|
|
6802
6978
|
uvCacheDir
|
|
6803
6979
|
});
|
|
6804
6980
|
});
|
|
6805
|
-
if ((0,
|
|
6981
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
6806
6982
|
const {
|
|
6807
6983
|
cliType,
|
|
6808
6984
|
lockfileVersion,
|
|
6809
6985
|
packageJsonPackageManager,
|
|
6810
6986
|
turboSupportsCorepackHome
|
|
6811
|
-
} = await (0,
|
|
6812
|
-
spawnEnv = (0,
|
|
6987
|
+
} = await (0, import_build_utils16.scanParentDirs)(workPath, true);
|
|
6988
|
+
spawnEnv = (0, import_build_utils16.getEnvForPackageManager)({
|
|
6813
6989
|
cliType,
|
|
6814
6990
|
lockfileVersion,
|
|
6815
6991
|
packageJsonPackageManager,
|
|
@@ -6831,38 +7007,25 @@ var build = async ({
|
|
|
6831
7007
|
const pythonEnv = createVenvEnv(venvPath, baseEnv, uvCacheDir);
|
|
6832
7008
|
pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
|
|
6833
7009
|
let assumeDepsInstalled = false;
|
|
6834
|
-
let uv;
|
|
6835
|
-
try {
|
|
6836
|
-
const uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
|
|
6837
|
-
uv = new UvRunner(uvPath, uvCacheDir);
|
|
6838
|
-
const uvVersionOutput = (0, import_child_process3.execSync)(`${uvPath} --version`, {
|
|
6839
|
-
encoding: "utf8"
|
|
6840
|
-
}).trim();
|
|
6841
|
-
console.log(`Using ${uvVersionOutput}`);
|
|
6842
|
-
} catch (err) {
|
|
6843
|
-
console.log("Failed to install or locate uv");
|
|
6844
|
-
throw new Error(
|
|
6845
|
-
`uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
|
|
6846
|
-
);
|
|
6847
|
-
}
|
|
6848
7010
|
let uvLockPath = null;
|
|
6849
7011
|
let uvProjectDir = null;
|
|
6850
7012
|
let projectName;
|
|
6851
|
-
await builderSpan.child(
|
|
7013
|
+
await builderSpan.child(import_build_utils16.BUILDER_INSTALLER_STEP, {
|
|
6852
7014
|
installCommand: projectInstallCommand || void 0
|
|
6853
7015
|
}).trace(async () => {
|
|
6854
7016
|
if (projectInstallCommand) {
|
|
6855
|
-
await
|
|
7017
|
+
await import_fs13.default.promises.rm(venvPath, { recursive: true, force: true });
|
|
6856
7018
|
await ensureVenv({
|
|
6857
7019
|
pythonVersion,
|
|
6858
7020
|
venvPath,
|
|
7021
|
+
uvPath: uv.getPath(),
|
|
6859
7022
|
uvCacheDir,
|
|
6860
7023
|
quiet: true
|
|
6861
7024
|
});
|
|
6862
7025
|
console.log(
|
|
6863
7026
|
`Running "install" command: \`${projectInstallCommand}\`...`
|
|
6864
7027
|
);
|
|
6865
|
-
await (0,
|
|
7028
|
+
await (0, import_build_utils16.execCommand)(projectInstallCommand, {
|
|
6866
7029
|
env: pythonEnv,
|
|
6867
7030
|
cwd: workPath
|
|
6868
7031
|
});
|
|
@@ -6883,7 +7046,7 @@ var build = async ({
|
|
|
6883
7046
|
}
|
|
6884
7047
|
if (!assumeDepsInstalled) {
|
|
6885
7048
|
const lockCacheKey = service?.name ? `uv.lock.${service.name}` : "uv.lock";
|
|
6886
|
-
const cachedLockPath = (0,
|
|
7049
|
+
const cachedLockPath = (0, import_path14.join)(uvCacheDir, lockCacheKey);
|
|
6887
7050
|
const { projectDir, lockPath, lockFileProvidedByUser } = await ensureUvProject({
|
|
6888
7051
|
workPath,
|
|
6889
7052
|
rootDir,
|
|
@@ -6903,21 +7066,21 @@ var build = async ({
|
|
|
6903
7066
|
frozen: lockFileProvidedByUser,
|
|
6904
7067
|
locked: !lockFileProvidedByUser
|
|
6905
7068
|
});
|
|
6906
|
-
if (lockPath &&
|
|
6907
|
-
await
|
|
6908
|
-
await
|
|
7069
|
+
if (lockPath && import_fs13.default.existsSync(lockPath)) {
|
|
7070
|
+
await import_fs13.default.promises.mkdir(uvCacheDir, { recursive: true });
|
|
7071
|
+
await import_fs13.default.promises.copyFile(lockPath, cachedLockPath);
|
|
6909
7072
|
}
|
|
6910
7073
|
}
|
|
6911
7074
|
});
|
|
6912
|
-
if ((0,
|
|
7075
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
6913
7076
|
const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
|
|
6914
7077
|
config?.buildCommand;
|
|
6915
|
-
await builderSpan.child(
|
|
7078
|
+
await builderSpan.child(import_build_utils16.BUILDER_COMPILE_STEP, {
|
|
6916
7079
|
buildCommand: projectBuildCommand || void 0
|
|
6917
7080
|
}).trace(async () => {
|
|
6918
7081
|
if (projectBuildCommand) {
|
|
6919
7082
|
console.log(`Running "${projectBuildCommand}"`);
|
|
6920
|
-
await (0,
|
|
7083
|
+
await (0, import_build_utils16.execCommand)(projectBuildCommand, {
|
|
6921
7084
|
env: pythonEnv,
|
|
6922
7085
|
cwd: workPath
|
|
6923
7086
|
});
|
|
@@ -6932,7 +7095,7 @@ var build = async ({
|
|
|
6932
7095
|
}
|
|
6933
7096
|
const hookResult = await runFrameworkHook(framework, {
|
|
6934
7097
|
pythonEnv,
|
|
6935
|
-
projectDir: (0,
|
|
7098
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6936
7099
|
workPath,
|
|
6937
7100
|
venvPath,
|
|
6938
7101
|
entrypoint,
|
|
@@ -6944,25 +7107,25 @@ var build = async ({
|
|
|
6944
7107
|
}
|
|
6945
7108
|
entrypoint = resolved?.entrypoint;
|
|
6946
7109
|
if (!entrypoint) {
|
|
6947
|
-
throw new
|
|
7110
|
+
throw new import_build_utils16.NowBuildError({
|
|
6948
7111
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
6949
7112
|
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
6950
7113
|
});
|
|
6951
7114
|
}
|
|
6952
7115
|
const djangoStatic = hookResult?.djangoStatic ?? null;
|
|
6953
7116
|
const runtimeDep = baseEnv.VERCEL_RUNTIME_PYTHON || `vercel-runtime==${VERCEL_RUNTIME_VERSION}`;
|
|
6954
|
-
(0,
|
|
7117
|
+
(0, import_build_utils16.debug)(`Installing ${runtimeDep}`);
|
|
6955
7118
|
await uv.pip({
|
|
6956
7119
|
venvPath,
|
|
6957
|
-
projectDir: (0,
|
|
7120
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6958
7121
|
args: ["install", runtimeDep]
|
|
6959
7122
|
});
|
|
6960
7123
|
if (shouldInstallVercelWorkers) {
|
|
6961
7124
|
const workersDep = baseEnv.VERCEL_WORKERS_PYTHON || `vercel-workers==${VERCEL_WORKERS_VERSION}`;
|
|
6962
|
-
(0,
|
|
7125
|
+
(0, import_build_utils16.debug)(`Installing ${workersDep}`);
|
|
6963
7126
|
await uv.pip({
|
|
6964
7127
|
venvPath,
|
|
6965
|
-
projectDir: (0,
|
|
7128
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6966
7129
|
args: ["install", workersDep]
|
|
6967
7130
|
});
|
|
6968
7131
|
}
|
|
@@ -6970,14 +7133,14 @@ var build = async ({
|
|
|
6970
7133
|
if (quirksResult.buildEnv) {
|
|
6971
7134
|
Object.assign(pythonEnv, quirksResult.buildEnv);
|
|
6972
7135
|
}
|
|
6973
|
-
(0,
|
|
7136
|
+
(0, import_build_utils16.debug)("Entrypoint is", entrypoint);
|
|
6974
7137
|
const moduleName = entrypoint.replace(/\//g, ".").replace(/\.py$/i, "");
|
|
6975
7138
|
if (handlerFunction) {
|
|
6976
|
-
const entrypointPath = (0,
|
|
6977
|
-
const source = await
|
|
7139
|
+
const entrypointPath = (0, import_path14.join)(workPath, entrypoint);
|
|
7140
|
+
const source = await import_fs13.default.promises.readFile(entrypointPath, "utf-8");
|
|
6978
7141
|
const found = await (0, import_python_analysis9.containsTopLevelCallable)(source, handlerFunction);
|
|
6979
7142
|
if (!found) {
|
|
6980
|
-
throw new
|
|
7143
|
+
throw new import_build_utils16.NowBuildError({
|
|
6981
7144
|
code: "PYTHON_HANDLER_NOT_FOUND",
|
|
6982
7145
|
message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
|
|
6983
7146
|
});
|
|
@@ -6986,9 +7149,23 @@ var build = async ({
|
|
|
6986
7149
|
const vendorDir = resolveVendorDir();
|
|
6987
7150
|
const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
|
|
6988
7151
|
const entrypointWithSuffix = `${entrypoint}${suffix}`;
|
|
6989
|
-
(0,
|
|
6990
|
-
const
|
|
6991
|
-
|
|
7152
|
+
(0, import_build_utils16.debug)("Entrypoint with suffix is", entrypointWithSuffix);
|
|
7153
|
+
const crons = await getServiceCrons({
|
|
7154
|
+
service,
|
|
7155
|
+
entrypoint,
|
|
7156
|
+
rawEntrypoint,
|
|
7157
|
+
handlerFunction,
|
|
7158
|
+
pythonBin: getVenvPythonBin(venvPath),
|
|
7159
|
+
env: pythonEnv,
|
|
7160
|
+
workPath
|
|
7161
|
+
});
|
|
7162
|
+
let cronEnvLine = "";
|
|
7163
|
+
if (crons?.length) {
|
|
7164
|
+
const json = JSON.stringify(buildCronRouteTable(crons));
|
|
7165
|
+
(0, import_assert.default)(!json.includes("\\"), `backslash in cron route table: ${json}`);
|
|
7166
|
+
cronEnvLine = `
|
|
7167
|
+
"__VC_CRON_ROUTES": '${json}',`;
|
|
7168
|
+
}
|
|
6992
7169
|
const variableName = resolved?.variableName ?? "";
|
|
6993
7170
|
const runtimeTrampoline = `
|
|
6994
7171
|
import importlib
|
|
@@ -7004,7 +7181,7 @@ os.environ.update({
|
|
|
7004
7181
|
"__VC_HANDLER_ENTRYPOINT": "${entrypointWithSuffix}",
|
|
7005
7182
|
"__VC_HANDLER_ENTRYPOINT_ABS": os.path.join(_here, "${entrypointWithSuffix}"),
|
|
7006
7183
|
"__VC_HANDLER_VENDOR_DIR": "${vendorDir}",
|
|
7007
|
-
"__VC_HANDLER_VARIABLE_NAME": "${variableName}",${
|
|
7184
|
+
"__VC_HANDLER_VARIABLE_NAME": "${variableName}",${cronEnvLine}
|
|
7008
7185
|
})
|
|
7009
7186
|
|
|
7010
7187
|
_vendor_rel = '${vendorDir}'
|
|
@@ -7057,10 +7234,10 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7057
7234
|
cwd: workPath,
|
|
7058
7235
|
ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
|
|
7059
7236
|
};
|
|
7060
|
-
const files = await (0,
|
|
7237
|
+
const files = await (0, import_build_utils16.glob)("**", globOptions);
|
|
7061
7238
|
if (djangoStatic?.manifestRelPath) {
|
|
7062
|
-
files[djangoStatic.manifestRelPath] = new
|
|
7063
|
-
fsPath: (0,
|
|
7239
|
+
files[djangoStatic.manifestRelPath] = new import_build_utils16.FileFsRef({
|
|
7240
|
+
fsPath: (0, import_path14.join)(workPath, djangoStatic.manifestRelPath)
|
|
7064
7241
|
});
|
|
7065
7242
|
}
|
|
7066
7243
|
const depExternalizer = new PythonDependencyExternalizer({
|
|
@@ -7096,12 +7273,12 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7096
7273
|
}
|
|
7097
7274
|
});
|
|
7098
7275
|
const handlerPyFilename = "vc__handler__python";
|
|
7099
|
-
files[`${handlerPyFilename}.py`] = new
|
|
7276
|
+
files[`${handlerPyFilename}.py`] = new import_build_utils16.FileBlob({ data: runtimeTrampoline });
|
|
7100
7277
|
if (config.framework === "fasthtml") {
|
|
7101
7278
|
const { SESSKEY = "" } = process.env;
|
|
7102
|
-
files[".sesskey"] = new
|
|
7279
|
+
files[".sesskey"] = new import_build_utils16.FileBlob({ data: `"${SESSKEY}"` });
|
|
7103
7280
|
}
|
|
7104
|
-
const output = new
|
|
7281
|
+
const output = new import_build_utils16.Lambda({
|
|
7105
7282
|
files,
|
|
7106
7283
|
handler: `${handlerPyFilename}.vc_handler`,
|
|
7107
7284
|
runtime: pythonVersion.runtime,
|
|
@@ -7117,16 +7294,20 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7117
7294
|
uvLockPath
|
|
7118
7295
|
});
|
|
7119
7296
|
} catch (err) {
|
|
7120
|
-
(0,
|
|
7297
|
+
(0, import_build_utils16.debug)(
|
|
7121
7298
|
`Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
|
|
7122
7299
|
);
|
|
7123
7300
|
}
|
|
7124
7301
|
}
|
|
7125
|
-
if (!(0,
|
|
7302
|
+
if (!(0, import_build_utils16.isPythonFramework)(framework) && !service?.name) {
|
|
7126
7303
|
return { resultVersion: 3, result: { output } };
|
|
7127
7304
|
}
|
|
7128
7305
|
const lambdaPath = service?.name ? `_svc/${service.name}/index` : "index";
|
|
7129
|
-
const staticFiles = djangoStatic?.cdnOutputDir ? await (0,
|
|
7306
|
+
const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils16.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
|
|
7307
|
+
const routes = [
|
|
7308
|
+
{ handle: "filesystem" },
|
|
7309
|
+
{ src: "/(.*)", dest: `/${lambdaPath}` }
|
|
7310
|
+
];
|
|
7130
7311
|
return {
|
|
7131
7312
|
resultVersion: 2,
|
|
7132
7313
|
result: {
|
|
@@ -7134,10 +7315,8 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7134
7315
|
[lambdaPath]: output,
|
|
7135
7316
|
...staticFiles
|
|
7136
7317
|
},
|
|
7137
|
-
routes
|
|
7138
|
-
|
|
7139
|
-
{ src: "/(.*)", dest: `/${lambdaPath}` }
|
|
7140
|
-
]
|
|
7318
|
+
routes,
|
|
7319
|
+
crons
|
|
7141
7320
|
}
|
|
7142
7321
|
};
|
|
7143
7322
|
};
|
|
@@ -7159,14 +7338,14 @@ var prepareCache = async ({
|
|
|
7159
7338
|
}
|
|
7160
7339
|
} catch {
|
|
7161
7340
|
}
|
|
7162
|
-
return (0,
|
|
7341
|
+
return (0, import_build_utils16.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
|
|
7163
7342
|
cwd: root,
|
|
7164
7343
|
ignore
|
|
7165
7344
|
});
|
|
7166
7345
|
};
|
|
7167
7346
|
var shouldServe = (opts) => {
|
|
7168
7347
|
const framework = opts.config.framework;
|
|
7169
|
-
if ((0,
|
|
7348
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
7170
7349
|
const requestPath = opts.requestPath.replace(/\/$/, "");
|
|
7171
7350
|
if (requestPath.startsWith("api") && opts.hasMatched) {
|
|
7172
7351
|
return false;
|
|
@@ -7185,7 +7364,7 @@ var defaultShouldServe = ({
|
|
|
7185
7364
|
if (entrypoint === requestPath && hasProp(files, entrypoint)) {
|
|
7186
7365
|
return true;
|
|
7187
7366
|
}
|
|
7188
|
-
const { dir, name } = (0,
|
|
7367
|
+
const { dir, name } = (0, import_path14.parse)(entrypoint);
|
|
7189
7368
|
if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
|
|
7190
7369
|
return true;
|
|
7191
7370
|
}
|