lunchmoney 1.4.0 → 1.5.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +7 -0
  3. data/.github/workflows/build_and_publish_yard_docs.yml +4 -4
  4. data/.github/workflows/ci.yml +9 -10
  5. data/.github/workflows/rbi-updater.yml +1 -1
  6. data/.github/workflows/release_pipeline.yml +1 -1
  7. data/.rubocop.yml +1 -1
  8. data/.ruby-version +1 -1
  9. data/.simplecov +1 -0
  10. data/.toys/.toys.rb +8 -0
  11. data/Gemfile +3 -3
  12. data/Gemfile.lock +102 -78
  13. data/README.md +0 -2
  14. data/SECURITY.md +151 -0
  15. data/bin/check_vcr_version +94 -0
  16. data/lib/lunchmoney/api.rb +26 -38
  17. data/lib/lunchmoney/calls/assets.rb +10 -13
  18. data/lib/lunchmoney/calls/base.rb +59 -7
  19. data/lib/lunchmoney/calls/budgets.rb +22 -25
  20. data/lib/lunchmoney/calls/categories.rb +28 -38
  21. data/lib/lunchmoney/calls/crypto.rb +7 -9
  22. data/lib/lunchmoney/calls/plaid_accounts.rb +7 -9
  23. data/lib/lunchmoney/calls/recurring_expenses.rb +4 -5
  24. data/lib/lunchmoney/calls/tags.rb +3 -4
  25. data/lib/lunchmoney/calls/transactions.rb +28 -37
  26. data/lib/lunchmoney/calls/users.rb +3 -4
  27. data/lib/lunchmoney/configuration.rb +20 -0
  28. data/lib/lunchmoney/deprecate.rb +35 -0
  29. data/lib/lunchmoney/objects/asset.rb +6 -1
  30. data/lib/lunchmoney/objects/object.rb +4 -9
  31. data/lib/lunchmoney/objects/plaid_account.rb +6 -1
  32. data/lib/lunchmoney/validators.rb +8 -6
  33. data/lib/lunchmoney/version.rb +1 -1
  34. data/lib/lunchmoney.rb +3 -3
  35. data/lunchmoney.gemspec +1 -1
  36. data/sorbet/rbi/annotations/activesupport.rbi +40 -0
  37. data/sorbet/rbi/dsl/active_support/callbacks.rbi +0 -2
  38. data/sorbet/rbi/gems/{activesupport@7.2.1.rbi → activesupport@8.0.2.1.rbi} +1431 -1028
  39. data/sorbet/rbi/gems/{ast@2.4.2.rbi → ast@2.4.3.rbi} +4 -3
  40. data/sorbet/rbi/gems/{base64@0.2.0.rbi → base64@0.3.0.rbi} +76 -39
  41. data/sorbet/rbi/gems/benchmark@0.4.1.rbi +619 -0
  42. data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +275 -0
  43. data/sorbet/rbi/gems/{concurrent-ruby@1.3.4.rbi → concurrent-ruby@1.3.5.rbi} +44 -32
  44. data/sorbet/rbi/gems/{connection_pool@2.4.1.rbi → connection_pool@2.5.3.rbi} +1 -0
  45. data/sorbet/rbi/gems/{dotenv@3.1.2.rbi → dotenv@3.1.8.rbi} +21 -29
  46. data/sorbet/rbi/gems/{drb@2.2.1.rbi → drb@2.2.3.rbi} +503 -188
  47. data/sorbet/rbi/gems/{erubi@1.13.0.rbi → erubi@1.13.1.rbi} +14 -9
  48. data/sorbet/rbi/gems/{faraday-net_http@3.1.1.rbi → faraday-net_http@3.4.1.rbi} +34 -34
  49. data/sorbet/rbi/gems/{faraday@2.10.1.rbi → faraday@2.13.4.rbi} +507 -171
  50. data/sorbet/rbi/gems/{hashdiff@1.1.1.rbi → hashdiff@1.2.0.rbi} +5 -3
  51. data/sorbet/rbi/gems/{i18n@1.14.5.rbi → i18n@1.14.7.rbi} +80 -80
  52. data/sorbet/rbi/gems/{json@2.7.2.rbi → json@2.13.2.rbi} +988 -226
  53. data/sorbet/rbi/gems/{kramdown@2.4.0.rbi → kramdown@2.5.1.rbi} +316 -234
  54. data/sorbet/rbi/gems/language_server-protocol@3.17.0.5.rbi +9 -0
  55. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  56. data/sorbet/rbi/gems/{logger@1.6.0.rbi → logger@1.7.0.rbi} +136 -76
  57. data/sorbet/rbi/gems/{minitest@5.25.1.rbi → minitest@5.25.5.rbi} +227 -220
  58. data/sorbet/rbi/gems/{mocha@2.4.5.rbi → mocha@2.7.1.rbi} +154 -118
  59. data/sorbet/rbi/gems/{net-http@0.4.1.rbi → net-http@0.6.0.rbi} +360 -181
  60. data/sorbet/rbi/gems/{parser@3.3.4.2.rbi → parser@3.3.9.0.rbi} +326 -308
  61. data/sorbet/rbi/gems/{prism@0.30.0.rbi → prism@1.4.0.rbi} +12440 -9920
  62. data/sorbet/rbi/gems/{rack@3.1.7.rbi → rack@3.2.1.rbi} +752 -579
  63. data/sorbet/rbi/gems/{rake@13.2.1.rbi → rake@13.3.0.rbi} +238 -227
  64. data/sorbet/rbi/gems/rbi@0.3.6.rbi +5162 -0
  65. data/sorbet/rbi/gems/rbs@4.0.0.dev.4.rbi +7895 -0
  66. data/sorbet/rbi/gems/{regexp_parser@2.9.2.rbi → regexp_parser@2.11.2.rbi} +1124 -1013
  67. data/sorbet/rbi/gems/require-hooks@0.2.2.rbi +110 -0
  68. data/sorbet/rbi/gems/{rexml@3.3.6.rbi → rexml@3.4.2.rbi} +755 -318
  69. data/sorbet/rbi/gems/{rubocop-ast@1.32.1.rbi → rubocop-ast@1.46.0.rbi} +1287 -899
  70. data/sorbet/rbi/gems/{rubocop-minitest@0.35.1.rbi → rubocop-minitest@0.38.2.rbi} +133 -97
  71. data/sorbet/rbi/gems/{rubocop-rails@2.26.0.rbi → rubocop-rails@2.33.3.rbi} +9874 -6597
  72. data/sorbet/rbi/gems/{rubocop-shopify@2.15.1.rbi → rubocop-shopify@2.17.1.rbi} +1 -0
  73. data/sorbet/rbi/gems/{rubocop-sorbet@0.8.5.rbi → rubocop-sorbet@0.10.5.rbi} +804 -83
  74. data/sorbet/rbi/gems/{rubocop@1.65.1.rbi → rubocop@1.80.1.rbi} +10688 -5103
  75. data/sorbet/rbi/gems/{securerandom@0.3.1.rbi → securerandom@0.4.1.rbi} +7 -5
  76. data/sorbet/rbi/gems/{spoom@1.4.2.rbi → spoom@1.7.6.rbi} +1939 -1039
  77. data/sorbet/rbi/gems/{tapioca@0.16.1.rbi → tapioca@0.17.7.rbi} +765 -821
  78. data/sorbet/rbi/gems/{thor@1.3.1.rbi → thor@1.4.0.rbi} +139 -91
  79. data/sorbet/rbi/gems/unicode-display_width@3.1.5.rbi +132 -0
  80. data/sorbet/rbi/gems/unicode-emoji@4.0.4.rbi +251 -0
  81. data/sorbet/rbi/gems/{uri@0.13.0.rbi → uri@1.0.3.rbi} +278 -256
  82. data/sorbet/rbi/gems/{vcr@6.3.1.rbi → vcr@6.3.1-ce35c236fe48899f02ddf780973b44cdb756c0ee.rbi} +140 -123
  83. data/sorbet/rbi/gems/{webmock@3.23.1.rbi → webmock@3.25.1.rbi} +101 -78
  84. data/sorbet/rbi/gems/{yard@0.9.36.rbi → yard@0.9.37.rbi} +394 -235
  85. metadata +55 -53
  86. data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +0 -78
  87. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +0 -14237
  88. data/sorbet/rbi/gems/rbi@0.1.14.rbi +0 -3305
  89. data/sorbet/rbi/gems/strscan@3.1.0.rbi +0 -9
  90. data/sorbet/rbi/gems/unicode-display_width@2.5.0.rbi +0 -65
  91. /data/sorbet/rbi/gems/{parallel@1.26.3.rbi → parallel@1.27.0.rbi} +0 -0
