import * as fs from 'fs'; import ConfigFileMissingError from '../errors/config_file_missing.error'; import ConfigProfileError from '../errors/config_profile_missing.error'; import ConfigFileFormatError from '../errors/config_file_format.error'; import Config004 from './config.0.0.4'; const HOME = require('os').homedir(); const CONFIG_FILE_NAME = '.telmeconfig'; const FILEPATH = `${HOME}/${CONFIG_FILE_NAME}`; export enum EConfigVersions { V004 = '0.0.4', V005 = '0.0.5' } const CURRENT_CONFIG_VERSION = EConfigVersions.V005; export default class Config { static APP_NAME = 'telme'; static CURRENT_CONFIG_VERSION = CURRENT_CONFIG_VERSION; static DEFAULT_TASK_MESSAGE_TEMPLATE = '*Task:*\n\n```sh\n%cmd%\n```\nHas finished.\n*Errors*:\n %errors%'; private config: IConfig; constructor() { const file = this.readConfigFile(); const parsed = this.parseConfig(file); if (parsed.originalConfigVersion != CURRENT_CONFIG_VERSION) { this.writeConfigToFile(parsed.config); } this.config = parsed.config; } static getConfig(profile: string = 'default'): IProfileConfig { return singleton.getConfig(profile); } static generateProfileTemplate(): IProfileConfig { return { chat_id: null, task_message_template: Config.DEFAULT_TASK_MESSAGE_TEMPLATE, bot_token: null } } static getFullConfig(): IConfig { return singleton.config; } static async writeConfigToFile(config: IConfig) { return singleton.writeConfigToFile(config); } private getConfig(profile: string): IProfileConfig { if (!this.config.profiles[profile]) { throw new ConfigProfileError(`No profile named ${profile} found.`); } return this.config.profiles[profile]; } private readConfigFile(): Buffer { try { const file = fs.readFileSync(FILEPATH); return file; } catch (e) { throw new ConfigFileMissingError(''); } } private parseConfig(file: Buffer): { config: IConfig, originalConfigVersion: EConfigVersions } { try { const config = JSON.parse(file.toString()); const confVersion: EConfigVersions = config.version || EConfigVersions.V004; switch (confVersion) { case EConfigVersions.V004: return { config: Config004.parse(config), originalConfigVersion: EConfigVersions.V004 }; // Using switch to easily add more config version. If needed... default: return { config, originalConfigVersion: config.version }; } } catch (e) { throw new ConfigFileFormatError(''); } } private writeConfigToFile(config: IConfig): boolean { try { fs.writeFileSync(FILEPATH, JSON.stringify(config, null, 2)); console.log(`created config file at ${FILEPATH}`); return true; } catch (e) { return false; } } } const singleton = new Config(); export interface IProfileConfig { chat_id: string; bot_token: string; task_message_template: string; } export interface IConfig { version: EConfigVersions, profiles: { [key: string]: IProfileConfig; } }