/** * Config values as whole trees: merging two trees into one view, and * splitting one tree into the settings file and the state file by key. * Pure transforms shared by the persistent store and the legacy migration. */ const currentWorkspaceIdKey = 'current_workspace_id' const patKey = 'pat' /** Whether a key holds auth state rather than a setting. */ export const isStateKey = (key: string): boolean => { return ( key === currentWorkspaceIdKey || key === patKey || key.endsWith(`.${patKey}`) ) } export const mergeConfig = ( baseConfig: Record, overrideConfig: Record, ): Record => { const mergedConfig = { ...baseConfig } for (const [key, value] of Object.entries(overrideConfig)) { const baseValue = mergedConfig[key] mergedConfig[key] = isRecord(baseValue) && isRecord(value) ? mergeConfig(baseValue, value) : value } return mergedConfig } export const splitConfig = ( config: Record, ): { settings: Record state: Record } => { const settings: Record = {} const state: Record = {} for (const [key, value] of Object.entries(config)) { if (isStateKey(key)) { state[key] = value continue } if (isRecord(value)) { const splitValue = splitConfig(value) if (Object.keys(splitValue.settings).length > 0) { settings[key] = splitValue.settings } if (Object.keys(splitValue.state).length > 0) { state[key] = splitValue.state } continue } settings[key] = value } return { settings, state } } const isRecord = (value: unknown): value is Record => { return value != null && typeof value === 'object' && !Array.isArray(value) }