Files
order_site/apps/backend/src/services/config/app-config-store.ts
T

106 lines
2.5 KiB
TypeScript

import fs from 'node:fs'
import { listAppConfigEntries, upsertAppConfigEntry } from '../../repositories/app-config-repo.js'
import { readJsonFile } from '../../utils/json-file-store.js'
type NormalizeJsonValue<T> = (value: unknown) => T
const configCache = new Map<string, unknown>()
let databaseCacheLoaded = false
export function hasAppConfigEntry(configKey: string, legacyFilePath = '') {
const key = normalizeConfigKey(configKey)
if (configCache.has(key)) {
return true
}
return Boolean(legacyFilePath) && fs.existsSync(legacyFilePath)
}
export function readAppConfigEntry<T>({
configKey,
legacyFilePath,
fallback,
normalize,
}: {
configKey: string
legacyFilePath?: string | undefined
fallback: T | (() => T)
normalize: NormalizeJsonValue<T>
}): T {
const key = normalizeConfigKey(configKey)
if (configCache.has(key)) {
return normalize(cloneJsonValue(configCache.get(key)))
}
if (!databaseCacheLoaded && legacyFilePath) {
return readJsonFile(legacyFilePath, fallback, normalize)
}
return normalize(resolveFallback(fallback))
}
export async function saveAppConfigEntry<T>({
configKey,
value,
legacyFilePath,
normalize,
}: {
configKey: string
value: unknown
legacyFilePath?: string | undefined
normalize: NormalizeJsonValue<T>
}): Promise<T> {
const key = normalizeConfigKey(configKey)
const normalized = normalize(value)
await upsertAppConfigEntry({
configKey: key,
configJson: normalized,
sourceFilePath: legacyFilePath,
migratedFromFile: false,
timestamp: new Date().toISOString(),
})
configCache.set(key, cloneJsonValue(normalized))
return normalized
}
export async function loadAppConfigCacheFromDatabase() {
const rows = await listAppConfigEntries()
configCache.clear()
for (const row of rows) {
const key = normalizeConfigKey(row.config_key)
if (!key) {
continue
}
configCache.set(key, cloneJsonValue(row.config_json))
}
databaseCacheLoaded = true
}
export function setAppConfigCacheEntry(configKey: string, value: unknown) {
const key = normalizeConfigKey(configKey)
if (!key) {
return
}
configCache.set(key, cloneJsonValue(value))
}
function normalizeConfigKey(value: unknown) {
return String(value || '').trim()
}
function resolveFallback<T>(fallback: T | (() => T)): T {
return typeof fallback === 'function' ? (fallback as () => T)() : fallback
}
function cloneJsonValue<T>(value: T): T {
return JSON.parse(JSON.stringify(value ?? null)) as T
}