forked from crowetic/commerce
Updated types and added remove item from cart api
This commit is contained in:
parent
486c50a68b
commit
45c3a5345d
@ -5,12 +5,20 @@ import createApiHandler, {
|
||||
} from './utils/create-api-handler'
|
||||
import { BigcommerceApiError } from './utils/errors'
|
||||
|
||||
export type Item = {
|
||||
type Body<T> = Partial<T> | undefined
|
||||
|
||||
export type ItemBody = {
|
||||
productId: number
|
||||
variantId: number
|
||||
quantity?: number
|
||||
}
|
||||
|
||||
export type AddItemBody = { item: ItemBody }
|
||||
|
||||
export type UpdateItemBody = { itemId: string; item: ItemBody }
|
||||
|
||||
export type RemoveItemBody = { itemId: string }
|
||||
|
||||
// TODO: this type should match:
|
||||
// https://developer.bigcommerce.com/api-reference/cart-checkout/server-server-cart-api/cart/getacart#responses
|
||||
export type Cart = {
|
||||
@ -34,6 +42,7 @@ export type Cart = {
|
||||
|
||||
const METHODS = ['GET', 'POST', 'PUT', 'DELETE']
|
||||
|
||||
// TODO: a complete implementation should have schema validation for `req.body`
|
||||
const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
if (!isAllowedMethod(req, res, METHODS)) return
|
||||
|
||||
@ -63,7 +72,7 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
|
||||
// Create or add an item to the cart
|
||||
if (req.method === 'POST') {
|
||||
const item: Item | undefined = req.body?.item
|
||||
const { item } = (req.body as Body<AddItemBody>) ?? {}
|
||||
|
||||
if (!item) {
|
||||
return res.status(400).json({
|
||||
@ -71,6 +80,7 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
errors: [{ message: 'Missing item' }],
|
||||
})
|
||||
}
|
||||
if (!item.quantity) item.quantity = 1
|
||||
|
||||
const options = {
|
||||
method: 'POST',
|
||||
@ -93,10 +103,7 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
|
||||
// Update item in cart
|
||||
if (req.method === 'PUT') {
|
||||
const { itemId, item } = (req.body ?? {}) as {
|
||||
itemId?: string
|
||||
item?: Item
|
||||
}
|
||||
const { itemId, item } = (req.body as Body<UpdateItemBody>) ?? {}
|
||||
|
||||
if (!cartId || !itemId || !item) {
|
||||
return res.status(400).json({
|
||||
@ -123,6 +130,33 @@ const cartApi: BigcommerceApiHandler<Cart> = async (req, res, config) => {
|
||||
|
||||
return res.status(200).json({ data })
|
||||
}
|
||||
|
||||
// Remove an item from the cart
|
||||
if (req.method === 'DELETE') {
|
||||
const { itemId } = (req.body as Body<RemoveItemBody>) ?? {}
|
||||
|
||||
if (!cartId || !itemId) {
|
||||
return res.status(400).json({
|
||||
data: null,
|
||||
errors: [{ message: 'Invalid request' }],
|
||||
})
|
||||
}
|
||||
|
||||
const { data } = await config.storeApiFetch(
|
||||
`/v3/carts/${cartId}/items/${itemId}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
}
|
||||
)
|
||||
|
||||
// Update the cart cookie
|
||||
res.setHeader(
|
||||
'Set-Cookie',
|
||||
getCartCookie(config.cartCookie, cartId, config.cartCookieMaxAge)
|
||||
)
|
||||
|
||||
return res.status(200).json({ data })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
@ -150,8 +184,8 @@ function getCartCookie(name: string, cartId?: string, maxAge?: number) {
|
||||
return serialize(name, cartId || '', options)
|
||||
}
|
||||
|
||||
const parseItem = (item: Item) => ({
|
||||
quantity: item.quantity || 1,
|
||||
const parseItem = (item: ItemBody) => ({
|
||||
quantity: item.quantity,
|
||||
product_id: item.productId,
|
||||
variant_id: item.variantId,
|
||||
})
|
||||
|
@ -1,11 +1,11 @@
|
||||
import type { Fetcher } from '@lib/commerce'
|
||||
import { default as useCartAddItem } from '@lib/commerce/cart/use-add-item'
|
||||
import type { Item } from '../api/cart'
|
||||
import type { ItemBody, AddItemBody } from '../api/cart'
|
||||
import { Cart, useCart } from '.'
|
||||
|
||||
export type { Item }
|
||||
export type { ItemBody, AddItemBody }
|
||||
|
||||
function fetcher(fetch: Fetcher<Cart>, { item }: { item: Item }) {
|
||||
function fetcher(fetch: Fetcher<Cart>, { item }: AddItemBody) {
|
||||
if (
|
||||
item.quantity &&
|
||||
(!Number.isInteger(item.quantity) || item.quantity! < 1)
|
||||
@ -20,7 +20,7 @@ function fetcher(fetch: Fetcher<Cart>, { item }: { item: Item }) {
|
||||
|
||||
export default function useAddItem() {
|
||||
const { mutate } = useCart()
|
||||
const fn = useCartAddItem<Cart, { item: Item }>(fetcher)
|
||||
const fn = useCartAddItem<Cart, AddItemBody>(fetcher)
|
||||
const addItem: typeof fn = async (input) => {
|
||||
const data = await fn(input)
|
||||
mutate(data)
|
||||
|
@ -1,16 +1,11 @@
|
||||
import type { Fetcher } from '@lib/commerce'
|
||||
import { default as useCartUpdateItem } from '@lib/commerce/cart/use-update-item'
|
||||
import type { Item } from '../api/cart'
|
||||
import type { ItemBody, UpdateItemBody } from '../api/cart'
|
||||
import { Cart, useCart } from '.'
|
||||
|
||||
export type { Item }
|
||||
export type { ItemBody, UpdateItemBody }
|
||||
|
||||
export type UpdateItemInput = {
|
||||
itemId: string
|
||||
item: Item
|
||||
}
|
||||
|
||||
function fetcher(fetch: Fetcher<Cart>, { itemId, item }: UpdateItemInput) {
|
||||
function fetcher(fetch: Fetcher<Cart>, { itemId, item }: UpdateItemBody) {
|
||||
if (
|
||||
item.quantity &&
|
||||
(!Number.isInteger(item.quantity) || item.quantity! < 1)
|
||||
@ -29,7 +24,7 @@ function fetcher(fetch: Fetcher<Cart>, { itemId, item }: UpdateItemInput) {
|
||||
|
||||
export default function useUpdateItem() {
|
||||
const { mutate } = useCart()
|
||||
const fn = useCartUpdateItem<Cart, UpdateItemInput>(fetcher)
|
||||
const fn = useCartUpdateItem<Cart, UpdateItemBody>(fetcher)
|
||||
const updateItem: typeof fn = async (input) => {
|
||||
const data = await fn(input)
|
||||
mutate(data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user