diff --git a/packages/core/data-transfer/lib/providers/local-strapi-source-provider/entities.ts b/packages/core/data-transfer/lib/providers/local-strapi-source-provider/entities.ts index b54293570f..0aaba4b213 100644 --- a/packages/core/data-transfer/lib/providers/local-strapi-source-provider/entities.ts +++ b/packages/core/data-transfer/lib/providers/local-strapi-source-provider/entities.ts @@ -1,5 +1,6 @@ import type { 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,52 @@ 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) || 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] = { populate: componentPopulate }; + } + + populate[key] = size(on) > 0 ? { on } : true; + } + } + + const values = Object.values(populate); + + if (values.length === 0) { + return true; + } + + if (values.every((value) => value === true)) { + return Object.keys(populate); + } + + return populate; };