iron_bank 5.4.0 → 6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 853859a45aaabdcfc831dca27a70882b28aa19f68b214a666cb0830ce4fa702f
4
- data.tar.gz: 3c755dd00fad7455b402dd04ae7f649f554fce6127608e11f28c2e16f31c85d9
3
+ metadata.gz: 21e2b4cd128fca398bbb0f377e13da07b12c61e38f9c5e68ed3f56274350ee76
4
+ data.tar.gz: e81a0902b8fa8337d629b03322546270539f3f148ffc4a3dbebc89800bc40a09
5
5
  SHA512:
6
- metadata.gz: 50f8865e78282701c705fd9e5b1b0f9978f152d54b7594784806153d9ffc3654d57871f6a9c4dbe1917611853915e27ff16e9b893e2bc2d848a27f963596aa32
7
- data.tar.gz: 41e18fea0a4047734d49c8a495dfb28c2c13b7a40ef4a4737f6ccf909e4894bca44048124793cb9924ed375000e12245be67eefe559967f943b1391f7f2024f3
6
+ metadata.gz: 17aea2bf7a329de0cec9e42cb8d29416fca829ab0b7801624d32ff1367938bd44dc957b7759cfad41562080dd8793258acc30b036ae7c60452e6b54e0f5c3eff
7
+ data.tar.gz: '06290a763ad6c65851d162396a2ea79da3cd6a144a2f51173ab3af995d3c0a4c136f01a997af81751cc06b0634e20560e5c8f475ed1cc4bcacc2e42023f63d65'
@@ -13,10 +13,9 @@ jobs:
13
13
  strategy:
14
14
  matrix:
15
15
  ruby-version:
16
- - '2.7'
17
- - '3.0'
18
16
  - '3.1'
19
17
  - '3.2'
18
+ - '3.3'
20
19
  steps:
21
20
  - uses: zendesk/checkout@v3
22
21
  - uses: zendesk/setup-ruby@v1
@@ -52,6 +51,6 @@ jobs:
52
51
  - name: Set up Ruby
53
52
  uses: zendesk/setup-ruby@v1
54
53
  with:
55
- ruby-version: "3.0"
54
+ ruby-version: "3.1"
56
55
  bundler-cache: true
57
56
  - run: bundle exec rake rubocop
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  DisplayStyleGuide: true
6
6
  NewCops: enable
7
7
  SuggestExtensions: false
8
- TargetRubyVersion: 2.7
8
+ TargetRubyVersion: 3.1
9
9
 
10
10
  Layout/DotPosition:
11
11
  EnforcedStyle: trailing
@@ -68,3 +68,15 @@ Style/RegexpLiteral:
68
68
  Style/RescueStandardError:
69
69
  Exclude:
70
70
  - lib/iron_bank/csv.rb
