Requested changes

This commit is contained in:
Catalin Pinte 2022-10-03 10:41:40 +03:00
parent e522ec1100
commit 2f0cb89bcb
7 changed files with 52 additions and 44 deletions

View File

@ -1,5 +1,5 @@
import type { ProductsSchema } from '../../../types/product'
import { getErrorMessage } from '../../utils/errors'
import { CommerceAPIError } from '../../utils/errors'
import isAllowedOperation from '../../utils/is-allowed-operation'
import type { GetAPISchema } from '../..'
@ -18,7 +18,12 @@ const productsEndpoint: GetAPISchema<
return await handlers['getProducts']({ ...ctx, body })
} catch (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 }] })
}
}

View File

@ -1,5 +1,5 @@
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 type { GetAPISchema } from '..'
@ -24,7 +24,10 @@ const loginEndpoint: GetAPISchema<
} catch (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 }] })
}

View File

@ -12,7 +12,7 @@ import type { CheckoutSchema } from '../types/checkout'
import type { CustomerCardSchema } from '../types/customer/card'
import type { CustomerAddressSchema } from '../types/customer/address'
import { withSchemaParser } from './utils/with-schema-parser'
import { withOperationCallback } from './utils/with-operation-callback'
import {
OPERATIONS,
@ -109,7 +109,7 @@ export function getCommerceApi<P extends APIProvider>(
OPERATIONS.forEach((k) => {
const op = ops[k]
if (op) {
commerce[k] = withSchemaParser(
commerce[k] = withOperationCallback(
k,
op({ commerce })
) as AllOperations<P>[typeof k]

View File

@ -25,6 +25,13 @@ export const OPERATIONS = [
'getProduct',
] as const
export type Operation = {
[O in AllowedOperations]: {
name: O
data: Awaited<ReturnType<Operations<APIProvider>[O]>>
}
}[AllowedOperations]
export const defaultOperations = OPERATIONS.reduce((ops, k) => {
ops[k] = noop
return ops
@ -32,15 +39,6 @@ export const defaultOperations = OPERATIONS.reduce((ops, k) => {
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> = {
login: {
<T extends LoginOperation>(opts: {

View File

@ -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) => {
if (error instanceof ZodError) {
return new CommerceError({

View File

@ -1,54 +1,42 @@
import type { AllowedOperations, OperationsData } from '../operations'
import type { AllowedOperations, Operation } from '../operations'
import { z } from 'zod'
import { getOperationError } from './errors'
import { pageSchema } from '../../schemas/page'
import { siteInfoSchema } from '../../schemas/site'
import { productSchema, productsPathsSchema } from '../../schemas/product'
export const withSchemaParser =
(
operation: AllowedOperations,
fn: (...args: any[]) => Promise<OperationsData>
) =>
export const withOperationCallback =
(name: AllowedOperations, fn: (...args: any[]) => Promise<any>) =>
async (...args: any[]) => {
try {
const result = await fn(...args)
parse(operation, result)
return result
const data = await fn(...args)
parse({ name, data })
return data
} catch (error) {
throw getOperationError(operation, error)
throw getOperationError(name, error)
}
}
const parse = (operation: AllowedOperations, data: OperationsData) => {
switch (operation) {
const parse = ({ name, data }: Operation) => {
switch (name) {
case 'getProduct':
productSchema.nullable().parse(data.product)
break
case 'getAllProducts':
z.array(productSchema).parse(data.products)
break
case 'getAllProductPaths':
productsPathsSchema.parse(data.products)
break
case 'getPage':
pageSchema.nullable().parse(data.page)
break
case 'getAllPages':
z.array(pageSchema).parse(data.pages)
break
case 'getSiteInfo':
siteInfoSchema.parse({
categories: data.categories,
brands: data.brands,
})
siteInfoSchema.parse(data)
break
}
}

View File

@ -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`
export interface ProductVariant {
@ -35,6 +35,26 @@ export interface ProductVariant {
* The image associated with the variant.
*/
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 {