UNPKG

forest-express-sequelize

Version:

Official Express/Sequelize Liana for Forest

98 lines (96 loc) 3.78 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); require("core-js/modules/es.promise.js"); require("core-js/modules/es.array.iterator.js"); var _lodash = _interopRequireDefault(require("lodash")); var _forestExpress = require("forest-express"); var _orm = _interopRequireDefault(require("../utils/orm")); var _sequelizeCompatibility = _interopRequireDefault(require("../utils/sequelize-compatibility")); var _errors = require("./errors"); var _queryOptions = _interopRequireDefault(require("./query-options")); function getAggregateField({ aggregateField, parentSchema, parentModel }) { // NOTICE: As MySQL cannot support COUNT(table_name.*) syntax, fieldName cannot be '*'. const fieldName = aggregateField || parentSchema.primaryKeys[0] || parentSchema.fields[0].field; return `${parentModel.name}.${_orm.default.getColumnName(parentSchema, fieldName)}`; } async function getSequelizeOptionsForModel(model, user, timezone) { const queryOptions = new _queryOptions.default(model); const scopeFilters = await _forestExpress.scopeManager.getScopeForUser(user, model.name, true); await queryOptions.filterByConditionTree(scopeFilters, timezone); return queryOptions.sequelizeOptions; } /** * @param {import('sequelize').Model} childModel * @param {import('sequelize').Model} parentModel * @param {{ * labelFieldName: string; * aggregator: string; * aggregateFieldName: string; * limit: number; * }} params */ function LeaderboardStatGetter(childModel, parentModel, params, user) { const labelField = params.labelFieldName; const aggregate = params.aggregator.toUpperCase(); const { limit } = params; const childSchema = _forestExpress.Schemas.schemas[childModel.name]; const parentSchema = _forestExpress.Schemas.schemas[parentModel.name]; let associationAs = childSchema.name; const associationFound = _lodash.default.find(parentModel.associations, function (association) { return association.target.name === childModel.name; }); const aggregateField = getAggregateField({ aggregateField: params.aggregateFieldName, parentSchema, parentModel }); if (!associationFound) { throw new _errors.InvalidParameterError(`Association ${childModel.name} not found`); } if (associationFound.as) { associationAs = associationFound.as; } const labelColumn = _orm.default.getColumnName(childSchema, labelField); const groupBy = `${associationAs}.${labelColumn}`; this.perform = async function () { const { timezone } = params; const parentSequelizeOptions = await getSequelizeOptionsForModel(parentModel, user, timezone); const childSequelizeOptions = await getSequelizeOptionsForModel(childModel, user, timezone); const queryOptions = _sequelizeCompatibility.default.postProcess(parentModel, { attributes: [[childModel.sequelize.col(groupBy), 'key'], [childModel.sequelize.fn(aggregate, childModel.sequelize.col(aggregateField)), 'value']], where: parentSequelizeOptions.where, includeIgnoreAttributes: false, include: [{ model: childModel, attributes: [labelField], as: associationAs, required: true, where: childSequelizeOptions.where, include: childSequelizeOptions.include || [] }, ...(parentSequelizeOptions.include || [])], subQuery: false, group: groupBy, order: [[childModel.sequelize.literal('value'), 'DESC']], limit, raw: true }); const records = await parentModel.findAll(queryOptions); return { value: records.map(function (data) { return { key: data.key, value: Number(data.value) }; }) }; }; } module.exports = LeaderboardStatGetter;