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