common

package
v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PermissionGrantGranted = "granted"
	PermissionGrantSkipped = "skipped"
	PermissionGrantFailed  = "failed"
)
View Source
const (
	File  = "file"  // support @path to read value from a file
	Stdin = "stdin" // support - to read value from stdin
)

Flag.Input source constants.

View Source
const MaxDriveMediaUploadSinglePartSize int64 = 20 * 1024 * 1024 // 20MB

Variables

View Source
var NewDryRunAPI = cmdutil.NewDryRunAPI

Functions

func AtLeastOne

func AtLeastOne(rt *RuntimeContext, flags ...string) error

AtLeastOne checks that at least one of the given flags is set.

func AutoGrantCurrentUserDrivePermission added in v1.0.7

func AutoGrantCurrentUserDrivePermission(runtime *RuntimeContext, token, resourceType string) map[string]interface{}

AutoGrantCurrentUserDrivePermission grants full_access on a newly created Drive resource to the current CLI user when the shortcut runs as bot.

Callers should attach the returned result only when it is non-nil.

func CallMCPTool

func CallMCPTool(runtime *RuntimeContext, toolName string, args map[string]interface{}) (map[string]interface{}, error)

CallMCPTool calls an MCP tool via JSON-RPC 2.0 and returns the parsed result.

func CheckApiError

func CheckApiError(w io.Writer, result interface{}, action string) bool

CheckApiError checks if API result is an error and prints it to w.

func DoMCPCall

func DoMCPCall(ctx context.Context, httpClient *http.Client, toolName string, args map[string]interface{}, accessToken string, mcpEndpoint string, isBot bool) (interface{}, error)

func EachMap

func EachMap(items []interface{}, fn func(m map[string]interface{}))

EachMap iterates over map elements in a slice, skipping non-map items.

func ExactlyOne

func ExactlyOne(rt *RuntimeContext, flags ...string) error

ExactlyOne checks that exactly one of the given flags is set.

func ExtractDriveMediaUploadFileToken added in v1.0.6

func ExtractDriveMediaUploadFileToken(data map[string]interface{}, action string) (string, error)

func ExtractMCPResult

func ExtractMCPResult(raw interface{}) interface{}

func FlagErrorf

func FlagErrorf(format string, args ...any) error

FlagErrorf returns a validation error with flag context (exit code 2).

func FormatSize

func FormatSize(bytes int64) string

func FormatTime

func FormatTime(ts interface{}) string

FormatTime converts Unix seconds/ms string to local time string.

func FormatTimeWithSeconds

func FormatTimeWithSeconds(ts interface{}) string

FormatTimeWithSeconds converts Unix seconds/ms string to local time string with seconds precision.

func GetBool

func GetBool(m map[string]interface{}, keys ...string) bool

GetBool safely extracts a bool.

func GetFloat

func GetFloat(m map[string]interface{}, keys ...string) float64

GetFloat safely extracts a float64 (the default JSON number type).

func GetMap

func GetMap(m map[string]interface{}, keys ...string) map[string]interface{}

GetMap safely extracts a nested map.

func GetSlice

func GetSlice(m map[string]interface{}, keys ...string) []interface{}

GetSlice safely extracts a []interface{}.

func GetString

func GetString(m map[string]interface{}, keys ...string) string

GetString safely extracts a string from a nested map path. Usage: GetString(data, "user", "name") is equivalent to data["user"].(map[string]interface{})["name"].(string)

func HandleApiResult

func HandleApiResult(result interface{}, err error, action string) (map[string]interface{}, error)

HandleApiResult checks for network/API errors and returns the "data" field.

func IsDangerousUnicode

func IsDangerousUnicode(r rune) bool

IsDangerousUnicode reports whether r is a Unicode character that can cause terminal injection: BiDi overrides, zero-width characters, and Unicode line terminators.

func MCPEndpoint

func MCPEndpoint(brand core.LarkBrand) string

func MaskToken

func MaskToken(token string) string

func MutuallyExclusive

func MutuallyExclusive(rt *RuntimeContext, flags ...string) error

MutuallyExclusive checks that at most one of the given flags is set.

