@magento/peregrine 12.2.0-beta.1 → 12.3.0-beta.1

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 (47) hide show
  1. package/lib/Apollo/clearCustomerDataFromCache.js +1 -0
  2. package/lib/Apollo/policies/index.js +9 -4
  3. package/lib/hooks/useGoogleReCaptcha/googleReCaptchaConfig.gql.js +16 -0
  4. package/lib/hooks/useGoogleReCaptcha/index.js +1 -0
  5. package/lib/hooks/useGoogleReCaptcha/useGoogleReCaptcha.js +210 -0
  6. package/lib/hooks/useMediaQuery.js +83 -0
  7. package/lib/hooks/useScript.js +68 -0
  8. package/lib/hooks/useSort.js +13 -2
  9. package/lib/talons/AccountInformationPage/useAccountInformationPage.js +23 -6
  10. package/lib/talons/CartPage/PriceAdjustments/GiftOptions/giftOptions.gql.js +36 -11
  11. package/lib/talons/CartPage/PriceAdjustments/GiftOptions/giftOptionsFragments.gql.js +19 -0
  12. package/lib/talons/CartPage/PriceAdjustments/GiftOptions/useGiftOptions.js +315 -94
  13. package/lib/talons/CartPage/PriceAdjustments/giftOptionsSection.gql.js +17 -0
  14. package/lib/talons/CartPage/PriceAdjustments/useGiftOptionsSection.js +61 -0
  15. package/lib/talons/CartPage/PriceSummary/__fixtures__/priceSummary.js +7 -2
  16. package/lib/talons/CartPage/PriceSummary/priceSummaryFragments.gql.js +7 -0
  17. package/lib/talons/CartPage/PriceSummary/queries/giftOptionsSummary.ce.js +8 -0
  18. package/lib/talons/CartPage/PriceSummary/queries/giftOptionsSummary.ee.js +15 -0
  19. package/lib/talons/CartPage/PriceSummary/useDiscountSummary.js +71 -0
  20. package/lib/talons/CartPage/PriceSummary/usePriceSummary.js +3 -1
  21. package/lib/talons/CartPage/ProductListing/EditModal/__fixtures__/configurableThumbnailSource.js +8 -0
  22. package/lib/talons/CartPage/ProductListing/EditModal/productForm.gql.js +11 -0
  23. package/lib/talons/CartPage/ProductListing/EditModal/useProductForm.js +15 -1
  24. package/lib/talons/CheckoutPage/OrderConfirmationPage/useCreateAccount.js +27 -5
  25. package/lib/talons/CheckoutPage/PaymentInformation/useCreditCard.js +36 -15
  26. package/lib/talons/CheckoutPage/useCheckoutPage.js +18 -3
  27. package/lib/talons/CmsDynamicBlock/client-schema.graphql +4 -0
  28. package/lib/talons/CmsDynamicBlock/cmsDynamicBlock.gql.js +113 -0
  29. package/lib/talons/CmsDynamicBlock/useCmsDynamicBlock.js +211 -0
  30. package/lib/talons/CreateAccount/useCreateAccount.js +29 -5
  31. package/lib/talons/ForgotPassword/useForgotPassword.js +26 -5
  32. package/lib/talons/Link/useLink.js +2 -1
  33. package/lib/talons/MiniCart/miniCartFragments.gql.js +4 -0
  34. package/lib/talons/MyAccount/useResetPassword.js +23 -5
  35. package/lib/talons/RootComponents/Category/useCategory.js +1 -1
  36. package/lib/talons/RootComponents/Product/useProduct.js +1 -6
  37. package/lib/talons/SearchPage/useSearchPage.js +1 -1
  38. package/lib/talons/SignIn/useSignIn.js +25 -6
  39. package/lib/talons/WishlistPage/createWishlist.gql.js +1 -0
  40. package/lib/talons/WishlistPage/useActionMenu.js +4 -4
  41. package/lib/talons/WishlistPage/useCreateWishlist.js +7 -4
  42. package/lib/talons/WishlistPage/useWishlistItem.js +3 -2
  43. package/lib/talons/WishlistPage/wishlistConfig.gql.ee.js +1 -0
  44. package/lib/talons/WishlistPage/wishlistItemFragments.gql.js +1 -0
  45. package/lib/util/configuredVariant.js +10 -6
  46. package/package.json +1 -1
  47. package/lib/talons/CartPage/PriceAdjustments/GiftOptions/client-schema.graphql +0 -7
