jekyll-ramler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc0e1f14109050ea1f296cc5ed5b3fb1ac100510
4
+ data.tar.gz: fdf5cee7e082ea0397f460233683b1b13aa5e034
5
+ SHA512:
6
+ metadata.gz: 54959f41e90effd0ab0af92512cc49780771e6bfb5cf204e5b725f81d24f70834396eff93c9f384ee49738cfd689eb0a34959e986ef36a6a6809476d36aa9a43
7
+ data.tar.gz: 4fe17f77d424cba1df92d33ce9ecb08d31179f25dfcdb03e3443f7aac569021897e50b7ce21c7d5783de3e54fad03dd7cdac006a076591eed616312faadfd87e
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3-p547
4
+ - 2.1.5
5
+ - 2.2.0
6
+ install:
7
+ - npm install raml-cop
8
+ - bundle install
9
+ script: "bundle exec rspec"
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test, :development do
6
+ gem 'fakefs', require: 'fakefs/safe'
7
+ gem 'pry'
8
+ gem 'rspec'
9
+ gem 'ruby_deep_clone'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,103 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jekyll-ramler (0.0.1)
5
+ jekyll
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ blankslate (2.1.2.4)
11
+ celluloid (0.16.0)
12
+ timers (~> 4.0.0)
13
+ classifier-reborn (2.0.3)
14
+ fast-stemmer (~> 1.0)
15
+ coderay (1.1.0)
16
+ coffee-script (2.3.0)
17
+ coffee-script-source
18
+ execjs
19
+ coffee-script-source (1.9.0)
20
+ colorator (0.1)
21
+ diff-lcs (1.2.5)
22
+ execjs (2.3.0)
23
+ fakefs (0.6.5)
24
+ fast-stemmer (1.0.2)
25
+ ffi (1.9.6)
26
+ hitimes (1.2.2)
27
+ jekyll (2.5.3)
28
+ classifier-reborn (~> 2.0)
29
+ colorator (~> 0.1)
30
+ jekyll-coffeescript (~> 1.0)
31
+ jekyll-gist (~> 1.0)
32
+ jekyll-paginate (~> 1.0)
33
+ jekyll-sass-converter (~> 1.0)
34
+ jekyll-watch (~> 1.1)
35
+ kramdown (~> 1.3)
36
+ liquid (~> 2.6.1)
37
+ mercenary (~> 0.3.3)
38
+ pygments.rb (~> 0.6.0)
39
+ redcarpet (~> 3.1)
40
+ safe_yaml (~> 1.0)
41
+ toml (~> 0.1.0)
42
+ jekyll-coffeescript (1.0.1)
43
+ coffee-script (~> 2.2)
44
+ jekyll-gist (1.1.0)
45
+ jekyll-paginate (1.1.0)
46
+ jekyll-sass-converter (1.3.0)
47
+ sass (~> 3.2)
48
+ jekyll-watch (1.2.1)
49
+ listen (~> 2.7)
50
+ kramdown (1.5.0)
51
+ liquid (2.6.2)
52
+ listen (2.8.5)
53
+ celluloid (>= 0.15.2)
54
+ rb-fsevent (>= 0.9.3)
55
+ rb-inotify (>= 0.9)
56
+ mercenary (0.3.5)
57
+ method_source (0.8.2)
58
+ parslet (1.5.0)
59
+ blankslate (~> 2.0)
60
+ posix-spawn (0.3.9)
61
+ pry (0.10.1)
62
+ coderay (~> 1.1.0)
63
+ method_source (~> 0.8.1)
64
+ slop (~> 3.4)
65
+ pygments.rb (0.6.2)
66
+ posix-spawn (~> 0.3.6)
67
+ yajl-ruby (~> 1.2.0)
68
+ rb-fsevent (0.9.4)
69
+ rb-inotify (0.9.5)
70
+ ffi (>= 0.5.0)
71
+ redcarpet (3.2.2)
72
+ rspec (3.2.0)
73
+ rspec-core (~> 3.2.0)
74
+ rspec-expectations (~> 3.2.0)
75
+ rspec-mocks (~> 3.2.0)
76
+ rspec-core (3.2.0)
77
+ rspec-support (~> 3.2.0)
78
+ rspec-expectations (3.2.0)
79
+ diff-lcs (>= 1.2.0, < 2.0)
80
+ rspec-support (~> 3.2.0)
81
+ rspec-mocks (3.2.0)
82
+ diff-lcs (>= 1.2.0, < 2.0)
83
+ rspec-support (~> 3.2.0)
84
+ rspec-support (3.2.1)
85
+ ruby_deep_clone (0.6.0)
86
+ safe_yaml (1.0.4)
87
+ sass (3.4.11)
88
+ slop (3.6.0)
89
+ timers (4.0.1)
90
+ hitimes
91
+ toml (0.1.2)
92
+ parslet (~> 1.5.0)
93
+ yajl-ruby (1.2.1)
94
+
95
+ PLATFORMS
96
+ ruby
97
+
98
+ DEPENDENCIES
99
+ fakefs
100
+ jekyll-ramler!
101
+ pry
102
+ rspec
103
+ ruby_deep_clone
data/LICENSE.md ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2015, GovDelivery, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of GovDelivery nor the names of its contributors may be
15
+ used to endorse or promote products derived from this software without
16
+ specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ [![Build Status](https://travis-ci.org/govdelivery/jekyll-ramler.svg?branch=master)](https://travis-ci.org/govdelivery/jekyll-ramler)
2
+ [![Gem Version](https://badge.fury.io/rb/jekyll-ramler.svg)](http://badge.fury.io/rb/jekyll-ramler)
3
+
4
+ jekyll-ramler
5
+ =============
6
+
7
+ Generates Jekyll pages for overview, security, and resource documentation
8
+ specificed in a RAML file.
9
+
10
+
11
+ ## Installation
12
+
13
+ ### Dependencies
14
+
15
+ jekyll-ramler relies on [raml-cop](https://www.npmjs.com/package/raml-cop), a
16
+ Node.js script, to actually parse a RAML file. Thus, you will need to install
17
+ [Node.js](http://nodejs.org/), then perform `npm install raml-cop`.
18
+
19
+
20
+ ## JSON Schema Support
21
+
22
+ jekyll-ramler includes a few features for JSON Schema.
23
+
24
+ ### Table and Raw views of JSON Schema
25
+
26
+ If a resource method defines `body:application/json:schema` item, then
27
+ jekyll-ramler will generate two views of the schema. One view will be an
28
+ easily copyable display of the raw schema. The other view will be a table-like
29
+ display of parameters, similar to what is generated for
30
+ `body:application/x-www-form-urlencoded:formParamters`.
31
+
32
+ ### Generated JSON Schema from formParameters
33
+
34
+ Recognizing that Content-Type does not impact functionality or content for some
35
+ APIs, jekyll-ramler will generate JSON Schema for resource methods that include
36
+ a defined `body:application/x-www-form-urlencoded:formParamters` list, as well
37
+ as a `body:application/json` item **without** a `schema` item. If a resource
38
+ includes a `body:application/json/schema` item, then nothing will happen.
39
+
40
+ ## $ref and allOf
41
+
42
+ [JSON Schema provides a semantic construct for schema inheritance](http://spacetelescope.github.io/understanding-json-schema/reference/combining.html)
43
+ via the **$ref** and **allOf** keywords. jekyll-ramler uses this construct to
44
+ allow for schema referred to in RAML to inherit from other schema, which allows
45
+ you to DRY your JSON schema bit.
46
+
47
+ When jekyll-ramler encounteres **$ref** and/or **allOf**, it pulls in and
48
+ merges the referred to schemas, creating a single schema object that includes
49
+ all attributes. Thus, while you might store your JSON schema across multiple
50
+ files, users of your site will only see fully de-referenced and merged JSON
51
+ schema on your site. This de-referencing and merging also allows jekyll-ramler
52
+ to generate complete, table-like views of your JSON schema, even if your schema
53
+ inherits from other schema.
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'jekyll-ramler'
3
+ s.version = '0.0.1'
4
+ s.date = '2015-02-09'
5
+ s.authors = ['GovDelivery']
6
+ s.email = 'support@govdelivery.com'
7
+ s.homepage = 'https://github.com/govdelivery/jekyll-ramler'
8
+ s.license = 'BSD-3-Cluase'
9
+ s.summary = 'Jekyll plugin that generates API documentation pages based on RAML'
10
+ s.description = %q{Generates Jekyll pages for overview, security, and
11
+ resource documentation specificed in a RAML file.}
12
+
13
+ s.add_runtime_dependency 'jekyll'
14
+
15
+ s.files = `git ls-files`.split($\)
16
+ s.require_paths = ['lib']
17
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'utils'
2
+ require_relative 'raml-generate'
@@ -0,0 +1,266 @@
1
+ require 'json'
2
+
3
+ module Jekyll
4
+ class RawFile<StaticFile
5
+ def initialize(site, base, dir, name, content)
6
+ @content = content
7
+ super(site, base, dir, name)
8
+ end
9
+
10
+ def write(dest)
11
+ dest_path = File.join(dest, @dir, @name)
12
+ FileUtils.mkdir_p(File.dirname(dest_path))
13
+ File.open(dest_path, 'w') do |f|
14
+ f.write(@content)
15
+ end
16
+ end
17
+ end
18
+
19
+ class GeneratedPage<Page
20
+ def initialize(site, base, dir, item, layout=nil)
21
+ @site = site
22
+ @base = base
23
+ @dir = dir.gsub(/{(\w*)}/, '--\1--').gsub(/\s/, '_')
24
+ @name = 'index.html'
25
+
26
+ layout = get_layout(dir) if layout.nil?
27
+ layout << '.html' if not layout.end_with?('.html')
28
+
29
+ self.process(@name)
30
+ self.read_yaml(File.join(base, '_layouts'), layout)
31
+
32
+ self.data['title'] = "#{item['title']}"
33
+ if item.include?('description')
34
+ self.data['description'] = transform_md(item['description'])
35
+ end
36
+ end
37
+
38
+ private
39
+ def transform_md(output)
40
+ # Use the existing Jekyll Markdown converters
41
+ md_converters = site.converters.select{|c| c.matches('.md')}
42
+ md_converters.reduce(output) do |output, converter|
43
+ converter.convert output
44
+ end
45
+ end
46
+
47
+ def get_layout(dir, site=@site)
48
+ default = site.config.fetch('defaults', {}).detect do |default|
49
+ default['scope']['path'] == dir.split('/').first
50
+ end
51
+
52
+ default = {"values" => {}} if default.nil?
53
+
54
+ default['values'].fetch('layout', 'default')
55
+ end
56
+
57
+ end
58
+
59
+ class SecuritySchemePage<GeneratedPage
60
+ def initialize(site, base, dir, securityScheme)
61
+ super(site, base, dir, securityScheme, layout=get_layout('resource', site))
62
+ end
63
+ end
64
+
65
+ class DocumentationPage<GeneratedPage
66
+ def initialize(site, base, dir, documentation)
67
+ super(site, base, dir, documentation)
68
+
69
+ output = documentation['content']
70
+ self.data['body'] = transform_md(output)
71
+ end
72
+ end
73
+
74
+ class ResourcePage<GeneratedPage
75
+ def initialize(site, base, dir, resource, traits, securitySchemes)
76
+ # Sandbox our resource, and do nothing with child resources
77
+ resource = resource.dup
78
+ resource.delete('resources')
79
+
80
+ resource['title'] = dir.sub('resource', '') if not resource.include?('title')
81
+ super(site, base, dir, resource)
82
+
83
+ # Add security data to the resource
84
+ resource.fetch('methods', []).each do |method|
85
+ if method.include?('securedBy')
86
+ for scheme in method['securedBy']
87
+ for attr in ['headers', 'queryParameters', 'responses']
88
+ method[attr] = {} if not method.include?(attr)
89
+ method[attr].merge!(securitySchemes[scheme].fetch('describedBy', {}).fetch(attr, {}))
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ # Add trait data to the resource
96
+ resource.fetch('methods', []).each do |method|
97
+ if method.include?('is')
98
+ for trait in method['is']
99
+ merge_method_trait(method, traits[trait])
100
+ end
101
+ end
102
+ end
103
+
104
+ # Compile JSON Schema that use $ref references
105
+ jsc = Jekyll::JsonSchemaCompiler.new
106
+ jsc.compile(resource['methods'])
107
+
108
+ # Generate new schema based on existing formParameters
109
+ schema_generator = Jekyll::RamlSchemaGenerator.new(site, resource['title'])
110
+ schema_generator.insert_schemas(resource['methods'])
111
+
112
+ # Transform descriptions via Markdown
113
+ resource = transform_resource_descriptions(resource)
114
+ self.data['methods'] = add_schema_hashes(resource['methods'])
115
+ end
116
+
117
+ private
118
+ def merge_method_trait(method, trait)
119
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
120
+ method.merge(trait, &merger)
121
+
122
+ if method.include?('description')
123
+ method['description'] = "#{method['description']}\n\n#{trait['description']}"
124
+ else
125
+ method['description'] = trait['description']
126
+ end
127
+ method
128
+ end
129
+
130
+ def transform_resource_descriptions(resource)
131
+ if resource.include?('description')
132
+ resource['description'] = transform_md(resource['description'])
133
+ end
134
+
135
+ resource.each_key do |key|
136
+ if resource[key].is_a?(Hash)
137
+ resource[key] = transform_resource_descriptions(resource[key])
138
+ end
139
+ if resource[key].is_a?(Array)
140
+ resource[key].map!{|h| h.is_a?(Hash) ? transform_resource_descriptions(h) : h }
141
+ end
142
+ end
143
+
144
+ resource
145
+ end
146
+
147
+ # Adds a 'schema_hash' attribute to bodies with 'schema', which allows for the generation of schema table views
148
+ def add_schema_hashes(obj, key=nil)
149
+ if obj.is_a?(Array)
150
+ obj.map! { |method| add_schema_hashes(method) }
151
+ elsif obj.is_a?(Hash)
152
+ obj.each { |k, v| obj[k] = add_schema_hashes(v, k)}
153
+
154
+ if obj.include?("schema")
155
+
156
+ case key
157
+ when 'application/json'
158
+ obj['schema_hash'] = JSON.parse(obj['schema'])
159
+
160
+ refactor_object = lambda do |obj|
161
+ obj['properties'].each do |name, param|
162
+ param['displayName'] = name
163
+ param['required'] = true if obj.fetch('required', []).include?(name)
164
+
165
+ if param.include?('example') and ['object', 'array'].include?(param['type'])
166
+ param['example'] = JSON.pretty_generate(JSON.parse(param['example']))
167
+ elsif param.include?('properties')
168
+ param['example'] = JSON.pretty_generate(param['properties'])
169
+ elsif param.include?('items')
170
+ param['example'] = JSON.pretty_generate(param['items'])
171
+ end
172
+
173
+ obj['properties'][name] = param
174
+ end
175
+ obj
176
+ end
177
+
178
+ if obj['schema_hash'].include?('properties')
179
+ obj['schema_hash'] = refactor_object.call(obj['schema_hash'])
180
+ end
181
+
182
+ if obj['schema_hash'].include?('items') and obj['schema_hash']['items'].include?('properties')
183
+ obj['schema_hash']['items'] = refactor_object.call(obj['schema_hash']['items'])
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ obj
190
+ end
191
+ end
192
+
193
+ class ReferencePageGenerator < Generator
194
+ safe true
195
+
196
+ def generate(site)
197
+ @site = site
198
+
199
+ raml_js_path = site.config.fetch('raml_json_file_path', 'api.json')
200
+ raml_js = File.open(raml_js_path).read
201
+ raml_hash = JSON.parse(raml_js)
202
+
203
+ # BETTER THE DATASTRUCTURES!
204
+ @traits = {}
205
+ @securitySchemes = {}
206
+ if raml_hash.has_key?('traits')
207
+ raml_hash['traits'].each {|obj| obj.each_pair {|k, v| @traits[k] = v}}
208
+ end
209
+ if raml_hash.has_key?('securitySchemes')
210
+ raml_hash['securitySchemes'].each do |obj|
211
+ obj.each_pair do |k, v|
212
+ v.fetch('describedBy', {}).fetch('headers', {}).each_pair{ |hn, hv| hv['displayName'] = hn if not hv.nil?}
213
+ v.fetch('describedBy', {}).fetch('queryParameters', {}).each_pair{ |hn, hv| hv['displayName'] = hn if not hv.nil?}
214
+ @securitySchemes[k] = v
215
+ end
216
+ end
217
+ end
218
+
219
+ # Create a page for each resource
220
+ if raml_hash.has_key?('resources')
221
+ generate_resource_pages(raml_hash['resources'])
222
+ end
223
+
224
+ dir = Jekyll::get_dir('overview', @site.config)
225
+ @securitySchemes.each do |scheme_name, scheme|
226
+ scheme_dir = File.join(dir, scheme_name)
227
+ scheme['title'] = scheme_name
228
+ @site.pages << SecuritySchemePage.new(@site, @site.source, scheme_dir, scheme)
229
+ end
230
+
231
+ raml_hash.fetch('documentation', []).each do |documentation|
232
+ documentation_dir = File.join(dir, documentation['title'])
233
+ @site.pages << DocumentationPage.new(@site, @site.source, documentation_dir, documentation)
234
+ end
235
+
236
+ # Allow users to download the RAML, which may be modified since it was read
237
+ raml_download_path = site.config.fetch('raml_download_path', 'api.raml').split('/')
238
+ raml_download_filename = raml_download_path.delete_at(-1)
239
+ raml_download_path = raml_download_path.join('/') + '/'
240
+
241
+ raml_yaml = raml_hash.to_yaml
242
+ raml_yaml.sub!('---', '#%RAML 0.8')
243
+ @site.static_files << RawFile.new(@site, @site.source, raml_download_path, raml_download_filename, raml_yaml)
244
+ end
245
+
246
+ private
247
+ def generate_resource_pages(resources, parent_dir=nil)
248
+
249
+ if parent_dir
250
+ dir = parent_dir
251
+ else
252
+ dir = Jekyll::get_dir('resource', @site.config)
253
+ end
254
+
255
+ resources.each do |resource|
256
+ resource_name = resource["relativeUri"]
257
+ resource_dir = File.join(dir, resource_name)
258
+ @site.pages << ResourcePage.new(@site, @site.source, resource_dir, resource, @traits, @securitySchemes)
259
+ if resource.has_key?('resources')
260
+ generate_resource_pages(resource['resources'], resource_dir)
261
+ end
262
+
263
+ end
264
+ end
265
+ end
266
+ end
data/lib/utils.rb ADDED
@@ -0,0 +1,135 @@
1
+ require 'json'
2
+
3
+ module Jekyll
4
+ def self.get_dir(page_type, config)
5
+ config.fetch('page_dirs', {}).fetch(page_type, page_type)
6
+ end
7
+
8
+ def self.sanatize_json_string(s)
9
+ strip_newlines(s)
10
+ end
11
+
12
+ def self.strip_newlines(s)
13
+ # Assuming Markdown, so do NOT remove consecutive newlines
14
+ regex = /([^\n])\n([^\n])/
15
+ s.gsub(regex, '\1 \2').strip
16
+ end
17
+
18
+ # Utility class for creating schema (current JSON, perhaps XML someday) based
19
+ # on existing RAML formParameters
20
+ class RamlSchemaGenerator
21
+
22
+
23
+ def initialize(site, title=nil)
24
+ @site = site
25
+ @title = title
26
+ @current_method = nil
27
+ end
28
+
29
+ # Creates a schema attribute sibling of any formParameter attribute found,
30
+ # based on the found formParameters attribute.
31
+ #
32
+ # Existing schema siblings of formParameter attributes are not modified.
33
+ #
34
+ # Modifys obj, and returns the modified obj
35
+ def insert_schemas(obj)
36
+ if obj.is_a?(Array)
37
+ obj.map!{|method| insert_schemas(method)}
38
+ elsif obj.is_a?(Hash)
39
+ @current_method = obj['method'] if obj.include?('method')
40
+
41
+ obj.each { |k, v| obj[k] = insert_schemas(v)}
42
+
43
+ if obj.include?('body')
44
+ if obj['body'].fetch('application/x-www-form-urlencoded', {}).include?('formParameters')
45
+ if obj['body'].include?('application/json') && !(obj['body']['application/json'].include?('schema'))
46
+ insert_json_schema(obj, generate_json_schema(obj))
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ obj
53
+ end
54
+
55
+ # Inserts provided JSON Schema into obj['body']['application/json']['schema']
56
+ def insert_json_schema(obj, schema)
57
+ obj['body']['application/json']['schema'] = schema
58
+ end
59
+
60
+ # Creates JSON Schema - as a string - based on obj['body']['application/x-www-form-urlencoded']['formParameters']
61
+ def generate_json_schema(obj)
62
+
63
+ # JSON Schema spec: http://json-schema.org/latest/json-schema-validation.html
64
+ schema_hash = {}
65
+ schema_hash['$schema'] = @site.config['json_schema_schema_uri']
66
+ schema_hash['title'] = @title if @title
67
+ schema_hash['description'] = Jekyll::sanatize_json_string(obj['description']) if obj.include?('description')
68
+ schema_hash['type'] = 'object'
69
+
70
+ required_properties = []
71
+ schema_hash['properties'] = obj['body']['application/x-www-form-urlencoded']['formParameters'].dup
72
+ schema_hash['properties'].each do |name, param|
73
+ if param.include?('required')
74
+ required_properties << name if param['required'] == true
75
+ param.delete('required')
76
+ end
77
+
78
+ if param.include?('description')
79
+ param['description'] = Jekyll::sanatize_json_string(param['description'])
80
+ end
81
+
82
+ # Repeat is not a supported keyword in JSON Schema
83
+ if param.include?('repeat')
84
+ param.delete('repeat')
85
+ end
86
+ end
87
+ schema_hash['required'] = required_properties if not required_properties.empty?
88
+
89
+ JSON.pretty_generate(schema_hash)
90
+ end
91
+ end
92
+
93
+ class JsonSchemaCompiler
94
+ def compile(obj, obj_name=nil)
95
+ if obj.is_a?(Array)
96
+ obj.map!{|method| compile(method)}
97
+ elsif obj.is_a?(Hash)
98
+ if obj.include?('schema') and obj_name == 'application/json'
99
+ schema_hash = JSON.parse(obj['schema'])
100
+ schema_hash = traverse_and_compile_schema(schema_hash)
101
+ obj['schema'] = JSON.pretty_generate(schema_hash)
102
+ end
103
+
104
+ obj.each { |k, v| obj[k] = compile(v, k)}
105
+ end
106
+
107
+ obj
108
+ end
109
+
110
+ private
111
+ def traverse_and_compile_schema(schema_hash)
112
+ if schema_hash.is_a?(Array)
113
+ schema_hash.map!{|method| traverse_and_compile_schema(method)}
114
+ elsif schema_hash.is_a?(Hash)
115
+ if schema_hash.include?('$ref')
116
+ refed = JSON.parse(File.read(schema_hash['$ref']))
117
+ schema_hash.delete('$ref')
118
+ schema_hash.merge!(refed)
119
+ end
120
+
121
+ schema_hash.each { |k, v| schema_hash[k] = traverse_and_compile_schema(v)}
122
+
123
+ # Merge allOfs into the parent object
124
+ if schema_hash.include?('allOf')
125
+ for item in schema_hash['allOf']
126
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
127
+ schema_hash.merge!(item, &merger)
128
+ end
129
+ schema_hash.delete('allOf')
130
+ end
131
+ end
132
+ schema_hash
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,125 @@
1
+ require_relative './spec_helper.rb'
2
+
3
+ describe 'ReferencePageGenerator', fakefs:true do
4
+
5
+ before(:each) do
6
+ @site = Jekyll::Site.new(Jekyll.configuration({
7
+ "skip_config_files" => true,
8
+ "json_schema_schema_uri" => "http://json-schema.org/draft-04/schema#"
9
+ }))
10
+ @rpg = Jekyll::ReferencePageGenerator.new
11
+
12
+ FakeFS.activate!
13
+ Pry.config.history.should_save = false;
14
+ Pry.config.history.should_load = false;
15
+
16
+ FileUtils.mkdir_p('_layouts')
17
+ File.open('_layouts/default.html', 'w') { |f| f << "{{ content }}" }
18
+
19
+ File.open('api.json', 'w') do |f|
20
+ f << JSON.pretty_generate(load_simple_raml)
21
+ end
22
+
23
+ end
24
+
25
+ after(:each) do
26
+ FakeFS.deactivate!
27
+ end
28
+
29
+ context 'Generating Pages from RAML' do
30
+
31
+ it 'generates a resource page for each resource in the RAML' do
32
+ @rpg.generate(@site)
33
+
34
+ raml_hash = load_simple_raml
35
+ passed = recursive_resource_search(raml_hash, @site)
36
+
37
+ expect(passed).to be true
38
+ end
39
+
40
+ it 'generates an overview page for each security or documentation item in the RAML' do
41
+ @rpg.generate(@site)
42
+ raml_hash = load_simple_raml
43
+
44
+ passed = documentation_search(raml_hash, @site)
45
+ expect(passed).to be true
46
+
47
+
48
+ passed = security_search(raml_hash, @site)
49
+ expect(passed).to be true
50
+
51
+ end
52
+
53
+ it 'transforms descriptions via Markdown' do
54
+ @rpg.generate(@site)
55
+ super_security = @site.pages.select {|p| p.data['title'] == 'Super Security'}.first
56
+
57
+ expect(super_security.data['description']).to match /<p>.*<\/p>/m
58
+ expect(super_security.data['description']).to include "<em>secured</em>"
59
+
60
+ test_doc = @site.pages.select {|p| p.data['title'] == 'Some Test Content'}.first
61
+ expect(test_doc.data['body']).to match /<p>.*<\/p>\n\n<h1.*>.*<\/h1>\n\n<p>.*<\/p>/m
62
+ expect(test_doc.data['body']).to include "<strong>Hello</strong>"
63
+
64
+ test_resource = @site.pages.select {|p| p.data['title'] == '/test_resource'}.first
65
+ test_post = test_resource.data['methods'].select {|r| r['method'] == 'post' }.first
66
+ test_post['body']['application/x-www-form-urlencoded']['formParameters'].each do |param|
67
+ expect(param[1]['description']).to match /<p>.*<\/p>/m
68
+ end
69
+ end
70
+
71
+ it 'inserts trait properties into resources that have traits' do
72
+ @rpg.generate(@site)
73
+
74
+ test_resource = @site.pages.select {|p| p.data['title'] == '/test_resource'}.first
75
+ test_post = test_resource.data['methods'].select {|r| r['method'] == 'post' }.first
76
+ expect(test_post['responses']).to include "418"
77
+ expect(test_post['responses']['418']['body']['application/json']['example']).to include "I'm a teapot"
78
+
79
+ # Should not insert a traits properties into pages that do not have that trait
80
+ @site.pages.delete(test_resource)
81
+ @site.pages.each do |page|
82
+ expect(page.data.to_s).not_to include "418"
83
+ end
84
+
85
+ end
86
+
87
+ it 'inserts security properties into resoruces that are secured' do
88
+ @rpg.generate(@site)
89
+
90
+ test_resource = @site.pages.select {|p| p.data['title'] == '/test_resource'}.first
91
+ test_post = test_resource.data['methods'].select {|r| r['method'] == 'post' }.first
92
+
93
+ expect(test_post['responses']).to include "401"
94
+ expect(test_post['responses']['401']['body']['application/json']['example']).to include "Whatcha doin' here?"
95
+ expect(test_post).to include "queryParameters"
96
+ expect(test_post['queryParameters']).to include "auth"
97
+ expect(test_post).to include "headers"
98
+ expect(test_post['headers']).to include "X-SUPER-SECURE"
99
+ expect(test_post['headers']['X-SUPER-SECURE']).to include "displayName"
100
+ expect(test_post['headers']['X-SUPER-SECURE']).to include "type"
101
+ expect(test_post['headers']['X-SUPER-SECURE']).to include "description"
102
+ expect(test_post['headers']['X-SUPER-SECURE']).to include "required"
103
+
104
+
105
+ # Should not insert security properties into pages that are not secured
106
+ @site.pages.delete(test_resource)
107
+ @site.pages.each do |page|
108
+ expect(page.data.to_s).not_to include "401"
109
+ end
110
+
111
+ end
112
+
113
+ it 'creates downloadable RAML and JSON of the API descriptor' do
114
+ @rpg.generate(@site)
115
+ @site.process
116
+ expect(File.file?(File.join('_site', 'api.raml'))).to be true
117
+ api_raml = File.read(File.join('_site', 'api.raml'))
118
+ expect(api_raml).to start_with "#%RAML 0.8"
119
+
120
+ expect(File.file?(File.join('_site', 'api.json'))).to be true
121
+ api_json = File.read(File.join('_site', 'api.json'))
122
+ expect{JSON.parse(api_json)}.not_to raise_error
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "allOf Schema",
4
+ "description": "An example of a schema with an allOf property",
5
+ "type": "object",
6
+ "allOf": [
7
+ { "properties": {
8
+ "foo": {
9
+ "description": "Fooing",
10
+ "type": "string",
11
+ "example": "Foo"
12
+ }
13
+ }
14
+ },
15
+ { "properties": {
16
+ "bar": {
17
+ "description": "A place to get a drink",
18
+ "type": "object"
19
+ }
20
+ }
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "foo": {
3
+ "description": "Fooing",
4
+ "type": "string",
5
+ "example": "Foo"
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Ref Schema",
4
+ "description": "An example of a schema with a $ref",
5
+ "type": "object",
6
+ "properties": {
7
+ "$ref": "spec/spec_assets/json/schema/foo.include.schema.json"
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Simple Schema",
4
+ "description": "An example of a schema with no inheritance",
5
+ "type": "object",
6
+ "properties": {
7
+ "foo": {
8
+ "description": "Fooing",
9
+ "type": "string",
10
+ "example": "Foo"
11
+ },
12
+ "bar": {
13
+ "description": "A place to get a drink",
14
+ "type": "object"
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,73 @@
1
+ #%RAML 0.8
2
+ title: Test!
3
+ documentation:
4
+ - title: Some Test Content
5
+ content: |
6
+ **Hello** and welcome to test content!
7
+
8
+ # Very Important Heading
9
+
10
+ This is all great!
11
+ securitySchemes:
12
+ - "Super Security":
13
+ description: |
14
+ This is a description of the super secure system we employ to secure our
15
+ *secured* api.
16
+ type: x-{other}
17
+ describedBy:
18
+ headers:
19
+ X-SUPER-SECURE:
20
+ description: Super Secure auth token
21
+ type: string
22
+ required: true
23
+ queryParameters:
24
+ auth:
25
+ responses:
26
+ 401:
27
+ body:
28
+ application/json:
29
+ example: |
30
+ {
31
+ "error": "Whatcha doin' here?"
32
+ }
33
+ - "More Security":
34
+ description: |
35
+ This is a description of some more security we employ to secure our
36
+ *secured* api.
37
+ type: x-{other}
38
+ traits:
39
+ - teapot:
40
+ usage: Used to test traits
41
+ responses:
42
+ 418:
43
+ body:
44
+ application/json:
45
+ example: |
46
+ {
47
+ "status": "I'm a teapot"
48
+ }
49
+ /test_resource:
50
+ post:
51
+ description: An example of a schema with no inheritance
52
+ is: [teapot]
53
+ securedBy: ["Super Security"]
54
+ body:
55
+ application/x-www-form-urlencoded:
56
+ formParameters:
57
+ foo:
58
+ description: Fooing
59
+ type: string
60
+ example: Foo
61
+ bar:
62
+ description: A place to get a drink
63
+ type: string
64
+ /nested_test_resource:
65
+ post:
66
+ description: An example of a nested resource
67
+ body:
68
+ application/x-www-form-urlencoded:
69
+ formParameters:
70
+ stuff:
71
+ description: Just some junk
72
+ type: string
73
+ example: Junk
@@ -0,0 +1,109 @@
1
+ require 'deep_clone'
2
+ require 'fakefs/spec_helpers'
3
+ require 'jekyll'
4
+ require 'pry'
5
+ require 'rspec/expectations'
6
+ require_relative '../lib/jekyll-ramler.rb'
7
+
8
+
9
+ RSpec.configure do |config|
10
+ config.include FakeFS::SpecHelpers, fakefs:true
11
+ end
12
+
13
+ def pretty_json(json)
14
+ JSON.pretty_generate(JSON.parse(json))
15
+ end
16
+
17
+ def spec_pwd
18
+ spec_pwd = File.dirname(__FILE__)
19
+ end
20
+
21
+ def example_raml_hash
22
+ raml_hash = {
23
+ 'title' => 'Test!',
24
+ 'resources' => {
25
+ '/test_resource' => {
26
+ 'post' => {
27
+ 'description' => 'An example of a schema with no inheritance',
28
+ 'body' => {
29
+ 'application/x-www-form-urlencoded' => {
30
+ 'formParameters' => {
31
+ 'foo' => {
32
+ 'description' => 'Fooing',
33
+ 'type' => 'string',
34
+ 'example' => 'Foo'
35
+ },
36
+ 'bar' => {
37
+ 'description' => 'A place to get a drink',
38
+ 'type' => 'object'
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ end
48
+
49
+ def load_simple_raml
50
+ JSON.parse(`raml-cop #{File.join(spec_pwd, 'spec_assets/raml/simple.raml')} -j`)
51
+ end
52
+
53
+ def simple_schema
54
+ pretty_json(File.read(File.join(spec_pwd, 'spec_assets/json/schema/simple_schema.schema.json')))
55
+ end
56
+
57
+ def ref_schema
58
+ pretty_json(File.read(File.join(spec_pwd, 'spec_assets/json/schema/ref_schema.schema.json')))
59
+ end
60
+
61
+ def foo_bit
62
+ pretty_json(File.read(File.join(spec_pwd, 'spec_assets/json/schema/foo.include.schema.json')))
63
+ end
64
+
65
+ def allOf_schema
66
+ pretty_json(File.read(File.join(spec_pwd, 'spec_assets/json/schema/allOf_schema.schema.json')))
67
+ end
68
+
69
+ def recursive_resource_search(raml_hash, site, parent='')
70
+ passed = raml_hash['resources'].all? do |resource_hash|
71
+ site.pages.any? do |page|
72
+ page.data['title'] == "#{parent}#{resource_hash['relativeUri']}"
73
+ end
74
+ end
75
+
76
+ if passed
77
+ raml_hash['resources'].each do |resource_hash|
78
+ if resource_hash.include?('resources')
79
+ passed = recursive_resource_search(resource_hash, site, resource_hash['relativeUri'])
80
+ end
81
+ end
82
+ end
83
+
84
+ passed
85
+ end
86
+
87
+ def documentation_search(raml_hash, site)
88
+ raml_hash['documentation'].all? do |resource_hash|
89
+ site.pages.any? do |page|
90
+ page.data['title'] == resource_hash['title']
91
+ end
92
+ end
93
+ end
94
+
95
+ def security_search(raml_hash, site)
96
+ raml_hash['securitySchemes'].all? do |security_hash|
97
+ security_hash.all? do |name, hash|
98
+ site.pages.any? do |page|
99
+ page.data['title'] == name
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ RSpec::Matchers.define :dereference do |expected_json|
106
+ match do |referenced_json|
107
+ !expected_json.include?('$ref') and referenced_json.all? {|k, v| expected_json[k] == v }
108
+ end
109
+ end
@@ -0,0 +1,87 @@
1
+ require_relative './spec_helper.rb'
2
+
3
+ describe 'Utils' do
4
+ context 'JSON Schema Compiler' do
5
+
6
+ before(:each) do
7
+ @jsc = Jekyll::JsonSchemaCompiler.new
8
+ @raml_hash = example_raml_hash
9
+ end
10
+
11
+ it 'does not modify an object that does not include a schema item for application/json' do
12
+ orig_raml_hash = DeepClone.clone @raml_hash
13
+ @raml_hash = @jsc.compile(@raml_hash)
14
+ expect(@raml_hash).to eq orig_raml_hash
15
+
16
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {
17
+ 'example' => "{ 'bar' => {} }"
18
+ }
19
+ orig_raml_hash = DeepClone.clone @raml_hash
20
+ @raml_hash = @jsc.compile(@raml_hash)
21
+ expect(@raml_hash).to eq orig_raml_hash
22
+ end
23
+
24
+ it 'does not modify an object with a schema item for application/json that does not include $ref or allOf' do
25
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {
26
+ 'schema' => simple_schema
27
+ }
28
+ orig_raml_hash = DeepClone.clone @raml_hash
29
+ @raml_hash = @jsc.compile(@raml_hash)
30
+ expect(@raml_hash).to eq orig_raml_hash
31
+ end
32
+
33
+
34
+ it 'replaces $ref items in application/json schema with the referred to content' do
35
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {
36
+ 'schema' => ref_schema
37
+ }
38
+ orig_raml_hash = DeepClone.clone @raml_hash
39
+
40
+ @raml_hash = @jsc.compile(@raml_hash)
41
+ orig_schema = orig_raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
42
+ orig_schema = JSON.parse(orig_schema)
43
+ new_schema = @raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
44
+ new_schema = JSON.parse(new_schema)
45
+
46
+ # The rest of the raml object should be identical
47
+ expect(@raml_hash).to eq(orig_raml_hash)
48
+
49
+ # Compiled, new_schema should include referred to properties
50
+ referenced_json = JSON.parse(foo_bit)
51
+ expect(new_schema['properties']).to dereference(referenced_json)
52
+
53
+ # The rest of the schema should be unchanged
54
+ referenced_json.each { |k, v| new_schema['properties'].delete(k) }
55
+ orig_schema['properties'].delete('$ref')
56
+ expect(new_schema).to eq(orig_schema)
57
+
58
+ end
59
+
60
+ it 'merges allOf items into the parent object in application/json schema items' do
61
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {
62
+ 'schema' => allOf_schema
63
+ }
64
+ orig_raml_hash = DeepClone.clone @raml_hash
65
+
66
+ @raml_hash = @jsc.compile(@raml_hash)
67
+ orig_schema = orig_raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
68
+ orig_schema = JSON.parse(orig_schema)
69
+ new_schema = @raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
70
+ new_schema = JSON.parse(new_schema)
71
+
72
+ # The rest of the raml object should be identical
73
+ expect(@raml_hash).to eq(orig_raml_hash)
74
+
75
+ # Compiled, new_schema should have merged all of the allOf items
76
+ # allOf_schema properties *should* compile to be equal to *simple_schema* properties
77
+ expect(new_schema).not_to include('allOf')
78
+ expect(new_schema['properties']).to eq(JSON.parse(simple_schema)['properties'])
79
+
80
+ # The rest of the schema should be unchanged
81
+ orig_schema.delete('properties')
82
+ orig_schema.delete('allOf')
83
+ new_schema.delete('properties')
84
+ expect(new_schema).to eq(orig_schema)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,91 @@
1
+ require_relative './spec_helper.rb'
2
+
3
+ describe 'Utils' do
4
+ context 'RAML Schema Generator' do
5
+
6
+ before(:each) do
7
+ @raml_hash = example_raml_hash
8
+ @site = Jekyll::Site.new(Jekyll.configuration({
9
+ "skip_config_files" => true,
10
+ "json_schema_schema_uri" => "http://json-schema.org/draft-04/schema#"
11
+ }))
12
+ @rsg = Jekyll::RamlSchemaGenerator.new(@site, 'Simple Schema')
13
+ end
14
+ context '.generate_json_schema' do
15
+ it 'creates a JSON Schema string that includes all properties from application/x-www-form-urlencoded:formParameters' do
16
+ json_schema = JSON.parse(@rsg.generate_json_schema(@raml_hash['resources']['/test_resource']['post']) )
17
+ expect(json_schema['properties']).to eq(JSON.parse(simple_schema)['properties'])
18
+ end
19
+
20
+ it 'creates a JSON Schema with a required attribute if application/x-www-form-urlencoded:formParameters includes a required parameter' do
21
+ @raml_hash['resources']['/test_resource']['post']['body']['application/x-www-form-urlencoded']['formParameters']['bar']['required'] = true
22
+ json_schema = JSON.parse(@rsg.generate_json_schema(@raml_hash['resources']['/test_resource']['post']))
23
+ expect(json_schema).to include('required')
24
+ expect(json_schema['required']).to include('bar')
25
+ expect(json_schema['properties']).to eq(JSON.parse(simple_schema)['properties'])
26
+
27
+ end
28
+
29
+ it 'throws an error if provided RAML does not include body:application/x-www-form-urlencoded:formParameters' do
30
+ body = @raml_hash['resources']['/test_resource']['post'].delete('body')
31
+ expect{@rsg.generate_json_schema(@raml_hash)}.to raise_error(NoMethodError)
32
+ @raml_hash['resources']['/test_resource']['post']['body'] = body
33
+ form = @raml_hash['resources']['/test_resource']['post']['body'].delete('application/x-www-form-urlencoded')
34
+ expect{@rsg.generate_json_schema(@raml_hash)}.to raise_error
35
+ @raml_hash['resources']['/test_resource']['post']['body']['application/x-www-form-urlencoded'] = form
36
+ formParameters = @raml_hash['resources']['/test_resource']['post']['body']['application/x-www-form-urlencoded'].delete('formParameters')
37
+ expect{@rsg.generate_json_schema(@raml_hash)}.to raise_error
38
+ end
39
+ end
40
+
41
+ context '.insert_json_schema' do
42
+ it 'inserts an appropriate string into application/json:schema' do
43
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {}
44
+ orig_raml_hash = DeepClone.clone @raml_hash
45
+
46
+ json_schema = @rsg.generate_json_schema(@raml_hash['resources']['/test_resource']['post'])
47
+ @rsg.insert_json_schema(@raml_hash['resources']['/test_resource']['post'], json_schema)
48
+
49
+ expect(@raml_hash['resources']['/test_resource']['post']['body']['application/json']).to include('schema')
50
+ expect(@raml_hash['resources']['/test_resource']['post']['body']['application/json']['schema']).to eq(json_schema)
51
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
52
+ expect(@raml_hash).to eq(orig_raml_hash)
53
+ end
54
+
55
+ it 'throws an error if provided object does not have expected properties' do
56
+ expect{@rsg.insert_json_schema(@raml_hash, 'foobar')}.to raise_error
57
+ end
58
+ end
59
+
60
+ context '.insert_schemas' do
61
+ it 'inserts an appropriate JSON Schema string in application/json:schema' do
62
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = {}
63
+ orig_raml_hash = DeepClone.clone @raml_hash
64
+ @raml_hash = @rsg.insert_schemas(@raml_hash)
65
+ expect(@raml_hash['resources']['/test_resource']['post']['body']['application/json']).to include('schema')
66
+ expect(@raml_hash['resources']['/test_resource']['post']['body']['application/json']['schema']).to eq(pretty_json(simple_schema))
67
+
68
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'].delete('schema')
69
+ expect(@raml_hash).to eq(orig_raml_hash)
70
+ end
71
+
72
+ it 'does nothing if application/json:schema already exists' do
73
+ orig_schema = 'foobar'
74
+ @raml_hash['resources']['/test_resource']['post']['body']['application/json'] = { 'schema' => orig_schema }
75
+ orig_raml_hash = DeepClone.clone @raml_hash
76
+ @rsg.insert_schemas(@raml_hash)
77
+
78
+ expect(@raml_hash).to eq(orig_raml_hash)
79
+ expect(@raml_hash['resources']['/test_resource']['post']['body']['application/json']['schema']).to eq(orig_schema)
80
+ end
81
+
82
+ it 'does nothing if there is no application/x-www-form-urlencoded:formParameters' do
83
+ @raml_hash['resources']['/test_resource']['post']['body']['application/x-www-form-urlencoded'].delete('formParameters')
84
+ orig_raml_hash = DeepClone.clone @raml_hash
85
+ @rsg.insert_schemas(@raml_hash)
86
+
87
+ expect(@raml_hash).to eq(orig_raml_hash)
88
+ end
89
+ end
90
+ end
91
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-ramler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - GovDelivery
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: "Generates Jekyll pages for overview, security, and \n resource
28
+ documentation specificed in a RAML file."
29
+ email: support@govdelivery.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .travis.yml
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE.md
38
+ - README.md
39
+ - jekyll-ramler.gemspec
40
+ - lib/jekyll-ramler.rb
41
+ - lib/raml-generate.rb
42
+ - lib/utils.rb
43
+ - spec/reference_page_generator_spec.rb
44
+ - spec/spec_assets/json/schema/allOf_schema.schema.json
45
+ - spec/spec_assets/json/schema/foo.include.schema.json
46
+ - spec/spec_assets/json/schema/ref_schema.schema.json
47
+ - spec/spec_assets/json/schema/simple_schema.schema.json
48
+ - spec/spec_assets/raml/simple.raml
49
+ - spec/spec_helper.rb
50
+ - spec/utils_json_schema_compiler_spec.rb
51
+ - spec/utils_raml_schema_generator_spec.rb
52
+ homepage: https://github.com/govdelivery/jekyll-ramler
53
+ licenses:
54
+ - BSD-3-Cluase
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.0.14
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Jekyll plugin that generates API documentation pages based on RAML
76
+ test_files: []