@commercengine/storefront-sdk 0.13.3 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +170 -0
- package/README.md +129 -53
- package/dist/index.d.mts +1763 -1382
- package/dist/index.iife.js +1598 -1359
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +1590 -1356
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.iife.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var CE_SDK = (function(exports) {
|
|
2
2
|
|
|
3
|
-
Object.
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
//#region ../../node_modules/.pnpm/openapi-fetch@0.17.0/node_modules/openapi-fetch/dist/index.mjs
|
|
6
6
|
const PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
@@ -455,7 +455,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
455
455
|
*/
|
|
456
456
|
var DebugLogger = class {
|
|
457
457
|
logger;
|
|
458
|
-
responseTextCache = /* @__PURE__ */ new Map();
|
|
459
458
|
constructor(logger) {
|
|
460
459
|
this.logger = logger || ((level, message, data) => {
|
|
461
460
|
console.log(`[${level.toUpperCase()}]`, message);
|
|
@@ -478,7 +477,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
478
477
|
* Log debug information about API response
|
|
479
478
|
*/
|
|
480
479
|
async logResponse(response, responseBody) {
|
|
481
|
-
if (responseBody && typeof responseBody === "string") this.responseTextCache.set(response.url, responseBody);
|
|
482
480
|
this.logger("info", "API Response Debug Info", {
|
|
483
481
|
url: response.url,
|
|
484
482
|
status: response.status,
|
|
@@ -502,17 +500,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
502
500
|
this.logger("error", message, error);
|
|
503
501
|
}
|
|
504
502
|
/**
|
|
505
|
-
*
|
|
503
|
+
* Compatibility shim retained for older internal callers.
|
|
504
|
+
* Response bodies are no longer cached by the debug logger.
|
|
506
505
|
*/
|
|
507
|
-
getCachedResponseText(
|
|
508
|
-
return
|
|
506
|
+
getCachedResponseText(_url) {
|
|
507
|
+
return null;
|
|
509
508
|
}
|
|
510
509
|
/**
|
|
511
|
-
*
|
|
510
|
+
* Compatibility shim retained for older internal callers.
|
|
511
|
+
* Response bodies are no longer cached by the debug logger.
|
|
512
512
|
*/
|
|
513
|
-
clearCache() {
|
|
514
|
-
this.responseTextCache.clear();
|
|
515
|
-
}
|
|
513
|
+
clearCache() {}
|
|
516
514
|
info(message, data) {
|
|
517
515
|
this.logger("info", message, data);
|
|
518
516
|
}
|
|
@@ -598,14 +596,33 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
598
596
|
* @returns Middleware object with onRequest handler
|
|
599
597
|
*/
|
|
600
598
|
function createTimeoutMiddleware(timeoutMs) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const timeoutId =
|
|
604
|
-
if (
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}
|
|
599
|
+
const timeouts = /* @__PURE__ */ new WeakMap();
|
|
600
|
+
const clearRequestTimeout = (signal) => {
|
|
601
|
+
const timeoutId = timeouts.get(signal);
|
|
602
|
+
if (timeoutId) {
|
|
603
|
+
clearTimeout(timeoutId);
|
|
604
|
+
timeouts.delete(signal);
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
return {
|
|
608
|
+
onRequest: async ({ request }) => {
|
|
609
|
+
const controller = new AbortController();
|
|
610
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
611
|
+
if (request.signal) request.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
612
|
+
const newRequest = new Request(request, { signal: controller.signal });
|
|
613
|
+
timeouts.set(newRequest.signal, timeoutId);
|
|
614
|
+
controller.signal.addEventListener("abort", () => clearRequestTimeout(newRequest.signal), { once: true });
|
|
615
|
+
return newRequest;
|
|
616
|
+
},
|
|
617
|
+
onResponse: async ({ request, response }) => {
|
|
618
|
+
clearRequestTimeout(request.signal);
|
|
619
|
+
return response;
|
|
620
|
+
},
|
|
621
|
+
onError: async ({ request, error }) => {
|
|
622
|
+
clearRequestTimeout(request.signal);
|
|
623
|
+
throw error;
|
|
624
|
+
}
|
|
625
|
+
};
|
|
609
626
|
}
|
|
610
627
|
/**
|
|
611
628
|
* Transform headers using a transformation mapping
|
|
@@ -671,8 +688,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
671
688
|
};
|
|
672
689
|
} catch (err) {
|
|
673
690
|
const mockResponse = new Response(null, {
|
|
674
|
-
status:
|
|
675
|
-
statusText: "
|
|
691
|
+
status: 503,
|
|
692
|
+
statusText: "Service Unavailable"
|
|
676
693
|
});
|
|
677
694
|
return {
|
|
678
695
|
data: null,
|
|
@@ -792,619 +809,228 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
792
809
|
}
|
|
793
810
|
|
|
794
811
|
//#endregion
|
|
795
|
-
//#region src/lib/
|
|
812
|
+
//#region src/lib/shared/url-utils.ts
|
|
796
813
|
/**
|
|
797
|
-
*
|
|
798
|
-
* This is a lightweight replacement for jose's decodeJwt.
|
|
799
|
-
*
|
|
800
|
-
* @param token - The JWT token to decode
|
|
801
|
-
* @returns The decoded payload
|
|
802
|
-
* @throws Error if the token is malformed
|
|
814
|
+
* URL utility functions for the Storefront SDK
|
|
803
815
|
*/
|
|
804
|
-
function decodeJwt(token) {
|
|
805
|
-
if (typeof token !== "string") throw new Error("Invalid token: must be a string");
|
|
806
|
-
const parts = token.split(".");
|
|
807
|
-
if (parts.length !== 3) throw new Error("Invalid token: must have 3 parts");
|
|
808
|
-
const base64Url = parts[1];
|
|
809
|
-
if (!base64Url) throw new Error("Invalid token: missing payload");
|
|
810
|
-
let base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
811
|
-
const padding = base64.length % 4;
|
|
812
|
-
if (padding) base64 += "=".repeat(4 - padding);
|
|
813
|
-
const binaryStr = atob(base64);
|
|
814
|
-
const bytes = new Uint8Array(binaryStr.length);
|
|
815
|
-
for (let i = 0; i < binaryStr.length; i++) bytes[i] = binaryStr.charCodeAt(i);
|
|
816
|
-
const payload = JSON.parse(new TextDecoder().decode(bytes));
|
|
817
|
-
if (typeof payload !== "object" || payload === null) throw new Error("Invalid token: payload must be an object");
|
|
818
|
-
return payload;
|
|
819
|
-
}
|
|
820
816
|
/**
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
* @param token - The JWT token to decode
|
|
824
|
-
* @returns User information or null if token is invalid
|
|
817
|
+
* Available API environments for Commerce Engine
|
|
825
818
|
*/
|
|
826
|
-
function
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
isLoggedIn: payload.is_logged_in,
|
|
838
|
-
isAnonymous: payload.is_anonymous,
|
|
839
|
-
customerId: payload.customer_id,
|
|
840
|
-
customerGroupId: payload.customer_group_id,
|
|
841
|
-
anonymousId: payload.anonymous_id,
|
|
842
|
-
channel: payload.channel,
|
|
843
|
-
tokenExpiry: /* @__PURE__ */ new Date(payload.exp * 1e3),
|
|
844
|
-
tokenIssuedAt: /* @__PURE__ */ new Date(payload.iat * 1e3)
|
|
845
|
-
};
|
|
846
|
-
} catch (error) {
|
|
847
|
-
console.warn("Failed to decode JWT token:", error);
|
|
848
|
-
return null;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
819
|
+
let Environment = /* @__PURE__ */ function(Environment) {
|
|
820
|
+
/**
|
|
821
|
+
* Staging environment
|
|
822
|
+
*/
|
|
823
|
+
Environment["Staging"] = "staging";
|
|
824
|
+
/**
|
|
825
|
+
* Production environment
|
|
826
|
+
*/
|
|
827
|
+
Environment["Production"] = "production";
|
|
828
|
+
return Environment;
|
|
829
|
+
}({});
|
|
851
830
|
/**
|
|
852
|
-
*
|
|
853
|
-
*
|
|
854
|
-
* @param token - The JWT token to check
|
|
855
|
-
* @param bufferSeconds - Buffer time in seconds (default: 30)
|
|
856
|
-
* @returns True if token is expired or will expire within buffer time
|
|
831
|
+
* Build base URL for Storefront API
|
|
857
832
|
*/
|
|
858
|
-
function
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
console.warn("Failed to decode JWT token:", error);
|
|
865
|
-
return true;
|
|
833
|
+
function buildStorefrontURL(config) {
|
|
834
|
+
if (config.baseUrl) return config.baseUrl;
|
|
835
|
+
switch (config.environment || Environment.Production) {
|
|
836
|
+
case Environment.Staging: return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;
|
|
837
|
+
case Environment.Production:
|
|
838
|
+
default: return `https://prod.api.commercengine.io/api/v1/${config.storeId}/storefront`;
|
|
866
839
|
}
|
|
867
840
|
}
|
|
868
|
-
/**
|
|
869
|
-
* Get the user ID from a JWT token
|
|
870
|
-
*
|
|
871
|
-
* @param token - The JWT token
|
|
872
|
-
* @returns User ID (ulid) or null if token is invalid
|
|
873
|
-
*/
|
|
874
|
-
function getUserIdFromToken(token) {
|
|
875
|
-
return extractUserInfoFromToken(token)?.id || null;
|
|
876
|
-
}
|
|
877
|
-
/**
|
|
878
|
-
* Check if user is logged in based on JWT token
|
|
879
|
-
*
|
|
880
|
-
* @param token - The JWT token
|
|
881
|
-
* @returns True if user is logged in, false otherwise
|
|
882
|
-
*/
|
|
883
|
-
function isUserLoggedIn(token) {
|
|
884
|
-
return extractUserInfoFromToken(token)?.isLoggedIn || false;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Check if user is anonymous based on JWT token
|
|
888
|
-
*
|
|
889
|
-
* @param token - The JWT token
|
|
890
|
-
* @returns True if user is anonymous, false otherwise
|
|
891
|
-
*/
|
|
892
|
-
function isUserAnonymous(token) {
|
|
893
|
-
return extractUserInfoFromToken(token)?.isAnonymous ?? true;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
//#endregion
|
|
897
|
-
//#region src/types/api-key-endpoints.ts
|
|
898
|
-
const API_KEY_ENDPOINTS = [
|
|
899
|
-
"/auth/anonymous",
|
|
900
|
-
"/store/check",
|
|
901
|
-
"/store/config"
|
|
902
|
-
];
|
|
903
841
|
|
|
904
842
|
//#endregion
|
|
905
|
-
//#region src/lib/
|
|
843
|
+
//#region src/lib/shared/client.ts
|
|
906
844
|
/**
|
|
907
|
-
*
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
/**
|
|
913
|
-
* Check if a URL path requires API key authentication (auto-generated from OpenAPI spec)
|
|
914
|
-
*/
|
|
915
|
-
function isApiKeyRequiredEndpoint(pathname) {
|
|
916
|
-
return API_KEY_ENDPOINTS.some((endpoint) => pathname.endsWith(endpoint));
|
|
917
|
-
}
|
|
918
|
-
/**
|
|
919
|
-
* Check if a URL path is a login/register endpoint that returns tokens
|
|
845
|
+
* Shared base class for Storefront API clients.
|
|
846
|
+
*
|
|
847
|
+
* This centralizes Storefront-specific URL construction, default header
|
|
848
|
+
* transformations, and shared API key state while leaving auth middleware
|
|
849
|
+
* decisions to the public and session-specific subclasses.
|
|
920
850
|
*/
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
851
|
+
var StorefrontAPIClientBase = class extends BaseAPIClient {
|
|
852
|
+
apiKey;
|
|
853
|
+
constructor(config) {
|
|
854
|
+
const baseUrl = buildStorefrontURL({
|
|
855
|
+
storeId: config.storeId,
|
|
856
|
+
environment: config.environment,
|
|
857
|
+
baseUrl: config.baseUrl
|
|
858
|
+
});
|
|
859
|
+
super({
|
|
860
|
+
baseUrl,
|
|
861
|
+
timeout: config.timeout,
|
|
862
|
+
defaultHeaders: config.defaultHeaders,
|
|
863
|
+
debug: config.debug,
|
|
864
|
+
logger: config.logger
|
|
865
|
+
}, baseUrl, {
|
|
866
|
+
customer_group_id: "x-customer-group-id",
|
|
867
|
+
debug_mode: "x-debug-mode"
|
|
868
|
+
});
|
|
869
|
+
this.apiKey = config.apiKey;
|
|
870
|
+
}
|
|
871
|
+
setApiKey(apiKey) {
|
|
872
|
+
this.apiKey = apiKey;
|
|
873
|
+
}
|
|
874
|
+
clearApiKey() {
|
|
875
|
+
this.apiKey = void 0;
|
|
876
|
+
}
|
|
877
|
+
useMiddleware(middleware) {
|
|
878
|
+
this.client.use(middleware);
|
|
879
|
+
}
|
|
880
|
+
};
|
|
931
881
|
|
|
932
882
|
//#endregion
|
|
933
|
-
//#region src/lib/
|
|
934
|
-
|
|
935
|
-
|
|
883
|
+
//#region src/lib/session/client.ts
|
|
884
|
+
function attachSessionAuth(client, sessionManager) {
|
|
885
|
+
client.useMiddleware(sessionManager.createAuthMiddleware());
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Storefront API client that extends the generic BaseAPIClient
|
|
889
|
+
* Adds Commerce Engine specific authentication and token management
|
|
936
890
|
*/
|
|
937
|
-
var
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
891
|
+
var SessionStorefrontAPIClient = class extends StorefrontAPIClientBase {
|
|
892
|
+
config;
|
|
893
|
+
/**
|
|
894
|
+
* Create a new SessionStorefrontAPIClient
|
|
895
|
+
*
|
|
896
|
+
* @param config - Configuration for the API client
|
|
897
|
+
*/
|
|
898
|
+
constructor(config) {
|
|
899
|
+
super(config);
|
|
900
|
+
this.config = { ...config };
|
|
901
|
+
this.setupStorefrontAuth();
|
|
942
902
|
}
|
|
943
|
-
|
|
944
|
-
|
|
903
|
+
/**
|
|
904
|
+
* Set up Storefront-specific authentication middleware
|
|
905
|
+
*/
|
|
906
|
+
setupStorefrontAuth() {
|
|
907
|
+
attachSessionAuth(this, this.config.sessionManager);
|
|
945
908
|
}
|
|
946
|
-
|
|
947
|
-
|
|
909
|
+
/**
|
|
910
|
+
* Get the authorization header value
|
|
911
|
+
* without creating a new session.
|
|
912
|
+
*
|
|
913
|
+
* @returns The Authorization header value or empty string if no token is set
|
|
914
|
+
*/
|
|
915
|
+
async getAuthorizationHeader() {
|
|
916
|
+
return this.config.sessionManager.getAuthorizationHeader();
|
|
948
917
|
}
|
|
949
|
-
|
|
950
|
-
|
|
918
|
+
/**
|
|
919
|
+
* Set authentication tokens
|
|
920
|
+
*
|
|
921
|
+
* @param accessToken - The access token (required)
|
|
922
|
+
* @param refreshToken - The refresh token (optional)
|
|
923
|
+
*
|
|
924
|
+
* Behavior:
|
|
925
|
+
* - If tokenStorage is provided: Stores tokens for automatic management
|
|
926
|
+
* - If tokenStorage is not provided: Only stores access token for manual management
|
|
927
|
+
*/
|
|
928
|
+
async setTokens(accessToken, refreshToken) {
|
|
929
|
+
await this.config.sessionManager.setTokens(accessToken, refreshToken);
|
|
951
930
|
}
|
|
931
|
+
/**
|
|
932
|
+
* Clear all authentication tokens
|
|
933
|
+
*
|
|
934
|
+
* Behavior:
|
|
935
|
+
* - If tokenStorage is provided: Clears both access and refresh tokens from storage
|
|
936
|
+
* - If tokenStorage is not provided: Clears the manual access token
|
|
937
|
+
*/
|
|
952
938
|
async clearTokens() {
|
|
953
|
-
this.
|
|
954
|
-
this.refreshToken = null;
|
|
939
|
+
await this.config.sessionManager.clearTokens();
|
|
955
940
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
this.
|
|
965
|
-
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
941
|
+
/**
|
|
942
|
+
* Set the X-Api-Key header
|
|
943
|
+
*
|
|
944
|
+
* @param apiKey - The API key to set
|
|
945
|
+
*/
|
|
946
|
+
setApiKey(apiKey) {
|
|
947
|
+
super.setApiKey(apiKey);
|
|
948
|
+
this.config.apiKey = apiKey;
|
|
949
|
+
this.config.sessionManager.setApiKey(apiKey);
|
|
966
950
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
951
|
+
/**
|
|
952
|
+
* Clear the X-Api-Key header
|
|
953
|
+
*/
|
|
954
|
+
clearApiKey() {
|
|
955
|
+
super.clearApiKey();
|
|
956
|
+
this.config.apiKey = void 0;
|
|
957
|
+
this.config.sessionManager.clearApiKey();
|
|
970
958
|
}
|
|
971
|
-
|
|
972
|
-
|
|
959
|
+
/**
|
|
960
|
+
* Resolve the current user ID from explicit parameters or the active session.
|
|
961
|
+
*
|
|
962
|
+
* @param explicitUserId - Optional user ID supplied by the caller
|
|
963
|
+
* @returns The resolved user ID
|
|
964
|
+
* @throws When no user ID is available
|
|
965
|
+
*/
|
|
966
|
+
async resolveCurrentUserId(explicitUserId) {
|
|
967
|
+
if (explicitUserId) return explicitUserId;
|
|
968
|
+
return this.config.sessionManager.ensureUserId();
|
|
973
969
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
970
|
+
/**
|
|
971
|
+
* Resolve path parameters that require `user_id`.
|
|
972
|
+
*
|
|
973
|
+
* @param pathParams - Path parameters with an optional `user_id`
|
|
974
|
+
* @returns Path parameters with a guaranteed `user_id`
|
|
975
|
+
*/
|
|
976
|
+
async resolveUserPathParams(pathParams) {
|
|
977
|
+
return {
|
|
978
|
+
...pathParams,
|
|
979
|
+
user_id: await this.resolveCurrentUserId(pathParams.user_id)
|
|
980
|
+
};
|
|
977
981
|
}
|
|
978
|
-
|
|
979
|
-
|
|
982
|
+
/**
|
|
983
|
+
* Resolve query parameters that require `user_id`.
|
|
984
|
+
*
|
|
985
|
+
* @param queryParams - Query parameters with an optional `user_id`
|
|
986
|
+
* @returns Query parameters with a guaranteed `user_id`
|
|
987
|
+
*/
|
|
988
|
+
async resolveUserQueryParams(queryParams) {
|
|
989
|
+
return {
|
|
990
|
+
...queryParams,
|
|
991
|
+
user_id: await this.resolveCurrentUserId(queryParams.user_id)
|
|
992
|
+
};
|
|
980
993
|
}
|
|
981
|
-
async clearTokens() {
|
|
982
|
-
if (typeof localStorage !== "undefined") {
|
|
983
|
-
localStorage.removeItem(this.accessTokenKey);
|
|
984
|
-
localStorage.removeItem(this.refreshTokenKey);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
};
|
|
988
|
-
/**
|
|
989
|
-
* Cookie-based token storage implementation
|
|
990
|
-
*/
|
|
991
|
-
var CookieTokenStorage = class {
|
|
992
|
-
accessTokenKey;
|
|
993
|
-
refreshTokenKey;
|
|
994
|
-
options;
|
|
995
|
-
constructor(options = {}) {
|
|
996
|
-
const prefix = options.prefix || "storefront_";
|
|
997
|
-
this.accessTokenKey = `${prefix}access_token`;
|
|
998
|
-
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
999
|
-
this.options = {
|
|
1000
|
-
maxAge: options.maxAge || 10080 * 60,
|
|
1001
|
-
path: options.path || "/",
|
|
1002
|
-
domain: options.domain,
|
|
1003
|
-
secure: options.secure ?? (typeof window !== "undefined" && window.location?.protocol === "https:"),
|
|
1004
|
-
sameSite: options.sameSite || "Lax",
|
|
1005
|
-
httpOnly: false
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
async getAccessToken() {
|
|
1009
|
-
return this.getCookie(this.accessTokenKey);
|
|
1010
|
-
}
|
|
1011
|
-
async setAccessToken(token) {
|
|
1012
|
-
this.setCookie(this.accessTokenKey, token);
|
|
1013
|
-
}
|
|
1014
|
-
async getRefreshToken() {
|
|
1015
|
-
return this.getCookie(this.refreshTokenKey);
|
|
1016
|
-
}
|
|
1017
|
-
async setRefreshToken(token) {
|
|
1018
|
-
this.setCookie(this.refreshTokenKey, token);
|
|
1019
|
-
}
|
|
1020
|
-
async clearTokens() {
|
|
1021
|
-
this.deleteCookie(this.accessTokenKey);
|
|
1022
|
-
this.deleteCookie(this.refreshTokenKey);
|
|
1023
|
-
}
|
|
1024
|
-
getCookie(name) {
|
|
1025
|
-
if (typeof document === "undefined") return null;
|
|
1026
|
-
const parts = `; ${document.cookie}`.split(`; ${name}=`);
|
|
1027
|
-
if (parts.length === 2) {
|
|
1028
|
-
const cookieValue = parts.pop()?.split(";").shift();
|
|
1029
|
-
return cookieValue ? decodeURIComponent(cookieValue) : null;
|
|
1030
|
-
}
|
|
1031
|
-
return null;
|
|
1032
|
-
}
|
|
1033
|
-
setCookie(name, value) {
|
|
1034
|
-
if (typeof document === "undefined") return;
|
|
1035
|
-
let cookieString = `${name}=${encodeURIComponent(value)}`;
|
|
1036
|
-
if (this.options.maxAge) cookieString += `; Max-Age=${this.options.maxAge}`;
|
|
1037
|
-
if (this.options.path) cookieString += `; Path=${this.options.path}`;
|
|
1038
|
-
if (this.options.domain) cookieString += `; Domain=${this.options.domain}`;
|
|
1039
|
-
if (this.options.secure) cookieString += `; Secure`;
|
|
1040
|
-
if (this.options.sameSite) cookieString += `; SameSite=${this.options.sameSite}`;
|
|
1041
|
-
document.cookie = cookieString;
|
|
1042
|
-
}
|
|
1043
|
-
deleteCookie(name) {
|
|
1044
|
-
if (typeof document === "undefined") return;
|
|
1045
|
-
let cookieString = `${name}=; Max-Age=0`;
|
|
1046
|
-
if (this.options.path) cookieString += `; Path=${this.options.path}`;
|
|
1047
|
-
if (this.options.domain) cookieString += `; Domain=${this.options.domain}`;
|
|
1048
|
-
document.cookie = cookieString;
|
|
1049
|
-
}
|
|
1050
|
-
};
|
|
1051
|
-
/**
|
|
1052
|
-
* Create authentication middleware for openapi-fetch
|
|
1053
|
-
*/
|
|
1054
|
-
function createAuthMiddleware(config) {
|
|
1055
|
-
let isRefreshing = false;
|
|
1056
|
-
let refreshPromise = null;
|
|
1057
|
-
let hasAssessedTokens = false;
|
|
1058
|
-
const assessTokenStateOnce = async () => {
|
|
1059
|
-
if (hasAssessedTokens) return;
|
|
1060
|
-
hasAssessedTokens = true;
|
|
1061
|
-
try {
|
|
1062
|
-
const accessToken = await config.tokenStorage.getAccessToken();
|
|
1063
|
-
const refreshToken = await config.tokenStorage.getRefreshToken();
|
|
1064
|
-
if (!accessToken && refreshToken) {
|
|
1065
|
-
await config.tokenStorage.clearTokens();
|
|
1066
|
-
console.info("Cleaned up orphaned refresh token");
|
|
1067
|
-
}
|
|
1068
|
-
} catch (error) {
|
|
1069
|
-
console.warn("Token state assessment failed:", error);
|
|
1070
|
-
}
|
|
1071
|
-
};
|
|
1072
|
-
const refreshTokens = async () => {
|
|
1073
|
-
if (isRefreshing && refreshPromise) return refreshPromise;
|
|
1074
|
-
isRefreshing = true;
|
|
1075
|
-
refreshPromise = (async () => {
|
|
1076
|
-
try {
|
|
1077
|
-
const refreshToken = await config.tokenStorage.getRefreshToken();
|
|
1078
|
-
let newTokens;
|
|
1079
|
-
if (refreshToken && !isTokenExpired(refreshToken)) if (config.refreshTokenFn) newTokens = await config.refreshTokenFn(refreshToken);
|
|
1080
|
-
else {
|
|
1081
|
-
const response = await fetch(`${config.baseUrl}/auth/refresh-token`, {
|
|
1082
|
-
method: "POST",
|
|
1083
|
-
headers: { "Content-Type": "application/json" },
|
|
1084
|
-
body: JSON.stringify({ refresh_token: refreshToken })
|
|
1085
|
-
});
|
|
1086
|
-
if (!response.ok) throw new Error(`Token refresh failed: ${response.status}`);
|
|
1087
|
-
newTokens = (await response.json()).content;
|
|
1088
|
-
}
|
|
1089
|
-
else {
|
|
1090
|
-
const currentAccessToken = await config.tokenStorage.getAccessToken();
|
|
1091
|
-
if (!currentAccessToken) throw new Error("No tokens available for refresh");
|
|
1092
|
-
const reason = refreshToken ? "refresh token expired" : "no refresh token available";
|
|
1093
|
-
const response = await fetch(`${config.baseUrl}/auth/anonymous`, {
|
|
1094
|
-
method: "POST",
|
|
1095
|
-
headers: {
|
|
1096
|
-
"Content-Type": "application/json",
|
|
1097
|
-
...config.apiKey && { "X-Api-Key": config.apiKey },
|
|
1098
|
-
Authorization: `Bearer ${currentAccessToken}`
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
if (!response.ok) throw new Error(`Anonymous token fallback failed: ${response.status}`);
|
|
1102
|
-
newTokens = (await response.json()).content;
|
|
1103
|
-
console.info(`Token refreshed via anonymous fallback (${reason}) - user may need to re-authenticate for privileged operations`);
|
|
1104
|
-
}
|
|
1105
|
-
await config.tokenStorage.setAccessToken(newTokens.access_token);
|
|
1106
|
-
await config.tokenStorage.setRefreshToken(newTokens.refresh_token);
|
|
1107
|
-
config.onTokensUpdated?.(newTokens.access_token, newTokens.refresh_token);
|
|
1108
|
-
} catch (error) {
|
|
1109
|
-
console.error("Token refresh failed:", error);
|
|
1110
|
-
await config.tokenStorage.clearTokens();
|
|
1111
|
-
config.onTokensCleared?.();
|
|
1112
|
-
throw error;
|
|
1113
|
-
} finally {
|
|
1114
|
-
isRefreshing = false;
|
|
1115
|
-
refreshPromise = null;
|
|
1116
|
-
}
|
|
1117
|
-
})();
|
|
1118
|
-
return refreshPromise;
|
|
1119
|
-
};
|
|
1120
|
-
return {
|
|
1121
|
-
async onRequest({ request }) {
|
|
1122
|
-
const pathname = getPathnameFromUrl(request.url);
|
|
1123
|
-
await assessTokenStateOnce();
|
|
1124
|
-
if (isAnonymousAuthEndpoint(pathname)) {
|
|
1125
|
-
if (config.apiKey) request.headers.set("X-Api-Key", config.apiKey);
|
|
1126
|
-
const existingToken = await config.tokenStorage.getAccessToken();
|
|
1127
|
-
if (existingToken && !isTokenExpired(existingToken) && isUserLoggedIn(existingToken)) return new Response(JSON.stringify({
|
|
1128
|
-
message: "Cannot create anonymous session while authenticated",
|
|
1129
|
-
success: false,
|
|
1130
|
-
code: "USER_ALREADY_AUTHENTICATED"
|
|
1131
|
-
}), {
|
|
1132
|
-
status: 400,
|
|
1133
|
-
headers: { "Content-Type": "application/json" }
|
|
1134
|
-
});
|
|
1135
|
-
if (existingToken) request.headers.set("Authorization", `Bearer ${existingToken}`);
|
|
1136
|
-
return request;
|
|
1137
|
-
}
|
|
1138
|
-
if (isApiKeyRequiredEndpoint(pathname)) {
|
|
1139
|
-
if (config.apiKey) request.headers.set("X-Api-Key", config.apiKey);
|
|
1140
|
-
return request;
|
|
1141
|
-
}
|
|
1142
|
-
let accessToken = await config.tokenStorage.getAccessToken();
|
|
1143
|
-
if (!accessToken) try {
|
|
1144
|
-
const response = await fetch(`${config.baseUrl}/auth/anonymous`, {
|
|
1145
|
-
method: "POST",
|
|
1146
|
-
headers: {
|
|
1147
|
-
"Content-Type": "application/json",
|
|
1148
|
-
...config.apiKey && { "X-Api-Key": config.apiKey }
|
|
1149
|
-
}
|
|
1150
|
-
});
|
|
1151
|
-
if (response.ok) {
|
|
1152
|
-
const tokens = (await response.json()).content;
|
|
1153
|
-
if (tokens?.access_token && tokens?.refresh_token) {
|
|
1154
|
-
await config.tokenStorage.setAccessToken(tokens.access_token);
|
|
1155
|
-
await config.tokenStorage.setRefreshToken(tokens.refresh_token);
|
|
1156
|
-
accessToken = tokens.access_token;
|
|
1157
|
-
config.onTokensUpdated?.(tokens.access_token, tokens.refresh_token);
|
|
1158
|
-
console.info("Automatically created anonymous session for first API request");
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
console.warn("Failed to automatically create anonymous tokens:", error);
|
|
1163
|
-
}
|
|
1164
|
-
if (accessToken && isTokenExpired(accessToken)) try {
|
|
1165
|
-
await refreshTokens();
|
|
1166
|
-
accessToken = await config.tokenStorage.getAccessToken();
|
|
1167
|
-
} catch (error) {}
|
|
1168
|
-
if (accessToken) request.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1169
|
-
return request;
|
|
1170
|
-
},
|
|
1171
|
-
async onResponse({ request, response }) {
|
|
1172
|
-
const pathname = getPathnameFromUrl(request.url);
|
|
1173
|
-
if (response.ok) {
|
|
1174
|
-
if (isTokenReturningEndpoint(pathname) || isAnonymousAuthEndpoint(pathname)) try {
|
|
1175
|
-
const content = (await response.clone().json()).content;
|
|
1176
|
-
if (content?.access_token && content?.refresh_token) {
|
|
1177
|
-
await config.tokenStorage.setAccessToken(content.access_token);
|
|
1178
|
-
await config.tokenStorage.setRefreshToken(content.refresh_token);
|
|
1179
|
-
config.onTokensUpdated?.(content.access_token, content.refresh_token);
|
|
1180
|
-
}
|
|
1181
|
-
} catch (error) {
|
|
1182
|
-
console.warn("Failed to extract tokens from response:", error);
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
if (response.status === 401 && !isAnonymousAuthEndpoint(pathname)) {
|
|
1186
|
-
const currentToken = await config.tokenStorage.getAccessToken();
|
|
1187
|
-
if (currentToken && isTokenExpired(currentToken, 0)) try {
|
|
1188
|
-
await refreshTokens();
|
|
1189
|
-
const newToken = await config.tokenStorage.getAccessToken();
|
|
1190
|
-
if (newToken) {
|
|
1191
|
-
const retryRequest = request.clone();
|
|
1192
|
-
retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
|
|
1193
|
-
return fetch(retryRequest);
|
|
1194
|
-
}
|
|
1195
|
-
} catch (error) {
|
|
1196
|
-
console.warn("Token refresh failed on 401 response:", error);
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
return response;
|
|
1200
|
-
}
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
/**
|
|
1204
|
-
* Helper function to create auth middleware with sensible defaults
|
|
1205
|
-
*/
|
|
1206
|
-
function createDefaultAuthMiddleware(options) {
|
|
1207
|
-
return createAuthMiddleware({
|
|
1208
|
-
tokenStorage: options.tokenStorage || (typeof localStorage !== "undefined" ? new BrowserTokenStorage() : new MemoryTokenStorage()),
|
|
1209
|
-
apiKey: options.apiKey,
|
|
1210
|
-
baseUrl: options.baseUrl,
|
|
1211
|
-
onTokensUpdated: options.onTokensUpdated,
|
|
1212
|
-
onTokensCleared: options.onTokensCleared
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
//#endregion
|
|
1217
|
-
//#region src/lib/url-utils.ts
|
|
1218
|
-
/**
|
|
1219
|
-
* URL utility functions for the Storefront SDK
|
|
1220
|
-
*/
|
|
1221
|
-
/**
|
|
1222
|
-
* Available API environments for Commerce Engine
|
|
1223
|
-
*/
|
|
1224
|
-
let Environment = /* @__PURE__ */ function(Environment) {
|
|
1225
|
-
/**
|
|
1226
|
-
* Staging environment
|
|
1227
|
-
*/
|
|
1228
|
-
Environment["Staging"] = "staging";
|
|
1229
994
|
/**
|
|
1230
|
-
*
|
|
995
|
+
* Resolve path parameters that require `customer_id`.
|
|
996
|
+
*
|
|
997
|
+
* @param pathParams - Path parameters with an optional `customer_id`
|
|
998
|
+
* @returns Path parameters with a guaranteed `customer_id`
|
|
999
|
+
* @throws When the user is anonymous or no session can be established
|
|
1231
1000
|
*/
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
*/
|
|
1238
|
-
function buildStorefrontURL(config) {
|
|
1239
|
-
if (config.baseUrl) return config.baseUrl;
|
|
1240
|
-
switch (config.environment || Environment.Production) {
|
|
1241
|
-
case Environment.Staging: return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;
|
|
1242
|
-
case Environment.Production:
|
|
1243
|
-
default: return `https://prod.api.commercengine.io/api/v1/${config.storeId}/storefront`;
|
|
1001
|
+
async resolveCustomerPathParams(pathParams) {
|
|
1002
|
+
return {
|
|
1003
|
+
...pathParams,
|
|
1004
|
+
customer_id: pathParams.customer_id ?? await this.config.sessionManager.ensureCustomerId()
|
|
1005
|
+
};
|
|
1244
1006
|
}
|
|
1245
|
-
}
|
|
1007
|
+
};
|
|
1246
1008
|
|
|
1247
1009
|
//#endregion
|
|
1248
|
-
//#region src/lib/
|
|
1010
|
+
//#region src/lib/shared/catalog.ts
|
|
1249
1011
|
/**
|
|
1250
|
-
*
|
|
1251
|
-
* Adds Commerce Engine specific authentication and token management
|
|
1012
|
+
* Client for interacting with catalog endpoints
|
|
1252
1013
|
*/
|
|
1253
|
-
var
|
|
1254
|
-
config;
|
|
1255
|
-
initializationPromise = null;
|
|
1256
|
-
/**
|
|
1257
|
-
* Create a new StorefrontAPIClient
|
|
1258
|
-
*
|
|
1259
|
-
* @param config - Configuration for the API client
|
|
1260
|
-
*/
|
|
1261
|
-
constructor(config) {
|
|
1262
|
-
const baseUrl = buildStorefrontURL({
|
|
1263
|
-
storeId: config.storeId,
|
|
1264
|
-
environment: config.environment,
|
|
1265
|
-
baseUrl: config.baseUrl
|
|
1266
|
-
});
|
|
1267
|
-
super({
|
|
1268
|
-
baseUrl,
|
|
1269
|
-
timeout: config.timeout,
|
|
1270
|
-
defaultHeaders: config.defaultHeaders,
|
|
1271
|
-
debug: config.debug,
|
|
1272
|
-
logger: config.logger
|
|
1273
|
-
}, baseUrl, {
|
|
1274
|
-
customer_group_id: "x-customer-group-id",
|
|
1275
|
-
debug_mode: "x-debug-mode"
|
|
1276
|
-
});
|
|
1277
|
-
this.config = { ...config };
|
|
1278
|
-
this.setupStorefrontAuth();
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Set up Storefront-specific authentication middleware
|
|
1282
|
-
*/
|
|
1283
|
-
setupStorefrontAuth() {
|
|
1284
|
-
const config = this.config;
|
|
1285
|
-
if (config.tokenStorage) {
|
|
1286
|
-
const authMiddleware = createDefaultAuthMiddleware({
|
|
1287
|
-
apiKey: config.apiKey,
|
|
1288
|
-
baseUrl: this.getBaseUrl(),
|
|
1289
|
-
tokenStorage: config.tokenStorage,
|
|
1290
|
-
onTokensUpdated: config.onTokensUpdated,
|
|
1291
|
-
onTokensCleared: config.onTokensCleared
|
|
1292
|
-
});
|
|
1293
|
-
this.client.use(authMiddleware);
|
|
1294
|
-
if (config.accessToken) {
|
|
1295
|
-
this.initializationPromise = this.initializeTokens(config.accessToken, config.refreshToken);
|
|
1296
|
-
config.accessToken = void 0;
|
|
1297
|
-
config.refreshToken = void 0;
|
|
1298
|
-
}
|
|
1299
|
-
} else this.client.use({ onRequest: async ({ request }) => {
|
|
1300
|
-
if (isAnonymousAuthEndpoint(getPathnameFromUrl(request.url))) {
|
|
1301
|
-
if (config.apiKey) request.headers.set("X-Api-Key", config.apiKey);
|
|
1302
|
-
if (config.accessToken) request.headers.set("Authorization", `Bearer ${config.accessToken}`);
|
|
1303
|
-
return request;
|
|
1304
|
-
}
|
|
1305
|
-
if (config.accessToken) request.headers.set("Authorization", `Bearer ${config.accessToken}`);
|
|
1306
|
-
return request;
|
|
1307
|
-
} });
|
|
1308
|
-
}
|
|
1014
|
+
var BaseCatalogClient = class extends StorefrontAPIClientBase {
|
|
1309
1015
|
/**
|
|
1310
|
-
*
|
|
1311
|
-
* If using token storage, gets the current token from storage
|
|
1312
|
-
* Otherwise returns the manual token
|
|
1016
|
+
* List all products
|
|
1313
1017
|
*
|
|
1314
|
-
* @
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
if (this.config.tokenStorage && this.initializationPromise) await this.initializationPromise;
|
|
1318
|
-
if (this.config.tokenStorage) {
|
|
1319
|
-
const token = await this.config.tokenStorage.getAccessToken();
|
|
1320
|
-
return token ? `Bearer ${token}` : "";
|
|
1321
|
-
}
|
|
1322
|
-
return this.config.accessToken ? `Bearer ${this.config.accessToken}` : "";
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Set authentication tokens
|
|
1018
|
+
* @param options - Optional query parameters
|
|
1019
|
+
* @param headers - Optional header parameters (customer_group_id, etc.)
|
|
1020
|
+
* @returns Promise with products and pagination info
|
|
1326
1021
|
*
|
|
1327
|
-
* @
|
|
1328
|
-
*
|
|
1022
|
+
* @example
|
|
1023
|
+
* ```typescript
|
|
1024
|
+
* // Basic product listing
|
|
1025
|
+
* const { data, error } = await sdk.catalog.listProducts();
|
|
1329
1026
|
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
*
|
|
1333
|
-
|
|
1334
|
-
async setTokens(accessToken, refreshToken) {
|
|
1335
|
-
if (this.config.tokenStorage) {
|
|
1336
|
-
await this.config.tokenStorage.setAccessToken(accessToken);
|
|
1337
|
-
if (refreshToken) await this.config.tokenStorage.setRefreshToken(refreshToken);
|
|
1338
|
-
} else {
|
|
1339
|
-
this.config.accessToken = accessToken;
|
|
1340
|
-
if (refreshToken) console.warn("Refresh token provided but ignored in manual token management mode. Use tokenStorage for automatic management.");
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Clear all authentication tokens
|
|
1027
|
+
* if (error) {
|
|
1028
|
+
* console.error("Failed to list products:", error);
|
|
1029
|
+
* return;
|
|
1030
|
+
* }
|
|
1345
1031
|
*
|
|
1346
|
-
*
|
|
1347
|
-
*
|
|
1348
|
-
* - If tokenStorage is not provided: Clears the manual access token
|
|
1349
|
-
*/
|
|
1350
|
-
async clearTokens() {
|
|
1351
|
-
if (this.config.tokenStorage) await this.config.tokenStorage.clearTokens();
|
|
1352
|
-
else this.config.accessToken = void 0;
|
|
1353
|
-
}
|
|
1354
|
-
/**
|
|
1355
|
-
* Set the X-Api-Key header
|
|
1356
|
-
*
|
|
1357
|
-
* @param apiKey - The API key to set
|
|
1358
|
-
*/
|
|
1359
|
-
setApiKey(apiKey) {
|
|
1360
|
-
this.config.apiKey = apiKey;
|
|
1361
|
-
}
|
|
1362
|
-
/**
|
|
1363
|
-
* Clear the X-Api-Key header
|
|
1364
|
-
*/
|
|
1365
|
-
clearApiKey() {
|
|
1366
|
-
this.config.apiKey = void 0;
|
|
1367
|
-
}
|
|
1368
|
-
/**
|
|
1369
|
-
* Initialize tokens in storage (private helper method)
|
|
1370
|
-
*/
|
|
1371
|
-
async initializeTokens(accessToken, refreshToken) {
|
|
1372
|
-
try {
|
|
1373
|
-
if (this.config.tokenStorage) {
|
|
1374
|
-
await this.config.tokenStorage.setAccessToken(accessToken);
|
|
1375
|
-
if (refreshToken) await this.config.tokenStorage.setRefreshToken(refreshToken);
|
|
1376
|
-
}
|
|
1377
|
-
} catch (error) {
|
|
1378
|
-
console.warn("Failed to initialize tokens in storage:", error);
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
};
|
|
1382
|
-
|
|
1383
|
-
//#endregion
|
|
1384
|
-
//#region src/lib/catalog.ts
|
|
1385
|
-
/**
|
|
1386
|
-
* Client for interacting with catalog endpoints
|
|
1387
|
-
*/
|
|
1388
|
-
var CatalogClient = class extends StorefrontAPIClient {
|
|
1389
|
-
/**
|
|
1390
|
-
* List all products
|
|
1391
|
-
*
|
|
1392
|
-
* @param options - Optional query parameters
|
|
1393
|
-
* @param headers - Optional header parameters (customer_group_id, etc.)
|
|
1394
|
-
* @returns Promise with products and pagination info
|
|
1395
|
-
*
|
|
1396
|
-
* @example
|
|
1397
|
-
* ```typescript
|
|
1398
|
-
* // Basic product listing
|
|
1399
|
-
* const { data, error } = await sdk.catalog.listProducts();
|
|
1400
|
-
*
|
|
1401
|
-
* if (error) {
|
|
1402
|
-
* console.error("Failed to list products:", error);
|
|
1403
|
-
* return;
|
|
1404
|
-
* }
|
|
1405
|
-
*
|
|
1406
|
-
* console.log("Products found:", data.products?.length || 0);
|
|
1407
|
-
* console.log("Pagination:", data.pagination);
|
|
1032
|
+
* console.log("Products found:", data.products?.length || 0);
|
|
1033
|
+
* console.log("Pagination:", data.pagination);
|
|
1408
1034
|
*
|
|
1409
1035
|
* // With filtering and pagination
|
|
1410
1036
|
* const { data: filteredData, error: filteredError } = await sdk.catalog.listProducts({
|
|
@@ -1501,7 +1127,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1501
1127
|
/**
|
|
1502
1128
|
* Get details for a specific product
|
|
1503
1129
|
*
|
|
1504
|
-
* @param pathParams - The path parameters
|
|
1130
|
+
* @param pathParams - The path parameters. Accepts product ID or product slug.
|
|
1505
1131
|
* @param headers - Optional header parameters (customer_group_id, etc.)
|
|
1506
1132
|
* @returns Promise with product details
|
|
1507
1133
|
*
|
|
@@ -1509,7 +1135,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1509
1135
|
* ```typescript
|
|
1510
1136
|
* // Get product by ID
|
|
1511
1137
|
* const { data, error } = await sdk.catalog.getProductDetail(
|
|
1512
|
-
* {
|
|
1138
|
+
* { product_id: "prod_123" }
|
|
1513
1139
|
* );
|
|
1514
1140
|
*
|
|
1515
1141
|
* if (error) {
|
|
@@ -1521,14 +1147,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1521
1147
|
* console.log("Price:", data.product.pricing?.selling_price);
|
|
1522
1148
|
* console.log("Description:", data.product.short_description);
|
|
1523
1149
|
*
|
|
1524
|
-
* // Get product by slug
|
|
1150
|
+
* // Get product by slug (also accepted in place of product_id)
|
|
1525
1151
|
* const { data: slugData, error: slugError } = await sdk.catalog.getProductDetail({
|
|
1526
|
-
*
|
|
1152
|
+
* product_id: "detox-candy"
|
|
1527
1153
|
* });
|
|
1528
1154
|
*
|
|
1529
1155
|
* // Override customer group ID for this specific request
|
|
1530
1156
|
* const { data: overrideData, error: overrideError } = await sdk.catalog.getProductDetail(
|
|
1531
|
-
* {
|
|
1157
|
+
* { product_id: "detox-candy" },
|
|
1158
|
+
* undefined,
|
|
1532
1159
|
* {
|
|
1533
1160
|
* "x-customer-group-id": "premium_customers" // Override default SDK config
|
|
1534
1161
|
* }
|
|
@@ -1544,7 +1171,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1544
1171
|
*/
|
|
1545
1172
|
async getProductDetail(pathParams, options, headers) {
|
|
1546
1173
|
const mergedHeaders = this.mergeHeaders(headers);
|
|
1547
|
-
return this.executeRequest(() => this.client.GET("/catalog/products/{
|
|
1174
|
+
return this.executeRequest(() => this.client.GET("/catalog/products/{product_id}", { params: {
|
|
1548
1175
|
path: pathParams,
|
|
1549
1176
|
query: options,
|
|
1550
1177
|
header: mergedHeaders
|
|
@@ -1553,12 +1180,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1553
1180
|
/**
|
|
1554
1181
|
* List all variants for a specific product
|
|
1555
1182
|
*
|
|
1556
|
-
* @param pathParams - The path parameters
|
|
1183
|
+
* @param pathParams - The path parameters. Accepts product ID or product slug.
|
|
1557
1184
|
* @param headers - Optional header parameters (customer_group_id, etc.)
|
|
1558
1185
|
* @returns Promise with product variants and pagination info
|
|
1559
1186
|
*
|
|
1560
1187
|
* @example
|
|
1561
1188
|
* ```typescript
|
|
1189
|
+
* // By product ID
|
|
1562
1190
|
* const { data, error } = await sdk.catalog.listProductVariants(
|
|
1563
1191
|
* { product_id: "prod_123" }
|
|
1564
1192
|
* );
|
|
@@ -1574,9 +1202,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1574
1202
|
* console.log(`Variant: ${variant.name} - SKU: ${variant.sku} - Price: ${variant.pricing?.selling_price}`);
|
|
1575
1203
|
* });
|
|
1576
1204
|
*
|
|
1205
|
+
* // By product slug (also accepted in place of product_id)
|
|
1206
|
+
* const { data: slugData, error: slugError } = await sdk.catalog.listProductVariants(
|
|
1207
|
+
* { product_id: "detox-candy" }
|
|
1208
|
+
* );
|
|
1209
|
+
*
|
|
1577
1210
|
* // Override customer group ID for this specific request
|
|
1578
1211
|
* const { data: overrideData, error: overrideError } = await sdk.catalog.listProductVariants(
|
|
1579
1212
|
* { product_id: "prod_123" },
|
|
1213
|
+
* undefined,
|
|
1580
1214
|
* {
|
|
1581
1215
|
* "x-customer-group-id": "wholesale_customers" // Override default SDK config
|
|
1582
1216
|
* }
|
|
@@ -1594,12 +1228,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1594
1228
|
/**
|
|
1595
1229
|
* Get details for a specific product variant
|
|
1596
1230
|
*
|
|
1597
|
-
* @param pathParams - The path parameters
|
|
1231
|
+
* @param pathParams - The path parameters. Accepts product ID or slug for product_id, and variant ID or slug for variant_id.
|
|
1598
1232
|
* @param headers - Optional header parameters (customer_group_id, etc.)
|
|
1599
1233
|
* @returns Promise with variant details
|
|
1600
1234
|
*
|
|
1601
1235
|
* @example
|
|
1602
1236
|
* ```typescript
|
|
1237
|
+
* // By product ID and variant ID
|
|
1603
1238
|
* const { data, error } = await sdk.catalog.getVariantDetail(
|
|
1604
1239
|
* {
|
|
1605
1240
|
* product_id: "prod_123",
|
|
@@ -1616,6 +1251,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1616
1251
|
* console.log("SKU:", data.variant.sku);
|
|
1617
1252
|
* console.log("Price:", data.variant.pricing?.selling_price);
|
|
1618
1253
|
* console.log("Stock available:", data.variant.stock_available);
|
|
1254
|
+
*
|
|
1255
|
+
* // By product slug and variant slug (also accepted in place of IDs)
|
|
1256
|
+
* const { data: slugData, error: slugError } = await sdk.catalog.getVariantDetail(
|
|
1257
|
+
* {
|
|
1258
|
+
* product_id: "detox-candy",
|
|
1259
|
+
* variant_id: "detox-candy-100g"
|
|
1260
|
+
* }
|
|
1261
|
+
* );
|
|
1619
1262
|
* ```
|
|
1620
1263
|
*/
|
|
1621
1264
|
async getVariantDetail(pathParams, options, headers) {
|
|
@@ -1700,49 +1343,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1700
1343
|
} }));
|
|
1701
1344
|
}
|
|
1702
1345
|
/**
|
|
1703
|
-
* Create a product review
|
|
1704
|
-
*
|
|
1705
|
-
* @param pathParams - The path parameters (product ID)
|
|
1706
|
-
* @param formData - The review data including rating, comment, and optional images
|
|
1707
|
-
* @returns Promise with review creation response
|
|
1708
|
-
*
|
|
1709
|
-
* @example
|
|
1710
|
-
* ```typescript
|
|
1711
|
-
* const { data, error } = await sdk.catalog.createProductReview(
|
|
1712
|
-
* { product_id: "prod_123" },
|
|
1713
|
-
* {
|
|
1714
|
-
* user_id: "user_123",
|
|
1715
|
-
* order_number: "ORD-001",
|
|
1716
|
-
* rating: 5,
|
|
1717
|
-
* review_text: "Excellent product! Highly recommended.",
|
|
1718
|
-
* images: [
|
|
1719
|
-
* new File(["image data"], "review1.jpg", { type: "image/jpeg" }),
|
|
1720
|
-
* new File(["image data"], "review2.jpg", { type: "image/jpeg" })
|
|
1721
|
-
* ]
|
|
1722
|
-
* }
|
|
1723
|
-
* );
|
|
1724
|
-
*
|
|
1725
|
-
* if (error) {
|
|
1726
|
-
* console.error("Failed to create review:", error);
|
|
1727
|
-
* return;
|
|
1728
|
-
* }
|
|
1729
|
-
*
|
|
1730
|
-
* console.log("Review created successfully:", data.message);
|
|
1731
|
-
* ```
|
|
1732
|
-
*/
|
|
1733
|
-
async createProductReview(pathParams, formData) {
|
|
1734
|
-
return this.executeRequest(() => this.client.POST("/catalog/products/{product_id}/reviews", {
|
|
1735
|
-
params: { path: pathParams },
|
|
1736
|
-
body: formData,
|
|
1737
|
-
bodySerializer: (body) => {
|
|
1738
|
-
const fd = new FormData();
|
|
1739
|
-
for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) if (value instanceof File || value instanceof Blob) fd.append(key, value);
|
|
1740
|
-
else fd.append(key, String(value));
|
|
1741
|
-
return fd;
|
|
1742
|
-
}
|
|
1743
|
-
}));
|
|
1744
|
-
}
|
|
1745
|
-
/**
|
|
1746
1346
|
* Search for products
|
|
1747
1347
|
*
|
|
1748
1348
|
* @param searchData - The search query, filters, sort, and pagination options
|
|
@@ -1982,12 +1582,74 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1982
1582
|
}
|
|
1983
1583
|
};
|
|
1984
1584
|
|
|
1585
|
+
//#endregion
|
|
1586
|
+
//#region src/lib/public/catalog.ts
|
|
1587
|
+
/**
|
|
1588
|
+
* Client for interacting with catalog endpoints
|
|
1589
|
+
*/
|
|
1590
|
+
var PublicCatalogClient = class extends BaseCatalogClient {};
|
|
1591
|
+
|
|
1592
|
+
//#endregion
|
|
1593
|
+
//#region src/lib/catalog.ts
|
|
1594
|
+
/**
|
|
1595
|
+
* Client for interacting with catalog endpoints
|
|
1596
|
+
*/
|
|
1597
|
+
var CatalogClient = class extends BaseCatalogClient {
|
|
1598
|
+
constructor(config) {
|
|
1599
|
+
super(config);
|
|
1600
|
+
attachSessionAuth(this, config.sessionManager);
|
|
1601
|
+
}
|
|
1602
|
+
/**
|
|
1603
|
+
* Create a product review
|
|
1604
|
+
*
|
|
1605
|
+
* @param pathParams - The path parameters (product ID)
|
|
1606
|
+
* @param formData - The review data including rating, comment, and optional images
|
|
1607
|
+
* @returns Promise with review creation response
|
|
1608
|
+
*
|
|
1609
|
+
* @example
|
|
1610
|
+
* ```typescript
|
|
1611
|
+
* const { data, error } = await sdk.catalog.createProductReview(
|
|
1612
|
+
* { product_id: "prod_123" },
|
|
1613
|
+
* {
|
|
1614
|
+
* user_id: "user_123",
|
|
1615
|
+
* order_number: "ORD-001",
|
|
1616
|
+
* rating: 5,
|
|
1617
|
+
* review_text: "Excellent product! Highly recommended.",
|
|
1618
|
+
* images: [
|
|
1619
|
+
* new File(["image data"], "review1.jpg", { type: "image/jpeg" }),
|
|
1620
|
+
* new File(["image data"], "review2.jpg", { type: "image/jpeg" })
|
|
1621
|
+
* ]
|
|
1622
|
+
* }
|
|
1623
|
+
* );
|
|
1624
|
+
*
|
|
1625
|
+
* if (error) {
|
|
1626
|
+
* console.error("Failed to create review:", error);
|
|
1627
|
+
* return;
|
|
1628
|
+
* }
|
|
1629
|
+
*
|
|
1630
|
+
* console.log("Review created successfully:", data.message);
|
|
1631
|
+
* ```
|
|
1632
|
+
*/
|
|
1633
|
+
async createProductReview(pathParams, formData) {
|
|
1634
|
+
return this.executeRequest(() => this.client.POST("/catalog/products/{product_id}/reviews", {
|
|
1635
|
+
params: { path: pathParams },
|
|
1636
|
+
body: formData,
|
|
1637
|
+
bodySerializer: (body) => {
|
|
1638
|
+
const fd = new FormData();
|
|
1639
|
+
for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) if (value instanceof File || value instanceof Blob) fd.append(key, value);
|
|
1640
|
+
else fd.append(key, String(value));
|
|
1641
|
+
return fd;
|
|
1642
|
+
}
|
|
1643
|
+
}));
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
|
|
1985
1647
|
//#endregion
|
|
1986
1648
|
//#region src/lib/cart.ts
|
|
1987
1649
|
/**
|
|
1988
1650
|
* Client for interacting with cart endpoints
|
|
1989
1651
|
*/
|
|
1990
|
-
var CartClient = class extends
|
|
1652
|
+
var CartClient = class extends SessionStorefrontAPIClient {
|
|
1991
1653
|
/**
|
|
1992
1654
|
* Create a new cart
|
|
1993
1655
|
*
|
|
@@ -2109,49 +1771,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2109
1771
|
body
|
|
2110
1772
|
}));
|
|
2111
1773
|
}
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
* @param userId - The ID of the user
|
|
2116
|
-
* @returns Promise with cart details
|
|
2117
|
-
* @example
|
|
2118
|
-
* ```typescript
|
|
2119
|
-
* const { data, error } = await sdk.cart.getUserCart({
|
|
2120
|
-
* user_id: "01H9USER12345ABCDE"
|
|
2121
|
-
* });
|
|
2122
|
-
*
|
|
2123
|
-
* if (error) {
|
|
2124
|
-
* console.error("Failed to get user cart:", error.message);
|
|
2125
|
-
* } else {
|
|
2126
|
-
* console.log("User cart ID:", data.cart.id);
|
|
2127
|
-
* console.log("Cart value:", data.cart.subtotal);
|
|
2128
|
-
* }
|
|
2129
|
-
* ```
|
|
2130
|
-
*/
|
|
2131
|
-
async getUserCart(userId) {
|
|
2132
|
-
return this.executeRequest(() => this.client.GET("/carts/users/{user_id}", { params: { path: userId } }));
|
|
1774
|
+
async getUserCart(pathParams = {}) {
|
|
1775
|
+
const resolvedPathParams = await this.resolveUserPathParams(pathParams);
|
|
1776
|
+
return this.executeRequest(() => this.client.GET("/carts/users/{user_id}", { params: { path: resolvedPathParams } }));
|
|
2133
1777
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
*
|
|
2137
|
-
* @param userId - The ID of the user
|
|
2138
|
-
* @returns Promise that resolves when the cart is deleted
|
|
2139
|
-
* @example
|
|
2140
|
-
* ```typescript
|
|
2141
|
-
* const { data, error } = await sdk.cart.deleteUserCart({
|
|
2142
|
-
* user_id: "01H9USER12345ABCDE"
|
|
2143
|
-
* });
|
|
2144
|
-
*
|
|
2145
|
-
* if (error) {
|
|
2146
|
-
* console.error("Failed to delete user cart:", error.message);
|
|
2147
|
-
* } else {
|
|
2148
|
-
* console.log("User cart cleared:", data.message);
|
|
2149
|
-
* }
|
|
2150
|
-
* ```
|
|
2151
|
-
*/
|
|
2152
|
-
async deleteUserCart(userId) {
|
|
1778
|
+
async deleteUserCart(pathParams = {}) {
|
|
1779
|
+
const resolvedPathParams = await this.resolveUserPathParams(pathParams);
|
|
2153
1780
|
return this.executeRequest(() => this.client.DELETE("/carts/users/{user_id}", {
|
|
2154
|
-
params: { path:
|
|
1781
|
+
params: { path: resolvedPathParams },
|
|
2155
1782
|
body: void 0
|
|
2156
1783
|
}));
|
|
2157
1784
|
}
|
|
@@ -2644,92 +2271,31 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2644
2271
|
body: void 0
|
|
2645
2272
|
}));
|
|
2646
2273
|
}
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
* @returns Promise with wishlist items
|
|
2653
|
-
* @example
|
|
2654
|
-
* ```typescript
|
|
2655
|
-
* const { data, error } = await sdk.cart.getWishlist({
|
|
2656
|
-
* user_id: "01H9USER12345ABCDE"
|
|
2657
|
-
* });
|
|
2658
|
-
*
|
|
2659
|
-
* if (error) {
|
|
2660
|
-
* console.error("Failed to get wishlist:", error.message);
|
|
2661
|
-
* } else {
|
|
2662
|
-
* const products = data.products;
|
|
2663
|
-
* console.log("Wishlist items:", products.length);
|
|
2664
|
-
* products.forEach(product => {
|
|
2665
|
-
* console.log("Product:", product.product_name, "Price:", product.pricing?.selling_price);
|
|
2666
|
-
* });
|
|
2667
|
-
* }
|
|
2668
|
-
* ```
|
|
2669
|
-
*/
|
|
2670
|
-
async getWishlist(userId, options) {
|
|
2274
|
+
async getWishlist(pathParamsOrQuery, options) {
|
|
2275
|
+
const hasPathParams = options !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "user_id" in pathParamsOrQuery;
|
|
2276
|
+
const pathParams = hasPathParams ? pathParamsOrQuery : {};
|
|
2277
|
+
const queryParams = hasPathParams ? options : pathParamsOrQuery;
|
|
2278
|
+
const resolvedPathParams = await this.resolveUserPathParams(pathParams);
|
|
2671
2279
|
return this.executeRequest(() => this.client.GET("/wishlist/{user_id}", { params: {
|
|
2672
|
-
path:
|
|
2673
|
-
query:
|
|
2280
|
+
path: resolvedPathParams,
|
|
2281
|
+
query: queryParams
|
|
2674
2282
|
} }));
|
|
2675
2283
|
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
* @param itemId - The ID of the item
|
|
2681
|
-
* @returns Promise with updated wishlist
|
|
2682
|
-
* @example
|
|
2683
|
-
* ```typescript
|
|
2684
|
-
* const { data, error } = await sdk.cart.addToWishlist(
|
|
2685
|
-
* { user_id: "01H9USER12345ABCDE" },
|
|
2686
|
-
* {
|
|
2687
|
-
* product_id: "01F3Z7KG06J4ACWH1C4926KJEC",
|
|
2688
|
-
* variant_id: null
|
|
2689
|
-
* }
|
|
2690
|
-
* );
|
|
2691
|
-
*
|
|
2692
|
-
* if (error) {
|
|
2693
|
-
* console.error("Failed to add to wishlist:", error.message);
|
|
2694
|
-
* } else {
|
|
2695
|
-
* const products = data.products;
|
|
2696
|
-
* console.log("Item added to wishlist, total items:", products.length);
|
|
2697
|
-
* }
|
|
2698
|
-
* ```
|
|
2699
|
-
*/
|
|
2700
|
-
async addToWishlist(userId, itemId) {
|
|
2284
|
+
async addToWishlist(pathParamsOrBody, maybeBody) {
|
|
2285
|
+
const pathParams = maybeBody ? pathParamsOrBody : {};
|
|
2286
|
+
const body = maybeBody ?? pathParamsOrBody;
|
|
2287
|
+
const resolvedPathParams = await this.resolveUserPathParams(pathParams);
|
|
2701
2288
|
return this.executeRequest(() => this.client.POST("/wishlist/{user_id}", {
|
|
2702
|
-
params: { path:
|
|
2703
|
-
body
|
|
2289
|
+
params: { path: resolvedPathParams },
|
|
2290
|
+
body
|
|
2704
2291
|
}));
|
|
2705
2292
|
}
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
* @param body - The body containing product details to remove
|
|
2711
|
-
* @returns Promise with updated wishlist
|
|
2712
|
-
* @example
|
|
2713
|
-
* ```typescript
|
|
2714
|
-
* const { data, error } = await sdk.cart.removeFromWishlist(
|
|
2715
|
-
* { user_id: "01H9USER12345ABCDE" },
|
|
2716
|
-
* {
|
|
2717
|
-
* product_id: "01F3Z7KG06J4ACWH1C4926KJEC",
|
|
2718
|
-
* variant_id: null
|
|
2719
|
-
* }
|
|
2720
|
-
* );
|
|
2721
|
-
*
|
|
2722
|
-
* if (error) {
|
|
2723
|
-
* console.error("Failed to remove from wishlist:", error.message);
|
|
2724
|
-
* } else {
|
|
2725
|
-
* const products = data.products;
|
|
2726
|
-
* console.log("Item removed from wishlist, remaining items:", products.length);
|
|
2727
|
-
* }
|
|
2728
|
-
* ```
|
|
2729
|
-
*/
|
|
2730
|
-
async removeFromWishlist(userId, body) {
|
|
2293
|
+
async removeFromWishlist(pathParamsOrBody, maybeBody) {
|
|
2294
|
+
const pathParams = maybeBody ? pathParamsOrBody : {};
|
|
2295
|
+
const body = maybeBody ?? pathParamsOrBody;
|
|
2296
|
+
const resolvedPathParams = await this.resolveUserPathParams(pathParams);
|
|
2731
2297
|
return this.executeRequest(() => this.client.DELETE("/wishlist/{user_id}", {
|
|
2732
|
-
params: { path:
|
|
2298
|
+
params: { path: resolvedPathParams },
|
|
2733
2299
|
body
|
|
2734
2300
|
}));
|
|
2735
2301
|
}
|
|
@@ -2740,7 +2306,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2740
2306
|
/**
|
|
2741
2307
|
* Client for interacting with authentication endpoints
|
|
2742
2308
|
*/
|
|
2743
|
-
var AuthClient = class extends
|
|
2309
|
+
var AuthClient = class extends SessionStorefrontAPIClient {
|
|
2744
2310
|
/**
|
|
2745
2311
|
* Get anonymous token for guest users
|
|
2746
2312
|
*
|
|
@@ -2873,13 +2439,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2873
2439
|
return this.executeRequest(() => this.client.POST("/auth/login/password", { body }));
|
|
2874
2440
|
}
|
|
2875
2441
|
/**
|
|
2876
|
-
*
|
|
2442
|
+
* Start forgot-password OTP flow
|
|
2877
2443
|
*
|
|
2878
|
-
* @param body - Request body containing email
|
|
2879
|
-
* @
|
|
2444
|
+
* @param body - Request body containing email or phone details
|
|
2445
|
+
* @param headers - Optional header parameters (for example `x-debug-mode`)
|
|
2446
|
+
* @returns Promise with OTP token and action for the reset flow
|
|
2880
2447
|
* @example
|
|
2881
2448
|
* ```typescript
|
|
2882
|
-
* // Send password reset
|
|
2449
|
+
* // Send password reset OTP
|
|
2883
2450
|
* const { data, error } = await sdk.auth.forgotPassword({
|
|
2884
2451
|
* email: "customer@example.com"
|
|
2885
2452
|
* });
|
|
@@ -2887,13 +2454,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2887
2454
|
* if (error) {
|
|
2888
2455
|
* console.error("Password reset failed:", error.message);
|
|
2889
2456
|
* } else {
|
|
2890
|
-
* console.log("
|
|
2891
|
-
*
|
|
2457
|
+
* console.log("OTP token:", data.otp_token);
|
|
2458
|
+
* console.log("Action:", data.otp_action);
|
|
2892
2459
|
* }
|
|
2893
2460
|
* ```
|
|
2894
2461
|
*/
|
|
2895
|
-
async forgotPassword(body) {
|
|
2896
|
-
|
|
2462
|
+
async forgotPassword(body, headers) {
|
|
2463
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
2464
|
+
return this.executeRequest(() => this.client.POST("/auth/forgot-password", {
|
|
2465
|
+
body,
|
|
2466
|
+
params: { header: mergedHeaders }
|
|
2467
|
+
}));
|
|
2897
2468
|
}
|
|
2898
2469
|
/**
|
|
2899
2470
|
* Reset password
|
|
@@ -2975,7 +2546,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2975
2546
|
* Register with phone
|
|
2976
2547
|
*
|
|
2977
2548
|
* @param body - Registration details including phone number and user information
|
|
2978
|
-
* @
|
|
2549
|
+
* @param headers - Optional header parameters (for example `x-debug-mode`)
|
|
2550
|
+
* @returns Promise with OTP token and action for completing registration
|
|
2979
2551
|
* @example
|
|
2980
2552
|
* ```typescript
|
|
2981
2553
|
* // Register a new user with phone number
|
|
@@ -2990,20 +2562,24 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
2990
2562
|
* if (error) {
|
|
2991
2563
|
* console.error("Phone registration failed:", error.message);
|
|
2992
2564
|
* } else {
|
|
2993
|
-
* console.log("
|
|
2994
|
-
* console.log("
|
|
2995
|
-
* console.log("Access token:", data.access_token);
|
|
2565
|
+
* console.log("OTP token:", data.otp_token);
|
|
2566
|
+
* console.log("Action:", data.otp_action);
|
|
2996
2567
|
* }
|
|
2997
2568
|
* ```
|
|
2998
2569
|
*/
|
|
2999
|
-
async registerWithPhone(body) {
|
|
3000
|
-
|
|
2570
|
+
async registerWithPhone(body, headers) {
|
|
2571
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
2572
|
+
return this.executeRequest(() => this.client.POST("/auth/register/phone", {
|
|
2573
|
+
body,
|
|
2574
|
+
params: { header: mergedHeaders }
|
|
2575
|
+
}));
|
|
3001
2576
|
}
|
|
3002
2577
|
/**
|
|
3003
2578
|
* Register with email
|
|
3004
2579
|
*
|
|
3005
2580
|
* @param body - Registration details including email and user information
|
|
3006
|
-
* @
|
|
2581
|
+
* @param headers - Optional header parameters (for example `x-debug-mode`)
|
|
2582
|
+
* @returns Promise with OTP token and action for completing registration
|
|
3007
2583
|
* @example
|
|
3008
2584
|
* ```typescript
|
|
3009
2585
|
* // Register a new user with email address
|
|
@@ -3017,29 +2593,93 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3017
2593
|
* if (error) {
|
|
3018
2594
|
* console.error("Email registration failed:", error.message);
|
|
3019
2595
|
* } else {
|
|
3020
|
-
* console.log("
|
|
3021
|
-
* console.log("
|
|
3022
|
-
* console.log("Access token:", data.access_token);
|
|
2596
|
+
* console.log("OTP token:", data.otp_token);
|
|
2597
|
+
* console.log("Action:", data.otp_action);
|
|
3023
2598
|
* }
|
|
3024
2599
|
* ```
|
|
3025
2600
|
*/
|
|
3026
|
-
async registerWithEmail(body) {
|
|
3027
|
-
|
|
2601
|
+
async registerWithEmail(body, headers) {
|
|
2602
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
2603
|
+
return this.executeRequest(() => this.client.POST("/auth/register/email", {
|
|
2604
|
+
body,
|
|
2605
|
+
params: { header: mergedHeaders }
|
|
2606
|
+
}));
|
|
3028
2607
|
}
|
|
3029
2608
|
/**
|
|
3030
|
-
*
|
|
3031
|
-
*
|
|
3032
|
-
* @
|
|
2609
|
+
* Register with WhatsApp
|
|
2610
|
+
*
|
|
2611
|
+
* @param body - Registration details including WhatsApp number and user information
|
|
2612
|
+
* @param headers - Optional header parameters (for example `x-debug-mode`)
|
|
2613
|
+
* @returns Promise with OTP token and action for completing registration
|
|
3033
2614
|
* @example
|
|
3034
2615
|
* ```typescript
|
|
3035
|
-
* //
|
|
3036
|
-
* const { data, error } = await sdk.auth.
|
|
3037
|
-
*
|
|
2616
|
+
* // Register a new user with WhatsApp number
|
|
2617
|
+
* const { data, error } = await sdk.auth.registerWithWhatsapp({
|
|
2618
|
+
* phone: "9876543210",
|
|
2619
|
+
* country_code: "+91",
|
|
2620
|
+
* first_name: "John",
|
|
2621
|
+
* last_name: "Doe",
|
|
2622
|
+
* email: "john.doe@example.com"
|
|
3038
2623
|
* });
|
|
3039
2624
|
*
|
|
3040
2625
|
* if (error) {
|
|
3041
|
-
* console.error("
|
|
3042
|
-
*
|
|
2626
|
+
* console.error("WhatsApp registration failed:", error.message);
|
|
2627
|
+
* } else {
|
|
2628
|
+
* console.log("OTP token:", data.otp_token);
|
|
2629
|
+
* console.log("Action:", data.otp_action);
|
|
2630
|
+
* }
|
|
2631
|
+
* ```
|
|
2632
|
+
*/
|
|
2633
|
+
async registerWithWhatsapp(body, headers) {
|
|
2634
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
2635
|
+
return this.executeRequest(() => this.client.POST("/auth/register/whatsapp", {
|
|
2636
|
+
body,
|
|
2637
|
+
params: { header: mergedHeaders }
|
|
2638
|
+
}));
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Register with password
|
|
2642
|
+
*
|
|
2643
|
+
* @param body - Registration details including email or phone and password
|
|
2644
|
+
* @param headers - Optional header parameters (for example `x-debug-mode`)
|
|
2645
|
+
* @returns Promise with OTP token and action for completing registration
|
|
2646
|
+
* @example
|
|
2647
|
+
* ```typescript
|
|
2648
|
+
* const { data, error } = await sdk.auth.registerWithPassword({
|
|
2649
|
+
* email: "jane.smith@example.com",
|
|
2650
|
+
* password: "securePassword123",
|
|
2651
|
+
* confirm_password: "securePassword123",
|
|
2652
|
+
* });
|
|
2653
|
+
*
|
|
2654
|
+
* if (error) {
|
|
2655
|
+
* console.error("Password registration failed:", error.message);
|
|
2656
|
+
* } else {
|
|
2657
|
+
* console.log("OTP token:", data.otp_token);
|
|
2658
|
+
* console.log("Action:", data.otp_action);
|
|
2659
|
+
* }
|
|
2660
|
+
* ```
|
|
2661
|
+
*/
|
|
2662
|
+
async registerWithPassword(body, headers) {
|
|
2663
|
+
const mergedHeaders = this.mergeHeaders(headers);
|
|
2664
|
+
return this.executeRequest(() => this.client.POST("/auth/register/password", {
|
|
2665
|
+
body,
|
|
2666
|
+
params: { header: mergedHeaders }
|
|
2667
|
+
}));
|
|
2668
|
+
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Refresh the access token using a refresh token
|
|
2671
|
+
* @param body - Request body containing the refresh token
|
|
2672
|
+
* @returns Promise with the new access token and refresh token
|
|
2673
|
+
* @example
|
|
2674
|
+
* ```typescript
|
|
2675
|
+
* // Refresh access token when it expires
|
|
2676
|
+
* const { data, error } = await sdk.auth.refreshToken({
|
|
2677
|
+
* refresh_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
2678
|
+
* });
|
|
2679
|
+
*
|
|
2680
|
+
* if (error) {
|
|
2681
|
+
* console.error("Token refresh failed:", error.message);
|
|
2682
|
+
* // Redirect to login
|
|
3043
2683
|
* } else {
|
|
3044
2684
|
* console.log("Token refreshed successfully");
|
|
3045
2685
|
* console.log("New access token:", data.access_token);
|
|
@@ -3293,90 +2933,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3293
2933
|
return this.executeRequest(() => this.client.PUT("/auth/user/{id}/deactivate", { params: { path: pathParams } }));
|
|
3294
2934
|
}
|
|
3295
2935
|
/**
|
|
3296
|
-
* Get user notification preferences
|
|
3297
|
-
*
|
|
3298
|
-
* @param pathParams - Path parameters containing user ID
|
|
3299
|
-
* @returns Promise with user's notification preferences
|
|
3300
|
-
* @example
|
|
3301
|
-
* ```typescript
|
|
3302
|
-
* // Get user's notification preferences
|
|
3303
|
-
* const { data, error } = await sdk.auth.getUserNotificationPreferences({
|
|
3304
|
-
* id: "01H9XYZ12345USERID"
|
|
3305
|
-
* });
|
|
3306
|
-
*
|
|
3307
|
-
* if (error) {
|
|
3308
|
-
* console.error("Failed to get preferences:", error.message);
|
|
3309
|
-
* } else {
|
|
3310
|
-
* console.log("Notification preferences:", data.notification_preferences);
|
|
3311
|
-
* }
|
|
3312
|
-
* ```
|
|
3313
|
-
*/
|
|
3314
|
-
async getUserNotificationPreferences(pathParams) {
|
|
3315
|
-
return this.executeRequest(() => this.client.GET("/auth/user/{id}/notification-preferences", { params: { path: pathParams } }));
|
|
3316
|
-
}
|
|
3317
|
-
/**
|
|
3318
|
-
* Update user notification preferences
|
|
3319
|
-
*
|
|
3320
|
-
* @param pathParams - Path parameters containing user ID
|
|
3321
|
-
* @param body - Updated notification preferences
|
|
3322
|
-
* @returns Promise with updated notification preferences
|
|
3323
|
-
* @example
|
|
3324
|
-
* ```typescript
|
|
3325
|
-
* // Update user's notification preferences
|
|
3326
|
-
* const { data, error } = await sdk.auth.updateUserNotificationPreferences(
|
|
3327
|
-
* { id: "01H9XYZ12345USERID" },
|
|
3328
|
-
* {
|
|
3329
|
-
* email_notifications: true,
|
|
3330
|
-
* sms_notifications: false,
|
|
3331
|
-
* push_notifications: true
|
|
3332
|
-
* }
|
|
3333
|
-
* );
|
|
3334
|
-
*
|
|
3335
|
-
* if (error) {
|
|
3336
|
-
* console.error("Failed to update preferences:", error.message);
|
|
3337
|
-
* } else {
|
|
3338
|
-
* console.log("Preferences updated successfully");
|
|
3339
|
-
* }
|
|
3340
|
-
* ```
|
|
3341
|
-
*/
|
|
3342
|
-
async updateUserNotificationPreferences(pathParams, body) {
|
|
3343
|
-
return this.executeRequest(() => this.client.PUT("/auth/user/{id}/notification-preferences", {
|
|
3344
|
-
params: { path: pathParams },
|
|
3345
|
-
body
|
|
3346
|
-
}));
|
|
3347
|
-
}
|
|
3348
|
-
/**
|
|
3349
|
-
* Create user notification preference
|
|
3350
|
-
*
|
|
3351
|
-
* @param pathParams - Path parameters containing user ID
|
|
3352
|
-
* @param body - Notification preferences to create
|
|
3353
|
-
* @returns Promise with created notification preferences
|
|
3354
|
-
* @example
|
|
3355
|
-
* ```typescript
|
|
3356
|
-
* // Create notification preferences for a user
|
|
3357
|
-
* const { data, error } = await sdk.auth.createUserNotificationPreference(
|
|
3358
|
-
* { id: "01H9XYZ12345USERID" },
|
|
3359
|
-
* {
|
|
3360
|
-
* email_notifications: true,
|
|
3361
|
-
* sms_notifications: true,
|
|
3362
|
-
* push_notifications: false
|
|
3363
|
-
* }
|
|
3364
|
-
* );
|
|
3365
|
-
*
|
|
3366
|
-
* if (error) {
|
|
3367
|
-
* console.error("Failed to create preferences:", error.message);
|
|
3368
|
-
* } else {
|
|
3369
|
-
* console.log("Preferences created successfully");
|
|
3370
|
-
* }
|
|
3371
|
-
* ```
|
|
3372
|
-
*/
|
|
3373
|
-
async createUserNotificationPreference(pathParams, body) {
|
|
3374
|
-
return this.executeRequest(() => this.client.POST("/auth/user/{id}/notification-preferences", {
|
|
3375
|
-
params: { path: pathParams },
|
|
3376
|
-
body
|
|
3377
|
-
}));
|
|
3378
|
-
}
|
|
3379
|
-
/**
|
|
3380
2936
|
* Generate OTP
|
|
3381
2937
|
*
|
|
3382
2938
|
* @param body - OTP generation body (phone or email)
|
|
@@ -3436,7 +2992,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3436
2992
|
/**
|
|
3437
2993
|
* Client for interacting with order endpoints
|
|
3438
2994
|
*/
|
|
3439
|
-
var OrderClient = class extends
|
|
2995
|
+
var OrderClient = class extends SessionStorefrontAPIClient {
|
|
3440
2996
|
/**
|
|
3441
2997
|
* Get order details
|
|
3442
2998
|
*
|
|
@@ -3567,41 +3123,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3567
3123
|
async createOrder(body) {
|
|
3568
3124
|
return this.executeRequest(() => this.client.POST("/orders", { body }));
|
|
3569
3125
|
}
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
* @param queryParams - Query parameters for filtering and pagination
|
|
3574
|
-
* @returns Promise with order list
|
|
3575
|
-
* @example
|
|
3576
|
-
* ```typescript
|
|
3577
|
-
* // Basic usage - only required parameter
|
|
3578
|
-
* const { data, error } = await sdk.order.listOrders({
|
|
3579
|
-
* user_id: "user_01H9XYZ12345ABCDE"
|
|
3580
|
-
* });
|
|
3581
|
-
*
|
|
3582
|
-
* // Advanced usage with optional parameters
|
|
3583
|
-
* const { data, error } = await sdk.order.listOrders({
|
|
3584
|
-
* user_id: "user_01H9XYZ12345ABCDE",
|
|
3585
|
-
* page: 1,
|
|
3586
|
-
* limit: 20,
|
|
3587
|
-
* sort_by: '{"created_at":"desc"}',
|
|
3588
|
-
* status: ["confirmed", "shipped", "delivered"]
|
|
3589
|
-
* });
|
|
3590
|
-
*
|
|
3591
|
-
* if (error) {
|
|
3592
|
-
* console.error("Failed to list orders:", error.message);
|
|
3593
|
-
* } else {
|
|
3594
|
-
* console.log("Orders found:", data.orders?.length || 0);
|
|
3595
|
-
* console.log("Pagination:", data.pagination);
|
|
3596
|
-
*
|
|
3597
|
-
* data.orders?.forEach(order => {
|
|
3598
|
-
* console.log(`Order ${order.order_number}: ${order.status}`);
|
|
3599
|
-
* });
|
|
3600
|
-
* }
|
|
3601
|
-
* ```
|
|
3602
|
-
*/
|
|
3603
|
-
async listOrders(queryParams) {
|
|
3604
|
-
return this.executeRequest(() => this.client.GET("/orders", { params: { query: queryParams } }));
|
|
3126
|
+
async listOrders(queryParams = {}) {
|
|
3127
|
+
const resolvedQueryParams = await this.resolveUserQueryParams(queryParams);
|
|
3128
|
+
return this.executeRequest(() => this.client.GET("/orders", { params: { query: resolvedQueryParams } }));
|
|
3605
3129
|
}
|
|
3606
3130
|
/**
|
|
3607
3131
|
* Get payment status for an order
|
|
@@ -3832,7 +3356,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3832
3356
|
/**
|
|
3833
3357
|
* Client for interacting with payment endpoints
|
|
3834
3358
|
*/
|
|
3835
|
-
var PaymentsClient = class extends
|
|
3359
|
+
var PaymentsClient = class extends SessionStorefrontAPIClient {
|
|
3836
3360
|
/**
|
|
3837
3361
|
* List all available payment methods
|
|
3838
3362
|
*
|
|
@@ -3975,11 +3499,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
3975
3499
|
};
|
|
3976
3500
|
|
|
3977
3501
|
//#endregion
|
|
3978
|
-
//#region src/lib/helper.ts
|
|
3502
|
+
//#region src/lib/shared/helper.ts
|
|
3979
3503
|
/**
|
|
3980
3504
|
* Client for interacting with helper endpoints
|
|
3981
3505
|
*/
|
|
3982
|
-
var
|
|
3506
|
+
var BaseHelpersClient = class extends StorefrontAPIClientBase {
|
|
3983
3507
|
/**
|
|
3984
3508
|
* Get a list of countries
|
|
3985
3509
|
*
|
|
@@ -4002,446 +3526,1077 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4002
3526
|
* });
|
|
4003
3527
|
* ```
|
|
4004
3528
|
*/
|
|
4005
|
-
async listCountries() {
|
|
4006
|
-
return this.executeRequest(() => this.client.GET("/common/countries", {}));
|
|
3529
|
+
async listCountries() {
|
|
3530
|
+
return this.executeRequest(() => this.client.GET("/common/countries", {}));
|
|
3531
|
+
}
|
|
3532
|
+
/**
|
|
3533
|
+
* Get a list of states for a country
|
|
3534
|
+
*
|
|
3535
|
+
* @param pathParams - Path parameters
|
|
3536
|
+
* @returns Promise with states
|
|
3537
|
+
*
|
|
3538
|
+
* @example
|
|
3539
|
+
* ```typescript
|
|
3540
|
+
* const { data, error } = await sdk.helpers.listCountryStates({
|
|
3541
|
+
* country_iso_code: "IN"
|
|
3542
|
+
* });
|
|
3543
|
+
*
|
|
3544
|
+
* if (error) {
|
|
3545
|
+
* console.error("Failed to get states:", error);
|
|
3546
|
+
* return;
|
|
3547
|
+
* }
|
|
3548
|
+
*
|
|
3549
|
+
* console.log("States found:", data.states?.length || 0);
|
|
3550
|
+
*
|
|
3551
|
+
* data.states?.forEach(state => {
|
|
3552
|
+
* console.log(`State: ${state.name} (${state.iso_code})`);
|
|
3553
|
+
* });
|
|
3554
|
+
*
|
|
3555
|
+
* // Get states for different country
|
|
3556
|
+
* const { data: usStates, error: usError } = await sdk.helpers.listCountryStates({
|
|
3557
|
+
* country_iso_code: "US"
|
|
3558
|
+
* });
|
|
3559
|
+
*
|
|
3560
|
+
* if (usError) {
|
|
3561
|
+
* console.error("Failed to get US states:", usError);
|
|
3562
|
+
* return;
|
|
3563
|
+
* }
|
|
3564
|
+
*
|
|
3565
|
+
* console.log("US States:", usStates.states?.map(s => s.name).join(", "));
|
|
3566
|
+
* ```
|
|
3567
|
+
*/
|
|
3568
|
+
async listCountryStates(pathParams) {
|
|
3569
|
+
return this.executeRequest(() => this.client.GET("/common/countries/{country_iso_code}/states", { params: { path: pathParams } }));
|
|
3570
|
+
}
|
|
3571
|
+
/**
|
|
3572
|
+
* Get pincodes for a country
|
|
3573
|
+
*
|
|
3574
|
+
* @param pathParams - Path parameters
|
|
3575
|
+
* @returns Promise with pincodes
|
|
3576
|
+
*
|
|
3577
|
+
* @example
|
|
3578
|
+
* ```typescript
|
|
3579
|
+
* const { data, error } = await sdk.helpers.listCountryPincodes({
|
|
3580
|
+
* country_iso_code: "IN"
|
|
3581
|
+
* });
|
|
3582
|
+
*
|
|
3583
|
+
* if (error) {
|
|
3584
|
+
* console.error("Failed to get pincodes:", error);
|
|
3585
|
+
* return;
|
|
3586
|
+
* }
|
|
3587
|
+
*
|
|
3588
|
+
* console.log("Pincodes found:", data.pincodes?.length || 0);
|
|
3589
|
+
*
|
|
3590
|
+
* data.pincodes?.forEach(pincode => {
|
|
3591
|
+
* console.log(`Pincode: ${pincode.pincode} - ${pincode.city}, ${pincode.state_name}`);
|
|
3592
|
+
* });
|
|
3593
|
+
*
|
|
3594
|
+
* // Get pincodes for different country
|
|
3595
|
+
* const { data: usPincodes, error: usError } = await sdk.helpers.listCountryPincodes({
|
|
3596
|
+
* country_iso_code: "US"
|
|
3597
|
+
* });
|
|
3598
|
+
*
|
|
3599
|
+
* if (usError) {
|
|
3600
|
+
* console.error("Failed to get US pincodes:", usError);
|
|
3601
|
+
* return;
|
|
3602
|
+
* }
|
|
3603
|
+
*
|
|
3604
|
+
* console.log("US Pincodes:", usPincodes.pincodes?.map(p => p.pincode).join(", "));
|
|
3605
|
+
* ```
|
|
3606
|
+
*/
|
|
3607
|
+
async listCountryPincodes(pathParams, queryParams) {
|
|
3608
|
+
return this.executeRequest(() => this.client.GET("/common/countries/{country_iso_code}/pincodes", { params: {
|
|
3609
|
+
path: pathParams,
|
|
3610
|
+
query: queryParams
|
|
3611
|
+
} }));
|
|
3612
|
+
}
|
|
3613
|
+
};
|
|
3614
|
+
|
|
3615
|
+
//#endregion
|
|
3616
|
+
//#region src/lib/public/helper.ts
|
|
3617
|
+
/**
|
|
3618
|
+
* Client for interacting with helper endpoints
|
|
3619
|
+
*/
|
|
3620
|
+
var PublicHelpersClient = class extends BaseHelpersClient {};
|
|
3621
|
+
|
|
3622
|
+
//#endregion
|
|
3623
|
+
//#region src/lib/helper.ts
|
|
3624
|
+
/**
|
|
3625
|
+
* Client for interacting with helper endpoints
|
|
3626
|
+
*/
|
|
3627
|
+
var HelpersClient = class extends BaseHelpersClient {
|
|
3628
|
+
constructor(config) {
|
|
3629
|
+
super(config);
|
|
3630
|
+
attachSessionAuth(this, config.sessionManager);
|
|
3631
|
+
}
|
|
3632
|
+
};
|
|
3633
|
+
|
|
3634
|
+
//#endregion
|
|
3635
|
+
//#region src/lib/customer.ts
|
|
3636
|
+
/**
|
|
3637
|
+
* Client for interacting with customer endpoints
|
|
3638
|
+
*/
|
|
3639
|
+
var CustomerClient = class extends SessionStorefrontAPIClient {
|
|
3640
|
+
async listAddresses(pathParamsOrQuery, queryParams) {
|
|
3641
|
+
const hasPathParams = queryParams !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "customer_id" in pathParamsOrQuery;
|
|
3642
|
+
const pathParams = hasPathParams ? pathParamsOrQuery : {};
|
|
3643
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3644
|
+
const resolvedQueryParams = hasPathParams ? queryParams : pathParamsOrQuery;
|
|
3645
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/addresses", { params: {
|
|
3646
|
+
path: resolvedPathParams,
|
|
3647
|
+
query: resolvedQueryParams
|
|
3648
|
+
} }));
|
|
3649
|
+
}
|
|
3650
|
+
async createAddress(pathParamsOrBody, maybeBody) {
|
|
3651
|
+
const pathParams = maybeBody ? pathParamsOrBody : {};
|
|
3652
|
+
const body = maybeBody ?? pathParamsOrBody;
|
|
3653
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3654
|
+
return this.executeRequest(() => this.client.POST("/customers/{customer_id}/addresses", {
|
|
3655
|
+
params: { path: resolvedPathParams },
|
|
3656
|
+
body
|
|
3657
|
+
}));
|
|
3658
|
+
}
|
|
3659
|
+
async getAddress(pathParams) {
|
|
3660
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3661
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/addresses/{address_id}", { params: { path: resolvedPathParams } }));
|
|
3662
|
+
}
|
|
3663
|
+
async updateAddress(pathParams, body) {
|
|
3664
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3665
|
+
return this.executeRequest(() => this.client.PUT("/customers/{customer_id}/addresses/{address_id}", {
|
|
3666
|
+
params: { path: resolvedPathParams },
|
|
3667
|
+
body
|
|
3668
|
+
}));
|
|
3669
|
+
}
|
|
3670
|
+
async deleteAddress(pathParams) {
|
|
3671
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3672
|
+
return this.executeRequest(() => this.client.DELETE("/customers/{customer_id}/addresses/{address_id}", { params: { path: resolvedPathParams } }));
|
|
3673
|
+
}
|
|
3674
|
+
async getLoyaltyDetails(pathParams = {}) {
|
|
3675
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3676
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/loyalty", { params: { path: resolvedPathParams } }));
|
|
3677
|
+
}
|
|
3678
|
+
async listLoyaltyPointsActivity(pathParamsOrQuery, queryParams) {
|
|
3679
|
+
const hasPathParams = queryParams !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "customer_id" in pathParamsOrQuery;
|
|
3680
|
+
const pathParams = hasPathParams ? pathParamsOrQuery : {};
|
|
3681
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3682
|
+
const resolvedQueryParams = hasPathParams ? queryParams : pathParamsOrQuery;
|
|
3683
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/loyalty-points-activity", { params: {
|
|
3684
|
+
path: resolvedPathParams,
|
|
3685
|
+
query: resolvedQueryParams
|
|
3686
|
+
} }));
|
|
3687
|
+
}
|
|
3688
|
+
async listCustomerReviews(pathParams = {}) {
|
|
3689
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3690
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/reviews", { params: { path: resolvedPathParams } }));
|
|
3691
|
+
}
|
|
3692
|
+
async listSavedPaymentMethods(pathParams = {}, queryParams) {
|
|
3693
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3694
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/payment-methods", { params: {
|
|
3695
|
+
path: resolvedPathParams,
|
|
3696
|
+
query: queryParams
|
|
3697
|
+
} }));
|
|
3698
|
+
}
|
|
3699
|
+
async listCustomerCards(pathParams = {}) {
|
|
3700
|
+
const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
|
|
3701
|
+
return this.executeRequest(() => this.client.GET("/customers/{customer_id}/cards", { params: { path: resolvedPathParams } }));
|
|
3702
|
+
}
|
|
3703
|
+
};
|
|
3704
|
+
|
|
3705
|
+
//#endregion
|
|
3706
|
+
//#region src/lib/shared/store-config.ts
|
|
3707
|
+
/**
|
|
3708
|
+
* Client for interacting with store config endpoints
|
|
3709
|
+
*/
|
|
3710
|
+
var BaseStoreConfigClient = class extends StorefrontAPIClientBase {
|
|
3711
|
+
/**
|
|
3712
|
+
* Check store existence
|
|
3713
|
+
*
|
|
3714
|
+
* @description Checks whether a store with the configured store ID exists.
|
|
3715
|
+
* Returns `success: true` if the store exists, `false` otherwise.
|
|
3716
|
+
*
|
|
3717
|
+
* @returns Promise with store existence check result
|
|
3718
|
+
* @example
|
|
3719
|
+
* ```typescript
|
|
3720
|
+
* const { data, error } = await sdk.store.checkStore();
|
|
3721
|
+
*
|
|
3722
|
+
* if (error) {
|
|
3723
|
+
* console.error("Failed to check store:", error.message);
|
|
3724
|
+
* } else {
|
|
3725
|
+
* console.log("Store exists:", data.success);
|
|
3726
|
+
* }
|
|
3727
|
+
* ```
|
|
3728
|
+
*/
|
|
3729
|
+
async checkStore() {
|
|
3730
|
+
return this.executeRequest(() => this.client.GET("/store/check"));
|
|
3731
|
+
}
|
|
3732
|
+
/**
|
|
3733
|
+
* Get store config
|
|
3734
|
+
*
|
|
3735
|
+
* @returns Promise with store configuration data
|
|
3736
|
+
*
|
|
3737
|
+
* @example
|
|
3738
|
+
* ```typescript
|
|
3739
|
+
* const { data, error } = await sdk.store.getStoreConfig();
|
|
3740
|
+
*
|
|
3741
|
+
* if (error) {
|
|
3742
|
+
* console.error('Failed to get store config:', error.message);
|
|
3743
|
+
* return;
|
|
3744
|
+
* }
|
|
3745
|
+
*
|
|
3746
|
+
* // Access store configuration data
|
|
3747
|
+
* const storeConfig = data.store_config;
|
|
3748
|
+
* console.log('Store brand:', storeConfig.brand.name);
|
|
3749
|
+
* console.log('Currency:', storeConfig.currency.code);
|
|
3750
|
+
* console.log('KYC enabled:', storeConfig.is_kyc_enabled);
|
|
3751
|
+
* console.log('Customer groups enabled:', storeConfig.is_customer_group_enabled);
|
|
3752
|
+
* ```
|
|
3753
|
+
*/
|
|
3754
|
+
async getStoreConfig() {
|
|
3755
|
+
return this.executeRequest(() => this.client.GET("/store/config"));
|
|
3756
|
+
}
|
|
3757
|
+
};
|
|
3758
|
+
|
|
3759
|
+
//#endregion
|
|
3760
|
+
//#region src/lib/public/store-config.ts
|
|
3761
|
+
/**
|
|
3762
|
+
* Client for interacting with store config endpoints
|
|
3763
|
+
*/
|
|
3764
|
+
var PublicStoreConfigClient = class extends BaseStoreConfigClient {};
|
|
3765
|
+
|
|
3766
|
+
//#endregion
|
|
3767
|
+
//#region src/lib/store-config.ts
|
|
3768
|
+
/**
|
|
3769
|
+
* Client for interacting with store config endpoints
|
|
3770
|
+
*/
|
|
3771
|
+
var StoreConfigClient = class extends BaseStoreConfigClient {
|
|
3772
|
+
constructor(config) {
|
|
3773
|
+
super(config);
|
|
3774
|
+
attachSessionAuth(this, config.sessionManager);
|
|
3775
|
+
}
|
|
3776
|
+
};
|
|
3777
|
+
|
|
3778
|
+
//#endregion
|
|
3779
|
+
//#region src/lib/storage/token-storage.ts
|
|
3780
|
+
/**
|
|
3781
|
+
* Simple in-memory token storage implementation
|
|
3782
|
+
*/
|
|
3783
|
+
var MemoryTokenStorage = class {
|
|
3784
|
+
accessToken = null;
|
|
3785
|
+
refreshToken = null;
|
|
3786
|
+
async getAccessToken() {
|
|
3787
|
+
return this.accessToken;
|
|
3788
|
+
}
|
|
3789
|
+
async setAccessToken(token) {
|
|
3790
|
+
this.accessToken = token;
|
|
3791
|
+
}
|
|
3792
|
+
async getRefreshToken() {
|
|
3793
|
+
return this.refreshToken;
|
|
3794
|
+
}
|
|
3795
|
+
async setRefreshToken(token) {
|
|
3796
|
+
this.refreshToken = token;
|
|
3797
|
+
}
|
|
3798
|
+
async clearTokens() {
|
|
3799
|
+
this.accessToken = null;
|
|
3800
|
+
this.refreshToken = null;
|
|
3801
|
+
}
|
|
3802
|
+
};
|
|
3803
|
+
/**
|
|
3804
|
+
* Browser localStorage token storage implementation
|
|
3805
|
+
*/
|
|
3806
|
+
var BrowserTokenStorage = class {
|
|
3807
|
+
accessTokenKey;
|
|
3808
|
+
refreshTokenKey;
|
|
3809
|
+
constructor(prefix = "storefront_") {
|
|
3810
|
+
this.accessTokenKey = `${prefix}access_token`;
|
|
3811
|
+
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
3812
|
+
}
|
|
3813
|
+
async getAccessToken() {
|
|
3814
|
+
if (typeof localStorage === "undefined") return null;
|
|
3815
|
+
return localStorage.getItem(this.accessTokenKey);
|
|
3816
|
+
}
|
|
3817
|
+
async setAccessToken(token) {
|
|
3818
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(this.accessTokenKey, token);
|
|
3819
|
+
}
|
|
3820
|
+
async getRefreshToken() {
|
|
3821
|
+
if (typeof localStorage === "undefined") return null;
|
|
3822
|
+
return localStorage.getItem(this.refreshTokenKey);
|
|
3823
|
+
}
|
|
3824
|
+
async setRefreshToken(token) {
|
|
3825
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(this.refreshTokenKey, token);
|
|
3826
|
+
}
|
|
3827
|
+
async clearTokens() {
|
|
3828
|
+
if (typeof localStorage !== "undefined") {
|
|
3829
|
+
localStorage.removeItem(this.accessTokenKey);
|
|
3830
|
+
localStorage.removeItem(this.refreshTokenKey);
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
};
|
|
3834
|
+
/**
|
|
3835
|
+
* Cookie-based token storage implementation
|
|
3836
|
+
*/
|
|
3837
|
+
var CookieTokenStorage = class {
|
|
3838
|
+
accessTokenKey;
|
|
3839
|
+
refreshTokenKey;
|
|
3840
|
+
options;
|
|
3841
|
+
constructor(options = {}) {
|
|
3842
|
+
const prefix = options.prefix || "storefront_";
|
|
3843
|
+
this.accessTokenKey = `${prefix}access_token`;
|
|
3844
|
+
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
3845
|
+
this.options = {
|
|
3846
|
+
maxAge: options.maxAge || 10080 * 60,
|
|
3847
|
+
path: options.path || "/",
|
|
3848
|
+
domain: options.domain,
|
|
3849
|
+
secure: options.secure ?? (typeof window !== "undefined" && window.location?.protocol === "https:"),
|
|
3850
|
+
sameSite: options.sameSite || "Lax",
|
|
3851
|
+
httpOnly: false
|
|
3852
|
+
};
|
|
3853
|
+
}
|
|
3854
|
+
async getAccessToken() {
|
|
3855
|
+
return this.getCookie(this.accessTokenKey);
|
|
3856
|
+
}
|
|
3857
|
+
async setAccessToken(token) {
|
|
3858
|
+
this.setCookie(this.accessTokenKey, token);
|
|
3859
|
+
}
|
|
3860
|
+
async getRefreshToken() {
|
|
3861
|
+
return this.getCookie(this.refreshTokenKey);
|
|
3862
|
+
}
|
|
3863
|
+
async setRefreshToken(token) {
|
|
3864
|
+
this.setCookie(this.refreshTokenKey, token);
|
|
3865
|
+
}
|
|
3866
|
+
async clearTokens() {
|
|
3867
|
+
this.deleteCookie(this.accessTokenKey);
|
|
3868
|
+
this.deleteCookie(this.refreshTokenKey);
|
|
3869
|
+
}
|
|
3870
|
+
getCookie(name) {
|
|
3871
|
+
if (typeof document === "undefined") return null;
|
|
3872
|
+
const parts = `; ${document.cookie}`.split(`; ${name}=`);
|
|
3873
|
+
if (parts.length === 2) {
|
|
3874
|
+
const cookieValue = parts.pop()?.split(";").shift();
|
|
3875
|
+
return cookieValue ? decodeURIComponent(cookieValue) : null;
|
|
3876
|
+
}
|
|
3877
|
+
return null;
|
|
3878
|
+
}
|
|
3879
|
+
setCookie(name, value) {
|
|
3880
|
+
if (typeof document === "undefined") return;
|
|
3881
|
+
let cookieString = `${name}=${encodeURIComponent(value)}`;
|
|
3882
|
+
if (this.options.maxAge) cookieString += `; Max-Age=${this.options.maxAge}`;
|
|
3883
|
+
if (this.options.path) cookieString += `; Path=${this.options.path}`;
|
|
3884
|
+
if (this.options.domain) cookieString += `; Domain=${this.options.domain}`;
|
|
3885
|
+
if (this.options.secure) cookieString += `; Secure`;
|
|
3886
|
+
if (this.options.sameSite) cookieString += `; SameSite=${this.options.sameSite}`;
|
|
3887
|
+
document.cookie = cookieString;
|
|
3888
|
+
}
|
|
3889
|
+
deleteCookie(name) {
|
|
3890
|
+
if (typeof document === "undefined") return;
|
|
3891
|
+
let cookieString = `${name}=; Max-Age=0`;
|
|
3892
|
+
if (this.options.path) cookieString += `; Path=${this.options.path}`;
|
|
3893
|
+
if (this.options.domain) cookieString += `; Domain=${this.options.domain}`;
|
|
3894
|
+
document.cookie = cookieString;
|
|
3895
|
+
}
|
|
3896
|
+
};
|
|
3897
|
+
|
|
3898
|
+
//#endregion
|
|
3899
|
+
//#region src/lib/session/jwt-utils.ts
|
|
3900
|
+
/**
|
|
3901
|
+
* Decode a JWT token payload without signature verification.
|
|
3902
|
+
* This is a lightweight replacement for jose's decodeJwt.
|
|
3903
|
+
*
|
|
3904
|
+
* @param token - The JWT token to decode
|
|
3905
|
+
* @returns The decoded payload
|
|
3906
|
+
* @throws Error if the token is malformed
|
|
3907
|
+
*/
|
|
3908
|
+
function decodeJwt(token) {
|
|
3909
|
+
if (typeof token !== "string") throw new Error("Invalid token: must be a string");
|
|
3910
|
+
const parts = token.split(".");
|
|
3911
|
+
if (parts.length !== 3) throw new Error("Invalid token: must have 3 parts");
|
|
3912
|
+
const base64Url = parts[1];
|
|
3913
|
+
if (!base64Url) throw new Error("Invalid token: missing payload");
|
|
3914
|
+
let base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
3915
|
+
const padding = base64.length % 4;
|
|
3916
|
+
if (padding) base64 += "=".repeat(4 - padding);
|
|
3917
|
+
const binaryStr = atob(base64);
|
|
3918
|
+
const bytes = new Uint8Array(binaryStr.length);
|
|
3919
|
+
for (let i = 0; i < binaryStr.length; i++) bytes[i] = binaryStr.charCodeAt(i);
|
|
3920
|
+
const payload = JSON.parse(new TextDecoder().decode(bytes));
|
|
3921
|
+
if (typeof payload !== "object" || payload === null) throw new Error("Invalid token: payload must be an object");
|
|
3922
|
+
return payload;
|
|
3923
|
+
}
|
|
3924
|
+
/**
|
|
3925
|
+
* Decode and extract user information from a JWT token
|
|
3926
|
+
*
|
|
3927
|
+
* @param token - The JWT token to decode
|
|
3928
|
+
* @returns User information or null if token is invalid
|
|
3929
|
+
*/
|
|
3930
|
+
function extractUserInfoFromToken(token) {
|
|
3931
|
+
try {
|
|
3932
|
+
const payload = decodeJwt(token);
|
|
3933
|
+
return {
|
|
3934
|
+
id: payload.ulid,
|
|
3935
|
+
email: payload.email,
|
|
3936
|
+
phone: payload.phone,
|
|
3937
|
+
username: payload.username,
|
|
3938
|
+
firstName: payload.first_name,
|
|
3939
|
+
lastName: payload.last_name,
|
|
3940
|
+
storeId: payload.store_id,
|
|
3941
|
+
isLoggedIn: payload.is_logged_in,
|
|
3942
|
+
isAnonymous: payload.is_anonymous,
|
|
3943
|
+
customerId: payload.customer_id,
|
|
3944
|
+
customerGroupId: payload.customer_group_id,
|
|
3945
|
+
anonymousId: payload.anonymous_id,
|
|
3946
|
+
channel: payload.channel,
|
|
3947
|
+
tokenExpiry: /* @__PURE__ */ new Date(payload.exp * 1e3),
|
|
3948
|
+
tokenIssuedAt: /* @__PURE__ */ new Date(payload.iat * 1e3)
|
|
3949
|
+
};
|
|
3950
|
+
} catch (error) {
|
|
3951
|
+
console.warn("Failed to decode JWT token:", error);
|
|
3952
|
+
return null;
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
/**
|
|
3956
|
+
* Check if a JWT token is expired
|
|
3957
|
+
*
|
|
3958
|
+
* @param token - The JWT token to check
|
|
3959
|
+
* @param bufferSeconds - Buffer time in seconds (default: 30)
|
|
3960
|
+
* @returns True if token is expired or will expire within buffer time
|
|
3961
|
+
*/
|
|
3962
|
+
function isTokenExpired(token, bufferSeconds = 30) {
|
|
3963
|
+
try {
|
|
3964
|
+
const payload = decodeJwt(token);
|
|
3965
|
+
if (!payload.exp) return true;
|
|
3966
|
+
return Math.floor(Date.now() / 1e3) >= payload.exp - bufferSeconds;
|
|
3967
|
+
} catch (error) {
|
|
3968
|
+
console.warn("Failed to decode JWT token:", error);
|
|
3969
|
+
return true;
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
/**
|
|
3973
|
+
* Get the user ID from a JWT token
|
|
3974
|
+
*
|
|
3975
|
+
* @param token - The JWT token
|
|
3976
|
+
* @returns User ID (ulid) or null if token is invalid
|
|
3977
|
+
*/
|
|
3978
|
+
function getUserIdFromToken(token) {
|
|
3979
|
+
return extractUserInfoFromToken(token)?.id || null;
|
|
3980
|
+
}
|
|
3981
|
+
/**
|
|
3982
|
+
* Check if user is logged in based on JWT token
|
|
3983
|
+
*
|
|
3984
|
+
* @param token - The JWT token
|
|
3985
|
+
* @returns True if user is logged in, false otherwise
|
|
3986
|
+
*/
|
|
3987
|
+
function isUserLoggedIn(token) {
|
|
3988
|
+
return extractUserInfoFromToken(token)?.isLoggedIn || false;
|
|
3989
|
+
}
|
|
3990
|
+
/**
|
|
3991
|
+
* Check if user is anonymous based on JWT token
|
|
3992
|
+
*
|
|
3993
|
+
* @param token - The JWT token
|
|
3994
|
+
* @returns True if user is anonymous, false otherwise
|
|
3995
|
+
*/
|
|
3996
|
+
function isUserAnonymous(token) {
|
|
3997
|
+
return extractUserInfoFromToken(token)?.isAnonymous ?? true;
|
|
3998
|
+
}
|
|
3999
|
+
|
|
4000
|
+
//#endregion
|
|
4001
|
+
//#region src/types/auth-operation-metadata.ts
|
|
4002
|
+
const API_KEY_ONLY_OPERATIONS = [
|
|
4003
|
+
{
|
|
4004
|
+
method: "POST",
|
|
4005
|
+
path: "/auth/anonymous"
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
method: "GET",
|
|
4009
|
+
path: "/common/countries"
|
|
4010
|
+
},
|
|
4011
|
+
{
|
|
4012
|
+
method: "GET",
|
|
4013
|
+
path: "/common/countries/{country_iso_code}/pincodes"
|
|
4014
|
+
},
|
|
4015
|
+
{
|
|
4016
|
+
method: "GET",
|
|
4017
|
+
path: "/common/countries/{country_iso_code}/states"
|
|
4018
|
+
},
|
|
4019
|
+
{
|
|
4020
|
+
method: "GET",
|
|
4021
|
+
path: "/store/check"
|
|
4022
|
+
},
|
|
4023
|
+
{
|
|
4024
|
+
method: "GET",
|
|
4025
|
+
path: "/store/config"
|
|
4026
|
+
},
|
|
4027
|
+
{
|
|
4028
|
+
method: "GET",
|
|
4029
|
+
path: "/store/kyc-document"
|
|
4030
|
+
},
|
|
4031
|
+
{
|
|
4032
|
+
method: "GET",
|
|
4033
|
+
path: "/store/sellers/{id}"
|
|
4034
|
+
},
|
|
4035
|
+
{
|
|
4036
|
+
method: "GET",
|
|
4037
|
+
path: "/store/sellers/{id}/reviews"
|
|
4038
|
+
}
|
|
4039
|
+
];
|
|
4040
|
+
|
|
4041
|
+
//#endregion
|
|
4042
|
+
//#region src/lib/session/auth-utils.ts
|
|
4043
|
+
const TOKEN_RETURNING_OPERATIONS = [
|
|
4044
|
+
{
|
|
4045
|
+
method: "POST",
|
|
4046
|
+
path: "/auth/change-password"
|
|
4047
|
+
},
|
|
4048
|
+
{
|
|
4049
|
+
method: "POST",
|
|
4050
|
+
path: "/auth/login/password"
|
|
4051
|
+
},
|
|
4052
|
+
{
|
|
4053
|
+
method: "POST",
|
|
4054
|
+
path: "/auth/reset-password"
|
|
4055
|
+
},
|
|
4056
|
+
{
|
|
4057
|
+
method: "POST",
|
|
4058
|
+
path: "/auth/verify-otp"
|
|
4059
|
+
},
|
|
4060
|
+
{
|
|
4061
|
+
method: "POST",
|
|
4062
|
+
path: "/auth/refresh-token"
|
|
4063
|
+
},
|
|
4064
|
+
{
|
|
4065
|
+
method: "POST",
|
|
4066
|
+
path: "/auth/logout"
|
|
4067
|
+
}
|
|
4068
|
+
];
|
|
4069
|
+
const ANONYMOUS_AUTH_OPERATION = {
|
|
4070
|
+
method: "POST",
|
|
4071
|
+
path: "/auth/anonymous"
|
|
4072
|
+
};
|
|
4073
|
+
function normalizeMethod(method) {
|
|
4074
|
+
return method.toUpperCase();
|
|
4075
|
+
}
|
|
4076
|
+
function normalizePathname(pathname) {
|
|
4077
|
+
let normalizedPathname = pathname;
|
|
4078
|
+
const storefrontMarkerIndex = normalizedPathname.indexOf("/storefront");
|
|
4079
|
+
if (storefrontMarkerIndex !== -1) normalizedPathname = normalizedPathname.slice(storefrontMarkerIndex + 11) || "/";
|
|
4080
|
+
if (normalizedPathname.length > 1 && normalizedPathname.endsWith("/")) return normalizedPathname.slice(0, -1);
|
|
4081
|
+
return normalizedPathname;
|
|
4082
|
+
}
|
|
4083
|
+
function matchesPathTemplate(pathTemplate, pathname) {
|
|
4084
|
+
const normalizedTemplate = normalizePathname(pathTemplate);
|
|
4085
|
+
const normalizedPathname = normalizePathname(pathname);
|
|
4086
|
+
const templateSegments = normalizedTemplate.split("/").filter(Boolean);
|
|
4087
|
+
const pathSegments = normalizedPathname.split("/").filter(Boolean);
|
|
4088
|
+
if (templateSegments.length !== pathSegments.length) return false;
|
|
4089
|
+
return templateSegments.every((templateSegment, index) => {
|
|
4090
|
+
if (templateSegment.startsWith("{") && templateSegment.endsWith("}")) return true;
|
|
4091
|
+
return templateSegment === pathSegments[index];
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
function matchesOperation(method, pathname, operation) {
|
|
4095
|
+
return normalizeMethod(method) === operation.method && matchesPathTemplate(operation.path, pathname);
|
|
4096
|
+
}
|
|
4097
|
+
function matchesOperationList(method, pathname, operations) {
|
|
4098
|
+
return operations.some((operation) => matchesOperation(method, pathname, operation));
|
|
4099
|
+
}
|
|
4100
|
+
/**
|
|
4101
|
+
* Check if a method+path pair is the anonymous auth operation.
|
|
4102
|
+
*/
|
|
4103
|
+
function isAnonymousAuthOperation(method, pathname) {
|
|
4104
|
+
return matchesOperation(method, pathname, ANONYMOUS_AUTH_OPERATION);
|
|
4105
|
+
}
|
|
4106
|
+
/**
|
|
4107
|
+
* Check if a method+path pair requires API key only authentication.
|
|
4108
|
+
*/
|
|
4109
|
+
function isApiKeyOnlyOperation(method, pathname) {
|
|
4110
|
+
return matchesOperationList(method, pathname, API_KEY_ONLY_OPERATIONS);
|
|
4111
|
+
}
|
|
4112
|
+
/**
|
|
4113
|
+
* Check if a method+path pair returns tokens in a successful response.
|
|
4114
|
+
*/
|
|
4115
|
+
function isTokenReturningOperation(method, pathname) {
|
|
4116
|
+
return matchesOperationList(method, pathname, TOKEN_RETURNING_OPERATIONS);
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4119
|
+
//#endregion
|
|
4120
|
+
//#region src/lib/session/manager.ts
|
|
4121
|
+
/**
|
|
4122
|
+
* Internal per-SDK session controller.
|
|
4123
|
+
*
|
|
4124
|
+
* A single instance is shared by all API clients created from the same
|
|
4125
|
+
* `SessionStorefrontSDK`. This keeps refresh locks, token assessment, and session
|
|
4126
|
+
* bootstrap logic coordinated in one place while preserving optional manual
|
|
4127
|
+
* token management when `tokenStorage` is not provided.
|
|
4128
|
+
*/
|
|
4129
|
+
var StorefrontSessionManager = class {
|
|
4130
|
+
tokenStorage;
|
|
4131
|
+
onTokensUpdated;
|
|
4132
|
+
onTokensCleared;
|
|
4133
|
+
baseUrl;
|
|
4134
|
+
refreshTokenFn;
|
|
4135
|
+
apiKey;
|
|
4136
|
+
accessToken;
|
|
4137
|
+
refreshToken;
|
|
4138
|
+
initializationPromise = null;
|
|
4139
|
+
refreshPromise = null;
|
|
4140
|
+
bootstrapPromise = null;
|
|
4141
|
+
hasAssessedTokens = false;
|
|
4142
|
+
constructor(options) {
|
|
4143
|
+
this.tokenStorage = options.tokenStorage;
|
|
4144
|
+
this.baseUrl = options.baseUrl;
|
|
4145
|
+
this.apiKey = options.apiKey;
|
|
4146
|
+
this.onTokensUpdated = options.onTokensUpdated;
|
|
4147
|
+
this.onTokensCleared = options.onTokensCleared;
|
|
4148
|
+
this.accessToken = options.accessToken ?? null;
|
|
4149
|
+
this.refreshToken = options.refreshToken ?? null;
|
|
4150
|
+
this.refreshTokenFn = options.refreshTokenFn;
|
|
4151
|
+
if (this.tokenStorage && this.accessToken) this.initializationPromise = this.initializeManagedTokens(this.accessToken, this.refreshToken);
|
|
4152
|
+
}
|
|
4153
|
+
/**
|
|
4154
|
+
* Update the API key used by session bootstrap and refresh flows.
|
|
4155
|
+
*/
|
|
4156
|
+
setApiKey(apiKey) {
|
|
4157
|
+
this.apiKey = apiKey;
|
|
4007
4158
|
}
|
|
4008
4159
|
/**
|
|
4009
|
-
*
|
|
4010
|
-
*
|
|
4011
|
-
* @param pathParams - Path parameters
|
|
4012
|
-
* @returns Promise with states
|
|
4013
|
-
*
|
|
4014
|
-
* @example
|
|
4015
|
-
* ```typescript
|
|
4016
|
-
* const { data, error } = await sdk.helpers.listCountryStates({
|
|
4017
|
-
* country_iso_code: "IN"
|
|
4018
|
-
* });
|
|
4019
|
-
*
|
|
4020
|
-
* if (error) {
|
|
4021
|
-
* console.error("Failed to get states:", error);
|
|
4022
|
-
* return;
|
|
4023
|
-
* }
|
|
4024
|
-
*
|
|
4025
|
-
* console.log("States found:", data.states?.length || 0);
|
|
4026
|
-
*
|
|
4027
|
-
* data.states?.forEach(state => {
|
|
4028
|
-
* console.log(`State: ${state.name} (${state.iso_code})`);
|
|
4029
|
-
* });
|
|
4030
|
-
*
|
|
4031
|
-
* // Get states for different country
|
|
4032
|
-
* const { data: usStates, error: usError } = await sdk.helpers.listCountryStates({
|
|
4033
|
-
* country_iso_code: "US"
|
|
4034
|
-
* });
|
|
4035
|
-
*
|
|
4036
|
-
* if (usError) {
|
|
4037
|
-
* console.error("Failed to get US states:", usError);
|
|
4038
|
-
* return;
|
|
4039
|
-
* }
|
|
4040
|
-
*
|
|
4041
|
-
* console.log("US States:", usStates.states?.map(s => s.name).join(", "));
|
|
4042
|
-
* ```
|
|
4160
|
+
* Remove the API key used by session bootstrap and refresh flows.
|
|
4043
4161
|
*/
|
|
4044
|
-
|
|
4045
|
-
|
|
4162
|
+
clearApiKey() {
|
|
4163
|
+
this.apiKey = void 0;
|
|
4046
4164
|
}
|
|
4047
4165
|
/**
|
|
4048
|
-
*
|
|
4049
|
-
*
|
|
4050
|
-
* @param pathParams - Path parameters
|
|
4051
|
-
* @returns Promise with pincodes
|
|
4052
|
-
*
|
|
4053
|
-
* @example
|
|
4054
|
-
* ```typescript
|
|
4055
|
-
* const { data, error } = await sdk.helpers.listCountryPincodes({
|
|
4056
|
-
* country_iso_code: "IN"
|
|
4057
|
-
* });
|
|
4058
|
-
*
|
|
4059
|
-
* if (error) {
|
|
4060
|
-
* console.error("Failed to get pincodes:", error);
|
|
4061
|
-
* return;
|
|
4062
|
-
* }
|
|
4063
|
-
*
|
|
4064
|
-
* console.log("Pincodes found:", data.pincodes?.length || 0);
|
|
4065
|
-
*
|
|
4066
|
-
* data.pincodes?.forEach(pincode => {
|
|
4067
|
-
* console.log(`Pincode: ${pincode.pincode} - ${pincode.city}, ${pincode.state_name}`);
|
|
4068
|
-
* });
|
|
4069
|
-
*
|
|
4070
|
-
* // Get pincodes for different country
|
|
4071
|
-
* const { data: usPincodes, error: usError } = await sdk.helpers.listCountryPincodes({
|
|
4072
|
-
* country_iso_code: "US"
|
|
4073
|
-
* });
|
|
4074
|
-
*
|
|
4075
|
-
* if (usError) {
|
|
4076
|
-
* console.error("Failed to get US pincodes:", usError);
|
|
4077
|
-
* return;
|
|
4078
|
-
* }
|
|
4166
|
+
* Create the auth middleware used by each API client.
|
|
4079
4167
|
*
|
|
4080
|
-
*
|
|
4081
|
-
*
|
|
4168
|
+
* The returned middleware shares the same session state and refresh locking
|
|
4169
|
+
* across all clients attached to a single `SessionStorefrontSDK` instance.
|
|
4082
4170
|
*/
|
|
4083
|
-
|
|
4084
|
-
return
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
}
|
|
4171
|
+
createAuthMiddleware() {
|
|
4172
|
+
return {
|
|
4173
|
+
onRequest: async ({ request }) => this.handleRequest(request),
|
|
4174
|
+
onResponse: async ({ request, response }) => this.handleResponse(request, response)
|
|
4175
|
+
};
|
|
4088
4176
|
}
|
|
4089
|
-
};
|
|
4090
|
-
|
|
4091
|
-
//#endregion
|
|
4092
|
-
//#region src/lib/customer.ts
|
|
4093
|
-
/**
|
|
4094
|
-
* Client for interacting with customer endpoints
|
|
4095
|
-
*/
|
|
4096
|
-
var CustomerClient = class extends StorefrontAPIClient {
|
|
4097
4177
|
/**
|
|
4098
|
-
*
|
|
4099
|
-
*
|
|
4100
|
-
* @param pathParams - Path parameters
|
|
4101
|
-
* @returns Promise with addresses
|
|
4102
|
-
*
|
|
4103
|
-
* @example
|
|
4104
|
-
* ```typescript
|
|
4105
|
-
* const { data, error } = await sdk.customer.listAddresses({
|
|
4106
|
-
* user_id: "user_456"
|
|
4107
|
-
* });
|
|
4108
|
-
*
|
|
4109
|
-
* if (error) {
|
|
4110
|
-
* console.error("Failed to list addresses:", error);
|
|
4111
|
-
* return;
|
|
4112
|
-
* }
|
|
4113
|
-
*
|
|
4114
|
-
* console.log("Addresses:", data.addresses);
|
|
4115
|
-
* console.log("Pagination:", data.pagination);
|
|
4178
|
+
* Read the current authorization header without creating a new session.
|
|
4116
4179
|
*
|
|
4117
|
-
*
|
|
4118
|
-
* const { data: page2, error: page2Error } = await sdk.customer.listAddresses({
|
|
4119
|
-
* user_id: "user_456",
|
|
4120
|
-
* page: 2,
|
|
4121
|
-
* limit: 10
|
|
4122
|
-
* });
|
|
4123
|
-
* ```
|
|
4180
|
+
* @returns A `Bearer` header value, or an empty string when no token exists
|
|
4124
4181
|
*/
|
|
4125
|
-
async
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
query: queryParams
|
|
4129
|
-
} }));
|
|
4182
|
+
async getAuthorizationHeader() {
|
|
4183
|
+
const token = await this.peekAccessToken();
|
|
4184
|
+
return token ? `Bearer ${token}` : "";
|
|
4130
4185
|
}
|
|
4131
4186
|
/**
|
|
4132
|
-
*
|
|
4133
|
-
*
|
|
4134
|
-
* @param pathParams - Path parameters
|
|
4135
|
-
* @param body - Address creation body
|
|
4136
|
-
* @returns Promise with address details
|
|
4137
|
-
*
|
|
4138
|
-
* @example
|
|
4139
|
-
* ```typescript
|
|
4140
|
-
* const { data, error } = await sdk.customer.createAddress(
|
|
4141
|
-
* { user_id: "user_456" },
|
|
4142
|
-
* {
|
|
4143
|
-
* address_line1: "123 Main Street",
|
|
4144
|
-
* address_line2: "Apt 4B",
|
|
4145
|
-
* city: "New York",
|
|
4146
|
-
* state: "NY",
|
|
4147
|
-
* country: "US",
|
|
4148
|
-
* pincode: "10001",
|
|
4149
|
-
* is_default_billing: true,
|
|
4150
|
-
* is_default_shipping: false
|
|
4151
|
-
* }
|
|
4152
|
-
* );
|
|
4153
|
-
*
|
|
4154
|
-
* if (error) {
|
|
4155
|
-
* console.error("Failed to create address:", error);
|
|
4156
|
-
* return;
|
|
4157
|
-
* }
|
|
4187
|
+
* Persist new session tokens.
|
|
4158
4188
|
*
|
|
4159
|
-
*
|
|
4160
|
-
*
|
|
4189
|
+
* In managed mode, tokens are written to the configured token storage. In
|
|
4190
|
+
* manual mode, they are stored in memory for header injection and session
|
|
4191
|
+
* inspection.
|
|
4161
4192
|
*/
|
|
4162
|
-
async
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4193
|
+
async setTokens(accessToken, refreshToken) {
|
|
4194
|
+
const previousTokens = await this.getCurrentTokenState();
|
|
4195
|
+
if (this.tokenStorage) {
|
|
4196
|
+
await this.awaitInitialization();
|
|
4197
|
+
await this.storeManagedTokens(accessToken, refreshToken ?? null);
|
|
4198
|
+
} else {
|
|
4199
|
+
this.accessToken = accessToken;
|
|
4200
|
+
if (refreshToken) {
|
|
4201
|
+
this.refreshToken = refreshToken;
|
|
4202
|
+
console.warn("Refresh token provided but automatic refresh is disabled because tokenStorage is not configured.");
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
const nextTokens = await this.getCurrentTokenState();
|
|
4206
|
+
this.notifyTokensUpdatedIfChanged(previousTokens, nextTokens);
|
|
4167
4207
|
}
|
|
4168
4208
|
/**
|
|
4169
|
-
*
|
|
4170
|
-
*
|
|
4171
|
-
* @param pathParams - Path parameters
|
|
4172
|
-
* @returns Promise with address details
|
|
4173
|
-
*
|
|
4174
|
-
* @example
|
|
4175
|
-
* ```typescript
|
|
4176
|
-
* const { data, error } = await sdk.customer.getAddress({
|
|
4177
|
-
* user_id: "user_456",
|
|
4178
|
-
* address_id: "addr_789"
|
|
4179
|
-
* });
|
|
4180
|
-
*
|
|
4181
|
-
* if (error) {
|
|
4182
|
-
* console.error("Failed to get address:", error);
|
|
4183
|
-
* return;
|
|
4184
|
-
* }
|
|
4185
|
-
*
|
|
4186
|
-
* console.log("Address details:", data.address);
|
|
4187
|
-
* ```
|
|
4209
|
+
* Clear all session tokens managed by this controller.
|
|
4188
4210
|
*/
|
|
4189
|
-
async
|
|
4190
|
-
|
|
4211
|
+
async clearTokens() {
|
|
4212
|
+
if (this.tokenStorage) {
|
|
4213
|
+
await this.awaitInitialization();
|
|
4214
|
+
await this.tokenStorage.clearTokens();
|
|
4215
|
+
} else {
|
|
4216
|
+
this.accessToken = null;
|
|
4217
|
+
this.refreshToken = null;
|
|
4218
|
+
}
|
|
4219
|
+
this.onTokensCleared?.();
|
|
4220
|
+
}
|
|
4221
|
+
/**
|
|
4222
|
+
* Clear all session tokens through the public session interface.
|
|
4223
|
+
*/
|
|
4224
|
+
async clear() {
|
|
4225
|
+
await this.clearTokens();
|
|
4226
|
+
}
|
|
4227
|
+
async peekAccessToken() {
|
|
4228
|
+
await this.awaitInitialization();
|
|
4229
|
+
if (this.tokenStorage) return this.tokenStorage.getAccessToken();
|
|
4230
|
+
return this.accessToken;
|
|
4231
|
+
}
|
|
4232
|
+
async peekRefreshToken() {
|
|
4233
|
+
await this.awaitInitialization();
|
|
4234
|
+
if (this.tokenStorage) return this.tokenStorage.getRefreshToken();
|
|
4235
|
+
return this.refreshToken;
|
|
4236
|
+
}
|
|
4237
|
+
async peekUserInfo() {
|
|
4238
|
+
const token = await this.peekAccessToken();
|
|
4239
|
+
if (!token) return null;
|
|
4240
|
+
return extractUserInfoFromToken(token);
|
|
4241
|
+
}
|
|
4242
|
+
async peekUserId() {
|
|
4243
|
+
const token = await this.peekAccessToken();
|
|
4244
|
+
if (!token) return null;
|
|
4245
|
+
return getUserIdFromToken(token);
|
|
4246
|
+
}
|
|
4247
|
+
async peekCustomerId() {
|
|
4248
|
+
return (await this.peekUserInfo())?.customerId ?? null;
|
|
4249
|
+
}
|
|
4250
|
+
async peekCustomerGroupId() {
|
|
4251
|
+
return (await this.peekUserInfo())?.customerGroupId ?? null;
|
|
4252
|
+
}
|
|
4253
|
+
async ensureAccessToken() {
|
|
4254
|
+
const token = await this.getOrCreateAccessToken();
|
|
4255
|
+
if (!token) throw new Error("No session available. Configure tokenStorage + apiKey for automatic session management, or call setTokens() to set tokens manually.");
|
|
4256
|
+
return token;
|
|
4257
|
+
}
|
|
4258
|
+
async ensureUserInfo() {
|
|
4259
|
+
const userInfo = extractUserInfoFromToken(await this.ensureAccessToken());
|
|
4260
|
+
if (!userInfo) throw new Error("Failed to extract user information from access token.");
|
|
4261
|
+
return userInfo;
|
|
4262
|
+
}
|
|
4263
|
+
async ensureUserId() {
|
|
4264
|
+
const userId = getUserIdFromToken(await this.ensureAccessToken());
|
|
4265
|
+
if (!userId) throw new Error("Failed to extract user ID from access token.");
|
|
4266
|
+
return userId;
|
|
4267
|
+
}
|
|
4268
|
+
async ensureCustomerId() {
|
|
4269
|
+
const userInfo = await this.ensureUserInfo();
|
|
4270
|
+
if (!userInfo.customerId) throw new Error("No customer_id available. User must be logged in (not anonymous) for this operation. Pass customer_id explicitly or log in first.");
|
|
4271
|
+
return userInfo.customerId;
|
|
4272
|
+
}
|
|
4273
|
+
async handleRequest(request) {
|
|
4274
|
+
const method = request.method;
|
|
4275
|
+
const pathname = getPathnameFromUrl(request.url);
|
|
4276
|
+
if (this.tokenStorage) await this.assessTokenStateOnce();
|
|
4277
|
+
if (isAnonymousAuthOperation(method, pathname)) return this.prepareAnonymousAuthRequest(request);
|
|
4278
|
+
if (isApiKeyOnlyOperation(method, pathname)) {
|
|
4279
|
+
this.applyApiKeyHeader(request);
|
|
4280
|
+
return request;
|
|
4281
|
+
}
|
|
4282
|
+
const accessToken = await this.getOrCreateAccessToken();
|
|
4283
|
+
if (accessToken) request.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
4284
|
+
return request;
|
|
4285
|
+
}
|
|
4286
|
+
async handleResponse(request, response) {
|
|
4287
|
+
if (!this.tokenStorage) return response;
|
|
4288
|
+
const method = request.method;
|
|
4289
|
+
const pathname = getPathnameFromUrl(request.url);
|
|
4290
|
+
if (response.ok) {
|
|
4291
|
+
await this.captureTokensFromResponse(method, pathname, response);
|
|
4292
|
+
return response;
|
|
4293
|
+
}
|
|
4294
|
+
if (response.status === 401 && !isAnonymousAuthOperation(method, pathname) && !isApiKeyOnlyOperation(method, pathname)) {
|
|
4295
|
+
const currentToken = await this.peekAccessToken();
|
|
4296
|
+
if (currentToken && isTokenExpired(currentToken, 0)) try {
|
|
4297
|
+
await this.refreshTokens();
|
|
4298
|
+
const refreshedToken = await this.peekAccessToken();
|
|
4299
|
+
if (refreshedToken) {
|
|
4300
|
+
const retryRequest = request.clone();
|
|
4301
|
+
retryRequest.headers.set("Authorization", `Bearer ${refreshedToken}`);
|
|
4302
|
+
return fetch(retryRequest);
|
|
4303
|
+
}
|
|
4304
|
+
} catch (error) {
|
|
4305
|
+
console.warn("Token refresh failed on 401 response:", error);
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
return response;
|
|
4309
|
+
}
|
|
4310
|
+
async prepareAnonymousAuthRequest(request) {
|
|
4311
|
+
this.applyApiKeyHeader(request);
|
|
4312
|
+
const existingToken = await this.peekAccessToken();
|
|
4313
|
+
if (this.tokenStorage && existingToken && !isTokenExpired(existingToken) && isUserLoggedIn(existingToken)) return new Response(JSON.stringify({
|
|
4314
|
+
message: "Cannot create anonymous session while authenticated",
|
|
4315
|
+
success: false,
|
|
4316
|
+
code: "USER_ALREADY_AUTHENTICATED"
|
|
4317
|
+
}), {
|
|
4318
|
+
status: 400,
|
|
4319
|
+
headers: { "Content-Type": "application/json" }
|
|
4320
|
+
});
|
|
4321
|
+
if (existingToken) request.headers.set("Authorization", `Bearer ${existingToken}`);
|
|
4322
|
+
return request;
|
|
4323
|
+
}
|
|
4324
|
+
applyApiKeyHeader(request) {
|
|
4325
|
+
if (this.apiKey) request.headers.set("X-Api-Key", this.apiKey);
|
|
4326
|
+
}
|
|
4327
|
+
/**
|
|
4328
|
+
* Snapshot the effective token pair from storage (managed mode) or
|
|
4329
|
+
* in-memory fields (manual mode). Used before and after `setTokens()` to
|
|
4330
|
+
* detect whether the tokens actually changed.
|
|
4331
|
+
*/
|
|
4332
|
+
async getCurrentTokenState() {
|
|
4333
|
+
await this.awaitInitialization();
|
|
4334
|
+
if (this.tokenStorage) return {
|
|
4335
|
+
accessToken: await this.tokenStorage.getAccessToken(),
|
|
4336
|
+
refreshToken: await this.tokenStorage.getRefreshToken()
|
|
4337
|
+
};
|
|
4338
|
+
return {
|
|
4339
|
+
accessToken: this.accessToken,
|
|
4340
|
+
refreshToken: this.refreshToken
|
|
4341
|
+
};
|
|
4342
|
+
}
|
|
4343
|
+
/**
|
|
4344
|
+
* Fire `onTokensUpdated` only when the effective token pair differs from
|
|
4345
|
+
* the previous snapshot. This prevents duplicate notifications when
|
|
4346
|
+
* `setTokens()` is called with the same values already in storage.
|
|
4347
|
+
*/
|
|
4348
|
+
notifyTokensUpdatedIfChanged(previousTokens, nextTokens) {
|
|
4349
|
+
if (!this.onTokensUpdated || !nextTokens.accessToken) return;
|
|
4350
|
+
if (previousTokens.accessToken === nextTokens.accessToken && previousTokens.refreshToken === nextTokens.refreshToken) return;
|
|
4351
|
+
this.onTokensUpdated(nextTokens.accessToken, nextTokens.refreshToken ?? "");
|
|
4352
|
+
}
|
|
4353
|
+
/**
|
|
4354
|
+
* Internal token acquisition — returns null on failure instead of throwing.
|
|
4355
|
+
* Used by middleware so requests degrade gracefully.
|
|
4356
|
+
*/
|
|
4357
|
+
async getOrCreateAccessToken() {
|
|
4358
|
+
if (!this.tokenStorage) return this.peekAccessToken();
|
|
4359
|
+
await this.awaitInitialization();
|
|
4360
|
+
await this.assessTokenStateOnce();
|
|
4361
|
+
let accessToken = await this.tokenStorage.getAccessToken();
|
|
4362
|
+
if (!accessToken) accessToken = await this.bootstrapAnonymousSession();
|
|
4363
|
+
if (accessToken && isTokenExpired(accessToken)) try {
|
|
4364
|
+
await this.refreshTokens();
|
|
4365
|
+
accessToken = await this.tokenStorage.getAccessToken();
|
|
4366
|
+
} catch {
|
|
4367
|
+
accessToken = await this.tokenStorage.getAccessToken();
|
|
4368
|
+
}
|
|
4369
|
+
return accessToken;
|
|
4370
|
+
}
|
|
4371
|
+
async initializeManagedTokens(accessToken, refreshToken) {
|
|
4372
|
+
try {
|
|
4373
|
+
await this.storeManagedTokens(accessToken, refreshToken);
|
|
4374
|
+
} catch (error) {
|
|
4375
|
+
console.warn("Failed to initialize tokens in storage:", error);
|
|
4376
|
+
} finally {
|
|
4377
|
+
this.accessToken = null;
|
|
4378
|
+
this.refreshToken = null;
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
async awaitInitialization() {
|
|
4382
|
+
if (this.initializationPromise) {
|
|
4383
|
+
await this.initializationPromise;
|
|
4384
|
+
this.initializationPromise = null;
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
async assessTokenStateOnce() {
|
|
4388
|
+
if (!this.tokenStorage || this.hasAssessedTokens) return;
|
|
4389
|
+
this.hasAssessedTokens = true;
|
|
4390
|
+
try {
|
|
4391
|
+
const accessToken = await this.tokenStorage.getAccessToken();
|
|
4392
|
+
const refreshToken = await this.tokenStorage.getRefreshToken();
|
|
4393
|
+
if (!accessToken && refreshToken) {
|
|
4394
|
+
await this.tokenStorage.clearTokens();
|
|
4395
|
+
console.info("Cleaned up orphaned refresh token");
|
|
4396
|
+
}
|
|
4397
|
+
} catch (error) {
|
|
4398
|
+
console.warn("Token state assessment failed:", error);
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
async bootstrapAnonymousSession() {
|
|
4402
|
+
if (!this.tokenStorage) return null;
|
|
4403
|
+
if (this.bootstrapPromise) return this.bootstrapPromise;
|
|
4404
|
+
this.bootstrapPromise = (async () => {
|
|
4405
|
+
try {
|
|
4406
|
+
const response = await fetch(`${this.baseUrl}/auth/anonymous`, {
|
|
4407
|
+
method: "POST",
|
|
4408
|
+
headers: {
|
|
4409
|
+
"Content-Type": "application/json",
|
|
4410
|
+
...this.apiKey && { "X-Api-Key": this.apiKey }
|
|
4411
|
+
}
|
|
4412
|
+
});
|
|
4413
|
+
if (!response.ok) return null;
|
|
4414
|
+
const tokens = (await response.json()).content;
|
|
4415
|
+
if (tokens?.access_token && tokens?.refresh_token) {
|
|
4416
|
+
await this.storeManagedTokens(tokens.access_token, tokens.refresh_token);
|
|
4417
|
+
this.onTokensUpdated?.(tokens.access_token, tokens.refresh_token);
|
|
4418
|
+
console.info("Automatically created anonymous session for first API request");
|
|
4419
|
+
return tokens.access_token;
|
|
4420
|
+
}
|
|
4421
|
+
return null;
|
|
4422
|
+
} catch (error) {
|
|
4423
|
+
console.warn("Failed to automatically create anonymous tokens:", error);
|
|
4424
|
+
return null;
|
|
4425
|
+
} finally {
|
|
4426
|
+
this.bootstrapPromise = null;
|
|
4427
|
+
}
|
|
4428
|
+
})();
|
|
4429
|
+
return this.bootstrapPromise;
|
|
4430
|
+
}
|
|
4431
|
+
async refreshTokens() {
|
|
4432
|
+
if (!this.tokenStorage) return;
|
|
4433
|
+
const tokenStorage = this.tokenStorage;
|
|
4434
|
+
if (this.refreshPromise) return this.refreshPromise;
|
|
4435
|
+
this.refreshPromise = (async () => {
|
|
4436
|
+
try {
|
|
4437
|
+
const refreshToken = await tokenStorage.getRefreshToken();
|
|
4438
|
+
let newTokens;
|
|
4439
|
+
if (refreshToken && !isTokenExpired(refreshToken)) if (this.refreshTokenFn) newTokens = await this.refreshTokenFn(refreshToken);
|
|
4440
|
+
else {
|
|
4441
|
+
const response = await fetch(`${this.baseUrl}/auth/refresh-token`, {
|
|
4442
|
+
method: "POST",
|
|
4443
|
+
headers: { "Content-Type": "application/json" },
|
|
4444
|
+
body: JSON.stringify({ refresh_token: refreshToken })
|
|
4445
|
+
});
|
|
4446
|
+
if (!response.ok) throw new Error(`Token refresh failed: ${response.status}`);
|
|
4447
|
+
newTokens = (await response.json()).content;
|
|
4448
|
+
}
|
|
4449
|
+
else {
|
|
4450
|
+
const currentAccessToken = await tokenStorage.getAccessToken();
|
|
4451
|
+
if (!currentAccessToken) throw new Error("No tokens available for refresh");
|
|
4452
|
+
const reason = refreshToken ? "refresh token expired" : "no refresh token available";
|
|
4453
|
+
const response = await fetch(`${this.baseUrl}/auth/anonymous`, {
|
|
4454
|
+
method: "POST",
|
|
4455
|
+
headers: {
|
|
4456
|
+
"Content-Type": "application/json",
|
|
4457
|
+
...this.apiKey && { "X-Api-Key": this.apiKey },
|
|
4458
|
+
Authorization: `Bearer ${currentAccessToken}`
|
|
4459
|
+
}
|
|
4460
|
+
});
|
|
4461
|
+
if (!response.ok) throw new Error(`Anonymous token fallback failed: ${response.status}`);
|
|
4462
|
+
newTokens = (await response.json()).content;
|
|
4463
|
+
console.info(`Token refreshed via anonymous fallback (${reason}) - user may need to re-authenticate for privileged operations`);
|
|
4464
|
+
}
|
|
4465
|
+
await this.storeManagedTokens(newTokens.access_token, newTokens.refresh_token);
|
|
4466
|
+
this.onTokensUpdated?.(newTokens.access_token, newTokens.refresh_token);
|
|
4467
|
+
} catch (error) {
|
|
4468
|
+
console.error("Token refresh failed:", error);
|
|
4469
|
+
await this.clearTokens();
|
|
4470
|
+
throw error;
|
|
4471
|
+
} finally {
|
|
4472
|
+
this.refreshPromise = null;
|
|
4473
|
+
}
|
|
4474
|
+
})();
|
|
4475
|
+
return this.refreshPromise;
|
|
4476
|
+
}
|
|
4477
|
+
async captureTokensFromResponse(method, pathname, response) {
|
|
4478
|
+
if (!this.tokenStorage || !(isTokenReturningOperation(method, pathname) || isAnonymousAuthOperation(method, pathname))) return;
|
|
4479
|
+
try {
|
|
4480
|
+
const content = (await response.clone().json()).content;
|
|
4481
|
+
if (content?.access_token && content?.refresh_token) {
|
|
4482
|
+
await this.storeManagedTokens(content.access_token, content.refresh_token);
|
|
4483
|
+
this.onTokensUpdated?.(content.access_token, content.refresh_token);
|
|
4484
|
+
}
|
|
4485
|
+
} catch (error) {
|
|
4486
|
+
console.warn("Failed to extract tokens from response:", error);
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
4489
|
+
async storeManagedTokens(accessToken, refreshToken) {
|
|
4490
|
+
if (!this.tokenStorage) return;
|
|
4491
|
+
await this.tokenStorage.setAccessToken(accessToken);
|
|
4492
|
+
if (refreshToken) await this.tokenStorage.setRefreshToken(refreshToken);
|
|
4493
|
+
}
|
|
4494
|
+
};
|
|
4495
|
+
|
|
4496
|
+
//#endregion
|
|
4497
|
+
//#region src/lib/public/client.ts
|
|
4498
|
+
/**
|
|
4499
|
+
* Storefront API client that always authenticates with `X-Api-Key`.
|
|
4500
|
+
*
|
|
4501
|
+
* This client is used by the public storefront surface where no session or
|
|
4502
|
+
* token lifecycle should be involved.
|
|
4503
|
+
*/
|
|
4504
|
+
var PublicStorefrontAPIClient = class extends StorefrontAPIClientBase {
|
|
4505
|
+
constructor(config) {
|
|
4506
|
+
super(config);
|
|
4507
|
+
this.setupPublicAuth();
|
|
4191
4508
|
}
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
* @returns Promise with address details
|
|
4198
|
-
*
|
|
4199
|
-
* @example
|
|
4200
|
-
* ```typescript
|
|
4201
|
-
* const { data, error } = await sdk.customer.updateAddress(
|
|
4202
|
-
* {
|
|
4203
|
-
* user_id: "user_456",
|
|
4204
|
-
* address_id: "addr_789"
|
|
4205
|
-
* },
|
|
4206
|
-
* {
|
|
4207
|
-
* address_line1: "456 Oak Avenue",
|
|
4208
|
-
* city: "Los Angeles",
|
|
4209
|
-
* state: "CA",
|
|
4210
|
-
* pincode: "90210"
|
|
4211
|
-
* }
|
|
4212
|
-
* );
|
|
4213
|
-
*
|
|
4214
|
-
* if (error) {
|
|
4215
|
-
* console.error("Failed to update address:", error);
|
|
4216
|
-
* return;
|
|
4217
|
-
* }
|
|
4218
|
-
*
|
|
4219
|
-
* console.log("Address updated:", data.address);
|
|
4220
|
-
* ```
|
|
4221
|
-
*/
|
|
4222
|
-
async updateAddress(pathParams, body) {
|
|
4223
|
-
return this.executeRequest(() => this.client.PUT("/customers/{user_id}/addresses/{address_id}", {
|
|
4224
|
-
params: { path: pathParams },
|
|
4225
|
-
body
|
|
4226
|
-
}));
|
|
4509
|
+
setupPublicAuth() {
|
|
4510
|
+
this.client.use({ onRequest: async ({ request }) => {
|
|
4511
|
+
if (this.apiKey) request.headers.set("X-Api-Key", this.apiKey);
|
|
4512
|
+
return request;
|
|
4513
|
+
} });
|
|
4227
4514
|
}
|
|
4515
|
+
};
|
|
4516
|
+
|
|
4517
|
+
//#endregion
|
|
4518
|
+
//#region src/index.ts
|
|
4519
|
+
/**
|
|
4520
|
+
* Public SDK class for the Storefront API.
|
|
4521
|
+
*
|
|
4522
|
+
* This surface is intentionally limited to API-key-backed, public read
|
|
4523
|
+
* operations so it can be used safely during build and prerender flows.
|
|
4524
|
+
*/
|
|
4525
|
+
var PublicStorefrontSDK = class {
|
|
4228
4526
|
/**
|
|
4229
|
-
*
|
|
4230
|
-
*
|
|
4231
|
-
* @param pathParams - Path parameters
|
|
4232
|
-
* @returns Promise with deletion response
|
|
4233
|
-
*
|
|
4234
|
-
* @example
|
|
4235
|
-
* ```typescript
|
|
4236
|
-
* const { data, error } = await sdk.customer.deleteAddress({
|
|
4237
|
-
* user_id: "user_456",
|
|
4238
|
-
* address_id: "addr_789"
|
|
4239
|
-
* });
|
|
4240
|
-
*
|
|
4241
|
-
* if (error) {
|
|
4242
|
-
* console.error("Failed to delete address:", error);
|
|
4243
|
-
* return;
|
|
4244
|
-
* }
|
|
4245
|
-
*
|
|
4246
|
-
* console.log("Address deleted:", data.message);
|
|
4247
|
-
* ```
|
|
4527
|
+
* Client for catalog-related read-only endpoints
|
|
4248
4528
|
*/
|
|
4249
|
-
|
|
4250
|
-
return this.executeRequest(() => this.client.DELETE("/customers/{user_id}/addresses/{address_id}", { params: { path: pathParams } }));
|
|
4251
|
-
}
|
|
4529
|
+
catalog;
|
|
4252
4530
|
/**
|
|
4253
|
-
*
|
|
4254
|
-
*
|
|
4255
|
-
* @param pathParams - Path parameters
|
|
4256
|
-
* @returns Promise with loyalty details
|
|
4257
|
-
*
|
|
4258
|
-
* @example
|
|
4259
|
-
* ```typescript
|
|
4260
|
-
* const { data, error } = await sdk.customer.getLoyaltyDetails({
|
|
4261
|
-
* user_id: "user_456"
|
|
4262
|
-
* });
|
|
4263
|
-
*
|
|
4264
|
-
* if (error) {
|
|
4265
|
-
* console.error("Failed to get loyalty details:", error);
|
|
4266
|
-
* return;
|
|
4267
|
-
* }
|
|
4268
|
-
*
|
|
4269
|
-
* console.log("Loyalty info:", data.loyalty);
|
|
4270
|
-
* console.log("Points balance:", data.loyalty_point_balance);
|
|
4271
|
-
* ```
|
|
4531
|
+
* Client for helper-related endpoints
|
|
4272
4532
|
*/
|
|
4273
|
-
|
|
4274
|
-
return this.executeRequest(() => this.client.GET("/customers/{user_id}/loyalty", { params: { path: pathParams } }));
|
|
4275
|
-
}
|
|
4533
|
+
helpers;
|
|
4276
4534
|
/**
|
|
4277
|
-
*
|
|
4278
|
-
*
|
|
4279
|
-
* @param pathParams - Path parameters
|
|
4280
|
-
* @returns Promise with loyalty points activity
|
|
4281
|
-
*
|
|
4282
|
-
* @example
|
|
4283
|
-
* ```typescript
|
|
4284
|
-
* const { data, error } = await sdk.customer.listLoyaltyPointsActivity({
|
|
4285
|
-
* user_id: "user_456"
|
|
4286
|
-
* });
|
|
4287
|
-
*
|
|
4288
|
-
* if (error) {
|
|
4289
|
-
* console.error("Failed to get loyalty activity:", error);
|
|
4290
|
-
* return;
|
|
4291
|
-
* }
|
|
4292
|
-
*
|
|
4293
|
-
* console.log("Loyalty activity:", data.loyalty_points_activity);
|
|
4294
|
-
*
|
|
4295
|
-
* // With pagination and sorting
|
|
4296
|
-
* const { data: sortedData, error: sortedError } = await sdk.customer.listLoyaltyPointsActivity({
|
|
4297
|
-
* user_id: "user_456",
|
|
4298
|
-
* page: 1,
|
|
4299
|
-
* limit: 20,
|
|
4300
|
-
* sort_by: JSON.stringify({ "created_at": "desc" })
|
|
4301
|
-
* });
|
|
4302
|
-
* ```
|
|
4535
|
+
* Client for store config-related endpoints
|
|
4303
4536
|
*/
|
|
4304
|
-
|
|
4305
|
-
return this.executeRequest(() => this.client.GET("/customers/{user_id}/loyalty-points-activity", { params: {
|
|
4306
|
-
path: pathParams,
|
|
4307
|
-
query: queryParams
|
|
4308
|
-
} }));
|
|
4309
|
-
}
|
|
4537
|
+
store;
|
|
4310
4538
|
/**
|
|
4311
|
-
*
|
|
4312
|
-
*
|
|
4313
|
-
* @param pathParams - Path parameters
|
|
4314
|
-
* @returns Promise with reviews
|
|
4315
|
-
*
|
|
4316
|
-
* @example
|
|
4317
|
-
* ```typescript
|
|
4318
|
-
* const { data, error } = await sdk.customer.listCustomerReviews({
|
|
4319
|
-
* user_id: "user_456"
|
|
4320
|
-
* });
|
|
4321
|
-
*
|
|
4322
|
-
* if (error) {
|
|
4323
|
-
* console.error("Failed to get customer reviews:", error);
|
|
4324
|
-
* return;
|
|
4325
|
-
* }
|
|
4326
|
-
*
|
|
4327
|
-
* console.log("Customer reviews:", data.reviews);
|
|
4328
|
-
* console.log("Ready for review:", data.ready_for_review);
|
|
4329
|
-
* ```
|
|
4539
|
+
* Centrally stored default headers for consistency
|
|
4330
4540
|
*/
|
|
4331
|
-
|
|
4332
|
-
|
|
4541
|
+
defaultHeaders;
|
|
4542
|
+
constructor(options) {
|
|
4543
|
+
this.defaultHeaders = options.defaultHeaders;
|
|
4544
|
+
const config = {
|
|
4545
|
+
storeId: options.storeId,
|
|
4546
|
+
environment: options.environment,
|
|
4547
|
+
baseUrl: options.baseUrl,
|
|
4548
|
+
apiKey: options.apiKey,
|
|
4549
|
+
timeout: options.timeout,
|
|
4550
|
+
defaultHeaders: options.defaultHeaders,
|
|
4551
|
+
debug: options.debug,
|
|
4552
|
+
logger: options.logger
|
|
4553
|
+
};
|
|
4554
|
+
this.catalog = new PublicCatalogClient(config);
|
|
4555
|
+
this.helpers = new PublicHelpersClient(config);
|
|
4556
|
+
this.store = new PublicStoreConfigClient(config);
|
|
4333
4557
|
}
|
|
4334
4558
|
/**
|
|
4335
|
-
*
|
|
4336
|
-
*
|
|
4337
|
-
* @param pathParams - Path parameters
|
|
4338
|
-
* @returns Promise with payment methods
|
|
4559
|
+
* Set the API key for all public clients
|
|
4339
4560
|
*
|
|
4340
|
-
* @
|
|
4341
|
-
* ```typescript
|
|
4342
|
-
* const { data, error } = await sdk.customer.listSavedPaymentMethods({
|
|
4343
|
-
* customer_id: "customer_123"
|
|
4344
|
-
* });
|
|
4345
|
-
*
|
|
4346
|
-
* if (error) {
|
|
4347
|
-
* console.error("Failed to list saved payment methods:", error);
|
|
4348
|
-
* return;
|
|
4349
|
-
* }
|
|
4350
|
-
*
|
|
4351
|
-
* console.log("Saved payment methods:", data.saved_payment_methods);
|
|
4352
|
-
* ```
|
|
4561
|
+
* @param apiKey - The API key to set
|
|
4353
4562
|
*/
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
} }));
|
|
4563
|
+
setApiKey(apiKey) {
|
|
4564
|
+
this.catalog.setApiKey(apiKey);
|
|
4565
|
+
this.helpers.setApiKey(apiKey);
|
|
4566
|
+
this.store.setApiKey(apiKey);
|
|
4359
4567
|
}
|
|
4360
4568
|
/**
|
|
4361
|
-
*
|
|
4362
|
-
*
|
|
4363
|
-
* @param pathParams - Path parameters
|
|
4364
|
-
* @returns Promise with cards
|
|
4365
|
-
*
|
|
4366
|
-
* @example
|
|
4367
|
-
* ```typescript
|
|
4368
|
-
* const { data, error } = await sdk.customer.listCustomerCards({
|
|
4369
|
-
* customer_id: "customer_123"
|
|
4370
|
-
* });
|
|
4371
|
-
*
|
|
4372
|
-
* if (error) {
|
|
4373
|
-
* console.error("Failed to list customer cards:", error);
|
|
4374
|
-
* return;
|
|
4375
|
-
* }
|
|
4376
|
-
*
|
|
4377
|
-
* console.log("Customer cards:", data.cards);
|
|
4378
|
-
* ```
|
|
4569
|
+
* Clear the API key from all public clients
|
|
4379
4570
|
*/
|
|
4380
|
-
|
|
4381
|
-
|
|
4571
|
+
clearApiKey() {
|
|
4572
|
+
this.catalog.clearApiKey();
|
|
4573
|
+
this.helpers.clearApiKey();
|
|
4574
|
+
this.store.clearApiKey();
|
|
4382
4575
|
}
|
|
4383
|
-
};
|
|
4384
|
-
|
|
4385
|
-
//#endregion
|
|
4386
|
-
//#region src/lib/store-config.ts
|
|
4387
|
-
/**
|
|
4388
|
-
* Client for interacting with store config endpoints
|
|
4389
|
-
*/
|
|
4390
|
-
var StoreConfigClient = class extends StorefrontAPIClient {
|
|
4391
4576
|
/**
|
|
4392
|
-
*
|
|
4393
|
-
*
|
|
4394
|
-
* @description Checks whether a store with the configured store ID exists.
|
|
4395
|
-
* Returns `success: true` if the store exists, `false` otherwise.
|
|
4396
|
-
*
|
|
4397
|
-
* @returns Promise with store existence check result
|
|
4398
|
-
* @example
|
|
4399
|
-
* ```typescript
|
|
4400
|
-
* const { data, error } = await sdk.storeConfig.checkStore();
|
|
4577
|
+
* Set default headers for all public clients
|
|
4401
4578
|
*
|
|
4402
|
-
*
|
|
4403
|
-
* console.error("Failed to check store:", error.message);
|
|
4404
|
-
* } else {
|
|
4405
|
-
* console.log("Store exists:", data.success);
|
|
4406
|
-
* }
|
|
4407
|
-
* ```
|
|
4579
|
+
* @param headers - Default headers to set (only supported headers allowed)
|
|
4408
4580
|
*/
|
|
4409
|
-
|
|
4410
|
-
|
|
4581
|
+
setDefaultHeaders(headers) {
|
|
4582
|
+
this.defaultHeaders = headers;
|
|
4583
|
+
this.catalog.setDefaultHeaders(headers);
|
|
4584
|
+
this.helpers.setDefaultHeaders(headers);
|
|
4585
|
+
this.store.setDefaultHeaders(headers);
|
|
4411
4586
|
}
|
|
4412
4587
|
/**
|
|
4413
|
-
* Get
|
|
4414
|
-
*
|
|
4415
|
-
* @returns Promise with store configuration data
|
|
4416
|
-
*
|
|
4417
|
-
* @example
|
|
4418
|
-
* ```typescript
|
|
4419
|
-
* const { data, error } = await sdk.storeConfig.getStoreConfig();
|
|
4420
|
-
*
|
|
4421
|
-
* if (error) {
|
|
4422
|
-
* console.error('Failed to get store config:', error.message);
|
|
4423
|
-
* return;
|
|
4424
|
-
* }
|
|
4588
|
+
* Get current default headers
|
|
4425
4589
|
*
|
|
4426
|
-
*
|
|
4427
|
-
* const storeConfig = data.store_config;
|
|
4428
|
-
* console.log('Store brand:', storeConfig.brand.name);
|
|
4429
|
-
* console.log('Currency:', storeConfig.currency.code);
|
|
4430
|
-
* console.log('KYC enabled:', storeConfig.is_kyc_enabled);
|
|
4431
|
-
* console.log('Customer groups enabled:', storeConfig.is_customer_group_enabled);
|
|
4432
|
-
* ```
|
|
4590
|
+
* @returns Current default headers from central storage (always consistent)
|
|
4433
4591
|
*/
|
|
4434
|
-
|
|
4435
|
-
return this.
|
|
4592
|
+
getDefaultHeaders() {
|
|
4593
|
+
return this.defaultHeaders;
|
|
4436
4594
|
}
|
|
4437
4595
|
};
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
//#region src/index.ts
|
|
4441
|
-
/**
|
|
4442
|
-
* Main SDK class for the Storefront API
|
|
4596
|
+
/**
|
|
4597
|
+
* Main session-aware SDK class for the Storefront API
|
|
4443
4598
|
*/
|
|
4444
|
-
var
|
|
4599
|
+
var SessionStorefrontSDK = class {
|
|
4445
4600
|
/**
|
|
4446
4601
|
* Client for catalog-related endpoints (products, categories, etc.)
|
|
4447
4602
|
*/
|
|
@@ -4479,12 +4634,33 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4479
4634
|
*/
|
|
4480
4635
|
defaultHeaders;
|
|
4481
4636
|
/**
|
|
4482
|
-
*
|
|
4637
|
+
* Shared session helper and coordinator for all API clients in this SDK instance.
|
|
4638
|
+
*/
|
|
4639
|
+
session;
|
|
4640
|
+
sessionManager;
|
|
4641
|
+
/**
|
|
4642
|
+
* Create a new SessionStorefrontSDK instance
|
|
4483
4643
|
*
|
|
4484
4644
|
* @param options - Configuration options for the SDK
|
|
4485
4645
|
*/
|
|
4486
4646
|
constructor(options) {
|
|
4487
4647
|
this.defaultHeaders = options.defaultHeaders;
|
|
4648
|
+
const sessionManager = new StorefrontSessionManager({
|
|
4649
|
+
accessToken: options.accessToken,
|
|
4650
|
+
apiKey: options.apiKey,
|
|
4651
|
+
baseUrl: buildStorefrontURL({
|
|
4652
|
+
storeId: options.storeId,
|
|
4653
|
+
environment: options.environment,
|
|
4654
|
+
baseUrl: options.baseUrl
|
|
4655
|
+
}),
|
|
4656
|
+
onTokensCleared: options.onTokensCleared,
|
|
4657
|
+
onTokensUpdated: options.onTokensUpdated,
|
|
4658
|
+
refreshToken: options.refreshToken,
|
|
4659
|
+
refreshTokenFn: options.refreshTokenFn,
|
|
4660
|
+
tokenStorage: options.tokenStorage
|
|
4661
|
+
});
|
|
4662
|
+
this.sessionManager = sessionManager;
|
|
4663
|
+
this.session = sessionManager;
|
|
4488
4664
|
const config = {
|
|
4489
4665
|
storeId: options.storeId,
|
|
4490
4666
|
environment: options.environment,
|
|
@@ -4498,7 +4674,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4498
4674
|
onTokensCleared: options.onTokensCleared,
|
|
4499
4675
|
defaultHeaders: options.defaultHeaders,
|
|
4500
4676
|
debug: options.debug,
|
|
4501
|
-
logger: options.logger
|
|
4677
|
+
logger: options.logger,
|
|
4678
|
+
sessionManager
|
|
4502
4679
|
};
|
|
4503
4680
|
this.catalog = new CatalogClient(config);
|
|
4504
4681
|
this.cart = new CartClient(config);
|
|
@@ -4520,14 +4697,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4520
4697
|
* - If tokenStorage is not provided: Only stores access token for manual management
|
|
4521
4698
|
*/
|
|
4522
4699
|
async setTokens(accessToken, refreshToken) {
|
|
4523
|
-
await this.
|
|
4524
|
-
await this.cart.setTokens(accessToken, refreshToken);
|
|
4525
|
-
await this.auth.setTokens(accessToken, refreshToken);
|
|
4526
|
-
await this.customer.setTokens(accessToken, refreshToken);
|
|
4527
|
-
await this.helpers.setTokens(accessToken, refreshToken);
|
|
4528
|
-
await this.order.setTokens(accessToken, refreshToken);
|
|
4529
|
-
await this.payments.setTokens(accessToken, refreshToken);
|
|
4530
|
-
await this.store.setTokens(accessToken, refreshToken);
|
|
4700
|
+
await this.sessionManager.setTokens(accessToken, refreshToken);
|
|
4531
4701
|
}
|
|
4532
4702
|
/**
|
|
4533
4703
|
* Clear all authentication tokens from all clients
|
|
@@ -4537,14 +4707,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4537
4707
|
* - If tokenStorage is not provided: Clears the manual access token
|
|
4538
4708
|
*/
|
|
4539
4709
|
async clearTokens() {
|
|
4540
|
-
await this.
|
|
4541
|
-
await this.cart.clearTokens();
|
|
4542
|
-
await this.auth.clearTokens();
|
|
4543
|
-
await this.customer.clearTokens();
|
|
4544
|
-
await this.helpers.clearTokens();
|
|
4545
|
-
await this.order.clearTokens();
|
|
4546
|
-
await this.payments.clearTokens();
|
|
4547
|
-
await this.store.clearTokens();
|
|
4710
|
+
await this.sessionManager.clearTokens();
|
|
4548
4711
|
}
|
|
4549
4712
|
/**
|
|
4550
4713
|
* Set the API key for all clients
|
|
@@ -4552,57 +4715,58 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4552
4715
|
* @param apiKey - The API key to set
|
|
4553
4716
|
*/
|
|
4554
4717
|
setApiKey(apiKey) {
|
|
4555
|
-
this.
|
|
4556
|
-
this.cart.setApiKey(apiKey);
|
|
4557
|
-
this.auth.setApiKey(apiKey);
|
|
4558
|
-
this.customer.setApiKey(apiKey);
|
|
4559
|
-
this.helpers.setApiKey(apiKey);
|
|
4560
|
-
this.order.setApiKey(apiKey);
|
|
4561
|
-
this.payments.setApiKey(apiKey);
|
|
4562
|
-
this.store.setApiKey(apiKey);
|
|
4718
|
+
this.sessionManager.setApiKey(apiKey);
|
|
4563
4719
|
}
|
|
4564
4720
|
/**
|
|
4565
4721
|
* Clear the API key from all clients
|
|
4566
4722
|
*/
|
|
4567
4723
|
clearApiKey() {
|
|
4568
|
-
this.
|
|
4569
|
-
this.cart.clearApiKey();
|
|
4570
|
-
this.auth.clearApiKey();
|
|
4571
|
-
this.customer.clearApiKey();
|
|
4572
|
-
this.helpers.clearApiKey();
|
|
4573
|
-
this.order.clearApiKey();
|
|
4574
|
-
this.payments.clearApiKey();
|
|
4575
|
-
this.store.clearApiKey();
|
|
4724
|
+
this.sessionManager.clearApiKey();
|
|
4576
4725
|
}
|
|
4577
4726
|
/**
|
|
4578
4727
|
* Get the current access token if using token storage
|
|
4728
|
+
*
|
|
4729
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4579
4730
|
*/
|
|
4580
4731
|
async getAccessToken() {
|
|
4581
|
-
return
|
|
4732
|
+
return this.session.peekAccessToken();
|
|
4733
|
+
}
|
|
4734
|
+
/**
|
|
4735
|
+
* Ensure an access token is available for the current session.
|
|
4736
|
+
*
|
|
4737
|
+
* This may create or refresh a managed session when automatic token
|
|
4738
|
+
* management is configured.
|
|
4739
|
+
*
|
|
4740
|
+
* @returns A usable access token
|
|
4741
|
+
*/
|
|
4742
|
+
async ensureAccessToken() {
|
|
4743
|
+
return this.session.ensureAccessToken();
|
|
4582
4744
|
}
|
|
4583
4745
|
/**
|
|
4584
4746
|
* Get user information from the current access token
|
|
4585
4747
|
*
|
|
4748
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4749
|
+
*
|
|
4586
4750
|
* @returns User information extracted from JWT token, or null if no token or invalid token
|
|
4587
4751
|
*/
|
|
4588
4752
|
async getUserInfo() {
|
|
4589
|
-
|
|
4590
|
-
if (!token) return null;
|
|
4591
|
-
return extractUserInfoFromToken(token);
|
|
4753
|
+
return this.session.peekUserInfo();
|
|
4592
4754
|
}
|
|
4593
4755
|
/**
|
|
4594
4756
|
* Get the current user ID from the access token
|
|
4595
4757
|
*
|
|
4758
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4759
|
+
*
|
|
4596
4760
|
* @returns User ID (ulid) or null if no token or invalid token
|
|
4597
4761
|
*/
|
|
4598
4762
|
async getUserId() {
|
|
4599
|
-
|
|
4600
|
-
if (!token) return null;
|
|
4601
|
-
return getUserIdFromToken(token);
|
|
4763
|
+
return this.session.peekUserId();
|
|
4602
4764
|
}
|
|
4603
4765
|
/**
|
|
4604
4766
|
* Check if the current user is logged in (not anonymous)
|
|
4605
4767
|
*
|
|
4768
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4769
|
+
*
|
|
4606
4770
|
* @returns True if user is logged in, false if anonymous or no token
|
|
4607
4771
|
*/
|
|
4608
4772
|
async isLoggedIn() {
|
|
@@ -4613,6 +4777,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4613
4777
|
/**
|
|
4614
4778
|
* Check if the current user is anonymous
|
|
4615
4779
|
*
|
|
4780
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4781
|
+
*
|
|
4616
4782
|
* @returns True if user is anonymous or no token, false if logged in
|
|
4617
4783
|
*/
|
|
4618
4784
|
async isAnonymous() {
|
|
@@ -4623,18 +4789,22 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4623
4789
|
/**
|
|
4624
4790
|
* Get the customer ID from the current access token
|
|
4625
4791
|
*
|
|
4792
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4793
|
+
*
|
|
4626
4794
|
* @returns Customer ID or null if no token, invalid token, or user has no customer ID
|
|
4627
4795
|
*/
|
|
4628
4796
|
async getCustomerId() {
|
|
4629
|
-
return
|
|
4797
|
+
return this.session.peekCustomerId();
|
|
4630
4798
|
}
|
|
4631
4799
|
/**
|
|
4632
4800
|
* Get the customer group ID from the current access token
|
|
4633
4801
|
*
|
|
4802
|
+
* This is a passive lookup. It will not create or refresh a session.
|
|
4803
|
+
*
|
|
4634
4804
|
* @returns Customer group ID or null if no token, invalid token, or user has no customer group
|
|
4635
4805
|
*/
|
|
4636
4806
|
async getCustomerGroupId() {
|
|
4637
|
-
return
|
|
4807
|
+
return this.session.peekCustomerGroupId();
|
|
4638
4808
|
}
|
|
4639
4809
|
/**
|
|
4640
4810
|
* Set default headers for all clients
|
|
@@ -4661,6 +4831,70 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
4661
4831
|
return this.defaultHeaders;
|
|
4662
4832
|
}
|
|
4663
4833
|
};
|
|
4834
|
+
function buildPublicStorefrontOptions(options) {
|
|
4835
|
+
return {
|
|
4836
|
+
storeId: options.storeId,
|
|
4837
|
+
environment: options.environment,
|
|
4838
|
+
baseUrl: options.baseUrl,
|
|
4839
|
+
apiKey: options.apiKey,
|
|
4840
|
+
timeout: options.timeout,
|
|
4841
|
+
defaultHeaders: options.defaultHeaders,
|
|
4842
|
+
debug: options.debug,
|
|
4843
|
+
logger: options.logger
|
|
4844
|
+
};
|
|
4845
|
+
}
|
|
4846
|
+
function buildSessionStorefrontOptions(options, overrides) {
|
|
4847
|
+
return {
|
|
4848
|
+
...buildPublicStorefrontOptions(options),
|
|
4849
|
+
...options.session,
|
|
4850
|
+
...overrides
|
|
4851
|
+
};
|
|
4852
|
+
}
|
|
4853
|
+
/**
|
|
4854
|
+
* Create a configured storefront factory with explicit public and session
|
|
4855
|
+
* access patterns.
|
|
4856
|
+
*
|
|
4857
|
+
* @example
|
|
4858
|
+
* ```typescript
|
|
4859
|
+
* import {
|
|
4860
|
+
* BrowserTokenStorage,
|
|
4861
|
+
* createStorefront,
|
|
4862
|
+
* Environment,
|
|
4863
|
+
* } from "@commercengine/storefront-sdk";
|
|
4864
|
+
*
|
|
4865
|
+
* export const storefront = createStorefront({
|
|
4866
|
+
* storeId: "your-store-id",
|
|
4867
|
+
* apiKey: "your-api-key",
|
|
4868
|
+
* environment: Environment.Staging,
|
|
4869
|
+
* session: {
|
|
4870
|
+
* tokenStorage: new BrowserTokenStorage("myapp_"),
|
|
4871
|
+
* },
|
|
4872
|
+
* });
|
|
4873
|
+
*
|
|
4874
|
+
* const { data: products } = await storefront.public().catalog.listProducts();
|
|
4875
|
+
* const { data: cart } = await storefront.session().cart.getCart();
|
|
4876
|
+
* ```
|
|
4877
|
+
*
|
|
4878
|
+
* @param options - Shared public config plus optional default session config
|
|
4879
|
+
* @returns A storefront factory with explicit `public()` and `session()` accessors
|
|
4880
|
+
*/
|
|
4881
|
+
function createStorefront(options) {
|
|
4882
|
+
const publicOptions = buildPublicStorefrontOptions(options);
|
|
4883
|
+
let publicSDK = null;
|
|
4884
|
+
let sessionSDK = null;
|
|
4885
|
+
const session = (overrides) => {
|
|
4886
|
+
if (overrides && Object.keys(overrides).length > 0) return new SessionStorefrontSDK(buildSessionStorefrontOptions(options, overrides));
|
|
4887
|
+
if (!sessionSDK) sessionSDK = new SessionStorefrontSDK(buildSessionStorefrontOptions(options));
|
|
4888
|
+
return sessionSDK;
|
|
4889
|
+
};
|
|
4890
|
+
return {
|
|
4891
|
+
public: () => {
|
|
4892
|
+
if (!publicSDK) publicSDK = new PublicStorefrontSDK(publicOptions);
|
|
4893
|
+
return publicSDK;
|
|
4894
|
+
},
|
|
4895
|
+
session
|
|
4896
|
+
};
|
|
4897
|
+
}
|
|
4664
4898
|
|
|
4665
4899
|
//#endregion
|
|
4666
4900
|
exports.AuthClient = AuthClient;
|
|
@@ -4674,11 +4908,16 @@ exports.HelpersClient = HelpersClient;
|
|
|
4674
4908
|
exports.MemoryTokenStorage = MemoryTokenStorage;
|
|
4675
4909
|
exports.OrderClient = OrderClient;
|
|
4676
4910
|
exports.PaymentsClient = PaymentsClient;
|
|
4911
|
+
exports.PublicCatalogClient = PublicCatalogClient;
|
|
4912
|
+
exports.PublicHelpersClient = PublicHelpersClient;
|
|
4913
|
+
exports.PublicStoreConfigClient = PublicStoreConfigClient;
|
|
4914
|
+
exports.PublicStorefrontAPIClient = PublicStorefrontAPIClient;
|
|
4915
|
+
exports.PublicStorefrontSDK = PublicStorefrontSDK;
|
|
4677
4916
|
exports.ResponseUtils = ResponseUtils;
|
|
4917
|
+
exports.SessionStorefrontAPIClient = SessionStorefrontAPIClient;
|
|
4918
|
+
exports.SessionStorefrontSDK = SessionStorefrontSDK;
|
|
4678
4919
|
exports.StoreConfigClient = StoreConfigClient;
|
|
4679
|
-
exports.
|
|
4680
|
-
exports.StorefrontSDK = StorefrontSDK;
|
|
4681
|
-
exports.default = StorefrontSDK;
|
|
4920
|
+
exports.createStorefront = createStorefront;
|
|
4682
4921
|
return exports;
|
|
4683
4922
|
})({});
|
|
4684
4923
|
//# sourceMappingURL=index.iife.js.map
|