hecks-plugins-json-validator 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5b20be7162ce46d038b8ef5c5551dfd7764a39a
4
+ data.tar.gz: 0ae13e35cab1100d8dd1c8ca4b46c9d6b9fc4548
5
+ SHA512:
6
+ metadata.gz: 8479f09a701a2ed7b19c6651790d641f6a2e4eeec40bcec5f12221632d84d48e51e7dbea77de0b1e3b4dec94a72868e5d9d846e75e8167cbdaf3c73c28c6d74c
7
+ data.tar.gz: 8dbfb5194d61bbb1e4139a7b688fc276f0899c85524dacab61657bdcd81574273b49324264938ec20ab319a1ac18e2bc53ba77212570641a803f28fd62aea84f
@@ -0,0 +1,58 @@
1
+ require 'json-schema'
2
+ require_relative 'matchers'
3
+ require_relative 'parsers/schema_parser'
4
+ require_relative 'parsers/message_parser'
5
+
6
+ module HecksPlugins
7
+ # A validator that is built on top of json-schema to provide more
8
+ # functionality than the basic hecks validator. Builds a json schema
9
+ # from a head spec and validates the user's input against it.
10
+ class JSONValidator
11
+ attr_reader :errors
12
+
13
+ def initialize(command:)
14
+ @args = command.args
15
+ @domain_module = command.domain_module
16
+ @errors = {}
17
+ @schema_parser = SchemaParser.new(
18
+ domain_module: domain_module,
19
+ object: command.domain_module.head
20
+ ).call
21
+
22
+ @validator = JSON::Validator
23
+ end
24
+
25
+ def call
26
+ parse_schema
27
+ validate
28
+ self
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :args, :domain_module, :schema, :schema_parser, :validator
34
+
35
+ def parse_schema
36
+ @schema = schema_parser.schema
37
+ end
38
+
39
+ def validate
40
+ MATCHERS.each do |matcher|
41
+ result = validator.fully_validate(schema, args, errors_as_objects: true)
42
+
43
+ result.each do |error|
44
+ parser = MessageParser.new(matcher: matcher, error: error).call
45
+ next unless parser.message
46
+ if parser.fragment && parser.fragment != parser.field_name
47
+ errors[parser.fragment] ||= {}
48
+ errors[parser.fragment][parser.field_name] ||= []
49
+ errors[parser.fragment][parser.field_name] << parser.message
50
+ else
51
+ errors[parser.field_name] ||= []
52
+ errors[parser.field_name] << parser.message
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,17 @@
1
+ #
2
+ module HecksPlugins
3
+ class JSONValidator
4
+ # These matchers create a cleaner, more user-friendly message out of the
5
+ # messages returned by json-schema
6
+ MATCHERS = [
7
+ {
8
+ regex: /did not contain a required property of '(.*)' in schema/,
9
+ message: 'Missing'
10
+ },
11
+ {
12
+ regex: /The property '#\/(.*)' of type (.*) did not match the following type: (.*) in schema/,
13
+ message: 'Type mismatch. Got \'%s\', should have been \'%s\''
14
+ }
15
+ ]
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ module HecksPlugins
2
+ class JSONValidator
3
+ # Turn the json-schema messages into easy to understand errors for the user
4
+ class MessageParser
5
+ attr_reader :message, :field_name, :fragment
6
+
7
+ def initialize(matcher:, error:)
8
+ @matcher = matcher
9
+ @error = error
10
+ @match = error[:message].match(matcher[:regex])
11
+ @fragment = error[:fragment].gsub('#/', '')
12
+ if fragment == ''
13
+ @fragment = nil
14
+ else
15
+ @fragment = fragment.to_sym
16
+ end
17
+
18
+ end
19
+
20
+ def call
21
+ parse_match
22
+ self
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :match, :matcher, :error
28
+
29
+ def parse_match
30
+ return unless match
31
+ @message = matcher[:message]
32
+ @message = message % match[2..-1] if match.length > 2
33
+ @field_name = match[1].to_sym
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,71 @@
1
+ module HecksPlugins
2
+ class JSONValidator
3
+ # Create a JSON Schema from an object
4
+ class SchemaParser
5
+ attr_reader :schema
6
+ JSON_TYPES = %w{string number object array boolean null}
7
+ HECKS_NUMBER_TYPES = %w{integer currency}
8
+
9
+ def initialize domain_module:, object:
10
+ @domain_module = domain_module
11
+ @object = object
12
+ @properties = {}
13
+ end
14
+
15
+ def call
16
+ parse_required_fields
17
+ object.attributes.each { |a| parse_property(a) }
18
+ build_schema
19
+ self
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :required_fields, :object, :properties, :domain_module
25
+
26
+ def build_schema
27
+ @schema = {
28
+ "type" => "object",
29
+ "required" => required_fields,
30
+ "properties" => properties
31
+ }
32
+ end
33
+
34
+ def parse_required_fields
35
+ @required_fields = object.attributes.map{ |a| a.name }
36
+ end
37
+
38
+ def get_json_type attribute
39
+ result = attribute.type.downcase
40
+ return 'array' if attribute.list?
41
+ return 'number' if HECKS_NUMBER_TYPES.include?(result)
42
+ return 'object' unless JSON_TYPES.include?(result)
43
+
44
+ result
45
+ end
46
+
47
+ def schema_for_attribute attribute
48
+ return {} if attribute.reference?
49
+ self.class.new(
50
+ domain_module: domain_module,
51
+ object: domain_module.find(attribute.type)
52
+ ).call.schema
53
+ end
54
+
55
+ def parse_property(attribute)
56
+ type = get_json_type(attribute)
57
+ name = attribute.name
58
+ properties[name] =
59
+ case type
60
+ when 'object' then schema_for_attribute(attribute)
61
+ when 'array'
62
+ {
63
+ "type" => 'array',
64
+ "items" => schema_for_attribute(attribute)
65
+ }
66
+ else { "type" => type }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hecks-plugins-json-validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Young
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json-schema
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ description: Hecks JSON Schema Validations
28
+ email: chris@example.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/hecks-plugins-json-validator.rb
34
+ - lib/matchers.rb
35
+ - lib/parsers/message_parser.rb
36
+ - lib/parsers/schema_parser.rb
37
+ homepage: https://github.com/chrisyoung/hecks
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.6.10
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Advanced Domain Validations Based on JSON Schema http://json-schema.org/
61
+ test_files: []