Skip to content

Kody is live

Watch the launch video — what Kody is, and why it exists.

← Public packages

@kody/blandPublic

src/settings.ts

56 lines · 1.5 KB · TypeScript
/**
 * Read or update non-secret Bland defaults (e.g. default voice).
 * Keep the API key in a Kody secret (`blandApiKey`), not here.
 *
 * @param input - optional defaultVoice to save
 * @returns Current settings plus setup URLs
 *
 * @example
 * import settings from 'kody:@kody/bland/settings'
 * await settings({ defaultVoice: 'maya' })
 */
import { packageStorage } from 'kody:runtime'
import {
	API_HOST,
	DASHBOARD_SETTINGS_URL,
	DEFAULT_API_KEY_SECRET,
	SETTINGS_DEFAULT_VOICE,
	apiKeySetupUrl,
} from './core.ts'

function trimString(value: unknown) {
	return typeof value === 'string' ? value.trim() : ''
}

export type BlandSettings = {
	defaultVoice: string | null
	apiKeySecret: string
	apiKeyUrl: string
	dashboard: string
	approveHost: string
}

export async function readBlandSettings(): Promise<BlandSettings> {
	const storage = packageStorage()
	const defaultVoice = trimString(await storage.get(SETTINGS_DEFAULT_VOICE)) || null
	return {
		defaultVoice,
		apiKeySecret: DEFAULT_API_KEY_SECRET,
		apiKeyUrl: apiKeySetupUrl(),
		dashboard: DASHBOARD_SETTINGS_URL,
		approveHost: API_HOST,
	}
}

export default async function settings(input: { defaultVoice?: string } = {}) {
	const storage = packageStorage()
	const updated: string[] = []
	const nextVoice = trimString(input.defaultVoice)
	if (input.defaultVoice !== undefined) {
		await storage.set(SETTINGS_DEFAULT_VOICE, nextVoice)
		updated.push('defaultVoice')
	}
	const current = await readBlandSettings()
	if (updated.length) return { updated, settings: current }
	return current
}