@vercel/fs-detectors 7.2.5 → 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.
@@ -0,0 +1,23 @@
1
+ import type { ServiceRuntime } from '@vercel/build-utils';
2
+ /**
3
+ * Runtimes that can build container images with Cloud Native Buildpacks,
4
+ * with the files (any one of them, at the build root) that mark a project
5
+ * the buildpack can build. Keep this in sync with `@vercel/container`'s
6
+ * buildpack registry (`BUILDPACKS[].projectMarkers`).
7
+ *
8
+ * Routing is per runtime on purpose: the platform decides which buildpack to
9
+ * run from the language markers, and the buildpack classifies the application
10
+ * (for example Rails versus a plain Rack app) from its resolved bundle. There
11
+ * are no framework-level presets for buildpack runtimes.
12
+ */
13
+ export declare const BUILDPACK_PROJECT_MARKERS: ReadonlyMap<ServiceRuntime, readonly string[]>;
14
+ export declare function isBuildpackRuntimeEnabled(runtime: string): boolean;
15
+ /** The runtime's buildpack, when one exists and its flag is on. */
16
+ export declare function toBuildpackRuntime(runtime: string | null | undefined): ServiceRuntime | undefined;
17
+ /**
18
+ * Whether the build root carries one of the buildpack's project markers.
19
+ * `hasFile` is checked against exact root-relative names, never ancestors or
20
+ * nested directories: the buildpack stages the root as-is, and the legacy
21
+ * runtime keeps building projects that lack the marker.
22
+ */
23
+ export declare function hasBuildpackProjectMarker(runtime: ServiceRuntime, hasFile: (name: string) => Promise<boolean> | boolean): Promise<boolean>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var buildpack_runtimes_exports = {};
20
+ __export(buildpack_runtimes_exports, {
21
+ BUILDPACK_PROJECT_MARKERS: () => BUILDPACK_PROJECT_MARKERS,
22
+ hasBuildpackProjectMarker: () => hasBuildpackProjectMarker,
23
+ isBuildpackRuntimeEnabled: () => isBuildpackRuntimeEnabled,
24
+ toBuildpackRuntime: () => toBuildpackRuntime
25
+ });
26
+ module.exports = __toCommonJS(buildpack_runtimes_exports);
27
+ const BUILDPACK_PROJECT_MARKERS = /* @__PURE__ */ new Map([["ruby", ["Gemfile"]]]);
28
+ function isBuildpackRuntimeEnabled(runtime) {
29
+ return process.env[`VERCEL_EXPERIMENTAL_BUILDPACK_${runtime.toUpperCase()}`] === "1";
30
+ }
31
+ function toBuildpackRuntime(runtime) {
32
+ if (!runtime || !BUILDPACK_PROJECT_MARKERS.has(runtime) || !isBuildpackRuntimeEnabled(runtime)) {
33
+ return void 0;
34
+ }
35
+ return runtime;
36
+ }
37
+ async function hasBuildpackProjectMarker(runtime, hasFile) {
38
+ for (const marker of BUILDPACK_PROJECT_MARKERS.get(runtime) ?? []) {
39
+ if (await hasFile(marker)) {
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ BUILDPACK_PROJECT_MARKERS,
48
+ hasBuildpackProjectMarker,
49
+ isBuildpackRuntimeEnabled,
50
+ toBuildpackRuntime
51
+ });
@@ -46,9 +46,12 @@ 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");
54
+ var import_buildpack_runtimes = require("./buildpack-runtimes");
52
55
  const REGEX_MIDDLEWARE_FILES = "middleware.[jt]s";
53
56
  const VERCEL_PLATFORM_FILES = [
54
57
  "api/**",
@@ -74,9 +77,6 @@ function getStaticFilesPattern(additionalExclusions = []) {
74
77
  ].join(",")}}`;
75
78
  }
76
79
  const REGEX_NON_VERCEL_PLATFORM_FILES = getStaticFilesPattern();
77
- const slugToFramework = new Map(
78
- import_frameworks.frameworkList.map((f) => [f.slug, f])
79
- );
80
80
  const builderToFrameworks = (() => {
81
81
  const map = /* @__PURE__ */ new Map();
82
82
  for (const f of import_frameworks.frameworkList) {
@@ -161,7 +161,7 @@ async function detectBuilders(files, pkg, options = {}) {
161
161
  };
162
162
  const absolutePathCache = /* @__PURE__ */ new Map();
163
163
  const { buildCommand, outputDirectory } = projectSettings;
164
- const frameworkConfig = slugToFramework.get(framework || "");
164
+ const frameworkConfig = import_framework.frameworksBySlug.get(framework || "");
165
165
  const rustStaticOutput = isRustStaticOutput(framework, projectSettings);
166
166
  const ignoreRuntimes = new Set(
167
167
  rustStaticOutput ? void 0 : frameworkConfig?.ignoreRuntimes
@@ -532,6 +532,14 @@ function validateProxy(options, files, framework) {
532
532
  message: `The \`proxy\` property cannot be used with ${framework === "nextjs" ? "Next.js" : "Astro"} because the framework builds its own routing middleware.`
