apia-open_api 0.1.8 → 0.1.9

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
  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