@vercel/client 17.2.30 → 17.2.32

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.
@@ -37,9 +37,10 @@ var import_utils = require("./utils");
37
37
  var import_get_polling_delay = require("./utils/get-polling-delay");
38
38
  var import_ready_state = require("./utils/ready-state");
39
39
  var import_utils2 = require("./utils");
40
- const RETRY_COUNT = 3;
40
+ const RETRY_COUNT = 5;
41
41
  const RETRY_DELAY_MAX_MS = 6e4;
42
42
  const RETRY_DELAY_MIN_MS = 5e3;
43
+ const RETRY_DELAY_SKEW_MS = 3e4;
43
44
  const RETRY_DELAY_DEFAULT_MS = 5e3;
44
45
  function parseRetryAfterMs(response) {
45
46
  if (response.status === 429 || response.status === 503) {
@@ -95,10 +96,11 @@ async function* checkDeploymentStatus(deployment, clientOptions) {
95
96
  }
96
97
  const retryAfterMs = parseRetryAfterMs(deploymentResponse);
97
98
  if (retryAfterMs != null) {
99
+ const randomSkewMs = Math.floor(RETRY_DELAY_SKEW_MS * Math.random());
98
100
  debug(
99
- `Received a transient error or rate limit (HTTP ${deploymentResponse.status}) while querying deployment status, retrying after ${retryAfterMs}ms`
101
+ `Received a transient error or rate limit (HTTP ${deploymentResponse.status}) while querying deployment status, retrying after ${retryAfterMs + randomSkewMs}ms (${retryAfterMs} + ${randomSkewMs}ms of random skew)`
100
102
  );
101
- await (0, import_sleep_promise.default)(retryAfterMs);
103
+ await (0, import_sleep_promise.default)(retryAfterMs + randomSkewMs);
102
104
  continue;
103
105
  }
104
106
  break;
package/dist/types.d.ts CHANGED
@@ -26,6 +26,11 @@ export interface VercelClientOptions {
26
26
  archive?: ArchiveFormat;
27
27
  agent?: Agent;
28
28
  projectName?: string;
29
+ /**
30
+ * Path to a file containing bulk redirects (relative to the project root).
31
+ * This file will be included in prebuilt deployments.
32
+ */
33
+ bulkRedirectsPath?: string | null;
29
34
  }
30
35
  /** @deprecated Use VercelClientOptions instead. */
31
36
  export type NowClientOptions = VercelClientOptions;
@@ -124,6 +129,11 @@ export interface VercelConfig {
124
129
  default5xx?: string;
125
130
  default4xx?: string;
126
131
  };
132
+ /**
133
+ * Path to a file containing bulk redirects (relative to the project root).
134
+ * This file will be included in prebuilt deployments.
135
+ */
136
+ bulkRedirectsPath?: string | null;
127
137
  /**
128
138
  * @experimental This feature is experimental and may change.
129
139
  */
@@ -9,7 +9,7 @@ export type DeploymentEventType = (typeof EVENTS_ARRAY)[number];
9
9
  export declare const EVENTS: Set<"hashes-calculated" | "file-count" | "file-uploaded" | "all-files-uploaded" | "created" | "building" | "ready" | "alias-assigned" | "warning" | "error" | "notice" | "tip" | "canceled" | "checks-registered" | "checks-completed" | "checks-running" | "checks-conclusion-succeeded" | "checks-conclusion-failed" | "checks-conclusion-skipped" | "checks-conclusion-canceled">;
10
10
  export declare function getApiDeploymentsUrl(): string;
11
11
  export declare function parseVercelConfig(filePath?: string): Promise<VercelConfig>;
12
- export declare function buildFileTree(path: string | string[], { isDirectory, prebuilt, vercelOutputDir, rootDirectory, projectName, }: Pick<VercelClientOptions, 'isDirectory' | 'prebuilt' | 'vercelOutputDir' | 'rootDirectory' | 'projectName'>, debug: Debug): Promise<{
12
+ export declare function buildFileTree(path: string | string[], { isDirectory, prebuilt, vercelOutputDir, rootDirectory, projectName, bulkRedirectsPath, }: Pick<VercelClientOptions, 'isDirectory' | 'prebuilt' | 'vercelOutputDir' | 'rootDirectory' | 'projectName' | 'bulkRedirectsPath'>, debug: Debug): Promise<{
13
13
  fileList: string[];
14
14
  ignoreList: string[];
15
15
  }>;
@@ -104,7 +104,8 @@ async function buildFileTree(path, {
104
104
  prebuilt,
105
105
  vercelOutputDir,
106
106
  rootDirectory,
107
- projectName
107
+ projectName,
108
+ bulkRedirectsPath
108
109
  }, debug) {
109
110
  const ignoreList = [];
110
111
  let fileList;
@@ -166,6 +167,37 @@ async function buildFileTree(path, {
166
167
  } catch (e) {
167
168
  debug(`Error checking for .vercel/routes.json: ${e}`);
168
169
  }
170
+ if (prebuilt && bulkRedirectsPath) {
171
+ try {
172
+ const projectRoot = path;
173
+ const bulkRedirectsFullPath = (0, import_path.join)(
174
+ projectRoot,
175
+ rootDirectory || "",
176
+ bulkRedirectsPath
177
+ );
178
+ const relativeFromRoot = (0, import_path.relative)(projectRoot, bulkRedirectsFullPath);
179
+ if (relativeFromRoot.startsWith("..")) {
180
+ debug(
181
+ `Skipping bulk redirects file "${bulkRedirectsPath}" - path traversal detected (resolves outside project root)`
182
+ );
183
+ } else {
184
+ const bulkRedirectsContent = await maybeRead(
185
+ bulkRedirectsFullPath,
186
+ null
187
+ );
188
+ if (bulkRedirectsContent !== null) {
189
+ refs.add(bulkRedirectsFullPath);
190
+ debug(
191
+ `Including bulk redirects file "${bulkRedirectsPath}" in deployment`
192
+ );
193
+ } else {
194
+ debug(`Bulk redirects file "${bulkRedirectsPath}" not found`);
195
+ }
196
+ }
197
+ } catch (e) {
198
+ debug(`Error checking for bulk redirects file: ${e}`);
199
+ }
200
+ }
169
201
  if (refs.size > 0) {
170
202
  fileList = fileList.concat(Array.from(refs));
171
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/client",
3
- "version": "17.2.30",
3
+ "version": "17.2.32",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "homepage": "https://vercel.com",
@@ -42,7 +42,7 @@
42
42
  "querystring": "^0.2.0",
43
43
  "sleep-promise": "8.0.1",
44
44
  "tar-fs": "1.16.3",
45
- "@vercel/build-utils": "13.2.16",
45
+ "@vercel/build-utils": "13.2.17",
46
46
  "@vercel/error-utils": "2.0.3",
47
47
  "@vercel/routing-utils": "5.3.2"
48
48
  },