apia-open_api 0.1.8 → 0.1.9

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
  SHA256:
3
- metadata.gz: 18cbf0db6400c3d1e60a769d2064e77259bc3368ccf39e8c8b4d8c3ae99125b9
4
- data.tar.gz: c29814927fee005a855592a8d7c7689decfffdb534c5cae5d7c1d4ec1a367d54
3
+ metadata.gz: ab4263122239dfce8e477f4279cbe4a03743f0e6fa4c1236c0480082d517ec8c
4
+ data.tar.gz: 8542223956ac7fc5fc4817cc627c0d5ec96876cd1f671a4e26422deae3818387
5
5
  SHA512:
6
- metadata.gz: fe2929de95c1b355815cb0d18a91af8fa373cd948ebf0465067211f75b9a3c5dc4f46795572b8ff5ce136410d0ae7865e01d8ea9c5a497adad272cb1f2e7f020
7
- data.tar.gz: bfd2cd9fe9a6a2e4148c9bf95b86b698584913c791fe03def05f99d56e484c1a49551e65fdac656d95229a90fbc6a24f41f19261d0e06f406bb7adb18bef2613
6
+ metadata.gz: 05131ea1ca348bce2d637314eba336e07bb4553f71ef3fd107c23ee854f107f09b26d24c0cdfdebb259ef450421bbcdc8864b6ac8fc057e32ac8570d590f24eb
7
+ data.tar.gz: 95cad90b7979f85e4cc085bb25ea7f33583766f8b05ef94a8ac91a93701e27e6b757bc3e63141211a9fab5dad16f57872b98dd3ad1c5a77fefa4c25c9b4f3bb1
@@ -36,20 +36,29 @@ module Apia
36
36
  @api_authenticator = api_authenticator
37
37
  @route_spec = {
38
38
  operationId: convert_route_to_id,
39
- tags: [name]
39
+ summary: @route.endpoint.definition.name,
40
+ description: @route.endpoint.definition.description,
41
+ tags: route.group ? get_group_tags(route.group) : [name]
40
42
  }
41
43
  end
42
44
 
43
45
  def add_to_spec
46
+ add_scopes_description
44
47
  path = @route.path
48
+
45
49
  if @route.request_method == :get
46
50
  add_parameters
47
51
  else
48
52
  add_request_body
49
53
  end
50
54
 
51
- @spec[:paths]["/#{path}"] ||= {}
52
- @spec[:paths]["/#{path}"][@route.request_method.to_s] = @route_spec
55
+ path = "/#{path}"
56
+ # Remove the `:` from the url parameters in the path
57
+ # This is because some tools based on the OpenAPI spec don't like the `:` in the path
58
+ path = path.gsub(/:([^\/]+)/, '\1')
59
+
60
+ @spec[:paths][path] ||= {}
61
+ @spec[:paths][path][@route.request_method.to_s] = @route_spec
53
62
 
54
63
  add_responses
55
64
  end
@@ -79,6 +88,24 @@ module Apia
79
88
  ).add_to_spec
80
89
  end
81
90
 
91
+ # Adds a description of the scopes to the route specification.
92
+ #
93
+ # This method checks if the route's endpoint definition has any scopes.
94
+ # If there are scopes, it appends a description of the scopes to the existing route specification description.
95
+ # The description of the scopes is formatted as a markdown list, with each scope represented as a bullet point.
96
+ def add_scopes_description
97
+ return unless @route.endpoint.definition.scopes.any?
98
+
99
+ @route_spec[:description] =
100
+ <<~DESCRIPTION
101
+ #{@route_spec[:description]}
102
+ ## Scopes
103
+ #{@route.endpoint.definition.scopes.map do |scope|
104
+ "- `#{scope}`"
105
+ end.join("\n")}
106
+ DESCRIPTION
107
+ end
108
+
82
109
  # It's worth creating a 'nice' operationId for each route, as this is used as the
83
110
  # basis for the method name when calling the endpoint using a generated client.
84
111
  def convert_route_to_id
@@ -126,6 +153,22 @@ module Apia
126
153
  "#{first_part}#{last_part}"
127
154
  end
128
155
 
156
+ # Returns an array of tags representing the group hierarchy for a given group.
157
+ #
158
+ # @param group [Group] The group for which to retrieve the tags.
159
+ # @return [Array<String>] An array of tags representing the group hierarchy.
160
+ def get_group_tags(group)
161
+ tags = []
162
+ current_group = group
163
+
164
+ while current_group
165
+ tags.unshift(current_group.name)
166
+ current_group = current_group.parent
167
+ end
168
+
169
+ tags
170
+ end
171
+
129
172
  end
