import path from 'node:path' import fs from 'node:fs' import { PROFILE_NATIVE_SKILLS_PATH, SKILL_PATH } from '@bridge/constants' export class Settings> { private readonly settingsPath: string private readonly settingsSamplePath: string constructor() { this.settingsPath = path.join( PROFILE_NATIVE_SKILLS_PATH, path.basename(SKILL_PATH), 'settings.json' ) this.settingsSamplePath = path.join( SKILL_PATH, 'src', 'settings.sample.json' ) } /** * Check if a setting is already set * @param key The key to verify whether its value is set * @returns isSettingSet('apiKey') // true */ public async isSettingSet(key: string): Promise { const settingsSample = await this.getSettingsSample() const settings = await this.get() return ( !!settings[key] && JSON.stringify(settings[key]) !== JSON.stringify(settingsSample[key]) ) } /** * Clear the settings and set it to the default settings.sample.json file * @example clear() */ public async clear(): Promise { const settingsSample = await this.getSettingsSample() await this.set(settingsSample) } private async getSettingsSample(): Promise { try { return JSON.parse( await fs.promises.readFile(this.settingsSamplePath, 'utf8') ) } catch (e) { console.error( `Error while reading settings sample at "${this.settingsSamplePath}":`, e ) throw e } } /** * Get the settings * @param key The key of the setting to get * @example get('API_KEY') // 'value' * @example get() // { API_KEY: 'value' } */ public async get(key: Key): Promise public async get(): Promise public async get(key?: Key): Promise { try { if (!fs.existsSync(this.settingsPath)) { await this.clear() } const settings = JSON.parse( await fs.promises.readFile(this.settingsPath, 'utf8') ) if (key != null) { return settings[key] } return settings } catch (e) { console.error( `Error while reading settings at "${this.settingsPath}":`, e ) throw e } } /** * Set the settings * @param key The key of the setting to set * @param value The value of the setting to set * @example set({ API_KEY: 'value' }) // { API_KEY: 'value' } */ public async set(key: Key, value: T[Key]): Promise public async set(settings: T): Promise public async set( keyOrSettings: Key | T, value?: T[Key] ): Promise { try { const newSettings = typeof keyOrSettings === 'object' ? keyOrSettings : { ...(await this.get()), [keyOrSettings]: value } await fs.promises.mkdir(path.dirname(this.settingsPath), { recursive: true }) await fs.promises.writeFile( this.settingsPath, JSON.stringify(newSettings, null, 2) ) return newSettings } catch (e) { console.error( `Error while writing settings at "${this.settingsPath}":`, e ) throw e } } }