Files
dingtalk-workspace-cli/internal/compat/calendar_hooks.go
修雨 4c5f1faeb1 feat: align open CLI with dws-wukong via cedar discovery version code (#509)
Switches the discovery version code bamboo -> cedar and aligns the open edition CLI with dws-wukong across communication (calendar book/acl/attendee, minutes tag, mail folder/template/contact, chat file upload, todo add-attachment, attendance transforms) and structured-office (aitable advperm/view/section/workflow/record, sheet/drive/wiki/doc) domains. Includes output-envelope parity, parse_bool/attendance_class_check_time transforms, --calendar-id support, CHANGELOG 1.0.43 and README command-index refresh. cedar config validated on pre and prod endpoints.
2026-06-26 21:49:38 +08:00

124 lines
4.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compat
import (
"strings"
apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors"
"github.com/spf13/cobra"
)
// calendarRecurrenceTools are the calendar leaves whose recurrence fields must
// be supplied as a complete set (the MCP backend does not merge partial
// recurrence, so a partial update would silently overwrite the rule). Mirrors
// wukong's calendar.go event create/update validation.
var calendarRecurrenceTools = map[string]bool{
"create_calendar_event": true,
"update_calendar_event": true,
}
// calendarRecurrenceFlags is the full set of --recurrence-* flags; touching any
// of them requires the core structural fields to be present.
var calendarRecurrenceFlags = []string{
"recurrence-type", "recurrence-interval", "recurrence-range-type",
"recurrence-count", "recurrence-end-date", "recurrence-days-of-week",
"recurrence-day-of-month", "recurrence-month", "recurrence-week-index",
"recurrence-first-day-of-week",
}
// installCalendarHook wires calendar-specific PreRunE validators onto leaf
// commands emitted by BuildDynamicCommands. No-op for non-calendar products and
// calendar tools without extra client-side checks. The hook chain preserves the
// PreRunE that NewDirectCommand already installed by invoking it first.
func installCalendarHook(cmd *cobra.Command, canonicalProduct, toolName string) {
if cmd == nil || strings.TrimSpace(canonicalProduct) != "calendar" {
return
}
if !calendarRecurrenceTools[toolName] {
return
}
original := cmd.PreRunE
cmd.PreRunE = func(c *cobra.Command, args []string) error {
if original != nil {
if err := original(c, args); err != nil {
return err
}
}
return validateCalendarRecurrence(c)
}
}
// validateCalendarRecurrence refuses a partial recurrence structure. If any
// --recurrence-* flag is set, recurrence-type / interval / range-type must be
// present, and weekly / relativeMonthly patterns require days-of-week. Error
// wording carries the kebab flag names so the messages match wukong and the
// auto-test substring assertions (days-of-week / recurrence-type).
func validateCalendarRecurrence(cmd *cobra.Command) error {
if cmd == nil {
return nil
}
used := false
for _, f := range calendarRecurrenceFlags {
if fl := cmd.Flags().Lookup(f); fl != nil && cmd.Flags().Changed(f) {
used = true
break
}
}
if !used {
return nil
}
recType := strings.TrimSpace(calendarFlagString(cmd, "recurrence-type"))
if recType == "" {
return apperrors.NewValidation(
"recurrence 结构不完整:使用任一 --recurrence-* 时必须整体重传完整循环字段" +
"(至少 --recurrence-type / --recurrence-interval / --recurrence-range-type," +
"MCP 不合并部分字段)")
}
if !calendarFlagSet(cmd, "recurrence-interval") {
return apperrors.NewValidation(
"recurrence 结构不完整:缺少 --recurrence-interval(循环间隔,recurrence 整体必填)")
}
if !calendarFlagSet(cmd, "recurrence-range-type") {
return apperrors.NewValidation(
"recurrence 结构不完整:缺少 --recurrence-range-type(循环范围类型,recurrence 整体必填)")
}
if recType == "weekly" || recType == "relativeMonthly" {
if strings.TrimSpace(calendarFlagString(cmd, "recurrence-days-of-week")) == "" {
return apperrors.NewValidation(
"weekly / relativeMonthly 循环必须提供 --recurrence-days-of-week (daysOfWeek)")
}
}
return nil
}
func calendarFlagString(cmd *cobra.Command, name string) string {
if cmd.Flags().Lookup(name) == nil {
return ""
}
v, _ := cmd.Flags().GetString(name)
return v
}
// calendarFlagSet reports whether a flag was explicitly provided by the user,
// tolerating both string and int (--recurrence-interval) flag kinds.
func calendarFlagSet(cmd *cobra.Command, name string) bool {
fl := cmd.Flags().Lookup(name)
if fl == nil {
return false
}
return cmd.Flags().Changed(name)
}