mirror of
https://github.com/larksuite/cli.git
synced 2026-07-06 16:18:05 +08:00
Input pre-check failures shared by every shortcut — @file/stdin input resolution, enum validation, and unsupported --dry-run — now leave the CLI as typed validation envelopes naming the offending flag, so scripts and AI agents can branch on `param` instead of parsing prose. Wire type, exit code, and message text are unchanged; the new fields are additive. The shared layer also gains typed replacements for its legacy error-producing helpers, so each business domain can migrate to typed errors without rebuilding common plumbing, and a path-scoped lint guard keeps migrated domains from sliding back. Changes: - Shared pre-check failures (input flags, enum values, dry-run support) return typed validation errors carrying the offending flag as `param`. - Every legacy error-producing helper in shortcuts/common has a typed replacement that preserves the existing message text: validation and flag-group checks, chat/user ID validation (callers name the flag so `param` is ground truth), "me" open-id resolution, safe-path checks, input-stat and save-error wrapping. Legacy helpers stay for not-yet-migrated domains, marked deprecated — including the legacy API-result classifier, whose typed route is runtime.CallAPITyped. - A new errscontract rule rejects legacy common-helper calls on migrated paths, so a migrated domain cannot silently reintroduce legacy envelopes; drive is the first locked path and its last legacy ID-helper calls are replaced.
63 lines
1.9 KiB
Go
63 lines
1.9 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/larksuite/cli/internal/output"
|
|
)
|
|
|
|
// ResolveOpenIDs expands the special identifier "me" to the current user's
|
|
// open_id, removes duplicates case-insensitively while preserving the
|
|
// first-occurrence form, and returns nil for an empty input. flagName is
|
|
// used in error messages to point the user at the offending CLI flag.
|
|
//
|
|
// Deprecated: use ResolveOpenIDsTyped for typed error envelopes.
|
|
func ResolveOpenIDs(flagName string, ids []string, runtime *RuntimeContext) ([]string, error) {
|
|
out, msg := resolveOpenIDs(flagName, ids, runtime)
|
|
if msg != "" {
|
|
return nil, output.ErrValidation("%s", msg)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// ResolveOpenIDsTyped expands the special identifier "me" to the current
|
|
// user's open_id, removes duplicates case-insensitively while preserving the
|
|
// first-occurrence form, and returns nil for an empty input. flagName names
|
|
// the flag being resolved (e.g. "--user-ids") and is recorded on the typed
|
|
// error.
|
|
func ResolveOpenIDsTyped(flagName string, ids []string, runtime *RuntimeContext) ([]string, error) {
|
|
out, msg := resolveOpenIDs(flagName, ids, runtime)
|
|
if msg != "" {
|
|
return nil, ValidationErrorf("%s", msg).WithParam(flagName)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func resolveOpenIDs(flagName string, ids []string, runtime *RuntimeContext) ([]string, string) {
|
|
if len(ids) == 0 {
|
|
return nil, ""
|
|
}
|
|
currentUserID := runtime.UserOpenId()
|
|
seen := make(map[string]struct{}, len(ids))
|
|
out := make([]string, 0, len(ids))
|
|
for _, id := range ids {
|
|
if strings.EqualFold(id, "me") {
|
|
if currentUserID == "" {
|
|
return nil, fmt.Sprintf("%s: \"me\" requires a logged-in user with a resolvable open_id", flagName)
|
|
}
|
|
id = currentUserID
|
|
}
|
|
key := strings.ToLower(id)
|
|
if _, ok := seen[key]; ok {
|
|
continue
|
|
}
|
|
seen[key] = struct{}{}
|
|
out = append(out, id)
|
|
}
|
|
return out, ""
|
|
}
|