@vercel/static-build 10.0.1 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1048 -140
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -19035,45 +19035,6 @@ var require_semver3 = __commonJS({
19035
19035
  }
19036
19036
  });
19037
19037
 
19038
- // ../fs-detectors/dist/is-official-runtime.js
19039
- var require_is_official_runtime = __commonJS({
19040
- "../fs-detectors/dist/is-official-runtime.js"(exports, module2) {
19041
- "use strict";
19042
- var __defProp2 = Object.defineProperty;
19043
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
19044
- var __getOwnPropNames2 = Object.getOwnPropertyNames;
19045
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
19046
- var __export2 = (target, all) => {
19047
- for (var name in all)
19048
- __defProp2(target, name, { get: all[name], enumerable: true });
19049
- };
19050
- var __copyProps2 = (to, from, except, desc) => {
19051
- if (from && typeof from === "object" || typeof from === "function") {
19052
- for (let key of __getOwnPropNames2(from))
19053
- if (!__hasOwnProp2.call(to, key) && key !== except)
19054
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
19055
- }
19056
- return to;
19057
- };
19058
- var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
19059
- var is_official_runtime_exports = {};
19060
- __export2(is_official_runtime_exports, {
19061
- isOfficialRuntime: () => isOfficialRuntime2,
19062
- isStaticRuntime: () => isStaticRuntime2
19063
- });
19064
- module2.exports = __toCommonJS2(is_official_runtime_exports);
19065
- var isOfficialRuntime2 = (desired, name) => {
19066
- if (typeof name !== "string") {
19067
- return false;
19068
- }
19069
- return name === `@vercel/${desired}` || name === `@now/${desired}` || name.startsWith(`@vercel/${desired}@`) || name.startsWith(`@now/${desired}@`);
19070
- };
19071
- var isStaticRuntime2 = (name) => {
19072
- return isOfficialRuntime2("static", name);
19073
- };
19074
- }
19075
- });
19076
-
19077
19038
  // ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/commonjs/index.js
