Skip to main content
Lambda Toolkit Logo

Lambda Toolkit

Lambda Toolkit is an open-source collection of utility functions designed to help teams write production-ready application code, for deployment to AWS Lambda, faster.

Read more in the docs here: Lambda Toolkit Docs

Features

  • Core Utilities: Logging, date utilities, schema validation, metrics, and tracing
  • Lambda HTTP Handler: Complete wrapper with observability and error handling
  • DNS Utilities: Domain name generation for consistent subdomain creation
  • DynamoDB Utilities: Helper functions for cleaning internal keys from items
  • Config Manager: Type-safe environment variable handling with validation
  • Error Classes: Built-in error classes for consistent HTTP error responses

Installation

npm install @leighton-digital/lambda-toolkit

Usage

Importing the Package

All utilities are available from the main package import:

import {
// Core utilities
logger,
tracer,
metrics,
getISOString,
validateSchema,

// Lambda utilities
withHttpHandler,

// DNS utilities
generateApiSubDomain,
generateWebSubDomain,
generateAuthDomain,
generateCognitoDomain,
sanitiseDnsString,

// DynamoDB utilities
stripInternalKeys,

// Config manager
envVar,

// Error classes
ValidationError,
ResourceNotFoundError,
UnauthorisedError,
ForbiddenError,
ConflictError,
TooManyRequestsError
} from '@leighton-digital/lambda-toolkit';

Basic HTTP Handler Example

Here's a complete example showing how to use the HTTP handler with validation and error handling:

import {
withHttpHandler,
validateSchema,
ValidationError,
ResourceNotFoundError,
logger
} from '@leighton-digital/lambda-toolkit';
import { z } from 'zod';

// Define request schema
const createUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(18).max(120),
});

export const handler = withHttpHandler(async ({ event }) => {
const { userId } = event.pathParameters || {};

if (event.httpMethod === 'POST') {
// Create user
const body = JSON.parse(event.body || '{}');
const validatedUser = validateSchema(createUserSchema, body);

logger.info('Creating user', { email: validatedUser.email });

// Your business logic here...
const newUser = { id: 'user123', ...validatedUser };

return {
statusCode: 201,
body: { message: 'User created successfully', user: newUser },
};
}

if (event.httpMethod === 'GET' && userId) {
// Get user
logger.info('Fetching user', { userId });

// Your business logic here...
const user = await getUserById(userId);
if (!user) {
throw new ResourceNotFoundError(`User ${userId} not found`);
}

return {
statusCode: 200,
body: { user },
};
}

throw new ValidationError('Invalid request method or missing parameters');
});

async function getUserById(id: string) {
// Mock implementation
return id === 'user123' ? { id, name: 'Alice', email: 'alice@example.com' } : null;
}

Config Manager Example

Use the config manager for type-safe environment variable handling:

import { envVar, withHttpHandler, logger } from '@leighton-digital/lambda-toolkit';

// Validate configuration at module load time
const config = {
apiUrl: envVar.getString('API_URL'),
enableDebug: envVar.getBoolean('ENABLE_DEBUG'),
maxRetries: envVar.getNumber('MAX_RETRIES'),
timeout: envVar.getNumber('TIMEOUT_MS'),
};

export const handler = withHttpHandler(async ({ event }) => {
logger.info('Handler configuration', {
apiUrl: config.apiUrl,
enableDebug: config.enableDebug,
maxRetries: config.maxRetries,
timeout: config.timeout,
});

// Your business logic here...

return {
statusCode: 200,
body: { message: 'Configuration loaded successfully', config },
};
});

DNS Utilities Example

Generate consistent domain names for different environments:

import {
generateApiSubDomain,
generateWebSubDomain,
generateAuthDomain,
generateCognitoDomain
} from '@leighton-digital/lambda-toolkit';

const stage = 'develop';
const domainName = 'example.com';

// API subdomain
const apiDomain = generateApiSubDomain({ stageName: stage, domainName });
// Returns: 'api-develop.example.com' (or 'api.example.com' for prod)

// Web subdomain
const webDomain = generateWebSubDomain({ stageName: stage, domainName });
// Returns: { stage: 'develop', subDomain: 'develop.example.com' }

// Auth domain
const authDomain = generateAuthDomain({ stageName: stage, domainName });
// Returns: { stage: 'develop', authDomain: 'auth-develop.example.com' }

// Cognito domain
const cognitoDomain = generateCognitoDomain({
stageName: stage,
domainName,
serviceName: 'myapp'
});
// Returns: 'https://myapp-develop.auth.us-east-1.amazoncognito.com'

DynamoDB Utilities Example

Clean internal keys from DynamoDB items before returning them:

import { stripInternalKeys, withHttpHandler } from '@leighton-digital/lambda-toolkit';

export const handler = withHttpHandler(async ({ event }) => {
// Mock DynamoDB item with internal keys
const dynamoItem = {
pk: 'USER#123',
sk: 'PROFILE',
gsi1pk: 'EMAIL#alice@example.com',
gsi1sk: 'USER#123',
name: 'Alice Johnson',
email: 'alice@example.com',
age: 30,
createdAt: '2025-01-01T00:00:00.000Z',
};

// Strip internal DynamoDB keys
const cleanItem = stripInternalKeys(dynamoItem);
// Result: { name: 'Alice Johnson', email: 'alice@example.com', age: 30, createdAt: '...' }

return {
statusCode: 200,
body: { user: cleanItem },
};
});

Running Tests

To run the tests:

pnpm test

Development

To build the package:

pnpm build

To run linting:

pnpm lint

To format code:

pnpm format

Dependencies

Required

  • @middy/core - Lambda middleware framework
  • @middy/http-error-handler - HTTP error handling middleware
  • http-errors - HTTP error utilities
  • zod - Schema validation

Peer Dependencies

  • @aws-lambda-powertools/logger - Structured logging
  • @aws-lambda-powertools/metrics - Custom metrics
  • @aws-lambda-powertools/tracer - Distributed tracing
  • aws-cdk-lib - AWS CDK library (for types)
  • aws-lambda - AWS Lambda types
  • constructs - CDK constructs (for types)

Key Features

  • Type Safety: Full TypeScript support with strict typing
  • Observability: Built-in logging, metrics, and tracing with AWS Lambda Powertools
  • Error Handling: Standardized HTTP error responses with proper status codes
  • Validation: Comprehensive input validation with Zod schemas and helpful error messages
  • DNS Management: Consistent domain name generation across environments
  • Environment Configuration: Type-safe environment variable handling

License

MIT License - see the LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a pull request.