pack_api 1.0.2 → 1.0.4
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/lib/pack_api/frozen_empty.rb +4 -0
- data/lib/pack_api/mapping/abstract_transformer.rb +4 -2
- data/lib/pack_api/mapping/api_to_model_attributes_transformer.rb +2 -9
- data/lib/pack_api/mapping/attribute_hash_transformer.rb +0 -1
- data/lib/pack_api/mapping/attribute_map.rb +18 -9
- data/lib/pack_api/mapping/filter_map.rb +2 -5
- data/lib/pack_api/mapping/model_to_api_attributes_transformer.rb +8 -11
- data/lib/pack_api/mapping/value_object_factory.rb +0 -1
- data/lib/pack_api/querying/collection_query.rb +12 -2
- data/lib/pack_api/querying/dynamic_enum_filter.rb +1 -3
- data/lib/pack_api/version.rb +1 -1
- data/lib/pack_api.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91807c3325db138316580a060e86626a03f7ebc9a4025d673a8144d9faf768e8
|
|
4
|
+
data.tar.gz: 22f935038e02720fd46351e96d7c379f40b25c4c930594e3f848b1440769cf8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c268b476a6c26f6832cb365ac01084309d4644f75a82cccde62223b70a19feda093971266bf620d20d97744e5e28ead4a9e72a778182c55c86b51dfb77f41d1
|
|
7
|
+
data.tar.gz: 8d4376d38175ed100ed4aee1ed432f6812ecca77da984e202a91b7dd465d85c5f7bdcd5156830a9ce5510cf45417cab006aa3f84a6685a16ee472f413ada94f5
|
|
@@ -10,7 +10,7 @@ module PackAPI::Mapping
|
|
|
10
10
|
@api_type = config[:api_type]
|
|
11
11
|
@model_type = config[:model_type]
|
|
12
12
|
@transform_value = config[:transform_value]
|
|
13
|
-
@options =
|
|
13
|
+
@options = PackAPI::FrozenEmpty::HASH
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
###
|
|
@@ -20,7 +20,7 @@ module PackAPI::Mapping
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def options=(value)
|
|
23
|
-
@options = value.presence ||
|
|
23
|
+
@options = value.presence || PackAPI::FrozenEmpty::HASH
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
protected
|
|
@@ -30,8 +30,10 @@ module PackAPI::Mapping
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def model_attribute(api_attribute)
|
|
33
|
+
# support _destroy and other special attributes used by Rails
|
|
33
34
|
return api_attribute if api_attribute.start_with?('_')
|
|
34
35
|
|
|
36
|
+
# prevent api_attributes from being used unless they are in the public type definition
|
|
35
37
|
unless mappings.key?(api_attribute)
|
|
36
38
|
raise ActiveModel::UnknownAttributeError.new(@model_type.name, api_attribute)
|
|
37
39
|
end
|
|
@@ -5,23 +5,16 @@ module PackAPI::Mapping
|
|
|
5
5
|
# Specialized attribute transformer allowing API attributes be converted to the attribute names needed to
|
|
6
6
|
# creating/updating an ActiveRecord model.
|
|
7
7
|
class APIToModelAttributesTransformer < AbstractTransformer
|
|
8
|
-
|
|
9
8
|
def execute
|
|
10
9
|
result = {}
|
|
11
10
|
attribute_names = NormalizedAPIAttribute.new(api_attribute_names)
|
|
12
11
|
data_source.each do |api_attribute, api_value|
|
|
13
12
|
normalized_api_attribute = attribute_names.normalize(api_attribute)
|
|
14
13
|
model_attribute = model_attribute(normalized_api_attribute)
|
|
15
|
-
model_value =
|
|
16
|
-
result
|
|
14
|
+
model_value = transform_value(normalized_api_attribute, api_value)
|
|
15
|
+
result[model_attribute] = model_value
|
|
17
16
|
end
|
|
18
17
|
result
|
|
19
18
|
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def model_value(api_attribute, api_value)
|
|
24
|
-
transform_value(api_attribute, api_value)
|
|
25
|
-
end
|
|
26
19
|
end
|
|
27
20
|
end
|
|
@@ -9,7 +9,6 @@ module PackAPI::Mapping
|
|
|
9
9
|
# Converts model attributes to API attributes
|
|
10
10
|
# Converts API attributes to model attributes
|
|
11
11
|
class AttributeHashTransformer < AbstractTransformer
|
|
12
|
-
|
|
13
12
|
def execute
|
|
14
13
|
options.fetch(:contains_model_attributes, true) ?
|
|
15
14
|
model_attributes_to_api_attributes :
|
|
@@ -26,8 +26,6 @@
|
|
|
26
26
|
# associate the error with the "user_id" attribute (not the "user" attribute).
|
|
27
27
|
module PackAPI::Mapping
|
|
28
28
|
class AttributeMap
|
|
29
|
-
FROZEN_EMPTY_HASH = {}.freeze
|
|
30
|
-
|
|
31
29
|
attr_reader :config, :options
|
|
32
30
|
|
|
33
31
|
class << self
|
|
@@ -225,25 +223,36 @@ module PackAPI::Mapping
|
|
|
225
223
|
end
|
|
226
224
|
|
|
227
225
|
def call(attribute_map, attribute_value)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
226
|
+
if @kwargs
|
|
227
|
+
proc ?
|
|
228
|
+
attribute_map.instance_exec(attribute_value, **@kwargs, &proc) :
|
|
229
|
+
attribute_map.send(instance_method.name, attribute_value, **@kwargs)
|
|
230
|
+
else
|
|
231
|
+
proc ?
|
|
232
|
+
attribute_map.instance_exec(attribute_value, &proc) :
|
|
233
|
+
attribute_map.send(instance_method.name, attribute_value)
|
|
234
|
+
end
|
|
231
235
|
end
|
|
232
236
|
|
|
233
237
|
def kwargs=(new_kwargs)
|
|
234
|
-
@kwargs =
|
|
238
|
+
@kwargs = new_kwargs == DEFAULT_OPTIONS || new_kwargs.blank? ?
|
|
239
|
+
nil :
|
|
240
|
+
supported_kwargs(new_kwargs)
|
|
235
241
|
end
|
|
236
242
|
|
|
237
243
|
private
|
|
238
244
|
|
|
239
245
|
def supported_kwargs(kwargs)
|
|
240
|
-
return
|
|
246
|
+
return if parameters.empty?
|
|
247
|
+
|
|
248
|
+
overlap = parameters.any? { |p| kwargs.key?(p) }
|
|
249
|
+
return unless overlap
|
|
241
250
|
|
|
242
|
-
kwargs.
|
|
251
|
+
kwargs.slice(*parameters)
|
|
243
252
|
end
|
|
244
253
|
|
|
245
254
|
def parameters
|
|
246
|
-
@parameters ||= (proc || instance_method).parameters
|
|
255
|
+
@parameters ||= (proc || instance_method).parameters.map(&:last)
|
|
247
256
|
end
|
|
248
257
|
end
|
|
249
258
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PackAPI::Mapping
|
|
4
|
-
FROZEN_EMPTY_ARRAY = [].freeze
|
|
5
|
-
FROZEN_EMPTY_HASH = {}.freeze
|
|
6
|
-
|
|
7
4
|
##
|
|
8
5
|
# This class is responsible for transforming API filter names into model filters. It also produces filter definitions
|
|
9
6
|
# in API terms for those filters that are supported by the model.
|
|
@@ -43,7 +40,7 @@ module PackAPI::Mapping
|
|
|
43
40
|
|
|
44
41
|
def api_attribute_filter_names
|
|
45
42
|
@api_attribute_filter_names ||= attribute_map_class.nil? ?
|
|
46
|
-
|
|
43
|
+
PackAPI::FrozenEmpty::ARRAY :
|
|
47
44
|
attribute_map_class.api_type.filterable_attributes.keys
|
|
48
45
|
end
|
|
49
46
|
|
|
@@ -51,7 +48,7 @@ module PackAPI::Mapping
|
|
|
51
48
|
# Map from a backend filter name to an API filter name for default attribute filters.
|
|
52
49
|
def api_attribute_filter_name_map
|
|
53
50
|
return @api_attribute_filter_name_map if defined?(@api_attribute_filter_name_map)
|
|
54
|
-
return
|
|
51
|
+
return PackAPI::FrozenEmpty::HASH if attribute_map_class.nil?
|
|
55
52
|
|
|
56
53
|
names = {}
|
|
57
54
|
api_attribute_filter_names.each { |name| names[name] = name }
|
|
@@ -5,7 +5,6 @@ module PackAPI::Mapping
|
|
|
5
5
|
# Specialized attribute transformer converting an ActiveRecord model attributes to the attribute names needed
|
|
6
6
|
# to create a ValueObject in the public API.
|
|
7
7
|
class ModelToAPIAttributesTransformer < AbstractTransformer
|
|
8
|
-
|
|
9
8
|
def options=(options)
|
|
10
9
|
super
|
|
11
10
|
@optional_attributes_to_include = nil
|
|
@@ -17,15 +16,17 @@ module PackAPI::Mapping
|
|
|
17
16
|
model_attribute = model_attribute(api_attribute)
|
|
18
17
|
next unless include_model_attribute?(model_attribute)
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
result[api_attribute] = value
|
|
19
|
+
api_value = transform_value(api_attribute, model_value(model_attribute)) if include_api_attribute?(api_attribute)
|
|
20
|
+
result[api_attribute] = api_value
|
|
24
21
|
end
|
|
25
22
|
end
|
|
26
23
|
|
|
27
24
|
protected
|
|
28
25
|
|
|
26
|
+
def include_api_attribute?(api_attribute)
|
|
27
|
+
!optional_api_attribute?(api_attribute) || include_optional_api_attribute?(api_attribute)
|
|
28
|
+
end
|
|
29
|
+
|
|
29
30
|
def model_attributes_of_interest
|
|
30
31
|
@model_attributes_of_interest ||= options[:model_attributes_of_interest]
|
|
31
32
|
end
|
|
@@ -38,7 +39,7 @@ module PackAPI::Mapping
|
|
|
38
39
|
api_type_optional_attributes.include?(api_attribute_name)
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
def
|
|
42
|
+
def include_optional_api_attribute?(api_attribute_name)
|
|
42
43
|
return false if optional_attributes_to_include.nil?
|
|
43
44
|
return false if optional_attributes_to_include.respond_to?(:exclude?) &&
|
|
44
45
|
optional_attributes_to_include.exclude?(api_attribute_name)
|
|
@@ -53,15 +54,11 @@ module PackAPI::Mapping
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
def api_type_optional_attributes
|
|
56
|
-
@api_type_optional_attributes ||= api_type.optional_attributes ||
|
|
57
|
+
@api_type_optional_attributes ||= api_type.optional_attributes || PackAPI::FrozenEmpty::ARRAY
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def model_value(model_attribute)
|
|
60
61
|
data_source.public_send(model_attribute)
|
|
61
62
|
end
|
|
62
|
-
|
|
63
|
-
def api_value(api_attribute, model_value)
|
|
64
|
-
transform_value(api_attribute, model_value)
|
|
65
|
-
end
|
|
66
63
|
end
|
|
67
64
|
end
|
|
@@ -109,11 +109,21 @@ module PackAPI::Querying
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def apply_filters(filters:)
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
filter_objects = filter_factory.create_filters(filters)
|
|
113
|
+
validate_filters(filter_objects)
|
|
114
|
+
filtered_query = filter_objects.each_with_object(ComposableQuery.new(@query)) do |filter, composable_query|
|
|
115
|
+
filter.apply_to(composable_query)
|
|
116
|
+
end
|
|
114
117
|
@query = filtered_query.build
|
|
115
118
|
end
|
|
116
119
|
|
|
120
|
+
def validate_filters(filter_objects)
|
|
121
|
+
errors = filter_objects.select { |filter| filter.respond_to?(:valid?) && !filter.valid? }
|
|
122
|
+
.map { |invalid_filter| { invalid_filter.filter_name => invalid_filter.errors.messages } }
|
|
123
|
+
.reduce({}, :merge)
|
|
124
|
+
raise PackAPI::InternalError.new(object: errors) if errors.present?
|
|
125
|
+
end
|
|
126
|
+
|
|
117
127
|
def stable_sort(sort)
|
|
118
128
|
return sort if sort.is_a?(Arel::Nodes::SqlLiteral)
|
|
119
129
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module PackAPI::Querying
|
|
4
4
|
module DynamicEnumFilter
|
|
5
|
-
FROZEN_EMPTY_ARRAY = [].freeze
|
|
6
|
-
|
|
7
5
|
extend ActiveSupport::Concern
|
|
8
6
|
class_methods do
|
|
9
7
|
def type = :dynamic_enum
|
|
@@ -14,7 +12,7 @@ module PackAPI::Querying
|
|
|
14
12
|
|
|
15
13
|
private
|
|
16
14
|
|
|
17
|
-
def filter_options(**) =
|
|
15
|
+
def filter_options(**) = PackAPI::FrozenEmpty::ARRAY
|
|
18
16
|
end
|
|
19
17
|
end
|
|
20
18
|
end
|
data/lib/pack_api/version.rb
CHANGED
data/lib/pack_api.rb
CHANGED
|
@@ -9,6 +9,7 @@ require_relative "types"
|
|
|
9
9
|
require_relative "pack_api/version"
|
|
10
10
|
|
|
11
11
|
module PackAPI
|
|
12
|
+
autoload :FrozenEmpty, "pack_api/frozen_empty"
|
|
12
13
|
autoload :InternalError, "pack_api/internal_error"
|
|
13
14
|
autoload :ValuesInBatches, "pack_api/values_in_batches"
|
|
14
15
|
autoload :ValuesInBackgroundBatches, "pack_api/values_in_background_batches"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pack_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Flytedesk
|
|
@@ -199,6 +199,7 @@ files:
|
|
|
199
199
|
- LICENSE.txt
|
|
200
200
|
- README.md
|
|
201
201
|
- lib/pack_api.rb
|
|
202
|
+
- lib/pack_api/frozen_empty.rb
|
|
202
203
|
- lib/pack_api/internal_error.rb
|
|
203
204
|
- lib/pack_api/mapping/abstract_transformer.rb
|
|
204
205
|
- lib/pack_api/mapping/api_to_model_attributes_transformer.rb
|