Class: GraphQLDocs::Generator

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/graphql-docs/generator.rb

Overview

Generates HTML documentation files from a parsed GraphQL schema.

The Generator takes the parsed schema structure and creates individual HTML pages for each GraphQL type, along with landing pages and static assets. It uses ERB templates for layout and the Renderer for converting content to HTML.

Examples:

Basic usage

generator = GraphQLDocs::Generator.new(parsed_schema, options)
generator.generate

See Also:

Constant Summary

Constants included from Helpers

Helpers::SLUGIFY_PRETTY_REGEXP

Instance Attribute Summary collapse

Attributes included from Helpers

#templates

Instance Method Summary collapse

Methods included from Helpers

#graphql_directive_types, #graphql_enum_types, #graphql_input_object_types, #graphql_interface_types, #graphql_mutation_types, #graphql_object_types, #graphql_operation_types, #graphql_query_types, #graphql_root_types, #graphql_scalar_types, #graphql_union_types, #include, #markdownify, #slugify, #split_into_metadata_and_contents, #yaml?, #yaml_split

Constructor Details

#initialize(parsed_schema, options) ⇒ Generator

Initializes a new Generator instance.

Sets up ERB templates for all GraphQL types and landing pages. Validates that all required template files exist before generation begins.

Options Hash (options):

  • :templates (Hash)

    Paths to ERB template files

  • :landing_pages (Hash)

    Paths to landing page files

  • :renderer (Class)

    Renderer class to use

Raises:

  • (IOError)

    If any required template or landing page file is not found



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/graphql-docs/generator.rb', line 40

def initialize(parsed_schema, options)
  @parsed_schema = parsed_schema
  @options = options

  @renderer = @options[:renderer].new(@parsed_schema, @options)

  %i[operations objects queries mutations interfaces enums unions input_objects scalars directives].each do |sym|
    raise IOError, "`#{sym}` template #{@options[:templates][sym]} was not found" unless File.exist?(@options[:templates][sym])

    instance_variable_set("@graphql_#{sym}_template", ERB.new(File.read(@options[:templates][sym])))
  end

  %i[index object query mutation interface enum union input_object scalar directive].each do |sym|
    if @options[:landing_pages][sym].nil?
      instance_variable_set("@#{sym}_landing_page", nil)
    elsif !File.exist?(@options[:landing_pages][sym])
      raise IOError, "`#{sym}` landing page #{@options[:landing_pages][sym]} was not found"
    end

    landing_page_contents = File.read(@options[:landing_pages][sym])
     = ''

    if File.extname((@options[:landing_pages][sym])) == '.erb'
      opts = @options.merge(@options[:landing_pages][:variables]).merge(helper_methods)
      if yaml?(landing_page_contents)
        , landing_page = (landing_page_contents, parse: false)
        erb_template = ERB.new(landing_page)
      else
        erb_template = ERB.new(landing_page_contents)
      end

      landing_page_contents = erb_template.result(OpenStruct.new(opts).instance_eval { binding })
    end

    instance_variable_set("@graphql_#{sym}_landing_page",  + landing_page_contents)
  end
end

Instance Attribute Details

#parsed_schemaHash



26
27
28
# File 'lib/graphql-docs/generator.rb', line 26

def parsed_schema
  @parsed_schema
end

Instance Method Details

#create_graphql_directive_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL directives.



264
265
266
267
268
269
270
271
# File 'lib/graphql-docs/generator.rb', line 264

def create_graphql_directive_pages
  graphql_directive_types.each do |directive_type|
    opts = default_generator_options(type: directive_type)

    contents = @graphql_directives_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('directive', directive_type[:name], contents)
  end
end

#create_graphql_enum_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL enum types.



216
217
218
219
220
221
222
223
# File 'lib/graphql-docs/generator.rb', line 216

def create_graphql_enum_pages
  graphql_enum_types.each do |enum_type|
    opts = default_generator_options(type: enum_type)

    contents = @graphql_enums_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('enum', enum_type[:name], contents)
  end
end

#create_graphql_input_object_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL input object types.



240
241
242
243
244
245
246
247
# File 'lib/graphql-docs/generator.rb', line 240

def create_graphql_input_object_pages
  graphql_input_object_types.each do |input_object_type|
    opts = default_generator_options(type: input_object_type)

    contents = @graphql_input_objects_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('input_object', input_object_type[:name], contents)
  end
end

#create_graphql_interface_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL interface types.



204
205
206
207
208
209
210
211
# File 'lib/graphql-docs/generator.rb', line 204

def create_graphql_interface_pages
  graphql_interface_types.each do |interface_type|
    opts = default_generator_options(type: interface_type)

    contents = @graphql_interfaces_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('interface', interface_type[:name], contents)
  end
end

#create_graphql_mutation_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL mutation fields.



192
193
194
195
196
197
198
199
# File 'lib/graphql-docs/generator.rb', line 192

def create_graphql_mutation_pages
  graphql_mutation_types.each do |mutation|
    opts = default_generator_options(type: mutation)

    contents = @graphql_mutations_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('mutation', mutation[:name], contents)
  end
