json_api_client 1.23.0 → 1.24.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +20 -20
  3. data/README.md +723 -705
  4. data/Rakefile +32 -32
  5. data/lib/json_api_client/associations/base_association.rb +33 -33
  6. data/lib/json_api_client/associations/belongs_to.rb +31 -31
  7. data/lib/json_api_client/associations/has_many.rb +7 -7
  8. data/lib/json_api_client/associations/has_one.rb +16 -16
  9. data/lib/json_api_client/associations.rb +7 -7
  10. data/lib/json_api_client/connection.rb +41 -41
  11. data/lib/json_api_client/error_collector.rb +91 -91
  12. data/lib/json_api_client/errors.rb +125 -125
  13. data/lib/json_api_client/formatter.rb +145 -145
  14. data/lib/json_api_client/helpers/associatable.rb +88 -88
  15. data/lib/json_api_client/helpers/callbacks.rb +27 -27
  16. data/lib/json_api_client/helpers/dirty.rb +75 -75
  17. data/lib/json_api_client/helpers/dynamic_attributes.rb +78 -78
  18. data/lib/json_api_client/helpers/uri.rb +9 -9
  19. data/lib/json_api_client/helpers.rb +9 -9
  20. data/lib/json_api_client/implementation.rb +11 -11
  21. data/lib/json_api_client/included_data.rb +58 -58
  22. data/lib/json_api_client/linking/links.rb +21 -21
  23. data/lib/json_api_client/linking/top_level_links.rb +39 -39
  24. data/lib/json_api_client/linking.rb +5 -5
  25. data/lib/json_api_client/meta_data.rb +19 -19
  26. data/lib/json_api_client/middleware/json_request.rb +26 -26
  27. data/lib/json_api_client/middleware/status.rb +67 -67
  28. data/lib/json_api_client/middleware.rb +6 -6
  29. data/lib/json_api_client/paginating/nested_param_paginator.rb +140 -140
  30. data/lib/json_api_client/paginating/paginator.rb +89 -89
  31. data/lib/json_api_client/paginating.rb +6 -6
  32. data/lib/json_api_client/parsers/parser.rb +102 -102
  33. data/lib/json_api_client/parsers.rb +4 -4
  34. data/lib/json_api_client/query/builder.rb +239 -239
  35. data/lib/json_api_client/query/requestor.rb +73 -73
  36. data/lib/json_api_client/query.rb +5 -5
  37. data/lib/json_api_client/relationships/relations.rb +55 -55
  38. data/lib/json_api_client/relationships/top_level_relations.rb +30 -30
  39. data/lib/json_api_client/relationships.rb +5 -5
  40. data/lib/json_api_client/request_params.rb +57 -57
  41. data/lib/json_api_client/resource.rb +671 -671
  42. data/lib/json_api_client/result_set.rb +25 -25
  43. data/lib/json_api_client/schema.rb +154 -154
  44. data/lib/json_api_client/utils.rb +53 -53
  45. data/lib/json_api_client/version.rb +3 -3
  46. data/lib/json_api_client.rb +30 -30
  47. metadata +55 -30
