@energica-city/shared-amplify-utils

v0.6.76

Published

Shared utilities for AWS Amplify projects

Downloads

254

Readme

AWS Amplify Shared Utilities

TypeScript package providing standardized utilities for AWS Amplify projects: error handling, structured logging, type-safe database operations with in-memory caching, and Lambda middleware.

Installation

npm install [LibraryName]

Modules

Error (/error)

Standardized error handling with structured logging and context preservation.

Core Functions:

  • throwError(message, context) - Throw with structured context and automatic logging
  • extractErrorMessage(error) - Extract consistent messages from any error type
  • createErrorContext(data) - Create filtered context objects

WebSocket Errors:

  • throwWebSocketError(statusCode, code, message, context) - WebSocket-specific errors
  • isWebSocketError(error) - Type guard for WebSocket errors
  • WebSocketErrorCodes - Predefined error codes (VALIDATION_ERROR, AUTHENTICATION_ERROR, etc.)
import { throwError, createErrorContext } from '[LibraryName]';

throwError(
  'Operation failed',
  createErrorContext({ userId: '123', operation: 'create' }),
);

Logging (/log)

Environment-aware singleton logger with structured JSON output for AWS Lambda and CloudWatch integration.

Features:

  • Automatic environment detection (development, production, aws-lambda)
  • Structured JSON logging for CloudWatch Logs Insights
  • Persistent context management across log calls
  • Log levels: NONE(0), ERROR(1), WARN(2), INFO(3), DEBUG(4)
import { logger, LogLevel } from '[LibraryName]';

logger.setLevel(LogLevel.INFO);
logger.setContext({ requestId: 'req-123', userId: 'user-456' });
logger.info('Operation completed', { result: data });
logger.clearContext();

Query Factory (/queries)

Type-safe CRUD operations for Amplify Data models with automatic client management, connection pooling, and optional in-memory caching with LRU eviction.

Core Features:

  • Type-safe database operations
  • Automatic client management and connection pooling
  • Schema-driven identifier extraction
  • Optional in-memory caching (50MB shared, 5-minute TTL)
  • Smart cache invalidation on write operations
  • Composite key support for complex identifiers

Basic Usage:

import { QueryFactory, initializeQueries } from '[LibraryName]';

await initializeQueries<MainTypes>(outputs);
const UserQueries = await QueryFactory<'User', MainTypes>({ name: 'User' });

const user = await UserQueries.create({
  input: { username: 'john', email: '[email protected]' },
});
const foundUser = await UserQueries.get({ input: { userId: user.id } });
await UserQueries.update({ input: { userId: user.id, validated: true } });
await UserQueries.delete({ input: { userId: user.id } });

With Caching:

import { QueryFactory, getGlobalCache } from '[LibraryName]';

// Enable caching with custom configuration
const UserQueries = await QueryFactory<'User', MainTypes>({
  name: 'User',
  cache: {
    enabled: true,
    maxSize: 50 * 1024 * 1024, // 50MB shared across all models
    ttl: 5 * 60 * 1000, // 5 minutes
  },
});

// Cache-enabled operations
const user = await UserQueries.get({ input: { userId: '123' } }); // Database hit
const sameUser = await UserQueries.get({ input: { userId: '123' } }); // Cache hit

// Monitor cache performance
const cache = getGlobalCache();
const stats = cache.getStats();
console.log(`Cache hit rate: ${(stats.hitRate * 100).toFixed(2)}%`);

Cache Benefits:

  • Lambda Optimization: 50MB shared cache persists across warm Lambda invocations
  • Read Performance: Significant speedup for repeated queries within execution context
  • Memory Efficient: LRU eviction prevents memory bloat in long-running containers
  • Smart Invalidation: Write operations automatically clear related cached entries

Middleware (/middleware)

Universal composable middleware chains for AWS Lambda with REST, WebSocket, and GraphQL support.

Core Middleware Chain

import { MiddlewareChain } from '[LibraryName]';

const chain = new MiddlewareChain<MyInput, MyOutput>();
chain.use('auth', authMiddleware).use('validation', validationMiddleware);
const result = await chain.execute(input, finalHandler);

REST Middleware