130
173
  end
131
174
  end
@@ -41,7 +41,7 @@ module Apia
41
41
  specification = Specification.new(api_class, base_url, @options[:name])
42
42
  body = specification.json
43
43
 
44
- [200, { "Content-Type" => "application/json", "Content-Length" => body.bytesize.to_s }, [body]]
44
+ [200, { "content-type" => "application/json", "content-length" => body.bytesize.to_s }, [body]]
45
45
  end
46
46
 
47
47
  end
@@ -26,7 +26,9 @@ module Apia
26
26
  components: {
27
27
  schemas: {}
28
28
  },
29
- security: []
29
+ security: [],
30
+ tags: [],
31
+ "x-tagGroups": []
30
32
  }
31
33
 
32
34
  # path_ids is used to keep track of all the IDs of all the paths we've generated, to avoid duplicates
@@ -41,11 +43,20 @@ module Apia
41
43
 
42
44
  private
43
45
 
46
+ def sort_hash_by_nested_tag(hash)
47
+ hash.sort_by do |_, nested_hash|
48
+ nested_hash.values.first[:tags]&.first
49
+ end.to_h
50
+ end
51
+
44
52
  def build_spec
45
53
  add_info
46
54
  add_servers
47
55
  add_paths
48
56
  add_security
57
+ add_tag_groups
58
+
59
+ @spec[:paths] = sort_hash_by_nested_tag(@spec[:paths])
49
60
  end
50
61
 
51
62
  def add_info
@@ -85,6 +96,63 @@ module Apia
85
96
  end
86
97
  end
87
98
 
99
+ def get_tag_group_index(tag)
100
+ @spec[:"x-tagGroups"].each_with_index do |group, index|
101
+ return index if !group.nil? && group[:name] == tag
102
+ end
103
+
104
+ nil
105
+ end
106
+
107
+ # Adds tag groups to the OpenAPI specification.
108
+ #
109
+ # This method iterates over the paths in the specification and adds tag groups
110
+ # based on the tags specified for each method.
111
+ # It ensures that each tag is included in the `tags` array of the specification,
112
+ # and creates tag groups based on the order of the tags.
113
+ # Tag groups are represented by the `x-tagGroups` property in the specification.
114
+ # Tag groups are nested groups and are used to group tags together in documentation.
115
+ # A Tag *must* be included in a tag group. So if it is not part of a group / has no parent tag,
116
+ # it will be added to a group with the same name as the tag.
117
+ #
118
+ # @return [void]
119
+ def add_tag_groups
120
+ @spec[:paths].each_value do |methods|
121
+ methods.each_value do |method_spec|
122
+ method_spec[:tags].each_with_index do |tag, tag_index|
123
+ unless @spec[:tags].any? { |t| t[:name] == tag }
124
+ @spec[:tags] << { name: tag }
125
+ end
126
+
127
+ next if tag_index.zero?
128
+
129
+ tags = method_spec[:tags]
130
+
131
+ parent_tag = tags[tag_index - 1]
132
+ parent_index = get_tag_group_index(parent_tag)
133
+
134
+ if parent_index.nil? && tags.size > 1
135
+ @spec[:"x-tagGroups"] << { name: parent_tag, tags: [parent_tag] }
136
+ parent_index = @spec[:"x-tagGroups"].size - 1
137
+ end
138
+
139
+ unless @spec[:"x-tagGroups"][parent_index][:tags].include?(tag)
140
+ @spec[:"x-tagGroups"][parent_index][:tags] << tag
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ @spec[:tags].each do |tag|
147
+ unless @spec[:"x-tagGroups"].any? { |group| group[:tags].include?(tag[:name]) }
148
+ @spec[:"x-tagGroups"] << { name: tag[:name], tags: [tag[:name]] }
149
+ end
150
+ end
151
+
152
+ @spec[:"x-tagGroups"].sort_by! { |group| group[:name] }
153
+ @spec[:"x-tagGroups"].each { |group| group[:tags].sort! }
154
+ end
155
+
88
156
  end
89
157
  end
90
158
  end
@@ -3,7 +3,7 @@
3
3
  module Apia
4
4
  module OpenApi
5
5
 
6
- VERSION = "0.1.8"
6
+ VERSION = "0.1.9"
7
7
 
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apia-open_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Sturgess