swagger_yard 0.3.0 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe5802a169475d76a89dfdefa227b4e70f656851
4
- data.tar.gz: 5a384463c1798693067ac7379093f28d1f194312
3
+ metadata.gz: b6d7e8bd82bb1384166a7b05b762bbfb31ae9940
4
+ data.tar.gz: b4094c3b0020e510234ff13632a7be76728bd625
5
5
  SHA512:
6
- metadata.gz: 0bad20c5172a080f1939eb511eac7b2c6930eb7bd3cf5f408a83100432f453bf9645c47bbbddc5bf35b98ab522d5f6d7e31f7a7277c19efd0607afa1ddfce309
7
- data.tar.gz: c6d2040c142826db3ecd4e02fe4a9be55d09369addb94db8ed4b0081f0f87119142b7cc6a7ca7a2ddfd3638a224a26f34af3ee9233a1b9d7ee4db5cb3810edde
6
+ metadata.gz: 01b6da87aaa978797af17e081421136c01441d22048666beb8aa6baadc15698110e443b0a263dac0f85c4b45f18e12f5d168bdd35a988aa54cd3799e0d8b9ac2
7
+ data.tar.gz: 9a8c5b69c3fbf57c17f44398f052ff994d1a640e3f7c0fcb2c54dc9ccfc4347ce1f80b5043f239244c1866ac421269294d367148ec81f0c9d5c0e54a4e66c940
data/README.md CHANGED
@@ -34,9 +34,16 @@ Types of things (parameters or responses of an operation, properties of a model)
34
34
  are indicated inside square-brackets (e.g., `[string]`) as part of a YARD tag.
35
35
 
36
36
  - Model references should be Capitalized or CamelCased by convention.
37
- - Basic types (integer, boolean, string, etc) should be lowercased.
37
+ - Basic types (integer, boolean, string, object, number, date, time, date-time,
38
+ uuid, etc.) should be lowercased.
38
39
  - An array of models or basic types is specified with `[array<...>]`.
39
40
  - An enum of allowed string values is specified with `[enum<one,two,three>]`.
41
+ - JSON-Schema `format` attributes can be specified for basic types using
42
+ `<...>`. For example, `[integer<int64>]` produces JSON
43
+ `{ "type": "integer", "format": "int64" }`.
44
+ - Regex pattern constraints can be specified for strings using
45
+ `[regex<PATTERN>]`. For example, `[regex<^.{3}$>]` produces JSON
46
+ `{ "type": "string", "pattern": "^.{3}$" }`.
40
47
 
41
48
  ### Options ###
42
49
 
@@ -46,11 +53,13 @@ following the parameter or property name.
46
53
  Examples:
47
54
 
48
55
  # @parameter name(required) [string] Name of the package
56
+ # @parameter age(nullable) [integer] Age of package
49
57
  # @parameter package(body) [Package] Package object
50
58
 
51
59
  Possible parameters include:
52
60
 
53
61
  - `required`: indicates a required parameter or property.
62
+ - `nullable`: indicates that JSON `null` is an allowed value for the property.
54
63
  - `multiple`: indicates a parameter may appear multiple times (usually in a
55
64
  query string, e.g., `param=a&param=b&param=c`)
56
65
  - `body`/`query`/`path`/`formData`: Indicates where the parameter is located.
@@ -1,10 +1,13 @@
1
1
  module SwaggerYard
2
2
  class ApiDeclaration
3
- attr_accessor :description, :resource, :resource_path
3
+ attr_accessor :description, :resource
4
4
  attr_reader :apis, :authorizations
5
5
 
6
- def initialize(resource_listing)
7
- @resource_listing = resource_listing
6
+ def self.from_yard_object(yard_object)
7
+ new.add_yard_object(yard_object)
8
+ end
9
+
10
+ def initialize
8
11
  @resource = nil
9
12
  @apis = {}
10
13
  @authorizations = {}
@@ -14,30 +17,37 @@ module SwaggerYard
14
17
  !@resource.nil?
15
18
  end
16
19
 
17
- def add_yard_objects(yard_objects)
18
- yard_objects.each do |yard_object|
19
- add_yard_object(yard_object)
20
- end
21
- self
22
- end
23
-
24
20
  def add_yard_object(yard_object)
25
21
  case yard_object.type
26
22
  when :class # controller
27
- add_listing_info(ListingInfo.new(yard_object))
28
- add_authorizations_to_resource_listing(yard_object)
23
+ add_info(yard_object)
24
+ if valid?
25
+ yard_object.children.each do |child_object|
26
+ add_yard_object(child_object)
27
+ end
28
+ end
29
29
  when :method # actions
30
30
  add_api(yard_object)
31
31
  end
32
+ self
32
33
  end
33
34
 
34
- def add_listing_info(listing_info)
35
- @description = listing_info.description
36
- @resource = listing_info.resource
37
- @resource_path = listing_info.resource_path # required for valid? but nothing else
35
+ def add_info(yard_object)
36
+ @description = yard_object.docstring
37
+
38
+ if tag = yard_object.tags.detect {|t| t.tag_name == "resource"}
39
+ @resource = tag.text
40
+ end
41
+
42
+ if tag = yard_object.tags.detect {|t| t.tag_name == "resource_path"}
43
+ log.warn "DEPRECATED: @resource_path tag is obsolete."
44
+ end
38
45
 
