@graphcommerce/magento-cart 8.0.3-canary.3 → 8.1.0-canary.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 CHANGED
@@ -1,16 +1,6 @@
1
1
  # Change Log
2
2
 
3
- ## 8.0.3-canary.3
4
-
5
- ## 8.0.3-canary.2
6
-
7
- ### Patch Changes
8
-
9
- - [#2205](https://github.com/graphcommerce-org/graphcommerce/pull/2205) [`d67c89d`](https://github.com/graphcommerce-org/graphcommerce/commit/d67c89d464a60f0e2618dab670b63a39f6291341) - Deprecate the allowUrl option for useCartQuery, it was already enabled by default and should never be set to false.
10
- ([@paales](https://github.com/paales))
11
-
12
- - [#2205](https://github.com/graphcommerce-org/graphcommerce/pull/2205) [`3fbf3da`](https://github.com/graphcommerce-org/graphcommerce/commit/3fbf3da8a67f2fbaa7fa974a37cbbf34613844e4) - Solve an issue where the user would be presented with the Session expired dialog when the user would be logging in during the checkout process.
13
- ([@paales](https://github.com/paales))
3
+ ## 8.1.0-canary.2
14
4
 
15
5
  ## 8.0.3-canary.1
16
6
 
@@ -1,6 +1,6 @@
1
1
  import { useApolloClient } from '@graphcommerce/graphql'
2
2
  import { Button } from '@mui/material'
3
- import { readCartId, writeCartId } from '../../hooks'
3
+ import { CurrentCartIdDocument } from '../../hooks/CurrentCartId.gql'
4
4
 
5
5
  export function CartDebugger() {
6
6
  const client = useApolloClient()
@@ -12,14 +12,24 @@ export function CartDebugger() {
12
12
  variant='text'
13
13
  size='small'
14
14
  onClick={() => {
15
- const currentCartId = readCartId(client.cache)
16
- if (!currentCartId) {
15
+ const currentCardId = client.readQuery({ query: CurrentCartIdDocument })
16
+ if (!currentCardId?.currentCartId) {
17
17
  // eslint-disable-next-line no-console
18
18
  console.log('No customerToken available, nothing to break')
19
19
  } else {
20
20
  // eslint-disable-next-line no-console
21
21
  console.log(`Changing current token to a random one`)
22
- writeCartId(client.cache, `${Math.random().toString(36).slice(2)}random-cardId`)
22
+
23
+ client.writeQuery({
24
+ query: CurrentCartIdDocument,
25
+ data: {
26
+ currentCartId: {
27
+ ...currentCardId.currentCartId,
28
+ id: `${Math.random().toString(36).slice(2)}random-cardId`,
29
+ },
30
+ },
31
+ broadcast: true,
32
+ })
23
33
  }
24
34
  }}
25
35
  >
@@ -38,7 +38,10 @@ type OrderSummaryProps = ActionCardLayoutProps & {
38
38
 
39
39
  export function CartItemSummary(props: OrderSummaryProps) {
40
40
  const { sx = [], size, layout = 'list', itemProps, ...cardLayout } = props
41
- const { data } = useCartQuery(CartItemSummaryDocument, { fetchPolicy: 'cache-only' })
41
+ const { data } = useCartQuery(CartItemSummaryDocument, {
42
+ allowUrl: true,
43
+ fetchPolicy: 'cache-only',
44
+ })
42
45
 
43
46
  if (!data?.cart) return null
44
47
 
@@ -82,7 +85,7 @@ export function CartItemSummary(props: OrderSummaryProps) {
82
85
  className={classes.scrollerContainer}
83
86
  {...cardLayout}
84
87
  >
85
- {(items ?? []).filter(nonNullable).map((item) => (
88
+ {items?.filter(nonNullable).map((item) => (
86
89
  <CartItemActionCard
87
90
  readOnly
88
91
  key={item.uid}
@@ -31,7 +31,7 @@ const { withState } = extendableComponent<OwnerProps, typeof name, typeof parts>
31
31
  * @see https://github.com/magento/magento2/issues/33848
32
32
  */
33
33
  export function CartTotals(props: CartTotalsProps) {
34
- const { data } = useCartQuery(GetCartTotalsDocument)
34
+ const { data } = useCartQuery(GetCartTotalsDocument, { allowUrl: true })
35
35
  const { containerMargin, additionalSubtotals, additionalTotals, sx = [] } = props
36
36
 
37
37
  const classes = withState({ containerMargin })
@@ -2,6 +2,5 @@ query CurrentCartId {
2
2
  currentCartId @client {
3
3
  __typename
4
4
  id
5
- locked
6
5
  }
7
6
  }
@@ -4,7 +4,6 @@ extend type Query {
4
4
 
5
5
  type CurrentCartId {
6
6
  id: String
7
- locked: Boolean
8
7
  }
9
8
 
10
9
  input RegisterCartIdInput {
@@ -2,5 +2,6 @@ query CustomerCart {
2
2
  customerCart {
3
3
  id
4
4
  __typename
5
+ ...CartItemCountChanged
5
6
  }
6
7
  }
@@ -1,6 +1,7 @@
1
- mutation MergeCarts($sourceCartId: String!, $destinationCartId: String!) {
1
+ mutation UseMergeCustomerCart($sourceCartId: String!, $destinationCartId: String!) {
2
2
  mergeCarts(source_cart_id: $sourceCartId, destination_cart_id: $destinationCartId) {
3
3
  __typename
4
4
  id
5
+ ...CartItemCountChanged
5
6
  }
6
7
  }
@@ -8,26 +8,11 @@ export const CART_ID_COOKIE = 'cart'
8
8
  export function writeCartId(cache: ApolloCache<object>, id: string | null = null) {
9
9
  cache.writeQuery({
10
10
  query: CurrentCartIdDocument,
11
- data: { currentCartId: { __typename: 'CurrentCartId', locked: false, id } },
11
+ data: { currentCartId: { __typename: 'CurrentCartId', id } },
12
12
  broadcast: true,
13
13
  })
14
14
  }
15
15
 
16
- export function readCartId(cache: ApolloCache<object>) {
17
- return cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId
18
- }
19
-
20
- export function cartLock(cache: ApolloCache<object>, locked: boolean) {
21
- const currentCartId = cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId
22
- if (currentCartId?.id && currentCartId.locked !== locked) {
23
- cache.writeQuery({
24
- query: CurrentCartIdDocument,
25
- data: { currentCartId: { ...currentCartId, locked } },
26
- broadcast: true,
27
- })
28
- }
29
- }
30
-
31
16
  export function useAssignCurrentCartId() {
32
17
  const { cache } = useApolloClient()
33
18
 
@@ -1,14 +1,16 @@
1
1
  import { useApolloClient } from '@graphcommerce/graphql'
2
2
  import { i18n } from '@lingui/core'
3
3
  import { CreateEmptyCartDocument } from './CreateEmptyCart.gql'
4
- import { readCartId, useAssignCurrentCartId } from './useAssignCurrentCartId'
4
+ import { CurrentCartIdDocument } from './CurrentCartId.gql'
5
+ import { useAssignCurrentCartId } from './useAssignCurrentCartId'
5
6
 
6
7
  export function useCartIdCreate() {
7
8
  const client = useApolloClient()
8
9
  const assignCurrentCartId = useAssignCurrentCartId()
9
10
 
10
11
  return async (): Promise<string> => {
11
- const currentCartId = readCartId(client.cache)?.id
12
+ const currentCartId = client.cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId
13
+ ?.id
12
14
 
13
15
  if (currentCartId) return currentCartId
14
16
 
@@ -15,21 +15,18 @@ import { useCurrentCartId } from './useCurrentCartId'
15
15
  export function useCartQuery<Q, V extends { cartId: string; [index: string]: unknown }>(
16
16
  document: TypedDocumentNode<Q, V>,
17
17
  options: QueryHookOptions<Q, Omit<V, 'cartId'>> & {
18
- /**
19
- * @deprecated Not used anymore, when the cart_id is in the URL, it will always be used.
20
- */
21
18
  allowUrl?: boolean
22
19
  } = {},
23
20
  ) {
24
- const { allowUrl, ...queryOptions } = options
21
+ const { allowUrl = true, ...queryOptions } = options
25
22
  const router = useRouter()
26
- const { currentCartId, locked } = useCurrentCartId()
23
+ const { currentCartId } = useCurrentCartId()
27
24
 
28
25
  const urlCartId = router.query.cart_id
29
- const usingUrl = typeof urlCartId === 'string'
26
+ const usingUrl = allowUrl && typeof urlCartId === 'string'
30
27
  const cartId = usingUrl ? urlCartId : currentCartId
31
28
 
32
- if (usingUrl || locked) queryOptions.fetchPolicy = 'cache-only'
29
+ if (usingUrl) queryOptions.fetchPolicy = 'cache-first'
33
30
 
34
31
  if (usingUrl && typeof queryOptions.returnPartialData === 'undefined')
35
32
  queryOptions.returnPartialData = true
@@ -37,5 +34,10 @@ export function useCartQuery<Q, V extends { cartId: string; [index: string]: unk
37
34
  queryOptions.variables = { cartId, ...options?.variables } as V
38
35
  queryOptions.skip = queryOptions?.skip || !cartId
39
36
 
40
- return useQuery(document, queryOptions as QueryHookOptions<Q, V>)
37
+ const result = useQuery(document, queryOptions as QueryHookOptions<Q, V>)
38
+
39
+ return {
40
+ ...result,
41
+ // error: called && !currentCartId ? noCartError : result.error,
42
+ }
41
43
  }
@@ -1,12 +1,20 @@
1
1
  import { useApolloClient } from '@graphcommerce/graphql'
2
2
  import { cookie } from '@graphcommerce/next-ui'
3
+ import { CurrentCartIdDocument } from './CurrentCartId.gql'
3
4
  import { CART_ID_COOKIE } from './useAssignCurrentCartId'
4
5
 
5
6
  export function useClearCurrentCartId() {
6
7
  const { cache } = useApolloClient()
7
8
 
8
9
  return () => {
9
- cache.evict({ fieldName: 'currentCartId', broadcast: true })
10
+ const id = cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId?.id
11
+ if (!id) return
12
+
13
+ cache.writeQuery({
14
+ query: CurrentCartIdDocument,
15
+ data: { currentCartId: { __typename: 'CurrentCartId', id: null } },
16
+ broadcast: true,
17
+ })
10
18
  cookie(CART_ID_COOKIE, null)
11
19
  }
12
20
  }
@@ -10,10 +10,5 @@ export function useCurrentCartId<
10
10
  V extends CurrentCartIdQueryVariables,
11
11
  >(options: QueryHookOptions<Q, V> = {}) {
12
12
  const queryResults = useQuery<Q, V>(CurrentCartIdDocument, options)
13
-
14
- return {
15
- currentCartId: queryResults.data?.currentCartId?.id || '',
16
- locked: queryResults.data?.currentCartId?.locked || false,
17
- ...queryResults,
18
- }
13
+ return { currentCartId: queryResults.data?.currentCartId?.id || '', ...queryResults }
19
14
  }
@@ -1,6 +1,43 @@
1
+ import { useMutation } from '@graphcommerce/graphql'
2
+ import { useCustomerQuery } from '@graphcommerce/magento-customer'
3
+ import { useEffect } from 'react'
4
+ import { CustomerCartDocument } from './CustomerCart.gql'
5
+ import { UseMergeCustomerCartDocument } from './UseMergeCustomerCart.gql'
6
+ import { useAssignCurrentCartId } from './useAssignCurrentCartId'
7
+ import { useCurrentCartId } from './useCurrentCartId'
8
+
1
9
  /**
2
- * @deprecated Is replaced by the useSignInFormMergeCart plugin.
10
+ * - Automatically assign the customer cart as the current cart
11
+ * - Merge the guest cart into the customer cart
3
12
  */
4
13
  export function useMergeCustomerCart() {
5
- return null
14
+ const { currentCartId } = useCurrentCartId()
15
+ const assignCurrentCartId = useAssignCurrentCartId()
16
+ const [merge] = useMutation(UseMergeCustomerCartDocument, { errorPolicy: 'all' })
17
+
18
+ const destinationCartId = useCustomerQuery(CustomerCartDocument, { fetchPolicy: 'network-only' })
19
+ ?.data?.customerCart.id
20
+
21
+ useEffect(() => {
22
+ // If we don't have a customer cart, we're done
23
+ // If the vistor cart is the same as the customer cart, we're done
24
+ if (!destinationCartId || currentCartId === destinationCartId) return
25
+
26
+ // If the visitor has a guest cart, try merging it into the customer cart
27
+ if (currentCartId) {
28
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
29
+ merge({ variables: { sourceCartId: currentCartId, destinationCartId } })
30
+ // We're not handling exceptions here:
31
+ // If the merge returns an error, we'll use the customer cart without merging the guest cart.
32
+ .catch((e) => {
33
+ console.error('Error merging carts', e)
34
+ })
35
+ .finally(() => {
36
+ // Assign the customer cart as the new cart id
37
+ assignCurrentCartId(destinationCartId)
38
+ })
39
+ } else {
40
+ assignCurrentCartId(destinationCartId)
41
+ }
42
+ }, [assignCurrentCartId, destinationCartId, merge, currentCartId])
6
43
  }
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": "8.0.3-canary.3",
5
+ "version": "8.1.0-canary.2",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,20 +12,20 @@
12
12
  }
13
13
  },
14
14
  "peerDependencies": {
15
- "@graphcommerce/ecommerce-ui": "^8.0.3-canary.3",
16
- "@graphcommerce/eslint-config-pwa": "^8.0.3-canary.3",
17
- "@graphcommerce/framer-next-pages": "^8.0.3-canary.3",
18
- "@graphcommerce/framer-scroller": "^8.0.3-canary.3",
19
- "@graphcommerce/framer-utils": "^8.0.3-canary.3",
20
- "@graphcommerce/graphql": "^8.0.3-canary.3",
21
- "@graphcommerce/image": "^8.0.3-canary.3",
22
- "@graphcommerce/magento-customer": "^8.0.3-canary.3",
23
- "@graphcommerce/magento-graphql": "^8.0.3-canary.3",
24
- "@graphcommerce/magento-store": "^8.0.3-canary.3",
25
- "@graphcommerce/next-ui": "^8.0.3-canary.3",
26
- "@graphcommerce/prettier-config-pwa": "^8.0.3-canary.3",
27
- "@graphcommerce/react-hook-form": "^8.0.3-canary.3",
28
- "@graphcommerce/typescript-config-pwa": "^8.0.3-canary.3",
15
+ "@graphcommerce/ecommerce-ui": "^8.1.0-canary.2",
16
+ "@graphcommerce/eslint-config-pwa": "^8.1.0-canary.2",
17
+ "@graphcommerce/framer-next-pages": "^8.1.0-canary.2",
18
+ "@graphcommerce/framer-scroller": "^8.1.0-canary.2",
19
+ "@graphcommerce/framer-utils": "^8.1.0-canary.2",
20
+ "@graphcommerce/graphql": "^8.1.0-canary.2",
21
+ "@graphcommerce/image": "^8.1.0-canary.2",
22
+ "@graphcommerce/magento-customer": "^8.1.0-canary.2",
23
+ "@graphcommerce/magento-graphql": "^8.1.0-canary.2",
24
+ "@graphcommerce/magento-store": "^8.1.0-canary.2",
25
+ "@graphcommerce/next-ui": "^8.1.0-canary.2",
26
+ "@graphcommerce/prettier-config-pwa": "^8.1.0-canary.2",
27
+ "@graphcommerce/react-hook-form": "^8.1.0-canary.2",
28
+ "@graphcommerce/typescript-config-pwa": "^8.1.0-canary.2",
29
29
  "@lingui/core": "^4.2.1",
30
30
  "@lingui/macro": "^4.2.1",
31
31
  "@lingui/react": "^4.2.1",
package/typePolicies.ts CHANGED
@@ -2,7 +2,7 @@ import { ApolloCache, NormalizedCacheObject } from '@graphcommerce/graphql'
2
2
  import type { StrictTypedTypePolicies } from '@graphcommerce/graphql'
3
3
  import type { CartPrices, QuerycartArgs, ShippingCartAddress } from '@graphcommerce/graphql-mesh'
4
4
  import { CartFabDocument } from './components/CartFab/CartFab.gql'
5
- import { readCartId, writeCartId } from './hooks'
5
+ import { CurrentCartIdDocument } from './hooks/CurrentCartId.gql'
6
6
 
7
7
  export const cartTypePolicies: StrictTypedTypePolicies = {
8
8
  CurrentCartId: { keyFields: [] },
@@ -53,10 +53,11 @@ export const migrateCart = (
53
53
  oldCache: ApolloCache<NormalizedCacheObject>,
54
54
  newCache: ApolloCache<NormalizedCacheObject>,
55
55
  ) => {
56
- const cartId = readCartId(oldCache)?.id
56
+ const currentCartId = oldCache.readQuery({ query: CurrentCartIdDocument })
57
+ const cartId = currentCartId?.currentCartId?.id
57
58
 
58
59
  if (cartId) {
59
- writeCartId(newCache, cartId)
60
+ newCache.writeQuery({ query: CurrentCartIdDocument, data: currentCartId, broadcast: true })
60
61
 
61
62
  // We have special handling for the CartFab because it tries to load data only from the cache.
62
63
  const cartFab = oldCache.readQuery({ query: CartFabDocument })
@@ -1,50 +0,0 @@
1
- import { useApolloClient } from '@graphcommerce/graphql'
2
- import type { useSignInForm } from '@graphcommerce/magento-customer/hooks/useSignInForm'
3
- import type { MethodPlugin } from '@graphcommerce/next-config'
4
- import { cartLock, readCartId, useAssignCurrentCartId } from '../hooks'
5
- import { CustomerCartDocument } from '../hooks/CustomerCart.gql'
6
- import { MergeCartsDocument } from '../hooks/MergeCarts.gql'
7
-
8
- export const func = 'useSignInForm'
9
- export const exported = '@graphcommerce/magento-customer/hooks/useSignInForm'
10
-
11
- const useSignInFormMergeCart: MethodPlugin<typeof useSignInForm> = (useSignInForm, options) => {
12
- const client = useApolloClient()
13
- const assignCurrentCartId = useAssignCurrentCartId()
14
-
15
- return useSignInForm({
16
- ...options,
17
- onComplete: async (data, variables) => {
18
- await options.onComplete?.(data, variables)
19
-
20
- cartLock(client.cache, true)
21
-
22
- const destinationCartId = (
23
- await client.query({
24
- query: CustomerCartDocument,
25
- fetchPolicy: 'network-only',
26
- })
27
- ).data.customerCart.id
28
-
29
- try {
30
- const sourceCartId = readCartId(client.cache)?.id
31
- if (sourceCartId && sourceCartId !== destinationCartId) {
32
- await client.mutate({
33
- mutation: MergeCartsDocument,
34
- variables: { sourceCartId, destinationCartId },
35
- })
36
- }
37
- } catch (error) {
38
- console.error(
39
- 'Error merging carts, continuing without merging, this might cause issues.',
40
- error,
41
- )
42
- } finally {
43
- // Assign the customer cart as the new cart id
44
- assignCurrentCartId(destinationCartId)
45
- }
46
- },
47
- })
48
- }
49
-
50
- export const plugin = useSignInFormMergeCart