func PaginationHint

func PaginationHint(data map[string]interface{}, count int) string

PaginationHint returns a human-readable pagination hint for pretty output.

func PaginationMeta

func PaginationMeta(data map[string]interface{}) (hasMore bool, pageToken string)

PaginationMeta extracts pagination metadata from an API response data map.

func ParseDriveMediaUploadResponse added in v1.0.6

func ParseDriveMediaUploadResponse(apiResp *larkcore.ApiResp, action string) (map[string]interface{}, error)

func ParseIntBounded

func ParseIntBounded(rt *RuntimeContext, name string, min, max int) int

ParseIntBounded parses an int flag and clamps it to [min, max].

func ParseJSON

func ParseJSON(data []byte, v interface{}) error

ParseJSON unmarshals JSON data into v.

func ParseTime

func ParseTime(input string, hint ...string) (string, error)

ParseTime converts time expressions to Unix seconds string.

Optional hint: "end" makes day-granularity inputs snap to 23:59:59 instead of 00:00:00.

ParseTime("2026-01-01")        → 2026-01-01 00:00:00
ParseTime("2026-01-01", "end") → 2026-01-01 23:59:59

Supported formats: ISO 8601 (with or without time/timezone), date-only, Unix timestamp.

func RejectDangerousChars

func RejectDangerousChars(paramName, value string) error

RejectDangerousChars returns an error if value contains ASCII control characters or dangerous Unicode code points.

func RequireConfirmation

func RequireConfirmation(risk string, yes bool, action string) error

RequireConfirmation blocks high-risk-write operations unless --yes is passed.

func SplitCSV

func SplitCSV(input string) []string

SplitCSV 解析逗号分隔的列表,忽略空项并去除空格

func TruncateStr

func TruncateStr(s string, n int) string

TruncateStr truncates s to at most n runes.

func UnwrapMCPResult

func UnwrapMCPResult(v interface{}) interface{}

func UploadDriveMediaAll added in v1.0.6

func UploadDriveMediaAll(runtime *RuntimeContext, cfg DriveMediaUploadAllConfig) (string, error)

func UploadDriveMediaMultipart added in v1.0.6

func UploadDriveMediaMultipart(runtime *RuntimeContext, cfg DriveMediaMultipartUploadConfig) (string, error)

func ValidateChatID

func ValidateChatID(input string) (string, error)

ValidateChatID checks if a chat ID has valid format (oc_ prefix). Also extracts token from URL if provided.

func ValidatePageSize

func ValidatePageSize(rt *RuntimeContext, flagName string, defaultVal, minVal, maxVal int) (int, error)

ValidatePageSize validates that the named flag (if set) is an integer within [minVal, maxVal]. It returns the parsed value (or defaultVal if the flag is empty) and any validation error.

func ValidateSafeOutputDir

func ValidateSafeOutputDir(fio fileio.FileIO, outputDir string) error

ValidateSafeOutputDir ensures outputDir is a relative path that resolves within the current working directory, preventing path traversal attacks (including symlink-based escape). It delegates all validation to FileIO.ResolvePath which already performs cwd-boundary checks, symlink resolution, and control-character rejection.

func ValidateUserID

func ValidateUserID(input string) (string, error)

ValidateUserID checks if a user ID has valid format (ou_ prefix).

func WrapDriveMediaUploadRequestError added in v1.0.6

func WrapDriveMediaUploadRequestError(err error, action string) error

func WrapInputStatError added in v1.0.7

func WrapInputStatError(err error, readMsg ...string) error

WrapInputStatError wraps a FileIO.Stat/Open error for input file validation, returning output.ErrValidation with the appropriate message:

  • Path validation failures → "unsafe file path: ..."
  • Other errors → readMsg prefix (default "cannot read file")

Pass an optional readMsg to override the non-path-validation message prefix.

func WrapOpenError added in v1.0.6

func WrapOpenError(err error, pathMsg, readMsg string) error

WrapOpenError matches a FileIO.Open/Stat error and wraps it with the caller-provided message prefix.

func WrapSaveError added in v1.0.6

