# @crvouga/mockingbird-service-resend 中文文档

规范地址：https://npmcn.com/package/%40crvouga/mockingbird-service-resend/

版本：3\.10\.7
npm 元数据更新时间：2026-11-03T01:30:22.072Z
中文译文更新时间：2026-11-11T02:34:58.959Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40crvouga/mockingbird-service-resend
原文对照：https://npmcn.com/package/%40crvouga/mockingbird-service-resend/?lang=original
项目主页：https://github.com/crvouga/mockingbird/tree/main/packages/service/resend#readme
源码仓库：https://github.com/crvouga/mockingbird

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：4.8 MB，28 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：6 个
- 首次发布：2026-09-22T23:57:09.429Z
- 最新版本发布：2026-11-03T01:30:21.778Z
- 近 30 天下载量：15887（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：39（近 12 个月 39 个）

## 中文简介

Resend电子邮件API的状态仿真器(以一等功率发送,收到电子邮件,附件),带有发件箱和Svix签名的入境webhoks(Mockingbird服务合同).

## 安装

```sh
npm install @crvouga/mockingbird-service-resend
```

也可以使用：`pnpm add @crvouga/mockingbird-service-resend`、`yarn add @crvouga/mockingbird-service-resend`、`bun add @crvouga/mockingbird-service-resend`

## README

# @crvouga/ mockingbird-service-resend 页面存档备份,存于互联网档案馆

> 本地模拟器。 真正的API合同. 部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

国家模拟器 **重新发送** 电子邮件 API 用于测试套房 。 每一个送货者都会在 **发件箱** 测试改为:`GET /__admin/outbox`,以及每个电子邮件中的链接). `Idempotency-Key` 重播 返回第一个发送的ID。 以 Svix 签名存储和宣布入境邮件 `email.received` webhook,和收到的电子邮件端点服务于其内容和 附录。 与 `--forward-to-inbox`,每个发送的电子邮件也会被复制到 [Maliosaur 模拟器](https://npmcn.com/package/%40crvouga/mailosaur),所以一个收件箱 持有每个代码和链接.

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/resend/SUPPORT.md)
-   `openapi.yaml` 从Resend公布的 API 引用到 `resend@4.8.0` 财务报告和审定财务报表 我们的后端电话.

## 安装

```bash
npm install -D @crvouga/mockingbird-service-resend
```

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 `npx mockingbird-resend serve`, (中文(简体) ), `createServer` 从 `./server` (节点),或 `createRuntime` 与 任何获取服务器.

## 使用量

`resend@4.x` 读取 `RESEND_BASE_URL` **当模块首次被导入时**设置在 应用程序的环境(或第一个程序之前) `import("resend")` 在测试中。 设置应用程序 `RESEND_INBOUND_WEBHOOK_SECRET` 并通过同样的 `whsec_…` 值为 `--webhook-secret`。 。 。 .

```bash
npx mockingbird-resend serve --port 8794 \
  --webhook-url http://127.0.0.1:3000/messaging/inbound/email \
  --webhook-secret "$RESEND_INBOUND_WEBHOOK_SECRET" \
  --forward-to-inbox http://127.0.0.1:8793
RESEND_BASE_URL=http://127.0.0.1:8794 node app.js
```

```ts
import { createServer } from "@crvouga/mockingbird-service-resend/server"

// Test setup: the emulator, and the base URL the Resend SDK reads at import.
const emulator = await createServer()
process.env.RESEND_BASE_URL = emulator.url
const { Resend } = await import("resend")

// The app's own Resend call.
await new Resend("re_test").emails.send({
  from: "Acme <no-reply@acme.example>",
  to: ["invitee@example.com"],
  subject: "You're invited",
  html: '<a href="https://app.test/family/invitations/claim?token=abc">Join</a>',
})

// The test reads the mail back from the outbox.
const { messages } = await (await fetch(`${emulator.url}/__admin/outbox?to=invitee@example.com`)).json()
const { links } = await (await fetch(`${emulator.url}/__admin/outbox/${messages[0].id}/links`)).json()
// links[0] === "https://app.test/family/invitations/claim?token=abc"
await emulator.close()
```

