openapi_parameters 0.2.1 → 0.3.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/CHANGELOG.md +9 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +28 -18
- data/README.md +8 -6
- data/lib/openapi_parameters/converter.rb +60 -80
- data/lib/openapi_parameters/cookie.rb +2 -30
- data/lib/openapi_parameters/header.rb +2 -30
- data/lib/openapi_parameters/parameter.rb +5 -12
- data/lib/openapi_parameters/path.rb +5 -49
- data/lib/openapi_parameters/query.rb +8 -39
- 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: aa586602013f736682059c6e4615dbd4eb7e57daaa4633e6fb35982261a39e11
|
|
4
|
+
data.tar.gz: 772345d845efdf6d191c362176deac63036cf064fbd4145c8b375f9bf500faaf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d21a6c44fc2a1d6d72a3b4cd2bab4804ee4ddfd62d5cf73d3407bf913583b0733b61e9b567da45dca13f9bf2007d58ac6b45fb71299ffa509385aaa1f05b18a
|
|
7
|
+
data.tar.gz: d7cc40c0551910ba432955e7008762950d8c65df0b06e45d094dca0f8b601c6bacc68e6ef8d223471d9f59c112f7a872fd2a5903a7f78de2d70f0580ccfc9115
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2023-10-27
|
|
4
|
+
|
|
5
|
+
- Query parameters: Don't attempt to convert arras within deepObject objects. Behaviour is not defined in OpenApi 3.1.
|
|
6
|
+
|
|
7
|
+
## [0.2.2] - 2023-06-01
|
|
8
|
+
|
|
9
|
+
- Remove superflous validation of "in" property
|
|
10
|
+
- Remove superfluous check for unsupported $ref inside parameter schema
|
|
11
|
+
|
|
3
12
|
## [0.2.1] - 2023-03-31
|
|
4
13
|
|
|
5
14
|
- Fix links in gemspec
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
openapi_parameters (0.
|
|
4
|
+
openapi_parameters (0.3.0)
|
|
5
5
|
rack (>= 2.2)
|
|
6
6
|
zeitwerk (~> 2.6)
|
|
7
7
|
|
|
@@ -14,14 +14,19 @@ GEM
|
|
|
14
14
|
benchmark-trend (0.4.0)
|
|
15
15
|
diff-lcs (1.5.0)
|
|
16
16
|
json (2.6.3)
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
language_server-protocol (3.17.0.3)
|
|
18
|
+
parallel (1.23.0)
|
|
19
|
+
parser (3.2.2.4)
|
|
19
20
|
ast (~> 2.4.1)
|
|
20
|
-
|
|
21
|
+
racc
|
|
22
|
+
racc (1.7.1)
|
|
23
|
+
rack (3.0.8)
|
|
24
|
+
rack-test (2.1.0)
|
|
25
|
+
rack (>= 1.3)
|
|
21
26
|
rainbow (3.1.1)
|
|
22
27
|
rake (13.0.6)
|
|
23
|
-
regexp_parser (2.
|
|
24
|
-
rexml (3.2.
|
|
28
|
+
regexp_parser (2.8.2)
|
|
29
|
+
rexml (3.2.6)
|
|
25
30
|
rspec (3.12.0)
|
|
26
31
|
rspec-core (~> 3.12.0)
|
|
27
32
|
rspec-expectations (~> 3.12.0)
|
|
@@ -31,35 +36,39 @@ GEM
|
|
|
31
36
|
benchmark-perf (~> 0.6)
|
|
32
37
|
benchmark-trend (~> 0.4)
|
|
33
38
|
rspec (>= 3.0)
|
|
34
|
-
rspec-core (3.12.
|
|
39
|
+
rspec-core (3.12.2)
|
|
35
40
|
rspec-support (~> 3.12.0)
|
|
36
|
-
rspec-expectations (3.12.
|
|
41
|
+
rspec-expectations (3.12.3)
|
|
37
42
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
43
|
rspec-support (~> 3.12.0)
|
|
39
|
-
rspec-mocks (3.12.
|
|
44
|
+
rspec-mocks (3.12.6)
|
|
40
45
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
41
46
|
rspec-support (~> 3.12.0)
|
|
42
|
-
rspec-support (3.12.
|
|
43
|
-
rubocop (1.
|
|
47
|
+
rspec-support (3.12.1)
|
|
48
|
+
rubocop (1.57.2)
|
|
44
49
|
json (~> 2.3)
|
|
50
|
+
language_server-protocol (>= 3.17.0)
|
|
45
51
|
parallel (~> 1.10)
|
|
46
|
-
parser (>= 3.2.
|
|
52
|
+
parser (>= 3.2.2.4)
|
|
47
53
|
rainbow (>= 2.2.2, < 4.0)
|
|
48
54
|
regexp_parser (>= 1.8, < 3.0)
|
|
49
55
|
rexml (>= 3.2.5, < 4.0)
|
|
50
|
-
rubocop-ast (>= 1.
|
|
56
|
+
rubocop-ast (>= 1.28.1, < 2.0)
|
|
51
57
|
ruby-progressbar (~> 1.7)
|
|
52
58
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
53
|
-
rubocop-ast (1.
|
|
59
|
+
rubocop-ast (1.30.0)
|
|
54
60
|
parser (>= 3.2.1.0)
|
|
55
|
-
rubocop-capybara (2.
|
|
61
|
+
rubocop-capybara (2.19.0)
|
|
56
62
|
rubocop (~> 1.41)
|
|
57
|
-
rubocop-
|
|
63
|
+
rubocop-factory_bot (2.24.0)
|
|
58
64
|
rubocop (~> 1.33)
|
|
65
|
+
rubocop-rspec (2.25.0)
|
|
66
|
+
rubocop (~> 1.40)
|
|
59
67
|
rubocop-capybara (~> 2.17)
|
|
68
|
+
rubocop-factory_bot (~> 2.22)
|
|
60
69
|
ruby-progressbar (1.13.0)
|
|
61
|
-
unicode-display_width (2.
|
|
62
|
-
zeitwerk (2.6.
|
|
70
|
+
unicode-display_width (2.5.0)
|
|
71
|
+
zeitwerk (2.6.12)
|
|
63
72
|
|
|
64
73
|
PLATFORMS
|
|
65
74
|
arm64-darwin-21
|
|
@@ -69,6 +78,7 @@ PLATFORMS
|
|
|
69
78
|
|
|
70
79
|
DEPENDENCIES
|
|
71
80
|
openapi_parameters!
|
|
81
|
+
rack-test
|
|
72
82
|
rake (~> 13.0)
|
|
73
83
|
rspec (~> 3.0)
|
|
74
84
|
rspec-benchmark
|
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.
|
|
@@ -3,97 +3,77 @@
|
|
|
3
3
|
module OpenapiParameters
|
|
4
4
|
##
|
|
5
5
|
# Tries to convert a request parameter value (string) to the type specified in the JSON Schema.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def initialize(input, schema)
|
|
15
|
-
@input = input
|
|
16
|
-
@root_schema = schema
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def call
|
|
20
|
-
convert(@input, @root_schema)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def convert(value, schema) # rubocop:disable Metrics/*
|
|
26
|
-
check_supported!(schema)
|
|
27
|
-
return if value.nil?
|
|
28
|
-
return value if schema.nil?
|
|
6
|
+
module Converter
|
|
7
|
+
class << self
|
|
8
|
+
##
|
|
9
|
+
# @param input [String, Hash, Array] the value to convert
|
|
10
|
+
# @param schema [Hash] the schema to use for conversion.
|
|
11
|
+
def convert(value, schema) # rubocop:disable Metrics
|
|
12
|
+
return if value.nil?
|
|
13
|
+
return value if schema.nil?
|
|
29
14
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
15
|
+
case type(schema)
|
|
16
|
+
when 'integer'
|
|
17
|
+
begin
|
|
18
|
+
Integer(value, 10)
|
|
19
|
+
rescue StandardError
|
|
20
|
+
value
|
|
21
|
+
end
|
|
22
|
+
when 'number'
|
|
23
|
+
begin
|
|
24
|
+
Float(value)
|
|
25
|
+
rescue StandardError
|
|
26
|
+
value
|
|
27
|
+
end
|
|
28
|
+
when 'boolean'
|
|
29
|
+
if value == 'true'
|
|
30
|
+
true
|
|
31
|
+
else
|
|
32
|
+
value == 'false' ? false : value
|
|
33
|
+
end
|
|
34
|
+
when 'object'
|
|
35
|
+
convert_object(value, schema)
|
|
36
|
+
when 'array'
|
|
37
|
+
convert_array(value, schema)
|
|
46
38
|
else
|
|
47
|
-
value
|
|
39
|
+
value
|
|
48
40
|
end
|
|
49
|
-
when 'object'
|
|
50
|
-
convert_object(value, schema)
|
|
51
|
-
when 'array'
|
|
52
|
-
convert_array(value, schema)
|
|
53
|
-
else
|
|
54
|
-
value
|
|
55
41
|
end
|
|
56
|
-
end
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
private_constant :REF
|
|
43
|
+
private
|
|
60
44
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
raise NotSupportedError,
|
|
65
|
-
"$ref is not supported: #{@root_schema.inspect}"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def type(schema)
|
|
69
|
-
schema && schema['type']
|
|
70
|
-
end
|
|
45
|
+
def type(schema)
|
|
46
|
+
schema && schema['type']
|
|
47
|
+
end
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
49
|
+
def convert_object(object, schema)
|
|
50
|
+
object.each_with_object({}) do |(key, value), hsh|
|
|
51
|
+
hsh[key] = convert(value, schema['properties']&.fetch(key))
|
|
52
|
+
end
|
|
75
53
|
end
|
|
76
|
-
end
|
|
77
54
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
prefix_schemas = schema['prefixItems']
|
|
81
|
-
return convert_array_with_prefixes(array, prefix_schemas, item_schema) if prefix_schemas
|
|
55
|
+
def convert_array(array, schema)
|
|
56
|
+
return array unless array.is_a?(Array)
|
|
82
57
|
|
|
83
|
-
|
|
84
|
-
|
|
58
|
+
item_schema = schema['items']
|
|
59
|
+
prefix_schemas = schema['prefixItems']
|
|
60
|
+
return convert_array_with_prefixes(array, prefix_schemas, item_schema) if prefix_schemas
|
|
85
61
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
convert(item,
|
|
95
|
-
|
|
96
|
-
|
|
62
|
+
array.map { |item| convert(item, item_schema) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def convert_array_with_prefixes(array, prefix_schemas, item_schema)
|
|
66
|
+
prefixes =
|
|
67
|
+
array
|
|
68
|
+
.slice(0, prefix_schemas.size)
|
|
69
|
+
.each_with_index
|
|
70
|
+
.map { |item, index| convert(item, prefix_schemas[index]) }
|
|
71
|
+
array =
|
|
72
|
+
array[prefix_schemas.size..].map! do |item|
|
|
73
|
+
convert(item, item_schema)
|
|
74
|
+
end
|
|
75
|
+
prefixes + array
|
|
76
|
+
end
|
|
97
77
|
end
|
|
98
78
|
end
|
|
99
79
|
end
|
|
@@ -20,8 +20,8 @@ module OpenapiParameters
|
|
|
20
20
|
next unless cookies.key?(parameter.name)
|
|
21
21
|
|
|
22
22
|
result[parameter.name] = catch :skip do
|
|
23
|
-
value =
|
|
24
|
-
@convert ? Converter.
|
|
23
|
+
value = Unpacker.unpack_value(parameter, cookies[parameter.name])
|
|
24
|
+
@convert ? Converter.convert(value, parameter.schema) : value
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
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,8 +17,8 @@ module OpenapiParameters
|
|
|
17
17
|
next unless headers.key?(parameter.name)
|
|
18
18
|
|
|
19
19
|
result[parameter.name] = catch :skip do
|
|
20
|
-
value =
|
|
21
|
-
@convert ? Converter.
|
|
20
|
+
value = Unpacker.unpack_value(parameter, headers[parameter.name])
|
|
21
|
+
@convert ? Converter.convert(value, parameter.schema) : value
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
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 =
|
|
25
|
-
@convert ? Converter.
|
|
24
|
+
value = Unpacker.unpack_value(parameter, path_params[parameter.name])
|
|
25
|
+
@convert ? Converter.convert(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
|
|
@@ -34,49 +34,18 @@ module OpenapiParameters
|
|
|
34
34
|
|
|
35
35
|
private
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def convert_primitive(value, parameter)
|
|
38
38
|
return value unless @convert
|
|
39
39
|
return value if value == ''
|
|
40
40
|
|
|
41
|
-
Converter.
|
|
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))
|
|
41
|
+
Converter.convert_primitive(value, parameter.schema)
|
|
60
42
|
end
|
|
61
43
|
|
|
62
|
-
def
|
|
63
|
-
return
|
|
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
|
|
44
|
+
def convert(value, parameter)
|
|
45
|
+
return value unless @convert
|
|
46
|
+
return value if value == ''
|
|
77
47
|
|
|
78
|
-
|
|
79
|
-
DELIMERS.fetch(style, ARRAY_DELIMER)
|
|
48
|
+
Converter.convert(value, parameter.schema)
|
|
80
49
|
end
|
|
81
50
|
end
|
|
82
51
|
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.
|
|
4
|
+
version: 0.3.0
|
|
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-10-27 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
|