@vercel/fs-detectors 7.3.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,8 @@ var import_minimatch = __toESM(require("minimatch"));
46
46
  var import_semver = require("semver");
47
47
  var import_path = require("path");
48
48
  var import_frameworks = require("@vercel/frameworks");
49
+ var import_framework = require("./services/runtimes/framework");
50
+ var import_constants = require("./services/runtimes/constants");
49
51
  var import_is_official_runtime = require("./is-official-runtime");
50
52
  var import_build_utils = require("@vercel/build-utils");
51
53
  var import_python = require("./python");
@@ -75,9 +77,6 @@ function getStaticFilesPattern(additionalExclusions = []) {
75
77
  ].join(",")}}`;
76
78
  }
77
79
  const REGEX_NON_VERCEL_PLATFORM_FILES = getStaticFilesPattern();
78
- const slugToFramework = new Map(
79
- import_frameworks.frameworkList.map((f) => [f.slug, f])
80
- );
81
80
  const builderToFrameworks = (() => {
82
81
  const map = /* @__PURE__ */ new Map();
83
82
  for (const f of import_frameworks.frameworkList) {
@@ -162,7 +161,7 @@ async function detectBuilders(files, pkg, options = {}) {
162
161
  };
163
162
  const absolutePathCache = /* @__PURE__ */ new Map();
164
163
  const { buildCommand, outputDirectory } = projectSettings;
165
- const frameworkConfig = slugToFramework.get(framework || "");
164
+ const frameworkConfig = import_framework.frameworksBySlug.get(framework || "");
166
165
  const rustStaticOutput = isRustStaticOutput(framework, projectSettings);
167
166
  const ignoreRuntimes = new Set(
168
167
  rustStaticOutput ? void 0 : frameworkConfig?.ignoreRuntimes
@@ -533,6 +532,14 @@ function validateProxy(options, files, framework) {
533
532
  message: `The \`proxy\` property cannot be used with ${framework === "nextjs" ? "Next.js" : "Astro"} because the framework builds its own routing middleware.`
534
533
  };
535
534
  }
