@owlmeans/mongo 0.1.1 → 0.1.3

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
3
+ Copyright (c) 2026 OwlMeans Common — Fullstack typescript framework
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,451 +1,59 @@
1
1
  # @owlmeans/mongo
2
2
 
3
- MongoDB service integration for OwlMeans Common server applications. This package provides a server-side MongoDB service implementation with clustering support, field-level encryption, and connection management designed for secure, multi-layer applications.
3
+ MongoDB service for OwlMeans server contexts — connection management with replica set and cluster support.
4
4
 
5
5
  ## Overview
6
6
 
7
- The `@owlmeans/mongo` package extends the OwlMeans resource system to provide MongoDB-specific functionality including:
8
-
9
- - **MongoDB Service Integration**: Factory functions for creating MongoDB services with connection management
10
- - **Field-Level Encryption**: Built-in encryption/decryption for sensitive database fields using OwlMeans cryptographic keys
11
- - **Cluster Support**: Automatic cluster setup and replica set configuration
12
- - **Multi-Layer Support**: Integration with OwlMeans context layer system for proper data isolation
13
- - **Connection Pooling**: Efficient MongoDB connection management with proper cleanup
14
-
15
- This package follows the OwlMeans "quadra" pattern as a server-side implementation complementing the basic `@owlmeans/mongo-resource` package.
7
+ - `makeMongoDbService(alias?)` — creates a MongoDB connection service
8
+ - `appendMongo(context, alias?)` — registers the service in the context
9
+ - Reads connection config from `context.cfg.dbs[alias]` (supports `kluster:` directives)
10
+ - Used as the database provider for `@owlmeans/mongo-resource`
16
11
 
17
12
  ## Installation
18
13
 
