@spree/next 0.6.0 → 0.6.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.
- package/README.md +39 -5
- package/dist/actions/locale.d.ts +10 -0
- package/dist/actions/locale.js +59 -0
- package/dist/actions/locale.js.map +1 -0
- package/dist/actions/orders.d.ts +2 -2
- package/dist/actions/orders.js.map +1 -1
- package/dist/data/countries.d.ts +2 -0
- package/dist/data/countries.js +26 -8
- package/dist/data/countries.js.map +1 -1
- package/dist/data/currencies.d.ts +1 -0
- package/dist/data/currencies.js +24 -4
- package/dist/data/currencies.js.map +1 -1
- package/dist/data/locales.d.ts +1 -0
- package/dist/data/locales.js +24 -4
- package/dist/data/locales.js.map +1 -1
- package/dist/data/products.d.ts +5 -2
- package/dist/data/products.js +28 -12
- package/dist/data/products.js.map +1 -1
- package/dist/data/store.d.ts +1 -0
- package/dist/data/store.js +24 -4
- package/dist/data/store.js.map +1 -1
- package/dist/data/taxonomies.d.ts +2 -0
- package/dist/data/taxonomies.js +26 -8
- package/dist/data/taxonomies.js.map +1 -1
- package/dist/data/taxons.d.ts +6 -3
- package/dist/data/taxons.js +28 -12
- package/dist/data/taxons.js.map +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +58 -54
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +12 -0
- package/dist/locale.js +52 -0
- package/dist/locale.js.map +1 -0
- package/dist/middleware.d.ts +26 -0
- package/dist/middleware.js +28 -0
- package/dist/middleware.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ import { listProducts, getProduct, listTaxons } from '@spree/next';
|
|
|
40
40
|
|
|
41
41
|
export default async function ProductsPage() {
|
|
42
42
|
const products = await listProducts({ per_page: 12 });
|
|
43
|
-
const categories = await listTaxons({
|
|
43
|
+
const categories = await listTaxons({ depth_eq: 1 });
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
46
|
<div>
|
|
@@ -104,7 +104,7 @@ const filters = await getProductFilters({ taxon_id: 'txn_123' });
|
|
|
104
104
|
import { listTaxons, getTaxon, listTaxonProducts } from '@spree/next';
|
|
105
105
|
import { listTaxonomies, getTaxonomy } from '@spree/next';
|
|
106
106
|
|
|
107
|
-
const taxons = await listTaxons({
|
|
107
|
+
const taxons = await listTaxons({ depth_eq: 1 });
|
|
108
108
|
const taxon = await getTaxon('categories/clothing');
|
|
109
109
|
const products = await listTaxonProducts('categories/clothing', { per_page: 12 });
|
|
110
110
|
|
|
@@ -240,11 +240,45 @@ const giftCard = await getGiftCard(giftCardId);
|
|
|
240
240
|
|
|
241
241
|
## Localization
|
|
242
242
|
|
|
243
|
-
|
|
243
|
+
### Automatic (recommended)
|
|
244
|
+
|
|
245
|
+
Data functions automatically read locale and country from cookies. Use the included middleware to handle URL-based routing and cookie persistence:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// middleware.ts
|
|
249
|
+
import { createSpreeMiddleware } from '@spree/next/middleware';
|
|
250
|
+
|
|
251
|
+
export default createSpreeMiddleware({
|
|
252
|
+
defaultCountry: 'us',
|
|
253
|
+
defaultLocale: 'en',
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
export const config = {
|
|
257
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\..*$).*)'],
|
|
258
|
+
};
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Data functions work without any locale arguments:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
const products = await listProducts({ per_page: 10 });
|
|
265
|
+
const taxon = await getTaxon('categories/clothing');
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Use the `setLocale` server action in country/language switchers:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { setLocale } from '@spree/next';
|
|
272
|
+
|
|
273
|
+
await setLocale({ country: 'de', locale: 'de' });
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Manual override
|
|
277
|
+
|
|
278
|
+
You can still pass locale options explicitly — they override auto-detected values:
|
|
244
279
|
|
|
245
280
|
```typescript
|
|
246
|
-
const products = await listProducts({ per_page: 10 }, { locale: 'fr',
|
|
247
|
-
const taxon = await getTaxon('categories/clothing', {}, { locale: 'de', currency: 'EUR' });
|
|
281
|
+
const products = await listProducts({ per_page: 10 }, { locale: 'fr', country: 'FR' });
|
|
248
282
|
```
|
|
249
283
|
|
|
250
284
|
## TypeScript
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set locale/country cookies for subsequent requests.
|
|
3
|
+
* Use this in country/language switchers instead of manipulating cookies directly.
|
|
4
|
+
*/
|
|
5
|
+
declare function setLocale(params: {
|
|
6
|
+
country?: string;
|
|
7
|
+
locale?: string;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
|
|
10
|
+
export { setLocale };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
// src/actions/locale.ts
|
|
4
|
+
import { cookies } from "next/headers";
|
|
5
|
+
|
|
6
|
+
// src/config.ts
|
|
7
|
+
import { createSpreeClient } from "@spree/sdk";
|
|
8
|
+
var _client = null;
|
|
9
|
+
var _config = null;
|
|
10
|
+
function initSpreeNext(config) {
|
|
11
|
+
_config = config;
|
|
12
|
+
_client = createSpreeClient({
|
|
13
|
+
baseUrl: config.baseUrl,
|
|
14
|
+
publishableKey: config.publishableKey
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function getClient() {
|
|
18
|
+
if (!_client) {
|
|
19
|
+
const baseUrl = process.env.SPREE_API_URL;
|
|
20
|
+
const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;
|
|
21
|
+
if (baseUrl && publishableKey) {
|
|
22
|
+
initSpreeNext({ baseUrl, publishableKey });
|
|
23
|
+
} else {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables."
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return _client;
|
|
30
|
+
}
|
|
31
|
+
function getConfig() {
|
|
32
|
+
if (!_config) {
|
|
33
|
+
getClient();
|
|
34
|
+
}
|
|
35
|
+
return _config;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/actions/locale.ts
|
|
39
|
+
async function setLocale(params) {
|
|
40
|
+
const config = getConfig();
|
|
41
|
+
const cookieStore = await cookies();
|
|
42
|
+
const maxAge = 60 * 60 * 24 * 365;
|
|
43
|
+
if (params.country) {
|
|
44
|
+
cookieStore.set(config.countryCookieName ?? "spree_country", params.country, {
|
|
45
|
+
path: "/",
|
|
46
|
+
maxAge
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (params.locale) {
|
|
50
|
+
cookieStore.set(config.localeCookieName ?? "spree_locale", params.locale, {
|
|
51
|
+
path: "/",
|
|
52
|
+
maxAge
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
setLocale
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=locale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/actions/locale.ts","../../src/config.ts"],"sourcesContent":["'use server';\n\nimport { cookies } from 'next/headers';\nimport { getConfig } from '../config';\n\n/**\n * Set locale/country cookies for subsequent requests.\n * Use this in country/language switchers instead of manipulating cookies directly.\n */\nexport async function setLocale(params: {\n country?: string;\n locale?: string;\n}): Promise<void> {\n const config = getConfig();\n const cookieStore = await cookies();\n const maxAge = 60 * 60 * 24 * 365; // 1 year\n\n if (params.country) {\n cookieStore.set(config.countryCookieName ?? 'spree_country', params.country, {\n path: '/',\n maxAge,\n });\n }\n if (params.locale) {\n cookieStore.set(config.localeCookieName ?? 'spree_locale', params.locale, {\n path: '/',\n maxAge,\n });\n }\n}\n","import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n"],"mappings":";;;AAEA,SAAS,eAAe;;;ACFxB,SAAS,yBAA2C;AAGpD,IAAI,UAA8B;AAClC,IAAI,UAAkC;AAO/B,SAAS,cAAc,QAA+B;AAC3D,YAAU;AACV,YAAU,kBAAkB;AAAA,IAC1B,SAAS,OAAO;AAAA,IAChB,gBAAgB,OAAO;AAAA,EACzB,CAAC;AACH;AAMO,SAAS,YAAyB;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,QAAQ,IAAI;AAC5B,UAAM,iBAAiB,QAAQ,IAAI;AACnC,QAAI,WAAW,gBAAgB;AAC7B,oBAAc,EAAE,SAAS,eAAe,CAAC;AAAA,IAC3C,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,YAA6B;AAC3C,MAAI,CAAC,SAAS;AACZ,cAAU;AAAA,EACZ;AACA,SAAO;AACT;;;ADtCA,eAAsB,UAAU,QAGd;AAChB,QAAM,SAAS,UAAU;AACzB,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,SAAS,KAAK,KAAK,KAAK;AAE9B,MAAI,OAAO,SAAS;AAClB,gBAAY,IAAI,OAAO,qBAAqB,iBAAiB,OAAO,SAAS;AAAA,MAC3E,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,OAAO,QAAQ;AACjB,gBAAY,IAAI,OAAO,oBAAoB,gBAAgB,OAAO,QAAQ;AAAA,MACxE,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AACF;","names":[]}
|
package/dist/actions/orders.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { StoreOrder, PaginatedResponse } from '@spree/sdk';
|
|
1
|
+
import { StoreOrder, OrderListParams, PaginatedResponse } from '@spree/sdk';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* List the authenticated customer's orders.
|
|
5
5
|
*/
|
|
6
|
-
declare function listOrders(params?:
|
|
6
|
+
declare function listOrders(params?: OrderListParams): Promise<PaginatedResponse<StoreOrder>>;
|
|
7
7
|
/**
|
|
8
8
|
* Get a single order by ID or number.
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth-helpers.ts","../../src/config.ts","../../src/cookies.ts","../../src/actions/orders.ts"],"sourcesContent":["import { SpreeError } from '@spree/sdk';\nimport type { RequestOptions } from '@spree/sdk';\nimport { getClient } from './config';\nimport { getAccessToken, setAccessToken, clearAccessToken } from './cookies';\n\n/**\n * Get auth request options from the current JWT token.\n * Proactively refreshes the token if it expires within 1 hour.\n */\nexport async function getAuthOptions(): Promise<RequestOptions> {\n const token = await getAccessToken();\n if (!token) {\n return {};\n }\n\n // Check if token is close to expiry by decoding JWT payload\n try {\n const payload = JSON.parse(atob(token.split('.')[1]));\n const exp = payload.exp;\n const now = Math.floor(Date.now() / 1000);\n\n // Refresh if token expires in less than 1 hour\n if (exp && exp - now < 3600) {\n try {\n const refreshed = await getClient().store.auth.refresh({ token });\n await setAccessToken(refreshed.token);\n return { token: refreshed.token };\n } catch {\n // Refresh failed — use existing token, it might still work\n }\n }\n } catch {\n // Can't decode JWT — use it as-is, the server will reject if invalid\n }\n\n return { token };\n}\n\n/**\n * Execute an authenticated request with automatic token refresh on 401.\n * @param fn - Function that takes RequestOptions and returns a promise\n * @returns The result of the function\n * @throws SpreeError if auth fails after refresh attempt\n */\nexport async function withAuthRefresh<T>(\n fn: (options: RequestOptions) => Promise<T>\n): Promise<T> {\n const options = await getAuthOptions();\n\n if (!options.token) {\n throw new Error('Not authenticated');\n }\n\n try {\n return await fn(options);\n } catch (error: unknown) {\n // If 401, try refreshing the token once\n if (error instanceof SpreeError && error.status === 401) {\n try {\n const refreshed = await getClient().store.auth.refresh({ token: options.token });\n await setAccessToken(refreshed.token);\n return await fn({ token: refreshed.token });\n } catch {\n // Refresh failed — clear token and rethrow\n await clearAccessToken();\n throw error;\n }\n }\n throw error;\n }\n}\n","import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_CART_COOKIE = '_spree_cart_token';\nconst DEFAULT_ACCESS_TOKEN_COOKIE = '_spree_jwt';\nconst CART_TOKEN_MAX_AGE = 60 * 60 * 24 * 30; // 30 days\nconst ACCESS_TOKEN_MAX_AGE = 60 * 60 * 24 * 7; // 7 days\n\nfunction getCartCookieName(): string {\n try {\n return getConfig().cartCookieName ?? DEFAULT_CART_COOKIE;\n } catch {\n return DEFAULT_CART_COOKIE;\n }\n}\n\nfunction getAccessTokenCookieName(): string {\n try {\n return getConfig().accessTokenCookieName ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n } catch {\n return DEFAULT_ACCESS_TOKEN_COOKIE;\n }\n}\n\n// --- Cart Token ---\n\nexport async function getCartToken(): Promise<string | undefined> {\n const cookieStore = await cookies();\n return cookieStore.get(getCartCookieName())?.value;\n}\n\nexport async function setCartToken(token: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getCartCookieName(), token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: CART_TOKEN_MAX_AGE,\n });\n}\n\nexport async function clearCartToken(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getCartCookieName(), '', {\n maxAge: -1,\n path: '/',\n });\n}\n\n// --- Access Token (JWT) ---\n\nexport async function getAccessToken(): Promise<string | undefined> {\n const cookieStore = await cookies();\n return cookieStore.get(getAccessTokenCookieName())?.value;\n}\n\nexport async function setAccessToken(token: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getAccessTokenCookieName(), token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: ACCESS_TOKEN_MAX_AGE,\n });\n}\n\nexport async function clearAccessToken(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getAccessTokenCookieName(), '', {\n maxAge: -1,\n path: '/',\n });\n}\n","'use server';\n\nimport type { StoreOrder, PaginatedResponse } from '@spree/sdk';\nimport { withAuthRefresh } from '../auth-helpers';\nimport { getClient } from '../config';\n\n/**\n * List the authenticated customer's orders.\n */\nexport async function listOrders(\n params?:
|
|
1
|
+
{"version":3,"sources":["../../src/auth-helpers.ts","../../src/config.ts","../../src/cookies.ts","../../src/actions/orders.ts"],"sourcesContent":["import { SpreeError } from '@spree/sdk';\nimport type { RequestOptions } from '@spree/sdk';\nimport { getClient } from './config';\nimport { getAccessToken, setAccessToken, clearAccessToken } from './cookies';\n\n/**\n * Get auth request options from the current JWT token.\n * Proactively refreshes the token if it expires within 1 hour.\n */\nexport async function getAuthOptions(): Promise<RequestOptions> {\n const token = await getAccessToken();\n if (!token) {\n return {};\n }\n\n // Check if token is close to expiry by decoding JWT payload\n try {\n const payload = JSON.parse(atob(token.split('.')[1]));\n const exp = payload.exp;\n const now = Math.floor(Date.now() / 1000);\n\n // Refresh if token expires in less than 1 hour\n if (exp && exp - now < 3600) {\n try {\n const refreshed = await getClient().store.auth.refresh({ token });\n await setAccessToken(refreshed.token);\n return { token: refreshed.token };\n } catch {\n // Refresh failed — use existing token, it might still work\n }\n }\n } catch {\n // Can't decode JWT — use it as-is, the server will reject if invalid\n }\n\n return { token };\n}\n\n/**\n * Execute an authenticated request with automatic token refresh on 401.\n * @param fn - Function that takes RequestOptions and returns a promise\n * @returns The result of the function\n * @throws SpreeError if auth fails after refresh attempt\n */\nexport async function withAuthRefresh<T>(\n fn: (options: RequestOptions) => Promise<T>\n): Promise<T> {\n const options = await getAuthOptions();\n\n if (!options.token) {\n throw new Error('Not authenticated');\n }\n\n try {\n return await fn(options);\n } catch (error: unknown) {\n // If 401, try refreshing the token once\n if (error instanceof SpreeError && error.status === 401) {\n try {\n const refreshed = await getClient().store.auth.refresh({ token: options.token });\n await setAccessToken(refreshed.token);\n return await fn({ token: refreshed.token });\n } catch {\n // Refresh failed — clear token and rethrow\n await clearAccessToken();\n throw error;\n }\n }\n throw error;\n }\n}\n","import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_CART_COOKIE = '_spree_cart_token';\nconst DEFAULT_ACCESS_TOKEN_COOKIE = '_spree_jwt';\nconst CART_TOKEN_MAX_AGE = 60 * 60 * 24 * 30; // 30 days\nconst ACCESS_TOKEN_MAX_AGE = 60 * 60 * 24 * 7; // 7 days\n\nfunction getCartCookieName(): string {\n try {\n return getConfig().cartCookieName ?? DEFAULT_CART_COOKIE;\n } catch {\n return DEFAULT_CART_COOKIE;\n }\n}\n\nfunction getAccessTokenCookieName(): string {\n try {\n return getConfig().accessTokenCookieName ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n } catch {\n return DEFAULT_ACCESS_TOKEN_COOKIE;\n }\n}\n\n// --- Cart Token ---\n\nexport async function getCartToken(): Promise<string | undefined> {\n const cookieStore = await cookies();\n return cookieStore.get(getCartCookieName())?.value;\n}\n\nexport async function setCartToken(token: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getCartCookieName(), token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: CART_TOKEN_MAX_AGE,\n });\n}\n\nexport async function clearCartToken(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getCartCookieName(), '', {\n maxAge: -1,\n path: '/',\n });\n}\n\n// --- Access Token (JWT) ---\n\nexport async function getAccessToken(): Promise<string | undefined> {\n const cookieStore = await cookies();\n return cookieStore.get(getAccessTokenCookieName())?.value;\n}\n\nexport async function setAccessToken(token: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getAccessTokenCookieName(), token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n maxAge: ACCESS_TOKEN_MAX_AGE,\n });\n}\n\nexport async function clearAccessToken(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(getAccessTokenCookieName(), '', {\n maxAge: -1,\n path: '/',\n });\n}\n","'use server';\n\nimport type { StoreOrder, PaginatedResponse, OrderListParams } from '@spree/sdk';\nimport { withAuthRefresh } from '../auth-helpers';\nimport { getClient } from '../config';\n\n/**\n * List the authenticated customer's orders.\n */\nexport async function listOrders(\n params?: OrderListParams\n): Promise<PaginatedResponse<StoreOrder>> {\n return withAuthRefresh(async (options) => {\n return getClient().store.customer.orders.list(params, options);\n });\n}\n\n/**\n * Get a single order by ID or number.\n */\nexport async function getOrder(\n idOrNumber: string,\n params?: Record<string, unknown>\n): Promise<StoreOrder> {\n return withAuthRefresh(async (options) => {\n return getClient().store.orders.get(idOrNumber, params, options);\n });\n}\n"],"mappings":";;;AAAA,SAAS,kBAAkB;;;ACA3B,SAAS,yBAA2C;AAGpD,IAAI,UAA8B;AAClC,IAAI,UAAkC;AAO/B,SAAS,cAAc,QAA+B;AAC3D,YAAU;AACV,YAAU,kBAAkB;AAAA,IAC1B,SAAS,OAAO;AAAA,IAChB,gBAAgB,OAAO;AAAA,EACzB,CAAC;AACH;AAMO,SAAS,YAAyB;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,QAAQ,IAAI;AAC5B,UAAM,iBAAiB,QAAQ,IAAI;AACnC,QAAI,WAAW,gBAAgB;AAC7B,oBAAc,EAAE,SAAS,eAAe,CAAC;AAAA,IAC3C,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,YAA6B;AAC3C,MAAI,CAAC,SAAS;AACZ,cAAU;AAAA,EACZ;AACA,SAAO;AACT;;;AC/CA,SAAS,eAAe;AAIxB,IAAM,8BAA8B;AACpC,IAAM,qBAAqB,KAAK,KAAK,KAAK;AAC1C,IAAM,uBAAuB,KAAK,KAAK,KAAK;AAU5C,SAAS,2BAAmC;AAC1C,MAAI;AACF,WAAO,UAAU,EAAE,yBAAyB;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA8BA,eAAsB,iBAA8C;AAClE,QAAM,cAAc,MAAM,QAAQ;AAClC,SAAO,YAAY,IAAI,yBAAyB,CAAC,GAAG;AACtD;AAEA,eAAsB,eAAe,OAA8B;AACjE,QAAM,cAAc,MAAM,QAAQ;AAClC,cAAY,IAAI,yBAAyB,GAAG,OAAO;AAAA,IACjD,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,eAAsB,mBAAkC;AACtD,QAAM,cAAc,MAAM,QAAQ;AAClC,cAAY,IAAI,yBAAyB,GAAG,IAAI;AAAA,IAC9C,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AACH;;;AFjEA,eAAsB,iBAA0C;AAC9D,QAAM,QAAQ,MAAM,eAAe;AACnC,MAAI,CAAC,OAAO;AACV,WAAO,CAAC;AAAA,EACV;AAGA,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACpD,UAAM,MAAM,QAAQ;AACpB,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAGxC,QAAI,OAAO,MAAM,MAAM,MAAM;AAC3B,UAAI;AACF,cAAM,YAAY,MAAM,UAAU,EAAE,MAAM,KAAK,QAAQ,EAAE,MAAM,CAAC;AAChE,cAAM,eAAe,UAAU,KAAK;AACpC,eAAO,EAAE,OAAO,UAAU,MAAM;AAAA,MAClC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO,EAAE,MAAM;AACjB;AAQA,eAAsB,gBACpB,IACY;AACZ,QAAM,UAAU,MAAM,eAAe;AAErC,MAAI,CAAC,QAAQ,OAAO;AAClB,UAAM,IAAI,MAAM,mBAAmB;AAAA,EACrC;AAEA,MAAI;AACF,WAAO,MAAM,GAAG,OAAO;AAAA,EACzB,SAAS,OAAgB;AAEvB,QAAI,iBAAiB,cAAc,MAAM,WAAW,KAAK;AACvD,UAAI;AACF,cAAM,YAAY,MAAM,UAAU,EAAE,MAAM,KAAK,QAAQ,EAAE,OAAO,QAAQ,MAAM,CAAC;AAC/E,cAAM,eAAe,UAAU,KAAK;AACpC,eAAO,MAAM,GAAG,EAAE,OAAO,UAAU,MAAM,CAAC;AAAA,MAC5C,QAAQ;AAEN,cAAM,iBAAiB;AACvB,cAAM;AAAA,MACR;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;;;AG7DA,eAAsB,WACpB,QACwC;AACxC,SAAO,gBAAgB,OAAO,YAAY;AACxC,WAAO,UAAU,EAAE,MAAM,SAAS,OAAO,KAAK,QAAQ,OAAO;AAAA,EAC/D,CAAC;AACH;AAKA,eAAsB,SACpB,YACA,QACqB;AACrB,SAAO,gBAAgB,OAAO,YAAY;AACxC,WAAO,UAAU,EAAE,MAAM,OAAO,IAAI,YAAY,QAAQ,OAAO;AAAA,EACjE,CAAC;AACH;","names":[]}
|
package/dist/data/countries.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { SpreeNextOptions } from '../types.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* List countries available in the store.
|
|
6
6
|
* Each country includes currency and default_locale derived from its market.
|
|
7
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
7
8
|
*/
|
|
8
9
|
declare function listCountries(options?: SpreeNextOptions): Promise<{
|
|
9
10
|
data: StoreCountry[];
|
|
@@ -12,6 +13,7 @@ declare function listCountries(options?: SpreeNextOptions): Promise<{
|
|
|
12
13
|
* Get a country by ISO code.
|
|
13
14
|
* @param iso - ISO 3166-1 alpha-2 code (e.g., "US", "DE")
|
|
14
15
|
* @param params - Optional params (e.g., { include: 'states' } for address forms)
|
|
16
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
15
17
|
*/
|
|
16
18
|
declare function getCountry(iso: string, params?: {
|
|
17
19
|
include?: string;
|
package/dist/data/countries.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createSpreeClient } from '@spree/sdk';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
2
3
|
|
|
3
4
|
// src/config.ts
|
|
4
5
|
var _client = null;
|
|
6
|
+
var _config = null;
|
|
5
7
|
function initSpreeNext(config) {
|
|
8
|
+
_config = config;
|
|
6
9
|
_client = createSpreeClient({
|
|
7
10
|
baseUrl: config.baseUrl,
|
|
8
11
|
publishableKey: config.publishableKey
|
|
@@ -22,19 +25,34 @@ function getClient() {
|
|
|
22
25
|
}
|
|
23
26
|
return _client;
|
|
24
27
|
}
|
|
28
|
+
function getConfig() {
|
|
29
|
+
if (!_config) {
|
|
30
|
+
getClient();
|
|
31
|
+
}
|
|
32
|
+
return _config;
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_COUNTRY_COOKIE = "spree_country";
|
|
35
|
+
var DEFAULT_LOCALE_COOKIE = "spree_locale";
|
|
36
|
+
async function getLocaleOptions() {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const cookieStore = await cookies();
|
|
39
|
+
const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;
|
|
40
|
+
const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;
|
|
41
|
+
return {
|
|
42
|
+
locale: locale || config.defaultLocale,
|
|
43
|
+
country: country || config.defaultCountry
|
|
44
|
+
// No currency — backend resolves from country via X-Spree-Country header
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
// src/data/countries.ts
|
|
27
49
|
async function listCountries(options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
currency: options?.currency
|
|
31
|
-
});
|
|
50
|
+
const resolved = options ?? await getLocaleOptions();
|
|
51
|
+
return getClient().store.countries.list(resolved);
|
|
32
52
|
}
|
|
33
53
|
async function getCountry(iso, params, options) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
currency: options?.currency
|
|
37
|
-
});
|
|
54
|
+
const resolved = options ?? await getLocaleOptions();
|
|
55
|
+
return getClient().store.countries.get(iso, params, resolved);
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
export { getCountry, listCountries };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts","../../src/data/countries.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config.ts","../../src/locale.ts","../../src/data/countries.ts"],"names":[],"mappings":";;;;AAGA,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAI,OAAA,GAAkC,IAAA;AAO/B,SAAS,cAAc,MAAA,EAA+B;AAC3D,EAAA,OAAA,GAAU,MAAA;AACV,EAAA,OAAA,GAAU,iBAAA,CAAkB;AAAA,IAC1B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,gBAAgB,MAAA,CAAO;AAAA,GACxB,CAAA;AACH;AAMO,SAAS,SAAA,GAAyB;AACvC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA;AAC5B,IAAA,MAAM,cAAA,GAAiB,QAAQ,GAAA,CAAI,qBAAA;AACnC,IAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,MAAA,aAAA,CAAc,EAAE,OAAA,EAAS,cAAA,EAAgB,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,SAAA,GAA6B;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,SAAA,EAAU;AAAA,EACZ;AACA,EAAA,OAAO,OAAA;AACT;AC5CA,IAAM,sBAAA,GAAyB,eAAA;AAC/B,IAAM,qBAAA,GAAwB,cAAA;AAO9B,eAAsB,gBAAA,GAInB;AACD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,WAAA,GAAc,MAAM,OAAA,EAAQ;AAElC,EAAA,MAAM,UAAU,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,iBAAA,IAAqB,sBAAsB,CAAA,EAAG,KAAA;AACrF,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,gBAAA,IAAoB,qBAAqB,CAAA,EAAG,KAAA;AAElF,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,UAAU,MAAA,CAAO,aAAA;AAAA,IACzB,OAAA,EAAS,WAAW,MAAA,CAAO;AAAA;AAAA,GAE7B;AACF;;;ACjBA,eAAsB,cACpB,OAAA,EACmC;AACnC,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,SAAA,EAAU,CAAE,KAAA,CAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAClD;AAQA,eAAsB,UAAA,CACpB,GAAA,EACA,MAAA,EACA,OAAA,EACuB;AACvB,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,WAAU,CAAE,KAAA,CAAM,UAAU,GAAA,CAAI,GAAA,EAAK,QAAQ,QAAQ,CAAA;AAC9D","file":"countries.js","sourcesContent":["import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_COUNTRY_COOKIE = 'spree_country';\nconst DEFAULT_LOCALE_COOKIE = 'spree_locale';\n\n/**\n * Read locale/currency/country from cookies (set by middleware).\n * Falls back to config defaults.\n * @internal\n */\nexport async function getLocaleOptions(): Promise<{\n locale?: string;\n currency?: string;\n country?: string;\n}> {\n const config = getConfig();\n const cookieStore = await cookies();\n\n const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;\n const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;\n\n return {\n locale: locale || config.defaultLocale,\n country: country || config.defaultCountry,\n // No currency — backend resolves from country via X-Spree-Country header\n };\n}\n","import type { StoreCountry } from '@spree/sdk';\nimport { getClient } from '../config';\nimport { getLocaleOptions } from '../locale';\nimport type { SpreeNextOptions } from '../types';\n\n/**\n * List countries available in the store.\n * Each country includes currency and default_locale derived from its market.\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function listCountries(\n options?: SpreeNextOptions\n): Promise<{ data: StoreCountry[] }> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.countries.list(resolved);\n}\n\n/**\n * Get a country by ISO code.\n * @param iso - ISO 3166-1 alpha-2 code (e.g., \"US\", \"DE\")\n * @param params - Optional params (e.g., { include: 'states' } for address forms)\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function getCountry(\n iso: string,\n params?: { include?: string },\n options?: SpreeNextOptions\n): Promise<StoreCountry> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.countries.get(iso, params, resolved);\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import { SpreeNextOptions } from '../types.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* List currencies supported by the store (derived from markets).
|
|
6
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
6
7
|
*/
|
|
7
8
|
declare function listCurrencies(options?: SpreeNextOptions): Promise<{
|
|
8
9
|
data: StoreCurrency[];
|
package/dist/data/currencies.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createSpreeClient } from '@spree/sdk';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
2
3
|
|
|
3
4
|
// src/config.ts
|
|
4
5
|
var _client = null;
|
|
6
|
+
var _config = null;
|
|
5
7
|
function initSpreeNext(config) {
|
|
8
|
+
_config = config;
|
|
6
9
|
_client = createSpreeClient({
|
|
7
10
|
baseUrl: config.baseUrl,
|
|
8
11
|
publishableKey: config.publishableKey
|
|
@@ -22,13 +25,30 @@ function getClient() {
|
|
|
22
25
|
}
|
|
23
26
|
return _client;
|
|
24
27
|
}
|
|
28
|
+
function getConfig() {
|
|
29
|
+
if (!_config) {
|
|
30
|
+
getClient();
|
|
31
|
+
}
|
|
32
|
+
return _config;
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_COUNTRY_COOKIE = "spree_country";
|
|
35
|
+
var DEFAULT_LOCALE_COOKIE = "spree_locale";
|
|
36
|
+
async function getLocaleOptions() {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const cookieStore = await cookies();
|
|
39
|
+
const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;
|
|
40
|
+
const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;
|
|
41
|
+
return {
|
|
42
|
+
locale: locale || config.defaultLocale,
|
|
43
|
+
country: country || config.defaultCountry
|
|
44
|
+
// No currency — backend resolves from country via X-Spree-Country header
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
// src/data/currencies.ts
|
|
27
49
|
async function listCurrencies(options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
currency: options?.currency
|
|
31
|
-
});
|
|
50
|
+
const resolved = options ?? await getLocaleOptions();
|
|
51
|
+
return getClient().store.currencies.list(resolved);
|
|
32
52
|
}
|
|
33
53
|
|
|
34
54
|
export { listCurrencies };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts","../../src/data/currencies.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config.ts","../../src/locale.ts","../../src/data/currencies.ts"],"names":[],"mappings":";;;;AAGA,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAI,OAAA,GAAkC,IAAA;AAO/B,SAAS,cAAc,MAAA,EAA+B;AAC3D,EAAA,OAAA,GAAU,MAAA;AACV,EAAA,OAAA,GAAU,iBAAA,CAAkB;AAAA,IAC1B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,gBAAgB,MAAA,CAAO;AAAA,GACxB,CAAA;AACH;AAMO,SAAS,SAAA,GAAyB;AACvC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA;AAC5B,IAAA,MAAM,cAAA,GAAiB,QAAQ,GAAA,CAAI,qBAAA;AACnC,IAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,MAAA,aAAA,CAAc,EAAE,OAAA,EAAS,cAAA,EAAgB,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,SAAA,GAA6B;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,SAAA,EAAU;AAAA,EACZ;AACA,EAAA,OAAO,OAAA;AACT;AC5CA,IAAM,sBAAA,GAAyB,eAAA;AAC/B,IAAM,qBAAA,GAAwB,cAAA;AAO9B,eAAsB,gBAAA,GAInB;AACD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,WAAA,GAAc,MAAM,OAAA,EAAQ;AAElC,EAAA,MAAM,UAAU,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,iBAAA,IAAqB,sBAAsB,CAAA,EAAG,KAAA;AACrF,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,gBAAA,IAAoB,qBAAqB,CAAA,EAAG,KAAA;AAElF,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,UAAU,MAAA,CAAO,aAAA;AAAA,IACzB,OAAA,EAAS,WAAW,MAAA,CAAO;AAAA;AAAA,GAE7B;AACF;;;AClBA,eAAsB,eACpB,OAAA,EACoC;AACpC,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,SAAA,EAAU,CAAE,KAAA,CAAM,UAAA,CAAW,KAAK,QAAQ,CAAA;AACnD","file":"currencies.js","sourcesContent":["import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_COUNTRY_COOKIE = 'spree_country';\nconst DEFAULT_LOCALE_COOKIE = 'spree_locale';\n\n/**\n * Read locale/currency/country from cookies (set by middleware).\n * Falls back to config defaults.\n * @internal\n */\nexport async function getLocaleOptions(): Promise<{\n locale?: string;\n currency?: string;\n country?: string;\n}> {\n const config = getConfig();\n const cookieStore = await cookies();\n\n const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;\n const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;\n\n return {\n locale: locale || config.defaultLocale,\n country: country || config.defaultCountry,\n // No currency — backend resolves from country via X-Spree-Country header\n };\n}\n","import type { StoreCurrency } from '@spree/sdk';\nimport { getClient } from '../config';\nimport { getLocaleOptions } from '../locale';\nimport type { SpreeNextOptions } from '../types';\n\n/**\n * List currencies supported by the store (derived from markets).\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function listCurrencies(\n options?: SpreeNextOptions\n): Promise<{ data: StoreCurrency[] }> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.currencies.list(resolved);\n}\n"]}
|
package/dist/data/locales.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { SpreeNextOptions } from '../types.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* List locales supported by the store (derived from markets).
|
|
6
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
6
7
|
*/
|
|
7
8
|
declare function listLocales(options?: SpreeNextOptions): Promise<{
|
|
8
9
|
data: StoreLocale[];
|
package/dist/data/locales.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createSpreeClient } from '@spree/sdk';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
2
3
|
|
|
3
4
|
// src/config.ts
|
|
4
5
|
var _client = null;
|
|
6
|
+
var _config = null;
|
|
5
7
|
function initSpreeNext(config) {
|
|
8
|
+
_config = config;
|
|
6
9
|
_client = createSpreeClient({
|
|
7
10
|
baseUrl: config.baseUrl,
|
|
8
11
|
publishableKey: config.publishableKey
|
|
@@ -22,13 +25,30 @@ function getClient() {
|
|
|
22
25
|
}
|
|
23
26
|
return _client;
|
|
24
27
|
}
|
|
28
|
+
function getConfig() {
|
|
29
|
+
if (!_config) {
|
|
30
|
+
getClient();
|
|
31
|
+
}
|
|
32
|
+
return _config;
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_COUNTRY_COOKIE = "spree_country";
|
|
35
|
+
var DEFAULT_LOCALE_COOKIE = "spree_locale";
|
|
36
|
+
async function getLocaleOptions() {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const cookieStore = await cookies();
|
|
39
|
+
const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;
|
|
40
|
+
const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;
|
|
41
|
+
return {
|
|
42
|
+
locale: locale || config.defaultLocale,
|
|
43
|
+
country: country || config.defaultCountry
|
|
44
|
+
// No currency — backend resolves from country via X-Spree-Country header
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
// src/data/locales.ts
|
|
27
49
|
async function listLocales(options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
currency: options?.currency
|
|
31
|
-
});
|
|
50
|
+
const resolved = options ?? await getLocaleOptions();
|
|
51
|
+
return getClient().store.locales.list(resolved);
|
|
32
52
|
}
|
|
33
53
|
|
|
34
54
|
export { listLocales };
|
package/dist/data/locales.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts","../../src/data/locales.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config.ts","../../src/locale.ts","../../src/data/locales.ts"],"names":[],"mappings":";;;;AAGA,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAI,OAAA,GAAkC,IAAA;AAO/B,SAAS,cAAc,MAAA,EAA+B;AAC3D,EAAA,OAAA,GAAU,MAAA;AACV,EAAA,OAAA,GAAU,iBAAA,CAAkB;AAAA,IAC1B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,gBAAgB,MAAA,CAAO;AAAA,GACxB,CAAA;AACH;AAMO,SAAS,SAAA,GAAyB;AACvC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA;AAC5B,IAAA,MAAM,cAAA,GAAiB,QAAQ,GAAA,CAAI,qBAAA;AACnC,IAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,MAAA,aAAA,CAAc,EAAE,OAAA,EAAS,cAAA,EAAgB,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,SAAA,GAA6B;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,SAAA,EAAU;AAAA,EACZ;AACA,EAAA,OAAO,OAAA;AACT;AC5CA,IAAM,sBAAA,GAAyB,eAAA;AAC/B,IAAM,qBAAA,GAAwB,cAAA;AAO9B,eAAsB,gBAAA,GAInB;AACD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,WAAA,GAAc,MAAM,OAAA,EAAQ;AAElC,EAAA,MAAM,UAAU,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,iBAAA,IAAqB,sBAAsB,CAAA,EAAG,KAAA;AACrF,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,gBAAA,IAAoB,qBAAqB,CAAA,EAAG,KAAA;AAElF,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,UAAU,MAAA,CAAO,aAAA;AAAA,IACzB,OAAA,EAAS,WAAW,MAAA,CAAO;AAAA;AAAA,GAE7B;AACF;;;AClBA,eAAsB,YACpB,OAAA,EACkC;AAClC,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,SAAA,EAAU,CAAE,KAAA,CAAM,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAChD","file":"locales.js","sourcesContent":["import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_COUNTRY_COOKIE = 'spree_country';\nconst DEFAULT_LOCALE_COOKIE = 'spree_locale';\n\n/**\n * Read locale/currency/country from cookies (set by middleware).\n * Falls back to config defaults.\n * @internal\n */\nexport async function getLocaleOptions(): Promise<{\n locale?: string;\n currency?: string;\n country?: string;\n}> {\n const config = getConfig();\n const cookieStore = await cookies();\n\n const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;\n const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;\n\n return {\n locale: locale || config.defaultLocale,\n country: country || config.defaultCountry,\n // No currency — backend resolves from country via X-Spree-Country header\n };\n}\n","import type { StoreLocale } from '@spree/sdk';\nimport { getClient } from '../config';\nimport { getLocaleOptions } from '../locale';\nimport type { SpreeNextOptions } from '../types';\n\n/**\n * List locales supported by the store (derived from markets).\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function listLocales(\n options?: SpreeNextOptions\n): Promise<{ data: StoreLocale[] }> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.locales.list(resolved);\n}\n"]}
|
package/dist/data/products.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import { StoreProduct, ProductFiltersResponse, PaginatedResponse } from '@spree/sdk';
|
|
1
|
+
import { StoreProduct, ProductFiltersResponse, ProductListParams, PaginatedResponse } from '@spree/sdk';
|
|
2
2
|
import { SpreeNextOptions } from '../types.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* List products with optional filtering, sorting, and pagination.
|
|
6
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
6
7
|
*/
|
|
7
|
-
declare function listProducts(params?:
|
|
8
|
+
declare function listProducts(params?: ProductListParams, options?: SpreeNextOptions): Promise<PaginatedResponse<StoreProduct>>;
|
|
8
9
|
/**
|
|
9
10
|
* Get a single product by slug or ID.
|
|
11
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
10
12
|
*/
|
|
11
13
|
declare function getProduct(slugOrId: string, params?: {
|
|
12
14
|
includes?: string;
|
|
13
15
|
}, options?: SpreeNextOptions): Promise<StoreProduct>;
|
|
14
16
|
/**
|
|
15
17
|
* Get available product filters (price ranges, option values, etc.).
|
|
18
|
+
* Locale/country are auto-read from cookies when not provided.
|
|
16
19
|
*/
|
|
17
20
|
declare function getProductFilters(params?: Record<string, unknown>, options?: SpreeNextOptions): Promise<ProductFiltersResponse>;
|
|
18
21
|
|
package/dist/data/products.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createSpreeClient } from '@spree/sdk';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
2
3
|
|
|
3
4
|
// src/config.ts
|
|
4
5
|
var _client = null;
|
|
6
|
+
var _config = null;
|
|
5
7
|
function initSpreeNext(config) {
|
|
8
|
+
_config = config;
|
|
6
9
|
_client = createSpreeClient({
|
|
7
10
|
baseUrl: config.baseUrl,
|
|
8
11
|
publishableKey: config.publishableKey
|
|
@@ -22,25 +25,38 @@ function getClient() {
|
|
|
22
25
|
}
|
|
23
26
|
return _client;
|
|
24
27
|
}
|
|
28
|
+
function getConfig() {
|
|
29
|
+
if (!_config) {
|
|
30
|
+
getClient();
|
|
31
|
+
}
|
|
32
|
+
return _config;
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_COUNTRY_COOKIE = "spree_country";
|
|
35
|
+
var DEFAULT_LOCALE_COOKIE = "spree_locale";
|
|
36
|
+
async function getLocaleOptions() {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const cookieStore = await cookies();
|
|
39
|
+
const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;
|
|
40
|
+
const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;
|
|
41
|
+
return {
|
|
42
|
+
locale: locale || config.defaultLocale,
|
|
43
|
+
country: country || config.defaultCountry
|
|
44
|
+
// No currency — backend resolves from country via X-Spree-Country header
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
// src/data/products.ts
|
|
27
49
|
async function listProducts(params, options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
currency: options?.currency
|
|
31
|
-
});
|
|
50
|
+
const resolved = options ?? await getLocaleOptions();
|
|
51
|
+
return getClient().store.products.list(params, resolved);
|
|
32
52
|
}
|
|
33
53
|
async function getProduct(slugOrId, params, options) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
currency: options?.currency
|
|
37
|
-
});
|
|
54
|
+
const resolved = options ?? await getLocaleOptions();
|
|
55
|
+
return getClient().store.products.get(slugOrId, params, resolved);
|
|
38
56
|
}
|
|
39
57
|
async function getProductFilters(params, options) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
currency: options?.currency
|
|
43
|
-
});
|
|
58
|
+
const resolved = options ?? await getLocaleOptions();
|
|
59
|
+
return getClient().store.products.filters(params, resolved);
|
|
44
60
|
}
|
|
45
61
|
|
|
46
62
|
export { getProduct, getProductFilters, listProducts };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts","../../src/data/products.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config.ts","../../src/locale.ts","../../src/data/products.ts"],"names":[],"mappings":";;;;AAGA,IAAI,OAAA,GAA8B,IAAA;AAClC,IAAI,OAAA,GAAkC,IAAA;AAO/B,SAAS,cAAc,MAAA,EAA+B;AAC3D,EAAA,OAAA,GAAU,MAAA;AACV,EAAA,OAAA,GAAU,iBAAA,CAAkB;AAAA,IAC1B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,gBAAgB,MAAA,CAAO;AAAA,GACxB,CAAA;AACH;AAMO,SAAS,SAAA,GAAyB;AACvC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA;AAC5B,IAAA,MAAM,cAAA,GAAiB,QAAQ,GAAA,CAAI,qBAAA;AACnC,IAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,MAAA,aAAA,CAAc,EAAE,OAAA,EAAS,cAAA,EAAgB,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,SAAA,GAA6B;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,SAAA,EAAU;AAAA,EACZ;AACA,EAAA,OAAO,OAAA;AACT;AC5CA,IAAM,sBAAA,GAAyB,eAAA;AAC/B,IAAM,qBAAA,GAAwB,cAAA;AAO9B,eAAsB,gBAAA,GAInB;AACD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,WAAA,GAAc,MAAM,OAAA,EAAQ;AAElC,EAAA,MAAM,UAAU,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,iBAAA,IAAqB,sBAAsB,CAAA,EAAG,KAAA;AACrF,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,gBAAA,IAAoB,qBAAqB,CAAA,EAAG,KAAA;AAElF,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,UAAU,MAAA,CAAO,aAAA;AAAA,IACzB,OAAA,EAAS,WAAW,MAAA,CAAO;AAAA;AAAA,GAE7B;AACF;;;AClBA,eAAsB,YAAA,CACpB,QACA,OAAA,EAC0C;AAC1C,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,WAAU,CAAE,KAAA,CAAM,QAAA,CAAS,IAAA,CAAK,QAAQ,QAAQ,CAAA;AACzD;AAMA,eAAsB,UAAA,CACpB,QAAA,EACA,MAAA,EACA,OAAA,EACuB;AACvB,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,WAAU,CAAE,KAAA,CAAM,SAAS,GAAA,CAAI,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAClE;AAMA,eAAsB,iBAAA,CACpB,QACA,OAAA,EACiC;AACjC,EAAA,MAAM,QAAA,GAAW,OAAA,IAAW,MAAM,gBAAA,EAAiB;AACnD,EAAA,OAAO,WAAU,CAAE,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,QAAQ,QAAQ,CAAA;AAC5D","file":"products.js","sourcesContent":["import { createSpreeClient, type SpreeClient } from '@spree/sdk';\nimport type { SpreeNextConfig } from './types';\n\nlet _client: SpreeClient | null = null;\nlet _config: SpreeNextConfig | null = null;\n\n/**\n * Initialize the Spree Next.js integration.\n * Call this once in your app (e.g., in `lib/storefront.ts`).\n * If not called, the client will auto-initialize from SPREE_API_URL and SPREE_PUBLISHABLE_KEY env vars.\n */\nexport function initSpreeNext(config: SpreeNextConfig): void {\n _config = config;\n _client = createSpreeClient({\n baseUrl: config.baseUrl,\n publishableKey: config.publishableKey,\n });\n}\n\n/**\n * Get the SpreeClient instance. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getClient(): SpreeClient {\n if (!_client) {\n const baseUrl = process.env.SPREE_API_URL;\n const publishableKey = process.env.SPREE_PUBLISHABLE_KEY;\n if (baseUrl && publishableKey) {\n initSpreeNext({ baseUrl, publishableKey });\n } else {\n throw new Error(\n '@spree/next is not configured. Either call initSpreeNext() or set SPREE_API_URL and SPREE_PUBLISHABLE_KEY environment variables.'\n );\n }\n }\n return _client!;\n}\n\n/**\n * Get the current config. Auto-initializes from env vars if needed.\n * @internal\n */\nexport function getConfig(): SpreeNextConfig {\n if (!_config) {\n getClient(); // triggers auto-init\n }\n return _config!;\n}\n\n/**\n * Reset the client (useful for testing).\n * @internal\n */\nexport function resetClient(): void {\n _client = null;\n _config = null;\n}\n","import { cookies } from 'next/headers';\nimport { getConfig } from './config';\n\nconst DEFAULT_COUNTRY_COOKIE = 'spree_country';\nconst DEFAULT_LOCALE_COOKIE = 'spree_locale';\n\n/**\n * Read locale/currency/country from cookies (set by middleware).\n * Falls back to config defaults.\n * @internal\n */\nexport async function getLocaleOptions(): Promise<{\n locale?: string;\n currency?: string;\n country?: string;\n}> {\n const config = getConfig();\n const cookieStore = await cookies();\n\n const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;\n const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;\n\n return {\n locale: locale || config.defaultLocale,\n country: country || config.defaultCountry,\n // No currency — backend resolves from country via X-Spree-Country header\n };\n}\n","import type { StoreProduct, PaginatedResponse, ProductFiltersResponse, ProductListParams } from '@spree/sdk';\nimport { getClient } from '../config';\nimport { getLocaleOptions } from '../locale';\nimport type { SpreeNextOptions } from '../types';\n\n/**\n * List products with optional filtering, sorting, and pagination.\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function listProducts(\n params?: ProductListParams,\n options?: SpreeNextOptions\n): Promise<PaginatedResponse<StoreProduct>> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.products.list(params, resolved);\n}\n\n/**\n * Get a single product by slug or ID.\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function getProduct(\n slugOrId: string,\n params?: { includes?: string },\n options?: SpreeNextOptions\n): Promise<StoreProduct> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.products.get(slugOrId, params, resolved);\n}\n\n/**\n * Get available product filters (price ranges, option values, etc.).\n * Locale/country are auto-read from cookies when not provided.\n */\nexport async function getProductFilters(\n params?: Record<string, unknown>,\n options?: SpreeNextOptions\n): Promise<ProductFiltersResponse> {\n const resolved = options ?? await getLocaleOptions();\n return getClient().store.products.filters(params, resolved);\n}\n"]}
|
package/dist/data/store.d.ts
CHANGED
package/dist/data/store.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createSpreeClient } from '@spree/sdk';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
2
3
|
|
|
3
4
|
// src/config.ts
|
|
4
5
|
var _client = null;
|
|
6
|
+
var _config = null;
|
|
5
7
|
function initSpreeNext(config) {
|
|
8
|
+
_config = config;
|
|
6
9
|
_client = createSpreeClient({
|
|
7
10
|
baseUrl: config.baseUrl,
|
|
8
11
|
publishableKey: config.publishableKey
|
|
@@ -22,13 +25,30 @@ function getClient() {
|
|
|
22
25
|
}
|
|
23
26
|
return _client;
|
|
24
27
|
}
|
|
28
|
+
function getConfig() {
|
|
29
|
+
if (!_config) {
|
|
30
|
+
getClient();
|
|
31
|
+
}
|
|
32
|
+
return _config;
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_COUNTRY_COOKIE = "spree_country";
|
|
35
|
+
var DEFAULT_LOCALE_COOKIE = "spree_locale";
|
|
36
|
+
async function getLocaleOptions() {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const cookieStore = await cookies();
|
|
39
|
+
const country = cookieStore.get(config.countryCookieName ?? DEFAULT_COUNTRY_COOKIE)?.value;
|
|
40
|
+
const locale = cookieStore.get(config.localeCookieName ?? DEFAULT_LOCALE_COOKIE)?.value;
|
|
41
|
+
return {
|
|
42
|
+
locale: locale || config.defaultLocale,
|
|
43
|
+
country: country || config.defaultCountry
|
|
44
|
+
// No currency — backend resolves from country via X-Spree-Country header
|
|
45
|
+
};
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
// src/data/store.ts
|
|
27
49
|
async function getStore(options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
currency: options?.currency
|
|
31
|
-
});
|
|
50
|
+
const resolved = options ?? await getLocaleOptions();
|
|
51
|
+
return getClient().store.store.get(resolved);
|
|
32
52
|
}
|
|
33
53
|
|
|
34
54
|
export { getStore };
|