forked from crowetic/commerce
Added useResponse hook
This commit is contained in:
parent
2613a5cec7
commit
bafb8a4479
@ -1,10 +1,9 @@
|
||||
import { normalizeCart } from '../lib/normalize'
|
||||
import type { HookFetcher } from '@commerce/utils/types'
|
||||
import type { SwrOptions } from '@commerce/utils/use-data'
|
||||
import defineProperty from '@commerce/utils/define-property'
|
||||
import useResponse from '@commerce/utils/use-response'
|
||||
import useCommerceCart, { CartInput } from '@commerce/cart/use-cart'
|
||||
import type { Cart as BigCommerceCart } from '../api/cart'
|
||||
import update from '@framework/lib/immutability'
|
||||
|
||||
const defaultOpts = {
|
||||
url: '/api/bigcommerce/cart',
|
||||
@ -30,25 +29,21 @@ export function extendHook(
|
||||
revalidateOnFocus: false,
|
||||
...swrOptions,
|
||||
})
|
||||
|
||||
// Uses a getter to only calculate the prop when required
|
||||
// response.data is also a getter and it's better to not trigger it early
|
||||
if (!('isEmpty' in response)) {
|
||||
defineProperty(response, 'isEmpty', {
|
||||
get() {
|
||||
return Object.values(response.data?.line_items ?? {}).every(
|
||||
(items) => !items.length
|
||||
)
|
||||
const res = useResponse(response, {
|
||||
normalizer: normalizeCart,
|
||||
descriptors: {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return Object.values(response.data?.line_items ?? {}).every(
|
||||
(items) => !items.length
|
||||
)
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
set: (x) => x,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return response.data
|
||||
? update(response, {
|
||||
data: { $set: normalizeCart(response.data) },
|
||||
})
|
||||
: response
|
||||
return res
|
||||
}
|
||||
|
||||
useCart.extend = extendHook
|
||||
|
@ -1,4 +1,3 @@
|
||||
import type { responseInterface } from 'swr'
|
||||
import Cookies from 'js-cookie'
|
||||
import type { HookInput, HookFetcher, HookFetcherOptions } from '../utils/types'
|
||||
import useData, { ResponseState, SwrOptions } from '../utils/use-data'
|
||||
@ -17,12 +16,10 @@ export default function useCart<Result>(
|
||||
swrOptions?: SwrOptions<Result, CartInput>
|
||||
): CartResponse<Result> {
|
||||
const { cartCookie } = useCommerce()
|
||||
|
||||
const fetcher: typeof fetcherFn = (options, input, fetch) => {
|
||||
input.cartId = Cookies.get(cartCookie)
|
||||
return fetcherFn(options, input, fetch)
|
||||
}
|
||||
|
||||
const response = useData(options, input, fetcher, swrOptions)
|
||||
|
||||
return response
|
||||
|
@ -22,3 +22,5 @@ export type HookFetcherOptions = {
|
||||
}
|
||||
|
||||
export type HookInput = [string, string | number | boolean | undefined][]
|
||||
|
||||
export type Override<T, K> = Omit<T, keyof K> & K
|
||||
|
@ -64,7 +64,7 @@ const useData: UseData = (options, input, fetcherFn, swrOptions) => {
|
||||
get() {
|
||||
return response.data === undefined
|
||||
},
|
||||
set: (x) => x,
|
||||
enumerable: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
40
framework/commerce/utils/use-response.tsx
Normal file
40
framework/commerce/utils/use-response.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { useMemo } from 'react'
|
||||
import { responseInterface } from 'swr'
|
||||
import { CommerceError } from './errors'
|
||||
import { Override } from './types'
|
||||
|
||||
export type UseResponseOptions<
|
||||
D,
|
||||
R extends responseInterface<any, CommerceError>
|
||||
> = {
|
||||
descriptors?: PropertyDescriptorMap
|
||||
normalizer?: (data: R['data']) => D
|
||||
}
|
||||
|
||||
export type UseResponse = <D, R extends responseInterface<any, CommerceError>>(
|
||||
response: R,
|
||||
options: UseResponseOptions<D, R>
|
||||
) => D extends object ? Override<R, { data?: D }> : R
|
||||
|
||||
const useResponse: UseResponse = (response, { descriptors, normalizer }) => {
|
||||
const memoizedResponse = useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
...descriptors,
|
||||
...(normalizer
|
||||
? {
|
||||
data: {
|
||||
get() {
|
||||
return normalizer(response.data)
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
return memoizedResponse
|
||||
}
|
||||
|
||||
export default useResponse
|
@ -1,4 +1,3 @@
|
||||
import type { responseInterface } from 'swr'
|
||||
import type { HookInput, HookFetcher, HookFetcherOptions } from '../utils/types'
|
||||
import useData, { ResponseState, SwrOptions } from '../utils/use-data'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user