1 | // Sourced from Snowpack
|
2 | // https://github.com/snowpackjs/snowpack/blob/2cbbdbbad1c4f842f86ff56d19f86afedf07d2e2/snowpack/src/util.ts#L156:L227
|
3 | /*
|
4 | * MIT License
|
5 | *
|
6 | * Copyright (c) 2019 Fred K. Schott
|
7 | *
|
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
9 | * of this software and associated documentation files (the "Software"), to deal
|
10 | * in the Software without restriction, including without limitation the rights
|
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12 | * copies of the Software, and to permit persons to whom the Software is
|
13 | * furnished to do so, subject to the following conditions:
|
14 | *
|
15 | * The above copyright notice and this permission notice shall be included in all
|
16 | * copies or substantial portions of the Software.
|
17 | *
|
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24 | * SOFTWARE.
|
25 | */
|
26 | import open from "open";
|
27 | import execa from "execa";
|
28 | import { join } from "path";
|
29 | const cwd = process.cwd();
|
30 | const appNames = {
|
31 | win32: {
|
32 | brave: "brave",
|
33 | chrome: "chrome",
|
34 | },
|
35 | darwin: {
|
36 | brave: "Brave Browser",
|
37 | chrome: "Google Chrome",
|
38 | },
|
39 | linux: {
|
40 | brave: "brave",
|
41 | chrome: "google-chrome",
|
42 | },
|
43 | };
|
44 | async function openInExistingChromeBrowser(url) {
|
45 | // see if Chrome process is open; fail if not
|
46 | await execa.command('ps cax | grep "Google Chrome"', {
|
47 | shell: true,
|
48 | });
|
49 | // use open Chrome tab if exists; create new Chrome tab if not
|
50 | const openChrome = execa(`osascript ${join("node_modules", "microsite", "assets", "openChrome.appleScript")} "${encodeURI(url)}"`, {
|
51 | cwd,
|
52 | stdio: "ignore",
|
53 | shell: true,
|
54 | });
|
55 | // if Chrome doesn’t respond within 3s, fall back to opening new tab in default browser
|
56 | let isChromeStalled = setTimeout(() => {
|
57 | openChrome.cancel();
|
58 | }, 3000);
|
59 | try {
|
60 | await openChrome;
|
61 | }
|
62 | catch (err) {
|
63 | console.error(err);
|
64 | if (err.isCanceled) {
|
65 | console.warn(`Chrome not responding to Snowpack after 3s. Opening in new tab.`);
|
66 | }
|
67 | else {
|
68 | console.error(err.toString() || err);
|
69 | }
|
70 | throw err;
|
71 | }
|
72 | finally {
|
73 | clearTimeout(isChromeStalled);
|
74 | }
|
75 | }
|
76 | export async function openInBrowser(protocol, hostname, port, basePath, browser) {
|
77 | const url = `${protocol}//${hostname}:${port}${basePath.replace(/\/$/, '')}`;
|
78 | browser = /chrome/i.test(browser)
|
79 | ? appNames[process.platform]["chrome"]
|
80 | : /brave/i.test(browser)
|
81 | ? appNames[process.platform]["brave"]
|
82 | : browser;
|
83 | const isMac = process.platform === "darwin";
|
84 | const isBrowserChrome = /chrome|default/i.test(browser);
|
85 | if (!isMac || !isBrowserChrome) {
|
86 | await (browser === "default" ? open(url) : open(url, { app: browser }));
|
87 | return;
|
88 | }
|
89 | try {
|
90 | // If we're on macOS, and we haven't requested a specific browser,
|
91 | // we can try opening Chrome with AppleScript. This lets us reuse an
|
92 | // existing tab when possible instead of creating a new one.
|
93 | await openInExistingChromeBrowser(url);
|
94 | }
|
95 | catch (err) {
|
96 | // if no open Chrome process, just go ahead and open default browser.
|
97 | await open(url);
|
98 | }
|
99 | }
|