fix(mcp): break circular import between googApiKeyAuth.ts and auth.ts (#9297)

This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-08-04 21:36:47 -03:00
committed by GitHub
parent b07182c72a
commit 7d6a64b054
4 changed files with 46 additions and 32 deletions

View File

@@ -0,0 +1 @@
- fix(mcp): break circular import between googApiKeyAuth.ts and auth.ts to fix esbuild SyntaxError in MCP server bundle (#9297)

View File

@@ -79,6 +79,7 @@ import { getNoAuthHydrationProviderIds } from "./noAuthProviderSiblings";
import { getResource404Bypass } from "./requestResourceHealth";
import * as log from "../utils/logger";
import { fisherYatesShuffle, getNextFromDeckSync } from "@/shared/utils/shuffleDeck";
import { readHeaderValue, type AuthRequestHeaders } from "./headerReader.ts";
type JsonRecord = Record<string, unknown>;
interface RecoverableConnectionState {
@@ -143,33 +144,6 @@ function toBooleanOrDefault(value: unknown, fallback: boolean): boolean {
return typeof value === "boolean" ? value : fallback;
}
export function readHeaderValue(
headers:
| Headers
| { get?: (name: string) => string | null }
| Record<string, string | string[] | undefined>
| null
| undefined,
name: string
): string | null {
if (!headers) return null;
if (typeof (headers as Headers).get === "function") {
const value = (headers as Headers).get(name) || (headers as Headers).get(name.toLowerCase());
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}
const recordHeaders = headers as Record<string, string | string[] | undefined>;
const value =
recordHeaders[name] || recordHeaders[name.toLowerCase()] || recordHeaders[name.toUpperCase()];
if (Array.isArray(value)) {
return typeof value[0] === "string" && value[0].trim().length > 0 ? value[0].trim() : null;
}
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}
function normalizeSessionKey(value: unknown, prefix: string): string | null {
if (typeof value !== "string" || value.trim().length === 0) return null;
const trimmed = value.trim();
@@ -946,6 +920,9 @@ const markMutexes = new Map<string, Promise<void>>();
// auth.ts uses getNextFromDeckSync inside the provider-scoped selection mutex.
// Re-export for backwards compat with existing test imports.
export { fisherYatesShuffle, getNextFromDeckSync as getNextFromDeck };
// Re-export readHeaderValue and AuthRequestHeaders from headerReader.ts for
// backwards compat with existing imports (e.g. googApiKeyAuth.ts).
export { readHeaderValue, type AuthRequestHeaders } from "./headerReader.ts";
const PROVIDER_SEARCH_PAIRS: string[][] = [
["nvidia", "nvidia_nim"],
@@ -2380,8 +2357,6 @@ export async function clearRecoveredProviderState(
return { applied: true };
}
type AuthRequestHeaders = Headers | Record<string, string | string[] | undefined>;
type AuthRequestLike = {
headers?: AuthRequestHeaders | null;
url?: string | null;

View File

@@ -1,6 +1,4 @@
import { readHeaderValue } from "./auth.ts";
type AuthRequestHeaders = Headers | Record<string, string | string[] | undefined>;
import { readHeaderValue, type AuthRequestHeaders } from "./headerReader.ts";
/**
* Issue #7034: `gemini-cli` (and any `@google/genai`-based client) sends its

View File

@@ -0,0 +1,40 @@
export type AuthRequestHeaders = Headers | Record<string, string | string[] | undefined>;
/**
* Safely read a header value from various request-like objects.
*
* Accepts:
* - `Headers` (Web API / Fetch API)
* - Objects with a `.get()` method (e.g. `IncomingMessage.headers`)
* - Plain `Record<string, string | string[] | undefined>` objects
*
* Extracted to its own module to break the circular import between
* `./auth.ts` and `./googApiKeyAuth.ts` — both import this function
* without creating a cycle.
*/
export function readHeaderValue(
headers:
| Headers
| { get?: (name: string) => string | null }
| Record<string, string | string[] | undefined>
| null
| undefined,
name: string
): string | null {
if (!headers) return null;
if (typeof (headers as Headers).get === "function") {
const value = (headers as Headers).get(name) || (headers as Headers).get(name.toLowerCase());
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}
const recordHeaders = headers as Record<string, string | string[] | undefined>;
const value =
recordHeaders[name] || recordHeaders[name.toLowerCase()] || recordHeaders[name.toUpperCase()];
if (Array.isArray(value)) {
return typeof value[0] === "string" && value[0].trim().length > 0 ? value[0].trim() : null;
}
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}