0

I've defined validation schema via Joi with nested object in AWS value:

const schema = Joi.object({
  NODE_ENV: Joi.string()
    .valid('development', 'production', 'test')
    .default('development'),
  PORT: Joi.number().default(3000),
  AWS: Joi.object({
    accessKeyId: Joi.string().required(),
    secretAccessKey: Joi.string().required(),
    region: Joi.string().required(),
    bucket: Joi.string().required(),
  }).required(),
});

Then I put my schema to config module

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: schema,
      validationOptions: {
        abortEarly: false,
        cache: false,
      },
    }),
    FilesModule,
    UsersModule,
    PostsModule,
    SharedModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

I've added inside .env file the next value for AWS variable:

AWS={"region": "string", "accessKeyId":"string", "secretAccessKey": "string", "bucket": "string"}

but I got the next error message after starting nest:

> project-8v@0.0.1 start /Volumes/MacDATA/NestJs/project-8v
> nest start


/Volumes/MacDATA/Lern/NestJs/project-8v/node_modules/@nestjs/config/dist/config.module.js:66
                throw new Error(`Config validation error: ${error.message}`);
                      ^
Error: Config validation error: "AWS" must be of type object

typeof process.env.AWS returns a string and Joi doesn't understand that he should parse it, maybe I need to add some in validationOptions or I miss something. How can I solve it?

Oro
  • 2,250
  • 1
  • 6
  • 22
  • it can depend on your node version. Which version you are run? – Maik Lowrey Jan 31 '22 at 08:03
  • 1
    After your comment I tried`v14.17.3` and with `v16.13.2`, but got the same result – Oro Jan 31 '22 at 08:38
  • @OroCan Ok. Thank you for feedback. Can you take a look on this link: https://stackoverflow.com/a/63285574/14807111 ? – Maik Lowrey Jan 31 '22 at 09:00
  • Cannot understand how it can help me. My problem is only with the nested Joi object, I can access other env variables without any errors. Could you clarify your point? – Oro Jan 31 '22 at 09:13
  • ok. i thought he generally has problems reading in the .env data. i didn't understand correctly. – Maik Lowrey Jan 31 '22 at 09:15

1 Answers1

2

As of Joi v16.0.0, object and array string coercion is no longer available as a built-in option.

You can replicate this functionality by extending Joi. For example:

const JoiCustom = Joi.extend({
  type: 'object',
  base: Joi.object(),
  coerce: {
    from: 'string',
    method(value) {
      if (value[0] !== '{' && !/^\s*{/.test(value)) {
        return {
          value
        };
      }
      try {
        return { value: JSON.parse(value) };
      } catch (error) {
        return {
          errors: [error]
        };
      }
    }
  }
});

Then use JoiCustom in your schema:

const schema = Joi.object({
    ...
    AWS: JoiCustom.object({
        ...
    }).required()
});
Ankh
  • 5,478
  • 3
  • 36
  • 40
  • 1
    Great it works, I've fixed some syntax errors of your example and now it works properly. I've sent the edited version to your answer, when it will be accepted by the community it will be visible – Oro Jan 31 '22 at 11:03