@vercel/fs-detectors 5.15.2 → 5.17.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/detect-builders.js
CHANGED
|
@@ -311,7 +311,7 @@ async function maybeGetApiBuilder(fileName, apiMatches, options) {
|
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
313
|
const nodeExtensions = [".js", ".mjs", ".ts", ".tsx"];
|
|
314
|
-
if (process.env.VERCEL_NODE_FILTER_ENTRYPOINTS === "1" && nodeExtensions.some((ext) => fileName.endsWith(ext)) && options.workPath) {
|
|
314
|
+
if (fileName.startsWith("api/") && process.env.VERCEL_NODE_FILTER_ENTRYPOINTS === "1" && nodeExtensions.some((ext) => fileName.endsWith(ext)) && options.workPath) {
|
|
315
315
|
const fsPath = (0, import_path.join)(options.workPath, fileName);
|
|
316
316
|
const isEntrypoint = await (0, import_build_utils.isNodeEntrypoint)({ fsPath });
|
|
317
317
|
if (!isEntrypoint) {
|
|
@@ -8,7 +8,9 @@ type RoutePrefixSource = 'configured' | 'generated';
|
|
|
8
8
|
interface ResolveConfiguredServiceOptions {
|
|
9
9
|
name: string;
|
|
10
10
|
config: ExperimentalServiceConfig;
|
|
11
|
-
fs
|
|
11
|
+
/** Filesystem scoped to the service root (via chdir) when root is set, otherwise the project-level fs. */
|
|
12
|
+
serviceFs: DetectorFilesystem;
|
|
13
|
+
root?: string;
|
|
12
14
|
group?: string;
|
|
13
15
|
resolvedEntrypoint?: ResolvedEntrypointPath;
|
|
14
16
|
routePrefixSource?: RoutePrefixSource;
|
package/dist/services/resolve.js
CHANGED
|
@@ -46,6 +46,33 @@ function parsePyModuleAttrEntrypoint(entrypoint) {
|
|
|
46
46
|
const SERVICE_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
|
|
47
47
|
const DNS_LABEL_RE = /^(?!-)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
|
|
48
48
|
const ENV_PREFIX_RE = /^[A-Z][A-Z0-9_]*_$/;
|
|
49
|
+
async function getServiceFs(fs, serviceName, root) {
|
|
50
|
+
if (!root) {
|
|
51
|
+
return { fs };
|
|
52
|
+
}
|
|
53
|
+
const normalizedRoot = import_path.posix.normalize(root);
|
|
54
|
+
if (!await fs.hasPath(normalizedRoot)) {
|
|
55
|
+
return {
|
|
56
|
+
fs,
|
|
57
|
+
error: {
|
|
58
|
+
code: "ROOT_NOT_FOUND",
|
|
59
|
+
message: `Service "${serviceName}" has root "${root}" but that directory does not exist.`,
|
|
60
|
+
serviceName
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (await fs.isFile(normalizedRoot)) {
|
|
65
|
+
return {
|
|
66
|
+
fs,
|
|
67
|
+
error: {
|
|
68
|
+
code: "ROOT_NOT_DIRECTORY",
|
|
69
|
+
message: `Service "${serviceName}" has root "${root}" but that path is a file, not a directory.`,
|
|
70
|
+
serviceName
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { fs: fs.chdir(normalizedRoot) };
|
|
75
|
+
}
|
|
49
76
|
function normalizeServiceEntrypoint(entrypoint) {
|
|
50
77
|
const normalized = import_path.posix.normalize(entrypoint);
|
|
51
78
|
return normalized === "" ? "." : normalized;
|
|
@@ -304,6 +331,23 @@ function validateServiceConfig(name, config) {
|
|
|
304
331
|
serviceName: name
|
|
305
332
|
};
|
|
306
333
|
}
|
|
334
|
+
if (config.root !== void 0) {
|
|
335
|
+
const normalizedRoot = import_path.posix.normalize(config.root);
|
|
336
|
+
if (normalizedRoot.startsWith("/")) {
|
|
337
|
+
return {
|
|
338
|
+
code: "INVALID_ROOT",
|
|
339
|
+
message: `Service "${name}" has invalid "root" "${config.root}". Must be a relative path.`,
|
|
340
|
+
serviceName: name
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
if (normalizedRoot === ".." || normalizedRoot.startsWith("../")) {
|
|
344
|
+
return {
|
|
345
|
+
code: "INVALID_ROOT",
|
|
346
|
+
message: `Service "${name}" has invalid "root" "${config.root}". Must not escape the project root.`,
|
|
347
|
+
serviceName: name
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
307
351
|
if (config.envPrefix !== void 0) {
|
|
308
352
|
if (!ENV_PREFIX_RE.test(config.envPrefix)) {
|
|
309
353
|
return {
|
|
@@ -377,14 +421,15 @@ async function resolveConfiguredService(options) {
|
|
|
377
421
|
const {
|
|
378
422
|
name,
|
|
379
423
|
config,
|
|
380
|
-
|
|
424
|
+
serviceFs,
|
|
425
|
+
root,
|
|
381
426
|
group,
|
|
382
427
|
resolvedEntrypoint,
|
|
383
428
|
routePrefixSource = "configured"
|
|
384
429
|
} = options;
|
|
385
430
|
const type = config.type || "web";
|
|
386
431
|
const rawEntrypoint = config.entrypoint;
|
|
387
|
-
const moduleAttrParsed = typeof rawEntrypoint === "string"
|
|
432
|
+
const moduleAttrParsed = typeof rawEntrypoint === "string" ? parsePyModuleAttrEntrypoint(rawEntrypoint) : null;
|
|
388
433
|
const routingResult = resolveServiceRoutingConfig(name, config);
|
|
389
434
|
if (routingResult.error) {
|
|
390
435
|
throw new Error(routingResult.error.message);
|
|
@@ -396,7 +441,7 @@ async function resolveConfiguredService(options) {
|
|
|
396
441
|
if (!resolvedEntrypointPath && typeof rawEntrypoint === "string") {
|
|
397
442
|
const entrypointToResolve = moduleAttrParsed ? moduleAttrParsed.filePath : rawEntrypoint;
|
|
398
443
|
const resolved = await resolveEntrypointPath({
|
|
399
|
-
fs,
|
|
444
|
+
fs: serviceFs,
|
|
400
445
|
serviceName: name,
|
|
401
446
|
entrypoint: entrypointToResolve
|
|
402
447
|
});
|
|
@@ -419,7 +464,7 @@ async function resolveConfiguredService(options) {
|
|
|
419
464
|
workspace = normalizedEntrypoint;
|
|
420
465
|
} else {
|
|
421
466
|
const inferredWorkspace = await inferWorkspaceFromNearestManifest({
|
|
422
|
-
fs,
|
|
467
|
+
fs: serviceFs,
|
|
423
468
|
entrypoint: resolvedEntrypointFile,
|
|
424
469
|
runtime: inferredRuntime
|
|
425
470
|
});
|
|
@@ -433,6 +478,12 @@ async function resolveConfiguredService(options) {
|
|
|
433
478
|
}
|
|
434
479
|
}
|
|
435
480
|
}
|
|
481
|
+
if (root) {
|
|
482
|
+
const normalizedRoot = import_path.posix.normalize(root);
|
|
483
|
+
if (normalizedRoot !== ".") {
|
|
484
|
+
workspace = workspace === "." ? normalizedRoot : import_path.posix.join(normalizedRoot, workspace);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
436
487
|
const topics = type === "worker" ? (0, import_build_utils.getWorkerTopics)(config) : config.topics;
|
|
437
488
|
const consumer = type === "worker" ? config.consumer || "default" : config.consumer;
|
|
438
489
|
let builderUse;
|
|
@@ -532,13 +583,19 @@ async function resolveAllConfiguredServices(services, fs, routePrefixSource = "c
|
|
|
532
583
|
errors.push(validationError);
|
|
533
584
|
continue;
|
|
534
585
|
}
|
|
586
|
+
const root = serviceConfig.root;
|
|
587
|
+
const serviceFsResult = await getServiceFs(fs, name, root);
|
|
588
|
+
if (serviceFsResult.error) {
|
|
589
|
+
errors.push(serviceFsResult.error);
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const serviceFs = serviceFsResult.fs;
|
|
535
593
|
let resolvedEntrypoint;
|
|
536
|
-
const serviceType = serviceConfig.type || "web";
|
|
537
594
|
if (typeof serviceConfig.entrypoint === "string") {
|
|
538
|
-
const moduleAttr =
|
|
539
|
-
const entrypointToResolve = moduleAttr
|
|
595
|
+
const moduleAttr = parsePyModuleAttrEntrypoint(serviceConfig.entrypoint);
|
|
596
|
+
const entrypointToResolve = moduleAttr?.filePath ?? serviceConfig.entrypoint;
|
|
540
597
|
const resolvedPath = await resolveEntrypointPath({
|
|
541
|
-
fs,
|
|
598
|
+
fs: serviceFs,
|
|
542
599
|
serviceName: name,
|
|
543
600
|
entrypoint: entrypointToResolve
|
|
544
601
|
});
|
|
@@ -567,7 +624,7 @@ async function resolveAllConfiguredServices(services, fs, routePrefixSource = "c
|
|
|
567
624
|
});
|
|
568
625
|
const workspace = resolvedEntrypoint.normalized;
|
|
569
626
|
const { framework, error } = await detectFrameworkFromWorkspace({
|
|
570
|
-
fs,
|
|
627
|
+
fs: serviceFs,
|
|
571
628
|
workspace,
|
|
572
629
|
runtime: inferredRuntime,
|
|
573
630
|
serviceName: name
|
|
@@ -595,13 +652,13 @@ async function resolveAllConfiguredServices(services, fs, routePrefixSource = "c
|
|
|
595
652
|
});
|
|
596
653
|
if (inferredRuntime) {
|
|
597
654
|
const inferredWorkspace = await inferWorkspaceFromNearestManifest({
|
|
598
|
-
fs,
|
|
655
|
+
fs: serviceFs,
|
|
599
656
|
entrypoint: resolvedEntrypoint.normalized,
|
|
600
657
|
runtime: inferredRuntime
|
|
601
658
|
});
|
|
602
659
|
const workspace = inferredWorkspace ?? import_path.posix.dirname(resolvedEntrypoint.normalized);
|
|
603
660
|
const detection = await detectFrameworkFromWorkspace({
|
|
604
|
-
fs,
|
|
661
|
+
fs: serviceFs,
|
|
605
662
|
workspace,
|
|
606
663
|
serviceName: name,
|
|
607
664
|
runtime: inferredRuntime
|
|
@@ -618,7 +675,8 @@ async function resolveAllConfiguredServices(services, fs, routePrefixSource = "c
|
|
|
618
675
|
const service = await resolveConfiguredService({
|
|
619
676
|
name,
|
|
620
677
|
config: resolvedConfig,
|
|
621
|
-
|
|
678
|
+
serviceFs,
|
|
679
|
+
root,
|
|
622
680
|
resolvedEntrypoint,
|
|
623
681
|
routePrefixSource
|
|
624
682
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/fs-detectors",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.17.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/
|
|
24
|
-
"@vercel/build-utils": "13.14.2",
|
|
23
|
+
"@vercel/build-utils": "13.16.0",
|
|
25
24
|
"@vercel/routing-utils": "6.1.1",
|
|
26
|
-
"@vercel/error-utils": "2.0.3"
|
|
25
|
+
"@vercel/error-utils": "2.0.3",
|
|
26
|
+
"@vercel/frameworks": "3.24.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/glob": "7.2.0",
|