@commercengine/storefront-sdk 0.3.0 → 0.3.2

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
@@ -1,7 +1,13 @@
1
1
  import { StorefrontAPIClient, Environment } from "./lib/client";
2
2
  import { CatalogClient } from "./lib/catalog";
3
3
  import { CartClient } from "./lib/cart";
4
- import { AuthClient, TokenStorage } from "./lib/auth";
4
+ import { AuthClient } from "./lib/auth";
5
+ import { OrderClient } from "./lib/order";
6
+ import { ShippingClient } from "./lib/shipping";
7
+ import { HelpersClient } from "./lib/helper";
8
+ import { CustomerClient } from "./lib/customer";
9
+ import { TokenStorage, MemoryTokenStorage, BrowserTokenStorage } from "./lib/middleware";
10
+ import { type UserInfo } from "./lib/jwt-utils";
5
11
  /**
6
12
  * SDK initialization options
7
13
  */
@@ -19,9 +25,17 @@ export interface StorefrontSDKOptions {
19
25
  */
20
26
  baseUrl?: string;
21
27
  /**
22
- * Optional authentication token
28
+ * Optional initial access token
29
+ * - If tokenStorage is provided: Used as initial token value, then managed automatically
30
+ * - If tokenStorage is not provided: Used for manual token management
23
31
  */
24
- token?: string;
32
+ accessToken?: string;
33
+ /**
34
+ * Optional initial refresh token
35
+ * - Only used when tokenStorage is provided
36
+ * - Allows initialization with both access and refresh tokens
37
+ */
38
+ refreshToken?: string;
25
39
  /**
26
40
  * X-Api-Key for anonymous authentication endpoints
27
41
  * Required for initial authentication
@@ -32,10 +46,18 @@ export interface StorefrontSDKOptions {
32
46
  */
33
47
  timeout?: number;
34
48
  /**
35
- * Optional token storage strategy
36
- * Defaults to MemoryTokenStorage if not provided
49
+ * Optional token storage for automatic token management
50
+ * If provided, enables automatic token refresh and management
37
51
  */
38
52
  tokenStorage?: TokenStorage;
53
+ /**
54
+ * Callback when tokens are updated (login/refresh)
55
+ */
56
+ onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
57
+ /**
58
+ * Callback when tokens are cleared (logout/error)
59
+ */
60
+ onTokensCleared?: () => void;
39
61
  }
40
62
  /**
41
63
  * Main SDK class for the Storefront API
@@ -54,13 +76,21 @@ export declare class StorefrontSDK {
54
76
  */
55
77
  readonly auth: AuthClient;
56
78
  /**
57
- * The client storage instance used by this SDK
79
+ * Client for customer-related endpoints
80
+ */
81
+ readonly customer: CustomerClient;
82
+ /**
83
+ * Client for helper-related endpoints
58
84
  */
59
- private readonly clientStorage;
85
+ readonly helpers: HelpersClient;
60
86
  /**
61
- * Whether the SDK has been initialized
87
+ * Client for shipping-related endpoints
62
88
  */
63
- private isInitialized;
89
+ readonly shipping: ShippingClient;
90
+ /**
91
+ * Client for order-related endpoints
92
+ */
93
+ readonly order: OrderClient;
64
94
  /**
65
95
  * Create a new StorefrontSDK instance
66
96
  *
@@ -68,58 +98,79 @@ export declare class StorefrontSDK {
68
98
  */
69
99
  constructor(options: StorefrontSDKOptions);
70
100
  /**
71
- * Set up storage with automatic fallback for non-browser environments
101
+ * Set authentication tokens for all clients
102
+ *
103
+ * @param accessToken - The access token (required)
104
+ * @param refreshToken - The refresh token (optional)
105
+ *
106
+ * Behavior:
107
+ * - If tokenStorage is provided: Stores tokens for automatic management
108
+ * - If tokenStorage is not provided: Only stores access token for manual management
72
109
  */
