@vercel/fs-detectors 6.15.10 → 7.0.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.d.ts +2 -9
- package/dist/detect-builders.js +3 -47
- package/dist/index.d.ts +1 -9
- package/dist/index.js +2 -40
- package/package.json +4 -6
- package/dist/services/auto-detect.d.ts +0 -46
- package/dist/services/auto-detect.js +0 -268
- package/dist/services/detect-procfile.d.ts +0 -22
- package/dist/services/detect-procfile.js +0 -249
- package/dist/services/detect-railway.d.ts +0 -22
- package/dist/services/detect-railway.js +0 -241
- package/dist/services/detect-render.d.ts +0 -14
- package/dist/services/detect-render.js +0 -230
- package/dist/services/detect-services.d.ts +0 -48
- package/dist/services/detect-services.js +0 -423
- package/dist/services/get-services-builders.d.ts +0 -43
- package/dist/services/get-services-builders.js +0 -161
- package/dist/services/resolve-v2.d.ts +0 -11
- package/dist/services/resolve-v2.js +0 -395
- package/dist/services/resolve.d.ts +0 -69
- package/dist/services/resolve.js +0 -914
- package/dist/services/types.d.ts +0 -134
- package/dist/services/types.js +0 -77
- package/dist/services/utils.d.ts +0 -95
- package/dist/services/utils.js +0 -265
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Rewrite, Route } from '@vercel/routing-utils';
|
|
2
|
-
import type { Builder, Services } from '@vercel/build-utils';
|
|
3
|
-
import type { ConfiguredServices, ConfiguredServicesType, Service } from './types';
|
|
4
|
-
export interface ErrorResponse {
|
|
5
|
-
code: string;
|
|
6
|
-
message: string;
|
|
7
|
-
action?: string;
|
|
8
|
-
link?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface GetServicesBuildersOptions {
|
|
11
|
-
workPath?: string;
|
|
12
|
-
configuredServices?: ConfiguredServices;
|
|
13
|
-
configuredServicesType?: ConfiguredServicesType;
|
|
14
|
-
projectFramework?: string | null;
|
|
15
|
-
}
|
|
16
|
-
export interface ServicesBuildersResult {
|
|
17
|
-
builders: Builder[] | null;
|
|
18
|
-
errors: ErrorResponse[] | null;
|
|
19
|
-
warnings: ErrorResponse[];
|
|
20
|
-
hostRewriteRoutes: Route[] | null;
|
|
21
|
-
defaultRoutes: Route[] | null;
|
|
22
|
-
fallbackRoutes: Route[] | null;
|
|
23
|
-
redirectRoutes: Route[] | null;
|
|
24
|
-
rewriteRoutes: Route[] | null;
|
|
25
|
-
errorRoutes: Route[] | null;
|
|
26
|
-
/** Top-level service-targeted rewrites generated by auto-detection. */
|
|
27
|
-
serviceRewrites?: Rewrite[];
|
|
28
|
-
/** V2 services config so the platform activates V2 routing. */
|
|
29
|
-
experimentalServicesV2?: Services;
|
|
30
|
-
services?: Service[];
|
|
31
|
-
useImplicitEnvInjection?: boolean;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Get builders for services - adapter for detectBuilders.
|
|
35
|
-
*
|
|
36
|
-
* This function wraps `detectServices` and transforms the result into
|
|
37
|
-
* the shape expected by `detectBuilders` when `framework === 'services'`.
|
|
38
|
-
*/
|
|
39
|
-
export declare function getServicesBuilders(options: GetServicesBuildersOptions): Promise<ServicesBuildersResult>;
|
|
40
|
-
/**
|
|
41
|
-
* Returns warnings for ignored directories that are not covered by services
|
|
42
|
-
*/
|
|
43
|
-
export declare function warnIgnoredDirectories(files: string[], configuredServices: ConfiguredServices): ErrorResponse[];
|
|
@@ -1,161 +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 get_services_builders_exports = {};
|
|
20
|
-
__export(get_services_builders_exports, {
|
|
21
|
-
getServicesBuilders: () => getServicesBuilders,
|
|
22
|
-
warnIgnoredDirectories: () => warnIgnoredDirectories
|
|
23
|
-
});
|
|
24
|
-
module.exports = __toCommonJS(get_services_builders_exports);
|
|
25
|
-
var import_detect_services = require("./detect-services");
|
|
26
|
-
var import_local_file_system_detector = require("../detectors/local-file-system-detector");
|
|
27
|
-
function isExperimentalServicesAutoDetectionEnabled() {
|
|
28
|
-
const env = process.env.VERCEL_USE_EXPERIMENTAL_SERVICES;
|
|
29
|
-
return env === "1" || env?.toLowerCase() === "true";
|
|
30
|
-
}
|
|
31
|
-
async function getServicesBuilders(options) {
|
|
32
|
-
const {
|
|
33
|
-
workPath,
|
|
34
|
-
configuredServices,
|
|
35
|
-
configuredServicesType,
|
|
36
|
-
projectFramework
|
|
37
|
-
} = options;
|
|
38
|
-
const hasServiceDefinitions = configuredServices != null && Object.keys(configuredServices).length > 0;
|
|
39
|
-
if (projectFramework === "services" && !hasServiceDefinitions && !isExperimentalServicesAutoDetectionEnabled()) {
|
|
40
|
-
return {
|
|
41
|
-
builders: null,
|
|
42
|
-
errors: [
|
|
43
|
-
{
|
|
44
|
-
code: "MISSING_SERVICES",
|
|
45
|
-
message: 'Project framework is set to "services", but no services are declared. Add `services` to vercel.json with at least one service, or change the project framework setting.'
|
|
46
|
-
}
|
|
47
|
-
],
|
|
48
|
-
warnings: [],
|
|
49
|
-
hostRewriteRoutes: null,
|
|
50
|
-
defaultRoutes: null,
|
|
51
|
-
fallbackRoutes: null,
|
|
52
|
-
redirectRoutes: null,
|
|
53
|
-
rewriteRoutes: null,
|
|
54
|
-
errorRoutes: null
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
if (!workPath) {
|
|
58
|
-
return {
|
|
59
|
-
builders: null,
|
|
60
|
-
errors: [
|
|
61
|
-
{
|
|
62
|
-
code: "MISSING_WORK_PATH",
|
|
63
|
-
message: "workPath is required for services detection."
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
warnings: [],
|
|
67
|
-
hostRewriteRoutes: null,
|
|
68
|
-
defaultRoutes: null,
|
|
69
|
-
fallbackRoutes: null,
|
|
70
|
-
redirectRoutes: null,
|
|
71
|
-
rewriteRoutes: null,
|
|
72
|
-
errorRoutes: null
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
const fs = new import_local_file_system_detector.LocalFileSystemDetector(workPath);
|
|
76
|
-
const result = await (0, import_detect_services.detectServices)({
|
|
77
|
-
fs,
|
|
78
|
-
configuredServices,
|
|
79
|
-
configuredServicesType
|
|
80
|
-
});
|
|
81
|
-
const warningResponses = result.warnings.map((w) => ({
|
|
82
|
-
code: w.code,
|
|
83
|
-
message: w.message
|
|
84
|
-
}));
|
|
85
|
-
if (result.errors.length > 0) {
|
|
86
|
-
return {
|
|
87
|
-
builders: null,
|
|
88
|
-
errors: result.errors.map((e) => ({
|
|
89
|
-
code: e.code,
|
|
90
|
-
message: e.message
|
|
91
|
-
})),
|
|
92
|
-
warnings: warningResponses,
|
|
93
|
-
hostRewriteRoutes: null,
|
|
94
|
-
defaultRoutes: null,
|
|
95
|
-
fallbackRoutes: null,
|
|
96
|
-
redirectRoutes: null,
|
|
97
|
-
rewriteRoutes: null,
|
|
98
|
-
errorRoutes: null
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
if (result.services.length === 0) {
|
|
102
|
-
return {
|
|
103
|
-
builders: null,
|
|
104
|
-
errors: [
|
|
105
|
-
{
|
|
106
|
-
code: "NO_SERVICES_CONFIGURED",
|
|
107
|
-
message: "No services configured. Add `services` to vercel.json."
|
|
108
|
-
}
|
|
109
|
-
],
|
|
110
|
-
warnings: warningResponses,
|
|
111
|
-
hostRewriteRoutes: null,
|
|
112
|
-
defaultRoutes: null,
|
|
113
|
-
fallbackRoutes: null,
|
|
114
|
-
redirectRoutes: null,
|
|
115
|
-
rewriteRoutes: null,
|
|
116
|
-
errorRoutes: null
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
const builders = result.services.map((service) => service.builder);
|
|
120
|
-
return {
|
|
121
|
-
builders: builders.length > 0 ? builders : null,
|
|
122
|
-
errors: null,
|
|
123
|
-
warnings: warningResponses,
|
|
124
|
-
hostRewriteRoutes: result.routes.hostRewrites.length > 0 ? result.routes.hostRewrites : null,
|
|
125
|
-
defaultRoutes: result.routes.defaults.length > 0 ? result.routes.defaults : null,
|
|
126
|
-
fallbackRoutes: result.routes.fallbacks.length > 0 ? result.routes.fallbacks : null,
|
|
127
|
-
redirectRoutes: [],
|
|
128
|
-
rewriteRoutes: result.routes.rewrites.length > 0 || result.routes.workers.length > 0 || result.routes.crons.length > 0 ? [
|
|
129
|
-
...result.routes.rewrites,
|
|
130
|
-
...result.routes.workers,
|
|
131
|
-
...result.routes.crons
|
|
132
|
-
] : null,
|
|
133
|
-
errorRoutes: [],
|
|
134
|
-
serviceRewrites: result.rewrites.length > 0 ? result.rewrites : void 0,
|
|
135
|
-
experimentalServicesV2: result.experimentalServicesV2,
|
|
136
|
-
services: result.services,
|
|
137
|
-
useImplicitEnvInjection: result.useImplicitEnvInjection
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
function warnIgnoredDirectories(files, configuredServices) {
|
|
141
|
-
const warnings = [];
|
|
142
|
-
if (files.some((f) => f.startsWith("api/"))) {
|
|
143
|
-
const serviceCoversApi = Object.values(configuredServices).some((service) => {
|
|
144
|
-
const root = service.root ?? ".";
|
|
145
|
-
const entrypoint = service.entrypoint ?? "";
|
|
146
|
-
return root === "api" || root.startsWith("api/") || root === "." && entrypoint.startsWith("api/");
|
|
147
|
-
});
|
|
148
|
-
if (!serviceCoversApi) {
|
|
149
|
-
warnings.push({
|
|
150
|
-
code: "api_dir_ignored",
|
|
151
|
-
message: "The `api/` directory will not be built because services are configured. To serve these files, declare them as a service in your `vercel.json`."
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return warnings;
|
|
156
|
-
}
|
|
157
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
158
|
-
0 && (module.exports = {
|
|
159
|
-
getServicesBuilders,
|
|
160
|
-
warnIgnoredDirectories
|
|
161
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
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
|
-
}>;
|
|
@@ -1,395 +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 resolve_v2_exports = {};
|
|
20
|
-
__export(resolve_v2_exports, {
|
|
21
|
-
resolveAllConfiguredServicesV2: () => resolveAllConfiguredServicesV2,
|
|
22
|
-
resolveConfiguredServiceV2: () => resolveConfiguredServiceV2,
|
|
23
|
-
validateServiceConfigV2: () => validateServiceConfigV2
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(resolve_v2_exports);
|
|
26
|
-
var import_path = require("path");
|
|
27
|
-
var import_build_utils = require("@vercel/build-utils");
|
|
28
|
-
var import_frameworks = require("@vercel/frameworks");
|
|
29
|
-
var import_types = require("./types");
|
|
30
|
-
var import_resolve = require("./resolve");
|
|
31
|
-
var import_utils = require("./utils");
|
|
32
|
-
const frameworksBySlug = new Map(import_frameworks.frameworkList.map((f) => [f.slug, f]));
|
|
33
|
-
const MAX_SERVICE_NAME_LENGTH = 64;
|
|
34
|
-
const SERVICE_NAME_REGEX = /^[a-z]([a-z_-]*[a-z])?$/;
|
|
35
|
-
function isValidServiceName(name) {
|
|
36
|
-
return name.length <= MAX_SERVICE_NAME_LENGTH && SERVICE_NAME_REGEX.test(name);
|
|
37
|
-
}
|
|
38
|
-
function getInvalidServiceNameMessage(name) {
|
|
39
|
-
return `Service name "${name}" is invalid. Names must be 1-${MAX_SERVICE_NAME_LENGTH} characters, start and end with a lowercase letter, and contain only lowercase letters, hyphens, and underscores.`;
|
|
40
|
-
}
|
|
41
|
-
const CONTAINER_ENTRYPOINT_CANDIDATES = [
|
|
42
|
-
"Dockerfile.vercel",
|
|
43
|
-
"Containerfile.vercel",
|
|
44
|
-
"Dockerfile",
|
|
45
|
-
"Containerfile"
|
|
46
|
-
];
|
|
47
|
-
const CONTAINER_ENTRYPOINT_BASENAMES = new Set(
|
|
48
|
-
CONTAINER_ENTRYPOINT_CANDIDATES.map((name) => name.toLowerCase())
|
|
49
|
-
);
|
|
50
|
-
function isDockerfileEntrypoint(entrypoint) {
|
|
51
|
-
return CONTAINER_ENTRYPOINT_BASENAMES.has(
|
|
52
|
-
import_path.posix.basename(entrypoint).toLowerCase()
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
async function detectContainerEntrypoint(serviceFs) {
|
|
56
|
-
for (const candidate of CONTAINER_ENTRYPOINT_CANDIDATES) {
|
|
57
|
-
if (await serviceFs.hasPath(candidate)) {
|
|
58
|
-
return candidate;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return void 0;
|
|
62
|
-
}
|
|
63
|
-
function normalizeContainerCommand(command) {
|
|
64
|
-
if (command === void 0) {
|
|
65
|
-
return void 0;
|
|
66
|
-
}
|
|
67
|
-
return Array.isArray(command) ? command : [command];
|
|
68
|
-
}
|
|
69
|
-
async function resolveContainerServiceV2(name, config, normalizedRoot, serviceFs) {
|
|
70
|
-
const isRoot = normalizedRoot === ".";
|
|
71
|
-
const entrypoint = config.entrypoint;
|
|
72
|
-
let dockerfile;
|
|
73
|
-
if (typeof entrypoint === "string") {
|
|
74
|
-
if (!isDockerfileEntrypoint(entrypoint)) {
|
|
75
|
-
return {
|
|
76
|
-
error: {
|
|
77
|
-
code: "INVALID_SERVICE_CONFIG",
|
|
78
|
-
message: `Container service "${name}" has invalid "entrypoint" "${entrypoint}". It must name a Dockerfile or Containerfile.`,
|
|
79
|
-
serviceName: name
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
dockerfile = import_path.posix.normalize(entrypoint);
|
|
84
|
-
} else {
|
|
85
|
-
dockerfile = await detectContainerEntrypoint(serviceFs);
|
|
86
|
-
if (!dockerfile) {
|
|
87
|
-
return {
|
|
88
|
-
error: {
|
|
89
|
-
code: "MISSING_SERVICE_CONFIG",
|
|
90
|
-
message: `Container service "${name}" has no "entrypoint" and no ${CONTAINER_ENTRYPOINT_CANDIDATES.join(
|
|
91
|
-
", "
|
|
92
|
-
)} was found in "${normalizedRoot}".`,
|
|
93
|
-
serviceName: name
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
const builderSrc = isRoot ? dockerfile : import_path.posix.join(normalizedRoot, dockerfile);
|
|
99
|
-
const builderConfig = { zeroConfig: true };
|
|
100
|
-
if (!isRoot) {
|
|
101
|
-
builderConfig.workspace = normalizedRoot;
|
|
102
|
-
}
|
|
103
|
-
const command = normalizeContainerCommand(config.command);
|
|
104
|
-
if (command) {
|
|
105
|
-
builderConfig.command = command;
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
service: {
|
|
109
|
-
schema: "experimentalServicesV2",
|
|
110
|
-
name,
|
|
111
|
-
root: normalizedRoot,
|
|
112
|
-
runtime: "container",
|
|
113
|
-
entrypoint: dockerfile,
|
|
114
|
-
command,
|
|
115
|
-
builder: {
|
|
116
|
-
src: builderSrc,
|
|
117
|
-
use: "@vercel/container",
|
|
118
|
-
config: builderConfig
|
|
119
|
-
},
|
|
120
|
-
bindings: config.bindings,
|
|
121
|
-
functions: config.functions,
|
|
122
|
-
headers: config.headers,
|
|
123
|
-
redirects: config.redirects,
|
|
124
|
-
rewrites: config.rewrites,
|
|
125
|
-
routes: config.routes,
|
|
126
|
-
cleanUrls: config.cleanUrls,
|
|
127
|
-
trailingSlash: config.trailingSlash
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
function validateServiceConfigV2(name, config) {
|
|
132
|
-
if (!isValidServiceName(name)) {
|
|
133
|
-
return {
|
|
134
|
-
code: "INVALID_SERVICE_NAME",
|
|
135
|
-
message: getInvalidServiceNameMessage(name),
|
|
136
|
-
serviceName: name
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
if (!config || typeof config !== "object") {
|
|
140
|
-
return {
|
|
141
|
-
code: "INVALID_SERVICE_CONFIG",
|
|
142
|
-
message: `Service "${name}" has an invalid configuration. Expected an object.`,
|
|
143
|
-
serviceName: name
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
if (typeof config.root !== "string" || config.root.length === 0) {
|
|
147
|
-
return {
|
|
148
|
-
code: "MISSING_ROOT",
|
|
149
|
-
message: `Service "${name}" must specify a "root".`,
|
|
150
|
-
serviceName: name
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
const normalizedRoot = import_path.posix.normalize(config.root);
|
|
154
|
-
if (normalizedRoot.startsWith("/")) {
|
|
155
|
-
return {
|
|
156
|
-
code: "INVALID_ROOT",
|
|
157
|
-
message: `Service "${name}" has invalid "root" "${config.root}". Must be a relative path.`,
|
|
158
|
-
serviceName: name
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (normalizedRoot === ".." || normalizedRoot.startsWith("../")) {
|
|
162
|
-
return {
|
|
163
|
-
code: "INVALID_ROOT",
|
|
164
|
-
message: `Service "${name}" has invalid "root" "${config.root}". Must not escape the project root.`,
|
|
165
|
-
serviceName: name
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
if (config.runtime && !(config.runtime in import_types.RUNTIME_BUILDERS)) {
|
|
169
|
-
return {
|
|
170
|
-
code: "INVALID_RUNTIME",
|
|
171
|
-
message: `Service "${name}" has invalid runtime "${config.runtime}".`,
|
|
172
|
-
serviceName: name
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
if (config.framework && !frameworksBySlug.has(config.framework)) {
|
|
176
|
-
return {
|
|
177
|
-
code: "INVALID_FRAMEWORK",
|
|
178
|
-
message: `Service "${name}" has invalid framework "${config.framework}".`,
|
|
179
|
-
serviceName: name
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
if (config.runtime && config.framework) {
|
|
183
|
-
const frameworkRuntime = (0, import_utils.inferRuntimeFromFramework)(config.framework);
|
|
184
|
-
if (frameworkRuntime && frameworkRuntime !== config.runtime) {
|
|
185
|
-
return {
|
|
186
|
-
code: "RUNTIME_FRAMEWORK_MISMATCH",
|
|
187
|
-
message: `Service "${name}" has conflicting runtime/framework: runtime "${config.runtime}" is incompatible with framework "${config.framework}" (runtime "${frameworkRuntime}").`,
|
|
188
|
-
serviceName: name
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
async function resolveConfiguredServiceV2(name, config, fs) {
|
|
195
|
-
const normalizedRoot = (0, import_utils.stripTrailingSlash)(import_path.posix.normalize(config.root));
|
|
196
|
-
const serviceFsResult = normalizedRoot === "." ? { fs } : await (0, import_resolve.getServiceFs)(fs, name, normalizedRoot);
|
|
197
|
-
if (serviceFsResult.error) {
|
|
198
|
-
return { error: serviceFsResult.error };
|
|
199
|
-
}
|
|
200
|
-
const serviceFs = serviceFsResult.fs;
|
|
201
|
-
const isContainer = config.runtime === "container" || typeof config.entrypoint === "string" && isDockerfileEntrypoint(config.entrypoint);
|
|
202
|
-
if (isContainer) {
|
|
203
|
-
return resolveContainerServiceV2(name, config, normalizedRoot, serviceFs);
|
|
204
|
-
}
|
|
205
|
-
const rawEntrypoint = config.entrypoint;
|
|
206
|
-
const moduleAttr = typeof rawEntrypoint === "string" ? (0, import_resolve.parsePyModuleAttrEntrypoint)(rawEntrypoint) : null;
|
|
207
|
-
let normalizedEntrypoint;
|
|
208
|
-
let entrypointIsDirectory = false;
|
|
209
|
-
if (typeof rawEntrypoint === "string") {
|
|
210
|
-
const entrypointToResolve = moduleAttr ? moduleAttr.filePath : rawEntrypoint;
|
|
211
|
-
const resolved = await (0, import_resolve.resolveEntrypointPath)({
|
|
212
|
-
fs: serviceFs,
|
|
213
|
-
serviceName: name,
|
|
214
|
-
entrypoint: entrypointToResolve
|
|
215
|
-
});
|
|
216
|
-
if (resolved.error) {
|
|
217
|
-
return { error: resolved.error };
|
|
218
|
-
}
|
|
219
|
-
normalizedEntrypoint = resolved.entrypoint?.normalized;
|
|
220
|
-
entrypointIsDirectory = Boolean(resolved.entrypoint?.isDirectory);
|
|
221
|
-
}
|
|
222
|
-
const entrypointFile = entrypointIsDirectory || !normalizedEntrypoint ? void 0 : normalizedEntrypoint;
|
|
223
|
-
let inferredRuntime = (0, import_utils.inferServiceRuntime)({
|
|
224
|
-
runtime: config.runtime,
|
|
225
|
-
framework: config.framework,
|
|
226
|
-
entrypoint: entrypointFile
|
|
227
|
-
});
|
|
228
|
-
let framework = config.framework;
|
|
229
|
-
let detectedFramework = false;
|
|
230
|
-
if (!framework) {
|
|
231
|
-
const workspace = entrypointIsDirectory && normalizedEntrypoint ? normalizedEntrypoint : ".";
|
|
232
|
-
const detection = await (0, import_resolve.detectFrameworkFromWorkspace)({
|
|
233
|
-
fs: serviceFs,
|
|
234
|
-
workspace,
|
|
235
|
-
serviceName: name,
|
|
236
|
-
runtime: inferredRuntime
|
|
237
|
-
});
|
|
238
|
-
if (detection.error) {
|
|
239
|
-
return { error: detection.error };
|
|
240
|
-
}
|
|
241
|
-
framework = detection.framework;
|
|
242
|
-
detectedFramework = Boolean(framework);
|
|
243
|
-
inferredRuntime = (0, import_utils.inferServiceRuntime)({
|
|
244
|
-
runtime: config.runtime,
|
|
245
|
-
framework,
|
|
246
|
-
entrypoint: entrypointFile
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
if (entrypointIsDirectory && !framework) {
|
|
250
|
-
return {
|
|
251
|
-
error: {
|
|
252
|
-
code: "MISSING_SERVICE_FRAMEWORK",
|
|
253
|
-
message: `Service "${name}" uses directory entrypoint "${config.entrypoint}" but no framework could be detected. Specify "framework" explicitly or use a file entrypoint.`,
|
|
254
|
-
serviceName: name
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
const frameworkRuntime = (0, import_utils.inferRuntimeFromFramework)(framework);
|
|
259
|
-
if (detectedFramework && frameworkRuntime && !entrypointFile) {
|
|
260
|
-
return {
|
|
261
|
-
error: {
|
|
262
|
-
code: "MISSING_SERVICE_CONFIG",
|
|
263
|
-
message: `Service "${name}" detected framework "${framework}" in "${normalizedRoot}" and must specify an "entrypoint" for runtime "${frameworkRuntime}".`,
|
|
264
|
-
serviceName: name
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
const frameworkDefinition = framework ? frameworksBySlug.get(framework) : void 0;
|
|
269
|
-
let builderUse;
|
|
270
|
-
let builderSrc;
|
|
271
|
-
if (framework) {
|
|
272
|
-
builderUse = (0, import_build_utils.isNodeBackendFramework)(framework) ? "@vercel/backends" : frameworkDefinition?.useRuntime?.use || "@vercel/static-build";
|
|
273
|
-
builderSrc = entrypointFile || frameworkDefinition?.useRuntime?.src || "package.json";
|
|
274
|
-
} else {
|
|
275
|
-
if (!inferredRuntime) {
|
|
276
|
-
if (config.buildCommand) {
|
|
277
|
-
builderUse = "@vercel/static-build";
|
|
278
|
-
builderSrc = "package.json";
|
|
279
|
-
} else {
|
|
280
|
-
builderUse = "@vercel/static";
|
|
281
|
-
builderSrc = config.outputDirectory ? import_path.posix.join(config.outputDirectory, "**") : "**";
|
|
282
|
-
}
|
|
283
|
-
} else {
|
|
284
|
-
if (!entrypointFile) {
|
|
285
|
-
return {
|
|
286
|
-
error: {
|
|
287
|
-
code: "MISSING_SERVICE_CONFIG",
|
|
288
|
-
message: `Service "${name}" must specify an "entrypoint" for runtime "${inferredRuntime}".`,
|
|
289
|
-
serviceName: name
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
builderUse = inferredRuntime === "node" ? "@vercel/backends" : (0, import_utils.getBuilderForRuntime)(inferredRuntime);
|
|
294
|
-
builderSrc = entrypointFile;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
const isRoot = normalizedRoot === ".";
|
|
298
|
-
const projectRelativeSrc = isRoot ? builderSrc : import_path.posix.join(normalizedRoot, builderSrc);
|
|
299
|
-
const builderConfig = { zeroConfig: true };
|
|
300
|
-
if (builderUse === "@vercel/backends") {
|
|
301
|
-
builderConfig.serviceName = name;
|
|
302
|
-
}
|
|
303
|
-
if (framework) {
|
|
304
|
-
builderConfig.framework = framework;
|
|
305
|
-
}
|
|
306
|
-
if (config.outputDirectory) {
|
|
307
|
-
builderConfig.outputDirectory = config.outputDirectory;
|
|
308
|
-
}
|
|
309
|
-
if (!isRoot) {
|
|
310
|
-
builderConfig.workspace = normalizedRoot;
|
|
311
|
-
}
|
|
312
|
-
if (moduleAttr) {
|
|
313
|
-
builderConfig.handlerFunction = moduleAttr.attrName;
|
|
314
|
-
}
|
|
315
|
-
const runtime = import_types.STATIC_BUILDERS.has(builderUse) ? void 0 : inferredRuntime;
|
|
316
|
-
return {
|
|
317
|
-
service: {
|
|
318
|
-
schema: "experimentalServicesV2",
|
|
319
|
-
name,
|
|
320
|
-
root: normalizedRoot,
|
|
321
|
-
framework,
|
|
322
|
-
runtime,
|
|
323
|
-
entrypoint: entrypointFile,
|
|
324
|
-
builder: {
|
|
325
|
-
src: projectRelativeSrc,
|
|
326
|
-
use: builderUse,
|
|
327
|
-
config: builderConfig
|
|
328
|
-
},
|
|
329
|
-
installCommand: config.installCommand,
|
|
330
|
-
buildCommand: config.buildCommand,
|
|
331
|
-
devCommand: config.devCommand,
|
|
332
|
-
ignoreCommand: config.ignoreCommand,
|
|
333
|
-
outputDirectory: config.outputDirectory,
|
|
334
|
-
bindings: config.bindings,
|
|
335
|
-
functions: config.functions,
|
|
336
|
-
headers: config.headers,
|
|
337
|
-
redirects: config.redirects,
|
|
338
|
-
rewrites: config.rewrites,
|
|
339
|
-
routes: config.routes,
|
|
340
|
-
cleanUrls: config.cleanUrls,
|
|
341
|
-
trailingSlash: config.trailingSlash
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
async function resolveAllConfiguredServicesV2(services, fs) {
|
|
346
|
-
const resolved = [];
|
|
347
|
-
const errors = [];
|
|
348
|
-
for (const name of Object.keys(services)) {
|
|
349
|
-
const config = services[name];
|
|
350
|
-
const validationError = validateServiceConfigV2(name, config);
|
|
351
|
-
if (validationError) {
|
|
352
|
-
errors.push(validationError);
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
const { service, error } = await resolveConfiguredServiceV2(
|
|
356
|
-
name,
|
|
357
|
-
config,
|
|
358
|
-
fs
|
|
359
|
-
);
|
|
360
|
-
if (error) {
|
|
361
|
-
errors.push(error);
|
|
362
|
-
continue;
|
|
363
|
-
}
|
|
364
|
-
if (service) {
|
|
365
|
-
resolved.push(service);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
const serviceNames = new Set(Object.keys(services));
|
|
369
|
-
for (const service of resolved) {
|
|
370
|
-
for (const binding of service.bindings ?? []) {
|
|
371
|
-
if (!isValidServiceName(binding.service)) {
|
|
372
|
-
errors.push({
|
|
373
|
-
code: "INVALID_SERVICE_BINDING_NAME",
|
|
374
|
-
message: `Service "${service.name}" declares an invalid binding service name "${binding.service}". ${getInvalidServiceNameMessage(binding.service)}`,
|
|
375
|
-
serviceName: service.name
|
|
376
|
-
});
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
if (!serviceNames.has(binding.service)) {
|
|
380
|
-
errors.push({
|
|
381
|
-
code: "UNKNOWN_SERVICE_BINDING",
|
|
382
|
-
message: `Service "${service.name}" declares a binding to unknown service "${binding.service}".`,
|
|
383
|
-
serviceName: service.name
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
return { services: resolved, errors };
|
|
389
|
-
}
|
|
390
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
391
|
-
0 && (module.exports = {
|
|
392
|
-
resolveAllConfiguredServicesV2,
|
|
393
|
-
resolveConfiguredServiceV2,
|
|
394
|
-
validateServiceConfigV2
|
|
395
|
-
});
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { ExperimentalService, ConfiguredServices, ExperimentalServiceConfig, ServiceDetectionError, ServiceRuntime } from './types';
|
|
2
|
-
import type { DetectorFilesystem } from '../detectors/filesystem';
|
|
3
|
-
export declare function parsePyModuleAttrEntrypoint(entrypoint: string): {
|
|
4
|
-
attrName: string;
|
|
5
|
-
filePath: string;
|
|
6
|
-
} | null;
|
|
7
|
-
type ConfiguredServiceConfig = ExperimentalServiceConfig;
|
|
8
|
-
interface ResolvedEntrypointPath {
|
|
9
|
-
normalized: string;
|
|
10
|
-
isDirectory: boolean;
|
|
11
|
-
}
|
|
12
|
-
export declare function getServiceFs(fs: DetectorFilesystem, serviceName: string, root?: string): Promise<{
|
|
13
|
-
fs: DetectorFilesystem;
|
|
14
|
-
error?: ServiceDetectionError;
|
|
15
|
-
}>;
|
|
16
|
-
export declare function resolveEntrypointPath({ fs, serviceName, entrypoint, }: {
|
|
17
|
-
fs: DetectorFilesystem;
|
|
18
|
-
serviceName: string;
|
|
19
|
-
entrypoint: string;
|
|
20
|
-
}): Promise<{
|
|
21
|
-
entrypoint?: ResolvedEntrypointPath;
|
|
22
|
-
error?: ServiceDetectionError;
|
|
23
|
-
}>;
|
|
24
|
-
type RoutePrefixSource = 'configured' | 'generated';
|
|
25
|
-
interface ResolveConfiguredServiceOptions {
|
|
26
|
-
name: string;
|
|
27
|
-
config: ConfiguredServiceConfig;
|
|
28
|
-
/** Filesystem scoped to the service root (via chdir) when root is set, otherwise the project-level fs. */
|
|
29
|
-
serviceFs: DetectorFilesystem;
|
|
30
|
-
root?: string;
|
|
31
|
-
group?: string;
|
|
32
|
-
resolvedEntrypoint?: ResolvedEntrypointPath;
|
|
33
|
-
routePrefixSource?: RoutePrefixSource;
|
|
34
|
-
}
|
|
35
|
-
interface ResolveAllConfiguredServicesOptions {
|
|
36
|
-
requireFileEntrypointForBackendRuntimes?: boolean;
|
|
37
|
-
}
|
|
38
|
-
export declare function inferWorkspaceFromNearestManifest({ fs, entrypoint, runtime, }: {
|
|
39
|
-
fs: DetectorFilesystem;
|
|
40
|
-
entrypoint?: string;
|
|
41
|
-
runtime?: ServiceRuntime;
|
|
42
|
-
}): Promise<string | undefined>;
|
|
43
|
-
export declare function detectFrameworkFromWorkspace({ fs, workspace, serviceName, runtime, }: {
|
|
44
|
-
fs: DetectorFilesystem;
|
|
45
|
-
workspace: string;
|
|
46
|
-
serviceName: string;
|
|
47
|
-
runtime?: ServiceRuntime;
|
|
48
|
-
}): Promise<{
|
|
49
|
-
framework?: string;
|
|
50
|
-
error?: ServiceDetectionError;
|
|
51
|
-
}>;
|
|
52
|
-
/**
|
|
53
|
-
* Validate a service configuration from vercel.json services.
|
|
54
|
-
*/
|
|
55
|
-
export declare function validateServiceConfig(name: string, config: ConfiguredServiceConfig, options?: ResolveAllConfiguredServicesOptions): ServiceDetectionError | null;
|
|
56
|
-
export declare function validateServiceEntrypoint(name: string, config: ConfiguredServiceConfig, resolvedEntrypoint: ResolvedEntrypointPath): ServiceDetectionError | null;
|
|
57
|
-
/**
|
|
58
|
-
* Resolve a single service from user configuration.
|
|
59
|
-
*/
|
|
60
|
-
export declare function resolveConfiguredService(options: ResolveConfiguredServiceOptions): Promise<ExperimentalService>;
|
|
61
|
-
/**
|
|
62
|
-
* Resolve all services from vercel.json services.
|
|
63
|
-
* Validates each service configuration.
|
|
64
|
-
*/
|
|
65
|
-
export declare function resolveAllConfiguredServices(services: ConfiguredServices, fs: DetectorFilesystem, routePrefixSource?: RoutePrefixSource, options?: ResolveAllConfiguredServicesOptions): Promise<{
|
|
66
|
-
services: ExperimentalService[];
|
|
67
|
-
errors: ServiceDetectionError[];
|
|
68
|
-
}>;
|
|
69
|
-
export {};
|