func WrapSaveError(err error, pathMsg, mkdirMsg, writeMsg string) error

WrapSaveError matches a FileIO.Save error against known categories and wraps it with the caller-provided message prefix, preserving backward-compatible error text per shortcut.

func WrapSaveErrorByCategory added in v1.0.6

func WrapSaveErrorByCategory(err error, category string) error

WrapSaveErrorByCategory maps a FileIO.Save error to structured output errors, using standardized messages and the given error category (e.g. "api_error", "io"). Path validation errors always use ErrValidation (exit code 2).

Types

type DriveMediaMultipartUploadConfig added in v1.0.6

type DriveMediaMultipartUploadConfig struct {
	FilePath   string
	FileName   string
	FileSize   int64
	ParentType string
	ParentNode string
	Extra      string
}

type DriveMediaMultipartUploadSession added in v1.0.6

type DriveMediaMultipartUploadSession struct {
	UploadID  string
	BlockSize int64
	BlockNum  int
}

func ParseDriveMediaMultipartUploadSession added in v1.0.6

func ParseDriveMediaMultipartUploadSession(data map[string]interface{}) (DriveMediaMultipartUploadSession, error)

type DriveMediaUploadAllConfig added in v1.0.6

type DriveMediaUploadAllConfig struct {
	FilePath   string
	FileName   string
	FileSize   int64
	ParentType string
	ParentNode *string
	Extra      string
}

type DryRunAPI

type DryRunAPI = cmdutil.DryRunAPI

Type aliases so all existing shortcut code continues to use common.DryRunAPI without any changes. The real implementation lives in internal/cmdutil.

type DryRunAPICall

type DryRunAPICall = cmdutil.DryRunAPICall

type Flag

type Flag struct {
	Name     string // flag name (e.g. "calendar-id")
	Type     string // "string" (default) | "bool" | "int" | "string_array"
	Default  string // default value as string
	Desc     string // help text
	Hidden   bool   // hidden from --help, still readable at runtime
	Required bool
	Enum     []string // allowed values (e.g. ["asc", "desc"]); empty means no constraint
	Input    []string // extra input sources: File (@path), Stdin (-); empty = flag value only
}

Flag describes a CLI flag for a shortcut.

type MultipartWriter

type MultipartWriter struct {
	*multipart.Writer
}

MultipartWriter wraps multipart.Writer for file uploads.

func NewMultipartWriter

func NewMultipartWriter(w io.Writer) *MultipartWriter

NewMultipartWriter creates a new MultipartWriter.

func (*MultipartWriter) CreateFormFile

func (mw *MultipartWriter) CreateFormFile(fieldname, filename string) (io.Writer, error)

CreateFormFile creates a form file with the given field name and file name.

type RuntimeContext

type RuntimeContext struct {
	Config *core.CliConfig
	Cmd    *cobra.Command
	Format string
	JqExpr string // --jq expression; empty = no filter

	Factory *cmdutil.Factory // injected by framework
	// contains filtered or unexported fields
}

RuntimeContext provides helpers for shortcut execution.

func TestNewRuntimeContext

func TestNewRuntimeContext(cmd *cobra.Command, cfg *core.CliConfig) *RuntimeContext

TestNewRuntimeContext creates a RuntimeContext for testing purposes. Only Cmd and Config are set; other fields (Factory, larkSDK, etc.) are nil.

func TestNewRuntimeContextWithCtx

func TestNewRuntimeContextWithCtx(ctx context.Context, cmd *cobra.Command, cfg *core.CliConfig) *RuntimeContext

TestNewRuntimeContextWithCtx creates a RuntimeContext with an explicit context for tests that invoke functions which call Ctx() (e.g. HTTP request helpers).

func TestNewRuntimeContextWithIdentity added in v1.0.4

func TestNewRuntimeContextWithIdentity(cmd *cobra.Command, cfg *core.CliConfig, as core.Identity) *RuntimeContext

TestNewRuntimeContextWithIdentity creates a RuntimeContext with a specific identity for testing.

func (*RuntimeContext) AccessToken

