@graphcommerce/magento-cart 4.13.3 → 4.14.0-canary.10

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 CHANGED
@@ -1,8 +1,32 @@
1
1
  # Change Log
2
2
 
3
- ## 4.13.3
3
+ ## 4.14.0-canary.10
4
4
 
5
- ## 4.13.2
5
+ ## 4.14.0-canary.9
6
+
7
+ ## 4.14.0-canary.8
8
+
9
+ ## 4.14.0-canary.7
10
+
11
+ ## 4.14.0-canary.6
12
+
13
+ ## 4.14.0-canary.5
14
+
15
+ ## 4.14.0-canary.4
16
+
17
+ ### Minor Changes
18
+
19
+ - [#1733](https://github.com/graphcommerce-org/graphcommerce/pull/1733) [`761bd2832`](https://github.com/graphcommerce-org/graphcommerce/commit/761bd2832f115afc8b95bedbf479266309dd5acc) - ApolloLinks, typePolicies and migration scripts are now handled with plugins on the new library component `<GraphQLProvider/>`. Hygraph's, Magento Cart, Customer, Store, Wishlist and Magento GraphQL are all migrated to be using plugins.
20
+
21
+ If you are using custom `links` / `policies` / `migrations` you can pass them as props to the `<GraphQLProvider/>` or create your own local plugin. ([@paales](https://github.com/paales))
22
+
23
+ ## 4.14.0-canary.3
24
+
25
+ ## 4.14.0-canary.2
26
+
27
+ ## 4.13.2-canary.1
28
+
29
+ ## 4.13.2-canary.0
6
30
 
7
31
  ## 4.13.1
8
32
 
@@ -3,12 +3,14 @@ import { iconChevronRight, IconSvg, extendableComponent } from '@graphcommerce/n
3
3
  import { Trans } from '@lingui/react'
4
4
  import { Box, Button, ButtonProps, SxProps, Theme } from '@mui/material'
5
5
  import PageLink from 'next/link'
6
+ import React from 'react'
6
7
  import { CartStartCheckoutFragment } from './CartStartCheckout.gql'
7
8
 
8
9
  export type CartStartCheckoutProps = CartStartCheckoutFragment & {
9
10
  children?: React.ReactNode
10
11
  sx?: SxProps<Theme>
11
12
  buttonProps?: ButtonProps<'button'>
13
+ onStart?: (e: React.MouseEvent<HTMLButtonElement>, cart: CartStartCheckoutFragment) => void
12
14
  }
13
15
 
14
16
  const name = 'CartStartCheckout' as const
@@ -21,17 +23,20 @@ const parts = [
21
23
  const { classes } = extendableComponent(name, parts)
22
24
 
23
25
  export function CartStartCheckout(props: CartStartCheckoutProps) {
24
- const { prices, children, buttonProps, sx = [] } = props
26
+ const {
27
+ children,
28
+ onStart,
29
+ buttonProps: { onClick, ...buttonProps } = {},
30
+ sx = [],
31
+ ...cart
32
+ } = props
25
33
 
26
- const hasTotals = (prices?.grand_total?.value ?? 0) > 0
34
+ const hasTotals = (cart.prices?.grand_total?.value ?? 0) > 0
27
35
  return (
28
36
  <Box
29
37
  className={classes.checkoutButtonContainer}
30
38
  sx={[
31
- (theme) => ({
32
- textAlign: 'center',
33
- my: theme.spacings.md,
34
- }),
39
+ (theme) => ({ textAlign: 'center', my: theme.spacings.md }),
35
40
  ...(Array.isArray(sx) ? sx : [sx]),
36
41
  ]}
37
42
  >
@@ -45,6 +50,11 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
45
50
  className={classes.checkoutButton}
46
51
  endIcon={<IconSvg src={iconChevronRight} />}
47
52
  {...buttonProps}
53
+ onClick={(e) => {
54
+ onClick?.(e)
55
+ onStart?.(e, cart)
56
+ return onClick?.(e)
57
+ }}
48
58
  disabled={!hasTotals || buttonProps?.disabled}
49
59
  >
50
60
  <Box
@@ -59,7 +69,7 @@ export function CartStartCheckout(props: CartStartCheckoutProps) {
59
69
  </Box>{' '}
60
70
  {hasTotals && (
61
71
  <span className={classes.checkoutMoney}>
62
- <Money {...prices?.grand_total} />
72
+ <Money {...cart.prices?.grand_total} />
63
73
  </span>
64
74
  )}
65
75
  </Button>
@@ -0,0 +1,45 @@
1
+ import { iconChevronRight, IconSvg, LinkOrButton, LinkOrButtonProps } from '@graphcommerce/next-ui'
2
+ import { Trans } from '@lingui/react'
3
+ import { SxProps, Theme } from '@mui/material'
4
+ import PageLink from 'next/link'
5
+ import React from 'react'
6
+ import { CartStartCheckoutFragment } from './CartStartCheckout.gql'
7
+
8
+ export type CartStartCheckoutLinkOrButtonProps = CartStartCheckoutFragment & {
9
+ children?: React.ReactNode
10
+ sx?: SxProps<Theme>
11
+ onStart?: (
12
+ e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
13
+ cart: CartStartCheckoutFragment,
14
+ ) => void
15
+ linkOrButtonProps?: LinkOrButtonProps
16
+ }
17
+
18
+ export function CartStartCheckoutLinkOrButton(props: CartStartCheckoutLinkOrButtonProps) {
19
+ const {
20
+ children,
21
+ onStart,
22
+ linkOrButtonProps: { onClick, button, ...linkOrButtonProps } = {},
23
+ ...cart
24
+ } = props
25
+
26
+ const hasTotals = (cart.prices?.grand_total?.value ?? 0) > 0
27
+
28
+ return (
29
+ <PageLink href='/checkout' passHref>
30
+ <LinkOrButton
31
+ onClick={(e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
32
+ onClick?.(e)
33
+ onStart?.(e, cart)
34
+ }}
35
+ button={{ variant: 'pill', ...button }}
36
+ disabled={!hasTotals}
37
+ color='secondary'
38
+ endIcon={<IconSvg src={iconChevronRight} />}
39
+ {...linkOrButtonProps}
40
+ >
41
+ <Trans id='Next' />
42
+ </LinkOrButton>
43
+ </PageLink>
44
+ )
45
+ }
@@ -0,0 +1,2 @@
1
+ export * from './CartStartCheckout'
2
+ export * from './CartStartCheckoutLinkOrButton'
@@ -6,7 +6,7 @@ export * from './CartAgreementsForm/CartAgreements.gql'
6
6
  export * from './CartAgreementsForm/CartAgreementsForm'
7
7
  export * from './CartFab/CartFab'
8
8
  export * from './CartItemSummary/CartItemSummary'
9
- export * from './CartStartCheckout/CartStartCheckout'
9
+ export * from './CartStartCheckout'
10
10
  export * from './CartSummary/CartSummary'
11
11
  export * from './CartSummary/CartSummary.gql'
12
12
  export * from './CartTotals/CartTotals'
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  ApolloClient,
3
3
  fromPromise,
4
+ globalApolloClient,
4
5
  NormalizedCacheObject,
5
6
  onError,
6
7
  Operation,
@@ -19,50 +20,51 @@ function errorIsIncluded(errorPath: readonly (string | number)[] | undefined, ke
19
20
  return keys.some((value) => value === error)
20
21
  }
21
22
 
22
- export const createCartErrorLink = (clientRef: RefObject<ApolloClient<NormalizedCacheObject>>) =>
23
- onError(({ graphQLErrors, operation, forward }) => {
24
- if (!clientRef.current) return undefined
23
+ export const cartErrorLink = onError(({ graphQLErrors, operation, forward }) => {
24
+ if (!globalApolloClient.current) return undefined
25
25
 
26
- const client = clientRef.current
27
- const { cache } = client
26
+ const client = globalApolloClient.current
27
+ const { cache } = client
28
28
 
29
- if (!isCartOperation(operation) || !graphQLErrors) return undefined
29
+ if (!isCartOperation(operation) || !graphQLErrors) return undefined
30
30
 
31
- const cartErr = graphQLErrors.find(
32
- (err) =>
33
- err.extensions?.category === 'graphql-no-such-entity' &&
34
- errorIsIncluded(err.path, [
35
- 'cart',
36
- 'addProductsToCart',
31
+ const cartErr = graphQLErrors.find(
32
+ (err) =>
33
+ err.extensions?.category === 'graphql-no-such-entity' &&
34
+ errorIsIncluded(err.path, [
35
+ 'cart',
36
+ 'addProductsToCart',
37
37
 
38
- /**
39
- * These mutations can also throw the graphql-no-such-entity exception, however, we're not
40
- * sure if it also throws for other types of entities.
41
- */
42
- // 'removeItemFromCart',
43
- // 'setBillingAddressOnCart',
44
- // 'setGuestEmailOnCart',
45
- // 'setPaymentMethodOnCart',
46
- // 'setShippingAddressesOnCart',
47
- // 'setShippingMethodsOnCart',
48
- // 'updateCartItems',
49
- // 'applyCouponToCart',
50
- // 'removeCouponFromCart'
51
- ]),
52
- )
38
+ /**
39
+ * These mutations can also throw the graphql-no-such-entity exception, however, we're not
40
+ * sure if it also throws for other types of entities.
41
+ */
42
+ // 'removeItemFromCart',
43
+ // 'setBillingAddressOnCart',
44
+ // 'setGuestEmailOnCart',
45
+ // 'setPaymentMethodOnCart',
46
+ // 'setShippingAddressesOnCart',
47
+ // 'setShippingMethodsOnCart',
48
+ // 'updateCartItems',
49
+ // 'applyCouponToCart',
50
+ // 'removeCouponFromCart'
51
+ ]),
52
+ )
53
53
 
54
- if (!cartErr) return undefined
54
+ if (!cartErr) return undefined
55
55
 
56
- return fromPromise(client?.mutate({ mutation: CreateEmptyCartDocument }))
57
- .filter((value) => Boolean(value))
58
- .flatMap((cartData) => {
59
- const cartId = cartData.data?.createEmptyCart
60
- if (!cartId) return forward(operation)
56
+ return fromPromise(client?.mutate({ mutation: CreateEmptyCartDocument }))
57
+ .filter((value) => Boolean(value))
58
+ .flatMap((cartData) => {
59
+ const cartId = cartData.data?.createEmptyCart
60
+ if (!cartId) return forward(operation)
61
61
 
62
- writeCartId(cache, cartId)
63
- operation.variables = { ...operation.variables, cartId }
62
+ writeCartId(cache, cartId)
63
+ operation.variables = { ...operation.variables, cartId }
64
64
 
65
- // retry the request, returning the new observable
66
- return forward(operation)
67
- })
68
- })
65
+ // retry the request, returning the new observable
66
+ return forward(operation)
67
+ })
68
+ })
69
+
70
+ export const createCartErrorLink = () => cartErrorLink
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-cart",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "4.13.3",
5
+ "version": "4.14.0-canary.10",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -18,17 +18,17 @@
18
18
  "@playwright/test": "^1.21.1"
19
19
  },
20
20
  "dependencies": {
21
- "@graphcommerce/ecommerce-ui": "4.30.2",
22
- "@graphcommerce/framer-utils": "4.30.2",
23
- "@graphcommerce/framer-next-pages": "4.30.2",
24
- "@graphcommerce/framer-scroller": "4.30.2",
25
- "@graphcommerce/graphql": "4.30.2",
26
- "@graphcommerce/image": "4.30.2",
27
- "@graphcommerce/magento-customer": "4.13.3",
28
- "@graphcommerce/magento-graphql": "4.13.3",
29
- "@graphcommerce/magento-store": "4.13.3",
30
- "@graphcommerce/next-ui": "4.30.2",
31
- "@graphcommerce/react-hook-form": "4.30.2"
21
+ "@graphcommerce/ecommerce-ui": "4.31.0-canary.6",
22
+ "@graphcommerce/framer-utils": "4.31.0-canary.6",
23
+ "@graphcommerce/framer-next-pages": "4.31.0-canary.6",
24
+ "@graphcommerce/framer-scroller": "4.31.0-canary.6",
25
+ "@graphcommerce/graphql": "4.31.0-canary.6",
26
+ "@graphcommerce/image": "4.31.0-canary.6",
27
+ "@graphcommerce/magento-customer": "4.14.0-canary.10",
28
+ "@graphcommerce/magento-graphql": "4.14.0-canary.10",
29
+ "@graphcommerce/magento-store": "4.14.0-canary.10",
30
+ "@graphcommerce/next-ui": "4.31.0-canary.6",
31
+ "@graphcommerce/react-hook-form": "4.31.0-canary.6"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@lingui/react": "^3.13.2",
@@ -0,0 +1,21 @@
1
+ import { GraphQLProviderProps } from '@graphcommerce/graphql'
2
+ import type { PluginProps } from '@graphcommerce/next-config'
3
+ import { cartErrorLink } from '../link/createCartErrorLink'
4
+ import { cartTypePolicies, migrateCart } from '../typePolicies'
5
+
6
+ export const component = 'GraphQLProvider'
7
+ export const exported = '@graphcommerce/graphql'
8
+
9
+ function MagentoCartGraphqlProvider(props: PluginProps<GraphQLProviderProps>) {
10
+ const { Prev, links = [], policies = [], migrations = [], ...rest } = props
11
+ return (
12
+ <Prev
13
+ {...rest}
14
+ links={[...links, cartErrorLink]}
15
+ policies={[...policies, cartTypePolicies]}
16
+ migrations={[...migrations, migrateCart]}
17
+ />
18
+ )
19
+ }
20
+
21
+ export const Plugin = MagentoCartGraphqlProvider