cmdctx

package
v3.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Exists

func Exists(fv map[string]any, key string) bool

Exists reports whether key is present in fv (value may be a zero value).

func GetBool

func GetBool(fv map[string]any, key string) bool

GetBool returns FlagValues[key] as a bool, parsing strings like "true"/"1" if needed.

func GetFloat64

func GetFloat64(fv map[string]any, key string) float64

GetFloat64 returns FlagValues[key] as a float64, parsing strings if needed.

func GetInt

func GetInt(fv map[string]any, key string) int

GetInt returns FlagValues[key] as an int, parsing strings if needed (hex/octal ok).

func GetString

func GetString(fv map[string]any, key string) string

GetString returns FlagValues[key] as a string, converting bool/int/float64 if needed.

func GetStringSlice

func GetStringSlice(fv map[string]any, key string) []string

GetStringSlice returns FlagValues[key] as []string, or nil on miss or wrong type.

func IsTimeout

func IsTimeout(err error) bool

IsTimeout reports whether err (or any error in its chain) is a TimeoutError.

func NormalizeFileBody

func NormalizeFileBody(body, ct, filePath string) (string, string, error)

NormalizeFileBody validates and normalizes a file body string based on the effective content type. ct should already be resolved (e.g. via resolveContentType) before calling; empty ct defaults to application/json.

For application/yaml endpoints: the body must NOT be JSON (first non-whitespace char is '{'). For JSON/merge-patch endpoints: JSON is passed through after validation; YAML is parsed and re-encoded as JSON.

Returns the normalized body string and the resolved content type, or an error.

func SlurpInputFile

func SlurpInputFile(fv map[string]any) (string, error)

SlurpInputFile reads the file path stored at FlagValues["file"]. "-" reads from stdin; "/dev/fd/N" works for process substitution. Must be called at endpoint execution time — not at ctx-construction time — so that the plugin exec path inherits stdin rather than consuming it early.

Types

type CreateBodyFn

type CreateBodyFn func(ctx *Ctx) (any, error)

CreateBodyFn builds the POST/PUT request body for an endpoint command.

type Ctx

type Ctx struct {
	Context      context.Context
	CancelFn     context.CancelCauseFunc
	Auth         *auth.ResolvedAuth
	Verb         string
	VerbHandler  string // behavioral dispatch verb; defaults to Verb when verb_handler is unset in spec
	Noun         string
	FieldsNoun   string // overrides Noun for field lookup when set (from spec fields_noun)
	Id           string
	ParentId     string            // optional parent-id arg for list commands (e.g. pipeline ID on "list execution")
	MigrateFrom  string            // --from flag value (pair verbs, e.g. migrate: identifies the source endpoint)
	MigrateTo    string            // --to flag value (pair verbs, e.g. migrate: identifies the destination endpoint)
	SetArgs      map[string]string // --set key=value pairs for update verb (when HasSetArg set on spec)
	DelArgs      []string          // --del key targets for update verb (when HasSetArg set on spec)
	Args         []string          // extra positional args beyond [id] (when HasArgs set on spec)
	IdParts      []string          // id split on "/" when id_parts > 1 on spec; length equals the number of actual parts
	Level        string            // scope level: "account", "org", or "project" (empty when flag not present)
	IsPty        bool              // true when stdout is an interactive terminal
	IsCompletion bool              // true when this ctx was built for a shell completion request
	Resolver     Resolver
	GlobalFlags  GlobalFlags
	FormatFlags  FormatFlags
	PagingFlags  PagingFlags
	// FlagValues holds typed flag values for this command, keyed by flag name. It contains:
	//   - all flags declared in the spec (cs.Flags), typed as string/bool/[]string
	//   - "page"         int    (0-indexed) when the spec declares builtin_flags.page
	//   - "format"       string when the flag exists (gates PTY-sensitive expr rendering)
	//   - "columns"      string when the flag exists (list commands)
	//   - "list-columns" bool   when the flag exists (list commands)
	//   - "list-fields"  bool   when the flag exists (get/update commands)
	//   - "profile", "org", "project" string when no_auth: true (the handler owns auth resolution)
	FlagValues map[string]any
	// UIHistory is the --ui back-navigation stack: one UILink pushed per Hop
	// (link/up/view), popped by the "b" key. Session-lifetime only.
	UIHistory []UILink
	// RestoreListPos is the cursor row (within the first-loaded page) to seed a
	// freshly built table with when replaying a popped UILink's ListPos.
	RestoreListPos int
}

Ctx is passed to every workflow handler, providing resolved auth and the parsed command identity. Auth is nil for management commands (version, etc.) that do not require credentials. When Auth is non-nil, OrgID and ProjectID already reflect any --org/--project overrides.

func (*Ctx) AccountAuth

func (c *Ctx) AccountAuth() *auth.ResolvedAuth

AccountAuth returns Auth with OrgID and ProjectID cleared, regardless of Level. Use for lookups against entities that are almost always account-scoped and don't inherit down to a narrower org/project lookup.