19
14
  ```bash
20
- npm install @owlmeans/mongo
21
- ```
22
-
23
- ## Dependencies
24
-
25
- This package requires MongoDB driver and integrates with:
26
- - `@owlmeans/mongo-resource`: Base MongoDB resource definitions
27
- - `@owlmeans/server-context`: Server context management
28
- - `@owlmeans/basic-keys`: Cryptographic operations for field encryption
29
- - `mongodb`: Official MongoDB Node.js driver
30
-
31
- ## Core Concepts
32
-
33
- ### MongoDB Service
34
-
35
- The MongoDB service provides database connection management and extends the base database service with MongoDB-specific functionality like field encryption and cluster support.
36
-
37
- ### Field Encryption
38
-
39
- Built-in support for encrypting/decrypting specific database fields using OwlMeans cryptographic keys, providing application-level encryption for sensitive data.
40
-
41
- ### Layer Integration
42
-
43
- Supports multi-layer data isolation through the OwlMeans context layer system, allowing service-specific and entity-specific database configurations.
44
-
45
- ## API Reference
46
-
47
- ### Types
48
-
49
- #### `MongoMeta`
50
- Metadata interface for MongoDB-specific configuration.
51
-
52
- ```typescript
53
- interface MongoMeta {
54
- replicaSet?: string // Replica set name for clustering
55
- }
56
- ```
57
-
58
- ### Factory Functions
59
-
60
- #### `makeMongoDbService(alias?: string): MongoDbService`
61
-
62
- Creates a MongoDB service instance with connection management and encryption capabilities.
63
-
64
- **Parameters:**
65
- - `alias` (optional): Service alias (default: `DEFAULT_ALIAS`)
66
-
67
- **Returns:** `MongoDbService` instance
68
-
69
- **Methods:**
70
- - **`db(configAlias?: string): Promise<Db>`**: Gets MongoDB database instance for the configuration
71
- - **`initialize(configAlias?: string): Promise<void>`**: Initializes MongoDB connection with cluster setup
72
- - **`lock(alias: string, record: object, fields: string[]): Promise<object>`**: Encrypts specified fields in a record
73
- - **`unlock(alias: string, record: object, fields: string[]): Promise<object>`**: Decrypts specified fields in a record
74
- - **`reinitializeContext<T>(context: BasicContext<ServerConfig>): T`**: Reinitializes service with new context
75
-
76
- **Example:**
77
- ```typescript
78
- import { makeMongoDbService } from '@owlmeans/mongo'
79
-
80
- const mongoService = makeMongoDbService('main-db')
81
-
82
- // Initialize with configuration
83
- await mongoService.initialize('prod-config')
84
-
85
- // Get database instance
86
- const db = await mongoService.db('prod-config')
87
-
88
- // Use database
89
- const collection = db.collection('users')
90
- const users = await collection.find().toArray()
91
- ```
92
-
93
- #### `appendMongo<C, T>(context: T, alias?: string): T`
94
-
95
- Convenience function to create and register a MongoDB service with a context.
96
-
97
- **Parameters:**
98
- - `context`: Server context instance
99
- - `alias` (optional): Service alias (default: `DEFAULT_ALIAS`)
100
-
101
- **Returns:** The context with MongoDB service registered
102
-
103
- **Example:**
104
- ```typescript
105
- import { appendMongo } from '@owlmeans/mongo'
106
- import { makeServerContext } from '@owlmeans/server-context'
107
-
108
- const context = makeServerContext(serverConfig)
109
- const contextWithMongo = appendMongo(context, 'app-db')
110
-
111
- await contextWithMongo.configure().init()
112
-
113
- // Access MongoDB service
114
- const mongoService = context.service('app-db')
115
- ```
116
-
117
- ### Field Encryption
118
-
119
- The MongoDB service provides built-in field-level encryption for sensitive data:
120
-
121
- #### `lock(alias: string, record: object, fields: string[]): Promise<object>`
122
-
123
- Encrypts specified fields in a database record.
124
-
125
- **Parameters:**
126
- - `alias`: Configuration alias with encryption key
127
- - `record`: Database record object
128
- - `fields`: Array of field names to encrypt
129
-
130
- **Returns:** Promise resolving to record with encrypted fields
131
-
132
- **Throws:**
133
- - `SyntaxError` if no encryption key configured
134
- - `SyntaxError` if no fields specified
135
-
136
- **Example:**
137
- ```typescript
138
- const sensitiveUser = {
139
- id: '123',
140
- name: 'John Doe',
141
- email: 'john@example.com',
142
- ssn: '123-45-6789',
143
- creditCard: '4111-1111-1111-1111'
144
- }
145
-
146
- // Encrypt sensitive fields before saving
147
- const encryptedUser = await mongoService.lock('prod-config', sensitiveUser, ['ssn', 'creditCard'])
148
-
149
- // Save to database with encrypted fields
150
- await collection.insertOne(encryptedUser)
151
- ```
152
-
153
- #### `unlock(alias: string, record: object, fields: string[]): Promise<object>`
154
-
155
- Decrypts specified fields in a database record.
156
-
157
- **Parameters:**
158
- - `alias`: Configuration alias with encryption key
159
- - `record`: Database record object with encrypted fields
160
- - `fields`: Array of field names to decrypt
161
-
162
- **Returns:** Promise resolving to record with decrypted fields
163
-
164
- **Example:**
165
- ```typescript
166
- // Retrieve from database
167
- const encryptedUser = await collection.findOne({ id: '123' })
168
-
169
- // Decrypt sensitive fields after retrieval
170
- const decryptedUser = await mongoService.unlock('prod-config', encryptedUser, ['ssn', 'creditCard'])
171
-
172
- console.log(decryptedUser.ssn) // '123-45-6789' (decrypted)
173
- ```
174
-
175
- ### Cluster Support
176
-
177
- The service automatically handles MongoDB cluster setup and replica set configuration:
178
-
179
- ```typescript
180
- // Configuration with cluster hosts
181
- const config = {
182
- alias: 'cluster-config',
183
- host: ['mongo1.example.com', 'mongo2.example.com', 'mongo3.example.com'],
184
- port: 27017,
185
- database: 'app-db',
186
- replicaSet: 'rs-main'
187
- }
188
-
189
- // Service automatically detects cluster and sets up connections
190
- await mongoService.initialize('cluster-config')
191
- ```
192
-
193
- ### Constants
194
-
195
- #### `DEFAULT_ALIAS`
196
- Default service alias for MongoDB services.
197
-
198
- ```typescript
199
- const DEFAULT_ALIAS = DEFAULT_DB_ALIAS // From @owlmeans/mongo-resource
200
- ```
201
-
202
- #### `DEF_REPLSET`
203
- Default replica set name for clustering.
204
-
205
- ```typescript
206
- const DEF_REPLSET = 'rs-main'
207
- ```
208
-
209
- ## Usage Examples
210
-
211
- ### Basic MongoDB Service Setup
212
-
213
- ```typescript
214
- import { makeMongoDbService } from '@owlmeans/mongo'
215
- import { makeServerContext } from '@owlmeans/server-context'
216
-
217
- // Create server context with MongoDB configuration
218
- const context = makeServerContext({
219
- service: 'my-app',
220
- type: AppType.Backend,
221
- layer: Layer.Service,
222
- dbs: [{
223
- alias: 'main-db',
224
- service: 'mongo',
225
- host: 'localhost',
226
- port: 27017,
227
- database: 'myapp'
228
- }]
229
- })
230
-
231
- // Create and register MongoDB service
232
- const mongoService = makeMongoDbService('mongo')
233
- context.registerService(mongoService)
234
-
235
- // Initialize context
236
- await context.configure().init()
237
-
238
- // Use MongoDB
239
- const db = await mongoService.db('main-db')
240
- const users = db.collection('users')
15
+ bun add @owlmeans/mongo
241
16
  ```