发件箱是每次发送的断言表层. 一个 `idempotencyKey` 回放第一个 发送身份证明 并留下一个信息:

```ts
import { createServer } from "@crvouga/mockingbird-service-resend/server"

const emulator = await createServer()
process.env.RESEND_BASE_URL = emulator.url
const { Resend } = await import("resend")

const resend = new Resend("re_test")
const email = { from: "no-reply@example.com", to: ["invitee@example.com"], subject: "Hi", text: "Hello" }
const first = await resend.emails.send(email, { idempotencyKey: "invite-1" })
const retry = await resend.emails.send(email, { idempotencyKey: "invite-1" })
// retry.data?.id === first.data?.id

const sent = await (await fetch(`${emulator.url}/__admin/outbox?to=invitee@example.com`)).json()
// sent.messages.length === 1
await emulator.close()
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `POST /emails` | `{from, to, subject, html?, text?, cc?, bcc?, reply_to?, headers?, tags?, attachments?, scheduled_at?}` → `{id}` (UUID). SDK让 `react` 到 HTML 发送前,模拟器会看到 HTML。 违者应答 Resend的尸体 `{statusCode, name, message}`: 422个 `missing_required_field` (单位:千美元)`Missing \`到"战地".`, or no` (简体中文)`/`文本`), 422` 校验错误 `for a malformed address (`无效的 " 从 " 字段。 电子邮件地址需要遵循..`), a tag outside` \[A-Za-z0-9--\] (中文(简体) )`, or any other contract violation.` 同上-关键`: the same key and payload replay the first 200 byte for byte (`二能重放:真实`); another payload is 409` 无效 偶数 请求`; a key still in flight is 409` 同时存在的 专有权 请求`; a key outside 1–256 characters is 400` 无效 偶发性 key' 。 只记得200多岁. |
| `GET /emails/{id}` | `emails.get`数字 : `{object: "email", id, to, from, created_at, subject, html, text, cc, bcc, reply_to, last_event: "delivered" | "scheduled", scheduled_at, headers, tags}`。 。 。 . `headers` 保存发送中的名称和值; `to` 保留原始地址格式和顺序. |
| `GET /emails` | 最新发送的电子邮件元数据, `{object: "list", has_more, data}`。 。 。 . `limit` 默认为20(1-100); `after`编号 :`before` 使用电子邮件标识并排除光标。 内容可从细节终点获得. |
| `GET /emails/receiving` | 最新收到的带有相同信封和ID光标的电子邮件元数据. 无 `limit`,返回收到的每封电子邮件;明确的限制必须是1-100。 包括附件元数据和大小. |
| `GET /emails/receiving/{id}` | 收到电子邮件: `{object: "email", id, to, from, cc, bcc, reply_to, created_at, subject, html, text, headers, message_id, attachments[{id, filename, content_type, content_disposition, content_id}]}`。 。 。 . |
| `GET /emails/receiving/{id}/attachments` | `{object: "list", has_more: false, data: [{id, filename, content_type, content_disposition, content_id, size, download_url, expires_at}]}`。 。 。 . |
| `GET /downloads/inbound/{attachment_id}` | 这个 `download_url`: 未校正的字节 `content-type` 财务报告和审定财务报表 `content-length`在非默认名称空间中, URL 携带 `/__admin/ns/<name>`。 。 。 . |

认证是 `Authorization: Bearer <key>`; 任何关键作品; 无为 401 `missing_api_key`。 。 。 .

**SDK出错映射.** `resend@4.8.0` 永远不要扔出: 一个非-2xx JSON身体 逐字回回作为 `{data: null, error: {statusCode, name, message}}`一个非JSON机构变成 `{name: "application_error", message: "Internal server error. …"}`; 已丢弃的连接 变成 `{name: "application_error", message: "Unable to fetch data. The request could not be resolved."}`。 。 。 . `resend@2.1.0` 也读作 `RESEND_BASE_URL` 导入并返回 JSON 错误对象,但是其 客户端不捕捉非 JSON 机构或被丢弃的套接字( 那些拒绝) 。 也没有 `idempotencyKey` 选项; 发送 `Idempotency-Key` 抬头,作为 `resend@4.8.0` 已经.

### 网络呼号

`POST /__admin/inbound` 存储电子邮件,然后发布到每个端点:

```json
{"type": "email.received", "created_at": "…",
 "data": {"email_id": "…", "created_at": "…", "from": "…", "to": ["care+tok@care.example"], "cc": [], "bcc": [],
          "subject": "…", "message_id": "<…>", "attachments": [{"id", "filename", "content_type", "content_disposition", "content_id"}]}}