func (*Ctx) OrgAuth

func (c *Ctx) OrgAuth() *auth.ResolvedAuth

OrgAuth returns Auth with ProjectID cleared but OrgID preserved, regardless of Level. Use to probe org-scoped entities while running at a narrower project scope under that org.

func (c *Ctx) PopUILink() (link UILink, ok bool)

PopUILink removes and returns the most recently pushed UILink. ok is false when the stack is empty, in which case link is the zero value.

func (c *Ctx) PushUILink(link UILink)

PushUILink appends link to the back-navigation stack (LIFO — PopUILink pops from the end).

func (*Ctx) ScopedAuth

func (c *Ctx) ScopedAuth() *auth.ResolvedAuth

ScopedAuth returns Auth adjusted for Level: "org" clears ProjectID, "account" clears both OrgID and ProjectID. Callers making direct API requests outside the endpoint framework (which applies this via CallEndpoint) must use this instead of Auth directly, or a --level account/org request will still scope to the profile's default org/project.

type DataAccessor

type DataAccessor interface {
	GetString(path string) string
	GetInt64(path string) int64
	GetBool(path string) bool
	GetTs(path string) string
	GetData() any
	GetSlice(path string) []any
}

DataAccessor provides typed field access over a response value. Paths are expr-lang expressions with "it" bound to the root data.

type EndpointRequest

type EndpointRequest struct {
	Method      string
	Path        string
	QueryParams map[string]string
	Body        any
	ContentType string
}

EndpointRequest is the materialized form of a pending API request passed to EndpointValidatorFns. Body mirrors client.Request.Body: a string when the request body came from a -f file, a map/struct for structured bodies, or nil.

type EndpointValidatorFn

type EndpointValidatorFn func(ctx *Ctx, req EndpointRequest) error

EndpointValidatorFn validates a request before it is sent. Declared via validators_endpoint in the spec; runs after file slurp, before the HTTP call. req.Body is the fully materialized request body (string or structured value).

type FetchFn

type FetchFn func(ctx *Ctx, ep *spec.EndpointSpec, wantStart, wantCount int, cursor any) (*PageResult, error)

FetchFn fetches one page of results. cursor is nil on the first call. Implementations may ignore wantStart/wantCount/cursor and return everything at once — the driver's slice math handles the window.

type FlagResolveFn

type FlagResolveFn func(ctx *Ctx, raw string) (*FlagResolveResult, error)

FlagResolveFn transforms a raw flag string value before it is placed into the CEL expression environment. Returning an error aborts the command.

type FlagResolveResult

type FlagResolveResult struct {
	Value    string
	Defaults map[string]string
}

FlagResolveResult is the result of resolving a flag's raw value. Value is the resolved value for the flag itself. Defaults, if non-nil, supplies values for OTHER flags — applied only if that flag is still unset; an already-set flag is never overridden.

type FollowFn

type FollowFn func(ctx *Ctx, result any) error

FollowFn is called after a successful endpoint command when --follow is set. result is the raw API response (same value RunEndpoint returns).

type FormatFlags

type FormatFlags struct {
	Format    string
	Columns   string
	Fields    string // --fields: comma-separated field IDs; outputs tab-separated values (get commands only)
	NoHeaders bool
	OutFile   string
	Raw       bool
}

FormatFlags holds all output-formatting flags (format, columns, headers, file, raw). Fields are zero-valued when the command did not declare support for them.

type GlobalFlags

type GlobalFlags struct{}

GlobalFlags is reserved for future non-formatting global flags.

type ItemFn

type ItemFn func(ctx *Ctx) (any, error)

ItemFn resolves a workflow-backed "get" command's target item without rendering it — used by the TUI detail-pane drilldown, which needs a value to render, not written text.

type ListTransformFn

type ListTransformFn func(ctx *Ctx, data any) (items []any, fields []spec.FieldDef, meta PageMeta, err error)

ListTransformFn converts a get/execute response into list-rendering inputs: the row slice, the columns available on those rows, and optional paging summary info.

type PageMeta

type PageMeta struct {
	Offset   int
	Count    int
	HasTotal bool
	Total    int64
	Notice   string
}

PageMeta carries optional paging summary information and a notice for display after a table. Offset is the item-level offset of the first item returned. Count is the number of items actually returned. HasTotal indicates whether Total is valid.

type PageResult

type PageResult struct {
	Raw         any
	Items       []any
	StartOffset int
	Last        bool
	HasTotal    bool
	Total       int64
	NextCursor  any
}

PageResult is returned by a FetchFn for one logical page of results.

type PagingFlags

type PagingFlags struct {
	Offset int  // item-level offset (not page-level)
	Limit  int  // max items to return; 0 means use page_size_default
	All    bool // fetch all pages, overrides Offset and Limit
	Count  bool // return total count instead of items; incompatible with Offset/Limit/All
	// OnPage, if set, is invoked once per fetched page with the number of items
	// accumulated so far and the reported grand total (hasTotal is false when the
	// paging strategy does not return one). Used to surface progress on slow,
	// many-page fetches (e.g. thousands of orgs during login).
	OnPage func(fetched int, total int64, hasTotal bool)
}

