server/helpers/middleware.js

"use strict";

require("core-js/modules/es.object.keys.js");
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.object.get-own-property-descriptor.js");
require("core-js/modules/web.dom-collections.for-each.js");
require("core-js/modules/es.object.get-own-property-descriptors.js");
require("core-js/modules/es.weak-map.js");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.addRelationships = addRelationships;
exports.checkValidEntityType = checkValidEntityType;
exports.checkValidRevisionId = checkValidRevisionId;
exports.checkValidTypeId = checkValidTypeId;
exports.loadEditionStatuses = exports.loadEditionGroupTypes = exports.loadEditionFormats = exports.loadAuthorTypes = void 0;
exports.loadEntityRelationships = loadEntityRelationships;
exports.loadRelationshipTypes = exports.loadRelationshipAttributeTypes = exports.loadPublisherTypes = exports.loadParentRelationshipTypes = exports.loadParentIdentifierTypes = exports.loadLanguages = exports.loadIdentifierTypes = exports.loadGenders = void 0;
exports.loadSeriesItems = loadSeriesItems;
exports.loadSeriesOrderingTypes = void 0;
exports.loadWikipediaExtract = loadWikipediaExtract;
exports.loadWorkTableAuthors = loadWorkTableAuthors;
exports.loadWorkTypes = void 0;
exports.makeCollectionLoader = makeCollectionLoader;
exports.makeEntityLoader = makeEntityLoader;
exports.redirectedBbid = redirectedBbid;
exports.validateBBIDsForCollectionAdd = validateBBIDsForCollectionAdd;
exports.validateBBIDsForCollectionRemove = validateBBIDsForCollectionRemove;
exports.validateCollaboratorIdsForCollectionRemove = validateCollaboratorIdsForCollectionRemove;
exports.validateCollectionParams = validateCollectionParams;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
require("core-js/modules/es.date.to-json.js");
require("core-js/modules/web.url.to-json.js");
require("core-js/modules/es.array.sort.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.map.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.parse-int.js");
require("core-js/modules/es.array.find.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.string.replace.js");
require("core-js/modules/es.array.includes.js");
require("core-js/modules/es.string.includes.js");
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _lowerCase2 = _interopRequireDefault(require("lodash/lowerCase"));
var _camelCase2 = _interopRequireDefault(require("lodash/camelCase"));
var _upperFirst2 = _interopRequireDefault(require("lodash/upperFirst"));
var _keys2 = _interopRequireDefault(require("lodash/keys"));
var _trim2 = _interopRequireDefault(require("lodash/trim"));
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _snakeCase2 = _interopRequireDefault(require("lodash/snakeCase"));
var _isInteger2 = _interopRequireDefault(require("lodash/isInteger"));
var _toNumber2 = _interopRequireDefault(require("lodash/toNumber"));
var _groupBy2 = _interopRequireDefault(require("lodash/groupBy"));
var _remove2 = _interopRequireDefault(require("lodash/remove"));
var commonUtils = _interopRequireWildcard(require("../../common/helpers/utils"));
var error = _interopRequireWildcard(require("../../common/helpers/error"));
var utils = _interopRequireWildcard(require("../helpers/utils"));
var _entity = require("../../client/helpers/entity");
var _wikimedia = require("./wikimedia");
var _i18n = require("./i18n");
var _critiquebrainz = require("./critiquebrainz");
var _wikimedia2 = require("../../common/helpers/wikimedia");
var _log = _interopRequireDefault(require("log"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof3(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /*
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * Copyright (C) 2015       Ben Ockmore
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *               2015-2016  Sean Burke
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *               2021       Akash Gupta
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *               2022       Ansh Goyal
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *               2023       David Kellner
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * This program is free software; you can redistribute it and/or modify
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * it under the terms of the GNU General Public License as published by
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * the Free Software Foundation; either version 2 of the License, or
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * (at your option) any later version.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * This program is distributed in the hope that it will be useful,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * GNU General Public License for more details.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * You should have received a copy of the GNU General Public License along
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * with this program; if not, write to the Free Software Foundation, Inc.,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          */
function makeLoader(modelName, propName, sortFunc) {
  var relations = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
  return /*#__PURE__*/function () {
    var _loaderFunc = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(req, res, next) {
      var orm, model, results, resultsSerial;
      return _regenerator.default.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.prev = 0;
              orm = req.app.locals.orm;
              model = orm[modelName];
              _context.next = 5;
              return model.fetchAll({
                withRelated: (0, _toConsumableArray2.default)(relations)
              });
            case 5:
              results = _context.sent;
              resultsSerial = results.toJSON();
              res.locals[propName] = sortFunc ? resultsSerial.sort(sortFunc) : resultsSerial;
              _context.next = 13;
              break;
            case 10:
              _context.prev = 10;
              _context.t0 = _context["catch"](0);
              return _context.abrupt("return", next(_context.t0));
            case 13:
              next();
              return _context.abrupt("return", null);
            case 15:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, null, [[0, 10]]);
    }));
    function loaderFunc(_x, _x2, _x3) {
      return _loaderFunc.apply(this, arguments);
    }
    return loaderFunc;
  }();
}
var loadAuthorTypes = makeLoader('AuthorType', 'authorTypes');
exports.loadAuthorTypes = loadAuthorTypes;
var loadEditionFormats = makeLoader('EditionFormat', 'editionFormats');
exports.loadEditionFormats = loadEditionFormats;
var loadEditionStatuses = makeLoader('EditionStatus', 'editionStatuses');
exports.loadEditionStatuses = loadEditionStatuses;
var loadIdentifierTypes = makeLoader('IdentifierType', 'identifierTypes');
exports.loadIdentifierTypes = loadIdentifierTypes;
var loadEditionGroupTypes = makeLoader('EditionGroupType', 'editionGroupTypes');
exports.loadEditionGroupTypes = loadEditionGroupTypes;
var loadPublisherTypes = makeLoader('PublisherType', 'publisherTypes');
exports.loadPublisherTypes = loadPublisherTypes;
var loadWorkTypes = makeLoader('WorkType', 'workTypes');
exports.loadWorkTypes = loadWorkTypes;
var loadSeriesOrderingTypes = makeLoader('SeriesOrderingType', 'seriesOrderingTypes');
exports.loadSeriesOrderingTypes = loadSeriesOrderingTypes;
var loadRelationshipTypes = makeLoader('RelationshipType', 'relationshipTypes', null, ['attributeTypes']);
exports.loadRelationshipTypes = loadRelationshipTypes;
var loadParentRelationshipTypes = makeLoader('RelationshipType', 'parentTypes');
exports.loadParentRelationshipTypes = loadParentRelationshipTypes;
var loadParentIdentifierTypes = makeLoader('IdentifierType', 'parentTypes');
exports.loadParentIdentifierTypes = loadParentIdentifierTypes;
var loadRelationshipAttributeTypes = makeLoader('RelationshipAttributeType', 'attributeTypes');
exports.loadRelationshipAttributeTypes = loadRelationshipAttributeTypes;
var loadGenders = makeLoader('Gender', 'genders', function (a, b) {
  return a.id > b.id;
});
exports.loadGenders = loadGenders;
var loadLanguages = makeLoader('Language', 'languages', function (a, b) {
  if (a.frequency !== b.frequency) {
    return b.frequency - a.frequency;
  }
  return a.name.localeCompare(b.name);
});
exports.loadLanguages = loadLanguages;
function loadSeriesItems(req, res, next) {
  try {
    var entity = res.locals.entity;
    if (entity.dataId) {
      var relationships = entity.relationships;
      // Extract the series items from relationships
      var seriesItems = (0, _remove2.default)(relationships, function (relationship) {
        return relationship.typeId > 69 && relationship.typeId < 75;
      });
      if (entity.seriesOrderingType.label === 'Manual') {
        seriesItems.sort(commonUtils.sortRelationshipOrdinal('position'));
      } else {
        seriesItems.sort(commonUtils.sortRelationshipOrdinal('number'));
      }
      var formattedSeriesItems = seriesItems.map(function (item) {
        return _objectSpread(_objectSpread({}, item.source), {}, {
          displayNumber: true,
          number: item.number,
          position: item.position
        });
      });
      res.locals.entity.seriesItems = formattedSeriesItems;
    } else {
      res.locals.entity.seriesItems = [];
    }
    return next();
  } catch (err) {
    return next(err);
  }
}
function loadWorkTableAuthors(_x4, _x5, _x6) {
  return _loadWorkTableAuthors.apply(this, arguments);
}
/**
 * Add the relationships on entity object.
 *
 * @param {Object} entity - The entity to load the relationships for.
 * @param {Object} relationshipSet - The RelationshipSet model.
 * @param {Object} orm - The ORM instance.
 */
