npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-kun

v1.0.24

Published

Functional Express Helper

Downloads

596

Readme

Express-Kun

Express Kun is providing you common helper for common express use case with functional programming mindset.

Installation

yarn add express-kun or npm install express-kun

Philosophy

Express Kun philosophy is An helper should only extends the functionality without redefining how we write our application. think of it as Redux vs Mobx. in Redux, you don't redefine how you write your components. redux only extends the functionality fia connect function to access your reducer. meanwhile MobX requiring you to wrap your function in decorator. by extending instead of redefining we can achieve smoother learning curve and more expressive. Express Kun does not dictate you. instead, you provided it with express Router object and returning modified Router express object or providing callback to play with modified Router Object. Express Kun is your friend and servant.

API

Base

withMiddleware(router: Router, middlewares: RequestHandler[]): Router;

with middleware apply middleware to your router and return back the midlewared router

// your router
const router = Router();
// with auth middleware
const protectedRouter = withMiddleware(router, authMiddleware); // also support array of middleware ex: [authMiddleware, myMiddleware2]

protectedRouter.get("/user", (req, res) => {
  res.send({
    message: "success"
  });
});

because this is only return the midlewared router. you can chain it without modifying the first router behavior

// your router
const router = Router();
// with auth middleware
const protectedRouter = withMiddleware(router, authMiddleware); // also support array of middleware ex: [authMiddleware, myMiddleware2]
// will apply authMiddleware and uploadMiddleware
const protectedUploadRouter = withMiddleware(protectedRouter, uploadMiddleware);

protectedRouter.get("/user", (req, res) => {
  res.send({
    message: "success"
  });
});
protectedUploadRouter.post("/user", (req, res) => {
  res.send({
    message: "success upload photo"
  });
}))

withErrorHandler(router: Router, errorHandler: ErrorRequestHandler): Router;

withErrorHandler returning a router that when that route error it will use the provided error handler

for example

function errorHandler(err, req, res, next) {
  res.json({
    error: true,
    mesage: "wow error"
  });
}

const withErrorHandlerRoute = withErrorHandler(router, errorHandler);

// when accessed will return json { error: true, message: 'wow error' }
withErrorHandlerRoute.get("/errorrouter", (req: Request, res: Response) => {
  throw new Error("Error here");
});

this provide further more functionality to compose middleware with error handler

function errorHandler(err, req, res, next) {
  res.json({
    error: true,
    mesage: "wow error"
  });
}

function middleware(req, res, next) {
  console.log("midleware");
  next();
}

const middlewaredRoute = withMiddleware(router, middleware);

const withErrorHandlerRoute = withErrorHandler(middlewaredRoute, errorHandler);

// when accessed will return json { error: true, message: 'wow error' }
withErrorHandlerRoute.get("/errorrouter", (req: Request, res: Response) => {
  throw new Error("Error here");
});

partialWithMiddleware(middlewares: RequestHandler[]): (router: Router) => void

partially use withMiddleware. this is useful if you want to create abstraction of midleware. for example you want to build helper to generate route with auth middleware. you can do like this

// in generateAuthMiddleware.js
const generateAuthMiddleware = partialWithMiddleware(authMiddleware);

// in your routes.js
const router = new Router();
const protectedRoute = generateAuthMiddleware(router);

this even support supplying partialWithmiddleware with middleware for easy composition

// in generateAuthMiddleware.js
const generateAuthMiddleware = partialWithMiddleware(authMiddleware);

// in uploadProtectedMiddleware.js
const generateUploadProtectedMiddleware = generateAuthMiddleware(
  uploadMiddleware
);

// in your routes.js
const router = new Router();
const uploadProtectedRouter = generateUploadProtectedMiddleware(router);

partialWithErrorHandler(errorHandler: ErrorRequestHandler): (router: Router) => void;

like partialWithMiddleware but for error handler

// in generateLoggingErrorRoute.js
const loggedErrorHandler = partialWithErrorHandler(errorHandler);

// in your routes.js
const router = new Router();
const loggedRoute = generateLoggingErrorRoute(routeer);

groupErrorHandler(routerOrApp: RouterOrApplication, handler: ErrorRequestHandler): (callback: (router: Router) => void) => void;

this wass Laravel-like route for reusable error handling. you can write it like this

// your router
const router = Router();
// define error handler
const errorHandler = (err, req, res, next) => {
  // log the error
  console.log(error);

  // sendJson
  res.json({
    error: true,
    messsage: "wow error"
  });
};

