openapi_first 0.21.0 → 1.0.0.beta3

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.
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rack'
4
-
5
- module OpenapiFirst
6
- class App
7
- def initialize( # rubocop:disable Metrics/ParameterLists
8
- parent_app,
9
- spec,
10
- namespace:,
11
- router_raise_error: false,
12
- request_validation_raise_error: false,
13
- response_validation: false,
14
- resolver: nil
15
- )
16
- @stack = Rack::Builder.app do
17
- freeze_app
18
- use OpenapiFirst::Router, spec: spec, raise_error: router_raise_error, parent_app: parent_app
19
- use OpenapiFirst::RequestValidation, raise_error: request_validation_raise_error
20
- use OpenapiFirst::ResponseValidation if response_validation
21
- run OpenapiFirst::Responder.new(namespace: namespace, resolver: resolver)
22
- end
23
- end
24
-
25
- def call(env)
26
- @stack.call(env)
27
- end
28
- end
29
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OpenapiFirst
4
- class Coverage
5
- attr_reader :to_be_called
6
-
7
- def initialize(app, spec)
8
- @app = app
9
- @spec = spec
10
- @to_be_called = spec.operations.map do |operation|
11
- endpoint_id(operation)
12
- end
13
- end
14
-
15
- def call(env)
16
- response = @app.call(env)
17
- operation = env[OPERATION]
18
- @to_be_called.delete(endpoint_id(operation)) if operation
19
- response
20
- end
21
-
22
- private
23
-
24
- def endpoint_id(operation)
25
- "#{operation.path}##{operation.method}"
26
- end
27
- end
28
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'utils'
4
-
5
- module OpenapiFirst
6
- class DefaultOperationResolver
7
- def initialize(namespace)
8
- @namespace = namespace
9
- @handlers = {}
10
- end
11
-
12
- def call(operation)
13
- @handlers[operation.name] ||= begin
14
- id = handler_id(operation)
15
- find_handler(id) if id
16
- end
17
- end
18
-
19
- def find_handler(id)
20
- name = id.match(/:*(.*)/)&.to_a&.at(1)
21
- return if name.nil?
22
-
23
- catch :halt do
24
- return find_class_method_handler(name) if name.include?('.')
25
- return find_instance_method_handler(name) if name.include?('#')
26
- end
27
- method_name = Utils.underscore(name)
28
- return unless @namespace.respond_to?(method_name)
29
-
30
- @namespace.method(method_name)
31
- end
32
-
33
- def handler_id(operation)
34
- id = operation['x-handler'] || operation['operationId']
35
- if id.nil?
36
- raise HandlerNotFoundError,
37
- "operationId or x-handler is missing in '#{operation.method} #{operation.path}' so I cannot find a handler for this operation." # rubocop:disable Layout/LineLength
38
- end
39
-
40
- id
41
- end
42
-
43
- def find_class_method_handler(name)
44
- module_name, method_name = name.split('.')
45
- klass = find_const(@namespace, module_name)
46
- klass.method(Utils.underscore(method_name))
47
- end
48
-
49
- def find_instance_method_handler(name)
50
- module_name, klass_name = name.split('#')
51
- const = find_const(@namespace, module_name)
52
- klass = find_const(const, klass_name)
53
- klass.new
54
- end
55
-
56
- def find_const(parent, name)
57
- name = Utils.classify(name)
58
- throw :halt unless parent.const_defined?(name, false)
59
-
60
- parent.const_get(name, false)
61
- end
62
- end
63
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OpenapiFirst
4
- # An instance of this gets passed to handler functions in the Responder.
5
- class Inbox < Hash
6
- attr_reader :env
7
-
8
- def initialize(env)
9
- @env = env
10
- super()
11
- end
12
- end
13
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'responder'
4
-
5
- module OpenapiFirst
6
- class RackResponder < Responder
7
- def call(env)
8
- operation = env[OpenapiFirst::OPERATION]
9
- find_handler(operation)&.call(env)
10
- end
11
- end
12
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rack'
4
- require 'multi_json'
5
- require_relative 'inbox'
6
- require_relative 'default_operation_resolver'
7
-
8
- module OpenapiFirst
9
- class Responder
10
- def initialize(namespace: nil, resolver: nil)
11
- @resolver = resolver || DefaultOperationResolver.new(namespace)
12
- @namespace = namespace
13
- end
14
-
15
- def call(env)
16
- operation = env[OpenapiFirst::OPERATION]
17
- res = Rack::Response.new
18
- handler = find_handler(operation)
19
- result = handler.call(inbox(env), res)
20
- res.write serialize(result) if result && res.body.empty?
21
- res[Rack::CONTENT_TYPE] ||= operation.content_types_for(res.status)&.first
22
- res.finish
23
- end
24
-
25
- private
26
-
27
- def inbox(env)
28
- Inbox.new(env).tap { |i| i.merge!(env[INBOX]) if env[INBOX] }
29
- end
30
-
31
- def find_handler(operation)
32
- handler = @resolver.call(operation)
33
- raise NotImplementedError, "Could not find handler for #{operation.name}" unless handler
34
-
35
- handler
36
- end
37
-
38
- def serialize(result)
39
- return result if result.is_a?(String)
40
-
41
- MultiJson.dump(result)
42
- end
43
- end
44
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'forwardable'
4
-
5
- module OpenapiFirst
6
- # Represents an OpenAPI Response Object
7
- class ResponseObject
8
- extend Forwardable
9
- def_delegators :@parsed,
10
- :content
11
-
12
- def_delegators :@raw,
13
- :[]
14
-
15
- def initialize(parsed)
16
- @parsed = parsed
17
- @raw = parsed.raw
18
- end
19
- end
20
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OpenapiFirst
4
- class Validation
5
- attr_reader :errors
6
-
7
- def initialize(errors)
8
- @errors = errors
9
- end
10
-
11
- def errors?
12
- !errors.empty?
13
- end
14
- end
15
- end