242
17
 
243
- ### Using appendMongo Helper
18
+ ## Usage
244
19
 
245
20
  ```typescript
246
- import { appendMongo } from '@owlmeans/mongo'
247
-
248
- const context = makeServerContext(config)
249
- const contextWithMongo = appendMongo(context)
21
+ import { appendMongo, DEFAULT_ALIAS as MONGO_SERVICE } from '@owlmeans/mongo'
250
22
 
251
- await contextWithMongo.configure().init()
252
-
253
- const mongoService = context.service('mongo')
254
- const db = await mongoService.db()
23
+ // In context setup (backend/src/context.ts)
24
+ appendMongo<C, T>(context)
255
25
  ```
256
26
 
257
- ### Field Encryption in Practice
258
-
259
- ```typescript
260
- // Configure encryption key in database config
261
- const config = {
262
- alias: 'secure-db',
263
- service: 'mongo',
264
- host: 'localhost',
265
- database: 'secure-app',
266
- encryptionKey: 'xchacha:base64encryptionkey...'
267
- }
27
+ Config (`config.json`):
268
28
 
269
- const mongoService = makeMongoDbService()
270
- await mongoService.initialize('secure-db')
271
-
272
- // Encrypt before saving
273
- const user = { name: 'Alice', ssn: '123-45-6789', balance: 1000 }
274
- const encrypted = await mongoService.lock('secure-db', user, ['ssn', 'balance'])
275
-
276
- const db = await mongoService.db('secure-db')
277
- await db.collection('users').insertOne(encrypted)
278
-
279
- // Decrypt after retrieval
280
- const retrieved = await db.collection('users').findOne({ name: 'Alice' })
281
- const decrypted = await mongoService.unlock('secure-db', retrieved, ['ssn', 'balance'])
282
-
283
- console.log(decrypted.ssn) // '123-45-6789'
284
- ```
285
-
286
- ### Multi-Database Configuration
287
-
288
- ```typescript
289
- const context = makeServerContext({
290
- service: 'multi-db-app',
291
- type: AppType.Backend,
292
- layer: Layer.Service,
293
- dbs: [
294
- {
295
- alias: 'user-db',
296
- service: 'mongo',
297
- host: 'users.db.example.com',
298
- database: 'users',
299
- encryptionKey: 'xchacha:userkey...'
300
- },
301
- {
302
- alias: 'analytics-db',
303
- service: 'mongo',
304
- host: 'analytics.db.example.com',
305
- database: 'analytics'
29
+ ```json
30
+ {
31
+ "dbs": {
32
+ "mongo": {
33
+ "url": "mongodb://localhost:27017",
34
+ "dbName": "myapp"
306
35
  }
307
- ]
308
- })
309
-
310
- const mongoService = makeMongoDbService('mongo')
311
- context.registerService(mongoService)
312
-
313
- await context.configure().init()
314
-
315
- // Use different databases
316
- const userDb = await mongoService.db('user-db')
317
- const analyticsDb = await mongoService.db('analytics-db')
318
- ```
319
-
320
- ### Cluster Configuration
321
-
322
- ```typescript
323
- const clusterConfig = {
324
- service: 'cluster-app',
325
- type: AppType.Backend,
326
- layer: Layer.Service,
327
- dbs: [{
328
- alias: 'cluster-db',
329
- service: 'mongo',
330
- host: [
331
- 'mongo1.cluster.example.com',
332
- 'mongo2.cluster.example.com',
333
- 'mongo3.cluster.example.com'
334
- ],
335
- port: 27017,
336
- database: 'clustered-app',
337
- replicaSet: 'production-rs'
338
- }]
339
- }
340
-
341
- const context = makeServerContext(clusterConfig)
342
- const mongoService = makeMongoDbService('mongo')
343
- context.registerService(mongoService)
344
-
345
- // Service automatically handles cluster setup
346
- await context.configure().init()
347
-
348
- const db = await mongoService.db('cluster-db')
349
- ```
350
-
351
- ### Service Reinitialization
352
-
353
- ```typescript
354
- // Original context
355
- const originalContext = makeServerContext(config)
356
- const mongoService = makeMongoDbService()
357
- originalContext.registerService(mongoService)
358
-
359
- // Later, reinitialize with new context
360
- const newContext = makeServerContext(newConfig)
361
- const reinitializedService = mongoService.reinitializeContext(newContext)
362
-
363
- // Service now uses new context configuration
364
- await reinitializedService.initialize()
365
- ```
366
-
367
- ## Configuration
368
-
369
- MongoDB service configuration is handled through the server context's database configuration:
370
-
371
- ```typescript
372
- interface DatabaseConfig {
373
- alias: string // Configuration alias
374
- service: string // Service name ('mongo')
375
- host: string | string[] // Database host(s)
376
- port?: number // Database port
377
- database: string // Database name
378
- username?: string // Authentication username
379
- password?: string // Authentication password
380
- encryptionKey?: string // Field encryption key
381
- replicaSet?: string // Replica set name
382
- serviceSensitive?: boolean // Enable service-layer isolation
383
- entitySensitive?: boolean // Enable entity-layer isolation
384
- }
385
- ```
386
-
387
- ## Error Handling
388
-
389
- The package provides descriptive error messages for common issues:
390
-
391
- - **Missing encryption key**: Thrown when attempting encryption/decryption without configured key
392
- - **No fields specified**: Thrown when lock/unlock called without fields
393
- - **Client replacement**: Thrown when attempting to replace existing MongoDB client
394
- - **Context assertion**: Thrown when service context is invalid
395
-
396
- ```typescript
397
- try {
398
- await mongoService.lock('config-alias', record, ['field'])
399
- } catch (error) {
400
- if (error.message.includes('No encryption key')) {
401
- // Handle missing encryption configuration
402
36
  }
403
37
  }
