swagger_yard 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjdkMTcwZWU5NTNhNjNhNjA0NzhlN2ZjMWZmMzZlMDUxZTI1NWNiOA==
5
- data.tar.gz: !binary |-
6
- MjAxYzIwNDYyNzc1MjEyMGU0MzIyNjAyZmU5OTI4YjA4MzFmMzRhOA==
2
+ SHA1:
3
+ metadata.gz: ef1f9c99cbcdd6a637a1d68079ba1e2a0b1cb718
4
+ data.tar.gz: 17849b615de17e9ec974f9905202a8097daf0eba
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MDhhNWJkNDJhNWI3ODQyZTI0OGQ3ZmM4ZGE4MzYzMzgwNWU3YmM2N2MyMTAz
10
- NGM3MDVkOTM1MDMwMDYxYTU1MjE4YTUyZWNlZmM0OWY3NjFhYjI0Mzc4ZDFk
11
- ODUxODdkZWQ4YWNiY2Q1YTQ0YjMwODRjMzI3ZDQ0NWQwYWQ1Nzc=
12
- data.tar.gz: !binary |-
13
- NWFkMDRjMGE1MGYzYzE1ZWQ2NGRiMjRiMmZkOWQ5YjliZGYzYWJlZDFjOWE5
14
- YzE2YWM0N2E2MzA4MDI4NzhmNTk0YjA3OTI2ODdjODUyZDU5OGNjNmE5NDBj
15
- OWUyNGEyYTc3OGYyNDhmMTgxOTYzM2YwMzFhOWJmN2JkMTcwNDI=
6
+ metadata.gz: e200703aa74c246766ec9dbeb448ab6fd7f8b036376f82bd8ae60d0c7b6abe4d1d1149ec662c45d4ab1d34af0f38ece20e909a501bcdae78ee9b038687aa1f68
7
+ data.tar.gz: 4877499f45c859a0d75ba2518d425a867f2dc072955c38ea49b5cbcaa13f8bd2322989a15f10cb39de1f8a6191057dfdb25333cdb6eef96bdf9aa339d54032e3
data/README.md CHANGED
@@ -47,6 +47,31 @@ are indicated inside square-brackets (e.g., `[string]`) as part of a YARD tag.
47
47
  `[regex<PATTERN>]`. For example, `[regex<^.{3}$>]` produces JSON
48
48
  `{ "type": "string", "pattern": "^.{3}$" }`.
49
49
 
