@vercel/static-build 2.11.1 → 2.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +186 -12
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -7160,6 +7160,53 @@ var require_frameworks = __commonJS({
7160
7160
  __reExport(frameworks_exports, require_types(), module2.exports);
7161
7161
  var { readdir, readFile, unlink } = import_fs5.promises;
7162
7162
  var frameworks2 = [
7163
+ {
7164
+ // A `Dockerfile.vercel` / `Containerfile.vercel` is an explicit opt-in to
7165
+ // deploy a project as a container, regardless of any other framework that
7166
+ // may also be detected. It is listed first so that framework detection
7167
+ // (which returns the first match in list order) selects it over everything
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`).
7172
+ name: "Container",
7173
+ slug: "container",
7174
+ experimental: true,
7175
+ runtimeFramework: true,
7176
+ logo: "https://api-frameworks.vercel.sh/framework-logos/container.svg",
7177
+ tagline: "Deploy any project as a container image built from a Dockerfile.",
7178
+ description: "A project deployed as a container image, built from a Dockerfile.vercel or Containerfile.vercel.",
7179
+ website: "https://docs.docker.com/reference/dockerfile/",
7180
+ useRuntime: { src: "<detect>", use: "@vercel/container" },
7181
+ detectors: {
7182
+ some: [
7183
+ {
7184
+ path: "Dockerfile.vercel"
7185
+ },
7186
+ {
7187
+ path: "Containerfile.vercel"
7188
+ }
7189
+ ]
7190
+ },
7191
+ settings: {
7192
+ installCommand: {
7193
+ placeholder: "None",
7194
+ value: null
7195
+ },
7196
+ buildCommand: {
7197
+ placeholder: "None",
7198
+ value: null
7199
+ },
7200
+ devCommand: {
7201
+ placeholder: "None",
7202
+ value: null
7203
+ },
7204
+ outputDirectory: {
7205
+ placeholder: "None"
7206
+ }
7207
+ },
7208
+ getOutputDirName: async () => "public"
7209
+ },
7163
7210
  {
7164
7211
  name: "Blitz.js (Legacy)",
7165
7212
  slug: "blitzjs",
@@ -21767,7 +21814,8 @@ var require_types3 = __commonJS({
21767
21814
  python: "@vercel/python",
21768
21815
  go: "@vercel/go",
21769
21816
  rust: "@vercel/rust",
21770
- ruby: "@vercel/ruby"
21817
+ ruby: "@vercel/ruby",
21818
+ container: "@vercel/container"
21771
21819
  };
21772
21820
  var RUNTIME_MANIFESTS = {
21773
21821
  node: ["package.json"],
@@ -23253,6 +23301,12 @@ var require_resolve = __commonJS({
23253
23301
  "python",
23254
23302
  "go"
23255
23303
  ]);
23304
+ function isContainerRuntime(config) {
23305
+ return config.runtime === "container";
23306
+ }
23307
+ function normalizeContainerCommand(command) {
23308
+ return Array.isArray(command) ? command : [command];
23309
+ }
23256
23310
  async function getServiceFs(fs5, serviceName, root) {
23257
23311
  if (!root) {
23258
23312
  return { fs: fs5 };
@@ -23338,6 +23392,10 @@ var require_resolve = __commonJS({
23338
23392
  }
23339
23393
  };
23340
23394
  }
23395
+ function isDockerfileEntrypoint(entrypoint) {
23396
+ const base = import_path7.posix.basename(entrypoint).toLowerCase();
23397
+ return base === "dockerfile" || base === "containerfile" || base.endsWith(".dockerfile");
23398
+ }
23341
23399
  function toWorkspaceRelativeEntrypoint(entrypoint, workspace) {
23342
23400
  const normalizedEntrypoint = import_path7.posix.normalize(entrypoint);
23343
23401
  if (workspace === ".") {
@@ -23716,6 +23774,13 @@ var require_resolve = __commonJS({
23716
23774
  serviceName: name
23717
23775
  };
23718
23776
  }
23777
+ if (config.command !== void 0 && !isContainerRuntime(config)) {
23778
+ return {
23779
+ code: "INVALID_COMMAND",
23780
+ message: `Service "${name}" can only specify "command" when using runtime "container".`,
23781
+ serviceName: name
23782
+ };
23783
+ }
23719
23784
  return null;
23720
23785
  }
23721
23786
  function validateServiceEntrypoint(name, config, resolvedEntrypoint) {
@@ -23756,8 +23821,11 @@ var require_resolve = __commonJS({
23756
23821
  const configuredRoutePrefix = routingResult.routing?.routePrefix;
23757
23822
  const configuredSubdomain = routingResult.routing?.subdomain;
23758
23823
  const routePrefixWasConfigured = routingResult.routing?.routePrefixConfigured ?? false;
23824
+ const containerEntrypoint = isContainerRuntime(config) && typeof rawEntrypoint === "string" ? rawEntrypoint : void 0;
23825
+ const containerDockerfile = containerEntrypoint && isDockerfileEntrypoint(containerEntrypoint) ? import_path7.posix.normalize(containerEntrypoint) : void 0;
23826
+ const containerImage = containerEntrypoint && !containerDockerfile ? containerEntrypoint : void 0;
23759
23827
  let resolvedEntrypointPath = resolvedEntrypoint;
23760
- if (!resolvedEntrypointPath && typeof rawEntrypoint === "string") {
23828
+ if (!containerEntrypoint && !resolvedEntrypointPath && typeof rawEntrypoint === "string") {
23761
23829
  const entrypointToResolve = moduleAttrParsed ? moduleAttrParsed.filePath : rawEntrypoint;
23762
23830
  const resolved = await resolveEntrypointPath({
23763
23831
  fs: serviceFs,
@@ -23766,7 +23834,7 @@ var require_resolve = __commonJS({
23766
23834
  });
23767
23835
  resolvedEntrypointPath = resolved.entrypoint;
23768
23836
  }
23769
- if (typeof rawEntrypoint === "string" && !resolvedEntrypointPath) {
23837
+ if (!containerEntrypoint && typeof rawEntrypoint === "string" && !resolvedEntrypointPath) {
23770
23838
  throw new Error(
23771
23839
  `Failed to resolve entrypoint "${rawEntrypoint}" for service "${name}".`
23772
23840
  );
@@ -23830,7 +23898,7 @@ var require_resolve = __commonJS({
23830
23898
  } else {
23831
23899
  builderUse = (0, import_utils.getBuilderForRuntime)(inferredRuntime);
23832
23900
  }
23833
- builderSrc = resolvedEntrypointFile;
23901
+ builderSrc = inferredRuntime === "container" && typeof containerEntrypoint === "string" ? containerEntrypoint : resolvedEntrypointFile;
23834
23902
  }
23835
23903
  const normalizedSubdomain = type === "web" && typeof configuredSubdomain === "string" ? configuredSubdomain.toLowerCase() : void 0;
23836
23904
  const defaultRoutePrefix = type === "web" && normalizedSubdomain ? `/_/${name}` : void 0;
@@ -23864,6 +23932,12 @@ var require_resolve = __commonJS({
23864
23932
  if (config.framework) {
23865
23933
  builderConfig.framework = config.framework;
23866
23934
  }
23935
+ if (containerImage) {
23936
+ builderConfig.handler = containerImage;
23937
+ }
23938
+ if (config.command !== void 0) {
23939
+ builderConfig.command = normalizeContainerCommand(config.command);
23940
+ }
23867
23941
  if (moduleAttrParsed) {
23868
23942
  builderConfig.handlerFunction = moduleAttrParsed.attrName;
23869
23943
  }
@@ -23874,7 +23948,7 @@ var require_resolve = __commonJS({
23874
23948
  trigger,
23875
23949
  group,
23876
23950
  workspace,
23877
- entrypoint: resolvedEntrypointFile,
23951
+ entrypoint: containerImage ?? containerDockerfile ?? resolvedEntrypointFile,
23878
23952
  routePrefix,
23879
23953
  routePrefixSource: resolvedRoutePrefixSource,
23880
23954
  subdomain: normalizedSubdomain,
@@ -23913,7 +23987,7 @@ var require_resolve = __commonJS({
23913
23987
  }
23914
23988
  const serviceFs = serviceFsResult.fs;
23915
23989
  let resolvedEntrypoint;
23916
- if (typeof serviceConfig.entrypoint === "string") {
23990
+ if (typeof serviceConfig.entrypoint === "string" && !isContainerRuntime(serviceConfig)) {
23917
23991
  const moduleAttr = parsePyModuleAttrEntrypoint(serviceConfig.entrypoint);
23918
23992
  const entrypointToResolve = moduleAttr?.filePath ?? serviceConfig.entrypoint;
23919
23993
  const resolvedPath = await resolveEntrypointPath({
@@ -24110,6 +24184,67 @@ var require_resolve_v2 = __commonJS({
24110
24184
  var import_utils = require_utils4();
24111
24185
  var frameworksBySlug = new Map(import_frameworks2.frameworkList.map((f) => [f.slug, f]));
24112
24186
  var SERVICE_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
24187
+ function isDockerfileEntrypoint(entrypoint) {
24188
+ const base = import_path7.posix.basename(entrypoint).toLowerCase();
24189
+ return base === "dockerfile" || base === "containerfile" || base.endsWith(".dockerfile");
24190
+ }
24191
+ function normalizeContainerCommand(command) {
24192
+ if (command === void 0) {
24193
+ return void 0;
24194
+ }
24195
+ return Array.isArray(command) ? command : [command];
24196
+ }
24197
+ function resolveContainerServiceV2(name, config, normalizedRoot) {
24198
+ const isRoot = normalizedRoot === ".";
24199
+ 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
+ };
24210
+ }
24211
+ const localSrc = dockerfile ?? image ?? "Dockerfile";
24212
+ const builderSrc = isRoot ? localSrc : import_path7.posix.join(normalizedRoot, localSrc);
24213
+ const builderConfig = { zeroConfig: true };
24214
+ if (!isRoot) {
24215
+ builderConfig.workspace = normalizedRoot;
24216
+ }
24217
+ if (image) {
24218
+ builderConfig.handler = image;
24219
+ }
24220
+ const command = normalizeContainerCommand(config.command);
24221
+ if (command) {
24222
+ builderConfig.command = command;
24223
+ }
24224
+ return {
24225
+ service: {
24226
+ schema: "experimentalServicesV2",
24227
+ name,
24228
+ root: normalizedRoot,
24229
+ runtime: "container",
24230
+ entrypoint: image ?? dockerfile,
24231
+ command,
24232
+ builder: {
24233
+ src: builderSrc,
24234
+ use: "@vercel/container",
24235
+ config: builderConfig
24236
+ },
24237
+ bindings: config.bindings,
24238
+ functions: config.functions,
24239
+ headers: config.headers,
24240
+ redirects: config.redirects,
24241
+ rewrites: config.rewrites,
24242
+ routes: config.routes,
24243
+ cleanUrls: config.cleanUrls,
24244
+ trailingSlash: config.trailingSlash
24245
+ }
24246
+ };
24247
+ }
24113
24248
  function validateServiceConfigV22(name, config) {
24114
24249
  if (!SERVICE_NAME_REGEX.test(name)) {
24115
24250
  return {
@@ -24171,7 +24306,8 @@ var require_resolve_v2 = __commonJS({
24171
24306
  };
24172
24307
  }
24173
24308
  }
24174
- if (!config.framework && !config.entrypoint) {
24309
+ const isContainer = config.runtime === "container";
24310
+ if (!config.framework && !config.entrypoint && !isContainer) {
24175
24311
  return {
24176
24312
  code: "MISSING_SERVICE_CONFIG",
24177
24313
  message: `Service "${name}" must specify "framework" or "entrypoint".`,
@@ -24182,6 +24318,10 @@ var require_resolve_v2 = __commonJS({
24182
24318
  }
24183
24319
  async function resolveConfiguredServiceV22(name, config, fs5) {
24184
24320
  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
+ }
24185
24325
  const serviceFsResult = normalizedRoot === "." ? { fs: fs5 } : await (0, import_resolve.getServiceFs)(fs5, name, normalizedRoot);
24186
24326
  if (serviceFsResult.error) {
24187
24327
  return { error: serviceFsResult.error };
@@ -28308,8 +28448,23 @@ var require_detect_services = __commonJS({
28308
28448
  warnings: []
28309
28449
  });
28310
28450
  }
28451
+ if (vercelConfig?.services != null && vercelConfig.experimentalServicesV2 != null) {
28452
+ return withResolvedResult({
28453
+ services: [],
28454
+ source: "configured",
28455
+ useImplicitEnvInjection: false,
28456
+ routes: emptyRoutes(),
28457
+ errors: [
28458
+ {
28459
+ code: "SERVICES_AND_EXPERIMENTAL_SERVICES_V2",
28460
+ message: "The `services` property cannot be used in conjunction with its deprecated alias `experimentalServicesV2`. Please use only `services`."
28461
+ }
28462
+ ],
28463
+ warnings: []
28464
+ });
28465
+ }
28311
28466
  const hasProvidedConfiguredServices = providedConfiguredServices && Object.keys(providedConfiguredServices).length > 0;
28312
- const experimentalServicesV2 = hasProvidedConfiguredServices && providedConfiguredServicesType === "experimentalServicesV2" ? providedConfiguredServices : hasProvidedConfiguredServices ? void 0 : vercelConfig?.experimentalServicesV2;
28467
+ const experimentalServicesV2 = hasProvidedConfiguredServices && (providedConfiguredServicesType === "services" || providedConfiguredServicesType === "experimentalServicesV2") ? providedConfiguredServices : hasProvidedConfiguredServices ? void 0 : vercelConfig?.services ?? vercelConfig?.experimentalServicesV2;
28313
28468
  if (experimentalServicesV2 && Object.keys(experimentalServicesV2).length > 0) {
28314
28469
  const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(
28315
28470
  experimentalServicesV2,
@@ -28488,11 +28643,12 @@ var require_detect_services = __commonJS({
28488
28643
  }
28489
28644
  } else if (service.runtime) {
28490
28645
  const functionPath = (0, import_utils.getInternalServiceFunctionPath)(service.name);
28646
+ const check = service.runtime === "container" ? void 0 : true;
28491
28647
  if (routePrefix === "/") {
28492
28648
  defaults.push({
28493
28649
  src: (0, import_routing_utils.scopeRouteSourceToOwnership)("^/(.*)$", ownershipGuard),
28494
28650
  dest: functionPath,
28495
- check: true
28651
+ ...check ? { check } : {}
28496
28652
  });
28497
28653
  } else {
28498
28654
  rewrites.push({
@@ -28501,7 +28657,7 @@ var require_detect_services = __commonJS({
28501
28657
  ownershipGuard
28502
28658
  ),
28503
28659
  dest: functionPath,
28504
- check: true
28660
+ ...check ? { check } : {}
28505
28661
  });
28506
28662
  }
28507
28663
  }
@@ -29009,12 +29165,30 @@ var require_detect_builders = __commonJS({
29009
29165
  async function detectBuilders2(files, pkg, options = {}) {
29010
29166
  const {
29011
29167
  experimentalServices: experimentalServicesV1,
29168
+ services,
29012
29169
  experimentalServicesV2,
29013
29170
  projectSettings = {}
29014
29171
  } = options;
29172
+ if (services != null && experimentalServicesV2 != null) {
29173
+ return {
29174
+ builders: null,
29175
+ errors: [
29176
+ {
29177
+ code: "SERVICES_AND_EXPERIMENTAL_SERVICES_V2",
29178
+ message: "The `services` option cannot be used in conjunction with its deprecated alias `experimentalServicesV2`. Please use only `services`."
29179
+ }
29180
+ ],
29181
+ warnings: [],
29182
+ defaultRoutes: null,
29183
+ redirectRoutes: null,
29184
+ rewriteRoutes: null,
29185
+ errorRoutes: null
29186
+ };
29187
+ }
29015
29188
  const { framework } = projectSettings;
29016
- const configuredServices = experimentalServicesV2 ?? experimentalServicesV1;
29017
- const configuredServicesType = experimentalServicesV2 ? "experimentalServicesV2" : "experimentalServices";
29189
+ const servicesConfig = services ?? experimentalServicesV2;
29190
+ const configuredServices = servicesConfig ?? experimentalServicesV1;
29191
+ const configuredServicesType = servicesConfig ? services ? "services" : "experimentalServicesV2" : "experimentalServices";
29018
29192
  const hasServicesConfig = configuredServices != null && typeof configuredServices === "object";
29019
29193
  if (hasServicesConfig || framework === "services") {
29020
29194
  const result = await (0, import_get_services_builders.getServicesBuilders)({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/static-build",
3
- "version": "2.11.1",
3
+ "version": "2.11.3",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/build-step",
@@ -15,8 +15,8 @@
15
15
  "dependencies": {
16
16
  "ts-morph": "12.0.0",
17
17
  "@vercel/gatsby-plugin-vercel-analytics": "1.0.11",
18
- "@vercel/static-config": "3.4.0",
19
- "@vercel/gatsby-plugin-vercel-builder": "2.2.21"
18
+ "@vercel/gatsby-plugin-vercel-builder": "2.2.23",
19
+ "@vercel/static-config": "3.4.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/aws-lambda": "8.10.64",
@@ -37,10 +37,10 @@
37
37
  "semver": "7.5.2",
38
38
  "tree-kill": "1.2.2",
39
39
  "vitest": "2.0.3",
40
- "@vercel/build-utils": "13.31.1",
41
- "@vercel/frameworks": "3.29.1",
40
+ "@vercel/build-utils": "13.32.1",
42
41
  "@vercel/error-utils": "2.2.0",
43
- "@vercel/fs-detectors": "6.9.3",
42
+ "@vercel/frameworks": "3.30.0",
43
+ "@vercel/fs-detectors": "6.10.1",
44
44
  "@vercel/routing-utils": "6.3.1"
45
45
  },
46
46
  "scripts": {