@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.
Files changed (2) hide show
  1. package/dist/index.js +78 -286
  2. 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 = valid2;
578
- function valid2(version2, options) {
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: valid2,
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 valid2(version2) {
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: ge2,
2846
+ ge: ge3,
2847
2847
  gt,
2848
2848
  "<": lt,
2849
2849
  "<=": le,
2850
2850
  "==": eq,
2851
2851
  "!=": ne,
2852
- ">=": ge2,
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 ge2(version2, other) {
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: valid2, clean, explain, parse: parse2 } = require_version();
3256
- var { lt, le, eq, ne, ge: ge2, gt, compare, rcompare } = require_operator();
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: valid2,
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: ge2,
3280
- gte: ge2,
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: sep5, posix: posix4 } = require("path");
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}${sep5 === posix4.sep ? "" : sep5}]`.replace(/(\\)/g, "\\$1"));
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 = valid2;
3553
- function valid2(version2, options) {
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 { mounts: [], shadowRoutes: [], excludedFiles: [] };
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 { mounts, shadowRoutes, excludedFiles } = await getFastAPIStaticDiscovery(
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
- if (mounts.length === 0) {
10500
- (0, import_build_utils20.debug)("FastAPI: no StaticFiles mounts found, skipping");
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
- const excludePatterns = [];
10609
- const directoryStubs = {};
10610
- let redirectDropped = 0;
10611
- const higherPriority = [];
10612
- for (const mount of byCopyPriority(collectedMounts)) {
10613
- if (!mount.html && !mount.frontend) {
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 installedDistributions = await InstalledPythonDistributions.load({
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 = installedDistributions.getPythonSourceFiles(includePackages);
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 = installedDistributions.getSitePackageDirs();
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 installedDistributions.collectBytecodeFiles({
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 installedDistributions.collectPrefixBytecodeFiles({
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 installedDistributions.collectPrefixBytecodeFiles({
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?.cdnOutputDir ?? null;
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?.collectedMounts ?? [],
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: [...excludeFilesPatterns, ...cdnBundle.excludePatterns],
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 shadowingRoutes = fastapiStatic ? fastapiShadowingRoutes(fastapiStatic, lambdaPath) : [];
13182
- const fallbackRoutes = fastapiStatic ? fastapiFallbackRoutes(fastapiStatic) : [];
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": "20.0.0",
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.16.0"
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": {