73
- private setupStorage;
110
+ setTokens(accessToken: string, refreshToken?: string): Promise<void>;
74
111
  /**
75
- * Initialize the SDK
76
- * This method should be called before using any SDK features
77
- * It ensures tokens are available and valid
78
- * @returns Promise that resolves when initialization is complete
112
+ * Clear all authentication tokens from all clients
113
+ *
114
+ * Behavior:
115
+ * - If tokenStorage is provided: Clears both access and refresh tokens from storage
116
+ * - If tokenStorage is not provided: Clears the manual access token
79
117
  */
80
- init(): Promise<void>;
118
+ clearTokens(): Promise<void>;
81
119
  /**
82
- * Get the current user ID if available
120
+ * Set the API key for all clients
121
+ *
122
+ * @param apiKey - The API key to set
83
123
  */
84
- getUserId(): Promise<string | null>;
124
+ setApiKey(apiKey: string): void;
85
125
  /**
86
- * Get the current cart ID if one is stored
87
- *
88
- * @returns The current cart ID or null if none exists
126
+ * Clear the API key from all clients
127
+ */
128
+ clearApiKey(): void;
129
+ /**
130
+ * Get the current access token if using token storage
89
131
  */
90
- getCartId(): Promise<string | null>;
132
+ getAccessToken(): Promise<string | null>;
91
133
  /**
92
- * Set a specific cart ID to use
134
+ * Get user information from the current access token
93
135
  *
94
- * @param cartId - The cart ID to use
136
+ * @returns User information extracted from JWT token, or null if no token or invalid token
95
137
  */
96
- setCartId(cartId: string): Promise<void>;
138
+ getUserInfo(): Promise<UserInfo | null>;
97
139
  /**
98
- * Clear the current cart ID
140
+ * Get the current user ID from the access token
141
+ *
142
+ * @returns User ID (ulid) or null if no token or invalid token
99
143
  */
100
- clearCartId(): Promise<void>;
144
+ getUserId(): Promise<string | null>;
101
145
  /**
102
- * Set the authentication token for all clients
103
- * Also stores the token in the configured storage
146
+ * Check if the current user is logged in (not anonymous)
147
+ *
148
+ * @returns True if user is logged in, false if anonymous or no token
104
149
  */
105
- setToken(token: string): Promise<void>;
150
+ isLoggedIn(): Promise<boolean>;
106
151
  /**
107
- * Clear the authentication token from all clients and storage
152
+ * Check if the current user is anonymous
153
+ *
154
+ * @returns True if user is anonymous or no token, false if logged in
108
155
  */
109
- clearToken(): Promise<void>;
156
+ isAnonymous(): Promise<boolean>;
110
157
  /**
111
- * Set the API key for all clients
158
+ * Get the customer ID from the current access token
112
159
  *
113
- * @param apiKey - The API key to set
160
+ * @returns Customer ID or null if no token, invalid token, or user has no customer ID
114
161
  */
115
- setApiKey(apiKey: string): void;
162
+ getCustomerId(): Promise<string | null>;
116
163
  /**
117
- * Clear the API key from all clients
164
+ * Get the customer group ID from the current access token
165
+ *
166
+ * @returns Customer group ID or null if no token, invalid token, or user has no customer group
118
167
  */
119
- clearApiKey(): void;
168
+ getCustomerGroupId(): Promise<string | null>;
120
169
  }
121
170
  export default StorefrontSDK;
122
- export { StorefrontAPIClient, CatalogClient, CartClient, AuthClient };
171
+ export { StorefrontAPIClient, AuthClient, CartClient, CatalogClient, CustomerClient, HelpersClient, ShippingClient, OrderClient };
123
172
  export { Environment };
124
- export { TokenStorage, MemoryTokenStorage, BrowserTokenStorage, CookieTokenStorage, NextCookieTokenStorage, createTokenStorage, } from "./lib/auth";
173
+ export { TokenStorage, MemoryTokenStorage, BrowserTokenStorage };
174
+ export type { UserInfo } from "./lib/jwt-utils";
125
175
  export type { components, operations, paths } from "./types/storefront";
