mirror of
https://github.com/larksuite/cli.git
synced 2026-08-03 08:32:46 +08:00
* fix(base): align table shortcut contracts * fix(base): treat null record projection as omitted 1. Treat select_fields:null as omitted before record-get projection conflict checks. 2. Add dry-run E2E coverage for omitted and flag-projection cases. ```ai-signature 改动范围: shortcuts/base/record_ops.go 与 tests/cli_e2e/base/base_record_list_dryrun_test.go,仅调整 record-get 对 JSON null projection 的处理和回归验证 思考过程: 保持现有 projection normalizer 与互斥规则不变,只在读取 select_fields 后把 null 与缺失键等价,避免扩大到字段上限或 auto_number 行为 改动原因: PR 1803 声明 list search get 使用统一 projection contract,但 record-get 对 select_fields:null 仍返回 invalid_argument,与 record-search 不一致 Break Change: 否;仅将此前失败的 select_fields:null 输入规范化为省略,并保留 flag projection ``` Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local> AI-SHA256: b3d37c6c026f0215d994bc7c9bad4c65caee1b3bc2e9584ff20403a4d06969c3 * refactor(base): deduplicate Base dry-run E2E setup 1. Centralize Base dry-run environment setup, timeout handling, command execution, and exit-code assertions in runBaseDryRun. 2. Migrate record projection and field update dry-run tests without changing their contract assertio ns or covered scenarios. 3. Verify all 11 affected top-level tests and four projection subtests with the current-HEAD binary under race mode. ```ai-signature 改动范围: tests/cli_e2e/base/helpers_test.go、base_record_list_dryrun_test.go 与 base_field_update_dryrun_test.go,仅收敛 dry-run 测试执行脚手架 思考过程: 复用现有测试基础设施,把环境隔离、超时、dry-run 参数、命令执行和退出码断言集中到一个 helper,同时保留每个用例的业务断言 改动原因: PR 1803 的新增测试占主要改动量,其中 11 处重复执行模板可安全去重,降低评审体量而不削减 P1 或 P2 场景覆盖 Break Change: 否 ``` Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local> AI-SHA256: ee39fef8497de65ecea1a0f22d9d87f1622c3f69daa5743ba7fd4c874dbb2ed3 --------- Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
40 lines
1.7 KiB
Go
40 lines
1.7 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package base
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/larksuite/cli/shortcuts/common"
|
|
)
|
|
|
|
var BaseRecordUpsert = common.Shortcut{
|
|
Service: "base",
|
|
Command: "+record-upsert",
|
|
Description: "Create or update a record",
|
|
Risk: "write",
|
|
Scopes: []string{"base:record:create", "base:record:update"},
|
|
AuthTypes: authTypes(),
|
|
Flags: []common.Flag{
|
|
baseTokenFlag(true),
|
|
tableRefFlag(true),
|
|
recordRefFlag(false),
|
|
{Name: "json", Desc: `record field map JSON object, e.g. {"Name":"Alice","Status":"Todo"}; do not wrap in fields`, Required: true},
|
|
},
|
|
Tips: append([]string{
|
|
"Happy path JSON is a top-level field map: each key is a real field name or field ID, each value is that field's CellValue.",
|
|
"Without --record-id this creates a record; with --record-id this updates that record. It does not auto-upsert by business key.",
|
|
"Before writing, use +field-list to confirm real writable fields; do not write system fields, formula, lookup, or attachment fields as normal CellValue.",
|
|
"Sub-record/child-record path: when a one-way/two-way link field represents hierarchy, create a normal record and set that link field to a parent record reference array, e.g. {\"Parent Link\":[{\"id\":\"rec_xxx\"}]}; do not look for parent_record_id or a separate child-record API.",
|
|
"Use the record-upsert guide for command limits and edge cases.",
|
|
}, recordCellValueHappyPathTips...),
|
|
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
|
|
return validateRecordJSON(runtime)
|
|
},
|
|
DryRun: dryRunRecordUpsert,
|
|
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
|
|
return executeRecordUpsert(runtime)
|
|
},
|
|
}
|