@doswiftly/storefront-sdk 18.1.0 → 19.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # Changelog
2
2
 
3
+ ## 19.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 7ee241f: Move the server-side cookie readers to the server entry and rename them for intent.
8
+
9
+ The two async cookie readers now live in `@doswiftly/storefront-sdk/react/server` (next to
10
+ `getInitialAuth`) and are renamed to describe what they read instead of how:
11
+
12
+ | Removed (from `@doswiftly/storefront-sdk/react`) | New (in `@doswiftly/storefront-sdk/react/server`) |
13
+ | ------------------------------------------------ | ------------------------------------------------- |
14
+ | `getCurrencyFromCookieAsync()` | `readCurrencyCookie()` |
15
+ | `getCartIdFromCookieAsync()` | `readCartIdCookie()` |
16
+
17
+ Both keep the same return type, `Promise<string | null>`, and read the same cookies
18
+ (`preferred-currency`, `cart-id`). They are still server-first with a `document.cookie` fallback,
19
+ so they remain safe to call from either side — these cookies are readable (not httpOnly).
20
+
21
+ `getCookie`, `setCookie`, `deleteCookie`, and `createBrowserCartCookieStore` are unchanged and
22
+ still exported from `@doswiftly/storefront-sdk/react`.
23
+
24
+ **Why**: the readers depend on `next/headers`, a server-only API, but were exported from the
25
+ client React entry — so the entry's own description ("client-side; for server use `next/headers`")
26
+ contradicted two of its functions. Moving them next to `getInitialAuth` keeps `next/headers` out of
27
+ the client entry and gives both cold-start cookie reads (auth, and now cart-id / currency) one home.
28
+
29
+ **Migration** — update the import path and the names:
30
+
31
+ ```ts
32
+ // Before — client React entry
33
+ import {
34
+ getCurrencyFromCookieAsync,
35
+ getCartIdFromCookieAsync,
36
+ } from "@doswiftly/storefront-sdk/react";
37
+ const currency = await getCurrencyFromCookieAsync();
38
+ const cartId = await getCartIdFromCookieAsync();
39
+
40
+ // After — server entry (use in a Server Component)
41
+ import {
42
+ readCurrencyCookie,
43
+ readCartIdCookie,
44
+ } from "@doswiftly/storefront-sdk/react/server";
45
+ const currency = await readCurrencyCookie();
46
+ const cartId = await readCartIdCookie();
47
+ ```
48
+
49
+ Reading the cart-id server-side is the supported way to resolve a returning buyer's cart on the
50
+ first render — including when a separate checkout deployment shares the storefront domain:
51
+
52
+ ```ts
53
+ // app/checkout/page.tsx (Server Component)
54
+ import { readCartIdCookie } from "@doswiftly/storefront-sdk/react/server";
55
+
56
+ const cartId = await readCartIdCookie();
57
+ const cart = cartId ? await fetchCart(cartId) : null;
58
+ ```
59
+
60
+ **Migration checklist**:
61
+ - [ ] Replace `getCurrencyFromCookieAsync` / `getCartIdFromCookieAsync` imports from
62
+ `@doswiftly/storefront-sdk/react` with `readCurrencyCookie` / `readCartIdCookie` from
63
+ `@doswiftly/storefront-sdk/react/server`.
64
+ - [ ] For purely client-side reads, use `getCookie('preferred-currency')` /
65
+ `getCookie('cart-id')` (or `createBrowserCartCookieStore()` for the cart id) from
66
+ `@doswiftly/storefront-sdk/react` instead.
67
+
3
68
  ## 18.1.0
4
69
 
5
70
  ### Minor Changes
@@ -1,8 +1,10 @@
1
1
  /**
2
- * Cookie utilities for SDK consumers.
2
+ * Client-side cookie utilities for SDK consumers.
3
3
  *
4
- * Simple, framework-agnostic cookie read/write for client-side.
5
- * For Next.js server-side cookies, use `cookies()` from next/headers.
4
+ * Synchronous read/write over `document.cookie`, SSR-safe via a `typeof document`
5
+ * guard (return null / no-op when there is no document). To read these cookies in
6
+ * a Next.js Server Component use the `@doswiftly/storefront-sdk/react/server`
7
+ * entry (`readCartIdCookie`, `readCurrencyCookie`).
6
8
  */
