@behio/storefront-sdk 0.3.0 → 0.5.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 +2 -1
- package/dist/{chunk-45FTJKSW.mjs → chunk-3GOQSB25.mjs} +229 -69
- package/dist/{chunk-ZEPWNT56.js → chunk-KRGDHGTY.js} +232 -72
- package/dist/index.d.mts +334 -90
- package/dist/index.d.ts +334 -90
- package/dist/index.js +8 -2
- package/dist/index.mjs +9 -3
- package/dist/react.d.mts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +80 -64
- package/dist/react.mjs +79 -63
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,7 +83,8 @@ function ProductList() {
|
|
|
83
83
|
| `customer` | Profile, addresses, password change |
|
|
84
84
|
| `wishlist` | Add, remove, check |
|
|
85
85
|
| `reviews` | Submit, list, vote helpful |
|
|
86
|
-
| `addresses` |
|
|
86
|
+
| `addresses` | Address autocomplete with debounce hook |
|
|
87
|
+
| `shipping` | List shipping methods and fetch live carrier quotes (Zaslat.cz + extensible) |
|
|
87
88
|
| `returns` | Submit return requests |
|
|
88
89
|
| `consent` | Cookie consent (GDPR) |
|
|
89
90
|
| `quotes` | B2B quote requests |
|
|
@@ -72,6 +72,40 @@ var BehioNetworkError = class extends Error {
|
|
|
72
72
|
this.code = isTimeout ? "TIMEOUT" : "NETWORK_ERROR";
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
+
function ok(data) {
|
|
76
|
+
return { data, error: null };
|
|
77
|
+
}
|
|
78
|
+
function err(error) {
|
|
79
|
+
return { data: null, error };
|
|
80
|
+
}
|
|
81
|
+
function toSdkError(err2) {
|
|
82
|
+
if (err2 instanceof BehioApiError) {
|
|
83
|
+
return {
|
|
84
|
+
code: err2.code,
|
|
85
|
+
message: err2.message,
|
|
86
|
+
status: err2.status,
|
|
87
|
+
body: err2.body,
|
|
88
|
+
isRetryable: err2.isRetryable,
|
|
89
|
+
cause: err2
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (err2 instanceof BehioNetworkError) {
|
|
93
|
+
return {
|
|
94
|
+
code: err2.code,
|
|
95
|
+
message: err2.message,
|
|
96
|
+
status: null,
|
|
97
|
+
isRetryable: err2.isRetryable,
|
|
98
|
+
cause: err2
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
code: "UNKNOWN",
|
|
103
|
+
message: err2 instanceof Error ? err2.message : String(err2),
|
|
104
|
+
status: null,
|
|
105
|
+
isRetryable: false,
|
|
106
|
+
cause: err2
|
|
107
|
+
};
|
|
108
|
+
}
|
|
75
109
|
|
|
76
110
|
// src/client.ts
|
|
77
111
|
var BehioStorefront = class {
|
|
@@ -108,6 +142,7 @@ var BehioStorefront = class {
|
|
|
108
142
|
this.consent = new ConsentModule(this);
|
|
109
143
|
this.quotes = new QuotesModule(this);
|
|
110
144
|
this.addresses = new AddressModule(this);
|
|
145
|
+
this.shipping = new ShippingModule(this);
|
|
111
146
|
}
|
|
112
147
|
// --- Public methods ---
|
|
113
148
|
/** Get basic shop info */
|
|
@@ -197,11 +232,17 @@ var BehioStorefront = class {
|
|
|
197
232
|
this.isRefreshing = true;
|
|
198
233
|
this.refreshPromise = (async () => {
|
|
199
234
|
try {
|
|
200
|
-
await this.auth.refresh();
|
|
235
|
+
const res = await this.auth.refresh();
|
|
236
|
+
if (res.error) {
|
|
237
|
+
this.clearTokens();
|
|
238
|
+
this.emit("auth:token-refresh-failed");
|
|
239
|
+
throw new BehioApiError(401, null, "Token refresh failed");
|
|
240
|
+
}
|
|
201
241
|
this.emit("auth:token-refresh");
|
|
202
|
-
} catch {
|
|
242
|
+
} catch (err2) {
|
|
203
243
|
this.clearTokens();
|
|
204
244
|
this.emit("auth:token-refresh-failed");
|
|
245
|
+
if (err2 instanceof BehioApiError) throw err2;
|
|
205
246
|
throw new BehioApiError(401, null, "Token refresh failed");
|
|
206
247
|
} finally {
|
|
207
248
|
this.isRefreshing = false;
|
|
@@ -210,9 +251,29 @@ var BehioStorefront = class {
|
|
|
210
251
|
})();
|
|
211
252
|
return this.refreshPromise;
|
|
212
253
|
}
|
|
213
|
-
// ---
|
|
214
|
-
/**
|
|
254
|
+
// --- Public request wrapper (SdkResult) ---
|
|
255
|
+
/**
|
|
256
|
+
* Every public module method funnels through here. Internally calls
|
|
257
|
+
* `rawRequest` (which throws on failure) and maps thrown errors to
|
|
258
|
+
* `SdkError` so the public surface can return `SdkResult<T>`.
|
|
259
|
+
*
|
|
260
|
+
* @internal — don't call from outside the SDK; use the typed module
|
|
261
|
+
* methods (behio.catalog.*, behio.cart.*, …) instead.
|
|
262
|
+
*/
|
|
215
263
|
async request(method, path, options) {
|
|
264
|
+
try {
|
|
265
|
+
const data = await this.rawRequest(method, path, options);
|
|
266
|
+
return ok(data);
|
|
267
|
+
} catch (err2) {
|
|
268
|
+
return { data: null, error: toSdkError(err2) };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Throws on failure (API error / network / timeout). Kept private so
|
|
273
|
+
* internal auth refresh recursion keeps its existing control flow —
|
|
274
|
+
* public callers must go through `request()` which returns Result.
|
|
275
|
+
*/
|
|
276
|
+
async rawRequest(method, path, options) {
|
|
216
277
|
const params = new URLSearchParams();
|
|
217
278
|
if (options?.query) {
|
|
218
279
|
for (const [key, value] of Object.entries(options.query)) {
|
|
@@ -275,11 +336,11 @@ var BehioStorefront = class {
|
|
|
275
336
|
body: interceptedConfig.body,
|
|
276
337
|
signal: controller.signal
|
|
277
338
|
});
|
|
278
|
-
} catch (
|
|
339
|
+
} catch (err2) {
|
|
279
340
|
clearTimeout(timeoutId);
|
|
280
|
-
const isAbort =
|
|
341
|
+
const isAbort = err2 instanceof DOMException && err2.name === "AbortError";
|
|
281
342
|
const networkErr = new BehioNetworkError(
|
|
282
|
-
isAbort ? "Request timed out" :
|
|
343
|
+
isAbort ? "Request timed out" : err2.message || "Network error",
|
|
283
344
|
isAbort
|
|
284
345
|
);
|
|
285
346
|
this.emit("error", networkErr);
|
|
@@ -305,7 +366,7 @@ var BehioStorefront = class {
|
|
|
305
366
|
if (res.status === 401 && this.refreshToken && options?.auth !== false && !options?._isRetryAfterRefresh) {
|
|
306
367
|
try {
|
|
307
368
|
await this.handleTokenRefresh();
|
|
308
|
-
return this.
|
|
369
|
+
return this.rawRequest(method, path, { ...options, _isRetryAfterRefresh: true });
|
|
309
370
|
} catch {
|
|
310
371
|
this.emit("error", apiError);
|
|
311
372
|
throw apiError;
|
|
@@ -371,7 +432,8 @@ var CatalogModule = class {
|
|
|
371
432
|
/** Get category tree */
|
|
372
433
|
async getCategories(locale) {
|
|
373
434
|
const res = await this.client.request("GET", "/catalog/categories", { query: { locale } });
|
|
374
|
-
|
|
435
|
+
if (res.error) return res;
|
|
436
|
+
return ok({ categories: res.data.categories || res.data.items || [] });
|
|
375
437
|
}
|
|
376
438
|
/** Get category detail by slug */
|
|
377
439
|
async getCategory(slug, locale) {
|
|
@@ -392,7 +454,8 @@ var CatalogModule = class {
|
|
|
392
454
|
/** Get all labels */
|
|
393
455
|
async getLabels(locale) {
|
|
394
456
|
const res = await this.client.request("GET", "/catalog/labels", { query: { locale } });
|
|
395
|
-
|
|
457
|
+
if (res.error) return res;
|
|
458
|
+
return ok({ labels: res.data.labels || res.data.items || [] });
|
|
396
459
|
}
|
|
397
460
|
/** Get featured products */
|
|
398
461
|
async getFeatured(options) {
|
|
@@ -418,7 +481,10 @@ var CatalogModule = class {
|
|
|
418
481
|
}
|
|
419
482
|
/** Cross-sell / related / upsell products for a product */
|
|
420
483
|
async getCrossSell(productSlug) {
|
|
421
|
-
return this.client.request(
|
|
484
|
+
return this.client.request(
|
|
485
|
+
"GET",
|
|
486
|
+
`/catalog/products/${productSlug}/cross-sell`
|
|
487
|
+
);
|
|
422
488
|
}
|
|
423
489
|
/** Active promotions applicable to a product (with countdown end time) */
|
|
424
490
|
async getProductPromotions(productSlug) {
|
|
@@ -435,44 +501,57 @@ var AuthModule = class {
|
|
|
435
501
|
}
|
|
436
502
|
/** Register a new customer */
|
|
437
503
|
async register(input) {
|
|
438
|
-
const
|
|
504
|
+
const res = await this.client.request("POST", "/auth/register", {
|
|
439
505
|
body: input,
|
|
440
506
|
auth: false
|
|
441
507
|
});
|
|
442
|
-
|
|
508
|
+
if (res.error) return res;
|
|
509
|
+
this.client.setTokens(res.data);
|
|
443
510
|
this.client.emit("auth:login", { email: input.email });
|
|
444
|
-
return
|
|
511
|
+
return res;
|
|
445
512
|
}
|
|
446
513
|
/** Login with email and password */
|
|
447
514
|
async login(input) {
|
|
448
|
-
const
|
|
515
|
+
const res = await this.client.request("POST", "/auth/login", {
|
|
449
516
|
body: input,
|
|
450
517
|
auth: false
|
|
451
518
|
});
|
|
452
|
-
|
|
519
|
+
if (res.error) return res;
|
|
520
|
+
this.client.setTokens(res.data);
|
|
453
521
|
this.client.emit("auth:login", { email: input.email });
|
|
454
|
-
return
|
|
522
|
+
return res;
|
|
455
523
|
}
|
|
456
524
|
/** Refresh access token using refresh token */
|
|
457
525
|
async refresh(refreshToken) {
|
|
458
526
|
const token = refreshToken || this.client.getRefreshToken();
|
|
459
|
-
if (!token)
|
|
460
|
-
|
|
527
|
+
if (!token) {
|
|
528
|
+
return {
|
|
529
|
+
data: null,
|
|
530
|
+
error: {
|
|
531
|
+
code: "UNAUTHORIZED",
|
|
532
|
+
message: "No refresh token available",
|
|
533
|
+
status: null,
|
|
534
|
+
isRetryable: false
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
const res = await this.client.request("POST", "/auth/refresh", {
|
|
461
539
|
body: { refreshToken: token },
|
|
462
540
|
auth: false
|
|
463
541
|
});
|
|
464
|
-
|
|
465
|
-
|
|
542
|
+
if (res.error) return res;
|
|
543
|
+
this.client.setTokens(res.data);
|
|
544
|
+
return res;
|
|
466
545
|
}
|
|
467
546
|
/** Logout (invalidate refresh token) */
|
|
468
547
|
async logout(refreshToken) {
|
|
469
548
|
const token = refreshToken || this.client.getRefreshToken();
|
|
470
|
-
const
|
|
549
|
+
const res = await this.client.request("POST", "/auth/logout", {
|
|
471
550
|
body: { refreshToken: token }
|
|
472
551
|
});
|
|
473
552
|
this.client.clearTokens();
|
|
474
553
|
this.client.emit("auth:logout");
|
|
475
|
-
return
|
|
554
|
+
return res;
|
|
476
555
|
}
|
|
477
556
|
/** Request password reset email */
|
|
478
557
|
async forgotPassword(email) {
|
|
@@ -510,90 +589,124 @@ var CartModule = class {
|
|
|
510
589
|
}
|
|
511
590
|
/** Add item to cart */
|
|
512
591
|
async addItem(input) {
|
|
513
|
-
const
|
|
592
|
+
const res = await this.client.request("POST", "/cart/items", {
|
|
514
593
|
body: { whItemId: input.productId, quantity: input.quantity }
|
|
515
594
|
});
|
|
516
|
-
if (
|
|
517
|
-
|
|
595
|
+
if (res.error) return res;
|
|
596
|
+
if (res.data.newSessionToken) {
|
|
597
|
+
this.client.setCartSession(res.data.newSessionToken);
|
|
518
598
|
}
|
|
519
|
-
this.client.emit("cart:updated",
|
|
520
|
-
return
|
|
599
|
+
this.client.emit("cart:updated", res.data);
|
|
600
|
+
return res;
|
|
521
601
|
}
|
|
522
602
|
/** Update item quantity */
|
|
523
603
|
async updateQuantity(itemId, quantity) {
|
|
524
|
-
const
|
|
604
|
+
const res = await this.client.request("PATCH", `/cart/items/${itemId}`, {
|
|
525
605
|
body: { quantity }
|
|
526
606
|
});
|
|
527
|
-
|
|
528
|
-
|
|
607
|
+
if (res.error) return res;
|
|
608
|
+
this.client.emit("cart:updated", res.data);
|
|
609
|
+
return res;
|
|
529
610
|
}
|
|
530
611
|
/** Remove item from cart */
|
|
531
612
|
async removeItem(itemId) {
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
613
|
+
const res = await this.client.request("DELETE", `/cart/items/${itemId}`);
|
|
614
|
+
if (res.error) return res;
|
|
615
|
+
this.client.emit("cart:updated", res.data);
|
|
616
|
+
return res;
|
|
535
617
|
}
|
|
536
618
|
/** Clear entire cart */
|
|
537
619
|
async clear() {
|
|
538
|
-
const
|
|
620
|
+
const res = await this.client.request("DELETE", "/cart");
|
|
621
|
+
if (res.error) return res;
|
|
539
622
|
this.client.emit("cart:cleared");
|
|
540
|
-
return
|
|
623
|
+
return res;
|
|
541
624
|
}
|
|
542
625
|
/** Apply a gift card code to the cart. Balance is deducted at checkout. */
|
|
543
626
|
async applyGiftCard(code) {
|
|
544
|
-
const
|
|
627
|
+
const res = await this.client.request("POST", "/cart/gift-card", {
|
|
545
628
|
body: { code }
|
|
546
629
|
});
|
|
547
|
-
|
|
548
|
-
|
|
630
|
+
if (res.error) return res;
|
|
631
|
+
this.client.emit("cart:updated", res.data);
|
|
632
|
+
return res;
|
|
549
633
|
}
|
|
550
634
|
/** Remove a gift card from the cart */
|
|
551
635
|
async removeGiftCard() {
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
636
|
+
const res = await this.client.request("DELETE", "/cart/gift-card");
|
|
637
|
+
if (res.error) return res;
|
|
638
|
+
this.client.emit("cart:updated", res.data);
|
|
639
|
+
return res;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Add a bundle to the cart. Price is snapshotted at the bundle's current
|
|
643
|
+
* price. Pass either the bundle id or its slug — slug is more ergonomic
|
|
644
|
+
* for static storefront wiring (`behio.cart.addBundle({slug: "morning-set"})`).
|
|
645
|
+
*
|
|
646
|
+
* Respects the bundle's `minQuantity`, `maxQuantity`, and `stockLimit`:
|
|
647
|
+
* the request rejects with HTTP 400 if the resulting cart line would
|
|
648
|
+
* violate any of them. The returned error includes the relevant field
|
|
649
|
+
* (`minQuantity`, `maxQuantity`, or `remaining`) so the storefront can
|
|
650
|
+
* surface a meaningful message.
|
|
651
|
+
*
|
|
652
|
+
* @param identifier Either `{id: bundleId}` or `{slug: bundleSlug}`. As a
|
|
653
|
+
* convenience, passing a plain string is treated as the
|
|
654
|
+
* bundle id for backwards compatibility.
|
|
655
|
+
* @param quantity How many bundles to add (defaults to 1). Capped by
|
|
656
|
+
* the bundle's `maxQuantity` if set.
|
|
657
|
+
*/
|
|
658
|
+
async addBundle(identifier, quantity = 1) {
|
|
659
|
+
const body = { quantity };
|
|
660
|
+
if (typeof identifier === "string") {
|
|
661
|
+
body.bundleId = identifier;
|
|
662
|
+
} else if ("id" in identifier) {
|
|
663
|
+
body.bundleId = identifier.id;
|
|
664
|
+
} else {
|
|
665
|
+
body.bundleSlug = identifier.slug;
|
|
666
|
+
}
|
|
667
|
+
const res = await this.client.request("POST", "/cart/bundles", { body });
|
|
668
|
+
if (res.error) return res;
|
|
669
|
+
this.client.emit("cart:updated", res.data);
|
|
670
|
+
return res;
|
|
563
671
|
}
|
|
564
672
|
/** Update quantity of a bundle already in the cart */
|
|
565
673
|
async updateBundleQuantity(bundleId, quantity) {
|
|
566
|
-
const
|
|
674
|
+
const res = await this.client.request("PATCH", `/cart/bundles/${bundleId}`, {
|
|
567
675
|
body: { quantity }
|
|
568
676
|
});
|
|
569
|
-
|
|
570
|
-
|
|
677
|
+
if (res.error) return res;
|
|
678
|
+
this.client.emit("cart:updated", res.data);
|
|
679
|
+
return res;
|
|
571
680
|
}
|
|
572
681
|
/** Remove a bundle from the cart */
|
|
573
682
|
async removeBundle(bundleId) {
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
683
|
+
const res = await this.client.request("DELETE", `/cart/bundles/${bundleId}`);
|
|
684
|
+
if (res.error) return res;
|
|
685
|
+
this.client.emit("cart:updated", res.data);
|
|
686
|
+
return res;
|
|
577
687
|
}
|
|
578
688
|
/** Merge anonymous cart into authenticated customer cart */
|
|
579
689
|
async merge() {
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
690
|
+
const res = await this.client.request("POST", "/cart/merge");
|
|
691
|
+
if (res.error) return res;
|
|
692
|
+
this.client.emit("cart:updated", res.data);
|
|
693
|
+
return res;
|
|
583
694
|
}
|
|
584
695
|
/** Apply discount code */
|
|
585
696
|
async applyDiscount(code) {
|
|
586
|
-
const
|
|
697
|
+
const res = await this.client.request("POST", "/cart/discount", {
|
|
587
698
|
body: { code }
|
|
588
699
|
});
|
|
589
|
-
|
|
590
|
-
|
|
700
|
+
if (res.error) return res;
|
|
701
|
+
this.client.emit("cart:updated", res.data);
|
|
702
|
+
return res;
|
|
591
703
|
}
|
|
592
704
|
/** Remove discount code */
|
|
593
705
|
async removeDiscount() {
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
706
|
+
const res = await this.client.request("DELETE", "/cart/discount");
|
|
707
|
+
if (res.error) return res;
|
|
708
|
+
this.client.emit("cart:updated", res.data);
|
|
709
|
+
return res;
|
|
597
710
|
}
|
|
598
711
|
};
|
|
599
712
|
var CheckoutModule = class {
|
|
@@ -602,13 +715,14 @@ var CheckoutModule = class {
|
|
|
602
715
|
}
|
|
603
716
|
/** Create order from cart */
|
|
604
717
|
async createOrder(input) {
|
|
605
|
-
const
|
|
718
|
+
const res = await this.client.request("POST", "/checkout", {
|
|
606
719
|
body: input
|
|
607
720
|
});
|
|
721
|
+
if (res.error) return res;
|
|
608
722
|
this.client.clearCartSession();
|
|
609
|
-
this.client.emit("order:created",
|
|
723
|
+
this.client.emit("order:created", res.data);
|
|
610
724
|
this.client.emit("cart:cleared");
|
|
611
|
-
return
|
|
725
|
+
return res;
|
|
612
726
|
}
|
|
613
727
|
};
|
|
614
728
|
var OrdersModule = class {
|
|
@@ -760,7 +874,7 @@ var AddressModule = class {
|
|
|
760
874
|
}
|
|
761
875
|
/** Search for address suggestions (debounce on your side, or use the React hook) */
|
|
762
876
|
async autocomplete(query, country) {
|
|
763
|
-
if (!query || query.length < 2) return { suggestions: [] };
|
|
877
|
+
if (!query || query.length < 2) return ok({ suggestions: [] });
|
|
764
878
|
return this.client.request("GET", "/addresses/autocomplete", {
|
|
765
879
|
query: { q: query, country }
|
|
766
880
|
});
|
|
@@ -772,6 +886,49 @@ var AddressModule = class {
|
|
|
772
886
|
});
|
|
773
887
|
}
|
|
774
888
|
};
|
|
889
|
+
var ShippingModule = class {
|
|
890
|
+
constructor(client) {
|
|
891
|
+
this.client = client;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Return the configured shipping methods that pass the current
|
|
895
|
+
* currency + country filter. Fixed-price methods come back with
|
|
896
|
+
* their `pricing[]` row resolved; live-quote methods come back with
|
|
897
|
+
* `price` 0 here — call `quote()` to get the real live price.
|
|
898
|
+
*/
|
|
899
|
+
async listMethods(opts) {
|
|
900
|
+
const query = {};
|
|
901
|
+
if (opts?.currency) query.currency = opts.currency;
|
|
902
|
+
if (opts?.country) query.country = opts.country;
|
|
903
|
+
if (opts?.cartTotal != null) query.cartTotal = String(opts.cartTotal);
|
|
904
|
+
if (opts?.cartWeightKg != null) query.cartWeightKg = String(opts.cartWeightKg);
|
|
905
|
+
return this.client.request(
|
|
906
|
+
"GET",
|
|
907
|
+
"/catalog/shipping-methods",
|
|
908
|
+
{ query }
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Quote shipping for a destination address + cart contents. Each
|
|
913
|
+
* configured method is evaluated:
|
|
914
|
+
* - `priceStrategy="fixed"` → resolved from the merchant's per-currency
|
|
915
|
+
* `pricing[]` rows + free-shipping threshold check.
|
|
916
|
+
* - `priceStrategy="live_quote"` → dispatched to the upstream
|
|
917
|
+
* meta-provider (Zaslat, future Shippo / Sendcloud / …) and run
|
|
918
|
+
* through the merchant's markup/rounding rules.
|
|
919
|
+
*
|
|
920
|
+
* Filter `available: true` for the checkout picker; `available: false`
|
|
921
|
+
* rows carry a `reason` (`"no_rate_returned"`, `"live_quote_not_implemented"`,
|
|
922
|
+
* …) you can log but should not display.
|
|
923
|
+
*/
|
|
924
|
+
async quote(input) {
|
|
925
|
+
return this.client.request(
|
|
926
|
+
"POST",
|
|
927
|
+
"/catalog/shipping/quote",
|
|
928
|
+
{ body: input }
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
};
|
|
775
932
|
|
|
776
933
|
export {
|
|
777
934
|
ProductSort,
|
|
@@ -781,5 +938,8 @@ export {
|
|
|
781
938
|
AddressTypes,
|
|
782
939
|
BehioApiError,
|
|
783
940
|
BehioNetworkError,
|
|
941
|
+
ok,
|
|
942
|
+
err,
|
|
943
|
+
toSdkError,
|
|
784
944
|
BehioStorefront
|
|
785
945
|
};
|