meadow-connection-mongodb 1.0.0 → 1.0.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/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # meadow-connection-mongodb
2
+
3
+ MongoDB connection service for the Meadow data access layer.
4
+
5
+ [![Coverage Status](https://coveralls.io/repos/github/stevenvelozo/meadow-connection-mongodb/badge.svg?branch=main)](https://coveralls.io/github/stevenvelozo/meadow-connection-mongodb?branch=main)
6
+ [![Build Status](https://github.com/stevenvelozo/meadow-connection-mongodb/workflows/Tests/badge.svg)](https://github.com/stevenvelozo/meadow-connection-mongodb/actions)
7
+ [![npm version](https://badge.fury.io/js/meadow-connection-mongodb.svg)](https://www.npmjs.com/package/meadow-connection-mongodb)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ## Features
11
+
12
+ - **Fable Service Provider** -- integrates with the Fable dependency injection ecosystem
13
+ - **Connection Pooling** -- built-in pool management via the official MongoDB Node.js driver
14
+ - **Collection & Index Management** -- automatic collection creation and index generation from Meadow schemas
15
+ - **Meadow-Compatible Settings** -- accepts both Meadow-style (`Server`, `Port`) and native MongoDB property names
16
+ - **Authentication Support** -- optional username/password credentials with URL-encoded connection URIs
17
+ - **Auto-Connect Mode** -- optionally connect during service construction
18
+ - **Idempotent Schema** -- safe to call `createTable()` on startup; existing collections are preserved
19
+
20
+ ## Installation
21
+
22
+ ```shell
23
+ npm install meadow-connection-mongodb
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```javascript
29
+ const libFable = require('fable');
30
+ const libMeadowConnectionMongoDB = require('meadow-connection-mongodb');
31
+
32
+ let _Fable = new libFable(
33
+ {
34
+ "MongoDB":
35
+ {
36
+ "Server": "localhost",
37
+ "Port": 27017,
38
+ "Database": "myapp"
39
+ }
40
+ });
41
+
42
+ _Fable.serviceManager.addAndInstantiateServiceType(
43
+ 'MeadowMongoDBProvider', libMeadowConnectionMongoDB);
44
+
45
+ _Fable.MeadowMongoDBProvider.connectAsync(
46
+ (pError, pDatabase) =>
47
+ {
48
+ if (pError) { return console.error(pError); }
49
+
50
+ let tmpDB = _Fable.MeadowMongoDBProvider.pool;
51
+ // tmpDB is the MongoDB Db instance -- ready for queries
52
+ });
53
+ ```
54
+
55
+ ## Configuration
56
+
57
+ Settings are read from `fable.settings.MongoDB`:
58
+
59
+ | Setting | Alias | Default | Description |
60
+ |---------|-------|---------|-------------|
61
+ | `Server` | `host` | `127.0.0.1` | MongoDB host |
62
+ | `Port` | `port` | `27017` | MongoDB port |
63
+ | `User` | `user` | `''` | Authentication username |
64
+ | `Password` | `password` | `''` | Authentication password |
65
+ | `Database` | `database` | `test` | Database name |
66
+ | `ConnectionPoolLimit` | `maxPoolSize` | `10` | Maximum connections in pool |
67
+
68
+ ## API
69
+
70
+ | Method | Description |
71
+ |--------|-------------|
72
+ | `connect()` | Synchronous -- create MongoClient and Db handle |
73
+ | `connectAsync(fCallback)` | Callback-style connection (recommended) |
74
+ | `pool` | Getter -- returns the `Db` instance |
75
+ | `client` | Getter -- returns the raw `MongoClient` |
76
+ | `generateCreateTableStatement(schema)` | Generate a collection/index descriptor |
77
+ | `createTable(schema, fCallback)` | Create a collection and its indexes |
78
+ | `createTables(schema, fCallback)` | Create multiple collections sequentially |
79
+ | `generateDropTableStatement(name)` | Generate a drop descriptor |
80
+
81
+ ## Collection & Index Mapping
82
+
83
+ | Meadow DataType | Index Created | Unique |
84
+ |-----------------|---------------|--------|
85
+ | `ID` | Ascending | Yes |
86
+ | `GUID` | Ascending | Yes |
87
+ | `ForeignKey` | Ascending | No |
88
+ | `String` | None | -- |
89
+ | `Numeric` | None | -- |
90
+ | `Decimal` | None | -- |
91
+ | `Text` | None | -- |
92
+ | `DateTime` | None | -- |
93
+ | `Boolean` | None | -- |
94
+
95
+ ## Part of the Retold Framework
96
+
97
+ This module is a Meadow connector that plugs into the Retold application framework. It provides the MongoDB persistence layer for the Meadow data access abstraction.
98
+
99
+ ## Testing
100
+
101
+ ```shell
102
+ npm test
103
+ ```
104
+
105
+ Coverage:
106
+
107
+ ```shell
108
+ npm run coverage
109
+ ```
110
+
111
+ ## Related Packages
112
+
113
+ - [meadow](https://github.com/stevenvelozo/meadow) -- Data access layer and ORM
114
+ - [fable](https://github.com/stevenvelozo/fable) -- Application framework and service manager
115
+ - [foxhound](https://github.com/stevenvelozo/foxhound) -- Query generation DSL (includes MongoDB dialect)
116
+ - [stricture](https://github.com/stevenvelozo/stricture) -- Schema definition and DDL tools
117
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) -- RESTful endpoint generation
118
+ - [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) -- MySQL/MariaDB connector
119
+ - [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) -- Microsoft SQL Server connector
120
+ - [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) -- SQLite connector
121
+
122
+ ## License
123
+
124
+ MIT
125
+
126
+ ## Contributing
127
+
128
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # meadow-connection-mongodb
2
+
3
+ MongoDB connection service for the Meadow data access layer. This module provides connection management, collection creation, and index generation for applications using MongoDB as their persistence store.
4
+
5
+ ## Quick Start
6
+
7
+ ```javascript
8
+ const libFable = require('fable');
9
+ const libMeadowConnectionMongoDB = require('meadow-connection-mongodb');
10
+
11
+ // 1. Create a Fable instance with MongoDB settings
12
+ let _Fable = new libFable(
13
+ {
14
+ "MongoDB":
15
+ {
16
+ "Server": "localhost",
17
+ "Port": 27017,
18
+ "Database": "myapp"
19
+ }
20
+ });
21
+
22
+ // 2. Register and instantiate the service
23
+ _Fable.serviceManager.addAndInstantiateServiceType(
24
+ 'MeadowMongoDBProvider', libMeadowConnectionMongoDB);
25
+
26
+ // 3. Connect
27
+ _Fable.MeadowMongoDBProvider.connectAsync(
28
+ (pError, pDatabase) =>
29
+ {
30
+ if (pError) { return console.error(pError); }
31
+
32
+ // 4. Use the Db instance
33
+ let tmpDB = _Fable.MeadowMongoDBProvider.pool;
34
+ let tmpCollection = tmpDB.collection('animals');
35
+
36
+ tmpCollection.find({}).toArray()
37
+ .then((pDocs) => { console.log(pDocs); });
38
+ });
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ Settings are read from `fable.settings.MongoDB`. Both Meadow-style names and native MongoDB names are supported:
44
+
45
+ | Setting | Alias | Default | Description |
46
+ |---------|-------|---------|-------------|
47
+ | `Server` | `host` | `127.0.0.1` | MongoDB hostname or IP |
48
+ | `Port` | `port` | `27017` | MongoDB port |
49
+ | `User` | `user` | `''` | Authentication username |
50
+ | `Password` | `password` | `''` | Authentication password |
51
+ | `Database` | `database` | `test` | Target database name |
52
+ | `ConnectionPoolLimit` | `maxPoolSize` | `10` | Maximum connection pool size |
53
+
54
+ ### Connection URI
55
+
56
+ The driver builds a standard MongoDB connection URI from these settings:
57
+
58
+ ```
59
+ mongodb://host:port/database
60
+ mongodb://user:password@host:port/database (with authentication)
61
+ ```
62
+
63
+ Credentials are URL-encoded automatically for safe handling of special characters.
64
+
65
+ ## How It Fits
66
+
67
+ ```
68
+ Application
69
+ |
70
+ v
71
+ Meadow (ORM)
72
+ |
73
+ v
74
+ FoxHound (MongoDB Dialect)
75
+ |
76
+ v
77
+ meadow-connection-mongodb <-- this module
78
+ |
79
+ v
80
+ Official MongoDB Driver (mongodb ^6.12.0)
81
+ |
82
+ v
83
+ MongoDB Server
84
+ ```
85
+
86
+ ## Learn More
87
+
88
+ - [Quickstart Guide](quickstart.md) -- step-by-step setup
89
+ - [Architecture](architecture.md) -- connection lifecycle and design diagrams
90
+ - [Collections & Indexes](schema.md) -- collection creation and index mapping
91
+ - [API Reference](api/reference.md) -- complete method documentation
92
+
93
+ ## Companion Modules
94
+
95
+ | Module | Purpose |
96
+ |--------|---------|
97
+ | [meadow](https://github.com/stevenvelozo/meadow) | Data access layer and ORM |
98
+ | [foxhound](https://github.com/stevenvelozo/foxhound) | Query generation DSL (MongoDB dialect) |
99
+ | [stricture](https://github.com/stevenvelozo/stricture) | Schema definition and DDL tools |
100
+ | [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) | MySQL / MariaDB connector |
101
+ | [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) | Microsoft SQL Server connector |
102
+ | [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) | SQLite connector |
103
+ | [meadow-connection-rocksdb](https://github.com/stevenvelozo/meadow-connection-rocksdb) | RocksDB key-value connector |
104
+ | [meadow-connection-dgraph](https://github.com/stevenvelozo/meadow-connection-dgraph) | Dgraph graph database connector |
package/docs/_cover.md ADDED
@@ -0,0 +1,17 @@
1
+ # meadow-connection-mongodb
2
+
3
+ <small>v1.0.0</small>
4
+
5
+ > MongoDB connection service for the Meadow data access layer
6
+
7
+ - **Fable Service Provider** -- seamless dependency injection integration
8
+ - **Connection Pooling** -- built-in pool management via the official MongoDB driver
9
+ - **Collection & Index Management** -- automatic creation from Meadow schemas
10
+ - **Authentication Support** -- optional credential-based connection URIs
11
+ - **Meadow-Compatible Settings** -- accepts both Meadow-style and native property names
12
+ - **Idempotent Schema** -- safe to call on every startup
13
+
14
+ [Overview](README.md)
15
+ [Quickstart](quickstart.md)
16
+ [API Reference](api/reference.md)
17
+ [GitHub](https://github.com/stevenvelozo/meadow-connection-mongodb)
@@ -0,0 +1,33 @@
1
+ - **Getting Started**
2
+ - [Overview](README.md)
3
+ - [Quickstart](quickstart.md)
4
+
5
+ - **Concepts**
6
+ - [Architecture](architecture.md)
7
+ - [Collections & Indexes](schema.md)
8
+
9
+ - **API Reference**
10
+ - [Full Reference](api/reference.md)
11
+ - Connection
12
+ - [connectAsync(fCallback)](api/connectAsync.md)
13
+ - [connect()](api/connect.md)
14
+ - Accessors
15
+ - [pool](api/pool.md)
16
+ - [client](api/client.md)
17
+ - Schema Management
18
+ - [generateCreateTableStatement()](api/generateCreateTableStatement.md)
19
+ - [createTable()](api/createTable.md)
20
+ - [createTables()](api/createTables.md)
21
+ - [generateDropTableStatement()](api/generateDropTableStatement.md)
22
+
23
+ - **Ecosystem**
24
+ - [Meadow](https://github.com/stevenvelozo/meadow)
25
+ - [FoxHound](https://github.com/stevenvelozo/foxhound)
26
+ - [Stricture](https://github.com/stevenvelozo/stricture)
27
+ - [Fable](https://github.com/stevenvelozo/fable)
28
+ - Connectors
29
+ - [MySQL](https://github.com/stevenvelozo/meadow-connection-mysql)
30
+ - [MSSQL](https://github.com/stevenvelozo/meadow-connection-mssql)
31
+ - [SQLite](https://github.com/stevenvelozo/meadow-connection-sqlite)
32
+ - [RocksDB](https://github.com/stevenvelozo/meadow-connection-rocksdb)
33
+ - [Dgraph](https://github.com/stevenvelozo/meadow-connection-dgraph)
@@ -0,0 +1,5 @@
1
+ - [Overview](README.md)
2
+ - [Quickstart](quickstart.md)
3
+ - [Architecture](architecture.md)
4
+ - [API Reference](api/reference.md)
5
+ - [GitHub](https://github.com/stevenvelozo/meadow-connection-mongodb)
@@ -0,0 +1,106 @@
1
+ # client (getter)
2
+
3
+ Returns the raw `MongoClient` instance for server-level operations.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ get client()
9
+ ```
10
+
11
+ ## Return Value
12
+
13
+ | Type | Description |
14
+ |------|-------------|
15
+ | `MongoClient` | The MongoDB client instance (after connecting) |
16
+ | `false` | Before connection |
17
+
18
+ ## Primary Use
19
+
20
+ The `client` getter exposes the underlying `MongoClient` from the official MongoDB driver. In most cases you should use the `pool` getter (which returns the `Db`) instead. The `client` is useful for:
21
+
22
+ - Accessing other databases on the same server
23
+ - Managing client sessions for transactions
24
+ - Watching change streams at the cluster level
25
+ - Closing the connection when shutting down
26
+ - Monitoring connection pool events
27
+
28
+ ```javascript
29
+ let tmpClient = _Fable.MeadowMongoDBProvider.client;
30
+ ```
31
+
32
+ ## Comparison with pool
33
+
34
+ | Getter | Returns | Purpose |
35
+ |--------|---------|---------|
36
+ | `pool` | `Db` | Database-level operations (collections, queries, aggregations) |
37
+ | `client` | `MongoClient` | Server-level operations (sessions, other databases, shutdown) |
38
+
39
+ The `pool` getter returns the `Db` instance for the configured database. The `client` getter returns the `MongoClient` that wraps the connection pool and provides server-level access.
40
+
41
+ ## Access Another Database
42
+
43
+ ```javascript
44
+ let tmpClient = _Fable.MeadowMongoDBProvider.client;
45
+
46
+ // Access a different database on the same server
47
+ let tmpAnalyticsDB = tmpClient.db('analytics');
48
+ let tmpEvents = tmpAnalyticsDB.collection('events');
49
+ ```
50
+
51
+ ## Client Session (Transactions)
52
+
53
+ ```javascript
54
+ let tmpClient = _Fable.MeadowMongoDBProvider.client;
55
+
56
+ let tmpSession = tmpClient.startSession();
57
+ tmpSession.startTransaction();
58
+
59
+ try
60
+ {
61
+ let tmpDB = _Fable.MeadowMongoDBProvider.pool;
62
+ let tmpAnimals = tmpDB.collection('Animal');
63
+
64
+ await tmpAnimals.insertOne({ Name: 'Fido' }, { session: tmpSession });
65
+ await tmpAnimals.updateOne(
66
+ { Name: 'Luna' },
67
+ { $set: { Age: 6 } },
68
+ { session: tmpSession });
69
+
70
+ await tmpSession.commitTransaction();
71
+ }
72
+ catch (pError)
73
+ {
74
+ await tmpSession.abortTransaction();
75
+ }
76
+ finally
77
+ {
78
+ tmpSession.endSession();
79
+ }
80
+ ```
81
+
82
+ ## Close Connection
83
+
84
+ ```javascript
85
+ let tmpClient = _Fable.MeadowMongoDBProvider.client;
86
+
87
+ tmpClient.close()
88
+ .then(() =>
89
+ {
90
+ console.log('MongoDB connection closed.');
91
+ });
92
+ ```
93
+
94
+ ## Before Connection
95
+
96
+ Returns `false` before connection:
97
+
98
+ ```javascript
99
+ let tmpClient = _Fable.MeadowMongoDBProvider.client;
100
+ // tmpClient => false (not connected yet)
101
+ ```
102
+
103
+ ## Related
104
+
105
+ - [pool](pool.md) -- The Db instance (recommended for most use)
106
+ - [connectAsync](connectAsync.md) -- Establish the connection
@@ -0,0 +1,97 @@
1
+ # connect()
2
+
3
+ Synchronous method that creates the MongoDB client and obtains the database handle.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ connect()
9
+ ```
10
+
11
+ ## Parameters
12
+
13
+ None.
14
+
15
+ ## Return Value
16
+
17
+ None.
18
+
19
+ ## Behavior
20
+
21
+ 1. If already connected (`this._Client` exists), logs an error with masked password and returns
22
+ 2. Builds the connection URI via `_buildConnectionURI()`
23
+ 3. Creates a new `MongoClient` with the URI and pool size option
24
+ 4. Calls `client.db(database)` to obtain the `Db` instance
25
+ 5. Sets `this.connected = true`
26
+
27
+ ## Usage
28
+
29
+ ```javascript
30
+ _Fable.MeadowMongoDBProvider.connect();
31
+
32
+ if (_Fable.MeadowMongoDBProvider.connected)
33
+ {
34
+ let tmpDB = _Fable.MeadowMongoDBProvider.pool;
35
+ // Use the Db instance
36
+ }
37
+ ```
38
+
39
+ ## Why Both connect() and connectAsync()?
40
+
41
+ The MongoDB Node.js driver v6 creates connections lazily -- the `MongoClient` constructor and `client.db()` are synchronous, with actual TCP connections established on first use. The `connect()` method works reliably for immediate use. However, `connectAsync()` is preferred because:
42
+
43
+ - It follows the Fable service provider convention
44
+ - It provides error handling via the callback
45
+ - It guards against missing callbacks
46
+ - It is consistent with other Meadow connector APIs
47
+
48
+ ## Double-Connect Protection
49
+
50
+ If `connect()` is called when already connected, it logs an error with the settings (password masked) and returns without action:
51
+
52
+ ```javascript
53
+ _Fable.MeadowMongoDBProvider.connect();
54
+ _Fable.MeadowMongoDBProvider.connect();
55
+ // Logs: "Meadow-Connection-MongoDB trying to connect but is already connected - skipping."
56
+ // Settings logged with password: '*****************'
57
+ ```
58
+
59
+ ## Auto-Connect
60
+
61
+ The `connect()` method is called automatically during construction if `MeadowConnectionMongoDBAutoConnect` is `true`:
62
+
63
+ ```javascript
64
+ let _Fable = new libFable(
65
+ {
66
+ "MongoDB":
67
+ {
68
+ "Server": "localhost",
69
+ "Port": 27017,
70
+ "Database": "myapp"
71
+ },
72
+ "MeadowConnectionMongoDBAutoConnect": true
73
+ });
74
+
75
+ _Fable.serviceManager.addAndInstantiateServiceType(
76
+ 'MeadowMongoDBProvider', libMeadowConnectionMongoDB);
77
+
78
+ // Already connected -- pool is ready
79
+ let tmpDB = _Fable.MeadowMongoDBProvider.pool;
80
+ ```
81
+
82
+ ## Connection URI Format
83
+
84
+ The `_buildConnectionURI()` method builds the URI from configuration:
85
+
86
+ ```
87
+ mongodb://host:port/database (no auth)
88
+ mongodb://user:password@host:port/database (with auth)
89
+ ```
90
+
91
+ Credentials are URL-encoded with `encodeURIComponent()` to handle special characters safely.
92
+
93
+ ## Related
94
+
95
+ - [connectAsync](connectAsync.md) -- Callback-style connection (recommended)
96
+ - [pool](pool.md) -- Access the Db instance after connecting
97
+ - [client](client.md) -- Access the raw MongoClient
@@ -0,0 +1,93 @@
1
+ # connectAsync(fCallback)
2
+
3
+ Callback-style connection method. Creates the `MongoClient` and obtains the `Db` instance, or returns the existing connection if already connected.
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ connectAsync(fCallback)
9
+ ```
10
+
11
+ ## Parameters
12
+
13
+ | Parameter | Type | Description |
14
+ |-----------|------|-------------|
15
+ | `fCallback` | `function` | Callback receiving `(error, database)` |
16
+
17
+ ## Return Value
18
+
19
+ Returns the result of the callback invocation.
20
+
21
+ ## Behavior
22
+
23
+ 1. If no callback is provided, logs an error and substitutes a no-op function
24
+ 2. If already connected (`this._Client` exists), calls `fCallback(null, this._Database)` immediately
25
+ 3. Otherwise, calls `this.connect()` to create the client and database handle
26
+ 4. On success: calls `fCallback(null, this._Database)`
27
+ 5. On error: logs the error, calls `fCallback(pError)`
28
+
29
+ ## Basic Usage
30
+
31
+ ```javascript
32
+ _Fable.MeadowMongoDBProvider.connectAsync(
33
+ (pError, pDatabase) =>
34
+ {
35
+ if (pError)
36
+ {
37
+ console.error('Connection failed:', pError);
38
+ return;
39
+ }
40
+ console.log('Connected! Database:', pDatabase.databaseName);
41
+ });
42
+ ```
43
+
44
+ ## Idempotent Calls
45
+
46
+ Calling `connectAsync()` multiple times is safe. If already connected, the existing `Db` instance is returned without creating a new connection:
47
+
48
+ ```javascript
49
+ // First call -- creates the connection
50
+ _Fable.MeadowMongoDBProvider.connectAsync(
51
+ (pError, pDatabase) =>
52
+ {
53
+ // pDatabase is the Db instance
54
+
55
+ // Second call -- reuses the existing connection
56
+ _Fable.MeadowMongoDBProvider.connectAsync(
57
+ (pError2, pDatabase2) =>
58
+ {
59
+ // pDatabase2 === pDatabase (same Db instance)
60
+ });
61
+ });
62
+ ```
63
+
64
+ ## Missing Callback
65
+
66
+ If called without a callback, a warning is logged and a no-op function is used:
67
+
68
+ ```javascript
69
+ // Logs: "Meadow MongoDB connectAsync() called without a callback."
70
+ _Fable.MeadowMongoDBProvider.connectAsync();
71
+ ```
72
+
73
+ ## Error Handling
74
+
75
+ If `connect()` throws, the error is caught and passed to the callback:
76
+
77
+ ```javascript
78
+ _Fable.MeadowMongoDBProvider.connectAsync(
79
+ (pError) =>
80
+ {
81
+ if (pError)
82
+ {
83
+ // Handle connection failure
84
+ console.error('MongoDB connection error:', pError.message);
85
+ }
86
+ });
87
+ ```
88
+
89
+ ## Related
90
+
91
+ - [connect()](connect.md) -- Synchronous connection method
92
+ - [pool](pool.md) -- Access the Db instance after connecting
93
+ - [client](client.md) -- Access the raw MongoClient