UNPKG

forest-express-sequelize

Version:

Official Express/Sequelize Liana for Forest

77 lines (72 loc) 2.76 kB
"use strict"; require("core-js/modules/es.array.iterator.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.replace.js"); const HAS_ONE = 'HasOne'; const BELONGS_TO = 'BelongsTo'; /** * @param {string[]} values * @returns {string[]} */ function uniqueValues(values) { return Array.from(new Set(values)); } /** * @param {string} key * @param {import('sequelize').Association} association * @returns {string} */ function getTargetFieldName(key, association) { // Defensive programming if (key && association.target.tableAttributes[key]) { return association.target.tableAttributes[key].fieldName; } return undefined; } /** * @param {import('sequelize').HasOne|import('sequelize').BelongsTo} association * @returns {string[]} */ function getMandatoryFields(association) { return association.target.primaryKeyAttributes.map(function (attribute) { return getTargetFieldName(attribute, association); }); } /** * Compute "includes" parameter which is expected by sequelize from a list of fields. * The list of fields can contain fields from relations in the form 'author.firstname' * * @param {string[]} fieldNames model and relationship field names */ function QueryBuilder() { this.getIncludes = function (modelForIncludes, fieldNamesRequested) { const includes = []; Object.values(modelForIncludes.associations).filter(function (association) { return [HAS_ONE, BELONGS_TO].includes(association.associationType); }).forEach(function (association) { const targetFields = Object.values(association.target.tableAttributes).map(function (attribute) { return attribute.fieldName; }); const explicitAttributes = (fieldNamesRequested || []).filter(function (name) { return name.startsWith(`${association.as}.`); }).map(function (name) { return name.replace(`${association.as}.`, ''); }).filter(function (fieldName) { return targetFields.includes(fieldName); }); if (fieldNamesRequested !== null && fieldNamesRequested !== void 0 && fieldNamesRequested.includes(association.as) || explicitAttributes.length) { // NOTICE: For performance reasons, we only request the keys // as they're the only needed fields for the interface const uniqueExplicitAttributes = uniqueValues([...getMandatoryFields(association), ...explicitAttributes].filter(Boolean)); const attributes = explicitAttributes.length ? uniqueExplicitAttributes : undefined; includes.push({ model: association.target.unscoped(), as: association.associationAccessor, attributes }); } }); return includes; }; } module.exports = QueryBuilder;