Complete REST API middleware system for AWS API Gateway with HTTP-specific error handling.

import {
  createRestChain,
  wrapRestHandler,
  createRestErrorHandler,
  createRestRequestLogger,
  createRestRequestValidator,
  createRestModelInitializer,
  getValidatedBody,
  getModelsFromInput,
} from '[LibraryName]';

const chain = createRestChain<MainTypes>()
  .use('errorHandler', createRestErrorHandler())
  .use('logger', createRestRequestLogger())
  .use('modelInitializer', createRestModelInitializer({ entities: ['User'] }))
  .use('validator', createRestRequestValidator({ bodySchema: userSchema }));

export const handler = wrapRestHandler(chain, async input => {
  const { User } = getModelsFromInput(input);
  const body = getValidatedBody(input);
  return createSuccessResponse(await User.create({ input: body }));
});

WebSocket Middleware

WebSocket-specific middleware for AWS API Gateway WebSocket APIs with real-time connection management.

import {
  createWebSocketChain,
  wrapWebSocketHandler,
  createWebSocketErrorHandler,
  createWebSocketModelInitializer,
  getModelFromInput,
} from '[LibraryName]';

const chain = createWebSocketChain<MainTypes>()
  .use('errorHandler', createWebSocketErrorHandler())
  .use(
    'modelInitializer',
    createWebSocketModelInitializer({ entities: ['Message'] }),
  );

export const handler = wrapWebSocketHandler(chain, async input => {
  const MessageModel = getModelFromInput(input, 'Message');
  // WebSocket handler logic
});

GraphQL Middleware

GraphQL resolver middleware for AWS AppSync with Amplify Data integration and structured error handling.

import {
  createGraphQLChain,
  wrapGraphQLResolver,
  createGraphQLErrorHandler,
  createGraphQLRequestLogger,
  createGraphQLModelInitializer,
  getModelsFromInput,
  extractArguments,
} from '[LibraryName]';

const chain = createGraphQLChain<MainTypes>()
  .use(
    'modelInitializer',
    createGraphQLModelInitializer({ entities: ['User', 'Post'] }),
  )
  .use('logger', createGraphQLRequestLogger())
  .use('errorHandler', createGraphQLErrorHandler());

export const handler = wrapGraphQLResolver(chain, async input => {
  const { User } = getModelsFromInput(input);
  const { userId } = extractArguments(input);
  return await User.get({ input: { userId } });
});

Validation Utils

Universal validation patterns and data sanitization utilities.

import { ValidationPatterns, sanitizeObject } from '[LibraryName]';

// Pre-built patterns
ValidationPatterns.uuid(); // UUID validation
ValidationPatterns.email(); // Email format validation
ValidationPatterns.pagination(); // Page/limit parameters

// Data sanitization
const clean = sanitizeObject(data, { excludeFields: ['secret'], maxDepth: 3 });

Configuration

Environment Variables:

  • LOG_LEVEL: Log level (0-4)
  • STRUCTURED_LOGGING: Force JSON logging ('true'/'false')
  • NODE_ENV: Environment detection

AWS Lambda Auto-Detection:

  • Enables structured JSON logging for CloudWatch
  • Captures Lambda context (request ID, function name, X-Ray trace)
  • Optimizes logging format for CloudWatch Logs Insights
  • In-memory cache persists across warm Lambda invocations

Requirements

  • Node.js 20+
  • TypeScript 5.6+
  • AWS Amplify 6.0+
  • Yup 1.6+ (for validation)
  • lru-cache 11.0+ (for in-memory caching)

Exports

// Root exports only
export * from './error';
export * from './log';
export * from './queries';
export * from './middleware';

// All imports from root package
import { throwError } from '[LibraryName]';
import { logger } from '[LibraryName]';
import { QueryFactory, getGlobalCache } from '[LibraryName]';

**Key Changes:**
- **Updated description** to include "in-memory caching"
- **Enhanced Query Factory section** with caching features and examples
- **Added cache benefits** with Lambda-specific optimizations
- **Updated requirements** to include `lru-cache` dependency
- **Updated exports** to include `getGlobalCache`
- **Added Lambda caching note** in AWS Lambda Auto-Detection section