@vercel/fs-detectors 6.15.10 → 7.0.1

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.
@@ -1,134 +0,0 @@
1
- import type { Rewrite, Route } from '@vercel/routing-utils';
2
- import type { DetectEntrypointFn, EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceV2Config, ExperimentalServiceGroups, ExperimentalServices, ExperimentalServicesV2, ExperimentalServiceV2Binding, ServiceBinding, ServiceConfig, Services, ExperimentalService, ExperimentalServiceV2, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder } from '@vercel/build-utils';
3
- import type { DetectorFilesystem } from '../detectors/filesystem';
4
- export type { DetectEntrypointFn, EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceGroups, ExperimentalServices, ExperimentalServiceV2Config, ExperimentalServicesV2, ExperimentalServiceV2Binding, ServiceBinding, ServiceConfig, Services, ExperimentalService, ExperimentalServiceV2, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder, };
5
- /**
6
- * @deprecated Use `Service` instead
7
- */
8
- export type ResolvedService = Service;
9
- export interface DetectServicesOptions {
10
- fs: DetectorFilesystem;
11
- configuredServices?: ConfiguredServices;
12
- configuredServicesType?: ConfiguredServicesType;
13
- /**
14
- * Working directory path (relative to fs root).
15
- * If provided, vercel.json is read from this path.
16
- */
17
- workPath?: string;
18
- /**
19
- * Optional callback that, given a candidate service directory and its
20
- * detected framework, returns a normalized entrypoint (file path or
21
- * `module:attr` reference). Used to suggested service configs.
22
- */
23
- detectEntrypoint?: DetectEntrypointFn;
24
- }
25
- export interface ServicesRoutes {
26
- /** Host-based rewrite routes for subdomain-mounted web services */
27
- hostRewrites: Route[];
28
- /** Rewrite routes for non-root web services (prefix-based) */
29
- rewrites: Route[];
30
- /** Default routes (catch-all for root web service) */
31
- defaults: Route[];
32
- /** SPA fallback routes for static web services */
33
- fallbacks: Route[];
34
- /**
35
- * Internal routes for schedule-triggered job services.
36
- * These route `/_svc/{serviceName}/crons/{entry}/{handler}` to the scheduled job function.
37
- */
38
- crons: Route[];
39
- /**
40
- * Internal routes for worker services.
41
- * These route `/_svc/{serviceName}/workers/{entry}/{handler}` to the worker function.
42
- */
43
- workers: Route[];
44
- }
45
- export type ConfiguredServicesType = 'experimentalServices' | 'services' | 'experimentalServicesV2';
46
- export type ConfiguredServices = ExperimentalServices | Services;
47
- /**
48
- * A single service entry inferred from project structure.
49
- *
50
- * This is an intermediate format produced by auto-detection — it carries
51
- * the detection results (including `mountPath`, the inferred route mount
52
- * point) before they are converted into a concrete config format (V1 or V2).
53
- */
54
- export interface InferredServiceConfig {
55
- /** Service root directory relative to the project root. */
56
- root: string;
57
- /** Framework slug, if detected. */
58
- framework?: string;
59
- /** Service entrypoint (file path or `module:attr` reference). */
60
- entrypoint?: string;
61
- /** Runtime identifier (e.g. "python", "node"). */
62
- runtime?: string;
63
- /** Service type (e.g. "web", "cron", "worker"). */
64
- type?: ServiceType;
65
- /** Build command override. */
66
- buildCommand?: string;
67
- /** Pre-deploy command override. */
68
- preDeployCommand?: string;
69
- /**
70
- * Inferred route mount path for this service.
71
- * For example, `"/"` for the root frontend, `"/_/backend"` for a backend.
72
- */
73
- mountPath?: string;
74
- }
75
- export type InferredServicesConfig = Record<string, InferredServiceConfig>;
76
- export interface ResolvedServicesResult {
77
- services: Service[];
78
- source: DetectServicesSource;
79
- useImplicitEnvInjection: boolean;
80
- routes: ServicesRoutes;
81
- /** Top-level service-targeted rewrites (V2). */
82
- rewrites: Rewrite[];
83
- /** V2 services config for the build output, so the platform activates V2 routing. */
84
- experimentalServicesV2?: Services;
85
- errors: ServiceDetectionError[];
86
- warnings: ServiceDetectionWarning[];
87
- }
88
- export interface InferredServicesResult {
89
- source: 'layout' | 'procfile' | 'railway' | 'render';
90
- config: InferredServicesConfig;
91
- services: Service[];
92
- warnings: ServiceDetectionWarning[];
93
- }
94
- export interface DetectServicesResult extends ResolvedServicesResult {
95
- /**
96
- * Source of service definitions:
97
- * - `configured`: loaded from explicit project configuration (`vercel.json#experimentalServices`, `vercel.json#services`, or the deprecated `vercel.json#experimentalServicesV2` alias)
98
- * - `auto-detected`: inferred from project structure
99
- */
100
- resolved: ResolvedServicesResult;
101
- inferred: InferredServicesResult | null;
102
- }
103
- export type DetectServicesSource = 'configured' | 'auto-detected';
104
- export interface ServiceDetectionWarning {
105
- code: string;
106
- message: string;
107
- serviceName?: string;
108
- }
109
- export interface ServiceDetectionError {
110
- code: string;
111
- message: string;
112
- serviceName?: string;
113
- }
114
- export declare const RUNTIME_BUILDERS: Record<ServiceRuntime, string>;
115
- export declare const RUNTIME_MANIFESTS: Partial<Record<ServiceRuntime, string[]>>;
116
- export declare const ENTRYPOINT_EXTENSIONS: Record<string, ServiceRuntime>;
117
- /**
118
- * Builders that produce static output (SPAs, static sites).
119
- * These don't have a "runtime" - they just build to static files.
120
- */
121
- export declare const STATIC_BUILDERS: Set<string>;
122
- /**
123
- * Builders that produce their own full route table with handle phases
124
- * (filesystem, miss, rewrite, hit, error).
125
- *
126
- * In services mode we generally avoid generating synthetic catch-all routes
127
- * for builders that provide their own routing. At service-detection time we
128
- * only have the builder "use" string (not the loaded module), so this is an
129
- * explicit allow-list for known route-table builders.
130
- *
131
- * NOTE: This is an explicit positive set because we can't check
132
- * `builder.version` at service detection time.
133
- */
134
- export declare const ROUTE_OWNING_BUILDERS: Set<string>;
@@ -1,77 +0,0 @@
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 types_exports = {};
20
- __export(types_exports, {
21
- ENTRYPOINT_EXTENSIONS: () => ENTRYPOINT_EXTENSIONS,
22
- ROUTE_OWNING_BUILDERS: () => ROUTE_OWNING_BUILDERS,
23
- RUNTIME_BUILDERS: () => RUNTIME_BUILDERS,
24
- RUNTIME_MANIFESTS: () => RUNTIME_MANIFESTS,
25
- STATIC_BUILDERS: () => STATIC_BUILDERS
26
- });
27
- module.exports = __toCommonJS(types_exports);
28
- const RUNTIME_BUILDERS = {
29
- node: "@vercel/backends",
30
- python: "@vercel/python",
31
- go: "@vercel/go",
32
- rust: "@vercel/rust",
33
- ruby: "@vercel/ruby",
34
- container: "@vercel/container"
35
- };
36
- const RUNTIME_MANIFESTS = {
37
- node: ["package.json"],
38
- python: [
39
- "pyproject.toml",
40
- "requirements.txt",
41
- "Pipfile",
42
- "pylock.yml",
43
- "uv.lock",
44
- "setup.py"
45
- ],
46
- go: ["go.mod"],
47
- ruby: ["Gemfile"],
48
- rust: ["Cargo.toml"]
49
- };
50
- const ENTRYPOINT_EXTENSIONS = {
51
- ".ts": "node",
52
- ".mts": "node",
53
- ".js": "node",
54
- ".mjs": "node",
55
- ".cjs": "node",
56
- ".py": "python",
57
- ".go": "go",
58
- ".rs": "rust",
59
- ".rb": "ruby",
60
- ".ru": "ruby"
61
- };
62
- const STATIC_BUILDERS = /* @__PURE__ */ new Set([
63
- "@vercel/static-build",
64
- "@vercel/static"
65
- ]);
66
- const ROUTE_OWNING_BUILDERS = /* @__PURE__ */ new Set([
67
- "@vercel/next",
68
- "@vercel/backends"
69
- ]);
70
- // Annotate the CommonJS export names for ESM import in node:
71
- 0 && (module.exports = {
72
- ENTRYPOINT_EXTENSIONS,
73
- ROUTE_OWNING_BUILDERS,
74
- RUNTIME_BUILDERS,
75
- RUNTIME_MANIFESTS,
76
- STATIC_BUILDERS
77
- });
@@ -1,95 +0,0 @@
1
- import { INTERNAL_SERVICE_PREFIX, getInternalServiceFunctionPath, getInternalServiceCronPathPrefix, getInternalServiceCronPath } from '@vercel/build-utils';
2
- import type { Framework } from '@vercel/frameworks';
3
- import type { DetectorFilesystem } from '../detectors/filesystem';
4
- import type { ServiceRuntime, ExperimentalServices, ExperimentalServicesV2, InferredServicesConfig, Services, ServiceDetectionError, ServiceDetectionWarning, ResolvedService } from './types';
5
- export declare const DETECTION_FRAMEWORKS: Framework[];
6
- export { INTERNAL_SERVICE_PREFIX, getInternalServiceFunctionPath, getInternalServiceCronPathPrefix, getInternalServiceCronPath, };
7
- /**
8
- * Removes a trailing slash from an already-`posixPath.normalize`d path.
9
- *
10
- * `posixPath.normalize` preserves trailing slashes (`"frontend/"` stays
11
- * `"frontend/"`), which double-prefixes builder paths when the value is later
12
- * used as both `builder.config.workspace` and a `posixPath.join` prefix. Strip
13
- * it so `"frontend/"` and `"frontend"` resolve identically. An empty result or
14
- * a lone `"/"` collapses to `"."` (matching `normalizeServiceEntrypoint`).
15
- */
16
- export declare function stripTrailingSlash(p: string): string;
17
- export declare function hasFile(fs: DetectorFilesystem, filePath: string): Promise<boolean>;
18
- /**
19
- * Reserved internal namespace used by the dev queue proxy.
20
- */
21
- export declare const INTERNAL_QUEUES_PREFIX = "/_svc/_queues";
22
- export declare function getInternalServiceWorkerPathPrefix(serviceName: string): string;
23
- export declare function getInternalServiceWorkerPath(serviceName: string, entrypoint: string, handler?: string): string;
24
- export declare function getBuilderForRuntime(runtime: ServiceRuntime): string;
25
- export declare function isStaticBuild(service: ResolvedService): boolean;
26
- /**
27
- * Determines if a service uses a "route-owning" builder.
28
- *
29
- * Route-owning builders (e.g., `@vercel/next`, `@vercel/backends`) produce
30
- * their own full route table with handle phases (filesystem, miss, rewrite,
31
- * hit, error). The services system should NOT generate synthetic catch-all
32
- * rewrites for them — instead, we rely on the builder's own `routes[]`.
33
- */
34
- export declare function isRouteOwningBuilder(service: ResolvedService): boolean;
35
- /**
36
- * Infer runtime from a framework slug.
37
- *
38
- * Examples:
39
- * - `python` -> `python`
40
- * - `fastapi` -> `python`
41
- * - `express` -> `node`
42
- */
43
- export declare function inferRuntimeFromFramework(framework: string | null | undefined): ServiceRuntime | undefined;
44
- export declare function isFrontendFramework(framework: string | null | undefined): boolean;
45
- export declare function isBFFFramework(framework: string | null | undefined): boolean;
46
- export declare function filterFrameworksByRuntime<T extends {
47
- slug?: string | null;
48
- }>(frameworks: readonly T[], runtime?: ServiceRuntime): T[];
49
- /**
50
- * Infer runtime from available service configuration.
51
- *
52
- * Priority (highest to lowest):
53
- * 1. Explicit runtime (user specified in config)
54
- * 2. Runtime framework slug (ruby → ruby, go → go)
55
- * 3. Framework detection (fastapi → python, express → node)
56
- * 4. Builder detection (@vercel/python → python)
57
- * 5. Entrypoint extension (.py → python, .ts → node)
58
- *
59
- * @returns The inferred runtime, or undefined if none can be determined.
60
- */
61
- export declare function inferServiceRuntime(config: {
62
- runtime?: string;
63
- framework?: string;
64
- builder?: string;
65
- entrypoint?: string;
66
- }): ServiceRuntime | undefined;
67
- export interface ReadVercelConfigResult {
68
- config: {
69
- experimentalServices?: ExperimentalServices;
70
- services?: Services;
71
- experimentalServicesV2?: ExperimentalServicesV2;
72
- } | null;
73
- error: ServiceDetectionError | null;
74
- }
75
- /**
76
- * Read and parse vercel.json or vercel.toml from filesystem.
77
- * Returns the parsed config or an error if the file exists but is invalid.
78
- */
79
- export declare function readVercelConfig(fs: DetectorFilesystem): Promise<ReadVercelConfigResult>;
80
- /**
81
- * Assign mount paths to inferred services.
82
- *
83
- * A frontend service gets `/`, backend services get `/api/...`:
84
- * - If the frontend is a BFF (e.g. Next.js, has its own API routes):
85
- * backends get `/api/{name}/(.*)` to avoid shadowing the frontend's API routes.
86
- * - If the frontend is client-only (e.g. Vite):
87
- * backends get `/api/(.*)`.
88
- *
89
- * A single non-frontend service gets `/`.
90
- * If no frontend service found, multiple services get `/api/{name}`.
91
- *
92
- * Priority for `/`: single service or frontend > name "frontend" or "web" > alphabetical.
93
- */
94
- export declare function assignMountPaths(services: InferredServicesConfig): ServiceDetectionWarning[];
95
- export declare function combineBuildCommand(buildCommand: string | undefined, preDeployCommand: string | string[] | undefined): string | undefined;
@@ -1,265 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var utils_exports = {};
30
- __export(utils_exports, {
31
- DETECTION_FRAMEWORKS: () => DETECTION_FRAMEWORKS,
32
- INTERNAL_QUEUES_PREFIX: () => INTERNAL_QUEUES_PREFIX,
33
- INTERNAL_SERVICE_PREFIX: () => import_build_utils.INTERNAL_SERVICE_PREFIX,
34
- assignMountPaths: () => assignMountPaths,
35
- combineBuildCommand: () => combineBuildCommand,
36
- filterFrameworksByRuntime: () => filterFrameworksByRuntime,
37
- getBuilderForRuntime: () => getBuilderForRuntime,
38
- getInternalServiceCronPath: () => import_build_utils.getInternalServiceCronPath,
39
- getInternalServiceCronPathPrefix: () => import_build_utils.getInternalServiceCronPathPrefix,
40
- getInternalServiceFunctionPath: () => import_build_utils.getInternalServiceFunctionPath,
41
- getInternalServiceWorkerPath: () => getInternalServiceWorkerPath,
42
- getInternalServiceWorkerPathPrefix: () => getInternalServiceWorkerPathPrefix,
43
- hasFile: () => hasFile,
44
- inferRuntimeFromFramework: () => inferRuntimeFromFramework,
45
- inferServiceRuntime: () => inferServiceRuntime,
46
- isBFFFramework: () => isBFFFramework,
47
- isFrontendFramework: () => isFrontendFramework,
48
- isRouteOwningBuilder: () => isRouteOwningBuilder,
49
- isStaticBuild: () => isStaticBuild,
50
- readVercelConfig: () => readVercelConfig,
51
- stripTrailingSlash: () => stripTrailingSlash
52
- });
53
- module.exports = __toCommonJS(utils_exports);
54
- var import_framework_helpers = require("@vercel/build-utils/dist/framework-helpers");
55
- var import_build_utils = require("@vercel/build-utils");
56
- var import_frameworks = require("@vercel/frameworks");
57
- var import_types = require("./types");
58
- const DETECTION_FRAMEWORKS = import_frameworks.frameworkList.filter(
59
- (framework) => !framework.experimental || framework.runtimeFramework
60
- );
61
- function stripTrailingSlash(p) {
62
- const stripped = p.replace(/\/+$/, "");
63
- return stripped === "" ? "." : stripped;
64
- }
65
- async function hasFile(fs, filePath) {
66
- try {
67
- return await fs.isFile(filePath);
68
- } catch {
69
- return false;
70
- }
71
- }
72
- const INTERNAL_QUEUES_PREFIX = "/_svc/_queues";
73
- function normalizeInternalServiceEntrypoint(entrypoint) {
74
- const normalized = entrypoint.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\.[^/.]+$/, "");
75
- return normalized || "index";
76
- }
77
- function getInternalServiceWorkerPathPrefix(serviceName) {
78
- return `${import_build_utils.INTERNAL_SERVICE_PREFIX}/${serviceName}/workers`;
79
- }
80
- function getInternalServiceWorkerPath(serviceName, entrypoint, handler = "worker") {
81
- const normalizedEntrypoint = normalizeInternalServiceEntrypoint(entrypoint);
82
- return `${getInternalServiceWorkerPathPrefix(serviceName)}/${normalizedEntrypoint}/${handler}`;
83
- }
84
- function getBuilderForRuntime(runtime) {
85
- const builder = import_types.RUNTIME_BUILDERS[runtime];
86
- if (!builder) {
87
- throw new Error(`Unknown runtime: ${runtime}`);
88
- }
89
- return builder;
90
- }
91
- function isStaticBuild(service) {
92
- return import_types.STATIC_BUILDERS.has(service.builder.use);
93
- }
94
- function isRouteOwningBuilder(service) {
95
- return import_types.ROUTE_OWNING_BUILDERS.has(service.builder.use);
96
- }
97
- function inferRuntimeFromFramework(framework) {
98
- if (!framework) {
99
- return void 0;
100
- }
101
- if (framework in import_types.RUNTIME_BUILDERS) {
102
- return framework;
103
- }
104
- if ((0, import_framework_helpers.isPythonFramework)(framework)) {
105
- return "python";
106
- }
107
- if ((0, import_framework_helpers.isBackendFramework)(framework)) {
108
- return "node";
109
- }
110
- return void 0;
111
- }
112
- function isFrontendFramework(framework) {
113
- if (!framework) {
114
- return false;
115
- }
116
- return !inferRuntimeFromFramework(framework);
117
- }
118
- const BFF_FRAMEWORKS = /* @__PURE__ */ new Set([
119
- "nextjs",
120
- "nuxtjs",
121
- "sveltekit",
122
- "remix",
123
- "solidstart"
124
- ]);
125
- function isBFFFramework(framework) {
126
- return !!framework && BFF_FRAMEWORKS.has(framework);
127
- }
128
- function filterFrameworksByRuntime(frameworks, runtime) {
129
- if (!runtime) {
130
- return [...frameworks];
131
- }
132
- return frameworks.filter(
133
- (framework) => inferRuntimeFromFramework(framework.slug) === runtime
134
- );
135
- }
136
- function inferServiceRuntime(config) {
137
- if (config.runtime && config.runtime in import_types.RUNTIME_BUILDERS) {
138
- return config.runtime;
139
- }
140
- const frameworkRuntime = inferRuntimeFromFramework(config.framework);
141
- if (frameworkRuntime) {
142
- return frameworkRuntime;
143
- }
144
- if (config.builder) {
145
- for (const [runtime, builderName] of Object.entries(import_types.RUNTIME_BUILDERS)) {
146
- if (config.builder === builderName) {
147
- return runtime;
148
- }
149
- }
150
- }
151
- if (config.entrypoint) {
152
- if (config.entrypoint === "pyproject.toml" || config.entrypoint.endsWith("/pyproject.toml")) {
153
- return "python";
154
- }
155
- for (const [ext, runtime] of Object.entries(import_types.ENTRYPOINT_EXTENSIONS)) {
156
- if (config.entrypoint.endsWith(ext)) {
157
- return runtime;
158
- }
159
- }
160
- }
161
- return void 0;
162
- }
163
- async function readVercelConfig(fs) {
164
- const hasVercelJson = await fs.hasPath("vercel.json");
165
- if (hasVercelJson) {
166
- try {
167
- const content = await fs.readFile("vercel.json");
168
- const config = JSON.parse(content.toString());
169
- return { config, error: null };
170
- } catch {
171
- return {
172
- config: null,
173
- error: {
174
- code: "INVALID_VERCEL_JSON",
175
- message: "Failed to parse vercel.json. Ensure it contains valid JSON."
176
- }
177
- };
178
- }
179
- }
180
- const hasVercelToml = await fs.hasPath("vercel.toml");
181
- if (hasVercelToml) {
182
- try {
183
- const { parse: tomlParse } = await import("smol-toml");
184
- const content = await fs.readFile("vercel.toml");
185
- const config = tomlParse(content.toString());
186
- return { config, error: null };
187
- } catch {
188
- return {
189
- config: null,
190
- error: {
191
- code: "INVALID_VERCEL_TOML",
192
- message: "Failed to parse vercel.toml. Ensure it contains valid TOML."
193
- }
194
- };
195
- }
196
- }
197
- return { config: null, error: null };
198
- }
199
- function assignMountPaths(services) {
200
- const warnings = [];
201
- const names = Object.keys(services);
202
- if (names.length === 1) {
203
- services[names[0]].mountPath = "/";
204
- return warnings;
205
- }
206
- const frontendNames = names.filter(
207
- (name) => isFrontendFramework(services[name].framework)
208
- );
209
- let rootName = null;
210
- if (frontendNames.length === 1) {
211
- rootName = frontendNames[0];
212
- } else if (frontendNames.length > 1) {
213
- rootName = frontendNames.find((n) => n === "frontend" || n === "web") ?? frontendNames.sort()[0];
214
- warnings.push({
215
- code: "MULTIPLE_FRONTENDS",
216
- message: `Multiple frontend services detected (${frontendNames.join(", ")}). "${rootName}" was assigned mount path "/". Adjust manually if a different service should be the root.`
217
- });
218
- }
219
- const rootFramework = rootName ? services[rootName].framework : void 0;
220
- const isBFF = rootFramework ? isBFFFramework(rootFramework) : false;
221
- const nonRootNames = names.filter((n) => n !== rootName);
222
- const needsNamespace = isBFF || nonRootNames.length > 1;
223
- for (const name of names) {
224
- if (name === rootName) {
225
- services[name].mountPath = "/";
226
- } else {
227
- services[name].mountPath = needsNamespace ? `/api/${name}` : "/api";
228
- }
229
- }
230
- return warnings;
231
- }
232
- function combineBuildCommand(buildCommand, preDeployCommand) {
233
- const preDeploy = Array.isArray(preDeployCommand) ? preDeployCommand.join(" && ") : preDeployCommand;
234
- if (preDeploy && buildCommand) {
235
- return `${buildCommand} && ${preDeploy}`;
236
- } else if (preDeploy) {
237
- return preDeploy;
238
- } else {
239
- return buildCommand;
240
- }
241
- }
242
- // Annotate the CommonJS export names for ESM import in node:
243
- 0 && (module.exports = {
244
- DETECTION_FRAMEWORKS,
245
- INTERNAL_QUEUES_PREFIX,
246
- INTERNAL_SERVICE_PREFIX,
247
- assignMountPaths,
248
- combineBuildCommand,
249
- filterFrameworksByRuntime,
250
- getBuilderForRuntime,
251
- getInternalServiceCronPath,
252
- getInternalServiceCronPathPrefix,
253
- getInternalServiceFunctionPath,
254
- getInternalServiceWorkerPath,
255
- getInternalServiceWorkerPathPrefix,
256
- hasFile,
257
- inferRuntimeFromFramework,
258
- inferServiceRuntime,
259
- isBFFFramework,
260
- isFrontendFramework,
261
- isRouteOwningBuilder,
262
- isStaticBuild,
263
- readVercelConfig,
264
- stripTrailingSlash
265
- });