import { and, eq, inArray } from "drizzle-orm"; import { db } from "./db"; import { appConfig, mediaUsage } from "./db/schema"; export const MAINTENANCE_MODE_KEY = "maintenance_mode"; export { SITE_NAME_KEY, SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY, SITE_SETTINGS_ENTITY_ID, SITE_SETTINGS_ENTITY_TYPE, SITE_SETTINGS_FAVICON_FIELD_KEY, SITE_SETTINGS_LOGO_DARK_FIELD_KEY, SITE_SETTINGS_LOGO_LIGHT_FIELD_KEY, SITE_SETTINGS_KEY, DEFAULT_SITE_NAME, buildDefaultSiteSettings, getDefaultSiteSettingsMediaBindings, parseSiteSettingsValue, type SiteSettings, type SiteSettingsMediaBindings, } from "./site-settings"; export { MAIL_SETTINGS_KEY, buildDefaultMailSettings, parseMailSettingsValue, toMailSettingsFormValues, type MailSettings, type MailSettingsFormValues, } from "./mail-settings"; export { MARQUEE_SETTINGS_KEY, buildDefaultMarqueeSettings, parseMarqueeSettingsValue, splitMarqueeRowItems, syncMarqueeSettingsToGermanSource, type MarqueeLocaleSettings, type MarqueeSettings, } from "./marquee-settings"; import { DEFAULT_SITE_NAME, SITE_NAME_KEY, SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY, SITE_SETTINGS_ENTITY_ID, SITE_SETTINGS_ENTITY_TYPE, SITE_SETTINGS_FAVICON_FIELD_KEY, SITE_SETTINGS_LOGO_DARK_FIELD_KEY, SITE_SETTINGS_LOGO_LIGHT_FIELD_KEY, SITE_SETTINGS_KEY, buildDefaultSiteSettings, getDefaultSiteSettingsMediaBindings, parseSiteSettingsValue, type SiteSettings, type SiteSettingsMediaBindings, } from "./site-settings"; import { MAIL_SETTINGS_KEY, buildDefaultMailSettings, parseMailSettingsValue, toMailSettingsFormValues, type MailSettings, type MailSettingsFormValues, } from "./mail-settings"; import { MARQUEE_SETTINGS_KEY, buildDefaultMarqueeSettings, parseMarqueeSettingsValue, syncMarqueeSettingsToGermanSource, type MarqueeSettings, } from "./marquee-settings"; async function getAppConfigValue(key: string): Promise { const rows = await db .select({ value: appConfig.value }) .from(appConfig) .where(eq(appConfig.key, key)) .limit(1); return rows[0]?.value; } async function upsertAppConfigValue(key: string, value: string): Promise { await db .insert(appConfig) .values({ key, value }) .onConflictDoUpdate({ target: appConfig.key, set: { value, updatedAt: new Date() }, }); } export async function getMaintenanceMode(): Promise { try { return (await getAppConfigValue(MAINTENANCE_MODE_KEY)) === "true"; } catch { return false; } } export async function setMaintenanceMode(enabled: boolean): Promise { await upsertAppConfigValue(MAINTENANCE_MODE_KEY, enabled ? "true" : "false"); } export async function getSiteSettings(): Promise { try { const configs = await db .select({ key: appConfig.key, value: appConfig.value }) .from(appConfig) .where(inArray(appConfig.key, [SITE_SETTINGS_KEY, SITE_NAME_KEY])); const configMap = new Map(configs.map((config) => [config.key, config.value])); const fallbackName = configMap.get(SITE_NAME_KEY) ?? DEFAULT_SITE_NAME; return parseSiteSettingsValue(configMap.get(SITE_SETTINGS_KEY), fallbackName); } catch { return buildDefaultSiteSettings(); } } export async function updateSiteSettings(settings: SiteSettings): Promise { await upsertAppConfigValue(SITE_SETTINGS_KEY, JSON.stringify(settings)); } export async function getMailSettings(): Promise { try { return parseMailSettingsValue(await getAppConfigValue(MAIL_SETTINGS_KEY)); } catch { return buildDefaultMailSettings(); } } export async function getMailSettingsFormValues(): Promise { const settings = await getMailSettings(); return toMailSettingsFormValues(settings); } export async function updateMailSettings(settings: MailSettings): Promise { await upsertAppConfigValue(MAIL_SETTINGS_KEY, JSON.stringify(settings)); } export async function getMarqueeSettings(): Promise { try { return parseMarqueeSettingsValue(await getAppConfigValue(MARQUEE_SETTINGS_KEY)); } catch { return buildDefaultMarqueeSettings(); } } export async function updateMarqueeSettings(settings: MarqueeSettings): Promise { const normalizedSettings = syncMarqueeSettingsToGermanSource(settings); await upsertAppConfigValue(MARQUEE_SETTINGS_KEY, JSON.stringify(normalizedSettings)); } export async function getSiteSettingsMediaBindings(): Promise { try { const usages = await db.query.mediaUsage.findMany({ where: and( eq(mediaUsage.entityType, SITE_SETTINGS_ENTITY_TYPE), eq(mediaUsage.entityId, SITE_SETTINGS_ENTITY_ID), ), columns: { fieldKey: true, updatedAt: true, }, with: { asset: { columns: { id: true, url: true, }, }, }, }); return usages.reduce( (result, usage) => { if (usage.fieldKey === SITE_SETTINGS_LOGO_LIGHT_FIELD_KEY) { result.siteLogoLight = { assetId: usage.asset.id, url: usage.asset.url, version: usage.updatedAt.toISOString(), }; } if (usage.fieldKey === SITE_SETTINGS_LOGO_DARK_FIELD_KEY) { result.siteLogoDark = { assetId: usage.asset.id, url: usage.asset.url, version: usage.updatedAt.toISOString(), }; } if (usage.fieldKey === SITE_SETTINGS_FAVICON_FIELD_KEY) { result.favicon = { assetId: usage.asset.id, url: usage.asset.url, version: usage.updatedAt.toISOString(), }; } if (usage.fieldKey === SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY) { result.defaultOgImage = { assetId: usage.asset.id, url: usage.asset.url, version: usage.updatedAt.toISOString(), }; } return result; }, getDefaultSiteSettingsMediaBindings(), ); } catch { return getDefaultSiteSettingsMediaBindings(); } }