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.
124 lines
4.4 KiB
Go
124 lines
4.4 KiB
Go
// 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)
|
||
}
|