end

#create_graphql_object_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL object types.



168
169
170
171
172
173
174
175
# File 'lib/graphql-docs/generator.rb', line 168

def create_graphql_object_pages
  graphql_object_types.each do |object_type|
    opts = default_generator_options(type: object_type)

    contents = @graphql_objects_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('object', object_type[:name], contents)
  end
end

#create_graphql_operation_pagesBoolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates HTML pages for GraphQL operation types (Query, Mutation).



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/graphql-docs/generator.rb', line 141

def create_graphql_operation_pages
  graphql_operation_types.each do |query_type|
     = ''
    next unless query_type[:name] == graphql_root_types['query']

    unless @options[:landing_pages][:query].nil?
      query_landing_page = @options[:landing_pages][:query]
      query_landing_page = File.read(query_landing_page)
      if yaml?(query_landing_page)
        pieces = yaml_split(query_landing_page)
        pieces[2] = pieces[2].chomp
         = pieces[1, 3].join("\n")
        query_landing_page = pieces[4]
      end
      query_type[:description] = query_landing_page
    end
    opts = default_generator_options(type: query_type)
    contents = @graphql_operations_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('operation', 'query',  + contents)
    return true
  end
  false
end

#create_graphql_query_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL query fields.



180
181
182
183
184
185
186
187
# File 'lib/graphql-docs/generator.rb', line 180

def create_graphql_query_pages
  graphql_query_types.each do |query|
    opts = default_generator_options(type: query)

    contents = @graphql_queries_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('query', query[:name], contents)
  end
end

#create_graphql_scalar_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL scalar types.



252
253
254
255
256
257
258
259
# File 'lib/graphql-docs/generator.rb', line 252

def create_graphql_scalar_pages
  graphql_scalar_types.each do |scalar_type|
    opts = default_generator_options(type: scalar_type)

    contents = @graphql_scalars_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('scalar', scalar_type[:name], contents)
  end
end

#create_graphql_union_pagesvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Creates HTML pages for GraphQL union types.



228
229
230
231
232
233
234
235
# File 'lib/graphql-docs/generator.rb', line 228

def create_graphql_union_pages
  graphql_union_types.each do |union_type|
    opts = default_generator_options(type: union_type)

    contents = @graphql_unions_template.result(OpenStruct.new(opts).instance_eval { binding })
    write_file('union', union_type[:name], contents)
  end
end

#generateBoolean

Generates all HTML documentation files.

This is the main generation method that creates:

  • Individual pages for each GraphQL type
  • Landing pages for type categories
  • Static assets (CSS, fonts, images) if using default styles

Examples:

generator.generate # Creates all docs in output directory


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/graphql-docs/generator.rb', line 89

def generate
  FileUtils.rm_rf(@options[:output_dir]) if @options[:delete_output]

  has_query = create_graphql_operation_pages
  create_graphql_object_pages
  create_graphql_query_pages
  create_graphql_mutation_pages
  create_graphql_interface_pages
  create_graphql_enum_pages
  create_graphql_union_pages
  create_graphql_input_object_pages
  create_graphql_scalar_pages
  create_graphql_directive_pages

  write_file('static', 'index', @graphql_index_landing_page, trim: false) unless @graphql_index_landing_page.nil?

  write_file('static', 'object', @graphql_object_landing_page, trim: false) unless @graphql_object_landing_page.nil?

  write_file('operation', 'query', @graphql_query_landing_page, trim: false) if !@graphql_query_landing_page.nil? && !has_query

  write_file('operation', 'mutation', @graphql_mutation_landing_page, trim: false) unless @graphql_mutation_landing_page.nil?

  write_file('static', 'interface', @graphql_interface_landing_page, trim: false) unless @graphql_interface_landing_page.nil?

  write_file('static', 'enum', @graphql_enum_landing_page, trim: false) unless @graphql_enum_landing_page.nil?

  write_file('static', 'union', @graphql_union_landing_page, trim: false) unless @graphql_union_landing_page.nil?

  write_file('static', 'input_object', @graphql_input_object_landing_page, trim: false) unless @graphql_input_object_landing_page.nil?

  write_file('static', 'scalar', @graphql_scalar_landing_page, trim: false) unless @graphql_scalar_landing_page.nil?

  write_file('static', 'directive', @graphql_directive_landing_page, trim: false) unless @graphql_directive_landing_page.nil?

  if @options[:use_default_styles]
    assets_dir = File.join(File.dirname(__FILE__), 'layouts', 'assets')
    FileUtils.mkdir_p(File.join(@options[:output_dir], 'assets'))

    css = Sass.compile(File.join(assets_dir, 'css', 'screen.scss')).css
    File.write(File.join(@options[:output_dir], 'assets', 'style.css'), css)

    FileUtils.cp_r(File.join(assets_dir, 'images'), File.join(@options[:output_dir], 'assets'))
    FileUtils.cp_r(File.join(assets_dir, 'webfonts'), File.join(@options[:output_dir], 'assets'))
  end

  true
end