swagger_yard 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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