-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
gatsby-node.js
133 lines (119 loc) · 3.19 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
122
123
124
125
126
127
128
129
130
131
132
133
const crypto = require(`crypto`)
const uuidv4 = require(`uuid/v4`)
const { buildSchema, printSchema } = require(`graphql`)
const {
makeRemoteExecutableSchema,
transformSchema,
introspectSchema,
RenameTypes,
} = require(`graphql-tools`)
const { createHttpLink } = require(`apollo-link-http`)
const fetch = require(`node-fetch`)
const invariant = require(`invariant`)
const {
NamespaceUnderFieldTransform,
StripNonQueryTransform,
} = require(`./transforms`)
exports.sourceNodes = async (
{ actions, createNodeId, cache, store },
options
) => {
const { addThirdPartySchema, createPageDependency, createNode } = actions
const {
url,
typeName,
fieldName,
headers = {},
fetchOptions = {},
createLink,
createSchema,
refetchInterval,
} = options
invariant(
typeName && typeName.length > 0,
`gatsby-source-graphql requires option \`typeName\` to be specified`
)
invariant(
fieldName && fieldName.length > 0,
`gatsby-source-graphql requires option \`fieldName\` to be specified`
)
invariant(
(url && url.length > 0) || createLink,
`gatsby-source-graphql requires either option \`url\` or \`createLink\` callback`
)
let link
if (createLink) {
link = await createLink(options)
} else {
link = createHttpLink({
uri: url,
fetch,
headers,
fetchOptions,
})
}
let introspectionSchema
if (createSchema) {
introspectionSchema = await createSchema(options)
} else {
const cacheKey = `gatsby-source-graphql-schema-${typeName}-${fieldName}`
let sdl = await cache.get(cacheKey)
if (!sdl) {
introspectionSchema = await introspectSchema(link)
sdl = printSchema(introspectionSchema)
} else {
introspectionSchema = buildSchema(sdl)
}
await cache.set(cacheKey, sdl)
}
const remoteSchema = makeRemoteExecutableSchema({
schema: introspectionSchema,
link,
})
const nodeId = createNodeId(`gatsby-source-graphql-${typeName}`)
const node = createSchemaNode({ id: nodeId, typeName, fieldName })
createNode(node)
const resolver = (parent, args, context) => {
createPageDependency({ path: context.path, nodeId: nodeId })
return {}
}
const schema = transformSchema(remoteSchema, [
new StripNonQueryTransform(),
new RenameTypes(name => `${typeName}_${name}`),
new NamespaceUnderFieldTransform({
typeName,
fieldName,
resolver,
}),
])
addThirdPartySchema({ schema })
if (process.env.NODE_ENV !== `production`) {
if (refetchInterval) {
const msRefetchInterval = refetchInterval * 1000
const refetcher = () => {
createNode(createSchemaNode({ id: nodeId, typeName, fieldName }))
setTimeout(refetcher, msRefetchInterval)
}
setTimeout(refetcher, msRefetchInterval)
}
}
}
function createSchemaNode({ id, typeName, fieldName }) {
const nodeContent = uuidv4()
const nodeContentDigest = crypto
.createHash(`md5`)
.update(nodeContent)
.digest(`hex`)
return {
id,
typeName: typeName,
fieldName: fieldName,
parent: null,
children: [],
internal: {
type: `GraphQLSource`,
contentDigest: nodeContentDigest,
ignoreType: true,
},
}
}