import { apiJSON, apiMutate } from '$lib/api/client.js'; import type { AppSettings } from '$lib/api/types.js'; import { emptyBirdSettingsForm, type BirdSettingsForm } from './bird-settings.schema.js'; import { emptyRevisionSettingsForm, type RevisionSettingsForm } from './revision-settings.schema.js'; import { BIRD_SETTING_KEYS, KNOWN_SETTING_KEYS, NUMERIC_SETTING_KEYS, type BirdSettingKey, type KnownSettingKey, type RevisionSettingKey } from './settings-known-keys.js'; export type AdditionalSettingEntry = { id: number; key: string; value: string }; export type PartitionedSettings = { bird: BirdSettingsForm; revision: RevisionSettingsForm; additional: AdditionalSettingEntry[]; }; function parseKnownValue(key: KnownSettingKey, value: unknown): string { if (NUMERIC_SETTING_KEYS.has(key)) { if (typeof value === 'number' && Number.isFinite(value)) return String(value); if (typeof value === 'string') return value; return ''; } if (typeof value === 'string') return value; return ''; } export function partitionSettings( settings: AppSettings, nextId = 1 ): { partitioned: PartitionedSettings; nextId: number } { const bird = emptyBirdSettingsForm(); const revision = emptyRevisionSettingsForm(); const additional: AdditionalSettingEntry[] = []; let idCounter = nextId; for (const [key, value] of Object.entries(settings as Record)) { if ((BIRD_SETTING_KEYS as readonly string[]).includes(key)) { bird[key as BirdSettingKey] = parseKnownValue(key as KnownSettingKey, value); } else if (key === 'revision_retention_minutes') { revision.revision_retention_minutes = parseKnownValue(key as RevisionSettingKey, value); } else { additional.push({ id: idCounter++, key, value: typeof value === 'string' ? value : String(value) }); } } return { partitioned: { bird, revision, additional }, nextId: idCounter }; } export async function loadSettings(): Promise { return apiJSON('/v1/settings'); } export async function patchSettings(payload: Record): Promise { await apiMutate('/v1/settings', 'PATCH', payload); } export function buildPayloadFromFormFields( keys: readonly KnownSettingKey[], form: Record, errors: Partial> ): Record { const payload: Record = {}; for (const key of keys) { const value = String(form[key] ?? '').trim(); if (!value || errors[key]?.length) continue; if (NUMERIC_SETTING_KEYS.has(key)) payload[key] = Number(value); else payload[key] = value; } return payload; } export function isKnownSettingKey(key: string): key is KnownSettingKey { return (KNOWN_SETTING_KEYS as readonly string[]).includes(key); }