From 02e78b3438e19c9f8a9792fe422451498473ec56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Tue, 28 Jan 2025 18:46:39 +0100 Subject: [PATCH] feat: allow passing an array of options into `forRoot` 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 --- README.md | 15 +++++++++++++++ src/mikro-orm-core.module.ts | 16 ++++++++++++++-- src/mikro-orm.module.ts | 13 +++++++++---- src/typings.ts | 2 ++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a0d3d63..d6b5a47 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/mikro-orm-core.module.ts b/src/mikro-orm-core.module.ts index 71e7f2a..1ad7a86 100644 --- a/src/mikro-orm-core.module.ts +++ b/src/mikro-orm-core.module.ts @@ -47,7 +47,13 @@ export class MikroOrmCoreModule implements NestModule, OnApplicationShutdown { private readonly options: MikroOrmModuleOptions, private readonly moduleRef: ModuleRef) { } - static async forRoot(options?: MikroOrmModuleSyncOptions): Promise { + static async forRoot(options?: MikroOrmModuleSyncOptions): Promise; + static async forRoot(options?: MikroOrmModuleSyncOptions[]): Promise; + static async forRoot(options?: MikroOrmModuleSyncOptions | MikroOrmModuleSyncOptions[]): Promise { + 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 { + static async forRootAsync(options: MikroOrmModuleAsyncOptions): Promise; + static async forRootAsync(options: MikroOrmModuleAsyncOptions[]): Promise; + static async forRootAsync(options: MikroOrmModuleAsyncOptions | MikroOrmModuleAsyncOptions[]): Promise { + 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'); diff --git a/src/mikro-orm.module.ts b/src/mikro-orm.module.ts index ef8607c..c8920e6 100644 --- a/src/mikro-orm.module.ts +++ b/src/mikro-orm.module.ts @@ -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 { - return MikroOrmCoreModule.forRoot(options); + static forRoot(options?: MikroOrmModuleSyncOptions): MaybePromise; + static forRoot(options?: MikroOrmModuleSyncOptions[]): MaybePromise; + static forRoot(options?: MikroOrmModuleSyncOptions | MikroOrmModuleSyncOptions[]): MaybePromise { + return MikroOrmCoreModule.forRoot(options as MikroOrmModuleSyncOptions); } - static forRootAsync(options: MikroOrmModuleAsyncOptions): DynamicModule | Promise { - return MikroOrmCoreModule.forRootAsync(options); + static forRootAsync(options: MikroOrmModuleAsyncOptions): MaybePromise; + static forRootAsync(options: MikroOrmModuleAsyncOptions[]): MaybePromise; + static forRootAsync(options: MikroOrmModuleAsyncOptions | MikroOrmModuleAsyncOptions[]): MaybePromise { + return MikroOrmCoreModule.forRootAsync(options as MikroOrmModuleAsyncOptions); } static forFeature(options: EntityName[] | MikroOrmModuleFeatureOptions, contextName?: string): DynamicModule { diff --git a/src/typings.ts b/src/typings.ts index ccfc6e0..e3a351b 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -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 | Promise; + export interface NestMiddlewareConsumer extends MiddlewareConsumer { httpAdapter: AbstractHttpAdapter; }