@commercengine/storefront-sdk 0.1.3 → 0.2.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/dist/index.d.ts CHANGED
@@ -53,12 +53,32 @@ export declare class StorefrontSDK {
53
53
  * Client for authentication-related endpoints
54
54
  */
55
55
  readonly auth: AuthClient;
56
+ /**
57
+ * The client storage instance used by this SDK
58
+ */
59
+ private readonly clientStorage;
56
60
  /**
57
61
  * Create a new StorefrontSDK instance
58
62
  *
59
63
  * @param options - Configuration options for the SDK
60
64
  */
61
65
  constructor(options: StorefrontSDKOptions);
66
+ /**
67
+ * Get the current cart ID if one is stored
68
+ *
69
+ * @returns The current cart ID or null if none exists
70
+ */
71
+ getCartId(): string | null;
72
+ /**
73
+ * Set a specific cart ID to use
74
+ *
75
+ * @param cartId - The cart ID to use
76
+ */
77
+ setCartId(cartId: string): void;
78
+ /**
79
+ * Clear the current cart ID
80
+ */
81
+ clearCartId(): void;
62
82
  /**
63
83
  * Set the authentication token for all clients
64
84
  *
package/dist/index.js CHANGED
@@ -20,6 +20,8 @@ class StorefrontSDK {
20
20
  * @param options - Configuration options for the SDK
21
21
  */
22
22
  constructor(options) {
23
+ // Set up client storage
24
+ this.clientStorage = options.tokenStorage || new auth_1.MemoryTokenStorage();
23
25
  // Convert options to internal config format
24
26
  const config = {
25
27
  storeId: options.storeId,
@@ -31,7 +33,31 @@ class StorefrontSDK {
31
33
  };
32
34
  this.catalog = new catalog_1.CatalogClient(config);
33
35
  this.cart = new cart_1.CartClient(config);
34
- this.auth = new auth_1.AuthClient(config, options.tokenStorage);
36
+ this.auth = new auth_1.AuthClient(config, this.clientStorage);
37
+ // Set client storage for cart management
38
+ this.cart.setClientStorage(this.clientStorage);
39
+ }
40
+ /**
41
+ * Get the current cart ID if one is stored
42
+ *
43
+ * @returns The current cart ID or null if none exists
44
+ */
45
+ getCartId() {
46
+ return this.cart.getCartId();
47
+ }
48
+ /**
49
+ * Set a specific cart ID to use
50
+ *
51
+ * @param cartId - The cart ID to use
52
+ */
53
+ setCartId(cartId) {
54
+ this.cart.setCartId(cartId);
55
+ }
56
+ /**
57
+ * Clear the current cart ID
58
+ */
59
+ clearCartId() {
60
+ this.cart.clearCartId();
35
61
  }
36
62
  /**
37
63
  * Set the authentication token for all clients
@@ -148,46 +148,59 @@ export declare class AuthClient extends StorefrontAPIClient {
148
148
  executeWithTokenRefresh<T>(requestFn: () => Promise<T>): Promise<T>;
149
149
  }
150
150
  /**
151
- * Interface for token storage implementations
151
+ * Interface for client storage implementations (tokens and cart ID)
152
152
  */
153
- export interface TokenStorage {
153
+ export interface ClientStorage {
154
154
  getAccessToken(): string | null;
155
155
  setAccessToken(token: string): void;
156
156
  getRefreshToken(): string | null;
157
157
  setRefreshToken(token: string): void;
158
158
  clearTokens(): void;
159
+ getCartId(): string | null;
160
+ setCartId(cartId: string): void;
161
+ clearCartId(): void;
159
162
  }
163
+ export type TokenStorage = ClientStorage;
160
164
  /**
161
- * Default in-memory implementation of token storage
165
+ * Default in-memory implementation of client storage
162
166
  */
163
- export declare class MemoryTokenStorage implements TokenStorage {
167
+ export declare class MemoryTokenStorage implements ClientStorage {
164
168
  private accessToken;
165
169
  private refreshToken;
170
+ private cartId;
166
171
  getAccessToken(): string | null;
167
172
  setAccessToken(token: string): void;
168
173
  getRefreshToken(): string | null;
169
174
  setRefreshToken(token: string): void;
170
175
  clearTokens(): void;
176
+ getCartId(): string | null;
177
+ setCartId(cartId: string): void;
178
+ clearCartId(): void;
171
179
  }
172
180
  /**
173
181
  * Browser storage implementation using localStorage
174
182
  */
175
- export declare class BrowserTokenStorage implements TokenStorage {
183
+ export declare class BrowserTokenStorage implements ClientStorage {
176
184
  private accessTokenKey;
177
185
  private refreshTokenKey;
186
+ private cartIdKey;
178
187
  constructor(prefix?: string);
179
188
  getAccessToken(): string | null;
180
189
  setAccessToken(token: string): void;
181
190
  getRefreshToken(): string | null;
182
191
  setRefreshToken(token: string): void;
183
192
  clearTokens(): void;
193
+ getCartId(): string | null;
194
+ setCartId(cartId: string): void;
195
+ clearCartId(): void;
184
196
  }
185
197
  /**
186
198
  * Cookie-based token storage for browser or server environments
187
199
  */
188
- export declare class CookieTokenStorage implements TokenStorage {
200
+ export declare class CookieTokenStorage implements ClientStorage {
189
201
  private accessTokenKey;
190
202
  private refreshTokenKey;
203
+ private cartIdKey;
191
204
  private cookieOptions;
192
205
  constructor(prefix?: string, cookieOptions?: {
193
206
  path: string;
@@ -220,14 +233,29 @@ export declare class CookieTokenStorage implements TokenStorage {
220
233
  * Clear all tokens from cookies
221
234
  */
222
235
  clearTokens(): void;
236
+ /**
237
+ * Get cart ID from cookies
238
+ * Works in both browser and Next.js server components
239
+ */
240
+ getCartId(): string | null;
241
+ /**
242
+ * Set cart ID in cookies
243
+ * Works in browser environment
244
+ */
245
+ setCartId(cartId: string): void;
246
+ /**
247
+ * Clear cart ID from cookies
248
+ */
249
+ clearCartId(): void;
223
250
  }
224
251
  /**
225
252
  * Next.js specific cookie storage implementation
226
253
  * Works with the Next.js cookies API
227
254
  */
228
- export declare class NextCookieTokenStorage implements TokenStorage {
255
+ export declare class NextCookieTokenStorage implements ClientStorage {
229
256
  private accessTokenKey;
230
257
  private refreshTokenKey;
258
+ private cartIdKey;
231
259
  private cookieStore;
232
260
  constructor(cookieStore: any, prefix?: string);
233
261
  /**
@@ -250,6 +278,18 @@ export declare class NextCookieTokenStorage implements TokenStorage {
250
278
  * Clear all tokens from Next.js cookies
251
279
  */
252
280
  clearTokens(): void;
281
+ /**
282
+ * Get cart ID from Next.js cookies
283
+ */
284
+ getCartId(): string | null;
285
+ /**
286
+ * Set cart ID in Next.js cookies
287
+ */
288
+ setCartId(cartId: string): void;
289
+ /**
290
+ * Clear cart ID from Next.js cookies
291
+ */
292
+ clearCartId(): void;
253
293
  }
254
294
  /**
255
295
  * Helper to create a token storage instance based on environment
package/dist/lib/auth.js CHANGED
@@ -385,12 +385,13 @@ class AuthClient extends client_1.StorefrontAPIClient {
385
385
  }
386
386
  exports.AuthClient = AuthClient;
387
387
  /**
388
- * Default in-memory implementation of token storage
388
+ * Default in-memory implementation of client storage
389
389
  */
390
390
  class MemoryTokenStorage {
391
391
  constructor() {
392
392
  this.accessToken = null;
393
393
  this.refreshToken = null;
394
+ this.cartId = null;
394
395
  }
395
396
  getAccessToken() {
396
397
  return this.accessToken;
@@ -408,6 +409,15 @@ class MemoryTokenStorage {
408
409
  this.accessToken = null;
409
410
  this.refreshToken = null;
410
411
  }
412
+ getCartId() {
413
+ return this.cartId;
414
+ }
415
+ setCartId(cartId) {
416
+ this.cartId = cartId;
417
+ }
418
+ clearCartId() {
419
+ this.cartId = null;
420
+ }
411
421
  }
412
422
  exports.MemoryTokenStorage = MemoryTokenStorage;
413
423
  /**
@@ -417,6 +427,7 @@ class BrowserTokenStorage {
417
427
  constructor(prefix = "storefront_") {
418
428
  this.accessTokenKey = `${prefix}access_token`;
419
429
  this.refreshTokenKey = `${prefix}refresh_token`;
430
+ this.cartIdKey = `${prefix}cart_id`;
420
431
  }
421
432
  getAccessToken() {
422
433
  if (typeof localStorage === "undefined")
@@ -444,6 +455,21 @@ class BrowserTokenStorage {
444
455
  localStorage.removeItem(this.accessTokenKey);
445
456
  localStorage.removeItem(this.refreshTokenKey);
446
457
  }
458
+ getCartId() {
459
+ if (typeof localStorage === "undefined")
460
+ return null;
461
+ return localStorage.getItem(this.cartIdKey);
462
+ }
463
+ setCartId(cartId) {
464
+ if (typeof localStorage === "undefined")
465
+ return;
466
+ localStorage.setItem(this.cartIdKey, cartId);
467
+ }
468
+ clearCartId() {
469
+ if (typeof localStorage === "undefined")
470
+ return;
471
+ localStorage.removeItem(this.cartIdKey);
472
+ }
447
473
  }
448
474
  exports.BrowserTokenStorage = BrowserTokenStorage;
449
475
  /**
@@ -459,6 +485,7 @@ class CookieTokenStorage {
459
485
  }) {
460
486
  this.accessTokenKey = `${prefix}access_token`;
461
487
  this.refreshTokenKey = `${prefix}refresh_token`;
488
+ this.cartIdKey = `${prefix}cart_id`;
462
489
  this.cookieOptions = cookieOptions;
463
490
  }
464
491
  /**
@@ -520,6 +547,39 @@ class CookieTokenStorage {
520
547
  }
521
548
  // Next.js - would need to be implemented by user
522
549
  }
550
+ /**
551
+ * Get cart ID from cookies
552
+ * Works in both browser and Next.js server components
553
+ */
554
+ getCartId() {
555
+ // Browser environment
556
+ if (typeof document !== "undefined") {
557
+ return getCookieValue(this.cartIdKey);
558
+ }
559
+ // Next.js server component - would need to be implemented by user
560
+ return null;
561
+ }
562
+ /**
563
+ * Set cart ID in cookies
564
+ * Works in browser environment
565
+ */
566
+ setCartId(cartId) {
567
+ // Browser environment
568
+ if (typeof document !== "undefined") {
569
+ setCookie(this.cartIdKey, cartId, this.cookieOptions);
570
+ }
571
+ // Next.js - would need to be implemented by user
572
+ }
573
+ /**
574
+ * Clear cart ID from cookies
575
+ */
576
+ clearCartId() {
577
+ // Browser environment
578
+ if (typeof document !== "undefined") {
579
+ deleteCookie(this.cartIdKey);
580
+ }
581
+ // Next.js - would need to be implemented by user
582
+ }
523
583
  }
524
584
  exports.CookieTokenStorage = CookieTokenStorage;
525
585
  /**
@@ -575,6 +635,7 @@ class NextCookieTokenStorage {
575
635
  constructor(cookieStore, prefix = "storefront_") {
576
636
  this.accessTokenKey = `${prefix}access_token`;
577
637
  this.refreshTokenKey = `${prefix}refresh_token`;
638
+ this.cartIdKey = `${prefix}cart_id`;
578
639
  this.cookieStore = cookieStore;
579
640
  }
580
641
  /**
@@ -652,6 +713,49 @@ class NextCookieTokenStorage {
652
713
  // Silently fail
653
714
  }
654
715
  }
716
+ /**
717
+ * Get cart ID from Next.js cookies
718
+ */
719
+ getCartId() {
720
+ try {
721
+ // Assuming cookieStore.get method exists
722
+ const cookie = this.cookieStore.get(this.cartIdKey);
723
+ return cookie ? cookie.value : null;
724
+ }
725
+ catch (error) {
726
+ return null;
727
+ }
728
+ }
729
+ /**
730
+ * Set cart ID in Next.js cookies
731
+ */
732
+ setCartId(cartId) {
733
+ try {
734
+ // Assuming cookieStore.set method exists
735
+ this.cookieStore.set(this.cartIdKey, cartId, {
736
+ path: "/",
737
+ secure: process.env.NODE_ENV === "production",
738
+ httpOnly: true,
739
+ sameSite: "strict",
740
+ maxAge: 60 * 60 * 24 * 30, // 30 days
741
+ });
742
+ }
743
+ catch (error) {
744
+ // Silently fail
745
+ }
746
+ }
747
+ /**
748
+ * Clear cart ID from Next.js cookies
749
+ */
750
+ clearCartId() {
751
+ try {
752
+ // Assuming cookieStore.delete method exists
753
+ this.cookieStore.delete(this.cartIdKey);
754
+ }
755
+ catch (error) {
756
+ // Silently fail
757
+ }
758
+ }
655
759
  }
656
760
  exports.NextCookieTokenStorage = NextCookieTokenStorage;
657
761
  /**
@@ -1,9 +1,33 @@
1
1
  import { StorefrontAPIClient } from "./client";
2
2
  import type { components } from "../types/storefront";
3
+ import { ClientStorage } from "./auth";
3
4
  /**
4
5
  * Client for interacting with cart endpoints
5
6
  */
6
7
  export declare class CartClient extends StorefrontAPIClient {
8
+ private clientStorage;
9
+ /**
10
+ * Set the client storage implementation to use for cart ID management
11
+ *
12
+ * @param storage - The client storage instance
13
+ */
14
+ setClientStorage(storage: ClientStorage): void;
15
+ /**
16
+ * Get the stored cart ID
17
+ *
18
+ * @returns The cart ID or null if not found
19
+ */
20
+ getCartId(): string | null;
21
+ /**
22
+ * Set the cart ID in storage
23
+ *
24
+ * @param cartId - The cart ID to store
25
+ */
26
+ setCartId(cartId: string): void;
27
+ /**
28
+ * Clear the stored cart ID
29
+ */
30
+ clearCartId(): void;
7
31
  /**
8
32
  * Create a new cart
9
33
  *
@@ -16,21 +40,45 @@ export declare class CartClient extends StorefrontAPIClient {
16
40
  cart: components["schemas"]["Cart"];
17
41
  }>;
18
42
  /**
19
- * Get cart details by ID
43
+ * Get cart details - either by ID or using the stored cart ID
20
44
  *
21
- * @param cartId - The ID of the cart
45
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID)
22
46
  * @returns Promise with cart details
47
+ * @throws Error if no cartId is provided and none is stored
23
48
  */
24
- getCart(cartId: string): Promise<{
49
+ getCart(cartId?: string): Promise<{
25
50
  cart: components["schemas"]["Cart"];
26
51
  }>;
27
52
  /**
28
- * Delete a cart by ID
53
+ * Delete a cart - either by ID or using the stored cart ID
29
54
  *
30
- * @param cartId - The ID of the cart
55
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID)
31
56
  * @returns Promise that resolves when the cart is deleted
57
+ * @throws Error if no cartId is provided and none is stored
32
58
  */
33
- deleteCart(cartId: string): Promise<void>;
59
+ deleteCart(cartId?: string): Promise<void>;
60
+ /**
61
+ * Add item to cart - either by specified ID or stored cart ID
62
+ * Will create a new cart if no cart ID is available
63
+ *
64
+ * @param item - The item to add to the cart
65
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID or creates a new cart)
66
+ * @returns Promise with updated or created cart
67
+ */
68
+ addItem(item: components["schemas"]["UpdateCartItem"], cartId?: string): Promise<{
69
+ cart: components["schemas"]["Cart"];
70
+ }>;
71
+ /**
72
+ * Update cart items (add, update quantity, remove)
73
+ *
74
+ * @param cartId - The ID of the cart or undefined to use stored cart ID
75
+ * @param item - The item data
76
+ * @returns Promise with updated cart
77
+ * @throws Error if no cartId is provided and none is stored
78
+ */
79
+ updateCartItem(cartId: string | undefined, item: components["schemas"]["UpdateCartItem"]): Promise<{
80
+ cart: components["schemas"]["Cart"];
81
+ }>;
34
82
  /**
35
83
  * Get cart details by user ID
36
84
  *
@@ -47,16 +95,6 @@ export declare class CartClient extends StorefrontAPIClient {
47
95
  * @returns Promise that resolves when the cart is deleted
48
96
  */
49
97
  deleteUserCart(userId: string): Promise<void>;
50
- /**
51
- * Update cart items (add, update quantity, remove)
52
- *
53
- * @param cartId - The ID of the cart
54
- * @param item - The item data
55
- * @returns Promise with updated cart
56
- */
57
- updateCartItem(cartId: string, item: components["schemas"]["UpdateCartItem"]): Promise<{
58
- cart: components["schemas"]["Cart"];
59
- }>;
60
98
  /**
61
99
  * Update cart addresses
62
100
  *
package/dist/lib/cart.js CHANGED
@@ -6,6 +6,40 @@ const client_1 = require("./client");
6
6
  * Client for interacting with cart endpoints
7
7
  */
8
8
  class CartClient extends client_1.StorefrontAPIClient {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.clientStorage = null;
12
+ }
13
+ /**
14
+ * Set the client storage implementation to use for cart ID management
15
+ *
16
+ * @param storage - The client storage instance
17
+ */
18
+ setClientStorage(storage) {
19
+ this.clientStorage = storage;
20
+ }
21
+ /**
22
+ * Get the stored cart ID
23
+ *
24
+ * @returns The cart ID or null if not found
25
+ */
26
+ getCartId() {
27
+ return this.clientStorage?.getCartId() || null;
28
+ }
29
+ /**
30
+ * Set the cart ID in storage
31
+ *
32
+ * @param cartId - The cart ID to store
33
+ */
34
+ setCartId(cartId) {
35
+ this.clientStorage?.setCartId(cartId);
36
+ }
37
+ /**
38
+ * Clear the stored cart ID
39
+ */
40
+ clearCartId() {
41
+ this.clientStorage?.clearCartId();
42
+ }
9
43
  /**
10
44
  * Create a new cart
11
45
  *
@@ -20,20 +54,30 @@ class CartClient extends client_1.StorefrontAPIClient {
20
54
  if (error) {
21
55
  this.handleError(error);
22
56
  }
57
+ // Store the cart ID
58
+ if (data?.content?.cart?.id) {
59
+ this.setCartId(data.content.cart.id);
60
+ }
23
61
  return data?.content;
24
62
  });
25
63
  }
26
64
  /**
27
- * Get cart details by ID
65
+ * Get cart details - either by ID or using the stored cart ID
28
66
  *
29
- * @param cartId - The ID of the cart
67
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID)
30
68
  * @returns Promise with cart details
69
+ * @throws Error if no cartId is provided and none is stored
31
70
  */
32
71
  async getCart(cartId) {
72
+ // Use provided cartId or stored cartId
73
+ const id = cartId || this.getCartId();
74
+ if (!id) {
75
+ throw new Error("Cart ID is required but not provided");
76
+ }
33
77
  return this.executeRequest(async () => {
34
78
  const { data, error } = await this.client.GET("/carts/{id}", {
35
79
  params: {
36
- path: { id: cartId },
80
+ path: { id },
37
81
  },
38
82
  });
39
83
  if (error) {
@@ -43,21 +87,78 @@ class CartClient extends client_1.StorefrontAPIClient {
43
87
  });
44
88
  }
45
89
  /**
46
- * Delete a cart by ID
90
+ * Delete a cart - either by ID or using the stored cart ID
47
91
  *
48
- * @param cartId - The ID of the cart
92
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID)
49
93
  * @returns Promise that resolves when the cart is deleted
94
+ * @throws Error if no cartId is provided and none is stored
50
95
  */
51
96
  async deleteCart(cartId) {
52
- const { error } = await this.client.DELETE("/carts/{id}", {
53
- params: {
54
- path: { id: cartId },
55
- },
56
- body: undefined,
97
+ // Use provided cartId or stored cartId
98
+ const id = cartId || this.getCartId();
99
+ if (!id) {
100
+ throw new Error("Cart ID is required but not provided");
101
+ }
102
+ return this.executeRequest(async () => {
103
+ const { error } = await this.client.DELETE("/carts/{id}", {
104
+ params: {
105
+ path: { id },
106
+ },
107
+ body: undefined,
108
+ });
109
+ if (error) {
110
+ this.handleError(error);
111
+ }
112
+ // Clear the stored cart ID if we deleted the current cart
113
+ if (cartId === undefined || cartId === this.getCartId()) {
114
+ this.clearCartId();
115
+ }
57
116
  });
58
- if (error) {
59
- this.handleError(error);
117
+ }
118
+ /**
119
+ * Add item to cart - either by specified ID or stored cart ID
120
+ * Will create a new cart if no cart ID is available
121
+ *
122
+ * @param item - The item to add to the cart
123
+ * @param cartId - Optional cart ID (if not provided, uses stored cart ID or creates a new cart)
124
+ * @returns Promise with updated or created cart
125
+ */
126
+ async addItem(item, cartId) {
127
+ // Check if we have a cart ID (either provided or stored)
128
+ const id = cartId || this.getCartId();
129
+ // If we don't have a cart ID, create a new cart
130
+ if (!id) {
131
+ return this.createCart({ items: [item] });
132
+ }
133
+ // Otherwise update existing cart
134
+ return this.updateCartItem(id, item);
135
+ }
136
+ /**
137
+ * Update cart items (add, update quantity, remove)
138
+ *
139
+ * @param cartId - The ID of the cart or undefined to use stored cart ID
140
+ * @param item - The item data
141
+ * @returns Promise with updated cart
142
+ * @throws Error if no cartId is provided and none is stored
143
+ */
144
+ async updateCartItem(cartId, item) {
145
+ // Use provided cartId or stored cartId
146
+ const id = cartId || this.getCartId();
147
+ if (!id) {
148
+ throw new Error("Cart ID is required but not provided");
60
149
  }
150
+ return this.executeRequest(async () => {
151
+ const { data, error } = await this.client.POST("/carts/{id}/items", {
152
+ params: {
153
+ path: { id },
154
+ },
155
+ body: item,
156
+ });
157
+ if (error) {
158
+ this.handleError(error);
159
+ }
160
+ return data?.content;
161
+ });
61
162
  }
62
163
  /**
63
164
  * Get cart details by user ID
@@ -66,15 +167,17 @@ class CartClient extends client_1.StorefrontAPIClient {
66
167
  * @returns Promise with cart details
67
168
  */
68
169
  async getUserCart(userId) {
69
- const { data, error } = await this.client.GET("/carts/users/{user_id}", {
70
- params: {
71
- path: { user_id: userId },
72
- },
170
+ return this.executeRequest(async () => {
171
+ const { data, error } = await this.client.GET("/carts/users/{user_id}", {
172
+ params: {
173
+ path: { user_id: userId },
174
+ },
175
+ });
176
+ if (error) {
177
+ this.handleError(error);
178
+ }
179
+ return data?.content;
73
180
  });
74
- if (error) {
75
- this.handleError(error);
76
- }
77
- return data?.content;
78
181
  }
79
182
  /**
80
183
  * Delete a cart by user ID
@@ -83,34 +186,17 @@ class CartClient extends client_1.StorefrontAPIClient {
83
186
  * @returns Promise that resolves when the cart is deleted
84
187
  */
85
188
  async deleteUserCart(userId) {
86
- const { error } = await this.client.DELETE("/carts/users/{user_id}", {
87
- params: {
88
- path: { user_id: userId },
89
- },
90
- body: undefined,
91
- });
92
- if (error) {
93
- this.handleError(error);
94
- }
95
- }
96
- /**
97
- * Update cart items (add, update quantity, remove)
98
- *
99
- * @param cartId - The ID of the cart
100
- * @param item - The item data
101
- * @returns Promise with updated cart
102
- */
103
- async updateCartItem(cartId, item) {
104
- const { data, error } = await this.client.POST("/carts/{id}/items", {
105
- params: {
106
- path: { id: cartId },
107
- },
108
- body: item,
189
+ return this.executeRequest(async () => {
190
+ const { error } = await this.client.DELETE("/carts/users/{user_id}", {
191
+ params: {
192
+ path: { user_id: userId },
193
+ },
194
+ body: undefined,
195
+ });
196
+ if (error) {
197
+ this.handleError(error);
198
+ }
109
199
  });
110
- if (error) {
111
- this.handleError(error);
112
- }
113
- return data?.content;
114
200
  }
115
201
  /**
116
202
  * Update cart addresses
@@ -120,16 +206,18 @@ class CartClient extends client_1.StorefrontAPIClient {
120
206
  * @returns Promise with updated cart
121
207
  */
122
208
  async updateCartAddress(cartId, addressData) {
123
- const { data, error } = await this.client.POST("/carts/{id}/address", {
124
- params: {
125
- path: { id: cartId },
126
- },
127
- body: addressData,
209
+ return this.executeRequest(async () => {
210
+ const { data, error } = await this.client.POST("/carts/{id}/address", {
211
+ params: {
212
+ path: { id: cartId },
213
+ },
214
+ body: addressData,
215
+ });
216
+ if (error) {
217
+ this.handleError(error);
218
+ }
219
+ return data?.content;
128
220
  });
129
- if (error) {
130
- this.handleError(error);
131
- }
132
- return data?.content;
133
221
  }
134
222
  /**
135
223
  * Apply a coupon to the cart
@@ -139,16 +227,18 @@ class CartClient extends client_1.StorefrontAPIClient {
139
227
  * @returns Promise with updated cart
140
228
  */
141
229
  async applyCoupon(cartId, couponCode) {
142
- const { data, error } = await this.client.POST("/carts/{id}/coupon", {
143
- params: {
144
- path: { id: cartId },
145
- },
146
- body: { coupon_code: couponCode },
230
+ return this.executeRequest(async () => {
231
+ const { data, error } = await this.client.POST("/carts/{id}/coupon", {
232
+ params: {
233
+ path: { id: cartId },
234
+ },
235
+ body: { coupon_code: couponCode },
236
+ });
237
+ if (error) {
238
+ this.handleError(error);
239
+ }
240
+ return data?.content;
147
241
  });
148
- if (error) {
149
- this.handleError(error);
150
- }
151
- return data?.content;
152
242
  }
153
243
  /**
154
244
  * Remove a coupon from the cart
@@ -157,16 +247,18 @@ class CartClient extends client_1.StorefrontAPIClient {
157
247
  * @returns Promise with updated cart
158
248
  */
159
249
  async removeCoupon(cartId) {
160
- const { data, error } = await this.client.DELETE("/carts/{id}/coupon", {
161
- params: {
162
- path: { id: cartId },
163
- },
164
- body: undefined,
250
+ return this.executeRequest(async () => {
251
+ const { data, error } = await this.client.DELETE("/carts/{id}/coupon", {
252
+ params: {
253
+ path: { id: cartId },
254
+ },
255
+ body: undefined,
256
+ });
257
+ if (error) {
258
+ this.handleError(error);
259
+ }
260
+ return data?.content;
165
261
  });
166
- if (error) {
167
- this.handleError(error);
168
- }
169
- return data?.content;
170
262
  }
171
263
  /**
172
264
  * Redeem loyalty points
@@ -176,16 +268,18 @@ class CartClient extends client_1.StorefrontAPIClient {
176
268
  * @returns Promise with updated cart
177
269
  */
178
270
  async redeemLoyaltyPoints(cartId, points) {
179
- const { data, error } = await this.client.POST("/carts/{id}/loyalty-points", {
180
- params: {
181
- path: { id: cartId },
182
- },
183
- body: { loyalty_point_redeemed: points },
271
+ return this.executeRequest(async () => {
272
+ const { data, error } = await this.client.POST("/carts/{id}/loyalty-points", {
273
+ params: {
274
+ path: { id: cartId },
275
+ },
276
+ body: { loyalty_point_redeemed: points },
277
+ });
278
+ if (error) {
279
+ this.handleError(error);
280
+ }
281
+ return data?.content;
184
282
  });
185
- if (error) {
186
- this.handleError(error);
187
- }
188
- return data?.content;
189
283
  }
190
284
  /**
191
285
  * Remove loyalty points
@@ -194,16 +288,18 @@ class CartClient extends client_1.StorefrontAPIClient {
194
288
  * @returns Promise with updated cart
195
289
  */
196
290
  async removeLoyaltyPoints(cartId) {
197
- const { data, error } = await this.client.DELETE("/carts/{id}/loyalty-points", {
198
- params: {
199
- path: { id: cartId },
200
- },
201
- body: undefined,
291
+ return this.executeRequest(async () => {
292
+ const { data, error } = await this.client.DELETE("/carts/{id}/loyalty-points", {
293
+ params: {
294
+ path: { id: cartId },
295
+ },
296
+ body: undefined,
297
+ });
298
+ if (error) {
299
+ this.handleError(error);
300
+ }
301
+ return data?.content;
202
302
  });
203
- if (error) {
204
- this.handleError(error);
205
- }
206
- return data?.content;
207
303
  }
208
304
  }
209
305
  exports.CartClient = CartClient;
@@ -31,16 +31,18 @@ class CatalogClient extends client_1.StorefrontAPIClient {
31
31
  * @returns Promise with product details
32
32
  */
33
33
  async getProductDetail(productId, options) {
34
- const { data, error } = await this.client.GET("/catalog/products/{product_id}", {
35
- params: {
36
- path: { product_id: productId },
37
- query: options,
38
- },
34
+ return this.executeRequest(async () => {
35
+ const { data, error } = await this.client.GET("/catalog/products/{product_id}", {
36
+ params: {
37
+ path: { product_id: productId },
38
+ query: options,
39
+ },
40
+ });
41
+ if (error) {
42
+ this.handleError(error);
43
+ }
44
+ return data?.content;
39
45
  });
40
- if (error) {
41
- this.handleError(error);
42
- }
43
- return data?.content;
44
46
  }
45
47
  /**
46
48
  * List variants for a specific product
@@ -50,16 +52,18 @@ class CatalogClient extends client_1.StorefrontAPIClient {
50
52
  * @returns Promise with variants
51
53
  */
52
54
  async listProductVariants(productId, options) {
53
- const { data, error } = await this.client.GET("/catalog/products/{product_id}/variants", {
54
- params: {
55
- path: { product_id: productId },
56
- query: options,
57
- },
55
+ return this.executeRequest(async () => {
56
+ const { data, error } = await this.client.GET("/catalog/products/{product_id}/variants", {
57
+ params: {
58
+ path: { product_id: productId },
59
+ query: options,
60
+ },
61
+ });
62
+ if (error) {
63
+ this.handleError(error);
64
+ }
65
+ return data?.content;
58
66
  });
59
- if (error) {
60
- this.handleError(error);
61
- }
62
- return data?.content;
63
67
  }
64
68
  /**
65
69
  * Get details for a specific variant
@@ -70,19 +74,21 @@ class CatalogClient extends client_1.StorefrontAPIClient {
70
74
  * @returns Promise with variant details
71
75
  */
72
76
  async getVariantDetail(productId, variantId, options) {
73
- const { data, error } = await this.client.GET("/catalog/products/{product_id}/variants/{variant_id}", {
74
- params: {
75
- path: {
76
- product_id: productId,
77
- variant_id: variantId,
77
+ return this.executeRequest(async () => {
78
+ const { data, error } = await this.client.GET("/catalog/products/{product_id}/variants/{variant_id}", {
79
+ params: {
80
+ path: {
81
+ product_id: productId,
82
+ variant_id: variantId,
83
+ },
84
+ query: options,
78
85
  },
79
- query: options,
80
- },
86
+ });
87
+ if (error) {
88
+ this.handleError(error);
89
+ }
90
+ return data?.content;
81
91
  });
82
- if (error) {
83
- this.handleError(error);
84
- }
85
- return data?.content;
86
92
  }
87
93
  /**
88
94
  * List all categories
@@ -91,13 +97,15 @@ class CatalogClient extends client_1.StorefrontAPIClient {
91
97
  * @returns Promise with categories and pagination info
92
98
  */
93
99
  async listCategories(options) {
94
- const { data, error } = await this.client.GET("/catalog/categories", {
95
- params: { query: options },
100
+ return this.executeRequest(async () => {
101
+ const { data, error } = await this.client.GET("/catalog/categories", {
102
+ params: { query: options },
103
+ });
104
+ if (error) {
105
+ this.handleError(error);
106
+ }
107
+ return data?.content;
96
108
  });
97
- if (error) {
98
- this.handleError(error);
99
- }
100
- return data?.content;
101
109
  }
102
110
  /**
103
111
  * List reviews for a specific product
@@ -107,16 +115,18 @@ class CatalogClient extends client_1.StorefrontAPIClient {
107
115
  * @returns Promise with reviews and pagination info
108
116
  */
109
117
  async listProductReviews(productId, options) {
110
- const { data, error } = await this.client.GET("/catalog/products/{product_id}/reviews", {
111
- params: {
112
- path: { product_id: productId },
113
- query: options,
114
- },
118
+ return this.executeRequest(async () => {
119
+ const { data, error } = await this.client.GET("/catalog/products/{product_id}/reviews", {
120
+ params: {
121
+ path: { product_id: productId },
122
+ query: options,
123
+ },
124
+ });
125
+ if (error) {
126
+ this.handleError(error);
127
+ }
128
+ return data?.content;
115
129
  });
116
- if (error) {
117
- this.handleError(error);
118
- }
119
- return data?.content;
120
130
  }
121
131
  /**
122
132
  * Create a review for a specific product
@@ -128,16 +138,18 @@ class CatalogClient extends client_1.StorefrontAPIClient {
128
138
  async createProductReview(productId, reviewData) {
129
139
  // Note: In a real implementation, you would need to handle multipart/form-data
130
140
  // This would require FormData and may need additional handling
131
- const { error } = await this.client.POST("/catalog/products/{product_id}/reviews", {
132
- params: {
133
- path: { product_id: productId },
134
- },
135
- body: reviewData,
136
- // This is simplified as we're not properly handling multipart/form-data
141
+ return this.executeRequest(async () => {
142
+ const { error } = await this.client.POST("/catalog/products/{product_id}/reviews", {
143
+ params: {
144
+ path: { product_id: productId },
145
+ },
146
+ body: reviewData,
147
+ // This is simplified as we're not properly handling multipart/form-data
148
+ });
149
+ if (error) {
150
+ this.handleError(error);
151
+ }
137
152
  });
138
- if (error) {
139
- this.handleError(error);
140
- }
141
153
  }
142
154
  /**
143
155
  * Search for products
@@ -146,13 +158,15 @@ class CatalogClient extends client_1.StorefrontAPIClient {
146
158
  * @returns Promise with search results
147
159
  */
148
160
  async searchProducts(searchData) {
149
- const { data, error } = await this.client.POST("/catalog/products/search", {
150
- body: searchData,
161
+ return this.executeRequest(async () => {
162
+ const { data, error } = await this.client.POST("/catalog/products/search", {
163
+ body: searchData,
164
+ });
165
+ if (error) {
166
+ this.handleError(error);
167
+ }
168
+ return data?.content;
151
169
  });
152
- if (error) {
153
- this.handleError(error);
154
- }
155
- return data?.content;
156
170
  }
157
171
  /**
158
172
  * Get product details by ID (alternative implementation)
@@ -61,6 +61,7 @@ export declare class StorefrontAPIClient {
61
61
  private headers;
62
62
  private readonly baseUrl;
63
63
  private isRefreshing;
64
+ private static sharedConfigs;
64
65
  /**
65
66
  * Create a new StorefrontAPIClient
66
67
  *
@@ -44,25 +44,51 @@ class StorefrontAPIClient {
44
44
  */
45
45
  constructor(config) {
46
46
  this.isRefreshing = false;
47
- this.config = config;
47
+ // Use shared config reference for the same storeId to ensure all clients use the same config
48
+ const storeKey = config.storeId + (config.baseUrl || config.environment || "");
49
+ if (!StorefrontAPIClient.sharedConfigs.has(storeKey)) {
50
+ StorefrontAPIClient.sharedConfigs.set(storeKey, { ...config });
51
+ }
52
+ // Use the shared config reference
53
+ this.config = StorefrontAPIClient.sharedConfigs.get(storeKey);
54
+ // Copy non-shared values from the provided config
55
+ if (config.token && !this.config.token) {
56
+ this.config.token = config.token;
57
+ }
58
+ if (config.apiKey && !this.config.apiKey) {
59
+ this.config.apiKey = config.apiKey;
60
+ }
48
61
  this.headers = {
49
62
  "Content-Type": "application/json",
50
63
  };
51
- if (config.token) {
52
- this.headers["Authorization"] = `Bearer ${config.token}`;
64
+ if (this.config.token) {
65
+ this.headers["Authorization"] = `Bearer ${this.config.token}`;
53
66
  }
54
- if (config.apiKey) {
55
- this.headers["X-Api-Key"] = config.apiKey;
67
+ if (this.config.apiKey) {
68
+ this.headers["X-Api-Key"] = this.config.apiKey;
56
69
  }
57
70
  // Determine base URL from environment or use custom URL if provided
58
- this.baseUrl = this.getBaseUrlFromConfig(config);
71
+ this.baseUrl = this.getBaseUrlFromConfig(this.config);
59
72
  this.client = (0, openapi_fetch_1.default)({
60
73
  baseUrl: this.baseUrl,
61
74
  fetch: (input, init) => {
62
75
  // Add timeout if configured
63
- const timeoutSignal = config.timeout
64
- ? AbortSignal.timeout(config.timeout)
76
+ const timeoutSignal = this.config.timeout
77
+ ? AbortSignal.timeout(this.config.timeout)
65
78
  : undefined;
79
+ // Always check for the most current token and API key before each request
80
+ if (this.config.token) {
81
+ this.headers["Authorization"] = `Bearer ${this.config.token}`;
82
+ }
83
+ else {
84
+ delete this.headers["Authorization"];
85
+ }
86
+ if (this.config.apiKey) {
87
+ this.headers["X-Api-Key"] = this.config.apiKey;
88
+ }
89
+ else {
90
+ delete this.headers["X-Api-Key"];
91
+ }
66
92
  // Merge headers
67
93
  const headers = {
68
94
  ...this.headers,
@@ -237,3 +263,5 @@ class StorefrontAPIClient {
237
263
  }
238
264
  }
239
265
  exports.StorefrontAPIClient = StorefrontAPIClient;
266
+ // Shared static reference for configs by storeId to ensure all clients use the same config
267
+ StorefrontAPIClient.sharedConfigs = new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercengine/storefront-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "TypeScript SDK for the Storefront API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",