hecks-plugins-json-validator 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/hecks-plugins-json-validator.rb +58 -0
- data/lib/matchers.rb +17 -0
- data/lib/parsers/message_parser.rb +37 -0
- data/lib/parsers/schema_parser.rb +71 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -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
|
data/lib/matchers.rb
ADDED
@@ -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: []
|