Как проверить данные на основе входного значения с помощью AJV?

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

То, что я пытаюсь проверить, это: - enabled всегда требуется, - если enabled = true, то должно быть предоставлено только одно из других свойств (realtime, threshold или digest),

Примеры полезной нагрузки и ожидаемые результаты:

Должен пройти

{
  "notifications": {
    "enabled": false
  }
}

Должен пройти

{
  "notifications": {
    "enabled": true,
    "realtime": true
  }
}

Должен пройти

{
  "notifications": {
    "enabled": true,
    "digest": true
  }
}

Должен пройти

{
  "notifications": {
    "enabled": true,
    "threshold": {}
  }
}

Должен завершиться ошибкой, поскольку enabled = true, но никакое другое свойство не установлено.

{
  "notifications": {
    "enabled": true
  }
}

Должен завершиться ошибкой, поскольку enabled = true и установлено более одного другого свойства.

{
  "notifications": {
    "enabled": true,
    "threshold": {},
    "digest: true
  }
}

Вот схема проверки, которую я использую:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Settings",
  "type": "object",
  "properties": {
    "notifications": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "realtime": {
          "type": "boolean"
        },
        "threshold": {
          "type": "object",
          "properties": {
            "detections": {
              "type": "number"
            },
            "elapsed": {
              "type": "number"
            }
          },
          "required": ["detections", "elapsed"]
        },
        "digest": {
          "type": "boolean"
        }
      },
      "required": ["enabled"],
      "if": {
        "properties": { "enabled": true }
      },
      "then": {
        "oneOf": [
          { "required": [ "realtime" ] },
          { "required": [ "threshold" ] },
          { "required": [ "digest" ] }
        ]
      }
    }
  }
}

Благодарю вас!


person Stefan    schedule 13.12.2019    source источник
comment
Вы говорите, что у вас есть эта схема, но она не работает?   -  person Relequestual    schedule 13.12.2019
comment
не могу понять в чем ваш вопрос. Можете ли вы быть более конкретным, пожалуйста? Может быть, приведите некоторые данные в качестве примера данных, которые вы ожидаете пройти и не пройти?   -  person Relequestual    schedule 13.12.2019
comment
@Relequestual - я обновил вопрос, не стесняйтесь попробовать.   -  person Stefan    schedule 16.12.2019
comment
Ваше решение почти такое же, как то, что я предложил бы, поскольку вы обновили свой вопрос.   -  person Relequestual    schedule 16.12.2019


Ответы (1)


Оказывается, я был очень близок, и проблема заключалась в том, как оператор if оценивался для true. Вот правильная схема, которая проверяет (проходит и не проходит) все приведенные выше примеры, как и ожидалось:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Settings",
  "type": "object",
  "properties": {
    "notifications": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "realtime": {
          "type": "boolean"
        },
        "threshold": {
          "type": "object",
          "properties": {
            "detections": {
              "type": "number"
            },
            "elapsed": {
              "type": "number"
            }
          },
          "required": ["detections", "elapsed"]
        },
        "digest": {
          "type": "boolean"
        }
      },
      "required": ["enabled"],
      "if": {
        "enabled": {
          "const": true
        }
      },
      "then": {
        "oneOf": [
          {
            "required": ["realtime"]
          },
          {
            "required": ["threshold"]
          },
          {
            "required": ["digest"]
          }
        ]
      }
    }
  }
}

Эта часть сделала свое дело:

"if": {
    "properties": {
        "enabled": {
            "const": true
        }
    }
}
person Stefan    schedule 16.12.2019