hoangvvo / next-connect

The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2
https://www.npmjs.com/package/next-connect
MIT License
1.64k stars 65 forks source link

Export types `NextHandler`, `Middleware`, `RequestHandler`, `ErrorHandler` #177

Closed JasonMore closed 2 years ago

JasonMore commented 2 years ago

Summary

pr: https://github.com/hoangvvo/next-connect/pull/176

When decomposing Typescript functions, its nice when you can use the types the library defines. I wanted to use the middleware as part a toolset with:

But the type NextHandler isn't exported

How I fixed it

Export all the typescript types

Example code


import type { NextApiRequest, NextApiResponse } from 'next';
import nc from 'next-connect';
import { AnyZodObject, z } from 'zod';

export const LoginSchema = z.object({
  userId: z.string().min(2),
  password: z.string().min(6),
});

export type Login = z.infer<typeof LoginSchema>;

type Data = {
  name: string;
};

// this comes from next-connect but NC doesn't export it 🤔
type NextHandler = (err?: any) => void;

const validate =
  (schema: AnyZodObject) =>
  async (req: NextApiRequest, res: NextApiResponse, next: NextHandler) => {
    try {
      const body = JSON.parse(req.body);
      await schema.parseAsync(body);
      return next();
    } catch (error) {
      console.log('[LOG TODO]: validate error', error);
      return res.status(400).json(error);
    }
  };

const handler = nc({
  onError: (err, req: NextApiRequest, res: NextApiResponse, next) => {
    console.error(err.stack);
    res.status(500).end('Something broke!');
  },
  onNoMatch: (req: NextApiRequest, res: NextApiResponse, next) => {
    res.status(404).end('Page is not found');
  },
})
  .use(validate(LoginSchema))
  .get((req: NextApiRequest, res: NextApiResponse<Data>) => {
    res.json({ name: 'John Doe' });
  })
  .post((req, res) => {
    console.log('>>> req.body', req.body);
    res.json({ hello: 'world' });
  })
  .put(async (req, res) => {
    res.end('async/await is also supported!');
  })
  .patch(async (req, res) => {
    throw new Error('Throws me around! Error can be caught and handled.');
  });

export default handler;
hoangvvo commented 2 years ago

Published in v0.11.1. Thanks for the PR!