UNPKG

3.15 kBJavaScriptView Raw
1#!/usr/bin/env node
2const fs = require('fs')
3const path = require('path')
4const { promisify } = require('util')
5const request = require('request-promise')
6const { uniqBy } = require('lodash')
7const additionalSupporters = require('./additional-supporters.json')
8const removeSupporters = require('./remove-supporters.json')
9
10const asyncWriteFile = promisify(fs.writeFile)
11
12const API_KEY = '43d883997da5983dc50dfcb288c690903fbebf9a'
13const REQUIRED_KEYS = ['totalDonations', 'slug', 'name']
14const filename = 'supports.json'
15const absoluteFilename = path.resolve('/home/zhixin/www/opencollective', filename)
16
17const graphqlEndpoint = `https://api.opencollective.com/graphql/v2/${API_KEY}`
18
19const graphqlQuery = `query account($limit: Int, $offset: Int) {
20 account(slug: "bootstrap-table") {
21 orders(limit: $limit, offset: $offset) {
22 limit
23 offset
24 totalCount
25 nodes {
26 fromAccount {
27 name
28 slug
29 website
30 imageUrl
31 }
32 totalDonations {
33 value
34 }
35 createdAt
36 }
37 }
38 }
39}`
40
41const graphqlPageSize = 1000
42
43const nodeToSupporter = node => ({
44 name: node.fromAccount.name,
45 slug: node.fromAccount.slug,
46 website: node.fromAccount.website,
47 avatar: node.fromAccount.imageUrl,
48 firstDonation: node.createdAt,
49 totalDonations: node.totalDonations.value
50})
51
52const getAllOrders = async () => {
53 const requestOptions = {
54 method: 'POST',
55 uri: graphqlEndpoint,
56 body: { query: graphqlQuery, variables: { limit: graphqlPageSize, offset: 0 } },
57 json: true
58 }
59
60 let allOrders = []
61
62 // Handling pagination if necessary (2 pages for ~1400 results in May 2019)
63 // eslint-disable-next-line
64 while (true) {
65 const result = await request(requestOptions)
66 const orders = result.data.account.orders.nodes
67 allOrders = [...allOrders, ...orders]
68 requestOptions.body.variables.offset += graphqlPageSize
69 if (orders.length < graphqlPageSize) {
70 return allOrders
71 }
72 }
73}
74
75getAllOrders()
76 .then(orders => {
77 let supporters = orders.map(nodeToSupporter)
78
79 supporters = supporters.concat(additionalSupporters)
80 .sort((a, b) => b.totalDonations - a.totalDonations)
81
82 // Deduplicating supporters with multiple orders
83 supporters = uniqBy(supporters, 'slug')
84
85 supporters = supporters.filter(s => {
86 return s.totalDonations > 0 && !removeSupporters.slugs.includes(s.slug)
87 })
88
89 if (!Array.isArray(supporters)) {
90 throw new Error('Supporters data is not an array.')
91 }
92
93 for (const item of supporters) {
94 for (const key of REQUIRED_KEYS) {
95 if (!item || typeof item !== 'object') {
96 throw new Error(`Supporters: ${JSON.stringify(item)} is not an object.`)
97 }
98 if (!(key in item)) {
99 throw new Error(`Supporters: ${JSON.stringify(item)} doesn't include ${key}.`)
100 }
101 }
102 }
103
104 // Write the file
105 return asyncWriteFile(absoluteFilename, JSON.stringify(supporters, null, 2)).then(() =>
106 console.log(`Fetched 1 file: ${filename}`)
107 )
108 })
109 .catch(error => {
110 console.error('utilities/fetch-supporters:', error)
111 })