ExodusMovement / schemasafe

A reasonably safe JSON Schema validator with draft-04/06/07/2019-09/2020-12 support.
https://npmjs.com/@exodus/schemasafe
MIT License
161 stars 12 forks source link

discriminator: support enum schemas #128

Closed kklash closed 4 years ago

kklash commented 4 years ago

Currently the discriminator subset supports only const keyword schemas for the discriminating property.

We should extend this to allow enum keyword schemas as well.

Consider this example schema, which takes an object and asserts the string property key matches the integer property value:

{
  "type": "object",
  "required": ["key"],
  "unevaluatedProperties": false,
  "oneOf": [
    {
      "required": [],
      "properties": {
        "key": { "const": "one" },
        "value": { "const": 1 }
      }
    },
    {
      "required": [],
      "properties": {
        "key": { "const": "ONE" },
        "value": { "const": 1 }
      }
    },

    {
      "required": [],
      "properties": {
        "key": { "const": "two" },
        "value": { "const": 2 }
      }
    },
    {
      "required": [],
      "properties": {
        "key": { "const": "TWO" },
        "value": { "const": 2 }
      }
    }
  ]
}
{ "key": "one", "value": 1 } // OK
{ "key": "TWO", "value": 2 } // OK
{ "key": "TWO", "value": 1 } // ERROR
{ "key": "one", "value": 2 } // ERROR
{ "key": "foo", "value": 1 } // ERROR

This could easily be simplified by allowing the discriminator to accept enums on the discriminating key property. Then you could do:

{
  "type": "object",
  "required": ["key"],
  "unevaluatedProperties": false,
  "oneOf": [
    {
      "required": [],
      "properties": {
        "key": { "enum": ["one", "ONE"] },
        "value": { "const": 1 }
      }
    },
    {
      "required": [],
      "properties": {
        "key": { "enum": ["two", "TWO"] },
        "value": { "const": 2 }
      }
    }
  ]
}

And add more options to the enums, catching any number of "discriminatee's" and validating them against a schema that you only need to declare once.

Mixing const and enum keyword discriminator schemas would be fine, as long as the discriminating property values are unique strings