@syngrisi/syngrisi
Version:
Syngrisi - Visual Testing Tool
145 lines (123 loc) • 4.28 kB
text/typescript
/* 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 };