mirror of
https://github.com/larksuite/cli.git
synced 2026-07-06 00:06:28 +08:00
* fix: validate base shortcut JSON object inputs * fix: reject null in base JSON object parser --------- Co-authored-by: kongenpei <kongenpei@users.noreply.github.com>
219 lines
7.2 KiB
Go
219 lines
7.2 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package base
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/larksuite/cli/shortcuts/common"
|
|
)
|
|
|
|
func dryRunFieldList(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
offset := runtime.Int("offset")
|
|
if offset < 0 {
|
|
offset = 0
|
|
}
|
|
limit := common.ParseIntBounded(runtime, "limit", 1, 200)
|
|
return common.NewDryRunAPI().
|
|
GET("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields").
|
|
Params(map[string]interface{}{"offset": offset, "limit": limit}).
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime))
|
|
}
|
|
|
|
func dryRunFieldGet(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
return common.NewDryRunAPI().
|
|
GET("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id").
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime)).
|
|
Set("field_id", runtime.Str("field-id"))
|
|
}
|
|
|
|
func dryRunFieldCreate(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
pc := newParseCtx(runtime)
|
|
body, _ := parseJSONObject(pc, runtime.Str("json"), "json")
|
|
return common.NewDryRunAPI().
|
|
POST("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields").
|
|
Body(body).
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime))
|
|
}
|
|
|
|
func dryRunFieldUpdate(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
pc := newParseCtx(runtime)
|
|
body, _ := parseJSONObject(pc, runtime.Str("json"), "json")
|
|
return common.NewDryRunAPI().
|
|
PUT("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id").
|
|
Body(body).
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime)).
|
|
Set("field_id", runtime.Str("field-id"))
|
|
}
|
|
|
|
func dryRunFieldDelete(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
return common.NewDryRunAPI().
|
|
DELETE("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id").
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime)).
|
|
Set("field_id", runtime.Str("field-id"))
|
|
}
|
|
|
|
func dryRunFieldSearchOptions(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
|
|
params := map[string]interface{}{
|
|
"offset": runtime.Int("offset"),
|
|
"limit": runtime.Int("limit"),
|
|
}
|
|
if params["limit"].(int) <= 0 {
|
|
params["limit"] = 30
|
|
}
|
|
if keyword := strings.TrimSpace(runtime.Str("keyword")); keyword != "" {
|
|
params["query"] = keyword
|
|
}
|
|
return common.NewDryRunAPI().
|
|
GET("/open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id/options").
|
|
Params(params).
|
|
Set("base_token", runtime.Str("base-token")).
|
|
Set("table_id", baseTableID(runtime)).
|
|
Set("field_id", runtime.Str("field-id"))
|
|
}
|
|
|
|
func validateFieldJSON(runtime *common.RuntimeContext) (map[string]interface{}, error) {
|
|
pc := newParseCtx(runtime)
|
|
return parseJSONObject(pc, runtime.Str("json"), "json")
|
|
}
|
|
|
|
func validateFormulaLookupGuideAck(runtime *common.RuntimeContext, command string, body map[string]interface{}) error {
|
|
fieldType := strings.ToLower(strings.TrimSpace(common.GetString(body, "type")))
|
|
if (fieldType == "formula" || fieldType == "lookup") && !runtime.Bool("i-have-read-guide") {
|
|
guidePath := "skills/lark-base/references/formula-field-guide.md"
|
|
if fieldType == "lookup" {
|
|
guidePath = "skills/lark-base/references/lookup-field-guide.md"
|
|
}
|
|
return common.FlagErrorf("--i-have-read-guide is required for %s when --json.type is %q; read %s first, then retry with --i-have-read-guide", command, fieldType, guidePath)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateFieldCreate(runtime *common.RuntimeContext) error {
|
|
body, err := validateFieldJSON(runtime)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return validateFormulaLookupGuideAck(runtime, "+field-create", body)
|
|
}
|
|
|
|
func validateFieldUpdate(runtime *common.RuntimeContext) error {
|
|
body, err := validateFieldJSON(runtime)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return validateFormulaLookupGuideAck(runtime, "+field-update", body)
|
|
}
|
|
|
|
func executeFieldList(runtime *common.RuntimeContext) error {
|
|
offset := runtime.Int("offset")
|
|
if offset < 0 {
|
|
offset = 0
|
|
}
|
|
limit := common.ParseIntBounded(runtime, "limit", 1, 200)
|
|
fields, total, err := listAllFields(runtime, runtime.Str("base-token"), baseTableID(runtime), offset, limit)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if total == 0 {
|
|
total = len(fields)
|
|
}
|
|
runtime.Out(map[string]interface{}{"fields": fields, "total": total}, nil)
|
|
return nil
|
|
}
|
|
|
|
func executeFieldGet(runtime *common.RuntimeContext) error {
|
|
baseToken := runtime.Str("base-token")
|
|
tableIDValue := baseTableID(runtime)
|
|
fieldRef := runtime.Str("field-id")
|
|
data, err := baseV3Call(runtime, "GET", baseV3Path("bases", baseToken, "tables", tableIDValue, "fields", fieldRef), nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
runtime.Out(map[string]interface{}{"field": data}, nil)
|
|
return nil
|
|
}
|
|
|
|
func executeFieldCreate(runtime *common.RuntimeContext) error {
|
|
pc := newParseCtx(runtime)
|
|
body, err := parseJSONObject(pc, runtime.Str("json"), "json")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
data, err := baseV3Call(runtime, "POST", baseV3Path("bases", runtime.Str("base-token"), "tables", baseTableID(runtime), "fields"), nil, body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
runtime.Out(map[string]interface{}{"field": data, "created": true}, nil)
|
|
return nil
|
|
}
|
|
|
|
func executeFieldUpdate(runtime *common.RuntimeContext) error {
|
|
pc := newParseCtx(runtime)
|
|
baseToken := runtime.Str("base-token")
|
|
tableIDValue := baseTableID(runtime)
|
|
body, err := parseJSONObject(pc, runtime.Str("json"), "json")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fieldRef := runtime.Str("field-id")
|
|
data, err := baseV3Call(runtime, "PUT", baseV3Path("bases", baseToken, "tables", tableIDValue, "fields", fieldRef), nil, body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
runtime.Out(map[string]interface{}{"field": data, "updated": true}, nil)
|
|
return nil
|
|
}
|
|
|
|
func executeFieldDelete(runtime *common.RuntimeContext) error {
|
|
baseToken := runtime.Str("base-token")
|
|
tableIDValue := baseTableID(runtime)
|
|
fieldRef := runtime.Str("field-id")
|
|
_, err := baseV3Call(runtime, "DELETE", baseV3Path("bases", baseToken, "tables", tableIDValue, "fields", fieldRef), nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
runtime.Out(map[string]interface{}{"deleted": true, "field_id": fieldRef, "field_name": fieldRef}, nil)
|
|
return nil
|
|
}
|
|
|
|
func executeFieldSearchOptions(runtime *common.RuntimeContext) error {
|
|
baseToken := runtime.Str("base-token")
|
|
tableIDValue := baseTableID(runtime)
|
|
fieldRef := runtime.Str("field-id")
|
|
params := map[string]interface{}{
|
|
"offset": runtime.Int("offset"),
|
|
"limit": runtime.Int("limit"),
|
|
}
|
|
if params["limit"].(int) <= 0 {
|
|
params["limit"] = 30
|
|
}
|
|
if keyword := strings.TrimSpace(runtime.Str("keyword")); keyword != "" {
|
|
params["query"] = keyword
|
|
}
|
|
data, err := baseV3Call(runtime, "GET", baseV3Path("bases", baseToken, "tables", tableIDValue, "fields", fieldRef, "options"), params, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
options, _ := data["options"].([]interface{})
|
|
total := toInt(data["total"])
|
|
if total == 0 {
|
|
total = len(options)
|
|
}
|
|
runtime.Out(map[string]interface{}{
|
|
"field_id": fieldRef,
|
|
"field_name": fieldRef,
|
|
"keyword": strings.TrimSpace(runtime.Str("keyword")),
|
|
"options": options,
|
|
"total": total,
|
|
}, nil)
|
|
return nil
|
|
}
|