@vercel/fs-detectors 7.1.7 → 7.2.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.
- package/dist/index.d.ts +7 -0
- package/dist/index.js +39 -0
- package/dist/services/auto-detect.d.ts +46 -0
- package/dist/services/auto-detect.js +269 -0
- package/dist/services/detect-procfile.d.ts +22 -0
- package/dist/services/detect-procfile.js +250 -0
- package/dist/services/detect-railway.d.ts +22 -0
- package/dist/services/detect-railway.js +242 -0
- package/dist/services/detect-render.d.ts +14 -0
- package/dist/services/detect-render.js +231 -0
- package/dist/services/detect-services.d.ts +48 -0
- package/dist/services/detect-services.js +424 -0
- package/dist/services/resolve-v2.d.ts +11 -0
- package/dist/services/resolve-v2.js +383 -0
- package/dist/services/resolve.d.ts +65 -0
- package/dist/services/resolve.js +901 -0
- package/dist/services/runtimes/constants.d.ts +19 -0
- package/dist/services/runtimes/constants.js +85 -0
- package/dist/services/runtimes/entrypoint.d.ts +20 -0
- package/dist/services/runtimes/entrypoint.js +58 -0
- package/dist/services/runtimes/framework.d.ts +25 -0
- package/dist/services/runtimes/framework.js +70 -0
- package/dist/services/runtimes/runtime.d.ts +18 -0
- package/dist/services/runtimes/runtime.js +61 -0
- package/dist/services/types.d.ts +113 -0
- package/dist/services/types.js +16 -0
- package/dist/services/utils.d.ts +48 -0
- package/dist/services/utils.js +157 -0
- package/package.json +4 -3
|
@@ -0,0 +1,424 @@
|
|
|
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 detect_services_exports = {};
|
|
20
|
+
__export(detect_services_exports, {
|
|
21
|
+
detectServices: () => detectServices,
|
|
22
|
+
generateServiceRewrites: () => generateServiceRewrites,
|
|
23
|
+
generateServicesRoutes: () => generateServicesRoutes
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(detect_services_exports);
|
|
26
|
+
var import_build_utils = require("@vercel/build-utils");
|
|
27
|
+
var import_routing_utils = require("@vercel/routing-utils");
|
|
28
|
+
var import_framework = require("./runtimes/framework");
|
|
29
|
+
var import_utils = require("./utils");
|
|
30
|
+
var import_resolve = require("./resolve");
|
|
31
|
+
var import_resolve_v2 = require("./resolve-v2");
|
|
32
|
+
var import_auto_detect = require("./auto-detect");
|
|
33
|
+
var import_detect_railway = require("./detect-railway");
|
|
34
|
+
var import_detect_render = require("./detect-render");
|
|
35
|
+
var import_detect_procfile = require("./detect-procfile");
|
|
36
|
+
const PREVIEW_DOMAIN_MISSING = [
|
|
37
|
+
{ type: "host", value: { suf: ".vercel.app" } },
|
|
38
|
+
{ type: "host", value: { suf: ".vercel.dev" } }
|
|
39
|
+
];
|
|
40
|
+
function emptyRoutes() {
|
|
41
|
+
return {
|
|
42
|
+
hostRewrites: [],
|
|
43
|
+
rewrites: [],
|
|
44
|
+
defaults: [],
|
|
45
|
+
fallbacks: [],
|
|
46
|
+
crons: [],
|
|
47
|
+
workers: []
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function withResolvedResult(resolved, inferred = null) {
|
|
51
|
+
return {
|
|
52
|
+
services: resolved.services,
|
|
53
|
+
source: resolved.source,
|
|
54
|
+
useImplicitEnvInjection: resolved.useImplicitEnvInjection,
|
|
55
|
+
routes: resolved.routes,
|
|
56
|
+
rewrites: resolved.rewrites,
|
|
57
|
+
errors: resolved.errors,
|
|
58
|
+
warnings: resolved.warnings,
|
|
59
|
+
resolved,
|
|
60
|
+
inferred
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function toInferredLayoutConfig(services) {
|
|
64
|
+
const inferredConfig = {};
|
|
65
|
+
for (const [name, service] of Object.entries(services)) {
|
|
66
|
+
const serviceConfig = {
|
|
67
|
+
root: service.root
|
|
68
|
+
};
|
|
69
|
+
if (service.type) {
|
|
70
|
+
serviceConfig.type = service.type;
|
|
71
|
+
}
|
|
72
|
+
if (typeof service.entrypoint === "string") {
|
|
73
|
+
serviceConfig.entrypoint = service.entrypoint;
|
|
74
|
+
}
|
|
75
|
+
if (typeof service.mountPath === "string") {
|
|
76
|
+
serviceConfig.mountPath = service.mountPath;
|
|
77
|
+
}
|
|
78
|
+
if ((0, import_framework.isFrontendFramework)(service.framework)) {
|
|
79
|
+
serviceConfig.framework = service.framework;
|
|
80
|
+
}
|
|
81
|
+
if (typeof service.buildCommand === "string") {
|
|
82
|
+
serviceConfig.buildCommand = service.buildCommand;
|
|
83
|
+
}
|
|
84
|
+
if (typeof service.runtime === "string") {
|
|
85
|
+
serviceConfig.runtime = service.runtime;
|
|
86
|
+
}
|
|
87
|
+
inferredConfig[name] = serviceConfig;
|
|
88
|
+
}
|
|
89
|
+
return inferredConfig;
|
|
90
|
+
}
|
|
91
|
+
async function detectServices(options) {
|
|
92
|
+
const {
|
|
93
|
+
fs,
|
|
94
|
+
workPath,
|
|
95
|
+
detectEntrypoint,
|
|
96
|
+
configuredServices: providedConfiguredServices,
|
|
97
|
+
configuredServicesType: providedConfiguredServicesType
|
|
98
|
+
} = options;
|
|
99
|
+
const scopedFs = workPath ? fs.chdir(workPath) : fs;
|
|
100
|
+
const { config: vercelConfig, error: configError } = await (0, import_utils.readVercelConfig)(scopedFs);
|
|
101
|
+
if (configError) {
|
|
102
|
+
return withResolvedResult({
|
|
103
|
+
services: [],
|
|
104
|
+
source: "configured",
|
|
105
|
+
useImplicitEnvInjection: true,
|
|
106
|
+
routes: emptyRoutes(),
|
|
107
|
+
rewrites: [],
|
|
108
|
+
errors: [configError],
|
|
109
|
+
warnings: []
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (vercelConfig?.services != null && vercelConfig.experimentalServicesV2 != null) {
|
|
113
|
+
return withResolvedResult({
|
|
114
|
+
services: [],
|
|
115
|
+
source: "configured",
|
|
116
|
+
useImplicitEnvInjection: false,
|
|
117
|
+
routes: emptyRoutes(),
|
|
118
|
+
rewrites: [],
|
|
119
|
+
errors: [
|
|
120
|
+
{
|
|
121
|
+
code: "SERVICES_AND_EXPERIMENTAL_SERVICES_V2",
|
|
122
|
+
message: "The `services` property cannot be used in conjunction with its deprecated alias `experimentalServicesV2`. Please use only `services`."
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
warnings: []
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const hasProvidedConfiguredServices = providedConfiguredServices && Object.keys(providedConfiguredServices).length > 0;
|
|
129
|
+
const experimentalServicesV2 = hasProvidedConfiguredServices && (providedConfiguredServicesType === "services" || providedConfiguredServicesType === "experimentalServicesV2") ? providedConfiguredServices : hasProvidedConfiguredServices ? void 0 : vercelConfig?.services ?? vercelConfig?.experimentalServicesV2;
|
|
130
|
+
if (experimentalServicesV2 && Object.keys(experimentalServicesV2).length > 0) {
|
|
131
|
+
const result = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(
|
|
132
|
+
experimentalServicesV2,
|
|
133
|
+
scopedFs
|
|
134
|
+
);
|
|
135
|
+
return withResolvedResult({
|
|
136
|
+
services: result.services,
|
|
137
|
+
source: "configured",
|
|
138
|
+
// V2 uses explicit `bindings`, so no implicit `{NAME}_URL` injection.
|
|
139
|
+
useImplicitEnvInjection: false,
|
|
140
|
+
// V2 routes are explicitly carried per-service to output them separately.
|
|
141
|
+
routes: emptyRoutes(),
|
|
142
|
+
rewrites: [],
|
|
143
|
+
errors: result.errors,
|
|
144
|
+
warnings: []
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const experimentalServicesV1 = hasProvidedConfiguredServices ? providedConfiguredServices : vercelConfig?.experimentalServices;
|
|
148
|
+
const hasExperimentalServicesV1 = experimentalServicesV1 && Object.keys(experimentalServicesV1).length > 0;
|
|
149
|
+
if (hasExperimentalServicesV1) {
|
|
150
|
+
const result = await (0, import_resolve.resolveAllConfiguredServices)(
|
|
151
|
+
experimentalServicesV1,
|
|
152
|
+
scopedFs,
|
|
153
|
+
"configured"
|
|
154
|
+
);
|
|
155
|
+
const routes = generateServicesRoutes(result.services);
|
|
156
|
+
return withResolvedResult({
|
|
157
|
+
services: result.services,
|
|
158
|
+
source: "configured",
|
|
159
|
+
// experimentalServices uses the legacy `{NAME}_URL` injection.
|
|
160
|
+
useImplicitEnvInjection: true,
|
|
161
|
+
routes,
|
|
162
|
+
rewrites: [],
|
|
163
|
+
errors: result.errors,
|
|
164
|
+
warnings: []
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const detectors = [
|
|
168
|
+
{ detect: import_detect_railway.detectRailwayServices, source: "railway" },
|
|
169
|
+
{ detect: import_detect_render.detectRenderServices, source: "render" },
|
|
170
|
+
{ detect: import_detect_procfile.detectProcfileServices, source: "procfile" },
|
|
171
|
+
{ detect: import_auto_detect.autoDetectServices, source: "layout" }
|
|
172
|
+
];
|
|
173
|
+
for (const { detect, source } of detectors) {
|
|
174
|
+
const detectResult = await detect({ fs: scopedFs, detectEntrypoint });
|
|
175
|
+
const match = await tryResolveInferred(detectResult, source, scopedFs);
|
|
176
|
+
if (match)
|
|
177
|
+
return match;
|
|
178
|
+
}
|
|
179
|
+
return withResolvedResult({
|
|
180
|
+
services: [],
|
|
181
|
+
source: "auto-detected",
|
|
182
|
+
useImplicitEnvInjection: true,
|
|
183
|
+
routes: emptyRoutes(),
|
|
184
|
+
rewrites: [],
|
|
185
|
+
errors: [
|
|
186
|
+
{
|
|
187
|
+
code: "NO_SERVICES_CONFIGURED",
|
|
188
|
+
message: "No services configured. Add `services` to vercel.json."
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
warnings: []
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
async function tryResolveInferred(detectResult, source, scopedFs) {
|
|
195
|
+
if (detectResult.errors.length > 0) {
|
|
196
|
+
return withResolvedResult({
|
|
197
|
+
services: [],
|
|
198
|
+
source: "auto-detected",
|
|
199
|
+
useImplicitEnvInjection: source !== "layout",
|
|
200
|
+
routes: emptyRoutes(),
|
|
201
|
+
rewrites: [],
|
|
202
|
+
errors: detectResult.errors,
|
|
203
|
+
warnings: detectResult.warnings
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (!detectResult.services) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
if (source === "layout") {
|
|
210
|
+
const v2Services = {};
|
|
211
|
+
for (const [name, svc] of Object.entries(detectResult.services)) {
|
|
212
|
+
v2Services[name] = {
|
|
213
|
+
root: svc.root,
|
|
214
|
+
...svc.framework ? { framework: svc.framework } : {},
|
|
215
|
+
...svc.entrypoint ? { entrypoint: svc.entrypoint } : {}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const result2 = await (0, import_resolve_v2.resolveAllConfiguredServicesV2)(v2Services, scopedFs);
|
|
219
|
+
const rootServices = Object.values(detectResult.services).filter(
|
|
220
|
+
(svc) => svc.mountPath === "/" && typeof svc.framework === "string"
|
|
221
|
+
);
|
|
222
|
+
const shouldInfer2 = result2.errors.length === 0 && rootServices.length === 1 && result2.services.length > 1;
|
|
223
|
+
const inferred2 = shouldInfer2 ? {
|
|
224
|
+
source,
|
|
225
|
+
config: toInferredLayoutConfig(detectResult.services),
|
|
226
|
+
services: result2.services,
|
|
227
|
+
warnings: detectResult.warnings
|
|
228
|
+
} : null;
|
|
229
|
+
return withResolvedResult(
|
|
230
|
+
{
|
|
231
|
+
services: shouldInfer2 ? result2.services : [],
|
|
232
|
+
source: "auto-detected",
|
|
233
|
+
useImplicitEnvInjection: false,
|
|
234
|
+
routes: emptyRoutes(),
|
|
235
|
+
rewrites: shouldInfer2 ? generateServiceRewrites(detectResult.services) : [],
|
|
236
|
+
experimentalServicesV2: shouldInfer2 ? v2Services : void 0,
|
|
237
|
+
errors: result2.errors,
|
|
238
|
+
warnings: detectResult.warnings
|
|
239
|
+
},
|
|
240
|
+
inferred2
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const v1Services = {};
|
|
244
|
+
for (const [name, svc] of Object.entries(detectResult.services)) {
|
|
245
|
+
v1Services[name] = {
|
|
246
|
+
root: svc.root === "." ? void 0 : svc.root,
|
|
247
|
+
...svc.framework ? { framework: svc.framework } : {},
|
|
248
|
+
...svc.entrypoint ? { entrypoint: svc.entrypoint } : {},
|
|
249
|
+
...svc.type ? { type: svc.type } : {},
|
|
250
|
+
...svc.buildCommand ? { buildCommand: svc.buildCommand } : {},
|
|
251
|
+
...svc.preDeployCommand ? { preDeployCommand: svc.preDeployCommand } : {},
|
|
252
|
+
...svc.mountPath ? { routePrefix: svc.mountPath } : {}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const result = await (0, import_resolve.resolveAllConfiguredServices)(
|
|
256
|
+
v1Services,
|
|
257
|
+
scopedFs,
|
|
258
|
+
"generated"
|
|
259
|
+
);
|
|
260
|
+
const shouldInfer = result.errors.length === 0 && result.services.length > 0;
|
|
261
|
+
const inferred = shouldInfer ? {
|
|
262
|
+
source,
|
|
263
|
+
config: toInferredLayoutConfig(detectResult.services),
|
|
264
|
+
services: result.services,
|
|
265
|
+
warnings: detectResult.warnings
|
|
266
|
+
} : null;
|
|
267
|
+
return withResolvedResult(
|
|
268
|
+
{
|
|
269
|
+
services: [],
|
|
270
|
+
source: "auto-detected",
|
|
271
|
+
useImplicitEnvInjection: true,
|
|
272
|
+
routes: emptyRoutes(),
|
|
273
|
+
rewrites: [],
|
|
274
|
+
errors: result.errors,
|
|
275
|
+
warnings: detectResult.warnings
|
|
276
|
+
},
|
|
277
|
+
inferred
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
function generateServiceRewrites(services) {
|
|
281
|
+
const entries = Object.entries(services).filter(
|
|
282
|
+
([, svc]) => typeof svc.mountPath === "string" && (!svc.type || svc.type === "web")
|
|
283
|
+
).sort(([, a], [, b]) => b.mountPath.length - a.mountPath.length);
|
|
284
|
+
return entries.map(([name, svc]) => {
|
|
285
|
+
const mountPath = svc.mountPath;
|
|
286
|
+
if (mountPath === "/") {
|
|
287
|
+
return {
|
|
288
|
+
source: "/(.*)",
|
|
289
|
+
destination: { type: "service", service: name }
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const prefix = mountPath.startsWith("/") ? mountPath.slice(1) : mountPath;
|
|
293
|
+
return {
|
|
294
|
+
source: `/${prefix}(/.*)?`,
|
|
295
|
+
destination: { type: "service", service: name }
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
function generateServicesRoutes(allServices) {
|
|
300
|
+
const services = allServices.filter(import_build_utils.isExperimentalService);
|
|
301
|
+
const hostRewrites = [];
|
|
302
|
+
const rewrites = [];
|
|
303
|
+
const defaults = [];
|
|
304
|
+
const fallbacks = [];
|
|
305
|
+
const crons = [];
|
|
306
|
+
const workers = [];
|
|
307
|
+
const sortedWebServices = services.filter(
|
|
308
|
+
(s) => s.type === "web" && typeof s.routePrefix === "string"
|
|
309
|
+
).sort((a, b) => b.routePrefix.length - a.routePrefix.length);
|
|
310
|
+
const allWebPrefixes = getWebRoutePrefixes(sortedWebServices);
|
|
311
|
+
const explicitHostPrefixGuard = getExplicitHostPrefixNegativeLookahead(allWebPrefixes);
|
|
312
|
+
for (const service of sortedWebServices) {
|
|
313
|
+
const { routePrefix } = service;
|
|
314
|
+
const normalizedPrefix = routePrefix.slice(1);
|
|
315
|
+
const ownershipGuard = (0, import_routing_utils.getOwnershipGuard)(routePrefix, allWebPrefixes);
|
|
316
|
+
const hostCondition = getHostCondition(service);
|
|
317
|
+
if (hostCondition && routePrefix !== "/") {
|
|
318
|
+
const normalizedRoutePrefix = (0, import_routing_utils.normalizeRoutePrefix)(routePrefix);
|
|
319
|
+
hostRewrites.push({
|
|
320
|
+
src: "^/$",
|
|
321
|
+
dest: normalizedRoutePrefix,
|
|
322
|
+
has: hostCondition,
|
|
323
|
+
missing: PREVIEW_DOMAIN_MISSING,
|
|
324
|
+
check: true
|
|
325
|
+
});
|
|
326
|
+
hostRewrites.push({
|
|
327
|
+
// Preserve explicit service prefixes so canonical paths like /_/api
|
|
328
|
+
// keep routing to their target service even on another service's host.
|
|
329
|
+
src: `^/${explicitHostPrefixGuard}(.*)$`,
|
|
330
|
+
dest: `${normalizedRoutePrefix}/$1`,
|
|
331
|
+
has: hostCondition,
|
|
332
|
+
missing: PREVIEW_DOMAIN_MISSING,
|
|
333
|
+
check: true
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
if ((0, import_utils.isRouteOwningBuilder)(service)) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if ((0, import_utils.isStaticBuild)(service)) {
|
|
340
|
+
if (routePrefix === "/") {
|
|
341
|
+
fallbacks.push({
|
|
342
|
+
src: (0, import_routing_utils.scopeRouteSourceToOwnership)("/(.*)", ownershipGuard),
|
|
343
|
+
dest: "/index.html"
|
|
344
|
+
});
|
|
345
|
+
} else {
|
|
346
|
+
fallbacks.push({
|
|
347
|
+
src: (0, import_routing_utils.scopeRouteSourceToOwnership)(
|
|
348
|
+
`^/${normalizedPrefix}(?:/.*)?$`,
|
|
349
|
+
ownershipGuard
|
|
350
|
+
),
|
|
351
|
+
dest: `/${normalizedPrefix}/index.html`
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
} else if (service.runtime) {
|
|
355
|
+
const functionPath = (0, import_utils.getInternalServiceFunctionPath)(service.name);
|
|
356
|
+
const check = service.runtime === "container" ? void 0 : true;
|
|
357
|
+
if (routePrefix === "/") {
|
|
358
|
+
defaults.push({
|
|
359
|
+
src: (0, import_routing_utils.scopeRouteSourceToOwnership)("^/(.*)$", ownershipGuard),
|
|
360
|
+
dest: functionPath,
|
|
361
|
+
...check ? { check } : {}
|
|
362
|
+
});
|
|
363
|
+
} else {
|
|
364
|
+
rewrites.push({
|
|
365
|
+
src: (0, import_routing_utils.scopeRouteSourceToOwnership)(
|
|
366
|
+
`^/${normalizedPrefix}(?:/.*)?$`,
|
|
367
|
+
ownershipGuard
|
|
368
|
+
),
|
|
369
|
+
dest: functionPath,
|
|
370
|
+
...check ? { check } : {}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const cronServices = services.filter(import_build_utils.isScheduleTriggeredService);
|
|
376
|
+
for (const service of cronServices) {
|
|
377
|
+
const cronPrefix = (0, import_utils.getInternalServiceCronPathPrefix)(service.name);
|
|
378
|
+
const functionPath = (0, import_utils.getInternalServiceFunctionPath)(service.name);
|
|
379
|
+
crons.push({
|
|
380
|
+
src: `^${escapeRegex(cronPrefix)}/.*$`,
|
|
381
|
+
dest: functionPath,
|
|
382
|
+
check: true
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
return { hostRewrites, rewrites, defaults, fallbacks, crons, workers };
|
|
386
|
+
}
|
|
387
|
+
function escapeRegex(str) {
|
|
388
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
389
|
+
}
|
|
390
|
+
function getWebRoutePrefixes(services) {
|
|
391
|
+
const unique = /* @__PURE__ */ new Set();
|
|
392
|
+
for (const service of services) {
|
|
393
|
+
if (service.type !== "web" || typeof service.routePrefix !== "string") {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
unique.add((0, import_routing_utils.normalizeRoutePrefix)(service.routePrefix));
|
|
397
|
+
}
|
|
398
|
+
return Array.from(unique);
|
|
399
|
+
}
|
|
400
|
+
function getExplicitHostPrefixNegativeLookahead(routePrefixes) {
|
|
401
|
+
const explicitPrefixes = routePrefixes.map(import_routing_utils.normalizeRoutePrefix).filter((prefix) => prefix !== "/").sort((a, b) => b.length - a.length).map((prefix) => escapeRegex(prefix.slice(1)));
|
|
402
|
+
if (explicitPrefixes.length === 0) {
|
|
403
|
+
return "";
|
|
404
|
+
}
|
|
405
|
+
if (explicitPrefixes.length === 1) {
|
|
406
|
+
return `(?!${explicitPrefixes[0]}(?:/|$))`;
|
|
407
|
+
}
|
|
408
|
+
return `(?!(?:${explicitPrefixes.join("|")})(?:/|$))`;
|
|
409
|
+
}
|
|
410
|
+
function getHostCondition(service) {
|
|
411
|
+
if (service.type !== "web") {
|
|
412
|
+
return void 0;
|
|
413
|
+
}
|
|
414
|
+
if (typeof service.subdomain === "string" && service.subdomain.length > 0) {
|
|
415
|
+
return [{ type: "host", value: { pre: `${service.subdomain}.` } }];
|
|
416
|
+
}
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
419
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
420
|
+
0 && (module.exports = {
|
|
421
|
+
detectServices,
|
|
422
|
+
generateServiceRewrites,
|
|
423
|
+
generateServicesRoutes
|
|
424
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExperimentalServiceV2, ExperimentalServiceV2Config, ExperimentalServicesV2, ServiceDetectionError } from './types';
|
|
2
|
+
import type { DetectorFilesystem } from '../detectors/filesystem';
|
|
3
|
+
export declare function validateServiceConfigV2(name: string, config: ExperimentalServiceV2Config): ServiceDetectionError | null;
|
|
4
|
+
export declare function resolveConfiguredServiceV2(name: string, config: ExperimentalServiceV2Config, fs: DetectorFilesystem): Promise<{
|
|
5
|
+
service?: ExperimentalServiceV2;
|
|
6
|
+
error?: ServiceDetectionError;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function resolveAllConfiguredServicesV2(services: ExperimentalServicesV2, fs: DetectorFilesystem): Promise<{
|
|
9
|
+
services: ExperimentalServiceV2[];
|
|
10
|
+
errors: ServiceDetectionError[];
|
|
11
|
+
}>;
|