()
| 58 | } |
| 59 | |
| 60 | export const fetchInngestEvents = async () => { |
| 61 | const maxEvents = MAX_EVENTS; |
| 62 | const all: InngestEventRow[] = []; |
| 63 | let cursor: string | undefined; |
| 64 | |
| 65 | do { |
| 66 | const params = new URLSearchParams({ limit: "100" }); |
| 67 | if (cursor) { |
| 68 | params.set("cursor", cursor); |
| 69 | } |
| 70 | |
| 71 | const res = await fetch(`${baseUrl}/v1/events?${params}`, { |
| 72 | headers: { |
| 73 | Authorization: `Bearer ${signingKey}`, |
| 74 | "Content-Type": "application/json", |
| 75 | }, |
| 76 | }); |
| 77 | |
| 78 | if (!res.ok) { |
| 79 | logger.warn("Inngest API error", { |
| 80 | status: res.status, |
| 81 | body: await res.text(), |
| 82 | }); |
| 83 | break; |
| 84 | } |
| 85 | |
| 86 | const body = (await res.json()) as { |
| 87 | data?: InngestEventRow[]; |
| 88 | cursor?: string; |
| 89 | nextCursor?: string; |
| 90 | }; |
| 91 | const data = Array.isArray(body.data) ? body.data : []; |
| 92 | all.push(...data); |
| 93 | |
| 94 | // Next page: API may return cursor/nextCursor, or use last event's internal_id (per API docs) |
| 95 | const nextCursor = |
| 96 | body.cursor ?? body.nextCursor ?? data[data.length - 1]?.internal_id; |
| 97 | const hasMore = data.length === 100 && nextCursor && all.length < maxEvents; |
| 98 | cursor = hasMore ? nextCursor : undefined; |
| 99 | } while (cursor); |
| 100 | |
| 101 | return all.slice(0, maxEvents); |
| 102 | }; |
| 103 | |
| 104 | /** Fetch runs for a single event (GET /v1/events/{eventId}/runs) – runs are the actual jobs */ |
| 105 | export const fetchInngestRunsForEvent = async ( |
no outgoing calls
no test coverage detected