@voltro/plugin-webhooks 0.25.0 → 0.27.0
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/CHANGELOG.md +541 -0
- package/dist/index.d.ts +215 -9
- package/dist/index.js +295 -151
- package/dist/mixin.d.ts +48 -0
- package/dist/mixin.js +1 -0
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import { Context as ee, Effect as b, Either as te, Schema as x } from "effect";
|
|
|
6
6
|
import { and as S, eq as C } from "@voltro/database";
|
|
7
7
|
import { assertPublicUrl as w } from "@voltro/integration-http";
|
|
8
8
|
import { publishServerError as ne } from "@voltro/protocol";
|
|
9
|
-
import { createLogger as
|
|
10
|
-
import { Activity as
|
|
9
|
+
import { createLogger as T } from "@voltro/logger";
|
|
10
|
+
import { Activity as E, DurableClock as re, Workflow as ie } from "@effect/workflow";
|
|
11
11
|
//#region src/eventAudience.ts
|
|
12
12
|
var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
13
13
|
let t = e.webhook;
|
|
@@ -39,7 +39,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
39
39
|
502,
|
|
40
40
|
503,
|
|
41
41
|
504
|
|
42
|
-
],
|
|
42
|
+
], se = (e, t, n) => {
|
|
43
43
|
if (t >= e.maxAttempts || n?.status !== void 0 && !(e.retryOn ?? k).includes(n.status)) return null;
|
|
44
44
|
if (e.honourRetryAfter !== !1 && n?.retryAfterSeconds !== void 0) {
|
|
45
45
|
let t = n.retryAfterSeconds * 1e3, r = O(e.maxDelay), i = Math.min(t, r);
|
|
@@ -66,7 +66,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
66
66
|
delayMs: Math.max(1, Math.floor(o)),
|
|
67
67
|
baseDelayMs: a
|
|
68
68
|
};
|
|
69
|
-
},
|
|
69
|
+
}, A = () => ({
|
|
70
70
|
strategy: "exponential",
|
|
71
71
|
maxAttempts: 8,
|
|
72
72
|
initialDelay: "5s",
|
|
@@ -74,7 +74,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
74
74
|
retryOn: k,
|
|
75
75
|
honourRetryAfter: !0,
|
|
76
76
|
jitter: "full"
|
|
77
|
-
}),
|
|
77
|
+
}), ce = () => ({
|
|
78
78
|
strategy: "fixed",
|
|
79
79
|
maxAttempts: 120,
|
|
80
80
|
initialDelay: "30s",
|
|
@@ -82,7 +82,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
82
82
|
retryOn: k,
|
|
83
83
|
honourRetryAfter: !0,
|
|
84
84
|
jitter: "full"
|
|
85
|
-
}),
|
|
85
|
+
}), j = class extends ee.Tag("@voltro/webhooks/WebhooksService")() {}, le = 32, M = 32, N = () => v(le).toString("hex"), P = (e) => e.events ?? (e.event === void 0 ? [] : [e.event]), F = (e) => {
|
|
86
86
|
let t;
|
|
87
87
|
try {
|
|
88
88
|
t = new URL(e.url);
|
|
@@ -104,13 +104,26 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
104
104
|
reason: e.message
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
-
|
|
107
|
+
let n = P(e);
|
|
108
|
+
if (n.length === 0) throw new p({
|
|
108
109
|
field: "event",
|
|
109
110
|
reason: "event id required"
|
|
110
111
|
});
|
|
111
|
-
if (e.
|
|
112
|
+
if (e.event !== void 0 && e.events !== void 0) throw new p({
|
|
113
|
+
field: "event",
|
|
114
|
+
reason: "pass `event` OR `events`, not both — the row set would be ambiguous"
|
|
115
|
+
});
|
|
116
|
+
if (n.some((e) => e.length === 0)) throw new p({
|
|
117
|
+
field: "events",
|
|
118
|
+
reason: "event id required"
|
|
119
|
+
});
|
|
120
|
+
if (new Set(n).size !== n.length) throw new p({
|
|
121
|
+
field: "events",
|
|
122
|
+
reason: "duplicate event — one row per event, so a repeat would deliver twice"
|
|
123
|
+
});
|
|
124
|
+
if (e.secret !== void 0 && e.secret.length < M) throw new p({
|
|
112
125
|
field: "secret",
|
|
113
|
-
reason: `secret must be at least ${
|
|
126
|
+
reason: `secret must be at least ${M} chars`
|
|
114
127
|
});
|
|
115
128
|
if (e.retry !== void 0) {
|
|
116
129
|
if (e.retry.maxAttempts < 1) throw new p({
|
|
@@ -130,14 +143,15 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
130
143
|
field: "autoDisableAfter",
|
|
131
144
|
reason: `autoDisableAfter must be a positive integer, got ${e.autoDisableAfter}`
|
|
132
145
|
});
|
|
133
|
-
}, I = (e, t) => ({
|
|
146
|
+
}, I = (e, t, n, r) => ({
|
|
134
147
|
id: y(),
|
|
135
|
-
event: e.event,
|
|
148
|
+
event: n ?? e.event ?? "",
|
|
136
149
|
url: e.url,
|
|
137
|
-
secret: e.secret ??
|
|
150
|
+
secret: r ?? e.secret ?? N(),
|
|
138
151
|
signing: e.signing ?? t?.defaultSigning ?? c(),
|
|
139
|
-
retry: e.retry ?? t?.defaultRetry ??
|
|
152
|
+
retry: e.retry ?? t?.defaultRetry ?? A(),
|
|
140
153
|
filter: e.filter ?? null,
|
|
154
|
+
scope: e.scope ?? null,
|
|
141
155
|
headers: e.headers ?? null,
|
|
142
156
|
rateLimitPerMinute: e.rateLimitPerMinute ?? null,
|
|
143
157
|
active: !0,
|
|
@@ -148,19 +162,40 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
148
162
|
autoDisableReason: null,
|
|
149
163
|
payloadVersion: e.payloadVersion ?? t?.version ?? 1,
|
|
150
164
|
description: e.description ?? null
|
|
151
|
-
}),
|
|
165
|
+
}), ue = (e) => e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : 0, L = (e) => e instanceof Date ? e.toISOString() : typeof e == "string" ? e : null, de = (e) => {
|
|
166
|
+
if (typeof e != "string") return e;
|
|
167
|
+
try {
|
|
168
|
+
return JSON.parse(e);
|
|
169
|
+
} catch {
|
|
170
|
+
return e;
|
|
171
|
+
}
|
|
172
|
+
}, R = (e) => ({
|
|
173
|
+
id: String(e.id),
|
|
174
|
+
deliveryId: String(e.deliveryId),
|
|
175
|
+
targetId: String(e.targetId),
|
|
176
|
+
event: String(e.event),
|
|
177
|
+
eventId: e.eventId ?? null,
|
|
178
|
+
attempt: Number(e.attempt ?? 0),
|
|
179
|
+
status: e.status,
|
|
180
|
+
responseStatus: e.responseStatus ?? null,
|
|
181
|
+
errorMessage: e.errorMessage ?? null,
|
|
182
|
+
latencyMs: e.latencyMs ?? null,
|
|
183
|
+
scheduledAt: L(e.scheduledAt),
|
|
184
|
+
nextAttemptAt: L(e.nextAttemptAt),
|
|
185
|
+
createdAt: L(e.createdAt)
|
|
186
|
+
}), fe = (e, t) => e === t ? "current" : e < t ? "behind" : "ahead", z = (e, t) => {
|
|
152
187
|
if (e === null) return !0;
|
|
153
188
|
let n = { payload: t };
|
|
154
|
-
for (let [t, r] of Object.entries(e)) if (!
|
|
189
|
+
for (let [t, r] of Object.entries(e)) if (!me(pe(n, t), r)) return !1;
|
|
155
190
|
return !0;
|
|
156
|
-
},
|
|
191
|
+
}, pe = (e, t) => {
|
|
157
192
|
let n = t.split("."), r = e;
|
|
158
193
|
for (let e of n) {
|
|
159
194
|
if (typeof r != "object" || !r) return;
|
|
160
195
|
r = r[e];
|
|
161
196
|
}
|
|
162
197
|
return r;
|
|
163
|
-
},
|
|
198
|
+
}, me = (e, t) => {
|
|
164
199
|
if (typeof t == "object" && t && !Array.isArray(t)) {
|
|
165
200
|
let n = t;
|
|
166
201
|
if ("eq" in n) return e === n.eq;
|
|
@@ -171,23 +206,28 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
171
206
|
if ("in" in n && Array.isArray(n.in)) return n.in.includes(e);
|
|
172
207
|
}
|
|
173
208
|
return e === t;
|
|
174
|
-
},
|
|
175
|
-
let r = new Map((n.events ?? []).map((e) => [e.id, e]))
|
|
176
|
-
return {
|
|
209
|
+
}, he = (e, t, n = {}) => {
|
|
210
|
+
let r = new Map((n.events ?? []).map((e) => [e.id, e])), i = {
|
|
177
211
|
subscribe: async (t) => {
|
|
178
212
|
F(t);
|
|
179
|
-
let n = I(t, r.get(
|
|
180
|
-
|
|
181
|
-
...
|
|
213
|
+
let n = P(t), i = t.secret ?? N(), a = n.map((e) => I(t, r.get(e), e, i));
|
|
214
|
+
for (let t of a) await e.store.insert("_voltro_webhook_targets", {
|
|
215
|
+
...t,
|
|
182
216
|
createdAt: /* @__PURE__ */ new Date(),
|
|
183
217
|
updatedAt: /* @__PURE__ */ new Date()
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
218
|
+
});
|
|
219
|
+
let o = a[0];
|
|
220
|
+
return {
|
|
221
|
+
id: o.id,
|
|
222
|
+
event: o.event,
|
|
223
|
+
url: o.url,
|
|
224
|
+
secret: o.secret,
|
|
225
|
+
signing: o.signing,
|
|
226
|
+
retry: o.retry,
|
|
227
|
+
...a.length > 1 ? { targets: a.map((e) => ({
|
|
228
|
+
id: e.id,
|
|
229
|
+
event: e.event
|
|
230
|
+
})) } : {}
|
|
191
231
|
};
|
|
192
232
|
},
|
|
193
233
|
emit: async (n, i) => {
|
|
@@ -209,7 +249,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
209
249
|
take: 1e3,
|
|
210
250
|
skip: void 0,
|
|
211
251
|
projection: void 0
|
|
212
|
-
})).filter((e) =>
|
|
252
|
+
})).filter((e) => z(e.filter, i)), d = [], f = JSON.stringify(i);
|
|
213
253
|
for (let n of l) {
|
|
214
254
|
let r = y();
|
|
215
255
|
n.active ? (await t({
|
|
@@ -268,49 +308,148 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
268
308
|
attemptEpoch: Date.now()
|
|
269
309
|
});
|
|
270
310
|
},
|
|
311
|
+
resolveTargets: async (t) => {
|
|
312
|
+
if (typeof t == "string") return [t];
|
|
313
|
+
let n = (await e.store.query({
|
|
314
|
+
table: "_voltro_webhook_targets",
|
|
315
|
+
predicate: void 0,
|
|
316
|
+
order: void 0,
|
|
317
|
+
take: 1e3,
|
|
318
|
+
skip: void 0,
|
|
319
|
+
projection: void 0
|
|
320
|
+
})).filter((e) => e.scope !== null && Object.entries(t.scope).every(([t, n]) => e.scope?.[t] === n)).map((e) => e.id);
|
|
321
|
+
if (n.length === 0) throw Error(`webhooks: no target matches scope ${JSON.stringify(t.scope)} — the operation would have silently done nothing`);
|
|
322
|
+
return n;
|
|
323
|
+
},
|
|
271
324
|
pauseTarget: async (t) => {
|
|
272
|
-
await e.store.update("_voltro_webhook_targets",
|
|
325
|
+
for (let n of await i.resolveTargets(t)) await e.store.update("_voltro_webhook_targets", n, {
|
|
273
326
|
active: !1,
|
|
274
327
|
updatedAt: /* @__PURE__ */ new Date()
|
|
275
328
|
});
|
|
276
329
|
},
|
|
277
330
|
resumeTarget: async (n) => {
|
|
278
|
-
await
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
331
|
+
for (let r of await i.resolveTargets(n)) {
|
|
332
|
+
await e.store.update("_voltro_webhook_targets", r, {
|
|
333
|
+
active: !0,
|
|
334
|
+
consecutiveFailures: 0,
|
|
335
|
+
autoDisabledAt: null,
|
|
336
|
+
autoDisableReason: null,
|
|
337
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
338
|
+
});
|
|
339
|
+
let n = await e.store.query({
|
|
340
|
+
table: "_voltro_webhook_deliveries",
|
|
341
|
+
predicate: S(C("targetId", r), C("status", "pending")),
|
|
342
|
+
order: [{
|
|
343
|
+
column: "createdAt",
|
|
344
|
+
direction: "asc"
|
|
345
|
+
}],
|
|
346
|
+
take: 1e4,
|
|
347
|
+
skip: void 0,
|
|
348
|
+
projection: void 0
|
|
349
|
+
}), i = Date.now();
|
|
350
|
+
for (let e of n) await t({
|
|
351
|
+
deliveryId: e.deliveryId,
|
|
352
|
+
targetId: r,
|
|
353
|
+
event: e.event,
|
|
354
|
+
eventId: e.eventId ?? y(),
|
|
355
|
+
payloadJson: typeof e.payload == "string" ? e.payload : JSON.stringify(e.payload),
|
|
356
|
+
attemptEpoch: i
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
deleteTarget: async (t) => {
|
|
361
|
+
for (let n of await i.resolveTargets(t)) await e.store.delete("_voltro_webhook_targets", n), await e.store.deleteMany("_voltro_webhook_deliveries", { where: S(C("targetId", n), C("status", "pending")) });
|
|
362
|
+
},
|
|
363
|
+
rotateSecret: async (t) => {
|
|
364
|
+
let n = N();
|
|
365
|
+
for (let r of await i.resolveTargets(t)) await e.store.update("_voltro_webhook_targets", r, {
|
|
366
|
+
secret: n,
|
|
283
367
|
updatedAt: /* @__PURE__ */ new Date()
|
|
284
368
|
});
|
|
285
|
-
|
|
369
|
+
return { secret: n };
|
|
370
|
+
},
|
|
371
|
+
updateTarget: async (t, n) => {
|
|
372
|
+
if (n.url !== void 0 && F({
|
|
373
|
+
event: "x",
|
|
374
|
+
url: n.url
|
|
375
|
+
}), n.rateLimitPerMinute !== void 0 && n.rateLimitPerMinute !== null && (!Number.isInteger(n.rateLimitPerMinute) || n.rateLimitPerMinute < 1)) throw Error("updateTarget: rateLimitPerMinute must be a positive integer or null");
|
|
376
|
+
let r = { updatedAt: /* @__PURE__ */ new Date() };
|
|
377
|
+
for (let e of [
|
|
378
|
+
"url",
|
|
379
|
+
"description",
|
|
380
|
+
"filter",
|
|
381
|
+
"scope",
|
|
382
|
+
"headers",
|
|
383
|
+
"rateLimitPerMinute",
|
|
384
|
+
"autoDisableAfter",
|
|
385
|
+
"format"
|
|
386
|
+
]) n[e] !== void 0 && (r[e] = n[e]);
|
|
387
|
+
for (let n of await i.resolveTargets(t)) await e.store.update("_voltro_webhook_targets", n, r);
|
|
388
|
+
},
|
|
389
|
+
testTarget: async (n, r) => {
|
|
390
|
+
let i = (await e.store.query({
|
|
391
|
+
table: "_voltro_webhook_targets",
|
|
392
|
+
predicate: C("id", n),
|
|
393
|
+
order: void 0,
|
|
394
|
+
take: 1,
|
|
395
|
+
skip: void 0,
|
|
396
|
+
projection: void 0
|
|
397
|
+
}))[0];
|
|
398
|
+
if (i === void 0) throw Error(`testTarget: no target ${n}`);
|
|
399
|
+
let a = y(), o = JSON.stringify(r ?? {
|
|
400
|
+
test: !0,
|
|
401
|
+
targetId: n,
|
|
402
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
403
|
+
});
|
|
404
|
+
return i.active ? await t({
|
|
405
|
+
deliveryId: a,
|
|
406
|
+
targetId: i.id,
|
|
407
|
+
event: i.event,
|
|
408
|
+
eventId: y(),
|
|
409
|
+
payloadJson: o
|
|
410
|
+
}) : await e.store.insert("_voltro_webhook_deliveries", {
|
|
411
|
+
id: `${a}:1`,
|
|
412
|
+
deliveryId: a,
|
|
413
|
+
targetId: i.id,
|
|
414
|
+
tenantId: i.tenantId ?? null,
|
|
415
|
+
event: i.event,
|
|
416
|
+
eventId: null,
|
|
417
|
+
attempt: 1,
|
|
418
|
+
status: "pending",
|
|
419
|
+
payload: o,
|
|
420
|
+
scheduledAt: /* @__PURE__ */ new Date(),
|
|
421
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
422
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
423
|
+
}), { deliveryId: a };
|
|
424
|
+
},
|
|
425
|
+
listDeliveries: async (t) => {
|
|
426
|
+
let n = t?.scope === void 0 ? void 0 : new Set(await i.resolveTargets({ scope: t.scope })), r = await e.store.query({
|
|
286
427
|
table: "_voltro_webhook_deliveries",
|
|
287
|
-
predicate:
|
|
428
|
+
predicate: t?.targetId === void 0 ? void 0 : C("targetId", t.targetId),
|
|
288
429
|
order: [{
|
|
289
430
|
column: "createdAt",
|
|
290
|
-
direction: "
|
|
431
|
+
direction: "desc"
|
|
291
432
|
}],
|
|
292
|
-
take:
|
|
433
|
+
take: Math.min((t?.limit ?? 200) * (t?.status !== void 0 || t?.since !== void 0 ? 10 : 1), 5e3),
|
|
293
434
|
skip: void 0,
|
|
294
435
|
projection: void 0
|
|
295
|
-
}),
|
|
296
|
-
|
|
297
|
-
deliveryId: e.deliveryId,
|
|
298
|
-
targetId: n,
|
|
299
|
-
event: e.event,
|
|
300
|
-
eventId: e.eventId ?? y(),
|
|
301
|
-
payloadJson: typeof e.payload == "string" ? e.payload : JSON.stringify(e.payload),
|
|
302
|
-
attemptEpoch: i
|
|
303
|
-
});
|
|
436
|
+
}), a = t?.since?.getTime();
|
|
437
|
+
return r.filter((e) => n === void 0 || n.has(String(e.targetId))).filter((e) => t?.status === void 0 || e.status === t.status).filter((e) => a === void 0 || ue(e.createdAt) >= a).slice(0, t?.limit ?? 200).map(R);
|
|
304
438
|
},
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
})
|
|
439
|
+
getDelivery: async (t) => {
|
|
440
|
+
let n = (await e.store.query({
|
|
441
|
+
table: "_voltro_webhook_deliveries",
|
|
442
|
+
predicate: C("id", t),
|
|
443
|
+
order: void 0,
|
|
444
|
+
take: 1,
|
|
445
|
+
skip: void 0,
|
|
446
|
+
projection: void 0
|
|
447
|
+
}))[0];
|
|
448
|
+
return n === void 0 ? null : {
|
|
449
|
+
...R(n),
|
|
450
|
+
payload: de(n.payload),
|
|
451
|
+
responseBody: n.responseBody ?? null
|
|
452
|
+
};
|
|
314
453
|
},
|
|
315
454
|
updateTargetPayloadVersion: async (t, n) => {
|
|
316
455
|
if (n < 1 || !Number.isInteger(n)) throw new f({ version: n });
|
|
@@ -319,39 +458,44 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
319
458
|
updatedAt: /* @__PURE__ */ new Date()
|
|
320
459
|
});
|
|
321
460
|
},
|
|
322
|
-
listTargets: async (t) =>
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
461
|
+
listTargets: async (t, n) => {
|
|
462
|
+
let r = await e.store.query({
|
|
463
|
+
table: "_voltro_webhook_targets",
|
|
464
|
+
predicate: t === void 0 ? void 0 : C("event", t),
|
|
465
|
+
order: [{
|
|
466
|
+
column: "createdAt",
|
|
467
|
+
direction: "desc"
|
|
468
|
+
}],
|
|
469
|
+
take: 500,
|
|
470
|
+
skip: void 0,
|
|
471
|
+
projection: void 0
|
|
472
|
+
});
|
|
473
|
+
return (n === void 0 ? r : r.filter((e) => e.scope !== null && Object.entries(n).every(([t, n]) => e.scope?.[t] === n))).map((e) => ({
|
|
474
|
+
id: e.id,
|
|
475
|
+
event: e.event,
|
|
476
|
+
url: e.url,
|
|
477
|
+
active: e.active,
|
|
478
|
+
rateLimitPerMinute: e.rateLimitPerMinute,
|
|
479
|
+
description: e.description,
|
|
480
|
+
payloadVersion: e.payloadVersion,
|
|
481
|
+
autoDisableAfter: e.autoDisableAfter,
|
|
482
|
+
consecutiveFailures: e.consecutiveFailures ?? 0,
|
|
483
|
+
autoDisabledAt: e.autoDisabledAt === null || e.autoDisabledAt === void 0 ? null : e.autoDisabledAt instanceof Date ? e.autoDisabledAt.toISOString() : String(e.autoDisabledAt),
|
|
484
|
+
autoDisableReason: e.autoDisableReason,
|
|
485
|
+
scope: e.scope
|
|
486
|
+
}));
|
|
487
|
+
}
|
|
345
488
|
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
489
|
+
return i;
|
|
490
|
+
}, ge = b.gen(function* () {
|
|
491
|
+
return yield* j;
|
|
492
|
+
}), _e = (e) => {
|
|
349
493
|
if (e.webhooks === void 0) throw Error("useWebhooks: `ctx.webhooks` is not set. Add @voltro/plugin-webhooks to your app.config.ts plugin list and declare at least one *.webhook.tsx file.");
|
|
350
494
|
return e.webhooks;
|
|
351
|
-
},
|
|
495
|
+
}, ve = 1e4, B = class {
|
|
352
496
|
capacity;
|
|
353
497
|
cache = /* @__PURE__ */ new Map();
|
|
354
|
-
constructor(e =
|
|
498
|
+
constructor(e = ve) {
|
|
355
499
|
this.capacity = e;
|
|
356
500
|
}
|
|
357
501
|
evictExpired() {
|
|
@@ -386,20 +530,20 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
386
530
|
clear() {
|
|
387
531
|
this.cache.clear();
|
|
388
532
|
}
|
|
389
|
-
},
|
|
533
|
+
}, V = null, H = () => (V === null && (V = new B()), V), U = {
|
|
390
534
|
"5m": 5 * 6e4,
|
|
391
535
|
"1h": 60 * 6e4,
|
|
392
536
|
"6h": 360 * 6e4,
|
|
393
537
|
"1d": 1440 * 6e4,
|
|
394
538
|
"7d": 10080 * 6e4,
|
|
395
539
|
"30d": 720 * 60 * 6e4
|
|
396
|
-
},
|
|
540
|
+
}, W = (e) => e === void 0 ? U["7d"] : U[e] ?? U["7d"], G = (e, t) => ({
|
|
397
541
|
status: e,
|
|
398
542
|
contentType: "application/json; charset=utf-8",
|
|
399
543
|
body: JSON.stringify(t)
|
|
400
|
-
}),
|
|
401
|
-
let n = e.provider, r = e.signature ?? n?.signature ?? null, i = e.idempotency ?? n?.idempotency ?? null, o = e.bodyType ?? n?.bodyType ?? "json", s = t.idempotencyCache ??
|
|
402
|
-
|
|
544
|
+
}), ye = (e, t) => {
|
|
545
|
+
let n = e.provider, r = e.signature ?? n?.signature ?? null, i = e.idempotency ?? n?.idempotency ?? null, o = e.bodyType ?? n?.bodyType ?? "json", s = t.idempotencyCache ?? H(), c = W(i?.ttl), l = t.log ?? ((e) => {
|
|
546
|
+
T({ scope: `webhook:${e.webhookId}` }).debug("incoming webhook", {
|
|
403
547
|
status: e.status,
|
|
404
548
|
signatureOk: e.signatureOk,
|
|
405
549
|
idempotency: e.idempotency,
|
|
@@ -410,7 +554,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
410
554
|
return async (n) => {
|
|
411
555
|
let u = Date.now();
|
|
412
556
|
if (n.method !== "POST") {
|
|
413
|
-
let t =
|
|
557
|
+
let t = G(405, {
|
|
414
558
|
error: "method not allowed",
|
|
415
559
|
expected: "POST"
|
|
416
560
|
});
|
|
@@ -431,7 +575,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
431
575
|
r._tag === "custom" && n.headers["x-slack-request-timestamp"] && (o = `${n.headers["x-slack-request-timestamp"]}|${t ?? ""}`);
|
|
432
576
|
let s = a(r, n.rawBody, i, o);
|
|
433
577
|
if (d = s.ok, !s.ok) {
|
|
434
|
-
let t =
|
|
578
|
+
let t = G(401, {
|
|
435
579
|
error: "invalid signature",
|
|
436
580
|
reason: s.reason
|
|
437
581
|
});
|
|
@@ -457,7 +601,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
457
601
|
f = r;
|
|
458
602
|
} else f = n.rawBody;
|
|
459
603
|
} catch (t) {
|
|
460
|
-
let n =
|
|
604
|
+
let n = G(400, {
|
|
461
605
|
error: "malformed body",
|
|
462
606
|
reason: t.message
|
|
463
607
|
});
|
|
@@ -474,7 +618,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
474
618
|
try {
|
|
475
619
|
p = x.decodeUnknownSync(e.payload)(f);
|
|
476
620
|
} catch (t) {
|
|
477
|
-
let n =
|
|
621
|
+
let n = G(422, {
|
|
478
622
|
error: "schema validation failed",
|
|
479
623
|
reason: t.message
|
|
480
624
|
});
|
|
@@ -493,7 +637,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
493
637
|
if (m = typeof t == "string" ? n.headers[t.toLowerCase()] : t(n.headers, n.rawBody), m !== void 0 && m.length > 0) {
|
|
494
638
|
let t = s.claim(m, c);
|
|
495
639
|
if (h = t, t === "duplicate") {
|
|
496
|
-
let t =
|
|
640
|
+
let t = G(200, {
|
|
497
641
|
received: !0,
|
|
498
642
|
duplicate: !0
|
|
499
643
|
});
|
|
@@ -506,7 +650,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
506
650
|
}), t;
|
|
507
651
|
}
|
|
508
652
|
if (t === "inflight") {
|
|
509
|
-
let t =
|
|
653
|
+
let t = G(409, {
|
|
510
654
|
error: "request already in flight",
|
|
511
655
|
idempotencyKey: m
|
|
512
656
|
});
|
|
@@ -529,7 +673,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
529
673
|
idempotencyKey: m ?? "",
|
|
530
674
|
...r ? { workflows: r } : {}
|
|
531
675
|
}), m !== void 0 && s.commit(m);
|
|
532
|
-
let i =
|
|
676
|
+
let i = G(200, { received: !0 });
|
|
533
677
|
return l({
|
|
534
678
|
webhookId: e.id,
|
|
535
679
|
status: 200,
|
|
@@ -539,7 +683,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
539
683
|
}), i;
|
|
540
684
|
} catch (t) {
|
|
541
685
|
m !== void 0 && s.release(m);
|
|
542
|
-
let n =
|
|
686
|
+
let n = G(500, {
|
|
543
687
|
error: "handler threw",
|
|
544
688
|
reason: t.message
|
|
545
689
|
});
|
|
@@ -558,20 +702,20 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
558
702
|
}), n;
|
|
559
703
|
}
|
|
560
704
|
};
|
|
561
|
-
},
|
|
705
|
+
}, be = (e) => `/webhooks/${e}`, K = "_voltro_webhook_rate_windows", q = 6e4, xe = (e, t) => `${e}@${t}`, J = async (e, t, n) => (await e.query({
|
|
562
706
|
table: "_voltro_webhook_rate_windows",
|
|
563
707
|
predicate: S(C("scope", t), C("bucket", n)),
|
|
564
708
|
order: [],
|
|
565
709
|
take: 1,
|
|
566
710
|
skip: void 0,
|
|
567
711
|
projection: void 0
|
|
568
|
-
}))[0] ?? null,
|
|
569
|
-
for (let r = 0; r <
|
|
712
|
+
}))[0] ?? null, Y = 32, X = async (e, t, n) => {
|
|
713
|
+
for (let r = 0; r < Y; r++) {
|
|
570
714
|
r > 0 && await new Promise((e) => setTimeout(e, r));
|
|
571
|
-
let i = await
|
|
715
|
+
let i = await J(e, t.key, n);
|
|
572
716
|
if (i === null) {
|
|
573
|
-
await e.insertIgnore(
|
|
574
|
-
id:
|
|
717
|
+
await e.insertIgnore(K, {
|
|
718
|
+
id: xe(t.key, n),
|
|
575
719
|
scope: t.key,
|
|
576
720
|
bucket: n,
|
|
577
721
|
count: 0,
|
|
@@ -586,29 +730,29 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
586
730
|
updatedAt: /* @__PURE__ */ new Date()
|
|
587
731
|
}, { where: S(C("id", i.id), C("count", i.count)) }) === 1) return !0;
|
|
588
732
|
}
|
|
589
|
-
throw Error(`webhook rate window: contention on (${t.key}, ${n}) exceeded ${
|
|
590
|
-
},
|
|
591
|
-
for (let r = 0; r <
|
|
733
|
+
throw Error(`webhook rate window: contention on (${t.key}, ${n}) exceeded ${Y} attempts`);
|
|
734
|
+
}, Z = async (e, t, n) => {
|
|
735
|
+
for (let r = 0; r < Y; r++) {
|
|
592
736
|
r > 0 && await new Promise((e) => setTimeout(e, r));
|
|
593
|
-
let i = await
|
|
737
|
+
let i = await J(e, t, n);
|
|
594
738
|
if (i === null || i.count <= 0 || await e.updateMany("_voltro_webhook_rate_windows", {
|
|
595
739
|
count: i.count - 1,
|
|
596
740
|
updatedAt: /* @__PURE__ */ new Date()
|
|
597
741
|
}, { where: S(C("id", i.id), C("count", i.count)) }) === 1) return;
|
|
598
742
|
}
|
|
599
|
-
throw Error(`webhook rate window: release contention on (${t}) exceeded ${
|
|
600
|
-
},
|
|
743
|
+
throw Error(`webhook rate window: release contention on (${t}) exceeded ${Y} attempts`);
|
|
744
|
+
}, Se = async (e, t, n, r = q) => {
|
|
601
745
|
if (t.length === 0) return {
|
|
602
746
|
acquired: !0,
|
|
603
747
|
retryInMs: 0
|
|
604
748
|
};
|
|
605
749
|
let i = Math.floor(n / r), a = [];
|
|
606
750
|
for (let o of t) {
|
|
607
|
-
if (await
|
|
751
|
+
if (await X(e, o, i)) {
|
|
608
752
|
a.push(o);
|
|
609
753
|
continue;
|
|
610
754
|
}
|
|
611
|
-
for (let t of a) await
|
|
755
|
+
for (let t of a) await Z(e, t.key, i);
|
|
612
756
|
return {
|
|
613
757
|
acquired: !1,
|
|
614
758
|
retryInMs: (i + 1) * r - n
|
|
@@ -618,7 +762,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
618
762
|
acquired: !0,
|
|
619
763
|
retryInMs: 0
|
|
620
764
|
};
|
|
621
|
-
},
|
|
765
|
+
}, Ce = (e, t) => {
|
|
622
766
|
if (e === "json") return {
|
|
623
767
|
contentType: "application/json",
|
|
624
768
|
bytes: Buffer.from(t, "utf8")
|
|
@@ -634,15 +778,15 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
634
778
|
}
|
|
635
779
|
return e === "form" ? {
|
|
636
780
|
contentType: "application/x-www-form-urlencoded",
|
|
637
|
-
bytes: Buffer.from(
|
|
781
|
+
bytes: Buffer.from(we(n), "utf8")
|
|
638
782
|
} : {
|
|
639
783
|
contentType: "application/xml",
|
|
640
|
-
bytes: Buffer.from(
|
|
784
|
+
bytes: Buffer.from(Ee(n), "utf8")
|
|
641
785
|
};
|
|
642
|
-
},
|
|
786
|
+
}, we = (e) => {
|
|
643
787
|
if (typeof e != "object" || !e || Array.isArray(e)) throw new d({
|
|
644
788
|
format: "form",
|
|
645
|
-
reason: `form encoding requires a JSON object at the top level, got ${
|
|
789
|
+
reason: `form encoding requires a JSON object at the top level, got ${ke(e)}`
|
|
646
790
|
});
|
|
647
791
|
let t = new URLSearchParams();
|
|
648
792
|
for (let [n, r] of Object.entries(e)) Q(t, n, r);
|
|
@@ -661,13 +805,13 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
661
805
|
return;
|
|
662
806
|
}
|
|
663
807
|
e.append(t, String(n));
|
|
664
|
-
},
|
|
665
|
-
if (!
|
|
808
|
+
}, Te = /^[A-Za-z_][A-Za-z0-9_.-]*$/, Ee = (e) => `<?xml version="1.0" encoding="UTF-8"?>${$("webhook", e)}`, $ = (e, t) => {
|
|
809
|
+
if (!Te.test(e)) throw new d({
|
|
666
810
|
format: "xml",
|
|
667
811
|
reason: `object key ${JSON.stringify(e)} is not a valid XML element name`
|
|
668
812
|
});
|
|
669
|
-
return `<${e}>${
|
|
670
|
-
},
|
|
813
|
+
return `<${e}>${De(e, t)}</${e}>`;
|
|
814
|
+
}, De = (e, t) => t == null ? "" : Array.isArray(t) ? t.map((e) => $("item", e)).join("") : typeof t == "object" ? Object.entries(t).map(([e, t]) => $(e, t)).join("") : Oe(String(t)), Oe = (e) => e.replace(/[&<>"']/g, (e) => {
|
|
671
815
|
switch (e) {
|
|
672
816
|
case "&": return "&";
|
|
673
817
|
case "<": return "<";
|
|
@@ -675,17 +819,17 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
675
819
|
case "\"": return """;
|
|
676
820
|
default: return "'";
|
|
677
821
|
}
|
|
678
|
-
}),
|
|
822
|
+
}), ke = (e) => e === null ? "null" : Array.isArray(e) ? "array" : typeof e, Ae = "_voltro_webhook_targets", je = 32, Me = async (e, t) => (await e.query({
|
|
679
823
|
table: "_voltro_webhook_targets",
|
|
680
824
|
predicate: C("id", t),
|
|
681
825
|
order: [],
|
|
682
826
|
take: 1,
|
|
683
827
|
skip: void 0,
|
|
684
828
|
projection: void 0
|
|
685
|
-
}))[0] ?? null,
|
|
686
|
-
for (let a = 0; a <
|
|
829
|
+
}))[0] ?? null, Ne = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => {
|
|
830
|
+
for (let a = 0; a < je; a++) {
|
|
687
831
|
a > 0 && await new Promise((e) => setTimeout(e, a));
|
|
688
|
-
let o = await
|
|
832
|
+
let o = await Me(e, t);
|
|
689
833
|
if (o === null) return {
|
|
690
834
|
consecutiveFailures: 0,
|
|
691
835
|
autoDisabled: !1
|
|
@@ -710,24 +854,24 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
710
854
|
autoDisabled: u
|
|
711
855
|
};
|
|
712
856
|
}
|
|
713
|
-
throw Error(`webhook auto-disable: streak CAS contention on target ${t} exceeded ${
|
|
714
|
-
},
|
|
857
|
+
throw Error(`webhook auto-disable: streak CAS contention on target ${t} exceeded ${je} attempts`);
|
|
858
|
+
}, Pe = x.Struct({
|
|
715
859
|
status: x.Number,
|
|
716
860
|
body: x.String,
|
|
717
861
|
latencyMs: x.Number,
|
|
718
862
|
retryAfterSec: x.Union(x.Number, x.Undefined),
|
|
719
863
|
transportError: x.Union(x.String, x.Undefined),
|
|
720
864
|
encodeError: x.Union(x.String, x.Undefined)
|
|
721
|
-
}),
|
|
865
|
+
}), Fe = x.Struct({
|
|
722
866
|
outcome: x.Literal("succeeded", "failed", "retry"),
|
|
723
867
|
delayMs: x.Union(x.Number, x.Undefined),
|
|
724
868
|
reason: x.Union(x.String, x.Undefined),
|
|
725
869
|
autoDisabled: x.Union(x.Boolean, x.Undefined),
|
|
726
870
|
consecutiveFailures: x.Union(x.Number, x.Undefined)
|
|
727
|
-
}),
|
|
871
|
+
}), Ie = x.Struct({
|
|
728
872
|
acquired: x.Boolean,
|
|
729
873
|
retryInMs: x.Number
|
|
730
|
-
}),
|
|
874
|
+
}), Le = ie.make({
|
|
731
875
|
name: "voltro.deliverWebhook",
|
|
732
876
|
payload: {
|
|
733
877
|
deliveryId: x.String,
|
|
@@ -742,10 +886,10 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
742
886
|
attempts: x.Number
|
|
743
887
|
}),
|
|
744
888
|
idempotencyKey: ({ deliveryId: e, attemptEpoch: t }) => `voltro.deliverWebhook:${e}:${t ?? 0}`
|
|
745
|
-
}),
|
|
746
|
-
let { deliveryId: i, targetId: a, event: s, eventId: c, payloadJson: l } = n, u =
|
|
889
|
+
}), Re = (e, t = {}) => (n, r) => {
|
|
890
|
+
let { deliveryId: i, targetId: a, event: s, eventId: c, payloadJson: l } = n, u = T({ scope: `webhook:${i}` });
|
|
747
891
|
return b.gen(function* () {
|
|
748
|
-
let n = yield*
|
|
892
|
+
let n = yield* E.make({
|
|
749
893
|
name: "fetch-target",
|
|
750
894
|
success: x.Union(x.Null, x.Struct({
|
|
751
895
|
id: x.String,
|
|
@@ -805,7 +949,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
805
949
|
...o
|
|
806
950
|
});
|
|
807
951
|
};
|
|
808
|
-
if (n.active !== !0) return yield*
|
|
952
|
+
if (n.active !== !0) return yield* E.make({
|
|
809
953
|
name: "record-paused-pending",
|
|
810
954
|
success: x.Void,
|
|
811
955
|
execute: b.tryPromise({
|
|
@@ -826,11 +970,11 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
826
970
|
for (let t = 1; t <= p.maxAttempts; t++) {
|
|
827
971
|
let f = `${i}:${t}`;
|
|
828
972
|
if (v.length > 0) for (let n = 0;; n++) {
|
|
829
|
-
let i = yield*
|
|
973
|
+
let i = yield* E.make({
|
|
830
974
|
name: `rate-acquire-${t}-${n}`,
|
|
831
|
-
success:
|
|
975
|
+
success: Ie,
|
|
832
976
|
execute: b.tryPromise({
|
|
833
|
-
try: () =>
|
|
977
|
+
try: () => Se(e.store, v, Date.now(), g),
|
|
834
978
|
catch: (e) => (u.debug("rate-acquire raw error", {
|
|
835
979
|
targetId: a,
|
|
836
980
|
event: s,
|
|
@@ -840,7 +984,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
840
984
|
}).pipe(b.orDie)
|
|
841
985
|
});
|
|
842
986
|
if (i.acquired) break;
|
|
843
|
-
yield*
|
|
987
|
+
yield* E.make({
|
|
844
988
|
name: `record-rate-deferral-${t}-${n}`,
|
|
845
989
|
success: x.Void,
|
|
846
990
|
execute: b.tryPromise({
|
|
@@ -850,12 +994,12 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
850
994
|
}),
|
|
851
995
|
catch: (e) => /* @__PURE__ */ Error(`record-rate-deferral failed: ${e.message}`)
|
|
852
996
|
}).pipe(b.orDie)
|
|
853
|
-
}), yield*
|
|
997
|
+
}), yield* re.sleep({
|
|
854
998
|
name: `rate-window-sleep-${t}-${n}`,
|
|
855
999
|
duration: `${i.retryInMs} millis`
|
|
856
1000
|
});
|
|
857
1001
|
}
|
|
858
|
-
yield*
|
|
1002
|
+
yield* E.make({
|
|
859
1003
|
name: `record-attempt-start-${t}`,
|
|
860
1004
|
success: x.Void,
|
|
861
1005
|
execute: b.tryPromise({
|
|
@@ -867,13 +1011,13 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
867
1011
|
catch: (e) => /* @__PURE__ */ Error(`record-attempt-start failed: ${e.message}`)
|
|
868
1012
|
}).pipe(b.orDie)
|
|
869
1013
|
});
|
|
870
|
-
let _ = yield*
|
|
1014
|
+
let _ = yield* E.make({
|
|
871
1015
|
name: `sign-and-post-${t}`,
|
|
872
|
-
success:
|
|
1016
|
+
success: Pe,
|
|
873
1017
|
execute: b.promise(async () => {
|
|
874
1018
|
let e = Date.now(), r;
|
|
875
1019
|
try {
|
|
876
|
-
r =
|
|
1020
|
+
r = Ce(n.format, l);
|
|
877
1021
|
} catch (t) {
|
|
878
1022
|
if (t instanceof d) return {
|
|
879
1023
|
status: 0,
|
|
@@ -921,12 +1065,12 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
921
1065
|
};
|
|
922
1066
|
}
|
|
923
1067
|
})
|
|
924
|
-
}), y = yield*
|
|
1068
|
+
}), y = yield* E.make({
|
|
925
1069
|
name: `classify-and-record-${t}`,
|
|
926
|
-
success:
|
|
1070
|
+
success: Fe,
|
|
927
1071
|
execute: b.tryPromise({
|
|
928
1072
|
try: async () => {
|
|
929
|
-
let r = _.status >= 200 && _.status < 300, i = _.transportError !== void 0, o = _.encodeError !== void 0, s = (t, n) =>
|
|
1073
|
+
let r = _.status >= 200 && _.status < 300, i = _.transportError !== void 0, o = _.encodeError !== void 0, s = (t, n) => Ne(e.store, a, t, n);
|
|
930
1074
|
if (r) {
|
|
931
1075
|
await e.store.update("_voltro_webhook_deliveries", f, {
|
|
932
1076
|
status: "succeeded",
|
|
@@ -944,7 +1088,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
944
1088
|
consecutiveFailures: t.consecutiveFailures
|
|
945
1089
|
};
|
|
946
1090
|
}
|
|
947
|
-
let c = o ? null :
|
|
1091
|
+
let c = o ? null : se(p, t, {
|
|
948
1092
|
...i ? {} : { status: _.status },
|
|
949
1093
|
..._.retryAfterSec === void 0 ? {} : { retryAfterSeconds: _.retryAfterSec }
|
|
950
1094
|
});
|
|
@@ -1004,7 +1148,7 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
1004
1148
|
finalStatus: "failed",
|
|
1005
1149
|
attempts: t
|
|
1006
1150
|
};
|
|
1007
|
-
y.delayMs !== void 0 && (yield*
|
|
1151
|
+
y.delayMs !== void 0 && (yield* re.sleep({
|
|
1008
1152
|
name: `retry-sleep-${t}`,
|
|
1009
1153
|
duration: `${y.delayMs} millis`
|
|
1010
1154
|
}));
|
|
@@ -1016,4 +1160,4 @@ var ae = (e) => e.webhook !== void 0, D = (e) => {
|
|
|
1016
1160
|
});
|
|
1017
1161
|
};
|
|
1018
1162
|
//#endregion
|
|
1019
|
-
export {
|
|
1163
|
+
export { B as IdempotencyCache, q as RATE_WINDOW_MS, K as RATE_WINDOW_TABLE, Ae as TARGETS_TABLE, l as WebhookDeliveryNotFound, u as WebhookPayloadInvalid, d as WebhookPayloadUnrepresentable, f as WebhookPayloadVersionInvalid, p as WebhookSubscribeInvalid, j as WebhooksService, m as _voltroWebhookDeliveriesTable, h as _voltroWebhookRateWindowsTable, g as _voltroWebhookTargetsTable, Se as acquireRateSlots, D as asOutgoingEvent, Re as buildDeliverWebhookExecute, he as buildWebhooksService, fe as compareVersions, X as consumeRateSlot, be as defaultIncomingPath, c as defaultOutgoingSignature, A as defaultRetryPolicy, s as defineIncomingWebhook, t as defineWebhookProvider, Le as deliverWebhookWorkflow, Ce as encodePayload, P as eventsOf, ce as fastRetryPolicy, N as generateSecret, H as getIdempotencyCache, i as githubSignature, ae as hasWebhookAudience, r as isWebhookDescriptor, z as matchesFilter, ye as mountIncomingWebhook, se as nextRetry, O as parseDuration, W as parseTtl, Ne as recordDeliveryOutcome, Z as releaseRateSlot, I as resolveSubscribe, o as signPayload, n as slackSignature, e as stripeSignature, _e as useWebhooks, ge as useWebhooksEffect, F as validateSubscribe, a as verifySignature, _ as webhookTables };
|