Files
kvs-sh/client.go
ryyst efaa5cdcc9 feat: add shell scripting with variables
Implemented roadmap #9: Shell scripts execution with variables.

Features:
- set <name> <value> - Set shell variable
- unset <name> - Remove variable
- vars - List all variables
- Variable substitution in all commands

Variable syntax:
- $VAR or ${VAR} - Shell variables
- $ENV:VARNAME - Environment variables

Variables expand before command execution, enabling:
- Dynamic key paths: put $BASE/$ID '{"data":"value"}'
- Reusable values: set TOKEN xyz && auth $TOKEN
- Script parameterization in batch files

Example batch script:
  set USER alice
  set KEY_PREFIX users
  put $KEY_PREFIX/$USER '{"name":"$USER"}'
  get $KEY_PREFIX/$USER

Variables are session-scoped and work in both interactive
and batch modes. Environment variables can be injected using
$ENV:HOME syntax.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 00:01:36 +03:00

64 lines
1.4 KiB
Go

package main
import (
"bytes"
"encoding/json"
"io"
"net/http"
"time"
)
// KVSClient maintains the connection state and configuration
type KVSClient struct {
baseURL string
currentToken string
currentUser string
httpClient *http.Client
profiles map[string]Profile
activeProfile string
variables map[string]string // Shell variables for scripting
}
// NewKVSClient creates a new KVS client instance
func NewKVSClient(baseURL string) *KVSClient {
return &KVSClient{
baseURL: baseURL,
httpClient: &http.Client{
Timeout: 30 * time.Second,
},
profiles: make(map[string]Profile),
variables: make(map[string]string),
}
}
// doRequest performs an HTTP request with JSON body and auth headers
func (c *KVSClient) doRequest(method, path string, body interface{}) ([]byte, int, error) {
var reqBody io.Reader
if body != nil {
jsonData, err := json.Marshal(body)
if err != nil {
return nil, 0, err
}
reqBody = bytes.NewBuffer(jsonData)
}
req, err := http.NewRequest(method, c.baseURL+path, reqBody)
if err != nil {
return nil, 0, err
}
req.Header.Set("Content-Type", "application/json")
if c.currentToken != "" {
req.Header.Set("Authorization", "Bearer "+c.currentToken)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, 0, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
return respBody, resp.StatusCode, err
}