39
46
  # we only have api_key auth, the value for now is always empty array
40
- @authorizations = Hash[listing_info.authorizations.uniq.map {|k| [k, []]}]
47
+ @authorizations = Hash[yard_object.tags.
48
+ select {|t| t.tag_name == "authorize_with"}.
49
+ map(&:text).uniq.
50
+ map {|k| [k, []]}]
41
51
  end
42
52
 
43
53
  def add_api(yard_object)
@@ -49,13 +59,6 @@ module SwaggerYard
49
59
  api.add_operation(yard_object)
50
60
  end
51
61
 
52
- # HACK, requires knowledge of resource_listing
53
- def add_authorizations_to_resource_listing(yard_object)
54
- yard_object.tags.select {|t| t.tag_name == "authorization"}.each do |t|
55
- @resource_listing.authorizations << Authorization.from_yard_object(t)
56
- end
57
- end
58
-
59
62
  def apis_hash
60
63
  Hash[apis.map {|path, api| [path, api.operations_hash]}]
61
64
  end
@@ -6,17 +6,9 @@ module SwaggerYard
6
6
  class Model
7
7
  attr_reader :id
8
8
 
9
- def self.from_yard_objects(yard_objects)
10
- from_yard_object(yard_objects.detect {|o| o.type == :class })
11
- end
12
-
13
9
  def self.from_yard_object(yard_object)
14
- from_tags(yard_object.tags) if yard_object
15
- end
16
-
17
- def self.from_tags(tags)
18
10
  new.tap do |model|
19
- model.parse_tags(tags)
11
+ model.parse_tags(yard_object.tags)
20
12
  end
21
13
  end
22
14
 
@@ -39,7 +39,7 @@ module SwaggerYard
39
39
  end
40
40
 
41
41
  def summary
42
- @summary || description.split("\n\n").first
42
+ @summary || description.split("\n\n").first || ""
43
43
  end
44
44
 
45
45
  def to_h
@@ -8,14 +8,15 @@ module SwaggerYard
8
8
  def self.from_tag(tag)
9
9
  name, options_string = tag.name.split(/[\(\)]/)
10
10
 
11
- required = options_string.to_s.split(',').map(&:strip).include?('required')
11
+ options = options_string.to_s.split(',').map(&:strip)
12
12
 
13
- new(name, tag.types, tag.text, required)
13
+ new(name, tag.types, tag.text, options)
14
14
  end
15
15
 
16
- def initialize(name, types, description, required)
17
- @name, @description, @required = name, description, required
18
-
16
+ def initialize(name, types, description, options)
17
+ @name, @description = name, description
18
+ @required = options.include?('required')
19
+ @nullable = options.include?('nullable')
19
20
  @type = Type.from_type_list(types)
20
21
  end
21
22
 
@@ -26,6 +27,12 @@ module SwaggerYard
26
27
  def to_h
27
28
  @type.to_h.tap do |h|
28
29
  h["description"] = description if description
30
+ if @nullable
31
+ h["x-nullable"] = true
32
+ if h["type"]
33
+ h["type"] = [h["type"], "null"]
34
+ end
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -51,22 +51,23 @@ module SwaggerYard
51
51
  return [] unless @model_path
52
52
 
53
53
  Dir[@model_path].map do |file_path|
54
- Model.from_yard_objects(SwaggerYard.yard_objects_from_file(file_path))
55
- end.compact.select(&:valid?)
54
+ SwaggerYard.yard_class_objects_from_file(file_path).map do |obj|
55
+ Model.from_yard_object(obj)
56
+ end
57
+ end.flatten.compact.select(&:valid?)
56
58
  end
57
59
 
58
60
  def parse_controllers
59
61
  return [] unless @controller_path
60
62
 
61
63
  Dir[@controller_path].map do |file_path|
62
- create_api_declaration(file_path)
63
- end.select(&:valid?)
64
- end
65
-
66
- def create_api_declaration(file_path)
67
- yard_objects = SwaggerYard.yard_objects_from_file(file_path)
68
-
69
- ApiDeclaration.new(self).add_yard_objects(yard_objects)
64
+ SwaggerYard.yard_class_objects_from_file(file_path).map do |obj|
65
+ obj.tags.select {|t| t.tag_name == "authorization"}.each do |t|
66
+ @authorizations << Authorization.from_yard_object(t)
67
+ end
68
+ ApiDeclaration.from_yard_object(obj)
69
+ end
70
+ end.flatten.select(&:valid?)
70
71
  end
71
72
  end
72
73
  end
@@ -2,20 +2,34 @@ module SwaggerYard
2
2
  class Type
3
3
  def self.from_type_list(types)
4
4
  parts = types.first.split(/[<>]/)
