@vercel/python 6.55.1 → 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.
- package/dist/index.js +363 -323
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5032,7 +5032,7 @@ var import_fs20 = __toESM(require("fs"));
|
|
|
5032
5032
|
var import_path21 = require("path");
|
|
5033
5033
|
|
|
5034
5034
|
// src/package-versions.ts
|
|
5035
|
-
var VERCEL_RUNTIME_VERSION = "0.
|
|
5035
|
+
var VERCEL_RUNTIME_VERSION = "0.18.0";
|
|
5036
5036
|
var VERCEL_WORKERS_VERSION = "0.0.25";
|
|
5037
5037
|
|
|
5038
5038
|
// src/conditional-vendoring.ts
|
|
@@ -5083,12 +5083,6 @@ async function getQueueIntegrations({
|
|
|
5083
5083
|
}
|
|
5084
5084
|
return integrations;
|
|
5085
5085
|
}
|
|
5086
|
-
var INJECTED_PACKAGE_NAMES = /* @__PURE__ */ new Set([
|
|
5087
|
-
"vercel-celery",
|
|
5088
|
-
"vercel-celery-bundle",
|
|
5089
|
-
"vercel-dramatiq",
|
|
5090
|
-
"vercel-dramatiq-bundle"
|
|
5091
|
-
]);
|
|
5092
5086
|
async function getConditionalInjectedPackages({
|
|
5093
5087
|
pythonPackage,
|
|
5094
5088
|
env
|
|
@@ -5100,7 +5094,7 @@ async function getConditionalInjectedPackages({
|
|
|
5100
5094
|
for (const [upstream, adapter] of UPSTREAM_DEPENDENCY_ADAPTERS) {
|
|
5101
5095
|
if (!dependencies.has(upstream))
|
|
5102
5096
|
continue;
|
|
5103
|
-
if (
|
|
5097
|
+
if (dependencies.has(adapter.bundled) || dependencies.has(adapter.unbundled)) {
|
|
5104
5098
|
continue;
|
|
5105
5099
|
}
|
|
5106
5100
|
const name = adapter.preferUnbundledWhenPresent.some(
|
|
@@ -5126,13 +5120,6 @@ async function getDirectDependencyNames(pythonPackage) {
|
|
|
5126
5120
|
);
|
|
5127
5121
|
return dependencyNames;
|
|
5128
5122
|
}
|
|
5129
|
-
function hasDirectInjectedPackage(dependencies) {
|
|
5130
|
-
for (const packageName of INJECTED_PACKAGE_NAMES) {
|
|
5131
|
-
if (dependencies.has(packageName))
|
|
5132
|
-
return true;
|
|
5133
|
-
}
|
|
5134
|
-
return false;
|
|
5135
|
-
}
|
|
5136
5123
|
|
|
5137
5124
|
// src/sdk-detection.ts
|
|
5138
5125
|
var import_fs = __toESM(require("fs"));
|
|
@@ -7975,18 +7962,18 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
|
|
|
7975
7962
|
|
|
7976
7963
|
// src/start-dev-server.ts
|
|
7977
7964
|
var import_child_process2 = require("child_process");
|
|
7978
|
-
var
|
|
7979
|
-
var
|
|
7980
|
-
var
|
|
7965
|
+
var import_fs13 = require("fs");
|
|
7966
|
+
var import_path13 = require("path");
|
|
7967
|
+
var import_build_utils15 = require("@vercel/build-utils");
|
|
7981
7968
|
var import_get_port = __toESM(require_get_port());
|
|
7982
7969
|
var import_is_port_reachable = __toESM(require_is_port_reachable());
|
|
7983
7970
|
var import_python_analysis8 = require("@vercel/python-analysis");
|
|
7984
7971
|
|
|
7985
7972
|
// src/subscribers.ts
|
|
7986
|
-
var
|
|
7987
|
-
var
|
|
7973
|
+
var import_path12 = require("path");
|
|
7974
|
+
var import_fs12 = __toESM(require("fs"));
|
|
7988
7975
|
var import_execa6 = __toESM(require_execa());
|
|
7989
|
-
var
|
|
7976
|
+
var import_build_utils14 = require("@vercel/build-utils");
|
|
7990
7977
|
|
|
7991
7978
|
// src/module-entrypoint.ts
|
|
7992
7979
|
var import_path10 = require("path");
|
|
@@ -8031,6 +8018,94 @@ async function resolveExistingEntrypoint(workPath, filePath) {
|
|
|
8031
8018
|
return null;
|
|
8032
8019
|
}
|
|
8033
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
|
+
|
|
8034
8109
|
// src/subscribers.ts
|
|
8035
8110
|
var SUBSCRIBER_OUTPUT_DIR = "_py_subscribers";
|
|
8036
8111
|
var TRIGGER_NUMBER_FIELDS = [
|
|
@@ -8095,7 +8170,7 @@ function getSubscriberOutputPath(subscriberName) {
|
|
|
8095
8170
|
return `${SUBSCRIBER_OUTPUT_DIR}/${safePathSegment(subscriberName)}`;
|
|
8096
8171
|
}
|
|
8097
8172
|
function getSubscriberConsumerName(subscriberName) {
|
|
8098
|
-
return (0,
|
|
8173
|
+
return (0, import_build_utils14.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
|
|
8099
8174
|
}
|
|
8100
8175
|
function getGeneratedQueueHandlerPath(outputPath) {
|
|
8101
8176
|
return `_vc_queue_handlers/${outputPath.replace(/[^A-Za-z0-9_]+/g, "_")}.py`;
|
|
@@ -8104,11 +8179,11 @@ function generatedPythonPathToModule(filePath) {
|
|
|
8104
8179
|
return filePath.replace(/\.py$/, "").split(/[\\/]+/).join(".");
|
|
8105
8180
|
}
|
|
8106
8181
|
async function getPyprojectSubscribers(workPath, { legacySchema = false } = {}) {
|
|
8107
|
-
const pyprojectPath = (0,
|
|
8108
|
-
if (!
|
|
8182
|
+
const pyprojectPath = (0, import_path12.join)(workPath, "pyproject.toml");
|
|
8183
|
+
if (!import_fs12.default.existsSync(pyprojectPath)) {
|
|
8109
8184
|
return [];
|
|
8110
8185
|
}
|
|
8111
|
-
const pyproject = await (0,
|
|
8186
|
+
const pyproject = await (0, import_build_utils14.readConfigFile)(pyprojectPath);
|
|
8112
8187
|
const subscribers = pyproject?.tool?.vercel?.subscribers;
|
|
8113
8188
|
if (!subscribers) {
|
|
8114
8189
|
return [];
|
|
@@ -8165,8 +8240,15 @@ async function resolveQueueSubscribers({
|
|
|
8165
8240
|
)}]${hint}`
|
|
8166
8241
|
);
|
|
8167
8242
|
}
|
|
8168
|
-
const subscriptions =
|
|
8243
|
+
const subscriptions = kind === "workflow" ? introspected.filter(
|
|
8244
|
+
(subscription) => isWorkflowQueueTopic(subscription.topic)
|
|
8245
|
+
) : filterQueueSubscriptions(declaration, introspected);
|
|
8169
8246
|
if (subscriptions.length === 0) {
|
|
8247
|
+
if (kind === "workflow") {
|
|
8248
|
+
throw subscriberError(
|
|
8249
|
+
`workflow "${declaration.name}" registered no workflow queue subscriptions${hint}`
|
|
8250
|
+
);
|
|
8251
|
+
}
|
|
8170
8252
|
const declared = declaration.topicPatterns?.join(", ") ?? "*";
|
|
8171
8253
|
throw subscriberError(
|
|
8172
8254
|
`${kind} "${declaration.name}" declared topics [${declared}] but no introspected queue subscriptions matched${hint}`
|
|
@@ -8210,8 +8292,10 @@ function queueTopicPatternsOverlap(left, right) {
|
|
|
8210
8292
|
}
|
|
8211
8293
|
return left.startsWith(rightPrefix);
|
|
8212
8294
|
}
|
|
8213
|
-
function createIntegrationInstallLines(integrations, { serving }) {
|
|
8214
|
-
return integrations.
|
|
8295
|
+
function createIntegrationInstallLines(integrations, { serving, beforeImport }) {
|
|
8296
|
+
return integrations.filter(
|
|
8297
|
+
(integration) => Boolean(integration.installBeforeImport) === beforeImport
|
|
8298
|
+
).flatMap(({ module: module2, installer, servingActivator }) => [
|
|
8215
8299
|
`from ${module2} import ${installer}`,
|
|
8216
8300
|
`${installer}()`,
|
|
8217
8301
|
// Queue-serving processes must also activate consumption (register
|
|
@@ -8225,8 +8309,15 @@ function createQueueHandlerModule(declaration, integrations) {
|
|
|
8225
8309
|
"import importlib",
|
|
8226
8310
|
"import vercel.queue",
|
|
8227
8311
|
"",
|
|
8312
|
+
...createIntegrationInstallLines(integrations, {
|
|
8313
|
+
serving: true,
|
|
8314
|
+
beforeImport: true
|
|
8315
|
+
}),
|
|
8228
8316
|
`importlib.import_module(${JSON.stringify(declaration.moduleName)})`,
|
|
8229
|
-
...createIntegrationInstallLines(integrations, {
|
|
8317
|
+
...createIntegrationInstallLines(integrations, {
|
|
8318
|
+
serving: true,
|
|
8319
|
+
beforeImport: false
|
|
8320
|
+
}),
|
|
8230
8321
|
"app = vercel.queue.asgi_app()",
|
|
8231
8322
|
""
|
|
8232
8323
|
].join("\n");
|
|
@@ -8358,8 +8449,15 @@ function parseTopicPatterns(name, value) {
|
|
|
8358
8449
|
function createQueueIntrospectionScript(moduleName, integrations) {
|
|
8359
8450
|
return [
|
|
8360
8451
|
"import importlib, json, sys",
|
|
8452
|
+
...createIntegrationInstallLines(integrations, {
|
|
8453
|
+
serving: false,
|
|
8454
|
+
beforeImport: true
|
|
8455
|
+
}),
|
|
8361
8456
|
`importlib.import_module(${JSON.stringify(moduleName)})`,
|
|
8362
|
-
...createIntegrationInstallLines(integrations, {
|
|
8457
|
+
...createIntegrationInstallLines(integrations, {
|
|
8458
|
+
serving: false,
|
|
8459
|
+
beforeImport: false
|
|
8460
|
+
}),
|
|
8363
8461
|
"from vercel.queue import get_subscriptions",
|
|
8364
8462
|
"subs = [",
|
|
8365
8463
|
" {k: v for k, v in {",
|
|
@@ -8407,7 +8505,7 @@ async function introspectQueueSubscriptions({
|
|
|
8407
8505
|
});
|
|
8408
8506
|
return parseIntrospectedSubscriptions(kind, declaration.name, stdout);
|
|
8409
8507
|
} catch (err) {
|
|
8410
|
-
if (err instanceof
|
|
8508
|
+
if (err instanceof import_build_utils14.NowBuildError) {
|
|
8411
8509
|
throw err;
|
|
8412
8510
|
}
|
|
8413
8511
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -8456,7 +8554,7 @@ async function introspectDevQueueSubscriptions({
|
|
|
8456
8554
|
};
|
|
8457
8555
|
});
|
|
8458
8556
|
} catch (err) {
|
|
8459
|
-
(0,
|
|
8557
|
+
(0, import_build_utils14.debug)(
|
|
8460
8558
|
`Failed to introspect dev queue subscriptions for module "${moduleName}": ${err instanceof Error ? err.message : String(err)}`
|
|
8461
8559
|
);
|
|
8462
8560
|
return void 0;
|
|
@@ -8523,7 +8621,7 @@ function getQueueWildcardPrefix(pattern) {
|
|
|
8523
8621
|
return void 0;
|
|
8524
8622
|
}
|
|
8525
8623
|
function subscriberError(message) {
|
|
8526
|
-
return new
|
|
8624
|
+
return new import_build_utils14.NowBuildError({
|
|
8527
8625
|
code: "PYTHON_INVALID_SUBSCRIBER_CONFIG",
|
|
8528
8626
|
message
|
|
8529
8627
|
});
|
|
@@ -8628,17 +8726,17 @@ async function syncDependencies({
|
|
|
8628
8726
|
let { manifestPath } = installInfo;
|
|
8629
8727
|
const manifest = pythonPackage.manifest;
|
|
8630
8728
|
if (!manifestType || !manifestPath) {
|
|
8631
|
-
(0,
|
|
8729
|
+
(0, import_build_utils15.debug)("No Python project manifest found, skipping dependency sync");
|
|
8632
8730
|
return;
|
|
8633
8731
|
}
|
|
8634
8732
|
if (manifest?.origin && manifestType === "pyproject.toml") {
|
|
8635
|
-
const syncDir = (0,
|
|
8636
|
-
(0,
|
|
8637
|
-
const tempPyproject = (0,
|
|
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");
|
|
8638
8736
|
const content = (0, import_python_analysis8.stringifyManifest)(manifest.data);
|
|
8639
|
-
(0,
|
|
8737
|
+
(0, import_fs13.writeFileSync)(tempPyproject, content, "utf8");
|
|
8640
8738
|
manifestPath = tempPyproject;
|
|
8641
|
-
(0,
|
|
8739
|
+
(0, import_build_utils15.debug)(
|
|
8642
8740
|
`Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
|
|
8643
8741
|
);
|
|
8644
8742
|
}
|
|
@@ -8671,7 +8769,7 @@ async function syncDependencies({
|
|
|
8671
8769
|
for (const [channel, chunk] of captured) {
|
|
8672
8770
|
(channel === "stdout" ? writeOut : writeErr)(chunk.toString());
|
|
8673
8771
|
}
|
|
8674
|
-
throw new
|
|
8772
|
+
throw new import_build_utils15.NowBuildError({
|
|
8675
8773
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
8676
8774
|
message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
|
|
8677
8775
|
});
|
|
@@ -8686,14 +8784,14 @@ async function runSync({
|
|
|
8686
8784
|
onStdout,
|
|
8687
8785
|
onStderr
|
|
8688
8786
|
}) {
|
|
8689
|
-
const projectDir = (0,
|
|
8787
|
+
const projectDir = (0, import_path13.dirname)(manifestPath);
|
|
8690
8788
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
8691
8789
|
let spawnCmd;
|
|
8692
8790
|
let spawnArgs;
|
|
8693
8791
|
switch (manifestType) {
|
|
8694
8792
|
case "uv.lock": {
|
|
8695
8793
|
if (!uvPath) {
|
|
8696
|
-
throw new
|
|
8794
|
+
throw new import_build_utils15.NowBuildError({
|
|
8697
8795
|
code: "PYTHON_DEPENDENCY_SYNC_FAILED",
|
|
8698
8796
|
message: "uv is required to install dependencies from uv.lock.",
|
|
8699
8797
|
link: "https://docs.astral.sh/uv/getting-started/installation/",
|
|
@@ -8715,11 +8813,11 @@ async function runSync({
|
|
|
8715
8813
|
break;
|
|
8716
8814
|
}
|
|
8717
8815
|
default:
|
|
8718
|
-
(0,
|
|
8816
|
+
(0, import_build_utils15.debug)(`Unknown manifest type: ${manifestType}`);
|
|
8719
8817
|
return;
|
|
8720
8818
|
}
|
|
8721
8819
|
await new Promise((resolve4, reject) => {
|
|
8722
|
-
(0,
|
|
8820
|
+
(0, import_build_utils15.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
|
|
8723
8821
|
const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
|
|
8724
8822
|
cwd: projectDir,
|
|
8725
8823
|
env: getProtectedUvEnv(env),
|
|
@@ -8758,7 +8856,7 @@ var COMPLETED_INSTALLS = /* @__PURE__ */ new Set();
|
|
|
8758
8856
|
function hasInstalledDistribution(targetDir, packageName) {
|
|
8759
8857
|
const prefix = `${packageName.replace("-", "_")}-`;
|
|
8760
8858
|
try {
|
|
8761
|
-
return (0,
|
|
8859
|
+
return (0, import_fs13.readdirSync)(targetDir).some(
|
|
8762
8860
|
(entry) => entry.startsWith(prefix) && entry.endsWith(".dist-info")
|
|
8763
8861
|
);
|
|
8764
8862
|
} catch {
|
|
@@ -8766,7 +8864,7 @@ function hasInstalledDistribution(targetDir, packageName) {
|
|
|
8766
8864
|
}
|
|
8767
8865
|
}
|
|
8768
8866
|
async function installInjectedDevPackage(pkg, opts) {
|
|
8769
|
-
const targetDir = (0,
|
|
8867
|
+
const targetDir = (0, import_path13.join)(opts.workPath, ".vercel", "python");
|
|
8770
8868
|
const source = pkg.envOverride || pkg.pinnedVersion || pkg.requirement;
|
|
8771
8869
|
const key = `${targetDir}:${pkg.name}:${source}`;
|
|
8772
8870
|
if (COMPLETED_INSTALLS.has(key) && hasInstalledDistribution(targetDir, pkg.name)) {
|
|
@@ -8780,23 +8878,23 @@ async function installInjectedDevPackage(pkg, opts) {
|
|
|
8780
8878
|
}
|
|
8781
8879
|
async function doInstallInjectedDevPackage(pkg, opts) {
|
|
8782
8880
|
const { targetDir, workPath, uvPath, pythonBin, env, onStdout, onStderr } = opts;
|
|
8783
|
-
(0,
|
|
8784
|
-
const localDir = (0,
|
|
8785
|
-
const isLocalDev = (0,
|
|
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"));
|
|
8786
8884
|
const requirement = pkg.pinnedVersion ? `${pkg.name}==${pkg.pinnedVersion}` : pkg.requirement ?? pkg.name;
|
|
8787
8885
|
const dep = pkg.envOverride || (isLocalDev ? localDir : requirement);
|
|
8788
8886
|
if (!isLocalDev && !pkg.envOverride && pkg.pinnedVersion) {
|
|
8789
8887
|
const distInfoName = pkg.name.replace("-", "_");
|
|
8790
|
-
const distInfo = (0,
|
|
8888
|
+
const distInfo = (0, import_path13.join)(
|
|
8791
8889
|
targetDir,
|
|
8792
8890
|
`${distInfoName}-${pkg.pinnedVersion}.dist-info`
|
|
8793
8891
|
);
|
|
8794
|
-
if ((0,
|
|
8795
|
-
(0,
|
|
8892
|
+
if ((0, import_fs13.existsSync)(distInfo)) {
|
|
8893
|
+
(0, import_build_utils15.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
|
|
8796
8894
|
return;
|
|
8797
8895
|
}
|
|
8798
8896
|
}
|
|
8799
|
-
(0,
|
|
8897
|
+
(0, import_build_utils15.debug)(
|
|
8800
8898
|
`Installing ${pkg.name} into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${dep})`
|
|
8801
8899
|
);
|
|
8802
8900
|
const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
|
|
@@ -8818,14 +8916,14 @@ async function doInstallInjectedDevPackage(pkg, opts) {
|
|
|
8818
8916
|
if (onStdout) {
|
|
8819
8917
|
onStdout(data);
|
|
8820
8918
|
} else {
|
|
8821
|
-
(0,
|
|
8919
|
+
(0, import_build_utils15.debug)(data.toString());
|
|
8822
8920
|
}
|
|
8823
8921
|
});
|
|
8824
8922
|
child.stderr?.on("data", (data) => {
|
|
8825
8923
|
if (onStderr) {
|
|
8826
8924
|
onStderr(data);
|
|
8827
8925
|
} else {
|
|
8828
|
-
(0,
|
|
8926
|
+
(0, import_build_utils15.debug)(data.toString());
|
|
8829
8927
|
}
|
|
8830
8928
|
});
|
|
8831
8929
|
child.on("error", reject);
|
|
@@ -8855,12 +8953,12 @@ function installGlobalCleanupHandlers() {
|
|
|
8855
8953
|
try {
|
|
8856
8954
|
process.kill(info.pid, "SIGTERM");
|
|
8857
8955
|
} catch (err) {
|
|
8858
|
-
(0,
|
|
8956
|
+
(0, import_build_utils15.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
|
|
8859
8957
|
}
|
|
8860
8958
|
try {
|
|
8861
8959
|
process.kill(info.pid, "SIGKILL");
|
|
8862
8960
|
} catch (err) {
|
|
8863
|
-
(0,
|
|
8961
|
+
(0, import_build_utils15.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
|
|
8864
8962
|
}
|
|
8865
8963
|
PERSISTENT_SERVERS.delete(key);
|
|
8866
8964
|
}
|
|
@@ -8868,7 +8966,7 @@ function installGlobalCleanupHandlers() {
|
|
|
8868
8966
|
try {
|
|
8869
8967
|
restoreWarnings();
|
|
8870
8968
|
} catch (err) {
|
|
8871
|
-
(0,
|
|
8969
|
+
(0, import_build_utils15.debug)(`Error restoring warnings: ${err}`);
|
|
8872
8970
|
}
|
|
8873
8971
|
restoreWarnings = null;
|
|
8874
8972
|
}
|
|
@@ -8885,46 +8983,46 @@ function installGlobalCleanupHandlers() {
|
|
|
8885
8983
|
}
|
|
8886
8984
|
function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
|
|
8887
8985
|
try {
|
|
8888
|
-
const vercelPythonDir = serviceName ? (0,
|
|
8889
|
-
(0,
|
|
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 });
|
|
8890
8988
|
let qualifiedModule = modulePath;
|
|
8891
8989
|
let extraPythonPath;
|
|
8892
|
-
if ((0,
|
|
8893
|
-
const pkgName = (0,
|
|
8990
|
+
if ((0, import_fs13.existsSync)((0, import_path13.join)(workPath, "__init__.py"))) {
|
|
8991
|
+
const pkgName = (0, import_path13.basename)(workPath);
|
|
8894
8992
|
qualifiedModule = `${pkgName}.${modulePath}`;
|
|
8895
|
-
extraPythonPath = (0,
|
|
8993
|
+
extraPythonPath = (0, import_path13.dirname)(workPath);
|
|
8896
8994
|
}
|
|
8897
|
-
const entryAbs = (0,
|
|
8898
|
-
const shimPath = (0,
|
|
8899
|
-
const templatePath = (0,
|
|
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)(
|
|
8900
8998
|
__dirname,
|
|
8901
8999
|
"..",
|
|
8902
9000
|
"templates",
|
|
8903
9001
|
`${DEV_SHIM_MODULE}.py`
|
|
8904
9002
|
);
|
|
8905
|
-
const template = (0,
|
|
9003
|
+
const template = (0, import_fs13.readFileSync)(templatePath, "utf8");
|
|
8906
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);
|
|
8907
|
-
(0,
|
|
8908
|
-
(0,
|
|
9005
|
+
(0, import_fs13.writeFileSync)(shimPath, shimSource, "utf8");
|
|
9006
|
+
(0, import_build_utils15.debug)(`Prepared Python dev shim at ${shimPath}`);
|
|
8909
9007
|
return {
|
|
8910
9008
|
module: DEV_SHIM_MODULE,
|
|
8911
9009
|
extraPythonPath,
|
|
8912
9010
|
shimDir: vercelPythonDir
|
|
8913
9011
|
};
|
|
8914
9012
|
} catch (err) {
|
|
8915
|
-
(0,
|
|
9013
|
+
(0, import_build_utils15.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
|
|
8916
9014
|
return null;
|
|
8917
9015
|
}
|
|
8918
9016
|
}
|
|
8919
9017
|
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
8920
|
-
const venvPath = (0,
|
|
9018
|
+
const venvPath = (0, import_path13.join)(workPath, ".venv");
|
|
8921
9019
|
const pendingCreation = PENDING_MANAGED_VENV_CREATIONS.get(venvPath);
|
|
8922
9020
|
if (pendingCreation) {
|
|
8923
9021
|
await pendingCreation;
|
|
8924
9022
|
}
|
|
8925
9023
|
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
8926
9024
|
if (venvRoot) {
|
|
8927
|
-
(0,
|
|
9025
|
+
(0, import_build_utils15.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
8928
9026
|
return { command: pythonCmd, args: [] };
|
|
8929
9027
|
}
|
|
8930
9028
|
await dedupePendingOperation(
|
|
@@ -8937,11 +9035,11 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
|
|
|
8937
9035
|
quiet: true
|
|
8938
9036
|
})
|
|
8939
9037
|
);
|
|
8940
|
-
(0,
|
|
9038
|
+
(0, import_build_utils15.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
8941
9039
|
const pythonBin = getVenvPythonBin(venvPath);
|
|
8942
9040
|
const binDir = getVenvBinDir(venvPath);
|
|
8943
9041
|
env.VIRTUAL_ENV = venvPath;
|
|
8944
|
-
env.PATH = `${binDir}${
|
|
9042
|
+
env.PATH = `${binDir}${import_path13.delimiter}${env.PATH || ""}`;
|
|
8945
9043
|
return { command: pythonBin, args: [] };
|
|
8946
9044
|
}
|
|
8947
9045
|
var startDevServer = async (opts) => {
|
|
@@ -9004,7 +9102,7 @@ var startDevServer = async (opts) => {
|
|
|
9004
9102
|
filePath: entrypoint,
|
|
9005
9103
|
// Schedule-triggered services create their own "app" wrapper dynamically.
|
|
9006
9104
|
// Other services use handlerFunction as the entrypoint variable name.
|
|
9007
|
-
varName: service && (0,
|
|
9105
|
+
varName: service && (0, import_build_utils15.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
|
|
9008
9106
|
} : void 0,
|
|
9009
9107
|
service,
|
|
9010
9108
|
opts.repoRootPath
|
|
@@ -9026,7 +9124,7 @@ var startDevServer = async (opts) => {
|
|
|
9026
9124
|
if (detected?.error) {
|
|
9027
9125
|
throw detected.error;
|
|
9028
9126
|
}
|
|
9029
|
-
throw new
|
|
9127
|
+
throw new import_build_utils15.NowBuildError({
|
|
9030
9128
|
code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
|
|
9031
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."
|
|
9032
9130
|
});
|
|
@@ -9058,7 +9156,7 @@ var startDevServer = async (opts) => {
|
|
|
9058
9156
|
const yellow = "\x1B[33m";
|
|
9059
9157
|
const white = "\x1B[1m";
|
|
9060
9158
|
const reset = "\x1B[0m";
|
|
9061
|
-
throw new
|
|
9159
|
+
throw new import_build_utils15.NowBuildError({
|
|
9062
9160
|
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
9063
9161
|
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
9064
9162
|
Run ${white}deactivate${reset} and try again.`
|
|
@@ -9075,11 +9173,11 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
9075
9173
|
);
|
|
9076
9174
|
spawnCommand = runner.command;
|
|
9077
9175
|
spawnArgsPrefix = runner.args;
|
|
9078
|
-
(0,
|
|
9176
|
+
(0, import_build_utils15.debug)(
|
|
9079
9177
|
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
9080
9178
|
);
|
|
9081
9179
|
} else if (venv) {
|
|
9082
|
-
(0,
|
|
9180
|
+
(0, import_build_utils15.debug)(`Running in virtualenv at ${venv}`);
|
|
9083
9181
|
} else {
|
|
9084
9182
|
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
9085
9183
|
workPath,
|
|
@@ -9088,9 +9186,9 @@ Run ${white}deactivate${reset} and try again.`
|
|
|
9088
9186
|
);
|
|
9089
9187
|
spawnCommand = venvPythonCmd;
|
|
9090
9188
|
if (venvRoot) {
|
|
9091
|
-
(0,
|
|
9189
|
+
(0, import_build_utils15.debug)(`Using virtualenv at ${venvRoot}`);
|
|
9092
9190
|
} else {
|
|
9093
|
-
(0,
|
|
9191
|
+
(0, import_build_utils15.debug)("No virtualenv found");
|
|
9094
9192
|
try {
|
|
9095
9193
|
const yellow = "\x1B[33m";
|
|
9096
9194
|
const reset = "\x1B[0m";
|
|
@@ -9166,7 +9264,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9166
9264
|
);
|
|
9167
9265
|
}
|
|
9168
9266
|
} catch (err) {
|
|
9169
|
-
(0,
|
|
9267
|
+
(0, import_build_utils15.debug)(
|
|
9170
9268
|
`Skipping conditional dev package injection: ${err instanceof Error ? err.message : String(err)}`
|
|
9171
9269
|
);
|
|
9172
9270
|
}
|
|
@@ -9180,7 +9278,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9180
9278
|
devOpts
|
|
9181
9279
|
);
|
|
9182
9280
|
}
|
|
9183
|
-
const queueSidecarKind = config?.pythonQueueSidecar === "subscriber" || config?.pythonQueueSidecar === "workflow" ? config.pythonQueueSidecar : service && (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;
|
|
9184
9282
|
let queueSubscriptions;
|
|
9185
9283
|
if (queueSidecarKind) {
|
|
9186
9284
|
let useQueueServing = !legacyProject;
|
|
@@ -9194,14 +9292,14 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9194
9292
|
}
|
|
9195
9293
|
if (useQueueServing) {
|
|
9196
9294
|
env.VERCEL_DEV_QUEUE_SERVING = "1";
|
|
9197
|
-
const runtimeDir = (0,
|
|
9295
|
+
const runtimeDir = (0, import_path13.join)(workPath, ".vercel", "python");
|
|
9198
9296
|
queueSubscriptions = await introspectDevQueueSubscriptions({
|
|
9199
9297
|
moduleName: modulePath,
|
|
9200
9298
|
pythonBin: spawnCommand,
|
|
9201
9299
|
cwd: workPath,
|
|
9202
9300
|
env: {
|
|
9203
9301
|
...env,
|
|
9204
|
-
PYTHONPATH: [runtimeDir, env.PYTHONPATH].filter(Boolean).join(
|
|
9302
|
+
PYTHONPATH: [runtimeDir, env.PYTHONPATH].filter(Boolean).join(import_path13.delimiter)
|
|
9205
9303
|
},
|
|
9206
9304
|
integrations: queueIntegrations
|
|
9207
9305
|
});
|
|
@@ -9232,7 +9330,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9232
9330
|
const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
|
|
9233
9331
|
env.PORT = `${port}`;
|
|
9234
9332
|
if (entry) {
|
|
9235
|
-
env.__VC_HANDLER_ENTRYPOINT_ABS = (0,
|
|
9333
|
+
env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path13.join)(workPath, entry);
|
|
9236
9334
|
}
|
|
9237
9335
|
const devShim = createDevShim(
|
|
9238
9336
|
workPath,
|
|
@@ -9243,8 +9341,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9243
9341
|
variableName ?? ""
|
|
9244
9342
|
);
|
|
9245
9343
|
if (devShim) {
|
|
9246
|
-
const shimDir = devShim.shimDir || (0,
|
|
9247
|
-
const runtimeDir = (0,
|
|
9344
|
+
const shimDir = devShim.shimDir || (0, import_path13.join)(workPath, ".vercel", "python");
|
|
9345
|
+
const runtimeDir = (0, import_path13.join)(workPath, ".vercel", "python");
|
|
9248
9346
|
const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
|
|
9249
9347
|
if (devShim.extraPythonPath) {
|
|
9250
9348
|
pathParts.push(devShim.extraPythonPath);
|
|
@@ -9256,12 +9354,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9256
9354
|
if (existingPythonPath) {
|
|
9257
9355
|
pathParts.push(existingPythonPath);
|
|
9258
9356
|
}
|
|
9259
|
-
env.PYTHONPATH = pathParts.join(
|
|
9357
|
+
env.PYTHONPATH = pathParts.join(import_path13.delimiter);
|
|
9260
9358
|
}
|
|
9261
9359
|
const moduleToRun = devShim?.module || modulePath;
|
|
9262
9360
|
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
9263
9361
|
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
9264
|
-
(0,
|
|
9362
|
+
(0, import_build_utils15.debug)(
|
|
9265
9363
|
`Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
|
|
9266
9364
|
);
|
|
9267
9365
|
if (process.stdout.columns) {
|
|
@@ -9315,7 +9413,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
9315
9413
|
};
|
|
9316
9414
|
|
|
9317
9415
|
// src/quirks/index.ts
|
|
9318
|
-
var
|
|
9416
|
+
var import_build_utils18 = require("@vercel/build-utils");
|
|
9319
9417
|
var import_python_analysis10 = require("@vercel/python-analysis");
|
|
9320
9418
|
|
|
9321
9419
|
// src/quirks/matplotlib.ts
|
|
@@ -9329,9 +9427,9 @@ var matplotlibQuirk = {
|
|
|
9329
9427
|
};
|
|
9330
9428
|
|
|
9331
9429
|
// src/quirks/litellm.ts
|
|
9332
|
-
var
|
|
9333
|
-
var
|
|
9334
|
-
var
|
|
9430
|
+
var import_fs14 = __toESM(require("fs"));
|
|
9431
|
+
var import_path14 = require("path");
|
|
9432
|
+
var import_build_utils16 = require("@vercel/build-utils");
|
|
9335
9433
|
var LAMBDA_ROOT = "/var/task";
|
|
9336
9434
|
var CONFIG_CANDIDATES = [
|
|
9337
9435
|
"litellm_config.yaml",
|
|
@@ -9341,9 +9439,9 @@ var CONFIG_CANDIDATES = [
|
|
|
9341
9439
|
];
|
|
9342
9440
|
async function findConfigFile(workPath) {
|
|
9343
9441
|
for (const name of CONFIG_CANDIDATES) {
|
|
9344
|
-
const candidate = (0,
|
|
9442
|
+
const candidate = (0, import_path14.join)(workPath, name);
|
|
9345
9443
|
try {
|
|
9346
|
-
await
|
|
9444
|
+
await import_fs14.default.promises.access(candidate);
|
|
9347
9445
|
return name;
|
|
9348
9446
|
} catch {
|
|
9349
9447
|
}
|
|
@@ -9358,32 +9456,32 @@ var litellmQuirk = {
|
|
|
9358
9456
|
const env = {};
|
|
9359
9457
|
const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
|
|
9360
9458
|
for (const sitePackages of sitePackagesDirs) {
|
|
9361
|
-
const schemaPath = (0,
|
|
9459
|
+
const schemaPath = (0, import_path14.join)(
|
|
9362
9460
|
sitePackages,
|
|
9363
9461
|
"litellm",
|
|
9364
9462
|
"proxy",
|
|
9365
9463
|
"schema.prisma"
|
|
9366
9464
|
);
|
|
9367
9465
|
try {
|
|
9368
|
-
await
|
|
9369
|
-
(0,
|
|
9466
|
+
await import_fs14.default.promises.access(schemaPath);
|
|
9467
|
+
(0, import_build_utils16.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
|
|
9370
9468
|
buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
|
|
9371
9469
|
break;
|
|
9372
9470
|
} catch {
|
|
9373
9471
|
}
|
|
9374
9472
|
}
|
|
9375
9473
|
if (!buildEnv.PRISMA_SCHEMA_PATH) {
|
|
9376
|
-
(0,
|
|
9474
|
+
(0, import_build_utils16.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
|
|
9377
9475
|
}
|
|
9378
9476
|
if (!process.env.CONFIG_FILE_PATH) {
|
|
9379
9477
|
const configName = await findConfigFile(ctx.workPath);
|
|
9380
9478
|
if (configName) {
|
|
9381
|
-
(0,
|
|
9382
|
-
buildEnv.CONFIG_FILE_PATH = (0,
|
|
9383
|
-
env.CONFIG_FILE_PATH = (0,
|
|
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);
|
|
9384
9482
|
}
|
|
9385
9483
|
} else {
|
|
9386
|
-
(0,
|
|
9484
|
+
(0, import_build_utils16.debug)(
|
|
9387
9485
|
`LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
|
|
9388
9486
|
);
|
|
9389
9487
|
}
|
|
@@ -9392,10 +9490,10 @@ var litellmQuirk = {
|
|
|
9392
9490
|
};
|
|
9393
9491
|
|
|
9394
9492
|
// src/quirks/prisma.ts
|
|
9395
|
-
var
|
|
9396
|
-
var
|
|
9493
|
+
var import_fs15 = __toESM(require("fs"));
|
|
9494
|
+
var import_path15 = require("path");
|
|
9397
9495
|
var import_execa7 = __toESM(require_execa());
|
|
9398
|
-
var
|
|
9496
|
+
var import_build_utils17 = require("@vercel/build-utils");
|
|
9399
9497
|
var import_python_analysis9 = require("@vercel/python-analysis");
|
|
9400
9498
|
function execErrorMessage(err) {
|
|
9401
9499
|
if (err != null && typeof err === "object" && "stderr" in err) {
|
|
@@ -9433,22 +9531,22 @@ model DummyModel {
|
|
|
9433
9531
|
async function findUserSchema(workPath) {
|
|
9434
9532
|
const envPath = process.env.PRISMA_SCHEMA_PATH;
|
|
9435
9533
|
if (envPath) {
|
|
9436
|
-
const resolved = (0,
|
|
9534
|
+
const resolved = (0, import_path15.isAbsolute)(envPath) ? envPath : (0, import_path15.join)(workPath, envPath);
|
|
9437
9535
|
try {
|
|
9438
|
-
await
|
|
9536
|
+
await import_fs15.default.promises.access(resolved);
|
|
9439
9537
|
return resolved;
|
|
9440
9538
|
} catch {
|
|
9441
|
-
(0,
|
|
9539
|
+
(0, import_build_utils17.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
|
|
9442
9540
|
return null;
|
|
9443
9541
|
}
|
|
9444
9542
|
}
|
|
9445
9543
|
const candidates = [
|
|
9446
|
-
(0,
|
|
9447
|
-
(0,
|
|
9544
|
+
(0, import_path15.join)(workPath, "schema.prisma"),
|
|
9545
|
+
(0, import_path15.join)(workPath, "prisma", "schema.prisma")
|
|
9448
9546
|
];
|
|
9449
9547
|
for (const candidate of candidates) {
|
|
9450
9548
|
try {
|
|
9451
|
-
await
|
|
9549
|
+
await import_fs15.default.promises.access(candidate);
|
|
9452
9550
|
return candidate;
|
|
9453
9551
|
} catch {
|
|
9454
9552
|
}
|
|
@@ -9459,32 +9557,32 @@ async function collectFiles(dir, base) {
|
|
|
9459
9557
|
const result = [];
|
|
9460
9558
|
let entries;
|
|
9461
9559
|
try {
|
|
9462
|
-
entries = await
|
|
9560
|
+
entries = await import_fs15.default.promises.readdir(dir, { withFileTypes: true });
|
|
9463
9561
|
} catch {
|
|
9464
9562
|
return result;
|
|
9465
9563
|
}
|
|
9466
9564
|
for (const entry of entries) {
|
|
9467
9565
|
if (entry.name === "__pycache__")
|
|
9468
9566
|
continue;
|
|
9469
|
-
const full = (0,
|
|
9567
|
+
const full = (0, import_path15.join)(dir, entry.name);
|
|
9470
9568
|
if (entry.isDirectory()) {
|
|
9471
9569
|
result.push(...await collectFiles(full, base));
|
|
9472
9570
|
} else {
|
|
9473
|
-
result.push((0,
|
|
9571
|
+
result.push((0, import_path15.relative)(base, full));
|
|
9474
9572
|
}
|
|
9475
9573
|
}
|
|
9476
9574
|
return result;
|
|
9477
9575
|
}
|
|
9478
9576
|
async function cleanCacheArtifacts(cacheDir, extras = []) {
|
|
9479
9577
|
const paths = [
|
|
9480
|
-
(0,
|
|
9481
|
-
(0,
|
|
9482
|
-
(0,
|
|
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"),
|
|
9483
9581
|
...extras
|
|
9484
9582
|
];
|
|
9485
9583
|
for (const p of paths) {
|
|
9486
9584
|
try {
|
|
9487
|
-
await
|
|
9585
|
+
await import_fs15.default.promises.rm(p, { recursive: true, force: true });
|
|
9488
9586
|
} catch (err) {
|
|
9489
9587
|
console.warn(
|
|
9490
9588
|
`could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -9508,7 +9606,7 @@ var prismaQuirk = {
|
|
|
9508
9606
|
async run(ctx) {
|
|
9509
9607
|
const { venvPath, pythonEnv, workPath } = ctx;
|
|
9510
9608
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
9511
|
-
const runtimeCacheDir = (0,
|
|
9609
|
+
const runtimeCacheDir = (0, import_path15.join)(
|
|
9512
9610
|
LAMBDA_ROOT2,
|
|
9513
9611
|
resolveVendorDir(),
|
|
9514
9612
|
"prisma",
|
|
@@ -9518,7 +9616,7 @@ var prismaQuirk = {
|
|
|
9518
9616
|
let sitePackages;
|
|
9519
9617
|
for (const dir of sitePackagesDirs) {
|
|
9520
9618
|
try {
|
|
9521
|
-
await
|
|
9619
|
+
await import_fs15.default.promises.access((0, import_path15.join)(dir, "prisma"));
|
|
9522
9620
|
sitePackages = dir;
|
|
9523
9621
|
break;
|
|
9524
9622
|
} catch {
|
|
@@ -9530,19 +9628,19 @@ var prismaQuirk = {
|
|
|
9530
9628
|
);
|
|
9531
9629
|
return {};
|
|
9532
9630
|
}
|
|
9533
|
-
const cacheDir = (0,
|
|
9534
|
-
await
|
|
9631
|
+
const cacheDir = (0, import_path15.join)(sitePackages, "prisma", "__bincache__");
|
|
9632
|
+
await import_fs15.default.promises.mkdir(cacheDir, { recursive: true });
|
|
9535
9633
|
const generateEnv = {
|
|
9536
9634
|
...pythonEnv,
|
|
9537
9635
|
PRISMA_BINARY_CACHE_DIR: cacheDir
|
|
9538
9636
|
};
|
|
9539
|
-
const generatedDir = (0,
|
|
9540
|
-
const dummySchemaPath = (0,
|
|
9541
|
-
await
|
|
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(
|
|
9542
9640
|
dummySchemaPath,
|
|
9543
9641
|
buildDummySchema(generatedDir)
|
|
9544
9642
|
);
|
|
9545
|
-
(0,
|
|
9643
|
+
(0, import_build_utils17.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
|
|
9546
9644
|
try {
|
|
9547
9645
|
const dummyResult = await (0, import_execa7.default)(
|
|
9548
9646
|
pythonPath,
|
|
@@ -9554,11 +9652,11 @@ var prismaQuirk = {
|
|
|
9554
9652
|
}
|
|
9555
9653
|
);
|
|
9556
9654
|
if (dummyResult.stdout)
|
|
9557
|
-
(0,
|
|
9655
|
+
(0, import_build_utils17.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
|
|
9558
9656
|
if (dummyResult.stderr)
|
|
9559
|
-
(0,
|
|
9657
|
+
(0, import_build_utils17.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
|
|
9560
9658
|
} catch (err) {
|
|
9561
|
-
throw new
|
|
9659
|
+
throw new import_build_utils17.NowBuildError({
|
|
9562
9660
|
code: "PRISMA_GENERATE_FAILED",
|
|
9563
9661
|
message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
|
|
9564
9662
|
` + execErrorMessage(err)
|
|
@@ -9566,47 +9664,47 @@ var prismaQuirk = {
|
|
|
9566
9664
|
}
|
|
9567
9665
|
const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
|
|
9568
9666
|
const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
|
|
9569
|
-
const nodeModulesDir = (0,
|
|
9667
|
+
const nodeModulesDir = (0, import_path15.join)(cacheDir, "node_modules", "prisma");
|
|
9570
9668
|
let engineCopied = false;
|
|
9571
9669
|
try {
|
|
9572
|
-
const entries = await
|
|
9670
|
+
const entries = await import_fs15.default.promises.readdir(nodeModulesDir);
|
|
9573
9671
|
for (const entry of entries) {
|
|
9574
9672
|
if (!entry.startsWith(srcBinaryPrefix))
|
|
9575
9673
|
continue;
|
|
9576
|
-
const srcPath = (0,
|
|
9577
|
-
const destPath = (0,
|
|
9674
|
+
const srcPath = (0, import_path15.join)(nodeModulesDir, entry);
|
|
9675
|
+
const destPath = (0, import_path15.join)(cacheDir, runtimeName);
|
|
9578
9676
|
try {
|
|
9579
|
-
await
|
|
9580
|
-
(0,
|
|
9677
|
+
await import_fs15.default.promises.access(destPath);
|
|
9678
|
+
(0, import_build_utils17.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
|
|
9581
9679
|
} catch {
|
|
9582
|
-
(0,
|
|
9583
|
-
await
|
|
9680
|
+
(0, import_build_utils17.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
|
|
9681
|
+
await import_fs15.default.promises.copyFile(srcPath, destPath);
|
|
9584
9682
|
}
|
|
9585
9683
|
engineCopied = true;
|
|
9586
9684
|
}
|
|
9587
9685
|
} catch (err) {
|
|
9588
|
-
throw new
|
|
9686
|
+
throw new import_build_utils17.NowBuildError({
|
|
9589
9687
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
9590
9688
|
message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
|
|
9591
9689
|
` + (err instanceof Error ? err.message : String(err))
|
|
9592
9690
|
});
|
|
9593
9691
|
}
|
|
9594
9692
|
if (!engineCopied) {
|
|
9595
|
-
throw new
|
|
9693
|
+
throw new import_build_utils17.NowBuildError({
|
|
9596
9694
|
code: "PRISMA_ENGINE_NOT_FOUND",
|
|
9597
9695
|
message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
|
|
9598
9696
|
});
|
|
9599
9697
|
}
|
|
9600
|
-
const shimPath = (0,
|
|
9601
|
-
await
|
|
9698
|
+
const shimPath = (0, import_path15.join)(cacheDir, "openssl");
|
|
9699
|
+
await import_fs15.default.promises.writeFile(
|
|
9602
9700
|
shimPath,
|
|
9603
9701
|
`#!/bin/sh
|
|
9604
9702
|
echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
|
|
9605
9703
|
`
|
|
9606
9704
|
);
|
|
9607
|
-
await
|
|
9705
|
+
await import_fs15.default.promises.chmod(shimPath, 493);
|
|
9608
9706
|
for (const p of [generatedDir, dummySchemaPath]) {
|
|
9609
|
-
await
|
|
9707
|
+
await import_fs15.default.promises.rm(p, { recursive: true, force: true });
|
|
9610
9708
|
}
|
|
9611
9709
|
await cleanCacheArtifacts(cacheDir);
|
|
9612
9710
|
const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
|
|
@@ -9619,14 +9717,14 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
9619
9717
|
pythonEnv
|
|
9620
9718
|
);
|
|
9621
9719
|
if (clientAlreadyGenerated) {
|
|
9622
|
-
(0,
|
|
9720
|
+
(0, import_build_utils17.debug)(
|
|
9623
9721
|
"Prisma quirk: client already generated, skipping user schema generate"
|
|
9624
9722
|
);
|
|
9625
9723
|
shouldGenerate = false;
|
|
9626
9724
|
}
|
|
9627
9725
|
}
|
|
9628
9726
|
if (shouldGenerate) {
|
|
9629
|
-
(0,
|
|
9727
|
+
(0, import_build_utils17.debug)(`Running prisma generate with user schema: ${userSchema}`);
|
|
9630
9728
|
try {
|
|
9631
9729
|
const userResult = await (0, import_execa7.default)(
|
|
9632
9730
|
pythonPath,
|
|
@@ -9638,11 +9736,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
9638
9736
|
}
|
|
9639
9737
|
);
|
|
9640
9738
|
if (userResult.stdout)
|
|
9641
|
-
(0,
|
|
9739
|
+
(0, import_build_utils17.debug)(`prisma generate stdout: ${userResult.stdout}`);
|
|
9642
9740
|
if (userResult.stderr)
|
|
9643
|
-
(0,
|
|
9741
|
+
(0, import_build_utils17.debug)(`prisma generate stderr: ${userResult.stderr}`);
|
|
9644
9742
|
} catch (err) {
|
|
9645
|
-
throw new
|
|
9743
|
+
throw new import_build_utils17.NowBuildError({
|
|
9646
9744
|
code: "PRISMA_GENERATE_FAILED",
|
|
9647
9745
|
message: `\`prisma generate\` failed for schema "${userSchema}".
|
|
9648
9746
|
` + execErrorMessage(err)
|
|
@@ -9653,12 +9751,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
|
|
|
9653
9751
|
}
|
|
9654
9752
|
try {
|
|
9655
9753
|
const allFiles = await collectFiles(
|
|
9656
|
-
(0,
|
|
9754
|
+
(0, import_path15.join)(sitePackages, "prisma"),
|
|
9657
9755
|
sitePackages
|
|
9658
9756
|
);
|
|
9659
9757
|
const count = await (0, import_python_analysis9.extendDistRecord)(sitePackages, "prisma", allFiles);
|
|
9660
9758
|
if (count > 0) {
|
|
9661
|
-
(0,
|
|
9759
|
+
(0, import_build_utils17.debug)(`Appended ${count} entries to prisma RECORD`);
|
|
9662
9760
|
}
|
|
9663
9761
|
} catch (err) {
|
|
9664
9762
|
console.warn(
|
|
@@ -9752,13 +9850,13 @@ async function runQuirks(ctx) {
|
|
|
9752
9850
|
(0, import_python_analysis10.normalizePackageName)(quirk.dependency)
|
|
9753
9851
|
);
|
|
9754
9852
|
if (!installed) {
|
|
9755
|
-
(0,
|
|
9853
|
+
(0, import_build_utils18.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
|
|
9756
9854
|
}
|
|
9757
9855
|
return installed;
|
|
9758
9856
|
});
|
|
9759
9857
|
const sorted = toposortQuirks(activated);
|
|
9760
9858
|
for (const quirk of sorted) {
|
|
9761
|
-
(0,
|
|
9859
|
+
(0, import_build_utils18.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
|
|
9762
9860
|
const result = await quirk.run(ctx);
|
|
9763
9861
|
if (result.env) {
|
|
9764
9862
|
Object.assign(mergedEnv, result.env);
|
|
@@ -9779,12 +9877,12 @@ async function runQuirks(ctx) {
|
|
|
9779
9877
|
}
|
|
9780
9878
|
|
|
9781
9879
|
// src/django.ts
|
|
9782
|
-
var
|
|
9783
|
-
var
|
|
9880
|
+
var import_fs16 = __toESM(require("fs"));
|
|
9881
|
+
var import_path16 = require("path");
|
|
9784
9882
|
var import_execa8 = __toESM(require_execa());
|
|
9785
|
-
var
|
|
9786
|
-
var scriptPath2 = (0,
|
|
9787
|
-
var script2 =
|
|
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");
|
|
9788
9886
|
async function getDjangoSettings(projectDir, env) {
|
|
9789
9887
|
const { stdout } = await (0, import_execa8.default)("python", ["-c", script2], {
|
|
9790
9888
|
env,
|
|
@@ -9812,10 +9910,10 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9812
9910
|
const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
|
|
9813
9911
|
const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
|
|
9814
9912
|
const staticSourceDirs = [
|
|
9815
|
-
...installedApps.map((app) => (0,
|
|
9913
|
+
...installedApps.map((app) => (0, import_path16.join)(djangoPath, ...app.split("."), "static")),
|
|
9816
9914
|
// TODO: Deal with optional prefixes in STATICFILES_DIRS.
|
|
9817
9915
|
...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
|
|
9818
|
-
].filter((d) =>
|
|
9916
|
+
].filter((d) => import_fs16.default.existsSync(d));
|
|
9819
9917
|
if (storageBackend.startsWith("storages.backends.")) {
|
|
9820
9918
|
console.log(
|
|
9821
9919
|
"django-storages detected \u2014 running collectstatic with original settings"
|
|
@@ -9826,7 +9924,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9826
9924
|
});
|
|
9827
9925
|
return {
|
|
9828
9926
|
staticSourceDirs,
|
|
9829
|
-
staticRoot: staticRoot ? (0,
|
|
9927
|
+
staticRoot: staticRoot ? (0, import_path16.resolve)(djangoPath, staticRoot) : null,
|
|
9830
9928
|
cdnOutputDir: null,
|
|
9831
9929
|
manifestRelPath: null
|
|
9832
9930
|
};
|
|
@@ -9838,9 +9936,9 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9838
9936
|
return null;
|
|
9839
9937
|
}
|
|
9840
9938
|
const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
|
|
9841
|
-
const staticOutputDir = (0,
|
|
9842
|
-
await
|
|
9843
|
-
const shimPath = (0,
|
|
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");
|
|
9844
9942
|
const shimLines = [
|
|
9845
9943
|
`from ${settingsModule} import *`,
|
|
9846
9944
|
`STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
|
|
@@ -9848,7 +9946,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9848
9946
|
if (whitenoiseUseFinders) {
|
|
9849
9947
|
shimLines.push(`WHITENOISE_USE_FINDERS = False`);
|
|
9850
9948
|
}
|
|
9851
|
-
await
|
|
9949
|
+
await import_fs16.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
|
|
9852
9950
|
try {
|
|
9853
9951
|
console.log("Running collectstatic...");
|
|
9854
9952
|
await (0, import_execa8.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
|
|
@@ -9859,7 +9957,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9859
9957
|
cwd: djangoPath
|
|
9860
9958
|
});
|
|
9861
9959
|
} finally {
|
|
9862
|
-
await
|
|
9960
|
+
await import_fs16.default.promises.unlink(shimPath).catch(() => {
|
|
9863
9961
|
});
|
|
9864
9962
|
}
|
|
9865
9963
|
const MANIFEST_STORAGE_BACKENDS = [
|
|
@@ -9868,38 +9966,38 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
|
|
|
9868
9966
|
];
|
|
9869
9967
|
let manifestRelPath = null;
|
|
9870
9968
|
if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
|
|
9871
|
-
const manifestSrc = (0,
|
|
9872
|
-
const resolvedStaticRoot = (0,
|
|
9873
|
-
const manifestDest = (0,
|
|
9874
|
-
await
|
|
9875
|
-
await
|
|
9876
|
-
manifestRelPath = (0,
|
|
9877
|
-
(0,
|
|
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`);
|
|
9878
9976
|
}
|
|
9879
9977
|
return {
|
|
9880
9978
|
staticSourceDirs,
|
|
9881
|
-
staticRoot: staticRoot ? (0,
|
|
9979
|
+
staticRoot: staticRoot ? (0, import_path16.resolve)(djangoPath, staticRoot) : null,
|
|
9882
9980
|
cdnOutputDir: outputStaticDir,
|
|
9883
9981
|
manifestRelPath
|
|
9884
9982
|
};
|
|
9885
9983
|
}
|
|
9886
9984
|
|
|
9887
9985
|
// src/fastapi.ts
|
|
9888
|
-
var
|
|
9889
|
-
var
|
|
9986
|
+
var import_fs17 = __toESM(require("fs"));
|
|
9987
|
+
var import_path17 = require("path");
|
|
9890
9988
|
var import_execa9 = __toESM(require_execa());
|
|
9891
|
-
var
|
|
9892
|
-
var scriptPath3 = (0,
|
|
9989
|
+
var import_build_utils20 = require("@vercel/build-utils");
|
|
9990
|
+
var scriptPath3 = (0, import_path17.join)(__dirname, "..", "templates", "vc_fastapi_static.py");
|
|
9893
9991
|
var _STATIC_FILE_COLLECTION_ERROR_MESSAGE = "Warning: FastAPI static file collection failed. Static files will not be served from the CDN.";
|
|
9894
9992
|
async function getFastAPIStaticMounts(venvPath, entrypointAbs, variableName, env, workPath) {
|
|
9895
9993
|
const pythonPath = getVenvPythonBin(venvPath);
|
|
9896
|
-
const outputPath = (0,
|
|
9994
|
+
const outputPath = (0, import_path17.join)(
|
|
9897
9995
|
workPath,
|
|
9898
9996
|
".vercel",
|
|
9899
9997
|
"python",
|
|
9900
9998
|
"vc_fastapi_static_output.json"
|
|
9901
9999
|
);
|
|
9902
|
-
await
|
|
10000
|
+
await import_fs17.default.promises.mkdir((0, import_path17.join)(workPath, ".vercel", "python"), {
|
|
9903
10001
|
recursive: true
|
|
9904
10002
|
});
|
|
9905
10003
|
try {
|
|
@@ -9909,27 +10007,27 @@ async function getFastAPIStaticMounts(venvPath, entrypointAbs, variableName, env
|
|
|
9909
10007
|
{ env, cwd: workPath }
|
|
9910
10008
|
);
|
|
9911
10009
|
if (stderr) {
|
|
9912
|
-
(0,
|
|
10010
|
+
(0, import_build_utils20.debug)(`FastAPI shim stderr:
|
|
9913
10011
|
${stderr}`);
|
|
9914
10012
|
}
|
|
9915
10013
|
} catch (err) {
|
|
9916
10014
|
console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
|
|
9917
|
-
(0,
|
|
10015
|
+
(0, import_build_utils20.debug)(
|
|
9918
10016
|
`FastAPI: could not discover static mounts: ${err?.stderr ?? err?.message ?? err}`
|
|
9919
10017
|
);
|
|
9920
10018
|
return [];
|
|
9921
10019
|
}
|
|
9922
10020
|
try {
|
|
9923
|
-
const raw = await
|
|
10021
|
+
const raw = await import_fs17.default.promises.readFile(outputPath, "utf8");
|
|
9924
10022
|
const parsed = JSON.parse(raw);
|
|
9925
|
-
(0,
|
|
10023
|
+
(0, import_build_utils20.debug)(`FastAPI: discovered mounts: ${JSON.stringify(parsed)}`);
|
|
9926
10024
|
return parsed;
|
|
9927
10025
|
} catch {
|
|
9928
10026
|
console.error(_STATIC_FILE_COLLECTION_ERROR_MESSAGE);
|
|
9929
|
-
(0,
|
|
10027
|
+
(0, import_build_utils20.debug)(`FastAPI: could not read shim output file: ${outputPath}`);
|
|
9930
10028
|
return [];
|
|
9931
10029
|
} finally {
|
|
9932
|
-
await
|
|
10030
|
+
await import_fs17.default.promises.rm(outputPath, { force: true });
|
|
9933
10031
|
}
|
|
9934
10032
|
}
|
|
9935
10033
|
async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir, entrypointAbs, variableName) {
|
|
@@ -9941,18 +10039,18 @@ async function runFastAPICollectStatic(venvPath, workPath, env, outputStaticDir,
|
|
|
9941
10039
|
workPath
|
|
9942
10040
|
);
|
|
9943
10041
|
if (mounts.length === 0) {
|
|
9944
|
-
(0,
|
|
10042
|
+
(0, import_build_utils20.debug)("FastAPI: no StaticFiles mounts found, skipping");
|
|
9945
10043
|
return null;
|
|
9946
10044
|
}
|
|
9947
|
-
(0,
|
|
10045
|
+
(0, import_build_utils20.debug)(
|
|
9948
10046
|
`Found ${mounts.length} FastAPI static mount(s): ${mounts.map((m) => m.urlPath).join(", ")}`
|
|
9949
10047
|
);
|
|
9950
10048
|
for (const mount of mounts) {
|
|
9951
10049
|
const urlSubPath = mount.urlPath.replace(/^\/|\/$/g, "");
|
|
9952
|
-
const dest = (0,
|
|
9953
|
-
await
|
|
9954
|
-
await
|
|
9955
|
-
(0,
|
|
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}`);
|
|
9956
10054
|
}
|
|
9957
10055
|
return {
|
|
9958
10056
|
collectedMounts: mounts.map((m) => m.urlPath),
|
|
@@ -10008,10 +10106,10 @@ function fillBytecodeWithinCapacity(files, rankedItems, capacity) {
|
|
|
10008
10106
|
|
|
10009
10107
|
// src/compileall.ts
|
|
10010
10108
|
var import_execa10 = __toESM(require_execa());
|
|
10011
|
-
var
|
|
10012
|
-
var
|
|
10109
|
+
var import_build_utils21 = require("@vercel/build-utils");
|
|
10110
|
+
var import_fs18 = __toESM(require("fs"));
|
|
10013
10111
|
var import_os3 = require("os");
|
|
10014
|
-
var
|
|
10112
|
+
var import_path18 = require("path");
|
|
10015
10113
|
var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
10016
10114
|
var PYCACHE_PREFIX_DIR = "_vc_pycache";
|
|
10017
10115
|
var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
|
|
@@ -10047,13 +10145,13 @@ async function runCompileAll({
|
|
|
10047
10145
|
}
|
|
10048
10146
|
let tempDir;
|
|
10049
10147
|
try {
|
|
10050
|
-
tempDir = await
|
|
10051
|
-
(0,
|
|
10148
|
+
tempDir = await import_fs18.default.promises.mkdtemp(
|
|
10149
|
+
(0, import_path18.join)((0, import_os3.tmpdir)(), "vercel-python-compileall-")
|
|
10052
10150
|
);
|
|
10053
|
-
const listPath = (0,
|
|
10054
|
-
await
|
|
10055
|
-
const timingsPath = (0,
|
|
10056
|
-
const scriptPath4 = (0,
|
|
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");
|
|
10057
10155
|
const baseEnv = env || process.env;
|
|
10058
10156
|
const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
|
|
10059
10157
|
await (0, import_execa10.default)(pythonBin, [scriptPath4, listPath, timingsPath], {
|
|
@@ -10062,21 +10160,21 @@ async function runCompileAll({
|
|
|
10062
10160
|
});
|
|
10063
10161
|
let timings;
|
|
10064
10162
|
try {
|
|
10065
|
-
const raw = await
|
|
10163
|
+
const raw = await import_fs18.default.promises.readFile(timingsPath, "utf8");
|
|
10066
10164
|
timings = new Map(Object.entries(JSON.parse(raw)));
|
|
10067
10165
|
} catch (err) {
|
|
10068
|
-
(0,
|
|
10166
|
+
(0, import_build_utils21.debug)(`compileall timings unavailable: ${String(err)}`);
|
|
10069
10167
|
}
|
|
10070
10168
|
return { success: true, timings };
|
|
10071
10169
|
} catch (err) {
|
|
10072
|
-
(0,
|
|
10170
|
+
(0, import_build_utils21.debug)(`compileall error details: ${JSON.stringify(err)}`);
|
|
10073
10171
|
return { success: false };
|
|
10074
10172
|
} finally {
|
|
10075
10173
|
if (tempDir) {
|
|
10076
10174
|
try {
|
|
10077
|
-
await
|
|
10175
|
+
await import_fs18.default.promises.rm(tempDir, { recursive: true, force: true });
|
|
10078
10176
|
} catch (err) {
|
|
10079
|
-
(0,
|
|
10177
|
+
(0, import_build_utils21.debug)(`compileall temporary file cleanup error: ${String(err)}`);
|
|
10080
10178
|
}
|
|
10081
10179
|
}
|
|
10082
10180
|
}
|
|
@@ -10113,7 +10211,7 @@ function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor)
|
|
|
10113
10211
|
);
|
|
10114
10212
|
if (!rel)
|
|
10115
10213
|
return null;
|
|
10116
|
-
return (0,
|
|
10214
|
+
return (0, import_path18.join)(stagingDir, rel.replaceAll("/", import_path18.sep));
|
|
10117
10215
|
}
|
|
10118
10216
|
function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
|
|
10119
10217
|
const rel = derivePrefixPycRelPath(
|
|
@@ -10137,7 +10235,7 @@ async function collectAppPrefixBytecodeFiles({
|
|
|
10137
10235
|
for (const bundlePath of Object.keys(appFiles)) {
|
|
10138
10236
|
if (!bundlePath.endsWith(".py"))
|
|
10139
10237
|
continue;
|
|
10140
|
-
const sourceAbsPath = (0,
|
|
10238
|
+
const sourceAbsPath = (0, import_path18.join)(workPath, bundlePath.replaceAll("/", import_path18.sep));
|
|
10141
10239
|
const stagedFsPath = deriveStagedPycFsPath(
|
|
10142
10240
|
stagingDir,
|
|
10143
10241
|
sourceAbsPath,
|
|
@@ -10161,7 +10259,7 @@ async function collectAppPrefixBytecodeFiles({
|
|
|
10161
10259
|
const results = await Promise.all(
|
|
10162
10260
|
pending.map(async ({ bundlePath, srcFsPath, moduleKey, sourceAbsPath }) => {
|
|
10163
10261
|
try {
|
|
10164
|
-
const stats = await
|
|
10262
|
+
const stats = await import_fs18.default.promises.stat(srcFsPath);
|
|
10165
10263
|
return {
|
|
10166
10264
|
bundlePath,
|
|
10167
10265
|
srcFsPath,
|
|
@@ -10181,7 +10279,7 @@ async function collectAppPrefixBytecodeFiles({
|
|
|
10181
10279
|
for (const result of results) {
|
|
10182
10280
|
if (!result)
|
|
10183
10281
|
continue;
|
|
10184
|
-
const file = new
|
|
10282
|
+
const file = new import_build_utils21.FileFsRef({
|
|
10185
10283
|
fsPath: result.srcFsPath,
|
|
10186
10284
|
size: result.size
|
|
10187
10285
|
});
|
|
@@ -10211,15 +10309,15 @@ async function collectAppBytecodeFiles({
|
|
|
10211
10309
|
continue;
|
|
10212
10310
|
pending.push({
|
|
10213
10311
|
bundlePath: pycRel,
|
|
10214
|
-
srcFsPath: (0,
|
|
10312
|
+
srcFsPath: (0, import_path18.join)(workPath, pycRel.replaceAll("/", import_path18.sep)),
|
|
10215
10313
|
moduleKey: bundlePath,
|
|
10216
|
-
sourceAbsPath: (0,
|
|
10314
|
+
sourceAbsPath: (0, import_path18.join)(workPath, bundlePath.replaceAll("/", import_path18.sep))
|
|
10217
10315
|
});
|
|
10218
10316
|
}
|
|
10219
10317
|
const results = await Promise.all(
|
|
10220
10318
|
pending.map(async ({ bundlePath, srcFsPath, moduleKey, sourceAbsPath }) => {
|
|
10221
10319
|
try {
|
|
10222
|
-
const stats = await
|
|
10320
|
+
const stats = await import_fs18.default.promises.stat(srcFsPath);
|
|
10223
10321
|
return {
|
|
10224
10322
|
bundlePath,
|
|
10225
10323
|
srcFsPath,
|
|
@@ -10239,7 +10337,7 @@ async function collectAppBytecodeFiles({
|
|
|
10239
10337
|
for (const result of results) {
|
|
10240
10338
|
if (!result)
|
|
10241
10339
|
continue;
|
|
10242
|
-
const file = new
|
|
10340
|
+
const file = new import_build_utils21.FileFsRef({
|
|
10243
10341
|
fsPath: result.srcFsPath,
|
|
10244
10342
|
size: result.size
|
|
10245
10343
|
});
|
|
@@ -10258,9 +10356,9 @@ async function collectAppBytecodeFiles({
|
|
|
10258
10356
|
}
|
|
10259
10357
|
|
|
10260
10358
|
// src/installed-distributions.ts
|
|
10261
|
-
var
|
|
10262
|
-
var
|
|
10263
|
-
var
|
|
10359
|
+
var import_fs19 = __toESM(require("fs"));
|
|
10360
|
+
var import_path19 = require("path");
|
|
10361
|
+
var import_build_utils22 = require("@vercel/build-utils");
|
|
10264
10362
|
var import_python_analysis11 = require("@vercel/python-analysis");
|
|
10265
10363
|
var STRIP_BASENAMES = /* @__PURE__ */ new Set([
|
|
10266
10364
|
"py.typed",
|
|
@@ -10269,7 +10367,7 @@ var STRIP_BASENAMES = /* @__PURE__ */ new Set([
|
|
|
10269
10367
|
"direct_url.json"
|
|
10270
10368
|
]);
|
|
10271
10369
|
function shouldStripVendorFile(filePath) {
|
|
10272
|
-
const segments = filePath.split(
|
|
10370
|
+
const segments = filePath.split(import_path19.sep);
|
|
10273
10371
|
if (segments.includes("__pycache__"))
|
|
10274
10372
|
return true;
|
|
10275
10373
|
const name = segments[segments.length - 1] ?? "";
|
|
@@ -10293,19 +10391,19 @@ function getDistributionFileGroups({
|
|
|
10293
10391
|
const dirDistributions = distributions.get(dir);
|
|
10294
10392
|
if (!dirDistributions)
|
|
10295
10393
|
continue;
|
|
10296
|
-
const sitePackagesDir = (0,
|
|
10394
|
+
const sitePackagesDir = (0, import_path19.resolve)(dir);
|
|
10297
10395
|
for (const [name, distribution] of dirDistributions) {
|
|
10298
10396
|
const packageName = (0, import_python_analysis11.normalizePackageName)(name);
|
|
10299
10397
|
if (includeSet && !includeSet.has(packageName))
|
|
10300
10398
|
continue;
|
|
10301
10399
|
const files = [];
|
|
10302
10400
|
for (const record of distribution.files) {
|
|
10303
|
-
const absolutePath = (0,
|
|
10401
|
+
const absolutePath = (0, import_path19.resolve)(
|
|
10304
10402
|
sitePackagesDir,
|
|
10305
|
-
record.path.replaceAll("/",
|
|
10403
|
+
record.path.replaceAll("/", import_path19.sep)
|
|
10306
10404
|
);
|
|
10307
|
-
const relativePath = (0,
|
|
10308
|
-
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${
|
|
10405
|
+
const relativePath = (0, import_path19.relative)(sitePackagesDir, absolutePath);
|
|
10406
|
+
if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path19.sep}`) || (0, import_path19.isAbsolute)(relativePath)) {
|
|
10309
10407
|
continue;
|
|
10310
10408
|
}
|
|
10311
10409
|
files.push({ absolutePath, relativePath, record });
|
|
@@ -10325,7 +10423,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10325
10423
|
const distributions = /* @__PURE__ */ new Map();
|
|
10326
10424
|
for (const dir of sitePackageDirs) {
|
|
10327
10425
|
try {
|
|
10328
|
-
await
|
|
10426
|
+
await import_fs19.default.promises.access(dir);
|
|
10329
10427
|
} catch {
|
|
10330
10428
|
continue;
|
|
10331
10429
|
}
|
|
@@ -10366,7 +10464,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10366
10464
|
if (shouldStripVendorFile(relativePath))
|
|
10367
10465
|
continue;
|
|
10368
10466
|
pending.push({
|
|
10369
|
-
bundlePath: (0,
|
|
10467
|
+
bundlePath: (0, import_path19.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
|
|
10370
10468
|
srcFsPath: absolutePath,
|
|
10371
10469
|
recordSize: record.size != null ? Number(record.size) : void 0
|
|
10372
10470
|
});
|
|
@@ -10376,10 +10474,10 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10376
10474
|
pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
|
|
10377
10475
|
try {
|
|
10378
10476
|
if (recordSize === void 0) {
|
|
10379
|
-
const stats = await
|
|
10477
|
+
const stats = await import_fs19.default.promises.stat(srcFsPath);
|
|
10380
10478
|
return { bundlePath, srcFsPath, size: stats.size };
|
|
10381
10479
|
}
|
|
10382
|
-
await
|
|
10480
|
+
await import_fs19.default.promises.access(srcFsPath);
|
|
10383
10481
|
return { bundlePath, srcFsPath, size: recordSize };
|
|
10384
10482
|
} catch {
|
|
10385
10483
|
return null;
|
|
@@ -10390,12 +10488,12 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10390
10488
|
for (const result of results) {
|
|
10391
10489
|
if (!result)
|
|
10392
10490
|
continue;
|
|
10393
|
-
vendorFiles[result.bundlePath] = new
|
|
10491
|
+
vendorFiles[result.bundlePath] = new import_build_utils22.FileFsRef({
|
|
10394
10492
|
fsPath: result.srcFsPath,
|
|
10395
10493
|
size: result.size
|
|
10396
10494
|
});
|
|
10397
10495
|
}
|
|
10398
|
-
(0,
|
|
10496
|
+
(0, import_build_utils22.debug)(
|
|
10399
10497
|
`Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
10400
10498
|
);
|
|
10401
10499
|
return vendorFiles;
|
|
@@ -10416,7 +10514,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10416
10514
|
knownSize += Number(record.size);
|
|
10417
10515
|
} else {
|
|
10418
10516
|
statPromises.push(
|
|
10419
|
-
|
|
10517
|
+
import_fs19.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
|
|
10420
10518
|
);
|
|
10421
10519
|
}
|
|
10422
10520
|
}
|
|
@@ -10459,7 +10557,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10459
10557
|
});
|
|
10460
10558
|
for (const { packageName, sitePackagesDir, files } of distributionGroups) {
|
|
10461
10559
|
for (const { relativePath } of files) {
|
|
10462
|
-
const moduleKey = relativePath.replaceAll(
|
|
10560
|
+
const moduleKey = relativePath.replaceAll(import_path19.sep, "/");
|
|
10463
10561
|
const pycRelativePath = derivePycPath(
|
|
10464
10562
|
moduleKey,
|
|
10465
10563
|
this.pythonMajor,
|
|
@@ -10467,18 +10565,18 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10467
10565
|
);
|
|
10468
10566
|
if (!pycRelativePath)
|
|
10469
10567
|
continue;
|
|
10470
|
-
const pycFilePath = pycRelativePath.replaceAll("/",
|
|
10568
|
+
const pycFilePath = pycRelativePath.replaceAll("/", import_path19.sep);
|
|
10471
10569
|
pending.push({
|
|
10472
|
-
bundlePath: (0,
|
|
10473
|
-
srcFsPath: (0,
|
|
10570
|
+
bundlePath: (0, import_path19.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
|
|
10571
|
+
srcFsPath: (0, import_path19.join)(sitePackagesDir, pycFilePath),
|
|
10474
10572
|
packageName,
|
|
10475
10573
|
moduleKey,
|
|
10476
|
-
sourceAbsPath: (0,
|
|
10574
|
+
sourceAbsPath: (0, import_path19.join)(sitePackagesDir, relativePath)
|
|
10477
10575
|
});
|
|
10478
10576
|
}
|
|
10479
10577
|
}
|
|
10480
10578
|
const result = await this.collectExistingBytecode(pending);
|
|
10481
|
-
(0,
|
|
10579
|
+
(0, import_build_utils22.debug)(
|
|
10482
10580
|
`Collected ${Object.keys(result.files).length} bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
|
|
10483
10581
|
);
|
|
10484
10582
|
return result;
|
|
@@ -10501,7 +10599,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10501
10599
|
for (const { absolutePath, relativePath } of files) {
|
|
10502
10600
|
if (!relativePath.endsWith(".py"))
|
|
10503
10601
|
continue;
|
|
10504
|
-
const recordPath = relativePath.replaceAll(
|
|
10602
|
+
const recordPath = relativePath.replaceAll(import_path19.sep, "/");
|
|
10505
10603
|
const srcFsPath = deriveStagedPycFsPath(
|
|
10506
10604
|
stagingDir,
|
|
10507
10605
|
absolutePath,
|
|
@@ -10525,7 +10623,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10525
10623
|
}
|
|
10526
10624
|
}
|
|
10527
10625
|
const result = await this.collectExistingBytecode(pending);
|
|
10528
|
-
(0,
|
|
10626
|
+
(0, import_build_utils22.debug)(
|
|
10529
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` : "")
|
|
10530
10628
|
);
|
|
10531
10629
|
return result;
|
|
@@ -10541,7 +10639,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10541
10639
|
sourceAbsPath
|
|
10542
10640
|
}) => {
|
|
10543
10641
|
try {
|
|
10544
|
-
const stats = await
|
|
10642
|
+
const stats = await import_fs19.default.promises.stat(srcFsPath);
|
|
10545
10643
|
return {
|
|
10546
10644
|
bundlePath,
|
|
10547
10645
|
srcFsPath,
|
|
@@ -10563,7 +10661,7 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10563
10661
|
for (const result of results) {
|
|
10564
10662
|
if (!result)
|
|
10565
10663
|
continue;
|
|
10566
|
-
const file = new
|
|
10664
|
+
const file = new import_build_utils22.FileFsRef({
|
|
10567
10665
|
fsPath: result.srcFsPath,
|
|
10568
10666
|
size: result.size
|
|
10569
10667
|
});
|
|
@@ -10585,84 +10683,6 @@ var InstalledPythonDistributions = class _InstalledPythonDistributions {
|
|
|
10585
10683
|
}
|
|
10586
10684
|
};
|
|
10587
10685
|
|
|
10588
|
-
// src/workflows.ts
|
|
10589
|
-
var import_path19 = require("path");
|
|
10590
|
-
var import_fs19 = __toESM(require("fs"));
|
|
10591
|
-
var import_build_utils22 = require("@vercel/build-utils");
|
|
10592
|
-
var WORKFLOW_OUTPUT_DIR = "_py_workflows";
|
|
10593
|
-
var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
|
|
10594
|
-
var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
|
|
10595
|
-
function getWorkflowOutputPath(workflowName) {
|
|
10596
|
-
return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
|
|
10597
|
-
}
|
|
10598
|
-
function getWorkflowConsumerName(workflowName) {
|
|
10599
|
-
return (0, import_build_utils22.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
|
|
10600
|
-
}
|
|
10601
|
-
async function getPyprojectWorkflows(workPath) {
|
|
10602
|
-
const pyprojectPath = (0, import_path19.join)(workPath, "pyproject.toml");
|
|
10603
|
-
if (!import_fs19.default.existsSync(pyprojectPath)) {
|
|
10604
|
-
return [];
|
|
10605
|
-
}
|
|
10606
|
-
const pyproject = await (0, import_build_utils22.readConfigFile)(pyprojectPath);
|
|
10607
|
-
const workflows = pyproject?.tool?.vercel?.workflows;
|
|
10608
|
-
if (!workflows) {
|
|
10609
|
-
return [];
|
|
10610
|
-
}
|
|
10611
|
-
if (!Array.isArray(workflows)) {
|
|
10612
|
-
throw workflowError('"tool.vercel.workflows" must be an array');
|
|
10613
|
-
}
|
|
10614
|
-
if (workflows.length > 1) {
|
|
10615
|
-
throw workflowError(
|
|
10616
|
-
'"tool.vercel.workflows" must declare a single entrypoint that registers every workflow'
|
|
10617
|
-
);
|
|
10618
|
-
}
|
|
10619
|
-
return Promise.all(
|
|
10620
|
-
workflows.map((config, index) => parseWorkflow(workPath, index, config))
|
|
10621
|
-
);
|
|
10622
|
-
}
|
|
10623
|
-
async function parseWorkflow(workPath, index, config) {
|
|
10624
|
-
const label = `workflow #${index + 1}`;
|
|
10625
|
-
if (!config || typeof config !== "object" || Array.isArray(config)) {
|
|
10626
|
-
throw workflowError(`${label} must be an object`);
|
|
10627
|
-
}
|
|
10628
|
-
for (const key of Object.keys(config)) {
|
|
10629
|
-
if (!WORKFLOW_FIELD_NAMES.has(key)) {
|
|
10630
|
-
throw workflowError(`${label} has unrecognized field "${key}"`);
|
|
10631
|
-
}
|
|
10632
|
-
}
|
|
10633
|
-
if (typeof config.entrypoint !== "string") {
|
|
10634
|
-
throw workflowError(`${label} must define string field "entrypoint"`);
|
|
10635
|
-
}
|
|
10636
|
-
const entrypoint = parseModuleEntrypoint(config.entrypoint);
|
|
10637
|
-
if (!entrypoint) {
|
|
10638
|
-
throw workflowError(
|
|
10639
|
-
`${label} has invalid entrypoint "${config.entrypoint}". Use "module:object"`
|
|
10640
|
-
);
|
|
10641
|
-
}
|
|
10642
|
-
const name = getModuleEntrypointName(entrypoint);
|
|
10643
|
-
const existingEntrypoint = await resolveExistingEntrypoint(
|
|
10644
|
-
workPath,
|
|
10645
|
-
entrypoint.filePath
|
|
10646
|
-
);
|
|
10647
|
-
if (!existingEntrypoint) {
|
|
10648
|
-
throw workflowError(
|
|
10649
|
-
`workflow "${name}" has entrypoint "${config.entrypoint}" but file "${entrypoint.filePath}" does not exist`
|
|
10650
|
-
);
|
|
10651
|
-
}
|
|
10652
|
-
return {
|
|
10653
|
-
name,
|
|
10654
|
-
entrypoint: existingEntrypoint,
|
|
10655
|
-
moduleName: entrypoint.moduleName,
|
|
10656
|
-
variableName: entrypoint.variableName
|
|
10657
|
-
};
|
|
10658
|
-
}
|
|
10659
|
-
function workflowError(message) {
|
|
10660
|
-
return new import_build_utils22.NowBuildError({
|
|
10661
|
-
code: "PYTHON_INVALID_WORKFLOW_CONFIG",
|
|
10662
|
-
message
|
|
10663
|
-
});
|
|
10664
|
-
}
|
|
10665
|
-
|
|
10666
10686
|
// src/import-closure.ts
|
|
10667
10687
|
var import_path20 = require("path");
|
|
10668
10688
|
var import_build_utils23 = require("@vercel/build-utils");
|
|
@@ -10796,7 +10816,7 @@ async function getDevSidecars({
|
|
|
10796
10816
|
pythonQueueSidecar: "workflow"
|
|
10797
10817
|
}
|
|
10798
10818
|
},
|
|
10799
|
-
topics: [{ topic:
|
|
10819
|
+
topics: [{ topic: WORKFLOW_DEV_TOPIC_PATTERN }]
|
|
10800
10820
|
})
|
|
10801
10821
|
)
|
|
10802
10822
|
];
|
|
@@ -11421,6 +11441,12 @@ var build = async ({
|
|
|
11421
11441
|
projectDir: (0, import_path21.join)(workPath, entryDirectory),
|
|
11422
11442
|
uvLockPath
|
|
11423
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
|
+
}
|
|
11424
11450
|
}
|
|
11425
11451
|
const shouldInstallVercelWorkers = legacyWorkersProject || workflows.length > 0 && workflowMode === "workers";
|
|
11426
11452
|
if (shouldInstallVercelWorkers) {
|
|
@@ -11462,7 +11488,7 @@ var build = async ({
|
|
|
11462
11488
|
for (const subscriber of subscribers) {
|
|
11463
11489
|
if (!subscriber.topicPatterns) {
|
|
11464
11490
|
subscriber.subscriptions = subscriber.subscriptions.filter(
|
|
11465
|
-
(subscription) => !subscription.topic
|
|
11491
|
+
(subscription) => !isWorkflowQueueTopic(subscription.topic)
|
|
11466
11492
|
);
|
|
11467
11493
|
}
|
|
11468
11494
|
}
|
|
@@ -11481,8 +11507,7 @@ var build = async ({
|
|
|
11481
11507
|
name: workflow.name,
|
|
11482
11508
|
entrypoint: workflow.entrypoint,
|
|
11483
11509
|
moduleName: workflow.moduleName,
|
|
11484
|
-
variableName: workflow.variableName
|
|
11485
|
-
topicPatterns: [WORKFLOW_TOPIC_PATTERN]
|
|
11510
|
+
variableName: workflow.variableName
|
|
11486
11511
|
})),
|
|
11487
11512
|
uv,
|
|
11488
11513
|
venvPath,
|
|
@@ -11490,6 +11515,21 @@ var build = async ({
|
|
|
11490
11515
|
kind: "workflow",
|
|
11491
11516
|
integrations: queueIntegrations
|
|
11492
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
|
+
}
|
|
11493
11533
|
for (const workflow of resolved2) {
|
|
11494
11534
|
workflowQueueSubscriptions.set(workflow.name, workflow.subscriptions);
|
|
11495
11535
|
await writeGeneratedQueueHandler(
|