@vercel/python 6.32.0 → 6.33.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 +474 -297
- 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
|
}
|
|
@@ -4313,6 +4314,11 @@ 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;
|
|
4315
4316
|
var HIVE_LAMBDA_SIZE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
4317
|
+
var FUNCTIONS_BETA_CTA = "Run `vercel deploy --functions-beta` to use extended function limits (up to 1 GB), or reduce your dependency footprint.";
|
|
4318
|
+
function shouldShowFunctionsBetaHint() {
|
|
4319
|
+
const v = process.env.VERCEL_FUNCTIONS_BETA_HINT;
|
|
4320
|
+
return v === "1" || v === "true";
|
|
4321
|
+
}
|
|
4316
4322
|
var PythonDependencyExternalizer = class {
|
|
4317
4323
|
constructor(options) {
|
|
4318
4324
|
// Populated by analyze()
|
|
@@ -4367,7 +4373,9 @@ var PythonDependencyExternalizer = class {
|
|
|
4367
4373
|
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
4368
4374
|
throw new import_build_utils5.NowBuildError({
|
|
4369
4375
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
4370
|
-
message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the
|
|
4376
|
+
message: shouldShowFunctionsBetaHint() ? `Total bundle size (${totalBundleSizeMB} MB) exceeds the size limit (${limitMB} MB).
|
|
4377
|
+
|
|
4378
|
+
` + FUNCTIONS_BETA_CTA : `Total bundle size (${totalBundleSizeMB} MB) exceeds the Lambda size limit (${limitMB} MB).
|
|
4371
4379
|
|
|
4372
4380
|
Runtime dependency installation is not available for projects that use a custom build or install command, because custom commands may install dependencies that are not tracked in uv.lock.
|
|
4373
4381
|
|
|
@@ -4419,7 +4427,9 @@ To resolve this, either:
|
|
|
4419
4427
|
const ephemeralLimitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(0);
|
|
4420
4428
|
throw new import_build_utils5.NowBuildError({
|
|
4421
4429
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
4422
|
-
message: `Total dependency size (${totalBundleSizeMB} MB) exceeds
|
|
4430
|
+
message: shouldShowFunctionsBetaHint() ? `Total dependency size (${totalBundleSizeMB} MB) exceeds the size limit (${ephemeralLimitMB} MB).
|
|
4431
|
+
|
|
4432
|
+
` + FUNCTIONS_BETA_CTA : `Total dependency size (${totalBundleSizeMB} MB) exceeds Lambda ephemeral storage limit (${ephemeralLimitMB} MB). Even with runtime dependency installation, all packages must fit within the ${ephemeralLimitMB} MB ephemeral storage available to Lambda functions. Consider removing unused dependencies or splitting your application into smaller functions.`,
|
|
4423
4433
|
link: "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled",
|
|
4424
4434
|
action: "Learn More"
|
|
4425
4435
|
});
|
|
@@ -4613,7 +4623,9 @@ To fix this, either:
|
|
|
4613
4623
|
const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
|
|
4614
4624
|
throw new import_build_utils5.NowBuildError({
|
|
4615
4625
|
code: "LAMBDA_SIZE_EXCEEDED",
|
|
4616
|
-
message: `Bundle size (${finalSizeMB} MB) exceeds
|
|
4626
|
+
message: shouldShowFunctionsBetaHint() ? `Bundle size (${finalSizeMB} MB) exceeds the size limit (${limitMB} MB).
|
|
4627
|
+
|
|
4628
|
+
` + FUNCTIONS_BETA_CTA : `Bundle size (${finalSizeMB} MB) exceeds Lambda limit (${limitMB} MB) even after deferring public packages to runtime installation. This usually means your private packages or source code are too large. Consider reducing the size of private dependencies or splitting your application.`,
|
|
4617
4629
|
link: "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled",
|
|
4618
4630
|
action: "Learn More"
|
|
4619
4631
|
});
|
|
@@ -5103,20 +5115,161 @@ var diagnostics = async ({
|
|
|
5103
5115
|
}
|
|
5104
5116
|
};
|
|
5105
5117
|
|
|
5118
|
+
// src/crons.ts
|
|
5119
|
+
var import_fs7 = __toESM(require("fs"));
|
|
5120
|
+
var import_path8 = require("path");
|
|
5121
|
+
var import_execa4 = __toESM(require_execa());
|
|
5122
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
5123
|
+
var DYNAMIC_SCHEDULE = "<dynamic>";
|
|
5124
|
+
function entrypointToModule(entrypoint) {
|
|
5125
|
+
return entrypoint.replace(/\\/g, "/").replace(/\.py$/i, "").replace(/\//g, ".");
|
|
5126
|
+
}
|
|
5127
|
+
var scriptPath = (0, import_path8.join)(__dirname, "..", "templates", "vc_cron_detect.py");
|
|
5128
|
+
var script = import_fs7.default.readFileSync(scriptPath, "utf-8");
|
|
5129
|
+
function buildCronRouteTable(crons) {
|
|
5130
|
+
const table = {};
|
|
5131
|
+
for (const cron of crons) {
|
|
5132
|
+
table[cron.path] = cron.resolvedHandler;
|
|
5133
|
+
}
|
|
5134
|
+
return table;
|
|
5135
|
+
}
|
|
5136
|
+
async function getServiceCrons(opts) {
|
|
5137
|
+
const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
|
|
5138
|
+
if (service?.type !== "cron" || !service.name || typeof service.schedule !== "string") {
|
|
5139
|
+
return void 0;
|
|
5140
|
+
}
|
|
5141
|
+
const cronEntrypoint = entrypoint || rawEntrypoint;
|
|
5142
|
+
if (!cronEntrypoint) {
|
|
5143
|
+
throw new import_build_utils7.NowBuildError({
|
|
5144
|
+
code: "PYTHON_CRON_NO_ENTRYPOINT",
|
|
5145
|
+
message: "Cron service is missing an entrypoint."
|
|
5146
|
+
});
|
|
5147
|
+
}
|
|
5148
|
+
if (service.schedule === DYNAMIC_SCHEDULE) {
|
|
5149
|
+
return getServiceCronsDynamic({
|
|
5150
|
+
serviceName: service.name,
|
|
5151
|
+
cronEntrypoint,
|
|
5152
|
+
handlerFunction,
|
|
5153
|
+
pythonBin: opts.pythonBin,
|
|
5154
|
+
env: opts.env,
|
|
5155
|
+
workPath: opts.workPath
|
|
5156
|
+
});
|
|
5157
|
+
}
|
|
5158
|
+
const cronPath = (0, import_build_utils7.getInternalServiceCronPath)(
|
|
5159
|
+
service.name,
|
|
5160
|
+
cronEntrypoint,
|
|
5161
|
+
handlerFunction || "cron"
|
|
5162
|
+
);
|
|
5163
|
+
const moduleName = entrypointToModule(cronEntrypoint);
|
|
5164
|
+
const resolvedHandler = handlerFunction ? `${moduleName}:${handlerFunction}` : moduleName;
|
|
5165
|
+
return [{ path: cronPath, schedule: service.schedule, resolvedHandler }];
|
|
5166
|
+
}
|
|
5167
|
+
async function getServiceCronsDynamic(opts) {
|
|
5168
|
+
const {
|
|
5169
|
+
serviceName,
|
|
5170
|
+
cronEntrypoint,
|
|
5171
|
+
handlerFunction,
|
|
5172
|
+
pythonBin,
|
|
5173
|
+
env,
|
|
5174
|
+
workPath
|
|
5175
|
+
} = opts;
|
|
5176
|
+
if (!handlerFunction) {
|
|
5177
|
+
throw new import_build_utils7.NowBuildError({
|
|
5178
|
+
code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
|
|
5179
|
+
message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
|
|
5180
|
+
});
|
|
5181
|
+
}
|
|
5182
|
+
const moduleName = entrypointToModule(cronEntrypoint);
|
|
5183
|
+
const entries = await detectDynamicCrons({
|
|
5184
|
+
pythonBin,
|
|
5185
|
+
env,
|
|
5186
|
+
workPath,
|
|
5187
|
+
moduleName,
|
|
5188
|
+
attrName: handlerFunction
|
|
5189
|
+
});
|
|
5190
|
+
console.log(
|
|
5191
|
+
`Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
|
|
5192
|
+
);
|
|
5193
|
+
if (entries.length === 0) {
|
|
5194
|
+
throw new import_build_utils7.NowBuildError({
|
|
5195
|
+
code: "PYTHON_DYNAMIC_CRON_EMPTY",
|
|
5196
|
+
message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
|
|
5197
|
+
});
|
|
5198
|
+
}
|
|
5199
|
+
return entries.map((entry) => {
|
|
5200
|
+
const cronPath = moduleColonFuncToCronPath(
|
|
5201
|
+
serviceName,
|
|
5202
|
+
entry.module_function
|
|
5203
|
+
);
|
|
5204
|
+
return {
|
|
5205
|
+
path: cronPath,
|
|
5206
|
+
schedule: entry.schedule,
|
|
5207
|
+
resolvedHandler: entry.module_function
|
|
5208
|
+
};
|
|
5209
|
+
});
|
|
5210
|
+
}
|
|
5211
|
+
async function detectDynamicCrons(opts) {
|
|
5212
|
+
const { pythonBin, env, workPath, moduleName, attrName } = opts;
|
|
5213
|
+
let stdout;
|
|
5214
|
+
try {
|
|
5215
|
+
const result = await (0, import_execa4.default)(
|
|
5216
|
+
pythonBin,
|
|
5217
|
+
["-c", script, moduleName, attrName],
|
|
5218
|
+
{ env, cwd: workPath }
|
|
5219
|
+
);
|
|
5220
|
+
stdout = result.stdout;
|
|
5221
|
+
} catch (err) {
|
|
5222
|
+
let detail = err?.stderr || err?.message || String(err);
|
|
5223
|
+
try {
|
|
5224
|
+
const parsed2 = JSON.parse(err?.stdout);
|
|
5225
|
+
if (parsed2.error)
|
|
5226
|
+
detail = parsed2.error;
|
|
5227
|
+
} catch {
|
|
5228
|
+
}
|
|
5229
|
+
throw new import_build_utils7.NowBuildError({
|
|
5230
|
+
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
5231
|
+
message: `Failed to detect dynamic cron entries: ${detail}`
|
|
5232
|
+
});
|
|
5233
|
+
}
|
|
5234
|
+
let parsed;
|
|
5235
|
+
try {
|
|
5236
|
+
parsed = JSON.parse(stdout);
|
|
5237
|
+
} catch {
|
|
5238
|
+
throw new import_build_utils7.NowBuildError({
|
|
5239
|
+
code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
|
|
5240
|
+
message: `Dynamic cron detection returned invalid JSON: ${stdout}`
|
|
5241
|
+
});
|
|
5242
|
+
}
|
|
5243
|
+
return parsed.entries || [];
|
|
5244
|
+
}
|
|
5245
|
+
function moduleColonFuncToCronPath(serviceName, moduleFunction) {
|
|
5246
|
+
const colonIdx = moduleFunction.indexOf(":");
|
|
5247
|
+
if (colonIdx === -1) {
|
|
5248
|
+
throw new import_build_utils7.NowBuildError({
|
|
5249
|
+
code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
|
|
5250
|
+
message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
|
|
5251
|
+
});
|
|
5252
|
+
}
|
|
5253
|
+
const modulePart = moduleFunction.slice(0, colonIdx);
|
|
5254
|
+
const funcPart = moduleFunction.slice(colonIdx + 1);
|
|
5255
|
+
const entrypointPath = modulePart.replace(/\./g, "/");
|
|
5256
|
+
return (0, import_build_utils7.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
|
|
5257
|
+
}
|
|
5258
|
+
|
|
5106
5259
|
// src/start-dev-server.ts
|
|
5107
5260
|
var import_child_process2 = require("child_process");
|
|
5108
|
-
var
|
|
5109
|
-
var
|
|
5110
|
-
var
|
|
5261
|
+
var import_fs9 = require("fs");
|
|
5262
|
+
var import_path10 = require("path");
|
|
5263
|
+
var import_build_utils11 = require("@vercel/build-utils");
|
|
5111
5264
|
var import_get_port = __toESM(require_get_port());
|
|
5112
5265
|
var import_is_port_reachable = __toESM(require_is_port_reachable());
|
|
5113
5266
|
|
|
5114
5267
|
// src/entrypoint.ts
|
|
5115
|
-
var
|
|
5116
|
-
var
|
|
5117
|
-
var import_build_utils7 = require("@vercel/build-utils");
|
|
5268
|
+
var import_fs8 = __toESM(require("fs"));
|
|
5269
|
+
var import_path9 = require("path");
|
|
5118
5270
|
var import_build_utils8 = require("@vercel/build-utils");
|
|
5119
5271
|
var import_build_utils9 = require("@vercel/build-utils");
|
|
5272
|
+
var import_build_utils10 = require("@vercel/build-utils");
|
|
5120
5273
|
var import_python_analysis5 = require("@vercel/python-analysis");
|
|
5121
5274
|
var PYTHON_ENTRYPOINT_FILENAMES = [
|
|
5122
5275
|
"app",
|
|
@@ -5133,27 +5286,27 @@ var PYTHON_CANDIDATE_ENTRYPOINTS = getCandidateEntrypointsInDirs(
|
|
|
5133
5286
|
function getCandidateEntrypointsInDirs(dirs) {
|
|
5134
5287
|
return dirs.flatMap(
|
|
5135
5288
|
(dir) => PYTHON_ENTRYPOINT_FILENAMES.map(
|
|
5136
|
-
(filename) =>
|
|
5289
|
+
(filename) => import_path9.posix.join(dir, `${filename}.py`)
|
|
5137
5290
|
)
|
|
5138
5291
|
);
|
|
5139
5292
|
}
|
|
5140
5293
|
async function fileExists(filePath) {
|
|
5141
5294
|
try {
|
|
5142
|
-
const stat = await
|
|
5295
|
+
const stat = await import_fs8.default.promises.stat(filePath);
|
|
5143
5296
|
return stat.isFile();
|
|
5144
5297
|
} catch {
|
|
5145
5298
|
return false;
|
|
5146
5299
|
}
|
|
5147
5300
|
}
|
|
5148
5301
|
async function checkEntrypoint(workPath, relPath) {
|
|
5149
|
-
const absPath = (0,
|
|
5302
|
+
const absPath = (0, import_path9.join)(workPath, relPath);
|
|
5150
5303
|
if (!await fileExists(absPath))
|
|
5151
5304
|
return null;
|
|
5152
|
-
const content = await
|
|
5305
|
+
const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
|
|
5153
5306
|
return (0, import_python_analysis5.findAppOrHandler)(content);
|
|
5154
5307
|
}
|
|
5155
5308
|
async function getPyprojectEntrypoint(workPath) {
|
|
5156
|
-
const pyprojectData = await (0,
|
|
5309
|
+
const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path9.join)(workPath, "pyproject.toml"));
|
|
5157
5310
|
if (!pyprojectData)
|
|
5158
5311
|
return null;
|
|
5159
5312
|
const scripts = pyprojectData.project?.scripts;
|
|
@@ -5168,7 +5321,7 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
5168
5321
|
const relPath = modulePath.replace(/\./g, "/");
|
|
5169
5322
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
5170
5323
|
for (const candidate of candidates) {
|
|
5171
|
-
if (await fileExists((0,
|
|
5324
|
+
if (await fileExists((0, import_path9.join)(workPath, candidate))) {
|
|
5172
5325
|
return { entrypoint: candidate, variableName };
|
|
5173
5326
|
}
|
|
5174
5327
|
}
|
|
@@ -5178,19 +5331,19 @@ async function findValidEntrypoint(workPath, candidates) {
|
|
|
5178
5331
|
for (const candidate of candidates) {
|
|
5179
5332
|
const varName = await checkEntrypoint(workPath, candidate);
|
|
5180
5333
|
if (varName) {
|
|
5181
|
-
(0,
|
|
5334
|
+
(0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
|
|
5182
5335
|
return { entrypoint: candidate, variableName: varName };
|
|
5183
5336
|
}
|
|
5184
5337
|
}
|
|
5185
5338
|
return null;
|
|
5186
5339
|
}
|
|
5187
5340
|
async function checkDjangoManage(workPath) {
|
|
5188
|
-
const managePath = (0,
|
|
5341
|
+
const managePath = (0, import_path9.join)(workPath, "manage.py");
|
|
5189
5342
|
try {
|
|
5190
|
-
const content = await
|
|
5343
|
+
const content = await import_fs8.default.promises.readFile(managePath, "utf-8");
|
|
5191
5344
|
if (!content.includes("DJANGO_SETTINGS_MODULE"))
|
|
5192
5345
|
return false;
|
|
5193
|
-
(0,
|
|
5346
|
+
(0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
|
|
5194
5347
|
return true;
|
|
5195
5348
|
} catch {
|
|
5196
5349
|
return false;
|
|
@@ -5198,7 +5351,7 @@ async function checkDjangoManage(workPath) {
|
|
|
5198
5351
|
}
|
|
5199
5352
|
async function getSubdirectories(workPath) {
|
|
5200
5353
|
try {
|
|
5201
|
-
const entries = await
|
|
5354
|
+
const entries = await import_fs8.default.promises.readdir(workPath, {
|
|
5202
5355
|
withFileTypes: true
|
|
5203
5356
|
});
|
|
5204
5357
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
@@ -5208,7 +5361,7 @@ async function getSubdirectories(workPath) {
|
|
|
5208
5361
|
}
|
|
5209
5362
|
function makeDetectError(framework) {
|
|
5210
5363
|
const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
5211
|
-
return new
|
|
5364
|
+
return new import_build_utils8.NowBuildError({
|
|
5212
5365
|
code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
|
|
5213
5366
|
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
|
|
5214
5367
|
link: `https://vercel.com/docs/frameworks/backend/${framework}#exporting-the-${framework}-application`,
|
|
@@ -5223,7 +5376,7 @@ async function detectGenericPythonEntrypoint(workPath) {
|
|
|
5223
5376
|
);
|
|
5224
5377
|
return found ? { entrypoint: found } : null;
|
|
5225
5378
|
} catch {
|
|
5226
|
-
(0,
|
|
5379
|
+
(0, import_build_utils9.debug)("Failed to discover Python entrypoint");
|
|
5227
5380
|
return null;
|
|
5228
5381
|
}
|
|
5229
5382
|
}
|
|
@@ -5232,7 +5385,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
5232
5385
|
const subdirs = await getSubdirectories(workPath);
|
|
5233
5386
|
const rootDirs = ["", ...subdirs];
|
|
5234
5387
|
for (const rootDir of rootDirs) {
|
|
5235
|
-
const currPath = (0,
|
|
5388
|
+
const currPath = (0, import_path9.join)(workPath, rootDir);
|
|
5236
5389
|
const isDjango = await checkDjangoManage(currPath);
|
|
5237
5390
|
if (isDjango) {
|
|
5238
5391
|
return { baseDir: rootDir, error: makeDetectError("django") };
|
|
@@ -5242,7 +5395,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
|
|
|
5242
5395
|
const found = await findValidEntrypoint(workPath, candidates);
|
|
5243
5396
|
return found ? { entrypoint: found } : null;
|
|
5244
5397
|
} catch {
|
|
5245
|
-
(0,
|
|
5398
|
+
(0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
|
|
5246
5399
|
return null;
|
|
5247
5400
|
}
|
|
5248
5401
|
}
|
|
@@ -5258,11 +5411,11 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
|
|
|
5258
5411
|
}
|
|
5259
5412
|
}
|
|
5260
5413
|
if (varName) {
|
|
5261
|
-
(0,
|
|
5414
|
+
(0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
|
|
5262
5415
|
return { entrypoint: { entrypoint, variableName: varName } };
|
|
5263
5416
|
} else {
|
|
5264
5417
|
return {
|
|
5265
|
-
error: new
|
|
5418
|
+
error: new import_build_utils8.NowBuildError({
|
|
5266
5419
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
5267
5420
|
message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
|
|
5268
5421
|
link: "https://vercel.com/docs/functions/serverless-functions/runtimes/python",
|
|
@@ -5368,17 +5521,17 @@ async function syncDependencies({
|
|
|
5368
5521
|
let { manifestPath } = installInfo;
|
|
5369
5522
|
const manifest = pythonPackage.manifest;
|
|
5370
5523
|
if (!manifestType || !manifestPath) {
|
|
5371
|
-
(0,
|
|
5524
|
+
(0, import_build_utils11.debug)("No Python project manifest found, skipping dependency sync");
|
|
5372
5525
|
return;
|
|
5373
5526
|
}
|
|
5374
5527
|
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
5375
|
-
const syncDir = (0,
|
|
5376
|
-
(0,
|
|
5377
|
-
const tempPyproject = (0,
|
|
5528
|
+
const syncDir = (0, import_path10.join)(workPath, ".vercel", "python", "sync");
|
|
5529
|
+
(0, import_fs9.mkdirSync)(syncDir, { recursive: true });
|
|
5530
|
+
const tempPyproject = (0, import_path10.join)(syncDir, "pyproject.toml");
|
|
5378
5531
|
const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
|
|
5379
|
-
(0,
|
|
5532
|
+
(0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
|
|
5380
5533
|
manifestPath = tempPyproject;
|
|
5381
|
-
(0,
|
|
5534
|
+
(0, import_build_utils11.debug)(
|
|
5382
5535
|
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
5383
5536
|
);
|
|
5384
5537
|
}
|
|
@@ -5411,7 +5564,7 @@ async function syncDependencies({
|
|
|
5411
5564
|
for (const [channel, chunk] of captured) {
|
|
5412
5565
|
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
5413
5566
|
}
|
|
5414
|
-
throw new
|
|
5567
|
+
throw new import_build_utils11.NowBuildError({
|
|
5415
5568
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
5416
5569
|
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
5417
5570
|
});
|
|
@@ -5426,14 +5579,14 @@ async function runSync({
|
|
|
5426
5579
|
onStdout,
|
|
5427
5580
|
onStderr
|
|
5428
5581
|
}) {
|
|
5429
|
-
const projectDir = (0,
|
|
5582
|
+
const projectDir = (0, import_path10.dirname)(manifestPath);
|
|
5430
5583
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
5431
5584
|
let spawnCmd;
|
|
5432
5585
|
let spawnArgs;
|
|
5433
5586
|
switch (manifestType) {
|
|
5434
5587
|
case "uv.lock": {
|
|
5435
5588
|
if (!uvPath) {
|
|
5436
|
-
throw new
|
|
5589
|
+
throw new import_build_utils11.NowBuildError({
|
|
5437
5590
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
5438
5591
|
message: "uv is required to install dependencies from uv.lock.",
|
|
5439
5592
|
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
@@ -5455,11 +5608,11 @@ async function runSync({
|
|
|
5455
5608
|
break;
|
|
5456
5609
|
}
|
|
5457
5610
|
default:
|
|
5458
|
-
(0,
|
|
5611
|
+
(0, import_build_utils11.debug)(`Unknown manifest type: ${manifestType}`);
|
|
5459
5612
|
return;
|
|
5460
5613
|
}
|
|
5461
5614
|
await new Promise((resolve3, reject) => {
|
|
5462
|
-
(0,
|
|
5615
|
+
(0, import_build_utils11.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
5463
5616
|
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
5464
5617
|
cwd: projectDir,
|
|
5465
5618
|
env: getProtectedUvEnv(env),
|
|
@@ -5503,7 +5656,7 @@ async function installVercelRuntime({
|
|
|
5503
5656
|
onStdout,
|
|
5504
5657
|
onStderr
|
|
5505
5658
|
}) {
|
|
5506
|
-
const targetDir = (0,
|
|
5659
|
+
const targetDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5507
5660
|
let pending = PENDING_RUNTIME_INSTALLS.get(targetDir);
|
|
5508
5661
|
if (!pending) {
|
|
5509
5662
|
pending = doInstallVercelRuntime({
|
|
@@ -5529,8 +5682,8 @@ async function doInstallVercelRuntime({
|
|
|
5529
5682
|
onStdout,
|
|
5530
5683
|
onStderr
|
|
5531
5684
|
}) {
|
|
5532
|
-
(0,
|
|
5533
|
-
const localRuntimeDir = (0,
|
|
5685
|
+
(0, import_fs9.mkdirSync)(targetDir, { recursive: true });
|
|
5686
|
+
const localRuntimeDir = (0, import_path10.join)(
|
|
5534
5687
|
__dirname,
|
|
5535
5688
|
"..",
|
|
5536
5689
|
"..",
|
|
@@ -5538,21 +5691,21 @@ async function doInstallVercelRuntime({
|
|
|
5538
5691
|
"python",
|
|
5539
5692
|
"vercel-runtime"
|
|
5540
5693
|
);
|
|
5541
|
-
const isLocalDev = (0,
|
|
5694
|
+
const isLocalDev = (0, import_fs9.existsSync)((0, import_path10.join)(localRuntimeDir, "pyproject.toml"));
|
|
5542
5695
|
const runtimeDep = env.VERCEL_RUNTIME_PYTHON || (isLocalDev ? localRuntimeDir : `vercel-runtime==${VERCEL_RUNTIME_VERSION}`);
|
|
5543
5696
|
if (!isLocalDev && !env.VERCEL_RUNTIME_PYTHON) {
|
|
5544
|
-
const distInfo = (0,
|
|
5697
|
+
const distInfo = (0, import_path10.join)(
|
|
5545
5698
|
targetDir,
|
|
5546
5699
|
`vercel_runtime-${VERCEL_RUNTIME_VERSION}.dist-info`
|
|
5547
5700
|
);
|
|
5548
|
-
if ((0,
|
|
5549
|
-
(0,
|
|
5701
|
+
if ((0, import_fs9.existsSync)(distInfo)) {
|
|
5702
|
+
(0, import_build_utils11.debug)(
|
|
5550
5703
|
`vercel-runtime ${VERCEL_RUNTIME_VERSION} already installed, skipping`
|
|
5551
5704
|
);
|
|
5552
5705
|
return;
|
|
5553
5706
|
}
|
|
5554
5707
|
}
|
|
5555
|
-
(0,
|
|
5708
|
+
(0, import_build_utils11.debug)(
|
|
5556
5709
|
`Installing vercel-runtime into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${runtimeDep})`
|
|
5557
5710
|
);
|
|
5558
5711
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -5567,14 +5720,14 @@ async function doInstallVercelRuntime({
|
|
|
5567
5720
|
if (onStdout) {
|
|
5568
5721
|
onStdout(data);
|
|
5569
5722
|
} else {
|
|
5570
|
-
(0,
|
|
5723
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5571
5724
|
}
|
|
5572
5725
|
});
|
|
5573
5726
|
child.stderr?.on("data", (data) => {
|
|
5574
5727
|
if (onStderr) {
|
|
5575
5728
|
onStderr(data);
|
|
5576
5729
|
} else {
|
|
5577
|
-
(0,
|
|
5730
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5578
5731
|
}
|
|
5579
5732
|
});
|
|
5580
5733
|
child.on("error", reject);
|
|
@@ -5599,7 +5752,7 @@ async function installVercelWorkers({
|
|
|
5599
5752
|
onStdout,
|
|
5600
5753
|
onStderr
|
|
5601
5754
|
}) {
|
|
5602
|
-
const targetDir = (0,
|
|
5755
|
+
const targetDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5603
5756
|
let pending = PENDING_WORKERS_INSTALLS.get(targetDir);
|
|
5604
5757
|
if (!pending) {
|
|
5605
5758
|
pending = doInstallVercelWorkers({
|
|
@@ -5625,8 +5778,8 @@ async function doInstallVercelWorkers({
|
|
|
5625
5778
|
onStdout,
|
|
5626
5779
|
onStderr
|
|
5627
5780
|
}) {
|
|
5628
|
-
(0,
|
|
5629
|
-
const localWorkersDir = (0,
|
|
5781
|
+
(0, import_fs9.mkdirSync)(targetDir, { recursive: true });
|
|
5782
|
+
const localWorkersDir = (0, import_path10.join)(
|
|
5630
5783
|
__dirname,
|
|
5631
5784
|
"..",
|
|
5632
5785
|
"..",
|
|
@@ -5634,21 +5787,21 @@ async function doInstallVercelWorkers({
|
|
|
5634
5787
|
"python",
|
|
5635
5788
|
"vercel-workers"
|
|
5636
5789
|
);
|
|
5637
|
-
const isLocalDev = (0,
|
|
5790
|
+
const isLocalDev = (0, import_fs9.existsSync)((0, import_path10.join)(localWorkersDir, "pyproject.toml"));
|
|
5638
5791
|
const workersDep = env.VERCEL_WORKERS_PYTHON || (isLocalDev ? localWorkersDir : `vercel-workers==${VERCEL_WORKERS_VERSION}`);
|
|
5639
5792
|
if (!isLocalDev && !env.VERCEL_WORKERS_PYTHON) {
|
|
5640
|
-
const distInfo = (0,
|
|
5793
|
+
const distInfo = (0, import_path10.join)(
|
|
5641
5794
|
targetDir,
|
|
5642
5795
|
`vercel_workers-${VERCEL_WORKERS_VERSION}.dist-info`
|
|
5643
5796
|
);
|
|
5644
|
-
if ((0,
|
|
5645
|
-
(0,
|
|
5797
|
+
if ((0, import_fs9.existsSync)(distInfo)) {
|
|
5798
|
+
(0, import_build_utils11.debug)(
|
|
5646
5799
|
`vercel-workers ${VERCEL_WORKERS_VERSION} already installed, skipping`
|
|
5647
5800
|
);
|
|
5648
5801
|
return;
|
|
5649
5802
|
}
|
|
5650
5803
|
}
|
|
5651
|
-
(0,
|
|
5804
|
+
(0, import_build_utils11.debug)(
|
|
5652
5805
|
`Installing vercel-workers into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${workersDep})`
|
|
5653
5806
|
);
|
|
5654
5807
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -5663,14 +5816,14 @@ async function doInstallVercelWorkers({
|
|
|
5663
5816
|
if (onStdout) {
|
|
5664
5817
|
onStdout(data);
|
|
5665
5818
|
} else {
|
|
5666
|
-
(0,
|
|
5819
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5667
5820
|
}
|
|
5668
5821
|
});
|
|
5669
5822
|
child.stderr?.on("data", (data) => {
|
|
5670
5823
|
if (onStderr) {
|
|
5671
5824
|
onStderr(data);
|
|
5672
5825
|
} else {
|
|
5673
|
-
(0,
|
|
5826
|
+
(0, import_build_utils11.debug)(data.toString());
|
|
5674
5827
|
}
|
|
5675
5828
|
});
|
|
5676
5829
|
child.on("error", reject);
|
|
@@ -5700,12 +5853,12 @@ function installGlobalCleanupHandlers() {
|
|
|
5700
5853
|
try {
|
|
5701
5854
|
process.kill(info.pid, "SIGTERM");
|
|
5702
5855
|
} catch (err) {
|
|
5703
|
-
(0,
|
|
5856
|
+
(0, import_build_utils11.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
|
|
5704
5857
|
}
|
|
5705
5858
|
try {
|
|
5706
5859
|
process.kill(info.pid, "SIGKILL");
|
|
5707
5860
|
} catch (err) {
|
|
5708
|
-
(0,
|
|
5861
|
+
(0, import_build_utils11.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
|
|
5709
5862
|
}
|
|
5710
5863
|
PERSISTENT_SERVERS.delete(key);
|
|
5711
5864
|
}
|
|
@@ -5713,7 +5866,7 @@ function installGlobalCleanupHandlers() {
|
|
|
5713
5866
|
try {
|
|
5714
5867
|
restoreWarnings();
|
|
5715
5868
|
} catch (err) {
|
|
5716
|
-
(0,
|
|
5869
|
+
(0, import_build_utils11.debug)(`Error restoring warnings: ${err}`);
|
|
5717
5870
|
}
|
|
5718
5871
|
restoreWarnings = null;
|
|
5719
5872
|
}
|
|
@@ -5730,55 +5883,55 @@ function installGlobalCleanupHandlers() {
|
|
|
5730
5883
|
}
|
|
5731
5884
|
function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
|
|
5732
5885
|
try {
|
|
5733
|
-
const vercelPythonDir = serviceName ? (0,
|
|
5734
|
-
(0,
|
|
5886
|
+
const vercelPythonDir = serviceName ? (0, import_path10.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5887
|
+
(0, import_fs9.mkdirSync)(vercelPythonDir, { recursive: true });
|
|
5735
5888
|
let qualifiedModule = modulePath;
|
|
5736
5889
|
let extraPythonPath;
|
|
5737
|
-
if ((0,
|
|
5738
|
-
const pkgName = (0,
|
|
5890
|
+
if ((0, import_fs9.existsSync)((0, import_path10.join)(workPath, "__init__.py"))) {
|
|
5891
|
+
const pkgName = (0, import_path10.basename)(workPath);
|
|
5739
5892
|
qualifiedModule = `${pkgName}.${modulePath}`;
|
|
5740
|
-
extraPythonPath = (0,
|
|
5893
|
+
extraPythonPath = (0, import_path10.dirname)(workPath);
|
|
5741
5894
|
}
|
|
5742
|
-
const entryAbs = (0,
|
|
5743
|
-
const shimPath = (0,
|
|
5744
|
-
const templatePath = (0,
|
|
5895
|
+
const entryAbs = (0, import_path10.join)(workPath, entry);
|
|
5896
|
+
const shimPath = (0, import_path10.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
|
|
5897
|
+
const templatePath = (0, import_path10.join)(
|
|
5745
5898
|
__dirname,
|
|
5746
5899
|
"..",
|
|
5747
5900
|
"templates",
|
|
5748
5901
|
`${DEV_SHIM_MODULE}.py`
|
|
5749
5902
|
);
|
|
5750
|
-
const template = (0,
|
|
5903
|
+
const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
|
|
5751
5904
|
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);
|
|
5752
|
-
(0,
|
|
5753
|
-
(0,
|
|
5905
|
+
(0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
|
|
5906
|
+
(0, import_build_utils11.debug)(`Prepared Python dev shim at ${shimPath}`);
|
|
5754
5907
|
return {
|
|
5755
5908
|
module: DEV_SHIM_MODULE,
|
|
5756
5909
|
extraPythonPath,
|
|
5757
5910
|
shimDir: vercelPythonDir
|
|
5758
5911
|
};
|
|
5759
5912
|
} catch (err) {
|
|
5760
|
-
(0,
|
|
5913
|
+
(0, import_build_utils11.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
|
|
5761
5914
|
return null;
|
|
5762
5915
|
}
|
|
5763
5916
|
}
|
|
5764
5917
|
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
5765
5918
|
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
5766
5919
|
if (venvRoot) {
|
|
5767
|
-
(0,
|
|
5920
|
+
(0, import_build_utils11.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
5768
5921
|
return { command: pythonCmd, args: [] };
|
|
5769
5922
|
}
|
|
5770
|
-
const venvPath = (0,
|
|
5923
|
+
const venvPath = (0, import_path10.join)(workPath, ".venv");
|
|
5771
5924
|
await ensureVenv({
|
|
5772
5925
|
pythonVersion: { pythonPath: systemPython },
|
|
5773
5926
|
venvPath,
|
|
5774
5927
|
uvPath,
|
|
5775
5928
|
quiet: true
|
|
5776
5929
|
});
|
|
5777
|
-
(0,
|
|
5930
|
+
(0, import_build_utils11.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
5778
5931
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
5779
5932
|
const binDir = getVenvBinDir(venvPath);
|
|
5780
5933
|
env.VIRTUAL_ENV = venvPath;
|
|
5781
|
-
env.PATH = `${binDir}${
|
|
5934
|
+
env.PATH = `${binDir}${import_path10.delimiter}${env.PATH || ""}`;
|
|
5782
5935
|
return { command: pythonBin, args: [] };
|
|
5783
5936
|
}
|
|
5784
5937
|
var startDevServer = async (opts) => {
|
|
@@ -5841,7 +5994,7 @@ var startDevServer = async (opts) => {
|
|
|
5841
5994
|
} else {
|
|
5842
5995
|
const hookResult = await runFrameworkHook(framework, {
|
|
5843
5996
|
pythonEnv: env,
|
|
5844
|
-
projectDir: (0,
|
|
5997
|
+
projectDir: (0, import_path10.join)(workPath, detected?.baseDir ?? ""),
|
|
5845
5998
|
workPath,
|
|
5846
5999
|
entrypoint,
|
|
5847
6000
|
detected: detected ?? void 0
|
|
@@ -5852,7 +6005,7 @@ var startDevServer = async (opts) => {
|
|
|
5852
6005
|
if (detected?.error) {
|
|
5853
6006
|
throw detected.error;
|
|
5854
6007
|
}
|
|
5855
|
-
throw new
|
|
6008
|
+
throw new import_build_utils11.NowBuildError({
|
|
5856
6009
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
5857
6010
|
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
5858
6011
|
});
|
|
@@ -5881,7 +6034,7 @@ var startDevServer = async (opts) => {
|
|
|
5881
6034
|
const yellow = "\x1B[33m";
|
|
5882
6035
|
const white = "\x1B[1m";
|
|
5883
6036
|
const reset = "\x1B[0m";
|
|
5884
|
-
throw new
|
|
6037
|
+
throw new import_build_utils11.NowBuildError({
|
|
5885
6038
|
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
5886
6039
|
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
5887
6040
|
Run ${white}deactivate${reset} and try again.`
|
|
@@ -5898,11 +6051,11 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
5898
6051
|
);
|
|
5899
6052
|
spawnCommand = runner.command;
|
|
5900
6053
|
spawnArgsPrefix = runner.args;
|
|
5901
|
-
(0,
|
|
6054
|
+
(0, import_build_utils11.debug)(
|
|
5902
6055
|
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
5903
6056
|
);
|
|
5904
6057
|
} else if (venv) {
|
|
5905
|
-
(0,
|
|
6058
|
+
(0, import_build_utils11.debug)(`Running in virtualenv at ${venv}`);
|
|
5906
6059
|
} else {
|
|
5907
6060
|
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
5908
6061
|
workPath,
|
|
@@ -5911,9 +6064,9 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
5911
6064
|
);
|
|
5912
6065
|
spawnCommand = venvPythonCmd;
|
|
5913
6066
|
if (venvRoot) {
|
|
5914
|
-
(0,
|
|
6067
|
+
(0, import_build_utils11.debug)(`Using virtualenv at ${venvRoot}`);
|
|
5915
6068
|
} else {
|
|
5916
|
-
(0,
|
|
6069
|
+
(0, import_build_utils11.debug)("No virtualenv found");
|
|
5917
6070
|
try {
|
|
5918
6071
|
const yellow = "\x1B[33m";
|
|
5919
6072
|
const reset = "\x1B[0m";
|
|
@@ -5962,13 +6115,22 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5962
6115
|
onStderr
|
|
5963
6116
|
});
|
|
5964
6117
|
}
|
|
6118
|
+
const crons = await getServiceCrons({
|
|
6119
|
+
service,
|
|
6120
|
+
entrypoint,
|
|
6121
|
+
rawEntrypoint,
|
|
6122
|
+
handlerFunction,
|
|
6123
|
+
pythonBin: spawnCommand,
|
|
6124
|
+
env,
|
|
6125
|
+
workPath
|
|
6126
|
+
});
|
|
6127
|
+
if (crons?.length) {
|
|
6128
|
+
env.__VC_CRON_ROUTES = JSON.stringify(buildCronRouteTable(crons));
|
|
6129
|
+
}
|
|
5965
6130
|
const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
|
|
5966
6131
|
env.PORT = `${port}`;
|
|
5967
|
-
if (config.handlerFunction && typeof config?.handlerFunction === "string") {
|
|
5968
|
-
env.__VC_HANDLER_FUNC_NAME = config.handlerFunction;
|
|
5969
|
-
}
|
|
5970
6132
|
if (entry) {
|
|
5971
|
-
env.__VC_HANDLER_ENTRYPOINT_ABS = (0,
|
|
6133
|
+
env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path10.join)(workPath, entry);
|
|
5972
6134
|
}
|
|
5973
6135
|
const devShim = createDevShim(
|
|
5974
6136
|
workPath,
|
|
@@ -5979,8 +6141,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5979
6141
|
variableName ?? ""
|
|
5980
6142
|
);
|
|
5981
6143
|
if (devShim) {
|
|
5982
|
-
const shimDir = devShim.shimDir || (0,
|
|
5983
|
-
const runtimeDir = (0,
|
|
6144
|
+
const shimDir = devShim.shimDir || (0, import_path10.join)(workPath, ".vercel", "python");
|
|
6145
|
+
const runtimeDir = (0, import_path10.join)(workPath, ".vercel", "python");
|
|
5984
6146
|
const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
|
|
5985
6147
|
if (devShim.extraPythonPath) {
|
|
5986
6148
|
pathParts.push(devShim.extraPythonPath);
|
|
@@ -5989,12 +6151,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
5989
6151
|
if (existingPythonPath) {
|
|
5990
6152
|
pathParts.push(existingPythonPath);
|
|
5991
6153
|
}
|
|
5992
|
-
env.PYTHONPATH = pathParts.join(
|
|
6154
|
+
env.PYTHONPATH = pathParts.join(import_path10.delimiter);
|
|
5993
6155
|
}
|
|
5994
6156
|
const moduleToRun = devShim?.module || modulePath;
|
|
5995
6157
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
5996
6158
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
5997
|
-
(0,
|
|
6159
|
+
(0, import_build_utils11.debug)(
|
|
5998
6160
|
`Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
|
|
5999
6161
|
);
|
|
6000
6162
|
if (process.stdout.columns) {
|
|
@@ -6038,7 +6200,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
6038
6200
|
});
|
|
6039
6201
|
const shutdown = async () => {
|
|
6040
6202
|
};
|
|
6041
|
-
return { port, pid, shutdown };
|
|
6203
|
+
return { port, pid, shutdown, crons };
|
|
6042
6204
|
} catch (err) {
|
|
6043
6205
|
rejectChildReady(err);
|
|
6044
6206
|
throw err;
|
|
@@ -6048,7 +6210,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
6048
6210
|
};
|
|
6049
6211
|
|
|
6050
6212
|
// src/quirks/index.ts
|
|
6051
|
-
var
|
|
6213
|
+
var import_build_utils14 = require("@vercel/build-utils");
|
|
6052
6214
|
var import_python_analysis8 = require("@vercel/python-analysis");
|
|
6053
6215
|
|
|
6054
6216
|
// src/quirks/matplotlib.ts
|
|
@@ -6062,9 +6224,9 @@ var matplotlibQuirk = {
|
|
|
6062
6224
|
};
|
|
6063
6225
|
|
|
6064
6226
|
// src/quirks/litellm.ts
|
|
6065
|
-
var
|
|
6066
|
-
var
|
|
6067
|
-
var
|
|
6227
|
+
var import_fs10 = __toESM(require("fs"));
|
|
6228
|
+
var import_path11 = require("path");
|
|
6229
|
+
var import_build_utils12 = require("@vercel/build-utils");
|
|
6068
6230
|
var LAMBDA_ROOT = "/var/task";
|
|
6069
6231
|
var CONFIG_CANDIDATES = [
|
|
6070
6232
|
"litellm_config.yaml",
|
|
@@ -6074,9 +6236,9 @@ var CONFIG_CANDIDATES = [
|
|
|
6074
6236
|
];
|
|
6075
6237
|
async function findConfigFile(workPath) {
|
|
6076
6238
|
for (const name of CONFIG_CANDIDATES) {
|
|
6077
|
-
const candidate = (0,
|
|
6239
|
+
const candidate = (0, import_path11.join)(workPath, name);
|
|
6078
6240
|
try {
|
|
6079
|
-
await
|
|
6241
|
+
await import_fs10.default.promises.access(candidate);
|
|
6080
6242
|
return name;
|
|
6081
6243
|
} catch {
|
|
6082
6244
|
}
|
|
@@ -6091,32 +6253,32 @@ var litellmQuirk = {
|
|
|
6091
6253
|
const env = {};
|
|
6092
6254
|
const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
|
|
6093
6255
|
for (const sitePackages of sitePackagesDirs) {
|
|
6094
|
-
const schemaPath = (0,
|
|
6256
|
+
const schemaPath = (0, import_path11.join)(
|
|
6095
6257
|
sitePackages,
|
|
6096
6258
|
"litellm",
|
|
6097
6259
|
"proxy",
|
|
6098
6260
|
"schema.prisma"
|
|
6099
6261
|
);
|
|
6100
6262
|
try {
|
|
6101
|
-
await
|
|
6102
|
-
(0,
|
|
6263
|
+
await import_fs10.default.promises.access(schemaPath);
|
|
6264
|
+
(0, import_build_utils12.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
|
|
6103
6265
|
buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
|
|
6104
6266
|
break;
|
|
6105
6267
|
} catch {
|
|
6106
6268
|
}
|
|
6107
6269
|
}
|
|
6108
6270
|
if (!buildEnv.PRISMA_SCHEMA_PATH) {
|
|
6109
|
-
(0,
|
|
6271
|
+
(0, import_build_utils12.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
|
|
6110
6272
|
}
|
|
6111
6273
|
if (!process.env.CONFIG_FILE_PATH) {
|
|
6112
6274
|
const configName = await findConfigFile(ctx.workPath);
|
|
6113
6275
|
if (configName) {
|
|
6114
|
-
(0,
|
|
6115
|
-
buildEnv.CONFIG_FILE_PATH = (0,
|
|
6116
|
-
env.CONFIG_FILE_PATH = (0,
|
|
6276
|
+
(0, import_build_utils12.debug)(`LiteLLM quirk: found config at ${configName}`);
|
|
6277
|
+
buildEnv.CONFIG_FILE_PATH = (0, import_path11.join)(ctx.workPath, configName);
|
|
6278
|
+
env.CONFIG_FILE_PATH = (0, import_path11.join)(LAMBDA_ROOT, configName);
|
|
6117
6279
|
}
|
|
6118
6280
|
} else {
|
|
6119
|
-
(0,
|
|
6281
|
+
(0, import_build_utils12.debug)(
|
|
6120
6282
|
`LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
|
|
6121
6283
|
);
|
|
6122
6284
|
}
|
|
@@ -6125,10 +6287,10 @@ var litellmQuirk = {
|
|
|
6125
6287
|
};
|
|
6126
6288
|
|
|
6127
6289
|
// src/quirks/prisma.ts
|
|
6128
|
-
var
|
|
6129
|
-
var
|
|
6130
|
-
var
|
|
6131
|
-
var
|
|
6290
|
+
var import_fs11 = __toESM(require("fs"));
|
|
6291
|
+
var import_path12 = require("path");
|
|
6292
|
+
var import_execa5 = __toESM(require_execa());
|
|
6293
|
+
var import_build_utils13 = require("@vercel/build-utils");
|
|
6132
6294
|
var import_python_analysis7 = require("@vercel/python-analysis");
|
|
6133
6295
|
function execErrorMessage(err) {
|
|
6134
6296
|
if (err != null && typeof err === "object" && "stderr" in err) {
|
|
@@ -6166,22 +6328,22 @@ model DummyModel {
|
|
|
6166
6328
|
async function findUserSchema(workPath) {
|
|
6167
6329
|
const envPath = process.env.PRISMA_SCHEMA_PATH;
|
|
6168
6330
|
if (envPath) {
|
|
6169
|
-
const resolved = (0,
|
|
6331
|
+
const resolved = (0, import_path12.isAbsolute)(envPath) ? envPath : (0, import_path12.join)(workPath, envPath);
|
|
6170
6332
|
try {
|
|
6171
|
-
await
|
|
6333
|
+
await import_fs11.default.promises.access(resolved);
|
|
6172
6334
|
return resolved;
|
|
6173
6335
|
} catch {
|
|
6174
|
-
(0,
|
|
6336
|
+
(0, import_build_utils13.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
|
|
6175
6337
|
return null;
|
|
6176
6338
|
}
|
|
6177
6339
|
}
|
|
6178
6340
|
const candidates = [
|
|
6179
|
-
(0,
|
|
6180
|
-
(0,
|
|
6341
|
+
(0, import_path12.join)(workPath, "schema.prisma"),
|
|
6342
|
+
(0, import_path12.join)(workPath, "prisma", "schema.prisma")
|
|
6181
6343
|
];
|
|
6182
6344
|
for (const candidate of candidates) {
|
|
6183
6345
|
try {
|
|
6184
|
-
await
|
|
6346
|
+
await import_fs11.default.promises.access(candidate);
|
|
6185
6347
|
return candidate;
|
|
6186
6348
|
} catch {
|
|
6187
6349
|
}
|
|
@@ -6192,32 +6354,32 @@ async function collectFiles(dir, base) {
|
|
|
6192
6354
|
const result = [];
|
|
6193
6355
|
let entries;
|
|
6194
6356
|
try {
|
|
6195
|
-
entries = await
|
|
6357
|
+
entries = await import_fs11.default.promises.readdir(dir, { withFileTypes: true });
|
|
6196
6358
|
} catch {
|
|
6197
6359
|
return result;
|
|
6198
6360
|
}
|
|
6199
6361
|
for (const entry of entries) {
|
|
6200
6362
|
if (entry.name === "__pycache__")
|
|
6201
6363
|
continue;
|
|
6202
|
-
const full = (0,
|
|
6364
|
+
const full = (0, import_path12.join)(dir, entry.name);
|
|
6203
6365
|
if (entry.isDirectory()) {
|
|
6204
6366
|
result.push(...await collectFiles(full, base));
|
|
6205
6367
|
} else {
|
|
6206
|
-
result.push((0,
|
|
6368
|
+
result.push((0, import_path12.relative)(base, full));
|
|
6207
6369
|
}
|
|
6208
6370
|
}
|
|
6209
6371
|
return result;
|
|
6210
6372
|
}
|
|
6211
6373
|
async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
6212
6374
|
const paths = [
|
|
6213
|
-
(0,
|
|
6214
|
-
(0,
|
|
6215
|
-
(0,
|
|
6375
|
+
(0, import_path12.join)(cacheDir, "node_modules"),
|
|
6376
|
+
(0, import_path12.join)(cacheDir, "package.json"),
|
|
6377
|
+
(0, import_path12.join)(cacheDir, "package-lock.json"),
|
|
6216
6378
|
...extras
|
|
6217
6379
|
];
|
|
6218
6380
|
for (const p of paths) {
|
|
6219
6381
|
try {
|
|
6220
|
-
await
|
|
6382
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
6221
6383
|
} catch (err) {
|
|
6222
6384
|
console.warn(
|
|
6223
6385
|
`could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -6227,7 +6389,7 @@ async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
|
6227
6389
|
}
|
|
6228
6390
|
async function isClientGenerated(pythonPath, env) {
|
|
6229
6391
|
try {
|
|
6230
|
-
await (0,
|
|
6392
|
+
await (0, import_execa5.default)(pythonPath, ["-c", "import prisma.client"], {
|
|
6231
6393
|
env,
|
|
6232
6394
|
stdio: "pipe"
|
|
6233
6395
|
});
|
|
@@ -6241,7 +6403,7 @@ var prismaQuirk = {
|
|
|
6241
6403
|
async run(ctx) {
|
|
6242
6404
|
const { venvPath, pythonEnv, workPath } = ctx;
|
|
6243
6405
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
6244
|
-
const runtimeCacheDir = (0,
|
|
6406
|
+
const runtimeCacheDir = (0, import_path12.join)(
|
|
6245
6407
|
LAMBDA_ROOT2,
|
|
6246
6408
|
resolveVendorDir(),
|
|
6247
6409
|
"prisma",
|
|
@@ -6251,7 +6413,7 @@ var prismaQuirk = {
|
|
|
6251
6413
|
let sitePackages;
|
|
6252
6414
|
for (const dir of sitePackagesDirs) {
|
|
6253
6415
|
try {
|
|
6254
|
-
await
|
|
6416
|
+
await import_fs11.default.promises.access((0, import_path12.join)(dir, "prisma"));
|
|
6255
6417
|
sitePackages = dir;
|
|
6256
6418
|
break;
|
|
6257
6419
|
} catch {
|
|
@@ -6263,21 +6425,21 @@ var prismaQuirk = {
|
|
|
6263
6425
|
);
|
|
6264
6426
|
return {};
|
|
6265
6427
|
}
|
|
6266
|
-
const cacheDir = (0,
|
|
6267
|
-
await
|
|
6428
|
+
const cacheDir = (0, import_path12.join)(sitePackages, "prisma", "__bincache__");
|
|
6429
|
+
await import_fs11.default.promises.mkdir(cacheDir, { recursive: true });
|
|
6268
6430
|
const generateEnv = {
|
|
6269
6431
|
...pythonEnv,
|
|
6270
6432
|
PRISMA_BINARY_CACHE_DIR: cacheDir
|
|
6271
6433
|
};
|
|
6272
|
-
const generatedDir = (0,
|
|
6273
|
-
const dummySchemaPath = (0,
|
|
6274
|
-
await
|
|
6434
|
+
const generatedDir = (0, import_path12.join)(workPath, "_prisma_generated");
|
|
6435
|
+
const dummySchemaPath = (0, import_path12.join)(workPath, DUMMY_SCHEMA_NAME);
|
|
6436
|
+
await import_fs11.default.promises.writeFile(
|
|
6275
6437
|
dummySchemaPath,
|
|
6276
6438
|
buildDummySchema(generatedDir)
|
|
6277
6439
|
);
|
|
6278
|
-
(0,
|
|
6440
|
+
(0, import_build_utils13.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
|
|
6279
6441
|
try {
|
|
6280
|
-
const dummyResult = await (0,
|
|
6442
|
+
const dummyResult = await (0, import_execa5.default)(
|
|
6281
6443
|
pythonPath,
|
|
6282
6444
|
["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
|
|
6283
6445
|
{
|
|
@@ -6287,11 +6449,11 @@ var prismaQuirk = {
|
|
|
6287
6449
|
}
|
|
6288
6450
|
);
|
|
6289
6451
|
if (dummyResult.stdout)
|
|
6290
|
-
(0,
|
|
6452
|
+
(0, import_build_utils13.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
|
|
6291
6453
|
if (dummyResult.stderr)
|
|
6292
|
-
(0,
|
|
6454
|
+
(0, import_build_utils13.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
|
|
6293
6455
|
} catch (err) {
|
|
6294
|
-
throw new
|
|
6456
|
+
throw new import_build_utils13.NowBuildError({
|
|
6295
6457
|
code: "PRISMA_GENERATE_FAILED",
|
|
6296
6458
|
message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
|
|
6297
6459
|
` + execErrorMessage(err)
|
|
@@ -6299,47 +6461,47 @@ var prismaQuirk = {
|
|
|
6299
6461
|
}
|
|
6300
6462
|
const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
|
|
6301
6463
|
const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
|
|
6302
|
-
const nodeModulesDir = (0,
|
|
6464
|
+
const nodeModulesDir = (0, import_path12.join)(cacheDir, "node_modules", "prisma");
|
|
6303
6465
|
let engineCopied = false;
|
|
6304
6466
|
try {
|
|
6305
|
-
const entries = await
|
|
6467
|
+
const entries = await import_fs11.default.promises.readdir(nodeModulesDir);
|
|
6306
6468
|
for (const entry of entries) {
|
|
6307
6469
|
if (!entry.startsWith(srcBinaryPrefix))
|
|
6308
6470
|
continue;
|
|
6309
|
-
const srcPath = (0,
|
|
6310
|
-
const destPath = (0,
|
|
6471
|
+
const srcPath = (0, import_path12.join)(nodeModulesDir, entry);
|
|
6472
|
+
const destPath = (0, import_path12.join)(cacheDir, runtimeName);
|
|
6311
6473
|
try {
|
|
6312
|
-
await
|
|
6313
|
-
(0,
|
|
6474
|
+
await import_fs11.default.promises.access(destPath);
|
|
6475
|
+
(0, import_build_utils13.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
|
|
6314
6476
|
} catch {
|
|
6315
|
-
(0,
|
|
6316
|
-
await
|
|
6477
|
+
(0, import_build_utils13.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
|
|
6478
|
+
await import_fs11.default.promises.copyFile(srcPath, destPath);
|
|
6317
6479
|
}
|
|
6318
6480
|
engineCopied = true;
|
|
6319
6481
|
}
|
|
6320
6482
|
} catch (err) {
|
|
6321
|
-
throw new
|
|
6483
|
+
throw new import_build_utils13.NowBuildError({
|
|
6322
6484
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
6323
6485
|
message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
|
|
6324
6486
|
` + (err instanceof Error ? err.message : String(err))
|
|
6325
6487
|
});
|
|
6326
6488
|
}
|
|
6327
6489
|
if (!engineCopied) {
|
|
6328
|
-
throw new
|
|
6490
|
+
throw new import_build_utils13.NowBuildError({
|
|
6329
6491
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
6330
6492
|
message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
|
|
6331
6493
|
});
|
|
6332
6494
|
}
|
|
6333
|
-
const shimPath = (0,
|
|
6334
|
-
await
|
|
6495
|
+
const shimPath = (0, import_path12.join)(cacheDir, "openssl");
|
|
6496
|
+
await import_fs11.default.promises.writeFile(
|
|
6335
6497
|
shimPath,
|
|
6336
6498
|
`#!/bin/sh
|
|
6337
6499
|
echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
|
|
6338
6500
|
`
|
|
6339
6501
|
);
|
|
6340
|
-
await
|
|
6502
|
+
await import_fs11.default.promises.chmod(shimPath, 493);
|
|
6341
6503
|
for (const p of [generatedDir, dummySchemaPath]) {
|
|
6342
|
-
await
|
|
6504
|
+
await import_fs11.default.promises.rm(p, { recursive: true, force: true });
|
|
6343
6505
|
}
|
|
6344
6506
|
await cleanCacheArtifacts(cacheDir);
|
|
6345
6507
|
const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
|
|
@@ -6352,16 +6514,16 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6352
6514
|
pythonEnv
|
|
6353
6515
|
);
|
|
6354
6516
|
if (clientAlreadyGenerated) {
|
|
6355
|
-
(0,
|
|
6517
|
+
(0, import_build_utils13.debug)(
|
|
6356
6518
|
"Prisma quirk: client already generated, skipping user schema generate"
|
|
6357
6519
|
);
|
|
6358
6520
|
shouldGenerate = false;
|
|
6359
6521
|
}
|
|
6360
6522
|
}
|
|
6361
6523
|
if (shouldGenerate) {
|
|
6362
|
-
(0,
|
|
6524
|
+
(0, import_build_utils13.debug)(`Running prisma generate with user schema: ${userSchema}`);
|
|
6363
6525
|
try {
|
|
6364
|
-
const userResult = await (0,
|
|
6526
|
+
const userResult = await (0, import_execa5.default)(
|
|
6365
6527
|
pythonPath,
|
|
6366
6528
|
["-m", "prisma", "generate", `--schema=${userSchema}`],
|
|
6367
6529
|
{
|
|
@@ -6371,11 +6533,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6371
6533
|
}
|
|
6372
6534
|
);
|
|
6373
6535
|
if (userResult.stdout)
|
|
6374
|
-
(0,
|
|
6536
|
+
(0, import_build_utils13.debug)(`prisma generate stdout: ${userResult.stdout}`);
|
|
6375
6537
|
if (userResult.stderr)
|
|
6376
|
-
(0,
|
|
6538
|
+
(0, import_build_utils13.debug)(`prisma generate stderr: ${userResult.stderr}`);
|
|
6377
6539
|
} catch (err) {
|
|
6378
|
-
throw new
|
|
6540
|
+
throw new import_build_utils13.NowBuildError({
|
|
6379
6541
|
code: "PRISMA_GENERATE_FAILED",
|
|
6380
6542
|
message: `\`prisma generate\` failed for schema "${userSchema}".
|
|
6381
6543
|
` + execErrorMessage(err)
|
|
@@ -6386,12 +6548,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
6386
6548
|
}
|
|
6387
6549
|
try {
|
|
6388
6550
|
const allFiles = await collectFiles(
|
|
6389
|
-
(0,
|
|
6551
|
+
(0, import_path12.join)(sitePackages, "prisma"),
|
|
6390
6552
|
sitePackages
|
|
6391
6553
|
);
|
|
6392
6554
|
const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
|
|
6393
6555
|
if (count > 0) {
|
|
6394
|
-
(0,
|
|
6556
|
+
(0, import_build_utils13.debug)(`Appended ${count} entries to prisma RECORD`);
|
|
6395
6557
|
}
|
|
6396
6558
|
} catch (err) {
|
|
6397
6559
|
console.warn(
|
|
@@ -6485,13 +6647,13 @@ async function runQuirks(ctx) {
|
|
|
6485
6647
|
(0, import_python_analysis8.normalizePackageName)(quirk.dependency)
|
|
6486
6648
|
);
|
|
6487
6649
|
if (!installed) {
|
|
6488
|
-
(0,
|
|
6650
|
+
(0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
|
|
6489
6651
|
}
|
|
6490
6652
|
return installed;
|
|
6491
6653
|
});
|
|
6492
6654
|
const sorted = toposortQuirks(activated);
|
|
6493
6655
|
for (const quirk of sorted) {
|
|
6494
|
-
(0,
|
|
6656
|
+
(0, import_build_utils14.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
|
|
6495
6657
|
const result = await quirk.run(ctx);
|
|
6496
6658
|
if (result.env) {
|
|
6497
6659
|
Object.assign(mergedEnv, result.env);
|
|
@@ -6512,14 +6674,14 @@ async function runQuirks(ctx) {
|
|
|
6512
6674
|
}
|
|
6513
6675
|
|
|
6514
6676
|
// src/django.ts
|
|
6515
|
-
var
|
|
6516
|
-
var
|
|
6517
|
-
var
|
|
6518
|
-
var
|
|
6519
|
-
var
|
|
6520
|
-
var
|
|
6677
|
+
var import_fs12 = __toESM(require("fs"));
|
|
6678
|
+
var import_path13 = require("path");
|
|
6679
|
+
var import_execa6 = __toESM(require_execa());
|
|
6680
|
+
var import_build_utils15 = require("@vercel/build-utils");
|
|
6681
|
+
var scriptPath2 = (0, import_path13.join)(__dirname, "..", "templates", "vc_django_settings.py");
|
|
6682
|
+
var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
|
|
6521
6683
|
async function getDjangoSettings(projectDir, env) {
|
|
6522
|
-
const { stdout } = await (0,
|
|
6684
|
+
const { stdout } = await (0, import_execa6.default)("python", ["-c", script2], {
|
|
6523
6685
|
env,
|
|
6524
6686
|
cwd: projectDir
|
|
6525
6687
|
});
|
|
@@ -6545,21 +6707,21 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6545
6707
|
const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
|
|
6546
6708
|
const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
|
|
6547
6709
|
const staticSourceDirs = [
|
|
6548
|
-
...installedApps.map((app) => (0,
|
|
6710
|
+
...installedApps.map((app) => (0, import_path13.join)(workPath, ...app.split("."), "static")),
|
|
6549
6711
|
// TODO: Deal with optional prefixes in STATICFILES_DIRS.
|
|
6550
6712
|
...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
|
|
6551
|
-
].filter((d) =>
|
|
6713
|
+
].filter((d) => import_fs12.default.existsSync(d));
|
|
6552
6714
|
if (storageBackend.startsWith("storages.backends.")) {
|
|
6553
6715
|
console.log(
|
|
6554
6716
|
"django-storages detected \u2014 running collectstatic with original settings"
|
|
6555
6717
|
);
|
|
6556
|
-
await (0,
|
|
6718
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
6557
6719
|
env: { ...env, DJANGO_SETTINGS_MODULE: settingsModule },
|
|
6558
6720
|
cwd: workPath
|
|
6559
6721
|
});
|
|
6560
6722
|
return {
|
|
6561
6723
|
staticSourceDirs,
|
|
6562
|
-
staticRoot: staticRoot ? (0,
|
|
6724
|
+
staticRoot: staticRoot ? (0, import_path13.resolve)(workPath, staticRoot) : null,
|
|
6563
6725
|
cdnOutputDir: null,
|
|
6564
6726
|
manifestRelPath: null
|
|
6565
6727
|
};
|
|
@@ -6571,9 +6733,9 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6571
6733
|
return null;
|
|
6572
6734
|
}
|
|
6573
6735
|
const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
|
|
6574
|
-
const staticOutputDir = (0,
|
|
6575
|
-
await
|
|
6576
|
-
const shimPath = (0,
|
|
6736
|
+
const staticOutputDir = (0, import_path13.join)(outputStaticDir, staticUrlPath);
|
|
6737
|
+
await import_fs12.default.promises.mkdir(staticOutputDir, { recursive: true });
|
|
6738
|
+
const shimPath = (0, import_path13.join)(workPath, "_vercel_collectstatic_settings.py");
|
|
6577
6739
|
const shimLines = [
|
|
6578
6740
|
`from ${settingsModule} import *`,
|
|
6579
6741
|
`STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
|
|
@@ -6581,10 +6743,10 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6581
6743
|
if (whitenoiseUseFinders) {
|
|
6582
6744
|
shimLines.push(`WHITENOISE_USE_FINDERS = False`);
|
|
6583
6745
|
}
|
|
6584
|
-
await
|
|
6746
|
+
await import_fs12.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
|
|
6585
6747
|
try {
|
|
6586
6748
|
console.log("Running collectstatic...");
|
|
6587
|
-
await (0,
|
|
6749
|
+
await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
6588
6750
|
env: {
|
|
6589
6751
|
...env,
|
|
6590
6752
|
DJANGO_SETTINGS_MODULE: "_vercel_collectstatic_settings"
|
|
@@ -6592,7 +6754,7 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6592
6754
|
cwd: workPath
|
|
6593
6755
|
});
|
|
6594
6756
|
} finally {
|
|
6595
|
-
await
|
|
6757
|
+
await import_fs12.default.promises.unlink(shimPath).catch(() => {
|
|
6596
6758
|
});
|
|
6597
6759
|
}
|
|
6598
6760
|
const MANIFEST_STORAGE_BACKENDS = [
|
|
@@ -6601,17 +6763,17 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6601
6763
|
];
|
|
6602
6764
|
let manifestRelPath = null;
|
|
6603
6765
|
if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
|
|
6604
|
-
const manifestSrc = (0,
|
|
6605
|
-
const resolvedStaticRoot = (0,
|
|
6606
|
-
const manifestDest = (0,
|
|
6607
|
-
await
|
|
6608
|
-
await
|
|
6609
|
-
manifestRelPath = (0,
|
|
6610
|
-
(0,
|
|
6766
|
+
const manifestSrc = (0, import_path13.join)(staticOutputDir, "staticfiles.json");
|
|
6767
|
+
const resolvedStaticRoot = (0, import_path13.resolve)(workPath, staticRoot);
|
|
6768
|
+
const manifestDest = (0, import_path13.join)(resolvedStaticRoot, "staticfiles.json");
|
|
6769
|
+
await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
|
|
6770
|
+
await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
|
|
6771
|
+
manifestRelPath = (0, import_path13.relative)(workPath, manifestDest);
|
|
6772
|
+
(0, import_build_utils15.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
|
|
6611
6773
|
}
|
|
6612
6774
|
return {
|
|
6613
6775
|
staticSourceDirs,
|
|
6614
|
-
staticRoot: staticRoot ? (0,
|
|
6776
|
+
staticRoot: staticRoot ? (0, import_path13.resolve)(workPath, staticRoot) : null,
|
|
6615
6777
|
cdnOutputDir: outputStaticDir,
|
|
6616
6778
|
manifestRelPath
|
|
6617
6779
|
};
|
|
@@ -6619,7 +6781,7 @@ async function runDjangoCollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
6619
6781
|
|
|
6620
6782
|
// src/index.ts
|
|
6621
6783
|
var import_python_analysis9 = require("@vercel/python-analysis");
|
|
6622
|
-
var writeFile =
|
|
6784
|
+
var writeFile = import_fs13.default.promises.writeFile;
|
|
6623
6785
|
var version = -1;
|
|
6624
6786
|
async function runFrameworkHook(framework, ctx) {
|
|
6625
6787
|
const hook = framework ? frameworkHooks[framework] : void 0;
|
|
@@ -6634,7 +6796,7 @@ var frameworkHooks = {
|
|
|
6634
6796
|
detected
|
|
6635
6797
|
}) => {
|
|
6636
6798
|
if (detected?.baseDir === void 0) {
|
|
6637
|
-
(0,
|
|
6799
|
+
(0, import_build_utils16.debug)("Django hook: no manage.py detected, skipping");
|
|
6638
6800
|
return;
|
|
6639
6801
|
}
|
|
6640
6802
|
let settingsResult;
|
|
@@ -6648,13 +6810,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
|
|
|
6648
6810
|
} else {
|
|
6649
6811
|
detail = err?.stderr || err?.message || String(err);
|
|
6650
6812
|
}
|
|
6651
|
-
throw new
|
|
6813
|
+
throw new import_build_utils16.NowBuildError({
|
|
6652
6814
|
code: "DJANGO_SETTINGS_FAILED",
|
|
6653
6815
|
message: `Failed to read Django application settings from ${projectDir}/manage.py:
|
|
6654
6816
|
${detail}`
|
|
6655
6817
|
});
|
|
6656
6818
|
}
|
|
6657
|
-
(0,
|
|
6819
|
+
(0, import_build_utils16.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
|
|
6658
6820
|
const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
|
|
6659
6821
|
if (djangoVersion) {
|
|
6660
6822
|
console.log(`Django ${djangoVersion.join(".")} detected`);
|
|
@@ -6667,7 +6829,7 @@ ${detail}`
|
|
|
6667
6829
|
const variableName = parts.at(-1);
|
|
6668
6830
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
6669
6831
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
6670
|
-
(0,
|
|
6832
|
+
(0, import_build_utils16.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
|
|
6671
6833
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
6672
6834
|
} else {
|
|
6673
6835
|
const wsgiApp = djangoSettings["WSGI_APPLICATION"];
|
|
@@ -6676,7 +6838,7 @@ ${detail}`
|
|
|
6676
6838
|
const variableName = parts.at(-1);
|
|
6677
6839
|
const rel = `${parts.slice(0, -1).join("/")}.py`;
|
|
6678
6840
|
const ep = baseDir ? `${baseDir}/${rel}` : rel;
|
|
6679
|
-
(0,
|
|
6841
|
+
(0, import_build_utils16.debug)(
|
|
6680
6842
|
`Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
|
|
6681
6843
|
);
|
|
6682
6844
|
resolvedEntrypoint = { entrypoint: ep, variableName };
|
|
@@ -6684,7 +6846,7 @@ ${detail}`
|
|
|
6684
6846
|
}
|
|
6685
6847
|
let djangoStatic = null;
|
|
6686
6848
|
if (workPath && venvPath) {
|
|
6687
|
-
const outputStaticDir = (0,
|
|
6849
|
+
const outputStaticDir = (0, import_path14.join)(workPath, ".vercel", "output", "static");
|
|
6688
6850
|
djangoStatic = await runDjangoCollectStatic(
|
|
6689
6851
|
venvPath,
|
|
6690
6852
|
workPath,
|
|
@@ -6704,14 +6866,14 @@ async function downloadFilesInWorkPath({
|
|
|
6704
6866
|
files,
|
|
6705
6867
|
meta = {}
|
|
6706
6868
|
}) {
|
|
6707
|
-
(0,
|
|
6708
|
-
let downloadedFiles = await (0,
|
|
6869
|
+
(0, import_build_utils16.debug)("Downloading user files...");
|
|
6870
|
+
let downloadedFiles = await (0, import_build_utils16.download)(files, workPath, meta);
|
|
6709
6871
|
if (meta.isDev && entrypoint) {
|
|
6710
|
-
const { devCacheDir = (0,
|
|
6711
|
-
const cacheKey = (0,
|
|
6712
|
-
const destCache = (0,
|
|
6713
|
-
await (0,
|
|
6714
|
-
downloadedFiles = await (0,
|
|
6872
|
+
const { devCacheDir = (0, import_path14.join)(workPath, ".now", "cache") } = meta;
|
|
6873
|
+
const cacheKey = (0, import_path14.basename)(entrypoint).replace(/\./g, "_");
|
|
6874
|
+
const destCache = (0, import_path14.join)(devCacheDir, cacheKey);
|
|
6875
|
+
await (0, import_build_utils16.download)(downloadedFiles, destCache);
|
|
6876
|
+
downloadedFiles = await (0, import_build_utils16.glob)("**", destCache);
|
|
6715
6877
|
workPath = destCache;
|
|
6716
6878
|
}
|
|
6717
6879
|
return workPath;
|
|
@@ -6727,13 +6889,13 @@ var build = async ({
|
|
|
6727
6889
|
service
|
|
6728
6890
|
}) => {
|
|
6729
6891
|
let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
|
|
6730
|
-
const builderSpan = parentSpan ?? new
|
|
6892
|
+
const builderSpan = parentSpan ?? new import_build_utils16.Span({ name: "vc.builder" });
|
|
6731
6893
|
const framework = config?.framework;
|
|
6732
6894
|
const shouldInstallVercelWorkers = config?.hasWorkerServices === true;
|
|
6733
6895
|
let spawnEnv;
|
|
6734
6896
|
let projectInstallCommand;
|
|
6735
6897
|
let hasCustomCommand = false;
|
|
6736
|
-
(0,
|
|
6898
|
+
(0, import_build_utils16.debug)(`workPath: ${workPath}`);
|
|
6737
6899
|
workPath = await downloadFilesInWorkPath({
|
|
6738
6900
|
workPath,
|
|
6739
6901
|
files: originalFiles,
|
|
@@ -6742,7 +6904,7 @@ var build = async ({
|
|
|
6742
6904
|
});
|
|
6743
6905
|
try {
|
|
6744
6906
|
if (meta.isDev) {
|
|
6745
|
-
const setupCfg = (0,
|
|
6907
|
+
const setupCfg = (0, import_path14.join)(workPath, "setup.cfg");
|
|
6746
6908
|
await writeFile(setupCfg, "[install]\nprefix=\n");
|
|
6747
6909
|
}
|
|
6748
6910
|
} catch (err) {
|
|
@@ -6765,8 +6927,8 @@ var build = async ({
|
|
|
6765
6927
|
if (detected?.error && detected?.baseDir === void 0) {
|
|
6766
6928
|
throw detected?.error;
|
|
6767
6929
|
}
|
|
6768
|
-
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0,
|
|
6769
|
-
const entrypointAbsDir = (0,
|
|
6930
|
+
const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path14.dirname)(entrypoint) : ".");
|
|
6931
|
+
const entrypointAbsDir = (0, import_path14.join)(workPath, entryDirectory);
|
|
6770
6932
|
const rootDir = repoRootPath ?? workPath;
|
|
6771
6933
|
const pythonPackage = await builderSpan.child("vc.builder.python.discover").trace(
|
|
6772
6934
|
() => discoverPackage({
|
|
@@ -6796,12 +6958,26 @@ var build = async ({
|
|
|
6796
6958
|
`
|
|
6797
6959
|
);
|
|
6798
6960
|
}
|
|
6799
|
-
const venvPath = service?.name ? (0, import_path13.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path13.join)(workPath, ".vercel", "python", ".venv");
|
|
6800
6961
|
const uvCacheDir = getUvCacheDir(workPath);
|
|
6801
|
-
|
|
6802
|
-
|
|
6962
|
+
let uv;
|
|
6963
|
+
try {
|
|
6964
|
+
const uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
|
|
6965
|
+
uv = new UvRunner(uvPath, uvCacheDir);
|
|
6966
|
+
const uvVersionOutput = (0, import_child_process3.execSync)(`${uvPath} --version`, {
|
|
6967
|
+
encoding: "utf8"
|
|
6968
|
+
}).trim();
|
|
6969
|
+
console.log(`Using ${uvVersionOutput}`);
|
|
6970
|
+
} catch (err) {
|
|
6971
|
+
console.log("Failed to install or locate uv");
|
|
6972
|
+
throw new Error(
|
|
6973
|
+
`uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
|
|
6974
|
+
);
|
|
6975
|
+
}
|
|
6976
|
+
const venvPath = service?.name ? (0, import_path14.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path14.join)(workPath, ".vercel", "python", ".venv");
|
|
6977
|
+
const hasCachedVenv = import_fs13.default.existsSync((0, import_path14.join)(venvPath, "pyvenv.cfg"));
|
|
6978
|
+
const hasCachedUv = import_fs13.default.existsSync(uvCacheDir);
|
|
6803
6979
|
if (hasCachedVenv || hasCachedUv) {
|
|
6804
|
-
(0,
|
|
6980
|
+
(0, import_build_utils16.debug)(
|
|
6805
6981
|
`Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
|
|
6806
6982
|
);
|
|
6807
6983
|
}
|
|
@@ -6809,17 +6985,18 @@ var build = async ({
|
|
|
6809
6985
|
await ensureVenv({
|
|
6810
6986
|
pythonVersion,
|
|
6811
6987
|
venvPath,
|
|
6988
|
+
uvPath: uv.getPath(),
|
|
6812
6989
|
uvCacheDir
|
|
6813
6990
|
});
|
|
6814
6991
|
});
|
|
6815
|
-
if ((0,
|
|
6992
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
6816
6993
|
const {
|
|
6817
6994
|
cliType,
|
|
6818
6995
|
lockfileVersion,
|
|
6819
6996
|
packageJsonPackageManager,
|
|
6820
6997
|
turboSupportsCorepackHome
|
|
6821
|
-
} = await (0,
|
|
6822
|
-
spawnEnv = (0,
|
|
6998
|
+
} = await (0, import_build_utils16.scanParentDirs)(workPath, true);
|
|
6999
|
+
spawnEnv = (0, import_build_utils16.getEnvForPackageManager)({
|
|
6823
7000
|
cliType,
|
|
6824
7001
|
lockfileVersion,
|
|
6825
7002
|
packageJsonPackageManager,
|
|
@@ -6841,38 +7018,25 @@ var build = async ({
|
|
|
6841
7018
|
const pythonEnv = createVenvEnv(venvPath, baseEnv, uvCacheDir);
|
|
6842
7019
|
pythonEnv.VERCEL_PYTHON_VENV_PATH = venvPath;
|
|
6843
7020
|
let assumeDepsInstalled = false;
|
|
6844
|
-
let uv;
|
|
6845
|
-
try {
|
|
6846
|
-
const uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
|
|
6847
|
-
uv = new UvRunner(uvPath, uvCacheDir);
|
|
6848
|
-
const uvVersionOutput = (0, import_child_process3.execSync)(`${uvPath} --version`, {
|
|
6849
|
-
encoding: "utf8"
|
|
6850
|
-
}).trim();
|
|
6851
|
-
console.log(`Using ${uvVersionOutput}`);
|
|
6852
|
-
} catch (err) {
|
|
6853
|
-
console.log("Failed to install or locate uv");
|
|
6854
|
-
throw new Error(
|
|
6855
|
-
`uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
|
|
6856
|
-
);
|
|
6857
|
-
}
|
|
6858
7021
|
let uvLockPath = null;
|
|
6859
7022
|
let uvProjectDir = null;
|
|
6860
7023
|
let projectName;
|
|
6861
|
-
await builderSpan.child(
|
|
7024
|
+
await builderSpan.child(import_build_utils16.BUILDER_INSTALLER_STEP, {
|
|
6862
7025
|
installCommand: projectInstallCommand || void 0
|
|
6863
7026
|
}).trace(async () => {
|
|
6864
7027
|
if (projectInstallCommand) {
|
|
6865
|
-
await
|
|
7028
|
+
await import_fs13.default.promises.rm(venvPath, { recursive: true, force: true });
|
|
6866
7029
|
await ensureVenv({
|
|
6867
7030
|
pythonVersion,
|
|
6868
7031
|
venvPath,
|
|
7032
|
+
uvPath: uv.getPath(),
|
|
6869
7033
|
uvCacheDir,
|
|
6870
7034
|
quiet: true
|
|
6871
7035
|
});
|
|
6872
7036
|
console.log(
|
|
6873
7037
|
`Running "install" command: \`${projectInstallCommand}\`...`
|
|
6874
7038
|
);
|
|
6875
|
-
await (0,
|
|
7039
|
+
await (0, import_build_utils16.execCommand)(projectInstallCommand, {
|
|
6876
7040
|
env: pythonEnv,
|
|
6877
7041
|
cwd: workPath
|
|
6878
7042
|
});
|
|
@@ -6893,7 +7057,7 @@ var build = async ({
|
|
|
6893
7057
|
}
|
|
6894
7058
|
if (!assumeDepsInstalled) {
|
|
6895
7059
|
const lockCacheKey = service?.name ? `uv.lock.${service.name}` : "uv.lock";
|
|
6896
|
-
const cachedLockPath = (0,
|
|
7060
|
+
const cachedLockPath = (0, import_path14.join)(uvCacheDir, lockCacheKey);
|
|
6897
7061
|
const { projectDir, lockPath, lockFileProvidedByUser } = await ensureUvProject({
|
|
6898
7062
|
workPath,
|
|
6899
7063
|
rootDir,
|
|
@@ -6913,21 +7077,21 @@ var build = async ({
|
|
|
6913
7077
|
frozen: lockFileProvidedByUser,
|
|
6914
7078
|
locked: !lockFileProvidedByUser
|
|
6915
7079
|
});
|
|
6916
|
-
if (lockPath &&
|
|
6917
|
-
await
|
|
6918
|
-
await
|
|
7080
|
+
if (lockPath && import_fs13.default.existsSync(lockPath)) {
|
|
7081
|
+
await import_fs13.default.promises.mkdir(uvCacheDir, { recursive: true });
|
|
7082
|
+
await import_fs13.default.promises.copyFile(lockPath, cachedLockPath);
|
|
6919
7083
|
}
|
|
6920
7084
|
}
|
|
6921
7085
|
});
|
|
6922
|
-
if ((0,
|
|
7086
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
6923
7087
|
const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
|
|
6924
7088
|
config?.buildCommand;
|
|
6925
|
-
await builderSpan.child(
|
|
7089
|
+
await builderSpan.child(import_build_utils16.BUILDER_COMPILE_STEP, {
|
|
6926
7090
|
buildCommand: projectBuildCommand || void 0
|
|
6927
7091
|
}).trace(async () => {
|
|
6928
7092
|
if (projectBuildCommand) {
|
|
6929
7093
|
console.log(`Running "${projectBuildCommand}"`);
|
|
6930
|
-
await (0,
|
|
7094
|
+
await (0, import_build_utils16.execCommand)(projectBuildCommand, {
|
|
6931
7095
|
env: pythonEnv,
|
|
6932
7096
|
cwd: workPath
|
|
6933
7097
|
});
|
|
@@ -6942,7 +7106,7 @@ var build = async ({
|
|
|
6942
7106
|
}
|
|
6943
7107
|
const hookResult = await runFrameworkHook(framework, {
|
|
6944
7108
|
pythonEnv,
|
|
6945
|
-
projectDir: (0,
|
|
7109
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6946
7110
|
workPath,
|
|
6947
7111
|
venvPath,
|
|
6948
7112
|
entrypoint,
|
|
@@ -6954,25 +7118,25 @@ var build = async ({
|
|
|
6954
7118
|
}
|
|
6955
7119
|
entrypoint = resolved?.entrypoint;
|
|
6956
7120
|
if (!entrypoint) {
|
|
6957
|
-
throw new
|
|
7121
|
+
throw new import_build_utils16.NowBuildError({
|
|
6958
7122
|
code: "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
6959
7123
|
message: "No Python entrypoint could be detected. Please specify an entrypoint file."
|
|
6960
7124
|
});
|
|
6961
7125
|
}
|
|
6962
7126
|
const djangoStatic = hookResult?.djangoStatic ?? null;
|
|
6963
7127
|
const runtimeDep = baseEnv.VERCEL_RUNTIME_PYTHON || `vercel-runtime==${VERCEL_RUNTIME_VERSION}`;
|
|
6964
|
-
(0,
|
|
7128
|
+
(0, import_build_utils16.debug)(`Installing ${runtimeDep}`);
|
|
6965
7129
|
await uv.pip({
|
|
6966
7130
|
venvPath,
|
|
6967
|
-
projectDir: (0,
|
|
7131
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6968
7132
|
args: ["install", runtimeDep]
|
|
6969
7133
|
});
|
|
6970
7134
|
if (shouldInstallVercelWorkers) {
|
|
6971
7135
|
const workersDep = baseEnv.VERCEL_WORKERS_PYTHON || `vercel-workers==${VERCEL_WORKERS_VERSION}`;
|
|
6972
|
-
(0,
|
|
7136
|
+
(0, import_build_utils16.debug)(`Installing ${workersDep}`);
|
|
6973
7137
|
await uv.pip({
|
|
6974
7138
|
venvPath,
|
|
6975
|
-
projectDir: (0,
|
|
7139
|
+
projectDir: (0, import_path14.join)(workPath, entryDirectory),
|
|
6976
7140
|
args: ["install", workersDep]
|
|
6977
7141
|
});
|
|
6978
7142
|
}
|
|
@@ -6980,14 +7144,14 @@ var build = async ({
|
|
|
6980
7144
|
if (quirksResult.buildEnv) {
|
|
6981
7145
|
Object.assign(pythonEnv, quirksResult.buildEnv);
|
|
6982
7146
|
}
|
|
6983
|
-
(0,
|
|
7147
|
+
(0, import_build_utils16.debug)("Entrypoint is", entrypoint);
|
|
6984
7148
|
const moduleName = entrypoint.replace(/\//g, ".").replace(/\.py$/i, "");
|
|
6985
7149
|
if (handlerFunction) {
|
|
6986
|
-
const entrypointPath = (0,
|
|
6987
|
-
const source = await
|
|
7150
|
+
const entrypointPath = (0, import_path14.join)(workPath, entrypoint);
|
|
7151
|
+
const source = await import_fs13.default.promises.readFile(entrypointPath, "utf-8");
|
|
6988
7152
|
const found = await (0, import_python_analysis9.containsTopLevelCallable)(source, handlerFunction);
|
|
6989
7153
|
if (!found) {
|
|
6990
|
-
throw new
|
|
7154
|
+
throw new import_build_utils16.NowBuildError({
|
|
6991
7155
|
code: "PYTHON_HANDLER_NOT_FOUND",
|
|
6992
7156
|
message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
|
|
6993
7157
|
});
|
|
@@ -6996,9 +7160,23 @@ var build = async ({
|
|
|
6996
7160
|
const vendorDir = resolveVendorDir();
|
|
6997
7161
|
const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
|
|
6998
7162
|
const entrypointWithSuffix = `${entrypoint}${suffix}`;
|
|
6999
|
-
(0,
|
|
7000
|
-
const
|
|
7001
|
-
|
|
7163
|
+
(0, import_build_utils16.debug)("Entrypoint with suffix is", entrypointWithSuffix);
|
|
7164
|
+
const crons = await getServiceCrons({
|
|
7165
|
+
service,
|
|
7166
|
+
entrypoint,
|
|
7167
|
+
rawEntrypoint,
|
|
7168
|
+
handlerFunction,
|
|
7169
|
+
pythonBin: getVenvPythonBin(venvPath),
|
|
7170
|
+
env: pythonEnv,
|
|
7171
|
+
workPath
|
|
7172
|
+
});
|
|
7173
|
+
let cronEnvLine = "";
|
|
7174
|
+
if (crons?.length) {
|
|
7175
|
+
const json = JSON.stringify(buildCronRouteTable(crons));
|
|
7176
|
+
(0, import_assert.default)(!json.includes("\\"), `backslash in cron route table: ${json}`);
|
|
7177
|
+
cronEnvLine = `
|
|
7178
|
+
"__VC_CRON_ROUTES": '${json}',`;
|
|
7179
|
+
}
|
|
7002
7180
|
const variableName = resolved?.variableName ?? "";
|
|
7003
7181
|
const runtimeTrampoline = `
|
|
7004
7182
|
import importlib
|
|
@@ -7014,7 +7192,7 @@ os.environ.update({
|
|
|
7014
7192
|
"__VC_HANDLER_ENTRYPOINT": "${entrypointWithSuffix}",
|
|
7015
7193
|
"__VC_HANDLER_ENTRYPOINT_ABS": os.path.join(_here, "${entrypointWithSuffix}"),
|
|
7016
7194
|
"__VC_HANDLER_VENDOR_DIR": "${vendorDir}",
|
|
7017
|
-
"__VC_HANDLER_VARIABLE_NAME": "${variableName}",${
|
|
7195
|
+
"__VC_HANDLER_VARIABLE_NAME": "${variableName}",${cronEnvLine}
|
|
7018
7196
|
})
|
|
7019
7197
|
|
|
7020
7198
|
_vendor_rel = '${vendorDir}'
|
|
@@ -7067,10 +7245,10 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7067
7245
|
cwd: workPath,
|
|
7068
7246
|
ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
|
|
7069
7247
|
};
|
|
7070
|
-
const files = await (0,
|
|
7248
|
+
const files = await (0, import_build_utils16.glob)("**", globOptions);
|
|
7071
7249
|
if (djangoStatic?.manifestRelPath) {
|
|
7072
|
-
files[djangoStatic.manifestRelPath] = new
|
|
7073
|
-
fsPath: (0,
|
|
7250
|
+
files[djangoStatic.manifestRelPath] = new import_build_utils16.FileFsRef({
|
|
7251
|
+
fsPath: (0, import_path14.join)(workPath, djangoStatic.manifestRelPath)
|
|
7074
7252
|
});
|
|
7075
7253
|
}
|
|
7076
7254
|
const depExternalizer = new PythonDependencyExternalizer({
|
|
@@ -7106,12 +7284,12 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7106
7284
|
}
|
|
7107
7285
|
});
|
|
7108
7286
|
const handlerPyFilename = "vc__handler__python";
|
|
7109
|
-
files[`${handlerPyFilename}.py`] = new
|
|
7287
|
+
files[`${handlerPyFilename}.py`] = new import_build_utils16.FileBlob({ data: runtimeTrampoline });
|
|
7110
7288
|
if (config.framework === "fasthtml") {
|
|
7111
7289
|
const { SESSKEY = "" } = process.env;
|
|
7112
|
-
files[".sesskey"] = new
|
|
7290
|
+
files[".sesskey"] = new import_build_utils16.FileBlob({ data: `"${SESSKEY}"` });
|
|
7113
7291
|
}
|
|
7114
|
-
const output = new
|
|
7292
|
+
const output = new import_build_utils16.Lambda({
|
|
7115
7293
|
files,
|
|
7116
7294
|
handler: `${handlerPyFilename}.vc_handler`,
|
|
7117
7295
|
runtime: pythonVersion.runtime,
|
|
@@ -7127,16 +7305,17 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7127
7305
|
uvLockPath
|
|
7128
7306
|
});
|
|
7129
7307
|
} catch (err) {
|
|
7130
|
-
(0,
|
|
7308
|
+
(0, import_build_utils16.debug)(
|
|
7131
7309
|
`Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
|
|
7132
7310
|
);
|
|
7133
7311
|
}
|
|
7134
7312
|
}
|
|
7135
|
-
if (!(0,
|
|
7313
|
+
if (!(0, import_build_utils16.isPythonFramework)(framework) && !service?.name) {
|
|
7136
7314
|
return { resultVersion: 3, result: { output } };
|
|
7137
7315
|
}
|
|
7138
7316
|
const lambdaPath = service?.name ? `_svc/${service.name}/index` : "index";
|
|
7139
|
-
const staticFiles = djangoStatic?.cdnOutputDir ? await (0,
|
|
7317
|
+
const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils16.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
|
|
7318
|
+
const routes = service?.name ? void 0 : [{ handle: "filesystem" }, { src: "/(.*)", dest: `/${lambdaPath}` }];
|
|
7140
7319
|
return {
|
|
7141
7320
|
resultVersion: 2,
|
|
7142
7321
|
result: {
|
|
@@ -7144,10 +7323,8 @@ from vercel_runtime.vc_init import vc_handler
|
|
|
7144
7323
|
[lambdaPath]: output,
|
|
7145
7324
|
...staticFiles
|
|
7146
7325
|
},
|
|
7147
|
-
routes:
|
|
7148
|
-
|
|
7149
|
-
{ src: "/(.*)", dest: `/${lambdaPath}` }
|
|
7150
|
-
]
|
|
7326
|
+
...routes ? { routes } : {},
|
|
7327
|
+
crons
|
|
7151
7328
|
}
|
|
7152
7329
|
};
|
|
7153
7330
|
};
|
|
@@ -7169,14 +7346,14 @@ var prepareCache = async ({
|
|
|
7169
7346
|
}
|
|
7170
7347
|
} catch {
|
|
7171
7348
|
}
|
|
7172
|
-
return (0,
|
|
7349
|
+
return (0, import_build_utils16.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
|
|
7173
7350
|
cwd: root,
|
|
7174
7351
|
ignore
|
|
7175
7352
|
});
|
|
7176
7353
|
};
|
|
7177
7354
|
var shouldServe = (opts) => {
|
|
7178
7355
|
const framework = opts.config.framework;
|
|
7179
|
-
if ((0,
|
|
7356
|
+
if ((0, import_build_utils16.isPythonFramework)(framework)) {
|
|
7180
7357
|
const requestPath = opts.requestPath.replace(/\/$/, "");
|
|
7181
7358
|
if (requestPath.startsWith("api") && opts.hasMatched) {
|
|
7182
7359
|
return false;
|
|
@@ -7195,7 +7372,7 @@ var defaultShouldServe = ({
|
|
|
7195
7372
|
if (entrypoint === requestPath && hasProp(files, entrypoint)) {
|
|
7196
7373
|
return true;
|
|
7197
7374
|
}
|
|
7198
|
-
const { dir, name } = (0,
|
|
7375
|
+
const { dir, name } = (0, import_path14.parse)(entrypoint);
|
|
7199
7376
|
if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
|
|
7200
7377
|
return true;
|
|
7201
7378
|
}
|