Archived
mail.send 工具契约 2.0.0(to 数组 / html / 附件 / inReplyTo / dryRun;保留 v1 的 body 与 queued);契约快照刷新,五道门禁绿
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TM4kUBvekALu9qqmp7D3wr
This commit is contained in:
+364
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
* 邮件收发的契约(设计稿 docs/superpowers/specs/2026-08-25-mail-design.md §7.1;ADR-013)。
|
||||
*
|
||||
* 只有 zod schema 与推导类型。账号视图**永不含密文**(ADR-009 §4):只回 `secretBound`。
|
||||
* 入参按 `kind` 分两形 —— 标准协议(IMAP/SMTP)与企业微信邮件 API(应用邮箱),
|
||||
* 两条路的共同点是「轮询拉 + MIME 解析」,腾讯没有带内容的推送。
|
||||
*/
|
||||
import { z } from 'zod';
|
||||
export declare const MAIL_ACCOUNT_KINDS: readonly ["imap-smtp", "wecom"];
|
||||
export declare const mailAccountKindSchema: z.ZodEnum<{
|
||||
"imap-smtp": "imap-smtp";
|
||||
wecom: "wecom";
|
||||
}>;
|
||||
export type MailAccountKind = z.infer<typeof mailAccountKindSchema>;
|
||||
export declare const MAIL_ACCOUNT_KIND_LABEL: Readonly<Record<MailAccountKind, string>>;
|
||||
/** 标准协议:默认值就是腾讯企业邮箱官方帮助给的服务器与 SSL 端口 */
|
||||
export declare const imapSmtpSettingsSchema: z.ZodObject<{
|
||||
imapHost: z.ZodDefault<z.ZodString>;
|
||||
imapPort: z.ZodDefault<z.ZodNumber>;
|
||||
imapTls: z.ZodDefault<z.ZodBoolean>;
|
||||
smtpHost: z.ZodDefault<z.ZodString>;
|
||||
smtpPort: z.ZodDefault<z.ZodNumber>;
|
||||
smtpTls: z.ZodDefault<z.ZodBoolean>;
|
||||
login: z.ZodOptional<z.ZodString>;
|
||||
folder: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type ImapSmtpSettings = z.infer<typeof imapSmtpSettingsSchema>;
|
||||
/** 企业微信邮件 API:corpid + 自建应用 secret(密封,不在 settings 里) */
|
||||
export declare const wecomSettingsSchema: z.ZodObject<{
|
||||
corpId: z.ZodString;
|
||||
apiBase: z.ZodDefault<z.ZodURL>;
|
||||
}, z.core.$strip>;
|
||||
export type WecomSettings = z.infer<typeof wecomSettingsSchema>;
|
||||
export declare const mailAccountInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
||||
settings: z.ZodPrefault<z.ZodObject<{
|
||||
imapHost: z.ZodDefault<z.ZodString>;
|
||||
imapPort: z.ZodDefault<z.ZodNumber>;
|
||||
imapTls: z.ZodDefault<z.ZodBoolean>;
|
||||
smtpHost: z.ZodDefault<z.ZodString>;
|
||||
smtpPort: z.ZodDefault<z.ZodNumber>;
|
||||
smtpTls: z.ZodDefault<z.ZodBoolean>;
|
||||
login: z.ZodOptional<z.ZodString>;
|
||||
folder: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
secret: z.ZodOptional<z.ZodObject<{
|
||||
password: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
name: z.ZodString;
|
||||
displayName: z.ZodDefault<z.ZodString>;
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
isDefault: z.ZodDefault<z.ZodBoolean>;
|
||||
pollIntervalSec: z.ZodDefault<z.ZodNumber>;
|
||||
channelId: z.ZodDefault<z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ChannelId", "out">>>;
|
||||
backfillFrom: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
||||
kind: z.ZodLiteral<"imap-smtp">;
|
||||
address: z.ZodEmail;
|
||||
}, z.core.$strip>, z.ZodObject<{
|
||||
settings: z.ZodObject<{
|
||||
corpId: z.ZodString;
|
||||
apiBase: z.ZodDefault<z.ZodURL>;
|
||||
}, z.core.$strip>;
|
||||
secret: z.ZodOptional<z.ZodObject<{
|
||||
corpSecret: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
name: z.ZodString;
|
||||
displayName: z.ZodDefault<z.ZodString>;
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
isDefault: z.ZodDefault<z.ZodBoolean>;
|
||||
pollIntervalSec: z.ZodDefault<z.ZodNumber>;
|
||||
channelId: z.ZodDefault<z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ChannelId", "out">>>;
|
||||
backfillFrom: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
||||
kind: z.ZodLiteral<"wecom">;
|
||||
}, z.core.$strip>], "kind">;
|
||||
export type MailAccountInput = z.infer<typeof mailAccountInputSchema>;
|
||||
export declare const mailAccountStatusSchema: z.ZodObject<{
|
||||
lastPolledAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
lastPollError: z.ZodNullable<z.ZodString>;
|
||||
lastInboundAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
cursor: z.ZodNullable<z.ZodString>;
|
||||
polling: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
export declare const mailAccountViewSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
||||
settings: z.ZodObject<{
|
||||
imapHost: z.ZodDefault<z.ZodString>;
|
||||
imapPort: z.ZodDefault<z.ZodNumber>;
|
||||
imapTls: z.ZodDefault<z.ZodBoolean>;
|
||||
smtpHost: z.ZodDefault<z.ZodString>;
|
||||
smtpPort: z.ZodDefault<z.ZodNumber>;
|
||||
smtpTls: z.ZodDefault<z.ZodBoolean>;
|
||||
login: z.ZodOptional<z.ZodString>;
|
||||
folder: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
address: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
enabled: z.ZodBoolean;
|
||||
isDefault: z.ZodBoolean;
|
||||
pollIntervalSec: z.ZodNumber;
|
||||
channelId: z.ZodNullable<z.ZodString>;
|
||||
backfillFrom: z.ZodNullable<z.ZodISODateTime>;
|
||||
secretBound: z.ZodBoolean;
|
||||
status: z.ZodObject<{
|
||||
lastPolledAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
lastPollError: z.ZodNullable<z.ZodString>;
|
||||
lastInboundAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
cursor: z.ZodNullable<z.ZodString>;
|
||||
polling: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
createdAt: z.ZodISODateTime;
|
||||
updatedAt: z.ZodISODateTime;
|
||||
kind: z.ZodLiteral<"imap-smtp">;
|
||||
}, z.core.$strip>, z.ZodObject<{
|
||||
settings: z.ZodObject<{
|
||||
corpId: z.ZodString;
|
||||
apiBase: z.ZodDefault<z.ZodURL>;
|
||||
}, z.core.$strip>;
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
address: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
enabled: z.ZodBoolean;
|
||||
isDefault: z.ZodBoolean;
|
||||
pollIntervalSec: z.ZodNumber;
|
||||
channelId: z.ZodNullable<z.ZodString>;
|
||||
backfillFrom: z.ZodNullable<z.ZodISODateTime>;
|
||||
secretBound: z.ZodBoolean;
|
||||
status: z.ZodObject<{
|
||||
lastPolledAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
lastPollError: z.ZodNullable<z.ZodString>;
|
||||
lastInboundAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
cursor: z.ZodNullable<z.ZodString>;
|
||||
polling: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
createdAt: z.ZodISODateTime;
|
||||
updatedAt: z.ZodISODateTime;
|
||||
kind: z.ZodLiteral<"wecom">;
|
||||
}, z.core.$strip>], "kind">;
|
||||
export type MailAccountView = z.infer<typeof mailAccountViewSchema>;
|
||||
/** 探测报告:收 / 发各说各的;wecom 的发信一栏 `checked:false` —— 拿到 token 不等于能发 */
|
||||
export declare const mailProbeReportSchema: z.ZodObject<{
|
||||
kind: z.ZodEnum<{
|
||||
"imap-smtp": "imap-smtp";
|
||||
wecom: "wecom";
|
||||
}>;
|
||||
address: z.ZodOptional<z.ZodString>;
|
||||
receive: z.ZodObject<{
|
||||
ok: z.ZodBoolean;
|
||||
error: z.ZodOptional<z.ZodString>;
|
||||
latencyMs: z.ZodOptional<z.ZodNumber>;
|
||||
}, z.core.$strip>;
|
||||
send: z.ZodObject<{
|
||||
checked: z.ZodBoolean;
|
||||
ok: z.ZodOptional<z.ZodBoolean>;
|
||||
error: z.ZodOptional<z.ZodString>;
|
||||
note: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>;
|
||||
export type MailProbeReport = z.infer<typeof mailProbeReportSchema>;
|
||||
export declare const MAIL_DELIVERY_STATES: readonly ["dispatching", "done", "failed", "skipped"];
|
||||
export declare const mailDeliveryStateSchema: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
done: "done";
|
||||
dispatching: "dispatching";
|
||||
skipped: "skipped";
|
||||
}>;
|
||||
export type MailDeliveryState = z.infer<typeof mailDeliveryStateSchema>;
|
||||
export declare const mailDeliveryViewSchema: z.ZodObject<{
|
||||
subscriber: z.ZodString;
|
||||
state: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
done: "done";
|
||||
dispatching: "dispatching";
|
||||
skipped: "skipped";
|
||||
}>;
|
||||
error: z.ZodNullable<z.ZodString>;
|
||||
startedAt: z.ZodISODateTime;
|
||||
finishedAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
}, z.core.$strip>;
|
||||
export type MailDeliveryView = z.infer<typeof mailDeliveryViewSchema>;
|
||||
export declare const mailAddressSchema: z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type MailAddress = z.infer<typeof mailAddressSchema>;
|
||||
export declare const mailInboundAttachmentSchema: z.ZodObject<{
|
||||
index: z.ZodNumber;
|
||||
name: z.ZodString;
|
||||
contentType: z.ZodString;
|
||||
size: z.ZodNumber;
|
||||
ref: z.ZodNullable<z.ZodString>;
|
||||
note: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type MailInboundAttachment = z.infer<typeof mailInboundAttachmentSchema>;
|
||||
export declare const mailInboundSummarySchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
accountId: z.ZodString;
|
||||
messageId: z.ZodString;
|
||||
from: z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
to: z.ZodArray<z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
cc: z.ZodArray<z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
subject: z.ZodString;
|
||||
sentAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
receivedAt: z.ZodISODateTime;
|
||||
textPreview: z.ZodString;
|
||||
hasHtml: z.ZodBoolean;
|
||||
attachments: z.ZodArray<z.ZodObject<{
|
||||
index: z.ZodNumber;
|
||||
name: z.ZodString;
|
||||
contentType: z.ZodString;
|
||||
size: z.ZodNumber;
|
||||
ref: z.ZodNullable<z.ZodString>;
|
||||
note: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
deliveries: z.ZodArray<z.ZodObject<{
|
||||
subscriber: z.ZodString;
|
||||
state: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
done: "done";
|
||||
dispatching: "dispatching";
|
||||
skipped: "skipped";
|
||||
}>;
|
||||
error: z.ZodNullable<z.ZodString>;
|
||||
startedAt: z.ZodISODateTime;
|
||||
finishedAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export type MailInboundSummary = z.infer<typeof mailInboundSummarySchema>;
|
||||
export declare const mailInboundDetailSchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
accountId: z.ZodString;
|
||||
messageId: z.ZodString;
|
||||
from: z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
to: z.ZodArray<z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
cc: z.ZodArray<z.ZodObject<{
|
||||
address: z.ZodString;
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
subject: z.ZodString;
|
||||
sentAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
receivedAt: z.ZodISODateTime;
|
||||
textPreview: z.ZodString;
|
||||
hasHtml: z.ZodBoolean;
|
||||
attachments: z.ZodArray<z.ZodObject<{
|
||||
index: z.ZodNumber;
|
||||
name: z.ZodString;
|
||||
contentType: z.ZodString;
|
||||
size: z.ZodNumber;
|
||||
ref: z.ZodNullable<z.ZodString>;
|
||||
note: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
deliveries: z.ZodArray<z.ZodObject<{
|
||||
subscriber: z.ZodString;
|
||||
state: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
done: "done";
|
||||
dispatching: "dispatching";
|
||||
skipped: "skipped";
|
||||
}>;
|
||||
error: z.ZodNullable<z.ZodString>;
|
||||
startedAt: z.ZodISODateTime;
|
||||
finishedAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
}, z.core.$strip>>;
|
||||
inReplyTo: z.ZodNullable<z.ZodString>;
|
||||
references: z.ZodArray<z.ZodString>;
|
||||
text: z.ZodNullable<z.ZodString>;
|
||||
html: z.ZodNullable<z.ZodString>;
|
||||
size: z.ZodNumber;
|
||||
rawAvailable: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
export type MailInboundDetail = z.infer<typeof mailInboundDetailSchema>;
|
||||
export declare const mailSendInputSchema: z.ZodObject<{
|
||||
accountId: z.ZodOptional<z.ZodString>;
|
||||
from: z.ZodOptional<z.ZodString>;
|
||||
to: z.ZodArray<z.ZodEmail>;
|
||||
cc: z.ZodDefault<z.ZodArray<z.ZodEmail>>;
|
||||
bcc: z.ZodDefault<z.ZodArray<z.ZodEmail>>;
|
||||
subject: z.ZodString;
|
||||
text: z.ZodOptional<z.ZodString>;
|
||||
html: z.ZodOptional<z.ZodString>;
|
||||
inReplyTo: z.ZodOptional<z.ZodString>;
|
||||
references: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
attachments: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
contentType: z.ZodDefault<z.ZodString>;
|
||||
dataBase64: z.ZodOptional<z.ZodString>;
|
||||
uploadRef: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>>;
|
||||
idempotencyKey: z.ZodOptional<z.ZodString>;
|
||||
requestedBy: z.ZodObject<{
|
||||
kind: z.ZodEnum<{
|
||||
channel: "channel";
|
||||
tool: "tool";
|
||||
ops: "ops";
|
||||
}>;
|
||||
taskId: z.ZodOptional<z.ZodString>;
|
||||
staffId: z.ZodOptional<z.ZodString>;
|
||||
tool: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>;
|
||||
export type MailSendInput = z.infer<typeof mailSendInputSchema>;
|
||||
export declare const MAIL_OUTBOUND_STATES: readonly ["sending", "sent", "failed"];
|
||||
export declare const mailOutboundStateSchema: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
sending: "sending";
|
||||
sent: "sent";
|
||||
}>;
|
||||
export type MailOutboundState = z.infer<typeof mailOutboundStateSchema>;
|
||||
export declare const mailSendResultSchema: z.ZodObject<{
|
||||
outboundId: z.ZodString;
|
||||
accountId: z.ZodString;
|
||||
messageId: z.ZodString;
|
||||
state: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
sent: "sent";
|
||||
}>;
|
||||
error: z.ZodOptional<z.ZodString>;
|
||||
providerRef: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type MailSendResult = z.infer<typeof mailSendResultSchema>;
|
||||
export declare const mailOutboundViewSchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
accountId: z.ZodString;
|
||||
messageId: z.ZodString;
|
||||
to: z.ZodArray<z.ZodString>;
|
||||
cc: z.ZodArray<z.ZodString>;
|
||||
bcc: z.ZodArray<z.ZodString>;
|
||||
subject: z.ZodString;
|
||||
state: z.ZodEnum<{
|
||||
failed: "failed";
|
||||
sending: "sending";
|
||||
sent: "sent";
|
||||
}>;
|
||||
error: z.ZodNullable<z.ZodString>;
|
||||
providerRef: z.ZodNullable<z.ZodString>;
|
||||
requestedBy: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
||||
createdAt: z.ZodISODateTime;
|
||||
sentAt: z.ZodNullable<z.ZodISODateTime>;
|
||||
}, z.core.$strip>;
|
||||
export type MailOutboundView = z.infer<typeof mailOutboundViewSchema>;
|
||||
export declare const mailPollOutcomeSchema: z.ZodObject<{
|
||||
accountId: z.ZodString;
|
||||
pulled: z.ZodNumber;
|
||||
stored: z.ZodNumber;
|
||||
dispatched: z.ZodNumber;
|
||||
more: z.ZodBoolean;
|
||||
error: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type MailPollOutcome = z.infer<typeof mailPollOutcomeSchema>;
|
||||
Reference in New Issue
Block a user