feat(cli): add browser open command and spawn options for different platforms

This commit is contained in:
Mega Yu
2026-04-23 12:00:52 +08:00
parent a0feca6510
commit fdf7eed219
2 changed files with 60 additions and 9 deletions

View File

@@ -319,14 +319,35 @@
(js/clearTimeout timeout-id)
(stop-server! server))})))))))
(defn- browser-open-command
[platform url]
(letfn [(unwrap-double-quoted [s]
(if (and (string/starts-with? s "\"")
(string/ends-with? s "\"")
(> (count s) 1))
(subs s 1 (dec (count s)))
s))
(windows-start-url-command [s]
(str "start \"\" \"" (unwrap-double-quoted s) "\""))]
(case platform
"darwin" ["open" [url]]
"linux" ["xdg-open" [url]]
"win32" ["cmd.exe" ["/d" "/c" (windows-start-url-command url)]]
[nil nil])))
(defn- browser-open-spawn-options
[platform]
(cond-> {:detached true
:stdio "ignore"
:shell false}
(= platform "win32")
(assoc :windowsVerbatimArguments true)))
(defn open-browser!
[url]
(let [platform (.-platform js/process)
[command args] (case platform
"darwin" ["open" [url]]
"linux" ["xdg-open" [url]]
"win32" ["cmd" ["/c" "start" "" url]]
[nil nil])]
[command args] (browser-open-command platform url)
spawn-opts (browser-open-spawn-options platform)]
(if-not (seq command)
(p/rejected (ex-info "unsupported platform for browser open"
{:code :browser-open-unsupported-platform
@@ -334,10 +355,7 @@
(p/create
(fn [resolve reject]
(try
(let [child (.spawn child-process command (clj->js args)
#js {:detached true
:stdio "ignore"
:shell false})]
(let [child (.spawn child-process command (clj->js args) (clj->js spawn-opts))]
(.unref child)
(resolve {:opened? true
:command command}))

View File

@@ -137,6 +137,39 @@
(p/finally (fn []
(done)))))))
(deftest test-open-browser-uses-cmd-start-on-windows
(let [open-command (fn [platform url]
(call-private 'browser-open-command platform url))
[command args] (open-command "win32"
"https://example.com/oauth2/authorize?response_type=code&client_id=abc&redirect_uri=http%3A%2F%2Flocalhost%3A8765%2Fauth%2Fcallback")]
(is (= "cmd.exe" command))
(is (= ["/d" "/c"
"start \"\" \"https://example.com/oauth2/authorize?response_type=code&client_id=abc&redirect_uri=http%3A%2F%2Flocalhost%3A8765%2Fauth%2Fcallback\""]
args))))
(deftest test-open-browser-normalizes-prequoted-windows-url
(let [open-command (fn [platform url]
(call-private 'browser-open-command platform url))
[command args] (open-command "win32"
"\"https://example.com/oauth2/authorize?response_type=code&client_id=abc&redirect_uri=http%3A%2F%2Flocalhost%3A8765%2Fauth%2Fcallback\"")]
(is (= "cmd.exe" command))
(is (= ["/d" "/c"
"start \"\" \"https://example.com/oauth2/authorize?response_type=code&client_id=abc&redirect_uri=http%3A%2F%2Flocalhost%3A8765%2Fauth%2Fcallback\""]
args))))
(deftest test-open-browser-uses-verbatim-windows-cmd-arguments
(let [spawn-options (fn [platform]
(call-private 'browser-open-spawn-options platform))]
(is (= {:detached true
:stdio "ignore"
:shell false
:windowsVerbatimArguments true}
(spawn-options "win32")))
(is (= {:detached true
:stdio "ignore"
:shell false}
(spawn-options "linux")))))
(deftest test-parse-jwt-fails-fast-on-invalid-token
(let [parse-jwt (fn [jwt]
(call-private 'parse-jwt jwt))]