hecks-plugins-json-validator 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|