Сбой вложенных условий Joi `when` в определении схемы с ошибкой `ERR_ASSERTION`

#node.js #joi

#node.js #joi

Вопрос:

Я пытался работать с Joi (старая версия 14.3.1) для создания схемы, и, к сожалению, я застрял. Я пробовал несколько способов определения схем, но результаты всегда приходят с ошибкой в определении схемы.

Вот мое определение схемы:

  const allowedUser = {
    admin: 'ADMIN',
    normal: 'NORMAL'
  };

  const schema = validator
    .object()
    .keys({
      user: validator.any().valid(Object.values(allowedUser)).required(),
      context: validator.object().default({})
    })
    .when('user', {
      is: allowedUser.admin,
      then: validator.when(validator.object({ context: validator.exist() }), {
        then: validator.object().keys({
          session: validator.string().required()
        })
      })
    })
    .when('user', {
      is: allowedUser.normal,
      then: validator.when(validator.object({ context: validator.exist() }), {
        then: validator.object().keys({
          id: validator.string().required()
        })
      })
    });
  

Другое определение схемы, которое я пробовал:

   const schema = validator.object().keys({
    user: validator.any().valid(Object.values(allowedUser)).required(),
    context: validator
      .object()
      .when('user', {
        is: allowedUser.admin,
        then: validator.when('context', {
          is: validator.exist(),
          then: validator.object().keys({
            session: validator.string().required()
          })
        })
      })
      .when('user', {
        is: allowedUser.normal,
        then: validator.when('context', {
          is: validator.exist(),
          then: validator.object().keys({
            id: validator.string().required()
          })
        })
      })
      .default({})
  });
  

Итак, условия для схемы следующие:

  1. В случае user типа ADMIN : если context свойство определено, оно должно содержать свойство session . если context свойство не определено, оно должно установить значение по умолчанию равным {}
  2. В случае user типа NORMAL : если context свойство определено, оно должно содержать свойство id . если context свойство не определено, оно должно установить значение по умолчанию равным {}
  3. Неявный случай, если context свойство содержит неизвестное свойство, оно также должно завершиться неудачей

Когда я запускаю код, я всегда получаю ошибку в определении схемы, которая выглядит следующим образом:

 AssertionError [ERR_ASSERTION]: Cannot merge type object with another type: alternatives
    
  

Мой минимальный пример кода выглядит следующим образом:

 const validator = require('joi');


  const allowedUser = {
    admin: 'ADMIN',
    normal: 'NORMAL'
  };

  const bodyWhenUndefined = {
    user: 'ADMIN',
    message: 'Hi'
  };

  const bodyWhenValidDefined = {
    user: 'ADMIN',
    message: 'Hi'
  };


  const bodyWhenDefinedEmpty = {
    user: 'ADMIN',
    message: 'Hi 2',
    context: {}
  };

  const bodyWhenDefinedWrong = {
    user: 'admin',
    message: 'Hi 3',
    context: {abc: 'wrong property'}
  };

  const schema = validator
    .object()
    .keys({
      user: validator.any().valid(Object.values(allowedUser)).required(),
      context: validator.object().default({})
    })
    .when('user', {
      is: allowedUser.admin,
      then: validator.when(validator.object({ context: validator.exist() }), {
        then: validator.object().keys({
          session: validator.string().required()
        })
      })
    })
    .when('user', {
      is: allowedUser.normal,
      then: validator.when(validator.object({ context: validator.exist() }), {
        then: validator.object().keys({
          id: validator.string().required()
        })
      })
    });


   const resultSuccess = validator.validate(bodyWhenValidDefined, schema);
    console.log("This is with success in validation",resultSuccess.value);

    const result = validator.validate(bodyWhenUndefined, schema);
    console.log("This is with default context property",result.value);


    const resultWithEmptyError = validator.validate(bodyWhenDefinedEmpty, schema);
    console.log("This should come with error with required property session",resultWithEmptyError.error);

    const resultWithWrongProp = validator.validate(bodyWhenDefinedWrong, schema);
    console.log("This should come with error with required property session",resultWithWrongProp.error);


  

Я создал рабочую скрипку REPL здесь, была бы признательна помощь, чтобы рассказать мне, где я делаю неправильно.

Ответ №1:

Итак, благодаря REPL, найденному здесь. Я получил представление о том, как вложенная схема может быть определена на основе значения родственного свойства. Вы можете просто предоставить then условие объекту и определить требуемые свойства. вот рабочая схема:

   const schema = validator.object().keys({
    user: validator.any().valid(Object.values(allowedUser)).required(),
    message: validator.string(),
    context: validator
      .object()
      .when('user', {
        is: allowedUser.admin,
        then: {
          session: validator.required()
        }
      })
      .when('user', {
        is: allowedUser.normal,
        then: {
          id: validator.required()
        }
      })
      .default({})
  });