@vercel/build-utils 13.22.1 → 13.24.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @vercel/build-utils
2
2
 
3
+ ## 13.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d874af6: Add support for env vars injection that reference other services in `services` with an explicit `env` configuration.
8
+
9
+ ## 13.23.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 22f77b9: Add project manifest to node builder.
14
+
15
+ ### Patch Changes
16
+
17
+ - 979d70a: [services] `services` schema support
18
+
3
19
  ## 13.22.1
4
20
 
5
21
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import type { Service } from './types';
1
+ import type { EnvVars, Service } from './types';
2
2
  type Envs = {
3
3
  [key: string]: string | undefined;
4
4
  };
@@ -7,27 +7,49 @@ interface FrameworkInfo {
7
7
  envPrefix?: string;
8
8
  }
9
9
  export interface GetServiceUrlEnvVarsOptions {
10
+ requestedEnv: EnvVars;
11
+ consumerService?: Service;
12
+ services: Service[];
13
+ frameworkList: readonly FrameworkInfo[];
14
+ currentEnv?: Envs;
15
+ deploymentUrl?: string;
16
+ origin?: string;
17
+ }
18
+ export interface GetExperimentalServiceUrlEnvVarsOptions {
10
19
  services: Service[];
11
20
  frameworkList: readonly FrameworkInfo[];
12
21
  currentEnv?: Envs;
13
22
  deploymentUrl?: string;
14
23
  origin?: string;
15
- envPrefix?: string;
16
24
  }
17
25
  /**
18
- * Generate environment variables for service URLs.
26
+ * Resolve a map of declared env-var refs into concrete URL values.
19
27
  *
20
- * For each web service, generates:
21
- * 1. A base env var with the full absolute URL (e.g., BACKEND_URL=https://deploy.vercel.app/api)
22
- * for server-side use.
23
- * 2. Framework-prefixed versions with only the route prefix path
24
- * (e.g., NEXT_PUBLIC_BACKEND_URL=/api, VITE_BACKEND_URL=/api) for client-side use.
25
- * Using relative paths avoids CORS issues since the browser resolves them against
26
- * the current origin, which works correctly across production domains, preview
27
- * deployments, and custom domains.
28
+ * By default the value is the absolute URL of the referenced web service,
29
+ * while if a consumer's framework has an `envPrefix`
30
+ * (e.g. `NEXT_PUBLIC_` or `VITE_`) and the declared name starts with that prefix
31
+ * then the target's route prefix (e.g. `/api`) is used,
32
+ * which useful for client bundles where same-origin requests avoid CORS.
28
33
  *
29
34
  * Environment variables that are already set in `currentEnv` will NOT be overwritten,
30
35
  * allowing user-defined values to take precedence.
31
36
  */
32
37
  export declare function getServiceUrlEnvVars(options: GetServiceUrlEnvVarsOptions): Record<string, string>;
38
+ /**
39
+ * Legacy implicit URL injection used for `experimentalServices` (and
40
+ * auto-detected services that map to the experimentalServices shape).
41
+ *
42
+ * For each web service, generates:
43
+ * 1. `{NAME}_URL` with the absolute URL (server-side use).
44
+ * 2. `{PREFIX}{NAME}_URL` for every framework prefix in `frameworkList` that
45
+ * matches a service in the deployment, with the relative route prefix
46
+ * (client-side use; relative paths avoid CORS).
47
+ *
48
+ * Entries already present in `currentEnv` are not overwritten — user-defined
49
+ * values win.
50
+ *
51
+ * The GA `services` field replaces this with explicit `env` declarations
52
+ * handled by `getServiceUrlEnvVars`.
53
+ */
54
+ export declare function getExperimentalServiceUrlEnvVars(options: GetExperimentalServiceUrlEnvVarsOptions): Record<string, string>;
33
55
  export {};
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var get_service_url_env_vars_exports = {};
20
20
  __export(get_service_url_env_vars_exports, {
21
+ getExperimentalServiceUrlEnvVars: () => getExperimentalServiceUrlEnvVars,
21
22
  getServiceUrlEnvVars: () => getServiceUrlEnvVars
22
23
  });
23
24
  module.exports = __toCommonJS(get_service_url_env_vars_exports);
@@ -44,12 +45,46 @@ function getFrameworkEnvPrefix(frameworkSlug, frameworkList) {
44
45
  }
