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,25 +1,25 @@
1
- require 'forwardable'
2
-
3
- module JsonApiClient
4
- class ResultSet < Array
5
- extend Forwardable
6
-
7
- attr_accessor :errors,
8
- :record_class,
9
- :meta,
10
- :pages,
11
- :uri,
12
- :links,
13
- :implementation,
14
- :relationships,
15
- :included
16
-
17
- # pagination methods are handled by the paginator
18
- def_delegators :pages, :total_pages, :total_entries, :total_count, :offset, :per_page, :current_page, :limit_value, :next_page, :previous_page, :out_of_bounds?
19
-
20
- def has_errors?
21
- errors.present?
22
- end
23
-
24
- end
25
- end
1
+ require 'forwardable'
2
+
3
+ module JsonApiClient
4
+ class ResultSet < Array
5
+ extend Forwardable
6
+
7
+ attr_accessor :errors,
8
+ :record_class,
9
+ :meta,
10
+ :pages,
11
+ :uri,
12
+ :links,
13
+ :implementation,
14
+ :relationships,
15
+ :included
16
+
17
+ # pagination methods are handled by the paginator
18
+ def_delegators :pages, :total_pages, :total_entries, :total_count, :offset, :per_page, :current_page, :limit_value, :next_page, :previous_page, :out_of_bounds?
19
+
20
+ def has_errors?
21
+ errors.present?
22
+ end
23
+
24
+ end
25
+ end
@@ -1,154 +1,154 @@
1
- require 'bigdecimal'
2
- module JsonApiClient
3
- class Schema
4
- module Types
5
-
6
- class Integer
7
- def self.cast(value, _)
8
- value.to_i
9
- end
10
- end
11
-
12
- class String
13
- def self.cast(value, _)
14
- value.to_s
15
- end
16
- end
17
-
18
- class Float
19
- def self.cast(value, _)
20
- value.to_f
21
- end
22
- end
23
-
24
- class Time
25
- def self.cast(value, _)
26
- value.is_a?(::Time) ? value : ::Time.parse(value)
27
- end
28
- end
29
-
30
- class Decimal
31
- def self.cast(value, _)
32
- BigDecimal(value)
33
- end
34
- end
35
-
36
- class Boolean
37
- def self.cast(value, default)
38
- case value
39
- when "false", "0", 0, false
40
- false
41
- when "true", "1", 1, true
42
- true
43
- else
44
- # if it's unknown, use the default value
45
- default
46
- end
47
- end
48
- end
49
-
50
- end
51
-
52
- class TypeFactory
53
- @@types = {}
54
- # Register a new type key or keys with appropriate classes
55
- #
56
- # eg:
57
- #
58
- # require 'money'
59
- #
60
- # class MyMoneyCaster
61
- # def self.cast(value, default)
62
- # begin
63
- # Money.new(value, "USD")
64
- # rescue ArgumentError
65
- # default
66
- # end
67
- # end
68
- # end
69
- #
70
- # JsonApiClient::Schema::TypeFactory.register money: MyMoneyCaster
71
- #
72
- # You can setup several at once:
73
- #
74
- # JsonApiClient::Schema::TypeFactory.register money: MyMoneyCaster,
75
- # date: MyJsonDateTypeCaster
76
- #
77
- #
78
- #
79
- #
80
- def self.register(type_hash)
81
- @@types.merge!(type_hash)
82
- end
83
-
84
- def self.type_for(type)
85
- @@types[type]
86
- end
87
-
88
- self.register int: Types::Integer,
89
- integer: Types::Integer,
90
- string: Types::String,
91
- float: Types::Float,
92
- time: Types::Time,
93
- decimal: Types::Decimal,
94
- boolean: Types::Boolean
95
-
96
- end
97
-
98
- Property = Struct.new(:name, :type, :default) do
99
- def cast(value)
100
- return nil if value.nil?
101
- return value if type.nil?
102
- type_caster = TypeFactory.type_for(type)
103
- return value if type_caster.nil?
104
- type_caster.cast(value, default)
105
- end
106
- end
107
-
108
- def initialize
109
- @properties = {}
110
- end
111
-
112
- # Add a property to the schema
113
- #
114
- # @param name [Symbol] the name of the property
115
- # @param options [Hash] property options
116
- # @option options [Symbol] :type The property type
117
- # @option options [Symbol] :default The default value for the property
118
- # @return [void]
119
- def add(name, options)
120
- @properties[name.to_sym] = Property.new(name.to_sym, options[:type], options[:default])
121
- end
122
-
123
- # How many properties are defined
124
- #
125
- # @return [Fixnum] the number of defined properties
126
- def size
127
- @properties.size
128
- end
129
-
130
- alias_method :length, :size
131
-
132
- def each_property(&block)
133
- @properties.values.each(&block)
134
- end
135
-
136
- alias_method :each, :each_property
137
-
138
- # Look up a property by name
139
- #
140
- # @param property_name [String] the name of the property
141
- # @return [Property, nil] the property definition for property_name or nil
142
- def find(property_name)
143
- @properties[property_name.to_sym]
144
- end
145
-
146
- alias_method :[], :find
147
-
148
- class << self
149
- def register(type_hash)
150
- TypeFactory.register(type_hash)
151
- end
152
- end
153
- end
154
- end
1
+ require 'bigdecimal'
2
+ module JsonApiClient
3
+ class Schema
4
+ module Types
5
+
6
+ class Integer
7
+ def self.cast(value, _)
8
+ value.to_i
9
+ end
10
+ end
11
+
12
+ class String
13
+ def self.cast(value, _)
14
+ value.to_s
15
+ end
16
+ end
17
+
18
+ class Float
19
+ def self.cast(value, _)
20
+ value.to_f
21
+ end
22
+ end
23
+
24
+ class Time
25
+ def self.cast(value, _)
26
+ value.is_a?(::Time) ? value : ::Time.parse(value)
27
+ end
28
+ end
29
+
30
+ class Decimal
31
+ def self.cast(value, _)
32
+ BigDecimal(value)
33
+ end
34
+ end
35
+
36
+ class Boolean
37
+ def self.cast(value, default)
38
+ case value
39
+ when "false", "0", 0, false
40
+ false
41
+ when "true", "1", 1, true
42
+ true
43
+ else
44
+ # if it's unknown, use the default value
45
+ default
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ class TypeFactory
53
+ @@types = {}
54
+ # Register a new type key or keys with appropriate classes
55
+ #
56
+ # eg:
57
+ #
58
+ # require 'money'
59
+ #
60
+ # class MyMoneyCaster
61
+ # def self.cast(value, default)
62
+ # begin
63
+ # Money.new(value, "USD")
64
+ # rescue ArgumentError
65
+ # default
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # JsonApiClient::Schema::TypeFactory.register money: MyMoneyCaster
71
+ #
72
+ # You can setup several at once:
73
+ #
74
+ # JsonApiClient::Schema::TypeFactory.register money: MyMoneyCaster,
75
+ # date: MyJsonDateTypeCaster
76
+ #
77
+ #
78
+ #
79
+ #
80
+ def self.register(type_hash)
81
+ @@types.merge!(type_hash)
82
+ end
83
+
84
+ def self.type_for(type)
85
+ @@types[type]
86
+ end
87
+
88
+ self.register int: Types::Integer,
89
+ integer: Types::Integer,
90
+ string: Types::String,
91
+ float: Types::Float,
92
+ time: Types::Time,
93
+ decimal: Types::Decimal,
94
+ boolean: Types::Boolean
95
+
96
+ end
97
+
98
+ Property = Struct.new(:name, :type, :default) do
99
+ def cast(value)
100
+ return nil if value.nil?
101
+ return value if type.nil?
102
+ type_caster = TypeFactory.type_for(type)
103
+ return value if type_caster.nil?
104
+ type_caster.cast(value, default)
105
+ end
106
+ end
107
+
108
+ def initialize
109
+ @properties = {}
110
+ end
111
+
112
+ # Add a property to the schema
113
+ #
114
+ # @param name [Symbol] the name of the property
115
+ # @param options [Hash] property options
116
+ # @option options [Symbol] :type The property type
117
+ # @option options [Symbol] :default The default value for the property
118
+ # @return [void]
119
+ def add(name, options)
120
+ @properties[name.to_sym] = Property.new(name.to_sym, options[:type], options[:default])
121
+ end
122
+
123
+ # How many properties are defined
124
+ #
125
+ # @return [Fixnum] the number of defined properties
126
+ def size
127
+ @properties.size
128
+ end
129
+
130
+ alias_method :length, :size
131
+
132
+ def each_property(&block)
133
+ @properties.values.each(&block)
134
+ end
135
+
136
+ alias_method :each, :each_property
137
+
138
+ # Look up a property by name
139
+ #
140
+ # @param property_name [String] the name of the property
141
+ # @return [Property, nil] the property definition for property_name or nil
142
+ def find(property_name)
143
+ @properties[property_name.to_sym]
144
+ end
145
+
146
+ alias_method :[], :find
147
+
148
+ class << self
149
+ def register(type_hash)
150
+ TypeFactory.register(type_hash)
151
+ end
152
+ end
153
+ end
154
+ end
@@ -1,53 +1,53 @@
1
- module JsonApiClient
2
- module Utils
3
-
4
- def self.compute_type(klass, type_name)
5
- return klass.custom_type_to_class.fetch(type_name).constantize if klass.custom_type_to_class.key?(type_name)
6
- # If the type is prefixed with a scope operator then we assume that
7
- # the type_name is an absolute reference.
8
- return type_name.constantize if type_name.match(/^::/)
9
-
10
- # Check the klass association definitions
11
- association_klass_match = klass.associations.find { |a| a.attr_name.to_s.singularize == type_name.underscore }
12
- association_klass = association_klass_match.options[:class] if association_klass_match
13
- return association_klass if association_klass
14
-
15
- # Build a list of candidates to search for
16
- candidates = []
17
- klass.name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
18
- candidates << type_name
19
-
20
- candidates.each do |candidate|
21
- begin
22
- constant = candidate.constantize
23
- return constant if candidate == constant.to_s
24
- rescue NameError => e
25
- # We don't want to swallow NoMethodError < NameError errors
26
- raise e unless e.instance_of?(NameError)
27
- end
28
- end
29
-
30
- raise NameError, "uninitialized constant #{candidates.first}"
31
- end
32
-
33
- def self.parse_includes(klass, *tables)
34
- tables.map do |table|
35
- case table
36
- when Hash
37
- table.map do |k, v|
38
- parse_includes(klass, *v).map do |sub|
39
- "#{k}.#{sub}"
40
- end
41
- end
42
- when Array
43
- table.map do |v|
44
- parse_includes(klass, *v)
45
- end
46
- else
47
- klass.key_formatter.format(table)
48
- end
49
- end.flatten
50
- end
51
-
52
- end
53
- end
1
+ module JsonApiClient
2
+ module Utils
3
+
4
+ def self.compute_type(klass, type_name)
5
+ return klass.custom_type_to_class.fetch(type_name).constantize if klass.custom_type_to_class.key?(type_name)
6
+ # If the type is prefixed with a scope operator then we assume that
7
+ # the type_name is an absolute reference.
8
+ return type_name.constantize if type_name.match(/^::/)
9
+
10
+ # Check the klass association definitions
11
+ association_klass_match = klass.associations.find { |a| a.attr_name.to_s.singularize == type_name.underscore }
12
+ association_klass = association_klass_match.options[:class] if association_klass_match
13
+ return association_klass if association_klass
14
+
15
+ # Build a list of candidates to search for
16
+ candidates = []
17
+ klass.name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
18
+ candidates << type_name
19
+
20
+ candidates.each do |candidate|
21
+ begin
22
+ constant = candidate.constantize
23
+ return constant if candidate == constant.to_s
24
+ rescue NameError => e
25
+ # We don't want to swallow NoMethodError < NameError errors
26
+ raise e unless e.instance_of?(NameError)
27
+ end
28
+ end
29
+
30
+ raise NameError, "uninitialized constant #{candidates.first}"
31
+ end
32
+
33
+ def self.parse_includes(klass, *tables)
34
+ tables.map do |table|
35
+ case table
36
+ when Hash
37
+ table.map do |k, v|
38
+ parse_includes(klass, *v).map do |sub|
39
+ "#{k}.#{sub}"
40
+ end
41
+ end
42
+ when Array
43
+ table.map do |v|
44
+ parse_includes(klass, *v)
45
+ end
46
+ else
47
+ klass.key_formatter.format(table)
48
+ end
49
+ end.flatten
50
+ end
51
+
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
- module JsonApiClient
2
- VERSION = "1.23.0"
3
- end
1
+ module JsonApiClient
2
+ VERSION = "1.24.0"
3
+ end
@@ -1,30 +1,30 @@
1
- require 'faraday'
2
- require 'faraday/gzip'
3
- require 'json'
4
- require 'addressable/uri'
5
- require 'json_api_client/formatter'
6
-
7
- module JsonApiClient
8
- autoload :Associations, 'json_api_client/associations'
9
- autoload :Attributes, 'json_api_client/attributes'
10
- autoload :Connection, 'json_api_client/connection'
11
- autoload :Errors, 'json_api_client/errors'
12
- autoload :ErrorCollector, 'json_api_client/error_collector'
13
- autoload :Helpers, 'json_api_client/helpers'
14
- autoload :Implementation, 'json_api_client/implementation'
15
- autoload :IncludedData, 'json_api_client/included_data'
16
- autoload :Linking, 'json_api_client/linking'
17
- autoload :Relationships, 'json_api_client/relationships'
18
- autoload :LinkDefinition, 'json_api_client/link_definition'
19
- autoload :MetaData, 'json_api_client/meta_data'
20
- autoload :Middleware, 'json_api_client/middleware'
21
- autoload :Paginating, 'json_api_client/paginating'
22
- autoload :Parsers, 'json_api_client/parsers'
23
- autoload :Query, 'json_api_client/query'
24
- autoload :RequestParams, 'json_api_client/request_params'
25
- autoload :Resource, 'json_api_client/resource'
26
- autoload :ResultSet, 'json_api_client/result_set'
27
- autoload :Schema, 'json_api_client/schema'
28
- autoload :Utils, 'json_api_client/utils'
29
- autoload :VERSION, 'json_api_client/version'
30
- end
1
+ require 'faraday'
2
+ require 'faraday/gzip'
3
+ require 'json'
4
+ require 'addressable/uri'
5
+ require 'json_api_client/formatter'
6
+
7
+ module JsonApiClient
8
+ autoload :Associations, 'json_api_client/associations'
9
+ autoload :Attributes, 'json_api_client/attributes'
10
+ autoload :Connection, 'json_api_client/connection'
11
+ autoload :Errors, 'json_api_client/errors'
12
+ autoload :ErrorCollector, 'json_api_client/error_collector'
13
+ autoload :Helpers, 'json_api_client/helpers'
14
+ autoload :Implementation, 'json_api_client/implementation'
15
+ autoload :IncludedData, 'json_api_client/included_data'
16
+ autoload :Linking, 'json_api_client/linking'
17
+ autoload :Relationships, 'json_api_client/relationships'
18
+ autoload :LinkDefinition, 'json_api_client/link_definition'
19
+ autoload :MetaData, 'json_api_client/meta_data'
20
+ autoload :Middleware, 'json_api_client/middleware'
21
+ autoload :Paginating, 'json_api_client/paginating'
22
+ autoload :Parsers, 'json_api_client/parsers'
23
+ autoload :Query, 'json_api_client/query'
24
+ autoload :RequestParams, 'json_api_client/request_params'
25
+ autoload :Resource, 'json_api_client/resource'
26
+ autoload :ResultSet, 'json_api_client/result_set'
27
+ autoload :Schema, 'json_api_client/schema'
28
+ autoload :Utils, 'json_api_client/utils'
29
+ autoload :VERSION, 'json_api_client/version'
30
+ end