├── .github
├── CODEOWNERS
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── ci.yml
│ ├── initiate_release.yml
│ ├── release.yml
│ ├── reviewdog.yml
│ └── scheduled_test.yml
├── .gitignore
├── .rubocop.yml
├── .versionrc.js
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── Rakefile
├── SECURITY.md
├── assets
└── logo.svg
├── lib
├── stream-chat.rb
└── stream-chat
│ ├── channel.rb
│ ├── client.rb
│ ├── errors.rb
│ ├── moderation.rb
│ ├── stream_rate_limits.rb
│ ├── stream_response.rb
│ ├── types.rb
│ ├── util.rb
│ └── version.rb
├── scripts
└── get_changelog_diff.js
├── sorbet
├── config
└── rbi
│ ├── gems
│ ├── coderay.rbi
│ ├── connection_pool.rbi
│ ├── docile.rbi
│ ├── faraday-em_http.rbi
│ ├── faraday-em_synchrony.rbi
│ ├── faraday-excon.rbi
│ ├── faraday-httpclient.rbi
│ ├── faraday-multipart.rbi
│ ├── faraday-net_http.rbi
│ ├── faraday-net_http_persistent.rbi
│ ├── faraday-patron.rbi
│ ├── faraday-rack.rbi
│ ├── faraday.rbi
│ ├── jwt.rbi
│ ├── method_source.rbi
│ ├── multipart-post.rbi
│ ├── net-http-persistent.rbi
│ ├── pry-doc.rbi
│ ├── pry.rbi
│ ├── rack.rbi
│ ├── rake.rbi
│ ├── rspec-core.rbi
│ ├── rspec-expectations.rbi
│ ├── rspec-mocks.rbi
│ ├── rspec-support.rbi
│ ├── rspec.rbi
│ ├── simplecov-html.rbi
│ ├── simplecov.rbi
│ ├── simplecov_json_formatter.rbi
│ └── yard.rbi
│ ├── hidden-definitions
│ ├── errors.txt
│ └── hidden.rbi
│ ├── sorbet-typed
│ └── lib
│ │ ├── faraday
│ │ └── all
│ │ │ └── faraday.rbi
│ │ ├── rainbow
│ │ └── all
│ │ │ └── rainbow.rbi
│ │ ├── rake
│ │ └── all
│ │ │ └── rake.rbi
│ │ ├── rspec-core
│ │ └── all
│ │ │ └── rspec-core.rbi
│ │ ├── rubocop
│ │ └── >=1.8
│ │ │ └── rubocop.rbi
│ │ └── yard
│ │ └── all
│ │ └── yard.rbi
│ └── todo.rbi
├── spec
├── channel_spec.rb
├── client_spec.rb
├── data
│ ├── helloworld.jpg
│ └── helloworld.txt
├── moderation_spec.rb
└── spec_helper.rb
└── stream-chat.gemspec
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @totalimmersion @akupila @guerinoni @JimmyPettersson85 @shaljam @vishalnarkhede @nijeesh-stream
2 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Submit a pull request
2 |
3 | ## CLA
4 |
5 | - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required).
6 | - [ ] The code changes follow best practices
7 | - [ ] Code changes are tested (add some information if not applicable)
8 |
9 | ## Description of the pull request
10 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: test
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | max-parallel: 1
10 | matrix:
11 | ruby: ["3.0", "3.1", "3.4"]
12 | name: 💎 Ruby ${{ matrix.ruby }}
13 | steps:
14 | - uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0 # gives the commit linter access to previous commits
17 |
18 | - uses: ruby/setup-ruby@v1
19 | with:
20 | ruby-version: ${{ matrix.ruby }}
21 | bundler-cache: true
22 |
23 | - run: bundle exec rake rubocop
24 | if: ${{ matrix.ruby == '3.4' }}
25 |
26 | - run: bundle exec srb tc
27 | if: ${{ matrix.ruby == '3.4' }}
28 |
29 | - run: bundle exec rspec ./spec --require spec_helper
30 | env:
31 | STREAM_KEY: ${{ secrets.STREAM_CHAT_API_KEY }}
32 | STREAM_SECRET: ${{ secrets.STREAM_CHAT_API_SECRET }}
33 |
--------------------------------------------------------------------------------
/.github/workflows/initiate_release.yml:
--------------------------------------------------------------------------------
1 | name: Create release PR
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | version:
7 | description: "The new version number with 'v' prefix. Example: v1.40.1"
8 | required: true
9 |
10 | jobs:
11 | init_release:
12 | name: 🚀 Create release PR
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0 # gives the changelog generator access to all previous commits
18 |
19 | - name: Update CHANGELOG.md, version.rb and push release branch
20 | env:
21 | VERSION: ${{ github.event.inputs.version }}
22 | run: |
23 | npx --yes standard-version@9.3.2 --release-as "$VERSION" --skip.tag --skip.commit --tag-prefix=v
24 | git config --global user.name 'github-actions'
25 | git config --global user.email 'release@getstream.io'
26 | git checkout -q -b "release-$VERSION"
27 | git commit -am "chore(release): $VERSION"
28 | git push -q -u origin "release-$VERSION"
29 |
30 | - name: Get changelog diff
31 | uses: actions/github-script@v6
32 | with:
33 | script: |
34 | const get_change_log_diff = require('./scripts/get_changelog_diff.js')
35 | core.exportVariable('CHANGELOG', get_change_log_diff())
36 |
37 | - name: Open pull request
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | run: |
41 | gh pr create \
42 | -t "Release ${{ github.event.inputs.version }}" \
43 | -b "# :rocket: ${{ github.event.inputs.version }}
44 | Make sure to use squash & merge when merging!
45 | Once this is merged, another job will kick off automatically and publish the package.
46 | # :memo: Changelog
47 | ${{ env.CHANGELOG }}"
48 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | pull_request:
5 | types: [closed]
6 | branches:
7 | - master
8 |
9 | jobs:
10 | Release:
11 | name: 🚀 Release
12 | if: github.event.pull_request.merged && startsWith(github.head_ref, 'release-')
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 |
19 | - uses: actions/github-script@v6
20 | with:
21 | script: |
22 | const get_change_log_diff = require('./scripts/get_changelog_diff.js')
23 | core.exportVariable('CHANGELOG', get_change_log_diff())
24 |
25 | // Getting the release version from the PR source branch
26 | // Source branch looks like this: release-1.0.0
27 | const version = context.payload.pull_request.head.ref.split('-')[1]
28 | core.exportVariable('VERSION', version)
29 |
30 | - name: Publish gem
31 | uses: dawidd6/action-publish-gem@v1
32 | with:
33 | api_key: ${{secrets.RUBYGEMS_API_KEY}}
34 |
35 | - name: Create release on GitHub
36 | uses: ncipollo/release-action@v1
37 | with:
38 | body: ${{ env.CHANGELOG }}
39 | tag: ${{ env.VERSION }}
40 | token: ${{ secrets.GITHUB_TOKEN }}
41 |
--------------------------------------------------------------------------------
/.github/workflows/reviewdog.yml:
--------------------------------------------------------------------------------
1 | name: reviewdog
2 |
3 | on: [pull_request]
4 |
5 | concurrency:
6 | group: ${{ github.workflow }}-${{ github.head_ref }}
7 | cancel-in-progress: true
8 |
9 | jobs:
10 | rubocop:
11 | name: 🐶 Reviewdog
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Check out code
15 | uses: actions/checkout@v4
16 |
17 | - uses: ruby/setup-ruby@v1
18 | with:
19 | ruby-version: 3
20 |
21 | - name: rubocop
22 | uses: reviewdog/action-rubocop@v2
23 | with:
24 | rubocop_version: gemfile
25 | reporter: github-pr-review
26 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled_test.yml:
--------------------------------------------------------------------------------
1 | name: Scheduled tests
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | # Monday at 9:00 UTC
7 | - cron: '0 9 * * 1'
8 |
9 | jobs:
10 | test:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 |
15 | - uses: ruby/setup-ruby@v1
16 | with:
17 | ruby-version: '3.1'
18 | bundler-cache: true
19 |
20 | - name: Test
21 | env:
22 | STREAM_KEY: ${{ secrets.STREAM_CHAT_API_KEY }}
23 | STREAM_SECRET: ${{ secrets.STREAM_CHAT_API_SECRET }}
24 | run: |
25 | # Retry 3 times because tests can be flaky
26 | for _ in 1 2 3;
27 | do
28 | bundle exec rspec ./spec --require spec_helper && break
29 | done
30 |
31 | - name: Notify Slack if failed
32 | uses: voxmedia/github-action-slack-notify-build@v1
33 | if: failure()
34 | with:
35 | channel_id: C02RPDF7T63
36 | color: danger
37 | status: FAILED
38 | env:
39 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }}
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | /.config
4 | /coverage/
5 | /InstalledFiles
6 | /pkg/
7 | /spec/reports/
8 | /spec/examples.txt
9 | /test/tmp/
10 | /test/version_tmp/
11 | /tmp/
12 | .vscode
13 | .idea
14 | .DS_Store
15 |
16 | # Used by dotenv library to load environment variables.
17 | # .env
18 |
19 | ## Specific to RubyMotion:
20 | .dat*
21 | .repl_history
22 | build/
23 | *.bridgesupport
24 | build-iPhoneOS/
25 | build-iPhoneSimulator/
26 |
27 | ## Specific to RubyMotion (use of CocoaPods):
28 | #
29 | # We recommend against adding the Pods directory to your .gitignore. However
30 | # you should judge for yourself, the pros and cons are mentioned at:
31 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32 | #
33 | # vendor/Pods/
34 |
35 | ## Documentation cache and generated files:
36 | /.yardoc/
37 | /_yardoc/
38 | /doc/
39 | /rdoc/
40 |
41 | ## Environment normalization:
42 | /.bundle/
43 | /vendor/bundle
44 | /lib/bundler/man/
45 |
46 | # for a library or gem, you might want to ignore these files since the code is
47 | # intended to run in multiple environments; otherwise, check them in:
48 | # See https://github.com/rubygems/rubygems/issues/3372 for more info
49 | Gemfile.lock
50 | .ruby-version
51 | # .ruby-gemset
52 |
53 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
54 | .rvmrc
55 | .envrc
56 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | AllCops:
2 | DisabledByDefault: false
3 | NewCops: enable
4 | TargetRubyVersion: 3.0
5 | Exclude:
6 | - sorbet/**/*.rbi
7 | - vendor/bundle/**/*
8 |
9 | Layout/LineLength:
10 | Enabled: false
11 |
12 | Lint/RedundantCopDisableDirective:
13 | Enabled: false
14 |
15 | Metrics/AbcSize:
16 | Enabled: false
17 | Metrics/BlockLength:
18 | Enabled: false
19 | Metrics/ClassLength:
20 | Enabled: false
21 | Metrics/MethodLength:
22 | Enabled: false
23 |
24 | Naming/AccessorMethodName:
25 | Enabled: false
26 |
27 | Style/AccessorGrouping:
28 | Enabled: false
29 | Style/Documentation:
30 | Enabled: false
31 | Style/DoubleCopDisableDirective:
32 | Enabled: false
33 | Style/FrozenStringLiteralComment:
34 | Enabled: false
35 |
36 | Gemspec/RequireMFA:
37 | Enabled: false
38 | Naming/PredicateMethod:
39 | Enabled: false
40 |
--------------------------------------------------------------------------------
/.versionrc.js:
--------------------------------------------------------------------------------
1 | const versionFileUpdater = {
2 | VERSION_REGEX: /VERSION = '(.+)'/,
3 |
4 | readVersion: function (contents) {
5 | const version = this.VERSION_REGEX.exec(contents)[1];
6 | return version;
7 | },
8 |
9 | writeVersion: function (contents, version) {
10 | return contents.replace(this.VERSION_REGEX.exec(contents)[0], `VERSION = '${version}'`);
11 | }
12 | }
13 |
14 | module.exports = {
15 | bumpFiles: [{ filename: './lib/stream-chat/version.rb', updater: versionFileUpdater }],
16 | types: [
17 | {"type": "feat", "section": "Features"},
18 | {"type": "fix", "section": "Bug Fixes"},
19 | {"type": "chore", "section": "Other", "hidden": false},
20 | {"type": "docs", "section": "Other", "hidden": false},
21 | {"type": "style", "section": "Other", "hidden": false},
22 | {"type": "refactor", "section": "Other", "hidden": false},
23 | {"type": "perf", "section": "Other", "hidden": false},
24 | {"type": "test", "section": "Other", "hidden": false}
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ## [3.15.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.14.0...v3.15.0) (2025-06-06)
6 |
7 | ## [3.14.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.13.0...v3.14.0) (2025-04-07)
8 |
9 | ## [3.13.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.12.0...v3.13.0) (2025-04-04)
10 |
11 |
12 | ### Features
13 |
14 | * deactivate users ([#162](https://github.com/GetStream/stream-chat-ruby/issues/162)) ([12bf4d1](https://github.com/GetStream/stream-chat-ruby/commit/12bf4d19846b5100f1886929b74c7ad05d753be4))
15 | * draft messages ([#161](https://github.com/GetStream/stream-chat-ruby/pull/161)) ([1719104](https://github.com/GetStream/stream-chat-ruby/commit/c7bccb3ad30721a20f32fd60eb13ab6d97a08208))
16 |
17 | ### Other
18 |
19 | * added nijeesh to code owners ([#156](https://github.com/GetStream/stream-chat-ruby/issues/156)) ([7cd4e54](https://github.com/GetStream/stream-chat-ruby/commit/7cd4e5443a8f283596b8eadc873030d737cd621c))
20 | * **release:** v3.12.0 ([#157](https://github.com/GetStream/stream-chat-ruby/issues/157)) ([993b7a3](https://github.com/GetStream/stream-chat-ruby/commit/993b7a30bd2222ee328ca7a862384c7baf7d53e1))
21 |
22 | ## [3.11.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.9.0...v3.11.0) (2025-03-21)
23 |
24 |
25 | ### Other
26 |
27 | * **release:** 3.10.0 ([#151](https://github.com/GetStream/stream-chat-ruby/issues/151)) ([ac11fc1](https://github.com/GetStream/stream-chat-ruby/commit/ac11fc122ec97ffd1b2bce820efe55925e96277f))
28 |
29 | ## [3.10.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.9.0...v3.10.0) (2025-02-24)
30 |
31 | ## [3.9.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.7.0...v3.9.0) (2025-02-11)
32 |
33 |
34 | ### Other
35 |
36 | * added tests using the restricted visibility feature ([#144](https://github.com/GetStream/stream-chat-ruby/issues/144)) ([b13cc92](https://github.com/GetStream/stream-chat-ruby/commit/b13cc92cd91aeb1f6e1a25f5c6d22efb41339f49))
37 | * **release:** 3.8.0 ([#146](https://github.com/GetStream/stream-chat-ruby/issues/146)) ([e2e7673](https://github.com/GetStream/stream-chat-ruby/commit/e2e7673f6b93a248e870f060e719c6ef16886129))
38 |
39 | ## [3.8.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.7.0...v3.8.0) (2025-02-11)
40 |
41 |
42 | ### Other
43 |
44 | * added tests using the restricted visibility feature ([#144](https://github.com/GetStream/stream-chat-ruby/issues/144)) ([b13cc92](https://github.com/GetStream/stream-chat-ruby/commit/b13cc92cd91aeb1f6e1a25f5c6d22efb41339f49))
45 |
46 | ## [3.7.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.6.0...v3.7.0) (2024-12-09)
47 |
48 | ## [3.6.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.5.1...v3.6.0) (2024-05-22)
49 |
50 |
51 | ### Features
52 |
53 | * add test for `notifications_muted` as filter in `query_members` ([#140](https://github.com/GetStream/stream-chat-ruby/issues/140)) ([61102ac](https://github.com/GetStream/stream-chat-ruby/commit/61102ac16783ecfc502d8f7d21435ec64af28436))
54 |
55 | ### [3.5.1](https://github.com/GetStream/stream-chat-ruby/compare/v3.5.0...v3.5.1) (2024-04-18)
56 |
57 | ## [3.5.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.4.0...v3.5.0) (2023-10-30)
58 |
59 |
60 | ### Features
61 |
62 | * add check sns point ([#134](https://github.com/GetStream/stream-chat-ruby/issues/134)) ([532ae7e](https://github.com/GetStream/stream-chat-ruby/commit/532ae7e9f2e0879f679dc3cd2c5afb27987d4e88))
63 |
64 | ## [3.4.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.3.0...v3.4.0) (2023-07-19)
65 |
66 |
67 | ### Features
68 |
69 | * commit message endpoint ([#129](https://github.com/GetStream/stream-chat-ruby/issues/129)) ([09eabb3](https://github.com/GetStream/stream-chat-ruby/commit/09eabb33f4bcfa6f8881dc545060bc5bdd51374e))
70 |
71 |
72 | ### Bug Fixes
73 |
74 | * sorbet type for mark_read function signature ([#130](https://github.com/GetStream/stream-chat-ruby/issues/130)) ([7ea0f51](https://github.com/GetStream/stream-chat-ruby/commit/7ea0f517592c1819e223a65eedb53caa85a92817))
75 |
76 | ## [3.3.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.2.0...v3.3.0) (2022-11-17)
77 |
78 |
79 | ### Features
80 |
81 | * add campaign support ([#124](https://github.com/GetStream/stream-chat-ruby/issues/124)) ([d7a935f](https://github.com/GetStream/stream-chat-ruby/commit/d7a935f7b4459399b82db1d51a541388caeb5e68))
82 |
83 | ## [3.2.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.1.0...v3.2.0) (2022-11-17)
84 |
85 |
86 | ### Features
87 |
88 | * **send_message:** add options argument ([#107](https://github.com/GetStream/stream-chat-ruby/issues/107)) ([8e5bf89](https://github.com/GetStream/stream-chat-ruby/commit/8e5bf8977f899d3e5a259efd38d7bcf3962cd999))
89 |
90 |
91 | ### Bug Fixes
92 |
93 | * do not ship lock ([#118](https://github.com/GetStream/stream-chat-ruby/issues/118)) ([4cd4f25](https://github.com/GetStream/stream-chat-ruby/commit/4cd4f251a575ec8b010543d0277914463028cf2b))
94 | * relax dependency versions ([#116](https://github.com/GetStream/stream-chat-ruby/issues/116)) ([2b87af6](https://github.com/GetStream/stream-chat-ruby/commit/2b87af624856c403ffaf8c9b69982832f169df70))
95 |
96 |
97 | ### Other
98 |
99 | * add ignored sections into changelog ([#120](https://github.com/GetStream/stream-chat-ruby/issues/120)) ([191ea82](https://github.com/GetStream/stream-chat-ruby/commit/191ea825c4ad68473568da6c801819d6a8fec827))
100 | * **deps-dev:** bump rack from 2.2.3 to 2.2.4 ([#110](https://github.com/GetStream/stream-chat-ruby/issues/110)) ([2ab646b](https://github.com/GetStream/stream-chat-ruby/commit/2ab646b4f6cdcb016203075a94a77437739b69d0))
101 | * drop old rubies ([#122](https://github.com/GetStream/stream-chat-ruby/issues/122)) ([77ddb1f](https://github.com/GetStream/stream-chat-ruby/commit/77ddb1f4917611a6579c177dd617358bdbde6bbc))
102 | * move pr template into github ([#119](https://github.com/GetStream/stream-chat-ruby/issues/119)) ([99cd178](https://github.com/GetStream/stream-chat-ruby/commit/99cd178571cfdf6b6828ef60f4eca57890f14e18))
103 |
104 | ## [3.1.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.0.0...v3.1.0) (2022-08-26)
105 |
106 |
107 | ### Chore
108 |
109 | * chore: pin dependencies versions ([#109](https://github.com/GetStream/stream-chat-ruby/pull/109)) ([66dc80b](https://github.com/GetStream/stream-chat-ruby/commit/66dc80bb3f5e3698450517e94238e28fa7bd9d9c))
110 |
111 | ## [3.0.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.23.0...v3.0.0) (2022-05-24)
112 |
113 |
114 | ### ⚠ BREAKING CHANGES
115 |
116 | * **sorbet:** enable runtime typecheck (#104)
117 |
118 | > In this release we have enabled runtime level typechecking for Sorbet. This means that if you input parameters
119 | are invalid **your code will throw an error during runtime**. Please ensure that your code is properly tested
120 | before continuing with v3.0.0 of this library.
121 |
122 | ### Features
123 |
124 | * **sorbet:** enable runtime typecheck ([#104](https://github.com/GetStream/stream-chat-ruby/issues/104)) ([97d5f29](https://github.com/GetStream/stream-chat-ruby/commit/97d5f299b652e8328af6e76d0d605c59f05a5cc3))
125 |
126 | ## [2.23.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.22.2...v2.23.0) (2022-05-19)
127 |
128 |
129 | ### Features
130 |
131 | * **campaign:** add campaign endpoints ([c8c698b](https://github.com/GetStream/stream-chat-ruby/commit/c8c698b51ee2c9f54819c2b9407a3fff7808efd5))
132 | * **import:** add import endpoints ([#102](https://github.com/GetStream/stream-chat-ruby/issues/102)) ([4d7358d](https://github.com/GetStream/stream-chat-ruby/commit/4d7358d39615c5346f9fdcb2b0dfbffa3c2ae79c))
133 |
134 | ### [2.22.2](https://github.com/GetStream/stream-chat-ruby/compare/v2.22.1...v2.22.2) (2022-04-21)
135 |
136 |
137 | ### Bug Fixes
138 |
139 | * **sorbet:** turn off runtime checks properly ([#98](https://github.com/GetStream/stream-chat-ruby/issues/98)) ([29e9e73](https://github.com/GetStream/stream-chat-ruby/commit/29e9e73ac07d163e8c1ca7b24516cb7ac61e93cd))
140 |
141 | ### [2.22.1](https://github.com/GetStream/stream-chat-ruby/compare/v2.22.0...v2.22.1) (2022-04-20)
142 |
143 | ### Features
144 |
145 | * added comments to public methods ([#93](https://github.com/GetStream/stream-chat-ruby/issues/93)) ([3843fe4](https://github.com/GetStream/stream-chat-ruby/commit/3843fe41ea7716d2b6a787d695bbe54981b2b35e))
146 |
147 | ## [2.22.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.21.0...v2.22.0) (2022-04-01)
148 |
149 |
150 | ### Features
151 |
152 | * add new device field ([#90](https://github.com/GetStream/stream-chat-ruby/issues/90)) ([aa6723c](https://github.com/GetStream/stream-chat-ruby/commit/aa6723cd54e58aab0f1b8c55bc4e54211ab39f3c))
153 | * add new moderation apis ([#88](https://github.com/GetStream/stream-chat-ruby/issues/88)) ([573c586](https://github.com/GetStream/stream-chat-ruby/commit/573c58650392eaa5a6d38b4423e170e30b3e98df))
154 | * add push provider apis ([#89](https://github.com/GetStream/stream-chat-ruby/issues/89)) ([d592fba](https://github.com/GetStream/stream-chat-ruby/commit/d592fba4c0041102fa18d0fee11961f881414337))
155 | * **update_user:** deprecate update in favor of upsert ([#91](https://github.com/GetStream/stream-chat-ruby/issues/91)) ([74d3163](https://github.com/GetStream/stream-chat-ruby/commit/74d316339b277b0f9cf0f94f40f11aae30fd7644))
156 |
157 | ## [2.21.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.20.0...v2.21.0) (2022-03-03)
158 |
159 |
160 | ### Features
161 |
162 | * add options to delete message ([#80](https://github.com/GetStream/stream-chat-ruby/issues/80)) ([6a343e9](https://github.com/GetStream/stream-chat-ruby/commit/6a343e9fa9409150c27afc4246765f07bb12e571))
163 | * add sorbet type checker ([#83](https://github.com/GetStream/stream-chat-ruby/issues/83)) ([f2fcee5](https://github.com/GetStream/stream-chat-ruby/commit/f2fcee58ecc0c3b4016721e997c42c44753bba9a))
164 |
165 |
166 | ### Bug Fixes
167 |
168 | * update app settings ([#86](https://github.com/GetStream/stream-chat-ruby/issues/86)) ([3f88185](https://github.com/GetStream/stream-chat-ruby/commit/3f88185117c5710e0b3e66f7f402f2c8969dec2f))
169 |
170 | ## [2.20.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.19.0...v2.20.0) (2022-02-04)
171 |
172 |
173 | ### Features
174 |
175 | * add helper for invitation acceptance and rejection ([#78](https://github.com/GetStream/stream-chat-ruby/issues/78)) ([c950694](https://github.com/GetStream/stream-chat-ruby/commit/c950694a0ac2b0906d7bedb4ebc9a1af00eea606))
176 |
177 | ## [2.19.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.18.0...v2.19.0) (2022-02-02)
178 |
179 |
180 | ### Features
181 |
182 | * ability to provide custom http client ([#75](https://github.com/GetStream/stream-chat-ruby/issues/75)) ([bfff20d](https://github.com/GetStream/stream-chat-ruby/commit/bfff20d06232c49a1a8d0eee255a718bfffbb351))
183 | * add connection pooling and idle timeout ([#74](https://github.com/GetStream/stream-chat-ruby/issues/74)) ([7891005](https://github.com/GetStream/stream-chat-ruby/commit/78910053b3a15b1efa3183a71299068e63b128e3))
184 | * env var handling enhancement ([#76](https://github.com/GetStream/stream-chat-ruby/issues/76)) ([0cdc38a](https://github.com/GetStream/stream-chat-ruby/commit/0cdc38abd671bfaa8cefa7f403b9e2ac8b642272))
185 | > 🚨 Note: if you used `STREAM_CHAT_URL` env var, you'll need to provide it manually in the `**options` as `base_url`. See the initializer of `Client` class for more information.
186 |
187 | ## [2.18.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.17.2...v2.18.0) (2022-01-26)
188 |
189 |
190 | ### Features
191 |
192 | * expose rate limits ([#72](https://github.com/GetStream/stream-chat-ruby/issues/72)) ([3f1ad5c](https://github.com/GetStream/stream-chat-ruby/commit/3f1ad5c8f43263424e934055d0ac283cdcce9376))
193 | * full feature parity ([#71](https://github.com/GetStream/stream-chat-ruby/issues/71)) ([a25a1b6](https://github.com/GetStream/stream-chat-ruby/commit/a25a1b66f9eadd77d09b99d5c3cfba27bba52f17))
194 |
195 | ### [2.17.2](https://github.com/GetStream/stream-chat-ruby/compare/v2.17.1...v2.17.2) (2022-01-17)
196 |
197 | ### Features
198 | * added some new metadata to the gemspec ([#69](https://github.com/GetStream/stream-chat-ruby/issues/69)) ([3e747bc](https://github.com/GetStream/stream-chat-ruby/commit/3e747bcd6aa338b08e136febfb0cf06f29d366b5))
199 |
200 | ### [2.17.1](https://github.com/GetStream/stream-chat-ruby/compare/v2.17.0...v2.17.1) (2022-01-17)
201 |
202 |
203 | ### Bug Fixes
204 |
205 | * load faraday-mutipart error ([#67](https://github.com/GetStream/stream-chat-ruby/issues/67)) ([55ec107](https://github.com/GetStream/stream-chat-ruby/commit/55ec107fb4d6af887aa562c1e04d90a669c630cb))
206 |
207 | ## [2.17.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.16.0...v2.17.0) (2022-01-14)
208 |
209 |
210 | ### Features
211 |
212 | * add options to add members ([#63](https://github.com/GetStream/stream-chat-ruby/issues/63)) ([89c9fa9](https://github.com/GetStream/stream-chat-ruby/commit/89c9fa98e19565c4b5353077523a1d407e1f10c9))
213 |
214 | ## [2.16.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.15.0...v2.16.0) (2021-12-01)
215 |
216 | - Add permissions v2 APIs by @ffenix113 in #62
217 |
218 | ## [2.15.0](https://github.com/GetStream/stream-chat-ruby/compare/v2.14.0...v2.15.0) (2021-11-25)
219 |
220 | - Add configuration support for channel truncate
221 | - truncated_at: to truncate channel up to given time
222 | - message: a system message to be added via truncation
223 | - skip_push: don't send a push notification for system message
224 | - hard_delete: true if truncation should delete messages instead of hiding
225 |
226 | ## November 24th, 2021 - 2.14.0
227 |
228 | - Add new flags for export channels
229 | - clear_deleted_message_text (default: false)
230 | - include_truncated_messages (default: false)
231 |
232 | ## November 17th, 2021 - 2.13.0
233 |
234 | - Add support for shadow banning user
235 | - shadow_ban
236 | - remove_shadow_ban
237 | - Add support for pinning messages
238 | - pin_message
239 | - unpin_message
240 | - Add support for partial updating messages
241 | - update_message_partial
242 | - Add support for updating channel ownership for Deleted Users
243 |
244 | ## November 1st, 2021 - 2.12.0
245 |
246 | - Add support for async endpoints
247 | - get_task
248 | - delete_channels
249 | - delete_users
250 |
251 | ## October 22nd, 2021 - 2.11.3
252 |
253 | - Don't log the entire response when creating exception
254 | - Access error details through StreamAPIException class attr_readers
255 |
256 | ## October 5th, 2021 - 2.11.2
257 |
258 | - Add Codeowners file
259 | - Fix StreamChannelException raises
260 | - Fix rubocop linting error
261 | - Fix channel export test
262 | - Update Github action
263 |
264 | ## August 23rd, 2021 - 2.11.1
265 |
266 | - Use edge as base url
267 |
268 | ## June 25th, 2021 - 2.11.0
269 |
270 | - Add support for improved search
271 |
272 | ## June 4th, 2021 - 2.10.0
273 |
274 | - Add custom command CRUD support
275 |
276 | ## May 31st, 2021 - 2.9.0
277 |
278 | - Add support for app and user level token revoke
279 |
280 | ## May 21st, 2021 - 2.8.0
281 |
282 | - Add query message flags support
283 |
284 | ## March 17th, 2021 - 2.7.0
285 |
286 | - Add Ruby 3.x support
287 | - Update CI to run all tests for all versions
288 |
289 | ## March 9th, 2021 - 2.6.0
290 |
291 | - Add get_rate_limits endpoint
292 |
293 | ## February 3rd, 2021 - 2.5.0
294 |
295 | - Add channel partial update
296 | - Increase convenience in query members
297 | - Improve internal symbol conversions
298 |
299 | ## January 20th, 2021 - 2.4.0
300 |
301 | - Add query_members to channel
302 | - Use post endpoint for query channels instead of get
303 | - Extract common code for sorting into a helper for query calls
304 |
305 | ## January 5th, 2021 - 2.3.0
306 |
307 | - Add check SQS helper
308 |
309 | ## January 4th, 2021 - 2.2.0
310 |
311 | - Add support for export channels
312 | - Improve readme for blocklist and export channels
313 | - Improve running tests for multiple versions of ruby
314 | - Fix issues from the latest version of rubocop
315 | - Move to GitHub Actions
316 |
317 | ## October 5th, 2020 - 2.1.0
318 |
319 | - Add support for blocklist
320 |
321 | ## October 2nd, 2020 - 2.0.0
322 |
323 | - Drop EOL Ruby versions: 2.3 && 2.4
324 | - Setup Rubocop and mark string literals as frozen
325 |
326 | ## August 3rd, 2020 - 1.1.3
327 |
328 | - Fixed Argument Error on delete_user
329 |
330 | ## April 23th, 2020 - 1.1.2
331 |
332 | - Fixed ArgumentError when no users was passed
333 |
334 | ## March 30th, 2020 - 1.1.1
335 |
336 | - Fixed few minor issues
337 |
338 | ## Oct 27th, 2019 - 1.1.0
339 |
340 | - Mark gems use for testing as development dependencies
341 | - Added `send_file`, `send_image`, `delete_file`, `delete_image`
342 | - Added `invite_members`
343 |
344 | ## Oct 19th, 2019 - 1.0.0
345 |
346 | - Added `channel.hide` and `channel.show`
347 | - Added `client.flag_message` and `client.unflag_message`
348 | - Added `client.flag_user` and `client.unflag_user`
349 | - Added `client.get_message`
350 | - Added `client.search`
351 | - Added `client.update_users_partial`
352 | - Added `client.update_user_partial`
353 | - Added `client.reactivate_user`
354 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 | # :recycle: Contributing
3 |
4 | We welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. See our license file for more details.
5 |
6 | ## Getting started
7 |
8 | ### Install dependencies
9 |
10 | ```shell
11 | $ bundle install --path vendor/bundle
12 | ```
13 |
14 | ### Run tests
15 |
16 | ```shell
17 | $ STREAM_KEY=my_api_key STREAM_SECRET=my_api_secret bundle exec rspec spec
18 | ```
19 |
20 | ### Run specific test
21 |
22 | Add :focus tag on target test:
23 |
24 | ```rb
25 | it 'can mark messages as read', :focus do
26 | # test something
27 | end
28 | ```
29 |
30 | And then run as following:
31 |
32 | ```shell
33 | $ STREAM_KEY=myapi_key STREAM_SECRET=my_secret STREAM_CHAT_URL=http://127.0.0.1:3030 bundle exec rspec spec --tag focus
34 | ```
35 |
36 | ### Linters and type check
37 |
38 | We use [Rubocop](https://github.com/rubocop/rubocop) for linting and [Sorbet](https://sorbet.org/) for type checking.
39 |
40 | To run them:
41 | ```shell
42 | $ bundle exec rake rubocop
43 | $ bundle exec srb tc
44 | ```
45 |
46 | These linters can be easily integrated into IDEs such as RubyMine or VS Code.
47 |
48 | For VS Code, just install the basic Ruby extension which handles Rubocop ([`rebornix.ruby`](https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby)) and the official Sorbet one ([`sorbet.sorbet-vscode-extension`](https://marketplace.visualstudio.com/items?itemName=sorbet.sorbet-vscode-extension)).
49 |
50 | Recommended settings:
51 | ```json
52 | {
53 | "editor.formatOnSave": true,
54 | "ruby.useBundler": true,
55 | "ruby.lint": {
56 | "rubocop": {
57 | "useBundler": true, // enable rubocop via bundler
58 | }
59 | },
60 | "ruby.format": "rubocop",
61 | "ruby.useLanguageServer": true,
62 | "sorbet.enabled": true
63 | }
64 | ```
65 |
66 | ### Commit message convention
67 |
68 | This repository follows a commit message convention in order to automatically generate the [CHANGELOG](./CHANGELOG.md). Make sure you follow the rules of [conventional commits](https://www.conventionalcommits.org/) when opening a pull request.
69 |
70 | ### Releasing a new version (for Stream developers)
71 |
72 | In order to release new version you need to be a maintainer of the library.
73 |
74 | - Kick off a job called `initiate_release` ([link](https://github.com/GetStream/stream-chat-ruby/actions/workflows/initiate_release.yml)).
75 |
76 | The job creates a pull request with the changelog. Check if it looks good.
77 |
78 | - Merge the pull request.
79 |
80 | Once the PR is merged, it automatically kicks off another job which will upload the Gem to RubyGems.org and creates a GitHub release.
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 |
7 | group :dev do
8 | gem 'method_source', '~> 1.0'
9 | gem 'pry', '~> 0.14'
10 | gem 'pry-doc', '~> 1.3'
11 | gem 'rake', '~> 13.0'
12 | gem 'rspec', '~> 3.12'
13 | gem 'rubocop', '~> 1.38', require: false
14 | gem 'rubocop-ast', '~> 1.23', require: false
15 | gem 'simplecov', '~> 0.21.2'
16 | gem 'simplecov-console', '~> 0.9.1'
17 | gem 'sorbet', '~> 0.5.10539'
18 | end
19 |
20 | group :test do
21 | gem 'rack', '~> 2.2.4'
22 | end
23 |
24 | ruby '>= 3.0.0'
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | SOURCE CODE LICENSE AGREEMENT
2 |
3 | IMPORTANT - READ THIS CAREFULLY BEFORE DOWNLOADING, INSTALLING, USING OR
4 | ELECTRONICALLY ACCESSING THIS PROPRIETARY PRODUCT.
5 |
6 | THIS IS A LEGAL AGREEMENT BETWEEN STREAM.IO, INC. (“STREAM.IO”) AND THE
7 | BUSINESS ENTITY OR PERSON FOR WHOM YOU (“YOU”) ARE ACTING (“CUSTOMER”) AS THE
8 | LICENSEE OF THE PROPRIETARY SOFTWARE INTO WHICH THIS AGREEMENT HAS BEEN
9 | INCLUDED (THE “AGREEMENT”). YOU AGREE THAT YOU ARE THE CUSTOMER, OR YOU ARE AN
10 | EMPLOYEE OR AGENT OF CUSTOMER AND ARE ENTERING INTO THIS AGREEMENT FOR LICENSE
11 | OF THE SOFTWARE BY CUSTOMER FOR CUSTOMER’S BUSINESS PURPOSES AS DESCRIBED IN
12 | AND IN ACCORDANCE WITH THIS AGREEMENT. YOU HEREBY AGREE THAT YOU ENTER INTO
13 | THIS AGREEMENT ON BEHALF OF CUSTOMER AND THAT YOU HAVE THE AUTHORITY TO BIND
14 | CUSTOMER TO THIS AGREEMENT.
15 |
16 | STREAM.IO IS WILLING TO LICENSE THE SOFTWARE TO CUSTOMER ONLY ON THE FOLLOWING
17 | CONDITIONS: (1) YOU ARE A CURRENT CUSTOMER OF STREAM.IO; (2) YOU ARE NOT A
18 | COMPETITOR OF STREAM.IO; AND (3) THAT YOU ACCEPT ALL THE TERMS IN THIS
19 | AGREEMENT. BY DOWNLOADING, INSTALLING, CONFIGURING, ACCESSING OR OTHERWISE
20 | USING THE SOFTWARE, INCLUDING ANY UPDATES, UPGRADES, OR NEWER VERSIONS, YOU
21 | REPRESENT, WARRANT AND ACKNOWLEDGE THAT (A) CUSTOMER IS A CURRENT CUSTOMER OF
22 | STREAM.IO; (B) CUSTOMER IS NOT A COMPETITOR OF STREAM.IO; AND THAT (C) YOU HAVE
23 | READ THIS AGREEMENT, UNDERSTAND THIS AGREEMENT, AND THAT CUSTOMER AGREES TO BE
24 | BOUND BY ALL THE TERMS OF THIS AGREEMENT.
25 |
26 | IF YOU DO NOT AGREE TO ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT,
27 | STREAM.IO IS UNWILLING TO LICENSE THE SOFTWARE TO CUSTOMER, AND THEREFORE, DO
28 | NOT COMPLETE THE DOWNLOAD PROCESS, ACCESS OR OTHERWISE USE THE SOFTWARE, AND
29 | CUSTOMER SHOULD IMMEDIATELY RETURN THE SOFTWARE AND CEASE ANY USE OF THE
30 | SOFTWARE.
31 |
32 | 1. SOFTWARE. The Stream.io software accompanying this Agreement, may include
33 | Source Code, Executable Object Code, associated media, printed materials and
34 | documentation (collectively, the “Software”). The Software also includes any
35 | updates or upgrades to or new versions of the original Software, if and when
36 | made available to you by Stream.io. “Source Code” means computer programming
37 | code in human readable form that is not suitable for machine execution without
38 | the intervening steps of interpretation or compilation. “Executable Object
39 | Code" means the computer programming code in any other form than Source Code
40 | that is not readily perceivable by humans and suitable for machine execution
41 | without the intervening steps of interpretation or compilation. “Site” means a
42 | Customer location controlled by Customer. “Authorized User” means any employee
43 | or contractor of Customer working at the Site, who has signed a written
44 | confidentiality agreement with Customer or is otherwise bound in writing by
45 | confidentiality and use obligations at least as restrictive as those imposed
46 | under this Agreement.
47 |
48 | 2. LICENSE GRANT. Subject to the terms and conditions of this Agreement, in
49 | consideration for the representations, warranties, and covenants made by
50 | Customer in this Agreement, Stream.io grants to Customer, during the term of
51 | this Agreement, a personal, non-exclusive, non-transferable, non-sublicensable
52 | license to:
53 |
54 | a. install and use Software Source Code on password protected computers at a Site,
55 | restricted to Authorized Users;
56 |
57 | b. create derivative works, improvements (whether or not patentable), extensions
58 | and other modifications to the Software Source Code (“Modifications”) to build
59 | unique scalable newsfeeds, activity streams, and in-app messaging via Stream’s
60 | application program interface (“API”);
61 |
62 | c. compile the Software Source Code to create Executable Object Code versions of
63 | the Software Source Code and Modifications to build such newsfeeds, activity
64 | streams, and in-app messaging via the API;
65 |
66 | d. install, execute and use such Executable Object Code versions solely for
67 | Customer’s internal business use (including development of websites through
68 | which data generated by Stream services will be streamed (“Apps”));
69 |
70 | e. use and distribute such Executable Object Code as part of Customer’s Apps; and
71 |
72 | f. make electronic copies of the Software and Modifications as required for backup
73 | or archival purposes.
74 |
75 | 3. RESTRICTIONS. Customer is responsible for all activities that occur in
76 | connection with the Software. Customer will not, and will not attempt to: (a)
77 | sublicense or transfer the Software or any Source Code related to the Software
78 | or any of Customer’s rights under this Agreement, except as otherwise provided
79 | in this Agreement, (b) use the Software Source Code for the benefit of a third
80 | party or to operate a service; (c) allow any third party to access or use the
81 | Software Source Code; (d) sublicense or distribute the Software Source Code or
82 | any Modifications in Source Code or other derivative works based on any part of
83 | the Software Source Code; (e) use the Software in any manner that competes with
84 | Stream.io or its business; or (e) otherwise use the Software in any manner that
85 | exceeds the scope of use permitted in this Agreement. Customer shall use the
86 | Software in compliance with any accompanying documentation any laws applicable
87 | to Customer.
88 |
89 | 4. OPEN SOURCE. Customer and its Authorized Users shall not use any software or
90 | software components that are open source in conjunction with the Software
91 | Source Code or any Modifications in Source Code or in any way that could
92 | subject the Software to any open source licenses.
93 |
94 | 5. CONTRACTORS. Under the rights granted to Customer under this Agreement,
95 | Customer may permit its employees, contractors, and agencies of Customer to
96 | become Authorized Users to exercise the rights to the Software granted to
97 | Customer in accordance with this Agreement solely on behalf of Customer to
98 | provide services to Customer; provided that Customer shall be liable for the
99 | acts and omissions of all Authorized Users to the extent any of such acts or
100 | omissions, if performed by Customer, would constitute a breach of, or otherwise
101 | give rise to liability to Customer under, this Agreement. Customer shall not
102 | and shall not permit any Authorized User to use the Software except as
103 | expressly permitted in this Agreement.
104 |
105 | 6. COMPETITIVE PRODUCT DEVELOPMENT. Customer shall not use the Software in any way
106 | to engage in the development of products or services which could be reasonably
107 | construed to provide a complete or partial functional or commercial alternative
108 | to Stream.io’s products or services (a “Competitive Product”). Customer shall
109 | ensure that there is no direct or indirect use of, or sharing of, Software
110 | source code, or other information based upon or derived from the Software to
111 | develop such products or services. Without derogating from the generality of
112 | the foregoing, development of Competitive Products shall include having direct
113 | or indirect access to, supervising, consulting or assisting in the development
114 | of, or producing any specifications, documentation, object code or source code
115 | for, all or part of a Competitive Product.
116 |
117 | 7. LIMITATION ON MODIFICATIONS. Notwithstanding any provision in this Agreement,
118 | Modifications may only be created and used by Customer as permitted by this
119 | Agreement and Modification Source Code may not be distributed to third parties.
120 | Customer will not assert against Stream.io, its affiliates, or their customers,
121 | direct or indirect, agents and contractors, in any way, any patent rights that
122 | Customer may obtain relating to any Modifications for Stream.io, its
123 | affiliates’, or their customers’, direct or indirect, agents’ and contractors’
124 | manufacture, use, import, offer for sale or sale of any Stream.io products or
125 | services.
126 |
127 | 8. DELIVERY AND ACCEPTANCE. The Software will be delivered electronically pursuant
128 | to Stream.io standard download procedures. The Software is deemed accepted upon
129 | delivery.
130 |
131 | 9. IMPLEMENTATION AND SUPPORT. Stream.io has no obligation under this Agreement to
132 | provide any support or consultation concerning the Software.
133 |
134 | 10. TERM AND TERMINATION. The term of this Agreement begins when the Software is
135 | downloaded or accessed and shall continue until terminated. Either party may
136 | terminate this Agreement upon written notice. This Agreement shall
137 | automatically terminate if Customer is or becomes a competitor of Stream.io or
138 | makes or sells any Competitive Products. Upon termination of this Agreement for
139 | any reason, (a) all rights granted to Customer in this Agreement immediately
140 | cease to exist, (b) Customer must promptly discontinue all use of the Software
141 | and return to Stream.io or destroy all copies of the Software in Customer’s
142 | possession or control. Any continued use of the Software by Customer or attempt
143 | by Customer to exercise any rights under this Agreement after this Agreement
144 | has terminated shall be considered copyright infringement and subject Customer
145 | to applicable remedies for copyright infringement. Sections 2, 5, 6, 8 and 9
146 | shall survive expiration or termination of this Agreement for any reason.
147 |
148 | 11. OWNERSHIP. As between the parties, the Software and all worldwide intellectual
149 | property rights and proprietary rights relating thereto or embodied therein,
150 | are the exclusive property of Stream.io and its suppliers. Stream.io and its
151 | suppliers reserve all rights in and to the Software not expressly granted to
152 | Customer in this Agreement, and no other licenses or rights are granted by
153 | implication, estoppel or otherwise.
154 |
155 | 12. WARRANTY DISCLAIMER. USE OF THIS SOFTWARE IS ENTIRELY AT YOURS AND CUSTOMER’S
156 | OWN RISK. THE SOFTWARE IS PROVIDED “AS IS” WITHOUT ANY WARRANTY OF ANY KIND
157 | WHATSOEVER. STREAM.IO DOES NOT MAKE, AND HEREBY DISCLAIMS, ANY WARRANTY OF ANY
158 | KIND, WHETHER EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING WITHOUT
159 | LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
160 | PURPOSE, TITLE, NON-INFRINGEMENT OF THIRD-PARTY RIGHTS, RESULTS, EFFORTS,
161 | QUALITY OR QUIET ENJOYMENT. STREAM.IO DOES NOT WARRANT THAT THE SOFTWARE IS
162 | ERROR-FREE, WILL FUNCTION WITHOUT INTERRUPTION, WILL MEET ANY SPECIFIC NEED
163 | THAT CUSTOMER HAS, THAT ALL DEFECTS WILL BE CORRECTED OR THAT IT IS
164 | SUFFICIENTLY DOCUMENTED TO BE USABLE BY CUSTOMER. TO THE EXTENT THAT STREAM.IO
165 | MAY NOT DISCLAIM ANY WARRANTY AS A MATTER OF APPLICABLE LAW, THE SCOPE AND
166 | DURATION OF SUCH WARRANTY WILL BE THE MINIMUM PERMITTED UNDER SUCH LAW.
167 | CUSTOMER ACKNOWLEDGES THAT IT HAS RELIED ON NO WARRANTIES OTHER THAN THE
168 | EXPRESS WARRANTIES IN THIS AGREEMENT.
169 |
170 | 13. LIMITATION OF LIABILITY. TO THE FULLEST EXTENT PERMISSIBLE BY LAW, STREAM.IO’S
171 | TOTAL LIABILITY FOR ALL DAMAGES ARISING OUT OF OR RELATED TO THE SOFTWARE OR
172 | THIS AGREEMENT, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE,
173 | SHALL NOT EXCEED $100. IN NO EVENT WILL STREAM.IO BE LIABLE FOR ANY INDIRECT,
174 | CONSEQUENTIAL, EXEMPLARY, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES OF ANY KIND
175 | WHATSOEVER, INCLUDING ANY LOST DATA AND LOST PROFITS, ARISING FROM OR RELATING
176 | TO THE SOFTWARE EVEN IF STREAM.IO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
177 | DAMAGES. CUSTOMER ACKNOWLEDGES THAT THIS PROVISION REFLECTS THE AGREED UPON
178 | ALLOCATION OF RISK FOR THIS AGREEMENT AND THAT STREAM.IO WOULD NOT ENTER INTO
179 | THIS AGREEMENT WITHOUT THESE LIMITATIONS ON ITS LIABILITY.
180 |
181 | 14. General. Customer may not assign or transfer this Agreement, by operation of
182 | law or otherwise, or any of its rights under this Agreement (including the
183 | license rights granted to Customer) to any third party without Stream.io’s
184 | prior written consent, which consent will not be unreasonably withheld or
185 | delayed. Stream.io may assign this Agreement, without consent, including, but
186 | limited to, affiliate or any successor to all or substantially all its business
187 | or assets to which this Agreement relates, whether by merger, sale of assets,
188 | sale of stock, reorganization or otherwise. Any attempted assignment or
189 | transfer in violation of the foregoing will be null and void. Stream.io shall
190 | not be liable hereunder by reason of any failure or delay in the performance of
191 | its obligations hereunder for any cause which is beyond the reasonable control.
192 | All notices, consents, and approvals under this Agreement must be delivered in
193 | writing by courier, by electronic mail, or by certified or registered mail,
194 | (postage prepaid and return receipt requested) to the other party at the
195 | address set forth in the customer agreement between Stream.io and Customer and
196 | will be effective upon receipt or when delivery is refused. This Agreement will
197 | be governed by and interpreted in accordance with the laws of the State of
198 | Colorado, without reference to its choice of laws rules. The United Nations
199 | Convention on Contracts for the International Sale of Goods does not apply to
200 | this Agreement. Any action or proceeding arising from or relating to this
201 | Agreement shall be brought in a federal or state court in Denver, Colorado, and
202 | each party irrevocably submits to the jurisdiction and venue of any such court
203 | in any such action or proceeding. All waivers must be in writing. Any waiver or
204 | failure to enforce any provision of this Agreement on one occasion will not be
205 | deemed a waiver of any other provision or of such provision on any other
206 | occasion. If any provision of this Agreement is unenforceable, such provision
207 | will be changed and interpreted to accomplish the objectives of such provision
208 | to the greatest extent possible under applicable law and the remaining
209 | provisions will continue in full force and effect. Customer shall not violate
210 | any applicable law, rule or regulation, including those regarding the export of
211 | technical data. The headings of Sections of this Agreement are for convenience
212 | and are not to be used in interpreting this Agreement. As used in this
213 | Agreement, the word “including” means “including but not limited to.” This
214 | Agreement (including all exhibits and attachments) constitutes the entire
215 | agreement between the parties regarding the subject hereof and supersedes all
216 | prior or contemporaneous agreements, understandings and communication, whether
217 | written or oral. This Agreement may be amended only by a written document
218 | signed by both parties. The terms of any purchase order or similar document
219 | submitted by Customer to Stream.io will have no effect.
220 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Submit a pull request
2 |
3 | ## CLA
4 |
5 | - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required).
6 | - [ ] The code changes follow best practices
7 | - [ ] Code changes are tested (add some information if not applicable)
8 |
9 | ## Description of the pull request
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Official Ruby SDK for [Stream Chat](https://getstream.io/chat/)
2 |
3 | [](https://github.com/GetStream/stream-chat-ruby/actions) [](http://badge.fury.io/rb/stream-chat-ruby)
4 |
5 |
6 |
7 |
8 |
9 | Official Ruby API client for Stream Chat, a service for building chat applications.
10 |
11 | Explore the docs »
12 |
13 |
14 | Code Samples
15 | ·
16 | Report Bug
17 | ·
18 | Request Feature
19 |
20 |
21 | ## 📝 About Stream
22 |
23 | You can sign up for a Stream account at our [Get Started](https://getstream.io/chat/get_started/) page.
24 |
25 | You can use this library to access chat API endpoints server-side.
26 |
27 | For the client-side integrations (web and mobile) have a look at the JavaScript, iOS and Android SDK libraries ([docs](https://getstream.io/chat/)).
28 |
29 | ## ⚙️ Installation
30 |
31 | [`stream-chat-ruby`](https://rubygems.org/gems/stream-chat-ruby) supports Ruby version `3.0` and greater. We test against Ruby versions `3.0`, `3.1` and `3.4`.
32 |
33 | ```bash
34 | $ gem install stream-chat-ruby
35 | ```
36 |
37 | ## ✨ Getting started
38 |
39 | ```ruby
40 | require 'stream-chat'
41 |
42 | client = StreamChat::Client.new('STREAM_KEY', 'STREAM_SECRET')
43 | ```
44 |
45 | > 💡 Note: since v2.21.0 we implemented [Sorbet](https://sorbet.org/) type checker. As of v2.x.x we only use it for static type checks and you won't notice any difference, but from v3.0.0 **we will enable runtime checks** 🚨 🚨 🚨.
46 |
47 | > What this means, is that you'll receive an error during runtime if you pass an invalid type to our methods. To prepare for that, just make sure whatever you pass in, matches the method signature (`sig { ... }`).
48 |
49 | > **Update (2022-May-24)**: we have relased [v3.0.0](https://github.com/GetStream/stream-chat-ruby/releases/tag/v3.0.0) with enabled runtime checks.
50 |
51 | ---
52 |
53 | > Additionally, in a future major version, we would like to enforce symbol hash keys during runtime to conform to Ruby best practises. It's a good idea to prepare your application for that.
54 | >
55 | > ```ruby
56 | > # Wrong:
57 | > user = { "user" => { "id" => "bob-1"}}
58 | > # Correct:
59 | > user = { user: { id: "bob-1" }}
60 | > ```
61 |
62 | ### Generate a token for client-side usage:
63 |
64 | ```ruby
65 | client.create_token('bob-1')
66 | ```
67 |
68 | ### Create/Update users
69 |
70 | ```ruby
71 | client.upsert_user({
72 | id: 'bob-1',
73 | role: 'admin',
74 | name: 'Robert Tables'
75 | })
76 |
77 | # Batch update is also supported
78 | jane = {id: 'jane-1'}
79 | june = {id: 'june-1'}
80 | client.upsert_users([jane, june])
81 | ```
82 |
83 | ### Channel types
84 |
85 | ```ruby
86 | client.create_channel_type({
87 | name: 'livechat',
88 | automod: 'disabled',
89 | commands: ['ban'],
90 | mutes: true
91 | })
92 |
93 | channel_types = client.list_channel_types()
94 | ```
95 |
96 | ### Channels
97 |
98 | ```ruby
99 | # Create a channel with members from the start
100 | chan = client.channel("messaging", channel_id: "bob-and-jane", data: {:members => ['bob-1', 'jane-77']})
101 | chan.create('bob-1')
102 |
103 | # Create a channel and then add members
104 | chan = client.channel("messaging", channel_id: "bob-and-jane")
105 | chan.create('bob-1')
106 | chan.add_members(['bob-1', 'jane-77'])
107 | ```
108 |
109 | ### Reactions
110 |
111 | ```ruby
112 | chan.send_reaction(m1['id'], {type: 'like'}, 'bob-1')
113 | ```
114 |
115 | ### Moderation
116 |
117 | ```ruby
118 | chan.add_moderators(['jane-77'])
119 | chan.demote_moderators(['bob-1'])
120 |
121 | chan.ban_user('bob-1', timeout: 30)
122 |
123 | chan.unban_user('bob-1')
124 | ```
125 |
126 | ### Messages
127 |
128 | ```ruby
129 | m1 = chan.send_message({text: 'Hi Jane!'}, 'bob-1')
130 |
131 | deleted_message = client.delete_message(m1['message']['id'])
132 |
133 | ```
134 |
135 | ### Devices
136 |
137 | ```ruby
138 | jane_phone = client.add_device({:id => 'iOS Device Token', :push_provider => push_provider.apn, :user_id => 'jane-77'})
139 |
140 | client.get_devices('jane-77')
141 |
142 | client.remove_device(jane_phone['id'], jane_phone['user_id'])
143 | ```
144 |
145 | ### Blocklists
146 |
147 | ```ruby
148 | client.create_blocklist('my_blocker', %w[fudge cream sugar])
149 |
150 | # Enable it on 'messaging' channel type
151 | client.update_channel_type('messaging', blocklist: 'my_blocker', blocklist_behavior: 'block')
152 |
153 | client.get_blocklist('my_blocker')
154 |
155 | client.delete_blocklist('my_blocker')
156 | ```
157 |
158 | ### Export Channels
159 |
160 | ```ruby
161 | # Register an export
162 | response = client.export_channels({type: 'messaging', id: 'jane'})
163 |
164 | # Check completion
165 | status_response = client.get_export_channel_status(response['task_id'])
166 | # status_response['status'] == 'pending', 'completed'
167 | ```
168 |
169 | ### Rate limits
170 |
171 | ```ruby
172 | # Get all rate limits
173 | limits = client.get_rate_limits
174 |
175 | # Get rate limits for specific platform(s)
176 | limits = client.get_rate_limits(server_side: true)
177 |
178 | # Get rate limits for specific platforms and endpoints
179 | limits = client.get_rate_limits(android: true, ios: true, endpoints: ['QueryChannels', 'SendMessage'])
180 | ```
181 |
182 | ## ✍️ Contributing
183 |
184 | We welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. See our [license file](./LICENSE) for more details.
185 |
186 | Head over to [CONTRIBUTING.md](./CONTRIBUTING.md) for some development tips.
187 |
188 | ## 🧑💻 We are hiring!
189 |
190 | We've recently closed a [$38 million Series B funding round](https://techcrunch.com/2021/03/04/stream-raises-38m-as-its-chat-and-activity-feed-apis-power-communications-for-1b-users/) and we keep actively growing.
191 | Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world.
192 |
193 | Check out our current openings and apply via [Stream's website](https://getstream.io/team/#jobs).
194 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'bundler/gem_tasks'
4 | # rake spec
5 | require 'rspec/core/rake_task'
6 | RSpec::Core::RakeTask.new(:spec) { |t| t.verbose = false }
7 |
8 | # rake console
9 | task :console do
10 | require 'pry'
11 | require 'stream-chat'
12 | ARGV.clear
13 | Pry.start
14 | end
15 |
16 | require 'rubocop/rake_task'
17 | RuboCop::RakeTask.new(:rubocop) do |t|
18 | t.options = ['--display-cop-names']
19 | end
20 |
21 | task default: [:spec]
22 | task test: [:spec]
23 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Reporting a Vulnerability
2 | At Stream we are committed to the security of our Software. We appreciate your efforts in disclosing vulnerabilities responsibly and we will make every effort to acknowledge your contributions.
3 |
4 | Report security vulnerabilities at the following email address:
5 | ```
6 | [security@getstream.io](mailto:security@getstream.io)
7 | ```
8 | Alternatively it is also possible to open a new issue in the affected repository, tagging it with the `security` tag.
9 |
10 | A team member will acknowledge the vulnerability and will follow-up with more detailed information. A representative of the security team will be in touch if more information is needed.
11 |
12 | # Information to include in a report
13 | While we appreciate any information that you are willing to provide, please make sure to include the following:
14 | * Which repository is affected
15 | * Which branch, if relevant
16 | * Be as descriptive as possible, the team will replicate the vulnerability before working on a fix.
17 |
--------------------------------------------------------------------------------
/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | STREAM MARK
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lib/stream-chat.rb:
--------------------------------------------------------------------------------
1 | # typed: strict # rubocop:todo Naming/FileName
2 | # frozen_string_literal: true
3 |
4 | require 'stream-chat/client'
5 |
--------------------------------------------------------------------------------
/lib/stream-chat/channel.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | require 'stream-chat/client'
5 | require 'stream-chat/errors'
6 | require 'stream-chat/util'
7 | require 'stream-chat/types'
8 |
9 | module StreamChat
10 | class Channel
11 | extend T::Sig
12 |
13 | sig { returns(T.nilable(String)) }
14 | attr_reader :id
15 |
16 | sig { returns(String) }
17 | attr_reader :channel_type
18 |
19 | sig { returns(String) }
20 | attr_reader :cid
21 |
22 | sig { returns(StringKeyHash) }
23 | attr_reader :custom_data
24 |
25 | sig { returns(T::Array[StringKeyHash]) }
26 | attr_reader :members
27 |
28 | sig { params(client: StreamChat::Client, channel_type: String, channel_id: T.nilable(String), custom_data: T.nilable(StringKeyHash)).void }
29 | def initialize(client, channel_type, channel_id = nil, custom_data = nil)
30 | @channel_type = channel_type
31 | @id = channel_id
32 | @cid = T.let("#{@channel_type}:#{@id}", String)
33 | @client = client
34 | @custom_data = T.let(custom_data || {}, StringKeyHash)
35 | @members = T.let([], T::Array[StringKeyHash])
36 | end
37 |
38 | sig { returns(String) }
39 | def url
40 | raise StreamChannelException, 'channel does not have an id' if @id.nil?
41 |
42 | "channels/#{@channel_type}/#{@id}"
43 | end
44 |
45 | # Gets multiple messages from the channel.
46 | sig { params(message_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
47 | def get_messages(message_ids)
48 | @client.get("#{url}/messages", params: { 'ids' => message_ids.join(',') })
49 | end
50 |
51 | # Sends a message to this channel.
52 | sig { params(message: StringKeyHash, user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
53 | def send_message(message, user_id, **options)
54 | payload = options.merge({ message: add_user_id(message, user_id) })
55 | @client.post("#{url}/message", data: payload)
56 | end
57 |
58 | # Sends an event on this channel.
59 | sig { params(event: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
60 | def send_event(event, user_id)
61 | payload = { 'event' => add_user_id(event, user_id) }
62 | @client.post("#{url}/event", data: payload)
63 | end
64 |
65 | # Sends a new reaction to a given message.
66 | sig { params(message_id: String, reaction: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
67 | def send_reaction(message_id, reaction, user_id)
68 | payload = { reaction: add_user_id(reaction, user_id) }
69 | @client.post("messages/#{message_id}/reaction", data: payload)
70 | end
71 |
72 | # Delete a reaction from a message.
73 | sig { params(message_id: String, reaction_type: String, user_id: String).returns(StreamChat::StreamResponse) }
74 | def delete_reaction(message_id, reaction_type, user_id)
75 | @client.delete(
76 | "messages/#{message_id}/reaction/#{reaction_type}",
77 | params: { user_id: user_id }
78 | )
79 | end
80 |
81 | # Creates a channel with the given creator user.
82 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
83 | def create(user_id)
84 | @custom_data['created_by'] = { id: user_id }
85 | query(watch: false, state: false, presence: false)
86 | end
87 |
88 | # Creates or returns a channel.
89 | sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
90 | def query(**options)
91 | payload = { state: true, data: @custom_data }.merge(options)
92 | url = "channels/#{@channel_type}"
93 | url = "#{url}/#{@id}" unless @id.nil?
94 |
95 | state = @client.post("#{url}/query", data: payload)
96 | @id = state['channel']['id'] if @id.nil?
97 | state
98 | end
99 |
100 | # Queries members of a channel.
101 | #
102 | # The queryMembers endpoint allows you to list and paginate members from a channel. The
103 | # endpoint supports filtering on numerous criteria to efficiently return members information.
104 | # This endpoint is useful for channels that have large lists of members and
105 | # you want to search members or if you want to display the full list of members for a channel.
106 | sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
107 | def query_members(filter_conditions = {}, sort: nil, **options)
108 | params = {}.merge(options).merge({
109 | id: @id,
110 | type: @channel_type,
111 | filter_conditions: filter_conditions,
112 | sort: StreamChat.get_sort_fields(sort)
113 | })
114 |
115 | if @id == '' && @members.length.positive?
116 | params['members'] = []
117 | @members.each do |m|
118 | params['members'] << m['user'].nil? ? m['user_id'] : m['user']['id']
119 | end
120 | end
121 |
122 | @client.get('members', params: { payload: params.to_json })
123 | end
124 |
125 | # Updates a channel.
126 | sig { params(channel_data: T.nilable(StringKeyHash), update_message: T.nilable(StringKeyHash), options: T.untyped).returns(StreamChat::StreamResponse) }
127 | def update(channel_data, update_message = nil, **options)
128 | payload = { data: channel_data, message: update_message }.merge(options)
129 | @client.post(url, data: payload)
130 | end
131 |
132 | # Updates a channel partially.
133 | sig { params(set: T.nilable(StringKeyHash), unset: T.nilable(T::Array[String])).returns(StreamChat::StreamResponse) }
134 | def update_partial(set = nil, unset = nil)
135 | raise StreamChannelException, 'set or unset is needed' if set.nil? && unset.nil?
136 |
137 | payload = { set: set, unset: unset }
138 | @client.patch(url, data: payload)
139 | end
140 |
141 | # Deletes a channel.
142 | sig { returns(StreamChat::StreamResponse) }
143 | def delete
144 | @client.delete(url)
145 | end
146 |
147 | # Removes all messages from the channel.
148 | sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
149 | def truncate(**options)
150 | @client.post("#{url}/truncate", data: options)
151 | end
152 |
153 | # Mutes a channel.
154 | #
155 | # Messages added to a muted channel will not trigger push notifications, nor change the
156 | # unread count for the users that muted it. By default, mutes stay in place indefinitely
157 | # until the user removes it; however, you can optionally set an expiration time. The list
158 | # of muted channels and their expiration time is returned when the user connects.
159 | sig { params(user_id: String, expiration: T.nilable(Integer)).returns(StreamChat::StreamResponse) }
160 | def mute(user_id, expiration = nil)
161 | data = { user_id: user_id, channel_cid: @cid }
162 | data['expiration'] = expiration if expiration
163 | @client.post('moderation/mute/channel', data: data)
164 | end
165 |
166 | # Unmutes a channel.
167 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
168 | def unmute(user_id)
169 | @client.post('moderation/unmute/channel', data: { 'user_id' => user_id, 'channel_cid' => @cid })
170 | end
171 |
172 | # Pins a channel for a user.
173 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
174 | def pin(user_id)
175 | raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
176 |
177 | payload = {
178 | set: {
179 | pinned: true
180 | }
181 | }
182 | @client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
183 | end
184 |
185 | # Unins a channel for a user.
186 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
187 | def unpin(user_id)
188 | raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
189 |
190 | payload = {
191 | set: {
192 | pinned: false
193 | }
194 | }
195 | @client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
196 | end
197 |
198 | # Archives a channel for a user.
199 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
200 | def archive(user_id)
201 | raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
202 |
203 | payload = {
204 | set: {
205 | archived: true
206 | }
207 | }
208 | @client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
209 | end
210 |
211 | # Archives a channel for a user.
212 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
213 | def unarchive(user_id)
214 | raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
215 |
216 | payload = {
217 | set: {
218 | archived: false
219 | }
220 | }
221 | @client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
222 | end
223 |
224 | # Updates a member partially in the channel.
225 | sig { params(user_id: String, set: T.nilable(StringKeyHash), unset: T.nilable(T::Array[String])).returns(StreamChat::StreamResponse) }
226 | def update_member_partial(user_id, set: nil, unset: nil)
227 | raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
228 | raise StreamChannelException, 'set or unset is required' if set.nil? && unset.nil?
229 |
230 | payload = { set: set, unset: unset }
231 | @client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
232 | end
233 |
234 | # Adds members to the channel.
235 | sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
236 | def add_members(user_ids, **options)
237 | payload = options.merge({ add_members: user_ids })
238 | update(nil, nil, **payload)
239 | end
240 |
241 | # Invites users to the channel.
242 | sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
243 | def invite_members(user_ids, **options)
244 | payload = options.merge({ invites: user_ids })
245 | update(nil, nil, **payload)
246 | end
247 |
248 | # Accepts an invitation to the channel.
249 | sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
250 | def accept_invite(user_id, **options)
251 | payload = options.merge({ user_id: user_id, accept_invite: true })
252 | update(nil, nil, **payload)
253 | end
254 |
255 | # Rejects an invitation to the channel.
256 | sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
257 | def reject_invite(user_id, **options)
258 | payload = options.merge({ user_id: user_id, reject_invite: true })
259 | update(nil, nil, **payload)
260 | end
261 |
262 | # Adds moderators to the channel.
263 | sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
264 | def add_moderators(user_ids)
265 | update(nil, nil, add_moderators: user_ids)
266 | end
267 |
268 | # Removes members from the channel.
269 | sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
270 | def remove_members(user_ids)
271 | update(nil, nil, remove_members: user_ids)
272 | end
273 |
274 | # Assigns roles to members in the channel.
275 | sig { params(members: T::Array[StringKeyHash], message: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
276 | def assign_roles(members, message = nil)
277 | update(nil, message, assign_roles: members)
278 | end
279 |
280 | # Demotes moderators in the channel.
281 | sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
282 | def demote_moderators(user_ids)
283 | update(nil, nil, demote_moderators: user_ids)
284 | end
285 |
286 | # Sends the mark read event for this user, only works if the `read_events` setting is enabled.
287 | sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
288 | def mark_read(user_id, **options)
289 | payload = add_user_id(options, user_id)
290 | @client.post("#{url}/read", data: payload)
291 | end
292 |
293 | # List the message replies for a parent message.
294 | sig { params(parent_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
295 | def get_replies(parent_id, **options)
296 | @client.get("messages/#{parent_id}/replies", params: options)
297 | end
298 |
299 | # List the reactions, supports pagination.
300 | sig { params(message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
301 | def get_reactions(message_id, **options)
302 | @client.get("messages/#{message_id}/reactions", params: options)
303 | end
304 |
305 | # Bans a user from this channel.
306 | sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
307 | def ban_user(user_id, **options)
308 | @client.ban_user(user_id, type: @channel_type, id: @id, **options)
309 | end
310 |
311 | # Removes the ban for a user on this channel.
312 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
313 | def unban_user(user_id)
314 | @client.unban_user(user_id, type: @channel_type, id: @id)
315 | end
316 |
317 | # Removes a channel from query channel requests for that user until a new message is added.
318 | # Use `show` to cancel this operation.
319 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
320 | def hide(user_id)
321 | @client.post("#{url}/hide", data: { user_id: user_id })
322 | end
323 |
324 | # Shows a previously hidden channel.
325 | # Use `hide` to hide a channel.
326 | sig { params(user_id: String).returns(StreamChat::StreamResponse) }
327 | def show(user_id)
328 | @client.post("#{url}/show", data: { user_id: user_id })
329 | end
330 |
331 | # Uploads a file.
332 | #
333 | # This functionality defaults to using the Stream CDN. If you would like, you can
334 | # easily change the logic to upload to your own CDN of choice.
335 | sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
336 | def send_file(url, user, content_type = nil)
337 | @client.send_file("#{self.url}/file", url, user, content_type)
338 | end
339 |
340 | # Uploads an image.
341 | #
342 | # Stream supported image types are: image/bmp, image/gif, image/jpeg, image/png, image/webp,
343 | # image/heic, image/heic-sequence, image/heif, image/heif-sequence, image/svg+xml.
344 | # You can set a more restrictive list for your application if needed.
345 | # The maximum file size is 100MB.
346 | sig { params(url: String, user: StringKeyHash, content_type: T.nilable(String)).returns(StreamChat::StreamResponse) }
347 | def send_image(url, user, content_type = nil)
348 | @client.send_file("#{self.url}/image", url, user, content_type)
349 | end
350 |
351 | # Deletes a file by file url.
352 | sig { params(url: String).returns(StreamChat::StreamResponse) }
353 | def delete_file(url)
354 | @client.delete("#{self.url}/file", params: { url: url })
355 | end
356 |
357 | # Deletes an image by image url.
358 | sig { params(url: String).returns(StreamChat::StreamResponse) }
359 | def delete_image(url)
360 | @client.delete("#{self.url}/image", params: { url: url })
361 | end
362 |
363 | # Creates or updates a draft message for this channel.
364 | #
365 | # @param [StringKeyHash] message The draft message content
366 | # @param [String] user_id The ID of the user creating/updating the draft
367 | # @return [StreamChat::StreamResponse]
368 | sig { params(message: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
369 | def create_draft(message, user_id)
370 | payload = { message: add_user_id(message, user_id) }
371 | @client.post("#{url}/draft", data: payload)
372 | end
373 |
374 | # Deletes a draft message for this channel.
375 | #
376 | # @param [String] user_id The ID of the user deleting the draft
377 | # @param [String] parent_id Optional parent message ID for thread drafts
378 | # @return [StreamChat::StreamResponse]
379 | sig { params(user_id: String, parent_id: T.nilable(String)).returns(StreamChat::StreamResponse) }
380 | def delete_draft(user_id, parent_id: nil)
381 | params = { user_id: user_id }
382 | params[:parent_id] = parent_id if parent_id
383 | @client.delete("#{url}/draft", params: params)
384 | end
385 |
386 | # Gets a draft message for this channel.
387 | #
388 | # @param [String] user_id The ID of the user getting the draft
389 | # @param [String] parent_id Optional parent message ID for thread drafts
390 | # @return [StreamChat::StreamResponse]
391 | sig { params(user_id: String, parent_id: T.nilable(String)).returns(StreamChat::StreamResponse) }
392 | def get_draft(user_id, parent_id: nil)
393 | params = { user_id: user_id }
394 | params[:parent_id] = parent_id if parent_id
395 | @client.get("#{url}/draft", params: params)
396 | end
397 |
398 | private
399 |
400 | sig { params(payload: StringKeyHash, user_id: String).returns(StringKeyHash) }
401 | def add_user_id(payload, user_id)
402 | payload.merge({ user: { id: user_id } })
403 | end
404 | end
405 | end
406 |
--------------------------------------------------------------------------------
/lib/stream-chat/errors.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | module StreamChat
5 | class StreamAPIException < StandardError
6 | extend T::Sig
7 |
8 | sig { returns(Integer) }
9 | attr_reader :error_code
10 |
11 | sig { returns(String) }
12 | attr_reader :error_message
13 |
14 | sig { returns(T::Boolean) }
15 | attr_reader :json_response
16 |
17 | sig { returns(Faraday::Response) }
18 | attr_reader :response
19 |
20 | sig { params(response: Faraday::Response).void }
21 | def initialize(response)
22 | super()
23 | @response = response
24 | begin
25 | parsed_response = JSON.parse(response.body)
26 | @json_response = T.let(true, T::Boolean)
27 | @error_code = T.let(parsed_response.fetch('code', 'unknown'), Integer)
28 | @error_message = T.let(parsed_response.fetch('message', 'unknown'), String)
29 | rescue JSON::ParserError
30 | @json_response = false
31 | end
32 | end
33 |
34 | sig { returns(String) }
35 | def message
36 | if @json_response
37 | "StreamChat error code #{@error_code}: #{@error_message}"
38 | else
39 | "StreamChat error HTTP code: #{@response.status}"
40 | end
41 | end
42 |
43 | sig { returns(String) }
44 | def to_s
45 | message
46 | end
47 | end
48 |
49 | class StreamChannelException < StandardError; end
50 | end
51 |
--------------------------------------------------------------------------------
/lib/stream-chat/moderation.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | require 'stream-chat/client'
5 | require 'stream-chat/errors'
6 | require 'stream-chat/util'
7 | require 'stream-chat/types'
8 |
9 | module StreamChat
10 | # Moderation class provides all the endpoints related to moderation v2
11 | class Moderation
12 | extend T::Sig
13 |
14 | MODERATION_ENTITY_TYPES = T.let(
15 | {
16 | user: 'stream:user',
17 | message: 'stream:chat:v1:message',
18 | userprofile: 'stream:v1:user_profile'
19 | }.freeze,
20 | T::Hash[Symbol, String]
21 | )
22 |
23 | sig { params(client: Client).void }
24 | def initialize(client)
25 | @client = client
26 | end
27 |
28 | # Experimental: Check user profile
29 | #
30 | # Warning: This is an experimental feature and the API is subject to change.
31 | #
32 | # This function is used to check a user profile for moderation.
33 | # This will not create any review queue items for the user profile.
34 | # You can just use this to check whether to allow a certain user profile to be created or not.
35 | #
36 | # @param [string] user_id User ID to be checked
37 | # @param [Hash] profile Profile data to be checked
38 | # @option profile [String] :username Username to be checked
39 | # @option profile [String] :image Image URL to be checked
40 | # @return [StreamChat::StreamResponse]
41 | #
42 | # example:
43 | # client.moderation.check_user_profile('user-id', {username: 'bad_username', image: 'https://example.com/profile.jpg'})
44 | sig do
45 | params(
46 | user_id: String,
47 | profile: T::Hash[Symbol, T.nilable(String)]
48 | ).returns(StreamChat::StreamResponse)
49 | end
50 | def check_user_profile(user_id, profile)
51 | raise ArgumentError, 'Either username or image must be provided' if profile[:username].nil? && profile[:image].nil?
52 |
53 | moderation_payload = {}
54 | moderation_payload[:texts] = [profile[:username]] if profile[:username]
55 | moderation_payload[:images] = [profile[:image]] if profile[:image]
56 |
57 | check(
58 | T.must(MODERATION_ENTITY_TYPES[:userprofile]),
59 | user_id,
60 | moderation_payload,
61 | 'user_profile:default',
62 | entity_creator_id: user_id,
63 | options: {
64 | force_sync: true,
65 | test_mode: true
66 | }
67 | )
68 | end
69 |
70 | # Flags a user with a reason
71 | #
72 | # @param [string] flagged_user_id User ID to be flagged
73 | # @param [string] reason Reason for flagging the user
74 | # @param [Hash] options Additional options for flagging the user
75 | # @option options [String] :user_id User ID of the user who is flagging the target user
76 | # @option options [Hash] :custom Additional data to be stored with the flag
77 | sig { params(flagged_user_id: String, reason: String, options: T.untyped).returns(StreamChat::StreamResponse) }
78 | def flag_user(flagged_user_id, reason, **options)
79 | flag(T.must(MODERATION_ENTITY_TYPES[:user]), flagged_user_id, reason, **options)
80 | end
81 |
82 | # Flags a message with a reason
83 | #
84 | # @param [string] message_id Message ID to be flagged
85 | # @param [string] reason Reason for flagging the message
86 | # @param [Hash] options Additional options for flagging the message
87 | # @option options [String] :user_id User ID of the user who is flagging the target message
88 | # @option options [Hash] :custom Additional data to be stored with the flag
89 | sig { params(message_id: String, reason: String, options: T.untyped).returns(StreamChat::StreamResponse) }
90 | def flag_message(message_id, reason, **options)
91 | flag(T.must(MODERATION_ENTITY_TYPES[:message]), message_id, reason, **options)
92 | end
93 |
94 | # Flags an entity with a reason
95 | #
96 | # @param [string] entity_type Entity type to be flagged
97 | # @param [string] entity_id Entity ID to be flagged
98 | # @param [string] reason Reason for flagging the entity
99 | # @param [string] entity_creator_id User ID of the entity creator (optional)
100 | # @param [Hash] options Additional options for flagging the entity
101 | # @option options [String] :user_id User ID of the user who is flagging the target entity
102 | # @option options [Hash] :moderation_payload Content to be flagged
103 | # @option options [Hash] :custom Additional data to be stored with the flag
104 | sig { params(entity_type: String, entity_id: String, reason: String, entity_creator_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
105 | def flag(entity_type, entity_id, reason, entity_creator_id: '', **options)
106 | @client.post('api/v2/moderation/flag', data: {
107 | entity_type: entity_type,
108 | entity_id: entity_id,
109 | entity_creator_id: entity_creator_id,
110 | reason: reason,
111 | **options
112 | })
113 | end
114 |
115 | # Mutes a user
116 | #
117 | # @param [string] target_id User ID to be muted
118 | # @param [Hash] options Additional options for muting the user
119 | # @option options [String] :user_id User ID of the user who is muting the target user
120 | # @option options [Integer] :timeout Timeout for the mute in minutes
121 | sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
122 | def mute_user(target_id, **options)
123 | @client.post('api/v2/moderation/mute', data: {
124 | target_ids: [target_id],
125 | **options
126 | })
127 | end
128 |
129 | # Unmutes a user
130 | #
131 | # @param [string] target_id User ID to be unmuted
132 | # @param [Hash] options Additional options for unmuting the user
133 | # @option options [String] :user_id User ID of the user who is unmuting the target user
134 | sig { params(target_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
135 | def unmute_user(target_id, **options)
136 | @client.post('api/v2/moderation/unmute', data: {
137 | target_ids: [target_id],
138 | **options
139 | })
140 | end
141 |
142 | # Gets moderation report for a user
143 | #
144 | # @param [string] user_id User ID for which moderation report is to be fetched
145 | # @param [Hash] options Additional options for fetching the moderation report
146 | # @option options [Boolean] :create_user_if_not_exists Create user if not exists
147 | # @option options [Boolean] :include_user_blocks Include user blocks
148 | # @option options [Boolean] :include_user_mutes Include user mutes
149 | sig { params(user_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
150 | def get_user_moderation_report(user_id, **options)
151 | @client.get('api/v2/moderation/user_report', params: {
152 | user_id: user_id,
153 | **options
154 | })
155 | end
156 |
157 | # Queries review queue
158 | #
159 | # @param [Hash] filter_conditions Filter conditions for querying review queue
160 | # @param [Array] sort Sort conditions for querying review queue
161 | # @param [Hash] options Pagination options for querying review queue
162 | sig { params(filter_conditions: T.untyped, sort: T.untyped, options: T.untyped).returns(StreamChat::StreamResponse) }
163 | def query_review_queue(filter_conditions = {}, sort = [], **options)
164 | @client.post('api/v2/moderation/review_queue', data: {
165 | filter: filter_conditions,
166 | sort: StreamChat.get_sort_fields(sort),
167 | **options
168 | })
169 | end
170 |
171 | # Upserts moderation config
172 | #
173 | # @param [Hash] config Moderation config to be upserted
174 | sig { params(config: T.untyped).returns(StreamChat::StreamResponse) }
175 | def upsert_config(config)
176 | @client.post('api/v2/moderation/config', data: config)
177 | end
178 |
179 | # Gets moderation config
180 | #
181 | # @param [string] key Key for which moderation config is to be fetched
182 | # @param [Hash] data Additional data
183 | # @option data [String] :team Team name
184 | sig { params(key: String, data: T.untyped).returns(StreamChat::StreamResponse) }
185 | def get_config(key, data = {})
186 | @client.get("api/v2/moderation/config/#{key}", params: data)
187 | end
188 |
189 | # Deletes moderation config
190 | #
191 | # @param [string] key Key for which moderation config is to be deleted
192 | # @param [Hash] data Additional data
193 | # @option data [String] :team Team name
194 | sig { params(key: String, data: T.untyped).returns(StreamChat::StreamResponse) }
195 | def delete_config(key, data = {})
196 | @client.delete("api/v2/moderation/config/#{key}", params: data)
197 | end
198 |
199 | # Queries moderation configs
200 | #
201 | # @param [Hash] filter_conditions Filter conditions for querying moderation configs
202 | # @param [Array] sort Sort conditions for querying moderation configs
203 | # @param [Hash] options Additional options for querying moderation configs
204 | sig { params(filter_conditions: T.untyped, sort: T.untyped, options: T.untyped).returns(StreamChat::StreamResponse) }
205 | def query_configs(filter_conditions, sort, **options)
206 | @client.post('api/v2/moderation/configs', data: {
207 | filter: filter_conditions,
208 | sort: sort,
209 | **options
210 | })
211 | end
212 |
213 | # Submits a moderation action
214 | #
215 | # @param [string] action_type Type of action to submit
216 | # @param [string] item_id ID of the item to submit action for
217 | # @param [Hash] options Additional options for submitting the action
218 | sig { params(action_type: String, item_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
219 | def submit_action(action_type, item_id, **options)
220 | @client.post('api/v2/moderation/submit_action', data: {
221 | action_type: action_type,
222 | item_id: item_id,
223 | **options
224 | })
225 | end
226 |
227 | # rubocop:disable Metrics/ParameterLists
228 | # Checks content for moderation
229 | #
230 | # @param [string] entity_type Type of entity to be checked E.g., stream:user, stream:chat:v1:message, or any custom string
231 | # @param [string] entity_id ID of the entity to be checked. This is mainly for tracking purposes
232 | # @param [string] entity_creator_id ID of the entity creator
233 | # @param [Hash] moderation_payload Content to be checked for moderation
234 | # @option moderation_payload [Array] :texts Array of texts to be checked for moderation
235 | # @option moderation_payload [Array] :images Array of images to be checked for moderation
236 | # @option moderation_payload [Array] :videos Array of videos to be checked for moderation
237 | # @option moderation_payload [Hash] :custom Additional custom data
238 | # @param [string] config_key Key of the moderation config to use
239 | # @param [Hash] options Additional options
240 | # @option options [Boolean] :force_sync Force synchronous check
241 | sig do
242 | params(
243 | entity_type: String,
244 | entity_id: String,
245 | moderation_payload: T::Hash[Symbol, T.any(T::Array[String], T::Hash[String, T.untyped])],
246 | config_key: String,
247 | entity_creator_id: String,
248 | options: T::Hash[Symbol, T::Boolean]
249 | ).returns(StreamChat::StreamResponse)
250 | end
251 | def check(entity_type, entity_id, moderation_payload, config_key, entity_creator_id: '', options: {})
252 | @client.post('api/v2/moderation/check', data: {
253 | entity_type: entity_type,
254 | entity_id: entity_id,
255 | entity_creator_id: entity_creator_id,
256 | moderation_payload: moderation_payload,
257 | config_key: config_key,
258 | options: options
259 | })
260 | end
261 | # rubocop:enable Metrics/ParameterLists
262 | # Adds custom flags to an entity
263 | #
264 | # @param [string] entity_type Type of entity to be checked
265 | # @param [string] entity_id ID of the entity to be checked
266 | # @param [string] entity_creator_id ID of the entity creator
267 | # @param [Hash] moderation_payload Content to be checked for moderation
268 | # @param [Array] flags Array of custom flags to add
269 | sig { params(entity_type: String, entity_id: String, moderation_payload: T.untyped, flags: T::Array[T.untyped], entity_creator_id: String).returns(StreamChat::StreamResponse) }
270 | def add_custom_flags(entity_type, entity_id, moderation_payload, flags, entity_creator_id: '')
271 | @client.post('api/v2/moderation/custom_check', data: {
272 | entity_type: entity_type,
273 | entity_id: entity_id,
274 | entity_creator_id: entity_creator_id,
275 | moderation_payload: moderation_payload,
276 | flags: flags
277 | })
278 | end
279 |
280 | # Adds custom flags to a message
281 | #
282 | # @param [string] message_id Message ID to be flagged
283 | # @param [Array] flags Array of custom flags to add
284 | sig { params(message_id: String, flags: T::Array[T.untyped]).returns(StreamChat::StreamResponse) }
285 | def add_custom_message_flags(message_id, flags)
286 | add_custom_flags(T.must(MODERATION_ENTITY_TYPES[:message]), message_id, {}, flags)
287 | end
288 | end
289 | end
290 |
--------------------------------------------------------------------------------
/lib/stream-chat/stream_rate_limits.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | module StreamChat
5 | class StreamRateLimits
6 | extend T::Sig
7 |
8 | sig { returns(Integer) }
9 | attr_reader :limit
10 |
11 | sig { returns(Integer) }
12 | attr_reader :remaining
13 |
14 | sig { returns(Time) }
15 | attr_reader :reset
16 |
17 | sig { params(limit: String, remaining: String, reset: String).void }
18 | def initialize(limit, remaining, reset)
19 | @limit = T.let(limit.to_i, Integer)
20 | @remaining = T.let(remaining.to_i, Integer)
21 | @reset = T.let(Time.at(reset.to_i), Time)
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/stream-chat/stream_response.rb:
--------------------------------------------------------------------------------
1 | # typed: true
2 | # frozen_string_literal: true
3 |
4 | require 'stream-chat/stream_rate_limits'
5 | require 'stream-chat/types'
6 |
7 | module StreamChat
8 | class StreamResponse < Hash
9 | extend T::Sig
10 |
11 | sig { returns(StreamRateLimits) }
12 | attr_reader :rate_limit
13 |
14 | sig { returns(Integer) }
15 | attr_reader :status_code
16 |
17 | sig { returns(StringKeyHash) }
18 | attr_reader :headers
19 |
20 | sig { params(hash: T::Hash[T.untyped, T.untyped], response: Faraday::Response).void }
21 | def initialize(hash, response)
22 | super(nil)
23 | merge!(hash)
24 |
25 | if response.headers.key?('X-Ratelimit-Limit')
26 | @rate_limit = T.let(StreamRateLimits.new(
27 | T.must(response.headers['X-Ratelimit-Limit']),
28 | T.must(response.headers['X-Ratelimit-Remaining']),
29 | T.must(response.headers['X-Ratelimit-Reset'])
30 | ), StreamRateLimits)
31 | end
32 |
33 | @status_code = T.let(response.status, Integer)
34 | @headers = T.let(response.headers, StringKeyHash)
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/lib/stream-chat/types.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | module StreamChat
5 | extend T::Sig
6 |
7 | StringKeyHash = T.type_alias { T::Hash[T.any(String, Symbol), T.untyped] }
8 | SortArray = T.type_alias { T::Array[{ field: String, direction: Integer }] }
9 | end
10 |
--------------------------------------------------------------------------------
/lib/stream-chat/util.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | require 'stream-chat/types'
5 |
6 | module StreamChat
7 | extend T::Sig
8 |
9 | sig { params(sort: T.nilable(T::Hash[String, Integer])).returns(SortArray) }
10 | def self.get_sort_fields(sort)
11 | sort_fields = T.let([], SortArray)
12 | sort&.each do |k, v|
13 | sort_fields << { field: k, direction: v }
14 | end
15 | sort_fields
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/stream-chat/version.rb:
--------------------------------------------------------------------------------
1 | # typed: strict
2 | # frozen_string_literal: true
3 |
4 | module StreamChat
5 | VERSION = '3.15.0'
6 | end
7 |
--------------------------------------------------------------------------------
/scripts/get_changelog_diff.js:
--------------------------------------------------------------------------------
1 | /*
2 | Here we're trying to parse the latest changes from CHANGELOG.md file.
3 | The changelog looks like this:
4 |
5 | ## 0.0.3
6 | - Something #3
7 | ## 0.0.2
8 | - Something #2
9 | ## 0.0.1
10 | - Something #1
11 |
12 | In this case we're trying to extract "- Something #3" since that's the latest change.
13 | */
14 | module.exports = () => {
15 | const fs = require('fs')
16 |
17 | changelog = fs.readFileSync('CHANGELOG.md', 'utf8')
18 | releases = changelog.match(/## [?[0-9](.+)/g)
19 |
20 | current_release = changelog.indexOf(releases[0])
21 | previous_release = changelog.indexOf(releases[1])
22 |
23 | latest_changes = changelog.substr(current_release, previous_release - current_release)
24 |
25 | return latest_changes
26 | }
27 |
--------------------------------------------------------------------------------
/sorbet/config:
--------------------------------------------------------------------------------
1 | --dir
2 | .
3 | --ignore=vendor/bundle,spec
4 | --disable-watchman
--------------------------------------------------------------------------------
/sorbet/rbi/gems/coderay.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: true
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/coderay/all/coderay.rbi
9 | #
10 | # coderay-1.1.3
11 |
12 | module CodeRay
13 | def self.coderay_path(*path); end
14 | def self.encode(code, lang, format, options = nil); end
15 | def self.encode_file(filename, format, options = nil); end
16 | def self.encode_tokens(tokens, format, options = nil); end
17 | def self.encoder(format, options = nil); end
18 | def self.get_scanner_options(options); end
19 | def self.highlight(code, lang, options = nil, format = nil); end
20 | def self.highlight_file(filename, options = nil, format = nil); end
21 | def self.scan(code, lang, options = nil, &block); end
22 | def self.scan_file(filename, lang = nil, options = nil, &block); end
23 | def self.scanner(lang, options = nil, &block); end
24 | end
25 | module CodeRay::FileType
26 | def self.[](filename, read_shebang = nil); end
27 | def self.fetch(filename, default = nil, read_shebang = nil); end
28 | def self.type_from_shebang(filename); end
29 | end
30 | class CodeRay::FileType::UnknownFileType < Exception
31 | end
32 | class CodeRay::Tokens < Array
33 | def begin_group(kind); end
34 | def begin_line(kind); end
35 | def count; end
36 | def encode(encoder, options = nil); end
37 | def end_group(kind); end
38 | def end_line(kind); end
39 | def method_missing(meth, options = nil); end
40 | def scanner; end
41 | def scanner=(arg0); end
42 | def split_into_parts(*sizes); end
43 | def text_token(*arg0); end
44 | def to_s; end
45 | def tokens(*arg0); end
46 | end
47 | class CodeRay::TokensProxy
48 | def block; end
49 | def block=(arg0); end
50 | def each(*args, &blk); end
51 | def encode(encoder, options = nil); end
52 | def initialize(input, lang, options = nil, block = nil); end
53 | def input; end
54 | def input=(arg0); end
55 | def lang; end
56 | def lang=(arg0); end
57 | def method_missing(method, *args, &blk); end
58 | def options; end
59 | def options=(arg0); end
60 | def scanner; end
61 | def tokens; end
62 | end
63 | module CodeRay::PluginHost
64 | def [](id, *args, &blk); end
65 | def all_plugins; end
66 | def const_missing(const); end
67 | def default(id = nil); end
68 | def list; end
69 | def load(id, *args, &blk); end
70 | def load_all; end
71 | def load_plugin_map; end
72 | def make_plugin_hash; end
73 | def map(hash); end
74 | def path_to(plugin_id); end
75 | def plugin_hash; end
76 | def plugin_path(*args); end
77 | def register(plugin, id); end
78 | def self.extended(mod); end
79 | def validate_id(id); end
80 | end
81 | class CodeRay::PluginHost::PluginNotFound < LoadError
82 | end
83 | class CodeRay::PluginHost::HostNotFound < LoadError
84 | end
85 | module CodeRay::Plugin
86 | def aliases; end
87 | def plugin_host(host = nil); end
88 | def plugin_id; end
89 | def register_for(id); end
90 | def title(title = nil); end
91 | end
92 | module CodeRay::Scanners
93 | extend CodeRay::PluginHost
94 | end
95 | class CodeRay::Scanners::Scanner < StringScanner
96 | def binary_string; end
97 | def column(pos = nil); end
98 | def each(&block); end
99 | def file_extension; end
100 | def initialize(code = nil, options = nil); end
101 | def lang; end
102 | def line(pos = nil); end
103 | def raise_inspect(message, tokens, state = nil, ambit = nil, backtrace = nil); end
104 | def raise_inspect_arguments(message, tokens, state, ambit); end
105 | def reset; end
106 | def reset_instance; end
107 | def scan_rest; end
108 | def scan_tokens(tokens, options); end
109 | def scanner_state_info(state); end
110 | def self.encode_with_encoding(code, target_encoding); end
111 | def self.encoding(name = nil); end
112 | def self.file_extension(extension = nil); end
113 | def self.guess_encoding(s); end
114 | def self.lang; end
115 | def self.normalize(code); end
116 | def self.to_unix(code); end
117 | def set_string_from_source(source); end
118 | def set_tokens_from_options(options); end
119 | def setup; end
120 | def state; end
121 | def state=(arg0); end
122 | def string=(code); end
123 | def tokenize(source = nil, options = nil); end
124 | def tokens; end
125 | def tokens_last(tokens, n); end
126 | def tokens_size(tokens); end
127 | extend CodeRay::Plugin
128 | include Enumerable
129 | end
130 | class CodeRay::Scanners::Scanner::ScanError < StandardError
131 | end
132 | class CodeRay::WordList < Hash
133 | def add(words, value = nil); end
134 | def initialize(default = nil); end
135 | end
136 | class CodeRay::WordList::CaseIgnoring < CodeRay::WordList
137 | def [](key); end
138 | def []=(key, value); end
139 | end
140 | module CodeRay::Scanners::Java::BuiltinTypes
141 | end
142 | class CodeRay::Scanners::Java < CodeRay::Scanners::Scanner
143 | def scan_tokens(encoder, options); end
144 | end
145 | class CodeRay::Scanners::Ruby < CodeRay::Scanners::Scanner
146 | def interpreted_string_state; end
147 | def scan_tokens(encoder, options); end
148 | def setup; end
149 | end
150 | module CodeRay::Scanners::Ruby::Patterns
151 | end
152 | class Anonymous_Struct_1 < Struct
153 | def delim; end
154 | def delim=(_); end
155 | def heredoc; end
156 | def heredoc=(_); end
157 | def interpreted; end
158 | def interpreted=(_); end
159 | def next_state; end
160 | def next_state=(_); end
161 | def opening_paren; end
162 | def opening_paren=(_); end
163 | def paren_depth; end
164 | def paren_depth=(_); end
165 | def pattern; end
166 | def pattern=(_); end
167 | def self.[](*arg0); end
168 | def self.inspect; end
169 | def self.members; end
170 | def self.new(*arg0); end
171 | def type; end
172 | def type=(_); end
173 | end
174 | class CodeRay::Scanners::Ruby::StringState < Anonymous_Struct_1
175 | def heredoc_pattern(delim, interpreted, indented); end
176 | def initialize(kind, interpreted, delim, heredoc = nil); end
177 | def self.simple_key_pattern(delim); end
178 | end
179 | module CodeRay::Encoders
180 | extend CodeRay::PluginHost
181 | end
182 | class CodeRay::Encoders::Encoder
183 | def <<(token); end
184 | def begin_group(kind); end
185 | def begin_line(kind); end
186 | def compile(tokens, options = nil); end
187 | def encode(code, lang, options = nil); end
188 | def encode_tokens(tokens, options = nil); end
189 | def end_group(kind); end
190 | def end_line(kind); end
191 | def file_extension; end
192 | def finish(options); end
193 | def get_output(options); end
194 | def highlight(code, lang, options = nil); end
195 | def initialize(options = nil); end
196 | def options; end
197 | def options=(arg0); end
198 | def output(data); end
199 | def scanner; end
200 | def scanner=(arg0); end
201 | def self.const_missing(sym); end
202 | def self.file_extension; end
203 | def setup(options); end
204 | def text_token(text, kind); end
205 | def token(content, kind); end
206 | def tokens(tokens, options = nil); end
207 | extend CodeRay::Plugin
208 | end
209 | class CodeRay::Encoders::HTML < CodeRay::Encoders::Encoder
210 | def begin_group(kind); end
211 | def begin_line(kind); end
212 | def break_lines(text, style); end
213 | def check_group_nesting(name, kind); end
214 | def check_options!(options); end
215 | def close_span; end
216 | def css; end
217 | def css_class_for_kinds(kinds); end
218 | def end_group(kind); end
219 | def end_line(kind); end
220 | def finish(options); end
221 | def make_span_for_kinds(method, hint); end
222 | def self.make_html_escape_hash; end
223 | def self.token_path_to_hint(hint, kinds); end
224 | def setup(options); end
225 | def style_for_kinds(kinds); end
226 | def text_token(text, kind); end
227 | end
228 | module CodeRay::Encoders::HTML::Output
229 | def apply_title!(title); end
230 | def css; end
231 | def css=(arg0); end
232 | def self.extended(o); end
233 | def self.make_stylesheet(css, in_tag = nil); end
234 | def self.page_template_for_css(css); end
235 | def stylesheet(in_tag = nil); end
236 | def wrap!(element, *args); end
237 | def wrap_in!(template); end
238 | def wrapped_in; end
239 | def wrapped_in=(arg0); end
240 | def wrapped_in?(element); end
241 | end
242 | class CodeRay::Encoders::HTML::Output::Template < String
243 | def apply(target, replacement); end
244 | def self.wrap!(str, template, target); end
245 | end
246 | class CodeRay::Encoders::HTML::CSS
247 | def get_style_for_css_classes(css_classes); end
248 | def initialize(style = nil); end
249 | def parse(stylesheet); end
250 | def self.load_stylesheet(style = nil); end
251 | def stylesheet; end
252 | end
253 | module CodeRay::Encoders::HTML::Numbering
254 | def self.number!(output, mode = nil, options = nil); end
255 | end
256 | module CodeRay::Styles
257 | extend CodeRay::PluginHost
258 | end
259 | class CodeRay::Styles::Style
260 | extend CodeRay::Plugin
261 | end
262 | class CodeRay::Duo
263 | def call(code, options = nil); end
264 | def encode(code, options = nil); end
265 | def encoder; end
266 | def format; end
267 | def format=(arg0); end
268 | def highlight(code, options = nil); end
269 | def initialize(lang = nil, format = nil, options = nil); end
270 | def lang; end
271 | def lang=(arg0); end
272 | def options; end
273 | def options=(arg0); end
274 | def scanner; end
275 | def self.[](*arg0); end
276 | end
277 | class CodeRay::Encoders::Terminal < CodeRay::Encoders::Encoder
278 | def begin_group(kind); end
279 | def begin_line(kind); end
280 | def end_group(kind); end
281 | def end_line(kind); end
282 | def open_token(kind); end
283 | def setup(options); end
284 | def text_token(text, kind); end
285 | end
286 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/connection_pool.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/connection_pool/all/connection_pool.rbi
9 | #
10 | # connection_pool-2.2.5
11 |
12 | class ConnectionPool
13 | def available; end
14 | def checkin; end
15 | def checkout(options = nil); end
16 | def initialize(options = nil, &block); end
17 | def reload(&block); end
18 | def self.wrap(options, &block); end
19 | def shutdown(&block); end
20 | def size; end
21 | def then(options = nil); end
22 | def with(options = nil); end
23 | end
24 | class ConnectionPool::TimedStack
25 | def <<(obj, options = nil); end
26 | def connection_stored?(options = nil); end
27 | def current_time; end
28 | def empty?; end
29 | def fetch_connection(options = nil); end
30 | def initialize(size = nil, &block); end
31 | def length; end
32 | def max; end
33 | def pop(timeout = nil, options = nil); end
34 | def push(obj, options = nil); end
35 | def shutdown(reload: nil, &block); end
36 | def shutdown_connections(options = nil); end
37 | def store_connection(obj, options = nil); end
38 | def try_create(options = nil); end
39 | end
40 | class ConnectionPool::Wrapper < BasicObject
41 | def initialize(options = nil, &block); end
42 | def method_missing(name, *args, &block); end
43 | def pool_available; end
44 | def pool_shutdown(&block); end
45 | def pool_size; end
46 | def respond_to?(id, *args); end
47 | def with(&block); end
48 | def wrapped_pool; end
49 | end
50 | class ConnectionPool::Error < RuntimeError
51 | end
52 | class ConnectionPool::PoolShuttingDownError < ConnectionPool::Error
53 | end
54 | class ConnectionPool::TimeoutError < Timeout::Error
55 | end
56 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/docile.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/docile/all/docile.rbi
9 | #
10 | # docile-1.4.0
11 |
12 | module Docile
13 | def dsl_eval(dsl, *args, &block); end
14 | def dsl_eval_immutable(dsl, *args, &block); end
15 | def dsl_eval_with_block_return(dsl, *args, &block); end
16 | def self.dsl_eval(dsl, *args, &block); end
17 | def self.dsl_eval_immutable(dsl, *args, &block); end
18 | def self.dsl_eval_with_block_return(dsl, *args, &block); end
19 | extend Docile::Execution
20 | end
21 | module Docile::Execution
22 | def exec_in_proxy_context(dsl, proxy_type, *args, &block); end
23 | def self.exec_in_proxy_context(dsl, proxy_type, *args, &block); end
24 | end
25 | class Docile::FallbackContextProxy
26 | def initialize(receiver, fallback); end
27 | def instance_variables; end
28 | def method_missing(method, *args, &block); end
29 | end
30 | class Docile::ChainingFallbackContextProxy < Docile::FallbackContextProxy
31 | def method_missing(method, *args, &block); end
32 | end
33 | module Docile::BacktraceFilter
34 | def backtrace; end
35 | def backtrace_locations; end
36 | end
37 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-em_http.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-em_http/all/faraday-em_http.rbi
9 | #
10 | # faraday-em_http-1.0.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::EMHttp < Faraday::Adapter
17 | def call(env); end
18 | def create_request(env); end
19 | def error_message(client); end
20 | def parallel?(env); end
21 | def perform_request(env); end
22 | def perform_single_request(env); end
23 | def raise_error(msg); end
24 | def self.setup_parallel_manager(_options = nil); end
25 | def timeout_message?(msg); end
26 | include Faraday::Adapter::EMHttp::Options
27 | end
28 | module Faraday::Adapter::EMHttp::Options
29 | def configure_compression(options, env); end
30 | def configure_proxy(options, env); end
31 | def configure_socket(options, env); end
32 | def configure_ssl(options, env); end
33 | def configure_timeout(options, env); end
34 | def connection_config(env); end
35 | def read_body(env); end
36 | def request_config(env); end
37 | def request_options(env); end
38 | end
39 | class Faraday::Adapter::EMHttp::Manager
40 | def add(&block); end
41 | def check_finished; end
42 | def initialize; end
43 | def perform_request; end
44 | def reset; end
45 | def run; end
46 | def running?; end
47 | end
48 | module Faraday::EmHttp
49 | end
50 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-em_synchrony.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-em_synchrony/all/faraday-em_synchrony.rbi
9 | #
10 | # faraday-em_synchrony-1.0.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::EMSynchrony < Faraday::Adapter
17 | def call(env); end
18 | def call_block(block); end
19 | def create_request(env); end
20 | def execute_parallel_request(env, request, http_method); end
21 | def execute_single_request(env, request, http_method); end
22 | def self.setup_parallel_manager(_options = nil); end
23 | include Faraday::Adapter::EMHttp::Options
24 | end
25 | module Faraday::EmSynchrony
26 | end
27 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-excon.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-excon/all/faraday-excon.rbi
9 | #
10 | # faraday-excon-1.1.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::Excon < Faraday::Adapter
17 | def amend_opts_with_proxy_settings!(opts, req); end
18 | def amend_opts_with_ssl!(opts, ssl); end
19 | def amend_opts_with_timeouts!(opts, req); end
20 | def build_connection(env); end
21 | def call(env); end
22 | def needs_ssl_settings?(env); end
23 | def opts_from_env(env); end
24 | def proxy_settings_for_opts(proxy); end
25 | def read_body(env); end
26 | end
27 | module Faraday::Excon
28 | end
29 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-httpclient.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-httpclient/all/faraday-httpclient.rbi
9 | #
10 | # faraday-httpclient-1.0.1
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::HTTPClient < Faraday::Adapter
17 | def build_connection(env); end
18 | def call(env); end
19 | def configure_client(client); end
20 | def configure_proxy(client, proxy); end
21 | def configure_socket(client, bind); end
22 | def configure_ssl(client, ssl); end
23 | def configure_timeouts(client, req); end
24 | def ssl_cert_store(ssl); end
25 | def ssl_verify_mode(ssl); end
26 | end
27 | module Faraday::HTTPClient
28 | end
29 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-multipart.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-multipart/all/faraday-multipart.rbi
9 | #
10 | # faraday-multipart-1.0.3
11 |
12 | module Faraday
13 | end
14 | module Faraday::Multipart
15 | end
16 | class Faraday::Multipart::CompositeReadIO
17 | def advance_io; end
18 | def close; end
19 | def current_io; end
20 | def ensure_open_and_readable; end
21 | def initialize(*parts); end
22 | def length; end
23 | def read(length = nil, outbuf = nil); end
24 | def rewind; end
25 | end
26 | class Faraday::Multipart::ParamPart
27 | def content_id; end
28 | def content_type; end
29 | def headers; end
30 | def initialize(value, content_type, content_id = nil); end
31 | def to_part(boundary, key); end
32 | def value; end
33 | end
34 | class Faraday::Multipart::Middleware < Faraday::Request::UrlEncoded
35 | def call(env); end
36 | def create_multipart(env, params); end
37 | def has_multipart?(obj); end
38 | def initialize(app = nil, options = nil); end
39 | def part(boundary, key, value); end
40 | def process_params(params, prefix = nil, pieces = nil, &block); end
41 | def process_request?(env); end
42 | def unique_boundary; end
43 | end
44 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-net_http.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-net_http/all/faraday-net_http.rbi
9 | #
10 | # faraday-net_http-1.0.1
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::NetHttp < Faraday::Adapter
17 | def build_connection(env); end
18 | def call(env); end
19 | def configure_request(http, req); end
20 | def configure_ssl(http, ssl); end
21 | def create_request(env); end
22 | def initialize(app = nil, opts = nil, &block); end
23 | def net_http_connection(env); end
24 | def perform_request(http, env); end
25 | def request_via_get_method(http, env, &block); end
26 | def request_via_request_method(http, env, &block); end
27 | def request_with_wrapped_block(http, env, &block); end
28 | def ssl_cert_store(ssl); end
29 | def ssl_verify_mode(ssl); end
30 | end
31 | module Faraday::NetHttp
32 | end
33 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-net_http_persistent.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-net_http_persistent/all/faraday-net_http_persistent.rbi
9 | #
10 | # faraday-net_http_persistent-1.2.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::NetHttpPersistent < Faraday::Adapter::NetHttp
17 | def configure_ssl(http, ssl); end
18 | def http_set(http, attr, value); end
19 | def net_http_connection(env); end
20 | def perform_request(http, env); end
21 | def proxy_uri(env); end
22 | end
23 | module Faraday::NetHttpPersistent
24 | end
25 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-patron.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-patron/all/faraday-patron.rbi
9 | #
10 | # faraday-patron-1.0.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::Patron < Faraday::Adapter
17 | def build_connection(env); end
18 | def call(env); end
19 | def configure_proxy(session, proxy); end
20 | def configure_ssl(session, ssl); end
21 | def configure_timeouts(session, req); end
22 | def connection_timed_out_message?(message); end
23 | end
24 | module Faraday::Patron
25 | end
26 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/faraday-rack.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/faraday-rack/all/faraday-rack.rbi
9 | #
10 | # faraday-rack-1.0.0
11 |
12 | module Faraday
13 | end
14 | class Faraday::Adapter
15 | end
16 | class Faraday::Adapter::Rack < Faraday::Adapter
17 | def build_rack_env(env); end
18 | def call(env); end
19 | def execute_request(env, rack_env); end
20 | def initialize(faraday_app, rack_app); end
21 | end
22 | module Faraday::Rack
23 | end
24 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/jwt.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: true
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/jwt/all/jwt.rbi
9 | #
10 | # jwt-2.3.0
11 |
12 | module JWT
13 | def decode(jwt, key = nil, verify = nil, options = nil, &keyfinder); end
14 | def encode(payload, key, algorithm = nil, header_fields = nil); end
15 | def self.decode(jwt, key = nil, verify = nil, options = nil, &keyfinder); end
16 | def self.encode(payload, key, algorithm = nil, header_fields = nil); end
17 | include JWT::DefaultOptions
18 | end
19 | class JWT::Base64
20 | def self.url_decode(str); end
21 | def self.url_encode(str); end
22 | end
23 | class JWT::JSON
24 | def self.generate(data); end
25 | def self.parse(data); end
26 | end
27 | module JWT::SecurityUtils
28 | def asn1_to_raw(signature, public_key); end
29 | def raw_to_asn1(signature, private_key); end
30 | def rbnacl_fixup(algorithm, key); end
31 | def secure_compare(left, right); end
32 | def self.asn1_to_raw(signature, public_key); end
33 | def self.raw_to_asn1(signature, private_key); end
34 | def self.rbnacl_fixup(algorithm, key); end
35 | def self.secure_compare(left, right); end
36 | def self.verify_ps(algorithm, public_key, signing_input, signature); end
37 | def self.verify_rsa(algorithm, public_key, signing_input, signature); end
38 | def verify_ps(algorithm, public_key, signing_input, signature); end
39 | def verify_rsa(algorithm, public_key, signing_input, signature); end
40 | end
41 | module JWT::Algos
42 | def find(algorithm); end
43 | def indexed; end
44 | extend JWT::Algos
45 | end
46 | module JWT::Algos::Hmac
47 | def self.sign(to_sign); end
48 | def self.verify(to_verify); end
49 | def sign(to_sign); end
50 | def verify(to_verify); end
51 | end
52 | module JWT::Algos::Eddsa
53 | def self.sign(to_sign); end
54 | def self.verify(to_verify); end
55 | def sign(to_sign); end
56 | def verify(to_verify); end
57 | end
58 | module JWT::Algos::Ecdsa
59 | def self.sign(to_sign); end
60 | def self.verify(to_verify); end
61 | def sign(to_sign); end
62 | def verify(to_verify); end
63 | end
64 | module JWT::Algos::Rsa
65 | def self.sign(to_sign); end
66 | def self.verify(to_verify); end
67 | def sign(to_sign); end
68 | def verify(to_verify); end
69 | end
70 | module JWT::Algos::Ps
71 | def require_openssl!; end
72 | def self.require_openssl!; end
73 | def self.sign(to_sign); end
74 | def self.verify(to_verify); end
75 | def sign(to_sign); end
76 | def verify(to_verify); end
77 | end
78 | module JWT::Algos::None
79 | def self.sign(*arg0); end
80 | def self.verify(*arg0); end
81 | def sign(*arg0); end
82 | def verify(*arg0); end
83 | end
84 | module JWT::Algos::Unsupported
85 | def self.sign(*arg0); end
86 | def self.verify(*arg0); end
87 | def sign(*arg0); end
88 | def verify(*arg0); end
89 | end
90 | module JWT::Signature
91 | def sign(algorithm, msg, key); end
92 | def verify(algorithm, key, signing_input, signature); end
93 | extend JWT::Signature
94 | end
95 | class JWT::Signature::ToSign < Struct
96 | def algorithm; end
97 | def algorithm=(_); end
98 | def key; end
99 | def key=(_); end
100 | def msg; end
101 | def msg=(_); end
102 | def self.[](*arg0); end
103 | def self.inspect; end
104 | def self.members; end
105 | def self.new(*arg0); end
106 | end
107 | class JWT::Signature::ToVerify < Struct
108 | def algorithm; end
109 | def algorithm=(_); end
110 | def public_key; end
111 | def public_key=(_); end
112 | def self.[](*arg0); end
113 | def self.inspect; end
114 | def self.members; end
115 | def self.new(*arg0); end
116 | def signature; end
117 | def signature=(_); end
118 | def signing_input; end
119 | def signing_input=(_); end
120 | end
121 | class JWT::EncodeError < StandardError
122 | end
123 | class JWT::DecodeError < StandardError
124 | end
125 | class JWT::RequiredDependencyError < StandardError
126 | end
127 | class JWT::VerificationError < JWT::DecodeError
128 | end
129 | class JWT::ExpiredSignature < JWT::DecodeError
130 | end
131 | class JWT::IncorrectAlgorithm < JWT::DecodeError
132 | end
133 | class JWT::ImmatureSignature < JWT::DecodeError
134 | end
135 | class JWT::InvalidIssuerError < JWT::DecodeError
136 | end
137 | class JWT::InvalidIatError < JWT::DecodeError
138 | end
139 | class JWT::InvalidAudError < JWT::DecodeError
140 | end
141 | class JWT::InvalidSubError < JWT::DecodeError
142 | end
143 | class JWT::InvalidJtiError < JWT::DecodeError
144 | end
145 | class JWT::InvalidPayload < JWT::DecodeError
146 | end
147 | class JWT::MissingRequiredClaim < JWT::DecodeError
148 | end
149 | class JWT::JWKError < JWT::DecodeError
150 | end
151 | class JWT::Verify
152 | def exp_leeway; end
153 | def global_leeway; end
154 | def initialize(payload, options); end
155 | def nbf_leeway; end
156 | def self.verify_aud(payload, options); end
157 | def self.verify_claims(payload, options); end
158 | def self.verify_expiration(payload, options); end
159 | def self.verify_iat(payload, options); end
160 | def self.verify_iss(payload, options); end
161 | def self.verify_jti(payload, options); end
162 | def self.verify_not_before(payload, options); end
163 | def self.verify_required_claims(payload, options); end
164 | def self.verify_sub(payload, options); end
165 | def verify_aud; end
166 | def verify_expiration; end
167 | def verify_iat; end
168 | def verify_iss; end
169 | def verify_jti; end
170 | def verify_not_before; end
171 | def verify_required_claims; end
172 | def verify_sub; end
173 | end
174 | class JWT::Decode
175 | def allowed_algorithms; end
176 | def decode_crypto; end
177 | def decode_segments; end
178 | def find_key(&keyfinder); end
179 | def header; end
180 | def initialize(jwt, key, verify, options, &keyfinder); end
181 | def options_includes_algo_in_header?; end
182 | def parse_and_decode(segment); end
183 | def payload; end
184 | def segment_length; end
185 | def signing_input; end
186 | def validate_segment_count!; end
187 | def verify_claims; end
188 | def verify_signature; end
189 | end
190 | module JWT::DefaultOptions
191 | end
192 | class JWT::ClaimsValidator
193 | def initialize(payload); end
194 | def validate!; end
195 | def validate_is_numeric(claim); end
196 | def validate_numeric_claims; end
197 | end
198 | class JWT::Encode
199 | def combine(*parts); end
200 | def encode(data); end
201 | def encode_header; end
202 | def encode_payload; end
203 | def encode_signature; end
204 | def encoded_header; end
205 | def encoded_header_and_payload; end
206 | def encoded_payload; end
207 | def encoded_signature; end
208 | def initialize(options); end
209 | def segments; end
210 | end
211 | module JWT::JWK
212 | def self.classes; end
213 | def self.create_from(keypair, kid = nil); end
214 | def self.generate_mappings; end
215 | def self.import(jwk_data); end
216 | def self.mappings; end
217 | def self.new(keypair, kid = nil); end
218 | end
219 | class JWT::JWK::KeyFinder
220 | def find_key(kid); end
221 | def initialize(options); end
222 | def jwks; end
223 | def jwks_keys; end
224 | def key_for(kid); end
225 | def load_keys(opts = nil); end
226 | def reloadable?; end
227 | def resolve_key(kid); end
228 | end
229 | class JWT::JWK::KeyBase
230 | def initialize(keypair, kid = nil); end
231 | def keypair; end
232 | def kid; end
233 | def self.inherited(klass); end
234 | end
235 | class JWT::JWK::EC < JWT::JWK::KeyBase
236 | def append_private_parts(the_hash); end
237 | def encode_octets(octets); end
238 | def encode_open_ssl_bn(key_part); end
239 | def export(options = nil); end
240 | def generate_kid(ec_keypair); end
241 | def initialize(keypair, kid = nil); end
242 | def keypair_components(ec_keypair); end
243 | def private?; end
244 | def public_key(*args, &block); end
245 | def self.decode_octets(jwk_data); end
246 | def self.decode_open_ssl_bn(jwk_data); end
247 | def self.ec_pkey(jwk_crv, jwk_x, jwk_y, jwk_d); end
248 | def self.import(jwk_data); end
249 | def self.jwk_attrs(jwk_data, attrs); end
250 | def self.to_openssl_curve(crv); end
251 | extend Forwardable
252 | end
253 | class JWT::JWK::RSA < JWT::JWK::KeyBase
254 | def append_private_parts(the_hash); end
255 | def encode_open_ssl_bn(key_part); end
256 | def export(options = nil); end
257 | def generate_kid(public_key); end
258 | def initialize(keypair, kid = nil); end
259 | def private?; end
260 | def public_key; end
261 | def self.decode_open_ssl_bn(jwk_data); end
262 | def self.import(jwk_data); end
263 | def self.jwk_attributes(jwk_data, *attributes); end
264 | def self.populate_key(rsa_key, rsa_parameters); end
265 | def self.rsa_pkey(rsa_parameters); end
266 | end
267 | class JWT::JWK::HMAC < JWT::JWK::KeyBase
268 | def export(options = nil); end
269 | def generate_kid; end
270 | def initialize(keypair, kid = nil); end
271 | def private?; end
272 | def public_key; end
273 | def self.import(jwk_data); end
274 | end
275 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/method_source.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/method_source/all/method_source.rbi
9 | #
10 | # method_source-1.0.0
11 |
12 | module MethodSource
13 | def self.comment_helper(source_location, name = nil); end
14 | def self.extract_code(source_location); end
15 | def self.lines_for(file_name, name = nil); end
16 | def self.source_helper(source_location, name = nil); end
17 | def self.valid_expression?(str); end
18 | extend MethodSource::CodeHelpers
19 | end
20 | module MethodSource::ReeSourceLocation
21 | def source_location; end
22 | end
23 | module MethodSource::SourceLocation
24 | end
25 | module MethodSource::SourceLocation::MethodExtensions
26 | def source_location; end
27 | def trace_func(event, file, line, id, binding, classname); end
28 | end
29 | module MethodSource::SourceLocation::ProcExtensions
30 | def source_location; end
31 | end
32 | module MethodSource::SourceLocation::UnboundMethodExtensions
33 | def source_location; end
34 | end
35 | module MethodSource::CodeHelpers
36 | def comment_describing(file, line_number); end
37 | def complete_expression?(str); end
38 | def expression_at(file, line_number, options = nil); end
39 | def extract_first_expression(lines, consume = nil, &block); end
40 | def extract_last_comment(lines); end
41 | end
42 | module MethodSource::CodeHelpers::IncompleteExpression
43 | def self.===(ex); end
44 | def self.rbx?; end
45 | end
46 | class MethodSource::SourceNotFoundError < StandardError
47 | end
48 | module MethodSource::MethodExtensions
49 | def comment; end
50 | def self.included(klass); end
51 | def source; end
52 | end
53 | class Method
54 | include MethodSource::MethodExtensions
55 | include MethodSource::SourceLocation::MethodExtensions
56 | end
57 | class UnboundMethod
58 | include MethodSource::MethodExtensions
59 | include MethodSource::SourceLocation::UnboundMethodExtensions
60 | end
61 | class Proc
62 | include MethodSource::MethodExtensions
63 | include MethodSource::SourceLocation::ProcExtensions
64 | end
65 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/multipart-post.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/multipart-post/all/multipart-post.rbi
9 | #
10 | # multipart-post-2.1.1
11 |
12 | class CompositeReadIO
13 | def advance_io; end
14 | def current_io; end
15 | def initialize(*ios); end
16 | def read(length = nil, outbuf = nil); end
17 | def rewind; end
18 | end
19 | class UploadIO
20 | def content_type; end
21 | def initialize(filename_or_io, content_type, filename = nil, opts = nil); end
22 | def io; end
23 | def local_path; end
24 | def method_missing(*args); end
25 | def opts; end
26 | def original_filename; end
27 | def respond_to?(meth, include_all = nil); end
28 | def self.convert!(io, content_type, original_filename, local_path); end
29 | end
30 | module Parts
31 | end
32 | module Parts::Part
33 | def length; end
34 | def self.file?(value); end
35 | def self.new(boundary, name, value, headers = nil); end
36 | def to_io; end
37 | end
38 | class Parts::ParamPart
39 | def build_part(boundary, name, value, headers = nil); end
40 | def initialize(boundary, name, value, headers = nil); end
41 | def length; end
42 | include Parts::Part
43 | end
44 | class Parts::FilePart
45 | def build_head(boundary, name, filename, type, content_len, opts = nil); end
46 | def initialize(boundary, name, io, headers = nil); end
47 | def length; end
48 | include Parts::Part
49 | end
50 | class Parts::EpiloguePart
51 | def initialize(boundary); end
52 | include Parts::Part
53 | end
54 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/net-http-persistent.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/net-http-persistent/all/net-http-persistent.rbi
9 | #
10 | # net-http-persistent-4.0.1
11 |
12 | class Net::HTTP::Persistent::Connection
13 | def finish; end
14 | def http; end
15 | def http=(arg0); end
16 | def initialize(http_class, http_args, ssl_generation); end
17 | def last_use; end
18 | def last_use=(arg0); end
19 | def requests; end
20 | def requests=(arg0); end
21 | def reset; end
22 | def ressl(ssl_generation); end
23 | def ssl_generation; end
24 | def ssl_generation=(arg0); end
25 | end
26 | class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack
27 | def connection_stored?(options = nil); end
28 | def empty?; end
29 | def fetch_connection(options = nil); end
30 | def initialize(size = nil, &block); end
31 | def length; end
32 | def lru_update(connection_args); end
33 | def self.hash_of_arrays; end
34 | def shutdown_connections; end
35 | def store_connection(obj, options = nil); end
36 | def try_create(options = nil); end
37 | end
38 | class Net::HTTP::Persistent::Pool < ConnectionPool
39 | def available; end
40 | def checkin(net_http_args); end
41 | def checkout(net_http_args); end
42 | def initialize(options = nil, &block); end
43 | def key; end
44 | def shutdown; end
45 | end
46 | class Net::HTTP::Persistent
47 | def ca_file; end
48 | def ca_file=(file); end
49 | def ca_path; end
50 | def ca_path=(path); end
51 | def cert; end
52 | def cert=(certificate); end
53 | def cert_store; end
54 | def cert_store=(store); end
55 | def certificate; end
56 | def certificate=(certificate); end
57 | def ciphers; end
58 | def ciphers=(ciphers); end
59 | def connection_for(uri); end
60 | def debug_output; end
61 | def debug_output=(arg0); end
62 | def escape(str); end
63 | def expired?(connection); end
64 | def finish(connection); end
65 | def generation; end
66 | def headers; end
67 | def http_version(uri); end
68 | def http_versions; end
69 | def idle_timeout; end
70 | def idle_timeout=(arg0); end
71 | def initialize(name: nil, proxy: nil, pool_size: nil); end
72 | def keep_alive; end
73 | def keep_alive=(arg0); end
74 | def key; end
75 | def key=(key); end
76 | def max_requests; end
77 | def max_requests=(arg0); end
78 | def max_retries; end
79 | def max_retries=(retries); end
80 | def max_version; end
81 | def max_version=(max_version); end
82 | def min_version; end
83 | def min_version=(min_version); end
84 | def name; end
85 | def no_proxy; end
86 | def normalize_uri(uri); end
87 | def open_timeout; end
88 | def open_timeout=(arg0); end
89 | def override_headers; end
90 | def pipeline(uri, requests, &block); end
91 | def pool; end
92 | def private_key; end
93 | def private_key=(key); end
94 | def proxy=(proxy); end
95 | def proxy_bypass?(host, port); end
96 | def proxy_from_env; end
97 | def proxy_uri; end
98 | def read_timeout; end
99 | def read_timeout=(arg0); end
100 | def reconnect; end
101 | def reconnect_ssl; end
102 | def request(uri, req = nil, &block); end
103 | def request_setup(req_or_uri); end
104 | def reset(connection); end
105 | def reuse_ssl_sessions; end
106 | def reuse_ssl_sessions=(arg0); end
107 | def self.detect_idle_timeout(uri, max = nil); end
108 | def shutdown; end
109 | def socket_options; end
110 | def ssl(connection); end
111 | def ssl_generation; end
112 | def ssl_timeout; end
113 | def ssl_timeout=(ssl_timeout); end
114 | def ssl_version; end
115 | def ssl_version=(ssl_version); end
116 | def start(http); end
117 | def timeout_key; end
118 | def unescape(str); end
119 | def verify_callback; end
120 | def verify_callback=(callback); end
121 | def verify_depth; end
122 | def verify_depth=(verify_depth); end
123 | def verify_mode; end
124 | def verify_mode=(verify_mode); end
125 | def write_timeout; end
126 | def write_timeout=(arg0); end
127 | end
128 | class Net::HTTP::Persistent::Error < StandardError
129 | end
130 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/pry-doc.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: true
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/pry-doc/all/pry-doc.rbi
9 | #
10 | # pry-doc-1.2.0
11 |
12 | module PryDoc
13 | def self.load_yardoc(version); end
14 | def self.root; end
15 | end
16 | module Pry::CInternals
17 | end
18 | class Pry::CInternals::SymbolExtractor
19 | def balanced?(str); end
20 | def complete_function_signature?(str); end
21 | def extract(info); end
22 | def extract_code(info, offset: nil, start_line: nil, direction: nil, &block); end
23 | def extract_function(info); end
24 | def extract_macro(info); end
25 | def extract_oneliner(info); end
26 | def extract_struct(info); end
27 | def extract_typedef_struct(info); end
28 | def function_return_type?(str); end
29 | def initialize(ruby_source_folder); end
30 | def self.file_cache; end
31 | def self.file_cache=(arg0); end
32 | def source_from_file(file); end
33 | def token_count(tokens, token); end
34 | end
35 | class Pry::CInternals::ETagParser
36 | def clean_file_name(file_name); end
37 | def file_name_and_content_for(c_file_section); end
38 | def initialize(tags_path, ruby_source_folder); end
39 | def parse_tagfile; end
40 | def ruby_source_folder; end
41 | def self.symbol_map_for(tags_path, ruby_source_folder); end
42 | def symbol_map; end
43 | def tagfile; end
44 | def tags_path; end
45 | end
46 | class Pry::CInternals::ETagParser::CFile
47 | def cleanup_linenumber(line_number); end
48 | def cleanup_symbol(symbol); end
49 | def file_name; end
50 | def file_name=(arg0); end
51 | def full_path_for(file_name); end
52 | def initialize(file_name: nil, content: nil, ruby_source_folder: nil); end
53 | def ruby_source_folder; end
54 | def source_location_for(symbol, line_number); end
55 | def symbol_map; end
56 | def symbol_type_for(symbol); end
57 | def windows?; end
58 | end
59 | class Pry::CInternals::ETagParser::SourceLocation < Struct
60 | def file; end
61 | def file=(_); end
62 | def line; end
63 | def line=(_); end
64 | def self.[](*arg0); end
65 | def self.inspect; end
66 | def self.members; end
67 | def self.new(*arg0); end
68 | def symbol_type; end
69 | def symbol_type=(_); end
70 | end
71 | class Pry::CInternals::RubySourceInstaller
72 | def arch; end
73 | def ask_for_install; end
74 | def check_for_error(message, &block); end
75 | def curl_cmd; end
76 | def curl_cmd=(arg0); end
77 | def download_ruby; end
78 | def etag_binary; end
79 | def etag_binary=(arg0); end
80 | def etag_cmd; end
81 | def etag_cmd=(arg0); end
82 | def generate_tagfile; end
83 | def initialize(ruby_version, ruby_source_folder); end
84 | def install; end
85 | def linux?; end
86 | def ruby_source_folder; end
87 | def ruby_version; end
88 | def set_platform_specific_commands; end
89 | def windows?; end
90 | end
91 | class Pry::CInternals::CodeFetcher
92 | def fetch_all_definitions(symbol); end
93 | def fetch_first_definition(symbol, index = nil); end
94 | def initialize(line_number_style: nil); end
95 | def line_number_style; end
96 | def self.ruby_source_folder; end
97 | def self.ruby_source_folder=(arg0); end
98 | def self.ruby_source_installer; end
99 | def self.ruby_source_installer=(arg0); end
100 | def self.ruby_version; end
101 | def self.symbol_map; end
102 | def self.symbol_map=(arg0); end
103 | def start_line_for(line); end
104 | def symbol_extractor; end
105 | def use_line_numbers?; end
106 | include Pry::Helpers::Text
107 | end
108 | class Pry::CInternals::ShowSourceWithCInternals < Pry::Command::ShowSource
109 | def line_number_style; end
110 | def options(opt); end
111 | def process; end
112 | def show_c_source; end
113 | end
114 | class Pry
115 | end
116 | module Pry::MethodInfo
117 | def self.aliases(meth); end
118 | def self.cache(meth); end
119 | def self.find_gem_dir(meth); end
120 | def self.gem_dir_from_method(meth); end
121 | def self.gem_root(dir); end
122 | def self.guess_gem_name(name); end
123 | def self.info_for(meth); end
124 | def self.is_singleton?(meth); end
125 | def self.method_host(meth); end
126 | def self.namespace_name(host); end
127 | def self.parse_and_cache_if_gem_cext(meth); end
128 | def self.receiver_notation_for(meth); end
129 | def self.registry_lookup(meth); end
130 | end
131 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/rspec-support.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: true
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/rspec-support/all/rspec-support.rbi
9 | #
10 | # rspec-support-3.10.3
11 |
12 | module RSpec
13 | extend RSpec::Support::Warnings
14 | end
15 | module RSpec::Support
16 | def self.class_of(object); end
17 | def self.define_optimized_require_for_rspec(lib, &require_relative); end
18 | def self.deregister_matcher_definition(&block); end
19 | def self.failure_notifier; end
20 | def self.failure_notifier=(callable); end
21 | def self.is_a_matcher?(object); end
22 | def self.matcher_definitions; end
23 | def self.method_handle_for(object, method_name); end
24 | def self.notify_failure(failure, options = nil); end
25 | def self.register_matcher_definition(&block); end
26 | def self.require_rspec_support(f); end
27 | def self.rspec_description_for_object(object); end
28 | def self.thread_local_data; end
29 | def self.warning_notifier; end
30 | def self.warning_notifier=(arg0); end
31 | def self.with_failure_notifier(callable); end
32 | end
33 | module RSpec::Support::Version
34 | end
35 | class RSpec::Support::ComparableVersion
36 | def <=>(other); end
37 | def initialize(string); end
38 | def segments; end
39 | def string; end
40 | include Comparable
41 | end
42 | module RSpec::Support::OS
43 | def self.windows?; end
44 | def self.windows_file_path?; end
45 | def windows?; end
46 | def windows_file_path?; end
47 | end
48 | module RSpec::Support::Ruby
49 | def jruby?; end
50 | def jruby_9000?; end
51 | def jruby_version; end
52 | def mri?; end
53 | def non_mri?; end
54 | def rbx?; end
55 | def self.jruby?; end
56 | def self.jruby_9000?; end
57 | def self.jruby_version; end
58 | def self.mri?; end
59 | def self.non_mri?; end
60 | def self.rbx?; end
61 | def self.truffleruby?; end
62 | def truffleruby?; end
63 | end
64 | module RSpec::Support::RubyFeatures
65 | def caller_locations_supported?; end
66 | def fork_supported?; end
67 | def kw_args_supported?; end
68 | def module_prepends_supported?; end
69 | def module_refinement_supported?; end
70 | def optional_and_splat_args_supported?; end
71 | def required_kw_args_supported?; end
72 | def ripper_supported?; end
73 | def self.caller_locations_supported?; end
74 | def self.fork_supported?; end
75 | def self.kw_args_supported?; end
76 | def self.module_prepends_supported?; end
77 | def self.module_refinement_supported?; end
78 | def self.optional_and_splat_args_supported?; end
79 | def self.required_kw_args_supported?; end
80 | def self.ripper_supported?; end
81 | def self.supports_exception_cause?; end
82 | def self.supports_rebinding_module_methods?; end
83 | def self.supports_taint?; end
84 | def supports_exception_cause?; end
85 | def supports_rebinding_module_methods?; end
86 | def supports_taint?; end
87 | end
88 | module RSpec::Support::AllExceptionsExceptOnesWeMustNotRescue
89 | def self.===(exception); end
90 | end
91 | class RSpec::CallerFilter
92 | def self.first_non_rspec_line(skip_frames = nil, increment = nil); end
93 | end
94 | module RSpec::Support::Warnings
95 | def deprecate(deprecated, options = nil); end
96 | def warn_deprecation(message, options = nil); end
97 | def warn_with(message, options = nil); end
98 | def warning(text, options = nil); end
99 | end
100 | class RSpec::Support::EncodedString
101 | def <<(string); end
102 | def ==(*args, &block); end
103 | def detect_source_encoding(string); end
104 | def empty?(*args, &block); end
105 | def encoding(*args, &block); end
106 | def eql?(*args, &block); end
107 | def initialize(string, encoding = nil); end
108 | def lines(*args, &block); end
109 | def matching_encoding(string); end
110 | def remove_invalid_bytes(string); end
111 | def self.pick_encoding(source_a, source_b); end
112 | def source_encoding; end
113 | def split(regex_or_string); end
114 | def to_s; end
115 | def to_str; end
116 | end
117 | class RSpec::Support::ReentrantMutex
118 | def enter; end
119 | def exit; end
120 | def initialize; end
121 | def synchronize; end
122 | end
123 | class RSpec::Support::Mutex < Thread::Mutex
124 | def self.new; end
125 | end
126 | class RSpec::Support::DirectoryMaker
127 | def self.directory_exists?(dirname); end
128 | def self.generate_path(stack, part); end
129 | def self.generate_stack(path); end
130 | def self.mkdir_p(path); end
131 | end
132 | class RSpec::Support::MethodSignature
133 | def arbitrary_kw_args?; end
134 | def classify_arity(arity = nil); end
135 | def classify_parameters; end
136 | def could_contain_kw_args?(args); end
137 | def description; end
138 | def has_kw_args_in?(args); end
139 | def initialize(method); end
140 | def invalid_kw_args_from(given_kw_args); end
141 | def max_non_kw_args; end
142 | def min_non_kw_args; end
143 | def missing_kw_args_from(given_kw_args); end
144 | def non_kw_args_arity_description; end
145 | def optional_kw_args; end
146 | def required_kw_args; end
147 | def unlimited_args?; end
148 | def valid_non_kw_args?(positional_arg_count, optional_max_arg_count = nil); end
149 | end
150 | class RSpec::Support::MethodSignatureExpectation
151 | def empty?; end
152 | def expect_arbitrary_keywords; end
153 | def expect_arbitrary_keywords=(arg0); end
154 | def expect_unlimited_arguments; end
155 | def expect_unlimited_arguments=(arg0); end
156 | def initialize; end
157 | def keywords; end
158 | def keywords=(values); end
159 | def max_count; end
160 | def max_count=(number); end
161 | def min_count; end
162 | def min_count=(number); end
163 | end
164 | class RSpec::Support::BlockSignature < RSpec::Support::MethodSignature
165 | def classify_parameters; end
166 | end
167 | class RSpec::Support::MethodSignatureVerifier
168 | def arbitrary_kw_args?; end
169 | def error_message; end
170 | def initialize(signature, args = nil); end
171 | def invalid_kw_args; end
172 | def kw_args; end
173 | def max_non_kw_args; end
174 | def min_non_kw_args; end
175 | def missing_kw_args; end
176 | def non_kw_args; end
177 | def split_args(*args); end
178 | def unlimited_args?; end
179 | def valid?; end
180 | def valid_non_kw_args?; end
181 | def with_expectation(expectation); end
182 | end
183 | class RSpec::Support::LooseSignatureVerifier < RSpec::Support::MethodSignatureVerifier
184 | def split_args(*args); end
185 | end
186 | class RSpec::Support::LooseSignatureVerifier::SignatureWithKeywordArgumentsMatcher
187 | def has_kw_args_in?(args); end
188 | def initialize(signature); end
189 | def invalid_kw_args_from(_kw_args); end
190 | def missing_kw_args_from(_kw_args); end
191 | def non_kw_args_arity_description; end
192 | def valid_non_kw_args?(*args); end
193 | end
194 | module RSpec::Support::WithKeywordsWhenNeeded
195 | def class_exec(klass, *args, &block); end
196 | def self.class_exec(klass, *args, &block); end
197 | end
198 | module RSpec::Support::RecursiveConstMethods
199 | def const_defined_on?(mod, const_name); end
200 | def constants_defined_on(mod); end
201 | def get_const_defined_on(mod, const_name); end
202 | def normalize_const_name(const_name); end
203 | def recursive_const_defined?(const_name); end
204 | def recursive_const_get(const_name); end
205 | end
206 | class RSpec::Support::ObjectFormatter
207 | def format(object); end
208 | def initialize(max_formatted_output_length = nil); end
209 | def max_formatted_output_length; end
210 | def max_formatted_output_length=(arg0); end
211 | def prepare_array(array); end
212 | def prepare_element(element); end
213 | def prepare_for_inspection(object); end
214 | def prepare_hash(input_hash); end
215 | def recursive_structure?(object); end
216 | def self.default_instance; end
217 | def self.format(object); end
218 | def self.prepare_for_inspection(object); end
219 | def sort_hash_keys(input_hash); end
220 | def truncate_string(str, start_index, end_index); end
221 | def with_entering_structure(structure); end
222 | end
223 | class RSpec::Support::ObjectFormatter::InspectableItem < Struct
224 | def inspect; end
225 | def pretty_print(pp); end
226 | def self.[](*arg0); end
227 | def self.inspect; end
228 | def self.members; end
229 | def self.new(*arg0); end
230 | def text; end
231 | def text=(_); end
232 | end
233 | class RSpec::Support::ObjectFormatter::BaseInspector < Struct
234 | def formatter; end
235 | def formatter=(_); end
236 | def inspect; end
237 | def object; end
238 | def object=(_); end
239 | def pretty_print(pp); end
240 | def self.[](*arg0); end
241 | def self.can_inspect?(_object); end
242 | def self.inspect; end
243 | def self.members; end
244 | def self.new(*arg0); end
245 | end
246 | class RSpec::Support::ObjectFormatter::TimeInspector < RSpec::Support::ObjectFormatter::BaseInspector
247 | def inspect; end
248 | def self.can_inspect?(object); end
249 | end
250 | class RSpec::Support::ObjectFormatter::DateTimeInspector < RSpec::Support::ObjectFormatter::BaseInspector
251 | def inspect; end
252 | def self.can_inspect?(object); end
253 | end
254 | class RSpec::Support::ObjectFormatter::BigDecimalInspector < RSpec::Support::ObjectFormatter::BaseInspector
255 | def inspect; end
256 | def self.can_inspect?(object); end
257 | end
258 | class RSpec::Support::ObjectFormatter::DescribableMatcherInspector < RSpec::Support::ObjectFormatter::BaseInspector
259 | def inspect; end
260 | def self.can_inspect?(object); end
261 | end
262 | class RSpec::Support::ObjectFormatter::UninspectableObjectInspector < RSpec::Support::ObjectFormatter::BaseInspector
263 | def inspect; end
264 | def klass; end
265 | def native_object_id; end
266 | def self.can_inspect?(object); end
267 | end
268 | class RSpec::Support::ObjectFormatter::DelegatorInspector < RSpec::Support::ObjectFormatter::BaseInspector
269 | def inspect; end
270 | def self.can_inspect?(object); end
271 | end
272 | class RSpec::Support::ObjectFormatter::InspectableObjectInspector < RSpec::Support::ObjectFormatter::BaseInspector
273 | def inspect; end
274 | def self.can_inspect?(object); end
275 | end
276 | module RSpec::Support::FuzzyMatcher
277 | def self.arrays_match?(expected_list, actual_list); end
278 | def self.hashes_match?(expected_hash, actual_hash); end
279 | def self.values_match?(expected, actual); end
280 | end
281 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/rspec.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/rspec/all/rspec.rbi
9 | #
10 | # rspec-3.10.0
11 |
12 | module RSpec
13 | end
14 | module RSpec::Version
15 | end
16 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/simplecov-html.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/simplecov-html/all/simplecov-html.rbi
9 | #
10 | # simplecov-html-0.12.3
11 |
12 | module SimpleCov
13 | end
14 | module SimpleCov::Formatter
15 | end
16 | class SimpleCov::Formatter::HTMLFormatter
17 | def asset_output_path; end
18 | def assets_path(name); end
19 | def branchable_result?; end
20 | def coverage_css_class(covered_percent); end
21 | def covered_percent(percent); end
22 | def format(result); end
23 | def formatted_file_list(title, source_files); end
24 | def formatted_source_file(source_file); end
25 | def id(source_file); end
26 | def initialize; end
27 | def line_status?(source_file, line); end
28 | def link_to_source_file(source_file); end
29 | def output_message(result); end
30 | def output_path; end
31 | def shortened_filename(source_file); end
32 | def strength_css_class(covered_strength); end
33 | def template(name); end
34 | def timeago(time); end
35 | end
36 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/simplecov.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: true
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/simplecov/all/simplecov.rbi
9 | #
10 | # simplecov-0.21.2
11 |
12 | module SimpleCov
13 | def self.adapt_coverage_result; end
14 | def self.add_not_loaded_files(result); end
15 | def self.at_exit_behavior; end
16 | def self.clear_result; end
17 | def self.collate(result_filenames, profile = nil, ignore_timeout: nil, &block); end
18 | def self.exit_and_report_previous_error(exit_status); end
19 | def self.exit_status_from_exception; end
20 | def self.external_at_exit; end
21 | def self.external_at_exit=(arg0); end
22 | def self.external_at_exit?; end
23 | def self.filtered(files); end
24 | def self.final_result_process?; end
25 | def self.grouped(files); end
26 | def self.initial_setup(profile, &block); end
27 | def self.load_adapter(name); end
28 | def self.load_profile(name); end
29 | def self.lookup_corresponding_ruby_coverage_name(criterion); end
30 | def self.make_parallel_tests_available; end
31 | def self.pid; end
32 | def self.pid=(arg0); end
33 | def self.previous_error?(error_exit_status); end
34 | def self.probably_running_parallel_tests?; end
35 | def self.process_coverage_result; end
36 | def self.process_result(result); end
37 | def self.process_results_and_report_error; end
38 | def self.ready_to_process_results?; end
39 | def self.remove_useless_results; end
40 | def self.result; end
41 | def self.result?; end
42 | def self.result_exit_status(result); end
43 | def self.result_with_not_loaded_files; end
44 | def self.round_coverage(coverage); end
45 | def self.run_exit_tasks!; end
46 | def self.running; end
47 | def self.running=(arg0); end
48 | def self.start(profile = nil, &block); end
49 | def self.start_coverage_measurement; end
50 | def self.start_coverage_with_criteria; end
51 | def self.wait_for_other_processes; end
52 | def self.write_last_run(result); end
53 | extend SimpleCov::Configuration
54 | end
55 | module SimpleCov::Formatter
56 | def self.from_env(env); end
57 | end
58 | class SimpleCov::Formatter::MultiFormatter
59 | def self.[](*args); end
60 | def self.new(formatters = nil); end
61 | end
62 | module SimpleCov::Formatter::MultiFormatter::InstanceMethods
63 | def format(result); end
64 | end
65 | module SimpleCov::Configuration
66 | def adapters; end
67 | def add_filter(filter_argument = nil, &filter_proc); end
68 | def add_group(group_name, filter_argument = nil, &filter_proc); end
69 | def at_exit(&block); end
70 | def at_fork(&block); end
71 | def branch_coverage?; end
72 | def branch_coverage_supported?; end
73 | def clear_coverage_criteria; end
74 | def command_name(name = nil); end
75 | def configure(&block); end
76 | def coverage_criteria; end
77 | def coverage_criterion(criterion = nil); end
78 | def coverage_criterion_enabled?(criterion); end
79 | def coverage_dir(dir = nil); end
80 | def coverage_path; end
81 | def coverage_start_arguments_supported?; end
82 | def enable_coverage(criterion); end
83 | def enable_for_subprocesses(value = nil); end
84 | def enabled_for_subprocesses?; end
85 | def filters; end
86 | def filters=(arg0); end
87 | def formatter(formatter = nil); end
88 | def formatter=(arg0); end
89 | def formatters; end
90 | def formatters=(formatters); end
91 | def groups; end
92 | def groups=(arg0); end
93 | def maximum_coverage_drop(coverage_drop = nil); end
94 | def merge_timeout(seconds = nil); end
95 | def minimum_coverage(coverage = nil); end
96 | def minimum_coverage_by_file(coverage = nil); end
97 | def minimum_possible_coverage_exceeded(coverage_option); end
98 | def nocov_token(nocov_token = nil); end
99 | def parse_filter(filter_argument = nil, &filter_proc); end
100 | def primary_coverage(criterion = nil); end
101 | def print_error_status; end
102 | def print_error_status=(arg0); end
103 | def profiles; end
104 | def project_name(new_name = nil); end
105 | def raise_if_criterion_disabled(criterion); end
106 | def raise_if_criterion_unsupported(criterion); end
107 | def raise_on_invalid_coverage(coverage, coverage_setting); end
108 | def refuse_coverage_drop(*criteria); end
109 | def root(root = nil); end
110 | def skip_token(nocov_token = nil); end
111 | def track_files(glob); end
112 | def tracked_files; end
113 | def use_merging(use = nil); end
114 | end
115 | class SimpleCov::CoverageStatistics
116 | def compute_percent(covered, missed, total); end
117 | def compute_strength(total_strength, total); end
118 | def covered; end
119 | def initialize(covered:, missed:, total_strength: nil); end
120 | def missed; end
121 | def percent; end
122 | def self.from(coverage_statistics); end
123 | def strength; end
124 | def total; end
125 | end
126 | module SimpleCov::ExitCodes
127 | end
128 | module SimpleCov::ExitCodes::ExitCodeHandling
129 | def call(result, coverage_limits:); end
130 | def coverage_checks(result, coverage_limits); end
131 | def self.call(result, coverage_limits:); end
132 | def self.coverage_checks(result, coverage_limits); end
133 | end
134 | class SimpleCov::ExitCodes::MaximumCoverageDropCheck
135 | def compute_coverage_drop_data; end
136 | def coverage_drop_violations; end
137 | def drop_percent(criterion); end
138 | def exit_code; end
139 | def failing?; end
140 | def initialize(result, maximum_coverage_drop); end
141 | def last_coverage(criterion); end
142 | def last_run; end
143 | def maximum_coverage_drop; end
144 | def report; end
145 | def result; end
146 | end
147 | class SimpleCov::ExitCodes::MinimumCoverageByFileCheck
148 | def compute_minimum_coverage_data; end
149 | def exit_code; end
150 | def failing?; end
151 | def initialize(result, minimum_coverage_by_file); end
152 | def minimum_coverage_by_file; end
153 | def minimum_violations; end
154 | def report; end
155 | def result; end
156 | end
157 | class SimpleCov::ExitCodes::MinimumOverallCoverageCheck
158 | def calculate_minimum_violations; end
159 | def exit_code; end
160 | def failing?; end
161 | def initialize(result, minimum_coverage); end
162 | def minimum_coverage; end
163 | def minimum_violations; end
164 | def report; end
165 | def result; end
166 | end
167 | class SimpleCov::Profiles < Hash
168 | def define(name, &blk); end
169 | def load(name); end
170 | end
171 | class SimpleCov::SourceFile
172 | def branch_coverage_statistics; end
173 | def branches; end
174 | def branches_coverage_percent; end
175 | def branches_for_line(line_number); end
176 | def branches_report; end
177 | def build_branch(branch_data, hit_count, condition_start_line); end
178 | def build_branches; end
179 | def build_branches_from(condition, branches); end
180 | def build_branches_report; end
181 | def build_lines; end
182 | def build_no_cov_chunks; end
183 | def coverage_data; end
184 | def coverage_exceeding_source_warn; end
185 | def coverage_statistics; end
186 | def covered_branches; end
187 | def covered_lines; end
188 | def covered_percent; end
189 | def covered_strength; end
190 | def ensure_remove_undefs(file_lines); end
191 | def filename; end
192 | def initialize(filename, coverage_data); end
193 | def line(number); end
194 | def line_coverage_statistics; end
195 | def line_with_missed_branch?(line_number); end
196 | def lines; end
197 | def lines_of_code; end
198 | def lines_strength; end
199 | def load_source; end
200 | def missed_branches; end
201 | def missed_lines; end
202 | def never_lines; end
203 | def no_branches?; end
204 | def no_cov_chunks; end
205 | def no_lines?; end
206 | def process_skipped_branches(branches); end
207 | def process_skipped_lines(lines); end
208 | def project_filename; end
209 | def read_lines(file, lines, current_line); end
210 | def relevant_lines; end
211 | def restore_ruby_data_structure(structure); end
212 | def set_encoding_based_on_magic_comment(file, line); end
213 | def shebang?(line); end
214 | def skipped_lines; end
215 | def source; end
216 | def source_lines; end
217 | def src; end
218 | def total_branches; end
219 | end
220 | class SimpleCov::SourceFile::Line
221 | def coverage; end
222 | def covered?; end
223 | def initialize(src, line_number, coverage); end
224 | def line; end
225 | def line_number; end
226 | def missed?; end
227 | def never?; end
228 | def number; end
229 | def skipped!; end
230 | def skipped; end
231 | def skipped?; end
232 | def source; end
233 | def src; end
234 | def status; end
235 | end
236 | class SimpleCov::SourceFile::Branch
237 | def coverage; end
238 | def covered?; end
239 | def end_line; end
240 | def initialize(start_line:, end_line:, coverage:, inline:, type:); end
241 | def inline?; end
242 | def missed?; end
243 | def overlaps_with?(line_range); end
244 | def report; end
245 | def report_line; end
246 | def skipped!; end
247 | def skipped?; end
248 | def start_line; end
249 | def type; end
250 | end
251 | class SimpleCov::FileList
252 | def branch_covered_percent; end
253 | def compute_coverage_statistics; end
254 | def compute_coverage_statistics_by_file; end
255 | def count(*args, &block); end
256 | def coverage_statistics; end
257 | def coverage_statistics_by_file; end
258 | def covered_branches; end
259 | def covered_lines; end
260 | def covered_percent; end
261 | def covered_percentages; end
262 | def covered_strength; end
263 | def each(*args, &block); end
264 | def empty?(*args, &block); end
265 | def initialize(files); end
266 | def least_covered_file; end
267 | def length(*args, &block); end
268 | def lines_of_code; end
269 | def map(*args, &block); end
270 | def missed_branches; end
271 | def missed_lines; end
272 | def never_lines; end
273 | def size(*args, &block); end
274 | def skipped_lines; end
275 | def to_a(*args, &block); end
276 | def to_ary(*args, &block); end
277 | def total_branches; end
278 | extend Forwardable
279 | include Enumerable
280 | end
281 | class SimpleCov::Result
282 | def command_name; end
283 | def command_name=(arg0); end
284 | def coverage; end
285 | def coverage_statistics(*args, &block); end
286 | def coverage_statistics_by_file(*args, &block); end
287 | def covered_branches(*args, &block); end
288 | def covered_lines(*args, &block); end
289 | def covered_percent(*args, &block); end
290 | def covered_percentages(*args, &block); end
291 | def covered_strength(*args, &block); end
292 | def created_at; end
293 | def created_at=(arg0); end
294 | def filenames; end
295 | def files; end
296 | def filter!; end
297 | def format!; end
298 | def groups; end
299 | def initialize(original_result, command_name: nil, created_at: nil); end
300 | def least_covered_file(*args, &block); end
301 | def missed_branches(*args, &block); end
302 | def missed_lines(*args, &block); end
303 | def original_result; end
304 | def self.from_hash(hash); end
305 | def source_files; end
306 | def to_hash; end
307 | def total_branches(*args, &block); end
308 | def total_lines(*args, &block); end
309 | extend Forwardable
310 | end
311 | class SimpleCov::Filter
312 | def filter_argument; end
313 | def initialize(filter_argument); end
314 | def matches?(_source_file); end
315 | def passes?(source_file); end
316 | def self.build_filter(filter_argument); end
317 | def self.class_for_argument(filter_argument); end
318 | end
319 | class SimpleCov::StringFilter < SimpleCov::Filter
320 | def matches?(source_file); end
321 | end
322 | class SimpleCov::RegexFilter < SimpleCov::Filter
323 | def matches?(source_file); end
324 | end
325 | class SimpleCov::BlockFilter < SimpleCov::Filter
326 | def matches?(source_file); end
327 | end
328 | class SimpleCov::ArrayFilter < SimpleCov::Filter
329 | def initialize(filter_argument); end
330 | def matches?(source_files_list); end
331 | end
332 | class SimpleCov::Formatter::SimpleFormatter
333 | def format(result); end
334 | end
335 | module SimpleCov::LastRun
336 | def self.last_run_path; end
337 | def self.read; end
338 | def self.write(json); end
339 | end
340 | class SimpleCov::LinesClassifier
341 | def classify(lines); end
342 | def self.no_cov_line; end
343 | def self.no_cov_line?(line); end
344 | def self.whitespace_line?(line); end
345 | end
346 | module SimpleCov::ResultMerger
347 | def self.adapt_pre_simplecov_0_18_result(result); end
348 | def self.adapt_result(result); end
349 | def self.create_result(command_names, coverage); end
350 | def self.merge_and_store(*file_paths, ignore_timeout: nil); end
351 | def self.merge_coverage(*results); end
352 | def self.merge_results(*file_paths, ignore_timeout: nil); end
353 | def self.merge_valid_results(results, ignore_timeout: nil); end
354 | def self.merged_result; end
355 | def self.parse_file(path); end
356 | def self.parse_json(content); end
357 | def self.pre_simplecov_0_18_result?(result); end
358 | def self.read_file(path); end
359 | def self.read_resultset; end
360 | def self.resultset_path; end
361 | def self.resultset_writelock; end
362 | def self.store_result(result); end
363 | def self.synchronize_resultset; end
364 | def self.time_since_result_creation(data); end
365 | def self.valid_results(file_path, ignore_timeout: nil); end
366 | def self.within_merge_timeout?(data); end
367 | end
368 | module SimpleCov::CommandGuesser
369 | def self.from_command_line_options; end
370 | def self.from_defined_constants; end
371 | def self.from_env; end
372 | def self.guess; end
373 | def self.original_run_command; end
374 | def self.original_run_command=(arg0); end
375 | end
376 | class SimpleCov::ResultAdapter
377 | def adapt; end
378 | def initialize(result); end
379 | def result; end
380 | def self.call(*args); end
381 | end
382 | module SimpleCov::Combine
383 | def combine(combiner_module, coverage_a, coverage_b); end
384 | def empty_coverage?(coverage_a, coverage_b); end
385 | def existing_coverage(coverage_a, coverage_b); end
386 | def self.combine(combiner_module, coverage_a, coverage_b); end
387 | def self.empty_coverage?(coverage_a, coverage_b); end
388 | def self.existing_coverage(coverage_a, coverage_b); end
389 | end
390 | module SimpleCov::Combine::BranchesCombiner
391 | def combine(coverage_a, coverage_b); end
392 | def self.combine(coverage_a, coverage_b); end
393 | end
394 | module SimpleCov::Combine::FilesCombiner
395 | def combine(coverage_a, coverage_b); end
396 | def self.combine(coverage_a, coverage_b); end
397 | end
398 | module SimpleCov::Combine::LinesCombiner
399 | def combine(coverage_a, coverage_b); end
400 | def merge_line_coverage(first_val, second_val); end
401 | def self.combine(coverage_a, coverage_b); end
402 | def self.merge_line_coverage(first_val, second_val); end
403 | end
404 | module SimpleCov::Combine::ResultsCombiner
405 | def combine(*results); end
406 | def combine_file_coverage(coverage_a, coverage_b); end
407 | def combine_result_sets(combined_results, result); end
408 | def self.combine(*results); end
409 | def self.combine_file_coverage(coverage_a, coverage_b); end
410 | def self.combine_result_sets(combined_results, result); end
411 | end
412 | module SimpleCov::UselessResultsRemover
413 | def self.call(coverage_result); end
414 | def self.root_regx; end
415 | end
416 | module SimpleCov::SimulateCoverage
417 | def call(absolute_path); end
418 | def self.call(absolute_path); end
419 | end
420 |
--------------------------------------------------------------------------------
/sorbet/rbi/gems/simplecov_json_formatter.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi gems
3 |
4 | # typed: strict
5 | #
6 | # If you would like to make changes to this file, great! Please create the gem's shim here:
7 | #
8 | # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/simplecov_json_formatter/all/simplecov_json_formatter.rbi
9 | #
10 | # simplecov_json_formatter-0.1.3
11 |
12 | module SimpleCovJSONFormatter
13 | end
14 | class SimpleCovJSONFormatter::SourceFileFormatter
15 | def branch_coverage; end
16 | def branches; end
17 | def format; end
18 | def initialize(source_file); end
19 | def line_coverage; end
20 | def lines; end
21 | def parse_branch(branch); end
22 | def parse_line(line); end
23 | end
24 | class SimpleCovJSONFormatter::ResultHashFormatter
25 | def format; end
26 | def format_source_file(source_file); end
27 | def formatted_result; end
28 | def initialize(result); end
29 | end
30 | class SimpleCovJSONFormatter::ResultExporter
31 | def export; end
32 | def export_path; end
33 | def initialize(result_hash); end
34 | def json_result; end
35 | end
36 | module SimpleCov
37 | end
38 | module SimpleCov::Formatter
39 | end
40 | class SimpleCov::Formatter::JSONFormatter
41 | def export_formatted_result(result_hash); end
42 | def format(result); end
43 | def format_result(result); end
44 | def output_message(result); end
45 | end
46 |
--------------------------------------------------------------------------------
/sorbet/rbi/sorbet-typed/lib/faraday/all/faraday.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi sorbet-typed
3 | #
4 | # If you would like to make changes to this file, great! Please upstream any changes you make here:
5 | #
6 | # https://github.com/sorbet/sorbet-typed/edit/master/lib/faraday/all/faraday.rbi
7 | #
8 | # typed: strict
9 |
10 | module Faraday
11 | def self.new(url = nil, options = nil, &block); end
12 |
13 | # HTTP verb methods. These are proxied to Faraday::Connecation,
14 | # which should have corresponding sigs
15 |
16 | # Query methods
17 | sig do
18 | params(
19 | url: String,
20 | params: T.nilable(T::Hash[Object, Object]),
21 | headers: T.nilable(T::Hash[Object, String]),
22 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
23 | ).returns(Faraday::Response)
24 | end
25 | def self.get(url, params = nil, headers = nil, &block); end
26 | sig do
27 | params(
28 | url: String,
29 | params: T.nilable(T::Hash[Object, Object]),
30 | headers: T.nilable(T::Hash[Object, String]),
31 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
32 | ).returns(Faraday::Response)
33 | end
34 | def self.head(url, params = nil, headers = nil, &block); end
35 | sig do
36 | params(
37 | url: String,
38 | params: T.nilable(T::Hash[Object, Object]),
39 | headers: T.nilable(T::Hash[Object, String]),
40 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
41 | ).returns(Faraday::Response)
42 | end
43 | def self.delete(url, params = nil, headers = nil, &block); end
44 | sig do
45 | params(
46 | url: String,
47 | params: T.nilable(T::Hash[Object, Object]),
48 | headers: T.nilable(T::Hash[Object, String]),
49 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
50 | ).returns(Faraday::Response)
51 | end
52 | def self.trace(url, params = nil, headers = nil, &block); end
53 |
54 | # Body methods
55 | sig do
56 | params(
57 | url: String,
58 | body: T.any(String, T.nilable(T::Hash[Object, Object])),
59 | headers: T.nilable(T::Hash[Object, String]),
60 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
61 | ).returns(Faraday::Response)
62 | end
63 | def self.post(url, body = nil, headers = nil, &block); end
64 | sig do
65 | params(
66 | url: String,
67 | body: T.any(String, T.nilable(T::Hash[Object, Object])),
68 | headers: T.nilable(T::Hash[Object, String]),
69 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
70 | ).returns(Faraday::Response)
71 | end
72 | def self.put(url, body = nil, headers = nil, &block); end
73 | sig do
74 | params(
75 | url: String,
76 | body: T.any(String, T.nilable(T::Hash[Object, Object])),
77 | headers: T.nilable(T::Hash[Object, String]),
78 | block: T.nilable(T.proc.params(req: Faraday::Request).void),
79 | ).returns(Faraday::Response)
80 | end
81 | def self.patch(url, body = nil, headers = nil, &block); end
82 | end
83 |
--------------------------------------------------------------------------------
/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi sorbet-typed
3 | #
4 | # If you would like to make changes to this file, great! Please upstream any changes you make here:
5 | #
6 | # https://github.com/sorbet/sorbet-typed/edit/master/lib/rainbow/all/rainbow.rbi
7 | #
8 | # typed: strong
9 |
10 | module Rainbow
11 | sig { returns(T::Boolean) }
12 | attr_accessor :enabled
13 |
14 | class Color
15 | sig { returns(Symbol) }
16 | attr_reader :ground
17 |
18 | sig do
19 | params(
20 | ground: Symbol,
21 | values: T.any([Integer], [Integer, Integer, Integer])
22 | ).returns(Color)
23 | end
24 | def self.build(ground, values); end
25 |
26 | sig { params(hex: String).returns([Integer, Integer, Integer]) }
27 | def self.parse_hex_color(hex); end
28 |
29 | class Indexed < Color
30 | sig { returns(Integer) }
31 | attr_reader :num
32 |
33 | sig { params(ground: Symbol, num: Integer).void }
34 | def initialize(ground, num); end
35 |
36 | sig { returns(T::Array[Integer]) }
37 | def codes; end
38 | end
39 |
40 | class Named < Indexed
41 | NAMES = T.let(nil, T::Hash[Symbol, Integer])
42 |
43 | sig { returns(T::Array[Symbol]) }
44 | def self.color_names; end
45 |
46 | sig { returns(String) }
47 | def self.valid_names; end
48 |
49 | sig { params(ground: Symbol, name: Symbol).void }
50 | def initialize(ground, name); end
51 | end
52 |
53 | class RGB < Indexed
54 | sig { returns(Integer) }
55 | attr_accessor :r, :g, :b
56 |
57 | sig { params(value: Numeric).returns(Integer) }
58 | def to_ansi_domain(value); end
59 |
60 | sig { params(ground: Symbol, values: Integer).void }
61 | def initialize(ground, *values); end
62 |
63 | sig { returns(T::Array[Integer]) }
64 | def codes; end
65 | end
66 |
67 | class X11Named < RGB
68 | include X11ColorNames
69 |
70 | sig { returns(T::Array[Symbol]) }
71 | def self.color_names; end
72 |
73 | sig { returns(String) }
74 | def self.valid_names; end
75 |
76 | sig { params(ground: Symbol, name: Symbol).void }
77 | def initialize(ground, name); end
78 | end
79 | end
80 |
81 | sig { returns(Wrapper) }
82 | def self.global; end
83 |
84 | sig { returns(T::Boolean) }
85 | def self.enabled; end
86 |
87 | sig { params(value: T::Boolean).returns(T::Boolean) }
88 | def self.enabled=(value); end
89 |
90 | sig { params(string: String).returns(String) }
91 | def self.uncolor(string); end
92 |
93 | class NullPresenter < String
94 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
95 | def color(*values); end
96 |
97 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
98 | def foreground(*values); end
99 |
100 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
101 | def fg(*values); end
102 |
103 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
104 | def background(*values); end
105 |
106 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
107 | def bg(*values); end
108 |
109 | sig { returns(NullPresenter) }
110 | def reset; end
111 |
112 | sig { returns(NullPresenter) }
113 | def bright; end
114 |
115 | sig { returns(NullPresenter) }
116 | def faint; end
117 |
118 | sig { returns(NullPresenter) }
119 | def italic; end
120 |
121 | sig { returns(NullPresenter) }
122 | def underline; end
123 |
124 | sig { returns(NullPresenter) }
125 | def blink; end
126 |
127 | sig { returns(NullPresenter) }
128 | def inverse; end
129 |
130 | sig { returns(NullPresenter) }
131 | def hide; end
132 |
133 | sig { returns(NullPresenter) }
134 | def cross_out; end
135 |
136 | sig { returns(NullPresenter) }
137 | def black; end
138 |
139 | sig { returns(NullPresenter) }
140 | def red; end
141 |
142 | sig { returns(NullPresenter) }
143 | def green; end
144 |
145 | sig { returns(NullPresenter) }
146 | def yellow; end
147 |
148 | sig { returns(NullPresenter) }
149 | def blue; end
150 |
151 | sig { returns(NullPresenter) }
152 | def magenta; end
153 |
154 | sig { returns(NullPresenter) }
155 | def cyan; end
156 |
157 | sig { returns(NullPresenter) }
158 | def white; end
159 |
160 | sig { returns(NullPresenter) }
161 | def bold; end
162 |
163 | sig { returns(NullPresenter) }
164 | def dark; end
165 |
166 | sig { returns(NullPresenter) }
167 | def strike; end
168 | end
169 |
170 | class Presenter < String
171 | TERM_EFFECTS = T.let(nil, T::Hash[Symbol, Integer])
172 |
173 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
174 | def color(*values); end
175 |
176 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
177 | def foreground(*values); end
178 |
179 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
180 | def fg(*values); end
181 |
182 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
183 | def background(*values); end
184 |
185 | sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
186 | def bg(*values); end
187 |
188 | sig { returns(Presenter) }
189 | def reset; end
190 |
191 | sig { returns(Presenter) }
192 | def bright; end
193 |
194 | sig { returns(Presenter) }
195 | def faint; end
196 |
197 | sig { returns(Presenter) }
198 | def italic; end
199 |
200 | sig { returns(Presenter) }
201 | def underline; end
202 |
203 | sig { returns(Presenter) }
204 | def blink; end
205 |
206 | sig { returns(Presenter) }
207 | def inverse; end
208 |
209 | sig { returns(Presenter) }
210 | def hide; end
211 |
212 | sig { returns(Presenter) }
213 | def cross_out; end
214 |
215 | sig { returns(Presenter) }
216 | def black; end
217 |
218 | sig { returns(Presenter) }
219 | def red; end
220 |
221 | sig { returns(Presenter) }
222 | def green; end
223 |
224 | sig { returns(Presenter) }
225 | def yellow; end
226 |
227 | sig { returns(Presenter) }
228 | def blue; end
229 |
230 | sig { returns(Presenter) }
231 | def magenta; end
232 |
233 | sig { returns(Presenter) }
234 | def cyan; end
235 |
236 | sig { returns(Presenter) }
237 | def white; end
238 |
239 | sig { returns(Presenter) }
240 | def bold; end
241 |
242 | sig { returns(Presenter) }
243 | def dark; end
244 |
245 | sig { returns(Presenter) }
246 | def strike; end
247 | end
248 |
249 | class StringUtils
250 | sig { params(string: String, codes: T::Array[Integer]).returns(String) }
251 | def self.wrap_with_sgr(string, codes); end
252 |
253 | sig { params(string: String).returns(String) }
254 | def uncolor(string); end
255 | end
256 |
257 | VERSION = T.let(nil, String)
258 |
259 | class Wrapper
260 | sig { returns(T::Boolean) }
261 | attr_accessor :enabled
262 |
263 | sig { params(enabled: T::Boolean).void }
264 | def initialize(enabled = true); end
265 |
266 | sig { params(string: String).returns(T.any(Rainbow::Presenter, Rainbow::NullPresenter)) }
267 | def wrap(string); end
268 | end
269 |
270 | module X11ColorNames
271 | NAMES = T.let(nil, T::Hash[Symbol, [Integer, Integer, Integer]])
272 | end
273 | end
274 |
275 | sig { params(string: String).returns(Rainbow::Presenter) }
276 | def Rainbow(string); end
277 |
--------------------------------------------------------------------------------
/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi sorbet-typed
3 | #
4 | # If you would like to make changes to this file, great! Please upstream any changes you make here:
5 | #
6 | # https://github.com/sorbet/sorbet-typed/edit/master/lib/rspec-core/all/rspec-core.rbi
7 | #
8 | # typed: strict
9 |
10 | module RSpec::Core::ShellEscape
11 | def conditionally_quote(id); end
12 | def escape(shell_command); end
13 | def quote(argument); end
14 | def self.conditionally_quote(id); end
15 | def self.escape(shell_command); end
16 | def self.quote(argument); end
17 | def self.shell_allows_unquoted_ids?; end
18 | def shell_allows_unquoted_ids?; end
19 | end
20 | class RSpec::Core::RakeTask < ::Rake::TaskLib
21 | include ::Rake::DSL
22 | include RSpec::Core::ShellEscape
23 | def initialize(*args, &task_block); end
24 | end
25 |
--------------------------------------------------------------------------------
/sorbet/rbi/sorbet-typed/lib/rubocop/>=1.8/rubocop.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi sorbet-typed
3 | #
4 | # If you would like to make changes to this file, great! Please upstream any changes you make here:
5 | #
6 | # https://github.com/sorbet/sorbet-typed/edit/master/lib/rubocop/>=1.8/rubocop.rbi
7 | #
8 | # typed: strict
9 |
10 | class RuboCop::RakeTask < ::Rake::TaskLib
11 | def initialize(name = :rubocop, *args, &task_block); end
12 | end
13 |
--------------------------------------------------------------------------------
/sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi sorbet-typed
3 | #
4 | # If you would like to make changes to this file, great! Please upstream any changes you make here:
5 | #
6 | # https://github.com/sorbet/sorbet-typed/edit/master/lib/yard/all/yard.rbi
7 | #
8 | # typed: strict
9 |
10 | class YARD::CodeObjects::Base
11 | def initialize(namespace, name, *arg2); end
12 | end
13 | class YARD::CodeObjects::NamespaceObject < YARD::CodeObjects::Base
14 | def mixins(*scopes); end
15 | end
16 | class YARD::CodeObjects::ClassObject < YARD::CodeObjects::NamespaceObject
17 | end
18 | class YARD::CodeObjects::ConstantObject < YARD::CodeObjects::Base
19 | end
20 | class YARD::CodeObjects::Proxy
21 | def initialize(namespace, name, type = nil); end
22 | end
23 | class YARD::Handlers::Base
24 | def handlers; end
25 | def self.handlers; end
26 | end
27 | class YARD::Handlers::Ruby::Base < YARD::Handlers::Base
28 | end
29 | class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
30 | end
31 | class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base
32 | end
33 |
--------------------------------------------------------------------------------
/sorbet/rbi/todo.rbi:
--------------------------------------------------------------------------------
1 | # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2 | # srb rbi todo
3 |
4 | # typed: strong
5 | module Rack::QueryParser::InvalidParameterError; end
6 | module Rack::QueryParser::ParameterTypeError; end
7 | module T::CompatibilityPatches::RSpecCompatibility::MethodDoubleExtensions; end
8 | module T::CompatibilityPatches::RSpecCompatibility::RecorderExtensions; end
9 | module T::Private::Methods::MethodHooks; end
10 | module T::Private::Methods::SingletonMethodHooks; end
11 | class Prism::LexCompat::Result; end
--------------------------------------------------------------------------------
/spec/channel_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'securerandom'
4 | require 'stream-chat'
5 |
6 | describe StreamChat::Channel do
7 | def loop_times(times)
8 | loop do
9 | begin
10 | yield()
11 | return
12 | rescue StandardError, RSpec::Expectations::ExpectationNotMetError
13 | raise if times.zero?
14 | end
15 |
16 | sleep(1)
17 | times -= 1
18 | end
19 | end
20 |
21 | before(:all) do
22 | @client = StreamChat::Client.from_env
23 | @created_users = []
24 | end
25 |
26 | before(:each) do
27 | @random_users = [{ id: SecureRandom.uuid, name: 'b' }, { id: SecureRandom.uuid, name: 'a' }]
28 | @random_user = { id: SecureRandom.uuid }
29 |
30 | users_to_insert = [@random_users[0], @random_users[1], @random_user]
31 |
32 | @created_users.push(*users_to_insert.map { |u| u[:id] })
33 | @client.upsert_users(users_to_insert)
34 |
35 | @channel = @client.channel('messaging', channel_id: SecureRandom.uuid, data: { test: true, language: 'ruby' })
36 | @channel.create(@random_user[:id])
37 | end
38 |
39 | after(:each) do
40 | @channel.delete
41 | rescue StreamChat::StreamAPIException
42 | # if the channel is already deleted by the test, we can ignore the error
43 | end
44 |
45 | after(:all) do
46 | curr_idx = 0
47 | batch_size = 25
48 |
49 | slice = @created_users.slice(0, batch_size)
50 |
51 | while !slice.nil? && !slice.empty?
52 | @client.delete_users(slice, user: StreamChat::HARD_DELETE, messages: StreamChat::HARD_DELETE)
53 |
54 | curr_idx += batch_size
55 | slice = @created_users.slice(curr_idx, batch_size)
56 | end
57 | end
58 |
59 | it 'can create channel without id' do
60 | channel = @client.channel('messaging', data: { 'members' => @random_users.map { |u| u[:id] } })
61 | expect(channel.id).to eq nil
62 |
63 | channel.create(@random_users[0][:id])
64 | expect(channel.id).not_to eq nil
65 | end
66 |
67 | it 'can send events' do
68 | response = @channel.send_event({ 'type' => 'typing.start' }, @random_user[:id])
69 | expect(response).to include 'event'
70 | expect(response['event']['type']).to eq 'typing.start'
71 | end
72 |
73 | it 'can get many messages' do
74 | msg = @channel.send_message({ text: 'hi' }, @random_user[:id])
75 | response = @channel.get_messages([msg['message']['id']])
76 | expect(response['messages']).not_to be_empty
77 | end
78 |
79 | it 'can send reactions' do
80 | msg = @channel.send_message({ 'text' => 'hi' }, @random_user[:id])
81 | response = @channel.send_reaction(msg['message']['id'], { 'type' => 'love' }, @random_user[:id])
82 | expect(response).to include 'message'
83 | expect(response['message']['latest_reactions'].length).to eq 1
84 | expect(response['message']['latest_reactions'][0]['type']).to eq 'love'
85 | end
86 |
87 | it 'can delete a reaction' do
88 | msg = @channel.send_message({ 'text' => 'hi' }, @random_user[:id])
89 | @channel.send_reaction(msg['message']['id'], { 'type' => 'love' }, @random_user[:id])
90 | response = @channel.delete_reaction(msg['message']['id'], 'love', @random_user[:id])
91 | expect(response).to include 'message'
92 | expect(response['message']['latest_reactions'].length).to eq 0
93 | end
94 |
95 | it 'can mute and unmute a channel' do
96 | response = @channel.mute(@random_user[:id])
97 | expect(response['channel_mute']['channel']['cid']).not_to be_empty
98 |
99 | @channel.unmute(@random_user[:id])
100 | end
101 |
102 | it 'can update metadata' do
103 | response = @channel.update({ 'motd' => 'one apple a day...' })
104 | expect(response).to include 'channel'
105 | expect(response['channel']['motd']).to eq 'one apple a day...'
106 | end
107 |
108 | it 'can update metadata partial' do
109 | @channel.update_partial({ color: 'blue', age: 30 }, ['motd'])
110 | response = @channel.query
111 | expect(response['channel']['color']).to eq 'blue'
112 | expect(response['channel']['age']).to eq 30
113 | expect(response['channel']).not_to include 'motd'
114 |
115 | @channel.update_partial({ color: 'red' }, ['age'])
116 | response = @channel.query
117 | expect(response['channel']['color']).to eq 'red'
118 | expect(response['channel']).not_to include 'age'
119 | expect(response['channel']).not_to include 'motd'
120 | end
121 |
122 | it 'can delete' do
123 | response = @channel.delete
124 | expect(response).to include 'channel'
125 | expect(response['channel'].fetch('deleted_at')).not_to eq nil
126 | end
127 |
128 | it 'can truncate' do
129 | response = @channel.truncate
130 | expect(response).to include 'channel'
131 | end
132 |
133 | it 'can truncate with message' do
134 | text = SecureRandom.uuid.to_s
135 | @channel.truncate(message: { text: text, user_id: @random_user[:id] })
136 |
137 | loop_times 60 do
138 | channel_state = @channel.query
139 | expect(channel_state).to include 'messages'
140 | expect(channel_state['messages'][0]['text']).to eq(text)
141 | end
142 | end
143 |
144 | it 'can add members' do
145 | response = @channel.remove_members([@random_users[0][:id], @random_users[1][:id]])
146 | expect(response['members'].length).to eq 0
147 |
148 | @channel.add_members([@random_users[0][:id]])
149 | response = @channel.add_members([@random_users[1][:id]], hide_history: true)
150 | expect(response['members'].length).to eq 2
151 | response['members']&.each do |m|
152 | expect(m.fetch('is_moderator', false)).to be false
153 | end
154 | end
155 |
156 | it 'can invite members' do
157 | response = @channel.remove_members([@random_user[:id]])
158 | expect(response['members'].length).to eq 0
159 |
160 | response = @channel.invite_members([@random_user[:id]])
161 | expect(response['members'].length).to eq 1
162 | expect(response['members'][0].fetch('invited', false)).to be true
163 | end
164 |
165 | it 'can accept invitation' do
166 | @channel.remove_members([@random_user[:id]])
167 | @channel.invite_members([@random_user[:id]])
168 |
169 | @channel.accept_invite(@random_user[:id])
170 | end
171 |
172 | it 'can reject invitation' do
173 | @channel.remove_members([@random_user[:id]])
174 | @channel.invite_members([@random_user[:id]])
175 |
176 | @channel.reject_invite(@random_user[:id])
177 | end
178 |
179 | it 'can add moderators' do
180 | response = @channel.add_moderators([@random_user[:id]])
181 | expect(response['members'][0]['is_moderator']).to be true
182 |
183 | response = @channel.demote_moderators([@random_user[:id]])
184 | expect(response['members'][0].fetch('is_moderator', false)).to be false
185 | end
186 |
187 | it 'can mark messages as read' do
188 | response = @channel.mark_read(@random_user[:id])
189 | expect(response).to include 'event'
190 | expect(response['event']['type']).to eq 'message.read'
191 | end
192 |
193 | it 'can get replies' do
194 | msg = @channel.send_message({ 'text' => 'hi' }, @random_user[:id])
195 | response = @channel.get_replies(msg['message']['id'])
196 | expect(response).to include 'messages'
197 | expect(response['messages'].length).to eq 0
198 | (1..10).each do |i|
199 | @channel.send_message(
200 | { 'text' => 'hi', 'index' => i, 'parent_id' => msg['message']['id'] },
201 | @random_user[:id]
202 | )
203 | end
204 | response = @channel.get_replies(msg['message']['id'])
205 | expect(response).to include 'messages'
206 | expect(response['messages'].length).to eq 10
207 | end
208 |
209 | it 'can get reactions' do
210 | msg = @channel.send_message({ 'text' => 'hi' }, @random_user[:id])
211 | response = @channel.get_reactions(msg['message']['id'])
212 | expect(response).to include 'reactions'
213 | expect(response['reactions'].length).to eq 0
214 |
215 | @channel.send_reaction(msg['message']['id'], { 'type' => 'love', 'count' => 42 }, @random_user[:id])
216 | @channel.send_reaction(msg['message']['id'], { 'type' => 'clap' }, @random_user[:id])
217 |
218 | response = @channel.get_reactions(msg['message']['id'])
219 | expect(response['reactions'].length).to eq 2
220 |
221 | response = @channel.get_reactions(msg['message']['id'], offset: 1)
222 | expect(response['reactions'].length).to eq 1
223 | expect(response['reactions'][0]['count']).to eq 42
224 | end
225 |
226 | it 'send message with pending metadata' do
227 | options = {
228 | is_pending_message: true,
229 | pending_message_metadata: {
230 | metadata: 'some_data'
231 | }
232 | }
233 | msg = @channel.send_message({ text: 'hi' }, @random_user[:id], **options)
234 | response = @client.get_message(msg['message']['id'])
235 | expect(response['message']).not_to be_empty
236 | expect(response['pending_message_metadata']['metadata']).to eq 'some_data'
237 | end
238 |
239 | it 'hides\shows channel for user' do
240 | @channel.hide(@random_user[:id])
241 | @channel.show(@random_user[:id])
242 | end
243 |
244 | file = ''
245 | it 'can send file' do
246 | response = @channel.send_file("#{__dir__}/data/helloworld.txt", @random_user, 'text/plain')
247 | expect(response).to have_key('file')
248 | file = response['file']
249 | end
250 |
251 | it 'delete file' do
252 | @channel.delete_file(file)
253 | end
254 |
255 | image = ''
256 | it 'can send image' do
257 | response = @channel.send_image("#{__dir__}/data/helloworld.jpg", @random_user, 'image/jpeg')
258 | expect(response).to have_key('file')
259 | image = response['file']
260 | end
261 |
262 | it 'delete image' do
263 | @channel.delete_image(image)
264 | end
265 |
266 | it 'query members' do
267 | response = @channel.query_members
268 | expect(response['members'].length).to eq 0
269 |
270 | members = []
271 | @random_users&.each do |u|
272 | members << u[:id]
273 | end
274 | @channel.add_members(members)
275 |
276 | response = @channel.query_members(sort: { name: 1 })
277 | expect(response['members'].length).to eq 2
278 |
279 | got_members = []
280 | response['members']&.each do |m|
281 | got_members << m['user']['id']
282 | end
283 | expect(got_members).to eq members.reverse
284 |
285 | response = @channel.query_members(limit: 1)
286 | expect(response['members'].length).to eq 1
287 |
288 | response = @channel.query_members(filter_conditions: { notifications_muted: true })
289 | expect(response['members'].length).to eq 2
290 | end
291 |
292 | it 'can pin and unpin a channel' do
293 | @channel.add_members([@random_users[0][:id]])
294 | @channel.add_members([@random_users[1][:id]])
295 |
296 | # Pin the channel
297 | now = Time.now
298 | response = @channel.pin(@random_users[0][:id])
299 | expect(response['channel_member']['pinned_at']).not_to be_nil
300 | expect(Time.parse(response['channel_member']['pinned_at']).to_i).to be >= now.to_i
301 |
302 | # Query for pinned channel
303 | response = @client.query_channels({ 'pinned' => true, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
304 | expect(response['channels'].length).to eq 1
305 | expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
306 |
307 | # Unpin the channel
308 | response = @channel.unpin(@random_users[0][:id])
309 | expect(response['channel_member']).not_to have_key('pinned_at')
310 |
311 | # Query for unpinned channel
312 | response = @client.query_channels({ 'pinned' => false, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
313 | expect(response['channels'].length).to eq 1
314 | expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
315 | end
316 |
317 | it 'can archive and unarchive a channel' do
318 | @channel.add_members([@random_users[0][:id]])
319 | @channel.add_members([@random_users[1][:id]])
320 |
321 | # Pin the channel
322 | now = Time.now
323 | response = @channel.archive(@random_users[0][:id])
324 | expect(response['channel_member']['archived_at']).not_to be_nil
325 | expect(Time.parse(response['channel_member']['archived_at']).to_i).to be >= now.to_i
326 |
327 | # Query for archived channel
328 | response = @client.query_channels({ 'archived' => true, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
329 | expect(response['channels'].length).to eq 1
330 | expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
331 |
332 | # Unarchive the channel
333 | response = @channel.unarchive(@random_users[0][:id])
334 | expect(response['channel_member']).not_to have_key('archived_at')
335 |
336 | # Query for unarchived channel
337 | response = @client.query_channels({ 'archived' => false, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
338 | expect(response['channels'].length).to eq 1
339 | expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
340 | end
341 |
342 | it 'can update channel member partially' do
343 | @channel.add_members([@random_users[0][:id]])
344 |
345 | # Test setting a field
346 | response = @channel.update_member_partial(@random_users[0][:id], set: { 'hat' => 'blue' })
347 | expect(response['channel_member']['hat']).to eq 'blue'
348 |
349 | # Test setting and unsetting fields
350 | response = @channel.update_member_partial(@random_users[0][:id], set: { 'color' => 'red' }, unset: ['hat'])
351 | expect(response['channel_member']['color']).to eq 'red'
352 | expect(response['channel_member']).not_to have_key('hat')
353 | end
354 |
355 | it 'can send message with restricted visibility' do
356 | # Send a message that's only visible to specific users
357 | msg = @channel.send_message(
358 | {
359 | 'text' => 'secret message',
360 | 'restricted_visibility' => [@random_users[0][:id], @random_users[1][:id]]
361 | },
362 | @random_user[:id]
363 | )
364 |
365 | # Verify the message was sent successfully
366 | expect(msg).to include 'message'
367 | expect(msg['message']['text']).to eq 'secret message'
368 |
369 | # Verify the restricted visibility
370 | expect(msg['message']['restricted_visibility']).to match_array([@random_users[0][:id], @random_users[1][:id]])
371 | end
372 |
373 | it 'can update message with restricted visibility' do
374 | # First send a regular message
375 | msg = @channel.send_message(
376 | {
377 | 'text' => 'original message'
378 | },
379 | @random_user[:id]
380 | )
381 |
382 | # Update the message with restricted visibility
383 | updated_msg = @client.update_message(
384 | {
385 | 'id' => msg['message']['id'],
386 | 'text' => 'updated secret message',
387 | 'restricted_visibility' => [@random_users[0][:id], @random_users[1][:id]],
388 | 'user' => { 'id' => @random_user[:id] }
389 | }
390 | )
391 |
392 | # Verify the message was updated successfully
393 | expect(updated_msg).to include 'message'
394 | expect(updated_msg['message']['text']).to eq 'updated secret message'
395 |
396 | # Verify the restricted visibility
397 | expect(updated_msg['message']['restricted_visibility']).to match_array([@random_users[0][:id], @random_users[1][:id]])
398 | end
399 |
400 | it 'can update message partially with restricted visibility' do
401 | # First send a regular message
402 | msg = @channel.send_message(
403 | {
404 | 'text' => 'original message',
405 | 'custom_field' => 'original value'
406 | },
407 | @random_user[:id]
408 | )
409 |
410 | # Partially update the message with restricted visibility
411 | updated_msg = @client.update_message_partial(
412 | msg['message']['id'],
413 | {
414 | set: {
415 | text: 'partially updated secret message',
416 | restricted_visibility: [@random_users[0][:id], @random_users[1][:id]]
417 | },
418 | unset: ['custom_field']
419 | },
420 | user_id: @random_user[:id]
421 | )
422 |
423 | # Verify the message was updated successfully
424 | expect(updated_msg).to include 'message'
425 | expect(updated_msg['message']['text']).to eq 'partially updated secret message'
426 |
427 | # Verify the restricted visibility was set
428 | expect(updated_msg['message']['restricted_visibility']).to match_array([@random_users[0][:id], @random_users[1][:id]])
429 |
430 | # Verify the custom field was unset
431 | expect(updated_msg['message']).not_to include 'custom_field'
432 | end
433 |
434 | it 'can create draft message' do
435 | draft_message = { 'text' => 'This is a draft message' }
436 | response = @channel.create_draft(draft_message, @random_user[:id])
437 |
438 | expect(response).to include 'draft'
439 | expect(response['draft']['message']['text']).to eq 'This is a draft message'
440 | expect(response['draft']['channel_cid']).to eq @channel.cid
441 | end
442 |
443 | it 'can get draft message' do
444 | # First create a draft
445 | draft_message = { 'text' => 'This is a draft to retrieve' }
446 | @channel.create_draft(draft_message, @random_user[:id])
447 |
448 | # Then get the draft
449 | response = @channel.get_draft(@random_user[:id])
450 |
451 | expect(response).to include 'draft'
452 | expect(response['draft']['message']['text']).to eq 'This is a draft to retrieve'
453 | expect(response['draft']['channel_cid']).to eq @channel.cid
454 | end
455 |
456 | it 'can delete draft message' do
457 | # First create a draft
458 | draft_message = { 'text' => 'This is a draft to delete' }
459 | @channel.create_draft(draft_message, @random_user[:id])
460 |
461 | # Then delete the draft
462 | @channel.delete_draft(@random_user[:id])
463 |
464 | # Verify it's deleted by trying to get it
465 | expect { @channel.get_draft(@random_user[:id]) }.to raise_error(StreamChat::StreamAPIException)
466 | end
467 |
468 | it 'can create and manage thread draft' do
469 | # First create a parent message
470 | msg = @channel.send_message({ 'text' => 'Parent message' }, @random_user[:id])
471 | parent_id = msg['message']['id']
472 |
473 | # Create a draft reply
474 | draft_reply = { 'text' => 'This is a draft reply', 'parent_id' => parent_id }
475 | response = @channel.create_draft(draft_reply, @random_user[:id])
476 |
477 | expect(response).to include 'draft'
478 | expect(response['draft']['message']['text']).to eq 'This is a draft reply'
479 | expect(response['draft']['parent_id']).to eq parent_id
480 |
481 | # Get the draft reply
482 | response = @channel.get_draft(@random_user[:id], parent_id: parent_id)
483 |
484 | expect(response).to include 'draft'
485 | expect(response['draft']['message']['text']).to eq 'This is a draft reply'
486 | expect(response['draft']['parent_id']).to eq parent_id
487 |
488 | # Delete the draft reply
489 | @channel.delete_draft(@random_user[:id], parent_id: parent_id)
490 |
491 | # Verify it's deleted
492 | expect { @channel.get_draft(@random_user[:id], parent_id: parent_id) }.to raise_error(StreamChat::StreamAPIException)
493 | end
494 | end
495 |
--------------------------------------------------------------------------------
/spec/data/helloworld.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GetStream/stream-chat-ruby/79aa72a75063498490866400e6e027f4f7fa8c72/spec/data/helloworld.jpg
--------------------------------------------------------------------------------
/spec/data/helloworld.txt:
--------------------------------------------------------------------------------
1 | Hello World!
2 |
--------------------------------------------------------------------------------
/spec/moderation_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'jwt'
4 | require 'securerandom'
5 | require 'stream-chat'
6 | require 'faraday'
7 |
8 | describe StreamChat::Moderation do
9 | def loop_times(times)
10 | loop do
11 | begin
12 | yield()
13 | return
14 | rescue StandardError, RSpec::Expectations::ExpectationNotMetError
15 | raise if times.zero?
16 | end
17 |
18 | sleep(1)
19 | times -= 1
20 | end
21 | end
22 |
23 | before(:all) do
24 | @client = StreamChat::Client.from_env
25 |
26 | @created_users = []
27 |
28 | @fellowship_of_the_ring = [
29 | { id: 'frodo-baggins', name: 'Frodo Baggins', race: 'Hobbit', age: 50 },
30 | { id: 'sam-gamgee', name: 'Samwise Gamgee', race: 'Hobbit', age: 38 },
31 | { id: 'gandalf', name: 'Gandalf the Grey', race: 'Istari' },
32 | { id: 'legolas', name: 'Legolas', race: 'Elf', age: 500 }
33 | ]
34 | @client.upsert_users(@fellowship_of_the_ring)
35 | @channel = @client.channel('team', channel_id: 'fellowship-of-the-ring',
36 | data: { members: @fellowship_of_the_ring.map { |fellow| fellow[:id] } })
37 | @channel.create('gandalf')
38 | end
39 |
40 | before(:each) do
41 | @random_users = [{ id: SecureRandom.uuid }, { id: SecureRandom.uuid }]
42 | @random_user = { id: SecureRandom.uuid }
43 | users_to_insert = [@random_users[0], @random_users[1], @random_user]
44 |
45 | @created_users.push(*users_to_insert.map { |u| u[:id] })
46 |
47 | @client.upsert_users(users_to_insert)
48 | end
49 |
50 | after(:all) do
51 | curr_idx = 0
52 | batch_size = 25
53 |
54 | slice = @created_users.slice(0, batch_size)
55 |
56 | while !slice.nil? && !slice.empty?
57 | @client.delete_users(slice, user: StreamChat::HARD_DELETE, messages: StreamChat::HARD_DELETE)
58 |
59 | curr_idx += batch_size
60 | slice = @created_users.slice(curr_idx, batch_size)
61 | end
62 | end
63 |
64 | it 'properly sets up a new client' do
65 | client = StreamChat::Client.from_env
66 |
67 | client.set_http_client(Faraday.new(url: 'https://getstream.io'))
68 | expect { client.get_app_settings }.to raise_error(StreamChat::StreamAPIException)
69 |
70 | client.set_http_client(Faraday.new(url: 'https://chat.stream-io-api.com'))
71 | response = client.get_app_settings
72 | expect(response).to include 'app'
73 | end
74 |
75 | it 'raises ArgumentError if no api_key is provided' do
76 | expect { StreamChat::Client.new(nil, nil) }.to raise_error(TypeError)
77 | end
78 |
79 | it 'properly handles stream response class' do
80 | response = @client.get_app_settings
81 | expect(response.rate_limit.limit).to be > 0
82 | expect(response.rate_limit.remaining).to be > 0
83 | expect(response.rate_limit.reset).to be_within(120).of Time.now.utc
84 | expect(response.status_code).to be 200
85 | expect(response.to_json).not_to include 'rate_limit'
86 | expect(response.to_json).not_to include 'status_code'
87 | end
88 |
89 | describe 'moderation' do
90 | before(:each) do
91 | @moderation = @client.moderation
92 | @test_user_id = SecureRandom.uuid
93 | @test_message_id = SecureRandom.uuid
94 | @test_config_key = SecureRandom.uuid
95 | end
96 |
97 | it 'flagging a user and message' do
98 | msg_response = @channel.send_message({ id: @test_message_id, text: 'Test message' }, @test_user_id)
99 | expect(msg_response['message']['id']).to eq(@test_message_id)
100 | expect(msg_response['message']['user']['id']).to eq(@test_user_id)
101 | response = @moderation.flag_user(
102 | @test_user_id,
103 | 'inappropriate_behavior',
104 | user_id: @random_user[:id],
105 | custom: { severity: 'high' }
106 | )
107 | expect(response['duration']).not_to be_nil
108 | response = @moderation.flag_message(
109 | @test_message_id,
110 | 'inappropriate_content',
111 | user_id: @random_user[:id],
112 | custom: { category: 'spam' }
113 | )
114 | expect(response['duration']).not_to be_nil
115 | end
116 |
117 | it 'mute a user and unmute a user' do
118 | @channel.send_message({ id: @test_message_id, text: 'Test message' }, @test_user_id)
119 | testuserid1 = @random_user[:id]
120 | response = @moderation.mute_user(
121 | @test_user_id,
122 | user_id: testuserid1,
123 | timeout: 60
124 | )
125 | expect(response['duration']).not_to be_nil
126 | expect(response['mutes'][0]['user']['id']).to eq(testuserid1)
127 | response = @moderation.unmute_user(
128 | @test_user_id,
129 | user_id: @random_user[:id]
130 | )
131 | expect(response['duration']).not_to be_nil
132 |
133 | response = @moderation.get_user_moderation_report(
134 | @test_user_id,
135 | include_user_blocks: true,
136 | include_user_mutes: true
137 | )
138 | expect(response['duration']).not_to be_nil
139 | end
140 |
141 | it 'adds custom flags to an entity' do
142 | testuserid1 = @random_user[:id]
143 | testmsgid1 = SecureRandom.uuid
144 | @channel.send_message({ id: testmsgid1, text: 'Test message' }, testuserid1)
145 | entity_type = 'stream:chat:v1:message'
146 | entity_id = testmsgid1
147 | moderation_payload = {
148 | 'texts' => ['Test message'],
149 | 'custom' => { 'original_message_type' => 'regular' }
150 | }
151 | flags = [{ type: 'custom_check_text', value: 'test_flag' }]
152 |
153 | response = @moderation.add_custom_flags(entity_type, entity_id, moderation_payload, flags, entity_creator_id: testuserid1)
154 | expect(response['duration']).not_to be_nil
155 | response = @moderation.add_custom_message_flags(
156 | testmsgid1,
157 | [{ type: 'custom_check_text', value: 'test_flag' }]
158 | )
159 | expect(response['duration']).not_to be_nil
160 | end
161 |
162 | it 'check user profile' do
163 | response = @moderation.check_user_profile(
164 | @test_user_id,
165 | { username: 'fuck_you_123' }
166 | )
167 | expect(response['duration']).not_to be_nil
168 | expect(response['status']).to eq('complete')
169 | expect(response['recommended_action']).to eq('remove')
170 |
171 | response = @moderation.check_user_profile(
172 | @test_user_id,
173 | { username: 'hi' }
174 | )
175 | expect(response['duration']).not_to be_nil
176 | expect(response['status']).to eq('complete')
177 | expect(response['recommended_action']).to eq('keep')
178 | end
179 |
180 | it 'config test' do
181 | # Create moderation config
182 | moderation_config = {
183 | key: "chat:team:#{@channel.id}",
184 | block_list_config: {
185 | enabled: true,
186 | rules: [
187 | {
188 | name: 'profanity_en_2020_v1',
189 | action: 'flag'
190 | }
191 | ]
192 | }
193 | }
194 | @moderation.upsert_config(moderation_config)
195 | response = @moderation.get_config("chat:team:#{@channel.id}")
196 | expect(response['config']['key']).to eq("chat:team:#{@channel.id}")
197 |
198 | response = @moderation.query_configs(
199 | { key: "chat:messaging:#{@channel.id}" },
200 | []
201 | )
202 | expect(response).not_to be_nil
203 |
204 | # Send message that should be blocked
205 | response = @channel.send_message(
206 | { text: 'damn' },
207 | @random_user[:id],
208 | force_moderation: true
209 | )
210 |
211 | # Verify message appears in review queue
212 | queue_response = @moderation.query_review_queue(
213 | { entity_type: 'stream:chat:v1:message' },
214 | { created_at: -1 },
215 | limit: 1
216 | )
217 | expect(queue_response['items'][0]['entity_id']).to eq(response['message']['id'])
218 |
219 | response = @moderation.delete_config("chat:team:#{@channel.id}")
220 | expect(response['duration']).not_to be_nil
221 | end
222 | end
223 | end
224 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'simplecov'
2 | require 'simplecov-console'
3 |
4 | SimpleCov.start do
5 | formatter SimpleCov::Formatter::Console
6 | add_filter '/spec/'
7 | end
8 |
--------------------------------------------------------------------------------
/stream-chat.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | lib = File.expand_path('lib', __dir__)
4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5 | require 'stream-chat/version'
6 |
7 | Gem::Specification.new do |gem|
8 | gem.name = 'stream-chat-ruby'
9 | gem.description = 'Ruby client for Stream Chat.'
10 | gem.version = StreamChat::VERSION
11 | gem.platform = Gem::Platform::RUBY
12 | gem.summary = 'The low level client for serverside calls for Stream Chat.'
13 | gem.email = 'support@getstream.io'
14 | gem.homepage = 'http://github.com/GetStream/stream-chat-ruby'
15 | gem.authors = ['getstream.io']
16 | gem.files = Dir.chdir(File.expand_path(__dir__)) do
17 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|sorbet|spec|\.github|scripts|assets)/}) }
18 | end
19 | gem.required_ruby_version = '>=3.0.0'
20 | gem.metadata = {
21 | 'rubygems_mfa_required' => 'false',
22 | 'homepage_uri' => 'https://getstream.io/chat/docs/',
23 | 'bug_tracker_uri' => 'https://github.com/GetStream/stream-chat-ruby/issues',
24 | 'documentation_uri' => 'https://getstream.io/chat/docs/ruby/?language=ruby',
25 | 'changelog_uri' => 'https://github.com/GetStream/stream-chat-ruby/blob/master/CHANGELOG.md',
26 | 'source_code_uri' => 'https://github.com/GetStream/stream-chat-ruby'
27 | }
28 |
29 | gem.add_dependency 'faraday', '~> 2.12.2'
30 | gem.add_dependency 'faraday-multipart', '~> 1.1.0'
31 | gem.add_dependency 'faraday-net_http_persistent', '~> 2.3.0'
32 | gem.add_dependency 'jwt', '~> 2.10'
33 | gem.add_dependency 'net-http-persistent', '~> 4.0'
34 | gem.add_dependency 'sorbet-runtime', '~> 0.5.11820'
35 | end
36 |
--------------------------------------------------------------------------------