import chalk from "chalk" ; import { execSync } from "child_process" ; import spawn from "cross-spawn" ; import open from "open" ; import * as logger from "./logger" ; const OSX_CHROME = "google chrome" ; enum Actions { NONE = "None" , BROWSER = "Browser" , SCRIPT = "Script" } const DEFAULT_BROWSER = process . env . BROWSER || OSX_CHROME ; const DEFAULT_BROWSER_ARGS = process . env . BROWSER_ARGS ? process . env . BROWSER_ARGS . split ( " " ) : [ ] ; const SUPPORTED_CHROMIUM_BROWSERS = [ "Google Chrome Canary" , "Google Chrome" , "Microsoft Edge" , "Brave Browser" , "Vivaldi" , "Chromium" , ] ; function getBrowserEnv ( ) { const value = DEFAULT_BROWSER ; const args = DEFAULT_BROWSER_ARGS ; let action ; if ( ! value ) { action = Actions . BROWSER ; } else if ( value . toLowerCase ( ) . endsWith ( ".js" ) ) { action = Actions . SCRIPT ; } else if ( value . toLowerCase ( ) === "none" ) { action = Actions . NONE ; } else { action = Actions . BROWSER ; } return { action , value , args } ; } function executeNodeScript ( scriptPath , url ) { const extraArgs = process . argv . slice ( 2 ) ; const child = spawn ( process . execPath , [ scriptPath , ... extraArgs , url ] , { stdio : "inherit" , } ) ; child . on ( "close" , ( code ) => { if ( code !== 0 ) { logger . log ( ) ; logger . log ( chalk . red ( "The script specified as BROWSER environment variable failed." ) ) ; logger . log ( `${ chalk . cyan ( scriptPath ) } exited with code ${ code }.` ) ; logger . log ( ) ; return ; } } ) ; return true ; } async function startBrowserProcess ( targetBrowser , url , args ) { const shouldTryOpenChromiumWithAppleScript = process . platform === "darwin" && targetBrowser === OSX_CHROME ; if ( shouldTryOpenChromiumWithAppleScript ) { for ( const chromiumBrowser of SUPPORTED_CHROMIUM_BROWSERS ) { try { execSync ( 'ps cax | grep "' + chromiumBrowser + '"' ) ; execSync ( 'osascript openChrome.applescript "' + encodeURI ( url ) + '" "' + chromiumBrowser + '"' , { cwd : __dirname , stdio : "ignore" , } ) ; return true ; } catch ( err ) { } } } if ( process . platform === "darwin" && targetBrowser === "open" ) { targetBrowser = undefined ; } try { await open ( url , { app : targetBrowser ? { name : targetBrowser , arguments : args , } : undefined , wait : false , } ) ; return true ; } catch ( err ) { return false ; } } /**
 * Reads the BROWSER environment variable and decides what to do with it. Returns
 * true if it opened a browser or ran a node.js script, otherwise false.
 */ export default async function openBrowser ( url ) { const { action , value , args } = getBrowserEnv ( ) ; switch ( action ) { case Actions . NONE : return false ; case Actions . SCRIPT : return executeNodeScript ( value , url ) ; case Actions . BROWSER : return startBrowserProcess ( value , url , args ) ; default : throw new Error ( "Not implemented." ) ; } }