forked from Nova-reward/Nova-Rewards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenv.ts
More file actions
85 lines (69 loc) · 2.96 KB
/
Copy pathenv.ts
File metadata and controls
85 lines (69 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { z } from 'zod';
// Define the environment variable schema
const envSchema = z.object({
// Server
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
PORT: z.string().transform(Number).default('3000'),
// Database
DATABASE_URL: z.string().min(1, 'DATABASE_URL is required'),
DATABASE_SSL: z.enum(['true', 'false']).default('false'),
// JWT
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 characters'),
JWT_EXPIRES_IN: z.string().default('7d'),
// Stellar
STELLAR_NETWORK: z.enum(['testnet', 'mainnet']).default('testnet'),
HORIZON_URL: z.string().url('HORIZON_URL must be a valid URL').default('https://horizon-testnet.stellar.org'),
ISSUER_PUBLIC: z.string().min(1, 'ISSUER_PUBLIC is required'),
ISSUER_SECRET: z.string().min(1, 'ISSUER_SECRET is required'),
// Redis
REDIS_URL: z.string().url('REDIS_URL must be a valid URL').default('redis://localhost:6379'),
REDIS_CACHE_TTL: z.string().transform(Number).default('30'),
// Rate Limiting
RATE_LIMIT_STRICT: z.string().transform(Number).default('10'),
RATE_LIMIT_STANDARD: z.string().transform(Number).default('60'),
RATE_LIMIT_WINDOW_MS: z.string().transform(Number).default('60000'),
// Multi-Signature
COSIGNER_SECRET: z.string().optional(),
MULTISIG_THRESHOLD_USD: z.string().transform(Number).default('10000'),
// Webhooks
WEBHOOK_RETRY_COUNT: z.string().transform(Number).default('5'),
WEBHOOK_TIMEOUT_MS: z.string().transform(Number).default('10000'),
// Feature Flags
ENABLE_METRICS: z.enum(['true', 'false']).default('true'),
ENABLE_LOGGING: z.enum(['true', 'false']).default('true'),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
// Security
CORS_ORIGIN: z.string().default('*'),
ALLOWED_ORIGINS: z.string().optional(),
});
// Infer the type from the schema
export type EnvConfig = z.infer<typeof envSchema>;
// Validate and export the config
function validateEnv(): EnvConfig {
try {
const validated = envSchema.parse(process.env);
return validated;
} catch (error) {
if (error instanceof z.ZodError) {
console.error('❌ Environment variable validation failed:');
error.errors.forEach((err) => {
console.error(` - ${err.path.join('.')}: ${err.message}`);
});
} else {
console.error('❌ Failed to validate environment variables:', error);
}
process.exit(1);
}
}
// Single source of truth - no direct process.env access
export const config = validateEnv();
// Export the schema for use in .env.example generation
export { envSchema };
// Helper to get environment name
export const isProduction = config.NODE_ENV === 'production';
export const isDevelopment = config.NODE_ENV === 'development';
export const isTest = config.NODE_ENV === 'test';
// Helper to check if feature is enabled
export const isFeatureEnabled = (feature: keyof Pick<EnvConfig, 'ENABLE_METRICS' | 'ENABLE_LOGGING'>): boolean => {
return config[feature] === 'true';
};