final config changes
This commit is contained in:
parent
718ace05b0
commit
19f05a2a69
7 changed files with 311 additions and 51 deletions
|
|
@ -8,7 +8,7 @@ This guide shows how to use the envalid-based configuration system in the Stock
|
|||
import { databaseConfig, loggingConfig, riskConfig, dataProvidersConfig } from '@stock-bot/config';
|
||||
|
||||
// Access individual values
|
||||
console.log(`Database: ${databaseConfig.DB_HOST}:${databaseConfig.DB_PORT}`);
|
||||
console.log(`Database: ${databaseConfig.POSTGRES_HOST}:${databaseConfig.POSTGRES_PORT}`);
|
||||
console.log(`Log level: ${loggingConfig.LOG_LEVEL}`);
|
||||
console.log(`Max position size: ${riskConfig.RISK_MAX_POSITION_SIZE}`);
|
||||
```
|
||||
|
|
@ -68,9 +68,9 @@ import type { DatabaseConfig, LoggingConfig, RiskConfig } from '@stock-bot/confi
|
|||
function setupDatabase(config: DatabaseConfig) {
|
||||
// TypeScript knows all the available properties
|
||||
return {
|
||||
host: config.DB_HOST,
|
||||
port: config.DB_PORT, // number
|
||||
ssl: config.DB_SSL, // boolean
|
||||
host: config.POSTGRES_HOST,
|
||||
port: config.POSTGRES_PORT, // number
|
||||
ssl: config.POSTGRES_SSL, // boolean
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -15,15 +15,19 @@ import {
|
|||
} from './core';
|
||||
|
||||
import {
|
||||
// Database configuration
|
||||
// PostgreSQL configuration
|
||||
postgresConfig,
|
||||
PostgresConfig,
|
||||
POSTGRES_HOST,
|
||||
POSTGRES_PORT,
|
||||
POSTGRES_DATABASE,
|
||||
POSTGRES_USERNAME,
|
||||
POSTGRES_PASSWORD,
|
||||
// Backwards compatibility
|
||||
databaseConfig,
|
||||
DatabaseConfig,
|
||||
DB_HOST,
|
||||
DB_PORT,
|
||||
DB_NAME,
|
||||
DB_USER,
|
||||
DB_PASSWORD,
|
||||
} from './database';
|
||||
} from './postgres';
|
||||
|
||||
import {
|
||||
// QuestDB configuration
|
||||
|
|
@ -119,18 +123,17 @@ function basicUsageExample() {
|
|||
// Get the current environment
|
||||
const env = getEnvironment();
|
||||
console.log(`Current environment: ${env}`);
|
||||
|
||||
// Access individual configuration values
|
||||
console.log(`Database host: ${DB_HOST}`);
|
||||
console.log(`Database port: ${DB_PORT}`);
|
||||
console.log(`Database host: ${POSTGRES_HOST}`);
|
||||
console.log(`Database port: ${POSTGRES_PORT}`);
|
||||
console.log(`Log level: ${LOG_LEVEL}`);
|
||||
|
||||
// Access full configuration objects
|
||||
// Access full database config objects
|
||||
console.log(`Full database config:`, {
|
||||
host: databaseConfig.DB_HOST,
|
||||
port: databaseConfig.DB_PORT,
|
||||
name: databaseConfig.DB_NAME,
|
||||
ssl: databaseConfig.DB_SSL,
|
||||
host: postgresConfig.POSTGRES_HOST,
|
||||
port: postgresConfig.POSTGRES_PORT,
|
||||
name: postgresConfig.POSTGRES_DATABASE,
|
||||
ssl: postgresConfig.POSTGRES_SSL,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -142,27 +145,27 @@ async function databaseConnectionExample() {
|
|||
|
||||
try {
|
||||
// Use the database configuration to create a connection string
|
||||
const connectionString = `postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}`;
|
||||
const connectionString = `postgresql://${POSTGRES_USERNAME}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DATABASE}`;
|
||||
|
||||
console.log('Database connection settings:');
|
||||
console.log(`- Host: ${databaseConfig.DB_HOST}`);
|
||||
console.log(`- Port: ${databaseConfig.DB_PORT}`);
|
||||
console.log(`- Database: ${databaseConfig.DB_NAME}`);
|
||||
console.log(`- SSL enabled: ${databaseConfig.DB_SSL}`);
|
||||
console.log(`- Pool max connections: ${databaseConfig.DB_POOL_MAX}`);
|
||||
console.log(`- Query timeout: ${databaseConfig.DB_QUERY_TIMEOUT}ms`);
|
||||
console.log(`- Host: ${databaseConfig.POSTGRES_HOST}`);
|
||||
console.log(`- Port: ${databaseConfig.POSTGRES_PORT}`);
|
||||
console.log(`- Database: ${databaseConfig.POSTGRES_NAME}`);
|
||||
console.log(`- SSL enabled: ${databaseConfig.POSTGRES_SSL}`);
|
||||
console.log(`- Pool max connections: ${databaseConfig.POSTGRES_POOL_MAX}`);
|
||||
console.log(`- Query timeout: ${databaseConfig.POSTGRES_QUERY_TIMEOUT}ms`);
|
||||
|
||||
// Example pool configuration
|
||||
const poolConfig = {
|
||||
host: databaseConfig.DB_HOST,
|
||||
port: databaseConfig.DB_PORT,
|
||||
database: databaseConfig.DB_NAME,
|
||||
user: databaseConfig.DB_USER,
|
||||
password: databaseConfig.DB_PASSWORD,
|
||||
ssl: databaseConfig.DB_SSL,
|
||||
min: databaseConfig.DB_POOL_MIN,
|
||||
max: databaseConfig.DB_POOL_MAX,
|
||||
idleTimeoutMillis: databaseConfig.DB_POOL_IDLE_TIMEOUT,
|
||||
host: databaseConfig.POSTGRES_HOST,
|
||||
port: databaseConfig.POSTGRES_PORT,
|
||||
database: databaseConfig.POSTGRES_NAME,
|
||||
user: databaseConfig.POSTGRES_USER,
|
||||
password: databaseConfig.POSTGRES_PASSWORD,
|
||||
ssl: databaseConfig.POSTGRES_SSL,
|
||||
min: databaseConfig.POSTGRES_POOL_MIN,
|
||||
max: databaseConfig.POSTGRES_POOL_MAX,
|
||||
idleTimeoutMillis: databaseConfig.POSTGRES_POOL_IDLE_TIMEOUT,
|
||||
};
|
||||
|
||||
console.log('Pool configuration:', poolConfig);
|
||||
|
|
@ -375,7 +378,7 @@ function configurationValidationExample() {
|
|||
}
|
||||
|
||||
// Validate database connection settings
|
||||
if (databaseConfig.DB_POOL_MAX < databaseConfig.DB_POOL_MIN) {
|
||||
if (databaseConfig.POSTGRES_POOL_MAX < databaseConfig.POSTGRES_POOL_MIN) {
|
||||
throw new ConfigurationError('Database max pool size must be greater than min pool size');
|
||||
}
|
||||
|
||||
|
|
@ -626,16 +629,16 @@ function multiDatabaseServiceExample() {
|
|||
|
||||
// PostgreSQL for operational data
|
||||
postgresql: {
|
||||
host: databaseConfig.DB_HOST,
|
||||
port: databaseConfig.DB_PORT,
|
||||
database: databaseConfig.DB_NAME,
|
||||
username: databaseConfig.DB_USER,
|
||||
password: databaseConfig.DB_PASSWORD,
|
||||
ssl: databaseConfig.DB_SSL,
|
||||
host: databaseConfig.POSTGRES_HOST,
|
||||
port: databaseConfig.POSTGRES_PORT,
|
||||
database: databaseConfig.POSTGRES_NAME,
|
||||
username: databaseConfig.POSTGRES_USER,
|
||||
password: databaseConfig.POSTGRES_PASSWORD,
|
||||
ssl: databaseConfig.POSTGRES_SSL,
|
||||
pool: {
|
||||
min: databaseConfig.DB_POOL_MIN,
|
||||
max: databaseConfig.DB_POOL_MAX,
|
||||
idleTimeout: databaseConfig.DB_POOL_IDLE_TIMEOUT,
|
||||
min: databaseConfig.POSTGRES_POOL_MIN,
|
||||
max: databaseConfig.POSTGRES_POOL_MAX,
|
||||
idleTimeout: databaseConfig.POSTGRES_POOL_IDLE_TIMEOUT,
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -712,10 +715,10 @@ function serviceConfigurationExample() {
|
|||
environment: getEnvironment(),
|
||||
},
|
||||
database: {
|
||||
host: databaseConfig.DB_HOST,
|
||||
port: databaseConfig.DB_PORT,
|
||||
name: databaseConfig.DB_NAME,
|
||||
ssl: databaseConfig.DB_SSL,
|
||||
host: databaseConfig.POSTGRES_HOST,
|
||||
port: databaseConfig.POSTGRES_PORT,
|
||||
name: databaseConfig.POSTGRES_NAME,
|
||||
ssl: databaseConfig.POSTGRES_SSL,
|
||||
}, logging: {
|
||||
level: loggingConfig.LOG_LEVEL,
|
||||
console: loggingConfig.LOG_CONSOLE,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
export * from './core';
|
||||
|
||||
// Database configurations
|
||||
export * from './database';
|
||||
export * from './postgres';
|
||||
export * from './questdb';
|
||||
export * from './mongodb';
|
||||
export * from './dragonfly';
|
||||
|
|
|
|||
54
libs/config/src/postgres.ts
Normal file
54
libs/config/src/postgres.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* PostgreSQL configuration using envalid
|
||||
*/
|
||||
import { cleanEnv, str, port, bool, num } from 'envalid';
|
||||
|
||||
/**
|
||||
* PostgreSQL configuration with validation and defaults
|
||||
*/
|
||||
export const postgresConfig = cleanEnv(process.env, {
|
||||
// PostgreSQL Connection Settings
|
||||
POSTGRES_HOST: str({ default: 'localhost', desc: 'PostgreSQL host' }),
|
||||
POSTGRES_PORT: port({ default: 5432, desc: 'PostgreSQL port' }),
|
||||
POSTGRES_DATABASE: str({ default: 'stockbot', desc: 'PostgreSQL database name' }),
|
||||
POSTGRES_USERNAME: str({ default: 'stockbot', desc: 'PostgreSQL username' }),
|
||||
POSTGRES_PASSWORD: str({ default: '', desc: 'PostgreSQL password' }),
|
||||
|
||||
// Connection Pool Settings
|
||||
POSTGRES_POOL_MIN: num({ default: 2, desc: 'Minimum pool connections' }),
|
||||
POSTGRES_POOL_MAX: num({ default: 10, desc: 'Maximum pool connections' }),
|
||||
POSTGRES_POOL_IDLE_TIMEOUT: num({ default: 30000, desc: 'Pool idle timeout in ms' }),
|
||||
|
||||
// SSL Configuration
|
||||
POSTGRES_SSL: bool({ default: false, desc: 'Enable SSL for PostgreSQL connection' }),
|
||||
POSTGRES_SSL_REJECT_UNAUTHORIZED: bool({ default: true, desc: 'Reject unauthorized SSL certificates' }),
|
||||
|
||||
// Additional Settings
|
||||
POSTGRES_QUERY_TIMEOUT: num({ default: 30000, desc: 'Query timeout in ms' }),
|
||||
POSTGRES_CONNECTION_TIMEOUT: num({ default: 5000, desc: 'Connection timeout in ms' }),
|
||||
POSTGRES_STATEMENT_TIMEOUT: num({ default: 30000, desc: 'Statement timeout in ms' }),
|
||||
POSTGRES_LOCK_TIMEOUT: num({ default: 10000, desc: 'Lock timeout in ms' }),
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: num({ default: 60000, desc: 'Idle in transaction timeout in ms' }),
|
||||
});
|
||||
|
||||
// Export typed configuration object
|
||||
export type PostgresConfig = typeof postgresConfig;
|
||||
|
||||
// Export individual config values for convenience
|
||||
export const {
|
||||
POSTGRES_HOST,
|
||||
POSTGRES_PORT,
|
||||
POSTGRES_DATABASE,
|
||||
POSTGRES_USERNAME,
|
||||
POSTGRES_PASSWORD,
|
||||
POSTGRES_POOL_MIN,
|
||||
POSTGRES_POOL_MAX,
|
||||
POSTGRES_POOL_IDLE_TIMEOUT,
|
||||
POSTGRES_SSL,
|
||||
POSTGRES_SSL_REJECT_UNAUTHORIZED,
|
||||
POSTGRES_QUERY_TIMEOUT,
|
||||
POSTGRES_CONNECTION_TIMEOUT,
|
||||
POSTGRES_STATEMENT_TIMEOUT,
|
||||
POSTGRES_LOCK_TIMEOUT,
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
|
||||
} = postgresConfig;
|
||||
85
libs/config/test-config.mjs
Normal file
85
libs/config/test-config.mjs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import {
|
||||
databaseConfig,
|
||||
questdbConfig,
|
||||
mongodbConfig,
|
||||
dragonflyConfig,
|
||||
prometheusConfig,
|
||||
grafanaConfig,
|
||||
lokiConfig,
|
||||
loggingConfig
|
||||
} from './dist/index.js';
|
||||
|
||||
// Set test environment variables
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.PORT = '3001';
|
||||
|
||||
// Database configs
|
||||
process.env.DB_HOST = 'localhost';
|
||||
process.env.DB_PORT = '5432';
|
||||
process.env.DB_NAME = 'test_db';
|
||||
process.env.DB_USER = 'test_user';
|
||||
process.env.DB_PASSWORD = 'test_pass';
|
||||
|
||||
// QuestDB configs
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
|
||||
// MongoDB configs
|
||||
process.env.MONGODB_HOST = 'localhost';
|
||||
process.env.MONGODB_PORT = '27017';
|
||||
process.env.MONGODB_DATABASE = 'test_db';
|
||||
|
||||
// Dragonfly configs
|
||||
process.env.DRAGONFLY_HOST = 'localhost';
|
||||
process.env.DRAGONFLY_PORT = '6379';
|
||||
|
||||
// Monitoring configs
|
||||
process.env.PROMETHEUS_HOST = 'localhost';
|
||||
process.env.PROMETHEUS_PORT = '9090';
|
||||
process.env.GRAFANA_HOST = 'localhost';
|
||||
process.env.GRAFANA_PORT = '3000';
|
||||
|
||||
// Loki configs
|
||||
process.env.LOKI_HOST = 'localhost';
|
||||
process.env.LOKI_PORT = '3100';
|
||||
|
||||
// Logging configs
|
||||
process.env.LOG_LEVEL = 'info';
|
||||
process.env.LOG_FORMAT = 'json';
|
||||
|
||||
console.log('🔍 Testing configuration modules...\n');
|
||||
|
||||
const configs = [
|
||||
{ name: 'Database', config: databaseConfig },
|
||||
{ name: 'QuestDB', config: questdbConfig },
|
||||
{ name: 'MongoDB', config: mongodbConfig },
|
||||
{ name: 'Dragonfly', config: dragonflyConfig },
|
||||
{ name: 'Prometheus', config: prometheusConfig },
|
||||
{ name: 'Grafana', config: grafanaConfig },
|
||||
{ name: 'Loki', config: lokiConfig },
|
||||
{ name: 'Logging', config: loggingConfig },
|
||||
];
|
||||
|
||||
let successful = 0;
|
||||
|
||||
for (const { name, config } of configs) {
|
||||
try {
|
||||
if (config && typeof config === 'object' && Object.keys(config).length > 0) {
|
||||
console.log(`✅ ${name}: Loaded successfully`);
|
||||
successful++;
|
||||
} else {
|
||||
console.log(`❌ ${name}: Invalid config object`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`❌ ${name}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Test Summary: ${successful}/${configs.length} modules loaded successfully`);
|
||||
|
||||
if (successful === configs.length) {
|
||||
console.log('🎉 All configuration modules working correctly!');
|
||||
} else {
|
||||
console.log('⚠️ Some configuration modules have issues.');
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
118
libs/config/validate-config.js
Normal file
118
libs/config/validate-config.js
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Configuration Validation Script
|
||||
* Tests that all configuration modules can be loaded and validated
|
||||
*/
|
||||
|
||||
// Set test environment variables
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.PORT = '3001';
|
||||
|
||||
// Database configs
|
||||
process.env.DB_HOST = 'localhost';
|
||||
process.env.DB_PORT = '5432';
|
||||
process.env.DB_NAME = 'test_db';
|
||||
process.env.DB_USER = 'test_user';
|
||||
process.env.DB_PASSWORD = 'test_pass';
|
||||
|
||||
// QuestDB configs
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
|
||||
// MongoDB configs
|
||||
process.env.MONGODB_HOST = 'localhost';
|
||||
process.env.MONGODB_PORT = '27017';
|
||||
process.env.MONGODB_DATABASE = 'test_db';
|
||||
|
||||
// Dragonfly configs
|
||||
process.env.DRAGONFLY_HOST = 'localhost';
|
||||
process.env.DRAGONFLY_PORT = '6379';
|
||||
|
||||
// Monitoring configs
|
||||
process.env.PROMETHEUS_HOST = 'localhost';
|
||||
process.env.PROMETHEUS_PORT = '9090';
|
||||
process.env.GRAFANA_HOST = 'localhost';
|
||||
process.env.GRAFANA_PORT = '3000';
|
||||
|
||||
// Loki configs
|
||||
process.env.LOKI_HOST = 'localhost';
|
||||
process.env.LOKI_PORT = '3100';
|
||||
|
||||
// Logging configs
|
||||
process.env.LOG_LEVEL = 'info';
|
||||
process.env.LOG_FORMAT = 'json';
|
||||
|
||||
try {
|
||||
console.log('🔍 Validating configuration modules...\n');
|
||||
|
||||
// Test each configuration module
|
||||
const modules = [
|
||||
{ name: 'Database', path: './dist/database.js' },
|
||||
{ name: 'QuestDB', path: './dist/questdb.js' },
|
||||
{ name: 'MongoDB', path: './dist/mongodb.js' },
|
||||
{ name: 'Dragonfly', path: './dist/dragonfly.js' },
|
||||
{ name: 'Monitoring', path: './dist/monitoring.js' },
|
||||
{ name: 'Loki', path: './dist/loki.js' },
|
||||
{ name: 'Logging', path: './dist/logging.js' },
|
||||
];
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const module of modules) {
|
||||
try {
|
||||
const config = require(module.path);
|
||||
const configKeys = Object.keys(config);
|
||||
|
||||
if (configKeys.length === 0) {
|
||||
throw new Error('No exported configuration found');
|
||||
}
|
||||
|
||||
// Try to access the main config object
|
||||
const mainConfig = config[configKeys[0]];
|
||||
if (!mainConfig || typeof mainConfig !== 'object') {
|
||||
throw new Error('Invalid configuration object');
|
||||
}
|
||||
|
||||
console.log(`✅ ${module.name}: ${configKeys.length} config(s) loaded`);
|
||||
results.push({ name: module.name, status: 'success', configs: configKeys });
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ ${module.name}: ${error.message}`);
|
||||
results.push({ name: module.name, status: 'error', error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
// Test main index exports
|
||||
try {
|
||||
const indexExports = require('./dist/index.js');
|
||||
const exportCount = Object.keys(indexExports).length;
|
||||
console.log(`\n✅ Index exports: ${exportCount} modules exported`);
|
||||
results.push({ name: 'Index', status: 'success', exports: exportCount });
|
||||
} catch (error) {
|
||||
console.log(`\n❌ Index exports: ${error.message}`);
|
||||
results.push({ name: 'Index', status: 'error', error: error.message });
|
||||
}
|
||||
|
||||
// Summary
|
||||
const successful = results.filter(r => r.status === 'success').length;
|
||||
const total = results.length;
|
||||
|
||||
console.log(`\n📊 Validation Summary:`);
|
||||
console.log(` Total modules: ${total}`);
|
||||
console.log(` Successful: ${successful}`);
|
||||
console.log(` Failed: ${total - successful}`);
|
||||
|
||||
if (successful === total) {
|
||||
console.log('\n🎉 All configuration modules validated successfully!');
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log('\n⚠️ Some configuration modules failed validation.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Validation script failed:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue