@@ -23,6 +23,7 @@ const LOCKFILE_NAMES: Readonly<Record<PackageManager, string | readonly string[]
2323 [ PackageManager . Pnpm ] : 'pnpm-lock.yaml' ,
2424 [ PackageManager . Bun ] : [ 'bun.lockb' , 'bun.lock' ] ,
2525 [ PackageManager . Npm ] : 'package-lock.json' ,
26+ [ PackageManager . Deno ] : 'deno.lock' ,
2627} ;
2728
2829interface PackageManagerOptions {
@@ -166,6 +167,14 @@ export class PackageManagerUtils {
166167 prefix : '--cwd' ,
167168 noLockfile : '--no-save' ,
168169 } ;
170+ case PackageManager . Deno :
171+ return {
172+ saveDev : '--dev' ,
173+ install : 'add' ,
174+ installAll : 'install' ,
175+ prefix : '--root' ,
176+ noLockfile : '--no-lock' ,
177+ } ;
169178 default :
170179 return {
171180 saveDev : '--save-dev' ,
@@ -179,12 +188,12 @@ export class PackageManagerUtils {
179188
180189 private async run (
181190 args : string [ ] ,
182- options : { cwd ?: string ; silent ?: boolean } = { } ,
191+ options : { cwd ?: string ; silent ?: boolean ; } = { } ,
183192 ) : Promise < boolean > {
184193 const { cwd = process . cwd ( ) , silent = false } = options ;
185194
186195 return new Promise ( ( resolve ) => {
187- const bufferedOutput : { stream : NodeJS . WriteStream ; data : Buffer } [ ] = [ ] ;
196+ const bufferedOutput : { stream : NodeJS . WriteStream ; data : Buffer ; } [ ] = [ ] ;
188197
189198 const childProcess = spawn ( `${ this . name } ${ args . join ( ' ' ) } ` , {
190199 // Always pipe stderr to allow for failures to be reported
@@ -212,7 +221,8 @@ export class PackageManagerUtils {
212221 @memoize
213222 private getVersion ( name : PackageManager ) : string | undefined {
214223 try {
215- return execSync ( `${ name } --version` , {
224+ const versionArg = name !== PackageManager . Deno ? '--version' : '-v' ;
225+ const version = execSync ( `${ name } ${ versionArg } ` , {
216226 encoding : 'utf8' ,
217227 stdio : [ 'ignore' , 'pipe' , 'ignore' ] ,
218228 env : {
@@ -222,6 +232,13 @@ export class PackageManagerUtils {
222232 NPM_CONFIG_UPDATE_NOTIFIER : 'false' ,
223233 } ,
224234 } ) . trim ( ) ;
235+
236+ if ( name === PackageManager . Deno ) {
237+ // Deno CLI outputs "deno 2.4.4"
238+ return version . replace ( 'deno ' , '' ) ;
239+ }
240+
241+ return version ;
225242 } catch {
226243 return undefined ;
227244 }
@@ -239,14 +256,21 @@ export class PackageManagerUtils {
239256 const hasYarnLock = this . hasLockfile ( PackageManager . Yarn , filesInRoot ) ;
240257 const hasPnpmLock = this . hasLockfile ( PackageManager . Pnpm , filesInRoot ) ;
241258 const hasBunLock = this . hasLockfile ( PackageManager . Bun , filesInRoot ) ;
259+ const hasDenoLock = this . hasLockfile ( PackageManager . Deno , filesInRoot ) ;
242260
243261 // PERF NOTE: `this.getVersion` spawns the package a the child_process which can take around ~300ms at times.
244262 // Therefore, we should only call this method when needed. IE: don't call `this.getVersion(PackageManager.Pnpm)` unless truly needed.
245263 // The result of this method is not stored in a variable because it's memoized.
246264
247265 if ( hasNpmLock ) {
248266 // Has NPM lock file.
249- if ( ! hasYarnLock && ! hasPnpmLock && ! hasBunLock && this . getVersion ( PackageManager . Npm ) ) {
267+ if (
268+ ! hasYarnLock &&
269+ ! hasPnpmLock &&
270+ ! hasBunLock &&
271+ ! hasDenoLock &&
272+ this . getVersion ( PackageManager . Npm )
273+ ) {
250274 // Only NPM lock file and NPM binary is available.
251275 return PackageManager . Npm ;
252276 }
@@ -261,6 +285,9 @@ export class PackageManagerUtils {
261285 } else if ( hasBunLock && this . getVersion ( PackageManager . Bun ) ) {
262286 // Bun lock file and Bun binary is available.
263287 return PackageManager . Bun ;
288+ } else if ( hasDenoLock && this . getVersion ( PackageManager . Deno ) ) {
289+ // Deno lock file and Deno binary is available.
290+ return PackageManager . Deno ;
264291 }
265292 }
266293
@@ -269,13 +296,16 @@ export class PackageManagerUtils {
269296 const hasYarn = ! ! this . getVersion ( PackageManager . Yarn ) ;
270297 const hasPnpm = ! ! this . getVersion ( PackageManager . Pnpm ) ;
271298 const hasBun = ! ! this . getVersion ( PackageManager . Bun ) ;
299+ const hasDeno = ! ! this . getVersion ( PackageManager . Deno ) ;
272300
273- if ( hasYarn && ! hasPnpm && ! hasBun ) {
301+ if ( hasYarn && ! hasPnpm && ! hasBun && ! hasDeno ) {
274302 return PackageManager . Yarn ;
275- } else if ( hasPnpm && ! hasYarn && ! hasBun ) {
303+ } else if ( hasPnpm && ! hasYarn && ! hasBun && ! hasDeno ) {
276304 return PackageManager . Pnpm ;
277- } else if ( hasBun && ! hasYarn && ! hasPnpm ) {
305+ } else if ( hasBun && ! hasYarn && ! hasPnpm && ! hasDeno ) {
278306 return PackageManager . Bun ;
307+ } else if ( hasDeno && ! hasYarn && ! hasPnpm && ! hasBun ) {
308+ return PackageManager . Deno ;
279309 }
280310 }
281311
0 commit comments