45
46
  function getServiceUrlEnvVars(options) {
46
47
  const {
48
+ requestedEnv,
49
+ consumerService,
47
50
  services,
48
51
  frameworkList,
49
52
  currentEnv = {},
50
53
  deploymentUrl,
51
- origin,
52
- envPrefix
54
+ origin
55
+ } = options;
56
+ const baseUrl = origin || deploymentUrl;
57
+ if (!baseUrl)
58
+ return {};
59
+ const servicesByName = new Map(services.map((s) => [s.name, s]));
60
+ const consumerEnvPrefix = getFrameworkEnvPrefix(
61
+ consumerService?.framework,
62
+ frameworkList
63
+ );
64
+ const result = {};
65
+ for (const [name, envVar] of Object.entries(requestedEnv)) {
66
+ if (name in currentEnv) {
67
+ continue;
68
+ }
69
+ if (envVar.type !== "service-ref") {
70
+ continue;
71
+ }
72
+ const target = servicesByName.get(envVar.service);
73
+ if (!target || target.type !== "web" || !target.routePrefix) {
74
+ continue;
75
+ }
76
+ const isClientSide = !!consumerEnvPrefix && name.startsWith(consumerEnvPrefix) && name.length > consumerEnvPrefix.length;
77
+ result[name] = isClientSide ? target.routePrefix : computeServiceUrl(baseUrl, target.routePrefix, !!origin);
78
+ }
79
+ return result;
80
+ }
81
+ function getExperimentalServiceUrlEnvVars(options) {
82
+ const {
83
+ services,
84
+ frameworkList,
85
+ currentEnv = {},
86
+ deploymentUrl,
87
+ origin
53
88
  } = options;
54
89
  const baseUrl = origin || deploymentUrl;
55
90
  if (!baseUrl || !services || services.length === 0) {
@@ -73,12 +108,11 @@ function getServiceUrlEnvVars(options) {
73
108
  service.routePrefix,
74
109
  !!origin
75
110
  );
76
- const effectiveBaseEnvVarName = envPrefix ? `${envPrefix}${baseEnvVarName}` : baseEnvVarName;
77
- if (!(effectiveBaseEnvVarName in currentEnv)) {
78
- envVars[effectiveBaseEnvVarName] = absoluteUrl;
111
+ if (!(baseEnvVarName in currentEnv)) {
112
+ envVars[baseEnvVarName] = absoluteUrl;
79
113
  }
80
114
  for (const prefix of frameworkPrefixes) {
81
- const prefixedEnvVarName = envPrefix ? `${prefix}${envPrefix}${baseEnvVarName}` : `${prefix}${baseEnvVarName}`;
115
+ const prefixedEnvVarName = `${prefix}${baseEnvVarName}`;
82
116
  if (!(prefixedEnvVarName in currentEnv)) {
83
117
  envVars[prefixedEnvVarName] = service.routePrefix;
84
118
  }
@@ -88,5 +122,6 @@ function getServiceUrlEnvVars(options) {
88
122
  }
89
123
  // Annotate the CommonJS export names for ESM import in node:
90
124
  0 && (module.exports = {
125
+ getExperimentalServiceUrlEnvVars,
91
126
  getServiceUrlEnvVars
92
127
  });
package/dist/index.d.ts CHANGED
@@ -15,12 +15,12 @@ import debug from './debug';
15
15
  import getIgnoreFilter from './get-ignore-filter';
16
16
  import { getPlatformEnv } from './get-platform-env';
17
17
  import { getPrefixedEnvVars } from './get-prefixed-env-vars';
18
- import { getServiceUrlEnvVars } from './get-service-url-env-vars';
18
+ import { getServiceUrlEnvVars, getExperimentalServiceUrlEnvVars } from './get-service-url-env-vars';
19
19
  import { cloneEnv } from './clone-env';
20
20
  import { hardLinkDir } from './hard-link-dir';
21
21
  import { validateNpmrc } from './validate-npmrc';
22
22
  export type { NodejsLambdaOptions };
23
- export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, downloadFile, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, getNodeBinPaths, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion, detectPackageManager, runNpmInstall, NpmInstallOutput, runBundleInstall, runPipInstall, PipInstallResult, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, getPrefixedEnvVars, getServiceUrlEnvVars, streamToBuffer, streamToBufferChunks, debug, isSymbolicLink, isDirectory, getLambdaOptionsFromFunction, sanitizeConsumerName, scanParentDirs, findPackageJson, getIgnoreFilter, cloneEnv, hardLinkDir, traverseUpDirectories, validateNpmrc, };
23
+ export { FileBlob, FileFsRef, FileRef, Lambda, NodejsLambda, createLambda, Prerender, download, downloadFile, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, getNodeBinPaths, getSupportedNodeVersion, isBunVersion, getSupportedBunVersion, detectPackageManager, runNpmInstall, NpmInstallOutput, runBundleInstall, runPipInstall, PipInstallResult, runShellScript, runCustomInstallCommand, resetCustomInstallCommandSet, getEnvForPackageManager, getNodeVersion, getPathForPackageManager, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, getPlatformEnv, getPrefixedEnvVars, getServiceUrlEnvVars, getExperimentalServiceUrlEnvVars, streamToBuffer, streamToBufferChunks, debug, isSymbolicLink, isDirectory, getLambdaOptionsFromFunction, sanitizeConsumerName, scanParentDirs, findPackageJson, getIgnoreFilter, cloneEnv, hardLinkDir, traverseUpDirectories, validateNpmrc, };
24
24
  export { EdgeFunction } from './edge-function';
25
25
  export { readConfigFile, getPackageJson } from './fs/read-config-file';
26
26
  export { normalizePath } from './fs/normalize-path';
@@ -28,6 +28,7 @@ export { getOsRelease, getProvidedRuntime } from './os';
28
28
  export * from './should-serve';
29
29
  export * from './schemas';
30
30
  export * from './package-manifest';
31
+ export { generateProjectManifest } from './node-diagnostics';
31
32
  export * from './types';
32
33
  export * from './errors';
33
34
  export * from './trace';