UNPKG

@syngrisi/syngrisi

Version:
145 lines (123 loc) 4.28 kB
/* eslint-disable dot-notation */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { AppSettings as AppSettingsModel } from '@models'; import initialAppSettings from '../../../seeds/initialAppSettings.json'; class AppSettings { private model: any; public cache: any; private lastFetch: number = 0; private TTL = 30 * 1000; // 30 seconds constructor() { this.model = AppSettingsModel; this.cache = null; // Initialize cache as null to indicate uninitialized state } async init() { await this.refreshCache(); return this; } private async refreshCache() { this.cache = await this.model.find().lean().exec(); this.lastFetch = Date.now(); } private async ensureInitialized() { if (!this.cache) { // If not initialized, try to initialize (lazy init fallback, though explicit init is preferred) await this.refreshCache(); } // Check TTL if (Date.now() - this.lastFetch > this.TTL) { await this.refreshCache(); } } async count(): Promise<number> { await this.ensureInitialized(); return this.model.countDocuments().exec(); } async loadInitialFromFile(): Promise<void> { await this.ensureInitialized(); for (const setting of initialAppSettings) { await this.model.updateOne( { name: setting.name }, { $setOnInsert: setting }, { upsert: true } ); } await this.refreshCache(); } async get(name: string): Promise<any> { await this.ensureInitialized(); return this.cache.find((x: any) => x.name === name) || (this.model.findOne({ name }).exec()); } async set(name: string, value: any): Promise<void> { await this.ensureInitialized(); const item = await this.model.findOneAndUpdate( { name }, { value }, { new: true } ).lean().exec(); if (!item) { throw new Error(`Setting '${name}' not found`); } // Update local cache immediately const cachedItem = this.cache.find((x: any) => x.name === name); if (cachedItem) { cachedItem['value'] = item.value; } } async enable(name: string): Promise<void> { await this.ensureInitialized(); const item = await this.model.findOneAndUpdate( { name }, { enabled: true }, { new: true } ).lean().exec(); if (!item) { throw new Error(`Setting '${name}' not found`); } const cachedItem = this.cache.find((x: any) => x.name === name); if (cachedItem) { cachedItem['enabled'] = true; } } async disable(name: string): Promise<void> { await this.ensureInitialized(); const item = await this.model.findOneAndUpdate( { name }, { enabled: false }, { new: true } ).lean().exec(); if (!item) { throw new Error(`Setting '${name}' not found`); } const cachedItem = this.cache.find((x: any) => x.name === name); if (cachedItem) { cachedItem['enabled'] = false; } } async isAuthEnabled(): Promise<boolean> { await this.ensureInitialized(); // Prefer explicit override to force-enable auth when set const envOverride = process.env.SYNGRISI_AUTH_OVERRIDE; if (typeof envOverride !== 'undefined') { if (envOverride === 'true') { return true; } // Allow DB setting to win when override is explicitly false } const envAuth = process.env.SYNGRISI_AUTH; if (envAuth === 'true') { return true; } if (envAuth === 'false') { return false; } return (await this.get('authentication'))?.value === 'true'; } async isFirstRun(): Promise<boolean> { await this.ensureInitialized(); return (await this.get('first_run'))?.value === 'true'; } } const appSettings = new AppSettings(); export { AppSettings, appSettings };