function _loadWorkTableAuthors() {
  _loadWorkTableAuthors = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(req, res, next) {
    var orm, entity, workBBIDs, authorsData, authorsDataGroupedByWorkBBID;
    return _regenerator.default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            orm = req.app.locals.orm;
            entity = res.locals.entity;
            _context4.prev = 2;
            workBBIDs = (0, _entity.getRelationshipTargetBBIDByTypeId)(entity, 10);
            _context4.next = 6;
            return orm.func.work.loadAuthorNames(orm, workBBIDs);
          case 6:
            authorsData = _context4.sent;
            authorsDataGroupedByWorkBBID = (0, _groupBy2.default)(authorsData, 'workbbid');
            entity.authorsData = authorsDataGroupedByWorkBBID;
            _context4.next = 14;
            break;
          case 11:
            _context4.prev = 11;
            _context4.t0 = _context4["catch"](2);
            return _context4.abrupt("return", next(_context4.t0));
          case 14:
            return _context4.abrupt("return", next());
          case 15:
          case "end":
            return _context4.stop();
        }
      }
    }, _callee4, null, [[2, 11]]);
  }));
  return _loadWorkTableAuthors.apply(this, arguments);
}
function addRelationships(_x7, _x8, _x9) {
  return _addRelationships.apply(this, arguments);
}
function _addRelationships() {
  _addRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(entity, relationshipSet, orm) {
    var getEntityWithAlias, _getEntityWithAlias, relationshipPromises, relationships;
    return _regenerator.default.wrap(function _callee7$(_context7) {
      while (1) {
        switch (_context7.prev = _context7.next) {
          case 0:
            _getEntityWithAlias = function _getEntityWithAlias3() {
              _getEntityWithAlias = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(relEntity) {
                var redirectBbid, model;
                return _regenerator.default.wrap(function _callee6$(_context6) {
                  while (1) {
                    switch (_context6.prev = _context6.next) {
                      case 0:
                        _context6.next = 2;
                        return orm.func.entity.recursivelyGetRedirectBBID(orm, relEntity.bbid, null);
                      case 2:
                        redirectBbid = _context6.sent;
                        model = commonUtils.getEntityModelByType(orm, relEntity.type);
                        return _context6.abrupt("return", model.forge({
                          bbid: redirectBbid
                        }).fetch({
                          require: false,
                          withRelated: ['defaultAlias'].concat(utils.getAdditionalRelations(relEntity.type))
                        }));
                      case 5:
                      case "end":
                        return _context6.stop();
                    }
                  }
                }, _callee6);
              }));
              return _getEntityWithAlias.apply(this, arguments);
            };
            getEntityWithAlias = function _getEntityWithAlias2(_x34) {
              return _getEntityWithAlias.apply(this, arguments);
            };
            entity.relationships = relationshipSet ? relationshipSet.related('relationships').toJSON() : [];
            utils.attachAttributes(entity.relationships);

            /**
             * Source and target are generic Entity objects, so until we have
             * a good way of polymorphically fetching the right specific entity,
             * we need to fetch default alias in a somewhat sketchier way.
             */
            relationshipPromises = entity.relationships.map( /*#__PURE__*/function () {
              var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(relationship) {
                var _yield$Promise$all, _yield$Promise$all2, source, target;
                return _regenerator.default.wrap(function _callee5$(_context5) {
                  while (1) {
                    switch (_context5.prev = _context5.next) {
                      case 0:
                        _context5.next = 2;
                        return Promise.all([getEntityWithAlias(relationship.source), getEntityWithAlias(relationship.target)]);
                      case 2:
                        _yield$Promise$all = _context5.sent;
                        _yield$Promise$all2 = (0, _slicedToArray2.default)(_yield$Promise$all, 2);
                        source = _yield$Promise$all2[0];
                        target = _yield$Promise$all2[1];
                        relationship.source = source.toJSON();
                        relationship.target = target.toJSON();
                        return _context5.abrupt("return", relationship);
                      case 9:
                      case "end":
                        return _context5.stop();
                    }
                  }
                }, _callee5);
              }));
              return function (_x35) {
                return _ref3.apply(this, arguments);
              };
            }());
            _context7.next = 7;
            return Promise.all(relationshipPromises);
          case 7:
            relationships = _context7.sent;
            return _context7.abrupt("return", relationships);
          case 9:
          case "end":
            return _context7.stop();
        }
      }
    }, _callee7);
  }));
  return _addRelationships.apply(this, arguments);
}
function loadEntityRelationships(_x10, _x11, _x12) {
  return _loadEntityRelationships.apply(this, arguments);
}
function _loadEntityRelationships() {
  _loadEntityRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(req, res, next) {
    var orm, RelationshipSet, entity, relationshipSet;
    return _regenerator.default.wrap(function _callee8$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            orm = req.app.locals.orm;
            RelationshipSet = orm.RelationshipSet;
            entity = res.locals.entity;
            _context8.prev = 3;
            if (entity) {
              _context8.next = 6;
              break;
            }
            throw new error.SiteError('Failed to load entity');
          case 6:
            _context8.next = 8;
            return RelationshipSet.forge({
              id: entity.relationshipSetId
            }).fetch({
              require: false,
              withRelated: ['relationships.source', 'relationships.target', 'relationships.type.attributeTypes', 'relationships.attributeSet.relationshipAttributes.value', 'relationships.attributeSet.relationshipAttributes.type']
            });
          case 8:
            relationshipSet = _context8.sent;
            _context8.next = 11;
            return addRelationships(entity, relationshipSet, orm);
          case 11:
            _context8.next = 16;
            break;
          case 13:
            _context8.prev = 13;
            _context8.t0 = _context8["catch"](3);
            return _context8.abrupt("return", next(_context8.t0));
          case 16:
            return _context8.abrupt("return", next());
          case 17:
          case "end":
            return _context8.stop();
        }
      }
    }, _callee8, null, [[3, 13]]);
  }));
  return _loadEntityRelationships.apply(this, arguments);
}
function loadWikipediaExtract(_x13, _x14, _x15) {
  return _loadWikipediaExtract.apply(this, arguments);
}
function _loadWikipediaExtract() {
  _loadWikipediaExtract = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(req, res, next) {
    var entity, wikidataId, browserLanguages, aliasLanguages, preferredLanguages, article, extract;
    return _regenerator.default.wrap(function _callee9$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            entity = res.locals.entity;
            if (entity) {
              _context9.next = 3;
              break;
            }
            return _context9.abrupt("return", next(new error.SiteError('Failed to load entity')));
          case 3:
            wikidataId = (0, _wikimedia2.getWikidataId)(entity);
            if (wikidataId) {
              _context9.next = 6;
              break;
            }
            return _context9.abrupt("return", next());
          case 6:
            // try to use the user's browser languages, fallback to English and alias languages
            browserLanguages = (0, _i18n.getAcceptedLanguageCodes)(req);
            aliasLanguages = commonUtils.getAliasLanguageCodes(entity);
            preferredLanguages = browserLanguages.concat('en', aliasLanguages);
            _context9.prev = 9;
            _context9.next = 12;
            return (0, _wikimedia.selectWikipediaPage)(wikidataId, {
              forceCache: true,
              preferredLanguages: preferredLanguages
            });
          case 12:
            article = _context9.sent;
            if (!article) {
              _context9.next = 18;
              break;
            }
            _context9.next = 16;
            return (0, _wikimedia.getWikipediaExtract)(article, {
              forceCache: true
            });
          case 16:
            extract = _context9.sent;
            if (extract) {
              res.locals.wikipediaExtract = _objectSpread({
                article: article
              }, extract);
            }
          case 18:
            _context9.next = 23;
            break;
          case 20:
            _context9.prev = 20;
            _context9.t0 = _context9["catch"](9);
            _log.default.warning("Failed to pre-load Wikipedia extract for ".concat(wikidataId, ": ").concat(_context9.t0.message));
          case 23:
            return _context9.abrupt("return", next());
          case 24:
          case "end":
            return _context9.stop();
        }
      }
    }, _callee9, null, [[9, 20]]);
  }));
  return _loadWikipediaExtract.apply(this, arguments);
}
function checkValidRevisionId(req, res, next, id) {
  var idToNumber = (0, _toNumber2.default)(id);
  if (!(0, _isInteger2.default)(idToNumber) || (0, _isInteger2.default)(idToNumber) && idToNumber <= 0) {
    return next(new error.BadRequestError("Invalid revision id: ".concat(req.params.id), req));
  }
  return next();
}
function checkValidTypeId(req, res, next, id) {
  var idToNumber = (0, _toNumber2.default)(id);
  if (!(0, _isInteger2.default)(idToNumber) || idToNumber <= 0) {
    return next(new error.BadRequestError("Invalid Type id: ".concat(req.params.id), req));
  }
  return next();
}
function checkValidEntityType(req, res, next, entityType) {
  var entityTypes = _entity.ENTITY_TYPES.map(function (entity) {
    return (0, _snakeCase2.default)(entity);
  });
  if (!(0, _includes2.default)(entityTypes, entityType)) {
    return next(new error.BadRequestError("Invalid Entity Type: ".concat(commonUtils.snakeCaseToSentenceCase(entityType)), req));
  }
  return next();
}
function redirectedBbid(_x16, _x17, _x18, _x19) {
  return _redirectedBbid.apply(this, arguments);
}
function _redirectedBbid() {
  _redirectedBbid = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(req, res, next, bbid) {
    var orm, redirectBbid;
    return _regenerator.default.wrap(function _callee10$(_context10) {
      while (1) {
        switch (_context10.prev = _context10.next) {
          case 0:
            if (commonUtils.isValidBBID(bbid)) {
              _context10.next = 2;
              break;
            }
            return _context10.abrupt("return", next(new error.BadRequestError("Invalid bbid: ".concat(req.params.bbid), req)));
          case 2:
            orm = req.app.locals.orm;
            _context10.prev = 3;
            _context10.next = 6;
            return orm.func.entity.recursivelyGetRedirectBBID(orm, bbid);
          case 6:
            redirectBbid = _context10.sent;
            if (!(redirectBbid !== bbid)) {
              _context10.next = 9;
              break;
            }
            return _context10.abrupt("return", res.redirect(301, "".concat(req.baseUrl).concat(req.path.replace(bbid, redirectBbid))));
          case 9:
            _context10.next = 14;
            break;
          case 11:
            _context10.prev = 11;
            _context10.t0 = _context10["catch"](3);
            return _context10.abrupt("return", next(_context10.t0));
          case 14:
            return _context10.abrupt("return", next());
          case 15:
          case "end":
            return _context10.stop();
        }
      }
    }, _callee10, null, [[3, 11]]);
  }));
  return _redirectedBbid.apply(this, arguments);
}
function makeEntityLoader(modelName, additionalRels, errMessage) {
  var relations = ['aliasSet.aliases.language', 'annotation.lastRevision', 'defaultAlias', 'disambiguation', 'identifierSet.identifiers.type', 'relationshipSet.relationships.type', 'revision.revision', 'collections.owner'].concat(additionalRels);
  return /*#__PURE__*/function () {
    var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(req, res, next, bbid) {
      var orm, entity, reviews;
      return _regenerator.default.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              orm = req.app.locals.orm;
              if (!commonUtils.isValidBBID(bbid)) {
                _context2.next = 25;
                break;
              }
              _context2.prev = 2;
              _context2.next = 5;
              return orm.func.entity.getEntity(orm, modelName, bbid, relations);
            case 5:
              entity = _context2.sent;
              if (entity.dataId) {
                _context2.next = 11;
                break;
              }
              entity.deleted = true;
              _context2.next = 10;
              return orm.func.entity.getEntityParentAlias(orm, modelName, bbid);
            case 10:
              entity.parentAlias = _context2.sent;
            case 11:
              if (entity.collections) {
                entity.collections = entity.collections.filter(function (collection) {
                  var _req$user;
                  return collection.public === true || parseInt(collection.ownerId, 10) === parseInt((_req$user = req.user) === null || _req$user === void 0 ? void 0 : _req$user.id, 10);
                });
              }
              _context2.next = 14;
              return (0, _critiquebrainz.getReviewsFromCB)(bbid, entity.type);
            case 14:
              reviews = _context2.sent;
              entity.reviews = reviews;
              res.locals.entity = entity;
              return _context2.abrupt("return", next());
            case 20:
              _context2.prev = 20;
              _context2.t0 = _context2["catch"](2);
              return _context2.abrupt("return", next(new error.NotFoundError(errMessage, req)));
            case 23:
              _context2.next = 26;
              break;
            case 25:
              return _context2.abrupt("return", next(new error.BadRequestError('Invalid BBID', req)));
            case 26:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, null, [[2, 20]]);
    }));
    return function (_x20, _x21, _x22, _x23) {
      return _ref.apply(this, arguments);
    };
  }();
}
function makeCollectionLoader() {
  return /*#__PURE__*/function () {
    var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(req, res, next, collectionId) {
      var UserCollection, collection, collectionJSON;
      return _regenerator.default.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              UserCollection = req.app.locals.orm.UserCollection;
              if (!commonUtils.isValidBBID(collectionId)) {
                _context3.next = 17;
                break;
              }
              _context3.prev = 2;
              _context3.next = 5;
              return new UserCollection({
                id: collectionId
              }).fetch({
                require: true,
                withRelated: ['collaborators.collaborator', 'items', 'owner']
              });
            case 5:
              collection = _context3.sent;
              collectionJSON = collection.toJSON(); // reshaping collaborators such that it can be used in EntitySearchFieldOption
              collectionJSON.collaborators = collectionJSON.collaborators.map(function (collaborator) {
                return {
                  id: collaborator.collaborator.id,
                  text: collaborator.collaborator.name
                };
              });
              res.locals.collection = collectionJSON;
              return _context3.abrupt("return", next());
            case 12:
              _context3.prev = 12;
              _context3.t0 = _context3["catch"](2);
              return _context3.abrupt("return", next(new error.NotFoundError('Collection Not Found', req)));
            case 15:
              _context3.next = 18;
              break;
            case 17:
              return _context3.abrupt("return", next(new error.BadRequestError('Invalid Collection ID', req)));
            case 18:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, null, [[2, 12]]);
    }));
    return function (_x24, _x25, _x26, _x27) {
      return _ref2.apply(this, arguments);
    };
  }();
}
function validateCollectionParams(_x28, _x29, _x30) {
  return _validateCollectionParams.apply(this, arguments);
}
function _validateCollectionParams() {
  _validateCollectionParams = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(req, res, next) {
    var _req$body, _req$body$collaborato2, collaborators, name, entityType, orm, Editor, entityTypes, collaboratorIds, i, collaboratorId, editors, editorsJSON, _loop3, _i2, _ret3;
    return _regenerator.default.wrap(function _callee11$(_context11) {
      while (1) {
        switch (_context11.prev = _context11.next) {
          case 0:
            _req$body = req.body, _req$body$collaborato2 = _req$body.collaborators, collaborators = _req$body$collaborato2 === void 0 ? [] : _req$body$collaborato2, name = _req$body.name, entityType = _req$body.entityType;
            orm = req.app.locals.orm;
            Editor = orm.Editor;
            if ((0, _trim2.default)(name).length) {
              _context11.next = 5;
              break;
            }
            return _context11.abrupt("return", next(new error.BadRequestError('Invalid collection name: Empty string not allowed', req)));
          case 5:
            entityTypes = (0, _keys2.default)(commonUtils.getEntityModels(orm));
            if (entityTypes.includes((0, _upperFirst2.default)((0, _camelCase2.default)(entityType)))) {
              _context11.next = 8;
              break;
            }
            return _context11.abrupt("return", next(new error.BadRequestError("Invalid entity type: ".concat(entityType, " does not exist"), req)));
          case 8:
            collaboratorIds = collaborators.map(function (collaborator) {
              return collaborator.id;
            });
            i = 0;
          case 10:
            if (!(i < collaboratorIds.length)) {
              _context11.next = 17;
              break;
            }
            collaboratorId = collaboratorIds[i];
            if (/^\d+$/.test(collaboratorId)) {
              _context11.next = 14;
              break;
            }
            return _context11.abrupt("return", next(new error.BadRequestError("Invalid collaborator id: ".concat(collaboratorId, " not valid"), req)));
          case 14:
            i++;
            _context11.next = 10;
            break;
          case 17:
            _context11.next = 19;
            return new Editor().where('id', 'in', collaboratorIds).fetchAll({
              require: false
            });
          case 19:
            editors = _context11.sent;
            editorsJSON = editors.toJSON();
            _loop3 = function _loop3(_i2) {
              var collaboratorId = collaboratorIds[_i2];
              if (!editorsJSON.find(function (editor) {
                return editor.id === collaboratorId;
              })) {
                return {
                  v: next(new error.NotFoundError("Collaborator ".concat(collaboratorId, " does not exist"), req))
                };
              }
            };
            _i2 = 0;
          case 23:
            if (!(_i2 < collaboratorIds.length)) {
              _context11.next = 30;
              break;
            }
            _ret3 = _loop3(_i2);
            if (!((0, _typeof2.default)(_ret3) === "object")) {
              _context11.next = 27;
              break;
            }
            return _context11.abrupt("return", _ret3.v);
          case 27:
            _i2++;
            _context11.next = 23;
            break;
          case 30:
            return _context11.abrupt("return", next());
          case 31:
          case "end":
            return _context11.stop();
        }
      }
    }, _callee11);
  }));
  return _validateCollectionParams.apply(this, arguments);
}
function validateBBIDsForCollectionAdd(_x31, _x32, _x33) {
  return _validateBBIDsForCollectionAdd.apply(this, arguments);
}
function _validateBBIDsForCollectionAdd() {
  _validateBBIDsForCollectionAdd = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(req, res, next) {
    var Entity, _req$body$bbids2, bbids, collection, collectionType, i, bbid, entities, entitiesJSON, _loop4, _i3, _ret4;
    return _regenerator.default.wrap(function _callee12$(_context12) {
      while (1) {
        switch (_context12.prev = _context12.next) {
          case 0:
            Entity = req.app.locals.orm.Entity;
            _req$body$bbids2 = req.body.bbids, bbids = _req$body$bbids2 === void 0 ? [] : _req$body$bbids2;
            if (bbids.length) {
              _context12.next = 4;
              break;
            }
            return _context12.abrupt("return", next(new error.BadRequestError('BBIDs array is empty')));
          case 4:
            collection = res.locals.collection;
            collectionType = collection.entityType;
            i = 0;
          case 7:
            if (!(i < bbids.length)) {
              _context12.next = 14;
              break;
            }
            bbid = bbids[i];
            if (commonUtils.isValidBBID(bbid)) {
              _context12.next = 11;
              break;
            }
            return _context12.abrupt("return", next(new error.BadRequestError("Invalid BBID ".concat(bbid), req)));
          case 11:
            i++;
            _context12.next = 7;
            break;
          case 14:
            _context12.next = 16;
            return new Entity().where('bbid', 'in', bbids).fetchAll({
              require: false
            });
          case 16:
            entities = _context12.sent;
            entitiesJSON = entities.toJSON();
            _loop4 = function _loop4(_i3) {
              var bbid = bbids[_i3];
              var entity = entitiesJSON.find(function (currEntity) {
                return currEntity.bbid === bbid;
              });
              if (!entity) {
                return {
                  v: next(new error.NotFoundError("".concat(collectionType, " ").concat(bbid, " does not exist"), req))
                };
              }
              if ((0, _lowerCase2.default)(entity.type) !== (0, _lowerCase2.default)(collectionType)) {
                return {
                  v: next(new error.BadRequestError("Cannot add an entity of type ".concat(entity.type, " to a collection of type ").concat(collectionType)))
                };
              }
            };
            _i3 = 0;
          case 20:
            if (!(_i3 < bbids.length)) {
              _context12.next = 27;
              break;
            }
            _ret4 = _loop4(_i3);
            if (!((0, _typeof2.default)(_ret4) === "object")) {
              _context12.next = 24;
              break;
            }
            return _context12.abrupt("return", _ret4.v);
          case 24:
            _i3++;
            _context12.next = 20;
            break;
          case 27:
            return _context12.abrupt("return", next());
          case 28:
          case "end":
            return _context12.stop();
        }
      }
    }, _callee12);
  }));
  return _validateBBIDsForCollectionAdd.apply(this, arguments);
}
function validateBBIDsForCollectionRemove(req, res, next) {
  var _req$body$bbids = req.body.bbids,
    bbids = _req$body$bbids === void 0 ? [] : _req$body$bbids;
  if (!bbids.length) {
    return next(new error.BadRequestError('BBIDs array is empty'));
  }
  var collection = res.locals.collection;
  for (var i = 0; i < bbids.length; i++) {
    var bbid = bbids[i];
    if (!commonUtils.isValidBBID(bbid)) {
      return next(new error.BadRequestError("Invalid BBID ".concat(bbid), req));
    }
  }
  var _loop = function _loop(_i) {
    var bbid = bbids[_i];
    var isBbidInCollection = collection.items.find(function (item) {
      return item.bbid === bbid;
    });
    if (!isBbidInCollection) {
      return {
        v: next(new error.BadRequestError("Entity ".concat(bbid, " is not in collection ").concat(collection.id), req))
      };
    }
  };
  for (var _i = 0; _i < bbids.length; _i++) {
    var _ret = _loop(_i);
    if ((0, _typeof2.default)(_ret) === "object") return _ret.v;
  }
  return next();
}
function validateCollaboratorIdsForCollectionRemove(req, res, next) {
  var _req$body$collaborato = req.body.collaboratorIds,
    collaboratorIds = _req$body$collaborato === void 0 ? [] : _req$body$collaborato;
  if (!collaboratorIds.length) {
    return next(new error.BadRequestError('CollaboratorIds array is empty'));
  }
  var collection = res.locals.collection;
  var _loop2 = function _loop2(i) {
    var collaboratorId = collaboratorIds[i];
    var isCollaborator = collection.collaborators.find(function (collaborator) {
      return collaborator.id === collaboratorId;
    });
    if (!isCollaborator) {
      return {
        v: next(new error.BadRequestError("User ".concat(collaboratorId, " is not a collaborator of collection ").concat(collection.id), req))
      };
    }
  };
  for (var i = 0; i < collaboratorIds.length; i++) {
    var _ret2 = _loop2(i);
    if ((0, _typeof2.default)(_ret2) === "object") return _ret2.v;
  }
  return next();
}
//# sourceMappingURL=middleware.js.map