Skip to content

Commit f2fcee5

Browse files
authored
feat: add sorbet type checker (#83)
1 parent 6a343e9 commit f2fcee5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+29339
-63
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ jobs:
2525
bundler-cache: true
2626

2727
- run: bundle exec rake rubocop
28+
if: ${{ matrix.ruby == '2.5' }}
29+
30+
- run: bundle exec srb tc
31+
if: ${{ matrix.ruby == '2.5' }}
2832

2933
- run: bundle exec rake test
3034
env:

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ AllCops:
22
DisabledByDefault: false
33
NewCops: enable
44
TargetRubyVersion: 2.5
5+
Exclude:
6+
- sorbet/**/*.rbi
7+
- vendor/bundle/**/*
58

69
Layout/LineLength:
710
Enabled: false

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ group :dev do
99
gem 'pry'
1010
gem 'pry-doc'
1111
gem 'rubocop', require: false
12+
gem 'sorbet'
1213
end
1314

1415
group :test do

lib/stream-chat.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
# frozen_string_literal: true # rubocop:todo Naming/FileName
1+
# typed: strict # rubocop:todo Naming/FileName
2+
# frozen_string_literal: true
23

34
require 'stream-chat/client'

lib/stream-chat/channel.rb

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,86 @@
1+
# typed: strict
12
# frozen_string_literal: true
23

4+
require 'stream-chat/client'
35
require 'stream-chat/errors'
46
require 'stream-chat/util'
7+
require 'stream-chat/types'
58

69
module StreamChat
7-
class Channel # rubocop:todo Metrics/ClassLength # rubocop:todo Style/Documentation
10+
class Channel
11+
extend T::Sig
12+
T::Configuration.default_checked_level = :never
13+
# For now we disable runtime type checks.
14+
# We will enable it with a major bump in the future,
15+
# but for now, let's just run a static type check.
16+
17+
sig { returns(T.nilable(String)) }
818
attr_reader :id
19+
20+
sig { returns(String) }
921
attr_reader :channel_type
22+
23+
sig { returns(StringKeyHash) }
1024
attr_reader :custom_data
25+
26+
sig { returns(T::Array[StringKeyHash]) }
1127
attr_reader :members
1228

29+
sig { params(client: StreamChat::Client, channel_type: String, channel_id: T.nilable(String), custom_data: T.nilable(StringKeyHash)).void }
1330
def initialize(client, channel_type, channel_id = nil, custom_data = nil)
1431
@channel_type = channel_type
1532
@id = channel_id
16-
@cid = "#{@channel_type}:#{@id}"
33+
@cid = T.let("#{@channel_type}:#{@id}", String)
1734
@client = client
18-
@custom_data = custom_data
19-
@custom_data = {} if @custom_data.nil?
35+
@custom_data = T.let(custom_data || {}, StringKeyHash)
36+
@members = T.let([], T::Array[StringKeyHash])
2037
end
2138

39+
sig { returns(String) }
2240
def url
2341
raise StreamChannelException, 'channel does not have an id' if @id.nil?
2442

2543
"channels/#{@channel_type}/#{@id}"
2644
end
2745

46+
sig { params(message_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
2847
def get_messages(message_ids)
2948
@client.get("#{url}/messages", params: { 'ids' => message_ids.join(',') })
3049
end
3150

51+
sig { params(message: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
3252
def send_message(message, user_id)
3353
payload = { message: add_user_id(message, user_id) }
3454
@client.post("#{url}/message", data: payload)
3555
end
3656

57+
sig { params(event: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
3758
def send_event(event, user_id)
3859
payload = { 'event' => add_user_id(event, user_id) }
3960
@client.post("#{url}/event", data: payload)
4061
end
4162

63+
sig { params(message_id: String, reaction: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
4264
def send_reaction(message_id, reaction, user_id)
4365
payload = { reaction: add_user_id(reaction, user_id) }
4466
@client.post("messages/#{message_id}/reaction", data: payload)
4567
end
4668

69+
sig { params(message_id: String, reaction_type: String, user_id: String).returns(StreamChat::StreamResponse) }
4770
def delete_reaction(message_id, reaction_type, user_id)
4871
@client.delete(
4972
"messages/#{message_id}/reaction/#{reaction_type}",
5073
params: { user_id: user_id }
5174
)
5275
end
5376

77+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
5478
def create(user_id)
5579
@custom_data['created_by'] = { id: user_id }
5680
query(watch: false, state: false, presence: false)
5781
end
5882

83+
sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
5984
def query(**options)
6085
payload = { state: true, data: @custom_data }.merge(options)
6186
url = "channels/#{@channel_type}"
@@ -66,137 +91,164 @@ def query(**options)
6691
state
6792
end
6893

94+
sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
6995
def query_members(filter_conditions = {}, sort: nil, **options)
7096
params = {}.merge(options).merge({
7197
id: @id,
7298
type: @channel_type,
7399
filter_conditions: filter_conditions,
74-
sort: get_sort_fields(sort)
100+
sort: StreamChat.get_sort_fields(sort)
75101
})
76102

77103
if @id == '' && @members.length.positive?
78104
params['members'] = []
79-
@members&.each do |m|
105+
@members.each do |m|
80106
params['members'] << m['user'].nil? ? m['user_id'] : m['user']['id']
81107
end
82108
end
83109

84110
@client.get('members', params: { payload: params.to_json })
85111
end
86112

113+
sig { params(channel_data: T.nilable(StringKeyHash), update_message: T.nilable(StringKeyHash), options: T.untyped).returns(StreamChat::StreamResponse) }
87114
def update(channel_data, update_message = nil, **options)
88115
payload = { data: channel_data, message: update_message }.merge(options)
89116
@client.post(url, data: payload)
90117
end
91118

119+
sig { params(set: T.nilable(StringKeyHash), unset: T.nilable(T::Array[String])).returns(StreamChat::StreamResponse) }
92120
def update_partial(set = nil, unset = nil)
93121
raise StreamChannelException, 'set or unset is needed' if set.nil? && unset.nil?
94122

95123
payload = { set: set, unset: unset }
96124
@client.patch(url, data: payload)
97125
end
98126

127+
sig { returns(StreamChat::StreamResponse) }
99128
def delete
100129
@client.delete(url)
101130
end
102131

132+
sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
103133
def truncate(**options)
104134
@client.post("#{url}/truncate", data: options)
105135
end
106136

137+
sig { params(user_id: String, expiration: T.nilable(Integer)).returns(StreamChat::StreamResponse) }
107138
def mute(user_id, expiration = nil)
108139
data = { user_id: user_id, channel_cid: @cid }
109140
data['expiration'] = expiration if expiration
110141
@client.post('moderation/mute/channel', data: data)
111142
end
112143

144+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
113145
def unmute(user_id)
114146
@client.post('moderation/unmute/channel', data: { 'user_id' => user_id, 'channel_cid' => @cid })
115147
end
116148

149+
sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
117150
def add_members(user_ids, **options)
118151
payload = options.merge({ add_members: user_ids })
119152
update(nil, nil, **payload)
120153
end
121154

155+
sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
122156
def invite_members(user_ids, **options)
123157
payload = options.merge({ invites: user_ids })
124158
update(nil, nil, **payload)
125159
end
126160

161+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
127162
def accept_invite(user_id, **options)
128163
payload = options.merge({ user_id: user_id, accept_invite: true })
129164
update(nil, nil, **payload)
130165
end
131166

167+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
132168
def reject_invite(user_id, **options)
133169
payload = options.merge({ user_id: user_id, reject_invite: true })
134170
update(nil, nil, **payload)
135171
end
136172

173+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
137174
def add_moderators(user_ids)
138175
update(nil, nil, add_moderators: user_ids)
139176
end
140177

178+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
141179
def remove_members(user_ids)
142180
update(nil, nil, remove_members: user_ids)
143181
end
144182

183+
sig { params(members: T::Array[StringKeyHash], message: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
145184
def assign_roles(members, message = nil)
146185
update(nil, message, assign_roles: members)
147186
end
148187

188+
sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
149189
def demote_moderators(user_ids)
150190
update(nil, nil, demote_moderators: user_ids)
151191
end
152192

193+
sig { params(user_id: String, options: StringKeyHash).returns(StreamChat::StreamResponse) }
153194
def mark_read(user_id, **options)
154195
payload = add_user_id(options, user_id)
155196
@client.post("#{url}/read", data: payload)
156197
end
157198

199+
sig { params(parent_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
158200
def get_replies(parent_id, **options)
159201
@client.get("messages/#{parent_id}/replies", params: options)
160202
end
161203

204+
sig { params(message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
162205
def get_reactions(message_id, **options)
163206
@client.get("messages/#{message_id}/reactions", params: options)
164207
end
165208

209+
sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
166210
def ban_user(user_id, **options)
167211
@client.ban_user(user_id, type: @channel_type, id: @id, **options)
168212
end
169213

214+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
170215
def unban_user(user_id)
171216
@client.unban_user(user_id, type: @channel_type, id: @id)
172217
end
173218

219+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
174220
def hide(user_id)
175221
@client.post("#{url}/hide", data: { user_id: user_id })
176222
end
177223

224+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
178225
def show(user_id)
179226
@client.post("#{url}/show", data: { user_id: user_id })
180227
end
181228

229+
sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
182230
def send_file(url, user, content_type = nil)
183231
@client.send_file("#{self.url}/file", url, user, content_type)
184232
end
185233

234+
sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
186235
def send_image(url, user, content_type = nil)
187236
@client.send_file("#{self.url}/image", url, user, content_type)
188237
end
189238

239+
sig { params(url: String).returns(StreamChat::StreamResponse) }
190240
def delete_file(url)
191241
@client.delete("#{self.url}/file", params: { url: url })
192242
end
193243

244+
sig { params(url: String).returns(StreamChat::StreamResponse) }
194245
def delete_image(url)
195246
@client.delete("#{self.url}/image", params: { url: url })
196247
end
197248

198249
private
199250

251+
sig { params(payload: StringKeyHash, user_id: String).returns(StringKeyHash) }
200252
def add_user_id(payload, user_id)
201253
payload.merge({ user: { id: user_id } })
202254
end

0 commit comments

Comments
 (0)