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/.eslintrc.json
CHANGED
|
File without changes
|
package/docs/errors.md
CHANGED
|
File without changes
|
package/docs/image-plugin.md
CHANGED
|
File without changes
|
package/docs/manager/model.md
CHANGED
|
File without changes
|
package/docs/manager/models.md
CHANGED
|
File without changes
|
package/docs/model/findOne.md
CHANGED
|
File without changes
|
package/docs/model/index.md
CHANGED
|
File without changes
|
package/docs/model/remove.md
CHANGED
|
File without changes
|
package/docs/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/monastery) [](https://travis-ci.com/boycce/monastery)
|
|
3
|
+
[](https://www.npmjs.com/package/monastery) [](https://app.travis-ci.com/github/boycce/monastery)
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
package/docs/rules.md
CHANGED
|
File without changes
|
package/lib/index.js
CHANGED
|
File without changes
|
package/lib/model-crud.js
CHANGED
|
@@ -9,7 +9,7 @@ module.exports = {
|
|
|
9
9
|
* @param {object|array} <opts.data> - documents to insert
|
|
10
10
|
* @param {array|string|false} <opts.blacklist> - augment schema.insertBL, `false` will remove all blacklisting
|
|
11
11
|
* @param {boolean} <opts.respond> - automatically call res.json/error (requires opts.req)
|
|
12
|
-
* @param {array|string|
|
|
12
|
+
* @param {array|string|false} validateUndefined - ignore all required fields during insert, or
|
|
13
13
|
* undefined subdocument required fields that have a defined parent/grandparent during update
|
|
14
14
|
* @param {array|string|true} <opts.skipValidation> - skip validation for this field name(s)
|
|
15
15
|
* @param {boolean} <opts.timestamps> - whether `createdAt` and `updatedAt` are automatically inserted
|
|
@@ -23,7 +23,7 @@ module.exports = {
|
|
|
23
23
|
opts.model = this
|
|
24
24
|
let data = opts.data = opts.data || (opts.req? opts.req.body : {})
|
|
25
25
|
let options = util.omit(opts, [
|
|
26
|
-
'data', 'insert', 'model', 'respond', '
|
|
26
|
+
'data', 'insert', 'model', 'respond', 'validateUndefined', 'skipValidation', 'blacklist'
|
|
27
27
|
])
|
|
28
28
|
if (cb && !util.isFunction(cb)) {
|
|
29
29
|
throw new Error(`The callback passed to ${this.name}.insert() is not a function`)
|
|
@@ -194,7 +194,7 @@ module.exports = {
|
|
|
194
194
|
* @param {object} <opts.query> - mongodb query object
|
|
195
195
|
* @param {object|array} <opts.data> - mongodb document update object(s)
|
|
196
196
|
* @param {boolean} <opts.respond> - automatically call res.json/error (requires opts.req)
|
|
197
|
-
* @param {array|string|
|
|
197
|
+
* @param {array|string|false} validateUndefined - ignore all required fields during insert, or
|
|
198
198
|
* undefined subdocument required fields that have a defined parent/grandparent during update
|
|
199
199
|
* @param {array|string|true} <opts.skipValidation> - skip validation for this field name(s)
|
|
200
200
|
* @param {boolean} <opts.timestamps> - whether `updatedAt` is automatically updated
|
|
@@ -215,7 +215,7 @@ module.exports = {
|
|
|
215
215
|
data = opts.data = opts.data || (opts.req? opts.req.body : null)
|
|
216
216
|
operators = util.pluck(opts, [/^\$/])
|
|
217
217
|
// Operation options
|
|
218
|
-
options = util.omit(opts, ['data', 'query', 'respond', '
|
|
218
|
+
options = util.omit(opts, ['data', 'query', 'respond', 'validateUndefined', 'skipValidation', 'blacklist'])
|
|
219
219
|
options.sort = options.sort || { 'createdAt': -1 }
|
|
220
220
|
options.limit = parseInt(options.limit || 0)
|
|
221
221
|
// Sort string passed
|
package/lib/model-validate.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = {
|
|
|
12
12
|
* @param {boolean(false)} update - are we validating for insert or update?
|
|
13
13
|
* @param {array|string|false} blacklist - augment schema blacklist, `false` will remove all blacklisting
|
|
14
14
|
* @param {array|string} projection - only return these fields, ignores blacklist
|
|
15
|
-
* @param {array|string|
|
|
15
|
+
* @param {array|string|false} validateUndefined - ignore all required fields during insert, or undefined
|
|
16
16
|
* subdocument required fields that have a defined parent/grandparent during update
|
|
17
17
|
* @param {array|string|true} skipValidation - skip validation on these fields
|
|
18
18
|
* @param {boolean} timestamps - whether `createdAt` and `updatedAt` are inserted, or `updatedAt` is
|
|
@@ -177,7 +177,11 @@ module.exports = {
|
|
|
177
177
|
// Object schema errors
|
|
178
178
|
errors.push(...(verrors = this._validateRules(dataRoot, schema, value, opts, path2)))
|
|
179
179
|
// Recurse if data value is a subdocument, or when inserting, or when updating deep properties (non-root)
|
|
180
|
-
if (
|
|
180
|
+
if (
|
|
181
|
+
util.isObject(value) ||
|
|
182
|
+
opts.insert ||
|
|
183
|
+
((path2||'').match(/\./) && (util.isDefined(opts.validateUndefined) ? opts.validateUndefined : true))
|
|
184
|
+
) {
|
|
181
185
|
var res = this._validateFields(dataRoot, field, value, opts, path2)
|
|
182
186
|
errors.push(...res[0])
|
|
183
187
|
}
|
|
@@ -213,6 +217,7 @@ module.exports = {
|
|
|
213
217
|
* @param {object} dataRoot - data
|
|
214
218
|
* @param {object} field - field schema
|
|
215
219
|
* @param {string} path - full field path
|
|
220
|
+
* @param {object} opts - original validate() options
|
|
216
221
|
* @this model
|
|
217
222
|
* @return {array} errors
|
|
218
223
|
*/
|
|
@@ -242,38 +247,32 @@ module.exports = {
|
|
|
242
247
|
|
|
243
248
|
for (let ruleName in field) {
|
|
244
249
|
if (this._ignoredRules.indexOf(ruleName) > -1) continue
|
|
245
|
-
|
|
246
|
-
if (util.isUndefined(value) && ((opts.update && !path.match(/\./)) || opts.ignoreUndefined)) continue
|
|
247
|
-
let error = this._validateRule(dataRoot, ruleName, field, field[ruleName], value, path)
|
|
250
|
+
let error = this._validateRule(dataRoot, ruleName, field, field[ruleName], value, opts, path)
|
|
248
251
|
if (error && ruleName == 'required') return [error] // only show the required error
|
|
249
252
|
if (error) errors.push(error)
|
|
250
253
|
}
|
|
251
254
|
return errors
|
|
252
255
|
},
|
|
253
256
|
|
|
254
|
-
_validateRule: function(dataRoot, ruleName, field, ruleArg, value, path) {
|
|
255
|
-
//this.debug(path, field, ruleName, ruleArg, value)
|
|
257
|
+
_validateRule: function(dataRoot, ruleName, field, ruleArg, value, opts, path) {
|
|
258
|
+
// this.debug(path, field, ruleName, ruleArg, value)
|
|
256
259
|
// Remove [] from the message path, and simply ignore non-numeric children to test for all array items
|
|
257
260
|
ruleArg = ruleArg === true? undefined : ruleArg
|
|
258
261
|
let rule = this.rules[ruleName] || rules[ruleName]
|
|
259
262
|
let fieldName = path.match(/[^.]+$/)[0]
|
|
260
263
|
let ruleMessageKey = this._getMostSpecificKeyMatchingPath(this.messages, path)
|
|
261
264
|
let ruleMessage = ruleMessageKey && this.messages[ruleMessageKey][ruleName]
|
|
265
|
+
let validateUndefined = util.isDefined(opts.validateUndefined) ? opts.validateUndefined : rule.validateUndefined
|
|
262
266
|
if (!ruleMessage) ruleMessage = rule.message
|
|
263
267
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
if (typeof value === 'undefined') return
|
|
268
|
+
// Ignore undefined (if updated root property, or ignoring)
|
|
269
|
+
if ((!validateUndefined || (opts.update && !path.match(/\./))) && typeof value === 'undefined') return
|
|
267
270
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
// Ignore null if nullObject is set on objects or arrays
|
|
272
|
-
if (value === null && field.nullObject) return
|
|
273
|
-
}
|
|
271
|
+
// Ignore null (if nullObject is set on objects or arrays) (todo: change to ignoreNull)
|
|
272
|
+
if (field.nullObject && (field.isObject || field.isArray) && value === null) return
|
|
274
273
|
|
|
275
274
|
// Ignore empty strings
|
|
276
|
-
if (value === ''
|
|
275
|
+
if (!rule.validateEmptyString && value === '') return
|
|
277
276
|
|
|
278
277
|
// Rule failed
|
|
279
278
|
if (!rule.fn.call(dataRoot, value, ruleArg, path, this)) return {
|
package/lib/model.js
CHANGED
|
@@ -61,6 +61,7 @@ let Model = module.exports = function(name, opts, manager) {
|
|
|
61
61
|
// Update with formatted rule
|
|
62
62
|
let formattedRule = util.isObject(rule)? rule : { fn: rule }
|
|
63
63
|
if (!formattedRule.message) formattedRule.message = `Invalid data property for rule "${ruleName}".`
|
|
64
|
+
if (typeof formattedRule.validateEmptyString == 'undefined') formattedRule.validateEmptyString = true
|
|
64
65
|
this.rules[ruleName] = formattedRule
|
|
65
66
|
}
|
|
66
67
|
}, this)
|
|
@@ -241,11 +242,10 @@ Model.prototype._setupFieldsAndWhitelists = function(fields, path) {
|
|
|
241
242
|
this.findBLProject = this.findBL.reduce((o, v) => { (o[v] = 0); return o }, {})
|
|
242
243
|
},
|
|
243
244
|
|
|
244
|
-
Model.prototype._setupIndexes = function(fields) {
|
|
245
|
+
Model.prototype._setupIndexes = function(fields, opts={}) {
|
|
245
246
|
/**
|
|
246
|
-
* Creates indexes for the model
|
|
247
|
+
* Creates indexes for the model (multikey, and sub-document supported)
|
|
247
248
|
* Note: only one text index per model(collection) is allowed due to mongodb limitations
|
|
248
|
-
* Note: we and currently don't support indexes on sub-collections, but sub-documents yes!
|
|
249
249
|
* @link https://docs.mongodb.com/manual/reference/command/createIndexes/
|
|
250
250
|
* @link https://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#createIndexes
|
|
251
251
|
* @param {object} <fields>
|
|
@@ -278,6 +278,7 @@ Model.prototype._setupIndexes = function(fields) {
|
|
|
278
278
|
recurseFields(fields || model.fields, '')
|
|
279
279
|
// console.log(2, indexes, fields)
|
|
280
280
|
if (hasTextIndex) indexes.push(textIndex)
|
|
281
|
+
if (opts.dryRun) return Promise.resolve(indexes || [])
|
|
281
282
|
if (!indexes.length) return Promise.resolve([]) // No indexes defined
|
|
282
283
|
|
|
283
284
|
// Create indexes
|
|
@@ -330,22 +331,24 @@ Model.prototype._setupIndexes = function(fields) {
|
|
|
330
331
|
util.forEach(fields, (field, name) => {
|
|
331
332
|
let index = field.index
|
|
332
333
|
if (index) {
|
|
333
|
-
let path = name == 'schema'? parentPath.slice(0, -1) : parentPath + name
|
|
334
334
|
let options = util.isObject(index)? util.omit(index, ['type']) : {}
|
|
335
335
|
let type = util.isObject(index)? index.type : index
|
|
336
|
+
let path = name == 'schema'? parentPath.slice(0, -1) : parentPath + name
|
|
337
|
+
let path2 = path.replace(/(^|\.)[0-9]+(\.|$)/g, '$2') // no numirical keys, e.g. pets.1.name
|
|
336
338
|
if (type === true) type = 1
|
|
337
|
-
|
|
338
339
|
if (type == 'text') {
|
|
339
|
-
hasTextIndex = textIndex.key[
|
|
340
|
+
hasTextIndex = textIndex.key[path2] = 'text'
|
|
340
341
|
Object.assign(textIndex, options)
|
|
341
342
|
} else if (type == '1' || type == '-1' || type == '2dsphere') {
|
|
342
|
-
indexes.push({ name: `${
|
|
343
|
+
indexes.push({ name: `${path2}_${type}`, key: { [path2]: type }, ...options })
|
|
343
344
|
} else if (type == 'unique') {
|
|
344
|
-
indexes.push({ name: `${
|
|
345
|
+
indexes.push({ name: `${path2}_1`, key: { [path2]: 1 }, unique: true, ...options })
|
|
345
346
|
}
|
|
346
347
|
}
|
|
347
348
|
if (util.isSubdocument(field)) {
|
|
348
349
|
recurseFields(field, parentPath + name + '.')
|
|
350
|
+
} else if (util.isArray(field)) {
|
|
351
|
+
recurseFields(field, parentPath + name + '.')
|
|
349
352
|
}
|
|
350
353
|
})
|
|
351
354
|
}
|
package/lib/rules.js
CHANGED
|
@@ -5,6 +5,8 @@ let validator = require('validator')
|
|
|
5
5
|
module.exports = {
|
|
6
6
|
|
|
7
7
|
required: {
|
|
8
|
+
validateUndefined: true,
|
|
9
|
+
validateEmptyString: true,
|
|
8
10
|
message: 'This field is required.',
|
|
9
11
|
fn: function(x) {
|
|
10
12
|
if (util.isArray(x) && !x.length) return false
|
|
@@ -12,9 +14,10 @@ module.exports = {
|
|
|
12
14
|
}
|
|
13
15
|
},
|
|
14
16
|
|
|
15
|
-
//
|
|
17
|
+
// Type rules below ignore undefined (default for custom model rules)
|
|
16
18
|
|
|
17
19
|
'isBoolean': {
|
|
20
|
+
validateEmptyString: true,
|
|
18
21
|
message: 'Value was not a boolean.',
|
|
19
22
|
tryParse: function(x) {
|
|
20
23
|
if (typeof x === 'string' && x === 'true') return true
|
|
@@ -25,13 +28,8 @@ module.exports = {
|
|
|
25
28
|
return typeof x === 'boolean'
|
|
26
29
|
}
|
|
27
30
|
},
|
|
28
|
-
'isNotEmptyString': {
|
|
29
|
-
message: 'Value was an empty string.',
|
|
30
|
-
fn: function(x) {
|
|
31
|
-
return x !== ''
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
31
|
'isArray': {
|
|
32
|
+
validateEmptyString: true,
|
|
35
33
|
message: 'Value was not an array.',
|
|
36
34
|
tryParse: function(x) {
|
|
37
35
|
if (x === '') return null
|
|
@@ -44,6 +42,7 @@ module.exports = {
|
|
|
44
42
|
}
|
|
45
43
|
},
|
|
46
44
|
'isDate': {
|
|
45
|
+
validateEmptyString: true,
|
|
47
46
|
message: 'Value was not a unix timestamp.',
|
|
48
47
|
tryParse: function(x) {
|
|
49
48
|
if (util.isString(x) && x.match(/^[+-]?[0-9]+$/)) return x // keep string nums intact
|
|
@@ -55,6 +54,7 @@ module.exports = {
|
|
|
55
54
|
}
|
|
56
55
|
},
|
|
57
56
|
'isImageObject': {
|
|
57
|
+
validateEmptyString: true,
|
|
58
58
|
message: 'Invalid image value',
|
|
59
59
|
messageLong: 'Image fields need to either be null, undefined, file, or an object containing the following '
|
|
60
60
|
+ 'fields \'{ bucket, date, filename, filesize, path, uid }\'',
|
|
@@ -70,6 +70,7 @@ module.exports = {
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
'isInteger': {
|
|
73
|
+
validateEmptyString: true,
|
|
73
74
|
message: 'Value was not an integer.',
|
|
74
75
|
tryParse: function(x) {
|
|
75
76
|
if (util.isString(x) && x.match(/^[+-][0-9]+$/)) return x // keep string nums intact
|
|
@@ -81,6 +82,7 @@ module.exports = {
|
|
|
81
82
|
}
|
|
82
83
|
},
|
|
83
84
|
'isNumber': {
|
|
85
|
+
validateEmptyString: true,
|
|
84
86
|
message: 'Value was not a number.',
|
|
85
87
|
tryParse: function(x) {
|
|
86
88
|
if (util.isString(x) && x.match(/^[+-][0-9]+$/)) return x // keep string nums intact
|
|
@@ -92,6 +94,7 @@ module.exports = {
|
|
|
92
94
|
}
|
|
93
95
|
},
|
|
94
96
|
'isObject': {
|
|
97
|
+
validateEmptyString: true,
|
|
95
98
|
message: 'Value was not an object.',
|
|
96
99
|
tryParse: function(x) {
|
|
97
100
|
if (x === '') return null
|
|
@@ -104,18 +107,21 @@ module.exports = {
|
|
|
104
107
|
}
|
|
105
108
|
},
|
|
106
109
|
'isString': {
|
|
110
|
+
validateEmptyString: true,
|
|
107
111
|
message: 'Value was not a string.',
|
|
108
112
|
fn: function(x) {
|
|
109
113
|
return typeof x === 'string'
|
|
110
114
|
}
|
|
111
115
|
},
|
|
112
116
|
'isAny': {
|
|
117
|
+
validateEmptyString: true,
|
|
113
118
|
message: '',
|
|
114
119
|
fn: function(x) {
|
|
115
120
|
return true
|
|
116
121
|
}
|
|
117
122
|
},
|
|
118
123
|
'isId': {
|
|
124
|
+
validateEmptyString: true,
|
|
119
125
|
message: 'Value was not a valid ObjectId.',
|
|
120
126
|
tryParse: function(x) {
|
|
121
127
|
// Try and parse value to a mongodb ObjectId
|
|
@@ -130,6 +136,7 @@ module.exports = {
|
|
|
130
136
|
}
|
|
131
137
|
},
|
|
132
138
|
'max': {
|
|
139
|
+
validateEmptyString: true,
|
|
133
140
|
message: (x, arg) => 'Value was greater than the configured maximum (' + arg + ')',
|
|
134
141
|
fn: function(x, arg) {
|
|
135
142
|
if (typeof x !== 'number') { throw new Error ('Value was not a number.') }
|
|
@@ -137,16 +144,25 @@ module.exports = {
|
|
|
137
144
|
}
|
|
138
145
|
},
|
|
139
146
|
'min': {
|
|
147
|
+
validateEmptyString: true,
|
|
140
148
|
message: (x, arg) => 'Value was less than the configured minimum (' + arg + ')',
|
|
141
149
|
fn: function(x, arg) {
|
|
142
150
|
if (typeof x !== 'number') { throw new Error ('Value was not a number.') }
|
|
143
151
|
return x >= arg
|
|
144
152
|
}
|
|
145
153
|
},
|
|
154
|
+
'isNotEmptyString': {
|
|
155
|
+
validateEmptyString: true,
|
|
156
|
+
message: 'Value was an empty string.',
|
|
157
|
+
fn: function(x) {
|
|
158
|
+
return x !== ''
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Rules below ignore undefined, & empty strings
|
|
163
|
+
// (e.g. an empty email field can be saved that isn't required)
|
|
146
164
|
|
|
147
|
-
// Rules below ignore null & empty strings
|
|
148
165
|
'enum': {
|
|
149
|
-
ignoreEmptyString: true,
|
|
150
166
|
message: (x, arg) => 'Invalid enum value',
|
|
151
167
|
fn: function(x, arg) {
|
|
152
168
|
for (let item of arg) {
|
|
@@ -154,62 +170,51 @@ module.exports = {
|
|
|
154
170
|
}
|
|
155
171
|
}
|
|
156
172
|
},
|
|
157
|
-
'hasAgreed': {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
},
|
|
173
|
+
// 'hasAgreed': {
|
|
174
|
+
// message: (x, arg) => 'Please agree to the terms and conditions.',
|
|
175
|
+
// fn: function(x, arg) { return !x }
|
|
176
|
+
// },
|
|
161
177
|
'isAfter': {
|
|
162
|
-
ignoreEmptyString: true,
|
|
163
178
|
message: (x, arg) => 'Value was before the configured time (' + arg + ')',
|
|
164
179
|
fn: function(x, arg) { return validator.isAfter(x, arg) }
|
|
165
180
|
},
|
|
166
181
|
'isBefore': {
|
|
167
|
-
ignoreEmptyString: true,
|
|
168
182
|
message: (x, arg) => 'Value was after the configured time (' + arg + ')',
|
|
169
183
|
fn: function(x, arg) { return validator.isBefore(x, arg) }
|
|
170
184
|
},
|
|
171
185
|
'isCreditCard': {
|
|
172
|
-
ignoreEmptyString: true,
|
|
173
186
|
message: 'Value was not a valid credit card.',
|
|
174
187
|
fn: function(x, arg) { return validator.isCreditCard(x, arg) }
|
|
175
188
|
},
|
|
176
189
|
'isEmail': {
|
|
177
|
-
ignoreEmptyString: true,
|
|
178
190
|
message: 'Please enter a valid email address.',
|
|
179
191
|
fn: function(x, arg) { return validator.isEmail(x, arg) }
|
|
180
192
|
},
|
|
181
193
|
'isHexColor': {
|
|
182
|
-
ignoreEmptyString: true,
|
|
183
194
|
message: 'Value was not a valid hex color.',
|
|
184
195
|
fn: function(x, arg) { return validator.isHexColor(x, arg) }
|
|
185
196
|
},
|
|
186
197
|
'isIn': {
|
|
187
|
-
ignoreEmptyString: true,
|
|
188
198
|
message: (x, arg) => 'Value was not in the configured whitelist (' + arg.join(', ') + ')',
|
|
189
199
|
fn: function(x, arg) { return validator.isIn(x, arg) }
|
|
190
200
|
},
|
|
191
201
|
'isIP': {
|
|
192
|
-
ignoreEmptyString: true,
|
|
193
202
|
message: 'Value was not a valid IP address.',
|
|
194
203
|
fn: function(x, arg) { return validator.isIP(x, arg) }
|
|
195
204
|
},
|
|
196
205
|
'isNotIn': {
|
|
197
|
-
ignoreEmptyString: true,
|
|
198
206
|
message: (x, arg) => 'Value was in the configured blacklist (' + arg.join(', ') + ')',
|
|
199
207
|
fn: function(x, arg) { return !validator.isIn(x, arg) }
|
|
200
208
|
},
|
|
201
209
|
'isURL': {
|
|
202
|
-
ignoreEmptyString: true,
|
|
203
210
|
message: 'Value was not a valid URL.',
|
|
204
211
|
fn: function(x, arg) { return validator.isURL(x, arg === true? undefined : arg) }
|
|
205
212
|
},
|
|
206
213
|
'isUUID': {
|
|
207
|
-
ignoreEmptyString: true,
|
|
208
214
|
message: 'Value was not a valid UUID.',
|
|
209
215
|
fn: function(x, arg) { return validator.isUUID(x) }
|
|
210
216
|
},
|
|
211
217
|
'minLength': {
|
|
212
|
-
ignoreEmptyString: true,
|
|
213
218
|
message: function(x, arg) {
|
|
214
219
|
if (typeof x === 'string') return 'Value needs to be at least ' + arg + ' characters long.'
|
|
215
220
|
else return 'Value needs to contain a minimum of ' + arg + ' items.'
|
|
@@ -221,7 +226,6 @@ module.exports = {
|
|
|
221
226
|
}
|
|
222
227
|
},
|
|
223
228
|
'maxLength': {
|
|
224
|
-
ignoreEmptyString: true,
|
|
225
229
|
message: function(x, arg) {
|
|
226
230
|
if (typeof x === 'string') return 'Value was longer than the configured maximum length (' + arg + ')'
|
|
227
231
|
else return 'Value cannot contain more than ' + arg + ' items.'
|
|
@@ -233,7 +237,6 @@ module.exports = {
|
|
|
233
237
|
}
|
|
234
238
|
},
|
|
235
239
|
'regex': {
|
|
236
|
-
ignoreEmptyString: true,
|
|
237
240
|
message: (x, arg) => 'Value did not match the configured regular expression (' + arg + ')',
|
|
238
241
|
fn: function(x, arg) {
|
|
239
242
|
if (util.isRegex(arg)) return validator.matches(x, arg)
|
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', '
|
|
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.
|
|
5
|
+
"version": "1.30.2",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "github:boycce/monastery",
|
|
8
8
|
"homepage": "https://boycce.github.io/monastery/",
|