7
9
  /**
8
10
  * Get cookie value by name (client-side only).
@@ -44,23 +46,4 @@ import type { CartCookieStore } from '../core/cart/cart-recovery';
44
46
  * ```
45
47
  */
46
48
  export declare function createBrowserCartCookieStore(): CartCookieStore;
47
- /**
48
- * Get preferred currency from cookie (async — works with Next.js cookies()).
49
- * Falls back to document.cookie on client.
50
- */
51
- export declare function getCurrencyFromCookieAsync(): Promise<string | null>;
52
- /**
53
- * Get cart ID from cookie (async — works with Next.js cookies()).
54
- * Falls back to document.cookie on client.
55
- *
56
- * Use in Server Components for SSR cart badge:
57
- * ```typescript
58
- * const cartId = await getCartIdFromCookieAsync();
59
- * if (cartId) {
60
- * const cart = await fetchCart(cartId);
61
- * // Render cart badge with real totalQuantity — no skeleton needed
62
- * }
63
- * ```
64
- */
65
- export declare function getCartIdFromCookieAsync(): Promise<string | null>;
66
49
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpF,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAID,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAQ9D;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYzE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYvE"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpF,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAGD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAQ9D"}
@@ -1,8 +1,10 @@
1
1
  /**
2
- * Cookie utilities for SDK consumers.
2
+ * Client-side cookie utilities for SDK consumers.
3
3
  *
4
- * Simple, framework-agnostic cookie read/write for client-side.
5
- * For Next.js server-side cookies, use `cookies()` from next/headers.
4
+ * Synchronous read/write over `document.cookie`, SSR-safe via a `typeof document`
5
+ * guard (return null / no-op when there is no document). To read these cookies in
6
+ * a Next.js Server Component use the `@doswiftly/storefront-sdk/react/server`
7
+ * entry (`readCartIdCookie`, `readCurrencyCookie`).
6
8
  */
7
9
  /**
8
10
  * Get cookie value by name (client-side only).
@@ -35,7 +37,6 @@ export function deleteCookie(name, path = '/') {
35
37
  return;
36
38
  document.cookie = `${name}=;max-age=0;path=${path}`;
37
39
  }
38
- import { CURRENCY_COOKIE_NAME } from '../core/currency/cookie-config';
39
40
  import { CART_COOKIE_NAME, CART_COOKIE_MAX_AGE } from '../core/cart/cookie-config';
40
41
  /**
41
42
  * Build a browser-side `CartCookieStore` backed by `document.cookie`.
@@ -65,46 +66,3 @@ export function createBrowserCartCookieStore() {
65
66
  clear: () => deleteCookie(CART_COOKIE_NAME),
66
67
  };
67
68
  }
68
- /**
69
- * Get preferred currency from cookie (async — works with Next.js cookies()).
70
- * Falls back to document.cookie on client.
71
- */
72
- export async function getCurrencyFromCookieAsync() {
73
- // Server-side: try Next.js cookies()
74
- try {
75
- const { cookies } = await import('next/headers');
76
- const cookieStore = await cookies();
77
- return cookieStore.get(CURRENCY_COOKIE_NAME)?.value ?? null;
78
- }
79
- catch {
80
- // Not in a server context or next not available
81
- }
82
- // Client-side fallback
83
- return getCookie(CURRENCY_COOKIE_NAME);
84
- }
85
- /**
86
- * Get cart ID from cookie (async — works with Next.js cookies()).
87
- * Falls back to document.cookie on client.
88
- *
89
- * Use in Server Components for SSR cart badge:
90
- * ```typescript
91
- * const cartId = await getCartIdFromCookieAsync();
92
- * if (cartId) {
93
- * const cart = await fetchCart(cartId);
94
- * // Render cart badge with real totalQuantity — no skeleton needed
95
- * }
96
- * ```
97
- */
98
- export async function getCartIdFromCookieAsync() {
99
- // Server-side: try Next.js cookies()
100
- try {
101
- const { cookies } = await import('next/headers');
102
- const cookieStore = await cookies();
103
- return cookieStore.get(CART_COOKIE_NAME)?.value ?? null;
104
- }
105
- catch {
106
- // Not in a server context or next not available
107
- }
108
- // Client-side fallback
109
- return getCookie(CART_COOKIE_NAME);
110
- }
@@ -36,7 +36,7 @@ export type { LanguageStore } from './stores/language.store';
36
36
  export type { ShopConfig } from './types/shop-config';
