tomograph 2.4.2 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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