@commercengine/storefront-sdk 0.13.4 → 0.14.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/MIGRATION.md ADDED
@@ -0,0 +1,170 @@
1
+ # Storefront SDK Migration Guide
2
+
3
+ This guide covers the breaking changes introduced by the refactor that split
4
+ the SDK into explicit public and session-aware surfaces.
5
+
6
+ ## Summary
7
+
8
+ - `StorefrontSDK` was renamed to `SessionStorefrontSDK`
9
+ - `StorefrontAPIClient` was renamed to `SessionStorefrontAPIClient`
10
+ - `StorefrontSDKOptions` was renamed to `SessionStorefrontSDKOptions`
11
+ - The default export was removed
12
+ - `createStorefront()` is now the recommended entry point
13
+ - `PublicStorefrontSDK` was added for strict API-key-backed public reads
14
+
15
+ ## Recommended Migration
16
+
17
+ Move to the factory pattern:
18
+
19
+ ```typescript
20
+ import {
21
+ BrowserTokenStorage,
22
+ Environment,
23
+ createStorefront,
24
+ } from "@commercengine/storefront-sdk";
25
+
26
+ export const storefront = createStorefront({
27
+ storeId: "your-store-id",
28
+ apiKey: "your-api-key",
29
+ environment: Environment.Staging,
30
+ session: {
31
+ tokenStorage: new BrowserTokenStorage("myapp_"),
32
+ },
33
+ });
34
+ ```
35
+
36
+ Then use the explicit accessor that matches the request:
37
+
38
+ ```typescript
39
+ const publicSdk = storefront.public();
40
+ const sessionSdk = storefront.session();
41
+ ```
42
+
43
+ ## Before / After
44
+
45
+ ### Managed session SDK
46
+
47
+ Before:
48
+
49
+ ```typescript
50
+ import StorefrontSDK, {
51
+ BrowserTokenStorage,
52
+ Environment,
53
+ } from "@commercengine/storefront-sdk";
54
+
55
+ const sdk = new StorefrontSDK({
56
+ storeId: "your-store-id",
57
+ apiKey: "your-api-key",
58
+ environment: Environment.Staging,
59
+ tokenStorage: new BrowserTokenStorage("myapp_"),
60
+ });
61
+ ```
62
+
63
+ After:
64
+
65
+ ```typescript
66
+ import {
67
+ BrowserTokenStorage,
68
+ Environment,
69
+ createStorefront,
70
+ } from "@commercengine/storefront-sdk";
71
+
72
+ const storefront = createStorefront({
73
+ storeId: "your-store-id",
74
+ apiKey: "your-api-key",
75
+ environment: Environment.Staging,
76
+ session: {
77
+ tokenStorage: new BrowserTokenStorage("myapp_"),
78
+ },
79
+ });
80
+
81
+ const sdk = storefront.session();
82
+ ```
83
+
84
+ ### Manual / stateless seeded tokens
85
+
86
+ Before:
87
+
88
+ ```typescript
89
+ import { StorefrontSDK } from "@commercengine/storefront-sdk";
90
+
91
+ const sdk = new StorefrontSDK({
92
+ storeId: "your-store-id",
93
+ apiKey: "your-api-key",
94
+ accessToken,
95
+ refreshToken,
96
+ });
97
+ ```
98
+
99
+ After:
100
+
101
+ ```typescript
102
+ import { createStorefront } from "@commercengine/storefront-sdk";
103
+
104
+ const storefront = createStorefront({
105
+ storeId: "your-store-id",
106
+ apiKey: "your-api-key",
107
+ });
108
+
109
+ const sdk = storefront.session({
110
+ accessToken,
111
+ refreshToken,
112
+ });
113
+ ```
114
+
115
+ ### Public build / prerender reads
116
+
117
+ Before:
118
+
119
+ ```typescript
120
+ import { StorefrontSDK } from "@commercengine/storefront-sdk";
121
+
122
+ const sdk = new StorefrontSDK({
123
+ storeId: "your-store-id",
124
+ apiKey: "your-api-key",
125
+ });
126
+ ```
127
+
128
+ After:
129
+
130
+ ```typescript
131
+ import { createStorefront } from "@commercengine/storefront-sdk";
132
+
133
+ const storefront = createStorefront({
134
+ storeId: "your-store-id",
135
+ apiKey: "your-api-key",
136
+ });
137
+
138
+ const sdk = storefront.public();
139
+ ```
140
+
141
+ ## Advanced Direct Instantiation
142
+
143
+ If you need direct class construction, use the explicit class names:
144
+
145
+ ```typescript
146
+ import {
147
+ PublicStorefrontSDK,
148
+ SessionStorefrontSDK,
149
+ } from "@commercengine/storefront-sdk";
150
+ ```
151
+
152
+ The session SDK keeps the same managed/manual token behavior as before:
153
+
154
+ - provide `tokenStorage` for managed mode
155
+ - provide `accessToken` / `refreshToken` or call `setTokens()` for manual mode
156
+
157
+ ## Public vs Session Surface
158
+
159
+ Use `public()` only for public reads that should never touch session bootstrap,
160
+ refresh, token persistence, or token callbacks.
161
+
162
+ Use `session()` for:
163
+
164
+ - auth flows
165
+ - cart operations
166
+ - customer operations
167
+ - order operations
168
+ - payment operations
169
+ - any request that should operate on behalf of an anonymous or authenticated
170
+ user session
package/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  A powerful, type-safe TypeScript SDK for the CommerceEngine Storefront API. Built with modern JavaScript patterns, automatic token management, and comprehensive error handling.
4
4
 
