simple_endpoint 0.1.2 → 1.0.1
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 +4 -4
- data/.circleci/config.yml +45 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +19 -6
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGES.md +11 -0
- data/README.md +35 -10
- data/lib/simple_endpoint/version.rb +1 -1
- data/lib/simple_endpoint.rb +19 -16
- data/simple_endpoint.gemspec +6 -5
- metadata +30 -14
- data/.travis.yml +0 -5
- data/Gemfile.lock +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cafc4ae0561d731416cdf3b2118ffbf06bc8a871b749965c4c08456f8eaa2aed
|
4
|
+
data.tar.gz: cf96b321cfb718850a9556b5abe05d0130462efa2a5d44ec10597b8c01796f18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4594e5c903c2cf287ec2183586fe521f00cee1ba898ee1e5da871efaf7eab0a10ec1808ab297073e28a6df4e16499831c833c7a551fc3c56b95c5e5c087e584
|
7
|
+
data.tar.gz: 46839e10421d39641931055e06bbce36154b62dd2e763910d7661130c55156bfbf6352b50bf6b7fe8cfdf13e39c5b846980972f288e646ccd6aeac8d62e98903
|
@@ -0,0 +1,45 @@
|
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
executors:
|
4
|
+
test_executor:
|
5
|
+
docker:
|
6
|
+
- image: circleci/ruby:${RUBY_VERSION}
|
7
|
+
working_directory: ~/simple_endpoint
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
environment:
|
12
|
+
RUBY_VERSION: << parameters.ruby_version >>
|
13
|
+
BUNDLER_VERSION: 2.1.4
|
14
|
+
executor: test_executor
|
15
|
+
parameters:
|
16
|
+
ruby_version:
|
17
|
+
type: string
|
18
|
+
steps:
|
19
|
+
- checkout
|
20
|
+
|
21
|
+
- run:
|
22
|
+
name: 'Install bundler'
|
23
|
+
command: 'gem install bundler'
|
24
|
+
|
25
|
+
- run:
|
26
|
+
name: Install dependencies
|
27
|
+
command: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs 4 --retry 3
|
28
|
+
|
29
|
+
# - run:
|
30
|
+
# name: Run Rubocop
|
31
|
+
# command: bundle exec rubocop
|
32
|
+
|
33
|
+
- run:
|
34
|
+
name: Run Tests
|
35
|
+
command: bundle exec rspec
|
36
|
+
|
37
|
+
workflows:
|
38
|
+
build_and_test:
|
39
|
+
jobs:
|
40
|
+
- build:
|
41
|
+
name: 'ruby 2.6.8'
|
42
|
+
ruby_version: 2.6.8
|
43
|
+
- build:
|
44
|
+
name: 'ruby 2.7.0'
|
45
|
+
ruby_version: 2.7.0
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,13 +1,26 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
1
3
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.
|
4
|
+
TargetRubyVersion: 2.7
|
5
|
+
NewCops: enable
|
6
|
+
SuggestExtensions: false
|
7
|
+
Exclude:
|
8
|
+
- 'simple_endpoint.gemspec'
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Enabled: false
|
3
12
|
|
4
|
-
|
13
|
+
Layout/LineLength:
|
14
|
+
Max: 120
|
15
|
+
|
16
|
+
Style/FrozenStringLiteralComment:
|
5
17
|
Enabled: true
|
6
|
-
Max: 120
|
7
18
|
|
8
19
|
Metrics/BlockLength:
|
9
|
-
|
10
|
-
- 'spec/**'
|
20
|
+
IgnoredMethods: ['describe','context']
|
11
21
|
|
12
|
-
|
22
|
+
RSpec/DescribeClass:
|
13
23
|
Enabled: false
|
24
|
+
|
25
|
+
RSpec/NestedGroups:
|
26
|
+
Max: 4
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
simple_endpoint
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.0
|
data/CHANGES.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
simple_endpoint changelog
|
2
|
+
=====================
|
3
|
+
|
4
|
+
[2022-02-09] Version 1.0.1
|
5
|
+
---------------------------
|
6
|
+
- Add Ruby 2.7+ support
|
7
|
+
|
8
|
+
[2020-01-25] Version 1.0.0
|
9
|
+
---------------------------
|
10
|
+
**Breaking changes**
|
11
|
+
- [PR #6](https://github.com/differencialx/simple_endpoint/pull/6): Added ability to pass additional options from controller tot handlers, such as options for serialization, to avoid setting them inside trailblazer operation.
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# SimpleEndpoint
|
2
|
+
[](https://circleci.com/gh/differencialx/simple_endpoint)
|
3
|
+
[](https://rubygems.org/gems/simple_endpoint)
|
2
4
|
|
3
5
|
Dry-matcher free implementation of trailblazer endpoint.
|
4
6
|
|
@@ -6,8 +8,7 @@ Dry-matcher free implementation of trailblazer endpoint.
|
|
6
8
|
Add this to your Gemfile:
|
7
9
|
|
8
10
|
```ruby
|
9
|
-
gem 'simple_endpoint'
|
10
|
-
gem 'simple_endpoint', github: 'differencialx/simple_endpoint', :branch => 'master'
|
11
|
+
gem 'simple_endpoint', '~> 1.0.0'
|
11
12
|
```
|
12
13
|
|
13
14
|
## Getting Started
|
@@ -47,8 +48,8 @@ class ApplicationController < ActionController::Base
|
|
47
48
|
|
48
49
|
def default_handler
|
49
50
|
{
|
50
|
-
success: -> (result) { render json: result['model'], **
|
51
|
-
invalid: -> (result) { render json: result['contract.default'].errors, serializer: ErrorSerializer, status: :unprocessable_entity }
|
51
|
+
success: -> (result, **opts) { render json: result['model'], **opts, status: 200 },
|
52
|
+
invalid: -> (result, **) { render json: result['contract.default'].errors, serializer: ErrorSerializer, status: :unprocessable_entity }
|
52
53
|
}
|
53
54
|
end
|
54
55
|
end
|
@@ -73,7 +74,8 @@ Now you are able to use `endpoint` method at other controllers
|
|
73
74
|
| `:different_cases`| no | {} | Cases that should be redefined for exact `#endpoint` call |
|
74
75
|
| `:different_handler` | no | {} | Case of handler that should be handled in different way |
|
75
76
|
| `:options` | no | {} | Additional hash which will be merged to `#ednpoint_options` method result before operation execution |
|
76
|
-
| `:
|
77
|
+
| `:before_response` | no | {} | Allow to process code before specific case handler |
|
78
|
+
| `:renderer_options` | no | {} | Allow to pass serializer options from controller and Will available inside handler as second parameter.
|
77
79
|
|
78
80
|
|
79
81
|
#### Simple endpoint call
|
@@ -101,7 +103,7 @@ class PostsController < ApplicationController
|
|
101
103
|
{
|
102
104
|
success: -> (result) { result.success? && is_it_raining? },
|
103
105
|
invalid: -> (result) { result.failure? && is_vasya_in_the_house? }
|
104
|
-
... # other cases
|
106
|
+
... # other cases
|
105
107
|
}
|
106
108
|
end
|
107
109
|
|
@@ -156,7 +158,7 @@ class PostsController < ApplicationController
|
|
156
158
|
|
157
159
|
def default_handler
|
158
160
|
{
|
159
|
-
success: -> (result) { head :ok }
|
161
|
+
success: -> (result, **) { head :ok }
|
160
162
|
}
|
161
163
|
end
|
162
164
|
end
|
@@ -175,7 +177,7 @@ class PostsController < ApplicationController
|
|
175
177
|
|
176
178
|
def different_handler
|
177
179
|
{
|
178
|
-
success: -> (result) { render json: { message: 'Nice!' }, status: :created }
|
180
|
+
success: -> (result, **) { render json: { message: 'Nice!' }, status: :created }
|
179
181
|
}
|
180
182
|
end
|
181
183
|
end
|
@@ -231,17 +233,40 @@ class PostsController < ApplicationController
|
|
231
233
|
def create
|
232
234
|
endpoint operation: Post::Create,
|
233
235
|
before_response: before_render_actions
|
234
|
-
end
|
236
|
+
end
|
235
237
|
end
|
236
238
|
|
237
239
|
private
|
238
240
|
|
239
241
|
def before_response_actions
|
240
242
|
{
|
241
|
-
success: -> (result) { response.headers['Some-header'] = result[:some_data] }
|
243
|
+
success: -> (result, **) { response.headers['Some-header'] = result[:some_data] }
|
242
244
|
}
|
243
245
|
end
|
244
246
|
end
|
245
247
|
```
|
246
248
|
|
247
249
|
Code above will put data from operation result into response haeders before render
|
250
|
+
|
251
|
+
|
252
|
+
#### Pass additional options from controller
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
class PostsController < ApplicationController
|
256
|
+
def create
|
257
|
+
endpoint operation: Post::Create,
|
258
|
+
renderer_options: { serializer: SerializerClass }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
private
|
263
|
+
|
264
|
+
def default_handler
|
265
|
+
{
|
266
|
+
# renderer_options will be available as **opts
|
267
|
+
success: -> (result, **opts) { render json: result['model'], **opts, status: 200 },
|
268
|
+
invalid: -> (result, **) { render json: result['contract.default'].errors, serializer: ErrorSerializer, status: :unprocessable_entity }
|
269
|
+
}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
```
|
data/lib/simple_endpoint.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# rubocop:disable Metrics/ParameterLists
|
5
4
|
module SimpleEndpoint
|
6
5
|
module Controller
|
7
|
-
def endpoint(operation:,
|
6
|
+
def endpoint(operation:,
|
7
|
+
different_cases: {},
|
8
|
+
different_handler: {},
|
9
|
+
options: {},
|
10
|
+
before_response: {},
|
11
|
+
renderer_options: {})
|
8
12
|
Endpoint.call(
|
9
13
|
operation,
|
10
|
-
default_handler.merge(
|
14
|
+
default_handler.merge(different_handler),
|
11
15
|
default_cases.merge(different_cases),
|
16
|
+
renderer_options,
|
12
17
|
before_response,
|
13
|
-
endpoint_options.merge(options)
|
18
|
+
**endpoint_options.merge(options)
|
14
19
|
)
|
15
20
|
end
|
16
21
|
|
@@ -30,15 +35,15 @@ module SimpleEndpoint
|
|
30
35
|
end
|
31
36
|
|
32
37
|
class Endpoint
|
33
|
-
def self.call(operation, handler, cases, before_response = {}, **args)
|
38
|
+
def self.call(operation, handler, cases, renderer_options = {}, before_response = {}, **args)
|
34
39
|
result = operation.call(**args)
|
35
|
-
new.call(result, cases, handler, before_response)
|
40
|
+
new.call(result, cases, renderer_options, handler, before_response)
|
36
41
|
end
|
37
42
|
|
38
|
-
def call(result, cases, handler = {}, before_response = {})
|
43
|
+
def call(result, cases, renderer_options = {}, handler = {}, before_response = {})
|
39
44
|
matched_case = matched_case(cases, result)
|
40
|
-
procees_handler(matched_case, before_response, result) unless before_response.empty?
|
41
|
-
procees_handler(matched_case, handler, result, UnhadledResultError)
|
45
|
+
procees_handler(matched_case, before_response, result, renderer_options) unless before_response.empty?
|
46
|
+
procees_handler(matched_case, handler, result, renderer_options, UnhadledResultError)
|
42
47
|
end
|
43
48
|
|
44
49
|
def matched_case(cases, result)
|
@@ -48,19 +53,16 @@ module SimpleEndpoint
|
|
48
53
|
matched_case
|
49
54
|
end
|
50
55
|
|
51
|
-
def procees_handler(matched_case, handler, result, exception_class = nil)
|
56
|
+
def procees_handler(matched_case, handler, result, renderer_options, exception_class = nil)
|
52
57
|
if handler.key?(matched_case)
|
53
|
-
handler
|
58
|
+
handler[matched_case]&.(result, **renderer_options)
|
54
59
|
elsif exception_class
|
55
60
|
raise exception_class, "Key: #{matched_case} is not present at #{handler}"
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
59
64
|
def obtain_matched_case(cases, result)
|
60
|
-
|
61
|
-
return if matched_case.is_a?(Hash)
|
62
|
-
|
63
|
-
matched_case
|
65
|
+
cases.detect { |_kase, condition| condition.call(result) }&.first
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
@@ -124,3 +126,4 @@ module SimpleEndpoint
|
|
124
126
|
You can move this to separate singleton class
|
125
127
|
LARGE_ERROR
|
126
128
|
end
|
129
|
+
# rubocop:enable Metrics/ParameterLists
|
data/simple_endpoint.gemspec
CHANGED
@@ -11,8 +11,8 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['differencialx@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'Simple implementation of Trailblazer endpoint'
|
14
|
-
spec.description = '
|
15
|
-
spec.homepage = ''
|
14
|
+
spec.description = 'Dry-matcher free implementation of trailblazer endpoint, with ability to redefine matchers and handlers behavior for separate controllers or actions.'
|
15
|
+
spec.homepage = 'https://github.com/differencialx/simple_endpoint'
|
16
16
|
|
17
17
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
18
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
@@ -32,9 +32,10 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
33
|
spec.require_paths = ['lib']
|
34
34
|
|
35
|
-
spec.add_development_dependency 'bundler', '
|
35
|
+
spec.add_development_dependency 'bundler', '>= 2.1.0'
|
36
36
|
spec.add_development_dependency 'pry-byebug'
|
37
|
-
spec.add_development_dependency 'rake', '~>
|
37
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
38
38
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
39
|
-
spec.add_development_dependency 'rubocop'
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 1.25.1'
|
40
|
+
spec.add_development_dependency 'rubocop-rspec'
|
40
41
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_endpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Bal
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.1.0
|
20
20
|
type: :development
|
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:
|
26
|
+
version: 2.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pry-byebug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,6 +68,20 @@ dependencies:
|
|
68
68
|
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.25.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.25.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -80,19 +94,22 @@ dependencies:
|
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
|
-
description:
|
97
|
+
description: Dry-matcher free implementation of trailblazer endpoint, with ability
|
98
|
+
to redefine matchers and handlers behavior for separate controllers or actions.
|
84
99
|
email:
|
85
100
|
- differencialx@gmail.com
|
86
101
|
executables: []
|
87
102
|
extensions: []
|
88
103
|
extra_rdoc_files: []
|
89
104
|
files:
|
105
|
+
- ".circleci/config.yml"
|
90
106
|
- ".gitignore"
|
91
107
|
- ".rspec"
|
92
108
|
- ".rubocop.yml"
|
93
|
-
- ".
|
109
|
+
- ".ruby-gemset"
|
110
|
+
- ".ruby-version"
|
111
|
+
- CHANGES.md
|
94
112
|
- Gemfile
|
95
|
-
- Gemfile.lock
|
96
113
|
- LICENSE
|
97
114
|
- README.md
|
98
115
|
- Rakefile
|
@@ -101,7 +118,7 @@ files:
|
|
101
118
|
- lib/simple_endpoint.rb
|
102
119
|
- lib/simple_endpoint/version.rb
|
103
120
|
- simple_endpoint.gemspec
|
104
|
-
homepage:
|
121
|
+
homepage: https://github.com/differencialx/simple_endpoint
|
105
122
|
licenses: []
|
106
123
|
metadata:
|
107
124
|
allowed_push_host: https://rubygems.org
|
@@ -120,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
137
|
- !ruby/object:Gem::Version
|
121
138
|
version: '0'
|
122
139
|
requirements: []
|
123
|
-
|
124
|
-
rubygems_version: 2.7.7
|
140
|
+
rubygems_version: 3.1.2
|
125
141
|
signing_key:
|
126
142
|
specification_version: 4
|
127
143
|
summary: Simple implementation of Trailblazer endpoint
|
data/.travis.yml
DELETED
data/Gemfile.lock
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
simple_endpoint (0.1.2)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
ast (2.4.0)
|
10
|
-
byebug (10.0.2)
|
11
|
-
coderay (1.1.2)
|
12
|
-
diff-lcs (1.3)
|
13
|
-
jaro_winkler (1.5.1)
|
14
|
-
method_source (0.9.2)
|
15
|
-
parallel (1.12.1)
|
16
|
-
parser (2.5.3.0)
|
17
|
-
ast (~> 2.4.0)
|
18
|
-
powerpack (0.1.2)
|
19
|
-
pry (0.12.2)
|
20
|
-
coderay (~> 1.1.0)
|
21
|
-
method_source (~> 0.9.0)
|
22
|
-
pry-byebug (3.6.0)
|
23
|
-
byebug (~> 10.0)
|
24
|
-
pry (~> 0.10)
|
25
|
-
rainbow (3.0.0)
|
26
|
-
rake (10.5.0)
|
27
|
-
rspec (3.8.0)
|
28
|
-
rspec-core (~> 3.8.0)
|
29
|
-
rspec-expectations (~> 3.8.0)
|
30
|
-
rspec-mocks (~> 3.8.0)
|
31
|
-
rspec-core (3.8.0)
|
32
|
-
rspec-support (~> 3.8.0)
|
33
|
-
rspec-expectations (3.8.2)
|
34
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
-
rspec-support (~> 3.8.0)
|
36
|
-
rspec-mocks (3.8.0)
|
37
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
-
rspec-support (~> 3.8.0)
|
39
|
-
rspec-support (3.8.0)
|
40
|
-
rubocop (0.60.0)
|
41
|
-
jaro_winkler (~> 1.5.1)
|
42
|
-
parallel (~> 1.10)
|
43
|
-
parser (>= 2.5, != 2.5.1.1)
|
44
|
-
powerpack (~> 0.1)
|
45
|
-
rainbow (>= 2.2.2, < 4.0)
|
46
|
-
ruby-progressbar (~> 1.7)
|
47
|
-
unicode-display_width (~> 1.4.0)
|
48
|
-
ruby-progressbar (1.10.0)
|
49
|
-
unicode-display_width (1.4.0)
|
50
|
-
|
51
|
-
PLATFORMS
|
52
|
-
ruby
|
53
|
-
|
54
|
-
DEPENDENCIES
|
55
|
-
bundler (~> 1.16)
|
56
|
-
pry-byebug
|
57
|
-
rake (~> 10.0)
|
58
|
-
rspec (~> 3.0)
|
59
|
-
rubocop
|
60
|
-
simple_endpoint!
|
61
|
-
|
62
|
-
BUNDLED WITH
|
63
|
-
1.16.2
|