server/routes/entity/entity.js

"use strict";

require("core-js/modules/es.array.from.js");
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.symbol.description.js");
require("core-js/modules/es.symbol.iterator.js");
require("core-js/modules/es.object.get-own-property-descriptor.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 _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.addNoteToRevision = addNoteToRevision;
exports.areaToOption = areaToOption;
exports.compareEntitiesByDate = compareEntitiesByDate;
exports.constructAliases = constructAliases;
exports.constructAuthorCredit = constructAuthorCredit;
exports.constructIdentifiers = constructIdentifiers;
exports.constructRelationships = constructRelationships;
exports.deleteRelationships = deleteRelationships;
exports.displayDeleteEntity = displayDeleteEntity;
exports.displayEntity = displayEntity;
exports.displayPreview = displayPreview;
exports.displayRevisions = displayRevisions;
exports.fetchEntitiesForRelationships = fetchEntitiesForRelationships;
exports.fetchOrCreateMainEntity = fetchOrCreateMainEntity;
exports.getChangedProps = getChangedProps;
exports.getDefaultAliasIndex = getDefaultAliasIndex;
exports.getEntityByBBID = getEntityByBBID;
exports.getNextRelationshipAttributeSets = getNextRelationshipAttributeSets;
exports.getNextRelationshipSets = getNextRelationshipSets;
exports.handleCreateOrEditEntity = handleCreateOrEditEntity;
exports.handleDelete = handleDelete;
exports.indexAutoCreatedEditionGroup = indexAutoCreatedEditionGroup;
exports.processMergeOperation = processMergeOperation;
exports.processSingleEntity = processSingleEntity;
exports.saveEntitiesAndFinishRevision = saveEntitiesAndFinishRevision;
exports.updateDisplayedRevisions = updateDisplayedRevisions;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.array.map.js");
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.string.split.js");
require("core-js/modules/es.parse-int.js");
require("core-js/modules/es.date.to-json.js");
require("core-js/modules/web.url.to-json.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.number.constructor.js");
require("core-js/modules/es.array.find-index.js");
require("core-js/modules/es.array.slice.js");
require("core-js/modules/es.array.find.js");
require("core-js/modules/web.dom-collections.for-each.js");
require("core-js/modules/es.object.keys.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.array.reduce.js");
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
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 _isNull2 = _interopRequireDefault(require("lodash/isNull"));
var _has2 = _interopRequireDefault(require("lodash/has"));
var _forEach2 = _interopRequireDefault(require("lodash/forEach"));
var _forOwn2 = _interopRequireDefault(require("lodash/forOwn"));
var _isEqual2 = _interopRequireDefault(require("lodash/isEqual"));
var _reduce2 = _interopRequireDefault(require("lodash/reduce"));
var _get2 = _interopRequireDefault(require("lodash/get"));
var _reject2 = _interopRequireDefault(require("lodash/reject"));
var _flatMap2 = _interopRequireDefault(require("lodash/flatMap"));
var _pick2 = _interopRequireDefault(require("lodash/pick"));
var _assign2 = _interopRequireDefault(require("lodash/assign"));
var _keys2 = _interopRequireDefault(require("lodash/keys"));
var _unionBy2 = _interopRequireDefault(require("lodash/unionBy"));
var _values2 = _interopRequireDefault(require("lodash/values"));
var _without2 = _interopRequireDefault(require("lodash/without"));
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _set2 = _interopRequireDefault(require("lodash/set"));
var _isNil2 = _interopRequireDefault(require("lodash/isNil"));
var _uniq2 = _interopRequireDefault(require("lodash/uniq"));
var _compact2 = _interopRequireDefault(require("lodash/compact"));
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
var _upperFirst2 = _interopRequireDefault(require("lodash/upperFirst"));
var _camelCase2 = _interopRequireDefault(require("lodash/camelCase"));
var _isString2 = _interopRequireDefault(require("lodash/isString"));
var _map2 = _interopRequireDefault(require("lodash/map"));
var _uniqBy2 = _interopRequireDefault(require("lodash/uniqBy"));
var React = _interopRequireWildcard(require("react"));
var achievement = _interopRequireWildcard(require("../../helpers/achievement"));
var commonUtils = _interopRequireWildcard(require("../../../common/helpers/utils"));
var error = _interopRequireWildcard(require("../../../common/helpers/error"));
var handler = _interopRequireWildcard(require("../../helpers/handler"));
var propHelpers = _interopRequireWildcard(require("../../../client/helpers/props"));
var search = _interopRequireWildcard(require("../../../common/helpers/search"));
var utils = _interopRequireWildcard(require("../../helpers/utils"));
var _props2 = require("../../helpers/props");
var _author = _interopRequireDefault(require("../../../client/components/pages/entities/author"));
var _deletion = _interopRequireDefault(require("../../../client/components/forms/deletion"));
var _editionGroup = _interopRequireDefault(require("../../../client/components/pages/entities/edition-group"));
var _edition = _interopRequireDefault(require("../../../client/components/pages/entities/edition"));
var _entityRevisions = _interopRequireDefault(require("../../../client/components/pages/entity-revisions"));
var _layout = _interopRequireDefault(require("../../../client/containers/layout"));
var _preview = _interopRequireDefault(require("../../../client/components/forms/preview"));
var _publisher = _interopRequireDefault(require("../../../client/components/pages/entities/publisher"));
var _server = _interopRequireDefault(require("react-dom/server"));
var _series = _interopRequireDefault(require("../../../client/components/pages/entities/series"));
var _work = _interopRequireDefault(require("../../../client/components/pages/entities/work"));
var _entity = require("../../../client/helpers/entity");
var _revisions = require("../../helpers/revisions");
var _log = _interopRequireDefault(require("log"));
var _processUnifiedForm = require("./process-unified-form");
var _target = _interopRequireDefault(require("../../templates/target"));
var _excluded = ["sourceBbid", "targetBbid"];
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 || _typeof(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; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /*
                                                                                                                                                                                         * Copyright (C) 2016  Ben Ockmore
                                                                                                                                                                                         *               2016  Sean Burke
                                                                                                                                                                                         *				 2021  Akash Gupta
                                                                                                                                                                                         * 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.
                                                                                                                                                                                         */
var entityComponents = {
  author: _author.default,
  edition: _edition.default,
  editionGroup: _editionGroup.default,
  publisher: _publisher.default,
  series: _series.default,
  work: _work.default
};
function displayEntity(req, res) {
  var orm = req.app.locals.orm;
  var AchievementUnlock = orm.AchievementUnlock,
    EditorEntityVisits = orm.EditorEntityVisits;
  var resLocals = res.locals;
  var entity = resLocals.entity;
  // Get unique identifier types for display
  // $FlowFixMe
  var identifierTypes = [];
  if (entity.identifierSet) {
    identifierTypes = (0, _uniqBy2.default)((0, _map2.default)(entity.identifierSet.identifiers, 'type'), 'id');
  }
  var editorEntityVisitPromise;
  if (resLocals.user) {
    editorEntityVisitPromise = new EditorEntityVisits({
      bbid: resLocals.entity.bbid,
      editorId: resLocals.user.id
    }).save(null, {
      method: 'insert'
    }).then(function () {
      return achievement.processPageVisit(orm, resLocals.user.id);
    }).catch(
    // error caused by duplicates we do not want in database
    function () {
      return new Promise(function (resolve) {
        return resolve(false);
      });
    });
  } else {
    editorEntityVisitPromise = new Promise(function (resolve) {
      return resolve(false);
    });
  }
  var alertPromise = editorEntityVisitPromise.then(function (visitAlert) {
    var alertIds = [];
    if (visitAlert.alert) {
      alertIds = alertIds.concat(visitAlert.alert.split(',').map(function (id) {
        return parseInt(id, 10);
      }));
    }
    if ((0, _isString2.default)(req.query.alert)) {
      // $FlowFixMe
      alertIds = alertIds.concat(req.query.alert.split(',').map(function (id) {
        return parseInt(id, 10);
      }));
    }
    if (alertIds.length > 0) {
      var promiseList = alertIds.map(function (achievementAlert) {
        return new AchievementUnlock({
          id: achievementAlert
        }).fetch({
          require: true,
          withRelated: 'achievement'
        }).then(function (unlock) {
          return unlock.toJSON();
        }).then(function (unlock) {
          var unlockName;
          if (req.user.id === unlock.editorId) {
            unlockName = {
              name: unlock.achievement.name
            };
          }
          return unlockName;
        }).catch(function (err) {
          _log.default.debug(err);
        });
      });
      alertPromise = Promise.all(promiseList);
    } else {
      alertPromise = new Promise(function (resolve) {
        return resolve(false);
      });
    }
    return alertPromise;
  });
  return alertPromise.then(function (alert) {
    var entityName = (0, _camelCase2.default)(entity.type);
    var EntityComponent = entityComponents[entityName];
    if (EntityComponent) {
      var props = (0, _props2.generateProps)(req, res, {
        alert: alert,
        genderOptions: res.locals.genders,
        identifierTypes: identifierTypes
      });
      var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(props), /*#__PURE__*/React.createElement(EntityComponent, propHelpers.extractEntityProps(props))));
      res.send((0, _target.default)({
        markup: markup,
        page: entityName,
        props: (0, _props2.escapeProps)(props),
        script: '/js/entity/entity.js',
        title: "".concat((0, _entity.getEntityLabel)(props.entity, false), " (").concat((0, _upperFirst2.default)(entityName), ")")
      }));
    } else {
      throw new Error("Component was not found for the following entity:".concat(entityName));
    }
  });
}
function displayDeleteEntity(req, res) {
  var props = (0, _props2.generateProps)(req, res);
  var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(props), /*#__PURE__*/React.createElement(_deletion.default, {
    entity: props.entity
  })));
  res.send((0, _target.default)({
    markup: markup,
    props: (0, _props2.escapeProps)(props),
    script: '/js/deletion.js'
  }));
}
function displayRevisions(_x, _x2, _x3, _x4) {
  return _displayRevisions.apply(this, arguments);
} // eslint-disable-next-line consistent-return
function _displayRevisions() {
  _displayRevisions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(req, res, next, RevisionModel) {
    var size, from, orm, bbid, orderedRevisions, _commonUtils$getNextE, newResultsArray, nextEnabled, props, markup;
    return _regenerator.default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            size = (0, _isString2.default)(req.query.size) ? parseInt(req.query.size, 10) : 20;
            from = (0, _isString2.default)(req.query.from) ? parseInt(req.query.from, 10) : 0;
            orm = req.app.locals.orm;
            bbid = req.params.bbid;
            _context2.prev = 4;
            _context2.next = 7;
            return (0, _revisions.getOrderedRevisionsForEntityPage)(orm, from, size + 1, RevisionModel, bbid);
          case 7:
            orderedRevisions = _context2.sent;
            _commonUtils$getNextE = commonUtils.getNextEnabledAndResultsArray(orderedRevisions, size), newResultsArray = _commonUtils$getNextE.newResultsArray, nextEnabled = _commonUtils$getNextE.nextEnabled;
            props = (0, _props2.generateProps)(req, res, {
              from: from,
              nextEnabled: nextEnabled,
              revisions: newResultsArray,
              showRevisionEditor: true,
              showRevisionNote: true,
              size: size
            });
            markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(props), /*#__PURE__*/React.createElement(_entityRevisions.default, (0, _extends2.default)({
              entity: props.entity
            }, propHelpers.extractChildProps(props)))));
            return _context2.abrupt("return", res.send((0, _target.default)({
              markup: markup,
              page: 'revisions',
              props: (0, _props2.escapeProps)(props),
              script: '/js/entity/entity.js'
            })));
          case 14:
            _context2.prev = 14;
            _context2.t0 = _context2["catch"](4);
            return _context2.abrupt("return", next(_context2.t0));
          case 17:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2, null, [[4, 14]]);
  }));
  return _displayRevisions.apply(this, arguments);
}
function updateDisplayedRevisions(_x5, _x6, _x7, _x8) {
  return _updateDisplayedRevisions.apply(this, arguments);
}
function _updateDisplayedRevisions() {
  _updateDisplayedRevisions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(req, res, next, RevisionModel) {
    var size, from, orm, bbid, orderedRevisions;
    return _regenerator.default.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            size = (0, _isString2.default)(req.query.size) ? parseInt(req.query.size, 10) : 20;
            from = (0, _isString2.default)(req.query.from) ? parseInt(req.query.from, 10) : 0;
            orm = req.app.locals.orm;
            bbid = req.params.bbid;
            _context3.prev = 4;
            _context3.next = 7;
            return (0, _revisions.getOrderedRevisionsForEntityPage)(orm, from, size, RevisionModel, bbid);
          case 7:
            orderedRevisions = _context3.sent;
            res.send(orderedRevisions);
            _context3.next = 14;
            break;
          case 11:
            _context3.prev = 11;
            _context3.t0 = _context3["catch"](4);
            return _context3.abrupt("return", next(_context3.t0));
          case 14:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee3, null, [[4, 11]]);
  }));
  return _updateDisplayedRevisions.apply(this, arguments);
}
function _createNote(orm, content, editorID, revision, transacting) {
  var Note = orm.Note;
  if (content) {
    var revisionId = revision.get('id');
    return new Note({
      authorId: editorID,
      content: content,
      revisionId: revisionId
    }).save(null, {
      transacting: transacting
    });
  }
  return null;
}
function addNoteToRevision(req, res) {
  var orm = req.app.locals.orm;
  var Revision = orm.Revision,
    bookshelf = orm.bookshelf;
  var editorJSON = req.session.passport.user;
  var revision = Revision.forge({
    id: req.params.id
  });
  var body = req.body;
  var revisionNotePromise = bookshelf.transaction(function (transacting) {
    return _createNote(orm, body.note, editorJSON.id, revision, transacting);
  });
  return handler.sendPromiseResult(res, revisionNotePromise);
}
function getEntityByBBID(_x9, _x10, _x11) {
  return _getEntityByBBID.apply(this, arguments);
}
function _getEntityByBBID() {
  _getEntityByBBID = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(orm, transacting, bbid) {
    var redirectBbid, entityHeader, model;
    return _regenerator.default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return orm.func.entity.recursivelyGetRedirectBBID(orm, bbid, transacting);
          case 2:
            redirectBbid = _context4.sent;
            _context4.next = 5;
            return orm.Entity.forge({
              bbid: redirectBbid
            }).fetch({
              transacting: transacting
            });
          case 5:
            entityHeader = _context4.sent;
            model = commonUtils.getEntityModelByType(orm, entityHeader.get('type'));
            return _context4.abrupt("return", model.forge({
              bbid: redirectBbid
            }).fetch({
              transacting: transacting
            }));
          case 8:
          case "end":
            return _context4.stop();
        }
      }
    }, _callee4);
  }));
  return _getEntityByBBID.apply(this, arguments);
}
function setParentRevisions(_x12, _x13, _x14) {
  return _setParentRevisions.apply(this, arguments);
}
function _setParentRevisions() {
  _setParentRevisions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(transacting, newRevision, parentRevisionIDs) {
    var parents;
    return _regenerator.default.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            if (!(0, _isEmpty2.default)(parentRevisionIDs)) {
              _context5.next = 2;
              break;
            }
            return _context5.abrupt("return", new Promise(function (resolve) {
              return resolve(null);
            }));
          case 2:
            _context5.next = 4;
            return newRevision.related('parents').fetch({
              transacting: transacting
            });
          case 4:
            parents = _context5.sent;
            return _context5.abrupt("return", parents.attach(parentRevisionIDs, {
              transacting: transacting
            }));
          case 6:
          case "end":
            return _context5.stop();
        }
      }
    }, _callee5);
  }));
  return _setParentRevisions.apply(this, arguments);
}
function saveEntitiesAndFinishRevision(_x15, _x16, _x17, _x18, _x19, _x20, _x21, _x22) {
  return _saveEntitiesAndFinishRevision.apply(this, arguments);
}
function _saveEntitiesAndFinishRevision() {
  _saveEntitiesAndFinishRevision = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(orm, transacting, isNew, newRevision, mainEntity, updatedEntities, editorID, note) {
    var parentRevisionIDs, entitiesSavedPromise, editorUpdatePromise, notePromise, parentsAddedPromise, _yield$Promise$all, _yield$Promise$all2, savedEntities, others;
    return _regenerator.default.wrap(function _callee6$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            parentRevisionIDs = (0, _compact2.default)((0, _uniq2.default)(updatedEntities.map(function (entityModel) {
              return entityModel.get('revisionId');
            })));
            entitiesSavedPromise = Promise.all((0, _map2.default)(updatedEntities, function (entityModel) {
              entityModel.set('revisionId', newRevision.get('id'));
              var shouldInsert = entityModel.get('bbid') === mainEntity.get('bbid') && isNew;
              var method = shouldInsert ? 'insert' : 'update';
              return entityModel.save(null, {
                method: method,
                transacting: transacting
              });
            }));
            editorUpdatePromise = utils.incrementEditorEditCountById(orm, editorID, transacting);
            notePromise = _createNote(orm, note, editorID, newRevision, transacting);
            parentsAddedPromise = setParentRevisions(transacting, newRevision, parentRevisionIDs);
            /** model.save returns a refreshed model */
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            _context6.next = 7;
            return Promise.all([entitiesSavedPromise, editorUpdatePromise, parentsAddedPromise, notePromise]);
          case 7:
            _yield$Promise$all = _context6.sent;
            _yield$Promise$all2 = (0, _toArray2.default)(_yield$Promise$all);
            savedEntities = _yield$Promise$all2[0];
            others = _yield$Promise$all2.slice(1);
            return _context6.abrupt("return", savedEntities.find(function (entityModel) {
              return entityModel.get('bbid') === mainEntity.get('bbid');
            }) || mainEntity);
          case 12:
          case "end":
            return _context6.stop();
        }
      }
    }, _callee6);
  }));
  return _saveEntitiesAndFinishRevision.apply(this, arguments);
}
function deleteRelationships(_x23, _x24, _x25) {
  return _deleteRelationships.apply(this, arguments);
}
function _deleteRelationships() {
  _deleteRelationships = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(orm, transacting, mainEntity) {
    var mainBBID, relationshipSet, otherBBIDs, otherEntities;
    return _regenerator.default.wrap(function _callee8$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            mainBBID = mainEntity.bbid;
            relationshipSet = mainEntity.relationshipSet;
            otherBBIDs = [];
            otherEntities = [];
            if (!relationshipSet) {
              _context8.next = 13;
              break;
            }
            if (relationshipSet.relationships) {
              _context8.next = 7;
              break;
            }
            return _context8.abrupt("return", []);
          case 7:
            relationshipSet.relationships.forEach(function (relationship) {
              if (relationship.sourceBbid === mainBBID) {
                otherBBIDs.push(relationship.targetBbid);
              } else if (relationship.targetBbid === mainBBID) {
                otherBBIDs.push(relationship.sourceBbid);
              }
            });

            // Loop over the BBID's of other entites related to deleted entity
            if (!otherBBIDs.length) {
              _context8.next = 13;
              break;
            }
            if (!(otherBBIDs.length === 0)) {
              _context8.next = 11;
              break;
            }
            return _context8.abrupt("return", []);
          case 11:
            _context8.next = 13;
            return Promise.all(otherBBIDs.map( /*#__PURE__*/function () {
              var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(entityBbid) {
                var otherEntity, otherEntityRelationshipSet, otherEntityRelationships, newRelationshipSet;
                return _regenerator.default.wrap(function _callee7$(_context7) {
                  while (1) {
                    switch (_context7.prev = _context7.next) {
                      case 0:
                        _context7.next = 2;
                        return getEntityByBBID(orm, transacting, entityBbid);
                      case 2:
                        otherEntity = _context7.sent;
                        _context7.next = 5;
                        return otherEntity.relationshipSet().fetch({
                          require: false,
                          transacting: transacting,
                          withRelated: 'relationships'
                        });
                      case 5:
                        otherEntityRelationshipSet = _context7.sent;
                        if (!(0, _isNil2.default)(otherEntityRelationshipSet)) {
                          _context7.next = 8;
                          break;
                        }
                        return _context7.abrupt("return");
                      case 8:
                        // Fetch other entity relationships to remove relation with the deleted entity
                        otherEntityRelationships = otherEntityRelationshipSet.related('relationships').toJSON(); // Mark entites related to deleted entity as removed
                        otherEntityRelationships = otherEntityRelationships.map(function (rel) {
                          if (mainBBID !== rel.sourceBbid && mainBBID !== rel.targetBbid) {
                            return rel;
                          }
                          (0, _set2.default)(rel, 'isRemoved', true);
                          return rel;
                        });
                        _context7.next = 12;
                        return orm.func.relationship.updateRelationshipSets(orm, transacting, otherEntityRelationshipSet, otherEntityRelationships);
                      case 12:
                        newRelationshipSet = _context7.sent;
                        otherEntity.set('relationshipSetId', newRelationshipSet[entityBbid] ? newRelationshipSet[entityBbid].get('id') : null);
                        otherEntities.push(otherEntity);
                      case 15:
                      case "end":
                        return _context7.stop();
                    }
                  }
                }, _callee7);
              }));
              return function (_x99) {
                return _ref6.apply(this, arguments);
              };
            }()));
          case 13:
            return _context8.abrupt("return", otherEntities);
          case 14:
          case "end":
            return _context8.stop();
        }
      }
    }, _callee8);
  }));
  return _deleteRelationships.apply(this, arguments);
}
function fetchOrCreateMainEntity(orm, transacting, isNew, bbid, entityType) {
  var model = commonUtils.getEntityModelByType(orm, entityType);
  var entity = model.forge({
    bbid: bbid
  });
  if (isNew) {
    return new Promise(function (resolve) {
      return resolve(entity);
    });
  }
  return entity.fetch({
    transacting: transacting
  });
}
function handleDelete(orm, req, res, HeaderModel, RevisionModel) {
  var entity = res.locals.entity;
  if (!entity.dataId) {
    throw new error.ConflictError('This entity has already been deleted');
  }
  var Revision = orm.Revision,
    bookshelf = orm.bookshelf;
  var editorJSON = req.session.passport.user;
  var body = req.body;
  var entityDeletePromise = bookshelf.transaction( /*#__PURE__*/function () {
    var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(transacting) {
      var otherEntities, newRevision, entityRevision, mainEntity, savedMainEntity;
      return _regenerator.default.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!(!body.note || !body.note.length)) {
                _context.next = 2;
                break;
              }
              throw new error.FormSubmissionError('A revision note is required when deleting an entity');
            case 2:
              _context.next = 4;
              return deleteRelationships(orm, transacting, entity);
            case 4:
              otherEntities = _context.sent;
              _context.next = 7;
              return new Revision({
                authorId: editorJSON.id
              }).save(null, {
                transacting: transacting
              });
            case 7:
              newRevision = _context.sent;
              _context.next = 10;
              return new RevisionModel({
                bbid: entity.bbid,
                dataId: null,
                id: newRevision.get('id')
              }).save(null, {
                method: 'insert',
                transacting: transacting
              });
            case 10:
              entityRevision = _context.sent;
              _context.next = 13;
              return setParentRevisions(transacting, newRevision, [entity.revisionId]);
            case 13:
              _context.next = 15;
              return new HeaderModel({
                bbid: entity.bbid,
                masterRevisionId: entityRevision.get('id')
              }).save(null, {
                transacting: transacting
              });
            case 15:
              _context.next = 17;
              return fetchOrCreateMainEntity(orm, transacting, false, entity.bbid, entity.type);
            case 17:
              mainEntity = _context.sent;
              _context.next = 20;
              return saveEntitiesAndFinishRevision(orm, transacting, false, newRevision, mainEntity, otherEntities, editorJSON.id, body.note);
            case 20:
              savedMainEntity = _context.sent;
              return _context.abrupt("return", savedMainEntity.toJSON({
                omitPivot: true
              }));
            case 22:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return function (_x26) {
      return _ref.apply(this, arguments);
    };
  }());
  return handler.sendPromiseResult(res, entityDeletePromise, search.deleteEntity);
}
function processMergeOperation(_x27, _x28, _x29, _x30, _x31, _x32) {
  return _processMergeOperation.apply(this, arguments);
}
function _processMergeOperation() {
  _processMergeOperation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(orm, transacting, session, mainEntity, allEntities, relationshipSets) {
    var Edition, bookshelf, mergingEntities, entityType, currentEntityBBID, mergingEntitiesBBIDs, entitiesToMergeBBIDs, allEntitiesReturnArray, entitiesToMerge, entitiesModelsToMerge, editionsToSet, editionsToSetCollections, _editionsToSet;
    return _regenerator.default.wrap(function _callee14$(_context14) {
      while (1) {
        switch (_context14.prev = _context14.next) {
          case 0:
            Edition = orm.Edition, bookshelf = orm.bookshelf;
            mergingEntities = session.mergeQueue.mergingEntities;
            if (mergingEntities) {
              _context14.next = 4;
              break;
            }
            throw new Error('Merge handler called with no merge queue, aborting');
          case 4:
            entityType = mainEntity.get('type');
            currentEntityBBID = mainEntity.get('bbid');
            mergingEntitiesBBIDs = Object.keys(mergingEntities);
            if ((0, _includes2.default)(mergingEntitiesBBIDs, currentEntityBBID)) {
              _context14.next = 9;
              break;
            }
            throw new Error('Entity being merged into does not appear in merge queue, aborting');
          case 9:
            entitiesToMergeBBIDs = (0, _without2.default)(Object.keys(mergingEntities), currentEntityBBID);
            allEntitiesReturnArray = allEntities; // fetch entities we're merging to add them to to the array of modified entities
            entitiesToMerge = (0, _values2.default)(mergingEntities).filter(function (_ref7) {
              var bbid = _ref7.bbid;
              return bbid !== currentEntityBBID;
            });
            _context14.next = 14;
            return Promise.all(entitiesToMergeBBIDs.map(function (bbid) {
              return fetchOrCreateMainEntity(orm, transacting, false, bbid, entityType);
            }));
          case 14:
            entitiesModelsToMerge = _context14.sent;
            /** Add entities to be merged to the array of modified entities */
            allEntitiesReturnArray = (0, _unionBy2.default)(allEntitiesReturnArray, entitiesModelsToMerge, 'id');

            /** Remove relationships that concern entities being merged from already modified relationshipSets */
            _context14.next = 18;
            return Promise.all((0, _map2.default)(relationshipSets, /*#__PURE__*/function () {
              var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(relationshipSet) {
                var refreshedrelationshipSet, relationshipsToRemove;
                return _regenerator.default.wrap(function _callee9$(_context9) {
                  while (1) {
                    switch (_context9.prev = _context9.next) {
                      case 0:
                        if (!relationshipSet) {
                          _context9.next = 8;
                          break;
                        }
                        _context9.next = 3;
                        return relationshipSet.refresh({
                          transacting: transacting,
                          withRelated: 'relationships'
                        });
                      case 3:
                        refreshedrelationshipSet = _context9.sent;
                        /** Find relationships with entities being merge and remove them from set */
                        relationshipsToRemove = refreshedrelationshipSet.related('relationships').toJSON().filter(function (_ref9) {
                          var sourceBbid = _ref9.sourceBbid,
                            targetBbid = _ref9.targetBbid;
                          return (0, _includes2.default)(entitiesToMergeBBIDs, sourceBbid) || (0, _includes2.default)(entitiesToMergeBBIDs, targetBbid);
                        }).map(function (_ref10) {
                          var id = _ref10.id;
                          return id;
                        });
                        if (!relationshipsToRemove.length) {
                          _context9.next = 8;
                          break;
                        }
                        _context9.next = 8;
                        return refreshedrelationshipSet.related('relationships').detach(relationshipsToRemove, {
                          transacting: transacting
                        });
                      case 8:
                      case "end":
                        return _context9.stop();
                    }
                  }
                }, _callee9);
              }));
              return function (_x100) {
                return _ref8.apply(this, arguments);
              };
            }()));
          case 18:
            _context14.next = 20;
            return Promise.all(entitiesModelsToMerge.map( /*#__PURE__*/function () {
              var _ref11 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(entity) {
                var entityBBID, relationshipSet, relationships, otherEntitiesToFetch;
                return _regenerator.default.wrap(function _callee11$(_context11) {
                  while (1) {
                    switch (_context11.prev = _context11.next) {
                      case 0:
                        entityBBID = entity.get('bbid');
                        _context11.next = 3;
                        return entity.relationshipSet().fetch({
                          require: false,
                          transacting: transacting,
                          withRelated: 'relationships'
                        });
                      case 3:
                        relationshipSet = _context11.sent;
                        if (relationshipSet) {
                          _context11.next = 6;
                          break;
                        }
                        return _context11.abrupt("return");
                      case 6:
                        relationships = relationshipSet.related('relationships').toJSON();
                        otherEntitiesToFetch = relationships.reduce(function (accumulator, relationship) {
                          if (relationship.sourceBbid === entityBBID) {
                            accumulator.push(relationship.targetBbid);
                          } else if (relationship.targetBbid === entityBBID) {
                            accumulator.push(relationship.sourceBbid);
                          }
                          return accumulator;
                        }, [])
                        // Ignore entities that already have a modified relationshipSet (dealed with above)
                        .filter(function (bbid) {
                          return !(0, _includes2.default)((0, _keys2.default)(relationshipSets), bbid);
                        });
                        _context11.next = 10;
                        return Promise.all(otherEntitiesToFetch.map( /*#__PURE__*/function () {
                          var _ref12 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(bbid) {
                            var otherEntity, otherEntityRelationshipSet, otherEntityRelationships, relsHaveChanged, updatedRelationshipSets;
                            return _regenerator.default.wrap(function _callee10$(_context10) {
                              while (1) {
                                switch (_context10.prev = _context10.next) {
                                  case 0:
                                    _context10.next = 2;
                                    return getEntityByBBID(orm, transacting, bbid);
                                  case 2:
                                    otherEntity = _context10.sent;
                                    _context10.next = 5;
                                    return entity.relationshipSet().fetch({
                                      require: false,
                                      transacting: transacting,
                                      withRelated: 'relationships'
                                    });
                                  case 5:
                                    otherEntityRelationshipSet = _context10.sent;
                                    if (otherEntityRelationshipSet) {
                                      _context10.next = 8;
                                      break;
                                    }
                                    return _context10.abrupt("return");
                                  case 8:
                                    otherEntityRelationships = otherEntityRelationshipSet.related('relationships').toJSON();
                                    relsHaveChanged = false; // Mark relationships with entity being merged as removed
                                    otherEntityRelationships.forEach(function (rel) {
                                      if (entityBBID === rel.sourceBbid || entityBBID === rel.targetBbid) {
                                        (0, _set2.default)(rel, 'isRemoved', true);
                                        relsHaveChanged = true;
                                      }
                                    });

                                    // If there's a difference, apply the new relationships array without rels to merged entity
                                    if (!relsHaveChanged) {
                                      _context10.next = 17;
                                      break;
                                    }
                                    _context10.next = 14;
                                    return orm.func.relationship.updateRelationshipSets(orm, transacting, otherEntityRelationshipSet, otherEntityRelationships);
                                  case 14:
                                    updatedRelationshipSets = _context10.sent;
                                    // Make sure the entity is later updated with its new relationshipSet id
                                    allEntitiesReturnArray = (0, _unionBy2.default)(allEntitiesReturnArray, [otherEntity], 'id');
                                    (0, _assign2.default)(relationshipSets, (0, _pick2.default)(updatedRelationshipSets, bbid));
                                  case 17:
                                  case "end":
                                    return _context10.stop();
                                }
                              }
                            }, _callee10);
                          }));
                          return function (_x102) {
                            return _ref12.apply(this, arguments);
                          };
                        }()));
                      case 10:
                      case "end":
                        return _context11.stop();
                    }
                  }
                }, _callee11);
              }));
              return function (_x101) {
                return _ref11.apply(this, arguments);
              };
            }()));
          case 20:
            if (!(entityType === 'EditionGroup')) {
              _context14.next = 25;
              break;
            }
            _context14.next = 23;
            return Edition.query(function (qb) {
              return qb.whereIn('edition_group_bbid', entitiesToMergeBBIDs).andWhere('master', true);
            }).fetchAll({
              require: false,
              transacting: transacting
            });
          case 23:
            editionsToSet = _context14.sent;
            if (editionsToSet.length) {
              editionsToSet.forEach(function (editionModel) {
                return editionModel.set({
                  editionGroupBbid: currentEntityBBID
                });
              });
              // Add the modified Editions to the revision
              allEntitiesReturnArray = (0, _unionBy2.default)(allEntitiesReturnArray, editionsToSet.toArray(), 'id');
            }
          case 25:
            if (!(entityType === 'Publisher')) {
              _context14.next = 40;
              break;
            }
            _context14.prev = 26;
            _context14.next = 29;
            return Promise.all(entitiesModelsToMerge.map(function (entitiesModel) {
              return entitiesModel.editions();
            }));
          case 29:
            editionsToSetCollections = _context14.sent;
            // eslint-disable-next-line consistent-return
            _editionsToSet = (0, _flatMap2.default)(editionsToSetCollections, function (edition) {
              if (edition.models && edition.models.length) {
                return edition.models;
              }
            }); // Remove 'undefined' entries (no editions in those publishers)
            _editionsToSet = (0, _reject2.default)(_editionsToSet, _isNil2.default);
            _context14.next = 34;
            return Promise.all(_editionsToSet.map( /*#__PURE__*/function () {
              var _ref13 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(edition) {
                var oldPublisherSet, newPublisherSet;
                return _regenerator.default.wrap(function _callee12$(_context12) {
                  while (1) {
                    switch (_context12.prev = _context12.next) {
                      case 0:
                        _context12.next = 2;
                        return edition.publisherSet();
                      case 2:
                        oldPublisherSet = _context12.sent;
                        _context12.next = 5;
                        return orm.func.publisher.updatePublisherSet(orm, transacting, oldPublisherSet, [{
                          bbid: currentEntityBBID
                        }]);
                      case 5:
                        newPublisherSet = _context12.sent;
                        // Set the new PublisherSet on the Edition
                        edition.set('publisherSetId', newPublisherSet.get('id'));
                        // Add the modified Edition to the revision (if it doesn't exist yet)
                        allEntitiesReturnArray = (0, _unionBy2.default)(allEntitiesReturnArray, [edition], 'id');
                      case 8:
                      case "end":
                        return _context12.stop();
                    }
                  }
                }, _callee12);
              }));
              return function (_x103) {
                return _ref13.apply(this, arguments);
              };
            }()));
          case 34:
            _context14.next = 40;
            break;
          case 36:
            _context14.prev = 36;
            _context14.t0 = _context14["catch"](26);
            _log.default.error(_context14.t0);
            throw _context14.t0;
          case 40:
            /**
             * Some actions we only want to take once the main entity has been saved
            */
            mainEntity.once('saved', /*#__PURE__*/function () {
              var _ref14 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(model) {
                var newEntityRevision;
                return _regenerator.default.wrap(function _callee13$(_context13) {
                  while (1) {
                    switch (_context13.prev = _context13.next) {
                      case 0:
                        _context13.next = 2;
                        return model.revision().fetch({
                          transacting: transacting
                        });
                      case 2:
                        newEntityRevision = _context13.sent;
                        _context13.next = 5;
                        return newEntityRevision.where('bbid', currentEntityBBID).save({
                          isMerge: true
                        }, {
                          patch: true,
                          transacting: transacting
                        });
                      case 5:
                        _context13.next = 7;
                        return newEntityRevision.query(function (qb) {
                          return qb.whereIn('bbid', entitiesToMergeBBIDs);
                        }).save({
                          dataId: null,
                          isMerge: true
                        }, {
                          patch: true,
                          transacting: transacting
                        });
                      case 7:
                        /** Clear the merge queue */
                        session.mergeQueue = null;
                        _context13.prev = 8;
                        _context13.next = 11;
                        return Promise.all(entitiesToMerge.map(search.deleteEntity));
                      case 11:
                        _context13.next = 16;
                        break;
                      case 13:
                        _context13.prev = 13;
                        _context13.t0 = _context13["catch"](8);
                        _log.default.debug(_context13.t0);
                      case 16:
                      case "end":
                        return _context13.stop();
                    }
                  }
                }, _callee13, null, [[8, 13]]);
              }));
              return function (_x104) {
                return _ref14.apply(this, arguments);
              };
            }());

            /** Update the redirection table to redirect merged entities' bbids
             *  to currentEntityBBID (the entity we're merging into)
            */
            _context14.next = 43;
            return bookshelf.knex('bookbrainz.entity_redirect').transacting(transacting).insert(entitiesToMergeBBIDs.map(function (bbid) {
              return (
                // eslint-disable-next-line camelcase
                {
                  source_bbid: bbid,
                  target_bbid: currentEntityBBID
                }
              );
            }));
          case 43:
            return _context14.abrupt("return", allEntitiesReturnArray);
          case 44:
          case "end":
            return _context14.stop();
        }
      }
    }, _callee14, null, [[26, 36]]);
  }));
  return _processMergeOperation.apply(this, arguments);
}
function processAuthorCredit(_x33, _x34, _x35, _x36) {
  return _processAuthorCredit.apply(this, arguments);
}
function _processAuthorCredit() {
  _processAuthorCredit = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(orm, currentEntity, newEntityBody, transacting) {
    var authorCreditEnabled, existingAuthorCreditID, oldAuthorCredit, names, newAuthorCredit;
    return _regenerator.default.wrap(function _callee15$(_context15) {
      while (1) {
        switch (_context15.prev = _context15.next) {
          case 0:
            authorCreditEnabled = newEntityBody.creditSection !== false;
            if (authorCreditEnabled) {
              _context15.next = 3;
              break;
            }
            return _context15.abrupt("return", {
              authorCreditId: null
            });
          case 3:
            existingAuthorCreditID = (0, _get2.default)(currentEntity, ['authorCredit', 'id']);
            _context15.next = 6;
            return existingAuthorCreditID && orm.AuthorCredit.forge({
              id: existingAuthorCreditID
            }).fetch({
              transacting: transacting,
              withRelated: ['names']
            });
          case 6:
            oldAuthorCredit = _context15.sent;
            names = (0, _get2.default)(newEntityBody, 'authorCredit') || [];
            _context15.next = 10;
            return orm.func.authorCredit.updateAuthorCredit(orm, transacting, oldAuthorCredit, names.map(function (name) {
              return {
                authorBBID: name.authorBBID,
                joinPhrase: name.joinPhrase,
                name: name.name
              };
            }));
          case 10:
            newAuthorCredit = _context15.sent;
            return _context15.abrupt("return", {
              authorCreditId: newAuthorCredit && newAuthorCredit.get('id')
            });
          case 12:
          case "end":
            return _context15.stop();
        }
      }
    }, _callee15);
  }));
  return _processAuthorCredit.apply(this, arguments);
}
function processEditionSets(_x37, _x38, _x39, _x40) {
  return _processEditionSets.apply(this, arguments);
}
function _processEditionSets() {
  _processEditionSets = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(orm, currentEntity, body, transacting) {
    var languageSetID, oldLanguageSet, languages, newLanguageSet, newLanguageSetID, publisherSetID, oldPublisherSet, publishers, newPublisherSet, newPublisherSetID, releaseEventSetID, oldReleaseEventSet, releaseEvents, newReleaseEventSet, newReleaseEventSetID, newAuthorCredit, newAuthorCreditID;
    return _regenerator.default.wrap(function _callee16$(_context16) {
      while (1) {
        switch (_context16.prev = _context16.next) {
          case 0:
            languageSetID = (0, _get2.default)(currentEntity, ['languageSet', 'id']);
            _context16.next = 3;
            return languageSetID && orm.LanguageSet.forge({
              id: languageSetID
            }).fetch({
              transacting: transacting,
              withRelated: ['languages']
            });
          case 3:
            oldLanguageSet = _context16.sent;
            languages = (0, _get2.default)(body, 'languages') || [];
            _context16.next = 7;
            return orm.func.language.updateLanguageSet(orm, transacting, oldLanguageSet, languages.map(function (languageID) {
              return {
                id: languageID
              };
            }));
          case 7:
            newLanguageSet = _context16.sent;
            newLanguageSetID = newLanguageSet && newLanguageSet.get('id');
            publisherSetID = (0, _get2.default)(currentEntity, ['publisherSet', 'id']);
            _context16.next = 12;
            return publisherSetID && orm.PublisherSet.forge({
              id: publisherSetID
            }).fetch({
              transacting: transacting,
              withRelated: ['publishers']
            });
          case 12:
            oldPublisherSet = _context16.sent;
            publishers = (0, _get2.default)(body, 'publishers') || [];
            _context16.next = 16;
            return orm.func.publisher.updatePublisherSet(orm, transacting, oldPublisherSet, publishers.map(function (publisherBBID) {
              return {
                bbid: publisherBBID
              };
            }));
          case 16:
            newPublisherSet = _context16.sent;
            newPublisherSetID = newPublisherSet && newPublisherSet.get('id');
            releaseEventSetID = (0, _get2.default)(currentEntity, ['releaseEventSet', 'id']);
            _context16.next = 21;
            return releaseEventSetID && orm.ReleaseEventSet.forge({
              id: releaseEventSetID
            }).fetch({
              transacting: transacting,
              withRelated: ['releaseEvents']
            });
          case 21:
            oldReleaseEventSet = _context16.sent;
            releaseEvents = (0, _get2.default)(body, 'releaseEvents') || []; // if areaId is not present, set it to null.
            // otherwise it shows error while comparing old and new releaseEvent;
            if (releaseEvents[0]) {
              if ((0, _isNil2.default)(releaseEvents[0].areaId)) {
                releaseEvents[0].areaId = null;
              }
              if (releaseEvents[0].date === '') {
                releaseEvents[0].date = null;
              }
            }
            _context16.next = 26;
            return orm.func.releaseEvent.updateReleaseEventSet(orm, transacting, oldReleaseEventSet, releaseEvents);
          case 26:
            newReleaseEventSet = _context16.sent;
            newReleaseEventSetID = newReleaseEventSet && newReleaseEventSet.get('id');
            _context16.next = 30;
            return processAuthorCredit(orm, currentEntity, body, transacting);
          case 30:
            newAuthorCredit = _context16.sent;
            newAuthorCreditID = newAuthorCredit.authorCreditId;
            return _context16.abrupt("return", {
              authorCreditId: newAuthorCreditID,
              languageSetId: newLanguageSetID,
              publisherSetId: newPublisherSetID,
              releaseEventSetId: newReleaseEventSetID
            });
          case 33:
          case "end":
            return _context16.stop();
        }
      }
    }, _callee16);
  }));
  return _processEditionSets.apply(this, arguments);
}
function processWorkSets(_x41, _x42, _x43, _x44) {
  return _processWorkSets.apply(this, arguments);
}
function _processWorkSets() {
  _processWorkSets = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(orm, currentEntity, body, transacting) {
    var id, oldSet, languages;
    return _regenerator.default.wrap(function _callee17$(_context17) {
      while (1) {
        switch (_context17.prev = _context17.next) {
          case 0:
            id = (0, _get2.default)(currentEntity, ['languageSet', 'id']);
            _context17.next = 3;
            return id && orm.LanguageSet.forge({
              id: id
            }).fetch({
              transacting: transacting,
              withRelated: ['languages']
            });
          case 3:
            oldSet = _context17.sent;
            languages = (0, _get2.default)(body, 'languages') || [];
            return _context17.abrupt("return", commonUtils.makePromiseFromObject({
              languageSetId: orm.func.language.updateLanguageSet(orm, transacting, oldSet, languages.map(function (languageID) {
                return {
                  id: languageID
                };
              })).then(function (set) {
                return set && set.get('id');
              })
            }));
          case 6:
          case "end":
            return _context17.stop();
        }
      }
    }, _callee17);
  }));
  return _processWorkSets.apply(this, arguments);
}
function processEntitySets(_x45, _x46, _x47, _x48, _x49) {
  return _processEntitySets.apply(this, arguments);
}
function _processEntitySets() {
  _processEntitySets = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(orm, currentEntity, entityType, body, transacting) {
    var editionSets, authorCredit, workSets;
    return _regenerator.default.wrap(function _callee18$(_context18) {
      while (1) {
        switch (_context18.prev = _context18.next) {
          case 0:
            if (!(entityType === 'Edition')) {
              _context18.next = 5;
              break;
            }
            _context18.next = 3;
            return processEditionSets(orm, currentEntity, body, transacting);
          case 3:
            editionSets = _context18.sent;
            return _context18.abrupt("return", editionSets);
          case 5:
            if (!(entityType === 'EditionGroup')) {
              _context18.next = 10;
              break;
            }
            _context18.next = 8;
            return processAuthorCredit(orm, currentEntity, body, transacting);
          case 8:
            authorCredit = _context18.sent;
            return _context18.abrupt("return", authorCredit);
          case 10:
            if (!(entityType === 'Work')) {
              _context18.next = 15;
              break;
            }
            _context18.next = 13;
            return processWorkSets(orm, currentEntity, body, transacting);
          case 13:
            workSets = _context18.sent;
            return _context18.abrupt("return", workSets);
          case 15:
            return _context18.abrupt("return", null);
          case 16:
          case "end":
            return _context18.stop();
        }
      }
    }, _callee18);
  }));
  return _processEntitySets.apply(this, arguments);
}
function getNextAliasSet(_x50, _x51, _x52, _x53) {
  return _getNextAliasSet.apply(this, arguments);
}
function _getNextAliasSet() {
  _getNextAliasSet = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(orm, transacting, currentEntity, body) {
    var AliasSet, id, oldAliasSet;
    return _regenerator.default.wrap(function _callee19$(_context19) {
      while (1) {
        switch (_context19.prev = _context19.next) {
          case 0:
            AliasSet = orm.AliasSet;
            id = (0, _get2.default)(currentEntity, ['aliasSet', 'id']);
            _context19.next = 4;
            return id && new AliasSet({
              id: id
            }).fetch({
              require: false,
              transacting: transacting,
              withRelated: ['aliases']
            });
          case 4:
            oldAliasSet = _context19.sent;
            return _context19.abrupt("return", orm.func.alias.updateAliasSet(orm, transacting, oldAliasSet, oldAliasSet && oldAliasSet.get('defaultAliasId'), body.aliases || []));
          case 6:
          case "end":
            return _context19.stop();
        }
      }
    }, _callee19);
  }));
  return _getNextAliasSet.apply(this, arguments);
}
function getNextIdentifierSet(_x54, _x55, _x56, _x57) {
  return _getNextIdentifierSet.apply(this, arguments);
}
function _getNextIdentifierSet() {
  _getNextIdentifierSet = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20(orm, transacting, currentEntity, body) {
    var IdentifierSet, id, oldIdentifierSet;
    return _regenerator.default.wrap(function _callee20$(_context20) {
      while (1) {
        switch (_context20.prev = _context20.next) {
          case 0:
            IdentifierSet = orm.IdentifierSet;
            id = (0, _get2.default)(currentEntity, ['identifierSet', 'id']);
            _context20.next = 4;
            return id && new IdentifierSet({
              id: id
            }).fetch({
              require: false,
              transacting: transacting,
              withRelated: ['identifiers']
            });
          case 4:
            oldIdentifierSet = _context20.sent;
            return _context20.abrupt("return", orm.func.identifier.updateIdentifierSet(orm, transacting, oldIdentifierSet, body.identifiers || []));
          case 6:
          case "end":
            return _context20.stop();
        }
      }
    }, _callee20);
  }));
  return _getNextIdentifierSet.apply(this, arguments);
}
function getNextRelationshipAttributeSets(_x58, _x59, _x60) {
  return _getNextRelationshipAttributeSets.apply(this, arguments);
}
function _getNextRelationshipAttributeSets() {
  _getNextRelationshipAttributeSets = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(orm, transacting, body) {
    var RelationshipAttributeSet, relationships;
    return _regenerator.default.wrap(function _callee22$(_context22) {
      while (1) {
        switch (_context22.prev = _context22.next) {
          case 0:
            RelationshipAttributeSet = orm.RelationshipAttributeSet;
            _context22.next = 3;
            return Promise.all(body.relationships.map( /*#__PURE__*/function () {
              var _ref15 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(relationship) {
                var id, oldRelationshipAttributeSet, attributeSet, attributeSetId;
                return _regenerator.default.wrap(function _callee21$(_context21) {
                  while (1) {
                    switch (_context21.prev = _context21.next) {
                      case 0:
                        if (relationship.isAdded) {
                          _context21.next = 3;
                          break;
                        }
                        relationship.attributeSetId = (0, _get2.default)(relationship, ['attributeSetId'], null);
                        return _context21.abrupt("return", relationship);
                      case 3:
                        id = relationship.attributeSetId;
                        _context21.next = 6;
                        return id && new RelationshipAttributeSet({
                          id: id
                        }).fetch({
                          require: false,
                          transacting: transacting,
                          withRelated: ['relationshipAttributes.value']
                        });
                      case 6:
                        oldRelationshipAttributeSet = _context21.sent;
                        _context21.next = 9;
                        return orm.func.relationshipAttributes.updateRelationshipAttributeSet(orm, transacting, oldRelationshipAttributeSet, relationship.attributes || []);
                      case 9:
                        attributeSet = _context21.sent;
                        attributeSetId = attributeSet && attributeSet.get('id');
                        relationship.attributeSetId = attributeSetId;
                        delete relationship.attributes;
                        return _context21.abrupt("return", relationship);
                      case 14:
                      case "end":
                        return _context21.stop();
                    }
                  }
                }, _callee21);
              }));
              return function (_x105) {
                return _ref15.apply(this, arguments);
              };
            }()));
          case 3:
            relationships = _context22.sent;
            return _context22.abrupt("return", relationships);
          case 5:
          case "end":
            return _context22.stop();
        }
      }
    }, _callee22);
  }));
  return _getNextRelationshipAttributeSets.apply(this, arguments);
}
function getNextRelationshipSets(_x61, _x62, _x63, _x64) {
  return _getNextRelationshipSets.apply(this, arguments);
}
function _getNextRelationshipSets() {
  _getNextRelationshipSets = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee23(orm, transacting, currentEntity, body) {
    var RelationshipSet, relationships, id, oldRelationshipSet;
    return _regenerator.default.wrap(function _callee23$(_context23) {
      while (1) {
        switch (_context23.prev = _context23.next) {
          case 0:
            RelationshipSet = orm.RelationshipSet;
            _context23.next = 3;
            return getNextRelationshipAttributeSets(orm, transacting, body);
          case 3:
            relationships = _context23.sent;
            id = (0, _get2.default)(currentEntity, ['relationshipSet', 'id']);
            _context23.next = 7;
            return id && new RelationshipSet({
              id: id
            }).fetch({
              require: false,
              transacting: transacting,
              withRelated: ['relationships']
            });
          case 7:
            oldRelationshipSet = _context23.sent;
            return _context23.abrupt("return", orm.func.relationship.updateRelationshipSets(orm, transacting, oldRelationshipSet, relationships || []));
          case 9:
          case "end":
            return _context23.stop();
        }
      }
    }, _callee23);
  }));
  return _getNextRelationshipSets.apply(this, arguments);
}
function getNextAnnotation(_x65, _x66, _x67, _x68, _x69) {
  return _getNextAnnotation.apply(this, arguments);
}
function _getNextAnnotation() {
  _getNextAnnotation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee24(orm, transacting, currentEntity, body, revision) {
    var Annotation, id, oldAnnotation;
    return _regenerator.default.wrap(function _callee24$(_context24) {
      while (1) {
        switch (_context24.prev = _context24.next) {
          case 0:
            Annotation = orm.Annotation;
            id = (0, _get2.default)(currentEntity, ['annotation', 'id']);
            _context24.next = 4;
            return id && new Annotation({
              id: id
            }).fetch({
              require: false,
              transacting: transacting
            });
          case 4:
            oldAnnotation = _context24.sent;
            return _context24.abrupt("return", body.annotation ? orm.func.annotation.updateAnnotation(orm, transacting, oldAnnotation, body.annotation, revision) : new Promise(function (resolve) {
              return resolve(null);
            }));
          case 6:
          case "end":
            return _context24.stop();
        }
      }
    }, _callee24);
  }));
  return _getNextAnnotation.apply(this, arguments);
}
function getNextDisambiguation(_x70, _x71, _x72, _x73) {
  return _getNextDisambiguation.apply(this, arguments);
}
function _getNextDisambiguation() {
  _getNextDisambiguation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee25(orm, transacting, currentEntity, body) {
    var Disambiguation, id, oldDisambiguation;
    return _regenerator.default.wrap(function _callee25$(_context25) {
      while (1) {
        switch (_context25.prev = _context25.next) {
          case 0:
            Disambiguation = orm.Disambiguation;
            id = (0, _get2.default)(currentEntity, ['disambiguation', 'id']);
            _context25.next = 4;
            return id && new Disambiguation({
              id: id
            }).fetch({
              require: false,
              transacting: transacting
            });
          case 4:
            oldDisambiguation = _context25.sent;
            return _context25.abrupt("return", orm.func.disambiguation.updateDisambiguation(orm, transacting, oldDisambiguation, body.disambiguation));
          case 6:
          case "end":
            return _context25.stop();
        }
      }
    }, _callee25);
  }));
  return _getNextDisambiguation.apply(this, arguments);
}
function getChangedProps(_x74, _x75, _x76, _x77, _x78, _x79, _x80, _x81) {
  return _getChangedProps.apply(this, arguments);
}
function _getChangedProps() {
  _getChangedProps = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee26(orm, transacting, isNew, currentEntity, body, entityType, newRevision, derivedProps) {
    var aliasSetPromise, identSetPromise, annotationPromise, disambiguationPromise, entitySetIdsPromise, _yield$Promise$all3, _yield$Promise$all4, aliasSet, identSet, annotation, disambiguation, entitySetIds, propsToSet;
    return _regenerator.default.wrap(function _callee26$(_context26) {
      while (1) {
        switch (_context26.prev = _context26.next) {
          case 0:
            aliasSetPromise = getNextAliasSet(orm, transacting, currentEntity, body);
            identSetPromise = getNextIdentifierSet(orm, transacting, currentEntity, body);
            annotationPromise = getNextAnnotation(orm, transacting, currentEntity, body, newRevision);
            disambiguationPromise = getNextDisambiguation(orm, transacting, currentEntity, body);
            entitySetIdsPromise = processEntitySets(orm, currentEntity, entityType, body, transacting);
            _context26.next = 7;
            return Promise.all([aliasSetPromise, identSetPromise, annotationPromise, disambiguationPromise, entitySetIdsPromise]);
          case 7:
            _yield$Promise$all3 = _context26.sent;
            _yield$Promise$all4 = (0, _slicedToArray2.default)(_yield$Promise$all3, 5);
            aliasSet = _yield$Promise$all4[0];
            identSet = _yield$Promise$all4[1];
            annotation = _yield$Promise$all4[2];
            disambiguation = _yield$Promise$all4[3];
            entitySetIds = _yield$Promise$all4[4];
            propsToSet = _objectSpread(_objectSpread({
              aliasSetId: aliasSet && aliasSet.get('id'),
              annotationId: annotation && annotation.get('id'),
              disambiguationId: disambiguation && disambiguation.get('id'),
              identifierSetId: identSet && identSet.get('id')
            }, derivedProps), entitySetIds);
            if (!isNew) {
              _context26.next = 17;
              break;
            }
            return _context26.abrupt("return", propsToSet);
          case 17:
            return _context26.abrupt("return", (0, _reduce2.default)(propsToSet, function (result, value, key) {
              if (!(0, _isEqual2.default)(value, currentEntity[key]) &&
              // If both items are null or undefined, consider them equal (null !=== undefined)
              !((0, _isNil2.default)(value) && (0, _isNil2.default)(currentEntity[key]))) {
                result[key] = value;
              }
              return result;
            }, {}));
          case 18:
          case "end":
            return _context26.stop();
        }
      }
    }, _callee26);
  }));
  return _getChangedProps.apply(this, arguments);
}
function fetchEntitiesForRelationships(orm, transacting, currentEntity, relationshipSets) {
  var bbidsToFetch = (0, _without2.default)((0, _keys2.default)(relationshipSets), (0, _get2.default)(currentEntity, 'bbid'));
  return Promise.all(bbidsToFetch.map(function (bbid) {
    return getEntityByBBID(orm, transacting, bbid);
  }));
}

