Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to remove in a hash the properties that do not exists in its JSON schema? #443

Open
gordielachance opened this issue Mar 6, 2020 · 1 comment

Comments

@gordielachance
Copy link

gordielachance commented Mar 6, 2020

Hi !
Thanks for your awesome work.

I would like to use your validator to "clean" my input compared to the JSON schema.
Thing is, for what I see, JSON::Validator.validate only returns a boolean and does not offer a way to return a "cleaned" hash. Would it be possible ?

schema = {
  'type': 'object',
  'properties': {
    'A'=>{
      'type': 'object',
      'properties': {
        'AsubA'=>{
          'type': 'string',
        },
        'AsubB'=>{
          'type': 'string',
          'default'=>'it s',
          'readOnly'=>true
        },
        'AsubC'=>{
          'type': 'string',
          'default'=>'foo',
          'readOnly'=>true
        },
      }
    },
    'B'=>{
      'type': 'string',
      'default'=>'bar',
    }
  }
}

input = {
  'A'=>{
    'AsubA'=>'hello',
    'AsubC'=>'me',
    'AsubD'=>'i was',
    'AsubE'=>'wondering',
  },
  'B'=>'if after',
  'C'=>'all those years',
}

the magic would happen here and give

output = {
  'A'=>{
    'AsubA'=>'hello',
    'AsubB'=>'it's', #filled with the default value of the schema since input was not set
    'AsubC'=>'foo', #schema is readonly and has a default
  },
  'B'=>'if after',
}

thanks

@gordielachance
Copy link
Author

I currently use this function to set the defaults based on the schema, but this does not remove the unecessary properties (which I would need).
AND it is redundant since you already do this type of work in your code. You should just make it accessible ...

Thanks

def defaultsFromSchema(node,readonly=false,nodekeys=[],datas={})
  return unless node.is_a?(Hash)

  defaultValue = node.dig('default');
  isReadOnly = ( node.dig('readOnly') === true )

  if defaultValue
    if ( !readonly || (readonly && isReadOnly) )
      #create hash and set deep keys
      return nodekeys.reverse.inject(defaultValue) { |a, n| { n => a } }
    end

  else
    node.each do |k, v|
      keys = nodekeys.clone
      if k != 'properties'
        keys.push(k)
      end

      append = defaultsFromSchema(v,readonly,keys,datas)
      if append
        datas = datas.deep_merge(append)
      end

    end
  end

  datas

end

defaults = defaultsFromSchema(schema) 
readonly = defaultsFromSchema(schema,true)
output = defaults.deep_merge(input).deep_merge(readonly)

With this, I almost got it except that I don't know how to remove the unecessary keys in output.

@gordielachance gordielachance changed the title use validator to get a cleaned input ? how to remove in a hash the properties that do not exists in its JSON schema? Mar 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant