whatsapp_sdk 0.3.2 → 0.4.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +14 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.lock +44 -0
  7. data/README.md +102 -28
  8. data/Rakefile +1 -0
  9. data/bin/tapioca +30 -0
  10. data/example.rb +31 -36
  11. data/lib/version.rb +2 -1
  12. data/lib/whatsapp_sdk/api/client.rb +14 -3
  13. data/lib/whatsapp_sdk/api/medias.rb +12 -3
  14. data/lib/whatsapp_sdk/api/messages.rb +72 -14
  15. data/lib/whatsapp_sdk/api/phone_numbers.rb +3 -0
  16. data/lib/whatsapp_sdk/api/request.rb +2 -2
  17. data/lib/whatsapp_sdk/api/response.rb +17 -1
  18. data/lib/whatsapp_sdk/api/responses/data_response.rb +10 -3
  19. data/lib/whatsapp_sdk/api/responses/error_response.rb +8 -1
  20. data/lib/whatsapp_sdk/api/responses/media_data_response.rb +26 -7
  21. data/lib/whatsapp_sdk/api/responses/message_data_response.rb +20 -3
  22. data/lib/whatsapp_sdk/api/responses/message_error_response.rb +26 -7
  23. data/lib/whatsapp_sdk/api/responses/phone_number_data_response.rb +18 -5
  24. data/lib/whatsapp_sdk/api/responses/phone_numbers_data_response.rb +9 -1
  25. data/lib/whatsapp_sdk/api/responses/read_message_data_response.rb +10 -3
  26. data/lib/whatsapp_sdk/api/responses/success_response.rb +5 -1
  27. data/lib/whatsapp_sdk/configuration.rb +7 -3
  28. data/lib/whatsapp_sdk/error.rb +1 -0
  29. data/lib/whatsapp_sdk/resource/address.rb +30 -6
  30. data/lib/whatsapp_sdk/resource/address_type.rb +15 -0
  31. data/lib/whatsapp_sdk/resource/button_parameter.rb +19 -23
  32. data/lib/whatsapp_sdk/resource/component.rb +45 -13
  33. data/lib/whatsapp_sdk/resource/contact.rb +30 -1
  34. data/lib/whatsapp_sdk/resource/contact_response.rb +9 -1
  35. data/lib/whatsapp_sdk/resource/currency.rb +9 -1
  36. data/lib/whatsapp_sdk/resource/date_time.rb +7 -1
  37. data/lib/whatsapp_sdk/resource/email.rb +9 -5
  38. data/lib/whatsapp_sdk/resource/media.rb +44 -15
  39. data/lib/whatsapp_sdk/resource/message.rb +5 -0
  40. data/lib/whatsapp_sdk/resource/name.rb +28 -1
  41. data/lib/whatsapp_sdk/resource/org.rb +13 -1
  42. data/lib/whatsapp_sdk/resource/parameter_object.rb +82 -39
  43. data/lib/whatsapp_sdk/resource/phone_number.rb +12 -5
  44. data/lib/whatsapp_sdk/resource/url.rb +9 -5
  45. data/lib/whatsapp_sdk.rb +7 -0
  46. data/sorbet/config +6 -0
  47. data/sorbet/rbi/annotations/faraday.rbi +17 -0
  48. data/sorbet/rbi/annotations/mocha.rbi +34 -0
  49. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  50. data/sorbet/rbi/gems/faraday-multipart@1.0.4.rbi +270 -0
  51. data/sorbet/rbi/gems/faraday-net_http@2.0.3.rbi +182 -0
  52. data/sorbet/rbi/gems/faraday@2.3.0.rbi +2494 -0
  53. data/sorbet/rbi/gems/method_source@1.0.0.rbi +272 -0
  54. data/sorbet/rbi/gems/minitest@5.16.1.rbi +1459 -0
  55. data/sorbet/rbi/gems/mocha@1.14.0.rbi +60 -0
  56. data/sorbet/rbi/gems/multipart-post@2.2.3.rbi +239 -0
  57. data/sorbet/rbi/gems/netrc@0.11.0.rbi +150 -0
  58. data/sorbet/rbi/gems/oj@3.13.14.rbi +589 -0
  59. data/sorbet/rbi/gems/zeitwerk@2.6.0.rbi +867 -0
  60. data/sorbet/rbi/todo.rbi +8 -0
  61. data/sorbet/shims/request.rbi +10 -0
  62. data/sorbet/tapioca/config.yml +13 -0
  63. data/sorbet/tapioca/require.rb +5 -0
  64. data/whatsapp_sdk.gemspec +4 -1
  65. metadata +50 -2