404
38
  ```
405
39
 
406
- ## Security Considerations
407
-
408
- ### Field Encryption
409
- - Use strong encryption keys for field-level encryption
410
- - Rotate encryption keys regularly
411
- - Store encryption keys securely outside the database
40
+ ## API
412
41
 
413
- ### Connection Security
414
- - Use authentication credentials for production databases
415
- - Configure TLS/SSL for database connections
416
- - Restrict database access to necessary IP addresses
42
+ ### `makeMongoDbService(alias?): MongoDbService`
417
43
 
418
- ### Data Isolation
419
- - Use layer-sensitive configurations for multi-tenant applications
420
- - Separate database configurations by security level
44
+ Creates the MongoDB service. `alias` defaults to `DEFAULT_ALIAS` (`'mongo'`).
421
45
 
422
- ## Performance Considerations
46
+ ### `appendMongo<C, T>(context, alias?): T`
423
47
 
424
- - **Connection Pooling**: MongoDB driver handles connection pooling automatically
425
- - **Encryption Overhead**: Field encryption adds computational overhead
426
- - **Cluster Latency**: Cluster setup may add initialization time
427
- - **Memory Usage**: Multiple database connections increase memory usage
48
+ Registers the MongoDB service in the context.
428
49
 
429
- ## Integration with OwlMeans Ecosystem
430
-
431
- This package integrates with:
432
-
433
- - **@owlmeans/mongo-resource**: Base MongoDB resource types and interfaces
434
- - **@owlmeans/server-context**: Server context and configuration management
435
- - **@owlmeans/basic-keys**: Cryptographic operations for field encryption
436
- - **@owlmeans/resource**: Base resource service patterns
437
-
438
- ## Best Practices
50
+ ### Constants
439
51
 
440
- 1. **Use field encryption** for sensitive data like PII, financial information
441
- 2. **Configure replica sets** for production high-availability
442
- 3. **Separate database configurations** by environment and sensitivity level
443
- 4. **Handle encryption errors** gracefully with fallback mechanisms
444
- 5. **Monitor connection health** and implement proper cleanup
52
+ - `DEFAULT_ALIAS` — `'mongo'`
53
+ - `DEF_REPLSET` — `'rs-main'` — default replica set name
445
54
 
446
55
  ## Related Packages
447
56
 
448
- - **@owlmeans/mongo-resource**: Base MongoDB resource definitions
449
- - **@owlmeans/redis**: Redis service implementation
450
- - **@owlmeans/server-context**: Server context management
451
- - **@owlmeans/resource**: Base resource service patterns
57
+ - [`@owlmeans/mongo-resource`](../mongo-resource) — `makeMongoResource` uses this service
58
+ - [`@owlmeans/server-app`](../server-app) — `makeContext` in conjunction with `appendMongo`
59
+ - [`@owlmeans/kluster`](../kluster) — `kluster:` directives resolve Mongo URLs in Kubernetes
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@owlmeans/mongo",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
+ "license": "MIT",
4
5
  "type": "module",
5
6
  "scripts": {
6
7
  "build": "tsc -b",
@@ -20,16 +21,17 @@
20
21
  }
21
22
  },
22
23
  "devDependencies": {
24
+ "@owlmeans/dep-config": "workspace:*",
23
25
  "@types/node": "^24.10.1",
24
26
  "nodemon": "^3.1.11",
25
- "typescript": "^5.8.3"
27
+ "typescript": "^6.0.2"
26
28
  },
27
29
  "dependencies": {
28
30
  "@noble/hashes": "^1.5.0",
29
- "@owlmeans/basic-keys": "^0.1.1",
30
- "@owlmeans/context": "^0.1.1",
31
- "@owlmeans/mongo-resource": "^0.1.1",
32
- "@owlmeans/server-context": "^0.1.1",
31
+ "@owlmeans/basic-keys": "^0.1.3",
32
+ "@owlmeans/context": "^0.1.3",
33
+ "@owlmeans/mongo-resource": "^0.1.3",
34
+ "@owlmeans/server-context": "^0.1.3",
33
35
  "@scure/base": "^1.1.9",
34
36
  "mongodb": "^6.9.0"
35
37
  },
package/tsconfig.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json",
3
+ "@owlmeans/dep-config/tsconfig.base.json",
4
+ "@owlmeans/dep-config/tsconfig.node.json"
4
5
  ],
5
6
  "compilerOptions": {
6
- "rootDir": "./src/", /* Specify the root folder within your source files. */
7
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
7
+ "rootDir": "./src/",
8
+ "outDir": "./build/"
8
9
  },
9
10
  "exclude": [
10
11
  "./dist/**/*",
11
12
  "./build/**/*",
12
13
  "./*.ts"
13
14
  ]
14
- }
15
+ }