@vercel/static-build 2.11.3 → 2.11.4

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 +250 -147
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -7166,12 +7166,9 @@ var require_frameworks = __commonJS({
7166
7166
  // may also be detected. It is listed first so that framework detection
7167
7167
  // (which returns the first match in list order) selects it over everything
7168
7168
  // else — e.g. a Next.js app shipping a `Dockerfile.vercel` deploys as a
7169
- // container, not via `@vercel/next`. Experimental for now, so it is only
7170
- // detected when experimental frameworks are enabled
7171
- // (`VERCEL_USE_EXPERIMENTAL_FRAMEWORKS`).
7169
+ // container, not via `@vercel/next`.
7172
7170
  name: "Container",
7173
7171
  slug: "container",
7174
- experimental: true,
7175
7172
  runtimeFramework: true,
7176
7173
  logo: "https://api-frameworks.vercel.sh/framework-logos/container.svg",
7177
7174
  tagline: "Deploy any project as a container image built from a Dockerfile.",
@@ -19803,7 +19800,7 @@ var require_superstatic = __commonJS({
19803
19800
  convertCleanUrls: () => convertCleanUrls,
19804
19801
  convertHeaders: () => convertHeaders,
19805
19802
  convertRedirects: () => convertRedirects,
19806
- convertRewrites: () => convertRewrites,
19803
+ convertRewrites: () => convertRewrites2,
19807
19804
  convertTrailingSlash: () => convertTrailingSlash,
19808
19805
  getCleanUrls: () => getCleanUrls2,
19809
19806
  pathToRegexp: () => pathToRegexp,
@@ -19919,7 +19916,7 @@ var require_superstatic = __commonJS({
19919
19916
  }
19920
19917
  });
19921
19918
  }
19922
- function convertRewrites(rewrites, internalParamNames) {
19919
+ function convertRewrites2(rewrites, internalParamNames) {
19923
19920
  return rewrites.map((r) => {
19924
19921
  const { src, segments } = sourceToRegex2(r.source);
19925
19922
  const hasSegments = collectHasSegments(r.has);
@@ -19937,7 +19934,7 @@ var require_superstatic = __commonJS({
19937
19934
  if (typeof r.destination === "string") {
19938
19935
  route = { src, dest: interpolate(r.destination), check: true };
19939
19936
  } else {
19940
- const destination = { ...r.destination };
19937
+ const destination = { ...r.destination, type: "service" };
19941
19938
  if (typeof destination.path === "string") {
19942
19939
  destination.path = interpolate(destination.path);
19943
19940
  }
@@ -20600,13 +20597,13 @@ var require_schemas = __commonJS({
20600
20597
  pattern: "^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$"
20601
20598
  };
20602
20599
  var serviceDestinationSchema = {
20603
- description: "A service-targeted destination that delegates routing into a named service from `services`.",
20600
+ description: "A service-targeted destination that delegates routing into a named service from `services`. Identified by the presence of `service`.",
20604
20601
  type: "object",
20605
20602
  additionalProperties: false,
20606
- required: ["type", "service"],
20603
+ required: ["service"],
20607
20604
  properties: {
20608
20605
  type: {
20609
- description: "Discriminator. Must be `service`.",
20606
+ description: "Optional explicit format marker. The destination shape is identified by the `service` property, so `type` is no longer required. When present it must be `service`.",
20610
20607
  type: "string",
20611
20608
  enum: ["service"]
20612
20609
  },
@@ -21376,6 +21373,7 @@ var require_dist7 = __commonJS({
21376
21373
  __export2(src_exports2, {
21377
21374
  appendRoutesToPhase: () => import_append.appendRoutesToPhase,
21378
21375
  compilePathToRegexpTemplate: () => import_superstatic2.compilePathToRegexpTemplate,
21376
+ convertRewrites: () => import_superstatic2.convertRewrites,
21379
21377
  getCleanUrls: () => import_superstatic2.getCleanUrls,
21380
21378
  getOwnershipGuard: () => import_service_route_ownership.getOwnershipGuard,
21381
21379
  getTransformedRoutes: () => getTransformedRoutes,
@@ -21430,6 +21428,8 @@ var require_dist7 = __commonJS({
21430
21428
  if (typeof route.destination === "string") {
21431
21429
  route.dest = route.destination;
21432
21430
  delete route.destination;
21431
+ } else if (typeof route.destination.service === "string") {
21432
+ route.destination = { ...route.destination, type: "service" };
21433
21433
  }
21434
21434
  }
21435
21435
  if (route.statusCode !== void 0) {
@@ -22799,7 +22799,7 @@ var require_utils4 = __commonJS({
22799
22799
  DETECTION_FRAMEWORKS: () => DETECTION_FRAMEWORKS,
22800
22800
  INTERNAL_QUEUES_PREFIX: () => INTERNAL_QUEUES_PREFIX,
22801
22801
  INTERNAL_SERVICE_PREFIX: () => import_build_utils5.INTERNAL_SERVICE_PREFIX,
22802
- assignRoutePrefixes: () => assignRoutePrefixes,
22802
+ assignMountPaths: () => assignMountPaths,
22803
22803
  combineBuildCommand: () => combineBuildCommand,
22804
22804
  filterFrameworksByRuntime: () => filterFrameworksByRuntime,
22805
22805
  getBuilderForRuntime: () => getBuilderForRuntime,
@@ -22811,6 +22811,7 @@ var require_utils4 = __commonJS({
22811
22811
  hasFile: () => hasFile,
22812
22812
  inferRuntimeFromFramework: () => inferRuntimeFromFramework,
22813
22813
  inferServiceRuntime: () => inferServiceRuntime,
22814
+ isBFFFramework: () => isBFFFramework,
22814
22815
  isFrontendFramework: () => isFrontendFramework,
22815
22816
  isRouteOwningBuilder: () => isRouteOwningBuilder2,
22816
22817
  isStaticBuild: () => isStaticBuild2,
@@ -22882,6 +22883,16 @@ var require_utils4 = __commonJS({
22882
22883
  }
22883
22884
  return !inferRuntimeFromFramework(framework);
22884
22885
  }
22886
+ var BFF_FRAMEWORKS = /* @__PURE__ */ new Set([
22887
+ "nextjs",
22888
+ "nuxtjs",
22889
+ "sveltekit",
22890
+ "remix",
22891
+ "solidstart"
22892
+ ]);
22893
+ function isBFFFramework(framework) {
22894
+ return !!framework && BFF_FRAMEWORKS.has(framework);
22895
+ }
22885
22896
  function filterFrameworksByRuntime(frameworks2, runtime) {
22886
22897
  if (!runtime) {
22887
22898
  return [...frameworks2];
@@ -22950,11 +22961,11 @@ var require_utils4 = __commonJS({
22950
22961
  }
22951
22962
  return { config: null, error: null };
22952
22963
  }
22953
- function assignRoutePrefixes(services) {
22964
+ function assignMountPaths(services) {
22954
22965
  const warnings = [];
22955
22966
  const names = Object.keys(services);
22956
22967
  if (names.length === 1) {
22957
- services[names[0]].routePrefix = "/";
22968
+ services[names[0]].mountPath = "/";
22958
22969
  return warnings;
22959
22970
  }
22960
22971
  const frontendNames = names.filter(
@@ -22967,11 +22978,19 @@ var require_utils4 = __commonJS({
22967
22978
  rootName = frontendNames.find((n) => n === "frontend" || n === "web") ?? frontendNames.sort()[0];
22968
22979
  warnings.push({
22969
22980
  code: "MULTIPLE_FRONTENDS",
22970
- message: `Multiple frontend services detected (${frontendNames.join(", ")}). "${rootName}" was assigned routePrefix "/". Adjust manually if a different service should be the root.`
22981
+ message: `Multiple frontend services detected (${frontendNames.join(", ")}). "${rootName}" was assigned mount path "/". Adjust manually if a different service should be the root.`
22971
22982
  });
22972
22983
  }
22984
+ const rootFramework = rootName ? services[rootName].framework : void 0;
22985
+ const isBFF = rootFramework ? isBFFFramework(rootFramework) : false;
22986
+ const nonRootNames = names.filter((n) => n !== rootName);
22987
+ const needsNamespace = isBFF || nonRootNames.length > 1;
22973
22988
  for (const name of names) {
22974
- services[name].routePrefix = name === rootName ? "/" : `/_/${name}`;
22989
+ if (name === rootName) {
22990
+ services[name].mountPath = "/";
22991
+ } else {
22992
+ services[name].mountPath = needsNamespace ? `/api/${name}` : "/api";
22993
+ }
22975
22994
  }
22976
22995
  return warnings;
22977
22996
  }
@@ -24184,9 +24203,27 @@ var require_resolve_v2 = __commonJS({
24184
24203
  var import_utils = require_utils4();
24185
24204
  var frameworksBySlug = new Map(import_frameworks2.frameworkList.map((f) => [f.slug, f]));
24186
24205
  var SERVICE_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
24206
+ var CONTAINER_ENTRYPOINT_CANDIDATES = [
24207
+ "Dockerfile.vercel",
24208
+ "Containerfile.vercel",
24209
+ "Dockerfile",
24210
+ "Containerfile"
24211
+ ];
24212
+ var CONTAINER_ENTRYPOINT_BASENAMES = new Set(
24213
+ CONTAINER_ENTRYPOINT_CANDIDATES.map((name) => name.toLowerCase())
24214
+ );
24187
24215
  function isDockerfileEntrypoint(entrypoint) {
24188
- const base = import_path7.posix.basename(entrypoint).toLowerCase();
24189
- return base === "dockerfile" || base === "containerfile" || base.endsWith(".dockerfile");
24216
+ return CONTAINER_ENTRYPOINT_BASENAMES.has(
24217
+ import_path7.posix.basename(entrypoint).toLowerCase()
24218
+ );
24219
+ }
24220
+ async function detectContainerEntrypoint(serviceFs) {
24221
+ for (const candidate of CONTAINER_ENTRYPOINT_CANDIDATES) {
24222
+ if (await serviceFs.hasPath(candidate)) {
24223
+ return candidate;
24224
+ }
24225
+ }
24226
+ return void 0;
24190
24227
  }
24191
24228
  function normalizeContainerCommand(command) {
24192
24229
  if (command === void 0) {
@@ -24194,29 +24231,40 @@ var require_resolve_v2 = __commonJS({
24194
24231
  }
24195
24232
  return Array.isArray(command) ? command : [command];
24196
24233
  }
24197
- function resolveContainerServiceV2(name, config, normalizedRoot) {
24234
+ async function resolveContainerServiceV2(name, config, normalizedRoot, serviceFs) {
24198
24235
  const isRoot = normalizedRoot === ".";
24199
24236
  const entrypoint = config.entrypoint;
24200
- const dockerfile = typeof entrypoint === "string" && isDockerfileEntrypoint(entrypoint) ? import_path7.posix.normalize(entrypoint) : void 0;
24201
- const image = typeof entrypoint === "string" && !dockerfile ? entrypoint : void 0;
24202
- if (!dockerfile && !image) {
24203
- return {
24204
- error: {
24205
- code: "MISSING_SERVICE_CONFIG",
24206
- message: `Container service "${name}" must specify an "entrypoint": a Dockerfile path to build, or a prebuilt OCI image reference.`,
24207
- serviceName: name
24208
- }
24209
- };
24237
+ let dockerfile;
24238
+ if (typeof entrypoint === "string") {
24239
+ if (!isDockerfileEntrypoint(entrypoint)) {
24240
+ return {
24241
+ error: {
24242
+ code: "INVALID_SERVICE_CONFIG",
24243
+ message: `Container service "${name}" has invalid "entrypoint" "${entrypoint}". It must name a Dockerfile or Containerfile.`,
24244
+ serviceName: name
24245
+ }
24246
+ };
24247
+ }
24248
+ dockerfile = import_path7.posix.normalize(entrypoint);
24249
+ } else {
24250
+ dockerfile = await detectContainerEntrypoint(serviceFs);
24251
+ if (!dockerfile) {
24252
+ return {
24253
+ error: {
24254
+ code: "MISSING_SERVICE_CONFIG",
24255
+ message: `Container service "${name}" has no "entrypoint" and no ${CONTAINER_ENTRYPOINT_CANDIDATES.join(
24256
+ ", "
24257
+ )} was found in "${normalizedRoot}".`,
24258
+ serviceName: name
24259
+ }
24260
+ };
24261
+ }
24210
24262
  }
24211
- const localSrc = dockerfile ?? image ?? "Dockerfile";
24212
- const builderSrc = isRoot ? localSrc : import_path7.posix.join(normalizedRoot, localSrc);
24263
+ const builderSrc = isRoot ? dockerfile : import_path7.posix.join(normalizedRoot, dockerfile);
24213
24264
  const builderConfig = { zeroConfig: true };
24214
24265
  if (!isRoot) {
24215
24266
  builderConfig.workspace = normalizedRoot;
24216
24267
  }
24217
- if (image) {
24218
- builderConfig.handler = image;
24219
- }
24220
24268
  const command = normalizeContainerCommand(config.command);
24221
24269
  if (command) {
24222
24270
  builderConfig.command = command;
@@ -24227,7 +24275,7 @@ var require_resolve_v2 = __commonJS({
24227
24275
  name,
24228
24276
  root: normalizedRoot,
24229
24277
  runtime: "container",
24230
- entrypoint: image ?? dockerfile,
24278
+ entrypoint: dockerfile,
24231
24279
  command,
24232
24280
  builder: {
24233
24281
  src: builderSrc,
@@ -24318,15 +24366,15 @@ var require_resolve_v2 = __commonJS({
24318
24366
  }
24319
24367
  async function resolveConfiguredServiceV22(name, config, fs5) {
24320
24368
  const normalizedRoot = (0, import_utils.stripTrailingSlash)(import_path7.posix.normalize(config.root));
24321
- const isContainer = config.runtime === "container" || typeof config.entrypoint === "string" && isDockerfileEntrypoint(config.entrypoint);
24322
- if (isContainer) {
24323
- return resolveContainerServiceV2(name, config, normalizedRoot);
24324
- }
24325
24369
  const serviceFsResult = normalizedRoot === "." ? { fs: fs5 } : await (0, import_resolve.getServiceFs)(fs5, name, normalizedRoot);
24326
24370
  if (serviceFsResult.error) {
24327
24371
  return { error: serviceFsResult.error };
24328
24372
  }
24329
24373
  const serviceFs = serviceFsResult.fs;
24374
+ const isContainer = config.runtime === "container" || typeof config.entrypoint === "string" && isDockerfileEntrypoint(config.entrypoint);
24375
+ if (isContainer) {
24376
+ return resolveContainerServiceV2(name, config, normalizedRoot, serviceFs);
24377
+ }
24330
24378
  const rawEntrypoint = config.entrypoint;
24331
24379
  const moduleAttr = typeof rawEntrypoint === "string" ? (0, import_resolve.parsePyModuleAttrEntrypoint)(rawEntrypoint) : null;
24332
24380
  let normalizedEntrypoint;
@@ -24579,8 +24627,9 @@ var require_auto_detect = __commonJS({
24579
24627
  async function detectServicesAtRoot(fs5, rootFramework, detectEntrypoint) {
24580
24628
  const services = {};
24581
24629
  services.frontend = {
24630
+ root: ".",
24582
24631
  framework: rootFramework.slug ?? void 0,
24583
- routePrefix: "/"
24632
+ mountPath: "/"
24584
24633
  };
24585
24634
  const backendResult = await detectBackendServices(fs5, detectEntrypoint);
24586
24635
  if (backendResult.error) {
@@ -24598,9 +24647,10 @@ var require_auto_detect = __commonJS({
24598
24647
  };
24599
24648
  }
24600
24649
  Object.assign(services, backendResult.services);
24650
+ const mountWarnings = (0, import_utils.assignMountPaths)(services);
24601
24651
  return {
24602
24652
  services,
24603
- warnings: [],
24653
+ warnings: mountWarnings,
24604
24654
  errors: []
24605
24655
  };
24606
24656
  }
@@ -24610,7 +24660,7 @@ var require_auto_detect = __commonJS({
24610
24660
  services[serviceName] = {
24611
24661
  framework: frontendFramework.slug ?? void 0,
24612
24662
  root: frontendLocation,
24613
- routePrefix: "/"
24663
+ mountPath: "/"
24614
24664
  };
24615
24665
  const backendResult = await detectBackendServices(fs5, detectEntrypoint);
24616
24666
  if (backendResult.error) {
@@ -24633,9 +24683,10 @@ var require_auto_detect = __commonJS({
24633
24683
  };
24634
24684
  }
24635
24685
  Object.assign(services, backendResult.services);
24686
+ const mountWarnings = (0, import_utils.assignMountPaths)(services);
24636
24687
  return {
24637
24688
  services,
24638
- warnings: [],
24689
+ warnings: mountWarnings,
24639
24690
  errors: []
24640
24691
  };
24641
24692
  }
@@ -24730,14 +24781,14 @@ var require_auto_detect = __commonJS({
24730
24781
  }
24731
24782
  const framework = frameworks2[0];
24732
24783
  const slug = framework.slug ?? void 0;
24733
- const routePrefix = `/_/${serviceName}`;
24784
+ const mountPath = `/${serviceName}`;
24734
24785
  const detected = detectEntrypoint && !(0, import_utils.isFrontendFramework)(slug) ? await detectEntrypoint({ workPath: dirPath, framework: slug }) : null;
24735
24786
  return {
24736
24787
  service: {
24737
24788
  framework: slug,
24738
24789
  root: dirPath,
24739
24790
  ...detected ? { entrypoint: detected.entrypoint } : {},
24740
- routePrefix
24791
+ mountPath
24741
24792
  }
24742
24793
  };
24743
24794
  }
@@ -24869,18 +24920,17 @@ var require_detect_railway = __commonJS({
24869
24920
  }
24870
24921
  const framework = frameworks2[0];
24871
24922
  const slug = framework.slug ?? void 0;
24872
- let serviceConfig = {};
24873
- serviceConfig.framework = slug;
24874
- if (cf.dirPath !== ".") {
24875
- serviceConfig.root = cf.dirPath;
24876
- if (detectEntrypoint && !(0, import_utils.isFrontendFramework)(slug)) {
24877
- const detected = await detectEntrypoint({
24878
- workPath: cf.dirPath,
24879
- framework: slug
24880
- });
24881
- if (detected) {
24882
- serviceConfig.entrypoint = detected.entrypoint;
24883
- }
24923
+ const serviceConfig = {
24924
+ root: cf.dirPath,
24925
+ framework: slug
24926
+ };
24927
+ if (cf.dirPath !== "." && detectEntrypoint && !(0, import_utils.isFrontendFramework)(slug)) {
24928
+ const detected = await detectEntrypoint({
24929
+ workPath: cf.dirPath,
24930
+ framework: slug
24931
+ });
24932
+ if (detected) {
24933
+ serviceConfig.entrypoint = detected.entrypoint;
24884
24934
  }
24885
24935
  }
24886
24936
  if (cf.config.build?.buildCommand) {
@@ -24899,7 +24949,7 @@ var require_detect_railway = __commonJS({
24899
24949
  if (serviceNames.length === 0) {
24900
24950
  return { services: null, errors: [], warnings };
24901
24951
  }
24902
- warnings.push(...(0, import_utils.assignRoutePrefixes)(services));
24952
+ warnings.push(...(0, import_utils.assignMountPaths)(services));
24903
24953
  return { services, errors: [], warnings };
24904
24954
  }
24905
24955
  async function findRailwayConfigs(fs5, dirPath = ".", depth = 0) {
@@ -27966,7 +28016,7 @@ var require_detect_render = __commonJS({
27966
28016
  const name = rs.name ?? "unnamed";
27967
28017
  const hint = {
27968
28018
  entrypoint: rs.rootDir ?? "<path-to-entrypoint>",
27969
- routePrefix: `/_/${name}`
28019
+ mountPath: `/api/${name}`
27970
28020
  };
27971
28021
  warnings.push({
27972
28022
  code: "RENDER_PSERV_HINT",
@@ -28020,19 +28070,18 @@ var require_detect_render = __commonJS({
28020
28070
  }
28021
28071
  const framework = frameworks2[0];
28022
28072
  const vercelType = SERVICE_TYPE_MAP[serviceType];
28023
- const serviceConfig = {};
28024
- serviceConfig.type = vercelType;
28025
- serviceConfig.framework = framework.slug ?? void 0;
28026
- if (rootDir !== ".") {
28027
- serviceConfig.root = rootDir;
28028
- if (detectEntrypoint && !(0, import_utils.isFrontendFramework)(serviceConfig.framework)) {
28029
- const detected = await detectEntrypoint({
28030
- workPath: rootDir,
28031
- framework: serviceConfig.framework
28032
- });
28033
- if (detected) {
28034
- serviceConfig.entrypoint = detected.entrypoint;
28035
- }
28073
+ const serviceConfig = {
28074
+ root: rootDir,
28075
+ type: vercelType,
28076
+ framework: framework.slug ?? void 0
28077
+ };
28078
+ if (rootDir !== "." && detectEntrypoint && !(0, import_utils.isFrontendFramework)(serviceConfig.framework)) {
28079
+ const detected = await detectEntrypoint({
28080
+ workPath: rootDir,
28081
+ framework: serviceConfig.framework
28082
+ });
28083
+ if (detected) {
28084
+ serviceConfig.entrypoint = detected.entrypoint;
28036
28085
  }
28037
28086
  }
28038
28087
  const buildCommand = (0, import_utils.combineBuildCommand)(
@@ -28050,7 +28099,7 @@ var require_detect_render = __commonJS({
28050
28099
  if (Object.keys(services).length === 0) {
28051
28100
  return { services: null, errors: [], warnings };
28052
28101
  }
28053
- warnings.push(...(0, import_utils.assignRoutePrefixes)(services));
28102
+ warnings.push(...(0, import_utils.assignMountPaths)(services));
28054
28103
  return { services, errors: [], warnings };
28055
28104
  }
28056
28105
  async function readRenderYaml(fs5) {
@@ -28207,6 +28256,7 @@ var require_detect_procfile = __commonJS({
28207
28256
  if (isWorkerLikeProcess) {
28208
28257
  if (hasSupportedWorkerCommand(tokens) && entrypoint?.endsWith(".py")) {
28209
28258
  services[processType] = {
28259
+ root: ".",
28210
28260
  type: "worker",
28211
28261
  entrypoint,
28212
28262
  runtime: "python"
@@ -28223,12 +28273,12 @@ var require_detect_procfile = __commonJS({
28223
28273
  });
28224
28274
  continue;
28225
28275
  }
28226
- const serviceConfig = { type: "web" };
28227
- if (detectedFramework) {
28228
- serviceConfig.framework = detectedFramework.slug ?? void 0;
28229
- }
28230
- serviceConfig.entrypoint = entrypoint ?? ".";
28231
- services[processType] = serviceConfig;
28276
+ services[processType] = {
28277
+ root: ".",
28278
+ type: "web",
28279
+ ...detectedFramework?.slug ? { framework: detectedFramework.slug } : {},
28280
+ entrypoint: entrypoint ?? "."
28281
+ };
28232
28282
  }
28233
28283
  if (errors.length > 0) {
28234
28284
  return { services: null, errors, warnings };
@@ -28244,7 +28294,7 @@ var require_detect_procfile = __commonJS({
28244
28294
  firstService.buildCommand = releaseCommand;
28245
28295
  }
28246
28296
  }
28247
- warnings.push(...(0, import_utils.assignRoutePrefixes)(services));
28297
+ warnings.push(...(0, import_utils.assignMountPaths)(services));
28248
28298
  return { services, errors: [], warnings };
28249
28299
  }
28250
28300
  function parseProcfile(content) {
@@ -28361,6 +28411,7 @@ var require_detect_services = __commonJS({
28361
28411
  var detect_services_exports = {};
28362
28412
  __export2(detect_services_exports, {
28363
28413
  detectServices: () => detectServices2,
28414
+ generateServiceRewrites: () => generateServiceRewrites,
28364
28415
  generateServicesRoutes: () => generateServicesRoutes2
28365
28416
  });
28366
28417
  module2.exports = __toCommonJS2(detect_services_exports);
@@ -28393,6 +28444,7 @@ var require_detect_services = __commonJS({
28393
28444
  source: resolved.source,
28394
28445
  useImplicitEnvInjection: resolved.useImplicitEnvInjection,
28395
28446
  routes: resolved.routes,
28447
+ rewrites: resolved.rewrites,
28396
28448
  errors: resolved.errors,
28397
28449
  warnings: resolved.warnings,
28398
28450
  resolved,
@@ -28402,18 +28454,17 @@ var require_detect_services = __commonJS({
28402
28454
  function toInferredLayoutConfig(services) {
28403
28455
  const inferredConfig = {};
28404
28456
  for (const [name, service] of Object.entries(services)) {
28405
- const serviceConfig = {};
28457
+ const serviceConfig = {
28458
+ root: service.root
28459
+ };
28406
28460
  if (service.type) {
28407
28461
  serviceConfig.type = service.type;
28408
28462
  }
28409
- if (typeof service.root === "string") {
28410
- serviceConfig.root = service.root;
28411
- }
28412
28463
  if (typeof service.entrypoint === "string") {
28413
28464
  serviceConfig.entrypoint = service.entrypoint;
28414
28465
  }
28415
- if (typeof service.routePrefix === "string") {
28416
- serviceConfig.routePrefix = service.routePrefix;
28466
+ if (typeof service.mountPath === "string") {
28467
+ serviceConfig.mountPath = service.mountPath;
28417
28468
  }
28418
28469
  if ((0, import_utils.isFrontendFramework)(service.framework)) {
28419
28470
  serviceConfig.framework = service.framework;
@@ -28444,6 +28495,7 @@ var require_detect_services = __commonJS({
28444
28495
  source: "configured",
28445
28496
  useImplicitEnvInjection: true,
28446
28497
  routes: emptyRoutes(),
28498
+ rewrites: [],
28447
28499
  errors: [configError],
28448
28500
  warnings: []
28449
28501
  });
@@ -28454,6 +28506,7 @@ var require_detect_services = __commonJS({
28454
28506
  source: "configured",
28455
28507
  useImplicitEnvInjection: false,
28456
28508
  routes: emptyRoutes(),
28509
+ rewrites: [],
28457
28510
  errors: [
28458
28511
  {
28459
28512
  code: "SERVICES_AND_EXPERIMENTAL_SERVICES_V2",
@@ -28466,63 +28519,66 @@ var require_detect_services = __commonJS({
28466
28519
  const hasProvidedConfiguredServices = providedConfiguredServices && Object.keys(providedConfiguredServices).length > 0;
28467
28520
  const experimentalServicesV2 = hasProvidedConfiguredServices && (providedConfiguredServicesType === "services" || providedConfiguredServicesType === "experimentalServicesV2") ? providedConfiguredServices : hasProvidedConfiguredServices ? void 0 : vercelConfig?.services ?? vercelConfig?.experimentalServicesV2;
28468
28521
  if (experimentalServicesV2 && Object.keys(experimentalServicesV2).length > 0) {
28469
- const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(
28522
+ const result = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(
28470
28523
  experimentalServicesV2,
28471
28524
  scopedFs
28472
28525
  );
28473
28526
  return withResolvedResult({
28474
- services: result2.services,
28527
+ services: result.services,
28475
28528
  source: "configured",
28476
28529
  // V2 uses explicit `bindings`, so no implicit `{NAME}_URL` injection.
28477
28530
  useImplicitEnvInjection: false,
28478
28531
  // V2 routes are explicitly carried per-service to output them separately.
28479
28532
  routes: emptyRoutes(),
28480
- errors: result2.errors,
28533
+ rewrites: [],
28534
+ errors: result.errors,
28481
28535
  warnings: []
28482
28536
  });
28483
28537
  }
28484
28538
  const experimentalServicesV1 = hasProvidedConfiguredServices ? providedConfiguredServices : vercelConfig?.experimentalServices;
28485
28539
  const hasExperimentalServicesV1 = experimentalServicesV1 && Object.keys(experimentalServicesV1).length > 0;
28486
- if (!hasExperimentalServicesV1) {
28487
- const detectors = [
28488
- { detect: import_detect_railway.detectRailwayServices, source: "railway" },
28489
- { detect: import_detect_render.detectRenderServices, source: "render" },
28490
- { detect: import_detect_procfile.detectProcfileServices, source: "procfile" },
28491
- { detect: import_auto_detect.autoDetectServices, source: "layout" }
28492
- ];
28493
- for (const { detect, source } of detectors) {
28494
- const detectResult = await detect({ fs: scopedFs, detectEntrypoint });
28495
- const match = await tryResolveInferred(detectResult, source, scopedFs);
28496
- if (match)
28497
- return match;
28498
- }
28540
+ if (hasExperimentalServicesV1) {
28541
+ const result = await (0, import_resolve.resolveAllConfiguredServices)(
28542
+ experimentalServicesV1,
28543
+ scopedFs,
28544
+ "configured"
28545
+ );
28546
+ const routes = generateServicesRoutes2(result.services);
28499
28547
  return withResolvedResult({
28500
- services: [],
28501
- source: "auto-detected",
28548
+ services: result.services,
28549
+ source: "configured",
28550
+ // experimentalServices uses the legacy `{NAME}_URL` injection.
28502
28551
  useImplicitEnvInjection: true,
28503
- routes: emptyRoutes(),
28504
- errors: [
28505
- {
28506
- code: "NO_EXPERIMENTAL_SERVICES_CONFIGURED",
28507
- message: "No services configured. Add `experimentalServices` to vercel.json."
28508
- }
28509
- ],
28552
+ routes,
28553
+ rewrites: [],
28554
+ errors: result.errors,
28510
28555
  warnings: []
28511
28556
  });
28512
28557
  }
28513
- const result = await (0, import_resolve.resolveAllConfiguredServices)(
28514
- experimentalServicesV1,
28515
- scopedFs,
28516
- "configured"
28517
- );
28518
- const routes = generateServicesRoutes2(result.services);
28558
+ const detectors = [
28559
+ { detect: import_detect_railway.detectRailwayServices, source: "railway" },
28560
+ { detect: import_detect_render.detectRenderServices, source: "render" },
28561
+ { detect: import_detect_procfile.detectProcfileServices, source: "procfile" },
28562
+ { detect: import_auto_detect.autoDetectServices, source: "layout" }
28563
+ ];
28564
+ for (const { detect, source } of detectors) {
28565
+ const detectResult = await detect({ fs: scopedFs, detectEntrypoint });
28566
+ const match = await tryResolveInferred(detectResult, source, scopedFs);
28567
+ if (match)
28568
+ return match;
28569
+ }
28519
28570
  return withResolvedResult({
28520
- services: result.services,
28521
- source: "configured",
28522
- // experimentalServices uses the legacy `{NAME}_URL` injection.
28571
+ services: [],
28572
+ source: "auto-detected",
28523
28573
  useImplicitEnvInjection: true,
28524
- routes,
28525
- errors: result.errors,
28574
+ routes: emptyRoutes(),
28575
+ rewrites: [],
28576
+ errors: [
28577
+ {
28578
+ code: "NO_EXPERIMENTAL_SERVICES_CONFIGURED",
28579
+ message: "No services configured. Add `experimentalServices` to vercel.json."
28580
+ }
28581
+ ],
28526
28582
  warnings: []
28527
28583
  });
28528
28584
  }
@@ -28531,8 +28587,9 @@ var require_detect_services = __commonJS({
28531
28587
  return withResolvedResult({
28532
28588
  services: [],
28533
28589
  source: "auto-detected",
28534
- useImplicitEnvInjection: true,
28590
+ useImplicitEnvInjection: source !== "layout",
28535
28591
  routes: emptyRoutes(),
28592
+ rewrites: [],
28536
28593
  errors: detectResult.errors,
28537
28594
  warnings: detectResult.warnings
28538
28595
  });
@@ -28540,52 +28597,96 @@ var require_detect_services = __commonJS({
28540
28597
  if (!detectResult.services) {
28541
28598
  return null;
28542
28599
  }
28600
+ if (source === "layout") {
28601
+ const v2Services = {};
28602
+ for (const [name, svc] of Object.entries(detectResult.services)) {
28603
+ v2Services[name] = {
28604
+ root: svc.root,
28605
+ ...svc.framework ? { framework: svc.framework } : {},
28606
+ ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {}
28607
+ };
28608
+ }
28609
+ const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(v2Services, scopedFs);
28610
+ const rootServices = Object.values(detectResult.services).filter(
28611
+ (svc) => svc.mountPath === "/" && typeof svc.framework === "string"
28612
+ );
28613
+ const shouldInfer2 = result2.errors.length === 0 && rootServices.length === 1 && result2.services.length > 1;
28614
+ const inferred2 = shouldInfer2 ? {
28615
+ source,
28616
+ config: toInferredLayoutConfig(detectResult.services),
28617
+ services: result2.services,
28618
+ warnings: detectResult.warnings
28619
+ } : null;
28620
+ return withResolvedResult(
28621
+ {
28622
+ services: shouldInfer2 ? result2.services : [],
28623
+ source: "auto-detected",
28624
+ useImplicitEnvInjection: false,
28625
+ routes: emptyRoutes(),
28626
+ rewrites: shouldInfer2 ? generateServiceRewrites(detectResult.services) : [],
28627
+ experimentalServicesV2: shouldInfer2 ? v2Services : void 0,
28628
+ errors: result2.errors,
28629
+ warnings: detectResult.warnings
28630
+ },
28631
+ inferred2
28632
+ );
28633
+ }
28634
+ const v1Services = {};
28635
+ for (const [name, svc] of Object.entries(detectResult.services)) {
28636
+ v1Services[name] = {
28637
+ root: svc.root === "." ? void 0 : svc.root,
28638
+ ...svc.framework ? { framework: svc.framework } : {},
28639
+ ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {},
28640
+ ...svc.type ? { type: svc.type } : {},
28641
+ ...svc.buildCommand ? { buildCommand: svc.buildCommand } : {},
28642
+ ...svc.preDeployCommand ? { preDeployCommand: svc.preDeployCommand } : {},
28643
+ ...svc.mountPath ? { routePrefix: svc.mountPath } : {}
28644
+ };
28645
+ }
28543
28646
  const result = await (0, import_resolve.resolveAllConfiguredServices)(
28544
- detectResult.services,
28647
+ v1Services,
28545
28648
  scopedFs,
28546
28649
  "generated"
28547
28650
  );
28548
- let shouldInfer;
28549
- if (source === "layout") {
28550
- const rootWebFrameworkServices = result.services.filter(
28551
- (service) => service.type === "web" && service.routePrefix === "/" && typeof service.framework === "string"
28552
- );
28553
- shouldInfer = result.errors.length === 0 && rootWebFrameworkServices.length === 1 && result.services.length > 1;
28554
- } else {
28555
- shouldInfer = result.errors.length === 0 && result.services.length > 0;
28556
- }
28651
+ const shouldInfer = result.errors.length === 0 && result.services.length > 0;
28557
28652
  const inferred = shouldInfer ? {
28558
28653
  source,
28559
28654
  config: toInferredLayoutConfig(detectResult.services),
28560
28655
  services: result.services,
28561
28656
  warnings: detectResult.warnings
28562
28657
  } : null;
28563
- if (source === "layout" && shouldInfer) {
28564
- const routes = generateServicesRoutes2(result.services);
28565
- return withResolvedResult(
28566
- {
28567
- services: result.services,
28568
- source: "auto-detected",
28569
- useImplicitEnvInjection: true,
28570
- routes,
28571
- errors: result.errors,
28572
- warnings: detectResult.warnings
28573
- },
28574
- inferred
28575
- );
28576
- }
28577
28658
  return withResolvedResult(
28578
28659
  {
28579
28660
  services: [],
28580
28661
  source: "auto-detected",
28581
28662
  useImplicitEnvInjection: true,
28582
28663
  routes: emptyRoutes(),
28664
+ rewrites: [],
28583
28665
  errors: result.errors,
28584
28666
  warnings: detectResult.warnings
28585
28667
  },
28586
28668
  inferred
28587
28669
  );
28588
28670
  }
28671
+ function generateServiceRewrites(services) {
28672
+ const entries = Object.entries(services).filter(
28673
+ ([, svc]) => typeof svc.mountPath === "string" && (!svc.type || svc.type === "web")
28674
+ ).sort(([, a], [, b]) => b.mountPath.length - a.mountPath.length);
28675
+ return entries.map(([name, svc]) => {
28676
+ const mountPath = svc.mountPath;
28677
+ if (mountPath === "/") {
28678
+ return {
28679
+ source: "/(.*)",
28680
+ destination: { type: "service", service: name }
28681
+ };
28682
+ }
28683
+ const prefix = mountPath.startsWith("/") ? mountPath.slice(1) : mountPath;
28684
+ return {
28685
+ source: `/${prefix}(/.*)?`,
28686
+ destination: { type: "service", service: name }
28687
+ };
28688
+ });
28689
+ }
28589
28690
  function generateServicesRoutes2(allServices) {
28590
28691
  const services = allServices.filter(import_build_utils5.isExperimentalService);
28591
28692
  const hostRewrites = [];
@@ -29042,6 +29143,8 @@ var require_get_services_builders = __commonJS({
29042
29143
  ...result.routes.crons
29043
29144
  ] : null,
29044
29145
  errorRoutes: [],
29146
+ serviceRewrites: result.rewrites.length > 0 ? result.rewrites : void 0,
29147
+ experimentalServicesV2: result.experimentalServicesV2,
29045
29148
  services: result.services,
29046
29149
  useImplicitEnvInjection: result.useImplicitEnvInjection
29047
29150
  };
@@ -29653,7 +29756,7 @@ var require_detect_builders = __commonJS({
29653
29756
  }
29654
29757
  }
29655
29758
  }
29656
- 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)("backends", frontendBuilder.use))) {
29759
+ 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))) {
29657
29760
  return null;
29658
29761
  }
29659
29762
  if (unusedFunctions.size) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/static-build",
3
- "version": "2.11.3",
3
+ "version": "2.11.4",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/build-step",
@@ -14,9 +14,9 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "ts-morph": "12.0.0",
17
- "@vercel/gatsby-plugin-vercel-analytics": "1.0.11",
18
- "@vercel/gatsby-plugin-vercel-builder": "2.2.23",
19
- "@vercel/static-config": "3.4.0"
17
+ "@vercel/static-config": "3.4.0",
18
+ "@vercel/gatsby-plugin-vercel-builder": "2.2.24",
19
+ "@vercel/gatsby-plugin-vercel-analytics": "1.0.11"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/aws-lambda": "8.10.64",
@@ -37,11 +37,11 @@
37
37
  "semver": "7.5.2",
38
38
  "tree-kill": "1.2.2",
39
39
  "vitest": "2.0.3",
40
- "@vercel/build-utils": "13.32.1",
41
40
  "@vercel/error-utils": "2.2.0",
42
- "@vercel/frameworks": "3.30.0",
43
- "@vercel/fs-detectors": "6.10.1",
44
- "@vercel/routing-utils": "6.3.1"
41
+ "@vercel/frameworks": "3.30.1",
42
+ "@vercel/build-utils": "13.32.2",
43
+ "@vercel/fs-detectors": "6.11.1",
44
+ "@vercel/routing-utils": "6.4.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "node ../../utils/build-builder.mjs",