Supporter class to create publications from a source object with minimal to no extra code.
Installation
1meteor add jkuester:publication-factory
Changelog
1.2.0
- Allow to pass custom validator functions vor
query
andprojection
with fallback to internal default validation.
1.1.1
- fixed check to comply auditAllArguments and still accept undefined query / projection args from subscription
1.1.0
- lint fix using standardjs
- merged publication arguments from two to one on order to support single object args on subscriptions
Principle
Pass in an object of your publication definitions with respect to the given API.
The factory will return a function that is ready to be passed to Meteor.publish
and will behave according to your
configuration.
API
The create
functio requires at least an object, referred as params
in this guide.
Note, that params.collectionName
is currently the only required property to be passed.
All other properties are optional! Such a publication would default to return all documents and accepts no args from subscriptions.
All Parameters
The basic paramater pattern is
1PublicationFactory.create(params)
which can be fully broken down to the following schema:
1PublicationFactory.create({ 2 3 // the collection to be published 4 collectionName: String, 5 6 // define query behavior 7 query: { 8 9 // describe the allowed query args 10 // using a schema descriptiom 11 schema: Object, 12 13 // describe the default query, the server 14 // will execute if no transform is applied 15 server: Object, 16 17 // provide a function that conditionally applies client 18 // queries on server queries. You can also include strict 19 // or loose security checks here as a third layer of security 20 transform: Function 21 }, 22 projection: { 23 24 // describe the allowed projection args 25 // using a schema descriptiom 26 schema: Object, 27 28 // describe the default projection, the server 29 // will execute if no transform is applied 30 server: Object, 31 32 // provide a function that conditionally applies client 33 // projection on server projection. You can also include strict 34 // or loose security checks here as a third layer of security 35 transform: Function 36 37 }, 38 security: { 39 40 // explicitly disable authentication check 41 // so the publication runs also for non-registered users 42 disable: Boolean, 43 44 // define roles that registered users need to comply 45 // in order to publish. 46 roles: [String], 47 48 // define a group that registered users need to comply 49 // in order to publish. 50 group: String, 51 }, 52 validators: { 53 54 // custom validation for the 55 // client side query 56 query: Function, 57 58 // custom validation for the 59 // client side projection 60 projection: Function, 61 } 62})
params.collectionName (String)
Pass the name of a collection for which you want to publish data. If no other parameters are passed, the whole collection's data will be published.
Example
1const Cars = new Mongo.Collection('cars') 2 3const allCars = PublicationFactory.create({ 4 collectionName: 'cars', // the collection to be published 5}) 6 7// publishing this will 8// return all cars, and 9// accept no args from subscriptions 10Meteor.publish("allCars", allCars)
params.query (Object)
You can define query behavior including transforming queries based on data, passed by clients.
params.query.server (Object)
You can define a static query using the server
property. This is useful when your publication always publishes data
by the same set of rules.
Falls back to {}
if nothing is passed.
params.query.schema (Object)
Restrict client's query options using schema definition that is conform to check/Match
.
Basic SimpleSchema
definitions can be used, too, as they both follow the property:Constructor
pattern.
Complex restrictions however, can also be set using Match
pattern.
params.query.transform (Function)
You can use this to define dynamic queries that respects users input and the default query on the server. You can also perform additional checks here.
Pass a function that accepts two parameters (queryClient
- the current client's query object that is passed to the pub,
queryServer
- the default server query) and return your final query.
Example
1const Cars = new Mongo.Collection('cars'); 2 3const redCarsByYear = PublicationFactory.create({ 4 collectionName: 'cars', // the collection to be published 5 query: { 6 schema: { year: Number }, 7 server: { color: 'red' }, 8 transform(queryClient, queryServer) { 9 return Object.assign({}, { year: { $gt: queryClient.year }, queryServer}) 10 } 11 } 12}) 13 14// this would create a publication that 15// returns all car docs with color=red by a 16// given year 17Meteor.publish("redCarsByYear", redCarsByYear)
params.projection (Object)
Works the same way as params.query
but for the projection values. Use transform
to add custom logic for handling
skip
, limit
etc.
params.security (Object)
The create method's parameter object accepts several security settings using the security
property.
By default each publication is checking this.userId
against Meteor.users
and throws an error if failing.
params.security.roles (String or [String])
Add roles (uses alanning:roles
) and optional group definition to security
to also check against roles. If no
roles
property is given, no roles check will be performed.
params.security.group (String)
Optional group definition as defined by alanning:roles
.
params.security.users ([String])
- You can add an array of user ids, named
users
tosecurity
in order to restrict for specific users.
This array can also be used in combination with roles
where roles
is first checked and then users
.
If a user passes the roles check but is not in the given pool of users, the check will fail. If no users
property
is given, no check will be performed.
params.security.disable (Boolean)
- Add
disable:true
tosecurity
in order to surpass all prior mentioned security checks. In this case anyone can
subscribe to the publication and view data. Use with care!
Example
1const Cars = new Mongo.Collection('cars'); 2 3const prototypeCars = PublicationFactory.create({ 4 collectionName: 'cars', // the collection to be published 5 security: { 6 roles: ['viewPrototypes'], 7 group: 'researchers', 8 members: ['someUserIdHere'], 9 disable: false, 10 } 11}); 12 13 14Meteor.publish("allToys", allToys);
params.validators
With version 1.2.0 it is supported to pass in custom validators. This solves the problem of providing a way for validating complex structures while keeping the package free of external dependencies.
params.validators.query
Runs a function that provides the current client query against the expected schema. Throw an error or return a falsey value in order to
Example using SimpleSchema
Note, that SimpleSchema is optional to this package and needs to be installed, if you want to use it.
1const Cars = new Mongo.Collection('cars'); 2 3const carsByYearSchemaDefinition = { 4 year: Number, 5 min: 1769, 6 max: new Date().getFullYear() 7} 8 9const carsByYearSchema = new SimplSchema(carsByYearSchemaDefinition) 10 11const carsByYear = PublicationFactory.create({ 12 collectionName: 'cars', // the collection to be published 13 query: { 14 schema: carsByYearSchemaDefinition, 15 }, 16 validators: { 17 query(clientQuery, querySchema) { 18 // throws error if not valid 19 carsByYearSchema.validate(clientQuery) 20 return true 21 } 22 } 23}); 24 25 26Meteor.publish("carsByYear", carsByYear);
params.validators.projection
The same principles apply to this function as for params.validators.query