From 6cfe877884ff8d3727b7d1c393fefb70bbc8836a Mon Sep 17 00:00:00 2001 From: Mahdi Dibaiee Date: Fri, 29 Jan 2016 11:30:39 +0330 Subject: [PATCH] feat(include): include query parameter, passed to sequelize query fix(associations): one-to-many associations -> destroyScope and get --- package.json | 2 +- src/associations/one-to-many.js | 146 +++++++++++++++++++++++++------- src/associations/one-to-one.js | 11 ++- src/crud.js | 57 +++++++++++-- 4 files changed, 176 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 83585e5..789cefb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hapi-sequelize-crud", - "version": "1.3.1", + "version": "1.4.0", "description": "Hapi plugin that automatically generates RESTful API for CRUD", "main": "build/index.js", "config": { diff --git a/src/associations/one-to-many.js b/src/associations/one-to-many.js index 0a5e2a9..733ec33 100644 --- a/src/associations/one-to-many.js +++ b/src/associations/one-to-many.js @@ -1,18 +1,50 @@ import joi from 'joi'; import error from '../error'; +import _ from 'lodash'; let prefix; export default (server, a, b, options) => { prefix = options.prefix; + get(server, a, b); list(server, a, b); scope(server, a, b); scopeScope(server, a, b); destroy(server, a, b); + destroyScope(server, a, b); update(server, a, b); } +export const get = (server, a, b) => { + server.route({ + method: 'GET', + path: `${prefix}/${a._singular}/{aid}/${b._singular}/{bid}`, + + @error + async handler(request, reply) { + let include = []; + if (request.query.include) + include = [request.models[request.query.include]]; + + let instance = await b.findOne({ + where: { + id: request.params.bid + }, + + include: include.concat({ + where: { + id: request.params.aid + }, + model: a + }) + }); + + reply(list); + } + }) +} + export const list = (server, a, b) => { server.route({ method: 'GET', @@ -20,15 +52,21 @@ export const list = (server, a, b) => { @error async handler(request, reply) { - let list = await b.findAll({ - include: [{ - model: a, - where: { - id: request.params.aid, + let include = []; + if (request.query.include) + include = [request.models[request.query.include]]; - ...request.query - } - }] + let where = _.omit(request.query, 'include'); + + let list = await b.findAll({ + where, + + include: include.concat({ + where: { + id: request.params.aid + }, + model: a + }) }); reply(list); @@ -45,15 +83,20 @@ export const scope = (server, a, b) => { @error async handler(request, reply) { - let list = await b.scope(request.params.scope).findAll({ - include: [{ - model: a, - where: { - id: request.params.aid, + let include = []; + if (request.query.include) + include = [request.models[request.query.include]]; - ...request.query - } - }] + let where = _.omit(request.query, 'include'); + + let list = await b.scope(request.params.scope).findAll({ + where, + include: include.concat({ + where: { + id: request.params.aid + }, + model: a + }) }); reply(list); @@ -82,13 +125,17 @@ export const scopeScope = (server, a, b) => { @error async handler(request, reply) { + let include = []; + if (request.query.include) + include = [request.models[request.query.include]]; + + let where = _.omit(request.query, 'include'); + let list = await b.scope(request.params.scopeb).findAll({ - include: [{ - model: a.scope(request.params.scopea), - where: { - ...request.query - } - }] + where, + include: include.concat({ + model: a.scope(request.params.scopea) + }) }) reply(list); @@ -112,24 +159,63 @@ export const destroy = (server, a, b) => { @error async handler(request, reply) { + let where = _.omit(request.query, 'include'); + let list = await b.findAll({ - include: [{ + where, + include: { model: a, where: { - id: request.params.aid, - - ...request.query + id: request.params.aid } - }] + } }); await* list.map(instance => instance.destroy()); - reply(); + reply(list); } }) } +export const destroyScope = (server, a, b) => { + let scopes = Object.keys(b.options.scopes); + + server.route({ + method: 'DELETE', + path: `${prefix}/${a._singular}/{aid}/${b._plural}/{scope}`, + + @error + async handler(request, reply) { + let where = _.omit(request.query, 'include'); + + let list = await b.scope(request.params.scope).findAll({ + where, + + include: { + model: a, + where: { + id: request.params.aid + } + } + }); + + await* list.map(instance => instance.destroy()); + + reply(list); + }, + + config: { + validate: { + params: joi.object().keys({ + scope: joi.string().valid(...scopes), + aid: joi.number().integer().required() + }) + } + } + }); +} + export const update = (server, a, b) => { server.route({ method: 'PUT', @@ -138,14 +224,14 @@ export const update = (server, a, b) => { @error async handler(request, reply) { let list = await b.findOne({ - include: [{ + include: { model: a, where: { id: request.params.aid, ...request.query } - }] + } }); await* list.map(instance => instance.update(request.payload)); diff --git a/src/associations/one-to-one.js b/src/associations/one-to-one.js index a93b2a9..130ed56 100644 --- a/src/associations/one-to-one.js +++ b/src/associations/one-to-one.js @@ -1,5 +1,6 @@ import joi from 'joi'; import error from '../error'; +import _ from 'lodash'; let prefix; @@ -19,13 +20,17 @@ export const get = (server, a, b) => { @error async handler(request, reply) { + let include = []; + if (request.query.include) + include = [request.models[request.query.include]]; + let instance = await b.findOne({ - include: [{ + include: include.concat({ model: a, where: { id: request.params.aid } - }] + }) }); reply(instance); @@ -70,7 +75,7 @@ export const destroy = (server, a, b) => { await instance.destroy(); - reply(); + reply(instance); } }) } diff --git a/src/crud.js b/src/crud.js index 2b2b99b..fa31ba3 100644 --- a/src/crud.js +++ b/src/crud.js @@ -1,5 +1,6 @@ import joi from 'joi'; import error from './error'; +import _ from 'lodash'; let prefix; @@ -11,6 +12,7 @@ export default (server, model, options) => { scope(server, model); create(server, model); destroy(server, model); + destroyScope(server, model); update(server, model); } @@ -21,8 +23,13 @@ export const list = (server, model) => { @error async handler(request, reply) { + if (request.query.include) + var include = [request.models[request.query.include]]; + + let where = _.omit(request.query, 'include'); + let list = await model.findAll({ - where: request.query + where, include }); reply(list); @@ -37,9 +44,12 @@ export const get = (server, model) => { @error async handler(request, reply) { - let where = request.params.id ? { id : request.params.id } : request.query; + if (request.query.include) + var include = [request.models[request.query.include]]; - let instance = await model.findOne({ where }); + let where = request.params.id ? { id : request.params.id } : _.omit(request.query, 'include'); + + let instance = await model.findOne({ where, include }); reply(instance); }, @@ -62,7 +72,12 @@ export const scope = (server, model) => { @error async handler(request, reply) { - let list = await model.scope(request.params.scope).findAll(); + if (request.query.include) + var include = [request.models[request.query.include]]; + + let where = _.omit(request.query, 'include'); + + let list = await model.scope(request.params.scope).findAll({ include, where }); reply(list); }, @@ -103,15 +118,45 @@ export const destroy = (server, model) => { await* list.map(instance => instance.destroy()); - reply(); + reply(list.length === 1 ? list[0] : list); } }) } +export const destroyScope = (server, model) => { + let scopes = Object.keys(model.options.scopes); + + server.route({ + method: 'DELETE', + path: `${prefix}/${model._plural}/{scope}`, + + @error + async handler(request, reply) { + if (request.query.include) + var include = [request.models[request.query.include]]; + + let where = _.omit(request.query, 'include'); + + let list = await model.scope(request.params.scope).findAll({ include, where }); + + await* list.map(instance => instance.destroy()); + + reply(list); + }, + config: { + validate: { + params: joi.object().keys({ + scope: joi.string().valid(...scopes) + }) + } + } + }); +} + export const update = (server, model) => { server.route({ method: 'PUT', - path: `/v1/${model._singular}/{id}`, + path: `${prefix}/${model._singular}/{id}`, @error async handler(request, reply) {