@@ -1,58 +1,58 @@
1
- module JsonApiClient
2
- class IncludedData
3
- attr_reader :data
4
-
5
- def initialize(result_set, data)
6
- record_class = result_set.record_class
7
- grouped_data = data.group_by{|datum| datum["type"]}
8
- grouped_included_set = grouped_data.each_with_object({}) do |(type, records), h|
9
- klass = Utils.compute_type(record_class, record_class.key_formatter.unformat(type).singularize.classify)
10
- h[type] = records.map do |record|
11
- params = klass.parser.parameters_from_resource(record)
12
- klass.load(params).tap do |resource|
13
- resource.last_result_set = result_set
14
- end
15
- end
16
- end
17
-
18
- if record_class.search_included_in_result_set
19
- # deep_merge overrides the nested Arrays o_O
20
- # {a: [1,2]}.deep_merge(a: [3,4]) # => {a: [3,4]}
21
- grouped_included_set.merge!(result_set.group_by(&:type)) do |_, resources1, resources2|
22
- resources1 + resources2
23
- end
24
- end
25
-
26
- grouped_included_set.each do |type, resources|
27
- grouped_included_set[type] = resources.index_by { |resource| resource.attributes[:id] }
28
- end
29
-
30
- @data = grouped_included_set
31
- end
32
-
33
- def data_for(method_name, definition)
34
- # If data is defined, pull the record from the included data
35
- return nil unless data = definition["data"]
36
-
37
- if data.is_a?(Array)
38
- # has_many link
39
- data.map(&method(:record_for)).compact
40
- else
41
- # has_one link
42
- record_for(data)
43
- end
44
- end
45
-
46
- def has_link?(name)
47
- data.has_key?(name.to_s)
48
- end
49
-
50
- private
51
-
52
- # should return a resource record of some type for this linked document
53
- def record_for(link_def)
54
- record = data[link_def["type"]]
55
- record[link_def["id"]] if record
56
- end
57
- end
58
- end
1
+ module JsonApiClient
2
+ class IncludedData
3
+ attr_reader :data
4
+
5
+ def initialize(result_set, data)
6
+ record_class = result_set.record_class
7
+ grouped_data = data.group_by{|datum| datum["type"]}
8
+ grouped_included_set = grouped_data.each_with_object({}) do |(type, records), h|
9
+ klass = Utils.compute_type(record_class, record_class.key_formatter.unformat(type).singularize.classify)
10
+ h[type] = records.map do |record|
11
+ params = klass.parser.parameters_from_resource(record)
12
+ klass.load(params).tap do |resource|
13
+ resource.last_result_set = result_set
14
+ end
15
+ end
16
+ end
17
+
18
+ if record_class.search_included_in_result_set
19
+ # deep_merge overrides the nested Arrays o_O
20
+ # {a: [1,2]}.deep_merge(a: [3,4]) # => {a: [3,4]}
21
+ grouped_included_set.merge!(result_set.group_by(&:type)) do |_, resources1, resources2|
22
+ resources1 + resources2
23
+ end
24
+ end
25
+
26
+ grouped_included_set.each do |type, resources|
27
+ grouped_included_set[type] = resources.index_by { |resource| resource.attributes[:id] }
28
+ end
29
+
30
+ @data = grouped_included_set
31
+ end
32
+
33
+ def data_for(method_name, definition)
34
+ # If data is defined, pull the record from the included data
35
+ return nil unless data = definition["data"]
36
+
37
+ if data.is_a?(Array)
38
+ # has_many link
39
+ data.map(&method(:record_for)).compact
40
+ else
41
+ # has_one link
42
+ record_for(data)
43
+ end
44
+ end
45
+
46
+ def has_link?(name)
47
+ data.has_key?(name.to_s)
48
+ end
49
+
50
+ private
51
+
52
+ # should return a resource record of some type for this linked document
53
+ def record_for(link_def)
54
+ record = data[link_def["type"]]
55
+ record[link_def["id"]] if record
56
+ end
57
+ end
58
+ end
@@ -1,22 +1,22 @@
1
- module JsonApiClient
2
- module Linking
3
- class Links
4
- include Helpers::DynamicAttributes
5
-
6
- def initialize(links)
7
- self.attributes = links
8
- end
9
-
10
- def present?
11
- attributes.present?
12
- end
13
-
14
- protected
15
-
16
- def set_attribute(name, value)
17
- attributes[name] = value
18
- end
19
-
20
- end
21
- end
1
+ module JsonApiClient
2
+ module Linking
3
+ class Links
4
+ include Helpers::DynamicAttributes
5
+
6
+ def initialize(links)
7
+ self.attributes = links
8
+ end
9
+
10
+ def present?
11
+ attributes.present?
12
+ end
13
+
14
+ protected
15
+
16
+ def set_attribute(name, value)
17
+ attributes[name] = value
18
+ end
19
+
20
+ end
21
+ end
22
22
  end
