@vercel/fs-detectors 5.8.5 → 5.8.6

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 CHANGED
@@ -2,7 +2,7 @@ export { detectBuilders, detectOutputDirectory, detectApiDirectory, detectApiExt
2
2
  export { detectServices, generateServicesRoutes, } from './services/detect-services';
3
3
  export { autoDetectServices } from './services/auto-detect';
4
4
  export type { AutoDetectOptions, AutoDetectResult, } from './services/auto-detect';
5
- export { isStaticBuild, isRouteOwningBuilder } from './services/utils';
5
+ export { isStaticBuild, isRouteOwningBuilder, INTERNAL_SERVICE_PREFIX, getInternalServiceFunctionPath, } from './services/utils';
6
6
  export { getServicesBuilders } from './services/get-services-builders';
7
7
  export type { DetectServicesOptions, DetectServicesResult, ResolvedService, Service, ServicesRoutes, ServiceDetectionError, } from './services/types';
8
8
  export { detectFileSystemAPI } from './detect-file-system-api';
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ __export(src_exports, {
22
22
  DetectorFilesystem: () => import_filesystem.DetectorFilesystem,
23
23
  GetWorkspaceOptions: () => import_get_workspaces.GetWorkspaceOptions,
24
24
  GetWorkspacePackagePathsOptions: () => import_get_workspace_package_paths.GetWorkspacePackagePathsOptions,
25
+ INTERNAL_SERVICE_PREFIX: () => import_utils.INTERNAL_SERVICE_PREFIX,
25
26
  LocalFileSystemDetector: () => import_local_file_system_detector.LocalFileSystemDetector,
26
27
  REGEX_NON_VERCEL_PLATFORM_FILES: () => import_detect_builders2.REGEX_NON_VERCEL_PLATFORM_FILES,
27
28
  Workspace: () => import_get_workspaces.Workspace,
@@ -39,6 +40,7 @@ __export(src_exports, {
39
40
  detectOutputDirectory: () => import_detect_builders.detectOutputDirectory,
40
41
  detectServices: () => import_detect_services.detectServices,
41
42
  generateServicesRoutes: () => import_detect_services.generateServicesRoutes,
43
+ getInternalServiceFunctionPath: () => import_utils.getInternalServiceFunctionPath,
42
44
  getProjectPaths: () => import_get_project_paths.getProjectPaths,
43
45
  getServicesBuilders: () => import_get_services_builders.getServicesBuilders,
44
46
  getWorkspacePackagePaths: () => import_get_workspace_package_paths.getWorkspacePackagePaths,
@@ -76,6 +78,7 @@ var import_detect_instrumentation = require("./detect-instrumentation");
76
78
  DetectorFilesystem,
77
79
  GetWorkspaceOptions,
78
80
  GetWorkspacePackagePathsOptions,
81
+ INTERNAL_SERVICE_PREFIX,
79
82
  LocalFileSystemDetector,
80
83
  REGEX_NON_VERCEL_PLATFORM_FILES,
81
84
  Workspace,
@@ -93,6 +96,7 @@ var import_detect_instrumentation = require("./detect-instrumentation");
93
96
  detectOutputDirectory,
94
97
  detectServices,
95
98
  generateServicesRoutes,
99
+ getInternalServiceFunctionPath,
96
100
  getProjectPaths,
97
101
  getServicesBuilders,
98
102
  getWorkspacePackagePaths,
@@ -1,4 +1,4 @@
1
- import type { DetectServicesOptions, DetectServicesResult, ResolvedService, ServicesRoutes } from './types';
1
+ import { type DetectServicesOptions, type DetectServicesResult, type ResolvedService, type ServicesRoutes } from './types';
2
2
  /**
3
3
  * Detect and resolve services within a project.
4
4
  *
@@ -20,7 +20,8 @@ export declare function detectServices(options: DetectServicesOptions): Promise<
20
20
  * SPA fallback routes to index.html under the service prefix.
21
21
  *
22
22
  * - **Runtime services** (`@vercel/python`, `@vercel/go`, `@vercel/ruby`, etc.):
23
- * Prefix rewrites to the function entrypoint with `check: true`.
23
+ * Prefix rewrites to an internal runtime destination (`/_svc/{name}/index`)
24
+ * with `check: true`.
24
25
  *
25
26
  * Builders that provide their own routing (`@vercel/next`, `@vercel/backends`,
26
27
  * Build Output API builders, etc.) are not given synthetic routes here.
@@ -22,7 +22,7 @@ __export(detect_services_exports, {
22
22
  generateServicesRoutes: () => generateServicesRoutes
23
23
  });
24
24
  module.exports = __toCommonJS(detect_services_exports);
25
- var import_types = require("./types");
25
+ var import_routing_utils = require("@vercel/routing-utils");
26
26
  var import_utils = require("./utils");
27
27
  var import_resolve = require("./resolve");
28
28
  var import_auto_detect = require("./auto-detect");
@@ -86,45 +86,47 @@ function generateServicesRoutes(services) {
86
86
  const defaults = [];
87
87
  const crons = [];
88
88
  const workers = [];
89
- const entrypointExtensions = Object.keys(import_types.ENTRYPOINT_EXTENSIONS).sort(
90
- (a, b) => b.length - a.length
91
- );
92
- const stripEntrypointExtension = (entrypoint) => {
93
- for (const ext of entrypointExtensions) {
94
- if (entrypoint.endsWith(ext)) {
95
- return entrypoint.slice(0, -ext.length);
96
- }
97
- }
98
- return entrypoint;
99
- };
100
89
  const sortedWebServices = services.filter(
101
90
  (s) => s.type === "web" && typeof s.routePrefix === "string"
102
91
  ).sort((a, b) => b.routePrefix.length - a.routePrefix.length);
92
+ const allWebPrefixes = getWebRoutePrefixes(sortedWebServices);
103
93
  for (const service of sortedWebServices) {
104
94
  const { routePrefix } = service;
105
95
  const normalizedPrefix = routePrefix.slice(1);
96
+ const ownershipGuard = (0, import_routing_utils.getOwnershipGuard)(routePrefix, allWebPrefixes);
106
97
  if ((0, import_utils.isRouteOwningBuilder)(service)) {
107
98
  continue;
108
99
  }
109
100
  if ((0, import_utils.isStaticBuild)(service)) {
110
101
  if (routePrefix === "/") {
111
102
  defaults.push({ handle: "filesystem" });
112
- defaults.push({ src: "/(.*)", dest: "/index.html" });
103
+ defaults.push({
104
+ src: (0, import_routing_utils.scopeRouteSourceToOwnership)("/(.*)", ownershipGuard),
105
+ dest: "/index.html"
106
+ });
113
107
  } else {
114
108
  rewrites.push({
115
- src: `^/${normalizedPrefix}(?:/.*)?$`,
109
+ src: (0, import_routing_utils.scopeRouteSourceToOwnership)(
110
+ `^/${normalizedPrefix}(?:/.*)?$`,
111
+ ownershipGuard
112
+ ),
116
113
  dest: `/${normalizedPrefix}/index.html`
117
114
  });
118
115
  }
119
116
  } else if (service.runtime) {
120
- const builderSrc = service.builder.src || routePrefix;
121
- const extensionless = stripEntrypointExtension(builderSrc);
122
- const functionPath = extensionless.startsWith("/") ? extensionless : `/${extensionless}`;
117
+ const functionPath = (0, import_utils.getInternalServiceFunctionPath)(service.name);
123
118
  if (routePrefix === "/") {
124
- defaults.push({ src: "^/(.*)$", dest: functionPath, check: true });
119
+ defaults.push({
120
+ src: (0, import_routing_utils.scopeRouteSourceToOwnership)("^/(.*)$", ownershipGuard),
121
+ dest: functionPath,
122
+ check: true
123
+ });
125
124
  } else {
126
125
  rewrites.push({
127
- src: `^/${normalizedPrefix}(?:/.*)?$`,
126
+ src: (0, import_routing_utils.scopeRouteSourceToOwnership)(
127
+ `^/${normalizedPrefix}(?:/.*)?$`,
128
+ ownershipGuard
129
+ ),
128
130
  dest: functionPath,
129
131
  check: true
130
132
  });
@@ -135,6 +137,16 @@ function generateServicesRoutes(services) {
135
137
  }
136
138
  return { rewrites, defaults, crons, workers };
137
139
  }
140
+ function getWebRoutePrefixes(services) {
141
+ const unique = /* @__PURE__ */ new Set();
142
+ for (const service of services) {
143
+ if (service.type !== "web" || typeof service.routePrefix !== "string") {
144
+ continue;
145
+ }
146
+ unique.add((0, import_routing_utils.normalizeRoutePrefix)(service.routePrefix));
147
+ }
148
+ return Array.from(unique);
149
+ }
138
150
  // Annotate the CommonJS export names for ESM import in node:
139
151
  0 && (module.exports = {
140
152
  detectServices,
@@ -37,14 +37,12 @@ var import_path = require("path");
37
37
  var import_types = require("./types");
38
38
  var import_utils = require("./utils");
39
39
  var import_frameworks = __toESM(require("@vercel/frameworks"));
40
+ var import_routing_utils = require("@vercel/routing-utils");
40
41
  const frameworksBySlug = new Map(import_frameworks.default.map((f) => [f.slug, f]));
41
42
  const SERVICE_NAME_REGEX = /^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
42
- function normalizeRoutePrefix(routePrefix) {
43
- let normalized = routePrefix.startsWith("/") ? routePrefix : `/${routePrefix}`;
44
- if (normalized !== "/" && normalized.endsWith("/")) {
45
- normalized = normalized.slice(0, -1);
46
- }
47
- return normalized || "/";
43
+ function isReservedServiceRoutePrefix(routePrefix) {
44
+ const normalized = (0, import_routing_utils.normalizeRoutePrefix)(routePrefix);
45
+ return normalized === import_utils.INTERNAL_SERVICE_PREFIX || normalized.startsWith(`${import_utils.INTERNAL_SERVICE_PREFIX}/`);
48
46
  }
49
47
  function validateServiceConfig(name, config) {
50
48
  if (!SERVICE_NAME_REGEX.test(name)) {
@@ -69,6 +67,13 @@ function validateServiceConfig(name, config) {
69
67
  serviceName: name
70
68
  };
71
69
  }
70
+ if (serviceType === "web" && config.routePrefix && isReservedServiceRoutePrefix(config.routePrefix)) {
71
+ return {
72
+ code: "RESERVED_ROUTE_PREFIX",
73
+ message: `Web service "${name}" cannot use routePrefix "${config.routePrefix}". The "${import_utils.INTERNAL_SERVICE_PREFIX}" prefix is reserved for internal services routing.`,
74
+ serviceName: name
75
+ };
76
+ }
72
77
  if ((serviceType === "worker" || serviceType === "cron") && config.routePrefix) {
73
78
  return {
74
79
  code: "INVALID_ROUTE_PREFIX",
@@ -206,7 +211,7 @@ function resolveAllConfiguredServices(services) {
206
211
  }
207
212
  const service = resolveConfiguredService(name, serviceConfig);
208
213
  if (service.type === "web" && typeof service.routePrefix === "string") {
209
- const normalizedRoutePrefix = normalizeRoutePrefix(service.routePrefix);
214
+ const normalizedRoutePrefix = (0, import_routing_utils.normalizeRoutePrefix)(service.routePrefix);
210
215
  const existingServiceName = webServicesByRoutePrefix.get(
211
216
  normalizedRoutePrefix
212
217
  );
@@ -1,5 +1,10 @@
1
1
  import type { DetectorFilesystem } from '../detectors/filesystem';
2
2
  import type { ServiceRuntime, ExperimentalServices, ServiceDetectionError, ResolvedService } from './types';
3
+ /**
4
+ * Reserved internal namespace used by services routing/runtime plumbing.
5
+ */
6
+ export declare const INTERNAL_SERVICE_PREFIX = "/_svc";
7
+ export declare function getInternalServiceFunctionPath(serviceName: string): string;
3
8
  export declare function getBuilderForRuntime(runtime: ServiceRuntime): string;
4
9
  export declare function isStaticBuild(service: ResolvedService): boolean;
5
10
  /**
@@ -18,7 +18,9 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var utils_exports = {};
20
20
  __export(utils_exports, {
21
+ INTERNAL_SERVICE_PREFIX: () => INTERNAL_SERVICE_PREFIX,
21
22
  getBuilderForRuntime: () => getBuilderForRuntime,
23
+ getInternalServiceFunctionPath: () => getInternalServiceFunctionPath,
22
24
  inferServiceRuntime: () => inferServiceRuntime,
23
25
  isRouteOwningBuilder: () => isRouteOwningBuilder,
24
26
  isStaticBuild: () => isStaticBuild,
@@ -27,6 +29,10 @@ __export(utils_exports, {
27
29
  module.exports = __toCommonJS(utils_exports);
28
30
  var import_framework_helpers = require("@vercel/build-utils/dist/framework-helpers");
29
31
  var import_types = require("./types");
32
+ const INTERNAL_SERVICE_PREFIX = "/_svc";
33
+ function getInternalServiceFunctionPath(serviceName) {
34
+ return `${INTERNAL_SERVICE_PREFIX}/${serviceName}/index`;
35
+ }
30
36
  function getBuilderForRuntime(runtime) {
31
37
  const builder = import_types.RUNTIME_BUILDERS[runtime];
32
38
  if (!builder) {
@@ -87,7 +93,9 @@ async function readVercelConfig(fs) {
87
93
  }
88
94
  // Annotate the CommonJS export names for ESM import in node:
89
95
  0 && (module.exports = {
96
+ INTERNAL_SERVICE_PREFIX,
90
97
  getBuilderForRuntime,
98
+ getInternalServiceFunctionPath,
91
99
  inferServiceRuntime,
92
100
  isRouteOwningBuilder,
93
101
  isStaticBuild,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/fs-detectors",
3
- "version": "5.8.5",
3
+ "version": "5.8.6",
4
4
  "description": "Vercel filesystem detectors",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  "json5": "2.2.2",
20
20
  "minimatch": "3.1.2",
21
21
  "semver": "6.3.1",
22
- "@vercel/routing-utils": "5.3.2",
22
+ "@vercel/routing-utils": "5.3.3",
23
23
  "@vercel/frameworks": "3.17.1",
24
24
  "@vercel/error-utils": "2.0.3"
25
25
  },
@@ -32,7 +32,7 @@
32
32
  "@types/semver": "7.3.10",
33
33
  "jest-junit": "16.0.0",
34
34
  "typescript": "4.9.5",
35
- "@vercel/build-utils": "13.3.5"
35
+ "@vercel/build-utils": "13.4.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "node ../../utils/build.mjs",