5
+ Breaking changes from the previous SDK surface are documented in
6
+ [MIGRATION.md](./MIGRATION.md).
7
+
5
8
  **✨ Key Features:**
6
9
  - **100% Type Safe**: Every API endpoint is fully typed with TypeScript
7
10
  - **Automatic Token Management**: Built-in refresh token logic for seamless authentication
@@ -26,53 +29,54 @@ pnpm add @commercengine/storefront-sdk
26
29
  ## Quick Start
27
30
 
28
31
  ```typescript
29
- import StorefrontSDK, { Environment } from "@commercengine/storefront-sdk";
32
+ import {
33
+ BrowserTokenStorage,
34
+ Environment,
35
+ createStorefront,
36
+ } from "@commercengine/storefront-sdk";
30
37
 
31
- // Basic initialization
32
- const sdk = new StorefrontSDK({
38
+ const storefront = createStorefront({
33
39
  storeId: "your-store-id",
34
40
  environment: Environment.Staging,
35
- apiKey: "your-api-key", // Required for authentication
41
+ apiKey: "your-api-key",
42
+ session: {
43
+ tokenStorage: new BrowserTokenStorage("myapp_"),
44
+ },
36
45
  });
37
46
 
38
- // Get started with anonymous authentication
39
- const { data, error } = await sdk.auth.getAnonymousToken();
40
- if (error) {
41
- console.log(error)
42
- } else {
43
- accessToken = data.accessToken
44
- }
47
+ // Public reads never touch session lifecycle
48
+ const { data: products } = await storefront.public().catalog.listProducts();
49
+
50
+ // User-scoped APIs can resolve user_id from the active session automatically
51
+ const { data: wishlist } = await storefront.session().cart.getWishlist();
45
52
  ```
46
53
 
47
54
  ## Configuration Options
48
55
 
49
56
  The SDK supports extensive configuration to fit your needs:
50
57
 
51
- ### Basic Configuration
58
+ ### Recommended Factory Pattern
52
59
 
53
60
  ```typescript
54
- const sdk = new StorefrontSDK({
61
+ const storefront = createStorefront({
55
62
  // Required
56
63
  storeId: "your-store-id",
57
64
 
58
65
  // Environment (optional, defaults to Production)
59
66
  environment: Environment.Staging, // or Environment.Production
60
67
 
61
- // API key for authentication (required for auth endpoints)
68
+ // API key for public and session-backed requests
62
69
  apiKey: "your-api-key",
63
70
  });
64
71
  ```
65
72
 
66
- ### Advanced Configuration
73
+ ### Session Defaults
67
74
 
