kapellmeister 0.9.8.rc1 → 0.9.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d27342cd8e4485dd5eaee6080b8eaa8d326075866b064c33c34de8b89e53a86
4
- data.tar.gz: 98bf453ec2448a29339b68e1f7a23651ccffc0f0ac8ed681cf6dc4afca6a3c60
3
+ metadata.gz: 00d0f29f4135cca35f1b74b9eb59e04686a30ce257e7448620fd7131faf73c6f
4
+ data.tar.gz: feeb5460b5771b5a1974c4a452d0b83f9046dcbc5b1b3e931b3d4c77febf862a
5
5
  SHA512:
6
- metadata.gz: 722595edfdcf3897d2aaaab02e43ed16e0238c53cc48906f6860b26849d43024a86adc24f77e2032fb390f4a96592767d5577240b4ae9d0362549d1136ce7826
7
- data.tar.gz: df18849b8fd401b32dc6fda74f1bd487264b00a85c1cd91e0bc65ab4059b215e60b7e05f146c4ad3313987db7c9f99b59cbe60f4e01c561263a70a7c17db64c5
6
+ metadata.gz: 321dd035242112e8ec715b68a7c2df4f10d0a14f8e47839d49b78e4bd81785c104aeac1a0c1a550b24f3badfd95950b79d0386db500c2e50b89d3177b16cda48
7
+ data.tar.gz: aff7e0ee44980ed3a92d5530ec57d97c7cba429f9d6cf8f876f59a06c7349fccfd4e7dc36f73e725a3dd71c8ffd4258b6ccd20e2f794f027adaa3409fb96032d
data/Gemfile CHANGED
@@ -6,9 +6,9 @@ gemspec
6
6
 
7
7
  gem 'dry-schema'
8
8
  gem 'faraday'
9
- gem 'faraday-follow_redirects'
9
+ gem 'faraday_middleware'
10
10
  gem 'faraday-cookie_jar'
11
- gem 'faraday-typhoeus'
11
+ gem 'typhoeus'
12
12
 
13
13
  # debug
14
14
  group :development do
@@ -23,6 +23,6 @@ group :development, :test do
23
23
  gem 'rubocop', require: false
24
24
  gem 'rubocop-performance'
25
25
  gem 'rubocop-rspec'
26
- gem 'rubycritic', '~> 4.9.1', require: false
26
+ gem 'rubycritic', require: false
27
27
  gem 'ruby_gntp'
28
28
  end
