mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 15:06:59 +00:00
Requested changes
This commit is contained in:
parent
e522ec1100
commit
2f0cb89bcb
@ -1,5 +1,5 @@
|
|||||||
import type { ProductsSchema } from '../../../types/product'
|
import type { ProductsSchema } from '../../../types/product'
|
||||||
import { getErrorMessage } from '../../utils/errors'
|
import { CommerceAPIError } from '../../utils/errors'
|
||||||
import isAllowedOperation from '../../utils/is-allowed-operation'
|
import isAllowedOperation from '../../utils/is-allowed-operation'
|
||||||
import type { GetAPISchema } from '../..'
|
import type { GetAPISchema } from '../..'
|
||||||
|
|
||||||
@ -18,7 +18,12 @@ const productsEndpoint: GetAPISchema<
|
|||||||
return await handlers['getProducts']({ ...ctx, body })
|
return await handlers['getProducts']({ ...ctx, body })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
const message = getErrorMessage(error)
|
|
||||||
|
const message =
|
||||||
|
error instanceof CommerceAPIError
|
||||||
|
? 'An unexpected error ocurred with the Commerce API'
|
||||||
|
: 'An unexpected error ocurred'
|
||||||
|
|
||||||
res.status(500).json({ data: null, errors: [{ message }] })
|
res.status(500).json({ data: null, errors: [{ message }] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { LoginSchema } from '../../types/login'
|
import type { LoginSchema } from '../../types/login'
|
||||||
import { CommerceAPIError, getErrorMessage } from '../utils/errors'
|
import { CommerceAPIError } from '../utils/errors'
|
||||||
import isAllowedOperation from '../utils/is-allowed-operation'
|
import isAllowedOperation from '../utils/is-allowed-operation'
|
||||||
import type { GetAPISchema } from '..'
|
import type { GetAPISchema } from '..'
|
||||||
|
|
||||||
@ -24,7 +24,10 @@ const loginEndpoint: GetAPISchema<
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
||||||
const message = getErrorMessage(error)
|
const message =
|
||||||
|
error instanceof CommerceAPIError
|
||||||
|
? 'An unexpected error ocurred with the Commerce API'
|
||||||
|
: 'An unexpected error ocurred'
|
||||||
|
|
||||||
res.status(500).json({ data: null, errors: [{ message }] })
|
res.status(500).json({ data: null, errors: [{ message }] })
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import type { CheckoutSchema } from '../types/checkout'
|
|||||||
import type { CustomerCardSchema } from '../types/customer/card'
|
import type { CustomerCardSchema } from '../types/customer/card'
|
||||||
import type { CustomerAddressSchema } from '../types/customer/address'
|
import type { CustomerAddressSchema } from '../types/customer/address'
|
||||||
|
|
||||||
import { withSchemaParser } from './utils/with-schema-parser'
|
import { withOperationCallback } from './utils/with-operation-callback'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
OPERATIONS,
|
OPERATIONS,
|
||||||
@ -109,7 +109,7 @@ export function getCommerceApi<P extends APIProvider>(
|
|||||||
OPERATIONS.forEach((k) => {
|
OPERATIONS.forEach((k) => {
|
||||||
const op = ops[k]
|
const op = ops[k]
|
||||||
if (op) {
|
if (op) {
|
||||||
commerce[k] = withSchemaParser(
|
commerce[k] = withOperationCallback(
|
||||||
k,
|
k,
|
||||||
op({ commerce })
|
op({ commerce })
|
||||||
) as AllOperations<P>[typeof k]
|
) as AllOperations<P>[typeof k]
|
||||||
|
@ -25,6 +25,13 @@ export const OPERATIONS = [
|
|||||||
'getProduct',
|
'getProduct',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
|
export type Operation = {
|
||||||
|
[O in AllowedOperations]: {
|
||||||
|
name: O
|
||||||
|
data: Awaited<ReturnType<Operations<APIProvider>[O]>>
|
||||||
|
}
|
||||||
|
}[AllowedOperations]
|
||||||
|
|
||||||
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
||||||
ops[k] = noop
|
ops[k] = noop
|
||||||
return ops
|
return ops
|
||||||
@ -32,15 +39,6 @@ export const defaultOperations = OPERATIONS.reduce((ops, k) => {
|
|||||||
|
|
||||||
export type AllowedOperations = typeof OPERATIONS[number]
|
export type AllowedOperations = typeof OPERATIONS[number]
|
||||||
|
|
||||||
export type OperationsData = GetProductOperation['data'] &
|
|
||||||
GetAllProductsOperation['data'] &
|
|
||||||
GetAllProductPathsOperation['data'] &
|
|
||||||
GetCustomerWishlistOperation['data'] &
|
|
||||||
GetSiteInfoOperation['data'] &
|
|
||||||
GetPageOperation['data'] &
|
|
||||||
GetAllPagesOperation['data'] &
|
|
||||||
LoginOperation['data']
|
|
||||||
|
|
||||||
export type Operations<P extends APIProvider> = {
|
export type Operations<P extends APIProvider> = {
|
||||||
login: {
|
login: {
|
||||||
<T extends LoginOperation>(opts: {
|
<T extends LoginOperation>(opts: {
|
||||||
|
@ -24,12 +24,6 @@ export class CommerceNetworkError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getErrorMessage = (error: unknown) => {
|
|
||||||
return error instanceof CommerceAPIError
|
|
||||||
? 'An unexpected error ocurred with the Commerce API'
|
|
||||||
: 'An unexpected error ocurred'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getOperationError = (operation: string, error: unknown) => {
|
export const getOperationError = (operation: string, error: unknown) => {
|
||||||
if (error instanceof ZodError) {
|
if (error instanceof ZodError) {
|
||||||
return new CommerceError({
|
return new CommerceError({
|
||||||
|
@ -1,54 +1,42 @@
|
|||||||
import type { AllowedOperations, OperationsData } from '../operations'
|
import type { AllowedOperations, Operation } from '../operations'
|
||||||
|
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
import { getOperationError } from './errors'
|
import { getOperationError } from './errors'
|
||||||
import { pageSchema } from '../../schemas/page'
|
import { pageSchema } from '../../schemas/page'
|
||||||
import { siteInfoSchema } from '../../schemas/site'
|
import { siteInfoSchema } from '../../schemas/site'
|
||||||
import { productSchema, productsPathsSchema } from '../../schemas/product'
|
import { productSchema, productsPathsSchema } from '../../schemas/product'
|
||||||
|
|
||||||
export const withSchemaParser =
|
export const withOperationCallback =
|
||||||
(
|
(name: AllowedOperations, fn: (...args: any[]) => Promise<any>) =>
|
||||||
operation: AllowedOperations,
|
|
||||||
fn: (...args: any[]) => Promise<OperationsData>
|
|
||||||
) =>
|
|
||||||
async (...args: any[]) => {
|
async (...args: any[]) => {
|
||||||
try {
|
try {
|
||||||
const result = await fn(...args)
|
const data = await fn(...args)
|
||||||
parse(operation, result)
|
parse({ name, data })
|
||||||
return result
|
return data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw getOperationError(operation, error)
|
throw getOperationError(name, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parse = (operation: AllowedOperations, data: OperationsData) => {
|
const parse = ({ name, data }: Operation) => {
|
||||||
switch (operation) {
|
switch (name) {
|
||||||
case 'getProduct':
|
case 'getProduct':
|
||||||
productSchema.nullable().parse(data.product)
|
productSchema.nullable().parse(data.product)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'getAllProducts':
|
case 'getAllProducts':
|
||||||
z.array(productSchema).parse(data.products)
|
z.array(productSchema).parse(data.products)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'getAllProductPaths':
|
case 'getAllProductPaths':
|
||||||
productsPathsSchema.parse(data.products)
|
productsPathsSchema.parse(data.products)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'getPage':
|
case 'getPage':
|
||||||
pageSchema.nullable().parse(data.page)
|
pageSchema.nullable().parse(data.page)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'getAllPages':
|
case 'getAllPages':
|
||||||
z.array(pageSchema).parse(data.pages)
|
z.array(pageSchema).parse(data.pages)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'getSiteInfo':
|
case 'getSiteInfo':
|
||||||
siteInfoSchema.parse({
|
siteInfoSchema.parse(data)
|
||||||
categories: data.categories,
|
|
||||||
brands: data.brands,
|
|
||||||
})
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import type { Discount, Image } from './common'
|
import type { Discount, Image, Measurement } from './common'
|
||||||
|
|
||||||
// TODO: This should use the same type as the `ProductVariant` type from `product.ts`
|
// TODO: This should use the same type as the `ProductVariant` type from `product.ts`
|
||||||
export interface ProductVariant {
|
export interface ProductVariant {
|
||||||
@ -35,6 +35,26 @@ export interface ProductVariant {
|
|||||||
* The image associated with the variant.
|
* The image associated with the variant.
|
||||||
*/
|
*/
|
||||||
image?: Image
|
image?: Image
|
||||||
|
/**
|
||||||
|
* The variant's weight. If a weight was not explicitly specified on the
|
||||||
|
* variant, this will be the product's weight.
|
||||||
|
*/
|
||||||
|
weight?: Measurement
|
||||||
|
/**
|
||||||
|
* The variant's height. If a height was not explicitly specified on the
|
||||||
|
* variant, this will be the product's height.
|
||||||
|
*/
|
||||||
|
height?: Measurement
|
||||||
|
/**
|
||||||
|
* The variant's width. If a width was not explicitly specified on the
|
||||||
|
* variant, this will be the product's width.
|
||||||
|
*/
|
||||||
|
width?: Measurement
|
||||||
|
/**
|
||||||
|
* The variant's depth. If a depth was not explicitly specified on the
|
||||||
|
* variant, this will be the product's depth.
|
||||||
|
*/
|
||||||
|
depth?: Measurement
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelectedOption {
|
export interface SelectedOption {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user