Updated the useAddItem and useRemoveItem hooks
This commit is contained in:
		@@ -11,42 +11,22 @@ import removeItem from './handlers/remove-item'
 | 
			
		||||
import type {
 | 
			
		||||
  BigcommerceCart,
 | 
			
		||||
  GetCartHandlerBody,
 | 
			
		||||
  AddCartItemHandlerBody,
 | 
			
		||||
  UpdateCartItemHandlerBody,
 | 
			
		||||
  RemoveCartItemHandlerBody,
 | 
			
		||||
} from '../../types'
 | 
			
		||||
 | 
			
		||||
type OptionSelections = {
 | 
			
		||||
  option_id: Number
 | 
			
		||||
  option_value: Number | String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type ItemBody = {
 | 
			
		||||
  productId: number
 | 
			
		||||
  variantId: number
 | 
			
		||||
  quantity?: number
 | 
			
		||||
  optionSelections?: OptionSelections
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type AddItemBody = { item: ItemBody }
 | 
			
		||||
 | 
			
		||||
export type RemoveItemBody = { itemId: string }
 | 
			
		||||
 | 
			
		||||
export type CartHandlers = {
 | 
			
		||||
  getCart: BigcommerceHandler<BigcommerceCart, GetCartHandlerBody>
 | 
			
		||||
  addItem: BigcommerceHandler<
 | 
			
		||||
    BigcommerceCart,
 | 
			
		||||
    { cartId?: string } & Partial<AddItemBody>
 | 
			
		||||
  >
 | 
			
		||||
  addItem: BigcommerceHandler<BigcommerceCart, AddCartItemHandlerBody>
 | 
			
		||||
  updateItem: BigcommerceHandler<BigcommerceCart, UpdateCartItemHandlerBody>
 | 
			
		||||
  removeItem: BigcommerceHandler<
 | 
			
		||||
    BigcommerceCart,
 | 
			
		||||
    { cartId?: string } & Partial<RemoveItemBody>
 | 
			
		||||
  >
 | 
			
		||||
  removeItem: BigcommerceHandler<BigcommerceCart, RemoveCartItemHandlerBody>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const METHODS = ['GET', 'POST', 'PUT', 'DELETE']
 | 
			
		||||
 | 
			
		||||
// TODO: a complete implementation should have schema validation for `req.body`
 | 
			
		||||
const cartApi: BigcommerceApiHandler<Cart, CartHandlers> = async (
 | 
			
		||||
const cartApi: BigcommerceApiHandler<BigcommerceCart, CartHandlers> = async (
 | 
			
		||||
  req,
 | 
			
		||||
  res,
 | 
			
		||||
  config,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,16 @@
 | 
			
		||||
import { useCallback } from 'react'
 | 
			
		||||
import type { HookFetcher } from '@commerce/utils/types'
 | 
			
		||||
import { CommerceError } from '@commerce/utils/errors'
 | 
			
		||||
import useCartAddItem from '@commerce/cart/use-add-item'
 | 
			
		||||
import useCartAddItem, {
 | 
			
		||||
  AddItemInput as UseAddItemInput,
 | 
			
		||||
} from '@commerce/cart/use-add-item'
 | 
			
		||||
import { normalizeCart } from '../lib/normalize'
 | 
			
		||||
import type {
 | 
			
		||||
  ItemBody,
 | 
			
		||||
  AddItemBody,
 | 
			
		||||
  Cart as BigcommerceCart,
 | 
			
		||||
} from '../api/cart'
 | 
			
		||||
  AddCartItemBody,
 | 
			
		||||
  Cart,
 | 
			
		||||
  BigcommerceCart,
 | 
			
		||||
  CartItemBody,
 | 
			
		||||
} from '../types'
 | 
			
		||||
import useCart from './use-cart'
 | 
			
		||||
 | 
			
		||||
const defaultOpts = {
 | 
			
		||||
@@ -15,9 +18,9 @@ const defaultOpts = {
 | 
			
		||||
  method: 'POST',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type AddItemInput = ItemBody
 | 
			
		||||
export type AddItemInput = UseAddItemInput<CartItemBody>
 | 
			
		||||
 | 
			
		||||
export const fetcher: HookFetcher<Cart, AddItemBody> = async (
 | 
			
		||||
export const fetcher: HookFetcher<Cart, AddCartItemBody> = async (
 | 
			
		||||
  options,
 | 
			
		||||
  { item },
 | 
			
		||||
  fetch
 | 
			
		||||
@@ -31,7 +34,7 @@ export const fetcher: HookFetcher<Cart, AddItemBody> = async (
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const data = await fetch<BigcommerceCart>({
 | 
			
		||||
  const data = await fetch<BigcommerceCart, AddCartItemBody>({
 | 
			
		||||
    ...defaultOpts,
 | 
			
		||||
    ...options,
 | 
			
		||||
    body: { item },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,16 @@
 | 
			
		||||
import { useCallback } from 'react'
 | 
			
		||||
import { HookFetcher } from '@commerce/utils/types'
 | 
			
		||||
import useCartRemoveItem from '@commerce/cart/use-remove-item'
 | 
			
		||||
import { ValidationError } from '@commerce/utils/errors'
 | 
			
		||||
import useCartRemoveItem, {
 | 
			
		||||
  RemoveItemInput as UseRemoveItemInput,
 | 
			
		||||
} from '@commerce/cart/use-remove-item'
 | 
			
		||||
import { normalizeCart } from '../lib/normalize'
 | 
			
		||||
import type { RemoveItemBody, Cart as BigcommerceCart } from '../api/cart'
 | 
			
		||||
import type {
 | 
			
		||||
  RemoveCartItemBody,
 | 
			
		||||
  Cart,
 | 
			
		||||
  BigcommerceCart,
 | 
			
		||||
  LineItem,
 | 
			
		||||
} from '../types'
 | 
			
		||||
import useCart from './use-cart'
 | 
			
		||||
 | 
			
		||||
const defaultOpts = {
 | 
			
		||||
@@ -10,11 +18,15 @@ const defaultOpts = {
 | 
			
		||||
  method: 'DELETE',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type RemoveItemInput = {
 | 
			
		||||
  id: string
 | 
			
		||||
}
 | 
			
		||||
export type RemoveItemFn<T = any> = T extends LineItem
 | 
			
		||||
  ? (input?: RemoveItemInput<T>) => Promise<Cart | null>
 | 
			
		||||
  : (input: RemoveItemInput<T>) => Promise<Cart | null>
 | 
			
		||||
 | 
			
		||||
export const fetcher: HookFetcher<Cart | null, RemoveItemBody> = async (
 | 
			
		||||
export type RemoveItemInput<T = any> = T extends LineItem
 | 
			
		||||
  ? Partial<UseRemoveItemInput>
 | 
			
		||||
  : UseRemoveItemInput
 | 
			
		||||
 | 
			
		||||
export const fetcher: HookFetcher<Cart | null, RemoveCartItemBody> = async (
 | 
			
		||||
  options,
 | 
			
		||||
  { itemId },
 | 
			
		||||
  fetch
 | 
			
		||||
@@ -28,21 +40,29 @@ export const fetcher: HookFetcher<Cart | null, RemoveItemBody> = async (
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function extendHook(customFetcher: typeof fetcher) {
 | 
			
		||||
  const useRemoveItem = (item?: any) => {
 | 
			
		||||
  const useRemoveItem = <T extends LineItem | undefined = undefined>(
 | 
			
		||||
    item?: T
 | 
			
		||||
  ) => {
 | 
			
		||||
    const { mutate } = useCart()
 | 
			
		||||
    const fn = useCartRemoveItem<Cart | null, RemoveItemBody>(
 | 
			
		||||
    const fn = useCartRemoveItem<Cart | null, RemoveCartItemBody>(
 | 
			
		||||
      defaultOpts,
 | 
			
		||||
      customFetcher
 | 
			
		||||
    )
 | 
			
		||||
    const removeItem: RemoveItemFn<LineItem> = async (input) => {
 | 
			
		||||
      const itemId = input?.id ?? item?.id
 | 
			
		||||
 | 
			
		||||
    return useCallback(
 | 
			
		||||
      async function removeItem(input: RemoveItemInput) {
 | 
			
		||||
        const data = await fn({ itemId: input.id ?? item?.id })
 | 
			
		||||
        await mutate(data, false)
 | 
			
		||||
        return data
 | 
			
		||||
      },
 | 
			
		||||
      [fn, mutate]
 | 
			
		||||
    )
 | 
			
		||||
      if (!itemId) {
 | 
			
		||||
        throw new ValidationError({
 | 
			
		||||
          message: 'Invalid input used for this operation',
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const data = await fn({ itemId })
 | 
			
		||||
      await mutate(data, false)
 | 
			
		||||
      return data
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return useCallback(removeItem as RemoveItemFn<T>, [fn, mutate])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  useRemoveItem.extend = extendHook
 | 
			
		||||
 
 | 
			
		||||
@@ -45,8 +45,18 @@ export interface CartItemBody extends Core.CartItemBody {
 | 
			
		||||
 | 
			
		||||
export interface GetCartHandlerBody extends Core.GetCartHandlerBody {}
 | 
			
		||||
 | 
			
		||||
export interface AddCartItemBody extends Core.AddCartItemBody<CartItemBody> {}
 | 
			
		||||
 | 
			
		||||
export interface AddCartItemHandlerBody
 | 
			
		||||
  extends Core.AddCartItemHandlerBody<CartItemBody> {}
 | 
			
		||||
 | 
			
		||||
export interface UpdateCartItemBody
 | 
			
		||||
  extends Core.UpdateCartItemBody<CartItemBody> {}
 | 
			
		||||
 | 
			
		||||
export interface UpdateCartItemHandlerBody
 | 
			
		||||
  extends Core.UpdateCartItemHandlerBody<CartItemBody> {}
 | 
			
		||||
 | 
			
		||||
export interface RemoveCartItemBody extends Core.RemoveCartItemBody {}
 | 
			
		||||
 | 
			
		||||
export interface RemoveCartItemHandlerBody
 | 
			
		||||
  extends Core.RemoveCartItemHandlerBody {}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,8 @@
 | 
			
		||||
import useAction from '../utils/use-action'
 | 
			
		||||
import type { CartItemBody } from '../types'
 | 
			
		||||
 | 
			
		||||
// Input expected by the action returned by the `useAddItem` hook
 | 
			
		||||
export type AddItemInput<T extends CartItemBody> = T
 | 
			
		||||
 | 
			
		||||
const useAddItem = useAction
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
import useAction from '../utils/use-action'
 | 
			
		||||
 | 
			
		||||
// Input expected by the action returned by the `useRemoveItem` hook
 | 
			
		||||
export interface RemoveItemInput {
 | 
			
		||||
  id: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const useRemoveItem = useAction
 | 
			
		||||
 | 
			
		||||
export default useRemoveItem
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,10 @@ export interface Cart {
 | 
			
		||||
  discounts?: Discount[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cart mutations
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Base cart item body used for cart mutations
 | 
			
		||||
export interface CartItemBody {
 | 
			
		||||
  variantId: string
 | 
			
		||||
@@ -99,14 +103,35 @@ export interface GetCartHandlerBody {
 | 
			
		||||
  cartId?: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body used by the update operation
 | 
			
		||||
// Body used by the add item to cart operation
 | 
			
		||||
export interface AddCartItemBody<T extends CartItemBody> {
 | 
			
		||||
  item: T
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body expected by the add item to cart operation handler
 | 
			
		||||
export interface AddCartItemHandlerBody<T extends CartItemBody>
 | 
			
		||||
  extends Partial<AddCartItemBody<T>> {
 | 
			
		||||
  cartId?: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body used by the update cart item operation
 | 
			
		||||
export interface UpdateCartItemBody<T extends CartItemBody> {
 | 
			
		||||
  itemId: string
 | 
			
		||||
  item: T
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body expected by the update operation handler
 | 
			
		||||
// Body expected by the update cart item operation handler
 | 
			
		||||
export interface UpdateCartItemHandlerBody<T extends CartItemBody>
 | 
			
		||||
  extends Partial<UpdateCartItemBody<T>> {
 | 
			
		||||
  cartId?: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body used by the remove cart item operation
 | 
			
		||||
export interface RemoveCartItemBody {
 | 
			
		||||
  itemId: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Body expected by the remove cart item operation handler
 | 
			
		||||
export interface RemoveCartItemHandlerBody extends Partial<RemoveCartItemBody> {
 | 
			
		||||
  cartId?: string
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user