func (ctx *RuntimeContext) AccessToken() (string, error)

AccessToken returns a valid access token for the current identity. For user: returns user access token (with auto-refresh). For bot: returns tenant access token.

func (*RuntimeContext) As

func (ctx *RuntimeContext) As() core.Identity

As returns the current identity. For bot-only shortcuts, always returns AsBot. For dual-auth shortcuts, uses the resolved identity (respects default-as config).

func (*RuntimeContext) Bool

func (ctx *RuntimeContext) Bool(name string) bool

Bool returns a bool flag value.

func (*RuntimeContext) CallAPI

func (ctx *RuntimeContext) CallAPI(method, url string, params map[string]interface{}, data interface{}) (map[string]interface{}, error)
CallAPI uses an internal HTTP wrapper with limited control over request/response.

Prefer DoAPI for new code — it calls the Lark SDK directly and supports file upload/download options.

CallAPI calls the Lark API using the current identity (ctx.As()) and auto-handles errors.

func (*RuntimeContext) Ctx

func (ctx *RuntimeContext) Ctx() context.Context

Ctx returns the context.Context propagated from cmd.Context().

func (*RuntimeContext) DoAPI

DoAPI executes a raw Lark SDK request with automatic auth handling. Unlike CallAPI which parses JSON and extracts the "data" field, DoAPI returns the raw *larkcore.ApiResp — suitable for file downloads (WithFileDownload) and uploads (WithFileUpload).

Auth resolution is delegated to APIClient.DoSDKRequest to avoid duplicating the identity → token logic across the generic and shortcut API paths.

func (*RuntimeContext) DoAPIAsBot added in v1.0.3

