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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +39 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +238 -0
  5. data/lib/pack_api/config/dry_types_initializer.rb +1 -0
  6. data/lib/pack_api/models/internal_error.rb +25 -0
  7. data/lib/pack_api/models/mapping/abstract_transformer.rb +46 -0
  8. data/lib/pack_api/models/mapping/api_to_model_attributes_transformer.rb +27 -0
  9. data/lib/pack_api/models/mapping/attribute_hash_transformer.rb +46 -0
  10. data/lib/pack_api/models/mapping/attribute_map.rb +268 -0
  11. data/lib/pack_api/models/mapping/attribute_map_registry.rb +21 -0
  12. data/lib/pack_api/models/mapping/error_hash_to_api_attributes_transformer.rb +101 -0
  13. data/lib/pack_api/models/mapping/filter_map.rb +97 -0
  14. data/lib/pack_api/models/mapping/model_to_api_attributes_transformer.rb +67 -0
  15. data/lib/pack_api/models/mapping/normalized_api_attribute.rb +40 -0
  16. data/lib/pack_api/models/mapping/null_transformer.rb +9 -0
  17. data/lib/pack_api/models/mapping/value_object_factory.rb +83 -0
  18. data/lib/pack_api/models/pagination/opaque_token_v2.rb +19 -0
  19. data/lib/pack_api/models/pagination/paginator.rb +155 -0
  20. data/lib/pack_api/models/pagination/paginator_builder.rb +112 -0
  21. data/lib/pack_api/models/pagination/paginator_cursor.rb +86 -0
  22. data/lib/pack_api/models/pagination/snapshot_paginator.rb +133 -0
  23. data/lib/pack_api/models/querying/abstract_boolean_filter.rb +38 -0
  24. data/lib/pack_api/models/querying/abstract_enum_filter.rb +54 -0
  25. data/lib/pack_api/models/querying/abstract_filter.rb +15 -0
  26. data/lib/pack_api/models/querying/abstract_numeric_filter.rb +37 -0
  27. data/lib/pack_api/models/querying/abstract_range_filter.rb +31 -0
  28. data/lib/pack_api/models/querying/attribute_filter.rb +36 -0
  29. data/lib/pack_api/models/querying/attribute_filter_factory.rb +62 -0
  30. data/lib/pack_api/models/querying/collection_query.rb +125 -0
  31. data/lib/pack_api/models/querying/composable_query.rb +22 -0
  32. data/lib/pack_api/models/querying/default_filter.rb +20 -0
  33. data/lib/pack_api/models/querying/discoverable_filter.rb +33 -0
  34. data/lib/pack_api/models/querying/dynamic_enum_filter.rb +20 -0
  35. data/lib/pack_api/models/querying/filter_factory.rb +54 -0
  36. data/lib/pack_api/models/querying/sort_hash.rb +36 -0
  37. data/lib/pack_api/models/types/aggregate_type.rb +202 -0
  38. data/lib/pack_api/models/types/base_type.rb +46 -0
  39. data/lib/pack_api/models/types/boolean_filter_definition.rb +9 -0
  40. data/lib/pack_api/models/types/collection_result_metadata.rb +48 -0
  41. data/lib/pack_api/models/types/custom_filter_definition.rb +8 -0
  42. data/lib/pack_api/models/types/enum_filter_definition.rb +10 -0
  43. data/lib/pack_api/models/types/filter_option.rb +8 -0
  44. data/lib/pack_api/models/types/globally_identifiable.rb +19 -0
  45. data/lib/pack_api/models/types/numeric_filter_definition.rb +9 -0
  46. data/lib/pack_api/models/types/range_filter_definition.rb +10 -0
  47. data/lib/pack_api/models/types/result.rb +70 -0
  48. data/lib/pack_api/models/types/simple_filter_definition.rb +9 -0
  49. data/lib/pack_api/models/values_in_background_batches.rb +58 -0
  50. data/lib/pack_api/models/values_in_batches.rb +51 -0
  51. data/lib/pack_api/version.rb +5 -0
  52. data/lib/pack_api.rb +72 -0
  53. data/lib/types.rb +3 -0
  54. 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,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PackAPI::Types
4
+ class CustomFilterDefinition < BaseType
5
+ attribute :name, Types::Symbol
6
+ attribute :type, Types::Symbol.default(:custom)
7
+ end
8
+ 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,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PackAPI::Types
4
+ class FilterOption < BaseType
5
+ attribute :label, Types::String
6
+ attribute :value, Types::String
7
+ end
8
+ 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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PackAPI::Types
4
+ class NumericFilterDefinition < BaseType
5
+ attribute :name, Types::Symbol
6
+ attribute :type, Types::Symbol.default(:numeric)
7
+ attribute :operators, Types::Array.of(FilterOption)
8
+ end
9
+ 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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PackAPI::Types
4
+ class SimpleFilterDefinition < BaseType
5
+ attribute :name, Types::Symbol
6
+ attribute :type, Types::Symbol.default(:simple)
7
+ attribute :data_type, Types::String
8
+ end
9
+ 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PackAPI
4
+ VERSION = "1.0.0"
5
+ 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
@@ -0,0 +1,3 @@
1
+ module Types
2
+ include Dry.Types()
3
+ end
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: []