mirror of
https://github.com/larksuite/cli.git
synced 2026-09-14 18:42:53 +08:00
4488da0b14
* feat(apps): add +user-id-convert shortcut for Miaoda↔Feishu ID conversion
Wrap the platform id_convert OpenAPI as a read-only shortcut that maps
Miaoda user_id ↔ Feishu open platform IDs (open_id / union_id / Feishu
user_id). It does one thing — conversion — with no local mapping table,
caching, permission pre-check, or direction guessing.
- --convert-type enum → server id_convert_type (10/11/20/21/40)
- --ids: csv / @file / stdin, 1-100 per call, not de-duped, input order
- reconstructs data.missed by diffing input positions against returned
source_ids (server silently drops unresolved IDs), keyed by 0-based index
- meta counters (total/hit_count/missed_count) via pointer fields on
output.Meta so an explicit missed_count: 0 survives omitempty
* test(apps): address review feedback on +user-id-convert
- reject empty --ids CSV entries (e.g. "a,,b") with a typed validation
error instead of silently dropping them, since a dropped entry shifts
every later result's 0-based index and breaks the position-keyed
items/missed contract; add an interior-empty-element test
- reuse common.GetSlice / common.GetString for response projection
(house convention) instead of local asSlice/asString helpers
- requireConvertValidation now asserts CategoryValidation +
SubtypeInvalidArgument via errs.ProblemOf, keeping ValidationError.Param
- table-drive TestResolveConvertType over all five directions so every
--convert-type → id_convert_type mapping (10/11/20/21/40) is protected
* fix(apps): split newline-delimited --ids for +user-id-convert @file/stdin
@file and - (stdin) input arrives verbatim from the framework as
one-ID-per-line text, but parseConvertIDs only split on commas, so such a
block was sent as a single malformed request ID. Treat a newline as
equivalent to a comma, tolerating a file's trailing newline while still
rejecting interior empty entries so position-keyed result indices stay
aligned. Add @file and stdin tests asserting the request body's ids are
split into discrete IDs.
* fix(apps): stringify numeric JSON IDs in +user-id-convert results
Responses decode with json.Number (client.ParseJSONResponse uses
dec.UseNumber()), so a server that emits source_id/target_id as bare
numbers — plausible for the numeric Miaoda user_id form — was silently
coerced to "" by buildConvertResult's strict string assertion: the
source_id got dropped (false not_found) and the target_id blanked
(false success).
Add common.GetStringLoose, which stringifies string/json.Number/int64/
float64 via literal text (large integer IDs keep full precision, never
routed through a lossy float64), and use it for both id reads. Cover it
with a package-level table test plus an end-to-end regression asserting a
numeric-JSON response yields intact, non-blank ids and no false miss.
Also exercise resolveConvertType's non-empty "not a valid direction"
branch directly, since the runner's enum gate preempts it in normal flow.
* test(common): tighten GetStringLoose numeric coverage
Add an int-branch case (was only covering int64) and swap the float64
fixture from 42 — which no formatter would render in exponent form — to
1e-7, whose fixed-point rendering "0.0000001" fails under the 'g' verb.
This turns the "no scientific notation" case into a real guard for the
'f' verb choice, per CodeRabbit review on c64cca39.
119 lines
3.2 KiB
Go
119 lines
3.2 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package apps
|
|
|
|
import "github.com/larksuite/cli/shortcuts/common"
|
|
|
|
// Shortcuts returns all apps domain shortcuts.
|
|
func Shortcuts() []common.Shortcut {
|
|
envSet := withExtraTips(AppsEnvVarSet, "Example: lark-cli apps +env-set --app-id <app_id> --environment online --key FOO --value <value> --yes")
|
|
envDelete := withExtraTips(AppsEnvVarDelete, "Tip: +env-delete is high-risk-write; only pass --yes after explicit confirmation.")
|
|
|
|
return []common.Shortcut{
|
|
AppsCreate,
|
|
AppsGet,
|
|
AppsUpdate,
|
|
AppsList,
|
|
AppsAccessScopeSet,
|
|
AppsAccessScopeGet,
|
|
AppsRoleList,
|
|
AppsRoleGet,
|
|
AppsRoleCreate,
|
|
AppsRoleUpdate,
|
|
AppsRoleDelete,
|
|
AppsRoleMemberList,
|
|
AppsRoleMemberAdd,
|
|
AppsRoleMemberRemove,
|
|
AppsRoleMatchList,
|
|
AppsMemberList,
|
|
AppsMemberAdd,
|
|
AppsMemberUpdate,
|
|
AppsMemberRemove,
|
|
AppsMemberSettingsGet,
|
|
AppsMemberSettingsSet,
|
|
AppsHTMLPublish,
|
|
AppsInit,
|
|
AppsReleaseCreate,
|
|
AppsReleaseList,
|
|
AppsReleaseGet,
|
|
AppsEnvPull,
|
|
withExtraTips(AppsLogList, "Tip: logs are online-only; keep --environment omitted or set --environment online."),
|
|
withExtraTips(AppsLogGet, "Tip: logs are online-only; keep --environment omitted or set --environment online."),
|
|
withExtraTips(AppsTraceList, "Tip: traces are online-only; keep --environment omitted or set --environment online."),
|
|
withExtraTips(AppsTraceGet, "Tip: traces are online-only; keep --environment omitted or set --environment online."),
|
|
withExtraTips(AppsMetricList, "Tip: metrics are online-only; keep --environment omitted or set --environment online."),
|
|
withExtraTips(AppsAnalyticsList, "Tip: analytics are online-only; keep --environment omitted or set --environment online."),
|
|
AppsEnvVarList,
|
|
envSet,
|
|
envDelete,
|
|
AppsDBTableList,
|
|
AppsDBTableGet,
|
|
AppsDBExecute,
|
|
AppsDBEnvCreate,
|
|
AppsDBDataImport,
|
|
AppsDBDataExport,
|
|
AppsDBSyncCreate,
|
|
AppsDBSyncList,
|
|
AppsDBSyncGet,
|
|
AppsDBSyncEnable,
|
|
AppsDBSyncDisable,
|
|
AppsDBSyncUpdate,
|
|
AppsDBSyncDelete,
|
|
AppsDBChangelogList,
|
|
AppsDBAuditStatus,
|
|
AppsDBAuditEnable,
|
|
AppsDBAuditDisable,
|
|
AppsDBAuditList,
|
|
AppsDBEnvDiff,
|
|
AppsDBEnvMigrate,
|
|
AppsDBRecoveryDiff,
|
|
AppsDBRecoveryApply,
|
|
AppsDBQuotaGet,
|
|
AppsFileList,
|
|
AppsFileGet,
|
|
AppsFileSign,
|
|
AppsFileDownload,
|
|
AppsFileUpload,
|
|
AppsFileDelete,
|
|
AppsFileQuotaGet,
|
|
AppsCacheGet,
|
|
AppsCacheDelete,
|
|
AppsCacheClear,
|
|
AppsGitCredentialInit,
|
|
AppsGitCredentialList,
|
|
AppsGitCredentialRemove,
|
|
AppsSessionCreate,
|
|
AppsSessionList,
|
|
AppsSessionGet,
|
|
AppsSessionStop,
|
|
AppsSessionMessagesList,
|
|
AppsChat,
|
|
AppsUserIDConvert,
|
|
AppsPluginInstall,
|
|
AppsPluginUninstall,
|
|
AppsPluginList,
|
|
// open API key management
|
|
AppsOpenAPIKeyList,
|
|
AppsOpenAPIKeyGet,
|
|
AppsOpenAPIKeyCreate,
|
|
AppsOpenAPIKeyUpdate,
|
|
AppsOpenAPIKeyEnable,
|
|
AppsOpenAPIKeyDisable,
|
|
AppsOpenAPIKeyDelete,
|
|
AppsOpenAPIKeyReset,
|
|
// automation triggers (cron / record-change / webhook / feishu-approval)
|
|
AppsAutomationList,
|
|
AppsAutomationGet,
|
|
AppsAutomationCreate,
|
|
AppsAutomationUpdate,
|
|
AppsAutomationEnable,
|
|
AppsAutomationDisable,
|
|
}
|
|
}
|
|
|
|
func withExtraTips(sc common.Shortcut, tips ...string) common.Shortcut {
|
|
sc.Tips = append(append([]string{}, sc.Tips...), tips...)
|
|
return sc
|
|
}
|