@@ -1,39 +1,39 @@
1
- module JsonApiClient
2
- module Linking
3
- class TopLevelLinks
4
-
5
- attr_reader :links, :record_class
6
-
7
- def initialize(record_class, links)
8
- @links = links
9
- @record_class = record_class
10
- end
11
-
12
- def respond_to_missing?(method, include_private = false)
13
- links.has_key?(method.to_s) || super
14
- end
15
-
16
- def method_missing(method, *args)
17
- if respond_to_missing?(method)
18
- fetch_link(method)
19
- else
20
- super
21
- end
22
- end
23
-
24
- def link_url_for(link_name)
25
- link_definition = links.fetch(link_name.to_s)
26
- if link_definition.is_a?(Hash)
27
- link_definition["href"]
28
- else
29
- link_definition
30
- end
31
- end
32
-
33
- def fetch_link(link_name)
34
- return unless respond_to_missing?(link_name)
35
- record_class.requestor.linked(link_url_for(link_name))
36
- end
37
- end
38
- end
39
- end
1
+ module JsonApiClient
2
+ module Linking
3
+ class TopLevelLinks
4
+
5
+ attr_reader :links, :record_class
6
+
7
+ def initialize(record_class, links)
8
+ @links = links
9
+ @record_class = record_class
10
+ end
11
+
12
+ def respond_to_missing?(method, include_private = false)
13
+ links.has_key?(method.to_s) || super
14
+ end
15
+
16
+ def method_missing(method, *args)
17
+ if respond_to_missing?(method)
18
+ fetch_link(method)
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def link_url_for(link_name)
25
+ link_definition = links.fetch(link_name.to_s)
26
+ if link_definition.is_a?(Hash)
27
+ link_definition["href"]
28
+ else
29
+ link_definition
30
+ end
31
+ end
32
+
33
+ def fetch_link(link_name)
34
+ return unless respond_to_missing?(link_name)
35
+ record_class.requestor.linked(link_url_for(link_name))
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
- module JsonApiClient
2
- module Linking
3
- autoload :Links, "json_api_client/linking/links"
4
- autoload :TopLevelLinks, "json_api_client/linking/top_level_links"
5
- end
1
+ module JsonApiClient
2
+ module Linking
3
+ autoload :Links, "json_api_client/linking/links"
4
+ autoload :TopLevelLinks, "json_api_client/linking/top_level_links"
5
+ end
6
6
  end
