diff --git a/internal/dataloader.go b/internal/dataloader.go index cf73af9..9dc9b62 100644 --- a/internal/dataloader.go +++ b/internal/dataloader.go @@ -73,11 +73,12 @@ func getFilesBatch(c context.Context, k dataloader.Keys) []*dataloader.Result { // TODO: how to handle? } else if !strings.HasSuffix(obj.Key, "/") { files = append(files, File{ - ID: obj.Key, - Name: filepath.Base(obj.Key), - Size: obj.Size, - ContentType: obj.ContentType, - ETag: obj.ETag, + ID: obj.Key, + Name: filepath.Base(obj.Key), + Size: obj.Size, + ContentType: obj.ContentType, + ETag: obj.ETag, + LastModified: obj.LastModified, }) } } @@ -112,10 +113,11 @@ func getFileBatch(c context.Context, k dataloader.Keys) []*dataloader.Result { } else { results = append(results, &dataloader.Result{ Data: &File{ - ID: obj.Key, - Size: obj.Size, - ContentType: obj.ContentType, - ETag: obj.ETag, + ID: obj.Key, + Size: obj.Size, + ContentType: obj.ContentType, + ETag: obj.ETag, + LastModified: obj.LastModified, }, Error: nil, }) diff --git a/internal/graphqlTypes.go b/internal/graphqlTypes.go index 71f2de6..9aef8c3 100644 --- a/internal/graphqlTypes.go +++ b/internal/graphqlTypes.go @@ -4,9 +4,11 @@ import ( "fmt" "path/filepath" "strings" + "time" "github.com/graph-gophers/dataloader" "github.com/graphql-go/graphql" + "github.com/graphql-go/graphql/language/ast" ) var graphqlDirType *graphql.Object @@ -14,6 +16,38 @@ var graphqlFileType *graphql.Object // graphqlTypes create all graphql types and stores the in the global variables func graphqlTypes() { + + var dateTimeType = graphql.NewScalar(graphql.ScalarConfig{ + Name: "DateTime", + Description: "DateTime is a DateTime in ISO 8601 format", + Serialize: func(value interface{}) interface{} { + switch value := value.(type) { + case time.Time: + return value.Format(time.RFC3339) + } + + return "INVALID" + }, + ParseValue: func(value interface{}) interface{} { + switch tvalue := value.(type) { + case string: + if tval, err := time.Parse(time.RFC3339, tvalue); err != nil { + return nil + } else { + return tval + } + } + return nil + }, + ParseLiteral: func(valueAST ast.Value) interface{} { + switch valueAST := valueAST.(type) { + case *ast.StringValue: + return valueAST.Value + } + return nil + }, + }) + graphqlDirType = graphql.NewObject(graphql.ObjectConfig{ Name: "Directory", Description: "Represents a directory", @@ -87,6 +121,17 @@ func graphqlTypes() { return file.ETag, nil }, }, + "lastModified": &graphql.Field{ + Type: dateTimeType, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + file, err := loadFile(p) + if err != nil { + return nil, err + } + + return file.LastModified, nil + }, + }, "parent": &graphql.Field{ Type: graphqlDirType, Resolve: func(p graphql.ResolveParams) (interface{}, error) { diff --git a/internal/s3Broswer.go b/internal/s3Broswer.go index b4ac794..90d87f1 100644 --- a/internal/s3Broswer.go +++ b/internal/s3Broswer.go @@ -22,11 +22,12 @@ type AppConfig struct { // File represents a file with its metadata type File struct { - ID string `json:"id"` - Name string `json:"name"` - Size int64 `json:"size"` - ContentType string `json:"contentType"` - ETag string `json:"etag"` + ID string `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + ContentType string `json:"contentType"` + ETag string `json:"etag"` + LastModified time.Time `json:"lastModified"` } // Directory represents a directory with its metadata