diff --git a/framework/shopify/cart/use-add-item.tsx b/framework/shopify/cart/use-add-item.tsx index 162627057..c17462cc0 100644 --- a/framework/shopify/cart/use-add-item.tsx +++ b/framework/shopify/cart/use-add-item.tsx @@ -1,66 +1,60 @@ -import { useCallback } from 'react' +import type { MutationHandler } from '@commerce/utils/types' +import { CommerceError } from '@commerce/utils/errors' +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' import useCart from './use-cart' - -import useCartAddItem, { - AddItemInput as UseAddItemInput, -} from '@commerce/cart/use-add-item' - -import type { HookFetcher } from '@commerce/utils/types' -import type { Cart } from '@commerce/types' - -import { checkoutLineItemAddMutation, getCheckoutId } from '@framework/utils' +import { ShopifyProvider } from '..' +import { AddCartItemBody, CartItemBody } from '@commerce/types' +import { Cart } from '@framework/types' +import { + checkoutLineItemAddMutation, + getCheckoutId, + getCheckoutQuery, +} from '@framework/utils' import { checkoutToCart } from './utils' -import { AddCartItemBody, CartItemBody } from '@framework/types' -import { MutationCheckoutLineItemsAddArgs } from '@framework/schema' - const defaultOpts = { query: checkoutLineItemAddMutation, } -export type AddItemInput = UseAddItemInput +export default useAddItem as UseAddItem -export const fetcher: HookFetcher< - Cart, - MutationCheckoutLineItemsAddArgs -> = async (options, { checkoutId, lineItems }, fetch) => { - const data = await fetch({ - ...options, - variables: { - checkoutId, - lineItems, - }, - }) +export const handler: MutationHandler = { + fetchOptions: { + query: checkoutLineItemAddMutation, + }, + async fetcher({ input, options, fetch }) { + const item = input.item ?? input + if ( + item.quantity && + (!Number.isInteger(item.quantity) || item.quantity! < 1) + ) { + throw new CommerceError({ + message: 'The item quantity has to be a valid integer greater than 0', + }) + } - return checkoutToCart(data?.checkoutLineItemsAdd) -} - -export function extendHook(customFetcher: typeof fetcher) { - const useAddItem = () => { - const { mutate, data: cart } = useCart() - const fn = useCartAddItem(defaultOpts, customFetcher) - - return useCallback( - async function addItem(input: AddItemInput) { - const data = await fn({ - lineItems: [ - { - variantId: input.variantId, - quantity: input.quantity ?? 1, - }, - ], - checkoutId: getCheckoutId(cart?.id)!, - }) - await mutate(data, false) - return data + const data = await fetch({ + ...defaultOpts, + ...options, + variables: { + lineItems: [ + { + variantId: item.variantId, + quantity: item.quantity ?? 1, + }, + ], + checkoutId: getCheckoutId(), }, - [fn, mutate] - ) - } + }) - useAddItem.extend = extendHook - - return useAddItem + return checkoutToCart(data.checkoutLineItemsAdd) + }, + useHook() { + const { mutate } = useCart() + return async function addItem({ input, fetch }) { + const data = await fetch({ input }) + await mutate(data, false) + return data + } + }, } - -export default extendHook(fetcher) diff --git a/framework/shopify/cart/use-remove-item.tsx b/framework/shopify/cart/use-remove-item.tsx index 193adede6..5c2c2dbee 100644 --- a/framework/shopify/cart/use-remove-item.tsx +++ b/framework/shopify/cart/use-remove-item.tsx @@ -34,7 +34,7 @@ export const fetcher: HookFetcher = async ( ...options, variables: { lineItemIds: [itemId], checkoutId }, }) - return checkoutToCart(data?.checkoutLineItemsRemove) + return checkoutToCart(data.checkoutLineItemsRemove) } export function extendHook(customFetcher: typeof fetcher) { diff --git a/framework/shopify/cart/use-update-item.tsx b/framework/shopify/cart/use-update-item.tsx index e29bf8b72..2b5e7c776 100644 --- a/framework/shopify/cart/use-update-item.tsx +++ b/framework/shopify/cart/use-update-item.tsx @@ -44,7 +44,7 @@ export const fetcher: HookFetcher = async ( variables: { checkoutId, lineItems: [item] }, }) - return checkoutToCart(data?.checkoutLineItemsUpdate) + return checkoutToCart(data.checkoutLineItemsUpdate) } function extendHook(customFetcher: typeof fetcher, cfg?: { wait?: number }) { diff --git a/framework/shopify/cart/utils/checkout-to-cart.ts b/framework/shopify/cart/utils/checkout-to-cart.ts index a8e91fbe1..104240220 100644 --- a/framework/shopify/cart/utils/checkout-to-cart.ts +++ b/framework/shopify/cart/utils/checkout-to-cart.ts @@ -1,12 +1,12 @@ import { Cart } from '@commerce/types' -import { CommerceError, ValidationError } from '@commerce/utils/errors' +import { ValidationError } from '@commerce/utils/errors' import { normalizeCart } from '@framework/utils/normalize' -import { Checkout, Maybe, UserError } from '@framework/schema' +import { Checkout, UserError } from '@framework/schema' -const checkoutToCart = (checkoutResponse?: { +const checkoutToCart = (checkoutResponse: { checkout: Checkout userErrors?: UserError[] -}): Maybe => { +}): Cart => { const checkout = checkoutResponse?.checkout const userErrors = checkoutResponse?.userErrors @@ -16,12 +16,6 @@ const checkoutToCart = (checkoutResponse?: { }) } - if (!checkout) { - throw new CommerceError({ - message: 'Missing checkout details from response cart Response', - }) - } - return normalizeCart(checkout) } diff --git a/framework/shopify/cart/utils/fetcher.ts b/framework/shopify/cart/utils/fetcher.ts index 6621b7fde..372860734 100644 --- a/framework/shopify/cart/utils/fetcher.ts +++ b/framework/shopify/cart/utils/fetcher.ts @@ -5,22 +5,22 @@ import { FetchCartInput } from '@commerce/cart/use-cart' const fetcher: HookFetcherFn = async ({ options, - input: { cartId }, + input: { cartId: checkoutId }, fetch, }) => { let checkout - if (cartId) { + if (checkoutId) { const data = await fetch({ ...options, variables: { - cartId, + checkoutId, }, }) checkout = data?.node } - if (checkout?.completedAt || !cartId) { + if (checkout?.completedAt || !checkoutId) { checkout = await checkoutCreate(fetch) } diff --git a/framework/shopify/provider.ts b/framework/shopify/provider.ts index 6da831e46..f11e9ff3f 100644 --- a/framework/shopify/provider.ts +++ b/framework/shopify/provider.ts @@ -1,8 +1,9 @@ import { SHOPIFY_CHECKOUT_ID_COOKIE, STORE_DOMAIN } from './const' -import { handler as useCart } from '@framework/cart/use-cart' -import { handler as useSearch } from '@framework/product/use-search' -import { handler as useCustomer } from '@framework/customer/use-customer' +import { handler as useCart } from './cart/use-cart' +import { handler as useAddItem } from './cart/use-add-item' +import { handler as useSearch } from './product/use-search' +import { handler as useCustomer } from './customer/use-customer' import fetcher from './fetcher' export const shopifyProvider = { @@ -10,7 +11,7 @@ export const shopifyProvider = { cartCookie: SHOPIFY_CHECKOUT_ID_COOKIE, storeDomain: STORE_DOMAIN, fetcher, - cart: { useCart }, + cart: { useCart, useAddItem }, customer: { useCustomer }, products: { useSearch }, } diff --git a/framework/shopify/types.ts b/framework/shopify/types.ts index 5d285d211..7f207b0c7 100644 --- a/framework/shopify/types.ts +++ b/framework/shopify/types.ts @@ -8,6 +8,7 @@ export type ShopifyCheckout = { } export interface Cart extends Core.Cart { + id: string lineItems: LineItem[] } diff --git a/framework/shopify/utils/normalize.ts b/framework/shopify/utils/normalize.ts index c39331cd9..edd295ddd 100644 --- a/framework/shopify/utils/normalize.ts +++ b/framework/shopify/utils/normalize.ts @@ -107,7 +107,7 @@ function normalizeLineItem({ variantId: String(variant?.id), productId: String(variant?.id), name: `${title} - ${variant?.title}`, - quantity: quantity, + quantity, variant: { id: String(variant?.id), sku: variant?.sku ?? '',