5
- args = [parts.last]
6
- case parts.first
7
- when /^array$/i
8
- args << true
9
- when /^enum$/i
10
- args = [nil, false, parts.last.split(/[,|]/)]
11
- end if parts.size > 1
12
- new(*args)
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
+ else
18
+ name = parts.first
19
+ options[:format] = parts.last
20
+ end
21
+ end
22
+ new(name, options)
13
23
  end
14
24
 
15
25
  attr_reader :name, :array, :enum
16
26
 
17
- def initialize(name, array = false, enum = nil)
18
- @name, @array, @enum = name, array, enum
27
+ def initialize(name, options = {})
28
+ @name = name
29
+ @array = options[:array]
30
+ @enum = options[:enum]
31
+ @format = options[:format]
32
+ @pattern = options[:pattern]
19
33
  end
20
34
 
21
35
  # TODO: have this look at resource listing?
@@ -31,18 +45,19 @@ module SwaggerYard
31
45
  alias :enum? :enum
32
46
 
33
47
  def json_type
34
- type, format = name, nil
48
+ type, format = name, @format
35
49
  case name
36
50
  when "float", "double"
37
51
  type = "number"
38
52
  format = name
39
- when "date-time", "date", "time"
53
+ when "date-time", "date", "time", "uuid"
40
54
  type = "string"
41
55
  format = name
42
56
  end
43
57
  {}.tap do |h|
44
58
  h["type"] = type
45
59
  h["format"] = format if format
60
+ h["pattern"] = @pattern if @pattern
46
61
  end
47
62
  end
48
63
 
@@ -1,3 +1,3 @@
1
1
  module SwaggerYard
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/swagger_yard.rb CHANGED
@@ -10,7 +10,6 @@ require "swagger_yard/resource_listing"
10
10
  require "swagger_yard/api_declaration"
11
11
  require "swagger_yard/model"
12
12
  require "swagger_yard/api"
13
- require "swagger_yard/listing_info"
14
13
  require "swagger_yard/swagger"
15
14
 
16
15
  module SwaggerYard
@@ -35,24 +34,33 @@ module SwaggerYard
35
34
 
36
35
  #
37
36
  # Use YARD to parse object tags from a file
38
- #
37
+ #
39
38
  # @param file_path [string] The complete path to file
39
+ # @param types additional types by which to filter the result (:class/:module/:method)
40
40
  # @return [YARD] objects representing class/methods and tags from the file
41
- #
42
- def yard_objects_from_file(file_path)
43
- ::YARD::Registry.clear
41
+ #
42
+ def yard_objects_from_file(file_path, *types)
44
43
  ::YARD.parse(file_path)
45
- ::YARD::Registry.all
44
+ ::YARD::Registry.all(*types).select {|co| co.file == file_path }
45
+ end
46
+
47
+ #
48
+ # Parse all objects in the file and return the class objects found.
49
+ #
50
+ # @param file_path [string] The complete path to file
51
+ # @return [YARD] objects representing classes from the file
52
+ #
53
+ def yard_class_objects_from_file(file_path)
54
+ yard_objects_from_file(file_path, :class)
46
55
  end
47
56
 
48
57
  ##
49
58
  # Register some custom yard tags used by swagger-ui
50
59
  def register_custom_yard_tags!
51
60
  ::YARD::Tags::Library.define_tag("Api resource", :resource)
52
- ::YARD::Tags::Library.define_tag("Resource path", :resource_path)
61
+ ::YARD::Tags::Library.define_tag("Resource path", :resource_path) # TODO: remove deprecated tag
53
62
  ::YARD::Tags::Library.define_tag("Api path", :path, :with_types)
54
63
  ::YARD::Tags::Library.define_tag("Parameter", :parameter, :with_types_name_and_default)
55
- ::YARD::Tags::Library.define_tag("Status code", :status_code)
56
64
  ::YARD::Tags::Library.define_tag("Response type", :response_type, :with_types)
57
65
  ::YARD::Tags::Library.define_tag("Error response message", :error_message, :with_types_and_name)
58
66
  ::YARD::Tags::Library.define_tag("Api Summary", :summary)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagger_yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
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: 2015-11-03 00:00:00.000000000 Z
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -138,7 +138,6 @@ files:
138
138
  - lib/swagger_yard/api_declaration.rb
139
139
  - lib/swagger_yard/authorization.rb
140
140
  - lib/swagger_yard/configuration.rb
141
- - lib/swagger_yard/listing_info.rb
142
141
  - lib/swagger_yard/model.rb
143
142
  - lib/swagger_yard/operation.rb
144
143
  - lib/swagger_yard/parameter.rb
@@ -1,19 +0,0 @@
1
- module SwaggerYard
2
- class ListingInfo
3
- attr_reader :description, :resource, :resource_path, :authorizations
4
-
5
- def initialize(yard_object)
6
- @description = yard_object.docstring
7
-
8
- if tag = yard_object.tags.detect {|t| t.tag_name == "resource"}
9
- @resource = tag.text
10
- end
11
-
12
- if tag = yard_object.tags.detect {|t| t.tag_name == "resource_path"}
13
- @resource_path = tag.text.downcase
14
- end
15
-
16
- @authorizations = yard_object.tags.select {|t| t.tag_name == "authorize_with"}.map(&:text)
17
- end
18
- end
19
- end