@@ -17,11 +17,10 @@ module LunchMoney
17
17
  params = clean_params({ start_date:, end_date: })
18
18
  response = get("recurring_expenses", query_params: params)
19
19
 
20
- api_errors = errors(response)
21
- return api_errors if api_errors.present?
22
-
23
- response.body[:recurring_expenses].map do |recurring_expense|
24
- LunchMoney::Objects::RecurringExpense.new(**recurring_expense)
20
+ handle_api_response(response) do |body|
21
+ body[:recurring_expenses].map do |recurring_expense|
22
+ LunchMoney::Objects::RecurringExpense.new(**recurring_expense)
23
+ end
25
24
  end
26
25
  end
27
26
  end
@@ -11,10 +11,9 @@ module LunchMoney
11
11
  def tags
12
12
  response = get("tags")
13
13
 
14
- api_errors = errors(response)
15
- return api_errors if api_errors.present?
16
-
17
- response.body.map { |tag| LunchMoney::Objects::Tag.new(**tag) }
14
+ handle_api_response(response) do |body|
15
+ body.map { |tag| LunchMoney::Objects::Tag.new(**tag) }
16
+ end
18
17
  end
19
18
  end
20
19
  end
@@ -42,7 +42,6 @@ module LunchMoney
42
42
  offset: nil,
