@nimbus-cqrs/mongodb 2.0.0-beta.0 → 2.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 CHANGED
@@ -5,10 +5,235 @@
5
5
 
6
6
  # Nimbus MongoDB
7
7
 
8
- The MongoDB package of the Nimbus framework.
8
+ A small, opinionated layer on top of the official [`mongodb`](https://www.mongodb.com/docs/drivers/node/current/) Node driver. The package gives you:
9
+
10
+ - a **singleton connection manager** with lazy connect, health check and graceful shutdown,
11
+ - typed **CRUD helpers** that throw Nimbus exceptions and emit OpenTelemetry spans automatically,
12
+ - a generic **`MongoDBRepository`** for typed entities with [Zod](https://zod.dev/) validation and pluggable document/entity mapping,
13
+ - a **collection deployer** that creates / updates collections and synchronizes their indexes from a single declarative definition,
14
+ - `MongoJSON` for round-tripping Mongo-typed values (`ObjectId`, `Date`, …) through plain JSON,
15
+ - `handleMongoError` for translating MongoDB driver errors into Nimbus exceptions.
9
16
 
10
17
  Refer to the [Nimbus main repository](https://github.com/overlap-dev/Nimbus) or the [Nimbus documentation](https://nimbus.overlap.at) for more information about the Nimbus framework.
11
18
 
19
+ ## Install
20
+
21
+ ```bash
22
+ # Deno
23
+ deno add jsr:@nimbus-cqrs/mongodb
24
+
25
+ # NPM
26
+ npm install @nimbus-cqrs/mongodb
27
+
28
+ # Bun
29
+ bun add @nimbus-cqrs/mongodb
30
+ ```
31
+
32
+ `mongodb` is a peer dependency — install it (or use one of the runtimes that resolves it via `npm:`/`jsr:` specifiers).
33
+
34
+ # Examples
35
+
36
+ For detailed documentation, please refer to the [Nimbus documentation](https://nimbus.overlap.at).
37
+
38
+ The snippets below use a tiny `Todo` entity to walk through the package.
39
+
40
+ ## MongoConnectionManager
41
+
42
+ `MongoConnectionManager` is a thin singleton around a single long-lived `MongoClient` that makes sure your app reuses one client, connects lazily on first use and shuts down cleanly.
43
+
44
+ ```typescript
45
+ import { MongoConnectionManager } from "@nimbus-cqrs/mongodb";
46
+ import { ServerApiVersion } from "mongodb";
47
+
48
+ export const mongoManager = MongoConnectionManager.getInstance(
49
+ process.env.MONGO_URI ?? "",
50
+ {
51
+ appName: "todo-app",
52
+ serverApi: {
53
+ version: ServerApiVersion.v1,
54
+ strict: false,
55
+ deprecationErrors: true,
56
+ },
57
+ }
58
+ );
59
+
60
+ // Use it from anywhere in the app.
61
+ const todos = await mongoManager.getCollection("todo-app", "todos");
62
+
63
+ // Health endpoint.
64
+ const health = await mongoManager.healthCheck();
65
+ // { status: 'healthy' } | { status: 'error', details: '...' }
66
+
67
+ // Graceful shutdown.
68
+ process.on("SIGTERM", () => {
69
+ mongoManager.close().catch(console.error);
70
+ });
71
+ ```
72
+
73
+ `getInstance` is idempotent: subsequent calls return the existing instance and ignore the arguments. Concurrent first-callers share the same in-flight `connect()` promise so only one connection is ever established.
74
+
75
+ ## CRUD helpers
76
+
77
+ Every common operation has a typed wrapper: `findOne`, `find`, `insertOne`, `insertMany`, `updateOne`, `updateMany`, `replaceOne`, `deleteOne`, `deleteMany`, `findOneAndUpdate`, `findOneAndReplace`, `findOneAndDelete`, `aggregate`, `bulkWrite` and `countDocuments`. They all share the same idea: take a Zod schema for the result, run the operation against a `Collection`, validate the output, throw a Nimbus exception on failure, and produce an OpenTelemetry span for observability.
78
+
79
+ ```typescript
80
+ import { findOne, insertOne } from "@nimbus-cqrs/mongodb";
81
+ import { z } from "zod";
82
+
83
+ const Todo = z.object({
84
+ _id: z.string(),
85
+ title: z.string().min(1),
86
+ status: z.enum(["open", "done"]),
87
+ });
88
+ type Todo = z.infer<typeof Todo>;
89
+
90
+ const collection = await mongoManager.getCollection("todo-app", "todos");
91
+
92
+ await insertOne({
93
+ collection,
94
+ document: { _id: "todo-1", title: "Write the README", status: "open" },
95
+ });
96
+
97
+ const todo = await findOne<Todo>({
98
+ collection,
99
+ filter: { _id: "todo-1" },
100
+ mapDocument: (doc) => ({
101
+ _id: doc._id.toString(),
102
+ title: doc.title,
103
+ status: doc.status,
104
+ }),
105
+ outputType: Todo,
106
+ });
107
+ ```
108
+
109
+ If the document doesn't exist, `findOne` throws a `NotFoundException` instead of returning `null`. If it exists but doesn't match the schema, it throws a `GenericException` carrying the original Zod error — so a malformed document at runtime is loud, not silent.
110
+
111
+ ## MongoDBRepository
112
+
113
+ For most domains you don't want to call the CRUD helpers directly in every handler. `MongoDBRepository` wraps them in a typed, single-collection class with consistent error handling (entity-specific `NotFoundException` codes), centralized document↔entity mapping and a stable API.
114
+
115
+ ```typescript
116
+ import { MongoDBRepository } from "@nimbus-cqrs/mongodb";
117
+ import type { Document } from "mongodb";
118
+ import { ObjectId } from "mongodb";
119
+ import { z } from "zod";
120
+
121
+ const Todo = z.object({
122
+ _id: z.string(),
123
+ title: z.string().min(1),
124
+ status: z.enum(["open", "done"]),
125
+ });
126
+ type Todo = z.infer<typeof Todo>;
127
+
128
+ class TodoRepository extends MongoDBRepository<Todo> {
129
+ constructor() {
130
+ super(
131
+ () => mongoManager.getCollection("todo-app", "todos"),
132
+ Todo,
133
+ "Todo"
134
+ );
135
+ }
136
+
137
+ override _mapDocumentToEntity(doc: Document): Todo {
138
+ return Todo.parse({
139
+ _id: doc._id.toString(),
140
+ title: doc.title,
141
+ status: doc.status,
142
+ });
143
+ }
144
+
145
+ override _mapEntityToDocument(todo: Todo): Document {
146
+ return {
147
+ _id: new ObjectId(todo._id),
148
+ title: todo.title,
149
+ status: todo.status,
150
+ };
151
+ }
152
+ }
153
+
154
+ export const todoRepository = new TodoRepository();
155
+
156
+ await todoRepository.insertOne({
157
+ item: { _id: "507f1f77bcf86cd799439011", title: "Ship v2", status: "open" },
158
+ });
159
+
160
+ const todo = await todoRepository.findOne({
161
+ filter: { _id: new ObjectId("507f1f77bcf86cd799439011") },
162
+ });
163
+ ```
164
+
165
+ Misses, missed updates and missed deletes throw a `NotFoundException` with a domain-specific `errorCode` derived from the entity name (e.g. `TODO_NOT_FOUND`), which combines very nicely with [`@nimbus-cqrs/hono`](https://www.npmjs.com/package/@nimbus-cqrs/hono)'s `handleError` to produce consistent `404` responses.
166
+
167
+ ## deployMongoCollection
168
+
169
+ `deployMongoCollection` reads a single `MongoCollectionDefinition` (name + driver options + indexes) and reconciles it against the database: it creates the collection if missing, applies `collMod` if it exists, and — when `allowUpdateIndexes` is enabled — adds new indexes and drops the ones no longer in the definition. Use it at startup or in a one-off migration script.
170
+
171
+ ```typescript
172
+ import { deployMongoCollection } from "@nimbus-cqrs/mongodb";
173
+
174
+ const todoCollection = {
175
+ name: "todos",
176
+ options: {
177
+ validator: {
178
+ $jsonSchema: {
179
+ bsonType: "object",
180
+ required: ["_id", "title", "status"],
181
+ properties: {
182
+ _id: { bsonType: "objectId" },
183
+ title: { bsonType: "string", minLength: 1 },
184
+ status: { enum: ["open", "done"] },
185
+ },
186
+ },
187
+ },
188
+ },
189
+ indexes: [{ key: { status: 1 }, name: "status_1" }],
190
+ };
191
+
192
+ const client = await mongoManager.getClient();
193
+
194
+ await deployMongoCollection({
195
+ mongoClient: client,
196
+ dbName: "todo-app",
197
+ collectionDefinition: todoCollection,
198
+ allowUpdateIndexes: true,
199
+ });
200
+ ```
201
+
202
+ ## MongoJSON
203
+
204
+ `MongoJSON` is a `parse` / `stringify` pair that preserves Mongo-typed values across JSON boundaries by encoding them with short prefixes (`objectId::`, `date::`, `int::`, `double::`). Handy when filters arrive as query-string parameters or are stored in configuration that has to round-trip through plain JSON.
205
+
206
+ ```typescript
207
+ import { MongoJSON } from "@nimbus-cqrs/mongodb";
208
+
209
+ const filter = MongoJSON.parse(`{
210
+ "_id": "objectId::507f1f77bcf86cd799439011",
211
+ "createdAt": { "$gte": "date::2025-01-01T00:00:00Z" },
212
+ "priority": "int::1"
213
+ }`);
214
+
215
+ // filter._id instanceof ObjectId
216
+ // filter.createdAt contains a Date
217
+ // filter.priority === 1 (number)
218
+ ```
219
+
220
+ `parse` rejects strings containing blacklisted operators (default: `$where`) so untrusted input can't smuggle in JavaScript execution.
221
+
222
+ ## handleMongoError
223
+
224
+ `handleMongoError` translates raw driver errors into Nimbus exceptions: schema-validation failures (`121`) and duplicate-key errors (`11000`) become `InvalidInputException` with the offending key/value attached, anything else falls back to `GenericException`. The CRUD helpers call it for you — reach for it directly only when you're using the raw driver inside a handler.
225
+
226
+ ```typescript
227
+ import { handleMongoError } from "@nimbus-cqrs/mongodb";
228
+
229
+ try {
230
+ await collection.insertOne({ _id: "duplicate", title: "oops" });
231
+ } catch (error) {
232
+ throw handleMongoError(error);
233
+ // -> InvalidInputException with { keyValue: { _id: 'duplicate' } }
234
+ }
235
+ ```
236
+
12
237
  # License
13
238
 
14
239
  Copyright 2024-present Overlap GmbH & Co KG (https://overlap.at)
@@ -1,4 +1,4 @@
1
- import { GenericException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { GenericException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { GenericException, NotFoundException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException, NotFoundException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { GenericException, NotFoundException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException, NotFoundException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { GenericException, NotFoundException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException, NotFoundException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { GenericException, NotFoundException } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException, NotFoundException } from '@nimbus-cqrs/core';
2
2
  import { handleMongoError } from '../handleMongoError.js';
3
3
  import { withSpan } from '../tracing.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { getLogger } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { getLogger } from '@nimbus-cqrs/core';
2
2
  /**
3
3
  * Deploys a collection to a MongoDB database.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type Exception } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { type Exception } from '@nimbus-cqrs/core';
2
2
  /**
3
3
  * Handles MongoDB errors and converts them
4
4
  * to Nimbus exceptions based on the error code.
@@ -1 +1 @@
1
- {"version":3,"file":"handleMongoError.d.ts","sourceRoot":"","sources":["../../src/lib/handleMongoError.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,SAAS,EAGjB,MAAM,gDAAgD,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,GAAG,KAAG,SAuB7C,CAAC"}
1
+ {"version":3,"file":"handleMongoError.d.ts","sourceRoot":"","sources":["../../src/lib/handleMongoError.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,SAAS,EAGjB,MAAM,qDAAqD,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,GAAG,KAAG,SAuB7C,CAAC"}
@@ -1,4 +1,4 @@
1
- import { GenericException, InvalidInputException, } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { GenericException, InvalidInputException, } from '@nimbus-cqrs/core';
2
2
  /**
3
3
  * Handles MongoDB errors and converts them
4
4
  * to Nimbus exceptions based on the error code.
@@ -14,7 +14,7 @@ import { type Collection, type Db, MongoClient, type MongoClientOptions } from '
14
14
  *
15
15
  * @example
16
16
  * ```ts
17
- * import { MongoConnectionManager } from '@nimbus/mongodb';
17
+ * import { MongoConnectionManager } from '@nimbus-cqrs/mongodb';
18
18
  * import { ServerApiVersion } from 'mongodb';
19
19
  *
20
20
  * export const mongoManager = MongoConnectionManager.getInstance(
@@ -1 +1 @@
1
- {"version":3,"file":"mongoConnectionManager.d.ts","sourceRoot":"","sources":["../../src/lib/mongoConnectionManager.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,EAAE,EACP,WAAW,EACX,KAAK,kBAAkB,EAC1B,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAuC;IAC/D,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAqB;IAE/C;;;;;OAKG;IACH,OAAO;IAKP;;;;;;;;;OASG;WACW,WAAW,CACrB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,kBAAkB,GAC7B,sBAAsB;IAWzB;;;;;;;;OAQG;IACI,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IAqCxC;;;;;OAKG;IACU,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAKrD;;;;;;OAMG;IACU,aAAa,CACtB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,UAAU,CAAC;IAKtB;;;;;OAKG;IACU,WAAW,IAAI,OAAO,CAC/B;QAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CACpD;IAeD;;;;;;;;OAQG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAqCtC"}
1
+ {"version":3,"file":"mongoConnectionManager.d.ts","sourceRoot":"","sources":["../../src/lib/mongoConnectionManager.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,EAAE,EACP,WAAW,EACX,KAAK,kBAAkB,EAC1B,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAuC;IAC/D,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAqB;IAE/C;;;;;OAKG;IACH,OAAO;IAKP;;;;;;;;;OASG;WACW,WAAW,CACrB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,kBAAkB,GAC7B,sBAAsB;IASzB;;;;;;;;OAQG;IACI,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IAqCxC;;;;;OAKG;IACU,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAKrD;;;;;;OAMG;IACU,aAAa,CACtB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,UAAU,CAAC;IAKtB;;;;;OAKG;IACU,WAAW,IAAI,OAAO,CAC/B;QAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CACpD;IAeD;;;;;;;;OAQG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAqCtC"}
@@ -1,4 +1,4 @@
1
- import { getLogger } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { getLogger } from '@nimbus-cqrs/core';
2
2
  import { MongoClient, } from 'mongodb';
3
3
  /**
4
4
  * Singleton wrapper around a single long-lived `MongoClient`.
@@ -15,7 +15,7 @@ import { MongoClient, } from 'mongodb';
15
15
  *
16
16
  * @example
17
17
  * ```ts
18
- * import { MongoConnectionManager } from '@nimbus/mongodb';
18
+ * import { MongoConnectionManager } from '@nimbus-cqrs/mongodb';
19
19
  * import { ServerApiVersion } from 'mongodb';
20
20
  *
21
21
  * export const mongoManager = MongoConnectionManager.getInstance(
@@ -62,9 +62,7 @@ export class MongoConnectionManager {
62
62
  * @returns {MongoConnectionManager} The singleton instance of the MongoConnectionManager
63
63
  */
64
64
  static getInstance(uri, options) {
65
- if (!MongoConnectionManager._instance) {
66
- MongoConnectionManager._instance = new MongoConnectionManager(uri, options);
67
- }
65
+ MongoConnectionManager._instance ??= new MongoConnectionManager(uri, options);
68
66
  return MongoConnectionManager._instance;
69
67
  }
70
68
  /**
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * import { MongoJSON } from '@nimbus/mongodb';
10
+ * import { MongoJSON } from '@nimbus-cqrs/mongodb';
11
11
  *
12
12
  * const filterString = MongoJSON.stringify({
13
13
  * _id: 'objectId::507f1f77bcf86cd799439011',
@@ -1,4 +1,4 @@
1
- import { InvalidInputException } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { InvalidInputException } from '@nimbus-cqrs/core';
2
2
  import { ObjectId } from 'mongodb';
3
3
  /**
4
4
  * Converts a JavaScript object to a JSON string.
@@ -68,7 +68,7 @@ const mongoJSONParse = (text, operatorBlackList = ['$where']) => {
68
68
  *
69
69
  * @example
70
70
  * ```ts
71
- * import { MongoJSON } from '@nimbus/mongodb';
71
+ * import { MongoJSON } from '@nimbus-cqrs/mongodb';
72
72
  *
73
73
  * const filterString = MongoJSON.stringify({
74
74
  * _id: 'objectId::507f1f77bcf86cd799439011',
@@ -27,8 +27,8 @@ export type WithStringId<TSchema> = Omit<TSchema, '_id'> & {
27
27
  *
28
28
  * @example
29
29
  * ```ts
30
- * import { MongoDBRepository } from '@nimbus/mongodb';
31
- * import { getEnv } from '@nimbus/utils';
30
+ * import { MongoDBRepository } from '@nimbus-cqrs/mongodb';
31
+ * import { getEnv } from '@nimbus-cqrs/utils';
32
32
  * import { mongoClient } from './mongoDBClient.ts';
33
33
  * import { User } from './user.type.ts';
34
34
  * import { USER_COLLECTION } from './user.collection.ts';
@@ -1,4 +1,4 @@
1
- import { NotFoundException } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
1
+ import { NotFoundException } from '@nimbus-cqrs/core';
2
2
  import { toSnakeCase } from '../deps/jsr.io/@std/text/1.0.18/mod.js';
3
3
  import { ObjectId } from 'mongodb';
4
4
  import { bulkWrite } from './crud/bulkWrite.js';
@@ -30,8 +30,8 @@ import { replaceOne } from './crud/replaceOne.js';
30
30
  *
31
31
  * @example
32
32
  * ```ts
33
- * import { MongoDBRepository } from '@nimbus/mongodb';
34
- * import { getEnv } from '@nimbus/utils';
33
+ * import { MongoDBRepository } from '@nimbus-cqrs/mongodb';
34
+ * import { getEnv } from '@nimbus-cqrs/utils';
35
35
  * import { mongoClient } from './mongoDBClient.ts';
36
36
  * import { User } from './user.type.ts';
37
37
  * import { USER_COLLECTION } from './user.collection.ts';
package/package.json CHANGED
@@ -1,7 +1,16 @@
1
1
  {
2
2
  "name": "@nimbus-cqrs/mongodb",
3
- "version": "2.0.0-beta.0",
4
- "description": "MongoDB integration for the Nimbus CQRS framework.",
3
+ "version": "2.0.2",
4
+ "description": "Simplify Event-Driven Applications - MongoDB integration for the Nimbus framework.",
5
+ "keywords": [
6
+ "nimbus",
7
+ "cqrs",
8
+ "event-sourcing",
9
+ "event-driven",
10
+ "typescript",
11
+ "mongodb",
12
+ "database"
13
+ ],
5
14
  "author": "Daniel Gördes <d.goerdes@overlap.at> (https://overlap.at)",
6
15
  "homepage": "https://nimbus.overlap.at",
7
16
  "repository": {
@@ -26,7 +35,7 @@
26
35
  "@opentelemetry/api": "^1.9.1",
27
36
  "mongodb": "^7.1.1",
28
37
  "zod": "^4.3.6",
29
- "@nimbus-cqrs/core": "^2.0.0-beta.0"
38
+ "@nimbus-cqrs/core": "^2.0.2"
30
39
  },
31
40
  "devDependencies": {
32
41
  "@types/node": "^22.0.0"