generator

package
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2025 License: MIT Imports: 10 Imported by: 1

Documentation

Overview

Package generator provides automatic GraphQL schema generation from Go structs.

This package scans Go source code for struct definitions and generates GraphQL type definitions, input types, and schema files based on struct tags and special directives. It supports field name transformations, custom type mappings, and automatic input generation for mutations.

Features

  • Automatic GraphQL type generation from Go structs
  • Field name transformations (camelCase, snake_case, PascalCase)
  • Support for gql tags and directives (@gqlgen, @gqlField, etc.)
  • Automatic input type generation from structs
  • Custom prefix/suffix stripping from type names
  • Support for embedded structs and referenced types
  • Configurable output strategies (single file or per-struct)

Basic Usage

parser := generator.NewParser()
err := parser.ParsePackages([]string{"./models"})
if err != nil {
	panic(err)
}

config := generator.NewConfig()
config.Output = "schema.graphql"

gen := generator.NewGenerator(parser, config)
err = gen.Run()
if err != nil {
	panic(err)
}

For detailed documentation and examples, see: https://github.com/pablor21/gqlscanner

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EnsureDir

func EnsureDir(dir string) error

EnsureDir makes sure a directory exists

func ExprToGraphQLType

func ExprToGraphQLType(expr ast.Expr) string

ExprToGraphQLType converts an ast.Expr to a GraphQL type string (with ! for required)

func FieldTypeName

func FieldTypeName(expr ast.Expr) string

FieldTypeName returns the bare type name used for nested type lookup

func FileExists

func FileExists(path string) bool

func PkgDir

func PkgDir(in string) string

helper to normalize package dir path for go run usage

func ResolveFieldName

func ResolveFieldName(field *ast.Field, config *Config) string

ResolveFieldName resolves field name based on config and tags Priority: gql tag name > json tag > struct field name (case transformation only applies to struct field)

func StripPrefixSuffix

func StripPrefixSuffix(name, prefixList, suffixList string) string

StripPrefixSuffix removes specified prefixes and suffixes from a type name prefixList and suffixList are comma-separated strings e.g. "DB,Pg" and "DTO,Entity,Model"

func ToSnakeCase

func ToSnakeCase(s string) string

ToSnakeCase converts PascalCase to snake_case

func TransformFieldName

func TransformFieldName(name string, fieldCase FieldCase) string

TransformFieldName transforms a field name based on the case setting

func WriteFile

func WriteFile(path, content string) error

Types

type Config

type Config struct {
	// Input directory to scan for Go structs (supports glob: /models/**/*.go)
	Input string `yaml:"input"`

	// Output directory or file path
	Output string `yaml:"output"`

	// Field name case transformation (camel, snake, pascal)
	FieldCase FieldCase `yaml:"field_case"`

	// Use json struct tag for field names if gql tag is not present
	UseJsonTag bool `yaml:"use_json_tag"`

	// Generate gqlgen directives (@goModel, @goField, @goTag)
	UseGqlGenDirectives bool `yaml:"use_gqlgen_directives"`

	// Base path for @goModel directive (e.g., "github.com/user/project/models")
	// If empty, uses the actual package path
	ModelPath string `yaml:"model_path"`

	// StripPrefix is a comma-separated list of prefixes to strip from type names
	// e.g. "DB,Pg" will convert "DBUser" to "User" and "PgPost" to "Post"
	// Only applies when @gqlType or @gqlInput doesn't specify a custom name
	StripPrefix string `yaml:"strip_prefix"`

	// StripSuffix is a comma-separated list of suffixes to strip from type names
	// e.g. "DTO,Entity,Model" will convert "UserDTO" to "User" and "PostEntity" to "Post"
	// Only applies when @gqlType or @gqlInput doesn't specify a custom name
	StripSuffix string `yaml:"strip_suffix"`

	// AddTypePrefix is a prefix to add to GraphQL type names
	// e.g. "Gql" will convert "User" to "GqlUser"
	// Only applies when @gqlType doesn't specify a custom name
	AddTypePrefix string `yaml:"add_type_prefix"`

	// AddTypeSuffix is a suffix to add to GraphQL type names
	// e.g. "Type" will convert "User" to "UserType"
	// Only applies when @gqlType doesn't specify a custom name
	AddTypeSuffix string `yaml:"add_type_suffix"`

	// AddInputPrefix is a prefix to add to GraphQL input names
	// e.g. "Gql" will convert "UserInput" to "GqlUserInput"
	// Only applies when @gqlInput doesn't specify a custom name
	AddInputPrefix string `yaml:"add_input_prefix"`

	// AddInputSuffix is a suffix to add to GraphQL input names
	// e.g. "Payload" will convert "CreateUser" to "CreateUserPayload"
	// Only applies when @gqlInput doesn't specify a custom name
	AddInputSuffix string `yaml:"add_input_suffix"`

	// Generation strategy: single file or multiple files
	GenStrategy GenStrategy `yaml:"strategy"`

	// Schema file name pattern (for multiple strategy)
	// Supports: {model_name}, {type_name}
	// Default: "{model_name}.graphqls"
	SchemaFileName string `yaml:"schema_file_name"`

	// Include empty types (types with no fields)
	IncludeEmptyTypes bool `yaml:"include_empty_types"`

	// Directory to scan (deprecated, use Input)
	PkgDir string `yaml:"pkg_dir"`

	// Output directory (deprecated, use Output)
	OutDir string `yaml:"out_dir"`

	// Single file mode (deprecated, use GenStrategy)
	SingleFile bool `yaml:"single_file"`

	// Skip existing files
	SkipExisting bool `yaml:"skip_existing"`

	// Generate inputs automatically
	GenInputs bool `yaml:"gen_inputs"`

	// Generate empty structs
	GenerateEmptyStructs bool `yaml:"generate_empty_structs"`
}

