From fed3c82c69e6e86b9d58b8c956baa90bca7f0dce Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Sat, 20 Mar 2021 16:52:32 -0600 Subject: [PATCH] Adding more experimental types --- framework/bigcommerce/api/cart/add-item.ts | 4 +- framework/bigcommerce/api/cart/get-cart.ts | 4 +- framework/bigcommerce/api/cart/index.ts | 30 +++++---- framework/bigcommerce/api/index.ts | 10 +-- framework/commerce/api/endpoints/cart.ts | 7 +- framework/commerce/api/index.ts | 76 +++++++++++++++------- 6 files changed, 84 insertions(+), 47 deletions(-) diff --git a/framework/bigcommerce/api/cart/add-item.ts b/framework/bigcommerce/api/cart/add-item.ts index 77c8a19ba..fd4387833 100644 --- a/framework/bigcommerce/api/cart/add-item.ts +++ b/framework/bigcommerce/api/cart/add-item.ts @@ -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, diff --git a/framework/bigcommerce/api/cart/get-cart.ts b/framework/bigcommerce/api/cart/get-cart.ts index 52a33b630..56fd23218 100644 --- a/framework/bigcommerce/api/cart/get-cart.ts +++ b/framework/bigcommerce/api/cart/get-cart.ts @@ -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, diff --git a/framework/bigcommerce/api/cart/index.ts b/framework/bigcommerce/api/cart/index.ts index 5d825d952..7c49434de 100644 --- a/framework/bigcommerce/api/cart/index.ts +++ b/framework/bigcommerce/api/cart/index.ts @@ -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 } diff --git a/framework/bigcommerce/api/index.ts b/framework/bigcommerce/api/index.ts index e9acbfffc..1411e7bce 100644 --- a/framework/bigcommerce/api/index.ts +++ b/framework/bigcommerce/api/index.ts @@ -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 extends Provider = Provider +> extends CoreCommerceAPI

{ constructor(readonly provider: P = provider) { super(provider) } } -export type CommerceAPIEndpoints = GetEndpointsSchema +export type CommerceAPIEndpoints = GetEndpointsSchema< + CommerceAPI, + EndpointsSchema +> export function getConfig(userConfig?: Partial) { return config.getConfig(userConfig) diff --git a/framework/commerce/api/endpoints/cart.ts b/framework/commerce/api/endpoints/cart.ts index 7bcb2c46f..770245a27 100644 --- a/framework/commerce/api/endpoints/cart.ts +++ b/framework/commerce/api/endpoints/cart.ts @@ -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> = async (ctx) => { +const cartApi: GetAPISchema< + CommerceAPI, + CartSchema +>['endpoint']['handler'] = async (ctx) => { const { req, res, handlers, config } = ctx if ( diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts index a1a3e4191..e170e06c4 100644 --- a/framework/commerce/api/index.ts +++ b/framework/commerce/api/index.ts @@ -46,6 +46,36 @@ export type CartHandlers2< removeItem: APIHandler, 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 +} + +export type EndpointContext2< + C extends CommerceAPI, + E extends EndpointSchemaBase +> = { + handler: Endpoint + operations: EndpointHandlers +} + export type EndpointsSchema = { cart?: { options: {} @@ -60,17 +90,16 @@ export type EndpointsSchema = { export type GetEndpointsSchema< C extends CommerceAPI, - Schema extends EndpointsSchema = C extends CommerceAPI - ? E - : never + Schema extends EndpointsSchema > = { - [E in keyof EndpointsSchema]-?: Schema[E] & { - endpoint: Endpoint> - handlers: EndpointHandlers> - } + [E in keyof EndpointsSchema]-?: { + schema: Schema[E] + } & EndpointContext> } -type X = Endpoint> +export type GetEndpointsFromSchema = T[keyof T] extends { endpoint: infer E } + ? E + : never export type EndpointSchemaBase = { options: {} @@ -111,10 +140,6 @@ export type EndpointHandlers< > } -export type CommerceEndpointsSchema = C extends CommerceAPI - ? E - : never - export type HandlerOperations = E extends APIEndpoint ? 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 + operations: EndpointHandlers +} + +export class CommerceAPI

{ 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 - options?: HandlerOptions - }): NextApiHandler { + endpoint>( + 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 ?? {}, }) } }