@vercel/static-build 10.0.0 → 10.0.2

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 +883 -55
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -19035,6 +19035,187 @@ var require_semver3 = __commonJS({
19035
19035
  }
19036
19036
  });
19037
19037
 
19038
+ // ../../internals/runtimes/dist/constants.js
19039
+ var require_constants2 = __commonJS({
19040
+ "../../internals/runtimes/dist/constants.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 constants_exports = {};
19060
+ __export2(constants_exports, {
19061
+ BUILDER_RUNTIMES: () => BUILDER_RUNTIMES,
19062
+ CONTAINER_ENTRYPOINT_CANDIDATES: () => CONTAINER_ENTRYPOINT_CANDIDATES,
19063
+ ENTRYPOINT_EXTENSIONS: () => ENTRYPOINT_EXTENSIONS,
19064
+ ROUTE_OWNING_BUILDERS: () => ROUTE_OWNING_BUILDERS,
19065
+ RUNTIME_BUILDERS: () => RUNTIME_BUILDERS,
19066
+ RUNTIME_MANIFESTS: () => RUNTIME_MANIFESTS,
19067
+ STATIC_BUILDERS: () => STATIC_BUILDERS
19068
+ });
19069
+ module2.exports = __toCommonJS2(constants_exports);
19070
+ var RUNTIME_BUILDERS = {
19071
+ node: "@vercel/backends",
19072
+ python: "@vercel/python",
19073
+ go: "@vercel/go",
19074
+ rust: "@vercel/rust",
19075
+ ruby: "@vercel/ruby",
19076
+ container: "@vercel/container"
19077
+ };
19078
+ var RUNTIME_MANIFESTS = {
19079
+ node: ["package.json"],
19080
+ python: [
19081
+ "pyproject.toml",
19082
+ "requirements.txt",
19083
+ "Pipfile",
19084
+ "pylock.yml",
19085
+ "uv.lock",
19086
+ "setup.py"
19087
+ ],
19088
+ go: ["go.mod"],
19089
+ ruby: ["Gemfile"],
19090
+ rust: ["Cargo.toml"]
19091
+ };
19092
+ var ENTRYPOINT_EXTENSIONS = {
19093
+ ".ts": "node",
19094
+ ".mts": "node",
19095
+ ".js": "node",
19096
+ ".mjs": "node",
19097
+ ".cjs": "node",
19098
+ ".py": "python",
19099
+ ".go": "go",
19100
+ ".rs": "rust",
19101
+ ".rb": "ruby",
19102
+ ".ru": "ruby"
19103
+ };
19104
+ var BUILDER_RUNTIMES = Object.fromEntries(
19105
+ Object.entries(RUNTIME_BUILDERS).map(([runtime, builder]) => [
19106
+ builder,
19107
+ runtime
19108
+ ])
19109
+ );
19110
+ var STATIC_BUILDERS = /* @__PURE__ */ new Set([
19111
+ "@vercel/static-build",
19112
+ "@vercel/static"
19113
+ ]);
19114
+ var ROUTE_OWNING_BUILDERS = /* @__PURE__ */ new Set([
19115
+ "@vercel/next",
19116
+ "@vercel/backends"
19117
+ ]);
19118
+ var CONTAINER_ENTRYPOINT_CANDIDATES = [
19119
+ "Dockerfile.vercel",
19120
+ "Containerfile.vercel",
19121
+ "Dockerfile",
19122
+ "Containerfile"
19123
+ ];
19124
+ }
19125
+ });
19126
+
19127
+ // ../../internals/runtimes/dist/framework.js
19128
+ var require_framework = __commonJS({
19129
+ "../../internals/runtimes/dist/framework.js"(exports, module2) {
19130
+ "use strict";
19131
+ var __defProp2 = Object.defineProperty;
19132
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
19133
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
19134
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
19135
+ var __export2 = (target, all) => {
19136
+ for (var name in all)
19137
+ __defProp2(target, name, { get: all[name], enumerable: true });
19138
+ };
19139
+ var __copyProps2 = (to, from, except, desc) => {
19140
+ if (from && typeof from === "object" || typeof from === "function") {
19141
+ for (let key of __getOwnPropNames2(from))
19142
+ if (!__hasOwnProp2.call(to, key) && key !== except)
19143
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
19144
+ }
19145
+ return to;
19146
+ };
19147
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
19148
+ var framework_exports = {};
19149
+ __export2(framework_exports, {
19150
+ DETECTION_FRAMEWORKS: () => DETECTION_FRAMEWORKS,
19151
+ filterFrameworksByRuntime: () => filterFrameworksByRuntime,
19152
+ frameworksBySlug: () => frameworksBySlug,
19153
+ inferBuilderRuntimeFromFramework: () => inferBuilderRuntimeFromFramework,
19154
+ inferRuntimeFromFramework: () => inferRuntimeFromFramework,
19155
+ isBFFFramework: () => isBFFFramework,
19156
+ isFrontendFramework: () => isFrontendFramework
19157
+ });
19158
+ module2.exports = __toCommonJS2(framework_exports);
19159
+ var import_build_utils5 = require("@vercel/build-utils");
19160
+ var import_frameworks2 = require_frameworks();
19161
+ var import_constants = require_constants2();
19162
+ var frameworksBySlug = new Map(
19163
+ import_frameworks2.frameworkList.flatMap((f) => typeof f.slug === "string" ? [[f.slug, f]] : [])
19164
+ );
19165
+ var DETECTION_FRAMEWORKS = import_frameworks2.frameworkList.filter(
19166
+ (framework) => !framework.experimental || framework.runtimeFramework
19167
+ );
19168
+ function inferRuntimeFromFramework(framework) {
19169
+ if (!framework)
19170
+ return void 0;
19171
+ if (framework in import_constants.RUNTIME_BUILDERS)
19172
+ return framework;
19173
+ if ((0, import_build_utils5.isPythonFramework)(framework))
19174
+ return "python";
19175
+ if ((0, import_build_utils5.isBackendFramework)(framework))
19176
+ return "node";
19177
+ return void 0;
19178
+ }
19179
+ var STATIC_BUILDER_RUNTIMES = {
19180
+ hugo: "go",
19181
+ jekyll: "ruby",
19182
+ middleman: "ruby",
19183
+ zola: "rust"
19184
+ };
19185
+ function inferBuilderRuntimeFromFramework(framework) {
19186
+ if (!framework || framework === "container" || framework === "services")
19187
+ return void 0;
19188
+ const f = frameworksBySlug.get(framework);
19189
+ const declaredBuilder = f?.useRuntime?.use;
19190
+ if (declaredBuilder)
19191
+ return import_constants.BUILDER_RUNTIMES[declaredBuilder];
19192
+ const detectorItems = [
19193
+ ...f?.detectors?.every ?? [],
19194
+ ...f?.detectors?.some ?? []
19195
+ ];
19196
+ return STATIC_BUILDER_RUNTIMES[framework] ?? (detectorItems.some((d) => d.matchPackage !== void 0) ? "node" : void 0);
19197
+ }
19198
+ function isFrontendFramework(framework) {
19199
+ return !!framework && !inferRuntimeFromFramework(framework);
19200
+ }
19201
+ var BFF_FRAMEWORKS = /* @__PURE__ */ new Set([
19202
+ "nextjs",
19203
+ "nuxtjs",
19204
+ "sveltekit",
19205
+ "remix",
19206
+ "solidstart"
19207
+ ]);
19208
+ function isBFFFramework(framework) {
19209
+ return !!framework && BFF_FRAMEWORKS.has(framework);
19210
+ }
19211
+ function filterFrameworksByRuntime(frameworks2, runtime) {
19212
+ if (!runtime)
19213
+ return [...frameworks2];
19214
+ return frameworks2.filter((f) => inferRuntimeFromFramework(f.slug) === runtime);
19215
+ }
19216
+ }
19217
+ });
19218
+
19038
19219
  // ../fs-detectors/dist/is-official-runtime.js
