graphql-docs 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbf28a678c378ebc2d54f6e5b7b24a05bd3eb577f144b9042fe11c4e7f34bd13
4
- data.tar.gz: 993ad8805892c0544128baabec9dfd4f5bfb1cf16fccbe5cc43c3373036fcbbd
3
+ metadata.gz: cd0680cb4e1d09c704fe10170e4f48340b845a96ec6a91420a1b379cf7b217fd
4
+ data.tar.gz: dde6edd6ff1dc7c70eab9495cb7f27aacfa3e770815f8bd26c7ddbb71cc05793
5
5
  SHA512:
6
- metadata.gz: 94e80febfa9d2c367182afd21b6a0d3e1206ec3d076a6b774ecfb96308648e4e582e818d1ac4f0b0734aaad514e46edac8a50f9ecb6baddf1370790e5eee7f38
7
- data.tar.gz: 549077a6761dd67e983ab2c6bb402d5d67cfecafde214ddc57a7580439012eeb6a68ae6f0ff2091076d56eb64449aae9c055d87dc6e8a9da3fec081f51806d76
6
+ metadata.gz: 71424bfe5ab2367fa0c1ac4721104dab9eda558b593293dbc46d6097bd01bfc1670a45adb4a75456f980ebb7f22eaf5b30485b3c2a2fb7b6cc7ee24e91d2bad6
7
+ data.tar.gz: a1ac5a15d011d9f750c15745a92e3d88a1035a729fd4a9486b159a7fa263e7a0226e3340fe262fa8624428a63d452c884ba60d262b7c51e33109b83cc3700d61
@@ -8,7 +8,7 @@ jobs:
8
8
 
9
9
  strategy:
10
10
  matrix:
11
- ruby-version: [3.3, 3.2, 3.1]
11
+ ruby-version: [3.4, 3.3, 3.2, 3.1]
12
12
 
13
13
  steps:
14
14
  - uses: actions/checkout@v2
data/.rubocop.yml CHANGED
@@ -6,3 +6,6 @@ Style/StringLiterals:
6
6
 
7
7
  Naming/FileName:
8
8
  Enabled: false
9
+
10
+ Layout/IndentationWidth:
11
+ Width: 2
data/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ A concise overview of the public-facing changes to the gem from version to versi
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v5.2.0 - 2025-02-09
8
+
9
+ - Add search filter to sidebar. Thanks @denisahearn!
10
+
11
+ ## v5.1.0 - 2024-12-09
12
+
13
+ - List queries in the sidebar, similar to mutations. See https://github.com/brettchalupa/graphql-docs/pull/156. Thanks @denisahearn!
14
+ - Fix Sass `@import` deprecation
15
+ - Add ostruct and logger gems to dependencies since they're being removed from the Ruby standard library in a future release
16
+ - Test and fixture improvements
17
+
7
18
  ## v5.0.0 - 2024-07-03
8
19
 
9
20
  - **breaking**: The graphql gem 2.2.0+ breaks some of the parsing and displaying of comments from a GraphQL schema file
data/CONTRIBUTING.md CHANGED
@@ -1,4 +1,4 @@
1
- # Contribuing Guide
1
+ # Contributing Guide
2
2
 
