Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrBodyConflict = errors.New("--body cannot be combined with field flags") ErrBodyUnreadable = errors.New("cannot read request body") ErrBodyNotJSON = errors.New("--body is not valid JSON") ErrMissingArguments = errors.New("missing argument") ErrTooManyArguments = errors.New("too many arguments") )
Functions ¶
func Build ¶
Build assembles the command tree straight from the contracts:
leaflow <service> <operation-id> leaflow compute create-disk
The name is a literal value from the contract, lowercased and hyphenated. Nothing is inferred, so nothing can drift: an operationId is already treated as a stable identifier — the Go and TypeScript SDKs generate their method names from it — and a command name is now that same identifier rather than a second vocabulary to keep in sync with it. One identifier therefore serves the CLI, the SDKs and an MCP tool name alike.
The contract's tag is not a level in the path. operationIds are unique within a contract, so a tag adds nothing to addressing and quite a lot of noise to typing: `compute disk create-disk` says disk twice. Tags become help groups instead, so `leaflow compute --help` still reads as a set of resources rather than eighty-three flat lines.
Every command comes from a contract. Nothing is hand-written on top: a hand-written command is a second source for the same surface, and then the question "is this one generated" has to be answered per command. Where the contract makes something awkward — a verb that lives in the request body — the fix belongs upstream in the contract, not in a local exception.
Types ¶
type Binding ¶
type Binding struct {
Operation *spec.Operation
Path []*openapi3.Parameter
Query []*openapi3.Parameter
Body *openapi3.Schema
Fields []*BodyField
// contains filtered or unexported fields
}
Binding describes an operation's arguments:
path parameters -> positional leaflow compute disk get <disk-id> query parameters -> flags --region-code cn-north-1 request body -> one flag per field, or --body
Path parameters are positional because they are always required and already ordered by the path itself; spelling them as flags only makes the same information longer.
func Bind ¶
Bind adds the shell's half to the contract's parameter split: a flag name for every query parameter, and one flag per scalar body field.
The split itself comes from the contract and is shared with every other caller; what is here is only what a shell needs, because a shell is the one caller that cannot type an object.