diff --git a/README.md b/README.md index 32c94ad..d0ebc5e 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,37 @@ await register({ options: { prefix: '/v1', name: 'db', // the same name you used for configuring `hapi-sequelize` (options.name) - defaultConfig: { ... } // passed as `config` to all routes created + defaultConfig: { ... }, // passed as `config` to all routes created + + // You can specify which models must have routes defined for using the + // `models` property. If you omit this property, all models will have + // models defined for them. e.g. + models: ['cat', 'dog'] // only the cat and dog models will have routes created + // or + models: { + // possible methods: list, get, scope, create, destroy, destroyAll, destroyScope, update + cat: ['get', 'list'], // the cat model only has get and list methods enabled + dog: true, // the dog model has all methods enabled + bat: { + methods: ['list'], + config: { ... } // if provided, overrides the default config + } + } } }); ``` +### Methods +* list: get all rows in a table +* get: get a single row +* scope: reference a [sequelize scope](http://docs.sequelizejs.com/en/latest/api/model/#scopeoptions-model) +* create: create a new row +* destroy: delete a row +* destroyAll: delete all models in the table +* destroyScope: use a [sequelize scope](http://docs.sequelizejs.com/en/latest/api/model/#scopeoptions-model) to find rows, then delete them +* update: update a row + + Please note that you should register `hapi-sequelize-crud` after defining your associations. diff --git a/src/crud.js b/src/crud.js index a34b274..84abafc 100644 --- a/src/crud.js +++ b/src/crud.js @@ -3,25 +3,66 @@ import error from './error'; import _ from 'lodash'; import { parseInclude, parseWhere } from './utils'; import { notFound } from 'boom'; +import * as associations from './associations/index'; -let prefix; -let defaultConfig; - -export default (server, model, options) => { - prefix = options.prefix; - defaultConfig = options.defaultConfig; - - list(server, model); - get(server, model); - scope(server, model); - create(server, model); - destroy(server, model); - destroyAll(server, model); - destroyScope(server, model); - update(server, model); +const createAll = ({ server, model, prefix, config }) => { + Object.keys(methods).forEach((method) => { + methods[method]({ server, model, prefix, config }); + }); }; -export const list = (server, model) => { +export { associations }; + +/* +The `models` option, becomes `permissions`, and can look like: + +``` +models: ['cat', 'dog'] +``` + +or + +``` +models: { + cat: ['list', 'get'] + , dog: true // all +} +``` + +*/ + +export default (server, model, { prefix, defaultConfig: config, models: permissions }) => { + const modelName = model._singular; + + if (!permissions) { + createAll({ server, model, prefix, config }); + } else if (Array.isArray(permissions) && permissions.includes(modelName)) { + createAll({ server, model, prefix, config }); + } else if (_.isPlainObject(permissions)) { + const permittedModels = Object.keys(permissions); + + if (permissions[modelName] === true) { + createAll({ server, model, prefix, config }); + } else if (permittedModels.includes(modelName)) { + if (Array.isArray(permissions[modelName])) { + permissions[modelName].forEach((method) => { + methods[method]({ server, model, prefix, config }); + }); + } else if (_.isPlainObject(permissions[modelName])) { + permissions[modelName].methods.forEach((method) => { + methods[method]({ + server, + model, + prefix, + config: permissions[modelName].config || config, + }); + }); + } + } + } +}; + +export const list = ({ server, model, prefix, config }) => { server.route({ method: 'GET', path: `${prefix}/${model._plural}`, @@ -40,11 +81,11 @@ export const list = (server, model) => { reply(list); }, - config: defaultConfig, + config, }); }; -export const get = (server, model) => { +export const get = ({ server, model, prefix, config }) => { server.route({ method: 'GET', path: `${prefix}/${model._singular}/{id?}`, @@ -68,11 +109,11 @@ export const get = (server, model) => { id: joi.any(), }), }, - }, defaultConfig), + }, config), }); }; -export const scope = (server, model) => { +export const scope = ({ server, model, prefix, config }) => { const scopes = Object.keys(model.options.scopes); server.route({ @@ -94,11 +135,11 @@ export const scope = (server, model) => { scope: joi.string().valid(...scopes), }), }, - }, defaultConfig), + }, config), }); }; -export const create = (server, model) => { +export const create = ({ server, model, prefix, config }) => { server.route({ method: 'POST', path: `${prefix}/${model._singular}`, @@ -110,11 +151,11 @@ export const create = (server, model) => { reply(instance); }, - config: defaultConfig, + config, }); }; -export const destroy = (server, model) => { +export const destroy = ({ server, model, prefix, config }) => { server.route({ method: 'DELETE', path: `${prefix}/${model._singular}/{id?}`, @@ -131,11 +172,11 @@ export const destroy = (server, model) => { reply(list.length === 1 ? list[0] : list); }, - config: defaultConfig, + config, }); }; -export const destroyAll = (server, model) => { +export const destroyAll = ({ server, model, prefix, config }) => { server.route({ method: 'DELETE', path: `${prefix}/${model._plural}`, @@ -151,11 +192,11 @@ export const destroyAll = (server, model) => { reply(list.length === 1 ? list[0] : list); }, - config: defaultConfig, + config, }); }; -export const destroyScope = (server, model) => { +export const destroyScope = ({ server, model, prefix, config }) => { const scopes = Object.keys(model.options.scopes); server.route({ @@ -179,11 +220,11 @@ export const destroyScope = (server, model) => { scope: joi.string().valid(...scopes), }), }, - }, defaultConfig), + }, config), }); }; -export const update = (server, model) => { +export const update = ({ server, model, prefix, config }) => { server.route({ method: 'PUT', path: `${prefix}/${model._singular}/{id}`, @@ -208,9 +249,10 @@ export const update = (server, model) => { validate: { payload: joi.object().required(), }, - }, defaultConfig), + }, config), }); }; -import * as associations from './associations/index'; -export { associations }; +const methods = { + list, get, scope, create, destroy, destroyAll, destroyScope, update, +};