```

和Resend一样 尸体上没有 `text`, (中文(简体) ), `html`, (中文(简体) ), `headers` 或下载 URL,所以是接收器 通过收发邮件的路线给它们水分. 过 `"inline": true` 包括他们 每个 发送由 Svix 方式签名 : `svix-id`, (中文(简体) ), `svix-timestamp` (墙钟,即使模拟器 时钟移动, `svix-signature: v1,<base64 HMAC-SHA256(secret bytes, "id.ts.body")>`编辑 正式 `svix` `Webhook.verify` 接受他们。 非-2xx 的答案被重审(立即,5 s, 5分30分2小时. `GET /__admin/webhooks`, (中文(简体) ), `…/events`, (中文(简体) ), `…/flush`, (中文(简体) ), `…/:id/replay` 财务报告和审定财务报表 `PUT /__admin/webhook-endpoints` (每个名称接收) 与合同.

### 管理员(超过标准合同)

| 路线 | 效果 |
| --- | --- |
| `GET /__admin/outcomes` | `{accepted, lost, replayed}` 发送的回复在接收后被撤回 丢失的回复 以及一能的重播. |
| `GET /__admin/outbox?to=&tag=<name>:<value>&since=&limit=` | 发邮件,最古老的第一: `{id, from, to (bare, lower-cased), toHeader, cc, bcc, replyTo, subject, html, text, tags, headers, attachments (filename, contentType, size), idempotencyKey, scheduledAt, createdAt}`。 。 。 . `tag=category` 匹配任意值. `GET /__admin/outbox/:id` 返回一个. |
| `GET /__admin/outbox/:id/links` | `{id, links}`: 每一个 `href` 在 HTML 中,实体解码(没有 HTML 时,文本中的每个 URL). |
| `POST /__admin/inbound` | `{from, to, cc?, bcc?, replyTo?, subject?, text?, html?, headers?, messageId?, attachments?: [{filename, content (base64), contentType?, contentId?, contentDisposition?}], inline?}` − 201个 `{id, webhook, event}`。 。 。 . |
| `GET /__admin/inbound` | 收到邮件,最老的第一. |
| `GET /__admin/forwarding` | `{target, forwarded, failed, lastError}` 页:1 `--forward-to-inbox`。 。 。 . |

`--forward-to-inbox <url>` 复制每个接受的发送( 不重放) 到 Mailosaur 模拟器 `POST /__admin/ingest`,在 **同名空间名称**,并等待最多2 s。 失败 收件箱从不失败发送; 计数为 `/__admin/forwarding`。将同样的密钥映射到 仿真器上的同名空间和一个工人通过Mailosaur SDK读取其转发的邮件.

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`· ; `GET /__admin/faults/presets`: `send_422` (单位:千美元)`{statusCode: 422, name: "validation_error", message}`, (中文(简体) ), `send_429` (单位:千美元)`rate_limit_exceeded` 与 `retry-after` 财务报告和审定财务报表 `ratelimit-*` 信头, `send_500` (单位:千美元)`internal_server_error`, (中文(简体) ), `non_json_500` (HTML 500页), `network_drop` (连接) 在接受之前死亡,所以没有储存, `accepted_then_network_drop` (发送被存储, 然后在任何响应字节之前连接会死;同样的键重放), `receiving_500` (收到的电子邮件路线回答500), `webhook_duplicate`, (中文(简体) ), `webhook_reorder`, (中文(简体) ), `webhook_drop`。 。 。 .

