Meteor ValidatedMethod Factory
Create validated Meteor methods. Lightweight. Simple.
With this package you can define factory functions to create a variety of Meteor methods. Decouples definition from instantiation (also for the schema) and allows different configurations for different types of methods.
Minified size < 2KB!
Why do I want this?
- Decouple definition from instantiation
- Just pass in the schema as plain object, instead of manually instantiating
SimpleSchema
- Create fixed mixins on the abstract factory level, on the factory level, or both (see mixins section)
Installation
Simply add this package to your meteor packages
$ meteor add leaonline:method-factory
Usage
Import the createMethodFactory
method and create the factory function from it:
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2 3const createMethod = createMethodFactory() // no params = use defaults 4const fancyMethod = createMethod({ name: 'fancy', validate: () => {}, run: () => 'fancy' }) // minimal required 5fancyMethod.call() // 'fancy'
With schema
We support various ways to validate an input schema. To decouple schema definition from instantiation, we introduced a shemaFactory
, which
is basically a function that creates your schema for this collection. This also ensures, that
methods don't share the same schema instances.
Using SimpleSchema
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import SimpleSchema from 'simpl-schema' 3 4const schemaFactory = definitions => new SimpleSchema(definitions) 5 6const createMethod = createMethodFactory({ schemaFactory }) 7const fancyMethod = createMethod({ 8 name: 'fancy', 9 schema: { title: String }, 10 run: function({ title }) { 11 return `Hello, ${title}` 12 } 13}) 14fancyMethod.call({ title: 'Mr.x' }) // Hello, Mr.x
As you can see, there is no need to pass a validate
function as it is internally built using the schemaFactory
and the given schema
.
Overriding validate
when using schema
You can also override the internal validate
when using schema
by passing a validate
function.
This, however, disables the schema validation and is then your responsibility:
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import SimpleSchema from 'simpl-schema' 3 4const schemaFactory = definitions => new SimpleSchema(definitions) 5 6const createMethod = createMethodFactory({ schemaFactory }) 7const customValidationMethod = createMethod({ 8 name: 'customValidation', 9 schema: { title: String }, 10 validate(document) { 11 if (!['Mrs.y', 'Mr.x'].includes(document.title)) { 12 throw new Error() 13 } 14 }, 15 run: function({ title }) { 16 return `Hello, ${title}` 17 } 18}) 19customValidationMethod.call({ title: 'Dr.z' }) // err
If none of these cover your use case, you can still use mixins.
Using check
You can also use Meteor's builtin check
and Match
for schema validation:
1import { check } from 'meteor/check' 2import { createMethodFactory } from 'meteor/leaonline:method-factory' 3 4const schemaFactory = schema => ({ 5 validate (args) { 6 check(args, schema) 7 } 8}) 9 10const createMethod = createMethodFactory({ schemaFactory }) 11const fancyMethod = createMethod({ 12 name: 'fancyMethod', 13 schema: { title: String }, 14 run: function({ title }) { 15 return `Hello, ${title}` 16 } 17}) 18fancyMethod.call({ title: 'Mr.x' }) // Hello, Mr.x
Note, that some definitions for
SimpleSchema
and check
/Match
may differ.
With custom ValidatedMethod
You can extend the ValidatedMethod
and pass it to the factory as well.
Note, that you need to inherit from ValidatedMethod
. Fully custom classes are not
supported.
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import { ValidatedMethod } from 'meteor/mdg:validated-method' 3import { myDefaultMixin } from '/path/to/myDefaultMixin' 4 5class CustomMethod extends ValidatedMethod { 6 constructor (options) { 7 if (options.mixins && options.mixins.length > 0) { 8 options.mixins = options.mixins.concat([myDefaultMixin]) 9 } else { 10 options.mixins = [myDefaultMixin] 11 } 12 super(options) 13 } 14} 15 16const createMethod = createMethodFactory({ custom: CustomMethod }) 17const customMethod = createMethod({ ... })
With mixins
There are three ways to define mixins:
- on the abstract factory function level, all methods created by the factory will contain these mixins
- on the factory level, you basically pass mixins the a single method
- on both levels, where mixins from the abstract factory function are executed first; no overrides
Abstract factory level mixins
If you want a certain mixin to be included for all methods created by the factory just pass them to the
createMethodFactory
function:
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import { ValidatedMethod } from 'meteor/mdg:validated-method' 3import { myDefaultMixin } from '/path/to/myDefaultMixin' 4 5const createMethod = createMethodFactory({ mixins: [myDefaultMixin] }) 6const someMethod = createMethod({ 7 name: 'methodWithMixin', 8 validate: () => {}, 9 run: () => 'result', 10 foo: 'bar' // assuming your mixin requires foo 11})
Factory level mixins
You can also define mixins for each method. This is the same as passing mixins to the ValidatedMethod
:
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import { ValidatedMethod } from 'meteor/mdg:validated-method' 3import { myDefaultMixin } from '/path/to/myDefaultMixin' 4 5const createMethod = createMethodFactory() // use defaults 6 7const methodWithMixin = createMethod({ 8 name: 'methodWithMixin', 9 mixins: [myDefaultMixin], 10 validate: () => {}, 11 run: () => 'result', 12 foo: 'bar' // assuming your mixin requires foo 13}) 14 15const methodWithoutMixin = createMethod({ 16 name: 'methodWithoutMixin', 17 validate: () => {}, 18 run: () => 'result', 19})
Use mixins on both levels
Of course you can define mixins on both levels, so that you have a certain set of default mixins and method-specific mixins:
1import { createMethodFactory } from 'meteor/leaonline:method-factory' 2import { ValidatedMethod } from 'meteor/mdg:validated-method' 3import { myDefaultMixin } from '/path/to/myDefaultMixin' 4import { someOtherMixin } from '/path/to/someOtherMixin' 5 6const createMethod = createMethodFactory({ mixins: [myDefaultMixin] }) 7 8const methodWithMixin = createMethod({ 9 name: 'methodWithMixin', 10 validate: () => {}, 11 run: () => 'result', 12 foo: 'bar' // assuming your mixin requires foo 13}) 14 15const methodWithMixins = createMethod({ 16 name: 'methodWithMixin', 17 mixins: [someOtherMixin], 18 validate: () => {}, 19 run: () => 'result', 20 foo: 'bar', // assuming your mixin requires foo 21 bar: 'baz', // assuming the other mixin requires bar 22})
Codestyle
We use standard
as code style and for linting.
via npm
$ npm install --global standard snazzy $ standard | snazzy
via Meteor npm
$ meteor npm install --global standard snazzy $ standard | snazzy
Test
We use meteortesting:mocha
to run our tests on the package.
Watch mode
$ TEST_WATCH=1 TEST_CLIENT=0 meteor test-packages ./ --driver-package meteortesting:mocha
Cli mode
License
MIT, see LICENSE