@graphcommerce/magento-cart 8.0.3-canary.4 → 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 +1 -13
- package/components/CartDebugger/CartDebugger.tsx +14 -4
- package/components/CartItemSummary/CartItemSummary.tsx +5 -2
- package/components/CartTotals/CartTotals.tsx +1 -1
- package/hooks/CurrentCartId.graphql +0 -1
- package/hooks/CurrentCartId.graphqls +0 -1
- package/hooks/CustomerCart.graphql +1 -0
- package/hooks/{MergeCarts.graphql → UseMergeCustomerCart.graphql} +2 -1
- package/hooks/useAssignCurrentCartId.ts +1 -16
- package/hooks/useCartIdCreate.ts +4 -2
- package/hooks/useCartQuery.ts +10 -8
- package/hooks/useClearCurrentCartId.ts +9 -1
- package/hooks/useCurrentCartId.ts +1 -6
- package/hooks/useMergeCustomerCart.ts +39 -2
- package/package.json +15 -15
- package/typePolicies.ts +4 -3
- package/plugins/useSignInFormMergeCart.ts +0 -50
package/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## 8.0
|
|
4
|
-
|
|
5
|
-
## 8.0.3-canary.3
|
|
6
|
-
|
|
7
|
-
## 8.0.3-canary.2
|
|
8
|
-
|
|
9
|
-
### Patch Changes
|
|
10
|
-
|
|
11
|
-
- [#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.
|
|
12
|
-
([@paales](https://github.com/paales))
|
|
13
|
-
|
|
14
|
-
- [#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.
|
|
15
|
-
([@paales](https://github.com/paales))
|
|
3
|
+
## 8.1.0-canary.2
|
|
16
4
|
|
|
17
5
|
## 8.0.3-canary.1
|
|
18
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useApolloClient } from '@graphcommerce/graphql'
|
|
2
2
|
import { Button } from '@mui/material'
|
|
3
|
-
import {
|
|
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
|
|
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
|
-
|
|
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, {
|
|
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
|
-
{
|
|
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 })
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
mutation
|
|
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',
|
|
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
|
|
package/hooks/useCartIdCreate.ts
CHANGED
|
@@ -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 {
|
|
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 =
|
|
12
|
+
const currentCartId = client.cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId
|
|
13
|
+
?.id
|
|
12
14
|
|
|
13
15
|
if (currentCartId) return currentCartId
|
|
14
16
|
|
package/hooks/useCartQuery.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^8.0
|
|
17
|
-
"@graphcommerce/framer-next-pages": "^8.0
|
|
18
|
-
"@graphcommerce/framer-scroller": "^8.0
|
|
19
|
-
"@graphcommerce/framer-utils": "^8.0
|
|
20
|
-
"@graphcommerce/graphql": "^8.0
|
|
21
|
-
"@graphcommerce/image": "^8.0
|
|
22
|
-
"@graphcommerce/magento-customer": "^8.0
|
|
23
|
-
"@graphcommerce/magento-graphql": "^8.0
|
|
24
|
-
"@graphcommerce/magento-store": "^8.0
|
|
25
|
-
"@graphcommerce/next-ui": "^8.0
|
|
26
|
-
"@graphcommerce/prettier-config-pwa": "^8.0
|
|
27
|
-
"@graphcommerce/react-hook-form": "^8.0
|
|
28
|
-
"@graphcommerce/typescript-config-pwa": "^8.0
|
|
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 {
|
|
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
|
|
56
|
+
const currentCartId = oldCache.readQuery({ query: CurrentCartIdDocument })
|
|
57
|
+
const cartId = currentCartId?.currentCartId?.id
|
|
57
58
|
|
|
58
59
|
if (cartId) {
|
|
59
|
-
|
|
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
|