【问题标题】:Nested object in Joi schemaJoi 模式中的嵌套对象
【发布时间】:2022-01-31 19:56:41
【问题描述】:

我已经通过 Joi 在 AWS 值中使用嵌套对象定义了验证模式:

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(),
});

然后我把我的架构放到配置模块中

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

我在 .env 文件中添加了 AWS 变量的下一个值:

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

但我在开始嵌套后收到了下一条错误消息:

> 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 返回一个 string 并且 Joi 不明白他应该解析它,也许我需要在 validationOptions 中添加一些或者我错过了一些东西。我该如何解决?

【问题讨论】:

  • 它可能取决于您的节点版本。你运行的是哪个版本?
  • 在您发表评论后,我尝试了v14.17.3v16.13.2,但得到了相同的结果
  • @OroCan 好的。感谢您的反馈。你能看看这个链接:stackoverflow.com/a/63285574/14807111 吗?
  • 无法理解它对我有何帮助。我的问题仅在于嵌套的 Joi 对象,我可以访问其他环境变量而不会出现任何错误。你能澄清一下你的观点吗?
  • 好的。我认为他通常在读取 .env 数据时遇到问题。我没有正确理解。

标签: javascript nestjs joi


【解决方案1】:

从 Joi v16.0.0 开始,对象和数组字符串强制不再作为内置选项提供。

您可以通过扩展 Joi 来复制此功能。例如:

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]
        };
      }
    }
  }
});

然后在您的架构中使用JoiCustom

const schema = Joi.object({
    ...
    AWS: JoiCustom.object({
        ...
    }).required()
});

【讨论】:

  • 很好用,我已经修复了您的示例的一些语法错误,现在它可以正常工作了。我已将编辑后的版本发送给您的答案,当它被社区接受时,它将是可见的
猜你喜欢
  • 2016-08-12
  • 2021-09-06
  • 2020-02-14
  • 2018-02-27
  • 2018-02-20
  • 2020-06-01
  • 2016-09-14
  • 2017-01-28
  • 1970-01-01
相关资源
最近更新 更多