GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

330 lines
7.7 KiB

package resolver
import (
"context"
"errors"
"strings"
"git.aiterp.net/rpdata/api/internal/session"
"git.aiterp.net/rpdata/api/loader"
"git.aiterp.net/rpdata/api/model/change"
"git.aiterp.net/rpdata/api/model/character"
"git.aiterp.net/rpdata/api/model/log"
)
// CharacterResolver for the Character graphql type
type CharacterResolver struct{ C character.Character }
// CharacterArgs is an arg
type CharacterArgs struct {
ID *string
Nick *string
}
// Character resolver
func (r *QueryResolver) Character(ctx context.Context, args *CharacterArgs) (*CharacterResolver, error) {
var char character.Character
var err error
loader := loader.FromContext(ctx)
if loader == nil {
return nil, errors.New("no loader")
}
switch {
case args.ID != nil:
char, err = character.FindID(*args.ID)
case args.Nick != nil:
char, err = character.FindNick(*args.Nick)
default:
err = ErrCannotResolve
}
if err != nil {
return nil, err
}
return &CharacterResolver{C: char}, nil
}
// CharactersArgs is an arg
type CharactersArgs struct {
IDs *[]string
Nicks *[]string
Author *string
}
// Characters resolves
func (r *QueryResolver) Characters(ctx context.Context, args *CharactersArgs) ([]*CharacterResolver, error) {
var chars []character.Character
var err error
loader := loader.FromContext(ctx)
if loader == nil {
return nil, errors.New("no loader")
}
switch {
case args.IDs != nil:
chars, err = character.ListIDs(*args.IDs...)
case args.Nicks != nil:
chars, err = character.ListNicks(*args.Nicks...)
case args.Author != nil:
chars, err = character.ListAuthor(*args.Author)
default:
chars, err = character.List()
}
if err != nil {
return nil, err
}
resolvers := make([]*CharacterResolver, 0, len(chars))
for i := range chars {
if chars[i].ID == "" {
continue
}
resolvers = append(resolvers, &CharacterResolver{C: chars[i]})
}
return resolvers, nil
}
// AddCharacterInput is args for mutation addCharacter
type AddCharacterInput struct {
Nick string
Name string
ShortName *string
Author *string
Description *string
}
// AddCharacter resolves the addCharacter mutation
func (r *MutationResolver) AddCharacter(ctx context.Context, args struct{ Input *AddCharacterInput }) (*CharacterResolver, error) {
user := session.FromContext(ctx).User()
if user == nil || !user.Permitted("member", "character.add") {
return nil, ErrUnauthorized
}
nick := args.Input.Nick
name := args.Input.Name
shortName := ""
if args.Input.ShortName != nil {
shortName = *args.Input.ShortName
} else {
shortName = strings.SplitN(args.Input.Name, " ", 2)[0]
}
author := user.ID
if args.Input.Author != nil {
author = *args.Input.Author
if author != user.ID && !user.Permitted("character.add") {
return nil, ErrPermissionDenied
}
}
description := ""
if args.Input.Description != nil {
description = *args.Input.Description
}
character, err := character.New(nick, name, shortName, author, description)
if err != nil {
return nil, err
}
go change.Submit("Character", "add", user.ID, character.ID, map[string]interface{}{
"name": character.Name,
"nick": character.Nicks[0],
"author": character.Author,
})
log.ScheduleCharacterUpdate()
return &CharacterResolver{C: character}, nil
}
// CharacterNickInput is args for mutation addCharacterNick/removeCharacterNick
type CharacterNickInput struct {
ID string
Nick string
}
// AddCharacterNick resolves the addCharacterNick mutation
func (r *MutationResolver) AddCharacterNick(ctx context.Context, args struct{ Input *CharacterNickInput }) (*CharacterResolver, error) {
user := session.FromContext(ctx).User()
if user == nil || !user.Permitted("member") {
return nil, ErrUnauthorized
}
character, err := character.FindID(args.Input.ID)
if err != nil {
return nil, err
}
if character.Author != user.ID && !user.Permitted("character.edit") {
return nil, ErrPermissionDenied
}
err = character.AddNick(args.Input.Nick)
if err != nil {
return nil, err
}
go change.Submit("Character", "add.nick", user.ID, character.ID, map[string]interface{}{
"nick": args.Input.Nick,
})
log.ScheduleCharacterUpdate()
return &CharacterResolver{C: character}, nil
}
// RemoveCharacterNick resolves the removeCharacterNick mutation
func (r *MutationResolver) RemoveCharacterNick(ctx context.Context, args struct{ Input *CharacterNickInput }) (*CharacterResolver, error) {
user := session.FromContext(ctx).User()
if user == nil || !user.Permitted("member") {
return nil, ErrUnauthorized
}
character, err := character.FindID(args.Input.ID)
if err != nil {
return nil, err
}
if character.Author != user.ID && !user.Permitted("character.edit") {
return nil, ErrPermissionDenied
}
err = character.RemoveNick(args.Input.Nick)
if err != nil {
return nil, err
}
go change.Submit("Character", "remove.nick", user.ID, character.ID, map[string]interface{}{
"nick": args.Input.Nick,
})
log.ScheduleCharacterUpdate()
return &CharacterResolver{C: character}, nil
}
// CharacterEditInput is args for mutation addCharacterNick/removeCharacterNick
type CharacterEditInput struct {
ID string
Name *string
ShortName *string
Description *string
}
// EditCharacter resolves the editCharacter mutation
func (r *MutationResolver) EditCharacter(ctx context.Context, args struct{ Input *CharacterEditInput }) (*CharacterResolver, error) {
user := session.FromContext(ctx).User()
if user == nil || !user.Permitted("member") {
return nil, ErrUnauthorized
}
character, err := character.FindID(args.Input.ID)
if err != nil {
return nil, err
}
if character.Author != user.ID && !user.Permitted("character.edit") {
return nil, ErrPermissionDenied
}
name := ""
if args.Input.Name != nil {
name = *args.Input.Name
}
shortName := ""
if args.Input.ShortName != nil {
shortName = *args.Input.ShortName
}
description := ""
if args.Input.Description != nil {
description = *args.Input.Description
}
err = character.Edit(name, shortName, description)
if err != nil {
return nil, err
}
go change.Submit("Character", "edit", user.ID, character.ID, map[string]interface{}{
"name": character.Name,
"shortName": character.ShortName,
"description": character.Description,
})
return &CharacterResolver{C: character}, nil
}
// RemoveCharacter resolves the removeCharacter mutation
func (r *MutationResolver) RemoveCharacter(ctx context.Context, args struct{ ID string }) (*CharacterResolver, error) {
user := session.FromContext(ctx).User()
if user == nil || !user.Permitted("member") {
return nil, ErrUnauthorized
}
character, err := character.FindID(args.ID)
if err != nil {
return nil, err
}
if character.Author != user.ID && !user.Permitted("character.remove") {
return nil, ErrPermissionDenied
}
err = character.Remove()
if err != nil {
return nil, err
}
go change.Submit("Character", "remove", user.ID, character.ID, map[string]interface{}{
"name": character.Name,
"author": character.Author,
"nicks": character.Nicks,
})
return &CharacterResolver{C: character}, nil
}
// ID is a property resolver
func (r *CharacterResolver) ID() string {
return r.C.ID
}
// Nick is a property resolver
func (r *CharacterResolver) Nick() *string {
if len(r.C.Nicks) == 0 {
return nil
}
return &r.C.Nicks[0]
}
// Nicks is a property resolver
func (r *CharacterResolver) Nicks() []string {
return r.C.Nicks
}
// Name is a property resolver
func (r *CharacterResolver) Name() string {
return r.C.Name
}
// ShortName is a property resolver
func (r *CharacterResolver) ShortName() string {
return r.C.ShortName
}
// Author is a property resolver
func (r *CharacterResolver) Author() string {
return r.C.Author
}
// Description is a property resolver
func (r *CharacterResolver) Description() string {
return r.C.Description
}