Skip to content

Instantly share code, notes, and snippets.

@BaptisteKaliop
Created March 1, 2024 08:53
Show Gist options
  • Save BaptisteKaliop/4c37048bc3225c8eb15598c6b3078e57 to your computer and use it in GitHub Desktop.
Save BaptisteKaliop/4c37048bc3225c8eb15598c6b3078e57 to your computer and use it in GitHub Desktop.
Strapi MRCT hydratation
async hydrateMultiContentTypeField<T extends StrapiContentType>(content: T, currentDepth: number) {
const eligibleProperties: Set<string> = new Set()
const flattenedProperties = this.flattenObj(content.attributes, null)
const nextDepth = currentDepth + 1
const linkedEntries: any[] = []
for (const [key, value] of Object.entries(flattenedProperties)) {
if (typeof value !== "string" || !value.includes("MRCT")) continue
try {
const field = JSON.parse(value)
if (!Array.isArray(field)) continue
for (const item of field) {
if (Object.keys(item).length !== 3 || (!item.uid && typeof item.uid !== "string") || !item.id) continue
eligibleProperties.add(key)
const configuration = CONST.UID_TO_CONTENT_TYPE[item.uid]
if (!configuration) {
console.warn(`WARN: "${item.uid}" is not defined in the constants.ts for MRCT hydration`)
continue
}
let linkedEntry
if (configuration.plural) {
linkedEntry = await this.getEntry(configuration.plural as ContentTypeKey, item.id, null, nextDepth).then(
(response) => ({
uid: item.uid,
response
})
)
} else {
linkedEntry = this.getSingleTypeEntry(configuration.singular as ContentTypeKey, null, nextDepth).then(
(response) => ({
uid: item.uid,
response
})
)
}
linkedEntries.push(linkedEntry)
}
} catch (e) {
continue
}
}
if (!linkedEntries.length) return content
for (const key of Array.from(eligibleProperties)) {
const hydratedArray: ContentType[] = []
const unhydratedField = JSON.parse(flattenedProperties[key]) as { uid: string; id: string }[]
for (const item of unhydratedField) {
const matchingContent = linkedEntries.find(
(linkedEntry) => item.uid === linkedEntry.uid && item.id === linkedEntry.response.data.id
)
const contentTypeConfiguration = CONST.UID_TO_CONTENT_TYPE[item.uid]
if (
matchingContent &&
// Is published
((contentTypeConfiguration.isDraftAndPublish && matchingContent.response.data.attributes.publishedAt) ||
// Is not concerned by "publish/unpublish" status
!contentTypeConfiguration.isDraftAndPublish)
) {
hydratedArray.push(matchingContent.response.data)
}
}
flattenedProperties[key] = hydratedArray
}
const newContent = this.unflatten(flattenedProperties)
return {
...content,
attributes: newContent
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment