JSPM

@thalorlabs/middleware

1.3.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q72151F
  • License ISC

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

Package Exports

  • @thalorlabs/middleware
  • @thalorlabs/middleware/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@thalorlabs/middleware) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

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.