@vercel/python 6.55.2 → 6.55.3

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 +341 -304
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -7962,18 +7962,18 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
7962
7962
 
7963
7963
  // src/start-dev-server.ts
7964
7964
  var import_child_process2 = require("child_process");
7965
- var import_fs12 = require("fs");
7966
- var import_path12 = require("path");
7967
- var import_build_utils14 = require("@vercel/build-utils");
7965
+ var import_fs13 = require("fs");
7966
+ var import_path13 = require("path");
7967
+ var import_build_utils15 = require("@vercel/build-utils");
7968
7968
  var import_get_port = __toESM(require_get_port());
7969
7969
  var import_is_port_reachable = __toESM(require_is_port_reachable());
7970
7970
  var import_python_analysis8 = require("@vercel/python-analysis");
7971
7971
 
7972
7972
  // src/subscribers.ts
7973
- var import_path11 = require("path");
7974
- var import_fs11 = __toESM(require("fs"));
7973
+ var import_path12 = require("path");
7974
+ var import_fs12 = __toESM(require("fs"));
7975
7975
  var import_execa6 = __toESM(require_execa());
7976
- var import_build_utils13 = require("@vercel/build-utils");
7976
+ var import_build_utils14 = require("@vercel/build-utils");
7977
7977
 
7978
7978
  // src/module-entrypoint.ts
7979
7979
  var import_path10 = require("path");
@@ -8018,6 +8018,94 @@ async function resolveExistingEntrypoint(workPath, filePath) {
8018
8018
  return null;
8019
8019
  }
8020
8020
 
8021
+ // src/workflows.ts
8022
+ var import_path11 = require("path");
8023
+ var import_fs11 = __toESM(require("fs"));
8024
+ var import_build_utils13 = require("@vercel/build-utils");
8025
+ var WORKFLOW_OUTPUT_DIR = "_py_workflows";
8026
+ var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
8027
+ var WORKFLOW_DEV_TOPIC_PATTERN = "__*wkf_*";
8028
+ var WORKFLOW_QUEUE_TOPIC_RE = /^__(?:[a-z][a-z0-9]*_)?wkf_/;
8029
+ function isWorkflowQueueTopic(topic) {
8030
+ return WORKFLOW_QUEUE_TOPIC_RE.test(topic);
8031
+ }
8032
+ var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
8033
+ function getWorkflowOutputPath(workflowName) {
8034
+ return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
8035
+ }
8036
+ function getWorkflowConsumerName(workflowName) {
8037
+ return (0, import_build_utils13.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
8038
+ }
8039
+ async function getPyprojectWorkflows(workPath) {
8040
+ const pyprojectPath = (0, import_path11.join)(workPath, "pyproject.toml");
8041
+ if (!import_fs11.default.existsSync(pyprojectPath)) {
8042
+ return [];
8043
+ }
8044
+ const pyproject = await (0, import_build_utils13.readConfigFile)(pyprojectPath);
8045
+ const workflows = pyproject?.tool?.vercel?.workflows;
8046
+ if (!workflows) {
8047
+ return [];
8048
+ }
8049
+ if (!Array.isArray(workflows)) {
8050
+ throw workflowError('"tool.vercel.workflows" must be an array');
8051
+ }
8052
+ const parsedWorkflows = await Promise.all(
8053
+ workflows.map((config, index) => parseWorkflow(workPath, index, config))
8054
+ );
8055
+ const seenNames = /* @__PURE__ */ new Set();
8056
+ for (const workflow of parsedWorkflows) {
8057
+ if (seenNames.has(workflow.name)) {
8058
+ throw workflowError(
8059
+ `workflow "${workflow.name}" is declared more than once`
8060
+ );
8061
+ }
8062
+ seenNames.add(workflow.name);
8063
+ }
8064
+ return parsedWorkflows;
8065
+ }
8066
+ async function parseWorkflow(workPath, index, config) {
8067
+ const label = `workflow #${index + 1}`;
8068
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
8069
+ throw workflowError(`${label} must be an object`);
8070
+ }
8071
+ for (const key of Object.keys(config)) {
8072
+ if (!WORKFLOW_FIELD_NAMES.has(key)) {
8073
+ throw workflowError(`${label} has unrecognized field "${key}"`);
8074
+ }
8075
+ }
8076
+ if (typeof config.entrypoint !== "string") {
8077
+ throw workflowError(`${label} must define string field "entrypoint"`);
8078
+ }
8079
+ const entrypoint = parseModuleEntrypoint(config.entrypoint);
8080
+ if (!entrypoint) {
8081
+ throw workflowError(
8082
+ `${label} has invalid entrypoint "${config.entrypoint}". Use "module:object"`
8083
+ );
8084
+ }
8085
+ const name = getModuleEntrypointName(entrypoint);
8086
+ const existingEntrypoint = await resolveExistingEntrypoint(
8087
+ workPath,
8088
+ entrypoint.filePath
8089
+ );
8090
+ if (!existingEntrypoint) {
8091
+ throw workflowError(
8092
+ `workflow "${name}" has entrypoint "${config.entrypoint}" but file "${entrypoint.filePath}" does not exist`
8093
+ );
8094
+ }
8095
+ return {
8096
+ name,
8097
+ entrypoint: existingEntrypoint,
8098
+ moduleName: entrypoint.moduleName,
8099
+ variableName: entrypoint.variableName
8100
+ };
8101
+ }
8102
+ function workflowError(message) {
8103
+ return new import_build_utils13.NowBuildError({
8104
+ code: "PYTHON_INVALID_WORKFLOW_CONFIG",
8105
+ message
8106
+ });
8107
+ }
8108
+
8021
8109
  // src/subscribers.ts
8022
8110
  var SUBSCRIBER_OUTPUT_DIR = "_py_subscribers";
