@vercel/client 17.6.3 → 17.6.5
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/check-deployment-status.js +187 -92
- package/dist/types.d.ts +24 -2
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +7 -4
- package/package.json +4 -4
|
@@ -42,6 +42,36 @@ const RETRY_DELAY_MAX_MS = 6e4;
|
|
|
42
42
|
const RETRY_DELAY_MIN_MS = 5e3;
|
|
43
43
|
const RETRY_DELAY_SKEW_MS = 3e4;
|
|
44
44
|
const RETRY_DELAY_DEFAULT_MS = 5e3;
|
|
45
|
+
function getAliasAssignedEvent(signal, deploymentId) {
|
|
46
|
+
if (!signal?.aborted)
|
|
47
|
+
return;
|
|
48
|
+
const event = signal.reason;
|
|
49
|
+
if (event?.type === "alias-assigned" && event.deploymentId === deploymentId && typeof event.date === "number" && Array.isArray(event.alias) && "aliasError" in event && "aliasWarning" in event) {
|
|
50
|
+
return event;
|
|
51
|
+
}
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
async function sleepUntilAliasAssigned(duration, signal, deploymentId) {
|
|
55
|
+
if (getAliasAssignedEvent(signal, deploymentId))
|
|
56
|
+
return;
|
|
57
|
+
if (!signal || signal.aborted) {
|
|
58
|
+
await (0, import_sleep_promise.default)(duration);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
await new Promise((resolve) => {
|
|
62
|
+
const timeout = setTimeout(finish, duration);
|
|
63
|
+
function finish() {
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
signal?.removeEventListener("abort", onAbort);
|
|
66
|
+
resolve();
|
|
67
|
+
}
|
|
68
|
+
function onAbort() {
|
|
69
|
+
if (getAliasAssignedEvent(signal, deploymentId))
|
|
70
|
+
finish();
|
|
71
|
+
}
|
|
72
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
45
75
|
function parseRetryAfterMs(response) {
|
|
46
76
|
if (response.status === 429 || response.status === 503) {
|
|
47
77
|
let header = response.headers.get("Retry-After");
|
|
@@ -71,6 +101,8 @@ async function* checkDeploymentStatus(deployment, clientOptions) {
|
|
|
71
101
|
const { token, teamId, apiUrl, userAgent } = clientOptions;
|
|
72
102
|
const debug = (0, import_utils2.createDebug)(clientOptions.debug);
|
|
73
103
|
let deploymentState = deployment;
|
|
104
|
+
const deploymentId = deployment.id || deployment.deploymentId;
|
|
105
|
+
let aliasAssignedSignal = clientOptions.aliasAssignedSignal;
|
|
74
106
|
const apiDeployments = (0, import_utils.getApiDeploymentsUrl)();
|
|
75
107
|
if ((0, import_ready_state.isDone)(deploymentState) && (0, import_ready_state.isAliasAssigned)(deploymentState)) {
|
|
76
108
|
debug(
|
|
@@ -81,109 +113,172 @@ async function* checkDeploymentStatus(deployment, clientOptions) {
|
|
|
81
113
|
debug("Waiting for builds and the deployment to complete...");
|
|
82
114
|
const finishedEvents = /* @__PURE__ */ new Set();
|
|
83
115
|
const startTime = Date.now();
|
|
84
|
-
|
|
85
|
-
let deploymentResponse;
|
|
86
|
-
let retriesLeft = RETRY_COUNT;
|
|
116
|
+
polling:
|
|
87
117
|
while (true) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
{ apiUrl, userAgent, agent: clientOptions.agent }
|
|
118
|
+
const aliasAssignedEvent = getAliasAssignedEvent(
|
|
119
|
+
aliasAssignedSignal,
|
|
120
|
+
deploymentId
|
|
92
121
|
);
|
|
93
|
-
|
|
94
|
-
|
|
122
|
+
if (aliasAssignedEvent) {
|
|
123
|
+
deploymentState = {
|
|
124
|
+
...deploymentState,
|
|
125
|
+
readyState: "READY",
|
|
126
|
+
aliasAssigned: aliasAssignedEvent.date,
|
|
127
|
+
alias: aliasAssignedEvent.alias,
|
|
128
|
+
aliasError: aliasAssignedEvent.aliasError,
|
|
129
|
+
aliasWarning: aliasAssignedEvent.aliasWarning
|
|
130
|
+
};
|
|
131
|
+
if (!finishedEvents.has("ready")) {
|
|
132
|
+
debug("Deployment state changed to READY");
|
|
133
|
+
finishedEvents.add("ready");
|
|
134
|
+
yield { type: "ready", payload: deploymentState };
|
|
135
|
+
}
|
|
136
|
+
debug("Deployment alias assigned from event stream");
|
|
137
|
+
return yield { type: "alias-assigned", payload: deploymentState };
|
|
138
|
+
}
|
|
139
|
+
let deploymentResponse;
|
|
140
|
+
let retriesLeft = RETRY_COUNT;
|
|
141
|
+
while (true) {
|
|
142
|
+
try {
|
|
143
|
+
deploymentResponse = await (0, import_utils.fetchApi)(
|
|
144
|
+
`${apiDeployments}/${deploymentId}${teamId ? `?teamId=${teamId}` : ""}`,
|
|
145
|
+
token,
|
|
146
|
+
{
|
|
147
|
+
apiUrl,
|
|
148
|
+
userAgent,
|
|
149
|
+
agent: clientOptions.agent,
|
|
150
|
+
// node-fetch's bundled AbortSignal type predates the native one.
|
|
151
|
+
signal: aliasAssignedSignal
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (getAliasAssignedEvent(aliasAssignedSignal, deploymentId)) {
|
|
156
|
+
continue polling;
|
|
157
|
+
}
|
|
158
|
+
if (aliasAssignedSignal?.aborted) {
|
|
159
|
+
aliasAssignedSignal = void 0;
|
|
160
|
+
continue polling;
|
|
161
|
+
}
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
if (getAliasAssignedEvent(aliasAssignedSignal, deploymentId)) {
|
|
165
|
+
continue polling;
|
|
166
|
+
}
|
|
167
|
+
retriesLeft--;
|
|
168
|
+
if (retriesLeft == 0) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
const retryAfterMs = parseRetryAfterMs(deploymentResponse);
|
|
172
|
+
if (retryAfterMs != null) {
|
|
173
|
+
const randomSkewMs = Math.floor(RETRY_DELAY_SKEW_MS * Math.random());
|
|
174
|
+
debug(
|
|
175
|
+
`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)`
|
|
176
|
+
);
|
|
177
|
+
await sleepUntilAliasAssigned(
|
|
178
|
+
retryAfterMs + randomSkewMs,
|
|
179
|
+
aliasAssignedSignal,
|
|
180
|
+
deploymentId
|
|
181
|
+
);
|
|
182
|
+
if (getAliasAssignedEvent(aliasAssignedSignal, deploymentId)) {
|
|
183
|
+
continue polling;
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
95
187
|
break;
|
|
96
188
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
189
|
+
let deploymentUpdate;
|
|
190
|
+
try {
|
|
191
|
+
deploymentUpdate = await deploymentResponse.json();
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (getAliasAssignedEvent(aliasAssignedSignal, deploymentId))
|
|
194
|
+
continue;
|
|
195
|
+
if (aliasAssignedSignal?.aborted) {
|
|
196
|
+
aliasAssignedSignal = void 0;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
if (getAliasAssignedEvent(aliasAssignedSignal, deploymentId))
|
|
104
202
|
continue;
|
|
203
|
+
if (deploymentUpdate.error) {
|
|
204
|
+
debug("Deployment status check has errorred");
|
|
205
|
+
return yield { type: "error", payload: deploymentUpdate.error };
|
|
105
206
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
207
|
+
deploymentState = deploymentUpdate;
|
|
208
|
+
if (deploymentUpdate.readyState === "BUILDING" && !finishedEvents.has("building")) {
|
|
209
|
+
debug("Deployment state changed to BUILDING");
|
|
210
|
+
finishedEvents.add("building");
|
|
211
|
+
yield { type: "building", payload: deploymentUpdate };
|
|
212
|
+
}
|
|
213
|
+
if (deploymentUpdate.readyState === "CANCELED" && !finishedEvents.has("canceled")) {
|
|
214
|
+
debug("Deployment state changed to CANCELED");
|
|
215
|
+
finishedEvents.add("canceled");
|
|
216
|
+
yield { type: "canceled", payload: deploymentUpdate };
|
|
217
|
+
}
|
|
218
|
+
if ((0, import_ready_state.isReady)(deploymentUpdate) && !finishedEvents.has("ready")) {
|
|
219
|
+
debug("Deployment state changed to READY");
|
|
220
|
+
finishedEvents.add("ready");
|
|
221
|
+
yield { type: "ready", payload: deploymentUpdate };
|
|
222
|
+
}
|
|
223
|
+
if (deploymentUpdate.checksState !== void 0) {
|
|
224
|
+
if (deploymentUpdate.checksState === "completed" && !finishedEvents.has("checks-completed")) {
|
|
225
|
+
finishedEvents.add("checks-completed");
|
|
226
|
+
if (deploymentUpdate.checksConclusion === "succeeded") {
|
|
227
|
+
yield {
|
|
228
|
+
type: "checks-conclusion-succeeded",
|
|
229
|
+
payload: deploymentUpdate
|
|
230
|
+
};
|
|
231
|
+
} else if (deploymentUpdate.checksConclusion === "failed") {
|
|
232
|
+
yield { type: "checks-conclusion-failed", payload: deploymentUpdate };
|
|
233
|
+
} else if (deploymentUpdate.checksConclusion === "skipped") {
|
|
234
|
+
yield {
|
|
235
|
+
type: "checks-conclusion-skipped",
|
|
236
|
+
payload: deploymentUpdate
|
|
237
|
+
};
|
|
238
|
+
} else if (deploymentUpdate.checksConclusion === "canceled") {
|
|
239
|
+
yield {
|
|
240
|
+
type: "checks-conclusion-canceled",
|
|
241
|
+
payload: deploymentUpdate
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (deploymentUpdate.checksState === "registered" && !finishedEvents.has("checks-registered")) {
|
|
246
|
+
finishedEvents.add("checks-registered");
|
|
247
|
+
yield { type: "checks-registered", payload: deploymentUpdate };
|
|
248
|
+
}
|
|
249
|
+
if (deploymentUpdate.checksState === "running" && !finishedEvents.has("checks-running")) {
|
|
250
|
+
finishedEvents.add("checks-running");
|
|
251
|
+
yield { type: "checks-running", payload: deploymentUpdate };
|
|
148
252
|
}
|
|
149
253
|
}
|
|
150
|
-
if (deploymentUpdate.
|
|
151
|
-
|
|
152
|
-
|
|
254
|
+
if (deploymentUpdate.checks?.["deployment-alias"]?.state === "failed" && !finishedEvents.has("checks-v2-failed")) {
|
|
255
|
+
debug("v2 deployment-alias check failed");
|
|
256
|
+
finishedEvents.add("checks-v2-failed");
|
|
257
|
+
return yield {
|
|
258
|
+
type: "checks-v2-failed",
|
|
259
|
+
payload: deploymentUpdate
|
|
260
|
+
};
|
|
153
261
|
}
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
yield { type: "
|
|
262
|
+
if ((0, import_ready_state.isAliasAssigned)(deploymentUpdate)) {
|
|
263
|
+
debug("Deployment alias assigned");
|
|
264
|
+
return yield { type: "alias-assigned", payload: deploymentUpdate };
|
|
157
265
|
}
|
|
266
|
+
if ((0, import_ready_state.isAliasError)(deploymentUpdate)) {
|
|
267
|
+
return yield { type: "error", payload: deploymentUpdate.aliasError };
|
|
268
|
+
}
|
|
269
|
+
if (deploymentUpdate.readyState === "ERROR" && deploymentUpdate.errorCode === "BUILD_FAILED") {
|
|
270
|
+
return yield { type: "error", payload: deploymentUpdate };
|
|
271
|
+
}
|
|
272
|
+
if ((0, import_ready_state.isFailed)(deploymentUpdate)) {
|
|
273
|
+
return yield {
|
|
274
|
+
type: "error",
|
|
275
|
+
payload: deploymentUpdate.error || deploymentUpdate
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const elapsed = Date.now() - startTime;
|
|
279
|
+
const duration = (0, import_get_polling_delay.getPollingDelay)(elapsed);
|
|
280
|
+
await sleepUntilAliasAssigned(duration, aliasAssignedSignal, deploymentId);
|
|
158
281
|
}
|
|
159
|
-
if (deploymentUpdate.checks?.["deployment-alias"]?.state === "failed" && !finishedEvents.has("checks-v2-failed")) {
|
|
160
|
-
debug("v2 deployment-alias check failed");
|
|
161
|
-
finishedEvents.add("checks-v2-failed");
|
|
162
|
-
return yield {
|
|
163
|
-
type: "checks-v2-failed",
|
|
164
|
-
payload: deploymentUpdate
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
if ((0, import_ready_state.isAliasAssigned)(deploymentUpdate)) {
|
|
168
|
-
debug("Deployment alias assigned");
|
|
169
|
-
return yield { type: "alias-assigned", payload: deploymentUpdate };
|
|
170
|
-
}
|
|
171
|
-
if ((0, import_ready_state.isAliasError)(deploymentUpdate)) {
|
|
172
|
-
return yield { type: "error", payload: deploymentUpdate.aliasError };
|
|
173
|
-
}
|
|
174
|
-
if (deploymentUpdate.readyState === "ERROR" && deploymentUpdate.errorCode === "BUILD_FAILED") {
|
|
175
|
-
return yield { type: "error", payload: deploymentUpdate };
|
|
176
|
-
}
|
|
177
|
-
if ((0, import_ready_state.isFailed)(deploymentUpdate)) {
|
|
178
|
-
return yield {
|
|
179
|
-
type: "error",
|
|
180
|
-
payload: deploymentUpdate.error || deploymentUpdate
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
const elapsed = Date.now() - startTime;
|
|
184
|
-
const duration = (0, import_get_polling_delay.getPollingDelay)(elapsed);
|
|
185
|
-
await (0, import_sleep_promise.default)(duration);
|
|
186
|
-
}
|
|
187
282
|
}
|
|
188
283
|
// Annotate the CommonJS export names for ESM import in node:
|
|
189
284
|
0 && (module.exports = {
|
package/dist/types.d.ts
CHANGED
|
@@ -7,6 +7,22 @@ export interface Dictionary<T> {
|
|
|
7
7
|
}
|
|
8
8
|
export declare const VALID_ARCHIVE_FORMATS: readonly ["tgz"];
|
|
9
9
|
export type ArchiveFormat = (typeof VALID_ARCHIVE_FORMATS)[number];
|
|
10
|
+
export interface DeploymentAliasError {
|
|
11
|
+
code: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DeploymentAliasWarning extends DeploymentAliasError {
|
|
15
|
+
link?: string;
|
|
16
|
+
action?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DeploymentAliasAssignedEvent {
|
|
19
|
+
type: 'alias-assigned';
|
|
20
|
+
deploymentId: string;
|
|
21
|
+
date: number;
|
|
22
|
+
alias: string[];
|
|
23
|
+
aliasError: DeploymentAliasError | null;
|
|
24
|
+
aliasWarning: DeploymentAliasWarning | null;
|
|
25
|
+
}
|
|
10
26
|
export interface VercelClientOptions {
|
|
11
27
|
token: string;
|
|
12
28
|
path: string | string[];
|
|
@@ -35,6 +51,11 @@ export interface VercelClientOptions {
|
|
|
35
51
|
* that the user later continues the deployment with an API call.
|
|
36
52
|
*/
|
|
37
53
|
manual?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Aborted with a `DeploymentAliasAssignedEvent` when an existing deployment
|
|
56
|
+
* event stream observes alias assignment.
|
|
57
|
+
*/
|
|
58
|
+
aliasAssignedSignal?: AbortSignal;
|
|
38
59
|
}
|
|
39
60
|
/** @deprecated Use VercelClientOptions instead. */
|
|
40
61
|
export type NowClientOptions = VercelClientOptions;
|
|
@@ -73,8 +94,9 @@ export interface Deployment {
|
|
|
73
94
|
};
|
|
74
95
|
target: string;
|
|
75
96
|
alias: string[];
|
|
76
|
-
aliasAssigned: boolean;
|
|
77
|
-
aliasError: string | null;
|
|
97
|
+
aliasAssigned: boolean | number | null;
|
|
98
|
+
aliasError: string | DeploymentAliasError | null;
|
|
99
|
+
aliasWarning?: DeploymentAliasWarning | null;
|
|
78
100
|
checks?: Record<string, {
|
|
79
101
|
state: 'pending' | 'succeeded' | 'failed';
|
|
80
102
|
startedAt?: string;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ type Ignore = ReturnType<typeof ignore>;
|
|
|
6
6
|
export declare const API_FILES = "/v2/files";
|
|
7
7
|
declare const EVENTS_ARRAY: readonly ["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", "checks-v2-failed"];
|
|
8
8
|
export type DeploymentEventType = (typeof EVENTS_ARRAY)[number];
|
|
9
|
-
export declare const EVENTS: Set<"hashes-calculated" | "file-count" | "file-uploaded" | "all-files-uploaded" | "created" | "building" | "ready" | "
|
|
9
|
+
export declare const EVENTS: Set<"alias-assigned" | "hashes-calculated" | "file-count" | "file-uploaded" | "all-files-uploaded" | "created" | "building" | "ready" | "warning" | "error" | "notice" | "tip" | "canceled" | "checks-registered" | "checks-completed" | "checks-running" | "checks-conclusion-succeeded" | "checks-conclusion-failed" | "checks-conclusion-skipped" | "checks-conclusion-canceled" | "checks-v2-failed">;
|
|
10
10
|
export declare function getApiDeploymentsUrl(): string;
|
|
11
11
|
export declare function parseVercelConfig(filePath?: string): Promise<VercelConfig>;
|
|
12
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<{
|
package/dist/utils/index.js
CHANGED
|
@@ -322,10 +322,13 @@ const fetchApi = async (url, token, opts = {}, debugEnabled) => {
|
|
|
322
322
|
};
|
|
323
323
|
debug(`${opts.method || "GET"} ${url}`);
|
|
324
324
|
time = Date.now();
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
325
|
+
try {
|
|
326
|
+
const res = await (0, import_node_fetch.default)(url, opts);
|
|
327
|
+
debug(`DONE in ${Date.now() - time}ms: ${opts.method || "GET"} ${url}`);
|
|
328
|
+
return res;
|
|
329
|
+
} finally {
|
|
330
|
+
semaphore.release();
|
|
331
|
+
}
|
|
329
332
|
};
|
|
330
333
|
const isWin = process.platform.includes("win");
|
|
331
334
|
const prepareFiles = (files, clientOptions) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/client",
|
|
3
|
-
"version": "17.6.
|
|
3
|
+
"version": "17.6.5",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
6
6
|
"homepage": "https://vercel.com",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"querystring": "^0.2.0",
|
|
40
40
|
"sleep-promise": "8.0.1",
|
|
41
41
|
"tar-fs": "1.16.3",
|
|
42
|
-
"@vercel/build-utils": "13.
|
|
43
|
-
"@vercel/
|
|
44
|
-
"@vercel/
|
|
42
|
+
"@vercel/build-utils": "13.33.0",
|
|
43
|
+
"@vercel/error-utils": "2.2.0",
|
|
44
|
+
"@vercel/routing-utils": "6.4.0"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build": "node ../../utils/build.mjs",
|