@teamplay/sharedb-schema

v0.3.24

Published

ShareDB schema validation middleware

Downloads

1,844

Readme

ShareDB-Schema

  • ShareDB plugin for schema validation
  • Uses z-schema, which supports JSON-Schema v4
  • Schema validation executes in sync validate hook, so you validate the actual result of operation
  • Supports custom validators with async and sync logic
  • Custom validators can preload data in async hook to use it later in sync

Known Issues

  • Works only with JSON OT type
  • Format functions should be sync
  • For every op the whole doc validates each time, because it`s the only case when z-schema returns full path to wrong fields

Installation

yarn add @teamplay/sharedb-schema

Setting

Step 1. Options

var options = {
  schemas: {
    users: {
      title: 'Example Schema',
      type: 'object',
      properties: {
        nickname: {
          type: 'string',
          format: 'xstring', // custom format
          minLength: 1,
          maxLength: 10,
        },
        email: {
          type: 'string',
          format: 'email',
        },
        age: {
          description: 'Age in years',
          type: 'integer',
          minimum: 0,
        },
        roleId: {
          type: 'string',
          collection: 'roles', // additional field for 'join' custom validator
          validators: ['join'], // custom validators
        },
        hobbies: {
          type: 'array',
          maxItems: 3,
          items: {
            type: 'string',
          },
          uniqueItems: true,
        },
      },
      required: ['email'],
    }
  },
  // JSON-Schema formats can be added here. They should be sync
  formats: {
    xstring: function(str) {
      return str !== 'xxx';
    }
  },
  // Custom validators
  validators: {
    // join - is working example of custom validator. It ensures that value is id of doc of specific collection
    join: {
      async: function (context, done) {
        var id = context.value // here is value for this op
        if (!id) return done()
        var collection = context.schema.collection // context.schema - is schema of current property
        var model = this.store.createModel()
        var $entity = model.at(collection + '.' + id)
        model.fetch($entity, function (err) {
          if (err) return done(err)
          if (!$entity.get()) {
            return done(Error('No ' + collection + ' with id ' + id))
          }
          done()
        })
      },
    },
    // this is example of custom validator, that preloads data and uses it later
    preload: {
      async: function (context, done) {
        var model = this.store.createModel() // that`s how to get model
        var $someData = model.at('some.path')
        model.fetch($someData, function (err) {
          if (err) return done(err)
          var data = $someData.get()
          done(null, data) // pass data as second parameter
        })
      },
      sync: function (value, context) {
        var data = context.data // preloaded data is here

        return true || false
      },
    },
  },
}

Step 2. Plugin

Add the sharedbSchemaInit function to your server/index.js

const sharedbSchemaInit = require('@teamplay/sharedb-schema')

and then call this function in the backend event

eventEmitter.on('backend', async backend => {
  sharedbSchemaInit(backend, options)
})

License

MIT

Copyright (c) 2016 Pavel Zhukov