Skip to content
Merged
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
39 changes: 38 additions & 1 deletion cli/src/utils/codebuff-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ export interface CodebuffApiClientConfig {
defaultTimeoutMs?: number
/** Default retry configuration */
retry?: RetryConfig
/**
* Proxy URL to use for all requests.
* If not set, falls back to HTTPS_PROXY / https_proxy / HTTP_PROXY / http_proxy
* environment variables. Set to null to explicitly disable proxy even if env
* vars are present.
*/
proxy?: string | null
}

/**
Expand Down Expand Up @@ -195,6 +202,23 @@ export interface CodebuffApiClient {
feedback(req: FeedbackRequest): Promise<ApiResponse<FeedbackResponse>>
}

/**
* Resolve the proxy URL from standard environment variables.
* Priority: HTTPS_PROXY > https_proxy > HTTP_PROXY > http_proxy
* Returns undefined when no proxy is configured.
*/
export function resolveProxyUrl(
env: Record<string, string | undefined> = process.env,
): string | undefined {
return (
env['HTTPS_PROXY'] ||
env['https_proxy'] ||
env['HTTP_PROXY'] ||
env['http_proxy'] ||
undefined
)
}

/**
* Sleep for a given duration
*/
Expand Down Expand Up @@ -253,8 +277,16 @@ export function createCodebuffApiClient(
fetch: fetchFn = fetch,
defaultTimeoutMs = 30000,
retry: defaultRetryConfig = {},
proxy: proxyConfig,
} = config

// Resolve proxy: explicit config wins, then env vars, then no proxy.
// Pass proxy: null to explicitly disable even when env vars are set.
const proxyUrl: string | undefined =
proxyConfig === null
? undefined
: (proxyConfig ?? resolveProxyUrl())

const mergedDefaultRetry: Required<RetryConfig> = {
...DEFAULT_RETRY_CONFIG,
...defaultRetryConfig,
Expand Down Expand Up @@ -321,7 +353,12 @@ export function createCodebuffApiClient(
const response = await fetchFn(url, {
...fetchOptions,
signal: controller.signal,
})
// Bun supports a `proxy` option on fetch. When a proxy URL is
// resolved (from config or env vars) we pass it here so that all
// API calls are tunnelled through the proxy. The cast is required
// because the WhatWG RequestInit type does not include `proxy`.
...(proxyUrl ? { proxy: proxyUrl } : {}),
} as RequestInit)

clearTimeout(timeoutId)

Expand Down
Loading