openapi_parameters 0.2.1 → 0.2.2

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: 8483c9c6b0071290af337487bdec6ae34c94904497c7dce5abb120c497eef94e
4
- data.tar.gz: 78a862041af3c393e242185021eb52314f8d47e81c03160c41b46a2437379db7
3
+ metadata.gz: d08c51fd9da86ddf6ef26a0e0778031b33224475091f21bf212cbdda65dd0b80
4
+ data.tar.gz: b8c2d56ad760c556cb51996e694d7bb8dbfe3d6188f4407702f698e8ca49b720
5
5
  SHA512:
6
- metadata.gz: 8234ded58769039d9366d94d0482be0ea0ba1ed22385ebb8d9f42ec9c1d93e3b3d5b295bc09cc049ba75613886dc7a1e8b7b6d83af953061591bb21d4c4ae80f
7
- data.tar.gz: 1f0cac157a4601b405199bbddce07cb6bb41f701cb69570ef8e8ecd92ad610a504c066a834f9aad9da157ede3987bd27356e59dd5ecdd29ce3ac2074d6f7ffbc
6
+ metadata.gz: fdb3cf5fd14b1decad231f881229d9344020a59722c07086e5a79c0ee6f58bbad335f982a8847d60e64fb9e62c066636a142f514239ca78a7ec5de0916663abd
7
+ data.tar.gz: affa943a27552eb4a9a1495272d80d5d8cb2f591145b79758056c2d2eb93949d61e63524733a0474a3596d1a7d0bc4c77c5187e0a7d4bd9cd02e41cbd88e6706
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.2] - 2023-06-01
4
+
5
+ - Remove superflous validation of "in" property
6
+ - Remove superfluous check for unsupported $ref inside parameter schema
7
+
3
8
  ## [0.2.1] - 2023-03-31
4
9
 
5
10
  - Fix links in gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openapi_parameters (0.2.1)
4
+ openapi_parameters (0.2.2)
5
5
  rack (>= 2.2)
6
6
  zeitwerk (~> 2.6)
7
7
 
@@ -14,13 +14,13 @@ GEM
14
14
  benchmark-trend (0.4.0)
15
15
  diff-lcs (1.5.0)
16
16
  json (2.6.3)
17
- parallel (1.22.1)
18
- parser (3.2.1.1)
17
+ parallel (1.23.0)
18
+ parser (3.2.2.1)
19
19
  ast (~> 2.4.1)
20
20
  rack (3.0.7)
21
21
  rainbow (3.1.1)
22
22
  rake (13.0.6)
23
- regexp_parser (2.7.0)
23
+ regexp_parser (2.8.0)
24
24
  rexml (3.2.5)
25
25
  rspec (3.12.0)
26
26
  rspec-core (~> 3.12.0)
@@ -31,35 +31,38 @@ GEM
31
31
  benchmark-perf (~> 0.6)
32
32
  benchmark-trend (~> 0.4)
33
33
  rspec (>= 3.0)
34
- rspec-core (3.12.1)
34
+ rspec-core (3.12.2)
35
35
  rspec-support (~> 3.12.0)
36
- rspec-expectations (3.12.2)
36
+ rspec-expectations (3.12.3)
37
37
  diff-lcs (>= 1.2.0, < 2.0)
38
38
  rspec-support (~> 3.12.0)
39
39
  rspec-mocks (3.12.5)
40
40
  diff-lcs (>= 1.2.0, < 2.0)
41
41
  rspec-support (~> 3.12.0)
42
42
  rspec-support (3.12.0)
43
- rubocop (1.48.1)
43
+ rubocop (1.51.0)
44
44
  json (~> 2.3)
45
45
  parallel (~> 1.10)
46
46
  parser (>= 3.2.0.0)
47
47
  rainbow (>= 2.2.2, < 4.0)
48
48
  regexp_parser (>= 1.8, < 3.0)
49
49
  rexml (>= 3.2.5, < 4.0)
50
- rubocop-ast (>= 1.26.0, < 2.0)
50
+ rubocop-ast (>= 1.28.0, < 2.0)
51
51
  ruby-progressbar (~> 1.7)
