@behio/storefront-sdk 0.8.0 → 0.12.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/react.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  BehioStorefront
3
- } from "./chunk-EZEZUV2B.mjs";
3
+ } from "./chunk-XITY2WQN.mjs";
4
4
 
5
5
  // src/react/provider.tsx
6
- import { useRef, useEffect, useMemo } from "react";
6
+ import { useRef, useEffect, useMemo, useState, useCallback } from "react";
7
7
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
8
8
 
9
9
  // src/react/context.ts
@@ -97,7 +97,9 @@ function resolveStorage(option) {
97
97
  var STORAGE_KEYS = {
98
98
  ACCESS_TOKEN: "behio_access_token",
99
99
  REFRESH_TOKEN: "behio_refresh_token",
100
- CART_SESSION: "behio_cart_session"
100
+ CART_SESSION: "behio_cart_session",
101
+ /** Shopper's chosen currency. Cookie so SSR (getBehio) reads the same value. */
102
+ CURRENCY: "behio_currency"
101
103
  };
102
104
 
103
105
  // src/react/provider.tsx
@@ -105,20 +107,37 @@ import { jsx } from "react/jsx-runtime";
105
107
  function BehioProvider({
106
108
  apiKey,
107
109
  baseUrl,
110
+ shopDomain,
108
111
  locale,
109
112
  currency,
113
+ defaultCurrency,
114
+ currencies,
115
+ onCurrencyChange,
116
+ persistCurrency = true,
117
+ currencyCookieName = STORAGE_KEYS.CURRENCY,
110
118
  storage: storageOption,
111
119
  queryClient: externalQueryClient,
112
120
  children
113
121
  }) {
114
122
  const storageAdapter = useMemo(() => resolveStorage(storageOption), [storageOption]);
123
+ const resolveInitialCurrency = () => {
124
+ if (persistCurrency) {
125
+ const stored = cookieStorage.get(currencyCookieName);
126
+ if (stored) return stored;
127
+ }
128
+ return currency;
129
+ };
130
+ const [activeCurrency, setActiveCurrency] = useState(resolveInitialCurrency);
115
131
  const clientRef = useRef(null);
116
132
  if (!clientRef.current) {
117
133
  clientRef.current = new BehioStorefront({
118
134
  apiKey,
119
135
  baseUrl,
136
+ ...shopDomain ? { shopDomain } : {},
120
137
  locale,
121
- currency
138
+ // Seed with the resolved active currency so the very first request (even
139
+ // before effects run) carries it.
140
+ ...activeCurrency ? { currency: activeCurrency } : {}
122
141
  });
123
142
  }
124
143
  const client = clientRef.current;
@@ -133,6 +152,20 @@ function BehioProvider({
133
152
  client.setCartSession(cartSession);
134
153
  }
135
154
  }, [client, storageAdapter]);
155
+ useEffect(() => {
156
+ if (!persistCurrency) return;
157
+ const stored = cookieStorage.get(currencyCookieName);
158
+ if (stored && stored !== activeCurrency) {
159
+ setActiveCurrency(stored);
160
+ client.setCurrency(stored);
161
+ }
162
+ }, []);
163
+ useEffect(() => {
164
+ if (currency !== void 0 && currency !== activeCurrency) {
165
+ setActiveCurrency(currency);
166
+ client.setCurrency(currency);
167
+ }
168
+ }, [currency]);
136
169
  const queryClientRef = useRef(null);
137
170
  const qc = useMemo(() => {
138
171
  if (externalQueryClient) return externalQueryClient;
@@ -148,15 +181,35 @@ function BehioProvider({
148
181
  }
149
182
  return queryClientRef.current;
150
183
  }, [externalQueryClient]);
184
+ const setCurrency = useCallback(
185
+ (next) => {
186
+ setActiveCurrency(next);
187
+ client.setCurrency(next);
188
+ if (persistCurrency) {
189
+ if (next) cookieStorage.set(currencyCookieName, next);
190
+ else cookieStorage.remove(currencyCookieName);
191
+ }
192
+ onCurrencyChange?.(next);
193
+ void qc.invalidateQueries({ queryKey: ["behio"] });
194
+ },
195
+ [client, qc, persistCurrency, currencyCookieName, onCurrencyChange]
196
+ );
151
197
  const ctxValue = useMemo(
152
- () => ({ client, storage: storageAdapter }),
153
- [client, storageAdapter]
198
+ () => ({
199
+ client,
200
+ storage: storageAdapter,
201
+ currency: activeCurrency,
202
+ setCurrency,
203
+ configuredDefaultCurrency: defaultCurrency,
204
+ configuredCurrencies: currencies
205
+ }),
206
+ [client, storageAdapter, activeCurrency, setCurrency, defaultCurrency, currencies]
154
207
  );
155
208
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: qc, children: /* @__PURE__ */ jsx(BehioContext.Provider, { value: ctxValue, children }) });
156
209
  }
