diff --git a/packages/bigcommerce/src/api/endpoints/checkout/get-checkout.ts b/packages/bigcommerce/src/api/endpoints/checkout/get-checkout.ts index f81899750..7de5369b7 100644 --- a/packages/bigcommerce/src/api/endpoints/checkout/get-checkout.ts +++ b/packages/bigcommerce/src/api/endpoints/checkout/get-checkout.ts @@ -13,10 +13,12 @@ const getCheckout: CheckoutEndpoint['handlers']['getCheckout'] = async ({ const { cookies } = req const cartId = cookies[config.cartCookie] const customerToken = cookies[config.customerCookie] + if (!cartId) { res.redirect('/cart') return } + const { data } = await config.storeApiFetch( `/v3/carts/${cartId}/redirect_urls`, { diff --git a/packages/commerce/src/api/endpoints/checkout.ts b/packages/commerce/src/api/endpoints/checkout.ts index 5f9257387..d972dfaa8 100644 --- a/packages/commerce/src/api/endpoints/checkout.ts +++ b/packages/commerce/src/api/endpoints/checkout.ts @@ -1,6 +1,11 @@ import type { GetAPISchema } from '..' import type { CheckoutSchema } from '../../types/checkout' +import { + getCheckoutBodySchema, + submitCheckoutBodySchema, +} from '../../schemas/checkout' + import validateHandlers from '../utils/validate-handlers' const checkoutEndpoint: GetAPISchema< @@ -19,13 +24,13 @@ const checkoutEndpoint: GetAPISchema< // Get checkout if (req.method === 'GET') { - const body = { ...req.body, cartId } + const body = getCheckoutBodySchema.parse({ ...req.body, cartId }) return handlers['getCheckout']({ ...ctx, body }) } // Create checkout if (req.method === 'POST' && handlers['submitCheckout']) { - const body = { ...req.body, cartId } + const body = submitCheckoutBodySchema.parse({ ...req.body, cartId }) return handlers['submitCheckout']({ ...ctx, body }) } } diff --git a/packages/commerce/src/api/endpoints/index.ts b/packages/commerce/src/api/endpoints/index.ts index 466a79593..cd3fea8f6 100644 --- a/packages/commerce/src/api/endpoints/index.ts +++ b/packages/commerce/src/api/endpoints/index.ts @@ -51,7 +51,7 @@ export default function createEndpoints

( const data = await handlers[path](req, res) // If the handler returns a value but the response hasn't been sent yet, send it - if (!res.headersSent) { + if (!res.headersSent && data) { res.status(200).json({ data, }) diff --git a/packages/commerce/src/api/utils/errors.ts b/packages/commerce/src/api/utils/errors.ts index 42c189320..e4c72feb0 100644 --- a/packages/commerce/src/api/utils/errors.ts +++ b/packages/commerce/src/api/utils/errors.ts @@ -25,26 +25,19 @@ export class CommerceNetworkError extends Error { } export const normalizeZodIssues = (issues: ZodError['issues']) => - issues.map((e, index) => ({ - message: `Error #${index + 1} ${ - e.path.length > 0 ? `Path: ${e.path.join('.')}, ` : '' - }Code: ${e.code}, Message: ${e.message}`, - })) + issues.map(({ path, message }) => `${message} at "${path.join('.')}"`) export const getOperationError = (operation: string, error: unknown) => { if (error instanceof ZodError) { return new CommerceError({ code: 'SCHEMA_VALIDATION_ERROR', message: - `The ${operation} operation returned invalid data and has ${ - error.issues.length - } parse ${error.issues.length === 1 ? 'error' : 'errors'}: \n` + - normalizeZodIssues(error.issues) - .map((e) => e.message) - .join('\n'), + `Validation ${ + error.issues.length === 1 ? 'error' : 'errors' + } at "${operation}" operation: \n` + + normalizeZodIssues(error.issues).join('\n'), }) } - return error } @@ -63,7 +56,7 @@ export const normalizeError = (error: unknown) => { return { status: 400, data: null, - errors: normalizeZodIssues(error.issues), + errors: normalizeZodIssues(error.issues).map((message) => ({ message })), } } diff --git a/packages/commerce/src/schemas/checkout.ts b/packages/commerce/src/schemas/checkout.ts new file mode 100644 index 000000000..bd1341f45 --- /dev/null +++ b/packages/commerce/src/schemas/checkout.ts @@ -0,0 +1,15 @@ +import { z } from 'zod' +import { addressFieldsSchema, cardFieldsSchema } from './customer' + +export const getCheckoutBodySchema = z.object({ + cartId: z.string().optional(), +}) + +export const submitCheckoutBodySchema = z.object({ + cartId: z.string(), + item: z.object({ + cartId: z.string().optional(), + card: cardFieldsSchema, + address: addressFieldsSchema, + }), +}) diff --git a/packages/commerce/src/types/checkout.ts b/packages/commerce/src/types/checkout.ts index 8b5d428fc..a892fcc68 100644 --- a/packages/commerce/src/types/checkout.ts +++ b/packages/commerce/src/types/checkout.ts @@ -69,7 +69,7 @@ export type CheckoutHooks = { } export type GetCheckoutHandler = GetCheckoutHook & { - body: { cartId: string } + body: { cartId?: string } } export type SubmitCheckoutHandler = SubmitCheckoutHook & { diff --git a/packages/shopify/src/api/endpoints/catalog/products/get-products.ts b/packages/shopify/src/api/endpoints/catalog/products/get-products.ts deleted file mode 100644 index 1e8829e78..000000000 --- a/packages/shopify/src/api/endpoints/catalog/products/get-products.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ProductsEndpoint } from '.' - -const SORT: { [key: string]: string | undefined } = { - latest: 'id', - trending: 'total_sold', - price: 'price', -} - -const LIMIT = 12 - -// Return current cart info -const getProducts: ProductsEndpoint['handlers']['getProducts'] = async ({ - res, - body: { search, categoryId, brandId, sort }, - config, - commerce, -}) => { - res.status(200).json({ - data: { - products: [], - found: false, - }, - }) -} - -export default getProducts diff --git a/packages/shopify/src/api/endpoints/catalog/products/index.ts b/packages/shopify/src/api/endpoints/catalog/products/index.ts deleted file mode 100644 index df680453a..000000000 --- a/packages/shopify/src/api/endpoints/catalog/products/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { GetAPISchema, createEndpoint } from '@vercel/commerce/api' -import productsEndpoint from '@vercel/commerce/api/endpoints/catalog/products' -import type { ProductsSchema } from '@vercel/commerce/types/product' -import type { ShopifyAPI } from '../../..' - -import getProducts from './get-products' - -export type ProductsAPI = GetAPISchema - -export type ProductsEndpoint = ProductsAPI['endpoint'] - -export const handlers: ProductsEndpoint['handlers'] = { getProducts } - -const productsApi = createEndpoint({ - handler: productsEndpoint, - handlers, -}) - -export default productsApi diff --git a/site/tsconfig.json b/site/tsconfig.json index 7c91afd6f..2de809a44 100644 --- a/site/tsconfig.json +++ b/site/tsconfig.json @@ -23,8 +23,8 @@ "@components/*": ["components/*"], "@commerce": ["../packages/commerce/src"], "@commerce/*": ["../packages/commerce/src/*"], - "@framework": ["../packages/local/src"], - "@framework/*": ["../packages/local/src/*"] + "@framework": ["../packages/shopify/src"], + "@framework/*": ["../packages/shopify/src/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],