Finish get-all-products operators

Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
Chloe 2022-04-18 17:14:32 +07:00
parent 2701b30756
commit ce31d86352
46 changed files with 2437 additions and 1300 deletions

View File

@ -1,3 +1,4 @@
COMMERCE_PROVIDER=@vercel/commerce-opencommerce
OPENCOMMERCE_STOREFRONT_API_URL=
OPENCOMMERCE_PRIMARY_SHOP_ID=

View File

@ -10,7 +10,10 @@
],
"generates": {
"./schema.d.ts": {
"plugins": ["typescript", "typescript-operations"]
"plugins": ["typescript", "typescript-operations"],
"config": {
"avoidOptionals": true
}
},
"./schema.graphql": {
"plugins": ["schema-ast"]

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,10 @@ import {
} from '@vercel/commerce/api'
import createFetchGraphqlApi from './utils/fetch-grapql-api'
import * as operations from './operations'
const API_URL = process.env.OPENCOMMERCE_STOREFRONT_API_URL
const SHOP_ID = process.env.OPENCOMMERCE_PRIMARY_SHOP_ID
if (!API_URL) {
throw new Error(
@ -13,20 +16,22 @@ if (!API_URL) {
)
}
export interface OpenCommerceConfig extends CommerceAPIConfig {}
export interface OpenCommerceConfig extends CommerceAPIConfig {
shopId: string
}
const ONE_DAY = 60 * 60 * 24
const config: OpenCommerceConfig = {
commerceUrl: `${API_URL}/graphql`,
apiToken: '',
shopId: SHOP_ID ?? '',
customerCookie: 'opencommerce_customerToken',
cartCookie: 'opencommerce_cartId',
cartCookieMaxAge: ONE_DAY * 30,
fetch: createFetchGraphqlApi(() => getCommerceApi().getConfig()),
}
const operations = {}
export const provider = { config, operations }
export type Provider = typeof provider

View File

@ -0,0 +1,15 @@
const authenticateMutation = /* GraphQL */ `
mutation authenticate(
$serviceName: String!
$params: AuthenticateParamsInput!
) {
authenticate(serviceName: $serviceName, params: $params) {
sessionId
tokens {
refreshToken
accessToken
}
}
}
`
export default authenticateMutation

View File

@ -0,0 +1,19 @@
export type Page = { url: string }
export type GetAllPagesResult = { pages: Page[] }
import type { OpenCommerceConfig } from '../index'
export default function getAllPagesOperation() {
function getAllPages({
config,
preview,
}: {
url?: string
config?: Partial<OpenCommerceConfig>
preview?: boolean
}): Promise<GetAllPagesResult> {
return Promise.resolve({
pages: [],
})
}
return getAllPages
}

View File

@ -0,0 +1,63 @@
import type {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import type {
CatalogItemsQuery,
CatalogItemsQueryVariables,
CatalogItemProduct,
} from '../../../schema'
import type { GetAllProductPathsOperation } from '../../types/product'
import type { RecursivePartial, RecursiveRequired } from '../utils/types'
import filterEdges from '../utils/filter-edges'
import { OpenCommerceConfig, Provider } from '..'
import getAllProductPathsQuery from '../queries/get-all-product-paths-query'
export default function getAllProductPathsOperation({
commerce,
}: OperationContext<Provider>) {
async function getAllProductPaths<
T extends GetAllProductPathsOperation
>(opts?: {
variables?: CatalogItemsQueryVariables
config?: OpenCommerceConfig
}): Promise<T['data']>
async function getAllProductPaths<T extends GetAllProductPathsOperation>(
opts: {
variables?: CatalogItemsQueryVariables
config?: OpenCommerceConfig
} & OperationOptions
): Promise<T['data']>
async function getAllProductPaths<T extends GetAllProductPathsOperation>({
query = getAllProductPathsQuery,
variables,
config,
}: {
query?: string
variables?: CatalogItemsQueryVariables
config?: OpenCommerceConfig
} = {}): Promise<T['data']> {
const { fetch, shopId } = commerce.getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `query`
const { data } = await fetch<
RecursivePartial<CatalogItemsQuery>,
CatalogItemsQueryVariables
>(query, {
variables: { ...variables, shopIds: [shopId] },
})
const products = data.catalogItems?.edges
return {
products: filterEdges(products as RecursiveRequired<typeof products>).map(
({ node }) => ({
path: `/${(node as CatalogItemProduct).product!.slug}`,
})
),
}
}
return getAllProductPaths
}

View File

@ -1,23 +1,21 @@
import type {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import type { OperationContext } from '@vercel/commerce/api/operations'
import type { GetAllProductsOperation } from '../../types/product'
import {
CatalogItemProduct,
CatalogItemsQuery,
CatalogItemsQueryVariables,
Product as OpenCommerceProduct,
} from '../../../schema'
import catalogItemsQuery from '../queries/product'
import catalogItemsQuery from '../queries/get-all-products-query'
import type { OpenCommerceConfig, Provider } from '..'
import { normalizeProduct } from '../../utils/normalize'
import { RecursivePartial, RecursiveRequired } from '../utils/types'
import filterEdges from '../utils/filter-edges'
export default function getAllProductsOperation({
commerce,
}: OperationContext<Provider>) {
async function getAllProducts<T extends GetAllProductsOperation>(opts?: {
variables?: T['variables']
variables?: CatalogItemsQueryVariables
config?: Partial<OpenCommerceConfig>
preview?: boolean
}): Promise<T['data']>
@ -32,11 +30,14 @@ export default function getAllProductsOperation({
config?: Partial<OpenCommerceConfig>
preview?: boolean
} = {}): Promise<T['data']> {
const { fetch, locale } = commerce.getConfig(config)
const { fetch, locale, shopId } = commerce.getConfig(config)
const { data } = await fetch<CatalogItemsQuery, CatalogItemsQueryVariables>(
const { data } = await fetch<
RecursivePartial<CatalogItemsQuery>,
CatalogItemsQueryVariables
>(
query,
{ variables },
{ variables: { ...variables, shopIds: [shopId] } },
{
...(locale && {
headers: {
@ -46,13 +47,14 @@ export default function getAllProductsOperation({
}
)
const edges = data.catalogItems?.edges
return {
products:
data.catalogItems?.edges?.map((item) =>
products: filterEdges(edges as RecursiveRequired<typeof edges>).map(
(item) =>
normalizeProduct(
item?.node ? (item.node as CatalogItemProduct) : null
)
) ?? [],
),
}
}

View File

@ -0,0 +1,6 @@
export default function getCustomerWishlistOperation() {
function getCustomerWishlist(): any {
return { wishlist: {} }
}
return getCustomerWishlist
}

View File

@ -0,0 +1,13 @@
export type Page = any
export type GetPageResult = { page?: Page }
export type PageVariables = {
id: number
}
export default function getPageOperation() {
function getPage(): Promise<GetPageResult> {
return Promise.resolve({})
}
return getPage
}

View File

@ -0,0 +1,68 @@
import type {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import { GetProductOperation } from '../../types/product'
import { normalizeProduct } from '../../utils/normalize'
import type { OpenCommerceConfig, Provider } from '..'
import {
CatalogItemProduct,
GetProductBySlugQuery,
GetProductBySlugQueryVariables,
} from '../../../schema'
import getProductQuery from '../queries/get-product-query'
export default function getProductOperation({
commerce,
}: OperationContext<Provider>) {
async function getProduct<T extends GetProductOperation>(opts: {
variables: GetProductBySlugQueryVariables
config?: Partial<OpenCommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getProduct<T extends GetProductOperation>(
opts: {
variables: GetProductBySlugQueryVariables
config?: Partial<OpenCommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
async function getProduct<T extends GetProductOperation>({
query = getProductQuery,
variables,
config: cfg,
}: {
query?: string
variables: GetProductBySlugQueryVariables
config?: Partial<OpenCommerceConfig>
preview?: boolean
}): Promise<T['data']> {
const { fetch, locale } = commerce.getConfig(cfg)
const {
data: { catalogItemProduct },
} = await fetch<GetProductBySlugQuery, GetProductBySlugQueryVariables>(
query,
{
variables,
},
{
...(locale && {
headers: {
'Accept-Language': locale,
},
}),
}
)
return {
...(catalogItemProduct && {
product: normalizeProduct(catalogItemProduct as CatalogItemProduct),
}),
}
}
return getProduct
}

View File

@ -0,0 +1,43 @@
import { OperationContext } from '@vercel/commerce/api/operations'
import { Category } from '@vercel/commerce/types/site'
import type { OpenCommerceConfig } from '../index'
export type GetSiteInfoResult<
T extends { categories: any[]; brands: any[] } = {
categories: Category[]
brands: any[]
}
> = T
export default function getSiteInfoOperation({}: OperationContext<any>) {
function getSiteInfo({
query,
variables,
config: cfg,
}: {
query?: string
variables?: any
config?: Partial<OpenCommerceConfig>
preview?: boolean
} = {}): Promise<GetSiteInfoResult> {
return Promise.resolve({
categories: [
{
id: 'new-arrivals',
name: 'New Arrivals',
slug: 'new-arrivals',
path: '/new-arrivals',
},
{
id: 'featured',
name: 'Featured',
slug: 'featured',
path: '/featured',
},
],
brands: [],
})
}
return getSiteInfo
}

View File

@ -0,0 +1,7 @@
export { default as getAllPages } from './get-all-pages'
export { default as getPage } from './get-page'
export { default as getAllProducts } from './get-all-products'
export { default as getAllProductPaths } from './get-all-product-paths'
export { default as getProduct } from './get-product'
export { default as getSiteInfo } from './get-site-info'
export { default as login } from './login'

View File

@ -0,0 +1,53 @@
import type { ServerResponse } from 'http'
import type {
OperationContext,
OperationOptions,
} from '@vercel/commerce/api/operations'
import type { LoginOperation } from '../../types/login'
import type { AuthenticateMutation } from '../../../schema'
import type { RecursivePartial } from '../utils/types'
import loginMutation from '../mutations/authenticate'
import type { OpenCommerceConfig, Provider } from '..'
export default function loginOperation({
commerce,
}: OperationContext<Provider>) {
async function login<T extends LoginOperation>(opts: {
variables: T['variables']
config?: OpenCommerceConfig
res: ServerResponse
}): Promise<T['data']>
async function login<T extends LoginOperation>(
opts: {
variables: T['variables']
config?: OpenCommerceConfig
res: ServerResponse
} & OperationOptions
): Promise<T['data']>
async function login<T extends LoginOperation>({
query = loginMutation,
variables,
res: response,
config: cfg,
}: {
query?: string
variables: T['variables']
res: ServerResponse
config?: OpenCommerceConfig
}): Promise<T['data']> {
const { fetch } = commerce.getConfig(cfg)
const { data } = await fetch<RecursivePartial<AuthenticateMutation>>(
query,
{ variables }
)
return {
result: data.authenticate?.tokens?.accessToken ?? undefined,
}
}
return login
}

View File

@ -0,0 +1,25 @@
const getAllProductsPathsQuery = `
query catalogItems(
$first: ConnectionLimitInt = 250
$sortBy: CatalogItemSortByField = updatedAt
$shopIds: [ID]!
) {
catalogItems(first: $first, sortBy: $sortBy, shopIds: $shopIds) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
... on CatalogItemProduct {
product {
slug
}
}
}
cursor
}
}
}
`
export default getAllProductsPathsQuery

View File

@ -0,0 +1,181 @@
const getProductQuery = /* GraphQL */ `
query getProductBySlug($slug: String!) {
catalogItemProduct(slugOrId: $slug) {
product {
_id
productId
title
slug
description
vendor
isLowQuantity
isSoldOut
isBackorder
metafields {
description
key
namespace
scope
value
valueType
}
pricing {
currency {
code
}
displayPrice
minPrice
maxPrice
}
shop {
currency {
code
}
}
primaryImage {
URLs {
large
medium
original
small
thumbnail
}
priority
productId
variantId
}
media {
priority
productId
variantId
URLs {
thumbnail
small
medium
large
original
}
}
tags {
nodes {
name
slug
position
}
}
variants {
_id
variantId
attributeLabel
title
optionTitle
index
pricing {
compareAtPrice {
displayAmount
}
price
currency {
code
}
displayPrice
}
canBackorder
inventoryAvailableToSell
isBackorder
isSoldOut
isLowQuantity
options {
_id
variantId
attributeLabel
title
index
pricing {
compareAtPrice {
displayAmount
}
price
currency {
code
}
displayPrice
}
optionTitle
canBackorder
inventoryAvailableToSell
isBackorder
isSoldOut
isLowQuantity
media {
priority
productId
variantId
URLs {
thumbnail
small
medium
large
original
}
}
metafields {
description
key
namespace
scope
value
valueType
}
primaryImage {
URLs {
large
medium
original
small
thumbnail
}
priority
productId
variantId
}
}
media {
priority
productId
variantId
URLs {
thumbnail
small
medium
large
original
}
}
metafields {
description
key
namespace
scope
value
valueType
}
primaryImage {
URLs {
large
medium
original
small
thumbnail
}
priority
productId
variantId
}
}
}
}
}
`
export default getProductQuery

View File

@ -0,0 +1,5 @@
export default function filterEdges<T>(
edges: (T | null | undefined)[] | null | undefined
) {
return edges?.filter((edge): edge is T => !!edge) ?? []
}

View File

@ -0,0 +1,7 @@
export type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>
}
export type RecursiveRequired<T> = {
[P in keyof T]-?: RecursiveRequired<T[P]>
}

View File

@ -0,0 +1,3 @@
export { default as useLogin } from './use-login'
export { default as useLogout } from './use-logout'
export { default as useSignup } from './use-signup'

View File

@ -0,0 +1,16 @@
import { MutationHook } from '@vercel/commerce/utils/types'
import useLogin, { UseLogin } from '@vercel/commerce/auth/use-login'
export default useLogin as UseLogin<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher() {
return null
},
useHook: () => () => {
return async function () {}
},
}

View File

@ -0,0 +1,17 @@
import { MutationHook } from '@vercel/commerce/utils/types'
import useLogout, { UseLogout } from '@vercel/commerce/auth/use-logout'
export default useLogout as UseLogout<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher() {
return null
},
useHook:
({ fetch }) =>
() =>
async () => {},
}

View File

@ -0,0 +1,19 @@
import { useCallback } from 'react'
import useCustomer from '../customer/use-customer'
import { MutationHook } from '@vercel/commerce/utils/types'
import useSignup, { UseSignup } from '@vercel/commerce/auth/use-signup'
export default useSignup as UseSignup<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher() {
return null
},
useHook:
({ fetch }) =>
() =>
() => {},
}

View File

@ -0,0 +1,4 @@
export { default as useCart } from './use-cart'
export { default as useAddItem } from './use-add-item'
export { default as useRemoveItem } from './use-remove-item'
export { default as useUpdateItem } from './use-update-item'

View File

@ -0,0 +1,17 @@
import useAddItem, { UseAddItem } from '@vercel/commerce/cart/use-add-item'
import { MutationHook } from '@vercel/commerce/utils/types'
export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() => {
return async function addItem() {
return {}
}
},
}

View File

@ -0,0 +1,42 @@
import { useMemo } from 'react'
import { SWRHook } from '@vercel/commerce/utils/types'
import useCart, { UseCart } from '@vercel/commerce/cart/use-cart'
export default useCart as UseCart<typeof handler>
export const handler: SWRHook<any> = {
fetchOptions: {
query: '',
},
async fetcher() {
return {
id: '',
createdAt: '',
currency: { code: '' },
taxesIncluded: '',
lineItems: [],
lineItemsSubtotalPrice: '',
subtotalPrice: 0,
totalPrice: 0,
}
},
useHook:
({ useData }) =>
(input) => {
return useMemo(
() =>
Object.create(
{},
{
isEmpty: {
get() {
return true
},
enumerable: true,
},
}
),
[]
)
},
}

View File

@ -0,0 +1,20 @@
import { MutationHook } from '@vercel/commerce/utils/types'
import useRemoveItem, {
UseRemoveItem,
} from '@vercel/commerce/cart/use-remove-item'
export default useRemoveItem as UseRemoveItem<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() => {
return async function removeItem(input) {
return {}
}
},
}

View File

@ -0,0 +1,20 @@
import { MutationHook } from '@vercel/commerce/utils/types'
import useUpdateItem, {
UseUpdateItem,
} from '@vercel/commerce/cart/use-update-item'
export default useUpdateItem as UseUpdateItem<any>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() => {
return async function addItem() {
return {}
}
},
}

View File

@ -0,0 +1,16 @@
import { SWRHook } from '@vercel/commerce/utils/types'
import useCheckout, {
UseCheckout,
} from '@vercel/commerce/checkout/use-checkout'
export default useCheckout as UseCheckout<typeof handler>
export const handler: SWRHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ useData }) =>
async (input) => ({}),
}

View File

@ -0,0 +1,17 @@
import useAddItem, {
UseAddItem,
} from '@vercel/commerce/customer/address/use-add-item'
import { MutationHook } from '@vercel/commerce/utils/types'
export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() =>
async () => ({}),
}

View File

@ -0,0 +1,17 @@
import useAddItem, {
UseAddItem,
} from '@vercel/commerce/customer/card/use-add-item'
import { MutationHook } from '@vercel/commerce/utils/types'
export default useAddItem as UseAddItem<typeof handler>
export const handler: MutationHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook:
({ fetch }) =>
() =>
async () => ({}),
}

View File

@ -0,0 +1 @@
export { default as useCustomer } from './use-customer'

View File

@ -0,0 +1,17 @@
import { SWRHook } from '@vercel/commerce/utils/types'
import useCustomer, {
UseCustomer,
} from '@vercel/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 {}
}
},
}

View File

@ -0,0 +1,41 @@
import type { Fetcher } from '@vercel/commerce/utils/types'
import { FetcherError } from '@vercel/commerce/utils/errors'
async function getText(res: Response) {
try {
return (await res.text()) || res.statusText
} catch (error) {
return res.statusText
}
}
async function getError(res: Response) {
if (res.headers.get('Content-Type')?.includes('application/json')) {
const data = await res.json()
return new FetcherError({ errors: data.errors, status: res.status })
}
return new FetcherError({ message: await getText(res), status: res.status })
}
const fetcher: Fetcher = async ({
url,
method = 'GET',
variables,
body: bodyObj,
}) => {
const hasBody = Boolean(variables || bodyObj)
const body = hasBody
? JSON.stringify(variables ? { variables } : bodyObj)
: undefined
const headers = hasBody ? { 'Content-Type': 'application/json' } : undefined
const res = await fetch(url!, { method, body, headers })
if (res.ok) {
const { data } = await res.json()
return data
}
throw await getError(res)
}
export default fetcher

View File

@ -0,0 +1,12 @@
import {
getCommerceProvider,
useCommerce as useCoreCommerce,
} from '@vercel/commerce'
import { openCommerceProvider, OpenCommerceProvider } from './provider'
export { openCommerceProvider }
export type { OpenCommerceProvider }
export const CommerceProvider = getCommerceProvider(openCommerceProvider)
export const useCommerce = () => useCoreCommerce<OpenCommerceProvider>()

View File

@ -0,0 +1,2 @@
export { default as usePrice } from './use-price'
export { default as useSearch } from './use-search'

View File

@ -0,0 +1,2 @@
export * from '@vercel/commerce/product/use-price'
export { default } from '@vercel/commerce/product/use-price'

View File

@ -0,0 +1,17 @@
import { SWRHook } from '@vercel/commerce/utils/types'
import useSearch, { UseSearch } from '@vercel/commerce/product/use-search'
export default useSearch as UseSearch<typeof handler>
export const handler: SWRHook<any> = {
fetchOptions: {
query: '',
},
async fetcher({ input, options, fetch }) {},
useHook: () => () => {
return {
data: {
products: [],
},
}
},
}

View File

@ -0,0 +1,22 @@
import fetcher from './fetcher'
import { handler as useCart } from './cart/use-cart'
import { handler as useAddItem } from './cart/use-add-item'
import { handler as useUpdateItem } from './cart/use-update-item'
import { handler as useRemoveItem } from './cart/use-remove-item'
import { handler as useCustomer } from './customer/use-customer'
import { handler as useSearch } from './product/use-search'
import { handler as useLogin } from './auth/use-login'
import { handler as useLogout } from './auth/use-logout'
import { handler as useSignup } from './auth/use-signup'
export const openCommerceProvider = {
locale: 'en-us',
cartCookie: 'opencommerce_cartId',
fetcher,
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
customer: { useCustomer },
products: { useSearch },
auth: { useLogin, useLogout, useSignup },
}
export type OpenCommerceProvider = typeof openCommerceProvider

View File

@ -0,0 +1,8 @@
import * as Core from '@vercel/commerce/types/login'
import type { AuthenticateMutationVariables } from '../../schema'
export * from '@vercel/commerce/types/login'
export type LoginOperation = Core.LoginOperation & {
variables: AuthenticateMutationVariables
}

View File

@ -18,7 +18,7 @@ const normalizeProductImages = (images: ImageInfo[], name: string) =>
}))
export function normalizeProduct(
productNode: CatalogItemProduct | null | undefined
productNode: CatalogItemProduct | null
): Product {
const product = productNode?.product
if (!product) {

View File

@ -0,0 +1,13 @@
import { useCallback } from 'react'
export function emptyHook() {
const useEmptyHook = async (options = {}) => {
return useCallback(async function () {
return Promise.resolve()
}, [])
}
return useEmptyHook
}
export default emptyHook

View File

@ -0,0 +1,17 @@
import { useCallback } from 'react'
type Options = {
includeProducts?: boolean
}
export function emptyHook(options?: Options) {
const useEmptyHook = async ({ id }: { id: string | number }) => {
return useCallback(async function () {
return Promise.resolve()
}, [])
}
return useEmptyHook
}
export default emptyHook

View File

@ -0,0 +1,43 @@
import { HookFetcher } from '@vercel/commerce/utils/types'
import type { Product } from '@vercel/commerce/types/product'
const defaultOpts = {}
export type Wishlist = {
items: [
{
product_id: number
variant_id: number
id: number
product: Product
}
]
}
export interface UseWishlistOptions {
includeProducts?: boolean
}
export interface UseWishlistInput extends UseWishlistOptions {
customerId?: number
}
export const fetcher: HookFetcher<Wishlist | null, UseWishlistInput> = () => {
return null
}
export function extendHook(
customFetcher: typeof fetcher,
// swrOptions?: SwrOptions<Wishlist | null, UseWishlistInput>
swrOptions?: any
) {
const useWishlist = ({ includeProducts }: UseWishlistOptions = {}) => {
return { data: null }
}
useWishlist.extend = extendHook
return useWishlist
}
export default extendHook(fetcher)

View File

@ -48,3 +48,6 @@ KIBO_API_HOST=
NEXT_PUBLIC_COMMERCEJS_PUBLIC_KEY=
NEXT_PUBLIC_COMMERCEJS_DEPLOYMENT_URL=
OPENCOMMERCE_STOREFRONT_API_URL=
OPENCOMMERCE_PRIMARY_SHOP_ID=

View File

@ -23,8 +23,8 @@
"@components/*": ["components/*"],
"@commerce": ["../packages/commerce/src"],
"@commerce/*": ["../packages/commerce/src/*"],
"@framework": ["../packages/local/src"],
"@framework/*": ["../packages/local/src/*"]
"@framework": ["../packages/opencommerce/src"],
"@framework/*": ["../packages/opencommerce/src/*"]
}
},
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],