2023-05-26 17:37:33 +02:00

92 lines
2.7 KiB
JavaScript

'use strict';
const { isNil } = require('lodash/fp');
const { getDeepPopulate, getQueryPopulate } = require('./utils/populate');
/**
* Builder to create a Strapi populate object.
*
* @param {string} uid - Content type UID
*
* @example
* const populate = await populateBuilder('api::article.article').countRelations().build();
* // populate = { article: { populate: { count: true } } }
*
*/
const populateBuilder = (uid) => {
let getInitialPopulate = async () => {};
const deepPopulateOptions = {
countMany: false,
countOne: false,
maxLevel: -1,
};
const builder = {
/**
* Populates all attribute fields present in a query.
* @param {Object} query - Query object
* @returns {typeof builder} - Builder
*/
populateFromQuery(query) {
getInitialPopulate = async () => getQueryPopulate(uid, query);
return builder;
},
/**
* Populate relations as count if condition is true.
* @param {Boolean} condition
* @param {Object} [options]
* @param {Boolean} [options.toMany] - Populate XtoMany relations as count if true.
* @param {Boolean} [options.toOne] - Populate XtoOne relations as count if true.
* @returns {typeof builder} - Builder
*/
countRelationsIf(condition, { toMany, toOne } = { toMany: true, toOne: true }) {
if (condition) {
return this.countRelations({ toMany, toOne });
}
return builder;
},
/**
* Populate relations as count.
* @param {Object} [options]
* @param {Boolean } [options.toMany] - Populate XtoMany relations as count if true.
* @param {Boolean} [options.toOne] - Populate XtoOne relations as count if true.
* @returns {typeof builder} - Builder
*/
countRelations({ toMany, toOne } = { toMany: true, toOne: true }) {
if (!isNil(toMany)) {
deepPopulateOptions.countMany = toMany;
}
if (!isNil(toOne)) {
deepPopulateOptions.countOne = toOne;
}
return builder;
},
/**
* Populate relations deeply, up to a certain level.
* @param {Number} [level=Infinity] - Max level of nested populate.
* @returns {typeof builder} - Builder
*/
populateDeep(level = Infinity) {
deepPopulateOptions.maxLevel = level;
return builder;
},
/**
* Construct the populate object based on the builder options.
* @returns {Object} - Populate object
*/
async build() {
const initialPopulate = await getInitialPopulate();
if (deepPopulateOptions.maxLevel === -1) {
return initialPopulate;
}
return getDeepPopulate(uid, { ...deepPopulateOptions, initialPopulate });
},
};
return builder;
};
module.exports = () => populateBuilder;