@doswiftly/storefront-sdk 11.1.0 → 11.3.1

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +297 -2
  3. package/dist/core/auth/handlers.d.ts.map +1 -1
  4. package/dist/core/auth/handlers.js +29 -1
  5. package/dist/core/bot-protection/turnstile-manager.d.ts +0 -1
  6. package/dist/core/bot-protection/turnstile-manager.d.ts.map +1 -1
  7. package/dist/core/bot-protection/turnstile-manager.js +0 -1
  8. package/dist/core/cart/cart-recovery.d.ts +210 -0
  9. package/dist/core/cart/cart-recovery.d.ts.map +1 -0
  10. package/dist/core/cart/cart-recovery.js +271 -0
  11. package/dist/core/index.d.ts +2 -0
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +2 -0
  14. package/dist/react/components/AddToCartButton.d.ts +49 -0
  15. package/dist/react/components/AddToCartButton.d.ts.map +1 -0
  16. package/dist/react/components/AddToCartButton.js +47 -0
  17. package/dist/react/components/CartCount.d.ts +35 -0
  18. package/dist/react/components/CartCount.d.ts.map +1 -0
  19. package/dist/react/components/CartCount.js +23 -0
  20. package/dist/react/components/CartTotals.d.ts +54 -0
  21. package/dist/react/components/CartTotals.d.ts.map +1 -0
  22. package/dist/react/components/CartTotals.js +38 -0
  23. package/dist/react/components/Image.d.ts +42 -0
  24. package/dist/react/components/Image.d.ts.map +1 -0
  25. package/dist/react/components/Image.js +33 -0
  26. package/dist/react/components/Money.d.ts +32 -0
  27. package/dist/react/components/Money.d.ts.map +1 -0
  28. package/dist/react/components/Money.js +27 -0
  29. package/dist/react/components/PriceDisplay.d.ts +34 -0
  30. package/dist/react/components/PriceDisplay.d.ts.map +1 -0
  31. package/dist/react/components/PriceDisplay.js +21 -0
  32. package/dist/react/components/index.d.ts +15 -0
  33. package/dist/react/components/index.d.ts.map +1 -0
  34. package/dist/react/components/index.js +14 -0
  35. package/dist/react/cookies.d.ts +21 -0
  36. package/dist/react/cookies.d.ts.map +1 -1
  37. package/dist/react/cookies.js +29 -1
  38. package/dist/react/hooks/use-auth.d.ts +19 -46
  39. package/dist/react/hooks/use-auth.d.ts.map +1 -1
  40. package/dist/react/hooks/use-auth.js +24 -141
  41. package/dist/react/hooks/use-cart-manager.d.ts +75 -15
  42. package/dist/react/hooks/use-cart-manager.d.ts.map +1 -1
  43. package/dist/react/hooks/use-cart-manager.js +106 -194
  44. package/dist/react/hooks/use-login.d.ts +40 -0
  45. package/dist/react/hooks/use-login.d.ts.map +1 -0
  46. package/dist/react/hooks/use-login.js +75 -0
  47. package/dist/react/hooks/use-logout.d.ts +40 -0
  48. package/dist/react/hooks/use-logout.d.ts.map +1 -0
  49. package/dist/react/hooks/use-logout.js +50 -0
  50. package/dist/react/hooks/use-refresh-token.d.ts +40 -0
  51. package/dist/react/hooks/use-refresh-token.d.ts.map +1 -0
  52. package/dist/react/hooks/use-refresh-token.js +66 -0
  53. package/dist/react/index.d.ts +6 -2
  54. package/dist/react/index.d.ts.map +1 -1
  55. package/dist/react/index.js +6 -1
  56. package/dist/react/server/get-storefront-client.d.ts +15 -5
  57. package/dist/react/server/get-storefront-client.d.ts.map +1 -1
  58. package/dist/react/stores/cart.store.d.ts +57 -10
  59. package/dist/react/stores/cart.store.d.ts.map +1 -1
  60. package/dist/react/stores/cart.store.js +112 -21
  61. package/dist/react/stores/store-context.d.ts.map +1 -1
  62. package/dist/react/stores/store-context.js +0 -2
  63. package/package.json +11 -4
  64. package/dist/__tests__/unit/test-helpers.d.ts +0 -46
  65. package/dist/__tests__/unit/test-helpers.d.ts.map +0 -1
  66. package/dist/__tests__/unit/test-helpers.js +0 -72
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-login.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,gHAAgH;IAChH,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,0GAA0G;IAC1G,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CA+DtE"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * useLogin — focused hook for the login flow.
3
+ *
4
+ * Composes the auth client + Zustand store + httpOnly cookie BFF callback.
5
+ * Returns `success`/`userErrors` rather than throwing on credential errors —
6
+ * standard form submission pattern.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const { login, isLoggingIn, error } = useLogin({ onSetToken });
11
+ * const result = await login(email, password);
12
+ * if (!result.success) showErrors(result.userErrors);
13
+ * ```
14
+ */
15
+ 'use client';
16
+ import { useCallback, useState } from 'react';
17
+ import { useStorefrontClientContext } from '../providers/storefront-client-provider';
18
+ import { useAuthStore } from '../stores/store-context';
19
+ import { StorefrontError } from '../../core/errors';
20
+ export function useLogin(options = {}) {
21
+ const { authClient } = useStorefrontClientContext();
22
+ const { setAuth } = useAuthStore();
23
+ const [isLoggingIn, setIsLoggingIn] = useState(false);
24
+ const [error, setError] = useState(null);
25
+ const login = useCallback(async (email, password) => {
26
+ setError(null);
27
+ setIsLoggingIn(true);
28
+ try {
29
+ const result = await authClient.login(email, password);
30
+ if (options.onSetToken) {
31
+ await options.onSetToken(result.accessToken);
32
+ }
33
+ // Fetch customer data and set store (best-effort — fallback to minimal data)
34
+ try {
35
+ const customer = await authClient.getCustomer();
36
+ if (customer) {
37
+ setAuth({
38
+ id: customer.id,
39
+ email: customer.email,
40
+ firstName: customer.firstName ?? undefined,
41
+ lastName: customer.lastName ?? undefined,
42
+ phone: customer.phone ?? undefined,
43
+ }, result.accessToken);
44
+ }
45
+ else {
46
+ setAuth({ id: '', email }, result.accessToken);
47
+ }
48
+ }
49
+ catch {
50
+ setAuth({ id: '', email }, result.accessToken);
51
+ }
52
+ return {
53
+ success: true,
54
+ userErrors: [],
55
+ accessToken: result.accessToken,
56
+ expiresAt: result.expiresAt,
57
+ };
58
+ }
59
+ catch (err) {
60
+ if (err instanceof StorefrontError && err.hasUserErrors) {
61
+ return {
62
+ success: false,
63
+ userErrors: err.userErrors.map((e) => ({ message: e.message, field: e.field })),
64
+ };
65
+ }
66
+ const message = err instanceof Error ? err.message : 'Login failed';
67
+ setError(message);
68
+ return { success: false, userErrors: [{ message }] };
69
+ }
70
+ finally {
71
+ setIsLoggingIn(false);
72
+ }
73
+ }, [authClient, setAuth, options]);
74
+ return { login, isLoggingIn, error };
75
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * useLogout — focused hook for the logout flow.
3
+ *
4
+ * Calls the auth client logout (which clears the backend's httpOnly cookie),
5
+ * invokes the consumer's `onClearToken` callback (BFF), and resets the local
6
+ * auth store. Even when the backend request fails, the local state is
7
+ * cleared (defensive — better to log a user out than leave them in a half
8
+ * state).
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const { logout, isLoggingOut } = useLogout({ onClearToken });
13
+ * await logout();
14
+ * router.push('/');
15
+ * ```
16
+ */
17
+ export interface UseLogoutOptions {
18
+ /**
19
+ * Called after logout to clear the httpOnly cookie via an API route handler
20
+ * (`createClearTokenHandler`).
21
+ */
22
+ onClearToken?: () => Promise<void>;
23
+ }
24
+ export interface LogoutResult {
25
+ success: boolean;
26
+ userErrors: Array<{
27
+ message: string;
28
+ field?: string[];
29
+ }>;
30
+ }
31
+ export interface UseLogoutReturn {
32
+ /** Run the logout flow. Resolves with `{success}` — local state is always cleared. */
33
+ logout: () => Promise<LogoutResult>;
34
+ /** `true` while the logout request is in flight. */
35
+ isLoggingOut: boolean;
36
+ /** Last error message (network, server) — local state is cleared regardless. */
37
+ error: string | null;
38
+ }
39
+ export declare function useLogout(options?: UseLogoutOptions): UseLogoutReturn;
40
+ //# sourceMappingURL=use-logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-logout.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-logout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,oDAAoD;IACpD,YAAY,EAAE,OAAO,CAAC;IACtB,gFAAgF;IAChF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAgCzE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * useLogout — focused hook for the logout flow.
3
+ *
4
+ * Calls the auth client logout (which clears the backend's httpOnly cookie),
5
+ * invokes the consumer's `onClearToken` callback (BFF), and resets the local
6
+ * auth store. Even when the backend request fails, the local state is
7
+ * cleared (defensive — better to log a user out than leave them in a half
8
+ * state).
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const { logout, isLoggingOut } = useLogout({ onClearToken });
13
+ * await logout();
14
+ * router.push('/');
15
+ * ```
16
+ */
17
+ 'use client';
18
+ import { useCallback, useState } from 'react';
19
+ import { useStorefrontClientContext } from '../providers/storefront-client-provider';
20
+ import { useAuthStore } from '../stores/store-context';
21
+ export function useLogout(options = {}) {
22
+ const { authClient } = useStorefrontClientContext();
23
+ const { clearAuth } = useAuthStore();
24
+ const [isLoggingOut, setIsLoggingOut] = useState(false);
25
+ const [error, setError] = useState(null);
26
+ const logout = useCallback(async () => {
27
+ setError(null);
28
+ setIsLoggingOut(true);
29
+ try {
30
+ // Auth context resolved server-side from cookie/Bearer — no token arg needed
31
+ await authClient.logout();
32
+ if (options.onClearToken) {
33
+ await options.onClearToken();
34
+ }
35
+ clearAuth();
36
+ return { success: true, userErrors: [] };
37
+ }
38
+ catch (err) {
39
+ // Even on error, clear local state — better than a stuck half-state
40
+ clearAuth();
41
+ const message = err instanceof Error ? err.message : 'Logout failed';
42
+ setError(message);
43
+ return { success: false, userErrors: [{ message }] };
44
+ }
45
+ finally {
46
+ setIsLoggingOut(false);
47
+ }
48
+ }, [authClient, clearAuth, options]);
49
+ return { logout, isLoggingOut, error };
50
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * useRefreshToken — focused hook for renewing the access token.
3
+ *
4
+ * Wraps `AuthClient.refreshToken`. On success the new token is propagated to
5
+ * the consumer's BFF (`onSetToken`) and the store keeps the existing customer
6
+ * data with the new token attached.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Periodic refresh (e.g. every 30 min)
11
+ * const { refreshToken } = useRefreshToken({ onSetToken });
12
+ * useEffect(() => {
13
+ * const timer = setInterval(() => refreshToken(), 30 * 60 * 1000);
14
+ * return () => clearInterval(timer);
15
+ * }, [refreshToken]);
16
+ * ```
17
+ */
18
+ export interface UseRefreshTokenOptions {
19
+ /** Called after a successful refresh with the new access token (BFF cookie sync). */
20
+ onSetToken?: (token: string) => Promise<void>;
21
+ }
22
+ export interface TokenRefreshResult {
23
+ success: boolean;
24
+ userErrors: Array<{
25
+ message: string;
26
+ field?: string[];
27
+ }>;
28
+ accessToken?: string;
29
+ expiresAt?: string;
30
+ }
31
+ export interface UseRefreshTokenReturn {
32
+ /** Renew the access token. Resolves with `{success}`. */
33
+ refreshToken: () => Promise<TokenRefreshResult>;
34
+ /** `true` while a refresh request is in flight. */
35
+ isRefreshingToken: boolean;
36
+ /** Last unexpected error message — credential / session expiry lands in `userErrors`. */
37
+ error: string | null;
38
+ }
39
+ export declare function useRefreshToken(options?: UseRefreshTokenOptions): UseRefreshTokenReturn;
40
+ //# sourceMappingURL=use-refresh-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-refresh-token.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-refresh-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,MAAM,WAAW,sBAAsB;IACrC,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,mDAAmD;IACnD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CA+C3F"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * useRefreshToken — focused hook for renewing the access token.
3
+ *
4
+ * Wraps `AuthClient.refreshToken`. On success the new token is propagated to
5
+ * the consumer's BFF (`onSetToken`) and the store keeps the existing customer
6
+ * data with the new token attached.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Periodic refresh (e.g. every 30 min)
11
+ * const { refreshToken } = useRefreshToken({ onSetToken });
12
+ * useEffect(() => {
13
+ * const timer = setInterval(() => refreshToken(), 30 * 60 * 1000);
14
+ * return () => clearInterval(timer);
15
+ * }, [refreshToken]);
16
+ * ```
17
+ */
18
+ 'use client';
19
+ import { useCallback, useState } from 'react';
20
+ import { useStorefrontClientContext } from '../providers/storefront-client-provider';
21
+ import { useAuthStore, useAuthStoreApi } from '../stores/store-context';
22
+ import { StorefrontError } from '../../core/errors';
23
+ export function useRefreshToken(options = {}) {
24
+ const { authClient } = useStorefrontClientContext();
25
+ const { setAuth } = useAuthStore();
26
+ const authStore = useAuthStoreApi();
27
+ const [isRefreshingToken, setIsRefreshingToken] = useState(false);
28
+ const [error, setError] = useState(null);
29
+ const refreshToken = useCallback(async () => {
30
+ setError(null);
31
+ setIsRefreshingToken(true);
32
+ try {
33
+ // Auth context resolved server-side from cookie/Bearer. If no active
34
+ // session, backend returns 401 and refreshToken throws.
35
+ const result = await authClient.refreshToken();
36
+ if (options.onSetToken) {
37
+ await options.onSetToken(result.accessToken);
38
+ }
39
+ const currentCustomer = authStore.getState().customer;
40
+ if (currentCustomer) {
41
+ setAuth(currentCustomer, result.accessToken);
42
+ }
43
+ return {
44
+ success: true,
45
+ userErrors: [],
46
+ accessToken: result.accessToken,
47
+ expiresAt: result.expiresAt,
48
+ };
49
+ }
50
+ catch (err) {
51
+ if (err instanceof StorefrontError && err.hasUserErrors) {
52
+ return {
53
+ success: false,
54
+ userErrors: err.userErrors.map((e) => ({ message: e.message, field: e.field })),
55
+ };
56
+ }
57
+ const message = err instanceof Error ? err.message : 'Token renewal failed';
58
+ setError(message);
59
+ return { success: false, userErrors: [{ message }] };
60
+ }
61
+ finally {
62
+ setIsRefreshingToken(false);
63
+ }
64
+ }, [authClient, setAuth, authStore, options]);
65
+ return { refreshToken, isRefreshingToken, error };
66
+ }
@@ -16,7 +16,10 @@ export { StorefrontClientProvider, type StorefrontClientProviderProps } from './
16
16
  export { CurrencyProvider, type CurrencyProviderProps } from './providers/currency-provider';
17
17
  export { LanguageProvider, type LanguageProviderProps } from './providers/language-provider';
18
18
  export { useAuth, type UseAuthOptions, type LoginResult, type LogoutResult, type TokenRefreshResult } from './hooks/use-auth';
19
- export { useCartManager } from './hooks/use-cart-manager';
19
+ export { useLogin, type UseLoginOptions, type UseLoginReturn } from './hooks/use-login';
20
+ export { useLogout, type UseLogoutOptions, type UseLogoutReturn } from './hooks/use-logout';
21
+ export { useRefreshToken, type UseRefreshTokenOptions, type UseRefreshTokenReturn } from './hooks/use-refresh-token';
22
+ export { useCartManager, type CartManagerOperation, type CartManagerStatus, type UseCartManagerResult } from './hooks/use-cart-manager';
20
23
  export { useStorefrontClient } from './hooks/use-storefront-client';
21
24
  export { useCurrency } from './hooks/use-currency';
22
25
  export { useAuthStore, useAuthStoreApi, useAuthHydrated } from './stores/store-context';
@@ -28,7 +31,7 @@ export type { LanguageStore } from './stores/language.store';
28
31
  export type { ShopConfig } from './types/shop-config';
29
32
  export { selectCurrency, selectBaseCurrency, selectSupportedCurrencies, selectIsLoaded } from './stores/currency.store';
30
33
  export { selectLanguage, selectDefaultLanguage, selectSupportedLanguages, selectLanguageIsLoaded } from './stores/language.store';
31
- export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync } from './cookies';
34
+ export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync, createBrowserCartCookieStore, } from './cookies';
32
35
  export { useBotProtection } from './hooks/use-bot-protection';
33
36
  export { useHydrated } from './hooks/use-hydrated';
34
37
  export { useDebouncedValue } from './hooks/use-debounced-value';
@@ -36,4 +39,5 @@ export { createCartStore, selectCartId, selectIsCartOpen, selectCartIsLoading, }
36
39
  export type { CartState, CartStoreConfig, CartActions, CartData, CartMutationAction, CartLineInput, CartLineUpdateInput, } from './stores/cart.store';
37
40
  export { CartProvider, useCartStore, useCartStoreApi } from './stores/cart.context';
38
41
  export { createStoreContext } from './helpers/create-store-context';
42
+ export { Money, type MoneyProps, Image, type ImageComponentProps, CartCount, type CartCountProps, AddToCartButton, type AddToCartButtonProps, PriceDisplay, type PriceDisplayProps, CartTotals, type CartTotalsProps, type CartTotalsLabels, } from './components';
39
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AACnG,OAAO,EAAE,wBAAwB,EAAE,KAAK,6BAA6B,EAAE,MAAM,wCAAwC,CAAC;AACtH,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAG7F,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9H,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG/E,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACxH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAGlI,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrH,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EACL,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,9 @@ export { CurrencyProvider } from './providers/currency-provider';
18
18
  export { LanguageProvider } from './providers/language-provider';
19
19
  // Hooks
20
20
  export { useAuth } from './hooks/use-auth';
21
+ export { useLogin } from './hooks/use-login';
22
+ export { useLogout } from './hooks/use-logout';
23
+ export { useRefreshToken } from './hooks/use-refresh-token';
21
24
  export { useCartManager } from './hooks/use-cart-manager';
22
25
  export { useStorefrontClient } from './hooks/use-storefront-client';
23
26
  export { useCurrency } from './hooks/use-currency';
@@ -29,7 +32,7 @@ export { useLanguageStore, useLanguageStoreApi } from './stores/store-context';
29
32
  export { selectCurrency, selectBaseCurrency, selectSupportedCurrencies, selectIsLoaded } from './stores/currency.store';
30
33
  export { selectLanguage, selectDefaultLanguage, selectSupportedLanguages, selectLanguageIsLoaded } from './stores/language.store';
31
34
  // Cookie utilities
32
- export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync } from './cookies';
35
+ export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync, createBrowserCartCookieStore, } from './cookies';
33
36
  // Bot protection
34
37
  export { useBotProtection } from './hooks/use-bot-protection';
35
38
  // Generic hooks
@@ -40,3 +43,5 @@ export { createCartStore, selectCartId, selectIsCartOpen, selectCartIsLoading, }
40
43
  export { CartProvider, useCartStore, useCartStoreApi } from './stores/cart.context';
41
44
  // Store context helper
42
45
  export { createStoreContext } from './helpers/create-store-context';
46
+ // Pre-built components (headless — no styling, accessibility-aware)
47
+ export { Money, Image, CartCount, AddToCartButton, PriceDisplay, CartTotals, } from './components';
@@ -21,13 +21,23 @@
21
21
  */
22
22
  import type { StorefrontClient, StorefrontClientConfig, Middleware } from '../../core/client/types';
23
23
  export interface ServerClientOptions extends Omit<StorefrontClientConfig, 'middleware'> {
24
- /**
25
- * Function that returns request-scoped headers (e.g. currency from cookie).
26
- * Called once per client creation.
27
- */
28
- getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
29
24
  /**
30
25
  * Additional middleware (prepended to default pipeline).
26
+ *
27
+ * Use this for request-scoped headers (e.g. currency from cookie, language
28
+ * from URL, custom tracking):
29
+ *
30
+ * ```ts
31
+ * getStorefrontClient({
32
+ * apiUrl, shopSlug,
33
+ * middleware: [
34
+ * async (req, next) => {
35
+ * req.headers['X-Preferred-Currency'] = await readCookieFromHeaders();
36
+ * return next(req);
37
+ * },
38
+ * ],
39
+ * });
40
+ * ```
31
41
  */
32
42
  middleware?: Middleware[];
33
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-storefront-client.d.ts","sourceRoot":"","sources":["../../../src/react/server/get-storefront-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEpG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC;IACrF;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAYlF"}
1
+ {"version":3,"file":"get-storefront-client.d.ts","sourceRoot":"","sources":["../../../src/react/server/get-storefront-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEpG,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC;IACrF;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAYlF"}
@@ -1,27 +1,50 @@
1
1
  /**
2
- * Cart Store — DI-based cart state management with cookie persistence.
2
+ * Cart Store — DI-based cart state management with cookie persistence and
3
+ * automatic stale-cart recovery.
3
4
  *
4
- * SDK orchestrates cart lifecycle (init, mutations, error handling).
5
- * Template provides CartActions implementation via DI (getActions getter).
6
- * Cart ID persisted in cookie (SSR/edge visible) — follows currency store pattern.
5
+ * SDK orchestrates cart lifecycle (init, mutations, recovery, error handling).
6
+ * Template provides `CartActions` via DI (getActions getter). Cart id persisted
7
+ * in cookie (SSR/edge visible) — follows currency store pattern.
8
+ *
9
+ * Per-operation recovery strategy (DX-first — caller never thinks about it):
10
+ *
11
+ * - **`addToCart`** auto-replays on stale-cart errors. If the template
12
+ * implements the optional `actions.createCartWithLines`, recovery is atomic
13
+ * (single `cartCreate({ lines })` round trip). Otherwise falls back to
14
+ * `createCart()` + `addLines()` (2 round trips, same end result).
15
+ *
16
+ * - **`updateQuantity`** and **`removeFromCart`** bail on stale-cart errors:
17
+ * local cart id is cleared, `onExpired` listeners fire, error surfaces via
18
+ * `onMutationError`. Replaying on a fresh empty cart would silently lose
19
+ * user intent (the lineId no longer exists).
20
+ *
21
+ * Stale-cart detection inspects `err.userErrors[].code` (CART_NOT_FOUND /
22
+ * ALREADY_COMPLETED) — locale-proof, see {@link isCartRecoverableError}.
7
23
  *
8
24
  * @example
9
25
  * ```typescript
10
26
  * import { createCartStore, type CartActions } from '@doswiftly/storefront-sdk/react';
11
27
  *
12
28
  * const actions: CartActions = {
13
- * fetchCart: async (cartId) => api.getCart(cartId),
14
- * createCart: async () => api.createCart().then(c => c.id),
15
- * addLines: async (cartId, lines) => api.addLines(cartId, lines),
16
- * updateLines: async (cartId, lines) => api.updateLines(cartId, lines),
17
- * removeLines: async (cartId, lineIds) => api.removeLines(cartId, lineIds),
29
+ * fetchCart: (id) => api.getCart(id),
30
+ * createCart: () => api.createCart().then(c => c.id),
31
+ * addLines: (id, lines) => api.addLines(id, lines),
32
+ * updateLines: (id, lines) => api.updateLines(id, lines),
33
+ * removeLines: (id, ids) => api.removeLines(id, ids),
34
+ * // optional — enables atomic add-to-cart recovery
35
+ * createCartWithLines: (lines) => api.cartCreate({ lines }),
18
36
  * };
19
37
  *
20
- * const store = createCartStore({ getActions: () => actions });
38
+ * const store = createCartStore({
39
+ * getActions: () => actions,
40
+ * onExpired: (e) => toast.error('Koszyk wygasł, dodaj produkty ponownie'),
41
+ * });
21
42
  * ```
22
43
  */
23
44
  import type { CartLineInput, CartLineUpdateInput } from '../../core/cart/types';
45
+ import { type CartExpiredEvent } from '../../core/cart/cart-recovery';
24
46
  export type { CartLineInput, CartLineUpdateInput } from '../../core/cart/types';
47
+ export type { CartExpiredEvent } from '../../core/cart/cart-recovery';
25
48
  /** Minimal cart data returned by DI actions. */
26
49
  export interface CartData {
27
50
  id: string;
@@ -39,6 +62,16 @@ export interface CartActions {
39
62
  updateLines: (cartId: string, lines: CartLineUpdateInput[]) => Promise<CartData>;
40
63
  /** Remove line items. Return updated cart or throw. */
41
64
  removeLines: (cartId: string, lineIds: string[]) => Promise<CartData>;
65
+ /**
66
+ * Optional — atomic create-with-lines for stale-cart recovery. When provided,
67
+ * the store recovers from `CART_NOT_FOUND` / `ALREADY_COMPLETED` in a single
68
+ * `cartCreate({ lines })` round trip. When omitted, store falls back to
69
+ * `createCart()` + `addLines()` (2 round trips, identical outcome).
70
+ *
71
+ * Wire this when your GraphQL `cartCreate` mutation accepts an initial
72
+ * `lines` payload (DoSwiftly Storefront API does).
73
+ */
74
+ createCartWithLines?: (lines: CartLineInput[]) => Promise<CartData>;
42
75
  }
43
76
  /** Action names passed to mutation callbacks. */
44
77
  export type CartMutationAction = 'initCart' | 'addToCart' | 'updateQuantity' | 'removeFromCart';
@@ -49,6 +82,20 @@ export interface CartStoreConfig {
49
82
  onMutationSuccess?: (action: CartMutationAction, cart: CartData) => void;
50
83
  /** Called on mutation error. */
51
84
  onMutationError?: (action: CartMutationAction, error: unknown) => void;
85
+ /**
86
+ * Called when a stale-cart event terminates an operation:
87
+ *
88
+ * - `state-dependent` — bail-on-stale operation (`updateQuantity`,
89
+ * `removeFromCart`) cannot be safely replayed on a new cart.
90
+ * - `recreate-failed` — recovery attempted but creating the replacement
91
+ * cart failed (network / backend error).
92
+ * - `retry-also-failed` — replacement cart also rejected by backend
93
+ * (rare; usually indicates a backend race / bug).
94
+ *
95
+ * Typical UI usage: subscribe once globally and surface a toast / banner
96
+ * inviting the user to add products again.
97
+ */
98
+ onExpired?: (event: CartExpiredEvent) => void;
52
99
  }
53
100
  export interface CartState {
54
101
  cartId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"cart.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/cart.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAKhF,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAMhF,gDAAgD;AAChD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACxD,iDAAiD;IACjD,UAAU,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,oDAAoD;IACpD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxE,4DAA4D;IAC5D,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjF,uDAAuD;IACvD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CACvE;AAMD,iDAAiD;AACjD,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAEhG,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,UAAU,EAAE,MAAM,WAAW,CAAC;IAC9B,wCAAwC;IACxC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACzE,gCAAgC;IAChC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACxE;AAMD,MAAM,WAAW,SAAS;IAExB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAGtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IAGvB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,cAAc,EAAE,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAMD,eAAO,MAAM,YAAY,GAAI,OAAO,SAAS,kBAAiB,CAAC;AAC/D,eAAO,MAAM,gBAAgB,GAAI,OAAO,SAAS,YAAiB,CAAC;AACnE,eAAO,MAAM,mBAAmB,GAAI,OAAO,SAAS,YAAoB,CAAC;AAMzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,yCAkJtD"}
1
+ {"version":3,"file":"cart.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/cart.store.ts"],"names":[],"mappings":"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"}