fastest-validator icon indicating copy to clipboard operation
fastest-validator copied to clipboard

feature request: `map` rule

Open zen-crab opened this issue 4 years ago • 12 comments

Is it possible to write a schema that validates an object whose keys aren't known, but the schema of the values are?

For example:

const obj = {
  steve: {
    age: 30,
    score: 100
  },
  doug: {
    age: 40,
    score: 10
  },
  bob: {
    age: 10,
    score: 3
  }
}`

In the data I'm being provided, the keys can be any valid key name but their values are objects with a consistent schema. 

zen-crab avatar Nov 05 '21 01:11 zen-crab

Please explain it better.

icebob avatar Nov 06 '21 10:11 icebob

@icebob he/she means something like this

schema = {
   "*": "string"
}

erfanium avatar Nov 06 '21 11:11 erfanium

Ahh, thanks. For this purpose, we use custom validators.

icebob avatar Nov 06 '21 11:11 icebob

@icebob I think we can introduce a new rule called Map for these kind of usages.

const schema = {
   dictionary: {
      type: "map",
      key: "string", // or number, default: string
      value: { type: "object": props: { foo: "string" } }
   }
}

erfanium avatar Nov 06 '21 12:11 erfanium

Please explain it better.

Say I have a data source that returns the current active users of a service:

    const status = {
      timestamp: 1233113131,
      numUsers: 3,
      uptime: 201,
      users: {
        steve_carlos: {
          email: '[email protected]',
          account_type: 'premium',
          last_login: 11244114
        },
        doug_flutey: {
          // same props as steve_carlos
        },
        mike_jones: {
          // same props
        }
      }
    }

I can't write a schema to validate this object because the keys of users change depending on which users are online. It's no problem to validate the objects within users because they have a known and unchanging schema, however validating the entire status object requires multiple schemas and multiple checks because there is currently no way to validate an object's props without explicitly listing the prop's name in the schema.

So basically I need to validate an object much in the same was as an array is validated. For example, if items is provided instead of props, iterate through the keys of the object.

zen-crab avatar Nov 06 '21 20:11 zen-crab

@icebob I think we can introduce a new rule called Map for these kind of usages.

const schema = {
   dictionary: {
      type: "map",
      key: "string", // or number, default: string
      value: { type: "object": props: { foo: "string" } }
   }
}

Does type: "map" here refer to a JS Map? I ask because a key in a JS Map can be any value (Object, function, string, primitives, etc).

zen-crab avatar Nov 06 '21 20:11 zen-crab

@sbmelvin You are doing it wrong. If you are the owner of the service, I recommend you just use arrays to represent online users. your response body would be like this:

    const status = {
      timestamp: 1233113131,
      numUsers: 3,
      uptime: 201,
      users: [
        {
          email: '[email protected]',
          name: 'steve_carlos'
          account_type: 'premium',
          last_login: 11244114
        },
        {
          name: 'doug_flutey'
          // same props as steve_carlos
        },
        {
          name: 'mike_jones'
          // same props
        }
      ]
    }

That's the expected way of using JSON

erfanium avatar Nov 06 '21 20:11 erfanium

You are doing it wrong. That's the expected way of using JSON

That is irrelevant. This is not a style guide, it's a validator. Also, what you posted is not JSON fwiw.

If you are the owner of the service

I'm not but that is also irrelevant. I should not have to change the structure of syntactically correct javascript in order to have it validated. My data comes from drones and remote sensors that cannot be updated once deployed.

For the record, Joi and Ajv support this feature.

https://joi.dev/api/?v=17.4.2#objectpatternpattern-schema-options

https://ajv.js.org/json-schema.html#patternproperties

zen-crab avatar Nov 06 '21 22:11 zen-crab

Keep open, because the @erfanium map rule is a good idea.

icebob avatar Nov 08 '21 17:11 icebob

+1. really strange map is not here.

askaribragimov avatar Feb 10 '22 13:02 askaribragimov

@icebob As far as I know, nobody works on it. I have a similar custom rule in my project and I think I can implement it here.

FFKL avatar Jun 30 '22 21:06 FFKL

Yeah, it would be great, please open a PR with your implementation.

icebob avatar Jul 10 '22 17:07 icebob