533
533
  };
534
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
+ }
535
543
  return null;
536
544
  }
537
545
  function hasBuildScript(pkg) {
@@ -586,8 +594,19 @@ function detectFrontBuilder(pkg, files, usedFunctions, fallbackEntrypoint, optio
586
594
  }
587
595
  });
588
596
  }
589
- const f = slugToFramework.get(framework || "");
597
+ const f = import_framework.frameworksBySlug.get(framework || "");
590
598
  if (f && f.useRuntime && !isRustStaticOutput(framework, projectSettings)) {
599
+ const buildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(framework);
600
+ if (buildpackRuntime && (import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? []).some(
601
+ (marker) => files.includes(marker)
602
+ )) {
603
+ config.buildpack = buildpackRuntime;
604
+ return {
605
+ src: "<detect>",
606
+ use: `@vercel/container${withTag}`,
607
+ config
608
+ };
609
+ }
591
610
  const { src, use } = f.useRuntime;
592
611
  const shouldUseUnifiedBackend = (0, import_build_utils.isExperimentalBackendsEnabled)() && import_build_utils.BACKEND_BUILDERS.includes(use);
593
612
  const finalUse = shouldUseUnifiedBackend ? import_build_utils.UNIFIED_BACKEND_BUILDER : use;
@@ -894,7 +913,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
894
913
  const framework = frontendBuilder?.config?.framework || "";
895
914
  const isGatsby = framework === "gatsby";
896
915
  const isNextjs = framework === "nextjs" || (0, import_is_official_runtime.isOfficialRuntime)("next", frontendBuilder?.use);
897
- const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
916
+ const ignoreRuntimes = import_framework.frameworksBySlug.get(framework)?.ignoreRuntimes;
898
917
  if (apiRoutes && apiRoutes.length > 0) {
899
918
  if (options.featHandleMiss) {
900
919
  const extSet = detectApiExtensions(apiBuilders);
@@ -27,6 +27,7 @@ __export(detect_framework_exports, {
27
27
  module.exports = __toCommonJS(detect_framework_exports);
28
28
  var import_build_utils = require("@vercel/build-utils");
29
29
  var import_child_process = require("child_process");
30
+ var import_buildpack_runtimes = require("./buildpack-runtimes");
30
31
  function shouldIncludeExperimentalFrameworks(useExperimentalFrameworks) {
31
32
  if (typeof useExperimentalFrameworks === "boolean") {
32
33
  return useExperimentalFrameworks;
@@ -41,7 +42,10 @@ function filterFrameworkList(frameworkList, useExperimentalFrameworks) {
41
42
  }
42
43
  return frameworkList.filter((f) => {
43
44
  const experimental = f.experimental;
44
- return !experimental;
45
+ if (!experimental) {
46
+ return true;
47
+ }
48
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(f.slug) !== void 0;
45
49
  });
46
50
  }
47
51
  async function matches(fs, framework) {
@@ -25,6 +25,7 @@ __export(detect_services_exports, {
25
25
  module.exports = __toCommonJS(detect_services_exports);
26
26
  var import_build_utils = require("@vercel/build-utils");
27
27
  var import_routing_utils = require("@vercel/routing-utils");
28
+ var import_buildpack_runtimes = require("../buildpack-runtimes");
28
29
  var import_framework = require("./runtimes/framework");
29
30
  var import_utils = require("./utils");
30
31
  var import_resolve = require("./resolve");
@@ -60,6 +61,11 @@ function withResolvedResult(resolved, inferred = null) {
60
61
  inferred
61
62
  };
62
63
  }
64
+ function isBuildpackInferredService(svc) {
65
+ return (0, import_buildpack_runtimes.toBuildpackRuntime)(
66
+ svc.runtime ?? (0, import_framework.inferRuntimeFromFramework)(svc.framework)
67
+ ) !== void 0;
68
+ }
63
69
  function toInferredLayoutConfig(services) {
64
70
  const inferredConfig = {};
65
71
  for (const [name, service] of Object.entries(services)) {
@@ -69,7 +75,7 @@ function toInferredLayoutConfig(services) {
69
75
  if (service.type) {
70
76
  serviceConfig.type = service.type;
71
77
  }
72
- if (typeof service.entrypoint === "string") {
78
+ if (typeof service.entrypoint === "string" && !isBuildpackInferredService(service)) {
73
79
  serviceConfig.entrypoint = service.entrypoint;
74
80
  }
75
81
  if (typeof service.mountPath === "string") {
@@ -212,7 +218,7 @@ async function tryResolveInferred(detectResult, source, scopedFs) {
212
218
  v2Services[name] = {
213
219
  root: svc.root,
214
220
  ...svc.framework ? { framework: svc.framework } : {},
215
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {}
221
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {}
216
222
  };
217
223
  }
218
224
  const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(v2Services, scopedFs);
@@ -245,7 +251,7 @@ async function tryResolveInferred(detectResult, source, scopedFs) {
245
251
  v1Services[name] = {
246
252
  root: svc.root === "." ? void 0 : svc.root,
247
253
  ...svc.framework ? { framework: svc.framework } : {},
248
- ...svc.entrypoint ? { entrypoint: svc.entrypoint } : {},
254
+ ...svc.entrypoint && !isBuildpackInferredService(svc) ? { entrypoint: svc.entrypoint } : {},
249
255
  ...svc.type ? { type: svc.type } : {},
250
256
  ...svc.buildCommand ? { buildCommand: svc.buildCommand } : {},
251
257
  ...svc.preDeployCommand ? { preDeployCommand: svc.preDeployCommand } : {},
@@ -30,7 +30,9 @@ var import_constants = require("./runtimes/constants");
30
30
  var import_framework = require("./runtimes/framework");
31
31
  var import_runtime = require("./runtimes/runtime");
32
32
  var import_entrypoint = require("./runtimes/entrypoint");
33
+ var import_buildpack_runtimes = require("../buildpack-runtimes");
33
34
  var import_resolve = require("./resolve");
35
+ var import_utils = require("./utils");
34
36
  const frameworksBySlug = new Map(import_frameworks.frameworkList.map((f) => [f.slug, f]));
35
37
  const MAX_SERVICE_NAME_LENGTH = 64;
36
38
  const SERVICE_NAME_REGEX = /^[a-z]([a-z_-]*[a-z])?$/;
@@ -234,7 +236,23 @@ async function resolveConfiguredServiceV2(name, config, fs) {
234
236
  entrypoint: entrypointFile
235
237
  });
236
238
  }
237
- if (entrypointIsDirectory && !framework) {
239
+ const flaggedBuildpackRuntime = (0, import_buildpack_runtimes.toBuildpackRuntime)(
240
+ inferredRuntime
241
+ );
242
+ if (flaggedBuildpackRuntime && config.command !== void 0) {
243
+ return {
244
+ error: {
245
+ code: "INVALID_COMMAND",
246
+ message: `Service "${name}" can only specify "command" when using runtime "container".`,
247
+ serviceName: name
248
+ }
249
+ };
250
+ }
251
+ const buildpackRuntime = flaggedBuildpackRuntime && !entrypointFile && !(0, import_framework.isFrontendFramework)(framework) && await (0, import_buildpack_runtimes.hasBuildpackProjectMarker)(
252
+ flaggedBuildpackRuntime,
253
+ (marker) => (0, import_utils.hasFile)(serviceFs, marker)
254
+ ) ? flaggedBuildpackRuntime : void 0;
255
+ if (entrypointIsDirectory && !framework && !buildpackRuntime) {
238
256
  return {
239
257
  error: {
240
258
  code: "MISSING_SERVICE_FRAMEWORK",
@@ -244,7 +262,7 @@ async function resolveConfiguredServiceV2(name, config, fs) {
244
262
  };
245
263
  }
246
264
  const frameworkRuntime = (0, import_framework.inferRuntimeFromFramework)(framework);
247
- if (detectedFramework && frameworkRuntime && !entrypointFile) {
265
+ if (detectedFramework && frameworkRuntime && !entrypointFile && !buildpackRuntime) {
248
266
  return {
249
267
  error: {
250
268
  code: "MISSING_SERVICE_CONFIG",
@@ -256,7 +274,10 @@ async function resolveConfiguredServiceV2(name, config, fs) {
256
274
  const frameworkDefinition = framework ? frameworksBySlug.get(framework) : void 0;
257
275
  let builderUse;
258
276
  let builderSrc;
259
- if (framework) {
277
+ if (buildpackRuntime) {
278
+ builderUse = "@vercel/container";
279
+ builderSrc = "<detect>";
280
+ } else if (framework) {
260
281
  builderUse = (0, import_build_utils.isNodeBackendFramework)(framework) ? "@vercel/backends" : frameworkDefinition?.useRuntime?.use || "@vercel/static-build";
261
282
  builderSrc = entrypointFile || frameworkDefinition?.useRuntime?.src || "package.json";
262
283
  } else {
@@ -291,6 +312,9 @@ async function resolveConfiguredServiceV2(name, config, fs) {
291
312
  if (framework) {
292
313
  builderConfig.framework = framework;
293
314
  }
315
+ if (buildpackRuntime) {
316
+ builderConfig.buildpack = buildpackRuntime;
317
+ }
294
318
  if (config.outputDirectory) {
295
319
  builderConfig.outputDirectory = config.outputDirectory;
296
320
  }
@@ -31,6 +31,7 @@ module.exports = __toCommonJS(resolve_exports);
31
31
  var import_path = require("path");
32
32
  var import_build_utils = require("@vercel/build-utils");
33
33
  var import_constants = require("./runtimes/constants");
34
+ var import_buildpack_runtimes = require("../buildpack-runtimes");
34
35
  var import_framework = require("./runtimes/framework");
35
36
  var import_runtime = require("./runtimes/runtime");
36
37
  var import_entrypoint = require("./runtimes/entrypoint");
@@ -511,6 +512,15 @@ function validateServiceConfig(name, config, options = {}) {
511
512
  };
512
513
  }
513
514
  if (hasBuilderOrRuntime && !hasFramework && !hasEntrypoint) {
515
+ const buildpackRuntime = config.builder ? void 0 : (0, import_buildpack_runtimes.toBuildpackRuntime)(config.runtime);
516
+ if (buildpackRuntime) {
517
+ const markers = import_buildpack_runtimes.BUILDPACK_PROJECT_MARKERS.get(buildpackRuntime) ?? [];
518
+ return {
519
+ code: "BUILDPACK_REQUIRES_SERVICES",
520
+ 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.`,
521
+ serviceName: name
522
+ };
523
+ }
514
524
  return {
515
525
  code: "MISSING_ENTRYPOINT",
516
526
  message: `Service "${name}" must specify "entrypoint" when using "${config.builder ? "builder" : "runtime"}".`,
@@ -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.2.5",
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/build-utils": "14.10.1",
24
23
  "@vercel/error-utils": "2.2.1",
25
- "@vercel/frameworks": "3.34.0",
24
+ "@vercel/build-utils": "14.10.1",
26
25
  "@vercel/python-analysis": "0.14.0",
27
- "@vercel/routing-utils": "6.6.0"
26
+ "@vercel/routing-utils": "6.6.0",
27
+ "@vercel/frameworks": "3.34.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/glob": "7.2.0",