PagingFlags holds the user-facing paging control flags for list commands. Only populated when the endpoint declares a paging model. Count is mutually exclusive with Offset, Limit, and All — the caller validates this.

type QueryParamsFn

type QueryParamsFn func(ctx *Ctx) (map[string]string, error)

QueryParamsFn returns extra query parameters to merge into a request. It is called after the spec's query_params CEL expressions are evaluated, and its results are merged on top (so it can override CEL values too). Only takes effect on GET and list requests; it is not called for update/create strategies (get-then-put, set-fields) which manage their own query params internally.

type RawBody

type RawBody struct {
	ContentType string
	Content     string
}

RawBody signals that the body should be sent as-is with the given ContentType, bypassing JSON encoding. Return this from a CreateBodyFn when the API expects a raw non-JSON body (e.g. application/yaml).

type Resolver

type Resolver interface {
	ResolveTextFormatter(id string) TextFormatterFn
	ResolveBodyFn(id string) CreateBodyFn
	ResolveQueryParamsFn(id string) QueryParamsFn
	ResolveFlagResolveFn(id string) FlagResolveFn
	ResolveFetchFn(id string) (FetchFn, error)
	ResolveListTransformFn(id string) ListTransformFn
	ResolveItemFn(id string) ItemFn
	ResolveEndpointValidator(id string) EndpointValidatorFn
	GetSpec(verb, noun string) *spec.CommandSpec
	GetNoun(noun string) *spec.NounDef
	// ResolveNounAlias returns the canonical noun name for the given alias, or "" if not an alias.
	ResolveNounAlias(alias string) string
	RunEndpoint(ctx *Ctx, ep *spec.EndpointSpec) (any, error)
	// RunUIHandler dispatches to the registered ui_handler_fn, e.g. from a get
	// command's drilldown detail overlay when the user presses "v".
	RunUIHandler(ctx *Ctx, fnID string) error
	// FormatList renders rows through the standard list formatting pipeline (table/json/csv/tsv).
	// fields declares the available columns; columnIDs sets the default column order (nil = all).
	FormatList(ctx *Ctx, rows []any, fields []spec.FieldDef, columnIDs []string) error
	// FetchItems fetches all items satisfying pf from a paging-enabled list endpoint.
	// Returns raw items as extracted by the endpoint's items_expr — no field unwrapping.
	FetchItems(ctx *Ctx, ep *spec.EndpointSpec, pf PagingFlags) ([]any, error)
	// GetModuleMetas returns metadata for all loaded modules in load order.
	GetModuleMetas() []spec.ModuleMeta
	// GetHiddenModule returns the recorded stub for a module_type: hidden
	// module by name (recorded regardless of enablement), or nil.
	GetHiddenModule(name string) *spec.ModuleMeta
	// GetSpecsForModule returns all registered CommandSpecs belonging to the given module.
	GetSpecsForModule(module string) []*spec.CommandSpec
	// GetAllSpecs returns every registered CommandSpec across all modules.
	GetAllSpecs() []*spec.CommandSpec
	// GetVerbInfos returns display metadata for all verbs that have at least one registered command.
	GetVerbInfos() []spec.VerbInfo
	// ResolveCommandFields returns the effective []FieldDef for a command: noun fields (or
	// fields_noun override), filtered by fields_subset, with fields_extra appended.
	ResolveCommandFields(cs *spec.CommandSpec) []spec.FieldDef
}

Resolver looks up registered handler functions by their fully-qualified ID. The registry implements this; commands receive it via Ctx.Resolver.

type TextFormatterFn

type TextFormatterFn func(w io.Writer, d DataAccessor) error

TextFormatterFn is a human-readable text renderer for a single item.

type TimeoutError

type TimeoutError struct {
	Secs float64
}

TimeoutError is the cause set on the context when --timeout expires.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string
type UILink struct {
	Verb, Noun string
	Id         string
	IdParts    []string
	Level      string

	Profile, Org, Project string
	FlagValues            map[string]any

	Screen  UIScreenKind
	ListPos int
}

UILink is a replayable reference to a --ui Hop's target: enough to rebuild the Ctx for that screen and redraw it, without encoding anything onto a command line. Profile/Org/Project are the raw scope flag strings in effect at the Hop (not a cached resolved Auth), so replay can re-resolve auth instead of inheriting whatever was live in memory when the Link was pushed.

type UIScreenKind

type UIScreenKind int

UIScreenKind identifies which screen function should be called to redraw a UILink: a browse table scoped to a parent id, a browse table scoped to a parent id that itself came from a "get" lookup, or a detail-only overlay.

const (
	ScreenTable UIScreenKind = iota
	ScreenTableForGet
	ScreenDetailForGet
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL