/* * Copyright (C) Sapphirecode - All Rights Reserved * This file is part of console-app which is released under MIT. * See file 'LICENSE' for full license details. * Created by Timo Hocker <timo@scode.ovh>, May 2020 */ /* eslint-disable no-await-in-loop */ import { dirname, join } from 'path'; import fs from 'fs-extra'; import { run_regex } from '@sapphirecode/utilities'; import hjson from 'hjson'; import { OptionValue, Option } from '../Option'; import { ErrorCallback } from '../ErrorCallback'; import { OptionSource } from './OptionSource'; export class ConfigSource extends OptionSource { private _config_files: string[]; public constructor (config_files: string[], error_callback?:ErrorCallback) { super (error_callback); this._config_files = config_files; } private async read_json_file (file: string): Promise<Record<string, unknown>> { if (!await fs.pathExists (file)) return {}; const dir = dirname (file); const contents = await fs.readFile (file, 'utf-8'); const obj: Record<string, unknown> = {}; const regex = /^#include (?<f>.+)/gmui; const includes: string[] = []; run_regex (regex, contents, (res: {groups:{f:string}}) => { includes.push (join (dir, res.groups.f)); }); for (const inc of includes) { const data = await this.read_json_file (inc); for (const key of Object.keys (data)) obj[key] = data[key]; } const config = hjson.parse (contents); for (const key of Object.keys (config)) obj[key] = config[key]; return obj; } public async parse (opt: Option, val: OptionValue): Promise<void> { const data: Record<string, unknown> = {}; for (const f of this._config_files) { try { const json = await this.read_json_file (f); for (const key of Object.keys (json)) data[key] = json[key]; } catch (e) { if (typeof this.error_callback !== 'undefined') this.error_callback ('*', `config file: ${f}`, e); continue; } } const keys = Object.keys (data); if (keys.includes (opt.name)) await val.assign_arg (opt, data[opt.name]); } }