mirror of
https://github.com/vercel/commerce.git
synced 2025-07-27 04:01:23 +00:00
Add ordercloud provider (#500)
* Add ordercloud provider * Fix provider errors * Make submit checkout optional * Make submit checkout optional * Remove nullables when creating endpoint type * Update readme * Log checkout error * Log error * Save token to cookie * Update fetch rest * Use token at checkout Co-authored-by: Luis Alvarez <luis@vercel.com>
This commit is contained in:
4
framework/ordercloud/customer/address/index.ts
Normal file
4
framework/ordercloud/customer/address/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as useAddresses } from './use-addresses'
|
||||
export { default as useAddItem } from './use-add-item'
|
||||
export { default as useRemoveItem } from './use-remove-item'
|
||||
export { default as useUpdateItem } from './use-update-item'
|
38
framework/ordercloud/customer/address/use-add-item.tsx
Normal file
38
framework/ordercloud/customer/address/use-add-item.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { AddItemHook } from '@commerce/types/customer/address'
|
||||
import type { MutationHook } from '@commerce/utils/types'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import useAddItem, { UseAddItem } from '@commerce/customer/address/use-add-item'
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/address',
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
const data = await fetch({
|
||||
...options,
|
||||
body: { item },
|
||||
})
|
||||
|
||||
return data
|
||||
},
|
||||
useHook: ({ fetch }) =>
|
||||
function useHook() {
|
||||
const { mutate } = useAddresses()
|
||||
|
||||
return useCallback(
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
35
framework/ordercloud/customer/address/use-addresses.tsx
Normal file
35
framework/ordercloud/customer/address/use-addresses.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { GetAddressesHook } from '@commerce/types/customer/address'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useAddresses, {
|
||||
UseAddresses,
|
||||
} from '@commerce/customer/address/use-addresses'
|
||||
|
||||
export default useAddresses as UseAddresses<typeof handler>
|
||||
|
||||
export const handler: SWRHook<GetAddressesHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/address',
|
||||
method: 'GET',
|
||||
},
|
||||
useHook: ({ useData }) =>
|
||||
function useHook(input) {
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
62
framework/ordercloud/customer/address/use-remove-item.tsx
Normal file
62
framework/ordercloud/customer/address/use-remove-item.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import type {
|
||||
MutationHookContext,
|
||||
HookFetcherContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { Address, RemoveItemHook } from '@commerce/types/customer/address'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useRemoveItem, {
|
||||
UseRemoveItem,
|
||||
} from '@commerce/customer/address/use-remove-item'
|
||||
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
export type RemoveItemFn<T = any> = T extends Address
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Address | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Address | null>
|
||||
|
||||
export type RemoveItemActionInput<T = any> = T extends Address
|
||||
? Partial<RemoveItemHook['actionInput']>
|
||||
: RemoveItemHook['actionInput']
|
||||
|
||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||
|
||||
export const handler = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/address',
|
||||
method: 'DELETE',
|
||||
},
|
||||
async fetcher({
|
||||
input: { itemId },
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<RemoveItemHook>) {
|
||||
return await fetch({ ...options, body: { itemId } })
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) =>
|
||||
function useHook<T extends Address | undefined = undefined>(
|
||||
ctx: { item?: T } = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useAddresses()
|
||||
const removeItem: RemoveItemFn<Address> = async (input) => {
|
||||
const itemId = input?.id ?? item?.id
|
||||
|
||||
if (!itemId) {
|
||||
throw new ValidationError({
|
||||
message: 'Invalid input used for this operation',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({ input: { itemId } })
|
||||
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
|
||||
},
|
||||
}
|
52
framework/ordercloud/customer/address/use-update-item.tsx
Normal file
52
framework/ordercloud/customer/address/use-update-item.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type {
|
||||
HookFetcherContext,
|
||||
MutationHookContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { UpdateItemHook, Address } from '@commerce/types/customer/address'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import useUpdateItem, {
|
||||
UseUpdateItem,
|
||||
} from '@commerce/customer/address/use-update-item'
|
||||
|
||||
import useAddresses from './use-addresses'
|
||||
|
||||
export type UpdateItemActionInput<T = any> = T extends Address
|
||||
? Partial<UpdateItemHook['actionInput']>
|
||||
: UpdateItemHook['actionInput']
|
||||
|
||||
export default useUpdateItem as UseUpdateItem<any>
|
||||
|
||||
export const handler: MutationHook<any> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/address',
|
||||
method: 'PUT',
|
||||
},
|
||||
async fetcher({
|
||||
input: { itemId, item },
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<UpdateItemHook>) {
|
||||
return await fetch({
|
||||
...options,
|
||||
body: { itemId, item },
|
||||
})
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) =>
|
||||
function useHook() {
|
||||
const { mutate } = useAddresses()
|
||||
|
||||
return useCallback(
|
||||
async function updateItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
4
framework/ordercloud/customer/card/index.ts
Normal file
4
framework/ordercloud/customer/card/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as useCards } from './use-cards'
|
||||
export { default as useAddItem } from './use-add-item'
|
||||
export { default as useRemoveItem } from './use-remove-item'
|
||||
export { default as useUpdateItem } from './use-update-item'
|
38
framework/ordercloud/customer/card/use-add-item.tsx
Normal file
38
framework/ordercloud/customer/card/use-add-item.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { AddItemHook } from '@commerce/types/customer/card'
|
||||
import type { MutationHook } from '@commerce/utils/types'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
import useAddItem, { UseAddItem } from '@commerce/customer/card/use-add-item'
|
||||
import useCards from './use-cards'
|
||||
|
||||
export default useAddItem as UseAddItem<typeof handler>
|
||||
|
||||
export const handler: MutationHook<AddItemHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/card',
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ input: item, options, fetch }) {
|
||||
const data = await fetch({
|
||||
...options,
|
||||
body: { item },
|
||||
})
|
||||
|
||||
return data
|
||||
},
|
||||
useHook: ({ fetch }) =>
|
||||
function useHook() {
|
||||
const { mutate } = useCards()
|
||||
|
||||
return useCallback(
|
||||
async function addItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([data], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
33
framework/ordercloud/customer/card/use-cards.tsx
Normal file
33
framework/ordercloud/customer/card/use-cards.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { GetCardsHook } from '@commerce/types/customer/card'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useCard, { UseCards } from '@commerce/customer/card/use-cards'
|
||||
|
||||
export default useCard as UseCards<typeof handler>
|
||||
|
||||
export const handler: SWRHook<GetCardsHook> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/card',
|
||||
method: 'GET',
|
||||
},
|
||||
useHook: ({ useData }) =>
|
||||
function useHook(input) {
|
||||
const response = useData({
|
||||
swrOptions: { revalidateOnFocus: false, ...input?.swrOptions },
|
||||
})
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
Object.create(response, {
|
||||
isEmpty: {
|
||||
get() {
|
||||
return (response.data?.length ?? 0) <= 0
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
}),
|
||||
[response]
|
||||
)
|
||||
},
|
||||
}
|
62
framework/ordercloud/customer/card/use-remove-item.tsx
Normal file
62
framework/ordercloud/customer/card/use-remove-item.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import type {
|
||||
MutationHookContext,
|
||||
HookFetcherContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { Card, RemoveItemHook } from '@commerce/types/customer/card'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { ValidationError } from '@commerce/utils/errors'
|
||||
import useRemoveItem, {
|
||||
UseRemoveItem,
|
||||
} from '@commerce/customer/card/use-remove-item'
|
||||
|
||||
import useCards from './use-cards'
|
||||
|
||||
export type RemoveItemFn<T = any> = T extends Card
|
||||
? (input?: RemoveItemActionInput<T>) => Promise<Card | null | undefined>
|
||||
: (input: RemoveItemActionInput<T>) => Promise<Card | null>
|
||||
|
||||
export type RemoveItemActionInput<T = any> = T extends Card
|
||||
? Partial<RemoveItemHook['actionInput']>
|
||||
: RemoveItemHook['actionInput']
|
||||
|
||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||
|
||||
export const handler = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/card',
|
||||
method: 'DELETE',
|
||||
},
|
||||
async fetcher({
|
||||
input: { itemId },
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<RemoveItemHook>) {
|
||||
return await fetch({ ...options, body: { itemId } })
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) =>
|
||||
function useHook<T extends Card | undefined = undefined>(
|
||||
ctx: { item?: T } = {}
|
||||
) {
|
||||
const { item } = ctx
|
||||
const { mutate } = useCards()
|
||||
const removeItem: RemoveItemFn<Card> = async (input) => {
|
||||
const itemId = input?.id ?? item?.id
|
||||
|
||||
if (!itemId) {
|
||||
throw new ValidationError({
|
||||
message: 'Invalid input used for this operation',
|
||||
})
|
||||
}
|
||||
|
||||
const data = await fetch({ input: { itemId } })
|
||||
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
|
||||
},
|
||||
}
|
52
framework/ordercloud/customer/card/use-update-item.tsx
Normal file
52
framework/ordercloud/customer/card/use-update-item.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type {
|
||||
HookFetcherContext,
|
||||
MutationHookContext,
|
||||
} from '@commerce/utils/types'
|
||||
import type { UpdateItemHook, Card } from '@commerce/types/customer/card'
|
||||
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { MutationHook } from '@commerce/utils/types'
|
||||
import useUpdateItem, {
|
||||
UseUpdateItem,
|
||||
} from '@commerce/customer/card/use-update-item'
|
||||
|
||||
import useCards from './use-cards'
|
||||
|
||||
export type UpdateItemActionInput<T = any> = T extends Card
|
||||
? Partial<UpdateItemHook['actionInput']>
|
||||
: UpdateItemHook['actionInput']
|
||||
|
||||
export default useUpdateItem as UseUpdateItem<any>
|
||||
|
||||
export const handler: MutationHook<any> = {
|
||||
fetchOptions: {
|
||||
url: '/api/customer/card',
|
||||
method: 'PUT',
|
||||
},
|
||||
async fetcher({
|
||||
input: { itemId, item },
|
||||
options,
|
||||
fetch,
|
||||
}: HookFetcherContext<UpdateItemHook>) {
|
||||
return await fetch({
|
||||
...options,
|
||||
body: { itemId, item },
|
||||
})
|
||||
},
|
||||
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) =>
|
||||
function useHook() {
|
||||
const { mutate } = useCards()
|
||||
|
||||
return useCallback(
|
||||
async function updateItem(input) {
|
||||
const data = await fetch({ input })
|
||||
|
||||
await mutate([], false)
|
||||
|
||||
return data
|
||||
},
|
||||
[fetch, mutate]
|
||||
)
|
||||
},
|
||||
}
|
1
framework/ordercloud/customer/index.ts
Normal file
1
framework/ordercloud/customer/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as useCustomer } from './use-customer'
|
15
framework/ordercloud/customer/use-customer.tsx
Normal file
15
framework/ordercloud/customer/use-customer.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { SWRHook } from '@commerce/utils/types'
|
||||
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
||||
|
||||
export default useCustomer as UseCustomer<typeof handler>
|
||||
export const handler: SWRHook<any> = {
|
||||
fetchOptions: {
|
||||
query: '',
|
||||
},
|
||||
async fetcher({ input, options, fetch }) {},
|
||||
useHook: () => () => {
|
||||
return async function addItem() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
}
|
Reference in New Issue
Block a user