- Auth commands: login, logout, status - Document commands: create, list, get, update, delete - Project commands: list, get - Folder commands: list, create - Tag commands: list, create, add - Search command - Reasoning save command - JSON output format with --output text option - Viper-based configuration management - Cobra CLI framework
146 lines
3.3 KiB
Go
146 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/claudia/docs-cli/pkg/types"
|
|
)
|
|
|
|
// FoldersClient handles folder API calls
|
|
type FoldersClient struct {
|
|
client *Client
|
|
}
|
|
|
|
// NewFoldersClient creates a new folders client
|
|
func NewFoldersClient(c *Client) *FoldersClient {
|
|
return &FoldersClient{client: c}
|
|
}
|
|
|
|
// List lists folders in a project
|
|
func (f *FoldersClient) List(projectID, parentID string) ([]types.Folder, error) {
|
|
path := "/projects/" + projectID + "/folders"
|
|
if parentID != "" {
|
|
path += "?parent_id=" + parentID
|
|
}
|
|
|
|
resp, err := f.client.doRequest(http.MethodGet, path, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read response: %w", err)
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, handleError(resp, body)
|
|
}
|
|
|
|
var folderResp types.Response
|
|
if err := decodeJSON(body, &folderResp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return sliceToFolders(folderResp.Data), nil
|
|
}
|
|
|
|
// Create creates a new folder
|
|
func (f *FoldersClient) Create(projectID string, req types.CreateFolderRequest) (*types.Folder, error) {
|
|
resp, err := f.client.doRequest(http.MethodPost, "/projects/"+projectID+"/folders", req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read response: %w", err)
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
|
|
return nil, handleError(resp, body)
|
|
}
|
|
|
|
var folderResp types.Response
|
|
if err := decodeJSON(body, &folderResp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
folder, ok := folderResp.Data.(map[string]interface{})
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected response format")
|
|
}
|
|
|
|
return mapToFolder(folder), nil
|
|
}
|
|
|
|
// Get gets a folder by ID
|
|
func (f *FoldersClient) Get(id string) (*types.Folder, error) {
|
|
resp, err := f.client.doRequest(http.MethodGet, "/folders/"+id, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read response: %w", err)
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, handleError(resp, body)
|
|
}
|
|
|
|
var folderResp types.Response
|
|
if err := decodeJSON(body, &folderResp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
folder, ok := folderResp.Data.(map[string]interface{})
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected response format")
|
|
}
|
|
|
|
return mapToFolder(folder), nil
|
|
}
|
|
|
|
func mapToFolder(m map[string]interface{}) *types.Folder {
|
|
folder := &types.Folder{}
|
|
if v, ok := m["id"].(string); ok {
|
|
folder.ID = v
|
|
}
|
|
if v, ok := m["name"].(string); ok {
|
|
folder.Name = v
|
|
}
|
|
if v, ok := m["project_id"].(string); ok {
|
|
folder.ProjectID = v
|
|
}
|
|
if v, ok := m["parent_id"].(string); ok {
|
|
folder.ParentID = v
|
|
}
|
|
if v, ok := m["created_at"].(string); ok {
|
|
folder.CreatedAt, _ = time.Parse(time.RFC3339, v)
|
|
}
|
|
if v, ok := m["updated_at"].(string); ok {
|
|
folder.UpdatedAt, _ = time.Parse(time.RFC3339, v)
|
|
}
|
|
return folder
|
|
}
|
|
|
|
func sliceToFolders(data interface{}) []types.Folder {
|
|
var folders []types.Folder
|
|
if arr, ok := data.([]interface{}); ok {
|
|
for _, item := range arr {
|
|
if m, ok := item.(map[string]interface{}); ok {
|
|
folders = append(folders, *mapToFolder(m))
|
|
}
|
|
}
|
|
}
|
|
return folders
|
|
}
|