19078
19039
  var require_commonjs = __commonJS({
19079
19040
  "../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/commonjs/index.js"(exports) {
@@ -32161,57 +32122,6 @@ ${issues}`,
32161
32122
  }
32162
32123
  });
32163
32124
 
32164
- // ../fs-detectors/dist/python.js
32165
- var require_python = __commonJS({
32166
- "../fs-detectors/dist/python.js"(exports, module2) {
32167
- "use strict";
32168
- var __create2 = Object.create;
32169
- var __defProp2 = Object.defineProperty;
32170
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
32171
- var __getOwnPropNames2 = Object.getOwnPropertyNames;
32172
- var __getProtoOf2 = Object.getPrototypeOf;
32173
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
32174
- var __export2 = (target, all) => {
32175
- for (var name in all)
32176
- __defProp2(target, name, { get: all[name], enumerable: true });
32177
- };
32178
- var __copyProps2 = (to, from, except, desc) => {
32179
- if (from && typeof from === "object" || typeof from === "function") {
32180
- for (let key of __getOwnPropNames2(from))
32181
- if (!__hasOwnProp2.call(to, key) && key !== except)
32182
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
32183
- }
32184
- return to;
32185
- };
32186
- var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
32187
- // If the importer is in node compatibility mode or this is not an ESM
32188
- // file that has been converted to a CommonJS file using a Babel-
32189
- // compatible transform (i.e. "__esModule" has not been set), then set
32190
- // "default" to the CommonJS "module.exports" for node compatibility.
32191
- isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
32192
- mod
32193
- ));
32194
- var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
32195
- var python_exports = {};
32196
- __export2(python_exports, {
32197
- isPythonEntrypoint: () => isPythonEntrypoint
32198
- });
32199
- module2.exports = __toCommonJS2(python_exports);
32200
- var import_fs5 = __toESM2(require("fs"));
32201
- var import_build_utils5 = require("@vercel/build-utils");
32202
- var import_python_analysis = require_dist5();
32203
- async function isPythonEntrypoint(fsPath) {
32204
- try {
32205
- const content = await import_fs5.default.promises.readFile(fsPath, "utf-8");
32206
- return await (0, import_python_analysis.findAppOrHandler)(content) !== null;
32207
- } catch (err) {
32208
- (0, import_build_utils5.debug)(`Failed to check Python entrypoint: ${err}`);
32209
- return false;
32210
- }
32211
- }
32212
- }
32213
- });
32214
-
32215
32125
  // ../fs-detectors/dist/detect-builders.js
32216
32126
  var require_detect_builders = __commonJS({
32217
32127
  "../fs-detectors/dist/detect-builders.js"(exports, module2) {
@@ -32222,6 +32132,9 @@ var require_detect_builders = __commonJS({
32222
32132
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
32223
32133
  var __getProtoOf2 = Object.getPrototypeOf;
32224
32134
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
32135
+ var __commonJS2 = (cb, mod) => function __require() {
32136
+ return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
32137
+ };
32225
32138
  var __export2 = (target, all) => {
32226
32139
  for (var name in all)
32227
32140
  __defProp2(target, name, { get: all[name], enumerable: true });
@@ -32243,6 +32156,264 @@ var require_detect_builders = __commonJS({
32243
32156
  mod
32244
32157
  ));
32245
32158
  var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
32159
+ var require_constants3 = __commonJS2({
32160
+ "../../internals/runtimes/dist/constants.js"(exports2, module22) {
32161
+ "use strict";
32162
+ var __defProp22 = Object.defineProperty;
32163
+ var __getOwnPropDesc22 = Object.getOwnPropertyDescriptor;
32164
+ var __getOwnPropNames22 = Object.getOwnPropertyNames;
32165
+ var __hasOwnProp22 = Object.prototype.hasOwnProperty;
32166
+ var __export22 = (target, all) => {
32167
+ for (var name in all)
32168
+ __defProp22(target, name, { get: all[name], enumerable: true });
32169
+ };
32170
+ var __copyProps22 = (to, from, except, desc) => {
32171
+ if (from && typeof from === "object" || typeof from === "function") {
32172
+ for (let key of __getOwnPropNames22(from))
32173
+ if (!__hasOwnProp22.call(to, key) && key !== except)
32174
+ __defProp22(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc22(from, key)) || desc.enumerable });
32175
+ }
32176
+ return to;
32177
+ };
32178
+ var __toCommonJS22 = (mod) => __copyProps22(__defProp22({}, "__esModule", { value: true }), mod);
32179
+ var constants_exports = {};
32180
+ __export22(constants_exports, {
32181
+ BUILDER_RUNTIMES: () => BUILDER_RUNTIMES,
32182
+ CONTAINER_ENTRYPOINT_CANDIDATES: () => CONTAINER_ENTRYPOINT_CANDIDATES,
32183
+ ENTRYPOINT_EXTENSIONS: () => ENTRYPOINT_EXTENSIONS2,
32184
+ ROUTE_OWNING_BUILDERS: () => ROUTE_OWNING_BUILDERS,
32185
+ RUNTIME_BUILDERS: () => RUNTIME_BUILDERS,
32186
+ RUNTIME_MANIFESTS: () => RUNTIME_MANIFESTS,
32187
+ STATIC_BUILDERS: () => STATIC_BUILDERS
32188
+ });
32189
+ module22.exports = __toCommonJS22(constants_exports);
32190
+ var RUNTIME_BUILDERS = {
32191
+ node: "@vercel/backends",
32192
+ python: "@vercel/python",
32193
+ go: "@vercel/go",
32194
+ rust: "@vercel/rust",
32195
+ ruby: "@vercel/ruby",
32196
+ container: "@vercel/container"
32197
+ };
32198
+ var RUNTIME_MANIFESTS = {
32199
+ node: ["package.json"],
32200
+ python: [
32201
+ "pyproject.toml",
32202
+ "requirements.txt",
32203
+ "Pipfile",
32204
+ "pylock.yml",
32205
+ "uv.lock",
32206
+ "setup.py"
32207
+ ],
32208
+ go: ["go.mod"],
32209
+ ruby: ["Gemfile"],
32210
+ rust: ["Cargo.toml"]
32211
+ };
32212
+ var ENTRYPOINT_EXTENSIONS2 = {
32213
+ ".ts": "node",
32214
+ ".mts": "node",
32215
+ ".js": "node",
32216
+ ".mjs": "node",
32217
+ ".cjs": "node",
32218
+ ".py": "python",
32219
+ ".go": "go",
32220
+ ".rs": "rust",
32221
+ ".rb": "ruby",
32222
+ ".ru": "ruby"
32223
+ };
32224
+ var BUILDER_RUNTIMES = Object.fromEntries(
32225
+ Object.entries(RUNTIME_BUILDERS).map(([runtime, builder]) => [
32226
+ builder,
32227
+ runtime
32228
+ ])
32229
+ );
32230
+ var STATIC_BUILDERS = /* @__PURE__ */ new Set([
32231
+ "@vercel/static-build",
32232
+ "@vercel/static"
32233
+ ]);
32234
+ var ROUTE_OWNING_BUILDERS = /* @__PURE__ */ new Set([
32235
+ "@vercel/next",
32236
+ "@vercel/backends"
32237
+ ]);
32238
+ var CONTAINER_ENTRYPOINT_CANDIDATES = [
32239
+ "Dockerfile.vercel",
32240
+ "Containerfile.vercel",
32241
+ "Dockerfile",
32242
+ "Containerfile"
32243
+ ];
32244
+ }
32245
+ });
32246
+ var require_entrypoint2 = __commonJS2({
32247
+ "../../internals/runtimes/dist/entrypoint.js"(exports2, module22) {
32248
+ "use strict";
32249
+ var __defProp22 = Object.defineProperty;
32250
+ var __getOwnPropDesc22 = Object.getOwnPropertyDescriptor;
32251
+ var __getOwnPropNames22 = Object.getOwnPropertyNames;
32252
+ var __hasOwnProp22 = Object.prototype.hasOwnProperty;
32253
+ var __export22 = (target, all) => {
32254
+ for (var name in all)
32255
+ __defProp22(target, name, { get: all[name], enumerable: true });
32256
+ };
32257
+ var __copyProps22 = (to, from, except, desc) => {
32258
+ if (from && typeof from === "object" || typeof from === "function") {
32259
+ for (let key of __getOwnPropNames22(from))
32260
+ if (!__hasOwnProp22.call(to, key) && key !== except)
32261
+ __defProp22(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc22(from, key)) || desc.enumerable });
32262
+ }
32263
+ return to;
32264
+ };
32265
+ var __toCommonJS22 = (mod) => __copyProps22(__defProp22({}, "__esModule", { value: true }), mod);
32266
+ var entrypoint_exports = {};
32267
+ __export22(entrypoint_exports, {
32268
+ SCHEDULE_ENTRYPOINT_FORMS_HINT: () => SCHEDULE_ENTRYPOINT_FORMS_HINT,
32269
+ isDockerfileEntrypoint: () => isDockerfileEntrypoint,
32270
+ parsePyModuleAttrEntrypoint: () => parsePyModuleAttrEntrypoint2,
32271
+ parseScheduleEntrypoint: () => parseScheduleEntrypoint,
32272
+ stripTrailingSlash: () => stripTrailingSlash
32273
+ });
32274
+ module22.exports = __toCommonJS22(entrypoint_exports);
32275
+ var import_path22 = require("path");
32276
+ var import_constants2 = require_constants3();
32277
+ var PYTHON_MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
32278
+ var NODE_FILE_ENTRYPOINT_RE = /^(?!\/)(?!.*(?:^|\/)\.\.?(?:\/|$))(?:[\w@+.-]+\/)*[\w@+.-]+\.[cm]?[jt]s$/;
32279
+ var NODE_DECLARATION_ENTRYPOINT_RE = /\.d\.[cm]?ts$/;
32280
+ function parsePyModuleAttrEntrypoint2(entrypoint) {
32281
+ const match = PYTHON_MODULE_ATTR_RE.exec(entrypoint);
32282
+ if (!match)
32283
+ return null;
32284
+ const [, modulePart, attrName] = match;
32285
+ if (!modulePart || !attrName)
32286
+ return null;
32287
+ return {
32288
+ attrName,
32289
+ filePath: modulePart.replace(/\./g, "/") + ".py",
32290
+ moduleName: modulePart
32291
+ };
32292
+ }
32293
+ var SCHEDULE_ENTRYPOINT_FORMS_HINT = 'Use a source file path like "jobs/nightly.ts" or a Python "module.path:function" reference.';
32294
+ function parseScheduleEntrypoint(entrypoint) {
32295
+ const python = parsePyModuleAttrEntrypoint2(entrypoint);
32296
+ if (python) {
32297
+ return { runtime: "python", ...python };
32298
+ }
32299
+ if (NODE_FILE_ENTRYPOINT_RE.test(entrypoint) && !NODE_DECLARATION_ENTRYPOINT_RE.test(entrypoint)) {
32300
+ return { runtime: "node", filePath: entrypoint };
32301
+ }
32302
+ return null;
32303
+ }
32304
+ var CONTAINER_ENTRYPOINT_BASENAMES = new Set(
32305
+ import_constants2.CONTAINER_ENTRYPOINT_CANDIDATES.map((name) => name.toLowerCase())
32306
+ );
32307
+ function isDockerfileEntrypoint(entrypoint) {
32308
+ return CONTAINER_ENTRYPOINT_BASENAMES.has(
32309
+ import_path22.posix.basename(entrypoint).toLowerCase()
32310
+ );
32311
+ }
32312
+ function stripTrailingSlash(p) {
32313
+ const stripped = p.replace(/\/+$/, "");
32314
+ return stripped === "" ? "." : stripped;
32315
+ }
32316
+ }
32317
+ });
32318
+ var require_framework2 = __commonJS2({
32319
+ "../../internals/runtimes/dist/framework.js"(exports2, module22) {
32320
+ "use strict";
32321
+ var __defProp22 = Object.defineProperty;
32322
+ var __getOwnPropDesc22 = Object.getOwnPropertyDescriptor;
32323
+ var __getOwnPropNames22 = Object.getOwnPropertyNames;
32324
+ var __hasOwnProp22 = Object.prototype.hasOwnProperty;
32325
+ var __export22 = (target, all) => {
32326
+ for (var name in all)
32327
+ __defProp22(target, name, { get: all[name], enumerable: true });
32328
+ };
32329
+ var __copyProps22 = (to, from, except, desc) => {
32330
+ if (from && typeof from === "object" || typeof from === "function") {
32331
+ for (let key of __getOwnPropNames22(from))
32332
+ if (!__hasOwnProp22.call(to, key) && key !== except)
32333
+ __defProp22(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc22(from, key)) || desc.enumerable });
32334
+ }
32335
+ return to;
32336
+ };
32337
+ var __toCommonJS22 = (mod) => __copyProps22(__defProp22({}, "__esModule", { value: true }), mod);
32338
+ var framework_exports = {};
32339
+ __export22(framework_exports, {
32340
+ DETECTION_FRAMEWORKS: () => DETECTION_FRAMEWORKS,
32341
+ filterFrameworksByRuntime: () => filterFrameworksByRuntime,
32342
+ frameworksBySlug: () => frameworksBySlug,
32343
+ inferBuilderRuntimeFromFramework: () => inferBuilderRuntimeFromFramework2,
32344
+ inferRuntimeFromFramework: () => inferRuntimeFromFramework,
32345
+ inferServerRuntimeFromFramework: () => inferServerRuntimeFromFramework,
32346
+ isBFFFramework: () => isBFFFramework,
32347
+ isFrontendFramework: () => isFrontendFramework
32348
+ });
32349
+ module22.exports = __toCommonJS22(framework_exports);
32350
+ var import_build_utils32 = require("@vercel/build-utils");
32351
+ var import_frameworks22 = require_frameworks();
32352
+ var import_constants2 = require_constants3();
32353
+ var frameworksBySlug = new Map(
32354
+ import_frameworks22.frameworkList.flatMap((f) => typeof f.slug === "string" ? [[f.slug, f]] : [])
32355
+ );
32356
+ var DETECTION_FRAMEWORKS = import_frameworks22.frameworkList.filter(
32357
+ (framework) => !framework.experimental || framework.runtimeFramework
32358
+ );
32359
+ function inferRuntimeFromFramework(framework) {
32360
+ if (!framework)
32361
+ return void 0;
32362
+ if (framework in import_constants2.RUNTIME_BUILDERS)
32363
+ return framework;
32364
+ if ((0, import_build_utils32.isPythonFramework)(framework))
32365
+ return "python";
32366
+ if ((0, import_build_utils32.isBackendFramework)(framework))
32367
+ return "node";
32368
+ return void 0;
32369
+ }
32370
+ var STATIC_BUILDER_RUNTIMES = {
32371
+ hugo: "go",
32372
+ jekyll: "ruby",
32373
+ middleman: "ruby",
32374
+ zola: "rust"
32375
+ };
32376
+ function inferServerRuntimeFromFramework(framework) {
32377
+ if (!framework || framework === "services")
32378
+ return void 0;
32379
+ const builder = frameworksBySlug.get(framework)?.useRuntime?.use;
32380
+ if (!builder)
32381
+ return void 0;
32382
+ return import_constants2.BUILDER_RUNTIMES[builder] ?? "node";
32383
+ }
32384
+ function inferBuilderRuntimeFromFramework2(framework) {
32385
+ if (!framework || framework === "container" || framework === "services")
32386
+ return void 0;
32387
+ const f = frameworksBySlug.get(framework);
32388
+ const declaredBuilder = f?.useRuntime?.use;
32389
+ if (declaredBuilder)
32390
+ return import_constants2.BUILDER_RUNTIMES[declaredBuilder];
32391
+ const detectorItems = [
32392
+ ...f?.detectors?.every ?? [],
32393
+ ...f?.detectors?.some ?? []
32394
+ ];
32395
+ return STATIC_BUILDER_RUNTIMES[framework] ?? (detectorItems.some((d) => d.matchPackage !== void 0) ? "node" : void 0);
32396
+ }
32397
+ function isFrontendFramework(framework) {
32398
+ return !!framework && !inferRuntimeFromFramework(framework);
32399
+ }
32400
+ var BFF_FRAMEWORKS = /* @__PURE__ */ new Set([
32401
+ "nextjs",
32402
+ "nuxtjs",
32403
+ "sveltekit",
32404
+ "remix",
32405
+ "solidstart"
32406
+ ]);
32407
+ function isBFFFramework(framework) {
32408
+ return !!framework && BFF_FRAMEWORKS.has(framework);
32409
+ }
32410
+ function filterFrameworksByRuntime(frameworks2, runtime) {
32411
+ if (!runtime)
32412
+ return [...frameworks2];
32413
+ return frameworks2.filter((f) => inferRuntimeFromFramework(f.slug) === runtime);
32414
+ }
32415
+ }
32416
+ });
32246
32417
  var detect_builders_exports = {};
32247
32418
  __export2(detect_builders_exports, {
32248
32419
  REGEX_MIDDLEWARE_FILES: () => REGEX_MIDDLEWARE_FILES,
@@ -32260,12 +32431,41 @@ var require_detect_builders = __commonJS({
32260
32431
  });
32261
32432
  module2.exports = __toCommonJS2(detect_builders_exports);
32262
32433
  var import_minimatch = __toESM2(require_minimatch());
32434
+ var import_entrypoint = __toESM2(require_entrypoint2());
32263
32435
  var import_semver2 = require_semver3();
32264
32436
  var import_path7 = require("path");
32265
32437
  var import_frameworks2 = require_frameworks();
32266
- var import_is_official_runtime = require_is_official_runtime();
32438
+ var import_framework = __toESM2(require_framework2());
32439
+ var import_constants = __toESM2(require_constants3());
32440
+ var isOfficialRuntime2 = (desired, name) => {
32441
+ if (typeof name !== "string") {
32442
+ return false;
32443
+ }
32444
+ return name === `@vercel/${desired}` || name === `@now/${desired}` || name.startsWith(`@vercel/${desired}@`) || name.startsWith(`@now/${desired}@`);
32445
+ };
32446
+ var import_build_utils22 = require("@vercel/build-utils");
32447
+ var import_fs5 = __toESM2(require("fs"));
32267
32448
  var import_build_utils5 = require("@vercel/build-utils");
32268
- var import_python = require_python();
32449
+ var import_python_analysis = require_dist5();
32450
+ async function isPythonEntrypoint(fsPath) {
32451
+ try {
32452
+ const content = await import_fs5.default.promises.readFile(fsPath, "utf-8");
32453
+ return await (0, import_python_analysis.findAppOrHandler)(content) !== null;
32454
+ } catch (err) {
32455
+ (0, import_build_utils5.debug)(`Failed to check Python entrypoint: ${err}`);
32456
+ return false;
32457
+ }
32458
+ }
32459
+ var BUILDPACK_PROJECT_MARKERS = /* @__PURE__ */ new Map([["ruby", ["Gemfile"]]]);
32460
+ function isBuildpackRuntimeEnabled(runtime) {
32461
+ return process.env[`VERCEL_EXPERIMENTAL_BUILDPACK_${runtime.toUpperCase()}`] === "1";
32462
+ }
32463
+ function toBuildpackRuntime(runtime) {
32464
+ if (!runtime || !BUILDPACK_PROJECT_MARKERS.has(runtime) || !isBuildpackRuntimeEnabled(runtime)) {
32465
+ return void 0;
32466
+ }
32467
+ return runtime;
32468
+ }
32269
32469
  var REGEX_MIDDLEWARE_FILES = "middleware.[jt]s";
32270
32470
  var VERCEL_PLATFORM_FILES = [
32271
32471
  "api/**",
@@ -32291,9 +32491,6 @@ var require_detect_builders = __commonJS({
32291
32491
  ].join(",")}}`;
32292
32492
  }
32293
32493
  var REGEX_NON_VERCEL_PLATFORM_FILES2 = getStaticFilesPattern();
32294
- var slugToFramework = new Map(
32295
- import_frameworks2.frameworkList.map((f) => [f.slug, f])
32296
- );
32297
32494
  var builderToFrameworks2 = (() => {
32298
32495
  const map = /* @__PURE__ */ new Map();
32299
32496
  for (const f of import_frameworks2.frameworkList) {
@@ -32327,7 +32524,7 @@ var require_detect_builders = __commonJS({
32327
32524
  }
32328
32525
  function getPublicBuilder(builders) {
32329
32526
  for (const builder of builders) {
32330
- if (typeof builder.src === "string" && (0, import_is_official_runtime.isOfficialRuntime)("static", builder.use) && /^.*\/\*\*\/\*$/.test(builder.src) && builder.config?.zeroConfig === true) {
32527
+ if (typeof builder.src === "string" && isOfficialRuntime2("static", builder.use) && /^.*\/\*\*\/\*$/.test(builder.src) && builder.config?.zeroConfig === true) {
32331
32528
  return builder;
32332
32529
  }
32333
32530
  }
@@ -32377,8 +32574,15 @@ var require_detect_builders = __commonJS({
32377
32574
  usedFunctions.add(key);
32378
32575
  };
32379
32576
  const absolutePathCache = /* @__PURE__ */ new Map();
32577
+ const proxyFile = options.proxy ? parseProxyEntrypoint(options.proxy.entrypoint).file : null;
32578
+ const reservedFunctionFiles = options.reservedFunctionFiles ?? [];
32579
+ const claimedFiles = /* @__PURE__ */ new Set([
32580
+ ...proxyFile !== null ? [proxyFile] : [],
32581
+ ...reservedFunctionFiles
32582
+ ]);
32583
+ const hasReservedFunctions = reservedFunctionFiles.length > 0;
32380
32584
  const { buildCommand, outputDirectory } = projectSettings;
32381
- const frameworkConfig = slugToFramework.get(framework || "");
32585
+ const frameworkConfig = import_framework.frameworksBySlug.get(framework || "");
32382
32586
  const rustStaticOutput = isRustStaticOutput(framework, projectSettings);
32383
32587
  const ignoreRuntimes = new Set(
32384
32588
  rustStaticOutput ? void 0 : frameworkConfig?.ignoreRuntimes
@@ -32403,7 +32607,7 @@ var require_detect_builders = __commonJS({
32403
32607
  const apiRoutes = [];
32404
32608
  const dynamicRoutes = [];
32405
32609
  for (const fileName of sortedFiles) {
32406
- if (fileName === options.proxy?.entrypoint) {
32610
+ if (claimedFiles.has(fileName)) {
32407
32611
  continue;
32408
32612
  }
32409
32613
  const apiBuilder = await maybeGetApiBuilder(fileName, apiMatches, options);
@@ -32467,7 +32671,7 @@ var require_detect_builders = __commonJS({
32467
32671
  options
32468
32672
  );
32469
32673
  } else {
32470
- if (pkg && !makeFrontendStatic && !apiBuilders.length && !options.ignoreBuildScript) {
32674
+ if (pkg && !makeFrontendStatic && !apiBuilders.length && !hasReservedFunctions && !options.ignoreBuildScript) {
32471
32675
  errors.push(getMissingBuildScriptError());
32472
32676
  return {
32473
32677
  errors,
@@ -32488,19 +32692,17 @@ var require_detect_builders = __commonJS({
32488
32692
  outputDirectory: usedOutputDirectory
32489
32693
  }
32490
32694
  };
32491
- } else if (apiBuilders.length && hasNoneApiFiles) {
32695
+ } else if ((apiBuilders.length || hasReservedFunctions) && hasNoneApiFiles) {
32492
32696
  frontendBuilder = {
32493
32697
  use: "@vercel/static",
32494
- src: getStaticFilesPattern(
32495
- options.proxy ? [options.proxy.entrypoint] : []
32496
- ),
32698
+ src: getStaticFilesPattern([...claimedFiles]),
32497
32699
  config: {
32498
32700
  zeroConfig: true
32499
32701
  }
32500
32702
  };
32501
32703
  }
32502
32704
  }
32503
- if (options.proxy && frontendBuilder && (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder.use)) {
32705
+ if (options.proxy && frontendBuilder && isOfficialRuntime2("next", frontendBuilder.use)) {
32504
32706
  return {
32505
32707
  builders: null,
32506
32708
  errors: [
@@ -32519,6 +32721,7 @@ var require_detect_builders = __commonJS({
32519
32721
  const unusedFunctionError = checkUnusedFunctions(
32520
32722
  frontendBuilder,
32521
32723
  usedFunctions,
32724
+ claimedFiles,
32522
32725
  options
32523
32726
  );
32524
32727
  if (unusedFunctionError) {
@@ -32543,7 +32746,7 @@ var require_detect_builders = __commonJS({
32543
32746
  builders.push(...apiBuilders);
32544
32747
  }
32545
32748
  if (frontendBuilder) {
32546
- if ((0, import_is_official_runtime.isOfficialRuntime)("express", frontendBuilder?.use) || (0, import_is_official_runtime.isOfficialRuntime)("hono", frontendBuilder?.use) || (0, import_is_official_runtime.isOfficialRuntime)("python", frontendBuilder?.use) || (0, import_is_official_runtime.isOfficialRuntime)("go", frontendBuilder?.use) || (0, import_is_official_runtime.isOfficialRuntime)("backends", frontendBuilder?.use)) {
32749
+ if (isOfficialRuntime2("express", frontendBuilder?.use) || isOfficialRuntime2("hono", frontendBuilder?.use) || isOfficialRuntime2("python", frontendBuilder?.use) || isOfficialRuntime2("go", frontendBuilder?.use) || isOfficialRuntime2("backends", frontendBuilder?.use)) {
32547
32750
  builders.push({
32548
32751
  src: "public/**/*",
32549
32752
  use: "@vercel/static",
@@ -32554,7 +32757,7 @@ var require_detect_builders = __commonJS({
32554
32757
  });
32555
32758
  }
32556
32759
  builders.push(frontendBuilder);
32557
- if (hasNextApiFiles && apiBuilders.some((b) => (0, import_is_official_runtime.isOfficialRuntime)("node", b.use))) {
32760
+ if (hasNextApiFiles && apiBuilders.some((b) => isOfficialRuntime2("node", b.use))) {
32558
32761
  warnings.push({
32559
32762
  code: "conflicting_files",
32560
32763
  message: "When using Next.js, it is recommended to place JavaScript Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel). Other languages (Python, Go, etc) should still go in the `api` directory.",
@@ -32603,7 +32806,7 @@ var require_detect_builders = __commonJS({
32603
32806
  }
32604
32807
  if (fileName.endsWith(".py") && options.workPath) {
32605
32808
  const fsPath = (0, import_path7.join)(options.workPath, fileName);
32606
- const isEntrypoint = await (0, import_python.isPythonEntrypoint)(fsPath);
32809
+ const isEntrypoint = await isPythonEntrypoint(fsPath);
32607
32810
  if (!isEntrypoint) {
32608
32811
  return null;
32609
32812
  }
@@ -32611,7 +32814,7 @@ var require_detect_builders = __commonJS({
32611
32814
  const nodeExtensions = [".js", ".mjs", ".ts", ".tsx"];
32612
32815
  if (fileName.startsWith("api/") && process.env.VERCEL_NODE_FILTER_ENTRYPOINTS === "1" && nodeExtensions.some((ext) => fileName.endsWith(ext)) && options.workPath) {
32613
32816
  const fsPath = (0, import_path7.join)(options.workPath, fileName);
32614
- const isEntrypoint = await (0, import_build_utils5.isNodeEntrypoint)({ fsPath });
32817
+ const isEntrypoint = await (0, import_build_utils22.isNodeEntrypoint)({ fsPath });
32615
32818
  if (!isEntrypoint) {
32616
32819
  return null;
32617
32820
  }
@@ -32655,14 +32858,25 @@ var require_detect_builders = __commonJS({
32655
32858
  const func = keys.find((key) => key === fileName || (0, import_minimatch.default)(fileName, key));
32656
32859
  return func ? { fnPattern: func, func: functions[func] } : { fnPattern: null, func: null };
32657
32860
  }
32861
+ function parseProxyEntrypoint(entrypoint) {
32862
+ if (process.env.VERCEL_PYTHON_PROXY) {
32863
+ const parsed = (0, import_entrypoint.parsePyModuleAttrEntrypoint)(entrypoint);
32864
+ if (parsed)
32865
+ return { file: parsed.filePath, variable: parsed.attrName };
32866
+ }
32867
+ return { file: entrypoint };
32868
+ }
32658
32869
  function getProxyBuilder2(proxy, tag, functions = {}) {
32659
- const { fnPattern, func } = getFunction(proxy.entrypoint, { functions });
32870
+ const { file, variable } = parseProxyEntrypoint(proxy.entrypoint);
32871
+ const isPython = (0, import_path7.extname)(file) === ".py";
32872
+ const { fnPattern, func } = getFunction(file, { functions });
32660
32873
  const runtime = func?.runtime;
32661
32874
  const config = {
32662
32875
  zeroConfig: true,
32663
32876
  middleware: true,
32664
- ...!runtime ? { middlewareRuntime: "nodejs" } : {},
32665
- ...proxy.matcher ? { middlewareMatcher: proxy.matcher } : {}
32877
+ ...!runtime && !isPython ? { middlewareRuntime: "nodejs" } : {},
32878
+ ...proxy.matcher ? { middlewareMatcher: proxy.matcher } : {},
32879
+ ...variable ? { handlerFunction: variable } : {}
32666
32880
  };
32667
32881
  if (fnPattern && func) {
32668
32882
  config.functions = { [fnPattern]: func };
@@ -32673,9 +32887,10 @@ var require_detect_builders = __commonJS({
32673
32887
  config.excludeFiles = func.excludeFiles;
32674
32888
  }
32675
32889
  }
32890
+ const defaultRuntime = isPython ? `@vercel/python${tag ? `@${tag}` : ""}` : `@vercel/node${tag ? `@${tag}` : ""}`;
32676
32891
  return {
32677
- src: proxy.entrypoint,
32678
- use: runtime || `@vercel/node${tag ? `@${tag}` : ""}`,
32892
+ src: file,
32893
+ use: runtime || defaultRuntime,
32679
32894
  config
32680
32895
  };
32681
32896
  }
@@ -32698,21 +32913,29 @@ var require_detect_builders = __commonJS({
32698
32913
  if (typeof proxy !== "object" || typeof proxy.entrypoint !== "string" || !proxy.entrypoint) {
32699
32914
  return {
32700
32915
  code: "invalid_proxy",
32701
- message: "The `proxy` property must contain an `entrypoint` string that references a `.js` or `.ts` file."
32916
+ message: "The `proxy` property must contain an `entrypoint` string."
32702
32917
  };
32703
32918
  }
32704
- const entrypoint = proxy.entrypoint;
32705
- const segments = entrypoint.split("/");
32706
- if (entrypoint.startsWith("/") || entrypoint.includes("\\") || segments.includes(".") || segments.includes("..") || /[?#\u0000-\u001f]/.test(entrypoint)) {
32919
+ const { file, variable } = parseProxyEntrypoint(proxy.entrypoint);
32920
+ const isPythonForm = (0, import_path7.extname)(file) === ".py";
32921
+ const isJsForm = /\.(?:js|ts)$/.test(file) && !file.endsWith(".d.ts");
32922
+ const segments = file.split("/");
32923
+ if (file.startsWith("/") || file.includes("\\") || segments.includes(".") || segments.includes("..") || /[?#\u0000-\u001f]/.test(file)) {
32707
32924
  return {
32708
32925
  code: "invalid_proxy_entrypoint",
32709
32926
  message: "The `proxy.entrypoint` path must be relative to the project root and cannot contain traversal, query, fragment, or control characters."
32710
32927
  };
32711
32928
  }
32712
- if (!/\.(?:js|ts)$/.test(entrypoint) || entrypoint.endsWith(".d.ts")) {
32929
+ if (!isPythonForm && !isJsForm) {
32930
+ return {
32931
+ code: "invalid_proxy_entrypoint",
32932
+ message: "The `proxy.entrypoint` must be a `.js` or `.ts` file path, or a Python `module:attr`."
32933
+ };
32934
+ }
32935
+ if (isPythonForm && !variable) {
32713
32936
  return {
32714
32937
  code: "invalid_proxy_entrypoint",
32715
- message: "The `proxy.entrypoint` path must end in `.js` or `.ts` and reference an executable file."
32938
+ message: "Python proxy entrypoints must use `module:attr` syntax, not a plain `.py` path."
32716
32939
  };
32717
32940
  }
32718
32941
  if (proxy.matcher !== void 0) {
@@ -32737,10 +32960,11 @@ var require_detect_builders = __commonJS({
32737
32960
  if (configError) {
32738
32961
  return configError;
32739
32962
  }
32740
- if (!files.includes(proxy.entrypoint)) {
32963
+ const { file } = parseProxyEntrypoint(proxy.entrypoint);
32964
+ if (!files.includes(file)) {
32741
32965
  return {
32742
32966
  code: "proxy_entrypoint_not_found",
32743
- message: `The proxy entrypoint \`${proxy.entrypoint}\` does not exist. Set \`proxy.entrypoint\` to an existing \`.js\` or \`.ts\` file.`
32967
+ message: `The proxy entrypoint \`${proxy.entrypoint}\` does not exist.`
32744
32968
  };
32745
32969
  }
32746
32970
  if (framework === "nextjs" || framework === "astro") {
@@ -32749,6 +32973,15 @@ var require_detect_builders = __commonJS({
32749
32973
  message: `The \`proxy\` property cannot be used with ${framework === "nextjs" ? "Next.js" : "Astro"} because the framework builds its own routing middleware.`
32750
32974
  };
32751
32975
  }
32976
+ const appRuntime = (0, import_framework.inferBuilderRuntimeFromFramework)(framework);
32977
+ const { file: proxyFile } = parseProxyEntrypoint(proxy.entrypoint);
32978
+ const proxyRuntime = import_constants.ENTRYPOINT_EXTENSIONS[(0, import_path7.extname)(proxyFile)];
32979
+ if (appRuntime !== void 0 && proxyRuntime !== void 0 && appRuntime !== proxyRuntime) {
32980
+ return {
32981
+ code: "proxy_runtime_mismatch",
32982
+ message: `The proxy entrypoint \`${proxy.entrypoint}\` uses the ${proxyRuntime} runtime, but the app uses the ${appRuntime} runtime. The proxy and app must use the same runtime.`
32983
+ };
32984
+ }
32752
32985
  return null;
32753
32986
  }
32754
32987
  function hasBuildScript(pkg) {
@@ -32803,11 +33036,22 @@ var require_detect_builders = __commonJS({
32803
33036
  }
32804
33037
  });
32805
33038
  }
32806
- const f = slugToFramework.get(framework || "");
33039
+ const f = import_framework.frameworksBySlug.get(framework || "");
32807
33040
  if (f && f.useRuntime && !isRustStaticOutput(framework, projectSettings)) {
33041
+ const buildpackRuntime = toBuildpackRuntime(framework);
33042
+ if (buildpackRuntime && (BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? []).some(
33043
+ (marker) => files.includes(marker)
33044
+ )) {
33045
+ config.buildpack = buildpackRuntime;
33046
+ return {
33047
+ src: "<detect>",
33048
+ use: `@vercel/container${withTag}`,
33049
+ config
33050
+ };
33051
+ }
32808
33052
  const { src, use } = f.useRuntime;
32809
- const shouldUseUnifiedBackend = (0, import_build_utils5.isExperimentalBackendsEnabled)() && import_build_utils5.BACKEND_BUILDERS.includes(use);
32810
- const finalUse = shouldUseUnifiedBackend ? import_build_utils5.UNIFIED_BACKEND_BUILDER : use;
33053
+ const shouldUseUnifiedBackend = (0, import_build_utils22.isExperimentalBackendsEnabled)() && import_build_utils22.BACKEND_BUILDERS.includes(use);
33054
+ const finalUse = shouldUseUnifiedBackend ? import_build_utils22.UNIFIED_BACKEND_BUILDER : use;
32811
33055
  return { src, use: `${finalUse}${withTag}`, config };
32812
33056
  }
32813
33057
  const entrypoints = /* @__PURE__ */ new Set([
@@ -32852,7 +33096,7 @@ var require_detect_builders = __commonJS({
32852
33096
  message: "Function must contain at least one property."
32853
33097
  };
32854
33098
  }
32855
- const maxDurationLimit = (0, import_build_utils5.getMaxDurationLimit)();
33099
+ const maxDurationLimit = (0, import_build_utils22.getMaxDurationLimit)();
32856
33100
  if (func.maxDuration !== void 0 && func.maxDuration !== "max" && (func.maxDuration < 1 || maxDurationLimit !== void 0 && func.maxDuration > maxDurationLimit || !Number.isInteger(func.maxDuration))) {
32857
33101
  return {
32858
33102
  code: "invalid_function_duration",
@@ -32899,14 +33143,22 @@ var require_detect_builders = __commonJS({
32899
33143
  }
32900
33144
  return null;
32901
33145
  }
32902
- function checkUnusedFunctions(frontendBuilder, usedFunctions, options) {
33146
+ function checkUnusedFunctions(frontendBuilder, usedFunctions, claimedFiles, options) {
32903
33147
  const unusedFunctions = new Set(
32904
33148
  Object.keys(options.functions || {}).filter((key) => !usedFunctions.has(key))
32905
33149
  );
33150
+ for (const fnKey of unusedFunctions) {
33151
+ for (const filePath of claimedFiles) {
33152
+ if (filePath === fnKey || (0, import_minimatch.default)(filePath, fnKey)) {
33153
+ unusedFunctions.delete(fnKey);
33154
+ break;
33155
+ }
33156
+ }
33157
+ }
32906
33158
  if (!unusedFunctions.size) {
32907
33159
  return null;
32908
33160
  }
32909
- if (frontendBuilder && (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder.use)) {
33161
+ if (frontendBuilder && isOfficialRuntime2("next", frontendBuilder.use)) {
32910
33162
  for (const fnKey of unusedFunctions.values()) {
32911
33163
  if (fnKey.startsWith("pages/") || fnKey.startsWith("src/pages") || fnKey.startsWith("app/") || fnKey.startsWith("src/app/") || fnKey.startsWith("middleware") || fnKey.startsWith("src/middleware")) {
32912
33164
  unusedFunctions.delete(fnKey);
@@ -32920,7 +33172,7 @@ var require_detect_builders = __commonJS({
32920
33172
  }
32921
33173
  }
32922
33174
  }
32923
- if (frontendBuilder && ((0, import_is_official_runtime.isOfficialRuntime)("express", frontendBuilder.use) || (0, import_is_official_runtime.isOfficialRuntime)("hono", frontendBuilder.use) || (0, import_is_official_runtime.isOfficialRuntime)("python", frontendBuilder.use) || (0, import_is_official_runtime.isOfficialRuntime)("backends", frontendBuilder.use))) {
33175
+ if (frontendBuilder && (isOfficialRuntime2("express", frontendBuilder.use) || isOfficialRuntime2("hono", frontendBuilder.use) || isOfficialRuntime2("python", frontendBuilder.use) || isOfficialRuntime2("backends", frontendBuilder.use))) {
32924
33176
  return null;
32925
33177
  }
32926
33178
  if (unusedFunctions.size) {
@@ -33110,8 +33362,8 @@ var require_detect_builders = __commonJS({
33110
33362
  const errorRoutes = [];
33111
33363
  const framework = frontendBuilder?.config?.framework || "";
33112
33364
  const isGatsby = framework === "gatsby";
33113
- const isNextjs = framework === "nextjs" || (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder?.use);
33114
- const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
33365
+ const isNextjs = framework === "nextjs" || isOfficialRuntime2("next", frontendBuilder?.use);
33366
+ const ignoreRuntimes = import_framework.frameworksBySlug.get(framework)?.ignoreRuntimes;
33115
33367
  if (apiRoutes && apiRoutes.length > 0) {
33116
33368
  if (options.featHandleMiss) {
33117
33369
  const extSet = detectApiExtensions2(apiBuilders);
@@ -33159,7 +33411,7 @@ var require_detect_builders = __commonJS({
33159
33411
  }
33160
33412
  }
33161
33413
  }
33162
- if (outputDirectory && frontendBuilder && !options.featHandleMiss && (0, import_is_official_runtime.isOfficialRuntime)("static", frontendBuilder.use)) {
33414
+ if (outputDirectory && frontendBuilder && !options.featHandleMiss && isOfficialRuntime2("static", frontendBuilder.use)) {
33163
33415
  defaultRoutes.push({
33164
33416
  src: "/(.*)",
33165
33417
  dest: `/${outputDirectory}/$1`
@@ -35981,6 +36233,56 @@ var require_dist8 = __commonJS({
35981
36233
  }
35982
36234
  });
35983
36235
 
36236
+ // ../fs-detectors/dist/buildpack-runtimes.js
36237
+ var require_buildpack_runtimes = __commonJS({
36238
+ "../fs-detectors/dist/buildpack-runtimes.js"(exports, module2) {
36239
+ "use strict";
36240
+ var __defProp2 = Object.defineProperty;
36241
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
36242
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
36243
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
36244
+ var __export2 = (target, all) => {
36245
+ for (var name in all)
36246
+ __defProp2(target, name, { get: all[name], enumerable: true });
36247
+ };
36248
+ var __copyProps2 = (to, from, except, desc) => {
36249
+ if (from && typeof from === "object" || typeof from === "function") {
36250
+ for (let key of __getOwnPropNames2(from))
36251
+ if (!__hasOwnProp2.call(to, key) && key !== except)
36252
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
36253
+ }
36254
+ return to;
36255
+ };
36256
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
36257
+ var buildpack_runtimes_exports = {};
36258
+ __export2(buildpack_runtimes_exports, {
36259
+ BUILDPACK_PROJECT_MARKERS: () => BUILDPACK_PROJECT_MARKERS,
36260
+ hasBuildpackProjectMarker: () => hasBuildpackProjectMarker,
36261
+ isBuildpackRuntimeEnabled: () => isBuildpackRuntimeEnabled,
36262
+ toBuildpackRuntime: () => toBuildpackRuntime
36263
+ });
36264
+ module2.exports = __toCommonJS2(buildpack_runtimes_exports);
36265
+ var BUILDPACK_PROJECT_MARKERS = /* @__PURE__ */ new Map([["ruby", ["Gemfile"]]]);
36266
+ function isBuildpackRuntimeEnabled(runtime) {
36267
+ return process.env[`VERCEL_EXPERIMENTAL_BUILDPACK_${runtime.toUpperCase()}`] === "1";
36268
+ }
36269
+ function toBuildpackRuntime(runtime) {
36270
+ if (!runtime || !BUILDPACK_PROJECT_MARKERS.has(runtime) || !isBuildpackRuntimeEnabled(runtime)) {
36271
+ return void 0;
36272
+ }
36273
+ return runtime;
36274
+ }
36275
+ async function hasBuildpackProjectMarker(runtime, hasFile) {
36276
+ for (const marker of BUILDPACK_PROJECT_MARKERS.get(runtime) ?? []) {
36277
+ if (await hasFile(marker)) {
36278
+ return true;
36279
+ }
36280
+ }
36281
+ return false;
36282
+ }
36283
+ }
36284
+ });
36285
+
35984
36286
  // ../fs-detectors/dist/services/runtimes/constants.js
35985
36287
  var require_constants2 = __commonJS({
35986
36288
  "../fs-detectors/dist/services/runtimes/constants.js"(exports, module2) {
@@ -37339,6 +37641,7 @@ var require_detect_framework = __commonJS({
37339
37641
  module2.exports = __toCommonJS2(detect_framework_exports);
37340
37642
  var import_build_utils5 = require("@vercel/build-utils");
37341
37643
  var import_child_process2 = require("child_process");
37644
+ var import_buildpack_runtimes = require_buildpack_runtimes();
37342
37645
  function shouldIncludeExperimentalFrameworks(useExperimentalFrameworks) {
37343
37646
  if (typeof useExperimentalFrameworks === "boolean") {
37344
37647
  return useExperimentalFrameworks;
@@ -37353,7 +37656,10 @@ var require_detect_framework = __commonJS({
37353
37656
  }
37354
37657
  return frameworkList.filter((f) => {
37355
37658
  const experimental = f.experimental;
37356
- return !experimental;
37659
+ if (!experimental) {
37660
+ return true;
37661
+ }
37662
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(f.slug) !== void 0;
37357
37663
  });
37358
37664
  }
37359
37665
  async function matches(fs5, framework) {
@@ -37583,7 +37889,7 @@ var require_resolve = __commonJS({
37583
37889
  detectFrameworkFromWorkspace: () => detectFrameworkFromWorkspace,
37584
37890
  getServiceFs: () => getServiceFs,
37585
37891
  inferWorkspaceFromNearestManifest: () => inferWorkspaceFromNearestManifest,
37586
- resolveAllConfiguredServices: () => resolveAllConfiguredServices,
37892
+ resolveAllConfiguredServices: () => resolveAllConfiguredServices2,
37587
37893
  resolveConfiguredService: () => resolveConfiguredService,
37588
37894
  resolveEntrypointPath: () => resolveEntrypointPath,
37589
37895
  validateServiceConfig: () => validateServiceConfig,
@@ -37593,6 +37899,7 @@ var require_resolve = __commonJS({
37593
37899
  var import_path7 = require("path");
37594
37900
  var import_build_utils5 = require("@vercel/build-utils");
37595
37901
  var import_constants = require_constants2();
37902
+ var import_buildpack_runtimes = require_buildpack_runtimes();
37596
37903
  var import_framework = require_framework();
37597
37904
  var import_runtime3 = require_runtime();
37598
37905
  var import_entrypoint = require_entrypoint();
@@ -38073,6 +38380,15 @@ var require_resolve = __commonJS({
38073
38380
  };
38074
38381
  }
38075
38382
  if (hasBuilderOrRuntime && !hasFramework && !hasEntrypoint) {
38383
+ const buildpackRuntime = config.builder ? void 0 : (0, import_buildpack_runtimes.toBuildpackRuntime)(config.runtime);
38384
+ if (buildpackRuntime) {
38385
+ const markers = import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? [];
38386
+ return {
38387
+ code: "BUILDPACK_REQUIRES_SERVICES",
38388
+ message: `Service "${name}" must specify "entrypoint" when using "runtime" with "experimentalServices". Move it to "services" to build without an "entrypoint" from a ${markers.join(" or ")} at the service root.`,
38389
+ serviceName: name
38390
+ };
38391
+ }
38076
38392
  return {
38077
38393
  code: "MISSING_ENTRYPOINT",
38078
38394
  message: `Service "${name}" must specify "entrypoint" when using "${config.builder ? "builder" : "runtime"}".`,
@@ -38273,7 +38589,7 @@ var require_resolve = __commonJS({
38273
38589
  env: config.env
38274
38590
  };
38275
38591
  }
38276
- async function resolveAllConfiguredServices(services, fs5, routePrefixSource = "configured", options = {}) {
38592
+ async function resolveAllConfiguredServices2(services, fs5, routePrefixSource = "configured", options = {}) {
38277
38593
  const resolved = [];
38278
38594
  const errors = [];
38279
38595
  const webServicesByRoutePrefix = /* @__PURE__ */ new Map();
@@ -38488,7 +38804,9 @@ var require_resolve_v2 = __commonJS({
38488
38804
  var import_framework = require_framework();
38489
38805
  var import_runtime3 = require_runtime();
38490
38806
  var import_entrypoint = require_entrypoint();
38807
+ var import_buildpack_runtimes = require_buildpack_runtimes();
38491
38808
  var import_resolve = require_resolve();
38809
+ var import_utils = require_utils5();
38492
38810
  var frameworksBySlug = new Map(import_frameworks2.frameworkList.map((f) => [f.slug, f]));
38493
38811
  var MAX_SERVICE_NAME_LENGTH = 64;
38494
38812
  var SERVICE_NAME_REGEX = /^[a-z]([a-z_-]*[a-z])?$/;
@@ -38692,7 +39010,23 @@ var require_resolve_v2 = __commonJS({
38692
39010
  entrypoint: entrypointFile
38693
39011
  });
38694
39012
  }
38695
- if (entrypointIsDirectory && !framework) {
39013
+ const flaggedBuildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(
39014
+ inferredRuntime
39015
+ );
39016
+ if (flaggedBuildpackRuntime && config.command !== void 0) {
39017
+ return {
39018
+ error: {
39019
+ code: "INVALID_COMMAND",
39020
+ message: `Service "${name}" can only specify "command" when using runtime "container".`,
39021
+ serviceName: name
39022
+ }
39023
+ };
39024
+ }
39025
+ const buildpackRuntime = flaggedBuildpackRuntime && (!entrypointFile || flaggedBuildpackRuntime === "ruby" && entrypointFile === "config.ru") && !(0, import_framework.isFrontendFramework)(framework) && await (0, import_buildpack_runtimes.hasBuildpackProjectMarker)(
39026
+ flaggedBuildpackRuntime,
39027
+ (marker) => (0, import_utils.hasFile)(serviceFs, marker)
39028
+ ) ? flaggedBuildpackRuntime : void 0;
39029
+ if (entrypointIsDirectory && !framework && !buildpackRuntime) {
38696
39030
  return {
38697
39031
  error: {
38698
39032
  code: "MISSING_SERVICE_FRAMEWORK",
@@ -38702,7 +39036,7 @@ var require_resolve_v2 = __commonJS({
38702
39036
  };
38703
39037
  }
38704
39038
  const frameworkRuntime = (0, import_framework.inferRuntimeFromFramework)(framework);
38705
- if (detectedFramework && frameworkRuntime && !entrypointFile) {
39039
+ if (detectedFramework && frameworkRuntime && !entrypointFile && !buildpackRuntime) {
38706
39040
  return {
38707
39041
  error: {
38708
39042
  code: "MISSING_SERVICE_CONFIG",
@@ -38714,7 +39048,10 @@ var require_resolve_v2 = __commonJS({
38714
39048
  const frameworkDefinition = framework ? frameworksBySlug.get(framework) : void 0;
38715
39049
  let builderUse;
38716
39050
  let builderSrc;
38717
- if (framework) {
39051
+ if (buildpackRuntime) {
39052
+ builderUse = "@vercel/container";
39053
+ builderSrc = "<detect>";
39054
+ } else if (framework) {
38718
39055
  builderUse = (0, import_build_utils5.isNodeBackendFramework)(framework) ? "@vercel/backends" : frameworkDefinition?.useRuntime?.use || "@vercel/static-build";
38719
39056
  builderSrc = entrypointFile || frameworkDefinition?.useRuntime?.src || "package.json";
38720
39057
  } else {
@@ -38749,6 +39086,9 @@ var require_resolve_v2 = __commonJS({
38749
39086
  if (framework) {
38750
39087
  builderConfig.framework = framework;
38751
39088
  }
39089
+ if (buildpackRuntime) {
39090
+ builderConfig.buildpack = buildpackRuntime;
39091
+ }
38752
39092
  if (config.outputDirectory) {
38753
39093
  builderConfig.outputDirectory = config.outputDirectory;
38754
39094
  }
@@ -42732,6 +43072,7 @@ var require_detect_services = __commonJS({
42732
43072
  module2.exports = __toCommonJS2(detect_services_exports);
42733
43073
  var import_build_utils5 = require("@vercel/build-utils");
42734
43074
  var import_routing_utils = require_dist8();
43075
+ var import_buildpack_runtimes = require_buildpack_runtimes();
42735
43076
  var import_framework = require_framework();
42736
43077
  var import_utils = require_utils5();
42737
43078
  var import_resolve = require_resolve();
@@ -42767,6 +43108,11 @@ var require_detect_services = __commonJS({
42767
43108
  inferred
42768
43109
  };
42769
43110
  }
43111
+ function isBuildpackInferredService(svc) {
43112
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(
43113
+ svc.runtime ?? (0, import_framework.inferRuntimeFromFramework)(svc.framework)
43114
+ ) !== void 0;
43115
+ }
42770
43116
  function toInferredLayoutConfig(services) {
42771
43117
  const inferredConfig = {};
42772
43118
  for (const [name, service] of Object.entries(services)) {
@@ -42776,7 +43122,7 @@ var require_detect_services = __commonJS({
42776
43122
  if (service.type) {
42777
43123
  serviceConfig.type = service.type;
42778
43124
  }
42779
- if (typeof service.entrypoint === "string") {
43125
+ if (typeof service.entrypoint === "string" && !isBuildpackInferredService(service)) {
42780
43126
  serviceConfig.entrypoint = service.entrypoint;
42781
43127
  }
42782
43128
  if (typeof service.mountPath === "string") {
@@ -42919,7 +43265,7 @@ var require_detect_services = __commonJS({
42919
43265
  v2Services[name] = {
42920
43266
  root: svc.root,
42921
43267
  ...svc.framework ? { framework: svc.framework } : {},
42922
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {}
43268
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {}
42923
43269
  };
42924
43270
  }
42925
43271
  const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(v2Services, scopedFs);
@@ -42952,7 +43298,7 @@ var require_detect_services = __commonJS({
42952
43298
  v1Services[name] = {
42953
43299
  root: svc.root === "." ? void 0 : svc.root,
42954
43300
  ...svc.framework ? { framework: svc.framework } : {},
42955
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {},
43301
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {},
42956
43302
  ...svc.type ? { type: svc.type } : {},
42957
43303
  ...svc.buildCommand ? { buildCommand: svc.buildCommand } : {},
42958
43304
  ...svc.preDeployCommand ? { preDeployCommand: svc.preDeployCommand } : {},
@@ -43126,6 +43472,523 @@ var require_detect_services = __commonJS({
43126
43472
  }
43127
43473
  });
43128
43474
 
43475
+ // ../fs-detectors/dist/services/migrate.js
43476
+ var require_migrate = __commonJS({
43477
+ "../fs-detectors/dist/services/migrate.js"(exports, module2) {
43478
+ "use strict";
43479
+ var __defProp2 = Object.defineProperty;
43480
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
43481
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
43482
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
43483
+ var __export2 = (target, all) => {
43484
+ for (var name in all)
43485
+ __defProp2(target, name, { get: all[name], enumerable: true });
43486
+ };
43487
+ var __copyProps2 = (to, from, except, desc) => {
43488
+ if (from && typeof from === "object" || typeof from === "function") {
43489
+ for (let key of __getOwnPropNames2(from))
43490
+ if (!__hasOwnProp2.call(to, key) && key !== except)
43491
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
43492
+ }
43493
+ return to;
43494
+ };
43495
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
43496
+ var migrate_exports = {};
43497
+ __export2(migrate_exports, {
43498
+ hasLegacyServicesConfig: () => hasLegacyServicesConfig2,
43499
+ migrateExperimentalServices: () => migrateExperimentalServices2,
43500
+ planExperimentalServicesMigration: () => planExperimentalServicesMigration2
43501
+ });
43502
+ module2.exports = __toCommonJS2(migrate_exports);
43503
+ var import_path7 = require("path");
43504
+ var import_frameworks2 = require_frameworks();
43505
+ var import_constants = require_constants2();
43506
+ var import_resolve = require_resolve();
43507
+ var import_resolve_v2 = require_resolve_v2();
43508
+ var import_utils = require_utils5();
43509
+ var SERVICES_DOCS_URL = "https://vercel.com/docs/services";
43510
+ var SERVICES_ROUTING_DOCS_URL = "https://vercel.com/docs/services/routing";
43511
+ var SERVICES_BINDINGS_DOCS_URL = "https://vercel.com/docs/services/bindings";
43512
+ var EXPERIMENTAL_SERVICES_DOCS_URL = "https://vercel.com/docs/services/experimental";
43513
+ var TOP_LEVEL_BUILD_KEYS = [
43514
+ "functions",
43515
+ "installCommand",
43516
+ "buildCommand",
43517
+ "devCommand",
43518
+ "ignoreCommand",
43519
+ "outputDirectory",
43520
+ "framework"
43521
+ ];
43522
+ var PREVIEW_DOMAIN_MISSING = [
43523
+ { type: "host", value: { suf: ".vercel.app" } },
43524
+ { type: "host", value: { suf: ".vercel.dev" } }
43525
+ ];
43526
+ function hasLegacyServicesConfig2(config) {
43527
+ return isNonEmptyObject(config?.experimentalServices) || isNonEmptyObject(config?.experimentalServicesV2);
43528
+ }
43529
+ function isNonEmptyObject(value) {
43530
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length > 0;
43531
+ }
43532
+ function getServicesConfigConflict(config) {
43533
+ const keys = ["services", "experimentalServices", "experimentalServicesV2"].filter((key) => config[key] !== void 0);
43534
+ if (keys.length > 1) {
43535
+ return {
43536
+ code: "CONFLICTING_SERVICES_CONFIG",
43537
+ message: `Cannot migrate a configuration containing ${keys.map((key) => `\`${key}\``).join(" and ")}. Keep only the configuration you intend to migrate; existing services will not be overwritten or discarded.`
43538
+ };
43539
+ }
43540
+ return void 0;
43541
+ }
43542
+ function normalizePrefix(prefix) {
43543
+ const withSlash = prefix.startsWith("/") ? prefix : `/${prefix}`;
43544
+ return withSlash !== "/" ? withSlash.replace(/\/+$/, "") : withSlash;
43545
+ }
43546
+ function publicRewrite(prefix, service) {
43547
+ return {
43548
+ source: prefix === "/" ? "/(.*)" : `${prefix}(/.*)?`,
43549
+ destination: { service }
43550
+ };
43551
+ }
43552
+ function planExperimentalServicesMigration2(config, resolvedServices) {
43553
+ const conflict = getServicesConfigConflict(config);
43554
+ if (conflict)
43555
+ return emptyPlanWithErrors([conflict]);
43556
+ const plan = emptyPlanWithErrors([]);
43557
+ const legacy = config.experimentalServices;
43558
+ if (isNonEmptyObject(config.experimentalServicesV2)) {
43559
+ plan.patch.services = { ...config.experimentalServicesV2 };
43560
+ plan.removeKeys.push("experimentalServicesV2");
43561
+ return plan;
43562
+ }
43563
+ if (!isNonEmptyObject(legacy)) {
43564
+ plan.errors.push({
43565
+ code: "NO_LEGACY_SERVICES",
43566
+ message: "No `experimentalServices` configuration found to migrate."
43567
+ });
43568
+ return plan;
43569
+ }
43570
+ plan.removeKeys.push("experimentalServices");
43571
+ if (config.experimentalServiceGroups !== void 0) {
43572
+ plan.removeKeys.push("experimentalServiceGroups");
43573
+ plan.warnings.push({
43574
+ code: "SERVICE_GROUPS_DROPPED",
43575
+ message: "`experimentalServiceGroups` has no equivalent in `services` and was removed.",
43576
+ link: SERVICES_DOCS_URL
43577
+ });
43578
+ }
43579
+ const webServices = [];
43580
+ const resolvedByName = new Map(resolvedServices.map((s) => [s.name, s]));
43581
+ for (const [legacyName, serviceConfig] of Object.entries(legacy)) {
43582
+ const resolved = resolvedByName.get(legacyName);
43583
+ if (!resolved) {
43584
+ plan.errors.push({
43585
+ code: "UNRESOLVED_SERVICE",
43586
+ serviceName: legacyName,
43587
+ message: `Service "${legacyName}" could not be resolved. Fix the errors reported for it before migrating.`
43588
+ });
43589
+ continue;
43590
+ }
43591
+ if (resolved.type !== "web") {
43592
+ plan.unmigrated.push(getUnmigratedNote(legacyName, resolved));
43593
+ continue;
43594
+ }
43595
+ const name = legacyName.toLowerCase();
43596
+ if (name.length > 64 || !/^[a-z]([a-z_-]*[a-z])?$/.test(name)) {
43597
+ plan.errors.push({
43598
+ code: "INVALID_SERVICE_NAME",
43599
+ serviceName: legacyName,
43600
+ message: `Service name "${legacyName}" is not valid for \`services\`. Names must be 1-64 characters, start and end with a lowercase letter, and contain only lowercase letters, hyphens, and underscores. Rename it in \`experimentalServices\` first.`
43601
+ });
43602
+ continue;
43603
+ }
43604
+ const conflict2 = webServices.find((s) => s.name === name);
43605
+ if (conflict2) {
43606
+ plan.errors.push({
43607
+ code: "DUPLICATE_SERVICE_NAME",
43608
+ serviceName: legacyName,
43609
+ message: `Services "${conflict2.resolved.name}" and "${legacyName}" both map to "${name}". Rename one of them first.`
43610
+ });
43611
+ continue;
43612
+ }
43613
+ if (name !== legacyName) {
43614
+ plan.renamedServices.push({ from: legacyName, to: name });
43615
+ }
43616
+ webServices.push({
43617
+ name,
43618
+ resolved,
43619
+ config: serviceConfig,
43620
+ prefix: normalizePrefix(resolved.routePrefix ?? "/")
43621
+ });
43622
+ }
43623
+ if (plan.errors.length > 0)
43624
+ return plan;
43625
+ if (webServices.length === 0) {
43626
+ plan.errors.push({
43627
+ code: "NO_WEB_SERVICES",
43628
+ message: "None of the configured services are web services. `services` only describes web services; see the manual steps for the others."
43629
+ });
43630
+ return plan;
43631
+ }
43632
+ for (const consumer of webServices) {
43633
+ plan.patch.services[consumer.name] = convertWebService(
43634
+ consumer,
43635
+ webServices,
43636
+ plan,
43637
+ config.build?.env ?? {}
43638
+ );
43639
+ }
43640
+ const subpaths = webServices.filter((svc) => svc.prefix !== "/").sort((a, b) => b.prefix.length - a.prefix.length);
43641
+ plan.patch.rewrites = subpaths.map(
43642
+ (svc) => publicRewrite(svc.prefix, svc.name)
43643
+ );
43644
+ for (const { name, prefix, resolved } of subpaths) {
43645
+ const { subdomain } = resolved;
43646
+ if (!subdomain)
43647
+ continue;
43648
+ const hostRewrite = {
43649
+ source: "/(.*)",
43650
+ has: [{ type: "host", value: { pre: `${subdomain}.` } }],
43651
+ missing: PREVIEW_DOMAIN_MISSING,
43652
+ destination: { service: name }
43653
+ };
43654
+ if (resolved.builder.use === "@vercel/next") {
43655
+ plan.patch.rewrites.push({
43656
+ ...hostRewrite,
43657
+ source: "/",
43658
+ destination: { service: name, path: prefix }
43659
+ });
43660
+ hostRewrite.source = "/:path(.*)";
43661
+ hostRewrite.destination = { service: name, path: `${prefix}/:path` };
43662
+ }
43663
+ plan.patch.rewrites.push(hostRewrite);
43664
+ plan.warnings.push({
43665
+ code: "SUBDOMAIN_ROUTING",
43666
+ serviceName: resolved.name,
43667
+ message: `"${subdomain}.<your-domain>" routes to "${resolved.name}". Explicit service prefixes take precedence. Host routing still applies only to custom domains, not preview URLs.`,
43668
+ link: SERVICES_ROUTING_DOCS_URL
43669
+ });
43670
+ }
43671
+ plan.patch.rewrites.push(
43672
+ ...webServices.filter((svc) => svc.prefix === "/").map((svc) => publicRewrite("/", svc.name))
43673
+ );
43674
+ const rootService = webServices.find((s) => s.resolved.workspace === ".");
43675
+ for (const key of TOP_LEVEL_BUILD_KEYS) {
43676
+ const value = config[key];
43677
+ if (value === void 0)
43678
+ continue;
43679
+ plan.removeKeys.push(key);
43680
+ if (key === "framework" && (value === "services" || value === null))
43681
+ continue;
43682
+ if (!rootService) {
43683
+ plan.errors.push({
43684
+ code: "TOP_LEVEL_SETTING_WITHOUT_ROOT_SERVICE",
43685
+ message: `Top-level \`${key}\` is not allowed with \`services\` and there is no service with root "." to receive it. Move it into the relevant service manually.`
43686
+ });
43687
+ continue;
43688
+ }
43689
+ const target = plan.patch.services[rootService.name];
43690
+ if (key === "functions") {
43691
+ target.functions = {
43692
+ ...value,
43693
+ ...target.functions
43694
+ };
43695
+ } else if (value !== null && target[key] !== void 0) {
43696
+ plan.warnings.push({
43697
+ code: "TOP_LEVEL_SETTING_CONFLICT",
43698
+ serviceName: rootService.resolved.name,
43699
+ message: `Top-level \`${key}\` was dropped because service "${rootService.resolved.name}" already defines it.`
43700
+ });
43701
+ continue;
43702
+ } else if (value !== null) {
43703
+ target[key] = value;
43704
+ }
43705
+ plan.movedTopLevelKeys.push({ key, service: rootService.name });
43706
+ }
43707
+ if (Array.isArray(config.rewrites) && config.rewrites.length > 0) {
43708
+ plan.warnings.push({
43709
+ code: "EXISTING_REWRITES",
43710
+ message: "Your existing top-level `rewrites` are kept ahead of the generated service rewrites. They are evaluated before a request is routed into a service, so rewrites that target a path inside a specific service should move into that service's own `rewrites`.",
43711
+ link: SERVICES_ROUTING_DOCS_URL
43712
+ });
43713
+ }
43714
+ return plan;
43715
+ }
43716
+ function convertWebService(consumer, webServices, plan, existingBuildEnv) {
43717
+ const { resolved, config: serviceConfig, prefix } = consumer;
43718
+ const { name: legacyName, entrypoint } = resolved;
43719
+ const service = { root: resolved.workspace };
43720
+ const warn = (code, message, link) => {
43721
+ plan.warnings.push({
43722
+ code,
43723
+ serviceName: legacyName,
43724
+ message: `Service "${legacyName}": ${message}`,
43725
+ ...link ? { link } : {}
43726
+ });
43727
+ };
43728
+ if (serviceConfig.framework)
43729
+ service.framework = serviceConfig.framework;
43730
+ const runtime = serviceConfig.runtime;
43731
+ if (runtime) {
43732
+ if (runtime in import_constants.RUNTIME_BUILDERS) {
43733
+ service.runtime = runtime;
43734
+ } else {
43735
+ warn(
43736
+ "RUNTIME_DROPPED",
43737
+ `Runtime "${runtime}" is not supported (${Object.keys(import_constants.RUNTIME_BUILDERS).join(", ")}); it will be inferred from the entrypoint instead.`
43738
+ );
43739
+ }
43740
+ }
43741
+ if (entrypoint) {
43742
+ const handler = resolved.builder.config?.handlerFunction;
43743
+ service.entrypoint = typeof handler === "string" && entrypoint.endsWith(".py") ? `${entrypoint.slice(0, -3).replace(/\//g, ".")}:${handler}` : entrypoint;
43744
+ }
43745
+ if (serviceConfig.command !== void 0) {
43746
+ service.command = serviceConfig.command;
43747
+ }
43748
+ if (serviceConfig.installCommand !== void 0) {
43749
+ service.installCommand = serviceConfig.installCommand;
43750
+ }
43751
+ const buildCommand = (0, import_utils.combineBuildCommand)(
43752
+ serviceConfig.buildCommand,
43753
+ serviceConfig.preDeployCommand
43754
+ );
43755
+ if (buildCommand !== void 0)
43756
+ service.buildCommand = buildCommand;
43757
+ if (serviceConfig.preDeployCommand) {
43758
+ warn(
43759
+ "PRE_DEPLOY_COMMAND_FOLDED",
43760
+ "`preDeployCommand` was appended to `buildCommand` and now runs at build time, not right before deployment."
43761
+ );
43762
+ }
43763
+ if (serviceConfig.builder) {
43764
+ warn(
43765
+ "BUILDER_DROPPED",
43766
+ `Builder "${serviceConfig.builder}" was removed; \`services\` selects it from the framework and runtime.`
43767
+ );
43768
+ }
43769
+ if (serviceConfig.workspace) {
43770
+ warn("WORKSPACE_REPLACED", "`workspace` is now expressed by `root`.");
43771
+ }
43772
+ const fnConfig = {};
43773
+ for (const key of ["maxDuration", "includeFiles", "excludeFiles"]) {
43774
+ if (serviceConfig[key] !== void 0)
43775
+ fnConfig[key] = serviceConfig[key];
43776
+ }
43777
+ if (serviceConfig.memory !== void 0) {
43778
+ warn(
43779
+ "MEMORY_DROPPED",
43780
+ "`memory` cannot be configured in vercel.json with Fluid compute; use the project's Functions settings instead.",
43781
+ "https://vercel.com/docs/functions/configuring-functions/memory"
43782
+ );
43783
+ }
43784
+ if (Object.keys(fnConfig).length > 0) {
43785
+ if (entrypoint && resolved.runtime !== "container") {
43786
+ service.functions = {
43787
+ [import_path7.posix.normalize(entrypoint)]: fnConfig
43788
+ };
43789
+ } else {
43790
+ warn(
43791
+ "FUNCTION_CONFIG_DROPPED",
43792
+ `No file entrypoint for ${Object.keys(fnConfig).join(", ")}; configure them under this service's \`functions\` manually.`
43793
+ );
43794
+ }
43795
+ }
43796
+ const isStatic = (0, import_utils.isStaticBuild)(resolved);
43797
+ const rewrites = [];
43798
+ if (prefix !== "/") {
43799
+ if (isStatic || resolved.builder.use !== "@vercel/next") {
43800
+ rewrites.push({ source: `${prefix}/:path(.*)?`, destination: "/:path" });
43801
+ }
43802
+ if (isStatic) {
43803
+ rewrites.push({ source: "/:path*", destination: "/index.html" });
43804
+ warn(
43805
+ "STATIC_SUBPATH",
43806
+ `Static output is no longer nested under "${prefix}"; a service rewrite maps "${prefix}/*" onto it. Keep the framework base path (e.g. Vite \`base\`) at "${prefix}/".`,
43807
+ SERVICES_ROUTING_DOCS_URL
43808
+ );
43809
+ } else if (resolved.builder.use === "@vercel/next") {
43810
+ warn("NEXT_SUBPATH", `Keep \`basePath\` in next.config at "${prefix}".`);
43811
+ } else {
43812
+ warn(
43813
+ "PREFIX_STRIP",
43814
+ `A service rewrite keeps stripping "${prefix}", but ASGI \`root_path\` / WSGI \`SCRIPT_NAME\` is no longer set. Check redirects and generated URLs; remove the rewrite if the app should handle the prefix itself.`,
43815
+ SERVICES_ROUTING_DOCS_URL
43816
+ );
43817
+ }
43818
+ } else if (isStatic) {
43819
+ rewrites.push({ source: "/(.*)", destination: "/index.html" });
43820
+ }
43821
+ if (rewrites.length > 0)
43822
+ service.rewrites = rewrites;
43823
+ const bindings = [];
43824
+ const seenEnv = /* @__PURE__ */ new Set();
43825
+ const consumerPrefix = import_frameworks2.frameworkList.find(
43826
+ (f) => f.slug === resolved.framework
43827
+ )?.envPrefix;
43828
+ const bindingsUnsupported = resolved.runtime === "go" || resolved.runtime === "rust";
43829
+ const implicit = [];
43830
+ const clientSide = [];
43831
+ const unsupported = [];
43832
+ const add = (target, env, explicit) => {
43833
+ if (seenEnv.has(env))
43834
+ return;
43835
+ seenEnv.add(env);
43836
+ if (consumerPrefix && env.startsWith(consumerPrefix)) {
43837
+ if (Object.prototype.hasOwnProperty.call(existingBuildEnv, env))
43838
+ return;
43839
+ const defaults = (plan.patch.build ??= { env: {} }).env;
43840
+ if (defaults[env] !== void 0 && defaults[env] !== target.prefix) {
43841
+ plan.errors.push({
43842
+ code: "CONFLICTING_BUILD_ENV",
43843
+ serviceName: legacyName,
43844
+ message: `Services use \`${env}\` for different public paths. Set a shared value in \`build.env\` or use distinct environment variable names before migrating.`
43845
+ });
43846
+ } else {
43847
+ defaults[env] = target.prefix;
43848
+ }
43849
+ return;
43850
+ }
43851
+ if (isStatic) {
43852
+ if (explicit) {
43853
+ clientSide.push(`\`${env}="${target.prefix}"\``);
43854
+ }
43855
+ return;
43856
+ }
43857
+ if (bindingsUnsupported) {
43858
+ unsupported.push(`\`${env}\``);
43859
+ return;
43860
+ }
43861
+ if (!explicit)
43862
+ implicit.push(`\`${env}\``);
43863
+ bindings.push({
43864
+ type: "service",
43865
+ service: target.name,
43866
+ format: "url",
43867
+ env
43868
+ });
43869
+ };
43870
+ for (const [env, ref] of Object.entries(serviceConfig.env ?? {})) {
43871
+ if (ref?.type !== "service-ref")
43872
+ continue;
43873
+ const target = webServices.find((s) => s.resolved.name === ref.service);
43874
+ if (!target) {
43875
+ warn(
43876
+ "SERVICE_REF_DROPPED",
43877
+ `\`${env}\` referenced "${ref.service}", which is not a web service and cannot be bound.`
43878
+ );
43879
+ continue;
43880
+ }
43881
+ add(target, env, true);
43882
+ }
43883
+ for (const target of webServices) {
43884
+ const env = `${target.resolved.name.replace(/-/g, "_").toUpperCase()}_URL`;
43885
+ if (target !== consumer) {
43886
+ add(target, env, false);
43887
+ } else if (!seenEnv.has(env)) {
43888
+ seenEnv.add(env);
43889
+ warn(
43890
+ "SELF_SERVICE_URL_DROPPED",
43891
+ `Implicit self URL \`${env}\` is no longer injected; no self-binding was generated. If used at build time or on the server, define a project environment variable with the absolute public URL for "${prefix}" (including the origin), or derive it from the request.`,
43892
+ SERVICES_BINDINGS_DOCS_URL
43893
+ );
43894
+ }
43895
+ if (consumerPrefix)
43896
+ add(target, `${consumerPrefix}${env}`, false);
43897
+ }
43898
+ if (implicit.length > 0) {
43899
+ warn(
43900
+ "IMPLICIT_URL_TO_BINDING",
43901
+ `Previously implicit URLs now use bindings: ${implicit.join(", ")}. These resolve to internal URLs; remove unused bindings.`,
43902
+ SERVICES_BINDINGS_DOCS_URL
43903
+ );
43904
+ }
43905
+ if (clientSide.length > 0) {
43906
+ warn(
43907
+ "CLIENT_SIDE_SERVICE_URL",
43908
+ `Bindings only cover server-side calls. Define any client-side URLs still in use as project environment variables: ${clientSide.join(", ")}.`,
43909
+ SERVICES_BINDINGS_DOCS_URL
43910
+ );
43911
+ }
43912
+ if (unsupported.length > 0) {
43913
+ warn(
43914
+ "BINDINGS_UNSUPPORTED_RUNTIME",
43915
+ `The ${resolved.runtime} runtime does not support bindings; ${unsupported.join(", ")} will no longer be injected. Build a container image to use bindings, or call other services through public URLs.`,
43916
+ SERVICES_BINDINGS_DOCS_URL
43917
+ );
43918
+ }
43919
+ if (bindings.length > 0)
43920
+ service.bindings = bindings;
43921
+ return service;
43922
+ }
43923
+ function getUnmigratedNote(legacyName, resolved) {
43924
+ const isPython = resolved.runtime === "python";
43925
+ let guidance;
43926
+ if (resolved.type === "cron" || resolved.trigger === "schedule") {
43927
+ guidance = isPython ? "Declare the schedule in your Python app (for example with APScheduler in the web service) or expose the job as a route and add it to top-level `crons`." : "Expose the job as a route in a web service and add it to top-level `crons`.";
43928
+ } else if (resolved.trigger === "workflow") {
43929
+ guidance = isPython ? "Declare it as a `[[tool.vercel.workflows]]` entry in the owning service's pyproject.toml." : "Move it into a web service that uses the Workflow SDK.";
43930
+ } else {
43931
+ guidance = isPython ? "Declare it as a `[[tool.vercel.subscribers]]` entry in the owning service's pyproject.toml." : "Move the queue consumer into a web service that subscribes to the topic.";
43932
+ }
43933
+ return {
43934
+ code: "UNSUPPORTED_SERVICE_TYPE",
43935
+ serviceName: legacyName,
43936
+ message: `"${legacyName}" (type "${resolved.type}"${resolved.trigger ? `, trigger "${resolved.trigger}"` : ""}) has no equivalent in \`services\` and was left out. ${guidance}`,
43937
+ link: EXPERIMENTAL_SERVICES_DOCS_URL
43938
+ };
43939
+ }
43940
+ async function migrateExperimentalServices2(options) {
43941
+ const { fs: fs5 } = options;
43942
+ let { config, resolvedServices } = options;
43943
+ if (!config) {
43944
+ const read = await (0, import_utils.readVercelConfig)(fs5);
43945
+ if (read.error)
43946
+ return emptyPlanWithErrors([read.error]);
43947
+ config = read.config ?? {};
43948
+ }
43949
+ const conflict = getServicesConfigConflict(config);
43950
+ if (conflict)
43951
+ return emptyPlanWithErrors([conflict]);
43952
+ if (!resolvedServices && isNonEmptyObject(config.experimentalServices)) {
43953
+ const result = await (0, import_resolve.resolveAllConfiguredServices)(
43954
+ config.experimentalServices,
43955
+ fs5,
43956
+ "configured"
43957
+ );
43958
+ if (result.errors.length > 0) {
43959
+ return emptyPlanWithErrors(result.errors);
43960
+ }
43961
+ resolvedServices = result.services;
43962
+ }
43963
+ const plan = planExperimentalServicesMigration2(
43964
+ config,
43965
+ resolvedServices ?? []
43966
+ );
43967
+ if (plan.errors.length > 0)
43968
+ return plan;
43969
+ const check = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(plan.patch.services, fs5);
43970
+ plan.errors.push(
43971
+ ...check.errors.map((error) => ({
43972
+ ...error,
43973
+ message: `Generated \`services\` config is invalid: ${error.message}`
43974
+ }))
43975
+ );
43976
+ return plan;
43977
+ }
43978
+ function emptyPlanWithErrors(errors) {
43979
+ return {
43980
+ patch: { services: {}, rewrites: [] },
43981
+ removeKeys: [],
43982
+ movedTopLevelKeys: [],
43983
+ renamedServices: [],
43984
+ warnings: [],
43985
+ unmigrated: [],
43986
+ errors
43987
+ };
43988
+ }
43989
+ }
43990
+ });
43991
+
43129
43992
  // ../fs-detectors/dist/detect-file-system-api.js
43130
43993
  var require_detect_file_system_api = __commonJS({
43131
43994
  "../fs-detectors/dist/detect-file-system-api.js"(exports, module2) {
@@ -47493,6 +48356,45 @@ var require_monorepo_managers = __commonJS({
47493
48356
  }
47494
48357
  });
47495
48358
 
48359
+ // ../fs-detectors/dist/is-official-runtime.js
48360
+ var require_is_official_runtime = __commonJS({
48361
+ "../fs-detectors/dist/is-official-runtime.js"(exports, module2) {
48362
+ "use strict";
48363
+ var __defProp2 = Object.defineProperty;
48364
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
48365
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
48366
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
48367
+ var __export2 = (target, all) => {
48368
+ for (var name in all)
48369
+ __defProp2(target, name, { get: all[name], enumerable: true });
48370
+ };
48371
+ var __copyProps2 = (to, from, except, desc) => {
48372
+ if (from && typeof from === "object" || typeof from === "function") {
48373
+ for (let key of __getOwnPropNames2(from))
48374
+ if (!__hasOwnProp2.call(to, key) && key !== except)
48375
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
48376
+ }
48377
+ return to;
48378
+ };
48379
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
48380
+ var is_official_runtime_exports = {};
48381
+ __export2(is_official_runtime_exports, {
48382
+ isOfficialRuntime: () => isOfficialRuntime2,
48383
+ isStaticRuntime: () => isStaticRuntime2
48384
+ });
48385
+ module2.exports = __toCommonJS2(is_official_runtime_exports);
48386
+ var isOfficialRuntime2 = (desired, name) => {
48387
+ if (typeof name !== "string") {
48388
+ return false;
48389
+ }
48390
+ return name === `@vercel/${desired}` || name === `@now/${desired}` || name.startsWith(`@vercel/${desired}@`) || name.startsWith(`@now/${desired}@`);
48391
+ };
48392
+ var isStaticRuntime2 = (name) => {
48393
+ return isOfficialRuntime2("static", name);
48394
+ };
48395
+ }
48396
+ });
48397
+
47496
48398
  // ../fs-detectors/dist/package-managers/package-managers.js
47497
48399
  var require_package_managers = __commonJS({
47498
48400
  "../fs-detectors/dist/package-managers/package-managers.js"(exports, module2) {
@@ -47915,14 +48817,18 @@ var require_dist9 = __commonJS({
47915
48817
  getProxyBuilder: () => import_detect_builders.getProxyBuilder,
47916
48818
  getWorkspacePackagePaths: () => import_get_workspace_package_paths.getWorkspacePackagePaths,
47917
48819
  getWorkspaces: () => import_get_workspaces.getWorkspaces,
48820
+ hasLegacyServicesConfig: () => import_migrate.hasLegacyServicesConfig,
47918
48821
  isExperimentalService: () => import_build_utils5.isExperimentalService,
47919
48822
  isExperimentalServiceV2: () => import_build_utils5.isExperimentalServiceV2,
47920
48823
  isOfficialRuntime: () => import_is_official_runtime.isOfficialRuntime,
47921
48824
  isRouteOwningBuilder: () => import_utils.isRouteOwningBuilder,
47922
48825
  isStaticBuild: () => import_utils.isStaticBuild,
47923
48826
  isStaticRuntime: () => import_is_official_runtime.isStaticRuntime,
48827
+ migrateExperimentalServices: () => import_migrate.migrateExperimentalServices,
47924
48828
  monorepoManagers: () => import_monorepo_managers.monorepoManagers,
47925
48829
  packageManagers: () => import_package_managers.packageManagers,
48830
+ planExperimentalServicesMigration: () => import_migrate.planExperimentalServicesMigration,
48831
+ resolveAllConfiguredServices: () => import_resolve.resolveAllConfiguredServices,
47926
48832
  resolveAllConfiguredServicesV2: () => import_resolve_v2.resolveAllConfiguredServicesV2,
47927
48833
  resolveConfiguredServiceV2: () => import_resolve_v2.resolveConfiguredServiceV2,
47928
48834
  validateProxy: () => import_detect_builders.validateProxy,
@@ -47934,6 +48840,8 @@ var require_dist9 = __commonJS({
47934
48840
  var import_detect_builders = require_detect_builders();
47935
48841
  var import_detect_services = require_detect_services();
47936
48842
  var import_resolve_v2 = require_resolve_v2();
48843
+ var import_resolve = require_resolve();
48844
+ var import_migrate = require_migrate();
47937
48845
  var import_build_utils5 = require("@vercel/build-utils");
47938
48846
  var import_auto_detect = require_auto_detect();
47939
48847
  var import_utils = require_utils5();