50
+ ### External Schema ###
51
+
52
+ Types can be specified that refer to external JSON schema documents for their definition. External schema documents are expected to also define their models under a `definitions` top-level key like so:
53
+ ```
54
+ {
55
+ "definitions": {
56
+ "MyStandardModel": {
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ To register an external schema so that it can be referenced in places where you specify a type, configure SwaggerYard as follows:
63
+ ```ruby
64
+ SwaggerYard.configure do |config|
65
+ config.external_schema mymodels: 'https://example.com/mymodels/v1.0'
66
+ end
67
+ ```
68
+
69
+ Then refer to models in the schema using the syntax `[mymodels#MyStandardModel]` where types are specified. This causes SwaggerYard to emit the following schema for the type:
70
+
71
+ ```
72
+ { "$ref": "https://example.com/mymodels/v1.0#/definitions/MyStandardModel" }
73
+ ```
74
+
50
75
  ### Options ###
51
76
 
52
77
  Parameter or property _options_ are expressed inside parenthesis immediately
@@ -11,7 +11,7 @@ module SwaggerYard
11
11
  yard_object.add_tag YARD::Tags::Tag.new("path", path, [method]) if path
12
12
  path
13
13
  rescue => e
14
- YARD::Logger.instance.warn e.message
14
+ SwaggerYard.log.warn e.message
15
15
  nil
16
16
  end
17
17
  end
@@ -41,7 +41,7 @@ module SwaggerYard
41
41
  end
42
42
 
43
43
  if tag = yard_object.tags.detect {|t| t.tag_name == "resource_path"}
44
- log.warn "DEPRECATED: @resource_path tag is obsolete."
44
+ SwaggerYard.log.warn "DEPRECATED: @resource_path tag is obsolete."
45
45
  end
46
46
 
47
47
  # we only have api_key auth, the value for now is always empty array
@@ -9,13 +9,21 @@ module SwaggerYard
9
9
  attr_accessor :security_definitions
10
10
 
11
11
  def initialize
12
- self.swagger_version = "2.0"
13
- self.api_version = "0.1"
14
- self.enable = false
15
- self.reload = true
16
- self.title = "Configure title with SwaggerYard.config.title"
17
- self.description = "Configure description with SwaggerYard.config.description"
18
- self.security_definitions = {}
12
+ @swagger_version = "2.0"
13
+ @api_version = "0.1"
14
+ @enable = false
15
+ @reload = true
16
+ @title = "Configure title with SwaggerYard.config.title"
17
+ @description = "Configure description with SwaggerYard.config.description"
18
+ @security_definitions = {}
19
+ @external_schema = {}
20
+ end
21
+
22
+ def external_schema(mappings = nil)
23
+ mappings.each do |prefix, url|
24
+ @external_schema[prefix.to_s] = url
25
+ end if mappings
26
+ @external_schema
19
27
  end
20
28
 
21
29
  def swagger_spec_base_path=(ignored)
@@ -90,6 +90,12 @@ module SwaggerYard
90
90
  # Example: [GET] /api/v2/ownerships
91
91
  # Example: [PUT] /api/v1/accounts/{account_id}
92
92
  def add_path_params_and_method(tag)
93
+ if @path && @http_method
94
+ SwaggerYard.log.warn 'multiple path tags not supported: ' \
95
+ "ignored [#{tag.types.first}] #{tag.text}"
96
+ return
97
+ end
98
+
93
99
  @path = tag.text
94
100
  @http_method = tag.types.first
95
101
 
@@ -113,6 +119,9 @@ module SwaggerYard
113
119
  existing.param_type = parameter.param_type if parameter.from_path?
114
120
  existing.required ||= parameter.required
115
121
  existing.allow_multiple = parameter.allow_multiple
122
+ elsif parameter.param_type == 'body' && @parameters.detect {|param| param.param_type == 'body'}
123
+ SwaggerYard.log.warn 'multiple body parameters invalid: ' \
124
+ "ignored #{parameter.name} for #{@api.api_declaration.class_name}##{ruby_method}"
116
125
  else
117
126
  @parameters << parameter
118
127
  end
@@ -1,10 +1,11 @@
1
1
  module SwaggerYard
2
2
  class Parameter
3
- attr_accessor :name, :description, :param_type, :required, :allow_multiple
3
+ attr_accessor :name, :type, :description, :param_type, :required, :allow_multiple
4
4
 
5
5
  def self.from_yard_tag(tag, operation)
6
- description = tag.text
7
6
  name, options_string = tag.name.split(/[\(\)]/)
7
+ description = tag.text
8
+ description = name if description.strip.empty?
8
9
  type = Type.from_type_list(tag.types)
9
10
 
10
11
  options = {}
@@ -26,11 +26,13 @@ module SwaggerYard
26
26
 
27
27
  def to_h
28
28
  @type.to_h.tap do |h|
29
- h["description"] = description if description
30
- if @nullable
31
- h["x-nullable"] = true
32
- if h["type"]
33
- h["type"] = [h["type"], "null"]
29
+ unless h['$ref']
30
+ h["description"] = description if description
31
+ if @nullable
32
+ h["x-nullable"] = true
33
+ if h["type"]
34
+ h["type"] = [h["type"], "null"]
35
+ end
34
36
  end
35
37
  end
36
38
  end
@@ -30,12 +30,14 @@ module SwaggerYard
30
30
  end
31
31
 
32
32
  def path_objects
33
- controllers.map(&:apis_hash).reduce({}, :merge)
33
+ controllers.map(&:apis_hash).reduce({}, :merge).tap do |paths|
34
+ warn_duplicate_operations(paths)
35
+ end
34
36
  end
35
37
 
36
38
  # Resources
37
39
  def tag_objects
38
- controllers.map(&:to_tag)
40
+ controllers.sort {|a,b| a.resource.upcase <=> b.resource.upcase}.map(&:to_tag)
39
41
  end
40
42
 
41
43
  def model_objects
@@ -73,5 +75,18 @@ module SwaggerYard
73
75
  end
74
76
  end.flatten.select(&:valid?)
75
77
  end
78
+
79
+ def warn_duplicate_operations(paths)
80
+ operation_ids = []
81
+ paths.each do |path,ops|
82
+ ops.each do |method,op|
83
+ if operation_ids.include?(op['operationId'])
84
+ SwaggerYard.log.warn("duplicate operation #{op['operationId']}")
85
+ next
86
+ end
87
+ operation_ids << op['operationId']
88
+ end
89
+ end
90
+ end
76
91
  end
77
92
  end
@@ -24,6 +24,8 @@ module SwaggerYard
24
24
 
25
25
  rule(:identifier) { name >> (str('::') >> name).repeat }
26
26
 
27
+ rule(:external_identifier) { name.as(:namespace) >> str('#') >> identifier.as(:identifier) }
28
+
27
29
  rule(:regexp) { stri('regex') >> match['Pp'].maybe >> space >>
28
30
  str('<') >> (str('\\\\') | str('\\>') | match['[^>]']).repeat.as(:regexp) >> str('>') }
29
31
 
@@ -45,6 +47,7 @@ module SwaggerYard
45
47
  array.as(:array) |
46
48
  object.as(:object) |
47
49
  formatted.as(:formatted) |
50
+ external_identifier.as(:external_identifier) |
48
51
  identifier.as(:identifier) |
49
52
  regexp }