3
3
  Contributions to this project are welcome. If you have an idea for a bigger change, [open an issue first](https://github.com/brettchalupa/graphql-docs/issues/new/choose) and we can discuss it.
4
4
 
data/README.md CHANGED
@@ -222,6 +222,15 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
222
222
  `bin/rake test` to run the tests. You can also run `bin/console` for
223
223
  an interactive prompt that will allow you to experiment.
224
224
 
225
+ ### Releasing a new version of the gem
226
+
227
+ 1. Update CHANGELOG.md
228
+ 2. Bump the version in `lib/graphql-docs/version.rb`
229
+ 3. Make a commit and tag it with `git commit -a vX.X.X`
230
+ 4. Push the commit and tags to GitHub: `git push origin main && git push --tags`
231
+ 5. Build the gem: `gem build`
232
+ 6. Push the gem to RubyGems.org: `gem push graphql-docs-X.X.X.gem`
233
+
225
234
  ## Sample Site
226
235
 
227
236
  Clone this repository and run:
data/graphql-docs.gemspec CHANGED
@@ -44,9 +44,11 @@ Gem::Specification.new do |spec|
44
44
  spec.add_dependency 'gemoji', '~> 3.0'
45
45
  spec.add_dependency 'html-pipeline', '>= 2.14.3', '~> 2.14'
46
46
  spec.add_dependency 'sass-embedded', '~> 1.58'
47
+ spec.add_dependency 'ostruct', '~> 0.6'
48
+ spec.add_dependency 'logger', '~> 1.6'
47
49
 
48
50
  spec.add_development_dependency 'html-proofer', '~> 3.4'
49
- spec.add_development_dependency 'minitest', '~> 5.0'
51
+ spec.add_development_dependency 'minitest', '~> 5.24'
50
52
  spec.add_development_dependency 'minitest-focus', '~> 1.1'
51
53
  spec.add_development_dependency 'rake', '~> 13.0'
52
54
  spec.add_development_dependency 'rubocop', '~> 1.37'
@@ -32,6 +32,7 @@ module GraphQLDocs
32
32
 
33
33
  operations: "#{File.dirname(__FILE__)}/layouts/graphql_operations.html",
34
34
  objects: "#{File.dirname(__FILE__)}/layouts/graphql_objects.html",
35
+ queries: "#{File.dirname(__FILE__)}/layouts/graphql_queries.html",
35
36
  mutations: "#{File.dirname(__FILE__)}/layouts/graphql_mutations.html",
36
37
  interfaces: "#{File.dirname(__FILE__)}/layouts/graphql_interfaces.html",
37
38
  enums: "#{File.dirname(__FILE__)}/layouts/graphql_enums.html",
@@ -17,7 +17,7 @@ module GraphQLDocs
17
17
 
18
18
  @renderer = @options[:renderer].new(@parsed_schema, @options)
19
19
 
20
- %i[operations objects mutations interfaces enums unions input_objects scalars directives].each do |sym|
20
+ %i[operations objects queries mutations interfaces enums unions input_objects scalars directives].each do |sym|
21
21
  raise IOError, "`#{sym}` template #{@options[:templates][sym]} was not found" unless File.exist?(@options[:templates][sym])
22
22
 
23
23
  instance_variable_set("@graphql_#{sym}_template", ERB.new(File.read(@options[:templates][sym])))
@@ -52,8 +52,9 @@ module GraphQLDocs
52
52
  def generate
53
53
  FileUtils.rm_rf(@options[:output_dir]) if @options[:delete_output]
54
54
 
55
- has_query = create_graphql_query_pages
55
+ has_query = create_graphql_operation_pages
56
56
  create_graphql_object_pages
57
+ create_graphql_query_pages
57
58
  create_graphql_mutation_pages
58
59
  create_graphql_interface_pages
59
60
  create_graphql_enum_pages
@@ -96,7 +97,7 @@ module GraphQLDocs
96
97
  true
97
98
  end
98
99
 
99
- def create_graphql_query_pages
100
+ def create_graphql_operation_pages
100
101
  graphql_operation_types.each do |query_type|
101
102
  metadata = ''
102
103
  next unless query_type[:name] == graphql_root_types['query']
@@ -129,6 +130,15 @@ module GraphQLDocs
129
130
  end
130
131
  end
131
132
 
133
+ def create_graphql_query_pages
134
+ graphql_query_types.each do |query|
135
+ opts = default_generator_options(type: query)
136
+
137
+ contents = @graphql_queries_template.result(OpenStruct.new(opts).instance_eval { binding })
138
+ write_file('query', query[:name], contents)
139
+ end
140
+ end
141
+
132
142
  def create_graphql_mutation_pages
133
143
  graphql_mutation_types.each do |mutation|
134
144
  opts = default_generator_options(type: mutation)
@@ -36,6 +36,10 @@ module GraphQLDocs
36
36
  @parsed_schema[:operation_types] || []
37
37
  end
38
38
 
39
+ def graphql_query_types
40
+ @parsed_schema[:query_types] || []
41
+ end
42
+
39
43
  def graphql_mutation_types
40
44
  @parsed_schema[:mutation_types] || []
41
45
  end
@@ -1,4 +1,8 @@
1
1
  ---
2
2
  title: Queries
3
3
  ---
4
- Every GraphQL schema has a root type for both queries and mutations. The [query type](http://spec.graphql.org/draft/#sec-Type-System) defines GraphQL operations that retrieve data from the server.
4
+ Every GraphQL schema has a root type for both queries and mutations.
5
+
6
+ The query type defines GraphQL operations that retrieve data from the server.
7
+
8
+ For more information, see [the GraphQL spec](http://spec.graphql.org/draft/#sec-Type-System).
@@ -69,6 +69,38 @@
69
69
  }
70
70
  }
71
71
  }