@@ -0,0 +1,71 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ const DEFAULT_AMOUNT = {
4
+ currency: 'USD',
5
+ value: 0
6
+ };
7
+
8
+ /**
9
+ * Reduces discounts array into a single amount.
10
+ *
11
+ * @param {Array} discounts
12
+ */
13
+ const getTotalDiscount = (discounts = []) => {
14
+ // discounts from data can be null
15
+ if (!discounts || !discounts.length) {
16
+ return DEFAULT_AMOUNT;
17
+ } else {
18
+ return {
19
+ currency: discounts[0].amount.currency,
20
+ value: discounts.reduce(
21
+ (acc, discount) => acc + discount.amount.value,
22
+ 0
23
+ )
24
+ };
25
+ }
26
+ };
27
+
28
+ /**
29
+ * This talon contains the logic for the discount summary component.
30
+ *
31
+ * @param {Object} props
32
+ * @param {Array} props.data Discount data
33
+ * @returns {DiscountSummaryProps}
34
+ */
35
+ export const useDiscountSummary = props => {
36
+ const { data: discountData } = props;
37
+
38
+ const totalDiscount = getTotalDiscount(discountData);
39
+
40
+ const [expanded, setExpanded] = useState(false);
41
+
42
+ const handleClick = useCallback(() => {
43
+ setExpanded(value => !value);
44
+ }, [setExpanded]);
45
+
46
+ return {
47
+ totalDiscount,
48
+ discountData,
49
+ expanded,
50
+ handleClick
51
+ };
52
+ };
53
+
54
+ /** JSDocs type definitions */
55
+
56
+ /**
57
+ * @typedef {Object} DiscountSummaryProps
58
+ *
59
+ * @property {DiscountObject} discount Object containing discount information
60
+ * @property {Array} discountData Array of discounts
61
+ * @property {Boolean} expanded
62
+ * @property {Function} handleClick Click handler for toggling the expanded state
63
+ *
64
+ */
65
+
66
+ /**
67
+ * @typedef {Object} DiscountObject
68
+ *
69
+ * @property {String} currency Currency code
70
+ * @property {Number} value Discount amount
71
+ */
@@ -21,6 +21,7 @@ const flattenData = data => {
21
21
  total: data.cart.prices.grand_total,
22
22
  discounts: data.cart.prices.discounts,
23
23
  giftCards: data.cart.applied_gift_cards,
24
+ giftOptions: data.cart.prices.gift_options,
24
25
  taxes: data.cart.prices.applied_taxes,
25
26
  shipping: data.cart.shipping_addresses
26
27
  };
