@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
60 lines (51 loc) • 2.26 kB
JavaScript
const childProcess = require('child_process')
const os = require('os')
module.exports.openURL = (urlArg, port) => {
const url = _url(urlArg, port)
return _open(url)
}
function _url (urlArg, port) {
const base = `http://localhost:${port}/`
if (typeof urlArg === 'string') {
if (urlArg.startsWith('http')) return urlArg
return base + urlArg // partial URL
}
return base
}
function _open(args) {
// http://stackoverflow.com/q/1480971/3191, but see below for Windows.
let platform = process.platform
// Attempt to detect Windows Subsystem for Linux (WSL). WSL itself as Linux (which works in most cases), but in
// this specific case we need to treat it as actually being Windows. The 'Windows-way' of opening things through
// cmd.exe works just fine here, whereas using xdg-open does not, since there is no X Windows in WSL.
if (platform === 'linux' && os.release().indexOf('Microsoft') !== -1) {
platform = 'win32'
}
let command = process.env.BROWSER
if (!command) {
switch (platform) {
case 'win32': { command = 'cmd.exe'; break }
case 'darwin': { command = 'open'; break }
default: { command = 'xdg-open'; break }
}
}
if (typeof args === 'string') args = [args]
if (platform === 'win32') {
// On Windows, we really want to use the 'start' command. But, the rules regarding arguments with spaces, and
// escaping them with quotes, can get really arcane. So the easiest way to deal with this is to pass off the
// responsibility to 'cmd /c', which has that logic built in.
//
// Furthermore, if 'cmd /c' double-quoted the first parameter, then 'start' will interpret it as a window title,
// so we need to add a dummy empty-string window title: http://stackoverflow.com/a/154090/3191
//
// Additionally, on Windows ampersand and caret need to be escaped when passed to 'start'
args = args.map(value => value.replace(/[&^]/g, '^$&'))
args = ['/c', 'start'].concat(args)
}
const delay = parseInt(process.env.CDS_WATCH_OPEN_DELAY) || 1000
setTimeout(() => {
childProcess.execFile(command, args, null, err => {
err && console.error(`Error opening '${command} ${args}' : ${err.message}`)
})
}, delay);
}