keycloak_ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,656 @@
1
+ # Module for interacting with Keycloak
2
+ module KeycloakRuby
3
+ self.@config: untyped
4
+
5
+ # Returns the singleton configuration object. The configuration is
6
+ # initialized on first access and validated immediately.
7
+ #
8
+ # @return [KeycloakRuby::Config] the configuration object
9
+ def self.config: () -> untyped
10
+
11
+ # Yields the configuration object for block-based configuration.
12
+ # Validates the configuration after the block executes.
13
+ #
14
+ # @yield [KeycloakRuby::Config] the configuration object
15
+ # @raise [ConfigurationError] if configuration is invalid
16
+ def self.configure: () { (untyped) -> untyped } -> untyped
17
+
18
+ VERSION: untyped
19
+ end
20
+
21
+ # lib/keycloak_ruby/user.rb
22
+ module KeycloakRuby
23
+ # User-related operations for interacting with Keycloak.
24
+ # This class provides a simple interface for creating, deleting, and finding users in Keycloak.
25
+ class User
26
+ self.@client: untyped
27
+
28
+ # Creates a new user in Keycloak.
29
+ #
30
+ # @param user_attrs [Hash] A hash of user attributes (e.g., :username, :email, :password, :temporary).
31
+ # @return [Hash] The created user's data.
32
+ # @raise [KeycloakRuby::Error] If the user creation fails.
33
+ def self.create: (?::Hash[untyped, untyped] user_attrs) -> untyped
34
+
35
+ # Deletes users from Keycloak based on a search string.
36
+ #
37
+ # @param search_string [String] A string to search for users (e.g., username, email, etc.).
38
+ # @return [void]
39
+ # @raise [KeycloakRuby::Error] If any user deletion fails.
40
+ def self.delete: (untyped search_string) -> untyped
41
+
42
+ # Deletes a user from Keycloak by ID.
43
+ #
44
+ # @param user_id [String] The ID of the user to delete.
45
+ # @return [void]
46
+ # @raise [KeycloakRuby::Error] If the deletion fails.
47
+ def self.delete_by_id: (untyped user_id) -> untyped
48
+
49
+ # Finds users in Keycloak based on a search string.
50
+ #
51
+ # @param search_string [String] A string to search for users (e.g., username, email, etc.).
52
+ # @return [Array<Hash>] An array of user objects (hashes) matching the search criteria.
53
+ # @raise [KeycloakRuby::Error] If the search fails.
54
+ def self.find: (untyped search_string) -> untyped
55
+
56
+ private
57
+
58
+ # Provides a singleton instance of the KeycloakRuby::Client.
59
+ #
60
+ # @return [KeycloakRuby::Client] The client instance used for making API requests.
61
+ def self.client: () -> untyped
62
+ end
63
+ end
64
+
65
+ module KeycloakRuby
66
+ # Responsible for performing HTTP requests with HTTParty
67
+ # and validating the response. This class helps to reduce
68
+ # FeatureEnvy and keep the Client code cleaner.
69
+ # :reek:FeatureEnvy
70
+ class RequestPerformer
71
+ @config: untyped
72
+
73
+ def initialize: (untyped config) -> void
74
+
75
+ # Executes an HTTP request and verifies the response code.
76
+ #
77
+ # @param request_params [KeycloakRuby::RequestParams] - an object containing
78
+ # :http_method, :url, :headers, :body, :success_codes, :error_class, :error_message
79
+ #
80
+ # @return [HTTParty::Response] The HTTParty response object on success.
81
+ # @raise [request_params.error_class] If the response code is not in success_codes
82
+ # or HTTParty raises an error.
83
+ def call: (untyped request_params) -> untyped
84
+
85
+ private
86
+
87
+ # Safe validation: returns true/false
88
+ def verify_response: (untyped response, untyped request_params) -> untyped
89
+
90
+ # Bang version that raises an error on invalid response
91
+ def verify_response!: (untyped response, untyped request_params) -> (nil | untyped)
92
+ end
93
+ end
94
+
95
+ # keycloak_ruby/testing/keycloak_helpers.rb
96
+ # :reek:UtilityFunction :reek:ControlParameter :reek:ManualDispatch :reek:BooleanParameter :reek:LongParameterList
97
+ module KeycloakRuby
98
+ module Testing
99
+ # Helper module for tests with Keycloak
100
+ module KeycloakHelpers
101
+ self.@keycloak_users: untyped
102
+
103
+ # Combines both sign-in approaches with automatic detection of test type
104
+ def sign_in: (untyped user, ?test_type: untyped) -> untyped
105
+
106
+ # Мокирует авторизацию в request-тестах, подставляя указанного пользователя в current_user.
107
+ # Нужно, так как в request-тестах нет прямого доступа к сессиям и внешним сервисам авторизации.
108
+ def mock_token_service: (untyped user) -> untyped
109
+
110
+ def create_keycloak_user: (username: untyped, email: untyped, password: untyped, temporary: untyped) -> untyped
111
+
112
+ # Delete all users from Keycloak
113
+ def self.delete_all_keycloak_users: () -> untyped
114
+
115
+ def self.track_keycloak_user: (untyped user_id) -> untyped
116
+
117
+ def self.cleanup_keycloak_users: () -> (nil | untyped)
118
+
119
+ private
120
+
121
+ def mock_keycloak_login: (untyped user, ?use_capybara: bool) -> untyped
122
+
123
+ def capybara_login: () -> untyped
124
+
125
+ def generate_fake_tokens: (untyped user) -> untyped
126
+
127
+ def store_session: (untyped credentials) -> untyped
128
+
129
+ def rspec_auto_detect_test_type: () -> (:request | :feature | :controller)
130
+
131
+ def auto_detect_test_type: () -> (untyped | :feature)
132
+ end
133
+ end
134
+ end
135
+
136
+ module Minitest
137
+ class Test
138
+ include KeycloakRuby::Testing::KeycloakHelpers
139
+ end
140
+ end
141
+
142
+ module KeycloakRuby
143
+ # Validates Keycloak API responses with both safe and strict modes
144
+ #
145
+ # Provides two validation approaches:
146
+ # 1. Safe validation (#validate) - returns boolean
147
+ # 2. Strict validation (#validate!) - raises detailed exceptions
148
+ #
149
+ # @example Safe validation
150
+ # validator = ResponseValidator.new(response)
151
+ # if validator.validate
152
+ # # proceed with valid response
153
+ # else
154
+ # # handle invalid response
155
+ # end
156
+ #
157
+ # @example Strict validation
158
+ # begin
159
+ # data = ResponseValidator.new(response).validate!
160
+ # # use validated data
161
+ # rescue KeycloakRuby::Errors::TokenRefreshFailed => e
162
+ # # handle error
163
+ # end
164
+ class ResponseValidator
165
+ @response: untyped
166
+
167
+ @data: untyped
168
+
169
+ # Initialize with the HTTP response
170
+ # @param response [HTTP::Response] The raw HTTP response from Keycloak
171
+ def initialize: (untyped response) -> void
172
+
173
+ # Safe validation - returns boolean instead of raising exceptions
174
+ # @return [Boolean] true if response is valid, false otherwise
175
+ def validate: () -> (false | untyped)
176
+
177
+ # Strict validation - raises exceptions for invalid responses
178
+ # @return [Hash] Parsed response data if valid
179
+ # @raise [KeycloakRuby::Errors::TokenRefreshFailed] if validation fails
180
+ def validate!: () -> untyped
181
+
182
+ private
183
+
184
+ # Parses JSON response body, returns empty hash on failure
185
+ # @return [Hash]
186
+ def parse_response_body: () -> untyped
187
+
188
+ # Checks if HTTP status indicates success
189
+ # @return [Boolean]
190
+ def valid_http_status?: () -> untyped
191
+
192
+ # Checks for OAuth2 "invalid_grant" error
193
+ # @return [Boolean]
194
+ def invalid_grant?: () -> untyped
195
+
196
+ # Checks for any error in response
197
+ # @return [Boolean]
198
+ def error_present?: () -> untyped
199
+
200
+ # Verifies access token presence
201
+ # @return [Boolean]
202
+ def access_token_present?: () -> untyped
203
+
204
+ # Raises appropriate validation error based on failure reason
205
+ # @raise [KeycloakRuby::Errors::TokenRefreshFailed]
206
+ def raise_validation_error: () -> untyped
207
+
208
+ # Extracts error message from response
209
+ # @return [String]
210
+ def extract_error_message: () -> (untyped | untyped | "See response body for details")
211
+ end
212
+ end
213
+
214
+ # lib/keycloak_ruby/config.rb
215
+ module KeycloakRuby
216
+ # Configuration class for Keycloak Ruby gem.
217
+ #
218
+ # Handles loading and validation of Keycloak configuration from either:
219
+ # - A YAML file (default: config/keycloak.yml)
220
+ # - Direct attribute assignment
221
+ #
222
+ # == Example YAML Configuration
223
+ #
224
+ # development:
225
+ # keycloak_url: "https://keycloak.example.com"
226
+ # app_host: "http://localhost:3000"
227
+ # realm: "my-realm"
228
+ # oauth_client_id: "my-client"
229
+ # oauth_client_secret: "secret"
230
+ #
231
+ # == Example Programmatic Configuration
232
+ #
233
+ # config = KeycloakRuby::Config.new
234
+ # config.keycloak_url = "https://keycloak.example.com"
235
+ # config.realm = "my-realm"
236
+ # # ... etc
237
+ # :reek:MissingSafeMethod
238
+ class Config
239
+ @config_path: untyped
240
+
241
+ # Default path to configuration file (Rails.root/config/keycloak.yml)
242
+ DEFAULT_CONFIG_PATH: untyped
243
+
244
+ REQUIRED_ATTRIBUTES: ::Array[:keycloak_url | :app_host | :realm | :oauth_client_id | :oauth_client_secret]
245
+
246
+ # :reek:Attribute
247
+ attr_accessor keycloak_url: untyped
248
+
249
+ # :reek:Attribute
250
+ attr_accessor app_host: untyped
251
+
252
+ # :reek:Attribute
253
+ attr_accessor realm: untyped
254
+
255
+ # :reek:Attribute
256
+ attr_accessor admin_client_id: untyped
257
+
258
+ # :reek:Attribute
259
+ attr_accessor admin_client_secret: untyped
260
+
261
+ # :reek:Attribute
262
+ attr_accessor oauth_client_id: untyped
263
+
264
+ # :reek:Attribute
265
+ attr_accessor oauth_client_secret: untyped
266
+
267
+ attr_reader config_path: untyped
268
+
269
+ # Initialize configuration, optionally loading from YAML file
270
+ #
271
+ # @param config_path [String] Path to YAML config file (default: config/keycloak.yml)
272
+ #
273
+ #
274
+ def initialize: (?untyped config_path) -> void
275
+
276
+ def validate!: () -> untyped
277
+
278
+ def realm_url: () -> ::String
279
+
280
+ def redirect_url: () -> ::String
281
+
282
+ def logout_url: () -> ::String
283
+
284
+ def token_url: () -> ::String
285
+
286
+ private
287
+
288
+ # Loads configuration from YAML file if it exists
289
+ # :reek:ManualDispatch
290
+ def load_config: () -> (nil | untyped)
291
+
292
+ def load_yaml_file: () -> untyped
293
+
294
+ def current_env: () -> untyped
295
+
296
+ def apply_config: (untyped config_hash) -> untyped
297
+ end
298
+ end
299
+
300
+ module KeycloakRuby
301
+ # Include test methods
302
+ module Testing
303
+ def self.included: (untyped base) -> untyped
304
+ end
305
+ end
306
+
307
+ # lib/keycloak_ruby/request_params.rb
308
+ module KeycloakRuby
309
+ # A small, typed struct for request parameters
310
+ RequestParams: untyped
311
+ end
312
+
313
+ # lib/keycloak_ruby/errors.rb
314
+ module KeycloakRuby
315
+ # Namespace for all KeycloakRuby specific errors
316
+ # Follows a hierarchical structure for better error handling
317
+ module Errors
318
+ # Base error class for all KeycloakRuby errors
319
+ # All custom errors inherit from this class
320
+ class Error < StandardError
321
+ end
322
+
323
+ # Raised when there's an issue with gem configuration
324
+ class ConfigurationError < Error
325
+ end
326
+
327
+ # Base class for authentication failures
328
+ class AuthenticationError < Error
329
+ end
330
+
331
+ # Raised when user credentials are invalid
332
+ class InvalidCredentials < AuthenticationError
333
+ end
334
+
335
+ # Raised when user account is not found
336
+ class UserNotFound < AuthenticationError
337
+ end
338
+
339
+ # Raised when account is temporarily locked
340
+ class AccountLocked < AuthenticationError
341
+ end
342
+
343
+ # Raised when user creation fails
344
+ class UserCreationError < Error
345
+ end
346
+
347
+ # Raised when user update fails
348
+ class UserUpdateError < Error
349
+ end
350
+
351
+ # Raised when user deletion fails
352
+ class UserDeletionError < Error
353
+ end
354
+
355
+ # Base class for all token-related errors
356
+ class TokenError < Error
357
+ end
358
+
359
+ # Raised when token has expired +
360
+ class TokenExpired < TokenError
361
+ end
362
+
363
+ # Raised when token is invalid (malformed, wrong signature, etc.)
364
+ class TokenInvalid < TokenError
365
+ end
366
+
367
+ # Raised when token refresh fails
368
+ class TokenRefreshFailed < TokenError
369
+ end
370
+
371
+ # Raised when token verification fails
372
+ class TokenVerificationFailed < TokenError
373
+ end
374
+
375
+ # Raised when API request fails
376
+ class APIError < Error
377
+ end
378
+
379
+ # Raised when receiving 4xx responses from Keycloak
380
+ class ClientError < APIError
381
+ end
382
+
383
+ # Raised when receiving 5xx responses from Keycloak
384
+ class ServerError < APIError
385
+ end
386
+
387
+ # Raised when connection to Keycloak fails
388
+ class ConnectionError < APIError
389
+ end
390
+ end
391
+ end
392
+
393
+ # lib/keycloak_ruby/token_service.rb
394
+ # :reek:FeatureEnvy
395
+ module KeycloakRuby
396
+ # Service for check and refresh jwt tokens
397
+ class TokenService
398
+ @session: untyped
399
+
400
+ @config: untyped
401
+
402
+ @refresh_mutex: untyped
403
+
404
+ @fetch_jwks: untyped
405
+
406
+ @issuer_url: untyped
407
+
408
+ def initialize: (untyped session, ?untyped config) -> void
409
+
410
+ # Finds user by token claims
411
+ # @return [User, nil]
412
+ def find_user: () -> (nil | untyped)
413
+
414
+ # Store token
415
+ def store_tokens: (untyped data) -> untyped
416
+
417
+ def clear_tokens: () -> untyped
418
+
419
+ private
420
+
421
+ # It's necessary, because omniauth return request.env["omniauth.auth"] as 'token', not 'access_token'
422
+ def extract_access_token: (untyped data) -> untyped
423
+
424
+ # Gets current token or attempts refresh if expired
425
+ # @return [Hash, nil] Decoded token claims
426
+ def current_token: () -> untyped
427
+
428
+ # Decodes JWT token
429
+ # @raise [Errors::TokenExpired, Errors::TokenInvalid]
430
+ def decode_token: (untyped token) -> untyped
431
+
432
+ def fetch_jwks: () -> untyped
433
+
434
+ # Attempts to refresh the current token
435
+ def refresh_current_token: () -> untyped
436
+
437
+ # JWT decoding options with JWKS
438
+ def jwt_decode_options: () -> { algorithms: ::Array["RS256"], verify_iss: true, iss: untyped, aud: untyped, verify_expiration: true, jwks: untyped }
439
+
440
+ # Constructs issuer URL from configuration
441
+ def issuer_url: () -> untyped
442
+ end
443
+ end
444
+
445
+ # lib/keycloak_ruby/token_refresher.rb`
446
+ module KeycloakRuby
447
+ # Handles OAuth2 refresh token flow with Keycloak
448
+ #
449
+ # Responsible for:
450
+ # - Executing refresh token requests
451
+ # - Validating responses
452
+ # - Managing refresh failures
453
+ #
454
+ # @example Basic usage
455
+ # refresher = TokenRefresher.new(session, config)
456
+ # new_tokens = refresher.call
457
+ #
458
+ # @example With error handling
459
+ # begin
460
+ # refresher.call
461
+ # rescue KeycloakRuby::Errors::TokenRefreshFailed => e
462
+ # # Handle token refresh failure (e.g., redirect to login)
463
+ # end
464
+ class TokenRefresher
465
+ @session: untyped
466
+
467
+ @config: untyped
468
+
469
+ def initialize: (untyped session, untyped config) -> void
470
+
471
+ # Main entry point - refreshes the token
472
+ # @return [Hash] New token data if successful
473
+ # @raise [KeycloakRuby::Errors::TokenRefreshFailed] if refresh fails
474
+ def call: () -> untyped
475
+
476
+ private
477
+
478
+ def refresh_token_flow: () -> untyped
479
+
480
+ def request_refresh: () -> untyped
481
+
482
+ def validate_response: (untyped response) -> untyped
483
+
484
+ def handle_http_error: (untyped exception) -> untyped
485
+
486
+ # :reek:FeatureEnvy
487
+ def handle_failed_validation: (untyped response) -> untyped
488
+
489
+ def refresh_params: () -> { grant_type: "refresh_token", client_id: untyped, client_secret: untyped, refresh_token: untyped }
490
+
491
+ def headers: () -> { "Content-Type" => "application/x-www-form-urlencoded", "Accept" => "application/json", "User-Agent" => ::String }
492
+
493
+ def log_refresh_attempt: () -> untyped
494
+
495
+ def log_successful_refresh: () -> untyped
496
+ end
497
+ end
498
+
499
+ # lib/keycloak_ruby/client.rb
500
+ module KeycloakRuby
501
+ # Client for interacting with Keycloak (create, delete, and find users, etc.).
502
+ # rubocop:disable Metrics/ClassLength
503
+ # rubocop:disable Metrics/MethodLength
504
+ # :reek:TooManyMethods
505
+ class Client
506
+ @config: untyped
507
+
508
+ @request_performer: untyped
509
+
510
+ def initialize: (?untyped config) -> void
511
+
512
+ # Authenticates a user with Keycloak and returns token data upon success.
513
+ #
514
+ # @param username [String] The user's username or email.
515
+ # @param password [String] The user's password.
516
+ # @return [Hash] The token data (access_token, refresh_token, id_token, etc.).
517
+ # @raise [KeycloakRuby::Errors::InvalidCredentials] If authentication fails.
518
+ def authenticate_user: (username: untyped, password: untyped) -> untyped
519
+
520
+ # Creates a user in Keycloak and returns the newly created user's data.
521
+ #
522
+ # @param user_attrs [Hash] A hash of user attributes. Must contain:
523
+ # :username, :email, :password, :temporary
524
+ # @option user_attrs [String] :username The username for the new user.
525
+ # @option user_attrs [String] :email The user's email.
526
+ # @option user_attrs [String] :password The initial password.
527
+ # @option user_attrs [Boolean] :temporary Whether to force a password update on first login.
528
+ #
529
+ # @raise [KeycloakRuby::Errors::UserCreationError] If user creation fails.
530
+ # @return [Hash] The newly created user's data.
531
+ def create_user: (?::Hash[untyped, untyped] user_attrs) -> untyped
532
+
533
+ # Deletes all users that match the provided search string (e.g., username, email).
534
+ #
535
+ # @param search_string [String] The search criteria for finding users in Keycloak.
536
+ # @raise [KeycloakRuby::Errors::UserDeletionError] If any user deletion fails.
537
+ def delete_users: (untyped search_string) -> untyped
538
+
539
+ # Deletes a single user by ID in Keycloak.
540
+ #
541
+ # @param user_id [String] The ID of the user to delete.
542
+ # @raise [KeycloakRuby::Errors::UserDeletionError] If the deletion fails.
543
+ def delete_user_by_id: (untyped user_id) -> untyped
544
+
545
+ # Finds all users in Keycloak that match the given search string.
546
+ #
547
+ # @param search [String] The search query (e.g., part of username or email).
548
+ # @return [Array<Hash>] An array of user objects.
549
+ # @raise [KeycloakRuby::Errors::APIError] If the request fails.
550
+ def find_users: (untyped search) -> untyped
551
+
552
+ # Updates the redirect URIs for a specific client in Keycloak.
553
+ #
554
+ # @param client_id [String] The client ID in Keycloak.
555
+ # @param redirect_uris [Array<String>] A list of valid redirect URIs for this client.
556
+ # @raise [KeycloakRuby::Errors::ConnectionError] If the update request fails.
557
+ def update_client_redirect_uris: (client_id: untyped, redirect_uris: untyped) -> untyped
558
+
559
+ private
560
+
561
+ def build_auth_body: (untyped username, untyped password) -> { client_id: untyped, client_secret: untyped, username: untyped, password: untyped, grant_type: "password" }
562
+
563
+ def build_user_data: (untyped attrs) -> { username: untyped, email: untyped, enabled: true, credentials: ::Array[{ type: "password", value: untyped, temporary: untyped }] }
564
+
565
+ # Builds RequestParams and passes them to the RequestPerformer.
566
+ def http_request: (?::Hash[untyped, untyped] options) -> untyped
567
+
568
+ def build_request_params: (untyped opts) -> untyped
569
+
570
+ # Retrieves client details by its "clientId".
571
+ #
572
+ # @param client_id [String] The "clientId" in Keycloak.
573
+ # @return [Hash] The client details.
574
+ # @raise [KeycloakRuby::Errors::ClientError] If no matching client is found or the request fails.
575
+ def find_client_by_id: (untyped client_id) -> untyped
576
+
577
+ # Performs a PUT request to update the redirect URIs for a given client in Keycloak.
578
+ #
579
+ # @param client_id [String] The internal Keycloak client ID.
580
+ # @param redirect_uris [Array<String>] List of valid redirect URIs for this client.
581
+ # @raise [KeycloakRuby::Errors::ConnectionError] If the update request fails.
582
+ def update_redirect_uris_for: (untyped client_id, untyped redirect_uris) -> untyped
583
+
584
+ # Fetches a user by ID from Keycloak.
585
+ #
586
+ # @param user_id [String] The user's ID in Keycloak.
587
+ # @return [Hash] The Keycloak user data.
588
+ # @raise [KeycloakRuby::Errors::UserNotFound] If the user cannot be found or the request fails.
589
+ def fetch_user: (untyped user_id) -> untyped
590
+
591
+ # Retrieves the admin token used to authenticate calls to the Keycloak Admin API.
592
+ #
593
+ # @return [String] The admin access token.
594
+ # @raise [KeycloakRuby::Errors::TokenVerificationFailed] If the token request fails.
595
+ def admin_token: () -> untyped
596
+
597
+ # Returns a set of default headers for requests requiring the admin token.
598
+ #
599
+ # @return [Hash] A headers Hash including Authorization and Content-Type.
600
+ def default_headers: () -> { "Authorization" => ::String, "Content-Type" => "application/json" }
601
+ end
602
+ end
603
+
604
+ # lib/keycloak_ruby/version.rb
605
+ # Module for interacting with Keycloak
606
+ module KeycloakRuby
607
+ # Version module following Semantic Versioning 2.0 guidelines
608
+ # Provides detailed version information and helper methods
609
+ #
610
+ # @example Getting version information
611
+ # KeycloakRuby::Version::VERSION # => "0.1.0"
612
+ # KeycloakRuby::Version.to_a # => [0, 1, 0]
613
+ # KeycloakRuby::Version.to_h # => { major: 0, minor: 1, patch: 0, pre: nil }
614
+ # KeycloakRuby.version # => "0.1.0"
615
+ #
616
+ # @example Checking version
617
+ # KeycloakRuby::Version >= '0.1.0' # => true
618
+ # Module for work with Version
619
+ module Version
620
+ # Major version number (incompatible API changes)
621
+ MAJOR: 0
622
+
623
+ # Minor version number (backwards-compatible functionality)
624
+ MINOR: 1
625
+
626
+ # Patch version number (backwards-compatible bug fixes)
627
+ PATCH: 0
628
+
629
+ # Pre-release version (nil for stable releases)
630
+ PRE: nil
631
+
632
+ # Full version string
633
+ VERSION: untyped
634
+
635
+ # Returns version components as an array
636
+ # @return [Array<Integer, Integer, Integer, String|nil>]
637
+ def self.to_a: () -> ::Array[untyped]
638
+
639
+ # Returns version components as a hash
640
+ # @return [Hash<Symbol, Integer|String|nil>]
641
+ def self.to_h: () -> { major: untyped, minor: untyped, patch: untyped, pre: untyped }
642
+
643
+ # Compares version with another version string
644
+ # @param version_string [String] version to compare with (e.g., "1.2.3")
645
+ # @return [Boolean]
646
+ def self.>=: (untyped version_string) -> untyped
647
+
648
+ # Returns the full version string
649
+ # @return [String]
650
+ def self.to_s: () -> untyped
651
+ end
652
+
653
+ # Returns the current gem version
654
+ # @return [String]
655
+ def self.version: () -> untyped
656
+ end