diff --git a/packages/commerce/src/api/utils/edge-handler.ts b/packages/commerce/src/api/utils/edge-handler.ts index 165d0bbcc..c438bd9fc 100644 --- a/packages/commerce/src/api/utils/edge-handler.ts +++ b/packages/commerce/src/api/utils/edge-handler.ts @@ -2,8 +2,9 @@ import type { APIProvider, CommerceAPI, EndpointHandler } from '..' import type { NextRequest } from 'next/server' import { normalizeApiError } from './errors' +import { transformHeaders } from '.' -export default function edgeApi

( +export default function edgeHandler

( commerce: CommerceAPI

, endpoints: Record) => EndpointHandler> ) { @@ -49,16 +50,14 @@ export default function edgeApi

( return output } - const { headers } = output + const headers = transformHeaders(output.headers) // If the output contains a redirectTo property, return a Response with the redirect if (output.redirectTo) { + headers.append('Location', output.redirectTo) return new Response(null, { status: 302, - headers: { - ...headers, - Location: output.redirectTo, - }, + headers, }) } diff --git a/packages/commerce/src/api/utils/index.ts b/packages/commerce/src/api/utils/index.ts index 5f316c2b6..219968578 100644 --- a/packages/commerce/src/api/utils/index.ts +++ b/packages/commerce/src/api/utils/index.ts @@ -50,3 +50,17 @@ export const transformRequest = (req: NextApiRequest, path: string) => { body, }) } + +export const transformHeaders = ( + headers?: Record +) => + headers + ? Object.entries(headers).reduce((acc, [key, value]) => { + if (Array.isArray(value)) { + value.forEach((v) => acc.append(key, v)) + } else { + acc.append(key, `${value}`) + } + return acc + }, new Headers()) + : new Headers() diff --git a/packages/commerce/src/api/utils/node-handler.ts b/packages/commerce/src/api/utils/node-handler.ts index ca48e1691..2b0f1ac71 100644 --- a/packages/commerce/src/api/utils/node-handler.ts +++ b/packages/commerce/src/api/utils/node-handler.ts @@ -4,7 +4,7 @@ import type { APIProvider, CommerceAPI, EndpointHandler } from '..' import { normalizeApiError } from './errors' import { transformRequest } from '.' -export default function nodeApi

( +export default function nodeHandler

( commerce: CommerceAPI

, endpoints: { [key: string]: (commerce: CommerceAPI

) => EndpointHandler @@ -44,8 +44,7 @@ export default function nodeApi

( ) } - const newReq = transformRequest(req, path) - const output = await handlers[path](newReq) + const output = await handlers[path](transformRequest(req, path)) if (output instanceof Response) { return res.end(output.body) @@ -54,9 +53,9 @@ export default function nodeApi

( const { status, errors, data, redirectTo, headers } = output if (headers) { - for (const [key, value] of Object.entries(headers)) { + Object.entries(headers).forEach(([key, value]) => { res.setHeader(key, value) - } + }) } if (redirectTo) { diff --git a/packages/commerce/src/api/utils/types.ts b/packages/commerce/src/api/utils/types.ts index b9946f4ae..f4401de6d 100644 --- a/packages/commerce/src/api/utils/types.ts +++ b/packages/commerce/src/api/utils/types.ts @@ -7,7 +7,7 @@ export type APIResponse = { data?: Data errors?: ErrorData[] status?: number - headers?: HeadersInit + headers?: Record /** * @type {string} * @example redirectTo: '/cart' diff --git a/packages/ordercloud/src/api/endpoints/cart/add-item.ts b/packages/ordercloud/src/api/endpoints/cart/add-item.ts index eacc26c9f..bed470602 100644 --- a/packages/ordercloud/src/api/endpoints/cart/add-item.ts +++ b/packages/ordercloud/src/api/endpoints/cart/add-item.ts @@ -11,7 +11,7 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({ }) => { // Get token let token = req.cookies.get(tokenCookie) - let headers = new Headers() + let headers: any = {} // Create an order if it doesn't exist if (!cartId) { @@ -24,27 +24,29 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({ cartId = ID - headers.append( - 'set-cookie', - serialize(cartCookie, cartId!, { - maxAge: 60 * 60 * 24 * 30, - expires: new Date(Date.now() + 60 * 60 * 24 * 30 * 1000), - secure: process.env.NODE_ENV === 'production', - path: '/', - sameSite: 'lax', - }) - ) + headers = { + 'set-cookie': [ + serialize(cartCookie, cartId!, { + maxAge: 60 * 60 * 24 * 30, + expires: new Date(Date.now() + 60 * 60 * 24 * 30 * 1000), + secure: process.env.NODE_ENV === 'production', + path: '/', + sameSite: 'lax', + }), + ], + } - headers.append( - 'set-cookie', - serialize(tokenCookie, meta.token.access_token, { - maxAge: meta.token.expires_in, - expires: new Date(Date.now() + meta.token.expires_in * 1000), - secure: process.env.NODE_ENV === 'production', - path: '/', - sameSite: 'lax', - }) - ) + if (meta?.token) { + headers['set-cookie'].push( + serialize(tokenCookie, meta.token?.access_token, { + maxAge: meta.token.expires_in, + expires: new Date(Date.now() + meta.token.expires_in * 1000), + secure: process.env.NODE_ENV === 'production', + path: '/', + sameSite: 'lax', + }) + ) + } } let specs: RawVariantSpec[] = [] diff --git a/packages/ordercloud/src/api/endpoints/cart/get-cart.ts b/packages/ordercloud/src/api/endpoints/cart/get-cart.ts index d7266f576..7cb23cb26 100644 --- a/packages/ordercloud/src/api/endpoints/cart/get-cart.ts +++ b/packages/ordercloud/src/api/endpoints/cart/get-cart.ts @@ -19,7 +19,7 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({ const token = req.cookies.get(tokenCookie) // Get cart & line items - const [cart, { Items, meta }] = await Promise.all([ + const [cart, { Items }] = await Promise.all([ restBuyerFetch('GET', `/orders/Outgoing/${cartId}`, null, { token }), restBuyerFetch('GET', `/orders/Outgoing/${cartId}/lineitems`, null, { token, @@ -34,24 +34,18 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({ } } catch (error) { console.error(error) - const headers = new Headers() - - headers.append( - 'set-cookie', - serialize(cartCookie, '', { - maxAge: -1, - path: '/', - }) - ) - - headers.append( - 'set-cookie', - serialize(tokenCookie, '', { - maxAge: -1, - path: '/', - }) - ) - + const headers = { + 'set-cookie': [ + serialize(cartCookie, '', { + maxAge: -1, + path: '/', + }), + serialize(tokenCookie, '', { + maxAge: -1, + path: '/', + }), + ], + } // Return empty cart return { data: null, diff --git a/packages/ordercloud/src/api/utils/fetch-rest.ts b/packages/ordercloud/src/api/utils/fetch-rest.ts index 60e760144..3724ebe84 100644 --- a/packages/ordercloud/src/api/utils/fetch-rest.ts +++ b/packages/ordercloud/src/api/utils/fetch-rest.ts @@ -75,11 +75,18 @@ export async function fetchData(opts: { // If something failed getting the data response if (!dataResponse.ok) { - // Get the body of it - const error = await dataResponse.json() - // And return an error + let errors + + try { + // Get the body of it + const error = await dataResponse.json() + errors = error.Errors + } catch (e) { + const message = await dataResponse.text() + errors = [{ message }] + } throw new FetcherError({ - errors: error.Errors, + errors, status: dataResponse.status, }) }