import * as toml from 'toml'; import { resolve } from 'path'; import { readFile } from 'fs/promises'; import { Configuration } from './config.interfaces'; import { FactoryProvider, Logger, ValueProvider } from '@nestjs/common'; const CONFIG_ENV = process.env.NODE_ENV === 'production' ? 'prod' : 'dev'; const CONFIG_FILENAME = process.env.CONFIG || `config.${CONFIG_ENV}.toml`; export const configProviders = [ { provide: 'CONFIG_PATH', useValue: resolve(__dirname, '..', '..', '..', CONFIG_FILENAME), } as ValueProvider, { provide: 'DEFAULT_CONFIG', useValue: { app: { base_url: 'http://localhost:3000', host: '0.0.0.0', port: 3000, session_name: '__sid', // generate the following with crypto.randomBytes(256 / 8).toString('hex') session_secret: 'change me!', challenge_secret: 'change me!', registrations: false, }, email: { from: 'no-reply@localhost', smtp: { host: 'localhost', port: 587, secure: false, auth: { user: 'root', pass: 'root', }, }, }, jwt: { algorithm: 'RS256', issuer: 'http://localhost', expiration: 604800, }, database: { type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'root', database: 'icyauth', entities: ['dist/**/*.entity.js'], synchronize: true, migrations: ['dist/migration/*.js'], cli: { migrationsDir: 'src/migration', }, }, } as Configuration, } as ValueProvider, { provide: 'CONFIGURATION', useFactory: async ( configPath: string, defaultConfig: Configuration, ): Promise => { try { const file = await readFile(configPath, { encoding: 'utf-8' }); return { ...defaultConfig, ...JSON.parse(JSON.stringify(toml.parse(file))), }; } catch (e: unknown) { Logger.error('Failed to load configuration:', (e as Error).message); return defaultConfig; } }, inject: ['CONFIG_PATH', 'DEFAULT_CONFIG'], } as FactoryProvider, ];