mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
Add checkout endpoint parser & update errors
This commit is contained in:
parent
4bd20ddf0f
commit
fa9fe72a68
@ -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<any>(
|
||||
`/v3/carts/${cartId}/redirect_urls`,
|
||||
{
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export default function createEndpoints<P extends APIProvider>(
|
||||
|
||||
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,
|
||||
})
|
||||
|
@ -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 })),
|
||||
}
|
||||
}
|
||||
|
||||
|
15
packages/commerce/src/schemas/checkout.ts
Normal file
15
packages/commerce/src/schemas/checkout.ts
Normal file
@ -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,
|
||||
}),
|
||||
})
|
@ -69,7 +69,7 @@ export type CheckoutHooks = {
|
||||
}
|
||||
|
||||
export type GetCheckoutHandler = GetCheckoutHook & {
|
||||
body: { cartId: string }
|
||||
body: { cartId?: string }
|
||||
}
|
||||
|
||||
export type SubmitCheckoutHandler = SubmitCheckoutHook & {
|
||||
|
@ -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
|
@ -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<ShopifyAPI, ProductsSchema>
|
||||
|
||||
export type ProductsEndpoint = ProductsAPI['endpoint']
|
||||
|
||||
export const handlers: ProductsEndpoint['handlers'] = { getProducts }
|
||||
|
||||
const productsApi = createEndpoint<ProductsAPI>({
|
||||
handler: productsEndpoint,
|
||||
handlers,
|
||||
})
|
||||
|
||||
export default productsApi
|
@ -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"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user