From 8b11819f59b26cf144caf50775c2365d9184f888 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Fri, 27 Jan 2023 19:20:21 +0800 Subject: [PATCH 01/23] Added browser and browserPrivate under open.apps --- index.d.ts | 15 ++++++++++++-- index.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---- package.json | 3 ++- test.js | 16 +++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9c8f2a3..cde0ebe 100644 --- a/index.d.ts +++ b/index.d.ts @@ -66,7 +66,9 @@ declare namespace open { type AppName = | 'chrome' | 'firefox' - | 'edge'; + | 'edge' + | 'browser' + | 'browserPrivate'; type App = { name: string | readonly string[]; @@ -102,6 +104,9 @@ declare const open: { // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); + + // Opens the url in the default browser incognito mode + await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); ``` */ ( @@ -140,9 +145,15 @@ declare const open: { // Open Firefox await openApp(apps.firefox); - // Open Chrome incognito mode + // Open Chrome in incognito mode await openApp(apps.chrome, {arguments: ['--incognito']}); + // Open default browser + await openApp(apps.browser); + + // Open default browser in incognito mode + await openApp(apps.browserPrivate); + // Open Xcode await openApp('xcode'); ``` diff --git a/index.js b/index.js index 290b4ec..fddbc3c 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ const {promises: fs, constants: fsConstants} = require('fs'); const isWsl = require('is-wsl'); const isDocker = require('is-docker'); const defineLazyProperty = require('define-lazy-prop'); +const defaultBrowser = require('x-default-browser'); // Path to included `xdg-open`. const localXdgOpenPath = path.join(__dirname, 'xdg-open'); @@ -98,6 +99,49 @@ const baseOpen = async options => { })); } + if (app === 'browser') { + return defaultBrowser((error, browser) => { + if (error) { + throw error; + } + + const browserName = browser.commonName; + + baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments + } + }); + }); + } + + if (app === 'browserPrivate') { + // Incognito or equivalent flags for each of the browser in open.apps + const flags = { + chrome: '--incognito', + firefox: '--private-window', + edge: '--inPrivate' + }; + + return defaultBrowser((error, browser) => { + if (error) { + throw error; + } + + const browserName = browser.commonName; + + baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: [...appArguments, flags[browserName]] + } + }); + }); + } + let command; const cliArguments = []; const childProcessOptions = {}; @@ -130,7 +174,7 @@ const baseOpen = async options => { cliArguments.push( '-NoProfile', '-NonInteractive', - '–ExecutionPolicy', + '-ExecutionPolicy', 'Bypass', '-EncodedCommand' ); @@ -148,9 +192,9 @@ const baseOpen = async options => { if (app) { // Double quote with double quotes to ensure the inner quotes are passed through. // Inner quotes are delimited for PowerShell interpretation with backticks. - encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList'); + encodedArguments.push(`"\`"${app}\`""`); if (options.target) { - appArguments.unshift(options.target); + appArguments.push(options.target); } } else if (options.target) { encodedArguments.push(`"${options.target}"`); @@ -158,7 +202,7 @@ const baseOpen = async options => { if (appArguments.length > 0) { appArguments = appArguments.map(arg => `"\`"${arg}\`""`); - encodedArguments.push(appArguments.join(',')); + encodedArguments.push('-ArgumentList', appArguments.join(',')); } // Using Base64-encoded command, accepted by PowerShell, to allow special characters. @@ -309,6 +353,10 @@ defineLazyProperty(apps, 'edge', () => detectPlatformBinary({ wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe' })); +defineLazyProperty(apps, 'browser', () => 'browser'); + +defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); + open.apps = apps; open.openApp = openApp; diff --git a/package.json b/package.json index 0b8bb25..23b235f 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,8 @@ "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "is-wsl": "^2.2.0", + "x-default-browser": "^0.5.0" }, "devDependencies": { "@types/node": "^15.0.0", diff --git a/test.js b/test.js index 2fe1c38..7393735 100644 --- a/test.js +++ b/test.js @@ -78,3 +78,19 @@ test('open Firefox without arguments', async t => { test('open Chrome in incognito mode', async t => { await t.notThrowsAsync(openApp(open.apps.chrome, {arguments: ['--incognito'], newInstance: true})); }); + +test('open URL with default browser argument', async t => { + await t.notThrowsAsync(open('https://sindresorhus.com', {app: {name: open.apps.browser}})); +}); + +test('open URL with default browser in incognito mode', async t => { + await t.notThrowsAsync(open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}})); +}); + +test('open default browser', async t => { + await t.notThrowsAsync(openApp(open.apps.browser, {newInstance: true})); +}); + +test('open default browser in incognito mode', async t => { + await t.notThrowsAsync(openApp(open.apps.browserPrivate, {newInstance: true})); +}); From 7253ffc65fe75e0452b58f36d7b38a15e3317789 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 22:51:02 +0800 Subject: [PATCH 02/23] Switched default browser library --- index.js | 56 +++++++++++++++++++++------------------------------- package.json | 4 +++- test.js | 4 ++-- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/index.js b/index.js index fddbc3c..3629bb9 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,10 @@ -const path = require('path'); -const childProcess = require('child_process'); -const {promises: fs, constants: fsConstants} = require('fs'); -const isWsl = require('is-wsl'); -const isDocker = require('is-docker'); -const defineLazyProperty = require('define-lazy-prop'); -const defaultBrowser = require('x-default-browser'); +import path from 'path'; +import childProcess from 'child_process'; +import {promises as fs, constants as fsConstants} from 'fs'; +import isWsl from 'is-wsl'; +import isDocker from 'is-docker'; +import defineLazyProperty from 'define-lazy-prop'; +import defaultBrowser from 'default-browser'; // Path to included `xdg-open`. const localXdgOpenPath = path.join(__dirname, 'xdg-open'); @@ -100,20 +100,14 @@ const baseOpen = async options => { } if (app === 'browser') { - return defaultBrowser((error, browser) => { - if (error) { - throw error; + const browser = await defaultBrowser(); + const browserName = browser.name.toLowerCase(); + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments } - - const browserName = browser.commonName; - - baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: appArguments - } - }); }); } @@ -125,20 +119,14 @@ const baseOpen = async options => { edge: '--inPrivate' }; - return defaultBrowser((error, browser) => { - if (error) { - throw error; + const browser = await defaultBrowser(); + const browserName = browser.name.toLowerCase(); + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: [...appArguments, flags[browserName]] } - - const browserName = browser.commonName; - - baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: [...appArguments, flags[browserName]] - } - }); }); } @@ -360,4 +348,4 @@ defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); open.apps = apps; open.openApp = openApp; -module.exports = open; +export {open}; diff --git a/package.json b/package.json index 23b235f..08bd0e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "open", "version": "8.4.0", + "type": "module", "description": "Open stuff like URLs, files, executables. Cross-platform.", "license": "MIT", "repository": "sindresorhus/open", @@ -14,7 +15,7 @@ "node": ">=12" }, "scripts": { - "test": "xo && tsd" + "test": "xo && tsd && ava" }, "files": [ "index.js", @@ -51,6 +52,7 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", + "default-browser": "^3.1.0", "x-default-browser": "^0.5.0" }, "devDependencies": { diff --git a/test.js b/test.js index 7393735..13de8e7 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ -const test = require('ava'); -const open = require('.'); +import test from 'ava'; +import {open} from './index.js'; const {openApp} = open; // Tests only checks that opening doesn't return an error From 5376f3da2c09262acea4694fbb651fd76cce9f30 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:17:14 +0800 Subject: [PATCH 03/23] Updated docs --- index.d.ts | 25 +++++++++++++------------ readme.md | 14 ++++++++++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/index.d.ts b/index.d.ts index cde0ebe..23b66f3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -90,13 +90,13 @@ declare const open: { @example ``` - import open = require('open'); + import {open} from 'open'; - // Opens the image in the default image viewer + // Opens the image in the default image viewer. await open('unicorn.png', {wait: true}); - console.log('The image viewer app closed'); + console.log('The image viewer app quit'); - // Opens the url in the default browser + // Opens the URL in the default browser. await open('https://sindresorhus.com'); // Opens the URL in a specified browser. @@ -105,7 +105,7 @@ declare const open: { // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); - // Opens the url in the default browser incognito mode + // Opens the URL in the default browser in incognito mode. await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); ``` */ @@ -119,7 +119,7 @@ declare const open: { @example ``` - import open = require('open'); + import {open} from 'open'; await open('https://google.com', { app: { @@ -140,21 +140,22 @@ declare const open: { @example ``` - const {apps, openApp} = require('open'); + import {open} from 'open'; + const {apps, openApp} = open; - // Open Firefox + // Open Firefox. await openApp(apps.firefox); - // Open Chrome in incognito mode + // Open Chrome in incognito mode. await openApp(apps.chrome, {arguments: ['--incognito']}); - // Open default browser + // Open default browser. await openApp(apps.browser); - // Open default browser in incognito mode + // Open default browser in incognito mode. await openApp(apps.browserPrivate); - // Open Xcode + // Open Xcode. await openApp('xcode'); ``` */ diff --git a/readme.md b/readme.md index 51f1359..bc075e9 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ npm install open ## Usage ```js -const open = require('open'); +import {open} from 'open'; // Opens the image in the default image viewer and waits for the opened app to quit. await open('unicorn.png', {wait: true}); @@ -41,10 +41,13 @@ await open('https://sindresorhus.com', {app: {name: 'firefox'}}); // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); -// Open an app +// Opens the URL in the default browser in incognito mode. +await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); + +// Open an app. await open.openApp('xcode'); -// Open an app with arguments +// Open an app with arguments. await open.openApp(open.apps.chrome, {arguments: ['--incognito']}); ``` @@ -121,7 +124,7 @@ We do not recommend setting this option. The convention for success is exit code An object containing auto-detected binary names for common apps. Useful to work around [cross-platform differences](#app). ```js -const open = require('open'); +import {open} from 'open'; await open('https://google.com', { app: { @@ -129,12 +132,15 @@ await open('https://google.com', { } }); ``` +`browser` and `browserPrivate` can also be used to access the user's default browser through [`default-browser`](https://github.com/sindresorhus/default-browser). #### Supported apps - [`chrome`](https://www.google.com/chrome) - Web browser - [`firefox`](https://www.mozilla.org/firefox) - Web browser - [`edge`](https://www.microsoft.com/edge) - Web browser +- `browser` - Default web browser +- `browserPrivate` - Default web browser in incognito mode ### open.openApp(name, options?) From cc68d5ab741ec839188862dd658a5c32c228bdae Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:28:38 +0800 Subject: [PATCH 04/23] Fixed issue with __dirname --- index.js | 2 ++ package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 3629bb9..c354c3b 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ import path from 'path'; +import {fileURLToPath} from 'url'; import childProcess from 'child_process'; import {promises as fs, constants as fsConstants} from 'fs'; import isWsl from 'is-wsl'; @@ -7,6 +8,7 @@ import defineLazyProperty from 'define-lazy-prop'; import defaultBrowser from 'default-browser'; // Path to included `xdg-open`. +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const localXdgOpenPath = path.join(__dirname, 'xdg-open'); const {platform, arch} = process; diff --git a/package.json b/package.json index 08bd0e3..06dc76c 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", - "default-browser": "^3.1.0", - "x-default-browser": "^0.5.0" + "url": "^0.11.0", + "default-browser": "^3.1.0" }, "devDependencies": { "@types/node": "^15.0.0", From 5828be0323e023f31563278bc4f00daab17c5605 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:32:32 +0800 Subject: [PATCH 05/23] Fix: removed ava test from test script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06dc76c..bc1e591 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "node": ">=12" }, "scripts": { - "test": "xo && tsd && ava" + "test": "xo && tsd" }, "files": [ "index.js", From 4cf1a6d0de33b5c6788ec2a64194076853ba4857 Mon Sep 17 00:00:00 2001 From: Khairul Azhar Kasmiran Date: Tue, 31 Jan 2023 01:09:47 +0800 Subject: [PATCH 06/23] Fix the `app` argument with WSL (#295) --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 290b4ec..7ad8122 100644 --- a/index.js +++ b/index.js @@ -120,7 +120,7 @@ const baseOpen = async options => { if (app) { cliArguments.push('-a', app); } - } else if (platform === 'win32' || (isWsl && !isDocker())) { + } else if (platform === 'win32' || (isWsl && !isDocker() && !app)) { const mountPoint = await getWslDrivesMountPoint(); command = isWsl ? From 5c6582ae2f1f301d86095d7ceebe976d44b11052 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Wed, 1 Feb 2023 22:18:55 +0800 Subject: [PATCH 07/23] Removed unnecessary url import --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index bc1e591..38b864d 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", - "url": "^0.11.0", "default-browser": "^3.1.0" }, "devDependencies": { From 53bb56503375cc82a3934949031250e554abc5cb Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Wed, 1 Feb 2023 22:21:53 +0800 Subject: [PATCH 08/23] Changed exports and specified supported browsers --- index.d.ts | 6 +++--- index.js | 43 ++++++++++++++++++++++--------------------- readme.md | 6 ++++-- test.js | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/index.d.ts b/index.d.ts index 23b66f3..95727f7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -90,7 +90,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; // Opens the image in the default image viewer. await open('unicorn.png', {wait: true}); @@ -119,7 +119,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; await open('https://google.com', { app: { @@ -140,7 +140,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; const {apps, openApp} = open; // Open Firefox. diff --git a/index.js b/index.js index c354c3b..aaf8272 100644 --- a/index.js +++ b/index.js @@ -101,20 +101,8 @@ const baseOpen = async options => { })); } - if (app === 'browser') { - const browser = await defaultBrowser(); - const browserName = browser.name.toLowerCase(); - return baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: appArguments - } - }); - } - - if (app === 'browserPrivate') { - // Incognito or equivalent flags for each of the browser in open.apps + if (app === 'browser' || app === 'browserPrivate') { + // Incognito or equivalent flags for each browser in open.apps const flags = { chrome: '--incognito', firefox: '--private-window', @@ -123,13 +111,25 @@ const baseOpen = async options => { const browser = await defaultBrowser(); const browserName = browser.name.toLowerCase(); - return baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: [...appArguments, flags[browserName]] + + const supportedBrowsers = Object.keys(flags); + for (const supportedBrowser of supportedBrowsers) { + if (browserName.includes(supportedBrowser)) { + if (app === 'browserPrivate') { + appArguments.push(flags[supportedBrowser]); + } + + return baseOpen({ + ...options, + app: { + name: open.apps[supportedBrowser], + arguments: appArguments + } + }); } - }); + } + + throw new Error(`${browserName} as the default browser is not supported`); } let command; @@ -350,4 +350,5 @@ defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); open.apps = apps; open.openApp = openApp; -export {open}; +export {apps}; +export default open; diff --git a/readme.md b/readme.md index bc075e9..35c0e31 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ npm install open ## Usage ```js -import {open} from 'open'; +import open from 'open'; // Opens the image in the default image viewer and waits for the opened app to quit. await open('unicorn.png', {wait: true}); @@ -124,7 +124,7 @@ We do not recommend setting this option. The convention for success is exit code An object containing auto-detected binary names for common apps. Useful to work around [cross-platform differences](#app). ```js -import {open} from 'open'; +import open from 'open'; await open('https://google.com', { app: { @@ -142,6 +142,8 @@ await open('https://google.com', { - `browser` - Default web browser - `browserPrivate` - Default web browser in incognito mode +`browser` and `browserPrivate` currently support `chrome`, `firefox` and `edge`. + ### open.openApp(name, options?) Open an app. diff --git a/test.js b/test.js index 13de8e7..af37e70 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import test from 'ava'; -import {open} from './index.js'; +import open from './index.js'; const {openApp} = open; // Tests only checks that opening doesn't return an error From 051edcae8f698905e2544a5bb3163bd70a185dab Mon Sep 17 00:00:00 2001 From: Jeff Fisher Date: Wed, 8 Feb 2023 06:18:53 -0600 Subject: [PATCH 09/23] Fix `allowNonzeroExitCode` option (#296) --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 7ad8122..72d1cdc 100644 --- a/index.js +++ b/index.js @@ -209,7 +209,7 @@ const baseOpen = async options => { subprocess.once('error', reject); subprocess.once('close', exitCode => { - if (options.allowNonzeroExitCode && exitCode > 0) { + if (!options.allowNonzeroExitCode && exitCode > 0) { reject(new Error(`Exited with code ${exitCode}`)); return; } From 13a800c711e4450350263b78365e61d32c513b64 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Feb 2023 19:19:21 +0700 Subject: [PATCH 10/23] Meta tweaks --- readme.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/readme.md b/readme.md index 51f1359..282e0a6 100644 --- a/readme.md +++ b/readme.md @@ -169,15 +169,3 @@ These arguments are app dependent. Check the app's documentation for what argume - [open-cli](https://github.com/sindresorhus/open-cli) - CLI for this module - [open-editor](https://github.com/sindresorhus/open-editor) - Open files in your editor at a specific line and column - ---- - -
- - Get professional support for this package with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
From 27e4e3a193928fe0cfb43cee746292df339bb332 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Feb 2023 19:21:18 +0700 Subject: [PATCH 11/23] 8.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b8bb25..34b4cc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open", - "version": "8.4.0", + "version": "8.4.1", "description": "Open stuff like URLs, files, executables. Cross-platform.", "license": "MIT", "repository": "sindresorhus/open", From 51fae87baffdb3952869c8e35a88dd125f36d3a5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 20 Feb 2023 19:42:08 +0700 Subject: [PATCH 12/23] Fix support for Podman Fixes sindresorhus/is-docker#14 --- index.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 72d1cdc..f66dc4c 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,25 @@ const localXdgOpenPath = path.join(__dirname, 'xdg-open'); const {platform, arch} = process; +// Podman detection +const hasContainerEnv = () => { + try { + fs.statSync('/run/.containerenv'); + return true; + } catch { + return false; + } +}; + +let cachedResult; +function isInsideContainer() { + if (cachedResult === undefined) { + cachedResult = hasContainerEnv() || isDocker(); + } + + return cachedResult; +} + /** Get the mount point for fixed drives in WSL. @@ -120,7 +139,7 @@ const baseOpen = async options => { if (app) { cliArguments.push('-a', app); } - } else if (platform === 'win32' || (isWsl && !isDocker() && !app)) { + } else if (platform === 'win32' || (isWsl && !isInsideContainer() && !app)) { const mountPoint = await getWslDrivesMountPoint(); command = isWsl ? From cbc008bab21f657475b54e33a823b2941737da6f Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 20 Feb 2023 19:43:02 +0700 Subject: [PATCH 13/23] 8.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34b4cc7..8987b5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open", - "version": "8.4.1", + "version": "8.4.2", "description": "Open stuff like URLs, files, executables. Cross-platform.", "license": "MIT", "repository": "sindresorhus/open", From b3212fbfc713e2efec6391d72122fd486a7fa018 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 13 Mar 2023 10:27:11 +0800 Subject: [PATCH 14/23] Mapped browser IDs to supported browsers --- index.js | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/index.js b/index.js index aaf8272..a2cd173 100644 --- a/index.js +++ b/index.js @@ -102,7 +102,18 @@ const baseOpen = async options => { } if (app === 'browser' || app === 'browserPrivate') { - // Incognito or equivalent flags for each browser in open.apps + // IDs from default-browser for macOS and windows are the same + const ids = { + 'com.google.chrome': 'chrome', + 'google-chrome.desktop': 'chrome', + 'org.mozilla.firefox': 'firefox', + 'firefox.desktop': 'firefox', + 'com.microsoft.msedge': 'edge', + 'com.microsoft.edge': 'edge', + 'microsoft-edge.desktop': 'edge' + }; + + // Incognito flags for each browser in open.apps const flags = { chrome: '--incognito', firefox: '--private-window', @@ -110,26 +121,23 @@ const baseOpen = async options => { }; const browser = await defaultBrowser(); - const browserName = browser.name.toLowerCase(); - - const supportedBrowsers = Object.keys(flags); - for (const supportedBrowser of supportedBrowsers) { - if (browserName.includes(supportedBrowser)) { - if (app === 'browserPrivate') { - appArguments.push(flags[supportedBrowser]); - } + if (browser.id in ids) { + const browserName = ids[browser.id]; - return baseOpen({ - ...options, - app: { - name: open.apps[supportedBrowser], - arguments: appArguments - } - }); + if (app === 'browserPrivate') { + appArguments.push(flags[browserName]); } + + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments + } + }); } - throw new Error(`${browserName} as the default browser is not supported`); + throw new Error(`${browser.name} is not supported as a default browser`); } let command; From aa21cadc19057ef16e877aff2421aa47f40fd18e Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Fri, 27 Jan 2023 19:20:21 +0800 Subject: [PATCH 15/23] Added browser and browserPrivate under open.apps --- index.d.ts | 15 ++++++++++++-- index.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---- package.json | 3 ++- test.js | 16 +++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9c8f2a3..cde0ebe 100644 --- a/index.d.ts +++ b/index.d.ts @@ -66,7 +66,9 @@ declare namespace open { type AppName = | 'chrome' | 'firefox' - | 'edge'; + | 'edge' + | 'browser' + | 'browserPrivate'; type App = { name: string | readonly string[]; @@ -102,6 +104,9 @@ declare const open: { // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); + + // Opens the url in the default browser incognito mode + await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); ``` */ ( @@ -140,9 +145,15 @@ declare const open: { // Open Firefox await openApp(apps.firefox); - // Open Chrome incognito mode + // Open Chrome in incognito mode await openApp(apps.chrome, {arguments: ['--incognito']}); + // Open default browser + await openApp(apps.browser); + + // Open default browser in incognito mode + await openApp(apps.browserPrivate); + // Open Xcode await openApp('xcode'); ``` diff --git a/index.js b/index.js index f66dc4c..40a0b0f 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ const {promises: fs, constants: fsConstants} = require('fs'); const isWsl = require('is-wsl'); const isDocker = require('is-docker'); const defineLazyProperty = require('define-lazy-prop'); +const defaultBrowser = require('x-default-browser'); // Path to included `xdg-open`. const localXdgOpenPath = path.join(__dirname, 'xdg-open'); @@ -117,6 +118,49 @@ const baseOpen = async options => { })); } + if (app === 'browser') { + return defaultBrowser((error, browser) => { + if (error) { + throw error; + } + + const browserName = browser.commonName; + + baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments + } + }); + }); + } + + if (app === 'browserPrivate') { + // Incognito or equivalent flags for each of the browser in open.apps + const flags = { + chrome: '--incognito', + firefox: '--private-window', + edge: '--inPrivate' + }; + + return defaultBrowser((error, browser) => { + if (error) { + throw error; + } + + const browserName = browser.commonName; + + baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: [...appArguments, flags[browserName]] + } + }); + }); + } + let command; const cliArguments = []; const childProcessOptions = {}; @@ -149,7 +193,7 @@ const baseOpen = async options => { cliArguments.push( '-NoProfile', '-NonInteractive', - '–ExecutionPolicy', + '-ExecutionPolicy', 'Bypass', '-EncodedCommand' ); @@ -167,9 +211,9 @@ const baseOpen = async options => { if (app) { // Double quote with double quotes to ensure the inner quotes are passed through. // Inner quotes are delimited for PowerShell interpretation with backticks. - encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList'); + encodedArguments.push(`"\`"${app}\`""`); if (options.target) { - appArguments.unshift(options.target); + appArguments.push(options.target); } } else if (options.target) { encodedArguments.push(`"${options.target}"`); @@ -177,7 +221,7 @@ const baseOpen = async options => { if (appArguments.length > 0) { appArguments = appArguments.map(arg => `"\`"${arg}\`""`); - encodedArguments.push(appArguments.join(',')); + encodedArguments.push('-ArgumentList', appArguments.join(',')); } // Using Base64-encoded command, accepted by PowerShell, to allow special characters. @@ -328,6 +372,10 @@ defineLazyProperty(apps, 'edge', () => detectPlatformBinary({ wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe' })); +defineLazyProperty(apps, 'browser', () => 'browser'); + +defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); + open.apps = apps; open.openApp = openApp; diff --git a/package.json b/package.json index 8987b5a..061e689 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,8 @@ "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "is-wsl": "^2.2.0", + "x-default-browser": "^0.5.0" }, "devDependencies": { "@types/node": "^15.0.0", diff --git a/test.js b/test.js index 2fe1c38..7393735 100644 --- a/test.js +++ b/test.js @@ -78,3 +78,19 @@ test('open Firefox without arguments', async t => { test('open Chrome in incognito mode', async t => { await t.notThrowsAsync(openApp(open.apps.chrome, {arguments: ['--incognito'], newInstance: true})); }); + +test('open URL with default browser argument', async t => { + await t.notThrowsAsync(open('https://sindresorhus.com', {app: {name: open.apps.browser}})); +}); + +test('open URL with default browser in incognito mode', async t => { + await t.notThrowsAsync(open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}})); +}); + +test('open default browser', async t => { + await t.notThrowsAsync(openApp(open.apps.browser, {newInstance: true})); +}); + +test('open default browser in incognito mode', async t => { + await t.notThrowsAsync(openApp(open.apps.browserPrivate, {newInstance: true})); +}); From f7b4c6ddef0ec7c2ead43686da3c4158dbe03326 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 22:51:02 +0800 Subject: [PATCH 16/23] Switched default browser library --- index.js | 56 +++++++++++++++++++++------------------------------- package.json | 5 +++-- test.js | 4 ++-- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/index.js b/index.js index 40a0b0f..1cc1052 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,10 @@ -const path = require('path'); -const childProcess = require('child_process'); -const {promises: fs, constants: fsConstants} = require('fs'); -const isWsl = require('is-wsl'); -const isDocker = require('is-docker'); -const defineLazyProperty = require('define-lazy-prop'); -const defaultBrowser = require('x-default-browser'); +import path from 'path'; +import childProcess from 'child_process'; +import {promises as fs, constants as fsConstants} from 'fs'; +import isWsl from 'is-wsl'; +import isDocker from 'is-docker'; +import defineLazyProperty from 'define-lazy-prop'; +import defaultBrowser from 'default-browser'; // Path to included `xdg-open`. const localXdgOpenPath = path.join(__dirname, 'xdg-open'); @@ -119,20 +119,14 @@ const baseOpen = async options => { } if (app === 'browser') { - return defaultBrowser((error, browser) => { - if (error) { - throw error; + const browser = await defaultBrowser(); + const browserName = browser.name.toLowerCase(); + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments } - - const browserName = browser.commonName; - - baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: appArguments - } - }); }); } @@ -144,20 +138,14 @@ const baseOpen = async options => { edge: '--inPrivate' }; - return defaultBrowser((error, browser) => { - if (error) { - throw error; + const browser = await defaultBrowser(); + const browserName = browser.name.toLowerCase(); + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: [...appArguments, flags[browserName]] } - - const browserName = browser.commonName; - - baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: [...appArguments, flags[browserName]] - } - }); }); } @@ -379,4 +367,4 @@ defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); open.apps = apps; open.openApp = openApp; -module.exports = open; +export {open}; diff --git a/package.json b/package.json index 061e689..18a9cd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open", - "version": "8.4.2", + "version": "8.4.0", "description": "Open stuff like URLs, files, executables. Cross-platform.", "license": "MIT", "repository": "sindresorhus/open", @@ -14,7 +14,7 @@ "node": ">=12" }, "scripts": { - "test": "xo && tsd" + "test": "xo && tsd && ava" }, "files": [ "index.js", @@ -51,6 +51,7 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", + "default-browser": "^3.1.0", "x-default-browser": "^0.5.0" }, "devDependencies": { diff --git a/test.js b/test.js index 7393735..13de8e7 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ -const test = require('ava'); -const open = require('.'); +import test from 'ava'; +import {open} from './index.js'; const {openApp} = open; // Tests only checks that opening doesn't return an error From 238770d669f5015a330672ad68263aa5d571b501 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:17:14 +0800 Subject: [PATCH 17/23] Updated docs --- index.d.ts | 25 +++++++++++++------------ readme.md | 14 ++++++++++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/index.d.ts b/index.d.ts index cde0ebe..23b66f3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -90,13 +90,13 @@ declare const open: { @example ``` - import open = require('open'); + import {open} from 'open'; - // Opens the image in the default image viewer + // Opens the image in the default image viewer. await open('unicorn.png', {wait: true}); - console.log('The image viewer app closed'); + console.log('The image viewer app quit'); - // Opens the url in the default browser + // Opens the URL in the default browser. await open('https://sindresorhus.com'); // Opens the URL in a specified browser. @@ -105,7 +105,7 @@ declare const open: { // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); - // Opens the url in the default browser incognito mode + // Opens the URL in the default browser in incognito mode. await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); ``` */ @@ -119,7 +119,7 @@ declare const open: { @example ``` - import open = require('open'); + import {open} from 'open'; await open('https://google.com', { app: { @@ -140,21 +140,22 @@ declare const open: { @example ``` - const {apps, openApp} = require('open'); + import {open} from 'open'; + const {apps, openApp} = open; - // Open Firefox + // Open Firefox. await openApp(apps.firefox); - // Open Chrome in incognito mode + // Open Chrome in incognito mode. await openApp(apps.chrome, {arguments: ['--incognito']}); - // Open default browser + // Open default browser. await openApp(apps.browser); - // Open default browser in incognito mode + // Open default browser in incognito mode. await openApp(apps.browserPrivate); - // Open Xcode + // Open Xcode. await openApp('xcode'); ``` */ diff --git a/readme.md b/readme.md index 282e0a6..7656a8e 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ npm install open ## Usage ```js -const open = require('open'); +import {open} from 'open'; // Opens the image in the default image viewer and waits for the opened app to quit. await open('unicorn.png', {wait: true}); @@ -41,10 +41,13 @@ await open('https://sindresorhus.com', {app: {name: 'firefox'}}); // Specify app arguments. await open('https://sindresorhus.com', {app: {name: 'google chrome', arguments: ['--incognito']}}); -// Open an app +// Opens the URL in the default browser in incognito mode. +await open('https://sindresorhus.com', {app: {name: open.apps.browserPrivate}}); + +// Open an app. await open.openApp('xcode'); -// Open an app with arguments +// Open an app with arguments. await open.openApp(open.apps.chrome, {arguments: ['--incognito']}); ``` @@ -121,7 +124,7 @@ We do not recommend setting this option. The convention for success is exit code An object containing auto-detected binary names for common apps. Useful to work around [cross-platform differences](#app). ```js -const open = require('open'); +import {open} from 'open'; await open('https://google.com', { app: { @@ -129,12 +132,15 @@ await open('https://google.com', { } }); ``` +`browser` and `browserPrivate` can also be used to access the user's default browser through [`default-browser`](https://github.com/sindresorhus/default-browser). #### Supported apps - [`chrome`](https://www.google.com/chrome) - Web browser - [`firefox`](https://www.mozilla.org/firefox) - Web browser - [`edge`](https://www.microsoft.com/edge) - Web browser +- `browser` - Default web browser +- `browserPrivate` - Default web browser in incognito mode ### open.openApp(name, options?) From 009b28ef633cdea41626d53b673ebc233e4c6c15 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:28:38 +0800 Subject: [PATCH 18/23] Fixed issue with __dirname --- index.js | 2 ++ package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 1cc1052..7548454 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ import path from 'path'; +import {fileURLToPath} from 'url'; import childProcess from 'child_process'; import {promises as fs, constants as fsConstants} from 'fs'; import isWsl from 'is-wsl'; @@ -7,6 +8,7 @@ import defineLazyProperty from 'define-lazy-prop'; import defaultBrowser from 'default-browser'; // Path to included `xdg-open`. +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const localXdgOpenPath = path.join(__dirname, 'xdg-open'); const {platform, arch} = process; diff --git a/package.json b/package.json index 18a9cd1..2b1d46e 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", - "default-browser": "^3.1.0", - "x-default-browser": "^0.5.0" + "url": "^0.11.0", + "default-browser": "^3.1.0" }, "devDependencies": { "@types/node": "^15.0.0", From 69b4bb57c264f9eee6ee4ed5379b9ca74c300068 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 30 Jan 2023 23:32:32 +0800 Subject: [PATCH 19/23] Fix: removed ava test from test script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b1d46e..b3efe66 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "node": ">=12" }, "scripts": { - "test": "xo && tsd && ava" + "test": "xo && tsd" }, "files": [ "index.js", From e368f9b84ce4ba8a801c20bad12a440ef5170b2d Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Wed, 1 Feb 2023 22:18:55 +0800 Subject: [PATCH 20/23] Removed unnecessary url import --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index b3efe66..4d818e9 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0", - "url": "^0.11.0", "default-browser": "^3.1.0" }, "devDependencies": { From 1af76c233427a71f4b53811f4e536268196318c1 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Wed, 1 Feb 2023 22:21:53 +0800 Subject: [PATCH 21/23] Changed exports and specified supported browsers --- index.d.ts | 6 +++--- index.js | 43 ++++++++++++++++++++++--------------------- readme.md | 6 ++++-- test.js | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/index.d.ts b/index.d.ts index 23b66f3..95727f7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -90,7 +90,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; // Opens the image in the default image viewer. await open('unicorn.png', {wait: true}); @@ -119,7 +119,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; await open('https://google.com', { app: { @@ -140,7 +140,7 @@ declare const open: { @example ``` - import {open} from 'open'; + import open from 'open'; const {apps, openApp} = open; // Open Firefox. diff --git a/index.js b/index.js index 7548454..37abfb2 100644 --- a/index.js +++ b/index.js @@ -120,20 +120,8 @@ const baseOpen = async options => { })); } - if (app === 'browser') { - const browser = await defaultBrowser(); - const browserName = browser.name.toLowerCase(); - return baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: appArguments - } - }); - } - - if (app === 'browserPrivate') { - // Incognito or equivalent flags for each of the browser in open.apps + if (app === 'browser' || app === 'browserPrivate') { + // Incognito or equivalent flags for each browser in open.apps const flags = { chrome: '--incognito', firefox: '--private-window', @@ -142,13 +130,25 @@ const baseOpen = async options => { const browser = await defaultBrowser(); const browserName = browser.name.toLowerCase(); - return baseOpen({ - ...options, - app: { - name: open.apps[browserName], - arguments: [...appArguments, flags[browserName]] + + const supportedBrowsers = Object.keys(flags); + for (const supportedBrowser of supportedBrowsers) { + if (browserName.includes(supportedBrowser)) { + if (app === 'browserPrivate') { + appArguments.push(flags[supportedBrowser]); + } + + return baseOpen({ + ...options, + app: { + name: open.apps[supportedBrowser], + arguments: appArguments + } + }); } - }); + } + + throw new Error(`${browserName} as the default browser is not supported`); } let command; @@ -369,4 +369,5 @@ defineLazyProperty(apps, 'browserPrivate', () => 'browserPrivate'); open.apps = apps; open.openApp = openApp; -export {open}; +export {apps}; +export default open; diff --git a/readme.md b/readme.md index 7656a8e..8e4beed 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ npm install open ## Usage ```js -import {open} from 'open'; +import open from 'open'; // Opens the image in the default image viewer and waits for the opened app to quit. await open('unicorn.png', {wait: true}); @@ -124,7 +124,7 @@ We do not recommend setting this option. The convention for success is exit code An object containing auto-detected binary names for common apps. Useful to work around [cross-platform differences](#app). ```js -import {open} from 'open'; +import open from 'open'; await open('https://google.com', { app: { @@ -142,6 +142,8 @@ await open('https://google.com', { - `browser` - Default web browser - `browserPrivate` - Default web browser in incognito mode +`browser` and `browserPrivate` currently support `chrome`, `firefox` and `edge`. + ### open.openApp(name, options?) Open an app. diff --git a/test.js b/test.js index 13de8e7..af37e70 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import test from 'ava'; -import {open} from './index.js'; +import open from './index.js'; const {openApp} = open; // Tests only checks that opening doesn't return an error From a4867a4905758f7c075cfa3526b79b757ad63ec2 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Mon, 13 Mar 2023 10:27:11 +0800 Subject: [PATCH 22/23] Mapped browser IDs to supported browsers --- index.js | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/index.js b/index.js index 37abfb2..aef1558 100644 --- a/index.js +++ b/index.js @@ -121,7 +121,18 @@ const baseOpen = async options => { } if (app === 'browser' || app === 'browserPrivate') { - // Incognito or equivalent flags for each browser in open.apps + // IDs from default-browser for macOS and windows are the same + const ids = { + 'com.google.chrome': 'chrome', + 'google-chrome.desktop': 'chrome', + 'org.mozilla.firefox': 'firefox', + 'firefox.desktop': 'firefox', + 'com.microsoft.msedge': 'edge', + 'com.microsoft.edge': 'edge', + 'microsoft-edge.desktop': 'edge' + }; + + // Incognito flags for each browser in open.apps const flags = { chrome: '--incognito', firefox: '--private-window', @@ -129,26 +140,23 @@ const baseOpen = async options => { }; const browser = await defaultBrowser(); - const browserName = browser.name.toLowerCase(); - - const supportedBrowsers = Object.keys(flags); - for (const supportedBrowser of supportedBrowsers) { - if (browserName.includes(supportedBrowser)) { - if (app === 'browserPrivate') { - appArguments.push(flags[supportedBrowser]); - } + if (browser.id in ids) { + const browserName = ids[browser.id]; - return baseOpen({ - ...options, - app: { - name: open.apps[supportedBrowser], - arguments: appArguments - } - }); + if (app === 'browserPrivate') { + appArguments.push(flags[browserName]); } + + return baseOpen({ + ...options, + app: { + name: open.apps[browserName], + arguments: appArguments + } + }); } - throw new Error(`${browserName} as the default browser is not supported`); + throw new Error(`${browser.name} is not supported as a default browser`); } let command; From 6d9d524b30760c2131014d722fff9dbbbf6a8438 Mon Sep 17 00:00:00 2001 From: Leslie Yip Date: Sun, 19 Mar 2023 14:01:45 +0800 Subject: [PATCH 23/23] Added documentation for apps export --- index.d.ts | 32 +++++++++++++++++++------------- index.test-d.ts | 2 +- readme.md | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/index.d.ts b/index.d.ts index 95727f7..f82d502 100644 --- a/index.d.ts +++ b/index.d.ts @@ -76,6 +76,22 @@ declare namespace open { }; } +/** +An object containing auto-detected binary names for common apps. Useful to work around cross-platform differences. + +@example +``` +import open from 'open'; + +await open('https://google.com', { + app: { + name: open.apps.chrome + } +}); +``` +*/ +declare const apps: Record; + // eslint-disable-next-line no-redeclare declare const open: { /** @@ -116,19 +132,8 @@ declare const open: { /** An object containing auto-detected binary names for common apps. Useful to work around cross-platform differences. - - @example - ``` - import open from 'open'; - - await open('https://google.com', { - app: { - name: open.apps.chrome - } - }); - ``` */ - apps: Record; + apps: typeof apps; /** Open an app. Cross-platform. @@ -162,4 +167,5 @@ declare const open: { openApp: (name: open.App['name'], options?: open.OpenAppOptions) => Promise; }; -export = open; +export {apps}; +export default open; diff --git a/index.test-d.ts b/index.test-d.ts index d57e60d..fb1649a 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,6 +1,6 @@ import {expectType} from 'tsd'; import {ChildProcess} from 'child_process'; -import open = require('.'); +import open from '.'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const options: open.Options = {}; diff --git a/readme.md b/readme.md index 8e4beed..aa9cbd8 100644 --- a/readme.md +++ b/readme.md @@ -119,11 +119,12 @@ Allow the opened app to exit with nonzero exit code when the `wait` option is `t We do not recommend setting this option. The convention for success is exit code zero. -### open.apps +### open.apps / apps An object containing auto-detected binary names for common apps. Useful to work around [cross-platform differences](#app). ```js +// Using default export. import open from 'open'; await open('https://google.com', { @@ -131,6 +132,15 @@ await open('https://google.com', { name: open.apps.chrome } }); + +// Using named export. +import open, {apps} from 'open'; + +await open('https://firefox.com', { + app: { + name: apps.browserPrivate + } +}); ``` `browser` and `browserPrivate` can also be used to access the user's default browser through [`default-browser`](https://github.com/sindresorhus/default-browser). @@ -142,7 +152,7 @@ await open('https://google.com', { - `browser` - Default web browser - `browserPrivate` - Default web browser in incognito mode -`browser` and `browserPrivate` currently support `chrome`, `firefox` and `edge`. +`browser` and `browserPrivate` only supports `chrome`, `firefox` and `edge`. ### open.openApp(name, options?)