data/README.md CHANGED
@@ -1,132 +1,3 @@
1
- # Диспетчер HTTP-запросов
2
-
3
- Этот шаблонизатор позволяет вам определять http-запросы к любым сторонним API с помощью упрощенного набора инструкций, включая анализатор маршрутов в формате yaml
4
- ## Использование
5
-
6
- Добавьте kapellmeister в свой Gemfile:
7
- На данный момент послденяя версия 0.9.8 (Проект находится в стадии тестирования работоспособности, beta-test)
8
- ```ruby
9
- gem 'kapellmeister', '~> 0.9.8'
10
- ```
11
-
12
- ### Добавьте новую конфигурацию для стороннего API:
13
-
14
- $ bin/rails g kapellmeister:add_service %<ThirdPartyName> %<options> --%<flags>
15
-
16
- `ThirdPartyName` — Имя сервиса, может быть указан как КэмелКейсом (CamelCase) так и с нижним_подчёркиванием (under_scored)
17
-
18
- `options` — Укажите ключи конфигурации, обычно это хост, ключ и версия
19
-
20
- `flags` — Этот шаблонзатор пока что имеет один флаг.
21
- Флаг `responder`, `false` — значение по-умолчанию.
22
- Если вы установите для него значение `true`, то будет сгенерирован файл responder.rb используемый для анализа и парсинга ответа.
23
-
24
- Все инструкции — это легковесные файлы в каталоге /lib вашего приложения.
25
- Вот пример структуры:
26
-
27
- ``` Capfile
28
- └── app
29
- └── lib
30
- └── third_party_service
31
- ├── client.rb
32
- ├── configuration.rb
33
- ├── responder.rb (опционально)
34
- └── routes.yml
35
- └── third_party_service.rb
36
- └── initializers
37
- └── third_party_service.rb
38
- ```
39
-
40
- Если вы используете Rails, в вашем приложении есть папка `initializers`. Добавьте секретные ключи в файле-инициализаторе
41
-
42
- initializers/third_party_service.rb
43
-
44
- Основной файл вашей интеграции, миксин, включающий Kapellmeister::Base
45
-
46
- app/lib/third_party_service.rb
47
-
48
- Каталог, содержащий `routes scheme`, `client`, `configuration` и опциональный `responder`.
49
-
50
- app/lib/third_party_service
51
-
52
-
53
-
54
- `routes.yml` — Маршруты к стороннему API во вложенном формате.
55
-
56
- ``` yaml
57
- foo: => Обёртка для метода
58
- bar: => Наименование метода
59
- scheme: => Описание схемы
60
- method: POST => Тип запроса (* обязательный параметр!)
61
- use_wrapper: true => Обёрнуть ли метод для обеспечения уникальности. По умолчанию true
62
- path: buz => Настоящий путь (роут). Если параметра нет, то путь будет взят из наименования метода.
63
- body: => Dry-scheme (из набора гемов DRY) для проверки параметров. Если параметра нет, то проверки не будет.
64
- query_params: => Описание query-параметров. Если параметра нет, то подстановки параметров не будет.
65
- mock: => Структура или путь к файлу mock для тестов. Если параметра нет, в среде разработки будет возвращён реальный ответ на запрос.
66
-
67
- # Результат из примера выше:
68
- # client = ThirdParty::Client.new
69
- # client.foo_bar { a: 'b' }
70
- # => POST https://third_party.com/foo/buz DATA: { a: 'b' }
71
- ```
72
- #### Пояснение к параметрам:
73
-
74
- `body` — Вы можете использовать dry-scheme (из набора гемов DRY) для проверки параметров запроса.
75
- Если этот ключ не существует, проверка будет пропущена.
76
- Пример:
77
-
78
- ```yaml
79
- body: DrySchema
80
- ```
81
-
82
- `query_params` — Если для запроса требуется query-параметры.
83
- Работают как массивы, так и руби-хэши.
84
- Если этот ключ не существует, то подстановки параметров и их проверки не будет.
85
- For example:
86
-
87
- ```yaml
88
- query_params:
89
- dbAct: getCities => Пример использования известных и неизменяемых параметров
90
- optional: => Пример использования опциональных параметров. Они будут подставлены при передачи их при запросе
91
- - city
92
- - state
93
-
94
- # Результат из примера выше:
95
- # /api?dbAct=getCities&city=Tokio
96
- ```
97
- ```yaml
98
- query_params:
99
- - dbAct: getTarif
100
- - org => Пример использования обязательных параметров.
101
- - dest
102
- - weight
103
-
104
- # Результат из примера выше:
105
- # /api?dbAct=getTarif&org=Tokio&dest=Beijing&weight=100
106
- ```
107
-
108
- `mock` — Если вам нужно, чтобы реальные запросы не проходили во время тестирования,
109
- вы можете заменить их на mocks.
110
- Можно использовать как структуру yaml, так и путь к файлу yaml.
111
- Например:
112
-
113
- ```yaml
114
- mock: spec/mocks/http_clients/public/cities.yml
115
- ```
116
-
117
- #### Объяснение сгенерированных файлов
118
-
119
- `client.rb` — Унаследованный файл от главного диспетчера, и вы можете добавить некоторые методы настройки, пользовательские заголовки, параметры запросов, query-параметры.
120
-
121
- `configuration.rb` — Добавляем путь к стороннему API, URL-адрес конфигурации и логгер.
122
-
123
- `responder.rb` — По умолчанию используется стандартный обработчик ответов, обработанный в формате json. Но вы можете написать свой собственный.
124
-
125
-
126
-
127
- ---
128
- ### english
129
-
130
1
  # HTTP requests dispatcher
