s3browser-backend/internal/graphqlTypes.go

179 lines
4.4 KiB
Go
Raw Normal View History

2021-07-26 12:52:36 +00:00
package s3browser
import (
"fmt"
"path/filepath"
"strings"
"github.com/graph-gophers/dataloader"
"github.com/graphql-go/graphql"
)
var graphqlDirType *graphql.Object
var graphqlFileType *graphql.Object
// graphqlTypes create all graphql types and stores the in the global variables
func graphqlTypes() {
graphqlDirType = graphql.NewObject(graphql.ObjectConfig{
Name: "Directory",
Description: "Represents a directory",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.NewNonNull(graphql.ID),
},
"name": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(Directory)
if !ok {
return nil, fmt.Errorf("Failed to parse source for resolve")
}
return filepath.Base(source.ID), nil
},
},
},
})
graphqlFileType = graphql.NewObject(graphql.ObjectConfig{
Name: "File",
Description: "Represents a file, not a directory",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.NewNonNull(graphql.ID),
Description: "The uniqe ID of the file. Represents the path and the s3 key.",
},
"name": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(File)
if !ok {
return nil, fmt.Errorf("Failed to parse source for resolve")
}
return filepath.Base(source.ID), nil
},
},
"size": &graphql.Field{
2021-07-27 19:24:36 +00:00
Type: graphql.NewNonNull(graphql.Int),
2021-07-26 12:52:36 +00:00
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
file, err := loadFile(p)
if err != nil {
return nil, err
}
2021-08-06 14:31:07 +00:00
2021-07-26 12:52:36 +00:00
return file.Size, nil
},
},
"contentType": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
file, err := loadFile(p)
if err != nil {
return nil, err
}
2021-08-06 14:31:07 +00:00
2021-07-26 12:52:36 +00:00
return file.ContentType, nil
},
},
"etag": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
file, err := loadFile(p)
if err != nil {
return nil, err
}
2021-08-06 14:31:07 +00:00
2021-07-26 12:52:36 +00:00
return file.ETag, nil
},
},
"parent": &graphql.Field{
Type: graphqlDirType,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(File)
if !ok {
return nil, fmt.Errorf("Failed to parse Source for parent resolve")
}
basename := filepath.Dir(source.ID)
if basename == "." {
basename = "/"
}
return Directory{
ID: basename,
}, nil
},
},
},
})
graphqlDirType.AddFieldConfig("files", &graphql.Field{
Type: graphql.NewList(graphqlFileType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(Directory)
if !ok {
return nil, fmt.Errorf("Failed to parse Source for files resolve")
}
loader := p.Context.Value("loader").(map[string]*dataloader.Loader)
thunk := loader["getFiles"].Load(p.Context, dataloader.StringKey(source.ID))
return thunk()
},
})
graphqlDirType.AddFieldConfig("directorys", &graphql.Field{
Type: graphql.NewList(graphqlDirType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(Directory)
if !ok {
2021-08-06 14:31:07 +00:00
return nil, fmt.Errorf("Failed to parse Source for directories resolve")
2021-07-26 12:52:36 +00:00
}
loader := p.Context.Value("loader").(map[string]*dataloader.Loader)
thunk := loader["getDirs"].Load(p.Context, dataloader.StringKey(source.ID))
return thunk()
},
})
graphqlDirType.AddFieldConfig("parent", &graphql.Field{
Type: graphqlDirType,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
source, ok := p.Source.(Directory)
if !ok {
2021-08-06 14:31:07 +00:00
return nil, fmt.Errorf("Failed to parse Source for directories resolve")
2021-07-26 12:52:36 +00:00
}
dirs := strings.Split(source.ID, "/")
return Directory{
ID: strings.Join(dirs[:len(dirs)-2], "/") + "/",
}, nil
},
})
}
// graphqlTypes helper func for using the dataloader to get a file
func loadFile(p graphql.ResolveParams) (*File, error) {
source, ok := p.Source.(File)
if !ok {
return nil, fmt.Errorf("Failed to parse source for resolve")
}
loader := p.Context.Value("loader").(map[string]*dataloader.Loader)
thunk := loader["getFile"].Load(p.Context, dataloader.StringKey(source.ID))
result, err := thunk()
file, ok := result.(*File)
if !ok {
return nil, fmt.Errorf("Failed to load file")
}
return file, err
}