tomograph 2.4.2 → 2.5.0

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
  SHA1:
3
- metadata.gz: 16ea0b414a1b2c95a82f5035141be6412fb2d395
4
- data.tar.gz: 5003e6f8f76620e8c404957e6359e62a3770f67b
3
+ metadata.gz: 937a82ea94c38bdfbb1a92a6710936c7d525e228
4
+ data.tar.gz: 33cf0b7e2a4643acf32175e22c9ade017e3db49d
5
5
  SHA512:
6
- metadata.gz: a3a1dbcb0f139cf0a219f1ec273afa77ad7b353d50cf418f196aa43561b9854df454aa66a67c4c2f5f6fd4d98f6203b9bc4473ae2646d9fd81e52e97722e0dac
7
- data.tar.gz: 69b79ba35535e8b4e3e1f0a43258553e8cd3826af5a2d58b19a07f7b63b03f759f0512c402f00edd087383958968d48a3df9e65d8753a610a7ee4dd0a44bd2ae
6
+ metadata.gz: a88be0b668cce03d6c6b2a13fca948bc620cd92c21936de32189db078f1872fe67b1a63c7a3e93da3352d9eeee755583f2406aac92691e268676dff65b6ac050
7
+ data.tar.gz: 9d07f3e96dfd6ba0c7075682c048719072c2cb6c3df22754703de42371f3bc5c6bed63af18c069076f0d80ca47f82dc3221db3d8e4c45064ec0607d4e5954a4d
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  .byebug_history
4
4
  Gemfile.lock
5
5
  coverage
6
+ .bundle/
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.2.10
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change log
2
2
 
3
+ ### 2.5.0 - 2018-05-28
4
+
5
+ * features
6
+ * аdded support for documents with pre-parsed by drafter 4.
7
+
3
8
  ### 2.4.2 - 2018-11-29
4
9
 
5
10
  * bug fixes
data/README.md CHANGED
@@ -38,11 +38,15 @@ The command line tool allows you to convert files from API Blueprint or API Elem
38
38
  ```
39
39
  tomograph doc.apib doc.json
40
40
  ```
