Files
wehub-resource-sync bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:54 +08:00

133 lines
4.6 KiB
Go

// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package okr
import (
"context"
"encoding/json"
"fmt"
"io"
"strconv"
"github.com/larksuite/cli/errs"
"github.com/larksuite/cli/shortcuts/common"
)
// OKRGetProgressRecord gets a progress by ID.
var OKRGetProgressRecord = common.Shortcut{
Service: "okr",
Command: "+progress-get",
Description: "Get an OKR progress by ID",
Risk: "read",
Scopes: []string{"okr:okr.progress:readonly"},
AuthTypes: []string{"user", "bot"},
HasFormat: true,
Flags: []common.Flag{
{Name: "progress-id", Desc: "progress ID (int64)", Required: true},
{Name: "user-id-type", Default: "open_id", Desc: "user ID type: open_id | union_id | user_id"},
{Name: "style", Default: "simple", Desc: "output style: simple (semi-plain text JSON) | richtext (ContentBlock JSON)", Enum: []string{"simple", "richtext"}},
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
progressID := runtime.Str("progress-id")
if progressID == "" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--progress-id is required").WithParam("--progress-id")
}
if id, err := strconv.ParseInt(progressID, 10, 64); err != nil || id <= 0 {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--progress-id must be a positive int64").WithParam("--progress-id")
}
idType := runtime.Str("user-id-type")
if idType != "open_id" && idType != "union_id" && idType != "user_id" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--user-id-type must be one of: open_id | union_id | user_id").WithParam("--user-id-type")
}
style := runtime.Str("style")
if style != "simple" && style != "richtext" {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "--style must be one of: simple | richtext").WithParam("--style")
}
return nil
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
progressID := runtime.Str("progress-id")
params := map[string]interface{}{
"user_id_type": runtime.Str("user-id-type"),
}
return common.NewDryRunAPI().
GET("/open-apis/okr/v1/progress_records/:progress_id").
Params(params).
Set("progress_id", progressID).
Desc("Get OKR progress")
},
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
progressID := runtime.Str("progress-id")
userIDType := runtime.Str("user-id-type")
style := runtime.Str("style")
queryParams := map[string]interface{}{"user_id_type": userIDType}
path := fmt.Sprintf("/open-apis/okr/v1/progress_records/%s", progressID)
data, err := runtime.CallAPITyped("GET", path, queryParams, nil)
if err != nil {
return err
}
record, err := parseProgressRecord(data)
if err != nil {
return err
}
var result map[string]interface{}
if style == "simple" {
resp := record.ToSimple()
result = map[string]interface{}{
"progress": resp,
"style": style,
}
runtime.OutFormat(result, nil, func(w io.Writer) {
fmt.Fprintf(w, "Progress [%s] (style: %s)\n", resp.ID, style)
fmt.Fprintf(w, " ModifyTime: %s\n", resp.ModifyTime)
if resp.ProgressRate != nil && resp.ProgressRate.Percent != nil {
fmt.Fprintf(w, " ProgressRate: %.1f%%\n", *resp.ProgressRate.Percent)
}
if resp.Content != nil {
fmt.Fprintf(w, " Content: %s\n", resp.Content.Text)
if len(resp.Content.Mention) > 0 {
fmt.Fprintf(w, " Mentions: %v\n", resp.Content.Mention)
}
}
})
} else {
resp := record.ToResp()
result = map[string]interface{}{
"progress": resp,
"style": style,
}
runtime.OutFormat(result, nil, func(w io.Writer) {
fmt.Fprintf(w, "Progress [%s] (style: %s)\n", resp.ID, style)
fmt.Fprintf(w, " ModifyTime: %s\n", resp.ModifyTime)
if resp.ProgressRate != nil && resp.ProgressRate.Percent != nil {
fmt.Fprintf(w, " ProgressRate: %.1f%%\n", *resp.ProgressRate.Percent)
}
if resp.Content != nil {
fmt.Fprintf(w, " Content: %s\n", *resp.Content)
}
})
}
return nil
},
}
// parseProgressRecord parses a single progress from API response data.
func parseProgressRecord(data map[string]any) (*ProgressV1, error) {
raw, err := json.Marshal(data)
if err != nil {
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "invalid progress response: marshal failed: %s", err).WithCause(err)
}
var record ProgressV1
if err := json.Unmarshal(raw, &record); err != nil {
return nil, errs.NewInternalError(errs.SubtypeInvalidResponse, "invalid progress response: unmarshal failed: %s", err).WithCause(err)
}
return &record, nil
}