71
+
72
+ Style/HashSyntax:
73
+ Exclude:
74
+ - spec/shared_examples/**
75
+ - spec/iron_bank/**/*.rb
76
+ - lib/iron_bank/*.
77
+ - lib/iron_bank/**/*.rb
78
+
79
+ Style/RedundantFreeze:
80
+ Exclude:
81
+ - lib/iron_bank/*.rb
82
+
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.7
1
+ 3.1.4
data/Gemfile.lock CHANGED
@@ -1,62 +1,58 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- iron_bank (5.4.0)
5
- faraday (~> 1)
6
- faraday_middleware (~> 1)
4
+ iron_bank (6.0.0)
5
+ faraday (~> 2)
6
+ faraday-retry (~> 2)
7
7
  nokogiri (~> 1)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (7.0.4.3)
12
+ activesupport (7.1.1)
13
+ base64
14
+ bigdecimal
13
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ connection_pool (>= 2.2.5)
17
+ drb
14
18
  i18n (>= 1.6, < 2)
15
19
  minitest (>= 5.1)
20
+ mutex_m
16
21
  tzinfo (~> 2.0)
17
22
  ast (2.4.2)
23
+ base64 (0.2.0)
24
+ bigdecimal (3.1.4)
18
25
  bump (0.10.0)
19
26
  byebug (11.1.3)
20
27
  coderay (1.1.3)
21
28
  concurrent-ruby (1.2.2)
29
+ connection_pool (2.4.1)
22
30
  diff-lcs (1.5.0)
23
31
  docile (1.4.0)
24
32
  dotenv (2.8.1)
33
+ drb (2.2.0)
34
+ ruby2_keywords
25
35
  factory_bot (6.2.1)
26
36
  activesupport (>= 5.0.0)
27
- faraday (1.10.3)
28
- faraday-em_http (~> 1.0)
29
- faraday-em_synchrony (~> 1.0)
30
- faraday-excon (~> 1.1)
31
- faraday-httpclient (~> 1.0)
32
- faraday-multipart (~> 1.0)
33
- faraday-net_http (~> 1.0)
34
- faraday-net_http_persistent (~> 1.0)
35
- faraday-patron (~> 1.0)
36
- faraday-rack (~> 1.0)
37
- faraday-retry (~> 1.0)
38
- ruby2_keywords (>= 0.0.4)
39
- faraday-em_http (1.0.0)
40
- faraday-em_synchrony (1.0.0)
41
- faraday-excon (1.1.0)
42
- faraday-httpclient (1.0.1)
43
- faraday-multipart (1.0.4)
44
- multipart-post (~> 2)
45
- faraday-net_http (1.0.1)
46
- faraday-net_http_persistent (1.2.0)
47
- faraday-patron (1.0.0)
48
- faraday-rack (1.0.0)
49
- faraday-retry (1.0.3)
50
- faraday_middleware (1.2.0)
51
- faraday (~> 1.0)
37
+ faraday (2.12.2)
38
+ faraday-net_http (>= 2.0, < 3.5)
39
+ json
40
+ logger
41
+ faraday-net_http (3.4.0)
42
+ net-http (>= 0.5.0)
43
+ faraday-retry (2.2.0)
44
+ faraday (~> 2.0)
52
45
  i18n (1.13.0)
53
46
  concurrent-ruby (~> 1.0)
54
47
  json (2.6.3)
55
48
  kwalify (0.7.2)
49
+ logger (1.6.6)
56
50
  method_source (1.0.0)
57
51
  mini_portile2 (2.8.2)
58
52
  minitest (5.18.0)
59
- multipart-post (2.3.0)
53
+ mutex_m (0.2.0)
54
+ net-http (0.6.0)
55
+ uri
60
56
  nokogiri (1.14.3)
61
57
  mini_portile2 (~> 2.8.0)
62
58
  racc (~> 1.4)
@@ -120,6 +116,7 @@ GEM
120
116
  tzinfo (2.0.6)
121
117
  concurrent-ruby (~> 1.0)
122
118
  unicode-display_width (2.4.2)
119
+ uri (1.0.3)
123
120
 
124
121
  PLATFORMS
125
122
  ruby
@@ -141,4 +138,4 @@ DEPENDENCIES
141
138
  timecop (~> 0.9)
142
139
 
143
140
  BUNDLED WITH
144
- 2.3.16
141
+ 2.4.19
data/README.md CHANGED
@@ -13,7 +13,7 @@ This gem provides opinionated resources to interact with the Zuora API through
13
13
  their REST interface. It defines **associations** between them, as well as a
14
14
  simple **declaration API** (`with_one`, `with_many`) to extend them.
15
15
 
16
- This gem is tested against Ruby `>= 2.6`.
16
+ This gem is tested against Ruby `>= 3.1`.
17
17
 
18
18
  Please use [GitHub Issues][issues] to report bugs.
19
19
 
data/Rakefile CHANGED
@@ -31,6 +31,14 @@ task :excluded_fields, [:filename] do |_t, args|
31
31
  setup_iron_bank
32
32
 
33
33
  destination = args[:filename] || IronBank.configuration.excluded_fields_file
34
+ # NOTE: In some instances the error message from Zuora will not include the
35
+ # unqueryable fields that need to be excluded. When that happens IronBank's
36
+ # strategy will be to perform a binary search through the fields listed in the
37
+ # query -- at the cost of performance due to repeated requests sent to Zuora
38
+ # as it tries to identify the offending field.
39
+ #
40
+ # See:
41
+ # - https://github.com/zendesk/iron_bank/pull/107
34
42
  fields = IronBank::Schema.excluded_fields.sort.to_h
35
43
 
36
44
  File.write(destination, Psych.dump(fields))
data/iron_bank.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  "mturan@zendesk.com"
20
20
  ]
21
21
 
22
- spec.required_ruby_version = ">= 2.7"
22
+ spec.required_ruby_version = ">= 3.1"
23
23
 
24
24
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
25
  f.match(%r{^(test|spec|features)/})
@@ -29,8 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency "faraday", "~> 1"
33
- spec.add_dependency "faraday_middleware", "~> 1"
32
+ spec.add_dependency "faraday", "~> 2"
33
+ spec.add_dependency "faraday-retry", "~> 2"
34
34
  spec.add_dependency "nokogiri", "~> 1"
35
35
  spec.metadata["rubygems_mfa_required"] = "true"
36
36
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IronBank
4
+ module Describe
5
+ # NOTE: Beware there could be a performance hit as the search repeatedly
6
+ # executes queries to perform the search for invalid fields in the query
7
+ # included in the query statement.
8
+
9
+ # rubocop:disable Style/ClassAndModuleChildren
10
+ class ExcludedFields::DeduceFromQuery
11
+ INVALID_OBJECT_ID = "InvalidObjectId"
12
+
13
+ private_class_method :new
14
+
15
+ def self.call(object)
16
+ new(object).call
17
+ end
18
+
19
+ def call
20
+ query_fields = object.query_fields.clone
21
+ divide_and_execute(query_fields)
22
+ object.query_fields.concat(query_fields)
23
+ invalid_fields
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :object, :valid_fields, :invalid_fields
29
+
30
+ def initialize(object)
31
+ @object = object
32
+ @valid_fields = []
33
+ @invalid_fields = []
34
+ end
35
+
36
+ def divide_and_execute(query_fields)
37
+ # clear state before queries
38
+ object.query_fields.clear
39
+
40
+ # we repeat dividing until only a single field remains
41
+ invalid_fields.push(query_fields.pop) if query_fields.one?
42
+ return if query_fields.empty?
43
+
44
+ left, right = divide_fields(query_fields)
45
+ execute_or_divide_again(left)
46
+ execute_or_divide_again(right)
47
+ end
48
+
49
+ def divide_fields(query_fields)
50
+ mid = query_fields.size / 2
51
+ [query_fields[0..mid - 1], query_fields[mid..]]
52
+ end
53
+
54
+ def execute_or_divide_again(fields)
55
+ if execute_query(fields)
56
+ valid_fields.concat(fields)
57
+ else
58
+ divide_and_execute(fields)
59
+ end
60
+ end
61
+
62
+ def execute_query(fields)
63
+ object.query_fields.concat(valid_fields + fields)
64
+ object.where({ id: INVALID_OBJECT_ID })
65
+ true
66
+ rescue IronBank::InternalServerError
67
+ false
68
+ end
69
+ end
70
+ # rubocop:enable Style/ClassAndModuleChildren
71
+ end
72
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IronBank
4
+ module Describe
5
+ # Extracts invalid fields from an exception message.
6
+ # Returns from a call if an exception message does not contain invalid field
7
+
8
+ # rubocop:disable Style/ClassAndModuleChildren
9
+ class ExcludedFields::ExtractFromMessage
10
+ FAULT_FIELD_MESSAGES = Regexp.union(
11
+ # Generic fault field
12
+ /invalid field for query: \w+\.(\w+)/,
13
+ # Invoice Bill Run is not selectable in ZOQL
14
+ /Cannot use the (BillRunId) field in the select clause/,
15
+ # Invoice Body, implemented as a separate call
16
+ /Can only query one invoice (body) at a time/,
17
+ # Catalog tier should only query the price field
18
+ /use Price or (DiscountAmount) or (DiscountPercentage)/,
19
+ # Catalog plan currencies, implemented as a separate call
20
+ /When querying for (active currencies)/,
21
+ # Catalog charge rollover balance
22
+ /You can only query (RolloverBalance) in particular/,
23
+ # (Subscription) charge should only query the price field
24
+ /
25
+ (OveragePrice),
26
+ \ Price,
27
+ \ (IncludedUnits),
28
+ \ (DiscountAmount)
29
+ \ or\ (DiscountPercentage)
30
+ /x
31
+ ).freeze
32
+
33
+ private_class_method :new
34
+
35
+ def self.call(message)
36
+ new(message).call
37
+ end
38
+
39
+ def call
40
+ return unless FAULT_FIELD_MESSAGES.match(message)
41
+
42
+ Regexp.last_match.captures.compact.
43
+ map { |capture| capture.delete(" ") }
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :message
49
+
50
+ def initialize(message)
51
+ @message = message
52
+ end
53
+ end
54
+ # rubocop:enable Style/ClassAndModuleChildren
55
+ end
56
+ end
@@ -5,32 +5,10 @@ module IronBank
5
5
  # Returns an array of non-queryable fields for the given object in the
6
6
  # current Zuora tenant, despites Zuora clearly marking these fields as
7
7
  # `<selectable>true</true>` in their Describe API... /rant
8
- #
9
8
  class ExcludedFields
10
9
  extend Forwardable
11
10
 
12
- FAULT_FIELD_MESSAGES = Regexp.union(
13
- # Generic fault field
14
- /invalid field for query: \w+\.(\w+)/,
15
- # Invoice Bill Run is not selectable in ZOQL
16
- /Cannot use the (BillRunId) field in the select clause/,
17
- # Invoice Body, implemented as a separate call
18
- /Can only query one invoice (body) at a time/,
19
- # Catalog tier should only query the price field
20
- /use Price or (DiscountAmount) or (DiscountPercentage)/,
21
- # Catalog plan currencies, implemented as a separate call
22
- /When querying for (active currencies)/,
23
- # Catalog charge rollover balance
24
- /You can only query (RolloverBalance) in particular/,
25
- # (Subscription) charge should only query the price field
26
- %r{
27
- (OveragePrice),
28
- \ Price,
29
- \ (IncludedUnits),
30
- \ (DiscountAmount)
31
- \ or\ (DiscountPercentage)
32
- }x
33
- ).freeze
11
+ INVALID_OBJECT_ID = "InvalidObjectId"
34
12
 
35
13
  private_class_method :new
36
14
 
@@ -39,43 +17,36 @@ module IronBank
39
17
  end
40
18
 
41
19
  def call
42
- remove_last_failure_fields until valid_query?
43
-
20
+ remove_invalid_fields until valid_query?
44
21
  (excluded_fields - single_resource_query_fields).sort
45
22
  end
46
23
 
47
24
  private
48
25
 
49
- INVALID_OBJECT_ID = "InvalidObjectId"
50
-
51
- attr_reader :object_name, :last_failed_fields
26
+ attr_reader :object_name, :invalid_fields
52
27
 
53
28
  def_delegators "IronBank.logger", :info
54
29
  def_delegators :object, :single_resource_query_fields
55
30
 
56
31
  def initialize(object_name)
57
- @object_name = object_name
58
- @last_failed_fields = nil
32
+ @object_name = object_name
33
+ @invalid_fields = []
59
34
  end
60
35
 
61
36
  def object
62
- IronBank::Resources.const_get(object_name)
37
+ @object ||= IronBank::Resources.const_get(object_name)
63
38
  end
64
39
 
65
40
  def excluded_fields
66
41
  @excluded_fields ||= object.excluded_fields.dup
67
42
  end
68
43
 
69
- def remove_last_failure_fields
70
- query_fields = object.query_fields
71
-
44
+ def remove_invalid_fields
45
+ query_fields = object.query_fields
72
46
  failed_fields = query_fields.select do |field|
73
- last_failed_fields.any? { |failed| field.casecmp?(failed) }
47
+ invalid_fields.any? { |failed| field.casecmp?(failed) }
74
48
  end
75
-
76
49
  excluded_fields.push(*failed_fields)
77
-
78
- # Remove the field for the next query
79
50
  query_fields.delete_if { |field| failed_fields.include?(field) }
80
51
  end
81
52
 
@@ -83,30 +54,16 @@ module IronBank
83
54
  # Querying using the ID (which is an indexed field) should return an
84
55
  # empty collection very quickly when successful
85
56
  object.where({ id: INVALID_OBJECT_ID })
86
-
87
57
  info "Successful query for #{object_name}"
88
-
89
58
  true
90
- rescue IronBank::InternalServerError, IronBank::BadRequestError => e
91
- @last_failed_fields = extract_fields_from_exception(e)
92
-
59
+ rescue IronBank::BadRequestError, InternalServerError => e
60
+ @invalid_fields = Array(
61
+ ExtractFromMessage.call(e.message) ||
62
+ DeduceFromQuery.call(object)
63
+ )
64
+ info "Invalid fields '#{@invalid_fields}' for #{object_name} query"
93
65
  false
94
66
  end
95
-
96
- def extract_fields_from_exception(exception)
97
- message = exception.message
98
-
99
- raise "Could not parse error message: #{message}" unless FAULT_FIELD_MESSAGES.match(message)
100
-
101
- failed_fields = Regexp.last_match.
102
- captures.
103
- compact.
104
- map { |capture| capture.delete(" ") }
105
-
106
- info "Invalid fields '#{failed_fields}' for #{object_name} query"
107
-
108
- failed_fields
109
- end
110
67
  end
111
68
  end
112
69
  end
@@ -8,7 +8,7 @@ module IronBank
8
8
  module Response
9
9
  # This class raises an exception based on the HTTP status code and the
10
10
  # `success` flag (if present in the response) from Zuora.
11
- class RaiseError < Faraday::Response::Middleware
11
+ class RaiseError < Faraday::Middleware
12
12
  def on_complete(env)
13
13
  (error = IronBank::Error.from_response(env.response)) && raise(error)
14
14
  end
@@ -7,7 +7,7 @@ module IronBank
7
7
  # IronBank Faraday response middleware module
8
8
  module Response
9
9
  # This middleware reauthorize the request on unauthorized request
10
- class RenewAuth < Faraday::Response::Middleware
10
+ class RenewAuth < Faraday::Middleware
11
11
  def initialize(app, auth)
12
12
  @auth = auth
13
13
 
@@ -39,6 +39,14 @@ module IronBank
39
39
  end
40
40
 
41
41
  def self.excluded_fields
42
+ # NOTE: In some instances the error message from Zuora will not include the
43
+ # unqueryable fields that need to be excluded. When that happens IronBank's
44
+ # strategy will be to perform a binary search through the fields listed in the
45
+ # query -- at the cost of performance due to repeated requests sent to Zuora
46
+ # as it tries to identify the offending field.
47
+ #
48
+ # See:
49
+ # - https://github.com/zendesk/iron_bank/pull/107
42
50
  @excluded_fields ||= IronBank::Resources.constants.each.with_object({}) do |resource, fields|
43
51
  fields[resource.to_s] =
44
52
  IronBank::Describe::ExcludedFields.call(object_name: resource)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IronBank
4
- VERSION = "5.4.0"
4
+ VERSION = "6.0.0"
5
5
  API_VERSION = "v1"
6
6
  end
data/lib/iron_bank.rb CHANGED
@@ -3,10 +3,10 @@
3
3
  # External librairies
4
4
  require "csv"
5
5
  require "faraday"
6
- require "faraday_middleware"
7
6
  require "fileutils"
8
7
  require "json"
9
8
  require "nokogiri"
9
+ require "faraday/retry"
10
10
 
11
11
  # An opinionated Ruby interface to the Zuora REST API
12
12
  module IronBank
@@ -83,6 +83,8 @@ require "iron_bank/authentications/token"
83
83
  require "iron_bank/client"
84
84
  require "iron_bank/describe/field"
85
85
  require "iron_bank/describe/excluded_fields"
86
+ require "iron_bank/describe/excluded_fields/deduce_from_query"
87
+ require "iron_bank/describe/excluded_fields/extract_from_message"
86
88
  require "iron_bank/describe/object"
87
89
  require "iron_bank/describe/related"
88
90
  require "iron_bank/describe/tenant"
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_bank
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mickael Pham
8
8
  - Cheng Cui
9
9
  - Ryan Ringler
10
10
  - Mustafa Turan
11
- autorequire:
11
+ autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2023-05-11 00:00:00.000000000 Z
14
+ date: 2025-03-10 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: faraday
@@ -19,28 +19,28 @@ dependencies:
19
19
  requirements:
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '1'
22
+ version: '2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '1'
29
+ version: '2'
30
30
  - !ruby/object:Gem::Dependency
31
- name: faraday_middleware
31
+ name: faraday-retry
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: '1'
36
+ version: '2'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '1'
43
+ version: '2'
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: nokogiri
46
46
  requirement: !ruby/object:Gem::Requirement
@@ -55,7 +55,7 @@ dependencies:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
57
  version: '1'
58
- description:
58
+ description:
59
59
  email:
60
60
  - mickael@zendesk.com
61
61
  - ccui@zendesk.com
@@ -107,6 +107,8 @@ files:
107
107
  - lib/iron_bank/configuration.rb
108
108
  - lib/iron_bank/csv.rb
109
109
  - lib/iron_bank/describe/excluded_fields.rb
110
+ - lib/iron_bank/describe/excluded_fields/deduce_from_query.rb
111
+ - lib/iron_bank/describe/excluded_fields/extract_from_message.rb
110
112
  - lib/iron_bank/describe/field.rb
111
113
  - lib/iron_bank/describe/object.rb
112
114
  - lib/iron_bank/describe/related.rb
@@ -157,7 +159,7 @@ licenses:
157
159
  - Apache-2.0
158
160
  metadata:
159
161
  rubygems_mfa_required: 'true'
160
- post_install_message:
162
+ post_install_message:
161
163
  rdoc_options: []
162
164
  require_paths:
163
165
  - lib
@@ -165,15 +167,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
167
  requirements:
166
168
  - - ">="
167
169
  - !ruby/object:Gem::Version
168
- version: '2.7'
170
+ version: '3.1'
169
171
  required_rubygems_version: !ruby/object:Gem::Requirement
170
172
  requirements:
171
173
  - - ">="
172
174
  - !ruby/object:Gem::Version
173
175
  version: '0'
174
176
  requirements: []
175
- rubygems_version: 3.0.3.1
176
- signing_key:
177
+ rubygems_version: 3.5.22
178
+ signing_key:
177
179
  specification_version: 4
178
180
  summary: An opinionated Ruby interface to the Zuora API.
179
181
  test_files: []