Moved a lot of functionality to mixins, improved parenting
This commit is contained in:
@@ -8,6 +8,7 @@ import Creatures from "/imports/api/creature/Creatures.js";
|
|||||||
import Attributes from "/imports/api/creature/properties/Attributes.js";
|
import Attributes from "/imports/api/creature/properties/Attributes.js";
|
||||||
import Skills from "/imports/api/creature/properties/Skills.js";
|
import Skills from "/imports/api/creature/properties/Skills.js";
|
||||||
import Effects from "/imports/api/creature/properties/Effects.js";
|
import Effects from "/imports/api/creature/properties/Effects.js";
|
||||||
|
import Proficiencies from "/imports/api/creature/properties/Proficiencies.js";
|
||||||
import DamageMultipliers from "/imports/api/creature/properties/DamageMultipliers.js";
|
import DamageMultipliers from "/imports/api/creature/properties/DamageMultipliers.js";
|
||||||
import Classes from "/imports/api/creature/properties/Classes.js";
|
import Classes from "/imports/api/creature/properties/Classes.js";
|
||||||
import * as math from 'mathjs';
|
import * as math from 'mathjs';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
|
|
||||||
function getCreature(creature, fields){
|
function getCreature(creature, fields){
|
||||||
if (typeof creature === 'string'){
|
if (typeof creature === 'string'){
|
||||||
return Creatures.findOne(id, {fields});
|
return Creatures.findOne(creature, {fields});
|
||||||
} else {
|
} else {
|
||||||
return creature;
|
return creature;
|
||||||
}
|
}
|
||||||
@@ -20,52 +20,9 @@ export function assertOwnership(creature, userId){
|
|||||||
export function assertEditPermission(creature, userId) {
|
export function assertEditPermission(creature, userId) {
|
||||||
creature = getCreature(creature, {owner: 1, writers: 1});
|
creature = getCreature(creature, {owner: 1, writers: 1});
|
||||||
editPermission(creature, userId);
|
editPermission(creature, userId);
|
||||||
};
|
}
|
||||||
|
|
||||||
export function assertViewPermission(creature, userId) {
|
export function assertViewPermission(creature, userId) {
|
||||||
creature = getCreature(creature, {owner: 1, writers: 1, public: 1});
|
creature = getCreature(creature, {owner: 1, writers: 1, public: 1});
|
||||||
viewPermission(creature, userId);
|
viewPermission(creature, userId);
|
||||||
};
|
}
|
||||||
|
|
||||||
// Checks if the method has permission to run on the document. If the document
|
|
||||||
// has a charId, that creature is checked, otherwise if it has an _id and the
|
|
||||||
// collection is defined in the method options, that document is fetched to
|
|
||||||
// determine its charId, otherwise a getCharId method can be defined to perform
|
|
||||||
// a special search for the required creature
|
|
||||||
export function creaturePermissionMixin(methodOptions){
|
|
||||||
let assertPermission;
|
|
||||||
if (methodOptions.permission === 'owner'){
|
|
||||||
assertPermission = assertOwnership;
|
|
||||||
} else if (methodOptions.permission === 'edit'){
|
|
||||||
assertPermission = assertEditPermission;
|
|
||||||
} else if (methodOptions.permission === 'view'){
|
|
||||||
assertPermission = assertViewPermission;
|
|
||||||
} else {
|
|
||||||
throw "`permission` missing in method options";
|
|
||||||
}
|
|
||||||
|
|
||||||
let getCharId;
|
|
||||||
if (methodOptions.getCharId){
|
|
||||||
getCharId = methodOptions.getCharId
|
|
||||||
} else if (methodOptions.collection) {
|
|
||||||
getCharId = function({_id}){
|
|
||||||
methodOptions.collection.findOne(_id, {
|
|
||||||
fields: {charId: 1}
|
|
||||||
}).charId;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
getCharId = function(){
|
|
||||||
throw "`getCharId` or `collection` missing in method options," +
|
|
||||||
" or {charId} missing in call";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let runFunc = methodOptions.run;
|
|
||||||
methodOptions.run = function(doc, ...rest){
|
|
||||||
// Store the charId on the doc for other mixins if it had to be fetched
|
|
||||||
doc.charId = doc.charId || getCharId.apply(this, arguments);
|
|
||||||
assertPermission(charId, this.userId)
|
|
||||||
return runFunc.call(this, doc, ...rest);
|
|
||||||
};
|
|
||||||
return methodOptions;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
|||||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
|
|
||||||
let Actions = new Mongo.Collection('actions');
|
let Actions = new Mongo.Collection('actions');
|
||||||
@@ -88,9 +88,9 @@ const insertAction = new ValidatedMethod({
|
|||||||
name: 'Actions.methods.insert',
|
name: 'Actions.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Actions,
|
collection: Actions,
|
||||||
|
|||||||
@@ -4,13 +4,19 @@ import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import schema from '/imports/api/schema.js';
|
import schema from '/imports/api/schema.js';
|
||||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||||
|
import getModifierFields from '/imports/api/getModifierFields.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import {
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
setDocAncestryMixin,
|
||||||
|
ensureAncestryContainsCharIdMixin
|
||||||
|
} from '/imports/api/parenting/parenting.js';
|
||||||
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
import updateSchemaMixin from '/imports/api/mixins/updateSchemaMixin.js';
|
||||||
|
import propagateInheritanceUpdateMixin from '/imports/api/mixins/propagateInheritanceUpdateMixin.js';
|
||||||
|
|
||||||
let Attributes = new Mongo.Collection('attributes');
|
let Attributes = new Mongo.Collection('attributes');
|
||||||
|
|
||||||
@@ -73,6 +79,7 @@ let AttributeSchema = schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
AttributeSchema.extend(ColorSchema);
|
AttributeSchema.extend(ColorSchema);
|
||||||
|
AttributeSchema.extend(PropertySchema);
|
||||||
|
|
||||||
const ComputedAttributeSchema = schema({
|
const ComputedAttributeSchema = schema({
|
||||||
// The computed value of the attribute
|
// The computed value of the attribute
|
||||||
@@ -88,17 +95,16 @@ const ComputedAttributeSchema = schema({
|
|||||||
}).extend(AttributeSchema);
|
}).extend(AttributeSchema);
|
||||||
|
|
||||||
Attributes.attachSchema(ComputedAttributeSchema);
|
Attributes.attachSchema(ComputedAttributeSchema);
|
||||||
Attributes.attachSchema(PropertySchema);
|
|
||||||
Attributes.attachSchema(ChildSchema);
|
Attributes.attachSchema(ChildSchema);
|
||||||
|
|
||||||
const insertAttribute = new ValidatedMethod({
|
const insertAttribute = new ValidatedMethod({
|
||||||
name: 'Attributes.methods.insert',
|
name: 'Attributes.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
recomputeCreatureMixin,
|
recomputeCreatureMixin,
|
||||||
|
creaturePermissionMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Attributes,
|
collection: Attributes,
|
||||||
@@ -112,31 +118,32 @@ const insertAttribute = new ValidatedMethod({
|
|||||||
const updateAttribute = new ValidatedMethod({
|
const updateAttribute = new ValidatedMethod({
|
||||||
name: 'Attributes.methods.update',
|
name: 'Attributes.methods.update',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
|
||||||
recomputeCreatureMixin,
|
recomputeCreatureMixin,
|
||||||
simpleSchemaMixin,
|
propagateInheritanceUpdateMixin,
|
||||||
|
updateSchemaMixin,
|
||||||
|
creaturePermissionMixin,
|
||||||
],
|
],
|
||||||
collection: Attributes,
|
collection: Attributes,
|
||||||
permission: 'edit',
|
permission: 'edit',
|
||||||
schema: new SimpleSchema({
|
updateSchema: AttributeSchema,
|
||||||
_id: SimpleSchema.RegEx.Id,
|
|
||||||
update: AttributeSchema.omit('adjustment', 'name'),
|
|
||||||
}),
|
|
||||||
skipRecompute({update}){
|
skipRecompute({update}){
|
||||||
return !('variableName' in update) &&
|
let fields = getModifierFields(update);
|
||||||
!('type' in update) &&
|
return !fields.hasAny([
|
||||||
!('baseValue' in update)
|
'variableName',
|
||||||
|
'type',
|
||||||
|
'baseValue',
|
||||||
|
]);
|
||||||
},
|
},
|
||||||
run({_id, update}) {
|
run({_id, update}) {
|
||||||
return Attributes.update(_id, {$set: update});
|
return Attributes.update(_id, update);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const adjustAttribute = new ValidatedMethod({
|
const adjustAttribute = new ValidatedMethod({
|
||||||
name: 'Attributes.methods.adjust',
|
name: 'Attributes.methods.adjust',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
|
creaturePermissionMixin,
|
||||||
],
|
],
|
||||||
collection: Attributes,
|
collection: Attributes,
|
||||||
permission: 'edit',
|
permission: 'edit',
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
|||||||
import { EffectSchema } from '/imports/api/creature/properties/Effects.js';
|
import { EffectSchema } from '/imports/api/creature/properties/Effects.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Buffs = new Mongo.Collection('buffs');
|
let Buffs = new Mongo.Collection('buffs');
|
||||||
|
|
||||||
@@ -83,9 +83,9 @@ const insertBuff = new ValidatedMethod({
|
|||||||
name: 'Buffs.methods.insert',
|
name: 'Buffs.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Buffs,
|
collection: Buffs,
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
|||||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let ClassLevels = new Mongo.Collection("classLevels");
|
let ClassLevels = new Mongo.Collection("classLevels");
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ const insertClassLevel = new ValidatedMethod({
|
|||||||
name: 'ClassLevels.methods.insert',
|
name: 'ClassLevels.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: ClassLevels,
|
collection: ClassLevels,
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
|||||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Classes = new Mongo.Collection("classes");
|
let Classes = new Mongo.Collection("classes");
|
||||||
|
|
||||||
@@ -35,9 +35,9 @@ const insertClass = new ValidatedMethod({
|
|||||||
name: 'Classes.methods.insert',
|
name: 'Classes.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Classes,
|
collection: Classes,
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
|||||||
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let DamageMultipliers = new Mongo.Collection("damageMultipliers");
|
let DamageMultipliers = new Mongo.Collection("damageMultipliers");
|
||||||
|
|
||||||
@@ -43,10 +43,10 @@ const insertDamageMultiplier = new ValidatedMethod({
|
|||||||
name: 'DamageMultipliers.methods.insert',
|
name: 'DamageMultipliers.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
recomputeCreatureMixin,
|
recomputeCreatureMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: DamageMultipliers,
|
collection: DamageMultipliers,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Effects = new Mongo.Collection('effects');
|
let Effects = new Mongo.Collection('effects');
|
||||||
|
|
||||||
@@ -64,10 +64,10 @@ const insertEffect = new ValidatedMethod({
|
|||||||
name: 'Effects.methods.insert',
|
name: 'Effects.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
recomputeCreatureMixin,
|
recomputeCreatureMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Effects,
|
collection: Effects,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import recomputeCreatureXP from '/imports/api/creature/creatureComputation.js';
|
import recomputeCreatureXP from '/imports/api/creature/creatureComputation.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Experiences = new Mongo.Collection("experience");
|
let Experiences = new Mongo.Collection("experience");
|
||||||
|
|
||||||
@@ -53,10 +53,10 @@ const insertExperience = new ValidatedMethod({
|
|||||||
name: 'Experiences.methods.insert',
|
name: 'Experiences.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
recomputeCreatureMixin,
|
recomputeCreatureMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Experiences,
|
collection: Experiences,
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import SimpleSchema from 'simpl-schema';
|
|||||||
import schema from '/imports/api/schema.js';
|
import schema from '/imports/api/schema.js';
|
||||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||||
import { recomputeCreatureById } from '/imports/api/creature/creatureComputation.js'
|
import { recomputeCreatureById } from '/imports/api/creature/creatureComputation.js'
|
||||||
import { getHighestOrder } from '/imports/api/order.js';
|
import { getHighestOrder } from '/imports/api/order/order.js';
|
||||||
import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Features = new Mongo.Collection('features');
|
let Features = new Mongo.Collection('features');
|
||||||
|
|
||||||
@@ -41,9 +41,9 @@ const insertFeature = new ValidatedMethod({
|
|||||||
name: 'Features.methods.insert',
|
name: 'Features.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Features,
|
collection: Features,
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Folders = new Mongo.Collection('folders');
|
let Folders = new Mongo.Collection('folders');
|
||||||
|
|
||||||
@@ -26,9 +26,9 @@ const insertFolder = new ValidatedMethod({
|
|||||||
name: 'Folders.methods.insert',
|
name: 'Folders.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Folders,
|
collection: Folders,
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
|||||||
import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Notes = new Mongo.Collection("notes");
|
let Notes = new Mongo.Collection("notes");
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ const insertNote = new ValidatedMethod({
|
|||||||
name: 'Notes.methods.insert',
|
name: 'Notes.methods.insert',
|
||||||
mixins: [
|
mixins: [
|
||||||
creaturePermissionMixin,
|
creaturePermissionMixin,
|
||||||
setDocToLastMixin,
|
|
||||||
setDocAncestryMixin,
|
setDocAncestryMixin,
|
||||||
ensureAncestryContainsCharIdMixin,
|
ensureAncestryContainsCharIdMixin,
|
||||||
|
setDocToLastMixin,
|
||||||
simpleSchemaMixin,
|
simpleSchemaMixin,
|
||||||
],
|
],
|
||||||
collection: Notes,
|
collection: Notes,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Proficiencies = new Mongo.Collection("proficiencies");
|
let Proficiencies = new Mongo.Collection("proficiencies");
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import AdjustmentSchema from '/imports/api/creature/subSchemas/AdjustmentSchema.
|
|||||||
import StoredBuffSchema from '/imports/api/creature/properties/Buffs.js';
|
import StoredBuffSchema from '/imports/api/creature/properties/Buffs.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Rolls = new Mongo.Collection('rolls');
|
let Rolls = new Mongo.Collection('rolls');
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
|||||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import recomputeCreatureMixin from '/imports/api/creature/recomputeCreatureMixin.js';
|
import recomputeCreatureMixin from '/imports/api/mixins/recomputeCreatureMixin.js';
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let Skills = new Mongo.Collection("skills");
|
let Skills = new Mongo.Collection("skills");
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
let SpellLists = new Mongo.Collection("spellLists");
|
let SpellLists = new Mongo.Collection("spellLists");
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import PropertySchema from '/imports/api/creature/subSchemas/PropertySchema.js';
|
|||||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { creaturePermissionMixin } from '/imports/api/creature/creaturePermissions.js';
|
import creaturePermissionMixin from '/imports/api/mixins/creaturePermissionMixin.js';
|
||||||
import { setDocToLastMixin } from '/imports/api/order.js';
|
import { setDocToLastMixin } from '/imports/api/mixins/setDocToLastMixin.js';
|
||||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||||
import simpleSchemaMixin from '/imports/api/simpleSchemaMixin.js';
|
import simpleSchemaMixin from '/imports/api/mixins/simpleSchemaMixin.js';
|
||||||
|
|
||||||
const magicSchools = [
|
const magicSchools = [
|
||||||
'Abjuration',
|
'Abjuration',
|
||||||
|
|||||||
28
app/imports/api/getModifierFields.js
Normal file
28
app/imports/api/getModifierFields.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import MONGO_OPERATORS from '/imports/constants/MONGO_OPERATORS.js';
|
||||||
|
|
||||||
|
const hasAny = function(values){
|
||||||
|
for (let value of values){
|
||||||
|
if (this.has(value)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns a Set of fields the modifier changes
|
||||||
|
// The set has been extended with the "hasAny" function
|
||||||
|
export default function getModifierFields (modifier) {
|
||||||
|
let fields = new Set();
|
||||||
|
|
||||||
|
for (let operator of MONGO_OPERATORS){
|
||||||
|
if (modifier[operator]) for (let field in modifier[operator]){
|
||||||
|
const indexOfDot = field.indexOf('.');
|
||||||
|
if (indexOfDot !== -1) {
|
||||||
|
field = field.substring(0, indexOfDot);
|
||||||
|
}
|
||||||
|
fields.add(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields.hasAny = hasAny;
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
52
app/imports/api/mixins/creaturePermissionMixin.js
Normal file
52
app/imports/api/mixins/creaturePermissionMixin.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {
|
||||||
|
assertEditPermission,
|
||||||
|
assertViewPermission,
|
||||||
|
assertOwnership,
|
||||||
|
} from '/imports/api/creature/creaturePermissions.js';
|
||||||
|
|
||||||
|
// Checks if the method has permission to run on the document. If the document
|
||||||
|
// has a charId, that creature is checked, otherwise if it has an _id and the
|
||||||
|
// collection is defined in the method options, that document is fetched to
|
||||||
|
// determine its charId, otherwise a getCharId method can be defined to perform
|
||||||
|
// a special search for the required creature
|
||||||
|
//
|
||||||
|
// Because this mixin injects the charId into argument objects that don't
|
||||||
|
// already contain it, it should always come last in the mixin list, so that it
|
||||||
|
// the outermost wrapper of the run function
|
||||||
|
export default function creaturePermissionMixin(methodOptions){
|
||||||
|
let assertPermission;
|
||||||
|
if (methodOptions.permission === 'owner'){
|
||||||
|
assertPermission = assertOwnership;
|
||||||
|
} else if (methodOptions.permission === 'edit'){
|
||||||
|
assertPermission = assertEditPermission;
|
||||||
|
} else if (methodOptions.permission === 'view'){
|
||||||
|
assertPermission = assertViewPermission;
|
||||||
|
} else {
|
||||||
|
throw "`permission` missing in method options";
|
||||||
|
}
|
||||||
|
|
||||||
|
let getCharId;
|
||||||
|
if (methodOptions.getCharId){
|
||||||
|
getCharId = methodOptions.getCharId;
|
||||||
|
} else if (methodOptions.collection) {
|
||||||
|
getCharId = function({_id}){
|
||||||
|
return methodOptions.collection.findOne(_id, {
|
||||||
|
fields: {charId: 1}
|
||||||
|
}).charId;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
getCharId = function(){
|
||||||
|
throw "`getCharId` or `collection` missing in method options," +
|
||||||
|
" or {charId} missing in call";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let runFunc = methodOptions.run;
|
||||||
|
methodOptions.run = function(doc, ...rest){
|
||||||
|
// Store the charId on the doc for other mixins if it had to be fetched
|
||||||
|
doc.charId = doc.charId || getCharId.apply(this, arguments);
|
||||||
|
assertPermission(doc.charId, this.userId);
|
||||||
|
return runFunc.call(this, doc, ...rest);
|
||||||
|
};
|
||||||
|
return methodOptions;
|
||||||
|
}
|
||||||
59
app/imports/api/mixins/propagateInheritanceUpdateMixin.js
Normal file
59
app/imports/api/mixins/propagateInheritanceUpdateMixin.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
updateChildren,
|
||||||
|
updateDecendents,
|
||||||
|
} from '/imports/api/parenting/parenting.js';
|
||||||
|
import { inheritedFields } from '/imports/api/parenting/ChildSchema.js';
|
||||||
|
import MONGO_OPERATORS from '/imports/constants/MONGO_OPERATORS.js';
|
||||||
|
|
||||||
|
// This mixin can be safely applied to all update methods which are validated
|
||||||
|
// with the updateSchemaMixin. It will propagate updates to fields which
|
||||||
|
// are inherited and normalised on the parent or ancestor docs
|
||||||
|
// It should have neglible performance impact for updates that aren't inherited
|
||||||
|
function propagateInheritanceUpdate({_id, update}){
|
||||||
|
let childModifier = {};
|
||||||
|
let decendentModifier = {};
|
||||||
|
// For each operator
|
||||||
|
for (let operator of MONGO_OPERATORS){
|
||||||
|
// If the operator is in the update, for each field
|
||||||
|
if (update[operator]) for (let field in update[operator]){
|
||||||
|
// Get the top level field that was actually modified
|
||||||
|
const indexOfDot = field.indexOf('.');
|
||||||
|
let modifiedField;
|
||||||
|
if (indexOfDot !== -1) {
|
||||||
|
modifiedField = field.substring(0, indexOfDot);
|
||||||
|
} else {
|
||||||
|
modifiedField = field;
|
||||||
|
}
|
||||||
|
// If that field is updated and inherited
|
||||||
|
if (inheritedFields.has(modifiedField)){
|
||||||
|
// Perform the same update on the decendents
|
||||||
|
if (!childModifier[operator]) childModifier[operator] = {};
|
||||||
|
if (!decendentModifier[operator]) decendentModifier[operator] = {};
|
||||||
|
childModifier[operator][`parent.${field}`] = update[operator][field];
|
||||||
|
decendentModifier[operator][`ancestors.$.${field}`] = update[operator][field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the parent object of its children
|
||||||
|
updateChildren({
|
||||||
|
parentId: _id,
|
||||||
|
modifier: childModifier,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the ancestors object of its decendents
|
||||||
|
updateDecendents({
|
||||||
|
ancestorId: _id,
|
||||||
|
modifier: decendentModifier,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function propagateInheritanceUpdateMixin(methodOptions){
|
||||||
|
let runFunc = methodOptions.run;
|
||||||
|
methodOptions.run = function({_id, update}){
|
||||||
|
const result = runFunc.apply(this, arguments);
|
||||||
|
propagateInheritanceUpdate({_id, update});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
return methodOptions;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { recomputeCreatureById } from '/imports/api/creature/creatureComputation.js';
|
||||||
|
|
||||||
export default function recomputeCreatureMixin(methodOptions){
|
export default function recomputeCreatureMixin(methodOptions){
|
||||||
let runFunc = methodOptions.run;
|
let runFunc = methodOptions.run;
|
||||||
methodOptions.run = function({charId}){
|
methodOptions.run = function({charId}){
|
||||||
@@ -5,9 +7,11 @@ export default function recomputeCreatureMixin(methodOptions){
|
|||||||
if (
|
if (
|
||||||
methodOptions.skipRecompute &&
|
methodOptions.skipRecompute &&
|
||||||
methodOptions.skipRecompute.apply(this, arguments)
|
methodOptions.skipRecompute.apply(this, arguments)
|
||||||
) return result;
|
) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
recomputeCreatureById(charId);
|
recomputeCreatureById(charId);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
return methodOptions;
|
return methodOptions;
|
||||||
};
|
}
|
||||||
27
app/imports/api/mixins/setDocToLastMixin.js
Normal file
27
app/imports/api/mixins/setDocToLastMixin.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
import { setDocToLastOrder } from '/imports/api/order/order.js';
|
||||||
|
|
||||||
|
export function setDocToLastMixin(methodOptions){
|
||||||
|
// Make sure the doc has a charId
|
||||||
|
// This mixin should come before simpleSchemaMixin so that it can extend the
|
||||||
|
// schema before it is turned into a validate function
|
||||||
|
if (methodOptions.validate){
|
||||||
|
throw new Meteor.Error(`setDocToLastMixin should come before simpleSchemaMixin`);
|
||||||
|
}
|
||||||
|
methodOptions.schema.extend({
|
||||||
|
charId: {
|
||||||
|
type: String,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let collection = methodOptions.collection;
|
||||||
|
if (!collection){
|
||||||
|
throw new Meteor.Error("`collection` required in method options for setDocToLastMixin");
|
||||||
|
}
|
||||||
|
let runFunc = methodOptions.run;
|
||||||
|
methodOptions.run = function(doc){
|
||||||
|
setDocToLastOrder({collection, doc});
|
||||||
|
return runFunc.apply(this, arguments);
|
||||||
|
};
|
||||||
|
return methodOptions;
|
||||||
|
}
|
||||||
61
app/imports/api/mixins/updateSchemaMixin.js
Normal file
61
app/imports/api/mixins/updateSchemaMixin.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
const argumentSchema = new SimpleSchema({
|
||||||
|
_id: SimpleSchema.RegEx.Id,
|
||||||
|
update: {
|
||||||
|
type: Object,
|
||||||
|
blackbox: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modified simpleSchemaMixin
|
||||||
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
|
||||||
|
export default function updateSchemaMixin(methodOptions) {
|
||||||
|
// If the user didn't give us a schema and they did give us a validate, assume
|
||||||
|
// that they are choosing to use the validate way of doing things in this call.
|
||||||
|
// If they've built a wrapper around ValidateMethod that includes this mixin
|
||||||
|
// all the time, this could happen semi-"intentionally". There may be times they
|
||||||
|
// just don't want to use a schema and have specified a "validate" option. So
|
||||||
|
// returning the unchanged options instead of an error seems proper.
|
||||||
|
if ((
|
||||||
|
typeof methodOptions.updateSchema === 'undefined' &&
|
||||||
|
typeof methodOptions.validate !== 'undefined'
|
||||||
|
) || (
|
||||||
|
typeof methodOptions.updateSchema !== 'undefined' &&
|
||||||
|
methodOptions.updateSchema === null &&
|
||||||
|
typeof methodOptions.validate !== 'undefined' &&
|
||||||
|
methodOptions.validate !== null
|
||||||
|
)) {
|
||||||
|
return methodOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If they truly gave us both... that just doesn't seem proper.
|
||||||
|
if (methodOptions.validate && methodOptions.validate !== null) {
|
||||||
|
throw new Meteor.Error(
|
||||||
|
'simpleSchemaMixin.options',
|
||||||
|
'"schema" and "validate" options cannot be used together');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that setting them both null will make it through, defaulting to the
|
||||||
|
// schema = null behavior (enforce no args) instead of the validate = null
|
||||||
|
// behavior (do no validation).
|
||||||
|
|
||||||
|
// Apply default validator options if none are provided
|
||||||
|
methodOptions.schemaValidatorOptions =
|
||||||
|
methodOptions.schemaValidatorOptions ||
|
||||||
|
{ clean: true, modifier: true };
|
||||||
|
|
||||||
|
// Make the update schema a SimpleSchema, if it isn't already
|
||||||
|
let updateSchema;
|
||||||
|
if (methodOptions.updateSchema instanceof SimpleSchema) {
|
||||||
|
updateSchema = methodOptions.updateSchema;
|
||||||
|
} else {
|
||||||
|
updateSchema = new SimpleSchema(methodOptions.updateSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the new validation
|
||||||
|
methodOptions.validate = function(args){
|
||||||
|
argumentSchema.validate(args);
|
||||||
|
updateSchema.validate(args.update, methodOptions.schemaValidatorOptions);
|
||||||
|
};
|
||||||
|
return methodOptions;
|
||||||
|
}
|
||||||
@@ -8,34 +8,13 @@ export function getHighestOrder({collection, charId}){
|
|||||||
sort: {order: -1},
|
sort: {order: -1},
|
||||||
});
|
});
|
||||||
return (highestOrderedDoc && highestOrderedDoc.order) || 0;
|
return (highestOrderedDoc && highestOrderedDoc.order) || 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
export function setDocToLastOrder({collection, doc}){
|
export function setDocToLastOrder({collection, doc}){
|
||||||
doc.order = getHighestOrder({
|
doc.order = getHighestOrder({
|
||||||
collection,
|
collection,
|
||||||
charId: doc.charId,
|
charId: doc.charId,
|
||||||
}) + 1;
|
}) + 1;
|
||||||
};
|
|
||||||
|
|
||||||
export function setDocToLastMixin(methodOptions){
|
|
||||||
// Make sure the doc has a charId
|
|
||||||
// This mixin should come before simpleSchemaMixin
|
|
||||||
methodOptions.schema.extend({
|
|
||||||
charId: {
|
|
||||||
type: String,
|
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
let collection = methodOptions.collection
|
|
||||||
if (!collection){
|
|
||||||
throw "`collection` required in method options for setDocToLastMixin"
|
|
||||||
}
|
|
||||||
let runFunc = methodOptions.run;
|
|
||||||
methodOptions.run = function(doc){
|
|
||||||
setDocToLastOrder({collection, doc});
|
|
||||||
return runFunc.apply(this, arguments);
|
|
||||||
};
|
|
||||||
return methodOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setDocOrder({collection, doc, order}){
|
export function setDocOrder({collection, doc, order}){
|
||||||
@@ -70,7 +49,7 @@ export function setDocOrder({collection, doc, order}){
|
|||||||
multi: true,
|
multi: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
export function reorderDocs({collection, charId}){
|
export function reorderDocs({collection, charId}){
|
||||||
let bulkWrite = [];
|
let bulkWrite = [];
|
||||||
@@ -96,4 +75,4 @@ export function reorderDocs({collection, charId}){
|
|||||||
collection.update(op.filter, op.update);
|
collection.update(op.filter, op.update);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import schema from '/imports/api/schema.js';
|
import schema from '/imports/api/schema.js';
|
||||||
|
|
||||||
const refSchema = new SimpleSchema({
|
const RefSchema = new SimpleSchema({
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
@@ -21,9 +21,9 @@ const refSchema = new SimpleSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let childSchema = schema({
|
let ChildSchema = schema({
|
||||||
parent: {
|
parent: {
|
||||||
type: refSchema,
|
type: RefSchema,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
ancestors: {
|
ancestors: {
|
||||||
@@ -31,8 +31,13 @@ let childSchema = schema({
|
|||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
},
|
},
|
||||||
'ancestors.$': {
|
'ancestors.$': {
|
||||||
type: refSchema,
|
type: RefSchema,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default childSchema;
|
const inheritedFields = new Set(RefSchema.objectKeys());
|
||||||
|
inheritedFields.delete('id');
|
||||||
|
inheritedFields.delete('collection');
|
||||||
|
|
||||||
|
export default ChildSchema;
|
||||||
|
export { inheritedFields };
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ let collections = [];
|
|||||||
|
|
||||||
export function registerCollection(collectionName){
|
export function registerCollection(collectionName){
|
||||||
collections.push(collectionName);
|
collections.push(collectionName);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 1 database hit to get the parent by reference
|
// 1 database hit to get the parent by reference
|
||||||
export function fetchParent({id, collection}){
|
export function fetchParent({id, collection}){
|
||||||
return fetchDocByRef({id, collection});
|
return fetchDocByRef({id, collection});
|
||||||
};
|
}
|
||||||
|
|
||||||
// n database hits to get the children by parent id
|
// n database hits to get the children by parent id
|
||||||
export function fetchChildren({parentId, filter = {}, options}){
|
export function fetchChildren({parentId, filter = {}, options}){
|
||||||
@@ -35,7 +35,7 @@ export function updateChildren({parentId, filter = {}, modifier, options={}}){
|
|||||||
collections.forEach(collection => {
|
collections.forEach(collection => {
|
||||||
collection.update(filter, modifier, options);
|
collection.update(filter, modifier, options);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
// n database hits to fetch the decendents by ancestor id, in no particular order
|
// n database hits to fetch the decendents by ancestor id, in no particular order
|
||||||
export function fetchDecendents({ancestorId, filter = {}, options}){
|
export function fetchDecendents({ancestorId, filter = {}, options}){
|
||||||
@@ -45,7 +45,7 @@ export function fetchDecendents({ancestorId, filter = {}, options}){
|
|||||||
decendents.push(...collection.find(filter, options).fetch());
|
decendents.push(...collection.find(filter, options).fetch());
|
||||||
});
|
});
|
||||||
return decendents;
|
return decendents;
|
||||||
};
|
}
|
||||||
|
|
||||||
// n database hits to update the decendents
|
// n database hits to update the decendents
|
||||||
export function updateDecendents({ancestorId, filter = {}, modifier, options={}}){
|
export function updateDecendents({ancestorId, filter = {}, modifier, options={}}){
|
||||||
@@ -54,7 +54,7 @@ export function updateDecendents({ancestorId, filter = {}, modifier, options={}}
|
|||||||
collections.forEach(collection => {
|
collections.forEach(collection => {
|
||||||
collection.update(filter, modifier, options);
|
collection.update(filter, modifier, options);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
// n database hits to get decendents to act on
|
// n database hits to get decendents to act on
|
||||||
export function forEachDecendent({ancestorId, filter = {}, options}, callback){
|
export function forEachDecendent({ancestorId, filter = {}, options}, callback){
|
||||||
@@ -62,9 +62,10 @@ export function forEachDecendent({ancestorId, filter = {}, options}, callback){
|
|||||||
collections.forEach(collection => {
|
collections.forEach(collection => {
|
||||||
collection.find(filter, options).forEach(callback);
|
collection.find(filter, options).forEach(callback);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
// 1 database read
|
// 1 database read
|
||||||
|
// TODO generalise for all inheritedFields
|
||||||
export function getAncestry({id, collection}){
|
export function getAncestry({id, collection}){
|
||||||
// Get the parent ref
|
// Get the parent ref
|
||||||
let parentDoc = fetchDocByRef({id, collection}, {fields: {
|
let parentDoc = fetchDocByRef({id, collection}, {fields: {
|
||||||
@@ -110,7 +111,7 @@ export function setDocAncestryMixin(methodOptions){
|
|||||||
return runFunc.call(this, doc, ...rest);
|
return runFunc.call(this, doc, ...rest);
|
||||||
};
|
};
|
||||||
return methodOptions;
|
return methodOptions;
|
||||||
};
|
}
|
||||||
|
|
||||||
function ensureAncestryContainsId(ancestors, id){
|
function ensureAncestryContainsId(ancestors, id){
|
||||||
if (!id){
|
if (!id){
|
||||||
@@ -148,7 +149,7 @@ export function ensureAncestryContainsCharIdMixin(methodOptions){
|
|||||||
return runFunc.apply(this, arguments);
|
return runFunc.apply(this, arguments);
|
||||||
};
|
};
|
||||||
return methodOptions;
|
return methodOptions;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export function updateParent(docRef, parentRef){
|
export function updateParent(docRef, parentRef){
|
||||||
@@ -183,57 +184,16 @@ export function updateParent(docRef, parentRef){
|
|||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export function setInheritedField({id, collection, fieldName, fieldValue}){
|
|
||||||
|
|
||||||
// Update the doc
|
|
||||||
collection = getCollectionByName(collection);
|
|
||||||
collection.update(id, {$set: {
|
|
||||||
[`${fieldName}`]: fieldValue,
|
|
||||||
}});
|
|
||||||
|
|
||||||
// Update the parent object of its children
|
|
||||||
updateChildren({
|
|
||||||
parentId: id,
|
|
||||||
modifier: {$set: {
|
|
||||||
[`parent.${fieldName}`]: fieldValue,
|
|
||||||
}},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the ancestors object of its decendents
|
|
||||||
updateDecendents({
|
|
||||||
ancestorId: id,
|
|
||||||
modifier: {$set: {
|
|
||||||
[`ancestors.$.${fieldName}`]: fieldValue,
|
|
||||||
}},
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export function setEnabled({id, collection, enabled}){
|
|
||||||
setInheritedField({
|
|
||||||
id,
|
|
||||||
collection,
|
|
||||||
fieldName: 'enabled',
|
|
||||||
fieldValue: enabled,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function setName({id, collection, name}){
|
|
||||||
setInheritedField({
|
|
||||||
id,
|
|
||||||
collection,
|
|
||||||
fieldName: 'name',
|
|
||||||
fieldValue: name,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// TODO these rely on hard coding inherited fields
|
||||||
|
// the inherited fields should only appear on the childChema, nowhere else
|
||||||
|
// Move these somewhere appropriate
|
||||||
export function findEnabled(collection, query, options){
|
export function findEnabled(collection, query, options){
|
||||||
query['enabled'] = true;
|
query.enabled = true;
|
||||||
query['ancestors.$.enabled'] = {$not: false};
|
query['ancestors.$.enabled'] = {$not: false};
|
||||||
return collection.find(query, options);
|
return collection.find(query, options);
|
||||||
};
|
}
|
||||||
|
|
||||||
export function getName(doc){
|
export function getName(doc){
|
||||||
if (doc.name) return name;
|
if (doc.name) return name;
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
export default function pickKeysAsOptional(schema, keys){
|
|
||||||
let newSchema = schema.pick(...keys);
|
|
||||||
let optionalSchema = {};
|
|
||||||
for (let i of keys){
|
|
||||||
optionalSchema[i] = {optional: true}
|
|
||||||
};
|
|
||||||
newSchema.extend(optionalSchema);
|
|
||||||
return newSchema;
|
|
||||||
};
|
|
||||||
17
app/imports/constants/MONGO_OPERATORS.js
Normal file
17
app/imports/constants/MONGO_OPERATORS.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const MONGO_OPERATORS = Object.freeze([
|
||||||
|
'$addToSet',
|
||||||
|
'$bit',
|
||||||
|
'$currentDate',
|
||||||
|
'$inc',
|
||||||
|
'$max',
|
||||||
|
'$min',
|
||||||
|
'$pop',
|
||||||
|
'$pull',
|
||||||
|
'$pullAll',
|
||||||
|
'$push',
|
||||||
|
'$rename',
|
||||||
|
'$set',
|
||||||
|
'$unset',
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default MONGO_OPERATORS;
|
||||||
@@ -9,8 +9,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import AttributeDialog from '/imports/ui/components/attributes/AttributeDialog.vue';
|
import AttributeDialog from '/imports/ui/components/attributes/AttributeDialog.vue';
|
||||||
import Attributes from '/imports/api/creature/properties/Attributes.js';
|
import Attributes from '/imports/api/creature/properties/Attributes.js';
|
||||||
import { updateAttribute, adjustAttribute } from '/imports/api/creature/properties/Attributes.js';
|
import {
|
||||||
|
updateAttribute,
|
||||||
|
adjustAttribute
|
||||||
|
} from '/imports/api/creature/properties/Attributes.js';
|
||||||
import Effects from '/imports/api/creature/properties/Effects.js';
|
import Effects from '/imports/api/creature/properties/Effects.js';
|
||||||
|
import { setName } from '/imports/api/parenting/parenting.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -41,13 +45,15 @@
|
|||||||
console.log({TODO: e});
|
console.log({TODO: e});
|
||||||
},
|
},
|
||||||
change(update, ack){
|
change(update, ack){
|
||||||
if(update.name){
|
if (update.name){
|
||||||
update.variableName = update.name.toLowerCase().replace(
|
setName.call({})
|
||||||
/\W+(\w?)/g, (match, p1) => p1.toUpperCase()
|
} if (update)
|
||||||
);
|
updateAttribute.call({
|
||||||
}
|
_id: this._id,
|
||||||
updateAttribute.call({_id: this._id, update}, error => {
|
update: {$set: update}
|
||||||
|
}, error => {
|
||||||
ack(error);
|
ack(error);
|
||||||
|
if (error) console.error(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user