19039
19220
  var require_is_official_runtime = __commonJS({
19040
19221
  "../fs-detectors/dist/is-official-runtime.js"(exports, module2) {
@@ -32212,6 +32393,56 @@ var require_python = __commonJS({
32212
32393
  }
32213
32394
  });
32214
32395
 
32396
+ // ../fs-detectors/dist/buildpack-runtimes.js
32397
+ var require_buildpack_runtimes = __commonJS({
32398
+ "../fs-detectors/dist/buildpack-runtimes.js"(exports, module2) {
32399
+ "use strict";
32400
+ var __defProp2 = Object.defineProperty;
32401
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
32402
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
32403
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
32404
+ var __export2 = (target, all) => {
32405
+ for (var name in all)
32406
+ __defProp2(target, name, { get: all[name], enumerable: true });
32407
+ };
32408
+ var __copyProps2 = (to, from, except, desc) => {
32409
+ if (from && typeof from === "object" || typeof from === "function") {
32410
+ for (let key of __getOwnPropNames2(from))
32411
+ if (!__hasOwnProp2.call(to, key) && key !== except)
32412
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
32413
+ }
32414
+ return to;
32415
+ };
32416
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
32417
+ var buildpack_runtimes_exports = {};
32418
+ __export2(buildpack_runtimes_exports, {
32419
+ BUILDPACK_PROJECT_MARKERS: () => BUILDPACK_PROJECT_MARKERS,
32420
+ hasBuildpackProjectMarker: () => hasBuildpackProjectMarker,
32421
+ isBuildpackRuntimeEnabled: () => isBuildpackRuntimeEnabled,
32422
+ toBuildpackRuntime: () => toBuildpackRuntime
32423
+ });
32424
+ module2.exports = __toCommonJS2(buildpack_runtimes_exports);
32425
+ var BUILDPACK_PROJECT_MARKERS = /* @__PURE__ */ new Map([["ruby", ["Gemfile"]]]);
32426
+ function isBuildpackRuntimeEnabled(runtime) {
32427
+ return process.env[`VERCEL_EXPERIMENTAL_BUILDPACK_${runtime.toUpperCase()}`] === "1";
32428
+ }
32429
+ function toBuildpackRuntime(runtime) {
32430
+ if (!runtime || !BUILDPACK_PROJECT_MARKERS.has(runtime) || !isBuildpackRuntimeEnabled(runtime)) {
32431
+ return void 0;
32432
+ }
32433
+ return runtime;
32434
+ }
32435
+ async function hasBuildpackProjectMarker(runtime, hasFile) {
32436
+ for (const marker of BUILDPACK_PROJECT_MARKERS.get(runtime) ?? []) {
32437
+ if (await hasFile(marker)) {
32438
+ return true;
32439
+ }
32440
+ }
32441
+ return false;
32442
+ }
32443
+ }
32444
+ });
32445
+
32215
32446
  // ../fs-detectors/dist/detect-builders.js
32216
32447
  var require_detect_builders = __commonJS({
32217
32448
  "../fs-detectors/dist/detect-builders.js"(exports, module2) {
@@ -32263,9 +32494,12 @@ var require_detect_builders = __commonJS({
32263
32494
  var import_semver2 = require_semver3();
32264
32495
  var import_path7 = require("path");
32265
32496
  var import_frameworks2 = require_frameworks();
32497
+ var import_framework = require_framework();
32498
+ var import_constants = require_constants2();
32266
32499
  var import_is_official_runtime = require_is_official_runtime();
32267
32500
  var import_build_utils5 = require("@vercel/build-utils");
32268
32501
  var import_python = require_python();
32502
+ var import_buildpack_runtimes = require_buildpack_runtimes();
32269
32503
  var REGEX_MIDDLEWARE_FILES = "middleware.[jt]s";
32270
32504
  var VERCEL_PLATFORM_FILES = [
32271
32505
  "api/**",
@@ -32291,9 +32525,6 @@ var require_detect_builders = __commonJS({
32291
32525
  ].join(",")}}`;
32292
32526
  }
32293
32527
  var REGEX_NON_VERCEL_PLATFORM_FILES2 = getStaticFilesPattern();
32294
- var slugToFramework = new Map(
32295
- import_frameworks2.frameworkList.map((f) => [f.slug, f])
32296
- );
32297
32528
  var builderToFrameworks2 = (() => {
32298
32529
  const map = /* @__PURE__ */ new Map();
32299
32530
  for (const f of import_frameworks2.frameworkList) {
@@ -32378,7 +32609,7 @@ var require_detect_builders = __commonJS({
32378
32609
  };
32379
32610
  const absolutePathCache = /* @__PURE__ */ new Map();
32380
32611
  const { buildCommand, outputDirectory } = projectSettings;
32381
- const frameworkConfig = slugToFramework.get(framework || "");
32612
+ const frameworkConfig = import_framework.frameworksBySlug.get(framework || "");
32382
32613
  const rustStaticOutput = isRustStaticOutput(framework, projectSettings);
32383
32614
  const ignoreRuntimes = new Set(
32384
32615
  rustStaticOutput ? void 0 : frameworkConfig?.ignoreRuntimes
@@ -32749,6 +32980,14 @@ var require_detect_builders = __commonJS({
32749
32980
  message: `The \`proxy\` property cannot be used with ${framework === "nextjs" ? "Next.js" : "Astro"} because the framework builds its own routing middleware.`
32750
32981
  };
32751
32982
  }
32983
+ const appRuntime = (0, import_framework.inferBuilderRuntimeFromFramework)(framework);
32984
+ const proxyRuntime = import_constants.ENTRYPOINT_EXTENSIONS[(0, import_path7.extname)(proxy.entrypoint)];
32985
+ if (appRuntime !== void 0 && proxyRuntime !== void 0 && appRuntime !== proxyRuntime) {
32986
+ return {
32987
+ code: "proxy_runtime_mismatch",
32988
+ 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.`
32989
+ };
32990
+ }
32752
32991
  return null;
32753
32992
  }
32754
32993
  function hasBuildScript(pkg) {
@@ -32803,8 +33042,19 @@ var require_detect_builders = __commonJS({
32803
33042
  }
32804
33043
  });
32805
33044
  }
32806
- const f = slugToFramework.get(framework || "");
33045
+ const f = import_framework.frameworksBySlug.get(framework || "");
32807
33046
  if (f && f.useRuntime && !isRustStaticOutput(framework, projectSettings)) {
33047
+ const buildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(framework);
33048
+ if (buildpackRuntime && (import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? []).some(
33049
+ (marker) => files.includes(marker)
33050
+ )) {
33051
+ config.buildpack = buildpackRuntime;
33052
+ return {
33053
+ src: "<detect>",
33054
+ use: `@vercel/container${withTag}`,
33055
+ config
33056
+ };
33057
+ }
32808
33058
  const { src, use } = f.useRuntime;
32809
33059
  const shouldUseUnifiedBackend = (0, import_build_utils5.isExperimentalBackendsEnabled)() && import_build_utils5.BACKEND_BUILDERS.includes(use);
32810
33060
  const finalUse = shouldUseUnifiedBackend ? import_build_utils5.UNIFIED_BACKEND_BUILDER : use;
@@ -33111,7 +33361,7 @@ var require_detect_builders = __commonJS({
33111
33361
  const framework = frontendBuilder?.config?.framework || "";
33112
33362
  const isGatsby = framework === "gatsby";
33113
33363
  const isNextjs = framework === "nextjs" || (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder?.use);
33114
- const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
33364
+ const ignoreRuntimes = import_framework.frameworksBySlug.get(framework)?.ignoreRuntimes;
33115
33365
  if (apiRoutes && apiRoutes.length > 0) {
33116
33366
  if (options.featHandleMiss) {
33117
33367
  const extSet = detectApiExtensions2(apiBuilders);
@@ -34582,6 +34832,24 @@ var require_merge3 = __commonJS({
34582
34832
  }
34583
34833
  return builderRoutes;
34584
34834
  }
34835
+ function addToHandleMap(path6, routesMapping, handleMap) {
34836
+ const br = routesMapping[path6];
34837
+ Object.keys(br).sort().forEach((use) => {
34838
+ let prevHandle = null;
34839
+ br[use].forEach((route) => {
34840
+ if ((0, import_index.isHandler)(route)) {
34841
+ prevHandle = route.handle;
34842
+ } else {
34843
+ const routes = handleMap.get(prevHandle);
34844
+ if (!routes) {
34845
+ handleMap.set(prevHandle, [route]);
34846
+ } else {
34847
+ routes.push(route);
34848
+ }
34849
+ }
34850
+ });
34851
+ });
34852
+ }
34585
34853
  function getCheckAndContinue(routes) {
34586
34854
  const checks = [];
34587
34855
  const continues = [];
@@ -34618,43 +34886,36 @@ var require_merge3 = __commonJS({
34618
34886
  }
34619
34887
  }
34620
34888
  });
34889
+ const projectHandleMap = /* @__PURE__ */ new Map();
34890
+ const projectMiddlewareRoutes = getBuilderRoutesMapping(
34891
+ builds.filter((b) => b.projectMiddleware)
34892
+ );
34893
+ Object.keys(projectMiddlewareRoutes).sort().forEach(
34894
+ (path6) => addToHandleMap(path6, projectMiddlewareRoutes, projectHandleMap)
34895
+ );
34621
34896
  const builderHandleMap = /* @__PURE__ */ new Map();
34622
- const builderRoutes = getBuilderRoutesMapping(builds);
34623
- const sortedPaths = Object.keys(builderRoutes).sort();
34624
- sortedPaths.forEach((path6) => {
34625
- const br = builderRoutes[path6];
34626
- const sortedBuilders = Object.keys(br).sort();
34627
- sortedBuilders.forEach((use) => {
34628
- let builderPrevHandle = null;
34629
- br[use].forEach((route) => {
34630
- if ((0, import_index.isHandler)(route)) {
34631
- builderPrevHandle = route.handle;
34632
- } else {
34633
- const routes = builderHandleMap.get(builderPrevHandle);
34634
- if (!routes) {
34635
- builderHandleMap.set(builderPrevHandle, [route]);
34636
- } else {
34637
- routes.push(route);
34638
- }
34639
- }
34640
- });
34641
- });
34642
- });
34897
+ const builderRoutes = getBuilderRoutesMapping(
34898
+ builds.filter((b) => !b.projectMiddleware)
34899
+ );
34900
+ Object.keys(builderRoutes).sort().forEach((path6) => addToHandleMap(path6, builderRoutes, builderHandleMap));
34643
34901
  const outputRoutes = [];
34644
34902
  const uniqueHandleValues = /* @__PURE__ */ new Set([
34645
34903
  null,
34646
34904
  ...userHandleMap.keys(),
34905
+ ...projectHandleMap.keys(),
34647
34906
  ...builderHandleMap.keys()
34648
34907
  ]);
34649
34908
  for (const handle of uniqueHandleValues) {
34650
34909
  const userRoutes2 = userHandleMap.get(handle) || [];
34910
+ const projectRoutes = projectHandleMap.get(handle) || [];
34651
34911
  const builderRoutes2 = builderHandleMap.get(handle) || [];
34652
34912
  const builderSorted = getCheckAndContinue(builderRoutes2);
34653
- if (handle !== null && (userRoutes2.length > 0 || builderRoutes2.length > 0)) {
34913
+ if (handle !== null && (userRoutes2.length > 0 || projectRoutes.length > 0 || builderRoutes2.length > 0)) {
34654
34914
  outputRoutes.push({ handle });
34655
34915
  }
34656
34916
  outputRoutes.push(...builderSorted.continues);
34657
34917
  outputRoutes.push(...userRoutes2);
34918
+ outputRoutes.push(...projectRoutes);
34658
34919
  outputRoutes.push(...builderSorted.checks);
34659
34920
  outputRoutes.push(...builderSorted.others);
34660
34921
  }
@@ -35971,7 +36232,7 @@ var require_dist8 = __commonJS({
35971
36232
  });
35972
36233
 
35973
36234
  // ../fs-detectors/dist/services/runtimes/constants.js
35974
- var require_constants2 = __commonJS({
36235
+ var require_constants3 = __commonJS({
35975
36236
  "../fs-detectors/dist/services/runtimes/constants.js"(exports, module2) {
35976
36237
  "use strict";
35977
36238
  var __defProp2 = Object.defineProperty;
@@ -36053,7 +36314,7 @@ var require_constants2 = __commonJS({
36053
36314
  });
36054
36315
 
36055
36316
  // ../fs-detectors/dist/services/runtimes/framework.js
36056
- var require_framework = __commonJS({
36317
+ var require_framework2 = __commonJS({
36057
36318
  "../fs-detectors/dist/services/runtimes/framework.js"(exports, module2) {
36058
36319
  "use strict";
36059
36320
  var __defProp2 = Object.defineProperty;
@@ -36084,7 +36345,7 @@ var require_framework = __commonJS({
36084
36345
  module2.exports = __toCommonJS2(framework_exports);
36085
36346
  var import_build_utils5 = require("@vercel/build-utils");
36086
36347
  var import_frameworks2 = require_frameworks();
36087
- var import_constants = require_constants2();
36348
+ var import_constants = require_constants3();
36088
36349
  var DETECTION_FRAMEWORKS = import_frameworks2.frameworkList.filter(
36089
36350
  (framework) => !framework.experimental || framework.runtimeFramework
36090
36351
  );
@@ -37078,8 +37339,8 @@ var require_utils5 = __commonJS({
37078
37339
  });
37079
37340
  module2.exports = __toCommonJS2(utils_exports);
37080
37341
  var import_build_utils5 = require("@vercel/build-utils");
37081
- var import_constants = require_constants2();
37082
- var import_framework = require_framework();
37342
+ var import_constants = require_constants3();
37343
+ var import_framework = require_framework2();
37083
37344
  async function hasFile(fs5, filePath) {
37084
37345
  try {
37085
37346
  return await fs5.isFile(filePath);
@@ -37203,8 +37464,8 @@ var require_runtime = __commonJS({
37203
37464
  inferRuntime: () => inferRuntime
37204
37465
  });
37205
37466
  module2.exports = __toCommonJS2(runtime_exports);
37206
- var import_constants = require_constants2();
37207
- var import_framework = require_framework();
37467
+ var import_constants = require_constants3();
37468
+ var import_framework = require_framework2();
37208
37469
  function getBuilderForRuntime(runtime) {
37209
37470
  const builder = import_constants.RUNTIME_BUILDERS[runtime];
37210
37471
  if (!builder)
@@ -37267,7 +37528,7 @@ var require_entrypoint = __commonJS({
37267
37528
  });
37268
37529
  module2.exports = __toCommonJS2(entrypoint_exports);
37269
37530
  var import_path7 = require("path");
37270
- var import_constants = require_constants2();
37531
+ var import_constants = require_constants3();
37271
37532
  var PYTHON_MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
37272
37533
  function parsePyModuleAttrEntrypoint(entrypoint) {
37273
37534
  const match = PYTHON_MODULE_ATTR_RE.exec(entrypoint);
@@ -37328,6 +37589,7 @@ var require_detect_framework = __commonJS({
37328
37589
  module2.exports = __toCommonJS2(detect_framework_exports);
37329
37590
  var import_build_utils5 = require("@vercel/build-utils");
37330
37591
  var import_child_process2 = require("child_process");
37592
+ var import_buildpack_runtimes = require_buildpack_runtimes();
37331
37593
  function shouldIncludeExperimentalFrameworks(useExperimentalFrameworks) {
37332
37594
  if (typeof useExperimentalFrameworks === "boolean") {
37333
37595
  return useExperimentalFrameworks;
@@ -37342,7 +37604,10 @@ var require_detect_framework = __commonJS({
37342
37604
  }
37343
37605
  return frameworkList.filter((f) => {
37344
37606
  const experimental = f.experimental;
37345
- return !experimental;
37607
+ if (!experimental) {
37608
+ return true;
37609
+ }
37610
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(f.slug) !== void 0;
37346
37611
  });
37347
37612
  }
37348
37613
  async function matches(fs5, framework) {
@@ -37572,7 +37837,7 @@ var require_resolve = __commonJS({
37572
37837
  detectFrameworkFromWorkspace: () => detectFrameworkFromWorkspace,
37573
37838
  getServiceFs: () => getServiceFs,
37574
37839
  inferWorkspaceFromNearestManifest: () => inferWorkspaceFromNearestManifest,
37575
- resolveAllConfiguredServices: () => resolveAllConfiguredServices,
37840
+ resolveAllConfiguredServices: () => resolveAllConfiguredServices2,
37576
37841
  resolveConfiguredService: () => resolveConfiguredService,
37577
37842
  resolveEntrypointPath: () => resolveEntrypointPath,
37578
37843
  validateServiceConfig: () => validateServiceConfig,
@@ -37581,8 +37846,9 @@ var require_resolve = __commonJS({
37581
37846
  module2.exports = __toCommonJS2(resolve_exports);
37582
37847
  var import_path7 = require("path");
37583
37848
  var import_build_utils5 = require("@vercel/build-utils");
37584
- var import_constants = require_constants2();
37585
- var import_framework = require_framework();
37849
+ var import_constants = require_constants3();
37850
+ var import_buildpack_runtimes = require_buildpack_runtimes();
37851
+ var import_framework = require_framework2();
37586
37852
  var import_runtime3 = require_runtime();
37587
37853
  var import_entrypoint = require_entrypoint();
37588
37854
  var import_utils = require_utils5();
@@ -38062,6 +38328,15 @@ var require_resolve = __commonJS({
38062
38328
  };
38063
38329
  }
38064
38330
  if (hasBuilderOrRuntime && !hasFramework && !hasEntrypoint) {
38331
+ const buildpackRuntime = config.builder ? void 0 : (0, import_buildpack_runtimes.toBuildpackRuntime)(config.runtime);
38332
+ if (buildpackRuntime) {
38333
+ const markers = import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? [];
38334
+ return {
38335
+ code: "BUILDPACK_REQUIRES_SERVICES",
38336
+ 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.`,
38337
+ serviceName: name
38338
+ };
38339
+ }
38065
38340
  return {
38066
38341
  code: "MISSING_ENTRYPOINT",
38067
38342
  message: `Service "${name}" must specify "entrypoint" when using "${config.builder ? "builder" : "runtime"}".`,
@@ -38262,7 +38537,7 @@ var require_resolve = __commonJS({
38262
38537
  env: config.env
38263
38538
  };
38264
38539
  }
38265
- async function resolveAllConfiguredServices(services, fs5, routePrefixSource = "configured", options = {}) {
38540
+ async function resolveAllConfiguredServices2(services, fs5, routePrefixSource = "configured", options = {}) {
38266
38541
  const resolved = [];
38267
38542
  const errors = [];
38268
38543
  const webServicesByRoutePrefix = /* @__PURE__ */ new Map();
@@ -38473,11 +38748,13 @@ var require_resolve_v2 = __commonJS({
38473
38748
  var import_path7 = require("path");
38474
38749
  var import_build_utils5 = require("@vercel/build-utils");
38475
38750
  var import_frameworks2 = require_frameworks();
38476
- var import_constants = require_constants2();
38477
- var import_framework = require_framework();
38751
+ var import_constants = require_constants3();
38752
+ var import_framework = require_framework2();
38478
38753
  var import_runtime3 = require_runtime();
38479
38754
  var import_entrypoint = require_entrypoint();
38755
+ var import_buildpack_runtimes = require_buildpack_runtimes();
38480
38756
  var import_resolve = require_resolve();
38757
+ var import_utils = require_utils5();
38481
38758
  var frameworksBySlug = new Map(import_frameworks2.frameworkList.map((f) => [f.slug, f]));
38482
38759
  var MAX_SERVICE_NAME_LENGTH = 64;
38483
38760
  var SERVICE_NAME_REGEX = /^[a-z]([a-z_-]*[a-z])?$/;
@@ -38681,7 +38958,23 @@ var require_resolve_v2 = __commonJS({
38681
38958
  entrypoint: entrypointFile
38682
38959
  });
38683
38960
  }
38684
- if (entrypointIsDirectory && !framework) {
38961
+ const flaggedBuildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(
38962
+ inferredRuntime
38963
+ );
38964
+ if (flaggedBuildpackRuntime && config.command !== void 0) {
38965
+ return {
38966
+ error: {
38967
+ code: "INVALID_COMMAND",
38968
+ message: `Service "${name}" can only specify "command" when using runtime "container".`,
38969
+ serviceName: name
38970
+ }
38971
+ };
38972
+ }
38973
+ const buildpackRuntime = flaggedBuildpackRuntime && !entrypointFile && !(0, import_framework.isFrontendFramework)(framework) && await (0, import_buildpack_runtimes.hasBuildpackProjectMarker)(
38974
+ flaggedBuildpackRuntime,
38975
+ (marker) => (0, import_utils.hasFile)(serviceFs, marker)
38976
+ ) ? flaggedBuildpackRuntime : void 0;
38977
+ if (entrypointIsDirectory && !framework && !buildpackRuntime) {
38685
38978
  return {
38686
38979
  error: {
38687
38980
  code: "MISSING_SERVICE_FRAMEWORK",
@@ -38691,7 +38984,7 @@ var require_resolve_v2 = __commonJS({
38691
38984
  };
38692
38985
  }
38693
38986
  const frameworkRuntime = (0, import_framework.inferRuntimeFromFramework)(framework);
38694
- if (detectedFramework && frameworkRuntime && !entrypointFile) {
38987
+ if (detectedFramework && frameworkRuntime && !entrypointFile && !buildpackRuntime) {
38695
38988
  return {
38696
38989
  error: {
38697
38990
  code: "MISSING_SERVICE_CONFIG",
@@ -38703,7 +38996,10 @@ var require_resolve_v2 = __commonJS({
38703
38996
  const frameworkDefinition = framework ? frameworksBySlug.get(framework) : void 0;
38704
38997
  let builderUse;
38705
38998
  let builderSrc;
38706
- if (framework) {
38999
+ if (buildpackRuntime) {
39000
+ builderUse = "@vercel/container";
39001
+ builderSrc = "<detect>";
39002
+ } else if (framework) {
38707
39003
  builderUse = (0, import_build_utils5.isNodeBackendFramework)(framework) ? "@vercel/backends" : frameworkDefinition?.useRuntime?.use || "@vercel/static-build";
38708
39004
  builderSrc = entrypointFile || frameworkDefinition?.useRuntime?.src || "package.json";
38709
39005
  } else {
@@ -38738,6 +39034,9 @@ var require_resolve_v2 = __commonJS({
38738
39034
  if (framework) {
38739
39035
  builderConfig.framework = framework;
38740
39036
  }
39037
+ if (buildpackRuntime) {
39038
+ builderConfig.buildpack = buildpackRuntime;
39039
+ }
38741
39040
  if (config.outputDirectory) {
38742
39041
  builderConfig.outputDirectory = config.outputDirectory;
38743
39042
  }
@@ -38853,7 +39152,7 @@ var require_auto_detect = __commonJS({
38853
39152
  module2.exports = __toCommonJS2(auto_detect_exports);
38854
39153
  var import_detect_framework = require_detect_framework();
38855
39154
  var import_frameworks2 = require_frameworks();
38856
- var import_framework = require_framework();
39155
+ var import_framework = require_framework2();
38857
39156
  var import_utils = require_utils5();
38858
39157
  var FRONTEND_DIR = "frontend";
38859
39158
  var APPS_WEB_DIR = "apps/web";
@@ -39135,7 +39434,7 @@ var require_detect_railway = __commonJS({
39135
39434
  var import_path7 = require("path");
39136
39435
  var import_smol_toml = __toESM2(require_dist());
39137
39436
  var import_detect_framework = require_detect_framework();
39138
- var import_framework = require_framework();
39437
+ var import_framework = require_framework2();
39139
39438
  var import_utils = require_utils5();
39140
39439
  var RAILWAY_JSON = "railway.json";
39141
39440
  var RAILWAY_TOML = "railway.toml";
@@ -42244,8 +42543,8 @@ var require_detect_render = __commonJS({
42244
42543
  module2.exports = __toCommonJS2(detect_render_exports);
42245
42544
  var import_js_yaml = __toESM2(require_js_yaml4());
42246
42545
  var import_detect_framework = require_detect_framework();
42247
- var import_constants = require_constants2();
42248
- var import_framework = require_framework();
42546
+ var import_constants = require_constants3();
42547
+ var import_framework = require_framework2();
42249
42548
  var import_utils = require_utils5();
42250
42549
  var RENDER_YAML = "render.yaml";
42251
42550
  var SERVICE_TYPE_MAP = {
@@ -42466,7 +42765,7 @@ var require_detect_procfile = __commonJS({
42466
42765
  });
42467
42766
  module2.exports = __toCommonJS2(detect_procfile_exports);
42468
42767
  var import_detect_framework = require_detect_framework();
42469
- var import_framework = require_framework();
42768
+ var import_framework = require_framework2();
42470
42769
  var import_utils = require_utils5();
42471
42770
  var PROCFILE = "Procfile";
42472
42771
  var PROCFILE_LINE_RE = /^\s*([A-Za-z_][A-Za-z0-9_-]*):\s*(.+)/;
@@ -42721,7 +43020,8 @@ var require_detect_services = __commonJS({
42721
43020
  module2.exports = __toCommonJS2(detect_services_exports);
42722
43021
  var import_build_utils5 = require("@vercel/build-utils");
42723
43022
  var import_routing_utils = require_dist8();
42724
- var import_framework = require_framework();
43023
+ var import_buildpack_runtimes = require_buildpack_runtimes();
43024
+ var import_framework = require_framework2();
42725
43025
  var import_utils = require_utils5();
42726
43026
  var import_resolve = require_resolve();
42727
43027
  var import_resolve_v2 = require_resolve_v2();
@@ -42756,6 +43056,11 @@ var require_detect_services = __commonJS({
42756
43056
  inferred
42757
43057
  };
42758
43058
  }
43059
+ function isBuildpackInferredService(svc) {
43060
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(
43061
+ svc.runtime ?? (0, import_framework.inferRuntimeFromFramework)(svc.framework)
43062
+ ) !== void 0;
43063
+ }
42759
43064
  function toInferredLayoutConfig(services) {
42760
43065
  const inferredConfig = {};
42761
43066
  for (const [name, service] of Object.entries(services)) {
@@ -42765,7 +43070,7 @@ var require_detect_services = __commonJS({
42765
43070
  if (service.type) {
42766
43071
  serviceConfig.type = service.type;
42767
43072
  }
42768
- if (typeof service.entrypoint === "string") {
43073
+ if (typeof service.entrypoint === "string" && !isBuildpackInferredService(service)) {
42769
43074
  serviceConfig.entrypoint = service.entrypoint;
42770
43075
  }
42771
43076
  if (typeof service.mountPath === "string") {
@@ -42908,7 +43213,7 @@ var require_detect_services = __commonJS({
42908
43213
  v2Services[name] = {
42909
43214
  root: svc.root,
42910
43215
  ...svc.framework ? { framework: svc.framework } : {},
42911
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {}
43216
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {}
42912
43217
  };
42913
43218
  }
42914
43219
  const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(v2Services, scopedFs);
@@ -42941,7 +43246,7 @@ var require_detect_services = __commonJS({
42941
43246
  v1Services[name] = {
42942
43247
  root: svc.root === "." ? void 0 : svc.root,
42943
43248
  ...svc.framework ? { framework: svc.framework } : {},
42944
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {},
43249
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {},
42945
43250
  ...svc.type ? { type: svc.type } : {},
42946
43251
  ...svc.buildCommand ? { buildCommand: svc.buildCommand } : {},
42947
43252
  ...svc.preDeployCommand ? { preDeployCommand: svc.preDeployCommand } : {},
@@ -43115,6 +43420,523 @@ var require_detect_services = __commonJS({
43115
43420
  }
43116
43421
  });
43117
43422
 
43423
+ // ../fs-detectors/dist/services/migrate.js
43424
+ var require_migrate = __commonJS({
43425
+ "../fs-detectors/dist/services/migrate.js"(exports, module2) {
43426
+ "use strict";
43427
+ var __defProp2 = Object.defineProperty;
43428
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
43429
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
43430
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
43431
+ var __export2 = (target, all) => {
43432
+ for (var name in all)
43433
+ __defProp2(target, name, { get: all[name], enumerable: true });
43434
+ };
43435
+ var __copyProps2 = (to, from, except, desc) => {
43436
+ if (from && typeof from === "object" || typeof from === "function") {
43437
+ for (let key of __getOwnPropNames2(from))
43438
+ if (!__hasOwnProp2.call(to, key) && key !== except)
43439
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
43440
+ }
43441
+ return to;
43442
+ };
43443
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
43444
+ var migrate_exports = {};
43445
+ __export2(migrate_exports, {
43446
+ hasLegacyServicesConfig: () => hasLegacyServicesConfig2,
43447
+ migrateExperimentalServices: () => migrateExperimentalServices2,
43448
+ planExperimentalServicesMigration: () => planExperimentalServicesMigration2
43449
+ });
43450
+ module2.exports = __toCommonJS2(migrate_exports);
43451
+ var import_path7 = require("path");
43452
+ var import_frameworks2 = require_frameworks();
43453
+ var import_constants = require_constants3();
43454
+ var import_resolve = require_resolve();
43455
+ var import_resolve_v2 = require_resolve_v2();
43456
+ var import_utils = require_utils5();
43457
+ var SERVICES_DOCS_URL = "https://vercel.com/docs/services";
43458
+ var SERVICES_ROUTING_DOCS_URL = "https://vercel.com/docs/services/routing";
43459
+ var SERVICES_BINDINGS_DOCS_URL = "https://vercel.com/docs/services/bindings";
43460
+ var EXPERIMENTAL_SERVICES_DOCS_URL = "https://vercel.com/docs/services/experimental";
43461
+ var TOP_LEVEL_BUILD_KEYS = [
43462
+ "functions",
43463
+ "installCommand",
43464
+ "buildCommand",
43465
+ "devCommand",
43466
+ "ignoreCommand",
43467
+ "outputDirectory",
43468
+ "framework"
43469
+ ];
43470
+ var PREVIEW_DOMAIN_MISSING = [
43471
+ { type: "host", value: { suf: ".vercel.app" } },
43472
+ { type: "host", value: { suf: ".vercel.dev" } }
43473
+ ];
43474
+ function hasLegacyServicesConfig2(config) {
43475
+ return isNonEmptyObject(config?.experimentalServices) || isNonEmptyObject(config?.experimentalServicesV2);
43476
+ }
43477
+ function isNonEmptyObject(value) {
43478
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length > 0;
43479
+ }
43480
+ function getServicesConfigConflict(config) {
43481
+ const keys = ["services", "experimentalServices", "experimentalServicesV2"].filter((key) => config[key] !== void 0);
43482
+ if (keys.length > 1) {
43483
+ return {
43484
+ code: "CONFLICTING_SERVICES_CONFIG",
43485
+ 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.`
43486
+ };
43487
+ }
43488
+ return void 0;
43489
+ }
43490
+ function normalizePrefix(prefix) {
43491
+ const withSlash = prefix.startsWith("/") ? prefix : `/${prefix}`;
43492
+ return withSlash !== "/" ? withSlash.replace(/\/+$/, "") : withSlash;
43493
+ }
43494
+ function publicRewrite(prefix, service) {
43495
+ return {
43496
+ source: prefix === "/" ? "/(.*)" : `${prefix}(/.*)?`,
43497
+ destination: { service }
43498
+ };
43499
+ }
43500
+ function planExperimentalServicesMigration2(config, resolvedServices) {
43501
+ const conflict = getServicesConfigConflict(config);
43502
+ if (conflict)
43503
+ return emptyPlanWithErrors([conflict]);
43504
+ const plan = emptyPlanWithErrors([]);
43505
+ const legacy = config.experimentalServices;
43506
+ if (isNonEmptyObject(config.experimentalServicesV2)) {
43507
+ plan.patch.services = { ...config.experimentalServicesV2 };
43508
+ plan.removeKeys.push("experimentalServicesV2");
43509
+ return plan;
43510
+ }
43511
+ if (!isNonEmptyObject(legacy)) {
43512
+ plan.errors.push({
43513
+ code: "NO_LEGACY_SERVICES",
43514
+ message: "No `experimentalServices` configuration found to migrate."
43515
+ });
43516
+ return plan;
43517
+ }
43518
+ plan.removeKeys.push("experimentalServices");
43519
+ if (config.experimentalServiceGroups !== void 0) {
43520
+ plan.removeKeys.push("experimentalServiceGroups");
43521
+ plan.warnings.push({
43522
+ code: "SERVICE_GROUPS_DROPPED",
43523
+ message: "`experimentalServiceGroups` has no equivalent in `services` and was removed.",
43524
+ link: SERVICES_DOCS_URL
43525
+ });
43526
+ }
43527
+ const webServices = [];
43528
+ const resolvedByName = new Map(resolvedServices.map((s) => [s.name, s]));
43529
+ for (const [legacyName, serviceConfig] of Object.entries(legacy)) {
43530
+ const resolved = resolvedByName.get(legacyName);
43531
+ if (!resolved) {
43532
+ plan.errors.push({
43533
+ code: "UNRESOLVED_SERVICE",
43534
+ serviceName: legacyName,
43535
+ message: `Service "${legacyName}" could not be resolved. Fix the errors reported for it before migrating.`
43536
+ });
43537
+ continue;
43538
+ }
43539
+ if (resolved.type !== "web") {
43540
+ plan.unmigrated.push(getUnmigratedNote(legacyName, resolved));
43541
+ continue;
43542
+ }
43543
+ const name = legacyName.toLowerCase();
43544
+ if (name.length > 64 || !/^[a-z]([a-z_-]*[a-z])?$/.test(name)) {
43545
+ plan.errors.push({
43546
+ code: "INVALID_SERVICE_NAME",
43547
+ serviceName: legacyName,
43548
+ 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.`
43549
+ });
43550
+ continue;
43551
+ }
43552
+ const conflict2 = webServices.find((s) => s.name === name);
43553
+ if (conflict2) {
43554
+ plan.errors.push({
43555
+ code: "DUPLICATE_SERVICE_NAME",
43556
+ serviceName: legacyName,
43557
+ message: `Services "${conflict2.resolved.name}" and "${legacyName}" both map to "${name}". Rename one of them first.`
43558
+ });
43559
+ continue;
43560
+ }
43561
+ if (name !== legacyName) {
43562
+ plan.renamedServices.push({ from: legacyName, to: name });
43563
+ }
43564
+ webServices.push({
43565
+ name,
43566
+ resolved,
43567
+ config: serviceConfig,
43568
+ prefix: normalizePrefix(resolved.routePrefix ?? "/")
43569
+ });
43570
+ }
43571
+ if (plan.errors.length > 0)
43572
+ return plan;
43573
+ if (webServices.length === 0) {
43574
+ plan.errors.push({
43575
+ code: "NO_WEB_SERVICES",
43576
+ message: "None of the configured services are web services. `services` only describes web services; see the manual steps for the others."
43577
+ });
43578
+ return plan;
43579
+ }
43580
+ for (const consumer of webServices) {
43581
+ plan.patch.services[consumer.name] = convertWebService(
43582
+ consumer,
43583
+ webServices,
43584
+ plan,
43585
+ config.build?.env ?? {}
43586
+ );
43587
+ }
43588
+ const subpaths = webServices.filter((svc) => svc.prefix !== "/").sort((a, b) => b.prefix.length - a.prefix.length);
43589
+ plan.patch.rewrites = subpaths.map(
43590
+ (svc) => publicRewrite(svc.prefix, svc.name)
43591
+ );
43592
+ for (const { name, prefix, resolved } of subpaths) {
43593
+ const { subdomain } = resolved;
43594
+ if (!subdomain)
43595
+ continue;
43596
+ const hostRewrite = {
43597
+ source: "/(.*)",
43598
+ has: [{ type: "host", value: { pre: `${subdomain}.` } }],
43599
+ missing: PREVIEW_DOMAIN_MISSING,
43600
+ destination: { service: name }
43601
+ };
43602
+ if (resolved.builder.use === "@vercel/next") {
43603
+ plan.patch.rewrites.push({
43604
+ ...hostRewrite,
43605
+ source: "/",
43606
+ destination: { service: name, path: prefix }
43607
+ });
43608
+ hostRewrite.source = "/:path(.*)";
43609
+ hostRewrite.destination = { service: name, path: `${prefix}/:path` };
43610
+ }
43611
+ plan.patch.rewrites.push(hostRewrite);
43612
+ plan.warnings.push({
43613
+ code: "SUBDOMAIN_ROUTING",
43614
+ serviceName: resolved.name,
43615
+ message: `"${subdomain}.<your-domain>" routes to "${resolved.name}". Explicit service prefixes take precedence. Host routing still applies only to custom domains, not preview URLs.`,
43616
+ link: SERVICES_ROUTING_DOCS_URL
43617
+ });
43618
+ }
43619
+ plan.patch.rewrites.push(
43620
+ ...webServices.filter((svc) => svc.prefix === "/").map((svc) => publicRewrite("/", svc.name))
43621
+ );
43622
+ const rootService = webServices.find((s) => s.resolved.workspace === ".");
43623
+ for (const key of TOP_LEVEL_BUILD_KEYS) {
43624
+ const value = config[key];
43625
+ if (value === void 0)
43626
+ continue;
43627
+ plan.removeKeys.push(key);
43628
+ if (key === "framework" && (value === "services" || value === null))
43629
+ continue;
43630
+ if (!rootService) {
43631
+ plan.errors.push({
43632
+ code: "TOP_LEVEL_SETTING_WITHOUT_ROOT_SERVICE",
43633
+ 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.`
43634
+ });
43635
+ continue;
43636
+ }
43637
+ const target = plan.patch.services[rootService.name];
43638
+ if (key === "functions") {
43639
+ target.functions = {
43640
+ ...value,
43641
+ ...target.functions
43642
+ };
43643
+ } else if (value !== null && target[key] !== void 0) {
43644
+ plan.warnings.push({
43645
+ code: "TOP_LEVEL_SETTING_CONFLICT",
43646
+ serviceName: rootService.resolved.name,
43647
+ message: `Top-level \`${key}\` was dropped because service "${rootService.resolved.name}" already defines it.`
43648
+ });
43649
+ continue;
43650
+ } else if (value !== null) {
43651
+ target[key] = value;
43652
+ }
43653
+ plan.movedTopLevelKeys.push({ key, service: rootService.name });
43654
+ }
43655
+ if (Array.isArray(config.rewrites) && config.rewrites.length > 0) {
43656
+ plan.warnings.push({
43657
+ code: "EXISTING_REWRITES",
43658
+ 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`.",
43659
+ link: SERVICES_ROUTING_DOCS_URL
43660
+ });
43661
+ }
43662
+ return plan;
43663
+ }
43664
+ function convertWebService(consumer, webServices, plan, existingBuildEnv) {
43665
+ const { resolved, config: serviceConfig, prefix } = consumer;
43666
+ const { name: legacyName, entrypoint } = resolved;
43667
+ const service = { root: resolved.workspace };
43668
+ const warn = (code, message, link) => {
43669
+ plan.warnings.push({
43670
+ code,
43671
+ serviceName: legacyName,
43672
+ message: `Service "${legacyName}": ${message}`,
43673
+ ...link ? { link } : {}
43674
+ });
43675
+ };
43676
+ if (serviceConfig.framework)
43677
+ service.framework = serviceConfig.framework;
43678
+ const runtime = serviceConfig.runtime;
43679
+ if (runtime) {
43680
+ if (runtime in import_constants.RUNTIME_BUILDERS) {
43681
+ service.runtime = runtime;
43682
+ } else {
43683
+ warn(
43684
+ "RUNTIME_DROPPED",
43685
+ `Runtime "${runtime}" is not supported (${Object.keys(import_constants.RUNTIME_BUILDERS).join(", ")}); it will be inferred from the entrypoint instead.`
43686
+ );
43687
+ }
43688
+ }
43689
+ if (entrypoint) {
43690
+ const handler = resolved.builder.config?.handlerFunction;
43691
+ service.entrypoint = typeof handler === "string" && entrypoint.endsWith(".py") ? `${entrypoint.slice(0, -3).replace(/\//g, ".")}:${handler}` : entrypoint;
43692
+ }
43693
+ if (serviceConfig.command !== void 0) {
43694
+ service.command = serviceConfig.command;
43695
+ }
43696
+ if (serviceConfig.installCommand !== void 0) {
43697
+ service.installCommand = serviceConfig.installCommand;
43698
+ }
43699
+ const buildCommand = (0, import_utils.combineBuildCommand)(
43700
+ serviceConfig.buildCommand,
43701
+ serviceConfig.preDeployCommand
43702
+ );
43703
+ if (buildCommand !== void 0)
43704
+ service.buildCommand = buildCommand;
43705
+ if (serviceConfig.preDeployCommand) {
43706
+ warn(
43707
+ "PRE_DEPLOY_COMMAND_FOLDED",
43708
+ "`preDeployCommand` was appended to `buildCommand` and now runs at build time, not right before deployment."
43709
+ );
43710
+ }
43711
+ if (serviceConfig.builder) {
43712
+ warn(
43713
+ "BUILDER_DROPPED",
43714
+ `Builder "${serviceConfig.builder}" was removed; \`services\` selects it from the framework and runtime.`
43715
+ );
43716
+ }
43717
+ if (serviceConfig.workspace) {
43718
+ warn("WORKSPACE_REPLACED", "`workspace` is now expressed by `root`.");
43719
+ }
43720
+ const fnConfig = {};
43721
+ for (const key of ["maxDuration", "includeFiles", "excludeFiles"]) {
43722
+ if (serviceConfig[key] !== void 0)
43723
+ fnConfig[key] = serviceConfig[key];
43724
+ }
43725
+ if (serviceConfig.memory !== void 0) {
43726
+ warn(
43727
+ "MEMORY_DROPPED",
43728
+ "`memory` cannot be configured in vercel.json with Fluid compute; use the project's Functions settings instead.",
43729
+ "https://vercel.com/docs/functions/configuring-functions/memory"
43730
+ );
43731
+ }
43732
+ if (Object.keys(fnConfig).length > 0) {
43733
+ if (entrypoint && resolved.runtime !== "container") {
43734
+ service.functions = {
43735
+ [import_path7.posix.normalize(entrypoint)]: fnConfig
43736
+ };
43737
+ } else {
43738
+ warn(
43739
+ "FUNCTION_CONFIG_DROPPED",
43740
+ `No file entrypoint for ${Object.keys(fnConfig).join(", ")}; configure them under this service's \`functions\` manually.`
43741
+ );
43742
+ }
43743
+ }
43744
+ const isStatic = (0, import_utils.isStaticBuild)(resolved);
43745
+ const rewrites = [];
43746
+ if (prefix !== "/") {
43747
+ if (isStatic || resolved.builder.use !== "@vercel/next") {
43748
+ rewrites.push({ source: `${prefix}/:path(.*)?`, destination: "/:path" });
43749
+ }
43750
+ if (isStatic) {
43751
+ rewrites.push({ source: "/:path*", destination: "/index.html" });
43752
+ warn(
43753
+ "STATIC_SUBPATH",
43754
+ `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}/".`,
43755
+ SERVICES_ROUTING_DOCS_URL
43756
+ );
43757
+ } else if (resolved.builder.use === "@vercel/next") {
43758
+ warn("NEXT_SUBPATH", `Keep \`basePath\` in next.config at "${prefix}".`);
43759
+ } else {
43760
+ warn(
43761
+ "PREFIX_STRIP",
43762
+ `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.`,
43763
+ SERVICES_ROUTING_DOCS_URL
43764
+ );
43765
+ }
43766
+ } else if (isStatic) {
43767
+ rewrites.push({ source: "/(.*)", destination: "/index.html" });
43768
+ }
43769
+ if (rewrites.length > 0)
43770
+ service.rewrites = rewrites;
43771
+ const bindings = [];
43772
+ const seenEnv = /* @__PURE__ */ new Set();
43773
+ const consumerPrefix = import_frameworks2.frameworkList.find(
43774
+ (f) => f.slug === resolved.framework
43775
+ )?.envPrefix;
43776
+ const bindingsUnsupported = resolved.runtime === "go" || resolved.runtime === "rust";
43777
+ const implicit = [];
43778
+ const clientSide = [];
43779
+ const unsupported = [];
43780
+ const add = (target, env, explicit) => {
43781
+ if (seenEnv.has(env))
43782
+ return;
43783
+ seenEnv.add(env);
43784
+ if (consumerPrefix && env.startsWith(consumerPrefix)) {
43785
+ if (Object.prototype.hasOwnProperty.call(existingBuildEnv, env))
43786
+ return;
43787
+ const defaults = (plan.patch.build ??= { env: {} }).env;
43788
+ if (defaults[env] !== void 0 && defaults[env] !== target.prefix) {
43789
+ plan.errors.push({
43790
+ code: "CONFLICTING_BUILD_ENV",
43791
+ serviceName: legacyName,
43792
+ message: `Services use \`${env}\` for different public paths. Set a shared value in \`build.env\` or use distinct environment variable names before migrating.`
43793
+ });
43794
+ } else {
43795
+ defaults[env] = target.prefix;
43796
+ }
43797
+ return;
43798
+ }
43799
+ if (isStatic) {
43800
+ if (explicit) {
43801
+ clientSide.push(`\`${env}="${target.prefix}"\``);
43802
+ }
43803
+ return;
43804
+ }
43805
+ if (bindingsUnsupported) {
43806
+ unsupported.push(`\`${env}\``);
43807
+ return;
43808
+ }
43809
+ if (!explicit)
43810
+ implicit.push(`\`${env}\``);
43811
+ bindings.push({
43812
+ type: "service",
43813
+ service: target.name,
43814
+ format: "url",
43815
+ env
43816
+ });
43817
+ };
43818
+ for (const [env, ref] of Object.entries(serviceConfig.env ?? {})) {
43819
+ if (ref?.type !== "service-ref")
43820
+ continue;
43821
+ const target = webServices.find((s) => s.resolved.name === ref.service);
43822
+ if (!target) {
43823
+ warn(
43824
+ "SERVICE_REF_DROPPED",
43825
+ `\`${env}\` referenced "${ref.service}", which is not a web service and cannot be bound.`
43826
+ );
43827
+ continue;
43828
+ }
43829
+ add(target, env, true);
43830
+ }
43831
+ for (const target of webServices) {
43832
+ const env = `${target.resolved.name.replace(/-/g, "_").toUpperCase()}_URL`;
43833
+ if (target !== consumer) {
43834
+ add(target, env, false);
43835
+ } else if (!seenEnv.has(env)) {
43836
+ seenEnv.add(env);
43837
+ warn(
43838
+ "SELF_SERVICE_URL_DROPPED",
43839
+ `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.`,
43840
+ SERVICES_BINDINGS_DOCS_URL
43841
+ );
43842
+ }
43843
+ if (consumerPrefix)
43844
+ add(target, `${consumerPrefix}${env}`, false);
43845
+ }
43846
+ if (implicit.length > 0) {
43847
+ warn(
43848
+ "IMPLICIT_URL_TO_BINDING",
43849
+ `Previously implicit URLs now use bindings: ${implicit.join(", ")}. These resolve to internal URLs; remove unused bindings.`,
43850
+ SERVICES_BINDINGS_DOCS_URL
43851
+ );
43852
+ }
43853
+ if (clientSide.length > 0) {
43854
+ warn(
43855
+ "CLIENT_SIDE_SERVICE_URL",
43856
+ `Bindings only cover server-side calls. Define any client-side URLs still in use as project environment variables: ${clientSide.join(", ")}.`,
43857
+ SERVICES_BINDINGS_DOCS_URL
43858
+ );
43859
+ }
43860
+ if (unsupported.length > 0) {
43861
+ warn(
43862
+ "BINDINGS_UNSUPPORTED_RUNTIME",
43863
+ `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.`,
43864
+ SERVICES_BINDINGS_DOCS_URL
43865
+ );
43866
+ }
43867
+ if (bindings.length > 0)
43868
+ service.bindings = bindings;
43869
+ return service;
43870
+ }
43871
+ function getUnmigratedNote(legacyName, resolved) {
43872
+ const isPython = resolved.runtime === "python";
43873
+ let guidance;
43874
+ if (resolved.type === "cron" || resolved.trigger === "schedule") {
43875
+ 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`.";
43876
+ } else if (resolved.trigger === "workflow") {
43877
+ 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.";
43878
+ } else {
43879
+ 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.";
43880
+ }
43881
+ return {
43882
+ code: "UNSUPPORTED_SERVICE_TYPE",
43883
+ serviceName: legacyName,
43884
+ message: `"${legacyName}" (type "${resolved.type}"${resolved.trigger ? `, trigger "${resolved.trigger}"` : ""}) has no equivalent in \`services\` and was left out. ${guidance}`,
43885
+ link: EXPERIMENTAL_SERVICES_DOCS_URL
43886
+ };
43887
+ }
43888
+ async function migrateExperimentalServices2(options) {
43889
+ const { fs: fs5 } = options;
43890
+ let { config, resolvedServices } = options;
43891
+ if (!config) {
43892
+ const read = await (0, import_utils.readVercelConfig)(fs5);
43893
+ if (read.error)
43894
+ return emptyPlanWithErrors([read.error]);
43895
+ config = read.config ?? {};
43896
+ }
43897
+ const conflict = getServicesConfigConflict(config);
43898
+ if (conflict)
43899
+ return emptyPlanWithErrors([conflict]);
43900
+ if (!resolvedServices && isNonEmptyObject(config.experimentalServices)) {
43901
+ const result = await (0, import_resolve.resolveAllConfiguredServices)(
43902
+ config.experimentalServices,
43903
+ fs5,
43904
+ "configured"
43905
+ );
43906
+ if (result.errors.length > 0) {
43907
+ return emptyPlanWithErrors(result.errors);
43908
+ }
43909
+ resolvedServices = result.services;
43910
+ }
43911
+ const plan = planExperimentalServicesMigration2(
43912
+ config,
43913
+ resolvedServices ?? []
43914
+ );
43915
+ if (plan.errors.length > 0)
43916
+ return plan;
43917
+ const check = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(plan.patch.services, fs5);
43918
+ plan.errors.push(
43919
+ ...check.errors.map((error) => ({
43920
+ ...error,
43921
+ message: `Generated \`services\` config is invalid: ${error.message}`
43922
+ }))
43923
+ );
43924
+ return plan;
43925
+ }
43926
+ function emptyPlanWithErrors(errors) {
43927
+ return {
43928
+ patch: { services: {}, rewrites: [] },
43929
+ removeKeys: [],
43930
+ movedTopLevelKeys: [],
43931
+ renamedServices: [],
43932
+ warnings: [],
43933
+ unmigrated: [],
43934
+ errors
43935
+ };
43936
+ }
43937
+ }
43938
+ });
43939
+
43118
43940
  // ../fs-detectors/dist/detect-file-system-api.js
43119
43941
  var require_detect_file_system_api = __commonJS({
43120
43942
  "../fs-detectors/dist/detect-file-system-api.js"(exports, module2) {
@@ -47904,14 +48726,18 @@ var require_dist9 = __commonJS({
47904
48726
  getProxyBuilder: () => import_detect_builders.getProxyBuilder,
47905
48727
  getWorkspacePackagePaths: () => import_get_workspace_package_paths.getWorkspacePackagePaths,
47906
48728
  getWorkspaces: () => import_get_workspaces.getWorkspaces,
48729
+ hasLegacyServicesConfig: () => import_migrate.hasLegacyServicesConfig,
47907
48730
  isExperimentalService: () => import_build_utils5.isExperimentalService,
47908
48731
  isExperimentalServiceV2: () => import_build_utils5.isExperimentalServiceV2,
47909
48732
  isOfficialRuntime: () => import_is_official_runtime.isOfficialRuntime,
47910
48733
  isRouteOwningBuilder: () => import_utils.isRouteOwningBuilder,
47911
48734
  isStaticBuild: () => import_utils.isStaticBuild,
47912
48735
  isStaticRuntime: () => import_is_official_runtime.isStaticRuntime,
48736
+ migrateExperimentalServices: () => import_migrate.migrateExperimentalServices,
47913
48737
  monorepoManagers: () => import_monorepo_managers.monorepoManagers,
47914
48738
  packageManagers: () => import_package_managers.packageManagers,
48739
+ planExperimentalServicesMigration: () => import_migrate.planExperimentalServicesMigration,
48740
+ resolveAllConfiguredServices: () => import_resolve.resolveAllConfiguredServices,
47915
48741
  resolveAllConfiguredServicesV2: () => import_resolve_v2.resolveAllConfiguredServicesV2,
47916
48742
  resolveConfiguredServiceV2: () => import_resolve_v2.resolveConfiguredServiceV2,
47917
48743
  validateProxy: () => import_detect_builders.validateProxy,
@@ -47923,6 +48749,8 @@ var require_dist9 = __commonJS({
47923
48749
  var import_detect_builders = require_detect_builders();
47924
48750
  var import_detect_services = require_detect_services();
47925
48751
  var import_resolve_v2 = require_resolve_v2();
48752
+ var import_resolve = require_resolve();
48753
+ var import_migrate = require_migrate();
47926
48754
  var import_build_utils5 = require("@vercel/build-utils");
47927
48755
  var import_auto_detect = require_auto_detect();
47928
48756
  var import_utils = require_utils5();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/static-build",
3
- "version": "10.0.0",
3
+ "version": "10.0.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/build-step",
@@ -14,12 +14,12 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "ts-morph": "12.0.0",
17
+ "@vercel/gatsby-plugin-vercel-builder": "2.2.58",
17
18
  "@vercel/gatsby-plugin-vercel-analytics": "1.0.12",
18
- "@vercel/static-config": "3.4.3",
19
- "@vercel/gatsby-plugin-vercel-builder": "2.2.56"
19
+ "@vercel/static-config": "3.4.3"
20
20
  },
21
21
  "peerDependencies": {
22
- "@vercel/build-utils": "14.10.0"
22
+ "@vercel/build-utils": "14.10.2"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/aws-lambda": "8.10.64",
@@ -40,11 +40,11 @@
40
40
  "semver": "7.5.2",
41
41
  "tree-kill": "1.2.2",
42
42
  "vitest": "4.1.10",
43
- "@vercel/build-utils": "14.10.0",
44
43
  "@vercel/error-utils": "2.2.1",
45
44
  "@vercel/frameworks": "3.34.0",
46
- "@vercel/fs-detectors": "7.2.4",
47
- "@vercel/routing-utils": "6.5.0"
45
+ "@vercel/build-utils": "14.10.2",
46
+ "@vercel/routing-utils": "6.6.0",
47
+ "@vercel/fs-detectors": "7.6.1"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "node ../../utils/build-builder.mjs",