Merge pull request #1525 from trheyi/main
feat(doc): add yao doc CLI commands and YAML documentation
This commit is contained in:
commit
9ff123433a
64 changed files with 5451 additions and 7 deletions
11
agent/caller/doc.go
Normal file
11
agent/caller/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package caller
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
13
agent/caller/doc.yml
Normal file
13
agent/caller/doc.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
group: agent
|
||||
type: process
|
||||
entries:
|
||||
- name: Call
|
||||
desc: Call an agent from contexts without agent.Context, enabling agent-to-agent communication
|
||||
args:
|
||||
- name: request
|
||||
type: object
|
||||
required: true
|
||||
desc: "Request object with fields: assistant_id (string, required), messages (array of message objects, required), model (string, connector override), skip (object, skip config), metadata (object, passed to hooks), locale (string), route (string), chat_id (string, auto-generated if empty), timeout (number, seconds, default 600)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Result object: { agent_id (string), response (object, full agent response), content (string, extracted text), error (string, error message if failed) }"
|
||||
11
agent/llm/doc.go
Normal file
11
agent/llm/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package llm
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
25
agent/llm/doc.yml
Normal file
25
agent/llm/doc.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
group: llm
|
||||
type: process
|
||||
entries:
|
||||
- name: ChatCompletions
|
||||
desc: Universal LLM chat completions that auto-detects connector type and routes accordingly
|
||||
args:
|
||||
- name: connector
|
||||
type: string
|
||||
required: true
|
||||
desc: Connector ID (supports any type, e.g. openai, anthropic)
|
||||
- name: messages
|
||||
type: array
|
||||
required: true
|
||||
desc: "Message array in OpenAI format: each element is an object with role, content (string or multimodal array), and optional name, tool_call_id, tool_calls"
|
||||
- name: opts
|
||||
type: object
|
||||
required: false
|
||||
desc: "Completion options: temperature, max_tokens, and other model parameters"
|
||||
- name: callback
|
||||
type: function
|
||||
required: false
|
||||
desc: "Streaming callback function that receives data chunks; signature: func(data []byte) int"
|
||||
return:
|
||||
type: object
|
||||
desc: "OpenAI-compatible response: { id, object, created, model, choices: [{ index, message: { role, content, tool_calls? }, finish_reason }], usage? }"
|
||||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/yaoapp/yao/test"
|
||||
)
|
||||
|
||||
// testConnectorID uses the cheapest model (Claude Haiku 3) to save tokens
|
||||
// testConnectorID uses the cheapest model (Claude Haiku 3.5) to save tokens
|
||||
const testConnectorID = "claude.haiku-3_0"
|
||||
|
||||
// TestAnthropicStreamBasic tests basic streaming completion with Anthropic API
|
||||
|
|
@ -214,7 +214,7 @@ func TestAnthropicStreamRetry(t *testing.T) {
|
|||
connDSL := `{
|
||||
"type": "anthropic",
|
||||
"options": {
|
||||
"model": "claude-3-haiku-20240307",
|
||||
"model": "claude-3-5-haiku-20241022",
|
||||
"key": "sk-ant-invalid-key-should-fail"
|
||||
}
|
||||
}`
|
||||
|
|
|
|||
11
agent/robot/doc.go
Normal file
11
agent/robot/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package robot
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
80
agent/robot/doc.yml
Normal file
80
agent/robot/doc.yml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
group: robot
|
||||
type: process
|
||||
entries:
|
||||
- name: get
|
||||
desc: Get a robot's details by member ID
|
||||
args:
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: The member ID of the robot to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Robot detail object
|
||||
|
||||
- name: list
|
||||
desc: List all robots with optional filtering and pagination
|
||||
args:
|
||||
- name: filter
|
||||
type: object
|
||||
required: false
|
||||
desc: "Filter options: page (number), pagesize (number), status (string), search (string, keywords), team_id (string)"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated list of robots
|
||||
|
||||
- name: status
|
||||
desc: Get the current status of a robot by member ID
|
||||
args:
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: The member ID of the robot
|
||||
return:
|
||||
type: object
|
||||
desc: Robot status object
|
||||
|
||||
- name: executions
|
||||
desc: List executions for a robot with optional filtering and pagination
|
||||
args:
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: The member ID of the robot
|
||||
- name: filter
|
||||
type: object
|
||||
required: false
|
||||
desc: "Filter options: page (number), pagesize (number), status (string, execution status), trigger (string, trigger type)"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated list of execution records
|
||||
|
||||
- name: execution
|
||||
desc: Get a specific execution record by member ID and execution ID
|
||||
args:
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: The member ID of the robot (reserved for permission scoping)
|
||||
- name: executionID
|
||||
type: string
|
||||
required: true
|
||||
desc: The execution ID to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Execution status and details
|
||||
|
||||
- name: updateChatTitle
|
||||
desc: Update the title of a chat session
|
||||
args:
|
||||
- name: chatID
|
||||
type: string
|
||||
required: true
|
||||
desc: The chat session ID to update
|
||||
- name: title
|
||||
type: string
|
||||
required: true
|
||||
desc: The new title for the chat session
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
11
attachment/doc.go
Normal file
11
attachment/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package attachment
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
177
attachment/doc.yml
Normal file
177
attachment/doc.yml
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
group: attachment
|
||||
type: process
|
||||
desc: "File attachment management processes for uploading, reading, listing, and managing files"
|
||||
entries:
|
||||
- name: Save
|
||||
desc: Save a file from base64 data URI or plain base64 string
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID (e.g. \"default\", \"__yao.attachment\")"
|
||||
- name: content
|
||||
type: string
|
||||
required: true
|
||||
desc: "Base64 data URI (e.g. \"data:image/png;base64,xxxx\") or plain base64 string"
|
||||
- name: filename
|
||||
type: string
|
||||
required: false
|
||||
desc: "Original filename; auto-generated from content type if omitted"
|
||||
- name: option
|
||||
type: object
|
||||
required: false
|
||||
desc: "Upload options: groups (array), gzip (bool), compress_image (bool), compress_size (number), public (bool), share (string: \"private\" or \"team\")"
|
||||
return:
|
||||
type: object
|
||||
desc: "File object with file_id, path, bytes, created_at, filename, content_type, and status fields"
|
||||
|
||||
- name: Read
|
||||
desc: Read file content as a base64 data URI
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to read"
|
||||
return:
|
||||
type: string
|
||||
desc: "Base64 data URI string (e.g. \"data:image/png;base64,xxxx\")"
|
||||
|
||||
- name: Info
|
||||
desc: Get file metadata information
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to query"
|
||||
return:
|
||||
type: object
|
||||
desc: "File object with file_id, path, bytes, created_at, filename, content_type, and status fields"
|
||||
|
||||
- name: List
|
||||
desc: List files with pagination and filtering
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: option
|
||||
type: object
|
||||
required: false
|
||||
desc: "List options: page (number), page_size (number, max 100), filters (object), order_by (string), select (array of field names)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Paginated result with files (array), total (number), page (number), page_size (number), and total_pages (number)"
|
||||
|
||||
- name: Delete
|
||||
desc: Delete a file by ID
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to delete"
|
||||
return:
|
||||
type: bool
|
||||
desc: "True on success"
|
||||
|
||||
- name: Exists
|
||||
desc: Check if a file exists
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to check"
|
||||
return:
|
||||
type: bool
|
||||
desc: "True if the file exists"
|
||||
|
||||
- name: URL
|
||||
desc: Get the URL for a file
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID"
|
||||
return:
|
||||
type: string
|
||||
desc: "File URL string"
|
||||
|
||||
- name: SaveText
|
||||
desc: Save parsed text content for a file
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to save text for"
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: "Text content to save"
|
||||
return:
|
||||
type: bool
|
||||
desc: "True on success"
|
||||
|
||||
- name: GetText
|
||||
desc: Get parsed text content for a file
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID"
|
||||
- name: fileID
|
||||
type: string
|
||||
required: true
|
||||
desc: "File ID to get text for"
|
||||
- name: fullContent
|
||||
type: bool
|
||||
required: false
|
||||
desc: "If true, return full content; if false (default), return preview (first 2000 chars)"
|
||||
return:
|
||||
type: string
|
||||
desc: "Text content string"
|
||||
|
||||
- name: Zip
|
||||
desc: Package multiple attachment files into a zip archive and upload it
|
||||
args:
|
||||
- name: uploaderID
|
||||
type: string
|
||||
required: true
|
||||
desc: "Uploader/manager ID (e.g. \"__yao.attachment\")"
|
||||
- name: fileIDs
|
||||
type: array
|
||||
required: true
|
||||
desc: "Array of file ID strings to include in the zip"
|
||||
- name: zipFilename
|
||||
type: string
|
||||
required: true
|
||||
desc: "Output zip filename (e.g. \"archive.zip\"); .zip extension added automatically if missing"
|
||||
- name: option
|
||||
type: object
|
||||
required: false
|
||||
desc: "Upload options for the zip file: groups (array), gzip (bool), public (bool), share (string)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Uploaded zip file object with file_id, filename, bytes, and other file metadata"
|
||||
74
cmd/doc/doc.go
Normal file
74
cmd/doc/doc.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package doc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
var jsonOutput bool
|
||||
|
||||
func printJSON(v any) {
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
enc.Encode(v)
|
||||
}
|
||||
|
||||
func formatArgs(args []doc.TypeValue) string {
|
||||
if len(args) == 0 {
|
||||
return "()"
|
||||
}
|
||||
parts := make([]string, 0, len(args))
|
||||
for _, a := range args {
|
||||
s := a.Name + " " + a.Type
|
||||
if !a.Required {
|
||||
s += "?"
|
||||
}
|
||||
parts = append(parts, s)
|
||||
}
|
||||
return "(" + strings.Join(parts, ", ") + ")"
|
||||
}
|
||||
|
||||
func formatReturn(ret *doc.TypeValue) string {
|
||||
if ret == nil {
|
||||
return "void"
|
||||
}
|
||||
return ret.Type
|
||||
}
|
||||
|
||||
func init() {
|
||||
ProcessCmd.AddCommand(processListCmd)
|
||||
ProcessCmd.AddCommand(processValidateCmd)
|
||||
ProcessCmd.AddCommand(processInspectCmd)
|
||||
RuntimeCmd.AddCommand(runtimeListCmd)
|
||||
RuntimeCmd.AddCommand(runtimeValidateCmd)
|
||||
RuntimeCmd.AddCommand(runtimeInspectCmd)
|
||||
|
||||
processListCmd.Flags().StringVarP(&groupFlag, "group", "g", "", "Filter by group")
|
||||
processListCmd.Flags().StringVarP(&searchFlag, "search", "s", "", "Search keyword")
|
||||
processListCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
processListCmd.Flags().BoolVar(&showAll, "all", false, "Include undocumented processes")
|
||||
|
||||
processValidateCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
processInspectCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
|
||||
runtimeListCmd.Flags().StringVarP(&typeFlag, "type", "t", "", "Filter by type: object, function, class")
|
||||
runtimeListCmd.Flags().StringVarP(&searchFlag, "search", "s", "", "Search keyword")
|
||||
runtimeListCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
|
||||
runtimeValidateCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
runtimeInspectCmd.Flags().BoolVar(&jsonOutput, "json", false, "Output as JSON")
|
||||
}
|
||||
|
||||
var groupFlag string
|
||||
var searchFlag string
|
||||
var typeFlag string
|
||||
var showAll bool
|
||||
|
||||
func errExit(format string, a ...any) {
|
||||
fmt.Fprintf(os.Stderr, format+"\n", a...)
|
||||
os.Exit(1)
|
||||
}
|
||||
345
cmd/doc/doc_test.go
Normal file
345
cmd/doc/doc_test.go
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
package doc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
const sampleProcessYAML = `
|
||||
group: test
|
||||
type: process
|
||||
entries:
|
||||
- name: test.hello
|
||||
desc: Greet someone
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: string
|
||||
- name: test.add
|
||||
desc: Add two numbers
|
||||
args:
|
||||
- name: a
|
||||
type: number
|
||||
required: true
|
||||
- name: b
|
||||
type: number
|
||||
required: true
|
||||
return:
|
||||
type: number
|
||||
`
|
||||
|
||||
const sampleShortNameYAML = `
|
||||
group: http
|
||||
type: process
|
||||
entries:
|
||||
- name: get
|
||||
desc: Send HTTP GET
|
||||
args:
|
||||
- name: url
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: object
|
||||
- name: post
|
||||
desc: Send HTTP POST
|
||||
args:
|
||||
- name: url
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: object
|
||||
`
|
||||
|
||||
const sampleSubGroupYAML = `
|
||||
group: utils
|
||||
type: process
|
||||
entries:
|
||||
- name: throw.Forbidden
|
||||
desc: Throw 403
|
||||
return:
|
||||
type: void
|
||||
`
|
||||
|
||||
const sampleRuntimeYAML = `
|
||||
group: objects
|
||||
type: js_object
|
||||
entries:
|
||||
- name: log
|
||||
desc: Logging utility
|
||||
methods:
|
||||
- name: Info
|
||||
desc: Log info
|
||||
args:
|
||||
- name: msg
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: void
|
||||
`
|
||||
|
||||
const sampleClassYAML = `
|
||||
group: objects
|
||||
type: js_class
|
||||
entries:
|
||||
- name: FS
|
||||
desc: File system operations
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
methods:
|
||||
- name: ReadFile
|
||||
desc: Read file
|
||||
args:
|
||||
- name: path
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: string
|
||||
`
|
||||
|
||||
const sampleFunctionYAML = `
|
||||
group: functions
|
||||
type: js_function
|
||||
entries:
|
||||
- name: Process
|
||||
desc: Execute a Yao process
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
return:
|
||||
type: any
|
||||
`
|
||||
|
||||
func setupTestData(t *testing.T) {
|
||||
t.Helper()
|
||||
doc.Reset()
|
||||
for _, yaml := range []string{
|
||||
sampleProcessYAML, sampleShortNameYAML, sampleSubGroupYAML,
|
||||
sampleRuntimeYAML, sampleClassYAML, sampleFunctionYAML,
|
||||
} {
|
||||
if err := doc.LoadYAML([]byte(yaml)); err != nil {
|
||||
t.Fatalf("LoadYAML failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalisedNames(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
// "test.hello" already has prefix → stays "test.hello"
|
||||
e, ok := doc.Get(doc.TypeProcess, "test.hello")
|
||||
if !ok {
|
||||
t.Fatal("test.hello not found")
|
||||
}
|
||||
if e.Name != "test.hello" {
|
||||
t.Errorf("name = %q, want test.hello", e.Name)
|
||||
}
|
||||
|
||||
// short name "get" with group "http" → normalised to "http.get"
|
||||
e, ok = doc.Get(doc.TypeProcess, "http.get")
|
||||
if !ok {
|
||||
t.Fatal("http.get not found — short name was not normalised")
|
||||
}
|
||||
if e.Name != "http.get" {
|
||||
t.Errorf("name = %q, want http.get", e.Name)
|
||||
}
|
||||
|
||||
// sub-group name "throw.Forbidden" with group "utils" → "utils.throw.Forbidden"
|
||||
e, ok = doc.Get(doc.TypeProcess, "utils.throw.Forbidden")
|
||||
if !ok {
|
||||
t.Fatal("utils.throw.Forbidden not found")
|
||||
}
|
||||
if e.Name != "utils.throw.Forbidden" {
|
||||
t.Errorf("name = %q, want utils.throw.Forbidden", e.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessListCommand(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
entries := doc.List(doc.TypeProcess)
|
||||
if len(entries) != 5 {
|
||||
t.Errorf("expected 5 process entries, got %d", len(entries))
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessListWithGroupFilter(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
entries := doc.List(doc.TypeProcess, doc.ListOption{Group: "http"})
|
||||
if len(entries) != 2 {
|
||||
t.Errorf("expected 2 http entries, got %d", len(entries))
|
||||
}
|
||||
|
||||
entries = doc.List(doc.TypeProcess, doc.ListOption{Group: "nonexistent"})
|
||||
if len(entries) != 0 {
|
||||
t.Errorf("expected 0, got %d", len(entries))
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessListWithSearch(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
entries := doc.List(doc.TypeProcess, doc.ListOption{Search: "hello"})
|
||||
if len(entries) != 1 {
|
||||
t.Fatalf("expected 1, got %d", len(entries))
|
||||
}
|
||||
if entries[0].Name != "test.hello" {
|
||||
t.Errorf("expected test.hello, got %s", entries[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessGet_FullName(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
e, ok := doc.Get(doc.TypeProcess, "http.post")
|
||||
if !ok {
|
||||
t.Fatal("http.post not found")
|
||||
}
|
||||
if e.Desc != "Send HTTP POST" {
|
||||
t.Errorf("desc = %q", e.Desc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidate_OK(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeProcess, "test.hello")
|
||||
if !r.Valid {
|
||||
t.Fatal("expected valid")
|
||||
}
|
||||
if r.Status != "ok" {
|
||||
t.Errorf("status = %q", r.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidate_FullName(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeProcess, "http.get")
|
||||
if !r.Valid {
|
||||
t.Fatal("expected valid for http.get")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidate_NotFound(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeProcess, "does.not.exist")
|
||||
if r.Valid {
|
||||
t.Fatal("expected not valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidate_Suggestions(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeProcess, "test.hell")
|
||||
if r.Valid {
|
||||
t.Fatal("expected not valid")
|
||||
}
|
||||
found := false
|
||||
for _, s := range r.Suggestion {
|
||||
if s == "test.hello" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("expected test.hello in suggestions: %v", r.Suggestion)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeList(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
objects := doc.List(doc.TypeJSObject)
|
||||
if len(objects) != 1 {
|
||||
t.Errorf("expected 1 object, got %d", len(objects))
|
||||
}
|
||||
|
||||
classes := doc.List(doc.TypeJSClass)
|
||||
if len(classes) != 1 {
|
||||
t.Errorf("expected 1 class, got %d", len(classes))
|
||||
}
|
||||
|
||||
functions := doc.List(doc.TypeJSFunction)
|
||||
if len(functions) != 1 {
|
||||
t.Errorf("expected 1 function, got %d", len(functions))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeValidate_Object(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeJSObject, "log")
|
||||
if !r.Valid {
|
||||
t.Fatal("expected valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeValidate_Class(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeJSClass, "FS")
|
||||
if !r.Valid {
|
||||
t.Fatal("expected valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeValidate_Function(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
r := doc.Validate(doc.TypeJSFunction, "Process")
|
||||
if !r.Valid {
|
||||
t.Fatal("expected valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindRuntime(t *testing.T) {
|
||||
setupTestData(t)
|
||||
|
||||
e := findRuntime("log")
|
||||
if e == nil {
|
||||
t.Fatal("expected to find log")
|
||||
}
|
||||
|
||||
e = findRuntime("FS")
|
||||
if e == nil {
|
||||
t.Fatal("expected to find FS")
|
||||
}
|
||||
|
||||
e = findRuntime("nonexistent")
|
||||
if e != nil {
|
||||
t.Fatal("expected nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatArgs(t *testing.T) {
|
||||
args := []doc.TypeValue{
|
||||
{Name: "name", Type: "string", Required: true},
|
||||
{Name: "options", Type: "object"},
|
||||
}
|
||||
s := formatArgs(args)
|
||||
if s != "(name string, options object?)" {
|
||||
t.Errorf("formatArgs = %q", s)
|
||||
}
|
||||
|
||||
s = formatArgs(nil)
|
||||
if s != "()" {
|
||||
t.Errorf("formatArgs nil = %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatReturn(t *testing.T) {
|
||||
if formatReturn(nil) != "void" {
|
||||
t.Error("nil should return void")
|
||||
}
|
||||
tv := &doc.TypeValue{Type: "string"}
|
||||
if formatReturn(tv) != "string" {
|
||||
t.Error("string type mismatch")
|
||||
}
|
||||
}
|
||||
298
cmd/doc/process.go
Normal file
298
cmd/doc/process.go
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
package doc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/gou/model"
|
||||
"github.com/yaoapp/gou/process"
|
||||
"github.com/yaoapp/gou/schedule"
|
||||
"github.com/yaoapp/gou/store"
|
||||
"github.com/yaoapp/gou/task"
|
||||
)
|
||||
|
||||
// ProcessCmd is the parent command for process documentation.
|
||||
var ProcessCmd = &cobra.Command{
|
||||
Use: "process",
|
||||
Short: "Process documentation",
|
||||
Long: "List, inspect and validate Yao process documentation",
|
||||
Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
|
||||
}
|
||||
|
||||
var processListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List documented processes",
|
||||
Long: `List all documented processes in flat format (one per line).
|
||||
Designed for grep/pipe usage:
|
||||
yao doc process list | grep model
|
||||
yao doc process list --group http`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
opts := doc.ListOption{Group: groupFlag, Search: searchFlag}
|
||||
entries := doc.List(doc.TypeProcess, opts)
|
||||
|
||||
if jsonOutput {
|
||||
printJSON(entries)
|
||||
return
|
||||
}
|
||||
|
||||
for _, e := range entries {
|
||||
fmt.Printf("%-45s %s\n", doc.CallableName(e), e.Desc)
|
||||
}
|
||||
|
||||
if showAll {
|
||||
undoc := doc.AutoDiscover()
|
||||
if len(undoc) > 0 {
|
||||
fmt.Printf("\nUNDOCUMENTED: %d processes\n", len(undoc))
|
||||
for _, name := range undoc {
|
||||
fmt.Printf("%-45s (no documentation)\n", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var processInspectCmd = &cobra.Command{
|
||||
Use: "inspect [process-name]",
|
||||
Short: "Show detailed info for a process",
|
||||
Long: `Show full documentation for a single process, including arguments,
|
||||
return type, field descriptions, and examples.
|
||||
yao doc process inspect http.get
|
||||
yao doc process inspect models.user.Find`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
name := args[0]
|
||||
e, ok := doc.Get(doc.TypeProcess, name)
|
||||
if !ok {
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "Process %q not found.\n", name)
|
||||
result := doc.Validate(doc.TypeProcess, name)
|
||||
if len(result.Suggestion) > 0 {
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "Did you mean:")
|
||||
for _, s := range result.Suggestion {
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), " - %s\n", s)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if jsonOutput {
|
||||
printJSON(e)
|
||||
return
|
||||
}
|
||||
|
||||
printProcessDetail(e)
|
||||
},
|
||||
}
|
||||
|
||||
var processValidateCmd = &cobra.Command{
|
||||
Use: "validate [process-name]",
|
||||
Short: "Validate a process name",
|
||||
Long: `Validate a process call using the engine's addressing logic,
|
||||
check that the referenced resource exists, and show documentation.
|
||||
|
||||
Examples:
|
||||
yao doc process validate models.user.Find
|
||||
yao doc process validate http.get
|
||||
yao doc process validate stores.cache.set`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
name := args[0]
|
||||
|
||||
p, err := process.Of(name)
|
||||
if err != nil {
|
||||
printError(cmd, name, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if process.Handlers[p.Handler] == nil {
|
||||
printError(cmd, name, fmt.Sprintf("handler %q not registered", p.Handler))
|
||||
return
|
||||
}
|
||||
|
||||
if reason := checkID(p); reason != "" {
|
||||
printError(cmd, name, reason)
|
||||
return
|
||||
}
|
||||
|
||||
docResult := doc.Validate(doc.TypeProcess, name)
|
||||
|
||||
if jsonOutput {
|
||||
out := map[string]interface{}{
|
||||
"name": name,
|
||||
"valid": true,
|
||||
"handler": p.Handler,
|
||||
"group": p.Group,
|
||||
"id": p.ID,
|
||||
"method": p.Method,
|
||||
"documented": docResult.Valid,
|
||||
}
|
||||
if docResult.Entry != nil {
|
||||
out["entry"] = docResult.Entry
|
||||
}
|
||||
printJSON(out)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("✓ %s — valid\n", name)
|
||||
fmt.Printf(" Handler: %s\n", p.Handler)
|
||||
fmt.Printf(" Group: %s\n", p.Group)
|
||||
if p.ID != "" {
|
||||
fmt.Printf(" ID: %s\n", p.ID)
|
||||
}
|
||||
fmt.Printf(" Method: %s\n", p.Method)
|
||||
fmt.Println()
|
||||
|
||||
if docResult.Valid && docResult.Entry != nil {
|
||||
printProcessDetail(docResult.Entry)
|
||||
} else {
|
||||
fmt.Printf("⚠ no documentation found for %s\n", name)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// checkID validates the <id> segment for dynamic-ID groups by looking up the
|
||||
// actual runtime registry. Returns an error message or "" if OK.
|
||||
func checkID(p *process.Process) string {
|
||||
switch p.Group {
|
||||
case "models":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: models.<id>.%s", p.Method)
|
||||
}
|
||||
if !model.Exists(p.ID) {
|
||||
return fmt.Sprintf("model %q not loaded", p.ID)
|
||||
}
|
||||
|
||||
case "schemas":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: schemas.<id>.%s", p.Method)
|
||||
}
|
||||
|
||||
case "stores":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: stores.<id>.%s", p.Method)
|
||||
}
|
||||
if _, has := store.Pools[p.ID]; !has {
|
||||
return fmt.Sprintf("store %q not loaded", p.ID)
|
||||
}
|
||||
|
||||
case "fs":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: fs.<id>.%s", p.Method)
|
||||
}
|
||||
if _, has := fs.FileSystems[p.ID]; !has {
|
||||
return fmt.Sprintf("filesystem %q not registered", p.ID)
|
||||
}
|
||||
|
||||
case "tasks":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: tasks.<id>.%s", p.Method)
|
||||
}
|
||||
if _, has := task.Tasks[p.ID]; !has {
|
||||
return fmt.Sprintf("task %q not loaded", p.ID)
|
||||
}
|
||||
|
||||
case "schedules":
|
||||
if p.ID == "" {
|
||||
return fmt.Sprintf("missing <id>, correct format: schedules.<id>.%s", p.Method)
|
||||
}
|
||||
if _, has := schedule.Schedules[p.ID]; !has {
|
||||
return fmt.Sprintf("schedule %q not loaded", p.ID)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func printError(cmd *cobra.Command, name, msg string) {
|
||||
if jsonOutput {
|
||||
printJSON(map[string]interface{}{
|
||||
"name": name,
|
||||
"valid": false,
|
||||
"error": msg,
|
||||
})
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "✗ %s — %s\n", name, msg)
|
||||
}
|
||||
|
||||
func printProcessDetail(e *doc.Entry) {
|
||||
fmt.Printf("Process: %s\n", doc.CallableName(e))
|
||||
fmt.Printf("Group: %s\n", e.Group)
|
||||
fmt.Printf("Desc: %s\n", e.Desc)
|
||||
fmt.Println()
|
||||
|
||||
if len(e.Args) > 0 {
|
||||
fmt.Println("Arguments:")
|
||||
for i, a := range e.Args {
|
||||
req := "required"
|
||||
if !a.Required {
|
||||
req = "optional"
|
||||
}
|
||||
fmt.Printf(" [%d] %s (%s, %s)\n", i, a.Name, a.Type, req)
|
||||
if a.Desc != "" {
|
||||
fmt.Printf(" %s\n", a.Desc)
|
||||
}
|
||||
if a.Example != nil {
|
||||
fmt.Printf(" Example: %v\n", a.Example)
|
||||
}
|
||||
printTypeFields(a.Fields, 6)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
fmt.Println("Returns:")
|
||||
if e.Return == nil {
|
||||
fmt.Println(" void")
|
||||
} else {
|
||||
printTypeValue(e.Return, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func printTypeValue(tv *doc.TypeValue, indent int) {
|
||||
pad := strings.Repeat(" ", indent)
|
||||
fmt.Printf("%s%s", pad, tv.Type)
|
||||
if tv.Desc != "" {
|
||||
fmt.Printf(" — %s", tv.Desc)
|
||||
}
|
||||
fmt.Println()
|
||||
if tv.Example != nil {
|
||||
fmt.Printf("%sExample: %v\n", pad, tv.Example)
|
||||
}
|
||||
|
||||
if len(tv.Fields) > 0 {
|
||||
printTypeFields(tv.Fields, indent)
|
||||
}
|
||||
if tv.Items != nil {
|
||||
fmt.Printf("%sItems:\n", pad)
|
||||
printTypeValue(tv.Items, indent+2)
|
||||
}
|
||||
if len(tv.Variants) > 0 {
|
||||
for i, v := range tv.Variants {
|
||||
fmt.Printf("%sVariant %d: ", pad, i+1)
|
||||
desc := v.Type
|
||||
if v.Desc != "" {
|
||||
desc += " — " + v.Desc
|
||||
}
|
||||
fmt.Println(desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printTypeFields(fields []doc.TypeValue, indent int) {
|
||||
if len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
pad := strings.Repeat(" ", indent)
|
||||
fmt.Printf("%sFields:\n", pad)
|
||||
for _, f := range fields {
|
||||
req := ""
|
||||
if f.Required {
|
||||
req = ", required"
|
||||
}
|
||||
fmt.Printf("%s .%-20s %s%s\n", pad, f.Name, f.Type, req)
|
||||
if f.Desc != "" {
|
||||
fmt.Printf("%s %s\n", pad, f.Desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
182
cmd/doc/runtime.go
Normal file
182
cmd/doc/runtime.go
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
package doc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
// RuntimeCmd is the parent command for runtime API documentation.
|
||||
var RuntimeCmd = &cobra.Command{
|
||||
Use: "runtime",
|
||||
Short: "JS runtime API documentation",
|
||||
Long: "List, inspect and validate JS runtime global objects, functions, and classes",
|
||||
Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
|
||||
}
|
||||
|
||||
var runtimeListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List JS runtime APIs",
|
||||
Long: `List all documented JS global objects, functions, and classes.
|
||||
Designed for grep/pipe usage:
|
||||
yao doc runtime list | grep FS
|
||||
yao doc runtime list --type class`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
types := runtimeTypes()
|
||||
var allEntries []*doc.Entry
|
||||
for _, t := range types {
|
||||
opts := doc.ListOption{Search: searchFlag}
|
||||
allEntries = append(allEntries, doc.List(t, opts)...)
|
||||
}
|
||||
|
||||
if jsonOutput {
|
||||
printJSON(allEntries)
|
||||
return
|
||||
}
|
||||
|
||||
for _, e := range allEntries {
|
||||
tag := string(e.Type)
|
||||
extra := ""
|
||||
if len(e.Methods) > 0 {
|
||||
extra = fmt.Sprintf(" (%d methods)", len(e.Methods))
|
||||
}
|
||||
fmt.Printf("%-20s [%-11s] %s%s\n", e.Name, tag, e.Desc, extra)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var runtimeInspectCmd = &cobra.Command{
|
||||
Use: "inspect [name]",
|
||||
Short: "Show detailed info for a JS runtime API",
|
||||
Long: `Show full documentation for a JS global object, function, or class.
|
||||
yao doc runtime inspect FS
|
||||
yao doc runtime inspect log
|
||||
yao doc runtime inspect Process`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
name := args[0]
|
||||
entry := findRuntime(name)
|
||||
if entry == nil {
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "Runtime API %q not found.\n", name)
|
||||
for _, t := range []doc.EntryType{doc.TypeJSObject, doc.TypeJSClass, doc.TypeJSFunction} {
|
||||
r := doc.Validate(t, name)
|
||||
if len(r.Suggestion) > 0 {
|
||||
fmt.Fprintln(cmd.ErrOrStderr(), "Did you mean:")
|
||||
for _, s := range r.Suggestion {
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), " - %s\n", s)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if jsonOutput {
|
||||
printJSON(entry)
|
||||
return
|
||||
}
|
||||
|
||||
printRuntimeDetail(entry)
|
||||
},
|
||||
}
|
||||
|
||||
var runtimeValidateCmd = &cobra.Command{
|
||||
Use: "validate [name]",
|
||||
Short: "Validate a JS runtime API name",
|
||||
Long: "Check if a JS global name is documented (e.g. FS, log, Process)",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
name := args[0]
|
||||
var result *doc.ValidationResult
|
||||
for _, t := range []doc.EntryType{doc.TypeJSObject, doc.TypeJSClass, doc.TypeJSFunction} {
|
||||
r := doc.Validate(t, name)
|
||||
if r.Valid {
|
||||
result = r
|
||||
break
|
||||
}
|
||||
if result == nil || len(r.Suggestion) > len(result.Suggestion) {
|
||||
result = r
|
||||
}
|
||||
}
|
||||
|
||||
if jsonOutput {
|
||||
printJSON(result)
|
||||
return
|
||||
}
|
||||
|
||||
if result.Valid {
|
||||
fmt.Printf("✓ %s — %s (type: %s)\n", result.Name, result.Message, result.Entry.Type)
|
||||
} else {
|
||||
fmt.Printf("✗ %s — %s (status: %s)\n", result.Name, result.Message, result.Status)
|
||||
if len(result.Suggestion) > 0 {
|
||||
fmt.Println(" Did you mean:")
|
||||
for _, s := range result.Suggestion {
|
||||
fmt.Printf(" - %s\n", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func findRuntime(name string) *doc.Entry {
|
||||
for _, t := range []doc.EntryType{doc.TypeJSObject, doc.TypeJSClass, doc.TypeJSFunction} {
|
||||
e, ok := doc.Get(t, name)
|
||||
if ok {
|
||||
return e
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printRuntimeDetail(e *doc.Entry) {
|
||||
fmt.Printf("Name: %s\n", e.Name)
|
||||
fmt.Printf("Type: %s\n", e.Type)
|
||||
fmt.Printf("Desc: %s\n", e.Desc)
|
||||
|
||||
if len(e.Args) > 0 {
|
||||
fmt.Println()
|
||||
fmt.Println("Constructor Arguments:")
|
||||
for i, a := range e.Args {
|
||||
req := "required"
|
||||
if !a.Required {
|
||||
req = "optional"
|
||||
}
|
||||
fmt.Printf(" [%d] %s (%s, %s)\n", i, a.Name, a.Type, req)
|
||||
if a.Desc != "" {
|
||||
fmt.Printf(" %s\n", a.Desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if e.Return != nil {
|
||||
fmt.Println()
|
||||
fmt.Println("Returns:")
|
||||
printTypeValue(e.Return, 2)
|
||||
}
|
||||
|
||||
if len(e.Methods) > 0 {
|
||||
fmt.Println()
|
||||
fmt.Printf("Methods (%d):\n", len(e.Methods))
|
||||
for _, m := range e.Methods {
|
||||
ret := formatReturn(m.Return)
|
||||
fmt.Printf(" .%-25s %s → %s\n", m.Name+formatArgs(m.Args), m.Desc, ret)
|
||||
if m.Return != nil && len(m.Return.Fields) > 0 {
|
||||
printTypeFields(m.Return.Fields, 4)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runtimeTypes() []doc.EntryType {
|
||||
switch typeFlag {
|
||||
case "object":
|
||||
return []doc.EntryType{doc.TypeJSObject}
|
||||
case "function":
|
||||
return []doc.EntryType{doc.TypeJSFunction}
|
||||
case "class":
|
||||
return []doc.EntryType{doc.TypeJSClass}
|
||||
default:
|
||||
return []doc.EntryType{doc.TypeJSObject, doc.TypeJSClass, doc.TypeJSFunction}
|
||||
}
|
||||
}
|
||||
18
cmd/root.go
18
cmd/root.go
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/cmd/agent"
|
||||
yaodoc "github.com/yaoapp/yao/cmd/doc"
|
||||
"github.com/yaoapp/yao/cmd/mcp"
|
||||
"github.com/yaoapp/yao/cmd/robot"
|
||||
"github.com/yaoapp/yao/cmd/sui"
|
||||
|
|
@ -167,6 +168,18 @@ var robotCmd = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
var docCmd = &cobra.Command{
|
||||
Use: "doc",
|
||||
Short: "Documentation and API reference",
|
||||
Long: "Browse and validate documentation for processes, JS runtime APIs, and more",
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
DisableDefaultCmd: true,
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
// Command initialize
|
||||
func init() {
|
||||
|
||||
|
|
@ -192,6 +205,10 @@ func init() {
|
|||
// Robot
|
||||
robotCmd.AddCommand(robot.AddCmd)
|
||||
|
||||
// Doc
|
||||
docCmd.AddCommand(yaodoc.ProcessCmd)
|
||||
docCmd.AddCommand(yaodoc.RuntimeCmd)
|
||||
|
||||
rootCmd.AddCommand(
|
||||
versionCmd,
|
||||
migrateCmd,
|
||||
|
|
@ -210,6 +227,7 @@ func init() {
|
|||
agentCmd,
|
||||
mcpCmd,
|
||||
robotCmd,
|
||||
docCmd,
|
||||
upgradeCmd,
|
||||
)
|
||||
// rootCmd.SetHelpCommand(helpCmd)
|
||||
|
|
|
|||
11
crypto/doc.go
Normal file
11
crypto/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
171
crypto/doc.yml
Normal file
171
crypto/doc.yml
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
group: crypto
|
||||
type: process
|
||||
entries:
|
||||
- name: Hash
|
||||
desc: Compute a cryptographic hash of a string value
|
||||
args:
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "Hash algorithm: MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, MD5SHA1, RIPEMD160, SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHA512_224, SHA512_256, BLAKE2s_256, BLAKE2b_256, BLAKE2b_384, BLAKE2b_512"
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: String value to hash
|
||||
return:
|
||||
type: string
|
||||
desc: Hex-encoded hash string
|
||||
|
||||
- name: Hmac
|
||||
desc: Compute a Keyed-Hash Message Authentication Code (HMAC)
|
||||
args:
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "Hash algorithm: MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, etc."
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: String value to hash
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Secret key for HMAC
|
||||
- name: encoding
|
||||
type: string
|
||||
required: false
|
||||
desc: "Output encoding: \"base64\" for base64 output (default: hex)"
|
||||
return:
|
||||
type: string
|
||||
desc: HMAC hash string (hex or base64 encoded)
|
||||
|
||||
- name: hmacwith
|
||||
desc: Compute HMAC with advanced encoding options for key, value, and output
|
||||
args:
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Encoding options: {key: \"base64\"|\"hex\", value: \"base64\"|\"hex\", output: \"base64\"|\"hex\", algo: \"SHA256\"}"
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: Value to hash (encoding specified in option)
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Secret key (encoding specified in option)
|
||||
return:
|
||||
type: string
|
||||
desc: HMAC hash string with specified output encoding
|
||||
|
||||
- name: rsa2sign
|
||||
desc: Create an RSA-SHA2 digital signature
|
||||
args:
|
||||
- name: privateKey
|
||||
type: string
|
||||
required: true
|
||||
desc: RSA private key in PEM format
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "Hash algorithm: SHA256, SHA384, SHA512, etc."
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: Data to sign
|
||||
- name: encoding
|
||||
type: string
|
||||
required: false
|
||||
desc: "Output encoding: \"base64\" for base64 output (default: hex)"
|
||||
return:
|
||||
type: string
|
||||
desc: Digital signature string (hex or base64 encoded)
|
||||
|
||||
- name: rsa2verify
|
||||
desc: Verify an RSA-SHA2 digital signature
|
||||
args:
|
||||
- name: publicKey
|
||||
type: string
|
||||
required: true
|
||||
desc: RSA public key in PEM format
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "Hash algorithm: SHA256, SHA384, SHA512, etc."
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: Original data that was signed
|
||||
- name: signature
|
||||
type: string
|
||||
required: true
|
||||
desc: Signature to verify (hex or base64 encoded)
|
||||
- name: encoding
|
||||
type: string
|
||||
required: false
|
||||
desc: "Signature encoding: \"base64\" if signature is base64-encoded (default: hex)"
|
||||
return:
|
||||
type: bool
|
||||
desc: True if signature is valid
|
||||
|
||||
- name: aes256encrypt
|
||||
desc: Encrypt data using AES-256 algorithm
|
||||
args:
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "AES mode: \"GCM\""
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: AES-256 encryption key (32 bytes)
|
||||
- name: nonce
|
||||
type: string
|
||||
required: true
|
||||
desc: Nonce/IV for encryption
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: Plaintext to encrypt
|
||||
- name: additionalData
|
||||
type: string
|
||||
required: false
|
||||
desc: Additional authenticated data (AAD) for GCM mode
|
||||
- name: encoding
|
||||
type: string
|
||||
required: false
|
||||
desc: "Output encoding: \"base64\" for base64 output (default: hex)"
|
||||
return:
|
||||
type: string
|
||||
desc: Encrypted ciphertext (hex or base64 encoded)
|
||||
|
||||
- name: aes256decrypt
|
||||
desc: Decrypt data using AES-256 algorithm
|
||||
args:
|
||||
- name: algorithm
|
||||
type: string
|
||||
required: true
|
||||
desc: "AES mode: \"GCM\""
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: AES-256 decryption key (32 bytes)
|
||||
- name: nonce
|
||||
type: string
|
||||
required: true
|
||||
desc: Nonce/IV used during encryption
|
||||
- name: ciphertext
|
||||
type: string
|
||||
required: true
|
||||
desc: Encrypted data to decrypt (hex or base64 encoded)
|
||||
- name: additionalData
|
||||
type: string
|
||||
required: false
|
||||
desc: Additional authenticated data (AAD) used during encryption
|
||||
- name: encoding
|
||||
type: string
|
||||
required: false
|
||||
desc: "Input encoding: \"base64\" if ciphertext is base64-encoded (default: hex)"
|
||||
return:
|
||||
type: string
|
||||
desc: Decrypted plaintext
|
||||
11
engine/doc.go
Normal file
11
engine/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
92
engine/doc.yml
Normal file
92
engine/doc.yml
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
group: utils.app
|
||||
type: process
|
||||
desc: "Utility and app bootstrap processes for health checks and system inspection"
|
||||
entries:
|
||||
# ── utils.app (current) ──────────────────────────────────────────
|
||||
- name: Ping
|
||||
desc: Return engine name, version, and application root path
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with engine, version, and root fields"
|
||||
|
||||
- name: Inspect
|
||||
desc: Return detailed system information including version, CUI, build name, config, and external tools
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with VERSION, CUI, BUILDNAME, CONFIG, and optionally TOOLS fields"
|
||||
|
||||
# ── xiang.main (deprecated, aliased to utils.app) ───────────────
|
||||
- name: Ping
|
||||
group: xiang.main
|
||||
desc: "[Deprecated: use utils.app.Ping] Return engine name, version, and application root path"
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with engine, version, and root fields"
|
||||
|
||||
- name: Inspect
|
||||
group: xiang.main
|
||||
desc: "[Deprecated: use utils.app.Inspect] Return detailed system information"
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with VERSION, CUI, BUILDNAME, CONFIG, and optionally TOOLS fields"
|
||||
|
||||
- name: Favicon
|
||||
group: xiang.main
|
||||
desc: "[Deprecated] Return the application favicon (currently returns null)"
|
||||
args: []
|
||||
return:
|
||||
type: "null"
|
||||
desc: "Always returns null"
|
||||
|
||||
- name: FileContent
|
||||
group: xiang.main
|
||||
desc: "[Deprecated] Return file content from storage (currently returns null)"
|
||||
args:
|
||||
- name: filename
|
||||
type: string
|
||||
required: false
|
||||
desc: "File path to read (handler is disabled)"
|
||||
- name: encode
|
||||
type: bool
|
||||
required: false
|
||||
desc: "Whether to base64 encode the content (handler is disabled)"
|
||||
return:
|
||||
type: "null"
|
||||
desc: "Always returns null"
|
||||
|
||||
- name: AppFileContent
|
||||
group: xiang.main
|
||||
desc: "[Deprecated] Return application data file content (currently returns null)"
|
||||
args:
|
||||
- name: filename
|
||||
type: string
|
||||
required: false
|
||||
desc: "Application data file path to read (handler is disabled)"
|
||||
- name: encode
|
||||
type: bool
|
||||
required: false
|
||||
desc: "Whether to base64 encode the content (handler is disabled)"
|
||||
return:
|
||||
type: "null"
|
||||
desc: "Always returns null"
|
||||
|
||||
# ── xiang.sys (deprecated aliases) ──────────────────────────────
|
||||
- name: Ping
|
||||
group: xiang.sys
|
||||
desc: "[Deprecated: use utils.app.Ping] Alias of xiang.main.Ping"
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with engine, version, and root fields"
|
||||
|
||||
- name: Inspect
|
||||
group: xiang.sys
|
||||
desc: "[Deprecated: use utils.app.Inspect] Alias of xiang.main.Inspect"
|
||||
args: []
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with VERSION, CUI, BUILDNAME, CONFIG, and optionally TOOLS fields"
|
||||
12
excel/doc.go
Normal file
12
excel/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package excel
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
678
excel/doc.yml
Normal file
678
excel/doc.yml
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
group: excel
|
||||
type: process
|
||||
entries:
|
||||
# File operations
|
||||
- name: open
|
||||
desc: Open an Excel file and return a handle for subsequent operations
|
||||
args:
|
||||
- name: file
|
||||
type: string
|
||||
required: true
|
||||
desc: File path relative to the data directory
|
||||
- name: writable
|
||||
type: bool
|
||||
required: false
|
||||
desc: "Whether to open in writable mode (default: false)"
|
||||
return:
|
||||
type: string
|
||||
desc: Handle string for referencing the opened file
|
||||
|
||||
- name: close
|
||||
desc: Close an opened Excel file and release resources
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: save
|
||||
desc: Save the current state of an opened Excel file to disk
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: sheets
|
||||
desc: Get the list of sheet names in an Excel file
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
return:
|
||||
type: array
|
||||
desc: Array of sheet name strings
|
||||
|
||||
# Sheet operations
|
||||
- name: sheet.create
|
||||
desc: Create a new sheet in an Excel file
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Name for the new sheet
|
||||
return:
|
||||
type: number
|
||||
desc: Index of the created sheet
|
||||
|
||||
- name: sheet.read
|
||||
desc: Read all data from a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: array
|
||||
desc: 2D array of sheet data
|
||||
|
||||
- name: sheet.update
|
||||
desc: Update a sheet with new data (overwrites existing content)
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: data
|
||||
type: array
|
||||
required: true
|
||||
desc: 2D array of data to write
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: sheet.delete
|
||||
desc: Delete a sheet from an Excel file
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name to delete
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: sheet.copy
|
||||
desc: Copy a sheet to a new sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: source
|
||||
type: string
|
||||
required: true
|
||||
desc: Source sheet name
|
||||
- name: target
|
||||
type: string
|
||||
required: true
|
||||
desc: Target sheet name
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: sheet.list
|
||||
desc: List all sheets with their metadata
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
return:
|
||||
type: array
|
||||
desc: Array of sheet information objects
|
||||
|
||||
- name: sheet.exists
|
||||
desc: Check if a sheet exists in an Excel file
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name to check
|
||||
return:
|
||||
type: bool
|
||||
desc: True if the sheet exists
|
||||
|
||||
- name: sheet.rows
|
||||
desc: Read a range of rows from a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: start
|
||||
type: number
|
||||
required: true
|
||||
desc: Start row index (0-based)
|
||||
- name: size
|
||||
type: number
|
||||
required: true
|
||||
desc: Number of rows to read
|
||||
return:
|
||||
type: array
|
||||
desc: 2D array of row data
|
||||
|
||||
- name: sheet.dimension
|
||||
desc: Get the dimensions (rows and columns count) of a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with rows and cols counts (e.g. {rows: 100, cols: 10})"
|
||||
|
||||
# Read operations
|
||||
- name: read.cell
|
||||
desc: Read the value of a single cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\", \"B2\")"
|
||||
return:
|
||||
type: string
|
||||
desc: Cell value as string
|
||||
|
||||
- name: read.row
|
||||
desc: Read all rows from a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: array
|
||||
desc: 2D array of all row data
|
||||
|
||||
- name: read.column
|
||||
desc: Read all columns from a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: array
|
||||
desc: 2D array of column data
|
||||
|
||||
# Write operations
|
||||
- name: write.cell
|
||||
desc: Write a value to a single cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\")"
|
||||
- name: value
|
||||
type: any
|
||||
required: true
|
||||
desc: Value to write
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: write.row
|
||||
desc: Write values to a row starting from a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Starting cell reference (e.g. \"A1\")"
|
||||
- name: values
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of values to write across the row
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: write.column
|
||||
desc: Write values to a column starting from a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Starting cell reference (e.g. \"A1\")"
|
||||
- name: values
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of values to write down the column
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: write.all
|
||||
desc: Write a 2D array of data starting from a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Starting cell reference (e.g. \"A1\")"
|
||||
- name: values
|
||||
type: array
|
||||
required: true
|
||||
desc: 2D array of values (array of row arrays)
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
# Style & formatting
|
||||
- name: set.style
|
||||
desc: Apply a style to a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\")"
|
||||
- name: styleID
|
||||
type: number
|
||||
required: true
|
||||
desc: Style ID to apply
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.formula
|
||||
desc: Set a formula for a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\")"
|
||||
- name: formula
|
||||
type: string
|
||||
required: true
|
||||
desc: "Excel formula string (e.g. \"=SUM(A1:A10)\")"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.link
|
||||
desc: Set a hyperlink for a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\")"
|
||||
- name: link
|
||||
type: string
|
||||
required: true
|
||||
desc: Hyperlink URL
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: Link type or display text
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.richtext
|
||||
desc: Set rich text content for a cell
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\")"
|
||||
- name: richText
|
||||
type: array
|
||||
required: true
|
||||
desc: "Array of rich text run objects: [{text: \"...\"}]"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.comment
|
||||
desc: Set a comment on a sheet
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: comment
|
||||
type: object
|
||||
required: true
|
||||
desc: Comment data object
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.rowheight
|
||||
desc: Set the height of a row
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: row
|
||||
type: number
|
||||
required: true
|
||||
desc: Row number (1-based)
|
||||
- name: height
|
||||
type: number
|
||||
required: true
|
||||
desc: Row height in points
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.columnwidth
|
||||
desc: Set the width of columns in a range
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: startCol
|
||||
type: string
|
||||
required: true
|
||||
desc: "Start column letter (e.g. \"A\")"
|
||||
- name: endCol
|
||||
type: string
|
||||
required: true
|
||||
desc: "End column letter (e.g. \"D\")"
|
||||
- name: width
|
||||
type: number
|
||||
required: true
|
||||
desc: Column width
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.mergecell
|
||||
desc: Merge a range of cells
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: start
|
||||
type: string
|
||||
required: true
|
||||
desc: "Top-left cell reference (e.g. \"A1\")"
|
||||
- name: end
|
||||
type: string
|
||||
required: true
|
||||
desc: "Bottom-right cell reference (e.g. \"D4\")"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: set.unmergecell
|
||||
desc: Unmerge a range of cells
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
- name: start
|
||||
type: string
|
||||
required: true
|
||||
desc: "Top-left cell reference (e.g. \"A1\")"
|
||||
- name: end
|
||||
type: string
|
||||
required: true
|
||||
desc: "Bottom-right cell reference (e.g. \"D4\")"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
# Iterator operations
|
||||
- name: each.openrow
|
||||
desc: Open a row iterator for streaming row-by-row reading
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: string
|
||||
desc: Iterator ID for use with nextrow/closerow
|
||||
|
||||
- name: each.closerow
|
||||
desc: Close a row iterator and release resources
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Iterator ID from each.openrow
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
- name: each.nextrow
|
||||
desc: Get the next row from the iterator; returns null when exhausted
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Iterator ID from each.openrow
|
||||
return:
|
||||
type: array
|
||||
desc: Array of cell values for the row, or null if no more rows
|
||||
|
||||
- name: each.opencolumn
|
||||
desc: Open a column iterator for streaming column-by-column reading
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: File handle from excel.open
|
||||
- name: sheet
|
||||
type: string
|
||||
required: true
|
||||
desc: Sheet name
|
||||
return:
|
||||
type: string
|
||||
desc: Iterator ID for use with nextcolumn/closecolumn
|
||||
|
||||
- name: each.closecolumn
|
||||
desc: Close a column iterator and release resources
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Iterator ID from each.opencolumn
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
- name: each.nextcolumn
|
||||
desc: Get the next column from the iterator; returns null when exhausted
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Iterator ID from each.opencolumn
|
||||
return:
|
||||
type: array
|
||||
desc: Array of cell values for the column, or null if no more columns
|
||||
|
||||
# Conversion utilities
|
||||
- name: convert.columnnametonumber
|
||||
desc: "Convert a column letter name to a number (e.g. \"A\" -> 1, \"Z\" -> 26)"
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: "Column letter name (e.g. \"A\", \"AB\")"
|
||||
return:
|
||||
type: number
|
||||
desc: Column number (1-based)
|
||||
|
||||
- name: convert.columnnumbertoname
|
||||
desc: "Convert a column number to a letter name (e.g. 1 -> \"A\", 26 -> \"Z\")"
|
||||
args:
|
||||
- name: number
|
||||
type: number
|
||||
required: true
|
||||
desc: Column number (1-based)
|
||||
return:
|
||||
type: string
|
||||
desc: Column letter name
|
||||
|
||||
- name: convert.cellnametocoordinates
|
||||
desc: "Convert a cell name to column and row coordinates (e.g. \"B3\" -> [2, 3])"
|
||||
args:
|
||||
- name: cell
|
||||
type: string
|
||||
required: true
|
||||
desc: "Cell reference (e.g. \"A1\", \"B3\")"
|
||||
return:
|
||||
type: array
|
||||
desc: "[column, row] coordinates (1-based)"
|
||||
|
||||
- name: convert.coordinatestocellname
|
||||
desc: "Convert column and row coordinates to a cell name (e.g. 2, 3 -> \"B3\")"
|
||||
args:
|
||||
- name: col
|
||||
type: number
|
||||
required: true
|
||||
desc: Column number (1-based)
|
||||
- name: row
|
||||
type: number
|
||||
required: true
|
||||
desc: Row number (1-based)
|
||||
return:
|
||||
type: string
|
||||
desc: "Cell reference string (e.g. \"B3\")"
|
||||
2
go.mod
2
go.mod
|
|
@ -147,7 +147,7 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.14.28 // indirect
|
||||
github.com/miekg/dns v1.1.66 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/spdystream v0.5.1 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -299,8 +299,8 @@ github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
|
|||
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
|
||||
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y=
|
||||
github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
|
|
|
|||
12
helper/doc.go
Normal file
12
helper/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
473
helper/doc.yml
Normal file
473
helper/doc.yml
Normal file
|
|
@ -0,0 +1,473 @@
|
|||
group: xiang.helper
|
||||
type: process
|
||||
entries:
|
||||
# Array operations
|
||||
- name: ArrayPluck
|
||||
desc: "[Deprecated: use utils.arr.Pluck] Merge multiple record sets into one by plucking specified columns"
|
||||
args:
|
||||
- name: columns
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of column names to pluck
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: Map of column names to value arrays
|
||||
return:
|
||||
type: array
|
||||
desc: Merged array of records
|
||||
|
||||
- name: ArraySplit
|
||||
desc: "[Deprecated: use utils.arr.Split] Split an array of records into columns and values"
|
||||
args:
|
||||
- name: records
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of record objects
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with columns (string[]) and values (any[][])"
|
||||
|
||||
- name: ArrayColumn
|
||||
desc: "[Deprecated: use utils.arr.Column] Extract values of a specified field from an array of records"
|
||||
args:
|
||||
- name: records
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of record objects
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Field name to extract
|
||||
return:
|
||||
type: array
|
||||
desc: Array of field values
|
||||
|
||||
- name: ArrayKeep
|
||||
desc: "[Deprecated: use utils.arr.Keep] Keep only specified keys in each record"
|
||||
args:
|
||||
- name: records
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of record objects
|
||||
- name: columns
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of key names to keep
|
||||
return:
|
||||
type: array
|
||||
desc: Filtered array of records
|
||||
|
||||
- name: ArrayTree
|
||||
desc: "[Deprecated: use utils.arr.Tree] Convert a flat array of records into a tree structure"
|
||||
args:
|
||||
- name: records
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of record objects
|
||||
- name: setting
|
||||
type: object
|
||||
required: true
|
||||
desc: "Tree settings: {primary, parent, children, etc.}"
|
||||
return:
|
||||
type: array
|
||||
desc: Tree-structured array
|
||||
|
||||
- name: ArrayUnique
|
||||
desc: "[Deprecated: use utils.arr.Unique] Remove duplicate values from an array"
|
||||
args:
|
||||
- name: array
|
||||
type: array
|
||||
required: true
|
||||
desc: Array to deduplicate
|
||||
return:
|
||||
type: array
|
||||
desc: Array with duplicates removed
|
||||
|
||||
- name: ArrayMapSet
|
||||
desc: "[Deprecated: use utils.arr.MapSet] Set a field value on every map in an array"
|
||||
args:
|
||||
- name: records
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of map objects
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Key to set in each map
|
||||
- name: value
|
||||
type: any
|
||||
required: true
|
||||
desc: Value to set
|
||||
return:
|
||||
type: array
|
||||
desc: Modified array
|
||||
|
||||
- name: ArrayIndexes
|
||||
desc: "[Deprecated: use utils.arr.Indexes] Return the index numbers of an array"
|
||||
args:
|
||||
- name: array
|
||||
type: array
|
||||
required: true
|
||||
desc: Input array
|
||||
return:
|
||||
type: array
|
||||
desc: Array of integer indexes
|
||||
|
||||
- name: ArrayGet
|
||||
desc: "[Deprecated: use utils.arr.Get] Get an element at a specified index from an array"
|
||||
args:
|
||||
- name: array
|
||||
type: array
|
||||
required: true
|
||||
desc: Input array
|
||||
- name: index
|
||||
type: number
|
||||
required: true
|
||||
desc: Index to retrieve
|
||||
return:
|
||||
type: any
|
||||
desc: Element at the given index, or null if out of range
|
||||
|
||||
# Map operations
|
||||
- name: MapKeys
|
||||
desc: "[Deprecated: use utils.map.Keys] Return all keys of a map"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
return:
|
||||
type: array
|
||||
desc: Array of key strings
|
||||
|
||||
- name: MapValues
|
||||
desc: "[Deprecated: use utils.map.Values] Return all values of a map"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
return:
|
||||
type: array
|
||||
desc: Array of values
|
||||
|
||||
- name: MapGet
|
||||
desc: "[Deprecated: use utils.map.Get] Get a value by key from a map (supports dot notation)"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Key name (supports dot notation for nested access)
|
||||
return:
|
||||
type: any
|
||||
desc: Value at the given key
|
||||
|
||||
- name: MapSet
|
||||
desc: "[Deprecated: use utils.map.Set] Set a key-value pair in a map (supports dot notation)"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Key name (supports dot notation for nested access)
|
||||
- name: value
|
||||
type: any
|
||||
required: true
|
||||
desc: Value to set
|
||||
return:
|
||||
type: object
|
||||
desc: Modified map
|
||||
|
||||
- name: MapDel
|
||||
desc: "[Deprecated: use utils.map.Del] Delete a key from a map"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
- name: key
|
||||
type: string
|
||||
required: true
|
||||
desc: Key name to delete
|
||||
return:
|
||||
type: object
|
||||
desc: Modified map
|
||||
|
||||
- name: MapMultiDel
|
||||
desc: "[Deprecated: use utils.map.DelMany] Delete multiple keys from a map"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
- name: keys
|
||||
type: string
|
||||
required: true
|
||||
desc: Keys to delete (variadic)
|
||||
return:
|
||||
type: object
|
||||
desc: Modified map
|
||||
|
||||
- name: MapToArray
|
||||
desc: "[Deprecated: use utils.map.Array] Convert a map to an array of key-value objects"
|
||||
args:
|
||||
- name: record
|
||||
type: object
|
||||
required: true
|
||||
desc: Input map
|
||||
return:
|
||||
type: array
|
||||
desc: "Array of {key, value} objects"
|
||||
|
||||
# String operations
|
||||
- name: StrConcat
|
||||
desc: "[Deprecated: use utils.str.Concat] Concatenate multiple values into a string"
|
||||
args:
|
||||
- name: values
|
||||
type: any
|
||||
required: true
|
||||
desc: Values to concatenate (variadic, minimum 2)
|
||||
return:
|
||||
type: string
|
||||
desc: Concatenated string
|
||||
|
||||
- name: HexToString
|
||||
desc: "[Deprecated: use utils.str.Hex] Encode a string or byte array to hexadecimal"
|
||||
args:
|
||||
- name: input
|
||||
type: any
|
||||
required: true
|
||||
desc: String or byte array to encode
|
||||
return:
|
||||
type: string
|
||||
desc: Hex-encoded string
|
||||
|
||||
# Captcha
|
||||
- name: Captcha
|
||||
desc: "[Deprecated: use utils.captcha.Make] Generate a captcha image/audio"
|
||||
args:
|
||||
- name: params
|
||||
type: any
|
||||
required: true
|
||||
desc: "URL-style params with width, height, length, type, lang, background"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with id and content (base64 image/audio data)"
|
||||
|
||||
- name: CaptchaValidate
|
||||
desc: "[Deprecated: use utils.captcha.Verify] Validate a captcha code"
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Captcha ID
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: User-entered captcha code
|
||||
return:
|
||||
type: bool
|
||||
desc: True if valid; throws exception if invalid
|
||||
|
||||
# Password
|
||||
- name: PasswordValidate
|
||||
desc: "[Deprecated: use utils.pwd.Verify] Validate a password against a bcrypt hash"
|
||||
args:
|
||||
- name: password
|
||||
type: string
|
||||
required: true
|
||||
desc: Plain text password
|
||||
- name: passwordHash
|
||||
type: string
|
||||
required: true
|
||||
desc: Bcrypt hash to compare against
|
||||
return:
|
||||
type: bool
|
||||
desc: True if password matches; throws exception if invalid
|
||||
|
||||
# JWT
|
||||
- name: JwtMake
|
||||
desc: "[Deprecated: use utils.jwt.Make] Generate a JWT token"
|
||||
args:
|
||||
- name: id
|
||||
type: number
|
||||
required: true
|
||||
desc: User ID
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: Custom claims data
|
||||
- name: option
|
||||
type: object
|
||||
required: false
|
||||
desc: "Options: {subject, audience, issuer, timeout (seconds), sid, expires_at}"
|
||||
return:
|
||||
type: object
|
||||
desc: "JWT token object with token string and expires_at timestamp"
|
||||
|
||||
- name: JwtValidate
|
||||
desc: "[Deprecated: use utils.jwt.Verify] Validate and parse a JWT token"
|
||||
args:
|
||||
- name: token
|
||||
type: string
|
||||
required: true
|
||||
desc: JWT token string
|
||||
return:
|
||||
type: object
|
||||
desc: "Decoded JWT claims: {id, sid, data, ...standard claims}"
|
||||
|
||||
# Flow control
|
||||
- name: For
|
||||
desc: "[Deprecated: use utils.flow.For] Execute a process in a loop from start to end"
|
||||
args:
|
||||
- name: from
|
||||
type: number
|
||||
required: true
|
||||
desc: Start index (inclusive)
|
||||
- name: to
|
||||
type: number
|
||||
required: true
|
||||
desc: End index (exclusive)
|
||||
- name: process
|
||||
type: object
|
||||
required: true
|
||||
desc: "Process definition: {process: \"name\", args: [\"::key\", \"::value\"]}"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
- name: Each
|
||||
desc: "[Deprecated: use utils.flow.Each] Iterate over a value (array, map, or integer) and execute a process"
|
||||
args:
|
||||
- name: data
|
||||
type: any
|
||||
required: true
|
||||
desc: Value to iterate over (array, map, or integer)
|
||||
- name: process
|
||||
type: object
|
||||
required: true
|
||||
desc: "Process definition: {process: \"name\", args: [\"::key\", \"::value\"]}"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
- name: Case
|
||||
desc: "[Deprecated: use utils.flow.Case] Execute the first process whose conditions are met"
|
||||
args:
|
||||
- name: cases
|
||||
type: object
|
||||
required: true
|
||||
desc: "Case objects (variadic): {when: [{...conditions}], process: \"name\", args: [...]}"
|
||||
return:
|
||||
type: any
|
||||
desc: Return value from the matched process, or null if no match
|
||||
|
||||
- name: IF
|
||||
desc: "[Deprecated: use utils.flow.IF] Conditional execution with optional else branch"
|
||||
args:
|
||||
- name: condition
|
||||
type: object
|
||||
required: true
|
||||
desc: "Primary condition: {when: [{...conditions}], process: \"name\", args: [...]}"
|
||||
- name: else
|
||||
type: object
|
||||
required: false
|
||||
desc: "Else condition: {when: [{...conditions}], process: \"name\", args: [...]}"
|
||||
return:
|
||||
type: any
|
||||
desc: Return value from the executed process, or null
|
||||
|
||||
- name: Throw
|
||||
desc: "[Deprecated: use utils.flow.Throw] Throw an exception with a message and HTTP status code"
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: true
|
||||
desc: Error message
|
||||
- name: code
|
||||
type: number
|
||||
required: true
|
||||
desc: HTTP status code
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: Return
|
||||
desc: "[Deprecated: use utils.flow.Return] Return all arguments as-is"
|
||||
args:
|
||||
- name: values
|
||||
type: any
|
||||
required: false
|
||||
desc: Values to return (variadic)
|
||||
return:
|
||||
type: array
|
||||
desc: Array of all passed arguments
|
||||
|
||||
# Environment
|
||||
- name: EnvGet
|
||||
desc: "[Deprecated: use utils.env.Get] Get an environment variable value"
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Environment variable name
|
||||
return:
|
||||
type: string
|
||||
desc: Environment variable value
|
||||
|
||||
- name: EnvSet
|
||||
desc: "[Deprecated: use utils.env.Set] Set an environment variable"
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: Environment variable name
|
||||
- name: value
|
||||
type: string
|
||||
required: true
|
||||
desc: Value to set
|
||||
return:
|
||||
type: any
|
||||
desc: Error on failure, null on success
|
||||
|
||||
- name: EnvMultiGet
|
||||
desc: "[Deprecated: use utils.env.GetMany] Get multiple environment variable values"
|
||||
args:
|
||||
- name: names
|
||||
type: string
|
||||
required: true
|
||||
desc: Environment variable names (variadic)
|
||||
return:
|
||||
type: object
|
||||
desc: Map of variable names to their values
|
||||
|
||||
- name: EnvMultiSet
|
||||
desc: "[Deprecated: use utils.env.SetMany] Set multiple environment variables"
|
||||
args:
|
||||
- name: envs
|
||||
type: object
|
||||
required: true
|
||||
desc: Map of variable names to values
|
||||
return:
|
||||
type: any
|
||||
desc: Error on failure, null on success
|
||||
|
||||
# Print
|
||||
- name: Print
|
||||
desc: "[Deprecated: use utils.fmt.Print] Print values to stdout (debug dump)"
|
||||
args:
|
||||
- name: values
|
||||
type: any
|
||||
required: true
|
||||
desc: Values to print (variadic)
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
12
openai/doc.go
Normal file
12
openai/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package openai
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
97
openai/doc.yml
Normal file
97
openai/doc.yml
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
group: openai
|
||||
type: process
|
||||
entries:
|
||||
- name: tiktoken
|
||||
desc: Count the number of tokens for a given model and input text
|
||||
args:
|
||||
- name: model
|
||||
type: string
|
||||
required: true
|
||||
desc: Model name for tokenization (e.g. "gpt-3.5-turbo", "gpt-4")
|
||||
- name: input
|
||||
type: string
|
||||
required: true
|
||||
desc: Input text to tokenize
|
||||
return:
|
||||
type: number
|
||||
desc: Number of tokens in the input text
|
||||
|
||||
- name: embeddings
|
||||
desc: Create embedding vectors representing the input text
|
||||
args:
|
||||
- name: model
|
||||
type: string
|
||||
required: true
|
||||
desc: AI connector name (e.g. "openai")
|
||||
- name: input
|
||||
type: any
|
||||
required: true
|
||||
desc: Input text or array of texts to embed
|
||||
- name: user
|
||||
type: string
|
||||
required: false
|
||||
desc: Unique identifier for the end-user
|
||||
return:
|
||||
type: object
|
||||
desc: Embedding response with vector data
|
||||
|
||||
- name: chat.completions
|
||||
desc: Create a chat completion response for the given messages
|
||||
args:
|
||||
- name: model
|
||||
type: string
|
||||
required: true
|
||||
desc: AI connector name (e.g. "openai")
|
||||
- name: messages
|
||||
type: array
|
||||
required: true
|
||||
desc: "Array of message objects with role and content fields"
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Additional options: temperature, max_tokens, etc."
|
||||
- name: callback
|
||||
type: function
|
||||
required: false
|
||||
desc: Callback function for streaming responses; receives each chunk and returns an int status
|
||||
return:
|
||||
type: object
|
||||
desc: Chat completion response object
|
||||
|
||||
- name: audio.transcriptions
|
||||
desc: Transcribe audio from base64-encoded data into text
|
||||
args:
|
||||
- name: model
|
||||
type: string
|
||||
required: true
|
||||
desc: AI connector name (e.g. "openai.whisper-1")
|
||||
- name: dataBase64
|
||||
type: string
|
||||
required: true
|
||||
desc: Base64-encoded audio data
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Additional options: language, model override, etc."
|
||||
return:
|
||||
type: object
|
||||
desc: "Transcription result (e.g. {\"text\": \"...\"})"
|
||||
|
||||
- name: audio.transcriptionsfile
|
||||
desc: Transcribe audio from a file path using streaming upload (no base64 overhead)
|
||||
args:
|
||||
- name: connector
|
||||
type: string
|
||||
required: true
|
||||
desc: AI connector name (e.g. "openai.whisper-1")
|
||||
- name: filePath
|
||||
type: string
|
||||
required: true
|
||||
desc: Absolute OS file path to the audio file
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Additional options: language, model override, etc."
|
||||
return:
|
||||
type: object
|
||||
desc: "Transcription result (e.g. {\"text\": \"...\"})"
|
||||
12
openapi/job/doc.go
Normal file
12
openapi/job/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package job
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
166
openapi/job/doc.yml
Normal file
166
openapi/job/doc.yml
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
group: job
|
||||
type: process
|
||||
entries:
|
||||
# Job Management
|
||||
- name: jobs.list
|
||||
desc: List jobs with pagination and optional query parameters
|
||||
args:
|
||||
- name: page
|
||||
type: number
|
||||
required: false
|
||||
desc: "Page number (default: 1)"
|
||||
- name: pagesize
|
||||
type: number
|
||||
required: false
|
||||
desc: "Number of records per page (default: 20)"
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters with wheres, orders, etc.
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated job list with data array and pagination info
|
||||
|
||||
- name: jobs.get
|
||||
desc: Get a specific job by its ID
|
||||
args:
|
||||
- name: jobID
|
||||
type: string
|
||||
required: true
|
||||
desc: Job ID to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Job instance details including status, schedule, last_run_at, next_run_at, etc.
|
||||
|
||||
- name: jobs.count
|
||||
desc: Count jobs matching query parameters
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters with wheres conditions
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with count"
|
||||
|
||||
- name: jobs.stop
|
||||
desc: Stop a running job
|
||||
args:
|
||||
- name: jobID
|
||||
type: string
|
||||
required: true
|
||||
desc: Job ID to stop
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message and job_id"
|
||||
|
||||
# Execution Management
|
||||
- name: executions.list
|
||||
desc: List executions for a specific job
|
||||
args:
|
||||
- name: jobID
|
||||
type: string
|
||||
required: true
|
||||
desc: Job ID to list executions for
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with executions array and count"
|
||||
|
||||
- name: executions.get
|
||||
desc: Get a specific execution by its ID
|
||||
args:
|
||||
- name: executionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Execution ID to retrieve
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Optional query parameters
|
||||
return:
|
||||
type: object
|
||||
desc: Execution details including status, progress, started_at, ended_at, duration, etc.
|
||||
|
||||
- name: executions.count
|
||||
desc: Count executions for a specific job
|
||||
args:
|
||||
- name: jobID
|
||||
type: string
|
||||
required: true
|
||||
desc: Job ID to count executions for
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Optional query parameters with wheres conditions
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with count"
|
||||
|
||||
- name: executions.stop
|
||||
desc: Stop a running execution (stops the parent job)
|
||||
args:
|
||||
- name: executionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Execution ID to stop
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message, execution_id, and job_id"
|
||||
|
||||
# Log Management
|
||||
- name: logs.list
|
||||
desc: List logs for a specific job with pagination
|
||||
args:
|
||||
- name: jobID
|
||||
type: string
|
||||
required: true
|
||||
desc: Job ID to list logs for
|
||||
- name: page
|
||||
type: number
|
||||
required: false
|
||||
desc: "Page number (default: 1)"
|
||||
- name: pagesize
|
||||
type: number
|
||||
required: false
|
||||
desc: "Number of records per page (default: 50)"
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Optional query parameters with wheres conditions (level, execution_id filters)
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated log list with data array and pagination info
|
||||
|
||||
# Category Management
|
||||
- name: categories.list
|
||||
desc: List job categories with optional filtering
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters with wheres conditions (enabled, system filters)
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with categories array and count"
|
||||
|
||||
- name: categories.get
|
||||
desc: Get a specific job category by its ID
|
||||
args:
|
||||
- name: categoryID
|
||||
type: string
|
||||
required: true
|
||||
desc: Category ID to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Category details including name, description, enabled status, etc.
|
||||
|
||||
- name: categories.count
|
||||
desc: Count job categories matching query parameters
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters with wheres conditions
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with count"
|
||||
|
|
@ -60,7 +60,7 @@ func ListLogs(c *gin.Context) {
|
|||
// Build query parameters
|
||||
param := model.QueryParam{
|
||||
Orders: []model.QueryOrder{
|
||||
{Column: "timestamp", Option: "desc"}, // 日志按时间戳倒序
|
||||
{Column: "timestamp", Option: "desc"},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ func ListExecutionLogs(c *gin.Context) {
|
|||
{Column: "execution_id", Value: executionID},
|
||||
},
|
||||
Orders: []model.QueryOrder{
|
||||
{Column: "timestamp", Option: "desc"}, // 日志按时间戳倒序
|
||||
{Column: "timestamp", Option: "desc"},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
12
openapi/kb/doc.go
Normal file
12
openapi/kb/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package kb
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
118
openapi/kb/doc.yml
Normal file
118
openapi/kb/doc.yml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
group: kb
|
||||
type: process
|
||||
entries:
|
||||
# Collection Management
|
||||
- name: collection.create
|
||||
desc: Create a new knowledge base collection with embedding configuration
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "Collection parameters: {id, metadata: {name, description}, embedding_provider_id, embedding_option_id, locale, config: {distance, index_type, m, ef_construction, ef_search}}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with collection_id and message"
|
||||
|
||||
- name: collection.remove
|
||||
desc: Remove a collection and all its documents
|
||||
args:
|
||||
- name: collectionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Collection ID to remove
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with collection_id, removed status, documents_removed count, and message"
|
||||
|
||||
- name: collection.get
|
||||
desc: Retrieve a collection by its ID
|
||||
args:
|
||||
- name: collectionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Collection ID to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Collection details including metadata, embedding config, status, etc.
|
||||
|
||||
- name: collection.exists
|
||||
desc: Check if a collection exists
|
||||
args:
|
||||
- name: collectionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Collection ID to check
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with collection_id and exists (bool)"
|
||||
|
||||
- name: collection.list
|
||||
desc: List collections with pagination and filtering
|
||||
args:
|
||||
- name: filter
|
||||
type: object
|
||||
required: false
|
||||
desc: "Filter parameters: {page, pagesize, keywords, status, embedding_provider_id, system, select, sort}"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated result with data array, page, pagesize, total, pagecnt, next, prev
|
||||
|
||||
- name: collection.updatemetadata
|
||||
desc: Update the metadata of an existing collection
|
||||
args:
|
||||
- name: collectionID
|
||||
type: string
|
||||
required: true
|
||||
desc: Collection ID to update
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "Update parameters: {metadata: {name, description}}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with collection_id and message"
|
||||
|
||||
# Document Management
|
||||
- name: documents.addfile
|
||||
desc: Add a document to a collection from an uploaded file
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: File upload parameters including collection_id and file data
|
||||
return:
|
||||
type: object
|
||||
desc: Document creation result with document_id
|
||||
|
||||
- name: documents.addtext
|
||||
desc: Add a document to a collection from raw text content
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: Text document parameters including collection_id, content, and metadata
|
||||
return:
|
||||
type: object
|
||||
desc: Document creation result with document_id
|
||||
|
||||
- name: documents.addurl
|
||||
desc: Add a document to a collection by fetching content from a URL
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: URL document parameters including collection_id and URL
|
||||
return:
|
||||
type: object
|
||||
desc: Document creation result with document_id
|
||||
|
||||
- name: documents.getcontents
|
||||
desc: Retrieve content for one or more documents by their IDs
|
||||
args:
|
||||
- name: documentIDs
|
||||
type: any
|
||||
required: true
|
||||
desc: "A single document ID (string) or an array of document IDs"
|
||||
return:
|
||||
type: array
|
||||
desc: Array of objects with document_id, name, content, content_type, etc.
|
||||
12
openapi/oauth/doc.go
Normal file
12
openapi/oauth/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
48
openapi/oauth/doc.yml
Normal file
48
openapi/oauth/doc.yml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
group: oauth
|
||||
type: process
|
||||
entries:
|
||||
- name: token.Make
|
||||
desc: Generate an OAuth access token with explicit parameters
|
||||
args:
|
||||
- name: clientID
|
||||
type: string
|
||||
required: true
|
||||
desc: OAuth client ID embedded in the token
|
||||
- name: scope
|
||||
type: string
|
||||
required: true
|
||||
desc: Token scope (space-separated)
|
||||
- name: subject
|
||||
type: string
|
||||
required: true
|
||||
desc: JWT subject claim
|
||||
- name: expiresIn
|
||||
type: number
|
||||
required: true
|
||||
desc: Token lifetime in seconds
|
||||
- name: extraClaims
|
||||
type: object
|
||||
required: false
|
||||
desc: Additional JWT claims (e.g. user_id, team_id)
|
||||
return:
|
||||
type: string
|
||||
desc: The generated access token string
|
||||
|
||||
- name: token.MakeByUser
|
||||
desc: Generate an OAuth access token for a team member by looking up user and team from the database
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: Member ID (business ID)
|
||||
- name: expiresIn
|
||||
type: number
|
||||
required: false
|
||||
desc: "Token lifetime in seconds (default: 86400 = 24h)"
|
||||
return:
|
||||
type: string
|
||||
desc: The generated access token string
|
||||
12
openapi/otp/doc.go
Normal file
12
openapi/otp/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package otp
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
50
openapi/otp/doc.yml
Normal file
50
openapi/otp/doc.yml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
group: otp
|
||||
type: process
|
||||
entries:
|
||||
- name: create
|
||||
desc: Create a new OTP code with associated payload data for login or verification
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "OTP creation parameters: team_id, member_id, user_id, expires_in, redirect, scope, token_expires_in, consume"
|
||||
return:
|
||||
type: string
|
||||
desc: The generated OTP code
|
||||
|
||||
- name: verify
|
||||
desc: Verify an OTP code and return its associated payload without consuming it
|
||||
args:
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: The OTP code to verify
|
||||
return:
|
||||
type: object
|
||||
desc: The payload associated with the OTP code (team_id, member_id, user_id, redirect, scope, etc.)
|
||||
|
||||
- name: login
|
||||
desc: Verify an OTP code and perform login, returning access tokens and redirect URL
|
||||
args:
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: The OTP code to authenticate with
|
||||
- name: locale
|
||||
type: string
|
||||
required: false
|
||||
desc: Locale for login context (e.g. "en", "zh-CN")
|
||||
return:
|
||||
type: object
|
||||
desc: Login result with access_token, id_token, refresh_token, expires_in, redirect, etc.
|
||||
|
||||
- name: revoke
|
||||
desc: Revoke an OTP code, making it no longer usable
|
||||
args:
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: The OTP code to revoke
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
12
openapi/user/doc.go
Normal file
12
openapi/user/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
264
openapi/user/doc.yml
Normal file
264
openapi/user/doc.yml
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
group: user
|
||||
type: process
|
||||
entries:
|
||||
# Profile
|
||||
- name: profile.get
|
||||
desc: Get the current user's profile information
|
||||
args:
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Optional flags: {team: bool, member: bool, type: bool} to include team, member, or type info"
|
||||
return:
|
||||
type: object
|
||||
desc: User profile data in OIDC format with optional team/member/type info
|
||||
|
||||
- name: profile.update
|
||||
desc: Update the current user's profile information
|
||||
args:
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Profile fields to update (name, given_name, family_name, nickname, picture, gender, locale, theme, metadata, etc.)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with user_id and message"
|
||||
|
||||
# Team Management
|
||||
- name: team.list
|
||||
desc: List teams owned by the current user with pagination and filtering
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "Query parameters: {status, name, page, pagesize}"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated team list with data array and pagination info
|
||||
|
||||
- name: team.get
|
||||
desc: Get details of a specific team the current user is a member of
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID to retrieve
|
||||
return:
|
||||
type: object
|
||||
desc: Team details including name, description, logo, owner_id, status, settings
|
||||
|
||||
- name: team.create
|
||||
desc: Create a new team with the current user as owner
|
||||
args:
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Team data: {name, description, settings, ...}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with team_id of the created team"
|
||||
|
||||
- name: team.update
|
||||
desc: Update an existing team owned by the current user
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID to update
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Fields to update: {name, description, settings, ...}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
|
||||
- name: team.delete
|
||||
desc: Delete a team owned by the current user (removes all members first)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID to delete
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
|
||||
# Team Member Management
|
||||
- name: member.list
|
||||
desc: List members of a team with advanced filtering and pagination
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "Query parameters: {page, pagesize, status, member_type, role_id, email, display_name, order, fields, locale}"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated member list with data array and pagination info
|
||||
|
||||
- name: member.get
|
||||
desc: Get details of a specific team member
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: Member ID (business key)
|
||||
return:
|
||||
type: object
|
||||
desc: Member details including role, status, display_name, robot config, etc.
|
||||
|
||||
- name: member.update
|
||||
desc: Update a team member (owner only, for role/status changes)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: Member ID (business key)
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Fields to update: {role_id, status, settings, last_activity}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
|
||||
- name: member.profile.get
|
||||
desc: Get a team member's profile (display_name, bio, avatar, email)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: userID
|
||||
type: string
|
||||
required: true
|
||||
desc: "User ID of the member (not member_id)"
|
||||
return:
|
||||
type: object
|
||||
desc: Member profile data with user_id, team_id, display_name, bio, avatar, email
|
||||
|
||||
- name: member.profile.update
|
||||
desc: Update a team member's own profile (display_name, bio, avatar, email)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: userID
|
||||
type: string
|
||||
required: true
|
||||
desc: "User ID of the member (not member_id)"
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Profile fields to update: {display_name, bio, avatar, email}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with user_id and message"
|
||||
|
||||
- name: member.delete
|
||||
desc: Remove a member from a team (owner only)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: memberID
|
||||
type: string
|
||||
required: true
|
||||
desc: Member ID (business key)
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
|
||||
# Team Invitation Management
|
||||
- name: team.invitation.list
|
||||
desc: List pending invitations for a team with pagination
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: "Query parameters: {status, page, pagesize}"
|
||||
return:
|
||||
type: object
|
||||
desc: Paginated invitation list with data array and pagination info
|
||||
|
||||
- name: team.invitation.get
|
||||
desc: Get details of a specific team invitation
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: invitationID
|
||||
type: string
|
||||
required: true
|
||||
desc: Invitation ID (business key)
|
||||
return:
|
||||
type: object
|
||||
desc: Invitation details including status, role, invited_by, expiry, etc.
|
||||
|
||||
- name: team.invitation.create
|
||||
desc: Create a new team invitation (owner only)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: "Invitation data: {user_id, email, member_type, role_id, message, expiry, settings}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with invitation_id"
|
||||
|
||||
- name: team.invitation.resend
|
||||
desc: Resend a pending team invitation with a new token and extended expiry
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: invitationID
|
||||
type: string
|
||||
required: true
|
||||
desc: Invitation ID (business key)
|
||||
- name: locale
|
||||
type: string
|
||||
required: false
|
||||
desc: "Locale for email template (default: \"en\")"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
|
||||
- name: team.invitation.delete
|
||||
desc: Cancel a pending team invitation (owner only)
|
||||
args:
|
||||
- name: teamID
|
||||
type: string
|
||||
required: true
|
||||
desc: Team ID
|
||||
- name: invitationID
|
||||
type: string
|
||||
required: true
|
||||
desc: Invitation ID (business key)
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with message"
|
||||
17
pipe/doc.go
Normal file
17
pipe/doc.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package pipe
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
//go:embed doc_pipes.yml
|
||||
var docPipesYAML []byte
|
||||
|
||||
func init() {
|
||||
doc.LoadYAML(docYAML)
|
||||
doc.LoadYAML(docPipesYAML)
|
||||
}
|
||||
96
pipe/doc.yml
Normal file
96
pipe/doc.yml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
group: pipe
|
||||
type: process
|
||||
entries:
|
||||
- name: run
|
||||
desc: Run a loaded pipeline by its registered ID
|
||||
args:
|
||||
- name: pipeId
|
||||
type: string
|
||||
required: true
|
||||
desc: Registered pipeline ID
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the pipeline execution"
|
||||
return:
|
||||
type: any
|
||||
desc: Pipeline execution result
|
||||
|
||||
- name: create
|
||||
desc: Create a new pipeline from a DSL string and run it immediately
|
||||
args:
|
||||
- name: dsl
|
||||
type: string
|
||||
required: true
|
||||
desc: Pipeline DSL definition as a YAML/JSON string
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the pipeline execution"
|
||||
return:
|
||||
type: any
|
||||
desc: Pipeline execution result
|
||||
|
||||
- name: createwith
|
||||
desc: Create a new pipeline from DSL with global data and run it immediately
|
||||
args:
|
||||
- name: dsl
|
||||
type: string
|
||||
required: true
|
||||
desc: Pipeline DSL definition as a YAML/JSON string
|
||||
- name: global
|
||||
type: object
|
||||
required: true
|
||||
desc: Global data map merged with process global context
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the pipeline execution"
|
||||
return:
|
||||
type: any
|
||||
desc: Pipeline execution result
|
||||
|
||||
- name: resume
|
||||
desc: Resume a paused pipeline context by its context ID
|
||||
args:
|
||||
- name: contextId
|
||||
type: string
|
||||
required: true
|
||||
desc: Pipeline context ID to resume
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the resumed pipeline"
|
||||
return:
|
||||
type: any
|
||||
desc: Resumed pipeline execution result
|
||||
|
||||
- name: resumewith
|
||||
desc: Resume a paused pipeline context with additional global data
|
||||
args:
|
||||
- name: contextId
|
||||
type: string
|
||||
required: true
|
||||
desc: Pipeline context ID to resume
|
||||
- name: global
|
||||
type: object
|
||||
required: true
|
||||
desc: Global data map merged with process global context
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the resumed pipeline"
|
||||
return:
|
||||
type: any
|
||||
desc: Resumed pipeline execution result
|
||||
|
||||
- name: close
|
||||
desc: Close and clean up a pipeline context
|
||||
args:
|
||||
- name: contextId
|
||||
type: string
|
||||
required: true
|
||||
desc: Pipeline context ID to close
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
13
pipe/doc_pipes.yml
Normal file
13
pipe/doc_pipes.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
group: pipes
|
||||
type: process
|
||||
entries:
|
||||
- name: "*"
|
||||
desc: "Run a loaded pipeline by ID. Called as pipes.<pipe_id> with the pipe ID as the process name suffix"
|
||||
args:
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Variable arguments passed to the pipeline execution"
|
||||
return:
|
||||
type: any
|
||||
desc: Pipeline execution result
|
||||
11
rss/doc.go
Normal file
11
rss/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package rss
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
66
rss/doc.yml
Normal file
66
rss/doc.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
group: rss
|
||||
type: process
|
||||
desc: "RSS/Atom feed parsing, validation, building, discovery, and fetching processes"
|
||||
entries:
|
||||
- name: parse
|
||||
desc: Parse an RSS 2.0 or Atom 1.0 XML string into a unified Feed object with auto-format detection and podcast metadata extraction
|
||||
args:
|
||||
- name: data
|
||||
type: string
|
||||
required: true
|
||||
desc: "Feed XML string to parse"
|
||||
return:
|
||||
type: object
|
||||
desc: "Feed object with format, title, link, description, language, updated, items (array), and podcast (object or null) fields"
|
||||
|
||||
- name: validate
|
||||
desc: Check whether a string is a valid RSS 2.0 or Atom 1.0 feed
|
||||
args:
|
||||
- name: data
|
||||
type: string
|
||||
required: true
|
||||
desc: "Feed XML string to validate"
|
||||
return:
|
||||
type: any
|
||||
desc: "True (bool) if valid; error description string if invalid"
|
||||
|
||||
- name: discover
|
||||
desc: Extract feed URLs from HTML, Markdown, or plain text content using regex-based detection (no network requests)
|
||||
args:
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: "Text content to scan for feed URLs"
|
||||
return:
|
||||
type: array
|
||||
desc: "Array of FeedLink objects with url, title, and type fields"
|
||||
|
||||
- name: build
|
||||
desc: Generate an XML feed document from a Feed object
|
||||
args:
|
||||
- name: feed
|
||||
type: object
|
||||
required: true
|
||||
desc: "Feed object (same structure as rss.parse output)"
|
||||
- name: format
|
||||
type: string
|
||||
required: false
|
||||
desc: "Output format: \"rss\" (default) or \"atom\""
|
||||
return:
|
||||
type: string
|
||||
desc: "XML feed document string"
|
||||
|
||||
- name: fetch
|
||||
desc: Fetch a remote RSS/Atom feed by URL and return the parsed Feed with HTTP metadata for conditional polling
|
||||
args:
|
||||
- name: url
|
||||
type: string
|
||||
required: true
|
||||
desc: "Feed URL to fetch"
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Fetch options: user_agent (string), timeout (number, seconds), etag (string, for If-None-Match), last_modified (string, for If-Modified-Since)"
|
||||
return:
|
||||
type: object
|
||||
desc: "FetchResult with feed (object or null), status_code (number), etag (string), last_modified (string), and not_modified (bool) fields"
|
||||
12
seed/doc.go
Normal file
12
seed/doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package seed
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
21
seed/doc.yml
Normal file
21
seed/doc.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
group: seeds
|
||||
type: process
|
||||
entries:
|
||||
- name: import
|
||||
desc: Import seed data from a file (CSV, XLSX, JSON, JSONC/Yao) into a model table
|
||||
args:
|
||||
- name: filename
|
||||
type: string
|
||||
required: true
|
||||
desc: "Seed file name relative to the seeds directory (e.g. \"users.csv\", \"data.xlsx\", \"records.json\")"
|
||||
- name: modelName
|
||||
type: string
|
||||
required: true
|
||||
desc: Target model name to import data into
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Import options: {chunk_size: number, duplicate: \"ignore\"|\"error\"|\"update\"|\"abort\", mode: \"batch\"|\"each\"}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Import result: {total, success, failure, ignore, errors: [{row, message, code, data}]}"
|
||||
11
sitemap/doc.go
Normal file
11
sitemap/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package sitemap
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
103
sitemap/doc.yml
Normal file
103
sitemap/doc.yml
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
group: sitemap
|
||||
type: process
|
||||
desc: "Sitemap parsing, validation, discovery, fetching, and streaming build processes"
|
||||
entries:
|
||||
- name: parse
|
||||
desc: Parse a sitemap XML string into a unified ParseResult, auto-detecting urlset or sitemapindex format
|
||||
args:
|
||||
- name: data
|
||||
type: string
|
||||
required: true
|
||||
desc: "Sitemap XML string to parse"
|
||||
return:
|
||||
type: object
|
||||
desc: "ParseResult with type (\"urlset\" or \"sitemapindex\"), urls (array of URL objects), and sitemaps (array of SitemapEntry objects)"
|
||||
|
||||
- name: validate
|
||||
desc: Check whether a string is a valid sitemap XML document
|
||||
args:
|
||||
- name: data
|
||||
type: string
|
||||
required: true
|
||||
desc: "Sitemap XML string to validate"
|
||||
return:
|
||||
type: any
|
||||
desc: "True (bool) if valid; error description string if invalid"
|
||||
|
||||
- name: parserobo
|
||||
desc: Extract sitemap URLs from robots.txt content (pure text parsing, no HTTP)
|
||||
args:
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: "robots.txt content"
|
||||
return:
|
||||
type: array
|
||||
desc: "Array of sitemap URL strings"
|
||||
|
||||
- name: discover
|
||||
desc: Discover sitemap files for a domain via robots.txt and well-known paths, recursively expanding sitemapindex files
|
||||
args:
|
||||
- name: domain
|
||||
type: string
|
||||
required: true
|
||||
desc: "Domain to discover sitemaps for (e.g. \"example.com\")"
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Options: user_agent (string), timeout (number, seconds)"
|
||||
return:
|
||||
type: object
|
||||
desc: "DiscoverResult with sitemaps (array of SitemapLink objects with url, source, url_count, content_size, encoding, last_modified, etag) and total_urls (number)"
|
||||
|
||||
- name: fetch
|
||||
desc: Fetch and parse URLs from sitemaps for a domain with pagination support
|
||||
args:
|
||||
- name: domain
|
||||
type: string
|
||||
required: true
|
||||
desc: "Domain to fetch sitemaps for (e.g. \"example.com\")"
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Options: offset (number), limit (number, default/max 50000), user_agent (string), timeout (number, seconds)"
|
||||
return:
|
||||
type: object
|
||||
desc: "FetchResult with urls (array of URL objects with loc, lastmod, changefreq, priority, images, videos, news) and total (number)"
|
||||
|
||||
- name: build.open
|
||||
desc: Open a new streaming sitemap writer and return a UUID handle
|
||||
args:
|
||||
- name: options
|
||||
type: object
|
||||
required: true
|
||||
desc: "Build options: dir (string, output directory path, required), base_url (string, URL prefix for index references, required if multiple files)"
|
||||
return:
|
||||
type: string
|
||||
desc: "UUID handle string for use with build.write and build.close"
|
||||
|
||||
- name: build.write
|
||||
desc: Write a batch of URLs to an open sitemap writer, automatically splitting at 50,000 URLs per file
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: "UUID handle from build.open"
|
||||
- name: urls
|
||||
type: array
|
||||
required: true
|
||||
desc: "Array of URL objects with loc (required), lastmod, changefreq, priority, images, videos, and news fields"
|
||||
return:
|
||||
type: "null"
|
||||
desc: "Returns null on success"
|
||||
|
||||
- name: build.close
|
||||
desc: Finalize the sitemap output, generate a sitemapindex if needed, and clean up the handle
|
||||
args:
|
||||
- name: handle
|
||||
type: string
|
||||
required: true
|
||||
desc: "UUID handle from build.open"
|
||||
return:
|
||||
type: object
|
||||
desc: "BuildResult with index (string, sitemap_index.xml path or empty), files (array of file paths), and total (number of URLs written)"
|
||||
11
sui/api/doc.go
Normal file
11
sui/api/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
772
sui/api/doc.yml
Normal file
772
sui/api/doc.yml
Normal file
|
|
@ -0,0 +1,772 @@
|
|||
group: sui
|
||||
type: process
|
||||
entries:
|
||||
- name: setting
|
||||
desc: Get the SUI instance settings
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
return:
|
||||
type: object
|
||||
desc: SUI setting object
|
||||
|
||||
- name: render
|
||||
desc: "[Internal] Render an HTML fragment by route. Do not use in scripts or flows, use template.render instead"
|
||||
args:
|
||||
- name: context
|
||||
type: external
|
||||
required: true
|
||||
desc: Gin request context (*gin.Context)
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Render payload containing name (render target), data (template data), and option (render options)"
|
||||
return:
|
||||
type: string
|
||||
desc: Rendered HTML string
|
||||
|
||||
- name: run
|
||||
desc: "[Internal] Execute a page backend script method. Do not use in scripts or flows"
|
||||
args:
|
||||
- name: context
|
||||
type: external
|
||||
required: true
|
||||
desc: Gin request context (*gin.Context)
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Execution payload with method (string, required) and args (array, optional)"
|
||||
return:
|
||||
type: any
|
||||
desc: Script execution result
|
||||
|
||||
- name: template.get
|
||||
desc: List all templates in the SUI instance
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
return:
|
||||
type: array
|
||||
desc: Array of template objects
|
||||
|
||||
- name: template.find
|
||||
desc: Find a template by ID
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: object
|
||||
desc: Template object
|
||||
|
||||
- name: template.asset
|
||||
desc: Get a template asset file content and MIME type
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: path
|
||||
type: string
|
||||
required: true
|
||||
desc: Asset file path within the template
|
||||
- name: width
|
||||
type: number
|
||||
required: false
|
||||
desc: Optional image width for resizing
|
||||
- name: height
|
||||
type: number
|
||||
required: false
|
||||
desc: Optional image height for resizing
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with content (asset data) and type (MIME type)"
|
||||
|
||||
- name: template.assetupload
|
||||
desc: Upload an asset file to a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: file
|
||||
type: any
|
||||
required: true
|
||||
desc: "File data: *gin.Context (form upload with field 'file') or base64-encoded string"
|
||||
- name: filename
|
||||
type: string
|
||||
required: false
|
||||
desc: "Filename when uploading as base64 string (default: file.png)"
|
||||
return:
|
||||
type: any
|
||||
desc: "Upload result: object with data and header (form upload), or file path string (base64)"
|
||||
|
||||
- name: template.render
|
||||
desc: Compile and render a template page to HTML
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: source
|
||||
type: string
|
||||
required: true
|
||||
desc: Page source path
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: Template data for rendering
|
||||
- name: option
|
||||
type: object
|
||||
required: false
|
||||
desc: "Render options with theme, locale, and data fields"
|
||||
- name: request
|
||||
type: object
|
||||
required: false
|
||||
desc: Override request object for rendering context
|
||||
return:
|
||||
type: string
|
||||
desc: Rendered HTML string
|
||||
|
||||
- name: locale.get
|
||||
desc: Get available locales for a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of locale select options, or empty array if none
|
||||
|
||||
- name: theme.get
|
||||
desc: Get available themes for a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of theme objects
|
||||
|
||||
- name: block.get
|
||||
desc: List all blocks in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of block objects
|
||||
|
||||
- name: block.find
|
||||
desc: Get the source code of a block by ID
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: blockId
|
||||
type: string
|
||||
required: true
|
||||
desc: Block ID (trailing .js suffix is stripped)
|
||||
return:
|
||||
type: string
|
||||
desc: Block source code
|
||||
|
||||
- name: block.Media
|
||||
desc: Get the media asset of a block
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: blockId
|
||||
type: string
|
||||
required: true
|
||||
desc: Block ID (trailing .js suffix is stripped)
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with content (media data) and type (MIME type)"
|
||||
|
||||
- name: block.export
|
||||
desc: Export block layout items from a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of block layout items
|
||||
|
||||
- name: component.get
|
||||
desc: List all components in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of component objects
|
||||
|
||||
- name: component.find
|
||||
desc: Get the source code of a component by ID
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: componentId
|
||||
type: string
|
||||
required: true
|
||||
desc: Component ID (trailing .js suffix is stripped)
|
||||
return:
|
||||
type: string
|
||||
desc: Component source code
|
||||
|
||||
- name: page.tree
|
||||
desc: Get the page tree under a route
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: false
|
||||
desc: "Route path (defaults to /index if empty)"
|
||||
return:
|
||||
type: object
|
||||
desc: Page tree structure
|
||||
|
||||
- name: page.get
|
||||
desc: List all pages in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
return:
|
||||
type: array
|
||||
desc: Array of page objects
|
||||
|
||||
- name: page.save
|
||||
desc: Save a page source to the given route
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: source
|
||||
type: any
|
||||
required: true
|
||||
desc: "Page source: RequestSource object, *gin.Context, JSON string, or map"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.savetemp
|
||||
desc: Temporarily save a page source (requires source.uid)
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: source
|
||||
type: any
|
||||
required: true
|
||||
desc: "Page source with uid field required: RequestSource object, *gin.Context, JSON string, or map"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.create
|
||||
desc: Create a new empty page and optionally save initial source
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: source
|
||||
type: any
|
||||
required: false
|
||||
desc: "Optional initial page source to save"
|
||||
- name: payload
|
||||
type: object
|
||||
required: false
|
||||
desc: "Optional payload with route (override) and title fields"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.duplicate
|
||||
desc: Duplicate a page to a new route
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: sourceRoute
|
||||
type: string
|
||||
required: true
|
||||
desc: Source page route to copy from
|
||||
- name: payload
|
||||
type: object
|
||||
required: false
|
||||
desc: "Object with route (required, target path) and title (optional)"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.rename
|
||||
desc: Rename (move) a page to a new route
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: sourceRoute
|
||||
type: string
|
||||
required: true
|
||||
desc: Current page route
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Object with route field (required, new route path)"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.remove
|
||||
desc: Remove a page from the template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path to remove
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: page.exist
|
||||
desc: Check if a page exists at the given route
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path to check
|
||||
return:
|
||||
type: bool
|
||||
desc: True if the page exists
|
||||
|
||||
- name: page.asset
|
||||
desc: Get the CSS or JS/TS asset content of a page
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: file
|
||||
type: string
|
||||
required: true
|
||||
desc: "Asset file path (.css, .js, or .ts extension)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with content (asset data) and type (MIME type)"
|
||||
|
||||
- name: editor.render
|
||||
desc: Render a page for the editor view
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
return:
|
||||
type: any
|
||||
desc: Editor render result
|
||||
|
||||
- name: editor.source
|
||||
desc: Get page source code by kind for the editor
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: kind
|
||||
type: string
|
||||
required: true
|
||||
desc: "Source kind: page, style, script, or data"
|
||||
return:
|
||||
type: any
|
||||
desc: Source code content for the specified kind
|
||||
|
||||
- name: editor.renderaftersavetemp
|
||||
desc: Temporarily save page source then render for the editor
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: source
|
||||
type: any
|
||||
required: true
|
||||
desc: Page source to save temporarily (requires uid)
|
||||
- name: extra
|
||||
type: any
|
||||
required: false
|
||||
desc: Additional arguments passed to the editor render
|
||||
return:
|
||||
type: any
|
||||
desc: Editor render result
|
||||
|
||||
- name: editor.sourceaftersavetemp
|
||||
desc: Temporarily save page source then get editor source
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: source
|
||||
type: any
|
||||
required: true
|
||||
desc: Page source to save temporarily (requires uid)
|
||||
- name: extra
|
||||
type: any
|
||||
required: false
|
||||
desc: Additional arguments passed to the editor source
|
||||
return:
|
||||
type: any
|
||||
desc: Source code content for the specified kind
|
||||
|
||||
- name: media.search
|
||||
desc: Search media assets in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: driver
|
||||
type: string
|
||||
required: true
|
||||
desc: "Media driver name (e.g., local)"
|
||||
- name: query
|
||||
type: any
|
||||
required: false
|
||||
desc: "Search query parameters: map or url.Values. Supports page, pagesize, and template fields"
|
||||
return:
|
||||
type: any
|
||||
desc: Media search results
|
||||
|
||||
- name: preview.render
|
||||
desc: Render a page for preview
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: referer
|
||||
type: string
|
||||
required: false
|
||||
desc: Optional referer URL
|
||||
return:
|
||||
type: string
|
||||
desc: Preview HTML string
|
||||
|
||||
- name: build.all
|
||||
desc: Build all pages in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Build options with ssr (bool), asset_root (string), and data (object) fields"
|
||||
return:
|
||||
type: any
|
||||
desc: Array of warnings if any, otherwise null
|
||||
|
||||
- name: build.page
|
||||
desc: Build a single page in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Build options with ssr (bool) and asset_root (string) fields"
|
||||
- name: extra
|
||||
type: any
|
||||
required: false
|
||||
desc: Reserved
|
||||
- name: data
|
||||
type: object
|
||||
required: false
|
||||
desc: Additional data for the build
|
||||
return:
|
||||
type: any
|
||||
desc: Array of warnings if any, otherwise null
|
||||
|
||||
- name: trans.all
|
||||
desc: Extract and translate all pages in a template
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Translation options with ssr (bool), asset_root (string), and data (object) fields"
|
||||
return:
|
||||
type: any
|
||||
desc: Array of warnings if any, otherwise null
|
||||
|
||||
- name: trans.page
|
||||
desc: Extract and translate a single page
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: route
|
||||
type: string
|
||||
required: true
|
||||
desc: Page route path
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Translation options with ssr (bool) and asset_root (string) fields"
|
||||
- name: extra
|
||||
type: any
|
||||
required: false
|
||||
desc: Reserved
|
||||
- name: data
|
||||
type: object
|
||||
required: false
|
||||
desc: Additional data for the translation
|
||||
return:
|
||||
type: any
|
||||
desc: Array of warnings if any, otherwise null
|
||||
|
||||
- name: sync.assetfile
|
||||
desc: "[Deprecated] Sync a single asset file in a template"
|
||||
args:
|
||||
- name: instance
|
||||
type: string
|
||||
required: true
|
||||
desc: SUI instance name
|
||||
- name: templateId
|
||||
type: string
|
||||
required: true
|
||||
desc: Template ID
|
||||
- name: filename
|
||||
type: string
|
||||
required: true
|
||||
desc: Asset filename to sync
|
||||
- name: option
|
||||
type: object
|
||||
required: true
|
||||
desc: "Sync options with ssr (bool), asset_root (string), and data (object) fields"
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null on success
|
||||
|
||||
- name: types.QueryParam
|
||||
desc: "[Deprecated] Convert various input formats to a query parameter structure"
|
||||
args:
|
||||
- name: input
|
||||
type: any
|
||||
required: true
|
||||
desc: "Input data: url.Values, map[string][]string, map[string]interface{}, or any serializable value"
|
||||
return:
|
||||
type: any
|
||||
desc: Converted query parameter structure
|
||||
11
utils/doc.go
Normal file
11
utils/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
377
utils/doc.yml
Normal file
377
utils/doc.yml
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
group: utils
|
||||
type: process
|
||||
entries:
|
||||
# throw
|
||||
- name: throw.Forbidden
|
||||
desc: Throw a 403 Forbidden exception
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: false
|
||||
desc: "Error message (default: \"Access denied\")"
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: throw.Unauthorized
|
||||
desc: Throw a 401 Unauthorized exception
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: false
|
||||
desc: "Error message (default: \"Authentication required\")"
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: throw.NotFound
|
||||
desc: Throw a 404 Not Found exception
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: false
|
||||
desc: "Error message (default: \"Resource not found\")"
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: throw.BadRequest
|
||||
desc: Throw a 400 Bad Request exception
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: false
|
||||
desc: "Error message (default: \"Bad Request\")"
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: throw.InternalError
|
||||
desc: Throw a 500 Internal Server Error exception
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: false
|
||||
desc: "Error message (default: \"Internal Error\")"
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
- name: throw.Exception
|
||||
desc: Throw a custom exception with specified message and HTTP status code
|
||||
args:
|
||||
- name: message
|
||||
type: string
|
||||
required: true
|
||||
desc: Error message
|
||||
- name: code
|
||||
type: number
|
||||
required: true
|
||||
desc: HTTP status code
|
||||
return:
|
||||
type: void
|
||||
desc: Does not return; throws exception
|
||||
|
||||
# fmt
|
||||
- name: fmt.Printf
|
||||
desc: Print formatted output to stdout
|
||||
args:
|
||||
- name: format
|
||||
type: string
|
||||
required: true
|
||||
desc: Format string (Go fmt style)
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: Values to format (variadic)
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
- name: fmt.ColorPrintf
|
||||
desc: Print colored formatted output to stdout
|
||||
args:
|
||||
- name: color
|
||||
type: string
|
||||
required: true
|
||||
desc: "Color name: red, green, yellow, blue, magenta, cyan, white, black, hired, higreen, etc."
|
||||
- name: format
|
||||
type: string
|
||||
required: true
|
||||
desc: Format string (Go fmt style)
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: Values to format (variadic)
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
|
||||
# str
|
||||
- name: str.Join
|
||||
desc: Join array elements into a string with a separator
|
||||
args:
|
||||
- name: array
|
||||
type: array
|
||||
required: true
|
||||
desc: Array of values to join
|
||||
- name: separator
|
||||
type: string
|
||||
required: true
|
||||
desc: Separator string
|
||||
return:
|
||||
type: string
|
||||
desc: Joined string
|
||||
|
||||
- name: str.JoinPath
|
||||
desc: Join path segments into a file path
|
||||
args:
|
||||
- name: paths
|
||||
type: string
|
||||
required: true
|
||||
desc: Path segments to join (variadic, minimum 2 segments required)
|
||||
return:
|
||||
type: string
|
||||
desc: Joined file path
|
||||
|
||||
- name: str.UUID
|
||||
desc: Generate a new UUID v4 string
|
||||
args: []
|
||||
return:
|
||||
type: string
|
||||
desc: UUID string (e.g. "550e8400-e29b-41d4-a716-446655440000")
|
||||
|
||||
- name: str.Pinyin
|
||||
desc: Convert Chinese characters to Pinyin
|
||||
args:
|
||||
- name: text
|
||||
type: string
|
||||
required: true
|
||||
desc: Chinese text to convert
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Options: {tone: bool|\"mark\"|\"number\"|\"none\", heteronym: bool, separator: string}"
|
||||
return:
|
||||
type: string
|
||||
desc: Pinyin string
|
||||
|
||||
# tree
|
||||
- name: tree.Flatten
|
||||
desc: Flatten a tree structure into a flat array
|
||||
args:
|
||||
- name: array
|
||||
type: array
|
||||
required: true
|
||||
desc: Tree-structured array to flatten
|
||||
- name: options
|
||||
type: object
|
||||
required: false
|
||||
desc: "Options: {primary: \"id\", children: \"children\", parent: \"parent\"}"
|
||||
return:
|
||||
type: array
|
||||
desc: Flat array with parent references
|
||||
|
||||
# now / time
|
||||
- name: now.Time
|
||||
desc: Get the current time as a string
|
||||
args: []
|
||||
return:
|
||||
type: string
|
||||
desc: "Current time in HH:MM:SS format (e.g. \"15:04:05\")"
|
||||
|
||||
- name: now.Date
|
||||
desc: Get the current date as a string
|
||||
args: []
|
||||
return:
|
||||
type: string
|
||||
desc: "Current date in YYYY-MM-DD format (e.g. \"2006-01-02\")"
|
||||
|
||||
- name: now.DateTime
|
||||
desc: Get the current date and time as a string
|
||||
args: []
|
||||
return:
|
||||
type: string
|
||||
desc: "Current datetime in YYYY-MM-DD HH:MM:SS format"
|
||||
|
||||
- name: now.Timestamp
|
||||
desc: Get the current Unix timestamp in seconds
|
||||
args: []
|
||||
return:
|
||||
type: number
|
||||
desc: Unix timestamp in seconds
|
||||
|
||||
- name: now.Timestampms
|
||||
desc: Get the current Unix timestamp in milliseconds
|
||||
args: []
|
||||
return:
|
||||
type: number
|
||||
desc: Unix timestamp in milliseconds
|
||||
|
||||
# url
|
||||
- name: url.ParseQuery
|
||||
desc: Parse a URL query string into key-value pairs
|
||||
args:
|
||||
- name: queryString
|
||||
type: string
|
||||
required: true
|
||||
desc: "URL query string (e.g. \"key1=val1&key2=val2\")"
|
||||
return:
|
||||
type: object
|
||||
desc: Parsed query parameters as map of string to string array
|
||||
|
||||
- name: url.QueryParam
|
||||
desc: Convert URL values or map to QueryParam object
|
||||
args:
|
||||
- name: values
|
||||
type: any
|
||||
required: true
|
||||
desc: "URL values: url.Values, map[string][]string, or map[string]interface{}"
|
||||
return:
|
||||
type: object
|
||||
desc: QueryParam object
|
||||
|
||||
- name: url.ParseURL
|
||||
desc: Parse a URL string into its components
|
||||
args:
|
||||
- name: url
|
||||
type: string
|
||||
required: true
|
||||
desc: URL string to parse
|
||||
return:
|
||||
type: object
|
||||
desc: "Parsed URL with scheme, host, domain, path, port, query, and url fields"
|
||||
|
||||
# json
|
||||
- name: json.Validate
|
||||
desc: "[Warning: under development] Validate JSON data against rules"
|
||||
args:
|
||||
- name: data
|
||||
type: object
|
||||
required: true
|
||||
desc: JSON data to validate
|
||||
- name: rules
|
||||
type: array
|
||||
required: true
|
||||
desc: "Validation rules (e.g. [{\"haskey\": \"fieldName\"}])"
|
||||
return:
|
||||
type: bool
|
||||
desc: True if validation passes, false otherwise
|
||||
|
||||
# jsonschema
|
||||
- name: jsonschema.ValidateSchema
|
||||
desc: Validate a JSON Schema structure
|
||||
args:
|
||||
- name: schema
|
||||
type: any
|
||||
required: true
|
||||
desc: "JSON Schema to validate (map, string, or bytes)"
|
||||
return:
|
||||
type: any
|
||||
desc: "Null if valid, error message string if invalid"
|
||||
|
||||
- name: jsonschema.Validate
|
||||
desc: Validate data against a JSON Schema
|
||||
args:
|
||||
- name: schema
|
||||
type: any
|
||||
required: true
|
||||
desc: "JSON Schema (map, string, or bytes)"
|
||||
- name: data
|
||||
type: any
|
||||
required: true
|
||||
desc: Data to validate against the schema
|
||||
return:
|
||||
type: any
|
||||
desc: "Null if valid, error message string if invalid"
|
||||
|
||||
# captcha (0.10.5+)
|
||||
- name: captcha.Generate
|
||||
desc: Generate a captcha image/audio with customizable options
|
||||
args:
|
||||
- name: options
|
||||
type: object
|
||||
required: true
|
||||
desc: "Options: {width, height, length, type, lang, background}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with id and content (base64 image/audio)"
|
||||
|
||||
- name: captcha.Validate
|
||||
desc: Validate a captcha code
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Captcha ID returned by Generate
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: User-entered captcha code
|
||||
return:
|
||||
type: bool
|
||||
desc: True if valid; throws exception if invalid
|
||||
|
||||
- name: captcha.Get
|
||||
desc: Get the captcha code by ID (for testing purposes)
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: Captcha ID
|
||||
return:
|
||||
type: string
|
||||
desc: The captcha answer code
|
||||
|
||||
# otp (0.10.5+)
|
||||
- name: otp.Generate
|
||||
desc: Generate a one-time password (OTP) code
|
||||
args:
|
||||
- name: options
|
||||
type: object
|
||||
required: true
|
||||
desc: "Options: {length: number, expiration: number (seconds), type: string}"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with id and code"
|
||||
|
||||
- name: otp.Validate
|
||||
desc: Validate a one-time password (OTP) code
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: OTP ID returned by Generate
|
||||
- name: code
|
||||
type: string
|
||||
required: true
|
||||
desc: OTP code to validate
|
||||
- name: clear
|
||||
type: bool
|
||||
required: false
|
||||
desc: "Whether to clear the OTP after validation (default: true)"
|
||||
return:
|
||||
type: bool
|
||||
desc: True if valid; throws exception if invalid or expired
|
||||
|
||||
- name: otp.Get
|
||||
desc: Get the OTP code by ID (for testing purposes)
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: OTP ID
|
||||
return:
|
||||
type: string
|
||||
desc: The OTP code
|
||||
|
||||
- name: otp.Delete
|
||||
desc: Delete an OTP code by ID
|
||||
args:
|
||||
- name: id
|
||||
type: string
|
||||
required: true
|
||||
desc: OTP ID to delete
|
||||
return:
|
||||
type: "null"
|
||||
desc: Returns null
|
||||
11
widgets/app/doc.go
Normal file
11
widgets/app/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
84
widgets/app/doc.yml
Normal file
84
widgets/app/doc.yml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
group: yao.app
|
||||
type: process
|
||||
desc: "Application widget processes for settings, menus, icons, setup, and services"
|
||||
entries:
|
||||
- name: setting
|
||||
desc: Return the application DSL settings with i18n translation applied
|
||||
args:
|
||||
- name: payload
|
||||
type: object
|
||||
required: false
|
||||
desc: "Optional object with sid (session ID), lang (language code e.g. \"en-us\"), and now (unix timestamp)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Application DSL object with name, version, description, theme, lang, menu, optional, sid, logo, and favicon fields"
|
||||
|
||||
- name: xgen
|
||||
desc: Return the merged Xgen settings including app config, login config, agent config, tools, and knowledge base
|
||||
args:
|
||||
- name: payload
|
||||
type: object
|
||||
required: false
|
||||
desc: "Optional object with sid (session ID), lang (language code e.g. \"en-us\"), and now (unix timestamp)"
|
||||
return:
|
||||
type: object
|
||||
desc: "Xgen settings object with name, description, version, yao, cui, theme, lang, mode, apiPrefix, token, optional, login, agent, tools, openapi, kb, logo, favicon, and sid fields"
|
||||
|
||||
- name: menu
|
||||
desc: Return the application menu list by delegating to the configured menu.process
|
||||
args:
|
||||
- name: args
|
||||
type: any
|
||||
required: false
|
||||
desc: "Arguments forwarded to the configured menu process"
|
||||
return:
|
||||
type: any
|
||||
desc: "Menu data returned by the configured menu process"
|
||||
|
||||
- name: icons
|
||||
desc: Return the content of an application icon file from the icons/ directory
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: "Icon filename (e.g. \"app.ico\", \"app.png\")"
|
||||
return:
|
||||
type: string
|
||||
desc: "Icon file content as string"
|
||||
|
||||
- name: setup
|
||||
desc: Run the application setup process and return home/admin URLs with translated settings
|
||||
args:
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Setup payload object; may include sid (session ID); include 'error' key to trigger a test error"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with home (string URL), admin (string URL), and setting (translated app DSL)"
|
||||
|
||||
- name: check
|
||||
desc: Run the application check process for setup validation
|
||||
args:
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Check payload object; include 'error' key to trigger a test error"
|
||||
return:
|
||||
type: "null"
|
||||
desc: "Returns null on success, throws exception on error"
|
||||
|
||||
- name: service
|
||||
desc: Call a named application service script method with arguments
|
||||
args:
|
||||
- name: name
|
||||
type: string
|
||||
required: true
|
||||
desc: "Service script name (resolves to __yao_service.<name> V8 script)"
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Object with method (string, required) and args (array, optional) fields"
|
||||
return:
|
||||
type: any
|
||||
desc: "Return value from the service method call"
|
||||
11
widgets/chart/doc.go
Normal file
11
widgets/chart/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package chart
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
62
widgets/chart/doc.yml
Normal file
62
widgets/chart/doc.yml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
group: yao.chart
|
||||
type: process
|
||||
entries:
|
||||
- name: setting
|
||||
desc: Get the setting configuration of a chart widget
|
||||
args:
|
||||
- name: chartId
|
||||
type: string
|
||||
required: true
|
||||
desc: Chart widget ID
|
||||
return:
|
||||
type: any
|
||||
desc: Chart setting from the configured action handler
|
||||
|
||||
- name: xgen
|
||||
desc: Get the Xgen UI configuration for a chart widget with permission filtering
|
||||
args:
|
||||
- name: chartId
|
||||
type: string
|
||||
required: true
|
||||
desc: Chart widget ID
|
||||
- name: data
|
||||
type: object
|
||||
required: false
|
||||
desc: Additional data for generating the configuration
|
||||
return:
|
||||
type: object
|
||||
desc: Xgen configuration object with permission-based field exclusions
|
||||
|
||||
- name: component
|
||||
desc: Execute a cloud component query within a chart widget
|
||||
args:
|
||||
- name: chartId
|
||||
type: string
|
||||
required: true
|
||||
desc: Chart widget ID
|
||||
- name: xpath
|
||||
type: string
|
||||
required: true
|
||||
desc: Component XPath (URL-encoded)
|
||||
- name: method
|
||||
type: string
|
||||
required: true
|
||||
desc: Component method name (URL-encoded)
|
||||
- name: query
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters for the component
|
||||
return:
|
||||
type: any
|
||||
desc: Component query execution result
|
||||
|
||||
- name: data
|
||||
desc: Get the data for a chart widget
|
||||
args:
|
||||
- name: chartId
|
||||
type: string
|
||||
required: true
|
||||
desc: Chart widget ID
|
||||
return:
|
||||
type: any
|
||||
desc: Chart data from the configured action handler
|
||||
11
widgets/component/doc.go
Normal file
11
widgets/component/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package component
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
24
widgets/component/doc.yml
Normal file
24
widgets/component/doc.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
group: yao.component
|
||||
type: process
|
||||
entries:
|
||||
- name: getoptions
|
||||
desc: Get select options by querying a model or query engine with configurable label/value mapping
|
||||
args:
|
||||
- name: params
|
||||
type: object
|
||||
required: true
|
||||
desc: Query parameters map for filtering results
|
||||
- name: props
|
||||
type: object
|
||||
required: true
|
||||
desc: "Component props containing a query object with engine, from, labelField, valueField, wheres, and other query configuration"
|
||||
return:
|
||||
type: array
|
||||
desc: "Array of option objects with label, value, and optional icon and color fields"
|
||||
|
||||
- name: selectoptions
|
||||
desc: "[Deprecated] Use yao.component.getoptions instead. Always throws a 400 error"
|
||||
args: []
|
||||
return:
|
||||
type: void
|
||||
desc: Never returns; always throws a deprecation error
|
||||
11
widgets/dashboard/doc.go
Normal file
11
widgets/dashboard/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package dashboard
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
62
widgets/dashboard/doc.yml
Normal file
62
widgets/dashboard/doc.yml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
group: yao.dashboard
|
||||
type: process
|
||||
entries:
|
||||
- name: setting
|
||||
desc: Get the setting configuration of a dashboard widget
|
||||
args:
|
||||
- name: dashboardId
|
||||
type: string
|
||||
required: true
|
||||
desc: Dashboard widget ID
|
||||
return:
|
||||
type: any
|
||||
desc: Dashboard setting from the configured action handler
|
||||
|
||||
- name: xgen
|
||||
desc: Get the Xgen UI configuration for a dashboard widget with permission filtering
|
||||
args:
|
||||
- name: dashboardId
|
||||
type: string
|
||||
required: true
|
||||
desc: Dashboard widget ID
|
||||
- name: data
|
||||
type: object
|
||||
required: false
|
||||
desc: Additional data for generating the configuration
|
||||
return:
|
||||
type: object
|
||||
desc: Xgen configuration object with permission-based field exclusions
|
||||
|
||||
- name: component
|
||||
desc: Execute a cloud component query within a dashboard widget
|
||||
args:
|
||||
- name: dashboardId
|
||||
type: string
|
||||
required: true
|
||||
desc: Dashboard widget ID
|
||||
- name: xpath
|
||||
type: string
|
||||
required: true
|
||||
desc: Component XPath (URL-encoded)
|
||||
- name: method
|
||||
type: string
|
||||
required: true
|
||||
desc: Component method name (URL-encoded)
|
||||
- name: query
|
||||
type: object
|
||||
required: false
|
||||
desc: Query parameters for the component
|
||||
return:
|
||||
type: any
|
||||
desc: Component query execution result
|
||||
|
||||
- name: data
|
||||
desc: Get the data for a dashboard widget
|
||||
args:
|
||||
- name: dashboardId
|
||||
type: string
|
||||
required: true
|
||||
desc: Dashboard widget ID
|
||||
return:
|
||||
type: any
|
||||
desc: Dashboard data from the configured action handler
|
||||
11
widgets/doc.go
Normal file
11
widgets/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
37
widgets/doc.yml
Normal file
37
widgets/doc.yml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
group: widget
|
||||
type: process
|
||||
entries:
|
||||
- name: apis
|
||||
desc: Get all loaded widget API definitions
|
||||
args: []
|
||||
return:
|
||||
type: any
|
||||
desc: Map of all registered widget APIs
|
||||
|
||||
- name: actions
|
||||
desc: Get all loaded widget action definitions
|
||||
args: []
|
||||
return:
|
||||
type: any
|
||||
desc: Map of all registered widget actions
|
||||
|
||||
- name: models
|
||||
desc: Get all loaded widget model definitions
|
||||
args: []
|
||||
return:
|
||||
type: any
|
||||
desc: Map of all registered widget models
|
||||
|
||||
- name: fields
|
||||
desc: Get all loaded widget field definitions
|
||||
args: []
|
||||
return:
|
||||
type: any
|
||||
desc: Map of all registered widget fields
|
||||
|
||||
- name: filters
|
||||
desc: Get all loaded widget filter definitions
|
||||
args: []
|
||||
return:
|
||||
type: any
|
||||
desc: Map of all registered widget filters
|
||||
11
widgets/expression/doc.go
Normal file
11
widgets/expression/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
32
widgets/expression/doc.yml
Normal file
32
widgets/expression/doc.yml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
group: yao.expression
|
||||
type: process
|
||||
entries:
|
||||
- name: selectoption
|
||||
desc: Convert input values into an array of label/value select options
|
||||
args:
|
||||
- name: input
|
||||
type: any
|
||||
required: true
|
||||
desc: "Comma-separated string, or array of strings/numbers/maps"
|
||||
- name: labelField
|
||||
type: string
|
||||
required: false
|
||||
desc: "Field name to use as label when input items are maps (default: name)"
|
||||
- name: valueField
|
||||
type: string
|
||||
required: false
|
||||
desc: "Field name to use as value when input items are maps (default: id)"
|
||||
return:
|
||||
type: array
|
||||
desc: Array of objects with label and value fields
|
||||
|
||||
- name: trimspace
|
||||
desc: Trim leading and trailing whitespace from a string
|
||||
args:
|
||||
- name: input
|
||||
type: string
|
||||
required: true
|
||||
desc: String to trim
|
||||
return:
|
||||
type: string
|
||||
desc: Trimmed string
|
||||
11
widgets/login/doc.go
Normal file
11
widgets/login/doc.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package login
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/yaoapp/gou/doc"
|
||||
)
|
||||
|
||||
//go:embed doc.yml
|
||||
var docYAML []byte
|
||||
|
||||
func init() { doc.LoadYAML(docYAML) }
|
||||
14
widgets/login/doc.yml
Normal file
14
widgets/login/doc.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
group: yao.login
|
||||
type: process
|
||||
desc: "Login widget processes for user authentication"
|
||||
entries:
|
||||
- name: admin
|
||||
desc: Authenticate an admin user with email or mobile, password, and captcha verification
|
||||
args:
|
||||
- name: payload
|
||||
type: object
|
||||
required: true
|
||||
desc: "Login payload with captcha.id (string), captcha.code (string), password (string), and either email (string) or mobile (string); optional sid (string) for session ID"
|
||||
return:
|
||||
type: object
|
||||
desc: "Object with expires_at (number, token expiry unix timestamp), token (string, JWT), user (object with id, name, type, email, mobile, extra, status), and menus (app menu data)"
|
||||
Loading…
Add table
Reference in a new issue