@salesforce/commerce-sdk-react 1.0.0-preview.0 → 1.0.0-preview.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/README.md +4 -0
- package/auth/index.d.ts +19 -4
- package/auth/index.js +49 -1
- package/auth/storage.d.ts +1 -1
- package/components/ShopperExperience/Component/index.d.ts +1 -1
- package/components/ShopperExperience/Page/index.d.ts +2 -2
- package/components/ShopperExperience/types.d.ts +5 -5
- package/hooks/ShopperBaskets/cache.d.ts +1 -1
- package/hooks/ShopperBaskets/mutation.d.ts +63 -282
- package/hooks/ShopperBaskets/mutation.js +60 -254
- package/hooks/ShopperBaskets/query.d.ts +11 -1
- package/hooks/ShopperBaskets/query.js +10 -0
- package/hooks/ShopperBaskets/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperContexts/cache.d.ts +1 -1
- package/hooks/ShopperContexts/mutation.d.ts +18 -13
- package/hooks/ShopperContexts/mutation.js +16 -11
- package/hooks/ShopperContexts/query.d.ts +4 -2
- package/hooks/ShopperContexts/query.js +3 -1
- package/hooks/ShopperContexts/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperCustomers/cache.d.ts +1 -1
- package/hooks/ShopperCustomers/mutation.d.ts +22 -82
- package/hooks/ShopperCustomers/mutation.js +20 -81
- package/hooks/ShopperCustomers/query.d.ts +28 -3
- package/hooks/ShopperCustomers/query.js +28 -2
- package/hooks/ShopperCustomers/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperExperience/query.d.ts +13 -9
- package/hooks/ShopperExperience/query.js +12 -8
- package/hooks/ShopperExperience/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperGiftCertificates/query.d.ts +3 -1
- package/hooks/ShopperGiftCertificates/query.js +2 -0
- package/hooks/ShopperGiftCertificates/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperLogin/mutation.d.ts +21 -49
- package/hooks/ShopperLogin/mutation.js +19 -41
- package/hooks/ShopperLogin/query.d.ts +9 -1
- package/hooks/ShopperLogin/query.js +8 -0
- package/hooks/ShopperLogin/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperOrders/cache.d.ts +1 -1
- package/hooks/ShopperOrders/mutation.d.ts +21 -25
- package/hooks/ShopperOrders/mutation.js +19 -21
- package/hooks/ShopperOrders/query.d.ts +7 -1
- package/hooks/ShopperOrders/query.js +7 -1
- package/hooks/ShopperOrders/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperProducts/query.d.ts +9 -1
- package/hooks/ShopperProducts/query.js +8 -0
- package/hooks/ShopperProducts/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperPromotions/query.d.ts +5 -1
- package/hooks/ShopperPromotions/query.js +4 -0
- package/hooks/ShopperPromotions/queryKeyHelpers.d.ts +4 -4
- package/hooks/ShopperSearch/query.d.ts +12 -4
- package/hooks/ShopperSearch/query.js +11 -3
- package/hooks/ShopperSearch/queryKeyHelpers.d.ts +4 -4
- package/hooks/types.d.ts +30 -27
- package/hooks/useAccessToken.d.ts +6 -0
- package/hooks/useAccessToken.js +8 -0
- package/hooks/useAuthHelper.d.ts +15 -1
- package/hooks/useAuthHelper.js +19 -0
- package/hooks/useCommerceApi.d.ts +2 -0
- package/hooks/useCommerceApi.js +2 -0
- package/hooks/useCustomerId.d.ts +2 -0
- package/hooks/useCustomerId.js +2 -0
- package/hooks/useCustomerType.d.ts +5 -2
- package/hooks/useCustomerType.js +12 -1
- package/hooks/useEncUserId.d.ts +3 -0
- package/hooks/useEncUserId.js +3 -0
- package/hooks/useLocalStorage.d.ts +1 -1
- package/hooks/useUsid.d.ts +2 -0
- package/hooks/useUsid.js +2 -0
- package/package.json +15 -13
- package/provider.d.ts +27 -1
- package/provider.js +27 -1
- package/scripts/build-and-release-docs.js +1 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -234,6 +234,10 @@ You could also import the mutation options as a constant like:
|
|
|
234
234
|
import {useShopperBasketsMutation, ShopperBasketsMutations} from '@salesforce/commerce-sdk-react'
|
|
235
235
|
|
|
236
236
|
const Example = ({basketId}) => {
|
|
237
|
+
// this works
|
|
238
|
+
const addItemToBasket = useShopperBasketsMutation('addItemToBasket')
|
|
239
|
+
|
|
240
|
+
// this also works
|
|
237
241
|
const addItemToBasket = useShopperBasketsMutation(ShopperBasketsMutations.AddItemToBasket)
|
|
238
242
|
return ...
|
|
239
243
|
}
|
package/auth/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { helpers, ShopperLoginTypes, ShopperCustomersTypes } from 'commerce-sdk-isomorphic';
|
|
2
2
|
import { ApiClientConfigParams, Prettify, RemoveStringIndex } from '../hooks/types';
|
|
3
3
|
import { CustomerType } from '../hooks/useCustomerType';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
type TokenResponse = ShopperLoginTypes.TokenResponse;
|
|
5
|
+
type Helpers = typeof helpers;
|
|
6
6
|
interface AuthConfig extends ApiClientConfigParams {
|
|
7
7
|
redirectURI: string;
|
|
8
8
|
proxy: string;
|
|
@@ -16,12 +16,12 @@ interface AuthConfig extends ApiClientConfigParams {
|
|
|
16
16
|
* Plus, the getCustomer endpoint only works for registered user, it returns a 404 for a guest user,
|
|
17
17
|
* and it's not easy to grab this info in user land, so we add it into the Auth object, and expose it via a hook
|
|
18
18
|
*/
|
|
19
|
-
export
|
|
19
|
+
export type AuthData = Prettify<RemoveStringIndex<TokenResponse> & {
|
|
20
20
|
customer_type: CustomerType;
|
|
21
21
|
idp_access_token: string;
|
|
22
22
|
}>;
|
|
23
23
|
/** A shopper could be guest or registered, so we store the refresh tokens individually. */
|
|
24
|
-
|
|
24
|
+
type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered' | 'refresh_token_guest_copy' | 'refresh_token_registered_copy';
|
|
25
25
|
/**
|
|
26
26
|
* This class is used to handle shopper authentication.
|
|
27
27
|
* It is responsible for initializing shopper session, manage access
|
|
@@ -51,6 +51,21 @@ declare class Auth {
|
|
|
51
51
|
* Used to validate JWT token expiration.
|
|
52
52
|
*/
|
|
53
53
|
private isTokenExpired;
|
|
54
|
+
/**
|
|
55
|
+
* WARNING: This function is relevant to be used in Hybrid deployments only.
|
|
56
|
+
* Compares the refresh_token keys for guest('cc-nx-g') and registered('cc-nx') login from the cookie received from SFRA with the copy stored in localstorage on PWA Kit
|
|
57
|
+
* to determine if the login state of the shopper on SFRA site has changed. If the keys are different we return true considering the login state did change. If the keys are same,
|
|
58
|
+
* we compare the values of the refresh_token to cover an edge case where the login state might have changed multiple times on SFRA and the eventual refresh_token key might be same
|
|
59
|
+
* as that on PWA Kit which would incorrectly show both keys to be the same even though the sessions are different.
|
|
60
|
+
* @returns {boolean} true if the keys do not match (login state changed), false otherwise.
|
|
61
|
+
*/
|
|
62
|
+
private hasSFRAAuthStateChanged;
|
|
63
|
+
/**
|
|
64
|
+
* Used to validate JWT expiry and ensure auth state consistency with SFRA in a hybrid setup
|
|
65
|
+
* @param token access_token received on SLAS authentication
|
|
66
|
+
* @returns {boolean} true if JWT is valid; false otherwise
|
|
67
|
+
*/
|
|
68
|
+
private isTokenValidForHybrid;
|
|
54
69
|
/**
|
|
55
70
|
* This method stores the TokenResponse object retrived from SLAS, and
|
|
56
71
|
* store the data in storage.
|
package/auth/index.js
CHANGED
|
@@ -82,6 +82,24 @@ const DATA_MAP = {
|
|
|
82
82
|
store.delete('cc-nx-g');
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
+
// For Hybrid setups, we need a mechanism to inform PWA Kit whenever customer login state changes on SFRA.
|
|
86
|
+
// So we maintain a copy of the refersh_tokens in the local storage which is compared to the actual refresh_token stored in cookie storage.
|
|
87
|
+
// If the key or value of the refresh_token in local storage is different from the one in cookie storage, this indicates a change in customer auth state and we invalidate the access_token in PWA Kit.
|
|
88
|
+
// This triggers a new fetch for access_token using the current refresh_token from cookie storage and makes sure customer auth state is always in sync between SFRA and PWA sites in a hybrid setup.
|
|
89
|
+
refresh_token_guest_copy: {
|
|
90
|
+
storageType: 'local',
|
|
91
|
+
key: 'cc-nx-g',
|
|
92
|
+
callback: store => {
|
|
93
|
+
store.delete('cc-nx');
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
refresh_token_registered_copy: {
|
|
97
|
+
storageType: 'local',
|
|
98
|
+
key: 'cc-nx',
|
|
99
|
+
callback: store => {
|
|
100
|
+
store.delete('cc-nx-g');
|
|
101
|
+
}
|
|
102
|
+
},
|
|
85
103
|
customer_type: {
|
|
86
104
|
storageType: 'local',
|
|
87
105
|
key: 'customer_type'
|
|
@@ -205,6 +223,32 @@ class Auth {
|
|
|
205
223
|
return validTimeSeconds <= tokenAgeSeconds;
|
|
206
224
|
}
|
|
207
225
|
|
|
226
|
+
/**
|
|
227
|
+
* WARNING: This function is relevant to be used in Hybrid deployments only.
|
|
228
|
+
* Compares the refresh_token keys for guest('cc-nx-g') and registered('cc-nx') login from the cookie received from SFRA with the copy stored in localstorage on PWA Kit
|
|
229
|
+
* to determine if the login state of the shopper on SFRA site has changed. If the keys are different we return true considering the login state did change. If the keys are same,
|
|
230
|
+
* we compare the values of the refresh_token to cover an edge case where the login state might have changed multiple times on SFRA and the eventual refresh_token key might be same
|
|
231
|
+
* as that on PWA Kit which would incorrectly show both keys to be the same even though the sessions are different.
|
|
232
|
+
* @returns {boolean} true if the keys do not match (login state changed), false otherwise.
|
|
233
|
+
*/
|
|
234
|
+
hasSFRAAuthStateChanged() {
|
|
235
|
+
const refreshTokenKey = this.get('refresh_token_registered') && 'refresh_token_registered' || 'refresh_token_guest';
|
|
236
|
+
const refreshTokenCopyKey = this.get('refresh_token_registered_copy') && 'refresh_token_registered_copy' || 'refresh_token_guest_copy';
|
|
237
|
+
if (DATA_MAP[refreshTokenKey].key !== DATA_MAP[refreshTokenCopyKey].key) {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
return this.get(refreshTokenKey) !== this.get(refreshTokenCopyKey);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Used to validate JWT expiry and ensure auth state consistency with SFRA in a hybrid setup
|
|
245
|
+
* @param token access_token received on SLAS authentication
|
|
246
|
+
* @returns {boolean} true if JWT is valid; false otherwise
|
|
247
|
+
*/
|
|
248
|
+
isTokenValidForHybrid(token) {
|
|
249
|
+
return !this.isTokenExpired(token) && !this.hasSFRAAuthStateChanged();
|
|
250
|
+
}
|
|
251
|
+
|
|
208
252
|
/**
|
|
209
253
|
* This method stores the TokenResponse object retrived from SLAS, and
|
|
210
254
|
* store the data in storage.
|
|
@@ -220,9 +264,13 @@ class Auth {
|
|
|
220
264
|
this.set('usid', res.usid);
|
|
221
265
|
this.set('customer_type', isGuest ? 'guest' : 'registered');
|
|
222
266
|
const refreshTokenKey = isGuest ? 'refresh_token_guest' : 'refresh_token_registered';
|
|
267
|
+
const refreshTokenCopyKey = isGuest ? 'refresh_token_guest_copy' : 'refresh_token_registered_copy';
|
|
223
268
|
this.set(refreshTokenKey, res.refresh_token, {
|
|
224
269
|
expires: this.REFRESH_TOKEN_EXPIRATION_DAYS
|
|
225
270
|
});
|
|
271
|
+
this.set(refreshTokenCopyKey, res.refresh_token, {
|
|
272
|
+
expires: this.REFRESH_TOKEN_EXPIRATION_DAYS
|
|
273
|
+
});
|
|
226
274
|
}
|
|
227
275
|
|
|
228
276
|
/**
|
|
@@ -283,7 +331,7 @@ class Auth {
|
|
|
283
331
|
return _this2.pendingToken;
|
|
284
332
|
}
|
|
285
333
|
const accessToken = _this2.get('access_token');
|
|
286
|
-
if (accessToken &&
|
|
334
|
+
if (accessToken && _this2.isTokenValidForHybrid(accessToken)) {
|
|
287
335
|
return _this2.data;
|
|
288
336
|
}
|
|
289
337
|
const refreshTokenRegistered = _this2.get('refresh_token_registered');
|
package/auth/storage.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Component as ComponentType, Page as PageType } from '../types';
|
|
3
|
-
|
|
3
|
+
type ComponentMap = {
|
|
4
4
|
[typeId: string]: React.ComponentType<ComponentType & unknown>;
|
|
5
5
|
};
|
|
6
6
|
interface PageProps extends React.ComponentProps<'div'> {
|
|
7
7
|
page: PageType;
|
|
8
8
|
components: ComponentMap;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
type PageContextValue = {
|
|
11
11
|
components: ComponentMap;
|
|
12
12
|
};
|
|
13
13
|
export declare const PageContext: React.Context<PageContextValue | undefined>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ApiClients, DataType } from '../../hooks/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
2
|
+
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];
|
|
3
|
+
type Client = ApiClients['shopperExperience'];
|
|
4
|
+
export type Page = DataType<Client['getPage']>;
|
|
5
|
+
export type Region = ArrayElement<NonNullable<Page['regions']>>;
|
|
6
|
+
export type Component = ArrayElement<NonNullable<Region['components']>>;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApiClients, CacheUpdateMatrix } from '../types';
|
|
2
|
-
|
|
2
|
+
type Client = ApiClients['shopperBaskets'];
|
|
3
3
|
export declare const cacheUpdateMatrix: CacheUpdateMatrix<Client>;
|
|
4
4
|
export {};
|
|
5
5
|
//# sourceMappingURL=cache.d.ts.map
|