We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
You could add support to typescript, rewriting withRest or adding compatibility through index.d.ts:
import type { NextApiRequest, NextApiResponse } from 'next' import Boom from '@hapi/boom' import Joi from 'joi' const defaultLogError = (err: Boom.Boom) => { // Only log internal server errors if (!err.isServer) { return } // Log original error if passed if (err.data && err.data.originalError) { err = err.data.originalError } console.error(err.stack) } const defaultSendError = (res: NextApiResponse, err: Boom.Boom) => { const { output } = err const { headers, statusCode, payload } = output Object.entries(headers).forEach(([key, value]) => res.setHeader(key, value || '') ) res.status(statusCode).json(payload) } /** * Wraps a HTTP request handler with validation against Joi schemas. * * @param {object} schemas - An object with `query`, `body` or `headers` keys and their associated Joi schemas. * Each of these schemas will be matched against the incoming request. * * @returns {Function} The HTTP handler that validates the request. * * @example * * const getSchema = { * query: Joi.object({ * id: Joi.string().required(), * }), * }; * * export default withRest({ * GET: withValidation(getSchema)(async req, res) => { * // Do something with `req.query.id` * * return { foo: 'bar' }; * }, * }); */ export const withValidation = <T = any, R = any>(schemas: Joi.PartialSchemaMap<T> | undefined) => (fn: (arg0: NextApiRequest, arg1: NextApiResponse<R>) => Promise<any>) => async (req: NextApiRequest, res: NextApiResponse) => { const joiSchema = Joi.object(schemas).unknown(true) let validated: { [x: string]: any } try { validated = await joiSchema.validateAsync(req) } catch (err: any) { throw Boom.badRequest(err.message, { originalError: err as Error }) } // Joi normalizes values, so we must copy things back to req ;['headers', 'body', 'query'].forEach((key: string) => { ;(req as any)[key] = validated[key] }) return fn(req, res) } /** * @typedef {Function} SendError * * @param {object} res - Node.js response object. * @param {Error} err - The Boom error object. */ /** * @typedef {Function} LogError * * @param {Error} err - The Boom error object. */ /** * Matches handlers defined in `methods` against the HTTP method, like `GET` or `POST`. * * @param {object.<string, Function>} methods - An object mapping HTTP methods to their handlers. * @param {object} options - The options. * @param {SendError} options.sendError - A function responsible to send Boom errors back to the client. * @param {LogError} options.logError - A function that logs errors. * * @returns {Function} The composed HTTP handler. * * @example * * export default withRest({ * GET: async (req, res) => { * // Do something... * * return { foo: 'bar' }; * }, * }); */ const withRest = ( methods: { [x: string]: any }, opts: { logError?: typeof defaultLogError sendError?: typeof defaultSendError } = { logError: defaultLogError, sendError: defaultSendError, } ) => { const options = { logError: defaultLogError, sendError: defaultSendError, ...opts, } return async (req: NextApiRequest, res: NextApiResponse) => { try { const method = methods && methods[req.method || 'unknown'] if (!method) { throw Boom.methodNotAllowed( `Method ${req.method} is not supported for this endpoint` ) } const json = await method(req, res) // Do nothing if the request is already sent (e.g.: a redirect was issued) if (res.headersSent) { if (json !== undefined) { options.logError( Boom.internal( 'You have sent the response inside your handler but still returned something. This error was not sent to the client, however you should probably not return a value in the handler.' ) // eslint-disable-line max-len ) } return } // Next.js doesn't support nulls as `RFC7159` dictates, but we do if (json == null) { res.setHeader('Content-Type', 'application/json') res.setHeader('Content-Length', '4') res.end('null') } else { res.json(json) } } catch (err: Error | Boom.Boom | any) { // Not an ApiError? Then wrap it into an ApiError and log it. let apiError = err if (!err.isBoom) { apiError = Boom.internal(undefined, { originalError: err }) } options.logError(apiError) options.sendError(res, apiError) } } } export default withRest
The text was updated successfully, but these errors were encountered:
I think this library is not maintained anymore
Sorry, something went wrong.
No branches or pull requests
You could add support to typescript, rewriting withRest or adding compatibility through index.d.ts:
The text was updated successfully, but these errors were encountered: