tomograph 3.0.1 → 3.1.3

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: 6b82305a8afc3940fb54799c20a96c71685f1950addb5b0413572bb3ca6e5c2f
4
- data.tar.gz: eddef2bcfd9ba3f22d3cf4511e0e7ce6a32c28992e0c022602c499210b72c2a1
3
+ metadata.gz: ab901173a56d7c3bb3627dc8e2103e21b2e6b321ab30d3df2d9c9f97726c2598
4
+ data.tar.gz: 9360f36f0a9aefb4e4c63b833cc26ac9ee88b6fb203ff59c7165af4bc7711dc5
5
5
  SHA512:
6
- metadata.gz: 4843bb38871e842c26f63c6af9ac1d87fd5f153a56255c1b3d070eb35686c08b84c8279bf900d9dd4a0cf38fb9daff3b905bb58285e169c118ad7d36c7855b8c
7
- data.tar.gz: 3df3afd4cc5064d767dad8640f156bd39972a728927621ac740f332609b21a3533be36d71099208f527e7d290970ab0e59814bc5d00239135687e2015a9e8b9d
6
+ metadata.gz: ec6645d8dadd46bdb77a08b72083102d192b8e51381324fa36b0113f143f06dadf33d82e721c5f066f53e84dda109a9f9f4dc9c70512013faa0c8b8bfbdb3669
7
+ data.tar.gz: 834f29f892f7776e706d958573a2077347b2f7e06beafa55fed5ea85c59ff6a70751a1556e9682ce58a68c0bb9fe5db840dd7c1262c99d0f6aebe2abc662c838
@@ -23,10 +23,10 @@ jobs:
23
23
  - name: Set up Ruby
24
24
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
25
25
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
26
- # uses: ruby/setup-ruby@v1
27
- uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
26
+ uses: ruby/setup-ruby@v1
27
+ # uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
28
28
  with:
29
- ruby-version: 2.6
29
+ ruby-version: 2.7
30
30
  - name: Install dependencies
31
31
  run: bundle install
32
32
  - name: Run tests
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ TargetRubyVersion: 2.4
3
3
 
4
- Metrics/LineLength:
4
+ Layout/LineLength:
5
5
  Max: 120
6
6
 
7
7
  Style/Documentation:
@@ -12,3 +12,21 @@ Style/FrozenStringLiteralComment:
12
12
 
13
13
  Metrics/BlockLength:
14
14
  Enabled: false
15
+
16
+ Naming/MemoizedInstanceVariableName:
17
+ Enabled: false
18
+
19
+ Lint/DisjunctiveAssignmentInConstructor:
20
+ Enabled: false
21
+
22
+ Metrics/ParameterLists:
23
+ Enabled: false
24
+
25
+ Metrics/MethodLength:
26
+ Max: 40
27
+
28
+ Metrics/AbcSize:
29
+ Max: 90
30
+
31
+ Metrics/ClassLength:
32
+ Max: 150
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.1
1
+ 3.0.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Change log
2
2
 
