(
code: string,
pkce: PkceCodes,
options: XaiAuthPluginOptions = {},
)
| 142 | } |
| 143 | |
| 144 | async function exchangeCodeForTokens( |
| 145 | code: string, |
| 146 | pkce: PkceCodes, |
| 147 | options: XaiAuthPluginOptions = {}, |
| 148 | ): Promise<TokenResponse> { |
| 149 | const response = await fetch(options.tokenUrl ?? TOKEN_URL, { |
| 150 | method: "POST", |
| 151 | headers: authHeaders(), |
| 152 | body: new URLSearchParams({ |
| 153 | grant_type: "authorization_code", |
| 154 | code, |
| 155 | redirect_uri: REDIRECT_URI, |
| 156 | client_id: CLIENT_ID, |
| 157 | code_verifier: pkce.verifier, |
| 158 | }).toString(), |
| 159 | }) |
| 160 | if (!response.ok) { |
| 161 | const detail = await response.text().catch(() => "") |
| 162 | throw new Error(`xAI token exchange failed (${response.status})${detail ? `: ${detail}` : ""}`) |
| 163 | } |
| 164 | return response.json() as Promise<TokenResponse> |
| 165 | } |
| 166 | |
| 167 | async function refreshAccessToken(refreshToken: string, options: XaiAuthPluginOptions = {}): Promise<TokenResponse> { |
| 168 | const response = await fetch(options.tokenUrl ?? TOKEN_URL, { |
no test coverage detected