@@ -1,59 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChannelAddArgs is input for the addChannel mutation
|
|
||||||
type ChannelAddArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
Name string
|
|
||||||
Logged *bool
|
|
||||||
Hub *bool
|
|
||||||
EventName *string
|
|
||||||
LocationName *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddChannel resolves the addChannel mutation
|
|
||||||
func (r *MutationResolver) AddChannel(ctx context.Context, args *ChannelAddArgs) (*types.ChannelResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("channel.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
logged := input.Logged != nil && *input.Logged
|
|
||||||
|
|
||||||
hub := input.Hub != nil && *input.Hub
|
|
||||||
|
|
||||||
eventName := ""
|
|
||||||
if input.EventName != nil {
|
|
||||||
eventName = *input.EventName
|
|
||||||
}
|
|
||||||
|
|
||||||
locationName := ""
|
|
||||||
if input.LocationName != nil {
|
|
||||||
locationName = *input.LocationName
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err := channel.New(input.Name, logged, hub, eventName, locationName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Channel", "add", token.UserID, channel.Name, map[string]interface{}{
|
|
||||||
"logged": channel.Logged,
|
|
||||||
"hub": channel.Hub,
|
|
||||||
"location": input.LocationName,
|
|
||||||
"event": input.EventName,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.ChannelResolver{C: channel}, nil
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddChapterArgs is args for the addChapter mutation
|
|
||||||
type AddChapterArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
StoryID string
|
|
||||||
Title string
|
|
||||||
Author *string
|
|
||||||
Source string
|
|
||||||
FictionalDate *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddChapter resolves the addChapter mutation
|
|
||||||
func (r *MutationResolver) AddChapter(ctx context.Context, args *AddChapterArgs) (*types.ChapterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "chapter.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.FindID(input.StoryID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
author := token.UserID
|
|
||||||
if input.Author != nil {
|
|
||||||
author = *input.Author
|
|
||||||
|
|
||||||
if token.UserID != author && !token.Permitted("chapter.add") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fictionalDate := time.Time{}
|
|
||||||
if input.FictionalDate != nil {
|
|
||||||
fictionalDate, err = time.Parse(time.RFC3339Nano, *input.FictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chapter, err := story.AddChapter(input.Title, author, input.Source, time.Now(), fictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Chapter", "add", token.UserID, chapter.ID, map[string]interface{}{
|
|
||||||
"title": input.Title,
|
|
||||||
"author": author,
|
|
||||||
"fictionalDate": fictionalDate,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.ChapterResolver{C: chapter}, nil
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddCharacterInput is args for the addCharacter mutation
|
|
||||||
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 }) (*types.CharacterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "character.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
nick := input.Nick
|
|
||||||
|
|
||||||
name := input.Name
|
|
||||||
|
|
||||||
shortName := ""
|
|
||||||
if input.ShortName != nil {
|
|
||||||
shortName = *input.ShortName
|
|
||||||
} else {
|
|
||||||
shortName = strings.SplitN(input.Name, " ", 2)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
author := token.UserID
|
|
||||||
if input.Author != nil {
|
|
||||||
author = *input.Author
|
|
||||||
|
|
||||||
if author != token.UserID && !token.Permitted("character.add") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
description := ""
|
|
||||||
if input.Description != nil {
|
|
||||||
description = *input.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
character, err := character.New(nick, name, shortName, author, description)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Character", "add", token.UserID, character.ID, map[string]interface{}{
|
|
||||||
"name": character.Name,
|
|
||||||
"nick": character.Nicks[0],
|
|
||||||
"author": character.Author,
|
|
||||||
})
|
|
||||||
|
|
||||||
log.ScheduleCharacterUpdate()
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: character}, nil
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddCharacterNickInput is args for the addCharacterNick mutation
|
|
||||||
type AddCharacterNickInput struct {
|
|
||||||
ID string
|
|
||||||
Nick string
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddCharacterNick resolves the addCharacterNick mutation
|
|
||||||
func (r *MutationResolver) AddCharacterNick(ctx context.Context, args struct{ Input *AddCharacterNickInput }) (*types.CharacterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
character, err := character.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if character.Author != token.UserID && !token.Permitted("character.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = character.AddNick(input.Nick)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Character", "add.nick", token.UserID, character.ID, map[string]interface{}{
|
|
||||||
"nick": input.Nick,
|
|
||||||
})
|
|
||||||
|
|
||||||
log.ScheduleCharacterUpdate()
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: character}, nil
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogAddArgs is args for the addLog mutation
|
|
||||||
type LogAddArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
Date string
|
|
||||||
Channel string
|
|
||||||
Title *string
|
|
||||||
Open *bool
|
|
||||||
Event *string
|
|
||||||
Description *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddLog resolves the addLog mutation
|
|
||||||
func (r *MutationResolver) AddLog(ctx context.Context, args *LogAddArgs) (*types.LogResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("log.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
date, err := time.Parse(time.RFC3339Nano, args.Input.Date)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
title := ""
|
|
||||||
if input.Title != nil {
|
|
||||||
title = *input.Title
|
|
||||||
}
|
|
||||||
|
|
||||||
event := ""
|
|
||||||
if input.Event != nil {
|
|
||||||
event = *input.Event
|
|
||||||
}
|
|
||||||
|
|
||||||
description := ""
|
|
||||||
if input.Description != nil {
|
|
||||||
description = *input.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
open := input.Open != nil && *input.Open == true
|
|
||||||
|
|
||||||
log, err := log.New(date, input.Channel, title, event, description, open)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Log", "add", token.UserID, log.ID, map[string]interface{}{
|
|
||||||
"channel": log.Channel,
|
|
||||||
"title": log.Title,
|
|
||||||
"event": log.Event,
|
|
||||||
"description": log.Description,
|
|
||||||
"open": log.Open,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.LogResolver{L: log}, nil
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostAddArgs is args for addPost mutation
|
|
||||||
type PostAddArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
LogID string
|
|
||||||
Time string
|
|
||||||
Kind string
|
|
||||||
Nick string
|
|
||||||
Text string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddPost resolves the addPost mutation
|
|
||||||
func (r *MutationResolver) AddPost(ctx context.Context, args *PostAddArgs) (*types.PostResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("post.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
postTime, err := time.Parse(time.RFC3339Nano, input.Time)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log, err := log.FindID(input.LogID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
post, err := log.NewPost(postTime, input.Kind, input.Nick, input.Text)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Post", "add", token.UserID, post.ID, map[string]interface{}{
|
|
||||||
"logId": post.LogID,
|
|
||||||
"time": post.Time,
|
|
||||||
"kind": post.Kind,
|
|
||||||
"nick": post.Nick,
|
|
||||||
"text": post.Text,
|
|
||||||
"position": post.Position,
|
|
||||||
})
|
|
||||||
|
|
||||||
go log.UpdateCharacters()
|
|
||||||
|
|
||||||
return &types.PostResolver{P: post}, nil
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryAddArgs is args for the addStory mutation
|
|
||||||
type StoryAddArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
Name string
|
|
||||||
Category string
|
|
||||||
Author *string
|
|
||||||
Open *bool
|
|
||||||
Listed *bool
|
|
||||||
FictionalDate *string
|
|
||||||
Tags *[]struct {
|
|
||||||
Kind string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddStory resolves the addStory mutation
|
|
||||||
func (r *MutationResolver) AddStory(ctx context.Context, args *StoryAddArgs) (*types.StoryResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "story.add") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
author := token.UserID
|
|
||||||
if input.Author != nil {
|
|
||||||
author = *input.Author
|
|
||||||
|
|
||||||
if token.UserID != author && !token.Permitted("story.add") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listed := (input.Listed != nil && *input.Listed == true)
|
|
||||||
|
|
||||||
open := (input.Open != nil && *input.Open == true)
|
|
||||||
|
|
||||||
tags := make([]story.Tag, 0, 8)
|
|
||||||
if input.Tags != nil {
|
|
||||||
for _, tagInput := range *input.Tags {
|
|
||||||
tags = append(tags, story.Tag{
|
|
||||||
Kind: tagInput.Kind,
|
|
||||||
Name: tagInput.Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fictionalDate := time.Time{}
|
|
||||||
if input.FictionalDate != nil {
|
|
||||||
date, err := time.Parse(time.RFC3339Nano, *input.FictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fictionalDate = date
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.New(input.Name, author, input.Category, listed, open, tags, time.Now(), fictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Story", "add", token.UserID, story.ID, map[string]interface{}{
|
|
||||||
"name": input.Name,
|
|
||||||
"category": input.Category,
|
|
||||||
"author": input.Author,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryTagAddArgs is args for the addStoryTag mutation
|
|
||||||
type StoryTagAddArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Tag struct {
|
|
||||||
Kind string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddStoryTag resolves the addStoryTag mutation
|
|
||||||
func (r *MutationResolver) AddStoryTag(ctx context.Context, args *StoryTagAddArgs) (*types.StoryResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
tag := story.Tag{Kind: input.Tag.Kind, Name: input.Tag.Name}
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "story.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if story.Author != token.UserID && !token.Permitted("story.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = story.AddTag(tag)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Story", "add.tag", token.UserID, story.ID, map[string]interface{}{
|
|
||||||
"kind": tag.Kind,
|
|
||||||
"name": tag.Name,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChannelEditArgs is input for the editChannel mutation
|
|
||||||
type ChannelEditArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
Name string
|
|
||||||
Logged *bool
|
|
||||||
Hub *bool
|
|
||||||
EventName *string
|
|
||||||
LocationName *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditChannel resolves the editChannel mutation
|
|
||||||
func (r *MutationResolver) EditChannel(ctx context.Context, args *ChannelEditArgs) (*types.ChannelResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("channel.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err := channel.FindName(input.Name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = channel.Edit(input.Logged, input.Hub, input.EventName, input.LocationName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Channel", "edit", token.UserID, channel.Name, map[string]interface{}{
|
|
||||||
"logged": input.Logged,
|
|
||||||
"hub": input.Hub,
|
|
||||||
"location": input.LocationName,
|
|
||||||
"event": input.EventName,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.ChannelResolver{C: channel}, nil
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EditChapterArgs is args for the editChapter mutation
|
|
||||||
type EditChapterArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Title *string
|
|
||||||
Source *string
|
|
||||||
FictionalDate *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditChapter resolves the editChapter mutation
|
|
||||||
func (r *MutationResolver) EditChapter(ctx context.Context, args *EditChapterArgs) (*types.ChapterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "chapter.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
chapter, err := story.FindChapterID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if chapter.Author != token.UserID && !token.Permitted("chapter.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
var fictionalDate *time.Time
|
|
||||||
if input.FictionalDate != nil {
|
|
||||||
date, err := time.Parse(time.RFC3339Nano, *input.FictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fictionalDate = &date
|
|
||||||
}
|
|
||||||
|
|
||||||
err = chapter.Edit(input.Title, input.Source, fictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Chapter", "edit", token.UserID, chapter.ID, map[string]interface{}{
|
|
||||||
"title": input.Title,
|
|
||||||
"source": input.Source,
|
|
||||||
"fictionalDate": fictionalDate,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.ChapterResolver{C: chapter}, nil
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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 }) (*types.CharacterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
character, err := character.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if character.Author != token.UserID && !token.Permitted("character.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
name := ""
|
|
||||||
if input.Name != nil {
|
|
||||||
name = *input.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
shortName := ""
|
|
||||||
if input.ShortName != nil {
|
|
||||||
shortName = *input.ShortName
|
|
||||||
}
|
|
||||||
|
|
||||||
description := ""
|
|
||||||
if input.Description != nil {
|
|
||||||
description = *input.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
err = character.Edit(name, shortName, description)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Character", "edit", token.UserID, character.ID, map[string]interface{}{
|
|
||||||
"name": character.Name,
|
|
||||||
"shortName": character.ShortName,
|
|
||||||
"description": character.Description,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: character}, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FileEditArgs is args for the editFile mutation
|
|
||||||
type FileEditArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Name *string
|
|
||||||
Public *bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditFile resolves the editFile mutation
|
|
||||||
func (r *MutationResolver) EditFile(ctx context.Context, args *FileEditArgs) (*types.FileResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := file.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if file.Author != token.UserID && !token.Permitted("file.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
err = file.Edit(input.Name, input.Public)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.FileResolver{F: file}, nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogEditArgs is args for the editLog mutation
|
|
||||||
type LogEditArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Title *string
|
|
||||||
Event *string
|
|
||||||
Description *string
|
|
||||||
Open *bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditLog resolves the editLog mutation
|
|
||||||
func (r *MutationResolver) EditLog(ctx context.Context, args *LogEditArgs) (*types.LogResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("log.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
log, err := log.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = log.Edit(input.Title, input.Event, input.Description, input.Open)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Log", "edit", token.UserID, log.ID, map[string]interface{}{
|
|
||||||
"channel": log.Channel,
|
|
||||||
"title": input.Title,
|
|
||||||
"event": input.Event,
|
|
||||||
"description": input.Description,
|
|
||||||
"open": input.Open,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.LogResolver{L: log}, nil
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostEditArgs is args for the editPost mutation
|
|
||||||
type PostEditArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Time *string
|
|
||||||
Kind *string
|
|
||||||
Nick *string
|
|
||||||
Text *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditPost resolves the editPost mutation
|
|
||||||
func (r *MutationResolver) EditPost(ctx context.Context, args *PostEditArgs) (*types.PostResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("post.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
postTime := (*time.Time)(nil)
|
|
||||||
if args.Input.Time != nil {
|
|
||||||
t, err := time.Parse(time.RFC3339Nano, *input.Time)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
postTime = &t
|
|
||||||
}
|
|
||||||
|
|
||||||
post, err := log.FindPostID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = post.Edit(postTime, input.Kind, input.Nick, input.Text)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Post", "edit", token.UserID, post.ID, map[string]interface{}{
|
|
||||||
"time": postTime,
|
|
||||||
"kind": input.Kind,
|
|
||||||
"nick": input.Nick,
|
|
||||||
"text": input.Text,
|
|
||||||
})
|
|
||||||
|
|
||||||
go log.UpdateCharacters(post.LogID)
|
|
||||||
|
|
||||||
return &types.PostResolver{P: post}, nil
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryEditArgs is args for the addStory mutation
|
|
||||||
type StoryEditArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Name *string
|
|
||||||
Category *string
|
|
||||||
Author *string
|
|
||||||
Open *bool
|
|
||||||
Listed *bool
|
|
||||||
FictionalDate *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditStory resolves the editStory mutation
|
|
||||||
func (r *MutationResolver) EditStory(ctx context.Context, args *StoryEditArgs) (*types.StoryResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "story.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if story.Author != token.UserID && !token.Permitted("story.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
var fictionalDate *time.Time
|
|
||||||
if input.FictionalDate != nil {
|
|
||||||
date, err := time.Parse(time.RFC3339Nano, *input.FictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fictionalDate = &date
|
|
||||||
}
|
|
||||||
|
|
||||||
err = story.Edit(input.Name, input.Category, input.Listed, input.Open, fictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Story", "edit", token.UserID, story.ID, map[string]interface{}{
|
|
||||||
"name": input.Name,
|
|
||||||
"category": input.Category,
|
|
||||||
"author": input.Author,
|
|
||||||
"open": input.Open,
|
|
||||||
"listed": input.Listed,
|
|
||||||
"fictionalDate": input.FictionalDate,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostMoveArgs is args for movePost mutation
|
|
||||||
type PostMoveArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
ToPosition int32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MovePost resolves the movePost mutation
|
|
||||||
func (r *MutationResolver) MovePost(ctx context.Context, args *PostMoveArgs) (*types.PostResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("post.move") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
post, err := log.FindPostID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = post.Move(int(input.ToPosition))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Post", "move", token.UserID, post.ID, map[string]interface{}{
|
|
||||||
"logId": post.LogID,
|
|
||||||
"targetIndex": input.ToPosition,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.PostResolver{P: post}, nil
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveChannelArgs is args for removeChannels mutation
|
|
||||||
type RemoveChannelArgs struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveChannel resolves the editChannel mutation
|
|
||||||
func (r *MutationResolver) RemoveChannel(ctx context.Context, args RemoveChannelArgs) (*types.ChannelResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("channel.remove") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err := channel.FindName(args.Name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = channel.Remove()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Channel", "remove", token.UserID, channel.Name, nil)
|
|
||||||
|
|
||||||
return &types.ChannelResolver{C: channel}, nil
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveChapterArgs is args for the addChapter mutation
|
|
||||||
type RemoveChapterArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveChapter resolves the removeChapter mutation
|
|
||||||
func (r *MutationResolver) RemoveChapter(ctx context.Context, args *RemoveChapterArgs) (*types.ChapterResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "chapter.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
chapter, err := story.FindChapterID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = chapter.Remove()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Chapter", "remove", token.UserID, chapter.ID, nil)
|
|
||||||
|
|
||||||
return &types.ChapterResolver{C: chapter}, nil
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveCharacterArgs is args for the removeCharacter mutation
|
|
||||||
type RemoveCharacterArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveCharacter resolves the removeCharacter mutation
|
|
||||||
func (r *MutationResolver) RemoveCharacter(ctx context.Context, args RemoveCharacterArgs) (*types.CharacterResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
character, err := character.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if character.Author != token.UserID && !token.Permitted("character.remove") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = character.Remove()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Character", "remove", token.UserID, character.ID, map[string]interface{}{
|
|
||||||
"name": character.Name,
|
|
||||||
"author": character.Author,
|
|
||||||
"nicks": character.Nicks,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: character}, nil
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveCharacterNick is args for the addCharacterNick mutation
|
|
||||||
type RemoveCharacterNick struct {
|
|
||||||
ID string
|
|
||||||
Nick string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveCharacterNick resolves the removeCharacterNick mutation
|
|
||||||
func (r *MutationResolver) RemoveCharacterNick(ctx context.Context, args struct{ Input *RemoveCharacterNick }) (*types.CharacterResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
character, err := character.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if character.Author != token.UserID && !token.Permitted("character.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = character.RemoveNick(input.Nick)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Character", "remove.nick", token.UserID, character.ID, map[string]interface{}{
|
|
||||||
"nick": input.Nick,
|
|
||||||
})
|
|
||||||
|
|
||||||
log.ScheduleCharacterUpdate()
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: character}, nil
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveFileArgs is an arg
|
|
||||||
type RemoveFileArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveFile resolves the removeFIle mutation
|
|
||||||
func (r *MutationResolver) RemoveFile(ctx context.Context, args *RemoveFileArgs) (*types.FileResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := file.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if file.Author != token.UserID && !token.Permitted("file.remove") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
err = file.Delete()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.FileResolver{F: file}, nil
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoveLogArgs is args for the removeLog mutation
|
|
||||||
type RemoveLogArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveLog resolves the removeLog mutation
|
|
||||||
func (r *MutationResolver) RemoveLog(ctx context.Context, args *RemoveLogArgs) (*types.LogResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("log.remove") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
log, err := log.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = log.Remove()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Log", "remove", token.UserID, log.ID, nil)
|
|
||||||
|
|
||||||
return &types.LogResolver{L: log}, nil
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostRemoveArgs is args for the removePost mutation
|
|
||||||
type PostRemoveArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovePost resolves the removePost mutation
|
|
||||||
func (r *MutationResolver) RemovePost(ctx context.Context, args PostRemoveArgs) (*types.PostResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("post.remove") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
post, err := log.RemovePost(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Post", "remove", token.UserID, post.ID, map[string]interface{}{
|
|
||||||
"logId": post.LogID,
|
|
||||||
})
|
|
||||||
|
|
||||||
go log.UpdateCharacters(post.LogID)
|
|
||||||
|
|
||||||
return &types.PostResolver{P: post}, nil
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryRemoveArgs is args for the removeStory mutation
|
|
||||||
type StoryRemoveArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveStory resolves the removeStory mutation
|
|
||||||
func (r *MutationResolver) RemoveStory(ctx context.Context, args *StoryRemoveArgs) (*types.StoryResolver, error) {
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "story.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if story.Author != token.UserID && !token.Permitted("story.remove") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = story.Remove()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Story", "remove", token.UserID, story.ID, nil)
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package mutations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/change"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryTagRemoveArgs is args for the removeStoryTag mutation
|
|
||||||
type StoryTagRemoveArgs struct {
|
|
||||||
Input *struct {
|
|
||||||
ID string
|
|
||||||
Tag struct {
|
|
||||||
Kind string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveStoryTag resolves the removeStoryTag mutation
|
|
||||||
func (r *MutationResolver) RemoveStoryTag(ctx context.Context, args *StoryTagRemoveArgs) (*types.StoryResolver, error) {
|
|
||||||
input := args.Input
|
|
||||||
tag := story.Tag{Kind: input.Tag.Kind, Name: input.Tag.Name}
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
if !token.Permitted("member", "story.edit") {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := story.FindID(input.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if story.Author != token.UserID && !token.Permitted("story.edit") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
err = story.RemoveTag(tag)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go change.Submit("Story", "remove.tag", token.UserID, story.ID, map[string]interface{}{
|
|
||||||
"kind": tag.Kind,
|
|
||||||
"name": tag.Name,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// Package mutations contains resolvers for individual GrahpQL mutations. They were previously mixed in with one another, but that caused
|
|
||||||
// difficulty seeking out specific mutations.
|
|
||||||
package mutations
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// MutationResolver is a resolver for all mutations. The stuttery name is due to being embedded in the root resolver.
|
|
||||||
type MutationResolver struct{}
|
|
||||||
|
|
||||||
// ErrUnauthorized is when a guest acts like they own the place
|
|
||||||
var ErrUnauthorized = errors.New("Unauthorized")
|
|
||||||
|
|
||||||
// ErrPermissionDenied is returned when users act above their station
|
|
||||||
var ErrPermissionDenied = errors.New("Permission denied")
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChannelArgs is args for channel query
|
|
||||||
type ChannelArgs struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel resolves the channel query
|
|
||||||
func (r *QueryResolver) Channel(ctx context.Context, args *ChannelArgs) (*types.ChannelResolver, error) {
|
|
||||||
channel, err := channel.FindName(args.Name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.ChannelResolver{C: channel}, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChannelsArgs is args for channel query
|
|
||||||
type ChannelsArgs struct {
|
|
||||||
Filter *struct {
|
|
||||||
Logged *bool
|
|
||||||
EventName *string
|
|
||||||
LocationName *string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channels resolves the channels query
|
|
||||||
func (r *QueryResolver) Channels(ctx context.Context, args *ChannelsArgs) ([]*types.ChannelResolver, error) {
|
|
||||||
var channels []channel.Channel
|
|
||||||
var err error
|
|
||||||
|
|
||||||
filter := args.Filter
|
|
||||||
if filter != nil {
|
|
||||||
channels, err = channel.List(filter.Logged, filter.EventName, filter.LocationName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
channels, err = channel.List(nil, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.ChannelResolver, len(channels))
|
|
||||||
for i := range channels {
|
|
||||||
resolvers[i] = &types.ChannelResolver{C: channels[i]}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChapterArgs is args for chapter query
|
|
||||||
type ChapterArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chapter resolves the chapter query
|
|
||||||
func (r *QueryResolver) Chapter(ctx context.Context, args *ChapterArgs) (*types.ChapterResolver, error) {
|
|
||||||
chapter, err := story.FindChapterID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.ChapterResolver{C: chapter}, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrIncorrectArguments is returned by character query.
|
|
||||||
var ErrIncorrectArguments = errors.New("You can only query character by ID or Nick")
|
|
||||||
|
|
||||||
// CharacterArgs is args for character query
|
|
||||||
type CharacterArgs struct {
|
|
||||||
ID *string
|
|
||||||
Nick *string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Character resolves the character query
|
|
||||||
func (r *QueryResolver) Character(ctx context.Context, args *CharacterArgs) (*types.CharacterResolver, error) {
|
|
||||||
var char character.Character
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if args.Nick != nil && args.ID != nil {
|
|
||||||
return nil, ErrIncorrectArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case args.ID != nil:
|
|
||||||
char, err = character.FindID(*args.ID)
|
|
||||||
case args.Nick != nil:
|
|
||||||
char, err = character.FindNick(*args.Nick)
|
|
||||||
default:
|
|
||||||
err = ErrIncorrectArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.CharacterResolver{C: char}, nil
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/character"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CharactersArgs is args for characters query
|
|
||||||
type CharactersArgs struct {
|
|
||||||
Filter *struct {
|
|
||||||
IDs *[]string
|
|
||||||
Nicks *[]string
|
|
||||||
Names *[]string
|
|
||||||
Author *string
|
|
||||||
Search *string
|
|
||||||
Logged *bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Characters resolves the characters query
|
|
||||||
func (r *QueryResolver) Characters(ctx context.Context, args *CharactersArgs) ([]*types.CharacterResolver, error) {
|
|
||||||
var characters []character.Character
|
|
||||||
var err error
|
|
||||||
|
|
||||||
filter := args.Filter
|
|
||||||
if filter != nil {
|
|
||||||
var ids []string
|
|
||||||
var nicks []string
|
|
||||||
var names []string
|
|
||||||
|
|
||||||
if filter.IDs != nil {
|
|
||||||
ids = *filter.IDs
|
|
||||||
}
|
|
||||||
if filter.Nicks != nil {
|
|
||||||
nicks = *filter.Nicks
|
|
||||||
}
|
|
||||||
if filter.Names != nil {
|
|
||||||
names = *filter.Names
|
|
||||||
}
|
|
||||||
|
|
||||||
characters, err = character.ListFilter(ids, nicks, names, filter.Author, filter.Search, filter.Logged)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
characters, err = character.List()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.CharacterResolver, 0, len(characters))
|
|
||||||
for _, character := range characters {
|
|
||||||
resolvers = append(resolvers, &types.CharacterResolver{C: character})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FileArgs is args for file query
|
|
||||||
type FileArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// File resolves the file query
|
|
||||||
func (r *QueryResolver) File(ctx context.Context, args *FileArgs) (*types.FileResolver, error) {
|
|
||||||
file, err := file.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.FileResolver{F: file}, nil
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FilesArgs is args for files query
|
|
||||||
type FilesArgs struct {
|
|
||||||
Filter *struct {
|
|
||||||
Public *bool
|
|
||||||
MimeTypes *[]string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Files resolves the file query
|
|
||||||
func (r *QueryResolver) Files(ctx context.Context, args *FilesArgs) ([]*types.FileResolver, error) {
|
|
||||||
filter := args.Filter
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
|
|
||||||
author := ""
|
|
||||||
if token != nil {
|
|
||||||
author = token.UserID
|
|
||||||
}
|
|
||||||
|
|
||||||
mimeTypes := []string(nil)
|
|
||||||
if filter.MimeTypes != nil {
|
|
||||||
mimeTypes = *filter.MimeTypes
|
|
||||||
}
|
|
||||||
|
|
||||||
files, err := file.List(author, filter.Public, mimeTypes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.FileResolver, len(files))
|
|
||||||
for i := range files {
|
|
||||||
resolvers[i] = &types.FileResolver{F: files[i]}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogArgs is args for log query
|
|
||||||
type LogArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log resolves the log query
|
|
||||||
func (r *QueryResolver) Log(ctx context.Context, args *LogArgs) (*types.LogResolver, error) {
|
|
||||||
log, err := log.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.LogResolver{L: log}, nil
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/loader"
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogsArgs is args for the logs query
|
|
||||||
type LogsArgs struct {
|
|
||||||
Filter *log.Filter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logs resolves the logs query
|
|
||||||
func (r *QueryResolver) Logs(ctx context.Context, args *LogsArgs) ([]*types.LogResolver, error) {
|
|
||||||
var logs []log.Log
|
|
||||||
|
|
||||||
filter := args.Filter
|
|
||||||
if filter == nil {
|
|
||||||
filter = log.NewFilter().WithLimit(100)
|
|
||||||
}
|
|
||||||
|
|
||||||
logs, err := log.List(filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(logs) >= 100 {
|
|
||||||
loader := loader.FromContext(ctx)
|
|
||||||
if loader == nil {
|
|
||||||
return nil, errors.New("no loader")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, log := range logs {
|
|
||||||
loader.PrimeCharacters("id", log.CharacterIDs...)
|
|
||||||
loader.PrimeChannels("name", log.Channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.LogResolver, len(logs))
|
|
||||||
for i := range logs {
|
|
||||||
resolvers[i] = &types.LogResolver{L: logs[i]}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostArgs is args for the post query
|
|
||||||
type PostArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post resolves the post query
|
|
||||||
func (r *QueryResolver) Post(ctx context.Context, args *PostArgs) (*types.PostResolver, error) {
|
|
||||||
post, err := log.FindPostID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.PostResolver{P: post}, nil
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostsArgs is args for the posts query
|
|
||||||
type PostsArgs struct {
|
|
||||||
IDs []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Posts resolves the posts query
|
|
||||||
func (r *QueryResolver) Posts(ctx context.Context, args *PostsArgs) ([]*types.PostResolver, error) {
|
|
||||||
posts, err := log.ListPostIDs(args.IDs...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.PostResolver, len(posts))
|
|
||||||
for i := range resolvers {
|
|
||||||
resolvers[i] = &types.PostResolver{P: posts[i]}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// Package queries contains resolvers for individual GrahpQL queries. They were previously mixed in with one another, but that caused
|
|
||||||
// difficulty seeking out specific queries.
|
|
||||||
package queries
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// QueryResolver is a resolver for all queries. The stuttery name is due to being embedded in the root resolver.
|
|
||||||
type QueryResolver struct{}
|
|
||||||
|
|
||||||
// ErrCannotResolve is returned when a resolver constructor is at its wit's end
|
|
||||||
var ErrCannotResolve = errors.New("Cannot resolve due to invalid arguments")
|
|
||||||
|
|
||||||
// ErrUnauthorized is when a guest acts like they own the place
|
|
||||||
var ErrUnauthorized = errors.New("Unauthorized")
|
|
||||||
|
|
||||||
// ErrPermissionDenied is returned when users act above their station
|
|
||||||
var ErrPermissionDenied = errors.New("Permission denied")
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/auth"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoriesArg is args for stories query
|
|
||||||
type StoriesArg struct {
|
|
||||||
Filter *struct {
|
|
||||||
Author *string
|
|
||||||
Tags *[]struct {
|
|
||||||
Kind string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
EarliestFictionalDate *string
|
|
||||||
LatestFictionalDate *string
|
|
||||||
Category *string
|
|
||||||
Limit *int32
|
|
||||||
Open *bool
|
|
||||||
Unlisted *bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stories resolves the stories query
|
|
||||||
func (r *QueryResolver) Stories(ctx context.Context, args *StoriesArg) ([]*types.StoryResolver, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
token := auth.TokenFromContext(ctx)
|
|
||||||
|
|
||||||
filter := args.Filter
|
|
||||||
|
|
||||||
author := ""
|
|
||||||
category := ""
|
|
||||||
tags := make([]story.Tag, 0, 8)
|
|
||||||
earliest := time.Time{}
|
|
||||||
latest := time.Time{}
|
|
||||||
unlisted := false
|
|
||||||
open := (*bool)(nil)
|
|
||||||
limit := 0
|
|
||||||
|
|
||||||
if filter != nil {
|
|
||||||
if filter.Author != nil {
|
|
||||||
author = *filter.Author
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.Category != nil {
|
|
||||||
category = *filter.Category
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.Tags != nil {
|
|
||||||
for _, tagInput := range *filter.Tags {
|
|
||||||
tags = append(tags, story.Tag{
|
|
||||||
Kind: tagInput.Kind,
|
|
||||||
Name: tagInput.Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.EarliestFictionalDate != nil {
|
|
||||||
earliest, err = time.Parse(time.RFC3339Nano, *filter.EarliestFictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.LatestFictionalDate != nil {
|
|
||||||
latest, err = time.Parse(time.RFC3339Nano, *filter.LatestFictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.Limit != nil {
|
|
||||||
limit = int(*filter.Limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
unlisted = filter.Unlisted != nil && *filter.Unlisted == true
|
|
||||||
if unlisted {
|
|
||||||
if token == nil {
|
|
||||||
return nil, ErrUnauthorized
|
|
||||||
}
|
|
||||||
|
|
||||||
if author != "" && author != token.UserID && !token.Permitted("story.unlisted") {
|
|
||||||
return nil, ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
author = token.UserID
|
|
||||||
}
|
|
||||||
|
|
||||||
open = filter.Open
|
|
||||||
}
|
|
||||||
|
|
||||||
stories, err := story.List(author, category, tags, earliest, latest, unlisted, open, limit)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.StoryResolver, len(stories))
|
|
||||||
for i, story := range stories {
|
|
||||||
resolvers[i] = &types.StoryResolver{S: story}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryArgs is args for story query
|
|
||||||
type StoryArgs struct {
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Story resolves the story query
|
|
||||||
func (r *QueryResolver) Story(ctx context.Context, args *StoryArgs) (*types.StoryResolver, error) {
|
|
||||||
story, err := story.FindID(args.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.StoryResolver{S: story}, nil
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package queries
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/types"
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Tags resolves the tags query
|
|
||||||
func (r *QueryResolver) Tags() ([]*types.TagResolver, error) {
|
|
||||||
tags, err := story.ListTags()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*types.TagResolver, len(tags))
|
|
||||||
for i, tag := range tags {
|
|
||||||
resolvers[i] = &types.TagResolver{T: tag}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/mutations"
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/resolver/queries"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The Resolver combines the query and mutation resolvers from the subpackages.
|
|
||||||
// This is the one to pass along with the schema.
|
|
||||||
type Resolver struct {
|
|
||||||
queries.QueryResolver
|
|
||||||
mutations.MutationResolver
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import "git.aiterp.net/rpdata/api/model/channel"
|
|
||||||
|
|
||||||
// ChannelResolver for the Channel graphql type
|
|
||||||
type ChannelResolver struct{ C channel.Channel }
|
|
||||||
|
|
||||||
// Name resolves channel.name
|
|
||||||
func (r *ChannelResolver) Name() string {
|
|
||||||
return r.C.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logged resolves channel.logged
|
|
||||||
func (r *ChannelResolver) Logged() bool {
|
|
||||||
return r.C.Logged
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hub resolves channel.hub
|
|
||||||
func (r *ChannelResolver) Hub() bool {
|
|
||||||
return r.C.Hub
|
|
||||||
}
|
|
||||||
|
|
||||||
// EventName resolves channel.eventName
|
|
||||||
func (r *ChannelResolver) EventName() *string {
|
|
||||||
if r.C.Event == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.C.Event
|
|
||||||
}
|
|
||||||
|
|
||||||
// LocationName resolves channel.locationName
|
|
||||||
func (r *ChannelResolver) LocationName() *string {
|
|
||||||
if r.C.Location == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.C.Location
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ChapterResolver for the Chapter graphql type
|
|
||||||
type ChapterResolver struct{ C story.Chapter }
|
|
||||||
|
|
||||||
// ID resolves Chapter.id
|
|
||||||
func (r *ChapterResolver) ID() string {
|
|
||||||
return r.C.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoryID resolves Chapter.storyId
|
|
||||||
func (r *ChapterResolver) StoryID() string {
|
|
||||||
return r.C.StoryID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title resolves Chapter.title
|
|
||||||
func (r *ChapterResolver) Title() string {
|
|
||||||
return r.C.Title
|
|
||||||
}
|
|
||||||
|
|
||||||
// Author resolves Chapter.author
|
|
||||||
func (r *ChapterResolver) Author() string {
|
|
||||||
return r.C.Author
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source resolves Chapter.source
|
|
||||||
func (r *ChapterResolver) Source() string {
|
|
||||||
return r.C.Source
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreatedDate resolves Chapter.createdDate
|
|
||||||
func (r *ChapterResolver) CreatedDate() string {
|
|
||||||
return r.C.CreatedDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FictionalDate resolves Chapter.fictionalDate
|
|
||||||
func (r *ChapterResolver) FictionalDate() string {
|
|
||||||
return r.C.FictionalDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditedDate resolves Chapter.editedDate
|
|
||||||
func (r *ChapterResolver) EditedDate() string {
|
|
||||||
return r.C.EditedDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import "git.aiterp.net/rpdata/api/model/character"
|
|
||||||
|
|
||||||
// CharacterResolver for the Character graphql type
|
|
||||||
type CharacterResolver struct{ C character.Character }
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/model/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FileResolver for the File graphql type
|
|
||||||
type FileResolver struct{ F file.File }
|
|
||||||
|
|
||||||
// ID resolves File.id
|
|
||||||
func (f *FileResolver) ID() string {
|
|
||||||
return f.F.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Author resolves File.author
|
|
||||||
func (f *FileResolver) Author() string {
|
|
||||||
return f.F.Author
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind resolves File.kind
|
|
||||||
func (f *FileResolver) Kind() string {
|
|
||||||
return f.F.Kind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time resolves File.time
|
|
||||||
func (f *FileResolver) Time() string {
|
|
||||||
return f.F.Time.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public resolves File.public
|
|
||||||
func (f *FileResolver) Public() bool {
|
|
||||||
return f.F.Public
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name resolves File.name
|
|
||||||
func (f *FileResolver) Name() string {
|
|
||||||
return f.F.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// MimeType resolves File.mimeType
|
|
||||||
func (f *FileResolver) MimeType() string {
|
|
||||||
return f.F.MimeType
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size resolves File.size
|
|
||||||
func (f *FileResolver) Size() int32 {
|
|
||||||
return int32(f.F.Size)
|
|
||||||
}
|
|
||||||
|
|
||||||
// URL resolves File.url
|
|
||||||
func (f *FileResolver) URL() *string {
|
|
||||||
if f.F.URL == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &f.F.URL
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/graphql/loader"
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogResolver for the Log graphql type
|
|
||||||
type LogResolver struct{ L log.Log }
|
|
||||||
|
|
||||||
// ID resolves Log.id
|
|
||||||
func (r *LogResolver) ID() string {
|
|
||||||
return r.L.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShortID resolves Log.shortId
|
|
||||||
func (r *LogResolver) ShortID() string {
|
|
||||||
return r.L.ShortID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date resolves Log.date
|
|
||||||
func (r *LogResolver) Date() string {
|
|
||||||
return r.L.Date.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChannelName resolves Log.channelName
|
|
||||||
func (r *LogResolver) ChannelName() string {
|
|
||||||
return r.L.Channel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel resolves Log.channe
|
|
||||||
func (r *LogResolver) Channel(ctx context.Context) (*ChannelResolver, error) {
|
|
||||||
loader := loader.FromContext(ctx)
|
|
||||||
if loader == nil {
|
|
||||||
return nil, errors.New("no loader")
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err := loader.Channel("name", r.L.Channel)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ChannelResolver{C: channel}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Title resolves Log.title
|
|
||||||
func (r *LogResolver) Title() string {
|
|
||||||
return r.L.Title
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event resolves Log.event
|
|
||||||
func (r *LogResolver) Event() string {
|
|
||||||
return r.L.Event
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description resolves Log.description
|
|
||||||
func (r *LogResolver) Description() string {
|
|
||||||
return r.L.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open resolves Log.open
|
|
||||||
func (r *LogResolver) Open() bool {
|
|
||||||
return r.L.Open
|
|
||||||
}
|
|
||||||
|
|
||||||
// Characters resolves Log.characters
|
|
||||||
func (r *LogResolver) Characters(ctx context.Context) ([]*CharacterResolver, error) {
|
|
||||||
loader := loader.FromContext(ctx)
|
|
||||||
if loader == nil {
|
|
||||||
return nil, errors.New("no loader")
|
|
||||||
}
|
|
||||||
|
|
||||||
chars, err := loader.Characters("id", r.L.CharacterIDs...)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Posts resolves Log.posts
|
|
||||||
func (r *LogResolver) Posts(ctx context.Context, args *LogPostArgs) ([]*PostResolver, error) {
|
|
||||||
var kinds []string
|
|
||||||
if args.Kinds != nil {
|
|
||||||
kinds = *args.Kinds
|
|
||||||
}
|
|
||||||
|
|
||||||
posts, err := r.L.Posts(kinds...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*PostResolver, len(posts))
|
|
||||||
for i := range posts {
|
|
||||||
resolvers[i] = &PostResolver{posts[i]}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogPostArgs is an arg
|
|
||||||
type LogPostArgs struct {
|
|
||||||
Kinds *[]string
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/model/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostResolver for the Post graphql type
|
|
||||||
type PostResolver struct{ P log.Post }
|
|
||||||
|
|
||||||
// ID resolves Post.id
|
|
||||||
func (r *PostResolver) ID() string {
|
|
||||||
return r.P.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogID resolves Post.logId
|
|
||||||
func (r *PostResolver) LogID() string {
|
|
||||||
return r.P.LogID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time resolves Post.time
|
|
||||||
func (r *PostResolver) Time() string {
|
|
||||||
return r.P.Time.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind resolves Post.logId
|
|
||||||
func (r *PostResolver) Kind() string {
|
|
||||||
return r.P.Kind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nick resolves Post.nick
|
|
||||||
func (r *PostResolver) Nick() string {
|
|
||||||
return r.P.Nick
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text resolves Post.text
|
|
||||||
func (r *PostResolver) Text() string {
|
|
||||||
return r.P.Text
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position resolves Post.text
|
|
||||||
func (r *PostResolver) Position() int32 {
|
|
||||||
return int32(r.P.Position)
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/model/story"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoryResolver for the Story graphql type
|
|
||||||
type StoryResolver struct{ S story.Story }
|
|
||||||
|
|
||||||
// ID resolves Story.id
|
|
||||||
func (r *StoryResolver) ID() string {
|
|
||||||
return r.S.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Author resolves Story.author
|
|
||||||
func (r *StoryResolver) Author() string {
|
|
||||||
return r.S.Author
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name resolves Story.name
|
|
||||||
func (r *StoryResolver) Name() string {
|
|
||||||
return r.S.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Category resolves Story.category
|
|
||||||
func (r *StoryResolver) Category() string {
|
|
||||||
return r.S.Category
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open resolves Story.open
|
|
||||||
func (r *StoryResolver) Open() bool {
|
|
||||||
return r.S.Open
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listed resolves Story.listed
|
|
||||||
func (r *StoryResolver) Listed() bool {
|
|
||||||
return r.S.Listed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tags resolves Story.tags
|
|
||||||
func (r *StoryResolver) Tags() []*TagResolver {
|
|
||||||
resolvers := make([]*TagResolver, len(r.S.Tags))
|
|
||||||
for i, tag := range r.S.Tags {
|
|
||||||
resolvers[i] = &TagResolver{T: tag}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chapters resolves Story.chapters
|
|
||||||
func (r *StoryResolver) Chapters() ([]*ChapterResolver, error) {
|
|
||||||
chapters, err := r.S.Chapters()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvers := make([]*ChapterResolver, len(chapters))
|
|
||||||
for i, chapter := range chapters {
|
|
||||||
resolvers[i] = &ChapterResolver{C: chapter}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreatedDate resolves Story.createdDate
|
|
||||||
func (r *StoryResolver) CreatedDate() string {
|
|
||||||
return r.S.CreatedDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FictionalDate resolves Story.fictionalDate
|
|
||||||
func (r *StoryResolver) FictionalDate() string {
|
|
||||||
return r.S.FictionalDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatedDate resolves Story.updatedDate
|
|
||||||
func (r *StoryResolver) UpdatedDate() string {
|
|
||||||
return r.S.UpdatedDate.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import "git.aiterp.net/rpdata/api/model/story"
|
|
||||||
|
|
||||||
// TagResolver for the Tag graphql type
|
|
||||||
type TagResolver struct{ T story.Tag }
|
|
||||||
|
|
||||||
// Kind resolves Tag.kind
|
|
||||||
func (r *TagResolver) Kind() string {
|
|
||||||
return r.T.Kind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name resolves Tag.name
|
|
||||||
func (r *TagResolver) Name() string {
|
|
||||||
return r.T.Name
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
# The Query type represents the read entry points into the API.
|
|
||||||
type Query {
|
|
||||||
# Find character by either an ID or a nick.
|
|
||||||
character(id: String, nick: String): Character
|
|
||||||
|
|
||||||
# Find characters
|
|
||||||
characters(filter: CharactersFilter): [Character!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find channel by name
|
|
||||||
channel(name: String!): Channel
|
|
||||||
|
|
||||||
# Find channels
|
|
||||||
channels(filter: ChannelsFilter): [Channel!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find log by ID
|
|
||||||
log(id: String!): Log
|
|
||||||
|
|
||||||
# Find logs
|
|
||||||
logs(filter: LogsFilter): [LogHeader!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find post by ID.
|
|
||||||
post(id: String!): Post
|
|
||||||
|
|
||||||
# Find posts by IDs. It's meant to allow other parts of the UI to link to a cluster of posts, e.g. for a room description for the
|
|
||||||
# Mapp should it ever become a thing. This does not have a filter, since it's meant to be queried in the logs' response's selection set.
|
|
||||||
posts(ids: [String!]!): [Post!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find file by ID
|
|
||||||
file(id: String!): File
|
|
||||||
|
|
||||||
# Find files
|
|
||||||
files(filter: FilesFilter): [File!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find story by ID
|
|
||||||
story(id: String!): Story
|
|
||||||
|
|
||||||
# Find stories
|
|
||||||
stories(filter: StoriesFilter): [Story!]!
|
|
||||||
|
|
||||||
|
|
||||||
# Find story chapter by ID
|
|
||||||
chapter(id: String!): Chapter
|
|
||||||
|
|
||||||
|
|
||||||
# Find all distinct tags used in stories
|
|
||||||
tags: [Tag!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
# The Mutation type represents write entry points into the API.
|
|
||||||
type Mutation {
|
|
||||||
# Add a new character
|
|
||||||
addCharacter(input: CharacterAddInput!): Character!
|
|
||||||
|
|
||||||
# Add nick to character
|
|
||||||
addCharacterNick(input: CharacterNickInput!): Character!
|
|
||||||
|
|
||||||
# Remove nick from character
|
|
||||||
removeCharacterNick(input: CharacterNickInput!): Character!
|
|
||||||
|
|
||||||
# Edit character
|
|
||||||
editCharacter(input: CharacterEditInput!): Character!
|
|
||||||
|
|
||||||
# Remove a character
|
|
||||||
removeCharacter(id: String!): Character!
|
|
||||||
|
|
||||||
|
|
||||||
# Add a channel
|
|
||||||
addChannel(input: ChannelAddInput!): Channel!
|
|
||||||
|
|
||||||
# Edit a channel
|
|
||||||
editChannel(input: ChannelEditInput!): Channel!
|
|
||||||
|
|
||||||
# Remove a channel
|
|
||||||
removeChannel(name: String!): Channel!
|
|
||||||
|
|
||||||
|
|
||||||
# Add a new log
|
|
||||||
addLog(input: LogAddInput!): Log!
|
|
||||||
|
|
||||||
# Edit a log
|
|
||||||
editLog(input: LogEditInput!): Log!
|
|
||||||
|
|
||||||
# Remove a log
|
|
||||||
removeLog(id: String!): Log!
|
|
||||||
|
|
||||||
|
|
||||||
# Add a post
|
|
||||||
addPost(input: AddPostInput!): Post!
|
|
||||||
|
|
||||||
# Edit a post
|
|
||||||
editPost(input: EditPostInput!): Post!
|
|
||||||
|
|
||||||
# Move a post
|
|
||||||
movePost(input: MovePostInput!): Post!
|
|
||||||
|
|
||||||
# Remove a post
|
|
||||||
removePost(id: String!): Post!
|
|
||||||
|
|
||||||
|
|
||||||
# Edit a file
|
|
||||||
editFile(input: EditFileInput!): File!
|
|
||||||
|
|
||||||
# Remove a file
|
|
||||||
removeFile(id: String!): File!
|
|
||||||
|
|
||||||
|
|
||||||
# Add a story
|
|
||||||
addStory(input: StoryAddInput!): Story!
|
|
||||||
|
|
||||||
# Add a story tag
|
|
||||||
addStoryTag(input: StoryTagAddInput!): Story!
|
|
||||||
|
|
||||||
# Remove a story tag
|
|
||||||
removeStoryTag(input: StoryTagRemoveInput!): Story!
|
|
||||||
|
|
||||||
# Edit a story
|
|
||||||
editStory(input: StoryEditInput!): Story!
|
|
||||||
|
|
||||||
# Remove a story
|
|
||||||
removeStory(id: String!): Story!
|
|
||||||
|
|
||||||
|
|
||||||
# Add a chapter to a story
|
|
||||||
addChapter(input: ChapterAddInput!): Chapter!
|
|
||||||
|
|
||||||
# Edit a chapter
|
|
||||||
editChapter(input: ChapterEditInput!): Chapter!
|
|
||||||
|
|
||||||
# Remove a chapter
|
|
||||||
removeChapter(id: String!): Chapter!
|
|
||||||
}
|
|
||||||
|
|
||||||
schema {
|
|
||||||
query: Query
|
|
||||||
mutation: Mutation
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
//go:generate go-bindata -ignore=\.go -pkg=schema -o=bindata.go ./...
|
|
||||||
|
|
||||||
import "bytes"
|
|
||||||
|
|
||||||
// String gets the schema
|
|
||||||
func String() string {
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
for _, name := range AssetNames() {
|
|
||||||
b := MustAsset(name)
|
|
||||||
buf.Write(b)
|
|
||||||
|
|
||||||
// Add a newline if the file does not end in a newline.
|
|
||||||
if len(b) > 0 && b[len(b)-1] != '\n' {
|
|
||||||
buf.WriteByte('\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# A Change is a part of the history that can be used to keep clients up to date.
|
|
||||||
type Change {
|
|
||||||
id: Int!
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
# Information about an IRC channel
|
|
||||||
type Channel {
|
|
||||||
# The channel's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# Whether the channel should be logged
|
|
||||||
logged: Boolean!
|
|
||||||
|
|
||||||
# Whether the channel is a hub channel
|
|
||||||
hub: Boolean!
|
|
||||||
|
|
||||||
# The event name, or `null` if none is specified
|
|
||||||
eventName: String
|
|
||||||
|
|
||||||
# The location name, or `null` if none is specified
|
|
||||||
locationName: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filters for the channels query
|
|
||||||
input ChannelsFilter {
|
|
||||||
# Filter to either logged or unlogged channels
|
|
||||||
logged: Boolean
|
|
||||||
|
|
||||||
# Filter by event name
|
|
||||||
eventName: String
|
|
||||||
|
|
||||||
# Filter by location name
|
|
||||||
locationName: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input ChannelAddInput {
|
|
||||||
# The channel's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# Whether the channel should be logged
|
|
||||||
logged: Boolean
|
|
||||||
|
|
||||||
# Whether the channel is a hub channel
|
|
||||||
hub: Boolean
|
|
||||||
|
|
||||||
# The event name, or `null` if none is specified
|
|
||||||
eventName: String
|
|
||||||
|
|
||||||
# The location name, or `null` if none is specified
|
|
||||||
locationName: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input ChannelEditInput {
|
|
||||||
# The channel's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# Whether the channel should be logged
|
|
||||||
logged: Boolean
|
|
||||||
|
|
||||||
# Whether the channel is a hub channel
|
|
||||||
hub: Boolean
|
|
||||||
|
|
||||||
# The event name, or `null` if none is specified
|
|
||||||
eventName: String
|
|
||||||
|
|
||||||
# The location name, or `null` if none is specified
|
|
||||||
locationName: String
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# A Chapter is the main content body of a story.
|
|
||||||
type Chapter {
|
|
||||||
# The chapter's ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The chapter's title
|
|
||||||
title: String!
|
|
||||||
|
|
||||||
# The chapter's author
|
|
||||||
author: String!
|
|
||||||
|
|
||||||
# The chapter's source
|
|
||||||
source: String!
|
|
||||||
|
|
||||||
# When the chapter was posted initialy
|
|
||||||
createdDate: String!
|
|
||||||
|
|
||||||
# The in-universe date and time of the chapter
|
|
||||||
fictionalDate: String!
|
|
||||||
|
|
||||||
# The date of edit.
|
|
||||||
editedDate: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for addChapter mutation
|
|
||||||
input ChapterAddInput {
|
|
||||||
# The story to add a chapter to
|
|
||||||
storyId: String!
|
|
||||||
|
|
||||||
# The title to give the chapter. It can not be left empty
|
|
||||||
title: String!
|
|
||||||
|
|
||||||
# The author to set for the chapter. It will use the logged in user ID, and only
|
|
||||||
# users with appropriate permissions can post as another author. Even then, it's only
|
|
||||||
# for importing/moving content. This author name will not be used when logging the
|
|
||||||
# submission
|
|
||||||
author: String
|
|
||||||
|
|
||||||
# The markdown source for the content
|
|
||||||
source: String!
|
|
||||||
|
|
||||||
# Optionally, assign a fictional date for the chapter
|
|
||||||
fictionalDate: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for editChapter mutation
|
|
||||||
input ChapterEditInput {
|
|
||||||
# The chapter to edit
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# Change the chapter's title
|
|
||||||
title: String
|
|
||||||
|
|
||||||
# Change the source
|
|
||||||
source: String
|
|
||||||
|
|
||||||
# Set the fictional date for a chapter
|
|
||||||
fictionalDate: String
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
# A Character represents an RP character
|
|
||||||
type Character {
|
|
||||||
# A unique identifier for the character
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The primary IRC nick belonging to the character
|
|
||||||
nick: String
|
|
||||||
|
|
||||||
# All IRC nicks associated with this character
|
|
||||||
nicks: [String!]!
|
|
||||||
|
|
||||||
# The character's author
|
|
||||||
author: String!
|
|
||||||
|
|
||||||
# The character's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# The name to display when space is scarce, usually the first/given name
|
|
||||||
shortName: String!
|
|
||||||
|
|
||||||
# A short description of the character
|
|
||||||
description: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filter for characters query
|
|
||||||
input CharactersFilter {
|
|
||||||
# Filter by character IDs
|
|
||||||
ids: [String!]
|
|
||||||
|
|
||||||
# Filter by nicks
|
|
||||||
nicks: [String!]
|
|
||||||
|
|
||||||
# Filter by names
|
|
||||||
names: [String!]
|
|
||||||
|
|
||||||
# Filter by author
|
|
||||||
author: String
|
|
||||||
|
|
||||||
# Filter by text search matching against the character's description
|
|
||||||
search: String
|
|
||||||
|
|
||||||
# Filter by whether they've been part of a log.
|
|
||||||
logged: Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for adding characters
|
|
||||||
input CharacterAddInput {
|
|
||||||
# The primary IRC nick name to recognize this character by
|
|
||||||
nick: String!
|
|
||||||
|
|
||||||
# The character's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# Optioanl shortened name. By default, it uses the first token in the name
|
|
||||||
shortName: String
|
|
||||||
|
|
||||||
# Description for a character.
|
|
||||||
description: String
|
|
||||||
|
|
||||||
# Optioanlly, specify another author. This needs special permissions if it's not
|
|
||||||
# your own username
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for addNick and removeNick mutation
|
|
||||||
input CharacterNickInput {
|
|
||||||
# The ID of the character
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The nick to add or remove
|
|
||||||
nick: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
input CharacterEditInput {
|
|
||||||
# The id for the character to edit
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The full name of the character -- not the salarian full name!
|
|
||||||
name: String
|
|
||||||
|
|
||||||
# The character's short name that is used in compact lists
|
|
||||||
shortName: String
|
|
||||||
|
|
||||||
# A short description for the character
|
|
||||||
description: String
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# A File contains information about a file and where to download it.
|
|
||||||
type File {
|
|
||||||
# The file's unique ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The kind of file. Most will be "upload", but some that are ported from the wiki will have other values for this.
|
|
||||||
kind: String!
|
|
||||||
|
|
||||||
# The time of uploading
|
|
||||||
time: String!
|
|
||||||
|
|
||||||
# Whether the file is publicly listable. Someone with knowledge of the ID
|
|
||||||
# will still be able to view it, however.
|
|
||||||
public: Boolean!
|
|
||||||
|
|
||||||
# The file's name
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# The MIME type of the file
|
|
||||||
mimeType: String!
|
|
||||||
|
|
||||||
# The file's size in bytes
|
|
||||||
size: Int!
|
|
||||||
|
|
||||||
# The uploader
|
|
||||||
author: String!
|
|
||||||
|
|
||||||
# The URL where the file is hosted
|
|
||||||
url: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filter for the files quiery.
|
|
||||||
input FilesFilter {
|
|
||||||
# If set, this will limit the results to either public or private files.
|
|
||||||
public: Boolean
|
|
||||||
|
|
||||||
# Limit the MIME types of the files.
|
|
||||||
mimeTypes: [String!]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for editFile mutation
|
|
||||||
input EditFileInput {
|
|
||||||
# The file's unique ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# Whether the file is publicly listable. Someone with knowledge of the ID
|
|
||||||
# will still be able to view it, however.
|
|
||||||
public: Boolean
|
|
||||||
|
|
||||||
# The file's name
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
# A Log is the "file" of an RP session
|
|
||||||
type Log {
|
|
||||||
# A unique identifier for the log.
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# A secondary unique identifier for the log. This is a lot shorter and more suitable for storage when
|
|
||||||
# the link doesn't need to be as expressive.
|
|
||||||
shortId: String!
|
|
||||||
|
|
||||||
# The date for a log.
|
|
||||||
date: String!
|
|
||||||
|
|
||||||
# The channel of a log.
|
|
||||||
channelName: String!
|
|
||||||
|
|
||||||
# Information about the channel this log is in.
|
|
||||||
channel: Channel!
|
|
||||||
|
|
||||||
# The session's title.
|
|
||||||
title: String!
|
|
||||||
|
|
||||||
# The log's event, which is the same as the tags in the previous logbot site.
|
|
||||||
# Empty string means that it's no event.
|
|
||||||
event: String!
|
|
||||||
|
|
||||||
# The description of a session, which is empty if unset.
|
|
||||||
description: String!
|
|
||||||
|
|
||||||
# Whether the log session is open.
|
|
||||||
open: Boolean!
|
|
||||||
|
|
||||||
# The characters involved in the log file.
|
|
||||||
characters: [Character!]!
|
|
||||||
|
|
||||||
# The posts of the logfile, which can be filtered by kinds.
|
|
||||||
posts(kinds:[String!]): [Post!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filter for logs query
|
|
||||||
input LogsFilter {
|
|
||||||
# Channels to limit results to (inclusive)
|
|
||||||
channels: [String!]
|
|
||||||
|
|
||||||
# Events to limit results to (inclusive)
|
|
||||||
events: [String!]
|
|
||||||
|
|
||||||
# Characters to limit results to (exclusive)
|
|
||||||
characters: [String!]
|
|
||||||
|
|
||||||
# Search post content
|
|
||||||
search: String
|
|
||||||
|
|
||||||
# Limit by whether it's open or not
|
|
||||||
open: Boolean
|
|
||||||
|
|
||||||
# Limit the amount of results you get back
|
|
||||||
limit: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for addLog mutation
|
|
||||||
input LogAddInput {
|
|
||||||
# The date of the log, in RFC3339 format with up to nanosecond precision
|
|
||||||
date: String!
|
|
||||||
|
|
||||||
# The channel where the log is set
|
|
||||||
channel: String!
|
|
||||||
|
|
||||||
# Optional: The log title
|
|
||||||
title: String
|
|
||||||
|
|
||||||
# Optional: Whether the log is open
|
|
||||||
open: Boolean
|
|
||||||
|
|
||||||
# Optional: The log event name
|
|
||||||
event: String
|
|
||||||
|
|
||||||
# Optional: A short description of the log
|
|
||||||
description: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for addLog mutation
|
|
||||||
input LogEditInput {
|
|
||||||
# The id of the log
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The log title
|
|
||||||
title: String
|
|
||||||
|
|
||||||
# The log event name
|
|
||||||
event: String
|
|
||||||
|
|
||||||
# A short description of the log
|
|
||||||
description: String
|
|
||||||
|
|
||||||
# Open/close the log
|
|
||||||
open: Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
# A LogHeader is a cut-down version of Log that does not allow getting the actual posts.
|
|
||||||
type LogHeader {
|
|
||||||
# A unique identifier for the log.
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# A secondary unique identifier for the log. This is a lot shorter and more suitable for storage when
|
|
||||||
# the link doesn't need to be as expressive.
|
|
||||||
shortId: String!
|
|
||||||
|
|
||||||
# The date for a log.
|
|
||||||
date: String!
|
|
||||||
|
|
||||||
# The channel name of a log.
|
|
||||||
channelName: String!
|
|
||||||
|
|
||||||
# Information about the channel this log is in.
|
|
||||||
channel: Channel!
|
|
||||||
|
|
||||||
# The session's title.
|
|
||||||
title: String!
|
|
||||||
|
|
||||||
# The log's event, which is the same as the tags in the previous logbot site.
|
|
||||||
# Empty string means that it's no event.
|
|
||||||
event: String!
|
|
||||||
|
|
||||||
# The description of a session, which is empty if unset.
|
|
||||||
description: String!
|
|
||||||
|
|
||||||
# Whether the log session is open.
|
|
||||||
open: Boolean!
|
|
||||||
|
|
||||||
# The characters involved in the log file.
|
|
||||||
characters: [Character!]!
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# A Post is a part of a log
|
|
||||||
type Post {
|
|
||||||
# The post's ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The post's Log ID. This is the closest thing to a link back since this API graph doesn't have any cycles.
|
|
||||||
logId: String!
|
|
||||||
|
|
||||||
# The date and time of posting
|
|
||||||
time: String!
|
|
||||||
|
|
||||||
# The kind of post this is. Only "text", "scene" and "action" are RP, while others are annotations and 'commands'.
|
|
||||||
kind: String!
|
|
||||||
|
|
||||||
# The character nick
|
|
||||||
nick: String!
|
|
||||||
|
|
||||||
# The post's text, which purpose depends on the kind
|
|
||||||
text: String!
|
|
||||||
|
|
||||||
# The post's position, used for reordering
|
|
||||||
position: Int!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the addPost mutation
|
|
||||||
input AddPostInput {
|
|
||||||
# The log's ID that this post should be a part of
|
|
||||||
logId: String!
|
|
||||||
|
|
||||||
# The date and time of posting, in a RFC3339 format with up to a nanosecond's precision
|
|
||||||
time: String!
|
|
||||||
|
|
||||||
# The kind of post this is. Only "text", "scene" and "action" are RP, while others are annotations and 'commands'.
|
|
||||||
kind: String!
|
|
||||||
|
|
||||||
# The character nick, or command invoker for non-RP stuff
|
|
||||||
nick: String!
|
|
||||||
|
|
||||||
# The post's text, which purpose depends on the kind
|
|
||||||
text: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the editPost mutation
|
|
||||||
input EditPostInput {
|
|
||||||
# The Post ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The date and time of posting, in a RFC3339 format with up to a nanosecond's precision
|
|
||||||
time: String
|
|
||||||
|
|
||||||
# The kind of post this is. Only "text", "scene" and "action" are RP, while others are annotations and 'commands'.
|
|
||||||
kind: String
|
|
||||||
|
|
||||||
# The character nick, or command invoker for non-RP stuff
|
|
||||||
nick: String
|
|
||||||
|
|
||||||
# The post's text, which purpose depends on the kind
|
|
||||||
text: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the movePost mutation
|
|
||||||
input MovePostInput {
|
|
||||||
# The Post ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# Target index
|
|
||||||
toPosition: Int!
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
# A Story is a piece of content that, unlike wiki articles, are not something that should be ordered by time instead of title. It can
|
|
||||||
# contain multiple chapters by one or more autohrs
|
|
||||||
type Story {
|
|
||||||
# The story's ID
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The story's name, which will show up in the lists.
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# The story's author
|
|
||||||
author: String!
|
|
||||||
|
|
||||||
# Whether other users may add/edit chapters to the story.
|
|
||||||
open: Boolean!
|
|
||||||
|
|
||||||
# Whether users without a direct link can find this story.
|
|
||||||
listed: Boolean!
|
|
||||||
|
|
||||||
# The category of the story
|
|
||||||
category: StoryCategory!
|
|
||||||
|
|
||||||
# The tags for this tory
|
|
||||||
tags: [Tag!]!
|
|
||||||
|
|
||||||
# The chapters of this story
|
|
||||||
chapters: [Chapter!]!
|
|
||||||
|
|
||||||
# The date the story was created (RFC3339 format).
|
|
||||||
createdDate: String!
|
|
||||||
|
|
||||||
# The date the story is set in (RFC3339 format).
|
|
||||||
fictionalDate: String!
|
|
||||||
|
|
||||||
# The date of the last major update to the story (RFC3339 format). This being bumped means a new chapter has been added.
|
|
||||||
updatedDate: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filter for stories query.
|
|
||||||
input StoriesFilter {
|
|
||||||
# What author to query for
|
|
||||||
author: String
|
|
||||||
|
|
||||||
# What category to query for
|
|
||||||
category: StoryCategory
|
|
||||||
|
|
||||||
# What tags to query for
|
|
||||||
tags: [TagInput!]
|
|
||||||
|
|
||||||
# If true, it will only show unlisted page you have access to
|
|
||||||
unlisted: Boolean
|
|
||||||
|
|
||||||
# Whether the page is open for additions by other users
|
|
||||||
open: Boolean
|
|
||||||
|
|
||||||
# The earliest fictionalDate
|
|
||||||
earliestFictionalDate: String
|
|
||||||
|
|
||||||
# The latest fictionalDate
|
|
||||||
latestFictionalDate: String
|
|
||||||
|
|
||||||
# The max amount of stories to get (default: 30)
|
|
||||||
limit: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the addStory mutation
|
|
||||||
input StoryAddInput {
|
|
||||||
# Set the name of the story, which will show up as the title, and as a suggestion for
|
|
||||||
# the first chapter being added.
|
|
||||||
name: String!
|
|
||||||
|
|
||||||
# Set the category for the new story.
|
|
||||||
category: StoryCategory!
|
|
||||||
|
|
||||||
# Add the story under another name. This requires the story.add permission, and should not be
|
|
||||||
# abused. The action will be logged with the actual creator's user ID.
|
|
||||||
author: String
|
|
||||||
|
|
||||||
# Allow other users to post chapters to the story.
|
|
||||||
open: Boolean
|
|
||||||
|
|
||||||
# Allow other users to see this page in any lists or search results.
|
|
||||||
listed: Boolean
|
|
||||||
|
|
||||||
# Set which tags the story should have.
|
|
||||||
tags: [TagInput!]
|
|
||||||
|
|
||||||
# Set the fictional date of the story (RFC3339 format).
|
|
||||||
fictionalDate: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the editStory mutation
|
|
||||||
input StoryEditInput {
|
|
||||||
# What story to edit
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# Set the name of the story, which will show up as the title, and as a suggestion for
|
|
||||||
# the first chapter being added.
|
|
||||||
name: String
|
|
||||||
|
|
||||||
# Set the category for the new story.
|
|
||||||
category: StoryCategory
|
|
||||||
|
|
||||||
# Add the story under another name. This requires the story.add permission, and should not be
|
|
||||||
# abused. The action will be logged with the actual creator's user ID.
|
|
||||||
author: String
|
|
||||||
|
|
||||||
# Change whether to allow others to add chapters
|
|
||||||
open: Boolean
|
|
||||||
|
|
||||||
# Change whether to show this story in the list and search results
|
|
||||||
listed: Boolean
|
|
||||||
|
|
||||||
# Set the fictional date of the story (RFC3339 format).
|
|
||||||
fictionalDate: String
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the addStoryTag mutation
|
|
||||||
input StoryTagAddInput {
|
|
||||||
# What story to add the tag to.
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The tag to add.
|
|
||||||
tag: TagInput!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Input for the removeStoryTag mutation
|
|
||||||
input StoryTagRemoveInput {
|
|
||||||
# What story to remove the tag from.
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# The tag to remove.
|
|
||||||
tag: TagInput!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Possible values for Story.category
|
|
||||||
enum StoryCategory {
|
|
||||||
# General information
|
|
||||||
Info
|
|
||||||
|
|
||||||
# News stories
|
|
||||||
News
|
|
||||||
|
|
||||||
# Description and content of a document or item
|
|
||||||
Document
|
|
||||||
|
|
||||||
# Information about something going on in the background that may or may not inform RP
|
|
||||||
Background
|
|
||||||
|
|
||||||
# A short story
|
|
||||||
Story
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# A Tag is a means of associating stories that have details in common with one another.
|
|
||||||
type Tag {
|
|
||||||
# The tag's kind
|
|
||||||
kind: TagKind!
|
|
||||||
|
|
||||||
# The tag's name
|
|
||||||
name: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# A Tag is a means of associating stories that have details in common with one another.
|
|
||||||
input TagInput {
|
|
||||||
# The tag's kind
|
|
||||||
kind: TagKind!
|
|
||||||
|
|
||||||
# The tag's name
|
|
||||||
name: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Allowed values for Tag.kind
|
|
||||||
enum TagKind {
|
|
||||||
# An organization is a catch all term for in-universe corporations, teams, groups, cults, forces, etc...
|
|
||||||
Organization
|
|
||||||
|
|
||||||
# A character tag should have the exact full name of the character.
|
|
||||||
Character
|
|
||||||
|
|
||||||
# A location is anything from a planet to an establishment. This may overlap with an organization, and if so, both
|
|
||||||
# kinds of tags should be used.
|
|
||||||
Location
|
|
||||||
|
|
||||||
# An event is a plot or a part of a plot.
|
|
||||||
Event
|
|
||||||
|
|
||||||
# None of the above, but it does still tie multiple stories together. The new story/chapter format may obsolete this tag kind.
|
|
||||||
Series
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# The User type is for interacting with user options and settings
|
|
||||||
type User {
|
|
||||||
# Their username
|
|
||||||
id: String!
|
|
||||||
|
|
||||||
# Their permission
|
|
||||||
permissions: [String!]!
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user