openapi_parser 0.10.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98afa3c7fb754859a594373659d18ebb81483581c948621d0ea050c360da38ec
4
- data.tar.gz: 9cf7b695875b6ca55a89a3d5e1a288381d39e203c5fbb469beeb7465232ff0a5
3
+ metadata.gz: e25413096d326cffe71e82846cc5c95c10c9d453ef7ec2026840cebc9d90ff67
4
+ data.tar.gz: e2c3efef0cab1f63e0c4c682802e4a377b711b769ffce3203b47a2313c5da235
5
5
  SHA512:
6
- metadata.gz: ddc32d47e0072b78f4790a6b6fa031eab103bb4665d5c0cfe4e7ac2ac9b2e04a048a82f4ddefd40fd112221e389cd86568ac67c3ca9db6f46ae4b9f8ece23c8a
7
- data.tar.gz: bdd2fdeaec224eaecdde6088abc7eb69513a4ab9e2afffbf23a6a21f9e13a640bddaf6bd7fbbaab16dff588c021bc12296aefd01b1efcb28908f33f8b263f9ad
6
+ metadata.gz: 1ddcd885be5ccfdd2cc74f60731517e9a18617d001abb3c95767905c6629e5fe6925e39cfb2668c81a94696974aab22a6a20f7eb96f403d189f9d3f6957f3fd2
7
+ data.tar.gz: b588c5ebfcecb63112c8cbf97bfdacc26bcdfdcea24d38315f20210eeb4b93848ed58dd3c415d8b866363b579f026a5449993932e919005509e6254ea3d3671b
data/.gitignore CHANGED
@@ -7,6 +7,9 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ # RubyMine
11
+ .idea
12
+
10
13
  # rspec failure tracking
11
14
  .rspec_status
12
- Gemfile.lock
15
+ Gemfile.lock
@@ -6,9 +6,10 @@ language: ruby
6
6
 
7
7
  rvm:
8
8
  - 2.3.8
9
- - 2.4.6
10
- - 2.5.5
11
- - 2.6.3
9
+ - 2.4.10
10
+ - 2.5.8
11
+ - 2.6.6
12
+ - 2.7.1
12
13
  - ruby-head
13
14
 
14
15
  cache: bundler
@@ -1,5 +1,24 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 0.12.1 (2020-08-27)
4
+ * Use CGI.unescape (warning fix) #92
5
+
6
+ ## 0.12.0 (2020-08-26)
7
+ * Find path by extracted params than path length #84
8
+ * Unescape ref URI before lookup in OpenAPIParser::Findable #85
9
+ * Improved path parameter matching code to allow file extensions, multiple parameters inside one path element, etc #90
10
+
11
+ ## 0.11.2 (2020-05-23)
12
+ * Allow date and time content in YAML #81
13
+
14
+ ## 0.11.1 (2020-05-09)
15
+ * fix too many warning
16
+
17
+ ## 0.11.0 (2020-05-09)
18
+ * Add committee friendly interface to use remote references. #74
19
+ * Prevent SystemStackError on recursive schema reference #76
20
+ * support newest ruby versions #78
21
+
3
22
  ## 0.10.0 (2020-04-01)
4
23
  * Support $ref to objects in other OpenAPI yaml files #66
5
24
  * Allow $ref for path item objects #71
@@ -18,18 +18,24 @@ require 'openapi_parser/reference_expander'
18
18
 
19
19
  module OpenAPIParser
20
20
  class << self
21
- # Load schema yaml object. Uri is not set for returned schema.
21
+ # Load schema hash object. Uri is not set for returned schema.
22
22
  # @return [OpenAPIParser::Schemas::OpenAPI]
23
23
  def parse(schema, config = {})
24
24
  load_hash(schema, config: Config.new(config), uri: nil, schema_registry: {})
25
25
  end
26
26
 
