@hookflo/tern 3.0.5-beta → 3.0.7-beta
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/upstash/queue.js +13 -47
- package/package.json +2 -1
package/dist/upstash/queue.js
CHANGED
|
@@ -4,15 +4,8 @@ exports.resolveQueueConfig = resolveQueueConfig;
|
|
|
4
4
|
exports.handleReceive = handleReceive;
|
|
5
5
|
exports.handleProcess = handleProcess;
|
|
6
6
|
exports.handleQueuedRequest = handleQueuedRequest;
|
|
7
|
+
const qstash_1 = require("@upstash/qstash");
|
|
7
8
|
const index_1 = require("../index");
|
|
8
|
-
function loadQStashModule() {
|
|
9
|
-
try {
|
|
10
|
-
return require('@upstash/qstash');
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
throw new Error('[tern] Queue support requires optional peer dependency "@upstash/qstash". Please install it to use queue mode.');
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
9
|
function nonRetryableResponse(message, status = 489) {
|
|
17
10
|
return new Response(JSON.stringify({ error: message }), {
|
|
18
11
|
status,
|
|
@@ -30,11 +23,7 @@ function resolveQueueConfig(queue) {
|
|
|
30
23
|
if (!token || !signingKey || !nextSigningKey) {
|
|
31
24
|
throw new Error('[tern] queue: true requires QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY in env');
|
|
32
25
|
}
|
|
33
|
-
return {
|
|
34
|
-
token,
|
|
35
|
-
signingKey,
|
|
36
|
-
nextSigningKey,
|
|
37
|
-
};
|
|
26
|
+
return { token, signingKey, nextSigningKey };
|
|
38
27
|
}
|
|
39
28
|
return queue;
|
|
40
29
|
}
|
|
@@ -43,16 +32,15 @@ async function handleReceive(request, platform, secret, queueConfig, toleranceIn
|
|
|
43
32
|
if (!verificationResult.isValid) {
|
|
44
33
|
return nonRetryableResponse(verificationResult.error || 'Webhook signature verification failed');
|
|
45
34
|
}
|
|
46
|
-
const
|
|
47
|
-
const client = new Client({ token: queueConfig.token });
|
|
35
|
+
const client = new qstash_1.Client({ token: queueConfig.token });
|
|
48
36
|
const queuedMessage = {
|
|
49
37
|
platform,
|
|
50
38
|
payload: verificationResult.payload,
|
|
51
39
|
metadata: verificationResult.metadata || {},
|
|
52
40
|
};
|
|
53
|
-
const idempotencyKey = request.headers.get('idempotency-key')
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
const idempotencyKey = request.headers.get('idempotency-key') ||
|
|
42
|
+
request.headers.get('x-webhook-id') ||
|
|
43
|
+
undefined;
|
|
56
44
|
const publishPayload = {
|
|
57
45
|
url: request.url,
|
|
58
46
|
body: queuedMessage,
|
|
@@ -64,22 +52,16 @@ async function handleReceive(request, platform, secret, queueConfig, toleranceIn
|
|
|
64
52
|
await client.publishJSON(publishPayload);
|
|
65
53
|
return new Response(JSON.stringify({ queued: true }), {
|
|
66
54
|
status: 200,
|
|
67
|
-
headers: {
|
|
68
|
-
'Content-Type': 'application/json',
|
|
69
|
-
},
|
|
55
|
+
headers: { 'Content-Type': 'application/json' },
|
|
70
56
|
});
|
|
71
57
|
}
|
|
72
58
|
async function handleProcess(request, handler, queueConfig) {
|
|
73
59
|
const signature = request.headers.get('upstash-signature');
|
|
74
60
|
if (!signature) {
|
|
75
|
-
return new Response(JSON.stringify({ error: 'Missing Upstash-Signature header' }), {
|
|
76
|
-
status: 401,
|
|
77
|
-
headers: { 'Content-Type': 'application/json' },
|
|
78
|
-
});
|
|
61
|
+
return new Response(JSON.stringify({ error: 'Missing Upstash-Signature header' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
|
|
79
62
|
}
|
|
80
63
|
const rawBody = await request.text();
|
|
81
|
-
const
|
|
82
|
-
const receiver = new Receiver({
|
|
64
|
+
const receiver = new qstash_1.Receiver({
|
|
83
65
|
currentSigningKey: queueConfig.signingKey,
|
|
84
66
|
nextSigningKey: queueConfig.nextSigningKey,
|
|
85
67
|
});
|
|
@@ -90,17 +72,11 @@ async function handleProcess(request, handler, queueConfig) {
|
|
|
90
72
|
url: request.url,
|
|
91
73
|
});
|
|
92
74
|
if (verification === false) {
|
|
93
|
-
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
|
|
94
|
-
status: 401,
|
|
95
|
-
headers: { 'Content-Type': 'application/json' },
|
|
96
|
-
});
|
|
75
|
+
return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
|
|
97
76
|
}
|
|
98
77
|
}
|
|
99
78
|
catch {
|
|
100
|
-
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
|
|
101
|
-
status: 401,
|
|
102
|
-
headers: { 'Content-Type': 'application/json' },
|
|
103
|
-
});
|
|
79
|
+
return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
|
|
104
80
|
}
|
|
105
81
|
if (!handler) {
|
|
106
82
|
return nonRetryableResponse('Queue processing requires a handler function');
|
|
@@ -114,20 +90,10 @@ async function handleProcess(request, handler, queueConfig) {
|
|
|
114
90
|
}
|
|
115
91
|
try {
|
|
116
92
|
await handler(parsedBody.payload, parsedBody.metadata || {});
|
|
117
|
-
return new Response(JSON.stringify({ delivered: true }), {
|
|
118
|
-
status: 200,
|
|
119
|
-
headers: {
|
|
120
|
-
'Content-Type': 'application/json',
|
|
121
|
-
},
|
|
122
|
-
});
|
|
93
|
+
return new Response(JSON.stringify({ delivered: true }), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
|
123
94
|
}
|
|
124
95
|
catch (error) {
|
|
125
|
-
return new Response(JSON.stringify({ error: error.message || 'Handler execution failed' }), {
|
|
126
|
-
status: 500,
|
|
127
|
-
headers: {
|
|
128
|
-
'Content-Type': 'application/json',
|
|
129
|
-
},
|
|
130
|
-
});
|
|
96
|
+
return new Response(JSON.stringify({ error: error.message || 'Handler execution failed' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
|
|
131
97
|
}
|
|
132
98
|
}
|
|
133
99
|
async function handleQueuedRequest(request, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hookflo/tern",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7-beta",
|
|
4
4
|
"description": "A robust, scalable webhook verification framework supporting multiple platforms and signature algorithms",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@types/node": "20.0.0",
|
|
51
51
|
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
|
52
52
|
"@typescript-eslint/parser": "^8.39.0",
|
|
53
|
+
"@upstash/qstash": "^2.9.0",
|
|
53
54
|
"eslint": "^8.57.1",
|
|
54
55
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
55
56
|
"eslint-plugin-import": "^2.32.0",
|