131
2
 
132
3
  This template-service allows you to define http requests to a third party through a lightweight set of instructions, including a route parser in yaml format
@@ -134,25 +5,25 @@ This template-service allows you to define http requests to a third party throug
134
5
  ## Usage
135
6
 
136
7
  Add kapellmeister to your Gemfile:
137
- At the moment, the latest version is 0.9.8 (The project is in the stage of performance testing, beta-test)
8
+
138
9
  ```ruby
139
10
  gem 'kapellmeister', '~> 0.9.6'
140
11
  ```
141
12
 
142
- ### Add a new configuration for the third-party API:
13
+ ### Add new third party configuration:
143
14
 
144
15
  $ bin/rails g kapellmeister:add_service %<ThirdPartyName> %<options> --%<flags>
145
16
 
146
- `ThirdPartyName` — The name of the service, can be specified either CamelCased or under_scored
17
+ `ThirdPartyName` — Pass the lib name, either CamelCased or under_scored
147
18
 
148
- `options` — Specify the configuration keys, usually `host`, `key` and `version`
19
+ `options` — Pass the configuration keys, usually host, key and version
149
20
 
150
- `flags` — This generator has only one flag so far.
151
- The `responder` flag, `false` is the default value.
152
- If you set it to `true`, the responder.rb file will be generated, which is used for analyzing and parsing the response.
21
+ `flags` — This generator have one flag.
22
+ This flag is `responder`, default is `false`.
23
+ If you set it to `true` will be generated responder.rb used for parsing response.
153
24
 
154
- All instructions are lightweight files in the /lib directory of your application.
155
- Here is an example of the structure:
25
+ All the instructions are lightweight files in your /lib folder.
26
+ Here's the example of structure:
156
27
 
157
28
  ``` Capfile
158
29
  └── app
@@ -169,86 +40,83 @@ Here is an example of the structure:
169
40
 
170
41
  initializers/third_party_service.rb
171
42
 
172
- If you are using Rails gem, there is a `initializers` folder in your application. Add the secret keys in the initializer file.
43
+ If you use the Rails gem you have the `initializers` folder in your application. Add the secret keys to config.
173
44
 
174
45
  app/lib/third_party_service.rb
175
46
 
176
- The main file of your integration, a mixin that includes Kapellmeister::Base
47
+ Main file of your integration. Make it module and include the Kapellmeister::Base
177
48
 
178
49
  app/lib/third_party_service
179
50
 
180
- A directory containing `routes scheme`, `client`, `configuration` and an optional `responder`.
51
+ Folder contains `routes scheme`, `client`, `configuration` and optional `responder`.
181
52
 
182
- `routes.yml` — Routes to a third-party API in a nested format.
53
+ `routes.yml` — Routes to third party in nested format.
183
54
 
184
55
  ``` yaml
185
- foo: => Wrapper of the method
186
- bar: => Name of the method
187
- scheme: => Description of the scheme
56
+ foo: => Wrapper for method
57
+ bar: => Method name
58
+ scheme: => Scheme description
188
59
  method: POST => Request type (* required)
189
- use_wrapper: true => Whether to wrap the method to ensure uniqueness. By default, true
190
- path: buz => The real path (route). If there is no parameter, the path will be taken from the method name.
191
- body: => Dry-scheme (from the set of DRY gems) to check the parameters. If there is no parameter, then there'll be no verification.
192
- query_params: => Description of the query parameters. If there is no parameter, then there'll be no parameter substitution.
193
- mock: => The structure or path to the mock file for the tests. If there is no parameter, the actual response to the request will be returned in the development environment.
60
+ use_wrapper: true => Wrap method for uniqueness. Default true
61
+ path: buz => Real path
62
+ body: => Dry schema for checking parameters. If key doesn't exist nothing happens
63
+ query_params: => Query params. If key doesn't exist nothing happens
64
+ mock: => Structure or Path to mock file for tests. If key doesn't exist nothing happens
194
65
 
