JSPM

  • Created
  • Published
  • Downloads 32138
  • Score
    100M100P100Q152592F
  • License MIT

Useful hooks for use with Feathersjs services.

Package Exports

  • feathers-hooks-common
  • feathers-hooks-common/lib/bundled
  • feathers-hooks-common/lib/index
  • feathers-hooks-common/lib/utils

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (feathers-hooks-common) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

feathers-hooks-common

Useful hooks for use with Feathersjs services.

Build Status Coverage Status

Data Items

(1) Join a related item to result (after hook).

  • Supports multiple result items, including paginated find.
  • Supports key field with an array of keys.
  • Supports multiple joins.
const hooks = require('feathers-hooks-common');
module.exports.after = {
  // add prop 'user' containing the user item who's key is in 'senderId'.
  all: [ hooks.populate('user', { field: 'senderId', service: '/users' }) ]
};

(2) Remove fields from data.

  • Field names support dot notation e.g. 'name.address.city'
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.after = {
  all: [ hooks.remove('verifyToken', 'verifyExpires', (hook) => true) ]
};

(3) Retain only selected fields in data.

  • Field names support dot notation
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.after = {
  all: [ hooks.pluck('employee.name', 'employee.email',
           (hook) => new Promise(resolve => setTimeout(() => resolve(true), 100)) ]
};

(4) Convert fields to lower case.

  • Field names support dot notation
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.after = {
  all: [ hooks.lowerCase('email') ]
};

(5) Add created at timestamp.

  • Field names support dot notation
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.before = {
  create: [ hooks.setCreatedAt('createdAt') ]
};

(6) Add or update the updated at timestamp.

  • Field names support dot notation
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.before = {
  create: [ hooks.setUpdatedAt('updatedAt') ]
};

Query params

(1) Remove criteria from query (before hook).

  • Field names support dot notation
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.before = {
  all: [ hooks.removeQuery('sex') ]
};

(2) Retain only selected criteria in query (before hook).

  • Field names support dot notation.
  • Supports multiple data items, including paginated find.
  • May be dynamically disabled, using either a sync or promise based function.
module.exports.before = {
  all: [ hooks.removeQuery('employee.dept') ]
};

Validation

Fidelity and code reuse are improved if the server can rerun validation code written for the front-end.

  • Support is provided for sync, callback and promise based validation routines.
  • Optionally replace the data with sanitized values.

(1) Invoke a synchronous validation routine (before; create, update, patch).

const usersClientValidation = (values) => values.email ? null : { email: 'Email is invalid' };

module.exports.before = {
  create: [ hooks.validateSync(usersClientValidations) ] // redo client sync validation
};

(2) Invoke a callback based validation routine (before; create, update, patch).

const usersServerValidation = (values, param2, cb) => {
  setTimeout(() => {
    values.email.trim()
      ? cb(null, { ...values, email: values.email.trim() }) // sanitize data
      : cb({ email: 'Email is invalid' });
  }, 100);
};

module.exports.before = {
  create: [ hooks.validateUsingCallback(usersServerValidations, 'value4param2') ] // server only
};

(3) Invoke a promise based validation routine (before; create, update, patch).

const usersServerValidation = (values, ...rest) => (
  new Promise((resolve, reject) => {
    setTimeout(() => {
      values.email.trim()
        ? resolve({ ...values, email: values.email.trim() })
        : reject(new errors.BadRequest({ email: 'Email is invalid' }));
    }, 100);
  })
);

module.exports.before = {
  create: [ hooks.validateUsingPromise(usersClientAsync) ] // redo client async validation
};

Note:

The structure of the data object should be checked before any validation is performed. Several schema validation packages are available.

Authorization

(1) Disable hook

  • Disable service completely, from all external providers, or from certain providers.
  • Service be dynamically disabled, using either a sync or promise based function.
module.exports.before = {
  patch: [ hooks.disable('socketio', 'rest') ],
  create: [ hooks.disable((hook) => new Promise(resolve => resolve(true) )) ]
};

(2) Authorize access by role. Convenience wrapper for feathers-authentication.hooks.restrictToRoles.

  • Clean, clear and DRY.
const authorizer = hooks.restrictToRoles(['inv', 'ship'], 'userAuthorizedRoles', false, 'userId');

module.exports.before = {
  all: [ authorizer() ]
  create: [ authorizer(['purch']) ]
};

Utilities

(1) Normalize the URL slug (before).

Copy the slug from raw HTTP requests, e.g. https://.../stores/:storeid/... to where other providers typically store it. Dot notation is supported.

module.exports.before = {
  create: [ hooks.setSlug('storeid') ]
};

(2) Display current info about the hook to console.

module.exports.after = {
  create: [ hooks.setUpdatedAt('step 1') ]
};
// * step 1
// type: before, method: create
// data: { name: 'Joe Doe' }
// query: { sex: 'm' }
// result: { assigned: true }

Motivation

Feathers services can be developed faster if the hooks you need are at hand.

This package provides some commonly needed hooks.

Installation

Install Nodejs.

Run npm install feathers-hooks-common --save in your project folder.

/src on GitHub contains the ES6 source. It will run on Node 6+ without transpiling.

API Reference

Each file fully documents its module's API.

Tests

npm test to run tests.

npm run cover to run tests plus coverage.

Contributing

Guide to ideomatic contributing.

License

MIT. See LICENSE.