not sure if this will help, but this is how I do it:
import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
export const Extensions = new Mongo.Collection('Extensions');
Extensions.allow({
insert: () => false,
update: () => false,
remove: () => false,
});
Extensions.deny({
insert: () => true,
update: () => true,
remove: () => true,
});
export const ExtensionUpdate = new SimpleSchema({
extensionId: { type: String },
extensionAction: { type: String },
extensionInformation: { type: Object, blackbox: true },
});
export const ExtensionSchema = new SimpleSchema({
extensionGeneralSettings: { type: Object },
'extensionGeneralSettings.name': { type: String },
'extensionGeneralSettings.code': { type: String },
'extensionGeneralSettings.key': { type: String },
'extensionGeneralSettings.createDate': { type: Date },
});
Extensions.attachSchema(ExtensionSchema);
So what this means is that I can import 3 things into my methods file, like so:
import { Extensions, ExtensionSchema, ExtensionUpdate } from './extensions.js';
But then I don’t need the schema validation here, as just use validate: ExtensionUpdate.validator(),
as an example. All updates then come in with three bits of info like so:
export const updateEGS = new ValidatedMethod({
name: 'extensionGeneralSettings.update',
validate: ExtensionUpdate.validator(),
run({ extensionId, extensionAction, extensionInformation }) {
if (Meteor.isServer) {
switch (extensionAction) {
case ('name'): {
let setModifier = { $set: {} };
setModifier.$set[
'extensionGeneralSettings.name'
] = extensionInformation.name;
Extensions.update(extensionId, setModifier);
break;
}
case ('code'): {
// some method
}
case ('key'): {
// some method
}
default: {
throw new Meteor.Error(
'extensionGeneralSettings.update.failure',
`Method ${extensionAction} was not recognized...`
);
}
}
}
},
});
This simple pattern makes metod calls and testing method calls really simple. The major downside is that much more of your business logic is going to end up in client side functions. How to test these now? SO updside and downside, based around your use case. Just my 2c.
Tat
Notes: I have wrapper functions, which do a lot of the security heavy lifting, on client side, like:
/**
* @function getExtensionGeneralSettings
* @param { String } extensionId
* @returns { Object } extensionGeneralSettings
* @throws { Meteor.Error }
*/
function getExtensionGeneralSettings(extensionId) {
checkExtension(extensionId);
return getExtension(extensionId).extensionGeneralSettings;
}
/**
* @function setExtensionGeneralSettings
* @param { String } extensionId
* @param { String } extensionAction
* @param { Object } extensionInformation
* @throws { Meteor.Error }
*/
function setExtensionGeneralSettings(extensionId, extensionAction, extensionInformation) {
checkExtension(extensionId); // special checking functions
// more checks. Depending on complexity, can also do deep checks
// of object structure for the extensionInformation object.
check(extensionAction, Match.OneOf(
'name', 'code', 'key', 'createDate',
));
check(extensionInformation, Object);
const updateModifier = {
extensionId: extensionId,
extensionAction: extensionAction,
extensionInformation: extensionInformation,
};
updateEGS.call(updateModifier, (err) => {
if (err) {
throw new Meteor.Error(
'setExtensionGeneralSettings.failure',
`${extensionAction} cannot be completed...`
);
}
});
}
/**
* @function getEGSname
* @param { String } extensionId
* @returns { String } name
* @throws { Meteor.Error }
*/
export function getEGSname(extensionId) {
checkExtension(extensionId);
return getExtensionGeneralSettings(extensionId).name;
}
/**
* @function setLGSname
* @param { String } extensionId
* @param { String } name
* @throws { Meteor.Error }
*/
export function setEGSname(extensionId, name) {
checkExtension(extensionId);
check(name, String);
const extensionInformation = {
name: name,
};
setExtensionGeneralSettings(extensionId, 'name', extensionInformation);
}