config.ts (2553B)
1 import { Type, type Static } from '@sinclair/typebox'; 2 import { Value } from '@sinclair/typebox/value'; 3 import fs from 'node:fs'; 4 import YAML from 'yaml'; 5 6 // The config schema 7 const ConfigSchema = Type.Object({ 8 homeserverUrl: Type.String(), 9 accessToken: Type.String(), 10 masMode: Type.Boolean(), 11 meilisearch: Type.Object({ 12 host: Type.String(), 13 masterKey: Type.String() 14 }) 15 }); 16 17 export type ConfigSchema = Static<typeof ConfigSchema>; 18 19 // A config loader with strict schema types using typebox 20 export default class Config { 21 private config: ConfigSchema; 22 23 constructor() { 24 // Load the config from the env and use the config for the rest. 25 // Then verify the config against the schema 26 const config = { 27 homeserverUrl: process.env.HOMESERVER_URL, 28 accessToken: process.env.ACCESS_TOKEN, 29 masMode: process.env.MAS_MODE === 'true', 30 }; 31 32 // load the config file async and merge it with the env 33 const configFile = fs.readFileSync('config.yaml', 'utf-8'); 34 const configFromFile = YAML.parse(configFile); 35 const mergedConfig = { 36 ...config, 37 ...configFromFile 38 }; 39 40 // Verify the config against the schema 41 if (!Value.Check(ConfigSchema, mergedConfig)) { 42 throw new Error('Invalid config'); 43 } 44 this.config = mergedConfig; 45 } 46 47 public get homeserverUrl(): string { 48 return this.config.homeserverUrl; 49 } 50 51 public get accessToken(): string { 52 return this.config.accessToken; 53 } 54 55 56 public get masMode(): boolean { 57 return this.config.masMode; 58 } 59 60 public set homeserverUrl(value: string) { 61 this.config.homeserverUrl = value; 62 this.save(); 63 } 64 65 public set accessToken(value: string) { 66 this.config.accessToken = value; 67 this.save(); 68 } 69 70 public set masMode(value: boolean) { 71 this.config.masMode = value; 72 this.save(); 73 } 74 75 public get meiliSearchHost(): string { 76 return this.config.meilisearch.host; 77 } 78 79 public set meiliSearchHost(value: string) { 80 this.config.meilisearch.host = value; 81 this.save(); 82 } 83 84 public get meiliSearchKey(): string { 85 return this.config.meilisearch.masterKey; 86 } 87 88 public set meiliSearchKey(value: string) { 89 this.config.meilisearch.masterKey = value; 90 this.save(); 91 } 92 93 public save() { 94 fs.writeFileSync('config.yaml', YAML.stringify(this.config)); 95 } 96 }