import { Stats } from 'fs' ; import { sep , dirname , join , resolve } from 'path' ; import { lstat , readlink , readFile , realpath } from 'fs-extra' ; import { isCanary } from './is-canary' ; import { getPkgName } from './pkg-name' ; async function isYarn ( ) { let s ; let binPath = process . argv [ 1 ] ; while ( true ) { s = await lstat ( binPath ) ; if ( s . isSymbolicLink ( ) ) { binPath = resolve ( dirname ( binPath ) , await readlink ( binPath ) ) ; } else { break ; } } const pkgPath = join ( dirname ( binPath ) , '..' , 'package.json' ) ; return pkgPath . includes ( join ( 'yarn' , 'global' ) ) ; } async function getConfigPrefix ( ) { const paths = [ process . env . npm_config_userconfig || process . env . NPM_CONFIG_USERCONFIG , join ( process . env . HOME || '/' , '.npmrc' ) , process . env . npm_config_globalconfig || process . env . NPM_CONFIG_GLOBALCONFIG , ] . filter ( Boolean ) ; for ( const configPath of paths ) { if ( ! configPath ) { continue ; } const content = await readFile ( configPath ) . then ( ( buffer ) => buffer . toString ( ) ) . catch ( ( ) => null ) ; if ( content ) { const [ prefix ] = content . split ( '\n' ) . map ( ( line ) => line && line . trim ( ) ) . filter ( ( line ) => line && line . startsWith ( 'prefix' ) ) . map ( ( line ) => line . slice ( line . indexOf ( '=' ) + 1 ) . trim ( ) ) ; if ( prefix ) { return prefix ; } } } return null ; } async function isGlobal ( ) { try { if ( dirname ( process . argv [ 0 ] ) === dirname ( process . argv [ 1 ] ) ) { return true ; } const isWindows = process . platform === 'win32' ; const defaultPath = isWindows ? process . env . APPDATA : '/usr/local/lib' ; const installPath = await realpath ( resolve ( __dirname ) ) ; if ( installPath . includes ( [ '' , 'yarn' , 'global' , 'node_modules' , '' ] . join ( sep ) ) ) { return true ; } const prefixPath = process . env . PREFIX || process . env . npm_config_prefix || process . env . NPM_CONFIG_PREFIX || ( await getConfigPrefix ( ) ) || defaultPath ; if ( ! prefixPath ) { return true ; } return installPath . startsWith ( await realpath ( prefixPath ) ) ; } catch ( _ ) { return true ; } } export default async function getUpdateCommand ( ) { const tag = isCanary ( ) ? 'canary' : 'latest' ; const pkgAndVersion = `${ getPkgName ( ) }@${ tag }` ; if ( await isGlobal ( ) ) { return ( await isYarn ( ) ) ? `yarn global add ${ pkgAndVersion }` : `npm i -g ${ pkgAndVersion }` ; } return ( await isYarn ( ) ) ? `yarn add ${ pkgAndVersion }` : `npm i ${ pkgAndVersion }` ; }