mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
Update api handlers
This commit is contained in:
parent
30a94cf857
commit
3a3883ada0
@ -17,7 +17,7 @@ const getCheckout: CheckoutEndpoint['handlers']['getCheckout'] = async ({
|
|||||||
res.redirect('/cart')
|
res.redirect('/cart')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { data } = await config.storeApiFetch(
|
const { data } = await config.storeApiFetch<any>(
|
||||||
`/v3/carts/${cartId}/redirect_urls`,
|
`/v3/carts/${cartId}/redirect_urls`,
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -42,7 +42,7 @@ const getCheckout: CheckoutEndpoint['handlers']['getCheckout'] = async ({
|
|||||||
store_hash: config.storeHash,
|
store_hash: config.storeHash,
|
||||||
customer_id: customerId,
|
customer_id: customerId,
|
||||||
channel_id: config.storeChannelId,
|
channel_id: config.storeChannelId,
|
||||||
redirect_to: data.checkout_url.replace(config.storeUrl, ""),
|
redirect_to: data.checkout_url.replace(config.storeUrl, ''),
|
||||||
}
|
}
|
||||||
let token = jwt.sign(payload, config.storeApiClientSecret!, {
|
let token = jwt.sign(payload, config.storeApiClientSecret!, {
|
||||||
algorithm: 'HS256',
|
algorithm: 'HS256',
|
||||||
|
@ -17,7 +17,6 @@ const productsEndpoint: GetAPISchema<
|
|||||||
categoryId: req.query.categoryId,
|
categoryId: req.query.categoryId,
|
||||||
brandId: req.query.brandId,
|
brandId: req.query.brandId,
|
||||||
sort: req.query.sort,
|
sort: req.query.sort,
|
||||||
locale: req.query.locale,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return handlers['getProducts']({ ...ctx, body })
|
return handlers['getProducts']({ ...ctx, body })
|
||||||
|
@ -17,7 +17,7 @@ const checkoutEndpoint: GetAPISchema<
|
|||||||
const { cookies } = req
|
const { cookies } = req
|
||||||
const cartId = cookies[config.cartCookie]
|
const cartId = cookies[config.cartCookie]
|
||||||
|
|
||||||
// Create checkout
|
// Get checkout
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
const body = { ...req.body, cartId }
|
const body = { ...req.body, cartId }
|
||||||
return handlers['getCheckout']({ ...ctx, body })
|
return handlers['getCheckout']({ ...ctx, body })
|
||||||
|
@ -2,6 +2,12 @@ import type { CustomerAddressSchema } from '../../../types/customer/address'
|
|||||||
import type { GetAPISchema } from '../..'
|
import type { GetAPISchema } from '../..'
|
||||||
|
|
||||||
import validateHandlers from '../../utils/validate-handlers'
|
import validateHandlers from '../../utils/validate-handlers'
|
||||||
|
import {
|
||||||
|
addAddressBodySchema,
|
||||||
|
deleteAddressBodySchema,
|
||||||
|
updateAddressBodySchema,
|
||||||
|
} from '../../../schemas/customer'
|
||||||
|
import { getCartBodySchema } from '../../../schemas/cart'
|
||||||
|
|
||||||
const customerShippingEndpoint: GetAPISchema<
|
const customerShippingEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
@ -15,6 +21,7 @@ const customerShippingEndpoint: GetAPISchema<
|
|||||||
PUT: handlers['updateItem'],
|
PUT: handlers['updateItem'],
|
||||||
DELETE: handlers['removeItem'],
|
DELETE: handlers['removeItem'],
|
||||||
})
|
})
|
||||||
|
|
||||||
const { cookies } = req
|
const { cookies } = req
|
||||||
|
|
||||||
// Cart id might be usefull for anonymous shopping
|
// Cart id might be usefull for anonymous shopping
|
||||||
@ -22,25 +29,25 @@ const customerShippingEndpoint: GetAPISchema<
|
|||||||
|
|
||||||
// Return customer addresses
|
// Return customer addresses
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
const body = { cartId }
|
const body = getCartBodySchema.parse({ cartId })
|
||||||
return handlers['getAddresses']({ ...ctx, body })
|
return handlers['getAddresses']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create or add an item to customer addresses list
|
// Create or add an item to customer addresses list
|
||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
const body = { ...req.body, cartId }
|
const body = addAddressBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['addItem']({ ...ctx, body })
|
return handlers['addItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update item in customer addresses list
|
// Update item in customer addresses list
|
||||||
if (req.method === 'PUT') {
|
if (req.method === 'PUT') {
|
||||||
const body = { ...req.body, cartId }
|
const body = updateAddressBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['updateItem']({ ...ctx, body })
|
return handlers['updateItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an item from customer addresses list
|
// Remove an item from customer addresses list
|
||||||
if (req.method === 'DELETE') {
|
if (req.method === 'DELETE') {
|
||||||
const body = { ...req.body, cartId }
|
const body = deleteAddressBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['removeItem']({ ...ctx, body })
|
return handlers['removeItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,12 @@ import type { GetAPISchema } from '../..'
|
|||||||
|
|
||||||
import validateHandlers from '../../utils/validate-handlers'
|
import validateHandlers from '../../utils/validate-handlers'
|
||||||
|
|
||||||
|
import {
|
||||||
|
addCardBodySchema,
|
||||||
|
deleteCardBodySchema,
|
||||||
|
updateCardBodySchema,
|
||||||
|
} from '../../../schemas/customer'
|
||||||
|
|
||||||
const customerCardEndpoint: GetAPISchema<
|
const customerCardEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
CustomerCardSchema
|
CustomerCardSchema
|
||||||
@ -28,19 +34,19 @@ const customerCardEndpoint: GetAPISchema<
|
|||||||
|
|
||||||
// Create or add an item to customer cards
|
// Create or add an item to customer cards
|
||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
const body = { ...req.body, cartId }
|
const body = addCardBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['addItem']({ ...ctx, body })
|
return handlers['addItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update item in customer cards
|
// Update item in customer cards
|
||||||
if (req.method === 'PUT') {
|
if (req.method === 'PUT') {
|
||||||
const body = { ...req.body, cartId }
|
const body = updateCardBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['updateItem']({ ...ctx, body })
|
return handlers['updateItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an item from customer cards
|
// Remove an item from customer cards
|
||||||
if (req.method === 'DELETE') {
|
if (req.method === 'DELETE') {
|
||||||
const body = { ...req.body, cartId }
|
const body = deleteCardBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['removeItem']({ ...ctx, body })
|
return handlers['removeItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
||||||
import type { APIProvider, CommerceAPI } from '..'
|
import type { APIProvider, CommerceAPI } from '..'
|
||||||
|
|
||||||
import { getErrorResponse } from '../utils/errors'
|
import { normalizeError } from '../utils/errors'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the catch-all api endpoint for the Commerce API.
|
* Handles the catch-all api endpoint for the Commerce API.
|
||||||
@ -62,7 +62,7 @@ export default function createEndpoints<P extends APIProvider>(
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
const { status, data, errors } = getErrorResponse(error)
|
const { status, data, errors } = normalizeError(error)
|
||||||
res.status(status).json({
|
res.status(status).json({
|
||||||
data,
|
data,
|
||||||
errors,
|
errors,
|
||||||
|
@ -2,6 +2,7 @@ import type { GetAPISchema } from '..'
|
|||||||
import type { LoginSchema } from '../../types/login'
|
import type { LoginSchema } from '../../types/login'
|
||||||
|
|
||||||
import validateHandlers from '../utils/validate-handlers'
|
import validateHandlers from '../utils/validate-handlers'
|
||||||
|
import { loginBodySchema } from '../../schemas/auth'
|
||||||
|
|
||||||
const loginEndpoint: GetAPISchema<any, LoginSchema>['endpoint']['handler'] = (
|
const loginEndpoint: GetAPISchema<any, LoginSchema>['endpoint']['handler'] = (
|
||||||
ctx
|
ctx
|
||||||
@ -13,7 +14,7 @@ const loginEndpoint: GetAPISchema<any, LoginSchema>['endpoint']['handler'] = (
|
|||||||
GET: handlers['login'],
|
GET: handlers['login'],
|
||||||
})
|
})
|
||||||
|
|
||||||
const body = req.body ?? {}
|
const body = loginBodySchema.parse(req.body)
|
||||||
return handlers['login']({ ...ctx, body })
|
return handlers['login']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { GetAPISchema } from '..'
|
import type { GetAPISchema } from '..'
|
||||||
import type { LogoutSchema } from '../../types/logout'
|
import type { LogoutSchema } from '../../types/logout'
|
||||||
|
|
||||||
|
import { logoutBodySchema } from '../../schemas/auth'
|
||||||
import validateHandlers from '../utils/validate-handlers'
|
import validateHandlers from '../utils/validate-handlers'
|
||||||
|
|
||||||
const logoutEndpoint: GetAPISchema<any, LogoutSchema>['endpoint']['handler'] = (
|
const logoutEndpoint: GetAPISchema<any, LogoutSchema>['endpoint']['handler'] = (
|
||||||
@ -11,8 +12,12 @@ const logoutEndpoint: GetAPISchema<any, LogoutSchema>['endpoint']['handler'] = (
|
|||||||
validateHandlers(req, res, {
|
validateHandlers(req, res, {
|
||||||
GET: handlers['logout'],
|
GET: handlers['logout'],
|
||||||
})
|
})
|
||||||
|
|
||||||
const redirectTo = req.query.redirect_to
|
const redirectTo = req.query.redirect_to
|
||||||
const body = typeof redirectTo === 'string' ? { redirectTo } : {}
|
|
||||||
|
const body = logoutBodySchema.parse(
|
||||||
|
typeof redirectTo === 'string' ? { redirectTo } : {}
|
||||||
|
)
|
||||||
|
|
||||||
return handlers['logout']({ ...ctx, body })
|
return handlers['logout']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import type { GetAPISchema } from '..'
|
import type { GetAPISchema } from '..'
|
||||||
import type { SignupSchema } from '../../types/signup'
|
import type { SignupSchema } from '../../types/signup'
|
||||||
|
|
||||||
|
import { signupBodySchema } from '../../schemas/auth'
|
||||||
|
|
||||||
import validateHandlers from '../utils/validate-handlers'
|
import validateHandlers from '../utils/validate-handlers'
|
||||||
|
|
||||||
const signupEndpoint: GetAPISchema<any, SignupSchema>['endpoint']['handler'] = (
|
const signupEndpoint: GetAPISchema<any, SignupSchema>['endpoint']['handler'] = (
|
||||||
@ -14,7 +16,7 @@ const signupEndpoint: GetAPISchema<any, SignupSchema>['endpoint']['handler'] = (
|
|||||||
const { cookies } = req
|
const { cookies } = req
|
||||||
const cartId = cookies[config.cartCookie]
|
const cartId = cookies[config.cartCookie]
|
||||||
|
|
||||||
const body = { ...req.body, cartId }
|
const body = signupBodySchema.parse({ ...req.body, cartId })
|
||||||
return handlers['signup']({ ...ctx, body })
|
return handlers['signup']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,12 @@ import type { WishlistSchema } from '../../types/wishlist'
|
|||||||
|
|
||||||
import validateHandlers from '../utils/validate-handlers'
|
import validateHandlers from '../utils/validate-handlers'
|
||||||
|
|
||||||
|
import {
|
||||||
|
getWishlistBodySchema,
|
||||||
|
addItemBodySchema,
|
||||||
|
removeItemBodySchema,
|
||||||
|
} from '../../schemas/whishlist'
|
||||||
|
|
||||||
const wishlistEndpoint: GetAPISchema<
|
const wishlistEndpoint: GetAPISchema<
|
||||||
any,
|
any,
|
||||||
WishlistSchema
|
WishlistSchema
|
||||||
@ -20,22 +26,22 @@ const wishlistEndpoint: GetAPISchema<
|
|||||||
|
|
||||||
// Return current wishlist info
|
// Return current wishlist info
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
const body = {
|
const body = getWishlistBodySchema.parse({
|
||||||
customerToken,
|
customerToken,
|
||||||
includeProducts: !!req.query.products,
|
includeProducts: !!req.query.products,
|
||||||
}
|
})
|
||||||
return handlers['getWishlist']({ ...ctx, body })
|
return handlers['getWishlist']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an item to the wishlist
|
// Add an item to the wishlist
|
||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
const body = { ...req.body, customerToken }
|
const body = addItemBodySchema.parse({ ...req.body, customerToken })
|
||||||
return handlers['addItem']({ ...ctx, body })
|
return handlers['addItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an item from the wishlist
|
// Remove an item from the wishlist
|
||||||
if (req.method === 'DELETE') {
|
if (req.method === 'DELETE') {
|
||||||
const body = { ...req.body, customerToken }
|
const body = removeItemBodySchema.parse({ ...req.body, customerToken })
|
||||||
return handlers['removeItem']({ ...ctx, body })
|
return handlers['removeItem']({ ...ctx, body })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { ZodError } from 'zod'
|
|
||||||
|
|
||||||
import type { Response } from '@vercel/fetch'
|
import type { Response } from '@vercel/fetch'
|
||||||
import { CommerceError } from '../../utils/errors'
|
import { ZodError } from 'zod'
|
||||||
|
|
||||||
export class CommerceAPIError extends Error {
|
export class CommerceAPIError extends Error {
|
||||||
status: number
|
status: number
|
||||||
@ -24,7 +22,14 @@ export class CommerceNetworkError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getErrorResponse = (error: unknown) => {
|
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}`,
|
||||||
|
}))
|
||||||
|
|
||||||
|
export const normalizeError = (error: unknown) => {
|
||||||
if (error instanceof CommerceAPIError) {
|
if (error instanceof CommerceAPIError) {
|
||||||
return {
|
return {
|
||||||
status: error.status || 500,
|
status: error.status || 500,
|
||||||
@ -39,7 +44,7 @@ export const getErrorResponse = (error: unknown) => {
|
|||||||
return {
|
return {
|
||||||
status: 400,
|
status: 400,
|
||||||
data: null,
|
data: null,
|
||||||
errors: error.issues,
|
errors: normalizeZodIssues(error.issues),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,25 +54,3 @@ export const getErrorResponse = (error: unknown) => {
|
|||||||
errors: [{ message: 'An unexpected error ocurred' }],
|
errors: [{ message: 'An unexpected error ocurred' }],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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` +
|
|
||||||
error.issues
|
|
||||||
.map(
|
|
||||||
(e, index) =>
|
|
||||||
`Error #${index + 1} ${
|
|
||||||
e.path.length > 0 ? `Path: ${e.path.join('.')}, ` : ''
|
|
||||||
}Code: ${e.code}, Message: ${e.message}`
|
|
||||||
)
|
|
||||||
.join('\n'),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,6 @@ import isAllowedMethod, { HTTP_METHODS } from './is-allowed-method'
|
|||||||
import { APIHandler } from './types'
|
import { APIHandler } from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the request method is allowed
|
|
||||||
* @throws Error if the method is not allowed
|
* @throws Error if the method is not allowed
|
||||||
*/
|
*/
|
||||||
export default function validateHandlers(
|
export default function validateHandlers(
|
||||||
|
18
packages/commerce/src/schemas/auth.ts
Normal file
18
packages/commerce/src/schemas/auth.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const loginBodySchema = z.object({
|
||||||
|
redirectTo: z.string().optional(),
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const logoutBodySchema = z.object({
|
||||||
|
redirectTo: z.string().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const signupBodySchema = z.object({
|
||||||
|
firstName: z.string(),
|
||||||
|
lastName: z.string(),
|
||||||
|
email: z.string(),
|
||||||
|
password: z.string(),
|
||||||
|
})
|
63
packages/commerce/src/schemas/customer.ts
Normal file
63
packages/commerce/src/schemas/customer.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const getCustomerAddressBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addressFieldsSchema = z.object({
|
||||||
|
type: z.string(),
|
||||||
|
firstName: z.string(),
|
||||||
|
lastName: z.string(),
|
||||||
|
company: z.string(),
|
||||||
|
streetNumber: z.string(),
|
||||||
|
apartments: z.string(),
|
||||||
|
zipCode: z.string(),
|
||||||
|
city: z.string(),
|
||||||
|
country: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addAddressBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
item: addressFieldsSchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateAddressBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
item: addressFieldsSchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteAddressBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const cardFieldsSchema = z.object({
|
||||||
|
cardHolder: z.string(),
|
||||||
|
cardNumber: z.string(),
|
||||||
|
cardExpireDate: z.string(),
|
||||||
|
cardCvc: z.string(),
|
||||||
|
firstName: z.string(),
|
||||||
|
lastName: z.string(),
|
||||||
|
company: z.string(),
|
||||||
|
streetNumber: z.string(),
|
||||||
|
zipCode: z.string(),
|
||||||
|
city: z.string(),
|
||||||
|
country: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addCardBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
item: cardFieldsSchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateCardBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
item: cardFieldsSchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteCardBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
})
|
27
packages/commerce/src/schemas/whishlist.ts
Normal file
27
packages/commerce/src/schemas/whishlist.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
export const getWishlistBodySchema = z.object({
|
||||||
|
customerAccessToken: z.string(),
|
||||||
|
includeProducts: z.boolean(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const wishlistItemBodySchema = z.object({
|
||||||
|
productId: z.string(),
|
||||||
|
variantId: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addItemBodySchema = z.object({
|
||||||
|
cartId: z.string().optional(),
|
||||||
|
item: wishlistItemBodySchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateItemBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
item: wishlistItemBodySchema,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const removeItemBodySchema = z.object({
|
||||||
|
cartId: z.string(),
|
||||||
|
itemId: z.string(),
|
||||||
|
})
|
@ -1,6 +1,6 @@
|
|||||||
import type { CommercejsAPI } from '..'
|
import type { CommercejsAPI } from '..'
|
||||||
|
|
||||||
import handleEndpoints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
|
||||||
import login from './login'
|
import login from './login'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
@ -10,7 +10,6 @@ const endpoints = {
|
|||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: CommercejsAPI) =>
|
export default function commercejsAPI(commerce: CommercejsAPI) {
|
||||||
handleEndpoints(commerce, endpoints)
|
return createEndpoints(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { KiboCommerceAPI } from '..'
|
import type { KiboCommerceAPI } from '..'
|
||||||
|
|
||||||
import handleEndpoints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
|
||||||
import cart from './cart'
|
import cart from './cart'
|
||||||
import login from './login'
|
import login from './login'
|
||||||
@ -20,7 +20,6 @@ const endpoints = {
|
|||||||
'catalog/products': products,
|
'catalog/products': products,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: KiboCommerceAPI) =>
|
export default function kiboCommerceAPI(commerce: KiboCommerceAPI) {
|
||||||
handleEndpoints(commerce, endpoints)
|
return createEndpoints(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
8
packages/local/src/api/endpoints.ts
Normal file
8
packages/local/src/api/endpoints.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
import type { LocalAPI } from '.'
|
||||||
|
|
||||||
|
const endpoints = {}
|
||||||
|
|
||||||
|
export default function localAPI(commerce: LocalAPI) {
|
||||||
|
return createEndpoints(commerce, endpoints)
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import type { OrdercloudAPI } from '..'
|
import type { OrdercloudAPI } from '..'
|
||||||
|
|
||||||
import handleEndpoints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
|
||||||
import cart from './cart'
|
import cart from './cart'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
@ -16,7 +16,6 @@ const endpoints = {
|
|||||||
'catalog/products': products,
|
'catalog/products': products,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: OrdercloudAPI) =>
|
export default function ordercloudAPI(commerce: OrdercloudAPI) {
|
||||||
handleEndpoints(commerce, endpoints)
|
return createEndpoints(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import vercelFetch from '@vercel/fetch'
|
import vercelFetch from '@vercel/fetch'
|
||||||
import { FetcherError } from '@vercel/commerce/utils/errors'
|
import { FetcherError } from '@vercel/commerce/utils/errors'
|
||||||
import { CustomNodeJsGlobal } from '../../types/node';
|
import { CustomNodeJsGlobal } from '../../types/node'
|
||||||
|
|
||||||
import { OrdercloudConfig } from '../index'
|
import { OrdercloudConfig } from '../index'
|
||||||
|
|
||||||
@ -32,6 +32,8 @@ async function getToken({
|
|||||||
// Get the body of it
|
// Get the body of it
|
||||||
const error = await authResponse.json()
|
const error = await authResponse.json()
|
||||||
|
|
||||||
|
console.log(JSON.stringify(error, null, 2))
|
||||||
|
|
||||||
// And return an error
|
// And return an error
|
||||||
throw new FetcherError({
|
throw new FetcherError({
|
||||||
errors: [{ message: error.error_description.Code }],
|
errors: [{ message: error.error_description.Code }],
|
||||||
@ -144,12 +146,11 @@ export const createBuyerFetcher: (
|
|||||||
body?: Record<string, unknown>,
|
body?: Record<string, unknown>,
|
||||||
fetchOptions?: Record<string, any>
|
fetchOptions?: Record<string, any>
|
||||||
) => {
|
) => {
|
||||||
const customGlobal = global as unknown as CustomNodeJsGlobal;
|
const customGlobal = global as unknown as CustomNodeJsGlobal
|
||||||
|
|
||||||
// Get provider config
|
// Get provider config
|
||||||
const config = getConfig()
|
const config = getConfig()
|
||||||
|
|
||||||
|
|
||||||
// If a token was passed, set it on global
|
// If a token was passed, set it on global
|
||||||
if (fetchOptions?.token) {
|
if (fetchOptions?.token) {
|
||||||
customGlobal.token = fetchOptions.token
|
customGlobal.token = fetchOptions.token
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import type { Provider, SaleorAPI } from '..'
|
import type { Provider, SaleorAPI } from '..'
|
||||||
|
|
||||||
import handleEndpoints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: SaleorAPI) =>
|
export default function saleorAPI(commerce: SaleorAPI) {
|
||||||
handleEndpoints<Provider>(commerce, endpoints)
|
return createEndpoints<Provider>(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Provider, SFCCProviderAPI } from '..'
|
import type { Provider, SFCCProviderAPI } from '..'
|
||||||
|
|
||||||
import handleEndpoints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
|
|
||||||
import products from './catalog/products'
|
import products from './catalog/products'
|
||||||
|
|
||||||
@ -8,7 +8,6 @@ const endpoints = {
|
|||||||
'catalog/products': products,
|
'catalog/products': products,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: SFCCProviderAPI) =>
|
export default function sfccApi(commerce: SFCCProviderAPI) {
|
||||||
handleEndpoints(commerce, endpoints)
|
return createEndpoints(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import type { Provider, ShopifyAPI } from '..'
|
import type { Provider, ShopifyAPI } from '..'
|
||||||
import handleEndopints from '@vercel/commerce/api/endpoints'
|
|
||||||
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: ShopifyAPI) =>
|
export default function shopifyAPI(commerce: ShopifyAPI) {
|
||||||
handleEndopints<Provider>(commerce, endpoints)
|
return createEndpoints<Provider>(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import type { SpreeApiProvider, SpreeApi } from '..'
|
import type { SpreeApiProvider, SpreeApi } from '..'
|
||||||
import handleEndopints from '@vercel/commerce/api/endpoints'
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: SpreeApi) =>
|
export default function spreeAPI(commerce: SpreeApi) {
|
||||||
handleEndopints<SpreeApiProvider>(commerce, endpoints)
|
return createEndpoints<SpreeApiProvider>(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import type { Provider, SwellAPI } from '..'
|
import type { Provider, SwellAPI } from '..'
|
||||||
import handleEndopints from '@vercel/commerce/api/endpoints'
|
|
||||||
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: SwellAPI) =>
|
export default function handler(commerce: SwellAPI) {
|
||||||
handleEndopints<Provider>(commerce, endpoints)
|
return createEndpoints<Provider>(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import type { Provider, VendureAPI } from '..'
|
import type { Provider, VendureAPI } from '..'
|
||||||
import handleEndopints from '@vercel/commerce/api/endpoints'
|
|
||||||
|
import createEndpoints from '@vercel/commerce/api/endpoints'
|
||||||
import checkout from './checkout'
|
import checkout from './checkout'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
checkout,
|
checkout,
|
||||||
}
|
}
|
||||||
|
|
||||||
const handler = (commerce: VendureAPI) =>
|
export default function vendureAPI(commerce: VendureAPI) {
|
||||||
handleEndopints<Provider>(commerce, endpoints)
|
return createEndpoints<Provider>(commerce, endpoints)
|
||||||
|
}
|
||||||
export default handler
|
|
@ -27,6 +27,7 @@ import {
|
|||||||
getDesignerPath,
|
getDesignerPath,
|
||||||
useSearchMeta,
|
useSearchMeta,
|
||||||
} from '@lib/search'
|
} from '@lib/search'
|
||||||
|
import ErrorMessage from './ui/ErrorMessage'
|
||||||
|
|
||||||
export default function Search({ categories, brands }: SearchPropsType) {
|
export default function Search({ categories, brands }: SearchPropsType) {
|
||||||
const [activeFilter, setActiveFilter] = useState('')
|
const [activeFilter, setActiveFilter] = useState('')
|
||||||
@ -46,7 +47,7 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
|||||||
(b: any) => getSlug(b.node.path) === `brands/${brand}`
|
(b: any) => getSlug(b.node.path) === `brands/${brand}`
|
||||||
)?.node
|
)?.node
|
||||||
|
|
||||||
const { data } = useSearch({
|
const { data, error } = useSearch({
|
||||||
search: typeof q === 'string' ? q : '',
|
search: typeof q === 'string' ? q : '',
|
||||||
categoryId: activeCategory?.id,
|
categoryId: activeCategory?.id,
|
||||||
brandId: (activeBrand as any)?.entityId,
|
brandId: (activeBrand as any)?.entityId,
|
||||||
@ -54,6 +55,10 @@ export default function Search({ categories, brands }: SearchPropsType) {
|
|||||||
locale,
|
locale,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <ErrorMessage error={error} />
|
||||||
|
}
|
||||||
|
|
||||||
const handleClick = (event: any, filter: string) => {
|
const handleClick = (event: any, filter: string) => {
|
||||||
if (filter !== activeFilter) {
|
if (filter !== activeFilter) {
|
||||||
setToggleFilter(true)
|
setToggleFilter(true)
|
||||||
|
28
site/components/ui/ErrorMessage/ErrorMessage.tsx
Normal file
28
site/components/ui/ErrorMessage/ErrorMessage.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import type { FC } from 'react'
|
||||||
|
|
||||||
|
interface ErrorMessageProps {
|
||||||
|
error: {
|
||||||
|
message: string
|
||||||
|
code?: string
|
||||||
|
errors?: {
|
||||||
|
message: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ErrorMessages: FC<ErrorMessageProps> = ({ error }) => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col text-red p-5 m-5 border border-solid border-red">
|
||||||
|
<span>{error.message}</span>
|
||||||
|
{error.errors && error.errors?.length > 0 && (
|
||||||
|
<ul>
|
||||||
|
{error.errors.map(({ message }, index) => (
|
||||||
|
<li key={index}>{message}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ErrorMessages
|
1
site/components/ui/ErrorMessage/index.ts
Normal file
1
site/components/ui/ErrorMessage/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './ErrorMessage'
|
@ -18,7 +18,7 @@ module.exports = withCommerceConfig({
|
|||||||
return [
|
return [
|
||||||
(isBC || isShopify || isSwell || isVendure || isSaleor) && {
|
(isBC || isShopify || isSwell || isVendure || isSaleor) && {
|
||||||
source: '/checkout',
|
source: '/checkout',
|
||||||
destination: '/api/checkout',
|
destination: '/api/commerce/checkout',
|
||||||
},
|
},
|
||||||
// The logout is also an action so this route is not required, but it's also another way
|
// The logout is also an action so this route is not required, but it's also another way
|
||||||
// you can allow a logout!
|
// you can allow a logout!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user