@@ -1,16 +1,28 @@
1
1
  # frozen_string_literal: true
2
+ # typed: strict
2
3
 
3
4
  module WhatsappSdk
4
5
  module Resource
5
6
  class Org
6
- attr_accessor :company, :department, :title
7
+ extend T::Sig
7
8
 
9
+ sig { returns(String) }
10
+ attr_accessor :company
11
+
12
+ sig { returns(String) }
13
+ attr_accessor :department
14
+
15
+ sig { returns(String) }
16
+ attr_accessor :title
17
+
18
+ sig { params(company: String, department: String, title: String).void }
8
19
  def initialize(company:, department:, title:)
9
20
  @company = company
10
21
  @department = department
11
22
  @title = title
12
23
  end
13
24
 
25
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
14
26
  def to_h
15
27
  {
16
28
  company: @company,
@@ -1,20 +1,37 @@
1
1
  # frozen_string_literal: true
2
+ # typed: strict
2
3
 
3
4
  module WhatsappSdk
4
5
  module Resource
5
6
  class ParameterObject
7
+ extend T::Sig
8
+
6
9
  class InvalidType < StandardError
10
+ extend T::Sig
11
+
12
+ sig { returns(String) }
7
13
  attr_accessor :message
8
14
 
15
+ sig { params(type: String).void }
9
16
  def initialize(type)
10
- @message = "invalid type #{type}. type should be text, currency, date_time, image, document or video"
17
+ @message = T.let(
18
+ "invalid type #{type}. type should be text, currency, date_time, image, document or video",
19
+ String
20
+ )
11
21
  super
12
22
  end
13
23
  end
14
24
 
15
25
  class MissingValue < StandardError
16
- attr_reader :field, :message
26
+ extend T::Sig
27
+
28
+ sig { returns(String) }
29
+ attr_reader :field
17
30
 
31
+ sig { returns(String) }
32
+ attr_reader :message
33
+
34
+ sig { params(field: String, message: String).void }
18
35
  def initialize(field, message)
19
36
  @field = field
20
37
  @message = message
@@ -25,17 +42,20 @@ module WhatsappSdk
25
42
  # Returns the parameter type.
26
43
  #
27
44
  # @returns type [String] Valid options are text, currency, date_time, image, document, video.
45
+ sig { returns(Type) }
28
46
  attr_accessor :type
29
47
 
30
- module Type
31
- TEXT = "text"
32
- CURRENCY = "currency"
33
- DATE_TIME = "date_time"
34
- IMAGE = "image"
35
- DOCUMENT = "document"
36
- VIDEO = "video"
48
+ class Type < T::Enum
49
+ extend T::Sig
37
50
 
38
- VALID_TYPES = [TEXT, CURRENCY, DATE_TIME, IMAGE, DOCUMENT, VIDEO].freeze
51
+ enums do
52
+ Text = new("text")
53
+ Currency = new("currency")
54
+ DateTime = new("date_time")
55
+ Image = new("image")
56
+ Document = new("document")
57
+ Video = new("video")
58
+ end
39
59
  end
40
60
 
41
61
  # Returns Text string if the parameter object type is text.
@@ -43,35 +63,47 @@ module WhatsappSdk
43
63
  # For the body component, the character limit is 1024 characters.
44
64
  #
45
65
  # @returns text [String]
66
+ sig { returns(T.nilable(String)) }
46
67
  attr_accessor :text
47
68
 
48
69
  # Returns Currency if the parameter object type is currency.
49
70
  #
50
71
  # @returns currency [Currency]
72
+ sig { returns(T.nilable(Currency)) }
51
73
  attr_accessor :currency
52
74
 
53
75
  # Returns date_time if the parameter object type is date_time.
54
76
  #
55
77
  # @returns date_time [DateTime]
78
+ sig { returns(T.nilable(DateTime)) }
56
79
  attr_accessor :date_time
57
80
 
58
81
  # Returns image if the parameter object type is image.
59
82
  #
60
83
  # @returns image [Media]
84
+ sig { returns(T.nilable(Media)) }
61
85
  attr_accessor :image
62
86
 
63
87
  # Returns document if the parameter object type is document.
64
88
  #
65
89
  # @returns document [Media]
90
+ sig { returns(T.nilable(Media)) }
66
91
  attr_accessor :document
67
92
 
68
93
  # Returns video if the parameter object type is video.
69
94
  #
70
95
  # @returns video [Media]
96
+ sig { returns(T.nilable(Media)) }
71
97
  attr_accessor :video
72
98
 
99
+ sig do
100
+ params(
101
+ type: T.any(Type, String), text: T.nilable(String), currency: T.nilable(Currency),
102
+ date_time: T.nilable(DateTime), image: T.nilable(Media), document: T.nilable(Media), video: T.nilable(Media)
103
+ ).void
104
+ end
73
105
  def initialize(type:, text: nil, currency: nil, date_time: nil, image: nil, document: nil, video: nil)
74
- @type = type
106
+ @type = T.let(deserialize_type(type), Type)
75
107
  @text = text
76
108
  @currency = currency
77
109
  @date_time = date_time
@@ -81,52 +113,63 @@ module WhatsappSdk
81
113
  validate
82
114
  end
83
115
 
84
- def to_json(*_args)
85
- json = { type: type }
86
- json[type.to_sym] = case type
87
- when "text"
88
- text
89
- when "currency"
90
- currency.to_json
91
- when "date_time"
92
- date_time.to_json
93
- when "image"
94
- image.to_json
95
- when "document"
96
- document.to_json
97
- when "video"
98
- video.to_json
99
- else
100
- raise "Invalid type: #{type}"
101
- end
116
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
117
+ def to_json
118
+ json = { type: type.serialize }
119
+ json[type.serialize.to_sym] = case type.serialize
120
+ when "text"
121
+ text
122
+ when "currency"
123
+ T.must(currency).to_json
124
+ when "date_time"
125
+ T.must(date_time).to_json
126
+ when "image"
127
+ T.must(image).to_json
128
+ when "document"
129
+ T.must(document).to_json
130
+ when "video"
131
+ T.must(video).to_json
132
+ else
133
+ raise "Invalid type: #{type}"
134
+ end
102
135
 
103
136
  json
104
137
  end
105
138
 
106
139
  private
107
140
 
141
+ sig { params(type: T.any(String, Type)).returns(Type) }
142
+ def deserialize_type(type)
143
+ return type if type.is_a?(Type)
144
+
145
+ Type.deserialize(type)
146
+ end
147
+
148
+ sig { void }
108
149
  def validate
109
150
  validate_attributes
110
151
  validate_type
111
152
  end
112
153
 
154
+ sig { void }
113
155
  def validate_type
114
- return if Type::VALID_TYPES.include?(type)
156
+ return if Type.valid?(type)
115
157
 
116
158
  raise InvalidType, type
117
159
  end
118
160
 
161
+ sig { void }
119
162
  def validate_attributes
120
163
  [
121
- [:text, text],
122
- [:currency, currency],
123
- [:date_time, date_time],
124
- [:image, image],
125
- [:document, document],
126
- [:video, video]
127
- ].each do |type_sym, value|
128
- next unless type == type_sym
129
- raise MissingValue.new(type, "#{type} is required when the type is #{type}") if value.nil?
164
+ [Type::Text, text],
165
+ [Type::Currency, currency],
166
+ [Type::DateTime, date_time],
167
+ [Type::Image, image],
168
+ [Type::Document, document],
169
+ [Type::Video, video]
170
+ ].each do |type_b, value|
171
+ next unless type == type_b
172
+ raise MissingValue.new(type.serialize, "#{type_b} is required when the type is #{type_b}") if value.nil?
130
173
  end
