diff --git a/command/handler.go b/command/handler.go index dca694e..4b107b0 100644 --- a/command/handler.go +++ b/command/handler.go @@ -131,10 +131,10 @@ func (c *Command) Create(ctx *gin.Context) { log.Debugf("%+v", toCreate) - // if _, err := c.Conn.Create(c.Table, toCreate); err != nil { - // util.NiceError(ctx, err, http.StatusBadRequest) - // return - // } + if _, err := c.Conn.Create(c.Table, toCreate); err != nil { + util.NiceError(ctx, err, http.StatusBadRequest) + return + } // Pass control off to GetSingle since we don't want to duplicate logic c.GetSingle(ctx) diff --git a/command/schema.go b/command/schema.go index ccf7c74..3f4b8f8 100644 --- a/command/schema.go +++ b/command/schema.go @@ -7,44 +7,27 @@ import ( // ResponseSchema is the schema for the data that will be sent out to the client type ResponseSchema struct { - ID string `jsonapi:"id,primary"` - Arguments []schemas.MessagePacket `jsonapi:"arguments,attr"` - Count int `jsonapi:"count,attr"` - CreatedAt string `jsonapi:"createdAt,meta"` - Enabled bool `jsonapi:"enabled,attr"` - Name string `jsonapi:"name,attr"` - Response EmbeddedResponseSchema `jsonapi:"response,attr"` - Token string `jsonapi:"token,meta"` + ID string `jsonapi:"primary,id"` + Name string `jsonapi:"attr,name"` + Context schemas.Context `jsonapi:"attr,context"` // TODO: use only data packet + Count int `jsonapi:"attr,count"` + Enabled bool `jsonapi:"attr,enabled"` + CreatedAt string `jsonapi:"meta,createdAt"` + Token string `jsonapi:"meta,token"` } // ClientSchema is the schema the data from the client will be marshalled into type ClientSchema struct { - Arguments []schemas.MessagePacket `json:"arguments" validate:"required"` - Enabled bool `json:"enabled" validate:"required"` - Response EmbeddedResponseSchema `json:"response" validate:"required"` + Context schemas.Context `json:"context" validate:"required"` + Enabled bool `json:"enabled" validate:"required"` // Ignore these fields in user input, they will be filled automatically by the API - ID string `json:"id" validate:"-"` - Count int `json:"count" validate:"-"` - CreatedAt string `json:"createdAt" validate:"-"` - Token string `json:"token" validate:"-"` - Name string `json:"name" validate:"-"` -} - -// EmbeddedResponseSchema is the schema that is stored under the response key in ResponseSchema -type EmbeddedResponseSchema struct { - Action bool `jsonapi:"action,attr" validate:"required"` - Message []schemas.MessagePacket `jsonapi:"message,attr" validate:"required,gt=0"` - Role int `jsonapi:"role,attr" validate:"gte=0,lte=256"` - Target string `jsonapi:"target,attr"` - User string `jsonapi:"user,attr"` + ID string `json:"id" validate:"-"` + Count int `json:"count" validate:"-"` + Token string `json:"token" validate:"-"` + Name string `json:"name" validate:"-"` } // GetAPITag allows each of these types to implement the JSONAPISchema interface func (r ResponseSchema) GetAPITag(lookup string) string { return util.FieldTag(r, lookup, "jsonapi") } - -// GetAPITag allows each of these types to implement the JSONAPISchema interface -func (r EmbeddedResponseSchema) GetAPITag(lookup string) string { - return util.FieldTag(r, lookup, "jsonapi") -} diff --git a/schemas/schemas.go b/schemas/schemas.go index b88adf7..c55b6bb 100644 --- a/schemas/schemas.go +++ b/schemas/schemas.go @@ -1,8 +1,67 @@ package schemas -// MessagePacket is the low-level format for storing contents of a message and arguments -type MessagePacket struct { - Data string `json:"data" validate:"required"` - Text string `json:"text" validate:"required"` - Type string `json:"type" validate:"required"` +import ( + "strings" +) + +// TODO: Remove `jsonapi:` tags. Should just be `json:`. +type Message struct { + Text []Component `jsonapi:"attr,text"` + Action bool `jsonapi:"attr,action"` +} + +// TODO: Remove `jsonapi:` tags. Should just be `json:`. +type Component struct { + Type string `jsonapi:"attr,type"` // HACK: need to validate type + Data string `jsonapi:"attr,data"` +} + +type Channel string +type User string +type Service string + +// TODO: Remove `jsonapi:` tags. Should just be `json:`. +type Context struct { + Packet Message `jsonapi:"attr,packet"` + Channel Channel `jsonapi:"attr,channel"` + User User `jsonapi:"attr,user,omitempty"` + Role Role `jsonapi:"attr,role,omitempty"` // FIXME: should return string ("owner"), not int (5). See UnmarshalJSON below. + Target User `jsonapi:"attr,target,omitempty"` + Service Service `jsonapi:"attr,service"` +} + +type Role int + +const ( + banned Role = iota + user + subscriber + moderator + owner +) + +func (r *Role) UnmarshalJSON(b []byte) error { + str := strings.Trim(string(b), `"`) + + switch { + case str == "banned": + *r = banned + + case str == "user": + *r = user + + case str == "subscriber": + *r = subscriber + + case str == "moderator": + *r = moderator + + case str == "owner": + *r = owner + + default: + *r = user + } + + return nil } diff --git a/util/jsonapi.go b/util/jsonapi.go index e927546..9698f9f 100644 --- a/util/jsonapi.go +++ b/util/jsonapi.go @@ -55,21 +55,21 @@ func pullVals(ift reflect.Type, ifv reflect.Value) (map[string]interface{}, map[ id = subID } } - // Anything after the first element is tags, figure out which we want - for _, tag := range split[1:] { - // Need to set the keys w/ their names here if it's a struct - switch tag { - case "attr": - // Attribute - attr[split[0]] = value - case "meta": - // Meta information about the request - meta[split[0]] = value - case "primary": - // It's the primary key/record ID - id = ifv.Field(i).String() - default: // Ignore any other tags - } + // Need to set the keys w/ their names here if it's a struct + switch split[0] { + case "attr": + // Attribute + attr[split[1]] = value + break + case "meta": + // Meta information about the request + meta[split[1]] = value + break + case "primary": + // It's the primary key/record ID + id = ifv.Field(i).String() + break + default: // Ignore any other tags } }