/**
 * @param  {any} orm -  The BookBrainz ORM
 * @param  {any} newEdition - The ORM model of the newly created Edition
 * @param  {any} transacting - The ORM transaction object
 * @description Edition Groups will be created automatically by the ORM if no EditionGroup BBID is set on a new Edition.
 * This method fetches and indexes (search) those potential new EditionGroups that may have been created automatically.
 */
function indexAutoCreatedEditionGroup(_x82, _x83, _x84) {
  return _indexAutoCreatedEditionGroup.apply(this, arguments);
}
function _indexAutoCreatedEditionGroup() {
  _indexAutoCreatedEditionGroup = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee27(orm, newEdition, transacting) {
    var EditionGroup, bbid, editionGroup;
    return _regenerator.default.wrap(function _callee27$(_context27) {
      while (1) {
        switch (_context27.prev = _context27.next) {
          case 0:
            EditionGroup = orm.EditionGroup;
            bbid = newEdition.get('editionGroupBbid');
            _context27.prev = 2;
            _context27.next = 5;
            return new EditionGroup({
              bbid: bbid
            }).fetch({
              require: true,
              transacting: transacting,
              withRelated: 'aliasSet.aliases'
            });
          case 5:
            editionGroup = _context27.sent;
            _context27.next = 8;
            return search.indexEntity(editionGroup);
          case 8:
            _context27.next = 13;
            break;
          case 10:
            _context27.prev = 10;
            _context27.t0 = _context27["catch"](2);
            _log.default.error('Could not reindex edition group after edition creation:', _context27.t0);
          case 13:
          case "end":
            return _context27.stop();
        }
      }
    }, _callee27, null, [[2, 10]]);
  }));
  return _indexAutoCreatedEditionGroup.apply(this, arguments);
}
function sanitizeBody(body) {
  var _iterator = _createForOfIteratorHelper(body.aliases),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var alias = _step.value;
      alias.name = commonUtils.sanitize(alias.name);
      alias.sortName = commonUtils.sanitize(alias.sortName);
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  body.disambiguation = commonUtils.sanitize(body.disambiguation);
  return body;
}
function processSingleEntity(_x85, _x86, _x87, _x88, _x89, _x90, _x91, _x92, _x93) {
  return _processSingleEntity.apply(this, arguments);
}
function _processSingleEntity() {
  _processSingleEntity = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee29(formBody, JSONEntity, reqSession, entityType, orm, editorJSON, derivedProps, isMergeOperation, transacting) {
    var Entity, Revision, body, currentEntity, _savedMainEntity$rela, isNew, newEntity, newEntityBBID, newRevision, relationshipSets, changedProps, mainEntity, otherEntities, allEntities, savedMainEntity, entityRelationships, authorsOfWork;
    return _regenerator.default.wrap(function _callee29$(_context29) {
      while (1) {
        switch (_context29.prev = _context29.next) {
          case 0:
            Entity = orm.Entity, Revision = orm.Revision;
            body = sanitizeBody(formBody);
            currentEntity = JSONEntity;
            _context29.prev = 3;
            // Determine if a new entity is being created
            isNew = !currentEntity; // sanitize namesection inputs
            body = sanitizeBody(body);
            if (!isNew) {
              _context29.next = 13;
              break;
            }
            _context29.next = 9;
            return new Entity({
              type: entityType
            }).save(null, {
              transacting: transacting
            });
          case 9:
            newEntity = _context29.sent;
            newEntityBBID = newEntity.get('bbid');
            body.relationships = (0, _map2.default)(body.relationships, function (_ref16) {
              var sourceBbid = _ref16.sourceBbid,
                targetBbid = _ref16.targetBbid,
                others = (0, _objectWithoutProperties2.default)(_ref16, _excluded);
              return _objectSpread({
                sourceBbid: sourceBbid || newEntityBBID,
                targetBbid: targetBbid || newEntityBBID
              }, others);
            });
            currentEntity = newEntity.toJSON();
          case 13:
            _context29.next = 15;
            return new Revision({
              authorId: editorJSON.id,
              isMerge: isMergeOperation
            }).save(null, {
              transacting: transacting
            });
          case 15:
            newRevision = _context29.sent;
            _context29.next = 18;
            return getNextRelationshipSets(orm, transacting, currentEntity, body);
          case 18:
            relationshipSets = _context29.sent;
            _context29.next = 21;
            return getChangedProps(orm, transacting, isNew, currentEntity, body, entityType, newRevision, derivedProps);
          case 21:
            changedProps = _context29.sent;
            if (!((0, _isEmpty2.default)(changedProps) && (0, _isEmpty2.default)(relationshipSets) && !isMergeOperation)) {
              _context29.next = 24;
              break;
            }
            throw new error.FormSubmissionError('No Updated Field');
          case 24:
            _context29.next = 26;
            return fetchOrCreateMainEntity(orm, transacting, isNew, currentEntity.bbid, entityType);
          case 26:
            mainEntity = _context29.sent;
            _context29.next = 29;
            return fetchEntitiesForRelationships(orm, transacting, currentEntity, relationshipSets);
          case 29:
            otherEntities = _context29.sent;
            otherEntities.forEach(function (entity) {
              entity.shouldInsert = false;
            });
            mainEntity.shouldInsert = isNew;
            (0, _forOwn2.default)(changedProps, function (value, key) {
              return mainEntity.set(key, value);
            });

            // Don't try to modify 'deleted' entities (those with no dataId)
            allEntities = [].concat((0, _toConsumableArray2.default)(otherEntities), [mainEntity]).filter(function (entity) {
              return entity.get('dataId') !== null;
            });
            if (!isMergeOperation) {
              _context29.next = 38;
              break;
            }
            _context29.next = 37;
            return processMergeOperation(orm, transacting, reqSession, mainEntity, allEntities, relationshipSets);
          case 37:
            allEntities = _context29.sent;
          case 38:
            (0, _forEach2.default)(allEntities, function (entityModel) {
              var bbid = entityModel.get('bbid');
              if ((0, _has2.default)(relationshipSets, bbid)) {
                entityModel.set('relationshipSetId',
                // Set to relationshipSet id or null if empty set
                relationshipSets[bbid] && relationshipSets[bbid].get('id'));
              }
            });
            _context29.next = 41;
            return saveEntitiesAndFinishRevision(orm, transacting, isNew, newRevision, mainEntity, allEntities, editorJSON.id, body.note);
          case 41:
            savedMainEntity = _context29.sent;
            _context29.next = 44;
            return savedMainEntity.refresh({
              transacting: transacting,
              withRelated: ['aliasSet.aliases', 'defaultAlias.language', 'relationshipSet.relationships.source', 'relationshipSet.relationships.target', 'relationshipSet.relationships.type', 'annotation']
            });
          case 44:
            if (!(isNew && savedMainEntity.get('type') === 'Edition')) {
              _context29.next = 47;
              break;
            }
            _context29.next = 47;
            return indexAutoCreatedEditionGroup(orm, savedMainEntity, transacting);
          case 47:
            entityRelationships = (_savedMainEntity$rela = savedMainEntity.related('relationshipSet')) === null || _savedMainEntity$rela === void 0 ? void 0 : _savedMainEntity$rela.related('relationships');
            if (!(savedMainEntity.get('type') === 'Work' && entityRelationships !== null && entityRelationships !== void 0 && entityRelationships.length)) {
              _context29.next = 53;
              break;
            }
            _context29.next = 51;
            return Promise.all(entityRelationships.toJSON().filter(
            // "Author wrote Work" relationship
            function (relation) {
              return relation.typeId === 8;
            }).map( /*#__PURE__*/function () {
              var _ref17 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee28(relationshipJSON) {
                var source, sourceEntity;
                return _regenerator.default.wrap(function _callee28$(_context28) {
                  while (1) {
                    switch (_context28.prev = _context28.next) {
                      case 0:
                        _context28.prev = 0;
                        source = relationshipJSON.source;
                        _context28.next = 4;
                        return commonUtils.getEntity(orm, source.bbid, source.type, {
                          require: false,
                          transacting: transacting
                        });
                      case 4:
                        sourceEntity = _context28.sent;
                        return _context28.abrupt("return", sourceEntity.name);
                      case 8:
                        _context28.prev = 8;
                        _context28.t0 = _context28["catch"](0);
                        _log.default.error(_context28.t0);
                      case 11:
                        return _context28.abrupt("return", null);
                      case 12:
                      case "end":
                        return _context28.stop();
                    }
                  }
                }, _callee28, null, [[0, 8]]);
              }));
              return function (_x106) {
                return _ref17.apply(this, arguments);
              };
            }()));
          case 51:
            authorsOfWork = _context29.sent;
            // Attach a work's authors for search indexing
            savedMainEntity.set('authors', authorsOfWork.filter(Boolean));
          case 53:
            return _context29.abrupt("return", savedMainEntity);
          case 56:
            _context29.prev = 56;
            _context29.t0 = _context29["catch"](3);
            _log.default.error(_context29.t0);
            throw _context29.t0;
          case 60:
          case "end":
            return _context29.stop();
        }
      }
    }, _callee29, null, [[3, 56]]);
  }));
  return _processSingleEntity.apply(this, arguments);
}
function handleCreateOrEditEntity(_x94, _x95, _x96, _x97, _x98) {
  return _handleCreateOrEditEntity.apply(this, arguments);
}
function _handleCreateOrEditEntity() {
  _handleCreateOrEditEntity = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee30(req, res, entityType, derivedProps, isMergeOperation) {
    var orm, editorJSON, bookshelf, savedEntityModel, entityJSON;
    return _regenerator.default.wrap(function _callee30$(_context30) {
      while (1) {
        switch (_context30.prev = _context30.next) {
          case 0:
            orm = req.app.locals.orm;
            editorJSON = req.user;
            bookshelf = orm.bookshelf;
            _context30.next = 5;
            return bookshelf.transaction(function (transacting) {
              return processSingleEntity(req.body, res.locals.entity, req.session, entityType, orm, editorJSON, derivedProps, isMergeOperation, transacting);
            });
          case 5:
            savedEntityModel = _context30.sent;
            entityJSON = savedEntityModel.toJSON();
            _context30.next = 9;
            return (0, _processUnifiedForm.processAchievement)(orm, editorJSON.id, entityJSON);
          case 9:
            _context30.next = 11;
            return search.indexEntity(savedEntityModel);
          case 11:
            return _context30.abrupt("return", res.status(200).send(entityJSON));
          case 12:
          case "end":
            return _context30.stop();
        }
      }
    }, _callee30);
  }));
  return _handleCreateOrEditEntity.apply(this, arguments);
}
function constructAliases(aliasEditor, nameSection) {
  var aliases = (0, _map2.default)(aliasEditor, function (_ref2, id) {
    var languageId = _ref2.language,
      name = _ref2.name,
      primary = _ref2.primary,
      sortName = _ref2.sortName;
    return {
      default: false,
      id: id,
      languageId: languageId,
      name: name,
      primary: primary,
      sortName: sortName
    };
  });
  return [{
    default: true,
    id: nameSection.id,
    languageId: nameSection.language,
    name: nameSection.name,
    primary: true,
    sortName: nameSection.sortName
  }].concat((0, _toConsumableArray2.default)(aliases));
}
function constructIdentifiers(identifierEditor) {
  return (0, _map2.default)(identifierEditor, function (_ref3, id) {
    var typeId = _ref3.type,
      value = _ref3.value;
    return {
      id: id,
      typeId: typeId,
      value: value
    };
  });
}
function constructRelationships(parentSection) {
  var childAttributeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'relationships';
  return (0, _map2.default)(parentSection[childAttributeName], function (_ref4) {
    var attributeSetId = _ref4.attributeSetId,
      rowID = _ref4.rowID,
      relationshipType = _ref4.relationshipType,
      sourceEntity = _ref4.sourceEntity,
      targetEntity = _ref4.targetEntity,
      attributes = _ref4.attributes,
      isRemoved = _ref4.isRemoved,
      isAdded = _ref4.isAdded;
    return {
      attributeSetId: attributeSetId,
      attributes: attributes,
      id: rowID,
      isAdded: isAdded,
      isRemoved: isRemoved,
      sourceBbid: (0, _get2.default)(sourceEntity, 'bbid'),
      targetBbid: (0, _get2.default)(targetEntity, 'bbid'),
      typeId: relationshipType.id
    };
  });
}