43
43
  limit: nil
44
44
  )
45
-
46
45
  params = clean_params({
47
46
  tag_id:,
48
47
  recurring_id:,
@@ -60,17 +59,16 @@ module LunchMoney
60
59
  })
61
60
  response = get("transactions", query_params: params)
62
61
 
63
- api_errors = errors(response)
64
- return api_errors if api_errors.present?
62
+ handle_api_response(response) do |body|
63
+ body[:transactions].map do |transaction|
64
+ transaction[:tags].map! { |tag| LunchMoney::Objects::TagBase.new(**tag) }
65
65
 
66
- response.body[:transactions].map do |transaction|
67
- transaction[:tags].map! { |tag| LunchMoney::Objects::TagBase.new(**tag) }
66
+ transaction[:children]&.map! do |child_transaction|
67
+ LunchMoney::Objects::ChildTransaction.new(**child_transaction)
68
+ end
68
69
 
69
- transaction[:children]&.map! do |child_transaction|
70
- LunchMoney::Objects::ChildTransaction.new(**child_transaction)
70
+ LunchMoney::Objects::Transaction.new(**transaction)
71
71
  end
72
-
73
- LunchMoney::Objects::Transaction.new(**transaction)
74
72
  end
75
73
  end
76
74
 
@@ -84,10 +82,9 @@ module LunchMoney
84
82
  params = clean_params({ debit_as_negative: })
85
83
  response = get("transactions/#{transaction_id}", query_params: params)
86
84
 
87
- api_errors = errors(response)
88
- return api_errors if api_errors.present?
89
-
90
- LunchMoney::Objects::Transaction.new(**response.body)
85
+ handle_api_response(response) do |body|
86
+ LunchMoney::Objects::Transaction.new(**body)
87
+ end
91
88
  end
92
89
 
93
90
  sig do
@@ -112,10 +109,9 @@ module LunchMoney
112
109
  })
113
110
  response = post("transactions", params)
114
111
 
115
- api_errors = errors(response)
116
- return api_errors if api_errors.present?
117
-
118
- response.body
112
+ handle_api_response(response) do |body|
113
+ body
114
+ end
119
115
  end
120
116
 
121
117
  sig do
