Refine the default system settings structure and model pricing editor so pricing configuration is easier to scan and edit.
202 lines
4.8 KiB
TypeScript
Vendored
202 lines
4.8 KiB
TypeScript
Vendored
export type HeaderNavPricingConfig = {
|
|
enabled: boolean
|
|
requireAuth: boolean
|
|
}
|
|
|
|
export type HeaderNavModulesConfig = {
|
|
home: boolean
|
|
console: boolean
|
|
pricing: HeaderNavPricingConfig
|
|
docs: boolean
|
|
about: boolean
|
|
[key: string]: boolean | HeaderNavPricingConfig
|
|
}
|
|
|
|
export type SidebarSectionConfig = {
|
|
enabled: boolean
|
|
[key: string]: boolean
|
|
}
|
|
|
|
export type SidebarModulesAdminConfig = Record<string, SidebarSectionConfig>
|
|
|
|
export const HEADER_NAV_DEFAULT: HeaderNavModulesConfig = {
|
|
home: true,
|
|
console: true,
|
|
pricing: {
|
|
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 },
|
|
})
|
|
|
|
const cloneSidebarDefault = (): SidebarModulesAdminConfig =>
|
|
Object.entries(SIDEBAR_MODULES_DEFAULT).reduce<SidebarModulesAdminConfig>(
|
|
(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<string, unknown>
|
|
const result: HeaderNavModulesConfig = {
|
|
...base,
|
|
pricing: { ...base.pricing },
|
|
}
|
|
|
|
Object.entries(parsed).forEach(([key, raw]) => {
|
|
if (key === 'pricing') {
|
|
if (raw && typeof raw === 'object') {
|
|
const rawPricing = raw as Record<string, unknown>
|
|
result.pricing = {
|
|
enabled: toBoolean(
|
|
rawPricing.enabled,
|
|
base.pricing?.enabled ?? true
|
|
),
|
|
requireAuth: toBoolean(
|
|
rawPricing.requireAuth,
|
|
base.pricing?.requireAuth ?? false
|
|
),
|
|
}
|
|
}
|
|
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<string, unknown>
|
|
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<string, unknown>).enabled,
|
|
defaultSection.enabled ?? true
|
|
),
|
|
}
|
|
|
|
Object.entries(raw as Record<string, unknown>).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)
|
|
}
|