Skip to content

Latest commit

 

History

History
280 lines (197 loc) · 10.7 KB

plugins.md

File metadata and controls

280 lines (197 loc) · 10.7 KB

Adding plugins

To handle server-side logic and custom behaviours, you can add plugins that we provide, or create your own if you like.

Provided plugins

We provide the following plugins. More are coming!

  1. Login Plugin
  2. Security Plugin
  3. Stripe Plugin

Express middleware

As a matter of facts, you can also provide a list of express middleware directly when creating the server. They will be merged with the plugins middlewares.

const app = express();
const middleware = (req, res, next) => next();
const middlewares = [middleware];
createServer({app, tables, database, rules, plugins, middlewares});

Create your own plugin

A plugin consist in an object containing the following optional properties:

  • preRequisite : A function that will make sure that the plugin is correctly configured.
  • middleware : A middleware that might intercept the whole request.
  • onRequest : An object containing functions being called before any request in a specific table.
  • onProcessing : An object containing functions being called after the execution of every depending request, but before any changes have been applied to the current results.
  • onCreation : An object containing functions being called each time an element is created into a specific table.
  • onDeletion : An object containing functions being called each time an element is deleted from a specific table.
  • onResult : An object containing functions being called after a request was resolved in a specific table.
  • onUpdate : An object containing functions being called after data have been changed in a specific table.
  • onListUpdate : An object containing functions being called after some objects have been linked or unlinked to existing objects of the specified tables.
  • onSuccess : An object containing functions being called when a request succeeds to resolve in a specific table.
  • onError : An object containing functions being called when a request failed to resolve in a specific table.
  • onResponse : A function being called after the whole request was resolved, just before commiting the changes in the database and returning the results to the client.
  • errorHandler : A middleware able to handle errors generated by this plugin before being sent to the user.

Prerequisite

This should be a function taking the tables as a parameter. It should then return a Promise that would reject if the plugin configuration is wrong given the provided tables. For instance, if the userTable that have been provided upon creation is actually not present in the tables object.

function preRequisite(tables) { return Promise.resolve(); }

middleware

This is exactly an express middleware.

function middleware(req, res, next) { return Promise.reject().catch(next).then(() => next()); }

onRequest

This is an object describing all the functions that should be called when a request starts on any table. It will receive the onEvent parameters as second parameter.

const onRequest = {
    User : (request, {parent, query, local, isAdmin}) => Promise.resolve()
}

onProcessing

This is an object describing all the functions that should be called after the depending requests, the get and create instructions have been resolved, but before the set, delete, add and remove instructions have been executed. The results are the elements found in the database that match the constraints up to now. It will receive the onEvent parameters as second parameter.

const onProcessing = {
    User : (results, {request, parent, query, local, isAdmin}) => Promise.resolve()
}

Notice: This won't be called when using readOnly option in query.

onUpdate

This is an object describing all the functions that should be called when some objects are updated inside any table. It will receive an object containing details about the update, and onEvent parameters as second parameter.

Details:

  • objects : The objects currently beeing updated
  • newValues : An object containing the new values for each field
  • oldValues : An object mapping the objects ids to the old values of that object for each field

Example:

Imagine the following table:

    const User = {};
    Object.assign(User, {
        name : 'string/40'
    });

You could create the following plugin:

{
  onUpdate: {
    User : ({objects, newValues: { name: newName }, oldValues}, {request, parent, query, local, isAdmin}) => {
      objects.forEach(user => console.log(`User ${user.reservedId} changed name from ${oldValues[user.reservedId]} to ${newName}.`));
    }
  }
}

onListUpdate

This is an object describing all the functions that should be called when some objects are linked or unlincked to an object inside the table. It will receive an object containing details about the modifications, and onEvent parameters as second parameter.

Details:

  • objects : The objects concerned with the modifications
  • added : An object containing the list of objects being added to each field
  • removed : An object containing the list of objects being removed to each field