@@ -142,10 +138,9 @@ module LunchMoney
142
138
  })
143
139
  response = put("transactions/#{transaction_id}", params)
144
140
 
145
- api_errors = errors(response)
146
- return api_errors if api_errors.present?
147
-
148
- response.body
141
+ handle_api_response(response) do |body|
142
+ body
143
+ end
149
144
  end
150
145
 
151
146
  sig do
@@ -158,20 +153,18 @@ module LunchMoney
158
153
  params = { parent_ids:, remove_parents: }
159
154
  response = post("transactions/unsplit", params)
160
155
 
161
- api_errors = errors(response)
162
- return api_errors if api_errors.present?
163
-
164
- response.body
156
+ handle_api_response(response) do |body|
157
+ body
158
+ end
165
159
  end
166
160
 
167
161
  sig { params(transaction_id: Integer).returns(T.any(LunchMoney::Objects::Transaction, LunchMoney::Errors)) }
168
162
  def transaction_group(transaction_id)
169
163
  response = get("transactions/group", query_params: { transaction_id: })
170
164
 
171
- api_errors = errors(response)
172
- return api_errors if api_errors.present?
173
-
174
- LunchMoney::Objects::Transaction.new(**response.body)
165
+ handle_api_response(response) do |body|
166
+ LunchMoney::Objects::Transaction.new(**body)
167
+ end
175
168
  end
176
169
 
177
170
  sig do
@@ -195,10 +188,9 @@ module LunchMoney
195
188
  })
196
189
  response = post("transactions/group", params)
197
190
 
198
- api_errors = errors(response)
199
- return api_errors if api_errors.present?
200
-
201
- response.body
191
+ handle_api_response(response) do |body|
192
+ body
193
+ end
202
194
  end
203
195
 
204
196
  sig do
@@ -210,10 +202,9 @@ module LunchMoney
210
202
  def delete_transaction_group(transaction_id)
211
203
  response = delete("transactions/group/#{transaction_id}")
212
204
 
213
- api_errors = errors(response)
214
- return api_errors if api_errors.present?
215
-
216
- response.body
205
+ handle_api_response(response) do |body|
206
+ body
207
+ end
217
208
  end
218
209
  end
219
210
  end
@@ -11,10 +11,9 @@ module LunchMoney
11
11
  def me
12
12
  response = get("me")
13
13
 
14
- api_errors = errors(response)
15
- return api_errors if api_errors.present?
16
-
17
- LunchMoney::Objects::User.new(**response.body)
14
+ handle_api_response(response) do |body|
15
+ LunchMoney::Objects::User.new(**body)
16
+ end
18
17
  end
19
18
  end
20
19
  end
@@ -22,5 +22,25 @@ module LunchMoney
22
22
  @api_key = ENV.fetch("LUNCHMONEY_TOKEN", nil)
23
23
  @validate_object_attributes = T.let(true, T::Boolean)
24
24
  end
25
+
26
+ sig { returns(T::Array[String]) }
27
+ def validation_errors
28
+ errors = []
29
+
30
+ if api_key&.strip&.empty?
31
+ errors << "API key cannot be empty"
32
+ end
33
+
34
+ if api_key && T.must(api_key).length < 10
35
+ errors << "API key appears to be too short"
36
+ end
37
+
38
+ errors
39
+ end
40
+
41
+ sig { returns(T::Boolean) }
42
+ def valid?
43
+ validation_errors.empty?
44
+ end
25
45
  end
26
46
  end
@@ -0,0 +1,35 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module LunchMoney
5
+ module Deprecate
6
+ cattr_accessor :endpoint_deprecation_warnings, default: true
7
+
8
+ sig { params(replacement: T.nilable(String)).void }
9
+ def deprecate_endpoint(replacement = nil)
10
+ return unless endpoint_deprecation_warnings
11
+
12
+ replacement = if replacement.nil?
13
+ "There is currently no replacement for this endpoint"
14
+ else
15
+ "Please use #{replacement} instead"
16
+ end
17
+
18
+ message = "#{deprecated_endpoint} is deprecated and may be removed from LunchMoney | #{replacement}"
19
+ Kernel.warn(message)
20
+ end
21
+
22
+ private
23
+
24
+ sig { returns(String) }
25
+ def deprecated_endpoint
26
+ endpoint_call = Kernel.caller_locations.find { |call| call.to_s.include?("lunchmoney/calls") }
27
+
28
+ if endpoint_call.nil?
29
+ ""
30
+ else
31
+ "LunchMoney::Api##{endpoint_call.label}"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -22,6 +22,9 @@ module LunchMoney
22
22
  sig { returns(T::Boolean) }
