@ledewire/browser 0.4.0 → 0.6.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/README.md +20 -15
- package/dist/index.d.ts +195 -40
- package/dist/index.js +165 -77
- package/dist/index.js.map +1 -1
- package/dist/ledewire.min.js +1 -1
- package/dist/ledewire.min.js.map +1 -1
- package/llms.txt +30 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var n = (s, e, t) =>
|
|
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);
|
|
4
|
+
function w(s) {
|
|
5
|
+
return atob(s);
|
|
6
|
+
}
|
|
7
|
+
function u(s) {
|
|
8
|
+
return {
|
|
9
|
+
...s,
|
|
10
|
+
...typeof s.content_body == "string" && {
|
|
11
|
+
content_body: w(s.content_body)
|
|
12
|
+
},
|
|
13
|
+
...typeof s.teaser == "string" && { teaser: w(s.teaser) }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
4
16
|
class c extends Error {
|
|
5
17
|
constructor(t, r, o) {
|
|
6
18
|
super(t);
|
|
@@ -11,33 +23,33 @@ class c extends Error {
|
|
|
11
23
|
this.name = "LedewireError", this.statusCode = r, this.code = o, Object.setPrototypeOf(this, new.target.prototype);
|
|
12
24
|
}
|
|
13
25
|
}
|
|
14
|
-
class
|
|
26
|
+
class l extends c {
|
|
15
27
|
constructor(e, t) {
|
|
16
28
|
super(e, 401, t), this.name = "AuthError";
|
|
17
29
|
}
|
|
18
30
|
}
|
|
19
|
-
class
|
|
31
|
+
class k extends c {
|
|
20
32
|
constructor(e, t) {
|
|
21
33
|
super(e, 403, t), this.name = "ForbiddenError";
|
|
22
34
|
}
|
|
23
35
|
}
|
|
24
|
-
class
|
|
36
|
+
class f extends c {
|
|
25
37
|
constructor(e, t) {
|
|
26
38
|
super(e, 404, t), this.name = "NotFoundError";
|
|
27
39
|
}
|
|
28
40
|
}
|
|
29
|
-
class
|
|
41
|
+
class B extends c {
|
|
30
42
|
constructor(e, t, r) {
|
|
31
43
|
super(e, t, r), this.name = "PurchaseError";
|
|
32
44
|
}
|
|
33
45
|
}
|
|
34
|
-
const
|
|
35
|
-
class
|
|
46
|
+
const T = "https://api.ledewire.com";
|
|
47
|
+
class y {
|
|
36
48
|
constructor(e = {}) {
|
|
37
49
|
n(this, "baseUrl");
|
|
38
50
|
n(this, "getAccessToken");
|
|
39
51
|
n(this, "onUnauthorized");
|
|
40
|
-
this.baseUrl = (e.baseUrl ??
|
|
52
|
+
this.baseUrl = (e.baseUrl ?? T).replace(/\/$/, ""), this.getAccessToken = e.getAccessToken ?? (() => null), this.onUnauthorized = e.onUnauthorized ?? (() => null);
|
|
41
53
|
}
|
|
42
54
|
/**
|
|
43
55
|
* GET request with optional query parameters.
|
|
@@ -99,7 +111,7 @@ class f {
|
|
|
99
111
|
if (a.status === 401 && !o) {
|
|
100
112
|
if (await this.onUnauthorized())
|
|
101
113
|
return this.request(e, t, r, !0);
|
|
102
|
-
throw new
|
|
114
|
+
throw new l("Session expired. Please re-authenticate.");
|
|
103
115
|
}
|
|
104
116
|
if (a.ok || await this.throwApiError(a), a.status !== 204)
|
|
105
117
|
return a.json();
|
|
@@ -113,18 +125,18 @@ class f {
|
|
|
113
125
|
const r = t?.error.message ?? e.statusText, o = t?.error.code;
|
|
114
126
|
switch (e.status) {
|
|
115
127
|
case 401:
|
|
116
|
-
throw new
|
|
128
|
+
throw new l(r, o);
|
|
117
129
|
case 403:
|
|
118
|
-
throw new
|
|
130
|
+
throw new k(r, o);
|
|
119
131
|
case 404:
|
|
120
|
-
throw new
|
|
132
|
+
throw new f(r, o);
|
|
121
133
|
default:
|
|
122
134
|
throw new c(r, e.status, o);
|
|
123
135
|
}
|
|
124
136
|
}
|
|
125
137
|
}
|
|
126
|
-
const
|
|
127
|
-
class
|
|
138
|
+
const m = 6e4;
|
|
139
|
+
class E {
|
|
128
140
|
constructor(e) {
|
|
129
141
|
n(this, "storage");
|
|
130
142
|
n(this, "refreshFn");
|
|
@@ -139,7 +151,7 @@ class y {
|
|
|
139
151
|
*/
|
|
140
152
|
async getAccessToken() {
|
|
141
153
|
const e = await this.storage.getTokens();
|
|
142
|
-
return e ? e.expiresAt - Date.now() <
|
|
154
|
+
return e ? e.expiresAt - Date.now() < m ? (await this.performRefresh(e.refreshToken))?.accessToken ?? null : e.accessToken : null;
|
|
143
155
|
}
|
|
144
156
|
/**
|
|
145
157
|
* Called by `HttpClient` when a 401 is received.
|
|
@@ -165,13 +177,13 @@ class y {
|
|
|
165
177
|
// ---------------------------------------------------------------------------
|
|
166
178
|
performRefresh(e) {
|
|
167
179
|
return this.refreshPromise ? this.refreshPromise : (this.refreshPromise = this.refreshFn(e).then(async (t) => (await this.storage.setTokens(t), await this.onTokenRefreshed?.(t), t)).catch((t) => {
|
|
168
|
-
throw this.storage.clearTokens(), new
|
|
180
|
+
throw this.storage.clearTokens(), new l("Token refresh failed. Please re-authenticate.");
|
|
169
181
|
}).finally(() => {
|
|
170
182
|
this.refreshPromise = null;
|
|
171
183
|
}), this.refreshPromise);
|
|
172
184
|
}
|
|
173
185
|
}
|
|
174
|
-
class
|
|
186
|
+
class A {
|
|
175
187
|
constructor() {
|
|
176
188
|
n(this, "tokens", null);
|
|
177
189
|
}
|
|
@@ -185,10 +197,10 @@ class m {
|
|
|
185
197
|
this.tokens = null;
|
|
186
198
|
}
|
|
187
199
|
}
|
|
188
|
-
function
|
|
200
|
+
function p(s) {
|
|
189
201
|
return new Date(s).getTime();
|
|
190
202
|
}
|
|
191
|
-
class
|
|
203
|
+
class S {
|
|
192
204
|
/** @internal */
|
|
193
205
|
constructor(e, t) {
|
|
194
206
|
this.http = e, this.tokenManager = t;
|
|
@@ -227,38 +239,52 @@ class E {
|
|
|
227
239
|
return await this.storeTokens(t), t;
|
|
228
240
|
}
|
|
229
241
|
/**
|
|
230
|
-
*
|
|
231
|
-
* Provide only `key` for read-only (`view`) access.
|
|
232
|
-
* Provide both `key` and `secret` for read/write (`full`) access.
|
|
233
|
-
* Tokens are stored automatically after successful authentication.
|
|
242
|
+
* Request a password reset code to be sent to the buyer's email address.
|
|
234
243
|
*
|
|
235
|
-
*
|
|
244
|
+
* The response is intentionally ambiguous — if the email does not exist,
|
|
245
|
+
* the API returns the same success message to prevent account enumeration.
|
|
236
246
|
*
|
|
237
|
-
* @param body -
|
|
238
|
-
* @returns
|
|
247
|
+
* @param body - The buyer's email address.
|
|
248
|
+
* @returns A response with a confirmation message.
|
|
239
249
|
*
|
|
240
250
|
* @example
|
|
241
251
|
* ```ts
|
|
242
|
-
*
|
|
243
|
-
*
|
|
252
|
+
* await lw.auth.requestPasswordReset({ email: 'buyer@example.com' })
|
|
253
|
+
* // → { data: { message: 'If an account with this email exists, a reset code has been sent.' } }
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
async requestPasswordReset(e) {
|
|
257
|
+
return this.http.post("/v1/auth/password/reset-request", e);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Reset a buyer's password using the code delivered to their email.
|
|
244
261
|
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
262
|
+
* Obtain the reset code first by calling `requestPasswordReset()`.
|
|
263
|
+
*
|
|
264
|
+
* @param body - Email address, 6-digit reset code, and the new password.
|
|
265
|
+
* @returns A response with a confirmation message.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```ts
|
|
269
|
+
* await lw.auth.resetPassword({
|
|
270
|
+
* email: 'buyer@example.com',
|
|
271
|
+
* reset_code: '123456',
|
|
272
|
+
* password: 'new-secure-password',
|
|
273
|
+
* })
|
|
247
274
|
* ```
|
|
248
275
|
*/
|
|
249
|
-
async
|
|
250
|
-
|
|
251
|
-
return await this.storeTokens(t), t;
|
|
276
|
+
async resetPassword(e) {
|
|
277
|
+
return this.http.post("/v1/auth/password/reset", e);
|
|
252
278
|
}
|
|
253
279
|
async storeTokens(e) {
|
|
254
280
|
await this.tokenManager.setTokens({
|
|
255
281
|
accessToken: e.access_token,
|
|
256
282
|
refreshToken: e.refresh_token,
|
|
257
|
-
expiresAt:
|
|
283
|
+
expiresAt: p(e.expires_at)
|
|
258
284
|
});
|
|
259
285
|
}
|
|
260
286
|
}
|
|
261
|
-
class
|
|
287
|
+
class v {
|
|
262
288
|
/** @internal */
|
|
263
289
|
constructor(e) {
|
|
264
290
|
this.http = e;
|
|
@@ -281,7 +307,7 @@ class A {
|
|
|
281
307
|
return this.http.get("/v1/config/public");
|
|
282
308
|
}
|
|
283
309
|
}
|
|
284
|
-
class
|
|
310
|
+
class x {
|
|
285
311
|
constructor(e) {
|
|
286
312
|
this.http = e;
|
|
287
313
|
}
|
|
@@ -290,18 +316,24 @@ class v {
|
|
|
290
316
|
* authenticated buyer (or a generic access response when unauthenticated).
|
|
291
317
|
*
|
|
292
318
|
* @param id - The content ID.
|
|
293
|
-
* @
|
|
294
|
-
*
|
|
319
|
+
* @returns The content item with access information. `content_body` and
|
|
320
|
+
* `teaser` are returned as plain UTF-8 text — the SDK decodes base64
|
|
321
|
+
* transparently so you can render them directly.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* const result = await lw.content.getWithAccess('article-123')
|
|
326
|
+
* if (result.access_info.next_required_action === 'view_content') {
|
|
327
|
+
* renderMarkdown(result.content_body ?? '')
|
|
328
|
+
* }
|
|
329
|
+
* ```
|
|
295
330
|
*/
|
|
296
|
-
async getWithAccess(e
|
|
297
|
-
const
|
|
298
|
-
return
|
|
299
|
-
`/v1/content/${e}/with-access`,
|
|
300
|
-
Object.keys(r).length > 0 ? r : void 0
|
|
301
|
-
);
|
|
331
|
+
async getWithAccess(e) {
|
|
332
|
+
const t = await this.http.get(`/v1/content/${e}/with-access`);
|
|
333
|
+
return u(t);
|
|
302
334
|
}
|
|
303
335
|
}
|
|
304
|
-
class
|
|
336
|
+
class b {
|
|
305
337
|
constructor(e) {
|
|
306
338
|
this.http = e;
|
|
307
339
|
}
|
|
@@ -341,7 +373,8 @@ class U {
|
|
|
341
373
|
* List all content for the authenticated seller's store.
|
|
342
374
|
* Requires a token with at least `view` permission.
|
|
343
375
|
*
|
|
344
|
-
* @returns Array of content items.
|
|
376
|
+
* @returns Array of content items. `teaser` is returned as plain text —
|
|
377
|
+
* the SDK decodes base64 automatically.
|
|
345
378
|
*
|
|
346
379
|
* @example
|
|
347
380
|
* ```ts
|
|
@@ -349,7 +382,7 @@ class U {
|
|
|
349
382
|
* ```
|
|
350
383
|
*/
|
|
351
384
|
async list() {
|
|
352
|
-
return this.http.get("/v1/seller/content");
|
|
385
|
+
return (await this.http.get("/v1/seller/content")).map(u);
|
|
353
386
|
}
|
|
354
387
|
/**
|
|
355
388
|
* Search content by title, URI, and/or metadata (AND logic).
|
|
@@ -357,43 +390,77 @@ class U {
|
|
|
357
390
|
* Requires a token with at least `view` permission.
|
|
358
391
|
*
|
|
359
392
|
* @param body - Search criteria (title, uri, and/or metadata).
|
|
360
|
-
* @returns Array of matching content items.
|
|
393
|
+
* @returns Array of matching content items. `teaser` is returned as plain
|
|
394
|
+
* text — the SDK decodes base64 automatically.
|
|
361
395
|
*
|
|
362
396
|
* @example
|
|
363
397
|
* ```ts
|
|
364
398
|
* const results = await lw.seller.content.search({ title: 'intro' })
|
|
365
399
|
* const byUri = await lw.seller.content.search({ uri: 'vimeo.com' })
|
|
400
|
+
* const byId = await lw.seller.content.search({ external_identifier: 'vimeo:123456789' })
|
|
366
401
|
* const byMeta = await lw.seller.content.search({ metadata: { author: 'Alice' } })
|
|
367
402
|
* ```
|
|
368
403
|
*/
|
|
369
404
|
async search(e) {
|
|
370
|
-
return this.http.post("/v1/seller/content/search", e);
|
|
405
|
+
return (await this.http.post("/v1/seller/content/search", e)).map(u);
|
|
371
406
|
}
|
|
372
407
|
/**
|
|
373
408
|
* Get a single content item by ID.
|
|
374
409
|
* Requires a token with at least `view` permission.
|
|
375
410
|
*
|
|
376
411
|
* @param id - The content ID.
|
|
377
|
-
* @returns The content item.
|
|
412
|
+
* @returns The content item. `content_body` and `teaser` are returned as
|
|
413
|
+
* plain UTF-8 text — the SDK decodes base64 automatically so you can render
|
|
414
|
+
* them directly without calling `atob()`.
|
|
378
415
|
*
|
|
379
416
|
* @example
|
|
380
417
|
* ```ts
|
|
381
418
|
* const item = await lw.seller.content.get('content-id')
|
|
419
|
+
* // item.content_body is plain markdown — no atob() needed
|
|
382
420
|
* ```
|
|
383
421
|
*/
|
|
384
422
|
async get(e) {
|
|
385
|
-
|
|
423
|
+
const t = await this.http.get(`/v1/seller/content/${e}`);
|
|
424
|
+
return u(t);
|
|
386
425
|
}
|
|
387
426
|
}
|
|
388
|
-
class
|
|
427
|
+
class P {
|
|
389
428
|
/** @internal */
|
|
390
|
-
constructor(e) {
|
|
429
|
+
constructor(e, t) {
|
|
391
430
|
/** Seller content: list, search, and get by API key. */
|
|
392
431
|
n(this, "content");
|
|
393
|
-
this.content = new U(e);
|
|
432
|
+
this.http = e, this.tokenManager = t, this.content = new U(e);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Log in using an API key to obtain a seller token.
|
|
436
|
+
* Provide only `key` for read-only (`view`) access.
|
|
437
|
+
* Provide both `key` and `secret` for read/write (`full`) access.
|
|
438
|
+
* Tokens are stored automatically after successful authentication.
|
|
439
|
+
*
|
|
440
|
+
* Use this before calling `lw.seller.content.*` methods.
|
|
441
|
+
*
|
|
442
|
+
* @param body - API key credentials.
|
|
443
|
+
* @returns The authentication token response.
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```ts
|
|
447
|
+
* // View access (read-only) — sufficient for seller.content.list/search/get
|
|
448
|
+
* await lw.seller.loginWithApiKey({ key: 'your_api_key' })
|
|
449
|
+
*
|
|
450
|
+
* // Full access (read/write)
|
|
451
|
+
* await lw.seller.loginWithApiKey({ key: 'your_api_key', secret: 'your_secret' })
|
|
452
|
+
* ```
|
|
453
|
+
*/
|
|
454
|
+
async loginWithApiKey(e) {
|
|
455
|
+
const t = await this.http.post("/v1/auth/login/api-key", e);
|
|
456
|
+
return await this.tokenManager.setTokens({
|
|
457
|
+
accessToken: t.access_token,
|
|
458
|
+
refreshToken: t.refresh_token,
|
|
459
|
+
expiresAt: p(t.expires_at)
|
|
460
|
+
}), t;
|
|
394
461
|
}
|
|
395
462
|
}
|
|
396
|
-
class
|
|
463
|
+
class N {
|
|
397
464
|
constructor(e) {
|
|
398
465
|
this.http = e;
|
|
399
466
|
}
|
|
@@ -432,7 +499,7 @@ class b {
|
|
|
432
499
|
return this.http.get(`/v1/wallet/payment-status/${e}`);
|
|
433
500
|
}
|
|
434
501
|
}
|
|
435
|
-
class
|
|
502
|
+
class _ {
|
|
436
503
|
constructor(e) {
|
|
437
504
|
this.http = e;
|
|
438
505
|
}
|
|
@@ -451,8 +518,8 @@ class P {
|
|
|
451
518
|
return this.http.get(`/v1/checkout/state/${e}`);
|
|
452
519
|
}
|
|
453
520
|
}
|
|
454
|
-
function
|
|
455
|
-
const e = s.baseUrl ?? "https://api.ledewire.com", t = s.storage ?? new
|
|
521
|
+
function q(s) {
|
|
522
|
+
const e = s.baseUrl ?? "https://api.ledewire.com", t = s.storage ?? new A(), r = new E({
|
|
456
523
|
storage: t,
|
|
457
524
|
refreshFn: async (h) => {
|
|
458
525
|
const i = await fetch(`${e}/v1/auth/token/refresh`, {
|
|
@@ -465,23 +532,23 @@ function C(s) {
|
|
|
465
532
|
return {
|
|
466
533
|
accessToken: a.access_token,
|
|
467
534
|
refreshToken: a.refresh_token,
|
|
468
|
-
expiresAt:
|
|
535
|
+
expiresAt: p(a.expires_at)
|
|
469
536
|
};
|
|
470
537
|
},
|
|
471
538
|
...s.onAuthExpired !== void 0 && { onAuthExpired: s.onAuthExpired }
|
|
472
|
-
}), o = new
|
|
539
|
+
}), o = new y({
|
|
473
540
|
baseUrl: e,
|
|
474
541
|
getAccessToken: () => r.getAccessToken(),
|
|
475
542
|
onUnauthorized: () => r.handleUnauthorized()
|
|
476
543
|
});
|
|
477
|
-
return new
|
|
544
|
+
return new R(o, r, s);
|
|
478
545
|
}
|
|
479
|
-
class
|
|
546
|
+
class R {
|
|
480
547
|
/** @internal */
|
|
481
548
|
constructor(e, t, r) {
|
|
482
549
|
/** Platform-level public configuration (no auth required) */
|
|
483
550
|
n(this, "config");
|
|
484
|
-
/** Buyer authentication: email/password signup/login, Google, password reset */
|
|
551
|
+
/** Buyer authentication: email/password signup/login, Google OAuth, password reset */
|
|
485
552
|
n(this, "auth");
|
|
486
553
|
/** Checkout state machine: determines next action for a piece of content */
|
|
487
554
|
n(this, "checkout");
|
|
@@ -491,13 +558,13 @@ class N {
|
|
|
491
558
|
n(this, "purchases");
|
|
492
559
|
/** Public content with per-user access information */
|
|
493
560
|
n(this, "content");
|
|
494
|
-
/** Seller
|
|
561
|
+
/** Seller operations: API key login, content list/search/get */
|
|
495
562
|
n(this, "seller");
|
|
496
|
-
this._http = e, this._tokenManager = t, this._config = r, this.config = new
|
|
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);
|
|
497
564
|
}
|
|
498
565
|
}
|
|
499
|
-
const
|
|
500
|
-
function
|
|
566
|
+
const F = "lw:tokens";
|
|
567
|
+
function L(s = F) {
|
|
501
568
|
return {
|
|
502
569
|
getTokens() {
|
|
503
570
|
const e = localStorage.getItem(s);
|
|
@@ -516,15 +583,36 @@ function B(s = R) {
|
|
|
516
583
|
}
|
|
517
584
|
};
|
|
518
585
|
}
|
|
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
|
+
};
|
|
605
|
+
}
|
|
519
606
|
export {
|
|
520
|
-
|
|
521
|
-
|
|
607
|
+
l as AuthError,
|
|
608
|
+
k as ForbiddenError,
|
|
522
609
|
c as LedewireError,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
610
|
+
A as MemoryTokenStorage,
|
|
611
|
+
f as NotFoundError,
|
|
612
|
+
B as PurchaseError,
|
|
613
|
+
q as init,
|
|
614
|
+
L as localStorageAdapter,
|
|
615
|
+
p as parseExpiresAt,
|
|
616
|
+
M as sessionStorageAdapter
|
|
529
617
|
};
|
|
530
618
|
//# sourceMappingURL=index.js.map
|