Files
DiceCloud/app/imports/api/library/methods/copyLibraryNodeTo.js
2023-10-03 16:28:20 +02:00

90 lines
2.6 KiB
JavaScript

import { ValidatedMethod } from 'meteor/mdg:validated-method';
import SimpleSchema from 'simpl-schema';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { RefSchema } from '/imports/api/parenting/ChildSchema';
import LibraryNodes from '/imports/api/library/LibraryNodes';
import {
assertDocCopyPermission,
assertDocEditPermission
} from '/imports/api/sharing/sharingPermissions';
import {
setLineageOfDocs,
renewDocIds,
getFilter
} from '/imports/api/parenting/parentingFunctions';
import { rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
import { fetchDocByRef } from '/imports/api/parenting/parentingFunctions';
var snackbar;
if (Meteor.isClient) {
snackbar = require(
'/imports/client/ui/components/snackbars/SnackbarQueue'
).snackbar
}
const DUPLICATE_CHILDREN_LIMIT = 500;
const copyLibraryNodeTo = new ValidatedMethod({
name: 'libraryNodes.copyTo',
validate: new SimpleSchema({
_id: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
parent: {
type: RefSchema,
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 1,
timeInterval: 10000,
},
run({ _id, parent }) {
if (parent.collection !== 'libraryNodes' && parent.collection !== 'libraries') {
throw new Meteor.Error('Invalid destination',
'Library documents can only be copied to destinations inside other libraries'
);
}
const libraryNode = LibraryNodes.findOne(_id);
if (!libraryNode) throw new Meteor.Error('not-found', 'Library node was not found');
const parentDoc = fetchDocByRef(parent);
assertDocCopyPermission(libraryNode, this.userId);
assertDocEditPermission(parentDoc, this.userId);
let decendants = LibraryNodes.find({
...getFilter.descendants(libraryNode),
removed: { $ne: true },
}, {
limit: DUPLICATE_CHILDREN_LIMIT + 1,
sort: { order: 1 },
}).fetch();
if (decendants.length > DUPLICATE_CHILDREN_LIMIT) {
decendants.pop();
if (Meteor.isClient) {
snackbar({
text: `Only the first ${DUPLICATE_CHILDREN_LIMIT} children were duplicated`,
});
}
}
const nodes = [libraryNode, ...decendants];
// Give the docs new IDs without breaking internal references
renewDocIds({ docArray: nodes });
// Order the root node
libraryNode.left = Number.MAX_SAFE_INTEGER - 1;
libraryNode.right = Number.MAX_SAFE_INTEGER;
LibraryNodes.batchInsert(nodes);
// Tree structure changed by inserts, reorder the tree
rebuildNestedSets(LibraryNodes, parentDoc.root.id);
},
});
export default copyLibraryNodeTo;