jsonapi-parser 0.1.1.beta3 → 0.1.1
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 +4 -4
- data/README.md +8 -1
- data/lib/jsonapi/parser/document.rb +2 -20
- metadata +51 -11
- data/lib/draft.rb +0 -151
- data/lib/jsonapi/exceptions.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 578891b6fc4f7b92a99ed7faf32e7293cdc14c3d
|
4
|
+
data.tar.gz: 9a90fae41ec97af4a3dbe7025b792d658077633e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d0d4be5a368f4a5b4607cbb99147bad6618e89eb236f68a4720da025f23f456f6454b78fc92942afcebdc4a4033b20cd75bceacb5c2f12def5f16ed72d4ea71
|
7
|
+
data.tar.gz: c41d00603ee49098e7bf425939b436bce7f5c53bc0112b7c58b030a8abb616bff9e02884b6f28ea9c4c0fe7ec0b9b3a403617af3f17cfb385429c42c352e38d6
|
data/README.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# jsonapi-parser
|
2
|
-
Ruby gem for
|
2
|
+
Ruby gem for validating [JSON API](http://jsonapi.org) documents.
|
3
|
+
|
4
|
+
## Status
|
5
|
+
|
6
|
+
[](https://badge.fury.io/rb/jsonapi-parser)
|
7
|
+
[](http://travis-ci.org/jsonapi-rb/parser?branch=master)
|
8
|
+
[](https://codecov.io/gh/jsonapi-rb/parser)
|
9
|
+
[](https://gitter.im/jsonapi-rb/Lobby)
|
3
10
|
|
4
11
|
## Installation
|
5
12
|
```ruby
|
@@ -4,12 +4,7 @@ module JSONAPI
|
|
4
4
|
module Parser
|
5
5
|
class Document
|
6
6
|
TOP_LEVEL_KEYS = %w(data errors meta).freeze
|
7
|
-
EXTENDED_TOP_LEVEL_KEYS =
|
8
|
-
(TOP_LEVEL_KEYS + %w(jsonapi links included)).freeze
|
9
|
-
RESOURCE_KEYS = %w(id type attributes relationships links meta).freeze
|
10
7
|
RESOURCE_IDENTIFIER_KEYS = %w(id type).freeze
|
11
|
-
EXTENDED_RESOURCE_IDENTIFIER_KEYS =
|
12
|
-
(RESOURCE_IDENTIFIER_KEYS + %w(meta)).freeze
|
13
8
|
RELATIONSHIP_KEYS = %w(data links meta).freeze
|
14
9
|
RELATIONSHIP_LINK_KEYS = %w(self related).freeze
|
15
10
|
JSONAPI_OBJECT_KEYS = %w(version meta).freeze
|
@@ -22,9 +17,6 @@ module JSONAPI
|
|
22
17
|
ensure!(document.is_a?(Hash),
|
23
18
|
'A JSON object MUST be at the root of every JSON API request ' \
|
24
19
|
'and response containing data.')
|
25
|
-
unexpected_keys = document.keys - EXTENDED_TOP_LEVEL_KEYS
|
26
|
-
ensure!(unexpected_keys.empty?,
|
27
|
-
"Unexpected members at top level: #{unexpected_keys}.")
|
28
20
|
ensure!(!(document.keys & TOP_LEVEL_KEYS).empty?,
|
29
21
|
"A document MUST contain at least one of #{TOP_LEVEL_KEYS}.")
|
30
22
|
ensure!(!(document.key?('data') && document.key?('errors')),
|
@@ -59,9 +51,6 @@ module JSONAPI
|
|
59
51
|
def self.parse_primary_resource!(res)
|
60
52
|
ensure!(res.is_a?(Hash), 'A resource object must be an object.')
|
61
53
|
ensure!(res.key?('type'), 'A resource object must have a type.')
|
62
|
-
unexpected_keys = res.keys - RESOURCE_KEYS
|
63
|
-
ensure!(unexpected_keys.empty?,
|
64
|
-
"Unexpected members for primary resource: #{unexpected_keys}")
|
65
54
|
parse_attributes!(res['attributes']) if res.key?('attributes')
|
66
55
|
parse_relationships!(res['relationships']) if res.key?('relationships')
|
67
56
|
parse_links!(res['links']) if res.key?('links')
|
@@ -90,9 +79,6 @@ module JSONAPI
|
|
90
79
|
# @api private
|
91
80
|
def self.parse_relationship!(rel)
|
92
81
|
ensure!(rel.is_a?(Hash), 'A relationship object must be an object.')
|
93
|
-
unexpected_keys = rel.keys - RELATIONSHIP_KEYS
|
94
|
-
ensure!(unexpected_keys.empty?,
|
95
|
-
"Unexpected members for relationship: #{unexpected_keys}")
|
96
82
|
ensure!(!rel.keys.empty?,
|
97
83
|
'A relationship object MUST contain at least one of ' \
|
98
84
|
"#{RELATIONSHIP_KEYS}")
|
@@ -119,10 +105,6 @@ module JSONAPI
|
|
119
105
|
def self.parse_resource_identifier!(ri)
|
120
106
|
ensure!(ri.is_a?(Hash),
|
121
107
|
'A resource identifier object must be an object')
|
122
|
-
unexpected_keys = ri.keys - EXTENDED_RESOURCE_IDENTIFIER_KEYS
|
123
|
-
ensure!(unexpected_keys.empty?,
|
124
|
-
'Unexpected members for resource identifier: ' \
|
125
|
-
"#{unexpected_keys}.")
|
126
108
|
ensure!(RESOURCE_IDENTIFIER_KEYS & ri.keys == RESOURCE_IDENTIFIER_KEYS,
|
127
109
|
'A resource identifier object MUST contain ' \
|
128
110
|
"#{RESOURCE_IDENTIFIER_KEYS} members.")
|
@@ -188,11 +170,11 @@ module JSONAPI
|
|
188
170
|
def self.parse_errors!(errors)
|
189
171
|
ensure!(errors.is_a?(Array),
|
190
172
|
'Top level errors member must be an array.')
|
191
|
-
errors.each { |error|
|
173
|
+
errors.each { |error| parse_error!(error) }
|
192
174
|
end
|
193
175
|
|
194
176
|
# @api private
|
195
|
-
def self.
|
177
|
+
def self.parse_error!(_error)
|
196
178
|
# NOTE(beauby): Do nothing for now, as errors are under-specified as of
|
197
179
|
# JSONAPI 1.0
|
198
180
|
end
|
metadata
CHANGED
@@ -1,16 +1,58 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2016-12-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '11.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '11.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: codecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
55
|
+
description: Validate JSONAPI response documents, resource creation/update payloads,
|
14
56
|
and relationship update payloads.
|
15
57
|
email: lucas.hosseini@gmail.com
|
16
58
|
executables: []
|
@@ -18,14 +60,12 @@ extensions: []
|
|
18
60
|
extra_rdoc_files: []
|
19
61
|
files:
|
20
62
|
- README.md
|
21
|
-
- lib/draft.rb
|
22
|
-
- lib/jsonapi/exceptions.rb
|
23
63
|
- lib/jsonapi/parser.rb
|
24
64
|
- lib/jsonapi/parser/document.rb
|
25
65
|
- lib/jsonapi/parser/exceptions.rb
|
26
66
|
- lib/jsonapi/parser/relationship.rb
|
27
67
|
- lib/jsonapi/parser/resource.rb
|
28
|
-
homepage: https://github.com/
|
68
|
+
homepage: https://github.com/jsonapi-rb/jsonapi-parser
|
29
69
|
licenses:
|
30
70
|
- MIT
|
31
71
|
metadata: {}
|
@@ -40,13 +80,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
80
|
version: '0'
|
41
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
82
|
requirements:
|
43
|
-
- - "
|
83
|
+
- - ">="
|
44
84
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
85
|
+
version: '0'
|
46
86
|
requirements: []
|
47
87
|
rubyforge_project:
|
48
|
-
rubygems_version: 2.
|
88
|
+
rubygems_version: 2.6.8
|
49
89
|
signing_key:
|
50
90
|
specification_version: 4
|
51
|
-
summary:
|
91
|
+
summary: Validate JSON API documents.
|
52
92
|
test_files: []
|
data/lib/draft.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class Validator
|
3
|
-
class << self
|
4
|
-
TOP_LEVEL_KEYS = [:data, :errors, :meta].freeze
|
5
|
-
EXTENDED_TOP_LEVEL_KEYS = (TOP_LEVEL_KEYS +
|
6
|
-
[:jsonapi, :links, :included]).freeze
|
7
|
-
RESOURCE_KEYS = [:id, :type, :attributes, :relationships, :links,
|
8
|
-
:meta].freeze
|
9
|
-
RESOURCE_IDENTIFIER_KEYS = [:id, :type].freeze
|
10
|
-
EXTENDED_RESOURCE_IDENTIFIER_KEYS = (RESOURCE_IDENTIFIER_KEYS +
|
11
|
-
[:meta]).freeze
|
12
|
-
RELATIONSHIP_KEYS = [:data, :links, :meta].freeze
|
13
|
-
RELATIONSHIP_LINK_KEYS = [:self, :related].freeze
|
14
|
-
JSONAPI_OBJECT_KEYS = [:version, :meta].freeze
|
15
|
-
|
16
|
-
# Validate the structure of a JSON API document.
|
17
|
-
def validate!(document)
|
18
|
-
@document = document
|
19
|
-
raise InvalidDocument unless @document.is_a?(Hash)
|
20
|
-
raise InvalidDocument if @document.keys.empty?
|
21
|
-
raise InvalidDocument unless (@document.keys - EXTENDED_TOP_LEVEL_KEYS).empty?
|
22
|
-
raise InvalidDocument if (@document.keys & TOP_LEVEL_KEYS).empty?
|
23
|
-
raise InvalidDocument if @document.key?(:data) && @document.key?(:errors)
|
24
|
-
raise InvalidDocument if @document.key?(:included) && !@document.key?(:data)
|
25
|
-
validate_data!(@document[:data]) if @document.key?(:data)
|
26
|
-
validate_errors!(@document[:errors]) if @document.key?(:errors)
|
27
|
-
validate_meta!(@document[:meta]) if @document.key?(:meta)
|
28
|
-
validate_jsonapi!(@document[:jsonapi]) if @document.key?(:jsonapi)
|
29
|
-
validate_included!(@document[:included]) if @document.key?(:included)
|
30
|
-
validate_links!(@document[:links]) if @document.key?(:links)
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def validate_data!(data)
|
36
|
-
if data.is_a?(Hash)
|
37
|
-
validate_primary_resource!(data)
|
38
|
-
elsif data.is_a?(Array)
|
39
|
-
data.each { |res| validate_resource!(res) }
|
40
|
-
elsif data.nil?
|
41
|
-
# Do nothing
|
42
|
-
else
|
43
|
-
raise InvalidDocument
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def validate_primary_resource!(res)
|
48
|
-
raise InvalidDocument unless res.is_a?(Hash)
|
49
|
-
raise InvalidDocument unless res.key?(:type)
|
50
|
-
raise InvalidDocument unless (res.keys - RESOURCE_KEYS).empty?
|
51
|
-
validate_attributes!(res[:attributes]) if res.key?(:attributes)
|
52
|
-
validate_relationships!(res[:relationships]) if res.key?(:relationships)
|
53
|
-
validate_links!(res[:links]) if res.key?(:links)
|
54
|
-
validate_meta!(res[:meta]) if res.key?(:meta)
|
55
|
-
end
|
56
|
-
|
57
|
-
def validate_resource!(res)
|
58
|
-
validate_primary_resource!(res)
|
59
|
-
raise InvalidDocument unless res.key?(:id)
|
60
|
-
end
|
61
|
-
|
62
|
-
def validate_attributes!(attrs)
|
63
|
-
raise InvalidDocument unless attrs.is_a?(Hash)
|
64
|
-
end
|
65
|
-
|
66
|
-
def validate_relationships!(rels)
|
67
|
-
raise InvalidDocument unless rels.is_a?(Hash)
|
68
|
-
rels.values.each { |rel| validate_relationship!(rel) }
|
69
|
-
end
|
70
|
-
|
71
|
-
def validate_relationship(rel)
|
72
|
-
raise InvalidDocument unless rel.is_a?(Hash)
|
73
|
-
raise InvalidDocument unless (rel.keys - RELATIONSHIP_KEYS).empty?
|
74
|
-
raise InvalidDocument if rel.keys.empty?
|
75
|
-
validate_relationship_data!(rel[:data]) if rel.key?(:data)
|
76
|
-
validate_relationship_links!(rel[:links]) if rel.key?(:links)
|
77
|
-
validate_meta!(rel[:meta]) if rel.key?(:meta)
|
78
|
-
end
|
79
|
-
|
80
|
-
def validate_relationship_data!(data)
|
81
|
-
if data.is_a?(Hash)
|
82
|
-
validate_resource_identifier!(data)
|
83
|
-
elsif data.is_a?(Array)
|
84
|
-
data.each { |ri| validate_resource_identifier!(ri) }
|
85
|
-
elsif data.nil?
|
86
|
-
# Do nothing
|
87
|
-
else
|
88
|
-
raise InvalidDocument
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def validate_resource_identifier!(ri)
|
93
|
-
raise InvalidDocument unless ri.is_a?(Hash)
|
94
|
-
raise InvalidDocument unless (ri.keys -
|
95
|
-
EXTENDED_RESOURCE_IDENTIFIER_KEYS).empty?
|
96
|
-
raise InvalidDocument unless ri.keys != RESOURCE_IDENTIFIER_KEYS
|
97
|
-
raise InvalidDocument unless ri[:id].is_a?(String)
|
98
|
-
raise InvalidDocument unless ri[:type].is_a?(String)
|
99
|
-
validate_meta!(ri[:meta]) if ri.key?(:meta)
|
100
|
-
end
|
101
|
-
|
102
|
-
def validate_relationship_links(links)
|
103
|
-
validate_links!(links)
|
104
|
-
raise InvalidDocument if (rel.keys & RELATIONSHIP_LINK_KEYS).empty?
|
105
|
-
end
|
106
|
-
|
107
|
-
def validate_links!(links)
|
108
|
-
raise InvalidDocument unless links.is_a?(Hash)
|
109
|
-
links.each { |link| validate_link!(link) }
|
110
|
-
end
|
111
|
-
|
112
|
-
def validate_link!(link)
|
113
|
-
if link.is_a?(String)
|
114
|
-
# Do nothing
|
115
|
-
elsif link.is_a?(Hash)
|
116
|
-
# TODO(beauby): Pending clarification request github.com/json-api/json-api/issues/1103
|
117
|
-
else
|
118
|
-
raise InvalidDocument
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def validate_meta!(meta)
|
123
|
-
raise InvalidDocument unless meta.is_a?(Hash)
|
124
|
-
end
|
125
|
-
|
126
|
-
def validate_jsonapi!(jsonapi)
|
127
|
-
raise InvalidDocument unless jsonapi.is_a?(Hash)
|
128
|
-
raise InvalidDocument unless (jsonapi.keys - JSONAPI_OBJECT_KEYS).empty?
|
129
|
-
if jsonapi.key?(:version)
|
130
|
-
raise InvalidDocument unless jsonapi[:version].is_a?(String)
|
131
|
-
end
|
132
|
-
validate_meta!(jsonapi[:meta]) if jsonapi.key?(:meta)
|
133
|
-
end
|
134
|
-
|
135
|
-
def validate_included!(included)
|
136
|
-
raise InvalidDocument unless included.is_a?(Array)
|
137
|
-
included.each { |res| validate_resource!(res) }
|
138
|
-
end
|
139
|
-
|
140
|
-
def validate_errors!(errors)
|
141
|
-
raise InvalidDocument unless errors.is_a?(Array)
|
142
|
-
errors.each { |error| validate_error!(error) }
|
143
|
-
end
|
144
|
-
|
145
|
-
def validate_error!(error)
|
146
|
-
# NOTE(beauby): Do nothing for now, as errors are under-specified as of
|
147
|
-
# JSONAPI 1.0
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
data/lib/jsonapi/exceptions.rb
DELETED
File without changes
|