23
23
  attr_accessor :exclude_transactions
24
24
 
25
+ sig { returns(T.nilable(Number)) }
26
+ attr_accessor :to_base
27
+
25
28
  # Valid asset type names
26
29
  VALID_TYPE_NAMES = T.let(
27
30
  [
@@ -54,10 +57,11 @@ module LunchMoney
54
57
  display_name: T.nilable(String),
55
58
  closed_on: T.nilable(String),
56
59
  institution_name: T.nilable(String),
60
+ to_base: T.nilable(Number),
57
61
  ).void
58
62
  end
59
63
  def initialize(created_at:, type_name:, name:, balance:, balance_as_of:, currency:, exclude_transactions:, id:,
60
- subtype_name: nil, display_name: nil, closed_on: nil, institution_name: nil)
64
+ subtype_name: nil, display_name: nil, closed_on: nil, institution_name: nil, to_base: nil)
61
65
  super()
62
66
  @created_at = T.let(validate_iso8601!(created_at), String)
63
67
  @type_name = T.let(validate_one_of!(type_name, VALID_TYPE_NAMES), String)
@@ -71,6 +75,7 @@ module LunchMoney
71
75
  @display_name = display_name
72
76
  @closed_on = closed_on
73
77
  @institution_name = institution_name
78
+ @to_base = to_base
74
79
  end
75
80
 
76
81
  sig { params(name: String).void }
@@ -8,17 +8,12 @@ module LunchMoney
8
8
  class Object
9
9
  sig { params(symbolize_keys: T::Boolean).returns(T::Hash[T.any(String, Symbol), T.untyped]) }
10
10
  def serialize(symbolize_keys: false)
11
- ivars = instance_variables
12
-
13
11
  output = {}
14
12
 
15
- ivars.each do |ivar|
16
- key = ivar.to_s.gsub("@", "")
17
- key = key.to_sym if symbolize_keys
18
-
19
- value = instance_variable_get(ivar)
20
-
21
- output[key] = value
13
+ instance_variables.each do |ivar|
14
+ key_string = ivar.to_s.delete_prefix("@")
15
+ key = symbolize_keys ? key_string.to_sym : key_string
16
+ output[key] = instance_variable_get(ivar)
22
17
  end
23
18
 
24
19
  output
@@ -27,6 +27,9 @@ module LunchMoney
27
27
  sig { returns(T.nilable(Integer)) }
28
28
  attr_accessor :limit
29
29
 
30
+ sig { returns(T.nilable(Number)) }
31
+ attr_accessor :to_base
32
+
30
33
  sig do
31
34
  params(
32
35
  date_linked: String,
@@ -46,11 +49,12 @@ module LunchMoney
46
49
  subtype: T.nilable(String),
47
50
  import_start_date: T.nilable(String),
48
51
  last_fetch: T.nilable(String),
52
+ to_base: T.nilable(Number),
49
53
  ).void
50
54
  end
51
55
  def initialize(date_linked:, name:, type:, mask:, institution_name:, status:, balance:, currency:,
52
56
  balance_last_update:, display_name:, id:, plaid_last_successful_update:, last_import: nil, limit: nil,
53
- subtype: nil, import_start_date: nil, last_fetch: nil)
57
+ subtype: nil, import_start_date: nil, last_fetch: nil, to_base: nil)
54
58
  super()
55
59
  @id = id
56
60
  @date_linked = date_linked
@@ -69,6 +73,7 @@ module LunchMoney
69
73
  @last_import = last_import
70
74
  @last_fetch = last_fetch
