rawi
Version:
Rawi (راوي) is the developer-friendly AI CLI that brings the power of 11 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into
1 lines • 7.4 kB
Source Map (JSON)
{"version":3,"sources":["/home/mkabumattar/work/withrawi/rawi/dist/chunk-AFYLVLTK.cjs","../src/core/configs/managers/base.manager.ts"],"names":["BaseConfigManager","getConfigDir","getCredentialsFilePath","join","existsSync","mkdirSync","error"],"mappings":"AAAA;AACA,wDAA+C,wDAAyC,wBCMjF,4BACY,4EACD,IAWLA,CAAAA,CAAN,KAAsE,CACxD,WAInB,CAAA,CAAc,CACZ,IAAA,CAAK,SAAA,CAAYC,iCAAAA,CAAa,CAC9B,IAAA,CAAK,UAAA,CAAaC,iCAAAA,CAAuB,CACzC,IAAA,CAAK,UAAA,CAAaC,wBAAAA,IAChB,CAAK,SAAA,CACL,CAAA,mBAAA,EAAsB,IAAI,IAAA,CAAK,CAAA,CAC5B,WAAA,CAAY,CAAA,CACZ,OAAA,CAAQ,OAAA,CAAS,GAAG,CAAC,CAAA,KAAA,CAC1B,CACF,CAEA,eAAA,CAAA,CAAwB,CACtB,EAAA,CAAI,CAACC,4BAAAA,IAAW,CAAK,SAAS,CAAA,CAC5B,GAAI,CACFC,2BAAAA,IAAU,CAAK,SAAA,CAAW,CAAC,SAAA,CAAW,CAAA,CAAI,CAAC,CAC7C,CAAA,KAAA,CAASC,CAAAA,CAAO,CACd,MAAM,IAAI,KAAA,CACR,CAAA,mCAAA,EACEA,EAAAA,WAAiB,KAAA,CAAQA,CAAAA,CAAM,OAAA,CAAU,MAAA,CAAOA,CAAK,CACvD,CAAA,CAAA;AD1CwnB","file":"/home/mkabumattar/work/withrawi/rawi/dist/chunk-AFYLVLTK.cjs","sourcesContent":[null,"import {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n writeFileSync,\n} from 'node:fs';\nimport {join} from 'node:path';\nimport chalk from 'chalk';\nimport {\n DEFAULT_PROFILE,\n getConfigDir,\n getCredentialsFilePath,\n type RawiConfig,\n type RawiCredentials,\n} from '../../shared/index.js';\nimport type {IConfigManager} from '../interfaces/config-manager.interface.js';\nimport type {IConfigPersistence} from '../interfaces/persistence.interface.js';\n\nexport class BaseConfigManager implements IConfigManager, IConfigPersistence {\n protected readonly configDir: string;\n protected readonly configFile: string;\n protected readonly backupFile: string;\n\n constructor() {\n this.configDir = getConfigDir();\n this.configFile = getCredentialsFilePath();\n this.backupFile = join(\n this.configDir,\n `backup.credentials.${new Date()\n .toISOString()\n .replace(/[:.]/g, '-')}.rawi`,\n );\n }\n\n ensureConfigDir(): void {\n if (!existsSync(this.configDir)) {\n try {\n mkdirSync(this.configDir, {recursive: true});\n } catch (error) {\n throw new Error(\n `Failed to create config directory: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n }\n\n configExists(): boolean {\n return existsSync(this.configFile);\n }\n\n readConfig(): RawiConfig {\n if (!existsSync(this.configFile)) {\n return {};\n }\n\n try {\n const content = readFileSync(this.configFile, 'utf-8');\n const config = JSON.parse(content);\n\n if (typeof config !== 'object' || config === null) {\n throw new Error('Invalid configuration format');\n }\n\n return config as RawiConfig;\n } catch {\n console.error(\n chalk.yellow(\n 'Warning: Failed to read config file, using empty config.',\n ),\n );\n\n if (existsSync(this.backupFile)) {\n console.log(chalk.blue('Attempting to restore from backup...'));\n try {\n this.restoreConfig();\n return this.readConfig();\n } catch (restoreError) {\n console.error(\n chalk.red(`Failed to restore from backup: ${restoreError}`),\n );\n }\n }\n\n return {};\n }\n }\n\n writeConfig(config: RawiConfig): void {\n this.ensureConfigDir();\n\n if (this.configExists()) {\n try {\n this.backupConfig();\n } catch (error) {\n console.warn(\n chalk.yellow(`Warning: Failed to create backup: ${error}`),\n );\n }\n }\n\n try {\n const content = JSON.stringify(config, null, 2);\n writeFileSync(this.configFile, content, 'utf-8');\n } catch (error) {\n throw new Error(\n `Failed to write config file: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n backupConfig(): void {\n if (!this.configExists()) {\n return;\n }\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupFilePath = join(\n this.configDir,\n `backup.credentials.${timestamp}.rawi`,\n );\n\n try {\n copyFileSync(this.configFile, backupFilePath);\n } catch (error) {\n throw new Error(\n `Failed to backup config file: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n restoreConfig(): void {\n const backupFiles = readdirSync(this.configDir).filter(\n (file) =>\n file.startsWith('backup.credentials.') && file.endsWith('.rawi'),\n );\n if (backupFiles.length === 0) {\n throw new Error('No backup file found');\n }\n\n const latestBackupFile = backupFiles.sort().pop();\n if (!latestBackupFile) {\n throw new Error('No backup file found');\n }\n\n const backupFilePath = join(this.configDir, latestBackupFile);\n\n try {\n copyFileSync(backupFilePath, this.configFile);\n } catch (error) {\n throw new Error(\n `Failed to restore config file: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n getCredentials(profile = DEFAULT_PROFILE): RawiCredentials | null {\n try {\n const config = this.readConfig();\n const credentials = config[profile];\n\n if (!credentials) {\n return null;\n }\n\n if (\n typeof credentials !== 'object' ||\n !credentials.provider ||\n !credentials.model\n ) {\n console.error(\n chalk.red(`Invalid credentials structure for profile '${profile}'`),\n );\n return null;\n }\n\n return credentials;\n } catch (error) {\n console.error(chalk.red(`Error reading credentials: ${error}`));\n return null;\n }\n }\n\n setCredentials(\n credentials: RawiCredentials,\n profile = DEFAULT_PROFILE,\n ): void {\n try {\n const config = this.readConfig();\n config[profile] = credentials;\n this.writeConfig(config);\n } catch (error) {\n throw new Error(\n `Failed to save credentials: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n listProfiles(): string[] {\n try {\n const config = this.readConfig();\n return Object.keys(config).filter((key) => {\n const credentials = config[key];\n return (\n credentials &&\n typeof credentials === 'object' &&\n credentials.provider &&\n credentials.model\n );\n });\n } catch (error) {\n console.error(chalk.red(`Error listing profiles: ${error}`));\n return [];\n }\n }\n\n deleteProfile(profile: string): boolean {\n try {\n const config = this.readConfig();\n\n if (!(profile in config)) {\n return false;\n }\n\n this.backupConfig();\n\n delete config[profile];\n this.writeConfig(config);\n return true;\n } catch (error) {\n console.error(chalk.red(`Error deleting profile: ${error}`));\n return false;\n }\n }\n\n getConfigFile(): string {\n return this.configFile;\n }\n\n getConfigDir(): string {\n return this.configDir;\n }\n\n getBackupFile(): string {\n return this.backupFile;\n }\n}\n"]}