Fix the nested populate for entities export

This commit is contained in:
Convly 2022-11-24 10:19:40 +01:00
parent c87b195361
commit 42304aa680

View File

@ -1,5 +1,6 @@
import type { ContentTypeSchema } from '@strapi/strapi';
import type { ComponentAttribute, ContentTypeSchema } from '@strapi/strapi';
import { isObject, isArray, size } from 'lodash/fp';
import { Readable, PassThrough } from 'stream';
/**
@ -14,7 +15,7 @@ export const createEntitiesStream = (strapi: Strapi.Strapi): Readable => {
// Create a query builder instance (default type is 'select')
.queryBuilder(contentType.uid)
// Apply the populate
.populate(getPopulateAttributes(contentType))
.populate(getPopulateAttributes(strapi, contentType))
// Get a readable stream
.stream();
@ -58,10 +59,58 @@ export const createEntitiesTransformStream = (): PassThrough => {
/**
* Get the list of attributes that needs to be populated for the entities streaming
*/
const getPopulateAttributes = (contentType: ContentTypeSchema) => {
const getPopulateAttributes = (strapi: Strapi.Strapi, contentType: ContentTypeSchema) => {
const { attributes } = contentType;
return Object.keys(attributes).filter((key) =>
['component', 'dynamiczone'].includes(attributes[key].type)
);
const populate: any = {};
const entries: [string, any][] = Object.entries(attributes);
for (const [key, attribute] of entries) {
if (attribute.type === 'component') {
const component = strapi.getModel(attribute.component);
const subPopulate = getPopulateAttributes(strapi, component);
if (isArray(subPopulate)) {
populate[key] = subPopulate;
}
if (isObject(subPopulate) && size(subPopulate) > 0) {
populate[key] = { populate: subPopulate };
}
if (subPopulate === true) {
populate[key] = true;
}
}
if (attribute.type === 'dynamiczone') {
const { components: componentsUID } = attribute;
const on: any = {};
for (const componentUID of componentsUID) {
const component = strapi.getModel(componentUID);
const componentPopulate = getPopulateAttributes(strapi, component);
on[componentUID] = componentPopulate;
}
populate[key] = size(on) > 0 ? { on } : true;
}
}
const values = Object.values(populate);
// console.log(contentType.uid, JSON.stringify(populate, null, 2));
if (values.length === 0) {
return true;
}
if (values.every((value) => value === true)) {
return Object.keys(populate);
}
return populate;
};