@vercel/queue 0.0.0-alpha.32 → 0.0.0-alpha.33
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.mts +260 -73
- package/dist/index.d.ts +260 -73
- package/dist/index.js +308 -245
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +307 -245
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs-pages.d.mts +1 -1
- package/dist/nextjs-pages.d.ts +1 -1
- package/dist/nextjs-pages.js +126 -118
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +126 -118
- package/dist/nextjs-pages.mjs.map +1 -1
- package/dist/{types-JvOenjfT.d.mts → types-Dw29Fr9y.d.mts} +126 -2
- package/dist/{types-JvOenjfT.d.ts → types-Dw29Fr9y.d.ts} +126 -2
- package/package.json +1 -1
package/dist/nextjs-pages.js
CHANGED
|
@@ -100,6 +100,9 @@ var InvalidLimitError = class extends Error {
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
// src/client.ts
|
|
103
|
+
function isDebugEnabled() {
|
|
104
|
+
return process.env.VERCEL_QUEUE_DEBUG === "1" || process.env.VERCEL_QUEUE_DEBUG === "true";
|
|
105
|
+
}
|
|
103
106
|
async function consumeStream(stream) {
|
|
104
107
|
const reader = stream.getReader();
|
|
105
108
|
try {
|
|
@@ -111,6 +114,31 @@ async function consumeStream(stream) {
|
|
|
111
114
|
reader.releaseLock();
|
|
112
115
|
}
|
|
113
116
|
}
|
|
117
|
+
function parseRetryAfter(headers) {
|
|
118
|
+
const retryAfterHeader = headers.get("Retry-After");
|
|
119
|
+
if (retryAfterHeader) {
|
|
120
|
+
const parsed = parseInt(retryAfterHeader, 10);
|
|
121
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
122
|
+
}
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
function throwCommonHttpError(status, statusText, errorText, operation, badRequestDefault = "Invalid parameters") {
|
|
126
|
+
if (status === 400) {
|
|
127
|
+
throw new BadRequestError(errorText || badRequestDefault);
|
|
128
|
+
}
|
|
129
|
+
if (status === 401) {
|
|
130
|
+
throw new UnauthorizedError(errorText || void 0);
|
|
131
|
+
}
|
|
132
|
+
if (status === 403) {
|
|
133
|
+
throw new ForbiddenError(errorText || void 0);
|
|
134
|
+
}
|
|
135
|
+
if (status >= 500) {
|
|
136
|
+
throw new InternalServerError(
|
|
137
|
+
errorText || `Server error: ${status} ${statusText}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`Failed to ${operation}: ${status} ${statusText}`);
|
|
141
|
+
}
|
|
114
142
|
function parseQueueHeaders(headers) {
|
|
115
143
|
const messageId = headers.get("Vqs-Message-Id");
|
|
116
144
|
const deliveryCountStr = headers.get("Vqs-Delivery-Count") || "0";
|
|
@@ -121,7 +149,7 @@ function parseQueueHeaders(headers) {
|
|
|
121
149
|
return null;
|
|
122
150
|
}
|
|
123
151
|
const deliveryCount = parseInt(deliveryCountStr, 10);
|
|
124
|
-
if (isNaN(deliveryCount)) {
|
|
152
|
+
if (Number.isNaN(deliveryCount)) {
|
|
125
153
|
return null;
|
|
126
154
|
}
|
|
127
155
|
return {
|
|
@@ -135,24 +163,22 @@ function parseQueueHeaders(headers) {
|
|
|
135
163
|
var QueueClient = class {
|
|
136
164
|
baseUrl;
|
|
137
165
|
basePath;
|
|
138
|
-
customHeaders
|
|
166
|
+
customHeaders;
|
|
167
|
+
providedToken;
|
|
139
168
|
/**
|
|
140
169
|
* Create a new Vercel Queue Service client
|
|
141
|
-
* @param options
|
|
170
|
+
* @param options QueueClient configuration options
|
|
142
171
|
*/
|
|
143
172
|
constructor(options = {}) {
|
|
144
173
|
this.baseUrl = options.baseUrl || process.env.VERCEL_QUEUE_BASE_URL || "https://vercel-queue.com";
|
|
145
174
|
this.basePath = options.basePath || process.env.VERCEL_QUEUE_BASE_PATH || "/api/v2/messages";
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
Object.entries(process.env).filter(([key]) => key.startsWith(VERCEL_QUEUE_HEADER_PREFIX)).map(([key, value]) => [
|
|
149
|
-
// This allows headers to use dashes independent of shell used
|
|
150
|
-
key.replace(VERCEL_QUEUE_HEADER_PREFIX, "").replaceAll("__", "-"),
|
|
151
|
-
value || ""
|
|
152
|
-
])
|
|
153
|
-
);
|
|
175
|
+
this.customHeaders = options.headers || {};
|
|
176
|
+
this.providedToken = options.token;
|
|
154
177
|
}
|
|
155
178
|
async getToken() {
|
|
179
|
+
if (this.providedToken) {
|
|
180
|
+
return this.providedToken;
|
|
181
|
+
}
|
|
156
182
|
const token = await (0, import_oidc.getVercelOidcToken)();
|
|
157
183
|
if (!token) {
|
|
158
184
|
throw new Error(
|
|
@@ -161,6 +187,45 @@ var QueueClient = class {
|
|
|
161
187
|
}
|
|
162
188
|
return token;
|
|
163
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Internal fetch wrapper that automatically handles debug logging
|
|
192
|
+
* when VERCEL_QUEUE_DEBUG is enabled
|
|
193
|
+
*/
|
|
194
|
+
async fetch(url, init) {
|
|
195
|
+
const method = init.method || "GET";
|
|
196
|
+
if (isDebugEnabled()) {
|
|
197
|
+
const logData = {
|
|
198
|
+
method,
|
|
199
|
+
url,
|
|
200
|
+
headers: init.headers
|
|
201
|
+
};
|
|
202
|
+
const body = init.body;
|
|
203
|
+
if (body !== void 0 && body !== null) {
|
|
204
|
+
if (body instanceof ArrayBuffer) {
|
|
205
|
+
logData.bodySize = body.byteLength;
|
|
206
|
+
} else if (body instanceof Uint8Array) {
|
|
207
|
+
logData.bodySize = body.byteLength;
|
|
208
|
+
} else if (typeof body === "string") {
|
|
209
|
+
logData.bodySize = body.length;
|
|
210
|
+
} else {
|
|
211
|
+
logData.bodyType = typeof body;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
console.debug("[VQS Debug] Request:", JSON.stringify(logData, null, 2));
|
|
215
|
+
}
|
|
216
|
+
const response = await fetch(url, init);
|
|
217
|
+
if (isDebugEnabled()) {
|
|
218
|
+
const logData = {
|
|
219
|
+
method,
|
|
220
|
+
url,
|
|
221
|
+
status: response.status,
|
|
222
|
+
statusText: response.statusText,
|
|
223
|
+
headers: response.headers
|
|
224
|
+
};
|
|
225
|
+
console.debug("[VQS Debug] Response:", JSON.stringify(logData, null, 2));
|
|
226
|
+
}
|
|
227
|
+
return response;
|
|
228
|
+
}
|
|
164
229
|
/**
|
|
165
230
|
* Send a message to a queue
|
|
166
231
|
* @param options Send message options
|
|
@@ -190,32 +255,21 @@ var QueueClient = class {
|
|
|
190
255
|
headers.set("Vqs-Retention-Seconds", retentionSeconds.toString());
|
|
191
256
|
}
|
|
192
257
|
const body = transport.serialize(payload);
|
|
193
|
-
const response = await fetch(`${this.baseUrl}${this.basePath}`, {
|
|
258
|
+
const response = await this.fetch(`${this.baseUrl}${this.basePath}`, {
|
|
194
259
|
method: "POST",
|
|
195
260
|
body,
|
|
196
261
|
headers
|
|
197
262
|
});
|
|
198
263
|
if (!response.ok) {
|
|
199
|
-
|
|
200
|
-
const errorText = await response.text();
|
|
201
|
-
throw new BadRequestError(errorText || "Invalid parameters");
|
|
202
|
-
}
|
|
203
|
-
if (response.status === 401) {
|
|
204
|
-
throw new UnauthorizedError();
|
|
205
|
-
}
|
|
206
|
-
if (response.status === 403) {
|
|
207
|
-
throw new ForbiddenError();
|
|
208
|
-
}
|
|
264
|
+
const errorText = await response.text();
|
|
209
265
|
if (response.status === 409) {
|
|
210
266
|
throw new Error("Duplicate idempotency key detected");
|
|
211
267
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
throw new Error(
|
|
218
|
-
`Failed to send message: ${response.status} ${response.statusText}`
|
|
268
|
+
throwCommonHttpError(
|
|
269
|
+
response.status,
|
|
270
|
+
response.statusText,
|
|
271
|
+
errorText,
|
|
272
|
+
"send message"
|
|
219
273
|
);
|
|
220
274
|
}
|
|
221
275
|
const responseData = await response.json();
|
|
@@ -255,7 +309,7 @@ var QueueClient = class {
|
|
|
255
309
|
if (limit !== void 0) {
|
|
256
310
|
headers.set("Vqs-Limit", limit.toString());
|
|
257
311
|
}
|
|
258
|
-
const response = await fetch(`${this.baseUrl}${this.basePath}`, {
|
|
312
|
+
const response = await this.fetch(`${this.baseUrl}${this.basePath}`, {
|
|
259
313
|
method: "GET",
|
|
260
314
|
headers
|
|
261
315
|
});
|
|
@@ -263,32 +317,18 @@ var QueueClient = class {
|
|
|
263
317
|
throw new QueueEmptyError(queueName, consumerGroup);
|
|
264
318
|
}
|
|
265
319
|
if (!response.ok) {
|
|
266
|
-
|
|
267
|
-
const errorText = await response.text();
|
|
268
|
-
throw new BadRequestError(errorText || "Invalid parameters");
|
|
269
|
-
}
|
|
270
|
-
if (response.status === 401) {
|
|
271
|
-
throw new UnauthorizedError();
|
|
272
|
-
}
|
|
273
|
-
if (response.status === 403) {
|
|
274
|
-
throw new ForbiddenError();
|
|
275
|
-
}
|
|
320
|
+
const errorText = await response.text();
|
|
276
321
|
if (response.status === 423) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const parsed = parseInt(retryAfterHeader, 10);
|
|
281
|
-
retryAfter = isNaN(parsed) ? void 0 : parsed;
|
|
282
|
-
}
|
|
283
|
-
throw new MessageLockedError("next message", retryAfter);
|
|
284
|
-
}
|
|
285
|
-
if (response.status >= 500) {
|
|
286
|
-
throw new InternalServerError(
|
|
287
|
-
`Server error: ${response.status} ${response.statusText}`
|
|
322
|
+
throw new MessageLockedError(
|
|
323
|
+
"next message",
|
|
324
|
+
parseRetryAfter(response.headers)
|
|
288
325
|
);
|
|
289
326
|
}
|
|
290
|
-
|
|
291
|
-
|
|
327
|
+
throwCommonHttpError(
|
|
328
|
+
response.status,
|
|
329
|
+
response.statusText,
|
|
330
|
+
errorText,
|
|
331
|
+
"receive messages"
|
|
292
332
|
);
|
|
293
333
|
}
|
|
294
334
|
for await (const multipartMessage of (0, import_mixpart.parseMultipartStream)(response)) {
|
|
@@ -337,7 +377,7 @@ var QueueClient = class {
|
|
|
337
377
|
if (skipPayload) {
|
|
338
378
|
headers.set("Vqs-Skip-Payload", "1");
|
|
339
379
|
}
|
|
340
|
-
const response = await fetch(
|
|
380
|
+
const response = await this.fetch(
|
|
341
381
|
`${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`,
|
|
342
382
|
{
|
|
343
383
|
method: "GET",
|
|
@@ -345,38 +385,24 @@ var QueueClient = class {
|
|
|
345
385
|
}
|
|
346
386
|
);
|
|
347
387
|
if (!response.ok) {
|
|
348
|
-
|
|
349
|
-
const errorText = await response.text();
|
|
350
|
-
throw new BadRequestError(errorText || "Invalid parameters");
|
|
351
|
-
}
|
|
352
|
-
if (response.status === 401) {
|
|
353
|
-
throw new UnauthorizedError();
|
|
354
|
-
}
|
|
355
|
-
if (response.status === 403) {
|
|
356
|
-
throw new ForbiddenError();
|
|
357
|
-
}
|
|
388
|
+
const errorText = await response.text();
|
|
358
389
|
if (response.status === 404) {
|
|
359
390
|
throw new MessageNotFoundError(messageId);
|
|
360
391
|
}
|
|
361
|
-
if (response.status === 423) {
|
|
362
|
-
const retryAfterHeader = response.headers.get("Retry-After");
|
|
363
|
-
let retryAfter;
|
|
364
|
-
if (retryAfterHeader) {
|
|
365
|
-
const parsed = parseInt(retryAfterHeader, 10);
|
|
366
|
-
retryAfter = isNaN(parsed) ? void 0 : parsed;
|
|
367
|
-
}
|
|
368
|
-
throw new MessageLockedError(messageId, retryAfter);
|
|
369
|
-
}
|
|
370
392
|
if (response.status === 409) {
|
|
371
393
|
throw new MessageNotAvailableError(messageId);
|
|
372
394
|
}
|
|
373
|
-
if (response.status
|
|
374
|
-
throw new
|
|
375
|
-
|
|
395
|
+
if (response.status === 423) {
|
|
396
|
+
throw new MessageLockedError(
|
|
397
|
+
messageId,
|
|
398
|
+
parseRetryAfter(response.headers)
|
|
376
399
|
);
|
|
377
400
|
}
|
|
378
|
-
|
|
379
|
-
|
|
401
|
+
throwCommonHttpError(
|
|
402
|
+
response.status,
|
|
403
|
+
response.statusText,
|
|
404
|
+
errorText,
|
|
405
|
+
"receive message by ID"
|
|
380
406
|
);
|
|
381
407
|
}
|
|
382
408
|
if (skipPayload && response.status === 204) {
|
|
@@ -446,7 +472,7 @@ var QueueClient = class {
|
|
|
446
472
|
*/
|
|
447
473
|
async deleteMessage(options) {
|
|
448
474
|
const { queueName, consumerGroup, messageId, ticket } = options;
|
|
449
|
-
const response = await fetch(
|
|
475
|
+
const response = await this.fetch(
|
|
450
476
|
`${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`,
|
|
451
477
|
{
|
|
452
478
|
method: "DELETE",
|
|
@@ -460,31 +486,22 @@ var QueueClient = class {
|
|
|
460
486
|
}
|
|
461
487
|
);
|
|
462
488
|
if (!response.ok) {
|
|
463
|
-
|
|
464
|
-
throw new BadRequestError("Missing or invalid ticket");
|
|
465
|
-
}
|
|
466
|
-
if (response.status === 401) {
|
|
467
|
-
throw new UnauthorizedError();
|
|
468
|
-
}
|
|
469
|
-
if (response.status === 403) {
|
|
470
|
-
throw new ForbiddenError();
|
|
471
|
-
}
|
|
489
|
+
const errorText = await response.text();
|
|
472
490
|
if (response.status === 404) {
|
|
473
491
|
throw new MessageNotFoundError(messageId);
|
|
474
492
|
}
|
|
475
493
|
if (response.status === 409) {
|
|
476
494
|
throw new MessageNotAvailableError(
|
|
477
495
|
messageId,
|
|
478
|
-
"Invalid ticket, message not in correct state, or already processed"
|
|
496
|
+
errorText || "Invalid ticket, message not in correct state, or already processed"
|
|
479
497
|
);
|
|
480
498
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
`Failed to delete message: ${response.status} ${response.statusText}`
|
|
499
|
+
throwCommonHttpError(
|
|
500
|
+
response.status,
|
|
501
|
+
response.statusText,
|
|
502
|
+
errorText,
|
|
503
|
+
"delete message",
|
|
504
|
+
"Missing or invalid ticket"
|
|
488
505
|
);
|
|
489
506
|
}
|
|
490
507
|
return { deleted: true };
|
|
@@ -508,7 +525,7 @@ var QueueClient = class {
|
|
|
508
525
|
ticket,
|
|
509
526
|
visibilityTimeoutSeconds
|
|
510
527
|
} = options;
|
|
511
|
-
const response = await fetch(
|
|
528
|
+
const response = await this.fetch(
|
|
512
529
|
`${this.baseUrl}${this.basePath}/${encodeURIComponent(messageId)}`,
|
|
513
530
|
{
|
|
514
531
|
method: "PATCH",
|
|
@@ -523,33 +540,22 @@ var QueueClient = class {
|
|
|
523
540
|
}
|
|
524
541
|
);
|
|
525
542
|
if (!response.ok) {
|
|
526
|
-
|
|
527
|
-
throw new BadRequestError(
|
|
528
|
-
"Missing ticket or invalid visibility timeout"
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
if (response.status === 401) {
|
|
532
|
-
throw new UnauthorizedError();
|
|
533
|
-
}
|
|
534
|
-
if (response.status === 403) {
|
|
535
|
-
throw new ForbiddenError();
|
|
536
|
-
}
|
|
543
|
+
const errorText = await response.text();
|
|
537
544
|
if (response.status === 404) {
|
|
538
545
|
throw new MessageNotFoundError(messageId);
|
|
539
546
|
}
|
|
540
547
|
if (response.status === 409) {
|
|
541
548
|
throw new MessageNotAvailableError(
|
|
542
549
|
messageId,
|
|
543
|
-
"Invalid ticket, message not in correct state, or already processed"
|
|
550
|
+
errorText || "Invalid ticket, message not in correct state, or already processed"
|
|
544
551
|
);
|
|
545
552
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
`Failed to change visibility: ${response.status} ${response.statusText}`
|
|
553
|
+
throwCommonHttpError(
|
|
554
|
+
response.status,
|
|
555
|
+
response.statusText,
|
|
556
|
+
errorText,
|
|
557
|
+
"change visibility",
|
|
558
|
+
"Missing ticket or invalid visibility timeout"
|
|
553
559
|
);
|
|
554
560
|
}
|
|
555
561
|
return { updated: true };
|
|
@@ -1123,7 +1129,7 @@ async function parseCallback(request) {
|
|
|
1123
1129
|
messageId
|
|
1124
1130
|
};
|
|
1125
1131
|
}
|
|
1126
|
-
function
|
|
1132
|
+
function createCallbackHandler(handlers, client) {
|
|
1127
1133
|
for (const topicPattern in handlers) {
|
|
1128
1134
|
if (topicPattern.includes("*")) {
|
|
1129
1135
|
if (!validateWildcardPattern(topicPattern)) {
|
|
@@ -1158,7 +1164,6 @@ function handleCallback(handlers) {
|
|
|
1158
1164
|
{ status: 404 }
|
|
1159
1165
|
);
|
|
1160
1166
|
}
|
|
1161
|
-
const client = new QueueClient();
|
|
1162
1167
|
const topic = new Topic(client, queueName);
|
|
1163
1168
|
const cg = topic.consumerGroup(consumerGroup);
|
|
1164
1169
|
await cg.consume(consumerGroupHandler, { messageId });
|
|
@@ -1179,6 +1184,9 @@ function handleCallback(handlers) {
|
|
|
1179
1184
|
}
|
|
1180
1185
|
return routeHandler;
|
|
1181
1186
|
}
|
|
1187
|
+
function handleCallback(handlers, client) {
|
|
1188
|
+
return createCallbackHandler(handlers, client || new QueueClient());
|
|
1189
|
+
}
|
|
1182
1190
|
|
|
1183
1191
|
// src/nextjs-pages.ts
|
|
1184
1192
|
function getHeader(headers, name) {
|