/**
 * Returns the index of the default alias if defined in the aliasSet.
 * If there is no defaultAliasId, return the first alias where default = true.
 * Returns null if there are no aliases in the set.
 * @param {Object} aliasSet - The entity's aliasSet returned by the ORM
 * @param {Object[]} aliasSet.aliases - The array of aliases contained in the set
 * @param {string} aliasSet.defaultAliasId - The id of the set's default alias
 * @returns {?number} The index of the default alias, or 0; returns null if 0 aliases in set
 */
function getDefaultAliasIndex(aliasSet) {
  if ((0, _isNil2.default)(aliasSet)) {
    return null;
  }
  var aliases = aliasSet.aliases,
    defaultAliasId = aliasSet.defaultAliasId;
  if (!aliases || !aliases.length) {
    return null;
  }
  var index;
  if (!(0, _isNil2.default)(defaultAliasId) && isFinite(defaultAliasId)) {
    var defaultAliasIdNumber = defaultAliasId;
    if ((0, _isString2.default)(defaultAliasId)) {
      defaultAliasIdNumber = Number(defaultAliasId);
    }
    index = aliases.findIndex(function (alias) {
      return alias.id === defaultAliasIdNumber;
    });
  } else {
    index = aliases.findIndex(function (alias) {
      return alias.default;
    });
  }
  return index > 0 ? index : 0;
}
function areaToOption(area) {
  if (!area) {
    return null;
  }
  var id = area.id;
  return {
    disambiguation: area.comment,
    id: id,
    text: area.name,
    type: 'area'
  };
}
function compareEntitiesByDate(a, b) {
  var aDate = (0, _get2.default)(a, 'releaseEventSet.releaseEvents[0].date', null);
  var bDate = (0, _get2.default)(b, 'releaseEventSet.releaseEvents[0].date', null);
  if ((0, _isNull2.default)(aDate)) {
    /*
     * return a positive value,
     * so that non-null dates always come before null dates.
     */
    return 1;
  }
  if ((0, _isNull2.default)(bDate)) {
    /*
     * return a negative value,
     * so that non-null dates always come before null dates.
     */
    return -1;
  }
  return new Date(aDate).getTime() - new Date(bDate).getTime();
}
function constructAuthorCredit(authorCreditEditor) {
  return (0, _map2.default)(authorCreditEditor, function (_ref5) {
    var author = _ref5.author,
      joinPhrase = _ref5.joinPhrase,
      name = _ref5.name;
    return {
      authorBBID: author.id,
      joinPhrase: joinPhrase,
      name: name
    };
  });
}
function displayPreview(req, res, next) {
  var baseUrl = "".concat(req.protocol, "://").concat(req.get('host'));
  var originalUrl = "".concat(baseUrl).concat(req.originalUrl);
  var sourceUrl = req.headers.origin !== 'null' ? req.headers.origin : '<Unknown Source>';
  if (sourceUrl === baseUrl) {
    return next();
  }
  var finalProps = {
    baseUrl: baseUrl,
    formBody: req.body,
    originalUrl: originalUrl,
    sourceUrl: sourceUrl
  };
  var props = (0, _props2.generateProps)(req, res, _objectSpread({
    alert: []
  }, finalProps));
  var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(props), /*#__PURE__*/React.createElement(_preview.default, propHelpers.extractPreviewProps(props))));
  return res.send((0, _target.default)({
    markup: markup,
    props: JSON.stringify(props),
    script: '/js/preview.js',
    title: 'Preview'
  }));
}
//# sourceMappingURL=entity.js.map