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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zooxsmart/lambda-middleware

v1.1.1

Published

Simple middleware implementation for AWS Lambda

Readme

Intro

@zooxsmart/lambda-middleware is a simple middleware implementation for AWS Lambda.

It uses async/await for handlers, no "callback hell".

This module also provides some basic middlewares.

Example

const middleware = require('@zooxsmart/lambda-middleware');
const CompanyMapper = require('./CompanyMapper');
const getParams = require('./getParams');

const handler = middleware.pipeline();

handler.use(getParams());
handler.use(middleware.halResponse().halEntity);

handler.handler(async event => {
  const mapper = new CompanyMapper();

  return mapper.fetch(event.pathParameters.id);
});

module.exports = { handler };

Here we have a get company example using some recommended lambda middlewares embedded in middleware.pipeline(), decorates the output with HAL links for the entity and a custom middleware getParam() to fetch database parameters.

How it works

This module implements the middleware pipeline in a onion style.

The terminology "pipeline" is often used to describe the onion. One way of looking at the "onion" is as a queue, which is first-in-first-out (FIFO) in operation. This means that the first middleware on the queue is executed first, and this invokes the next, and so on (and hence the "next" terminology)

Each middleware receives the event and context, and pass to the handler only when wanting to hand off processing.

A middleware can return a response immediately, for example validate in input before handling it to the handler. In this case, the pipeline will not continue and the request will not even reach the handler.

Pipeline

The pipeline will return the middleware engine.

Options:

{
    useRecommended: true
}
  • useRecommended: Will automatically add the following middlewares at the top:
    • doNotWaitEmptyEventLoop
    • errorHandler
    • eventParser

You can add other middlewares using the use(middleware) method and finally your handler with the handler(handler) method.

Middlewares

Included (more on the way)

doNotWaitEmptyEventLoop(wait = false)

Will set context.callbackWaitsForEmptyEventLoop = wait;

errorHandler

Will wrap the following middlewares and handler with a try/catch and return a formatted json response (recommended using http-errors). If not using http-errors, set expose to true so the message can be used. See http-errors for more details.

eventParser({ parseBody: true })

Will parse a body string into json and ensure the presence of pathParameters, queryStringParameters, requestContext and requestContext.authorizer.

halResponse({ path: null, collectionName: null, entityPath: null })

Will decorate an entity json with the _link.self from HAL and a collection with links, pagination, and it's entities.

  • path: the path to include in the _link.self . Fallback to the current event.path if not provided
  • collectionName: the collection name (duh) to be named in the _embedded
  • entityPath: the entity path prefix. Will append the entity id

The middleware will use context.statusCode for the response with fallback to 200.

parameterStore(keyMap, destination, { ssmOptions: {}, expiryMs: 10 * 60 * 1000 })

Will fetch the keys from SSM Parameter Store, embed in the destination and cache the result for the specified expiryMs.

  • keyMap: A map of key names and paths in SSM. Example: { MYSQL_HOST: '/production/MYSQL_HOST', MYSQL_USER: '/production/MYSQL_USER', MYSQL_PASS: '/production/MYSQL_PASS', }
  • destination: the destination of the parameters. Example: process.env, context
  • ssmOptions: Will be passed to the SSM constructor
  • expiryMs: Will keep the parameters in the memory cache for expiryMs in milliseconds. Default is 10 minutes.

secretsManager(keyMap, destination, { secretsManagerOptions: {}, expiryMs: 10 * 60 * 1000 })

Will fetch the keys from AWS Secrets Manager, embed in the destination and cache the result for the specified expiryMs.

  • keyMap: A map of key names and paths in Secrets Manager. Example: { MYSQL_HOST: '/production/MYSQL_HOST', MYSQL_USER: '/production/MYSQL_USER', MYSQL_PASS: '/production/MYSQL_PASS', }
  • destination: the destination of the parameters. Example: context . context will be used if null
  • secretsManagerOptions: Will be passed to the AWS.secretsmanager constructor
  • expiryMs: Will keep the parameters in the memory cache for expiryMs in milliseconds. Default is 10 minutes.

Custom

You can create a custom middleware and even call another middleware, just follow the following signature and example:

const middleware = require('../lambda-middleware');

module.exports = () => {
  return async (event, context, next) => {
    if (process.env.NODE_ENV !== 'development') {
      const params = {};
      await secretManager({ MYSQL: 'prod/mysql' })(event, params, (ev, ctx) => {
        process.env.MYSQL_HOST = ctx.MYSQL.host;
        process.env.MYSQL_USER = ctx.MYSQL.username;
        process.env.MYSQL_PASS = ctx.MYSQL.password;
      });
    }

    return next(event, context);
  };
};
const middleware = require('../lambda-middleware');

module.exports = () => {
  return async (event, context, next) => {
    if (process.env.NODE_ENV !== 'development') {
      return middleware.parameterStore(
        {
          MYSQL_HOST: '/production/MYSQL_HOST',
          MYSQL_USER: '/production/MYSQL_USER',
          MYSQL_PASS: '/production/MYSQL_PASS',
        },
        process.env,
      )(event, context, next);
    }

    return next(event, context);
  };
};

Warning Don't forget to call return next(event, context) at the end or the pipeline will not continue and will get no response.