func (ctx *RuntimeContext) DoAPIAsBot(req *larkcore.ApiReq, opts ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

DoAPIAsBot executes a raw Lark SDK request using bot identity (tenant access token), regardless of the current --as flag. Use this for bot-only APIs (e.g. image/file upload) that must be called with TAT even when the surrounding shortcut runs as user.

func (*RuntimeContext) DoAPIJSON

func (ctx *RuntimeContext) DoAPIJSON(method, apiPath string, query larkcore.QueryParams, body any) (map[string]any, error)

DoAPIJSON calls the Lark API via DoAPI, parses the JSON response envelope, and returns the "data" field. Suitable for standard JSON APIs (non-file).

func (*RuntimeContext) DoAPIStream

func (ctx *RuntimeContext) DoAPIStream(callCtx context.Context, req *larkcore.ApiReq, opts ...client.Option) (*http.Response, error)

DoAPIStream executes a streaming HTTP request via APIClient.DoStream. Unlike DoAPI (which buffers the full body via the SDK), DoAPIStream returns a live *http.Response whose Body is an io.Reader for streaming consumption. HTTP errors (status >= 400) are handled internally by DoStream.

func (*RuntimeContext) FileIO added in v1.0.6

func (ctx *RuntimeContext) FileIO() fileio.FileIO

FileIO resolves the FileIO using the current execution context. Falls back to the globally registered provider when Factory or its FileIOProvider is nil (e.g. in lightweight test helpers).

func (*RuntimeContext) IO

func (ctx *RuntimeContext) IO() *cmdutil.IOStreams

IO returns the IOStreams from the Factory.

func (*RuntimeContext) Int

func (ctx *RuntimeContext) Int(name string) int

Int returns an int flag value.

func (*RuntimeContext) IsBot

func (ctx *RuntimeContext) IsBot() bool

IsBot returns true if current identity is bot.

func (*RuntimeContext) LarkSDK

func (ctx *RuntimeContext) LarkSDK() *lark.Client

LarkSDK returns the eagerly-initialized Lark SDK client.

func (*RuntimeContext) Out

func (ctx *RuntimeContext) Out(data interface{}, meta *output.Meta)

Out prints a success JSON envelope to stdout.

func (*RuntimeContext) OutFormat

func (ctx *RuntimeContext) OutFormat(data interface{}, meta *output.Meta, prettyFn func(w io.Writer))

OutFormat prints output based on --format flag. "json" (default) outputs JSON envelope; "pretty" calls prettyFn; others delegate to FormatValue. When JqExpr is set, routes through Out() regardless of format.

func (*RuntimeContext) PaginateAll

func (ctx *RuntimeContext) PaginateAll(method, url string, params map[string]interface{}, data interface{}, opts client.PaginationOptions) (interface{}, error)

PaginateAll fetches all pages and returns a single merged result.

func (*RuntimeContext) RawAPI deprecated

func (ctx *RuntimeContext) RawAPI(method, url string, params map[string]interface{}, data interface{}) (interface{}, error)

Deprecated: RawAPI uses an internal HTTP wrapper with limited control over request/response. Prefer DoAPI for new code — it calls the Lark SDK directly and supports file upload/download options.

RawAPI calls the Lark API using the current identity (ctx.As()) and returns raw result for manual error handling.

func (*RuntimeContext) ResolveSavePath added in v1.0.6

func (ctx *RuntimeContext) ResolveSavePath(path string) (string, error)

ResolveSavePath resolves a relative path to a validated absolute path via FileIO.ResolvePath. It returns an error if no FileIO provider is registered or if the path fails validation (e.g. traversal, symlink escape).

func (*RuntimeContext) Str

func (ctx *RuntimeContext) Str(name string) string

Str returns a string flag value.

func (*RuntimeContext) StrArray

func (ctx *RuntimeContext) StrArray(name string) []string

StrArray returns a string-array flag value (repeated flag, no CSV splitting).

func (*RuntimeContext) StreamPages

func (ctx *RuntimeContext) StreamPages(method, url string, params map[string]interface{}, data interface{}, onItems func([]interface{}), opts client.PaginationOptions) (interface{}, bool, error)

StreamPages fetches all pages and streams each page's items via onItems. Returns the last result (for error checking) and whether any list items were found.

func (*RuntimeContext) UserOpenId

func (ctx *RuntimeContext) UserOpenId() string

UserOpenId returns the current user's open_id from config.

func (*RuntimeContext) ValidatePath added in v1.0.6

func (ctx *RuntimeContext) ValidatePath(path string) error

ValidatePath checks that path is a valid relative input path within the working directory by delegating to FileIO.Stat. Returns nil if the path is valid or does not exist yet; returns an error only for illegal paths (absolute, traversal, symlink escape, control chars).

NOTE: This validates input (read) paths via SafeInputPath semantics inside the FileIO implementation. For output (write) path validation, use ResolveSavePath instead.

type Shortcut

type Shortcut struct {
	Service     string
	Command     string
	Description string
	Risk        string   // "read" | "write" | "high-risk-write" (empty defaults to "read")
	Scopes      []string // default scopes (fallback when UserScopes/BotScopes are empty)
	UserScopes  []string // optional: user-identity scopes (overrides Scopes when non-empty)
	BotScopes   []string // optional: bot-identity scopes (overrides Scopes when non-empty)

	// Declarative fields (new framework).
	AuthTypes []string // supported identities: "user", "bot" (default: ["user"])
	Flags     []Flag   // flag definitions; --dry-run is auto-injected
	HasFormat bool     // auto-inject --format flag (json|pretty|table|ndjson|csv)
	Tips      []string // optional tips shown in --help output

	// Business logic hooks.
	DryRun   func(ctx context.Context, runtime *RuntimeContext) *DryRunAPI // optional: framework prints & returns when --dry-run is set
	Validate func(ctx context.Context, runtime *RuntimeContext) error      // optional pre-execution validation
	Execute  func(ctx context.Context, runtime *RuntimeContext) error      // main logic
}

Shortcut represents a high-level CLI command.

func (Shortcut) Mount

func (s Shortcut) Mount(parent *cobra.Command, f *cmdutil.Factory)

Mount registers the shortcut on a parent command.

func (*Shortcut) ScopesForIdentity

func (s *Shortcut) ScopesForIdentity(identity string) []string

ScopesForIdentity returns the scopes applicable for the given identity. If identity-specific scopes (UserScopes/BotScopes) are set, they take precedence over the default Scopes.

Jump to

Keyboard shortcuts

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