reynard 0.10.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d2a2059bfff7777ad1d0b122d83afff99bc6af883a35f8970091fa3197fd541
4
- data.tar.gz: 05d9297e7d4d86e43f733f5c385ac2ea93a16b681d4f51e09bea9e20e97a00bc
3
+ metadata.gz: c3c34bb5538fc723eb3089aed2fcc9297caecd7c12802081fb1c0ffd5b930885
4
+ data.tar.gz: fd266bc7821ef67989261e66923605b3ea0b249f19c028ada40815928c070b7b
5
5
  SHA512:
6
- metadata.gz: 8b0ccb3d8e187780cdca33e65588b4da8d835910f247f618e5b67114e58cda744745826ff9e8c223742be55c003ea6df904b18a6fee9bc7e2b7b466c9739f751
7
- data.tar.gz: dd5bf8691ae5c72ea7462e313992671ad82125fb0de3228d09d6a26fa367734cd14498de7bc02dda73684b255774b40e5991464c606609bc16517528f75b4219
6
+ metadata.gz: edd450cc95fc83f6f16c8e8a77d7600f98d8524fe75a1abc78b383cd6442458acf3351e7ea0513cb539a00870bea79729a57120a4c0b556e54c937dcc0275e63
7
+ data.tar.gz: b00d56c46b6c29f5ccf01a83a6fc8f62e53a44953787441bb13af36a7025a0712f75ad537507f917644acff2f134edf71502461cb930e0bbe1c5a4a1b0ff9f6f
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
-
5
3
  class Reynard
6
4
  # Exposes a public interface to build a request context.
7
5
  class Context
@@ -3,9 +3,16 @@
3
3
  require 'rack'
4
4
 
5
5
  class Reynard
6
- # Loads external references.
6
+ # Loads data for external references from disk.
7
7
  class External
8
- def initialize(path:, ref:)
8
+ # Build a new external reference loader.
9
+ #
10
+ # @param basepath [String] base path of the OpenAPI specification, we never load any files
11
+ # higher in the directory tree
12
+ # @param path [String] base path of the current file, used to resolve relative paths
13
+ # @param ref [String] the $ref value we actually resolve
14
+ def initialize(basepath:, path:, ref:)
15
+ @basepath = basepath
9
16
  @path = path
10
17
  @relative_path, @anchor = ref.split('#', 2)
11
18
  @filename = File.expand_path(@relative_path, @path)
@@ -14,7 +21,10 @@ class Reynard
14
21
  def path
15
22
  return [] unless @anchor
16
23
 
17
- @anchor.split('/')[1..]
24
+ # Remove explicit absolute (ie. /) and explicitly relative (ie. ./) instructions from the
25
+ # path expression because we're starting at the root of an external file. We currently don't
26
+ # support the // syntax.
27
+ @anchor.to_s.gsub(%r{\A\.?/}, '').split('/')
18
28
  end
19
29
 
20
30
  def data
@@ -30,7 +40,7 @@ class Reynard
30
40
  private
31
41
 
32
42
  def filename
33
- return @filename if @filename.start_with?(@path)
43
+ return @filename if @filename.start_with?(@basepath)
34
44
 
35
45
  raise 'You are only allowed to reference files relative to the specification file.'
36
46
  end
@@ -3,14 +3,21 @@
3
3
  class Reynard
4
4
  # Groups parameters based on the parameters specification.
5
5
  class GroupedParameters
6
- def initialize(specification, params)
7
- @specification = pivot(specification)
6
+ def initialize(specification:, node:, params:)
7
+ @specification = specification
8
+ @node = node
8
9
  @params = params
9
10
  end
10
11
 
12
+ def constraints
13
+ return @constraints if defined?(@constraints)
14
+
15
+ @constraints = actualize(*@node, 'parameters') || actualize(*@node[..-2], 'parameters') || {}
16
+ end
17
+
11
18
  def to_h
12
19
  @params.each_with_object({}) do |(name, value), grouped|
13
- group_name = @specification.dig(name, 'in') || 'query'
20
+ group_name = constraints.dig(name, 'in') || 'query'
14
21
  grouped[group_name] ||= {}
15
22
  grouped[group_name].merge!({ name => value })
16
23
  end
@@ -18,12 +25,16 @@ class Reynard
18
25
 
19
26
  private
20
27
 
