import { useCallback } from 'react' import debounce from 'lodash.debounce' import type { HookFetcherContext, MutationHookContext, } from '@commerce/utils/types' import { ValidationError } from '@commerce/utils/errors' import useUpdateItem, { UpdateItemInput as UpdateItemInputBase, UseUpdateItem, } from '@commerce/cart/use-update-item' import useCart from './use-cart' import { handler as removeItemHandler } from './use-remove-item' import type { Cart, LineItem, UpdateCartItemBody } from '../types' import { checkoutToCart } from '../utils' export type UpdateItemInput = T extends LineItem ? Partial> : UpdateItemInputBase export default useUpdateItem as UseUpdateItem export const handler = { fetchOptions: { query: ``, }, async fetcher({ input: { itemId, item }, }: HookFetcherContext) { return { item, itemId, } }, useHook: ({ fetch, }: MutationHookContext) => < T extends LineItem | undefined = undefined >( ctx: { item?: T wait?: number } = {} ) => { const { item } = ctx const { mutate } = useCart() as any return useCallback( debounce(async (input: UpdateItemInput) => { const itemId = input.id ?? item?.id const productId = input.productId ?? item?.productId const variantId = input.productId ?? item?.variantId if (!itemId || !productId || !variantId) { throw new ValidationError({ message: 'Invalid input used for this operation', }) } const data = await fetch({ input: { item: { productId, variantId, quantity: input.quantity, }, itemId, }, }) await mutate(data, false) return data }, ctx.wait ?? 500), [fetch, mutate] ) }, }