@yaoyuanchao/dingtalk 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,115 @@
1
+ import { z } from 'zod';
2
+
3
+ // 定义枚举类型
4
+ export const dmPolicySchema = z.enum(['disabled', 'pairing', 'allowlist', 'open'], {
5
+ description: 'DM access control policy',
6
+ });
7
+
8
+ export const groupPolicySchema = z.enum(['disabled', 'allowlist', 'open'], {
9
+ description: 'Group chat access control policy',
10
+ });
11
+
12
+ export const messageFormatSchema = z.enum(['text', 'markdown'], {
13
+ description: 'Message format for bot responses',
14
+ });
15
+
16
+ // DingTalk 配置 Schema
17
+ export const dingTalkConfigSchema = z.object({
18
+ enabled: z.boolean().default(true).describe('Enable DingTalk channel'),
19
+
20
+ // 凭证配置(必需)
21
+ clientId: z.string().min(1, 'Client ID (AppKey) is required')
22
+ .describe('DingTalk application AppKey'),
23
+ clientSecret: z.string().min(1, 'Client Secret (AppSecret) is required')
24
+ .describe('DingTalk application AppSecret'),
25
+ robotCode: z.string().optional()
26
+ .describe('Robot code (optional, defaults to clientId if not provided)'),
27
+
28
+ // 私聊配置
29
+ dm: z.object({
30
+ enabled: z.boolean().default(true)
31
+ .describe('Enable direct messages'),
32
+ policy: dmPolicySchema.default('pairing')
33
+ .describe(
34
+ 'Access control policy:\n' +
35
+ ' - disabled: No DM allowed\n' +
36
+ ' - pairing: Show staffId on first contact, admin adds to allowlist\n' +
37
+ ' - allowlist: Only specified users can DM\n' +
38
+ ' - open: Anyone can DM (not recommended)'
39
+ ),
40
+ allowFrom: z.array(z.string()).default([])
41
+ .describe('Allowed staff IDs (for pairing/allowlist policy)'),
42
+ }).default({}),
43
+
44
+ // 群聊配置
45
+ groupPolicy: groupPolicySchema.default('allowlist')
46
+ .describe(
47
+ 'Group chat policy:\n' +
48
+ ' - disabled: No groups\n' +
49
+ ' - allowlist: Only specified groups\n' +
50
+ ' - open: All groups'
51
+ ),
52
+ groupAllowlist: z.array(z.string()).default([])
53
+ .describe('Allowed group conversation IDs (only used when groupPolicy is "allowlist")'),
54
+ requireMention: z.boolean().default(true)
55
+ .describe('Require @ mention in group chats'),
56
+
57
+ // 消息格式
58
+ messageFormat: messageFormatSchema.default('text')
59
+ .describe(
60
+ 'Message format:\n' +
61
+ ' - text: Plain text (recommended, supports tables)\n' +
62
+ ' - markdown: DingTalk markdown (limited support, no tables)'
63
+ ),
64
+
65
+ // 高级配置(可选)
66
+ textChunkLimit: z.number().int().positive().default(2000).optional()
67
+ .describe('Text chunk size limit for long messages'),
68
+ }).strict();
69
+
70
+ // 导出配置类型
71
+ export type DingTalkConfig = z.infer<typeof dingTalkConfigSchema>;
72
+
73
+ /**
74
+ * 验证 DingTalk 配置
75
+ * @param config - 原始配置对象
76
+ * @returns 验证后的配置
77
+ * @throws ZodError 如果配置无效
78
+ */
79
+ export function validateDingTalkConfig(config: unknown): DingTalkConfig {
80
+ try {
81
+ return dingTalkConfigSchema.parse(config);
82
+ } catch (error) {
83
+ if (error instanceof z.ZodError) {
84
+ const issues = error.errors.map(e => {
85
+ const path = e.path.join('.');
86
+ return ` - ${path || 'root'}: ${e.message}`;
87
+ }).join('\n');
88
+ throw new Error(`DingTalk config validation failed:\n${issues}`);
89
+ }
90
+ throw error;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * 安全地验证配置,返回错误而不抛出异常
96
+ * @param config - 原始配置对象
97
+ * @returns { success: true, data } 或 { success: false, error }
98
+ */
99
+ export function safeValidateDingTalkConfig(config: unknown):
100
+ | { success: true; data: DingTalkConfig }
101
+ | { success: false; error: string } {
102
+ try {
103
+ const data = dingTalkConfigSchema.parse(config);
104
+ return { success: true, data };
105
+ } catch (error) {
106
+ if (error instanceof z.ZodError) {
107
+ const issues = error.errors.map(e => {
108
+ const path = e.path.join('.');
109
+ return `${path || 'root'}: ${e.message}`;
110
+ }).join('; ');
111
+ return { success: false, error: issues };
112
+ }
113
+ return { success: false, error: String(error) };
114
+ }
115
+ }