@mikro-orm/mongodb 7.0.0-dev.9 → 7.0.0-dev.91

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.
@@ -1,10 +1,12 @@
1
- import { MongoClient, type ClientSession, type Collection, type Db, type MongoClientOptions, type TransactionOptions } from 'mongodb';
2
- import { Connection, type AnyEntity, type Configuration, type ConnectionOptions, type ConnectionType, type EntityData, type EntityName, type FilterQuery, type IsolationLevel, type QueryOrderMap, type QueryResult, type Transaction, type TransactionEventBroadcaster, type UpsertOptions, type UpsertManyOptions, type LoggingOptions } from '@mikro-orm/core';
1
+ import { type ClientSession, type Collection, type Db, MongoClient, type MongoClientOptions, type TransactionOptions } from 'mongodb';
2
+ import { type AnyEntity, type Configuration, Connection, type ConnectionOptions, type ConnectionType, type EntityData, type EntityName, type FilterQuery, type IsolationLevel, type LoggingOptions, type QueryOrderMap, type QueryResult, type Transaction, type TransactionEventBroadcaster, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
3
3
  export declare class MongoConnection extends Connection {
4
4
  protected client: MongoClient;
5
5
  protected db: Db;
6
6
  constructor(config: Configuration, options?: ConnectionOptions, type?: ConnectionType);
7
- connect(): Promise<void>;
7
+ connect(options?: {
8
+ skipOnConnect?: boolean;
9
+ }): Promise<void>;
8
10
  close(force?: boolean): Promise<void>;
9
11
  isConnected(): Promise<boolean>;
10
12
  checkConnection(): Promise<{
@@ -20,16 +22,18 @@ export declare class MongoConnection extends Connection {
20
22
  listCollections(): Promise<string[]>;
21
23
  dropCollection(name: EntityName<AnyEntity>): Promise<boolean>;
22
24
  mapOptions(overrides: MongoClientOptions): MongoClientOptions;
23
- getClientUrl(): string;
24
25
  getDb(): Db;
25
26
  execute(query: string): Promise<any>;
26
27
  find<T extends object>(collection: string, where: FilterQuery<T>, orderBy?: QueryOrderMap<T> | QueryOrderMap<T>[], limit?: number, offset?: number, fields?: string[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions): Promise<EntityData<T>[]>;
28
+ stream<T extends object>(collection: string, where: FilterQuery<T>, orderBy?: QueryOrderMap<T> | QueryOrderMap<T>[], limit?: number, offset?: number, fields?: string[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions): AsyncIterableIterator<T>;
29
+ private _find;
27
30
  insertOne<T extends object>(collection: string, data: Partial<T>, ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
28
31
  insertMany<T extends object>(collection: string, data: Partial<T>[], ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
29
32
  updateMany<T extends object>(collection: string, where: FilterQuery<T>, data: Partial<T>, ctx?: Transaction<ClientSession>, upsert?: boolean, upsertOptions?: UpsertOptions<T>): Promise<QueryResult<T>>;
30
33
  bulkUpdateMany<T extends object>(collection: string, where: FilterQuery<T>[], data: Partial<T>[], ctx?: Transaction<ClientSession>, upsert?: boolean, upsertOptions?: UpsertManyOptions<T>): Promise<QueryResult<T>>;
31
34
  deleteMany<T extends object>(collection: string, where: FilterQuery<T>, ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
32
35
  aggregate<T extends object = any>(collection: string, pipeline: any[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions): Promise<T[]>;
36
+ streamAggregate<T extends object>(collection: string, pipeline: any[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions, stream?: boolean): AsyncIterableIterator<T>;
33
37
  countDocuments<T extends object>(collection: string, where: FilterQuery<T>, ctx?: Transaction<ClientSession>): Promise<number>;
34
38
  transactional<T>(cb: (trx: Transaction<ClientSession>) => Promise<T>, options?: {
35
39
  isolationLevel?: IsolationLevel;
@@ -1,21 +1,20 @@
1
- import { ObjectId, MongoClient, } from 'mongodb';
2
- import { inspect } from 'node:util';
3
- import { Connection, EventType, QueryOrder, Utils, ValidationError, } from '@mikro-orm/core';
1
+ import { MongoClient, ObjectId, } from 'mongodb';
2
+ import { Connection, EventType, QueryOrder, Utils, ValidationError, inspect, } from '@mikro-orm/core';
4
3
  export class MongoConnection extends Connection {
5
4
  client;
6
5
  db;
7
6
  constructor(config, options, type = 'write') {
8
7
  super(config, options, type);
9
8
  // @ts-ignore
10
- ObjectId.prototype[inspect.custom] = function () {
9
+ ObjectId.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
11
10
  return `ObjectId('${this.toHexString()}')`;
12
11
  };
13
12
  // @ts-ignore
14
- Date.prototype[inspect.custom] = function () {
13
+ Date.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
15
14
  return `ISODate('${this.toISOString()}')`;
16
15
  };
17
16
  }
18
- async connect() {
17
+ async connect(options) {
19
18
  let driverOptions = this.options.driverOptions ?? this.config.get('driverOptions');
20
19
  if (typeof driverOptions === 'function') {
21
20
  driverOptions = await driverOptions();
@@ -25,19 +24,22 @@ export class MongoConnection extends Connection {
25
24
  this.client = driverOptions;
26
25
  }
27
26
  else {
28
- this.client = new MongoClient(this.config.getClientUrl(), this.mapOptions(driverOptions));
27
+ this.client = new MongoClient(this.config.get('clientUrl'), this.mapOptions(driverOptions));
29
28
  await this.client.connect();
30
29
  const onCreateConnection = this.options.onCreateConnection ?? this.config.get('onCreateConnection');
31
- /* v8 ignore next 3 */
30
+ /* v8 ignore next */
32
31
  this.client.on('connectionCreated', () => {
33
32
  void onCreateConnection?.(this.client);
34
33
  });
35
34
  }
36
35
  this.db = this.client.db(this.config.get('dbName'));
37
36
  this.connected = true;
37
+ if (options?.skipOnConnect !== true) {
38
+ await this.onConnect();
39
+ }
38
40
  }
39
41
  async close(force) {
40
- await this.client?.close(!!force);
42
+ await this.client?.close(force);
41
43
  this.connected = false;
42
44
  }
43
45
  async isConnected() {
@@ -96,12 +98,6 @@ export class MongoConnection extends Connection {
96
98
  };
97
99
  return Utils.mergeConfig(ret, overrides);
98
100
  }
99
- getClientUrl() {
100
- const options = this.mapOptions(this.options.driverOptions ?? {});
101
- const clientUrl = this.config.getClientUrl(true);
102
- const match = clientUrl.match(/^(\w+):\/\/((.*@.+)|.+)$/);
103
- return match ? `${match[1]}://${options.auth ? options.auth.username + ':*****@' : ''}${match[2]}` : clientUrl;
104
- }
105
101
  getDb() {
106
102
  return this.db;
107
103
  }
@@ -109,6 +105,18 @@ export class MongoConnection extends Connection {
109
105
  throw new Error(`${this.constructor.name} does not support generic execute method`);
110
106
  }
111
107
  async find(collection, where, orderBy, limit, offset, fields, ctx, loggerContext) {
108
+ const { cursor, query } = await this._find(collection, where, orderBy, limit, offset, fields, ctx, loggerContext);
109
+ const now = Date.now();
110
+ const res = await cursor.toArray();
111
+ this.logQuery(`${query}.toArray();`, { took: Date.now() - now, results: res.length, ...loggerContext });
112
+ return res;
113
+ }
114
+ async *stream(collection, where, orderBy, limit, offset, fields, ctx, loggerContext) {
115
+ const { cursor, query } = await this._find(collection, where, orderBy, limit, offset, fields, ctx, loggerContext);
116
+ this.logQuery(`${query}.toArray();`, loggerContext);
117
+ yield* cursor;
118
+ }
119
+ async _find(collection, where, orderBy, limit, offset, fields, ctx, loggerContext) {
112
120
  await this.ensureConnection();
113
121
  collection = this.getCollectionName(collection);
114
122
  const options = ctx ? { session: ctx } : {};
@@ -123,12 +131,11 @@ export class MongoConnection extends Connection {
123
131
  orderBy.forEach(o => {
124
132
  Utils.keys(o).forEach(k => {
125
133
  const direction = o[k];
126
- orderByTuples.push([k.toString(), Utils.isString(direction) ? direction.toUpperCase() === QueryOrder.ASC ? 1 : -1 : direction]);
134
+ orderByTuples.push([k.toString(), typeof direction === 'string' ? direction.toUpperCase() === QueryOrder.ASC ? 1 : -1 : direction]);
127
135
  });
128
136
  });
129
137
  if (orderByTuples.length > 0) {
130
138
  query += `.sort(${this.logObject(orderByTuples)})`;
131
- // @ts-expect-error ??
132
139
  resultSet.sort(orderByTuples);
133
140
  }
134
141
  }
@@ -140,10 +147,7 @@ export class MongoConnection extends Connection {
140
147
  query += `.skip(${offset})`;
141
148
  resultSet.skip(offset);
142
149
  }
143
- const now = Date.now();
144
- const res = await resultSet.toArray();
145
- this.logQuery(`${query}.toArray();`, { took: Date.now() - now, results: res.length, ...loggerContext });
146
- return res;
150
+ return { cursor: resultSet, query };
147
151
  }
148
152
  async insertOne(collection, data, ctx) {
149
153
  return this.runQuery('insertOne', collection, data, undefined, ctx);
@@ -171,6 +175,16 @@ export class MongoConnection extends Connection {
171
175
  this.logQuery(query, { took: Date.now() - now, results: res.length, ...loggerContext });
172
176
  return res;
173
177
  }
178
+ async *streamAggregate(collection, pipeline, ctx, loggerContext, stream = false) {
179
+ await this.ensureConnection();
180
+ collection = this.getCollectionName(collection);
181
+ /* v8 ignore next */
182
+ const options = ctx ? { session: ctx } : {};
183
+ const query = `db.getCollection('${collection}').aggregate(${this.logObject(pipeline)}, ${this.logObject(options)})};`;
184
+ const cursor = this.getCollection(collection).aggregate(pipeline, options);
185
+ this.logQuery(query, { ...loggerContext });
186
+ yield* cursor;
187
+ }
174
188
  async countDocuments(collection, where, ctx) {
175
189
  return this.runQuery('countDocuments', collection, undefined, where, ctx);
176
190
  }
@@ -292,12 +306,19 @@ export class MongoConnection extends Connection {
292
306
  createUpdatePayload(row, upsertOptions) {
293
307
  const doc = { $set: row };
294
308
  const $unset = {};
295
- Utils.keys(row)
296
- .filter(k => typeof row[k] === 'undefined')
297
- .forEach(k => {
298
- $unset[k] = '';
299
- delete row[k];
300
- });
309
+ const $inc = {};
310
+ for (const k of Utils.keys(row)) {
311
+ const item = row[k];
312
+ if (typeof item === 'undefined') {
313
+ $unset[k] = '';
314
+ delete row[k];
315
+ continue;
316
+ }
317
+ if (Utils.isPlainObject(item) && '$inc' in item) {
318
+ $inc[k] = item.$inc;
319
+ delete row[k];
320
+ }
321
+ }
301
322
  if (upsertOptions) {
302
323
  if (upsertOptions.onConflictAction === 'ignore') {
303
324
  doc.$setOnInsert = doc.$set;
@@ -323,9 +344,12 @@ export class MongoConnection extends Connection {
323
344
  }
324
345
  if (Utils.hasObjectKeys($unset)) {
325
346
  doc.$unset = $unset;
326
- if (!Utils.hasObjectKeys(doc.$set)) {
327
- delete doc.$set;
328
- }
347
+ }
348
+ if (Utils.hasObjectKeys($inc)) {
349
+ doc.$inc = $inc;
350
+ }
351
+ if (!Utils.hasObjectKeys(doc.$set)) {
352
+ delete doc.$set;
329
353
  }
330
354
  return doc;
331
355
  }
package/MongoDriver.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type ClientSession } from 'mongodb';
2
- import { type Configuration, type CountOptions, DatabaseDriver, type EntityData, type EntityDictionary, type EntityField, EntityManagerType, type FilterQuery, type FindOneOptions, type FindOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type PopulateOptions, type PopulatePath, type QueryResult, type Transaction, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
2
+ import { type Configuration, type CountOptions, DatabaseDriver, type EntityData, type EntityDictionary, type EntityField, EntityManagerType, type EntityName, type FilterQuery, type FindOneOptions, type FindOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type PopulateOptions, type PopulatePath, type QueryResult, type StreamOptions, type Transaction, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
3
3
  import { MongoConnection } from './MongoConnection.js';
4
4
  import { MongoPlatform } from './MongoPlatform.js';
5
5
  import { MongoEntityManager } from './MongoEntityManager.js';
@@ -9,9 +9,13 @@ export declare class MongoDriver extends DatabaseDriver<MongoConnection> {
9
9
  protected readonly platform: MongoPlatform;
10
10
  constructor(config: Configuration);
11
11
  createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
12
+ stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T, any, any, any> & {
13
+ rawResults?: boolean;
14
+ }): AsyncIterableIterator<T>;
12
15
  find<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName: string, where: FilterQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
13
16
  findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: string, where: FilterQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
14
17
  findVirtual<T extends object>(entityName: string, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
18
+ streamVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): AsyncIterableIterator<EntityData<T>>;
15
19
  count<T extends object>(entityName: string, where: FilterQuery<T>, options?: CountOptions<T>, ctx?: Transaction<ClientSession>): Promise<number>;
16
20
  nativeInsert<T extends object>(entityName: string, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
17
21
  nativeInsertMany<T extends object>(entityName: string, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>): Promise<QueryResult<T>>;
@@ -21,9 +25,11 @@ export declare class MongoDriver extends DatabaseDriver<MongoConnection> {
21
25
  ctx?: Transaction<ClientSession>;
22
26
  }): Promise<QueryResult<T>>;
23
27
  aggregate(entityName: string, pipeline: any[], ctx?: Transaction<ClientSession>): Promise<any[]>;
28
+ streamAggregate<T extends object>(entityName: string, pipeline: any[], ctx?: Transaction<ClientSession>): AsyncIterableIterator<T>;
24
29
  getPlatform(): MongoPlatform;
25
30
  private renameFields;
26
31
  private convertObjectIds;
27
32
  private buildFilterById;
28
33
  protected buildFields<T extends object, P extends string = never>(entityName: string, populate: PopulateOptions<T>[], fields?: readonly EntityField<T, P>[], exclude?: string[]): string[] | undefined;
34
+ private handleVersionProperty;
29
35
  }
package/MongoDriver.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ObjectId } from 'mongodb';
2
- import { DatabaseDriver, EntityManagerType, ReferenceKind, Utils, } from '@mikro-orm/core';
2
+ import { DatabaseDriver, EntityManagerType, GroupOperator, ReferenceKind, Utils, } from '@mikro-orm/core';
3
3
  import { MongoConnection } from './MongoConnection.js';
4
4
  import { MongoPlatform } from './MongoPlatform.js';
5
5
  import { MongoEntityManager } from './MongoEntityManager.js';
@@ -14,6 +14,25 @@ export class MongoDriver extends DatabaseDriver {
14
14
  const EntityManagerClass = this.config.get('entityManager', MongoEntityManager);
15
15
  return new EntityManagerClass(this.config, this, this.metadata, useContext);
16
16
  }
17
+ async *stream(entityName, where, options) {
18
+ if (this.metadata.find(entityName)?.virtual) {
19
+ yield* this.streamVirtual(entityName, where, options);
20
+ return;
21
+ }
22
+ entityName = Utils.className(entityName);
23
+ const fields = this.buildFields(entityName, options.populate || [], options.fields, options.exclude);
24
+ where = this.renameFields(entityName, where, true);
25
+ const orderBy = Utils.asArray(options.orderBy).map(orderBy => this.renameFields(entityName, orderBy, true));
26
+ const res = this.getConnection('read').stream(entityName, where, orderBy, options.limit, options.offset, fields, options.ctx);
27
+ for await (const item of res) {
28
+ if (options.rawResults) {
29
+ yield item;
30
+ }
31
+ else {
32
+ yield this.mapResult(item, this.metadata.find(entityName));
33
+ }
34
+ }
35
+ }
17
36
  async find(entityName, where, options = {}) {
18
37
  if (this.metadata.find(entityName)?.virtual) {
19
38
  return this.findVirtual(entityName, where, options);
@@ -70,8 +89,19 @@ export class MongoDriver extends DatabaseDriver {
70
89
  /* v8 ignore next */
71
90
  return super.findVirtual(entityName, where, options);
72
91
  }
92
+ async *streamVirtual(entityName, where, options) {
93
+ const meta = this.metadata.find(entityName);
94
+ if (meta.expression instanceof Function) {
95
+ const em = this.createEntityManager();
96
+ const stream = await meta.expression(em, where, options, true);
97
+ yield* stream;
98
+ return;
99
+ }
100
+ /* v8 ignore next */
101
+ return super.findVirtual(entityName, where, options);
102
+ }
73
103
  async count(entityName, where, options = {}, ctx) {
74
- /* v8 ignore next 3 */
104
+ /* v8 ignore next */
75
105
  if (this.metadata.find(entityName)?.virtual) {
76
106
  return this.countVirtual(entityName, where, options);
77
107
  }
@@ -79,11 +109,15 @@ export class MongoDriver extends DatabaseDriver {
79
109
  return this.rethrow(this.getConnection('read').countDocuments(entityName, where, ctx));
80
110
  }
81
111
  async nativeInsert(entityName, data, options = {}) {
112
+ this.handleVersionProperty(entityName, data);
82
113
  data = this.renameFields(entityName, data);
83
114
  return this.rethrow(this.getConnection('write').insertOne(entityName, data, options.ctx));
84
115
  }
85
116
  async nativeInsertMany(entityName, data, options = {}) {
86
- data = data.map(d => this.renameFields(entityName, d));
117
+ data = data.map(item => {
118
+ this.handleVersionProperty(entityName, item);
119
+ return this.renameFields(entityName, item);
120
+ });
87
121
  const meta = this.metadata.find(entityName);
88
122
  /* v8 ignore next */
89
123
  const pk = meta?.getPrimaryProps()[0].fieldNames[0] ?? '_id';
@@ -95,8 +129,9 @@ export class MongoDriver extends DatabaseDriver {
95
129
  if (Utils.isPrimaryKey(where)) {
96
130
  where = this.buildFilterById(entityName, where);
97
131
  }
98
- where = this.renameFields(entityName, where, true);
132
+ this.handleVersionProperty(entityName, data, true);
99
133
  data = this.renameFields(entityName, data);
134
+ where = this.renameFields(entityName, where, true);
100
135
  options = { ...options };
101
136
  const meta = this.metadata.find(entityName);
102
137
  /* v8 ignore next */
@@ -119,7 +154,10 @@ export class MongoDriver extends DatabaseDriver {
119
154
  }
120
155
  return row;
121
156
  });
122
- data = data.map(row => this.renameFields(entityName, row));
157
+ data = data.map(row => {
158
+ this.handleVersionProperty(entityName, row, true);
159
+ return this.renameFields(entityName, row);
160
+ });
123
161
  options = { ...options };
124
162
  const meta = this.metadata.find(entityName);
125
163
  /* v8 ignore next */
@@ -157,6 +195,9 @@ export class MongoDriver extends DatabaseDriver {
157
195
  async aggregate(entityName, pipeline, ctx) {
158
196
  return this.rethrow(this.getConnection('read').aggregate(entityName, pipeline, ctx));
159
197
  }
198
+ async *streamAggregate(entityName, pipeline, ctx) {
199
+ yield* this.getConnection('read').streamAggregate(entityName, pipeline, ctx);
200
+ }
160
201
  getPlatform() {
161
202
  return this.platform;
162
203
  }
@@ -176,7 +217,7 @@ export class MongoDriver extends DatabaseDriver {
176
217
  for (let i = 0; i < copiedData.$and.length; i++) {
177
218
  const and = copiedData.$and[i];
178
219
  if ('$fulltext' in and) {
179
- /* v8 ignore next 3 */
220
+ /* v8 ignore next */
180
221
  if ('$fulltext' in copiedData) {
181
222
  throw new Error('Cannot merge multiple $fulltext conditions to top level of the query object.');
182
223
  }
@@ -196,8 +237,8 @@ export class MongoDriver extends DatabaseDriver {
196
237
  throw new Error('Full text search is only supported on the top level of the query object.');
197
238
  }
198
239
  Utils.keys(copiedData).forEach(k => {
199
- if (Utils.isGroupOperator(k)) {
200
- /* v8 ignore next 5 */
240
+ if (k in GroupOperator) {
241
+ /* v8 ignore next */
201
242
  if (Array.isArray(copiedData[k])) {
202
243
  copiedData[k] = copiedData[k].map(v => this.renameFields(entityName, v));
203
244
  }
@@ -210,7 +251,7 @@ export class MongoDriver extends DatabaseDriver {
210
251
  const prop = meta.properties[k];
211
252
  let isObjectId = false;
212
253
  if (prop.kind === ReferenceKind.SCALAR) {
213
- isObjectId = prop.type.toLowerCase() === 'objectid';
254
+ isObjectId = prop.type === 'ObjectId';
214
255
  }
215
256
  else if (prop.kind === ReferenceKind.EMBEDDED) {
216
257
  if (copiedData[prop.name] == null) {
@@ -226,7 +267,7 @@ export class MongoDriver extends DatabaseDriver {
226
267
  else {
227
268
  const meta2 = this.metadata.find(prop.type);
228
269
  const pk = meta2.properties[meta2.primaryKeys[0]];
229
- isObjectId = pk.type.toLowerCase() === 'objectid';
270
+ isObjectId = pk.type === 'ObjectId';
230
271
  }
231
272
  if (isObjectId) {
232
273
  copiedData[k] = this.convertObjectIds(copiedData[k]);
@@ -245,7 +286,7 @@ export class MongoDriver extends DatabaseDriver {
245
286
  if (data instanceof ObjectId) {
246
287
  return data;
247
288
  }
248
- if (Utils.isString(data) && data.match(/^[0-9a-f]{24}$/i)) {
289
+ if (typeof data === 'string' && data.match(/^[0-9a-f]{24}$/i)) {
249
290
  return new ObjectId(data);
250
291
  }
251
292
  if (Array.isArray(data)) {
@@ -260,7 +301,7 @@ export class MongoDriver extends DatabaseDriver {
260
301
  }
261
302
  buildFilterById(entityName, id) {
262
303
  const meta = this.metadata.find(entityName);
263
- if (meta.properties[meta.primaryKeys[0]].type.toLowerCase() === 'objectid') {
304
+ if (meta.properties[meta.primaryKeys[0]].type === 'ObjectId') {
264
305
  return { _id: new ObjectId(id) };
265
306
  }
266
307
  return { _id: id };
@@ -270,11 +311,11 @@ export class MongoDriver extends DatabaseDriver {
270
311
  if (!meta) {
271
312
  return fields;
272
313
  }
273
- const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => p.field === prop.name || p.all));
314
+ const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => this.isPopulated(meta, prop, p)));
274
315
  const ret = [];
275
316
  if (fields) {
276
317
  for (let field of fields) {
277
- /* v8 ignore next 3 */
318
+ /* v8 ignore next */
278
319
  if (Utils.isPlainObject(field)) {
279
320
  continue;
280
321
  }
@@ -282,7 +323,7 @@ export class MongoDriver extends DatabaseDriver {
282
323
  field = field.toString().substring(0, field.toString().indexOf('.'));
283
324
  }
284
325
  let prop = meta.properties[field];
285
- /* v8 ignore start */
326
+ /* v8 ignore next */
286
327
  if (prop) {
287
328
  if (!prop.fieldNames) {
288
329
  continue;
@@ -297,7 +338,6 @@ export class MongoDriver extends DatabaseDriver {
297
338
  else {
298
339
  ret.push(field);
299
340
  }
300
- /* v8 ignore stop */
301
341
  }
302
342
  ret.unshift(...meta.primaryKeys.filter(pk => !fields.includes(pk)));
303
343
  }
@@ -307,4 +347,17 @@ export class MongoDriver extends DatabaseDriver {
307
347
  }
308
348
  return ret.length > 0 ? ret : undefined;
309
349
  }
350
+ handleVersionProperty(entityName, data, update = false) {
351
+ const meta = this.metadata.find(entityName);
352
+ if (!meta?.versionProperty) {
353
+ return;
354
+ }
355
+ const versionProperty = meta.properties[meta.versionProperty];
356
+ if (versionProperty.runtimeType === 'Date') {
357
+ data[versionProperty.name] ??= new Date();
358
+ }
359
+ else {
360
+ data[versionProperty.name] ??= update ? { $inc: 1 } : 1;
361
+ }
362
+ }
310
363
  }
@@ -1,4 +1,4 @@
1
- import { EntityManager, type EntityName, type EntityRepository, type GetRepository, type TransactionOptions } from '@mikro-orm/core';
1
+ import { EntityManager, type EntityName, type EntityRepository, type GetRepository, type TransactionOptions, type StreamOptions, type NoInfer, type Loaded } from '@mikro-orm/core';
2
2
  import type { Collection, Document, TransactionOptions as MongoTransactionOptions } from 'mongodb';
3
3
  import type { MongoDriver } from './MongoDriver.js';
4
4
  import type { MongoEntityRepository } from './MongoEntityRepository.js';
@@ -10,6 +10,14 @@ export declare class MongoEntityManager<Driver extends MongoDriver = MongoDriver
10
10
  * Shortcut to driver's aggregate method. Available in MongoDriver only.
11
11
  */
12
12
  aggregate(entityName: EntityName<any>, pipeline: any[]): Promise<any[]>;
13
+ /**
14
+ * Shortcut to driver's aggregate method. Returns a stream. Available in MongoDriver only.
15
+ */
16
+ streamAggregate<T extends object>(entityName: EntityName<any>, pipeline: any[]): AsyncIterableIterator<T>;
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ stream<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entityName: EntityName<Entity>, options?: StreamOptions<NoInfer<Entity>, Hint, Fields, Excludes>): AsyncIterableIterator<Loaded<Entity, Hint, Fields, Excludes>>;
13
21
  getCollection<T extends Document>(entityName: EntityName<T>): Collection<T>;
14
22
  /**
15
23
  * @inheritDoc
@@ -1,4 +1,4 @@
1
- import { EntityManager, Utils } from '@mikro-orm/core';
1
+ import { EntityManager, Utils, } from '@mikro-orm/core';
2
2
  /**
3
3
  * @inheritDoc
4
4
  */
@@ -8,7 +8,23 @@ export class MongoEntityManager extends EntityManager {
8
8
  */
9
9
  async aggregate(entityName, pipeline) {
10
10
  entityName = Utils.className(entityName);
11
- return this.getDriver().aggregate(entityName, pipeline);
11
+ return this.getDriver().aggregate(entityName, pipeline, this.getTransactionContext());
12
+ }
13
+ /**
14
+ * Shortcut to driver's aggregate method. Returns a stream. Available in MongoDriver only.
15
+ */
16
+ async *streamAggregate(entityName, pipeline) {
17
+ entityName = Utils.className(entityName);
18
+ yield* this.getDriver().streamAggregate(entityName, pipeline, this.getTransactionContext());
19
+ }
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ async *stream(entityName, options = {}) {
24
+ if (!Utils.isEmpty(options.populate)) {
25
+ throw new Error('Populate option is not supported when streaming results in MongoDB');
26
+ }
27
+ yield* super.stream(entityName, options);
12
28
  }
13
29
  getCollection(entityName) {
14
30
  return this.getConnection().getCollection(entityName);
@@ -1,7 +1,7 @@
1
1
  import { ExceptionConverter, type Dictionary, type DriverException } from '@mikro-orm/core';
2
2
  export declare class MongoExceptionConverter extends ExceptionConverter {
3
3
  /**
4
- * @link https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
4
+ * @see https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
5
5
  */
6
6
  convertException(exception: Error & Dictionary): DriverException;
7
7
  }
@@ -1,9 +1,9 @@
1
1
  import { UniqueConstraintViolationException, ExceptionConverter, TableExistsException } from '@mikro-orm/core';
2
- /* v8 ignore start */
3
2
  export class MongoExceptionConverter extends ExceptionConverter {
4
3
  /**
5
- * @link https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
4
+ * @see https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
6
5
  */
6
+ /* v8 ignore next */
7
7
  convertException(exception) {
8
8
  switch (exception.code) {
9
9
  case 48:
@@ -14,4 +14,3 @@ export class MongoExceptionConverter extends ExceptionConverter {
14
14
  return super.convertException(exception);
15
15
  }
16
16
  }
17
- /* v8 ignore stop */
@@ -1,19 +1,22 @@
1
- import { MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from '@mikro-orm/core';
1
+ import { type AnyEntity, type EntityClass, type EntitySchema, MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType, type IMigrator } from '@mikro-orm/core';
2
2
  import { MongoDriver } from './MongoDriver.js';
3
3
  import type { MongoEntityManager } from './MongoEntityManager.js';
4
+ export type MongoOptions<EM extends MongoEntityManager = MongoEntityManager, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> = Options<MongoDriver, EM, Entities>;
5
+ export declare function defineMongoConfig<EM extends MongoEntityManager = MongoEntityManager, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: MongoOptions<EM, Entities>): Options<MongoDriver, EM, Entities>;
4
6
  /**
5
7
  * @inheritDoc
6
8
  */
7
- export declare class MongoMikroORM<EM extends EntityManager = MongoEntityManager> extends MikroORM<MongoDriver, EM> {
8
- private static DRIVER;
9
+ export declare class MongoMikroORM<EM extends MongoEntityManager = MongoEntityManager, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> extends MikroORM<MongoDriver, EM, Entities> {
9
10
  /**
10
11
  * @inheritDoc
11
12
  */
12
- static init<D extends IDatabaseDriver = MongoDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options?: Options<D, EM>): Promise<MikroORM<D, EM>>;
13
+ static init<D extends IDatabaseDriver = MongoDriver, EM extends EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities>): Promise<MikroORM<D, EM, Entities>>;
13
14
  /**
14
15
  * @inheritDoc
15
16
  */
16
- static initSync<D extends IDatabaseDriver = MongoDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options: Options<D, EM>): MikroORM<D, EM>;
17
+ constructor(options: Options<MongoDriver, EM, Entities>);
18
+ /**
19
+ * Gets the Migrator.
20
+ */
21
+ get migrator(): IMigrator;
17
22
  }
18
- export type MongoOptions = Options<MongoDriver>;
19
- export declare function defineMongoConfig(options: MongoOptions): Options<MongoDriver, MongoEntityManager<MongoDriver> & EntityManager<IDatabaseDriver<import("@mikro-orm/core").Connection>>>;
package/MongoMikroORM.js CHANGED
@@ -1,24 +1,28 @@
1
1
  import { defineConfig, MikroORM, } from '@mikro-orm/core';
2
2
  import { MongoDriver } from './MongoDriver.js';
3
+ export function defineMongoConfig(options) {
4
+ return defineConfig({ driver: MongoDriver, ...options });
5
+ }
3
6
  /**
4
7
  * @inheritDoc
5
8
  */
6
9
  export class MongoMikroORM extends MikroORM {
7
- static DRIVER = MongoDriver;
8
10
  /**
9
11
  * @inheritDoc
10
12
  */
11
13
  static async init(options) {
12
- return super.init(options);
14
+ return super.init(defineMongoConfig(options));
13
15
  }
14
16
  /**
15
17
  * @inheritDoc
16
18
  */
17
- static initSync(options) {
18
- return super.initSync(options);
19
+ constructor(options) {
20
+ super(defineMongoConfig(options));
21
+ }
22
+ /**
23
+ * Gets the Migrator.
24
+ */
25
+ get migrator() {
26
+ return this.driver.getPlatform().getExtension('Migrator', '@mikro-orm/migrator', '@mikro-orm/migrations-mongodb', this.em);
19
27
  }
20
- }
21
- /* v8 ignore next 3 */
22
- export function defineMongoConfig(options) {
23
- return defineConfig({ driver: MongoDriver, ...options });
24
28
  }
@@ -1,5 +1,5 @@
1
1
  import { ObjectId } from 'mongodb';
2
- import { Platform, type IPrimaryKey, type Primary, type NamingStrategy, type Constructor, type EntityRepository, type EntityProperty, type PopulateOptions, type EntityMetadata, type IDatabaseDriver, type EntityManager, type Configuration, type MikroORM } from '@mikro-orm/core';
2
+ import { Platform, type IPrimaryKey, type Primary, type NamingStrategy, type Constructor, type EntityRepository, type EntityProperty, type PopulateOptions, type EntityMetadata, type IDatabaseDriver, type EntityManager, type Configuration, type MikroORM, type TransformContext } from '@mikro-orm/core';
3
3
  import { MongoExceptionConverter } from './MongoExceptionConverter.js';
4
4
  import { MongoSchemaGenerator } from './MongoSchemaGenerator.js';
5
5
  export declare class MongoPlatform extends Platform {
@@ -16,12 +16,10 @@ export declare class MongoPlatform extends Platform {
16
16
  getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): MongoSchemaGenerator;
17
17
  normalizePrimaryKey<T extends number | string = number | string>(data: Primary<T> | IPrimaryKey | ObjectId): T;
18
18
  denormalizePrimaryKey(data: number | string): IPrimaryKey;
19
- getSerializedPrimaryKeyField(field: string): string;
20
- usesDifferentSerializedPrimaryKey(): boolean;
21
19
  usesImplicitTransactions(): boolean;
22
20
  convertsJsonAutomatically(): boolean;
23
21
  convertJsonToDatabaseValue(value: unknown): unknown;
24
- convertJsonToJSValue(value: unknown, prop: EntityProperty): unknown;
22
+ convertJsonToJSValue(value: unknown, context?: TransformContext): unknown;
25
23
  marshallArray(values: string[]): string;
26
24
  cloneEmbeddable<T>(data: T): T;
27
25
  shouldHaveColumn<T>(prop: EntityProperty<T>, populate: PopulateOptions<T>[], exclude?: string[]): boolean;
package/MongoPlatform.js CHANGED
@@ -32,12 +32,12 @@ export class MongoPlatform extends Platform {
32
32
  /* v8 ignore next */
33
33
  return super.getExtension(extensionName, extensionKey, moduleName, em);
34
34
  }
35
- /* v8 ignore next 3: kept for type inference only */
35
+ /* v8 ignore next: kept for type inference only */
36
36
  getSchemaGenerator(driver, em) {
37
37
  return new MongoSchemaGenerator(em ?? driver);
38
38
  }
39
39
  normalizePrimaryKey(data) {
40
- if (Utils.isObjectID(data)) {
40
+ if (Utils.isObject(data) && data.constructor?.name === 'ObjectId') {
41
41
  return data.toHexString();
42
42
  }
43
43
  return data;
@@ -45,12 +45,6 @@ export class MongoPlatform extends Platform {
45
45
  denormalizePrimaryKey(data) {
46
46
  return new ObjectId(data);
47
47
  }
48
- getSerializedPrimaryKeyField(field) {
49
- return 'id';
50
- }
51
- usesDifferentSerializedPrimaryKey() {
52
- return true;
53
- }
54
48
  usesImplicitTransactions() {
55
49
  return false;
56
50
  }
@@ -60,7 +54,7 @@ export class MongoPlatform extends Platform {
60
54
  convertJsonToDatabaseValue(value) {
61
55
  return Utils.copy(value);
62
56
  }
63
- convertJsonToJSValue(value, prop) {
57
+ convertJsonToJSValue(value, context) {
64
58
  return value;
65
59
  }
66
60
  marshallArray(values) {
@@ -2,13 +2,13 @@ import { AbstractSchemaGenerator, type CreateSchemaOptions, type MikroORM } from
2
2
  import type { MongoDriver } from './MongoDriver.js';
3
3
  export declare class MongoSchemaGenerator extends AbstractSchemaGenerator<MongoDriver> {
4
4
  static register(orm: MikroORM): void;
5
- createSchema(options?: MongoCreateSchemaOptions): Promise<void>;
6
- dropSchema(options?: {
5
+ create(options?: MongoCreateSchemaOptions): Promise<void>;
6
+ drop(options?: {
7
7
  dropMigrationsTable?: boolean;
8
8
  }): Promise<void>;
9
- updateSchema(options?: MongoCreateSchemaOptions): Promise<void>;
9
+ update(options?: MongoCreateSchemaOptions): Promise<void>;
10
10
  ensureDatabase(): Promise<boolean>;
11
- refreshDatabase(options?: MongoCreateSchemaOptions): Promise<void>;
11
+ refresh(options?: MongoCreateSchemaOptions): Promise<void>;
12
12
  dropIndexes(options?: {
13
13
  skipIndexes?: {
14
14
  collection: string;
@@ -17,7 +17,9 @@ export declare class MongoSchemaGenerator extends AbstractSchemaGenerator<MongoD
17
17
  collectionsWithFailedIndexes?: string[];
18
18
  }): Promise<void>;
19
19
  ensureIndexes(options?: EnsureIndexesOptions): Promise<void>;
20
+ private mapIndexProperties;
20
21
  private createIndexes;
22
+ private executeQuery;
21
23
  private createUniqueIndexes;
22
24
  private createPropertyIndexes;
23
25
  }
@@ -1,14 +1,14 @@
1
- import { AbstractSchemaGenerator, Utils, } from '@mikro-orm/core';
1
+ import { AbstractSchemaGenerator, Utils, inspect, } from '@mikro-orm/core';
2
2
  export class MongoSchemaGenerator extends AbstractSchemaGenerator {
3
3
  static register(orm) {
4
4
  orm.config.registerExtension('@mikro-orm/schema-generator', () => new MongoSchemaGenerator(orm.em));
5
5
  }
6
- async createSchema(options = {}) {
6
+ async create(options = {}) {
7
7
  await this.connection.ensureConnection();
8
8
  options.ensureIndexes ??= true;
9
9
  const existing = await this.connection.listCollections();
10
10
  const metadata = this.getOrderedMetadata();
11
- /* v8 ignore start */
11
+ /* v8 ignore next */
12
12
  const promises = metadata
13
13
  .filter(meta => !existing.includes(meta.collection))
14
14
  .map(meta => this.connection.createCollection(meta.collection).catch(err => {
@@ -18,13 +18,12 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
18
18
  throw err;
19
19
  }
20
20
  }));
21
- /* v8 ignore stop */
22
21
  if (options.ensureIndexes) {
23
22
  await this.ensureIndexes({ ensureCollections: false });
24
23
  }
25
24
  await Promise.all(promises);
26
25
  }
27
- async dropSchema(options = {}) {
26
+ async drop(options = {}) {
28
27
  await this.connection.ensureConnection();
29
28
  const existing = await this.connection.listCollections();
30
29
  const metadata = this.getOrderedMetadata();
@@ -36,16 +35,16 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
36
35
  .map(meta => this.connection.dropCollection(meta.collection));
37
36
  await Promise.all(promises);
38
37
  }
39
- async updateSchema(options = {}) {
40
- await this.createSchema(options);
38
+ async update(options = {}) {
39
+ await this.create(options);
41
40
  }
42
41
  async ensureDatabase() {
43
42
  return false;
44
43
  }
45
- async refreshDatabase(options = {}) {
44
+ async refresh(options = {}) {
46
45
  await this.ensureDatabase();
47
- await this.dropSchema();
48
- await this.createSchema(options);
46
+ await this.drop();
47
+ await this.create(options);
49
48
  }
50
49
  async dropIndexes(options) {
51
50
  await this.connection.ensureConnection();
@@ -59,9 +58,9 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
59
58
  const indexes = await db.collection(collection.name).listIndexes().toArray();
60
59
  for (const index of indexes) {
61
60
  const isIdIndex = index.key._id === 1 && Utils.getObjectKeysSize(index.key) === 1;
62
- /* v8 ignore next 3 */
61
+ /* v8 ignore next */
63
62
  if (!isIdIndex && !options?.skipIndexes?.find(idx => idx.collection === collection.name && idx.indexName === index.name)) {
64
- promises.push(db.collection(collection.name).dropIndex(index.name));
63
+ promises.push(this.executeQuery(db.collection(collection.name), 'dropIndex', index.name));
65
64
  }
66
65
  }
67
66
  }
@@ -72,7 +71,7 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
72
71
  options.ensureCollections ??= true;
73
72
  options.retryLimit ??= 3;
74
73
  if (options.ensureCollections) {
75
- await this.createSchema({ ensureIndexes: false });
74
+ await this.create({ ensureIndexes: false });
76
75
  }
77
76
  const promises = [];
78
77
  for (const meta of this.getOrderedMetadata()) {
@@ -113,11 +112,21 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
113
112
  });
114
113
  }
115
114
  }
115
+ mapIndexProperties(index, meta) {
116
+ return Utils.flatten(Utils.asArray(index.properties).map(propName => {
117
+ const rootPropName = propName.split('.')[0];
118
+ const prop = meta.properties[rootPropName];
119
+ if (propName.includes('.')) {
120
+ return [prop.fieldNames[0] + propName.substring(propName.indexOf('.'))];
121
+ }
122
+ return prop?.fieldNames ?? propName;
123
+ }));
124
+ }
116
125
  createIndexes(meta) {
117
126
  const res = [];
118
127
  meta.indexes.forEach(index => {
119
128
  let fieldOrSpec;
120
- const properties = Utils.flatten(Utils.asArray(index.properties).map(prop => meta.properties[prop].fieldNames));
129
+ const properties = this.mapIndexProperties(index, meta);
121
130
  const collection = this.connection.getCollection(meta.className);
122
131
  if (Array.isArray(index.options) && index.options.length === 2 && properties.length === 0) {
123
132
  res.push([collection.collectionName, collection.createIndex(index.options[0], index.options[1])]);
@@ -138,7 +147,7 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
138
147
  else {
139
148
  fieldOrSpec = properties.reduce((o, i) => { o[i] = 1; return o; }, {});
140
149
  }
141
- res.push([collection.collectionName, collection.createIndex(fieldOrSpec, {
150
+ res.push([collection.collectionName, this.executeQuery(collection, 'createIndex', fieldOrSpec, {
142
151
  name: index.name,
143
152
  unique: false,
144
153
  ...index.options,
@@ -146,13 +155,26 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
146
155
  });
147
156
  return res;
148
157
  }
158
+ async executeQuery(collection, method, ...args) {
159
+ const now = Date.now();
160
+ return collection[method](...args).then((res) => {
161
+ Utils.dropUndefinedProperties(args);
162
+ const query = `db.getCollection('${collection.collectionName}').${method}(${args.map(arg => inspect(arg)).join(', ')});`;
163
+ this.config.getLogger().logQuery({
164
+ level: 'info',
165
+ query,
166
+ took: Date.now() - now,
167
+ });
168
+ return res;
169
+ });
170
+ }
149
171
  createUniqueIndexes(meta) {
150
172
  const res = [];
151
173
  meta.uniques.forEach(index => {
152
- const properties = Utils.flatten(Utils.asArray(index.properties).map(prop => meta.properties[prop].fieldNames));
174
+ const properties = this.mapIndexProperties(index, meta);
153
175
  const fieldOrSpec = properties.reduce((o, i) => { o[i] = 1; return o; }, {});
154
176
  const collection = this.connection.getCollection(meta.className);
155
- res.push([collection.collectionName, collection.createIndex(fieldOrSpec, {
177
+ res.push([collection.collectionName, this.executeQuery(collection, 'createIndex', fieldOrSpec, {
156
178
  name: index.name,
157
179
  unique: true,
158
180
  ...index.options,
@@ -168,8 +190,8 @@ export class MongoSchemaGenerator extends AbstractSchemaGenerator {
168
190
  const fieldOrSpec = prop.embeddedPath
169
191
  ? prop.embeddedPath.join('.')
170
192
  : prop.fieldNames.reduce((o, i) => { o[i] = 1; return o; }, {});
171
- return [[collection.collectionName, collection.createIndex(fieldOrSpec, {
172
- name: (Utils.isString(prop[type]) ? prop[type] : undefined),
193
+ return [[collection.collectionName, this.executeQuery(collection, 'createIndex', fieldOrSpec, {
194
+ name: typeof prop[type] === 'string' ? prop[type] : undefined,
173
195
  unique: type === 'unique',
174
196
  sparse: prop.nullable === true,
175
197
  })]];
package/README.md CHANGED
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
11
11
  [![Chat on discord](https://img.shields.io/discord/1214904142443839538?label=discord&color=blue)](https://discord.gg/w8bjxFHS7X)
12
12
  [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://www.npmjs.com/package/@mikro-orm/core)
13
13
  [![Coverage Status](https://img.shields.io/coveralls/mikro-orm/mikro-orm.svg)](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
14
- [![Maintainability](https://api.codeclimate.com/v1/badges/27999651d3adc47cfa40/maintainability)](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
15
14
  [![Build Status](https://github.com/mikro-orm/mikro-orm/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
16
15
 
17
16
  ## 🤔 Unit of What?
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
141
140
  - [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
142
141
  - [Filters](https://mikro-orm.io/docs/filters)
143
142
  - [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
144
- - [Preloading Deeply Nested Structures via populate](https://mikro-orm.io/docs/nested-populate)
143
+ - [Populating relations](https://mikro-orm.io/docs/populating-relations)
145
144
  - [Property Validation](https://mikro-orm.io/docs/property-validation)
146
145
  - [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
147
146
  - [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
382
381
 
383
382
  Please ⭐️ this repository if this project helped you!
384
383
 
384
+ > If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
385
+
385
386
  ## 📝 License
386
387
 
387
388
  Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
package/index.d.ts CHANGED
@@ -8,4 +8,4 @@ export * from './MongoEntityRepository.js';
8
8
  export * from './MongoSchemaGenerator.js';
9
9
  export { MongoEntityManager as EntityManager } from './MongoEntityManager.js';
10
10
  export { MongoEntityRepository as EntityRepository } from './MongoEntityRepository.js';
11
- export { MongoMikroORM as MikroORM, MongoOptions as Options, defineMongoConfig as defineConfig, } from './MongoMikroORM.js';
11
+ export { MongoMikroORM as MikroORM, type MongoOptions as Options, defineMongoConfig as defineConfig, } from './MongoMikroORM.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikro-orm/mongodb",
3
3
  "type": "module",
4
- "version": "7.0.0-dev.9",
4
+ "version": "7.0.0-dev.91",
5
5
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
6
6
  "exports": {
7
7
  "./package.json": "./package.json",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "homepage": "https://mikro-orm.io",
40
40
  "engines": {
41
- "node": ">= 22.11.0"
41
+ "node": ">= 22.17.0"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "yarn clean && yarn compile && yarn copy",
@@ -50,12 +50,12 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "mongodb": "6.15.0"
53
+ "mongodb": "6.20.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@mikro-orm/core": "^6.4.13"
56
+ "@mikro-orm/core": "^6.6.2"
57
57
  },
58
58
  "peerDependencies": {
59
- "@mikro-orm/core": "7.0.0-dev.9"
59
+ "@mikro-orm/core": "7.0.0-dev.91"
60
60
  }
61
61
  }