From 680fa50d9c0cd66e096d35bbf23ade1f44b4debb Mon Sep 17 00:00:00 2001 From: Vivswan Shah <58091053+Vivswan@users.noreply.github.com> Date: Tue, 6 Oct 2026 06:09:19 -0400 Subject: [PATCH] refactor(github): build request headers once GitHubApi built the accept and x-github-api-version pair inline at three request sites (tryList, request, tryGraphql). The pair now rides on Octokit's request defaults, set once after construction; the raw media-type read passes its own accept, which the defaults merge lets override, and the plugins' wrapped hook stays. Nothing on the wire changes. --- src/github/api.ts | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/github/api.ts b/src/github/api.ts index 0a5f4a6e..55771c01 100644 --- a/src/github/api.ts +++ b/src/github/api.ts @@ -182,10 +182,8 @@ export class GitHubApi implements GitHubClient { private readonly octokit: InstanceType; private readonly trace: TraceRedaction; private readonly baseUrl: string; - private readonly apiVersion: string; constructor(options: GitHubApiOptions) { this.baseUrl = options.baseUrl ?? process.env.GITHUB_API_URL ?? "https://api.github.com"; - this.apiVersion = options.apiVersion ?? DEFAULT_API_VERSION; this.trace = new TraceRedaction(options.io ?? SILENT_TRACE); const envKnob = envRetryBaseMs(); const retryBaseMs = options.retryBaseMs ?? envKnob ?? 1000; @@ -219,6 +217,13 @@ export class GitHubApi implements GitHubClient { onSecondaryRateLimit: throttleCallback("secondary rate limit", this.trace), }, }); + // A per-request accept (the raw media-type read) overrides the default; the hooks the plugins wrapped stay. + this.octokit.request = this.octokit.request.defaults({ + headers: { + accept: "application/vnd.github+json", + "x-github-api-version": options.apiVersion ?? DEFAULT_API_VERSION, + }, + }); } async tryRequest( @@ -295,10 +300,6 @@ export class GitHubApi implements GitHubClient { url: path, per_page: options?.perPage ?? PAGE_SIZE, page: 1, - headers: { - accept: "application/vnd.github+json", - "x-github-api-version": this.apiVersion, - }, } as unknown as Parameters[0]; try { for await (const _page of this.octokit.paginate.iterator(request, firstPage)) { @@ -357,10 +358,7 @@ export class GitHubApi implements GitHubClient { const response = await this.octokit.request({ method, url: path, - headers: { - accept: options?.accept ?? "application/vnd.github+json", - "x-github-api-version": this.apiVersion, - }, + ...(options?.accept === undefined ? {} : { headers: { accept: options.accept } }), // The body is the tree the scan inspected, so octokit never reshapes the payload and the wire carries exactly what was scanned. ...(payload === undefined ? {} : { data: secretScan.value.payload }), } as unknown as Parameters["request"]>[0]); @@ -437,10 +435,6 @@ export class GitHubApi implements GitHubClient { response = (await this.octokit.request({ method: "POST", url: "/graphql", - headers: { - accept: "application/vnd.github+json", - "x-github-api-version": this.apiVersion, - }, // operationName makes the request self-describing on the wire (the mock dispatches on it). data: { query: op.query, operationName: op.name, variables: scan.value.payload }, } as unknown as Parameters["request"]>[0])) as {