@hookflo/tern 3.0.9-beta → 3.0.11-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 +68 -6
- package/package.json +2 -2
package/dist/upstash/queue.js
CHANGED
|
@@ -39,17 +39,79 @@ exports.handleProcess = handleProcess;
|
|
|
39
39
|
exports.handleQueuedRequest = handleQueuedRequest;
|
|
40
40
|
const QStash = __importStar(require("@upstash/qstash"));
|
|
41
41
|
const index_1 = require("../index");
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
async function dynamicImport(modulePath) {
|
|
43
|
+
return new Function('modulePath', 'return import(modulePath);')(modulePath);
|
|
44
|
+
}
|
|
45
|
+
async function loadQStashModules() {
|
|
46
|
+
const optionalImports = await Promise.allSettled([
|
|
47
|
+
dynamicImport('@upstash/qstash'),
|
|
48
|
+
dynamicImport('@upstash/qstash/nextjs'),
|
|
49
|
+
dynamicImport('@upstash/qstash/nuxt'),
|
|
50
|
+
dynamicImport('@upstash/qstash/sveltekit'),
|
|
51
|
+
dynamicImport('@upstash/qstash/cloudflare'),
|
|
52
|
+
]);
|
|
53
|
+
return [
|
|
54
|
+
QStash,
|
|
55
|
+
...optionalImports.flatMap((result) => (result.status === 'fulfilled' ? [result.value] : [])),
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
function resolveModuleExport(modules, key) {
|
|
59
|
+
for (const moduleRef of modules) {
|
|
60
|
+
const directExport = moduleRef[key];
|
|
61
|
+
if (typeof directExport === 'function') {
|
|
62
|
+
return directExport;
|
|
63
|
+
}
|
|
64
|
+
const defaultExport = moduleRef.default?.[key];
|
|
65
|
+
if (typeof defaultExport === 'function') {
|
|
66
|
+
return defaultExport;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
function resolveNestedConstructor(modules, key) {
|
|
72
|
+
const seen = new Set();
|
|
73
|
+
const queue = [...modules];
|
|
74
|
+
while (queue.length) {
|
|
75
|
+
const current = queue.shift();
|
|
76
|
+
if (!current || typeof current !== 'object' || seen.has(current)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
seen.add(current);
|
|
80
|
+
const record = current;
|
|
81
|
+
const candidate = record[key];
|
|
82
|
+
if (typeof candidate === 'function') {
|
|
83
|
+
return candidate;
|
|
84
|
+
}
|
|
85
|
+
for (const value of Object.values(record)) {
|
|
86
|
+
if (value && typeof value === 'object') {
|
|
87
|
+
queue.push(value);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
async function createQStashReceiver(queueConfig) {
|
|
94
|
+
const modules = await loadQStashModules();
|
|
95
|
+
const receiverExport = resolveModuleExport(modules, 'Receiver')
|
|
96
|
+
?? resolveNestedConstructor(modules, 'Receiver');
|
|
45
97
|
if (typeof receiverExport !== 'function') {
|
|
46
|
-
throw new Error('[tern] Incompatible @upstash/qstash version: Receiver export not found.
|
|
98
|
+
throw new Error('[tern] Incompatible @upstash/qstash version: Receiver export not found. Ensure @upstash/qstash is installed and up-to-date.');
|
|
47
99
|
}
|
|
48
100
|
return new receiverExport({
|
|
49
101
|
currentSigningKey: queueConfig.signingKey,
|
|
50
102
|
nextSigningKey: queueConfig.nextSigningKey,
|
|
51
103
|
});
|
|
52
104
|
}
|
|
105
|
+
async function createQStashClient(queueConfig) {
|
|
106
|
+
const modules = await loadQStashModules();
|
|
107
|
+
const clientExport = resolveModuleExport(modules, 'Client');
|
|
108
|
+
const resolvedClientExport = clientExport
|
|
109
|
+
?? resolveNestedConstructor(modules, 'Client');
|
|
110
|
+
if (typeof resolvedClientExport !== 'function') {
|
|
111
|
+
throw new Error('[tern] Incompatible @upstash/qstash version: Client export not found. Ensure @upstash/qstash is installed and up-to-date.');
|
|
112
|
+
}
|
|
113
|
+
return new resolvedClientExport({ token: queueConfig.token });
|
|
114
|
+
}
|
|
53
115
|
function nonRetryableResponse(message, status = 489) {
|
|
54
116
|
return new Response(JSON.stringify({ error: message }), {
|
|
55
117
|
status,
|
|
@@ -76,7 +138,7 @@ async function handleReceive(request, platform, secret, queueConfig, toleranceIn
|
|
|
76
138
|
if (!verificationResult.isValid) {
|
|
77
139
|
return nonRetryableResponse(verificationResult.error || 'Webhook signature verification failed');
|
|
78
140
|
}
|
|
79
|
-
const client =
|
|
141
|
+
const client = await createQStashClient(queueConfig);
|
|
80
142
|
const queuedMessage = {
|
|
81
143
|
platform,
|
|
82
144
|
payload: verificationResult.payload,
|
|
@@ -105,7 +167,7 @@ async function handleProcess(request, handler, queueConfig) {
|
|
|
105
167
|
return new Response(JSON.stringify({ error: 'Missing Upstash-Signature header' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
|
|
106
168
|
}
|
|
107
169
|
const rawBody = await request.text();
|
|
108
|
-
const receiver = createQStashReceiver(queueConfig);
|
|
170
|
+
const receiver = await createQStashReceiver(queueConfig);
|
|
109
171
|
try {
|
|
110
172
|
const verification = await receiver.verify({
|
|
111
173
|
signature,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hookflo/tern",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.11-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",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
}
|
|
126
126
|
},
|
|
127
127
|
"peerDependencies": {
|
|
128
|
-
"@upstash/qstash": ">=2.
|
|
128
|
+
"@upstash/qstash": ">=2.9.0"
|
|
129
129
|
},
|
|
130
130
|
"peerDependenciesMeta": {
|
|
131
131
|
"@upstash/qstash": {
|