openapi_first 2.0.3 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 600de21e1747c012275bf68c2d577296a8d82bb158cb4d73949b5b97167e655d
4
- data.tar.gz: 86bcde27440b46fba91662fc7e6b86ac05d899da927fefc3e9d45a41a6d7fac9
3
+ metadata.gz: 1c1cc903f3a064f2f386503959e1b437729ab8a668ffbf0dd5aac19c38b4faf4
4
+ data.tar.gz: 0ee337872917f9009c9e9b9d57da4382e7b34248cf7df51a2926b3c589bc2f46
5
5
  SHA512:
6
- metadata.gz: ee729f6f6fedf5d6e9b82b82bdf86493a0a7ea6274e20b60e2cdd84eda2ce086cf366249f61a28016374355d11ab32654a970a418cf5af24a0b187d31b967618
7
- data.tar.gz: 125cc38e91e489f30c922f38056c69f9a6d501f3748ee098f2977d8fc6dc7f5f43f77264991f98564cb60ff2af19912ae85537c57d25c92604f8f6ee8766a749
6
+ metadata.gz: 30636bed981564cfe21696a46eb92d51ccb7680531b754dbfa37a6f52e37420f4e9611437e93ee54aada8eb6062db92ffd7fbce32eb1c76e8d856c5777b64444
7
+ data.tar.gz: 769c0821eca57bf60d8554ffd231b042511f57627f55c6083f2a9d054b35d08f0451d20f2411eaae035d7b3a591a046c57d732bf086143ac3d16162bf25b7c69
data/CHANGELOG.md CHANGED
@@ -2,8 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.1.0
6
+
7
+ - Added `OpenapiFirst::Definition#[]` to access the raw Hash representation of the OAS document. Example: `api['components'].fetch('schemas', 'Stations')`
8
+
9
+ ## 2.0.4
10
+
11
+ - Fix issue with parsing reponse body when using Rails https://github.com/ahx/openapi_first/issues/281
12
+
5
13
  ## 2.0.3
6
14
 
15
+ - Fix `OpenapiFirst::Test.register` https://github.com/ahx/openapi_first/issues/276
16
+
7
17
  - Request validation middleware now accepts `error_response: false` do disable rendering a response. This is useful if you just want to collect metrics (via hooks) during a migration phase.
8
18
 
9
19
  ## 2.0.2
@@ -5,12 +5,22 @@ require_relative 'router'
5
5
  require_relative 'request'
6
6
  require_relative 'response'
7
7
  require_relative 'builder'
8
+ require 'forwardable'
8
9
 
9
10
  module OpenapiFirst
10
11
  # Represents an OpenAPI API Description document
11
12
  # This is returned by OpenapiFirst.load.
12
13
  class Definition
13
- attr_reader :filepath, :config, :paths, :router
14
+ extend Forwardable
15
+
16
+ # @return [String,nil]
17
+ attr_reader :filepath
18
+ # @return [Configuration]
19
+ attr_reader :config
20
+ # @return [Enumerable[String]]
21
+ attr_reader :paths
22
+ # @return [Router]
23
+ attr_reader :router
14
24
 
15
25
  # @param resolved [Hash] The resolved OpenAPI document.
16
26
  # @param filepath [String] The file path of the OpenAPI document.
@@ -20,15 +30,23 @@ module OpenapiFirst
20
30
  yield @config if block_given?
21
31
  @config.freeze
22
32
  @router = Builder.build_router(resolved, @config)
33
+ @resolved = resolved
23
34
  @paths = resolved['paths'].keys # TODO: Move into builder as well
24
35
  end
25
36
 
37
+ # Gives access to the raw resolved Hash. Like `mydefinition['components'].dig('schemas', 'Stations')`
38
+ # @!method [](key)
39
+ # @return [Hash]
40
+ def_delegators :@resolved, :[]
41
+
42
+ # Returns an Enumerable of available Routes for this API description.
43
+ # @return [Enumerable[Router::Route]]
26
44
  def routes
27
45
  @router.routes
28
46
  end
29
47
 
30
48
  # Validates the request against the API description.
31
- # @param [Rack::Request] rack_request The Rack request object.
49
+ # @param [Rack::Request] request The Rack request object.
32
50
  # @param [Boolean] raise_error Whether to raise an error if validation fails.
33
51
  # @return [ValidatedRequest] The validated request object.
34
52
  def validate_request(request, raise_error: false)
@@ -1,38 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenapiFirst
4
- # @!visibility private
4
+ # Base class for all errors
5
5
  class Error < StandardError; end
6
- # @!visibility private
6
+
7
+ # Raised if YAML/JSON file was not found
7
8
  class FileNotFoundError < Error; end
8
- # @!visibility private
9
+
10
+ # Raised if response body could not be parsed
9
11
  class ParseError < Error; end
10
12
 
11
- # @!visibility private
13
+ # Raised during request validation if request was invalid
12
14
  class RequestInvalidError < Error
13
15
  def initialize(message, validated_request)
14
16
  super(message)
15
17
  @request = validated_request
16
18
  end
17
19
 
18
- # @attr_reader [OpenapiFirst::ValidatedRequest] request The validated request
20
+ # @return [ValidatedRequest] The validated request
19
21
  attr_reader :request
20
22
  end
21
23
 
22
- # @!visibility private
24
+ # Raised during request validation if request was not defined in the API description
23
25
  class NotFoundError < RequestInvalidError; end
24
26
 
25
- # @!visibility private
27
+ # Raised during response validation if request was invalid
26
28
  class ResponseInvalidError < Error
27
29
  def initialize(message, validated_response)
28
30
  super(message)
29
31
  @response = validated_response
30
32
  end
31
33
 
