monastery 1.30.1 → 1.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/util.js CHANGED
@@ -300,7 +300,7 @@ module.exports = {
300
300
  * @param {boolean} ignoreEmptyArrays - ignore empty arrays
301
301
  * @return obj
302
302
  */
303
- let chunks = path.split('.') // ['pets', '$', 'dog']
303
+ let chunks = path.split('.') // ['pets', '$|0-9', 'dog']
304
304
  let target = obj
305
305
  for (let i=0, l=chunks.length; i<l; i++) {
306
306
  if (l === i+1) { // Last
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "monastery",
3
3
  "description": "⛪ A straight forward MongoDB ODM built around Monk",
4
4
  "author": "Ricky Boyce",
5
- "version": "1.30.1",
5
+ "version": "1.30.2",
6
6
  "license": "MIT",
7
7
  "repository": "github:boycce/monastery",
8
8
  "homepage": "https://boycce.github.io/monastery/",
@@ -56,6 +56,9 @@ let plugin = module.exports = {
56
56
  if (model.imageFields.length) {
57
57
  // Todo?: Update image fields and whitelists with the new object schema
58
58
  // model._setupFieldsAndWhitelists(model.fields)
59
+ model.beforeValidate.push(function(data, n) {
60
+ plugin.keepImagePlacement(this, data).then(() => n(null, data)).catch(e => n(e))
61
+ })
59
62
  model.beforeUpdate.push(function(data, n) {
60
63
  plugin.removeImages(this, data).then(() => n(null, data)).catch(e => n(e))
61
64
  })
@@ -169,6 +172,32 @@ let plugin = module.exports = {
169
172
  })
170
173
  },
171
174
 
175
+ keepImagePlacement: async function(options, data) {
176
+ /**
177
+ * Hook before update/remove
178
+ * Since monastery removes undefined array items on validate, we need to convert any
179
+ * undefined array items to null where files are located to maintain image ordering
180
+ * Todo: maybe dont remove undefined array items in general
181
+ *
182
+ * E.g.
183
+ * req.body = 'photos[0]' : undefined || non existing (set to null)
184
+ * req.files = 'photos[0]' : { ...binary }
185
+ *
186
+ * @param {object} options - monastery operation options {query, model, files, multi, ..}
187
+ * @return promise
188
+ * @this plugin
189
+ */
190
+ if (typeof options.files == 'undefined') return
191
+ // Check upload errors and find valid uploaded images
192
+ let files = await plugin._findValidImages(options.files || {}, options.model)
193
+ // Set undefined primative-array items to null where files are located
194
+ for (let filesArray of files) {
195
+ if (filesArray.inputPath.match(/\.[0-9]+$/)) {
196
+ util.setDeepValue(data, filesArray.inputPath, null, true, false, true)
197
+ }
198
+ }
199
+ },
200
+
172
201
  removeImages: async function(options, data, test) {
173
202
  /**
174
203
  * Hook before update/remove
@@ -1,3 +1,5 @@
1
+ let util = require('../lib/util')
2
+
1
3
  module.exports = function(monastery, opendb) {
2
4
 
3
5
  // Data no images doesn't throw error
@@ -617,7 +619,7 @@ module.exports = function(monastery, opendb) {
617
619
  })).db
618
620
 
619
621
  let user = db.model('user', { fields: {
620
- logos: [{ type: 'image' }],
622
+ photos: [{ type: 'image' }],
621
623
  }})
622
624
 
623
625
  let image = {
@@ -630,7 +632,7 @@ module.exports = function(monastery, opendb) {
630
632
  }
631
633
 
632
634
  let user1 = await db.user._insert({
633
- logos: [image],
635
+ photos: [image],
634
636
  })
635
637
 
636
638
  let plugin = db.imagePluginFile
@@ -642,22 +644,28 @@ module.exports = function(monastery, opendb) {
642
644
 
643
645
  app.post('/', async function(req, res) {
644
646
  try {
645
- req.body.logos = JSON.parse(req.body.logos)
647
+ // Parse and validate data which is used before in update/insert
646
648
  let options = { files: req.files, model: user, query: { _id: user1._id } }
649
+ let data = await util.parseData(req.body)
650
+ data = await user.validate(data, { ...options, update: true })
651
+
652
+ // Empty photo placeholder not removed in validate?
653
+ expect(data.photos[0]).toEqual(null)
654
+ expect(data.photos[1]).toEqual(image)
647
655
 
648
656
  // Remove images
649
- let response = await plugin.removeImages(options, req.body, true)
657
+ let response = await plugin.removeImages(options, data, true)
650
658
  expect(response[0]).toEqual({ lion1: 1 }) // useCount
651
659
  expect(response[1]).toEqual([]) // unused
652
660
 
653
- // File exists
661
+ // New file exists
654
662
  let validFiles = await plugin._findValidImages(req.files, user)
655
- expect(((validFiles||[])[0]||{}).inputPath).toEqual('logos.0') // Valid inputPath
663
+ expect(((validFiles||[])[0]||{}).inputPath).toEqual('photos.0') // Valid inputPath
656
664
 
657
665
  // Add images
658
- response = await plugin.addImages(options, req.body, true)
666
+ response = await plugin.addImages(options, data, true)
659
667
  expect(response[0]).toEqual({
660
- logos: [{
668
+ photos: [{
661
669
  bucket: 'fake',
662
670
  date: expect.any(Number),
663
671
  filename: 'lion2.jpg',
@@ -683,8 +691,17 @@ module.exports = function(monastery, opendb) {
683
691
 
684
692
  await supertest(app)
685
693
  .post('/')
686
- .field('logos', JSON.stringify([ null, image ]))
687
- .attach('logos.0', `${__dirname}/assets/lion2.jpg`)
694
+ // Mock multipart/form-data syntax which is not supported by supertest (formdata sent with axios)
695
+ // E.g.
696
+ // req.body = 'photos[1][bucket]' : '...'
697
+ // req.files = 'photos[0]' : { ...binary }
698
+ .field('photos[1][bucket]', image.bucket)
699
+ .field('photos[1][date]', image.date)
700
+ .field('photos[1][filename]', image.filename)
701
+ .field('photos[1][filesize]', image.filesize)
702
+ .field('photos[1][path]', image.path)
703
+ .field('photos[1][uid]', image.uid)
704
+ .attach('photos[0]', `${__dirname}/assets/lion2.jpg`)
688
705
  .expect(200)
689
706
 
690
707
  db.close()