11import { readFileSync , existsSync , writeFileSync , mkdirSync } from 'fs' ;
22import { homedir } from 'os' ;
33import { join , dirname } from 'path' ;
4- import { PackageManager } from './package-manager-config' ;
4+ import { PackageManager , SUPPORTED_PACKAGE_MANAGERS } from './package-manager-config' ;
55
6- const CONFIG_PATH = join ( homedir ( ) , '.xpmrc' ) ;
6+ function isValidPackageManager ( pm : string ) : pm is PackageManager {
7+ return SUPPORTED_PACKAGE_MANAGERS . includes ( pm as any ) ;
8+ }
9+
10+ const CONFIG_PATHS = [
11+ ( ) => join ( process . env . XDG_CONFIG_HOME || join ( homedir ( ) , '.config' ) , 'xpm' , 'config.json' ) ,
12+ ( ) => join ( homedir ( ) , '.xpmrc' )
13+ ] ;
14+
15+ function getConfigPath ( ) : string {
16+ for ( const pathFn of CONFIG_PATHS ) {
17+ const path = pathFn ( ) ;
18+ if ( existsSync ( path ) ) {
19+ return path ;
20+ }
21+ }
22+ // Default to XDG config for new config files
23+ return CONFIG_PATHS [ 0 ] ( ) ;
24+ }
25+
26+ interface Config {
27+ defaultPackageManager ?: PackageManager ;
28+ globalPackageManager ?: PackageManager ;
29+ }
730
8- function getConfig ( ) : any {
9- if ( existsSync ( CONFIG_PATH ) ) {
31+ function getConfig ( ) : Config {
32+ const configPath = getConfigPath ( ) ;
33+ if ( existsSync ( configPath ) ) {
1034 try {
11- return JSON . parse ( readFileSync ( CONFIG_PATH , 'utf-8' ) ) ;
12- } catch { }
35+ return JSON . parse ( readFileSync ( configPath , 'utf-8' ) ) ;
36+ } catch {
37+ console . warn ( `Failed to parse config at ${ configPath } ` ) ;
38+ }
1339 }
1440 return { } ;
1541}
1642
17- function saveConfig ( config : any ) : void {
18- const dir = dirname ( CONFIG_PATH ) ;
43+ function saveConfig ( config : Config ) : void {
44+ const configPath = getConfigPath ( ) ;
45+ const dir = dirname ( configPath ) ;
1946 if ( ! existsSync ( dir ) ) {
2047 mkdirSync ( dir , { recursive : true } ) ;
2148 }
22- writeFileSync ( CONFIG_PATH , JSON . stringify ( config , null , 2 ) ) ;
49+ writeFileSync ( configPath , JSON . stringify ( config , null , 2 ) ) ;
2350}
2451
25- function getPackageManager ( envVar : string , configKey : string ) : PackageManager {
26- // 1. Check environment variable
52+ function getPackageManager ( envVar : string , configKey : keyof Config ) : PackageManager {
53+ // 1. Environment variable (highest priority)
2754 const envPM = process . env [ envVar ] ;
2855 if ( envPM && isValidPackageManager ( envPM ) ) {
2956 return envPM as PackageManager ;
3057 }
3158
32- // 2. Check config file
59+ // 2. Config file
3360 const config = getConfig ( ) ;
3461 if ( config [ configKey ] && isValidPackageManager ( config [ configKey ] ) ) {
3562 return config [ configKey ] ;
3663 }
3764
38- // 3. Fall back to npm
65+ // 3. Default fallback
3966 return 'npm' ;
4067}
4168
@@ -47,13 +74,13 @@ export function getGlobalPackageManager(): PackageManager {
4774 return getPackageManager ( 'XPM_GLOBAL_PM' , 'globalPackageManager' ) ;
4875}
4976
50- function setPackageManager ( pm : string , configKey : string , displayName : string ) : void {
77+ function setPackageManager ( pm : string , configKey : keyof Config , displayName : string ) : void {
5178 if ( ! isValidPackageManager ( pm ) ) {
52- throw new Error ( `Invalid package manager: ${ pm } . Must be one of: npm, yarn, pnpm, bun ` ) ;
79+ throw new Error ( `Invalid package manager: ${ pm } . Must be one of: ${ SUPPORTED_PACKAGE_MANAGERS . join ( ', ' ) } ` ) ;
5380 }
5481
5582 const config = getConfig ( ) ;
56- config [ configKey ] = pm ;
83+ config [ configKey ] = pm as PackageManager ;
5784 saveConfig ( config ) ;
5885 console . log ( `${ displayName } set to: ${ pm } ` ) ;
5986}
@@ -66,6 +93,3 @@ export function setGlobalPackageManager(pm: string): void {
6693 setPackageManager ( pm , 'globalPackageManager' , 'Global package manager' ) ;
6794}
6895
69- function isValidPackageManager ( pm : string ) : boolean {
70- return [ 'npm' , 'yarn' , 'pnpm' , 'bun' ] . includes ( pm ) ;
71- }
0 commit comments