5.8 KiB
5.8 KiB
@stock-bot/config
A robust, type-safe configuration library for the Stock Bot application. Built with Zod for validation and supports multiple configuration sources with proper precedence.
Features
- Type-safe configuration with Zod schemas
- Multiple configuration sources: JSON files and environment variables
- Environment-specific overrides (development, test, production)
- Dynamic provider configurations
- No circular dependencies - designed to be used by all other libraries
- Clear error messages with validation
- Runtime configuration updates (useful for testing)
- Singleton pattern for global configuration access
Installation
bun add @stock-bot/config
Usage
Basic Usage
import { initializeConfig, getConfig } from '@stock-bot/config';
// Initialize configuration (call once at app startup)
await initializeConfig();
// Get configuration
const config = getConfig();
console.log(config.database.postgres.host);
// Use convenience functions
import { getDatabaseConfig, isProduction } from '@stock-bot/config';
const dbConfig = getDatabaseConfig();
if (isProduction()) {
// Production-specific logic
}
Custom Configuration
import { ConfigManager } from '@stock-bot/config';
import { z } from 'zod';
// Define your schema
const myConfigSchema = z.object({
app: z.object({
name: z.string(),
version: z.string(),
}),
features: z.object({
enableBeta: z.boolean().default(false),
}),
});
// Create config manager
const configManager = new ConfigManager({
configPath: './my-config',
});
// Initialize with schema
const config = await configManager.initialize(myConfigSchema);
Provider-Specific Configuration
import { getProviderConfig } from '@stock-bot/config';
// Get provider configuration
const eodConfig = getProviderConfig('eod');
console.log(eodConfig.apiKey);
// Check if provider is enabled
if (eodConfig.enabled) {
// Use EOD provider
}
Environment Variables
Environment variables are loaded with the STOCKBOT_ prefix and follow a naming convention:
# Database configuration
STOCKBOT_DATABASE_POSTGRES_HOST=localhost
STOCKBOT_DATABASE_POSTGRES_PORT=5432
# Provider configuration
STOCKBOT_PROVIDERS_EOD_API_KEY=your_api_key
STOCKBOT_PROVIDERS_EOD_ENABLED=true
# Service configuration
STOCKBOT_SERVICE_PORT=3000
STOCKBOT_LOGGING_LEVEL=debug
Configuration Precedence
Configuration is loaded in the following order (later sources override earlier ones):
config/default.json- Base configurationconfig/{environment}.json- Environment-specific overrides- Environment variables - Highest priority
Advanced Usage
import { getConfigManager } from '@stock-bot/config';
const manager = getConfigManager();
// Get specific value by path
const port = manager.getValue<number>('service.port');
// Check if configuration exists
if (manager.has('providers.ib')) {
// IB provider is configured
}
// Update configuration at runtime (useful for testing)
manager.set({
logging: {
level: 'debug'
}
});
// Create typed getter
const getQueueConfig = manager.createTypedGetter(queueConfigSchema);
const queueConfig = getQueueConfig();
Configuration Schema
The library provides pre-defined schemas for common configurations:
Base Configuration
environment- Current environment (development/test/production)name- Application nameversion- Application versiondebug- Debug mode flag
Service Configuration
name- Service nameport- Service porthost- Service hosthealthCheckPath- Health check endpointcors- CORS configuration
Database Configuration
postgres- PostgreSQL configurationquestdb- QuestDB configurationmongodb- MongoDB configurationdragonfly- Dragonfly/Redis configuration
Provider Configuration
eod- EOD Historical Data providerib- Interactive Brokers providerqm- QuoteMedia provideryahoo- Yahoo Finance provider
Testing
import { resetConfig, initializeConfig } from '@stock-bot/config';
beforeEach(() => {
resetConfig();
});
test('custom config', async () => {
process.env.NODE_ENV = 'test';
process.env.STOCKBOT_SERVICE_PORT = '4000';
await initializeConfig();
const config = getConfig();
expect(config.service.port).toBe(4000);
});
Custom Loaders
You can create custom configuration loaders:
import { ConfigLoader } from '@stock-bot/config';
class ApiConfigLoader implements ConfigLoader {
readonly priority = 75; // Between file (50) and env (100)
async load(): Promise<Record<string, unknown>> {
// Fetch configuration from API
const response = await fetch('https://api.example.com/config');
return response.json();
}
}
// Use custom loader
const configManager = new ConfigManager({
loaders: [
new FileLoader('./config', 'production'),
new ApiConfigLoader(),
new EnvLoader('STOCKBOT_'),
],
});
Error Handling
The library provides specific error types:
import { ConfigError, ConfigValidationError } from '@stock-bot/config';
try {
await initializeConfig();
} catch (error) {
if (error instanceof ConfigValidationError) {
console.error('Validation failed:', error.errors);
} else if (error instanceof ConfigError) {
console.error('Configuration error:', error.message);
}
}
Best Practices
- Initialize once: Call
initializeConfig()once at application startup - Use schemas: Always define and validate configurations with Zod schemas
- Environment variables: Use the
STOCKBOT_prefix for all env vars - Type safety: Leverage TypeScript types from the schemas
- Testing: Reset configuration between tests with
resetConfig()
License
MIT