3
+ ### 3.1.3 - 2021-11-09
4
+
5
+ * features
6
+ * rubocop style
7
+
8
+ ### 3.1.2 - 2021-09-28
9
+
10
+ * bug fixes
11
+ * fix parser last crafter version
12
+
13
+ ### 3.1.1 - 2021-02-10
14
+
15
+ * setting
16
+ * improve gemspec summary and description
17
+
18
+ ### 3.1.0 - 2021-02-09
19
+
20
+ * features
21
+ * support Swagger/OpenAPI 2.0 [#47](https://github.com/funbox/tomograph/issues/47)
22
+ * support OpenAPI 3.0 [#50](https://github.com/funbox/tomograph/issues/50)
23
+ * removed
24
+ * delete travis [#45](https://github.com/funbox/tomograph/issues/45)
25
+
3
26
  ### 3.0.1 - 2020-10-14
4
27
 
5
28
  * removed
data/README.md CHANGED
@@ -1,12 +1,86 @@
1
1
  # Tomograph
2
2
 
3
- [![Build Status](https://travis-ci.org/funbox/tomograph.svg?branch=master)](https://travis-ci.org/funbox/tomograph) [![Gem Version](https://badge.fury.io/rb/tomograph.svg)](https://badge.fury.io/rb/tomograph)
3
+ Convert API Blueprint, Swagger and OpenAPI to minimal routes with JSON Schema. For ease of use and creation of new tools.
4
4
 
5
- Convert API Blueprint to JSON Schema and search.
5
+ Will look like
6
6
 
7
- ## Installation
7
+ ```json
8
+ [
9
+ {
10
+ "path": "/sessions",
11
+ "method": "POST",
12
+ "content-type": "application/json",
13
+ "requests": [{
14
+ "$schema": "http://json-schema.org/draft-04/schema#",
15
+ "type": "object",
16
+ "properties": {
17
+ "login": {
18
+ "type": "string"
19
+ },
20
+ "password": {
21
+ "type": "string"
22
+ },
23
+ "captcha": {
24
+ "type": "string"
25
+ }
26
+ },
27
+ "required": [
28
+ "login",
29
+ "password"
30
+ ]
31
+ }],
32
+ "responses": [
33
+ {
34
+ "status": "401",
35
+ "content-type": "application/json",
36
+ "body": {}
37
+ },
38
+ {
39
+ "status": "429",
40
+ "content-type": "application/json",
41
+ "body": {}
42
+ },
43
+ {
44
+ "status": "201",
45
+ "content-type": "application/json",
46
+ "body": {
47
+ "$schema": "http://json-schema.org/draft-04/schema#",
48
+ "type": "object",
49
+ "properties": {
50
+ "confirmation": {
51
+ "type": "object",
52
+ "properties": {
53
+ "id": {
54
+ "type": "string"
55
+ },
56
+ "type": {
57
+ "type": "string"
58
+ },
59
+ "operation": {
60
+ "type": "string"
61
+ }
62
+ },
63
+ "required": [
64
+ "id",
65
+ "type",
66
+ "operation"
67
+ ]
68
+ },
69
+ "captcha": {
70
+ "type": "string"
71
+ },
72
+ "captcha_does_not_match": {
73
+ "type": "boolean"
74
+ }
75
+ }
76
+ }
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ ```
8
82
 
9
- First you need to install [drafter](https://github.com/apiaryio/drafter).
83
+ ## Installation
10
84
 
11
85
  Then add this line to your application's Gemfile:
12
86
 
@@ -28,36 +102,72 @@ $ gem install tomograph
28
102
 
29
103
  ## Usage
30
104
 
105
+ ### In code
106
+
107
+ #### OpenAPI 2.0
108
+
109
+ Also Swagger
110
+
31
111
  ```ruby
32
112
  require 'tomograph'
33
113
 
34
- tomogram = Tomograph::Tomogram.new(drafter_yaml_path: '/path/to/doc.yaml')
114
+ tomogram = Tomograph::Tomogram.new(openapi2_json_path: '/path/to/doc.json')
35
115
  ```
36
116
 
37
- ### Command line tool
117
+ #### OpenAPI 3.0
38
118
 
39
- CLI allows you to convert files from API Elements to JSON Schema.
119
+ Also OpenAPI
40
120
 
41
- ```bash
42
- tomograph doc.yaml doc.json
121
+ ```ruby
122
+ require 'tomograph'
123
+
124
+ tomogram = Tomograph::Tomogram.new(openapi3_yaml_path: '/path/to/doc.yaml')
43
125
  ```
44
126
 
45
- There is also support for documents pre-parsed by [drafter](https://github.com/apiaryio/drafter) versions 3 and 4, or `crafter`.
46
- To specify the handler version use the `-d` flag:
127
+ #### API Blueprint
128
+
129
+ First you need to install [drafter](https://github.com/apiaryio/drafter).
130
+ Works after conversion from API Blueprint to API Elements (in YAML file) with Drafter.
131
+
132
+ That is, I mean that you first need to do this
47
133
 
48
134
  ```bash
49
- tomograph -d 4 doc_by_drafter4.yaml doc.json
135
+ drafter doc.apib -o doc.yaml
50
136
  ```
51
137
 
52
- Run CLI with `-h` to get detailed help:
138
+ and then
53
139
 
54
- ```bash
55
- tomograph -h
140
+ ```ruby
141
+ require 'tomograph'
142
+
143
+ tomogram = Tomograph::Tomogram.new(drafter_yaml_path: '/path/to/doc.yaml')
144
+ ```
145
+
146
+ #### Tomograph
147
+
148
+ To use additional features of the pre-converted
149
+
150
+ ```ruby
151
+ require 'tomograph'
152
+
153
+ tomogram = Tomograph::Tomogram.new(tomogram_json_path: '/path/to/doc.json')
56
154
  ```
57
155
 
58
- ## Convert
156
+ #### prefix
157
+ Default: `''`
158
+
159
+ You can specify API prefix and path to the spec using one of the possible formats:
160
+
161
+ ```ruby
162
+ Tomograph::Tomogram.new(prefix: '/api/v2', drafter_yaml_path: '/path/to/doc.yaml')
163
+ ```
164
+
165
+ ```ruby
166
+ Tomograph::Tomogram.new(prefix: '/api/v2', tomogram_json_path: '/path/to/doc.json')
167
+ ```
59
168
 
60
- Use `to_json` for converting APIB to JSON:
169
+ #### to_json
170
+ Use `to_json` for converting to JSON, example from API Blueprint:
61
171
 
62
172
  ```ruby
63
173
  tomogram.to_json
@@ -65,7 +175,7 @@ tomogram.to_json
65
175
 
66
176
  <details>
67
177
  <summary>Example input</summary>
68
-
178
+
69
179
  ```apib
70
180
  FORMAT: 1A
71
181
  HOST: http://test.local
@@ -110,7 +220,7 @@ tomogram.to_json
110
220
 
111
221
  <details>
112
222
  <summary>Example output</summary>
113
-
223
+
114
224
  ```json
115
225
  [
116
226
  {
@@ -188,41 +298,35 @@ tomogram.to_json
188
298
  ```
189
299
  </details>
190
300
 
191
- ## Search
192
-
193
- Use these methods to search through parsed API Blueprint spec to get request => responses hash maps.
194
-
195
- ### `find_request`
301
+ #### to_a
302
+ ```ruby
303
+ tomogram.to_a
304
+ ```
196
305
 
306
+ #### find_request
197
307
  ```ruby
198
308
  request = tomogram.find_request(method: 'GET', path: '/status/1?qwe=rty')
199
309
  ```
200
310
 
201
- ### `find_request_with_content_type`
202
-
311
+ #### find_request_with_content_type
203
312
  ```ruby
204
313
  request = tomogram.find_request_with_content_type(method: 'GET', path: '/status/1?qwe=rty', content_type: 'application/json')
205
314
  ```
206
315
 
207
- ### `find_responses`
208
-
316
+ #### `find_responses`
209
317
  ```ruby
210
318
  responses = request.find_responses(status: '200')
211
319
  ```
212
320
 
213
- ## Other methods
214
-
215
- ### `prefix_match?`
216
-
321
+ #### prefix_match?
217
322
  This may be useful if you specify a prefix.
218
323
 
219
324
  ```ruby
220
325
  tomogram.prefix_match?('http://local/api/v2/users')
221
326
  ```
222
327
 
223
- ### `to_resources`
224
-
225
- Maps resources with possible requests.
328
+ #### to_resources
329
+ Maps resources for API Blueprint with possible requests.
226
330
 
227
331
  Example output:
228
332
 
@@ -232,39 +336,48 @@ Example output:
232
336
  }
233
337
  ```
234
338
 
235
- ## Constructor params
339
+ ### Command line tool
236
340
 
237
- You can specify API prefix and path to the spec using one of the possible formats:
341
+ CLI allows you to convert files from API Blueprint (API Elements), Swagger and OpenAPI to JSON Schema.
238
342
 
239
- ```ruby
240
- Tomograph::Tomogram.new(prefix: '/api/v2', drafter_yaml_path: '/path/to/doc.yaml')
241
- ```
343
+ Run CLI with `-h` to get detailed help:
242
344
 
243
- ```ruby
244
- Tomograph::Tomogram.new(prefix: '/api/v2', tomogram_json_path: '/path/to/doc.json')
345
+ ```bash
346
+ tomograph -h
245
347
  ```
246
348
 
247
- ### `drafter_yaml_path`
248
-
249
- Path to API Blueprint documentation pre-parsed with `drafter` and saved to a YAML file.
349
+ To specify the handler version use the `-d` flag:
250
350
 
251
- ### Drafter v4 & Crafter support
351
+ #### OpenAPI 2.0
352
+ ```bash
353
+ tomograph -d openapi2 openapi2.json tomogram.json
354
+ ```
252
355
 
253
- If you are using a `drafter v4`, you should use `drafter_yaml_path`.
356
+ #### OpenAPI 3.0
357
+ ```bash
358
+ tomograph -d openapi3 openapi3.yaml doc.json
359
+ ```
254
360
 
255
- In case when you want to use `сrafter`, then you should pass `crafter_yaml_path` respectively.
361
+ #### API Blueprint
362
+ ```bash
363
+ tomograph -d 4 apielemetns.yaml doc.json
364
+ ```
256
365
 
257
- ### `tomogram_json_path`
366
+ #### exclude-description
258
367
 
259
- Path to API Blueprint documentation converted with `tomograph` to a JSON file.
368
+ Exclude "description" keys from json-schemas.
260
369
 
261
- ### `prefix`
370
+ ```bash
371
+ tomograph -d 4 apielemetns.yaml doc.json --exclude-description
372
+ ```
262
373
 
263
- Default: `''`
374
+ #### split
264
375
 
265
- Prefix for API requests.
376
+ Split output into files by method. Output in dir path.
266
377
 
267
- Example: `'/api'`.
378
+ ```bash
379
+ tomograph -d 4 --split apielemetns.yaml jsons/
380
+ ```
268
381
 
269
382
  ## License
270
383
 
data/exe/tomograph CHANGED
@@ -7,12 +7,15 @@ require 'methadone'
7
7
  require 'tomograph'
8
8
  require 'tomograph/version'
9
9
 
10
+ # rubocop:disable Style/MixinUsage
10
11
  include Methadone::Main
11
12
  include Methadone::CLILogging
13
+ # rubocop:enable Style/MixinUsage
12
14
 
13
15
  version Tomograph::VERSION
14
16
  description 'Converts API Blueprint to JSON Schema'
15
- on('-d DRAFTER_VERSION', '--drafter', 'Choose drafter version: crafter or 4. Default: use drafter v.4.')
17
+ on('-d DRAFTER_VERSION', '--drafter', 'Choose drafter version: crafter or 4,
18
+ or OpenAPI version: openapi2 or openapi3. Default: use drafter v.4.')
16
19
  on('--exclude-description', 'Exclude "description" keys.')
17
20
  on('--split', 'Split output into files by method.')
18
21
  arg :input, 'path/to/doc.yaml (API Elements)'
@@ -33,6 +36,10 @@ def choose_drafter(opt_parser)
33
36
  :crafter
34
37
  when '4'
35
38
  :drafter_4
39
+ when 'openapi2'
40
+ :openapi2
41
+ when 'openapi3'
42
+ :openapi3
36
43
  when nil
37
44
  :drafter_4
38
45
  else
@@ -43,7 +50,7 @@ end
43
50
  def write_split_json(actions, output)
44
51
  FileUtils.mkdir_p(output)
45
52
  actions.clone.each do |action|
46
- json_name = "#{action.delete("path").to_s} #{action.delete("method")}.json"
53
+ json_name = "#{action.delete('path')} #{action.delete('method')}.json"
47
54
  [['/', '#'],
48
55
  ['{', '('],
49
56
  ['}', ')']].each do |pattern, replacement|
@@ -63,9 +70,11 @@ end
63
70
  main do |input, output|
64
71
  version = choose_drafter(options['drafter'])
65
72
  format_key = {
66
- crafter: :crafter_yaml_path,
67
- drafter_4: :drafter_yaml_path
68
- }[version]
73
+ crafter: :crafter_yaml_path,
74
+ drafter_4: :drafter_yaml_path,
75
+ openapi2: :openapi2_json_path,
76
+ openapi3: :openapi3_yaml_path
77
+ }[version]
69
78
 
70
79
  tomogram = Tomograph::Tomogram.new(format_key => input)
71
80
  actions = tomogram.to_a.map(&:to_hash)
@@ -18,9 +18,9 @@ module Tomograph
18
18
  end
19
19
 
20
20
  def content_type
21
- if @content.first['attributes'].has_key?('headers')
22
- @content.first['attributes']['headers']['content'][0]['content']['key']['content'] == 'Content-Type' ?
23
- @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
21
+ if @content.first['attributes'].key?('headers') &&
22
+ @content.first['attributes']['headers']['content'][0]['content']['key']['content'] == 'Content-Type'
23
+ @content.first['attributes']['headers']['content'][0]['content']['value']['content']
24
24
  end
25
25
  end
26
26
 
@@ -33,7 +33,11 @@ module Tomograph
33
33
 
34
34
  def json_schema(actions)
35
35
  schema_node = actions.find do |action|
36
- action && action['element'] == 'asset' && action['attributes']['contentType']['content'] == 'application/schema+json'
36
+ action &&
37
+ action.fetch('element', nil) == 'asset' &&
38
+ action.fetch('attributes', {})
39
+ .fetch('contentType', {})
40
+ .fetch('content', nil) == 'application/schema+json'
37
41
  end
38
42
  return {} unless schema_node
39
43
 
@@ -50,11 +54,14 @@ module Tomograph
50
54
  response['element'] == 'httpResponse' && response['attributes']
51
55
  end
52
56
  @responses = @responses.map do |response|
57
+ content_type = if response['attributes'].key?('headers')
58
+ response['attributes']['headers']['content'][0]['content']['value']['content']
59
+ end
60
+
53
61
  {
54
62
  'status' => response['attributes']['statusCode']['content'].to_s,
55
63
  'body' => json_schema(response['content']),
56
- 'content-type' => response['attributes'].has_key?('headers') ?
57
- response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
64
+ 'content-type' => content_type
58
65
  }
59
66
  end
60
67
  end
@@ -24,6 +24,7 @@ module Tomograph
24
24
 
25
25
  def group?(group)
26
26
  return false if group['element'] == 'resource'
27
+
27
28
  group['element'] != 'copy' && # Element is a human readable text
28
29
  group['meta']['classes']['content'][0]['content'] == 'resourceGroup' # skip Data Structures
29
30
  end
@@ -31,7 +32,9 @@ module Tomograph
31
32
  def resources
32
33
  @resources ||= groups.inject([]) do |result_groups, group|
33
34
  result_groups.push(group['content'].each_with_object([]) do |resource, result_resources|
34
- result_resources.push('resource' => resource, 'resource_path' => resource_path(resource)) if resource?(resource)
35
+ if resource?(resource)
36
+ result_resources.push('resource' => resource, 'resource_path' => resource_path(resource))
37
+ end
35
38
  end)
36
39
  end.flatten
37
40
  end
@@ -46,9 +49,12 @@ module Tomograph
46
49
 
47
50
  def transitions
48
51
  @transitions ||= resources.inject([]) do |result_resources, resource|
49
- result_resources.push(resource['resource']['content'].each_with_object([]) do |transition, result_transitions|
50
- result_transitions.push(transition_hash(transition, resource)) if transition?(transition)
51
- end)
52
+ result_resources.push(resource['resource']['content']
53
+ .each_with_object([]) do |transition, result_transitions|
54
+ if transition?(transition)
55
+ result_transitions.push(transition_hash(transition, resource))
56
+ end
57
+ end)
52
58
  end.flatten
53
59
  end
54
60
 
@@ -65,18 +71,22 @@ module Tomograph
65
71
  end
66
72
 
67
73
  def transition_path(transition, resource_path)
68
- transition['attributes'] && transition['attributes']['href'] && transition['attributes']['href']['content'] || resource_path
74
+ transition['attributes'] && transition['attributes']['href'] &&
75
+ transition['attributes']['href']['content'] || resource_path
69
76
  end
70
77
 
71
78
  def without_group_actions
72
79
  transitions.inject([]) do |result_transition, transition|
73
- result_transition.push(transition['transition']['content'].each_with_object([]) do |content, result_contents|
74
- result_contents.push(Tomograph::ApiBlueprint::Crafter::Yaml::Action.new(
75
- content['content'],
76
- transition['transition_path'],
77
- transition['resource']
78
- )) if action?(content)
79
- end)
80
+ result_transition.push(transition['transition']['content']
81
+ .each_with_object([]) do |content, result_contents|
82
+ next unless action?(content)
83
+
84
+ result_contents.push(Tomograph::ApiBlueprint::Crafter::Yaml::Action.new(
85
+ content['content'],
86
+ transition['transition_path'],
87
+ transition['resource']
88
+ ))
89
+ end)
80
90
  end
81
91
  end
82
92
 
@@ -18,9 +18,9 @@ module Tomograph
18
18
  end
19
19
 
20
20
  def content_type
21
- if @content.first['attributes'].has_key?('headers')
22
- @content.first['attributes']['headers']['content'][0]['content']['key']['content'] == 'Content-Type' ?
23
- @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
21
+ if @content.first['attributes'].key?('headers') &&
22
+ @content.first['attributes']['headers']['content'][0]['content']['key']['content'] == 'Content-Type'
23
+ @content.first['attributes']['headers']['content'][0]['content']['value']['content']
24
24
  end
25
25
  end
26
26
 
@@ -33,7 +33,8 @@ module Tomograph
33
33
 
34
34
  def json_schema(actions)
35
35
  schema_node = actions.find do |action|
36
- action && action['element'] == 'asset' && action['attributes']['contentType']['content'] == 'application/schema+json'
36
+ action && action['element'] == 'asset' &&
37
+ action['attributes']['contentType']['content'] == 'application/schema+json'
37
38
  end
38
39
  return {} unless schema_node
39
40
 
@@ -50,11 +51,14 @@ module Tomograph
50
51
  response['element'] == 'httpResponse' && response['attributes']
51
52
  end
52
53
  @responses = @responses.map do |response|
54
+ content_type = if response['attributes'].key?('headers')
55
+ response['attributes']['headers']['content'][0]['content']['value']['content']
56
+ end
57
+
53
58
  {
54
59
  'status' => response['attributes']['statusCode']['content'].to_s,
55
60
  'body' => json_schema(response['content']),
56
- 'content-type' => response['attributes'].has_key?('headers') ?
57
- response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
61
+ 'content-type' => content_type
58
62
  }
59
63
  end
60
64
  end
@@ -24,6 +24,7 @@ module Tomograph
24
24
 
25
25
  def group?(group)
26
26
  return false if group['element'] == 'resource'
27
+
27
28
  group['element'] != 'copy' && # Element is a human readable text
28
29
  group['meta']['classes']['content'][0]['content'] == 'resourceGroup' # skip Data Structures
29
30
  end
@@ -31,7 +32,9 @@ module Tomograph
31
32
  def resources
32
33
  @resources ||= groups.inject([]) do |result_groups, group|
33
34
  result_groups.push(group['content'].each_with_object([]) do |resource, result_resources|
34
- result_resources.push('resource' => resource, 'resource_path' => resource_path(resource)) if resource?(resource)
35
+ if resource?(resource)
36
+ result_resources.push('resource' => resource, 'resource_path' => resource_path(resource))
37
+ end
35
38
  end)
36
39
  end.flatten
37
40
  end
@@ -46,9 +49,12 @@ module Tomograph
46
49
 
47
50
  def transitions
48
51
  @transitions ||= resources.inject([]) do |result_resources, resource|
49
- result_resources.push(resource['resource']['content'].each_with_object([]) do |transition, result_transitions|
50
- result_transitions.push(transition_hash(transition, resource)) if transition?(transition)
51
- end)
52
+ result_resources.push(resource['resource']['content']
53
+ .each_with_object([]) do |transition, result_transitions|
54
+ if transition?(transition)
55
+ result_transitions.push(transition_hash(transition, resource))
56
+ end
57
+ end)
52
58
  end.flatten
53
59
  end
54
60
 
@@ -70,13 +76,16 @@ module Tomograph
70
76
 
71
77
  def without_group_actions
72
78
  transitions.inject([]) do |result_transition, transition|
73
- result_transition.push(transition['transition']['content'].each_with_object([]) do |content, result_contents|
74
- result_contents.push(Tomograph::ApiBlueprint::Drafter4::Yaml::Action.new(
75
- content['content'],
76
- transition['transition_path'],
77
- transition['resource']
78
- )) if action?(content)
79
- end)
79
+ result_transition.push(transition['transition']['content']
80
+ .each_with_object([]) do |content, result_contents|
81
+ next unless action?(content)
82
+
83
+ result_contents.push(Tomograph::ApiBlueprint::Drafter4::Yaml::Action.new(
84
+ content['content'],
85
+ transition['transition_path'],
86
+ transition['resource']
87
+ ))
88
+ end)
80
89
  end
81
90
  end
82
91
 
@@ -12,11 +12,12 @@ module Tomograph
12
12
  @tomogram ||= @documentation.inject([]) do |result, action|
13
13
  result.push(Tomograph::Tomogram::Action.new(
14
14
  path: "#{@prefix}#{action['path']}",
15
- method: action['method'],
15
+ method: action['method'],
16
16
  content_type: action['content-type'],
17
17
  requests: action['requests'],
18
18
  responses: action['responses'],
19
- resource: action['resource']))
19
+ resource: action['resource']
20
+ ))
20
21
  end
21
22
  end
22
23
 
@@ -0,0 +1,88 @@
1
+ require 'tomograph/tomogram/action'
2
+
3
+ module Tomograph
4
+ module OpenApi
5
+ class OpenApi2
6
+ def initialize(prefix, json_schema_path)
7
+ @prefix = prefix
8
+ @documentation = JSON.parse(File.read(json_schema_path))
9
+ end
10
+
11
+ def to_tomogram
12
+ @tomogram ||= @documentation['paths'].each_with_object([]) do |action, result|
13
+ action[1].keys.each do |method|
14
+ result.push(Tomograph::Tomogram::Action.new(
15
+ path: "#{@prefix}#{action[0]}",
16
+ method: method.upcase,
17
+ content_type: '',
18
+ requests: [],
19
+ responses: responses(action[1][method]['responses'], @documentation['definitions']),
20
+ resource: ''
21
+ ))
22
+ end
23
+ end
24
+ end
25
+
26
+ def responses(resp, defi)
27
+ resp.inject([]) do |result, reponse|
28
+ if reponse[1]['schema']
29
+ result.push(
30
+ status: reponse[0],
31
+ body: schema(reponse[1]['schema'], defi),
32
+ 'content-type': ''
33
+ )
34
+ else
35
+ result.push(
36
+ status: reponse[0],
37
+ body: {},
38
+ 'content-type': ''
39
+ )
40
+ end
41
+ end
42
+ end
43
+
44
+ def schema(sche, defi)
45
+ if sche.keys.include?('$ref')
46
+ res = sche.merge('definitions' => { sche['$ref'][14..-1] => defi[sche['$ref'][14..-1]] })
47
+ if defi[sche['$ref'][14..-1]].to_s.include?('$ref')
48
+ keys = defi[sche['$ref'][14..-1]].to_s.split('"').find_all { |word| word.include?('definitions') }
49
+ keys.each do |key|
50
+ res['definitions'].merge!({ key[14..-1] => defi[key[14..-1]] })
51
+ end
52
+ end
53
+ res
54
+ elsif sche.to_s.include?('$ref')
55
+ res = sche.merge('definitions' => {})
56
+ keys = sche.to_s.split('"').find_all { |word| word.include?('definitions') }
57
+ keys.each do |key|
58
+ res['definitions'].merge!({ key[14..-1] => defi[key[14..-1]] })
59
+ end
60
+ res
61
+ else
62
+ sche
63
+ end
64
+ end
65
+
66
+ def search_hash(hash, key)
67
+ return hash[key] if hash.assoc(key)
68
+
69
+ hash.delete_if { |_key, value| value.class != Hash }
70
+ new_hash = {}
71
+ hash.each_value { |values| new_hash.merge!(values) }
72
+ search_hash(new_hash, key) unless new_hash.empty?
73
+ end
74
+
75
+ def to_resources
76
+ return @to_resources if @to_resources
77
+
78
+ @to_resources = @documentation.group_by { |action| action['resource'] }
79
+ @to_resources = @to_resources.each_with_object({}) do |(resource, actions), resource_map|
80
+ requests = actions.map do |action|
81
+ "#{action['method']} #{@prefix}#{action['path']}"
82
+ end
83
+ resource_map[resource] = requests
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,115 @@
1
+ require 'tomograph/tomogram/action'
2
+
3
+ module Tomograph
4
+ module OpenApi
5
+ class OpenApi3
6
+ def initialize(prefix, openapi3_yaml_path)
7
+ @prefix = prefix
8
+ @documentation = YAML.safe_load(File.read(openapi3_yaml_path))
9
+ end
10
+
11
+ def to_tomogram
12
+ @tomogram ||= @documentation['paths'].each_with_object([]) do |action, result|
13
+ action[1].keys.each do |method|
14
+ result.push(Tomograph::Tomogram::Action.new(
15
+ path: "#{@prefix}#{action[0]}",
16
+ method: method.upcase,
17
+ content_type: '',
18
+ requests: [],
19
+ responses: responses(action[1][method]['responses'], @documentation['components']['schemas']),
20
+ resource: ''
21
+ ))
22
+ end
23
+ end
24
+ end
25
+
26
+ def responses(resp, defi)
27
+ resp.inject([]) do |result, response|
28
+ if response[1]['content'].nil?
29
+ # TODO: 403Forbidden
30
+ result.push(
31
+ status: response[0],
32
+ body: {},
33
+ 'content-type': ''
34
+ )
35
+ elsif response[1]['content'].values[0]['schema']
36
+ result.push(
37
+ status: response[0],
38
+ body: schema(response[1]['content'].values[0]['schema'], defi),
39
+ 'content-type': ''
40
+ )
41
+ else
42
+ result.push(
43
+ status: response[0],
44
+ body: {},
45
+ 'content-type': ''
46
+ )
47
+ end
48
+ end
49
+ end
50
+
51
+ def schema(sche, defi)
52
+ if sche.keys.include?('$ref')
53
+ sche.merge!('components' => {})
54
+ sche['components'].merge!('schemas' => {})
55
+ sche['components']['schemas'].merge!({ sche['$ref'][21..-1] => defi[sche['$ref'][21..-1]] })
56
+
57
+ if defi[sche['$ref'][21..-1]].to_s.include?('$ref')
58
+ keys = defi[sche['$ref'][21..-1]].to_s.split('"').find_all { |word| word.include?('#/components/schemas/') }
59
+ keys.each do |key|
60
+ sche['components']['schemas'].merge!({ key[21..-1] => defi[key[21..-1]] })
61
+
62
+ next unless defi[key[21..-1]].to_s.include?('$ref')
63
+
64
+ keys2 = defi[key[21..-1]].to_s.split('"').find_all { |word| word.include?('#/components/schemas/') }
65
+ keys2.each do |key2|
66
+ sche['components']['schemas'].merge!({ key2[21..-1] => defi[key2[21..-1]] })
67
+
68
+ next unless defi[key2[21..-1]].to_s.include?('$ref')
69
+
70
+ keys3 = defi[key2[21..-1]].to_s.split('"')
71
+ .find_all { |word| word.include?('#/components/schemas/') }
72
+ .uniq
73
+ keys3.each do |key3|
74
+ sche['components']['schemas'].merge!({ key3[21..-1] => defi[key3[21..-1]] })
75
+ end
76
+ end
77
+ end
78
+ end
79
+ sche
80
+
81
+ elsif sche.to_s.include?('$ref')
82
+ res = sche.merge('definitions' => {})
83
+ keys = sche.to_s.split('"').find_all { |word| word.include?('definitions') }
84
+ keys.each do |key|
85
+ res['definitions'].merge!({ key[21..-1] => defi[key[21..-1]] })
86
+ end
87
+ res
88
+ else
89
+ sche
90
+ end
91
+ end
92
+
93
+ def search_hash(hash, key)
94
+ return hash[key] if hash.assoc(key)
95
+
96
+ hash.delete_if { |_key, value| value.class != Hash }
97
+ new_hash = {}
98
+ hash.each_value { |values| new_hash.merge!(values) }
99
+ search_hash(new_hash, key) unless new_hash.empty?
100
+ end
101
+
102
+ def to_resources
103
+ return @to_resources if @to_resources
104
+
105
+ @to_resources = @documentation.group_by { |action| action['resource'] }
106
+ @to_resources = @to_resources.each_with_object({}) do |(resource, actions), resource_map|
107
+ requests = actions.map do |action|
108
+ "#{action['method']} #{@prefix}#{action['path']}"
109
+ end
110
+ resource_map[resource] = requests
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -32,7 +32,7 @@ module Tomograph
32
32
  end
33
33
 
34
34
  def ==(other)
35
- other.instance_of? self.class and other.path == path
35
+ other.instance_of?(self.class) && (other.path == path)
36
36
  end
37
37
 
38
38
  private
@@ -3,16 +3,27 @@ require 'tomograph/path'
3
3
  require 'tomograph/api_blueprint/json_schema'
4
4
  require 'tomograph/api_blueprint/drafter_4/yaml'
5
5
  require 'tomograph/api_blueprint/crafter/yaml'
6
+ require 'tomograph/openapi/openapi2'
7
+ require 'tomograph/openapi/openapi3'
6
8
 
7
9
  module Tomograph
8
10
  class Tomogram
9
11
  extend Gem::Deprecate
10
12
 
11
- def initialize(prefix: '', drafter_yaml_path: nil, tomogram_json_path: nil, crafter_yaml_path: nil)
13
+ def initialize(prefix: '',
14
+ drafter_yaml_path: nil,
15
+ tomogram_json_path: nil,
16
+ crafter_yaml_path: nil,
17
+ openapi2_json_path: nil,
18
+ openapi3_yaml_path: nil)
12
19
  @documentation = if tomogram_json_path
13
20
  Tomograph::ApiBlueprint::JsonSchema.new(prefix, tomogram_json_path)
14
21
  elsif crafter_yaml_path
15
22
  Tomograph::ApiBlueprint::Crafter::Yaml.new(prefix, crafter_yaml_path)
23
+ elsif openapi2_json_path
24
+ Tomograph::OpenApi::OpenApi2.new(prefix, openapi2_json_path)
25
+ elsif openapi3_yaml_path
26
+ Tomograph::OpenApi::OpenApi3.new(prefix, openapi3_yaml_path)
16
27
  else
17
28
  Tomograph::ApiBlueprint::Drafter4::Yaml.new(prefix, drafter_yaml_path)
18
29
  end
@@ -23,12 +34,7 @@ module Tomograph
23
34
  @actions ||= @documentation.to_tomogram
24
35
  end
25
36
 
26
- def to_hash
27
- to_a.map(&:to_hash)
28
- end
29
- deprecate :to_hash, 'to_a with method access', 2018, 8
30
-
31
- def to_json
37
+ def to_json(*_args)
32
38
  JSON.pretty_generate(to_a.map(&:to_hash))
33
39
  end
34
40
 
@@ -1,3 +1,3 @@
1
1
  module Tomograph
2
- VERSION = '3.0.1'.freeze
2
+ VERSION = '3.1.3'.freeze
3
3
  end
data/tomograph.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'tomograph/version'
4
4
 
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['d.efimov']
9
9
  spec.email = ['d.efimov@fun-box.ru']
10
10
 
11
- spec.summary = 'Convert API Blueprint to Tomogram'
12
- spec.description = 'Convert API Blueprint to routes and JSON-Schemas'
11
+ spec.summary = 'Convert API Blueprint, Swagger and OpenAPI to Tomogram'
12
+ spec.description = 'Convert API Blueprint, Swagger and OpenAPI to routes and JSON-Schemas'
13
13
  spec.homepage = 'https://github.com/funbox/tomograph'
14
14
  spec.license = 'MIT'
15
15
 
@@ -20,9 +20,10 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_runtime_dependency 'methadone', '~> 2', '>= 2.0.2'
22
22
  spec.add_development_dependency 'byebug', '~> 11.1', '>= 11.1.1'
23
+ spec.add_development_dependency 'json-schema', '~> 2.8', '>= 2.8.1'
23
24
  spec.add_development_dependency 'rake', '>= 13.0.1'
24
- spec.add_development_dependency 'rspec', '~> 3.9', '>= 3.9.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.10', '>= 3.10.0'
25
26
  spec.add_development_dependency 'rubocop', '~> 0.81', '>= 0.81.0'
26
- spec.add_development_dependency 'simplecov', '~> 0.18', '>= 0.18.5'
27
+ spec.add_development_dependency 'simplecov', '~> 0.21', '>= 0.21.2'
27
28
  spec.required_ruby_version = '>= 2.4.0'
28
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomograph
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - d.efimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-14 00:00:00.000000000 Z
11
+ date: 2021-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: methadone
@@ -50,6 +50,26 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 11.1.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: json-schema
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.8'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.8.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.8'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 2.8.1
53
73
  - !ruby/object:Gem::Dependency
54
74
  name: rake
55
75
  requirement: !ruby/object:Gem::Requirement
@@ -70,20 +90,20 @@ dependencies:
70
90
  requirements:
71
91
  - - "~>"
72
92
  - !ruby/object:Gem::Version
73
- version: '3.9'
93
+ version: '3.10'
74
94
  - - ">="
75
95
  - !ruby/object:Gem::Version
76
- version: 3.9.0
96
+ version: 3.10.0
77
97
  type: :development
78
98
  prerelease: false
79
99
  version_requirements: !ruby/object:Gem::Requirement
80
100
  requirements:
81
101
  - - "~>"
82
102
  - !ruby/object:Gem::Version
83
- version: '3.9'
103
+ version: '3.10'
84
104
  - - ">="
85
105
  - !ruby/object:Gem::Version
86
- version: 3.9.0
106
+ version: 3.10.0
87
107
  - !ruby/object:Gem::Dependency
88
108
  name: rubocop
89
109
  requirement: !ruby/object:Gem::Requirement
@@ -110,21 +130,21 @@ dependencies:
110
130
  requirements:
111
131
  - - "~>"
112
132
  - !ruby/object:Gem::Version
113
- version: '0.18'
133
+ version: '0.21'
114
134
  - - ">="
115
135
  - !ruby/object:Gem::Version
116
- version: 0.18.5
136
+ version: 0.21.2
117
137
  type: :development
118
138
  prerelease: false
119
139
  version_requirements: !ruby/object:Gem::Requirement
120
140
  requirements:
121
141
  - - "~>"
122
142
  - !ruby/object:Gem::Version
123
- version: '0.18'
143
+ version: '0.21'
124
144
  - - ">="
125
145
  - !ruby/object:Gem::Version
126
- version: 0.18.5
127
- description: Convert API Blueprint to routes and JSON-Schemas
146
+ version: 0.21.2
147
+ description: Convert API Blueprint, Swagger and OpenAPI to routes and JSON-Schemas
128
148
  email:
129
149
  - d.efimov@fun-box.ru
130
150
  executables:
@@ -137,7 +157,6 @@ files:
137
157
  - ".rubocop.yml"
138
158
  - ".ruby-version"
139
159
  - ".tool-versions"
140
- - ".travis.yml"
141
160
  - CHANGELOG.md
142
161
  - CODE_OF_CONDUCT.md
143
162
  - Gemfile
@@ -153,6 +172,8 @@ files:
153
172
  - lib/tomograph/api_blueprint/drafter_4/yaml.rb
154
173
  - lib/tomograph/api_blueprint/drafter_4/yaml/action.rb
155
174
  - lib/tomograph/api_blueprint/json_schema.rb
175
+ - lib/tomograph/openapi/openapi2.rb
176
+ - lib/tomograph/openapi/openapi3.rb
156
177
  - lib/tomograph/path.rb
157
178
  - lib/tomograph/tomogram.rb
158
179
  - lib/tomograph/tomogram/action.rb
@@ -181,5 +202,5 @@ requirements: []
181
202
  rubygems_version: 3.1.2
182
203
  signing_key:
183
204
  specification_version: 4
184
- summary: Convert API Blueprint to Tomogram
205
+ summary: Convert API Blueprint, Swagger and OpenAPI to Tomogram
185
206
  test_files: []
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.4
4
- - 2.5
5
- - 2.6
6
- - 2.7