swagger-parser 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +23 -0
  6. data/.travis.yml +6 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +5 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +114 -0
  11. data/Rakefile +11 -0
  12. data/lib/swagger.rb +56 -0
  13. data/lib/swagger/api.rb +26 -0
  14. data/lib/swagger/attachable.rb +39 -0
  15. data/lib/swagger/boolean.rb +13 -0
  16. data/lib/swagger/builder.rb +109 -0
  17. data/lib/swagger/mime_type.rb +46 -0
  18. data/lib/swagger/notes.md +35 -0
  19. data/lib/swagger/parsers.rb +36 -0
  20. data/lib/swagger/schema.rb +63 -0
  21. data/lib/swagger/swagger_object.rb +49 -0
  22. data/lib/swagger/uri.rb +11 -0
  23. data/lib/swagger/uri_template.rb +11 -0
  24. data/lib/swagger/v2/api.rb +90 -0
  25. data/lib/swagger/v2/deterministic_json_schema.rb +130 -0
  26. data/lib/swagger/v2/example.rb +32 -0
  27. data/lib/swagger/v2/header.rb +22 -0
  28. data/lib/swagger/v2/info.rb +33 -0
  29. data/lib/swagger/v2/operation.rb +66 -0
  30. data/lib/swagger/v2/parameter.rb +35 -0
  31. data/lib/swagger/v2/path.rb +47 -0
  32. data/lib/swagger/v2/response.rb +26 -0
  33. data/lib/swagger/v2/security_requirement.rb +12 -0
  34. data/lib/swagger/v2/security_scheme.rb +25 -0
  35. data/lib/swagger/v2/tag.rb +11 -0
  36. data/lib/swagger/version.rb +3 -0
  37. data/resources/schemas/json_schema/draft-04.json +150 -0
  38. data/resources/schemas/swagger/v2.0/schema.json +1483 -0
  39. data/spec/fixtures/custom-properties.yaml +61 -0
  40. data/spec/fixtures/petstore-full.yaml +245 -0
  41. data/spec/fixtures/swagger.yaml +100 -0
  42. data/spec/spec_helper.rb +2 -0
  43. data/spec/swagger/api_spec.rb +87 -0
  44. data/spec/swagger/builder_spec.rb +52 -0
  45. data/spec/swagger/custom_properties_spec.rb +22 -0
  46. data/spec/swagger/info_spec.rb +76 -0
  47. data/spec/swagger/operation_spec.rb +99 -0
  48. data/spec/swagger/swagger_spec.rb +74 -0
  49. data/swagger-parser.gemspec +32 -0
  50. metadata +250 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 740d876af96ebfcc2ccbf08644e6d7ea1935911a
