Updated CommerceAPI class for better usage

This commit is contained in:
Luis Alvarez 2021-03-17 02:23:38 -06:00
parent 4afb5f569e
commit 21c0b7ee42
4 changed files with 54 additions and 13 deletions

View File

@ -1,8 +1,7 @@
import type { RequestInit } from '@vercel/fetch' import type { RequestInit } from '@vercel/fetch'
import { import {
CommerceAPI, CommerceAPI as CoreCommerceAPI,
CommerceAPIConfig, CommerceAPIConfig,
createAPIProvider,
} from '@commerce/api' } from '@commerce/api'
import fetchGraphqlApi from './utils/fetch-graphql-api' import fetchGraphqlApi from './utils/fetch-graphql-api'
import fetchStoreApi from './utils/fetch-store-api' import fetchStoreApi from './utils/fetch-store-api'
@ -99,13 +98,17 @@ const config2: BigcommerceConfig = {
storeApiFetch: fetchStoreApi, storeApiFetch: fetchStoreApi,
} }
const provider = { export const provider = {
config: config2, config: config2,
// endpoints
} }
export const commerce2 = createAPIProvider(provider) export type Provider = typeof provider
export const commerce = new CommerceAPI(provider)
export class CommerceAPI<P extends Provider> extends CoreCommerceAPI<P> {
constructor(readonly provider: P = provider) {
super(provider)
}
}
export function getConfig(userConfig?: Partial<BigcommerceConfig>) { export function getConfig(userConfig?: Partial<BigcommerceConfig>) {
return config.getConfig(userConfig) return config.getConfig(userConfig)

View File

@ -1,6 +1,9 @@
import type { NextApiHandler } from 'next'
import type { RequestInit, Response } from '@vercel/fetch' import type { RequestInit, Response } from '@vercel/fetch'
import type { APIEndpoint, APIHandler } from './utils/types' import type { APIEndpoint, APIHandler } from './utils/types'
export type CartEndpoint = APIEndpoint<any, any, CartHandlers<any>, any>
export type CartHandlers<Body extends { cartId: 'string' }> = { export type CartHandlers<Body extends { cartId: 'string' }> = {
getCart: APIHandler<any, CartHandlers<Body>, any, Body> getCart: APIHandler<any, CartHandlers<Body>, any, Body>
addItem: APIHandler<any, CartHandlers<Body>, any, Body> addItem: APIHandler<any, CartHandlers<Body>, any, Body>
@ -8,14 +11,18 @@ export type CartHandlers<Body extends { cartId: 'string' }> = {
removeItem: APIHandler<any, CartHandlers<Body>, any, Body> removeItem: APIHandler<any, CartHandlers<Body>, any, Body>
} }
export type Endpoints = CartEndpoint
export type EndpointHandlers<E> = E extends APIEndpoint<any, any, infer T>
? T
: never
export type EndpointOptions<E> = E extends APIEndpoint<any, any, any, infer T>
? T
: never
export type CoreAPIProvider = { export type CoreAPIProvider = {
config: CommerceAPIConfig config: CommerceAPIConfig
endpoints?: {
cart?: {
handler: APIEndpoint<any, any, CartHandlers<any>, any>
handlers: CartHandlers<any>
}
}
} }
export type APIProvider<P extends CoreAPIProvider = CoreAPIProvider> = P & { export type APIProvider<P extends CoreAPIProvider = CoreAPIProvider> = P & {
@ -23,7 +30,10 @@ export type APIProvider<P extends CoreAPIProvider = CoreAPIProvider> = P & {
setConfig(newConfig: Partial<P['config']>): void setConfig(newConfig: Partial<P['config']>): void
} }
export class CommerceAPI<P extends CoreAPIProvider = CoreAPIProvider> { export class CommerceAPI<
P extends CoreAPIProvider = CoreAPIProvider,
E extends Endpoints = Endpoints
> {
constructor(readonly provider: P) { constructor(readonly provider: P) {
this.provider = provider this.provider = provider
} }
@ -38,6 +48,27 @@ export class CommerceAPI<P extends CoreAPIProvider = CoreAPIProvider> {
setConfig(newConfig: Partial<P['config']>) { setConfig(newConfig: Partial<P['config']>) {
Object.assign(this.provider.config, newConfig) Object.assign(this.provider.config, newConfig)
} }
endpoint(context: {
handler: E
config?: P['config']
operations: EndpointHandlers<typeof context.handler>
options?: EndpointOptions<typeof context.handler>
}): NextApiHandler {
const provider = this
const cfg = this.getConfig(context.config)
return function apiHandler(req, res) {
return context.handler({
req,
res,
provider,
config: cfg,
handlers: context.operations,
options: context.options,
})
}
}
} }
export function createAPIProvider<P extends CoreAPIProvider>( export function createAPIProvider<P extends CoreAPIProvider>(

3
lib/api/commerce.ts Normal file
View File

@ -0,0 +1,3 @@
import { CommerceAPI } from '@framework/api'
export default new CommerceAPI()

View File

@ -1,3 +1,7 @@
import cartApi from '@framework/api/cart' import cartApi from '@framework/api/cart'
import cart from '@commerce/api/endpoints/cart'
import commerce from '@lib/api/commerce'
const x = commerce.endpoint({ handler: cart, operations: {} as any })
export default cartApi() export default cartApi()