Skip to content

Commit 61138b4

Browse files
authored
refactor: open function (#5257)
* refactor: fix type annotations in open There was no clear reason as to why we needed to use type assertions when initializing both `args` and `options` in `open` so I refactored them both. * refactor: create constructOpenOptions * refactor: add urlSearch and remove options * feat: add tests for constructOpenOptions
1 parent 113ad85 commit 61138b4

File tree

2 files changed

+68
-9
lines changed

2 files changed

+68
-9
lines changed

src/node/util.ts

+34-9
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,37 @@ export const isWsl = async (
404404
}
405405
}
406406

407+
interface OpenOptions {
408+
args: string[]
409+
command: string
410+
urlSearch: string
411+
}
412+
413+
/**
414+
* A helper function to construct options for `open` function.
415+
*
416+
* Extract to make it easier to test.
417+
*
418+
* @param platform - platform on machine
419+
* @param urlSearch - url.search
420+
* @returns an object with args, command, options and urlSearch
421+
*/
422+
export function constructOpenOptions(platform: NodeJS.Platform | "wsl", urlSearch: string): OpenOptions {
423+
const args: string[] = []
424+
let command = platform === "darwin" ? "open" : "xdg-open"
425+
if (platform === "win32" || platform === "wsl") {
426+
command = platform === "wsl" ? "cmd.exe" : "cmd"
427+
args.push("/c", "start", '""', "/b")
428+
urlSearch = urlSearch.replace(/&/g, "^&")
429+
}
430+
431+
return {
432+
args,
433+
command,
434+
urlSearch,
435+
}
436+
}
437+
407438
/**
408439
* Try opening an address using whatever the system has set for opening URLs.
409440
*/
@@ -416,16 +447,10 @@ export const open = async (address: URL | string): Promise<void> => {
416447
if (url.hostname === "0.0.0.0") {
417448
url.hostname = "localhost"
418449
}
419-
const args = [] as string[]
420-
const options = {} as cp.SpawnOptions
421450
const platform = (await isWsl(process.platform, os.release(), "/proc/version")) ? "wsl" : process.platform
422-
let command = platform === "darwin" ? "open" : "xdg-open"
423-
if (platform === "win32" || platform === "wsl") {
424-
command = platform === "wsl" ? "cmd.exe" : "cmd"
425-
args.push("/c", "start", '""', "/b")
426-
url.search = url.search.replace(/&/g, "^&")
427-
}
428-
const proc = cp.spawn(command, [...args, url.toString()], options)
451+
const { command, args, urlSearch } = constructOpenOptions(platform, url.search)
452+
url.search = urlSearch
453+
const proc = cp.spawn(command, [...args, url.toString()], {})
429454
await new Promise<void>((resolve, reject) => {
430455
proc.on("error", reject)
431456
proc.on("close", (code) => {

test/unit/node/util.test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,37 @@ describe("open", () => {
544544
await expect(util.open(address)).rejects.toThrow("Cannot open socket paths")
545545
})
546546
})
547+
describe("constructOpenOptions", () => {
548+
it("should return options for darwin", () => {
549+
const platform: NodeJS.Platform | "wsl" = "darwin"
550+
const url = new URL("localhost:8080")
551+
const { args, command, urlSearch } = util.constructOpenOptions(platform, url.search)
552+
expect(args).toStrictEqual([])
553+
expect(command).toBe("open")
554+
expect(urlSearch).toBe("")
555+
})
556+
it("should return options for linux", () => {
557+
const platform: NodeJS.Platform | "wsl" = "linux"
558+
const url = new URL("localhost:8080")
559+
const { args, command, urlSearch } = util.constructOpenOptions(platform, url.search)
560+
expect(args).toStrictEqual([])
561+
expect(command).toBe("xdg-open")
562+
expect(urlSearch).toBe("")
563+
})
564+
it("should return options for win32", () => {
565+
const platform: NodeJS.Platform | "wsl" = "win32"
566+
const url = new URL("localhost:8080?q=&test")
567+
const { args, command, urlSearch } = util.constructOpenOptions(platform, url.search)
568+
expect(args).toStrictEqual(["/c", "start", '""', "/b"])
569+
expect(command).toBe("cmd")
570+
expect(urlSearch).toBe("?q=^&test")
571+
})
572+
it("should return options for wsl", () => {
573+
const platform: NodeJS.Platform | "wsl" = "wsl"
574+
const url = new URL("localhost:8080?q=&test")
575+
const { args, command, urlSearch } = util.constructOpenOptions(platform, url.search)
576+
expect(args).toStrictEqual(["/c", "start", '""', "/b"])
577+
expect(command).toBe("cmd.exe")
578+
expect(urlSearch).toBe("?q=^&test")
579+
})
580+
})

0 commit comments

Comments
 (0)