chore: init

This commit is contained in:
DevMiner 2024-08-11 03:51:22 +02:00
commit 320715f3e7
174 changed files with 42083 additions and 0 deletions

View file

@ -0,0 +1,86 @@
package api_schema
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
)
type APIError struct {
StatusCode int `json:"status_code"`
Description string `json:"description"`
Metadata map[string]any `json:"metadata,omitempty"`
}
func (e APIError) Error() string {
if e.Metadata == nil || len(e.Metadata) == 0 {
return fmt.Sprintf("APIError: %d - %s", e.StatusCode, e.Description)
}
return fmt.Sprintf("APIError: %d - %s, %s", e.StatusCode, e.Description, stringifyErrorMetadata(e.Metadata))
}
func stringifyErrorMetadata(m map[string]any) string {
sb := strings.Builder{}
for key, value := range m {
sb.WriteString(fmt.Sprintf("%s=%v, ", key, value))
}
return strings.TrimSuffix(sb.String(), ", ")
}
func (e APIError) Equals(other any) bool {
var err *APIError
switch raw := other.(type) {
case *APIError:
err = raw
default:
return false
}
return e.StatusCode == err.StatusCode && e.Description == err.Description
}
func (e APIError) URLEncode() (string, error) {
v := url.Values{}
v.Set("status_code", fmt.Sprintf("%d", e.StatusCode))
v.Set("description", e.Description)
if e.Metadata != nil {
b, err := json.Marshal(e.Metadata)
if err != nil {
return "", err
}
v.Set("metadata", string(b))
}
// Fix up spaces because Golang's net/url.URL encodes " " as "+" instead of "%20"
// https://github.com/golang/go/issues/13982
return strings.ReplaceAll(v.Encode(), "+", "%20"), nil
}
func NewAPIError(code int, description string) func(metadata map[string]any) *APIError {
return func(metadata map[string]any) *APIError {
return &APIError{StatusCode: code, Description: description, Metadata: metadata}
}
}
type APIResponse[T any] struct {
Ok bool `json:"ok"`
Data *T `json:"data"`
Error *APIError `json:"error"`
}
func NewFailedAPIResponse[T any](err error) APIResponse[T] {
var e *APIError
if errors.As(err, &e) {
} else {
e = NewAPIError(500, err.Error())(nil)
}
return APIResponse[T]{Ok: false, Error: e}
}

View file

@ -0,0 +1,15 @@
package api_schema
var (
ErrBadRequest = NewAPIError(400, "Bad request")
ErrInvalidRequestBody = NewAPIError(400, "Invalid request body")
ErrUnauthorized = NewAPIError(401, "Unauthorized")
ErrForbidden = NewAPIError(403, "Forbidden")
ErrNotFound = NewAPIError(404, "Not found")
ErrConflict = NewAPIError(409, "Conflict")
ErrUsernameTaken = NewAPIError(409, "Username is taken")
ErrRateLimitExceeded = NewAPIError(429, "Rate limit exceeded")
ErrInternalServerError = NewAPIError(500, "Internal server error")
ErrNotImplemented = NewAPIError(501, "Not implemented")
)

View file

@ -0,0 +1,18 @@
package api_schema
import (
"github.com/google/uuid"
"github.com/lysand-org/versia-go/pkg/lysand"
)
type Note struct {
ID uuid.UUID `json:"id,string"`
}
type FetchNoteResponse = APIResponse[Note]
type CreateNoteRequest struct {
Content string `json:"content" validate:"required,min=1,max=1024"`
Visibility lysand.PublicationVisibility `json:"visibility" validate:"required,oneof=public private direct"`
Mentions []lysand.URL `json:"mentions"`
}

View file

@ -0,0 +1,17 @@
package api_schema
import (
"github.com/google/uuid"
)
type User struct {
ID uuid.UUID `json:"id,string"`
Username string `json:"username"`
}
type FetchUserResponse = APIResponse[User]
type CreateUserRequest struct {
Username string `json:"username" validate:"required,username_regex,min=3,max=32"`
Password string `json:"password" validate:"required,min=8,max=256"`
}