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

@thalorlabs/middleware

v1.3.0

Published

Express.js middleware collection for TypeScript applications with authentication, logging, and error handling

Readme

@thalorlabs/middleware

A comprehensive Express.js middleware collection for TypeScript applications with authentication and error handling capabilities.

Installation

npm install @thalorlabs/middleware

Features

  • Authentication middleware with API key validation
  • Error handling middleware with try-catch wrapper and structured error responses
  • Protected access middleware combining authentication and error handling
  • TypeScript support with full type safety
  • Configurable options for different use cases
  • Request tracking with requestId and context support
  • Structured error responses for consistent API responses

Quick Start

import express from 'express';
import {
  protect,
  TryCatchMiddleware,
  protectedAccessMiddleware,
} from '@thalorlabs/middleware';

const app = express();

// Basic authentication middleware
app.use('/api', TryCatchMiddleware(protect));

// Protected route with custom handler
app.get(
  '/api/data',
  protectedAccessMiddleware(async (req, res) => {
    res.json({ message: 'Protected data' });
  }, 'your-api-key')
);

// Custom middleware with error handling
app.get(
  '/api/custom',
  TryCatchMiddleware(async (req, res) => {
    // Your custom logic here
    res.json({ success: true });
  })
);

Middleware Components

Authentication Middleware (protect)

Validates API keys from request headers.

import { protect } from '@thalorlabs/middleware';

// Basic usage (no validation - for testing)
app.use('/api', TryCatchMiddleware(protect));

// With API key validation
app.use(
  '/api',
  TryCatchMiddleware(async (req, res) => {
    await protect(req, res, 'your-secret-api-key');
  })
);

// With multiple valid API keys
app.use(
  '/api',
  TryCatchMiddleware(async (req, res) => {
    await protect(req, res, ['key1', 'key2', 'key3']);
  })
);

Request Headers:

  • x-api-key: The API key to validate

Response:

  • Sets res.locals.apiKey with the validated API key
  • Throws AuthenticationError if validation fails

Error Handling Middleware (TryCatchMiddleware)

Wraps middleware functions with comprehensive error handling.

import { TryCatchMiddleware } from '@thalorlabs/middleware';

// Wrap any async middleware function
const safeMiddleware = TryCatchMiddleware(async (req, res, next) => {
  // Your middleware logic here
  // Errors will be automatically caught and handled
});

app.use('/api', safeMiddleware);

Error Handling:

  • CustomError instances: Returns structured error responses
  • ZodError instances: Converts to ValidationError format
  • MongoDB duplicate key errors: Converts to DatabaseError
  • Generic errors: Returns appropriate HTTP status codes

Protected Access Middleware (protectedAccessMiddleware)

Combines authentication and error handling for protected routes.

import { protectedAccessMiddleware } from '@thalorlabs/middleware';

// Single API key
app.get(
  '/api/protected',
  protectedAccessMiddleware(async (req, res) => {
    res.json({ message: 'This is protected data' });
  }, 'your-api-key')
);

// Multiple API keys
app.post(
  '/api/admin',
  protectedAccessMiddleware(
    async (req, res) => {
      res.json({ message: 'Admin operation completed' });
    },
    ['admin-key-1', 'admin-key-2']
  )
);

// No API key validation (for testing)
app.get(
  '/api/test',
  protectedAccessMiddleware(async (req, res) => {
    res.json({ message: 'Test endpoint' });
  })
);

Type Definitions

MiddlewareFunction

type MiddlewareFunction<T = Record<string, string>> = (
  req: Request<T>,
  res: Response,
  next: NextFunction
) => Promise<void>;

Error Handling

The middleware integrates with @thalorlabs/errors for consistent error responses:

CustomError Integration

import { BadRequestError, ValidationError } from '@thalorlabs/errors';

app.get(
  '/api/example',
  TryCatchMiddleware(async (req, res) => {
    if (!req.query.id) {
      throw new BadRequestError('ID parameter is required');
    }

    // Validation errors
    if (someValidationFails) {
      throw new ValidationError('Validation failed', [
        { field: 'email', message: 'Invalid email format' },
      ]);
    }

    res.json({ success: true });
  })
);

Error Response Format

{
  "status": "failure",
  "error": "Error message",
  "timestamp": "2024-01-01T12:00:00.000Z",
  "requestId": "req-123",
  "context": {
    "additional": "context"
  }
}

Advanced Usage

Custom Error Handling

import { TryCatchMiddleware } from '@thalorlabs/middleware';

const customErrorHandler = TryCatchMiddleware(async (req, res) => {
  // Your logic that might throw errors
  if (someCondition) {
    throw new Error('Custom error message');
  }

  res.json({ success: true });
});

app.use('/api/custom', customErrorHandler);

Multiple Middleware Layers

import { protect, TryCatchMiddleware } from '@thalorlabs/middleware';

// Authentication + custom logic
app.get(
  '/api/data',
  TryCatchMiddleware(async (req, res) => {
    await protect(req, res, 'api-key');
  }),
  TryCatchMiddleware(async (req, res) => {
    // Additional middleware logic
    res.json({ data: 'some data' });
  })
);

Configuration

Environment Variables

# Optional: Set default API key
API_KEY=your-default-api-key

# Optional: Set environment
NODE_ENV=production

TypeScript Configuration

The package includes full TypeScript support. Make sure your tsconfig.json includes:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "declaration": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

Testing

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

Dependencies

  • @thalorlabs/errors: Error handling classes
  • @thalorlabs/types: Type definitions
  • express: Express.js framework
  • uuid: UUID generation
  • zod: Schema validation (for error handling)

Peer Dependencies

  • express: ^4.18.0

Best Practices

1. Always Use TryCatchMiddleware

// Good
app.use('/api', TryCatchMiddleware(protect));

// Avoid
app.use('/api', protect); // Errors won't be handled properly

2. Use Protected Access for Routes

// Good - combines auth and error handling
app.get('/api/data', protectedAccessMiddleware(handler, 'api-key'));

// More verbose but equivalent
app.get(
  '/api/data',
  TryCatchMiddleware(async (req, res) => {
    await protect(req, res, 'api-key');
    await handler(req, res);
  })
);

3. Provide API Keys

// Good - validates API keys
app.use(
  '/api',
  TryCatchMiddleware(async (req, res) => {
    await protect(req, res, process.env.API_KEY);
  })
);

// Avoid - no validation (only for testing)
app.use('/api', TryCatchMiddleware(protect));

4. Use Request IDs for Tracing

import { v4 as uuidv4 } from 'uuid';

app.use((req, res, next) => {
  req.headers['x-request-id'] = req.headers['x-request-id'] || uuidv4();
  next();
});

Migration Guide

From Basic Express Middleware

// Before
app.get('/api/data', async (req, res) => {
  try {
    // Validate API key
    if (req.headers['x-api-key'] !== 'secret') {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    // Your logic
    res.json({ data: 'some data' });
  } catch (error) {
    res.status(500).json({ error: 'Internal server error' });
  }
});

// After
app.get(
  '/api/data',
  protectedAccessMiddleware(async (req, res) => {
    res.json({ data: 'some data' });
  }, 'secret')
);

License

ISC

This middleware collection provides a solid foundation for building robust Express.js applications with proper authentication and error handling.