forked from crowetic/commerce
Update Swell Provider (#359)
* fix update cart item * update types * update checkout * update get-page, cleanup types * revert change to incorrect file * cleanup Co-authored-by: Greg Hoskin <greghoskin@Gregs-MacBook-Pro.local>
This commit is contained in:
parent
ddd4631ade
commit
4d85b43a30
@ -1,20 +0,0 @@
|
|||||||
import createApiHandler, { SwellApiHandler } from '../utils/create-api-handler'
|
|
||||||
|
|
||||||
import { SWELL_CHECKOUT_URL_COOKIE } from '../../const'
|
|
||||||
|
|
||||||
import { getConfig } from '..'
|
|
||||||
|
|
||||||
const checkoutApi: SwellApiHandler<any> = async (req, res, config) => {
|
|
||||||
config = getConfig()
|
|
||||||
|
|
||||||
const { cookies } = req
|
|
||||||
const checkoutUrl = cookies[SWELL_CHECKOUT_URL_COOKIE]
|
|
||||||
|
|
||||||
if (checkoutUrl) {
|
|
||||||
res.redirect(checkoutUrl)
|
|
||||||
} else {
|
|
||||||
res.redirect('/cart')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default createApiHandler(checkoutApi, {}, {})
|
|
@ -1 +0,0 @@
|
|||||||
export default function () {}
|
|
1
framework/swell/api/endpoints/cart.ts
Normal file
1
framework/swell/api/endpoints/cart.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
1
framework/swell/api/endpoints/catalog/products.ts
Normal file
1
framework/swell/api/endpoints/catalog/products.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
30
framework/swell/api/endpoints/checkout/index.ts
Normal file
30
framework/swell/api/endpoints/checkout/index.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { CommerceAPI, createEndpoint, GetAPISchema } from '@commerce/api'
|
||||||
|
import { CheckoutSchema } from '@commerce/types/checkout'
|
||||||
|
import { SWELL_CHECKOUT_URL_COOKIE } from '../../../const'
|
||||||
|
import checkoutEndpoint from '@commerce/api/endpoints/checkout'
|
||||||
|
|
||||||
|
const checkout: CheckoutEndpoint['handlers']['checkout'] = async ({
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
config,
|
||||||
|
}) => {
|
||||||
|
const { cookies } = req
|
||||||
|
const checkoutUrl = cookies[SWELL_CHECKOUT_URL_COOKIE]
|
||||||
|
|
||||||
|
if (checkoutUrl) {
|
||||||
|
res.redirect(checkoutUrl)
|
||||||
|
} else {
|
||||||
|
res.redirect('/cart')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const handlers: CheckoutEndpoint['handlers'] = { checkout }
|
||||||
|
|
||||||
|
export type CheckoutAPI = GetAPISchema<CommerceAPI, CheckoutSchema>
|
||||||
|
export type CheckoutEndpoint = CheckoutAPI['endpoint']
|
||||||
|
|
||||||
|
const checkoutApi = createEndpoint<CheckoutAPI>({
|
||||||
|
handler: checkoutEndpoint,
|
||||||
|
handlers,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default checkoutApi
|
1
framework/swell/api/endpoints/customer.ts
Normal file
1
framework/swell/api/endpoints/customer.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
1
framework/swell/api/endpoints/login.ts
Normal file
1
framework/swell/api/endpoints/login.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
1
framework/swell/api/endpoints/logout.ts
Normal file
1
framework/swell/api/endpoints/logout.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
1
framework/swell/api/endpoints/signup.ts
Normal file
1
framework/swell/api/endpoints/signup.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
1
framework/swell/api/endpoints/wishlist.ts
Normal file
1
framework/swell/api/endpoints/wishlist.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default function (_commerce: any) {}
|
@ -1,5 +1,8 @@
|
|||||||
import type { CommerceAPIConfig } from '@commerce/api'
|
import {
|
||||||
|
CommerceAPI,
|
||||||
|
CommerceAPIConfig,
|
||||||
|
getCommerceApi as commerceApi,
|
||||||
|
} from '@commerce/api'
|
||||||
import {
|
import {
|
||||||
SWELL_CHECKOUT_ID_COOKIE,
|
SWELL_CHECKOUT_ID_COOKIE,
|
||||||
SWELL_CUSTOMER_TOKEN_COOKIE,
|
SWELL_CUSTOMER_TOKEN_COOKIE,
|
||||||
@ -7,31 +10,19 @@ import {
|
|||||||
} from '../const'
|
} from '../const'
|
||||||
|
|
||||||
import fetchApi from './utils/fetch-swell-api'
|
import fetchApi from './utils/fetch-swell-api'
|
||||||
|
import login from './operations/login'
|
||||||
|
import getAllPages from './operations/get-all-pages'
|
||||||
|
import getPage from './operations/get-page'
|
||||||
|
import getSiteInfo from './operations/get-site-info'
|
||||||
|
import getAllProductPaths from './operations/get-all-product-paths'
|
||||||
|
import getAllProducts from './operations/get-all-products'
|
||||||
|
import getProduct from './operations/get-product'
|
||||||
|
|
||||||
export interface SwellConfig extends CommerceAPIConfig {
|
export interface SwellConfig extends CommerceAPIConfig {
|
||||||
fetch: any
|
fetch: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Config {
|
const config: SwellConfig = {
|
||||||
private config: SwellConfig
|
|
||||||
|
|
||||||
constructor(config: SwellConfig) {
|
|
||||||
this.config = config
|
|
||||||
}
|
|
||||||
|
|
||||||
getConfig(userConfig: Partial<SwellConfig> = {}) {
|
|
||||||
return Object.entries(userConfig).reduce<SwellConfig>(
|
|
||||||
(cfg, [key, value]) => Object.assign(cfg, { [key]: value }),
|
|
||||||
{ ...this.config }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
setConfig(newConfig: Partial<SwellConfig>) {
|
|
||||||
Object.assign(this.config, newConfig)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = new Config({
|
|
||||||
locale: 'en-US',
|
locale: 'en-US',
|
||||||
commerceUrl: '',
|
commerceUrl: '',
|
||||||
apiToken: ''!,
|
apiToken: ''!,
|
||||||
@ -39,12 +30,24 @@ const config = new Config({
|
|||||||
cartCookieMaxAge: SWELL_COOKIE_EXPIRE,
|
cartCookieMaxAge: SWELL_COOKIE_EXPIRE,
|
||||||
fetch: fetchApi,
|
fetch: fetchApi,
|
||||||
customerCookie: SWELL_CUSTOMER_TOKEN_COOKIE,
|
customerCookie: SWELL_CUSTOMER_TOKEN_COOKIE,
|
||||||
})
|
|
||||||
|
|
||||||
export function getConfig(userConfig?: Partial<SwellConfig>) {
|
|
||||||
return config.getConfig(userConfig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setConfig(newConfig: Partial<SwellConfig>) {
|
const operations = {
|
||||||
return config.setConfig(newConfig)
|
login,
|
||||||
|
getAllPages,
|
||||||
|
getPage,
|
||||||
|
getSiteInfo,
|
||||||
|
getAllProductPaths,
|
||||||
|
getAllProducts,
|
||||||
|
getProduct,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const provider = { config, operations }
|
||||||
|
|
||||||
|
export type Provider = typeof provider
|
||||||
|
|
||||||
|
export function getCommerceApi<P extends Provider>(
|
||||||
|
customProvider: P = provider as any
|
||||||
|
): CommerceAPI<P> {
|
||||||
|
return commerceApi(customProvider)
|
||||||
}
|
}
|
||||||
|
45
framework/swell/api/operations/get-all-pages.ts
Normal file
45
framework/swell/api/operations/get-all-pages.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { Provider, SwellConfig } from '..'
|
||||||
|
import type { OperationContext } from '@commerce/api/operations'
|
||||||
|
import type { Page } from '../../types/page'
|
||||||
|
|
||||||
|
export type GetAllPagesResult<
|
||||||
|
T extends { pages: any[] } = { pages: Page[] }
|
||||||
|
> = T
|
||||||
|
|
||||||
|
export default function getAllPagesOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getAllPages(opts?: {
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<GetAllPagesResult>
|
||||||
|
|
||||||
|
async function getAllPages<T extends { pages: any[] }>(opts: {
|
||||||
|
url: string
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<GetAllPagesResult<T>>
|
||||||
|
|
||||||
|
async function getAllPages({
|
||||||
|
config: cfg,
|
||||||
|
preview,
|
||||||
|
}: {
|
||||||
|
url?: string
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
} = {}): Promise<GetAllPagesResult> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
const { locale, fetch } = config
|
||||||
|
const data = await fetch('content', 'list', ['pages'])
|
||||||
|
const pages =
|
||||||
|
data?.results?.map(({ slug, ...rest }: { slug: string }) => ({
|
||||||
|
url: `/${locale}/${slug}`,
|
||||||
|
...rest,
|
||||||
|
})) ?? []
|
||||||
|
return {
|
||||||
|
pages,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllPages
|
||||||
|
}
|
48
framework/swell/api/operations/get-all-product-paths.ts
Normal file
48
framework/swell/api/operations/get-all-product-paths.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { SwellProduct } from '../../types'
|
||||||
|
import { SwellConfig, Provider } from '..'
|
||||||
|
import { OperationContext, OperationOptions } from '@commerce/api/operations'
|
||||||
|
import { GetAllProductPathsOperation } from '@commerce/types/product'
|
||||||
|
|
||||||
|
export default function getAllProductPathsOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getAllProductPaths<
|
||||||
|
T extends GetAllProductPathsOperation
|
||||||
|
>(opts?: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: SwellConfig
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
async function getAllProductPaths<T extends GetAllProductPathsOperation>(
|
||||||
|
opts: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: SwellConfig
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
|
||||||
|
async function getAllProductPaths<T extends GetAllProductPathsOperation>({
|
||||||
|
variables,
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: SwellConfig
|
||||||
|
} = {}): Promise<T['data']> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
// RecursivePartial forces the method to check for every prop in the data, which is
|
||||||
|
// required in case there's a custom `query`
|
||||||
|
const { results } = await config.fetch('products', 'list', [
|
||||||
|
{
|
||||||
|
limit: variables?.first,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
return {
|
||||||
|
products: results?.map(({ slug: handle }: SwellProduct) => ({
|
||||||
|
path: `/${handle}`,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllProductPaths
|
||||||
|
}
|
43
framework/swell/api/operations/get-all-products.ts
Normal file
43
framework/swell/api/operations/get-all-products.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { normalizeProduct } from '../../utils/normalize'
|
||||||
|
import { SwellProduct } from '../../types'
|
||||||
|
import { Product } from '@commerce/types/product'
|
||||||
|
import { Provider, SwellConfig } from '../'
|
||||||
|
import { OperationContext } from '@commerce/api/operations'
|
||||||
|
|
||||||
|
export type ProductVariables = { first?: number }
|
||||||
|
|
||||||
|
export default function getAllProductsOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getAllProducts(opts?: {
|
||||||
|
variables?: ProductVariables
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<{ products: Product[] }>
|
||||||
|
|
||||||
|
async function getAllProducts({
|
||||||
|
config: cfg,
|
||||||
|
variables = { first: 250 },
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables?: ProductVariables
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
} = {}): Promise<{ products: Product[] | any[] }> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
const { results } = await config.fetch('products', 'list', [
|
||||||
|
{
|
||||||
|
limit: variables.first,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
const products = results.map((product: SwellProduct) =>
|
||||||
|
normalizeProduct(product)
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
products,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllProducts
|
||||||
|
}
|
@ -1,25 +1,54 @@
|
|||||||
import { Page } from '../../schema'
|
import { Page } from '../../schema'
|
||||||
import { SwellConfig, getConfig } from '..'
|
import { SwellConfig, Provider } from '..'
|
||||||
|
import { OperationContext, OperationOptions } from '@commerce/api/operations'
|
||||||
|
import { GetPageOperation } from '../../types/page'
|
||||||
|
|
||||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
||||||
|
|
||||||
export type PageVariables = {
|
export type PageVariables = {
|
||||||
id: string
|
id: number
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPage({
|
export default function getPageOperation({
|
||||||
url,
|
commerce,
|
||||||
variables,
|
}: OperationContext<Provider>) {
|
||||||
config,
|
async function getPage<T extends GetPageOperation>(opts: {
|
||||||
preview,
|
variables: T['variables']
|
||||||
}: {
|
config?: Partial<SwellConfig>
|
||||||
url?: string
|
preview?: boolean
|
||||||
variables: PageVariables
|
}): Promise<T['data']>
|
||||||
config?: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<GetPageResult> {
|
|
||||||
config = getConfig(config)
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getPage
|
async function getPage<T extends GetPageOperation>(
|
||||||
|
opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
|
||||||
|
async function getPage<T extends GetPageOperation>({
|
||||||
|
variables,
|
||||||
|
config,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<T['data']> {
|
||||||
|
const { fetch, locale = 'en-US' } = commerce.getConfig(config)
|
||||||
|
const id = variables.id
|
||||||
|
const result = await fetch('content', 'get', ['pages', id])
|
||||||
|
const page = result
|
||||||
|
|
||||||
|
return {
|
||||||
|
page: page
|
||||||
|
? {
|
||||||
|
...page,
|
||||||
|
url: `/${locale}/${page.slug}`,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getPage
|
||||||
|
}
|
||||||
|
33
framework/swell/api/operations/get-product.ts
Normal file
33
framework/swell/api/operations/get-product.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { normalizeProduct } from '../../utils'
|
||||||
|
|
||||||
|
import { Product } from '@commerce/types/product'
|
||||||
|
import { OperationContext } from '@commerce/api/operations'
|
||||||
|
import { Provider, SwellConfig } from '../'
|
||||||
|
|
||||||
|
export default function getProductOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getProduct({
|
||||||
|
variables,
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables: { slug: string }
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<Product | {} | any> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
|
||||||
|
const product = await config.fetch('products', 'get', [variables.slug])
|
||||||
|
|
||||||
|
if (product && product.variants) {
|
||||||
|
product.variants = product.variants?.results
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
product: product ? normalizeProduct(product) : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getProduct
|
||||||
|
}
|
37
framework/swell/api/operations/get-site-info.ts
Normal file
37
framework/swell/api/operations/get-site-info.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import getCategories from '../../utils/get-categories'
|
||||||
|
import getVendors, { Brands } from '../../utils/get-vendors'
|
||||||
|
import { Provider, SwellConfig } from '../'
|
||||||
|
import { OperationContext } from '@commerce/api/operations'
|
||||||
|
import { Category } from '@commerce/types/site'
|
||||||
|
|
||||||
|
export type GetSiteInfoResult<
|
||||||
|
T extends { categories: any[]; brands: any[] } = {
|
||||||
|
categories: Category[]
|
||||||
|
brands: Brands
|
||||||
|
}
|
||||||
|
> = T
|
||||||
|
|
||||||
|
export default function getSiteInfoOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function getSiteInfo({
|
||||||
|
variables,
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables?: any
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
preview?: boolean
|
||||||
|
} = {}): Promise<GetSiteInfoResult> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
const categories = await getCategories(config)
|
||||||
|
const brands = await getVendors(config)
|
||||||
|
|
||||||
|
return {
|
||||||
|
categories,
|
||||||
|
brands,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSiteInfo
|
||||||
|
}
|
46
framework/swell/api/operations/login.ts
Normal file
46
framework/swell/api/operations/login.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import type { ServerResponse } from 'http'
|
||||||
|
import type {
|
||||||
|
OperationContext,
|
||||||
|
OperationOptions,
|
||||||
|
} from '@commerce/api/operations'
|
||||||
|
import type { LoginOperation } from '../../types/login'
|
||||||
|
import { Provider, SwellConfig } from '..'
|
||||||
|
|
||||||
|
export default function loginOperation({
|
||||||
|
commerce,
|
||||||
|
}: OperationContext<Provider>) {
|
||||||
|
async function login<T extends LoginOperation>(opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
res: ServerResponse
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
async function login<T extends LoginOperation>(
|
||||||
|
opts: {
|
||||||
|
variables: T['variables']
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
res: ServerResponse
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
|
||||||
|
async function login<T extends LoginOperation>({
|
||||||
|
variables,
|
||||||
|
res: response,
|
||||||
|
config: cfg,
|
||||||
|
}: {
|
||||||
|
query?: string
|
||||||
|
variables: T['variables']
|
||||||
|
res: ServerResponse
|
||||||
|
config?: Partial<SwellConfig>
|
||||||
|
}): Promise<T['data']> {
|
||||||
|
const config = commerce.getConfig(cfg)
|
||||||
|
|
||||||
|
const { data } = await config.fetch('account', 'login', [variables])
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return login
|
||||||
|
}
|
@ -1,58 +0,0 @@
|
|||||||
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
|
||||||
import { SwellConfig, getConfig } from '..'
|
|
||||||
|
|
||||||
export type SwellApiHandler<
|
|
||||||
T = any,
|
|
||||||
H extends SwellHandlers = {},
|
|
||||||
Options extends {} = {}
|
|
||||||
> = (
|
|
||||||
req: NextApiRequest,
|
|
||||||
res: NextApiResponse<SwellApiResponse<T>>,
|
|
||||||
config: SwellConfig,
|
|
||||||
handlers: H,
|
|
||||||
// Custom configs that may be used by a particular handler
|
|
||||||
options: Options
|
|
||||||
) => void | Promise<void>
|
|
||||||
|
|
||||||
export type SwellHandler<T = any, Body = null> = (options: {
|
|
||||||
req: NextApiRequest
|
|
||||||
res: NextApiResponse<SwellApiResponse<T>>
|
|
||||||
config: SwellConfig
|
|
||||||
body: Body
|
|
||||||
}) => void | Promise<void>
|
|
||||||
|
|
||||||
export type SwellHandlers<T = any> = {
|
|
||||||
[k: string]: SwellHandler<T, any>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SwellApiResponse<T> = {
|
|
||||||
data: T | null
|
|
||||||
errors?: { message: string; code?: string }[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function createApiHandler<
|
|
||||||
T = any,
|
|
||||||
H extends SwellHandlers = {},
|
|
||||||
Options extends {} = {}
|
|
||||||
>(
|
|
||||||
handler: SwellApiHandler<T, H, Options>,
|
|
||||||
handlers: H,
|
|
||||||
defaultOptions: Options
|
|
||||||
) {
|
|
||||||
return function getApiHandler({
|
|
||||||
config,
|
|
||||||
operations,
|
|
||||||
options,
|
|
||||||
}: {
|
|
||||||
config?: SwellConfig
|
|
||||||
operations?: Partial<H>
|
|
||||||
options?: Options extends {} ? Partial<Options> : never
|
|
||||||
} = {}): NextApiHandler {
|
|
||||||
const ops = { ...operations, ...handlers }
|
|
||||||
const opts = { ...defaultOptions, ...options }
|
|
||||||
|
|
||||||
return function apiHandler(req, res) {
|
|
||||||
return handler(req, res, getConfig(config), ops, opts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,12 +3,12 @@ import type { MutationHook } from '@commerce/utils/types'
|
|||||||
import { CommerceError, ValidationError } from '@commerce/utils/errors'
|
import { CommerceError, ValidationError } from '@commerce/utils/errors'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
import {
|
import {
|
||||||
CustomerAccessTokenCreateInput,
|
|
||||||
CustomerUserError,
|
CustomerUserError,
|
||||||
Mutation,
|
Mutation,
|
||||||
MutationCheckoutCreateArgs,
|
MutationCheckoutCreateArgs,
|
||||||
} from '../schema'
|
} from '../schema'
|
||||||
import useLogin, { UseLogin } from '@commerce/auth/use-login'
|
import useLogin, { UseLogin } from '@commerce/auth/use-login'
|
||||||
|
import { LoginHook } from '../types/login'
|
||||||
import { setCustomerToken } from '../utils'
|
import { setCustomerToken } from '../utils'
|
||||||
|
|
||||||
export default useLogin as UseLogin<typeof handler>
|
export default useLogin as UseLogin<typeof handler>
|
||||||
@ -22,7 +22,7 @@ const getErrorMessage = ({ code, message }: CustomerUserError) => {
|
|||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handler: MutationHook<null, {}, CustomerAccessTokenCreateInput> = {
|
export const handler: MutationHook<LoginHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'account',
|
query: 'account',
|
||||||
method: 'login',
|
method: 'login',
|
||||||
|
@ -3,10 +3,11 @@ import type { MutationHook } from '@commerce/utils/types'
|
|||||||
import useLogout, { UseLogout } from '@commerce/auth/use-logout'
|
import useLogout, { UseLogout } from '@commerce/auth/use-logout'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
import { getCustomerToken, setCustomerToken } from '../utils/customer-token'
|
import { getCustomerToken, setCustomerToken } from '../utils/customer-token'
|
||||||
|
import { LogoutHook } from '../types/logout'
|
||||||
|
|
||||||
export default useLogout as UseLogout<typeof handler>
|
export default useLogout as UseLogout<typeof handler>
|
||||||
|
|
||||||
export const handler: MutationHook<null> = {
|
export const handler: MutationHook<LogoutHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'account',
|
query: 'account',
|
||||||
method: 'logout',
|
method: 'logout',
|
||||||
|
@ -3,18 +3,12 @@ import type { MutationHook } from '@commerce/utils/types'
|
|||||||
import { CommerceError } from '@commerce/utils/errors'
|
import { CommerceError } from '@commerce/utils/errors'
|
||||||
import useSignup, { UseSignup } from '@commerce/auth/use-signup'
|
import useSignup, { UseSignup } from '@commerce/auth/use-signup'
|
||||||
import useCustomer from '../customer/use-customer'
|
import useCustomer from '../customer/use-customer'
|
||||||
import { CustomerCreateInput } from '../schema'
|
import { SignupHook } from '../types/signup'
|
||||||
|
|
||||||
import handleLogin from '../utils/handle-login'
|
import handleLogin from '../utils/handle-login'
|
||||||
|
|
||||||
export default useSignup as UseSignup<typeof handler>
|
export default useSignup as UseSignup<typeof handler>
|
||||||
|
|
||||||
export const handler: MutationHook<
|
export const handler: MutationHook<SignupHook> = {
|
||||||
null,
|
|
||||||
{},
|
|
||||||
CustomerCreateInput,
|
|
||||||
CustomerCreateInput
|
|
||||||
> = {
|
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'account',
|
query: 'account',
|
||||||
method: 'create',
|
method: 'create',
|
||||||
|
@ -2,14 +2,14 @@ import type { MutationHook } from '@commerce/utils/types'
|
|||||||
import { CommerceError } from '@commerce/utils/errors'
|
import { CommerceError } from '@commerce/utils/errors'
|
||||||
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
import { Cart, CartItemBody } from '../types'
|
|
||||||
import { checkoutToCart } from './utils'
|
import { checkoutToCart } from './utils'
|
||||||
import { getCheckoutId } from '../utils'
|
import { getCheckoutId } from '../utils'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
import { AddItemHook } from '../types/cart'
|
||||||
|
|
||||||
export default useAddItem as UseAddItem<typeof handler>
|
export default useAddItem as UseAddItem<typeof handler>
|
||||||
|
|
||||||
export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
export const handler: MutationHook<AddItemHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'cart',
|
query: 'cart',
|
||||||
method: 'addItem',
|
method: 'addItem',
|
||||||
@ -24,7 +24,7 @@ export const handler: MutationHook<Cart, {}, CartItemBody> = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
const variables: {
|
const variables: {
|
||||||
product_id: string
|
product_id: string | undefined
|
||||||
variant_id?: string
|
variant_id?: string
|
||||||
checkoutId?: string
|
checkoutId?: string
|
||||||
quantity?: number
|
quantity?: number
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import useCart, { UseCart } from '@commerce/cart/use-cart'
|
import useCart, { UseCart } from '@commerce/cart/use-cart'
|
||||||
import { Cart } from '@commerce/types'
|
|
||||||
import { SWRHook } from '@commerce/utils/types'
|
import { SWRHook } from '@commerce/utils/types'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { normalizeCart } from '../utils/normalize'
|
import { normalizeCart } from '../utils/normalize'
|
||||||
import { checkoutCreate, checkoutToCart } from './utils'
|
import { checkoutCreate, checkoutToCart } from './utils'
|
||||||
|
import type { GetCartHook } from '@commerce/types/cart'
|
||||||
|
|
||||||
export default useCart as UseCart<typeof handler>
|
export default useCart as UseCart<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<Cart | null, {}, any, { isEmpty?: boolean }> = {
|
export const handler: SWRHook<GetCartHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'cart',
|
query: 'cart',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
@ -1,29 +1,21 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
MutationHookContext,
|
MutationHookContext,
|
||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
} from '@commerce/utils/types'
|
} from '@commerce/utils/types'
|
||||||
|
|
||||||
import { ValidationError } from '@commerce/utils/errors'
|
import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item'
|
||||||
|
import type { Cart, LineItem, RemoveItemHook } from '@commerce/types/cart'
|
||||||
import useRemoveItem, {
|
|
||||||
RemoveItemInput as RemoveItemInputBase,
|
|
||||||
UseRemoveItem,
|
|
||||||
} from '@commerce/cart/use-remove-item'
|
|
||||||
|
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
import { checkoutToCart } from './utils'
|
import { checkoutToCart } from './utils'
|
||||||
import { Cart, LineItem } from '../types'
|
|
||||||
import { RemoveCartItemBody } from '@commerce/types'
|
|
||||||
|
|
||||||
export type RemoveItemFn<T = any> = T extends LineItem
|
export type RemoveItemFn<T = any> = T extends LineItem
|
||||||
? (input?: RemoveItemInput<T>) => Promise<Cart | null>
|
? (input?: RemoveItemActionInput<T>) => Promise<Cart | null | undefined>
|
||||||
: (input: RemoveItemInput<T>) => Promise<Cart | null>
|
: (input: RemoveItemActionInput<T>) => Promise<Cart | null>
|
||||||
|
|
||||||
export type RemoveItemInput<T = any> = T extends LineItem
|
export type RemoveItemActionInput<T = any> = T extends LineItem
|
||||||
? Partial<RemoveItemInputBase>
|
? Partial<RemoveItemHook['actionInput']>
|
||||||
: RemoveItemInputBase
|
: RemoveItemHook['actionInput']
|
||||||
|
|
||||||
export default useRemoveItem as UseRemoveItem<typeof handler>
|
export default useRemoveItem as UseRemoveItem<typeof handler>
|
||||||
|
|
||||||
@ -36,36 +28,22 @@ export const handler = {
|
|||||||
input: { itemId },
|
input: { itemId },
|
||||||
options,
|
options,
|
||||||
fetch,
|
fetch,
|
||||||
}: HookFetcherContext<RemoveCartItemBody>) {
|
}: HookFetcherContext<RemoveItemHook>) {
|
||||||
const response = await fetch({
|
const response = await fetch({ ...options, variables: [itemId] })
|
||||||
...options,
|
|
||||||
variables: [itemId],
|
|
||||||
})
|
|
||||||
return checkoutToCart(response)
|
return checkoutToCart(response)
|
||||||
},
|
},
|
||||||
useHook: ({
|
useHook: ({ fetch }: MutationHookContext<RemoveItemHook>) => () => {
|
||||||
fetch,
|
|
||||||
}: MutationHookContext<Cart | null, RemoveCartItemBody>) => <
|
|
||||||
T extends LineItem | undefined = undefined
|
|
||||||
>(
|
|
||||||
ctx: { item?: T } = {}
|
|
||||||
) => {
|
|
||||||
const { item } = ctx
|
|
||||||
const { mutate } = useCart()
|
const { mutate } = useCart()
|
||||||
const removeItem: RemoveItemFn<LineItem> = async (input) => {
|
|
||||||
const itemId = input?.id ?? item?.id
|
|
||||||
|
|
||||||
if (!itemId) {
|
return useCallback(
|
||||||
throw new ValidationError({
|
async function removeItem(input) {
|
||||||
message: 'Invalid input used for this operation',
|
const data = await fetch({ input: { itemId: input.id } })
|
||||||
})
|
await mutate(data, false)
|
||||||
}
|
|
||||||
|
|
||||||
const data = await fetch({ input: { itemId } })
|
return data
|
||||||
await mutate(data, false)
|
},
|
||||||
return data
|
[fetch, mutate]
|
||||||
}
|
)
|
||||||
|
|
||||||
return useCallback(removeItem as RemoveItemFn<T>, [fetch, mutate])
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,30 @@ import { useCallback } from 'react'
|
|||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import type {
|
import type {
|
||||||
HookFetcherContext,
|
HookFetcherContext,
|
||||||
|
MutationHook,
|
||||||
MutationHookContext,
|
MutationHookContext,
|
||||||
} from '@commerce/utils/types'
|
} from '@commerce/utils/types'
|
||||||
import { ValidationError } from '@commerce/utils/errors'
|
import { ValidationError } from '@commerce/utils/errors'
|
||||||
import useUpdateItem, {
|
// import useUpdateItem, {
|
||||||
UpdateItemInput as UpdateItemInputBase,
|
// UpdateItemInput as UpdateItemInputBase,
|
||||||
UseUpdateItem,
|
// UseUpdateItem,
|
||||||
} from '@commerce/cart/use-update-item'
|
// } from '@commerce/cart/use-update-item'
|
||||||
|
import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item'
|
||||||
import useCart from './use-cart'
|
import useCart from './use-cart'
|
||||||
import { handler as removeItemHandler } from './use-remove-item'
|
import { handler as removeItemHandler } from './use-remove-item'
|
||||||
import type { Cart, LineItem, UpdateCartItemBody } from '../types'
|
import { CartItemBody, LineItem } from '@commerce/types/cart'
|
||||||
import { checkoutToCart } from './utils'
|
import { checkoutToCart } from './utils'
|
||||||
|
import { UpdateItemHook } from '../types/cart'
|
||||||
export type UpdateItemInput<T = any> = T extends LineItem
|
// export type UpdateItemInput<T = any> = T extends LineItem
|
||||||
? Partial<UpdateItemInputBase<LineItem>>
|
// ? Partial<UpdateItemInputBase<LineItem>>
|
||||||
: UpdateItemInputBase<LineItem>
|
// : UpdateItemInputBase<LineItem>
|
||||||
|
|
||||||
export default useUpdateItem as UseUpdateItem<typeof handler>
|
export default useUpdateItem as UseUpdateItem<typeof handler>
|
||||||
|
|
||||||
|
export type UpdateItemActionInput<T = any> = T extends LineItem
|
||||||
|
? Partial<UpdateItemHook['actionInput']>
|
||||||
|
: UpdateItemHook['actionInput']
|
||||||
|
|
||||||
export const handler = {
|
export const handler = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'cart',
|
query: 'cart',
|
||||||
@ -30,7 +35,7 @@ export const handler = {
|
|||||||
input: { itemId, item },
|
input: { itemId, item },
|
||||||
options,
|
options,
|
||||||
fetch,
|
fetch,
|
||||||
}: HookFetcherContext<UpdateCartItemBody>) {
|
}: HookFetcherContext<UpdateItemHook>) {
|
||||||
if (Number.isInteger(item.quantity)) {
|
if (Number.isInteger(item.quantity)) {
|
||||||
// Also allow the update hook to remove an item if the quantity is lower than 1
|
// Also allow the update hook to remove an item if the quantity is lower than 1
|
||||||
if (item.quantity! < 1) {
|
if (item.quantity! < 1) {
|
||||||
@ -52,9 +57,7 @@ export const handler = {
|
|||||||
|
|
||||||
return checkoutToCart(response)
|
return checkoutToCart(response)
|
||||||
},
|
},
|
||||||
useHook: ({
|
useHook: ({ fetch }: MutationHookContext<UpdateItemHook>) => <
|
||||||
fetch,
|
|
||||||
}: MutationHookContext<Cart | null, UpdateCartItemBody>) => <
|
|
||||||
T extends LineItem | undefined = undefined
|
T extends LineItem | undefined = undefined
|
||||||
>(
|
>(
|
||||||
ctx: {
|
ctx: {
|
||||||
@ -66,7 +69,7 @@ export const handler = {
|
|||||||
const { mutate, data: cartData } = useCart() as any
|
const { mutate, data: cartData } = useCart() as any
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
debounce(async (input: UpdateItemInput<T>) => {
|
debounce(async (input: UpdateItemActionInput) => {
|
||||||
const firstLineItem = cartData.lineItems[0]
|
const firstLineItem = cartData.lineItems[0]
|
||||||
const itemId = item?.id || firstLineItem.id
|
const itemId = item?.id || firstLineItem.id
|
||||||
const productId = item?.productId || firstLineItem.productId
|
const productId = item?.productId || firstLineItem.productId
|
||||||
|
@ -9,7 +9,7 @@ export const checkoutCreate = async (fetch: any) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!cart) {
|
if (!cart) {
|
||||||
const cart = await fetch({
|
await fetch({
|
||||||
query: 'cart',
|
query: 'cart',
|
||||||
method: 'setItems',
|
method: 'setItems',
|
||||||
variables: [[]],
|
variables: [[]],
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import { HookFetcherFn } from '@commerce/utils/types'
|
|
||||||
import { Cart } from '@commerce/types'
|
|
||||||
// import { checkoutCreate, checkoutToCart } from '.'
|
|
||||||
import { FetchCartInput } from '@commerce/cart/use-cart'
|
|
||||||
import { data } from 'autoprefixer'
|
|
||||||
import { normalizeCart } from '../../utils'
|
|
||||||
|
|
||||||
const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
|
|
||||||
options,
|
|
||||||
// input: { cartId: checkoutId },
|
|
||||||
fetch,
|
|
||||||
}) => {
|
|
||||||
let checkout
|
|
||||||
|
|
||||||
// if (checkoutId) {
|
|
||||||
const data = await fetch({
|
|
||||||
query: 'cart',
|
|
||||||
method: 'get',
|
|
||||||
// variables: { category: categoryId },
|
|
||||||
})
|
|
||||||
// checkout = data.node
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (checkout?.completedAt || !checkoutId) {
|
|
||||||
// checkout = await checkoutCreate(fetch)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO: Fix this type
|
|
||||||
// return checkoutToCart({ checkout } as any)
|
|
||||||
return normalizeCart(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default fetcher
|
|
@ -1,37 +0,0 @@
|
|||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
|
|
||||||
type Variables = {
|
|
||||||
first?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReturnType = {
|
|
||||||
pages: Page[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Page = {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
url: string
|
|
||||||
sort_order?: number
|
|
||||||
body: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAllPages = async (options?: {
|
|
||||||
variables?: Variables
|
|
||||||
config: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<ReturnType> => {
|
|
||||||
let { config, variables = { first: 250 } } = options ?? {}
|
|
||||||
config = getConfig(config)
|
|
||||||
const { locale, fetch } = config
|
|
||||||
const data = await fetch('content', 'list', ['pages'])
|
|
||||||
const pages =
|
|
||||||
data?.results?.map(({ slug, ...rest }: { slug: string }) => ({
|
|
||||||
url: `/${locale}/${slug}`,
|
|
||||||
...rest,
|
|
||||||
})) ?? []
|
|
||||||
|
|
||||||
return { pages }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getAllPages
|
|
@ -1,33 +0,0 @@
|
|||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
import { Page } from './get-all-pages'
|
|
||||||
|
|
||||||
type Variables = {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetPageResult<T extends { page?: any } = { page?: Page }> = T
|
|
||||||
|
|
||||||
const getPage = async (options: {
|
|
||||||
variables: Variables
|
|
||||||
config: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<GetPageResult> => {
|
|
||||||
let { config, variables } = options ?? {}
|
|
||||||
|
|
||||||
config = getConfig(config)
|
|
||||||
const { locale } = config
|
|
||||||
const { id } = variables
|
|
||||||
const result = await config.fetch('content', 'get', ['pages', id])
|
|
||||||
const page = result
|
|
||||||
|
|
||||||
return {
|
|
||||||
page: page
|
|
||||||
? {
|
|
||||||
...page,
|
|
||||||
url: `/${locale}/${page.slug}`,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getPage
|
|
@ -1,31 +0,0 @@
|
|||||||
import getCategories from '../utils/get-categories'
|
|
||||||
import getVendors, { Brands } from '../utils/get-vendors'
|
|
||||||
import { Category } from '@commerce/types'
|
|
||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
|
|
||||||
export type GetSiteInfoResult<
|
|
||||||
T extends { categories: any[]; brands: any[] } = {
|
|
||||||
categories: Category[]
|
|
||||||
brands: Brands
|
|
||||||
}
|
|
||||||
> = T
|
|
||||||
|
|
||||||
const getSiteInfo = async (options?: {
|
|
||||||
variables?: any
|
|
||||||
config: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<GetSiteInfoResult> => {
|
|
||||||
let { config } = options ?? {}
|
|
||||||
|
|
||||||
config = getConfig(config)
|
|
||||||
|
|
||||||
const categories = await getCategories(config)
|
|
||||||
const brands = await getVendors(config)
|
|
||||||
|
|
||||||
return {
|
|
||||||
categories,
|
|
||||||
brands,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getSiteInfo
|
|
@ -1,11 +1,11 @@
|
|||||||
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
import useCustomer, { UseCustomer } from '@commerce/customer/use-customer'
|
||||||
import { Customer } from '@commerce/types'
|
|
||||||
import { SWRHook } from '@commerce/utils/types'
|
import { SWRHook } from '@commerce/utils/types'
|
||||||
import { normalizeCustomer } from '../utils/normalize'
|
import { normalizeCustomer } from '../utils/normalize'
|
||||||
|
import type { CustomerHook } from '../types/customer'
|
||||||
|
|
||||||
export default useCustomer as UseCustomer<typeof handler>
|
export default useCustomer as UseCustomer<typeof handler>
|
||||||
|
|
||||||
export const handler: SWRHook<Customer | null> = {
|
export const handler: SWRHook<CustomerHook> = {
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'account',
|
query: 'account',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@ -25,26 +25,3 @@ export const handler: SWRHook<Customer | null> = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handler = (): { data: Customer } => {
|
|
||||||
// const swell = getContext();
|
|
||||||
// const response = swell.account.get();
|
|
||||||
// const { firstName, lastName, email, company, customerGroupId, notes, phone,
|
|
||||||
// entityId, addressCount, attributeCount, storeCredit } = response;
|
|
||||||
// return {
|
|
||||||
// data: {
|
|
||||||
// firstName,
|
|
||||||
// lastName,
|
|
||||||
// email,
|
|
||||||
// company,
|
|
||||||
// customerGroupId,
|
|
||||||
// notes,
|
|
||||||
// phone,
|
|
||||||
// entityId,
|
|
||||||
// addressCount,
|
|
||||||
// attributeCount,
|
|
||||||
// storeCredit
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// export default handler;
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
import { CollectionEdge } from '../schema'
|
|
||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
|
|
||||||
const getAllCollections = async (options?: {
|
|
||||||
variables?: any
|
|
||||||
config: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}) => {
|
|
||||||
let { config, variables = { limit: 25 } } = options ?? {}
|
|
||||||
config = getConfig(config)
|
|
||||||
|
|
||||||
const response = await config.fetch('categories', 'list', { variables })
|
|
||||||
const edges = response.results ?? []
|
|
||||||
|
|
||||||
const categories = edges.map(
|
|
||||||
({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({
|
|
||||||
entityId,
|
|
||||||
name,
|
|
||||||
path: `/${handle}`,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
categories,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getAllCollections
|
|
@ -1,39 +0,0 @@
|
|||||||
import { SwellProduct } from '../types'
|
|
||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
|
|
||||||
type ProductPath = {
|
|
||||||
path: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ProductPathNode = {
|
|
||||||
node: ProductPath
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReturnType = {
|
|
||||||
products: ProductPathNode[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAllProductPaths = async (options?: {
|
|
||||||
variables?: any
|
|
||||||
config?: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<ReturnType> => {
|
|
||||||
let { config, variables = [{ limit: 100 }] } = options ?? {}
|
|
||||||
config = getConfig(config)
|
|
||||||
|
|
||||||
const { results } = await config.fetch('products', 'list', [
|
|
||||||
{
|
|
||||||
limit: variables.first,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
return {
|
|
||||||
products: results?.map(({ slug: handle }: SwellProduct) => ({
|
|
||||||
node: {
|
|
||||||
path: `/${handle}`,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getAllProductPaths
|
|
@ -1,36 +0,0 @@
|
|||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
import { normalizeProduct } from '../utils/normalize'
|
|
||||||
import { Product } from '@commerce/types'
|
|
||||||
import { SwellProduct } from '../types'
|
|
||||||
|
|
||||||
type Variables = {
|
|
||||||
first?: number
|
|
||||||
field?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReturnType = {
|
|
||||||
products: Product[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAllProducts = async (options: {
|
|
||||||
variables?: Variables
|
|
||||||
config?: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<ReturnType> => {
|
|
||||||
let { config, variables = { first: 250 } } = options ?? {}
|
|
||||||
config = getConfig(config)
|
|
||||||
const { results } = await config.fetch('products', 'list', [
|
|
||||||
{
|
|
||||||
limit: variables.first,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
const products = results.map((product: SwellProduct) =>
|
|
||||||
normalizeProduct(product)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
products,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getAllProducts
|
|
@ -1,32 +0,0 @@
|
|||||||
import { GraphQLFetcherResult } from '@commerce/api'
|
|
||||||
import { getConfig, SwellConfig } from '../api'
|
|
||||||
import { normalizeProduct } from '../utils'
|
|
||||||
|
|
||||||
type Variables = {
|
|
||||||
slug: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReturnType = {
|
|
||||||
product: any
|
|
||||||
}
|
|
||||||
|
|
||||||
const getProduct = async (options: {
|
|
||||||
variables: Variables
|
|
||||||
config: SwellConfig
|
|
||||||
preview?: boolean
|
|
||||||
}): Promise<ReturnType> => {
|
|
||||||
let { config, variables } = options ?? {}
|
|
||||||
config = getConfig(config)
|
|
||||||
|
|
||||||
const product = await config.fetch('products', 'get', [variables.slug])
|
|
||||||
|
|
||||||
if (product && product.variants) {
|
|
||||||
product.variants = product.variants?.results
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
product: product ? normalizeProduct(product) : null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getProduct
|
|
2
framework/swell/product/index.ts
Normal file
2
framework/swell/product/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { default as usePrice } from './use-price'
|
||||||
|
export { default as useSearch } from './use-search'
|
@ -1,11 +1,8 @@
|
|||||||
import { SWRHook } from '@commerce/utils/types'
|
import { SWRHook } from '@commerce/utils/types'
|
||||||
import useSearch, { UseSearch } from '@commerce/product/use-search'
|
import useSearch, { UseSearch } from '@commerce/product/use-search'
|
||||||
|
|
||||||
import { normalizeProduct } from '../utils'
|
import { normalizeProduct } from '../utils'
|
||||||
|
|
||||||
import { Product } from '@commerce/types'
|
|
||||||
|
|
||||||
import { SwellProduct } from '../types'
|
import { SwellProduct } from '../types'
|
||||||
|
import type { SearchProductsHook } from '../types/product'
|
||||||
|
|
||||||
export default useSearch as UseSearch<typeof handler>
|
export default useSearch as UseSearch<typeof handler>
|
||||||
|
|
||||||
@ -16,18 +13,9 @@ export type SearchProductsInput = {
|
|||||||
sort?: string
|
sort?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchProductsData = {
|
export const handler: SWRHook<SearchProductsHook> = {
|
||||||
products: Product[]
|
|
||||||
found: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const handler: SWRHook<
|
|
||||||
SearchProductsData,
|
|
||||||
SearchProductsInput,
|
|
||||||
SearchProductsInput
|
|
||||||
> = {
|
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
query: 'products', // String(Math.random()),
|
query: 'products',
|
||||||
method: 'list',
|
method: 'list',
|
||||||
},
|
},
|
||||||
async fetcher({ input, options, fetch }) {
|
async fetcher({ input, options, fetch }) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { Provider } from '@commerce'
|
||||||
|
|
||||||
import { SWELL_CHECKOUT_URL_COOKIE, STORE_DOMAIN } from './const'
|
import { SWELL_CHECKOUT_URL_COOKIE, STORE_DOMAIN } from './const'
|
||||||
|
|
||||||
import { handler as useCart } from './cart/use-cart'
|
import { handler as useCart } from './cart/use-cart'
|
||||||
@ -14,18 +16,15 @@ import { handler as useSignup } from './auth/use-signup'
|
|||||||
|
|
||||||
import fetcher from './fetcher'
|
import fetcher from './fetcher'
|
||||||
|
|
||||||
export const swellProvider = {
|
export const swellProvider: Provider = {
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
cartCookie: SWELL_CHECKOUT_URL_COOKIE,
|
cartCookie: SWELL_CHECKOUT_URL_COOKIE,
|
||||||
storeDomain: STORE_DOMAIN,
|
// storeDomain: STORE_DOMAIN,
|
||||||
fetcher,
|
fetcher,
|
||||||
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
|
||||||
customer: { useCustomer },
|
customer: { useCustomer },
|
||||||
products: { useSearch },
|
products: { useSearch },
|
||||||
auth: { useLogin, useLogout, useSignup },
|
auth: { useLogin, useLogout, useSignup },
|
||||||
features: {
|
|
||||||
wishlist: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SwellProvider = typeof swellProvider
|
export type SwellProvider = typeof swellProvider
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as Core from '@commerce/types'
|
import * as Core from '@commerce/types/cart'
|
||||||
|
import { Customer } from '@commerce/types'
|
||||||
import { CheckoutLineItem } from './schema'
|
import { CheckoutLineItem } from './schema'
|
||||||
|
|
||||||
export type SwellImage = {
|
export type SwellImage = {
|
||||||
@ -43,12 +44,18 @@ export type SwellVariant = {
|
|||||||
name: string
|
name: string
|
||||||
price?: number
|
price?: number
|
||||||
stock_status?: string
|
stock_status?: string
|
||||||
|
__type?: 'MultipleChoiceOption' | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SwellProductOptionValue {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
hexColors?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductOptionValue {
|
export interface ProductOptionValue {
|
||||||
label: string
|
label: string
|
||||||
hexColors?: string[]
|
hexColors?: string[]
|
||||||
id: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductOptions = {
|
export type ProductOptions = {
|
||||||
@ -73,10 +80,7 @@ export interface SwellProduct {
|
|||||||
variants: any[]
|
variants: any[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SwellCustomer extends Core.Customer {
|
export type SwellCustomer = any
|
||||||
first_name: string
|
|
||||||
last_name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SwellCheckout = {
|
export type SwellCheckout = {
|
||||||
id: string
|
id: string
|
||||||
@ -106,17 +110,3 @@ export type CartItemBody = Core.CartItemBody & {
|
|||||||
productId: string // The product id is always required for BC
|
productId: string // The product id is always required for BC
|
||||||
optionSelections?: OptionSelections
|
optionSelections?: OptionSelections
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetCartHandlerBody = Core.GetCartHandlerBody
|
|
||||||
|
|
||||||
export type AddCartItemBody = Core.AddCartItemBody<CartItemBody>
|
|
||||||
|
|
||||||
export type AddCartItemHandlerBody = Core.AddCartItemHandlerBody<CartItemBody>
|
|
||||||
|
|
||||||
export type UpdateCartItemBody = Core.UpdateCartItemBody<CartItemBody>
|
|
||||||
|
|
||||||
export type UpdateCartItemHandlerBody = Core.UpdateCartItemHandlerBody<CartItemBody>
|
|
||||||
|
|
||||||
export type RemoveCartItemBody = Core.RemoveCartItemBody
|
|
||||||
|
|
||||||
export type RemoveCartItemHandlerBody = Core.RemoveCartItemHandlerBody
|
|
||||||
|
1
framework/swell/types/cart.ts
Normal file
1
framework/swell/types/cart.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/cart'
|
1
framework/swell/types/checkout.ts
Normal file
1
framework/swell/types/checkout.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/checkout'
|
1
framework/swell/types/common.ts
Normal file
1
framework/swell/types/common.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/common'
|
1
framework/swell/types/customer.ts
Normal file
1
framework/swell/types/customer.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/customer'
|
25
framework/swell/types/index.ts
Normal file
25
framework/swell/types/index.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import * as Cart from './cart'
|
||||||
|
import * as Checkout from './checkout'
|
||||||
|
import * as Common from './common'
|
||||||
|
import * as Customer from './customer'
|
||||||
|
import * as Login from './login'
|
||||||
|
import * as Logout from './logout'
|
||||||
|
import * as Page from './page'
|
||||||
|
import * as Product from './product'
|
||||||
|
import * as Signup from './signup'
|
||||||
|
import * as Site from './site'
|
||||||
|
import * as Wishlist from './wishlist'
|
||||||
|
|
||||||
|
export type {
|
||||||
|
Cart,
|
||||||
|
Checkout,
|
||||||
|
Common,
|
||||||
|
Customer,
|
||||||
|
Login,
|
||||||
|
Logout,
|
||||||
|
Page,
|
||||||
|
Product,
|
||||||
|
Signup,
|
||||||
|
Site,
|
||||||
|
Wishlist,
|
||||||
|
}
|
11
framework/swell/types/login.ts
Normal file
11
framework/swell/types/login.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import * as Core from '@commerce/types/login'
|
||||||
|
import { LoginBody, LoginTypes } from '@commerce/types/login'
|
||||||
|
|
||||||
|
export * from '@commerce/types/login'
|
||||||
|
|
||||||
|
export type LoginHook<T extends LoginTypes = LoginTypes> = {
|
||||||
|
data: null
|
||||||
|
actionInput: LoginBody
|
||||||
|
fetcherInput: LoginBody
|
||||||
|
body: T['body']
|
||||||
|
}
|
1
framework/swell/types/logout.ts
Normal file
1
framework/swell/types/logout.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/logout'
|
1
framework/swell/types/page.ts
Normal file
1
framework/swell/types/page.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/page'
|
1
framework/swell/types/product.ts
Normal file
1
framework/swell/types/product.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/product'
|
1
framework/swell/types/signup.ts
Normal file
1
framework/swell/types/signup.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/signup'
|
1
framework/swell/types/site.ts
Normal file
1
framework/swell/types/site.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/site'
|
1
framework/swell/types/wishlist.ts
Normal file
1
framework/swell/types/wishlist.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from '@commerce/types/wishlist'
|
@ -1,5 +1,5 @@
|
|||||||
import { SwellConfig } from '../api'
|
import { SwellConfig } from '../api'
|
||||||
import { Category } from '@commerce/types'
|
import { Category } from '../types/site'
|
||||||
|
|
||||||
const getCategories = async (config: SwellConfig): Promise<Category[]> => {
|
const getCategories = async (config: SwellConfig): Promise<Category[]> => {
|
||||||
const data = await config.fetch('categories', 'get')
|
const data = await config.fetch('categories', 'get')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Product, Customer } from '@commerce/types'
|
import { Customer } from '../types/customer'
|
||||||
|
import { Product, ProductOption } from '../types/product'
|
||||||
import { MoneyV2, ProductOption } from '../schema'
|
import { MoneyV2 } from '../schema'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
Cart,
|
Cart,
|
||||||
@ -10,6 +10,7 @@ import type {
|
|||||||
SwellImage,
|
SwellImage,
|
||||||
SwellVariant,
|
SwellVariant,
|
||||||
ProductOptionValue,
|
ProductOptionValue,
|
||||||
|
SwellProductOptionValue,
|
||||||
SwellCart,
|
SwellCart,
|
||||||
LineItem,
|
LineItem,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
@ -21,8 +22,13 @@ const money = ({ amount, currencyCode }: MoneyV2) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type swellProductOption = {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
values: any[]
|
||||||
|
}
|
||||||
|
|
||||||
type normalizedProductOption = {
|
type normalizedProductOption = {
|
||||||
__typename?: string
|
|
||||||
id: string
|
id: string
|
||||||
displayName: string
|
displayName: string
|
||||||
values: ProductOptionValue[]
|
values: ProductOptionValue[]
|
||||||
@ -32,11 +38,11 @@ const normalizeProductOption = ({
|
|||||||
id,
|
id,
|
||||||
name: displayName = '',
|
name: displayName = '',
|
||||||
values = [],
|
values = [],
|
||||||
}: ProductOption) => {
|
}: swellProductOption): ProductOption => {
|
||||||
let returnValues = values.map((value) => {
|
let returnValues = values.map((value) => {
|
||||||
let output: any = {
|
let output: any = {
|
||||||
label: value.name,
|
label: value.name,
|
||||||
id: value?.id || id,
|
// id: value?.id || id,
|
||||||
}
|
}
|
||||||
if (displayName.match(/colou?r/gi)) {
|
if (displayName.match(/colou?r/gi)) {
|
||||||
output = {
|
output = {
|
||||||
@ -68,7 +74,7 @@ const normalizeProductImages = (images: SwellImage[]) => {
|
|||||||
|
|
||||||
const normalizeProductVariants = (
|
const normalizeProductVariants = (
|
||||||
variants: SwellVariant[],
|
variants: SwellVariant[],
|
||||||
productOptions: normalizedProductOption[]
|
productOptions: swellProductOption[]
|
||||||
) => {
|
) => {
|
||||||
return variants?.map(
|
return variants?.map(
|
||||||
({ id, name, price, option_value_ids: optionValueIds = [] }) => {
|
({ id, name, price, option_value_ids: optionValueIds = [] }) => {
|
||||||
@ -79,22 +85,22 @@ const normalizeProductVariants = (
|
|||||||
const options = optionValueIds.map((id) => {
|
const options = optionValueIds.map((id) => {
|
||||||
const matchingOption = productOptions.find((option) => {
|
const matchingOption = productOptions.find((option) => {
|
||||||
return option.values.find(
|
return option.values.find(
|
||||||
(value: ProductOptionValue) => value.id == id
|
(value: SwellProductOptionValue) => value.id == id
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
return normalizeProductOption({
|
return normalizeProductOption({
|
||||||
id,
|
id,
|
||||||
name: matchingOption?.displayName ?? '',
|
name: matchingOption?.name ?? '',
|
||||||
values,
|
values,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
name,
|
// name,
|
||||||
// sku: sku ?? id,
|
// sku: sku ?? id,
|
||||||
price: price ?? null,
|
// price: price ?? null,
|
||||||
listPrice: price ?? null,
|
// listPrice: price ?? null,
|
||||||
// requiresShipping: true,
|
// requiresShipping: true,
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
@ -116,11 +122,12 @@ export function normalizeProduct(swellProduct: SwellProduct): Product {
|
|||||||
} = swellProduct
|
} = swellProduct
|
||||||
// ProductView accesses variants for each product
|
// ProductView accesses variants for each product
|
||||||
const emptyVariants = [{ options: [], id, name }]
|
const emptyVariants = [{ options: [], id, name }]
|
||||||
|
|
||||||
const productOptions = options
|
const productOptions = options
|
||||||
? options.map((o) => normalizeProductOption(o))
|
? options.map((o) => normalizeProductOption(o))
|
||||||
: []
|
: []
|
||||||
const productVariants = variants
|
const productVariants = variants
|
||||||
? normalizeProductVariants(variants, productOptions)
|
? normalizeProductVariants(variants, options)
|
||||||
: []
|
: []
|
||||||
|
|
||||||
const productImages = normalizeProductImages(images)
|
const productImages = normalizeProductImages(images)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user