176
+ export type * from "./types/storefront-api-types";
package/dist/index.js CHANGED
@@ -1,178 +1,207 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createTokenStorage = exports.NextCookieTokenStorage = exports.CookieTokenStorage = exports.BrowserTokenStorage = exports.MemoryTokenStorage = exports.Environment = exports.AuthClient = exports.CartClient = exports.CatalogClient = exports.StorefrontAPIClient = exports.StorefrontSDK = void 0;
4
- const client_1 = require("./lib/client");
5
- Object.defineProperty(exports, "StorefrontAPIClient", { enumerable: true, get: function () { return client_1.StorefrontAPIClient; } });
6
- Object.defineProperty(exports, "Environment", { enumerable: true, get: function () { return client_1.Environment; } });
7
- const catalog_1 = require("./lib/catalog");
8
- Object.defineProperty(exports, "CatalogClient", { enumerable: true, get: function () { return catalog_1.CatalogClient; } });
9
- const cart_1 = require("./lib/cart");
10
- Object.defineProperty(exports, "CartClient", { enumerable: true, get: function () { return cart_1.CartClient; } });
11
- const auth_1 = require("./lib/auth");
12
- Object.defineProperty(exports, "AuthClient", { enumerable: true, get: function () { return auth_1.AuthClient; } });
1
+ import { StorefrontAPIClient, Environment, } from "./lib/client";
2
+ import { CatalogClient } from "./lib/catalog";
3
+ import { CartClient } from "./lib/cart";
4
+ import { AuthClient } from "./lib/auth";
5
+ import { OrderClient } from "./lib/order";
6
+ import { ShippingClient } from "./lib/shipping";
7
+ import { HelpersClient } from "./lib/helper";
8
+ import { CustomerClient } from "./lib/customer";
9
+ import { MemoryTokenStorage, BrowserTokenStorage, } from "./lib/middleware";
10
+ import { extractUserInfoFromToken, getUserIdFromToken, isUserLoggedIn, isUserAnonymous, } from "./lib/jwt-utils";
13
11
  /**
14
12
  * Main SDK class for the Storefront API
15
13
  */
