UNPKG

strapi-plugin-publisher

Version:

A plugin for Strapi Headless CMS that provides the ability to schedule publishing for any content type.

125 lines (111 loc) 3.6 kB
'use strict'; // from https://github.com/strapi/strapi/blob/main/packages/core/content-manager/server/services/utils/populate.js const _ = require('lodash'); const { isAnyToMany, isVisibleAttribute } = require('./relations'); /** * Populate the model for relation * @param {Object} attribute - Attribute containing a relation * @param {String} attribute.relation - type of relation * @param model - Model of the populated entity * @param attributeName * @param {Object} options - Options to apply while populating * @param {Boolean} options.countMany * @param {Boolean} options.countOne * @returns {true|{count: true}} */ function getPopulateForRelation(attribute, model, attributeName, { countMany, countOne }) { const isManyRelation = isAnyToMany(attribute); // always populate createdBy, updatedBy, localizations etc. if (!isVisibleAttribute(model, attributeName)) { return true; } if ((isManyRelation && countMany) || (!isManyRelation && countOne)) { return { count: true }; } return true; } /** * Populate the model for Dynamic Zone components * @param {Object} attribute - Attribute containing the components * @param {String[]} attribute.components - IDs of components * @param {Object} options - Options to apply while populating * @param {Boolean} options.countMany * @param {Boolean} options.countOne * @param {Number} options.maxLevel * @param {Number} level * @returns {{populate: Object}} */ function getPopulateForDZ(attribute, options, level) { const populatedComponents = (attribute.components || []).map((componentUID) => getDeepPopulate(componentUID, options, level + 1) ); return { populate: populatedComponents.reduce(_.merge, {}) }; } /** * Get the populated value based on the type of the attribute * @param {String} attributeName - Name of the attribute * @param {Object} model - Model of the populated entity * @param {Object} model.attributes * @param {Object} options - Options to apply while populating * @param {Boolean} options.countMany * @param {Boolean} options.countOne * @param {Number} options.maxLevel * @param {Number} level * @returns {Object} */ function getPopulateFor(attributeName, model, options, level) { const attribute = model.attributes[attributeName]; switch (attribute.type) { case 'relation': return { [attributeName]: getPopulateForRelation(attribute, model, attributeName, options), }; case 'component': return { [attributeName]: { populate: getDeepPopulate(attribute.component, options, level + 1), }, }; case 'media': return { [attributeName]: { populate: 'folder' }, }; case 'dynamiczone': return { [attributeName]: getPopulateForDZ(attribute, options, level), }; default: return {}; } } /** * Deeply populate a model based on UID * @param {String} uid - Unique identifier of the model * @param {Object} [options] - Options to apply while populating * @param {Boolean} [options.countMany=false] * @param {Boolean} [options.countOne=false] * @param {Number} [options.maxLevel=Infinity] * @param {Number} [level=1] - Current level of nested call * @returns {Object} */ const getDeepPopulate = ( uid, { countMany = false, countOne = false, maxLevel = Infinity } = {}, level = 1 ) => { if (level > maxLevel) { return {}; } const model = strapi.getModel(uid); return Object.keys(model.attributes).reduce( (populateAcc, attributeName) => _.merge( populateAcc, getPopulateFor(attributeName, model, { countMany, countOne, maxLevel }, level) ), {} ); }; module.exports = { getDeepPopulate, };