Example:

Imagine the following table:

    const User = {};
    Object.assign(User, {
        name : 'string/40',
        contacts : [User],
    });

You could create the following plugin:

{
  onListUpdate: {
    User : ({objects: [ myUser ], added, removed}, {request, parent, query, local, isAdmin}) => {
      objects.forEach(user => {
        added.contacts && added.contacts.forEach(contact => console.log(`User ${contact.name} was added to the contacts of ${user.name}.`));
        removed.contacts && removed.contacts.forEach(contact => console.log(`User ${contact.name} was removed from the contacts of ${user.name}.`));
      });
    }
  }
}

onCreation

This is an object describing all the functions that should be called when an object is created inside any table. It will receive the newly created object, and onEvent parameters as second parameter.

const onCreation = {
    User : (createdObject, {request, parent, query, local, isAdmin}) => Promise.resolve()
}

onDeletion

This is an object describing all the functions that should be called when an object is deleted from any table. It will receive the list of deleted objects and onEvent parameters as second parameter.

const onDeletion = {
    User : (deletedObjectsArray, {request, parent, query, local, isAdmin}) => Promise.resolve()
}

onResult

This is an object describing all the functions that should be called when a request has been fully executed in any table. It will receive the list of results matching the request, and onEvent parameters as second parameter.

const onResult = {
    User : (results, {request, parent, query, local, isAdmin}) => Promise.resolve()
}

onSuccess

This callback is called when the whole request will succeed and the changes will be committed to the database. It will receive the onEvent parameters as second parameter. It is probably not recommanded to throw an error at this point.

const onSuccess = (results, {request, query, local, isAdmin }) => Promise.resolve()

onError

This callback is called when the whole request will fail and the changes made to the database will be rolled back. It will receive the onEvent parameters as second parameter.

const onError = (error, {request, query, local, isAdmin}) => Promise.resolve()

errorHandler

This is an express errorHandler.

function middleware(err, req, res, next) { return next(err); }

onEvent parameter

The onEvent parameter consist of an object containing the following properties

  • request : The request currently being executed.
  • parent : The parent of the request currently being executed.
  • isAdmin : A boolean indicating if the current request is being executed as an administrator.
  • query : A function that you can use to make a SimpleQL query to the database.
  • local : The current request local variables (like authId). You can read them or edit them directly through this object.

parent

This is the parent of the current request part.

Consider the following request:

    {
      Feed : {
        participants : [
          { email : 'user1@email.com' },
          { email : 'user2@email.com' },
        ],
        comments : {
          add : {
            create : true,
            content : 'test',
            title : 'Test',
            author: {
              email : 'user2@email.com',
            }
          }
        }
      }
    }

This request will create a comment inside the Comment table, and add this comment to the Feed table. The parent of the Comment request is the Feed request. This will be the value of parent:

      {
        participants : [
          { email : 'user1@email.com' },
          { email : 'user2@email.com' },
        ],
        comments : {
          add : {
            create : true,
            content : 'test',
            title : 'Test',
            author: {
              email : 'user2@email.com',
            }
          }
        }
      }

isAdmin

This is a boolean indicating if the current request is being executed with admin rights. You can use this to avoid looping into your event handler. Especially for onRequest and onResult

query

The query function provided can be used to make SimpleQL requests to the database. This function takes 2 parameters: the SimpleQL request, and an optional object having the following properties:

  • admin (boolean : default false) : indicate that the request should be made with admin credentials. Be careful, this will ignore all access rules.
  • readOnly (boolean : default false) : indicate that the request should only read data and is not allowed to make any change to the database.

local

This objects provide the local variables used through the request. You can read the values or edit them by updating the object. Right now, the only parameter that you can change is the authId.

For instance:

local.authId = privateKey; //This will make the request executed with admin rights from now on.

This would make the complete request being executed as admin. (this should be avoided at all cost!)