tomograph 3.0.1 → 3.1.3

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