Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom resolver won't load into i18n module #403

Open
BobbiSixkiller opened this issue Oct 21, 2022 · 8 comments · May be fixed by #483
Open

Custom resolver won't load into i18n module #403

BobbiSixkiller opened this issue Oct 21, 2022 · 8 comments · May be fixed by #483

Comments

@BobbiSixkiller
Copy link

BobbiSixkiller commented Oct 21, 2022

Hi I'd like to reopen this issue because with current version "^9.2.1" I can not successfuly import custom Resolver. I'm testing this the same way as OP. It doesn't run the console log in resolve method so I guess the resolver does not load to i18n service at all.

custom.resolver.ts

import { Injectable, ExecutionContext } from '@nestjs/common';
import { I18nResolver, I18nResolverOptions } from 'nestjs-i18n';
import { isRabbitContext } from '@golevelup/nestjs-rabbitmq';

@Injectable()
export class CustomResolver implements I18nResolver {
  constructor(@I18nResolverOptions() private keys: string[]) {}

  resolve(context: ExecutionContext) {
    let lang: string;
    console.log('HAJZLE');
    console.log(context);

    switch (context.getType() as string) {
      case 'rmq':
        const message = context.getArgs()[0];
        console.log(message);
    }

    return this.keys[1];
  }
}

email.module.ts

import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MailerModule } from '@nestjs-modules/mailer';
import { I18nModule, I18nService } from 'nestjs-i18n';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { join } from 'path';
import { EmailService } from './email.service';
import { CustomResolver } from 'src/email/custom.resolver';

@Module({
  imports: [
    I18nModule.forRootAsync({
      useFactory() {
        return {
          fallbackLanguage: 'sk',
          loaderOptions: {
            path: join(__dirname, '/locales/'),
            watch: true,
          },
        };
      },
      resolvers: [{ use: CustomResolver, options: ['en', 'sk'] }],
    }),
    MailerModule.forRootAsync({
      useFactory(config: ConfigService, i18n: I18nService) {
        return {
          transport: {
            host: 'smtp.mailtrap.io',
            secure: false,
            auth: {
              user: 'dfe6cc63fd2380',
              pass: 'b7e520dba14a13',
            },
          },
          defaults: {
            from: `"No Reply" <${config.get<string>('EMAIL_FROM')}>`,
          },
          template: {
            dir: join(__dirname, '/templates/'),
            adapter: new HandlebarsAdapter({ t: i18n.hbsHelper }),
            options: {
              strict: true,
            },
          },
        };
      },
      inject: [ConfigService, I18nService],
    }),
  ],
  providers: [EmailService],
})
export class EmailModule {}

thanks for any help in advance!

@toonvanstrijp
Copy link
Owner

@BobbiSixkiller can you send a small repo containing the issue? A zip is enough :)

@BobbiSixkiller
Copy link
Author

BobbiSixkiller commented Oct 21, 2022

First of all thanks a lot @toonvanstrijp for such a fast reply:) here's the link. Basically the idea is that the whole nestjs app consists of mail module and rmq module and responds to an incoming message from rmq by sending email. The email itself has to be localized and I wanted to use the custom resolver to resolve proper locale that comes in with the message object.

@Tomas2D
Copy link
Contributor

Tomas2D commented Oct 28, 2022

Having same issue, temporary downgraded to 9.1.10

@toonvanstrijp
Copy link
Owner

@BobbiSixkiller sorry for the late reply, do you still need help with this issue?

@BobbiSixkiller
Copy link
Author

@toonvanstrijp yes, I even tried to downgrade the version as mentioned by @Tomas2D but still no luck. Right now I set the locale when sending the mail via MailerService sendmail method's context property. Resolving the locale inside custom resolver based on incoming RMQ message would be way more ellegant in my opion. Thank's again for coming back to me btw.

@toonvanstrijp
Copy link
Owner

@BobbiSixkiller feel free to make a PR to support this. I've not worked with NestJS and RMQ before. So any help is welcome!

BANG88 added a commit to BANG88/nestjs-i18n that referenced this issue Apr 2, 2023
This change gives us a chance to implement any custom resolver we can.

eg: toonvanstrijp#403
@BANG88 BANG88 linked a pull request Apr 2, 2023 that will close this issue
@B0ER
Copy link

B0ER commented Oct 13, 2023

@BobbiSixkiller, tried to reproduce, just took sample/simple project with nestjs-i18n@9.2.3 and got correct logs and response.
(switch operator to rmq was commented)
image

If you could, it will be better to have attached package-lock, Interesting in nestjs packages' versions and nestjs-i18n
Also would be great to have tsconfig and ts version

@agilesoftgrowth
Copy link

example of custom resolver for rabbitmq

import { ExecutionContext, Injectable, Logger } from '@nestjs/common';

@Injectable()
export default class AmqpResolver implements I18nResolver {
  private logger = new Logger('I18nService');

  constructor(
    @I18nResolverOptions()
    private keys: string[] = ['x-lang'],
  ) {}

  resolve(context: ExecutionContext) {
    const ctx = context.switchToRpc().getContext();
    const message = ctx.getMessage();

    let lang: string;

    if (message) {
      for (const key of this.keys) {
        if (message?.properties?.headers[key] !== undefined) {
          this.logger.log(
            `Detected header '${key}' with value: '${message.properties.headers[key]}'`,
          );
          lang = message.properties.headers[key];
          break;
        }
      }
    }

    if (!lang) {
      this.logger.warn(
        `No language detected. None of the following headers were found in message: ${this.keys.join(', ')}`,
      );
    }

    return lang;
  }
}

and app.module.ts

import { Module } from '@nestjs/common';
import config from './config';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { EmailController } from './controller/email.controller';
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { join } from 'path';
import { EmailService } from './services/email.service';
import { I18nModule, I18nService } from 'nestjs-i18n';
import { AmqpResolver } from './common/resolver';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: config,
      isGlobal: true,
      cache: true,
      envFilePath: ['.env', '.env.local'],
      expandVariables: true,
    }),
    I18nModule.forRootAsync({
      useFactory: () => ({
        disableMiddleware: false,
        fallbackLanguage: 'en',
        viewEngine: 'hbs',
        loaderOptions: {
          path: join(__dirname, '/assets/i18n/'),
        },
      }),
      resolvers: [new AmqpResolver()],
    }),
    MailerModule.forRootAsync({
      inject: [ConfigService, I18nService],
      useFactory: (configs: ConfigService, i18n: I18nService) => {
        console.log(i18n.getTranslations());
        return {
          transport: {
            host: configs.get('smtp.host'),
            port: configs.get('smtp.port'),
            secure: configs.get('smtp.InsecureSkipVerify'),
            auth: {
              user: configs.get('smtp.user'),
              pass: configs.get('smtp.password'),
            },
          },
          template: {
            dir: join(__dirname, 'assets/template'),
            adapter: new HandlebarsAdapter({ t: i18n.hbsHelper }),
            options: {
              strict: true,
            },
          },
        };
      },
    }),
  ],
  controllers: [EmailController],
  providers: [EmailService],
})
export class AppModule {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants