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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +15 -12
- data/README.md +8 -6
- data/lib/openapi_parameters/converter.rb +1 -11
- data/lib/openapi_parameters/cookie.rb +1 -29
- data/lib/openapi_parameters/header.rb +1 -29
- data/lib/openapi_parameters/parameter.rb +5 -12
- data/lib/openapi_parameters/path.rb +4 -48
- data/lib/openapi_parameters/query.rb +2 -40
- data/lib/openapi_parameters/unpacker.rb +73 -0
- data/lib/openapi_parameters/version.rb +1 -1
- 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: d08c51fd9da86ddf6ef26a0e0778031b33224475091f21bf212cbdda65dd0b80
|
4
|
+
data.tar.gz: b8c2d56ad760c556cb51996e694d7bb8dbfe3d6188f4407702f698e8ca49b720
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdb3cf5fd14b1decad231f881229d9344020a59722c07086e5a79c0ee6f58bbad335f982a8847d60e64fb9e62c066636a142f514239ca78a7ec5de0916663abd
|
7
|
+
data.tar.gz: affa943a27552eb4a9a1495272d80d5d8cb2f591145b79758056c2d2eb93949d61e63524733a0474a3596d1a7d0bc4c77c5187e0a7d4bd9cd02e41cbd88e6706
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openapi_parameters (0.2.
|
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.
|
18
|
-
parser (3.2.
|
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.
|
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.
|
34
|
+
rspec-core (3.12.2)
|
35
35
|
rspec-support (~> 3.12.0)
|
36
|
-
rspec-expectations (3.12.
|
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.
|
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.
|
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.
|
53
|
+
rubocop-ast (1.28.1)
|
54
54
|
parser (>= 3.2.1.0)
|
55
|
-
rubocop-capybara (2.
|
55
|
+
rubocop-capybara (2.18.0)
|
56
56
|
rubocop (~> 1.41)
|
57
|
-
rubocop-
|
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.
|
65
|
+
zeitwerk (2.6.8)
|
63
66
|
|
64
67
|
PLATFORMS
|
65
68
|
arm64-darwin-21
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# openapi_parameters
|
2
2
|
|
3
|
-
|
3
|
+
openapi_parameters is an an [OpenAPI](https://www.openapis.org/) aware parameter parser.
|
4
4
|
|
5
|
-
|
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
|
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
|
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/
|
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 =
|
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 =
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
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
|
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 =
|
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
|
-
|
28
|
-
result[parameter.name] = convert(
|
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
|
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.
|
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-
|
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
|