graphqlmd 1.0.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/bin/graphqlmd +56 -0
- data/lib/graphqlmd.rb +167 -0
- data/lib/graphqlmd/consts.rb +106 -0
- data/lib/graphqlmd/version.rb +3 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 75e4efde27cb6b626368452682c61b319ab9ef2ee21f25bf1a6a9e2684e6fc3a
|
4
|
+
data.tar.gz: f5370b610c3628879e2c01d95bd4ac3465ec5dc24fe8a8b536fa0a7fb38bf36c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f51ece8322bb19a14015e111e2e64c8601eb5ed20ae4e7ef314c837ea927fce31e166b6b1acb6369540b8714e88e09e23c2ed4160c6d2e0e1dda3901b8a6b1d6
|
7
|
+
data.tar.gz: 3715e96440f72ee5c7661ae48f63b514c6e1121c9ed130e11a76846f5293ecc0c093d95d34a5b5dc58289d0d3173eb823c11f7e5bc8d3818c2d5d4e3757bb8d4
|
data/bin/graphqlmd
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'graphqlmd'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {
|
7
|
+
url: 'http://localhost:3000/graphql',
|
8
|
+
is_hide_client_mutation_id: true,
|
9
|
+
is_hide_scalar: true,
|
10
|
+
is_hide_deprecated: false,
|
11
|
+
is_allow_links: true,
|
12
|
+
is_vuepress: false
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = 'Usage: graphqlmd [options]'
|
18
|
+
|
19
|
+
opts.on_tail '-v', '--version', 'Show version' do
|
20
|
+
puts "graphqlmd v#{Graphqlmd::VERSION}"
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on(
|
25
|
+
'-u', '--url [URL]', "GraphQL schema url (default: #{options[:url]})"
|
26
|
+
) do |url|
|
27
|
+
options[:url] = url
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on '--no-deprecated', 'Do not add deprecated objects, fields, args and etc.' do
|
31
|
+
options[:is_hide_deprecated] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on '--no-links', 'Do not add links with anchors to docs' do
|
35
|
+
options[:is_allow_links] = false
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on '--client-mutation-id', 'Add clientMutationId to docs' do
|
39
|
+
options[:is_hide_client_mutation_id] = false
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on '--scalar', 'Add scalar objects to docs' do
|
43
|
+
options[:is_hide_scalar] = false
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on '--vuepress', 'Use vuepress additional styles' do
|
47
|
+
options[:is_vuepress] = true
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on_tail '-h', '--help', 'Show this message' do
|
51
|
+
puts opts
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end.parse!
|
55
|
+
|
56
|
+
::Graphqlmd::Graphqlmd.new(options).call
|
data/lib/graphqlmd.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'graphqlmd/consts'
|
2
|
+
require 'graphqlmd/version'
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
class Graphqlmd::Graphqlmd
|
8
|
+
include ::Graphqlmd
|
9
|
+
|
10
|
+
def initialize options
|
11
|
+
@url = options[:url]
|
12
|
+
@is_hide_client_mutation_id = options[:is_hide_client_mutation_id]
|
13
|
+
@is_hide_deprecated = options[:is_hide_deprecated]
|
14
|
+
@is_hide_scalar = options[:is_hide_scalar]
|
15
|
+
@is_allow_links = options[:is_allow_links]
|
16
|
+
@is_vuepress = options[:is_vuepress]
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
response = fetch_schema
|
21
|
+
data = JSON.parse(response.body).dig 'data', 'schema'
|
22
|
+
puts_queries data['queries']
|
23
|
+
puts_mutations data['mutations']
|
24
|
+
puts_objects data['types']
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def puts_queries data
|
30
|
+
print_header 'Queries'
|
31
|
+
queries = data['fields'].sort_by { |v| v['name'] }
|
32
|
+
|
33
|
+
queries.each do |v|
|
34
|
+
puts "\n### #{v['name']}\n"
|
35
|
+
print_deprecation v
|
36
|
+
puts "Return Type | Description\n"
|
37
|
+
puts "-|-\n"
|
38
|
+
puts "#{type_as_string v['type']} | #{print_description(v['description'])}\n"
|
39
|
+
print_args v['args']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def puts_mutations data
|
44
|
+
print_header 'Mutations'
|
45
|
+
mutations = data['fields'].sort_by { |v| v['name'] }
|
46
|
+
mutations = mutations.reject { |v| v['isDeprecated'] } if @is_hide_deprecated
|
47
|
+
|
48
|
+
mutations.each do |v|
|
49
|
+
puts "\n### #{v['name']}\n"
|
50
|
+
print_deprecation v
|
51
|
+
puts "Return Type | Description\n"
|
52
|
+
puts "-|-\n"
|
53
|
+
puts "#{type_as_string v['type']} | #{print_description(v['description'])}\n"
|
54
|
+
print_args v['args']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def puts_objects data
|
59
|
+
print_header 'Objects'
|
60
|
+
objects = data
|
61
|
+
.reject { |v| IGNORED_OBJECT_NAMES.include? v['name'] }
|
62
|
+
.sort_by { |v| v['name'] }
|
63
|
+
objects = objects.reject { |v| v['kind'] == SCALAR } if @is_hide_scalar
|
64
|
+
|
65
|
+
objects.each do |v|
|
66
|
+
puts "\n### #{v['name']}\n"
|
67
|
+
puts "#{print_description v['description']}\n" unless v['description'].nil?
|
68
|
+
print_fields v['fields'] || v['inputFields']
|
69
|
+
end
|
70
|
+
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def print_header value
|
75
|
+
puts "## #{value}\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
def print_fields fields
|
79
|
+
return if fields.nil?
|
80
|
+
return if fields.empty?
|
81
|
+
|
82
|
+
puts "\n**Fields**\n"
|
83
|
+
puts "Name | Type | Description\n"
|
84
|
+
puts "-|-|-\n"
|
85
|
+
fields.each do |v|
|
86
|
+
next if v['name'] == CLIENT_MUTATION_ID && @is_hide_client_mutation_id
|
87
|
+
|
88
|
+
puts "#{v['name']} | #{type_as_string(v['type'])} | #{print_description(v['description'])}\n"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def print_args args
|
93
|
+
return if args.nil?
|
94
|
+
return if args.empty?
|
95
|
+
|
96
|
+
puts "#### Arguments\n"
|
97
|
+
puts "Name | Type | Description\n"
|
98
|
+
puts "-|-|-|-\n"
|
99
|
+
args.each do |v|
|
100
|
+
puts "#{v['name']} | #{type_as_string(v['type'])} | #{print_description(v['description'])}\n"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def print_description value
|
105
|
+
return if value.nil? || value.empty?
|
106
|
+
|
107
|
+
"_#{value}_"
|
108
|
+
end
|
109
|
+
|
110
|
+
def print_deprecation data
|
111
|
+
return unless data['isDeprecated']
|
112
|
+
|
113
|
+
if @is_vuepress
|
114
|
+
puts "::: warning DEPRECATED\n"
|
115
|
+
puts "#{data['deprecationReason']}\n"
|
116
|
+
puts ":::\n\n"
|
117
|
+
else
|
118
|
+
puts "> **DEPRECATED**\n"
|
119
|
+
puts ">\n"
|
120
|
+
puts "> #{data['deprecationReason']}\n\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def type_as_string type
|
125
|
+
is_required = type['kind'] == NON_NULL
|
126
|
+
is_list = type['kind'] == LIST
|
127
|
+
|
128
|
+
if type['name']
|
129
|
+
"#{name_as_link(type)}#{required_postfix(is_required)}"
|
130
|
+
elsif is_list
|
131
|
+
"[#{type_as_string(type['ofType'])}#{required_postfix(is_required)}]"
|
132
|
+
else
|
133
|
+
"#{type_as_string(type['ofType'])}#{required_postfix(is_required)}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def required_postfix is_required
|
138
|
+
is_required ? '!' : ''
|
139
|
+
end
|
140
|
+
|
141
|
+
def name_as_link type
|
142
|
+
return type['name'] unless @is_allow_links
|
143
|
+
return type['name'] if type['kind'] == SCALAR
|
144
|
+
|
145
|
+
"[#{type['name']}](##{type['name'].downcase})"
|
146
|
+
end
|
147
|
+
|
148
|
+
def fetch_schema
|
149
|
+
uri = URI.parse @url
|
150
|
+
|
151
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
152
|
+
request = Net::HTTP::Post.new uri.request_uri, headers
|
153
|
+
request.body = body
|
154
|
+
http.request request
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def headers
|
159
|
+
{
|
160
|
+
'Content-Type' => 'application/json'
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
def body
|
165
|
+
{ query: SCHEMA_QUERY, variables: nil }.to_json
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Graphqlmd
|
2
|
+
SCHEMA_QUERY = <<~QUERY
|
3
|
+
fragment FullType on __Type {
|
4
|
+
kind
|
5
|
+
name
|
6
|
+
description
|
7
|
+
fields(includeDeprecated: true) {
|
8
|
+
name
|
9
|
+
description
|
10
|
+
args {
|
11
|
+
...InputValue
|
12
|
+
}
|
13
|
+
type {
|
14
|
+
...TypeRef
|
15
|
+
}
|
16
|
+
isDeprecated
|
17
|
+
deprecationReason
|
18
|
+
}
|
19
|
+
inputFields {
|
20
|
+
...InputValue
|
21
|
+
}
|
22
|
+
interfaces {
|
23
|
+
...TypeRef
|
24
|
+
}
|
25
|
+
enumValues(includeDeprecated: true) {
|
26
|
+
name
|
27
|
+
isDeprecated
|
28
|
+
deprecationReason
|
29
|
+
}
|
30
|
+
possibleTypes {
|
31
|
+
...TypeRef
|
32
|
+
}
|
33
|
+
}
|
34
|
+
fragment InputValue on __InputValue {
|
35
|
+
name
|
36
|
+
type {
|
37
|
+
...TypeRef
|
38
|
+
}
|
39
|
+
defaultValue
|
40
|
+
}
|
41
|
+
fragment TypeRef on __Type {
|
42
|
+
kind
|
43
|
+
name
|
44
|
+
ofType {
|
45
|
+
kind
|
46
|
+
name
|
47
|
+
ofType {
|
48
|
+
kind
|
49
|
+
name
|
50
|
+
ofType {
|
51
|
+
kind
|
52
|
+
name
|
53
|
+
ofType {
|
54
|
+
kind
|
55
|
+
name
|
56
|
+
ofType {
|
57
|
+
kind
|
58
|
+
name
|
59
|
+
ofType {
|
60
|
+
kind
|
61
|
+
name
|
62
|
+
ofType {
|
63
|
+
kind
|
64
|
+
name
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
{
|
75
|
+
schema:__schema {
|
76
|
+
queries:queryType {
|
77
|
+
...FullType
|
78
|
+
}
|
79
|
+
mutations:mutationType {
|
80
|
+
...FullType
|
81
|
+
}
|
82
|
+
types {
|
83
|
+
...FullType
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
QUERY
|
88
|
+
|
89
|
+
LIST = 'LIST'
|
90
|
+
SCALAR = 'SCALAR'
|
91
|
+
NON_NULL = 'NON_NULL'
|
92
|
+
CLIENT_MUTATION_ID = 'clientMutationId'
|
93
|
+
IGNORED_OBJECT_NAMES = %w[
|
94
|
+
Query
|
95
|
+
Mutation
|
96
|
+
SCALAR
|
97
|
+
__DirectiveLocation
|
98
|
+
__TypeKind
|
99
|
+
__InputValue
|
100
|
+
__EnumValue
|
101
|
+
__Directive
|
102
|
+
__Field
|
103
|
+
__Type
|
104
|
+
__Schema
|
105
|
+
]
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphqlmd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Kalinichev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: This gem will generate markdown by your GraphQL schema
|
14
|
+
email: alex@agileseason.com
|
15
|
+
executables:
|
16
|
+
- graphqlmd
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/graphqlmd
|
21
|
+
- lib/graphqlmd.rb
|
22
|
+
- lib/graphqlmd/consts.rb
|
23
|
+
- lib/graphqlmd/version.rb
|
24
|
+
homepage: https://github.com/blackchestnut/graphqlmd
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubygems_version: 3.0.3
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: graphqlmd
|
47
|
+
test_files: []
|