-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
gatsby-node.js
121 lines (103 loc) · 3.15 KB
/
gatsby-node.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const axios = require(`axios`)
const crypto = require(`crypto`)
const fetch = (username, limit = 100) => {
const url = `https://medium.com/${username}/latest?format=json&limit=${limit}`
return axios.get(url)
}
const prefix = `])}while(1);</x>`
const convertTimestamps = (nextObj, prevObj, prevKey) => {
if (typeof nextObj === `object`) {
Object.keys(nextObj).map(key =>
convertTimestamps(nextObj[key], nextObj, key)
)
} else {
if (typeof nextObj === `number` && nextObj >> 0 !== nextObj) {
const date = new Date(nextObj)
if (date.getTime() === nextObj) {
prevObj[prevKey] = date.toISOString().slice(0, 10)
}
}
}
}
const strip = payload => payload.replace(prefix, ``)
exports.sourceNodes = async (
{ actions, createNodeId },
{ username, limit }
) => {
const { createNode } = actions
try {
const result = await fetch(username, limit)
const json = JSON.parse(strip(result.data))
let importableResources = []
let posts = {} // because `posts` needs to be in a scope accessible by `links` below
const users = Object.keys(json.payload.references.User).map(
key => json.payload.references.User[key]
)
importableResources = importableResources.concat(users)
if (json.payload.posts) {
posts = json.payload.posts
importableResources = importableResources.concat(posts)
}
if (json.payload.references.Post) {
posts = Object.keys(json.payload.references.Post).map(
key => json.payload.references.Post[key]
)
importableResources = importableResources.concat(posts)
}
if (json.payload.references.Collection) {
const collections = Object.keys(json.payload.references.Collection).map(
key => json.payload.references.Collection[key]
)
importableResources = importableResources.concat(collections)
}
const resources = Array.prototype
.concat(...importableResources)
.map(resource => {
return {
...resource,
medium_id: resource.id,
id: createNodeId(resource.id ? resource.id : resource.userId),
}
})
const getID = node => (node ? node.id : null)
resources.map(resource => {
convertTimestamps(resource)
const digest = crypto
.createHash(`md5`)
.update(JSON.stringify(resource))
.digest(`hex`)
const links =
resource.type === `Post`
? {
author___NODE: getID(
resources.find(r => r.userId === resource.creatorId)
),
}
: resource.type === `User`
? {
posts___NODE: resources
.filter(
r => r.type === `Post` && r.creatorId === resource.userId
)
.map(r => r.id),
}
: {}
const node = Object.assign(
resource,
{
parent: null,
children: [],
internal: {
type: `Medium${resource.type}`,
contentDigest: digest,
},
},
links
)
createNode(node)
})
} catch (error) {
console.error(error)
process.exit(1)
}
}