71
75
  @plaid_last_successful_update = plaid_last_successful_update
76
+ @to_base = to_base
72
77
  end
73
78
  end
74
79
  end
@@ -8,9 +8,10 @@ module LunchMoney
8
8
  module Validators
9
9
  include Kernel
10
10
 
11
- sig { params(value: String, valid_values: T::Array[String]).returns(String) }
12
- def validate_one_of!(value, valid_values)
13
- return value unless LunchMoney.validate_object_attributes?
11
+ sig { params(value: String, valid_values: T::Array[String], validate: T.nilable(T::Boolean)).returns(String) }
12
+ def validate_one_of!(value, valid_values, validate: nil)
13
+ should_validate = validate.nil? ? LunchMoney.validate_object_attributes? : validate
14
+ return value unless should_validate
14
15
 
15
16
  if valid_values.exclude?(value)
16
17
  raise(InvalidObjectAttribute, "#{value} is invalid, must be one of #{valid_values.join(", ")}")
@@ -19,9 +20,10 @@ module LunchMoney
19
20
  value
20
21
  end
21
22
 
22
- sig { params(value: String).returns(String) }
23
- def validate_iso8601!(value)
24
- return value unless LunchMoney.validate_object_attributes?
23
+ sig { params(value: String, validate: T.nilable(T::Boolean)).returns(String) }
24
+ def validate_iso8601!(value, validate: nil)
25
+ should_validate = validate.nil? ? LunchMoney.validate_object_attributes? : validate
26
+ return value unless should_validate
25
27
 
26
28
  raise(InvalidObjectAttribute, "#{value} is not a valid ISO 8601 string") unless valid_iso8601_string?(value)
27
29
 
@@ -3,5 +3,5 @@
3
3
 
4
4
  module LunchMoney
5
5
  # Current version of the gem
6
- VERSION = "1.4.0"
6
+ VERSION = "1.5.0"
7
7
  end
data/lib/lunchmoney.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "active_support"
5
- require "active_support/core_ext/module/delegation.rb"
6
- require "active_support/core_ext/object/blank.rb"
4
+ require "active_support/core_ext/module/delegation"
5
+ require "active_support/core_ext/object/blank"
6
+ require "active_support/core_ext/module/attribute_accessors"
7
7
  require "faraday"
8
8
  require "sorbet-runtime"
9
9
 
data/lunchmoney.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
 
10
10
  spec.summary = "LunchMoney API client library."
11
11
  spec.homepage = "https://github.com/mmenanno/lunchmoney"
12
- spec.required_ruby_version = ">= 3.1"
12
+ spec.required_ruby_version = ">= 3.2"
13
13
  spec.license = "MIT"
14
14
 
15
15
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
@@ -88,6 +88,10 @@ class Hash
88
88
 
89
89
  sig { returns(T::Boolean) }
90
90
  def extractable_options?; end
91
+
92
+ # @version >= 6.1.0
93
+ sig { returns(T::Hash[K, V]) }
94
+ def compact_blank; end
91
95
  end
92
96
 
93
97
  class Array
@@ -193,6 +197,32 @@ class DateTime
193
197
  def present?; end
194
198
  end
195
199
 
200
+ module Enumerable
201
+ sig { type_parameters(:Block).params(block: T.proc.params(arg0: Elem).returns(T.type_parameter(:Block))).returns(T::Hash[T.type_parameter(:Block), Elem]) }
202
+ sig { returns(T::Enumerable[T.untyped]) }
203
+ def index_by(&block); end
204
+
205
+ sig { type_parameters(:Block).params(block: T.proc.params(arg0: Elem).returns(T.type_parameter(:Block))).returns(T::Hash[Elem, T.type_parameter(:Block)]) }
206
+ sig { returns(T::Enumerable[T.untyped]) }
207
+ sig { type_parameters(:Default).params(default: T.type_parameter(:Default)).returns(T::Hash[Elem, T.type_parameter(:Default)]) }
208
+ def index_with(default = nil, &block); end
209
+
210
+ sig { params(block: T.proc.params(arg0: Elem).returns(BasicObject)).returns(T::Boolean) }
211
+ sig { returns(T::Boolean) }
212
+ def many?(&block); end
213
+
214
+ sig { params(object: BasicObject).returns(T::Boolean) }
215
+ def exclude?(object); end
216
+
217
+ # @version >= 6.1.0
218
+ sig { returns(T::Array[Elem]) }
219
+ def compact_blank; end
220
+
221
+ # @version >= 7.0.0
222
+ sig { returns(Elem) }
223
+ def sole; end
224
+ end
225
+
196
226
  class NilClass
