swagger_yard 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9aeaddf2ad2b175e4bfdc57babde3aa86ee99062
4
- data.tar.gz: ff4b60b5e565142fb1fbca9a965df9ac966c1de1
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjdkMTcwZWU5NTNhNjNhNjA0NzhlN2ZjMWZmMzZlMDUxZTI1NWNiOA==
5
+ data.tar.gz: !binary |-
6
+ MjAxYzIwNDYyNzc1MjEyMGU0MzIyNjAyZmU5OTI4YjA4MzFmMzRhOA==
5
7
  SHA512:
6
- metadata.gz: 803a430a06eb91d2b853a9e1eccd45920d7047db36181076e53aec1e64ebc43a2e288cbab11f4541bb43e8d37f11b7f9822d0557065cd0f1ac92389ada974643
7
- data.tar.gz: 19ce8dba724574bc55588c3ee5b913b3416ee18e24b26818e8ed5862637df439d8b83ddb3e54fbd1477594cc29d13d43cbe9d6352b327becf9e4d52aa19b6b49
8
+ metadata.gz: !binary |-
9
+ MDhhNWJkNDJhNWI3ODQyZTI0OGQ3ZmM4ZGE4MzYzMzgwNWU3YmM2N2MyMTAz
10
+ NGM3MDVkOTM1MDMwMDYxYTU1MjE4YTUyZWNlZmM0OWY3NjFhYjI0Mzc4ZDFk
11
+ ODUxODdkZWQ4YWNiY2Q1YTQ0YjMwODRjMzI3ZDQ0NWQwYWQ1Nzc=
12
+ data.tar.gz: !binary |-
13
+ NWFkMDRjMGE1MGYzYzE1ZWQ2NGRiMjRiMmZkOWQ5YjliZGYzYWJlZDFjOWE5
14
+ YzE2YWM0N2E2MzA4MDI4NzhmNTk0YjA3OTI2ODdjODUyZDU5OGNjNmE5NDBj
15
+ OWUyNGEyYTc3OGYyNDhmMTgxOTYzM2YwMzFhOWJmN2JkMTcwNDI=
data/README.md CHANGED
@@ -38,6 +38,8 @@ are indicated inside square-brackets (e.g., `[string]`) as part of a YARD tag.
38
38
  uuid, etc.) should be lowercased.
39
39
  - An array of models or basic types is specified with `[array<...>]`.
40
40
  - An enum of allowed string values is specified with `[enum<one,two,three>]`.
41
+ - An object definition can include the property definitions of its fields, and / or of an additional property for any remaining allowed fields. E.g., `[object<name: string, age: integer, string >]`
42
+ - Structured data like objects, arrays, pairs, etc., definitions can also be nested; E.g., `[object<pairs:array<object<right:integer,left:integer>>>]`
41
43
  - JSON-Schema `format` attributes can be specified for basic types using
42
44
  `<...>`. For example, `[integer<int64>]` produces JSON
43
45
  `{ "type": "integer", "format": "int64" }`.
@@ -156,8 +158,9 @@ end
156
158
  ```
157
159
 
158
160
  ## Authorization ##
161
+ ### API Key auth ###
159
162
 
160
- Currently, SwaggerYard only supports API Key auth descriptions. Start by adding `@authorization` to your `ApplicationController`.
163
+ SwaggerYard supports API Key auth descriptions. Start by adding `@authorization` to your `ApplicationController`.
161
164
 
162
165
  ```ruby
163
166
  #
@@ -177,6 +180,28 @@ class PetController < ApplicationController
177
180
  end
