@vercel/python 20.0.0 → 22.0.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 +78 -286
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -574,8 +574,8 @@ var require_semver = __commonJS({
|
|
|
574
574
|
return null;
|
|
575
575
|
}
|
|
576
576
|
}
|
|
577
|
-
exports.valid =
|
|
578
|
-
function
|
|
577
|
+
exports.valid = valid3;
|
|
578
|
+
function valid3(version2, options) {
|
|
579
579
|
var v = parse2(version2, options);
|
|
580
580
|
return v ? v.version : null;
|
|
581
581
|
}
|
|
@@ -2712,14 +2712,14 @@ var require_version = __commonJS({
|
|
|
2712
2712
|
].join("");
|
|
2713
2713
|
module2.exports = {
|
|
2714
2714
|
VERSION_PATTERN,
|
|
2715
|
-
valid:
|
|
2715
|
+
valid: valid3,
|
|
2716
2716
|
clean,
|
|
2717
2717
|
explain,
|
|
2718
2718
|
parse: parse2,
|
|
2719
2719
|
stringify
|
|
2720
2720
|
};
|
|
2721
2721
|
var validRegex = new RegExp("^" + VERSION_PATTERN + "$", "i");
|
|
2722
|
-
function
|
|
2722
|
+
function valid3(version2) {
|
|
2723
2723
|
return validRegex.test(version2) ? version2 : null;
|
|
2724
2724
|
}
|
|
2725
2725
|
var cleanRegex = new RegExp("^\\s*" + VERSION_PATTERN + "\\s*$", "i");
|
|
@@ -2843,13 +2843,13 @@ var require_operator = __commonJS({
|
|
|
2843
2843
|
le,
|
|
2844
2844
|
eq,
|
|
2845
2845
|
ne,
|
|
2846
|
-
ge:
|
|
2846
|
+
ge: ge3,
|
|
2847
2847
|
gt,
|
|
2848
2848
|
"<": lt,
|
|
2849
2849
|
"<=": le,
|
|
2850
2850
|
"==": eq,
|
|
2851
2851
|
"!=": ne,
|
|
2852
|
-
">=":
|
|
2852
|
+
">=": ge3,
|
|
2853
2853
|
">": gt,
|
|
2854
2854
|
"===": arbitrary
|
|
2855
2855
|
};
|
|
@@ -2865,7 +2865,7 @@ var require_operator = __commonJS({
|
|
|
2865
2865
|
function ne(version2, other) {
|
|
2866
2866
|
return compare(version2, other) !== 0;
|
|
2867
2867
|
}
|
|
2868
|
-
function
|
|
2868
|
+
function ge3(version2, other) {
|
|
2869
2869
|
return compare(version2, other) >= 0;
|
|
2870
2870
|
}
|
|
2871
2871
|
function gt(version2, other) {
|
|
@@ -3252,8 +3252,8 @@ var require_semantic = __commonJS({
|
|
|
3252
3252
|
// ../../node_modules/.pnpm/@renovatebot+pep440@4.2.1/node_modules/@renovatebot/pep440/index.js
|
|
3253
3253
|
var require_pep440 = __commonJS({
|
|
3254
3254
|
"../../node_modules/.pnpm/@renovatebot+pep440@4.2.1/node_modules/@renovatebot/pep440/index.js"(exports, module2) {
|
|
3255
|
-
var { valid:
|
|
3256
|
-
var { lt, le, eq, ne, ge:
|
|
3255
|
+
var { valid: valid3, clean, explain, parse: parse2 } = require_version();
|
|
3256
|
+
var { lt, le, eq, ne, ge: ge3, gt, compare, rcompare } = require_operator();
|
|
3257
3257
|
var {
|
|
3258
3258
|
filter,
|
|
3259
3259
|
maxSatisfying,
|
|
@@ -3265,7 +3265,7 @@ var require_pep440 = __commonJS({
|
|
|
3265
3265
|
var { major, minor, patch, inc } = require_semantic();
|
|
3266
3266
|
module2.exports = {
|
|
3267
3267
|
// version
|
|
3268
|
-
valid:
|
|
3268
|
+
valid: valid3,
|
|
3269
3269
|
clean,
|
|
3270
3270
|
explain,
|
|
3271
3271
|
parse: parse2,
|
|
@@ -3276,8 +3276,8 @@ var require_pep440 = __commonJS({
|
|
|
3276
3276
|
eq,
|
|
3277
3277
|
ne,
|
|
3278
3278
|
neq: ne,
|
|
3279
|
-
ge:
|
|
3280
|
-
gte:
|
|
3279
|
+
ge: ge3,
|
|
3280
|
+
gte: ge3,
|
|
3281
3281
|
gt,
|
|
3282
3282
|
compare,
|
|
3283
3283
|
rcompare,
|
|
@@ -3301,9 +3301,9 @@ var require_pep440 = __commonJS({
|
|
|
3301
3301
|
var require_lib = __commonJS({
|
|
3302
3302
|
"../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
|
|
3303
3303
|
var isexe = require_isexe();
|
|
3304
|
-
var { join: join21, delimiter: delimiter2, sep:
|
|
3304
|
+
var { join: join21, delimiter: delimiter2, sep: sep4, posix: posix4 } = require("path");
|
|
3305
3305
|
var isWindows = process.platform === "win32";
|
|
3306
|
-
var rSlash = new RegExp(`[${posix4.sep}${
|
|
3306
|
+
var rSlash = new RegExp(`[${posix4.sep}${sep4 === posix4.sep ? "" : sep4}]`.replace(/(\\)/g, "\\$1"));
|
|
3307
3307
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
3308
3308
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
3309
3309
|
var getPathInfo = (cmd, {
|
|
@@ -3549,8 +3549,8 @@ var require_semver2 = __commonJS({
|
|
|
3549
3549
|
return null;
|
|
3550
3550
|
}
|
|
3551
3551
|
}
|
|
3552
|
-
exports.valid =
|
|
3553
|
-
function
|
|
3552
|
+
exports.valid = valid3;
|
|
3553
|
+
function valid3(version2, options) {
|
|
3554
3554
|
var v = parse2(version2, options);
|
|
3555
3555
|
return v ? v.version : null;
|
|
3556
3556
|
}
|
|
@@ -10371,11 +10371,13 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
10371
10371
|
}
|
|
10372
10372
|
|
|
10373
10373
|
// src/fastapi.ts
|
|
10374
|
+
var import_pep4402 = __toESM(require_pep440());
|
|
10374
10375
|
var import_fs17 = __toESM(require("fs"));
|
|
10375
10376
|
var import_path17 = require("path");
|
|
10376
10377
|
var import_execa9 = __toESM(require_execa());
|
|
10377
10378
|
var import_build_utils20 = require("@vercel/build-utils");
|
|
10378
10379
|
var scriptPath3 = (0, import_path17.join)(__dirname, "..", "templates", "vc_fastapi_static.py");
|
|
10380
|
+
var STATIC_FILES_DEBUG_LABEL = "FastAPI";
|
|
10379
10381
|
var STATIC_COLLECTION_WARNING = "Warning: FastAPI static file collection failed. Static files will not be served from the CDN.";
|
|
10380
10382
|
async function getFastAPIStaticDiscovery(venvPath, entrypointAbs, variableName, env, workPath, suppressMiddlewareMounts) {
|
|
10381
10383
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
@@ -10409,86 +10411,13 @@ ${stderr}`);
|
|
|
10409
10411
|
(0, import_build_utils20.debug)(
|
|
10410
10412
|
`FastAPI: static discovery failed: ${err?.stderr ?? err?.message ?? err}`
|
|
10411
10413
|
);
|
|
10412
|
-
return
|
|
10414
|
+
return import_build_utils20.EMPTY_DISCOVERY;
|
|
10413
10415
|
} finally {
|
|
10414
10416
|
await import_fs17.default.promises.rm(outputPath, { force: true });
|
|
10415
10417
|
}
|
|
10416
10418
|
}
|
|
10417
|
-
function trimTrailingSlashes(urlPath) {
|
|
10418
|
-
return urlPath.replace(/\/+$/, "");
|
|
10419
|
-
}
|
|
10420
|
-
function trimSlashes(urlPath) {
|
|
10421
|
-
return urlPath.replace(/^\/+|\/+$/g, "");
|
|
10422
|
-
}
|
|
10423
|
-
function mountCovers(base, urlPath) {
|
|
10424
|
-
return base === "" || urlPath === base || urlPath.startsWith(base + "/");
|
|
10425
|
-
}
|
|
10426
|
-
function cdnUrlPath(outputStaticDir, destPath) {
|
|
10427
|
-
const rel = (0, import_path17.relative)(outputStaticDir, destPath);
|
|
10428
|
-
return rel === "" ? "/" : "/" + rel.split(import_path17.sep).join("/");
|
|
10429
|
-
}
|
|
10430
|
-
function byCopyPriority(mounts) {
|
|
10431
|
-
return [
|
|
10432
|
-
...mounts.filter((m) => !m.frontend),
|
|
10433
|
-
...mounts.filter((m) => m.frontend).sort((a, b) => b.urlPath.length - a.urlPath.length)
|
|
10434
|
-
];
|
|
10435
|
-
}
|
|
10436
|
-
async function copyFastAPIStaticMounts(mounts, outputStaticDir, excludedFiles = []) {
|
|
10437
|
-
const excluded = new Set(excludedFiles);
|
|
10438
|
-
const higherPriority = [];
|
|
10439
|
-
const copied = [];
|
|
10440
|
-
for (const mount of byCopyPriority(mounts)) {
|
|
10441
|
-
const dest = (0, import_path17.join)(outputStaticDir, trimSlashes(mount.urlPath));
|
|
10442
|
-
try {
|
|
10443
|
-
await import_fs17.default.promises.mkdir(dest, { recursive: true });
|
|
10444
|
-
await import_fs17.default.promises.cp(mount.directory, dest, {
|
|
10445
|
-
recursive: true,
|
|
10446
|
-
force: false,
|
|
10447
|
-
filter: (_src, destPath) => {
|
|
10448
|
-
const urlPath = cdnUrlPath(outputStaticDir, destPath);
|
|
10449
|
-
return !higherPriority.some((base) => mountCovers(base, urlPath)) && !excluded.has(urlPath);
|
|
10450
|
-
}
|
|
10451
|
-
});
|
|
10452
|
-
copied.push(mount);
|
|
10453
|
-
(0, import_build_utils20.debug)(`copied ${mount.directory} -> ${dest}`);
|
|
10454
|
-
} catch (err) {
|
|
10455
|
-
(0, import_build_utils20.debug)(`FastAPI: skipping ${mount.urlPath}: copy failed (${err})`);
|
|
10456
|
-
}
|
|
10457
|
-
higherPriority.push(trimTrailingSlashes(mount.urlPath));
|
|
10458
|
-
}
|
|
10459
|
-
return copied;
|
|
10460
|
-
}
|
|
10461
|
-
var MAX_ROUTE_SRC_LENGTH = 4096;
|
|
10462
|
-
function shadowSrc(bodies) {
|
|
10463
|
-
return `^/((?:${bodies.join("|")})/?)$`;
|
|
10464
|
-
}
|
|
10465
|
-
function redirectSrc(bodies) {
|
|
10466
|
-
return `^/((?:${bodies.join("|")}))$`;
|
|
10467
|
-
}
|
|
10468
|
-
var SHADOW_SRC_WRAPPER_LENGTH = shadowSrc([]).length;
|
|
10469
|
-
var REDIRECT_SRC_WRAPPER_LENGTH = redirectSrc([]).length;
|
|
10470
|
-
function chunkBodies(bodies, wrapperLength) {
|
|
10471
|
-
const chunks = [];
|
|
10472
|
-
let srcLen = 0;
|
|
10473
|
-
let dropped = 0;
|
|
10474
|
-
for (const body of bodies) {
|
|
10475
|
-
if (wrapperLength + body.length > MAX_ROUTE_SRC_LENGTH) {
|
|
10476
|
-
dropped += 1;
|
|
10477
|
-
continue;
|
|
10478
|
-
}
|
|
10479
|
-
const current = chunks[chunks.length - 1];
|
|
10480
|
-
if (current && srcLen + 1 + body.length <= MAX_ROUTE_SRC_LENGTH) {
|
|
10481
|
-
current.push(body);
|
|
10482
|
-
srcLen += 1 + body.length;
|
|
10483
|
-
} else {
|
|
10484
|
-
chunks.push([body]);
|
|
10485
|
-
srcLen = wrapperLength + body.length;
|
|
10486
|
-
}
|
|
10487
|
-
}
|
|
10488
|
-
return { chunks, dropped };
|
|
10489
|
-
}
|
|
10490
10419
|
async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir, entrypointAbs, variableName, suppressMiddlewareMounts = true) {
|
|
10491
|
-
const
|
|
10420
|
+
const discovery = await getFastAPIStaticDiscovery(
|
|
10492
10421
|
venvPath,
|
|
10493
10422
|
entrypointAbs,
|
|
10494
10423
|
variableName,
|
|
@@ -10496,191 +10425,28 @@ async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
10496
10425
|
workPath,
|
|
10497
10426
|
suppressMiddlewareMounts
|
|
10498
10427
|
);
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
return null;
|
|
10502
|
-
}
|
|
10503
|
-
(0, import_build_utils20.debug)(
|
|
10504
|
-
`Found ${mounts.length} FastAPI static mount(s): ${mounts.map((m) => m.urlPath).join(", ")}`
|
|
10505
|
-
);
|
|
10506
|
-
const copiedMounts = await copyFastAPIStaticMounts(
|
|
10507
|
-
mounts,
|
|
10508
|
-
outputStaticDir,
|
|
10509
|
-
excludedFiles
|
|
10510
|
-
);
|
|
10511
|
-
if (copiedMounts.length === 0) {
|
|
10512
|
-
return null;
|
|
10513
|
-
}
|
|
10514
|
-
return {
|
|
10515
|
-
collectedMounts: mounts,
|
|
10516
|
-
cdnOutputDir: outputStaticDir,
|
|
10517
|
-
shadowRoutes,
|
|
10518
|
-
excludedFiles,
|
|
10519
|
-
// Only copied mounts get a fallback: a check:true dest that is missing makes
|
|
10520
|
-
// the proxy exit with the status instead of reaching the Lambda.
|
|
10521
|
-
fallbacks: copiedMounts.flatMap(
|
|
10522
|
-
(m) => m.fallback ? [{ urlPath: m.urlPath, ...m.fallback }] : []
|
|
10523
|
-
)
|
|
10524
|
-
};
|
|
10525
|
-
}
|
|
10526
|
-
function fastapiShadowingRoutes(discovery, lambdaPath) {
|
|
10527
|
-
const byMethods = /* @__PURE__ */ new Map();
|
|
10528
|
-
for (const sr of discovery.shadowRoutes) {
|
|
10529
|
-
const key = sr.methods === null ? "" : JSON.stringify([...sr.methods].sort());
|
|
10530
|
-
const group = byMethods.get(key);
|
|
10531
|
-
if (group) {
|
|
10532
|
-
group.push(sr.body);
|
|
10533
|
-
} else {
|
|
10534
|
-
byMethods.set(key, [sr.body]);
|
|
10535
|
-
}
|
|
10536
|
-
}
|
|
10537
|
-
const routes = [];
|
|
10538
|
-
let dropped = 0;
|
|
10539
|
-
for (const [methodsKey, bodies] of byMethods) {
|
|
10540
|
-
const methods = methodsKey === "" ? void 0 : JSON.parse(methodsKey);
|
|
10541
|
-
const { chunks, dropped: d } = chunkBodies(
|
|
10542
|
-
bodies,
|
|
10543
|
-
SHADOW_SRC_WRAPPER_LENGTH
|
|
10544
|
-
);
|
|
10545
|
-
dropped += d;
|
|
10546
|
-
for (const chunk of chunks) {
|
|
10547
|
-
routes.push({
|
|
10548
|
-
src: shadowSrc(chunk),
|
|
10549
|
-
dest: `/${lambdaPath}`,
|
|
10550
|
-
...methods ? { methods } : {},
|
|
10551
|
-
transforms: [
|
|
10552
|
-
{ type: "request.path", op: "set", args: "/$1" }
|
|
10553
|
-
]
|
|
10554
|
-
});
|
|
10555
|
-
}
|
|
10556
|
-
}
|
|
10557
|
-
if (dropped > 0) {
|
|
10558
|
-
(0, import_build_utils20.debug)(
|
|
10559
|
-
`FastAPI: ${dropped} shadow route(s) over the ${MAX_ROUTE_SRC_LENGTH} char cap left unshadowed`
|
|
10560
|
-
);
|
|
10561
|
-
}
|
|
10562
|
-
return routes;
|
|
10563
|
-
}
|
|
10564
|
-
function escapeRegex(text) {
|
|
10565
|
-
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10566
|
-
}
|
|
10567
|
-
var NAVIGATION_ACCEPT_RE = ".*(?:^|[,\\s])(?:text/html|application/xhtml\\+xml)(?=[,;\\s]|$)(?![^,]*;\\s*q=0(?:\\.0+)?(?:[,;\\s]|$)).*";
|
|
10568
|
-
function fastapiFallbackRoutes(discovery) {
|
|
10569
|
-
const mountPrefixes = discovery.collectedMounts.map(
|
|
10570
|
-
(m) => trimTrailingSlashes(m.urlPath)
|
|
10571
|
-
);
|
|
10572
|
-
return discovery.fallbacks.flatMap((fb) => {
|
|
10573
|
-
const prefix = trimTrailingSlashes(fb.urlPath);
|
|
10574
|
-
const nested = mountPrefixes.filter((urlPath) => urlPath.startsWith(`${prefix}/`)).map((urlPath) => urlPath.slice(prefix.length + 1));
|
|
10575
|
-
const guard = nested.length ? `(?!(?:${nested.map(escapeRegex).join("|")})(?:/|$))` : "";
|
|
10576
|
-
const isNavigation = fb.status === 200;
|
|
10577
|
-
const navigationGuard = isNavigation ? "(?!.*[^/.]\\.[^/]*$)" : "";
|
|
10578
|
-
const src = `^${escapeRegex(prefix)}/${guard}${navigationGuard}.*$`;
|
|
10579
|
-
if (src.length > MAX_ROUTE_SRC_LENGTH) {
|
|
10580
|
-
(0, import_build_utils20.debug)(
|
|
10581
|
-
`FastAPI: fallback route for ${fb.urlPath} over the ${MAX_ROUTE_SRC_LENGTH} char cap, served by the Lambda`
|
|
10582
|
-
);
|
|
10583
|
-
return [];
|
|
10584
|
-
}
|
|
10585
|
-
const navigationOnly = isNavigation ? {
|
|
10586
|
-
has: [
|
|
10587
|
-
{
|
|
10588
|
-
type: "header",
|
|
10589
|
-
key: "accept",
|
|
10590
|
-
value: NAVIGATION_ACCEPT_RE
|
|
10591
|
-
}
|
|
10592
|
-
]
|
|
10593
|
-
} : {};
|
|
10594
|
-
return [
|
|
10595
|
-
{
|
|
10596
|
-
src,
|
|
10597
|
-
dest: `${prefix}/${fb.file}`,
|
|
10598
|
-
status: fb.status,
|
|
10599
|
-
check: true,
|
|
10600
|
-
methods: ["GET", "HEAD"],
|
|
10601
|
-
...navigationOnly
|
|
10602
|
-
}
|
|
10603
|
-
];
|
|
10428
|
+
return (0, import_build_utils20.promoteStaticFiles)(discovery, outputStaticDir, {
|
|
10429
|
+
debugLabel: STATIC_FILES_DEBUG_LABEL
|
|
10604
10430
|
});
|
|
10605
10431
|
}
|
|
10606
10432
|
function getFastAPICdnBundle(collectedMounts, workPath, fastapiConfig) {
|
|
10607
|
-
const redirects =
|
|
10608
|
-
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
higherPriority.push(trimTrailingSlashes(mount.urlPath));
|
|
10615
|
-
continue;
|
|
10616
|
-
}
|
|
10617
|
-
const urlPrefix = trimSlashes(mount.urlPath);
|
|
10618
|
-
const bodies = [];
|
|
10619
|
-
const collectBodies = (absDir, urlPath) => {
|
|
10620
|
-
if (higherPriority.some((base) => mountCovers(base, `/${urlPath}`))) {
|
|
10621
|
-
return;
|
|
10622
|
-
}
|
|
10623
|
-
if (urlPath && import_fs17.default.existsSync((0, import_path17.join)(absDir, "index.html"))) {
|
|
10624
|
-
bodies.push(escapeRegex(urlPath));
|
|
10625
|
-
}
|
|
10626
|
-
for (const entry of import_fs17.default.readdirSync(absDir, { withFileTypes: true })) {
|
|
10627
|
-
if (!entry.isDirectory())
|
|
10628
|
-
continue;
|
|
10629
|
-
collectBodies(
|
|
10630
|
-
(0, import_path17.join)(absDir, entry.name),
|
|
10631
|
-
urlPath ? `${urlPath}/${entry.name}` : entry.name
|
|
10632
|
-
);
|
|
10633
|
-
}
|
|
10634
|
-
};
|
|
10635
|
-
try {
|
|
10636
|
-
collectBodies(mount.directory, urlPrefix);
|
|
10637
|
-
} catch (err) {
|
|
10638
|
-
(0, import_build_utils20.debug)(
|
|
10639
|
-
`FastAPI: skipping bare-dir redirects for ${mount.urlPath} (${err})`
|
|
10640
|
-
);
|
|
10641
|
-
}
|
|
10642
|
-
higherPriority.push(trimTrailingSlashes(mount.urlPath));
|
|
10643
|
-
const { chunks, dropped } = chunkBodies(
|
|
10644
|
-
bodies,
|
|
10645
|
-
REDIRECT_SRC_WRAPPER_LENGTH
|
|
10646
|
-
);
|
|
10647
|
-
redirectDropped += dropped;
|
|
10648
|
-
for (const chunk of chunks) {
|
|
10649
|
-
redirects.push({
|
|
10650
|
-
src: redirectSrc(chunk),
|
|
10651
|
-
dest: "/$1/",
|
|
10652
|
-
status: 307,
|
|
10653
|
-
methods: ["GET", "HEAD"]
|
|
10654
|
-
});
|
|
10655
|
-
}
|
|
10656
|
-
}
|
|
10657
|
-
if (redirectDropped > 0) {
|
|
10658
|
-
(0, import_build_utils20.debug)(
|
|
10659
|
-
`FastAPI: ${redirectDropped} redirect(s) over the ${MAX_ROUTE_SRC_LENGTH} char cap left unredirected`
|
|
10660
|
-
);
|
|
10661
|
-
}
|
|
10662
|
-
if (fastapiConfig?.static?.exclude === true) {
|
|
10663
|
-
for (const mount of collectedMounts) {
|
|
10664
|
-
const relDir = (0, import_path17.relative)(workPath, mount.directory);
|
|
10665
|
-
if (!relDir || relDir.startsWith("..") || (0, import_path17.isAbsolute)(relDir))
|
|
10666
|
-
continue;
|
|
10667
|
-
const relDirUnix = relDir.split(import_path17.sep).join("/");
|
|
10668
|
-
excludePatterns.push(`${relDirUnix}/**`);
|
|
10669
|
-
directoryStubs[`${relDirUnix}/.static-placeholder`] = new import_build_utils20.FileBlob({
|
|
10670
|
-
data: ""
|
|
10671
|
-
});
|
|
10672
|
-
for (const fallbackFile of ["index.html", "404.html"]) {
|
|
10673
|
-
const fsPath = (0, import_path17.join)(mount.directory, fallbackFile);
|
|
10674
|
-
if (import_fs17.default.existsSync(fsPath)) {
|
|
10675
|
-
directoryStubs[`${relDirUnix}/${fallbackFile}`] = new import_build_utils20.FileFsRef({
|
|
10676
|
-
fsPath
|
|
10677
|
-
});
|
|
10678
|
-
}
|
|
10679
|
-
}
|
|
10680
|
-
}
|
|
10681
|
-
}
|
|
10433
|
+
const redirects = (0, import_build_utils20.staticDirectoryRedirects)(collectedMounts, {
|
|
10434
|
+
debugLabel: STATIC_FILES_DEBUG_LABEL
|
|
10435
|
+
});
|
|
10436
|
+
const { excludePatterns, directoryStubs } = fastapiConfig?.static?.exclude === true ? (0, import_build_utils20.staticBundleExclusions)(collectedMounts, workPath, [
|
|
10437
|
+
"index.html",
|
|
10438
|
+
"404.html"
|
|
10439
|
+
]) : { excludePatterns: [], directoryStubs: {} };
|
|
10682
10440
|
return { excludePatterns, directoryStubs, redirects };
|
|
10683
10441
|
}
|
|
10442
|
+
function fastapiStaticOptions(installedDistributions) {
|
|
10443
|
+
const fastapiVersion = installedDistributions.getInstalledVersion("fastapi");
|
|
10444
|
+
const versionAtLeast140 = !!fastapiVersion && !!(0, import_pep4402.valid)(fastapiVersion) && (0, import_pep4402.ge)(fastapiVersion, "0.140.0");
|
|
10445
|
+
return {
|
|
10446
|
+
debugLabel: STATIC_FILES_DEBUG_LABEL,
|
|
10447
|
+
useFallbackForExtensionedPaths: versionAtLeast140
|
|
10448
|
+
};
|
|
10449
|
+
}
|
|
10684
10450
|
|
|
10685
10451
|
// src/index.ts
|
|
10686
10452
|
var import_python_analysis12 = require("@vercel/python-analysis");
|
|
@@ -11073,6 +10839,19 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
11073
10839
|
getSitePackageDirs() {
|
|
11074
10840
|
return this.sitePackageDirs;
|
|
11075
10841
|
}
|
|
10842
|
+
/**
|
|
10843
|
+
* Return the installed version of a package (matched via PEP 503
|
|
10844
|
+
* normalization), or null when the package is not found in the venv.
|
|
10845
|
+
*/
|
|
10846
|
+
getInstalledVersion(packageName) {
|
|
10847
|
+
const target = (0, import_python_analysis11.normalizePackageName)(packageName);
|
|
10848
|
+
for (const index of this.distributions.values()) {
|
|
10849
|
+
const dist = index.get(target);
|
|
10850
|
+
if (dist)
|
|
10851
|
+
return dist.version;
|
|
10852
|
+
}
|
|
10853
|
+
return null;
|
|
10854
|
+
}
|
|
11076
10855
|
async mirrorPackagesIntoVendor({
|
|
11077
10856
|
vendorDirName,
|
|
11078
10857
|
includePackages
|
|
@@ -11908,14 +11687,14 @@ async function packFunctionBundle({
|
|
|
11908
11687
|
Object.assign(files, initialFiles);
|
|
11909
11688
|
const appPythonSourceFiles = Object.keys(files).filter((file) => file.endsWith(".py")).map((file) => (0, import_path21.join)(workPath, file)).sort();
|
|
11910
11689
|
let pycachePrefix;
|
|
11911
|
-
await builderSpan.child("vc.builder.python.bundle").trace(async (bundleSpan) => {
|
|
11912
|
-
const
|
|
11690
|
+
const installedDistributions = await builderSpan.child("vc.builder.python.bundle").trace(async (bundleSpan) => {
|
|
11691
|
+
const installedDistributions2 = await InstalledPythonDistributions.load({
|
|
11913
11692
|
venvPath,
|
|
11914
11693
|
pythonMajor: pythonVersion.major,
|
|
11915
11694
|
pythonMinor: pythonVersion.minor
|
|
11916
11695
|
});
|
|
11917
11696
|
const depExternalizer = new PythonDependencyExternalizer({
|
|
11918
|
-
installedDistributions,
|
|
11697
|
+
installedDistributions: installedDistributions2,
|
|
11919
11698
|
vendorDir,
|
|
11920
11699
|
workPath,
|
|
11921
11700
|
uvLockPath,
|
|
@@ -11945,7 +11724,7 @@ async function packFunctionBundle({
|
|
|
11945
11724
|
}) => {
|
|
11946
11725
|
if (!compileAllOptions)
|
|
11947
11726
|
return void 0;
|
|
11948
|
-
const vendorSourceFiles =
|
|
11727
|
+
const vendorSourceFiles = installedDistributions2.getPythonSourceFiles(includePackages);
|
|
11949
11728
|
let timings;
|
|
11950
11729
|
await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
|
|
11951
11730
|
console.log("Compiling Python bytecode...");
|
|
@@ -11971,7 +11750,7 @@ async function packFunctionBundle({
|
|
|
11971
11750
|
const getImportClosureKeys = () => {
|
|
11972
11751
|
importClosurePromise ??= (async () => {
|
|
11973
11752
|
try {
|
|
11974
|
-
const sitePackageDirs =
|
|
11753
|
+
const sitePackageDirs = installedDistributions2.getSitePackageDirs();
|
|
11975
11754
|
const closure = await withTimeout(
|
|
11976
11755
|
(0, import_python_analysis12.collectImportClosure)(
|
|
11977
11756
|
getImportClosureOptions({
|
|
@@ -12058,7 +11837,7 @@ async function packFunctionBundle({
|
|
|
12058
11837
|
pythonMajor: pyMajor,
|
|
12059
11838
|
pythonMinor: pyMinor
|
|
12060
11839
|
});
|
|
12061
|
-
const vendorInfo = await
|
|
11840
|
+
const vendorInfo = await installedDistributions2.collectBytecodeFiles({
|
|
12062
11841
|
vendorDirName: vendorDir,
|
|
12063
11842
|
includePackages
|
|
12064
11843
|
});
|
|
@@ -12111,12 +11890,12 @@ async function packFunctionBundle({
|
|
|
12111
11890
|
pythonMajor: pyMajor,
|
|
12112
11891
|
pythonMinor: pyMinor
|
|
12113
11892
|
});
|
|
12114
|
-
const bundledVendorInfo = await
|
|
11893
|
+
const bundledVendorInfo = await installedDistributions2.collectPrefixBytecodeFiles({
|
|
12115
11894
|
stagingDir,
|
|
12116
11895
|
runtimeRoot: `/var/task/${vendorDir}`,
|
|
12117
11896
|
includePackages: [...alwaysBundled, ...bundledPublic]
|
|
12118
11897
|
});
|
|
12119
|
-
const externalizedInfo = await
|
|
11898
|
+
const externalizedInfo = await installedDistributions2.collectPrefixBytecodeFiles({
|
|
12120
11899
|
stagingDir,
|
|
12121
11900
|
runtimeRoot: `${RUNTIME_DEPS_DIR}/lib/python${pyMajor}.${pyMinor}/site-packages`,
|
|
12122
11901
|
includePackages: externalized
|
|
@@ -12208,8 +11987,9 @@ async function packFunctionBundle({
|
|
|
12208
11987
|
),
|
|
12209
11988
|
"python.bundle.packingMode": packingMode
|
|
12210
11989
|
});
|
|
11990
|
+
return installedDistributions2;
|
|
12211
11991
|
});
|
|
12212
|
-
return { pycachePrefix, vendorDir, files };
|
|
11992
|
+
return { pycachePrefix, vendorDir, files, installedDistributions };
|
|
12213
11993
|
}
|
|
12214
11994
|
async function buildProxyMiddleware({
|
|
12215
11995
|
workPath,
|
|
@@ -12629,7 +12409,7 @@ var build = async ({
|
|
|
12629
12409
|
const djangoStatic = hookResult?.djangoStatic ?? null;
|
|
12630
12410
|
const fastapiStatic = hookResult?.fastapiStatic ?? null;
|
|
12631
12411
|
const importSeeds = hookResult?.importSeeds ?? [];
|
|
12632
|
-
const cdnOutputDir = djangoStatic?.cdnOutputDir ?? fastapiStatic?.
|
|
12412
|
+
const cdnOutputDir = djangoStatic?.cdnOutputDir ?? fastapiStatic?.outputStaticDir ?? null;
|
|
12633
12413
|
const pipPlatformArgs = target.uvPlatform ? ["--python-platform", target.uvPlatform] : [];
|
|
12634
12414
|
await installInjectedPackage({
|
|
12635
12415
|
name: "vercel-runtime",
|
|
@@ -12895,7 +12675,7 @@ var build = async ({
|
|
|
12895
12675
|
...normalizeGlobs(functionConfig?.excludeFiles)
|
|
12896
12676
|
];
|
|
12897
12677
|
const cdnBundle = getFastAPICdnBundle(
|
|
12898
|
-
fastapiStatic?.
|
|
12678
|
+
fastapiStatic?.discovery.mounts ?? [],
|
|
12899
12679
|
workPath,
|
|
12900
12680
|
pythonPackage.manifest?.data?.tool?.vercel?.fastapi
|
|
12901
12681
|
);
|
|
@@ -12914,7 +12694,7 @@ var build = async ({
|
|
|
12914
12694
|
const { SESSKEY = "" } = process.env;
|
|
12915
12695
|
initialFiles[".sesskey"] = new import_build_utils24.FileBlob({ data: `"${SESSKEY}"` });
|
|
12916
12696
|
}
|
|
12917
|
-
const { pycachePrefix, files } = await packFunctionBundle({
|
|
12697
|
+
const { pycachePrefix, files, installedDistributions } = await packFunctionBundle({
|
|
12918
12698
|
builderSpan,
|
|
12919
12699
|
workPath,
|
|
12920
12700
|
uvLockPath,
|
|
@@ -12927,7 +12707,10 @@ var build = async ({
|
|
|
12927
12707
|
...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
|
|
12928
12708
|
],
|
|
12929
12709
|
initialFiles,
|
|
12930
|
-
additionalExcludes: [
|
|
12710
|
+
additionalExcludes: [
|
|
12711
|
+
...excludeFilesPatterns,
|
|
12712
|
+
...cdnBundle.excludePatterns
|
|
12713
|
+
],
|
|
12931
12714
|
compileAllEnabled,
|
|
12932
12715
|
compileEnv: pythonEnv,
|
|
12933
12716
|
venvPath,
|
|
@@ -13178,8 +12961,17 @@ var build = async ({
|
|
|
13178
12961
|
src: `/${outputPath}`,
|
|
13179
12962
|
dest: `/${outputPath}`
|
|
13180
12963
|
}));
|
|
13181
|
-
const
|
|
13182
|
-
const
|
|
12964
|
+
const staticOptions = fastapiStatic ? fastapiStaticOptions(installedDistributions) : void 0;
|
|
12965
|
+
const shadowingRoutes = fastapiStatic ? (0, import_build_utils24.staticShadowRoutes)(
|
|
12966
|
+
fastapiStatic.discovery.shadowRoutes,
|
|
12967
|
+
lambdaPath,
|
|
12968
|
+
staticOptions
|
|
12969
|
+
) : [];
|
|
12970
|
+
const fallbackRoutes = fastapiStatic ? (0, import_build_utils24.staticFallbackRoutes)(
|
|
12971
|
+
fastapiStatic.copiedMounts,
|
|
12972
|
+
fastapiStatic.discovery.mounts,
|
|
12973
|
+
staticOptions
|
|
12974
|
+
) : [];
|
|
13183
12975
|
const routes = isNonWebService || !output ? queueRoutes.length > 0 ? queueRoutes : void 0 : [
|
|
13184
12976
|
...shadowingRoutes,
|
|
13185
12977
|
...cdnBundle.redirects,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/python",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.0.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@vercel/python-analysis": "0.14.0"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@vercel/build-utils": "14.
|
|
20
|
+
"@vercel/build-utils": "14.18.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@renovatebot/pep440": "4.2.1",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"smol-toml": "1.5.2",
|
|
38
38
|
"vitest": "4.1.10",
|
|
39
39
|
"which": "3.0.0",
|
|
40
|
-
"@vercel/build-utils": "14.16.0",
|
|
41
40
|
"@vercel/error-utils": "2.2.1",
|
|
41
|
+
"@vercel/build-utils": "14.18.0",
|
|
42
42
|
"@vercel/python-runtime": "0.23.2"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|