添加条件Joi架构

时间:2017-12-29 14:08:53

标签: node.js joi

好的,我放弃了......

如何selectorSettings仅在selectorStrategy设置为tournament时显示?

selectorStrategy: joi.string().valid(['tournament',  'roulette']).default('tournament'),
selectorSettings: joi.any().when('selectorStrategy', { 
  is: 'tournament',
  then: joi.object().keys({
     tournamentSize: joi.number().integer().default(2),
     baseWeight: joi.number().integer().default(1)
   })
 })

我的选项中设置了stripUnknown: true。我的期望是,如果我通过:

 selectorStrategy: 'roulette',
 selectorSettings: { tournamentSize: 3 }

我会得到:

selectorStrategy: 'roulette'

如果我这样做:

selectorStrategy: 'tournament'

我会得到:

 selectorStrategy: 'tournament',
 selectorSettings: { tournamentSize: 2, baseWeight: 1 }

1 个答案:

答案 0 :(得分:5)

您需要设置selectorSettings默认值,并根据selectorStrategy的值有条件地将其删除。

让我们来看看你的两个用例。

根据兄弟值

删除密钥
const thing = {
  selectorStrategy: 'roulette',
  selectorSettings: { tournamentSize: 3 },
};

joi.validate(thing, schema, { stripUnknown: true} );
selectorSettings选项不会删除

stripUnknown,因为密钥不是未知的 - 它位于您的架构中。

我们需要根据selectorStrategy

的值明确删除它
.when('selectorStrategy', {
  is: 'tournament',
  otherwise: joi.strip(),
}),

根据兄弟值

添加/验证密钥
const thing = { 
  selectorStrategy: 'tournament'
};

joi.validate(thing, schema);

代码未设置selectorSettings密钥本身的默认值,仅设置其属性。由于不需要selectorSettings,验证通过。

我们需要设置默认值:

selectorSettings: joi
  .object()
  .default({ tournamentSize: 2, baseWeight: 1 })

处理这两种情况的修改代码如下所示:

const joi = require('joi');

const schema = {
  selectorStrategy: joi
    .string()
    .valid(['tournament', 'roulette'])
    .default('tournament'),
  selectorSettings: joi
    .object()
    .default({ tournamentSize: 2, baseWeight: 1 })
    .keys({
      tournamentSize: joi
        .number()
        .integer()
        .default(2),
      baseWeight: joi
        .number()
        .integer()
        .default(1),
    })
    .when('selectorStrategy', {
      is: 'tournament',
      otherwise: joi.strip(),
    }),
};

实施例

// should remove settings when not a tournament
var thing = {
  selectorStrategy: 'roulette',
  selectorSettings: { tournamentSize: 3 },
};

// returns
{
  "selectorStrategy": "roulette"
}

// should insert default settings
var thing = {
  selectorStrategy: 'tournament'
};

// returns
{
  "selectorStrategy": "tournament",
  "selectorSettings": {
    "tournamentSize": 2,
    "baseWeight": 1
  }
}

// should add missing baseWeight default
var thing = {
  selectorStrategy: 'tournament',
  selectorSettings: { tournamentSize: 5 } 
};

// returns
{
  "selectorStrategy": "tournament",
  "selectorSettings": {
    "tournamentSize": 5,
    "baseWeight": 1
  }
}