157
210
 
158
211
  // src/react/hooks/use-products.ts
159
- import { useCallback, useMemo as useMemo2, useState } from "react";
212
+ import { useCallback as useCallback2, useMemo as useMemo2, useState as useState2 } from "react";
160
213
  import { useInfiniteQuery } from "@tanstack/react-query";
161
214
 
162
215
  // src/react/utils/unwrap.ts
@@ -177,7 +230,7 @@ async function unwrap(p) {
177
230
  function useProducts(query) {
178
231
  const { client } = useBehio();
179
232
  const { initialData, enabled, page: initialPage, limit, ...filters } = query ?? {};
180
- const [page, setPage] = useState(initialPage ?? 1);
233
+ const [page, setPage] = useState2(initialPage ?? 1);
181
234
  const serializedFilters = useMemo2(() => JSON.stringify({ ...filters, limit }), [filters, limit]);
182
235
  const infinite = useInfiniteQuery({
183
236
  queryKey: ["behio", "products", serializedFilters, page],
@@ -194,13 +247,13 @@ function useProducts(query) {
194
247
  );
195
248
  const lastPage = infinite.data?.pages[infinite.data.pages.length - 1];
196
249
  const firstPage = infinite.data?.pages[0];
197
- const loadMore = useCallback(() => {
250
+ const loadMore = useCallback2(() => {
198
251
  if (infinite.hasNextPage && !infinite.isFetchingNextPage) {
199
252
  return infinite.fetchNextPage();
200
253
  }
201
254
  return Promise.resolve();
202
255
  }, [infinite]);
203
- const goToPage = useCallback((newPage) => {
256
+ const goToPage = useCallback2((newPage) => {
204
257
  setPage(newPage);
205
258
  }, []);
206
259
  return {
@@ -243,7 +296,9 @@ import { useQuery } from "@tanstack/react-query";
243
296
  function useProduct(slug, options) {
244
297
  const { client } = useBehio();
245
298
  return useQuery({
246
- queryKey: ["behio", "product", slug],
299
+ // currency + locale belong in the key so switching either refetches the
300
+ // price/translation instead of serving a stale cache hit.
301
+ queryKey: ["behio", "product", slug, options?.locale, options?.currency],
247
302
  queryFn: () => unwrap(client.catalog.getProduct(slug, {
248
303
  locale: options?.locale,
249
304
  currency: options?.currency
@@ -319,12 +374,12 @@ function useFilters(options) {
319
374
  }
320
375
 
321
376
  // src/react/hooks/use-search.ts
322
- import { useState as useState2, useEffect as useEffect2 } from "react";
377
+ import { useState as useState3, useEffect as useEffect2 } from "react";
323
378
  import { useQuery as useQuery6 } from "@tanstack/react-query";
324
379
  function useSearch(query, options) {
325
380
  const { client } = useBehio();
326
381
  const debounceMs = options?.debounceMs ?? 300;
327
- const [debouncedQuery, setDebouncedQuery] = useState2(query);
382
+ const [debouncedQuery, setDebouncedQuery] = useState3(query);
328
383
  useEffect2(() => {
329
384
  if (debounceMs <= 0) {
330
385
  setDebouncedQuery(query);
@@ -344,7 +399,7 @@ function useSearch(query, options) {
344
399
  }
345
400
 
346
401
  // src/react/hooks/use-cart.ts
347
- import { useCallback as useCallback2 } from "react";
402
+ import { useCallback as useCallback3 } from "react";
348
403
  import { useQuery as useQuery7, useMutation, useQueryClient } from "@tanstack/react-query";
349
404
  var CART_KEY = ["behio", "cart"];
350
405
  function useCart(options) {
@@ -453,31 +508,31 @@ function useCart(options) {
453
508
  storage.remove(STORAGE_KEYS.CART_SESSION);
454
509
  }
455
510
  });
456
- const addItem = useCallback2(
511
+ const addItem = useCallback3(
457
512
  (productId, quantity) => addMutation.mutateAsync({ productId, quantity }),
458
513
  [addMutation]
459
514
  );
460
- const updateQuantity = useCallback2(
515
+ const updateQuantity = useCallback3(
461
516
  (itemId, quantity) => updateMutation.mutateAsync({ itemId, quantity }),
462
517
  [updateMutation]
463
518
  );
464
- const removeItem = useCallback2(
519
+ const removeItem = useCallback3(
465
520
  (itemId) => removeMutation.mutateAsync(itemId),
466
521
  [removeMutation]
467
522
  );
468
- const clear = useCallback2(
523
+ const clear = useCallback3(
469
524
  () => clearMutation.mutateAsync(),
470
525
  [clearMutation]
471
526
  );
472
- const applyDiscount = useCallback2(
527
+ const applyDiscount = useCallback3(
473
528
  (code) => applyDiscountMutation.mutateAsync(code),
474
529
  [applyDiscountMutation]
475
530
  );
476
- const removeDiscount = useCallback2(
531
+ const removeDiscount = useCallback3(
477
532
  () => removeDiscountMutation.mutateAsync(),
478
533
  [removeDiscountMutation]
479
534
  );
480
- const merge = useCallback2(
535
+ const merge = useCallback3(
481
536
  () => mergeMutation.mutateAsync(),
482
537
  [mergeMutation]
483
538
  );
@@ -520,7 +575,7 @@ function useCartCount(options) {
520
575
  }
521
576
 
522
577
  // src/react/hooks/use-auth.ts
523
- import { useCallback as useCallback3 } from "react";
578
+ import { useCallback as useCallback4 } from "react";
524
579
  import { useQuery as useQuery9, useMutation as useMutation2, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
525
580
  var CUSTOMER_KEY = ["behio", "customer"];
526
581
  var CART_KEY3 = ["behio", "cart"];
@@ -536,7 +591,7 @@ function useAuth() {
536
591
  queryFn: () => unwrap(client.customer.getProfile()),
537
592
  enabled: isLoggedIn
538
593
  });
539
- const persistTokens = useCallback3(
594
+ const persistTokens = useCallback4(
540
595
  (tokens) => {
541
596
  client.setTokens(tokens);
542
597
  storage.set(STORAGE_KEYS.ACCESS_TOKEN, tokens.accessToken);
@@ -544,7 +599,7 @@ function useAuth() {
544
599
  },
545
600
  [client, storage]
546
601
  );
547
- const clearAuth = useCallback3(() => {
602
+ const clearAuth = useCallback4(() => {
548
603
  client.clearTokens();
549
604
  storage.remove(STORAGE_KEYS.ACCESS_TOKEN);
550
605
  storage.remove(STORAGE_KEYS.REFRESH_TOKEN);
@@ -552,7 +607,7 @@ function useAuth() {
552
607
  queryClient.invalidateQueries({ queryKey: ["behio", "orders"] });
553
608
  queryClient.invalidateQueries({ queryKey: ["behio", "addresses"] });
554
609
  }, [client, storage, queryClient]);
555
- const postAuth = useCallback3(async () => {
610
+ const postAuth = useCallback4(async () => {
556
611
  await queryClient.invalidateQueries({ queryKey: [...CUSTOMER_KEY] });
557
612
  if (client.getCartSession()) {
558
613
  try {
@@ -597,27 +652,27 @@ function useAuth() {
597
652
  const verifyEmailMutation = useMutation2({
598
653
  mutationFn: (token) => unwrap(client.auth.verifyEmail(token))
599
654
  });
600
- const login = useCallback3(
655
+ const login = useCallback4(
601
656
  (email, password) => loginMutation.mutateAsync({ email, password }).then(() => void 0),
602
657
  [loginMutation]
603
658
  );
604
- const register = useCallback3(
659
+ const register = useCallback4(
605
660
  (input) => registerMutation.mutateAsync(input).then(() => void 0),
606
661
  [registerMutation]
607
662
  );
608
- const logout = useCallback3(
663
+ const logout = useCallback4(
609
664
  () => logoutMutation.mutateAsync().then(() => void 0),
610
665
  [logoutMutation]
611
666
  );
612
- const forgotPassword = useCallback3(
667
+ const forgotPassword = useCallback4(
613
668
  (email) => forgotPasswordMutation.mutateAsync(email).then(() => void 0),
614
669
  [forgotPasswordMutation]
615
670
  );
616
- const resetPassword = useCallback3(
671
+ const resetPassword = useCallback4(
617
672
  (token, newPassword) => resetPasswordMutation.mutateAsync({ token, newPassword }).then(() => void 0),
618
673
  [resetPasswordMutation]
619
674
  );
620
- const verifyEmail = useCallback3(
675
+ const verifyEmail = useCallback4(
621
676
  (token) => verifyEmailMutation.mutateAsync(token).then(() => void 0),
622
677
  [verifyEmailMutation]
623
678
  );
@@ -641,7 +696,7 @@ function useAuth() {
641
696
  }
642
697
 
643
698
  // src/react/hooks/use-customer.ts
644
- import { useCallback as useCallback4 } from "react";
699
+ import { useCallback as useCallback5 } from "react";
645
700
  import { useQuery as useQuery10, useMutation as useMutation3, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
646
701
  var CUSTOMER_KEY2 = ["behio", "customer"];
647
702
  function useCustomer(options) {
@@ -662,7 +717,7 @@ function useCustomer(options) {
662
717
  queryClient.setQueryData([...CUSTOMER_KEY2], updated);
663
718
  }
664
719
  });
665
- const updateProfile = useCallback4(
720
+ const updateProfile = useCallback5(
666
721
  (profileData) => updateMutation.mutateAsync(profileData),
667
722
  [updateMutation]
668
723
  );
@@ -676,7 +731,7 @@ function useCustomer(options) {
676
731
  }
677
732
 
678
733
  // src/react/hooks/use-addresses.ts
679
- import { useCallback as useCallback5 } from "react";
734
+ import { useCallback as useCallback6 } from "react";
680
735
  import { useQuery as useQuery11, useMutation as useMutation4, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
681
736
  var ADDRESSES_KEY = ["behio", "addresses"];
682
737
  function useAddresses(options) {
@@ -712,15 +767,15 @@ function useAddresses(options) {
712
767
  queryClient.invalidateQueries({ queryKey: [...ADDRESSES_KEY] });
713
768
  }
714
769
  });
715
- const createAddress = useCallback5(
770
+ const createAddress = useCallback6(
716
771
  (address) => createMutation.mutateAsync(address),
717
772
  [createMutation]
718
773
  );
719
- const updateAddress = useCallback5(
774
+ const updateAddress = useCallback6(
720
775
  (addressId, addressData) => updateMutation.mutateAsync({ addressId, data: addressData }),
721
776
  [updateMutation]
722
777
  );
723
- const deleteAddress = useCallback5(
778
+ const deleteAddress = useCallback6(
724
779
  (addressId) => deleteMutation.mutateAsync(addressId),
725
780
  [deleteMutation]
726
781
  );
@@ -737,16 +792,16 @@ function useAddresses(options) {
737
792
  }
738
793
 
739
794
  // src/react/hooks/use-address-autocomplete.ts
740
- import { useState as useState3, useEffect as useEffect3, useRef as useRef2, useCallback as useCallback6 } from "react";
795
+ import { useState as useState4, useEffect as useEffect3, useRef as useRef2, useCallback as useCallback7 } from "react";
741
796
  import { useQuery as useQuery12 } from "@tanstack/react-query";
742
797
  var AC_KEY = ["behio", "address-autocomplete"];
743
798
  function useAddressAutocomplete(options) {
744
799
  const { country, debounce = 300, minChars = 3, enabled = true } = options;
745
800
  const { client } = useBehio();
746
- const [query, setQuery] = useState3("");
747
- const [debouncedQuery, setDebouncedQuery] = useState3("");
748
- const [selected, setSelected] = useState3(null);
749
- const [isSelecting, setIsSelecting] = useState3(false);
801
+ const [query, setQuery] = useState4("");
802
+ const [debouncedQuery, setDebouncedQuery] = useState4("");
803
+ const [selected, setSelected] = useState4(null);
804
+ const [isSelecting, setIsSelecting] = useState4(false);
750
805
  const timerRef = useRef2(void 0);
751
806
  useEffect3(() => {
752
807
  if (timerRef.current) clearTimeout(timerRef.current);
@@ -768,7 +823,7 @@ function useAddressAutocomplete(options) {
768
823
  staleTime: 6e4
769
824
  // Cache suggestions for 1 min
770
825
  });
771
- const select = useCallback6(
826
+ const select = useCallback7(
772
827
  async (placeId) => {
773
828
  setIsSelecting(true);
774
829
  try {
@@ -783,7 +838,7 @@ function useAddressAutocomplete(options) {
783
838
  },
784
839
  [client]
785
840
  );
786
- const clear = useCallback6(() => {
841
+ const clear = useCallback7(() => {
787
842
  setQuery("");
788
843
  setDebouncedQuery("");
789
844
  setSelected(null);
@@ -801,12 +856,12 @@ function useAddressAutocomplete(options) {
801
856
  }
802
857
 
803
858
  // src/react/hooks/use-orders.ts
804
- import { useCallback as useCallback7, useMemo as useMemo3, useState as useState4 } from "react";
859
+ import { useCallback as useCallback8, useMemo as useMemo3, useState as useState5 } from "react";
805
860
  import { useInfiniteQuery as useInfiniteQuery2 } from "@tanstack/react-query";
806
861
  function useOrders(options) {
807
862
  const { client } = useBehio();
808
863
  const { page: initialPage, limit, enabled } = options ?? {};
809
- const [page, setPage] = useState4(initialPage ?? 1);
864
+ const [page, setPage] = useState5(initialPage ?? 1);
810
865
  const infinite = useInfiniteQuery2({
811
866
  queryKey: ["behio", "orders", limit, page],
812
867
  queryFn: ({ pageParam }) => unwrap(client.orders.list({ limit, page: pageParam })),
@@ -820,13 +875,13 @@ function useOrders(options) {
820
875
  [infinite.data]
821
876
  );
822
877
  const lastPage = infinite.data?.pages[infinite.data.pages.length - 1];
823
- const loadMore = useCallback7(() => {
878
+ const loadMore = useCallback8(() => {
824
879
  if (infinite.hasNextPage && !infinite.isFetchingNextPage) {
825
880
  return infinite.fetchNextPage();
826
881
  }
827
882
  return Promise.resolve();
828
883
  }, [infinite]);
829
- const goToPage = useCallback7((newPage) => {
884
+ const goToPage = useCallback8((newPage) => {
830
885
  setPage(newPage);
831
886
  }, []);
832
887
  return {
@@ -852,7 +907,7 @@ function useOrders(options) {
852
907
  }
853
908
 
854
909
  // src/react/hooks/use-order.ts
855
- import { useCallback as useCallback8 } from "react";
910
+ import { useCallback as useCallback9 } from "react";
856
911
  import { useQuery as useQuery13, useMutation as useMutation5, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
857
912
  function useOrder(orderNumber, options) {
858
913
  const { client } = useBehio();
@@ -873,7 +928,7 @@ function useOrder(orderNumber, options) {
873
928
  queryClient.invalidateQueries({ queryKey: ["behio", "orders"] });
874
929
  }
875
930
  });
876
- const cancel = useCallback8(
931
+ const cancel = useCallback9(
877
932
  () => cancelMutation.mutateAsync(),
878
933
  [cancelMutation]
879
934
  );
@@ -886,14 +941,74 @@ function useOrder(orderNumber, options) {
886
941
  };
887
942
  }
888
943
 
944
+ // src/react/hooks/use-order-access.ts
945
+ import { useCallback as useCallback10, useState as useState6 } from "react";
946
+ import { useMutation as useMutation6 } from "@tanstack/react-query";
947
+ function useOrderAccess() {
948
+ const { client } = useBehio();
949
+ const [orderNumber, setOrderNumber] = useState6(null);
950
+ const [email, setEmail] = useState6(null);
951
+ const [order, setOrder] = useState6(null);
952
+ const [accessToken, setAccessToken] = useState6(null);
953
+ const requestMutation = useMutation6({
954
+ mutationFn: (input) => unwrap(client.orders.requestAccessCode(input.orderNumber, input.email)),
955
+ onSuccess: (_data, input) => {
956
+ setOrderNumber(input.orderNumber);
957
+ setEmail(input.email);
958
+ }
959
+ });
960
+ const verifyMutation = useMutation6({
961
+ mutationFn: (code) => {
962
+ if (!orderNumber || !email) {
963
+ throw new Error("Request a code before verifying");
964
+ }
965
+ return unwrap(client.orders.verifyAccessCode(orderNumber, email, code));
966
+ },
967
+ onSuccess: (result) => {
968
+ setOrder(result.order);
969
+ setAccessToken(result.accessToken);
970
+ }
971
+ });
972
+ const requestCode = useCallback10(
973
+ (on, em) => requestMutation.mutateAsync({ orderNumber: on, email: em }),
974
+ [requestMutation]
975
+ );
976
+ const verifyCode = useCallback10((code) => verifyMutation.mutateAsync(code), [verifyMutation]);
977
+ const reset = useCallback10(() => {
978
+ setOrderNumber(null);
979
+ setEmail(null);
980
+ setOrder(null);
981
+ setAccessToken(null);
982
+ requestMutation.reset();
983
+ verifyMutation.reset();
984
+ }, [requestMutation, verifyMutation]);
985
+ return {
986
+ /** Step 1: send the code. */
987
+ requestCode,
988
+ isRequesting: requestMutation.isPending,
989
+ requestError: requestMutation.error,
990
+ /** True once a code has been requested (move the UI to the code input). */
991
+ codeSent: !!orderNumber && !!email,
992
+ /** Step 2: verify the code. */
993
+ verifyCode,
994
+ isVerifying: verifyMutation.isPending,
995
+ verifyError: verifyMutation.error,
996
+ /** Full order detail, available after a successful verify. */
997
+ order,
998
+ /** Short-lived token scoped to this order (30 min). */
999
+ accessToken,
1000
+ reset
1001
+ };
1002
+ }
1003
+
889
1004
  // src/react/hooks/use-checkout.ts
890
- import { useState as useState5, useCallback as useCallback9 } from "react";
891
- import { useMutation as useMutation6, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
1005
+ import { useState as useState7, useCallback as useCallback11 } from "react";
1006
+ import { useMutation as useMutation7, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
892
1007
  function useCheckout() {
893
1008
  const { client, storage } = useBehio();
894
1009
  const queryClient = useQueryClient8();
895
- const [order, setOrder] = useState5(null);
896
- const mutation = useMutation6({
1010
+ const [order, setOrder] = useState7(null);
1011
+ const mutation = useMutation7({
897
1012
  mutationFn: (input) => unwrap(client.checkout.createOrder(input)),
898
1013
  onSuccess: (result) => {
899
1014
  setOrder(result);
@@ -902,11 +1017,11 @@ function useCheckout() {
902
1017
  queryClient.invalidateQueries({ queryKey: ["behio", "orders"] });
903
1018
  }
904
1019
  });
905
- const createOrder = useCallback9(
1020
+ const createOrder = useCallback11(
906
1021
  (input) => mutation.mutateAsync(input),
907
1022
  [mutation]
908
1023
  );
909
- const reset = useCallback9(() => {
1024
+ const reset = useCallback11(() => {
910
1025
  setOrder(null);
911
1026
  mutation.reset();
912
1027
  }, [mutation]);
@@ -965,6 +1080,57 @@ function useShopSeo(options) {
965
1080
  });
966
1081
  }
967
1082
 
1083
+ // src/react/hooks/use-currency.ts
1084
+ function dedupe(values) {
1085
+ const out = [];
1086
+ for (const v of values) {
1087
+ if (v && !out.includes(v)) out.push(v);
1088
+ }
1089
+ return out;
1090
+ }
1091
+ function useCurrency() {
1092
+ const { currency, setCurrency, configuredDefaultCurrency, configuredCurrencies } = useBehio();
1093
+ const { data: shop, isLoading } = useShopInfo();
1094
+ const defaultCurrency = configuredDefaultCurrency ?? shop?.defaultCurrency;
1095
+ const currencies = configuredCurrencies && configuredCurrencies.length > 0 ? dedupe(configuredCurrencies) : dedupe([defaultCurrency, ...shop?.supportedCurrencies ?? []]);
1096
+ return {
1097
+ currency,
1098
+ effectiveCurrency: currency ?? defaultCurrency,
1099
+ setCurrency,
1100
+ currencies,
1101
+ defaultCurrency,
1102
+ isLoading
1103
+ };
1104
+ }
1105
+
1106
+ // src/react/components/currency-switcher.tsx
1107
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
1108
+ function CurrencySwitcher({
1109
+ className,
1110
+ labels,
1111
+ showWhenSingle = false,
1112
+ ariaLabel = "Currency",
1113
+ children
1114
+ }) {
1115
+ const { currencies, effectiveCurrency, setCurrency } = useCurrency();
1116
+ if (currencies.length === 0) return null;
1117
+ if (currencies.length <= 1 && !showWhenSingle) return null;
1118
+ const label = (code) => labels?.[code] ?? code;
1119
+ if (children) {
1120
+ return /* @__PURE__ */ jsx2(Fragment, { children: children({ currencies, value: effectiveCurrency, setCurrency, label }) });
1121
+ }
1122
+ return /* @__PURE__ */ jsx2(
1123
+ "select",
1124
+ {
1125
+ className,
1126
+ "aria-label": ariaLabel,
1127
+ value: effectiveCurrency ?? "",
1128
+ onChange: (e) => setCurrency(e.target.value),
1129
+ children: currencies.map((code) => /* @__PURE__ */ jsx2("option", { value: code, children: label(code) }, code))
1130
+ }
1131
+ );
1132
+ }
1133
+
968
1134
  // src/react/hooks/use-bundles.ts
969
1135
  import { useQuery as useQuery17 } from "@tanstack/react-query";
970
1136
  function useBundles(options) {
@@ -1023,7 +1189,7 @@ function useGiftCardBalance(code, options) {
1023
1189
  }
1024
1190
 
1025
1191
  // src/react/hooks/use-wishlist.ts
1026
- import { useQuery as useQuery21, useMutation as useMutation7, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
1192
+ import { useQuery as useQuery21, useMutation as useMutation8, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
1027
1193
  function useWishlist(options) {
1028
1194
  const { client } = useBehio();
1029
1195
  const qc = useQueryClient9();
@@ -1032,11 +1198,11 @@ function useWishlist(options) {
1032
1198
  queryFn: () => unwrap(client.wishlist.get()),
1033
1199
  enabled: options?.enabled ?? true
1034
1200
  });
1035
- const addMutation = useMutation7({
1201
+ const addMutation = useMutation8({
1036
1202
  mutationFn: (productId) => unwrap(client.wishlist.add(productId)),
1037
1203
  onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "wishlist"] })
1038
1204
  });
1039
- const removeMutation = useMutation7({
1205
+ const removeMutation = useMutation8({
1040
1206
  mutationFn: (productId) => unwrap(client.wishlist.remove(productId)),
1041
1207
  onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "wishlist"] })
1042
1208
  });
@@ -1058,7 +1224,7 @@ function useIsInWishlist(productId) {
1058
1224
  }
1059
1225
 
1060
1226
  // src/react/hooks/use-reviews.ts
1061
- import { useQuery as useQuery22, useMutation as useMutation8, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
1227
+ import { useQuery as useQuery22, useMutation as useMutation9, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
1062
1228
  function useProductReviews(productId, options) {
1063
1229
  const { client } = useBehio();
1064
1230
  return useQuery22({
@@ -1070,23 +1236,23 @@ function useProductReviews(productId, options) {
1070
1236
  function useSubmitReview() {
1071
1237
  const { client } = useBehio();
1072
1238
  const qc = useQueryClient10();
1073
- return useMutation8({
1239
+ return useMutation9({
1074
1240
  mutationFn: (input) => unwrap(client.reviews.submit(input)),
1075
1241
  onSuccess: (_, input) => qc.invalidateQueries({ queryKey: ["behio", "reviews", input.productId] })
1076
1242
  });
1077
1243
  }
1078
1244
 
1079
1245
  // src/react/hooks/use-returns.ts
1080
- import { useQuery as useQuery23, useMutation as useMutation9 } from "@tanstack/react-query";
1246
+ import { useQuery as useQuery23, useMutation as useMutation10 } from "@tanstack/react-query";
1081
1247
  function useLookupReturnableOrder() {
1082
1248
  const { client } = useBehio();
1083
- return useMutation9({
1249
+ return useMutation10({
1084
1250
  mutationFn: ({ orderNumber, email }) => unwrap(client.returns.lookupOrder(orderNumber, email))
1085
1251
  });
1086
1252
  }
1087
1253
  function useSubmitReturn() {
1088
1254
  const { client } = useBehio();
1089
- return useMutation9({
1255
+ return useMutation10({
1090
1256
  mutationFn: (input) => unwrap(client.returns.submit(input))
1091
1257
  });
1092
1258
  }
@@ -1100,7 +1266,7 @@ function useReturnStatus(returnId, email) {
1100
1266
  }
1101
1267
 
1102
1268
  // src/react/hooks/use-consent.ts
1103
- import { useQuery as useQuery24, useMutation as useMutation10, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
1269
+ import { useQuery as useQuery24, useMutation as useMutation11, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
1104
1270
  function useCookieConsent(visitorId) {
1105
1271
  const { client } = useBehio();
1106
1272
  const qc = useQueryClient11();
@@ -1109,11 +1275,11 @@ function useCookieConsent(visitorId) {
1109
1275
  queryFn: () => unwrap(client.consent.get(visitorId)),
1110
1276
  enabled: Boolean(visitorId)
1111
1277
  });
1112
- const recordMutation = useMutation10({
1278
+ const recordMutation = useMutation11({
1113
1279
  mutationFn: (input) => unwrap(client.consent.record(input)),
1114
1280
  onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "consent"] })
1115
1281
  });
1116
- const revokeMutation = useMutation10({
1282
+ const revokeMutation = useMutation11({
1117
1283
  mutationFn: () => unwrap(client.consent.revoke(visitorId)),
1118
1284
  onSuccess: () => qc.invalidateQueries({ queryKey: ["behio", "consent"] })
1119
1285
  });
@@ -1125,10 +1291,10 @@ function useCookieConsent(visitorId) {
1125
1291
  }
1126
1292
 
1127
1293
  // src/react/hooks/use-quotes.ts
1128
- import { useMutation as useMutation11, useQuery as useQuery25 } from "@tanstack/react-query";
1294
+ import { useMutation as useMutation12, useQuery as useQuery25 } from "@tanstack/react-query";
1129
1295
  function useSubmitQuote() {
1130
1296
  const { client } = useBehio();
1131
- return useMutation11({
1297
+ return useMutation12({
1132
1298
  mutationFn: (input) => unwrap(client.quotes.submit(input))
1133
1299
  });
1134
1300
  }
@@ -1142,10 +1308,10 @@ function useQuoteStatus(quoteId, email) {
1142
1308
  }
1143
1309
 
1144
1310
  // src/react/hooks/use-back-in-stock.ts
1145
- import { useMutation as useMutation12 } from "@tanstack/react-query";
1311
+ import { useMutation as useMutation13 } from "@tanstack/react-query";
1146
1312
  function useNotifyWhenAvailable() {
1147
1313
  const { client } = useBehio();
1148
- return useMutation12({
1314
+ return useMutation13({
1149
1315
  mutationFn: ({ productId, email }) => unwrap(client.catalog.notifyWhenAvailable(productId, email))
1150
1316
  });
1151
1317
  }
@@ -1171,6 +1337,7 @@ function formatPrice(amount, currency, locale) {
1171
1337
  }
1172
1338
  export {
1173
1339
  BehioProvider,
1340
+ CurrencySwitcher,
1174
1341
  cookieStorage,
1175
1342
  createMemoryStorage,
1176
1343
  detectStorage,
@@ -1191,6 +1358,7 @@ export {
1191
1358
  useCheckout,
1192
1359
  useCookieConsent,
1193
1360
  useCrossSell,
1361
+ useCurrency,
1194
1362
  useCustomer,
1195
1363
  useFeatured,
1196
1364
  useFilters,
@@ -1200,6 +1368,7 @@ export {
1200
1368
  useLookupReturnableOrder,
1201
1369
  useNotifyWhenAvailable,
1202
1370
  useOrder,
1371
+ useOrderAccess,
1203
1372
  useOrders,
1204
1373
  usePage,
1205
1374
  usePages,