monastery 1.28.0 → 1.28.4

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/docs/Gemfile CHANGED
@@ -1,20 +1,10 @@
1
- # Gemfile is only used in development
1
+ # Old
2
+ # source 'https://rubygems.org'
3
+ # gem 'github-pages', group: :jekyll_plugins
2
4
 
3
- # Old, doesn't pull the latest version
5
+ # Below pulls the latest remote_theme in development
4
6
  source 'https://rubygems.org'
5
- gem 'github-pages', group: :jekyll_plugins
6
-
7
- # # Below pulls the latest remote_theme in development
8
- # source "https://rubygems.org"
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/readme.md CHANGED
@@ -71,6 +71,12 @@ $ DEBUG=monastery:info
71
71
  $ DEBUG=monastery:*
72
72
  ```
73
73
 
74
+ To run isolated tests with Jest:
75
+
76
+ ```bash
77
+ npm run dev -- -t 'Model indexes'
78
+ ```
79
+
74
80
  ## Contributing
75
81
 
76
82
  Coming soon...
package/docs/schema.md CHANGED
@@ -173,13 +173,13 @@ You are able to define custom validation rules to use. (`this` will refer to the
173
173
  ```js
174
174
  schema.rules = {
175
175
  // Basic definition
176
- isGrandMaster: function(value, ruleArgument, fieldName, model) {
176
+ isGrandMaster: function(value, ruleArgument, path, model) {
177
177
  return (value == 'Martin Luther')? true : false
178
178
  },
179
179
  // Full definition
180
180
  isGrandMaster: {
181
- message: (value, ruleArgument, fieldName, model) => 'Only grand masters are permitted'
182
- fn: function(value, ruleArgument, fieldName, model) {
181
+ message: (value, ruleArgument, path, model) => 'Only grand masters are permitted'
182
+ fn: function(value, ruleArgument, path, model) {
183
183
  return (value == 'Martin Luther' || this.age > 100)? true : false
184
184
  }
185
185
  }
@@ -214,7 +214,7 @@ schema.messages = {
214
214
  type: 'Sorry, your name needs to be a string'
215
215
  },
216
216
  'address.city': {
217
- minLength: (value, ruleArgument, fieldName, model) => {
217
+ minLength: (value, ruleArgument, path, model) => {
218
218
  return `Is your city of residence really only ${ruleArgument} characters long?`
219
219
  }
220
220
  },
package/lib/model.js CHANGED
@@ -6,10 +6,11 @@ let validate = require('./model-validate')
6
6
  let Model = module.exports = function(name, opts, manager) {
7
7
  /**
8
8
  * Setup a model (aka monk collection)
9
- * Todo: convert into a promise
10
9
  * @param {string} name
11
10
  * @param {object} opts - see mongodb colleciton documentation
12
- * @this Model
11
+ * @param {boolean} opts.waitForIndexes
12
+ * @this model
13
+ * @return Promise(model) | this
13
14
  */
14
15
  if (!(this instanceof Model)) {
15
16
  return new Model(name, opts, this)
@@ -25,10 +26,6 @@ let Model = module.exports = function(name, opts, manager) {
25
26
  opts = opts || {}
26
27
  Object.assign(this, {
27
28
  ...(opts.methods || {}),
28
- name: name,
29
- manager: manager,
30
- error: manager.error,
31
- info: manager.info,
32
29
  afterFind: opts.afterFind || [],
33
30
  afterInsert: (opts.afterInsert || []).concat(opts.afterInsertUpdate || []),
34
31
  afterUpdate: (opts.afterUpdate || []).concat(opts.afterInsertUpdate || []),
@@ -37,12 +34,16 @@ let Model = module.exports = function(name, opts, manager) {
37
34
  beforeUpdate: (opts.beforeUpdate || []).concat(opts.beforeInsertUpdate || []),
38
35
  beforeRemove: opts.beforeRemove || [],
39
36
  beforeValidate: opts.beforeValidate || [],
40
- findBL: opts.findBL || ['password'],
37
+ error: manager.error,
38
+ info: manager.info,
41
39
  insertBL: opts.insertBL || [],
42
- updateBL: opts.updateBL || [],
43
- messages: opts.messages || {},
44
40
  fields: { ...(util.deepCopy(opts.fields) || {}) },
45
- rules: { ...(opts.rules || {}) }
41
+ findBL: opts.findBL || ['password'],
42
+ manager: manager,
43
+ messages: opts.messages || {},
44
+ name: name,
45
+ rules: { ...(opts.rules || {}) },
46
+ updateBL: opts.updateBL || [],
46
47
  })
47
48
 
48
49
  // Run before model hooks
@@ -94,13 +95,13 @@ let Model = module.exports = function(name, opts, manager) {
94
95
  // Add model to manager.model
95
96
  this.manager.model[name] = this
96
97
 
97
- // Ensure field indexes exist in mongodb
98
+ // Setup/Ensure field indexes exist in MongoDB
98
99
  let errHandler = err => {
99
100
  if (err.type == 'info') this.info(err.detail)
100
101
  else this.error(err)
101
102
  }
102
- if (opts.promise) return this._setupIndexes().catch(errHandler)
103
- else this._setupIndexes().catch(errHandler)
103
+ if (opts.waitForIndexes) return this._setupIndexes().catch(errHandler).then(() => this)
104
+ else this._setupIndexes().catch(errHandler) // returns this
104
105
  }
105
106
 
106
107
  Model.prototype._getFieldlist = function(fields, path) {
@@ -243,7 +244,7 @@ Model.prototype._setupIndexes = function(fields) {
243
244
  * @link https://docs.mongodb.com/manual/reference/command/createIndexes/
244
245
  * @link https://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#createIndexes
245
246
  * @param {object} <fields>
246
- * @return Promise( {array} indexes | {string} error )
247
+ * @return Promise( {array} indexes ensured | {string} error )
247
248
  *
248
249
  * MongoDB index structures = [
249
250
  * true = { name: 'name_1', key: { name: 1 } },
@@ -267,6 +268,7 @@ Model.prototype._setupIndexes = function(fields) {
267
268
 
268
269
  // Find all indexes
269
270
  recurseFields(fields || model.fields, '')
271
+ // console.log(2, indexes, fields)
270
272
  if (hasTextIndex) indexes.push(textIndex)
271
273
  if (!indexes.length) return Promise.resolve([]) // No indexes defined
272
274
 
@@ -313,6 +315,7 @@ Model.prototype._setupIndexes = function(fields) {
313
315
  })
314
316
  .then(response => {
315
317
  model.info('db index(s) created for ' + model.name)
318
+ return indexes
316
319
  })
317
320
 
318
321
  function recurseFields(fields, parentPath) {
package/lib/rules.js CHANGED
File without changes
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.28.0",
5
+ "version": "1.28.4",
6
6
  "license": "MIT",
7
7
  "repository": "github:boycce/monastery",
8
8
  "homepage": "https://boycce.github.io/monastery/",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "aws-sdk": "^2.742.0",
29
- "debug": "^4.1.1",
29
+ "debug": "4.1.1",
30
30
  "file-type": "^15.0.0",
31
31
  "monk": "^7.3.0",
32
32
  "nanoid": "^3.1.12",
package/test/model.js CHANGED
@@ -116,27 +116,76 @@ module.exports = function(monastery, opendb) {
116
116
  })
117
117
 
118
118
  test('Model indexes', async (done) => {
119
- // Setup
120
119
  // Need to test different types of indexes
121
120
  let db = (await opendb(null)).db
122
- let user = db.model('user', {})
123
- let user2 = db.model('user2', {})
124
121
 
125
- // Text index setup
126
- let setupIndex1 = await user._setupIndexes({
127
- name: { type: 'string', index: 'text' }
122
+ // Drop previously tested collections
123
+ if ((await db._db.listCollections().toArray()).find(o => o.name == 'userIndexRaw')) {
124
+ await db._db.collection('userIndexRaw').drop()
125
+ }
126
+ if ((await db._db.listCollections().toArray()).find(o => o.name == 'userIndex')) {
127
+ await db._db.collection('userIndex').drop()
128
+ }
129
+
130
+ // Unique & text index (after model initialisation, in serial)
131
+ let userIndexRawModel = db.model('userIndexRaw', {})
132
+ let setupIndex1 = await userIndexRawModel._setupIndexes({
133
+ email: { type: 'string', index: 'unique' },
134
+ })
135
+ let setupIndex2 = await userIndexRawModel._setupIndexes({
136
+ name: { type: 'string', index: 'text' },
137
+ })
138
+ let indexes = await db._db.collection('userIndexRaw').indexes()
139
+ expect(indexes[0]).toMatchObject({ v: 2, key: { _id: 1 }, name: '_id_' })
140
+ expect(indexes[1]).toMatchObject({ v: 2, unique: true, key: { email: 1 }, name: 'email_1' })
141
+ expect(indexes[2]).toMatchObject({
142
+ v: 2,
143
+ key: { _fts: 'text', _ftsx: 1 },
144
+ name: 'text',
145
+ weights: { name: 1 },
146
+ default_language: 'english',
147
+ language_override: 'language',
148
+ textIndexVersion: 3
149
+ })
150
+
151
+ // Unique & text index
152
+ let userIndexModel = await db.model('userIndex', {
153
+ waitForIndexes: true,
154
+ fields: {
155
+ email: { type: 'string', index: 'unique' },
156
+ name: { type: 'string', index: 'text' },
157
+ }
158
+ })
159
+
160
+ let indexes2 = await db._db.collection('userIndex').indexes()
161
+ expect(indexes2[0]).toMatchObject({ v: 2, key: { _id: 1 }, name: '_id_' })
162
+ expect(indexes2[1]).toMatchObject({ v: 2, unique: true, key: { email: 1 }, name: 'email_1' })
163
+ expect(indexes2[2]).toMatchObject({
164
+ v: 2,
165
+ key: { _fts: 'text', _ftsx: 1 },
166
+ name: 'text',
167
+ weights: { name: 1 },
168
+ default_language: 'english',
169
+ language_override: 'language',
170
+ textIndexVersion: 3
128
171
  })
129
172
 
130
173
  // No text index change error, i.e. new Error("Index with name: text already exists with different options")
131
- await expect(user._setupIndexes({
174
+ await expect(userIndexModel._setupIndexes({
132
175
  name: { type: 'string', index: 'text' },
133
176
  name2: { type: 'string', index: 'text' }
134
- })).resolves.toEqual(undefined)
177
+ })).resolves.toEqual([{
178
+ "key": { "name": "text", "name2": "text" },
179
+ "name": "text",
180
+ }])
135
181
 
136
182
  // Text index on a different model
137
- await expect(user2._setupIndexes({
138
- name: { type: 'string', index: 'text' }
139
- })).resolves.toEqual(undefined)
183
+ await expect(userIndexRawModel._setupIndexes({
184
+ name2: { type: 'string', index: 'text' }
185
+ })).resolves.toEqual([{
186
+ "key": {"name2": "text"},
187
+ "name": "text",
188
+ }])
140
189
 
141
190
  db.close()
142
191
  done()
@@ -147,7 +196,7 @@ module.exports = function(monastery, opendb) {
147
196
  // with text indexes are setup at the same time
148
197
  let db = (await opendb(null)).db
149
198
  await db.model('user3', {
150
- promise: true,
199
+ waitForIndexes: true,
151
200
  fields: {
152
201
  location: {
153
202
  index: '2dsphere',