27
+ # @param filepath [String] Path of the file containing the passed schema.
28
+ # Used for resolving remote $ref if provided.
29
+ # If file path is relative, it is resolved using working directory.
30
+ # @return [OpenAPIParser::Schemas::OpenAPI]
31
+ def parse_with_filepath(schema, filepath, config = {})
32
+ load_hash(schema, config: Config.new(config), uri: filepath && file_uri(filepath), schema_registry: {})
33
+ end
34
+
27
35
  # Load schema in specified filepath. If file path is relative, it is resolved using working directory.
28
36
  # @return [OpenAPIParser::Schemas::OpenAPI]
29
37
  def load(filepath, config = {})
30
- path = Pathname.new(filepath)
31
- path = Pathname.getwd + path if path.relative?
32
- load_uri(URI.join("file:///", path.to_s), config: Config.new(config), schema_registry: {})
38
+ load_uri(file_uri(filepath), config: Config.new(config), schema_registry: {})
33
39
  end
34
40
 
35
41
  # Load schema located by the passed uri. Uri must be absolute.
@@ -49,6 +55,12 @@ module OpenAPIParser
49
55
 
50
56
  private
51
57
 
58
+ def file_uri(filepath)
59
+ path = Pathname.new(filepath)
60
+ path = Pathname.getwd + path if path.relative?
61
+ URI.join("file:///", path.to_s)
62
+ end
63
+
52
64
  def parse_file(content, extension)
53
65
  case extension.downcase
54
66
  when '.yaml', '.yml'
@@ -66,7 +78,10 @@ module OpenAPIParser
66
78
  end
67
79
 
68
80
  def parse_yaml(content)
