openapi3_parser 0.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.
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