/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ export type HeaderNavAccessConfig = { enabled: boolean requireAuth: boolean } export type HeaderNavModulesConfig = { home: boolean console: boolean pricing: HeaderNavAccessConfig rankings: HeaderNavAccessConfig docs: boolean about: boolean [key: string]: boolean | HeaderNavAccessConfig } export type SidebarSectionConfig = { enabled: boolean [key: string]: boolean } export type SidebarModulesAdminConfig = Record export const HEADER_NAV_DEFAULT: HeaderNavModulesConfig = { home: true, console: true, pricing: { enabled: true, requireAuth: false, }, rankings: { enabled: true, requireAuth: false, }, docs: true, about: true, } export const SIDEBAR_MODULES_DEFAULT: SidebarModulesAdminConfig = { chat: { enabled: true, playground: true, chat: true, }, console: { enabled: true, detail: true, token: true, log: true, midjourney: true, task: true, }, personal: { enabled: true, topup: true, personal: true, }, admin: { enabled: true, channel: true, models: true, redemption: true, user: true, setting: true, subscription: true, }, } const toBoolean = (value: unknown, fallback: boolean): boolean => { if (typeof value === 'boolean') return value if (typeof value === 'number') return value === 1 if (typeof value === 'string') { const normalized = value.trim().toLowerCase() if (normalized === 'true' || normalized === '1') return true if (normalized === 'false' || normalized === '0') return false } return fallback } const cloneHeaderNavDefault = (): HeaderNavModulesConfig => ({ ...HEADER_NAV_DEFAULT, pricing: { ...HEADER_NAV_DEFAULT.pricing }, rankings: { ...HEADER_NAV_DEFAULT.rankings }, }) const parseAccessModule = ( raw: unknown, fallback: HeaderNavAccessConfig ): HeaderNavAccessConfig => { if ( typeof raw === 'boolean' || typeof raw === 'string' || typeof raw === 'number' ) { return { enabled: toBoolean(raw, fallback.enabled), requireAuth: fallback.requireAuth, } } if (raw && typeof raw === 'object') { const record = raw as Record return { enabled: toBoolean(record.enabled, fallback.enabled), requireAuth: toBoolean(record.requireAuth, fallback.requireAuth), } } return { ...fallback } } const cloneSidebarDefault = (): SidebarModulesAdminConfig => Object.entries(SIDEBAR_MODULES_DEFAULT).reduce( (acc, [section, config]) => { acc[section] = { ...config } return acc }, {} ) export function parseHeaderNavModules( value: string | null | undefined ): HeaderNavModulesConfig { const base = cloneHeaderNavDefault() if (!value) { return base } try { const parsed = JSON.parse(value) as Record const result: HeaderNavModulesConfig = { ...base, pricing: { ...base.pricing }, rankings: { ...base.rankings }, } Object.entries(parsed).forEach(([key, raw]) => { if (key === 'pricing') { result.pricing = parseAccessModule(raw, base.pricing) return } if (key === 'rankings') { result.rankings = parseAccessModule(raw, base.rankings) return } if (typeof raw === 'boolean') { result[key] = raw return } if (typeof raw === 'string' || typeof raw === 'number') { result[key] = toBoolean(raw, Boolean(base[key])) return } }) return result } catch { return base } } export function serializeHeaderNavModules( config: HeaderNavModulesConfig ): string { return JSON.stringify(config) } export function parseSidebarModulesAdmin( value: string | null | undefined ): SidebarModulesAdminConfig { const defaults = cloneSidebarDefault() // If empty string, null, or undefined, use default config if (!value || value.trim() === '') return defaults try { const parsed = JSON.parse(value) as Record const result: SidebarModulesAdminConfig = {} Object.entries(parsed).forEach(([sectionKey, raw]) => { if (!raw || typeof raw !== 'object') return const defaultSection = defaults[sectionKey] ?? { enabled: true } const sectionConfig: SidebarSectionConfig = { enabled: toBoolean( (raw as Record).enabled, defaultSection.enabled ?? true ), } Object.entries(raw as Record).forEach( ([moduleKey, moduleValue]) => { if (moduleKey === 'enabled') return sectionConfig[moduleKey] = toBoolean( moduleValue, defaultSection[moduleKey] ?? true ) } ) result[sectionKey] = sectionConfig }) // Merge defaults to ensure expected sections exist Object.entries(defaults).forEach(([sectionKey, config]) => { if (!result[sectionKey]) { result[sectionKey] = { ...config } return } Object.entries(config).forEach(([moduleKey, moduleValue]) => { if (!(moduleKey in result[sectionKey])) { result[sectionKey][moduleKey] = moduleValue } }) }) return result } catch { return defaults } } export function serializeSidebarModulesAdmin( config: SidebarModulesAdminConfig ): string { return JSON.stringify(config) }