nx-mongo 3.6.0 → 3.8.1
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 +239 -22
- package/dist/simpleMongoHelper.d.ts +68 -15
- package/dist/simpleMongoHelper.d.ts.map +1 -1
- package/dist/simpleMongoHelper.js +263 -83
- package/dist/simpleMongoHelper.js.map +1 -1
- package/package.json +1 -1
- package/src/simpleMongoHelper.ts +319 -84
- package/test-connection.ts +47 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nx-mongo
|
|
2
2
|
|
|
3
|
-
**Version:** 3.
|
|
3
|
+
**Version:** 3.8.0
|
|
4
4
|
|
|
5
5
|
A lightweight, feature-rich MongoDB helper library for Node.js and TypeScript. Provides a simple, intuitive API for common MongoDB operations with built-in retry logic, pagination, transactions, config-driven ref mapping, and signature-based deduplication.
|
|
6
6
|
|
|
@@ -31,24 +31,39 @@ npm install nx-mongo
|
|
|
31
31
|
```typescript
|
|
32
32
|
import { SimpleMongoHelper } from 'nx-mongo';
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
// Connection string: database name is ignored/stripped automatically
|
|
35
|
+
// Use base connection string: mongodb://localhost:27017/
|
|
36
|
+
const helper = new SimpleMongoHelper('mongodb://localhost:27017/');
|
|
35
37
|
|
|
36
38
|
// Initialize connection
|
|
37
39
|
await helper.initialize();
|
|
38
40
|
|
|
39
|
-
// Insert a document
|
|
41
|
+
// Insert a document (defaults to 'admin' database)
|
|
40
42
|
await helper.insert('users', {
|
|
41
43
|
name: 'John Doe',
|
|
42
44
|
email: 'john@example.com',
|
|
43
45
|
age: 30
|
|
44
46
|
});
|
|
45
47
|
|
|
46
|
-
//
|
|
48
|
+
// Insert into a specific database
|
|
49
|
+
await helper.insert('users', {
|
|
50
|
+
name: 'Jane Doe',
|
|
51
|
+
email: 'jane@example.com',
|
|
52
|
+
age: 28
|
|
53
|
+
}, {}, 'mydb'); // Specify database name
|
|
54
|
+
|
|
55
|
+
// Find documents from 'admin' database (default)
|
|
47
56
|
const users = await helper.loadCollection('users');
|
|
48
57
|
|
|
58
|
+
// Find documents from specific database
|
|
59
|
+
const mydbUsers = await helper.loadCollection('users', {}, undefined, 'mydb');
|
|
60
|
+
|
|
49
61
|
// Find one document
|
|
50
62
|
const user = await helper.findOne('users', { email: 'john@example.com' });
|
|
51
63
|
|
|
64
|
+
// Find from specific database
|
|
65
|
+
const mydbUser = await helper.findOne('users', { email: 'jane@example.com' }, undefined, 'mydb');
|
|
66
|
+
|
|
52
67
|
// Update document
|
|
53
68
|
await helper.update(
|
|
54
69
|
'users',
|
|
@@ -56,6 +71,15 @@ await helper.update(
|
|
|
56
71
|
{ $set: { age: 31 } }
|
|
57
72
|
);
|
|
58
73
|
|
|
74
|
+
// Update in specific database
|
|
75
|
+
await helper.update(
|
|
76
|
+
'users',
|
|
77
|
+
{ email: 'jane@example.com' },
|
|
78
|
+
{ $set: { age: 29 } },
|
|
79
|
+
undefined,
|
|
80
|
+
'mydb'
|
|
81
|
+
);
|
|
82
|
+
|
|
59
83
|
// Delete document
|
|
60
84
|
await helper.delete('users', { email: 'john@example.com' });
|
|
61
85
|
|
|
@@ -63,6 +87,8 @@ await helper.delete('users', { email: 'john@example.com' });
|
|
|
63
87
|
await helper.disconnect();
|
|
64
88
|
```
|
|
65
89
|
|
|
90
|
+
**Note:** The connection string database name (if present) is automatically stripped. All operations default to the `'admin'` database unless you specify a different database name as the last parameter.
|
|
91
|
+
|
|
66
92
|
## API Reference
|
|
67
93
|
|
|
68
94
|
### Constructor
|
|
@@ -72,7 +98,8 @@ new SimpleMongoHelper(connectionString: string, retryOptions?: RetryOptions)
|
|
|
72
98
|
```
|
|
73
99
|
|
|
74
100
|
**Parameters:**
|
|
75
|
-
- `connectionString` - MongoDB connection string
|
|
101
|
+
- `connectionString` - MongoDB base connection string (database name is automatically stripped if present)
|
|
102
|
+
- Example: `'mongodb://localhost:27017/'` or `'mongodb://localhost:27017/admin'` (both work the same)
|
|
76
103
|
- `retryOptions` (optional) - Retry configuration
|
|
77
104
|
- `maxRetries?: number` - Maximum retry attempts (default: 3)
|
|
78
105
|
- `retryDelay?: number` - Initial retry delay in ms (default: 1000)
|
|
@@ -80,12 +107,15 @@ new SimpleMongoHelper(connectionString: string, retryOptions?: RetryOptions)
|
|
|
80
107
|
|
|
81
108
|
**Example:**
|
|
82
109
|
```typescript
|
|
110
|
+
// Database name in connection string is ignored/stripped
|
|
83
111
|
const helper = new SimpleMongoHelper(
|
|
84
|
-
'mongodb://localhost:27017/
|
|
112
|
+
'mongodb://localhost:27017/', // or 'mongodb://localhost:27017/admin'
|
|
85
113
|
{ maxRetries: 5, retryDelay: 2000 }
|
|
86
114
|
);
|
|
87
115
|
```
|
|
88
116
|
|
|
117
|
+
**Important:** The database name in the connection string is automatically stripped. All operations default to the `'admin'` database unless you specify a different database name per operation.
|
|
118
|
+
|
|
89
119
|
### Connection Methods
|
|
90
120
|
|
|
91
121
|
#### `testConnection(): Promise<{ success: boolean; error?: { type: string; message: string; details?: string } }>`
|
|
@@ -103,9 +133,26 @@ Tests the MongoDB connection and returns detailed error information if it fails.
|
|
|
103
133
|
```typescript
|
|
104
134
|
const result = await helper.testConnection();
|
|
105
135
|
if (!result.success) {
|
|
106
|
-
console.error('Connection test failed
|
|
107
|
-
console.error('
|
|
108
|
-
|
|
136
|
+
console.error('Connection test failed!');
|
|
137
|
+
console.error('Error Type:', result.error?.type);
|
|
138
|
+
console.error('Error Message:', result.error?.message);
|
|
139
|
+
console.error('Error Details:', result.error?.details);
|
|
140
|
+
|
|
141
|
+
// Handle error based on type
|
|
142
|
+
switch (result.error?.type) {
|
|
143
|
+
case 'connection_failed':
|
|
144
|
+
console.error('Cannot connect to MongoDB server. Check if server is running.');
|
|
145
|
+
// On Windows, try using 127.0.0.1 instead of localhost
|
|
146
|
+
break;
|
|
147
|
+
case 'authentication_failed':
|
|
148
|
+
console.error('Invalid credentials. Check username and password.');
|
|
149
|
+
break;
|
|
150
|
+
case 'invalid_connection_string':
|
|
151
|
+
console.error('Connection string format is invalid.');
|
|
152
|
+
break;
|
|
153
|
+
default:
|
|
154
|
+
console.error('Unknown error occurred.');
|
|
155
|
+
}
|
|
109
156
|
} else {
|
|
110
157
|
console.log('Connection test passed!');
|
|
111
158
|
await helper.initialize();
|
|
@@ -120,6 +167,12 @@ if (!result.success) {
|
|
|
120
167
|
- `config_error` - Configuration issues
|
|
121
168
|
- `unknown` - Unexpected error
|
|
122
169
|
|
|
170
|
+
**Troubleshooting Tips:**
|
|
171
|
+
- **Windows users**: If using `localhost` fails, try `127.0.0.1` instead (e.g., `mongodb://127.0.0.1:27017/`) to avoid IPv6 resolution issues
|
|
172
|
+
- **Connection timeout**: Verify MongoDB is running and accessible on the specified host and port
|
|
173
|
+
- **Connection refused**: Check if MongoDB is listening on the correct port (default: 27017)
|
|
174
|
+
- **Authentication failed**: Verify username and password in the connection string
|
|
175
|
+
|
|
123
176
|
#### `initialize(): Promise<void>`
|
|
124
177
|
|
|
125
178
|
Establishes MongoDB connection with automatic retry logic. Must be called before using other methods.
|
|
@@ -144,7 +197,7 @@ await helper.disconnect();
|
|
|
144
197
|
|
|
145
198
|
### Query Methods
|
|
146
199
|
|
|
147
|
-
#### `loadCollection<T>(collectionName: string, query?: Filter<T>, options?: PaginationOptions): Promise<WithId<T>[] | PaginatedResult<T>>`
|
|
200
|
+
#### `loadCollection<T>(collectionName: string, query?: Filter<T>, options?: PaginationOptions, database?: string): Promise<WithId<T>[] | PaginatedResult<T>>`
|
|
148
201
|
|
|
149
202
|
Loads documents from a collection with optional query filter and pagination.
|
|
150
203
|
|
|
@@ -155,6 +208,7 @@ Loads documents from a collection with optional query filter and pagination.
|
|
|
155
208
|
- `page?: number` - Page number (1-indexed)
|
|
156
209
|
- `limit?: number` - Documents per page
|
|
157
210
|
- `sort?: Sort` - Sort specification
|
|
211
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
158
212
|
|
|
159
213
|
**Returns:**
|
|
160
214
|
- Without pagination: `WithId<T>[]`
|
|
@@ -162,9 +216,12 @@ Loads documents from a collection with optional query filter and pagination.
|
|
|
162
216
|
|
|
163
217
|
**Examples:**
|
|
164
218
|
```typescript
|
|
165
|
-
// Load all documents
|
|
219
|
+
// Load all documents from 'admin' database (default)
|
|
166
220
|
const allUsers = await helper.loadCollection('users');
|
|
167
221
|
|
|
222
|
+
// Load from specific database
|
|
223
|
+
const mydbUsers = await helper.loadCollection('users', {}, undefined, 'mydb');
|
|
224
|
+
|
|
168
225
|
// Load with query
|
|
169
226
|
const activeUsers = await helper.loadCollection('users', { active: true });
|
|
170
227
|
|
|
@@ -180,9 +237,16 @@ const result = await helper.loadCollection('users', {}, {
|
|
|
180
237
|
// result.totalPages - total pages
|
|
181
238
|
// result.hasNext - has next page
|
|
182
239
|
// result.hasPrev - has previous page
|
|
240
|
+
|
|
241
|
+
// Load with pagination from specific database
|
|
242
|
+
const mydbResult = await helper.loadCollection('users', {}, {
|
|
243
|
+
page: 1,
|
|
244
|
+
limit: 10,
|
|
245
|
+
sort: { createdAt: -1 }
|
|
246
|
+
}, 'mydb');
|
|
183
247
|
```
|
|
184
248
|
|
|
185
|
-
#### `findOne<T>(collectionName: string, query: Filter<T>, options?: { sort?: Sort; projection?: Document }): Promise<WithId<T> | null>`
|
|
249
|
+
#### `findOne<T>(collectionName: string, query: Filter<T>, options?: { sort?: Sort; projection?: Document }, database?: string): Promise<WithId<T> | null>`
|
|
186
250
|
|
|
187
251
|
Finds a single document in a collection.
|
|
188
252
|
|
|
@@ -192,6 +256,7 @@ Finds a single document in a collection.
|
|
|
192
256
|
- `options` (optional) - Find options
|
|
193
257
|
- `sort?: Sort` - Sort specification
|
|
194
258
|
- `projection?: Document` - Field projection
|
|
259
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
195
260
|
|
|
196
261
|
**Example:**
|
|
197
262
|
```typescript
|
|
@@ -201,7 +266,7 @@ const latestUser = await helper.findOne('users', {}, { sort: { createdAt: -1 } }
|
|
|
201
266
|
|
|
202
267
|
### Insert Methods
|
|
203
268
|
|
|
204
|
-
#### `insert<T>(collectionName: string, data: T | T[], options?: { session?: ClientSession }): Promise<any>`
|
|
269
|
+
#### `insert<T>(collectionName: string, data: T | T[], options?: { session?: ClientSession }, database?: string): Promise<any>`
|
|
205
270
|
|
|
206
271
|
Inserts one or more documents into a collection.
|
|
207
272
|
|
|
@@ -234,7 +299,7 @@ await session.withTransaction(async () => {
|
|
|
234
299
|
|
|
235
300
|
### Update Methods
|
|
236
301
|
|
|
237
|
-
#### `update<T>(collectionName: string, filter: Filter<T>, updateData: UpdateFilter<T>, options?: { upsert?: boolean; multi?: boolean; session?: ClientSession }): Promise<any>`
|
|
302
|
+
#### `update<T>(collectionName: string, filter: Filter<T>, updateData: UpdateFilter<T>, options?: { upsert?: boolean; multi?: boolean; session?: ClientSession }, database?: string): Promise<any>`
|
|
238
303
|
|
|
239
304
|
Updates documents in a collection.
|
|
240
305
|
|
|
@@ -275,7 +340,7 @@ await helper.update(
|
|
|
275
340
|
|
|
276
341
|
### Delete Methods
|
|
277
342
|
|
|
278
|
-
#### `delete<T>(collectionName: string, filter: Filter<T>, options?: { multi?: boolean }): Promise<any>`
|
|
343
|
+
#### `delete<T>(collectionName: string, filter: Filter<T>, options?: { multi?: boolean }, database?: string): Promise<any>`
|
|
279
344
|
|
|
280
345
|
Deletes documents from a collection.
|
|
281
346
|
|
|
@@ -314,6 +379,7 @@ Merges two collections into a new target collection using various strategies (in
|
|
|
314
379
|
- `onUnmatched1` - (Deprecated: use `joinType` instead) What to do with unmatched records from collection 1: 'include' | 'skip' (default: 'include')
|
|
315
380
|
- `onUnmatched2` - (Deprecated: use `joinType` instead) What to do with unmatched records from collection 2: 'include' | 'skip' (default: 'include')
|
|
316
381
|
- `session` - Optional transaction session
|
|
382
|
+
- `database` - Optional database name (defaults to `'admin'`)
|
|
317
383
|
|
|
318
384
|
**Returns:**
|
|
319
385
|
```typescript
|
|
@@ -491,10 +557,15 @@ const result6 = await helper.mergeCollections({
|
|
|
491
557
|
|
|
492
558
|
### Count Methods
|
|
493
559
|
|
|
494
|
-
#### `countDocuments<T>(collectionName: string, query?: Filter<T
|
|
560
|
+
#### `countDocuments<T>(collectionName: string, query?: Filter<T>, database?: string): Promise<number>`
|
|
495
561
|
|
|
496
562
|
Counts documents matching a query (accurate count).
|
|
497
563
|
|
|
564
|
+
**Parameters:**
|
|
565
|
+
- `collectionName` - Name of the collection
|
|
566
|
+
- `query` (optional) - MongoDB query filter
|
|
567
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
568
|
+
|
|
498
569
|
**Example:**
|
|
499
570
|
```typescript
|
|
500
571
|
const userCount = await helper.countDocuments('users');
|
|
@@ -512,10 +583,15 @@ const estimatedCount = await helper.estimatedDocumentCount('users');
|
|
|
512
583
|
|
|
513
584
|
### Aggregation Methods
|
|
514
585
|
|
|
515
|
-
#### `aggregate<T>(collectionName: string, pipeline: Document[]): Promise<T[]>`
|
|
586
|
+
#### `aggregate<T>(collectionName: string, pipeline: Document[], database?: string): Promise<T[]>`
|
|
516
587
|
|
|
517
588
|
Runs an aggregation pipeline on a collection.
|
|
518
589
|
|
|
590
|
+
**Parameters:**
|
|
591
|
+
- `collectionName` - Name of the collection
|
|
592
|
+
- `pipeline` - Array of aggregation pipeline stages
|
|
593
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
594
|
+
|
|
519
595
|
**Example:**
|
|
520
596
|
```typescript
|
|
521
597
|
const result = await helper.aggregate('orders', [
|
|
@@ -531,10 +607,16 @@ const result = await helper.aggregate('orders', [
|
|
|
531
607
|
|
|
532
608
|
### Index Methods
|
|
533
609
|
|
|
534
|
-
#### `createIndex(collectionName: string, indexSpec: IndexSpecification, options?: CreateIndexesOptions): Promise<string>`
|
|
610
|
+
#### `createIndex(collectionName: string, indexSpec: IndexSpecification, options?: CreateIndexesOptions, database?: string): Promise<string>`
|
|
535
611
|
|
|
536
612
|
Creates an index on a collection.
|
|
537
613
|
|
|
614
|
+
**Parameters:**
|
|
615
|
+
- `collectionName` - Name of the collection
|
|
616
|
+
- `indexSpec` - Index specification
|
|
617
|
+
- `options` (optional) - Index creation options
|
|
618
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
619
|
+
|
|
538
620
|
**Example:**
|
|
539
621
|
```typescript
|
|
540
622
|
// Simple index
|
|
@@ -547,19 +629,28 @@ await helper.createIndex('users', { email: 1 }, { unique: true });
|
|
|
547
629
|
await helper.createIndex('users', { email: 1, createdAt: -1 });
|
|
548
630
|
```
|
|
549
631
|
|
|
550
|
-
#### `dropIndex(collectionName: string, indexName: string): Promise<any>`
|
|
632
|
+
#### `dropIndex(collectionName: string, indexName: string, database?: string): Promise<any>`
|
|
551
633
|
|
|
552
634
|
Drops an index from a collection.
|
|
553
635
|
|
|
636
|
+
**Parameters:**
|
|
637
|
+
- `collectionName` - Name of the collection
|
|
638
|
+
- `indexName` - Name of the index to drop
|
|
639
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
640
|
+
|
|
554
641
|
**Example:**
|
|
555
642
|
```typescript
|
|
556
643
|
await helper.dropIndex('users', 'email_1');
|
|
557
644
|
```
|
|
558
645
|
|
|
559
|
-
#### `listIndexes(collectionName: string): Promise<Document[]>`
|
|
646
|
+
#### `listIndexes(collectionName: string, database?: string): Promise<Document[]>`
|
|
560
647
|
|
|
561
648
|
Lists all indexes on a collection.
|
|
562
649
|
|
|
650
|
+
**Parameters:**
|
|
651
|
+
- `collectionName` - Name of the collection
|
|
652
|
+
- `database` (optional) - Database name (defaults to `'admin'`)
|
|
653
|
+
|
|
563
654
|
**Example:**
|
|
564
655
|
```typescript
|
|
565
656
|
const indexes = await helper.listIndexes('users');
|
|
@@ -621,6 +712,11 @@ interface HelperConfig {
|
|
|
621
712
|
uniqueIndexKeys?: string[]; // Unique index keys (default: ["provider","key"])
|
|
622
713
|
provider?: string; // Default provider namespace for this helper instance
|
|
623
714
|
};
|
|
715
|
+
databases?: Array<{
|
|
716
|
+
ref: string; // Reference identifier
|
|
717
|
+
type: string; // Type identifier
|
|
718
|
+
database: string; // Database name to use
|
|
719
|
+
}>;
|
|
624
720
|
}
|
|
625
721
|
```
|
|
626
722
|
|
|
@@ -669,15 +765,101 @@ Sets or updates the configuration for ref-based operations.
|
|
|
669
765
|
helper.useConfig(config);
|
|
670
766
|
```
|
|
671
767
|
|
|
768
|
+
### Database Selection via Ref/Type Map
|
|
769
|
+
|
|
770
|
+
The helper supports config-driven database selection using `ref` and `type` parameters. This allows you to map logical identifiers to database names without hardcoding them in your application code.
|
|
771
|
+
|
|
772
|
+
**Configuration:**
|
|
773
|
+
|
|
774
|
+
```typescript
|
|
775
|
+
const config = {
|
|
776
|
+
// ... inputs, outputs, etc.
|
|
777
|
+
databases: [
|
|
778
|
+
{ ref: "app1", type: "production", database: "app1_prod" },
|
|
779
|
+
{ ref: "app1", type: "staging", database: "app1_staging" },
|
|
780
|
+
{ ref: "app2", type: "production", database: "app2_prod" },
|
|
781
|
+
{ ref: "app2", type: "staging", database: "app2_staging" },
|
|
782
|
+
]
|
|
783
|
+
};
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
**Usage in CRUD Operations:**
|
|
787
|
+
|
|
788
|
+
All CRUD operations now support optional `ref` and `type` parameters for automatic database resolution:
|
|
789
|
+
|
|
790
|
+
```typescript
|
|
791
|
+
// Priority 1: Direct database parameter (highest priority)
|
|
792
|
+
await helper.insert('users', { name: 'John' }, {}, 'mydb');
|
|
793
|
+
|
|
794
|
+
// Priority 2: Using ref + type (exact match)
|
|
795
|
+
await helper.insert('users', { name: 'John' }, {}, undefined, 'app1', 'production');
|
|
796
|
+
// Resolves to 'app1_prod' database
|
|
797
|
+
|
|
798
|
+
// Priority 3: Using ref alone (must have exactly one match)
|
|
799
|
+
await helper.insert('users', { name: 'John' }, {}, undefined, 'app1');
|
|
800
|
+
// Throws error if multiple matches found
|
|
801
|
+
|
|
802
|
+
// Priority 4: Using type alone (must have exactly one match)
|
|
803
|
+
await helper.insert('users', { name: 'John' }, {}, undefined, undefined, 'production');
|
|
804
|
+
// Throws error if multiple matches found
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
**Database Resolution Priority:**
|
|
808
|
+
|
|
809
|
+
1. **Direct `database` parameter** - If provided, it's used immediately (highest priority)
|
|
810
|
+
2. **`ref` + `type`** - If both provided, finds exact match in databases map
|
|
811
|
+
3. **`ref` alone** - If only ref provided, finds entries matching ref (must be exactly one)
|
|
812
|
+
4. **`type` alone** - If only type provided, finds entries matching type (must be exactly one)
|
|
813
|
+
5. **Default** - If none provided, defaults to `'admin'` database
|
|
814
|
+
|
|
815
|
+
**Error Handling:**
|
|
816
|
+
|
|
817
|
+
- If no match found: throws error with descriptive message
|
|
818
|
+
- If multiple matches found: throws error suggesting to use additional parameter to narrow down
|
|
819
|
+
|
|
820
|
+
**Example:**
|
|
821
|
+
|
|
822
|
+
```typescript
|
|
823
|
+
const config = {
|
|
824
|
+
databases: [
|
|
825
|
+
{ ref: "tenant1", type: "prod", database: "tenant1_prod" },
|
|
826
|
+
{ ref: "tenant1", type: "dev", database: "tenant1_dev" },
|
|
827
|
+
{ ref: "tenant2", type: "prod", database: "tenant2_prod" },
|
|
828
|
+
]
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
const helper = new SimpleMongoHelper('mongodb://localhost:27017/', undefined, config);
|
|
832
|
+
await helper.initialize();
|
|
833
|
+
|
|
834
|
+
// Use ref + type for exact match
|
|
835
|
+
await helper.insert('users', { name: 'John' }, {}, undefined, 'tenant1', 'prod');
|
|
836
|
+
// Uses 'tenant1_prod' database
|
|
837
|
+
|
|
838
|
+
// Use ref alone (only works if exactly one match)
|
|
839
|
+
// This would throw error because tenant1 has 2 matches (prod and dev)
|
|
840
|
+
// await helper.insert('users', { name: 'John' }, {}, undefined, 'tenant1');
|
|
841
|
+
|
|
842
|
+
// Use type alone (only works if exactly one match)
|
|
843
|
+
// This would throw error because 'prod' has 2 matches (tenant1 and tenant2)
|
|
844
|
+
// await helper.insert('users', { name: 'John' }, {}, undefined, undefined, 'prod');
|
|
845
|
+
```
|
|
846
|
+
|
|
672
847
|
### Ref-based Operations
|
|
673
848
|
|
|
674
|
-
#### `loadByRef<T>(ref: string, options?: PaginationOptions & { session?: ClientSession }): Promise<WithId<T>[] | PaginatedResult<T>>`
|
|
849
|
+
#### `loadByRef<T>(ref: string, options?: PaginationOptions & { session?: ClientSession; database?: string; ref?: string; type?: string }): Promise<WithId<T>[] | PaginatedResult<T>>`
|
|
675
850
|
|
|
676
851
|
Loads data from a collection using a ref name from the configuration.
|
|
677
852
|
|
|
678
853
|
**Parameters:**
|
|
679
854
|
- `ref` - Application-level reference name (must exist in config.inputs)
|
|
680
855
|
- `options` (optional) - Pagination and session options
|
|
856
|
+
- `page?: number` - Page number (1-indexed)
|
|
857
|
+
- `limit?: number` - Documents per page
|
|
858
|
+
- `sort?: Sort` - Sort specification
|
|
859
|
+
- `session?: ClientSession` - Transaction session
|
|
860
|
+
- `database?: string` - Database name (defaults to `'admin'`)
|
|
861
|
+
- `ref?: string` - Optional ref for database resolution
|
|
862
|
+
- `type?: string` - Optional type for database resolution
|
|
681
863
|
|
|
682
864
|
**Example:**
|
|
683
865
|
|
|
@@ -694,7 +876,7 @@ const result = await helper.loadByRef('topology', {
|
|
|
694
876
|
});
|
|
695
877
|
```
|
|
696
878
|
|
|
697
|
-
#### `writeByRef(ref: string, documents: any[], options?: { session?: ClientSession; ensureIndex?: boolean }): Promise<WriteByRefResult>`
|
|
879
|
+
#### `writeByRef(ref: string, documents: any[], options?: { session?: ClientSession; ensureIndex?: boolean; database?: string; ref?: string; type?: string }): Promise<WriteByRefResult>`
|
|
698
880
|
|
|
699
881
|
Writes documents to a collection using a ref name from the configuration. Supports signature-based deduplication and append/replace modes.
|
|
700
882
|
|
|
@@ -704,6 +886,9 @@ Writes documents to a collection using a ref name from the configuration. Suppor
|
|
|
704
886
|
- `options` (optional) - Write options
|
|
705
887
|
- `session?: ClientSession` - Transaction session
|
|
706
888
|
- `ensureIndex?: boolean` - Whether to ensure signature index exists (default: true)
|
|
889
|
+
- `database?: string` - Database name (defaults to `'admin'`)
|
|
890
|
+
- `ref?: string` - Optional ref for database resolution
|
|
891
|
+
- `type?: string` - Optional type for database resolution
|
|
707
892
|
|
|
708
893
|
**Returns:**
|
|
709
894
|
|
|
@@ -732,6 +917,15 @@ await helper.writeByRef('prioritizedPaths', prioritizedDocs);
|
|
|
732
917
|
|
|
733
918
|
Writes documents to a collection and optionally marks a stage as complete atomically. See the [Progress Tracking](#progress-tracking) section for details and examples.
|
|
734
919
|
|
|
920
|
+
**Parameters:**
|
|
921
|
+
- `ref` - Application-level reference name (must exist in config.outputs)
|
|
922
|
+
- `documents` - Array of documents to write
|
|
923
|
+
- `options` (optional) - Write and completion options
|
|
924
|
+
- `session?: ClientSession` - Transaction session
|
|
925
|
+
- `ensureIndex?: boolean` - Whether to ensure signature index exists (default: true)
|
|
926
|
+
- `database?: string` - Database name (defaults to `'admin'`)
|
|
927
|
+
- `complete?: object` - Stage completion information (optional)
|
|
928
|
+
|
|
735
929
|
**Example:**
|
|
736
930
|
|
|
737
931
|
```typescript
|
|
@@ -1323,6 +1517,29 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
1323
1517
|
|
|
1324
1518
|
## Changelog
|
|
1325
1519
|
|
|
1520
|
+
### 3.8.1
|
|
1521
|
+
- **Fixed `testConnection()` error reporting bug**: Improved error extraction from MongoDB error objects to prevent `[object Object]` display
|
|
1522
|
+
- Enhanced error handling to extract MongoDB-specific error properties (`code`, `codeName`, `errmsg`)
|
|
1523
|
+
- Added Windows-specific troubleshooting hints for localhost connection issues (suggests using `127.0.0.1` instead of `localhost`)
|
|
1524
|
+
- Improved error messages with error codes and types for better debugging
|
|
1525
|
+
- Updated documentation with better error handling examples
|
|
1526
|
+
|
|
1527
|
+
### 3.8.0
|
|
1528
|
+
- **Database selection via ref/type map**: Added config-driven database selection using `ref` and `type` parameters
|
|
1529
|
+
- Added `databases` array to `HelperConfig` for mapping ref/type combinations to database names
|
|
1530
|
+
- All CRUD operations now support optional `ref` and `type` parameters for automatic database resolution
|
|
1531
|
+
- Database resolution priority: direct `database` parameter > `ref` + `type` > `ref` alone > `type` alone
|
|
1532
|
+
- Throws descriptive errors when no match or multiple matches found in database map
|
|
1533
|
+
- Updated Progress API to support database resolution via ref/type
|
|
1534
|
+
- Updated `loadByRef`, `writeByRef`, `writeStage`, and `mergeCollections` to support database map resolution
|
|
1535
|
+
|
|
1536
|
+
### 3.7.0
|
|
1537
|
+
- **Separated database from connection string**: Database name is now specified per operation, not in connection string
|
|
1538
|
+
- **Multi-database support**: All operations accept optional `database` parameter (defaults to `'admin'`)
|
|
1539
|
+
- Connection string database name is automatically stripped if present (e.g., `mongodb://localhost:27017/admin` becomes `mongodb://localhost:27017/`)
|
|
1540
|
+
- Updated all methods (`insert`, `update`, `delete`, `loadCollection`, `findOne`, `countDocuments`, `aggregate`, `createIndex`, `dropIndex`, `listIndexes`, `writeByRef`, `loadByRef`, `mergeCollections`, `writeStage`, and progress API) to support per-operation database selection
|
|
1541
|
+
- **Breaking change**: No backward compatibility - all code must be updated to use new database parameter
|
|
1542
|
+
|
|
1326
1543
|
### 3.6.0
|
|
1327
1544
|
- **Automatic connection cleanup**: Connections now automatically close on app exit (SIGINT, SIGTERM, beforeExit)
|
|
1328
1545
|
- **Multi-instance support**: Global registry handles multiple `SimpleMongoHelper` instances gracefully
|