69
- Psych.safe_load(content)
81
+ # FIXME: when drop ruby 2.5, we should use permitted_classes
82
+ (Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.6.0")) ?
83
+ Psych.safe_load(content, [Date, Time]) :
84
+ Psych.safe_load(content, permitted_classes: [Date, Time])
70
85
  end
71
86
 
72
87
  def parse_json(content)
@@ -1,9 +1,11 @@
1
+ require 'cgi'
1
2
  require 'uri'
2
3
 
3
4
  module OpenAPIParser::Findable
4
5
  # @param [String] reference
5
6
  # @return [OpenAPIParser::Findable]
6
7
  def find_object(reference)
8
+ reference = CGI.unescape(reference)
7
9
  return self if object_reference == reference
8
10
  remote_reference = !reference.start_with?('#')
9
11
  return find_remote_object(reference) if remote_reference
@@ -30,7 +32,12 @@ module OpenAPIParser::Findable
30
32
  end
31
33
 
32
34
  def purge_object_cache
35
+ @purged = false unless defined? @purged
36
+
37
+ return if @purged
38
+
33
39
  @find_object_cache = {}
40
+ @purged = true
34
41
 
35
42
  _openapi_all_child_objects.values.each(&:purge_object_cache)
36
43
  end
@@ -38,7 +38,41 @@ class OpenAPIParser::PathItemFinder
38
38
  end
39
39
  end
40
40
 
41
+ def parse_path_parameters(schema_path, request_path)
42
+ parameters = path_parameters(schema_path)
43
+ return nil if parameters.empty?
44
+
45
+ # If there are regex special characters in the path, the regex will
46
+ # be too permissive, so escape the non-parameter parts.
47
+ components = []
48
+ unprocessed = schema_path.dup
49
+ parameters.each do |parameter|
50
+ parts = unprocessed.partition(parameter)
51
+ components << Regexp.escape(parts[0]) unless parts[0] == ''
52
+ components << "(?<#{param_name(parameter)}>.+)"
53
+ unprocessed = parts[2]
54
+ end
55
+ components << Regexp.escape(unprocessed) unless unprocessed == ''
56
+
57
+ regex = components.join('')
58
+ matches = request_path.match(regex)
59
+ return nil unless matches
60
+
61
+ # Match up the captured names with the captured values as a hash
62
+ matches.names.zip(matches.captures).to_h
63
+ end
64
+
41
65
  private
66
+ def path_parameters(schema_path)
67
+ # OAS3 follows a RFC6570 subset for URL templates
68
+ # https://swagger.io/docs/specification/serialization/#uri-templates
69
+ # A URL template param can be preceded optionally by a "." or ";", and can be succeeded optionally by a "*";
70
+ # this regex returns a match of the full parameter name with all of these modifiers. Ex: {;id*}
71
+ parameters = schema_path.scan(/(\{[\.;]*[^\{\*\}]+\**\})/)
72
+ # The `String#scan` method returns an array of arrays; we want an array of strings
73
+ parameters.collect { |param| param[0] }
74
+ end
75
+
42
76
  # check if there is a identical path in the schema (without any param)
43
77
  def matches_directly?(request_path, http_method)
44
78
  @paths.path[request_path]&.operation(http_method)
@@ -70,8 +104,9 @@ class OpenAPIParser::PathItemFinder
70
104
  splitted_request_path.zip(splitted_schema_path).reduce({}) do |result, zip_item|
71
105
  request_path_item, schema_path_item = zip_item
72
106
 
73
- if path_template?(schema_path_item)
74
- result[param_name(schema_path_item)] = request_path_item
107
+ params = parse_path_parameters(schema_path_item, request_path_item)
108
+ if params
109
+ result.merge!(params)
75
110
  else
76
111
  return if schema_path_item != request_path_item
77
112
  end
@@ -80,7 +115,7 @@ class OpenAPIParser::PathItemFinder
80
115
  end
81
116
  end
82
117
 
83
- # find all matching patchs with parameters extracted
118
+ # find all matching paths with parameters extracted
84
119
  # EXAMPLE:
85
120
  # [
86
121
  # ['/user/{id}/edit', { 'id' => 1 }],
@@ -94,7 +129,7 @@ class OpenAPIParser::PathItemFinder
94
129
  splitted_schema_path = path.split('/')
95
130
 
96
131
  next result if different_depth_or_method?(splitted_schema_path, splitted_request_path, path_item, http_method)
97
-
132
+
98
133
  extracted_params = extract_params(splitted_request_path, splitted_schema_path)
99
134
  result << [path, extracted_params] if extracted_params
100
135
  result
@@ -105,12 +140,12 @@ class OpenAPIParser::PathItemFinder
105
140
  # EXAMPLE: find_path_and_params('get', '/user/1') => ['/user/{id}', { 'id' => 1 }]
106
141
  def find_path_and_params(http_method, request_path)
107
142
  return [request_path, {}] if matches_directly?(request_path, http_method)
108
-
143
+
109
144
  matching = matching_paths_with_params(request_path, http_method)
110
145
 
111
146
  # if there are many matching paths, return the one with the smallest number of params
112
147
  # (prefer /user/{id}/action over /user/{param_1}/{param_2} )
113
- matching.min_by { |match| match[0].size }
148
+ matching.min_by { |match| match[1].size }
114
149
  end
115
150
 
116
151
  def parse_request_path(http_method, request_path)
@@ -34,7 +34,7 @@ class OpenAPIParser::SchemaValidator
34
34
  unless resolved_schema
35
35
  return [nil, OpenAPIParser::NotExistDiscriminatorMappedSchema.new(mapping_target, discriminator.object_reference)]
36
36
  end
37
- validatable.validate_schema(value, resolved_schema, {discriminator_property_name: discriminator.property_name})
37
+ validatable.validate_schema(value, resolved_schema, **{discriminator_property_name: discriminator.property_name})
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module OpenAPIParser
2
- VERSION = '0.10.0'.freeze
2
+ VERSION = '0.12.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ota42y
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-01 00:00:00.000000000 Z
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  - !ruby/object:Gem::Version
223
223
  version: '0'
224
224
  requirements: []
225
- rubygems_version: 3.0.3
225
+ rubygems_version: 3.1.2
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: OpenAPI3 parser