This repository has been archived by the owner on May 16, 2023. It is now read-only.
forked from digidem/airtable-github-export
-
Notifications
You must be signed in to change notification settings - Fork 5
/
airtable-export.js
82 lines (70 loc) · 2.46 KB
/
airtable-export.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
const stringify = require('json-stable-stringify')
const Airtable = require('airtable')
const { Octokit } = require('@octokit/rest')
require('dotenv').config()
const config = {
tables: process.env.TABLES.split(','),
githubToken: process.env.GITHUB_TOKEN,
repo: process.env.GITHUB_REPO,
owner: process.env.GITHUB_OWNER,
airtableToken: process.env.AIRTABLE_API_KEY,
base: process.env.AIRTABLE_BASE_ID,
branches: process.env.GITHUB_BRANCH ? process.env.GITHUB_BRANCH.split(',') : ['master'],
filename: process.env.GITHUB_FILENAME || 'data.json'
}
const CREATE_MESSAGE = 'Create dump'
const UPDATE_MESSAGE = 'Update dump (if something has changed)'
const octokit = Octokit({
auth: config.githubToken
})
const base = new Airtable({apiKey: config.airtableToken}).base(config.base)
const tasks = config.tables.map(tableName => {
return new Promise((resolve, reject) => {
const data = []
base(tableName).select().eachPage(page, done)
function page (records, next) {
// This function will get called for each page of records.
for (const record of records) {
data.push({
...record._rawJson.fields,
airtableId: record._rawJson.id
})
}
next()
}
function done (err) {
if (err) reject(err)
resolve({table: tableName, data})
}
})
})
Promise.all(tasks).then(results => results.reduce((tables, result) => {
tables[result.table] = result.data
return tables
}, {})).catch(err => console.error(err)).then(tables => {
// Use json-stable-stringify to ensure the JSON to be the same, even if the order has changed
const json = stringify(tables, { space: 2})
return updateOrCreate(json)
}).then(() => {
console.log(`Successful. See https://github.com/${config.owner}/${config.repo}/`)
}).catch(err => { console.error('Error during Airtable dump to Github', err) })
const updateOrCreate = (text) => octokit.repos.getContents({
owner: config.owner,
repo: config.repo,
path: config.filename
}).catch(err => {
if (err.status !== 404) {
throw new Error(err)
} // else: it's ok
}).then(result => {
const createParams = {
owner: config.owner,
repo: config.repo,
path: config.filename,
message: CREATE_MESSAGE,
content: Buffer.from(text, 'utf-8').toString('base64')
}
const updateParams = (result && result.data && result.data.sha) ?
{sha: result.data.sha, message: UPDATE_MESSAGE} : {}
return octokit.repos.createOrUpdateFile({...createParams, ...updateParams})
})