@behio/storefront-sdk 1.9.0 → 1.18.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 +11 -9
- package/dist/{chunk-CY6D2YEI.js → chunk-GAYYRRUL.js} +178 -27
- package/dist/{chunk-XMKY4RI5.mjs → chunk-W2P2D3EZ.mjs} +154 -3
- package/dist/{client-C635vSzU.d.mts → client-B29GktSJ.d.mts} +421 -7
- package/dist/{client-C635vSzU.d.ts → client-B29GktSJ.d.ts} +421 -7
- package/dist/index.d.mts +44 -3
- package/dist/index.d.ts +44 -3
- package/dist/index.js +743 -2
- package/dist/index.mjs +742 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +2 -2
- package/dist/next.mjs +1 -1
- package/dist/react.d.mts +456 -13
- package/dist/react.d.ts +456 -13
- package/dist/react.js +339 -54
- package/dist/react.mjs +326 -46
- package/package.json +2 -2
package/dist/react.mjs
CHANGED
|
@@ -5,6 +5,38 @@ import { useRef, useEffect, useMemo, useState, useCallback } from "react";
|
|
|
5
5
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
6
6
|
|
|
7
7
|
// src/types.ts
|
|
8
|
+
var BE_CODE_TO_ERROR = {
|
|
9
|
+
"be.storefront.cartIsEmpty": "CART_EMPTY",
|
|
10
|
+
"be.storefront.productNotFound": "PRODUCT_NOT_FOUND",
|
|
11
|
+
"be.storefront.productNotAvailable": "PRODUCT_NOT_FOUND",
|
|
12
|
+
"be.storefront.invalidEmailOrPassword": "INVALID_CREDENTIALS",
|
|
13
|
+
"be.storefront.currentPasswordIncorrect": "INVALID_CREDENTIALS",
|
|
14
|
+
"be.storefront.discountExpired": "DISCOUNT_EXPIRED",
|
|
15
|
+
"be.storefront.discountExpiredOrLimit": "DISCOUNT_EXPIRED",
|
|
16
|
+
"be.storefront.invalidDiscountCode": "INVALID_DISCOUNT",
|
|
17
|
+
"be.storefront.discountInvalid": "INVALID_DISCOUNT",
|
|
18
|
+
"be.storefront.discountInactive": "INVALID_DISCOUNT",
|
|
19
|
+
"be.storefront.discountWrongCurrency": "INVALID_DISCOUNT",
|
|
20
|
+
"be.storefront.discountNotApplicable": "INVALID_DISCOUNT",
|
|
21
|
+
"be.storefront.discountNotYetValid": "INVALID_DISCOUNT",
|
|
22
|
+
"be.storefront.discountUsageLimitReached": "INVALID_DISCOUNT",
|
|
23
|
+
"be.storefront.discountLimitedToGroups": "INVALID_DISCOUNT",
|
|
24
|
+
"be.storefront.tokenInvalid": "TOKEN_INVALID",
|
|
25
|
+
"be.storefront.orderAccessTokenInvalid": "TOKEN_INVALID",
|
|
26
|
+
"be.storefront.resetTokenInvalid": "TOKEN_INVALID",
|
|
27
|
+
"be.storefront.invalidVerificationToken": "TOKEN_INVALID",
|
|
28
|
+
"be.storefront.invalidRefreshToken": "TOKEN_INVALID",
|
|
29
|
+
"be.storefront.refreshTokenExpired": "TOKEN_EXPIRED",
|
|
30
|
+
"be.storefront.apiKeyExpired": "TOKEN_EXPIRED",
|
|
31
|
+
"be.storefront.customerEmailTaken": "EMAIL_ALREADY_EXISTS",
|
|
32
|
+
"be.storefront.orderNotCancellable": "ORDER_NOT_CANCELLABLE",
|
|
33
|
+
"be.storefront.orderCancelledNotReturnable": "ORDER_NOT_CANCELLABLE",
|
|
34
|
+
"be.validation.failed": "VALIDATION_ERROR",
|
|
35
|
+
"be.forms.formNotFound": "NOT_FOUND",
|
|
36
|
+
"be.forms.validationFailed": "VALIDATION_ERROR",
|
|
37
|
+
"be.forms.consentRequired": "VALIDATION_ERROR",
|
|
38
|
+
"be.forms.tooLarge": "VALIDATION_ERROR"
|
|
39
|
+
};
|
|
8
40
|
var BehioApiError = class _BehioApiError extends Error {
|
|
9
41
|
constructor(status, body, message) {
|
|
10
42
|
super(message || `API Error ${status}`);
|
|
@@ -21,6 +53,11 @@ var BehioApiError = class _BehioApiError extends Error {
|
|
|
21
53
|
if (status === 409) return "EMAIL_ALREADY_EXISTS";
|
|
22
54
|
if (status === 429) return "RATE_LIMITED";
|
|
23
55
|
if (status >= 500) return "INTERNAL_ERROR";
|
|
56
|
+
const rawCode = body?.code;
|
|
57
|
+
if (typeof rawCode === "string") {
|
|
58
|
+
const mapped = BE_CODE_TO_ERROR[rawCode];
|
|
59
|
+
if (mapped) return mapped;
|
|
60
|
+
}
|
|
24
61
|
const msg = (body?.message || "").toLowerCase();
|
|
25
62
|
if (msg.includes("invalid") && msg.includes("password"))
|
|
26
63
|
return "INVALID_CREDENTIALS";
|
|
@@ -126,6 +163,8 @@ var BehioStorefront = class {
|
|
|
126
163
|
this.orders = new OrdersModule(this);
|
|
127
164
|
this.customer = new CustomerModule(this);
|
|
128
165
|
this.pages = new PagesModule(this);
|
|
166
|
+
this.blog = new BlogModule(this);
|
|
167
|
+
this.forms = new FormsModule(this);
|
|
129
168
|
this.wishlist = new WishlistModule(this);
|
|
130
169
|
this.reviews = new ReviewsModule(this);
|
|
131
170
|
this.returns = new ReturnsModule(this);
|
|
@@ -574,6 +613,7 @@ var CatalogModule = class {
|
|
|
574
613
|
if (query.priceMin) q.priceMin = query.priceMin;
|
|
575
614
|
if (query.priceMax) q.priceMax = query.priceMax;
|
|
576
615
|
if (query.currency) q.currency = query.currency;
|
|
616
|
+
if (query.country) q.country = query.country;
|
|
577
617
|
if (query.locale) q.locale = query.locale;
|
|
578
618
|
if (query.sort) q.sort = query.sort;
|
|
579
619
|
if (query.inStock !== void 0) q.inStock = query.inStock;
|
|
@@ -606,7 +646,7 @@ var CatalogModule = class {
|
|
|
606
646
|
"GET",
|
|
607
647
|
`/catalog/products/${slug}`,
|
|
608
648
|
{
|
|
609
|
-
query: { locale: options?.locale, currency: options?.currency }
|
|
649
|
+
query: { locale: options?.locale, currency: options?.currency, country: options?.country }
|
|
610
650
|
}
|
|
611
651
|
);
|
|
612
652
|
}
|
|
@@ -828,16 +868,27 @@ var CatalogModule = class {
|
|
|
828
868
|
{ body: input }
|
|
829
869
|
);
|
|
830
870
|
}
|
|
831
|
-
/**
|
|
871
|
+
/**
|
|
872
|
+
* List configured payment methods (filtered by currency). `locale` picks the
|
|
873
|
+
* language of `instruments[].label` / `swifts[].label` (SDK 1.14.0); pass the
|
|
874
|
+
* locale of the page so the instrument tiles read in the shopper's language.
|
|
875
|
+
*/
|
|
832
876
|
async listPaymentMethods(opts) {
|
|
833
877
|
const query = {};
|
|
834
878
|
if (opts?.currency) query.currency = opts.currency;
|
|
879
|
+
if (opts?.locale) query.locale = opts.locale;
|
|
880
|
+
if (opts?.country) query.country = opts.country;
|
|
881
|
+
if (opts?.shippingMethodId) query.shippingMethodId = opts.shippingMethodId;
|
|
835
882
|
return this.client.request(
|
|
836
883
|
"GET",
|
|
837
884
|
"/catalog/payment-methods",
|
|
838
885
|
{ query }
|
|
839
886
|
);
|
|
840
887
|
}
|
|
888
|
+
/** Alias of `listPaymentMethods` (SDK 1.14.0). */
|
|
889
|
+
paymentMethods(opts) {
|
|
890
|
+
return this.listPaymentMethods(opts);
|
|
891
|
+
}
|
|
841
892
|
};
|
|
842
893
|
var AuthModule = class {
|
|
843
894
|
constructor(client) {
|
|
@@ -991,6 +1042,26 @@ var CartModule = class {
|
|
|
991
1042
|
this.client.emit("cart:updated", res.data);
|
|
992
1043
|
return res;
|
|
993
1044
|
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Tell the cart where the order will ship (and, for B2B, the buyer's VAT
|
|
1047
|
+
* ID) so the VAT breakdown matches the checkout before the address form:
|
|
1048
|
+
* destination-country rate (OSS), 0 % export outside the EU, or reverse
|
|
1049
|
+
* charge for an EU business with a VIES-valid VAT ID. `cart.vatMode` says
|
|
1050
|
+
* which rule applied. SDK 1.17.0.
|
|
1051
|
+
*
|
|
1052
|
+
* ```ts
|
|
1053
|
+
* await client.cart.setDestination({ country: "SK" });
|
|
1054
|
+
* await client.cart.setDestination({ vatId: "SK2020000001" }); // "" clears
|
|
1055
|
+
* ```
|
|
1056
|
+
*/
|
|
1057
|
+
async setDestination(input) {
|
|
1058
|
+
const res = await this.client.request("PUT", "/cart/destination", {
|
|
1059
|
+
body: input
|
|
1060
|
+
});
|
|
1061
|
+
if (res.error) return res;
|
|
1062
|
+
this.client.emit("cart:updated", res.data);
|
|
1063
|
+
return res;
|
|
1064
|
+
}
|
|
994
1065
|
/** Update item quantity */
|
|
995
1066
|
async updateQuantity(itemId, quantity) {
|
|
996
1067
|
const res = await this.client.request(
|
|
@@ -1142,6 +1213,30 @@ var OrdersModule = class {
|
|
|
1142
1213
|
constructor(client) {
|
|
1143
1214
|
this.client = client;
|
|
1144
1215
|
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Ask the backend to re-check this order's payment with the gateway.
|
|
1218
|
+
*
|
|
1219
|
+
* Call it on the thank-you page the customer lands on after paying, BEFORE
|
|
1220
|
+
* you read the order. Some gateways (Tatrapay+) have no server-to-server
|
|
1221
|
+
* notification at all, so the customer's return is the only fast way the
|
|
1222
|
+
* payment gets confirmed; for the others it is a safety net for a lost
|
|
1223
|
+
* notification.
|
|
1224
|
+
*
|
|
1225
|
+
* The response is deliberately opaque (`{ok: true}` every time, even for an
|
|
1226
|
+
* order number that does not exist): order numbers are sequential, so
|
|
1227
|
+
* anything else would turn this into a probe for other people's orders.
|
|
1228
|
+
* Read the actual state afterwards through a path that proves entitlement
|
|
1229
|
+
* ({@link get}, {@link track} or the guest access-code flow).
|
|
1230
|
+
*
|
|
1231
|
+
* Never throws for a missing order and never blocks the page: treat a
|
|
1232
|
+
* failure as "not confirmed yet", the backend poller catches up on its own.
|
|
1233
|
+
*/
|
|
1234
|
+
async syncPaymentOnReturn(orderNumber) {
|
|
1235
|
+
return this.client.request(
|
|
1236
|
+
"POST",
|
|
1237
|
+
`/payments/return/${orderNumber}`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1145
1240
|
/** List customer orders (requires auth) */
|
|
1146
1241
|
async list(options) {
|
|
1147
1242
|
return this.client.request(
|
|
@@ -1268,7 +1363,10 @@ var CustomerModule = class {
|
|
|
1268
1363
|
body: address
|
|
1269
1364
|
});
|
|
1270
1365
|
}
|
|
1271
|
-
/**
|
|
1366
|
+
/**
|
|
1367
|
+
* Update address. Partial: `{isDefault: true}` alone is a valid body. A
|
|
1368
|
+
* changed `vatId` or `country` re-runs the VIES check on the server.
|
|
1369
|
+
*/
|
|
1272
1370
|
async updateAddress(addressId, data) {
|
|
1273
1371
|
return this.client.request(
|
|
1274
1372
|
"PATCH",
|
|
@@ -1494,6 +1592,59 @@ var PagesModule = class {
|
|
|
1494
1592
|
});
|
|
1495
1593
|
}
|
|
1496
1594
|
};
|
|
1595
|
+
var BlogModule = class {
|
|
1596
|
+
constructor(client) {
|
|
1597
|
+
this.client = client;
|
|
1598
|
+
}
|
|
1599
|
+
/** List the site's blogs (active only). */
|
|
1600
|
+
async list(locale) {
|
|
1601
|
+
return this.client.request("GET", "/blogs", {
|
|
1602
|
+
query: { locale }
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
/** Published posts of one blog, newest first (featured first), paginated. */
|
|
1606
|
+
async posts(handle, query = {}) {
|
|
1607
|
+
return this.client.request("GET", `/blogs/${handle}/posts`, {
|
|
1608
|
+
query: {
|
|
1609
|
+
locale: query.locale,
|
|
1610
|
+
page: query.page,
|
|
1611
|
+
limit: query.limit,
|
|
1612
|
+
tag: query.tag
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
/** One published post with sanitised HTML content and related posts. */
|
|
1617
|
+
async post(handle, slug, locale) {
|
|
1618
|
+
return this.client.request("GET", `/blogs/${handle}/posts/${slug}`, {
|
|
1619
|
+
query: { locale }
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1623
|
+
var FormsModule = class {
|
|
1624
|
+
constructor(client) {
|
|
1625
|
+
this.client = client;
|
|
1626
|
+
}
|
|
1627
|
+
/** Public definition of one form (fields + settings). 404 for an unknown or inactive slug. */
|
|
1628
|
+
async get(slug) {
|
|
1629
|
+
return this.client.request(
|
|
1630
|
+
"GET",
|
|
1631
|
+
`/forms/${encodeURIComponent(slug)}`
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Submit a response. On `be.forms.validationFailed` the returned error
|
|
1636
|
+
* carries per-field codes: read them with `formFieldErrors(error)`. Other
|
|
1637
|
+
* rejections: `be.forms.consentRequired`, `be.forms.tooLarge`,
|
|
1638
|
+
* `be.forms.formNotFound`; rate limit 10 submits per minute per visitor.
|
|
1639
|
+
*/
|
|
1640
|
+
async submit(slug, input) {
|
|
1641
|
+
return this.client.request(
|
|
1642
|
+
"POST",
|
|
1643
|
+
`/forms/${encodeURIComponent(slug)}/submit`,
|
|
1644
|
+
{ body: input, auth: false }
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1497
1648
|
var WishlistModule = class {
|
|
1498
1649
|
constructor(client) {
|
|
1499
1650
|
this.client = client;
|
|
@@ -3081,9 +3232,10 @@ import { useQuery as useQuery25 } from "@tanstack/react-query";
|
|
|
3081
3232
|
function usePaymentMethods(options) {
|
|
3082
3233
|
const { client, currency: activeCurrency } = useBehio();
|
|
3083
3234
|
const currency = options?.currency ?? activeCurrency;
|
|
3235
|
+
const locale = options?.locale;
|
|
3084
3236
|
const { data, isLoading, error, refetch } = useQuery25({
|
|
3085
|
-
queryKey: ["behio", "payment-methods", currency ?? ""],
|
|
3086
|
-
queryFn: () => unwrap(client.catalog.listPaymentMethods({ currency })),
|
|
3237
|
+
queryKey: ["behio", "payment-methods", currency ?? "", locale ?? ""],
|
|
3238
|
+
queryFn: () => unwrap(client.catalog.listPaymentMethods({ currency, ...locale ? { locale } : {} })),
|
|
3087
3239
|
enabled: options?.enabled !== false
|
|
3088
3240
|
});
|
|
3089
3241
|
return { methods: data?.items ?? [], isLoading, error, refetch };
|
|
@@ -3461,11 +3613,134 @@ function usePage(slug, locale, options) {
|
|
|
3461
3613
|
});
|
|
3462
3614
|
}
|
|
3463
3615
|
|
|
3464
|
-
// src/react/hooks/use-
|
|
3616
|
+
// src/react/hooks/use-blog.ts
|
|
3465
3617
|
import { useQuery as useQuery30 } from "@tanstack/react-query";
|
|
3466
|
-
function
|
|
3618
|
+
function useBlogs(locale, options) {
|
|
3467
3619
|
const { client } = useBehio();
|
|
3468
3620
|
return useQuery30({
|
|
3621
|
+
queryKey: ["behio", "blogs", locale],
|
|
3622
|
+
queryFn: async () => {
|
|
3623
|
+
const result = await unwrap(client.blog.list(locale));
|
|
3624
|
+
return result.blogs;
|
|
3625
|
+
},
|
|
3626
|
+
enabled: options?.enabled !== false
|
|
3627
|
+
});
|
|
3628
|
+
}
|
|
3629
|
+
function useBlogPosts(handle, query, options) {
|
|
3630
|
+
const { client } = useBehio();
|
|
3631
|
+
return useQuery30({
|
|
3632
|
+
queryKey: ["behio", "blog", handle, "posts", query?.locale, query?.page, query?.limit, query?.tag],
|
|
3633
|
+
queryFn: () => unwrap(client.blog.posts(handle, query)),
|
|
3634
|
+
enabled: options?.enabled !== false && !!handle
|
|
3635
|
+
});
|
|
3636
|
+
}
|
|
3637
|
+
function useBlogPost(handle, slug, locale, options) {
|
|
3638
|
+
const { client } = useBehio();
|
|
3639
|
+
return useQuery30({
|
|
3640
|
+
queryKey: ["behio", "blog", handle, "post", slug, locale],
|
|
3641
|
+
queryFn: () => unwrap(client.blog.post(handle, slug, locale)),
|
|
3642
|
+
enabled: options?.enabled !== false && !!handle && !!slug
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3646
|
+
// src/react/hooks/use-site-form.ts
|
|
3647
|
+
import { useCallback as useCallback15, useMemo as useMemo4 } from "react";
|
|
3648
|
+
import { useMutation as useMutation15, useQuery as useQuery31 } from "@tanstack/react-query";
|
|
3649
|
+
|
|
3650
|
+
// src/errors.ts
|
|
3651
|
+
function bodyOf(err) {
|
|
3652
|
+
const body = err instanceof BehioApiError ? err.body : err && typeof err === "object" && "body" in err ? err.body : err;
|
|
3653
|
+
return body && typeof body === "object" ? body : null;
|
|
3654
|
+
}
|
|
3655
|
+
function errorCode(err) {
|
|
3656
|
+
const body = bodyOf(err);
|
|
3657
|
+
if (!body) return null;
|
|
3658
|
+
const code = body.code ?? body.key;
|
|
3659
|
+
return typeof code === "string" && code.startsWith("be.") ? code : null;
|
|
3660
|
+
}
|
|
3661
|
+
function errorParams(err) {
|
|
3662
|
+
const body = bodyOf(err);
|
|
3663
|
+
const params = body?.params;
|
|
3664
|
+
return params && typeof params === "object" && !Array.isArray(params) ? params : {};
|
|
3665
|
+
}
|
|
3666
|
+
var FORM_FIELD_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3667
|
+
"required",
|
|
3668
|
+
"invalid",
|
|
3669
|
+
"tooShort",
|
|
3670
|
+
"tooLong",
|
|
3671
|
+
"min",
|
|
3672
|
+
"max",
|
|
3673
|
+
"notOption",
|
|
3674
|
+
"pattern"
|
|
3675
|
+
]);
|
|
3676
|
+
function formFieldErrors(err) {
|
|
3677
|
+
if (errorCode(err) !== "be.forms.validationFailed") return [];
|
|
3678
|
+
const raw = errorParams(err).errors;
|
|
3679
|
+
if (!Array.isArray(raw)) return [];
|
|
3680
|
+
const out = [];
|
|
3681
|
+
for (const entry of raw) {
|
|
3682
|
+
if (typeof entry !== "string") continue;
|
|
3683
|
+
const idx = entry.lastIndexOf(":");
|
|
3684
|
+
if (idx <= 0) continue;
|
|
3685
|
+
const key = entry.slice(0, idx);
|
|
3686
|
+
const code = entry.slice(idx + 1);
|
|
3687
|
+
if (!FORM_FIELD_ERROR_CODES.has(code)) continue;
|
|
3688
|
+
out.push({ key, code });
|
|
3689
|
+
}
|
|
3690
|
+
return out;
|
|
3691
|
+
}
|
|
3692
|
+
|
|
3693
|
+
// src/react/hooks/use-site-form.ts
|
|
3694
|
+
function useSiteForm(slug, options) {
|
|
3695
|
+
const { client } = useBehio();
|
|
3696
|
+
return useQuery31({
|
|
3697
|
+
queryKey: ["behio", "form", slug],
|
|
3698
|
+
queryFn: () => unwrap(client.forms.get(slug)),
|
|
3699
|
+
enabled: options?.enabled !== false && !!slug
|
|
3700
|
+
});
|
|
3701
|
+
}
|
|
3702
|
+
function useSiteFormSubmit(slug) {
|
|
3703
|
+
const { client } = useBehio();
|
|
3704
|
+
const mutation = useMutation15({
|
|
3705
|
+
mutationFn: (input) => unwrap(client.forms.submit(slug, input))
|
|
3706
|
+
});
|
|
3707
|
+
const sdkError = mutation.error instanceof UnwrappedError ? mutation.error.sdkError : null;
|
|
3708
|
+
const fieldErrors = useMemo4(() => {
|
|
3709
|
+
const out = {};
|
|
3710
|
+
for (const e of formFieldErrors(sdkError)) out[e.key] = e.code;
|
|
3711
|
+
return out;
|
|
3712
|
+
}, [sdkError]);
|
|
3713
|
+
const errorCode2 = useMemo4(() => {
|
|
3714
|
+
const body = sdkError?.body;
|
|
3715
|
+
const code = body?.code ?? body?.key;
|
|
3716
|
+
return typeof code === "string" ? code : sdkError ? sdkError.code : null;
|
|
3717
|
+
}, [sdkError]);
|
|
3718
|
+
const submit = useCallback15(
|
|
3719
|
+
(input) => mutation.mutateAsync(input).catch(() => null),
|
|
3720
|
+
[mutation]
|
|
3721
|
+
);
|
|
3722
|
+
return {
|
|
3723
|
+
/** Resolves to the result, or null when the submit was rejected (see `fieldErrors` / `errorCode`). */
|
|
3724
|
+
submit,
|
|
3725
|
+
isSubmitting: mutation.isPending,
|
|
3726
|
+
isSuccess: mutation.isSuccess,
|
|
3727
|
+
/** `{ok, id, message, redirectUrl}` after a successful submit. */
|
|
3728
|
+
result: mutation.data ?? null,
|
|
3729
|
+
/** Field key -> validation code after a rejected submit. */
|
|
3730
|
+
fieldErrors,
|
|
3731
|
+
/** Backend error key (`be.forms.*`) or SDK code when the rejection is not per field. */
|
|
3732
|
+
errorCode: errorCode2,
|
|
3733
|
+
/** Raw SDK error (pass to `errorMessage(error, locale)` for a sentence). */
|
|
3734
|
+
error: sdkError,
|
|
3735
|
+
reset: mutation.reset
|
|
3736
|
+
};
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
// src/react/hooks/use-shop-info.ts
|
|
3740
|
+
import { useQuery as useQuery32 } from "@tanstack/react-query";
|
|
3741
|
+
function useShopInfo(options) {
|
|
3742
|
+
const { client } = useBehio();
|
|
3743
|
+
return useQuery32({
|
|
3469
3744
|
queryKey: ["behio", "shop-info"],
|
|
3470
3745
|
queryFn: () => unwrap(client.getShopInfo()),
|
|
3471
3746
|
enabled: options?.enabled !== false
|
|
@@ -3473,10 +3748,10 @@ function useShopInfo(options) {
|
|
|
3473
3748
|
}
|
|
3474
3749
|
|
|
3475
3750
|
// src/react/hooks/use-shop-scripts.ts
|
|
3476
|
-
import { useQuery as
|
|
3751
|
+
import { useQuery as useQuery33 } from "@tanstack/react-query";
|
|
3477
3752
|
function useShopScripts(options) {
|
|
3478
3753
|
const { client } = useBehio();
|
|
3479
|
-
return
|
|
3754
|
+
return useQuery33({
|
|
3480
3755
|
queryKey: ["behio", "shop-scripts"],
|
|
3481
3756
|
queryFn: () => unwrap(client.getShopScripts()),
|
|
3482
3757
|
enabled: options?.enabled !== false
|
|
@@ -3484,11 +3759,11 @@ function useShopScripts(options) {
|
|
|
3484
3759
|
}
|
|
3485
3760
|
|
|
3486
3761
|
// src/react/hooks/use-shop-seo.ts
|
|
3487
|
-
import { useQuery as
|
|
3762
|
+
import { useQuery as useQuery34 } from "@tanstack/react-query";
|
|
3488
3763
|
function useShopSeo(options) {
|
|
3489
3764
|
const { client } = useBehio();
|
|
3490
3765
|
const { locale, initialData, enabled = true } = options ?? {};
|
|
3491
|
-
return
|
|
3766
|
+
return useQuery34({
|
|
3492
3767
|
queryKey: ["behio", "shop-seo", locale ?? "_default"],
|
|
3493
3768
|
queryFn: () => unwrap(client.getShopSeo(locale)),
|
|
3494
3769
|
initialData,
|
|
@@ -3548,23 +3823,23 @@ function CurrencySwitcher({
|
|
|
3548
3823
|
}
|
|
3549
3824
|
|
|
3550
3825
|
// src/react/components/storefront-scripts.tsx
|
|
3551
|
-
import { useEffect as useEffect6, useMemo as
|
|
3826
|
+
import { useEffect as useEffect6, useMemo as useMemo5, useState as useState10 } from "react";
|
|
3552
3827
|
|
|
3553
3828
|
// src/react/hooks/use-consent.ts
|
|
3554
|
-
import { useQuery as
|
|
3829
|
+
import { useQuery as useQuery35, useMutation as useMutation16, useQueryClient as useQueryClient16 } from "@tanstack/react-query";
|
|
3555
3830
|
function useCookieConsent(visitorId) {
|
|
3556
3831
|
const { client } = useBehio();
|
|
3557
3832
|
const qc = useQueryClient16();
|
|
3558
|
-
const query =
|
|
3833
|
+
const query = useQuery35({
|
|
3559
3834
|
queryKey: ["behio", "consent", visitorId],
|
|
3560
3835
|
queryFn: () => unwrap(client.consent.get(visitorId)),
|
|
3561
3836
|
enabled: Boolean(visitorId)
|
|
3562
3837
|
});
|
|
3563
|
-
const recordMutation =
|
|
3838
|
+
const recordMutation = useMutation16({
|
|
3564
3839
|
mutationFn: (input) => unwrap(client.consent.record(input)),
|
|
3565
3840
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "consent"] })
|
|
3566
3841
|
});
|
|
3567
|
-
const revokeMutation =
|
|
3842
|
+
const revokeMutation = useMutation16({
|
|
3568
3843
|
mutationFn: () => unwrap(client.consent.revoke(visitorId)),
|
|
3569
3844
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "consent"] })
|
|
3570
3845
|
});
|
|
@@ -3649,11 +3924,11 @@ function StorefrontScripts({ visitorId: visitorIdProp } = {}) {
|
|
|
3649
3924
|
}, [visitorIdProp]);
|
|
3650
3925
|
const { data: consent } = useCookieConsent(visitorId || void 0);
|
|
3651
3926
|
const analyticsOk = Boolean(consent?.analytics);
|
|
3652
|
-
const scripts =
|
|
3927
|
+
const scripts = useMemo5(
|
|
3653
3928
|
() => (data?.scripts ?? []).filter((s) => !s.consentRequired || analyticsOk),
|
|
3654
3929
|
[data, analyticsOk]
|
|
3655
3930
|
);
|
|
3656
|
-
const signature =
|
|
3931
|
+
const signature = useMemo5(
|
|
3657
3932
|
() => JSON.stringify(scripts.map((s) => [s.id, s.type, s.placement, s.value])),
|
|
3658
3933
|
[scripts]
|
|
3659
3934
|
);
|
|
@@ -3923,10 +4198,10 @@ function utmFromSearch(search) {
|
|
|
3923
4198
|
}
|
|
3924
4199
|
|
|
3925
4200
|
// src/react/hooks/use-bundles.ts
|
|
3926
|
-
import { useQuery as
|
|
4201
|
+
import { useQuery as useQuery36 } from "@tanstack/react-query";
|
|
3927
4202
|
function useBundles(options) {
|
|
3928
4203
|
const { client } = useBehio();
|
|
3929
|
-
return
|
|
4204
|
+
return useQuery36({
|
|
3930
4205
|
queryKey: ["behio", "bundles"],
|
|
3931
4206
|
queryFn: () => unwrap(client.catalog.getBundles()),
|
|
3932
4207
|
enabled: options?.enabled ?? true,
|
|
@@ -3935,7 +4210,7 @@ function useBundles(options) {
|
|
|
3935
4210
|
}
|
|
3936
4211
|
function useBundle(slug, options) {
|
|
3937
4212
|
const { client } = useBehio();
|
|
3938
|
-
return
|
|
4213
|
+
return useQuery36({
|
|
3939
4214
|
queryKey: ["behio", "bundle", slug],
|
|
3940
4215
|
queryFn: () => unwrap(client.catalog.getBundle(slug)),
|
|
3941
4216
|
enabled: Boolean(slug) && (options?.enabled ?? true),
|
|
@@ -3944,10 +4219,10 @@ function useBundle(slug, options) {
|
|
|
3944
4219
|
}
|
|
3945
4220
|
|
|
3946
4221
|
// src/react/hooks/use-product-group.ts
|
|
3947
|
-
import { useQuery as
|
|
4222
|
+
import { useQuery as useQuery37 } from "@tanstack/react-query";
|
|
3948
4223
|
function useProductGroup(slug, options) {
|
|
3949
4224
|
const { client } = useBehio();
|
|
3950
|
-
return
|
|
4225
|
+
return useQuery37({
|
|
3951
4226
|
queryKey: ["behio", "product-group", slug, options?.locale, options?.currency],
|
|
3952
4227
|
queryFn: () => unwrap(
|
|
3953
4228
|
client.catalog.getProductGroup(slug, {
|
|
@@ -3961,10 +4236,10 @@ function useProductGroup(slug, options) {
|
|
|
3961
4236
|
}
|
|
3962
4237
|
|
|
3963
4238
|
// src/react/hooks/use-cross-sell.ts
|
|
3964
|
-
import { useQuery as
|
|
4239
|
+
import { useQuery as useQuery38 } from "@tanstack/react-query";
|
|
3965
4240
|
function useCrossSell(productSlug, options) {
|
|
3966
4241
|
const { client } = useBehio();
|
|
3967
|
-
return
|
|
4242
|
+
return useQuery38({
|
|
3968
4243
|
queryKey: ["behio", "cross-sell", productSlug, options?.locale, options?.currency],
|
|
3969
4244
|
queryFn: () => unwrap(
|
|
3970
4245
|
client.catalog.getCrossSell(productSlug, {
|
|
@@ -3978,10 +4253,10 @@ function useCrossSell(productSlug, options) {
|
|
|
3978
4253
|
}
|
|
3979
4254
|
|
|
3980
4255
|
// src/react/hooks/use-product-promotions.ts
|
|
3981
|
-
import { useQuery as
|
|
4256
|
+
import { useQuery as useQuery39 } from "@tanstack/react-query";
|
|
3982
4257
|
function useProductPromotions(productSlug, options) {
|
|
3983
4258
|
const { client } = useBehio();
|
|
3984
|
-
return
|
|
4259
|
+
return useQuery39({
|
|
3985
4260
|
queryKey: ["behio", "product-promotions", productSlug],
|
|
3986
4261
|
queryFn: () => unwrap(client.catalog.getProductPromotions(productSlug)),
|
|
3987
4262
|
enabled: Boolean(productSlug) && (options?.enabled ?? true),
|
|
@@ -3990,11 +4265,11 @@ function useProductPromotions(productSlug, options) {
|
|
|
3990
4265
|
}
|
|
3991
4266
|
|
|
3992
4267
|
// src/react/hooks/use-gift-card.ts
|
|
3993
|
-
import { useQuery as
|
|
4268
|
+
import { useQuery as useQuery40 } from "@tanstack/react-query";
|
|
3994
4269
|
function useGiftCardBalance(code, options) {
|
|
3995
4270
|
const { client } = useBehio();
|
|
3996
4271
|
const trimmed = code?.trim();
|
|
3997
|
-
return
|
|
4272
|
+
return useQuery40({
|
|
3998
4273
|
queryKey: ["behio", "gift-card-balance", trimmed],
|
|
3999
4274
|
queryFn: () => unwrap(client.catalog.checkGiftCard(trimmed)),
|
|
4000
4275
|
enabled: Boolean(trimmed && trimmed.length >= 6) && (options?.enabled ?? true)
|
|
@@ -4002,20 +4277,20 @@ function useGiftCardBalance(code, options) {
|
|
|
4002
4277
|
}
|
|
4003
4278
|
|
|
4004
4279
|
// src/react/hooks/use-wishlist.ts
|
|
4005
|
-
import { useQuery as
|
|
4280
|
+
import { useQuery as useQuery41, useMutation as useMutation17, useQueryClient as useQueryClient17 } from "@tanstack/react-query";
|
|
4006
4281
|
function useWishlist(options) {
|
|
4007
4282
|
const { client } = useBehio();
|
|
4008
4283
|
const qc = useQueryClient17();
|
|
4009
|
-
const query =
|
|
4284
|
+
const query = useQuery41({
|
|
4010
4285
|
queryKey: ["behio", "wishlist"],
|
|
4011
4286
|
queryFn: () => unwrap(client.wishlist.get()),
|
|
4012
4287
|
enabled: options?.enabled ?? true
|
|
4013
4288
|
});
|
|
4014
|
-
const addMutation =
|
|
4289
|
+
const addMutation = useMutation17({
|
|
4015
4290
|
mutationFn: (productId) => unwrap(client.wishlist.add(productId)),
|
|
4016
4291
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "wishlist"] })
|
|
4017
4292
|
});
|
|
4018
|
-
const removeMutation =
|
|
4293
|
+
const removeMutation = useMutation17({
|
|
4019
4294
|
mutationFn: (productId) => unwrap(client.wishlist.remove(productId)),
|
|
4020
4295
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "wishlist"] })
|
|
4021
4296
|
});
|
|
@@ -4029,7 +4304,7 @@ function useWishlist(options) {
|
|
|
4029
4304
|
}
|
|
4030
4305
|
function useIsInWishlist(productId) {
|
|
4031
4306
|
const { client } = useBehio();
|
|
4032
|
-
return
|
|
4307
|
+
return useQuery41({
|
|
4033
4308
|
queryKey: ["behio", "wishlist-check", productId],
|
|
4034
4309
|
queryFn: () => unwrap(client.wishlist.isInWishlist(productId)),
|
|
4035
4310
|
enabled: Boolean(productId)
|
|
@@ -4037,10 +4312,10 @@ function useIsInWishlist(productId) {
|
|
|
4037
4312
|
}
|
|
4038
4313
|
|
|
4039
4314
|
// src/react/hooks/use-reviews.ts
|
|
4040
|
-
import { useQuery as
|
|
4315
|
+
import { useQuery as useQuery42, useMutation as useMutation18, useQueryClient as useQueryClient18 } from "@tanstack/react-query";
|
|
4041
4316
|
function useProductReviews(productId, options) {
|
|
4042
4317
|
const { client } = useBehio();
|
|
4043
|
-
return
|
|
4318
|
+
return useQuery42({
|
|
4044
4319
|
queryKey: ["behio", "reviews", productId, options?.page ?? 1],
|
|
4045
4320
|
queryFn: () => unwrap(client.reviews.getProductReviews(productId, options?.page, options?.limit)),
|
|
4046
4321
|
enabled: Boolean(productId) && (options?.enabled ?? true)
|
|
@@ -4049,29 +4324,29 @@ function useProductReviews(productId, options) {
|
|
|
4049
4324
|
function useSubmitReview() {
|
|
4050
4325
|
const { client } = useBehio();
|
|
4051
4326
|
const qc = useQueryClient18();
|
|
4052
|
-
return
|
|
4327
|
+
return useMutation18({
|
|
4053
4328
|
mutationFn: (input) => unwrap(client.reviews.submit(input)),
|
|
4054
4329
|
onSuccess: (_, input) => qc.invalidateQueries({ queryKey: ["behio", "reviews", input.productId] })
|
|
4055
4330
|
});
|
|
4056
4331
|
}
|
|
4057
4332
|
|
|
4058
4333
|
// src/react/hooks/use-returns.ts
|
|
4059
|
-
import { useQuery as
|
|
4334
|
+
import { useQuery as useQuery43, useMutation as useMutation19 } from "@tanstack/react-query";
|
|
4060
4335
|
function useLookupReturnableOrder() {
|
|
4061
4336
|
const { client } = useBehio();
|
|
4062
|
-
return
|
|
4337
|
+
return useMutation19({
|
|
4063
4338
|
mutationFn: ({ orderNumber, email }) => unwrap(client.returns.lookupOrder(orderNumber, email))
|
|
4064
4339
|
});
|
|
4065
4340
|
}
|
|
4066
4341
|
function useSubmitReturn() {
|
|
4067
4342
|
const { client } = useBehio();
|
|
4068
|
-
return
|
|
4343
|
+
return useMutation19({
|
|
4069
4344
|
mutationFn: (input) => unwrap(client.returns.submit(input))
|
|
4070
4345
|
});
|
|
4071
4346
|
}
|
|
4072
4347
|
function useReturnStatus(returnId, email) {
|
|
4073
4348
|
const { client } = useBehio();
|
|
4074
|
-
return
|
|
4349
|
+
return useQuery43({
|
|
4075
4350
|
queryKey: ["behio", "return-status", returnId],
|
|
4076
4351
|
queryFn: () => unwrap(client.returns.getStatus(returnId, email)),
|
|
4077
4352
|
enabled: Boolean(returnId && email)
|
|
@@ -4079,16 +4354,16 @@ function useReturnStatus(returnId, email) {
|
|
|
4079
4354
|
}
|
|
4080
4355
|
|
|
4081
4356
|
// src/react/hooks/use-quotes.ts
|
|
4082
|
-
import { useMutation as
|
|
4357
|
+
import { useMutation as useMutation20, useQuery as useQuery44 } from "@tanstack/react-query";
|
|
4083
4358
|
function useSubmitQuote() {
|
|
4084
4359
|
const { client } = useBehio();
|
|
4085
|
-
return
|
|
4360
|
+
return useMutation20({
|
|
4086
4361
|
mutationFn: (input) => unwrap(client.quotes.submit(input))
|
|
4087
4362
|
});
|
|
4088
4363
|
}
|
|
4089
4364
|
function useQuoteStatus(quoteId, email) {
|
|
4090
4365
|
const { client } = useBehio();
|
|
4091
|
-
return
|
|
4366
|
+
return useQuery44({
|
|
4092
4367
|
queryKey: ["behio", "quote-status", quoteId],
|
|
4093
4368
|
queryFn: () => unwrap(client.quotes.getStatus(quoteId, email)),
|
|
4094
4369
|
enabled: Boolean(quoteId && email)
|
|
@@ -4096,10 +4371,10 @@ function useQuoteStatus(quoteId, email) {
|
|
|
4096
4371
|
}
|
|
4097
4372
|
|
|
4098
4373
|
// src/react/hooks/use-back-in-stock.ts
|
|
4099
|
-
import { useMutation as
|
|
4374
|
+
import { useMutation as useMutation21 } from "@tanstack/react-query";
|
|
4100
4375
|
function useNotifyWhenAvailable() {
|
|
4101
4376
|
const { client } = useBehio();
|
|
4102
|
-
return
|
|
4377
|
+
return useMutation21({
|
|
4103
4378
|
mutationFn: ({ productId, email }) => unwrap(client.catalog.notifyWhenAvailable(productId, email))
|
|
4104
4379
|
});
|
|
4105
4380
|
}
|
|
@@ -4235,6 +4510,9 @@ export {
|
|
|
4235
4510
|
useAuth,
|
|
4236
4511
|
useBehio,
|
|
4237
4512
|
useBehioClient,
|
|
4513
|
+
useBlogPost,
|
|
4514
|
+
useBlogPosts,
|
|
4515
|
+
useBlogs,
|
|
4238
4516
|
useBundle,
|
|
4239
4517
|
useBundles,
|
|
4240
4518
|
useCart,
|
|
@@ -4288,6 +4566,8 @@ export {
|
|
|
4288
4566
|
useShopInfo,
|
|
4289
4567
|
useShopScripts,
|
|
4290
4568
|
useShopSeo,
|
|
4569
|
+
useSiteForm,
|
|
4570
|
+
useSiteFormSubmit,
|
|
4291
4571
|
useSubmitQuote,
|
|
4292
4572
|
useSubmitReturn,
|
|
4293
4573
|
useSubmitReview,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@behio/storefront-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "TypeScript SDK for Behio
|
|
3
|
+
"version": "1.18.0",
|
|
4
|
+
"description": "TypeScript SDK for Behio headless e-commerce: core client + React hooks",
|
|
5
5
|
"author": "Behio",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "./dist/index.js",
|