@bunbase-ae/js 3.0.0 → 3.0.1-next.406.cb900dd
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/package.json +1 -1
- package/src/admin.ts +73 -0
package/package.json
CHANGED
package/src/admin.ts
CHANGED
|
@@ -1387,6 +1387,21 @@ export type HookEvent =
|
|
|
1387
1387
|
| "beforeDelete"
|
|
1388
1388
|
| "afterDelete";
|
|
1389
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* Per-hook delivery options (issue #682). `mode: "durable"` persists each
|
|
1392
|
+
* after-hook delivery before its first attempt and retries with backoff until
|
|
1393
|
+
* acked or dead-lettered, surviving restarts. Default is fire-and-forget.
|
|
1394
|
+
*/
|
|
1395
|
+
export interface HookDeliveryConfig {
|
|
1396
|
+
mode?: "fire_and_forget" | "durable";
|
|
1397
|
+
/** Max attempts before dead-lettering (durable mode). Default 10. */
|
|
1398
|
+
max_retries?: number;
|
|
1399
|
+
/** Per-attempt request timeout in ms. Default 10000. */
|
|
1400
|
+
timeout_ms?: number;
|
|
1401
|
+
/** Park exhausted deliveries in the dead-letter store for replay. Default true. */
|
|
1402
|
+
dead_letter?: boolean;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1390
1405
|
export interface HookConfig {
|
|
1391
1406
|
id: string;
|
|
1392
1407
|
collection: string;
|
|
@@ -1397,6 +1412,8 @@ export interface HookConfig {
|
|
|
1397
1412
|
timeout_ms: number;
|
|
1398
1413
|
enabled: boolean;
|
|
1399
1414
|
sort_order: number;
|
|
1415
|
+
/** Durable-delivery options, or null for legacy fire-and-forget (#682). */
|
|
1416
|
+
delivery?: HookDeliveryConfig | null;
|
|
1400
1417
|
created_at: number;
|
|
1401
1418
|
}
|
|
1402
1419
|
|
|
@@ -1412,10 +1429,35 @@ export interface CreateHookInput {
|
|
|
1412
1429
|
enabled?: boolean;
|
|
1413
1430
|
/** Ascending order for hooks sharing the same (collection, event). Default 0. */
|
|
1414
1431
|
sort_order?: number;
|
|
1432
|
+
/** Durable, at-least-once delivery options (after-hooks only). (#682) */
|
|
1433
|
+
delivery?: HookDeliveryConfig | null;
|
|
1415
1434
|
}
|
|
1416
1435
|
|
|
1417
1436
|
export type UpdateHookInput = Partial<Omit<CreateHookInput, "collection" | "event">>;
|
|
1418
1437
|
|
|
1438
|
+
/** Status of a durable delivery as surfaced to the admin replay API (#682). */
|
|
1439
|
+
export type WebhookDeliveryStatus = "pending" | "in_flight" | "delivered" | "dead_letter";
|
|
1440
|
+
|
|
1441
|
+
/** Admin-facing view of a durable delivery. The signing secret is never included. */
|
|
1442
|
+
export interface WebhookDeliverySummary {
|
|
1443
|
+
id: string;
|
|
1444
|
+
idempotency_key: string;
|
|
1445
|
+
hook_id: string | null;
|
|
1446
|
+
collection: string;
|
|
1447
|
+
event: string;
|
|
1448
|
+
url: string;
|
|
1449
|
+
has_secret: boolean;
|
|
1450
|
+
status: WebhookDeliveryStatus;
|
|
1451
|
+
attempts: number;
|
|
1452
|
+
max_attempts: number;
|
|
1453
|
+
timeout_ms: number;
|
|
1454
|
+
next_attempt_at: number;
|
|
1455
|
+
last_error: string | null;
|
|
1456
|
+
last_status: number | null;
|
|
1457
|
+
created_at: number;
|
|
1458
|
+
updated_at: number;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1419
1461
|
class AdminHooksClient {
|
|
1420
1462
|
constructor(private readonly http: HttpClient) {}
|
|
1421
1463
|
|
|
@@ -1453,6 +1495,37 @@ class AdminHooksClient {
|
|
|
1453
1495
|
async delete(id: string): Promise<void> {
|
|
1454
1496
|
await this.http.request("DELETE", `/api/v1/admin/hooks/${encodeURIComponent(id)}`);
|
|
1455
1497
|
}
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* List durable deliveries (issue #682). `status: "pending"` returns rows
|
|
1501
|
+
* still in the live queue; `status: "dead_letter"` returns exhausted
|
|
1502
|
+
* deliveries parked for inspection/replay. Secrets are never returned.
|
|
1503
|
+
*/
|
|
1504
|
+
async deliveries(opts?: {
|
|
1505
|
+
status?: "pending" | "dead_letter";
|
|
1506
|
+
limit?: number;
|
|
1507
|
+
}): Promise<WebhookDeliverySummary[]> {
|
|
1508
|
+
const query: Record<string, string> = {};
|
|
1509
|
+
if (opts?.status) query.status = opts.status;
|
|
1510
|
+
if (opts?.limit != null) query.limit = String(opts.limit);
|
|
1511
|
+
const res = await this.http.request<{ items: WebhookDeliverySummary[] }>(
|
|
1512
|
+
"GET",
|
|
1513
|
+
"/api/v1/admin/hooks/deliveries",
|
|
1514
|
+
{ query },
|
|
1515
|
+
);
|
|
1516
|
+
return res.items;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
/**
|
|
1520
|
+
* Replay a durable delivery (issue #682) — re-arm a queue row or re-enqueue
|
|
1521
|
+
* a dead-letter row back to pending. Returns the (possibly new) queue id.
|
|
1522
|
+
*/
|
|
1523
|
+
async replayDelivery(id: string): Promise<{ id: string; source: "queue" | "dead_letter" }> {
|
|
1524
|
+
return this.http.request<{ id: string; source: "queue" | "dead_letter" }>(
|
|
1525
|
+
"POST",
|
|
1526
|
+
`/api/v1/admin/hooks/deliveries/${encodeURIComponent(id)}/replay`,
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1456
1529
|
}
|
|
1457
1530
|
|
|
1458
1531
|
// Tenant membership management — surfaces the /api/v1/admin/tenants/* endpoints
|