mirror of
https://github.com/vercel/commerce.git
synced 2025-06-30 18:31:21 +00:00
Added the get customer wishlist operation
This commit is contained in:
parent
676b614bf6
commit
a1167e46f7
@ -1,4 +1,4 @@
|
|||||||
import getCustomerWishlist from '../../../customer/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import { parseWishlistItem } from '../../utils/parse-item'
|
import { parseWishlistItem } from '../../utils/parse-item'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from './utils/get-customer-id'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
@ -8,6 +8,7 @@ const addItem: WishlistEndpoint['handlers']['addItem'] = async ({
|
|||||||
res,
|
res,
|
||||||
body: { customerToken, item },
|
body: { customerToken, item },
|
||||||
config,
|
config,
|
||||||
|
commerce,
|
||||||
}) => {
|
}) => {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
@ -26,7 +27,7 @@ const addItem: WishlistEndpoint['handlers']['addItem'] = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { wishlist } = await getCustomerWishlist({
|
const { wishlist } = await commerce.getCustomerWishlist({
|
||||||
variables: { customerId },
|
variables: { customerId },
|
||||||
config,
|
config,
|
||||||
})
|
})
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '../../../types/wishlist'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from './utils/get-customer-id'
|
||||||
import getCustomerWishlist from '../../../customer/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({
|
const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({
|
||||||
res,
|
res,
|
||||||
body: { customerToken, includeProducts },
|
body: { customerToken, includeProducts },
|
||||||
config,
|
config,
|
||||||
|
commerce,
|
||||||
}) => {
|
}) => {
|
||||||
let result: { data?: Wishlist } = {}
|
let result: { data?: Wishlist } = {}
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ const getWishlist: WishlistEndpoint['handlers']['getWishlist'] = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { wishlist } = await getCustomerWishlist({
|
const { wishlist } = await commerce.getCustomerWishlist({
|
||||||
variables: { customerId },
|
variables: { customerId },
|
||||||
includeProducts,
|
includeProducts,
|
||||||
config,
|
config,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { Wishlist } from '../../../types/wishlist'
|
import type { Wishlist } from '../../../types/wishlist'
|
||||||
import getCustomerWishlist from '../../../customer/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import getCustomerId from './utils/get-customer-id'
|
import getCustomerId from './utils/get-customer-id'
|
||||||
import type { WishlistEndpoint } from '.'
|
import type { WishlistEndpoint } from '.'
|
||||||
|
|
||||||
@ -8,12 +8,13 @@ const removeItem: WishlistEndpoint['handlers']['removeItem'] = async ({
|
|||||||
res,
|
res,
|
||||||
body: { customerToken, itemId },
|
body: { customerToken, itemId },
|
||||||
config,
|
config,
|
||||||
|
commerce,
|
||||||
}) => {
|
}) => {
|
||||||
const customerId =
|
const customerId =
|
||||||
customerToken && (await getCustomerId({ customerToken, config }))
|
customerToken && (await getCustomerId({ customerToken, config }))
|
||||||
const { wishlist } =
|
const { wishlist } =
|
||||||
(customerId &&
|
(customerId &&
|
||||||
(await getCustomerWishlist({
|
(await commerce.getCustomerWishlist({
|
||||||
variables: { customerId },
|
variables: { customerId },
|
||||||
config,
|
config,
|
||||||
}))) ||
|
}))) ||
|
||||||
|
@ -15,7 +15,7 @@ async function getCustomerId({
|
|||||||
}: {
|
}: {
|
||||||
customerToken: string
|
customerToken: string
|
||||||
config: BigcommerceConfig
|
config: BigcommerceConfig
|
||||||
}): Promise<number | undefined> {
|
}): Promise<string | undefined> {
|
||||||
const { data } = await config.fetch<GetCustomerIdQuery>(
|
const { data } = await config.fetch<GetCustomerIdQuery>(
|
||||||
getCustomerIdQuery,
|
getCustomerIdQuery,
|
||||||
undefined,
|
undefined,
|
||||||
@ -26,7 +26,7 @@ async function getCustomerId({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return data?.customer?.entityId
|
return String(data?.customer?.entityId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getCustomerId
|
export default getCustomerId
|
||||||
|
@ -20,6 +20,7 @@ import login from './operations/login'
|
|||||||
import getAllPages from './operations/get-all-pages'
|
import getAllPages from './operations/get-all-pages'
|
||||||
import getPage from './operations/get-page'
|
import getPage from './operations/get-page'
|
||||||
import getSiteInfo from './operations/get-site-info'
|
import getSiteInfo from './operations/get-site-info'
|
||||||
|
import getCustomerWishlist from './operations/get-customer-wishlist'
|
||||||
|
|
||||||
export interface BigcommerceConfig extends CommerceAPIConfig {
|
export interface BigcommerceConfig extends CommerceAPIConfig {
|
||||||
// Indicates if the returned metadata with translations should be applied to the
|
// Indicates if the returned metadata with translations should be applied to the
|
||||||
@ -115,7 +116,7 @@ const config2: BigcommerceConfig = {
|
|||||||
|
|
||||||
export const provider = {
|
export const provider = {
|
||||||
config: config2,
|
config: config2,
|
||||||
operations: { login, getAllPages, getPage, getSiteInfo },
|
operations: { login, getAllPages, getPage, getSiteInfo, getCustomerWishlist },
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Provider = typeof provider
|
export type Provider = typeof provider
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
import type {
|
||||||
|
OperationContext,
|
||||||
|
OperationOptions,
|
||||||
|
} from '@commerce/api/operations'
|
||||||
|
import type {
|
||||||
|
GetCustomerWishlistOperation,
|
||||||
|
Wishlist,
|
||||||
|
} from '../../types/wishlist'
|
||||||
|
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
|
||||||
|
import { BigcommerceConfig, Provider } from '..'
|
||||||
|
import getAllProducts, { ProductEdge } from '../../product/get-all-products'
|
||||||
|
|
||||||
|
export default function getCustomerWishlistOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getCustomerWishlist<
|
||||||
|
T extends GetCustomerWishlistOperation
|
||||||
|
>(opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
async function getCustomerWishlist<T extends GetCustomerWishlistOperation>(
|
||||||
|
opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
|
||||||
|
async function getCustomerWishlist<T extends GetCustomerWishlistOperation>({
|
||||||
|
config,
|
||||||
|
variables,
|
||||||
|
includeProducts,
|
||||||
|
}: {
|
||||||
|
url?: string
|
||||||
|
variables: T['variables']
|
||||||
|
config?: BigcommerceConfig
|
||||||
|
includeProducts?: boolean
|
||||||
|
}): Promise<T['data']> {
|
||||||
|
config = commerce.getConfig(config)
|
||||||
|
|
||||||
|
const { data = [] } = await config.storeApiFetch<
|
||||||
|
RecursivePartial<{ data: Wishlist[] }>
|
||||||
|
>(`/v3/wishlists?customer_id=${variables.customerId}`)
|
||||||
|
const wishlist = data[0]
|
||||||
|
|
||||||
|
if (includeProducts && wishlist?.items?.length) {
|
||||||
|
const entityIds = wishlist.items
|
||||||
|
?.map((item) => item?.product_id)
|
||||||
|
.filter((id): id is number => !!id)
|
||||||
|
|
||||||
|
if (entityIds?.length) {
|
||||||
|
const graphqlData = await getAllProducts({
|
||||||
|
variables: { first: 100, entityIds },
|
||||||
|
config,
|
||||||
|
})
|
||||||
|
// Put the products in an object that we can use to get them by id
|
||||||
|
const productsById = graphqlData.products.reduce<{
|
||||||
|
[k: number]: ProductEdge
|
||||||
|
}>((prods, p) => {
|
||||||
|
prods[Number(p.id)] = p as any
|
||||||
|
return prods
|
||||||
|
}, {})
|
||||||
|
// Populate the wishlist items with the graphql products
|
||||||
|
wishlist.items.forEach((item) => {
|
||||||
|
const product = item && productsById[item.product_id!]
|
||||||
|
if (item && product) {
|
||||||
|
// @ts-ignore Fix this type when the wishlist type is properly defined
|
||||||
|
item.product = product
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { wishlist: wishlist as RecursiveRequired<typeof wishlist> }
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCustomerWishlist
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import type { WishlistHandlers } from '..'
|
import type { WishlistHandlers } from '..'
|
||||||
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
||||||
import getCustomerWishlist from '../../../customer/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import { parseWishlistItem } from '../../utils/parse-item'
|
import { parseWishlistItem } from '../../utils/parse-item'
|
||||||
|
|
||||||
// Returns the wishlist of the signed customer
|
// Returns the wishlist of the signed customer
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
||||||
import getCustomerWishlist from '../../../customer/get-customer-wishlist'
|
import getCustomerWishlist from '../../operations/get-customer-wishlist'
|
||||||
import type { Wishlist, WishlistHandlers } from '..'
|
import type { Wishlist, WishlistHandlers } from '..'
|
||||||
|
|
||||||
// Return wishlist info
|
// Return wishlist info
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
import getCustomerId from '../../endpoints/wishlist/utils/get-customer-id'
|
||||||
import getCustomerWishlist, {
|
import getCustomerWishlist, {
|
||||||
Wishlist,
|
Wishlist,
|
||||||
} from '../../../customer/get-customer-wishlist'
|
} from '../../operations/get-customer-wishlist'
|
||||||
import type { WishlistHandlers } from '..'
|
import type { WishlistHandlers } from '..'
|
||||||
|
|
||||||
// Return current wishlist info
|
// Return current wishlist info
|
||||||
|
@ -7,7 +7,7 @@ import { BigcommerceApiError } from '../utils/errors'
|
|||||||
import type {
|
import type {
|
||||||
Wishlist,
|
Wishlist,
|
||||||
WishlistItem,
|
WishlistItem,
|
||||||
} from '../../customer/get-customer-wishlist'
|
} from '../operations/get-customer-wishlist'
|
||||||
import getWishlist from './handlers/get-wishlist'
|
import getWishlist from './handlers/get-wishlist'
|
||||||
import addItem from './handlers/add-item'
|
import addItem from './handlers/add-item'
|
||||||
import removeItem from './handlers/remove-item'
|
import removeItem from './handlers/remove-item'
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
import type { RecursivePartial, RecursiveRequired } from '../api/utils/types'
|
|
||||||
import { definitions } from '../api/definitions/wishlist'
|
|
||||||
import { BigcommerceConfig, getConfig } from '../api'
|
|
||||||
import getAllProducts, { ProductEdge } from '../product/get-all-products'
|
|
||||||
|
|
||||||
export type Wishlist = Omit<definitions['wishlist_Full'], 'items'> & {
|
|
||||||
items?: WishlistItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WishlistItem = NonNullable<
|
|
||||||
definitions['wishlist_Full']['items']
|
|
||||||
>[0] & {
|
|
||||||
product?: ProductEdge['node']
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetCustomerWishlistResult<
|
|
||||||
T extends { wishlist?: any } = { wishlist?: Wishlist }
|
|
||||||
> = T
|
|
||||||
|
|
||||||
export type GetCustomerWishlistVariables = {
|
|
||||||
customerId: number
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCustomerWishlist(opts: {
|
|
||||||
variables: GetCustomerWishlistVariables
|
|
||||||
config?: BigcommerceConfig
|
|
||||||
includeProducts?: boolean
|
|
||||||
}): Promise<GetCustomerWishlistResult>
|
|
||||||
|
|
||||||
async function getCustomerWishlist<
|
|
||||||
T extends { wishlist?: any },
|
|
||||||
V = any
|
|
||||||
>(opts: {
|
|
||||||
url: string
|
|
||||||
variables: V
|
|
||||||
config?: BigcommerceConfig
|
|
||||||
includeProducts?: boolean
|
|
||||||
}): Promise<GetCustomerWishlistResult<T>>
|
|
||||||
|
|
||||||
async function getCustomerWishlist({
|
|
||||||
config,
|
|
||||||
variables,
|
|
||||||
includeProducts,
|
|
||||||
}: {
|
|
||||||
url?: string
|
|
||||||
variables: GetCustomerWishlistVariables
|
|
||||||
config?: BigcommerceConfig
|
|
||||||
includeProducts?: boolean
|
|
||||||
}): Promise<GetCustomerWishlistResult> {
|
|
||||||
config = getConfig(config)
|
|
||||||
|
|
||||||
const { data = [] } = await config.storeApiFetch<
|
|
||||||
RecursivePartial<{ data: Wishlist[] }>
|
|
||||||
>(`/v3/wishlists?customer_id=${variables.customerId}`)
|
|
||||||
const wishlist = data[0]
|
|
||||||
|
|
||||||
if (includeProducts && wishlist?.items?.length) {
|
|
||||||
const entityIds = wishlist.items
|
|
||||||
?.map((item) => item?.product_id)
|
|
||||||
.filter((id): id is number => !!id)
|
|
||||||
|
|
||||||
if (entityIds?.length) {
|
|
||||||
const graphqlData = await getAllProducts({
|
|
||||||
variables: { first: 100, entityIds },
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
// Put the products in an object that we can use to get them by id
|
|
||||||
const productsById = graphqlData.products.reduce<{
|
|
||||||
[k: number]: ProductEdge
|
|
||||||
}>((prods, p) => {
|
|
||||||
prods[Number(p.id)] = p as any
|
|
||||||
return prods
|
|
||||||
}, {})
|
|
||||||
// Populate the wishlist items with the graphql products
|
|
||||||
wishlist.items.forEach((item) => {
|
|
||||||
const product = item && productsById[item.product_id!]
|
|
||||||
if (item && product) {
|
|
||||||
// @ts-ignore Fix this type when the wishlist type is properly defined
|
|
||||||
item.product = product
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { wishlist: wishlist as RecursiveRequired<typeof wishlist> }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getCustomerWishlist
|
|
@ -20,3 +20,4 @@ export type WishlistTypes = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type WishlistSchema = Core.WishlistSchema<WishlistTypes>
|
export type WishlistSchema = Core.WishlistSchema<WishlistTypes>
|
||||||
|
export type GetCustomerWishlistOperation = Core.GetCustomerWishlistOperation<WishlistTypes>
|
||||||
|
@ -2,6 +2,7 @@ import type { ServerResponse } from 'http'
|
|||||||
import type { LoginOperation } from '../types/login'
|
import type { LoginOperation } from '../types/login'
|
||||||
import type { GetAllPagesOperation, GetPageOperation } from '../types/page'
|
import type { GetAllPagesOperation, GetPageOperation } from '../types/page'
|
||||||
import type { GetSiteInfoOperation } from '../types/site'
|
import type { GetSiteInfoOperation } from '../types/site'
|
||||||
|
import type { GetCustomerWishlistOperation } from '../types/wishlist'
|
||||||
import type { APIProvider, CommerceAPI } from '.'
|
import type { APIProvider, CommerceAPI } from '.'
|
||||||
|
|
||||||
const noop = () => {
|
const noop = () => {
|
||||||
@ -77,6 +78,22 @@ export type Operations<P extends APIProvider> = {
|
|||||||
} & OperationOptions
|
} & OperationOptions
|
||||||
): Promise<T['data']>
|
): Promise<T['data']>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCustomerWishlist: {
|
||||||
|
<T extends GetCustomerWishlistOperation>(opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
includeProducts?: boolean
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
<T extends GetCustomerWishlistOperation>(
|
||||||
|
opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
includeProducts?: boolean
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type APIOperations<P extends APIProvider> = {
|
export type APIOperations<P extends APIProvider> = {
|
||||||
|
@ -30,3 +30,10 @@ export type WishlistSchema<T extends WishlistTypes = WishlistTypes> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GetCustomerWishlistOperation<
|
||||||
|
T extends WishlistTypes = WishlistTypes
|
||||||
|
> = {
|
||||||
|
data: { wishlist?: T['wishlist'] }
|
||||||
|
variables: { customerId: string }
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user