monastery 3.5.9 → 3.5.11
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 +4 -0
- package/lib/manager.js +6 -2
- package/lib/model.js +19 -1
- package/package.json +1 -1
- package/test/manager.js +11 -0
- package/test/model.js +21 -0
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
|
+
### [3.5.11](https://github.com/boycce/monastery/compare/3.5.10...3.5.11) (2026-02-02)
|
|
6
|
+
|
|
7
|
+
### [3.5.10](https://github.com/boycce/monastery/compare/3.5.9...3.5.10) (2026-02-02)
|
|
8
|
+
|
|
5
9
|
### [3.5.9](https://github.com/boycce/monastery/compare/3.5.8...3.5.9) (2025-12-23)
|
|
6
10
|
|
|
7
11
|
### [3.5.8](https://github.com/boycce/monastery/compare/3.5.6...3.5.8) (2025-12-23)
|
package/lib/manager.js
CHANGED
|
@@ -37,10 +37,10 @@ function Manager(uri, opts, parent) {
|
|
|
37
37
|
if (typeof opts.logLevel == 'undefined') opts.logLevel = 2
|
|
38
38
|
|
|
39
39
|
// opts: separate out monastery options
|
|
40
|
-
const mongoOpts = Object.keys(opts||{}).reduce((acc, key) => {
|
|
40
|
+
const mongoOpts = Object.keys(opts || {}).reduce((acc, key) => {
|
|
41
41
|
if (![
|
|
42
42
|
'databaseName', 'defaultObjects', 'logLevel', 'imagePlugin', 'limit', 'noDefaults', 'nullObjects',
|
|
43
|
-
'promise', 'timestamps', 'useMilliseconds',
|
|
43
|
+
'promise', 'timestamps', 'useMilliseconds', 'forJest', 'showConnectionInfo',
|
|
44
44
|
].includes(key)) {
|
|
45
45
|
acc[key] = opts[key]
|
|
46
46
|
}
|
|
@@ -57,6 +57,8 @@ function Manager(uri, opts, parent) {
|
|
|
57
57
|
that.collections = {}
|
|
58
58
|
that._openQueue = []
|
|
59
59
|
that.emitter = new EventEmitter()
|
|
60
|
+
that.forJest = opts.forJest || false
|
|
61
|
+
that.showConnectionInfo = opts.showConnectionInfo || false
|
|
60
62
|
|
|
61
63
|
// If there is no DEBUG= environment variable, we will need to force the debugs on (due to bug on debug@4.3.4)
|
|
62
64
|
if (!debug.namespaces) {
|
|
@@ -283,9 +285,11 @@ Manager.prototype.open = async function() {
|
|
|
283
285
|
* @return {Promise(manager)}
|
|
284
286
|
*/
|
|
285
287
|
try {
|
|
288
|
+
this.openTimestamp = Date.now()
|
|
286
289
|
this._state = 'opening'
|
|
287
290
|
this.db = this.client.db()
|
|
288
291
|
await this.client.connect() // now optional since db().command() will auto-connect
|
|
292
|
+
if (this.showConnectionInfo) console.info(`Connected to MongoDB in ${Date.now() - this.openTimestamp}ms`)
|
|
289
293
|
this.emitter.emit(this._state = 'open', this)
|
|
290
294
|
return this
|
|
291
295
|
|
package/lib/model.js
CHANGED
|
@@ -346,7 +346,25 @@ Model.prototype._setupIndexes = async function(fields, opts={}) {
|
|
|
346
346
|
const collection = this.collection
|
|
347
347
|
|
|
348
348
|
// Get the collections indexes
|
|
349
|
-
|
|
349
|
+
let existingIndexes = []
|
|
350
|
+
try {
|
|
351
|
+
existingIndexes = await collection.indexes() // returns [] if collection doesn't exist
|
|
352
|
+
} catch (err) {
|
|
353
|
+
// Show a succinct error message for timeout errors, which is due to onOpen() timing out.
|
|
354
|
+
if (err.message.match(/Server selection timed out after/)) {
|
|
355
|
+
const msg = `Unable to create an index on the '${model.name||''}' model, the server selection has timed out already.`
|
|
356
|
+
if (model.manager.forJest) throw new Error(msg)
|
|
357
|
+
else this.error(msg)
|
|
358
|
+
return []
|
|
359
|
+
} else if (err.message.match(/Topology is closed/)) {
|
|
360
|
+
const msg = `Unable to create an index on the '${model.name||''}' model, the 'Topology is closed'. Bad connection URL?`
|
|
361
|
+
if (model.manager.forJest) throw new Error(msg)
|
|
362
|
+
else this.error(msg)
|
|
363
|
+
return []
|
|
364
|
+
} else {
|
|
365
|
+
throw err
|
|
366
|
+
}
|
|
367
|
+
}
|
|
350
368
|
|
|
351
369
|
// Remove any existing text index that has different options as createIndexes will throws error about this
|
|
352
370
|
if (existingIndexes.length) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "monastery",
|
|
3
3
|
"description": "⛪ A simple, straightforward MongoDB ODM",
|
|
4
4
|
"author": "Ricky Boyce",
|
|
5
|
-
"version": "3.5.
|
|
5
|
+
"version": "3.5.11",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "github:boycce/monastery",
|
|
8
8
|
"homepage": "https://boycce.github.io/monastery/",
|
package/test/manager.js
CHANGED
|
@@ -59,6 +59,17 @@ test('manager > onOpen error', async () => {
|
|
|
59
59
|
db.close()
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
+
test('manager > onOpen timeout error', async () => {
|
|
63
|
+
// Bad connection url, which will hang and timeout after 100ms
|
|
64
|
+
// Related: test/model.js > model index timeout topology closed
|
|
65
|
+
let manager
|
|
66
|
+
const db = monastery.manager('google.com', { serverSelectionTimeoutMS:100, logLevel: 3 }) // should hang
|
|
67
|
+
await expect(db.onOpen((res) => { manager = res })).rejects.toThrow('Server selection timed out after 100 ms')
|
|
68
|
+
expect(manager).toEqual(undefined)
|
|
69
|
+
expect(db).toEqual(expect.any(Object))
|
|
70
|
+
db.close()
|
|
71
|
+
})
|
|
72
|
+
|
|
62
73
|
test('manager > return a promise', async () => {
|
|
63
74
|
const db = await monastery.manager('localhost/monastery', { serverSelectionTimeoutMS: 500, promise: true })
|
|
64
75
|
expect(db).toEqual(expect.any(Object))
|
package/test/model.js
CHANGED
|
@@ -495,6 +495,27 @@ test('model indexes basic', async () => {
|
|
|
495
495
|
}])
|
|
496
496
|
})
|
|
497
497
|
|
|
498
|
+
test('model index timeout topology closed', async () => {
|
|
499
|
+
// 1. For a invalid URL, while a connection is still opening, we should expect a
|
|
500
|
+
// 'topology is closed' error when trying to create an index.
|
|
501
|
+
// 2. For valid connection URL, we should expect a 'server selection timed out' error (which we can't reproduce in tests)
|
|
502
|
+
const db2 = monastery.manager('google.com', { logLevel: 3, serverSelectionTimeoutMS: 50, forJest: true })
|
|
503
|
+
// Attempt to use the collection while the connection is still opening.
|
|
504
|
+
const userIndexErrModel = db2.model('userIndexErr', {
|
|
505
|
+
fields: {
|
|
506
|
+
age: { type: 'number' },
|
|
507
|
+
name: { type: 'string' },
|
|
508
|
+
},
|
|
509
|
+
})
|
|
510
|
+
expect(
|
|
511
|
+
userIndexErrModel._setupIndexes({ age: { type: 'number', index: 'text' }, name: { type: 'string', index: 'text' } })
|
|
512
|
+
).rejects.toThrow('Unable to create an index on the \'userIndexErr\' model, the \'Topology is closed\'. Bad connection URL?')
|
|
513
|
+
await expect(
|
|
514
|
+
db2.onOpen((res) => { })
|
|
515
|
+
).rejects.toThrow('Server selection timed out after 50 ms')
|
|
516
|
+
db2.close()
|
|
517
|
+
})
|
|
518
|
+
|
|
498
519
|
test('model indexes unique', async () => {
|
|
499
520
|
// Setup: Drop previously tested collections
|
|
500
521
|
if ((await db.db.listCollections().toArray()).find(o => o.name == 'userUniqueIndex')) {
|