195
- # The result from the example above:
196
66
  # client = ThirdParty::Client.new
197
67
  # client.foo_bar { a: 'b' }
198
68
  # => POST https://third_party.com/foo/buz DATA: { a: 'b' }
199
69
  ```
200
- #### Explanation of the parameters:
70
+ #### Parameters explanation:
201
71
 
202
- `body` — You can use the dry-scheme (from the set of DRY gems) to check the request parameters.
203
- If this key doesn't exist, the verification will be skipped.
204
- Example:
72
+ `body` — You can use dry-schema for validate request parameters.
73
+ If this key doesn't exist validation will be skipped.
74
+ For example:
205
75
 
206
76
  ```yaml
207
- body: DrySchema
77
+ body: CreateSchema
208
78
  ```
209
79
 
210
- `query_params` — If the request requires query parameters.
211
- Both arrays and ruby-hashes work.
212
- If this key doesn't exist, then there'll be no parameter substitution and validation.
213
- Example:
80
+ `query_params` — If request needs a query string.
81
+ Both arrays and hashes work.
82
+ If this key doesn't exist validation will be skipped.
83
+ For example:
214
84
 
215
85
  ```yaml
216
86
  query_params:
217
- dbAct: getCities => Example of using known and immutable parameters
218
- optional: => An example of using optional parameters. They'll be substituted when they are transmitted during the request
87
+ dbAct: getCities => For known and unchangeable parameters
88
+ optional: => For optional parameters
219
89
  - city
220
90
  - state
221
91
 
222
- # The result from the example above:
223
92
  # /api?dbAct=getCities&city=Tokio
224
93
  ```
225
94
  ```yaml
226
95
  query_params:
227
96
  - dbAct: getTarif
228
- - org => Example of using required parameters.
97
+ - org => For required parameters
229
98
  - dest
230
99
  - weight
231
-
232
- # The result from the example above:
100
+
233
101
  # /api?dbAct=getTarif&org=Tokio&dest=Beijing&weight=100
234
102
  ```
235
103
 
236
- `mock` — If you need real requests not to pass during testing,
237
- you can replace them with mocks.
238
- You can use both the yaml structure and the path to the yaml-file.
239
- Example:
104
+ `mock` — If you need real requests don't pass during the testing,
105
+ then you can replace them with mocks.
106
+ Both yaml structure or path to yaml file can be used.
107
+ For example:
240
108
 
241
109
  ```yaml
242
110
  mock: spec/mocks/http_clients/public/cities.yml
