@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/admin.ts +73 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunbase-ae/js",
3
- "version": "3.0.0",
3
+ "version": "3.0.1-next.406.cb900dd",
4
4
  "type": "module",
5
5
  "description": "TypeScript/JavaScript SDK for BunBase",
6
6
  "license": "UNLICENSED",
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