import { saveAs } from 'file-saver'; let characterCollections = []; Meteor.startup(() => { characterCollections = [ Actions, Attacks, Buffs, Classes, Conditions, CustomBuffs, Effects, Experiences, Features, Notes, Proficiencies, SpellLists, Spells, TemporaryHitPoints, Items, Containers, ]; }); dumpCharacter = function(charId){ let characterDump = {collections: {}}; characterDump.character = Characters.findOne(charId); characterCollections.forEach(c => { characterDump.collections[c._name] = c.find({charId}).fetch(); }); return characterDump; }; saveCharacterDump = function(charId){ let dump = dumpCharacter(charId); let textDump = JSON.stringify(dump, null, 2); let charName = dump.character.name; let blob = new Blob([textDump], {type: "application/json;charset=utf-8"}); saveAs(blob, `${charName}.JSON`); }; giveCharacterDumpNewIds = function(characterDump){ // Give the character a new Id const oldCharId = characterDump.character._id; const newCharId = Random.id(); characterDump.character._id = newCharId; let idMap = {[oldCharId]: newCharId}; // {oldId: newId} // Give all documents a new Id, and store the mapping from old to new for (let colName in characterDump.collections){ for (let doc of characterDump.collections[colName]){ let oldId = doc._id; let newId = Random.id(); doc._id = newId; idMap[oldId] = newId; } } // Replace all references to old Ids with new ones for (let colName in characterDump.collections){ for (let doc of characterDump.collections[colName]){ // Replace the character Id with the new one doc.charId = newCharId; // Replace the parent reference id with a new id if (doc.parent && doc.parent.id){ let newParentId = idMap[doc.parent.id]; if(!newParentId) throw `Can't find the mapping for id ${doc.parent.id}`; doc.parent.id = newParentId; } } } } restoreCharacter = function(characterDump){ Characters.direct.insert(characterDump.character); for (collectionName in characterDump.collections){ let collection = Meteor.Collection.get(collectionName); for (doc of characterDump.collections[collectionName]){ // delete problematic keys that shouldn't ever be available on insert delete doc.restoredAt; delete doc.restoredBy; // Insert the doc with no hooks collection.direct.insert(doc); } } }; Meteor.methods({ restoreCharacter(characterDump){ characterDump.character.name += " - Restored" characterDump.character.owner = Meteor.userId(); characterDump.character.readers = []; characterDump.character.writers = []; giveCharacterDumpNewIds(characterDump); restoreCharacter(characterDump); return characterDump.character }, });