monastery 1.40.3 → 1.40.5

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/changelog.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [1.40.5](https://github.com/boycce/monastery/compare/1.40.4...1.40.5) (2023-02-22)
6
+
7
+ ### [1.40.4](https://github.com/boycce/monastery/compare/1.40.3...1.40.4) (2022-12-21)
8
+
5
9
  ### [1.40.3](https://github.com/boycce/monastery/compare/1.40.2...1.40.3) (2022-12-21)
6
10
 
7
11
  ### [1.40.2](https://github.com/boycce/monastery/compare/1.40.1...1.40.2) (2022-12-15)
@@ -43,7 +43,7 @@ let user = db.model('user', {
43
43
  })
44
44
  ```
45
45
 
46
- Then when inserting or updating a document you need to set `files` to an obkect containing containing your parsed files, [express-fileupload](https://github.com/richardgirges/express-fileupload) works great with an express setup, e.g.
46
+ Then when inserting or updating a document you need to set `options.files` to an object containing your parsed files, [express-fileupload](https://github.com/richardgirges/express-fileupload) works great with an express setup, e.g.
47
47
 
48
48
  ```js
49
49
  user.update({
@@ -53,7 +53,13 @@ user.update({
53
53
  })
54
54
  ```
55
55
 
56
- When updating, you need to make sure you always pass all of your image objects again back into `data` since any images not found will be removed automatically from your S3 bucket. A nice way to handle image/non-image updates is by appending `?files=true` to your API route calls, e.g.
56
+ ### Updating documents
57
+
58
+ When updating a document with `options.files`, you need to make sure to **always** include previously uploaded file objects in `options.data` otherwise these will be removed automatically from your S3 bucket (via a comparsion check against your previous document).
59
+
60
+ You can reuse the image objects (e.g. `{ bucket, data, uid, ... }`) for other file field values on the same document. You can't however copy image objects across documents and collections.
61
+
62
+ You can skip all file processing by not defining `options.files`. A nice way to sepearte file and non-file updates is by appending ?files=true to your API route calls, e.g.
57
63
 
58
64
  ```js
59
65
  user.update({
package/docs/readme.md CHANGED
@@ -95,17 +95,12 @@ Coming soon...
95
95
  - Automatic embedded document ids/createdAt/updatedAt fields
96
96
  - ~~Ability to change ACL default on the manager~~
97
97
  - ~~Public db.arrayWithSchema method~~
98
- - ~~Added support for array population~~
99
- - Change population warnings into errors
100
98
  - Global after/before hooks
101
99
  - before hooks can receive a data array, remove this
102
100
  - docs: Make the implicit ID query conversion more apparent
103
101
  - Split away from Monk (unless updated)
104
102
  - Add a warning if an invalid model is referenced in jthe schema
105
- - Allow rules on image types, e.g. `required`
106
- - test importing of models
107
- - Docs: model.methods
108
- -
103
+ - Remove leading forward slashes from custom image paths (AWS adds this as a seperate folder)
109
104
 
110
105
  ## Versions
111
106
 
package/lib/model-crud.js CHANGED
@@ -89,37 +89,13 @@ module.exports = {
89
89
  if (util.isObject(item)) {
90
90
  lookups.push({ $lookup: item })
91
91
  } else {
92
- let arrayTarget
93
- let arrayCount = 0
94
- let schema = path.split('.').reduce((o, i) => {
95
- if (util.isArray(o[i])) {
96
- arrayCount++
97
- arrayTarget = true
98
- return o[i][0]
99
- } else {
100
- arrayTarget = false
101
- return o[i]
102
- }
103
- }, this.fields)
104
- let modelName = (schema||{}).model
92
+ let modelName = (path.split('.').reduce((o,i) => o[i], this.fields) ||{}).model
105
93
  if (!modelName) {
106
94
  this.error(
107
95
  `The field "${path}" passed to populate is not of type model. You would ` +
108
96
  'need to add the field option e.g. { model: \'comment\' } in your schema.'
109
97
  )
110
98
  continue
111
- } else if (arrayCount > 1) {
112
- this.error(
113
- `You cannot populate on array's nested in array's: ${path}: ` +
114
- `{ model: "${modelName}" }`
115
- )
116
- continue
117
- } else if (arrayCount == 1 && !arrayTarget) {
118
- this.error(
119
- `You cannot populate within an array of sub-documents: ${path}: ` +
120
- `{ model: "${modelName}" }`
121
- )
122
- continue
123
99
  } else if (!this.manager.model[modelName]) {
124
100
  this.error(
125
101
  `The field's model defined in your schema does not exist: ${path}: ` +
@@ -127,11 +103,8 @@ module.exports = {
127
103
  )
128
104
  continue
129
105
  }
130
- // Convert array into a document for non-array targets
131
- if (!arrayTarget) {
132
- (opts.addFields = opts.addFields || {})[path] = { '$arrayElemAt': [ '$' + path, 0 ] }
133
- }
134
- // Create lookup
106
+ // Populate model (convert array into document & create lookup)
107
+ (opts.addFields = opts.addFields || {})[path] = { '$arrayElemAt': [ '$' + path, 0 ] }
135
108
  lookups.push({ $lookup: {
136
109
  from: modelName,
137
110
  localField: path,
@@ -529,9 +502,6 @@ module.exports = {
529
502
  let parentModelData = util.toArray(data).map(o => ({ modelName: this.name, dataRef: o }))
530
503
  let modelData = this._recurseAndFindModels(this.fields, data).concat(parentModelData)
531
504
 
532
- // Need to remove ////////////////// make sure blacklist default fields on populated arrays dont show
533
- console.log(modelData)
534
-
535
505
  // Loop found model/deep-model data objects, and populate missing default-fields and call afterFind on each
536
506
  for (let item of modelData) {
537
507
  // Populate missing default fields if data !== null
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.40.3",
5
+ "version": "1.40.5",
6
6
  "license": "MIT",
7
7
  "repository": "github:boycce/monastery",
8
8
  "homepage": "https://boycce.github.io/monastery/",
@@ -322,7 +322,8 @@ let plugin = module.exports = {
322
322
  // valid image-object?
323
323
  if (typeof useCount[image.image.uid] == 'undefined') {
324
324
  throw `The passed image object for '${image.dataPath}' does not match any pre-existing
325
- images saved on this document.`
325
+ images saved on this document. Make sure that this image dosen't come from another document or
326
+ collection, and is indeed saved on this document.`
326
327
  // Different image from prexisting image
327
328
  } else if (preExistingImage && preExistingImage.image.uid != image.image.uid) {
328
329
  useCount[preExistingImage.image.uid]--
package/test/crud.js CHANGED
@@ -460,7 +460,6 @@ module.exports = function(monastery, opendb) {
460
460
  addresses: [{ city: { type: 'string' }, country: { type: 'string', default: 'Germany' } }],
461
461
  address: { country: { type: 'string', default: 'Germany' }},
462
462
  pet: { dog: { model: 'dog' }},
463
- pets: { dog: [{ model: 'dog' }]},
464
463
  dogs: [{ model: 'dog' }], // virtual association
465
464
  }
466
465
  })
@@ -490,20 +489,18 @@ module.exports = function(monastery, opendb) {
490
489
  // Note that addresses.1.country shouldn't be overridden
491
490
  // Insert documents (without defaults)
492
491
  let dog1 = await db.dog._insert({})
493
- let dog2 = await db.dog._insert({})
494
492
  let user1 = await db.user._insert({
495
493
  addresses: [
496
494
  { city: 'Frankfurt' },
497
495
  { city: 'Christchurch', country: 'New Zealand' }
498
496
  ],
499
- pet: { dog: dog1._id },
500
- pets: { dog: [dog1._id, dog2._id]},
497
+ pet: { dog: dog1._id }
501
498
  })
502
499
  await db.dog._update(dog1._id, { $set: { user: user1._id }})
503
500
 
504
501
  let find1 = await db.user.findOne({
505
502
  query: user1._id,
506
- populate: ['pet.dog', 'pets.dog', {
503
+ populate: ['pet.dog', {
507
504
  from: 'dog',
508
505
  localField: '_id',
509
506
  foreignField: 'user',
@@ -519,25 +516,19 @@ module.exports = function(monastery, opendb) {
519
516
  ],
520
517
  address: { country: 'Germany' },
521
518
  pet: { dog: { _id: dog1._id, name: 'Scruff', user: user1._id }},
522
- pets: {
523
- dog: [
524
- { _id: dog1._id, name: 'Scruff', user: user1._id },
525
- { _id: dog2._id, name: 'Scruff' },
526
- ]
527
- },
528
519
  dogs: [{ _id: dog1._id, name: 'Scruff', user: user1._id }]
529
520
  })
530
521
 
531
522
  // Blacklisted default field population test
532
523
  let find2 = await db.user.findOne({
533
524
  query: user1._id,
534
- populate: ['pet.dog', 'pets.dog', {
525
+ populate: ['pet.dog', {
535
526
  from: 'dog',
536
527
  localField: '_id',
537
528
  foreignField: 'user',
538
- as: 'dogs',
529
+ as: 'dogs'
539
530
  }],
540
- blacklist: ['address', 'addresses.country', 'pets.dog.name', 'dogs.name'],
531
+ blacklist: ['address', 'addresses.country', 'dogs.name']
541
532
  // ^ great test (address should cancel addresses if not stopping at the .)
542
533
  })
543
534
  expect(find2).toEqual({
@@ -545,20 +536,14 @@ module.exports = function(monastery, opendb) {
545
536
  name: 'Martin Luther',
546
537
  addresses: [{ city: 'Frankfurt' }, { city: 'Christchurch' }],
547
538
  pet: { dog: { _id: dog1._id, name: 'Scruff', user: user1._id }},
548
- dogs: [{ _id: dog1._id, user: user1._id }],
549
- pets: {
550
- dog: [
551
- { _id: dog1._id, user: user1._id }, //////////////////get this working
552
- { _id: dog2._id },
553
- ]
554
- },
539
+ dogs: [{ _id: dog1._id, user: user1._id }]
555
540
  })
556
541
 
557
542
  db.close()
558
543
  })
559
544
 
560
545
  test('findOneAndUpdate general', async () => {
561
- // todo: test all findOneAndUpdate options (e.g. array population)
546
+ // todo: test all findOneAndUpdate options
562
547
  // todo: test find & update hooks
563
548
  let db = (await opendb(null)).db
564
549
  let dog = db.model('dog', {
package/test/populate.js CHANGED
@@ -82,78 +82,6 @@ module.exports = function(monastery, opendb) {
82
82
  db.close()
83
83
  })
84
84
 
85
- test('model populate array', async () => {
86
- // Setup
87
- let db = (await opendb(null)).db
88
- let bird = db.model('bird', { fields: {
89
- name: { type: 'string' }
90
- }})
91
- let user = db.model('user', { fields: {
92
- birds: [{ model: 'bird' }],
93
- animal: { birds: [{ model: 'bird' }] },
94
- animals: [{ bird: { model: 'bird' }, num: { type: 'number' } }],
95
- }})
96
- let bird1 = await bird.insert({ data: { name: 'ponyo' }})
97
- let bird2 = await bird.insert({ data: { name: 'jack' }})
98
- let bird3 = await bird.insert({ data: { name: 'sophie' }})
99
- let user1 = await user.insert({ data: {
100
- birds: [bird1._id, bird2._id],
101
- animal: { birds: [bird1._id, bird2._id] },
102
- animals: [{ bird: bird1._id, num: 1 }, { bird: bird3._id, num: 2 }],
103
- }})
104
-
105
- // Array
106
- let find1 = await user.findOne({ query: user1._id, populate: ['birds'] })
107
- expect(find1).toEqual({
108
- _id: user1._id,
109
- birds: [
110
- { _id: bird1._id, name: 'ponyo' },
111
- { _id: bird2._id, name: 'jack' },
112
- ],
113
- animal: {
114
- birds: [bird1._id, bird2._id],
115
- },
116
- animals: [
117
- { bird: bird1._id, num: 1 },
118
- { bird: bird3._id, num: 2 },
119
- ],
120
- })
121
-
122
- // Nested array
123
- let find2 = await user.findOne({ query: user1._id, populate: ['animal.birds'] })
124
- expect(find2).toEqual({
125
- _id: user1._id,
126
- birds: [bird1._id, bird2._id],
127
- animal: {
128
- birds: [
129
- { _id: bird1._id, name: 'ponyo' },
130
- { _id: bird2._id, name: 'jack' },
131
- ],
132
- },
133
- animals: [
134
- { bird: bird1._id, num: 1 },
135
- { bird: bird3._id, num: 2 },
136
- ],
137
- })
138
-
139
- // modelId within an array of subdocuments (won't populate, but show a debug error)
140
- user.error = () => {} // hide debug error
141
- let find3 = await user.findOne({ query: user1._id, populate: ['animals.bird'] })
142
- expect(find3).toEqual({
143
- _id: user1._id,
144
- birds: [bird1._id, bird2._id],
145
- animal: {
146
- birds: [bird1._id, bird2._id],
147
- },
148
- animals: [
149
- { bird: bird1._id, num: 1 },
150
- { bird: bird3._id, num: 2 },
151
- ],
152
- })
153
-
154
- db.close()
155
- })
156
-
157
85
  test('model populate type=any', async () => {
158
86
  let db = (await opendb(null)).db
159
87
  db.model('company', { fields: {