Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions entx/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ func WithFederation() ExtensionOption {
}
}

// WithConnectionNodes adds the templates for adding nodes to relay connections
func WithConnectionNodes() ExtensionOption {
return func(ex *Extension) error {
ex.templates = append(ex.templates, PaginationTemplate)
ex.gqlSchemaHooks = append(ex.gqlSchemaHooks, addNodesToConnections)

return nil
}
}

// WithJSONScalar adds the JSON scalar definition
func WithJSONScalar() ExtensionOption {
return func(ex *Extension) error {
Expand Down
32 changes: 32 additions & 0 deletions entx/gql_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package entx

import (
"errors"
"slices"
"strings"

"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
Expand Down Expand Up @@ -88,6 +90,36 @@ var (
}
return nil
}

addNodesToConnections = func(_ *gen.Graph, s *ast.Schema) error {
for _, t := range s.Types {
if !strings.HasSuffix(t.Name, "Connection") {
continue
}

existingFields := []string{"edges", "pageInfo", "totalCount"}
missingField := false
for _, f := range t.Fields {
if !slices.Contains(existingFields, f.Name) {
missingField = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really a huge improvement, but we could break after setting this.

Copy link
Member Author

@nicolerenee nicolerenee Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it, but given there should be only 3 fields on a Connection I wasn't to worried about it.

}
}
if missingField {
continue
}

// If we are here then this type is a connection with only the fields we expect so add nodes
nodeType := strings.TrimSuffix(t.Name, "Connection")

t.Fields = append(t.Fields, &ast.FieldDefinition{
Name: "nodes",
Type: ast.ListType(ast.NamedType(nodeType, nil), nil),
Description: "A list of nodes.",
})
}

return nil
}
)

// import string mutations from entc
Expand Down
12 changes: 11 additions & 1 deletion entx/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"strings"
"text/template"

"entgo.io/contrib/entgql"
"entgo.io/ent/entc/gen"
"github.com/mitchellh/mapstructure"
)
Expand All @@ -30,6 +31,9 @@ var (
// EventHooksTemplate adds support for generating event hooks
EventHooksTemplate = parseT("template/event_hooks.tmpl")

// PaginationTemplate adds support for adding the nodes field to relay connections
PaginationTemplate = parseT("template/pagination.tmpl")

// TemplateFuncs contains the extra template functions used by entx.
TemplateFuncs = template.FuncMap{
"contains": strings.Contains,
Expand All @@ -41,8 +45,14 @@ var (
)

func parseT(path string) *gen.Template {
funcMap := entgql.TemplateFuncs

for k, v := range TemplateFuncs {
funcMap[k] = v
}

return gen.MustParse(gen.NewTemplate(path).
Funcs(TemplateFuncs).
Funcs(funcMap).
ParseFS(_templates, path))
}

Expand Down
Loading
Loading