monastery 1.28.2 → 1.29.0
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 +30 -4
- package/docs/Gemfile +8 -18
- package/docs/_config.yml +1 -4
- 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 -1
- package/lib/model-crud.js +32 -16
- package/lib/model-validate.js +20 -24
- package/lib/model.js +13 -4
- package/lib/rules.js +38 -16
- package/lib/util.js +13 -7
- package/package.json +17 -16
- package/plugins/images/index.js +4 -4
- 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/blacklisting.js +4 -8
- package/test/crud.js +28 -31
- package/test/model.js +22 -25
- package/test/monk.js +4 -4
- package/test/plugin-images.js +400 -390
- package/test/populate.js +15 -18
- package/test/util.js +8 -8
- package/test/validate.js +126 -50
- package/test/virtuals.js +2 -4
package/.eslintrc.json
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es2021": true,
|
|
5
|
+
"node": true
|
|
6
|
+
},
|
|
7
|
+
"extends": [
|
|
8
|
+
"eslint:recommended"
|
|
9
|
+
],
|
|
10
|
+
"globals": {
|
|
11
|
+
"test": true,
|
|
12
|
+
"expect": true
|
|
13
|
+
},
|
|
2
14
|
"parserOptions": {
|
|
3
|
-
"ecmaVersion": 2018,
|
|
4
|
-
"sourceType": "module",
|
|
5
15
|
"ecmaFeatures": {
|
|
6
16
|
"jsx": true
|
|
7
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"ecmaVersion": "latest",
|
|
19
|
+
"sourceType": "module"
|
|
8
20
|
},
|
|
21
|
+
"plugins": [],
|
|
9
22
|
"rules": {
|
|
10
|
-
|
|
23
|
+
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
|
24
|
+
"max-len": ["error", { "code": 120, "ignorePattern": "^\\s*<(rect|path|line)\\s" }],
|
|
25
|
+
"no-prototype-builtins": "off",
|
|
26
|
+
"no-unused-vars": ["error", { "args": "none" }],
|
|
27
|
+
"object-shorthand": ["error", "consistent"],
|
|
28
|
+
// "no-restricted-syntax": [
|
|
29
|
+
// "error",
|
|
30
|
+
// {
|
|
31
|
+
// "selector": "ObjectPattern > Property[shorthand=false]",
|
|
32
|
+
// "message": "Renaming properties within object deconstructions is not allowed."
|
|
33
|
+
// }
|
|
34
|
+
// ],
|
|
35
|
+
"quotes": ["error", "single"],
|
|
36
|
+
"semi": ["error", "never"]
|
|
11
37
|
}
|
|
12
38
|
}
|
package/docs/Gemfile
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Old
|
|
2
|
+
# source 'https://rubygems.org'
|
|
3
|
+
# gem 'github-pages', group: :jekyll_plugins
|
|
2
4
|
|
|
3
|
-
#
|
|
5
|
+
# Below pulls the latest remote_theme in development
|
|
4
6
|
source 'https://rubygems.org'
|
|
5
|
-
gem
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# # Same as github-docs
|
|
11
|
-
# gem "bundler"
|
|
12
|
-
# gem "jekyll", "~> 3.9.0"
|
|
13
|
-
# gem "jekyll-github-metadata", "~> 2.13.0"
|
|
14
|
-
# gem "jekyll-seo-tag", "~> 2.7.1"
|
|
15
|
-
# gem "kramdown-parser-gfm", "~> 1.1.0"
|
|
16
|
-
# gem "github-docs", git: "https://github.com/boycce/github-docs"
|
|
17
|
-
|
|
18
|
-
# group :jekyll_plugins do
|
|
19
|
-
# gem "jekyll-remote-theme", "~> 0.4.2"
|
|
20
|
-
# end
|
|
7
|
+
gem "github-docs", git: "https://github.com/boycce/github-docs"
|
|
8
|
+
group :jekyll_plugins do
|
|
9
|
+
gem "jekyll-remote-theme", "~> 0.4.2"
|
|
10
|
+
end
|
package/docs/_config.yml
CHANGED
|
@@ -2,16 +2,13 @@ remote_theme: boycce/github-docs
|
|
|
2
2
|
title: Monastery
|
|
3
3
|
description: A straight forward MongoDB ODM built upon MonkJS
|
|
4
4
|
github_url: "https://github.com/boycce/monastery"
|
|
5
|
-
basedir: ""
|
|
5
|
+
basedir: "docs"
|
|
6
6
|
|
|
7
7
|
# Aux links for the naviation.
|
|
8
8
|
aux_links:
|
|
9
9
|
"Monastery on GitHub":
|
|
10
10
|
- "//github.com/boycce/monastery"
|
|
11
11
|
|
|
12
|
-
plugins:
|
|
13
|
-
- jekyll-remote-theme
|
|
14
|
-
|
|
15
12
|
defaults:
|
|
16
13
|
-
|
|
17
14
|
scope:
|
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
package/lib/model-crud.js
CHANGED
|
@@ -9,7 +9,8 @@ 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|true} ignoreUndefined - ignore all required fields during insert, or
|
|
12
|
+
* @param {array|string|true} ignoreUndefined - ignore all required fields during insert, or
|
|
13
|
+
* undefined subdocument required fields that have a defined parent/grandparent during update
|
|
13
14
|
* @param {array|string|true} <opts.skipValidation> - skip validation for this field name(s)
|
|
14
15
|
* @param {boolean} <opts.timestamps> - whether `createdAt` and `updatedAt` are automatically inserted
|
|
15
16
|
* @param {any} <opts.any> - any mongodb option
|
|
@@ -21,7 +22,9 @@ module.exports = {
|
|
|
21
22
|
opts.insert = true
|
|
22
23
|
opts.model = this
|
|
23
24
|
let data = opts.data = opts.data || (opts.req? opts.req.body : {})
|
|
24
|
-
let options = util.omit(opts, [
|
|
25
|
+
let options = util.omit(opts, [
|
|
26
|
+
'data', 'insert', 'model', 'respond', 'ignoreUndefined', 'skipValidation', 'blacklist'
|
|
27
|
+
])
|
|
25
28
|
if (cb && !util.isFunction(cb)) {
|
|
26
29
|
throw new Error(`The callback passed to ${this.name}.insert() is not a function`)
|
|
27
30
|
}
|
|
@@ -75,7 +78,7 @@ module.exports = {
|
|
|
75
78
|
opts.one = one || opts.one
|
|
76
79
|
// Operation options
|
|
77
80
|
options = util.omit(opts, ['blacklist', 'one', 'populate', 'project', 'query', 'respond'])
|
|
78
|
-
options.sort = options.sort || {
|
|
81
|
+
options.sort = options.sort || { 'createdAt': -1 }
|
|
79
82
|
options.skip = Math.max(0, options.skip || 0)
|
|
80
83
|
options.limit = opts.one? 1 : parseInt(options.limit || this.manager.limit || 0)
|
|
81
84
|
options.addFields = options.addFields || {}
|
|
@@ -99,8 +102,8 @@ module.exports = {
|
|
|
99
102
|
}
|
|
100
103
|
// Has text search?
|
|
101
104
|
// if (opts.query.$text) {
|
|
102
|
-
// options.projection.score = { $meta:
|
|
103
|
-
// options.sort = { score: { $meta:
|
|
105
|
+
// options.projection.score = { $meta: 'textScore' }
|
|
106
|
+
// options.sort = { score: { $meta: 'textScore' }}
|
|
104
107
|
// }
|
|
105
108
|
// Sort string passed
|
|
106
109
|
if (util.isString(options.sort)) {
|
|
@@ -130,7 +133,7 @@ module.exports = {
|
|
|
130
133
|
continue
|
|
131
134
|
}
|
|
132
135
|
// Populate model (convert array into document & create lookup)
|
|
133
|
-
options.addFields[path] = {
|
|
136
|
+
options.addFields[path] = { '$arrayElemAt': [ '$' + path, 0 ] }
|
|
134
137
|
lookups.push({ $lookup: {
|
|
135
138
|
from: modelName,
|
|
136
139
|
localField: path,
|
|
@@ -191,7 +194,8 @@ module.exports = {
|
|
|
191
194
|
* @param {object} <opts.query> - mongodb query object
|
|
192
195
|
* @param {object|array} <opts.data> - mongodb document update object(s)
|
|
193
196
|
* @param {boolean} <opts.respond> - automatically call res.json/error (requires opts.req)
|
|
194
|
-
* @param {array|string|true} ignoreUndefined - ignore all required fields during insert, or
|
|
197
|
+
* @param {array|string|true} ignoreUndefined - ignore all required fields during insert, or
|
|
198
|
+
* undefined subdocument required fields that have a defined parent/grandparent during update
|
|
195
199
|
* @param {array|string|true} <opts.skipValidation> - skip validation for this field name(s)
|
|
196
200
|
* @param {boolean} <opts.timestamps> - whether `updatedAt` is automatically updated
|
|
197
201
|
* @param {array|string|false} <opts.blacklist> - augment schema.updateBL, `false` will remove all blacklisting
|
|
@@ -212,7 +216,7 @@ module.exports = {
|
|
|
212
216
|
operators = util.pluck(opts, [/^\$/])
|
|
213
217
|
// Operation options
|
|
214
218
|
options = util.omit(opts, ['data', 'query', 'respond', 'ignoreUndefined', 'skipValidation', 'blacklist'])
|
|
215
|
-
options.sort = options.sort || {
|
|
219
|
+
options.sort = options.sort || { 'createdAt': -1 }
|
|
216
220
|
options.limit = parseInt(options.limit || 0)
|
|
217
221
|
// Sort string passed
|
|
218
222
|
if (util.isString(options.sort)) {
|
|
@@ -283,7 +287,7 @@ module.exports = {
|
|
|
283
287
|
if (util.isEmpty(opts.query)) throw new Error('Please specify opts.query')
|
|
284
288
|
// Operation options
|
|
285
289
|
options = util.omit(opts, ['query', 'respond'])
|
|
286
|
-
options.sort = options.sort || {
|
|
290
|
+
options.sort = options.sort || { 'createdAt': -1 }
|
|
287
291
|
options.limit = parseInt(options.limit || 1)
|
|
288
292
|
// Sort string passed
|
|
289
293
|
if (util.isString(options.sort)) {
|
|
@@ -397,7 +401,7 @@ module.exports = {
|
|
|
397
401
|
let paths = (populate||[]).map(o => o && o.as? o.as : o)
|
|
398
402
|
|
|
399
403
|
if (!paths.length) return blacklistProjection
|
|
400
|
-
this._recurseFields(model.fields,
|
|
404
|
+
this._recurseFields(model.fields, '', function(path, field) {
|
|
401
405
|
// Remove array indexes from the path e.g. '0.'
|
|
402
406
|
path = path.replace(/(\.[0-9]+)(\.|$)/, '$2')
|
|
403
407
|
if (!field.model || !paths.includes(path)) return
|
|
@@ -420,7 +424,8 @@ module.exports = {
|
|
|
420
424
|
/**
|
|
421
425
|
* Merge blacklist in
|
|
422
426
|
* @param {object} blacklistProjection
|
|
423
|
-
* @param {array} paths - e.g. ['password', '-email'] - email will be whitelisted / removed from
|
|
427
|
+
* @param {array} paths - e.g. ['password', '-email'] - email will be whitelisted / removed from
|
|
428
|
+
* exlcusion projection
|
|
424
429
|
* @return {object} exclusion blacklist
|
|
425
430
|
* @this model
|
|
426
431
|
*/
|
|
@@ -461,7 +466,7 @@ module.exports = {
|
|
|
461
466
|
let findWL = [ '_id', ...this.findWL ]
|
|
462
467
|
let model = this.manager.model
|
|
463
468
|
|
|
464
|
-
this._recurseFields(this.fields,
|
|
469
|
+
this._recurseFields(this.fields, '', function(path, field) {
|
|
465
470
|
// Remove array indexes from the path e.g. '0.'
|
|
466
471
|
path = path.replace(/(\.[0-9]+)(\.|$)/, '$2')
|
|
467
472
|
//if (field.type == 'any') findWL.push(path) //exclude.push(path)
|
|
@@ -529,7 +534,7 @@ module.exports = {
|
|
|
529
534
|
}
|
|
530
535
|
|
|
531
536
|
for (let doc of util.toArray(data)) {
|
|
532
|
-
recurseAndDeleteData(doc,
|
|
537
|
+
recurseAndDeleteData(doc, '')
|
|
533
538
|
}
|
|
534
539
|
return data
|
|
535
540
|
},
|
|
@@ -586,7 +591,11 @@ module.exports = {
|
|
|
586
591
|
if (!data) return
|
|
587
592
|
|
|
588
593
|
// Valid model object field.
|
|
589
|
-
if (
|
|
594
|
+
if (
|
|
595
|
+
((util.isArray(field) && field[0].model) || field.model) &&
|
|
596
|
+
data[fieldName] &&
|
|
597
|
+
util.isObjectAndNotID(data[fieldName])
|
|
598
|
+
) {
|
|
590
599
|
// Note that sometimes a single model is passed instead of an array of models via a custom populate $lookup
|
|
591
600
|
out.push({
|
|
592
601
|
dataRef: data[fieldName],
|
|
@@ -595,11 +604,18 @@ module.exports = {
|
|
|
595
604
|
})
|
|
596
605
|
|
|
597
606
|
// Recurse through fields that are sub-documents
|
|
598
|
-
} else if (
|
|
607
|
+
} else if (
|
|
608
|
+
util.isSubdocument(field) &&
|
|
609
|
+
util.isObjectAndNotID(data[fieldName])
|
|
610
|
+
) {
|
|
599
611
|
out = [...out, ...this._recurseAndFindModels(field, data[fieldName])]
|
|
600
612
|
|
|
601
613
|
// Array of sub-documents or models
|
|
602
|
-
} else if (
|
|
614
|
+
} else if (
|
|
615
|
+
(util.isArray(field) || field.model) &&
|
|
616
|
+
data[fieldName] &&
|
|
617
|
+
util.isObjectAndNotID(data[fieldName][0])
|
|
618
|
+
) {
|
|
603
619
|
// Valid model object found in array
|
|
604
620
|
// Note that sometimes an array of models are passed instead of single object via a custom populate $lookup
|
|
605
621
|
if (field.model || field[0].model) {
|
package/lib/model-validate.js
CHANGED
|
@@ -12,9 +12,11 @@ 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|true} ignoreUndefined - ignore all required fields during insert, or undefined
|
|
15
|
+
* @param {array|string|true} ignoreUndefined - ignore all required fields during insert, or undefined
|
|
16
|
+
* subdocument required fields that have a defined parent/grandparent during update
|
|
16
17
|
* @param {array|string|true} skipValidation - skip validation on these fields
|
|
17
|
-
* @param {boolean} timestamps - whether `createdAt` and `updatedAt` are inserted, or `updatedAt` is
|
|
18
|
+
* @param {boolean} timestamps - whether `createdAt` and `updatedAt` are inserted, or `updatedAt` is
|
|
19
|
+
* updated, depending on the `options.update` value
|
|
18
20
|
* @param {function} <cb> - instead of returning a promise
|
|
19
21
|
* @this model
|
|
20
22
|
|
|
@@ -56,7 +58,7 @@ module.exports = {
|
|
|
56
58
|
else continue
|
|
57
59
|
if (whitelist.includes(split.join())) {
|
|
58
60
|
blacklist.splice(i, 1)
|
|
59
|
-
break
|
|
61
|
+
break
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
}
|
|
@@ -189,11 +191,11 @@ module.exports = {
|
|
|
189
191
|
errors.push(...(verrors = this._validateRules(dataRoot, schema, value, opts, path2)))
|
|
190
192
|
// Data value is array too
|
|
191
193
|
if (util.isArray(value)) {
|
|
192
|
-
var
|
|
193
|
-
errors.push(...
|
|
194
|
+
var res2 = this._validateFields(dataRoot, field, value, opts, path2)
|
|
195
|
+
errors.push(...res2[0])
|
|
194
196
|
}
|
|
195
197
|
if (util.isDefined(value) && !verrors.length) {
|
|
196
|
-
data2[indexOrFieldName] =
|
|
198
|
+
data2[indexOrFieldName] = res2? res2[1] : value
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
}, this)
|
|
@@ -211,6 +213,7 @@ module.exports = {
|
|
|
211
213
|
* @param {object} dataRoot - data
|
|
212
214
|
* @param {object} field - field schema
|
|
213
215
|
* @param {string} path - full field path
|
|
216
|
+
* @param {object} opts - original validate() options
|
|
214
217
|
* @this model
|
|
215
218
|
* @return {array} errors
|
|
216
219
|
*/
|
|
@@ -234,45 +237,38 @@ module.exports = {
|
|
|
234
237
|
for (let i=0, l=skippedFieldChunks.length; i<l; i++) {
|
|
235
238
|
if (skippedFieldChunks[i] == '$') skippedFieldChunks[i] = '[0-9]+'
|
|
236
239
|
}
|
|
237
|
-
if (path.match(new RegExp('^' + skippedFieldChunks.join('.') + '(
|
|
240
|
+
if (path.match(new RegExp('^' + skippedFieldChunks.join('.') + '(.|$)'))) return []
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
|
|
241
244
|
for (let ruleName in field) {
|
|
242
245
|
if (this._ignoredRules.indexOf(ruleName) > -1) continue
|
|
243
|
-
|
|
244
|
-
if (util.isUndefined(value) && ((opts.update && !path.match(/\./)) || opts.ignoreUndefined)) continue
|
|
245
|
-
let error = this._validateRule(dataRoot, ruleName, field, field[ruleName], value, path)
|
|
246
|
+
let error = this._validateRule(dataRoot, ruleName, field, field[ruleName], value, opts, path)
|
|
246
247
|
if (error && ruleName == 'required') return [error] // only show the required error
|
|
247
248
|
if (error) errors.push(error)
|
|
248
249
|
}
|
|
249
250
|
return errors
|
|
250
251
|
},
|
|
251
252
|
|
|
252
|
-
_validateRule: function(dataRoot, ruleName, field, ruleArg, value, path) {
|
|
253
|
-
//this.debug(path, field, ruleName, ruleArg, value)
|
|
253
|
+
_validateRule: function(dataRoot, ruleName, field, ruleArg, value, opts, path) {
|
|
254
|
+
// this.debug(path, field, ruleName, ruleArg, value)
|
|
254
255
|
// Remove [] from the message path, and simply ignore non-numeric children to test for all array items
|
|
255
256
|
ruleArg = ruleArg === true? undefined : ruleArg
|
|
256
257
|
let rule = this.rules[ruleName] || rules[ruleName]
|
|
257
|
-
let fieldName = path.match(/[
|
|
258
|
+
let fieldName = path.match(/[^.]+$/)[0]
|
|
258
259
|
let ruleMessageKey = this._getMostSpecificKeyMatchingPath(this.messages, path)
|
|
259
260
|
let ruleMessage = ruleMessageKey && this.messages[ruleMessageKey][ruleName]
|
|
261
|
+
let ignoreUndefined = util.isDefined(opts.ignoreUndefined) ? opts.ignoreUndefined : rule.ignoreUndefined
|
|
260
262
|
if (!ruleMessage) ruleMessage = rule.message
|
|
261
263
|
|
|
264
|
+
// Ignore undefined (if updated root property, or ignoring)
|
|
265
|
+
if ((ignoreUndefined || (opts.update && !path.match(/\./))) && typeof value === 'undefined') return
|
|
262
266
|
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
if (typeof value === 'undefined') return ////////////////////////////////////////
|
|
266
|
-
|
|
267
|
-
// Ignore null if not testing required
|
|
268
|
-
if (value === null && !field.isObject && !field.isArray) return
|
|
269
|
-
|
|
270
|
-
// Ignore null if nullObject is set on objects or arrays
|
|
271
|
-
if (value === null && field.nullObject) return
|
|
272
|
-
}
|
|
267
|
+
// Ignore null (if nullObject is set on objects or arrays) (todo: change to ignoreNull)
|
|
268
|
+
if (field.nullObject && (field.isObject || field.isArray) && value === null) return
|
|
273
269
|
|
|
274
270
|
// Ignore empty strings
|
|
275
|
-
if (value === ''
|
|
271
|
+
if (rule.ignoreEmptyString && value === '') return
|
|
276
272
|
|
|
277
273
|
// Rule failed
|
|
278
274
|
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.ignoreUndefined == 'undefined') formattedRule.ignoreUndefined = true
|
|
64
65
|
this.rules[ruleName] = formattedRule
|
|
65
66
|
}
|
|
66
67
|
}, this)
|
|
@@ -203,7 +204,12 @@ Model.prototype._setupFields = function(fields) {
|
|
|
203
204
|
let nullObject = this.manager.nullObjects
|
|
204
205
|
let virtual = field.length == 1 && (field[0]||{}).virtual ? true : undefined
|
|
205
206
|
field.schema = {
|
|
206
|
-
type: 'array',
|
|
207
|
+
type: 'array',
|
|
208
|
+
isArray: true,
|
|
209
|
+
default: arrayDefault,
|
|
210
|
+
nullObject: nullObject,
|
|
211
|
+
virtual: virtual,
|
|
212
|
+
...(field.schema || {})
|
|
207
213
|
}
|
|
208
214
|
this._setupFields(field)
|
|
209
215
|
|
|
@@ -262,7 +268,10 @@ Model.prototype._setupIndexes = function(fields) {
|
|
|
262
268
|
|
|
263
269
|
// No db defined
|
|
264
270
|
if (!(model.manager._state || '').match(/^open/)) {
|
|
265
|
-
let error = {
|
|
271
|
+
let error = {
|
|
272
|
+
type: 'info',
|
|
273
|
+
detail: `Skipping createIndex on the '${model.name}' model, no mongodb connection found.`
|
|
274
|
+
}
|
|
266
275
|
return Promise.reject(error)
|
|
267
276
|
}
|
|
268
277
|
|
|
@@ -361,10 +370,10 @@ Model.prototype._timestampFields = {
|
|
|
361
370
|
}
|
|
362
371
|
}
|
|
363
372
|
|
|
364
|
-
for (
|
|
373
|
+
for (let key in crud) {
|
|
365
374
|
Model.prototype[key] = crud[key]
|
|
366
375
|
}
|
|
367
376
|
|
|
368
|
-
for (
|
|
377
|
+
for (let key in validate) {
|
|
369
378
|
Model.prototype[key] = validate[key]
|
|
370
379
|
}
|