@sens-tools/base-server v0.0.2
Sens Node.js Base Server
A powerful Express server package that provides a robust foundation for building secure and well-documented APIs with Swagger integration, authentication, rate limiting, and more.
Features
🛡️ Security Features
- Helmet for security headers
- CORS support with configurable options
- Rate limiting to prevent abuse
- Basic authentication for Swagger UI
- Toobusy protection against server overload
📚 Swagger Integration
- Multiple theme support (classic, dark, material, monokai, muted, newspaper, outline, shadow)
- Instance-specific documentation
- Basic authentication protection
- Customizable base URL and API path
🚀 Express Enhancements
- Instance-based routing
- Standardized response helper
- Error handling middleware
- Morgan logging with configurable formats
- Body parsing middleware
Installation
pnpm add @sens-tools/base-serverQuick Start
import { SensServer } from '@sens-tools/base-server';
// Create your Swagger documentation
const swaggerJson = {
openapi: '3.0.0',
info: {
title: 'Your API',
version: '1.0.0',
},
paths: {
'/users': {
get: {
responses: {
'200': {
description: 'List of users',
},
},
},
},
},
};
// Initialize the server with configuration
const server = new SensServer({
swaggerJson,
iotaBaseUrl: 'your-domain.com',
apiPath: '/api',
swaggerPath: '/docs',
swaggerUsername: 'admin',
swaggerPassword: 'secret',
morgan: 'dev',
rateLimitWindowMs: 15 * 60 * 1000, // 15 minutes
rateLimitMaxRequests: 100,
toobusyMaxLag: 100,
toobusyInterval: 500,
corsOptions: {
origin: ['https://your-frontend.com'],
methods: ['GET', 'POST'],
},
});
// Get the router to add your routes
const router = server.getRouter();
// Add your routes
router.get('/users', (req, res) => {
res.api.ok({ users: [] });
});
// Start the server
server.start(3000);Available Components
import SensServer, { handleEndpointResult } from '@sens-tools/base-server';Exported Types
The package exports the following TypeScript types:
import type {
SensConfig, // Complete server configuration with all required fields
SensConfigInput, // Input configuration interface for SensServer constructor
InstanceConfig, // Configuration for API instances
EndpointResultType, // Type for endpoint result data (string | number | Record<string, unknown> | Array<unknown>)
EndpointFunction, // Type for endpoint functions that return a Result type
ErrorResponse, // Standard error response format
} from '@sens-tools/base-server';Configuration Options
The SensConfigInput interface accepts the following configuration:
interface SensConfigInput {
swaggerJson: any; // Your Swagger documentation
iotaBaseUrl: string; // Base URL for your API
corsOptions?: CorsOptions; // Optional CORS configuration
swaggerUsername?: string; // Username for Swagger UI basic auth
swaggerPassword?: string; // Password for Swagger UI basic auth
morgan?: 'combined' | 'common' | 'dev' | 'short' | 'tiny'; // Logging format
toobusyMaxLag?: number; // Maximum event loop lag in milliseconds
toobusyInterval?: number; // Check interval in milliseconds
rateLimitWindowMs?: number; // Rate limit window in milliseconds
rateLimitMaxRequests?: number; // Maximum requests per window
apiPath?: string; // API path prefix (defaults to '/api')
swaggerPath?: string; // Swagger UI path (defaults to '/docs')
}SensServer Components and Functionality
After initializing a new SensServer instance, you have access to several powerful components and methods:
Available Methods
// Get the router to add your routes
const router = server.getRouter();
// Get the Express app instance for advanced customization
const app = server.getApp();
// Get the current server configuration
const config = server.getConfig();
// Start the server
await server.start(port);
// Shutdown the server gracefully
await server.shutdown();
// Restart the server
await server.restart(port);Request Context
Each request automatically includes instance and authentication information through req.api:
req.api.iota.instance; // The instance identifier
req.api.iota.token; // The authentication tokenResponse Helpers
The server provides a rich set of response helpers through res.api:
res.api.ok(data); // 200 OK
res.api.created(data); // 201 Created
res.api.accepted(data); // 202 Accepted
res.api.noContent(); // 204 No Content
res.api.badRequest(error); // 400 Bad Request
res.api.unauthorized(error); // 401 Unauthorized
res.api.forbidden(error); // 403 Forbidden
res.api.notFound(error); // 404 Not Found
res.api.methodNotAllowed(error); // 405 Method Not Allowed
res.api.requestTimeout(error); // 408 Request Timeout
res.api.conflict(error); // 409 Conflict
res.api.gone(error); // 410 Gone
res.api.unprocessableEntity(error); // 422 Unprocessable Entity
res.api.internalServerError(error); // 500 Internal Server Error
res.api.serviceUnavailable(error); // 503 Service Unavailable
res.api.tooBusy(error); // 503 Too Busy
res.api.gatewayTimeout(error); // 504 Gateway TimeoutError Handling with handleEndpointResult
The SensServer provides a powerful error handling system through the handleEndpointResult utility. This utility helps standardize error handling across your API endpoints and ensures consistent error responses.
Basic Usage
import { handleEndpointResult } from '@sens-tools/base-server';
// Define your endpoint function
const getUsers = async (req: Request, res: Response) => {
const users = await getUsersFromDatabase();
if (users.isErr()) {
return err(users.error);
}
return ok(users.value);
};
// Use handleEndpointResult in your route
router.get('/users', (req, res) => {
handleEndpointResult(req, res, getUsers);
});Error Response Format
All errors follow a consistent format:
{
error: string, // Error code/type
error_description: string, // Human-readable error message
details?: any // Optional additional error details (e.g., validation errors)
}Error Types Handled
The system automatically handles various types of errors:
Validation Errors (Zod)
{ error: 'Validation Error', error_description: 'The request data failed validation', details: [ { path: 'user.email', message: 'Invalid email format', code: 'invalid_string' } ] }API Errors
{ error: 'API Error', error_description: 'Custom error message', statusCode: 400 // Optional status code }Standard Errors
{ error: 'Internal Server Error', error_description: 'An unexpected error occurred' }
Example with Error Handling
import { handleEndpointResult } from '@sens-tools/base-server';
import { ok, err } from 'neverthrow';
const createUser = async (req: Request, res: Response) => {
try {
// Validate input
const validation = userSchema.safeParse(req.body);
if (!validation.success) {
return err(validation.error);
}
// Create user
const user = await db.users.create(validation.data);
if (!user) {
return err({
error: 'User Creation Failed',
error_description: 'Failed to create user in database',
});
}
// Return success
return ok(user);
} catch (error) {
return err(error);
}
};
router.post('/users', (req, res) => {
handleEndpointResult(req, res, createUser);
});Swagger Documentation
Access your API documentation through multiple endpoints:
- Default theme:
/${swaggerPath} - Theme-specific:
/${swaggerPath}/{theme} - Instance-specific JSON:
/${swaggerPath}/{theme}/{instance}/swagger.json
Available themes:
- classic (default)
- dark
- material
- monokai
- muted
- newspaper
- outline
- shadow
Development
- Clone the repository
Install dependencies:
pnpm installBuild the project:
pnpm build
Version Management
This project uses Bumpp for version management. See BUMPP.md for detailed instructions.
Contributing
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
5 months ago
5 months ago