diff --git a/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.test.js b/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.test.js index 5ca0f4ed..d7b33cc0 100644 --- a/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.test.js +++ b/app/imports/api/creature/creatureProperties/methods/getSlotFillFilter.test.js @@ -27,7 +27,7 @@ describe('Slot fill filter', function () { slot: { slotTags: ['tag1', 'tag2'] }, - libraryIds: ['libraryId1', 'libraryId2'] + libraryIds: ['libraryId1', 'libraryId2'], }); assert.deepStrictEqual(filter, { $or: [{ @@ -35,6 +35,7 @@ describe('Slot fill filter', function () { }], 'ancestors.id': { $in: ['libraryId1', 'libraryId2'] }, removed: { $ne: true }, + fillSlots: true, }); }); @@ -65,7 +66,7 @@ describe('Slot fill filter', function () { { operation: 'NOT', tags: ['tag7', 'tag8'] }, ], }, - libraryIds: ['libraryId1', 'libraryId2'] + libraryIds: ['libraryId1', 'libraryId2'], }); assert.deepStrictEqual(filter, { $or: [ @@ -77,6 +78,7 @@ describe('Slot fill filter', function () { ], 'ancestors.id': { $in: ['libraryId1', 'libraryId2'] }, removed: { $ne: true }, + fillSlots: true, }); }); diff --git a/app/imports/migrations/server/dbv2/dbv2.js b/app/imports/migrations/server/dbv2/dbv2.js index 2ba5fca3..770f1975 100644 --- a/app/imports/migrations/server/dbv2/dbv2.js +++ b/app/imports/migrations/server/dbv2/dbv2.js @@ -1,8 +1,11 @@ import { Migrations } from 'meteor/percolate:migrations'; import LibraryNodes from '/imports/api/library/LibraryNodes.js'; -import { union } from 'lodash'; +import { union, get } from 'lodash'; import Libraries from '/imports/api/library/Libraries.js'; import LibraryCollections from '/imports/api/library/LibraryCollections.js'; +import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; +import computedSchemas from '/imports/api/properties/computedPropertySchemasIndex.js'; +import applyFnToKey from '/imports/api/engine/computation/utility/applyFnToKey.js'; // Git version 2.0.52 // Database version 2 @@ -12,21 +15,25 @@ Migrations.add({ up() { console.log('migrating up library nodes 1 -> 2'); - const bulk = LibraryNodes.rawCollection().initializeUnorderedBulkOp(); - LibraryNodes.find({}).forEach(prop => migratePropUp(bulk, prop)); - bulk.execute(); + migrateCollection(LibraryNodes, migratePropUp); + migrateCollection(CreatureProperties, migratePropUp); countSubscribers(); }, down() { console.log('Migrating down library nodes 2 -> 1'); - const bulk = LibraryNodes.rawCollection().initializeUnorderedBulkOp(); - LibraryNodes.find({}).forEach(prop => migratePropDown(bulk, prop)); - bulk.execute(); + migrateCollection(LibraryNodes, migratePropDown); + migrateCollection(CreatureProperties, migratePropDown); }, }); +function migrateCollection(collection, migrateDoc) { + const bulk = collection.rawCollection().initializeUnorderedBulkOp(); + collection.find({}).forEach(doc => migrateDoc(bulk, doc)); + bulk.execute(); +} + export function migratePropUp(bulk, prop) { let update; // If the prop is a slot filler with an image, move it @@ -42,6 +49,7 @@ export function migratePropUp(bulk, prop) { update.$set.fillSlots = true; update.$set.searchable = true; } + update = dollarSignToTilde(prop, update); if (update) { bulk.find({ _id: prop._id }).updateOne(update); } @@ -91,3 +99,38 @@ function countSubscribers() { }); bulkLibCols.execute(); } + +const dollarSignRegex = /(\W)\$(\w+)/gi; +function dollarSignToTilde(prop, update) { + computedSchemas[prop.type]?.inlineCalculationFields()?.forEach(calcKey => { + applyFnToKey(prop, calcKey, (prop, key) => { + const inlineCalcObj = get(prop, key); + const string = inlineCalcObj?.text; + if (!string) return; + const newString = string.replace(dollarSignRegex, '$1~$2'); + if (string !== newString) { + // If changed + update = update || { $set: {} }; + if (!update.$unset) update.$unset = {}; + update.$unset[key + '.hash'] = 1; // zero the hash so it re-parses the calculation + update.$set[key + '.text'] = newString + } + }); + }); + computedSchemas[prop.type]?.computedFields()?.forEach(calcKey => { + applyFnToKey(prop, calcKey, (prop, key) => { + const inlineCalcObj = get(prop, key); + const string = inlineCalcObj?.calculation; + if (!string) return; + const newString = string.replace(dollarSignRegex, '$1~$2'); + if (string !== newString) { + // If changed + update = update || { $set: {} }; + if (!update.$unset) update.$unset = {}; + update.$unset[key + '.hash'] = 1; // remove the hash so it re-parses the calculation + update.$set[key + '.calculation'] = newString + } + }); + }); + return update; +} diff --git a/app/imports/migrations/server/dbv2/dbv2.test.js b/app/imports/migrations/server/dbv2/dbv2.test.js index 0f006bf4..642f4c2f 100644 --- a/app/imports/migrations/server/dbv2/dbv2.test.js +++ b/app/imports/migrations/server/dbv2/dbv2.test.js @@ -11,7 +11,12 @@ const exampleAttack = { 'attributesConsumed': [] }, 'attackRoll': { - calculation: 'dexterity.modifier + proficiencyBonus + 2 - hp.total + hp.value', + calculation: 'dexterity.modifier + proficiency$Bonus + 2 - hp.total + hp.value + $dollarSign', + hash: 1234567, + }, + 'summary': { + text: 'What if we {$had} two {$dollarSigns?} ', + hash: 123456, }, 'type': 'action', 'name': 'Claws', @@ -38,10 +43,16 @@ const exampleAttack = { const expectedAttackUpdate = { $set: { + 'attackRoll.calculation': 'dexterity.modifier + proficiency$Bonus + 2 - hp.total + hp.value + ~dollarSign', 'libraryTags': ['attack', 'magical', 'very cool'], 'fillSlots': true, 'searchable': true, - } + 'summary.text': 'What if we {~had} two {~dollarSigns?} ', + }, + $unset: { + 'attackRoll.hash': 1, + 'summary.hash': 1, + }, }; const emptyFolderExample = {