@vercel/queue 0.0.0-alpha.6 → 0.0.0-alpha.8
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/README.md +130 -192
- package/dist/index.d.mts +2 -386
- package/dist/index.d.ts +2 -386
- package/dist/index.js +106 -100
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +106 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,75 @@
|
|
|
1
|
+
// src/transports.ts
|
|
2
|
+
var JsonTransport = class {
|
|
3
|
+
contentType = "application/json";
|
|
4
|
+
serialize(value) {
|
|
5
|
+
return Buffer.from(JSON.stringify(value), "utf8");
|
|
6
|
+
}
|
|
7
|
+
async deserialize(stream) {
|
|
8
|
+
const reader = stream.getReader();
|
|
9
|
+
let totalLength = 0;
|
|
10
|
+
const chunks = [];
|
|
11
|
+
try {
|
|
12
|
+
while (true) {
|
|
13
|
+
const { done, value } = await reader.read();
|
|
14
|
+
if (done) break;
|
|
15
|
+
chunks.push(value);
|
|
16
|
+
totalLength += value.length;
|
|
17
|
+
}
|
|
18
|
+
} finally {
|
|
19
|
+
reader.releaseLock();
|
|
20
|
+
}
|
|
21
|
+
const buffer = Buffer.concat(chunks, totalLength);
|
|
22
|
+
return JSON.parse(buffer.toString("utf8"));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var BufferTransport = class {
|
|
26
|
+
contentType = "application/octet-stream";
|
|
27
|
+
serialize(value) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
async deserialize(stream) {
|
|
31
|
+
const reader = stream.getReader();
|
|
32
|
+
const chunks = [];
|
|
33
|
+
try {
|
|
34
|
+
while (true) {
|
|
35
|
+
const { done, value } = await reader.read();
|
|
36
|
+
if (done) break;
|
|
37
|
+
chunks.push(value);
|
|
38
|
+
}
|
|
39
|
+
} finally {
|
|
40
|
+
reader.releaseLock();
|
|
41
|
+
}
|
|
42
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
43
|
+
const buffer = new Uint8Array(totalLength);
|
|
44
|
+
let offset = 0;
|
|
45
|
+
for (const chunk of chunks) {
|
|
46
|
+
buffer.set(chunk, offset);
|
|
47
|
+
offset += chunk.length;
|
|
48
|
+
}
|
|
49
|
+
return Buffer.from(buffer);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var StreamTransport = class {
|
|
53
|
+
contentType = "application/octet-stream";
|
|
54
|
+
serialize(value) {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
async deserialize(stream) {
|
|
58
|
+
return stream;
|
|
59
|
+
}
|
|
60
|
+
async finalize(payload) {
|
|
61
|
+
const reader = payload.getReader();
|
|
62
|
+
try {
|
|
63
|
+
while (true) {
|
|
64
|
+
const { done } = await reader.read();
|
|
65
|
+
if (done) break;
|
|
66
|
+
}
|
|
67
|
+
} finally {
|
|
68
|
+
reader.releaseLock();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
1
73
|
// src/client.ts
|
|
2
74
|
import { parseMultipartStream } from "mixpart";
|
|
3
75
|
|
|
@@ -107,7 +179,7 @@ var QueueClient = class _QueueClient {
|
|
|
107
179
|
baseUrl;
|
|
108
180
|
token;
|
|
109
181
|
/**
|
|
110
|
-
* Internal default instance for use by
|
|
182
|
+
* Internal default instance for use by convenience functions
|
|
111
183
|
* @internal
|
|
112
184
|
*/
|
|
113
185
|
static _defaultInstance = null;
|
|
@@ -543,78 +615,6 @@ var QueueClient = class _QueueClient {
|
|
|
543
615
|
}
|
|
544
616
|
};
|
|
545
617
|
|
|
546
|
-
// src/transports.ts
|
|
547
|
-
var JsonTransport = class {
|
|
548
|
-
contentType = "application/json";
|
|
549
|
-
serialize(value) {
|
|
550
|
-
return Buffer.from(JSON.stringify(value), "utf8");
|
|
551
|
-
}
|
|
552
|
-
async deserialize(stream) {
|
|
553
|
-
const reader = stream.getReader();
|
|
554
|
-
let totalLength = 0;
|
|
555
|
-
const chunks = [];
|
|
556
|
-
try {
|
|
557
|
-
while (true) {
|
|
558
|
-
const { done, value } = await reader.read();
|
|
559
|
-
if (done) break;
|
|
560
|
-
chunks.push(value);
|
|
561
|
-
totalLength += value.length;
|
|
562
|
-
}
|
|
563
|
-
} finally {
|
|
564
|
-
reader.releaseLock();
|
|
565
|
-
}
|
|
566
|
-
const buffer = Buffer.concat(chunks, totalLength);
|
|
567
|
-
return JSON.parse(buffer.toString("utf8"));
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
var BufferTransport = class {
|
|
571
|
-
contentType = "application/octet-stream";
|
|
572
|
-
serialize(value) {
|
|
573
|
-
return value;
|
|
574
|
-
}
|
|
575
|
-
async deserialize(stream) {
|
|
576
|
-
const reader = stream.getReader();
|
|
577
|
-
const chunks = [];
|
|
578
|
-
try {
|
|
579
|
-
while (true) {
|
|
580
|
-
const { done, value } = await reader.read();
|
|
581
|
-
if (done) break;
|
|
582
|
-
chunks.push(value);
|
|
583
|
-
}
|
|
584
|
-
} finally {
|
|
585
|
-
reader.releaseLock();
|
|
586
|
-
}
|
|
587
|
-
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
588
|
-
const buffer = new Uint8Array(totalLength);
|
|
589
|
-
let offset = 0;
|
|
590
|
-
for (const chunk of chunks) {
|
|
591
|
-
buffer.set(chunk, offset);
|
|
592
|
-
offset += chunk.length;
|
|
593
|
-
}
|
|
594
|
-
return Buffer.from(buffer);
|
|
595
|
-
}
|
|
596
|
-
};
|
|
597
|
-
var StreamTransport = class {
|
|
598
|
-
contentType = "application/octet-stream";
|
|
599
|
-
serialize(value) {
|
|
600
|
-
return value;
|
|
601
|
-
}
|
|
602
|
-
async deserialize(stream) {
|
|
603
|
-
return stream;
|
|
604
|
-
}
|
|
605
|
-
async finalize(payload) {
|
|
606
|
-
const reader = payload.getReader();
|
|
607
|
-
try {
|
|
608
|
-
while (true) {
|
|
609
|
-
const { done } = await reader.read();
|
|
610
|
-
if (done) break;
|
|
611
|
-
}
|
|
612
|
-
} finally {
|
|
613
|
-
reader.releaseLock();
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
|
|
618
618
|
// src/consumer-group.ts
|
|
619
619
|
var ConsumerGroup = class {
|
|
620
620
|
client;
|
|
@@ -885,10 +885,6 @@ var Topic = class {
|
|
|
885
885
|
};
|
|
886
886
|
|
|
887
887
|
// src/factory.ts
|
|
888
|
-
function createTopic(topicName, transport) {
|
|
889
|
-
const client = QueueClient._getDefaultInstance();
|
|
890
|
-
return new Topic(client, topicName, transport);
|
|
891
|
-
}
|
|
892
888
|
async function send(topicName, payload, options) {
|
|
893
889
|
const transport = options?.transport || new JsonTransport();
|
|
894
890
|
const client = QueueClient._getDefaultInstance();
|
|
@@ -905,7 +901,8 @@ async function send(topicName, payload, options) {
|
|
|
905
901
|
}
|
|
906
902
|
async function receive(topicName, consumerGroup, handler, options) {
|
|
907
903
|
const transport = options?.transport || new JsonTransport();
|
|
908
|
-
const
|
|
904
|
+
const client = QueueClient._getDefaultInstance();
|
|
905
|
+
const topic = new Topic(client, topicName, transport);
|
|
909
906
|
const { messageId, skipPayload, ...consumerGroupOptions } = options || {};
|
|
910
907
|
const consumer = topic.consumerGroup(consumerGroup, consumerGroupOptions);
|
|
911
908
|
if (messageId) {
|
|
@@ -923,19 +920,38 @@ async function receive(topicName, consumerGroup, handler, options) {
|
|
|
923
920
|
}
|
|
924
921
|
|
|
925
922
|
// src/callback.ts
|
|
926
|
-
function parseCallbackRequest(request) {
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
923
|
+
async function parseCallbackRequest(request) {
|
|
924
|
+
const contentType = request.headers.get("content-type");
|
|
925
|
+
if (!contentType || !contentType.includes("application/cloudevents+json")) {
|
|
926
|
+
throw new Error(
|
|
927
|
+
"Invalid content type: expected 'application/cloudevents+json'"
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
let cloudEvent;
|
|
931
|
+
try {
|
|
932
|
+
cloudEvent = await request.json();
|
|
933
|
+
} catch (error) {
|
|
934
|
+
throw new Error("Failed to parse CloudEvent from request body");
|
|
935
|
+
}
|
|
936
|
+
if (!cloudEvent.type || !cloudEvent.source || !cloudEvent.id || typeof cloudEvent.data !== "object" || cloudEvent.data == null) {
|
|
937
|
+
throw new Error("Invalid CloudEvent: missing required fields");
|
|
938
|
+
}
|
|
939
|
+
if (cloudEvent.type !== "com.vercel.queue.v1beta") {
|
|
940
|
+
throw new Error(
|
|
941
|
+
`Invalid CloudEvent type: expected 'com.vercel.queue.v1beta', got '${cloudEvent.type}'`
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
const missingFields = [];
|
|
945
|
+
if (!("queueName" in cloudEvent.data)) missingFields.push("queueName");
|
|
946
|
+
if (!("consumerGroup" in cloudEvent.data))
|
|
947
|
+
missingFields.push("consumerGroup");
|
|
948
|
+
if (!("messageId" in cloudEvent.data)) missingFields.push("messageId");
|
|
949
|
+
if (missingFields.length > 0) {
|
|
935
950
|
throw new Error(
|
|
936
|
-
`Missing required
|
|
951
|
+
`Missing required CloudEvent data fields: ${missingFields.join(", ")}`
|
|
937
952
|
);
|
|
938
953
|
}
|
|
954
|
+
const { messageId, queueName, consumerGroup } = cloudEvent.data;
|
|
939
955
|
return {
|
|
940
956
|
queueName,
|
|
941
957
|
consumerGroup,
|
|
@@ -945,7 +961,7 @@ function parseCallbackRequest(request) {
|
|
|
945
961
|
function handleCallback(handlers) {
|
|
946
962
|
return async (request) => {
|
|
947
963
|
try {
|
|
948
|
-
const { queueName, consumerGroup, messageId } = parseCallbackRequest(request);
|
|
964
|
+
const { queueName, consumerGroup, messageId } = await parseCallbackRequest(request);
|
|
949
965
|
const topicHandler = handlers[queueName];
|
|
950
966
|
if (!topicHandler) {
|
|
951
967
|
const availableTopics = Object.keys(handlers).join(", ");
|
|
@@ -975,7 +991,7 @@ function handleCallback(handlers) {
|
|
|
975
991
|
return Response.json({ status: "success" });
|
|
976
992
|
} catch (error) {
|
|
977
993
|
console.error("Queue callback error:", error);
|
|
978
|
-
if (error instanceof Error && error.message.includes("Missing required
|
|
994
|
+
if (error instanceof Error && (error.message.includes("Missing required CloudEvent data fields") || error.message.includes("Invalid CloudEvent") || error.message.includes("Invalid CloudEvent type") || error.message.includes("Invalid content type") || error.message.includes("Failed to parse CloudEvent"))) {
|
|
979
995
|
return Response.json({ error: error.message }, { status: 400 });
|
|
980
996
|
}
|
|
981
997
|
return Response.json(
|
|
@@ -988,7 +1004,6 @@ function handleCallback(handlers) {
|
|
|
988
1004
|
export {
|
|
989
1005
|
BadRequestError,
|
|
990
1006
|
BufferTransport,
|
|
991
|
-
ConsumerGroup,
|
|
992
1007
|
ForbiddenError,
|
|
993
1008
|
InternalServerError,
|
|
994
1009
|
InvalidLimitError,
|
|
@@ -997,14 +1012,10 @@ export {
|
|
|
997
1012
|
MessageLockedError,
|
|
998
1013
|
MessageNotAvailableError,
|
|
999
1014
|
MessageNotFoundError,
|
|
1000
|
-
QueueClient,
|
|
1001
1015
|
QueueEmptyError,
|
|
1002
1016
|
StreamTransport,
|
|
1003
|
-
Topic,
|
|
1004
1017
|
UnauthorizedError,
|
|
1005
|
-
createTopic,
|
|
1006
1018
|
handleCallback,
|
|
1007
|
-
parseCallbackRequest,
|
|
1008
1019
|
receive,
|
|
1009
1020
|
send
|
|
1010
1021
|
};
|