https://github.com/leaonline/publication-factory
Create Meteor publications. Lightweight. Simple.
https://github.com/leaonline/publication-factory
hacktoberfest meteor meteorjs pub-sub publication
Last synced: 14 days ago
JSON representation
Create Meteor publications. Lightweight. Simple.
- Host: GitHub
- URL: https://github.com/leaonline/publication-factory
- Owner: leaonline
- License: mit
- Created: 2020-04-29T17:21:14.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-09-03T10:55:51.000Z (8 months ago)
- Last Synced: 2025-03-27T05:23:55.946Z (about 1 month ago)
- Topics: hacktoberfest, meteor, meteorjs, pub-sub, publication
- Language: JavaScript
- Homepage:
- Size: 15.6 KB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Meteor Publication Factory
[](https://standardjs.com)
[](https://www.repostatus.org/#active)

Create validated Meteor publications. Lightweight. Simple.
With this package you can define factory functions to create a variety of Meteor publications.
Decouples definition from instantiation (also for the schema) and allows different configurations for different
types of publications.**Minified size < 2KB!**
## Why do I want this?
- Decouple definition from instantiation
- Validate publication arguments as with `mdg:validated-method`
- Just pass in the schema as plain object, instead of manually instantiating `SimpleSchema`
- Create mixins (similar to `mdg:validated-method`) on the abstract factory level, on the factory level, or both
(see mixins section)
- Fail silently in case of errors (uses the publication's `error` and `ready`), undefined cursors or unexpected
returntypes## Installation
Simply add this package to your meteor packages
```bash
$ meteor add leaonline:publication-factory
```## Usage
Import the `createPublicationFactory` publication and create the factory function from it:
```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { MyCollection } from '/path/to/MyCollection'const createPublication = createPublicationFactory() // no params = use defaults
const fancyPublication = createPublication({ name: 'fancy', validate: () => {}, run: () => MyCollection.find() }) // minimal required
```Under the hood it all runs like a
### 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
publications don't share the same schema instances.#### Using SimpleSchema
```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { MyCollection } from '/path/to/MyCollection'
import SimpleSchema from 'simpl-schema'const schemaFactory = definitions => new SimpleSchema(definitions)
const createPublication = createPublicationFactory({ schemaFactory })
createPublication({
name: 'fancy',
schema: { author: String },
run: function({ author }) {
return MyCollection.find({ author })
}
})
```and subcribe via
```javascript
Meteor.subscribe('fancy', { author: 'Mr.x' }) // leaving author will raise an error
```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:```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { MyCollection } from '/path/to/MyCollection'
import SimpleSchema from 'simpl-schema'const schemaFactory = definitions => new SimpleSchema(definitions)
const createPublication = createPublicationFactory({ schemaFactory })
createPublication({
name: 'fancy',
schema: { author: String },
validate: () => {},
run: function({ author }) {
return MyCollection.find({ author })
}
})
```and subcribe via
```javascript
Meteor.subscribe('fancy', {}) // leaving author will NOT raise an error
```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:
```javascript
import { check } from 'meteor/check'
import { MyCollection } from '/path/to/MyCollection'
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'const schemaFactory = schema => ({
validate (args) {
check(args, schema)
}
})const createPublication = createPublicationFactory({ schemaFactory })
createPublication({
name: 'fancy',
schema: { author: String },
run: function({ author }) {
return MyCollection.find({ author })
}
})
```Note, that some definitions for `SimpleSchema` and `check`/`Match` may differ.
### With mixins
There are three ways to define [mixins](https://github.com/meteor/validated-publication#mixins):
- on the abstract factory function level, all publications created by the factory will contain these mixins
- on the factory level, you basically pass mixins the a single publication
- 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 publications created by the factory just pass them to the
`createPublicationFactory` function:```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { ValidatedPublication } from 'meteor/mdg:validated-publication'
import { myDefaultMixin } from '/path/to/myDefaultMixin'
import { MyCollection } from '/path/to/MyCollection'const createPublication = createPublicationFactory({ mixins: [myDefaultMixin] })
createPublication({
name: 'publicationWithMixin',
validate: () => {},
run: () => MyCollection.find(),
foo: 'bar' // assuming your mixin requires foo
})
```#### Factory level mixins
You can also define mixins for each publication. This is the same as passing mixins to the `ValidatedPublication`:
```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { ValidatedPublication } from 'meteor/mdg:validated-publication'
import { myDefaultMixin } from '/path/to/myDefaultMixin'
import { MyCollection } from '/path/to/MyCollection'const createPublication = createPublicationFactory() // use defaults
createPublication({
name: 'publicationWithMixin',
mixins: [myDefaultMixin],
validate: () => {},
run: () => MyCollection.find(),
foo: 'bar' // assuming your mixin requires foo
})const publicationWithoutMixin = createPublication({
name: 'publicationWithoutMixin',
validate: () => {},
run: () => MyCollection.find(),
})
```##### 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 publication-specific
mixins:```javascript
import { createPublicationFactory } from 'meteor/leaonline:publication-factory'
import { ValidatedPublication } from 'meteor/mdg:validated-publication'
import { myDefaultMixin } from '/path/to/myDefaultMixin'
import { someOtherMixin } from '/path/to/someOtherMixin'
import { MyCollection } from '/path/to/MyCollection'const createPublication = createPublicationFactory({ mixins: [myDefaultMixin] })
const publicationWithMixin = createPublication({
name: 'publicationWithMixin',
validate: () => {},
run: () => MyCollection.find(),
foo: 'bar' // assuming your mixin requires foo
})const publicationWithMixins = createPublication({
name: 'publicationWithMixin',
mixins: [someOtherMixin],
validate: () => {},
run: () => MyCollection.find(),
foo: 'bar', // assuming your mixin requires foo
bar: 'baz', // assuming the other mixin requires bar
})
```### Error handling
With version 1.1.0 we introduced an `onError` handler, that allows to log and transform errors.
Sometimes errors are not thrown as `Meteor.Errors` and may be sent as ambiguous or confusing 500 messages
to the client.Therefore it is possible to transform errors on both, abstract factory and publication, levels.
#### Abstract factory level error handling
Add an `onError` handler to your `createPublicationFactory` invocation in order to handle any occurring error, including
validation errors and runtime errors:```javascript
const createPublication = createPublicationFactory({
onError: function(e) {
// if you want to log the error just pass it to your logger
myLogger.log(e)
// if you want to pass this error to the client
// and it's a Meteor.Error, just return it
if (e.errorType === 'Meteor.Error') {
return e
}
// if it is not a Meteor.Error but you still want to pass it
// (in this case we have a validation-error from SimpleSchema)
// just add the isClientSafe attribute to it
if (e.errorType === 'ClientError' && e.error === 'validation-error') {
e.isClientSafe = true
}
// if you like to transform if, feel free to do so
e.message = 'There was an error but we won\'t tell you about it'
// return the error on order to tell the publication to set it
// as error to be returned to client, however, you can also omit
// this and return nothing in order to let Meteor decide
return e
}
})
```#### Publication level error handling
You can also handle errors differently for each publication you create. Also note, that like with mixins, the local
definitions override the abstract factory level definitions.```javascript
const createPublication = createPublicationFactory({
onError: function(e) {
myLogger.logError(e)
}
})const publicationWithErrorHandler = createPublication({
name: 'publicationWithMixin',
validate: () => {},
run: () => MyCollection.find(),
onError: function(e) {
// for this pub we log this error with a different priority
myLogger.logFatalError(e)
}
})
```## Codestyle
We use `standard` as code style and for linting.
##### via npm
```bash
$ npm install --global standard snazzy
$ standard | snazzy
```##### via Meteor npm
```bash
$ meteor npm install --global standard snazzy
$ standard | snazzy
```## Test
We use `meteortesting:mocha` to run our tests on the package.
##### Watch mode
```bash
$ TEST_WATCH=1 TEST_CLIENT=0 meteor test-packages ./ --driver-package meteortesting:mocha
```##### Cli mode
## License
MIT, see [LICENSE](LICENSE)