openapi3_parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +9 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +4 -0
  7. data/Gemfile +5 -0
  8. data/LICENCE +19 -0
  9. data/README.md +32 -0
  10. data/Rakefile +10 -0
  11. data/TODO.md +30 -0
  12. data/lib/openapi3_parser.rb +39 -0
  13. data/lib/openapi3_parser/context.rb +54 -0
  14. data/lib/openapi3_parser/document.rb +48 -0
  15. data/lib/openapi3_parser/error.rb +5 -0
  16. data/lib/openapi3_parser/fields/map.rb +83 -0
  17. data/lib/openapi3_parser/node.rb +115 -0
  18. data/lib/openapi3_parser/node/map.rb +24 -0
  19. data/lib/openapi3_parser/node/object.rb +28 -0
  20. data/lib/openapi3_parser/node_factories/array.rb +105 -0
  21. data/lib/openapi3_parser/node_factories/callback.rb +26 -0
  22. data/lib/openapi3_parser/node_factories/components.rb +83 -0
  23. data/lib/openapi3_parser/node_factories/contact.rb +24 -0
  24. data/lib/openapi3_parser/node_factories/discriminator.rb +31 -0
  25. data/lib/openapi3_parser/node_factories/encoding.rb +34 -0
  26. data/lib/openapi3_parser/node_factories/example.rb +25 -0
  27. data/lib/openapi3_parser/node_factories/external_documentation.rb +23 -0
  28. data/lib/openapi3_parser/node_factories/header.rb +36 -0
  29. data/lib/openapi3_parser/node_factories/info.rb +28 -0
  30. data/lib/openapi3_parser/node_factories/license.rb +22 -0
  31. data/lib/openapi3_parser/node_factories/link.rb +40 -0
  32. data/lib/openapi3_parser/node_factories/map.rb +110 -0
  33. data/lib/openapi3_parser/node_factories/media_type.rb +44 -0
  34. data/lib/openapi3_parser/node_factories/oauth_flow.rb +24 -0
  35. data/lib/openapi3_parser/node_factories/oauth_flows.rb +31 -0
  36. data/lib/openapi3_parser/node_factories/openapi.rb +50 -0
  37. data/lib/openapi3_parser/node_factories/operation.rb +76 -0
  38. data/lib/openapi3_parser/node_factories/parameter.rb +43 -0
  39. data/lib/openapi3_parser/node_factories/parameter/parameter_like.rb +37 -0
  40. data/lib/openapi3_parser/node_factories/path_item.rb +75 -0
  41. data/lib/openapi3_parser/node_factories/paths.rb +32 -0
  42. data/lib/openapi3_parser/node_factories/reference.rb +33 -0
  43. data/lib/openapi3_parser/node_factories/request_body.rb +31 -0
  44. data/lib/openapi3_parser/node_factories/response.rb +45 -0
  45. data/lib/openapi3_parser/node_factories/responses.rb +32 -0
  46. data/lib/openapi3_parser/node_factories/schema.rb +106 -0
  47. data/lib/openapi3_parser/node_factories/security_requirement.rb +25 -0
  48. data/lib/openapi3_parser/node_factories/security_scheme.rb +35 -0
  49. data/lib/openapi3_parser/node_factories/server.rb +32 -0
  50. data/lib/openapi3_parser/node_factories/server_variable.rb +28 -0
  51. data/lib/openapi3_parser/node_factories/tag.rb +24 -0
  52. data/lib/openapi3_parser/node_factories/xml.rb +25 -0
  53. data/lib/openapi3_parser/node_factory.rb +126 -0
  54. data/lib/openapi3_parser/node_factory/field_config.rb +88 -0
  55. data/lib/openapi3_parser/node_factory/map.rb +39 -0
  56. data/lib/openapi3_parser/node_factory/object.rb +80 -0
  57. data/lib/openapi3_parser/node_factory/object/node_builder.rb +85 -0
  58. data/lib/openapi3_parser/node_factory/object/validator.rb +102 -0
  59. data/lib/openapi3_parser/node_factory/optional_reference.rb +23 -0
  60. data/lib/openapi3_parser/nodes/array.rb +26 -0
  61. data/lib/openapi3_parser/nodes/callback.rb +11 -0
  62. data/lib/openapi3_parser/nodes/components.rb +47 -0
  63. data/lib/openapi3_parser/nodes/contact.rb +23 -0
  64. data/lib/openapi3_parser/nodes/discriminator.rb +19 -0
  65. data/lib/openapi3_parser/nodes/encoding.rb +31 -0
  66. data/lib/openapi3_parser/nodes/example.rb +27 -0
  67. data/lib/openapi3_parser/nodes/external_documentation.rb +19 -0
  68. data/lib/openapi3_parser/nodes/header.rb +13 -0
  69. data/lib/openapi3_parser/nodes/info.rb +35 -0
  70. data/lib/openapi3_parser/nodes/license.rb +19 -0
  71. data/lib/openapi3_parser/nodes/link.rb +35 -0
  72. data/lib/openapi3_parser/nodes/map.rb +11 -0
  73. data/lib/openapi3_parser/nodes/media_type.rb +27 -0
  74. data/lib/openapi3_parser/nodes/oauth_flow.rb +27 -0
  75. data/lib/openapi3_parser/nodes/oauth_flows.rb +27 -0
  76. data/lib/openapi3_parser/nodes/openapi.rb +44 -0
  77. data/lib/openapi3_parser/nodes/operation.rb +59 -0
  78. data/lib/openapi3_parser/nodes/parameter.rb +21 -0
  79. data/lib/openapi3_parser/nodes/parameter/parameter_like.rb +53 -0
  80. data/lib/openapi3_parser/nodes/path_item.rb +59 -0
  81. data/lib/openapi3_parser/nodes/paths.rb +11 -0
  82. data/lib/openapi3_parser/nodes/request_body.rb +23 -0
  83. data/lib/openapi3_parser/nodes/response.rb +27 -0
  84. data/lib/openapi3_parser/nodes/responses.rb +15 -0
  85. data/lib/openapi3_parser/nodes/schema.rb +159 -0
  86. data/lib/openapi3_parser/nodes/security_requirement.rb +11 -0
  87. data/lib/openapi3_parser/nodes/security_scheme.rb +44 -0
  88. data/lib/openapi3_parser/nodes/server.rb +25 -0
  89. data/lib/openapi3_parser/nodes/server_variable.rb +23 -0
  90. data/lib/openapi3_parser/nodes/tag.rb +23 -0
  91. data/lib/openapi3_parser/nodes/xml.rb +31 -0
  92. data/lib/openapi3_parser/validation/error.rb +14 -0
  93. data/lib/openapi3_parser/validation/error_collection.rb +36 -0
  94. data/lib/openapi3_parser/version.rb +5 -0
  95. data/openapi3_parser.gemspec +28 -0
  96. metadata +208 -0
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/info"
4
+ require "openapi3_parser/node_factories/license"
5
+ require "openapi3_parser/node_factories/contact"
6
+ require "openapi3_parser/node_factory/object"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class Info
11
+ include NodeFactory::Object
12
+
13
+ allow_extensions
14
+ field "title", input_type: String, required: true
15
+ field "description", input_type: String
16
+ field "termsOfService", input_type: String
17
+ field "contact", factory: Contact
18
+ field "license", factory: License
19
+ field "version", input_type: String, required: true
20
+
21
+ private
22
+
23
+ def build_object(data, context)
24
+ Nodes::Info.new(data, context)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/license"
4
+ require "openapi3_parser/node_factory/object"
5
+
6
+ module Openapi3Parser
7
+ module NodeFactories
8
+ class License
9
+ include NodeFactory::Object
10
+
11
+ allow_extensions
12
+ field "name", input_type: String, required: true
13
+ field "url", input_type: String
14
+
15
+ private
16
+
17
+ def build_object(data, context)
18
+ Nodes::License.new(data, context)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/license"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factories/map"
6
+ require "openapi3_parser/node_factories/server"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class Link
11
+ include NodeFactory::Object
12
+
13
+ allow_extensions
14
+
15
+ # @TODO The link object in OAS is pretty meaty and there's lot of scope
16
+ # for further work here to make use of it's funcationality
17
+
18
+ field "operationRef", input_type: String
19
+ field "operationId", input_type: String
20
+ field "parameters", factory: :parameters_factory
21
+ field "requestBody"
22
+ field "description", input_type: String
23
+ field "server", factory: :server_factory
24
+
25
+ private
26
+
27
+ def build_object(data, context)
28
+ Nodes::Link.new(data, context)
29
+ end
30
+
31
+ def parameters_factory(context)
32
+ NodeFactories::Map.new(context)
33
+ end
34
+
35
+ def server_factory(context)
36
+ NodeFactories::Server.new(context)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/node_factory/map"
4
+ require "openapi3_parser/nodes/map"
5
+ require "openapi3_parser/validation/error"
6
+
7
+ module Openapi3Parser
8
+ module NodeFactories
9
+ class Map
10
+ include NodeFactory::Map
11
+
12
+ def initialize(
13
+ context,
14
+ key_input_type: String,
15
+ value_input_type: nil,
16
+ value_factory: nil,
17
+ validate: nil
18
+ )
19
+ super(context)
20
+ @given_key_input_type = key_input_type
21
+ @given_value_input_type = value_input_type
22
+ @given_value_factory = value_factory
23
+ @given_validate = validate
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :given_key_input_type, :given_value_input_type,
29
+ :given_value_factory, :given_validate
30
+
31
+ def process_input(input)
32
+ input.each_with_object({}) do |(key, value), memo|
33
+ memo[key] = if value_factory?
34
+ initialize_value_factory(context.next_namespace(key))
35
+ else
36
+ value
37
+ end
38
+ end
39
+ end
40
+
41
+ def validate_type
42
+ error = super
43
+ return error if error
44
+ return unless given_key_input_type
45
+ invalid_keys = context.input.keys.reject do |key|
46
+ key.is_a?(given_key_input_type)
47
+ end
48
+ error = "Expected keys to be of type #{given_key_input_type}"
49
+ return error if invalid_keys.any?
50
+ end
51
+
52
+ def validate(input, context)
53
+ given_validate&.call(input, context)
54
+ end
55
+
56
+ def validate_input(error_collection)
57
+ super(error_collection)
58
+ error_collection.merge(
59
+ validate_value_input_type(processed_input, context)
60
+ )
61
+ end
62
+
63
+ def build_node(input)
64
+ check_value_input_type(input)
65
+ super(input)
66
+ end
67
+
68
+ def build_map(data, context)
69
+ Nodes::Map.new(data, context)
70
+ end
71
+
72
+ def value_factory?
73
+ !given_value_factory.nil?
74
+ end
75
+
76
+ def initialize_value_factory(context)
77
+ factory = given_value_factory
78
+ return factory.new(context) if factory.is_a?(Class)
79
+ factory.call(context)
80
+ end
81
+
82
+ def validate_value_input_type(input, context)
83
+ input.each_with_object([]) do |(key, value), memo|
84
+ error = error_for_value_input_type(value)
85
+ next unless error
86
+ memo << Validation::Error.new(
87
+ context.next_namespace(key), error
88
+ )
89
+ end
90
+ end
91
+
92
+ def check_value_input_type(input)
93
+ input.each do |key, value|
94
+ error = error_for_value_input_type(value)
95
+ next unless error
96
+ next_context = context.next_namespace(key)
97
+ raise Openapi3Parser::Error,
98
+ "Invalid type for #{next_context.stringify_namespace}. "\
99
+ "#{error}"
100
+ end
101
+ end
102
+
103
+ def error_for_value_input_type(value)
104
+ type = given_value_input_type
105
+ return unless type
106
+ "Expected #{type}" unless value.is_a?(type)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/media_type"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factory/optional_reference"
6
+ require "openapi3_parser/node_factories/map"
7
+ require "openapi3_parser/node_factories/schema"
8
+ require "openapi3_parser/node_factories/example"
9
+ require "openapi3_parser/node_factories/encoding"
10
+
11
+ module Openapi3Parser
12
+ module NodeFactories
13
+ class MediaType
14
+ include NodeFactory::Object
15
+
16
+ allow_extensions
17
+ field "schema", factory: :schema_factory
18
+ field "example"
19
+ field "examples", factory: :examples_factory
20
+ field "encoding", factory: :encoding_factory
21
+
22
+ private
23
+
24
+ def build_object(data, context)
25
+ Nodes::MediaType.new(data, context)
26
+ end
27
+
28
+ def schema_factory(context)
29
+ factory = NodeFactories::Schema
30
+ NodeFactory::OptionalReference.new(factory).call(context)
31
+ end
32
+
33
+ def examples_factory(context)
34
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Example)
35
+ NodeFactories::Map.new(context, value_factory: factory)
36
+ end
37
+
38
+ def encoding_factory(context)
39
+ factory = NodeFactories::Encoding
40
+ NodeFactories::Map.new(context, value_factory: factory)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/oauth_flow"
4
+ require "openapi3_parser/node_factory/object"
5
+
6
+ module Openapi3Parser
7
+ module NodeFactories
8
+ class OauthFlow
9
+ include NodeFactory::Object
10
+
11
+ allow_extensions
12
+ field "authorizationUrl", input_type: String
13
+ field "tokenUrl", input_type: String
14
+ field "refreshUrl", input_type: String
15
+ field "scopes", input_type: Hash
16
+
17
+ private
18
+
19
+ def build_object(data, context)
20
+ Nodes::OauthFlow.new(data, context)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/oauth_flows"
4
+ require "openapi3_parser/node_factories/oauth_flow"
5
+ require "openapi3_parser/node_factory/object"
6
+ require "openapi3_parser/node_factory/optional_reference"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class OauthFlows
11
+ include NodeFactory::Object
12
+
13
+ allow_extensions
14
+ field "implicit", factory: :oauth_flow_factory
15
+ field "password", factory: :oauth_flow_factory
16
+ field "clientCredentials", factory: :oauth_flow_factory
17
+ field "authorizationCode", factory: :oauth_flow_factory
18
+
19
+ private
20
+
21
+ def oauth_flow_factory(context)
22
+ NodeFactory::OptionalReference.new(NodeFactories::OauthFlow)
23
+ .call(context)
24
+ end
25
+
26
+ def build_object(data, context)
27
+ Nodes::OauthFlows.new(data, context)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/openapi"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factories/info"
6
+ require "openapi3_parser/node_factories/array"
7
+ require "openapi3_parser/node_factories/server"
8
+ require "openapi3_parser/node_factories/paths"
9
+ require "openapi3_parser/node_factories/components"
10
+ require "openapi3_parser/node_factories/security_requirement"
11
+ require "openapi3_parser/node_factories/tag"
12
+ require "openapi3_parser/node_factories/external_documentation"
13
+
14
+ module Openapi3Parser
15
+ module NodeFactories
16
+ class Openapi
17
+ include NodeFactory::Object
18
+
19
+ allow_extensions
20
+ field "openapi", input_type: String, required: true
21
+ field "info", factory: NodeFactories::Info, required: true
22
+ field "servers", factory: :servers_factory
23
+ field "paths", factory: NodeFactories::Paths, required: true
24
+ field "components", factory: NodeFactories::Components
25
+ field "security", factory: :security_factory
26
+ field "tags", factory: :tags_factory
27
+ field "externalDocs", factory: NodeFactories::ExternalDocumentation
28
+
29
+ private
30
+
31
+ def build_object(data, context)
32
+ Nodes::Openapi.new(data, context)
33
+ end
34
+
35
+ def servers_factory(context)
36
+ NodeFactories::Array.new(context, value_factory: NodeFactories::Server)
37
+ end
38
+
39
+ def security_factory(context)
40
+ NodeFactories::Array.new(
41
+ context, value_factory: NodeFactories::SecurityRequirement
42
+ )
43
+ end
44
+
45
+ def tags_factory(context)
46
+ NodeFactories::Array.new(context, value_factory: NodeFactories::Tag)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/operation"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factory/optional_reference"
6
+ require "openapi3_parser/node_factories/array"
7
+ require "openapi3_parser/node_factories/external_documentation"
8
+ require "openapi3_parser/node_factories/parameter"
9
+ require "openapi3_parser/node_factories/request_body"
10
+ require "openapi3_parser/node_factories/responses"
11
+ require "openapi3_parser/node_factories/callback"
12
+ require "openapi3_parser/node_factories/server"
13
+ require "openapi3_parser/node_factories/security_requirement"
14
+
15
+ module Openapi3Parser
16
+ module NodeFactories
17
+ class Operation
18
+ include NodeFactory::Object
19
+
20
+ allow_extensions
21
+ field "tags", factory: :tags_factory
22
+ field "summary", input_type: String
23
+ field "description", input_type: String
24
+ field "externalDocs", factory: NodeFactories::ExternalDocumentation
25
+ field "operationId", input_type: String
26
+ field "parameters", factory: :parameters_factory
27
+ field "requestBody", factory: :request_body_factory
28
+ field "responses", factory: NodeFactories::Responses,
29
+ required: true
30
+ field "callbacks", factory: :callbacks_factory
31
+ field "deprecated", input_type: :boolean, default: false
32
+ field "security", factory: :security_factory
33
+ field "servers", factory: :servers_factory
34
+
35
+ private
36
+
37
+ def build_object(data, context)
38
+ Nodes::Operation.new(data, context)
39
+ end
40
+
41
+ def tags_factory(context)
42
+ NodeFactories::Array.new(context, value_input_type: String)
43
+ end
44
+
45
+ def parameters_factory(context)
46
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Parameter)
47
+ NodeFactories::Array.new(context, value_factory: factory)
48
+ end
49
+
50
+ def request_body_factory(context)
51
+ factory = NodeFactories::RequestBody
52
+ NodeFactory::OptionalReference.new(factory).call(context)
53
+ end
54
+
55
+ def callbacks_factory(context)
56
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Callback)
57
+ NodeFactories::Map.new(context, value_factory: factory)
58
+ end
59
+
60
+ def responses_factory(context)
61
+ factory = NodeFactories::RequestBody
62
+ NodeFactory::OptionalReference.new(factory).call(context)
63
+ end
64
+
65
+ def security_factory(context)
66
+ NodeFactories::Array.new(
67
+ context, value_factory: NodeFactories::SecurityRequirement
68
+ )
69
+ end
70
+
71
+ def servers_factory(context)
72
+ NodeFactories::Array.new(context, value_factory: NodeFactories::Server)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/parameter"
4
+ require "openapi3_parser/node_factories/parameter/parameter_like"
5
+ require "openapi3_parser/node_factory/object"
6
+
7
+ module Openapi3Parser
8
+ module NodeFactories
9
+ class Parameter
10
+ include NodeFactory::Object
11
+ include Parameter::ParameterLike
12
+
13
+ allow_extensions
14
+
15
+ field "name", input_type: String, required: true
16
+ field "in", input_type: String, required: true
17
+ field "description", input_type: String
18
+ field "required", input_type: :boolean, default: false
19
+ field "deprecated", input_type: :boolean, default: false
20
+ field "allowEmptyValue", input_type: :boolean, default: false
21
+
22
+ field "style", input_type: String, default: :default_style
23
+ field "explode", input_type: :boolean, default: :default_explode
24
+ field "allowReserved", input_type: :boolean, default: false
25
+ field "schema", factory: :schema_factory
26
+ field "example"
27
+ field "examples", factory: :examples_factory
28
+
29
+ field "content", factory: :content_factory
30
+
31
+ private
32
+
33
+ def build_object(data, context)
34
+ Nodes::Parameter.new(data, context)
35
+ end
36
+
37
+ def default_style
38
+ return "simple" if %w[path header].include?(context.input["in"])
39
+ "form"
40
+ end
41
+ end
42
+ end
43
+ end