178
181
  ```
179
182
 
183
+ ### Custom security definitions (OAuth2) ###
184
+
185
+ Additionally SwaggerYard also supports custom [security definitions](http://swagger.io/specification/#securityDefinitionsObject). You can define these in your configuration like:
186
+
187
+ ```ruby
188
+ SwaggerYard.configure do |config|
189
+ config.security_definitions['petstore_oauth'] = {
190
+ type: "oauth2",
191
+ authorizationUrl: "http://swagger.io/api/oauth/dialog",
192
+ flow: :implicit
193
+ }
194
+ end
195
+ ```
196
+
197
+ Then you can also use these authorizations from your controller or actions in a controller.
198
+
199
+ ```ruby
200
+ # @authorize_with petstore_oauth
201
+ class PetController < ApplicationController
202
+ end
203
+ ```
204
+
180
205
  ## UI ##
181
206
 
182
207
  We suggest using something like [swagger-ui_rails](https://github.com/3scale/swagger-ui_rails/tree/dev-2.1.3) for your UI needs inside of Rails.
@@ -6,6 +6,7 @@ module SwaggerYard
6
6
  attr_accessor :enable, :reload
7
7
  attr_accessor :controller_path, :model_path
8
8
  attr_accessor :path_discovery_function
9
+ attr_accessor :security_definitions
9
10
 
10
11
  def initialize
11
12
  self.swagger_version = "2.0"
@@ -14,6 +15,7 @@ module SwaggerYard
14
15
  self.reload = true
15
16
  self.title = "Configure title with SwaggerYard.config.title"
16
17
  self.description = "Configure description with SwaggerYard.config.description"
18
+ self.security_definitions = {}
17
19
  end
18
20
 
19
21
  def swagger_spec_base_path=(ignored)
@@ -43,7 +43,10 @@ module SwaggerYard
43
43
  end
44
44
 
45
45
  def security_objects
46
- Hash[authorizations.map {|auth| [auth.name, auth.to_h]}]
46
+ controllers # triggers controller parsing in case it did not happen before
47
+ SwaggerYard.config.security_definitions.merge(
48
+ Hash[authorizations.map {|auth| [auth.name, auth.to_h]}]
49
+ )
47
50
  end
48
51
 
49
52
  private
@@ -1,89 +1,34 @@
1
1
  module SwaggerYard
2
2
  class Type
3
3
  def self.from_type_list(types)
4
- parts = types.first.split(/[<>]/)
5
- name = parts.last
6
- options = {}
7
- if parts.size > 1
8
- case parts.first
9
- when /^array$/i
10
- options[:array] = true
11
- when /^enum$/i
12
- name = nil
13
- options[:enum] = parts.last.split(/[,|]/)
14
- when /^regexp?$/i
15
- name = 'string'
16
- options[:pattern] = parts.last
17
- when /^object$/i
18
- options[:object] = parts[1..-1]
19
- else
20
- name = parts.first
21
- options[:format] = parts.last
22
- end
23
- end
24
- new(name, options)
4
+ new(types.first)
25
5
  end
26
6
 
27
- attr_reader :name, :array, :enum, :object
7
+ attr_reader :name, :source, :schema
28
8
 
29
- def initialize(name, options = {})
30
- @name = Model.mangle(name) if name
31
- @array = options[:array]
32
- @enum = options[:enum]
33
- @format = options[:format]
34
- @pattern = options[:pattern]
35
- @object = options[:object]
9
+ def initialize(string)
10
+ @source = string
11
+ @schema = TypeParser.new.json_schema(string)
12
+ @name = name_for(@schema)
13
+ @name = name_for(@schema['items']) if @name == 'array'
36
14
  end
37
15
 
38
16
  # TODO: have this look at resource listing?
39
17
  def ref?
40
- /[[:upper:]]/.match(name)
18
+ schema["$ref"]
41
19
  end
42
20
 
43
21
  def model_name
44
22
  ref? ? name : nil
45
23
  end
46
24
 
47
- alias :array? :array
48
- alias :enum? :enum
49
- alias :object? :object
50
-
51
- def json_type
52
- type, format = name, @format
53
- case name
54
- when "float", "double"
55
- type = "number"
56
- format = name
57
- when "date-time", "date", "time", "uuid"
58
- type = "string"
59
- format = name
60
- end
61
-
62
- hsh = { "type" => type }
63
- hsh["format"] = format if format
64
- hsh["pattern"] = @pattern if @pattern
65
- hsh
66
- end
67
-
68
25
  def to_h
69
- type = if ref?
70
- { "$ref" => "#/definitions/#{name}"}
71
- elsif enum?
72
- { "type" => "string", "enum" => @enum }
73
- else
74
- json_type
75
- end
26
+ schema
27
+ end
76
28
 
77
- if array?
78
- { "type" => "array", "items" => type }
79
- elsif object?
80
- {
81
- "type" => "object",
82
- "additionalProperties" => Type.from_type_list([object.join("<")]).to_h
83
- }
84
- else
85
- type
86
- end
29
+ private
30
+ def name_for(schema)
31
+ schema["type"] || schema["$ref"][%r'#/definitions/(.*)', 1]
87
32
  end
88
33
  end
89
34
  end
@@ -0,0 +1,129 @@
1
+ require 'parslet'
2
+
3
+ module SwaggerYard
4
+ class TypeParser
5
+ class Parser < Parslet::Parser
6
+ # Allow for whitespace surrounding a string value
7
+ def spaced(arg)
8
+ space >> str(arg) >> space
9
+ end
10
+
11
+ def stri(str)
12
+ key_chars = str.split(//)
13
+ key_chars.collect! { |char| match["#{char.upcase}#{char.downcase}"] }.
14
+ reduce(:>>)
15
+ end
16
+
17
+ rule(:space) { match[" \n"].repeat }
18
+
19
+ rule(:id_char) { match['-a-zA-Z0-9_'].repeat }
20
+
21
+ rule(:id_start) { match('[a-zA-Z_]') }
22
+
23
+ rule(:name) { id_start >> id_char }
24
+
25
+ rule(:identifier) { name >> (str('::') >> name).repeat }
26
+
27
+ rule(:regexp) { stri('regex') >> match['Pp'].maybe >> space >>
28
+ str('<') >> (str('\\\\') | str('\\>') | match['[^>]']).repeat.as(:regexp) >> str('>') }
29
+
30
+ rule(:enum_list) { name.as(:value) >> (spaced(',') >> name.as(:value)).repeat }
31
+
32
+ rule(:enum) { stri('enum') >> spaced('<') >> enum_list >> spaced('>') }
33
+
34
+ rule(:array) { stri('array') >> spaced('<') >> type >> spaced('>') }
35
+
36
+ rule(:pair) { (name.as(:property) >> spaced(':') >> type.as(:type)).as(:pair) }
37
+
38
+ rule(:pairs) { pair >> (spaced(',') >> pair).repeat >> (spaced(',') >> type.as(:additional)).maybe }
39
+
40
+ rule(:object) { stri('object') >> spaced('<') >> (pairs | type.as(:additional)) >> spaced('>') }
41
+
42
+ rule(:formatted) { name.as(:name) >> spaced('<') >> name.as(:format) >> spaced('>') }
43
+
44
+ rule(:type) { enum.as(:enum) |
45
+ array.as(:array) |
46
+ object.as(:object) |
47
+ formatted.as(:formatted) |
48
+ identifier.as(:identifier) |
49
+ regexp }
50
+
51
+ root :type
52
+ end
53
+
54
+ class Transform < Parslet::Transform
55
+ rule(identifier: simple(:id)) do
56
+ v = id.to_s
57
+ case v
58
+ when /array/i
59
+ { 'type' => 'array', 'items' => { 'type' => 'string' } }
60
+ when /object/i
61
+ { 'type' => 'object' }
62
+ when "float", "double"
63
+ { 'type' => 'number', 'format' => v }
64
+ when "date-time", "date", "time", "uuid"
65
+ { 'type' => 'string', 'format' => v }
66
+ else
67
+ name = Model.mangle(v)
68
+ if /[[:upper:]]/.match(name)
69
+ { '$ref' => "#/definitions/#{name}" }
70
+ else
71
+ { 'type' => name }
72
+ end
73
+ end
74
+ end
75
+
76
+ rule(formatted: { name: simple(:name), format: simple(:format) }) do
77
+ { 'type' => name.to_s, 'format' => format.to_s }
78
+ end
79
+
80
+ rule(regexp: simple(:pattern)) do
81
+ { 'type' => 'string', 'pattern' => pattern.to_s.gsub('\\\\', '\\').gsub('\>', '>') }
82
+ end
83
+
84
+ rule(value: simple(:value)) { value.to_s }
85
+
86
+ rule(enum: subtree(:values)) do
87
+ { 'type' => 'string', 'enum' => Array(values) }
88
+ end
89
+
90
+ rule(array: subtree(:type)) do
91
+ { 'type' => 'array', 'items' => type }
92
+ end
93
+
94
+ rule(pair: { property: simple(:prop), type: subtree(:type) }) do
95
+ { 'properties' => { prop.to_s => type } }
96
+ end
97
+
98
+ rule(additional: subtree(:type)) do
99
+ { 'additionalProperties' => type }
100
+ end
101
+
102
+ rule(object: subtree(:properties)) do
103
+ { 'type' => 'object' }.tap do |result|
104
+ all_props = Array === properties ? properties : [properties]
105
+ props, additional = all_props.partition {|pr| pr['properties'] }
106
+ props.each do |pr|
107
+ result['properties'] = (result['properties'] || {}).merge(pr['properties'])
108
+ end
109
+ result.update additional.first unless additional.empty?
110
+ end
111
+ end
112
+ end
113
+
114
+ def initialize
115
+ @parser = Parser.new
116
+ @xform = Transform.new
117
+ end
118
+
119
+ def parse(str)
120
+ @parser.parse(str)
121
+ end
122
+
123
+ def json_schema(str)
124
+ @xform.apply(parse(str))
125
+ rescue Parslet::ParseFailed => e
126
+ raise ArgumentError, "invalid type: #{e.message}"
127
+ end
128
+ end
129
+ end
@@ -1,3 +1,3 @@
1
1
  module SwaggerYard
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
data/lib/swagger_yard.rb CHANGED
@@ -2,6 +2,7 @@ require "yard"
2
2
  require "json"
3
3
  require "swagger_yard/configuration"
4
4
  require "swagger_yard/type"
5
+ require "swagger_yard/type_parser"
5
6
  require "swagger_yard/parameter"
6
7
  require "swagger_yard/property"
7
8
  require "swagger_yard/operation"
metadata CHANGED
@@ -1,125 +1,167 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagger_yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - chtrinh (Chris Trinh)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-26 00:00:00.000000000 Z
11
+ date: 2016-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: parslet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - ">="
45
+ - - ! '>='
32
46
  - !ruby/object:Gem::Version
33
47
  version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ">="
52
+ - - ! '>='
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - ! '>='
46
60
  - !ruby/object:Gem::Version
47
61
  version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - ! '>='
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec-its
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ">="
73
+ - - ! '>='
60
74
  - !ruby/object:Gem::Version
61
75
  version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - ">="
80
+ - - ! '>='
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: apivore
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - ! '>='
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - ! '>='
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: addressable
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - <=
102
+ - !ruby/object:Gem::Version
103
+ version: 2.4.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - <=
109
+ - !ruby/object:Gem::Version
110
+ version: 2.4.0
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: simplecov
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - ">="
115
+ - - ! '>='
88
116
  - !ruby/object:Gem::Version
89
117
  version: '0'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - ">="
122
+ - - ! '>='
95
123
  - !ruby/object:Gem::Version
96
124
  version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: mocha
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
- - - ">="
129
+ - - ! '>='
102
130
  - !ruby/object:Gem::Version
103
131
  version: '0'
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - ">="
136
+ - - ! '>='
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: bourne
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
- - - ">="
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: wwtd
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ! '>='
116
158
  - !ruby/object:Gem::Version
117
159
  version: '0'
118
160
  type: :development
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
122
- - - ">="
164
+ - - ! '>='
123
165
  - !ruby/object:Gem::Version
124
166
  version: '0'
125
167
  description: SwaggerYard API doc gem that uses YARD to parse the docs for a REST rails
@@ -145,6 +187,7 @@ files:
145
187
  - lib/swagger_yard/resource_listing.rb
146
188
  - lib/swagger_yard/swagger.rb
147
189
  - lib/swagger_yard/type.rb
190
+ - lib/swagger_yard/type_parser.rb
148
191
  - lib/swagger_yard/version.rb
149
192
  homepage: http://www.synctv.com
150
193
  licenses:
@@ -156,19 +199,18 @@ require_paths:
156
199
  - lib
157
200
  required_ruby_version: !ruby/object:Gem::Requirement
158
201
  requirements:
159
- - - ">="
202
+ - - ! '>='
160
203
  - !ruby/object:Gem::Version
161
204
  version: '0'
162
205
  required_rubygems_version: !ruby/object:Gem::Requirement
163
206
  requirements:
164
- - - ">="
207
+ - - ! '>='
165
208
  - !ruby/object:Gem::Version
166
209
  version: '0'
167
210
  requirements: []
168
211
  rubyforge_project:
169
- rubygems_version: 2.4.5
212
+ rubygems_version: 2.4.8
170
213
  signing_key:
171
214
  specification_version: 4
172
215
  summary: SwaggerYard API doc through YARD
173
216
  test_files: []
174
- has_rdoc: