@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.
Files changed (72) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +4 -0
  3. package/auth/index.d.ts +19 -4
  4. package/auth/index.js +49 -1
  5. package/auth/storage.d.ts +1 -1
  6. package/components/ShopperExperience/Component/index.d.ts +1 -1
  7. package/components/ShopperExperience/Page/index.d.ts +2 -2
  8. package/components/ShopperExperience/types.d.ts +5 -5
  9. package/hooks/ShopperBaskets/cache.d.ts +1 -1
  10. package/hooks/ShopperBaskets/mutation.d.ts +63 -282
  11. package/hooks/ShopperBaskets/mutation.js +60 -254
  12. package/hooks/ShopperBaskets/query.d.ts +11 -1
  13. package/hooks/ShopperBaskets/query.js +10 -0
  14. package/hooks/ShopperBaskets/queryKeyHelpers.d.ts +4 -4
  15. package/hooks/ShopperContexts/cache.d.ts +1 -1
  16. package/hooks/ShopperContexts/mutation.d.ts +18 -13
  17. package/hooks/ShopperContexts/mutation.js +16 -11
  18. package/hooks/ShopperContexts/query.d.ts +4 -2
  19. package/hooks/ShopperContexts/query.js +3 -1
  20. package/hooks/ShopperContexts/queryKeyHelpers.d.ts +4 -4
  21. package/hooks/ShopperCustomers/cache.d.ts +1 -1
  22. package/hooks/ShopperCustomers/mutation.d.ts +22 -82
  23. package/hooks/ShopperCustomers/mutation.js +20 -81
  24. package/hooks/ShopperCustomers/query.d.ts +28 -3
  25. package/hooks/ShopperCustomers/query.js +28 -2
  26. package/hooks/ShopperCustomers/queryKeyHelpers.d.ts +4 -4
  27. package/hooks/ShopperExperience/query.d.ts +13 -9
  28. package/hooks/ShopperExperience/query.js +12 -8
  29. package/hooks/ShopperExperience/queryKeyHelpers.d.ts +4 -4
  30. package/hooks/ShopperGiftCertificates/query.d.ts +3 -1
  31. package/hooks/ShopperGiftCertificates/query.js +2 -0
  32. package/hooks/ShopperGiftCertificates/queryKeyHelpers.d.ts +4 -4
  33. package/hooks/ShopperLogin/mutation.d.ts +21 -49
  34. package/hooks/ShopperLogin/mutation.js +19 -41
  35. package/hooks/ShopperLogin/query.d.ts +9 -1
  36. package/hooks/ShopperLogin/query.js +8 -0
  37. package/hooks/ShopperLogin/queryKeyHelpers.d.ts +4 -4
  38. package/hooks/ShopperOrders/cache.d.ts +1 -1
  39. package/hooks/ShopperOrders/mutation.d.ts +21 -25
  40. package/hooks/ShopperOrders/mutation.js +19 -21
  41. package/hooks/ShopperOrders/query.d.ts +7 -1
  42. package/hooks/ShopperOrders/query.js +7 -1
  43. package/hooks/ShopperOrders/queryKeyHelpers.d.ts +4 -4
  44. package/hooks/ShopperProducts/query.d.ts +9 -1
  45. package/hooks/ShopperProducts/query.js +8 -0
  46. package/hooks/ShopperProducts/queryKeyHelpers.d.ts +4 -4
  47. package/hooks/ShopperPromotions/query.d.ts +5 -1
  48. package/hooks/ShopperPromotions/query.js +4 -0
  49. package/hooks/ShopperPromotions/queryKeyHelpers.d.ts +4 -4
  50. package/hooks/ShopperSearch/query.d.ts +12 -4
  51. package/hooks/ShopperSearch/query.js +11 -3
  52. package/hooks/ShopperSearch/queryKeyHelpers.d.ts +4 -4
  53. package/hooks/types.d.ts +30 -27
  54. package/hooks/useAccessToken.d.ts +6 -0
  55. package/hooks/useAccessToken.js +8 -0
  56. package/hooks/useAuthHelper.d.ts +15 -1
  57. package/hooks/useAuthHelper.js +19 -0
  58. package/hooks/useCommerceApi.d.ts +2 -0
  59. package/hooks/useCommerceApi.js +2 -0
  60. package/hooks/useCustomerId.d.ts +2 -0
  61. package/hooks/useCustomerId.js +2 -0
  62. package/hooks/useCustomerType.d.ts +5 -2
  63. package/hooks/useCustomerType.js +12 -1
  64. package/hooks/useEncUserId.d.ts +3 -0
  65. package/hooks/useEncUserId.js +3 -0
  66. package/hooks/useLocalStorage.d.ts +1 -1
  67. package/hooks/useUsid.d.ts +2 -0
  68. package/hooks/useUsid.js +2 -0
  69. package/package.json +15 -13
  70. package/provider.d.ts +27 -1
  71. package/provider.js +27 -1
  72. package/scripts/build-and-release-docs.js +1 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ## v1.0.0-preview.2 (Jun 05, 2023)
2
+ ## v1.0.0-preview.1 (Jun 02, 2023)
1
3
  ## v1.0.0-preview.0 (May 31, 2023)
2
4
  ## v1.0.0-dev (May 29, 2023)
3
5
  ## v3.0.0-dev (May 12, 2023)
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
- declare type TokenResponse = ShopperLoginTypes.TokenResponse;
5
- declare type Helpers = typeof helpers;
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 declare type AuthData = Prettify<RemoveStringIndex<TokenResponse> & {
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
- declare type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered';
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 && !_this2.isTokenExpired(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,5 +1,5 @@
1
1
  import Cookies from 'js-cookie';
2
- export declare type StorageType = 'cookie' | 'local' | 'memory';
2
+ export type StorageType = 'cookie' | 'local' | 'memory';
3
3
  export interface BaseStorageOptions {
4
4
  keySuffix?: string;
5
5
  }
@@ -1,5 +1,5 @@
1
1
  import { Component as ComponentType } from '../types';
2
- declare type ComponentProps = {
2
+ type ComponentProps = {
3
3
  component: ComponentType;
4
4
  };
5
5
  /**
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
2
  import type { Component as ComponentType, Page as PageType } from '../types';
3
- declare type ComponentMap = {
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
- declare type PageContextValue = {
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
- declare type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];
3
- declare type Client = ApiClients['shopperExperience'];
4
- export declare type Page = DataType<Client['getPage']>;
5
- export declare type Region = ArrayElement<NonNullable<Page['regions']>>;
6
- export declare type Component = ArrayElement<NonNullable<Region['components']>>;
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
- declare type Client = ApiClients['shopperBaskets'];
2
+ type Client = ApiClients['shopperBaskets'];
3
3
  export declare const cacheUpdateMatrix: CacheUpdateMatrix<Client>;
4
4
  export {};
5
5
  //# sourceMappingURL=cache.d.ts.map