41
+ Now there is support for documents pre-parsed by [drafter](https://github.com/apiaryio/drafter) versions 3 and 4. To select the handler version, use the -d key and specify the required version. For example:
42
+ ```
43
+ tomograph -d 4 doc_by_drafter4.yaml doc.json
44
+ ```
41
45
  See
42
46
  ```
43
47
  tomograph -h
44
48
  ```
45
- for details on usage.
49
+ for more details on usage.
46
50
 
47
51
  ## Convert
48
52
 
@@ -228,6 +232,10 @@ Path to API Blueprint documentation. There must be an installed [drafter](https:
228
232
 
229
233
  Path to API Blueprint documentation pre-parsed with `drafter` and saved to a YAML file.
230
234
 
235
+ Drafter v.4
236
+
237
+ If you are using a `drafter v.4`, then you need to use the following parameters`drafter_4_apib_path` and `drafter_4_yaml_path` respectively.
238
+
231
239
  ### tomogram_json_path
232
240
 
233
241
  Path to API Blueprint documentation converted with `tomograph` to a JSON file.
data/exe/tomograph CHANGED
@@ -7,12 +7,12 @@ require 'methadone'
7
7
  require 'tomograph'
8
8
  require 'tomograph/version'
9
9
 
10
-
11
10
  include Methadone::Main
12
11
  include Methadone::CLILogging
13
12
 
14
13
  version Tomograph::VERSION
15
14
  description 'Converts API Blueprint to JSON Schema'
15
+ on('-d DRAFTER_VERSION', '--drafter', 'Choose drafter version: crafter, 3 or 4. Default: use drafter v.3.')
16
16
  on('-f INPUT_FORMAT', '--format', 'Force input format: "apib" or "yaml". Default: detect by file extension.')
17
17
  on('--exclude-description', 'Exclude "description" keys.')
18
18
  on('--split', 'Split output into files by method.')
@@ -48,6 +48,21 @@ def guess_format(opt_format, input)
48
48
  end
49
49
  end
50
50
 
51
+ def choose_drafter(opt_parser)
52
+ case opt_parser
53
+ when 'crafter'
54
+ :crafter
55
+ when '3'
56
+ :drafter_3
57
+ when '4'
58
+ :drafter_4
59
+ when nil
60
+ :drafter_3
61
+ else
62
+ raise 'Unsupported drafter version!'
63
+ end
64
+ end
65
+
51
66
  def write_split_json(actions, output)
52
67
  FileUtils.mkdir_p(output)
53
68
  actions.clone.each do |action|
@@ -70,20 +85,31 @@ end
70
85
 
71
86
  main do |input, output|
72
87
  format = guess_format(options['format'], input)
88
+ version = choose_drafter(options['drafter'])
73
89
  format_key = case format
74
90
  when :apib
75
- :apib_path
91
+ if version == :drafter_3
92
+ :apib_path
93
+ elsif version == :crafter
94
+ :crafter_apib_path
95
+ else
96
+ :drafter_4_apib_path
97
+ end
76
98
  when :yaml
77
- :drafter_yaml_path
99
+ if version == :drafter_3
100
+ :drafter_yaml_path
101
+ elsif version == :crafter
102
+ :crafter_yaml_path
103
+ else
104
+ :drafter_4_yaml_path
105
+ end
78
106
  else
79
107
  fail NotImplementedError
80
108
  end
81
109
  tomogram = Tomograph::Tomogram.new(format_key => input)
82
110
  actions = tomogram.to_a.map(&:to_hash)
83
111
 
84
- if options['exclude-description']
85
- prune!(actions, 'description')
86
- end
112
+ prune!(actions, 'description') if options['exclude-description']
87
113
 
88
114
  if options['split']
89
115
  write_split_json(actions, output)
@@ -0,0 +1,63 @@
1
+ require 'tomograph/tomogram/action'
2
+
3
+ module Tomograph
4
+ module ApiBlueprint
5
+ class Crafter
6
+ class Yaml
7
+ class Action
8
+ def initialize(content, path, resource)
9
+ @content = content
10
+ @path = path
11
+ @resource = resource
12
+ end
13
+
14
+ attr_reader :path, :resource
15
+
16
+ def method
17
+ @method ||= @content.first['attributes']['method']['content']
18
+ end
19
+
20
+ def content_type
21
+ @content_type ||= @content.first['attributes'].has_key?('headers') ?
22
+ @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
23
+ end
24
+
25
+ def request
26
+ return @request if @request
27
+
28
+ request_action = @content.find { |el| el['element'] == 'httpRequest' }
29
+ @request = json_schema(request_action['content'])
30
+ end
31
+
32
+ def json_schema(actions)
33
+ schema_node = actions.find do |action|
34
+ action && action['element'] == 'asset' && action['attributes']['contentType']['content'] == 'application/schema+json'
35
+ end
36
+ return {} unless schema_node
37
+
38
+ MultiJson.load(schema_node['content'])
39
+ rescue MultiJson::ParseError => e
40
+ puts "[Tomograph] Error while parsing #{e}. skipping..."
41
+ {}
42
+ end
43
+
44
+ def responses
45
+ return @responses if @responses
46
+
47
+ @responses = @content.select do |response|
48
+ response['element'] == 'httpResponse' && response['attributes']
49
+ end
50
+ @responses = @responses.map do |response|
51
+ {
52
+ 'status' => response['attributes']['statusCode']['content'],
53
+ 'body' => json_schema(response['content']),
54
+ 'content-type' => response['attributes'].has_key?('headers') ?
55
+ response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,130 @@
1
+ require 'yaml'
2
+ require 'tomograph/api_blueprint/crafter/yaml/action'
3
+ require 'tomograph/tomogram/action'
4
+
5
+ module Tomograph
6
+ module ApiBlueprint
7
+ class Crafter
8
+ class Yaml
9
+ def initialize(prefix, apib_path, drafter_yaml_path)
10
+ @prefix = prefix
11
+ @documentation = if apib_path
12
+ YAML.safe_load(`drafter #{apib_path}`)
13
+ elsif drafter_yaml_path
14
+ YAML.safe_load(File.read(drafter_yaml_path))
15
+ end
16
+ end
17
+
18
+ def groups
19
+ @groups ||= @documentation['content'][0]['content'].each_with_object([]) do |group, result_groups|
20
+ result_groups.push(group) if group?(group)
21
+ result_groups.push('content' => [group]) if single_resource?(group)
22
+ end
23
+ end
24
+
25
+ def single_resource?(group)
26
+ group['element'] == 'resource'
27
+ end
28
+
29
+ def group?(group)
30
+ return false if group['element'] == 'resource'
31
+ group['element'] != 'copy' && # Element is a human readable text
32
+ group['meta']['classes'][0] == 'resourceGroup' # skip Data Structures
33
+ end
34
+
35
+ def resources
36
+ @resources ||= groups.inject([]) do |result_groups, group|
37
+ result_groups.push(group['content'].each_with_object([]) do |resource, result_resources|
38
+ result_resources.push('resource' => resource, 'resource_path' => resource_path(resource)) if resource?(resource)
39
+ end)
40
+ end.flatten
41
+ end
42
+
43
+ def resource?(resource)
44
+ resource['element'] != 'copy' # Element is a human readable text
45
+ end
46
+
47
+ def resource_path(resource)
48
+ resource['attributes'] && resource['attributes']['href']['content']
49
+ end
50
+
51
+ def transitions
52
+ @transitions ||= resources.inject([]) do |result_resources, resource|
53
+ result_resources.push(resource['resource']['content'].each_with_object([]) do |transition, result_transitions|
54
+ result_transitions.push(transition_hash(transition, resource)) if transition?(transition)
55
+ end)
56
+ end.flatten
57
+ end
58
+
59
+ def transition?(transition)
60
+ transition['element'] == 'transition'
61
+ end
62
+
63
+ def transition_hash(transition, resource)
64
+ {
65
+ 'transition' => transition,
66
+ 'transition_path' => transition_path(transition, resource['resource_path']),
67
+ 'resource' => resource['resource_path']
68
+ }
69
+ end
70
+
71
+ def transition_path(transition, resource_path)
72
+ transition['attributes'] && transition['attributes']['href'] && transition['attributes']['href']['content'] || resource_path
73
+ end
74
+
75
+ def without_group_actions
76
+ transitions.inject([]) do |result_transition, transition|
77
+ result_transition.push(transition['transition']['content'].each_with_object([]) do |content, result_contents|
78
+ result_contents.push(Tomograph::ApiBlueprint::Crafter::Yaml::Action.new(
79
+ content['content'],
80
+ transition['transition_path'],
81
+ transition['resource']
82
+ )) if action?(content)
83
+ end)
84
+ end
85
+ end
86
+
87
+ def action?(content)
88
+ content['element'] == 'httpTransaction'
89
+ end
90
+
91
+ def actions
92
+ @actions ||= without_group_actions
93
+ .flatten
94
+ .group_by { |action| "#{action.method} #{action.path}" }.map do |_key, related_actions|
95
+ action_hash(related_actions)
96
+ end.flatten
97
+ end
98
+
99
+ def action_hash(related_actions)
100
+ {
101
+ path: "#{@prefix}#{related_actions.first.path}",
102
+ method: related_actions.first.method,
103
+ content_type: related_actions.first.content_type,
104
+ request: related_actions.first.request,
105
+ responses: related_actions.map(&:responses).flatten,
106
+ resource: related_actions.first.resource
107
+ }
108
+ end
109
+
110
+ def to_tomogram
111
+ @tomogram ||= actions.inject([]) do |result, action|
112
+ result.push(Tomograph::Tomogram::Action.new(action))
113
+ end
114
+ end
115
+
116
+ def to_resources
117
+ return @to_resources if @to_resources
118
+
119
+ @to_resources = actions.group_by { |action| action[:resource] }
120
+ @to_resources = @to_resources.inject({}) do |res, related_actions|
121
+ requests = related_actions[1].map do |action|
122
+ "#{action[:method]} #{action[:path]}"
123
+ end
124
+ res.merge(related_actions[1].first[:resource] => requests)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,63 @@
1
+ require 'tomograph/tomogram/action'
2
+
3
+ module Tomograph
4
+ module ApiBlueprint
5
+ class Drafter3
6
+ class Yaml
7
+ class Action
8
+ def initialize(content, path, resource)
9
+ @content = content
10
+ @path = path
11
+ @resource = resource
12
+ end
13
+
14
+ attr_reader :path, :resource
15
+
16
+ def method
17
+ @method ||= @content.first['attributes']['method']
18
+ end
19
+
20
+ def content_type
21
+ @content_type ||= @content.first['attributes'].has_key?('headers') ?
22
+ @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
23
+ end
24
+
25
+ def request
26
+ return @request if @request
27
+
28
+ request_action = @content.find { |el| el['element'] == 'httpRequest' }
29
+ @request = json_schema(request_action['content'])
30
+ end
31
+
32
+ def json_schema(actions)
33
+ schema_node = actions.find do |action|
34
+ action && action['element'] == 'asset' && action['attributes']['contentType'] == 'application/schema+json'
35
+ end
36
+ return {} unless schema_node
37
+
38
+ MultiJson.load(schema_node['content'])
39
+ rescue MultiJson::ParseError => e
40
+ puts "[Tomograph] Error while parsing #{e}. skipping..."
41
+ {}
42
+ end
43
+
44
+ def responses
45
+ return @responses if @responses
46
+
47
+ @responses = @content.select do |response|
48
+ response['element'] == 'httpResponse' && response['attributes']
49
+ end
50
+ @responses = @responses.map do |response|
51
+ {
52
+ 'status' => response['attributes']['statusCode'],
53
+ 'body' => json_schema(response['content']),
54
+ 'content-type' => response['attributes'].has_key?('headers') ?
55
+ response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,128 @@
1
+ require 'yaml'
2
+ require 'tomograph/api_blueprint/drafter_3/yaml/action'
3
+ require 'tomograph/tomogram/action'
4
+
5
+ module Tomograph
6
+ module ApiBlueprint
7
+ class Drafter3
8
+ class Yaml
9
+ def initialize(prefix, apib_path, drafter_yaml_path)
10
+ @prefix = prefix
11
+ @documentation = if apib_path
12
+ YAML.safe_load(`drafter #{apib_path}`)
13
+ elsif drafter_yaml_path
14
+ YAML.safe_load(File.read(drafter_yaml_path))
15
+ end
16
+ end
17
+
18
+ def groups
19
+ @groups ||= @documentation['content'][0]['content'].inject([]) do |result_groups, group|
20
+ next result_groups unless group?(group)
21
+ result_groups.push(group)
22
+ end
23
+ end
24
+
25
+ def group?(group)
26
+ group['element'] != 'copy' && # Element is a human readable text
27
+ group['meta']['classes'][0] == 'resourceGroup' # skip Data Structures
28
+ end
29
+
30
+ def resources
31
+ @resources ||= groups.inject([]) do |result_groups, group|
32
+ result_groups.push(group['content'].inject([]) do |result_resources, resource|
33
+ next result_resources unless resource?(resource)
34
+ result_resources.push('resource' => resource, 'resource_path' => resource_path(resource))
35
+ end)
36
+ end.flatten
37
+ end
38
+
39
+ def resource?(resource)
40
+ resource['element'] != 'copy' # Element is a human readable text
41
+ end
42
+
43
+ def resource_path(resource)
44
+ resource['attributes'] && resource['attributes']['href']
45
+ end
46
+
47
+ def transitions
48
+ @transitions ||= resources.inject([]) do |result_resources, resource|
49
+ result_resources.push(resource['resource']['content'].inject([]) do |result_transitions, transition|
50
+ next result_transitions unless transition?(transition)
51
+ result_transitions.push(transition_hash(transition, resource))
52
+ end)
53
+ end.flatten
54
+ end
55
+
56
+ def transition?(transition)
57
+ transition['element'] == 'transition'
58
+ end
59
+
60
+ def transition_hash(transition, resource)
61
+ {
62
+ 'transition' => transition,
63
+ 'transition_path' => transition_path(transition, resource['resource_path']),
64
+ 'resource' => resource['resource_path']
65
+ }
66
+ end
67
+
68
+ def transition_path(transition, resource_path)
69
+ transition['attributes'] && transition['attributes']['href'] || resource_path
70
+ end
71
+
72
+ def without_group_actions
73
+ transitions.inject([]) do |result_transition, transition|
74
+ result_transition.push(transition['transition']['content'].inject([]) do |result_contents, content|
75
+ next result_contents unless action?(content)
76
+ result_contents.push(Tomograph::ApiBlueprint::Drafter3::Yaml::Action.new(
77
+ content['content'],
78
+ transition['transition_path'],
79
+ transition['resource']
80
+ ))
81
+ end)
82
+ end
83
+ end
84
+
85
+ def action?(content)
86
+ content['element'] == 'httpTransaction'
87
+ end
88
+
89
+ def actions
90
+ @actions ||= without_group_actions
91
+ .flatten
92
+ .group_by { |action| "#{action.method} #{action.path}" }.map do |_key, related_actions|
93
+ action_hash(related_actions)
94
+ end.flatten
95
+ end
96
+
97
+ def action_hash(related_actions)
98
+ {
99
+ path: "#{@prefix}#{related_actions.first.path}",
100
+ method: related_actions.first.method,
101
+ content_type: related_actions.first.content_type,
102
+ request: related_actions.first.request,
103
+ responses: related_actions.map(&:responses).flatten,
104
+ resource: related_actions.first.resource
105
+ }
106
+ end
107
+
108
+ def to_tomogram
109
+ @tomogram ||= actions.inject([]) do |result, action|
110
+ result.push(Tomograph::Tomogram::Action.new(action))
111
+ end
112
+ end
113
+
114
+ def to_resources
115
+ return @to_resources if @to_resources
116
+
117
+ @to_resources = actions.group_by { |action| action[:resource] }
118
+ @to_resources = @to_resources.inject({}) do |res, related_actions|
119
+ requests = related_actions[1].map do |action|
120
+ "#{action[:method]} #{action[:path]}"
121
+ end
122
+ res.merge(related_actions[1].first[:resource] => requests)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,63 @@
1
+ require 'tomograph/tomogram/action'
2
+
3
+ module Tomograph
4
+ module ApiBlueprint
5
+ class Drafter4
6
+ class Yaml
7
+ class Action
8
+ def initialize(content, path, resource)
9
+ @content = content
10
+ @path = path
11
+ @resource = resource
12
+ end
13
+
14
+ attr_reader :path, :resource
15
+
16
+ def method
17
+ @method ||= @content.first['attributes']['method']['content']
18
+ end
19
+
20
+ def content_type
21
+ @content_type ||= @content.first['attributes'].has_key?('headers') ?
22
+ @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
23
+ end
24
+
25
+ def request
26
+ return @request if @request
27
+
28
+ request_action = @content.find { |el| el['element'] == 'httpRequest' }
29
+ @request = json_schema(request_action['content'])
30
+ end
31
+
32
+ def json_schema(actions)
33
+ schema_node = actions.find do |action|
34
+ action && action['element'] == 'asset' && action['attributes']['contentType']['content'] == 'application/schema+json'
35
+ end
36
+ return {} unless schema_node
37
+
38
+ MultiJson.load(schema_node['content'])
39
+ rescue MultiJson::ParseError => e
40
+ puts "[Tomograph] Error while parsing #{e}. skipping..."
41
+ {}
42
+ end
43
+
44
+ def responses
45
+ return @responses if @responses
46
+
47
+ @responses = @content.select do |response|
48
+ response['element'] == 'httpResponse' && response['attributes']
49
+ end
50
+ @responses = @responses.map do |response|
51
+ {
52
+ 'status' => response['attributes']['statusCode']['content'],
53
+ 'body' => json_schema(response['content']),
54
+ 'content-type' => response['attributes'].has_key?('headers') ?
55
+ response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,130 @@
1
+ require 'yaml'
2
+ require 'tomograph/api_blueprint/drafter_4/yaml/action'
3
+ require 'tomograph/tomogram/action'
4
+
5
+ module Tomograph
6
+ module ApiBlueprint
7
+ class Drafter4
8
+ class Yaml
9
+ def initialize(prefix, apib_path, drafter_yaml_path)
10
+ @prefix = prefix
11
+ @documentation = if apib_path
12
+ YAML.safe_load(`drafter #{apib_path}`)
13
+ elsif drafter_yaml_path
14
+ YAML.safe_load(File.read(drafter_yaml_path))
15
+ end
16
+ end
17
+
18
+ def groups
19
+ @groups ||= @documentation['content'][0]['content'].each_with_object([]) do |group, result_groups|
20
+ result_groups.push(group) if group?(group)
21
+ result_groups.push('content' => [group]) if single_resource?(group)
22
+ end
23
+ end
24
+
25
+ def single_resource?(group)
26
+ group['element'] == 'resource'
27
+ end
28
+
29
+ def group?(group)
30
+ return false if group['element'] == 'resource'
31
+ group['element'] != 'copy' && # Element is a human readable text
32
+ group['meta']['classes']['content'][0]['content'] == 'resourceGroup' # skip Data Structures
33
+ end
34
+
35
+ def resources
36
+ @resources ||= groups.inject([]) do |result_groups, group|
37
+ result_groups.push(group['content'].each_with_object([]) do |resource, result_resources|
38
+ result_resources.push('resource' => resource, 'resource_path' => resource_path(resource)) if resource?(resource)
39
+ end)
40
+ end.flatten
41
+ end
42
+
43
+ def resource?(resource)
44
+ resource['element'] != 'copy' # Element is a human readable text
45
+ end
46
+
47
+ def resource_path(resource)
48
+ resource['attributes'] && resource['attributes']['href']['content']
49
+ end
50
+
51
+ def transitions
52
+ @transitions ||= resources.inject([]) do |result_resources, resource|
53
+ result_resources.push(resource['resource']['content'].each_with_object([]) do |transition, result_transitions|
54
+ result_transitions.push(transition_hash(transition, resource)) if transition?(transition)
55
+ end)
56
+ end.flatten
57
+ end
58
+
59
+ def transition?(transition)
60
+ transition['element'] == 'transition'
61
+ end
62
+
63
+ def transition_hash(transition, resource)
64
+ {
65
+ 'transition' => transition,
66
+ 'transition_path' => transition_path(transition, resource['resource_path']),
67
+ 'resource' => resource['resource_path']
68
+ }
69
+ end
70
+
71
+ def transition_path(transition, resource_path)
72
+ transition['attributes'] && transition['attributes']['href']['content'] || resource_path
73
+ end
74
+
75
+ def without_group_actions
76
+ transitions.inject([]) do |result_transition, transition|
77
+ result_transition.push(transition['transition']['content'].each_with_object([]) do |content, result_contents|
78
+ result_contents.push(Tomograph::ApiBlueprint::Drafter4::Yaml::Action.new(
79
+ content['content'],
80
+ transition['transition_path'],
81
+ transition['resource']
82
+ )) if action?(content)
83
+ end)
84
+ end
85
+ end
86
+
87
+ def action?(content)
88
+ content['element'] == 'httpTransaction'
89
+ end
90
+
91
+ def actions
92
+ @actions ||= without_group_actions
93
+ .flatten
94
+ .group_by { |action| "#{action.method} #{action.path}" }.map do |_key, related_actions|
95
+ action_hash(related_actions)
96
+ end.flatten
97
+ end
98
+
99
+ def action_hash(related_actions)
100
+ {
101
+ path: "#{@prefix}#{related_actions.first.path}",
102
+ method: related_actions.first.method,
103
+ content_type: related_actions.first.content_type,
104
+ request: related_actions.first.request,
105
+ responses: related_actions.map(&:responses).flatten,
106
+ resource: related_actions.first.resource
107
+ }
108
+ end
109
+
110
+ def to_tomogram
111
+ @tomogram ||= actions.inject([]) do |result, action|
112
+ result.push(Tomograph::Tomogram::Action.new(action))
113
+ end
114
+ end
115
+
116
+ def to_resources
117
+ return @to_resources if @to_resources
118
+
119
+ @to_resources = actions.group_by { |action| action[:resource] }
120
+ @to_resources = @to_resources.inject({}) do |res, related_actions|
121
+ requests = related_actions[1].map do |action|
122
+ "#{action[:method]} #{action[:path]}"
123
+ end
124
+ res.merge(related_actions[1].first[:resource] => requests)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,17 +1,23 @@
1
1
  require 'multi_json'
2
2
  require 'tomograph/path'
3
3
  require 'tomograph/api_blueprint/json_schema'
4
- require 'tomograph/api_blueprint/yaml'
4
+ require 'tomograph/api_blueprint/drafter_3/yaml'
5
+ require 'tomograph/api_blueprint/drafter_4/yaml'
6
+ require 'tomograph/api_blueprint/crafter/yaml'
5
7
 
6
8
  module Tomograph
7
9
  class Tomogram
8
10
  extend Gem::Deprecate
9
11
 
10
- def initialize(prefix: '', apib_path: nil, drafter_yaml_path: nil, tomogram_json_path: nil)
12
+ def initialize(prefix: '', apib_path: nil, drafter_yaml_path: nil, tomogram_json_path: nil, drafter_4_apib_path: nil, drafter_4_yaml_path: nil, crafter_apib_path: nil, crafter_yaml_path: nil)
11
13
  @documentation = if tomogram_json_path
12
14
  Tomograph::ApiBlueprint::JsonSchema.new(prefix, tomogram_json_path)
15
+ elsif drafter_4_yaml_path || drafter_4_apib_path
16
+ Tomograph::ApiBlueprint::Drafter4::Yaml.new(prefix, drafter_4_apib_path, drafter_4_yaml_path)
17
+ elsif crafter_yaml_path || crafter_apib_path
18
+ Tomograph::ApiBlueprint::Crafter::Yaml.new(prefix, crafter_apib_path, crafter_yaml_path)
13
19
  else
14
- Tomograph::ApiBlueprint::Yaml.new(prefix, apib_path, drafter_yaml_path)
20
+ Tomograph::ApiBlueprint::Drafter3::Yaml.new(prefix, apib_path, drafter_yaml_path)
15
21
  end
16
22
  @prefix = prefix
17
23
  end
@@ -1,3 +1,3 @@
1
1
  module Tomograph
2
- VERSION = '2.4.2'.freeze
2
+ VERSION = '2.5.0'.freeze
3
3
  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: 2.4.2
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - d.efimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-29 00:00:00.000000000 Z
11
+ date: 2019-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: methadone
@@ -180,9 +180,13 @@ files:
180
180
  - bin/setup
181
181
  - exe/tomograph
182
182
  - lib/tomograph.rb
183
+ - lib/tomograph/api_blueprint/crafter/yaml.rb
184
+ - lib/tomograph/api_blueprint/crafter/yaml/action.rb
185
+ - lib/tomograph/api_blueprint/drafter_3/yaml.rb
186
+ - lib/tomograph/api_blueprint/drafter_3/yaml/action.rb
187
+ - lib/tomograph/api_blueprint/drafter_4/yaml.rb
188
+ - lib/tomograph/api_blueprint/drafter_4/yaml/action.rb
183
189
  - lib/tomograph/api_blueprint/json_schema.rb
184
- - lib/tomograph/api_blueprint/yaml.rb
185
- - lib/tomograph/api_blueprint/yaml/action.rb
186
190
  - lib/tomograph/path.rb
187
191
  - lib/tomograph/tomogram.rb
188
192
  - lib/tomograph/tomogram/action.rb
@@ -209,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
213
  version: '0'
210
214
  requirements: []
211
215
  rubyforge_project:
212
- rubygems_version: 2.4.5
216
+ rubygems_version: 2.4.5.5
213
217
  signing_key:
214
218
  specification_version: 4
215
219
  summary: Convert API Blueprint to Tomogram
@@ -1,61 +0,0 @@
1
- require 'tomograph/tomogram/action'
2
-
3
- module Tomograph
4
- module ApiBlueprint
5
- class Yaml
6
- class Action
7
- def initialize(content, path, resource)
8
- @content = content
9
- @path = path
10
- @resource = resource
11
- end
12
-
13
- attr_reader :path, :resource
14
-
15
- def method
16
- @method ||= @content.first['attributes']['method']
17
- end
18
-
19
- def content_type
20
- @content_type ||= @content.first['attributes'].has_key?('headers') ?
21
- @content.first['attributes']['headers']['content'][0]['content']['value']['content'] : nil
22
- end
23
-
24
- def request
25
- return @request if @request
26
-
27
- request_action = @content.find { |el| el['element'] == 'httpRequest' }
28
- @request = json_schema(request_action['content'])
29
- end
30
-
31
- def json_schema(actions)
32
- schema_node = actions.find do |action|
33
- action && action['element'] == 'asset' && action['attributes']['contentType'] == 'application/schema+json'
34
- end
35
- return {} unless schema_node
36
-
37
- MultiJson.load(schema_node['content'])
38
- rescue MultiJson::ParseError => e
39
- puts "[Tomograph] Error while parsing #{e}. skipping..."
40
- {}
41
- end
42
-
43
- def responses
44
- return @responses if @responses
45
-
46
- @responses = @content.select do |response|
47
- response['element'] == 'httpResponse' && response['attributes']
48
- end
49
- @responses = @responses.map do |response|
50
- {
51
- 'status' => response['attributes']['statusCode'],
52
- 'body' => json_schema(response['content']),
53
- 'content-type' => response['attributes'].has_key?('headers') ?
54
- response['attributes']['headers']['content'][0]['content']['value']['content'] : nil
55
- }
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,126 +0,0 @@
1
- require 'yaml'
2
- require 'tomograph/api_blueprint/yaml/action'
3
- require 'tomograph/tomogram/action'
4
-
5
- module Tomograph
6
- module ApiBlueprint
7
- class Yaml
8
- def initialize(prefix, apib_path, drafter_yaml_path)
9
- @prefix = prefix
10
- @documentation = if apib_path
11
- YAML.safe_load(`drafter #{apib_path}`)
12
- elsif drafter_yaml_path
13
- YAML.safe_load(File.read(drafter_yaml_path))
14
- end
15
- end
16
-
17
- def groups
18
- @groups ||= @documentation['content'][0]['content'].inject([]) do |result_groups, group|
19
- next result_groups unless group?(group)
20
- result_groups.push(group)
21
- end
22
- end
23
-
24
- def group?(group)
25
- group['element'] != 'copy' && # Element is a human readable text
26
- group['meta']['classes'][0] == 'resourceGroup' # skip Data Structures
27
- end
28
-
29
- def resources
30
- @resources ||= groups.inject([]) do |result_groups, group|
31
- result_groups.push(group['content'].inject([]) do |result_resources, resource|
32
- next result_resources unless resource?(resource)
33
- result_resources.push('resource' => resource, 'resource_path' => resource_path(resource))
34
- end)
35
- end.flatten
36
- end
37
-
38
- def resource?(resource)
39
- resource['element'] != 'copy' # Element is a human readable text
40
- end
41
-
42
- def resource_path(resource)
43
- resource['attributes'] && resource['attributes']['href']
44
- end
45
-
46
- def transitions
47
- @transitions ||= resources.inject([]) do |result_resources, resource|
48
- result_resources.push(resource['resource']['content'].inject([]) do |result_transitions, transition|
49
- next result_transitions unless transition?(transition)
50
- result_transitions.push(transition_hash(transition, resource))
51
- end)
52
- end.flatten
53
- end
54
-
55
- def transition?(transition)
56
- transition['element'] == 'transition'
57
- end
58
-
59
- def transition_hash(transition, resource)
60
- {
61
- 'transition' => transition,
62
- 'transition_path' => transition_path(transition, resource['resource_path']),
63
- 'resource' => resource['resource_path']
64
- }
65
- end
66
-
67
- def transition_path(transition, resource_path)
68
- transition['attributes'] && transition['attributes']['href'] || resource_path
69
- end
70
-
71
- def without_group_actions
72
- transitions.inject([]) do |result_transition, transition|
73
- result_transition.push(transition['transition']['content'].inject([]) do |result_contents, content|
74
- next result_contents unless action?(content)
75
- result_contents.push(Tomograph::ApiBlueprint::Yaml::Action.new(
76
- content['content'],
77
- transition['transition_path'],
78
- transition['resource']
79
- ))
80
- end)
81
- end
82
- end
83
-
84
- def action?(content)
85
- content['element'] == 'httpTransaction'
86
- end
87
-
88
- def actions
89
- @actions ||= without_group_actions
90
- .flatten
91
- .group_by { |action| "#{action.method} #{action.path}" }.map do |_key, related_actions|
92
- action_hash(related_actions)
93
- end.flatten
94
- end
95
-
96
- def action_hash(related_actions)
97
- {
98
- path: "#{@prefix}#{related_actions.first.path}",
99
- method: related_actions.first.method,
100
- content_type: related_actions.first.content_type,
101
- request: related_actions.first.request,
102
- responses: related_actions.map(&:responses).flatten,
103
- resource: related_actions.first.resource
104
- }
105
- end
106
-
107
- def to_tomogram
108
- @tomogram ||= actions.inject([]) do |result, action|
109
- result.push(Tomograph::Tomogram::Action.new(action))
110
- end
111
- end
112
-
113
- def to_resources
114
- return @to_resources if @to_resources
115
-
116
- @to_resources = actions.group_by { |action| action[:resource] }
117
- @to_resources = @to_resources.inject({}) do |res, related_actions|
118
- requests = related_actions[1].map do |action|
119
- "#{action[:method]} #{action[:path]}"
120
- end
121
- res.merge(related_actions[1].first[:resource] => requests)
122
- end
123
- end
124
- end
125
- end
126
- end