52
52
  unicode-display_width (>= 2.4.0, < 3.0)
53
- rubocop-ast (1.28.0)
53
+ rubocop-ast (1.28.1)
54
54
  parser (>= 3.2.1.0)
55
- rubocop-capybara (2.17.1)
55
+ rubocop-capybara (2.18.0)
56
56
  rubocop (~> 1.41)
57
- rubocop-rspec (2.19.0)
57
+ rubocop-factory_bot (2.23.1)
58
+ rubocop (~> 1.33)
59
+ rubocop-rspec (2.22.0)
58
60
  rubocop (~> 1.33)
59
61
  rubocop-capybara (~> 2.17)
62
+ rubocop-factory_bot (~> 2.22)
60
63
  ruby-progressbar (1.13.0)
61
64
  unicode-display_width (2.4.2)
62
- zeitwerk (2.6.7)
65
+ zeitwerk (2.6.8)
63
66
 
64
67
  PLATFORMS
65
68
  arm64-darwin-21
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # OpenapiParameters
1
+ # openapi_parameters
2
2
 
3
- OpenapiParameters is an an [OpenAPI](https://www.openapis.org/) aware parameter parser.
3
+ openapi_parameters is an an [OpenAPI](https://www.openapis.org/) aware parameter parser.
4
4
 
5
- OpenapiParameters unpacks HTTP/Rack (query / header / cookie) parameters exactly as described in an [OpenAPI](https://www.openapis.org/) definition. It supports `style`, `explode` and `schema` definitions according to OpenAPI 3.1 (or 3.0). The gem is mainly build to be used inside of other OpenAPI tooling.
5
+ openapi_parameters unpacks HTTP/Rack query / path / header / cookie parameters exactly as described in an [OpenAPI](https://www.openapis.org/) definition. It supports `style`, `explode` and `schema` definitions according to OpenAPI 3.1 (or 3.0). The gem is mainly build to be used inside of other OpenAPI tooling like [openapi_first](https://github.com/ahx/openapi_first).
6
+
7
+ [Learn about parameters in OpenAPI](https://spec.openapis.org/oas/latest.html#parameter-object).
6
8
 
7
9
  ## Synopsis
8
10
 
@@ -72,11 +74,11 @@ parameter.allow_reserved? # => false
72
74
 
73
75
  Install the gem and add to the application's Gemfile by executing:
74
76
 
75
- $ bundle add OpenapiParameters
77
+ $ bundle add openapi_parameters
76
78
 
77
79
  If bundler is not being used to manage dependencies, install the gem by executing:
78
80
 
79
- $ gem install OpenapiParameters
81
+ $ gem install openapi_parameters
80
82
 
81
83
  ## Development
82
84
 
@@ -86,4 +88,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
86
88
 
87
89
  ## Contributing
88
90
 
89
- Bug reports and pull requests are welcome on GitHub at https://github.com/ahx/OpenapiParameters.
91
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ahx/openapi_parameters.
@@ -23,7 +23,7 @@ module OpenapiParameters
23
23
  private
24
24
 
25
25
  def convert(value, schema) # rubocop:disable Metrics/*
26
- check_supported!(schema)
26
+ # check_supported!(schema)
27
27
  return if value.nil?
28
28
  return value if schema.nil?
29
29
 
@@ -55,16 +55,6 @@ module OpenapiParameters
55
55
  end
56
56
  end
57
57
 
58
- REF = '$ref'
59
- private_constant :REF
60
-
61
- def check_supported!(schema)
62
- return unless schema&.key?(REF)
63
-
64
- raise NotSupportedError,
65
- "$ref is not supported: #{@root_schema.inspect}"
66
- end
67
-
68
58
  def type(schema)
69
59
  schema && schema['type']
70
60
  end
@@ -20,7 +20,7 @@ module OpenapiParameters
20
20
  next unless cookies.key?(parameter.name)
21
21
 
22
22
  result[parameter.name] = catch :skip do
23
- value = unpack_parameter(parameter, cookies)
23
+ value = Unpacker.unpack_value(parameter, cookies[parameter.name])
24
24
  @convert ? Converter.call(value, parameter.schema) : value
25
25
  end
26
26
  end
@@ -29,33 +29,5 @@ module OpenapiParameters
29
29
  private
30
30
 
31
31
  attr_reader :parameters
32
-
33
- def unpack_parameter(parameter, cookies)
34
- value = cookies[parameter.name]
35
- return if value.nil?
36
- return unpack_object(parameter, value) if parameter.object?
37
- return unpack_array(value) if parameter.array?
38
-
39
- value
40
- end
41
-
42
- def unpack_array(value)
43
- value.split(ARRAY_DELIMER)
44
- end
45
-
46
- ARRAY_DELIMER = ','
47
- OBJECT_EXPLODE_SPLITTER = Regexp.union(',', '=').freeze
48
-
49
- def unpack_object(parameter, value)
50
- entries =
51
- if parameter.explode?
52
- value.split(OBJECT_EXPLODE_SPLITTER)
53
- else
54
- value.split(ARRAY_DELIMER)
55
- end
56
- throw :skip, value if entries.length.odd?
57
-
58
- Hash[*entries]
59
- end
60
32
  end
61
33
  end
@@ -17,7 +17,7 @@ module OpenapiParameters
17
17
  next unless headers.key?(parameter.name)
18
18
 
19
19
  result[parameter.name] = catch :skip do
20
- value = unpack_parameter(parameter, headers)
20
+ value = Unpacker.unpack_value(parameter, headers[parameter.name])
21
21
  @convert ? Converter.call(value, parameter.schema) : value
22
22
  end
23
23
  end
@@ -28,33 +28,5 @@ module OpenapiParameters
28
28
  end
29
29
 
30
30
  attr_reader :parameters
31
-
32
- private
33
-
34
- def unpack_parameter(parameter, headers)
35
- value = headers[parameter.name]
36
- return value if parameter.primitive?
37
- return unpack_object(parameter, value) if parameter.object?
38
- return unpack_array(value) if parameter.array?
39
- end
40
-
41
- def unpack_array(value)
42
- value.split(ARRAY_DELIMER)
43
- end
44
-
45
- ARRAY_DELIMER = ','
46
- OBJECT_EXPLODE_SPLITTER = Regexp.union(',', '=').freeze
47
-
48
- def unpack_object(parameter, value)
49
- entries =
50
- if parameter.explode?
51
- value.split(OBJECT_EXPLODE_SPLITTER)
52
- else
53
- value.split(ARRAY_DELIMER)
54
- end
55
- throw :skip, value if entries.length.odd?
56
-
57
- Hash[*entries]
58
- end
59
31
  end
60
32
  end
@@ -4,6 +4,7 @@ module OpenapiParameters
4
4
  ##
5
5
  # Represents a parameter in an OpenAPI operation.
6
6
  class Parameter
7
+ # @param definition [Hash] The parameter definition. A string keyed Hash.
7
8
  def initialize(definition)
8
9
  check_supported!(definition)
9
10
  @definition = definition
@@ -86,22 +87,14 @@ module OpenapiParameters
86
87
  }.freeze
87
88
  private_constant :DEFAULT_STYLE
88
89
 
89
- VALID_LOCATIONS = Set.new(%w[query header path cookie]).freeze
90
- private_constant :VALID_LOCATIONS
91
-
92
90
  REF = '$ref'
93
91
  private_constant :REF
94
92
 
95
93
  def check_supported!(definition)
96
- if definition.values.any? { |v| v.is_a?(Hash) && v.key?(REF) }
97
- raise NotSupportedError,
98
- "Parameter schema with $ref is not supported: #{definition.inspect}"
99
- end
100
- return if VALID_LOCATIONS.include?(definition['in'])
101
-
102
- raise ArgumentError,
103
- %(Parameter definition must have an 'in' property defined
104
- which should be one of #{VALID_LOCATIONS.join(', ')}).freeze
94
+ return unless definition.values.any? { |v| v.is_a?(Hash) && v.key?(REF) }
95
+
96
+ raise NotSupportedError,
97
+ "Parameter schema with $ref is not supported: #{definition.inspect}"
105
98
  end
106
99
  end
107
100
  end
@@ -3,72 +3,28 @@
3
3
  require 'rack'
4
4
 
5
5
  module OpenapiParameters
6
- # Parses OpenAPI path parameters from path template strings and the request path.
6
+ # Parses OpenAPI path parameters from a route params Hash that is usually provided by your Rack webframework
7
7
  class Path
8
8
  # @param parameters [Array<Hash>] The OpenAPI path parameters.
9
- # @param path [String] The OpenAPI path template string.
10
9
  # @param convert [Boolean] Whether to convert the values to the correct type.
11
10
  def initialize(parameters, convert: true)
12
11
  @parameters = parameters
13
12
  @convert = convert
14
13
  end
15
14
 
16
- attr_reader :parameters, :path
15
+ attr_reader :parameters
17
16
 
17
+ # @param path_params [Hash] The path parameters from the Rack request. The keys are strings.
18
18
  def unpack(path_params)
19
19
  parameters.each_with_object({}) do |param, result|
20
20
  parameter = Parameter.new(param)
21
21
  next unless path_params.key?(parameter.name)
22
22
 
23
23
  result[parameter.name] = catch :skip do
24
- value = unpack_parameter(parameter, path_params)
24
+ value = Unpacker.unpack_value(parameter, path_params[parameter.name])
25
25
  @convert ? Converter.call(value, parameter.schema) : value
26
26
  end
27
27
  end
28
28
  end
29
-
30
- private
31
-
32
- def unpack_parameter(parameter, parsed_path)
33
- value = parsed_path[parameter.name]
34
- return value if parameter.primitive? || value.nil?
35
- return unpack_array(parameter, value) if parameter.array?
36
- return unpack_object(parameter, value) if parameter.object?
37
- end
38
-
39
- def unpack_array(parameter, value)
40
- return value if value.empty?
41
- return unpack_matrix(parameter, value) if parameter.style == 'matrix'
42
-
43
- value = value[1..] if PREFIXED.key?(parameter.style)
44
- value.split(ARRAY_DELIMITER[parameter.style])
45
- end
46
-
47
- def unpack_matrix(parameter, value)
48
- result = Rack::Utils.parse_query(value, ';')[parameter.name]
49
- return result if parameter.explode?
50
-
51
- result.split(',')
52
- end
53
-
54
- def unpack_object(parameter, value)
55
- return Rack::Utils.parse_query(value, ',') if parameter.explode?
56
-
57
- array = unpack_array(parameter, value)
58
- throw :skip, value if array.length.odd?
59
-
60
- Hash[*array]
61
- end
62
-
63
- PREFIXED = {
64
- 'label' => '.',
65
- 'matrix' => ';'
66
- }.freeze
67
-
68
- ARRAY_DELIMITER = {
69
- 'label' => '.',
70
- 'simple' => ','
71
- }.freeze
72
- private_constant :ARRAY_DELIMITER
73
29
  end
74
30
  end
@@ -24,8 +24,8 @@ module OpenapiParameters
24
24
  else
25
25
  next unless parsed_query.key?(parameter.name)
26
26
 
27
- unpacked = unpack_parameter(parameter, parsed_query)
28
- result[parameter.name] = convert(unpacked, parameter)
27
+ value = Unpacker.unpack_value(parameter, parsed_query[parameter.name])
28
+ result[parameter.name] = convert(value, parameter)
29
29
  end
30
30
  end
31
31
  end
@@ -40,43 +40,5 @@ module OpenapiParameters
40
40
 
41
41
  Converter.call(value, parameter.schema)
42
42
  end
43
-
44
- QUERY_PARAMETER_DELIMETER = '&'
45
- ARRAY_DELIMER = ','
46
-
47
- def unpack_parameter(parameter, parsed_query)
48
- value = parsed_query[parameter.name]
49
- return value if parameter.primitive? || value.nil?
50
- return unpack_array(parameter, parsed_query) if parameter.array?
51
- return unpack_object(parameter, parsed_query) if parameter.object?
52
- end
53
-
54
- def unpack_array(parameter, parsed_query)
55
- value = parsed_query[parameter.name]
56
- return value if value.empty?
57
- return Array(value) if parameter.explode?
58
-
59
- value.split(array_delimiter(parameter.style))
60
- end
61
-
62
- def unpack_object(parameter, parsed_query)
63
- return parsed_query[parameter.name] if parameter.explode?
64
-
65
- array = parsed_query[parameter.name]&.split(ARRAY_DELIMER)
66
- return array if array.length.odd?
67
-
68
- Hash[*array]
69
- end
70
-
71
- DELIMERS = {
72
- 'pipeDelimited' => '|',
73
- 'spaceDelimited' => ' ',
74
- 'form' => ',',
75
- 'simple' => ','
76
- }.freeze
77
-
78
- def array_delimiter(style)
79
- DELIMERS.fetch(style, ARRAY_DELIMER)
80
- end
81
43
  end
82
44
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenapiParameters
4
+ ## Unpacks a paramexter value from a string as defined in the OpenAPI specification.
5
+ # @visibility private
6
+ module Unpacker
7
+ class << self
8
+ def unpack_value(parameter, value)
9
+ return value if value.nil?
10
+ return unpack_array(parameter, value) if parameter.array?
11
+ return unpack_object(parameter, value) if parameter.object?
12
+
13
+ value
14
+ end
15
+
16
+ def unpack_array(parameter, value)
17
+ return value if value.is_a?(Array)
18
+ return value if value.empty?
19
+ return unpack_matrix(parameter, value) if parameter.style == 'matrix'
20
+
21
+ value = value[1..] if PREFIXED.key?(parameter.style)
22
+ value.split(ARRAY_DELIMITER[parameter.style])
23
+ end
24
+
25
+ def unpack_matrix(parameter, value)
26
+ result = Rack::Utils.parse_query(value, ';')[parameter.name]
27
+ return result if parameter.explode?
28
+
29
+ result.split(',')
30
+ end
31
+
32
+ OBJECT_EXPLODE_SPLITTER = Regexp.union(',', '=').freeze
33
+ private_constant :OBJECT_EXPLODE_SPLITTER
34
+
35
+ def unpack_object(parameter, value)
36
+ return unpack_object_path(parameter, value) if parameter.location == 'path'
37
+
38
+ entries =
39
+ if parameter.explode?
40
+ value.split(OBJECT_EXPLODE_SPLITTER)
41
+ else
42
+ value.split(ARRAY_DELIMITER[parameter.style])
43
+ end
44
+ throw :skip, value if entries.length.odd?
45
+
46
+ Hash[*entries]
47
+ end
48
+
49
+ def unpack_object_path(parameter, value)
50
+ return Rack::Utils.parse_query(value, ',') if parameter.explode?
51
+
52
+ array = unpack_array(parameter, value)
53
+ throw :skip, value if array.length.odd?
54
+
55
+ Hash[*array]
56
+ end
57
+
58
+ PREFIXED = {
59
+ 'label' => '.',
60
+ 'matrix' => ';'
61
+ }.freeze
62
+
63
+ ARRAY_DELIMITER = {
64
+ 'label' => '.',
65
+ 'simple' => ',',
66
+ 'form' => ',',
67
+ 'pipeDelimited' => '|',
68
+ 'spaceDelimited' => ' '
69
+ }.freeze
70
+ private_constant :ARRAY_DELIMITER
71
+ end
72
+ end
73
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenapiParameters
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi_parameters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Haller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-31 00:00:00.000000000 Z
11
+ date: 2023-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -64,6 +64,7 @@ files:
64
64
  - lib/openapi_parameters/parameter.rb
65
65
  - lib/openapi_parameters/path.rb
66
66
  - lib/openapi_parameters/query.rb
67
+ - lib/openapi_parameters/unpacker.rb
67
68
  - lib/openapi_parameters/version.rb
68
69
  - openapi_parameters.gemspec
69
70
  - sig/openapi_parameters.rbs