config.ts 2.43 KB
Newer Older
silver47gin's avatar
silver47gin committed
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 86 87 88 89 90 91 92 93 94 95 96
import fs from "fs";
import os from "os";
import path from "path";
import { promisify } from "util";
import { logger } from "./logger";

const configDirName = ".HelloWorld";

/**
 * 用来管理配置文件
 * 方便按照模块存储配置文件到$HOMEDIR/${configDirName}文件夹中
 */
export class ConfigManager<T extends {}> {
  module: string;
  configDir: string;
  configFile: string;
  config: T;
  defaultValue: T;

  constructor(module: string, defaultValue: T) {
    this.module = module;
    this.defaultValue = defaultValue;
    this.config = defaultValue;
    this.configDir = path.join(os.homedir(), configDirName);
    this.configFile = path.join(this.configDir, `${this.module}.json`);
  }

  static create = async <T extends {}>(module: string, defaultValue: T) => {
    const c = new ConfigManager<T>(module, defaultValue);
    await c.init();
    return c;
  };

  init = async () => {
    await this.sureConfig();
    await this.load();
  };

  sureConfig = async () => {
    try {
      await promisify(fs.access)(this.configDir);
    } catch (error) {
      logger.log(`配置文件目录${this.configDir}不存在`);
      logger.log(`创建目录`);
      await promisify(fs.mkdir)(this.configDir, { recursive: true });
    }
    try {
      await promisify(fs.access)(this.configFile);
    } catch (error) {
      logger.log(`配置文件${this.configFile}不存在`);
      logger.log(`创建配置文件`);
      await promisify(fs.writeFile)(
        this.configFile,
        JSON.stringify(this.defaultValue, null, 4),
        { flag: "w" }
      );
    }
  };

  load = async () => {
    try {
      this.config = JSON.parse(
        (await promisify(fs.readFile)(this.configFile)).toString()
      );
    } catch (error) {
      logger.log(`读取${this.module}配置文件失败`);
      this.config = this.defaultValue;
    }
  };

  save = async () => {
    try {
      await promisify(fs.writeFile)(
        this.configFile,
        JSON.stringify(this.config, null, 4),
        { flag: "w" }
      );
    } catch (error) {
      logger.log(`写入${this.module}配置文件失败`);
    }
  };

  setValue = async <K extends keyof T>(key: K, value: T[K]) => {
    this.config[key] = value;
    await this.save();
  };

  setValues = async (changes: Partial<T>) => {
    this.config = { ...this.config, ...changes };
    await this.save();
  };

  getValues = () => this.config;
}

export const mainConfigManager = new ConfigManager("main", {});