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