535
+ const appRuntime = (0, import_framework.inferBuilderRuntimeFromFramework)(framework);
536
+ const proxyRuntime = import_constants.ENTRYPOINT_EXTENSIONS[(0, import_path.extname)(proxy.entrypoint)];
537
+ if (appRuntime !== void 0 && proxyRuntime !== void 0 && appRuntime !== proxyRuntime) {
538
+ return {
539
+ code: "proxy_runtime_mismatch",
540
+ 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.`
541
+ };
542
+ }
536
543
  return null;
537
544
  }
538
545
  function hasBuildScript(pkg) {
@@ -587,7 +594,7 @@ function detectFrontBuilder(pkg, files, usedFunctions, fallbackEntrypoint, optio
587
594
  }
588
595
  });
589
596
  }
590
- const f = slugToFramework.get(framework || "");
597
+ const f = import_framework.frameworksBySlug.get(framework || "");
591
598
  if (f && f.useRuntime && !isRustStaticOutput(framework, projectSettings)) {
592
599
  const buildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(framework);
593
600
  if (buildpackRuntime && (import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? []).some(
@@ -906,7 +913,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
906
913
  const framework = frontendBuilder?.config?.framework || "";
907
914
  const isGatsby = framework === "gatsby";
908
915
  const isNextjs = framework === "nextjs" || (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder?.use);
909
- const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
916
+ const ignoreRuntimes = import_framework.frameworksBySlug.get(framework)?.ignoreRuntimes;
910
917
  if (apiRoutes && apiRoutes.length > 0) {
911
918
  if (options.featHandleMiss) {
912
919
  const extSet = detectApiExtensions(apiBuilders);
@@ -2,6 +2,10 @@ import type { ServiceRuntime } from '@vercel/build-utils';
2
2
  export declare const RUNTIME_BUILDERS: Record<ServiceRuntime, string>;
3
3
  export declare const RUNTIME_MANIFESTS: Partial<Record<ServiceRuntime, string[]>>;
4
4
  export declare const ENTRYPOINT_EXTENSIONS: Record<string, ServiceRuntime>;
5
+ /**
6
+ * The inverse of RUNTIME_BUILDERS. Maps each builder to its runtime.
7
+ */
8
+ export declare const BUILDER_RUNTIMES: Record<string, ServiceRuntime>;
5
9
  /**
6
10
  * Builders that produce static output (SPAs, static sites) with no runtime.
7
11
  */
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var constants_exports = {};
20
20
  __export(constants_exports, {
21
+ BUILDER_RUNTIMES: () => BUILDER_RUNTIMES,
21
22
  CONTAINER_ENTRYPOINT_CANDIDATES: () => CONTAINER_ENTRYPOINT_CANDIDATES,
22
23
  ENTRYPOINT_EXTENSIONS: () => ENTRYPOINT_EXTENSIONS,
23
24
  ROUTE_OWNING_BUILDERS: () => ROUTE_OWNING_BUILDERS,
@@ -60,6 +61,12 @@ const ENTRYPOINT_EXTENSIONS = {
60
61
  ".rb": "ruby",
61
62
  ".ru": "ruby"
62
63
  };
64
+ const BUILDER_RUNTIMES = Object.fromEntries(
65
+ Object.entries(RUNTIME_BUILDERS).map(([runtime, builder]) => [
66
+ builder,
67
+ runtime
68
+ ])
69
+ );
63
70
  const STATIC_BUILDERS = /* @__PURE__ */ new Set([
64
71
  "@vercel/static-build",
65
72
  "@vercel/static"
@@ -76,6 +83,7 @@ const CONTAINER_ENTRYPOINT_CANDIDATES = [
76
83
  ];
77
84
  // Annotate the CommonJS export names for ESM import in node:
78
85
  0 && (module.exports = {
86
+ BUILDER_RUNTIMES,
79
87
  CONTAINER_ENTRYPOINT_CANDIDATES,
80
88
  ENTRYPOINT_EXTENSIONS,
81
89
  ROUTE_OWNING_BUILDERS,
@@ -1,5 +1,6 @@
1
1
  import type { ServiceRuntime } from '@vercel/build-utils';
2
2
  import type { Framework } from '@vercel/frameworks';
3
+ export declare const frameworksBySlug: Map<string, Framework>;
3
4
  /**
4
5
  * Framework list filtered to entries eligible for auto-detection.
5
6
  * Includes non-experimental frameworks and runtime frameworks (Python, Node, etc.)
@@ -15,6 +16,12 @@ export declare const DETECTION_FRAMEWORKS: Framework[];
15
16
  * - `express` → `node`
16
17
  */
17
18
  export declare function inferRuntimeFromFramework(framework: string | null | undefined): ServiceRuntime | undefined;
19
+ /**
20
+ * Infer the runtime used by a framework's builder.
21
+ *
22
+ * A builder may not necessarily produce a function with a runtime, e.g. @vercel/static-build.
23
+ */
24
+ export declare function inferBuilderRuntimeFromFramework(framework: string | null | undefined): ServiceRuntime | undefined;
18
25
  /**
19
26
  * Returns true if the framework is a client-only frontend (no server runtime).
20
27
  */
@@ -20,6 +20,8 @@ var framework_exports = {};
20
20
  __export(framework_exports, {
21
21
  DETECTION_FRAMEWORKS: () => DETECTION_FRAMEWORKS,
22
22
  filterFrameworksByRuntime: () => filterFrameworksByRuntime,
23
+ frameworksBySlug: () => frameworksBySlug,
24
+ inferBuilderRuntimeFromFramework: () => inferBuilderRuntimeFromFramework,
23
25
  inferRuntimeFromFramework: () => inferRuntimeFromFramework,
24
26
  isBFFFramework: () => isBFFFramework,
25
27
  isFrontendFramework: () => isFrontendFramework
@@ -28,6 +30,9 @@ module.exports = __toCommonJS(framework_exports);
28
30
  var import_build_utils = require("@vercel/build-utils");
29
31
  var import_frameworks = require("@vercel/frameworks");
30
32
  var import_constants = require("./constants");
33
+ const frameworksBySlug = new Map(
34
+ import_frameworks.frameworkList.flatMap((f) => typeof f.slug === "string" ? [[f.slug, f]] : [])
35
+ );
31
36
  const DETECTION_FRAMEWORKS = import_frameworks.frameworkList.filter(
32
37
  (framework) => !framework.experimental || framework.runtimeFramework
33
38
  );
@@ -42,6 +47,25 @@ function inferRuntimeFromFramework(framework) {
42
47
  return "node";
43
48
  return void 0;
44
49
  }
50
+ const STATIC_BUILDER_RUNTIMES = {
51
+ hugo: "go",
52
+ jekyll: "ruby",
53
+ middleman: "ruby",
54
+ zola: "rust"
55
+ };
56
+ function inferBuilderRuntimeFromFramework(framework) {
57
+ if (!framework || framework === "container" || framework === "services")
58
+ return void 0;
59
+ const f = frameworksBySlug.get(framework);
60
+ const declaredBuilder = f?.useRuntime?.use;
61
+ if (declaredBuilder)
62
+ return import_constants.BUILDER_RUNTIMES[declaredBuilder];
63
+ const detectorItems = [
64
+ ...f?.detectors?.every ?? [],
65
+ ...f?.detectors?.some ?? []
66
+ ];
67
+ return STATIC_BUILDER_RUNTIMES[framework] ?? (detectorItems.some((d) => d.matchPackage !== void 0) ? "node" : void 0);
68
+ }
45
69
  function isFrontendFramework(framework) {
46
70
  return !!framework && !inferRuntimeFromFramework(framework);
47
71
  }
@@ -64,6 +88,8 @@ function filterFrameworksByRuntime(frameworks, runtime) {
64
88
  0 && (module.exports = {
65
89
  DETECTION_FRAMEWORKS,
66
90
  filterFrameworksByRuntime,
91
+ frameworksBySlug,
92
+ inferBuilderRuntimeFromFramework,
67
93
  inferRuntimeFromFramework,
68
94
  isBFFFramework,
69
95
  isFrontendFramework
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/fs-detectors",
3
- "version": "7.3.0",
3
+ "version": "7.4.0",
4
4
  "description": "Vercel filesystem detectors",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -20,11 +20,11 @@
20
20
  "minimatch": "3.1.2",
21
21
  "semver": "6.3.1",
22
22
  "smol-toml": "1.5.2",
23
- "@vercel/frameworks": "3.34.0",
24
23
  "@vercel/error-utils": "2.2.1",
24
+ "@vercel/build-utils": "14.10.1",
25
25
  "@vercel/python-analysis": "0.14.0",
26
26
  "@vercel/routing-utils": "6.6.0",
27
- "@vercel/build-utils": "14.10.1"
27
+ "@vercel/frameworks": "3.34.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/glob": "7.2.0",