* Resolves label IDs to human-readable label names using a cache.
( accessToken: string, labelIds: string[], syncContext?: Record<string, unknown> )
| 277 | * Resolves label IDs to human-readable label names using a cache. |
| 278 | */ |
| 279 | async function resolveLabelNames( |
| 280 | accessToken: string, |
| 281 | labelIds: string[], |
| 282 | syncContext?: Record<string, unknown> |
| 283 | ): Promise<string[]> { |
| 284 | const cacheKey = '_gmailLabelCache' |
| 285 | |
| 286 | if (syncContext && !syncContext[cacheKey]) { |
| 287 | try { |
| 288 | const url = `${GMAIL_API_BASE}/labels` |
| 289 | const response = await fetchWithRetry(url, { |
| 290 | method: 'GET', |
| 291 | headers: { |
| 292 | Authorization: `Bearer ${accessToken}`, |
| 293 | Accept: 'application/json', |
| 294 | }, |
| 295 | }) |
| 296 | |
| 297 | if (response.ok) { |
| 298 | const data = await response.json() |
| 299 | const labels = (data.labels || []) as GmailLabel[] |
| 300 | const labelMap: Record<string, string> = {} |
| 301 | for (const label of labels) { |
| 302 | labelMap[label.id] = label.name |
| 303 | } |
| 304 | syncContext[cacheKey] = labelMap |
| 305 | } |
| 306 | } catch { |
| 307 | syncContext[cacheKey] = {} |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | const cache = (syncContext?.[cacheKey] as Record<string, string>) ?? {} |
| 312 | return labelIds |
| 313 | .map((id) => cache[id] || id) |
| 314 | .filter((name) => !name.startsWith('CATEGORY_') && name !== 'UNREAD') |
| 315 | } |
| 316 | |
| 317 | /** |
| 318 | * Creates a lightweight document stub from a thread list entry. |
no test coverage detected