Removed old getConfig and references

This commit is contained in:
Luis Alvarez 2021-05-24 19:01:27 -05:00
parent a106629964
commit ee3e4143b9
19 changed files with 51 additions and 247 deletions

View File

@ -1,77 +0,0 @@
import isAllowedMethod from './utils/is-allowed-method'
import createApiHandler, {
BigcommerceApiHandler,
} from './utils/create-api-handler'
import { BigcommerceApiError } from './utils/errors'
const METHODS = ['GET']
const fullCheckout = true
// TODO: a complete implementation should have schema validation for `req.body`
const checkoutApi: BigcommerceApiHandler<any> = async (req, res, config) => {
if (!isAllowedMethod(req, res, METHODS)) return
const { cookies } = req
const cartId = cookies[config.cartCookie]
try {
if (!cartId) {
res.redirect('/cart')
return
}
const { data } = await config.storeApiFetch(
`/v3/carts/${cartId}/redirect_urls`,
{
method: 'POST',
}
)
if (fullCheckout) {
res.redirect(data.checkout_url)
return
}
// TODO: make the embedded checkout work too!
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Checkout</title>
<script src="https://checkout-sdk.bigcommerce.com/v1/loader.js"></script>
<script>
window.onload = function() {
checkoutKitLoader.load('checkout-sdk').then(function (service) {
service.embedCheckout({
containerId: 'checkout',
url: '${data.embedded_checkout_url}'
});
});
}
</script>
</head>
<body>
<div id="checkout"></div>
</body>
</html>
`
res.status(200)
res.setHeader('Content-Type', 'text/html')
res.write(html)
res.end()
} catch (error) {
console.error(error)
const message =
error instanceof BigcommerceApiError
? 'An unexpected error ocurred with the Bigcommerce API'
: 'An unexpected error ocurred'
res.status(500).json({ data: null, errors: [{ message }] })
}
}
export default createApiHandler(checkoutApi, {}, {})

View File

@ -61,47 +61,9 @@ if (!(STORE_API_URL && STORE_API_TOKEN && STORE_API_CLIENT_ID)) {
)
}
export class Config {
private config: BigcommerceConfig
constructor(config: Omit<BigcommerceConfig, 'customerCookie'>) {
this.config = {
...config,
// The customerCookie is not customizable for now, BC sets the cookie and it's
// not important to rename it
customerCookie: 'SHOP_TOKEN',
}
}
getConfig(userConfig: Partial<BigcommerceConfig> = {}) {
return Object.entries(userConfig).reduce<BigcommerceConfig>(
(cfg, [key, value]) => Object.assign(cfg, { [key]: value }),
{ ...this.config }
)
}
setConfig(newConfig: Partial<BigcommerceConfig>) {
Object.assign(this.config, newConfig)
}
}
const ONE_DAY = 60 * 60 * 24
const config = new Config({
commerceUrl: API_URL,
apiToken: API_TOKEN,
cartCookie: process.env.BIGCOMMERCE_CART_COOKIE ?? 'bc_cartId',
cartCookieMaxAge: ONE_DAY * 30,
fetch: fetchGraphqlApi,
applyLocale: true,
// REST API only
storeApiUrl: STORE_API_URL,
storeApiToken: STORE_API_TOKEN,
storeApiClientId: STORE_API_CLIENT_ID,
storeChannelId: STORE_CHANNEL_ID,
storeApiFetch: fetchStoreApi,
})
const config2: BigcommerceConfig = {
const config: BigcommerceConfig = {
commerceUrl: API_URL,
apiToken: API_TOKEN,
customerCookie: 'SHOP_TOKEN',
@ -117,20 +79,19 @@ const config2: BigcommerceConfig = {
storeApiFetch: fetchStoreApi,
}
export const provider = {
config: config2,
operations: {
login,
getAllPages,
getPage,
getSiteInfo,
getCustomerWishlist,
getAllProductPaths,
getAllProducts,
getProduct,
},
const operations = {
login,
getAllPages,
getPage,
getSiteInfo,
getCustomerWishlist,
getAllProductPaths,
getAllProducts,
getProduct,
}
export const provider = { config, operations }
export type Provider = typeof provider
export type APIs =
@ -149,11 +110,3 @@ export function getCommerceApi<P extends Provider>(
): BigcommerceAPI<P> {
return commerceApi(customProvider)
}
export function getConfig(userConfig?: Partial<BigcommerceConfig>) {
return config.getConfig(userConfig)
}
export function setConfig(newConfig: Partial<BigcommerceConfig>) {
return config.setConfig(newConfig)
}

View File

@ -10,13 +10,13 @@ export default function getAllPagesOperation({
commerce,
}: OperationContext<Provider>) {
async function getAllPages<T extends GetAllPagesOperation>(opts?: {
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getAllPages<T extends GetAllPagesOperation>(
opts: {
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
@ -26,13 +26,13 @@ export default function getAllPagesOperation({
preview,
}: {
url?: string
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} = {}): Promise<T['data']> {
config = commerce.getConfig(config)
const cfg = commerce.getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `url`
const { data } = await config.storeApiFetch<
const { data } = await cfg.storeApiFetch<
RecursivePartial<{ data: Page[] }>
>('/v3/content/pages')
const pages = (data as RecursiveRequired<typeof data>) ?? []

View File

@ -76,14 +76,14 @@ export default function getAllProductsOperation({
}: OperationContext<Provider>) {
async function getAllProducts<T extends GetAllProductsOperation>(opts?: {
variables?: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getAllProducts<T extends GetAllProductsOperation>(
opts: {
variables?: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
@ -91,15 +91,14 @@ export default function getAllProductsOperation({
async function getAllProducts<T extends GetAllProductsOperation>({
query = getAllProductsQuery,
variables: vars = {},
config,
config: cfg,
}: {
query?: string
variables?: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} = {}): Promise<T['data']> {
config = commerce.getConfig(config)
const config = commerce.getConfig(cfg)
const { locale } = config
const field = getProductsType(vars.relevance)
const variables: GetAllProductsQueryVariables = {

View File

@ -11,14 +11,14 @@ export default function getPageOperation({
}: OperationContext<Provider>) {
async function getPage<T extends GetPageOperation>(opts: {
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getPage<T extends GetPageOperation>(
opts: {
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
@ -31,13 +31,13 @@ export default function getPageOperation({
}: {
url?: string
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']> {
config = commerce.getConfig(config)
const cfg = commerce.getConfig(config)
// RecursivePartial forces the method to check for every prop in the data, which is
// required in case there's a custom `url`
const { data } = await config.storeApiFetch<
const { data } = await cfg.storeApiFetch<
RecursivePartial<{ data: Page[] }>
>(url || `/v3/content/pages?id=${variables.id}&include=body`)
const firstPage = data?.[0]

View File

@ -73,14 +73,14 @@ export default function getAllProductPathsOperation({
}: OperationContext<Provider>) {
async function getProduct<T extends GetProductOperation>(opts: {
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getProduct<T extends GetProductOperation>(
opts: {
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
@ -88,15 +88,14 @@ export default function getAllProductPathsOperation({
async function getProduct<T extends GetProductOperation>({
query = getProductQuery,
variables: { slug, ...vars },
config,
config: cfg,
}: {
query?: string
variables: T['variables']
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']> {
config = commerce.getConfig(config)
const config = commerce.getConfig(cfg)
const { locale } = config
const variables: GetProductQueryVariables = {
locale,

View File

@ -53,13 +53,13 @@ export default function getSiteInfoOperation({
commerce,
}: OperationContext<Provider>) {
async function getSiteInfo<T extends GetSiteInfoOperation>(opts?: {
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
}): Promise<T['data']>
async function getSiteInfo<T extends GetSiteInfoOperation>(
opts: {
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} & OperationOptions
): Promise<T['data']>
@ -69,15 +69,13 @@ export default function getSiteInfoOperation({
config,
}: {
query?: string
config?: BigcommerceConfig
config?: Partial<BigcommerceConfig>
preview?: boolean
} = {}): Promise<T['data']> {
config = commerce.getConfig(config)
const cfg = 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 config.fetch<RecursivePartial<GetSiteInfoQuery>>(
query
)
const { data } = await cfg.fetch<RecursivePartial<GetSiteInfoQuery>>(query)
const categories = data.site?.categoryTree
const brands = data.site?.brands?.edges

View File

@ -1,58 +0,0 @@
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
import { BigcommerceConfig, getConfig } from '..'
export type BigcommerceApiHandler<
T = any,
H extends BigcommerceHandlers = {},
Options extends {} = {}
> = (
req: NextApiRequest,
res: NextApiResponse<BigcommerceApiResponse<T>>,
config: BigcommerceConfig,
handlers: H,
// Custom configs that may be used by a particular handler
options: Options
) => void | Promise<void>
export type BigcommerceHandler<T = any, Body = null> = (options: {
req: NextApiRequest
res: NextApiResponse<BigcommerceApiResponse<T>>
config: BigcommerceConfig
body: Body
}) => void | Promise<void>
export type BigcommerceHandlers<T = any> = {
[k: string]: BigcommerceHandler<T, any>
}
export type BigcommerceApiResponse<T> = {
data: T | null
errors?: { message: string; code?: string }[]
}
export default function createApiHandler<
T = any,
H extends BigcommerceHandlers = {},
Options extends {} = {}
>(
handler: BigcommerceApiHandler<T, H, Options>,
handlers: H,
defaultOptions: Options
) {
return function getApiHandler({
config,
operations,
options,
}: {
config?: BigcommerceConfig
operations?: Partial<H>
options?: Options extends {} ? Partial<Options> : never
} = {}): NextApiHandler {
const ops = { ...handlers, ...operations }
const opts = { ...defaultOptions, ...options }
return function apiHandler(req, res) {
return handler(req, res, getConfig(config), ops, opts)
}
}
}

View File

@ -1,15 +1,15 @@
import { FetcherError } from '@commerce/utils/errors'
import type { GraphQLFetcher } from '@commerce/api'
import { getConfig } from '..'
import { provider } from '..'
import fetch from './fetch'
const { config } = provider
const fetchGraphqlApi: GraphQLFetcher = async (
query: string,
{ variables, preview } = {},
fetchOptions
) => {
// log.warn(query)
const config = getConfig()
const res = await fetch(config.commerceUrl + (preview ? '/preview' : ''), {
...fetchOptions,
method: 'POST',

View File

@ -1,13 +1,14 @@
import type { RequestInit, Response } from '@vercel/fetch'
import { getConfig } from '..'
import { provider } from '..'
import { BigcommerceApiError, BigcommerceNetworkError } from './errors'
import fetch from './fetch'
const { config } = provider
export default async function fetchStoreApi<T>(
endpoint: string,
options?: RequestInit
): Promise<T> {
const config = getConfig()
let res: Response
try {

View File

@ -8,7 +8,6 @@ import { Text } from '@components/ui'
import { Layout } from '@components/common'
import getSlug from '@lib/get-slug'
import { missingLocaleInPages } from '@lib/usage-warns'
import { getConfig } from '@framework/api'
import { defaultPageProps } from '@lib/defaults'
export async function getStaticProps({
@ -16,7 +15,7 @@ export async function getStaticProps({
params,
locale,
}: GetStaticPropsContext<{ pages: string[] }>) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ preview, config })
const path = params?.pages.join('/')
const slug = locale ? `${locale}/${path}` : path

View File

@ -1,5 +1,4 @@
import type { GetStaticPropsContext } from 'next'
import { getConfig } from '@framework/api'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { Container } from '@components/ui'
@ -8,7 +7,7 @@ export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
return {
props: { pages },

View File

@ -1,5 +1,4 @@
import type { GetStaticPropsContext } from 'next'
import { getConfig } from '@framework/api'
import useCart from '@framework/cart/use-cart'
import usePrice from '@framework/product/use-price'
import commerce from '@lib/api/commerce'
@ -12,7 +11,7 @@ export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
return {
props: { pages },

View File

@ -5,14 +5,11 @@ import { ProductCard } from '@components/product'
// import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
import { getConfig } from '@framework/api'
export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { products } = await commerce.getAllProducts({
variables: { first: 12 },
config,

View File

@ -3,13 +3,12 @@ import commerce from '@lib/api/commerce'
import { Bag } from '@components/icons'
import { Layout } from '@components/common'
import { Container, Text } from '@components/ui'
import { getConfig } from '@framework/api'
export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
return {
props: { pages },

View File

@ -7,14 +7,13 @@ import { useRouter } from 'next/router'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
import { ProductView } from '@components/product'
import { getConfig } from '@framework/api'
export async function getStaticProps({
params,
locale,
preview,
}: GetStaticPropsContext<{ slug: string }>) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
const { product } = await commerce.getProduct({
variables: { slug: params!.slug },

View File

@ -1,5 +1,4 @@
import type { GetStaticPropsContext } from 'next'
import { getConfig } from '@framework/api'
import useCustomer from '@framework/customer/use-customer'
import commerce from '@lib/api/commerce'
import { Layout } from '@components/common'
@ -9,7 +8,7 @@ export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
return {
props: { pages },

View File

@ -8,7 +8,6 @@ import { Layout } from '@components/common'
import { ProductCard } from '@components/product'
import { Container, Grid, Skeleton } from '@components/ui'
import { getConfig } from '@framework/api'
import useSearch from '@framework/product/use-search'
import commerce from '@lib/api/commerce'
import rangeMap from '@lib/range-map'
@ -36,7 +35,7 @@ export async function getStaticProps({
preview,
locale,
}: GetStaticPropsContext) {
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
const { categories, brands } = await commerce.getSiteInfo({ config, preview })
return {

View File

@ -4,7 +4,6 @@ import { Heart } from '@components/icons'
import { Layout } from '@components/common'
import { Text, Container } from '@components/ui'
import { defaultPageProps } from '@lib/defaults'
import { getConfig } from '@framework/api'
import { useCustomer } from '@framework/customer'
import { WishlistCard } from '@components/wishlist'
import useWishlist from '@framework/wishlist/use-wishlist'
@ -20,7 +19,7 @@ export async function getStaticProps({
}
}
const config = getConfig({ locale })
const config = { locale }
const { pages } = await commerce.getAllPages({ config, preview })
return {
props: {