@commercengine/storefront-sdk 0.3.11 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,129 +0,0 @@
1
- import type { Middleware } from "openapi-fetch";
2
- /**
3
- * Token storage interface for the auth middleware
4
- */
5
- export interface TokenStorage {
6
- getAccessToken(): Promise<string | null>;
7
- setAccessToken(token: string): Promise<void>;
8
- getRefreshToken(): Promise<string | null>;
9
- setRefreshToken(token: string): Promise<void>;
10
- clearTokens(): Promise<void>;
11
- }
12
- /**
13
- * Simple in-memory token storage implementation
14
- */
15
- export declare class MemoryTokenStorage implements TokenStorage {
16
- private accessToken;
17
- private refreshToken;
18
- getAccessToken(): Promise<string | null>;
19
- setAccessToken(token: string): Promise<void>;
20
- getRefreshToken(): Promise<string | null>;
21
- setRefreshToken(token: string): Promise<void>;
22
- clearTokens(): Promise<void>;
23
- }
24
- /**
25
- * Browser localStorage token storage implementation
26
- */
27
- export declare class BrowserTokenStorage implements TokenStorage {
28
- private accessTokenKey;
29
- private refreshTokenKey;
30
- constructor(prefix?: string);
31
- getAccessToken(): Promise<string | null>;
32
- setAccessToken(token: string): Promise<void>;
33
- getRefreshToken(): Promise<string | null>;
34
- setRefreshToken(token: string): Promise<void>;
35
- clearTokens(): Promise<void>;
36
- }
37
- /**
38
- * Cookie-based token storage implementation
39
- */
40
- export declare class CookieTokenStorage implements TokenStorage {
41
- private accessTokenKey;
42
- private refreshTokenKey;
43
- private options;
44
- constructor(options?: CookieTokenStorageOptions);
45
- getAccessToken(): Promise<string | null>;
46
- setAccessToken(token: string): Promise<void>;
47
- getRefreshToken(): Promise<string | null>;
48
- setRefreshToken(token: string): Promise<void>;
49
- clearTokens(): Promise<void>;
50
- private getCookie;
51
- private setCookie;
52
- private deleteCookie;
53
- }
54
- /**
55
- * Configuration options for CookieTokenStorage
56
- */
57
- export interface CookieTokenStorageOptions {
58
- /**
59
- * Prefix for cookie names (default: "storefront_")
60
- */
61
- prefix?: string;
62
- /**
63
- * Maximum age of cookies in seconds (default: 7 days)
64
- */
65
- maxAge?: number;
66
- /**
67
- * Cookie path (default: "/")
68
- */
69
- path?: string;
70
- /**
71
- * Cookie domain (default: current domain)
72
- */
73
- domain?: string;
74
- /**
75
- * Whether cookies should be secure (default: auto-detect based on protocol)
76
- */
77
- secure?: boolean;
78
- /**
79
- * SameSite cookie attribute (default: "Lax")
80
- */
81
- sameSite?: "Strict" | "Lax" | "None";
82
- }
83
- /**
84
- * Configuration for the auth middleware
85
- */
86
- export interface AuthMiddlewareConfig {
87
- /**
88
- * Token storage implementation
89
- */
90
- tokenStorage: TokenStorage;
91
- /**
92
- * API key for anonymous endpoints
93
- */
94
- apiKey?: string;
95
- /**
96
- * Base URL for the API (used for refresh token endpoint)
97
- */
98
- baseUrl: string;
99
- /**
100
- * Function to refresh tokens
101
- * Should make a call to /auth/refresh-token endpoint
102
- */
103
- refreshTokenFn?: (refreshToken: string) => Promise<{
104
- access_token: string;
105
- refresh_token: string;
106
- }>;
107
- /**
108
- * Callback when tokens are updated (login/refresh)
109
- */
110
- onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
111
- /**
112
- * Callback when tokens are cleared (logout/error)
113
- */
114
- onTokensCleared?: () => void;
115
- }
116
- /**
117
- * Create authentication middleware for openapi-fetch
118
- */
119
- export declare function createAuthMiddleware(config: AuthMiddlewareConfig): Middleware;
120
- /**
121
- * Helper function to create auth middleware with sensible defaults
122
- */
123
- export declare function createDefaultAuthMiddleware(options: {
124
- apiKey?: string;
125
- baseUrl: string;
126
- tokenStorage?: TokenStorage;
127
- onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
128
- onTokensCleared?: () => void;
129
- }): Middleware;
@@ -1,333 +0,0 @@
1
- import { isTokenExpired } from "./jwt-utils";
2
- import { getPathnameFromUrl, isAnonymousAuthEndpoint, isTokenReturningEndpoint, isLogoutEndpoint, } from "./auth-utils";
3
- /**
4
- * Simple in-memory token storage implementation
5
- */
6
- export class MemoryTokenStorage {
7
- accessToken = null;
8
- refreshToken = null;
9
- async getAccessToken() {
10
- return this.accessToken;
11
- }
12
- async setAccessToken(token) {
13
- this.accessToken = token;
14
- }
15
- async getRefreshToken() {
16
- return this.refreshToken;
17
- }
18
- async setRefreshToken(token) {
19
- this.refreshToken = token;
20
- }
21
- async clearTokens() {
22
- this.accessToken = null;
23
- this.refreshToken = null;
24
- }
25
- }
26
- /**
27
- * Browser localStorage token storage implementation
28
- */
29
- export class BrowserTokenStorage {
30
- accessTokenKey;
31
- refreshTokenKey;
32
- constructor(prefix = "storefront_") {
33
- this.accessTokenKey = `${prefix}access_token`;
34
- this.refreshTokenKey = `${prefix}refresh_token`;
35
- }
36
- async getAccessToken() {
37
- if (typeof localStorage === "undefined")
38
- return null;
39
- return localStorage.getItem(this.accessTokenKey);
40
- }
41
- async setAccessToken(token) {
42
- if (typeof localStorage !== "undefined") {
43
- localStorage.setItem(this.accessTokenKey, token);
44
- }
45
- }
46
- async getRefreshToken() {
47
- if (typeof localStorage === "undefined")
48
- return null;
49
- return localStorage.getItem(this.refreshTokenKey);
50
- }
51
- async setRefreshToken(token) {
52
- if (typeof localStorage !== "undefined") {
53
- localStorage.setItem(this.refreshTokenKey, token);
54
- }
55
- }
56
- async clearTokens() {
57
- if (typeof localStorage !== "undefined") {
58
- localStorage.removeItem(this.accessTokenKey);
59
- localStorage.removeItem(this.refreshTokenKey);
60
- }
61
- }
62
- }
63
- /**
64
- * Cookie-based token storage implementation
65
- */
66
- export class CookieTokenStorage {
67
- accessTokenKey;
68
- refreshTokenKey;
69
- options;
70
- constructor(options = {}) {
71
- const prefix = options.prefix || "storefront_";
72
- this.accessTokenKey = `${prefix}access_token`;
73
- this.refreshTokenKey = `${prefix}refresh_token`;
74
- this.options = {
75
- maxAge: options.maxAge || 7 * 24 * 60 * 60, // 7 days default
76
- path: options.path || "/",
77
- domain: options.domain,
78
- secure: options.secure ??
79
- (typeof window !== "undefined" &&
80
- window.location?.protocol === "https:"),
81
- sameSite: options.sameSite || "Lax",
82
- httpOnly: false, // Must be false for client-side access
83
- };
84
- }
85
- async getAccessToken() {
86
- return this.getCookie(this.accessTokenKey);
87
- }
88
- async setAccessToken(token) {
89
- this.setCookie(this.accessTokenKey, token);
90
- }
91
- async getRefreshToken() {
92
- return this.getCookie(this.refreshTokenKey);
93
- }
94
- async setRefreshToken(token) {
95
- this.setCookie(this.refreshTokenKey, token);
96
- }
97
- async clearTokens() {
98
- this.deleteCookie(this.accessTokenKey);
99
- this.deleteCookie(this.refreshTokenKey);
100
- }
101
- getCookie(name) {
102
- if (typeof document === "undefined")
103
- return null;
104
- const value = `; ${document.cookie}`;
105
- const parts = value.split(`; ${name}=`);
106
- if (parts.length === 2) {
107
- const cookieValue = parts.pop()?.split(";").shift();
108
- return cookieValue ? decodeURIComponent(cookieValue) : null;
109
- }
110
- return null;
111
- }
112
- setCookie(name, value) {
113
- if (typeof document === "undefined")
114
- return;
115
- const encodedValue = encodeURIComponent(value);
116
- let cookieString = `${name}=${encodedValue}`;
117
- if (this.options.maxAge) {
118
- cookieString += `; Max-Age=${this.options.maxAge}`;
119
- }
120
- if (this.options.path) {
121
- cookieString += `; Path=${this.options.path}`;
122
- }
123
- if (this.options.domain) {
124
- cookieString += `; Domain=${this.options.domain}`;
125
- }
126
- if (this.options.secure) {
127
- cookieString += `; Secure`;
128
- }
129
- if (this.options.sameSite) {
130
- cookieString += `; SameSite=${this.options.sameSite}`;
131
- }
132
- document.cookie = cookieString;
133
- }
134
- deleteCookie(name) {
135
- if (typeof document === "undefined")
136
- return;
137
- let cookieString = `${name}=; Max-Age=0`;
138
- if (this.options.path) {
139
- cookieString += `; Path=${this.options.path}`;
140
- }
141
- if (this.options.domain) {
142
- cookieString += `; Domain=${this.options.domain}`;
143
- }
144
- document.cookie = cookieString;
145
- }
146
- }
147
- /**
148
- * Create authentication middleware for openapi-fetch
149
- */
150
- export function createAuthMiddleware(config) {
151
- let isRefreshing = false;
152
- let refreshPromise = null;
153
- const refreshTokens = async () => {
154
- if (isRefreshing && refreshPromise) {
155
- return refreshPromise;
156
- }
157
- isRefreshing = true;
158
- refreshPromise = (async () => {
159
- try {
160
- const refreshToken = await config.tokenStorage.getRefreshToken();
161
- let newTokens;
162
- if (refreshToken && !isTokenExpired(refreshToken)) {
163
- // Try normal refresh token flow first (only if refresh token is not expired)
164
- if (config.refreshTokenFn) {
165
- // Use provided refresh function
166
- newTokens = await config.refreshTokenFn(refreshToken);
167
- }
168
- else {
169
- // Default refresh implementation
170
- const response = await fetch(`${config.baseUrl}/auth/refresh-token`, {
171
- method: "POST",
172
- headers: {
173
- "Content-Type": "application/json",
174
- },
175
- body: JSON.stringify({ refresh_token: refreshToken }),
176
- });
177
- if (!response.ok) {
178
- throw new Error(`Token refresh failed: ${response.status}`);
179
- }
180
- const data = await response.json();
181
- newTokens = data.content;
182
- }
183
- }
184
- else {
185
- // No refresh token available OR refresh token is expired - try anonymous token fallback
186
- // This handles cases where:
187
- // 1. SDK was initialized with just an access token
188
- // 2. Refresh token has expired
189
- const currentAccessToken = await config.tokenStorage.getAccessToken();
190
- if (!currentAccessToken) {
191
- throw new Error("No tokens available for refresh");
192
- }
193
- const reason = refreshToken
194
- ? "refresh token expired"
195
- : "no refresh token available";
196
- // Get new anonymous tokens while preserving user_id
197
- const response = await fetch(`${config.baseUrl}/auth/anonymous`, {
198
- method: "POST",
199
- headers: {
200
- "Content-Type": "application/json",
201
- ...(config.apiKey && { "X-Api-Key": config.apiKey }),
202
- Authorization: `Bearer ${currentAccessToken}`, // For user_id continuity
203
- },
204
- });
205
- if (!response.ok) {
206
- throw new Error(`Anonymous token fallback failed: ${response.status}`);
207
- }
208
- const data = await response.json();
209
- newTokens = data.content;
210
- console.info(`Token refreshed via anonymous fallback (${reason}) - user may need to re-authenticate for privileged operations`);
211
- }
212
- // Store new tokens
213
- await config.tokenStorage.setAccessToken(newTokens.access_token);
214
- await config.tokenStorage.setRefreshToken(newTokens.refresh_token);
215
- // Notify callback
216
- config.onTokensUpdated?.(newTokens.access_token, newTokens.refresh_token);
217
- }
218
- catch (error) {
219
- console.error("Token refresh failed:", error);
220
- // Clear tokens on refresh failure
221
- await config.tokenStorage.clearTokens();
222
- config.onTokensCleared?.();
223
- throw error;
224
- }
225
- finally {
226
- isRefreshing = false;
227
- refreshPromise = null;
228
- }
229
- })();
230
- return refreshPromise;
231
- };
232
- return {
233
- async onRequest({ request }) {
234
- const pathname = getPathnameFromUrl(request.url);
235
- // Handle anonymous auth endpoint - use API key
236
- if (isAnonymousAuthEndpoint(pathname)) {
237
- if (config.apiKey) {
238
- request.headers.set("X-Api-Key", config.apiKey);
239
- }
240
- // Also send existing access token if available (even if expired)
241
- // This helps the server maintain anonymous user continuity
242
- const existingToken = await config.tokenStorage.getAccessToken();
243
- if (existingToken) {
244
- request.headers.set("Authorization", `Bearer ${existingToken}`);
245
- }
246
- return request;
247
- }
248
- // For all other endpoints, use access token
249
- let accessToken = await config.tokenStorage.getAccessToken();
250
- // Check if token needs refresh
251
- if (accessToken && isTokenExpired(accessToken)) {
252
- try {
253
- await refreshTokens();
254
- accessToken = await config.tokenStorage.getAccessToken();
255
- }
256
- catch (error) {
257
- // If refresh fails, continue with expired token
258
- // The server will return 401 and we'll handle it in onResponse
259
- }
260
- }
261
- // Add Authorization header if we have a token
262
- if (accessToken) {
263
- request.headers.set("Authorization", `Bearer ${accessToken}`);
264
- }
265
- return request;
266
- },
267
- async onResponse({ request, response }) {
268
- const pathname = getPathnameFromUrl(request.url);
269
- // Handle successful responses that return tokens
270
- if (response.ok) {
271
- if (isTokenReturningEndpoint(pathname) ||
272
- isAnonymousAuthEndpoint(pathname)) {
273
- try {
274
- const data = await response.clone().json();
275
- const content = data.content;
276
- if (content?.access_token && content?.refresh_token) {
277
- await config.tokenStorage.setAccessToken(content.access_token);
278
- await config.tokenStorage.setRefreshToken(content.refresh_token);
279
- config.onTokensUpdated?.(content.access_token, content.refresh_token);
280
- }
281
- }
282
- catch (error) {
283
- console.warn("Failed to extract tokens from response:", error);
284
- }
285
- }
286
- else if (isLogoutEndpoint(pathname)) {
287
- // Clear tokens on successful logout
288
- await config.tokenStorage.clearTokens();
289
- config.onTokensCleared?.();
290
- }
291
- }
292
- // Handle 401 responses - only retry if token was expired
293
- if (response.status === 401 && !isAnonymousAuthEndpoint(pathname)) {
294
- const currentToken = await config.tokenStorage.getAccessToken();
295
- // Only attempt refresh if we have a token and it's expired
296
- // This prevents infinite retries for privilege-related 401s
297
- if (currentToken && isTokenExpired(currentToken, 0)) {
298
- try {
299
- await refreshTokens();
300
- // Retry the original request with new token
301
- const newToken = await config.tokenStorage.getAccessToken();
302
- if (newToken) {
303
- const retryRequest = request.clone();
304
- retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
305
- return fetch(retryRequest);
306
- }
307
- }
308
- catch (error) {
309
- // If refresh fails, let the original 401 response through
310
- console.warn("Token refresh failed on 401 response:", error);
311
- }
312
- }
313
- }
314
- return response;
315
- },
316
- };
317
- }
318
- /**
319
- * Helper function to create auth middleware with sensible defaults
320
- */
321
- export function createDefaultAuthMiddleware(options) {
322
- const tokenStorage = options.tokenStorage ||
323
- (typeof localStorage !== "undefined"
324
- ? new BrowserTokenStorage()
325
- : new MemoryTokenStorage());
326
- return createAuthMiddleware({
327
- tokenStorage,
328
- apiKey: options.apiKey,
329
- baseUrl: options.baseUrl,
330
- onTokensUpdated: options.onTokensUpdated,
331
- onTokensCleared: options.onTokensCleared,
332
- });
333
- }
@@ -1,72 +0,0 @@
1
- import type { ApiResult, CancelOrderBody, CancelOrderContent, CancelOrderPathParams, CreateOrderBody, CreateOrderContent, GetOrderDetailContent, GetOrderDetailPathParams, GetPaymentStatusContent, ListOrderPaymentsContent, ListOrderPaymentsPathParams, ListOrderRefundsContent, ListOrderRefundsPathParams, ListOrdersContent, ListOrderShipmentsContent, ListOrderShipmentsPathParams, ListOrdersQuery, RetryOrderPaymentBody, RetryOrderPaymentContent, RetryOrderPaymentPathParams } from "../types/storefront-api-types";
2
- import { StorefrontAPIClient } from "./client";
3
- /**
4
- * Client for interacting with order endpoints
5
- */
6
- export declare class OrderClient extends StorefrontAPIClient {
7
- /**
8
- * Get order details
9
- *
10
- * @param orderNumber - Order number
11
- * @returns Promise with order details
12
- */
13
- getOrderDetails(pathParams: GetOrderDetailPathParams): Promise<ApiResult<GetOrderDetailContent>>;
14
- /**
15
- * Create order
16
- *
17
- * @param cartId - Cart ID
18
- * @param paymentGateway - Payment gateway
19
- * @param paymentGatewayParams - Params for the selected payment gateway
20
- * @returns Promise with order details
21
- */
22
- createOrder(body: CreateOrderBody): Promise<ApiResult<CreateOrderContent>>;
23
- /**
24
- * List all orders
25
- *
26
- * @param queryParams - Query parameters
27
- * @returns Promise with order details
28
- */
29
- listOrders(queryParams: ListOrdersQuery): Promise<ApiResult<ListOrdersContent>>;
30
- /**
31
- * Get payment status for an order
32
- *
33
- * @param orderNumber - Order number
34
- * @returns Promise with payment status
35
- */
36
- getPaymentStatus(orderNumber: string): Promise<ApiResult<GetPaymentStatusContent>>;
37
- /**
38
- * Get all shipments for an order
39
- *
40
- * @param orderNumber - Order number
41
- * @returns Promise with shipments
42
- */
43
- listOrderShipments(pathParams: ListOrderShipmentsPathParams): Promise<ApiResult<ListOrderShipmentsContent>>;
44
- /**
45
- * List order payments
46
- *
47
- * @param orderNumber - Order number
48
- * @returns Promise with payments
49
- */
50
- listOrderPayments(pathParams: ListOrderPaymentsPathParams): Promise<ApiResult<ListOrderPaymentsContent>>;
51
- /**
52
- * List order refunds
53
- *
54
- * @param orderNumber - Order number
55
- * @returns Promise with refunds
56
- */
57
- listOrderRefunds(pathParams: ListOrderRefundsPathParams): Promise<ApiResult<ListOrderRefundsContent>>;
58
- /**
59
- * Cancel an order
60
- *
61
- * @param orderNumber - Order number
62
- * @returns Promise with order details
63
- */
64
- cancelOrder(pathParams: CancelOrderPathParams, body: CancelOrderBody): Promise<ApiResult<CancelOrderContent>>;
65
- /**
66
- * Retry payment for an order
67
- *
68
- * @param orderNumber - Order number
69
- * @returns Promise with order details
70
- */
71
- retryOrderPayment(pathParams: RetryOrderPaymentPathParams, body: RetryOrderPaymentBody): Promise<ApiResult<RetryOrderPaymentContent>>;
72
- }
package/dist/lib/order.js DELETED
@@ -1,125 +0,0 @@
1
- import { StorefrontAPIClient } from "./client";
2
- /**
3
- * Client for interacting with order endpoints
4
- */
5
- export class OrderClient extends StorefrontAPIClient {
6
- /**
7
- * Get order details
8
- *
9
- * @param orderNumber - Order number
10
- * @returns Promise with order details
11
- */
12
- async getOrderDetails(pathParams) {
13
- return this.executeRequest(() => this.client.GET("/orders/{order_number}", {
14
- params: {
15
- path: pathParams,
16
- },
17
- }));
18
- }
19
- /**
20
- * Create order
21
- *
22
- * @param cartId - Cart ID
23
- * @param paymentGateway - Payment gateway
24
- * @param paymentGatewayParams - Params for the selected payment gateway
25
- * @returns Promise with order details
26
- */
27
- async createOrder(body) {
28
- return this.executeRequest(() => this.client.POST("/orders", {
29
- body: body,
30
- }));
31
- }
32
- /**
33
- * List all orders
34
- *
35
- * @param queryParams - Query parameters
36
- * @returns Promise with order details
37
- */
38
- async listOrders(queryParams) {
39
- return this.executeRequest(() => this.client.GET("/orders", {
40
- params: {
41
- query: queryParams,
42
- },
43
- }));
44
- }
45
- /**
46
- * Get payment status for an order
47
- *
48
- * @param orderNumber - Order number
49
- * @returns Promise with payment status
50
- */
51
- async getPaymentStatus(orderNumber) {
52
- return this.executeRequest(() => this.client.GET("/orders/{order_number}/payment-status", {
53
- params: {
54
- path: { order_number: orderNumber },
55
- },
56
- }));
57
- }
58
- /**
59
- * Get all shipments for an order
60
- *
61
- * @param orderNumber - Order number
62
- * @returns Promise with shipments
63
- */
64
- async listOrderShipments(pathParams) {
65
- return this.executeRequest(() => this.client.GET("/orders/{order_number}/shipments", {
66
- params: {
67
- path: pathParams,
68
- },
69
- }));
70
- }
71
- /**
72
- * List order payments
73
- *
74
- * @param orderNumber - Order number
75
- * @returns Promise with payments
76
- */
77
- async listOrderPayments(pathParams) {
78
- return this.executeRequest(() => this.client.GET("/orders/{order_number}/payments", {
79
- params: {
80
- path: pathParams,
81
- },
82
- }));
83
- }
84
- /**
85
- * List order refunds
86
- *
87
- * @param orderNumber - Order number
88
- * @returns Promise with refunds
89
- */
90
- async listOrderRefunds(pathParams) {
91
- return this.executeRequest(() => this.client.GET("/orders/{order_number}/refunds", {
92
- params: {
93
- path: pathParams,
94
- },
95
- }));
96
- }
97
- /**
98
- * Cancel an order
99
- *
100
- * @param orderNumber - Order number
101
- * @returns Promise with order details
102
- */
103
- async cancelOrder(pathParams, body) {
104
- return this.executeRequest(() => this.client.POST("/orders/{order_number}/cancel", {
105
- params: {
106
- path: pathParams,
107
- },
108
- body: body,
109
- }));
110
- }
111
- /**
112
- * Retry payment for an order
113
- *
114
- * @param orderNumber - Order number
115
- * @returns Promise with order details
116
- */
117
- async retryOrderPayment(pathParams, body) {
118
- return this.executeRequest(() => this.client.POST("/orders/{order_number}/retry-payment", {
119
- params: {
120
- path: pathParams,
121
- },
122
- body: body,
123
- }));
124
- }
125
- }
@@ -1,21 +0,0 @@
1
- import type { ApiResult, CheckPincodeServiceabilityContent, CheckPincodeServiceabilityPathParams, GetShippingMethodsBody, GetShippingMethodsContent } from "../types/storefront-api-types";
2
- import { StorefrontAPIClient } from "./client";
3
- /**
4
- * Client for interacting with shipping endpoints
5
- */
6
- export declare class ShippingClient extends StorefrontAPIClient {
7
- /**
8
- * Get shipping options for an order
9
- *
10
- * @param body - Shipping methods body
11
- * @returns Promise with shipping options
12
- */
13
- getShippingMethods(body: GetShippingMethodsBody): Promise<ApiResult<GetShippingMethodsContent>>;
14
- /**
15
- * Check pincode deliverability
16
- *
17
- * @param pathParams - Path parameters
18
- * @returns Promise with pincode deliverability result
19
- */
20
- checkPincodeDeliverability(pathParams: CheckPincodeServiceabilityPathParams): Promise<ApiResult<CheckPincodeServiceabilityContent>>;
21
- }