50
53
 
@@ -73,6 +76,14 @@ module SwaggerYard
73
76
  end
74
77
  end
75
78
 
79
+ rule(external_identifier: { namespace: simple(:namespace), identifier: simple(:identifier) }) do
80
+ prefix, name = namespace.to_s, identifier.to_s
81
+ unless url = SwaggerYard.config.external_schema[prefix]
82
+ raise UndefinedSchemaError, "unknown prefix #{prefix} for #{name}"
83
+ end
84
+ { '$ref' => "#{url}#/definitions/#{Model.mangle(name)}"}
85
+ end
86
+
76
87
  rule(formatted: { name: simple(:name), format: simple(:format) }) do
77
88
  { 'type' => name.to_s, 'format' => format.to_s }
78
89
  end
@@ -123,7 +134,7 @@ module SwaggerYard
123
134
  def json_schema(str)
124
135
  @xform.apply(parse(str))
125
136
  rescue Parslet::ParseFailed => e
126
- raise ArgumentError, "invalid type: #{e.message}"
137
+ raise InvalidTypeError, "'#{str}': #{e.message}"
127
138
  end
128
139
  end
129
140
  end
@@ -1,3 +1,3 @@
1
1
  module SwaggerYard
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/swagger_yard.rb CHANGED
@@ -14,6 +14,10 @@ require "swagger_yard/api"
14
14
  require "swagger_yard/swagger"
15
15
 
16
16
  module SwaggerYard
17
+ class Error < StandardError; end
18
+ class InvalidTypeError < Error; end
19
+ class UndefinedSchemaError < Error; end
20
+
17
21
  class << self
18
22
  ##
19
23
  # Configuration for Swagger Yard, use like:
@@ -33,6 +37,10 @@ module SwaggerYard
33
37
  @configuration ||= Configuration.new
34
38
  end
35
39
 
40
+ def log
41
+ YARD::Logger.instance
42
+ end
43
+
36
44
  #
37
45
  # Use YARD to parse object tags from a file
38
46
  #
metadata CHANGED
@@ -1,167 +1,181 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagger_yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
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-11-29 00:00:00.000000000 Z
11
+ date: 2018-04-05 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
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: parslet
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '12'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - "<"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '12'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-its
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: apivore
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - "<"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '1.6'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - "<"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: nokogiri
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "<"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "<"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.8'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: addressable
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - <=
115
+ - - "<="
102
116
  - !ruby/object:Gem::Version
103
117
  version: 2.4.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - <=
122
+ - - "<="
109
123
  - !ruby/object:Gem::Version
110
124
  version: 2.4.0
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: simplecov
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - ! '>='
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - ! '>='
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: mocha
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - ! '>='
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
145
  version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - ! '>='
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bourne
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - ! '>='
157
+ - - ">="
144
158
  - !ruby/object:Gem::Version
145
159
  version: '0'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
- - - ! '>='
164
+ - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: '0'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: wwtd
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
- - - ! '>='
171
+ - - ">="
158
172
  - !ruby/object:Gem::Version
159
173
  version: '0'
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
- - - ! '>='
178
+ - - ">="
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
167
181
  description: SwaggerYard API doc gem that uses YARD to parse the docs for a REST rails
@@ -199,17 +213,17 @@ require_paths:
199
213
  - lib
200
214
  required_ruby_version: !ruby/object:Gem::Requirement
201
215
  requirements:
202
- - - ! '>='
216
+ - - ">="
203
217
  - !ruby/object:Gem::Version
204
218
  version: '0'
205
219
  required_rubygems_version: !ruby/object:Gem::Requirement
206
220
  requirements:
207
- - - ! '>='
221
+ - - ">="
208
222
  - !ruby/object:Gem::Version
209
223
  version: '0'
210
224
  requirements: []
211
225
  rubyforge_project:
212
- rubygems_version: 2.4.8
226
+ rubygems_version: 2.6.12
213
227
  signing_key:
214
228
  specification_version: 4
215
229
  summary: SwaggerYard API doc through YARD