monastery 1.28.5 → 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/.eslintrc.json +0 -0
- package/docs/errors.md +0 -0
- package/docs/image-plugin.md +0 -0
- package/docs/manager/model.md +0 -0
- package/docs/manager/models.md +0 -0
- package/docs/model/findOne.md +0 -0
- package/docs/model/index.md +0 -0
- package/docs/model/remove.md +0 -0
- package/docs/readme.md +1 -1
- package/docs/rules.md +0 -0
- package/lib/index.js +0 -0
- package/lib/model-crud.js +4 -4
- package/lib/model-validate.js +16 -17
- package/lib/model.js +11 -8
- package/lib/rules.js +29 -26
- package/lib/util.js +1 -1
- package/package.json +1 -1
- package/plugins/images/index.js +123 -87
- package/test/assets/bad.svg +0 -0
- package/test/assets/image.ico +0 -0
- package/test/assets/image.webp +0 -0
- package/test/assets/lion1.png +0 -0
- package/test/assets/lion2.jpg +0 -0
- package/test/assets/logo.png +0 -0
- package/test/assets/logo2.png +0 -0
- package/test/model.js +92 -3
- package/test/monk.js +0 -0
- package/test/plugin-images.js +153 -6
- package/test/populate.js +0 -0
- package/test/util.js +0 -0
- package/test/validate.js +178 -66
package/test/validate.js
CHANGED
|
@@ -19,7 +19,7 @@ module.exports = function(monastery, opendb) {
|
|
|
19
19
|
detail: 'This field is required.',
|
|
20
20
|
meta: { rule: 'required', model: 'user', field: 'name' }
|
|
21
21
|
})
|
|
22
|
-
await expect(user.validate({ name : '' }, {
|
|
22
|
+
await expect(user.validate({ name : '' }, { validateUndefined: false })).rejects.toContainEqual({
|
|
23
23
|
status: '400',
|
|
24
24
|
title: 'name',
|
|
25
25
|
detail: 'This field is required.',
|
|
@@ -27,8 +27,8 @@ module.exports = function(monastery, opendb) {
|
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
// Required error (insert, and with ignoreRequired)
|
|
30
|
-
await expect(user.validate({}, {
|
|
31
|
-
await expect(user.validate({}, {
|
|
30
|
+
await expect(user.validate({}, { validateUndefined: false })).resolves.toEqual({})
|
|
31
|
+
await expect(user.validate({}, { validateUndefined: false, update: true })).resolves.toEqual({})
|
|
32
32
|
|
|
33
33
|
// No required error (update)
|
|
34
34
|
await expect(user.validate({}, { update: true })).resolves.toEqual({})
|
|
@@ -87,77 +87,120 @@ module.exports = function(monastery, opendb) {
|
|
|
87
87
|
let db = (await opendb(false)).db
|
|
88
88
|
let user = db.model('user', { fields: {
|
|
89
89
|
animals: {
|
|
90
|
-
cat: { type: 'string', required: true },
|
|
90
|
+
cat: { type: 'string', required: true }, // {} = required on insert
|
|
91
91
|
dog: {
|
|
92
92
|
name: { type: 'string' },
|
|
93
|
-
color: { type: 'string', required: true }
|
|
93
|
+
color: { type: 'string', required: true } // {} = required on insert
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}})
|
|
97
97
|
|
|
98
|
-
//
|
|
99
|
-
await expect(user.validate({
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
// Insert: Required subdocument properties
|
|
99
|
+
await expect(user.validate({})).rejects.toEqual(
|
|
100
|
+
expect.arrayContaining([
|
|
101
|
+
expect.objectContaining({
|
|
102
|
+
status: '400',
|
|
103
|
+
title: 'animals.cat',
|
|
104
|
+
detail: 'This field is required.',
|
|
105
|
+
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
106
|
+
}),
|
|
107
|
+
expect.objectContaining({
|
|
108
|
+
status: '400',
|
|
109
|
+
title: 'animals.dog.color',
|
|
110
|
+
detail: 'This field is required.',
|
|
111
|
+
meta: { rule: 'required', model: 'user', field: 'color' }
|
|
112
|
+
}),
|
|
113
|
+
])
|
|
114
|
+
)
|
|
105
115
|
|
|
106
|
-
// Required subdocument
|
|
107
|
-
await expect(user.validate({})).rejects.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
// Insert: Required subdocument properties
|
|
117
|
+
await expect(user.validate({ animals: {} })).rejects.toEqual(
|
|
118
|
+
expect.arrayContaining([
|
|
119
|
+
expect.objectContaining({
|
|
120
|
+
status: '400',
|
|
121
|
+
title: 'animals.cat',
|
|
122
|
+
detail: 'This field is required.',
|
|
123
|
+
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
124
|
+
}),
|
|
125
|
+
expect.objectContaining({
|
|
126
|
+
status: '400',
|
|
127
|
+
title: 'animals.dog.color',
|
|
128
|
+
detail: 'This field is required.',
|
|
129
|
+
meta: { rule: 'required', model: 'user', field: 'color' }
|
|
130
|
+
}),
|
|
131
|
+
])
|
|
132
|
+
)
|
|
113
133
|
|
|
114
|
-
//
|
|
115
|
-
await expect(user.validate({})).rejects.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
134
|
+
// Insert: Invalid subdocument type
|
|
135
|
+
await expect(user.validate({ animals: { dog: 1 }})).rejects.toEqual(
|
|
136
|
+
expect.arrayContaining([
|
|
137
|
+
expect.objectContaining({
|
|
138
|
+
status: '400',
|
|
139
|
+
title: 'animals.cat',
|
|
140
|
+
detail: 'This field is required.',
|
|
141
|
+
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
142
|
+
}),
|
|
143
|
+
expect.objectContaining({
|
|
144
|
+
status: '400',
|
|
145
|
+
title: 'animals.dog',
|
|
146
|
+
detail: 'Value was not an object.',
|
|
147
|
+
meta: { rule: 'isObject', model: 'user', field: 'dog' }
|
|
148
|
+
}),
|
|
149
|
+
])
|
|
150
|
+
)
|
|
121
151
|
|
|
122
|
-
//
|
|
123
|
-
await expect(user.validate({ animals: {} }, {
|
|
124
|
-
|
|
125
|
-
title: 'animals.cat',
|
|
126
|
-
detail: 'This field is required.',
|
|
127
|
-
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
152
|
+
// Insert: Ignore required subdocument property with a defined parent
|
|
153
|
+
await expect(user.validate({ animals: {} }, { validateUndefined: false })).resolves.toEqual({
|
|
154
|
+
animals: {}
|
|
128
155
|
})
|
|
129
156
|
|
|
130
|
-
// Required subdocument property
|
|
131
|
-
await expect(user.validate({ animals: {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
157
|
+
// Update: Required subdocument property when a parent/grandparent is specified
|
|
158
|
+
await expect(user.validate({ animals: {} }, { update: true })).rejects.toEqual(
|
|
159
|
+
expect.arrayContaining([
|
|
160
|
+
expect.objectContaining({
|
|
161
|
+
status: '400',
|
|
162
|
+
title: 'animals.cat',
|
|
163
|
+
detail: 'This field is required.',
|
|
164
|
+
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
165
|
+
}),
|
|
166
|
+
expect.objectContaining({
|
|
167
|
+
status: '400',
|
|
168
|
+
title: 'animals.dog.color',
|
|
169
|
+
detail: 'This field is required.',
|
|
170
|
+
meta: { rule: 'required', model: 'user', field: 'color' }
|
|
171
|
+
}),
|
|
172
|
+
])
|
|
173
|
+
)
|
|
137
174
|
|
|
138
|
-
// Required subdocument property
|
|
139
|
-
await expect(user.validate({ animals: {} }, { update: true })).rejects.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
175
|
+
// Update: Required subdocument property when a parent is specified
|
|
176
|
+
await expect(user.validate({ animals: { dog: {}} }, { update: true })).rejects.toEqual(
|
|
177
|
+
expect.arrayContaining([
|
|
178
|
+
expect.objectContaining({
|
|
179
|
+
status: '400',
|
|
180
|
+
title: 'animals.cat',
|
|
181
|
+
detail: 'This field is required.',
|
|
182
|
+
meta: { rule: 'required', model: 'user', field: 'cat' }
|
|
183
|
+
}),
|
|
184
|
+
expect.objectContaining({
|
|
185
|
+
status: '400',
|
|
186
|
+
title: 'animals.dog.color',
|
|
187
|
+
detail: 'This field is required.',
|
|
188
|
+
meta: { rule: 'required', model: 'user', field: 'color' }
|
|
189
|
+
}),
|
|
190
|
+
])
|
|
191
|
+
)
|
|
145
192
|
|
|
146
|
-
// Ignore required subdocument property
|
|
193
|
+
// Update: Ignore required subdocument property when root parent is undefined
|
|
147
194
|
await expect(user.validate({}, { update: true })).resolves.toEqual({})
|
|
148
195
|
|
|
149
|
-
// Ignore required subdocument property with a defined parent (update) (not required if ignoreUndefined set)
|
|
150
|
-
await expect(user.validate({ animals: {} }, { ignoreUndefined: true })).resolves.toEqual({
|
|
151
|
-
animals: {}
|
|
152
|
-
})
|
|
153
196
|
|
|
154
|
-
// Ignore required subdocument property with a defined parent
|
|
155
|
-
await expect(user.validate({ animals: {} }, { update: true,
|
|
197
|
+
// Update: Ignore required subdocument property with a defined parent when validateUndefined = false
|
|
198
|
+
await expect(user.validate({ animals: {} }, { update: true, validateUndefined: false })).resolves.toEqual({
|
|
156
199
|
animals: {}
|
|
157
200
|
})
|
|
158
201
|
|
|
159
|
-
// Required subdocument property
|
|
160
|
-
await expect(user.validate({ animals: { cat: '' }}, { update: true,
|
|
202
|
+
// Update: Required defined subdocument property when validateUndefined = false
|
|
203
|
+
await expect(user.validate({ animals: { cat: '' }}, { update: true, validateUndefined: false }))
|
|
161
204
|
.rejects.toContainEqual({
|
|
162
205
|
status: '400',
|
|
163
206
|
title: 'animals.cat',
|
|
@@ -215,17 +258,17 @@ module.exports = function(monastery, opendb) {
|
|
|
215
258
|
await expect(user.validate({ animals: { dogs: [] }}))
|
|
216
259
|
.resolves.toEqual({ animals: { dogs: [] }})
|
|
217
260
|
|
|
218
|
-
// No undefined item errors with
|
|
261
|
+
// No undefined item errors with validateUndefined=false
|
|
219
262
|
await expect(user.validate(
|
|
220
263
|
{ animals: { dogs: [{ name: 'sparky' }] }},
|
|
221
|
-
{ update: true,
|
|
264
|
+
{ update: true, validateUndefined: false }
|
|
222
265
|
))
|
|
223
266
|
.resolves.toEqual({ animals: { dogs: [{ name: 'sparky' }] }})
|
|
224
267
|
|
|
225
|
-
// Requried error within an array subdocument (even during update when parent defined &&
|
|
268
|
+
// Requried error within an array subdocument (even during update when parent defined && validateUndefined = false)
|
|
226
269
|
await expect(user.validate(
|
|
227
270
|
{ animals: { dogs: [{ name: 'sparky', color: '' }] }},
|
|
228
|
-
{ update: true,
|
|
271
|
+
{ update: true, validateUndefined: false }
|
|
229
272
|
))
|
|
230
273
|
.rejects.toContainEqual(error)
|
|
231
274
|
})
|
|
@@ -481,7 +524,7 @@ module.exports = function(monastery, opendb) {
|
|
|
481
524
|
name: { type: 'string', bigName: 8 },
|
|
482
525
|
animals: [{
|
|
483
526
|
name: { type: 'string', bigName: 8 }
|
|
484
|
-
}]
|
|
527
|
+
}],
|
|
485
528
|
},
|
|
486
529
|
rules: {
|
|
487
530
|
bigName: function(value, ruleArg) {
|
|
@@ -489,6 +532,21 @@ module.exports = function(monastery, opendb) {
|
|
|
489
532
|
}
|
|
490
533
|
}
|
|
491
534
|
})
|
|
535
|
+
let user2 = db.model('user2', {
|
|
536
|
+
fields: {
|
|
537
|
+
name: { type: 'string' },
|
|
538
|
+
nickname: { type: 'string', requiredIfNoName: true },
|
|
539
|
+
age: { type: 'number', required: true },
|
|
540
|
+
},
|
|
541
|
+
rules: {
|
|
542
|
+
requiredIfNoName: {
|
|
543
|
+
validateUndefined: true,
|
|
544
|
+
fn: function(value, ruleArg) {
|
|
545
|
+
return value || this.name
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
})
|
|
492
550
|
|
|
493
551
|
// Basic field
|
|
494
552
|
await expect(user.validate({ name: 'benjamin' })).resolves.toEqual({ name: 'benjamin' })
|
|
@@ -509,6 +567,39 @@ module.exports = function(monastery, opendb) {
|
|
|
509
567
|
detail: 'Invalid data property for rule "bigName".',
|
|
510
568
|
meta: { rule: 'bigName', model: 'user', field: 'name' }
|
|
511
569
|
})
|
|
570
|
+
|
|
571
|
+
// Required rule based off another field (create)
|
|
572
|
+
await expect(user2.validate({ name: 'benjamin', age: 12 })).resolves.toEqual({
|
|
573
|
+
name: 'benjamin',
|
|
574
|
+
age: 12
|
|
575
|
+
})
|
|
576
|
+
await expect(user2.validate({ nickname: 'benny', age: 12 })).resolves.toEqual({
|
|
577
|
+
nickname: 'benny',
|
|
578
|
+
age: 12
|
|
579
|
+
})
|
|
580
|
+
await expect(user2.validate({ })).rejects.toEqual([
|
|
581
|
+
{
|
|
582
|
+
'detail': 'Invalid data property for rule "requiredIfNoName".',
|
|
583
|
+
'meta': { 'field': 'nickname', 'model': 'user2', 'rule': 'requiredIfNoName'},
|
|
584
|
+
'status': '400',
|
|
585
|
+
'title': 'nickname'
|
|
586
|
+
}, {
|
|
587
|
+
'detail': 'This field is required.',
|
|
588
|
+
'meta': { 'field': 'age', 'model': 'user2', 'rule': 'required'},
|
|
589
|
+
'status': '400',
|
|
590
|
+
'title': 'age'
|
|
591
|
+
}
|
|
592
|
+
])
|
|
593
|
+
await expect(user2.validate({ }, { validateUndefined: false })).resolves.toEqual({})
|
|
594
|
+
|
|
595
|
+
// Required rule based off another field (update)
|
|
596
|
+
await expect(user2.validate({ }, { update: true })).resolves.toEqual({})
|
|
597
|
+
await expect(user2.validate({ nickname: '' }, { update: true })).rejects.toEqual([{
|
|
598
|
+
'detail': 'Invalid data property for rule "requiredIfNoName".',
|
|
599
|
+
'meta': { 'field': 'nickname', 'model': 'user2', 'rule': 'requiredIfNoName'},
|
|
600
|
+
'status': '400',
|
|
601
|
+
'title': 'nickname'
|
|
602
|
+
}])
|
|
512
603
|
})
|
|
513
604
|
|
|
514
605
|
test('Validated data', async () => {
|
|
@@ -532,8 +623,13 @@ module.exports = function(monastery, opendb) {
|
|
|
532
623
|
// Ignores invalid data
|
|
533
624
|
await expect(user.validate({ badprop: true, schema: {} })).resolves.toEqual({})
|
|
534
625
|
|
|
535
|
-
//
|
|
536
|
-
await expect(user.validate({ name: null })).
|
|
626
|
+
// Rejects null for non object/array fields
|
|
627
|
+
await expect(user.validate({ name: null })).rejects.toEqual([{
|
|
628
|
+
'detail': 'Value was not a string.',
|
|
629
|
+
'meta': {'detailLong': undefined, 'field': 'name', 'model': 'user', 'rule': 'isString'},
|
|
630
|
+
'status':'400',
|
|
631
|
+
'title': 'name'
|
|
632
|
+
}])
|
|
537
633
|
|
|
538
634
|
// String data
|
|
539
635
|
await expect(user.validate({ name: 'Martin Luther' })).resolves.toEqual({ name: 'Martin Luther' })
|
|
@@ -556,9 +652,14 @@ module.exports = function(monastery, opendb) {
|
|
|
556
652
|
|
|
557
653
|
// Subdocument property data (null)
|
|
558
654
|
await expect(user.validate({ animals: { dog: null }}))
|
|
559
|
-
.
|
|
560
|
-
|
|
561
|
-
|
|
655
|
+
.rejects.toEqual([{
|
|
656
|
+
'detail': 'Value was not a string.',
|
|
657
|
+
'meta': {'detailLong': undefined, 'field': 'dog', 'model': 'user', 'rule': 'isString'},
|
|
658
|
+
'status': '400',
|
|
659
|
+
'title': 'animals.dog',
|
|
660
|
+
}])
|
|
661
|
+
|
|
662
|
+
// Subdocument property data (unknown data)
|
|
562
663
|
await expect(user.validate({ animals: { dog: 'sparky', cat: 'grumpy' } }))
|
|
563
664
|
.resolves.toEqual({ animals: { dog: 'sparky' } })
|
|
564
665
|
|
|
@@ -668,7 +769,12 @@ module.exports = function(monastery, opendb) {
|
|
|
668
769
|
await expect(user2.validate({ amount: 0 })).resolves.toEqual({ amount: 0 }) // required
|
|
669
770
|
await expect(user.validate({ amount: '0' })).resolves.toEqual({ amount: 0 }) // required
|
|
670
771
|
await expect(user.validate({ amount: undefined })).resolves.toEqual({}) // not required
|
|
671
|
-
await expect(user.validate({ amount: null })).
|
|
772
|
+
await expect(user.validate({ amount: null })).rejects.toEqual([{ // type error
|
|
773
|
+
'detail': 'Value was not a number.',
|
|
774
|
+
'meta': { 'field': 'amount', 'model': 'user', 'rule': 'isNumber'},
|
|
775
|
+
'status': '400',
|
|
776
|
+
'title': 'amount'
|
|
777
|
+
}])
|
|
672
778
|
|
|
673
779
|
// Number required
|
|
674
780
|
let mock1 = {
|
|
@@ -734,6 +840,12 @@ module.exports = function(monastery, opendb) {
|
|
|
734
840
|
}})
|
|
735
841
|
|
|
736
842
|
// Subdocument data (null/string)
|
|
843
|
+
await expect(user.validate({ animals: 'notAnObject' })).rejects.toEqual([{
|
|
844
|
+
'detail': 'Value was not an object.',
|
|
845
|
+
'meta': {'detailLong': undefined, 'field': 'animals', 'model': 'user', 'rule': 'isObject'},
|
|
846
|
+
'status': '400',
|
|
847
|
+
'title': 'animals'
|
|
848
|
+
}])
|
|
737
849
|
await expect(user.validate({ animals: '', names: null })).resolves.toEqual({ animals: null, names: null })
|
|
738
850
|
|
|
739
851
|
db.close()
|