68
75
  ```typescript
69
- const sdk = new StorefrontSDK({
76
+ const storefront = createStorefront({
70
77
  storeId: "your-store-id",
71
78
  environment: Environment.Production,
72
-
73
- // Token Management
74
- accessToken: "initial-access-token", // Initial access token
75
- refreshToken: "initial-refresh-token", // Initial refresh token (for automatic mode)
79
+ apiKey: "your-api-key",
76
80
 
77
81
  // Custom base URL (optional, overrides environment) - Not needed for most implementations
78
82
  baseUrl: "https://your-custom-api.example.com",
@@ -88,56 +92,111 @@ const sdk = new StorefrontSDK({
88
92
  // Debug and Logging
89
93
  debug: true, // Enable detailed request/response logging - Uses console.log by default
90
94
  logger: console.log, // Custom logger function - structure your logs any way you want. Also helpful to pipe logs into external services
95
+
96
+ session: {
97
+ // Token Management
98
+ accessToken: "initial-access-token", // Initial access token
99
+ refreshToken: "initial-refresh-token", // Initial refresh token (for automatic mode)
100
+ tokenStorage: new BrowserTokenStorage("myapp_"),
101
+ },
102
+ });
103
+ ```
104
+
105
+ ### Direct Session SDK (Advanced)
106
+
107
+ If you only need the session-aware client directly, you can still instantiate it yourself:
108
+
109
+ ```typescript
110
+ import {
111
+ BrowserTokenStorage,
112
+ Environment,
113
+ SessionStorefrontSDK,
114
+ } from "@commercengine/storefront-sdk";
115
+
116
+ const sdk = new SessionStorefrontSDK({
117
+ storeId: "your-store-id",
118
+ environment: Environment.Staging,
119
+ apiKey: "your-api-key",
120
+ tokenStorage: new BrowserTokenStorage("myapp_"),
91
121
  });
92
122
  ```
93
123
 
94
124
  ## Token Management
95
125
 
96
- The SDK offers two approaches to token management:
126
+ The SDK supports three primary access patterns:
97
127
 
98
- ### 1. Manual Token Management (Simple)
128
+ ### 1. Managed Sessions (Recommended)
99
129
 
100
- For basic use cases where you manage tokens yourself:
130
+ Managed mode is enabled when you provide `tokenStorage`.
131
+ The SDK can then:
132
+ - Persist tokens
133
+ - Refresh expired tokens
134
+ - Bootstrap an anonymous session on the first token-required request
135
+ - Resolve `user_id` automatically for user-scoped methods
101
136
 
102
137
  ```typescript
103
- const sdk = new StorefrontSDK({
138
+ import {
139
+ BrowserTokenStorage,
140
+ SessionStorefrontSDK,
141
+ } from "@commercengine/storefront-sdk";
142
+
143
+ const sdk = new SessionStorefrontSDK({
104
144
  storeId: "your-store-id",
105
145
  apiKey: "your-api-key",
146
+ tokenStorage: new BrowserTokenStorage("myapp_"),
106
147
  });
148
+ ```
149
+
150
+ ### 2. Manual Sessions
151
+
152
+ Manual mode is enabled when you set tokens directly (`accessToken` or `sdk.setTokens`) without `tokenStorage`.
153
+ The SDK uses the token you provide but does not auto-refresh or auto-persist sessions.
107
154
 
