diff --git a/README.md b/README.md index e24c83c..56b56ee 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,7 @@ npx qiita version 設定できるオプションは以下の通りです。 - includePrivate: 限定共有記事を含めるかどうかを選べます。デフォルトは`false`です。 +- host: `qiita preview`コマンドで利用するホストを指定できます。デフォルトは`localhost`です。 - port: `qiita preview`コマンドで利用するポートを指定できます。デフォルトは`8888`です。 ## オプション diff --git a/src/commands/preview.ts b/src/commands/preview.ts index 14ab2c0..a85868e 100644 --- a/src/commands/preview.ts +++ b/src/commands/preview.ts @@ -1,6 +1,7 @@ import { config } from "../lib/config"; import { getFileSystemRepo } from "../lib/get-file-system-repo"; import { getQiitaApiInstance } from "../lib/get-qiita-api-instance"; +import { getUrlAddress } from "../lib/getUrlAddress"; import { syncArticlesFromQiita } from "../lib/sync-articles-from-qiita"; import { startLocalChangeWatcher, startServer } from "../server/app"; @@ -13,9 +14,11 @@ export const preview = async () => { const server = await startServer(); const address = server.address(); - if (address && typeof address !== "string") { + const url = getUrlAddress(address); + + if (url) { const open = (await import("open")).default; - await open(`http://localhost:${address.port}`); + await open(url); } startLocalChangeWatcher({ diff --git a/src/lib/config.test.ts b/src/lib/config.test.ts index dbc5443..81ac679 100644 --- a/src/lib/config.test.ts +++ b/src/lib/config.test.ts @@ -224,6 +224,7 @@ describe("config", () => { beforeEach(() => { const userConfigData = { includePrivate: true, + host: "localhost", port: 9999, }; resetFiles(); @@ -234,6 +235,7 @@ describe("config", () => { const userConfig = await config.getUserConfig(); expect(userConfig).toStrictEqual({ includePrivate: true, + host: "localhost", port: 9999, }); }); @@ -248,6 +250,7 @@ describe("config", () => { const userConfig = await config.getUserConfig(); expect(userConfig).toStrictEqual({ includePrivate: false, + host: "localhost", port: 8888, }); }); diff --git a/src/lib/config.ts b/src/lib/config.ts index a6ba2cf..873b99b 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -14,6 +14,7 @@ interface Options { type UserConfig = { includePrivate: boolean; + host: string; port: number; }; @@ -107,6 +108,7 @@ class Config { async getUserConfig() { const defaultConfig = { includePrivate: false, + host: "localhost", port: 8888, } as UserConfig; diff --git a/src/lib/getUrlAddress.test.ts b/src/lib/getUrlAddress.test.ts new file mode 100644 index 0000000..1a569dd --- /dev/null +++ b/src/lib/getUrlAddress.test.ts @@ -0,0 +1,42 @@ +import { AddressInfo } from "net"; +import { getUrlAddress } from "./getUrlAddress"; + +describe("getUrlAddress", () => { + describe("when null is passed", () => { + it("returns null", () => { + const url = getUrlAddress(null); + expect(url).toBeNull(); + }); + }); + + describe("when string is passed", () => { + it("returns null", () => { + const url = getUrlAddress("foobar"); + expect(url).toBeNull(); + }); + }); + + describe("when IPv4 is passed", () => { + it("returns correct url", () => { + const address: AddressInfo = { + address: "0.0.0.0", + family: "IPv4", + port: 8888, + }; + const url = getUrlAddress(address); + expect(url).toEqual(`http://${address.address}:${address.port}`); + }); + }); + + describe("when IPv6 is passed", () => { + it("returns correct url", () => { + const address: AddressInfo = { + address: "::", + family: "IPv6", + port: 8888, + }; + const url = getUrlAddress(address); + expect(url).toEqual(`http://[${address.address}]:${address.port}`); + }); + }); +}); diff --git a/src/lib/getUrlAddress.ts b/src/lib/getUrlAddress.ts new file mode 100644 index 0000000..f56442e --- /dev/null +++ b/src/lib/getUrlAddress.ts @@ -0,0 +1,12 @@ +import { AddressInfo } from "net"; + +export const getUrlAddress = (address: string | AddressInfo | null) => { + if (!address || typeof address === "string") return null; + + if (["IPv4", "IPv6"].indexOf(address.family) === -1) + throw new Error("Unknown address family"); + + return `http://${ + address.family === "IPv4" ? address.address : `[${address.address}]` + }:${address.port}`; +}; diff --git a/src/server/app.ts b/src/server/app.ts index 9f2de35..5b9168e 100644 --- a/src/server/app.ts +++ b/src/server/app.ts @@ -10,6 +10,7 @@ import { EmojiRouter } from "./api/emoji"; import { ItemsRouter } from "./api/items"; import { ReadmeRouter } from "./api/readme"; import { config } from "../lib/config"; +import { getUrlAddress } from "../lib/getUrlAddress"; export async function startServer() { const app = express(); @@ -33,13 +34,17 @@ export async function startServer() { const server = createServer(app); const userConfig = await config.getUserConfig(); const port = userConfig.port; - const host = "localhost"; + const host = userConfig.host; return new Promise((resolve, reject) => { server .listen(port, host) .once("listening", () => { - console.log(`Preview: http://${host}:${port}`); + const address = server.address(); + const url = getUrlAddress(address); + if (url) { + console.log(`Preview: ${url}`); + } resolve(server); })