37
37
  export { selectCurrency, selectBaseCurrency, selectSupportedCurrencies, selectIsLoaded } from './stores/currency.store';
38
38
  export { selectLanguage, selectDefaultLanguage, selectSupportedLanguages, selectLanguageIsLoaded } from './stores/language.store';
39
- export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync, createBrowserCartCookieStore, } from './cookies';
39
+ export { getCookie, setCookie, deleteCookie, createBrowserCartCookieStore, } from './cookies';
40
40
  export { useBotProtection } from './hooks/use-bot-protection';
41
41
  export { useHydrated } from './hooks/use-hydrated';
42
42
  export { useDebouncedValue } from './hooks/use-debounced-value';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -35,8 +35,9 @@ export { useLanguageStore, useLanguageStoreApi } from './stores/store-context';
35
35
  // Selectors
36
36
  export { selectCurrency, selectBaseCurrency, selectSupportedCurrencies, selectIsLoaded } from './stores/currency.store';
37
37
  export { selectLanguage, selectDefaultLanguage, selectSupportedLanguages, selectLanguageIsLoaded } from './stores/language.store';
38
- // Cookie utilities
39
- export { getCookie, setCookie, deleteCookie, getCurrencyFromCookieAsync, getCartIdFromCookieAsync, createBrowserCartCookieStore, } from './cookies';
38
+ // Cookie utilities (client-side). Server-side readers (readCartIdCookie,
39
+ // readCurrencyCookie) live in `@doswiftly/storefront-sdk/react/server`.
40
+ export { getCookie, setCookie, deleteCookie, createBrowserCartCookieStore, } from './cookies';
40
41
  // Bot protection
41
42
  export { useBotProtection } from './hooks/use-bot-protection';
