@fonderie/client 0.1.0 → 0.2.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/dist/index.js CHANGED
@@ -24,6 +24,7 @@ var HttpClient = class {
24
24
  };
25
25
  if (opts.token) headers["Authorization"] = `Bearer ${opts.token}`;
26
26
  if (opts.cookie) headers["Cookie"] = opts.cookie;
27
+ if (opts.workspaceId) headers["X-Workspace-ID"] = opts.workspaceId;
27
28
  const fetchInit = {
28
29
  method: opts.method,
29
30
  headers,
@@ -31,6 +32,10 @@ var HttpClient = class {
31
32
  };
32
33
  if (opts.body !== void 0) fetchInit.body = JSON.stringify(opts.body);
33
34
  const res = await fetch(`${this.baseUrl}${opts.path}`, fetchInit);
35
+ if (res.status === 204) {
36
+ if (!res.ok) throw new FonderieApiError("unknown", res.statusText, res.status);
37
+ return void 0;
38
+ }
34
39
  const data = await res.json();
35
40
  if (!res.ok || res.status === 202) {
36
41
  const err = data;
@@ -40,27 +45,42 @@ var HttpClient = class {
40
45
  }
41
46
  };
42
47
 
43
- // src/modules/auth.ts
44
- var PhoneClient = class {
45
- constructor(http) {
48
+ // src/modules/audit.ts
49
+ var AuditClient = class {
50
+ constructor(http, tokens) {
46
51
  this.http = http;
52
+ this.tokens = tokens;
47
53
  }
48
54
  http;
49
- sendVerification(phone) {
50
- return this.http.request({
51
- method: "POST",
52
- path: "/auth/phone/send-verification",
53
- body: { phone }
54
- });
55
+ tokens;
56
+ workspaceId;
57
+ setAccessToken(token) {
58
+ this.tokens.set(token);
55
59
  }
56
- verify(phone, otp) {
60
+ // Scopes the audit query to a workspace (X-Workspace-ID). Falls back to
61
+ // the caller's personal workspace when unset, same as billing/workspaces.
62
+ setWorkspaceId(workspaceId) {
63
+ this.workspaceId = workspaceId;
64
+ }
65
+ listEvents(input = {}) {
66
+ const params = new URLSearchParams();
67
+ if (input.limit !== void 0) params.set("limit", String(input.limit));
68
+ if (input.type) params.set("type", input.type);
69
+ if (input.actorId) params.set("actorId", input.actorId);
70
+ if (input.from) params.set("from", input.from.toISOString());
71
+ if (input.to) params.set("to", input.to.toISOString());
72
+ if (input.cursor) params.set("cursor", input.cursor);
73
+ const qs = params.toString();
57
74
  return this.http.request({
58
- method: "POST",
59
- path: "/auth/phone/verify",
60
- body: { phone, otp }
75
+ method: "GET",
76
+ path: `/audit${qs ? `?${qs}` : ""}`,
77
+ token: this.tokens.get(),
78
+ workspaceId: this.workspaceId
61
79
  });
62
80
  }
63
81
  };
82
+
83
+ // src/modules/auth.ts
64
84
  var MfaClient = class {
65
85
  constructor(http, token) {
66
86
  this.http = http;
@@ -75,36 +95,43 @@ var MfaClient = class {
75
95
  token: this.token()
76
96
  });
77
97
  }
78
- verify(code) {
98
+ verify(token) {
79
99
  return this.http.request({
80
100
  method: "POST",
81
101
  path: "/auth/mfa/verify",
82
- body: { token: code },
102
+ body: { token },
83
103
  token: this.token()
84
104
  });
85
105
  }
86
- disable(code) {
106
+ disable(token) {
87
107
  return this.http.request({
88
108
  method: "POST",
89
109
  path: "/auth/mfa/disable",
90
- body: { code },
110
+ body: { token },
111
+ token: this.token()
112
+ });
113
+ }
114
+ // POST /auth/mfa/backup-codes (mfaTokenSchema { token }) — returns a fresh set.
115
+ regenerateBackupCodes(token) {
116
+ return this.http.request({
117
+ method: "POST",
118
+ path: "/auth/mfa/backup-codes",
119
+ body: { token },
91
120
  token: this.token()
92
121
  });
93
122
  }
94
123
  };
95
124
  var AuthClient = class {
96
- constructor(http, accessToken) {
125
+ constructor(http, tokens) {
97
126
  this.http = http;
98
- this.accessToken = accessToken;
99
- this.phone = new PhoneClient(http);
100
- this.mfa = new MfaClient(http, () => this.accessToken);
127
+ this.tokens = tokens;
128
+ this.mfa = new MfaClient(http, () => this.tokens.get());
101
129
  }
102
130
  http;
103
- accessToken;
104
- phone;
131
+ tokens;
105
132
  mfa;
106
133
  setAccessToken(token) {
107
- this.accessToken = token;
134
+ this.tokens.set(token);
108
135
  }
109
136
  // ── Public ─────────────────────────────────────────────────────────────────
110
137
  register(input) {
@@ -142,11 +169,12 @@ var AuthClient = class {
142
169
  body: input
143
170
  });
144
171
  }
145
- verifyEmail(pin) {
172
+ verifyEmail(token) {
146
173
  return this.http.request({
147
174
  method: "POST",
148
- path: "/auth/email/verify",
149
- body: { pin }
175
+ path: "/auth/verify",
176
+ body: { token },
177
+ token: this.tokens.get()
150
178
  });
151
179
  }
152
180
  // ── Protected ──────────────────────────────────────────────────────────────
@@ -155,14 +183,14 @@ var AuthClient = class {
155
183
  method: "POST",
156
184
  path: "/auth/logout",
157
185
  body: refreshToken ? { refreshToken } : void 0,
158
- token: this.accessToken
186
+ token: this.tokens.get()
159
187
  });
160
188
  }
161
189
  sendVerificationEmail() {
162
190
  return this.http.request({
163
- method: "POST",
164
- path: "/auth/email/send-verification",
165
- token: this.accessToken
191
+ method: "GET",
192
+ path: "/auth/send-verification",
193
+ token: this.tokens.get()
166
194
  });
167
195
  }
168
196
  // ── Protected + Verified ───────────────────────────────────────────────────
@@ -170,38 +198,1026 @@ var AuthClient = class {
170
198
  return this.http.request({
171
199
  method: "GET",
172
200
  path: "/users",
173
- token: this.accessToken
201
+ token: this.tokens.get()
202
+ });
203
+ }
204
+ updateProfile(input) {
205
+ return this.http.request({
206
+ method: "PUT",
207
+ path: "/users/profile",
208
+ body: input,
209
+ token: this.tokens.get()
210
+ });
211
+ }
212
+ updatePreferences(input) {
213
+ return this.http.request({
214
+ method: "PUT",
215
+ path: "/users/preferences",
216
+ body: input,
217
+ token: this.tokens.get()
218
+ });
219
+ }
220
+ updateEmail(email) {
221
+ return this.http.request({
222
+ method: "PUT",
223
+ path: "/users/email",
224
+ body: { email },
225
+ token: this.tokens.get()
226
+ });
227
+ }
228
+ updatePhone(phone) {
229
+ return this.http.request({
230
+ method: "PUT",
231
+ path: "/users/phone",
232
+ body: { phone },
233
+ token: this.tokens.get()
174
234
  });
175
235
  }
176
- updateUser(input) {
236
+ changePassword(input) {
177
237
  return this.http.request({
178
238
  method: "PUT",
179
- path: "/users/update",
239
+ path: "/users/password",
180
240
  body: input,
181
- token: this.accessToken
241
+ token: this.tokens.get()
242
+ });
243
+ }
244
+ // GET /users/export — the caller's own data as a portable bundle (SAR).
245
+ exportData() {
246
+ return this.http.request({
247
+ method: "GET",
248
+ path: "/users/export",
249
+ token: this.tokens.get()
182
250
  });
183
251
  }
184
252
  deleteUser() {
185
253
  return this.http.request({
186
254
  method: "DELETE",
187
255
  path: "/users",
188
- token: this.accessToken
256
+ token: this.tokens.get()
257
+ });
258
+ }
259
+ };
260
+
261
+ // src/modules/billing.ts
262
+ var BillingClient = class {
263
+ constructor(http, tokens) {
264
+ this.http = http;
265
+ this.tokens = tokens;
266
+ }
267
+ http;
268
+ tokens;
269
+ workspaceId;
270
+ setAccessToken(token) {
271
+ this.tokens.set(token);
272
+ }
273
+ // Subscriber is resolved from this workspace ID (X-Workspace-ID) when set,
274
+ // falling back to the session user otherwise — see @fonderie/billing's
275
+ // resolveSubscriber. Call with undefined to bill the signed-in user directly.
276
+ setWorkspaceId(workspaceId) {
277
+ this.workspaceId = workspaceId;
278
+ }
279
+ // ── Plans — public read-only ────────────────────────────────────────────────
280
+ listPlans() {
281
+ return this.http.request({
282
+ method: "GET",
283
+ path: "/plans"
284
+ });
285
+ }
286
+ getPlan(planId) {
287
+ return this.http.request({
288
+ method: "GET",
289
+ path: `/plans/${planId}`
290
+ });
291
+ }
292
+ // ── Plans — admin write ──────────────────────────────────────────────────────
293
+ // Unlike every other write in this client, @fonderie/billing does not gate
294
+ // these with requireAuth or an admin token — "the caller is responsible for
295
+ // authorization" (its own routes.ts comment). Sending the session token is
296
+ // harmless (the server ignores it) but does nothing on its own; gate access
297
+ // to these calls yourself (an app-level route guard, a reverse-proxy admin
298
+ // zone, or similar) before wiring them into a UI.
299
+ createPlan(input) {
300
+ return this.http.request({
301
+ method: "POST",
302
+ path: "/plans",
303
+ body: input,
304
+ token: this.tokens.get()
305
+ });
306
+ }
307
+ updatePlan(planId, input) {
308
+ return this.http.request({
309
+ method: "PUT",
310
+ path: `/plans/${planId}`,
311
+ body: input,
312
+ token: this.tokens.get()
313
+ });
314
+ }
315
+ deletePlan(planId) {
316
+ return this.http.request({
317
+ method: "DELETE",
318
+ path: `/plans/${planId}`,
319
+ token: this.tokens.get()
320
+ });
321
+ }
322
+ // ── Subscription ─────────────────────────────────────────────────────────────
323
+ getSubscription() {
324
+ return this.http.request({
325
+ method: "GET",
326
+ path: "/billing/subscription",
327
+ token: this.tokens.get(),
328
+ workspaceId: this.workspaceId
329
+ });
330
+ }
331
+ // ── Checkout / portal ────────────────────────────────────────────────────────
332
+ createCheckoutSession(input) {
333
+ return this.http.request({
334
+ method: "POST",
335
+ path: "/billing/checkout",
336
+ body: input,
337
+ token: this.tokens.get(),
338
+ workspaceId: this.workspaceId
339
+ });
340
+ }
341
+ createPortalSession() {
342
+ return this.http.request({
343
+ method: "POST",
344
+ path: "/billing/portal",
345
+ token: this.tokens.get(),
346
+ workspaceId: this.workspaceId
347
+ });
348
+ }
349
+ // ── Usage ────────────────────────────────────────────────────────────────────
350
+ recordUsage(input) {
351
+ return this.http.request({
352
+ method: "POST",
353
+ path: "/billing/usage",
354
+ body: input,
355
+ token: this.tokens.get(),
356
+ workspaceId: this.workspaceId
357
+ });
358
+ }
359
+ getUsage(metric) {
360
+ return this.http.request({
361
+ method: "GET",
362
+ path: `/billing/usage/${metric}`,
363
+ token: this.tokens.get(),
364
+ workspaceId: this.workspaceId
365
+ });
366
+ }
367
+ };
368
+
369
+ // src/modules/customers.ts
370
+ var CustomersClient = class {
371
+ constructor(http, tokens) {
372
+ this.http = http;
373
+ this.tokens = tokens;
374
+ }
375
+ http;
376
+ tokens;
377
+ workspaceId;
378
+ setAccessToken(token) {
379
+ this.tokens.set(token);
380
+ }
381
+ // Scopes every request to this workspace (X-Workspace-ID). Falls back to
382
+ // the caller's personal workspace when unset, same as billing/workspaces/audit/webhooks.
383
+ setWorkspaceId(workspaceId) {
384
+ this.workspaceId = workspaceId;
385
+ }
386
+ // ── Core customer CRUD ───────────────────────────────────────────────────────
387
+ listCustomers(input = {}) {
388
+ const params = new URLSearchParams();
389
+ if (input.search !== void 0) params.set("search", input.search);
390
+ if (input.blacklisted !== void 0) params.set("blacklisted", String(input.blacklisted));
391
+ if (input.limit !== void 0) params.set("limit", String(input.limit));
392
+ if (input.offset !== void 0) params.set("offset", String(input.offset));
393
+ const qs = params.toString();
394
+ return this.http.request({
395
+ method: "GET",
396
+ path: qs ? `/customers?${qs}` : "/customers",
397
+ token: this.tokens.get(),
398
+ workspaceId: this.workspaceId
399
+ });
400
+ }
401
+ createCustomer(input = {}) {
402
+ return this.http.request({
403
+ method: "POST",
404
+ path: "/customers",
405
+ body: input,
406
+ token: this.tokens.get(),
407
+ workspaceId: this.workspaceId
408
+ });
409
+ }
410
+ // depth defaults to 2 server-side; pass { depth: 1 } for one level of
411
+ // relationship expansion instead of the D2 (nested-relationships) shape.
412
+ getCustomer(customerId, input = {}) {
413
+ const qs = input.depth === 1 ? "?depth=1" : "";
414
+ return this.http.request({
415
+ method: "GET",
416
+ path: `/customers/${customerId}${qs}`,
417
+ token: this.tokens.get(),
418
+ workspaceId: this.workspaceId
419
+ });
420
+ }
421
+ updateCustomer(customerId, input) {
422
+ return this.http.request({
423
+ method: "PUT",
424
+ path: `/customers/${customerId}`,
425
+ body: input,
426
+ token: this.tokens.get(),
427
+ workspaceId: this.workspaceId
428
+ });
429
+ }
430
+ deleteCustomer(customerId) {
431
+ return this.http.request({
432
+ method: "DELETE",
433
+ path: `/customers/${customerId}`,
434
+ token: this.tokens.get(),
435
+ workspaceId: this.workspaceId
436
+ });
437
+ }
438
+ blacklistCustomer(customerId, input = {}) {
439
+ return this.http.request({
440
+ method: "POST",
441
+ path: `/customers/${customerId}/blacklist`,
442
+ body: input,
443
+ token: this.tokens.get(),
444
+ workspaceId: this.workspaceId
445
+ });
446
+ }
447
+ unblacklistCustomer(customerId) {
448
+ return this.http.request({
449
+ method: "POST",
450
+ path: `/customers/${customerId}/unblacklist`,
451
+ token: this.tokens.get(),
452
+ workspaceId: this.workspaceId
453
+ });
454
+ }
455
+ // ── Emails ───────────────────────────────────────────────────────────────────
456
+ listEmails(customerId) {
457
+ return this.http.request({
458
+ method: "GET",
459
+ path: `/customers/${customerId}/emails`,
460
+ token: this.tokens.get(),
461
+ workspaceId: this.workspaceId
462
+ });
463
+ }
464
+ addEmail(customerId, input) {
465
+ return this.http.request({
466
+ method: "POST",
467
+ path: `/customers/${customerId}/emails`,
468
+ body: input,
469
+ token: this.tokens.get(),
470
+ workspaceId: this.workspaceId
471
+ });
472
+ }
473
+ // Only the label is editable — email addresses themselves are immutable
474
+ // once added; remove and re-add to change the address.
475
+ updateEmailLabel(customerId, emailId, label) {
476
+ return this.http.request({
477
+ method: "PATCH",
478
+ path: `/customers/${customerId}/emails/${emailId}`,
479
+ body: { label },
480
+ token: this.tokens.get(),
481
+ workspaceId: this.workspaceId
482
+ });
483
+ }
484
+ setPrimaryEmail(customerId, emailId) {
485
+ return this.http.request({
486
+ method: "PUT",
487
+ path: `/customers/${customerId}/emails/${emailId}/primary`,
488
+ token: this.tokens.get(),
489
+ workspaceId: this.workspaceId
490
+ });
491
+ }
492
+ removeEmail(customerId, emailId) {
493
+ return this.http.request({
494
+ method: "DELETE",
495
+ path: `/customers/${customerId}/emails/${emailId}`,
496
+ token: this.tokens.get(),
497
+ workspaceId: this.workspaceId
498
+ });
499
+ }
500
+ // ── Phones ───────────────────────────────────────────────────────────────────
501
+ listPhones(customerId) {
502
+ return this.http.request({
503
+ method: "GET",
504
+ path: `/customers/${customerId}/phones`,
505
+ token: this.tokens.get(),
506
+ workspaceId: this.workspaceId
507
+ });
508
+ }
509
+ addPhone(customerId, input) {
510
+ return this.http.request({
511
+ method: "POST",
512
+ path: `/customers/${customerId}/phones`,
513
+ body: input,
514
+ token: this.tokens.get(),
515
+ workspaceId: this.workspaceId
516
+ });
517
+ }
518
+ // Only the label is editable — same as updateEmailLabel.
519
+ updatePhoneLabel(customerId, phoneId, label) {
520
+ return this.http.request({
521
+ method: "PATCH",
522
+ path: `/customers/${customerId}/phones/${phoneId}`,
523
+ body: { label },
524
+ token: this.tokens.get(),
525
+ workspaceId: this.workspaceId
526
+ });
527
+ }
528
+ setPrimaryPhone(customerId, phoneId) {
529
+ return this.http.request({
530
+ method: "PUT",
531
+ path: `/customers/${customerId}/phones/${phoneId}/primary`,
532
+ token: this.tokens.get(),
533
+ workspaceId: this.workspaceId
534
+ });
535
+ }
536
+ removePhone(customerId, phoneId) {
537
+ return this.http.request({
538
+ method: "DELETE",
539
+ path: `/customers/${customerId}/phones/${phoneId}`,
540
+ token: this.tokens.get(),
541
+ workspaceId: this.workspaceId
542
+ });
543
+ }
544
+ // ── Addresses ────────────────────────────────────────────────────────────────
545
+ listAddresses(customerId) {
546
+ return this.http.request({
547
+ method: "GET",
548
+ path: `/customers/${customerId}/addresses`,
549
+ token: this.tokens.get(),
550
+ workspaceId: this.workspaceId
551
+ });
552
+ }
553
+ addAddress(customerId, input) {
554
+ return this.http.request({
555
+ method: "POST",
556
+ path: `/customers/${customerId}/addresses`,
557
+ body: input,
558
+ token: this.tokens.get(),
559
+ workspaceId: this.workspaceId
560
+ });
561
+ }
562
+ // Only the label is editable — same as updateEmailLabel.
563
+ updateAddressLabel(customerId, addrId, label) {
564
+ return this.http.request({
565
+ method: "PATCH",
566
+ path: `/customers/${customerId}/addresses/${addrId}`,
567
+ body: { label },
568
+ token: this.tokens.get(),
569
+ workspaceId: this.workspaceId
570
+ });
571
+ }
572
+ setPrimaryAddress(customerId, addrId) {
573
+ return this.http.request({
574
+ method: "PUT",
575
+ path: `/customers/${customerId}/addresses/${addrId}/primary`,
576
+ token: this.tokens.get(),
577
+ workspaceId: this.workspaceId
578
+ });
579
+ }
580
+ removeAddress(customerId, addrId) {
581
+ return this.http.request({
582
+ method: "DELETE",
583
+ path: `/customers/${customerId}/addresses/${addrId}`,
584
+ token: this.tokens.get(),
585
+ workspaceId: this.workspaceId
586
+ });
587
+ }
588
+ // ── Notes ────────────────────────────────────────────────────────────────────
589
+ listNotes(customerId) {
590
+ return this.http.request({
591
+ method: "GET",
592
+ path: `/customers/${customerId}/notes`,
593
+ token: this.tokens.get(),
594
+ workspaceId: this.workspaceId
595
+ });
596
+ }
597
+ createNote(customerId, body) {
598
+ return this.http.request({
599
+ method: "POST",
600
+ path: `/customers/${customerId}/notes`,
601
+ body: { body },
602
+ token: this.tokens.get(),
603
+ workspaceId: this.workspaceId
604
+ });
605
+ }
606
+ updateNote(customerId, noteId, body) {
607
+ return this.http.request({
608
+ method: "PUT",
609
+ path: `/customers/${customerId}/notes/${noteId}`,
610
+ body: { body },
611
+ token: this.tokens.get(),
612
+ workspaceId: this.workspaceId
613
+ });
614
+ }
615
+ deleteNote(customerId, noteId) {
616
+ return this.http.request({
617
+ method: "DELETE",
618
+ path: `/customers/${customerId}/notes/${noteId}`,
619
+ token: this.tokens.get(),
620
+ workspaceId: this.workspaceId
621
+ });
622
+ }
623
+ // ── Tags ─────────────────────────────────────────────────────────────────────
624
+ listTags(customerId) {
625
+ return this.http.request({
626
+ method: "GET",
627
+ path: `/customers/${customerId}/tags`,
628
+ token: this.tokens.get(),
629
+ workspaceId: this.workspaceId
630
+ });
631
+ }
632
+ addTag(customerId, tag) {
633
+ return this.http.request({
634
+ method: "POST",
635
+ path: `/customers/${customerId}/tags`,
636
+ body: { tag },
637
+ token: this.tokens.get(),
638
+ workspaceId: this.workspaceId
639
+ });
640
+ }
641
+ removeTag(customerId, tag) {
642
+ return this.http.request({
643
+ method: "DELETE",
644
+ path: `/customers/${customerId}/tags/${encodeURIComponent(tag)}`,
645
+ token: this.tokens.get(),
646
+ workspaceId: this.workspaceId
647
+ });
648
+ }
649
+ // ── Relationships ────────────────────────────────────────────────────────────
650
+ listRelationships(customerId) {
651
+ return this.http.request({
652
+ method: "GET",
653
+ path: `/customers/${customerId}/relationships`,
654
+ token: this.tokens.get(),
655
+ workspaceId: this.workspaceId
656
+ });
657
+ }
658
+ addRelationship(customerId, input) {
659
+ return this.http.request({
660
+ method: "POST",
661
+ path: `/customers/${customerId}/relationships`,
662
+ body: input,
663
+ token: this.tokens.get(),
664
+ workspaceId: this.workspaceId
665
+ });
666
+ }
667
+ setPrimaryRelationship(customerId, relatedId) {
668
+ return this.http.request({
669
+ method: "PUT",
670
+ path: `/customers/${customerId}/relationships/${relatedId}/primary`,
671
+ token: this.tokens.get(),
672
+ workspaceId: this.workspaceId
673
+ });
674
+ }
675
+ removeRelationship(customerId, relatedId) {
676
+ return this.http.request({
677
+ method: "DELETE",
678
+ path: `/customers/${customerId}/relationships/${relatedId}`,
679
+ token: this.tokens.get(),
680
+ workspaceId: this.workspaceId
681
+ });
682
+ }
683
+ // ── Labels ───────────────────────────────────────────────────────────────────
684
+ // Shared vocabulary across all customers in the workspace — labels are
685
+ // looked up/created implicitly by addEmail/addPhone/addAddress's `label`
686
+ // string; these two methods are for managing the vocabulary directly
687
+ // (e.g. an admin screen listing/pruning unused labels).
688
+ listLabels(type) {
689
+ return this.http.request({
690
+ method: "GET",
691
+ path: `/customers/labels?type=${type}`,
692
+ token: this.tokens.get(),
693
+ workspaceId: this.workspaceId
694
+ });
695
+ }
696
+ removeLabel(labelId) {
697
+ return this.http.request({
698
+ method: "DELETE",
699
+ path: `/customers/labels/${labelId}`,
700
+ token: this.tokens.get(),
701
+ workspaceId: this.workspaceId
189
702
  });
190
703
  }
191
704
  };
192
705
 
706
+ // src/modules/webhooks.ts
707
+ var WebhooksClient = class {
708
+ constructor(http, tokens) {
709
+ this.http = http;
710
+ this.tokens = tokens;
711
+ }
712
+ http;
713
+ tokens;
714
+ workspaceId;
715
+ setAccessToken(token) {
716
+ this.tokens.set(token);
717
+ }
718
+ // Scopes every request to this workspace (X-Workspace-ID). Falls back to
719
+ // the caller's personal workspace when unset, same as billing/workspaces/audit.
720
+ setWorkspaceId(workspaceId) {
721
+ this.workspaceId = workspaceId;
722
+ }
723
+ listEndpoints() {
724
+ return this.http.request({
725
+ method: "GET",
726
+ path: "/webhooks",
727
+ token: this.tokens.get(),
728
+ workspaceId: this.workspaceId
729
+ });
730
+ }
731
+ // The response includes `secret` — shown once, at creation. There is no
732
+ // way to retrieve it again afterward; store it or let the caller copy it.
733
+ createEndpoint(input) {
734
+ return this.http.request({
735
+ method: "POST",
736
+ path: "/webhooks",
737
+ body: input,
738
+ token: this.tokens.get(),
739
+ workspaceId: this.workspaceId
740
+ });
741
+ }
742
+ getEndpoint(endpointId) {
743
+ return this.http.request({
744
+ method: "GET",
745
+ path: `/webhooks/${endpointId}`,
746
+ token: this.tokens.get(),
747
+ workspaceId: this.workspaceId
748
+ });
749
+ }
750
+ updateEndpoint(endpointId, input) {
751
+ return this.http.request({
752
+ method: "PATCH",
753
+ path: `/webhooks/${endpointId}`,
754
+ body: input,
755
+ token: this.tokens.get(),
756
+ workspaceId: this.workspaceId
757
+ });
758
+ }
759
+ deleteEndpoint(endpointId) {
760
+ return this.http.request({
761
+ method: "DELETE",
762
+ path: `/webhooks/${endpointId}`,
763
+ token: this.tokens.get(),
764
+ workspaceId: this.workspaceId
765
+ });
766
+ }
767
+ listDeliveries(endpointId) {
768
+ return this.http.request({
769
+ method: "GET",
770
+ path: `/webhooks/${endpointId}/deliveries`,
771
+ token: this.tokens.get(),
772
+ workspaceId: this.workspaceId
773
+ });
774
+ }
775
+ testEndpoint(endpointId) {
776
+ return this.http.request({
777
+ method: "POST",
778
+ path: `/webhooks/${endpointId}/test`,
779
+ token: this.tokens.get(),
780
+ workspaceId: this.workspaceId
781
+ });
782
+ }
783
+ };
784
+
785
+ // src/modules/workspaces.ts
786
+ var WorkspacesClient = class {
787
+ constructor(http, tokens) {
788
+ this.http = http;
789
+ this.tokens = tokens;
790
+ }
791
+ http;
792
+ tokens;
793
+ workspaceId;
794
+ setAccessToken(token) {
795
+ this.tokens.set(token);
796
+ }
797
+ // Scopes every subsequent request to this workspace (X-Workspace-ID).
798
+ // Falls back to the caller's personal workspace when unset.
799
+ setWorkspaceId(workspaceId) {
800
+ this.workspaceId = workspaceId;
801
+ }
802
+ // ── Workspace creation + listing ─────────────────────────────────────────────
803
+ listWorkspaces() {
804
+ return this.http.request({
805
+ method: "GET",
806
+ path: "/workspaces",
807
+ token: this.tokens.get()
808
+ });
809
+ }
810
+ createWorkspace(input) {
811
+ return this.http.request({
812
+ method: "POST",
813
+ path: "/workspaces",
814
+ body: input,
815
+ token: this.tokens.get()
816
+ });
817
+ }
818
+ getWorkspace(id) {
819
+ return this.http.request({
820
+ method: "GET",
821
+ path: `/workspaces/${id}`,
822
+ token: this.tokens.get()
823
+ });
824
+ }
825
+ updateWorkspace(input) {
826
+ return this.http.request({
827
+ method: "PUT",
828
+ path: "/workspaces",
829
+ body: input,
830
+ token: this.tokens.get(),
831
+ workspaceId: this.workspaceId
832
+ });
833
+ }
834
+ // Personal workspaces can't be archived — the server returns 403 if you try.
835
+ archiveWorkspace() {
836
+ return this.http.request({
837
+ method: "POST",
838
+ path: "/workspaces/archive",
839
+ token: this.tokens.get(),
840
+ workspaceId: this.workspaceId
841
+ });
842
+ }
843
+ restoreWorkspace() {
844
+ return this.http.request({
845
+ method: "POST",
846
+ path: "/workspaces/restore",
847
+ token: this.tokens.get(),
848
+ workspaceId: this.workspaceId
849
+ });
850
+ }
851
+ // ── Roles ────────────────────────────────────────────────────────────────────
852
+ listRoles() {
853
+ return this.http.request({
854
+ method: "GET",
855
+ path: "/workspaces/roles",
856
+ token: this.tokens.get(),
857
+ workspaceId: this.workspaceId
858
+ });
859
+ }
860
+ createRole(input) {
861
+ return this.http.request({
862
+ method: "POST",
863
+ path: "/workspaces/roles",
864
+ body: input,
865
+ token: this.tokens.get(),
866
+ workspaceId: this.workspaceId
867
+ });
868
+ }
869
+ getRole(roleId) {
870
+ return this.http.request({
871
+ method: "GET",
872
+ path: `/workspaces/roles/${roleId}`,
873
+ token: this.tokens.get(),
874
+ workspaceId: this.workspaceId
875
+ });
876
+ }
877
+ updateRole(roleId, input) {
878
+ return this.http.request({
879
+ method: "PUT",
880
+ path: `/workspaces/roles/${roleId}`,
881
+ body: input,
882
+ token: this.tokens.get(),
883
+ workspaceId: this.workspaceId
884
+ });
885
+ }
886
+ removeRole(roleId) {
887
+ return this.http.request({
888
+ method: "DELETE",
889
+ path: `/workspaces/roles/${roleId}`,
890
+ token: this.tokens.get(),
891
+ workspaceId: this.workspaceId
892
+ });
893
+ }
894
+ getRolePermissions(roleId) {
895
+ return this.http.request({
896
+ method: "GET",
897
+ path: `/workspaces/roles/${roleId}/permissions`,
898
+ token: this.tokens.get(),
899
+ workspaceId: this.workspaceId
900
+ });
901
+ }
902
+ setRolePermissions(roleId, permissions) {
903
+ return this.http.request({
904
+ method: "POST",
905
+ path: `/workspaces/roles/${roleId}/permissions`,
906
+ body: { permissions },
907
+ token: this.tokens.get(),
908
+ workspaceId: this.workspaceId
909
+ });
910
+ }
911
+ // ── Members ──────────────────────────────────────────────────────────────────
912
+ listMembers() {
913
+ return this.http.request({
914
+ method: "GET",
915
+ path: "/workspaces/members",
916
+ token: this.tokens.get(),
917
+ workspaceId: this.workspaceId
918
+ });
919
+ }
920
+ removeMember(userId) {
921
+ return this.http.request({
922
+ method: "DELETE",
923
+ path: `/workspaces/members/${userId}`,
924
+ token: this.tokens.get(),
925
+ workspaceId: this.workspaceId
926
+ });
927
+ }
928
+ getMemberRoles(userId) {
929
+ return this.http.request({
930
+ method: "GET",
931
+ path: `/workspaces/members/${userId}/roles`,
932
+ token: this.tokens.get(),
933
+ workspaceId: this.workspaceId
934
+ });
935
+ }
936
+ addMemberRole(userId, roleId) {
937
+ return this.http.request({
938
+ method: "POST",
939
+ path: `/workspaces/members/${userId}/roles`,
940
+ body: { roleId },
941
+ token: this.tokens.get(),
942
+ workspaceId: this.workspaceId
943
+ });
944
+ }
945
+ removeMemberRole(userId, roleId) {
946
+ return this.http.request({
947
+ method: "DELETE",
948
+ path: `/workspaces/members/${userId}/roles/${roleId}`,
949
+ token: this.tokens.get(),
950
+ workspaceId: this.workspaceId
951
+ });
952
+ }
953
+ // ── Invitations ──────────────────────────────────────────────────────────────
954
+ listInvitations() {
955
+ return this.http.request({
956
+ method: "GET",
957
+ path: "/workspaces/invitations",
958
+ token: this.tokens.get(),
959
+ workspaceId: this.workspaceId
960
+ });
961
+ }
962
+ invite(entries) {
963
+ return this.http.request({
964
+ method: "POST",
965
+ path: "/workspaces/invitations",
966
+ body: entries,
967
+ token: this.tokens.get(),
968
+ workspaceId: this.workspaceId
969
+ });
970
+ }
971
+ cancelInvitation(inviteId) {
972
+ return this.http.request({
973
+ method: "DELETE",
974
+ path: `/workspaces/invitations/${inviteId}`,
975
+ token: this.tokens.get(),
976
+ workspaceId: this.workspaceId
977
+ });
978
+ }
979
+ acceptInvitation(pin) {
980
+ return this.http.request({
981
+ method: "POST",
982
+ path: "/workspaces/invitations/accept",
983
+ body: { pin },
984
+ token: this.tokens.get()
985
+ });
986
+ }
987
+ // ── Settings ─────────────────────────────────────────────────────────────────
988
+ getSettings() {
989
+ return this.http.request({
990
+ method: "GET",
991
+ path: "/workspaces/settings",
992
+ token: this.tokens.get(),
993
+ workspaceId: this.workspaceId
994
+ });
995
+ }
996
+ updateSettings(input) {
997
+ return this.http.request({
998
+ method: "PUT",
999
+ path: "/workspaces/settings",
1000
+ body: input,
1001
+ token: this.tokens.get(),
1002
+ workspaceId: this.workspaceId
1003
+ });
1004
+ }
1005
+ };
1006
+
1007
+ // src/token-store.ts
1008
+ var TokenStore = class {
1009
+ token;
1010
+ constructor(initial) {
1011
+ this.token = initial;
1012
+ }
1013
+ get() {
1014
+ return this.token;
1015
+ }
1016
+ set(token) {
1017
+ this.token = token;
1018
+ }
1019
+ };
1020
+
193
1021
  // src/client.ts
194
1022
  var FonderieClient = class {
195
1023
  auth;
1024
+ billing;
1025
+ workspaces;
1026
+ audit;
1027
+ webhooks;
1028
+ customers;
1029
+ http;
1030
+ constructor(opts) {
1031
+ this.http = new HttpClient(opts.baseUrl);
1032
+ const tokens = new TokenStore(opts.accessToken);
1033
+ this.auth = new AuthClient(this.http, tokens);
1034
+ this.billing = new BillingClient(this.http, tokens);
1035
+ this.workspaces = new WorkspacesClient(this.http, tokens);
1036
+ this.audit = new AuditClient(this.http, tokens);
1037
+ this.webhooks = new WebhooksClient(this.http, tokens);
1038
+ this.customers = new CustomersClient(this.http, tokens);
1039
+ }
1040
+ };
1041
+
1042
+ // src/modules/config-admin.ts
1043
+ function envQuery(environment) {
1044
+ return environment ? `?environment=${encodeURIComponent(environment)}` : "";
1045
+ }
1046
+ var ConfigAdminClient = class {
1047
+ http;
1048
+ adminToken;
1049
+ constructor(opts) {
1050
+ this.http = new HttpClient(opts.baseUrl);
1051
+ this.adminToken = opts.adminToken;
1052
+ }
1053
+ // ── Config ───────────────────────────────────────────────────────────────
1054
+ listConfig(environment) {
1055
+ return this.http.request({
1056
+ method: "GET",
1057
+ path: `/admin/config${envQuery(environment)}`,
1058
+ token: this.adminToken
1059
+ });
1060
+ }
1061
+ getConfig(key, environment) {
1062
+ return this.http.request({
1063
+ method: "GET",
1064
+ path: `/admin/config/${key}${envQuery(environment)}`,
1065
+ token: this.adminToken
1066
+ });
1067
+ }
1068
+ setConfig(key, input, environment) {
1069
+ return this.http.request({
1070
+ method: "PUT",
1071
+ path: `/admin/config/${key}${envQuery(environment)}`,
1072
+ body: input,
1073
+ token: this.adminToken
1074
+ });
1075
+ }
1076
+ deleteConfig(key, environment) {
1077
+ return this.http.request({
1078
+ method: "DELETE",
1079
+ path: `/admin/config/${key}${envQuery(environment)}`,
1080
+ token: this.adminToken
1081
+ });
1082
+ }
1083
+ listConfigRevisions(key, environment) {
1084
+ return this.http.request({
1085
+ method: "GET",
1086
+ path: `/admin/config/${key}/revisions${envQuery(environment)}`,
1087
+ token: this.adminToken
1088
+ });
1089
+ }
1090
+ rollbackConfig(key, input, environment) {
1091
+ return this.http.request({
1092
+ method: "POST",
1093
+ path: `/admin/config/${key}/rollback${envQuery(environment)}`,
1094
+ body: input,
1095
+ token: this.adminToken
1096
+ });
1097
+ }
1098
+ // ── Secrets (masked) ─────────────────────────────────────────────────────
1099
+ listSecrets(environment) {
1100
+ return this.http.request({
1101
+ method: "GET",
1102
+ path: `/admin/secrets${envQuery(environment)}`,
1103
+ token: this.adminToken
1104
+ });
1105
+ }
1106
+ getSecret(key, environment) {
1107
+ return this.http.request({
1108
+ method: "GET",
1109
+ path: `/admin/secrets/${key}${envQuery(environment)}`,
1110
+ token: this.adminToken
1111
+ });
1112
+ }
1113
+ setSecret(key, input, environment) {
1114
+ return this.http.request({
1115
+ method: "PUT",
1116
+ path: `/admin/secrets/${key}${envQuery(environment)}`,
1117
+ body: input,
1118
+ token: this.adminToken
1119
+ });
1120
+ }
1121
+ deleteSecret(key, environment) {
1122
+ return this.http.request({
1123
+ method: "DELETE",
1124
+ path: `/admin/secrets/${key}${envQuery(environment)}`,
1125
+ token: this.adminToken
1126
+ });
1127
+ }
1128
+ listSecretRevisions(key, environment) {
1129
+ return this.http.request({
1130
+ method: "GET",
1131
+ path: `/admin/secrets/${key}/revisions${envQuery(environment)}`,
1132
+ token: this.adminToken
1133
+ });
1134
+ }
1135
+ rollbackSecret(key, input, environment) {
1136
+ return this.http.request({
1137
+ method: "POST",
1138
+ path: `/admin/secrets/${key}/rollback${envQuery(environment)}`,
1139
+ body: input,
1140
+ token: this.adminToken
1141
+ });
1142
+ }
1143
+ // POST (not GET) so the decrypted value never lands in a URL or access log.
1144
+ revealSecret(key, environment) {
1145
+ return this.http.request({
1146
+ method: "POST",
1147
+ path: `/admin/secrets/${key}/reveal${envQuery(environment)}`,
1148
+ token: this.adminToken
1149
+ });
1150
+ }
1151
+ };
1152
+
1153
+ // src/modules/courier-admin.ts
1154
+ var CourierAdminClient = class {
196
1155
  http;
1156
+ adminToken;
197
1157
  constructor(opts) {
198
1158
  this.http = new HttpClient(opts.baseUrl);
199
- this.auth = new AuthClient(this.http, opts.accessToken);
1159
+ this.adminToken = opts.adminToken;
1160
+ }
1161
+ listTemplates() {
1162
+ return this.http.request({
1163
+ method: "GET",
1164
+ path: "/admin/templates",
1165
+ token: this.adminToken
1166
+ });
1167
+ }
1168
+ getTemplate(type, locale) {
1169
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
1170
+ return this.http.request({
1171
+ method: "GET",
1172
+ path: `/admin/templates/${type}${q}`,
1173
+ token: this.adminToken
1174
+ });
1175
+ }
1176
+ setTemplate(type, input, locale) {
1177
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
1178
+ return this.http.request({
1179
+ method: "PUT",
1180
+ path: `/admin/templates/${type}${q}`,
1181
+ body: input,
1182
+ token: this.adminToken
1183
+ });
1184
+ }
1185
+ deleteTemplate(type, locale) {
1186
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
1187
+ return this.http.request({
1188
+ method: "DELETE",
1189
+ path: `/admin/templates/${type}${q}`,
1190
+ token: this.adminToken
1191
+ });
1192
+ }
1193
+ listRevisions(type, locale) {
1194
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
1195
+ return this.http.request({
1196
+ method: "GET",
1197
+ path: `/admin/templates/${type}/revisions${q}`,
1198
+ token: this.adminToken
1199
+ });
1200
+ }
1201
+ rollback(type, input, locale) {
1202
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
1203
+ return this.http.request({
1204
+ method: "POST",
1205
+ path: `/admin/templates/${type}/rollback${q}`,
1206
+ body: input,
1207
+ token: this.adminToken
1208
+ });
200
1209
  }
201
1210
  };
202
1211
  export {
1212
+ AuditClient,
203
1213
  AuthClient,
1214
+ BillingClient,
1215
+ ConfigAdminClient,
1216
+ CourierAdminClient,
1217
+ CustomersClient,
204
1218
  FonderieApiError,
205
- FonderieClient
1219
+ FonderieClient,
1220
+ WebhooksClient,
1221
+ WorkspacesClient
206
1222
  };
207
1223
  //# sourceMappingURL=index.js.map