### 命名空间

`new Resend(key)` 无法添加信头, 因此将 API 密钥映射到命名空间 : `PUT /__admin/credentials {"credentials": {"<RESEND_API_KEY>": "<namespace>"}}`此外 `x-mockingbird-namespace`,或一个 `/__admin/ns/<name>` 前缀在 `RESEND_BASE_URL`。 。 。 .

### 故意不模拟

-   交付本身:没有SMTP、弹出、投诉、打开或点击,没有 `email.sent` 编号 : `email.delivered` (原始内容存档于2018-10-21). webhoks. `last_event` 实值 `delivered` 一次(`scheduled` 与 `scheduled_at`,储存但永远不放火).
-   批次发送,模板,域名, API 密钥, 受众, 联系人和广播(我们的代码调用为无) .
-   附录 `path` 未获取 URL; 发送附件只保留元数据 .
-   费率限额,但 `send_429`。 。 。 .
-   偶能窗口:密钥永远不会过期(Resend keep them 24 h).

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `ResendAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `sent()`, (中文(简体) ), `sendOutcomes()`, (中文(简体) ), `inbound()`, (中文(简体) ), `receive(input, origin)`, (中文(简体) ), `state`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `publicNamespace`, (中文(简体) ), `onSent`, (中文(简体) ), `onOutcome`。 。 。 . |
| `createRuntime` | 函数 | 全面服务合同的仿真器(健康、管理、命名空间、证书、预设、Svix Webhooks、发包)。 选项 : `webhooks: {url, secret, retryDelaysMs?, fetch?}`, (中文(简体) ), `forwardToInbox: {url, adminKey?, timeoutMs?, fetch?}`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`, (中文(简体) ), `sqlite`。 。 。 . |
| `forwardToInbox` | 函数 | 复制一个发送的电子邮件到 Mailosaur 模拟器的摄入路径. |
| `RESEND_PRESETS` | 对象 | 每个命名的断层预设. |
| `RESEND_NAMESPACE` | 字符串 | 服务名称, `"resend"`。 。 。 . |
| `DOWNLOAD_URL_TTL_MS` | 编号 | 广告的一生a `download_url` (1小时). |
| `bareAddress` | 函数 | `Name <a@b.co>` → `a@b.co` (如何发箱) `?to=` 页:1. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | 销售商为OpenAPI合同及其业务代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标(`--webhook-url`, (中文(简体) ), `--webhook-secret`, (中文(简体) ), `--forward-to-inbox`; 蚌埠8794. |

部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

## 常见问题

### @crvouga/mockingbird-service-resend 是什么？

Resend电子邮件API的状态仿真器\(以一等功率发送,收到电子邮件,附件\),带有发件箱和Svix签名的入境webhoks\(Mockingbird服务合同\)\.

### 如何安装 @crvouga/mockingbird-service-resend？

在项目目录运行 npm install @crvouga/mockingbird-service-resend，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-resend，可以用 npx mockingbird-resend 直接运行。

### @crvouga/mockingbird-service-resend 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @crvouga/mockingbird-service-resend 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @crvouga/mockingbird-service-resend 可以商用吗？

@crvouga/mockingbird-service-resend 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @crvouga/mockingbird-service-resend 的下载量有多少？

根据 npm 官方下载统计，@crvouga/mockingbird-service-resend 在 2026/10/11 – 2026/11/09 这 30 天内被下载 15,887 次，日均约 530 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @crvouga/mockingbird-service-resend 还在维护吗？

最新版本 3\.10\.7 发布于 2026/11/03（8 天前）；至今共发布 39 个版本，其中过去 12 个月发布了 39 个；首次发布于 2026/09/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

