mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
Fix provider errors
This commit is contained in:
@@ -46,7 +46,7 @@ export type SubmitCheckoutHandler<T extends CheckoutTypes = CheckoutTypes> =
|
||||
|
||||
export type CheckoutHandlers<T extends CheckoutTypes = CheckoutTypes> = {
|
||||
getCheckout: GetCheckoutHandler<T>
|
||||
submitCheckout?: SubmitCheckoutHandler<T>
|
||||
submitCheckout: SubmitCheckoutHandler<T>
|
||||
}
|
||||
|
||||
export type CheckoutSchema<T extends CheckoutTypes = CheckoutTypes> = {
|
||||
|
@@ -1,41 +1,46 @@
|
||||
export interface Address {
|
||||
id: string;
|
||||
mask: string;
|
||||
id: string
|
||||
mask: string
|
||||
}
|
||||
|
||||
export interface AddressFields {
|
||||
type: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
company: string;
|
||||
streetNumber: string;
|
||||
apartments: string;
|
||||
zipCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
type: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
company: string
|
||||
streetNumber: string
|
||||
apartments: string
|
||||
zipCode: string
|
||||
city: string
|
||||
country: string
|
||||
}
|
||||
|
||||
export type CustomerAddressTypes = {
|
||||
address?: Address;
|
||||
fields: AddressFields;
|
||||
address?: Address
|
||||
fields: AddressFields
|
||||
}
|
||||
|
||||
export type GetAddressesHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
data: T['address'] | null
|
||||
export type GetAddressesHook<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
data: T['address'][] | null
|
||||
input: {}
|
||||
fetcherInput: { cartId?: string }
|
||||
swrState: { isEmpty: boolean }
|
||||
}
|
||||
|
||||
export type AddItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
data: T['address']
|
||||
input?: T['fields']
|
||||
fetcherInput: T['fields']
|
||||
body: { item: T['fields'] }
|
||||
actionInput: T['fields']
|
||||
}
|
||||
export type AddItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> =
|
||||
{
|
||||
data: T['address']
|
||||
input?: T['fields']
|
||||
fetcherInput: T['fields']
|
||||
body: { item: T['fields'] }
|
||||
actionInput: T['fields']
|
||||
}
|
||||
|
||||
export type UpdateItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
export type UpdateItemHook<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
data: T['address'] | null
|
||||
input: { item?: T['fields']; wait?: number }
|
||||
fetcherInput: { itemId: string; item: T['fields'] }
|
||||
@@ -43,49 +48,62 @@ export type UpdateItemHook<T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
actionInput: T['fields'] & { id: string }
|
||||
}
|
||||
|
||||
export type RemoveItemHook<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
export type RemoveItemHook<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
data: T['address'] | null
|
||||
input: { item?: T['fields'] }
|
||||
input: { item?: T['address'] }
|
||||
fetcherInput: { itemId: string }
|
||||
body: { itemId: string }
|
||||
actionInput: { id: string }
|
||||
}
|
||||
|
||||
export type CustomerAddressHooks<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
export type CustomerAddressHooks<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
getAddresses: GetAddressesHook<T>
|
||||
addItem: AddItemHook<T>
|
||||
updateItem: UpdateItemHook<T>
|
||||
removeItem: RemoveItemHook<T>
|
||||
}
|
||||
|
||||
export type AddresssHandler<T extends CustomerAddressTypes = CustomerAddressTypes> = GetAddressesHook<T> & {
|
||||
export type AddressHandler<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = GetAddressesHook<T> & {
|
||||
body: { cartId?: string }
|
||||
}
|
||||
|
||||
export type AddItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> = AddItemHook<T> & {
|
||||
export type AddItemHandler<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = AddItemHook<T> & {
|
||||
body: { cartId: string }
|
||||
}
|
||||
|
||||
export type UpdateItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> =
|
||||
UpdateItemHook<T> & {
|
||||
data: T['address']
|
||||
body: { cartId: string }
|
||||
}
|
||||
export type UpdateItemHandler<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = UpdateItemHook<T> & {
|
||||
data: T['address']
|
||||
body: { cartId: string }
|
||||
}
|
||||
|
||||
export type RemoveItemHandler<T extends CustomerAddressTypes = CustomerAddressTypes> =
|
||||
RemoveItemHook<T> & {
|
||||
body: { cartId: string }
|
||||
}
|
||||
export type RemoveItemHandler<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = RemoveItemHook<T> & {
|
||||
body: { cartId: string }
|
||||
}
|
||||
|
||||
|
||||
export type CustomerAddressHandlers<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
export type CustomerAddressHandlers<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
getAddresses: GetAddressesHook<T>
|
||||
addItem: AddItemHandler<T>
|
||||
updateItem: UpdateItemHandler<T>
|
||||
removeItem: RemoveItemHandler<T>
|
||||
}
|
||||
|
||||
export type CustomerAddressSchema<T extends CustomerAddressTypes = CustomerAddressTypes> = {
|
||||
export type CustomerAddressSchema<
|
||||
T extends CustomerAddressTypes = CustomerAddressTypes
|
||||
> = {
|
||||
endpoint: {
|
||||
options: {}
|
||||
handlers: CustomerAddressHandlers<T>
|
||||
|
@@ -1,30 +1,30 @@
|
||||
export interface Card {
|
||||
id: string;
|
||||
mask: string;
|
||||
provider: string;
|
||||
id: string
|
||||
mask: string
|
||||
provider: string
|
||||
}
|
||||
|
||||
export interface CardFields {
|
||||
cardHolder: string;
|
||||
cardNumber: string;
|
||||
cardExpireDate: string;
|
||||
cardCvc: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
company: string;
|
||||
streetNumber: string;
|
||||
zipCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
cardHolder: string
|
||||
cardNumber: string
|
||||
cardExpireDate: string
|
||||
cardCvc: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
company: string
|
||||
streetNumber: string
|
||||
zipCode: string
|
||||
city: string
|
||||
country: string
|
||||
}
|
||||
|
||||
export type CustomerCardTypes = {
|
||||
card?: Card;
|
||||
fields: CardFields;
|
||||
card?: Card
|
||||
fields: CardFields
|
||||
}
|
||||
|
||||
export type GetCardsHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
data: T['card'] | null
|
||||
data: T['card'][] | null
|
||||
input: {}
|
||||
fetcherInput: { cartId?: string }
|
||||
swrState: { isEmpty: boolean }
|
||||
@@ -48,26 +48,29 @@ export type UpdateItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
|
||||
export type RemoveItemHook<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
data: T['card'] | null
|
||||
input: { item?: T['fields'] }
|
||||
input: { item?: T['card'] }
|
||||
fetcherInput: { itemId: string }
|
||||
body: { itemId: string }
|
||||
actionInput: { id: string }
|
||||
}
|
||||
|
||||
export type CustomerCardHooks<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
getCards: GetCardsHook<T>
|
||||
addItem: AddItemHook<T>
|
||||
updateItem: UpdateItemHook<T>
|
||||
removeItem: RemoveItemHook<T>
|
||||
}
|
||||
export type CustomerCardHooks<T extends CustomerCardTypes = CustomerCardTypes> =
|
||||
{
|
||||
getCards: GetCardsHook<T>
|
||||
addItem: AddItemHook<T>
|
||||
updateItem: UpdateItemHook<T>
|
||||
removeItem: RemoveItemHook<T>
|
||||
}
|
||||
|
||||
export type CardsHandler<T extends CustomerCardTypes = CustomerCardTypes> = GetCardsHook<T> & {
|
||||
body: { cartId?: string }
|
||||
}
|
||||
export type CardsHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
||||
GetCardsHook<T> & {
|
||||
body: { cartId?: string }
|
||||
}
|
||||
|
||||
export type AddItemHandler<T extends CustomerCardTypes = CustomerCardTypes> = AddItemHook<T> & {
|
||||
body: { cartId: string }
|
||||
}
|
||||
export type AddItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
||||
AddItemHook<T> & {
|
||||
body: { cartId: string }
|
||||
}
|
||||
|
||||
export type UpdateItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
||||
UpdateItemHook<T> & {
|
||||
@@ -80,15 +83,18 @@ export type RemoveItemHandler<T extends CustomerCardTypes = CustomerCardTypes> =
|
||||
body: { cartId: string }
|
||||
}
|
||||
|
||||
|
||||
export type CustomerCardHandlers<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
export type CustomerCardHandlers<
|
||||
T extends CustomerCardTypes = CustomerCardTypes
|
||||
> = {
|
||||
getCards: GetCardsHook<T>
|
||||
addItem: AddItemHandler<T>
|
||||
updateItem: UpdateItemHandler<T>
|
||||
removeItem: RemoveItemHandler<T>
|
||||
}
|
||||
|
||||
export type CustomerCardSchema<T extends CustomerCardTypes = CustomerCardTypes> = {
|
||||
export type CustomerCardSchema<
|
||||
T extends CustomerCardTypes = CustomerCardTypes
|
||||
> = {
|
||||
endpoint: {
|
||||
options: {}
|
||||
handlers: CustomerCardHandlers<T>
|
||||
|
@@ -2,7 +2,6 @@ import type { AddItemHook } from '@commerce/types/customer/address'
|
||||
import type { MutationHook } from '@commerce/utils/types'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import { CommerceError } from '@commerce/utils/errors'
|
||||
import useAddItem, { UseAddItem } from '@commerce/customer/address/use-add-item'
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
@@ -14,15 +13,6 @@ export const handler: MutationHook<AddItemHook> = {
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
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',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({
|
||||
...options,
|
||||
body: { item },
|
||||
@@ -38,7 +28,7 @@ export const handler: MutationHook<AddItemHook> = {
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
|
@@ -2,7 +2,9 @@ import type { GetAddressesHook } from '@commerce/types/customer/address'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useAddresses, { UseAddresses } from '@commerce/customer/address/use-addresses'
|
||||
import useAddresses, {
|
||||
UseAddresses,
|
||||
} from '@commerce/customer/address/use-addresses'
|
||||
|
||||
export default useAddresses as UseAddresses<typeof handler>
|
||||
|
||||
@@ -22,7 +24,7 @@ export const handler: SWRHook<GetAddressesHook> = {
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.lineItems?.length ?? 0) <= 0
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
|
@@ -2,20 +2,22 @@ import type {
|
||||
MutationHookContext,
|
||||
HookFetcherContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart'
|
||||
import type { Address, RemoveItemHook } from '@commerce/types/customer/address'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useRemoveItem, { UseRemoveItem } from '@commerce/customer/address/use-remove-item'
|
||||
import useRemoveItem, {
|
||||
UseRemoveItem,
|
||||
} from '@commerce/customer/address/use-remove-item'
|
||||
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
export type RemoveItemFn<T = any> = T extends LineItem
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Cart | null>
|
||||
export type RemoveItemFn<T = any> = T extends Address
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Address | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Address | null>
|
||||
|
||||
export type RemoveItemActionInput<T = any> = T extends LineItem
|
||||
export type RemoveItemActionInput<T = any> = T extends Address
|
||||
? Partial<RemoveItemHook['actionInput']>
|
||||
: RemoveItemHook['actionInput']
|
||||
|
||||
@@ -34,12 +36,12 @@ export const handler = {
|
||||
return await fetch({ ...options, body: { itemId } })
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) =>
|
||||
function useHook<T extends LineItem | undefined = undefined>(
|
||||
function useHook<T extends Address | undefined = undefined>(
|
||||
ctx: { item?: T } = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useAddresses()
|
||||
const removeItem: RemoveItemFn<LineItem> = async (input) => {
|
||||
const removeItem: RemoveItemFn<Address> = async (input) => {
|
||||
const itemId = input?.id ?? item?.id
|
||||
|
||||
if (!itemId) {
|
||||
@@ -50,7 +52,7 @@ export const handler = {
|
||||
|
||||
const data = await fetch({ input: { itemId } })
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}
|
||||
|
@@ -2,19 +2,18 @@ import type {
|
||||
HookFetcherContext,
|
||||
MutationHookContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { UpdateItemHook, LineItem } from '@commerce/types/cart'
|
||||
import type { UpdateItemHook, Address } from '@commerce/types/customer/address'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useUpdateItem, { UseUpdateItem } from '@commerce/customer/address/use-update-item'
|
||||
import useUpdateItem, {
|
||||
UseUpdateItem,
|
||||
} from '@commerce/customer/address/use-update-item'
|
||||
|
||||
import { handler as removeItemHandler } from './use-remove-item'
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
export type UpdateItemActionInput<T = any> = T extends LineItem
|
||||
export type UpdateItemActionInput<T = any> = T extends Address
|
||||
? Partial<UpdateItemHook['actionInput']>
|
||||
: UpdateItemHook['actionInput']
|
||||
|
||||
@@ -30,63 +29,23 @@ export const handler: MutationHook<any> = {
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<UpdateItemHook>) {
|
||||
if (Number.isInteger(item.quantity)) {
|
||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||
if (item.quantity! < 1) {
|
||||
return removeItemHandler.fetcher({
|
||||
options: removeItemHandler.fetchOptions,
|
||||
input: { itemId },
|
||||
fetch,
|
||||
})
|
||||
}
|
||||
} else if (item.quantity) {
|
||||
throw new ValidationError({
|
||||
message: 'The item quantity has to be a valid integer',
|
||||
})
|
||||
}
|
||||
|
||||
return await fetch({
|
||||
...options,
|
||||
body: { itemId, item },
|
||||
})
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) =>
|
||||
function useHook<T extends LineItem | undefined = undefined>(
|
||||
ctx: {
|
||||
item?: T
|
||||
wait?: number
|
||||
} = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useAddresses() as any
|
||||
function useHook() {
|
||||
const { mutate } = useAddresses()
|
||||
|
||||
return useCallback(
|
||||
debounce(async (input: UpdateItemActionInput<T>) => {
|
||||
const itemId = input.id ?? item?.id
|
||||
const productId = input.productId ?? item?.productId
|
||||
const variantId = input.productId ?? item?.variantId
|
||||
async function updateItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
if (!itemId || !productId) {
|
||||
throw new ValidationError({
|
||||
message: 'Invalid input used for this operation',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({
|
||||
input: {
|
||||
itemId,
|
||||
item: {
|
||||
productId,
|
||||
variantId: variantId || '',
|
||||
quantity: input.quantity,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}, ctx.wait ?? 500),
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
|
@@ -2,7 +2,6 @@ import type { AddItemHook } from '@commerce/types/customer/card'
|
||||
import type { MutationHook } from '@commerce/utils/types'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import { CommerceError } from '@commerce/utils/errors'
|
||||
import useAddItem, { UseAddItem } from '@commerce/customer/card/use-add-item'
|
||||
import useCards from './use-cards'
|
||||
|
||||
@@ -14,15 +13,6 @@ export const handler: MutationHook<AddItemHook> = {
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
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',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({
|
||||
...options,
|
||||
body: { item },
|
||||
@@ -38,7 +28,7 @@ export const handler: MutationHook<AddItemHook> = {
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
|
@@ -22,7 +22,7 @@ export const handler: SWRHook<GetCardsHook> = {
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.lineItems?.length ?? 0) <= 0
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
|
@@ -2,20 +2,22 @@ import type {
|
||||
MutationHookContext,
|
||||
HookFetcherContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/customer/card'
|
||||
import type { Card, RemoveItemHook } from '@commerce/types/customer/card'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useRemoveItem, { UseRemoveItem } from '@commerce/customer/card/use-remove-item'
|
||||
import useRemoveItem, {
|
||||
UseRemoveItem,
|
||||
} from '@commerce/customer/card/use-remove-item'
|
||||
|
||||
import useCards from './use-cards'
|
||||
|
||||
export type RemoveItemFn<T = any> = T extends LineItem
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Cart | null>
|
||||
export type RemoveItemFn<T = any> = T extends Card
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Card | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Card | null>
|
||||
|
||||
export type RemoveItemActionInput<T = any> = T extends LineItem
|
||||
export type RemoveItemActionInput<T = any> = T extends Card
|
||||
? Partial<RemoveItemHook['actionInput']>
|
||||
: RemoveItemHook['actionInput']
|
||||
|
||||
@@ -34,12 +36,12 @@ export const handler = {
|
||||
return await fetch({ ...options, body: { itemId } })
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) =>
|
||||
function useHook<T extends LineItem | undefined = undefined>(
|
||||
function useHook<T extends Card | undefined = undefined>(
|
||||
ctx: { item?: T } = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useCards()
|
||||
const removeItem: RemoveItemFn<LineItem> = async (input) => {
|
||||
const removeItem: RemoveItemFn<Card> = async (input) => {
|
||||
const itemId = input?.id ?? item?.id
|
||||
|
||||
if (!itemId) {
|
||||
@@ -50,7 +52,7 @@ export const handler = {
|
||||
|
||||
const data = await fetch({ input: { itemId } })
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}
|
||||
|
@@ -2,19 +2,18 @@ import type {
|
||||
HookFetcherContext,
|
||||
MutationHookContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { UpdateItemHook, LineItem } from '@commerce/types/customer/card'
|
||||
import type { UpdateItemHook, Card } from '@commerce/types/customer/card'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useUpdateItem, { UseUpdateItem } from '@commerce/customer/card/use-update-item'
|
||||
import useUpdateItem, {
|
||||
UseUpdateItem,
|
||||
} from '@commerce/customer/card/use-update-item'
|
||||
|
||||
import { handler as removeItemHandler } from './use-remove-item'
|
||||
import useCards from './use-cards'
|
||||
|
||||
export type UpdateItemActionInput<T = any> = T extends LineItem
|
||||
export type UpdateItemActionInput<T = any> = T extends Card
|
||||
? Partial<UpdateItemHook['actionInput']>
|
||||
: UpdateItemHook['actionInput']
|
||||
|
||||
@@ -30,63 +29,23 @@ export const handler: MutationHook<any> = {
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<UpdateItemHook>) {
|
||||
if (Number.isInteger(item.quantity)) {
|
||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||
if (item.quantity! < 1) {
|
||||
return removeItemHandler.fetcher({
|
||||
options: removeItemHandler.fetchOptions,
|
||||
input: { itemId },
|
||||
fetch,
|
||||
})
|
||||
}
|
||||
} else if (item.quantity) {
|
||||
throw new ValidationError({
|
||||
message: 'The item quantity has to be a valid integer',
|
||||
})
|
||||
}
|
||||
|
||||
return await fetch({
|
||||
...options,
|
||||
body: { itemId, item },
|
||||
})
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) =>
|
||||
function useHook<T extends LineItem | undefined = undefined>(
|
||||
ctx: {
|
||||
item?: T
|
||||
wait?: number
|
||||
} = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useCards() as any
|
||||
function useHook() {
|
||||
const { mutate } = useCards()
|
||||
|
||||
return useCallback(
|
||||
debounce(async (input: UpdateItemActionInput<T>) => {
|
||||
const itemId = input.id ?? item?.id
|
||||
const productId = input.productId ?? item?.productId
|
||||
const variantId = input.productId ?? item?.variantId
|
||||
async function updateItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
if (!itemId || !productId) {
|
||||
throw new ValidationError({
|
||||
message: 'Invalid input used for this operation',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({
|
||||
input: {
|
||||
itemId,
|
||||
item: {
|
||||
productId,
|
||||
variantId: variantId || '',
|
||||
quantity: input.quantity,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await mutate(data, false)
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}, ctx.wait ?? 500),
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
|
Reference in New Issue
Block a user