reynard 0.3.0 → 0.5.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.
- checksums.yaml +4 -4
- data/README.md +17 -1
- data/lib/reynard/context.rb +4 -0
- data/lib/reynard/external.rb +34 -0
- data/lib/reynard/http/request.rb +10 -37
- data/lib/reynard/object_builder.rb +1 -1
- data/lib/reynard/request_context.rb +1 -0
- data/lib/reynard/specification.rb +22 -5
- data/lib/reynard/version.rb +1 -1
- data/lib/reynard.rb +5 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d85681365ddb46b06c062b39bdea10bf46810d80d813c9737df0ee3aeb38e843
|
4
|
+
data.tar.gz: '007908692ed0a3c437befba30a29d0f694429033097b7ae47ca2aaf7050c05ea'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e23bf2702660623a61039bb8444ea3e0f4bdd7eaceab42d22dbca2ea157e705a54af69558ce84812d4ef2f13c1330071781e8da61d3ed44c8b0d2a944816752
|
7
|
+
data.tar.gz: 9e973c551d30a6b7e6ab8ef494d270b5dac05dfd96de86c49448c5889b070a07ee8d8aa486de1f80c3d372c73ed7b11e37da49625fdeb64d21e84352130e55f3
|
data/README.md
CHANGED
@@ -81,6 +81,22 @@ response['Content-Type'] #=> 'application/json'
|
|
81
81
|
response.body #=> '{"name":"Sam Seven"}'
|
82
82
|
```
|
83
83
|
|
84
|
+
## Logging
|
85
|
+
|
86
|
+
When you want to know what the Reynard client is doing you can enable logging.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
logger = Logger.new($stdout)
|
90
|
+
logger.level = Logger::INFO
|
91
|
+
reynard.logger(logger).execute
|
92
|
+
```
|
93
|
+
|
94
|
+
The logging should be compatible with the Ruby on Rails logger.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
reynard.logger(Rails.logger).execute
|
98
|
+
```
|
99
|
+
|
84
100
|
## Mocking
|
85
101
|
|
86
102
|
You can mock Reynard requests by changing the HTTP implementation. The class **must** implement a single `request` method that accepts an URI and net/http request object. It **must** return a net/http response object or an object with the exact same interface.
|
@@ -97,4 +113,4 @@ end
|
|
97
113
|
|
98
114
|
## Copyright and other legal
|
99
115
|
|
100
|
-
See LICENCE.
|
116
|
+
See LICENCE.
|
data/lib/reynard/context.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
class Reynard
|
6
|
+
# Loads external references.
|
7
|
+
class External
|
8
|
+
def initialize(path:, ref:)
|
9
|
+
@path = path
|
10
|
+
@relative_path, @anchor = ref.split('#', 2)
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
return [] unless @anchor
|
15
|
+
|
16
|
+
@anchor.split('/')[1..]
|
17
|
+
end
|
18
|
+
|
19
|
+
def data
|
20
|
+
File.open(filename, encoding: 'UTF-8') do |file|
|
21
|
+
YAML.safe_load(file, aliases: true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def filename
|
28
|
+
filename = File.expand_path(@relative_path, @path)
|
29
|
+
return filename if filename.start_with?(@path)
|
30
|
+
|
31
|
+
raise 'You are only allowed to reference files relative to the specification file.'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/reynard/http/request.rb
CHANGED
@@ -15,50 +15,23 @@ class Reynard
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def perform
|
18
|
+
@request_context.logger&.info { "#{@request_context.verb.upcase} #{uri}" }
|
18
19
|
Reynard.http.request(uri, build_request)
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
23
|
-
def
|
24
|
-
|
25
|
-
when 'get'
|
26
|
-
build_http_get
|
27
|
-
when 'post'
|
28
|
-
build_http_post
|
29
|
-
when 'put'
|
30
|
-
build_http_put
|
31
|
-
when 'patch'
|
32
|
-
build_http_patch
|
33
|
-
when 'delete'
|
34
|
-
build_http_delete
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def build_http_get
|
39
|
-
Net::HTTP::Get.new(uri, @request_context.headers)
|
40
|
-
end
|
41
|
-
|
42
|
-
def build_http_post
|
43
|
-
post = Net::HTTP::Post.new(uri, @request_context.headers)
|
44
|
-
post.body = @request_context.body
|
45
|
-
post
|
24
|
+
def request_class
|
25
|
+
Net::HTTP.const_get(@request_context.verb.capitalize)
|
46
26
|
end
|
47
27
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
patch = Net::HTTP::Patch.new(uri, @request_context.headers)
|
56
|
-
patch.body = @request_context.body
|
57
|
-
patch
|
58
|
-
end
|
59
|
-
|
60
|
-
def build_http_delete
|
61
|
-
Net::HTTP::Delete.new(uri, @request_context.headers)
|
28
|
+
def build_request
|
29
|
+
request = request_class.new(uri, @request_context.headers)
|
30
|
+
if @request_context.body
|
31
|
+
@request_context.logger&.debug { @request_context.body }
|
32
|
+
request.body = @request_context.body
|
33
|
+
end
|
34
|
+
request
|
62
35
|
end
|
63
36
|
end
|
64
37
|
end
|
@@ -102,11 +102,14 @@ class Reynard
|
|
102
102
|
|
103
103
|
def self.normalize_model_name(name)
|
104
104
|
# 1. Unescape encoded characters to create an UTF-8 string
|
105
|
-
# 2.
|
106
|
-
# 3.
|
105
|
+
# 2. Remove extensions for regularly used external schema files
|
106
|
+
# 3. Replace all non-alphabetic characters with a space (not allowed in Ruby constant)
|
107
|
+
# 4. Camelcase
|
107
108
|
Rack::Utils.unescape_path(name)
|
109
|
+
.gsub(/(.yml|.yaml|.json)\Z/, '')
|
108
110
|
.gsub(/[^[:alpha:]]/, ' ')
|
109
111
|
.gsub(/(\s+)([[:alpha:]])/) { Regexp.last_match(2).upcase }
|
112
|
+
.gsub(/\A(.)/) { Regexp.last_match(1).upcase }
|
110
113
|
end
|
111
114
|
|
112
115
|
private
|
@@ -117,6 +120,9 @@ class Reynard
|
|
117
120
|
end
|
118
121
|
end
|
119
122
|
|
123
|
+
# rubocop:disable Metrics/AbcSize
|
124
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
125
|
+
# rubocop:disable Metrics/MethodLength
|
120
126
|
def dig_into(data, cursor, path)
|
121
127
|
while path.length.positive?
|
122
128
|
cursor = cursor[path.first]
|
@@ -125,12 +131,23 @@ class Reynard
|
|
125
131
|
path.shift
|
126
132
|
next unless cursor.respond_to?(:key?) && cursor&.key?('$ref')
|
127
133
|
|
128
|
-
|
129
|
-
|
130
|
-
|
134
|
+
case cursor['$ref']
|
135
|
+
# References another element in the current specification.
|
136
|
+
when %r{\A#/}
|
137
|
+
path = Rack::Utils.unescape_path(cursor['$ref'][2..]).split('/') + path
|
138
|
+
cursor = data
|
139
|
+
# References another file, with an optional anchor to an element in the data.
|
140
|
+
when %r{\A\./}
|
141
|
+
external = External.new(path: File.dirname(@filename), ref: cursor['$ref'])
|
142
|
+
path = external.path + path
|
143
|
+
cursor = external.data
|
144
|
+
end
|
131
145
|
end
|
132
146
|
cursor
|
133
147
|
end
|
148
|
+
# rubocop:enable Metrics/AbcSize
|
149
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
150
|
+
# rubocop:enable Metrics/MethodLength
|
134
151
|
|
135
152
|
def schema_name(response)
|
136
153
|
ref = response.dig('schema', '$ref')
|
data/lib/reynard/version.rb
CHANGED
data/lib/reynard.rb
CHANGED
@@ -11,12 +11,14 @@ require 'uri'
|
|
11
11
|
# OpenAPI specification.
|
12
12
|
class Reynard
|
13
13
|
extend Forwardable
|
14
|
-
def_delegators :build_context, :base_url, :operation, :headers, :params
|
14
|
+
def_delegators :build_context, :logger, :base_url, :operation, :headers, :params
|
15
15
|
def_delegators :@specification, :servers
|
16
16
|
|
17
17
|
autoload :Context, 'reynard/context'
|
18
|
+
autoload :External, 'reynard/external'
|
18
19
|
autoload :GroupedParameters, 'reynard/grouped_parameters'
|
19
20
|
autoload :Http, 'reynard/http'
|
21
|
+
autoload :Logger, 'reynard/logger'
|
20
22
|
autoload :MediaType, 'reynard/media_type'
|
21
23
|
autoload :Model, 'reynard/model'
|
22
24
|
autoload :Models, 'reynard/models'
|
@@ -34,9 +36,9 @@ class Reynard
|
|
34
36
|
@specification = Specification.new(filename: filename)
|
35
37
|
end
|
36
38
|
|
37
|
-
# Assign an object that follows Reynard's internal request interface to mock requests or use a
|
38
|
-
# different HTTP client.
|
39
39
|
class << self
|
40
|
+
# Assign an object that follows Reynard's internal request interface to mock requests or use a
|
41
|
+
# different HTTP client.
|
40
42
|
attr_writer :http
|
41
43
|
end
|
42
44
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reynard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manfred Stienstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- README.md
|
122
122
|
- lib/reynard.rb
|
123
123
|
- lib/reynard/context.rb
|
124
|
+
- lib/reynard/external.rb
|
124
125
|
- lib/reynard/grouped_parameters.rb
|
125
126
|
- lib/reynard/http.rb
|
126
127
|
- lib/reynard/http/request.rb
|