- 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
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/claudia/docs-cli/pkg/types"
|
|
)
|
|
|
|
// SearchClient handles search API calls
|
|
type SearchClient struct {
|
|
client *Client
|
|
}
|
|
|
|
// NewSearchClient creates a new search client
|
|
func NewSearchClient(c *Client) *SearchClient {
|
|
return &SearchClient{client: c}
|
|
}
|
|
|
|
// Search performs a full-text search
|
|
func (s *SearchClient) Search(query, projectID, tags string) (*types.SearchResult, error) {
|
|
params := url.Values{}
|
|
params.Set("q", query)
|
|
if projectID != "" {
|
|
params.Set("project_id", projectID)
|
|
}
|
|
if tags != "" {
|
|
params.Set("tags", tags)
|
|
}
|
|
|
|
path := "/search?" + params.Encode()
|
|
resp, err := s.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 searchResp types.Response
|
|
if err := decodeJSON(body, &searchResp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapToSearchResult(searchResp.Data, query), nil
|
|
}
|
|
|
|
func mapToSearchResult(data interface{}, query string) *types.SearchResult {
|
|
result := &types.SearchResult{Query: query}
|
|
if m, ok := data.(map[string]interface{}); ok {
|
|
if v, ok := m["documents"].([]interface{}); ok {
|
|
for _, item := range v {
|
|
if doc, ok := item.(map[string]interface{}); ok {
|
|
result.Documents = append(result.Documents, *mapToDocument(doc))
|
|
}
|
|
}
|
|
}
|
|
if v, ok := m["total"].(float64); ok {
|
|
result.Total = int(v)
|
|
}
|
|
}
|
|
return result
|
|
}
|