"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createNewRelationshipAttributeSetWithItems = createNewRelationshipAttributeSetWithItems;
exports.createNewSetWithItems = createNewSetWithItems;
exports.getAddedItems = getAddedItems;
exports.getComparisonFunc = getComparisonFunc;
exports.getRemovedItems = getRemovedItems;
exports.getUnchangedItems = getUnchangedItems;
exports.removeItemsFromSet = void 0;
var _pick2 = _interopRequireDefault(require("lodash/pick"));
var _omit2 = _interopRequireDefault(require("lodash/omit"));
var _map2 = _interopRequireDefault(require("lodash/map"));
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
var _differenceWith2 = _interopRequireDefault(require("lodash/differenceWith"));
var _intersectionWith2 = _interopRequireDefault(require("lodash/intersectionWith"));
var _uniqWith2 = _interopRequireDefault(require("lodash/uniqWith"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
* Copyright (C) 2018 Ben Ockmore
*
* 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.
*/
/**
* Returns a function which compares two object provided to it using the
* comparison fields mentioned
* @param {Array<string>} compareFields - Comparison fields of two objects
* @returns {Function} - Returns a comparison function
*/
function getComparisonFunc(compareFields) {
/**
* @param {any} obj - Object for comparison
* @param {any} other - Object for comparison
* @returns {boolean} Boolean value denoting objects are equal on fields
*/
return function Cmp(obj, other) {
for (const field of compareFields) {
if (obj[field] !== other[field]) {
return false;
}
}
return true;
};
}
/**
* Get the intersection of two arrays of objects using a custom comparison
* function. The two arrays represent two versions of a single set - one array
* is the set before a particular change and the other is the same set after
* that change.
*
* @param {Array<Item>} oldSet - The old array to compare
* @param {Array<Item>} newSet - The new array to compare
* @param {Function} comparisonFunc - Function to compare items from the two
* arrays
*
* @returns {Array<Item>} - An array representing the intersection of the two
* arrays
*/
function getUnchangedItems(oldSet, newSet, comparisonFunc) {
return (0, _uniqWith2.default)((0, _intersectionWith2.default)(oldSet, newSet, comparisonFunc), comparisonFunc);
}
/**
* Get any items in the new version of the set that aren't present in the old
* version using a custom comparison function. The two arrays represent two
* versions of a single set - one array is the set before a particular change
* and the other is the same set after that change.
*
* @param {Array<Item>} oldSet - The old array to compare
* @param {Array<Item>} newSet - The new array to compare
* @param {Function} comparisonFunc - Function to compare items from the two
* arrays
*
* @returns {Array<Item>} - An array representing the difference of the two
* arrays
*/
function getAddedItems(oldSet, newSet, comparisonFunc) {
return (0, _uniqWith2.default)((0, _differenceWith2.default)(newSet, oldSet, comparisonFunc), comparisonFunc);
}
/**
* Get any items in the old version of the set that aren't present in the new
* version using a custom comparison function. The two arrays represent two
* versions of a single set - one array is the set before a particular change
* and the other is the same set after that change.
*
* @param {Array<Item>} oldSet - The old array to compare
* @param {Array<Item>} newSet - The new array to compare
* @param {Function} comparisonFunc - Function to compare items from the two
* arrays
*
* @returns {Array<Item>} - An array representing the difference of the two
* arrays
*/
function getRemovedItems(oldSet, newSet, comparisonFunc) {
return (0, _uniqWith2.default)((0, _differenceWith2.default)(oldSet, newSet, comparisonFunc), comparisonFunc);
}
const removeItemsFromSet = getRemovedItems;
// TODO: unchangedItems: ItemWithIdT, addedItems: ItemT
exports.removeItemsFromSet = removeItemsFromSet;
async function createNewSetWithItems(orm, transacting, SetModel, unchangedItems, addedItems, itemsAttribute, idAttribute = 'id') {
if (!itemsAttribute) {
throw Error('itemsAttribute must be set in createNewSetWithItems');
}
if ((0, _isEmpty2.default)(unchangedItems) && (0, _isEmpty2.default)(addedItems)) {
return null;
}
const newSet = await new SetModel().save(null, {
transacting
});
const newSetItemsCollection = await newSet.related(itemsAttribute).fetch({
transacting
});
const newSetItemsCollectionAttached = await newSetItemsCollection.attach((0, _map2.default)(unchangedItems, idAttribute), {
transacting
});
await Promise.all((0, _map2.default)(addedItems, ident => newSetItemsCollectionAttached.create((0, _omit2.default)(ident, idAttribute), {
transacting
})));
return newSet;
}
async function createNewRelationshipAttributeSetWithItems(orm, transacting, SetModel, unchangedItems, addedItems, itemsAttribute, idAttribute = 'id') {
const {
RelationshipAttributeTextValue
} = orm;
if (!itemsAttribute) {
throw Error('itemsAttribute must be set in createNewRelationshipAttributeSetWithItems');
}
if ((0, _isEmpty2.default)(unchangedItems) && (0, _isEmpty2.default)(addedItems)) {
return null;
}
const newSet = await new SetModel().save(null, {
transacting
});
const newSetItemsCollection = await newSet.related(itemsAttribute).fetch({
transacting
});
const newSetItemsCollectionAttached = await newSetItemsCollection.attach((0, _map2.default)(unchangedItems, idAttribute), {
transacting
});
await Promise.all((0, _map2.default)(addedItems, async ident => {
const model = await newSetItemsCollectionAttached.create((0, _pick2.default)(ident, 'attributeType'), {
transacting
});
const {
value
} = ident;
await new RelationshipAttributeTextValue({
attributeId: model.get('id'),
textValue: value.textValue
}).save(null, {
method: 'insert',
transacting
});
return model;
}));
return newSet;
}