forked from crowetic/commerce
Updated how the hook input is handled
This commit is contained in:
parent
016be86d9a
commit
5aecb0f303
@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import {
|
import {
|
||||||
CommerceConfig,
|
CommerceConfig,
|
||||||
CommerceProvider as CoreCommerceProvider,
|
CommerceProvider as CoreCommerceProvider,
|
||||||
|
@ -43,7 +43,7 @@ const fetcher: Fetcher = async ({
|
|||||||
|
|
||||||
const useCart: HookHandler<
|
const useCart: HookHandler<
|
||||||
Cart | null,
|
Cart | null,
|
||||||
[],
|
{},
|
||||||
FetchCartInput,
|
FetchCartInput,
|
||||||
any,
|
any,
|
||||||
any,
|
any,
|
||||||
@ -71,7 +71,7 @@ const useCart: HookHandler<
|
|||||||
|
|
||||||
const useWishlist: HookHandler<
|
const useWishlist: HookHandler<
|
||||||
Cart | null,
|
Cart | null,
|
||||||
[],
|
{},
|
||||||
FetchCartInput,
|
FetchCartInput,
|
||||||
any,
|
any,
|
||||||
any,
|
any,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import type { Cart } from '../types'
|
|
||||||
import type { HookFetcherFn } from '../utils/types'
|
import type { HookFetcherFn } from '../utils/types'
|
||||||
import useData from '../utils/use-data-2'
|
import useData from '../utils/use-data-2'
|
||||||
|
import type { Cart } from '../types'
|
||||||
import { Provider, useCommerce } from '..'
|
import { Provider, useCommerce } from '..'
|
||||||
|
|
||||||
export type FetchCartInput = {
|
export type FetchCartInput = {
|
||||||
@ -13,13 +13,17 @@ export type CartResponse<P extends Provider> = ReturnType<
|
|||||||
NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>['onResponse']>
|
NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>['onResponse']>
|
||||||
>
|
>
|
||||||
|
|
||||||
export type UseCart<P extends Provider> = (
|
export type UseCartInput<P extends Provider> = Parameters<
|
||||||
...input: UseCartInput<P>
|
NonNullable<
|
||||||
) => CartResponse<P>
|
|
||||||
|
|
||||||
export type UseCartInput<P extends Provider> = NonNullable<
|
|
||||||
NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>>['input']
|
NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>>['input']
|
||||||
>
|
>
|
||||||
|
>[0]
|
||||||
|
|
||||||
|
export type UseCart<P extends Provider> = Partial<
|
||||||
|
UseCartInput<P>
|
||||||
|
> extends UseCartInput<P>
|
||||||
|
? (input?: UseCartInput<P>) => CartResponse<P>
|
||||||
|
: (input: UseCartInput<P>) => CartResponse<P>
|
||||||
|
|
||||||
export const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
|
export const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
|
||||||
options,
|
options,
|
||||||
@ -31,7 +35,7 @@ export const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
|
|||||||
return data && normalize ? normalize(data) : data
|
return data && normalize ? normalize(data) : data
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useCart<P extends Provider>(...input: UseCartInput<P>) {
|
export default function useCart<P extends Provider>(input?: UseCartInput<P>) {
|
||||||
const { providerRef, fetcherRef, cartCookie } = useCommerce<P>()
|
const { providerRef, fetcherRef, cartCookie } = useCommerce<P>()
|
||||||
|
|
||||||
const provider = providerRef.current
|
const provider = providerRef.current
|
||||||
@ -43,7 +47,7 @@ export default function useCart<P extends Provider>(...input: UseCartInput<P>) {
|
|||||||
}
|
}
|
||||||
const response = useData(
|
const response = useData(
|
||||||
{ ...opts, fetcher: wrapper },
|
{ ...opts, fetcher: wrapper },
|
||||||
input,
|
opts?.input ? opts.input(input ?? {}) : [],
|
||||||
provider.fetcher ?? fetcherRef.current
|
provider.fetcher ?? fetcherRef.current
|
||||||
)
|
)
|
||||||
const memoizedResponse = useMemo(
|
const memoizedResponse = useMemo(
|
||||||
|
@ -16,10 +16,10 @@ const Commerce = createContext<CommerceContextValue<any> | {}>({})
|
|||||||
export type Provider = CommerceConfig & {
|
export type Provider = CommerceConfig & {
|
||||||
fetcher: Fetcher
|
fetcher: Fetcher
|
||||||
cart?: {
|
cart?: {
|
||||||
useCart?: HookHandler<Cart | null, [...any], FetchCartInput>
|
useCart?: HookHandler<Cart | null, {}, FetchCartInput>
|
||||||
}
|
}
|
||||||
wishlist?: {
|
wishlist?: {
|
||||||
useWishlist?: HookHandler<Cart | null, [...any], FetchCartInput>
|
useWishlist?: HookHandler<Cart | null, {}, FetchCartInput>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,15 @@ import type { ResponseState } from './use-data'
|
|||||||
|
|
||||||
export type Override<T, K> = Omit<T, keyof K> & K
|
export type Override<T, K> = Omit<T, keyof K> & K
|
||||||
|
|
||||||
// Returns the properties in T with the properties in type K changed from optional to required
|
/**
|
||||||
|
* Returns the properties in T with the properties in type K changed from optional to required
|
||||||
|
*/
|
||||||
export type PickRequired<T, K extends keyof T> = Omit<T, K> &
|
export type PickRequired<T, K extends keyof T> = Omit<T, K> &
|
||||||
Required<Pick<T, K>>
|
Required<Pick<T, K>>
|
||||||
|
|
||||||
// Core fetcher added by CommerceProvider
|
/**
|
||||||
|
* Core fetcher added by CommerceProvider
|
||||||
|
*/
|
||||||
export type Fetcher<T = any, B = any> = (
|
export type Fetcher<T = any, B = any> = (
|
||||||
options: FetcherOptions<B>
|
options: FetcherOptions<B>
|
||||||
) => T | Promise<T>
|
) => T | Promise<T>
|
||||||
@ -47,15 +51,17 @@ export type HookFetcherOptions = {
|
|||||||
|
|
||||||
export type HookInputValue = string | number | boolean | undefined
|
export type HookInputValue = string | number | boolean | undefined
|
||||||
|
|
||||||
export type HookInput = [string, HookInputValue][]
|
export type HookSwrInput = [string, HookInputValue][]
|
||||||
|
|
||||||
export type HookFetchInput = { [k: string]: HookInputValue }
|
export type HookFetchInput = { [k: string]: HookInputValue }
|
||||||
|
|
||||||
|
export type HookInput = {}
|
||||||
|
|
||||||
export type HookHandler<
|
export type HookHandler<
|
||||||
// Data obj returned by the hook and fetch operation
|
// Data obj returned by the hook and fetch operation
|
||||||
Data,
|
Data,
|
||||||
// Input expected by the hook
|
// Input expected by the hook
|
||||||
Input = [...any],
|
Input extends { [k: string]: unknown } = {},
|
||||||
// Input expected before doing a fetch operation
|
// Input expected before doing a fetch operation
|
||||||
FetchInput extends HookFetchInput = never,
|
FetchInput extends HookFetchInput = never,
|
||||||
// Data returned by the API after a fetch operation
|
// Data returned by the API after a fetch operation
|
||||||
@ -65,7 +71,9 @@ export type HookHandler<
|
|||||||
// Custom state added to the response object of SWR
|
// Custom state added to the response object of SWR
|
||||||
State = {}
|
State = {}
|
||||||
> = {
|
> = {
|
||||||
input?: Input
|
input?(
|
||||||
|
input: Input & { swrOptions?: SwrOptions<Data, FetchInput, Result> }
|
||||||
|
): HookFetchInput | HookSwrInput
|
||||||
swrOptions?: SwrOptions<Data, FetchInput, Result>
|
swrOptions?: SwrOptions<Data, FetchInput, Result>
|
||||||
onResponse?(response: ResponseState<Data>): ResponseState<Data> & State
|
onResponse?(response: ResponseState<Data>): ResponseState<Data> & State
|
||||||
onMutation?: any
|
onMutation?: any
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import useSWR, { responseInterface } from 'swr'
|
import useSWR, { responseInterface } from 'swr'
|
||||||
import type {
|
import type {
|
||||||
HookHandler,
|
HookHandler,
|
||||||
HookInput,
|
HookSwrInput,
|
||||||
HookFetchInput,
|
HookFetchInput,
|
||||||
PickRequired,
|
PickRequired,
|
||||||
Fetcher,
|
Fetcher,
|
||||||
@ -15,7 +15,7 @@ export type ResponseState<Result> = responseInterface<Result, CommerceError> & {
|
|||||||
|
|
||||||
export type UseData = <
|
export type UseData = <
|
||||||
Data = any,
|
Data = any,
|
||||||
Input = [...any],
|
Input extends { [k: string]: unknown } = {},
|
||||||
FetchInput extends HookFetchInput = never,
|
FetchInput extends HookFetchInput = never,
|
||||||
Result = any,
|
Result = any,
|
||||||
Body = any
|
Body = any
|
||||||
@ -24,11 +24,12 @@ export type UseData = <
|
|||||||
HookHandler<Data, Input, FetchInput, Result, Body>,
|
HookHandler<Data, Input, FetchInput, Result, Body>,
|
||||||
'fetcher'
|
'fetcher'
|
||||||
>,
|
>,
|
||||||
input: HookInput,
|
input: HookFetchInput | HookSwrInput,
|
||||||
fetcherFn: Fetcher
|
fetcherFn: Fetcher
|
||||||
) => ResponseState<Data>
|
) => ResponseState<Data>
|
||||||
|
|
||||||
const useData: UseData = (options, input, fetcherFn) => {
|
const useData: UseData = (options, input, fetcherFn) => {
|
||||||
|
const hookInput = Array.isArray(input) ? input : Object.entries(input)
|
||||||
const fetcher = async (
|
const fetcher = async (
|
||||||
url?: string,
|
url?: string,
|
||||||
query?: string,
|
query?: string,
|
||||||
@ -40,7 +41,7 @@ const useData: UseData = (options, input, fetcherFn) => {
|
|||||||
options: { url, query, method },
|
options: { url, query, method },
|
||||||
// Transform the input array into an object
|
// Transform the input array into an object
|
||||||
input: args.reduce((obj, val, i) => {
|
input: args.reduce((obj, val, i) => {
|
||||||
obj[input[i][0]!] = val
|
obj[hookInput[i][0]!] = val
|
||||||
return obj
|
return obj
|
||||||
}, {}),
|
}, {}),
|
||||||
fetch: fetcherFn,
|
fetch: fetcherFn,
|
||||||
@ -59,7 +60,7 @@ const useData: UseData = (options, input, fetcherFn) => {
|
|||||||
() => {
|
() => {
|
||||||
const opts = options.fetchOptions
|
const opts = options.fetchOptions
|
||||||
return opts
|
return opts
|
||||||
? [opts.url, opts.query, opts.method, ...input.map((e) => e[1])]
|
? [opts.url, opts.query, opts.method, ...hookInput.map((e) => e[1])]
|
||||||
: null
|
: null
|
||||||
},
|
},
|
||||||
fetcher,
|
fetcher,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import useSWR, { ConfigInterface, responseInterface } from 'swr'
|
import useSWR, { ConfigInterface, responseInterface } from 'swr'
|
||||||
import type { HookInput, HookFetcher, HookFetcherOptions } from './types'
|
import type { HookSwrInput, HookFetcher, HookFetcherOptions } from './types'
|
||||||
import defineProperty from './define-property'
|
import defineProperty from './define-property'
|
||||||
import { CommerceError } from './errors'
|
import { CommerceError } from './errors'
|
||||||
import { useCommerce } from '..'
|
import { useCommerce } from '..'
|
||||||
@ -16,7 +16,7 @@ export type ResponseState<Result> = responseInterface<Result, CommerceError> & {
|
|||||||
|
|
||||||
export type UseData = <Data = any, Input = null, Result = any>(
|
export type UseData = <Data = any, Input = null, Result = any>(
|
||||||
options: HookFetcherOptions | (() => HookFetcherOptions | null),
|
options: HookFetcherOptions | (() => HookFetcherOptions | null),
|
||||||
input: HookInput,
|
input: HookSwrInput,
|
||||||
fetcherFn: HookFetcher<Data, Input, Result>,
|
fetcherFn: HookFetcher<Data, Input, Result>,
|
||||||
swrOptions?: SwrOptions<Data, Input, Result>
|
swrOptions?: SwrOptions<Data, Input, Result>
|
||||||
) => ResponseState<Data>
|
) => ResponseState<Data>
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import type { HookInput, HookFetcher, HookFetcherOptions } from '../utils/types'
|
import type {
|
||||||
|
HookSwrInput,
|
||||||
|
HookFetcher,
|
||||||
|
HookFetcherOptions,
|
||||||
|
} from '../utils/types'
|
||||||
import useData, { ResponseState, SwrOptions } from '../utils/use-data'
|
import useData, { ResponseState, SwrOptions } from '../utils/use-data'
|
||||||
|
|
||||||
export type WishlistResponse<Result> = ResponseState<Result> & {
|
export type WishlistResponse<Result> = ResponseState<Result> & {
|
||||||
@ -7,7 +11,7 @@ export type WishlistResponse<Result> = ResponseState<Result> & {
|
|||||||
|
|
||||||
export default function useWishlist<Result, Input = null>(
|
export default function useWishlist<Result, Input = null>(
|
||||||
options: HookFetcherOptions,
|
options: HookFetcherOptions,
|
||||||
input: HookInput,
|
input: HookSwrInput,
|
||||||
fetcherFn: HookFetcher<Result, Input>,
|
fetcherFn: HookFetcher<Result, Input>,
|
||||||
swrOptions?: SwrOptions<Result, Input>
|
swrOptions?: SwrOptions<Result, Input>
|
||||||
): WishlistResponse<Result> {
|
): WishlistResponse<Result> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user