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