@@ -45,28 +45,14 @@ export class JsPackageManagerFactory {
45
45
this . cache . clear ( ) ;
46
46
}
47
47
48
- public static getPackageManager (
49
- {
50
- force,
51
- configDir = '.storybook' ,
52
- storiesPaths,
53
- } : { force ?: PackageManagerName ; configDir ?: string ; storiesPaths ?: string [ ] } = { } ,
54
- cwd = process . cwd ( )
55
- ) : JsPackageManager {
56
- // Check cache first
57
- const cacheKey = this . getCacheKey ( force , configDir , cwd , storiesPaths ) ;
58
- const cached = this . cache . get ( cacheKey ) ;
59
- if ( cached ) {
60
- return cached ;
61
- }
62
-
63
- // Option 1: If the user has provided a forcing flag, we use it
64
- if ( force && force in this . PROXY_MAP ) {
65
- const packageManager = new this . PROXY_MAP [ force ] ( { cwd, configDir, storiesPaths } ) ;
66
- this . cache . set ( cacheKey , packageManager ) ;
67
- return packageManager ;
68
- }
69
-
48
+ /**
49
+ * Determine which package manager type to use based on lockfiles, commands, and environment
50
+ *
51
+ * @param cwd - Current working directory
52
+ * @returns Package manager type as string: 'npm', 'pnpm', 'bun', 'yarn1', or 'yarn2'
53
+ * @throws Error if no usable package manager is found
54
+ */
55
+ public static getPackageManagerType ( cwd = process . cwd ( ) ) : PackageManagerName {
70
56
const root = getProjectRoot ( ) ;
71
57
72
58
const lockFiles = [
@@ -94,66 +80,81 @@ export class JsPackageManagerFactory {
94
80
return 1 ;
95
81
} ) ;
96
82
97
- // Option 2 : We try to infer the package manager from the closest lockfile
83
+ // Option 1 : We try to infer the package manager from the closest lockfile
98
84
const closestLockfilePath = lockFiles [ 0 ] ;
99
-
100
85
const closestLockfile = closestLockfilePath && basename ( closestLockfilePath ) ;
101
86
102
87
const yarnVersion = getYarnVersion ( cwd ) ;
103
88
104
89
if ( yarnVersion && closestLockfile === YARN_LOCKFILE ) {
105
- const packageManager =
106
- yarnVersion === 1
107
- ? new Yarn1Proxy ( { cwd, configDir, storiesPaths } )
108
- : new Yarn2Proxy ( { cwd, configDir, storiesPaths } ) ;
109
- this . cache . set ( cacheKey , packageManager ) ;
110
- return packageManager ;
90
+ return yarnVersion === 1 ? 'yarn1' : 'yarn2' ;
111
91
}
112
92
113
93
if ( hasPNPM ( cwd ) && closestLockfile === PNPM_LOCKFILE ) {
114
- const packageManager = new PNPMProxy ( { cwd, configDir, storiesPaths } ) ;
115
- this . cache . set ( cacheKey , packageManager ) ;
116
- return packageManager ;
94
+ return 'pnpm' ;
117
95
}
118
96
119
97
const isNPMCommandOk = hasNPM ( cwd ) ;
120
98
121
99
if ( isNPMCommandOk && closestLockfile === NPM_LOCKFILE ) {
122
- const packageManager = new NPMProxy ( { cwd, configDir, storiesPaths } ) ;
123
- this . cache . set ( cacheKey , packageManager ) ;
124
- return packageManager ;
100
+ return 'npm' ;
125
101
}
126
102
127
103
if (
128
104
hasBun ( cwd ) &&
129
105
( closestLockfile === BUN_LOCKFILE || closestLockfile === BUN_LOCKFILE_BINARY )
130
106
) {
131
- const packageManager = new BUNProxy ( { cwd, configDir, storiesPaths } ) ;
132
- this . cache . set ( cacheKey , packageManager ) ;
133
- return packageManager ;
107
+ return 'bun' ;
134
108
}
135
109
136
- // Option 3 : If the user is running a command via npx/pnpx/yarn create/etc, we infer the package manager from the command
110
+ // Option 2 : If the user is running a command via npx/pnpx/yarn create/etc, we infer the package manager from the command
137
111
const inferredPackageManager = this . inferPackageManagerFromUserAgent ( ) ;
138
112
if ( inferredPackageManager && inferredPackageManager in this . PROXY_MAP ) {
139
- const packageManager = new this . PROXY_MAP [ inferredPackageManager ] ( {
140
- cwd,
141
- storiesPaths,
142
- configDir,
143
- } ) ;
144
- this . cache . set ( cacheKey , packageManager ) ;
145
- return packageManager ;
113
+ return inferredPackageManager ;
146
114
}
147
115
148
116
// Default fallback, whenever users try to use something different than NPM, PNPM, Yarn,
149
117
// but still have NPM installed
150
118
if ( isNPMCommandOk ) {
151
- const packageManager = new NPMProxy ( { cwd, configDir, storiesPaths } ) ;
119
+ return 'npm' ;
120
+ }
121
+
122
+ throw new Error ( 'Unable to find a usable package manager within NPM, PNPM, Yarn and Yarn 2' ) ;
123
+ }
124
+
125
+ public static getPackageManager (
126
+ {
127
+ force,
128
+ configDir = '.storybook' ,
129
+ storiesPaths,
130
+ ignoreCache = false ,
131
+ } : {
132
+ force ?: PackageManagerName ;
133
+ configDir ?: string ;
134
+ storiesPaths ?: string [ ] ;
135
+ ignoreCache ?: boolean ;
136
+ } = { } ,
137
+ cwd = process . cwd ( )
138
+ ) : JsPackageManager {
139
+ // Check cache first, unless ignored
140
+ const cacheKey = this . getCacheKey ( force , configDir , cwd , storiesPaths ) ;
141
+ const cached = this . cache . get ( cacheKey ) ;
142
+ if ( cached && ! ignoreCache ) {
143
+ return cached ;
144
+ }
145
+
146
+ // Option 1: If the user has provided a forcing flag, we use it
147
+ if ( force && force in this . PROXY_MAP ) {
148
+ const packageManager = new this . PROXY_MAP [ force ] ( { cwd, configDir, storiesPaths } ) ;
152
149
this . cache . set ( cacheKey , packageManager ) ;
153
150
return packageManager ;
154
151
}
155
152
156
- throw new Error ( 'Unable to find a usable package manager within NPM, PNPM, Yarn and Yarn 2' ) ;
153
+ // Option 2: Detect package managers based on some heuristics
154
+ const packageManagerType = this . getPackageManagerType ( cwd ) ;
155
+ const packageManager = new this . PROXY_MAP [ packageManagerType ] ( { cwd, configDir, storiesPaths } ) ;
156
+ this . cache . set ( cacheKey , packageManager ) ;
157
+ return packageManager ;
157
158
}
158
159
159
160
/** Look up map of package manager proxies by name */
0 commit comments