@@ -1,19 +1,19 @@
1
- module JsonApiClient
2
- class MetaData
3
- include Helpers::DynamicAttributes
4
-
5
- attr_accessor :record_class
6
-
7
- def initialize(data, record_class = nil)
8
- self.record_class = record_class
9
- self.attributes = data
10
- end
11
-
12
- protected
13
-
14
- def key_formatter
15
- record_class && record_class.key_formatter
16
- end
17
-
18
- end
19
- end
1
+ module JsonApiClient
2
+ class MetaData
3
+ include Helpers::DynamicAttributes
4
+
5
+ attr_accessor :record_class
6
+
7
+ def initialize(data, record_class = nil)
8
+ self.record_class = record_class
9
+ self.attributes = data
10
+ end
11
+
12
+ protected
13
+
14
+ def key_formatter
15
+ record_class && record_class.key_formatter
16
+ end
17
+
18
+ end
19
+ end
@@ -1,26 +1,26 @@
1
- module JsonApiClient
2
- module Middleware
3
- class JsonRequest < Faraday::Middleware
4
- def call(environment)
5
- accept_header = update_accept_header(environment[:request_headers])
6
-
7
- environment[:request_headers]["Content-Type"] = 'application/vnd.api+json'
8
- environment[:request_headers]["Accept"] = accept_header
9
- @app.call(environment)
10
- end
11
-
12
- private
13
-
14
- def update_accept_header(headers)
15
- return 'application/vnd.api+json' if headers["Accept"].nil?
16
- accept_params = headers["Accept"].split(",")
17
-
18
- unless accept_params.include?('application/vnd.api+json')
19
- accept_params.unshift('application/vnd.api+json')
20
- end
21
-
22
- accept_params.join(",")
23
- end
24
- end
25
- end
26
- end
1
+ module JsonApiClient
2
+ module Middleware
3
+ class JsonRequest < Faraday::Middleware
4
+ def call(environment)
5
+ accept_header = update_accept_header(environment[:request_headers])
6
+
7
+ environment[:request_headers]["Content-Type"] = 'application/vnd.api+json'
8
+ environment[:request_headers]["Accept"] = accept_header
9
+ @app.call(environment)
10
+ end
11
+
12
+ private
13
+
14
+ def update_accept_header(headers)
15
+ return 'application/vnd.api+json' if headers["Accept"].nil?
16
+ accept_params = headers["Accept"].split(",")
17
+
18
+ unless accept_params.include?('application/vnd.api+json')
19
+ accept_params.unshift('application/vnd.api+json')
20
+ end
21
+
22
+ accept_params.join(",")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,67 +1,67 @@
1
- module JsonApiClient
2
- module Middleware
3
- class Status < Faraday::Middleware
4
- def initialize(app, options)
5
- super(app)
6
- @options = options
7
- end
8
-
9
- def call(environment)
10
- @app.call(environment).on_complete do |env|
11
- handle_status(env[:status], env)
12
-
13
- # look for meta[:status]
14
- if env[:body].is_a?(Hash)
15
- code = env[:body].fetch("meta", {}).fetch("status", 200).to_i
16
- handle_status(code, env)
17
- end
18
- end
19
- rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e
20
- raise Errors::ConnectionError.new environment, e.to_s
21
- end
22
-
23
- private
24
-
25
- def custom_handler_for(code)
26
- @options.fetch(:custom_handlers, {})[code]
27
- end
28
-
29
- def handle_status(code, env)
30
- custom_handler = custom_handler_for(code)
31
- return custom_handler.call(env) if custom_handler.present?
32
-
33
- case code
34
- when 200..399
35
- when 401
36
- raise Errors::NotAuthorized, env
37
- when 403
38
- raise Errors::AccessDenied, env
39
- when 404
40
- raise Errors::NotFound, env
41
- when 408
42
- raise Errors::RequestTimeout, env
43
- when 409
44
- raise Errors::Conflict, env
45
- when 422
46
- # Allow to proceed as resource errors will be populated
47
- when 429
48
- raise Errors::TooManyRequests, env
49
- when 400..499
50
- raise Errors::ClientError, env
51
- when 500
52
- raise Errors::InternalServerError, env
53
- when 502
54
- raise Errors::BadGateway, env
55
- when 503
56
- raise Errors::ServiceUnavailable, env
57
- when 504
58
- raise Errors::GatewayTimeout, env
59
- when 501..599
60
- raise Errors::ServerError, env
61
- else
62
- raise Errors::UnexpectedStatus.new(code, env[:url])
63
- end
64
- end
65
- end
66
- end
67
- end
1
+ module JsonApiClient
2
+ module Middleware
3
+ class Status < Faraday::Middleware
4
+ def initialize(app, options)
5
+ super(app)
6
+ @options = options
7
+ end
8
+
9
+ def call(environment)
10
+ @app.call(environment).on_complete do |env|
11
+ handle_status(env[:status], env)
12
+
13
+ # look for meta[:status]
14
+ if env[:body].is_a?(Hash)
15
+ code = env[:body].fetch("meta", {}).fetch("status", 200).to_i
16
+ handle_status(code, env)
17
+ end
18
+ end
19
+ rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e
20
+ raise Errors::ConnectionError.new environment, e.to_s
21
+ end
22
+
23
+ private
24
+
25
+ def custom_handler_for(code)
26
+ @options.fetch(:custom_handlers, {})[code]
27
+ end
28
+
29
+ def handle_status(code, env)
30
+ custom_handler = custom_handler_for(code)
31
+ return custom_handler.call(env) if custom_handler.present?
32
+
33
+ case code
34
+ when 200..399
35
+ when 401
36
+ raise Errors::NotAuthorized, env
37
+ when 403
38
+ raise Errors::AccessDenied, env
39
+ when 404
40
+ raise Errors::NotFound, env
41
+ when 408
42
+ raise Errors::RequestTimeout, env
43
+ when 409
44
+ raise Errors::Conflict, env
45
+ when 422
46
+ # Allow to proceed as resource errors will be populated
47
+ when 429
48
+ raise Errors::TooManyRequests, env
49
+ when 400..499
50
+ raise Errors::ClientError, env
51
+ when 500
52
+ raise Errors::InternalServerError, env
53
+ when 502
54
+ raise Errors::BadGateway, env
55
+ when 503
56
+ raise Errors::ServiceUnavailable, env
57
+ when 504
58
+ raise Errors::GatewayTimeout, env
59
+ when 501..599
60
+ raise Errors::ServerError, env
61
+ else
62
+ raise Errors::UnexpectedStatus.new(code, env[:url])
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,6 +1,6 @@
1
- module JsonApiClient
2
- module Middleware
3
- autoload :JsonRequest, 'json_api_client/middleware/json_request'
4
- autoload :Status, 'json_api_client/middleware/status'
5
- end
6
- end
1
+ module JsonApiClient
2
+ module Middleware
3
+ autoload :JsonRequest, 'json_api_client/middleware/json_request'
4
+ autoload :Status, 'json_api_client/middleware/status'
5
+ end
6
+ end