pack_api 1.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +39 -0
- data/LICENSE.txt +21 -0
- data/README.md +238 -0
- data/lib/pack_api/config/dry_types_initializer.rb +1 -0
- data/lib/pack_api/models/internal_error.rb +25 -0
- data/lib/pack_api/models/mapping/abstract_transformer.rb +46 -0
- data/lib/pack_api/models/mapping/api_to_model_attributes_transformer.rb +27 -0
- data/lib/pack_api/models/mapping/attribute_hash_transformer.rb +46 -0
- data/lib/pack_api/models/mapping/attribute_map.rb +268 -0
- data/lib/pack_api/models/mapping/attribute_map_registry.rb +21 -0
- data/lib/pack_api/models/mapping/error_hash_to_api_attributes_transformer.rb +101 -0
- data/lib/pack_api/models/mapping/filter_map.rb +97 -0
- data/lib/pack_api/models/mapping/model_to_api_attributes_transformer.rb +67 -0
- data/lib/pack_api/models/mapping/normalized_api_attribute.rb +40 -0
- data/lib/pack_api/models/mapping/null_transformer.rb +9 -0
- data/lib/pack_api/models/mapping/value_object_factory.rb +83 -0
- data/lib/pack_api/models/pagination/opaque_token_v2.rb +19 -0
- data/lib/pack_api/models/pagination/paginator.rb +155 -0
- data/lib/pack_api/models/pagination/paginator_builder.rb +112 -0
- data/lib/pack_api/models/pagination/paginator_cursor.rb +86 -0
- data/lib/pack_api/models/pagination/snapshot_paginator.rb +133 -0
- data/lib/pack_api/models/querying/abstract_boolean_filter.rb +38 -0
- data/lib/pack_api/models/querying/abstract_enum_filter.rb +54 -0
- data/lib/pack_api/models/querying/abstract_filter.rb +15 -0
- data/lib/pack_api/models/querying/abstract_numeric_filter.rb +37 -0
- data/lib/pack_api/models/querying/abstract_range_filter.rb +31 -0
- data/lib/pack_api/models/querying/attribute_filter.rb +36 -0
- data/lib/pack_api/models/querying/attribute_filter_factory.rb +62 -0
- data/lib/pack_api/models/querying/collection_query.rb +125 -0
- data/lib/pack_api/models/querying/composable_query.rb +22 -0
- data/lib/pack_api/models/querying/default_filter.rb +20 -0
- data/lib/pack_api/models/querying/discoverable_filter.rb +33 -0
- data/lib/pack_api/models/querying/dynamic_enum_filter.rb +20 -0
- data/lib/pack_api/models/querying/filter_factory.rb +54 -0
- data/lib/pack_api/models/querying/sort_hash.rb +36 -0
- data/lib/pack_api/models/types/aggregate_type.rb +202 -0
- data/lib/pack_api/models/types/base_type.rb +46 -0
- data/lib/pack_api/models/types/boolean_filter_definition.rb +9 -0
- data/lib/pack_api/models/types/collection_result_metadata.rb +48 -0
- data/lib/pack_api/models/types/custom_filter_definition.rb +8 -0
- data/lib/pack_api/models/types/enum_filter_definition.rb +10 -0
- data/lib/pack_api/models/types/filter_option.rb +8 -0
- data/lib/pack_api/models/types/globally_identifiable.rb +19 -0
- data/lib/pack_api/models/types/numeric_filter_definition.rb +9 -0
- data/lib/pack_api/models/types/range_filter_definition.rb +10 -0
- data/lib/pack_api/models/types/result.rb +70 -0
- data/lib/pack_api/models/types/simple_filter_definition.rb +9 -0
- data/lib/pack_api/models/values_in_background_batches.rb +58 -0
- data/lib/pack_api/models/values_in_batches.rb +51 -0
- data/lib/pack_api/version.rb +5 -0
- data/lib/pack_api.rb +72 -0
- data/lib/types.rb +3 -0
- metadata +276 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI::Types
|
|
4
|
+
class CollectionResultMetadata < Dry::Struct
|
|
5
|
+
attribute :first_item, Types::Integer
|
|
6
|
+
attribute :last_item, Types::Integer
|
|
7
|
+
attribute :total_items, Types::Integer
|
|
8
|
+
|
|
9
|
+
###
|
|
10
|
+
# Cursors for the current record set (see PackAPI::Paginator)
|
|
11
|
+
attribute? :next_page_cursor, Types::String.optional
|
|
12
|
+
attribute? :previous_page_cursor, Types::String.optional
|
|
13
|
+
attribute? :first_page_cursor, Types::String.optional
|
|
14
|
+
attribute? :last_page_cursor, Types::String.optional
|
|
15
|
+
attribute? :current_page_cursor, Types::String.optional
|
|
16
|
+
attribute? :recordset_cursor, Types::String.optional
|
|
17
|
+
|
|
18
|
+
###
|
|
19
|
+
# A cursor representing a separate query that will always yield what the current_page_cursor produces
|
|
20
|
+
attribute? :current_page_snapshot_cursor, Types::String.optional
|
|
21
|
+
|
|
22
|
+
attribute? :sort, Types::Any.optional
|
|
23
|
+
|
|
24
|
+
def self.default
|
|
25
|
+
new(
|
|
26
|
+
first_item: 1,
|
|
27
|
+
last_item: 1,
|
|
28
|
+
total_items: 1
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.from_paginator(paginator, sort = nil, current_page_snapshot_cursor = nil)
|
|
33
|
+
new(
|
|
34
|
+
first_item: paginator.item_range.begin,
|
|
35
|
+
last_item: paginator.item_range.end,
|
|
36
|
+
total_items: paginator.total_items,
|
|
37
|
+
next_page_cursor: paginator.next_page_cursor,
|
|
38
|
+
previous_page_cursor: paginator.previous_page_cursor,
|
|
39
|
+
current_page_cursor: paginator.current_page_cursor,
|
|
40
|
+
first_page_cursor: paginator.first_page_cursor,
|
|
41
|
+
last_page_cursor: paginator.last_page_cursor,
|
|
42
|
+
recordset_cursor: paginator.recordset_cursor,
|
|
43
|
+
sort: sort || paginator.sort,
|
|
44
|
+
current_page_snapshot_cursor:
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI::Types
|
|
4
|
+
class EnumFilterDefinition < BaseType
|
|
5
|
+
attribute :name, Types::Symbol
|
|
6
|
+
attribute :type, Types::Symbol.default(:enum)
|
|
7
|
+
attribute :options, Types::Array.of(FilterOption)
|
|
8
|
+
attribute :can_exclude, Types::Bool.default(false)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI::Types
|
|
4
|
+
module GloballyIdentifiable
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def make_gid(model_id)
|
|
9
|
+
GlobalID.new(URI::GID.build(app: GlobalID.app, model_name: name, model_id: model_id))
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
included do
|
|
14
|
+
def gid
|
|
15
|
+
@gid ||= self.class.make_gid(id)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI::Types
|
|
4
|
+
class RangeFilterDefinition < BaseType
|
|
5
|
+
attribute :name, Types::Symbol
|
|
6
|
+
attribute :type, Types::Symbol.default(:range)
|
|
7
|
+
attribute :range_start_constraints, Types::Hash.schema(min: Types::Any.optional, max: Types::Any.optional).optional
|
|
8
|
+
attribute :range_end_constraints, Types::Hash.schema(min: Types::Any.optional, max: Types::Any.optional).optional
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI::Types
|
|
4
|
+
class Result < Dry::Struct
|
|
5
|
+
attribute :success, Types::Bool
|
|
6
|
+
attribute? :value, Types::Any.optional
|
|
7
|
+
attribute? :errors, Types::Hash.optional
|
|
8
|
+
attribute? :collection_metadata, CollectionResultMetadata.optional
|
|
9
|
+
|
|
10
|
+
def self.from_request_error(message, model: nil)
|
|
11
|
+
new(success: false, errors: { request: [message] }, value: model)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.from_collection(models:,
|
|
15
|
+
value_object_factory:,
|
|
16
|
+
optional_attributes: nil,
|
|
17
|
+
paginator: nil,
|
|
18
|
+
sort: nil,
|
|
19
|
+
current_page_snapshot_cursor: nil)
|
|
20
|
+
value = value_object_factory.create_collection(models:, optional_attributes:)
|
|
21
|
+
if paginator.present?
|
|
22
|
+
collection_metadata = CollectionResultMetadata.from_paginator(paginator, sort, current_page_snapshot_cursor)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
new(
|
|
26
|
+
success: true,
|
|
27
|
+
value:,
|
|
28
|
+
collection_metadata:
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.from_model(model:, value_object_factory:, optional_attributes: nil)
|
|
33
|
+
if model.errors.present?
|
|
34
|
+
errors = value_object_factory.create_errors(model:)
|
|
35
|
+
errors[:request] = model.errors[:base] if model.errors[:base].present?
|
|
36
|
+
new(
|
|
37
|
+
success: false,
|
|
38
|
+
errors:
|
|
39
|
+
)
|
|
40
|
+
else
|
|
41
|
+
new(
|
|
42
|
+
success: true,
|
|
43
|
+
value: value_object_factory.create_object(model:, optional_attributes:)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def attribute_error_string(attribute)
|
|
49
|
+
return '' if errors.nil? || errors[attribute].blank?
|
|
50
|
+
|
|
51
|
+
errors[attribute]&.join(', ')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def request_error_string
|
|
55
|
+
return '' if errors.nil? || errors[:request].blank?
|
|
56
|
+
|
|
57
|
+
"#{errors[:request]&.join(', ')}."
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def error_string
|
|
61
|
+
return '' if errors.nil?
|
|
62
|
+
|
|
63
|
+
one_message_per_error = errors.map do |attribute, errors|
|
|
64
|
+
"#{attribute.to_s.titleize}: #{Array.wrap(errors).join(', ')}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
one_message_per_error.join(', ')
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI
|
|
4
|
+
class ValuesInBackgroundBatches < ValuesInBatches
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
attr_reader :low_watermark, :background_worker
|
|
8
|
+
|
|
9
|
+
def initialize(method:, batch_size:, optional_attributes: nil, **kwargs, &block)
|
|
10
|
+
super
|
|
11
|
+
@low_watermark = 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def each
|
|
15
|
+
@background_worker = Rails.env.test? ?
|
|
16
|
+
Concurrent::ImmediateExecutor.new :
|
|
17
|
+
Concurrent::SingleThreadExecutor.new
|
|
18
|
+
super
|
|
19
|
+
background_worker.shutdown
|
|
20
|
+
@background_worker = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def process_item(index, item, block)
|
|
26
|
+
cache_next_batch if index == low_watermark
|
|
27
|
+
block.call(item)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cache_key
|
|
31
|
+
@cache_key ||= "api:batches:#{SecureRandom.uuid}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cache_next_batch
|
|
35
|
+
background_worker.post do
|
|
36
|
+
Rails.application.executor.wrap do
|
|
37
|
+
Rails.logger.debug { "Storing next batch in cache #{cache_key}" }
|
|
38
|
+
Rails.cache.write(cache_key, fetch_batch(cursor: next_batch_cursor), expires_in: 1.minute)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def make_next_batch_available
|
|
44
|
+
cached_next_result = Rails.cache.read(cache_key)
|
|
45
|
+
if cached_next_result.nil?
|
|
46
|
+
Rails.logger.debug { "Fetching next batch without cache #{cache_key}" }
|
|
47
|
+
@result = fetch_batch(cursor: next_batch_cursor)
|
|
48
|
+
else
|
|
49
|
+
Rails.logger.debug { "Fetching next batch from cache #{cache_key}" }
|
|
50
|
+
@result = cached_next_result
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
raise PackAPI::InternalError.new(object: @result.errors) unless @result.success
|
|
54
|
+
ensure
|
|
55
|
+
Rails.cache.delete(cache_key)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PackAPI
|
|
4
|
+
class ValuesInBatches
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
attr_reader :method, :batch_size, :optional_attributes, :kwargs
|
|
8
|
+
|
|
9
|
+
def initialize(method:, batch_size:, optional_attributes: nil, **kwargs)
|
|
10
|
+
@method = method
|
|
11
|
+
@batch_size = batch_size
|
|
12
|
+
@optional_attributes = optional_attributes
|
|
13
|
+
@kwargs = kwargs
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def each(&block)
|
|
17
|
+
make_next_batch_available
|
|
18
|
+
return if batch.empty?
|
|
19
|
+
|
|
20
|
+
loop do
|
|
21
|
+
batch.each_with_index { |item, index| process_item(index, item, block) }
|
|
22
|
+
break if next_batch_cursor.blank?
|
|
23
|
+
|
|
24
|
+
make_next_batch_available
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def batch
|
|
29
|
+
@result.value
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def process_item(_index, item, block)
|
|
35
|
+
block.call(item)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def next_batch_cursor
|
|
39
|
+
@result&.collection_metadata&.next_page_cursor
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def make_next_batch_available
|
|
43
|
+
@result = fetch_batch(cursor: next_batch_cursor)
|
|
44
|
+
raise PackAPI::InternalError.new(object: @result.errors) unless @result.success
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def fetch_batch(cursor: nil)
|
|
48
|
+
method.call(**kwargs.merge(optional_attributes:, per_page: batch_size, cursor:))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/pack_api.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_model"
|
|
4
|
+
require "active_record"
|
|
5
|
+
require "dry-types"
|
|
6
|
+
require "dry/struct"
|
|
7
|
+
require "brotli"
|
|
8
|
+
|
|
9
|
+
require_relative "types"
|
|
10
|
+
require_relative "pack_api/version"
|
|
11
|
+
require_relative "pack_api/config/dry_types_initializer"
|
|
12
|
+
|
|
13
|
+
# Load in dependency order
|
|
14
|
+
module PackAPI
|
|
15
|
+
autoload :InternalError, "pack_api/models/internal_error"
|
|
16
|
+
autoload :ValuesInBatches, "pack_api/models/values_in_batches"
|
|
17
|
+
autoload :ValuesInBackgroundBatches, "pack_api/models/values_in_background_batches"
|
|
18
|
+
|
|
19
|
+
module Mapping
|
|
20
|
+
autoload :AbstractTransformer, "pack_api/models/mapping/abstract_transformer"
|
|
21
|
+
autoload :AttributeHashTransformer, "pack_api/models/mapping/attribute_hash_transformer"
|
|
22
|
+
autoload :NullTransformer, "pack_api/models/mapping/null_transformer"
|
|
23
|
+
autoload :APIToModelAttributesTransformer, "pack_api/models/mapping/api_to_model_attributes_transformer"
|
|
24
|
+
autoload :ModelToAPIAttributesTransformer, "pack_api/models/mapping/model_to_api_attributes_transformer"
|
|
25
|
+
autoload :ErrorHashToAPIAttributesTransformer, "pack_api/models/mapping/error_hash_to_api_attributes_transformer"
|
|
26
|
+
autoload :NormalizedAPIAttribute, "pack_api/models/mapping/normalized_api_attribute"
|
|
27
|
+
autoload :AttributeMap, "pack_api/models/mapping/attribute_map"
|
|
28
|
+
autoload :AttributeMapRegistry, "pack_api/models/mapping/attribute_map_registry"
|
|
29
|
+
autoload :FilterMap, "pack_api/models/mapping/filter_map"
|
|
30
|
+
autoload :ValueObjectFactory, "pack_api/models/mapping/value_object_factory"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Pagination
|
|
34
|
+
autoload :OpaqueTokenV2, "pack_api/models/pagination/opaque_token_v2"
|
|
35
|
+
autoload :PaginatorCursor, "pack_api/models/pagination/paginator_cursor"
|
|
36
|
+
autoload :Paginator, "pack_api/models/pagination/paginator"
|
|
37
|
+
autoload :PaginatorBuilder, "pack_api/models/pagination/paginator_builder"
|
|
38
|
+
autoload :SnapshotPaginator, "pack_api/models/pagination/snapshot_paginator"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module Querying
|
|
42
|
+
autoload :AbstractFilter, "pack_api/models/querying/abstract_filter"
|
|
43
|
+
autoload :AbstractBooleanFilter, "pack_api/models/querying/abstract_boolean_filter"
|
|
44
|
+
autoload :AbstractEnumFilter, "pack_api/models/querying/abstract_enum_filter"
|
|
45
|
+
autoload :AbstractNumericFilter, "pack_api/models/querying/abstract_numeric_filter"
|
|
46
|
+
autoload :AbstractRangeFilter, "pack_api/models/querying/abstract_range_filter"
|
|
47
|
+
autoload :DefaultFilter, "pack_api/models/querying/default_filter"
|
|
48
|
+
autoload :DiscoverableFilter, "pack_api/models/querying/discoverable_filter"
|
|
49
|
+
autoload :DynamicEnumFilter, "pack_api/models/querying/dynamic_enum_filter"
|
|
50
|
+
autoload :AttributeFilter, "pack_api/models/querying/attribute_filter"
|
|
51
|
+
autoload :AttributeFilterFactory, "pack_api/models/querying/attribute_filter_factory"
|
|
52
|
+
autoload :FilterFactory, "pack_api/models/querying/filter_factory"
|
|
53
|
+
autoload :ComposableQuery, "pack_api/models/querying/composable_query"
|
|
54
|
+
autoload :CollectionQuery, "pack_api/models/querying/collection_query"
|
|
55
|
+
autoload :SortHash, "pack_api/models/querying/sort_hash"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module Types
|
|
59
|
+
autoload :BaseType, "pack_api/models/types/base_type"
|
|
60
|
+
autoload :AggregateType, "pack_api/models/types/aggregate_type"
|
|
61
|
+
autoload :GloballyIdentifiable, "pack_api/models/types/globally_identifiable"
|
|
62
|
+
autoload :Result, "pack_api/models/types/result"
|
|
63
|
+
autoload :CollectionResultMetadata, "pack_api/models/types/collection_result_metadata"
|
|
64
|
+
autoload :FilterOption, "pack_api/models/types/filter_option"
|
|
65
|
+
autoload :SimpleFilterDefinition, "pack_api/models/types/simple_filter_definition"
|
|
66
|
+
autoload :BooleanFilterDefinition, "pack_api/models/types/boolean_filter_definition"
|
|
67
|
+
autoload :EnumFilterDefinition, "pack_api/models/types/enum_filter_definition"
|
|
68
|
+
autoload :NumericFilterDefinition, "pack_api/models/types/numeric_filter_definition"
|
|
69
|
+
autoload :RangeFilterDefinition, "pack_api/models/types/range_filter_definition"
|
|
70
|
+
autoload :CustomFilterDefinition, "pack_api/models/types/custom_filter_definition"
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/types.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pack_api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Flytedesk
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: brotli
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0.5'
|
|
39
|
+
type: :runtime
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0.5'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: dry-types
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '1.8'
|
|
53
|
+
- - "<"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '2.0'
|
|
56
|
+
type: :runtime
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '1.8'
|
|
63
|
+
- - "<"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '2.0'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: dry-struct
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '1.6'
|
|
73
|
+
- - "<"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '2.0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.6'
|
|
83
|
+
- - "<"
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '2.0'
|
|
86
|
+
- !ruby/object:Gem::Dependency
|
|
87
|
+
name: rspec
|
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '3.12'
|
|
93
|
+
- - "<"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '4.0'
|
|
96
|
+
type: :development
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.12'
|
|
103
|
+
- - "<"
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '4.0'
|
|
106
|
+
- !ruby/object:Gem::Dependency
|
|
107
|
+
name: rspec-collection_matchers
|
|
108
|
+
requirement: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - "~>"
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '1.2'
|
|
113
|
+
type: :development
|
|
114
|
+
prerelease: false
|
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - "~>"
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '1.2'
|
|
120
|
+
- !ruby/object:Gem::Dependency
|
|
121
|
+
name: rake
|
|
122
|
+
requirement: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - "~>"
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '13.0'
|
|
127
|
+
type: :development
|
|
128
|
+
prerelease: false
|
|
129
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
130
|
+
requirements:
|
|
131
|
+
- - "~>"
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '13.0'
|
|
134
|
+
- !ruby/object:Gem::Dependency
|
|
135
|
+
name: sqlite3
|
|
136
|
+
requirement: !ruby/object:Gem::Requirement
|
|
137
|
+
requirements:
|
|
138
|
+
- - ">="
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '1.4'
|
|
141
|
+
- - "<"
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: '2.0'
|
|
144
|
+
type: :development
|
|
145
|
+
prerelease: false
|
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '1.4'
|
|
151
|
+
- - "<"
|
|
152
|
+
- !ruby/object:Gem::Version
|
|
153
|
+
version: '2.0'
|
|
154
|
+
- !ruby/object:Gem::Dependency
|
|
155
|
+
name: rack
|
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
|
157
|
+
requirements:
|
|
158
|
+
- - "~>"
|
|
159
|
+
- !ruby/object:Gem::Version
|
|
160
|
+
version: '2.0'
|
|
161
|
+
type: :development
|
|
162
|
+
prerelease: false
|
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
164
|
+
requirements:
|
|
165
|
+
- - "~>"
|
|
166
|
+
- !ruby/object:Gem::Version
|
|
167
|
+
version: '2.0'
|
|
168
|
+
- !ruby/object:Gem::Dependency
|
|
169
|
+
name: rails
|
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
|
171
|
+
requirements:
|
|
172
|
+
- - ">="
|
|
173
|
+
- !ruby/object:Gem::Version
|
|
174
|
+
version: '7.0'
|
|
175
|
+
- - "<"
|
|
176
|
+
- !ruby/object:Gem::Version
|
|
177
|
+
version: '9.0'
|
|
178
|
+
type: :development
|
|
179
|
+
prerelease: false
|
|
180
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
181
|
+
requirements:
|
|
182
|
+
- - ">="
|
|
183
|
+
- !ruby/object:Gem::Version
|
|
184
|
+
version: '7.0'
|
|
185
|
+
- - "<"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '9.0'
|
|
188
|
+
description: |
|
|
189
|
+
Building blocks used to implement an API around a domain pack. Includes:
|
|
190
|
+
- elements for passing data out of the API
|
|
191
|
+
- elements for describing the filters supported by query endpoints in the API
|
|
192
|
+
- elements for building the mapping between domain models and API models
|
|
193
|
+
- elements for building the query endpoints themselves, based on user inputs (sort, filter, pagination)
|
|
194
|
+
- elements for retrieving multiple pages of data from other query endpoints
|
|
195
|
+
email:
|
|
196
|
+
- dev@flytedesk.com
|
|
197
|
+
executables: []
|
|
198
|
+
extensions: []
|
|
199
|
+
extra_rdoc_files: []
|
|
200
|
+
files:
|
|
201
|
+
- CHANGELOG.md
|
|
202
|
+
- LICENSE.txt
|
|
203
|
+
- README.md
|
|
204
|
+
- lib/pack_api.rb
|
|
205
|
+
- lib/pack_api/config/dry_types_initializer.rb
|
|
206
|
+
- lib/pack_api/models/internal_error.rb
|
|
207
|
+
- lib/pack_api/models/mapping/abstract_transformer.rb
|
|
208
|
+
- lib/pack_api/models/mapping/api_to_model_attributes_transformer.rb
|
|
209
|
+
- lib/pack_api/models/mapping/attribute_hash_transformer.rb
|
|
210
|
+
- lib/pack_api/models/mapping/attribute_map.rb
|
|
211
|
+
- lib/pack_api/models/mapping/attribute_map_registry.rb
|
|
212
|
+
- lib/pack_api/models/mapping/error_hash_to_api_attributes_transformer.rb
|
|
213
|
+
- lib/pack_api/models/mapping/filter_map.rb
|
|
214
|
+
- lib/pack_api/models/mapping/model_to_api_attributes_transformer.rb
|
|
215
|
+
- lib/pack_api/models/mapping/normalized_api_attribute.rb
|
|
216
|
+
- lib/pack_api/models/mapping/null_transformer.rb
|
|
217
|
+
- lib/pack_api/models/mapping/value_object_factory.rb
|
|
218
|
+
- lib/pack_api/models/pagination/opaque_token_v2.rb
|
|
219
|
+
- lib/pack_api/models/pagination/paginator.rb
|
|
220
|
+
- lib/pack_api/models/pagination/paginator_builder.rb
|
|
221
|
+
- lib/pack_api/models/pagination/paginator_cursor.rb
|
|
222
|
+
- lib/pack_api/models/pagination/snapshot_paginator.rb
|
|
223
|
+
- lib/pack_api/models/querying/abstract_boolean_filter.rb
|
|
224
|
+
- lib/pack_api/models/querying/abstract_enum_filter.rb
|
|
225
|
+
- lib/pack_api/models/querying/abstract_filter.rb
|
|
226
|
+
- lib/pack_api/models/querying/abstract_numeric_filter.rb
|
|
227
|
+
- lib/pack_api/models/querying/abstract_range_filter.rb
|
|
228
|
+
- lib/pack_api/models/querying/attribute_filter.rb
|
|
229
|
+
- lib/pack_api/models/querying/attribute_filter_factory.rb
|
|
230
|
+
- lib/pack_api/models/querying/collection_query.rb
|
|
231
|
+
- lib/pack_api/models/querying/composable_query.rb
|
|
232
|
+
- lib/pack_api/models/querying/default_filter.rb
|
|
233
|
+
- lib/pack_api/models/querying/discoverable_filter.rb
|
|
234
|
+
- lib/pack_api/models/querying/dynamic_enum_filter.rb
|
|
235
|
+
- lib/pack_api/models/querying/filter_factory.rb
|
|
236
|
+
- lib/pack_api/models/querying/sort_hash.rb
|
|
237
|
+
- lib/pack_api/models/types/aggregate_type.rb
|
|
238
|
+
- lib/pack_api/models/types/base_type.rb
|
|
239
|
+
- lib/pack_api/models/types/boolean_filter_definition.rb
|
|
240
|
+
- lib/pack_api/models/types/collection_result_metadata.rb
|
|
241
|
+
- lib/pack_api/models/types/custom_filter_definition.rb
|
|
242
|
+
- lib/pack_api/models/types/enum_filter_definition.rb
|
|
243
|
+
- lib/pack_api/models/types/filter_option.rb
|
|
244
|
+
- lib/pack_api/models/types/globally_identifiable.rb
|
|
245
|
+
- lib/pack_api/models/types/numeric_filter_definition.rb
|
|
246
|
+
- lib/pack_api/models/types/range_filter_definition.rb
|
|
247
|
+
- lib/pack_api/models/types/result.rb
|
|
248
|
+
- lib/pack_api/models/types/simple_filter_definition.rb
|
|
249
|
+
- lib/pack_api/models/values_in_background_batches.rb
|
|
250
|
+
- lib/pack_api/models/values_in_batches.rb
|
|
251
|
+
- lib/pack_api/version.rb
|
|
252
|
+
- lib/types.rb
|
|
253
|
+
homepage: https://github.com/flytedesk/pack_api
|
|
254
|
+
licenses:
|
|
255
|
+
- MIT
|
|
256
|
+
metadata:
|
|
257
|
+
homepage_uri: https://github.com/flytedesk/pack_api
|
|
258
|
+
changelog_uri: https://github.com/flytedesk/pack_api/blob/main/CHANGELOG.md
|
|
259
|
+
rdoc_options: []
|
|
260
|
+
require_paths:
|
|
261
|
+
- lib
|
|
262
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
263
|
+
requirements:
|
|
264
|
+
- - ">="
|
|
265
|
+
- !ruby/object:Gem::Version
|
|
266
|
+
version: 3.0.0
|
|
267
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
|
+
requirements:
|
|
269
|
+
- - ">="
|
|
270
|
+
- !ruby/object:Gem::Version
|
|
271
|
+
version: '0'
|
|
272
|
+
requirements: []
|
|
273
|
+
rubygems_version: 3.6.9
|
|
274
|
+
specification_version: 4
|
|
275
|
+
summary: Building blocks for implementing APIs around domain models
|
|
276
|
+
test_files: []
|