@vercel/fs-detectors 6.5.0 → 6.6.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.
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import type { DetectEntrypointFn } from '@vercel/build-utils';
|
|
1
2
|
import type { DetectorFilesystem } from '../detectors/filesystem';
|
|
2
3
|
import type { ExperimentalServices, ServiceDetectionError, ServiceDetectionWarning } from './types';
|
|
3
4
|
export interface AutoDetectOptions {
|
|
4
5
|
fs: DetectorFilesystem;
|
|
6
|
+
/**
|
|
7
|
+
* Optional callback used to enrich runtime services with a normalized
|
|
8
|
+
* entrypoint (file path or `module:attr` reference).
|
|
9
|
+
*/
|
|
10
|
+
detectEntrypoint?: DetectEntrypointFn;
|
|
5
11
|
}
|
|
6
12
|
export interface AutoDetectResult {
|
|
7
13
|
services: ExperimentalServices | null;
|
|
@@ -30,7 +30,7 @@ const BACKEND_DIR = "backend";
|
|
|
30
30
|
const SERVICES_DIR = "services";
|
|
31
31
|
const FRONTEND_LOCATIONS = [FRONTEND_DIR, APPS_WEB_DIR];
|
|
32
32
|
async function autoDetectServices(options) {
|
|
33
|
-
const { fs } = options;
|
|
33
|
+
const { fs, detectEntrypoint } = options;
|
|
34
34
|
const rootFrameworks = await (0, import_detect_framework.detectFrameworks)({
|
|
35
35
|
fs,
|
|
36
36
|
frameworkList: import_frameworks.frameworkList
|
|
@@ -49,7 +49,7 @@ async function autoDetectServices(options) {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
if (rootFrameworks.length === 1) {
|
|
52
|
-
return detectServicesAtRoot(fs, rootFrameworks[0]);
|
|
52
|
+
return detectServicesAtRoot(fs, rootFrameworks[0], detectEntrypoint);
|
|
53
53
|
}
|
|
54
54
|
for (const frontendLocation of FRONTEND_LOCATIONS) {
|
|
55
55
|
const hasFrontendDir = await fs.hasPath(frontendLocation);
|
|
@@ -78,7 +78,8 @@ async function autoDetectServices(options) {
|
|
|
78
78
|
return detectServicesFrontendSubdir(
|
|
79
79
|
fs,
|
|
80
80
|
frontendFrameworks[0],
|
|
81
|
-
frontendLocation
|
|
81
|
+
frontendLocation,
|
|
82
|
+
detectEntrypoint
|
|
82
83
|
);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -93,13 +94,13 @@ async function autoDetectServices(options) {
|
|
|
93
94
|
]
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
|
-
async function detectServicesAtRoot(fs, rootFramework) {
|
|
97
|
+
async function detectServicesAtRoot(fs, rootFramework, detectEntrypoint) {
|
|
97
98
|
const services = {};
|
|
98
99
|
services.frontend = {
|
|
99
100
|
framework: rootFramework.slug ?? void 0,
|
|
100
101
|
routePrefix: "/"
|
|
101
102
|
};
|
|
102
|
-
const backendResult = await detectBackendServices(fs);
|
|
103
|
+
const backendResult = await detectBackendServices(fs, detectEntrypoint);
|
|
103
104
|
if (backendResult.error) {
|
|
104
105
|
return {
|
|
105
106
|
services: null,
|
|
@@ -121,15 +122,15 @@ async function detectServicesAtRoot(fs, rootFramework) {
|
|
|
121
122
|
errors: []
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
|
-
async function detectServicesFrontendSubdir(fs, frontendFramework, frontendLocation) {
|
|
125
|
+
async function detectServicesFrontendSubdir(fs, frontendFramework, frontendLocation, detectEntrypoint) {
|
|
125
126
|
const services = {};
|
|
126
127
|
const serviceName = frontendLocation.split("/").pop() || "frontend";
|
|
127
128
|
services[serviceName] = {
|
|
128
129
|
framework: frontendFramework.slug ?? void 0,
|
|
129
|
-
|
|
130
|
+
root: frontendLocation,
|
|
130
131
|
routePrefix: "/"
|
|
131
132
|
};
|
|
132
|
-
const backendResult = await detectBackendServices(fs);
|
|
133
|
+
const backendResult = await detectBackendServices(fs, detectEntrypoint);
|
|
133
134
|
if (backendResult.error) {
|
|
134
135
|
return {
|
|
135
136
|
services: null,
|
|
@@ -156,16 +157,24 @@ async function detectServicesFrontendSubdir(fs, frontendFramework, frontendLocat
|
|
|
156
157
|
errors: []
|
|
157
158
|
};
|
|
158
159
|
}
|
|
159
|
-
async function detectBackendServices(fs) {
|
|
160
|
+
async function detectBackendServices(fs, detectEntrypoint) {
|
|
160
161
|
const services = {};
|
|
161
|
-
const backendResult = await detectServiceInDir(
|
|
162
|
+
const backendResult = await detectServiceInDir(
|
|
163
|
+
fs,
|
|
164
|
+
BACKEND_DIR,
|
|
165
|
+
"backend",
|
|
166
|
+
detectEntrypoint
|
|
167
|
+
);
|
|
162
168
|
if (backendResult.error) {
|
|
163
169
|
return { services: {}, error: backendResult.error };
|
|
164
170
|
}
|
|
165
171
|
if (backendResult.service) {
|
|
166
172
|
services.backend = backendResult.service;
|
|
167
173
|
}
|
|
168
|
-
const multiServicesResult = await detectServicesDirectory(
|
|
174
|
+
const multiServicesResult = await detectServicesDirectory(
|
|
175
|
+
fs,
|
|
176
|
+
detectEntrypoint
|
|
177
|
+
);
|
|
169
178
|
if (multiServicesResult.error) {
|
|
170
179
|
return { services: {}, error: multiServicesResult.error };
|
|
171
180
|
}
|
|
@@ -184,7 +193,7 @@ async function detectBackendServices(fs) {
|
|
|
184
193
|
Object.assign(services, multiServicesResult.services);
|
|
185
194
|
return { services };
|
|
186
195
|
}
|
|
187
|
-
async function detectServicesDirectory(fs) {
|
|
196
|
+
async function detectServicesDirectory(fs, detectEntrypoint) {
|
|
188
197
|
const services = {};
|
|
189
198
|
const hasServicesDir = await fs.hasPath(SERVICES_DIR);
|
|
190
199
|
if (!hasServicesDir) {
|
|
@@ -198,7 +207,12 @@ async function detectServicesDirectory(fs) {
|
|
|
198
207
|
}
|
|
199
208
|
const serviceName = entry.name;
|
|
200
209
|
const serviceDir = `${SERVICES_DIR}/${serviceName}`;
|
|
201
|
-
const result = await detectServiceInDir(
|
|
210
|
+
const result = await detectServiceInDir(
|
|
211
|
+
fs,
|
|
212
|
+
serviceDir,
|
|
213
|
+
serviceName,
|
|
214
|
+
detectEntrypoint
|
|
215
|
+
);
|
|
202
216
|
if (result.error) {
|
|
203
217
|
return { services: {}, error: result.error };
|
|
204
218
|
}
|
|
@@ -208,7 +222,7 @@ async function detectServicesDirectory(fs) {
|
|
|
208
222
|
}
|
|
209
223
|
return { services };
|
|
210
224
|
}
|
|
211
|
-
async function detectServiceInDir(fs, dirPath, serviceName) {
|
|
225
|
+
async function detectServiceInDir(fs, dirPath, serviceName, detectEntrypoint) {
|
|
212
226
|
const hasDirPath = await fs.hasPath(dirPath);
|
|
213
227
|
if (!hasDirPath) {
|
|
214
228
|
return {};
|
|
@@ -229,17 +243,21 @@ async function detectServiceInDir(fs, dirPath, serviceName) {
|
|
|
229
243
|
}
|
|
230
244
|
};
|
|
231
245
|
}
|
|
232
|
-
if (frameworks.length
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
service: {
|
|
236
|
-
framework: framework.slug ?? void 0,
|
|
237
|
-
entrypoint: dirPath,
|
|
238
|
-
routePrefix: `/_/${serviceName}`
|
|
239
|
-
}
|
|
240
|
-
};
|
|
246
|
+
if (frameworks.length !== 1) {
|
|
247
|
+
return {};
|
|
241
248
|
}
|
|
242
|
-
|
|
249
|
+
const framework = frameworks[0];
|
|
250
|
+
const slug = framework.slug ?? void 0;
|
|
251
|
+
const routePrefix = `/_/${serviceName}`;
|
|
252
|
+
const detected = detectEntrypoint && !(0, import_utils.isFrontendFramework)(slug) ? await detectEntrypoint({ workPath: dirPath, framework: slug }) : null;
|
|
253
|
+
return {
|
|
254
|
+
service: {
|
|
255
|
+
framework: slug,
|
|
256
|
+
root: dirPath,
|
|
257
|
+
...detected ? { entrypoint: detected.entrypoint } : {},
|
|
258
|
+
routePrefix
|
|
259
|
+
}
|
|
260
|
+
};
|
|
243
261
|
}
|
|
244
262
|
// Annotate the CommonJS export names for ESM import in node:
|
|
245
263
|
0 && (module.exports = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DetectEntrypointFn } from '@vercel/build-utils';
|
|
1
2
|
import type { DetectorFilesystem } from '../detectors/filesystem';
|
|
2
3
|
import type { ExperimentalServices, ServiceDetectionError, ServiceDetectionWarning } from './types';
|
|
3
4
|
export interface RailwayDetectResult {
|
|
@@ -17,4 +18,5 @@ export interface RailwayDetectResult {
|
|
|
17
18
|
*/
|
|
18
19
|
export declare function detectRailwayServices(options: {
|
|
19
20
|
fs: DetectorFilesystem;
|
|
21
|
+
detectEntrypoint?: DetectEntrypointFn;
|
|
20
22
|
}): Promise<RailwayDetectResult>;
|
|
@@ -56,7 +56,7 @@ const SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
56
56
|
"CVS"
|
|
57
57
|
]);
|
|
58
58
|
async function detectRailwayServices(options) {
|
|
59
|
-
const { fs } = options;
|
|
59
|
+
const { fs, detectEntrypoint } = options;
|
|
60
60
|
const { configs, warnings } = await findRailwayConfigs(fs);
|
|
61
61
|
if (configs.length === 0) {
|
|
62
62
|
return { services: null, errors: [], warnings };
|
|
@@ -119,10 +119,20 @@ async function detectRailwayServices(options) {
|
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
const framework = frameworks[0];
|
|
122
|
+
const slug = framework.slug ?? void 0;
|
|
122
123
|
let serviceConfig = {};
|
|
123
|
-
serviceConfig.framework =
|
|
124
|
+
serviceConfig.framework = slug;
|
|
124
125
|
if (cf.dirPath !== ".") {
|
|
125
|
-
serviceConfig.
|
|
126
|
+
serviceConfig.root = cf.dirPath;
|
|
127
|
+
if (detectEntrypoint && !(0, import_utils.isFrontendFramework)(slug)) {
|
|
128
|
+
const detected = await detectEntrypoint({
|
|
129
|
+
workPath: cf.dirPath,
|
|
130
|
+
framework: slug
|
|
131
|
+
});
|
|
132
|
+
if (detected) {
|
|
133
|
+
serviceConfig.entrypoint = detected.entrypoint;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
126
136
|
}
|
|
127
137
|
if (cf.config.build?.buildCommand) {
|
|
128
138
|
serviceConfig.buildCommand = cf.config.build.buildCommand;
|
|
@@ -69,6 +69,9 @@ function toInferredLayoutConfig(services) {
|
|
|
69
69
|
if (service.type) {
|
|
70
70
|
serviceConfig.type = service.type;
|
|
71
71
|
}
|
|
72
|
+
if (typeof service.root === "string") {
|
|
73
|
+
serviceConfig.root = service.root;
|
|
74
|
+
}
|
|
72
75
|
if (typeof service.entrypoint === "string") {
|
|
73
76
|
serviceConfig.entrypoint = service.entrypoint;
|
|
74
77
|
}
|
|
@@ -89,7 +92,7 @@ function toInferredLayoutConfig(services) {
|
|
|
89
92
|
return inferredConfig;
|
|
90
93
|
}
|
|
91
94
|
async function detectServices(options) {
|
|
92
|
-
const { fs, workPath } = options;
|
|
95
|
+
const { fs, workPath, detectEntrypoint } = options;
|
|
93
96
|
const scopedFs = workPath ? fs.chdir(workPath) : fs;
|
|
94
97
|
const { config: vercelConfig, error: configError } = await (0, import_utils.readVercelConfig)(scopedFs);
|
|
95
98
|
if (configError) {
|
|
@@ -113,7 +116,7 @@ async function detectServices(options) {
|
|
|
113
116
|
{ detect: import_auto_detect.autoDetectServices, source: "layout" }
|
|
114
117
|
];
|
|
115
118
|
for (const { detect, source } of detectors) {
|
|
116
|
-
const detectResult = await detect({ fs: scopedFs });
|
|
119
|
+
const detectResult = await detect({ fs: scopedFs, detectEntrypoint });
|
|
117
120
|
const match = await tryResolveInferred(detectResult, source, scopedFs);
|
|
118
121
|
if (match)
|
|
119
122
|
return match;
|
package/dist/services/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Route } from '@vercel/routing-utils';
|
|
2
|
-
import type { EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceGroups, ExperimentalServices, ServiceConfig, Services, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder } from '@vercel/build-utils';
|
|
2
|
+
import type { DetectEntrypointFn, EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceGroups, ExperimentalServices, ServiceConfig, Services, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder } from '@vercel/build-utils';
|
|
3
3
|
import type { DetectorFilesystem } from '../detectors/filesystem';
|
|
4
|
-
export type { EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceGroups, ExperimentalServices, ServiceConfig, Services, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder, };
|
|
4
|
+
export type { DetectEntrypointFn, EnvVar, EnvVars, ExperimentalServiceConfig, ExperimentalServiceGroups, ExperimentalServices, ServiceConfig, Services, ServiceRuntime, ServiceType, ServiceRefEnvVar, Service, Builder, };
|
|
5
5
|
/**
|
|
6
6
|
* @deprecated Use `Service` instead
|
|
7
7
|
*/
|
|
@@ -13,6 +13,12 @@ export interface DetectServicesOptions {
|
|
|
13
13
|
* If provided, vercel.json is read from this path.
|
|
14
14
|
*/
|
|
15
15
|
workPath?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional callback that, given a candidate service directory and its
|
|
18
|
+
* detected framework, returns a normalized entrypoint (file path or
|
|
19
|
+
* `module:attr` reference). Used to suggested service configs.
|
|
20
|
+
*/
|
|
21
|
+
detectEntrypoint?: DetectEntrypointFn;
|
|
16
22
|
}
|
|
17
23
|
export interface ServicesRoutes {
|
|
18
24
|
/** Host-based rewrite routes for subdomain-mounted web services */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/fs-detectors",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "Vercel filesystem detectors",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"minimatch": "3.1.2",
|
|
21
21
|
"semver": "6.3.1",
|
|
22
22
|
"smol-toml": "1.5.2",
|
|
23
|
-
"@vercel/error-utils": "2.1.0",
|
|
24
|
-
"@vercel/routing-utils": "6.2.0",
|
|
25
23
|
"@vercel/build-utils": "13.26.0",
|
|
26
|
-
"@vercel/
|
|
24
|
+
"@vercel/error-utils": "2.1.0",
|
|
25
|
+
"@vercel/frameworks": "3.26.1",
|
|
26
|
+
"@vercel/routing-utils": "6.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/glob": "7.2.0",
|