feat: initial implementation with docs and system_config

This commit is contained in:
2026-06-01 11:19:02 -04:00
commit 1337034f07
39 changed files with 3451 additions and 0 deletions
+239
View File
@@ -0,0 +1,239 @@
package client
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type AlbumUser struct {
User *User `json:"user,omitempty"`
Role string `json:"role"`
}
type Album struct {
ID string `json:"id,omitempty"`
AlbumName string `json:"albumName"`
Description string `json:"description"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
AlbumThumbnailAssetId *string `json:"albumThumbnailAssetId"`
Shared bool `json:"shared"`
AlbumUsers []AlbumUser `json:"albumUsers"`
HasSharedLink bool `json:"hasSharedLink"`
AssetCount int `json:"assetCount"`
IsActivityEnabled bool `json:"isActivityEnabled"`
Order string `json:"order,omitempty"`
}
type AlbumUserCreate struct {
UserId string `json:"userId"`
Role string `json:"role"`
}
type CreateAlbumRequest struct {
AlbumName string `json:"albumName"`
Description string `json:"description,omitempty"`
AlbumUsers []AlbumUserCreate `json:"albumUsers,omitempty"`
AssetIds []string `json:"assetIds,omitempty"`
}
type UpdateAlbumRequest struct {
AlbumName string `json:"albumName,omitempty"`
Description string `json:"description,omitempty"`
AlbumThumbnailAssetId *string `json:"albumThumbnailAssetId,omitempty"`
IsActivityEnabled *bool `json:"isActivityEnabled,omitempty"`
Order string `json:"order,omitempty"`
}
type BulkIdsRequest struct {
Ids []string `json:"ids"`
}
func (c *Client) GetAlbums() ([]Album, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/albums", c.HostURL), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var albums []Album
err = json.Unmarshal(body, &albums)
if err != nil {
return nil, err
}
return albums, nil
}
func (c *Client) GetAlbum(id string) (*Album, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/albums/%s", c.HostURL, id), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var album Album
err = json.Unmarshal(body, &album)
if err != nil {
return nil, err
}
return &album, nil
}
func (c *Client) CreateAlbum(data CreateAlbumRequest) (*Album, error) {
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/albums", c.HostURL), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var album Album
err = json.Unmarshal(body, &album)
if err != nil {
return nil, err
}
return &album, nil
}
func (c *Client) UpdateAlbum(id string, data UpdateAlbumRequest) (*Album, error) {
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PATCH", fmt.Sprintf("%s/albums/%s", c.HostURL, id), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var album Album
err = json.Unmarshal(body, &album)
if err != nil {
return nil, err
}
return &album, nil
}
func (c *Client) DeleteAlbum(id string) error {
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/albums/%s", c.HostURL, id), nil)
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}
func (c *Client) AddAssetsToAlbum(albumId string, assetIds []string) error {
data := BulkIdsRequest{Ids: assetIds}
rb, err := json.Marshal(data)
if err != nil {
return err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/albums/%s/assets", c.HostURL, albumId), bytes.NewBuffer(rb))
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}
type AddUsersRequest struct {
AlbumUsers []AlbumUserCreate `json:"albumUsers"`
}
type UpdateAlbumUserRequest struct {
Role string `json:"role"`
}
func (c *Client) AddUsersToAlbum(albumId string, users []AlbumUserCreate) (*Album, error) {
data := AddUsersRequest{AlbumUsers: users}
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/albums/%s/users", c.HostURL, albumId), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var album Album
err = json.Unmarshal(body, &album)
if err != nil {
return nil, err
}
return &album, nil
}
func (c *Client) UpdateAlbumUserRole(albumId string, userId string, role string) (*Album, error) {
data := UpdateAlbumUserRequest{Role: role}
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/albums/%s/user/%s", c.HostURL, albumId, userId), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var album Album
err = json.Unmarshal(body, &album)
if err != nil {
return nil, err
}
return &album, nil
}
func (c *Client) RemoveUserFromAlbum(albumId string, userId string) error {
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/albums/%s/user/%s", c.HostURL, albumId, userId), nil)
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}
+131
View File
@@ -0,0 +1,131 @@
package client
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type ApiKey struct {
ID string `json:"id"`
Name string `json:"name"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Permissions []string `json:"permissions"`
}
type ApiKeyCreateResponse struct {
Secret string `json:"secret"`
ApiKey ApiKey `json:"apiKey"`
}
type ApiKeyCreateRequest struct {
Name string `json:"name,omitempty"`
Permissions []string `json:"permissions"`
}
type ApiKeyUpdateRequest struct {
Name string `json:"name,omitempty"`
Permissions []string `json:"permissions,omitempty"`
}
func (c *Client) GetApiKeys() ([]ApiKey, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api-keys", c.HostURL), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var apiKeys []ApiKey
err = json.Unmarshal(body, &apiKeys)
if err != nil {
return nil, err
}
return apiKeys, nil
}
func (c *Client) GetApiKey(apiKeyID string) (*ApiKey, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/api-keys/%s", c.HostURL, apiKeyID), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var apiKey ApiKey
err = json.Unmarshal(body, &apiKey)
if err != nil {
return nil, err
}
return &apiKey, nil
}
func (c *Client) CreateApiKey(apiKey ApiKeyCreateRequest) (*ApiKeyCreateResponse, error) {
rb, err := json.Marshal(apiKey)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api-keys", c.HostURL), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var resp ApiKeyCreateResponse
err = json.Unmarshal(body, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}
func (c *Client) UpdateApiKey(apiKeyID string, apiKey ApiKeyUpdateRequest) (*ApiKey, error) {
rb, err := json.Marshal(apiKey)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/api-keys/%s", c.HostURL, apiKeyID), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var updatedApiKey ApiKey
err = json.Unmarshal(body, &updatedApiKey)
if err != nil {
return nil, err
}
return &updatedApiKey, nil
}
func (c *Client) DeleteApiKey(apiKeyID string) error {
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/api-keys/%s", c.HostURL, apiKeyID), nil)
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}
+43
View File
@@ -0,0 +1,43 @@
package client
import (
"fmt"
"io"
"net/http"
)
type Client struct {
HostURL string
HTTPClient *http.Client
Token string
}
func NewClient(host, token string) *Client {
return &Client{
HTTPClient: &http.Client{},
HostURL: host,
Token: token,
}
}
func (c *Client) doRequest(req *http.Request) ([]byte, error) {
req.Header.Set("x-api-key", c.Token)
req.Header.Set("Content-Type", "application/json")
res, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
if res.StatusCode < 200 || res.StatusCode >= 300 {
return nil, fmt.Errorf("status: %d, body: %s", res.StatusCode, string(body))
}
return body, nil
}
+145
View File
@@ -0,0 +1,145 @@
package client
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type SharedLink struct {
ID string `json:"id"`
Description *string `json:"description"`
UserId string `json:"userId"`
Key string `json:"key"`
Type string `json:"type"`
CreatedAt string `json:"createdAt"`
ExpiresAt *string `json:"expiresAt"`
AllowUpload bool `json:"allowUpload"`
AllowDownload bool `json:"allowDownload"`
ShowMetadata bool `json:"showMetadata"`
Slug *string `json:"slug"`
}
type SharedLinkCreateRequest struct {
Type string `json:"type"`
AssetIds []string `json:"assetIds,omitempty"`
AlbumId *string `json:"albumId,omitempty"`
Description *string `json:"description,omitempty"`
Password *string `json:"password,omitempty"`
Slug *string `json:"slug,omitempty"`
ExpiresAt *string `json:"expiresAt,omitempty"`
AllowUpload *bool `json:"allowUpload,omitempty"`
AllowDownload *bool `json:"allowDownload,omitempty"`
ShowMetadata *bool `json:"showMetadata,omitempty"`
}
type SharedLinkUpdateRequest struct {
Description *string `json:"description,omitempty"`
Password *string `json:"password,omitempty"`
Slug *string `json:"slug,omitempty"`
ExpiresAt *string `json:"expiresAt,omitempty"`
AllowUpload *bool `json:"allowUpload,omitempty"`
AllowDownload *bool `json:"allowDownload,omitempty"`
ShowMetadata *bool `json:"showMetadata,omitempty"`
}
func (c *Client) GetSharedLinks() ([]SharedLink, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/shared-links", c.HostURL), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var sharedLinks []SharedLink
err = json.Unmarshal(body, &sharedLinks)
if err != nil {
return nil, err
}
return sharedLinks, nil
}
func (c *Client) GetSharedLink(id string) (*SharedLink, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/shared-links/%s", c.HostURL, id), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var sharedLink SharedLink
err = json.Unmarshal(body, &sharedLink)
if err != nil {
return nil, err
}
return &sharedLink, nil
}
func (c *Client) CreateSharedLink(data SharedLinkCreateRequest) (*SharedLink, error) {
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/shared-links", c.HostURL), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var sharedLink SharedLink
err = json.Unmarshal(body, &sharedLink)
if err != nil {
return nil, err
}
return &sharedLink, nil
}
func (c *Client) UpdateSharedLink(id string, data SharedLinkUpdateRequest) (*SharedLink, error) {
rb, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PATCH", fmt.Sprintf("%s/shared-links/%s", c.HostURL, id), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var sharedLink SharedLink
err = json.Unmarshal(body, &sharedLink)
if err != nil {
return nil, err
}
return &sharedLink, nil
}
func (c *Client) DeleteSharedLink(id string) error {
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/shared-links/%s", c.HostURL, id), nil)
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}
+77
View File
@@ -0,0 +1,77 @@
package client
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type SystemConfig struct {
Backup map[string]interface{} `json:"backup"`
FFmpeg map[string]interface{} `json:"ffmpeg"`
Logging map[string]interface{} `json:"logging"`
MachineLearning map[string]interface{} `json:"machineLearning"`
Map map[string]interface{} `json:"map"`
NewVersionCheck map[string]interface{} `json:"newVersionCheck"`
NightlyTasks map[string]interface{} `json:"nightlyTasks"`
OAuth map[string]interface{} `json:"oauth"`
PasswordLogin map[string]interface{} `json:"passwordLogin"`
ReverseGeocoding map[string]interface{} `json:"reverseGeocoding"`
Metadata map[string]interface{} `json:"metadata"`
StorageTemplate map[string]interface{} `json:"storageTemplate"`
Job map[string]interface{} `json:"job"`
Image map[string]interface{} `json:"image"`
Trash map[string]interface{} `json:"trash"`
Theme map[string]interface{} `json:"theme"`
Library map[string]interface{} `json:"library"`
Notifications map[string]interface{} `json:"notifications"`
Templates map[string]interface{} `json:"templates"`
Server map[string]interface{} `json:"server"`
User map[string]interface{} `json:"user"`
}
func (c *Client) GetSystemConfig() (*SystemConfig, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/system-config", c.HostURL), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var config SystemConfig
err = json.Unmarshal(body, &config)
if err != nil {
return nil, err
}
return &config, nil
}
func (c *Client) UpdateSystemConfig(config SystemConfig) (*SystemConfig, error) {
rb, err := json.Marshal(config)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/system-config", c.HostURL), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var updatedConfig SystemConfig
err = json.Unmarshal(body, &updatedConfig)
if err != nil {
return nil, err
}
return &updatedConfig, nil
}
+143
View File
@@ -0,0 +1,143 @@
package client
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type User struct {
ID string `json:"id,omitempty"`
Email string `json:"email"`
Name string `json:"name"`
IsAdmin bool `json:"isAdmin"`
StorageLabel string `json:"storageLabel,omitempty"`
QuotaSizeInBytes *int64 `json:"quotaSizeInBytes,omitempty"`
ShouldChangePassword bool `json:"shouldChangePassword,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
}
type UserAdminCreateRequest struct {
Email string `json:"email"`
Password string `json:"password"`
Name string `json:"name"`
IsAdmin bool `json:"isAdmin,omitempty"`
StorageLabel string `json:"storageLabel,omitempty"`
QuotaSizeInBytes *int64 `json:"quotaSizeInBytes,omitempty"`
ShouldChangePassword bool `json:"shouldChangePassword,omitempty"`
}
type UserAdminUpdateRequest struct {
Email string `json:"email,omitempty"`
Password string `json:"password,omitempty"`
Name string `json:"name,omitempty"`
IsAdmin bool `json:"isAdmin,omitempty"`
StorageLabel string `json:"storageLabel,omitempty"`
QuotaSizeInBytes *int64 `json:"quotaSizeInBytes,omitempty"`
ShouldChangePassword bool `json:"shouldChangePassword,omitempty"`
}
func (c *Client) GetUsers() ([]User, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/admin/users", c.HostURL), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var users []User
err = json.Unmarshal(body, &users)
if err != nil {
return nil, err
}
return users, nil
}
func (c *Client) GetUser(userID string) (*User, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/admin/users/%s", c.HostURL, userID), nil)
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var user User
err = json.Unmarshal(body, &user)
if err != nil {
return nil, err
}
return &user, nil
}
func (c *Client) CreateUser(user UserAdminCreateRequest) (*User, error) {
rb, err := json.Marshal(user)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/admin/users", c.HostURL), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var newUser User
err = json.Unmarshal(body, &newUser)
if err != nil {
return nil, err
}
return &newUser, nil
}
func (c *Client) UpdateUser(userID string, user UserAdminUpdateRequest) (*User, error) {
rb, err := json.Marshal(user)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/admin/users/%s", c.HostURL, userID), bytes.NewBuffer(rb))
if err != nil {
return nil, err
}
body, err := c.doRequest(req)
if err != nil {
return nil, err
}
var updatedUser User
err = json.Unmarshal(body, &updatedUser)
if err != nil {
return nil, err
}
return &updatedUser, nil
}
func (c *Client) DeleteUser(userID string) error {
// UserAdminDeleteDto has force: boolean
// For simplicity, we'll force delete if needed, or just send empty object if it works.
// Actually, the DTO says optional.
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/admin/users/%s", c.HostURL, userID), bytes.NewBufferString("{}"))
if err != nil {
return err
}
_, err = c.doRequest(req)
return err
}