Skip to content

Commit

Permalink
feat: allow passing an array of options into forRoot
Browse files Browse the repository at this point in the history
Since MikroORM v6.4, you can also define [multiple configurations](https://mikro-orm.io/docs/quick-start#configuration-file-structure) as part of a single ORM config. If you want to use such a combined config file, you need to destructure the result, since it will be also an array:

```typescript
@module({
  imports: [
    // `config` exports an array of configs
    ...MikroOrmModule.forRoot(config),
    MikroOrmModule.forMiddleware()
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Closes #202
  • Loading branch information
B4nan committed Jan 28, 2025
1 parent 98171c4 commit 02e78b3
Showing 4 changed files with 40 additions and 6 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -365,6 +365,21 @@ You can define multiple database connections by registering multiple `MikroOrmMo
export class AppModule {}
```

Since MikroORM v6.4, you can also define [multiple configurations](https://mikro-orm.io/docs/quick-start#configuration-file-structure) as part of a single ORM config. If you want to use such a combined config file, you need to destructure the result, since it will be also an array:

```typescript
@Module({
imports: [
// `config` exports an array of configs
...MikroOrmModule.forRoot(config),
MikroOrmModule.forMiddleware()
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
```

To access different `MikroORM`/`EntityManager` connections you have to use the new injection tokens `@InjectMikroORM()`/`@InjectEntityManager()` where you are required to pass the `contextName` in:

```ts
16 changes: 14 additions & 2 deletions src/mikro-orm-core.module.ts
Original file line number Diff line number Diff line change
@@ -47,7 +47,13 @@ export class MikroOrmCoreModule implements NestModule, OnApplicationShutdown {
private readonly options: MikroOrmModuleOptions,
private readonly moduleRef: ModuleRef) { }

static async forRoot(options?: MikroOrmModuleSyncOptions): Promise<DynamicModule> {
static async forRoot(options?: MikroOrmModuleSyncOptions): Promise<DynamicModule>;
static async forRoot(options?: MikroOrmModuleSyncOptions[]): Promise<DynamicModule[]>;
static async forRoot(options?: MikroOrmModuleSyncOptions | MikroOrmModuleSyncOptions[]): Promise<DynamicModule | DynamicModule[]> {
if (Array.isArray(options)) {
return Promise.all(options.map(o => this.forRoot(o)));
}

const contextName = this.setContextName(options?.contextName);
const knex = await tryRequire('@mikro-orm/knex');
const mongo = await tryRequire('@mikro-orm/mongodb');
@@ -98,7 +104,13 @@ export class MikroOrmCoreModule implements NestModule, OnApplicationShutdown {
};
}

static async forRootAsync(options: MikroOrmModuleAsyncOptions): Promise<DynamicModule> {
static async forRootAsync(options: MikroOrmModuleAsyncOptions): Promise<DynamicModule>;
static async forRootAsync(options: MikroOrmModuleAsyncOptions[]): Promise<DynamicModule[]>;
static async forRootAsync(options: MikroOrmModuleAsyncOptions | MikroOrmModuleAsyncOptions[]): Promise<DynamicModule | DynamicModule[]> {
if (Array.isArray(options)) {
return Promise.all(options.map(o => this.forRootAsync(o)));
}

const contextName = this.setContextName(options?.contextName);
const knex = await tryRequire('@mikro-orm/knex');
const mongo = await tryRequire('@mikro-orm/mongodb');
13 changes: 9 additions & 4 deletions src/mikro-orm.module.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import {
MikroOrmModuleFeatureOptions,
MikroOrmModuleSyncOptions,
MikroOrmMiddlewareModuleOptions,
MaybePromise,
} from './typings';

@Module({})
@@ -23,12 +24,16 @@ export class MikroOrmModule {
MikroOrmEntitiesStorage.clear(contextName);
}

static forRoot(options?: MikroOrmModuleSyncOptions): DynamicModule | Promise<DynamicModule> {
return MikroOrmCoreModule.forRoot(options);
static forRoot(options?: MikroOrmModuleSyncOptions): MaybePromise<DynamicModule>;
static forRoot(options?: MikroOrmModuleSyncOptions[]): MaybePromise<DynamicModule[]>;
static forRoot(options?: MikroOrmModuleSyncOptions | MikroOrmModuleSyncOptions[]): MaybePromise<DynamicModule | DynamicModule[]> {
return MikroOrmCoreModule.forRoot(options as MikroOrmModuleSyncOptions);
}

static forRootAsync(options: MikroOrmModuleAsyncOptions): DynamicModule | Promise<DynamicModule> {
return MikroOrmCoreModule.forRootAsync(options);
static forRootAsync(options: MikroOrmModuleAsyncOptions): MaybePromise<DynamicModule>;
static forRootAsync(options: MikroOrmModuleAsyncOptions[]): MaybePromise<DynamicModule[]>;
static forRootAsync(options: MikroOrmModuleAsyncOptions | MikroOrmModuleAsyncOptions[]): MaybePromise<DynamicModule | DynamicModule[]> {
return MikroOrmCoreModule.forRootAsync(options as MikroOrmModuleAsyncOptions);
}

static forFeature(options: EntityName<AnyEntity>[] | MikroOrmModuleFeatureOptions, contextName?: string): DynamicModule {
2 changes: 2 additions & 0 deletions src/typings.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ import type { AnyEntity, EntityName as CoreEntityName, EntitySchema, ForkOptions
import type { MiddlewareConsumer, ModuleMetadata, Scope, Type } from '@nestjs/common';
import type { AbstractHttpAdapter } from '@nestjs/core';

export type MaybePromise<T> = T | Promise<T>;

export interface NestMiddlewareConsumer extends MiddlewareConsumer {
httpAdapter: AbstractHttpAdapter;
}

0 comments on commit 02e78b3

Please sign in to comment.