131
174
  end
132
175
  end
@@ -1,21 +1,28 @@
1
1
  # frozen_string_literal: true
2
+ # typed: strict
2
3
 
3
4
  module WhatsappSdk
4
5
  module Resource
5
6
  class PhoneNumber
6
- attr_accessor :phone, :type, :wa_id
7
+ extend T::Sig
7
8
 
8
- PHONE_NUMBER_TYPE = {
9
- home: "HOME",
10
- work: "WORK"
11
- }.freeze
9
+ sig { returns(String) }
10
+ attr_accessor :phone
12
11
 
12
+ sig { returns(String) }
13
+ attr_accessor :wa_id
14
+
15
+ sig { returns(AddressType) }
16
+ attr_accessor :type
17
+
18
+ sig { params(phone: String, type: AddressType, wa_id: String).void }
13
19
  def initialize(phone:, type:, wa_id:)
14
20
  @phone = phone
15
21
  @type = type
16
22
  @wa_id = wa_id
17
23
  end
18
24
 
25
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
19
26
  def to_h
20
27
  {
21
28
  phone: @phone,
@@ -1,20 +1,24 @@
1
1
  # frozen_string_literal: true
2
+ # typed: strict
2
3
 
3
4
  module WhatsappSdk
4
5
  module Resource
5
6
  class Url
6
- attr_accessor :url, :type
7
+ extend T::Sig
7
8
 
8
- ADDRESS_TYPE = {
9
- home: "HOME",
10
- work: "WORK"
11
- }.freeze
9
+ sig { returns(String) }
10
+ attr_accessor :url
12
11
 
12
+ sig { returns(AddressType) }
13
+ attr_accessor :type
14
+
15
+ sig { params(url: String, type: AddressType).void }
13
16
  def initialize(url:, type:)
14
17
  @url = url
15
18
  @type = type
16
19
  end
17
20
 
21
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
18
22
  def to_h
19
23
  {
20
24
  url: @url,
data/lib/whatsapp_sdk.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  require "zeitwerk"
5
+
4
6
  loader = Zeitwerk::Loader.for_gem
5
7
  loader.setup
6
8
 
9
+ require "sorbet-runtime"
10
+
7
11
  module WhatsappSdk
8
12
  class << self
13
+ extend T::Sig
14
+
15
+ sig { returns(Configuration) }
9
16
  def configuration
10
17
  @configuration ||= Configuration.new
11
18
  end
data/sorbet/config ADDED
@@ -0,0 +1,6 @@
1
+ --dir
2
+ .
3
+ --ignore=vendor/
4
+ --ignore=testing.rb
5
+ --ignore=example.rb
6
+ --enable-experimental-requires-ancestor
@@ -0,0 +1,17 @@
1
+ # typed: strict
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Faraday
8
+ class << self
9
+ sig { params(url: T.untyped, options: T::Hash[Symbol, T.untyped], block: T.nilable(T.proc.params(connection: Faraday::Connection).void)).returns(Faraday::Connection) }
10
+ def new(url = nil, options = {}, &block); end
11
+ end
12
+ end
13
+
14
+ class Faraday::Response
15
+ sig { returns(T::Boolean) }
16
+ def success?; end
17
+ end
@@ -0,0 +1,34 @@
1
+ # typed: strict
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Mocha::API
8
+ sig { params(arguments: T.untyped).returns(Mocha::Mock) }
9
+ def mock(*arguments); end
10
+
11
+ sig { params(arguments: T.untyped).returns(T.untyped) }
12
+ def stub(*arguments); end
13
+ end
14
+
15
+ module Mocha::ClassMethods
16
+ sig { returns(Mocha::Mock) }
17
+ def any_instance; end
18
+ end
19
+
20
+ class Mocha::Expectation
21
+ sig { params(expected_parameters: T.untyped, matching_block: T.nilable(T.proc.params(actual_parameters: T.untyped).void)).returns(Mocha::Expectation) }
22
+ def with(*expected_parameters, &matching_block); end
23
+
24
+ sig { params(values: T.untyped).returns(Mocha::Expectation) }
25
+ def returns(*values); end
26
+ end
27
+
28
+ module Mocha::ObjectMethods
29
+ sig { params(expected_methods_vs_return_values: T.untyped).returns(Mocha::Expectation) }
30
+ def expects(expected_methods_vs_return_values); end
31
+
32
+ sig { params(stubbed_methods_vs_return_values: T.untyped).returns(Mocha::Expectation) }
33
+ def stubs(stubbed_methods_vs_return_values); end
34
+ end
@@ -0,0 +1,269 @@
1
+ # typed: strict
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Rainbow
8
+ # @shim: https://github.com/sickill/rainbow/blob/master/lib/rainbow.rb#L10-L12
9
+ sig { returns(T::Boolean) }
10
+ attr_accessor :enabled
11
+
12
+ class Color
13
+ sig { returns(Symbol) }
14
+ attr_reader :ground
15
+
16
+ sig { params(ground: Symbol, values: T.any([Integer], [Integer, Integer, Integer])).returns(Color) }
17
+ def self.build(ground, values); end
18
+
19
+ sig { params(hex: String).returns([Integer, Integer, Integer]) }
20
+ def self.parse_hex_color(hex); end
21
+
22
+ class Indexed < Rainbow::Color
23
+ sig { returns(Integer) }
24
+ attr_reader :num
25
+
26
+ sig { params(ground: Symbol, num: Integer).void }
27
+ def initialize(ground, num); end
28
+
29
+ sig { returns(T::Array[Integer]) }
30
+ def codes; end
31
+ end
32
+
33
+ class Named < Rainbow::Color::Indexed
34
+ NAMES = T.let(nil, T::Hash[Symbol, Integer])
35
+
36
+ sig { params(ground: Symbol, name: Symbol).void }
37
+ def initialize(ground, name); end
38
+
39
+ sig { returns(T::Array[Symbol]) }
40
+ def self.color_names; end
41
+
42
+ sig { returns(String) }
43
+ def self.valid_names; end
44
+ end
45
+
46
+ class RGB < Rainbow::Color::Indexed
47
+ sig { returns(Integer) }
48
+ attr_reader :r, :g, :b
49
+
50
+ sig { params(ground: Symbol, values: Integer).void }
51
+ def initialize(ground, *values); end
52
+
53
+ sig { returns(T::Array[Integer]) }
54
+ def codes; end
55
+
56
+ sig { params(value: Numeric).returns(Integer) }
57
+ def self.to_ansi_domain(value); end
58
+ end
59
+
60
+ class X11Named < Rainbow::Color::RGB
61
+ include Rainbow::X11ColorNames
62
+
63
+ sig { returns(T::Array[Symbol]) }
64
+ def self.color_names; end
65
+
66
+ sig { returns(String) }
67
+ def self.valid_names; end
68
+
69
+ sig { params(ground: Symbol, name: Symbol).void }
70
+ def initialize(ground, name); end
71
+ end
72
+ end
73
+
74
+ sig { returns(Wrapper) }
75
+ def self.global; end
76
+
77
+ sig { returns(T::Boolean) }
78
+ def self.enabled; end
79
+
80
+ sig { params(value: T::Boolean).returns(T::Boolean) }
81
+ def self.enabled=(value); end
82
+
83
+ sig { params(string: String).returns(String) }
84
+ def self.uncolor(string); end
85
+
86
+ class NullPresenter < String
87
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
88
+ def color(*values); end
89
+
90
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
91
+ def foreground(*values); end
92
+
93
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
94
+ def fg(*values); end
95
+
96
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
97
+ def background(*values); end
98
+
99
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
100
+ def bg(*values); end
101
+
102
+ sig { returns(NullPresenter) }
103
+ def reset; end
104
+
105
+ sig { returns(NullPresenter) }
106
+ def bright; end
107
+
108
+ sig { returns(NullPresenter) }
109
+ def faint; end
110
+
111
+ sig { returns(NullPresenter) }
112
+ def italic; end
113
+
114
+ sig { returns(NullPresenter) }
115
+ def underline; end
116
+
117
+ sig { returns(NullPresenter) }
118
+ def blink; end
119
+
120
+ sig { returns(NullPresenter) }
121
+ def inverse; end
122
+
123
+ sig { returns(NullPresenter) }
124
+ def hide; end
125
+
126
+ sig { returns(NullPresenter) }
127
+ def cross_out; end
128
+
129
+ sig { returns(NullPresenter) }
130
+ def black; end
131
+
132
+ sig { returns(NullPresenter) }
133
+ def red; end
134
+
135
+ sig { returns(NullPresenter) }
136
+ def green; end
137
+
138
+ sig { returns(NullPresenter) }
139
+ def yellow; end
140
+
141
+ sig { returns(NullPresenter) }
142
+ def blue; end
143
+
144
+ sig { returns(NullPresenter) }
145
+ def magenta; end
146
+
147
+ sig { returns(NullPresenter) }
148
+ def cyan; end
149
+
150
+ sig { returns(NullPresenter) }
151
+ def white; end
152
+
153
+ sig { returns(NullPresenter) }
154
+ def bold; end
155
+
156
+ sig { returns(NullPresenter) }
157
+ def dark; end
158
+
159
+ sig { returns(NullPresenter) }
160
+ def strike; end
161
+ end
162
+
163
+ class Presenter < String
164
+ TERM_EFFECTS = T.let(nil, T::Hash[Symbol, Integer])
165
+
166
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
167
+ def color(*values); end
168
+
169
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
170
+ def foreground(*values); end
171
+
172
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
173
+ def fg(*values); end
174
+
175
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
176
+ def background(*values); end
177
+
178
+ sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
179
+ def bg(*values); end
180
+
181
+ sig { returns(Presenter) }
182
+ def reset; end
183
+
184
+ sig { returns(Presenter) }
185
+ def bright; end
186
+
187
+ sig { returns(Presenter) }
188
+ def faint; end
189
+
190
+ sig { returns(Presenter) }
191
+ def italic; end
192
+
193
+ sig { returns(Presenter) }
194
+ def underline; end
195
+
196
+ sig { returns(Presenter) }
197
+ def blink; end
198
+
199
+ sig { returns(Presenter) }
200
+ def inverse; end
201
+
202
+ sig { returns(Presenter) }
203
+ def hide; end
204
+
205
+ sig { returns(Presenter) }
206
+ def cross_out; end
207
+
208
+ sig { returns(Presenter) }
209
+ def black; end
210
+
211
+ sig { returns(Presenter) }
212
+ def red; end
213
+
214
+ sig { returns(Presenter) }
215
+ def green; end
216
+
217
+ sig { returns(Presenter) }
218
+ def yellow; end
219
+
220
+ sig { returns(Presenter) }
221
+ def blue; end
222
+
223
+ sig { returns(Presenter) }
224
+ def magenta; end
225
+
226
+ sig { returns(Presenter) }
227
+ def cyan; end
228
+
229
+ sig { returns(Presenter) }
230
+ def white; end
231
+
232
+ sig { returns(Presenter) }
233
+ def bold; end
234
+
235
+ sig { returns(Presenter) }
236
+ def dark; end
237
+
238
+ sig { returns(Presenter) }
239
+ def strike; end
240
+ end
241
+
242
+ class StringUtils
243
+ sig { params(string: String, codes: T::Array[Integer]).returns(String) }
244
+ def self.wrap_with_sgr(string, codes); end
245
+
246
+ sig { params(string: String).returns(String) }
247
+ def self.uncolor(string); end
248
+ end
249
+
250
+ VERSION = T.let(nil, String)
251
+
252
+ class Wrapper
253
+ sig { returns(T::Boolean) }
254
+ attr_accessor :enabled
255
+
256
+ sig { params(enabled: T::Boolean).void }
257
+ def initialize(enabled = true); end
258
+
259
+ sig { params(string: String).returns(T.any(Rainbow::Presenter, Rainbow::NullPresenter)) }
260
+ def wrap(string); end
261
+ end
262
+
263
+ module X11ColorNames
264
+ NAMES = T.let(nil, T::Hash[Symbol, [Integer, Integer, Integer]])
265
+ end
266
+ end
267
+
268
+ sig { params(string: String).returns(Rainbow::Presenter) }
269
+ def Rainbow(string); end