Began rebuilding computation engine to be dependency graph centric
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import '/imports/api/simpleSchemaConfig.js';
|
||||
import '/imports/ui/vueSetup.js';
|
||||
import '/imports/ui/styles/stylesIndex.js';
|
||||
import '/imports/client/config.js';
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { get } from 'lodash';
|
||||
|
||||
export function applyFnToKey(doc, key, fn){
|
||||
if (key.includes('$.')){
|
||||
applyToArrayKey(doc, key, fn);
|
||||
} else {
|
||||
applyToSingleKey(doc, key, fn);
|
||||
}
|
||||
}
|
||||
|
||||
function applyToSingleKey(doc, key, fn){
|
||||
// call the function with the current value and document for context
|
||||
fn(doc, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function to all instances in a document key
|
||||
* key.$.with.$.subdocs will apply to all key[i...n].with[j...m].subdocs
|
||||
*/
|
||||
function applyToArrayKey(doc, key, fn){
|
||||
const keySplit = key.split('.$');
|
||||
|
||||
// Stack based depth first traversal of arrays
|
||||
const stack = [{
|
||||
array: get(doc, keySplit[0]),
|
||||
paths: keySplit.slice(1),
|
||||
currentPath: keySplit[0],
|
||||
indices: [],
|
||||
}];
|
||||
while(stack.length){
|
||||
const state = stack.pop();
|
||||
for (let index in state.array.length){
|
||||
const currentPath = `${state.currentPath}[${index}]${state.paths[0]}`
|
||||
if (state.paths.length == 1){
|
||||
applyToSingleKey(doc, currentPath, fn);
|
||||
} else {
|
||||
stack.push({
|
||||
array: get(doc, currentPath),
|
||||
paths: state.paths.slice(1),
|
||||
currentPath,
|
||||
indices: [...state.indices, index],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
|
||||
import CreatureProperties,
|
||||
{ DenormalisedOnlyCreaturePropertySchema as denormSchema }
|
||||
from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import computedOnlySchemas from '/imports/api/properties/computedOnlyPropertySchemasIndex.js';
|
||||
import computedSchemas from '/imports/api/properties/computedPropertySchemasIndex.js';
|
||||
import applyFnToKey from '/imports/api/creature/computation/newEngine/applyFnToKey.js';
|
||||
import { cloneDeep, unset } from 'lodash';
|
||||
import { prettifyParseError, parse } from '/imports/parser/parser.js';
|
||||
import ErrorNode from '/imports/parser/parseTree/ErrorNode.js';
|
||||
import SymbolNode from '/imports/parser/parseTree/SymbolNode.js';
|
||||
import AccessorNode from '/imports/parser/parseTree/AccessorNode.js';
|
||||
import createGraph from 'ngraph.graph';
|
||||
import findAncestorByType from 'imports/api/creature/computation/newEngine/findAncestorByType.js';
|
||||
|
||||
/**
|
||||
* Store index of properties
|
||||
* recompute static tree-based enabled/disabled status
|
||||
* Build a dependency graph
|
||||
* id -> id dependencies for docs that rely on other docs directly
|
||||
* id -> variable deps for docs that rely on a variable's value
|
||||
* TODO:
|
||||
* variable -> id deps for variables that are impacted by docs
|
||||
* Depth first traversal or dependency graph to:
|
||||
* Find loops in the dependency graph
|
||||
* resolve variables in dependency order
|
||||
*/
|
||||
|
||||
export default function computeCreature(creatureId){
|
||||
let properties = CreatureProperties.find({
|
||||
'ancestors.id': creatureId,
|
||||
'removed': {$ne: true},
|
||||
}, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
|
||||
const originalPropsById = {};
|
||||
const propsById = {};
|
||||
const propsByType = {};
|
||||
|
||||
// Process the properties one by one
|
||||
properties.forEach(prop => {
|
||||
// Store the prop by Id and Type
|
||||
originalPropsById[prop._id] = cloneDeep(prop);
|
||||
propsById[prop._id] = prop;
|
||||
if (!propsByType[prop.type]) propsByType[prop.type] = [];
|
||||
propsByType[prop.type].push(prop);
|
||||
|
||||
// Store the prop in the dependency graph
|
||||
dependencyGraph.addNode(prop._id, prop);
|
||||
|
||||
// Remove all computed only fields
|
||||
computedOnlySchemas[prop.type]._schemaKeys.forEach(key =>
|
||||
applyFnToKey(prop, key, unset)
|
||||
);
|
||||
|
||||
// Remove all denormalised fields
|
||||
denormSchema._schemaKeys.forEach(key =>
|
||||
applyFnToKey(prop, key, unset)
|
||||
);
|
||||
|
||||
// Add a place to store all the computation details
|
||||
prop._computationDetails = {
|
||||
calculations: [],
|
||||
toggleAncestors: [],
|
||||
};
|
||||
|
||||
// parse every calculation field
|
||||
computedSchemas[prop.type]._schemaKeys.forEach( key => {
|
||||
if (key.slice(-11) !== 'calculation') return;
|
||||
const calcKey = key.sclice(0, -11);
|
||||
applyFnToKey(prop, calcKey, calcObj => {
|
||||
// Store a reference to all the calculations
|
||||
prop._computationDetails.calculations.push(calcObj);
|
||||
// Parse the calculation
|
||||
parseCalculation(calcObj);
|
||||
return calcObj;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Dependency graph where edge(a, b) means a depends on b
|
||||
const dependencyGraph = createGraph();
|
||||
// Build graph now that all props are stored
|
||||
properties.forEach(prop => {
|
||||
linkDependencies(dependencyGraph, prop, propsById);
|
||||
});
|
||||
|
||||
// Process the properties in tree format
|
||||
let creatureTree = nodeArrayToTree(properties);
|
||||
walkDown(creatureTree, node => {
|
||||
denormaliseInactiveStatus(node);
|
||||
inheritToggleDependencies(node);
|
||||
});
|
||||
}
|
||||
|
||||
function walkDown(tree, callback){
|
||||
let stack = [...tree];
|
||||
while(stack.length){
|
||||
let node = stack.pop();
|
||||
callback(node);
|
||||
stack.push(...node.children);
|
||||
}
|
||||
}
|
||||
|
||||
function denormaliseInactiveStatus(node){
|
||||
const prop = node.node;
|
||||
if (isActive(prop)) return;
|
||||
prop.inactive = true;
|
||||
prop.deactivatedBySelf = true;
|
||||
// Mark children as inactive due to ancestor
|
||||
walkDown(node.children, child => {
|
||||
child.node.inactive = true;
|
||||
child.node.deactivatedByAncestor = true;
|
||||
});
|
||||
}
|
||||
|
||||
function isActive(prop){
|
||||
if (prop.disabled) return false;
|
||||
switch (prop.type){
|
||||
case 'buff': return !!prop.applied;
|
||||
case 'item': return !!prop.equipped;
|
||||
case 'spell': return !!prop.prepared || !!prop.alwaysPrepared;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
function inheritToggleDependencies(node, dependencyGraph){
|
||||
const prop = node.node;
|
||||
// Only for toggles that aren't inactive and aren't set to enabled or disabled
|
||||
if (
|
||||
prop.inactive ||
|
||||
prop.type !== 'toggle' ||
|
||||
prop.disabled ||
|
||||
prop.enabled
|
||||
) return;
|
||||
walkDown(node.children, child => {
|
||||
child.node._computationDetails.toggleAncestors.push(prop._id);
|
||||
dependencyGraph.addLink(child.node._id, prop._id, prop.condition);
|
||||
});
|
||||
}
|
||||
|
||||
function parseCalculation(calcObj){
|
||||
let calculation = calcObj.calculation || '';
|
||||
try {
|
||||
calcObj._parsedCalculation = parse(calculation);
|
||||
} catch (e) {
|
||||
let error = prettifyParseError(e);
|
||||
calcObj.errors ?
|
||||
calcObj.errors.push(error) :
|
||||
calcObj.errors = [error];
|
||||
calcObj._parsedCalculation = new ErrorNode({error});
|
||||
}
|
||||
}
|
||||
|
||||
function linkDependencies(dependencyGraph, prop, propsById){
|
||||
let variableNames = [];
|
||||
prop._computationDetails.calculations.forEach(calcObj => {
|
||||
calcObj._parsedCalculation.travese(node => {
|
||||
if (node instanceof SymbolNode || node instanceof AccessorNode){
|
||||
if (node.name[0] !== '#'){
|
||||
dependencyGraph.addLink(prop._id, node.name, calcObj);
|
||||
} else {
|
||||
let ancestorProp = findAncestorByType(
|
||||
prop, node.name.slice(1), propsById
|
||||
);
|
||||
if (!ancestorProp) return;
|
||||
dependencyGraph.addLink(prop._id, ancestorProp._id, calcObj);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return variableNames;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export default function findAncestorByType(prop, type, propsById){
|
||||
if (!prop || !prop.ancestors) return;
|
||||
let ancestor;
|
||||
for (let i = prop.ancestors.length - 1; i >= 0; i--){
|
||||
ancestor = propsById[prop.ancestors[i].id];
|
||||
if (ancestor && ancestor.type === type){
|
||||
return ancestor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,9 @@ let CreaturePropertySchema = new SimpleSchema({
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const DenormalisedOnlyCreaturePropertySchema = new SimpleSchema({
|
||||
// Denormalised flag if this property is inactive on the sheet for any reason
|
||||
// Including being disabled, or a decendent of a disabled property
|
||||
inactive: {
|
||||
@@ -86,6 +89,8 @@ let CreaturePropertySchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
CreaturePropertySchema.extend(DenormalisedOnlyCreaturePropertySchema);
|
||||
|
||||
for (let key in propertySchemasIndex){
|
||||
let schema = new SimpleSchema({});
|
||||
schema.extend(propertySchemasIndex[key]);
|
||||
@@ -104,5 +109,6 @@ import '/imports/api/creature/actions/castSpellWithSlot.js';
|
||||
|
||||
export default CreatureProperties;
|
||||
export {
|
||||
DenormalisedOnlyCreaturePropertySchema,
|
||||
CreaturePropertySchema,
|
||||
};
|
||||
|
||||
@@ -7,10 +7,8 @@ const AdjustmentSchema = createPropertySchema({
|
||||
// This can be simplified, but should only compute when activated
|
||||
amount: {
|
||||
type: 'fieldToCompute',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
},
|
||||
'amount.calculation': {
|
||||
type: String,
|
||||
defaultValue: 1,
|
||||
},
|
||||
// Who this adjustment applies to
|
||||
@@ -39,6 +37,7 @@ const AdjustmentSchema = createPropertySchema({
|
||||
const ComputedOnlyAdjustmentSchema = createPropertySchema({
|
||||
amount: {
|
||||
type: 'computedOnlyField',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,10 +10,8 @@ let AttackSchema = new SimpleSchema()
|
||||
// What gets added to the d20 roll
|
||||
rollBonus: {
|
||||
type: 'fieldToCompute',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
},
|
||||
'rollBonus.calculation': {
|
||||
type: String,
|
||||
defaultValue: 'strength.modifier + proficiencyBonus',
|
||||
},
|
||||
// Set better defaults for the action
|
||||
@@ -38,6 +36,7 @@ const ComputedOnlyAttackSchema = new SimpleSchema()
|
||||
.extend(createPropertySchema({
|
||||
rollBonus: {
|
||||
type: 'computedOnlyField',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -57,7 +57,6 @@ let AttributeSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
// The damage done to the attribute, always positive
|
||||
damage: {
|
||||
@@ -108,7 +107,7 @@ let ComputedOnlyAttributeSchema = createPropertySchema({
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
// The computed creature constitution modifier
|
||||
// The computed creature constitution modifier for hit dice
|
||||
constitutionMod: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let BuffSchema = new SimpleSchema({
|
||||
name: {
|
||||
let BuffSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
// How many rounds this buff lasts
|
||||
duration: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
applied: {
|
||||
type: Boolean,
|
||||
@@ -34,13 +33,16 @@ let BuffSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyBuffSchema = new SimpleSchema({
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
let ComputedOnlyBuffSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
duration: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
},
|
||||
durationSpent: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let ClassLevelSchema = new SimpleSchema({
|
||||
let ClassLevelSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
// Only used by slot filling dialog, not computed
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
// The name of this class level's variable
|
||||
variableName: {
|
||||
type: String,
|
||||
@@ -25,13 +25,6 @@ let ClassLevelSchema = new SimpleSchema({
|
||||
type: SimpleSchema.Integer,
|
||||
defaultValue: 1,
|
||||
},
|
||||
nextLevelTags: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'nextLevelTags.$': {
|
||||
type: String,
|
||||
},
|
||||
// Same as in SlotFillers.js
|
||||
slotFillerCondition: {
|
||||
type: String,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let ContainerSchema = new SimpleSchema({
|
||||
let ContainerSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -29,20 +29,16 @@ let ContainerSchema = new SimpleSchema({
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
trim: false,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyContainerSchema = new SimpleSchema({
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
const ComputedOnlyContainerSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
// Weight of all the contents, zero if `contentsWeightless` is true
|
||||
contentsWeight:{
|
||||
type: Number,
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
const DamageSchema = new SimpleSchema({
|
||||
const DamageSchema = createPropertySchema({
|
||||
// The roll that determines how much to damage the attribute
|
||||
// This can be simplified, but only computed when applied
|
||||
amount: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
defaultValue: '1d8 + strength.modifier',
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
// Who this damage applies to
|
||||
target: {
|
||||
@@ -29,19 +27,11 @@ const DamageSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyDamageSchema = new SimpleSchema({
|
||||
amountResult: {
|
||||
type: SimpleSchema.oneOf(String, Number),
|
||||
const ComputedOnlyDamageSchema = createPropertySchema({
|
||||
amount: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
},
|
||||
amountErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'amountErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedDamageSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
/*
|
||||
* Effects are reason-value attached to skills and abilities
|
||||
* that modify their final value or presentation in some way
|
||||
*/
|
||||
let EffectSchema = new SimpleSchema({
|
||||
let EffectSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -30,10 +30,9 @@ let EffectSchema = new SimpleSchema({
|
||||
'rollBonus',
|
||||
],
|
||||
},
|
||||
calculation: {
|
||||
type: String,
|
||||
amount: {
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
//which stats the effect is applied to
|
||||
stats: {
|
||||
@@ -47,20 +46,10 @@ let EffectSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyEffectSchema = new SimpleSchema({
|
||||
// The computed result of the effect
|
||||
result: {
|
||||
type: SimpleSchema.oneOf(Number, String, Boolean),
|
||||
optional: true,
|
||||
},
|
||||
// The errors encountered while computing the result
|
||||
errors: {
|
||||
type: Array,
|
||||
const ComputedOnlyEffectSchema = createPropertySchema({
|
||||
amount: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'errors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,40 +1,31 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let FeatureSchema = new SimpleSchema({
|
||||
let FeatureSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
summary: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.summary,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyFeatureSchema = new SimpleSchema({
|
||||
|
||||
summaryCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
let ComputedOnlyFeatureSchema = createPropertySchema({
|
||||
summary: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
'summaryCalculations.$': InlineComputationSchema,
|
||||
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
|
||||
});
|
||||
|
||||
const ComputedFeatureSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
const ItemSchema = new SimpleSchema({
|
||||
const ItemSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -14,10 +14,9 @@ const ItemSchema = new SimpleSchema({
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
// Number currently held
|
||||
quantity: {
|
||||
@@ -58,13 +57,11 @@ const ItemSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyItemSchema = new SimpleSchema({
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
let ComputedOnlyItemSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
});
|
||||
|
||||
const ComputedItemSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,41 +1,32 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let NoteSchema = new SimpleSchema({
|
||||
let NoteSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
summary: {
|
||||
type: String,
|
||||
summary: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.summary,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyNoteSchema = new SimpleSchema({
|
||||
|
||||
summaryCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
let ComputedOnlyNoteSchema = createPropertySchema({
|
||||
summary: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
'summaryCalculations.$': InlineComputationSchema,
|
||||
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
|
||||
});
|
||||
|
||||
const ComputedNoteSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
/**
|
||||
* Rolls are children to actions or other rolls, they are triggered with 0 or
|
||||
@@ -21,7 +21,7 @@ import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
* If the roll fails to meet or exceed the target number, the adjustments and
|
||||
* child rolls are applied
|
||||
*/
|
||||
let RollSchema = new SimpleSchema({
|
||||
let RollSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
defaultValue: 'New Roll',
|
||||
@@ -37,25 +37,18 @@ let RollSchema = new SimpleSchema({
|
||||
},
|
||||
// The roll, can be simplified, but only computed in context
|
||||
roll: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyRollSchema = new SimpleSchema({
|
||||
rollResult: {
|
||||
type: SimpleSchema.Integer,
|
||||
let ComputedOnlyRollSchema = createPropertySchema({
|
||||
roll: {
|
||||
type: 'computedOnlyField',
|
||||
parseLevel: 'compile',
|
||||
optional: true,
|
||||
},
|
||||
rollErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'rollErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedRollSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
// These are the rolls made when saves are called for
|
||||
// For the saving throw bonus or proficiency, see ./Skills.js
|
||||
let SavingThrowSchema = new SimpleSchema ({
|
||||
let SavingThrowSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -12,9 +12,8 @@ let SavingThrowSchema = new SimpleSchema ({
|
||||
},
|
||||
// The computed DC
|
||||
dc: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
// Who this saving throw applies to
|
||||
target: {
|
||||
@@ -34,19 +33,11 @@ let SavingThrowSchema = new SimpleSchema ({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlySavingThrowSchema = new SimpleSchema({
|
||||
dcResult: {
|
||||
type: Number,
|
||||
const ComputedOnlySavingThrowSchema = createPropertySchema({
|
||||
dc: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
},
|
||||
dcErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'dcErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedSavingThrowSchema = new SimpleSchema()
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
/*
|
||||
* Skills are anything that results in a modifier to be added to a D20
|
||||
* Skills have an ability score modifier that they use as their basis
|
||||
*/
|
||||
let SkillSchema = new SimpleSchema({
|
||||
let SkillSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -42,26 +42,24 @@ let SkillSchema = new SimpleSchema({
|
||||
],
|
||||
defaultValue: 'skill',
|
||||
},
|
||||
// The starting value, before effects
|
||||
baseValueCalculation: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
// The base proficiency of this skill
|
||||
baseProficiency: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
// The starting value, before effects
|
||||
baseValue: {
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
// Description of what the skill is used for
|
||||
description: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlySkillSchema = new SimpleSchema({
|
||||
let ComputedOnlySkillSchema = createPropertySchema({
|
||||
// Computed value of skill to be added to skill rolls
|
||||
value: {
|
||||
type: Number,
|
||||
@@ -69,17 +67,13 @@ let ComputedOnlySkillSchema = new SimpleSchema({
|
||||
},
|
||||
// The result of baseValueCalculation
|
||||
baseValue: {
|
||||
type: SimpleSchema.oneOf(Number, String, Boolean),
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
},
|
||||
baseValueErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'baseValueErrors.$': {
|
||||
type: ErrorSchema,
|
||||
},
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
// Computed value added by the ability
|
||||
abilityMod: {
|
||||
type: SimpleSchema.Integer,
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let SlotSchema = new SimpleSchema({
|
||||
let SlotSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
slotType: {
|
||||
type: String,
|
||||
@@ -57,19 +56,17 @@ let SlotSchema = new SimpleSchema({
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
quantityExpected: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
defaultValue: '1',
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
ignored: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
slotCondition: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
hideWhenFull: {
|
||||
type: Boolean,
|
||||
@@ -89,33 +86,15 @@ let SlotSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlySlotSchema = new SimpleSchema({
|
||||
// Condition calculation results
|
||||
slotConditionResult: {
|
||||
type: SimpleSchema.oneOf(Number, String, Boolean),
|
||||
optional: true,
|
||||
},
|
||||
slotConditionErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'slotConditionErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
|
||||
// Quantity Expected calculation results
|
||||
quantityExpectedResult: {
|
||||
type: SimpleSchema.Integer,
|
||||
const ComputedOnlySlotSchema = createPropertySchema({
|
||||
// Computed fields
|
||||
quantityExpected: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
},
|
||||
quantityExpectedErrors: {
|
||||
type: Array,
|
||||
slotCondition: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'quantityExpectedErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
|
||||
// Denormalised fields
|
||||
|
||||
@@ -1,87 +1,50 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import InlineComputationSchema from '/imports/api/properties/subSchemas/InlineComputationSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
let SpellListSchema = new SimpleSchema({
|
||||
let SpellListSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
// Calculation of how many spells in this list can be prepared
|
||||
maxPrepared: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
// Calculation of The attack roll bonus used by spell attacks in this list
|
||||
attackRollBonus: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
// Calculation of the save dc used by spells in this list
|
||||
dc: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlySpellListSchema = new SimpleSchema({
|
||||
descriptionCalculations: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.inlineCalculationCount,
|
||||
},
|
||||
'descriptionCalculations.$': InlineComputationSchema,
|
||||
|
||||
// maxPrepared
|
||||
maxPreparedResult: {
|
||||
type: Number,
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
maxPreparedErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'maxPreparedErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
|
||||
// attackRollBonus
|
||||
attackRollBonusResult: {
|
||||
type: Number,
|
||||
maxPrepared: {
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
attackRollBonusErrors: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'attackRollBonusErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
|
||||
// dc
|
||||
dcResult: {
|
||||
type: Number,
|
||||
attackRollBonus: {
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
dcErrors: {
|
||||
type: Array,
|
||||
dc: {
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'dcErrors.$':{
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
|
||||
const ToggleSchema = new SimpleSchema({
|
||||
const ToggleSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
@@ -19,26 +19,15 @@ const ToggleSchema = new SimpleSchema({
|
||||
// if neither disabled or enabled, the condition will be run to determine
|
||||
// if the children of the toggle should be active
|
||||
condition: {
|
||||
type: String,
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.calculation,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyToggleSchema = new SimpleSchema({
|
||||
// The computed result of the effect
|
||||
toggleResult: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// The errors encountered while computing the result
|
||||
errors: {
|
||||
type: Array,
|
||||
const ComputedOnlyToggleSchema = createPropertySchema({
|
||||
condition: {
|
||||
type: 'computedOnlyField',
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.errorCount,
|
||||
},
|
||||
'errors.$': {
|
||||
type: ErrorSchema,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
} from '/imports/api/properties/subSchemas/computedField.js';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
// Search through the schema for keys whose type is 'fieldToCompute' etc.
|
||||
// replace the type with Object and attach extend the schema with
|
||||
// the required fields to make the computation work
|
||||
export default function createPropertySchema(definition){
|
||||
const computationFields = {
|
||||
inlineCalculationFieldToCompute: [],
|
||||
@@ -21,12 +24,20 @@ export default function createPropertySchema(definition){
|
||||
const def = definition[key];
|
||||
if (computedKeys.includes(def.type)){
|
||||
computationFields[def.type].push(key);
|
||||
applyDefaultCalculationValue(definition, key);
|
||||
def.type = Object;
|
||||
if (!def.optional){
|
||||
console.warn(
|
||||
`computed field: '${key}' of '${def.type}' is expected to be optional`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a schema with the edited definition
|
||||
const schema = new SimpleSchema(definition);
|
||||
|
||||
// Extend the schema with all the computation fields
|
||||
computationFields.inlineCalculationFieldToCompute.forEach(key => {
|
||||
schema.extend(inlineCalculationFieldToCompute(key))
|
||||
});
|
||||
@@ -41,3 +52,33 @@ export default function createPropertySchema(definition){
|
||||
});
|
||||
return schema
|
||||
}
|
||||
|
||||
function applyDefaultCalculationValue(definition, key){
|
||||
const def = definition[key];
|
||||
if (
|
||||
def.type === 'computedOnlyField' ||
|
||||
def.type === 'computedOnlyInlineCalculationField'
|
||||
){
|
||||
// don't apply defaults to computed only fields
|
||||
// because it would add the calculation field which should only appear
|
||||
// on the fields to compute
|
||||
return;
|
||||
}
|
||||
let defaultValue = def.defaultValue;
|
||||
if (!defaultValue) return;
|
||||
let calcField;
|
||||
if (def.type === 'fieldToCompute'){
|
||||
calcField = key + '.calculation'
|
||||
} else {
|
||||
calcField = key + '.text'
|
||||
}
|
||||
if (definition[calcField]){
|
||||
definition[calcField].defaultValue = defaultValue;
|
||||
} else {
|
||||
definition[calcField] = {
|
||||
type: String,
|
||||
defaultValue,
|
||||
};
|
||||
}
|
||||
delete def.defaultValue;
|
||||
}
|
||||
|
||||
3
app/imports/api/simpleSchemaConfig.js
Normal file
3
app/imports/api/simpleSchemaConfig.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
SimpleSchema.extendOptions(['parseLevel']);
|
||||
@@ -15,15 +15,19 @@ export default function transformFields(src, transformList, reversed = false){
|
||||
} else {
|
||||
transform = {...originalTransform};
|
||||
}
|
||||
if (transform.from?.includes('$.')){
|
||||
transformArrayField(src, doc, transform, reversed);
|
||||
} else {
|
||||
transformSingleField(src, doc, transform);
|
||||
}
|
||||
transformField(src, doc, transform, reversed);
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
export function transformField(src, doc, transform, reversed){
|
||||
if (transform.from?.includes('$.')){
|
||||
transformArrayField(src, doc, transform, reversed);
|
||||
} else {
|
||||
transformSingleField(src, doc, transform);
|
||||
}
|
||||
}
|
||||
|
||||
function transformSingleField(src, doc, {from, to, up}){
|
||||
// Get the value in the `from` path and delete it
|
||||
let value = undefined;
|
||||
|
||||
13
app/package-lock.json
generated
13
app/package-lock.json
generated
@@ -2408,6 +2408,19 @@
|
||||
"randexp": "0.4.6"
|
||||
}
|
||||
},
|
||||
"ngraph.events": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.1.tgz",
|
||||
"integrity": "sha512-D4C+nXH/RFxioGXQdHu8ELDtC6EaCiNsZtih0IvyGN81OZSUby4jXoJ5+RNWasfsd0FnKxxpAROyUMzw64QNsw=="
|
||||
},
|
||||
"ngraph.graph": {
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-19.1.0.tgz",
|
||||
"integrity": "sha512-9cws84qfPkrYa7BaBtT+KgZfLXrd6pNL9Gl5Do+MBO/0Hm6rOM7qK78MZaO1uEoIK6p2pgUs6lu29zn/6tP59w==",
|
||||
"requires": {
|
||||
"ngraph.events": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"meteor-node-stubs": "^1.1.0",
|
||||
"moo": "^0.5.1",
|
||||
"nearley": "^2.19.1",
|
||||
"ngraph.graph": "^19.1.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"request": "^2.88.2",
|
||||
"simpl-schema": "^1.12.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import '/imports/api/simpleSchemaConfig.js';
|
||||
import '/imports/server/config/accountsEmailConfig.js';
|
||||
import '/imports/server/config/SimpleRestConfig.js';
|
||||
import '/imports/server/config/simpleSchemaDebug.js';
|
||||
|
||||
Reference in New Issue
Block a user