diff --git a/packages/strapi-plugin-rest-cache/server/utils/config/getRelatedModelsUid.js b/packages/strapi-plugin-rest-cache/server/utils/config/getRelatedModelsUid.js index 8fea828a7..1cba3d12d 100644 --- a/packages/strapi-plugin-rest-cache/server/utils/config/getRelatedModelsUid.js +++ b/packages/strapi-plugin-rest-cache/server/utils/config/getRelatedModelsUid.js @@ -16,119 +16,63 @@ function getRelatedModelsUid(strapi, uid) { return []; } - const models = strapi.contentTypes; - - const { components } = strapi; - const modelObj = models[uid]; - const modelAttributes = modelObj?.attributes ?? {}; - /** - * @type {any[]} - */ - const relatedComponents = []; - /** - * @type {any} - */ - const relatedModels = {}; - - // first, look for direct relations in other contentTypes - for (const key in modelAttributes) { - if (!Object.hasOwnProperty.call(modelAttributes, key)) { - continue; - } - - const attr = modelAttributes[key]; - - if (attr.type !== 'relation') continue; - if (!attr.target) continue; - - relatedModels[attr.target] = models[attr.target]; - } - - // second, look for relations to current model in components - for (const compKey in components) { - if (!Object.hasOwnProperty.call(components, compKey)) { - continue; - } - - const compObj = components[compKey]; - const attributes = compObj?.attributes ?? {}; - - for (const key in attributes) { - if (!Object.hasOwnProperty.call(attributes, key)) { + let contentTypeList = [uid]; + let componentList = []; + while (true) { + const componentListLenght = componentList.length; + for (const component of Object.values(strapi.components)) { + if (componentList.includes(component.uid)) { continue; } - - const attr = attributes[key]; - - if (attr.type !== 'relation') continue; - if (!attr.target) continue; - - if (attr.target === uid) { - relatedComponents.push(compKey); + for (const attribute of Object.values(component.attributes)) { + if (attribute.type === 'relation') { + if ( + contentTypeList.includes(attribute.target) && + !componentList.includes(component.uid) + ) { + componentList.push(component.uid); + } + } else if (attribute.type === 'component') { + if ( + componentList.includes(attribute.component) && + !componentList.includes(component.uid) + ) { + componentList.push(component.uid); + } + } } } - } - - // third, look for nested components with relations to current model - for (const compKey in components) { - if (!Object.hasOwnProperty.call(components, compKey)) { - continue; - } - const compObj = components[compKey]; - const attributes = compObj?.attributes ?? {}; - // check if current component contains another component that contains a relation to the current model - // look one level deeper - for (const key in attributes) { - if (!Object.hasOwnProperty.call(attributes, key)) { + const contentTypeListLenght = contentTypeList.length; + for (const contentType of Object.values(strapi.contentTypes)) { + if (contentTypeList.includes(contentType.uid)) { continue; } - - const attr = attributes[key]; - - if (attr.type !== 'component') continue; - if (!attr.component) continue; - if (!relatedComponents.includes(attr.component)) continue; - if (relatedComponents.includes(compKey)) continue; - - relatedComponents.push(compKey); - } - } - - // finally locate all the models that have the related components in their models - for (const modelKey in models) { - if (!Object.hasOwnProperty.call(models, modelKey)) { - continue; - } - - const otherModelObj = models[modelKey]; - const attributes = otherModelObj?.attributes ?? {}; - - for (const key in attributes) { - if (!Object.hasOwnProperty.call(attributes, key)) { - continue; + for (const attribute of Object.values(contentType.attributes)) { + if (attribute.type === 'relation') { + if ( + contentTypeList.includes(attribute.target) && + !contentTypeList.includes(contentType.uid) + ) { + contentTypeList.push(contentType.uid); + } + } else if (attribute.type === 'component') { + if ( + componentList.includes(attribute.component) && + !contentTypeList.includes(contentType.uid) + ) { + contentTypeList.push(contentType.uid); + } + } } - const attr = attributes[key]; - - if (attr.type !== 'component') continue; - if (!attr.component) continue; - if (!relatedComponents.includes(attr.component)) continue; - if (relatedModels[modelKey]) continue; - - relatedModels[modelKey] = models[modelKey]; } - } - - const relatedModelUid = []; - - Object.values(relatedModels).reduce((acc, model) => { - if (model.uid) { - acc.push(model.uid); + if ( + contentTypeListLenght === contentTypeList.length && + componentListLenght === componentList.length + ) { + return contentTypeList; } - return acc; - }, relatedModelUid); - - return relatedModelUid; + } } module.exports = { getRelatedModelsUid };