Skip to content

Commit dd130f1

Browse files
authored
feat(gatsby): pass webhook data to sourceNodes functions (gatsbyjs#15564)
* feat(gatsby): pass webhook data to sourceNodes plugins from Cloud * chore: stat writing e2e test * test: add e2e test * chore: fix failing test * chore: get tests passing in CI (by skipping them 😩) * fix: only apply to refresh endpoint; skip test * chore: reset _after_
1 parent 54abc5f commit dd130f1

File tree

9 files changed

+63
-15
lines changed

9 files changed

+63
-15
lines changed

.eslintrc.json

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
},
2626
"globals": {
2727
"before": true,
28+
"after": true,
2829
"spyOn": true,
2930
"__PATH_PREFIX__": true,
3031
"__BASE_PATH__": true,

e2e-tests/development-runtime/cypress/integration/gatsby-preview/updating.js

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ beforeEach(() => {
33
cy.visit(`/preview`).waitForRouteChange()
44
})
55

6+
after(() => reset())
7+
68
const update = (times = 1) =>
79
new Array(times)
810
.fill(undefined)
@@ -48,4 +50,14 @@ describe(`Gatsby Preview (Updating)`, () => {
4850
.its(`length`)
4951
.should(`be`, 1)
5052
})
53+
54+
/*
55+
* TODO: get this test passing in CI
56+
* https://github.com/testing-library/cypress-testing-library/issues/23
57+
*/
58+
it.skip(`can be triggered with webhook data`, () => {
59+
cy.exec(`npm run update:webhook`)
60+
61+
cy.queryByText(`Hello World from a Webhook (999)`).should(`exist`)
62+
})
5163
})

e2e-tests/development-runtime/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"reset": "node scripts/reset.js",
3636
"reset:preview": "node plugins/gatsby-source-fake-data/reset.js && npm run update:preview",
3737
"update": "node scripts/update.js",
38+
"update:webhook": "node scripts/webhook.js",
3839
"update:preview": "curl -X POST http://localhost:8000/__refresh",
3940
"start-server-and-test": "start-server-and-test develop http://localhost:8000 cy:run",
4041
"cy:open": "cypress open",

e2e-tests/development-runtime/plugins/gatsby-source-fake-data/api.js

+2
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,5 @@ We welcome any and all contributions! 💪
101101
return writeFile(this.dbFilePath, [])
102102
},
103103
}
104+
105+
module.exports.getNode = getNode

e2e-tests/development-runtime/plugins/gatsby-source-fake-data/gatsby-node.js

+20-11
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,30 @@ exports.sourceNodes = async function sourceNodes({
1515
createNodeId,
1616
createContentDigest,
1717
getNode,
18+
reporter,
19+
webhookBody,
1820
}) {
1921
const { createNode, deleteNode } = actions
2022

21-
const [updated, deleted = []] = await api.sync({
23+
const helpers = {
2224
createNodeId,
2325
createContentDigest,
24-
})
26+
}
27+
28+
if (webhookBody && webhookBody.items) {
29+
reporter.info(`Webhook data detected; creating nodes`)
30+
webhookBody.items.forEach(node => createNode(api.getNode(node, helpers)))
31+
} else {
32+
const [updated, deleted = []] = await api.sync(helpers)
2533

26-
updated.forEach(node => createNode(node))
27-
deleted.forEach(node => {
28-
const existing = getNode(node.id)
29-
if (existing) {
30-
deleteNode({
31-
node: existing,
32-
})
33-
}
34-
})
34+
updated.forEach(node => createNode(node))
35+
deleted.forEach(node => {
36+
const existing = getNode(node.id)
37+
if (existing) {
38+
deleteNode({
39+
node: existing,
40+
})
41+
}
42+
})
43+
}
3544
}

e2e-tests/development-runtime/scripts/hook-with-data.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require(`isomorphic-fetch`)
2+
3+
fetch(`http://localhost:8000/__refresh`, {
4+
method: `POST`,
5+
headers: {
6+
"Content-Type": `application/json`,
7+
},
8+
body: JSON.stringify({
9+
items: [
10+
{
11+
updates: 0,
12+
uuid: 999,
13+
title: `Hello World from a Webhook (999)`,
14+
message: `testing`,
15+
},
16+
],
17+
}),
18+
})

packages/gatsby/src/commands/develop.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,19 @@ async function startServer(program) {
175175
* This behavior is disabled by default, but the ENABLE_REFRESH_ENDPOINT env var enables it
176176
* If no GATSBY_REFRESH_TOKEN env var is available, then no Authorization header is required
177177
**/
178-
app.post(`/__refresh`, (req, res) => {
178+
const REFRESH_ENDPOINT = `/__refresh`
179+
app.use(REFRESH_ENDPOINT, express.json())
180+
app.post(REFRESH_ENDPOINT, (req, res) => {
179181
const enableRefresh = process.env.ENABLE_GATSBY_REFRESH_ENDPOINT
180182
const refreshToken = process.env.GATSBY_REFRESH_TOKEN
181183
const authorizedRefresh =
182184
!refreshToken || req.headers.authorization === refreshToken
183185

184186
if (enableRefresh && authorizedRefresh) {
185187
console.log(`Refreshing source data`)
186-
sourceNodes()
188+
sourceNodes({
189+
webhookBody: req.body,
190+
})
187191
}
188192
res.end()
189193
})

packages/gatsby/src/utils/source-nodes.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ function discoverPluginsWithoutNodes(storeState) {
3131
return _.difference(nodeCreationPlugins, nodeOwners)
3232
}
3333

34-
module.exports = async ({ parentSpan } = {}) => {
34+
module.exports = async ({ webhookBody = {}, parentSpan } = {}) => {
3535
await apiRunner(`sourceNodes`, {
3636
traceId: `initial-sourceNodes`,
3737
waitForCascadingActions: true,
38-
parentSpan: parentSpan,
38+
parentSpan,
39+
webhookBody,
3940
})
4041

4142
const state = store.getState()

0 commit comments

Comments
 (0)