21
- def pivot(specification)
22
- return {} unless specification
28
+ def actualize(*node)
29
+ parameters = @specification.dig(*node)
30
+ return unless parameters
23
31
 
24
- specification.each_with_object({}) do |attribute, pivot|
25
- pivot[attribute['name']] = attribute
32
+ pivot = {}
33
+ parameters.each.with_index do |attributes, index|
34
+ attributes = @specification.dig(*node, index) if attributes.key?('$ref')
35
+ pivot[attributes['name']] = attributes
26
36
  end
37
+ pivot
27
38
  end
28
39
  end
29
40
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
-
5
3
  class Reynard
6
4
  # Defines dynamic classes based on schema and instantiates them for a response.
7
5
  class ObjectBuilder
@@ -18,7 +18,7 @@ class Reynard
18
18
  def find_into(path, &block)
19
19
  data = @specification.dig(*path)
20
20
 
21
- yield path if data.respond_to?(:key?) && (data.key?('type') && (@query.type == data['type']))
21
+ yield path if data.respond_to?(:key?) && data.key?('type') && (@query.type == data['type'])
22
22
 
23
23
  return unless data.respond_to?(:each_key)
24
24
 
@@ -47,13 +47,9 @@ class Reynard
47
47
  return {} unless params
48
48
 
49
49
  GroupedParameters.new(
50
- [
51
- # Parameters can be shared between methods on a path or be specific to an operation. The
52
- # parameters on the operation level override those at the path level.
53
- dig(*operation_node, 'parameters'),
54
- dig(*operation_node[..-2], 'parameters')
55
- ].compact.flatten,
56
- params
50
+ specification: self,
51
+ node: operation_node,
52
+ params:
57
53
  ).to_h
58
54
  end
59
55
 
@@ -64,7 +60,8 @@ class Reynard
64
60
  end
65
61
 
66
62
  def operation(operation_name)
67
- dig('paths').each do |path, operations|
63
+ dig('paths').each_key do |path|
64
+ operations = dig('paths', path)
68
65
  operations.slice(*VERBS).each do |verb, operation|
69
66
  return Operation.new(node: ['paths', path, verb]) if operation_name == operation['operationId']
70
67
  end
@@ -113,7 +110,6 @@ class Reynard
113
110
  end
114
111
 
115
112
  # rubocop:disable Metrics/AbcSize
116
- # rubocop:disable Metrics/CyclomaticComplexity
117
113
  # rubocop:disable Metrics/MethodLength
118
114
  def dig_into(data, cursor, path, filesystem_path)
119
115
  while path.length.positive?
@@ -129,8 +125,8 @@ class Reynard
129
125
  path = Rack::Utils.unescape_path(cursor['$ref'][2..]).split('/') + path
130
126
  cursor = data
131
127
  # References another file, with an optional anchor to an element in the data.
132
- when %r{\A\./}
133
- external = External.new(path: filesystem_path, ref: cursor['$ref'])
128
+ else
129
+ external = External.new(basepath:, path: filesystem_path, ref: cursor['$ref'])
134
130
  filesystem_path = external.filesystem_path
135
131
  path = external.path + path
136
132
  cursor = external.data
@@ -139,7 +135,10 @@ class Reynard
139
135
  cursor
140
136
  end
141
137
  # rubocop:enable Metrics/AbcSize
142
- # rubocop:enable Metrics/CyclomaticComplexity
143
138
  # rubocop:enable Metrics/MethodLength
139
+
140
+ def basepath
141
+ File.dirname(File.expand_path(@filename))
142
+ end
144
143
  end
145
144
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Reynard
4
- VERSION = '0.10.0'
4
+ VERSION = '0.10.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reynard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manfred Stienstra
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-08-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: multi_json
@@ -91,7 +90,6 @@ licenses:
91
90
  - MIT
92
91
  metadata:
93
92
  rubygems_mfa_required: 'true'
94
- post_install_message:
95
93
  rdoc_options: []
96
94
  require_paths:
97
95
  - lib
@@ -106,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
104
  - !ruby/object:Gem::Version
107
105
  version: '0'
108
106
  requirements: []
109
- rubygems_version: 3.5.16
110
- signing_key:
107
+ rubygems_version: 3.6.7
111
108
  specification_version: 4
112
109
  summary: Minimal OpenAPI client.
113
110
  test_files: []