4
+ data.tar.gz: 4a01f87d82ac5fca6fdc3390450e2a03a6fddc6b
5
+ SHA512:
6
+ metadata.gz: 51f6dc4a18985c3cef69c51b79eb37f8519a6cba754bb9e2b0568523adace5deec94c98d870a1058336131b13ea1f0dbdede5d647457feaba2818196314dfda0
7
+ data.tar.gz: ec70831ccdb90fbaeb49ced11a4a80862b19371d0d87676de2835e38f79c9b2b5512ad582b4ddbe04a439d0cfc9a9d6bfb029728f412b7c1ddabbb05394ff4a4
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.swp
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "swagger_spec"]
2
+ path = swagger_spec
3
+ url = https://github.com/wordnik/swagger-spec
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,23 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-08-05 12:05:37 -0400 using RuboCop version 0.24.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Not yet...
9
+ Style/Documentation:
10
+ # See https://github.com/bbatsov/rubocop/issues/947
11
+ # Use inch instead
12
+ Enabled: false
13
+ Style/Encoding:
14
+ EnforcedStyle: when_needed
15
+
16
+ Metrics/LineLength:
17
+ Max: 120
18
+ Metrics/MethodLength:
19
+ Max: 15
20
+
21
+ AllCops:
22
+ Exclude:
23
+ - 'swagger_spec/**/*'
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - jruby
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ lib/swagger/definition_section.rb
3
+ lib/swagger.rb
4
+ lib/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in swagger.gemspec
4
+ gemspec
5
+ gem 'pry'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Max Lincoln
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # Swagger
2
+
3
+ This is a fork of (swagger-rb)[https://github.com/swagger-rb/swagger-rb]. I've renamed the repo and pushed it to ruby-gems because it seems like the other repo is no longer maintained.
4
+
5
+ Swagger is a Ruby library for parsing, building, and traversing (Swagger)[http://swagger.io/] API definitions.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'swagger-parser'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install swagger-parser
22
+
23
+ ## Features
24
+
25
+ - Structural and semantic validation of Swagger objects
26
+ - Convenient traversal APIs: use hierarchical or flat traversals
27
+ - Handles derived or combined properties, like joining root, path, and operation level property definitions
28
+ - A Swagger::Builder to help create valid Swagger documents from other data
29
+
30
+ ## Usage
31
+
32
+ ### Parsing
33
+
34
+ If you're loading a Swagger document from a file, you can use `#load`. The Swagger version will be detected from the file content.
35
+
36
+ ```ruby
37
+ api = Swagger.load('swagger.yaml')
38
+ ```
39
+
40
+ If you already have the Swagger content loaded as a Hash you can call build, or you can call
41
+ build and tell Swagger the content is a JSON or YAML string it needs to parse.
42
+
43
+ ```ruby
44
+ api = Swagger.build(hash)
45
+ # or
46
+ api = Swagger.build(json, format: :json)
47
+ # or
48
+ api = Swagger.build(yaml, format: :yaml)
49
+ ```
50
+
51
+ ### Traversing
52
+
53
+ The parsing methods above all return an API object. The object has a hierarchical object that mirrors the Swagger specification. You can traverse it hierarchically, for example:
54
+
55
+ ```ruby
56
+ api.paths['/pets'].get
57
+ # {"tags"=>["Pet Operations"],
58
+ # "summary"=>"finds pets in the system",
59
+ # "responses"=>
60
+ {"200"=>{"description"=>"pet response", "schema"=>{"type"=>"array", "items"=>{"$ref"=>"#/definitions/Pet"}}, "headers"=>[{"x-expires"=>{"type"=>"string"}}]},
61
+ "default"=>{"description"=>"unexpected error", "schema"=>{"$ref"=>"#/definitions/Error"}}}}
62
+ ```
63
+
64
+ There are also methods available to provide flatter APIs or convenient derived properties. For example:
65
+
66
+ ```ruby
67
+ api.operations.each do | operation |
68
+ puts operation.signature
69
+ end
70
+ # GET petstore.swagger.wordnik.com/api/pets
71
+ # POST petstore.swagger.wordnik.com/api/pets
72
+ # GET petstore.swagger.wordnik.com/api/pets/{id}
73
+ # DELETE petstore.swagger.wordnik.com/api/pets/{id}
74
+ ```
75
+
76
+ See the RDoc documentation for more details.
77
+
78
+ ### Building
79
+
80
+ If you want to build a Swagger document from another structure, you can use the builder. It will validate the structure and data types as you build the Swagger document, but it won't enforce constraints about required Swagger fields until you call `Swagger::Builder#build`.
81
+
82
+ ```ruby
83
+ builder = Swagger.builder
84
+ # or builder = Swagger.builder(version: '2.0')
85
+
86
+ builder.swagger = 2.0
87
+ builder.info do |info|
88
+ info.title = 'Sample Swagger API'
89
+ info.version = '1.0'
90
+ end
91
+ builder.paths = {
92
+ '/foo' => {}
93
+ }
94
+ builder.paths['/foo'].get do |get|
95
+ get.description = 'Testing...'
96
+ get.tags = %w(foo bar)
97
+ end
98
+
99
+ api = builder.build
100
+ ```
101
+
102
+ ## TODO
103
+
104
+ * Support Swagger 1.2 - right now only Swagger 2.0 is supported
105
+ * Better handling of $ref
106
+ * Handle combined parameters, respones, etc
107
+
108
+ ## Contributing
109
+
110
+ 1. Fork it ( https://github.com/[my-github-username]/swagger/fork )
111
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
112
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
113
+ 4. Push to the branch (`git push origin my-new-feature`)
114
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+ require 'rake/notes/rake_task'
5
+ require 'inch/rake'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+ Inch::Rake::Suggest.new
10
+
11
+ task default: [:spec, :rubocop, :notes]
data/lib/swagger.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'addressable/uri'
2
+ require 'addressable/template'
3
+ require 'forwardable'
4
+ require 'hashie'
5
+ require 'swagger/version'
6
+ require 'swagger/boolean'
7
+
8
+ # Provides loading and building capabilities for Swagger.
9
+ # @see http://swagger.io Swagger
10
+ module Swagger
11
+ RESOURCES_DIR = File.expand_path '../../resources/', __FILE__
12
+ class InvalidDefinition < StandardError
13
+ def initialize(errors)
14
+ @errors = errors
15
+ super("The Swagger definition is invalid. The following errors were detected: #{errors.inspect}")
16
+ end
17
+ end
18
+ # Instantiates a Swagger::API from the content.
19
+ # @param [Hash] opts the build options
20
+ # @option opts [String] :version the target Swagger specification version
21
+ # @returns [API]
22
+ def self.build(content, opts = {})
23
+ parser ||= Swagger::Parsers.parser_for(opts[:format])
24
+ content = parser.parse(content) unless parser.nil?
25
+ Swagger::API.build_api(content)
26
+ end
27
+
28
+ # Load a Swagger document from a file.
29
+ # @param [Hash] opts the load options
30
+ # @option opts [String] :format the format (yaml or json). Detected by file extension if omitted.
31
+ # @returns [API] a Swagger API object
32
+ def self.load(file, opts = {})
33
+ ext = File.extname file
34
+ opts[:format] = ext
35
+ content = File.read(file)
36
+ build(content, opts)
37
+ end
38
+
39
+ # Creates a Swagger::Builder that can be used to create a Swagger document.
40
+ # @param [Hash] opts the build options
41
+ # @option opts [String] :version the target Swagger specification version
42
+ # @returns Swagger::Builder
43
+ def self.builder(opts = {})
44
+ Swagger::Builder.builder(opts)
45
+ end
46
+ end
47
+
48
+ require 'swagger/attachable'
49
+ require 'swagger/swagger_object'
50
+ require 'swagger/schema'
51
+ require 'swagger/uri'
52
+ require 'swagger/uri_template'
53
+ require 'swagger/parsers'
54
+ require 'swagger/mime_type'
55
+ require 'swagger/api'
56
+ require 'swagger/builder'
@@ -0,0 +1,26 @@
1
+ module Swagger
2
+ # A common interface for building or loading Swagger documents of any version. See subclasses.
3
+ class API < SwaggerObject
4
+ def self.build_api(hash)
5
+ version = hash['swaggerVersion'] || hash['swagger']
6
+ major, _minor = version.to_s.split('.')
7
+ case major
8
+ when '2'
9
+ Swagger::V2::API.new hash
10
+ else
11
+ fail ArgumentError, "Swagger version #{version} is not currently supported"
12
+ end
13
+ end
14
+
15
+ def initialize(hash)
16
+ @vendor_extensions = {}
17
+ hash.each do |k, v|
18
+ @vendor_extensions[k] = v if k.to_s.start_with? 'x-'
19
+ end
20
+ # HACK: There's got to be a better way, but Dash wasn't working well with strings
21
+ super(Hashie::Mash.new(hash).to_hash(symbolize_keys: true))
22
+ end
23
+ end
24
+ end
25
+
26
+ require 'swagger/v2/api'
@@ -0,0 +1,39 @@
1
+ module Swagger
2
+ # A module that attaches parent objects to their children so you can navigate back
3
+ # up the hierarchy.
4
+ module Attachable
5
+ # The top-level object in the hierarchy.
6
+ attr_accessor :children
7
+ def root
8
+ return self if parent.nil?
9
+ parent.root
10
+ end
11
+
12
+ # @api private
13
+ def attach_parent(parent)
14
+ @parent = parent
15
+ attach_to_children
16
+ end
17
+
18
+ # @api private
19
+ def attach_to_children
20
+ @children ||= []
21
+ each_value do |v| # rubocop:disable Style/Next
22
+ if v.respond_to? :attach_parent
23
+ v.attach_parent self
24
+ self.children << v
25
+ end
26
+ if v.respond_to? :each_value
27
+ v.each_value do |sv|
28
+ sv.attach_parent self if sv.respond_to? :attach_parent
29
+ end
30
+ end
31
+ if v.respond_to? :each
32
+ v.each do |sv|
33
+ sv.attach_parent self if sv.respond_to? :attach_parent
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module Swagger
2
+ class Boolean
3
+ TRUE_REGEXP = /(y|Y|yes|Yes|YES|true|True|TRUE|on|On|ON)/
4
+ FALSE_REGEXP = /(n|N|no|No|NO|false|False|FALSE|off|Off|OFF)/
5
+
6
+ def self.coerce(obj)
7
+ val = obj.to_s.downcase
8
+ return true if val.match(TRUE_REGEXP)
9
+ return false if val.match(FALSE_REGEXP)
10
+ fail ArgumentError, "#{obj} cannot be coerced to a boolean"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,109 @@
1
+ module Swagger
2
+ # A Bash is a 'builder' Hash that can be used to be a
3
+ # Dash ('defined' or 'discrete' Hash). It provides a
4
+ # build method that turns it into a Dash. It enforces
5
+ # the same rules as a Dash except for 'required' properties,
6
+ # which are not enforced until converting to a Dash via `build`.
7
+ module Bash
8
+ # @api private
9
+ module ClassMethods
10
+ def self.extend_object(dash)
11
+ fail TypeError, 'Bash only works on Dash' unless dash <= Hashie::Dash
12
+ dash.instance_variable_get('@required_properties').clear
13
+ dash.coerce_value Hashie::Dash, Swagger::Bash, strict: false
14
+ end
15
+
16
+ def required?(_name)
17
+ false
18
+ end
19
+ end
20
+
21
+ # @api private
22
+ def self.included(dash) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
23
+ fail TypeError, 'Bash only works on Dash' unless dash <= Hashie::Dash
24
+ dash.extend ClassMethods
25
+ dash.instance_variable_get('@required_properties').clear
26
+
27
+ # Very hacky... copy instance_variables for coercions
28
+ base_dash = dash.superclass
29
+ [:@properties, :@defaults].each do |property|
30
+ dash.instance_variable_set(property, base_dash.instance_variable_get(property))
31
+ end
32
+
33
+ [:@key_coercions, :@value_coercions].each do |property|
34
+ coercions = base_dash.instance_variable_get(property)
35
+ coercions.each_pair do |key, into|
36
+ infect_class coercions, key, into
37
+ end if coercions
38
+ dash.instance_variable_set(property, coercions)
39
+ end
40
+
41
+ def [](key, &_block)
42
+ super(key) do |v|
43
+ if block_given?
44
+ v ||= send(:[]=, key, {})
45
+ yield v
46
+ v
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def build
53
+ self.class.superclass.new(to_hash)
54
+ end
55
+
56
+ private
57
+
58
+ def self.infect_class(coercions, key, into)
59
+ if into.is_a? Hash
60
+ into.each_pair do |sub_key, sub_into|
61
+ coercions[key][sub_key] = infect sub_into
62
+ end
63
+ elsif into.is_a? Array
64
+ coercions[key] = into.map do |sub_into|
65
+ infect sub_into
66
+ end
67
+ else
68
+ coercions[key] = infect into
69
+ end
70
+ end
71
+
72
+ def self.infect(klass)
73
+ return klass unless klass <= Hashie::Dash
74
+
75
+ klass.const_set('Bash',
76
+ Class.new(klass).tap do |bash_klass|
77
+ # include is public in Ruby 2.1+, hack to support older
78
+ bash_klass.send(:include, Bash)
79
+ end
80
+ ) unless klass.const_defined? 'Bash'
81
+
82
+ klass.const_get('Bash')
83
+ end
84
+ end
85
+
86
+ # An object for building a Swagger document. Coerces and validates data types
87
+ # as create the document, but does not enforce required fields until you call
88
+ # #{Bash#build}.
89
+ module Builder
90
+ def self.builder(opts = {})
91
+ version = opts[:version] || '2.0'
92
+ target_class = target_api_class(version)
93
+ klass = Swagger::Bash.infect(target_class)
94
+ klass.new({})
95
+ end
96
+
97
+ private
98
+
99
+ def self.target_api_class(version)
100
+ major, _minor = version.to_s.split('.')
101
+ case major
102
+ when '2'
103
+ Swagger::V2::API
104
+ else
105
+ fail ArgumentError, "Swagger version #{version} is not currently supported"
106
+ end
107
+ end
108
+ end
109
+ end