8023
8111
  var TRIGGER_NUMBER_FIELDS = [
@@ -8082,7 +8170,7 @@ function getSubscriberOutputPath(subscriberName) {
8082
8170
  return `${SUBSCRIBER_OUTPUT_DIR}/${safePathSegment(subscriberName)}`;
8083
8171
  }
8084
8172
  function getSubscriberConsumerName(subscriberName) {
8085
- return (0, import_build_utils13.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
8173
+ return (0, import_build_utils14.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
8086
8174
  }
8087
8175
  function getGeneratedQueueHandlerPath(outputPath) {
8088
8176
  return `_vc_queue_handlers/${outputPath.replace(/[^A-Za-z0-9_]+/g, "_")}.py`;
@@ -8091,11 +8179,11 @@ function generatedPythonPathToModule(filePath) {
8091
8179
  return filePath.replace(/\.py$/, "").split(/[\\/]+/).join(".");
8092
8180
  }
8093
8181
  async function getPyprojectSubscribers(workPath, { legacySchema = false } = {}) {
8094
- const pyprojectPath = (0, import_path11.join)(workPath, "pyproject.toml");
8095
- if (!import_fs11.default.existsSync(pyprojectPath)) {
8182
+ const pyprojectPath = (0, import_path12.join)(workPath, "pyproject.toml");
8183
+ if (!import_fs12.default.existsSync(pyprojectPath)) {
8096
8184
  return [];
8097
8185
  }
8098
- const pyproject = await (0, import_build_utils13.readConfigFile)(pyprojectPath);
8186
+ const pyproject = await (0, import_build_utils14.readConfigFile)(pyprojectPath);
8099
8187
  const subscribers = pyproject?.tool?.vercel?.subscribers;
8100
8188
  if (!subscribers) {
8101
8189
  return [];
@@ -8152,8 +8240,15 @@ async function resolveQueueSubscribers({
8152
8240
  )}]${hint}`
8153
8241
  );
8154
8242
  }
8155
- const subscriptions = filterQueueSubscriptions(declaration, introspected);
8243
+ const subscriptions = kind === "workflow" ? introspected.filter(
8244
+ (subscription) => isWorkflowQueueTopic(subscription.topic)
8245
+ ) : filterQueueSubscriptions(declaration, introspected);
8156
8246
  if (subscriptions.length === 0) {
8247
+ if (kind === "workflow") {
8248
+ throw subscriberError(
8249
+ `workflow "${declaration.name}" registered no workflow queue subscriptions${hint}`
8250
+ );
8251
+ }
8157
8252
  const declared = declaration.topicPatterns?.join(", ") ?? "*";
8158
8253
  throw subscriberError(
8159
8254
  `${kind} "${declaration.name}" declared topics [${declared}] but no introspected queue subscriptions matched${hint}`
@@ -8410,7 +8505,7 @@ async function introspectQueueSubscriptions({
8410
8505
  });
8411
8506
  return parseIntrospectedSubscriptions(kind, declaration.name, stdout);
8412
8507
  } catch (err) {
8413
- if (err instanceof import_build_utils13.NowBuildError) {
8508
+ if (err instanceof import_build_utils14.NowBuildError) {
8414
8509
  throw err;
8415
8510
  }
8416
8511
  const message = err instanceof Error ? err.message : String(err);
@@ -8459,7 +8554,7 @@ async function introspectDevQueueSubscriptions({
8459
8554
  };
8460
8555
  });
8461
8556
  } catch (err) {
8462
- (0, import_build_utils13.debug)(
8557
+ (0, import_build_utils14.debug)(
8463
8558
  `Failed to introspect dev queue subscriptions for module "${moduleName}": ${err instanceof Error ? err.message : String(err)}`
8464
8559
  );
8465
8560
  return void 0;
@@ -8526,7 +8621,7 @@ function getQueueWildcardPrefix(pattern) {
8526
8621
  return void 0;
8527
8622
  }
8528
8623
  function subscriberError(message) {
8529
- return new import_build_utils13.NowBuildError({
8624
+ return new import_build_utils14.NowBuildError({
8530
8625
  code: "PYTHON_INVALID_SUBSCRIBER_CONFIG",
8531
8626
  message
8532
8627
  });
@@ -8631,17 +8726,17 @@ async function syncDependencies({
8631
8726
  let { manifestPath } = installInfo;
8632
8727
  const manifest = pythonPackage.manifest;
8633
8728
  if (!manifestType || !manifestPath) {
8634
- (0, import_build_utils14.debug)("No Python project manifest found, skipping dependency sync");
8729
+ (0, import_build_utils15.debug)("No Python project manifest found, skipping dependency sync");
8635
8730
  return;
8636
8731
  }
8637
8732
  if (manifest?.origin && manifestType === "pyproject.toml") {
8638
- const syncDir = (0, import_path12.join)(workPath, ".vercel", "python", "sync");
8639
- (0, import_fs12.mkdirSync)(syncDir, { recursive: true });
8640
- const tempPyproject = (0, import_path12.join)(syncDir, "pyproject.toml");
8733
+ const syncDir = (0, import_path13.join)(workPath, ".vercel", "python", "sync");
8734
+ (0, import_fs13.mkdirSync)(syncDir, { recursive: true });
8735
+ const tempPyproject = (0, import_path13.join)(syncDir, "pyproject.toml");
8641
8736
  const content = (0, import_python_analysis8.stringifyManifest)(manifest.data);
8642
- (0, import_fs12.writeFileSync)(tempPyproject, content, "utf8");
8737
+ (0, import_fs13.writeFileSync)(tempPyproject, content, "utf8");
8643
8738
  manifestPath = tempPyproject;
8644
- (0, import_build_utils14.debug)(
8739
+ (0, import_build_utils15.debug)(
8645
8740
  `Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
8646
8741
  );
8647
8742
  }
@@ -8674,7 +8769,7 @@ async function syncDependencies({
8674
8769
  for (const [channel, chunk] of captured) {
8675
8770
  (channel === "stdout" ? writeOut : writeErr)(chunk.toString());
8676
8771
  }
8677
- throw new import_build_utils14.NowBuildError({
8772
+ throw new import_build_utils15.NowBuildError({
8678
8773
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
8679
8774
  message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
8680
8775
  });
@@ -8689,14 +8784,14 @@ async function runSync({
8689
8784
  onStdout,
8690
8785
  onStderr
8691
8786
  }) {
8692
- const projectDir = (0, import_path12.dirname)(manifestPath);
8787
+ const projectDir = (0, import_path13.dirname)(manifestPath);
8693
8788
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
8694
8789
  let spawnCmd;
8695
8790
  let spawnArgs;
8696
8791
  switch (manifestType) {
8697
8792
  case "uv.lock": {
8698
8793
  if (!uvPath) {
8699
- throw new import_build_utils14.NowBuildError({
8794
+ throw new import_build_utils15.NowBuildError({
8700
8795
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
8701
8796
  message: "uv is required to install dependencies from uv.lock.",
8702
8797
  link: "https://docs.astral.sh/uv/getting-started/installation/",
@@ -8718,11 +8813,11 @@ async function runSync({
8718
8813
  break;
8719
8814
  }
8720
8815
  default:
8721
- (0, import_build_utils14.debug)(`Unknown manifest type: ${manifestType}`);
8816
+ (0, import_build_utils15.debug)(`Unknown manifest type: ${manifestType}`);
8722
8817
  return;
8723
8818
  }
8724
8819
  await new Promise((resolve4, reject) => {
8725
- (0, import_build_utils14.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
8820
+ (0, import_build_utils15.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
8726
8821
  const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
8727
8822
  cwd: projectDir,
8728
8823
  env: getProtectedUvEnv(env),
@@ -8761,7 +8856,7 @@ var COMPLETED_INSTALLS = /* @__PURE__ */ new Set();
8761
8856
  function hasInstalledDistribution(targetDir, packageName) {
8762
8857
  const prefix = `${packageName.replace("-", "_")}-`;
8763
8858
  try {
8764
- return (0, import_fs12.readdirSync)(targetDir).some(
8859
+ return (0, import_fs13.readdirSync)(targetDir).some(
8765
8860
  (entry) => entry.startsWith(prefix) && entry.endsWith(".dist-info")
8766
8861
  );
8767
8862
  } catch {
@@ -8769,7 +8864,7 @@ function hasInstalledDistribution(targetDir, packageName) {
8769
8864
  }
8770
8865
  }
8771
8866
  async function installInjectedDevPackage(pkg, opts) {
8772
- const targetDir = (0, import_path12.join)(opts.workPath, ".vercel", "python");
8867
+ const targetDir = (0, import_path13.join)(opts.workPath, ".vercel", "python");
8773
8868
  const source = pkg.envOverride || pkg.pinnedVersion || pkg.requirement;
8774
8869
  const key = `${targetDir}:${pkg.name}:${source}`;
8775
8870
  if (COMPLETED_INSTALLS.has(key) && hasInstalledDistribution(targetDir, pkg.name)) {
@@ -8783,23 +8878,23 @@ async function installInjectedDevPackage(pkg, opts) {
8783
8878
  }
8784
8879
  async function doInstallInjectedDevPackage(pkg, opts) {
8785
8880
  const { targetDir, workPath, uvPath, pythonBin, env, onStdout, onStderr } = opts;
8786
- (0, import_fs12.mkdirSync)(targetDir, { recursive: true });
8787
- const localDir = (0, import_path12.join)(__dirname, "..", "..", "..", "python", pkg.name);
8788
- const isLocalDev = (0, import_fs12.existsSync)((0, import_path12.join)(localDir, "pyproject.toml"));
8881
+ (0, import_fs13.mkdirSync)(targetDir, { recursive: true });
8882
+ const localDir = (0, import_path13.join)(__dirname, "..", "..", "..", "python", pkg.name);
8883
+ const isLocalDev = (0, import_fs13.existsSync)((0, import_path13.join)(localDir, "pyproject.toml"));
8789
8884
  const requirement = pkg.pinnedVersion ? `${pkg.name}==${pkg.pinnedVersion}` : pkg.requirement ?? pkg.name;
8790
8885
  const dep = pkg.envOverride || (isLocalDev ? localDir : requirement);
8791
8886
  if (!isLocalDev && !pkg.envOverride && pkg.pinnedVersion) {
8792
8887
  const distInfoName = pkg.name.replace("-", "_");
8793
- const distInfo = (0, import_path12.join)(
8888
+ const distInfo = (0, import_path13.join)(
8794
8889
  targetDir,
8795
8890
  `${distInfoName}-${pkg.pinnedVersion}.dist-info`
8796
8891
  );
8797
- if ((0, import_fs12.existsSync)(distInfo)) {
8798
- (0, import_build_utils14.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
8892
+ if ((0, import_fs13.existsSync)(distInfo)) {
8893
+ (0, import_build_utils15.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
8799
8894
  return;
8800
8895
  }
8801
8896
  }
8802
- (0, import_build_utils14.debug)(
8897
+ (0, import_build_utils15.debug)(
8803
8898
  `Installing ${pkg.name} into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${dep})`
8804
8899
  );
8805
8900
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
@@ -8821,14 +8916,14 @@ async function doInstallInjectedDevPackage(pkg, opts) {
8821
8916
  if (onStdout) {
8822
8917
  onStdout(data);
8823
8918
  } else {
8824
- (0, import_build_utils14.debug)(data.toString());
8919
+ (0, import_build_utils15.debug)(data.toString());
8825
8920
  }
8826
8921
  });
8827
8922
  child.stderr?.on("data", (data) => {
8828
8923
  if (onStderr) {
8829
8924
  onStderr(data);
8830
8925
  } else {
8831
- (0, import_build_utils14.debug)(data.toString());
8926
+ (0, import_build_utils15.debug)(data.toString());
8832
8927
  }
8833
8928
  });
8834
8929
  child.on("error", reject);
@@ -8858,12 +8953,12 @@ function installGlobalCleanupHandlers() {
8858
8953
  try {
8859
8954
  process.kill(info.pid, "SIGTERM");
8860
8955
  } catch (err) {
8861
- (0, import_build_utils14.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
8956
+ (0, import_build_utils15.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
8862
8957
  }
8863
8958
  try {
8864
8959
  process.kill(info.pid, "SIGKILL");
8865
8960
  } catch (err) {
8866
- (0, import_build_utils14.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
8961
+ (0, import_build_utils15.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
8867
8962
  }
8868
8963
  PERSISTENT_SERVERS.delete(key);
8869
8964
  }
@@ -8871,7 +8966,7 @@ function installGlobalCleanupHandlers() {
8871
8966
  try {
8872
8967
  restoreWarnings();
8873
8968
  } catch (err) {
8874
- (0, import_build_utils14.debug)(`Error restoring warnings: ${err}`);
8969
+ (0, import_build_utils15.debug)(`Error restoring warnings: ${err}`);
8875
8970
  }
8876
8971
  restoreWarnings = null;
8877
8972
  }
@@ -8888,46 +8983,46 @@ function installGlobalCleanupHandlers() {
8888
8983
  }
8889
8984
  function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
8890
8985
  try {
8891
- const vercelPythonDir = serviceName ? (0, import_path12.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path12.join)(workPath, ".vercel", "python");
8892
- (0, import_fs12.mkdirSync)(vercelPythonDir, { recursive: true });
8986
+ const vercelPythonDir = serviceName ? (0, import_path13.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path13.join)(workPath, ".vercel", "python");
8987
+ (0, import_fs13.mkdirSync)(vercelPythonDir, { recursive: true });
8893
8988
  let qualifiedModule = modulePath;
8894
8989
  let extraPythonPath;
8895
- if ((0, import_fs12.existsSync)((0, import_path12.join)(workPath, "__init__.py"))) {
8896
- const pkgName = (0, import_path12.basename)(workPath);
8990
+ if ((0, import_fs13.existsSync)((0, import_path13.join)(workPath, "__init__.py"))) {
8991
+ const pkgName = (0, import_path13.basename)(workPath);
8897
8992
  qualifiedModule = `${pkgName}.${modulePath}`;
8898
- extraPythonPath = (0, import_path12.dirname)(workPath);
8993
+ extraPythonPath = (0, import_path13.dirname)(workPath);
8899
8994
  }
8900
- const entryAbs = (0, import_path12.join)(workPath, entry);
8901
- const shimPath = (0, import_path12.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
8902
- const templatePath = (0, import_path12.join)(
8995
+ const entryAbs = (0, import_path13.join)(workPath, entry);
8996
+ const shimPath = (0, import_path13.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
8997
+ const templatePath = (0, import_path13.join)(
8903
8998
  __dirname,
8904
8999
  "..",
8905
9000
  "templates",
8906
9001
  `${DEV_SHIM_MODULE}.py`
8907
9002
  );
8908
- const template = (0, import_fs12.readFileSync)(templatePath, "utf8");
9003
+ const template = (0, import_fs13.readFileSync)(templatePath, "utf8");
8909
9004
  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);
8910
- (0, import_fs12.writeFileSync)(shimPath, shimSource, "utf8");
8911
- (0, import_build_utils14.debug)(`Prepared Python dev shim at ${shimPath}`);
9005
+ (0, import_fs13.writeFileSync)(shimPath, shimSource, "utf8");
9006
+ (0, import_build_utils15.debug)(`Prepared Python dev shim at ${shimPath}`);
8912
9007
  return {
8913
9008
  module: DEV_SHIM_MODULE,
8914
9009
  extraPythonPath,
8915
9010
  shimDir: vercelPythonDir
8916
9011
  };
8917
9012
  } catch (err) {
8918
- (0, import_build_utils14.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
9013
+ (0, import_build_utils15.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
8919
9014
  return null;
8920
9015
  }
8921
9016
  }
8922
9017
  async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
8923
- const venvPath = (0, import_path12.join)(workPath, ".venv");
9018
+ const venvPath = (0, import_path13.join)(workPath, ".venv");
8924
9019
  const pendingCreation = PENDING_MANAGED_VENV_CREATIONS.get(venvPath);
8925
9020
  if (pendingCreation) {
8926
9021
  await pendingCreation;
8927
9022
  }
8928
9023
  const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
8929
9024
  if (venvRoot) {
8930
- (0, import_build_utils14.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
9025
+ (0, import_build_utils15.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
8931
9026
  return { command: pythonCmd, args: [] };
8932
9027
  }
8933
9028
  await dedupePendingOperation(
@@ -8940,11 +9035,11 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
8940
9035
  quiet: true
8941
9036
  })
8942
9037
  );
8943
- (0, import_build_utils14.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
9038
+ (0, import_build_utils15.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
8944
9039
  const pythonBin = getVenvPythonBin(venvPath);
8945
9040
  const binDir = getVenvBinDir(venvPath);
8946
9041
  env.VIRTUAL_ENV = venvPath;
8947
- env.PATH = `${binDir}${import_path12.delimiter}${env.PATH || ""}`;
9042
+ env.PATH = `${binDir}${import_path13.delimiter}${env.PATH || ""}`;
8948
9043
  return { command: pythonBin, args: [] };
8949
9044
  }
8950
9045
  var startDevServer = async (opts) => {
@@ -9007,7 +9102,7 @@ var startDevServer = async (opts) => {
9007
9102
  filePath: entrypoint,
9008
9103
  // Schedule-triggered services create their own "app" wrapper dynamically.
9009
9104
  // Other services use handlerFunction as the entrypoint variable name.
9010
- varName: service && (0, import_build_utils14.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9105
+ varName: service && (0, import_build_utils15.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9011
9106
  } : void 0,
9012
9107
  service,
9013
9108
  opts.repoRootPath
@@ -9029,7 +9124,7 @@ var startDevServer = async (opts) => {
9029
9124
  if (detected?.error) {
9030
9125
  throw detected.error;
9031
9126
  }
9032
- throw new import_build_utils14.NowBuildError({
9127
+ throw new import_build_utils15.NowBuildError({
9033
9128
  code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
9034
9129
  message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
9035
9130
  });
@@ -9061,7 +9156,7 @@ var startDevServer = async (opts) => {
9061
9156
  const yellow = "\x1B[33m";
9062
9157
  const white = "\x1B[1m";
9063
9158
  const reset = "\x1B[0m";
9064
- throw new import_build_utils14.NowBuildError({
9159
+ throw new import_build_utils15.NowBuildError({
9065
9160
  code: "PYTHON_EXTERNAL_VENV_DETECTED",
9066
9161
  message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
9067
9162
  Run ${white}deactivate${reset} and try again.`
@@ -9078,11 +9173,11 @@ Run ${white}deactivate${reset} and try again.`
9078
9173
  );
9079
9174
  spawnCommand = runner.command;
9080
9175
  spawnArgsPrefix = runner.args;
9081
- (0, import_build_utils14.debug)(
9176
+ (0, import_build_utils15.debug)(
9082
9177
  `Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
9083
9178
  );
9084
9179
  } else if (venv) {
9085
- (0, import_build_utils14.debug)(`Running in virtualenv at ${venv}`);
9180
+ (0, import_build_utils15.debug)(`Running in virtualenv at ${venv}`);
9086
9181
  } else {
9087
9182
  const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
9088
9183
  workPath,
@@ -9091,9 +9186,9 @@ Run ${white}deactivate${reset} and try again.`
9091
9186
  );
9092
9187
  spawnCommand = venvPythonCmd;
9093
9188
  if (venvRoot) {
9094
- (0, import_build_utils14.debug)(`Using virtualenv at ${venvRoot}`);
9189
+ (0, import_build_utils15.debug)(`Using virtualenv at ${venvRoot}`);
9095
9190
  } else {
9096
- (0, import_build_utils14.debug)("No virtualenv found");
9191
+ (0, import_build_utils15.debug)("No virtualenv found");
9097
9192
  try {
9098
9193
  const yellow = "\x1B[33m";
9099
9194
  const reset = "\x1B[0m";
@@ -9169,7 +9264,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
9169
9264
  );
9170
9265
  }
9171
9266
  } catch (err) {
9172
- (0, import_build_utils14.debug)(
9267
+ (0, import_build_utils15.debug)(
9173
9268
  `Skipping conditional dev package injection: ${err instanceof Error ? err.message : String(err)}`
9174
9269
  );
9175
9270
  }
@@ -9183,7 +9278,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
9183
9278
  devOpts
9184
9279
  );
9185
9280
  }
9186
- const queueSidecarKind = config?.pythonQueueSidecar === "subscriber" || config?.pythonQueueSidecar === "workflow" ? config.pythonQueueSidecar : service && (0, import_build_utils14.isQueueBackedService)(service) ? (0, import_build_utils14.isWorkflowTriggeredService)(service) ? "workflow" : "subscriber" : void 0;
9281
+ const queueSidecarKind = config?.pythonQueueSidecar === "subscriber" || config?.pythonQueueSidecar === "workflow" ? config.pythonQueueSidecar : service && (0, import_build_utils15.isQueueBackedService)(service) ? (0, import_build_utils15.isWorkflowTriggeredService)(service) ? "workflow" : "subscriber" : void 0;
9187
9282
  let queueSubscriptions;
9188
9283
  if (queueSidecarKind) {
9189
9284
  let useQueueServing = !legacyProject;
@@ -9197,14 +9292,14 @@ If you are using a virtual environment, activate it before running "vercel dev",
9197
9292
  }
9198
9293
  if (useQueueServing) {
9199
9294
  env.VERCEL_DEV_QUEUE_SERVING = "1";
9200
- const runtimeDir = (0, import_path12.join)(workPath, ".vercel", "python");
9295
+ const runtimeDir = (0, import_path13.join)(workPath, ".vercel", "python");
9201
9296
  queueSubscriptions = await introspectDevQueueSubscriptions({
9202
9297
  moduleName: modulePath,
9203
9298
  pythonBin: spawnCommand,
9204
9299
  cwd: workPath,
9205
9300
  env: {
9206
9301
  ...env,
9207
- PYTHONPATH: [runtimeDir, env.PYTHONPATH].filter(Boolean).join(import_path12.delimiter)
9302
+ PYTHONPATH: [runtimeDir, env.PYTHONPATH].filter(Boolean).join(import_path13.delimiter)
9208
9303
  },
9209
9304
  integrations: queueIntegrations
9210
9305
  });
@@ -9235,7 +9330,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
9235
9330
  const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
9236
9331
  env.PORT = `${port}`;
9237
9332
  if (entry) {
9238
- env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path12.join)(workPath, entry);
9333
+ env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path13.join)(workPath, entry);
9239
9334
  }
9240
9335
  const devShim = createDevShim(
9241
9336
  workPath,
@@ -9246,8 +9341,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
9246
9341
  variableName ?? ""
9247
9342
  );
9248
9343
  if (devShim) {
9249
- const shimDir = devShim.shimDir || (0, import_path12.join)(workPath, ".vercel", "python");
9250
- const runtimeDir = (0, import_path12.join)(workPath, ".vercel", "python");
9344
+ const shimDir = devShim.shimDir || (0, import_path13.join)(workPath, ".vercel", "python");
9345
+ const runtimeDir = (0, import_path13.join)(workPath, ".vercel", "python");
9251
9346
  const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
9252
9347
  if (devShim.extraPythonPath) {
9253
9348
  pathParts.push(devShim.extraPythonPath);
@@ -9259,12 +9354,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
9259
9354
  if (existingPythonPath) {
9260
9355
  pathParts.push(existingPythonPath);
9261
9356
  }
9262
- env.PYTHONPATH = pathParts.join(import_path12.delimiter);
9357
+ env.PYTHONPATH = pathParts.join(import_path13.delimiter);
9263
9358
  }
9264
9359
  const moduleToRun = devShim?.module || modulePath;
9265
9360
  const pythonArgs = ["-u", "-m", moduleToRun];
9266
9361
  const argv = [...spawnArgsPrefix, ...pythonArgs];
9267
- (0, import_build_utils14.debug)(
9362
+ (0, import_build_utils15.debug)(
9268
9363
  `Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
9269
9364
  );
9270
9365
  if (process.stdout.columns) {
@@ -9318,7 +9413,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
9318
9413
  };
9319
9414
 
9320
9415
  // src/quirks/index.ts
9321
- var import_build_utils17 = require("@vercel/build-utils");
9416
+ var import_build_utils18 = require("@vercel/build-utils");
9322
9417
  var import_python_analysis10 = require("@vercel/python-analysis");
9323
9418
 
9324
9419
  // src/quirks/matplotlib.ts
@@ -9332,9 +9427,9 @@ var matplotlibQuirk = {
9332
9427
  };
9333
9428
 
9334
9429
  // src/quirks/litellm.ts
9335
- var import_fs13 = __toESM(require("fs"));
9336
- var import_path13 = require("path");
9337
- var import_build_utils15 = require("@vercel/build-utils");
9430
+ var import_fs14 = __toESM(require("fs"));
9431
+ var import_path14 = require("path");
9432
+ var import_build_utils16 = require("@vercel/build-utils");
9338
9433
  var LAMBDA_ROOT = "/var/task";
9339
9434
  var CONFIG_CANDIDATES = [
9340
9435
  "litellm_config.yaml",
@@ -9344,9 +9439,9 @@ var CONFIG_CANDIDATES = [
9344
9439
  ];
9345
9440
  async function findConfigFile(workPath) {
9346
9441
  for (const name of CONFIG_CANDIDATES) {
9347
- const candidate = (0, import_path13.join)(workPath, name);
9442
+ const candidate = (0, import_path14.join)(workPath, name);
9348
9443
  try {
9349
- await import_fs13.default.promises.access(candidate);
9444
+ await import_fs14.default.promises.access(candidate);
9350
9445
  return name;
9351
9446
  } catch {
9352
9447
  }
@@ -9361,32 +9456,32 @@ var litellmQuirk = {
9361
9456
  const env = {};
9362
9457
  const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
9363
9458
  for (const sitePackages of sitePackagesDirs) {
9364
- const schemaPath = (0, import_path13.join)(
9459
+ const schemaPath = (0, import_path14.join)(
9365
9460
  sitePackages,
9366
9461
  "litellm",
9367
9462
  "proxy",
9368
9463
  "schema.prisma"
9369
9464
  );
9370
9465
  try {
9371
- await import_fs13.default.promises.access(schemaPath);
9372
- (0, import_build_utils15.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
9466
+ await import_fs14.default.promises.access(schemaPath);
9467
+ (0, import_build_utils16.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
9373
9468
  buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
9374
9469
  break;
9375
9470
  } catch {
9376
9471
  }
9377
9472
  }
9378
9473
  if (!buildEnv.PRISMA_SCHEMA_PATH) {
9379
- (0, import_build_utils15.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
9474
+ (0, import_build_utils16.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
9380
9475
  }
9381
9476
  if (!process.env.CONFIG_FILE_PATH) {
9382
9477
  const configName = await findConfigFile(ctx.workPath);
9383
9478
  if (configName) {
9384
- (0, import_build_utils15.debug)(`LiteLLM quirk: found config at ${configName}`);
9385
- buildEnv.CONFIG_FILE_PATH = (0, import_path13.join)(ctx.workPath, configName);
9386
- env.CONFIG_FILE_PATH = (0, import_path13.join)(LAMBDA_ROOT, configName);
9479
+ (0, import_build_utils16.debug)(`LiteLLM quirk: found config at ${configName}`);
9480
+ buildEnv.CONFIG_FILE_PATH = (0, import_path14.join)(ctx.workPath, configName);
9481
+ env.CONFIG_FILE_PATH = (0, import_path14.join)(LAMBDA_ROOT, configName);
9387
9482
  }
9388
9483
  } else {
9389
- (0, import_build_utils15.debug)(
9484
+ (0, import_build_utils16.debug)(
9390
9485
  `LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
9391
9486
  );
9392
9487
  }
@@ -9395,10 +9490,10 @@ var litellmQuirk = {
9395
9490
  };
9396
9491
 
9397
9492
  // src/quirks/prisma.ts
9398
- var import_fs14 = __toESM(require("fs"));
9399
- var import_path14 = require("path");
9493
+ var import_fs15 = __toESM(require("fs"));
9494
+ var import_path15 = require("path");
9400
9495
  var import_execa7 = __toESM(require_execa());
9401
- var import_build_utils16 = require("@vercel/build-utils");
9496
+ var import_build_utils17 = require("@vercel/build-utils");
9402
9497
  var import_python_analysis9 = require("@vercel/python-analysis");
9403
9498
  function execErrorMessage(err) {
9404
9499
  if (err != null && typeof err === "object" && "stderr" in err) {
@@ -9436,22 +9531,22 @@ model DummyModel {
9436
9531
  async function findUserSchema(workPath) {
9437
9532
  const envPath = process.env.PRISMA_SCHEMA_PATH;
9438
9533
  if (envPath) {
9439
- const resolved = (0, import_path14.isAbsolute)(envPath) ? envPath : (0, import_path14.join)(workPath, envPath);
9534
+ const resolved = (0, import_path15.isAbsolute)(envPath) ? envPath : (0, import_path15.join)(workPath, envPath);
9440
9535
  try {
9441
- await import_fs14.default.promises.access(resolved);
9536
+ await import_fs15.default.promises.access(resolved);
9442
9537
  return resolved;
9443
9538
  } catch {
9444
- (0, import_build_utils16.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
9539
+ (0, import_build_utils17.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
9445
9540
  return null;
9446
9541
  }
9447
9542
  }
9448
9543
  const candidates = [
9449
- (0, import_path14.join)(workPath, "schema.prisma"),
9450
- (0, import_path14.join)(workPath, "prisma", "schema.prisma")
9544
+ (0, import_path15.join)(workPath, "schema.prisma"),
9545
+ (0, import_path15.join)(workPath, "prisma", "schema.prisma")
9451
9546
  ];
9452
9547
  for (const candidate of candidates) {
9453
9548
  try {
9454
- await import_fs14.default.promises.access(candidate);
9549
+ await import_fs15.default.promises.access(candidate);
9455
9550
  return candidate;
9456
9551
  } catch {
9457
9552
  }
@@ -9462,32 +9557,32 @@ async function collectFiles(dir, base) {
9462
9557
  const result = [];
9463
9558
  let entries;
9464
9559
  try {
9465
- entries = await import_fs14.default.promises.readdir(dir, { withFileTypes: true });
9560
+ entries = await import_fs15.default.promises.readdir(dir, { withFileTypes: true });
9466
9561
  } catch {
9467
9562
  return result;
9468
9563
  }
9469
9564
  for (const entry of entries) {
9470
9565
  if (entry.name === "__pycache__")
9471
9566
  continue;
9472
- const full = (0, import_path14.join)(dir, entry.name);
9567
+ const full = (0, import_path15.join)(dir, entry.name);
9473
9568
  if (entry.isDirectory()) {
9474
9569
  result.push(...await collectFiles(full, base));
9475
9570
  } else {
9476
- result.push((0, import_path14.relative)(base, full));
9571
+ result.push((0, import_path15.relative)(base, full));
9477
9572
  }
9478
9573
  }
9479
9574
  return result;
9480
9575
  }
9481
9576
  async function cleanCacheArtifacts(cacheDir, extras = []) {
9482
9577
  const paths = [
9483
- (0, import_path14.join)(cacheDir, "node_modules"),
9484
- (0, import_path14.join)(cacheDir, "package.json"),
9485
- (0, import_path14.join)(cacheDir, "package-lock.json"),
9578
+ (0, import_path15.join)(cacheDir, "node_modules"),
9579
+ (0, import_path15.join)(cacheDir, "package.json"),
9580
+ (0, import_path15.join)(cacheDir, "package-lock.json"),
9486
9581
  ...extras
9487
9582
  ];
9488
9583
  for (const p of paths) {
9489
9584
  try {
9490
- await import_fs14.default.promises.rm(p, { recursive: true, force: true });
9585
+ await import_fs15.default.promises.rm(p, { recursive: true, force: true });
9491
9586
  } catch (err) {
9492
9587
  console.warn(
9493
9588
  `could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
@@ -9511,7 +9606,7 @@ var prismaQuirk = {
9511
9606
  async run(ctx) {
9512
9607
  const { venvPath, pythonEnv, workPath } = ctx;
9513
9608
  const pythonPath = getVenvPythonBin(venvPath);
9514
- const runtimeCacheDir = (0, import_path14.join)(
9609
+ const runtimeCacheDir = (0, import_path15.join)(
9515
9610
  LAMBDA_ROOT2,
9516
9611
  resolveVendorDir(),
9517
9612
  "prisma",
@@ -9521,7 +9616,7 @@ var prismaQuirk = {
9521
9616
  let sitePackages;
9522
9617
  for (const dir of sitePackagesDirs) {
9523
9618
  try {
9524
- await import_fs14.default.promises.access((0, import_path14.join)(dir, "prisma"));
9619
+ await import_fs15.default.promises.access((0, import_path15.join)(dir, "prisma"));
9525
9620
  sitePackages = dir;
9526
9621
  break;
9527
9622
  } catch {
@@ -9533,19 +9628,19 @@ var prismaQuirk = {
9533
9628
  );
9534
9629
  return {};
9535
9630
  }
9536
- const cacheDir = (0, import_path14.join)(sitePackages, "prisma", "__bincache__");
9537
- await import_fs14.default.promises.mkdir(cacheDir, { recursive: true });
9631
+ const cacheDir = (0, import_path15.join)(sitePackages, "prisma", "__bincache__");
9632
+ await import_fs15.default.promises.mkdir(cacheDir, { recursive: true });
9538
9633
  const generateEnv = {
9539
9634
  ...pythonEnv,
9540
9635
  PRISMA_BINARY_CACHE_DIR: cacheDir
9541
9636
  };
9542
- const generatedDir = (0, import_path14.join)(workPath, "_prisma_generated");
9543
- const dummySchemaPath = (0, import_path14.join)(workPath, DUMMY_SCHEMA_NAME);
9544
- await import_fs14.default.promises.writeFile(
9637
+ const generatedDir = (0, import_path15.join)(workPath, "_prisma_generated");
9638
+ const dummySchemaPath = (0, import_path15.join)(workPath, DUMMY_SCHEMA_NAME);
9639
+ await import_fs15.default.promises.writeFile(
9545
9640
  dummySchemaPath,
9546
9641
  buildDummySchema(generatedDir)
9547
9642
  );
9548
- (0, import_build_utils16.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
9643
+ (0, import_build_utils17.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
9549
9644
  try {
9550
9645
  const dummyResult = await (0, import_execa7.default)(
9551
9646
  pythonPath,
@@ -9557,11 +9652,11 @@ var prismaQuirk = {
9557
9652
  }
9558
9653
  );
9559
9654
  if (dummyResult.stdout)
9560
- (0, import_build_utils16.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
9655
+ (0, import_build_utils17.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
9561
9656
  if (dummyResult.stderr)
9562
- (0, import_build_utils16.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
9657
+ (0, import_build_utils17.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
9563
9658
  } catch (err) {
9564
- throw new import_build_utils16.NowBuildError({
9659
+ throw new import_build_utils17.NowBuildError({
9565
9660
  code: "PRISMA_GENERATE_FAILED",
9566
9661
  message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
9567
9662
  ` + execErrorMessage(err)
@@ -9569,47 +9664,47 @@ var prismaQuirk = {
9569
9664
  }
9570
9665
  const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
9571
9666
  const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
9572
- const nodeModulesDir = (0, import_path14.join)(cacheDir, "node_modules", "prisma");
9667
+ const nodeModulesDir = (0, import_path15.join)(cacheDir, "node_modules", "prisma");
9573
9668
  let engineCopied = false;
9574
9669
  try {
9575
- const entries = await import_fs14.default.promises.readdir(nodeModulesDir);
9670
+ const entries = await import_fs15.default.promises.readdir(nodeModulesDir);
9576
9671
  for (const entry of entries) {
9577
9672
  if (!entry.startsWith(srcBinaryPrefix))
9578
9673
  continue;
9579
- const srcPath = (0, import_path14.join)(nodeModulesDir, entry);
9580
- const destPath = (0, import_path14.join)(cacheDir, runtimeName);
9674
+ const srcPath = (0, import_path15.join)(nodeModulesDir, entry);
9675
+ const destPath = (0, import_path15.join)(cacheDir, runtimeName);
9581
9676
  try {
9582
- await import_fs14.default.promises.access(destPath);
9583
- (0, import_build_utils16.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
9677
+ await import_fs15.default.promises.access(destPath);
9678
+ (0, import_build_utils17.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
9584
9679
  } catch {
9585
- (0, import_build_utils16.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
9586
- await import_fs14.default.promises.copyFile(srcPath, destPath);
9680
+ (0, import_build_utils17.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
9681
+ await import_fs15.default.promises.copyFile(srcPath, destPath);
9587
9682
  }
9588
9683
  engineCopied = true;
9589
9684
  }
9590
9685
  } catch (err) {
9591
- throw new import_build_utils16.NowBuildError({
9686
+ throw new import_build_utils17.NowBuildError({
9592
9687
  code: "PRISMA_ENGINE_NOT_FOUND",
9593
9688
  message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
9594
9689
  ` + (err instanceof Error ? err.message : String(err))
9595
9690
  });
9596
9691
  }
9597
9692
  if (!engineCopied) {
9598
- throw new import_build_utils16.NowBuildError({
9693
+ throw new import_build_utils17.NowBuildError({
9599
9694
  code: "PRISMA_ENGINE_NOT_FOUND",
9600
9695
  message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
9601
9696
  });
9602
9697
  }
9603
- const shimPath = (0, import_path14.join)(cacheDir, "openssl");
9604
- await import_fs14.default.promises.writeFile(
9698
+ const shimPath = (0, import_path15.join)(cacheDir, "openssl");
9699
+ await import_fs15.default.promises.writeFile(
9605
9700
  shimPath,
9606
9701
  `#!/bin/sh
9607
9702
  echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
9608
9703
  `
9609
9704
  );
9610
- await import_fs14.default.promises.chmod(shimPath, 493);
9705
+ await import_fs15.default.promises.chmod(shimPath, 493);
9611
9706
  for (const p of [generatedDir, dummySchemaPath]) {
9612
- await import_fs14.default.promises.rm(p, { recursive: true, force: true });
9707
+ await import_fs15.default.promises.rm(p, { recursive: true, force: true });
9613
9708
  }
9614
9709
  await cleanCacheArtifacts(cacheDir);
9615
9710
  const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
@@ -9622,14 +9717,14 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
9622
9717
  pythonEnv
9623
9718
  );
9624
9719
  if (clientAlreadyGenerated) {
9625
- (0, import_build_utils16.debug)(
9720
+ (0, import_build_utils17.debug)(
9626
9721
  "Prisma quirk: client already generated, skipping user schema generate"
9627
9722
  );
9628
9723
  shouldGenerate = false;
9629
9724
  }
9630
9725
  }
9631
9726
  if (shouldGenerate) {
9632
- (0, import_build_utils16.debug)(`Running prisma generate with user schema: ${userSchema}`);
9727
+ (0, import_build_utils17.debug)(`Running prisma generate with user schema: ${userSchema}`);
9633
9728
  try {
9634
9729
  const userResult = await (0, import_execa7.default)(
9635
9730
  pythonPath,
@@ -9641,11 +9736,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
9641
9736
  }
9642
9737
  );
9643
9738
  if (userResult.stdout)
9644
- (0, import_build_utils16.debug)(`prisma generate stdout: ${userResult.stdout}`);
9739
+ (0, import_build_utils17.debug)(`prisma generate stdout: ${userResult.stdout}`);
9645
9740
  if (userResult.stderr)
9646
- (0, import_build_utils16.debug)(`prisma generate stderr: ${userResult.stderr}`);
9741
+ (0, import_build_utils17.debug)(`prisma generate stderr: ${userResult.stderr}`);
9647
9742
  } catch (err) {
9648
- throw new import_build_utils16.NowBuildError({
9743
+ throw new import_build_utils17.NowBuildError({
9649
9744
  code: "PRISMA_GENERATE_FAILED",
9650
9745
  message: `\`prisma generate\` failed for schema "${userSchema}".
9651
9746
  ` + execErrorMessage(err)
@@ -9656,12 +9751,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
9656
9751
  }
9657
9752
  try {
9658
9753
  const allFiles = await collectFiles(
9659
- (0, import_path14.join)(sitePackages, "prisma"),
9754
+ (0, import_path15.join)(sitePackages, "prisma"),
9660
9755
  sitePackages
9661
9756
  );
9662
9757
  const count = await (0, import_python_analysis9.extendDistRecord)(sitePackages, "prisma", allFiles);
9663
9758
  if (count > 0) {
9664
- (0, import_build_utils16.debug)(`Appended ${count} entries to prisma RECORD`);
9759
+ (0, import_build_utils17.debug)(`Appended ${count} entries to prisma RECORD`);
9665
9760
  }
9666
9761
  } catch (err) {
9667
9762
  console.warn(
@@ -9755,13 +9850,13 @@ async function runQuirks(ctx) {
9755
9850
  (0, import_python_analysis10.normalizePackageName)(quirk.dependency)
9756
9851
  );
9757
9852
  if (!installed) {
9758
- (0, import_build_utils17.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
9853
+ (0, import_build_utils18.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
9759
9854
  }
9760
9855
  return installed;
9761
9856
  });
9762
9857
  const sorted = toposortQuirks(activated);
9763
9858
  for (const quirk of sorted) {
9764
- (0, import_build_utils17.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
9859
+ (0, import_build_utils18.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
9765
9860
  const result = await quirk.run(ctx);
9766
9861
  if (result.env) {
9767
9862
  Object.assign(mergedEnv, result.env);
@@ -9782,12 +9877,12 @@ async function runQuirks(ctx) {
9782
9877
  }
9783
9878
 
9784
9879
  // src/django.ts
9785
- var import_fs15 = __toESM(require("fs"));
9786
- var import_path15 = require("path");
9880
+ var import_fs16 = __toESM(require("fs"));
9881
+ var import_path16 = require("path");
9787
9882
  var import_execa8 = __toESM(require_execa());
9788
- var import_build_utils18 = require("@vercel/build-utils");
9789
- var scriptPath2 = (0, import_path15.join)(__dirname, "..", "templates", "vc_django_settings.py");
9790
- var script2 = import_fs15.default.readFileSync(scriptPath2, "utf-8");
9883
+ var import_build_utils19 = require("@vercel/build-utils");
9884
+ var scriptPath2 = (0, import_path16.join)(__dirname, "..", "templates", "vc_django_settings.py");
9885
+ var script2 = import_fs16.default.readFileSync(scriptPath2, "utf-8");
9791
9886
  async function getDjangoSettings(projectDir, env) {
9792
9887
  const { stdout } = await (0, import_execa8.default)("python", ["-c", script2], {
9793
9888
  env,
@@ -9815,10 +9910,10 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9815
9910
  const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
9816
9911
  const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
9817
9912
  const staticSourceDirs = [
9818
- ...installedApps.map((app) => (0, import_path15.join)(djangoPath, ...app.split("."), "static")),
9913
+ ...installedApps.map((app) => (0, import_path16.join)(djangoPath, ...app.split("."), "static")),
9819
9914
  // TODO: Deal with optional prefixes in STATICFILES_DIRS.
9820
9915
  ...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
9821
- ].filter((d) => import_fs15.default.existsSync(d));
9916
+ ].filter((d) => import_fs16.default.existsSync(d));
9822
9917
  if (storageBackend.startsWith("storages.backends.")) {
9823
9918
  console.log(
9824
9919
  "django-storages detected \u2014 running collectstatic with original settings"
@@ -9829,7 +9924,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9829
9924
  });
9830
9925
  return {
9831
9926
  staticSourceDirs,
9832
- staticRoot: staticRoot ? (0, import_path15.resolve)(djangoPath, staticRoot) : null,
9927
+ staticRoot: staticRoot ? (0, import_path16.resolve)(djangoPath, staticRoot) : null,
9833
9928
  cdnOutputDir: null,
9834
9929
  manifestRelPath: null
9835
9930
  };
@@ -9841,9 +9936,9 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9841
9936
  return null;
9842
9937
  }
9843
9938
  const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
9844
- const staticOutputDir = (0, import_path15.join)(outputStaticDir, staticUrlPath);
9845
- await import_fs15.default.promises.mkdir(staticOutputDir, { recursive: true });
9846
- const shimPath = (0, import_path15.join)(djangoPath, "_vercel_collectstatic_settings.py");
9939
+ const staticOutputDir = (0, import_path16.join)(outputStaticDir, staticUrlPath);
9940
+ await import_fs16.default.promises.mkdir(staticOutputDir, { recursive: true });
9941
+ const shimPath = (0, import_path16.join)(djangoPath, "_vercel_collectstatic_settings.py");
9847
9942
  const shimLines = [
9848
9943
  `from ${settingsModule} import *`,
9849
9944
  `STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
@@ -9851,7 +9946,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9851
9946
  if (whitenoiseUseFinders) {
9852
9947
  shimLines.push(`WHITENOISE_USE_FINDERS = False`);
9853
9948
  }
9854
- await import_fs15.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
9949
+ await import_fs16.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
9855
9950
  try {
9856
9951
  console.log("Running collectstatic...");
9857
9952
  await (0, import_execa8.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
@@ -9862,7 +9957,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9862
9957
  cwd: djangoPath
9863
9958
  });
9864
9959
  } finally {
9865
- await import_fs15.default.promises.unlink(shimPath).catch(() => {
9960
+ await import_fs16.default.promises.unlink(shimPath).catch(() => {
9866
9961
  });
9867
9962
  }
9868
9963
  const MANIFEST_STORAGE_BACKENDS = [
@@ -9871,38 +9966,38 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
9871
9966
  ];
9872
9967
  let manifestRelPath = null;
9873
9968
  if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
9874
- const manifestSrc = (0, import_path15.join)(staticOutputDir, "staticfiles.json");
9875
- const resolvedStaticRoot = (0, import_path15.resolve)(djangoPath, staticRoot);
9876
- const manifestDest = (0, import_path15.join)(resolvedStaticRoot, "staticfiles.json");
9877
- await import_fs15.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
9878
- await import_fs15.default.promises.copyFile(manifestSrc, manifestDest);
9879
- manifestRelPath = (0, import_path15.relative)(workPath, manifestDest);
9880
- (0, import_build_utils18.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
9969
+ const manifestSrc = (0, import_path16.join)(staticOutputDir, "staticfiles.json");
9970
+ const resolvedStaticRoot = (0, import_path16.resolve)(djangoPath, staticRoot);
9971
+ const manifestDest = (0, import_path16.join)(resolvedStaticRoot, "staticfiles.json");
9972
+ await import_fs16.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
9973
+ await import_fs16.default.promises.copyFile(manifestSrc, manifestDest);
9974
+ manifestRelPath = (0, import_path16.relative)(workPath, manifestDest);
9975
+ (0, import_build_utils19.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
9881
9976
  }
9882
9977
  return {
9883
9978
  staticSourceDirs,
9884
- staticRoot: staticRoot ? (0, import_path15.resolve)(djangoPath, staticRoot) : null,
9979
+ staticRoot: staticRoot ? (0, import_path16.resolve)(djangoPath, staticRoot) : null,
9885
9980
  cdnOutputDir: outputStaticDir,
9886
9981
  manifestRelPath
9887
9982
  };
9888
9983
  }
9889
9984
 
9890
9985
  // src/fastapi.ts
9891
- var import_fs16 = __toESM(require("fs"));
9892
- var import_path16 = require("path");
9986
+ var import_fs17 = __toESM(require("fs"));
9987
+ var import_path17 = require("path");
9893
9988
  var import_execa9 = __toESM(require_execa());
9894
- var import_build_utils19 = require("@vercel/build-utils");
9895
- var scriptPath3 = (0, import_path16.join)(__dirname, "..", "templates", "vc_fastapi_static.py");
9989
+ var import_build_utils20 = require("@vercel/build-utils");
9990
+ var scriptPath3 = (0, import_path17.join)(__dirname, "..", "templates", "vc_fastapi_static.py");
9896
9991
  var _STATIC_FILE_COLLECTION_ERROR_MESSAGE = "Warning: FastAPI static file collection failed. Static files will not be served from the CDN.";
9897
9992
  async function getFastAPIStaticMounts(venvPath, entrypointAbs, variableName, env, workPath) {
9898
9993
  const pythonPath = getVenvPythonBin(venvPath);
9899
- const outputPath = (0, import_path16.join)(
9994
+ const outputPath = (0, import_path17.join)(
9900
9995
  workPath,
9901
9996
  ".vercel",
9902
9997
  "python",
9903
9998
  "vc_fastapi_static_output.json"
9904
9999
  );
9905
- await import_fs16.default.promises.mkdir((0, import_path16.join)(workPath, ".vercel", "python"), {
10000
+ await import_fs17.default.promises.mkdir((0, import_path17.join)(workPath, ".vercel", "python"), {
9906
10001
  recursive: true
9907
10002
  });
9908
10003
  try {
@@ -9912,27 +10007,27 @@ async function getFastAPIStaticMounts(venvPath, entrypointAbs, variableName, env
9912
10007
  { env, cwd: workPath }
9913
10008
  );
9914
10009
  if (stderr) {
9915
- (0, import_build_utils19.debug)(`FastAPI shim stderr:
10010
+ (0, import_build_utils20.debug)(`FastAPI shim stderr:
9916
10011
  ${stderr}`);
9917
10012
  }
9918
10013
  } catch (err) {
9919
10014
  console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
9920
- (0, import_build_utils19.debug)(
10015
+ (0, import_build_utils20.debug)(
9921
10016
  `FastAPI: could not discover static mounts: ${err?.stderr ?? err?.message ?? err}`
9922
10017
  );
9923
10018
  return [];
9924
10019
  }
9925
10020
  try {
9926
- const raw = await import_fs16.default.promises.readFile(outputPath, "utf8");
10021
+ const raw = await import_fs17.default.promises.readFile(outputPath, "utf8");
9927
10022
  const parsed = JSON.parse(raw);
9928
- (0, import_build_utils19.debug)(`FastAPI: discovered mounts: ${JSON.stringify(parsed)}`);
10023
+ (0, import_build_utils20.debug)(`FastAPI: discovered mounts: ${JSON.stringify(parsed)}`);
9929
10024
  return parsed;
9930
10025
  } catch {
9931
10026
  console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
9932
- (0, import_build_utils19.debug)(`FastAPI: could not read shim output file: ${outputPath}`);
10027
+ (0, import_build_utils20.debug)(`FastAPI: could not read shim output file: ${outputPath}`);
9933
10028
  return [];
9934
10029
  } finally {
9935
- await import_fs16.default.promises.rm(outputPath, { force: true });
10030
+ await import_fs17.default.promises.rm(outputPath, { force: true });
9936
10031
  }
9937
10032
  }
9938
10033
  async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir, entrypointAbs, variableName) {
@@ -9944,18 +10039,18 @@ async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir,
9944
10039
  workPath
9945
10040
  );
9946
10041
  if (mounts.length === 0) {
9947
- (0, import_build_utils19.debug)("FastAPI: no StaticFiles mounts found, skipping");
10042
+ (0, import_build_utils20.debug)("FastAPI: no StaticFiles mounts found, skipping");
9948
10043
  return null;
9949
10044
  }
9950
- (0, import_build_utils19.debug)(
10045
+ (0, import_build_utils20.debug)(
9951
10046
  `Found ${mounts.length} FastAPI static mount(s): ${mounts.map((m) => m.urlPath).join(", ")}`
9952
10047
  );
9953
10048
  for (const mount of mounts) {
9954
10049
  const urlSubPath = mount.urlPath.replace(/^\/|\/$/g, "");
9955
- const dest = (0, import_path16.join)(outputStaticDir, urlSubPath);
9956
- await import_fs16.default.promises.mkdir(dest, { recursive: true });
9957
- await import_fs16.default.promises.cp(mount.directory, dest, { recursive: true });
9958
- (0, import_build_utils19.debug)(`copied ${mount.directory} -> ${dest}`);
10050
+ const dest = (0, import_path17.join)(outputStaticDir, urlSubPath);
10051
+ await import_fs17.default.promises.mkdir(dest, { recursive: true });
10052
+ await import_fs17.default.promises.cp(mount.directory, dest, { recursive: true });
10053
+ (0, import_build_utils20.debug)(`copied ${mount.directory} -> ${dest}`);
9959
10054
  }
9960
10055
  return {
9961
10056
  collectedMounts: mounts.map((m) => m.urlPath),
@@ -10011,10 +10106,10 @@ function fillBytecodeWithinCapacity(files, rankedItems, capacity) {
10011
10106
 
10012
10107
  // src/compileall.ts
10013
10108
  var import_execa10 = __toESM(require_execa());
10014
- var import_build_utils20 = require("@vercel/build-utils");
10015
- var import_fs17 = __toESM(require("fs"));
10109
+ var import_build_utils21 = require("@vercel/build-utils");
10110
+ var import_fs18 = __toESM(require("fs"));
10016
10111
  var import_os3 = require("os");
10017
- var import_path17 = require("path");
10112
+ var import_path18 = require("path");
10018
10113
  var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
10019
10114
  var PYCACHE_PREFIX_DIR = "_vc_pycache";
10020
10115
  var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
@@ -10050,13 +10145,13 @@ async function runCompileAll({
10050
10145
  }
10051
10146
  let tempDir;
10052
10147
  try {
10053
- tempDir = await import_fs17.default.promises.mkdtemp(
10054
- (0, import_path17.join)((0, import_os3.tmpdir)(), "vercel-python-compileall-")
10148
+ tempDir = await import_fs18.default.promises.mkdtemp(
10149
+ (0, import_path18.join)((0, import_os3.tmpdir)(), "vercel-python-compileall-")
10055
10150
  );
10056
- const listPath = (0, import_path17.join)(tempDir, "pysources.json");
10057
- await import_fs17.default.promises.writeFile(listPath, JSON.stringify(uniqueSourceFiles));
10058
- const timingsPath = (0, import_path17.join)(tempDir, "timings.json");
10059
- const scriptPath4 = (0, import_path17.join)(__dirname, "..", "templates", "vc_compileall.py");
10151
+ const listPath = (0, import_path18.join)(tempDir, "pysources.json");
10152
+ await import_fs18.default.promises.writeFile(listPath, JSON.stringify(uniqueSourceFiles));
10153
+ const timingsPath = (0, import_path18.join)(tempDir, "timings.json");
10154
+ const scriptPath4 = (0, import_path18.join)(__dirname, "..", "templates", "vc_compileall.py");
10060
10155
  const baseEnv = env || process.env;
10061
10156
  const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
10062
10157
  await (0, import_execa10.default)(pythonBin, [scriptPath4, listPath, timingsPath], {
@@ -10065,21 +10160,21 @@ async function runCompileAll({
10065
10160
  });
10066
10161
  let timings;
10067
10162
  try {
10068
- const raw = await import_fs17.default.promises.readFile(timingsPath, "utf8");
10163
+ const raw = await import_fs18.default.promises.readFile(timingsPath, "utf8");
10069
10164
  timings = new Map(Object.entries(JSON.parse(raw)));
10070
10165
  } catch (err) {
10071
- (0, import_build_utils20.debug)(`compileall timings unavailable: ${String(err)}`);
10166
+ (0, import_build_utils21.debug)(`compileall timings unavailable: ${String(err)}`);
10072
10167
  }
10073
10168
  return { success: true, timings };
10074
10169
  } catch (err) {
10075
- (0, import_build_utils20.debug)(`compileall error details: ${JSON.stringify(err)}`);
10170
+ (0, import_build_utils21.debug)(`compileall error details: ${JSON.stringify(err)}`);
10076
10171
  return { success: false };
10077
10172
  } finally {
10078
10173
  if (tempDir) {
10079
10174
  try {
10080
- await import_fs17.default.promises.rm(tempDir, { recursive: true, force: true });
10175
+ await import_fs18.default.promises.rm(tempDir, { recursive: true, force: true });
10081
10176
  } catch (err) {
10082
- (0, import_build_utils20.debug)(`compileall temporary file cleanup error: ${String(err)}`);
10177
+ (0, import_build_utils21.debug)(`compileall temporary file cleanup error: ${String(err)}`);
10083
10178
  }
10084
10179
  }
10085
10180
  }
@@ -10116,7 +10211,7 @@ function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor)
10116
10211
  );
10117
10212
  if (!rel)
10118
10213
  return null;
10119
- return (0, import_path17.join)(stagingDir, rel.replaceAll("/", import_path17.sep));
10214
+ return (0, import_path18.join)(stagingDir, rel.replaceAll("/", import_path18.sep));
10120
10215
  }
10121
10216
  function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
10122
10217
  const rel = derivePrefixPycRelPath(
@@ -10140,7 +10235,7 @@ async function collectAppPrefixBytecodeFiles({
10140
10235
  for (const bundlePath of Object.keys(appFiles)) {
10141
10236
  if (!bundlePath.endsWith(".py"))
10142
10237
  continue;
10143
- const sourceAbsPath = (0, import_path17.join)(workPath, bundlePath.replaceAll("/", import_path17.sep));
10238
+ const sourceAbsPath = (0, import_path18.join)(workPath, bundlePath.replaceAll("/", import_path18.sep));
10144
10239
  const stagedFsPath = deriveStagedPycFsPath(
10145
10240
  stagingDir,
10146
10241
  sourceAbsPath,
@@ -10164,7 +10259,7 @@ async function collectAppPrefixBytecodeFiles({
10164
10259
  const results = await Promise.all(
10165
10260
  pending.map(async ({ bundlePath, srcFsPath, moduleKey, sourceAbsPath }) => {
10166
10261
  try {
10167
- const stats = await import_fs17.default.promises.stat(srcFsPath);
10262
+ const stats = await import_fs18.default.promises.stat(srcFsPath);
10168
10263
  return {
10169
10264
  bundlePath,
10170
10265
  srcFsPath,
@@ -10184,7 +10279,7 @@ async function collectAppPrefixBytecodeFiles({
10184
10279
  for (const result of results) {
10185
10280
  if (!result)
10186
10281
  continue;
10187
- const file = new import_build_utils20.FileFsRef({
10282
+ const file = new import_build_utils21.FileFsRef({
10188
10283
  fsPath: result.srcFsPath,
10189
10284
  size: result.size
10190
10285
  });
@@ -10214,15 +10309,15 @@ async function collectAppBytecodeFiles({
10214
10309
  continue;
10215
10310
  pending.push({
10216
10311
  bundlePath: pycRel,
10217
- srcFsPath: (0, import_path17.join)(workPath, pycRel.replaceAll("/", import_path17.sep)),
10312
+ srcFsPath: (0, import_path18.join)(workPath, pycRel.replaceAll("/", import_path18.sep)),
10218
10313
  moduleKey: bundlePath,
10219
- sourceAbsPath: (0, import_path17.join)(workPath, bundlePath.replaceAll("/", import_path17.sep))
10314
+ sourceAbsPath: (0, import_path18.join)(workPath, bundlePath.replaceAll("/", import_path18.sep))
10220
10315
  });
10221
10316
  }
10222
10317
  const results = await Promise.all(
10223
10318
  pending.map(async ({ bundlePath, srcFsPath, moduleKey, sourceAbsPath }) => {
10224
10319
  try {
10225
- const stats = await import_fs17.default.promises.stat(srcFsPath);
10320
+ const stats = await import_fs18.default.promises.stat(srcFsPath);
10226
10321
  return {
10227
10322
  bundlePath,
10228
10323
  srcFsPath,
@@ -10242,7 +10337,7 @@ async function collectAppBytecodeFiles({
10242
10337
  for (const result of results) {
10243
10338
  if (!result)
10244
10339
  continue;
10245
- const file = new import_build_utils20.FileFsRef({
10340
+ const file = new import_build_utils21.FileFsRef({
10246
10341
  fsPath: result.srcFsPath,
10247
10342
  size: result.size
10248
10343
  });
@@ -10261,9 +10356,9 @@ async function collectAppBytecodeFiles({
10261
10356
  }
10262
10357
 
10263
10358
  // src/installed-distributions.ts
10264
- var import_fs18 = __toESM(require("fs"));
10265
- var import_path18 = require("path");
10266
- var import_build_utils21 = require("@vercel/build-utils");
10359
+ var import_fs19 = __toESM(require("fs"));
10360
+ var import_path19 = require("path");
10361
+ var import_build_utils22 = require("@vercel/build-utils");
10267
10362
  var import_python_analysis11 = require("@vercel/python-analysis");
10268
10363
  var STRIP_BASENAMES = /* @__PURE__ */ new Set([
10269
10364
  "py.typed",
@@ -10272,7 +10367,7 @@ var STRIP_BASENAMES = /* @__PURE__ */ new Set([
10272
10367
  "direct_url.json"
10273
10368
  ]);
10274
10369
  function shouldStripVendorFile(filePath) {
10275
- const segments = filePath.split(import_path18.sep);
10370
+ const segments = filePath.split(import_path19.sep);
10276
10371
  if (segments.includes("__pycache__"))
10277
10372
  return true;
10278
10373
  const name = segments[segments.length - 1] ?? "";
@@ -10296,19 +10391,19 @@ function getDistributionFileGroups({
10296
10391
  const dirDistributions = distributions.get(dir);
10297
10392
  if (!dirDistributions)
10298
10393
  continue;
10299
- const sitePackagesDir = (0, import_path18.resolve)(dir);
10394
+ const sitePackagesDir = (0, import_path19.resolve)(dir);
10300
10395
  for (const [name, distribution] of dirDistributions) {
10301
10396
  const packageName = (0, import_python_analysis11.normalizePackageName)(name);
10302
10397
  if (includeSet && !includeSet.has(packageName))
10303
10398
  continue;
10304
10399
  const files = [];
10305
10400
  for (const record of distribution.files) {
10306
- const absolutePath = (0, import_path18.resolve)(
10401
+ const absolutePath = (0, import_path19.resolve)(
10307
10402
  sitePackagesDir,
10308
- record.path.replaceAll("/", import_path18.sep)
10403
+ record.path.replaceAll("/", import_path19.sep)
10309
10404
  );
10310
- const relativePath = (0, import_path18.relative)(sitePackagesDir, absolutePath);
10311
- if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path18.sep}`) || (0, import_path18.isAbsolute)(relativePath)) {
10405
+ const relativePath = (0, import_path19.relative)(sitePackagesDir, absolutePath);
10406
+ if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path19.sep}`) || (0, import_path19.isAbsolute)(relativePath)) {
10312
10407
  continue;
10313
10408
  }
10314
10409
  files.push({ absolutePath, relativePath, record });
@@ -10328,7 +10423,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10328
10423
  const distributions = /* @__PURE__ */ new Map();
10329
10424
  for (const dir of sitePackageDirs) {
10330
10425
  try {
10331
- await import_fs18.default.promises.access(dir);
10426
+ await import_fs19.default.promises.access(dir);
10332
10427
  } catch {
10333
10428
  continue;
10334
10429
  }
@@ -10369,7 +10464,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10369
10464
  if (shouldStripVendorFile(relativePath))
10370
10465
  continue;
10371
10466
  pending.push({
10372
- bundlePath: (0, import_path18.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
10467
+ bundlePath: (0, import_path19.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
10373
10468
  srcFsPath: absolutePath,
10374
10469
  recordSize: record.size != null ? Number(record.size) : void 0
10375
10470
  });
@@ -10379,10 +10474,10 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10379
10474
  pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
10380
10475
  try {
10381
10476
  if (recordSize === void 0) {
10382
- const stats = await import_fs18.default.promises.stat(srcFsPath);
10477
+ const stats = await import_fs19.default.promises.stat(srcFsPath);
10383
10478
  return { bundlePath, srcFsPath, size: stats.size };
10384
10479
  }
10385
- await import_fs18.default.promises.access(srcFsPath);
10480
+ await import_fs19.default.promises.access(srcFsPath);
10386
10481
  return { bundlePath, srcFsPath, size: recordSize };
10387
10482
  } catch {
10388
10483
  return null;
@@ -10393,12 +10488,12 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10393
10488
  for (const result of results) {
10394
10489
  if (!result)
10395
10490
  continue;
10396
- vendorFiles[result.bundlePath] = new import_build_utils21.FileFsRef({
10491
+ vendorFiles[result.bundlePath] = new import_build_utils22.FileFsRef({
10397
10492
  fsPath: result.srcFsPath,
10398
10493
  size: result.size
10399
10494
  });
10400
10495
  }
10401
- (0, import_build_utils21.debug)(
10496
+ (0, import_build_utils22.debug)(
10402
10497
  `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
10403
10498
  );
10404
10499
  return vendorFiles;
@@ -10419,7 +10514,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10419
10514
  knownSize += Number(record.size);
10420
10515
  } else {
10421
10516
  statPromises.push(
10422
- import_fs18.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
10517
+ import_fs19.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
10423
10518
  );
10424
10519
  }
10425
10520
  }
@@ -10462,7 +10557,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10462
10557
  });
10463
10558
  for (const { packageName, sitePackagesDir, files } of distributionGroups) {
10464
10559
  for (const { relativePath } of files) {
10465
- const moduleKey = relativePath.replaceAll(import_path18.sep, "/");
10560
+ const moduleKey = relativePath.replaceAll(import_path19.sep, "/");
10466
10561
  const pycRelativePath = derivePycPath(
10467
10562
  moduleKey,
10468
10563
  this.pythonMajor,
@@ -10470,18 +10565,18 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10470
10565
  );
10471
10566
  if (!pycRelativePath)
10472
10567
  continue;
10473
- const pycFilePath = pycRelativePath.replaceAll("/", import_path18.sep);
10568
+ const pycFilePath = pycRelativePath.replaceAll("/", import_path19.sep);
10474
10569
  pending.push({
10475
- bundlePath: (0, import_path18.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
10476
- srcFsPath: (0, import_path18.join)(sitePackagesDir, pycFilePath),
10570
+ bundlePath: (0, import_path19.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
10571
+ srcFsPath: (0, import_path19.join)(sitePackagesDir, pycFilePath),
10477
10572
  packageName,
10478
10573
  moduleKey,
10479
- sourceAbsPath: (0, import_path18.join)(sitePackagesDir, relativePath)
10574
+ sourceAbsPath: (0, import_path19.join)(sitePackagesDir, relativePath)
10480
10575
  });
10481
10576
  }
10482
10577
  }
10483
10578
  const result = await this.collectExistingBytecode(pending);
10484
- (0, import_build_utils21.debug)(
10579
+ (0, import_build_utils22.debug)(
10485
10580
  `Collected ${Object.keys(result.files).length} bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
10486
10581
  );
10487
10582
  return result;
@@ -10504,7 +10599,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10504
10599
  for (const { absolutePath, relativePath } of files) {
10505
10600
  if (!relativePath.endsWith(".py"))
10506
10601
  continue;
10507
- const recordPath = relativePath.replaceAll(import_path18.sep, "/");
10602
+ const recordPath = relativePath.replaceAll(import_path19.sep, "/");
10508
10603
  const srcFsPath = deriveStagedPycFsPath(
10509
10604
  stagingDir,
10510
10605
  absolutePath,
@@ -10528,7 +10623,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10528
10623
  }
10529
10624
  }
10530
10625
  const result = await this.collectExistingBytecode(pending);
10531
- (0, import_build_utils21.debug)(
10626
+ (0, import_build_utils22.debug)(
10532
10627
  `Collected ${Object.keys(result.files).length} prefix bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
10533
10628
  );
10534
10629
  return result;
@@ -10544,7 +10639,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10544
10639
  sourceAbsPath
10545
10640
  }) => {
10546
10641
  try {
10547
- const stats = await import_fs18.default.promises.stat(srcFsPath);
10642
+ const stats = await import_fs19.default.promises.stat(srcFsPath);
10548
10643
  return {
10549
10644
  bundlePath,
10550
10645
  srcFsPath,
@@ -10566,7 +10661,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10566
10661
  for (const result of results) {
10567
10662
  if (!result)
10568
10663
  continue;
10569
- const file = new import_build_utils21.FileFsRef({
10664
+ const file = new import_build_utils22.FileFsRef({
10570
10665
  fsPath: result.srcFsPath,
10571
10666
  size: result.size
10572
10667
  });
@@ -10588,84 +10683,6 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
10588
10683
  }
10589
10684
  };
10590
10685
 
10591
- // src/workflows.ts
10592
- var import_path19 = require("path");
10593
- var import_fs19 = __toESM(require("fs"));
10594
- var import_build_utils22 = require("@vercel/build-utils");
10595
- var WORKFLOW_OUTPUT_DIR = "_py_workflows";
10596
- var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
10597
- var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
10598
- function getWorkflowOutputPath(workflowName) {
10599
- return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
10600
- }
10601
- function getWorkflowConsumerName(workflowName) {
10602
- return (0, import_build_utils22.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
10603
- }
10604
- async function getPyprojectWorkflows(workPath) {
10605
- const pyprojectPath = (0, import_path19.join)(workPath, "pyproject.toml");
10606
- if (!import_fs19.default.existsSync(pyprojectPath)) {
10607
- return [];
10608
- }
10609
- const pyproject = await (0, import_build_utils22.readConfigFile)(pyprojectPath);
10610
- const workflows = pyproject?.tool?.vercel?.workflows;
10611
- if (!workflows) {
10612
- return [];
10613
- }
10614
- if (!Array.isArray(workflows)) {
10615
- throw workflowError('"tool.vercel.workflows" must be an array');
10616
- }
10617
- if (workflows.length > 1) {
10618
- throw workflowError(
10619
- '"tool.vercel.workflows" must declare a single entrypoint that registers every workflow'
10620
- );
10621
- }
10622
- return Promise.all(
10623
- workflows.map((config, index) => parseWorkflow(workPath, index, config))
10624
- );
10625
- }
10626
- async function parseWorkflow(workPath, index, config) {
10627
- const label = `workflow #${index + 1}`;
10628
- if (!config || typeof config !== "object" || Array.isArray(config)) {
10629
- throw workflowError(`${label} must be an object`);
10630
- }
10631
- for (const key of Object.keys(config)) {
10632
- if (!WORKFLOW_FIELD_NAMES.has(key)) {
10633
- throw workflowError(`${label} has unrecognized field "${key}"`);
10634
- }
10635
- }
10636
- if (typeof config.entrypoint !== "string") {
10637
- throw workflowError(`${label} must define string field "entrypoint"`);
10638
- }
10639
- const entrypoint = parseModuleEntrypoint(config.entrypoint);
10640
- if (!entrypoint) {
10641
- throw workflowError(
10642
- `${label} has invalid entrypoint "${config.entrypoint}". Use "module:object"`
10643
- );
10644
- }
10645
- const name = getModuleEntrypointName(entrypoint);
10646
- const existingEntrypoint = await resolveExistingEntrypoint(
10647
- workPath,
10648
- entrypoint.filePath
10649
- );
10650
- if (!existingEntrypoint) {
10651
- throw workflowError(
10652
- `workflow "${name}" has entrypoint "${config.entrypoint}" but file "${entrypoint.filePath}" does not exist`
10653
- );
10654
- }
10655
- return {
10656
- name,
10657
- entrypoint: existingEntrypoint,
10658
- moduleName: entrypoint.moduleName,
10659
- variableName: entrypoint.variableName
10660
- };
10661
- }
10662
- function workflowError(message) {
10663
- return new import_build_utils22.NowBuildError({
10664
- code: "PYTHON_INVALID_WORKFLOW_CONFIG",
10665
- message
10666
- });
10667
- }
10668
-
10669
10686
  // src/import-closure.ts
10670
10687
  var import_path20 = require("path");
10671
10688
  var import_build_utils23 = require("@vercel/build-utils");
@@ -10799,7 +10816,7 @@ async function getDevSidecars({
10799
10816
  pythonQueueSidecar: "workflow"
10800
10817
  }
10801
10818
  },
10802
- topics: [{ topic: WORKFLOW_TOPIC_PATTERN }]
10819
+ topics: [{ topic: WORKFLOW_DEV_TOPIC_PATTERN }]
10803
10820
  })
10804
10821
  )
10805
10822
  ];
@@ -11424,6 +11441,12 @@ var build = async ({
11424
11441
  projectDir: (0, import_path21.join)(workPath, entryDirectory),
11425
11442
  uvLockPath
11426
11443
  });
11444
+ if (workflowMode === "workers" && workflows.length > 1) {
11445
+ throw new import_build_utils24.NowBuildError({
11446
+ code: "PYTHON_INVALID_WORKFLOW_CONFIG",
11447
+ message: `"tool.vercel.workflows" declares multiple entrypoints, which requires vercel>=${MIN_QUEUE_WORKFLOW_SDK_VERSION} with a distinct namespace per Workflows registry; the installed SDK serves every workflow on the shared __wkf_* topic`
11448
+ });
11449
+ }
11427
11450
  }
11428
11451
  const shouldInstallVercelWorkers = legacyWorkersProject || workflows.length > 0 && workflowMode === "workers";
11429
11452
  if (shouldInstallVercelWorkers) {
@@ -11465,7 +11488,7 @@ var build = async ({
11465
11488
  for (const subscriber of subscribers) {
11466
11489
  if (!subscriber.topicPatterns) {
11467
11490
  subscriber.subscriptions = subscriber.subscriptions.filter(
11468
- (subscription) => !subscription.topic.startsWith("__wkf_")
11491
+ (subscription) => !isWorkflowQueueTopic(subscription.topic)
11469
11492
  );
11470
11493
  }
11471
11494
  }
@@ -11484,8 +11507,7 @@ var build = async ({
11484
11507
  name: workflow.name,
11485
11508
  entrypoint: workflow.entrypoint,
11486
11509
  moduleName: workflow.moduleName,
11487
- variableName: workflow.variableName,
11488
- topicPatterns: [WORKFLOW_TOPIC_PATTERN]
11510
+ variableName: workflow.variableName
11489
11511
  })),
11490
11512
  uv,
11491
11513
  venvPath,
@@ -11493,6 +11515,21 @@ var build = async ({
11493
11515
  kind: "workflow",
11494
11516
  integrations: queueIntegrations
11495
11517
  });
11518
+ for (let i = 0; i < resolved2.length; i++) {
11519
+ for (let j = i + 1; j < resolved2.length; j++) {
11520
+ const overlaps = resolved2[i].subscriptions.some(
11521
+ (left) => resolved2[j].subscriptions.some(
11522
+ (right) => queueTopicPatternsOverlap(left.topic, right.topic)
11523
+ )
11524
+ );
11525
+ if (overlaps) {
11526
+ throw new import_build_utils24.NowBuildError({
11527
+ code: "PYTHON_INVALID_WORKFLOW_CONFIG",
11528
+ message: `workflow entrypoints "${resolved2[i].moduleName}:${resolved2[i].variableName}" and "${resolved2[j].moduleName}:${resolved2[j].variableName}" subscribe to overlapping queue topics; construct each vercel.workflow.Workflows registry with a distinct namespace`
11529
+ });
11530
+ }
11531
+ }
11532
+ }
11496
11533
  for (const workflow of resolved2) {
11497
11534
  workflowQueueSubscriptions.set(workflow.name, workflow.subscriptions);
11498
11535
  await writeGeneratedQueueHandler(