From e7980e17f576930e081fed67f57e16aeff958fbb Mon Sep 17 00:00:00 2001
From: Luis Alvarez <luis@vercel.com>
Date: Tue, 25 May 2021 10:59:22 -0500
Subject: [PATCH] Updated useCustomer and core types

---
 framework/bigcommerce/customer/use-customer.tsx |  8 ++++----
 framework/commerce/customer/use-customer.tsx    |  8 ++++----
 framework/commerce/types/customer.ts            |  7 +++++++
 framework/commerce/utils/types.ts               | 17 +++++++++++------
 4 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/framework/bigcommerce/customer/use-customer.tsx b/framework/bigcommerce/customer/use-customer.tsx
index 093007824..238b1229b 100644
--- a/framework/bigcommerce/customer/use-customer.tsx
+++ b/framework/bigcommerce/customer/use-customer.tsx
@@ -1,16 +1,16 @@
 import { SWRHook } from '@commerce/utils/types'
 import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
-import type { Customer, CustomerData } from '../api/customers'
+import type { CustomerHook } from '../types/customer'
 
 export default useCustomer as UseCustomer<typeof handler>
 
-export const handler: SWRHook<Customer | null> = {
+export const handler: SWRHook<CustomerHook> = {
   fetchOptions: {
-    url: '/api/bigcommerce/customers',
+    url: '/api/customer',
     method: 'GET',
   },
   async fetcher({ options, fetch }) {
-    const data = await fetch<CustomerData | null>(options)
+    const data = await fetch(options)
     return data?.customer ?? null
   },
   useHook: ({ useData }) => (input) => {
diff --git a/framework/commerce/customer/use-customer.tsx b/framework/commerce/customer/use-customer.tsx
index 5d6416a4b..bbeeb3269 100644
--- a/framework/commerce/customer/use-customer.tsx
+++ b/framework/commerce/customer/use-customer.tsx
@@ -1,14 +1,14 @@
 import { useHook, useSWRHook } from '../utils/use-hook'
 import { SWRFetcher } from '../utils/default-fetcher'
+import type { CustomerHook } from '../types/customer'
 import type { HookFetcherFn, SWRHook } from '../utils/types'
-import type { Customer } from '../types'
-import { Provider } from '..'
+import type { Provider } from '..'
 
 export type UseCustomer<
-  H extends SWRHook<any, any, any> = SWRHook<Customer | null>
+  H extends SWRHook<CustomerHook<any>> = SWRHook<CustomerHook>
 > = ReturnType<H['useHook']>
 
-export const fetcher: HookFetcherFn<Customer | null, any> = SWRFetcher
+export const fetcher: HookFetcherFn<CustomerHook> = SWRFetcher
 
 const fn = (provider: Provider) => provider.customer?.useCustomer!
 
diff --git a/framework/commerce/types/customer.ts b/framework/commerce/types/customer.ts
index 46c415f0a..4df0fade3 100644
--- a/framework/commerce/types/customer.ts
+++ b/framework/commerce/types/customer.ts
@@ -5,6 +5,13 @@ export type CustomerTypes = {
   customer: Customer
 }
 
+export type CustomerHook<T extends CustomerTypes = CustomerTypes> = {
+  data: T['customer'] | null
+  fetchData: { customer: T['customer'] } | null
+  // actionInput: T['body']
+  // fetchInput: T['body']
+}
+
 export type CustomerSchema<T extends CustomerTypes = CustomerTypes> = {
   endpoint: {
     options: {}
diff --git a/framework/commerce/utils/types.ts b/framework/commerce/utils/types.ts
index 736ef60f3..e842df58c 100644
--- a/framework/commerce/utils/types.ts
+++ b/framework/commerce/utils/types.ts
@@ -43,7 +43,12 @@ export type HookFetcherFn<H extends HookSchemaBase> = (
 export type HookFetcherContext<H extends HookSchemaBase> = {
   options: HookFetcherOptions
   input: H['fetchInput']
-  fetch: <T = any, B = H['body']>(options: FetcherOptions<B>) => Promise<T>
+  fetch: {
+    (
+      options: FetcherOptions<H['body'] extends {} ? H['body'] : never>
+    ): Promise<H['fetchData'] extends {} | null ? H['fetchData'] : any>
+    <T = any, B = any>(options: FetcherOptions<B>): Promise<T>
+  }
 }
 
 export type HookFetcherOptions = { method?: string } & (
@@ -67,19 +72,21 @@ export type HookFunction<
   : (input: Input) => T
 
 export type HookSchemaBase = {
-  // Data obj returned by the hook and fetch operation
+  // Data obj returned by the hook
   data: any
   // Input expected by the hook
   input?: {}
   // Input expected before doing a fetch operation (aka fetch handler)
   fetchInput?: {}
-  // Data expected by the fetch operation
+  // Body object expected by the fetch operation
   body?: {}
+  // Data returned by the fetch operation
+  fetchData?: any
 }
 
 export type SWRHookSchemaBase = HookSchemaBase & {
   // Custom state added to the response object of SWR
-  swrState: {}
+  swrState?: {}
 }
 
 export type MutationSchemaBase = HookSchemaBase & {
@@ -101,8 +108,6 @@ export type SWRHook<H extends SWRHookSchemaBase> = {
   fetcher?: HookFetcherFn<H>
 }
 
-type X = {} & undefined
-
 export type SWRHookContext<H extends SWRHookSchemaBase> = {
   useData(context?: {
     input?: HookFetchInput | HookSWRInput