This commit is contained in:
Catalin Pinte 2022-10-04 15:40:59 +03:00
parent 3a3883ada0
commit 600d8bb325
3 changed files with 32 additions and 15 deletions

View File

@ -7,6 +7,7 @@ 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.
* @param {CommerceAPI} commerce The Commerce API instance. * @param {CommerceAPI} commerce The Commerce API instance.
* @param endpoints An object containing the handlers for each endpoint. * @param endpoints An object containing the handlers for each endpoint.
* @returns JSON response with the data or error.
*/ */
export default function createEndpoints<P extends APIProvider>( export default function createEndpoints<P extends APIProvider>(
commerce: CommerceAPI<P>, commerce: CommerceAPI<P>,
@ -39,9 +40,7 @@ export default function createEndpoints<P extends APIProvider>(
? req.query.commerce.join('/') ? req.query.commerce.join('/')
: req.query.commerce : req.query.commerce
/** // Check if the handler for this path exists and return a 404 if it doesn't
* Check if the handler for this path exists and return a 404 if it doesn't
*/
if (!paths.includes(path)) { if (!paths.includes(path)) {
throw new Error( throw new Error(
`Endpoint handler not implemented. Please use one of the available api endpoints: ${paths.join( `Endpoint handler not implemented. Please use one of the available api endpoints: ${paths.join(
@ -51,16 +50,18 @@ export default function createEndpoints<P extends APIProvider>(
} }
const data = await handlers[path](req, res) const data = await handlers[path](req, res)
// If the handler returns a value but the response hasn't been sent yet, send it
/**
* If the handler returns a value but the response hasn't been sent yet, send it
*/
if (!res.headersSent) { if (!res.headersSent) {
res.status(200).json({ res.status(200).json({
data, data,
}) })
} }
} catch (error) { } catch (error) {
/**
* Return the error as a JSON response only if the response hasn't been sent yet
* Eg. by the `isAllowedMethod` util returning a 405 status code
*/
if (!res.headersSent) {
console.error(error) console.error(error)
const { status, data, errors } = normalizeError(error) const { status, data, errors } = normalizeError(error)
res.status(status).json({ res.status(status).json({
@ -69,4 +70,5 @@ export default function createEndpoints<P extends APIProvider>(
}) })
} }
} }
}
} }

View File

@ -14,7 +14,17 @@ export default function isAllowedMethod(
if (!req.method || !methods.includes(req.method)) { if (!req.method || !methods.includes(req.method)) {
res.status(405) res.status(405)
res.setHeader('Allow', methods.join(', ')) res.setHeader('Allow', methods.join(', '))
res.end() res.json({
errors: [
{
message: `You are not allowed to use the ${
req.method
} method for this route, please use one of the following methods: ${methods.join(
', '
)}`,
},
],
})
return false return false
} }

View File

@ -3,7 +3,12 @@ import isAllowedMethod, { HTTP_METHODS } from './is-allowed-method'
import { APIHandler } from './types' import { APIHandler } from './types'
/** /**
* @throws Error if the method is not allowed * Validates the request method and throws an error if it's not allowed, or if the handler is not implemented.
* and stops the execution of the handler.
* @param req The request object.
* @param res The response object.
* @param allowedOperations An object containing the handlers for each method.
* @throws Error when the method is not allowed or the handler is not implemented.
*/ */
export default function validateHandlers( export default function validateHandlers(
req: NextApiRequest, req: NextApiRequest,