@commercengine/storefront-sdk 0.3.10 → 0.3.12
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 +354 -53
- package/dist/index.js +1 -1
- package/dist/lib/catalog.d.ts +2 -2
- package/dist/lib/catalog.js +3 -1
- package/dist/lib/client.d.ts +1 -1
- package/dist/lib/client.js +3 -25
- package/dist/lib/header-utils.d.ts +26 -0
- package/dist/lib/header-utils.js +66 -0
- package/dist/types/storefront-api-types.d.ts +1 -0
- package/dist/types/storefront.d.ts +25 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Storefront SDK
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for the CommerceEngine Storefront API.
|
|
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
|
+
|
|
5
|
+
**✨ Key Features:**
|
|
6
|
+
- **100% Type Safe**: Every API endpoint is fully typed with TypeScript
|
|
7
|
+
- **Automatic Token Management**: Built-in refresh token logic for seamless authentication
|
|
8
|
+
- **Universal Compatibility**: Works in browser, Node.js, and hybrid rendering environments
|
|
9
|
+
- **Production Ready**: Implements all API best practices out of the box
|
|
10
|
+
- **Zero Configuration**: Works with sensible defaults, extensive customization available
|
|
4
11
|
|
|
5
12
|
## Installation
|
|
6
13
|
|
|
@@ -8,104 +15,398 @@ TypeScript SDK for the CommerceEngine Storefront API.
|
|
|
8
15
|
npm install @commercengine/storefront-sdk
|
|
9
16
|
```
|
|
10
17
|
|
|
11
|
-
Or with yarn:
|
|
12
|
-
|
|
13
18
|
```bash
|
|
14
19
|
yarn add @commercengine/storefront-sdk
|
|
15
20
|
```
|
|
16
21
|
|
|
17
|
-
Or with pnpm:
|
|
18
|
-
|
|
19
22
|
```bash
|
|
20
23
|
pnpm add @commercengine/storefront-sdk
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
### Initializing the SDK
|
|
26
|
-
|
|
27
|
-
You can initialize the SDK in just a few lines:
|
|
26
|
+
## Quick Start
|
|
28
27
|
|
|
29
28
|
```typescript
|
|
30
29
|
import StorefrontSDK, { Environment } from "@commercengine/storefront-sdk";
|
|
31
30
|
|
|
32
|
-
//
|
|
31
|
+
// Basic initialization
|
|
32
|
+
const sdk = new StorefrontSDK({
|
|
33
|
+
storeId: "your-store-id",
|
|
34
|
+
environment: Environment.Staging,
|
|
35
|
+
apiKey: "your-api-key", // Required for authentication
|
|
36
|
+
});
|
|
37
|
+
|
|
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
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Configuration Options
|
|
48
|
+
|
|
49
|
+
The SDK supports extensive configuration to fit your needs:
|
|
50
|
+
|
|
51
|
+
### Basic Configuration
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
33
54
|
const sdk = new StorefrontSDK({
|
|
55
|
+
// Required
|
|
34
56
|
storeId: "your-store-id",
|
|
57
|
+
|
|
58
|
+
// Environment (optional, defaults to Production)
|
|
35
59
|
environment: Environment.Staging, // or Environment.Production
|
|
60
|
+
|
|
61
|
+
// API key for authentication (required for auth endpoints)
|
|
62
|
+
apiKey: "your-api-key",
|
|
36
63
|
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Advanced Configuration
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
const
|
|
68
|
+
```typescript
|
|
69
|
+
const sdk = new StorefrontSDK({
|
|
40
70
|
storeId: "your-store-id",
|
|
41
|
-
|
|
71
|
+
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)
|
|
76
|
+
|
|
77
|
+
// Custom base URL (optional, overrides environment) - Not needed for most implementations
|
|
78
|
+
baseUrl: "https://your-custom-api.example.com",
|
|
79
|
+
|
|
80
|
+
// Request Configuration
|
|
81
|
+
timeout: 10000, // Request timeout in milliseconds
|
|
82
|
+
|
|
83
|
+
// Default Headers (auto applied to all applicable requests)
|
|
84
|
+
defaultHeaders: {
|
|
85
|
+
customer_group_id: "01JHS28V83KDWTRBXXJQRTEKA0", // For pricing and promotions
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
// Debug and Logging
|
|
89
|
+
debug: true, // Enable detailed request/response logging - Uses console.log by default
|
|
90
|
+
logger: console.log, // Custom logger function - structure your logs any way you want. Also helpful to pipe logs into external services
|
|
42
91
|
});
|
|
43
92
|
```
|
|
44
93
|
|
|
45
|
-
|
|
94
|
+
## Token Management
|
|
95
|
+
|
|
96
|
+
The SDK offers two approaches to token management:
|
|
97
|
+
|
|
98
|
+
### 1. Manual Token Management (Simple)
|
|
46
99
|
|
|
47
|
-
|
|
100
|
+
For basic use cases where you manage tokens yourself:
|
|
48
101
|
|
|
49
102
|
```typescript
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
103
|
+
const sdk = new StorefrontSDK({
|
|
104
|
+
storeId: "your-store-id",
|
|
105
|
+
apiKey: "your-api-key",
|
|
106
|
+
});
|
|
53
107
|
|
|
54
|
-
//
|
|
55
|
-
const {
|
|
108
|
+
// Login and set tokens manually
|
|
109
|
+
const { data: loginData } = await sdk.auth.loginWithPassword({
|
|
110
|
+
email: "user@example.com",
|
|
111
|
+
password: "password",
|
|
112
|
+
});
|
|
56
113
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
114
|
+
if (loginData) {
|
|
115
|
+
await sdk.setTokens(loginData.access_token);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
61
118
|
|
|
62
|
-
|
|
63
|
-
const { user, access_token, refresh_token } = await sdk.auth.verifyOtp(
|
|
64
|
-
"123456",
|
|
65
|
-
otp_token,
|
|
66
|
-
"login"
|
|
67
|
-
);
|
|
119
|
+
### 2. Automatic Token Management (Recommended)
|
|
68
120
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
121
|
+
For production applications with automatic token refresh and persistence:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import StorefrontSDK, { BrowserTokenStorage } from "@commercengine/storefront-sdk";
|
|
125
|
+
|
|
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
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Token Storage Options
|
|
144
|
+
|
|
145
|
+
Choose the storage method that fits your environment:
|
|
146
|
+
|
|
147
|
+
#### Browser localStorage
|
|
148
|
+
```typescript
|
|
149
|
+
import { BrowserTokenStorage } from "@commercengine/storefront-sdk";
|
|
150
|
+
|
|
151
|
+
const tokenStorage = new BrowserTokenStorage("myapp_"); // Optional prefix
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Cookies (for SSR or cross-tab sync)
|
|
155
|
+
```typescript
|
|
156
|
+
import { CookieTokenStorage } from "@commercengine/storefront-sdk";
|
|
157
|
+
|
|
158
|
+
const tokenStorage = new CookieTokenStorage({
|
|
159
|
+
prefix: "myapp_",
|
|
160
|
+
maxAge: 7 * 24 * 60 * 60, // 7 days
|
|
161
|
+
secure: true,
|
|
162
|
+
sameSite: "Lax",
|
|
73
163
|
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Memory (for server-side or temporary storage)
|
|
167
|
+
```typescript
|
|
168
|
+
import { MemoryTokenStorage } from "@commercengine/storefront-sdk";
|
|
169
|
+
|
|
170
|
+
const tokenStorage = new MemoryTokenStorage();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### Custom Storage
|
|
174
|
+
```typescript
|
|
175
|
+
class CustomTokenStorage implements TokenStorage {
|
|
176
|
+
async getAccessToken(): Promise<string | null> {
|
|
177
|
+
// Your implementation
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async setAccessToken(token: string): Promise<void> {
|
|
181
|
+
// Your implementation
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ... implement other required methods
|
|
185
|
+
}
|
|
186
|
+
```
|
|
74
187
|
|
|
75
|
-
|
|
76
|
-
|
|
188
|
+
## Authentication
|
|
189
|
+
|
|
190
|
+
### Anonymous Authentication
|
|
191
|
+
```typescript
|
|
192
|
+
// Get anonymous token for guest users
|
|
193
|
+
const { data } = await sdk.auth.getAnonymousToken();
|
|
194
|
+
if (data) {
|
|
195
|
+
await sdk.setTokens(data.access_token, data.refresh_token);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Phone/Email Authentication
|
|
200
|
+
```typescript
|
|
201
|
+
// Step 1: Initiate login
|
|
202
|
+
const { data: otpData } = await sdk.auth.loginWithPhone({
|
|
77
203
|
phone: "9876543210",
|
|
204
|
+
country_code: "+91",
|
|
205
|
+
register_if_not_exists: true,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Step 2: Verify OTP
|
|
209
|
+
if (otpData) {
|
|
210
|
+
const { data: authData } = await sdk.auth.verifyOtp({
|
|
211
|
+
otp: "123456",
|
|
212
|
+
otp_token: otpData.otp_token,
|
|
213
|
+
otp_action: otpData.otp_action,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
if (authData) {
|
|
217
|
+
await sdk.setTokens(authData.access_token, authData.refresh_token);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Password Authentication
|
|
223
|
+
```typescript
|
|
224
|
+
const { data } = await sdk.auth.loginWithPassword({
|
|
78
225
|
email: "user@example.com",
|
|
79
|
-
|
|
80
|
-
|
|
226
|
+
password: "your-password",
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
if (data) {
|
|
230
|
+
await sdk.setTokens(data.access_token, data.refresh_token);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## API Clients & Complete Type Safety
|
|
235
|
+
|
|
236
|
+
The SDK provides **complete access to every CommerceEngine API endpoint** with full TypeScript support. All clients are automatically generated from the OpenAPI specification, ensuring 100% accuracy and type safety.
|
|
237
|
+
|
|
238
|
+
### Available Clients
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// Authentication & User Management
|
|
242
|
+
sdk.auth.* // Login, registration, OTP, password management
|
|
243
|
+
sdk.customer.* // Customer profiles, addresses, preferences
|
|
244
|
+
|
|
245
|
+
// E-commerce Core
|
|
246
|
+
sdk.catalog.* // Products, categories, search, variants
|
|
247
|
+
sdk.cart.* // Cart management, coupons, promotions
|
|
248
|
+
sdk.order.* // Order creation, tracking, history
|
|
249
|
+
|
|
250
|
+
// Supporting Services
|
|
251
|
+
sdk.shipping.* // Shipping methods, rates, tracking
|
|
252
|
+
sdk.helpers.* // Countries, currencies, utilities
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Example Usage
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// Every method is fully typed - IntelliSense shows all available parameters
|
|
259
|
+
const { data: products } = await sdk.catalog.listProducts({
|
|
260
|
+
query: {
|
|
261
|
+
page: 1,
|
|
262
|
+
limit: 20,
|
|
263
|
+
category_id: "electronics",
|
|
264
|
+
sort: "price_asc",
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Get product details
|
|
269
|
+
const { data: product } = await sdk.catalog.getProduct({
|
|
270
|
+
product_id_or_slug: "product-id"
|
|
81
271
|
});
|
|
82
272
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
273
|
+
// Create a cart with full type checking
|
|
274
|
+
const { data: cart } = await sdk.cart.createCart({
|
|
275
|
+
items: [
|
|
276
|
+
{
|
|
277
|
+
product_id: "product-id",
|
|
278
|
+
quantity: 2,
|
|
279
|
+
variant_id: "variant-id",
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
> **📚 API Reference**: For complete endpoint documentation, parameters, and response schemas, visit [docs.commercengine.io/api-reference](https://docs.commercengine.io/api-reference)
|
|
286
|
+
|
|
287
|
+
## User Information & JWT Utilities
|
|
288
|
+
|
|
289
|
+
Extract user information from tokens with built-in utilities:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// Get current user info
|
|
293
|
+
const userInfo = await sdk.getUserInfo();
|
|
294
|
+
console.log(userInfo?.userId, userInfo?.email, userInfo?.customerId);
|
|
295
|
+
|
|
296
|
+
// Check authentication status
|
|
297
|
+
const isLoggedIn = await sdk.isLoggedIn();
|
|
298
|
+
const isAnonymous = await sdk.isAnonymous();
|
|
299
|
+
|
|
300
|
+
// Get specific user data
|
|
301
|
+
const userId = await sdk.getUserId();
|
|
302
|
+
const customerId = await sdk.getCustomerId();
|
|
303
|
+
const customerGroupId = await sdk.getCustomerGroupId();
|
|
86
304
|
```
|
|
87
305
|
|
|
88
|
-
|
|
306
|
+
## Error Handling
|
|
307
|
+
|
|
308
|
+
All API calls return a consistent `ApiResult<T>` structure with full error information:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
const { data, error, response } = await sdk.catalog.listProducts();
|
|
89
312
|
|
|
90
|
-
|
|
313
|
+
if (error) {
|
|
314
|
+
console.error("API Error:", error.message, error.code);
|
|
315
|
+
console.log("Status:", response.status);
|
|
316
|
+
} else {
|
|
317
|
+
console.log("Success:", data);
|
|
318
|
+
}
|
|
319
|
+
```
|
|
91
320
|
|
|
321
|
+
### Network Error Handling
|
|
92
322
|
```typescript
|
|
93
|
-
|
|
94
|
-
const products = await sdk.catalog.listProducts();
|
|
323
|
+
const result = await sdk.catalog.getProduct({ product_id_or_slug: "invalid-id" });
|
|
95
324
|
|
|
96
|
-
|
|
97
|
-
|
|
325
|
+
if (result.error) {
|
|
326
|
+
switch (result.error.code) {
|
|
327
|
+
case "NETWORK_ERROR":
|
|
328
|
+
console.log("Network connection failed");
|
|
329
|
+
break;
|
|
330
|
+
case "UNAUTHORIZED":
|
|
331
|
+
console.log("Authentication required");
|
|
332
|
+
break;
|
|
333
|
+
default:
|
|
334
|
+
console.log("API Error:", result.error.message);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
98
337
|
```
|
|
99
338
|
|
|
100
|
-
##
|
|
339
|
+
## Debug Mode
|
|
101
340
|
|
|
102
|
-
|
|
341
|
+
Enable detailed logging for development:
|
|
103
342
|
|
|
104
343
|
```typescript
|
|
105
344
|
const sdk = new StorefrontSDK({
|
|
106
345
|
storeId: "your-store-id",
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
346
|
+
debug: true,
|
|
347
|
+
// Optional: Pass a custom logger
|
|
348
|
+
logger: (message, data) => {
|
|
349
|
+
console.log(`[SDK Debug] ${message}`, data);
|
|
350
|
+
},
|
|
110
351
|
});
|
|
111
352
|
```
|
|
353
|
+
|
|
354
|
+
Debug mode logs:
|
|
355
|
+
- Request URLs, methods, headers, and bodies
|
|
356
|
+
- Response status, headers, and bodies
|
|
357
|
+
- Token refresh attempts and results
|
|
358
|
+
- Network errors and retry attempts
|
|
359
|
+
|
|
360
|
+
## TypeScript Support
|
|
361
|
+
|
|
362
|
+
The SDK is built with TypeScript-first design:
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
import type {
|
|
366
|
+
ApiResult,
|
|
367
|
+
UserInfo,
|
|
368
|
+
DebugLoggerFn,
|
|
369
|
+
SupportedDefaultHeaders
|
|
370
|
+
} from "@commercengine/storefront-sdk";
|
|
371
|
+
|
|
372
|
+
// All API responses are properly typed
|
|
373
|
+
const { data }: ApiResult<ProductListResponse> = await sdk.catalog.listProducts();
|
|
374
|
+
|
|
375
|
+
// IntelliSense works for all nested properties
|
|
376
|
+
console.log(data?.products[0].name);
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Universal Compatibility
|
|
380
|
+
|
|
381
|
+
The SDK works seamlessly across all JavaScript environments:
|
|
382
|
+
|
|
383
|
+
### Client-Side Applications
|
|
384
|
+
- **React, Vue, Angular**: Use `BrowserTokenStorage` for persistent sessions
|
|
385
|
+
- **Automatic token refresh**: Handles token expiry transparently
|
|
386
|
+
- **Cross-tab synchronization**: With `CookieTokenStorage`
|
|
387
|
+
|
|
388
|
+
### Server-Side Applications
|
|
389
|
+
- **Node.js, Bun, Deno**: Use `MemoryTokenStorage` or custom storage
|
|
390
|
+
- **API routes**: Perfect for Next.js API routes, Express middleware
|
|
391
|
+
- **Background jobs**: Reliable token management for long-running processes
|
|
392
|
+
|
|
393
|
+
### Hybrid Rendering (SSR/SSG)
|
|
394
|
+
- **Next.js, Nuxt, SvelteKit**: Seamless client/server token handoff
|
|
395
|
+
- **Cookie-based storage**: Maintains sessions across server/client boundaries
|
|
396
|
+
- **Hydration-safe**: No client/server state mismatches
|
|
397
|
+
|
|
398
|
+
## Best Practices Built-In
|
|
399
|
+
|
|
400
|
+
The SDK implements CommerceEngine API best practices automatically:
|
|
401
|
+
|
|
402
|
+
- ✅ **Automatic token refresh** before expiry
|
|
403
|
+
- ✅ **Proper error handling** for all edge cases
|
|
404
|
+
- ✅ **Request retries** for transient failures
|
|
405
|
+
- ✅ **Rate limiting compliance** with proper backoff
|
|
406
|
+
- ✅ **Security headers** and CSRF protection
|
|
407
|
+
- ✅ **Timeout handling** with configurable limits
|
|
408
|
+
- ✅ **Memory leak prevention** with proper cleanup
|
|
409
|
+
|
|
410
|
+
## License
|
|
411
|
+
|
|
412
|
+
This project is licensed under the MIT License.
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { HelpersClient } from "./lib/helper";
|
|
|
8
8
|
import { CustomerClient } from "./lib/customer";
|
|
9
9
|
import { MemoryTokenStorage, BrowserTokenStorage, CookieTokenStorage, } from "./lib/middleware";
|
|
10
10
|
import { extractUserInfoFromToken, getUserIdFromToken, isUserLoggedIn, isUserAnonymous, } from "./lib/jwt-utils";
|
|
11
|
-
import { ResponseUtils
|
|
11
|
+
import { ResponseUtils } from "./lib/logger-utils";
|
|
12
12
|
/**
|
|
13
13
|
* Main SDK class for the Storefront API
|
|
14
14
|
*/
|
package/dist/lib/catalog.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StorefrontAPIClient } from "./client";
|
|
2
|
-
import type { ApiResult, GetProductDetailContent, GetProductDetailPathParams, GetProductDetailHeaderParams, GetVariantDetailContent, GetVariantDetailPathParams, GetVariantDetailHeaderParams, ListProductsContent, ListProductsQuery, ListProductsHeaderParams, ListProductVariantsContent, ListProductVariantsPathParams, ListProductVariantsHeaderParams, ListCategoriesQuery, ListCategoriesContent, ListProductReviewsQuery, ListProductReviewsPathParams, ListProductReviewsContent, CreateProductReviewPathParams, CreateProductReviewFormData, CreateProductReviewResponse, SearchProductsBody, SearchProductsContent, ListSkusQuery, ListSkusContent, ListSkusHeaderParams, ListCrosssellProductsContent, ListCrosssellProductsQuery, ListCrosssellProductsHeaderParams, ListUpsellProductsQuery, ListUpsellProductsContent, ListUpsellProductsHeaderParams, ListSimilarProductsQuery, ListSimilarProductsContent, ListSimilarProductsHeaderParams } from "../types/storefront-api-types";
|
|
2
|
+
import type { ApiResult, GetProductDetailContent, GetProductDetailPathParams, GetProductDetailHeaderParams, GetVariantDetailContent, GetVariantDetailPathParams, GetVariantDetailHeaderParams, ListProductsContent, ListProductsQuery, ListProductsHeaderParams, ListProductVariantsContent, ListProductVariantsPathParams, ListProductVariantsHeaderParams, ListCategoriesQuery, ListCategoriesContent, ListProductReviewsQuery, ListProductReviewsPathParams, ListProductReviewsContent, CreateProductReviewPathParams, CreateProductReviewFormData, CreateProductReviewResponse, SearchProductsBody, SearchProductsContent, ListSkusQuery, ListSkusContent, ListSkusHeaderParams, ListCrosssellProductsContent, ListCrosssellProductsQuery, ListCrosssellProductsHeaderParams, ListUpsellProductsQuery, ListUpsellProductsContent, ListUpsellProductsHeaderParams, ListSimilarProductsQuery, ListSimilarProductsContent, ListSimilarProductsHeaderParams, SearchProductsHeaderParams } from "../types/storefront-api-types";
|
|
3
3
|
/**
|
|
4
4
|
* Client for interacting with catalog endpoints
|
|
5
5
|
*/
|
|
@@ -73,7 +73,7 @@ export declare class CatalogClient extends StorefrontAPIClient {
|
|
|
73
73
|
* @param searchData - The search parameters
|
|
74
74
|
* @returns Promise with search results, facet distribution, facet stats, and pagination
|
|
75
75
|
*/
|
|
76
|
-
searchProducts(searchData: SearchProductsBody): Promise<ApiResult<SearchProductsContent>>;
|
|
76
|
+
searchProducts(searchData: SearchProductsBody, headers?: SearchProductsHeaderParams): Promise<ApiResult<SearchProductsContent>>;
|
|
77
77
|
/**
|
|
78
78
|
* List cross-sell products
|
|
79
79
|
*
|
package/dist/lib/catalog.js
CHANGED
|
@@ -146,9 +146,11 @@ export class CatalogClient extends StorefrontAPIClient {
|
|
|
146
146
|
* @param searchData - The search parameters
|
|
147
147
|
* @returns Promise with search results, facet distribution, facet stats, and pagination
|
|
148
148
|
*/
|
|
149
|
-
async searchProducts(searchData) {
|
|
149
|
+
async searchProducts(searchData, headers) {
|
|
150
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
150
151
|
return this.executeRequest(() => this.client.POST("/catalog/products/search", {
|
|
151
152
|
body: searchData,
|
|
153
|
+
header: mergedHeaders,
|
|
152
154
|
}));
|
|
153
155
|
}
|
|
154
156
|
/**
|
package/dist/lib/client.d.ts
CHANGED
|
@@ -107,7 +107,7 @@ export declare class StorefrontAPIClient {
|
|
|
107
107
|
* Method-level headers take precedence over default headers
|
|
108
108
|
*
|
|
109
109
|
* @param methodHeaders - Headers passed to the specific method call
|
|
110
|
-
* @returns Merged headers object
|
|
110
|
+
* @returns Merged headers object with proper HTTP header names
|
|
111
111
|
*/
|
|
112
112
|
protected mergeHeaders<T extends Record<string, any> = Record<string, any>>(methodHeaders?: T): T;
|
|
113
113
|
}
|
package/dist/lib/client.js
CHANGED
|
@@ -2,6 +2,7 @@ import createClient from "openapi-fetch";
|
|
|
2
2
|
import { createDefaultAuthMiddleware } from "./middleware";
|
|
3
3
|
import { getPathnameFromUrl, isAnonymousAuthEndpoint } from "./auth-utils";
|
|
4
4
|
import { createDebugMiddleware } from "./logger-utils";
|
|
5
|
+
import { mergeHeaders } from "./header-utils";
|
|
5
6
|
/**
|
|
6
7
|
* Available API environments
|
|
7
8
|
*/
|
|
@@ -288,32 +289,9 @@ export class StorefrontAPIClient {
|
|
|
288
289
|
* Method-level headers take precedence over default headers
|
|
289
290
|
*
|
|
290
291
|
* @param methodHeaders - Headers passed to the specific method call
|
|
291
|
-
* @returns Merged headers object
|
|
292
|
+
* @returns Merged headers object with proper HTTP header names
|
|
292
293
|
*/
|
|
293
294
|
mergeHeaders(methodHeaders) {
|
|
294
|
-
|
|
295
|
-
return {};
|
|
296
|
-
}
|
|
297
|
-
// Start with default headers, but only include supported ones
|
|
298
|
-
const merged = {};
|
|
299
|
-
// Add default headers if they exist
|
|
300
|
-
if (this.config.defaultHeaders) {
|
|
301
|
-
if (this.config.defaultHeaders.customer_group_id !== undefined) {
|
|
302
|
-
merged.customer_group_id =
|
|
303
|
-
this.config.defaultHeaders.customer_group_id;
|
|
304
|
-
}
|
|
305
|
-
// Future: Add other supported headers here as they become available
|
|
306
|
-
}
|
|
307
|
-
if (methodHeaders) {
|
|
308
|
-
// Method headers override default headers
|
|
309
|
-
Object.assign(merged, methodHeaders);
|
|
310
|
-
}
|
|
311
|
-
// Remove undefined values
|
|
312
|
-
Object.keys(merged).forEach((key) => {
|
|
313
|
-
if (merged[key] === undefined) {
|
|
314
|
-
delete merged[key];
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
return merged;
|
|
295
|
+
return mergeHeaders(this.config.defaultHeaders, methodHeaders);
|
|
318
296
|
}
|
|
319
297
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SupportedDefaultHeaders } from "../index";
|
|
2
|
+
/**
|
|
3
|
+
* Transform SDK header parameters to actual HTTP header names
|
|
4
|
+
* Headers not in the transformation map are passed through unchanged
|
|
5
|
+
*
|
|
6
|
+
* @param headers - Headers object with SDK parameter names
|
|
7
|
+
* @returns Headers object with actual HTTP header names
|
|
8
|
+
*/
|
|
9
|
+
export declare function transformHeaders(headers: SupportedDefaultHeaders): Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Merge default headers with method-level headers
|
|
12
|
+
* Method-level headers take precedence over default headers
|
|
13
|
+
* Automatically transforms SDK parameter names to HTTP header names
|
|
14
|
+
*
|
|
15
|
+
* @param defaultHeaders - Default headers from SDK configuration
|
|
16
|
+
* @param methodHeaders - Headers passed to the specific method call
|
|
17
|
+
* @returns Merged headers object with proper HTTP header names
|
|
18
|
+
*/
|
|
19
|
+
export declare function mergeHeaders<T extends Record<string, any> = Record<string, any>>(defaultHeaders?: SupportedDefaultHeaders, methodHeaders?: T): T;
|
|
20
|
+
/**
|
|
21
|
+
* Get the list of supported header transformations
|
|
22
|
+
* Useful for debugging or documentation purposes
|
|
23
|
+
*
|
|
24
|
+
* @returns Copy of the header transformations mapping
|
|
25
|
+
*/
|
|
26
|
+
export declare function getHeaderTransformations(): Record<string, string>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapping of SDK header parameter names to actual HTTP header names
|
|
3
|
+
* Only include headers that need transformation - others pass through as-is
|
|
4
|
+
*/
|
|
5
|
+
const HEADER_TRANSFORMATIONS = {
|
|
6
|
+
customer_group_id: "x-customer-group-id",
|
|
7
|
+
// Future transformations can be added here:
|
|
8
|
+
// some_param: "X-Some-Header",
|
|
9
|
+
// another_param: "X-Another-Header",
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Transform SDK header parameters to actual HTTP header names
|
|
13
|
+
* Headers not in the transformation map are passed through unchanged
|
|
14
|
+
*
|
|
15
|
+
* @param headers - Headers object with SDK parameter names
|
|
16
|
+
* @returns Headers object with actual HTTP header names
|
|
17
|
+
*/
|
|
18
|
+
export function transformHeaders(headers) {
|
|
19
|
+
const transformed = {};
|
|
20
|
+
// Iterate through all headers in the input
|
|
21
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
22
|
+
if (value !== undefined) {
|
|
23
|
+
// Use transformation if available, otherwise use the original key
|
|
24
|
+
const headerName = HEADER_TRANSFORMATIONS[key] || key;
|
|
25
|
+
transformed[headerName] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return transformed;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Merge default headers with method-level headers
|
|
32
|
+
* Method-level headers take precedence over default headers
|
|
33
|
+
* Automatically transforms SDK parameter names to HTTP header names
|
|
34
|
+
*
|
|
35
|
+
* @param defaultHeaders - Default headers from SDK configuration
|
|
36
|
+
* @param methodHeaders - Headers passed to the specific method call
|
|
37
|
+
* @returns Merged headers object with proper HTTP header names
|
|
38
|
+
*/
|
|
39
|
+
export function mergeHeaders(defaultHeaders, methodHeaders) {
|
|
40
|
+
const merged = {};
|
|
41
|
+
// Transform and add default headers if they exist
|
|
42
|
+
if (defaultHeaders) {
|
|
43
|
+
const transformedDefaults = transformHeaders(defaultHeaders);
|
|
44
|
+
Object.assign(merged, transformedDefaults);
|
|
45
|
+
}
|
|
46
|
+
// Method headers override default headers
|
|
47
|
+
if (methodHeaders) {
|
|
48
|
+
Object.assign(merged, methodHeaders);
|
|
49
|
+
}
|
|
50
|
+
// Remove undefined values
|
|
51
|
+
Object.keys(merged).forEach((key) => {
|
|
52
|
+
if (merged[key] === undefined) {
|
|
53
|
+
delete merged[key];
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return merged;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the list of supported header transformations
|
|
60
|
+
* Useful for debugging or documentation purposes
|
|
61
|
+
*
|
|
62
|
+
* @returns Copy of the header transformations mapping
|
|
63
|
+
*/
|
|
64
|
+
export function getHeaderTransformations() {
|
|
65
|
+
return { ...HEADER_TRANSFORMATIONS };
|
|
66
|
+
}
|
|
@@ -58,6 +58,7 @@ export type ListCrosssellProductsQuery = paths['/catalog/products/cross-sell']['
|
|
|
58
58
|
export type ListCrosssellProductsHeaderParams = paths['/catalog/products/cross-sell']['get']['parameters']['header'];
|
|
59
59
|
export type SearchProductsResponse = paths['/catalog/products/search']['post']['responses'][200]['content']['application/json'];
|
|
60
60
|
export type SearchProductsContent = SearchProductsResponse['content'];
|
|
61
|
+
export type SearchProductsHeaderParams = paths['/catalog/products/search']['post']['parameters']['header'];
|
|
61
62
|
export type SearchProductsBody = NonNullable<paths['/catalog/products/search']['post']['requestBody']>['content']['application/json'];
|
|
62
63
|
export type CreateCartResponse = paths['/carts']['post']['responses'][200]['content']['application/json'];
|
|
63
64
|
export type CreateCartContent = CreateCartResponse['content'];
|
|
@@ -2426,8 +2426,6 @@ export interface components {
|
|
|
2426
2426
|
* @default 25
|
|
2427
2427
|
*/
|
|
2428
2428
|
limit: number;
|
|
2429
|
-
/** @description to return pricing, promotion and subscriptions data for a specific customer group. Otherwise it will return data as per default customer group. */
|
|
2430
|
-
customer_group_id?: string;
|
|
2431
2429
|
/** @description provide list of attributes for specific facets or * for all facets.
|
|
2432
2430
|
* ```json
|
|
2433
2431
|
* For specific facets: ["size", "color", "brand"]
|
|
@@ -4540,7 +4538,7 @@ export interface components {
|
|
|
4540
4538
|
sortingParam: string;
|
|
4541
4539
|
/** @description search keyword */
|
|
4542
4540
|
searchKeyword: string;
|
|
4543
|
-
/** @description
|
|
4541
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4544
4542
|
CustomerGroupId: string;
|
|
4545
4543
|
};
|
|
4546
4544
|
requestBodies: never;
|
|
@@ -4564,8 +4562,8 @@ export interface operations {
|
|
|
4564
4562
|
category_slug?: string[];
|
|
4565
4563
|
};
|
|
4566
4564
|
header?: {
|
|
4567
|
-
/** @description
|
|
4568
|
-
|
|
4565
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4566
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4569
4567
|
};
|
|
4570
4568
|
path?: never;
|
|
4571
4569
|
cookie?: never;
|
|
@@ -4607,8 +4605,8 @@ export interface operations {
|
|
|
4607
4605
|
sku?: string[];
|
|
4608
4606
|
};
|
|
4609
4607
|
header?: {
|
|
4610
|
-
/** @description
|
|
4611
|
-
|
|
4608
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4609
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4612
4610
|
};
|
|
4613
4611
|
path?: never;
|
|
4614
4612
|
cookie?: never;
|
|
@@ -4639,8 +4637,8 @@ export interface operations {
|
|
|
4639
4637
|
parameters: {
|
|
4640
4638
|
query?: never;
|
|
4641
4639
|
header?: {
|
|
4642
|
-
/** @description
|
|
4643
|
-
|
|
4640
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4641
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4644
4642
|
};
|
|
4645
4643
|
path: {
|
|
4646
4644
|
/** @description The unique identifier of the product. Can be either the product ID or the slug. */
|
|
@@ -4673,8 +4671,8 @@ export interface operations {
|
|
|
4673
4671
|
parameters: {
|
|
4674
4672
|
query?: never;
|
|
4675
4673
|
header?: {
|
|
4676
|
-
/** @description
|
|
4677
|
-
|
|
4674
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4675
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4678
4676
|
};
|
|
4679
4677
|
path: {
|
|
4680
4678
|
/** @description ID of a particular product */
|
|
@@ -4707,8 +4705,8 @@ export interface operations {
|
|
|
4707
4705
|
parameters: {
|
|
4708
4706
|
query?: never;
|
|
4709
4707
|
header?: {
|
|
4710
|
-
/** @description
|
|
4711
|
-
|
|
4708
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4709
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4712
4710
|
};
|
|
4713
4711
|
path: {
|
|
4714
4712
|
/** @description product id */
|
|
@@ -4870,8 +4868,8 @@ export interface operations {
|
|
|
4870
4868
|
sort_by?: string;
|
|
4871
4869
|
};
|
|
4872
4870
|
header?: {
|
|
4873
|
-
/** @description
|
|
4874
|
-
|
|
4871
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4872
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4875
4873
|
};
|
|
4876
4874
|
path?: never;
|
|
4877
4875
|
cookie?: never;
|
|
@@ -4911,8 +4909,8 @@ export interface operations {
|
|
|
4911
4909
|
sort_by?: string;
|
|
4912
4910
|
};
|
|
4913
4911
|
header?: {
|
|
4914
|
-
/** @description
|
|
4915
|
-
|
|
4912
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4913
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4916
4914
|
};
|
|
4917
4915
|
path?: never;
|
|
4918
4916
|
cookie?: never;
|
|
@@ -4953,8 +4951,8 @@ export interface operations {
|
|
|
4953
4951
|
sort_by?: string;
|
|
4954
4952
|
};
|
|
4955
4953
|
header?: {
|
|
4956
|
-
/** @description
|
|
4957
|
-
|
|
4954
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4955
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4958
4956
|
};
|
|
4959
4957
|
path?: never;
|
|
4960
4958
|
cookie?: never;
|
|
@@ -4984,7 +4982,10 @@ export interface operations {
|
|
|
4984
4982
|
"search-products": {
|
|
4985
4983
|
parameters: {
|
|
4986
4984
|
query?: never;
|
|
4987
|
-
header?:
|
|
4985
|
+
header?: {
|
|
4986
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
4987
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
4988
|
+
};
|
|
4988
4989
|
path?: never;
|
|
4989
4990
|
cookie?: never;
|
|
4990
4991
|
};
|
|
@@ -5608,8 +5609,8 @@ export interface operations {
|
|
|
5608
5609
|
parameters: {
|
|
5609
5610
|
query?: never;
|
|
5610
5611
|
header?: {
|
|
5611
|
-
/** @description
|
|
5612
|
-
|
|
5612
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
5613
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
5613
5614
|
};
|
|
5614
5615
|
path?: never;
|
|
5615
5616
|
cookie?: never;
|
|
@@ -5640,8 +5641,8 @@ export interface operations {
|
|
|
5640
5641
|
parameters: {
|
|
5641
5642
|
query?: never;
|
|
5642
5643
|
header?: {
|
|
5643
|
-
/** @description
|
|
5644
|
-
|
|
5644
|
+
/** @description This param is used to determine product pricing, promotions, and subscription rates. If a valid customer group id is provided, pricing details will be retrieved accordingly. If no matching data is found for the specified customer group id, the system will fall back to the default customer group id. If no data is found for the default group either, the highest applicable price will be returned. */
|
|
5645
|
+
"x-customer-group-id"?: components["parameters"]["CustomerGroupId"];
|
|
5645
5646
|
};
|
|
5646
5647
|
path?: never;
|
|
5647
5648
|
cookie?: never;
|