graphql-docs 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +9 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +23 -0
- data/graphql-docs.gemspec +41 -0
- data/lib/graphql-docs.rb +40 -0
- data/lib/graphql-docs/client.rb +53 -0
- data/lib/graphql-docs/configuration.rb +35 -0
- data/lib/graphql-docs/generator.rb +140 -0
- data/lib/graphql-docs/generator/helpers.rb +46 -0
- data/lib/graphql-docs/layouts/graphql_enums.html +9 -0
- data/lib/graphql-docs/layouts/graphql_input_objects.html +9 -0
- data/lib/graphql-docs/layouts/graphql_interfaces.html +11 -0
- data/lib/graphql-docs/layouts/graphql_mutations.html +11 -0
- data/lib/graphql-docs/layouts/graphql_objects.html +31 -0
- data/lib/graphql-docs/layouts/graphql_scalars.html +3 -0
- data/lib/graphql-docs/layouts/graphql_unions.html +9 -0
- data/lib/graphql-docs/layouts/includes/arguments.html +31 -0
- data/lib/graphql-docs/layouts/includes/connections.html +17 -0
- data/lib/graphql-docs/layouts/includes/fields.html +47 -0
- data/lib/graphql-docs/layouts/includes/input_fields.html +42 -0
- data/lib/graphql-docs/layouts/includes/possible_types.html +9 -0
- data/lib/graphql-docs/layouts/includes/values.html +11 -0
- data/lib/graphql-docs/parser.rb +41 -0
- data/lib/graphql-docs/renderer.rb +46 -0
- data/lib/graphql-docs/version.rb +3 -0
- data/script/bootstrap +5 -0
- data/script/console +11 -0
- metadata +285 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 95ab4bc20c02f63be2acd6f1383fd57184719a7e
|
4
|
+
data.tar.gz: 79679c4f467ceef22e31677a22b4706011c555c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d4d9f76f49551625f2509138f44e90bae1e5643ea736b1b949a2efbd66366acb262b8710813a1afe401515c8525b788ca95a77f60163a9ee1c3c0130c148b418
|
7
|
+
data.tar.gz: 087bfd499ba9196fbd85c6026dd16911b0f270cc81fd162782ad0d1a70822112d55bf745906f03ab21c5d7ea196ddd80fa99c76ee01a776b28819ae0725dc4ec
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2017 Garen Torikian
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# GraphQLDocs
|
2
|
+
|
3
|
+
Easily generate beautiful documentation from your GraphQL schema.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'graphql-docs'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install graphql-docs
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Simple! Call `GraphQLDocs.generate`, taking care to pass in the GraphQL endpoint:
|
24
|
+
|
25
|
+
``` ruby
|
26
|
+
GraphQLDocs.build(url: "http://graphql.org/swapi-graphql/")
|
27
|
+
```
|
28
|
+
|
29
|
+
If you already have the JSON locally, great! Call the same method with `path` instead:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
GraphQLDocs.build(path: "location/to/sw-api.json")
|
33
|
+
```
|
34
|
+
|
35
|
+
If your GraphQL endpoint requires authentication, you can provide a username or password, or an access token:
|
36
|
+
|
37
|
+
``` ruby
|
38
|
+
options = {
|
39
|
+
url: "http://graphql.org/swapi-graphql/"
|
40
|
+
login: "gjtorikian",
|
41
|
+
password: "lolnowai"
|
42
|
+
}
|
43
|
+
GraphQLDocs.build(options)
|
44
|
+
|
45
|
+
options = {
|
46
|
+
url: "http://graphql.org/swapi-graphql/"
|
47
|
+
access_token: "something123"
|
48
|
+
}
|
49
|
+
|
50
|
+
GraphQLDocs.build(options)
|
51
|
+
```
|
52
|
+
|
53
|
+
## Breakdown
|
54
|
+
|
55
|
+
There are three phases going on in one little `GraphQLDocs.build` call:
|
56
|
+
|
57
|
+
* The GraphQL JSON is _fetched_ (if you passed `url`) through `GraphQL::Client` (or simply read if you passed `path`).
|
58
|
+
* `GraphQL::Parser` manipulates that JSON into a slightly saner format.
|
59
|
+
* `GraphQL::Generator` takes that JSON and converts it into HTML.
|
60
|
+
|
61
|
+
If you wanted to, you could break these calls up individually:
|
62
|
+
|
63
|
+
``` ruby
|
64
|
+
client = GraphQLDocs::Client.new(options)
|
65
|
+
response = client.fetch
|
66
|
+
|
67
|
+
# do something
|
68
|
+
|
69
|
+
parser = GraphQLDocs::Parser.new(response, options)
|
70
|
+
parsed_schema = parser.parse
|
71
|
+
|
72
|
+
# do something else
|
73
|
+
generator = Generator.new(parsed_schema, options)
|
74
|
+
|
75
|
+
generator.generate
|
76
|
+
```
|
77
|
+
|
78
|
+
## Generating output
|
79
|
+
|
80
|
+
The HTML generation process uses [html-pipeline](https://github.com/jch/html-pipeline) and ERB to style the output. There are a bunch of default options provided for you, but feel free to override any of these. The *Configuration* section below has more information on what you can change.
|
81
|
+
|
82
|
+
### Herlper methods
|
83
|
+
|
84
|
+
## Development
|
85
|
+
|
86
|
+
After checking out the repo, run `script/bootstrap` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
task default: :test
|
11
|
+
|
12
|
+
task :console do
|
13
|
+
require 'pry'
|
14
|
+
require 'graphql-docs'
|
15
|
+
|
16
|
+
def reload!
|
17
|
+
files = $LOADED_FEATURES.select { |feat| feat =~ /\/graphql-docs\// }
|
18
|
+
files.each { |file| load file }
|
19
|
+
end
|
20
|
+
|
21
|
+
ARGV.clear
|
22
|
+
Pry.start
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'graphql-docs/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'graphql-docs'
|
8
|
+
spec.version = GraphQLDocs::VERSION
|
9
|
+
spec.authors = ['Garen Torikian']
|
10
|
+
spec.email = ['gjtorikian@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Easily generate beautiful documentation from your GraphQL schema.'
|
13
|
+
spec.homepage = 'https://github.com/gjtorikian/graphql-docs'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_dependency 'faraday', '~> 0.11'
|
24
|
+
spec.add_dependency 'graphql', '~> 1.4'
|
25
|
+
|
26
|
+
# rendering
|
27
|
+
spec.add_dependency 'html-pipeline', '2.5.0'
|
28
|
+
spec.add_dependency 'github-markdown', '0.6.9'
|
29
|
+
spec.add_dependency 'extended-markdown-filter', '~> 0.4'
|
30
|
+
spec.add_dependency 'gemoji', '2.1.0'
|
31
|
+
spec.add_dependency 'page-toc-filter', '~> 0.0.1'
|
32
|
+
|
33
|
+
spec.add_development_dependency 'awesome_print'
|
34
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
35
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
36
|
+
spec.add_development_dependency 'minitest-focus', '~> 1.1'
|
37
|
+
spec.add_development_dependency 'pry', '~> 0.10.0'
|
38
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
39
|
+
spec.add_development_dependency 'rubocop-github'
|
40
|
+
spec.add_development_dependency 'webmock', '~> 2.3'
|
41
|
+
end
|
data/lib/graphql-docs.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'graphql-docs/client'
|
2
|
+
require 'graphql-docs/configuration'
|
3
|
+
require 'graphql-docs/generator'
|
4
|
+
require 'graphql-docs/parser'
|
5
|
+
require 'graphql-docs/renderer'
|
6
|
+
require 'graphql-docs/version'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'awesome_print'
|
10
|
+
rescue LoadError; end
|
11
|
+
|
12
|
+
module GraphQLDocs
|
13
|
+
class << self
|
14
|
+
def build(options)
|
15
|
+
options = GraphQLDocs::Configuration::GRAPHQLDOCS_DEFAULTS.merge(options)
|
16
|
+
|
17
|
+
if options[:url].nil? && options[:path].nil?
|
18
|
+
fail ArgumentError, 'No :url or :path provided!'
|
19
|
+
end
|
20
|
+
|
21
|
+
if !options[:url].nil? && !options[:path].nil?
|
22
|
+
fail ArgumentError, 'You can\'t pass both :url and :path!'
|
23
|
+
end
|
24
|
+
|
25
|
+
if options[:url]
|
26
|
+
client = GraphQLDocs::Client.new(options)
|
27
|
+
response = client.fetch
|
28
|
+
else
|
29
|
+
response = File.read(options[:path])
|
30
|
+
end
|
31
|
+
|
32
|
+
parser = GraphQLDocs::Parser.new(response, options)
|
33
|
+
parsed_schema = parser.parse
|
34
|
+
|
35
|
+
generator = Generator.new(parsed_schema, options)
|
36
|
+
|
37
|
+
generator.generate
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'graphql'
|
3
|
+
|
4
|
+
module GraphQLDocs
|
5
|
+
class Client
|
6
|
+
attr_accessor :faraday
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@login = options[:login]
|
10
|
+
@password = options[:password]
|
11
|
+
|
12
|
+
if @login.nil? && !@password.nil?
|
13
|
+
fail ArgumentError, 'Client provided a login, but no password!'
|
14
|
+
end
|
15
|
+
|
16
|
+
if !@login.nil? && @password.nil?
|
17
|
+
fail ArgumentError, 'Client provided a password, but no login!'
|
18
|
+
end
|
19
|
+
|
20
|
+
@access_token = options[:access_token]
|
21
|
+
|
22
|
+
@url = options[:url]
|
23
|
+
@faraday = Faraday.new(url: @url)
|
24
|
+
|
25
|
+
if @login && @password
|
26
|
+
@faraday.basic_auth(@login, @password)
|
27
|
+
elsif @access_token
|
28
|
+
@faraday.authorization('token', @access_token)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def fetch
|
33
|
+
@faraday.post do |req|
|
34
|
+
req.headers['Content-Type'] = 'application/json'
|
35
|
+
req.body = "{ \"query\": \"#{GraphQL::Introspection::INTROSPECTION_QUERY.gsub("\n", '')}\" }"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
inspected = super
|
41
|
+
|
42
|
+
# mask password
|
43
|
+
inspected = inspected.gsub! @password, '*******' if @password
|
44
|
+
|
45
|
+
# Only show last 4 of token, secret
|
46
|
+
if @access_token
|
47
|
+
inspected = inspected.gsub! @access_token, "#{'*'*36}#{@access_token[36..-1]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
inspected
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module GraphQLDocs
|
2
|
+
module Configuration
|
3
|
+
GRAPHQLDOCS_DEFAULTS = {
|
4
|
+
# Client
|
5
|
+
access_token: nil,
|
6
|
+
login: nil,
|
7
|
+
password: nil,
|
8
|
+
path: nil,
|
9
|
+
url: nil,
|
10
|
+
|
11
|
+
# Generating
|
12
|
+
output_dir: './output/',
|
13
|
+
pipeline_config: {
|
14
|
+
pipeline:
|
15
|
+
%i(ExtendedMarkdownFilter
|
16
|
+
EmojiFilter
|
17
|
+
PageTocFilter),
|
18
|
+
context: {
|
19
|
+
gfm: false,
|
20
|
+
asset_root: 'https://a248.e.akamai.net/assets.github.com/images/icons'
|
21
|
+
}
|
22
|
+
},
|
23
|
+
templates: {
|
24
|
+
includes: "#{File.dirname(__FILE__)}/layouts/includes",
|
25
|
+
objects: "#{File.dirname(__FILE__)}/layouts/graphql_objects.html",
|
26
|
+
mutations: "#{File.dirname(__FILE__)}/layouts/graphql_mutations.html",
|
27
|
+
interfaces: "#{File.dirname(__FILE__)}/layouts/graphql_interfaces.html",
|
28
|
+
enums: "#{File.dirname(__FILE__)}/layouts/graphql_enums.html",
|
29
|
+
unions: "#{File.dirname(__FILE__)}/layouts/graphql_unions.html",
|
30
|
+
input_objects: "#{File.dirname(__FILE__)}/layouts/graphql_input_objects.html",
|
31
|
+
scalars: "#{File.dirname(__FILE__)}/layouts/graphql_scalars.html"
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'graphql-docs/generator/helpers'
|
3
|
+
|
4
|
+
module GraphQLDocs
|
5
|
+
class Generator
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
def initialize(parsed_schema, options)
|
9
|
+
@parsed_schema = parsed_schema
|
10
|
+
@options = options
|
11
|
+
|
12
|
+
@renderer = Renderer.new(@options)
|
13
|
+
|
14
|
+
@graphql_object_template = ERB.new(File.read(@options[:templates][:objects]))
|
15
|
+
@graphql_mutations_template = ERB.new(File.read(@options[:templates][:mutations]))
|
16
|
+
@graphql_interfaces_template = ERB.new(File.read(@options[:templates][:interfaces]))
|
17
|
+
@graphql_enums_template = ERB.new(File.read(@options[:templates][:enums]))
|
18
|
+
@graphql_unions_template = ERB.new(File.read(@options[:templates][:unions]))
|
19
|
+
@graphql_input_objects_template = ERB.new(File.read(@options[:templates][:input_objects]))
|
20
|
+
@graphql_scalars_template = ERB.new(File.read(@options[:templates][:scalars]))
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate
|
24
|
+
FileUtils.rm_rf(@options[:output_dir])
|
25
|
+
|
26
|
+
create_graphql_object_pages
|
27
|
+
create_graphql_mutation_pages
|
28
|
+
create_graphql_interface_pages
|
29
|
+
create_graphql_enum_pages
|
30
|
+
create_graphql_union_pages
|
31
|
+
create_graphql_input_object_pages
|
32
|
+
create_graphql_scalar_pages
|
33
|
+
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_graphql_object_pages
|
38
|
+
graphql_object_types.each do |object_type|
|
39
|
+
next if object_type['name'].start_with?('__')
|
40
|
+
opts = { type: object_type }.merge(helper_methods)
|
41
|
+
contents = @graphql_object_template.result(OpenStruct.new(opts).instance_eval { binding })
|
42
|
+
write_file('object', object_type['name'], contents)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_graphql_mutation_pages
|
47
|
+
graphql_mutation_types.each do |mutation|
|
48
|
+
input = graphql_input_object_types.find { |t| t['name'] = mutation['args'].first['type']['ofType']['name'] }
|
49
|
+
payload = graphql_object_types.find { |t| t['name'] == mutation['type']['name'] }
|
50
|
+
|
51
|
+
opts = { type: mutation, input_fields: input, return_fields: payload }.merge(helper_methods)
|
52
|
+
|
53
|
+
contents = @graphql_mutations_template.result(OpenStruct.new(opts).instance_eval { binding })
|
54
|
+
write_file('mutation', mutation['name'], contents)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_graphql_interface_pages
|
59
|
+
graphql_interface_types.each do |interface_type|
|
60
|
+
opts = { type: interface_type }.merge(helper_methods)
|
61
|
+
|
62
|
+
contents = @graphql_interfaces_template.result(OpenStruct.new(opts).instance_eval { binding })
|
63
|
+
write_file('interface', interface_type['name'], contents)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_graphql_enum_pages
|
68
|
+
graphql_enum_types.each do |enum_type|
|
69
|
+
opts = { type: enum_type }.merge(helper_methods)
|
70
|
+
|
71
|
+
contents = @graphql_enums_template.result(OpenStruct.new(opts).instance_eval { binding })
|
72
|
+
write_file('enum', enum_type['name'], contents)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_graphql_union_pages
|
77
|
+
graphql_union_types.each do |union_type|
|
78
|
+
opts = { type: union_type }.merge(helper_methods)
|
79
|
+
|
80
|
+
contents = @graphql_unions_template.result(OpenStruct.new(opts).instance_eval { binding })
|
81
|
+
write_file('union', union_type['name'], contents)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_graphql_input_object_pages
|
86
|
+
graphql_input_object_types.each do |input_object_type|
|
87
|
+
opts = { type: input_object_type }.merge(helper_methods)
|
88
|
+
|
89
|
+
contents = @graphql_input_objects_template.result(OpenStruct.new(opts).instance_eval { binding })
|
90
|
+
write_file('input_object', input_object_type['name'], contents)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_graphql_scalar_pages
|
95
|
+
graphql_scalar_types.each do |scalar_type|
|
96
|
+
opts = { type: scalar_type }.merge(helper_methods)
|
97
|
+
|
98
|
+
contents = @graphql_scalars_template.result(OpenStruct.new(opts).instance_eval { binding })
|
99
|
+
write_file('scalar', scalar_type['name'], contents)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def graphql_mutation_types
|
106
|
+
graphql_object_types.find { |t| t['name'] == 'Mutation' }['fields']
|
107
|
+
end
|
108
|
+
|
109
|
+
def graphql_object_types
|
110
|
+
@parsed_schema['object_types']
|
111
|
+
end
|
112
|
+
|
113
|
+
def graphql_interface_types
|
114
|
+
@parsed_schema['interface_types']
|
115
|
+
end
|
116
|
+
|
117
|
+
def graphql_enum_types
|
118
|
+
@parsed_schema['enum_types']
|
119
|
+
end
|
120
|
+
|
121
|
+
def graphql_union_types
|
122
|
+
@parsed_schema['union_types']
|
123
|
+
end
|
124
|
+
|
125
|
+
def graphql_input_object_types
|
126
|
+
@parsed_schema['input_object_types']
|
127
|
+
end
|
128
|
+
|
129
|
+
def graphql_scalar_types
|
130
|
+
@parsed_schema['scalar_types']
|
131
|
+
end
|
132
|
+
|
133
|
+
def write_file(type, name, contents)
|
134
|
+
path = File.join(@options[:output_dir], type, name.downcase)
|
135
|
+
FileUtils.mkdir_p(path)
|
136
|
+
contents = @renderer.render(contents)
|
137
|
+
File.write(File.join(path, 'index.html'), contents)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module GraphQLDocs
|
2
|
+
class Generator
|
3
|
+
module Helpers
|
4
|
+
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
|
5
|
+
|
6
|
+
attr_accessor :templates
|
7
|
+
|
8
|
+
def slugify(str)
|
9
|
+
slug = str.gsub(SLUGIFY_PRETTY_REGEXP, '-')
|
10
|
+
slug.gsub!(%r!^\-|\-$!i, '')
|
11
|
+
slug.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def include(filename, opts)
|
15
|
+
template = fetch_include(filename)
|
16
|
+
template.result(OpenStruct.new(opts.merge(helper_methods)).instance_eval { binding })
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_include(filename)
|
20
|
+
@templates ||= {}
|
21
|
+
|
22
|
+
return @templates[filename] unless @templates[filename].nil?
|
23
|
+
|
24
|
+
@templates[filename] = ERB.new(File.read(File.join(@options[:templates][:includes], filename)))
|
25
|
+
@templates[filename]
|
26
|
+
end
|
27
|
+
|
28
|
+
def markdown(string)
|
29
|
+
GitHub::Markdown.render(string || 'n/a')
|
30
|
+
end
|
31
|
+
|
32
|
+
def helper_methods
|
33
|
+
return @helper_methods if defined?(@helper_methods)
|
34
|
+
|
35
|
+
@helper_methods = {}
|
36
|
+
|
37
|
+
Helpers.instance_methods.each do |name|
|
38
|
+
next if name == :helper_methods
|
39
|
+
@helper_methods[name] = method(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
@helper_methods
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
## <%= type['name'] %>
|
2
|
+
|
3
|
+
<%= type['description'] %>
|
4
|
+
|
5
|
+
<% unless type['interfaces'].empty? %>
|
6
|
+
|
7
|
+
### Implements
|
8
|
+
|
9
|
+
<ul>
|
10
|
+
<% type['interfaces'].each do |interface| %>
|
11
|
+
<li><code><a href="./interface/<%= slugify.(interface['name']) %>"><%= interface['name'] %></a></code></li>
|
12
|
+
<% end %>
|
13
|
+
</ul>
|
14
|
+
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<% unless type['connections'].empty? %>
|
18
|
+
|
19
|
+
### Connections
|
20
|
+
|
21
|
+
<%= include.('connections.html', connections: type['connections']) %>
|
22
|
+
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<% unless type['fields'].empty? %>
|
26
|
+
|
27
|
+
### Fields
|
28
|
+
|
29
|
+
<%= include.('fields.html', fields: type['fields']) %>
|
30
|
+
|
31
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<table class="arguments" markdown="1">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th>Argument</th>
|
5
|
+
<th>Type</th>
|
6
|
+
<th>Description</th>
|
7
|
+
</tr>
|
8
|
+
</thead>
|
9
|
+
<tbody>
|
10
|
+
<% args.each do |argument| %>
|
11
|
+
<tr>
|
12
|
+
<td><code><%= argument['name'] %><code></td>
|
13
|
+
<td>
|
14
|
+
|
15
|
+
<% if argument['type']['name'] == "Non-Null" %>
|
16
|
+
<% @arg_path = argument['type']['ofType']['kind'] %>
|
17
|
+
<% @arg_name = argument['type']['ofType']['name'] %>
|
18
|
+
<% else %>
|
19
|
+
<% @arg_path = argument['type']['kind'] %>
|
20
|
+
<% @arg_name = argument['type']['name'] %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<code><%= @arg_name %></code>
|
24
|
+
</td>
|
25
|
+
<td>
|
26
|
+
<p><%= markdown.(argument['description']) %></p>
|
27
|
+
</td>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<% connections.each do |connection| %>
|
2
|
+
|
3
|
+
<div class="field-entry my-4">
|
4
|
+
<span class="field-name connection-name"><%= connection['name'] %> (<a href="./object/<%= slugify.(connection['type']['ofType']['name']) %>" class="js-connection-name"><code><%= connection['type']['ofType']['name'] %></code></a>)</span>
|
5
|
+
|
6
|
+
<div class="description-wrapper">
|
7
|
+
<%= connection['description'] %>
|
8
|
+
|
9
|
+
<% unless connection['args'].empty? %>
|
10
|
+
|
11
|
+
<%= include.('arguments.html', args: connection['args']) %>
|
12
|
+
|
13
|
+
<% end %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<% end %>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<% fields.each do |field| %>
|
2
|
+
|
3
|
+
<% next if field['type']['ofType'] && field['type']['ofType']['name'] && field['type']['ofType']['name'].end_with?('Connection') %>
|
4
|
+
|
5
|
+
<div class="field-entry">
|
6
|
+
<% next if field['name'] == "id" || field['name'].blank? %>
|
7
|
+
|
8
|
+
<% if field['type']['ofType'] && !field['type']['ofType']['ofType'].nil? %>
|
9
|
+
<% if !field['type']['ofType']['ofType']['ofType'].nil? %>
|
10
|
+
<% @type_path = field['type']['ofType']['ofType']['ofType']['kind'] %>
|
11
|
+
<% @type_name = field['type']['ofType']['ofType']['ofType']['name'] %>
|
12
|
+
<% else %>
|
13
|
+
<% @type_path = field['type']['ofType']['ofType']['kind'] %>
|
14
|
+
<% @type_name = field['type']['ofType']['ofType']['name'] %>
|
15
|
+
<% end %>
|
16
|
+
<% elsif field['type']['ofType'].blank? %>
|
17
|
+
<% @type_path = field['type']['kind'] %>
|
18
|
+
<% @type_name = field['type']['name'] %>
|
19
|
+
<% elsif field['type']['name'] == "Non-Null" || field['type']['ofType']['name'] == "Non-Null" %>
|
20
|
+
<% @type_path = field['type']['ofType']['kind'] %>
|
21
|
+
<% @type_name = field['type']['ofType']['name'] %>
|
22
|
+
<% else %>
|
23
|
+
<% @type_path = field['type']['ofType']['kind'] %>
|
24
|
+
<% @type_name = field['type']['ofType']['name'] %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<span class="field-name"><%= field['name'] %> (<code><a href="./<%= @type_path.downcase %>/<%= slugify.(@type_name) %>"><%= @type_name %></a></code>)</span>
|
28
|
+
|
29
|
+
<div class="description-wrapper">
|
30
|
+
<% if field['isDeprecated'] %>
|
31
|
+
<div class="deprecation-notice">
|
32
|
+
<span class="deprecation-title">Deprecation notice</span>
|
33
|
+
<%= markdown.(field['deprecationReason']) %>
|
34
|
+
</div>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<%= markdown.(field['description']) %>
|
38
|
+
|
39
|
+
<% unless field['args'].blank? %>
|
40
|
+
|
41
|
+
<%= include.('arguments.html', args: field['args']) %>
|
42
|
+
|
43
|
+
<% end %>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<% end %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
### Input Fields
|
2
|
+
|
3
|
+
<% input_fields.each do |field| %>
|
4
|
+
|
5
|
+
<% next if field['type']['ofType'] && field['type']['ofType']['name'] && field['type']['ofType']['name'].end_with?('Connection') %>
|
6
|
+
|
7
|
+
<div class="field-entry">
|
8
|
+
<% next if field['name'] == "id" || field['name'].blank? %>
|
9
|
+
|
10
|
+
<% if field['type']['ofType'] && !field['type']['ofType']['ofType'].nil? %>
|
11
|
+
<% if !field['type']['ofType']['ofType']['ofType'].nil? %>
|
12
|
+
<% @type_path = field['type']['ofType']['ofType']['ofType']['kind'] %>
|
13
|
+
<% @type_name = field['type']['ofType']['ofType']['ofType']['name'] %>
|
14
|
+
<% else %>
|
15
|
+
<% @type_path = field['type']['ofType']['ofType']['kind'] %>
|
16
|
+
<% @type_name = field['type']['ofType']['ofType']['name'] %>
|
17
|
+
<% end %>
|
18
|
+
<% elsif field['type']['ofType'].blank? %>
|
19
|
+
<% @type_path = field['type']['kind'] %>
|
20
|
+
<% @type_name = field['type']['name'] %>
|
21
|
+
<% elsif field['type']['name'] == "Non-Null" || field['type']['ofType']['name'] == "Non-Null" %>
|
22
|
+
<% @type_path = field['type']['ofType']['kind'] %>
|
23
|
+
<% @type_name = field['type']['ofType']['name'] %>
|
24
|
+
<% else %>
|
25
|
+
<% @type_path = field['type']['ofType']['kind'] %>
|
26
|
+
<% @type_name = field['type']['ofType']['name'] %>
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<span class="field-name"><%= field['name'] %> (<a href="./<%= @type_path.downcase %>/slugify.(@type_name.parameterize)"><code><%= @type_name %></code></a>)</span>
|
30
|
+
|
31
|
+
<div class="description-wrapper">
|
32
|
+
<%= field['description'] %>
|
33
|
+
|
34
|
+
<% unless field['args'].nil? %>
|
35
|
+
|
36
|
+
<%= include.('arguments.html', args: field['args']) %>
|
37
|
+
|
38
|
+
<% end %>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module GraphQLDocs
|
2
|
+
class Parser
|
3
|
+
attr_reader :schema, :processed_schema
|
4
|
+
|
5
|
+
def initialize(response, options)
|
6
|
+
@options = options
|
7
|
+
@schema = JSON.parse(response)['data']
|
8
|
+
@processed_schema = @schema.dup['__schema']
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse
|
12
|
+
# sort the types
|
13
|
+
@processed_schema['types'] = @processed_schema['types'].sort_by { |key, _| key['name'] }
|
14
|
+
|
15
|
+
# fetch the connections
|
16
|
+
@processed_schema['types'].each do |object|
|
17
|
+
next if object['fields'].nil?
|
18
|
+
object['connections'] = object['fields'].select { |f| next if f.is_a?(Array); connection?(f) }
|
19
|
+
end
|
20
|
+
|
21
|
+
# fetch the kinds of items
|
22
|
+
type_kinds = @processed_schema['types'].map { |h| h['kind'] }.uniq
|
23
|
+
type_kinds.each do |kind|
|
24
|
+
@processed_schema["#{kind.downcase}_types"] = @processed_schema['types'].select { |t| t['kind'] == kind }
|
25
|
+
end
|
26
|
+
# TODO: should the 'types' key be deleted now?
|
27
|
+
|
28
|
+
@processed_schema
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def connection?(hash)
|
34
|
+
if hash['type']['ofType'] && hash['type']['ofType']['name'] && hash['type']['ofType']['name'].end_with?('Connection')
|
35
|
+
true
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'html/pipeline'
|
2
|
+
require 'extended-markdown-filter'
|
3
|
+
require 'page-toc-filter'
|
4
|
+
|
5
|
+
module GraphQLDocs
|
6
|
+
class Renderer
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
|
10
|
+
@pipeline_config = @options[:pipeline_config]
|
11
|
+
|
12
|
+
filters = @pipeline_config[:pipeline].map do |f|
|
13
|
+
if filter?(f)
|
14
|
+
f
|
15
|
+
else
|
16
|
+
key = filter_key(f)
|
17
|
+
filter = HTML::Pipeline.constants.find { |c| c.downcase == key }
|
18
|
+
# possibly a custom filter
|
19
|
+
if filter.nil?
|
20
|
+
Kernel.const_get(f)
|
21
|
+
else
|
22
|
+
HTML::Pipeline.const_get(filter)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@pipeline = HTML::Pipeline.new(filters, @pipeline_config[:context])
|
28
|
+
end
|
29
|
+
|
30
|
+
def render(string)
|
31
|
+
@pipeline.to_html(string)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def filter_key(s)
|
37
|
+
s.downcase
|
38
|
+
end
|
39
|
+
|
40
|
+
def filter?(f)
|
41
|
+
f < HTML::Pipeline::Filter
|
42
|
+
rescue LoadError, ArgumentError
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/script/bootstrap
ADDED
data/script/console
ADDED
metadata
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphql-docs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Garen Torikian
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-02-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.11'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: graphql
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: html-pipeline
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: github-markdown
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.6.9
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.6.9
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: extended-markdown-filter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.4'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: gemoji
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.1.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.1.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: page-toc-filter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.0.1
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.0.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: awesome_print
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: bundler
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.14'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.14'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: minitest
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '5.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '5.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: minitest-focus
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.1'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.1'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: pry
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.10.0
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.10.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rake
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '10.0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '10.0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rubocop-github
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: webmock
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '2.3'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '2.3'
|
223
|
+
description:
|
224
|
+
email:
|
225
|
+
- gjtorikian@gmail.com
|
226
|
+
executables: []
|
227
|
+
extensions: []
|
228
|
+
extra_rdoc_files: []
|
229
|
+
files:
|
230
|
+
- ".gitignore"
|
231
|
+
- ".rubocop.yml"
|
232
|
+
- ".travis.yml"
|
233
|
+
- Gemfile
|
234
|
+
- LICENSE.txt
|
235
|
+
- README.md
|
236
|
+
- Rakefile
|
237
|
+
- graphql-docs.gemspec
|
238
|
+
- lib/graphql-docs.rb
|
239
|
+
- lib/graphql-docs/client.rb
|
240
|
+
- lib/graphql-docs/configuration.rb
|
241
|
+
- lib/graphql-docs/generator.rb
|
242
|
+
- lib/graphql-docs/generator/helpers.rb
|
243
|
+
- lib/graphql-docs/layouts/graphql_enums.html
|
244
|
+
- lib/graphql-docs/layouts/graphql_input_objects.html
|
245
|
+
- lib/graphql-docs/layouts/graphql_interfaces.html
|
246
|
+
- lib/graphql-docs/layouts/graphql_mutations.html
|
247
|
+
- lib/graphql-docs/layouts/graphql_objects.html
|
248
|
+
- lib/graphql-docs/layouts/graphql_scalars.html
|
249
|
+
- lib/graphql-docs/layouts/graphql_unions.html
|
250
|
+
- lib/graphql-docs/layouts/includes/arguments.html
|
251
|
+
- lib/graphql-docs/layouts/includes/connections.html
|
252
|
+
- lib/graphql-docs/layouts/includes/fields.html
|
253
|
+
- lib/graphql-docs/layouts/includes/input_fields.html
|
254
|
+
- lib/graphql-docs/layouts/includes/possible_types.html
|
255
|
+
- lib/graphql-docs/layouts/includes/values.html
|
256
|
+
- lib/graphql-docs/parser.rb
|
257
|
+
- lib/graphql-docs/renderer.rb
|
258
|
+
- lib/graphql-docs/version.rb
|
259
|
+
- script/bootstrap
|
260
|
+
- script/console
|
261
|
+
homepage: https://github.com/gjtorikian/graphql-docs
|
262
|
+
licenses:
|
263
|
+
- MIT
|
264
|
+
metadata: {}
|
265
|
+
post_install_message:
|
266
|
+
rdoc_options: []
|
267
|
+
require_paths:
|
268
|
+
- lib
|
269
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
270
|
+
requirements:
|
271
|
+
- - ">="
|
272
|
+
- !ruby/object:Gem::Version
|
273
|
+
version: '0'
|
274
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - ">="
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '0'
|
279
|
+
requirements: []
|
280
|
+
rubyforge_project:
|
281
|
+
rubygems_version: 2.4.5.1
|
282
|
+
signing_key:
|
283
|
+
specification_version: 4
|
284
|
+
summary: Easily generate beautiful documentation from your GraphQL schema.
|
285
|
+
test_files: []
|