fix(cli,plugin-email)!: 缺 apiKey 的 resend/postmark 不再静默降级为 LogTransport (#5132) - #5153
Merged
Merged
Conversation
…Key fails the boot instead of becoming a LogTransport (#5132) `resolveEmailCapabilityArg` answered a missing API key by rewriting the provider to `log`, printing a warning, and booting: a server that accepted every send, recorded each in `sys_email` as sent, and delivered nothing. #5087 closed that inside plugin-email (`makeTransport` throws rather than substituting a transport); the CLI kept doing it one layer up, which the #5087 PR itself flagged in this function's docstring. It now refuses every mail configuration it cannot deliver through, the way its neighbouring `smtp` arm already did — resend/postmark with no key, and a provider tag outside the supported set (retired `sendgrid`/`ses` get the SMTP migration). Each message names the consequence and both fixes, per AGENTS.md degradation-log-level. Refusing is only fair because `OS_EMAIL_PROVIDER=log` is how a deployment says "no mail from here" — a test pins that it still boots. The provider vocabulary is read from `@objectstack/plugin-email` (`isEmailTransportProvider` / `unsupportedProviderFix` from #5094, plus the new `API_KEY_EMAIL_PROVIDERS` / `emailProviderRequiresApiKey`) rather than restated in the CLI, and the new constant is tied to `makeTransport` by a compile error in one direction and a contract test in the other. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017MCKJaEomEqg4tvz4SzdNd
…-email-provider-loud
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 24 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5132
改了什么
packages/cli/src/commands/serve.ts的resolveEmailCapabilityArg里,provider非log/smtp且缺apiKey时把 provider 改写成log、打一条 warning、照常启动的那段没了。现在与紧邻的smtp分支同形:建不出投递通道就抛,由 capability 循环把它变成响亮失败。覆盖三种「声明了投递意图但投不出去」的配置:
OS_EMAIL_PROVIDER=resend/postmark,无OS_EMAIL_API_KEYlog+ warning,正常启动OS_EMAIL_PROVIDER=sendgrid(已退役)/ 拼错的 taglog;有 key 时透传到插件层再抛OS_EMAIL_PROVIDER=smtp无 host「响亮失败」的准确含义(未夸大):app 在
requires: [...]里显式声明了email时是硬启动失败;email是平台自动补齐的默认能力时,是console.error+ 不挂载 email 服务。两种都不再是「每封都成功、一封没发出」——这与smtp分支现有行为完全一致。抛错成立的前提是「本环境不发信」有说得出口的写法:
OS_EMAIL_PROVIDER=log(也是默认值)。测试专门钉住了这一条仍能正常启动。错误消息按 AGENTS.md degradation-log-level 同时给出后果与修复,措辞照抄
smtp缺 host 那条的形状:provider 词汇表:复用而非重写
按裁定要求,CLI 不再自己写
provider !== 'log' && provider !== 'smtp',而是从@objectstack/plugin-email(#5133 合入的单一真相)读:isEmailTransportProvider/unsupportedProviderFix。「哪些 provider 需要 apiKey」此前没有共享形式(
makeTransport的 switch 里、mail.manifest.ts里各有一份),所以本 PR 在同一个文件里补上:API_KEY_EMAIL_PROVIDERS(satisfies readonly EmailTransportProvider[])、ApiKeyEmailProvider、emailProviderRequiresApiKey();makeTransport的resend/postmark分支改走requireApiKey(provider, apiKey),其形参类型是ApiKeyEmailProvider—— 常量里删掉一个 tag,switch 直接编译不过(这是一个方向的锁);transports/api-key-providers.contract.test.ts遍历EMAIL_TRANSPORT_PROVIDERS逐个实测makeTransport的真实行为钉住。makeTransport抛出的文案与改前逐字一致,插件层行为不变。破坏性变更
@objectstack/cli记为 major,changeset 里写明了受影响人群与迁移:只设OS_EMAIL_PROVIDER=resend|postmark而不配 key、靠降级启动的部署(典型是 CI / preview 环境),两条一行修法——改成OS_EMAIL_PROVIDER=log,或补上OS_EMAIL_API_KEY。完整配置、以及不设OS_EMAIL_PROVIDER的默认路径都不受影响。顺带把
content/docs/deployment/environment-variables.mdx的OS_EMAIL_API_KEY一行改成 Required(参照同表OS_EMAIL_SMTP_HOST的写法),并点明log是「本环境不发信」的声明方式。测试
serve-email-capability.test.ts:钉降级行为的那条用例已翻面(postmark无 key 从「断言回落到 log」改为「断言抛错 + 消息里同时有后果、OS_EMAIL_API_KEY、OS_EMAIL_PROVIDER=log」),另加显式OS_EMAIL_PROVIDER=log仍能启动、未知/退役 provider 抛错并带迁移、完整 resend/postmark 配置原样透传三条;warning字段随最后一个生产者一起删除(接口上不再保留没人写入的降级通道)。越界发现
packages/spec/src/system/email-config.zod.ts的EmailProviderSchema缺'smtp'、TSDoc 仍称 SMTP 不随 plugin-email 发布 —— 已有 spec: EmailProviderSchema 缺 'smtp',TSDoc 仍称 SMTP 不随 plugin-email 发布(#5087 落地后为假) #5104 在跟,未重复开单,本 PR 也未碰packages/spec。🤖 Generated with Claude Code
https://claude.ai/code/session_017MCKJaEomEqg4tvz4SzdNd
Generated by Claude Code