controller.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. const _ = require('lodash')
  2. const defaults = require('./defaults')
  3. const { Op } = require('sequelize')
  4. const crudController = (opts) => {
  5. opts = defaults(opts)
  6. const { Type } = opts
  7. const subset = async (req) => {
  8. const subset = {}
  9. const params = _.toPairs(req.params)
  10. .map(([key, value])=>({key, value}))
  11. .filter(({value}) => value !== opts.paramAll)
  12. for (let { key, value } of params) {
  13. const assoc = Type.associations[key]
  14. if (assoc) {
  15. subset[assoc.foreignKey] = (await assoc.target.findOne({
  16. parameters: ['id'],
  17. where: { key: value }
  18. })).id
  19. }
  20. }
  21. return subset
  22. }
  23. const list = async (req, res) => {
  24. // TODO Pagination (http://docs.sequelizejs.com/manual/tutorial/querying.html#pagination-limiting)
  25. if (req.query && req.query.q) {
  26. const fields = [Type.tableAttributes.name, Type.tableAttributes.tag].filter(x => x)
  27. if (!fields) throw new Error('Table has no searchable fields')
  28. const or = fields.map(field => ({
  29. [field.fieldName]: { [Op.like]: `%${req.query.q}%` }
  30. }))
  31. const where = { ...subset, [Op.or]: or }
  32. const data = (await Type.findAll({ where })).map(d => d.sanitize ? d.sanitize() : d)
  33. res.status(200).send(data)
  34. } else if (res.query && res.query.ids) {
  35. const ids = res.query.ids.split(',')
  36. const data = (await Type.findAll({where: { ...(await subset(req)), id: { [Op.in]: ids }}})).map(d => d.sanitize ? d.sanitize() : d)
  37. res.status(200).send(data)
  38. } else {
  39. const data = (await Type.findAll({where: { ...(await subset(req)) }})).map(d => d.sanitize ? d.sanitize() : d)
  40. res.status(200).send(data)
  41. }
  42. }
  43. const create = async (req, res) => {
  44. const data = (await Type.create(req.body))
  45. res.status(200).send(data && data.sanitize ? data.sanitize() : data)
  46. }
  47. const read = async (req, res) => {
  48. const data = (await Type.findOne({where: {id: req.params[opts.routeParam]}}))
  49. res.status(200).send(data && data.sanitize ? data.sanitize() : data)
  50. }
  51. const update = async (req, res) => {
  52. const data = (await Type.update(req.body, { where: { id: req.params[opts.routeParam] } }))
  53. res.status(200).send(data && data.sanitize ? data.sanitize() : data)
  54. }
  55. const $delete = async (req, res) => {
  56. const data = (await Type.destroy({ where: { id: req.params[opts.routeParam] } }))
  57. res.status(204).end()
  58. }
  59. const trash = async (req, res) => {
  60. const data = (await Type.findAll({
  61. model: Type,
  62. paranoid: false,
  63. where: {
  64. ...(await subset(req)),
  65. deletedAt: { [Op.ne]: null }
  66. }
  67. }))
  68. res.status(200).send(data && data.sanitize ? data.sanitize() : data)
  69. }
  70. const undelete = async (req, res) => {
  71. const data = (await Type.update({ deletedAt: null }, {
  72. paranoid: false,
  73. where: { id: req.params[opts.routeParam] }
  74. }))
  75. res.status(200).send(data && data.sanitize ? data.sanitize() : data)
  76. }
  77. // TODO: Create, Read, Update, Delete
  78. return {
  79. list,
  80. create,
  81. read,
  82. update,
  83. delete: $delete,
  84. trash,
  85. undelete
  86. }
  87. }
  88. module.exports = crudController