Adding more experimental types

This commit is contained in:
Luis Alvarez 2021-03-20 16:52:32 -06:00
parent 149df82f45
commit fed3c82c69
6 changed files with 84 additions and 47 deletions

View File

@ -1,9 +1,9 @@
import { normalizeCart } from '@framework/lib/normalize'
import { parseCartItem } from '../utils/parse-item'
import getCartCookie from '../utils/get-cart-cookie'
import type { CartHandlers } from '.'
import type { CartEndpoint } from '.'
const addItem: CartHandlers['addItem'] = async ({
const addItem: CartEndpoint['operations']['addItem'] = async ({
res,
body: { cartId, item },
config,

View File

@ -2,10 +2,10 @@ import { normalizeCart } from '@framework/lib/normalize'
import { BigcommerceApiError } from '../utils/errors'
import getCartCookie from '../utils/get-cart-cookie'
import type { BigcommerceCart } from '../../types'
import type { CartHandlers } from '.'
import type { CartEndpoint } from '.'
// Return current cart info
const getCart: CartHandlers['getCart'] = async ({
const getCart: CartEndpoint['operations']['getCart'] = async ({
res,
body: { cartId },
config,

View File

@ -1,4 +1,4 @@
import { EndpointSchema } from '@commerce/api'
import { EndpointSchema, GetAPISchema } from '@commerce/api'
import getCart from './get-cart'
import addItem from './add-item'
import updateItem from './handlers/update-item'
@ -10,25 +10,27 @@ import type {
RemoveCartItemHandlerBody,
Cart,
} from '../../types'
import type { CommerceAPIEndpoints } from '..'
import type { CommerceAPI } from '..'
export type CartEndpointSchema = EndpointSchema<
'cart',
export type CartAPI = GetAPISchema<
CommerceAPI,
{
options: {}
operations: {
getCart: {
data: Cart | null
body: GetCartHandlerBody
options: { yay: string }
endpoint: {
options: {}
operations: {
getCart: {
data: Cart | null
body: GetCartHandlerBody
options: { yay: string }
}
addItem: { data: Cart; body: AddCartItemHandlerBody; options: {} }
updateItem: { data: Cart; body: UpdateCartItemHandlerBody; options: {} }
removeItem: { data: Cart; body: RemoveCartItemHandlerBody; options: {} }
}
addItem: { data: Cart; body: AddCartItemHandlerBody; options: {} }
updateItem: { data: Cart; body: UpdateCartItemHandlerBody; options: {} }
removeItem: { data: Cart; body: RemoveCartItemHandlerBody; options: {} }
}
}
>
export type CartAPI = CommerceAPIEndpoints['cart']
export type CartEndpoint = CartAPI['endpoint']
export const operations = { getCart, addItem }

View File

@ -109,15 +109,17 @@ export type Provider = typeof provider
export type EndpointsSchema = { cart: CartEndpointSchema }
export class CommerceAPI<
P extends Provider = Provider,
E extends EndpointsSchema = EndpointsSchema
> extends CoreCommerceAPI<P, E> {
P extends Provider = Provider
> extends CoreCommerceAPI<P> {
constructor(readonly provider: P = provider) {
super(provider)
}
}
export type CommerceAPIEndpoints = GetEndpointsSchema<CommerceAPI>
export type CommerceAPIEndpoints = GetEndpointsSchema<
CommerceAPI,
EndpointsSchema
>
export function getConfig(userConfig?: Partial<BigcommerceConfig>) {
return config.getConfig(userConfig)

View File

@ -1,9 +1,12 @@
import type { APIEndpoint } from '../utils/types'
import { CommerceAPIError } from '../utils/errors'
import isAllowedOperation from '../utils/is-allowed-operation'
import type { CommerceAPI, CartHandlers } from '..'
import type { GetAPISchema, CommerceAPI, CartSchema } from '..'
const cartApi: APIEndpoint<CommerceAPI, CartHandlers<any>> = async (ctx) => {
const cartApi: GetAPISchema<
CommerceAPI,
CartSchema
>['endpoint']['handler'] = async (ctx) => {
const { req, res, handlers, config } = ctx
if (

View File

@ -46,6 +46,36 @@ export type CartHandlers2<
removeItem: APIHandler<any, CartHandlersBase<C>, Cart, any>
}
export type CartSchema = {
endpoint: {
options: {}
operations: {
getCart: { data?: Cart | null; body?: any }
addItem: { data?: Cart; body?: any }
updateItem: { data?: Cart; body?: any }
removeItem: { data?: Cart; body?: any }
}
}
}
export type APISchemas = CartSchema
export type GetAPISchema<
C extends CommerceAPI,
S extends APISchemas = APISchemas
> = {
schema: S
endpoint: EndpointContext2<C, S['endpoint']>
}
export type EndpointContext2<
C extends CommerceAPI,
E extends EndpointSchemaBase
> = {
handler: Endpoint<C, E>
operations: EndpointHandlers<C, E>
}
export type EndpointsSchema = {
cart?: {
options: {}
@ -60,17 +90,16 @@ export type EndpointsSchema = {
export type GetEndpointsSchema<
C extends CommerceAPI,
Schema extends EndpointsSchema = C extends CommerceAPI<any, infer E>
? E
: never
Schema extends EndpointsSchema
> = {
[E in keyof EndpointsSchema]-?: Schema[E] & {
endpoint: Endpoint<C, NonNullable<Schema[E]>>
handlers: EndpointHandlers<C, NonNullable<Schema[E]>>
}
[E in keyof EndpointsSchema]-?: {
schema: Schema[E]
} & EndpointContext<C, NonNullable<Schema[E]>>
}
type X = Endpoint<CommerceAPI, NonNullable<EndpointsSchema['cart']>>
export type GetEndpointsFromSchema<T> = T[keyof T] extends { endpoint: infer E }
? E
: never
export type EndpointSchemaBase = {
options: {}
@ -111,10 +140,6 @@ export type EndpointHandlers<
>
}
export type CommerceEndpointsSchema<C> = C extends CommerceAPI<any, infer E>
? E
: never
export type HandlerOperations<E> = E extends APIEndpoint<any, any, infer T>
? T
: never
@ -127,10 +152,15 @@ export type APIProvider = {
config: CommerceAPIConfig
}
export class CommerceAPI<
P extends APIProvider = APIProvider,
E extends EndpointsSchema = EndpointsSchema
> {
export type EndpointContext<
C extends CommerceAPI,
E extends EndpointSchemaBase
> = {
endpoint: Endpoint<C, E>
operations: EndpointHandlers<C, E>
}
export class CommerceAPI<P extends APIProvider = APIProvider> {
constructor(readonly provider: P) {
this.provider = provider
}
@ -146,12 +176,12 @@ export class CommerceAPI<
Object.assign(this.provider.config, newConfig)
}
endpoint(context: {
handler: E
config?: P['config']
operations: HandlerOperations<typeof context.handler>
options?: HandlerOptions<typeof context.handler>
}): NextApiHandler {
endpoint<E extends GetAPISchema<this>>(
context: E['endpoint'] & {
config?: P['config']
options?: E['schema']['endpoint']['options']
}
): NextApiHandler {
const commerce = this
const cfg = this.getConfig(context.config)
@ -162,7 +192,7 @@ export class CommerceAPI<
commerce,
config: cfg,
handlers: context.operations,
options: context.options,
options: context.options ?? {},
})
}
}