72
+ #search {
73
+ display: flex;
74
+ position: relative;
75
+ align-items: center;
76
+ border: 1px solid #ddd;
77
+ border-radius: 5px;
78
+ padding: 0.01em 16px;
79
+ margin-bottom: 20px;
80
+
81
+ img {
82
+ position: absolute;
83
+ left: 10px;
84
+ height: 16px;
85
+ width: 16px;
86
+ }
87
+
88
+ input {
89
+ height: 24px;
90
+ line-height: 1.5;
91
+ width: 100%;
92
+ padding-left: 15px;
93
+ background-color: transparent;
94
+ color: #444;
95
+ border: none;
96
+ font-size: 14px;
97
+ font-family: 'ProximaNova-Semibold';
98
+ }
99
+
100
+ input:focus {
101
+ outline: none;
102
+ }
103
+ }
72
104
  }
73
105
 
74
106
  #sidebar-mobile {
@@ -1,7 +1,8 @@
1
1
  @charset "utf-8";
2
2
 
3
- @import "../_sass/_normalize.scss";
4
- @import "../_sass/_fonts";
3
+ @use "sass:meta";
4
+ @use "../_sass/_normalize.scss";
5
+ @use "../_sass/_fonts";
5
6
 
6
7
  body {
7
8
  font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
@@ -39,11 +40,11 @@ em {
39
40
  font-family: 'ProximaNova-Semibold';
40
41
  }
41
42
 
42
- @import '../_sass/_header';
43
- @import '../_sass/_sidebar';
44
- @import '../_sass/_content';
45
- @import '../_sass/_types';
46
- @import '../_sass/_mobile';
47
- @import '../_sass/_api-box';
48
- @import '../_sass/_syntax';
49
- @import '../_sass/_deprecations';
43
+ @include meta.load-css('../_sass/_header');
44
+ @include meta.load-css('../_sass/_sidebar');
45
+ @include meta.load-css('../_sass/_content');
46
+ @include meta.load-css('../_sass/_types');
47
+ @include meta.load-css('../_sass/_mobile');
48
+ @include meta.load-css('../_sass/_api-box');
49
+ @include meta.load-css('../_sass/_syntax');
50
+ @include meta.load-css('../_sass/_deprecations');
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14" />
3
+ </svg>
@@ -9,16 +9,71 @@
9
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.2.2/anchor.min.js"></script>
10
10
  <script>
11
11
 
12
- // Add anchors on DOMContentLoaded
13
12
  document.addEventListener("DOMContentLoaded", function(event) {
13
+ // Add anchors
14
14
  anchors.options = {
15
15
  placement: 'left',
16
16
  visible: 'hover',
17
17
  icon: '¶'
18
18
  };
19
19
  anchors.add('h2, h3, h4, h5, h6, .anchored');
20
+
21
+ // Add listener for search filter input
22
+ const sidebarDiv = document.getElementById('sidebar');
23
+ const searchDiv = sidebarDiv.querySelector('#search')
24
+
25
+ if (searchDiv) {
26
+ const searchInput = searchDiv.querySelector('input');
27
+ const menuElements = sidebarDiv.querySelectorAll('ul.menu-root');
28
+
29
+ const listener = debounce((event) => {
30
+ const searchValue = event.target.value;
31
+ applySearchFilter(searchValue, menuElements)
32
+ }, 500);
33
+
34
+ searchInput.addEventListener('input', listener);
35
+ }
20
36
  });
21
37
 
38
+ function debounce(func, wait) {
39
+ let timeout;
40
+
41
+ return function executedFunction(...args) {
42
+ const later = () => {
43
+ clearTimeout(timeout);
44
+ func(...args);
45
+ };
46
+
47
+ clearTimeout(timeout);
48
+ timeout = setTimeout(later, wait);
49
+ };
50
+ }
51
+
52
+ function applySearchFilter(searchValue, menuElements) {
53
+ menuElements.forEach(menuElement => {
54
+ const listElements = menuElement.getElementsByTagName('li');
55
+ let hasVisibleElements = false;
56
+ Array.from(listElements).forEach(listElement => {
57
+ let contains = true
58
+ if (searchValue.length > 0) {
59
+ const anchorElement = listElement.querySelector('a');
60
+ const textContent = anchorElement.innerText;
61
+ contains = textContent.toLowerCase().includes(searchValue.toLowerCase());
62
+ }
63
+
64
+ // Hide the list element if its text does not contain the search value
65
+ listElement.style.display = contains ? '' : 'none';
66
+
67
+ if (contains) {
68
+ hasVisibleElements = true;
69
+ }
70
+ });
71
+
72
+ // Hide the entire menu if none of the list items are visible
73
+ const menuParentElement = menuElement.closest('li')
74
+ menuParentElement.style.display = hasVisibleElements ? '' : 'none';
75
+ });
76
+ }
22
77
  </script>
23
78
  </head>
24
79
  <body>
@@ -1,19 +1,3 @@
1
1
  <h1><%= type[:name] %></h1>
2
2
 
3
3
  <%= type[:description] %>
4
-
5
- <% unless type[:connections].empty? %>
6
-
7
- <h2>Connections</h2>
8
-
9
- <%= include.('connections.html', connections: type[:connections]) %>
10
-
11
- <% end %>
12
-
13
- <% unless type[:fields].empty? %>
14
-
15
- <h2>Fields</h2>
16
-
17
- <%= include.('fields.html', fields: type[:fields]) %>
18
-
19
- <% end %>
@@ -0,0 +1,22 @@
1
+ <h1><%= type[:name] %></h1>
2
+
3
+ <%= include.('notices.html', notices: type[:notices]) %>
4
+
5
+ <%= type[:description] %>
6
+
7
+ <% if !type[:arguments].empty? %>
8
+
9
+ <h2>Arguments</h2>
10
+
11
+ <%= include.('fields.html', fields: type[:arguments]) %>
12
+
13
+ <% end %>
14
+
15
+
16
+ <% if !type[:return_fields].empty? %>
17
+
18
+ <h2>Return fields</h2>
19
+
20
+ <%= include.('fields.html', fields: type[:return_fields]) %>
21
+
22
+ <% end %>
@@ -1,3 +1,7 @@
1
+ <div id="search">
2
+ <img src="<%= base_url %>/assets/images/search.svg">
3
+ <input autocomplete="off" placeholder="Search" />
4
+ </div>
1
5
  <ul class="categories">
2
6
  <li>
3
7
  <ul class="menu-root">
@@ -7,7 +11,7 @@
7
11
  </li>
8
12
 
9
13
  <li>
10
- <p>Queries</p>
14
+ <p>Operations</p>
11
15
  <ul class="menu-root">
12
16
  <li>
13
17
  <a href="<%= base_url %>/operation/query/" class="sidebar-link<% if title == "Query" %> current<% end %>">
@@ -23,12 +27,12 @@
23
27
  </li>
24
28
 
25
29
  <li>
26
- <p><a href="<%= base_url %>/object">Objects</a></p>
30
+ <p><a href="<%= base_url %>/operation/query">Queries</a></p>
27
31
  <ul class="menu-root">
28
- <% graphql_object_types.().each do |type| %>
29
- <% @name = type[:name] %>
32
+ <% graphql_query_types.().each do |type| %>
33
+ <% @name = type[:name] %>
30
34
  <li>
31
- <a href="<%= base_url %>/object/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
35
+ <a href="<%= base_url %>/query/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
32
36
  <%= @name %>
33
37
  </a>
34
38
  </li>
@@ -50,6 +54,20 @@
50
54
  </ul>
51
55
  </li>
52
56
 
57
+ <li>
58
+ <p><a href="<%= base_url %>/object">Objects</a></p>
59
+ <ul class="menu-root">
60
+ <% graphql_object_types.().each do |type| %>
61
+ <% @name = type[:name] %>
62
+ <li>
63
+ <a href="<%= base_url %>/object/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
64
+ <%= @name %>
65
+ </a>
66
+ </li>
67
+ <% end %>
68
+ </ul>
69
+ </li>
70
+
53
71
  <li>
54
72
  <p><a href="<%= base_url %>/interface">Interfaces</a></p>
55
73
  <ul class="menu-root">
@@ -21,6 +21,7 @@ module GraphQLDocs
21
21
 
22
22
  @processed_schema = {
23
23
  operation_types: [],
24
+ query_types: [],
24
25
  mutation_types: [],
25
26
  object_types: [],
26
27
  interface_types: [],
@@ -51,8 +52,25 @@ module GraphQLDocs
51
52
  if data[:name] == root_types['query']
52
53
  data[:interfaces] = object.interfaces.map(&:graphql_name).sort
53
54
  data[:fields], data[:connections] = fetch_fields(object.fields, object.graphql_name)
54
-
55
55
  @processed_schema[:operation_types] << data
56
+
57
+ object.fields.each_value do |query|
58
+ h = {}
59
+
60
+ h[:notices] = @options[:notices].call([object.graphql_name, query.graphql_name].join('.'))
61
+ h[:name] = query.graphql_name
62
+ h[:description] = query.description
63
+ h[:arguments], = fetch_fields(query.arguments, [object.graphql_name, query.graphql_name].join('.'))
64
+
65
+ return_type = query.type
66
+ if return_type.unwrap.respond_to?(:fields)
67
+ h[:return_fields], = fetch_fields(return_type.unwrap.fields, return_type.graphql_name)
68
+ else # it is a scalar return type
69
+ h[:return_fields], = fetch_fields({ return_type.graphql_name => query }, return_type.graphql_name)
70
+ end
71
+
72
+ @processed_schema[:query_types] << h
73
+ end
56
74
  elsif data[:name] == root_types['mutation']
57
75
  @processed_schema[:operation_types] << data
58
76
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphQLDocs
4
- VERSION = '5.0.0'
4
+ VERSION = '5.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-docs
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Chalupa
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-07-03 00:00:00.000000000 Z
12
+ date: 2025-02-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphql
@@ -121,6 +121,34 @@ dependencies:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
123
  version: '1.58'
124
+ - !ruby/object:Gem::Dependency
125
+ name: ostruct
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.6'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.6'
138
+ - !ruby/object:Gem::Dependency
139
+ name: logger
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '1.6'
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.6'
124
152
  - !ruby/object:Gem::Dependency
125
153
  name: html-proofer
126
154
  requirement: !ruby/object:Gem::Requirement
@@ -141,14 +169,14 @@ dependencies:
141
169
  requirements:
142
170
  - - "~>"
143
171
  - !ruby/object:Gem::Version
144
- version: '5.0'
172
+ version: '5.24'
145
173
  type: :development
146
174
  prerelease: false
147
175
  version_requirements: !ruby/object:Gem::Requirement
148
176
  requirements:
149
177
  - - "~>"
150
178
  - !ruby/object:Gem::Version
151
- version: '5.0'
179
+ version: '5.24'
152
180
  - !ruby/object:Gem::Dependency
153
181
  name: minitest-focus
154
182
  requirement: !ruby/object:Gem::Requirement
@@ -294,6 +322,7 @@ files:
294
322
  - lib/graphql-docs/layouts/assets/images/graphiql.png
295
323
  - lib/graphql-docs/layouts/assets/images/menu.png
296
324
  - lib/graphql-docs/layouts/assets/images/navbar.png
325
+ - lib/graphql-docs/layouts/assets/images/search.svg
297
326
  - lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.eot
298
327
  - lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.ttf
299
328
  - lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.woff
@@ -318,6 +347,7 @@ files:
318
347
  - lib/graphql-docs/layouts/graphql_mutations.html
319
348
  - lib/graphql-docs/layouts/graphql_objects.html
320
349
  - lib/graphql-docs/layouts/graphql_operations.html
350
+ - lib/graphql-docs/layouts/graphql_queries.html
321
351
  - lib/graphql-docs/layouts/graphql_scalars.html
322
352
  - lib/graphql-docs/layouts/graphql_unions.html
323
353
  - lib/graphql-docs/layouts/includes/arguments.html
@@ -355,7 +385,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
355
385
  - !ruby/object:Gem::Version
356
386
  version: '0'
357
387
  requirements: []
358
- rubygems_version: 3.5.7
388
+ rubygems_version: 3.3.27
359
389
  signing_key:
360
390
  specification_version: 4
361
391
  summary: Easily generate beautiful documentation from your GraphQL schema.