// use it
groupErrorHandler(
  router,
  errorHandler
)(withErrorHandlerRoute => {
  // when every route defined here return an error it will passed to the error handler
  withErrorHandleRoute.get("/testError", (req, res) => {
    throw new Error("error Here");
  });
});

by providing error this way you can provide multiple error handle for different route easily

const userRouter = Router();
const customerRouter = Router();
// define error handler
const errorHandlerUser = (err, req, res, next) => {
  // log the error
  console.log(error);

  // sendJson
  res.json({
    error: true,
    messsage: "wow error in user"
  });
};

const errorHandlerCustomer = (err, req, res, next) => {
  // log the error
  console.log(error);

  // sendJson
  res.json({
    error: true,
    messsage: "wow error in customer"
  });
};

// use it
groupErrorHandler(
  userRouter,
  errorHandlerUser
)(withErrorHandlerRoute => {
  // when every route defined here return an error it will passed to the error handler
  withErrorHandleRoute.get("/user/testError", (req, res) => {
    throw new Error("error Here");
  });
});

groupErrorHandler(
  customerRouter,
  errorHandlerCustomer
)(withErrorHandlerRoute => {
  // when every route defined here return an error it will passed to the error handler
  withErrorHandleRoute.get("/customer/testError", (req, res) => {
    throw new Error("error Here");
  });
});

Extended

withJWTAuthMiddleware(router: Router, secretKey: string, getToken?: GetTokenFun, preCheckFun?: PreCheckFun, errorHandler?: ErrorRequestHandler, verifyOptions?: jwt.VerifyOptions): Router;

typings
type GetTokenFun = (req: Request) => any;
type PreCheckFun = (req: Request, res: Response) => any;
use
const protectedRouter = withJWTAuthMiddleware(router, "mySecretKey");

withJWTAuthMiddleware make it simple to create middleware for authentication if you are using jwt. the only required parameter is secretKeey that you use to sign your jwt. by default it will get token from the bearer from authorization header for example

Headers: ...
  Authorizatation: Bearer 321lnasljndjijno214

but you can also provide getToken Function that will pass the request object as parameter and should return the token, for example

function getTokenFromBearer(req: Request) {
  const authorization = req.headers.authorization;
  if (!authorization) {
    throw new Error("No Authorization Header");
  }
  try {
    const token = authorization?.split("Bearer ")[1];
    return token;
  } catch {
    throw new Error("Invalid Token Format");
  }
}

and then use like below

const protectedRouter = withJWTAuthMiddleware(
  router,
  "mySecretKey",
  getTokenFromBearer
);

you can also provide pre check for example to check if user exist

function checkUser(req: Request, res: Response) {
  // check user object
  // ...
  // user not found
  if (!user) {
    res.status(404).json({
      message: "User Not Found",
      error: true
    });
  }
}

and then use like below

withJWTAuthMiddleware(router, "mySecretKey", getTokenFromBearer, checkUser);

partialWithJWTAuthMiddleware(secretKey: string, getToken?: GetTokenFun, preCheckFun?: PreCheckFun, errorHandler?: ErrorRequestHandler, verifyOptions?: jwt.VerifyOptions)

this function is like withJWTAuthMiddleware but you can pass the Router later;

export const authMiddleware = partialWithJWTAuthMiddleware(
  "mySecretKey",
  getTokenFromBearer,
  checkUser
);

// later
const protectedRoute = authMiddleware(router);

Callback API

groupMiddleware(router: Router, middlewares: SupportedMiddleware): (callback: (router: Router) => void) => void;

This is like groupErrorHandler but instead of error handler you can pass middleware here for example

// your router
const router = Router();
// define error handler
const myMiddleware = (err, req, res, next) => {
  // log or do something
  console.log("logging in something");
};

// use it
groupMiddleware(
  router,
  myMiddleware // also support array of middleware ex: [myMiddleware, myMiddleware2]
)(middlewaredRoute => {
  // when every route defined here return an error it will passed to the error handler
  middlewaredRoute.get("/user/middlewared", (req, res) => {
    res.send("hello world");
  });
});

groupPrefix(router: Router, prefix: string): (callback: (router: Router) => void) => void;

Provide laravel-like grouping route/controller with the same prefix

// your router
const router = Router();
// add prefix
groupPrefix(
  router,
  "/customer"
)(prefixedRoute => {
  // the route will be '/customer/test'
  prefixedRoute.get("/test", (req, res) => {
    res.send("hello world");
  });
});

Features

  • Functional Like
  • extendable
  • built with Typescript