@ledewire/browser 0.6.0 → 0.7.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
@@ -1,6 +1,6 @@
1
- var d = Object.defineProperty;
2
- var g = (s, e, t) => e in s ? d(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var n = (s, e, t) => g(s, typeof e != "symbol" ? e + "" : e, t);
1
+ var f = Object.defineProperty;
2
+ var k = (s, e, t) => e in s ? f(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var n = (s, e, t) => k(s, typeof e != "symbol" ? e + "" : e, t);
4
4
  function w(s) {
5
5
  return atob(s);
6
6
  }
@@ -28,33 +28,33 @@ class l extends c {
28
28
  super(e, 401, t), this.name = "AuthError";
29
29
  }
30
30
  }
31
- class k extends c {
31
+ class y extends c {
32
32
  constructor(e, t) {
33
33
  super(e, 403, t), this.name = "ForbiddenError";
34
34
  }
35
35
  }
36
- class f extends c {
36
+ class T extends c {
37
37
  constructor(e, t) {
38
38
  super(e, 404, t), this.name = "NotFoundError";
39
39
  }
40
40
  }
41
- class B extends c {
41
+ class M extends c {
42
42
  constructor(e, t, r) {
43
43
  super(e, t, r), this.name = "PurchaseError";
44
44
  }
45
45
  }
46
- const T = "https://api.ledewire.com";
47
- class y {
46
+ const d = "https://api.ledewire.com";
47
+ class m {
48
48
  constructor(e = {}) {
49
49
  n(this, "baseUrl");
50
50
  n(this, "getAccessToken");
51
51
  n(this, "onUnauthorized");
52
- this.baseUrl = (e.baseUrl ?? T).replace(/\/$/, ""), this.getAccessToken = e.getAccessToken ?? (() => null), this.onUnauthorized = e.onUnauthorized ?? (() => null);
52
+ this.baseUrl = (e.baseUrl ?? d).replace(/\/$/, ""), this.getAccessToken = e.getAccessToken ?? (() => null), this.onUnauthorized = e.onUnauthorized ?? (() => null);
53
53
  }
54
54
  /**
55
55
  * GET request with optional query parameters.
56
56
  * @param path - API path (e.g. `/v1/wallet/balance`)
57
- * @param params - Query string parameters
57
+ * @param params - Query string parameters. `undefined` values are omitted; numbers are coerced to strings.
58
58
  */
59
59
  async get(e, t) {
60
60
  return this.request("GET", this.buildUrl(e, t));
@@ -63,9 +63,10 @@ class y {
63
63
  * POST request.
64
64
  * @param path - API path
65
65
  * @param body - Request body (JSON-serialized)
66
+ * @param params - Optional query string parameters. `undefined` values are omitted; numbers are coerced to strings.
66
67
  */
67
- async post(e, t) {
68
- return this.request("POST", this.buildUrl(e), t);
68
+ async post(e, t, r) {
69
+ return this.request("POST", this.buildUrl(e, r), t);
69
70
  }
70
71
  /**
71
72
  * PUT request.
@@ -95,7 +96,13 @@ class y {
95
96
  // ---------------------------------------------------------------------------
96
97
  buildUrl(e, t) {
97
98
  const r = `${this.baseUrl}${e}`;
98
- return !t || Object.keys(t).length === 0 ? r : `${r}?${new URLSearchParams(t).toString()}`;
99
+ if (!t) return r;
100
+ const o = Object.entries(t).filter(
101
+ (i) => i[1] !== void 0
102
+ );
103
+ if (o.length === 0) return r;
104
+ const h = new URLSearchParams(o.map(([i, a]) => [i, String(a)]));
105
+ return `${r}?${h.toString()}`;
99
106
  }
100
107
  async request(e, t, r, o = !1) {
101
108
  const h = await this.getAccessToken(), i = {
@@ -127,15 +134,15 @@ class y {
127
134
  case 401:
128
135
  throw new l(r, o);
129
136
  case 403:
130
- throw new k(r, o);
137
+ throw new y(r, o);
131
138
  case 404:
132
- throw new f(r, o);
139
+ throw new T(r, o);
133
140
  default:
134
141
  throw new c(r, e.status, o);
135
142
  }
136
143
  }
137
144
  }
138
- const m = 6e4;
145
+ const A = 6e4;
139
146
  class E {
140
147
  constructor(e) {
141
148
  n(this, "storage");
@@ -151,7 +158,7 @@ class E {
151
158
  */
152
159
  async getAccessToken() {
153
160
  const e = await this.storage.getTokens();
154
- return e ? e.expiresAt - Date.now() < m ? (await this.performRefresh(e.refreshToken))?.accessToken ?? null : e.accessToken : null;
161
+ return e ? e.expiresAt - Date.now() < A ? (await this.performRefresh(e.refreshToken))?.accessToken ?? null : e.accessToken : null;
155
162
  }
156
163
  /**
157
164
  * Called by `HttpClient` when a 401 is received.
@@ -183,7 +190,7 @@ class E {
183
190
  }), this.refreshPromise);
184
191
  }
185
192
  }
186
- class A {
193
+ class U {
187
194
  constructor() {
188
195
  n(this, "tokens", null);
189
196
  }
@@ -200,7 +207,23 @@ class A {
200
207
  function p(s) {
201
208
  return new Date(s).getTime();
202
209
  }
203
- class S {
210
+ function v(s) {
211
+ return async (e) => {
212
+ const t = await fetch(`${s}/v1/auth/token/refresh`, {
213
+ method: "POST",
214
+ headers: { "Content-Type": "application/json" },
215
+ body: JSON.stringify({ refresh_token: e })
216
+ });
217
+ if (!t.ok) throw new Error("Token refresh failed");
218
+ const r = await t.json();
219
+ return {
220
+ accessToken: r.access_token,
221
+ refreshToken: r.refresh_token,
222
+ expiresAt: p(r.expires_at)
223
+ };
224
+ };
225
+ }
226
+ class x {
204
227
  /** @internal */
205
228
  constructor(e, t) {
206
229
  this.http = e, this.tokenManager = t;
@@ -238,6 +261,29 @@ class S {
238
261
  const t = await this.http.post("/v1/auth/login/google", e);
239
262
  return await this.storeTokens(t), t;
240
263
  }
264
+ /**
265
+ * Log in using a buyer API key and secret.
266
+ * Returns a buyer-scoped JWT, stored automatically after successful authentication.
267
+ *
268
+ * Primarily useful when building buyer-facing dashboards where the user
269
+ * has created a named API key and wishes to authenticate with it programmatically,
270
+ * or for agent workflows running inside a browser context.
271
+ *
272
+ * @param body - The buyer API key and secret.
273
+ * @returns The authentication token response.
274
+ *
275
+ * @example
276
+ * ```ts
277
+ * await lw.auth.loginWithBuyerApiKey({
278
+ * key: 'bktst_abc123',
279
+ * secret: 'deadbeef...',
280
+ * })
281
+ * ```
282
+ */
283
+ async loginWithBuyerApiKey(e) {
284
+ const t = await this.http.post("/v1/auth/login/buyer-api-key", e);
285
+ return await this.storeTokens(t), t;
286
+ }
241
287
  /**
242
288
  * Request a password reset code to be sent to the buyer's email address.
243
289
  *
@@ -284,7 +330,7 @@ class S {
284
330
  });
285
331
  }
286
332
  }
287
- class v {
333
+ class b {
288
334
  /** @internal */
289
335
  constructor(e) {
290
336
  this.http = e;
@@ -307,7 +353,7 @@ class v {
307
353
  return this.http.get("/v1/config/public");
308
354
  }
309
355
  }
310
- class x {
356
+ class S {
311
357
  constructor(e) {
312
358
  this.http = e;
313
359
  }
@@ -329,11 +375,13 @@ class x {
329
375
  * ```
330
376
  */
331
377
  async getWithAccess(e) {
332
- const t = await this.http.get(`/v1/content/${e}/with-access`);
378
+ const t = await this.http.get(
379
+ `/v1/content/${encodeURIComponent(e)}/with-access`
380
+ );
333
381
  return u(t);
334
382
  }
335
383
  }
336
- class b {
384
+ class P {
337
385
  constructor(e) {
338
386
  this.http = e;
339
387
  }
@@ -361,10 +409,10 @@ class b {
361
409
  * @returns The purchase record.
362
410
  */
363
411
  async get(e) {
364
- return this.http.get(`/v1/purchases/${e}`);
412
+ return this.http.get(`/v1/purchases/${encodeURIComponent(e)}`);
365
413
  }
366
414
  }
367
- class U {
415
+ class R {
368
416
  /** @internal */
369
417
  constructor(e) {
370
418
  this.http = e;
@@ -420,16 +468,16 @@ class U {
420
468
  * ```
421
469
  */
422
470
  async get(e) {
423
- const t = await this.http.get(`/v1/seller/content/${e}`);
471
+ const t = await this.http.get(`/v1/seller/content/${encodeURIComponent(e)}`);
424
472
  return u(t);
425
473
  }
426
474
  }
427
- class P {
475
+ class C {
428
476
  /** @internal */
429
477
  constructor(e, t) {
430
478
  /** Seller content: list, search, and get by API key. */
431
479
  n(this, "content");
432
- this.http = e, this.tokenManager = t, this.content = new U(e);
480
+ this.http = e, this.tokenManager = t, this.content = new R(e);
433
481
  }
434
482
  /**
435
483
  * Log in using an API key to obtain a seller token.
@@ -496,10 +544,12 @@ class N {
496
544
  * @returns The current payment status.
497
545
  */
498
546
  async getPaymentStatus(e) {
499
- return this.http.get(`/v1/wallet/payment-status/${e}`);
547
+ return this.http.get(
548
+ `/v1/wallet/payment-status/${encodeURIComponent(e)}`
549
+ );
500
550
  }
501
551
  }
502
- class _ {
552
+ class F {
503
553
  constructor(e) {
504
554
  this.http = e;
505
555
  }
@@ -515,35 +565,84 @@ class _ {
515
565
  * @returns The checkout state, including what action is required next.
516
566
  */
517
567
  async state(e) {
518
- return this.http.get(`/v1/checkout/state/${e}`);
568
+ return this.http.get(
569
+ `/v1/checkout/state/${encodeURIComponent(e)}`
570
+ );
519
571
  }
520
572
  }
521
- function q(s) {
522
- const e = s.baseUrl ?? "https://api.ledewire.com", t = s.storage ?? new A(), r = new E({
573
+ class _ {
574
+ /** @internal */
575
+ constructor(e) {
576
+ this.http = e;
577
+ }
578
+ /**
579
+ * Returns all buyer API keys for the authenticated user.
580
+ * The `secret` is never included in list responses.
581
+ *
582
+ * @returns Array of API key records.
583
+ */
584
+ async list() {
585
+ return this.http.get("/v1/user/api-keys");
586
+ }
587
+ /**
588
+ * Creates a new buyer API key.
589
+ *
590
+ * The `secret` in the response is shown exactly once and cannot be retrieved
591
+ * again. Store it immediately in a secrets manager before discarding the
592
+ * response object.
593
+ *
594
+ * @param body - Name and optional spend ceiling for the new key.
595
+ * @returns The new key's public identifier and one-time secret.
596
+ *
597
+ * @example
598
+ * ```ts
599
+ * const { key, secret } = await client.user.apiKeys.create({
600
+ * name: 'production-agent',
601
+ * spending_limit_cents: 5000, // $50 cap
602
+ * })
603
+ * // ⚠️ Store secret NOW — it is shown once only
604
+ * process.env.LEDEWIRE_BUYER_SECRET = secret
605
+ * ```
606
+ */
607
+ async create(e) {
608
+ return this.http.post("/v1/user/api-keys", e);
609
+ }
610
+ /**
611
+ * Revokes (permanently deletes) a buyer API key by ID.
612
+ *
613
+ * Any agent currently using this key will receive `401` on its next
614
+ * token refresh. Revocation takes effect immediately.
615
+ *
616
+ * @param id - UUID of the API key to revoke.
617
+ */
618
+ async revoke(e) {
619
+ return this.http.delete(`/v1/user/api-keys/${encodeURIComponent(e)}`);
620
+ }
621
+ }
622
+ class $ {
623
+ /** @internal */
624
+ constructor(e) {
625
+ /**
626
+ * Buyer API key management: create, list, and revoke named API keys.
627
+ * Keys are used by autonomous agents to authenticate without a username/password.
628
+ */
629
+ n(this, "apiKeys");
630
+ this.apiKeys = new _(e);
631
+ }
632
+ }
633
+ function j(s) {
634
+ const e = s.baseUrl ?? d, t = s.storage ?? new U(), r = new E({
523
635
  storage: t,
524
- refreshFn: async (h) => {
525
- const i = await fetch(`${e}/v1/auth/token/refresh`, {
526
- method: "POST",
527
- headers: { "Content-Type": "application/json" },
528
- body: JSON.stringify({ refresh_token: h })
529
- });
530
- if (!i.ok) throw new Error("Token refresh failed");
531
- const a = await i.json();
532
- return {
533
- accessToken: a.access_token,
534
- refreshToken: a.refresh_token,
535
- expiresAt: p(a.expires_at)
536
- };
537
- },
636
+ refreshFn: v(e),
538
637
  ...s.onAuthExpired !== void 0 && { onAuthExpired: s.onAuthExpired }
539
- }), o = new y({
638
+ }), o = new m({
540
639
  baseUrl: e,
541
640
  getAccessToken: () => r.getAccessToken(),
542
641
  onUnauthorized: () => r.handleUnauthorized()
543
642
  });
544
- return new R(o, r, s);
643
+ return new B(o, r, s);
545
644
  }
546
- class R {
645
+ class B {
547
646
  /** @internal */
548
647
  constructor(e, t, r) {
549
648
  /** Platform-level public configuration (no auth required) */
@@ -560,59 +659,47 @@ class R {
560
659
  n(this, "content");
561
660
  /** Seller operations: API key login, content list/search/get */
562
661
  n(this, "seller");
563
- this._http = e, this._tokenManager = t, this._config = r, this.config = new v(e), this.auth = new S(e, t), this.checkout = new _(e), this.wallet = new N(e), this.purchases = new b(e), this.content = new x(e), this.seller = new P(e, t);
662
+ /** Authenticated buyer account: API key management */
663
+ n(this, "user");
664
+ this._http = e, this._tokenManager = t, this._config = r, this.config = new b(e), this.auth = new x(e, t), this.checkout = new F(e), this.wallet = new N(e), this.purchases = new P(e), this.content = new S(e), this.seller = new C(e, t), this.user = new $(e);
564
665
  }
565
666
  }
566
- const F = "lw:tokens";
567
- function L(s = F) {
667
+ const I = "lw:tokens";
668
+ function g(s, e = I) {
568
669
  return {
569
670
  getTokens() {
570
- const e = localStorage.getItem(s);
571
- if (!e) return null;
671
+ const t = s.getItem(e);
672
+ if (!t) return null;
572
673
  try {
573
- return JSON.parse(e);
674
+ return JSON.parse(t);
574
675
  } catch {
575
676
  return null;
576
677
  }
577
678
  },
578
- setTokens(e) {
579
- localStorage.setItem(s, JSON.stringify(e));
679
+ setTokens(t) {
680
+ s.setItem(e, JSON.stringify(t));
580
681
  },
581
682
  clearTokens() {
582
- localStorage.removeItem(s);
683
+ s.removeItem(e);
583
684
  }
584
685
  };
585
686
  }
586
- const O = "lw:tokens";
587
- function M(s = O) {
588
- return {
589
- getTokens() {
590
- const e = sessionStorage.getItem(s);
591
- if (!e) return null;
592
- try {
593
- return JSON.parse(e);
594
- } catch {
595
- return null;
596
- }
597
- },
598
- setTokens(e) {
599
- sessionStorage.setItem(s, JSON.stringify(e));
600
- },
601
- clearTokens() {
602
- sessionStorage.removeItem(s);
603
- }
604
- };
687
+ function z(s) {
688
+ return g(localStorage, s);
689
+ }
690
+ function L(s) {
691
+ return g(sessionStorage, s);
605
692
  }
606
693
  export {
607
694
  l as AuthError,
608
- k as ForbiddenError,
695
+ y as ForbiddenError,
609
696
  c as LedewireError,
610
- A as MemoryTokenStorage,
611
- f as NotFoundError,
612
- B as PurchaseError,
613
- q as init,
614
- L as localStorageAdapter,
697
+ U as MemoryTokenStorage,
698
+ T as NotFoundError,
699
+ M as PurchaseError,
700
+ j as init,
701
+ z as localStorageAdapter,
615
702
  p as parseExpiresAt,
616
- M as sessionStorageAdapter
703
+ L as sessionStorageAdapter
617
704
  };
618
705
  //# sourceMappingURL=index.js.map