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,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Openapi3Parser
4
+ module NodeFactories
5
+ class Parameter
6
+ module ParameterLike
7
+ def default_explode
8
+ context.input["style"] == "form"
9
+ end
10
+
11
+ def schema_factory(context)
12
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Schema)
13
+ factory.call(context)
14
+ end
15
+
16
+ def examples_factory(context)
17
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Schema)
18
+ NodeFactories::Map.new(context, value_factory: factory)
19
+ end
20
+
21
+ def content_factory(context)
22
+ factory = NodeFactory::OptionalReference.new(
23
+ NodeFactories::MediaType
24
+ )
25
+ NodeFactories::Map.new(context, value_factory: factory)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ # These are in the footer as a cyclic dependency can stop this module loading
33
+ require "openapi3_parser/node_factory/optional_reference"
34
+ require "openapi3_parser/node_factories/schema"
35
+ require "openapi3_parser/node_factories/map"
36
+ require "openapi3_parser/node_factories/example"
37
+ require "openapi3_parser/node_factories/media_type"
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/path_item"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factory/object/node_builder"
6
+ require "openapi3_parser/node_factory/optional_reference"
7
+ require "openapi3_parser/node_factories/array"
8
+ require "openapi3_parser/node_factories/server"
9
+ require "openapi3_parser/node_factories/operation"
10
+ require "openapi3_parser/node_factories/parameter"
11
+
12
+ module Openapi3Parser
13
+ module NodeFactories
14
+ class PathItem
15
+ include NodeFactory::Object
16
+
17
+ allow_extensions
18
+ field "$ref", input_type: String
19
+ field "summary", input_type: String
20
+ field "description", input_type: String
21
+ field "get", factory: :operation_factory
22
+ field "put", factory: :operation_factory
23
+ field "post", factory: :operation_factory
24
+ field "delete", factory: :operation_factory
25
+ field "options", factory: :operation_factory
26
+ field "head", factory: :operation_factory
27
+ field "patch", factory: :operation_factory
28
+ field "trace", factory: :operation_factory
29
+ field "servers", factory: :servers_factory
30
+ field "parameters", factory: :parameters_factory
31
+
32
+ def node_data
33
+ NodeBuilder.new(processed_input, self).data
34
+ end
35
+
36
+ private
37
+
38
+ def build_object(data, context)
39
+ merged_data = merge_reference(data, context)
40
+ merged_data.delete("$ref")
41
+ Nodes::PathItem.new(merged_data, context)
42
+ end
43
+
44
+ def operation_factory(context)
45
+ NodeFactories::Operation.new(context)
46
+ end
47
+
48
+ def servers_factory(context)
49
+ NodeFactories::Array.new(
50
+ context,
51
+ value_factory: NodeFactories::Server
52
+ )
53
+ end
54
+
55
+ def parameters_factory(context)
56
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Parameter)
57
+ NodeFactories::Array.new(context, value_factory: factory)
58
+ end
59
+
60
+ def merge_reference(data, context)
61
+ return data unless data["$ref"]
62
+ factory = context.resolve_reference do |ref_context|
63
+ self.class.new(ref_context)
64
+ end
65
+
66
+ # @TODO In this situation we're basically sacrificing the reference
67
+ # context as we don't know how to merge them. Should develop a system
68
+ # to have a dual context
69
+ factory.node_data.merge(data) do |_, new, old|
70
+ new.nil? ? old : new
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/node_factory/map"
4
+ require "openapi3_parser/node_factory/optional_reference"
5
+ require "openapi3_parser/node_factories/path_item"
6
+ require "openapi3_parser/nodes/paths"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class Paths
11
+ include NodeFactory::Map
12
+
13
+ private
14
+
15
+ def process_input(input)
16
+ input.each_with_object({}) do |(key, value), memo|
17
+ memo[key] = value if extension?(key)
18
+ memo[key] = child_factory(context.next_namespace(key))
19
+ end
20
+ end
21
+
22
+ def child_factory(child_context)
23
+ NodeFactory::OptionalReference.new(NodeFactories::PathItem)
24
+ .call(child_context)
25
+ end
26
+
27
+ def build_map(data, context)
28
+ Nodes::Paths.new(data, context)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/node_factory/object"
4
+
5
+ module Openapi3Parser
6
+ module NodeFactories
7
+ class Reference
8
+ include NodeFactory::Object
9
+
10
+ field "$ref", input_type: String, required: true
11
+
12
+ attr_reader :factory
13
+
14
+ def initialize(context, factory)
15
+ super(context)
16
+ @factory = factory
17
+ end
18
+
19
+ private
20
+
21
+ def build_object(_, context)
22
+ context.resolve_reference do |ref_context|
23
+ resolve_factory(ref_context).node
24
+ end
25
+ end
26
+
27
+ def resolve_factory(ref_context)
28
+ return factory.new(ref_context) if factory.is_a?(Class)
29
+ factory.call(ref_context)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/request_body"
4
+ require "openapi3_parser/node_factory/object"
5
+ require "openapi3_parser/node_factories/media_type"
6
+ require "openapi3_parser/node_factories/map"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class RequestBody
11
+ include NodeFactory::Object
12
+
13
+ allow_extensions
14
+ field "description", input_type: String
15
+ field "content", factory: :content_factory, required: true
16
+ field "required", input_type: :boolean, default: false
17
+
18
+ private
19
+
20
+ def build_object(data, context)
21
+ Nodes::RequestBody.new(data, context)
22
+ end
23
+
24
+ def content_factory(context)
25
+ NodeFactories::Map.new(
26
+ context, value_factory: NodeFactories::MediaType
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/response"
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/header"
8
+ require "openapi3_parser/node_factories/media_type"
9
+ require "openapi3_parser/node_factories/link"
10
+
11
+ module Openapi3Parser
12
+ module NodeFactories
13
+ class Response
14
+ include NodeFactory::Object
15
+
16
+ allow_extensions
17
+ field "description", input_type: String, required: true
18
+ field "headers", factory: :headers_factory
19
+ field "content", factory: :content_factory
20
+ field "links", factory: :links_factory
21
+
22
+ private
23
+
24
+ def build_object(data, context)
25
+ Nodes::Response.new(data, context)
26
+ end
27
+
28
+ def headers_factory(context)
29
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Header)
30
+ NodeFactories::Map.new(context, value_factory: factory)
31
+ end
32
+
33
+ def content_factory(context)
34
+ NodeFactories::Map.new(
35
+ context, value_factory: NodeFactories::MediaType
36
+ )
37
+ end
38
+
39
+ def links_factory(context)
40
+ factory = NodeFactory::OptionalReference.new(NodeFactories::Link)
41
+ NodeFactories::Map.new(context, value_factory: factory)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/node_factory/map"
4
+ require "openapi3_parser/node_factory/optional_reference"
5
+ require "openapi3_parser/nodes/responses"
6
+ require "openapi3_parser/node_factories/response"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class Responses
11
+ include NodeFactory::Map
12
+
13
+ private
14
+
15
+ def process_input(input)
16
+ input.each_with_object({}) do |(key, value), memo|
17
+ memo[key] = value if extension?(key)
18
+ memo[key] = child_factory(context.next_namespace(key))
19
+ end
20
+ end
21
+
22
+ def child_factory(child_context)
23
+ NodeFactory::OptionalReference.new(NodeFactories::Response)
24
+ .call(child_context)
25
+ end
26
+
27
+ def build_map(data, context)
28
+ Nodes::Responses.new(data, context)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/schema"
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/array"
8
+ require "openapi3_parser/node_factories/external_documentation"
9
+ require "openapi3_parser/node_factories/discriminator"
10
+ require "openapi3_parser/node_factories/xml"
11
+
12
+ module Openapi3Parser
13
+ module NodeFactories
14
+ class Schema
15
+ include NodeFactory::Object
16
+
17
+ allow_extensions
18
+ field "title", input_type: String
19
+ field "multipleOf", input_type: Numeric
20
+ field "maximum", input_type: Integer
21
+ field "exclusiveMaximum", input_type: :boolean, default: false
22
+ field "minimum", input_type: Integer
23
+ field "exclusiveMinimum", input_type: :boolean, default: false
24
+ field "maxLength", input_type: Integer
25
+ field "minLength", input_type: Integer, default: 0
26
+ field :pattern, input_type: String
27
+ field "maxItems", input_type: Integer
28
+ field "minItems", input_type: Integer, default: 0
29
+ field "uniqueItems", input_type: :boolean, default: false
30
+ field "maxProperties", input_type: Integer
31
+ field "minProperties", input_type: Integer, default: 0
32
+ field "required", input_type: ::Array
33
+ field "enum", input_type: ::Array
34
+
35
+ field "type", input_type: String
36
+ field "allOf", factory: :referenceable_schema_array
37
+ field "oneOf", factory: :referenceable_schema_array
38
+ field "anyOf", factory: :referenceable_schema_array
39
+ field "not", factory: :referenceable_schema
40
+ field "items", factory: :referenceable_schema
41
+ field "properties", factory: :properties_factory
42
+ field "additionalProperties",
43
+ input_type: :additional_properties_input_type,
44
+ factory: :additional_properties_factory,
45
+ default: false
46
+ field "description", input_type: String
47
+ field "format", input_type: String
48
+ field "default"
49
+
50
+ field "nullable", input_type: :boolean, default: false
51
+ field "discriminator", factory: :disciminator_factory
52
+ field "readOnly", input_type: :boolean, default: false
53
+ field "writeOnly", input_type: :boolean, default: false
54
+ field "xml", factory: :xml_factory
55
+ field "externalDocs", factory: :external_docs_factory
56
+ field "example"
57
+ field "deprecated", input_type: :boolean, default: false
58
+
59
+ private
60
+
61
+ def build_object(data, context)
62
+ Nodes::Schema.new(data, context)
63
+ end
64
+
65
+ def disciminator_factory(context)
66
+ NodeFactories::Discriminator.new(context)
67
+ end
68
+
69
+ def xml_factory(context)
70
+ NodeFactories::Xml.new(context)
71
+ end
72
+
73
+ def external_docs_factory(context)
74
+ NodeFactories::ExternalDocumentation.new(context)
75
+ end
76
+
77
+ def properties_factory(context)
78
+ NodeFactories::Map.new(
79
+ context,
80
+ value_factory: NodeFactories::Schema
81
+ )
82
+ end
83
+
84
+ def referenceable_schema(context)
85
+ NodeFactory::OptionalReference.new(self.class).call(context)
86
+ end
87
+
88
+ def referenceable_schema_array(context)
89
+ NodeFactories::Array.new(
90
+ context,
91
+ value_factory: NodeFactory::OptionalReference.new(self.class)
92
+ )
93
+ end
94
+
95
+ def additional_properties_input_type(input)
96
+ return if [true, false].include?(input) || input.is_a?(Hash)
97
+ "Expected a boolean or an object"
98
+ end
99
+
100
+ def additional_properties_factory(context)
101
+ return context.input if [true, false].include?(context.input)
102
+ referenceable_schema(context)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/security_requirement"
4
+ require "openapi3_parser/node_factory/map"
5
+ require "openapi3_parser/node_factories/array"
6
+
7
+ module Openapi3Parser
8
+ module NodeFactories
9
+ class SecurityRequirement
10
+ include NodeFactory::Map
11
+
12
+ private
13
+
14
+ def process_input(input)
15
+ input.keys.each_with_object({}) do |key, memo|
16
+ memo[key] = NodeFactories::Array.new(context.next_namespace(key))
17
+ end
18
+ end
19
+
20
+ def build_map(data, context)
21
+ Nodes::SecurityRequirement.new(data, context)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openapi3_parser/nodes/security_scheme"
4
+ require "openapi3_parser/node_factories/oauth_flows"
5
+ require "openapi3_parser/node_factory/object"
6
+ require "openapi3_parser/node_factory/optional_reference"
7
+
8
+ module Openapi3Parser
9
+ module NodeFactories
10
+ class SecurityScheme
11
+ include NodeFactory::Object
12
+
13
+ allow_extensions
14
+
15
+ field "type", input_type: String, required: true
16
+ field "description", input_type: String
17
+ field "name", input_type: String
18
+ field "in", input_type: String
19
+ field "scheme", input_type: String
20
+ field "bearerFormat", input_type: String
21
+ field "flows", factory: :flows_factory
22
+ field "openIdConnectUrl", input_type: String
23
+
24
+ private
25
+
26
+ def build_object(data, context)
27
+ Nodes::SecurityScheme.new(data, context)
28
+ end
29
+
30
+ def flows_factory(context)
31
+ NodeFactories::OauthFlows.new(context)
32
+ end
33
+ end
34
+ end
35
+ end