feat(docs): support lang for fetch v2 (#1459)

This commit is contained in:
ZEden0
2026-06-16 16:25:36 +08:00
committed by GitHub
parent a0e83c7e59
commit 64b1b3f3ed
4 changed files with 80 additions and 1 deletions

View File

@@ -265,8 +265,8 @@ func ResolveConfigFromMulti(raw *MultiAppConfig, kc keychain.KeychainAccess, pro
AppID: app.AppId,
AppSecret: secret,
Brand: app.Brand,
DefaultAs: app.DefaultAs,
Lang: app.Lang,
DefaultAs: app.DefaultAs,
}
if len(app.Users) > 0 {
cfg.UserOpenId = app.Users[0].UserOpenId

View File

@@ -132,6 +132,27 @@ func TestResolveConfigFromMulti_AcceptsPlainSecret(t *testing.T) {
}
}
func TestResolveConfigFromMulti_CarriesLang(t *testing.T) {
raw := &MultiAppConfig{
Apps: []AppConfig{
{
AppId: "cli_abc",
AppSecret: PlainSecret("my-secret"),
Brand: BrandFeishu,
Lang: "en",
},
},
}
cfg, err := ResolveConfigFromMulti(raw, nil, "")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if cfg.Lang != "en" {
t.Errorf("Lang = %q, want %q", cfg.Lang, "en")
}
}
func TestResolveConfigFromMulti_MatchingKeychainRefPassesValidation(t *testing.T) {
// Keychain ref matches appId, so validation passes.
// The subsequent ResolveSecretInput will fail (no real keychain),

View File

@@ -19,6 +19,7 @@ func v2FetchFlags() []common.Flag {
return []common.Flag{
{Name: "doc-format", Desc: "output content format; xml keeps DocxXML structure and optional block ids, markdown is plain export", Default: "xml", Enum: []string{"xml", "markdown"}},
{Name: "detail", Desc: "detail level; simple for reading, with-ids for block references, full for styles and edit metadata", Default: "simple", Enum: []string{"simple", "with-ids", "full"}},
{Name: "lang", Desc: "user cite display language, e.g. en-US, zh-CN, ja-JP"},
{Name: "revision-id", Desc: "document revision id; -1 means latest", Type: "int", Default: "-1"},
{Name: "scope", Desc: "read scope; full reads whole doc, outline lists headings, section expands from heading anchor, range uses block ids, keyword searches text", Default: "full", Enum: []string{"full", "outline", "range", "keyword", "section"}},
{Name: "start-block-id", Desc: "range/section anchor block id; required for section and optional start for range"},
@@ -89,6 +90,9 @@ func buildFetchBody(runtime *common.RuntimeContext) map[string]interface{} {
if v := runtime.Int("revision-id"); v > 0 {
body["revision_id"] = v
}
if lang := resolveFetchLang(runtime); lang != "" {
body["lang"] = lang
}
detail := effectiveFetchDetail(runtime)
switch detail {
@@ -118,6 +122,16 @@ func buildFetchBody(runtime *common.RuntimeContext) map[string]interface{} {
return body
}
func resolveFetchLang(runtime *common.RuntimeContext) string {
if runtime.Changed("lang") {
return strings.TrimSpace(runtime.Str("lang"))
}
if runtime.Config == nil {
return ""
}
return strings.TrimSpace(string(runtime.Config.Lang))
}
// buildReadOption 拼装 read_option JSONfull/空模式返回 nil让服务端走默认全文路径。
func buildReadOption(runtime *common.RuntimeContext) map[string]interface{} {
mode := strings.TrimSpace(runtime.Str("scope"))

View File

@@ -10,6 +10,7 @@ import (
"testing"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/httpmock"
"github.com/larksuite/cli/shortcuts/common"
"github.com/spf13/cobra"
@@ -62,6 +63,47 @@ func TestBuildFetchBodyOmitsEmptyScene(t *testing.T) {
}
}
func TestBuildFetchBodyIncludesExplicitLang(t *testing.T) {
t.Parallel()
runtime := newFetchBodyTestRuntime(context.Background())
if err := runtime.Cmd.Flags().Set("lang", "en-US"); err != nil {
t.Fatalf("set lang: %v", err)
}
body := buildFetchBody(runtime)
if got := body["lang"]; got != "en-US" {
t.Fatalf("lang = %#v, want %q", got, "en-US")
}
}
func TestBuildFetchBodyUsesRuntimeConfigLang(t *testing.T) {
t.Parallel()
runtime := newFetchBodyTestRuntime(context.Background())
runtime.Config = &core.CliConfig{Lang: "zh_cn"}
body := buildFetchBody(runtime)
if got := body["lang"]; got != "zh_cn" {
t.Fatalf("lang = %#v, want %q", got, "zh_cn")
}
}
func TestBuildFetchBodyExplicitBlankLangOmitsLang(t *testing.T) {
t.Parallel()
runtime := newFetchBodyTestRuntime(context.Background())
runtime.Config = &core.CliConfig{Lang: "zh_cn"}
if err := runtime.Cmd.Flags().Set("lang", ""); err != nil {
t.Fatalf("set lang: %v", err)
}
body := buildFetchBody(runtime)
if _, ok := body["lang"]; ok {
t.Fatalf("did not expect blank explicit lang in fetch body: %#v", body)
}
}
func TestDocsFetchDryRunDefaultsToV2Endpoint(t *testing.T) {
t.Parallel()
@@ -262,6 +304,7 @@ func newFetchBodyTestRuntime(ctx context.Context) *common.RuntimeContext {
cmd := &cobra.Command{Use: "+fetch"}
cmd.Flags().String("doc-format", "xml", "")
cmd.Flags().String("detail", "simple", "")
cmd.Flags().String("lang", "", "")
cmd.Flags().Int("revision-id", -1, "")
cmd.Flags().String("scope", "full", "")
cmd.Flags().String("start-block-id", "", "")
@@ -281,6 +324,7 @@ func newFetchShortcutTestRuntime(t *testing.T, apiVersion string, setFlags map[s
cmd.Flags().String("doc", "doxcnFetchDryRun", "")
cmd.Flags().String("doc-format", "xml", "")
cmd.Flags().String("detail", "simple", "")
cmd.Flags().String("lang", "", "")
cmd.Flags().Int("revision-id", -1, "")
cmd.Flags().String("scope", "full", "")
cmd.Flags().String("start-block-id", "", "")