108
- // Login and set tokens manually
109
- const { data: loginData } = await sdk.auth.loginWithPassword({
155
+ ```typescript
156
+ const storefront = createStorefront({
157
+ storeId: "your-store-id",
158
+ apiKey: "your-api-key",
159
+ });
160
+
161
+ const sdk = storefront.session();
162
+
163
+ const { data } = await sdk.auth.loginWithPassword({
110
164
  email: "user@example.com",
111
165
  password: "password",
112
166
  });
113
167
 
114
- if (loginData) {
115
- await sdk.setTokens(loginData.access_token);
168
+ if (data) {
169
+ await sdk.setTokens(data.access_token, data.refresh_token);
116
170
  }
117
171
  ```
118
172
 
119
- ### 2. Automatic Token Management (Recommended)
173
+ For stateless/token-seeded requests, create a one-off session client:
120
174
 
121
- For production applications with automatic token refresh and persistence:
175
+ ```typescript
176
+ const sdk = storefront.session({
177
+ accessToken: "existing-access-token",
178
+ refreshToken: "existing-refresh-token",
179
+ });
180
+ ```
181
+
182
+ ### 3. Public Client
183
+
184
+ Use `storefront.public()` when a flow should stay API-key-backed and never
185
+ participate in session bootstrap, refresh, or token persistence.
186
+
187
+ ## Session Helpers (`sdk.session`)
188
+
189
+ Use `sdk.session` when you need explicit control over passive vs active session reads.
190
+
191
+ - `peek*` methods are passive reads and never mint/refresh.
192
+ - `ensure*` methods can mint/refresh in managed mode.
122
193
 
123
194
  ```typescript
124
- import StorefrontSDK, { BrowserTokenStorage } from "@commercengine/storefront-sdk";
195
+ // Passive read (no side effects)
196
+ const userId = await sdk.session.peekUserId();
125
197
 
126
- const sdk = new StorefrontSDK({
127
- storeId: "your-store-id",
128
- apiKey: "your-api-key",
129
-
130
- // Enable automatic token management
131
- tokenStorage: new BrowserTokenStorage("myapp_"), // Prefix for localStorage keys
132
-
133
- // Optional callbacks
134
- onTokensUpdated: (accessToken, refreshToken) => {
135
- console.log("Tokens updated!");
136
- },
137
- onTokensCleared: () => {
138
- console.log("User logged out");
139
- },
140
- });
198
+ // Active resolution (may mint or refresh in managed mode)
199
+ const resolvedUserId = await sdk.session.ensureUserId();
141
200
  ```
142
201
 
143
202
  ### Token Storage Options
@@ -187,9 +246,11 @@ class CustomTokenStorage implements TokenStorage {
187
246
 
188
247
  ## Authentication
189
248
 
249
+ If you use managed sessions (`tokenStorage`), you usually do not need to call anonymous auth manually. The SDK can bootstrap anonymous sessions automatically on token-required requests.
250
+
190
251
  ### Anonymous Authentication
191
252
  ```typescript
192
- // Get anonymous token for guest users
253
+ // Optional: manually create an anonymous session
193
254
  const { data } = await sdk.auth.getAnonymousToken();
194
255
  if (data) {
195
256
  await sdk.setTokens(data.access_token, data.refresh_token);
@@ -248,8 +309,8 @@ sdk.cart.* // Cart management, coupons, promotions
248
309
  sdk.order.* // Order creation, tracking, history
249
310
 
250
311
  // Supporting Services
251
- sdk.shipping.* // Shipping methods, rates, tracking
252
312
  sdk.helpers.* // Countries, currencies, utilities
313
+ sdk.store.* // Store config and health endpoints
253
314
  ```
254
315
 
255
316
  ### Example Usage
@@ -286,10 +347,10 @@ const { data: cart } = await sdk.cart.createCart({
286
347
 
287
348
  ## User Information & JWT Utilities
288
349
 
289
- Extract user information from tokens with built-in utilities:
350
+ The top-level getters are passive lookups. They never mint or refresh a session:
290
351
 
291
352
  ```typescript
292
- // Get current user info
353
+ // Passive reads from the current token
293
354
  const userInfo = await sdk.getUserInfo();
294
355
  console.log(userInfo?.userId, userInfo?.email, userInfo?.customerId);
295
356
 
@@ -303,6 +364,21 @@ const customerId = await sdk.getCustomerId();
303
364
  const customerGroupId = await sdk.getCustomerGroupId();
304
365
  ```
305
366
 
367
+ Use `sdk.session.ensure*` for active resolution:
368
+
369
+ ```typescript
370
+ const userId = await sdk.session.ensureUserId();
371
+ const accessToken = await sdk.session.ensureAccessToken();
372
+ ```
373
+
374
+ For user-scoped APIs, `user_id` can be omitted and resolved automatically in managed mode:
375
+
376
+ ```typescript
377
+ await sdk.cart.getWishlist();
378
+ await sdk.customer.listAddresses();
379
+ await sdk.order.listOrders({ page: 1, limit: 20 });
380
+ ```
381
+
306
382
  ## Error Handling
307
383
 
308
384
  All API calls return a consistent `ApiResult<T>` structure with full error information:
@@ -341,7 +417,7 @@ if (result.error) {
341
417
  Enable detailed logging for development:
342
418
 
343
419
  ```typescript
344
- const sdk = new StorefrontSDK({
420
+ const sdk = new SessionStorefrontSDK({
345
421
  storeId: "your-store-id",
346
422
  debug: true,
347
423
  // Optional: Pass a custom logger
@@ -391,8 +467,8 @@ The SDK works seamlessly across all JavaScript environments:
391
467
  - **Background jobs**: Reliable token management for long-running processes
392
468
 
393
469
  ### Hybrid Rendering (SSR/SSG)
394
- - **Next.js**: Use `NextJSTokenStorage` for universal client/server token access
395
- - **Nuxt, SvelteKit**: Use `CookieTokenStorage` for seamless client/server token handoff
470
+ - **Next.js, Nuxt, SvelteKit, Remix**: Use request-aware cookie-backed storage
471
+ - **CookieTokenStorage**: Useful for browser cookie persistence
396
472
  - **Cookie-based storage**: Maintains sessions across server/client boundaries
397
473
  - **Hydration-safe**: No client/server state mismatches
398
474