@@ -86,8 +87,9 @@ export const usePriceSummary = (props = {}) => {
86
87
  *
87
88
  * @property {String} subtotal Cart subtotal (excluding tax)
88
89
  * @property {String} total Cart grand total
89
- * @property {Array<Object>} discounts Discounts applied to the cart
90
+ * @property {Array<Object>} discounts Applied discounts to the cart
90
91
  * @property {Array<Object>} giftCards Gift cards applied to the cart
92
+ * @property {Array<Object>} giftOptions Gift Options applied to the cart
91
93
  * @property {Array<Object>} taxes Taxes applied to the cart
92
94
  * @property {Array<Object>} shipping Shipping addresses associated with this cart
93
95
  */
@@ -0,0 +1,8 @@
1
+ export const configurableThumbnailSourceResponse = {
2
+ data: {
3
+ storeConfig: {
4
+ store_code: 1,
5
+ configurable_thumbnail_source: 'parent'
6
+ }
7
+ }
8
+ };
@@ -74,7 +74,18 @@ const UPDATE_CONFIGURABLE_OPTIONS_MUTATION = gql`
74
74
  ${CartPageFragment}
75
75
  `;
76
76
 
77
+ const GET_CONFIGURABLE_THUMBNAIL_SOURCE = gql`
78
+ query getConfigurableThumbnailSource {
79
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
80
+ storeConfig {
81
+ store_code
82
+ configurable_thumbnail_source
83
+ }
84
+ }
85
+ `;
86
+
77
87
  export default {
88
+ getConfigurableThumbnailSourceQuery: GET_CONFIGURABLE_THUMBNAIL_SOURCE,
78
89
  getConfigurableOptionsQuery: GET_CONFIGURABLE_OPTIONS,
79
90
  updateQuantityMutation: UPDATE_QUANTITY_MUTATION,
80
91
  updateConfigurableOptionsMutation: UPDATE_CONFIGURABLE_OPTIONS_MUTATION
@@ -35,6 +35,7 @@ export const useProductForm = props => {
35
35
  const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
36
36
 
37
37
  const {
38
+ getConfigurableThumbnailSourceQuery,
38
39
  getConfigurableOptionsQuery,
39
40
  updateConfigurableOptionsMutation,
40
41
  updateQuantityMutation
@@ -87,6 +88,13 @@ export const useProductForm = props => {
87
88
  }
88
89
  });
89
90
 
91
+ const { data: storeConfigData } = useQuery(
92
+ getConfigurableThumbnailSourceQuery,
93
+ {
94
+ fetchPolicy: 'cache-and-network'
95
+ }
96
+ );
97
+
90
98
  const handleOptionSelection = useCallback(
91
99
  (optionId, selection) => {
92
100
  const nextOptionSelections = new Map([...optionSelections]);
@@ -137,6 +145,10 @@ export const useProductForm = props => {
137
145
  }
138
146
  }, [cartItem, configItem, configurableOptionCodes, optionSelections]);
139
147
 
148
+ const configurableThumbnailSource = useMemo(() => {
149
+ return storeConfigData?.storeConfig?.configurable_thumbnail_source;
150
+ }, [storeConfigData]);
151
+
140
152
  useEffect(() => {
141
153
  let variantPrice = null;
142
154
 
@@ -208,7 +220,8 @@ export const useProductForm = props => {
208
220
  isLoading: !!loading,
209
221
  isSaving,
210
222
  isDialogOpen: cartItem !== null,
211
- handleClose
223
+ handleClose,
224
+ configurableThumbnailSource
212
225
  };
213
226
  };
214
227
 
@@ -228,4 +241,5 @@ export const useProductForm = props => {
228
241
  * @property {boolean} isSaving True if the form is saving data. False otherwise.
229
242
  * @property {boolean} isDialogOpen True if the form is visible. False otherwise.
230
243
  * @property {function} handleClose A callback function for handling form closing
244
+ * @property {String} configurableThumbnailSource A string indicating which thumbnail should be used for configurable products
231
245
  */
@@ -5,6 +5,7 @@ import mergeOperations from '../../../util/shallowMerge';
5
5
  import { useUserContext } from '../../../context/user';
6
6
  import { useCartContext } from '../../../context/cart';
7
7
  import { useAwaitQuery } from '../../../hooks/useAwaitQuery';
8
+ import { useGoogleReCaptcha } from '../../../hooks/useGoogleReCaptcha';
8
9
 
9
10
  import DEFAULT_OPERATIONS from './createAccount.gql';
10
11
 
@@ -23,7 +24,8 @@ import DEFAULT_OPERATIONS from './createAccount.gql';
23
24
  * errors: Map,
24
25
  * handleSubmit: function,
25
26
  * isDisabled: boolean,
26
- * initialValues: object
27
+ * initialValues: object,
28
+ * recaptchaWidgetProps: { containerElement: function, shouldRender: boolean }
27
29
  * }}
28
30
  */
29
31
  export const useCreateAccount = props => {
@@ -62,10 +64,22 @@ export const useCreateAccount = props => {
62
64
  const fetchUserDetails = useAwaitQuery(getCustomerQuery);
63
65
  const fetchCartDetails = useAwaitQuery(getCartDetailsQuery);
64
66
 
67
+ const {
68
+ generateReCaptchaData,
69
+ recaptchaLoading,
70
+ recaptchaWidgetProps
71
+ } = useGoogleReCaptcha({
72
+ currentForm: 'CUSTOMER_CREATE',
73
+ formAction: 'createAccount'
74
+ });
75
+
65
76
  const handleSubmit = useCallback(
66
77
  async formValues => {
67
78
  setIsSubmitting(true);
68
79
  try {
80
+ // Get reCaptchaV3 Data for createAccount mutation
81
+ const recaptchaDataForCreateAccount = await generateReCaptchaData();
82
+
69
83
  // Create the account and then sign in.
70
84
  await createAccount({
71
85
  variables: {
@@ -74,13 +88,19 @@ export const useCreateAccount = props => {
74
88
  lastname: formValues.customer.lastname,
75
89
  password: formValues.password,
76
90
  is_subscribed: !!formValues.subscribe
77
- }
91
+ },
92
+ ...recaptchaDataForCreateAccount
78
93
  });
94
+
95
+ // Get reCaptchaV3 Data for signIn mutation
96
+ const recaptchaDataForSignIn = await generateReCaptchaData();
97
+
79
98
  const signInResponse = await signIn({
80
99
  variables: {
81
100
  email: formValues.customer.email,
82
101
  password: formValues.password
83
- }
102
+ },
103
+ ...recaptchaDataForSignIn
84
104
  });
85
105
  const token = signInResponse.data.generateCustomerToken.token;
86
106
  await setToken(token);
@@ -117,6 +137,7 @@ export const useCreateAccount = props => {
117
137
  fetchCartDetails,
118
138
  fetchCartId,
119
139
  fetchUserDetails,
140
+ generateReCaptchaData,
120
141
  getCartDetails,
121
142
  getUserDetails,
122
143
  onSubmit,
@@ -147,7 +168,8 @@ export const useCreateAccount = props => {
147
168
  return {
148
169
  errors,
149
170
  handleSubmit,
150
- isDisabled: isSubmitting || isGettingDetails,
151
- initialValues: sanitizedInitialValues
171
+ isDisabled: isSubmitting || isGettingDetails || recaptchaLoading,
172
+ initialValues: sanitizedInitialValues,
173
+ recaptchaWidgetProps
152
174
  };
153
175
  };
@@ -6,6 +6,7 @@ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
6
6
  import { useCartContext } from '../../../context/cart';
7
7
 
8
8
  import DEFAULT_OPERATIONS from './creditCard.gql';
9
+ import { useGoogleReCaptcha } from '../../../hooks/useGoogleReCaptcha';
9
10
 
10
11
  const getRegion = region => {
11
12
  return region.region_id || region.label || region.code;
@@ -107,6 +108,15 @@ export const useCreditCard = props => {
107
108
  setCreditCardDetailsOnCartMutation
108
109
  } = operations;
109
110
 
111
+ const {
112
+ recaptchaLoading,
113
+ generateReCaptchaData,
114
+ recaptchaWidgetProps
115
+ } = useGoogleReCaptcha({
116
+ currentForm: 'BRAINTREE',
117
+ formAction: 'braintree'
118
+ });
119
+
110
120
  /**
111
121
  * Definitions
112
122
  */
@@ -121,9 +131,9 @@ export const useCreditCard = props => {
121
131
  * payment flow.
122
132
  *
123
133
  * `0` No call made yet
124
- * `1` Billing address mutation intiated
125
- * `2` Braintree nonce requsted
126
- * `3` Payment information mutation intiated
134
+ * `1` Billing address mutation initiated
135
+ * `2` Braintree nonce requested
136
+ * `3` Payment information mutation initiated
127
137
  * `4` All mutations done
128
138
  */
129
139
  const [stepNumber, setStepNumber] = useState(0);
@@ -133,7 +143,10 @@ export const useCreditCard = props => {
133
143
  const { validate: validateBillingAddressForm } = useFormApi();
134
144
  const [{ cartId }] = useCartContext();
135
145
 
136
- const isLoading = isDropinLoading || (stepNumber >= 1 && stepNumber <= 3);
146
+ const isLoading =
147
+ isDropinLoading ||
148
+ recaptchaLoading ||
149
+ (stepNumber >= 1 && stepNumber <= 3);
137
150
 
138
151
  const { data: billingAddressData } = useQuery(getBillingAddressQuery, {
139
152
  skip: !cartId,
@@ -306,17 +319,24 @@ export const useCreditCard = props => {
306
319
  * this case `braintree`.
307
320
  */
308
321
  const updateCCDetailsOnCart = useCallback(
309
- braintreeNonce => {
310
- const { nonce } = braintreeNonce;
311
- updateCCDetails({
312
- variables: {
313
- cartId,
314
- paymentMethod: 'braintree',
315
- paymentNonce: nonce
316
- }
317
- });
322
+ async braintreeNonce => {
323
+ try {
324
+ const { nonce } = braintreeNonce;
325
+ const reCaptchaData = await generateReCaptchaData();
326
+
327
+ await updateCCDetails({
328
+ variables: {
329
+ cartId,
330
+ paymentMethod: 'braintree',
331
+ paymentNonce: nonce
332
+ },
333
+ ...reCaptchaData
334
+ });
335
+ } catch (error) {
336
+ // Error is logged by apollo link - no need to double log.
337
+ }
318
338
  },
319
- [updateCCDetails, cartId]
339
+ [updateCCDetails, cartId, generateReCaptchaData]
320
340
  );
321
341
 
322
342
  /**
@@ -545,6 +565,7 @@ export const useCreditCard = props => {
545
565
  initialValues,
546
566
  shippingAddressCountry,
547
567
  shouldTeardownDropin,
548
- resetShouldTeardownDropin
568
+ resetShouldTeardownDropin,
569
+ recaptchaWidgetProps
549
570
  };
550
571
  };
@@ -14,6 +14,7 @@ import mergeOperations from '../../util/shallowMerge';
14
14
  import DEFAULT_OPERATIONS from './checkoutPage.gql.js';
15
15
 
16
16
  import CheckoutError from './CheckoutError';
17
+ import { useGoogleReCaptcha } from '../../hooks/useGoogleReCaptcha';
17
18
 
18
19
  export const CHECKOUT_STEP = {
19
20
  SHIPPING_ADDRESS: 1,
@@ -74,6 +75,11 @@ export const useCheckoutPage = (props = {}) => {
74
75
  placeOrderMutation
75
76
  } = operations;
76
77
 
78
+ const { generateReCaptchaData, recaptchaWidgetProps } = useGoogleReCaptcha({
79
+ currentForm: 'PLACE_ORDER',
80
+ formAction: 'placeOrder'
81
+ });
82
+
77
83
  const [reviewOrderButtonClicked, setReviewOrderButtonClicked] = useState(
78
84
  false
79
85
  );
@@ -83,6 +89,9 @@ export const useCheckoutPage = (props = {}) => {
83
89
 
84
90
  const apolloClient = useApolloClient();
85
91
  const [isUpdating, setIsUpdating] = useState(false);
92
+ const [placeOrderButtonClicked, setPlaceOrderButtonClicked] = useState(
93
+ false
94
+ );
86
95
  const [activeContent, setActiveContent] = useState('checkout');
87
96
  const [checkoutStep, setCheckoutStep] = useState(
88
97
  CHECKOUT_STEP.SHIPPING_ADDRESS
@@ -227,6 +236,7 @@ export const useCheckoutPage = (props = {}) => {
227
236
  cartId
228
237
  }
229
238
  });
239
+ setPlaceOrderButtonClicked(true);
230
240
  setIsPlacingOrder(true);
231
241
  }, [cartId, getOrderDetails]);
232
242
 
@@ -240,10 +250,13 @@ export const useCheckoutPage = (props = {}) => {
240
250
  useEffect(() => {
241
251
  async function placeOrderAndCleanup() {
242
252
  try {
253
+ const reCaptchaData = await generateReCaptchaData();
254
+
243
255
  await placeOrder({
244
256
  variables: {
245
257
  cartId
246
- }
258
+ },
259
+ ...reCaptchaData
247
260
  });
248
261
  // Cleanup stale cart and customer info.
249
262
  await removeCart();
@@ -257,8 +270,7 @@ export const useCheckoutPage = (props = {}) => {
257
270
  'An error occurred during when placing the order',
258
271
  err
259
272
  );
260
- setReviewOrderButtonClicked(false);
261
- setCheckoutStep(CHECKOUT_STEP.PAYMENT);
273
+ setPlaceOrderButtonClicked(false);
262
274
  }
263
275
  }
264
276
 
@@ -271,6 +283,7 @@ export const useCheckoutPage = (props = {}) => {
271
283
  cartId,
272
284
  createCart,
273
285
  fetchCartId,
286
+ generateReCaptchaData,
274
287
  orderDetailsData,
275
288
  placeOrder,
276
289
  removeCart,
@@ -299,6 +312,7 @@ export const useCheckoutPage = (props = {}) => {
299
312
  (placeOrderData && placeOrderData.placeOrder.order.order_number) ||
300
313
  null,
301
314
  placeOrderLoading,
315
+ placeOrderButtonClicked,
302
316
  setCheckoutStep,
303
317
  setGuestSignInUsername,
304
318
  setIsUpdating,
@@ -312,6 +326,7 @@ export const useCheckoutPage = (props = {}) => {
312
326
  resetReviewOrderButtonClicked,
313
327
  handleReviewOrder,
314
328
  reviewOrderButtonClicked,
329
+ recaptchaWidgetProps,
315
330
  toggleAddressBookContent,
316
331
  toggleSignInContent
317
332
  };
@@ -0,0 +1,4 @@
1
+ # Save cart conditions data in cache
2
+ extend type DynamicBlocks {
3
+ salesRulesData: String
4
+ }
@@ -0,0 +1,113 @@
1
+ import { gql } from '@apollo/client';
2
+
3
+ export const GET_CMS_DYNAMIC_BLOCKS = gql`
4
+ query GetCmsDynamicBlocks(
5
+ $cartId: String
6
+ $productId: ID
7
+ $type: DynamicBlockTypeEnum!
8
+ $locations: [DynamicBlockLocationEnum]
9
+ $uids: [ID]!
10
+ ) {
11
+ dynamicBlocks(
12
+ input: {
13
+ cart_id: $cartId
14
+ product_uid: $productId
15
+ dynamic_block_uids: $uids
16
+ locations: $locations
17
+ type: $type
18
+ }
19
+ ) {
20
+ items {
21
+ content {
22
+ html
23
+ }
24
+ uid
25
+ }
26
+ salesRulesData @client
27
+ }
28
+ }
29
+ `;
30
+
31
+ export const GET_SALES_RULES_DATA = gql`
32
+ query SalesRulesDataQuery($cartId: String!) {
33
+ cart(cart_id: $cartId) {
34
+ id
35
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
36
+ items {
37
+ uid
38
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
39
+ product {
40
+ uid
41
+ ... on PhysicalProductInterface {
42
+ weight
43
+ }
44
+ }
45
+ quantity
46
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
47
+ ... on ConfigurableCartItem {
48
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
49
+ configured_variant {
50
+ uid
51
+ ... on PhysicalProductInterface {
52
+ weight
53
+ }
54
+ }
55
+ }
56
+ }
57
+ prices {
58
+ subtotal_excluding_tax {
59
+ value
60
+ }
61
+ subtotal_including_tax {
62
+ value
63
+ }
64
+ }
65
+ selected_payment_method {
66
+ code
67
+ }
68
+ shipping_addresses {
69
+ country {
70
+ code
71
+ }
72
+ postcode
73
+ region {
74
+ code
75
+ region_id
76
+ }
77
+ street
78
+ selected_shipping_method {
79
+ method_code
80
+ }
81
+ }
82
+ total_quantity
83
+ }
84
+ }
85
+ `;
86
+
87
+ export const GET_STORE_CONFIG_DATA = gql`
88
+ query getStoreConfigData {
89
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
90
+ storeConfig {
91
+ product_url_suffix
92
+ }
93
+ }
94
+ `;
95
+
96
+ export const GET_PRODUCT_DETAIL_QUERY = gql`
97
+ query getProductDetailForProductPage($urlKey: String!) {
98
+ products(filter: { url_key: { eq: $urlKey } }) {
99
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
100
+ items {
101
+ uid
102
+ url_key
103
+ }
104
+ }
105
+ }
106
+ `;
107
+
108
+ export default {
109
+ getCmsDynamicBlocksQuery: GET_CMS_DYNAMIC_BLOCKS,
110
+ getSalesRulesDataQuery: GET_SALES_RULES_DATA,
111
+ getStoreConfigData: GET_STORE_CONFIG_DATA,
112
+ getProductDetailQuery: GET_PRODUCT_DETAIL_QUERY
113
+ };