From 8ad6a341751368b2b4877cf7b8d962137899a59d Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Mon, 29 Mar 2021 11:25:21 -0600 Subject: [PATCH] Updated types for hooks now using the API --- framework/bigcommerce/cart/use-cart.tsx | 11 +-- framework/commerce/cart/use-add-item.tsx | 9 +-- framework/commerce/cart/use-cart.tsx | 17 +---- framework/commerce/types/cart.ts | 5 ++ framework/commerce/utils/types.ts | 94 +++++++++++++----------- 5 files changed, 67 insertions(+), 69 deletions(-) diff --git a/framework/bigcommerce/cart/use-cart.tsx b/framework/bigcommerce/cart/use-cart.tsx index 2098e7431..2ef5f606c 100644 --- a/framework/bigcommerce/cart/use-cart.tsx +++ b/framework/bigcommerce/cart/use-cart.tsx @@ -1,17 +1,12 @@ import { useMemo } from 'react' import { SWRHook } from '@commerce/utils/types' -import useCart, { UseCart, FetchCartInput } from '@commerce/cart/use-cart' +import useCart, { UseCart } from '@commerce/cart/use-cart' import { normalizeCart } from '../lib/normalize' -import type { Cart } from '../types' +import type { GetCartHook } from '../types/cart' export default useCart as UseCart -export const handler: SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } -> = { +export const handler: SWRHook = { fetchOptions: { url: '/api/bigcommerce/cart', method: 'GET', diff --git a/framework/commerce/cart/use-add-item.tsx b/framework/commerce/cart/use-add-item.tsx index 324464656..072e68674 100644 --- a/framework/commerce/cart/use-add-item.tsx +++ b/framework/commerce/cart/use-add-item.tsx @@ -1,17 +1,14 @@ import { useHook, useMutationHook } from '../utils/use-hook' import { mutationFetcher } from '../utils/default-fetcher' import type { HookFetcherFn, MutationHook } from '../utils/types' -import type { Cart, CartItemBody, AddCartItemBody } from '../types' +import type { AddItemHook } from '../types/cart' import type { Provider } from '..' export type UseAddItem< - H extends MutationHook = MutationHook + H extends MutationHook = MutationHook > = ReturnType -export const fetcher: HookFetcherFn< - Cart, - AddCartItemBody -> = mutationFetcher +export const fetcher: HookFetcherFn = mutationFetcher const fn = (provider: Provider) => provider.cart?.useAddItem! diff --git a/framework/commerce/cart/use-cart.tsx b/framework/commerce/cart/use-cart.tsx index 98ab9713d..57008a42d 100644 --- a/framework/commerce/cart/use-cart.tsx +++ b/framework/commerce/cart/use-cart.tsx @@ -1,23 +1,14 @@ import Cookies from 'js-cookie' import { useHook, useSWRHook } from '../utils/use-hook' -import type { HookFetcherFn, SWRHook } from '../utils/types' -import type { Cart } from '../types/cart' +import type { SWRHook, HookFetcherFn } from '../utils/types' +import type { GetCartHook } from '../types/cart' import { Provider, useCommerce } from '..' -export type FetchCartInput = { - cartId?: Cart['id'] -} - export type UseCart< - H extends SWRHook = SWRHook< - Cart | null, - {}, - FetchCartInput, - { isEmpty?: boolean } - > + H extends SWRHook = SWRHook > = ReturnType -export const fetcher: HookFetcherFn = async ({ +export const fetcher: HookFetcherFn = async ({ options, input: { cartId }, fetch, diff --git a/framework/commerce/types/cart.ts b/framework/commerce/types/cart.ts index 82959bf78..91cd3819c 100644 --- a/framework/commerce/types/cart.ts +++ b/framework/commerce/types/cart.ts @@ -94,11 +94,16 @@ export type CartHooks = { export type GetCartHook = { data: Cart | null + input: {} + fetchInput: { cartId?: string } + swrState: { isEmpty: boolean } } export type AddItemHook = { data: Cart body: { item: CartItemBody } + input: CartItemBody + fetchInput: { item: CartItemBody } } export type UpdateItemHook = { diff --git a/framework/commerce/utils/types.ts b/framework/commerce/utils/types.ts index 852afb208..865f7279d 100644 --- a/framework/commerce/utils/types.ts +++ b/framework/commerce/utils/types.ts @@ -36,9 +36,13 @@ export type HookFetcher = ( fetch: (options: FetcherOptions) => Promise ) => Data | Promise -export type HookFetcherFn = ( - context: HookFetcherContext -) => Data | Promise +export type HookFetcherFn< + H extends HookSchemaBase, + Result = any, + Body = any +> = ( + context: HookFetcherContext +) => H['data'] | Promise export type HookFetcherContext = { options: HookFetcherOptions @@ -58,7 +62,7 @@ export type HookSWRInput = [string, HookInputValue][] export type HookFetchInput = { [k: string]: HookInputValue } export type HookFunction< - Input extends { [k: string]: unknown } | null, + Input extends { [k: string]: unknown } | undefined, T > = keyof Input extends never ? () => T @@ -66,62 +70,68 @@ export type HookFunction< ? (input?: Input) => T : (input: Input) => T -export type SWRHook< +export type HookSchemaBase = { // Data obj returned by the hook and fetch operation - Data, + data: any // Input expected by the hook - Input extends { [k: string]: unknown } = {}, + input: {} // Input expected before doing a fetch operation - FetchInput extends HookFetchInput = {}, + fetchInput?: {} +} + +export type SWRHookSchemaBase = HookSchemaBase & { // Custom state added to the response object of SWR - State = {} -> = { + swrState: {} +} + +export type MutationSchemaBase = HookSchemaBase & { + // Input expected by the action returned by the hook + actionInput?: {} +} + +/** + * Generates a SWR hook handler based on the schema of a hook + */ +export type SWRHook = { useHook( - context: SWRHookContext + context: SWRHookContext ): HookFunction< - Input & { swrOptions?: SwrOptions }, - ResponseState & State + H['input'] & { swrOptions?: SwrOptions }, + ResponseState & H['swrState'] > fetchOptions: HookFetcherOptions - fetcher?: HookFetcherFn + fetcher?: HookFetcherFn } -export type SWRHookContext< - Data, - FetchInput extends { [k: string]: unknown } = {} -> = { +type X = {} & undefined + +export type SWRHookContext = { useData(context?: { input?: HookFetchInput | HookSWRInput - swrOptions?: SwrOptions - }): ResponseState + swrOptions?: SwrOptions + }): ResponseState } -export type MutationHook< - // Data obj returned by the hook and fetch operation - Data, - // Input expected by the hook - Input extends { [k: string]: unknown } = {}, - // Input expected by the action returned by the hook - ActionInput extends { [k: string]: unknown } = {}, - // Input expected before doing a fetch operation - FetchInput extends { [k: string]: unknown } = ActionInput -> = { +/** + * Generates a mutation hook handler based on the schema of a hook + */ +export type MutationHook = { useHook( - context: MutationHookContext - ): HookFunction>> + context: MutationHookContext + ): HookFunction< + H['input'], + HookFunction> + > fetchOptions: HookFetcherOptions - fetcher?: HookFetcherFn + fetcher?: HookFetcherFn } -export type MutationHookContext< - Data, - FetchInput extends { [k: string]: unknown } | null = {} -> = { - fetch: keyof FetchInput extends never - ? () => Data | Promise - : Partial extends FetchInput - ? (context?: { input?: FetchInput }) => Data | Promise - : (context: { input: FetchInput }) => Data | Promise +export type MutationHookContext = { + fetch: keyof H['fetchInput'] extends never + ? () => H['data'] | Promise + : Partial extends H['fetchInput'] + ? (context?: { input?: H['fetchInput'] }) => H['data'] | Promise + : (context: { input: H['fetchInput'] }) => H['data'] | Promise } export type SwrOptions = ConfigInterface<