Config controls how the schema generator behaves

func NewConfig

func NewConfig() *Config

NewConfig creates a new Config with defaults

func (*Config) Normalize

func (c *Config) Normalize()

Normalize ensures config values are valid

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the configuration is valid

type ExtraField

type ExtraField struct {
	Name         string
	Type         string
	OverrideTags string
	Description  string
}

ExtraField represents a @gqlExtraField annotation

type FieldCase

type FieldCase string

FieldCase determines how field names are formatted

const (
	FieldCaseCamel    FieldCase = "camel"
	FieldCaseSnake    FieldCase = "snake"
	FieldCasePascal   FieldCase = "pascal"
	FieldCaseOriginal FieldCase = "original"
	FieldCaseNone     FieldCase = "none" // Keep struct field name untouched
)

type FieldOptions

type FieldOptions struct {
	Name          string
	Ignore        bool
	Include       bool
	Omit          bool
	Optional      bool
	Required      bool
	Type          string // Custom GraphQL type
	ForceResolver bool
	Description   string
}

FieldOptions describes parsed options from gql struct tag

func ParseFieldOptions

func ParseFieldOptions(field *ast.Field, config *Config) FieldOptions

ParseFieldOptions parses `gql:"name,omit|include,optional|required,type:GqlType,forceResolver,description:\"desc\""`

type GenStrategy

type GenStrategy string

GenStrategy determines output file strategy

const (
	GenStrategySingle   GenStrategy = "single"
	GenStrategyMultiple GenStrategy = "multiple"
)

type Generator

type Generator struct {
	P      *Parser
	Config *Config
}

func NewGenerator

func NewGenerator(p *Parser, config *Config) *Generator

func (*Generator) Run

func (g *Generator) Run() error

type Parser

type Parser struct {
	StructTypes  map[string]*ast.TypeSpec
	Structs      map[string]*ast.StructType
	PackageNames map[string]string
	TypeToDecl   map[string]*ast.GenDecl
	// ordered list of type names for deterministic output
	TypeNames []string
}

Parser collects type specs and related AST nodes across a root dir

func NewParser

func NewParser() *Parser

func (*Parser) Walk

func (p *Parser) Walk(root string) error

type StructDirectives

type StructDirectives struct {
	GQLName           string
	GQLInput          string       // @gqlInput(name:"InputName",description:"desc")
	GQLType           string       // @gqlType(name:"TypeName",description:"desc")
	TypeDescription   string       // Description from @gqlType
	InputDescription  string       // Description from @gqlInput
	IgnoreAll         bool         // @gqlIgnoreAll
	UseModelDirective bool         // @gqlUseModelDirective
	SkipType          bool         // @gqlskip
	GenInput          bool         // Generate input type
	Partial           bool         // @partial
	ExtraFields       []ExtraField // @gqlExtraField (repeatable)
}

StructDirectives holds parsed values from surrounding comments for a type

func ParseDirectives

func ParseDirectives(typeSpec *ast.TypeSpec, genDecl *ast.GenDecl) StructDirectives

ParseDirectives collects directives from GenDecl.Doc, TypeSpec.Doc and TypeSpec.Comment

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL