MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / exchangeCodeForTokens

Function exchangeCodeForTokens

packages/cli/src/auth/oauth.ts:283–320  ·  view source on GitHub ↗
(args: {
  clientId: string;
  code: string;
  redirectUri: string;
  verifier: string;
  fetchImpl?: typeof fetch;
})

Source from the content-addressed store, hash-verified

281}
282
283async function exchangeCodeForTokens(args: {
284 clientId: string;
285 code: string;
286 redirectUri: string;
287 verifier: string;
288 fetchImpl?: typeof fetch;
289}): Promise<OAuthTokens> {
290 const fetchImpl = args.fetchImpl ?? fetch;
291 const body = new URLSearchParams({
292 grant_type: "authorization_code",
293 code: args.code,
294 redirect_uri: args.redirectUri,
295 client_id: args.clientId,
296 code_verifier: args.verifier,
297 });
298 const res = await fetchImpl(tokenEndpoint(), {
299 method: "POST",
300 headers: {
301 "content-type": "application/x-www-form-urlencoded",
302 accept: "application/json",
303 },
304 body: body.toString(),
305 });
306 if (res.status === 400 || res.status === 401) {
307 // The authorization code is single-use and short-lived. A 400/401
308 // here almost always means it expired during the loopback wait or
309 // was already redeemed — surface an actionable message instead of
310 // a bare "HeyGen API error (400)".
311 const detail = (await safeText(res)) || res.statusText;
312 throw ErrRefreshFailed(
313 `authorization code rejected (${detail}); please run \`auth login\` again`,
314 );
315 }
316 if (!res.ok) {
317 throw ErrApi(res.status, (await safeText(res)) || res.statusText);
318 }
319 return parseTokenResponse(await readJsonOrThrow(res));
320}
321
322/**
323 * Parse the RFC 6749 token response. Backend may also include

Callers 1

Calls 6

tokenEndpointFunction · 0.85
ErrRefreshFailedFunction · 0.85
ErrApiFunction · 0.85
parseTokenResponseFunction · 0.85
readJsonOrThrowFunction · 0.85
safeTextFunction · 0.70

Tested by

no test coverage detected