1 | |
2 |
|
3 | type Airtable = { |
4 | apiKey: string; |
5 | }; |
6 |
|
7 | type AirtableTable = { |
8 | baseId: string; |
9 | tableName: string; |
10 | }; |
11 |
|
12 | |
13 | * List Records |
14 | * List records in a table, following Airtable's `offset` pagination to return |
15 | * every record (the API returns at most 100 per page). Optionally cap the |
16 | * number of records returned with `maxRecords`. |
17 | */ |
18 | export async function main( |
19 | atCon: Airtable, |
20 | atTable: AirtableTable, |
21 | maxRecords?: number, |
22 | ) { |
23 | const records: any[] = []; |
24 | let offset: string | undefined = undefined; |
25 |
|
26 | do { |
27 | const url = new URL( |
28 | `https://api.airtable.com/v0/${atTable.baseId}/${encodeURIComponent( |
29 | atTable.tableName, |
30 | )}`, |
31 | ); |
32 | if (offset !== undefined) { |
33 | url.searchParams.append("offset", offset); |
34 | } |
35 |
|
36 | const response = await fetch(url, { |
37 | method: "GET", |
38 | headers: { |
39 | Authorization: `Bearer ${atCon.apiKey}`, |
40 | }, |
41 | }); |
42 |
|
43 | if (!response.ok) { |
44 | throw new Error(`${response.status} ${await response.text()}`); |
45 | } |
46 |
|
47 | const page = await response.json(); |
48 | records.push(...(page.records ?? [])); |
49 | offset = page.offset; |
50 | } while ( |
51 | offset !== undefined && |
52 | (maxRecords === undefined || records.length < maxRecords) |
53 | ); |
54 |
|
55 | return { |
56 | records: |
57 | maxRecords !== undefined ? records.slice(0, maxRecords) : records, |
58 | }; |
59 | } |
60 |
|