243
111
  ```
244
112
 
245
- #### Explanation of the generated files
113
+ #### Generated files explanation
246
114
 
247
- `client.rb` — An inherited file from the main dispatcher, and you can add some configuration methods, custom headers, request parameters, query-parameters.
115
+ `client.rb` — Nested from main dispatcher and you can add some configuration methods, custom headers, requests options, query parameters.
248
116
 
249
- `configuration.rb` — Add the path to the third-party API, the configuration URL and the logger.
117
+ `configuration.rb` — Add path to third party, config url and logger
250
118
 
251
- `responder.rb` — By default, a standard response handler is used, parsed in json format. But you can write your own.
119
+ `responder.rb` — By default uses standard responders parsed response in json. But you can write your own.
252
120
 
253
121
  ## Contributing
254
122
 
@@ -14,9 +14,11 @@ Gem::Specification.new do |gem|
14
14
 
15
15
  gem.license = 'MIT'
16
16
 
17
- raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless gem.respond_to?(:metadata)
18
-
19
- gem.metadata['allowed_push_host'] = 'https://rubygems.org'
17
+ if gem.respond_to?(:metadata)
18
+ gem.metadata['allowed_push_host'] = 'https://rubygems.org'
19
+ else
20
+ fail 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
21
+ end
20
22
 
21
23
  gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(/^(test|spec|features)/) }
22
24
  gem.bindir = 'exe'
@@ -25,16 +27,16 @@ Gem::Specification.new do |gem|
25
27
 
26
28
  gem.required_ruby_version = '>= 2.4.2'
27
29
 
28
- gem.add_dependency 'dry-schema', '~> 1.6.0'
30
+ gem.add_dependency 'dry-schema', '~> 1.13'
29
31
  gem.add_dependency 'faraday', '~> 2.10'
30
32
  gem.add_dependency 'faraday-cookie_jar', '~> 0.0.7'
31
- gem.add_dependency 'faraday-follow_redirects', '~> 0.3.0'
32
- gem.add_dependency 'faraday-typhoeus', '~> 1.1.0'
33
+ gem.add_dependency 'faraday_middleware', '~> 1.2'
34
+ gem.add_dependency 'typhoeus', '~> 1.4.0'
33
35
 
34
36
  gem.add_development_dependency 'bundler', '~> 2.0', '>= 2.0.2'
35
37
  gem.add_development_dependency 'rake', '~> 13.0'
36
38
  gem.add_development_dependency 'redcarpet', '~> 1.17', '>= 1.17.0'
37
- gem.add_development_dependency 'rubocop', '~> 1.6'
39
+ gem.add_development_dependency 'rubocop', '~> 1.21'
38
40
  gem.add_development_dependency 'yard', '~> 0.7', '>= 0.7.5'
39
41
  gem.metadata['rubygems_mfa_required'] = 'true'
40
42
  end
@@ -37,7 +37,7 @@ end
37
37
  def generate_routes(json_scheme)
38
38
  json_scheme.dup.each_with_object({}) do |(key, value), scheme|
39
39
  scheme[key] = value.delete(:scheme) if (value.is_a?(Hash) && value.key?(:scheme)) || value.is_a?(String)
40
- next if value.nil? || value.empty?
40
+ next if value.nil? || value.length.zero?
41
41
 
42
42
  generate_routes(value).map { |deep_key, deep_value| mapping(deep_key, deep_value, key, scheme) }
43
43
  end
@@ -1,12 +1,12 @@
1
- require 'faraday/follow_redirects'
2
- require_relative 'requests_extension'
1
+ require 'faraday_middleware'
2
+ require_relative './requests_extension'
3
3
 
4
4
  class Kapellmeister::Dispatcher
5
5
  def self.new(**args)
6
- main_klass = module_parent.name&.delete('::')
6
+ main_klass = self.module_parent.name.delete('::')
7
7
 
8
- module_parent.requests.each do |request|
9
- include Kapellmeister::RequestsExtension.request_processing(main_klass, request)
8
+ self.module_parent.requests.each do |request|
9
+ self.include Kapellmeister::RequestsExtension.request_processing(main_klass, request)
10
10
  end
11
11
  super(**args)
12
12
  end
@@ -60,7 +60,7 @@ class Kapellmeister::Dispatcher
60
60
  faraday.request :multipart
61
61
  faraday.response :logger, logger
62
62
  faraday.response :json, content_type: 'application/json; charset=utf-8'
63
- faraday.response :follow_redirects
63
+ faraday.use FaradayMiddleware::FollowRedirects, limit: 5
64
64
  faraday.adapter :typhoeus do |http|
65
65
  http.timeout = 20
66
66
  end
@@ -3,7 +3,7 @@ module Kapellmeister::RequestsExtension
3
3
  mod = if Object.const_defined?("#{self}::#{klass}InstanceMethods")
4
4
  const_get("#{self}::#{klass}InstanceMethods")
5
5
  else
6
- const_set(:"#{klass}InstanceMethods", Module.new)
6
+ const_set("#{klass}InstanceMethods", Module.new)
7
7
  end
8
8
 
9
9
  mod.module_eval do
@@ -37,7 +37,7 @@ def parsed_query(params, data)
37
37
 
38
38
  hash_data, filtered_query = *split_hashes(params)
39
39
  required_empty_query, default_data = *hash_data.partition { |elem| elem.values.compact_blank.blank? }
40
- data = filtered_query.zip([]).to_h.compact_blank.merge(data) if data.is_a?(Hash)
40
+ data = Hash[filtered_query.zip].compact_blank.merge(data) if data.is_a?(Hash)
41
41
  _optional_data, default_data = *split_optional(default_data)
42
42
  data = data.merge(default_data) if !data.blank? || !default_data.blank?
43
43
 
@@ -79,7 +79,7 @@ def generate_path(original_path, data)
79
79
  end
80
80
 
81
81
  def valid_body?(data, body)
82
- return true if body.blank? || body.is_a?(Hash)
82
+ return if body.blank? || body.is_a?(Hash)
83
83
 
84
84
  schema = Object.const_get(body).schema
85
85
  result = schema.call(data)
@@ -89,7 +89,7 @@ def valid_body?(data, body)
89
89
  end
90
90
 
91
91
  def valid_query?(data, query)
92
- return true if query.blank?
92
+ return if query.blank?
93
93
 
94
94
  required_keys = query.map(&:to_sym)
95
95
 
@@ -99,7 +99,7 @@ def valid_query?(data, query)
99
99
  data[:query_params] = data[:query_params].to_h.merge!(from_data)
100
100
 
101
101
  different_keys = data[:query_params].transform_keys(&:to_sym)
102
- return true if required_keys.all? { |key| different_keys.key? key.to_sym }
102
+ return if required_keys.all? { |key| different_keys.key? key.to_sym }
103
103
 
104
104
  raise ArgumentError, "Query params needs keys #{required_keys}"
105
105
  end
@@ -1,3 +1,3 @@
1
1
  module Kapellmeister
2
- VERSION = '0.9.8.rc1'.freeze
2
+ VERSION = '0.9.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kapellmeister
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8.rc1
4
+ version: 0.9.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarkWater
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: '1.13'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: '1.13'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +53,33 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.0.7
55
55
  - !ruby/object:Gem::Dependency
56
- name: faraday-follow_redirects
56
+ name: faraday_middleware
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.0
61
+ version: '1.2'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.3.0
68
+ version: '1.2'
69
69
  - !ruby/object:Gem::Dependency
70
- name: faraday-typhoeus
70
+ name: typhoeus
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.1.0
75
+ version: 1.4.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.1.0
82
+ version: 1.4.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -140,14 +140,14 @@ dependencies:
140
140
  requirements:
141
141
  - - "~>"
142
142
  - !ruby/object:Gem::Version
143
- version: '1.6'
143
+ version: '1.21'
144
144
  type: :development
145
145
  prerelease: false
146
146
  version_requirements: !ruby/object:Gem::Requirement
147
147
  requirements:
148
148
  - - "~>"
149
149
  - !ruby/object:Gem::Version
150
- version: '1.6'
150
+ version: '1.21'
151
151
  - !ruby/object:Gem::Dependency
152
152
  name: yard
153
153
  requirement: !ruby/object:Gem::Requirement
@@ -217,9 +217,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
217
  version: 2.4.2
218
218
  required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  requirements:
220
- - - ">"
220
+ - - ">="
221
221
  - !ruby/object:Gem::Version
222
- version: 1.3.1
222
+ version: '0'
223
223
  requirements: []
224
224
  rubygems_version: 3.3.7
225
225
  signing_key: