Archived
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TM4kUBvekALu9qqmp7D3wr
365 lines
13 KiB
TypeScript
365 lines
13 KiB
TypeScript
/**
|
|
* 邮件收发的契约(设计稿 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>;
|