Skip to content

Commit

Permalink
fix(plugin-nested-docs): update draft and published child docs on resave
Browse files Browse the repository at this point in the history
  • Loading branch information
JessChowdhury committed Jan 8, 2025
1 parent 17e7ee2 commit 3be1fa0
Showing 1 changed file with 64 additions and 52 deletions.
116 changes: 64 additions & 52 deletions packages/plugin-nested-docs/src/hooks/resaveChildren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ type ResaveArgs = {

const resave = async ({ collection, doc, draft, pluginConfig, req }: ResaveArgs) => {
const parentSlug = pluginConfig?.parentFieldSlug || 'parent'
const parentDocIsPublished = doc._status === 'published'
const children = await req.payload.find({
const breadcrumbSlug = pluginConfig.breadcrumbsFieldSlug || 'breadcrumbs'

if (draft) {
// If the parent is a draft, don't resave children
return null
}

const draftChildren = await req.payload.find({
collection: collection.slug,
depth: 0,
draft: true,
Expand All @@ -36,51 +42,67 @@ const resave = async ({ collection, doc, draft, pluginConfig, req }: ResaveArgs)
},
})

const breadcrumbSlug = pluginConfig.breadcrumbsFieldSlug || 'breadcrumbs'

try {
await children.docs.reduce(async (priorSave, child) => {
await priorSave
const publishedChildren = await req.payload.find({
collection: collection.slug,
depth: 0,
draft: false,
locale: req.locale,
req,
where: {
[parentSlug]: {
equals: doc.id,
},
},
})

const childIsPublished =
typeof collection.versions === 'object' &&
collection.versions.drafts &&
child._status === 'published'
const childrenById = [...draftChildren.docs, ...publishedChildren.docs].reduce((acc, child) => {
acc[child.id] = acc[child.id] || []
acc[child.id].push(child)
return acc
}, {})

if (!parentDocIsPublished && childIsPublished) {
return
const sortedChildren = Object.values(childrenById).flatMap((group: JsonObject[]) => {
return group.sort((a, b) => {
if (a.updatedAt !== b.updatedAt) {
return a.updatedAt > b.updatedAt ? -1 : 1
}
return a._status === 'published' ? -1 : 1
})
})

await req.payload.update({
id: child.id,
collection: collection.slug,
data: {
...child,
[breadcrumbSlug]: await populateBreadcrumbs(req, pluginConfig, collection, child),
},
depth: 0,
draft: !childIsPublished,
locale: req.locale,
req,
})
}, Promise.resolve())
} catch (err: unknown) {
req.payload.logger.error(
`Nested Docs plugin has had an error while re-saving a child document${
draft ? ' as draft' : ' as published'
}.`,
)
req.payload.logger.error(err)
if (sortedChildren) {
try {
for (const child of sortedChildren) {
const isDraft = child._status !== 'published'

// Use type assertion until we can use instanceof reliably with our Error types
if (
(err as ValidationError)?.name === 'ValidationError' &&
(err as ValidationError)?.data?.errors?.length
) {
throw new APIError(
'Could not publish or save changes: One or more children are invalid.',
400,
await req.payload.update({
id: child.id,
collection: collection.slug,
data: {
...child,
[breadcrumbSlug]: await populateBreadcrumbs(req, pluginConfig, collection, child),
},
depth: 0,
draft: isDraft,
locale: req.locale,
req,
})
}
} catch (err: unknown) {
req.payload.logger.error(
`Nested Docs plugin encountered an error while re-saving a child document.`,
)
req.payload.logger.error(err)

if (
(err as ValidationError)?.name === 'ValidationError' &&
(err as ValidationError)?.data?.errors?.length
) {
throw new APIError(
'Could not publish or save changes: One or more children are invalid.',
400,
)
}
}
}
}
Expand All @@ -91,20 +113,10 @@ export const resaveChildren =
await resave({
collection,
doc,
draft: true,
draft: doc._status === 'published' ? false : true,
pluginConfig,
req,
})

if (doc._status === 'published') {
await resave({
collection,
doc,
draft: false,
pluginConfig,
req,
})
}

return undefined
}

0 comments on commit 3be1fa0

Please sign in to comment.