diff --git a/lib/config.module.ts b/lib/config.module.ts index 55a6ac89..5572a74d 100644 --- a/lib/config.module.ts +++ b/lib/config.module.ts @@ -53,7 +53,7 @@ export class ConfigModule { * Also, registers custom configurations globally. * @param options */ - static forRoot(options: ConfigModuleOptions = {}): DynamicModule { + static async forRoot(options: ConfigModuleOptions = {}): Promise { const envFilePaths = Array.isArray(options.envFilePath) ? options.envFilePath : [options.envFilePath || resolve(process.cwd(), '.env')]; @@ -88,7 +88,8 @@ export class ConfigModule { } const isConfigToLoad = options.load && options.load.length; - const providers = (options.load || []) + const configFactory = options.load ? await Promise.all(options.load.map((configFactory) => configFactory)) : []; + const providers = configFactory .map(factory => createConfigProvider(factory as ConfigFactory & ConfigFactoryKeyHost), ) diff --git a/lib/interfaces/config-module-options.interface.ts b/lib/interfaces/config-module-options.interface.ts index 90e149b9..de5b5695 100644 --- a/lib/interfaces/config-module-options.interface.ts +++ b/lib/interfaces/config-module-options.interface.ts @@ -57,7 +57,7 @@ export interface ConfigModuleOptions { * Array of custom configuration files to be loaded. * See: https://docs.nestjs.com/techniques/configuration */ - load?: Array; + load?: Array>; /** * A boolean value indicating the use of expanded variables, or object diff --git a/tests/e2e/load-files-async.spec.ts b/tests/e2e/load-files-async.spec.ts new file mode 100644 index 00000000..eea26064 --- /dev/null +++ b/tests/e2e/load-files-async.spec.ts @@ -0,0 +1,31 @@ +import { INestApplication } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import { AppModule } from '../src/app.module'; + +describe('Async Files', () => { + let app: INestApplication; + + beforeEach(async () => { + const module = await Test.createTestingModule({ + imports: [AppModule.withLoadedAsyncConfigurations()], + }).compile(); + + app = module.createNestApplication(); + await app.init(); + }); + + it(`should return loaded configuration`, () => { + const host = app.get(AppModule).getDatabaseHost(); + expect(host).toEqual('host'); + }); + + it(`should return loaded configuration (injected through constructor)`, () => { + const config = app.get(AppModule).getDatabaseConfig(); + expect(config.host).toEqual('host'); + expect(config.port).toEqual(4000); + }); + + afterEach(async () => { + await app.close(); + }); +}); diff --git a/tests/src/app.module.ts b/tests/src/app.module.ts index a7c4cb47..5d39b1de 100644 --- a/tests/src/app.module.ts +++ b/tests/src/app.module.ts @@ -140,6 +140,17 @@ export class AppModule { }; } + static withLoadedAsyncConfigurations() { + return { + module: AppModule, + imports: [ + ConfigModule.forRoot({ + load: [Promise.resolve(databaseConfig)], + }), + ], + }; + } + static withNestedLoadedConfigurations(): DynamicModule { return { module: AppModule,