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 +4 -4
- data/.github/workflows/ruby.yml +3 -3
- data/.rubocop.yml +20 -2
- data/.ruby-version +1 -1
- data/CHANGELOG.md +23 -0
- data/README.md +167 -54
- data/exe/tomograph +14 -5
- data/lib/tomograph/api_blueprint/crafter/yaml/action.rb +13 -6
- data/lib/tomograph/api_blueprint/crafter/yaml.rb +22 -12
- data/lib/tomograph/api_blueprint/drafter_4/yaml/action.rb +10 -6
- data/lib/tomograph/api_blueprint/drafter_4/yaml.rb +20 -11
- data/lib/tomograph/api_blueprint/json_schema.rb +3 -2
- data/lib/tomograph/openapi/openapi2.rb +88 -0
- data/lib/tomograph/openapi/openapi3.rb +115 -0
- data/lib/tomograph/path.rb +1 -1
- data/lib/tomograph/tomogram.rb +13 -7
- data/lib/tomograph/version.rb +1 -1
- data/tomograph.gemspec +6 -5
- metadata +34 -13
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab901173a56d7c3bb3627dc8e2103e21b2e6b321ab30d3df2d9c9f97726c2598
|
4
|
+
data.tar.gz: 9360f36f0a9aefb4e4c63b833cc26ac9ee88b6fb203ff59c7165af4bc7711dc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec6645d8dadd46bdb77a08b72083102d192b8e51381324fa36b0113f143f06dadf33d82e721c5f066f53e84dda109a9f9f4dc9c70512013faa0c8b8bfbdb3669
|
7
|
+
data.tar.gz: 834f29f892f7776e706d958573a2077347b2f7e06beafa55fed5ea85c59ff6a70751a1556e9682ce58a68c0bb9fe5db840dd7c1262c99d0f6aebe2abc662c838
|
data/.github/workflows/ruby.yml
CHANGED
@@ -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
|
-
|
27
|
-
|
26
|
+
uses: ruby/setup-ruby@v1
|
27
|
+
# uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
|
28
28
|
with:
|
29
|
-
ruby-version: 2.
|
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.
|
2
|
+
TargetRubyVersion: 2.4
|
3
3
|
|
4
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
5
|
+
Will look like
|
6
6
|
|
7
|
-
|
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
|
-
|
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(
|
114
|
+
tomogram = Tomograph::Tomogram.new(openapi2_json_path: '/path/to/doc.json')
|
35
115
|
```
|
36
116
|
|
37
|
-
|
117
|
+
#### OpenAPI 3.0
|
38
118
|
|
39
|
-
|
119
|
+
Also OpenAPI
|
40
120
|
|
41
|
-
```
|
42
|
-
tomograph
|
121
|
+
```ruby
|
122
|
+
require 'tomograph'
|
123
|
+
|
124
|
+
tomogram = Tomograph::Tomogram.new(openapi3_yaml_path: '/path/to/doc.yaml')
|
43
125
|
```
|
44
126
|
|
45
|
-
|
46
|
-
|
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
|
-
|
135
|
+
drafter doc.apib -o doc.yaml
|
50
136
|
```
|
51
137
|
|
52
|
-
|
138
|
+
and then
|
53
139
|
|
54
|
-
```
|
55
|
-
tomograph
|
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
|
-
|
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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
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
|
-
|
208
|
-
|
316
|
+
#### `find_responses`
|
209
317
|
```ruby
|
210
318
|
responses = request.find_responses(status: '200')
|
211
319
|
```
|
212
320
|
|
213
|
-
|
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
|
-
|
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
|
-
|
339
|
+
### Command line tool
|
236
340
|
|
237
|
-
|
341
|
+
CLI allows you to convert files from API Blueprint (API Elements), Swagger and OpenAPI to JSON Schema.
|
238
342
|
|
239
|
-
|
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
|
-
```
|
244
|
-
|
345
|
+
```bash
|
346
|
+
tomograph -h
|
245
347
|
```
|
246
348
|
|
247
|
-
|
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
|
-
|
351
|
+
#### OpenAPI 2.0
|
352
|
+
```bash
|
353
|
+
tomograph -d openapi2 openapi2.json tomogram.json
|
354
|
+
```
|
252
355
|
|
253
|
-
|
356
|
+
#### OpenAPI 3.0
|
357
|
+
```bash
|
358
|
+
tomograph -d openapi3 openapi3.yaml doc.json
|
359
|
+
```
|
254
360
|
|
255
|
-
|
361
|
+
#### API Blueprint
|
362
|
+
```bash
|
363
|
+
tomograph -d 4 apielemetns.yaml doc.json
|
364
|
+
```
|
256
365
|
|
257
|
-
|
366
|
+
#### exclude-description
|
258
367
|
|
259
|
-
|
368
|
+
Exclude "description" keys from json-schemas.
|
260
369
|
|
261
|
-
|
370
|
+
```bash
|
371
|
+
tomograph -d 4 apielemetns.yaml doc.json --exclude-description
|
372
|
+
```
|
262
373
|
|
263
|
-
|
374
|
+
#### split
|
264
375
|
|
265
|
-
|
376
|
+
Split output into files by method. Output in dir path.
|
266
377
|
|
267
|
-
|
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
|
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(
|
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
|
-
|
67
|
-
|
68
|
-
|
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'].
|
22
|
-
|
23
|
-
|
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 &&
|
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' =>
|
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
|
-
|
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']
|
50
|
-
|
51
|
-
|
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'] &&
|
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']
|
74
|
-
|
75
|
-
content
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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'].
|
22
|
-
|
23
|
-
|
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' &&
|
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' =>
|
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
|
-
|
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']
|
50
|
-
|
51
|
-
|
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']
|
74
|
-
|
75
|
-
content
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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:
|
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
|
data/lib/tomograph/path.rb
CHANGED
data/lib/tomograph/tomogram.rb
CHANGED
@@ -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: '',
|
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
|
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
|
|
data/lib/tomograph/version.rb
CHANGED
data/tomograph.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path('
|
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.
|
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.
|
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.
|
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:
|
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.
|
93
|
+
version: '3.10'
|
74
94
|
- - ">="
|
75
95
|
- !ruby/object:Gem::Version
|
76
|
-
version: 3.
|
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.
|
103
|
+
version: '3.10'
|
84
104
|
- - ">="
|
85
105
|
- !ruby/object:Gem::Version
|
86
|
-
version: 3.
|
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.
|
133
|
+
version: '0.21'
|
114
134
|
- - ">="
|
115
135
|
- !ruby/object:Gem::Version
|
116
|
-
version: 0.
|
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.
|
143
|
+
version: '0.21'
|
124
144
|
- - ">="
|
125
145
|
- !ruby/object:Gem::Version
|
126
|
-
version: 0.
|
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: []
|