@@ -2,8 +2,13 @@ import fs from 'fs/promises';
22import path from 'path' ;
33import os from 'os' ;
44
5- const CONFIG_DIR = path . join ( os . homedir ( ) , '.kodus' ) ;
6- const CONFIG_FILE = path . join ( CONFIG_DIR , 'config.json' ) ;
5+ function getConfigDir ( ) : string {
6+ return path . join ( os . homedir ( ) , '.kodus' ) ;
7+ }
8+
9+ function getConfigFile ( ) : string {
10+ return path . join ( getConfigDir ( ) , 'config.json' ) ;
11+ }
712
813export interface CliConfig {
914 teamKey : string ;
@@ -20,7 +25,7 @@ function isJsonParseError(error: unknown): boolean {
2025
2126async function ensureConfigDir ( ) : Promise < void > {
2227 try {
23- await fs . mkdir ( CONFIG_DIR , { recursive : true , mode : 0o700 } ) ;
28+ await fs . mkdir ( getConfigDir ( ) , { recursive : true , mode : 0o700 } ) ;
2429 } catch ( error ) {
2530 if ( ( error as NodeJS . ErrnoException ) . code !== 'EEXIST' ) {
2631 throw error ;
@@ -30,16 +35,18 @@ async function ensureConfigDir(): Promise<void> {
3035
3136export async function saveConfig ( config : CliConfig ) : Promise < void > {
3237 await ensureConfigDir ( ) ;
33- const tmpFile = `${ CONFIG_FILE } .${ process . pid } .${ Date . now ( ) } .tmp` ;
38+ const configFile = getConfigFile ( ) ;
39+ const tmpFile = `${ configFile } .${ process . pid } .${ Date . now ( ) } .tmp` ;
3440 const content = JSON . stringify ( config , null , 2 ) ;
3541
3642 await fs . writeFile ( tmpFile , content , { encoding : 'utf-8' , mode : 0o600 } ) ;
37- await fs . rename ( tmpFile , CONFIG_FILE ) ;
43+ await fs . rename ( tmpFile , configFile ) ;
3844}
3945
4046export async function loadConfig ( ) : Promise < CliConfig | null > {
4147 try {
42- const content = await fs . readFile ( CONFIG_FILE , 'utf-8' ) ;
48+ const configFile = getConfigFile ( ) ;
49+ const content = await fs . readFile ( configFile , 'utf-8' ) ;
4350 return JSON . parse ( content ) as CliConfig ;
4451 } catch ( error ) {
4552 const code = ( error as NodeJS . ErrnoException ) . code ;
@@ -49,8 +56,9 @@ export async function loadConfig(): Promise<CliConfig | null> {
4956
5057 // Self-heal malformed JSON by isolating the broken file and treating as no config.
5158 if ( isJsonParseError ( error ) ) {
52- const brokenFile = `${ CONFIG_FILE } .corrupted.${ Date . now ( ) } ` ;
53- await fs . rename ( CONFIG_FILE , brokenFile ) . catch ( ( ) => { } ) ;
59+ const configFile = getConfigFile ( ) ;
60+ const brokenFile = `${ configFile } .corrupted.${ Date . now ( ) } ` ;
61+ await fs . rename ( configFile , brokenFile ) . catch ( ( ) => { } ) ;
5462 return null ;
5563 }
5664
@@ -60,7 +68,7 @@ export async function loadConfig(): Promise<CliConfig | null> {
6068
6169export async function clearConfig ( ) : Promise < void > {
6270 try {
63- await fs . unlink ( CONFIG_FILE ) ;
71+ await fs . unlink ( getConfigFile ( ) ) ;
6472 } catch ( error ) {
6573 if ( ( error as NodeJS . ErrnoException ) . code !== 'ENOENT' ) {
6674 throw error ;
@@ -70,7 +78,7 @@ export async function clearConfig(): Promise<void> {
7078
7179export async function configExists ( ) : Promise < boolean > {
7280 try {
73- await fs . access ( CONFIG_FILE ) ;
81+ await fs . access ( getConfigFile ( ) ) ;
7482 return true ;
7583 } catch {
7684 return false ;
0 commit comments