197
227
  sig { returns(TrueClass) }
198
228
  def blank?; end
@@ -287,6 +317,8 @@ class String
287
317
  sig { returns(TrueClass) }
288
318
  def acts_like_string?; end
289
319
 
320
+ # This is the subset of `#[]` sigs that have just 1 parameter.
321
+ # https://github.com/sorbet/sorbet/blob/40ad87b4dc7be23fa00c1369ac9f927053c68907/rbi/core/string.rbi#L270-L303
290
322
  sig { params(position: Integer).returns(T.nilable(String)) }
291
323
  sig { params(position: T.any(T::Range[Integer], Regexp)).returns(T.nilable(String)) }
292
324
  sig { params(position: String).returns(T.nilable(String)) }
@@ -437,12 +469,15 @@ class String
437
469
  end
438
470
 
439
471
  class ActiveSupport::ErrorReporter
472
+ # @version >= 7.1.0.beta1
440
473
  sig { type_parameters(:Block, :Fallback).params(error_classes: T.class_of(Exception), severity: T.nilable(Symbol), context: T.nilable(T::Hash[Symbol, T.untyped]), fallback: T.nilable(T.proc.returns(T.type_parameter(:Fallback))), source: T.nilable(String), blk: T.proc.returns(T.type_parameter(:Block))).returns(T.any(T.type_parameter(:Block), T.type_parameter(:Fallback))) }
441
474
  def handle(*error_classes, severity: T.unsafe(nil), context: T.unsafe(nil), fallback: T.unsafe(nil), source: T.unsafe(nil), &blk); end
442
475
 
476
+ # @version >= 7.1.0.beta1
443
477
  sig { type_parameters(:Block).params(error_classes: T.class_of(Exception), severity: T.nilable(Symbol), context: T.nilable(T::Hash[Symbol, T.untyped]), source: T.nilable(String), blk: T.proc.returns(T.type_parameter(:Block))).returns(T.type_parameter(:Block)) }
444
478
  def record(*error_classes, severity: T.unsafe(nil), context: T.unsafe(nil), source: T.unsafe(nil), &blk); end
445
479
 
480
+ # @version >= 7.1.0.beta1
446
481
  sig { params(error: Exception, handled: T::Boolean, severity: T.nilable(Symbol), context: T::Hash[Symbol, T.untyped], source: T.nilable(String)).void }
447
482
  def report(error, handled: true, severity: T.unsafe(nil), context: T.unsafe(nil), source: T.unsafe(nil)); end
448
483
 
@@ -450,3 +485,8 @@ class ActiveSupport::ErrorReporter
450
485
  sig { params(error: T.any(Exception, String), severity: T.nilable(Symbol), context: T::Hash[Symbol, T.untyped], source: T.nilable(String)).void }
451
486
  def unexpected(error, severity: T.unsafe(nil), context: T.unsafe(nil), source: T.unsafe(nil)); end
452
487
  end
488
+
489
+ module ActiveSupport::Testing::Assertions
490
+ sig { type_parameters(:Block).params(block: T.proc.returns(T.type_parameter(:Block))).returns(T.type_parameter(:Block)) }
491
+ def assert_nothing_raised(&block); end
492
+ end
@@ -13,11 +13,9 @@ module ActiveSupport::Callbacks
13
13
  module GeneratedClassMethods
14
14
  def __callbacks; end
15
15
  def __callbacks=(value); end
16
- def __callbacks?; end
17
16
  end
18
17
 
19
18
  module GeneratedInstanceMethods
20
19
  def __callbacks; end
21
- def __callbacks?; end
22
20
  end
23
21
  end