Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var WhiteboardUpdate = common.Shortcut{ Service: "docs", Command: "+whiteboard-update", Description: "Update an existing whiteboard in lark document with whiteboard dsl. Such DSL input from stdin. refer to lark-whiteboard skill for more details.", Risk: "high-risk-write", Scopes: []string{"board:whiteboard:node:read", "board:whiteboard:node:create", "board:whiteboard:node:delete"}, AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "idempotent-token", Desc: "idempotent token to ensure the update is idempotent. Default is empty. min length is 10.", Required: false}, {Name: "whiteboard-token", Desc: "whiteboard token of the whiteboard to update. You will need edit permission to update the whiteboard.", Required: true}, {Name: "overwrite", Desc: "overwrite the whiteboard content, delete all existing content before update. Default is false.", Required: false, Type: "bool"}, }, HasFormat: false, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if err := validate.RejectControlChars(runtime.Str("whiteboard-token"), "whiteboard-token"); err != nil { return err } itoken := runtime.Str("idempotent-token") if err := validate.RejectControlChars(itoken, "idempotent-token"); err != nil { return err } if itoken != "" && len(itoken) < 10 { return common.FlagErrorf("--idempotent-token must be at least 10 characters long.") } stat, err := os.Stdin.Stat() if err != nil || (stat.Mode()&os.ModeCharDevice) != 0 { return output.ErrValidation("read stdin failed, please follow lark-whiteboard skill to pipe in input data") } return nil }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { input, err := io.ReadAll(os.Stdin) if err != nil { return common.NewDryRunAPI().Desc("read stdin failed: " + err.Error()) } var wbOutput WbCliOutput if err := json.Unmarshal(input, &wbOutput); err != nil { return common.NewDryRunAPI().Desc("unmarshal stdin json failed: " + err.Error()) } if wbOutput.Code != 0 || wbOutput.Data.To != "openapi" { return common.NewDryRunAPI().Desc("whiteboard-draw failed. please check previous log.") } token := runtime.Str("whiteboard-token") overwrite := runtime.Bool("overwrite") descStr := "will call whiteboard open api to draw such DSL content." var delNum int if overwrite { delNum, _, err = clearWhiteboardContent(ctx, runtime, token, []string{}, true) if err != nil { return common.NewDryRunAPI().Desc("read whiteboard nodes failed: " + err.Error()) } if delNum > 0 { descStr += fmt.Sprintf("%d existing nodes deleted before update.", delNum) } } desc := common.NewDryRunAPI().Desc(descStr) desc.POST(fmt.Sprintf("/open-apis/board/v1/whiteboards/%s/nodes", common.MaskToken(url.PathEscape(token)))).Body(wbOutput.Data.Result).Desc("create all nodes of the whiteboard.") if overwrite && delNum > 0 { desc.GET(fmt.Sprintf("/open-apis/board/v1/whiteboards/%s/nodes", common.MaskToken(url.PathEscape(token)))).Desc("get all nodes of the whiteboard to delete, then filter out newly created ones.") desc.DELETE(fmt.Sprintf("/open-apis/board/v1/whiteboards/%s/nodes/batch_delete", common.MaskToken(url.PathEscape(token)))).Body("{\"ids\":[\"...\"]}"). Desc(fmt.Sprintf("delete all old nodes of the whiteboard 100 nodes at a time. This API may be called multiple times and is not reversible. %d whiteboard nodes will be deleted while update.", delNum)) } return desc }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { token := runtime.Str("whiteboard-token") overwrite := runtime.Bool("overwrite") idempotentToken := runtime.Str("idempotent-token") input, err := io.ReadAll(os.Stdin) if err != nil { return output.ErrValidation("read stdin failed: " + err.Error()) } var wbOutput WbCliOutput if err := json.Unmarshal(input, &wbOutput); err != nil { return output.Errorf(output.ExitInternal, "parsing", fmt.Sprintf("unmarshal stdin json failed: %v", err)) } if wbOutput.Code != 0 || wbOutput.Data.To != "openapi" { return output.Errorf(output.ExitValidation, "whiteboard-cli", "whiteboard-draw failed. please check previous log.") } outData := make(map[string]string) req := &larkcore.ApiReq{ HttpMethod: http.MethodPost, ApiPath: fmt.Sprintf("/open-apis/board/v1/whiteboards/%s/nodes", url.PathEscape(token)), Body: wbOutput.Data.Result, QueryParams: map[string][]string{}, } if idempotentToken != "" { req.QueryParams["client_token"] = []string{idempotentToken} } resp, err := runtime.DoAPI(req) if err != nil { return output.ErrNetwork(fmt.Sprintf("update whiteboard failed: %v", err)) } if resp.StatusCode != http.StatusOK { return output.ErrAPI(resp.StatusCode, string(resp.RawBody), nil) } var createResp createResponse err = json.Unmarshal(resp.RawBody, &createResp) if err != nil { return output.Errorf(output.ExitInternal, "parsing", fmt.Sprintf("parse whiteboard create response failed: %v", err)) } if createResp.Code != 0 { return output.ErrAPI(createResp.Code, "update whiteboard failed", fmt.Sprintf("update whiteboard failed: %s", createResp.Msg)) } outData["created_node_ids"] = strings.Join(createResp.Data.NodeIDs, ",") if overwrite { numNodes, _, err := clearWhiteboardContent(ctx, runtime, token, createResp.Data.NodeIDs, false) if err != nil { return err } outData["deleted_nodes_num"] = fmt.Sprintf("%d", numNodes) } runtime.OutFormat(outData, nil, func(w io.Writer) { if outData["deleted_nodes_num"] != "" { fmt.Fprintf(w, "%s existing nodes deleted.\n", outData["deleted_nodes_num"]) } if outData["created_node_ids"] != "" { fmt.Fprintf(w, "%d new nodes created.\n", len(createResp.Data.NodeIDs)) } fmt.Fprintf(w, "update whiteboard success") }) return nil }, }
Functions ¶
Types ¶
type WbCliOutput ¶
type WbCliOutput struct {
Code int `json:"code"`
Data WbCliOutputData
}
type WbCliOutputData ¶
type WbCliOutputData struct {
To string `json:"to"`
Result interface{} `json:"result"`
}
Click to show internal directories.
Click to hide internal directories.