karenetheridge / JSON-Schema-Modern

Validate data against a schema using a JSON Schema
https://metacpan.org/release/JSON-Schema-Modern/
Other
10 stars 1 forks source link

collect annotations #6

Closed karenetheridge closed 4 years ago

karenetheridge commented 4 years ago

unknown keywords should become annotations. standard annotation keywords in the meta-data, content and format vocabularies should be collected. existing applicator and validation keywords that can produce annotations should have them collected.

https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.7.3 https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7 https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.8 https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9

karenetheridge commented 4 years ago

Note that there are some legacy keywords that are still defined in the main metaschema (https://json-schema.org/draft/2019-09/schema) and should not result in annotation collection: definitions and dependencies (see https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.appendix.A)

karenetheridge commented 4 years ago

Also add a configuration option that collects annotations for all unrecognized/unknown keywords.

karenetheridge commented 4 years ago
if (my $result = $js->evaluate($instance_data, $schema_data_or_name)) {
  my $data = $result->data_with_defaults;
  # or rather:
  my $data = Mojo::JSON::Pointer->new(dclone($instance_data));   # from Storable
  foreach (my $annotation = $result->annotations) {  # maybe sort annotations by instance_location
    next if $annotation->keyword ne 'default';
    next if $data->contains($annotation->instance_location);
    $data->set($annotation->instance_location, $annotation->value);
  }
  # which could be abstracted out as:
  $data->decorate_with('default', $result->annotations); # maybe?
}
else {
  $c->render(400, ... something with $result->errors to create a response body);
}

where ::Result::data_with_annotations takes a copy of the instance data and overlays on top of it (using a Mojo::JSON::Pointer extension that needs to be written) all the annotations of type 'default' at their respective instance_locations (if a property did not exist there yet).

karenetheridge commented 4 years ago

done with release 0.011.