kapellmeister 0.9.8.rc1 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
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: