Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import consola from "consola";
import { installHttpLogger } from "@repo/backlog-utils";
import { installHttpDispatcher } from "@repo/backlog-utils";
import { BeeCommand } from "./lib/bee-command";
import { handleError } from "./lib/error";
import pkg from "../package.json" with { type: "json" };

consola.options.formatOptions.date = false;
installHttpLogger();
installHttpDispatcher();

const program = new BeeCommand("bee").version(pkg.version).description(pkg.description ?? "");

Expand Down
6 changes: 6 additions & 0 deletions apps/docs/src/content/docs/guides/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ description: |-
`BACKLOG_OAUTH_PORT`
: OAuth 認証で使用するコールバックサーバーのポート番号。デフォルトは `5033`。別のアプリケーションとポートが競合する場合に変更できます。

`HTTPS_PROXY` / `HTTP_PROXY`
: アウトバウンドの HTTPS / HTTP リクエストを指定したプロキシ経由でルーティングします(例: `http://proxy.corp.example.com:8080`)。社内プロキシ環境や制限されたネットワークでの利用に必要です。

`NO_PROXY`
: プロキシをバイパスするホストをカンマ区切りで指定します(例: `internal.example.com,localhost`)。サブドメイン(`.example.com`)、ポート指定(`example.com:8080`)、ワイルドカード(`*`)にも対応しています。

## よく使うパターン

### プロジェクトの固定
Expand Down
31 changes: 31 additions & 0 deletions packages/backlog-utils/src/http-dispatcher.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { beforeEach, describe, expect, it, vi } from "vitest";

vi.mock("consola", () => import("@repo/test-utils/mock-consola"));

vi.mock("undici", () => {
const MockAgent = vi.fn();
MockAgent.prototype.compose = vi.fn(function (this: unknown) {
return this;
});
return {
EnvHttpProxyAgent: MockAgent,
setGlobalDispatcher: vi.fn(),
};
});

describe("installHttpDispatcher", () => {
beforeEach(() => {
vi.clearAllMocks();
});

it("calls setGlobalDispatcher with a composed EnvHttpProxyAgent", async () => {
const { EnvHttpProxyAgent, setGlobalDispatcher } = await import("undici");
const { installHttpDispatcher } = await import("./http-dispatcher");

installHttpDispatcher();

expect(EnvHttpProxyAgent).toHaveBeenCalled();
expect(vi.mocked(EnvHttpProxyAgent).prototype.compose).toHaveBeenCalled();
expect(setGlobalDispatcher).toHaveBeenCalled();
});
});
15 changes: 15 additions & 0 deletions packages/backlog-utils/src/http-dispatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
import { createLoggingInterceptor } from "./http-logger";

/** Installs the global fetch dispatcher with logging and proxy support.
*
* Respects the standard HTTP proxy environment variables:
* HTTPS_PROXY / https_proxy, HTTP_PROXY / http_proxy,
* NO_PROXY / no_proxy (comma-separated list of hosts to bypass).
*/
const installHttpDispatcher = (): void => {
const agent = new EnvHttpProxyAgent().compose(createLoggingInterceptor());
setGlobalDispatcher(agent);
};

export { installHttpDispatcher };
28 changes: 0 additions & 28 deletions packages/backlog-utils/src/http-logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@ import consola from "consola";

vi.mock("consola", () => import("@repo/test-utils/mock-consola"));

vi.mock("undici", () => {
const MockAgent = vi.fn();
MockAgent.prototype.compose = vi.fn(function (this: unknown) {
return this;
});
return {
Agent: MockAgent,
setGlobalDispatcher: vi.fn(),
};
});

const newHandler = () => ({
onRequestStart: vi.fn(),
onResponseStart: vi.fn(),
Expand Down Expand Up @@ -132,20 +121,3 @@ describe("createLoggingInterceptor", () => {
expect(consola.debug).toHaveBeenCalledWith("→ GET /api/v2/issues?apiKey=***&projectId[]=1");
});
});

describe("installHttpLogger", () => {
beforeEach(() => {
vi.clearAllMocks();
});

it("calls setGlobalDispatcher with a composed agent", async () => {
const { Agent, setGlobalDispatcher } = await import("undici");
const { installHttpLogger } = await import("./http-logger");

installHttpLogger();

expect(Agent).toHaveBeenCalled();
expect(vi.mocked(Agent).prototype.compose).toHaveBeenCalled();
expect(setGlobalDispatcher).toHaveBeenCalled();
});
});
10 changes: 2 additions & 8 deletions packages/backlog-utils/src/http-logger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import consola from "consola";
import { Agent, type Dispatcher, setGlobalDispatcher } from "undici";
import { type Dispatcher } from "undici";

type Interceptor = (dispatch: Dispatcher["dispatch"]) => Dispatcher["dispatch"];

Expand Down Expand Up @@ -65,10 +65,4 @@ const createLoggingInterceptor = (): Interceptor => {
};
};

/** Installs the logging interceptor as the global fetch dispatcher. */
const installHttpLogger = (): void => {
const agent = new Agent().compose(createLoggingInterceptor());
setGlobalDispatcher(agent);
};

export { createLoggingInterceptor, installHttpLogger };
export { createLoggingInterceptor };
2 changes: 1 addition & 1 deletion packages/backlog-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ export {
getRepoRelativePath,
parseBacklogRemoteUrl,
} from "./git-context";
export { installHttpLogger } from "./http-logger";
export { installHttpDispatcher } from "./http-dispatcher";