ionian/src/util/configRW.ts
2023-06-01 14:18:53 +09:00

51 lines
1.7 KiB
TypeScript

import { existsSync, promises as fs, readFileSync, writeFileSync } from "fs";
import { validate } from "jsonschema";
export class ConfigManager<T> {
path: string;
default_config: T;
config: T | null;
schema: object;
constructor(path: string, default_config: T, schema: object) {
this.path = path;
this.default_config = default_config;
this.config = null;
this.schema = schema;
}
get_config_file(): T {
if (this.config !== null) return this.config;
this.config = { ...this.read_config_file() };
return this.config;
}
private emptyToDefault(target: T) {
let occur = false;
for (const key in this.default_config) {
if (key === undefined || key in target) {
continue;
}
target[key] = this.default_config[key];
occur = true;
}
return occur;
}
read_config_file(): T {
if (!existsSync(this.path)) {
writeFileSync(this.path, JSON.stringify(this.default_config));
return this.default_config;
}
const ret = JSON.parse(readFileSync(this.path, { encoding: "utf8" }));
if (this.emptyToDefault(ret)) {
writeFileSync(this.path, JSON.stringify(ret));
}
const result = validate(ret, this.schema);
if (!result.valid) {
throw new Error(result.toString());
}
return ret;
}
async write_config_file(new_config: T) {
this.config = new_config;
await fs.writeFile(`${this.path}.temp`, JSON.stringify(new_config));
await fs.rename(`${this.path}.temp`, this.path);
}
}