Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby-source-drupal): handle edge case with deleting nodes #33143

Merged
merged 2 commits into from
Sep 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
{
"timestamp": 1593545807,
"entities": [
{
"action": "delete",
"id": "article-71",
"type": "node--article"
},
{
"action": "delete",
"id": "file-4",
"type": "file--file"
},
{
"action": "delete",
"id": "does-not-exist",
"type": "file--file"
},
{
"jsonapi": {
"version": "1.0",
Expand Down
32 changes: 32 additions & 0 deletions packages/gatsby-source-drupal/src/__tests__/fixtures/article.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,38 @@
"data": null
}
}
},
{
"type": "node--article",
"id": "article-71",
"attributes": {
"id": 223,
"uuid": "article-71",
"title": "Article #71",
"body": "Proin pulvinar hendrerit magna nec maximus. Donec rhoncus libero ac nisi porttitor pulvinar. Quisque semper ultricies nulla sit amet vestibulum. Ut vel libero erat. Ut ultrices eleifend scelerisque. Nam non massa sit amet magna molestie tempus vel non neque. Praesent ac est congue, euismod mi ut, tristique mi. Etiam dapibus feugiat lectus, vel condimentum nisl maximus et. Praesent et placerat magna. Sed nec risus non ipsum venenatis placerat. Vestibulum vitae felis eget nunc mattis congue. Morbi volutpat odio purus. Donec placerat massa sed neque molestie, sed finibus nibh scelerisque. In faucibus ante tortor, in efficitur lectus feugiat vitae. Aliquam sodales mollis consectetur."
},
"relationships": {
"field_secondary_image": {
"data": [
{
"type": "file--file",
"id": "file-4"
}
]
},
"field_secondary_multiple_image": {
"data": [
{
"type": "file--file",
"id": "file-3"
},
{
"type": "file--file",
"id": "file-4"
}
]
}
}
}
],
"links": {
Expand Down
72 changes: 40 additions & 32 deletions packages/gatsby-source-drupal/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,50 +136,58 @@ const handleDeletedNode = async ({
return deletedNode
}

// Remove the deleted node from backRefsNamesLookup
// Remove the deleted node from backRefsNamesLookup and referencedNodesLookup
backRefsNamesLookup.delete(deletedNode)
referencedNodesLookup.delete(deletedNode)

// Remove relationships from other nodes and re-create them.
Object.keys(deletedNode.relationships).forEach(key => {
let ids = deletedNode.relationships[key]
ids = [].concat(ids)
ids.forEach(id => {
const node = getNode(id)
let referencedNodes = referencedNodesLookup.get(node)
if (referencedNodes?.includes(deletedNode.id)) {
// Loop over relationships and cleanup references.
Object.entries(node.relationships).forEach(([key, value]) => {
// If a string ref matches, delete it.
if (_.isString(value) && value === deletedNode.id) {
delete node.relationships[key]
}

// If it's an array, filter, then check if the array is empty and then delete
// if so
if (_.isArray(value)) {
value = value.filter(v => v !== deletedNode.id)

if (value.length === 0) {

// The referenced node might have already been deleted.
if (node) {
let referencedNodes = referencedNodesLookup.get(node)
if (referencedNodes?.includes(deletedNode.id)) {
// Loop over relationships and cleanup references.
Object.entries(node.relationships).forEach(([key, value]) => {
// If a string ref matches, delete it.
if (_.isString(value) && value === deletedNode.id) {
delete node.relationships[key]
} else {
node.relationships[key] = value
}
}
})

// Remove deleted node from array of referencedNodes
referencedNodes = referencedNodes.filter(nId => nId !== deletedNode.id)
referencedNodesLookup.set(node, referencedNodes)
}
// Recreate the referenced node with its now cleaned-up relationships.
if (node.internal.owner) {
delete node.internal.owner
}
if (node.fields) {
delete node.fields
// If it's an array, filter, then check if the array is empty and then delete
// if so
if (_.isArray(value)) {
value = value.filter(v => v !== deletedNode.id)

if (value.length === 0) {
delete node.relationships[key]
} else {
node.relationships[key] = value
}
}
})

// Remove deleted node from array of referencedNodes
referencedNodes = referencedNodes.filter(
nId => nId !== deletedNode.id
)
referencedNodesLookup.set(node, referencedNodes)
}

// Recreate the referenced node with its now cleaned-up relationships.
if (node.internal.owner) {
delete node.internal.owner
}
if (node.fields) {
delete node.fields
}
node.internal.contentDigest = createContentDigest(node)
actions.createNode(node)
}
node.internal.contentDigest = createContentDigest(node)
actions.createNode(node)
})
})

Expand Down