Skip to content

Commit 85266b1

Browse files
committed
Fix to show correct url even for IPv6
1 parent f116018 commit 85266b1

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

src/commands/preview.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { config } from "../lib/config";
22
import { getFileSystemRepo } from "../lib/get-file-system-repo";
33
import { getQiitaApiInstance } from "../lib/get-qiita-api-instance";
4+
import { resolveUrlFromAddress } from "../lib/resolve-url-from-address";
45
import { syncArticlesFromQiita } from "../lib/sync-articles-from-qiita";
56
import { startLocalChangeWatcher, startServer } from "../server/app";
67

@@ -13,9 +14,10 @@ export const preview = async () => {
1314
const server = await startServer();
1415

1516
const address = server.address();
16-
if (address && typeof address !== "string") {
17+
const url = resolveUrlFromAddress(address);
18+
if (url) {
1719
const open = (await import("open")).default;
18-
await open(`http://${address.address}:${address.port}`);
20+
await open(url);
1921
}
2022

2123
startLocalChangeWatcher({
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { AddressInfo } from "node:net";
2+
import { resolveUrlFromAddress } from "./resolve-url-from-address";
3+
4+
describe("resolveUrlFromAddress", () => {
5+
describe("when null is passed", () => {
6+
it("returns null", () => {
7+
const url = resolveUrlFromAddress(null);
8+
9+
expect(url).toBeNull();
10+
});
11+
});
12+
13+
describe("when string is passed", () => {
14+
it("returns null", () => {
15+
const url = resolveUrlFromAddress("foobar");
16+
17+
expect(url).toBeNull();
18+
});
19+
});
20+
21+
describe("when AddressInfo is passed", () => {
22+
describe("when IPv4 family", () => {
23+
it("returns url", () => {
24+
const address: AddressInfo = {
25+
address: "0.0.0.0",
26+
family: "IPv4",
27+
port: 8888,
28+
};
29+
const url = resolveUrlFromAddress(address);
30+
31+
expect(url).toEqual(`http://${address.address}:${address.port}`);
32+
});
33+
});
34+
35+
describe("when IPv6 family", () => {
36+
it("returns url", () => {
37+
const address: AddressInfo = {
38+
address: "::",
39+
family: "IPv6",
40+
port: 8888,
41+
};
42+
const url = resolveUrlFromAddress(address);
43+
44+
expect(url).toEqual(`http://[${address.address}]:${address.port}`);
45+
});
46+
});
47+
});
48+
});

src/lib/resolve-url-from-address.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { AddressInfo } from "node:net";
2+
3+
export const resolveUrlFromAddress = (address: string | AddressInfo | null) => {
4+
if (!address || typeof address === "string") return null;
5+
6+
let hostname;
7+
switch (address.family) {
8+
case "IPv6":
9+
hostname = `[${address.address}]`;
10+
break;
11+
case "IPv4":
12+
hostname = address.address;
13+
break;
14+
default:
15+
throw new Error("Unknown address family");
16+
}
17+
18+
return `http://${hostname}:${address.port}`;
19+
};

src/server/app.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { EmojiRouter } from "./api/emoji";
1010
import { ItemsRouter } from "./api/items";
1111
import { ReadmeRouter } from "./api/readme";
1212
import { config } from "../lib/config";
13+
import { resolveUrlFromAddress } from "../lib/resolve-url-from-address";
1314

1415
export async function startServer() {
1516
const app = express();
@@ -39,7 +40,11 @@ export async function startServer() {
3940
server
4041
.listen(port, host)
4142
.once("listening", () => {
42-
console.log(`Preview: http://${host}:${port}`);
43+
const address = server.address();
44+
const url = resolveUrlFromAddress(address);
45+
if (url) {
46+
console.log(`Preview: ${url}`);
47+
}
4348

4449
resolve(server);
4550
})

0 commit comments

Comments
 (0)