Update handlers

This commit is contained in:
Catalin Pinte 2022-10-20 10:09:46 +03:00
parent e8c1ef1f57
commit 3fd24810f9
7 changed files with 71 additions and 56 deletions

View File

@ -2,8 +2,9 @@ import type { APIProvider, CommerceAPI, EndpointHandler } from '..'
import type { NextRequest } from 'next/server' import type { NextRequest } from 'next/server'
import { normalizeApiError } from './errors' import { normalizeApiError } from './errors'
import { transformHeaders } from '.'
export default function edgeApi<P extends APIProvider>( export default function edgeHandler<P extends APIProvider>(
commerce: CommerceAPI<P>, commerce: CommerceAPI<P>,
endpoints: Record<string, (commerce: CommerceAPI<P>) => EndpointHandler> endpoints: Record<string, (commerce: CommerceAPI<P>) => EndpointHandler>
) { ) {
@ -49,16 +50,14 @@ export default function edgeApi<P extends APIProvider>(
return output return output
} }
const { headers } = output const headers = transformHeaders(output.headers)
// If the output contains a redirectTo property, return a Response with the redirect // If the output contains a redirectTo property, return a Response with the redirect
if (output.redirectTo) { if (output.redirectTo) {
headers.append('Location', output.redirectTo)
return new Response(null, { return new Response(null, {
status: 302, status: 302,
headers: { headers,
...headers,
Location: output.redirectTo,
},
}) })
} }

View File

@ -50,3 +50,17 @@ export const transformRequest = (req: NextApiRequest, path: string) => {
body, body,
}) })
} }
export const transformHeaders = (
headers?: Record<string, string | number | string[]>
) =>
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()

View File

@ -4,7 +4,7 @@ import type { APIProvider, CommerceAPI, EndpointHandler } from '..'
import { normalizeApiError } from './errors' import { normalizeApiError } from './errors'
import { transformRequest } from '.' import { transformRequest } from '.'
export default function nodeApi<P extends APIProvider>( export default function nodeHandler<P extends APIProvider>(
commerce: CommerceAPI<P>, commerce: CommerceAPI<P>,
endpoints: { endpoints: {
[key: string]: (commerce: CommerceAPI<P>) => EndpointHandler [key: string]: (commerce: CommerceAPI<P>) => EndpointHandler
@ -44,8 +44,7 @@ export default function nodeApi<P extends APIProvider>(
) )
} }
const newReq = transformRequest(req, path) const output = await handlers[path](transformRequest(req, path))
const output = await handlers[path](newReq)
if (output instanceof Response) { if (output instanceof Response) {
return res.end(output.body) return res.end(output.body)
@ -54,9 +53,9 @@ export default function nodeApi<P extends APIProvider>(
const { status, errors, data, redirectTo, headers } = output const { status, errors, data, redirectTo, headers } = output
if (headers) { if (headers) {
for (const [key, value] of Object.entries(headers)) { Object.entries(headers).forEach(([key, value]) => {
res.setHeader(key, value) res.setHeader(key, value)
} })
} }
if (redirectTo) { if (redirectTo) {

View File

@ -7,7 +7,7 @@ export type APIResponse<Data = any> = {
data?: Data data?: Data
errors?: ErrorData[] errors?: ErrorData[]
status?: number status?: number
headers?: HeadersInit headers?: Record<string, number | string | string[]>
/** /**
* @type {string} * @type {string}
* @example redirectTo: '/cart' * @example redirectTo: '/cart'

View File

@ -11,7 +11,7 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
}) => { }) => {
// Get token // Get token
let token = req.cookies.get(tokenCookie) let token = req.cookies.get(tokenCookie)
let headers = new Headers() let headers: any = {}
// Create an order if it doesn't exist // Create an order if it doesn't exist
if (!cartId) { if (!cartId) {
@ -24,27 +24,29 @@ const addItem: CartEndpoint['handlers']['addItem'] = async ({
cartId = ID cartId = ID
headers.append( headers = {
'set-cookie', 'set-cookie': [
serialize(cartCookie, cartId!, { serialize(cartCookie, cartId!, {
maxAge: 60 * 60 * 24 * 30, maxAge: 60 * 60 * 24 * 30,
expires: new Date(Date.now() + 60 * 60 * 24 * 30 * 1000), expires: new Date(Date.now() + 60 * 60 * 24 * 30 * 1000),
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === 'production',
path: '/', path: '/',
sameSite: 'lax', sameSite: 'lax',
}) }),
) ],
}
headers.append( if (meta?.token) {
'set-cookie', headers['set-cookie'].push(
serialize(tokenCookie, meta.token.access_token, { serialize(tokenCookie, meta.token?.access_token, {
maxAge: meta.token.expires_in, maxAge: meta.token.expires_in,
expires: new Date(Date.now() + meta.token.expires_in * 1000), expires: new Date(Date.now() + meta.token.expires_in * 1000),
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === 'production',
path: '/', path: '/',
sameSite: 'lax', sameSite: 'lax',
}) })
) )
}
} }
let specs: RawVariantSpec[] = [] let specs: RawVariantSpec[] = []

View File

@ -19,7 +19,7 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({
const token = req.cookies.get(tokenCookie) const token = req.cookies.get(tokenCookie)
// Get cart & line items // 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}`, null, { token }),
restBuyerFetch('GET', `/orders/Outgoing/${cartId}/lineitems`, null, { restBuyerFetch('GET', `/orders/Outgoing/${cartId}/lineitems`, null, {
token, token,
@ -34,24 +34,18 @@ const getCart: CartEndpoint['handlers']['getCart'] = async ({
} }
} catch (error) { } catch (error) {
console.error(error) console.error(error)
const headers = new Headers() const headers = {
'set-cookie': [
headers.append( serialize(cartCookie, '', {
'set-cookie', maxAge: -1,
serialize(cartCookie, '', { path: '/',
maxAge: -1, }),
path: '/', serialize(tokenCookie, '', {
}) maxAge: -1,
) path: '/',
}),
headers.append( ],
'set-cookie', }
serialize(tokenCookie, '', {
maxAge: -1,
path: '/',
})
)
// Return empty cart // Return empty cart
return { return {
data: null, data: null,

View File

@ -75,11 +75,18 @@ export async function fetchData<T>(opts: {
// If something failed getting the data response // If something failed getting the data response
if (!dataResponse.ok) { if (!dataResponse.ok) {
// Get the body of it let errors
const error = await dataResponse.json()
// And return an error 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({ throw new FetcherError({
errors: error.Errors, errors,
status: dataResponse.status, status: dataResponse.status,
}) })
} }