Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
583 views
in Technique[技术] by (71.8m points)

typescript - NestJS : nested async inits in dynamic modules

In my main module (A), I import an external module (B) with its configuration:

imports: [
NestAuthModule.registerAsync({
  inject: [authConfig.KEY],
  useFactory: async (config: ConfigType<typeof authConfig>) => ({
    google: config.google,
    jwt: config.jwt,
  }),
})
]
export class NestAuthModule {
  static registerAsync(options: AuthModuleAsyncOptions): DynamicModule {
    return this.createModule(
      this.createAsyncProviders(options),
      options.imports || []
    );
  }

  private static createModule(
    providers: Provider[],
    imports: Array<
      Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference
    >
  ) {
    return {
      module: NestAuthModule,
      controllers: [AuthController],
      providers: [
        ...providers
      ],
      imports: [
        ...imports,
        JwtModule.registerAsync({
          inject: [AuthModuleOptions],
          useFactory: async (options: AuthModuleOptions) => {
            return {
              secret: options.jwt.secretKey,
              signOptions: {
                expiresIn: options.jwt.expires,
              },
            };
          },
        }),
      ],
      exports: [AuthModuleOptions],
    };
  }

  private static createAsyncProviders(
    options: AuthModuleAsyncOptions
  ): Provider[] {
    if (options.useExisting || options.useFactory) {
      return [this.createAsyncOptionsProvider(options)];
    } else if (options.useClass) {
      return [
        this.createAsyncOptionsProvider(options),
        {
          provide: options.useClass,
          useClass: options.useClass,
        },
      ];
    }
    throw new Error('missing provider config');
  }

  private static createAsyncOptionsProvider(
    options: AuthModuleAsyncOptions
  ): Provider {
    const useFactory =
      options.useFactory ??
      (async (optionsFactory: AuthOptionsFactory) =>
        await optionsFactory.createAuthOptions());
    const inject = options.useFactory
      ? options.inject || []
      : [options.useExisting || options.useClass];
    return {
      provide: AuthModuleOptions,
      useFactory,
      inject,
    };
  }
}

Notice that in module B, I am importing a third party module using a factory and it needs module B configuration. However, it is not yet available because it is async. It is going to be provided when module is finally instanced. However, I am already injecting this provider in my imports. So, I get an injection error:

[ExceptionHandler] Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument AuthModuleOptions at index [0] is available in the JwtModule context.
Potential solutions:
- If AuthModuleOptions is a provider, is it part of the current JwtModule?

I am pretty sure there is a solution, but I haven't found it yet.

question from:https://stackoverflow.com/questions/65875076/nestjs-nested-async-inits-in-dynamic-modules

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...