42
43
  // Generic hooks
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Server-first readers for the storefront's readable first-party cookies.
3
+ *
4
+ * `readCartIdCookie` / `readCurrencyCookie` return the `cart-id` /
5
+ * `preferred-currency` cookie value. They run server-first: in a Next.js Server
6
+ * Component they read the request cookies via `next/headers`; when that is
7
+ * unavailable (client bundle, build time, non-Next runtime) they fall back to
8
+ * `document.cookie`. This isomorphic behaviour is deliberate and safe here
9
+ * because both cookies are readable (NOT httpOnly) — unlike the auth token,
10
+ * which `getInitialAuth` reads server-only precisely because it is httpOnly.
11
+ *
12
+ * They live under `@doswiftly/storefront-sdk/react/server` so the `next/headers`
13
+ * dependency stays out of the client entry; the dynamic import keeps importing
14
+ * this module safe in runtimes without `next/headers`.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // app/checkout/page.tsx (Server Component)
19
+ * import { readCartIdCookie } from '@doswiftly/storefront-sdk/react/server';
20
+ *
21
+ * const cartId = await readCartIdCookie();
22
+ * const cart = cartId ? await fetchCart(cartId) : null;
23
+ * ```
24
+ */
25
+ /** Read the first-party `cart-id` cookie (server-first, client fallback). */
26
+ export declare function readCartIdCookie(): Promise<string | null>;
27
+ /** Read the first-party `preferred-currency` cookie (server-first, client fallback). */
28
+ export declare function readCurrencyCookie(): Promise<string | null>;
29
+ //# sourceMappingURL=cookie-readers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-readers.d.ts","sourceRoot":"","sources":["../../../src/react/server/cookie-readers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAuBH,6EAA6E;AAC7E,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE/D;AAED,wFAAwF;AACxF,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEjE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Server-first readers for the storefront's readable first-party cookies.
3
+ *
4
+ * `readCartIdCookie` / `readCurrencyCookie` return the `cart-id` /
5
+ * `preferred-currency` cookie value. They run server-first: in a Next.js Server
6
+ * Component they read the request cookies via `next/headers`; when that is
7
+ * unavailable (client bundle, build time, non-Next runtime) they fall back to
8
+ * `document.cookie`. This isomorphic behaviour is deliberate and safe here
9
+ * because both cookies are readable (NOT httpOnly) — unlike the auth token,
10
+ * which `getInitialAuth` reads server-only precisely because it is httpOnly.
11
+ *
12
+ * They live under `@doswiftly/storefront-sdk/react/server` so the `next/headers`
13
+ * dependency stays out of the client entry; the dynamic import keeps importing
14
+ * this module safe in runtimes without `next/headers`.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // app/checkout/page.tsx (Server Component)
19
+ * import { readCartIdCookie } from '@doswiftly/storefront-sdk/react/server';
20
+ *
21
+ * const cartId = await readCartIdCookie();
22
+ * const cart = cartId ? await fetchCart(cartId) : null;
23
+ * ```
24
+ */
25
+ import { CART_COOKIE_NAME } from '../../core/cart/cookie-config';
26
+ import { CURRENCY_COOKIE_NAME } from '../../core/currency/cookie-config';
27
+ import { getCookie } from '../cookies';
28
+ /**
29
+ * Read a cookie server-first: the request cookies via `next/headers` in a Server
30
+ * Component, falling back to `document.cookie` on the client / outside a request
31
+ * scope. Returns null when the cookie is absent on both sides.
32
+ */
33
+ async function readCookieIsomorphic(name) {
34
+ try {
35
+ const { cookies } = await import('next/headers');
36
+ const store = await cookies();
37
+ return store.get(name)?.value ?? null;
38
+ }
39
+ catch {
40
+ // No Next.js server request scope (client bundle, build time, non-Next
41
+ // runtime) — fall back to the client reader (null on the server).
42
+ return getCookie(name);
43
+ }
44
+ }
45
+ /** Read the first-party `cart-id` cookie (server-first, client fallback). */
46
+ export async function readCartIdCookie() {
47
+ return readCookieIsomorphic(CART_COOKIE_NAME);
48
+ }
49
+ /** Read the first-party `preferred-currency` cookie (server-first, client fallback). */
50
+ export async function readCurrencyCookie() {
51
+ return readCookieIsomorphic(CURRENCY_COOKIE_NAME);
52
+ }
@@ -1,5 +1,6 @@
1
1
  export { getStorefrontClient, type ServerClientOptions } from './get-storefront-client';
2
2
  export { createStorefrontAuthRoute, type StorefrontAuthRouteOptions, type StorefrontAuthRouteHandlers, } from './create-storefront-auth-route';
3
3
  export { getInitialAuth, type InitialAuth } from './get-initial-auth';
4
+ export { readCartIdCookie, readCurrencyCookie } from './cookie-readers';
4
5
  export { trustedForwardedHostValidator, originAllowlistValidator, type OriginValidator, type OriginValidatorContext, } from '../../core/auth/handlers';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGxE,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC"}
@@ -3,5 +3,7 @@ export { getStorefrontClient } from './get-storefront-client';
3
3
  export { createStorefrontAuthRoute, } from './create-storefront-auth-route';
4
4
  // Server-only cold-start auth seed from the first-party cookies.
5
5
  export { getInitialAuth } from './get-initial-auth';
6
+ // Server-first readers for the readable first-party cookies (cart-id, currency).
7
+ export { readCartIdCookie, readCurrencyCookie } from './cookie-readers';
6
8
  // Origin validators — wire CSRF defense-in-depth on the route handlers from a single import.
7
9
  export { trustedForwardedHostValidator, originAllowlistValidator, } from '../../core/auth/handlers';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doswiftly/storefront-sdk",
3
- "version": "18.1.0",
3
+ "version": "19.0.0",
4
4
  "description": "Storefront runtime SDK for DoSwiftly Commerce — layered transport, middleware pipeline, React providers, Zustand stores, cache strategies. 0 runtime dependencies in core.",
5
5
  "type": "module",
6
6
  "sideEffects": false,