16
- class StorefrontSDK {
14
+ export class StorefrontSDK {
15
+ /**
16
+ * Client for catalog-related endpoints (products, categories, etc.)
17
+ */
18
+ catalog;
19
+ /**
20
+ * Client for cart-related endpoints
21
+ */
22
+ cart;
23
+ /**
24
+ * Client for authentication-related endpoints
25
+ */
26
+ auth;
27
+ /**
28
+ * Client for customer-related endpoints
29
+ */
30
+ customer;
31
+ /**
32
+ * Client for helper-related endpoints
33
+ */
34
+ helpers;
35
+ /**
36
+ * Client for shipping-related endpoints
37
+ */
38
+ shipping;
39
+ /**
40
+ * Client for order-related endpoints
41
+ */
42
+ order;
17
43
  /**
18
44
  * Create a new StorefrontSDK instance
19
45
  *
20
46
  * @param options - Configuration options for the SDK
21
47
  */
22
48
  constructor(options) {
23
- /**
24
- * Whether the SDK has been initialized
25
- */
26
- this.isInitialized = false;
27
- // Set up client storage with fallback handling
28
- this.clientStorage = this.setupStorage(options.tokenStorage);
29
49
  // Convert options to internal config format
30
50
  const config = {
31
51
  storeId: options.storeId,
32
52
  environment: options.environment,
33
53
  baseUrl: options.baseUrl,
34
- token: options.token,
54
+ accessToken: options.accessToken,
55
+ refreshToken: options.refreshToken,
35
56
  apiKey: options.apiKey,
36
57
  timeout: options.timeout,
58
+ tokenStorage: options.tokenStorage,
59
+ onTokensUpdated: options.onTokensUpdated,
60
+ onTokensCleared: options.onTokensCleared,
37
61
  };
38
- this.catalog = new catalog_1.CatalogClient(config);
39
- this.cart = new cart_1.CartClient(config);
40
- this.auth = new auth_1.AuthClient(config, this.clientStorage);
41
- // Set client storage for cart management
42
- this.cart.setClientStorage(this.clientStorage);
62
+ this.catalog = new CatalogClient(config);
63
+ this.cart = new CartClient(config);
64
+ this.auth = new AuthClient(config);
65
+ this.customer = new CustomerClient(config);
66
+ this.helpers = new HelpersClient(config);
67
+ this.shipping = new ShippingClient(config);
68
+ this.order = new OrderClient(config);
43
69
  }
44
70
  /**
45
- * Set up storage with automatic fallback for non-browser environments
46
- */
47
- setupStorage(requestedStorage) {
48
- if (!requestedStorage) {
49
- return new auth_1.MemoryTokenStorage();
50
- }
51
- try {
52
- // Test if the requested storage is available
53
- requestedStorage.getItem("test");
54
- // Check if it's a ClientStorage implementation
55
- if ("getCartId" in requestedStorage &&
56
- "setCartId" in requestedStorage &&
57
- "clearCartId" in requestedStorage) {
58
- return requestedStorage;
59
- }
60
- // If it's just a TokenStorage, wrap it in a MemoryTokenStorage for cart functionality
61
- console.warn("Provided storage does not implement ClientStorage interface, wrapping with MemoryTokenStorage for cart functionality");
62
- return new auth_1.MemoryTokenStorage();
63
- }
64
- catch (e) {
65
- // If storage access fails, fallback to memory storage
66
- console.warn("Requested storage is not available in this environment, falling back to memory storage");
67
- return new auth_1.MemoryTokenStorage();
68
- }
71
+ * Set authentication tokens for all clients
72
+ *
73
+ * @param accessToken - The access token (required)
74
+ * @param refreshToken - The refresh token (optional)
75
+ *
76
+ * Behavior:
77
+ * - If tokenStorage is provided: Stores tokens for automatic management
78
+ * - If tokenStorage is not provided: Only stores access token for manual management
79
+ */
80
+ async setTokens(accessToken, refreshToken) {
81
+ await this.catalog.setTokens(accessToken, refreshToken);
82
+ await this.cart.setTokens(accessToken, refreshToken);
83
+ await this.auth.setTokens(accessToken, refreshToken);
84
+ await this.customer.setTokens(accessToken, refreshToken);
85
+ await this.helpers.setTokens(accessToken, refreshToken);
86
+ await this.shipping.setTokens(accessToken, refreshToken);
87
+ await this.order.setTokens(accessToken, refreshToken);
69
88
  }
70
89
  /**
71
- * Initialize the SDK
72
- * This method should be called before using any SDK features
73
- * It ensures tokens are available and valid
74
- * @returns Promise that resolves when initialization is complete
75
- */
76
- async init() {
77
- if (this.isInitialized) {
78
- return;
79
- }
80
- try {
81
- // Try to get existing tokens from storage
82
- const accessToken = await this.clientStorage.getItem("access_token");
83
- const userData = await this.clientStorage.getItem("user_data");
84
- if (accessToken && userData) {
85
- // Set the token for all clients
86
- await this.setToken(accessToken);
87
- }
88
- else {
89
- // If no token exists or no user data, get a new anonymous token
90
- const authResponse = await this.auth.getAnonymousToken();
91
- await this.setToken(authResponse.access_token);
92
- // Store user data
93
- await this.clientStorage.setItem("user_data", JSON.stringify(authResponse.user));
94
- }
95
- this.isInitialized = true;
96
- }
97
- catch (error) {
98
- console.error("Failed to initialize SDK:", error);
99
- throw error;
100
- }
90
+ * Clear all authentication tokens from all clients
91
+ *
92
+ * Behavior:
93
+ * - If tokenStorage is provided: Clears both access and refresh tokens from storage
94
+ * - If tokenStorage is not provided: Clears the manual access token
95
+ */
96
+ async clearTokens() {
97
+ await this.catalog.clearTokens();
98
+ await this.cart.clearTokens();
99
+ await this.auth.clearTokens();
100
+ await this.customer.clearTokens();
101
+ await this.helpers.clearTokens();
102
+ await this.shipping.clearTokens();
103
+ await this.order.clearTokens();
101
104
  }
102
105
  /**
103
- * Get the current user ID if available
106
+ * Set the API key for all clients
107
+ *
108
+ * @param apiKey - The API key to set
104
109
  */
105
- async getUserId() {
106
- return this.clientStorage.getItem("user_id");
110
+ setApiKey(apiKey) {
111
+ this.catalog.setApiKey(apiKey);
112
+ this.cart.setApiKey(apiKey);
113
+ this.auth.setApiKey(apiKey);
114
+ this.customer.setApiKey(apiKey);
115
+ this.helpers.setApiKey(apiKey);
116
+ this.shipping.setApiKey(apiKey);
117
+ this.order.setApiKey(apiKey);
107
118
  }
108
119
  /**
109
- * Get the current cart ID if one is stored
110
- *
111
- * @returns The current cart ID or null if none exists
120
+ * Clear the API key from all clients
112
121
  */
113
- async getCartId() {
114
- return this.clientStorage.getCartId();
122
+ clearApiKey() {
123
+ this.catalog.clearApiKey();
124
+ this.cart.clearApiKey();
125
+ this.auth.clearApiKey();
126
+ this.customer.clearApiKey();
127
+ this.helpers.clearApiKey();
128
+ this.shipping.clearApiKey();
129
+ this.order.clearApiKey();
115
130
  }
116
131
  /**
117
- * Set a specific cart ID to use
132
+ * Get the current access token if using token storage
133
+ */
134
+ async getAccessToken() {
135
+ return await this.auth.getAuthorizationHeader().then(header => header.startsWith('Bearer ') ? header.substring(7) : null);
136
+ }
137
+ /**
138
+ * Get user information from the current access token
118
139
  *
119
- * @param cartId - The cart ID to use
140
+ * @returns User information extracted from JWT token, or null if no token or invalid token
120
141
  */
121
- async setCartId(cartId) {
122
- await this.clientStorage.setCartId(cartId);
142
+ async getUserInfo() {
143
+ const token = await this.getAccessToken();
144
+ if (!token)
145
+ return null;
146
+ return extractUserInfoFromToken(token);
123
147
  }
124
148
  /**
125
- * Clear the current cart ID
149
+ * Get the current user ID from the access token
150
+ *
151
+ * @returns User ID (ulid) or null if no token or invalid token
126
152
  */
127
- async clearCartId() {
128
- await this.clientStorage.clearCartId();
153
+ async getUserId() {
154
+ const token = await this.getAccessToken();
155
+ if (!token)
156
+ return null;
157
+ return getUserIdFromToken(token);
129
158
  }
130
159
  /**
131
- * Set the authentication token for all clients
132
- * Also stores the token in the configured storage
160
+ * Check if the current user is logged in (not anonymous)
161
+ *
162
+ * @returns True if user is logged in, false if anonymous or no token
133
163
  */
134
- async setToken(token) {
135
- this.catalog.setToken(token);
136
- this.cart.setToken(token);
137
- this.auth.setToken(token);
138
- await this.clientStorage.setItem("access_token", token);
164
+ async isLoggedIn() {
165
+ const token = await this.getAccessToken();
166
+ if (!token)
167
+ return false;
168
+ return isUserLoggedIn(token);
139
169
  }
140
170
  /**
141
- * Clear the authentication token from all clients and storage
171
+ * Check if the current user is anonymous
172
+ *
173
+ * @returns True if user is anonymous or no token, false if logged in
142
174
  */
143
- async clearToken() {
144
- this.catalog.clearToken();
145
- this.cart.clearToken();
146
- this.auth.clearToken();
147
- await this.clientStorage.removeItem("access_token");
148
- await this.clientStorage.removeItem("refresh_token");
175
+ async isAnonymous() {
176
+ const token = await this.getAccessToken();
177
+ if (!token)
178
+ return true;
179
+ return isUserAnonymous(token);
149
180
  }
150
181
  /**
151
- * Set the API key for all clients
182
+ * Get the customer ID from the current access token
152
183
  *
153
- * @param apiKey - The API key to set
184
+ * @returns Customer ID or null if no token, invalid token, or user has no customer ID
154
185
  */
155
- setApiKey(apiKey) {
156
- this.catalog.setApiKey(apiKey);
157
- this.cart.setApiKey(apiKey);
158
- this.auth.setApiKey(apiKey);
186
+ async getCustomerId() {
187
+ const userInfo = await this.getUserInfo();
188
+ return userInfo?.customerId || null;
159
189
  }
160
190
  /**
161
- * Clear the API key from all clients
191
+ * Get the customer group ID from the current access token
192
+ *
193
+ * @returns Customer group ID or null if no token, invalid token, or user has no customer group
162
194
  */
163
- clearApiKey() {
164
- this.catalog.clearApiKey();
165
- this.cart.clearApiKey();
166
- this.auth.clearApiKey();
195
+ async getCustomerGroupId() {
196
+ const userInfo = await this.getUserInfo();
197
+ return userInfo?.customerGroupId || null;
167
198
  }
168
199
  }
169
- exports.StorefrontSDK = StorefrontSDK;
170
200
  // Export the main SDK class
171
- exports.default = StorefrontSDK;
201
+ export default StorefrontSDK;
202
+ // Export individual clients for advanced usage
203
+ export { StorefrontAPIClient, AuthClient, CartClient, CatalogClient, CustomerClient, HelpersClient, ShippingClient, OrderClient };
204
+ // Export environment enum
205
+ export { Environment };
172
206
  // Export token storage types
173
- var auth_2 = require("./lib/auth");
174
- Object.defineProperty(exports, "MemoryTokenStorage", { enumerable: true, get: function () { return auth_2.MemoryTokenStorage; } });
175
- Object.defineProperty(exports, "BrowserTokenStorage", { enumerable: true, get: function () { return auth_2.BrowserTokenStorage; } });
176
- Object.defineProperty(exports, "CookieTokenStorage", { enumerable: true, get: function () { return auth_2.CookieTokenStorage; } });
177
- Object.defineProperty(exports, "NextCookieTokenStorage", { enumerable: true, get: function () { return auth_2.NextCookieTokenStorage; } });
178
- Object.defineProperty(exports, "createTokenStorage", { enumerable: true, get: function () { return auth_2.createTokenStorage; } });
207
+ export { MemoryTokenStorage, BrowserTokenStorage };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Extract pathname from URL
3
+ */
4
+ export declare function getPathnameFromUrl(url: string): string;
5
+ /**
6
+ * Check if a URL path is an auth endpoint that should use API key
7
+ */
8
+ export declare function isAnonymousAuthEndpoint(pathname: string): boolean;
9
+ /**
10
+ * Check if a URL path is a login/register endpoint that returns tokens
11
+ */
12
+ export declare function isTokenReturningEndpoint(pathname: string): boolean;
13
+ /**
14
+ * Check if a URL path is the logout endpoint
15
+ */
16
+ export declare function isLogoutEndpoint(pathname: string): boolean;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Extract pathname from URL
3
+ */
4
+ export function getPathnameFromUrl(url) {
5
+ try {
6
+ const urlObj = new URL(url);
7
+ return urlObj.pathname;
8
+ }
9
+ catch {
10
+ // If URL parsing fails, assume it's a relative path
11
+ return url.split('?')[0];
12
+ }
13
+ }
14
+ /**
15
+ * Check if a URL path is an auth endpoint that should use API key
16
+ */
17
+ export function isAnonymousAuthEndpoint(pathname) {
18
+ return pathname.endsWith("/auth/anonymous");
19
+ }
20
+ /**
21
+ * Check if a URL path is a login/register endpoint that returns tokens
22
+ */
23
+ export function isTokenReturningEndpoint(pathname) {
24
+ const tokenEndpoints = [
25
+ "/auth/login/password",
26
+ "/auth/register/phone",
27
+ "/auth/register/email",
28
+ "/auth/verify-otp",
29
+ "/auth/refresh-token"
30
+ ];
31
+ return tokenEndpoints.some(endpoint => pathname.endsWith(endpoint));
32
+ }
33
+ /**
34
+ * Check if a URL path is the logout endpoint
35
+ */
36
+ export function isLogoutEndpoint(pathname) {
37
+ return pathname.endsWith("/auth/logout");
38
+ }