32
- # @attr_reader [OpenapiFirst::ValidatedResponse] request The validated response
34
+ # @return [ValidatedResponse] The validated response
33
35
  attr_reader :response
34
36
  end
35
37
 
36
- # @!visibility private
38
+ # Raised during request validation if response was not defined in the API description
37
39
  class ResponseNotFoundError < ResponseInvalidError; end
38
40
  end
@@ -25,20 +25,9 @@ module OpenapiFirst
25
25
 
26
26
  def call(env)
27
27
  status, headers, body = @app.call(env)
28
- body = read_body(body)
29
28
  @definition.validate_response(Rack::Request.new(env), Rack::Response[status, headers, body], raise_error: @raise)
30
29
  [status, headers, body]
31
30
  end
32
-
33
- private
34
-
35
- def read_body(body)
36
- return body.to_ary if body.respond_to?(:to_ary)
37
-
38
- result = []
39
- body.each { |part| result << part }
40
- result
41
- end
42
31
  end
43
32
  end
44
33
  end
@@ -15,46 +15,53 @@ module OpenapiFirst
15
15
  @request_definition = request_definition
16
16
  end
17
17
 
18
- # @!method error
19
- # @return [Failure, nil] The error that occurred during validation.
20
- # @!method request_definition
21
- # @return [Request, nil]
22
- attr_reader :parsed_values, :error, :request_definition
18
+ # A Failure object if the request is invalid
19
+ # @return [Failure, nil]
20
+ attr_reader :error
21
+
22
+ # The request definition if this request is defined in the API description
23
+ # @return [Request, nil]
24
+ attr_reader :request_definition
23
25
 
24
- # Openapi 3 specific
25
- # @!method operation
26
- # @return [Hash] The OpenAPI 3 operation object
27
26
  # @!method operation_id
28
- # @return [String, nil] The OpenAPI 3 operationId
29
- def_delegators :request_definition, :operation_id, :operation
27
+ # @return [String, nil] The OpenAPI 3 operationId
28
+ def_delegator :request_definition, :operation_id
29
+
30
+ # @!method operation
31
+ # @return [Hash] The raw OpenAPI 3 operation object
32
+ def_delegator :request_definition, :operation
30
33
 
31
34
  # Parsed path parameters
32
- # @return [Hash] A string keyed hash of path parameters
35
+ # @return [Hash<String, anything>]
33
36
  def parsed_path_parameters
34
- parsed_values[:path]
37
+ @parsed_values[:path]
35
38
  end
36
39
 
37
40
  # Parsed query parameters. This only returns the query parameters that are defined in the OpenAPI spec.
41
+ # @return [Hash<String, anything>]
38
42
  def parsed_query
39
- parsed_values[:query]
43
+ @parsed_values[:query]
40
44
  end
41
45
 
42
46
  # Parsed headers. This only returns the query parameters that are defined in the OpenAPI spec.
47
+ # @return [Hash<String, anything>]
43
48
  def parsed_headers
44
- parsed_values[:headers]
49
+ @parsed_values[:headers]
45
50
  end
46
51
 
47
52
  # Parsed cookies. This only returns the query parameters that are defined in the OpenAPI spec.
53
+ # @return [Hash<String, anything>]
48
54
  def parsed_cookies
49
- parsed_values[:cookies]
55
+ @parsed_values[:cookies]
50
56
  end
51
57
 
52
58
  # Parsed body. This parses the body according to the content type.
53
59
  # Note that this returns the hole body, not only the fields that are defined in the OpenAPI spec.
54
60
  # You can use JSON Schemas `additionalProperties` or `unevaluatedProperties` to
55
61
  # returns a validation error if the body contains unknown fields.
62
+ # @return [Hash<String, anything>]
56
63
  def parsed_body
57
- parsed_values[:body]
64
+ @parsed_values[:body]
58
65
  end
59
66
 
60
67
  # Checks if the request is valid.
@@ -74,6 +81,7 @@ module OpenapiFirst
74
81
 
75
82
  # Merged path, query, body parameters.
76
83
  # Here path has the highest precedence, then query, then body.
84
+ # @return [Hash<String, anything>]
77
85
  def parsed_params
78
86
  @parsed_params ||= parsed_body.merge(parsed_query, parsed_path_parameters)
79
87
  end
@@ -15,10 +15,23 @@ module OpenapiFirst
15
15
  @response_definition = response_definition
16
16
  end
17
17
 
18
- attr_reader :parsed_values, :error, :response_definition
18
+ # A Failure object if the response is invalid
19
+ # @return [Failure, nil]
20
+ attr_reader :error
19
21
 
20
- def_delegator :parsed_values, :headers, :parsed_headers
21
- def_delegator :parsed_values, :body, :parsed_body
22
+ # The response definition if this response is defined in the API description
23
+ # @return [Response, nil]
24
+ attr_reader :response_definition
25
+
26
+ # The parsed headers
27
+ # @!method parsed_headers
28
+ # @return [Hash<String,anything>]
29
+ def_delegator :@parsed_values, :headers, :parsed_headers
30
+
31
+ # The parsed body
32
+ # @!method parsed_body
33
+ # @return [Hash<String,anything>]
34
+ def_delegator :@parsed_values, :body, :parsed_body
22
35
 
23
36
  # Checks if the response is valid.
24
37
  # @return [Boolean] true if the response is valid, false otherwise.
@@ -26,6 +39,8 @@ module OpenapiFirst
26
39
  error.nil?
27
40
  end
28
41
 
42
+ # Checks if the response is invalid.
43
+ # @return [Boolean]
29
44
  def invalid?
30
45
  !valid?
31
46
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenapiFirst
4
- VERSION = '2.0.3'
4
+ VERSION = '2.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi_first
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Haller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-13 00:00:00.000000000 Z
11
+ date: 2024-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hana