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

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

版本：3\.11\.0
npm 元数据更新时间：2026-11-11T02:16:43.946Z
中文译文更新时间：2026-11-11T02:33:41.917Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：4.5 MB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：3 个
- 首次发布：2026-09-22T23:54:39.127Z
- 最新版本发布：2026-11-11T02:16:43.536Z
- 近 30 天下载量：16127（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：41（近 12 个月 41 个）

## 中文简介

Healthie GraphQL API (Legacy surface) 的状态仿真器: 签名 In, 用户, 当前用户, 更新 User/ updateClient( 包括多部分的avatar), 地址, 文件和文件夹, 服务下载, 格式答案, 提供, 计费项目, IP- allowl

## 安装

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

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

## README

# @crvouga/mockingbird-service-healthie (英语)

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

国家模拟器 **健康图QL API**覆盖着遗产 仍然暴露我们的后端 电话:

-   签名、用户、当前用户以及配置、密码和外观更新
-   客户端更新和地址
-   文档和文件夹,包括多部分上传,下载由模拟器提供
-   请求的窗体和窗体答案
-   提供和收费项目
-   iP 允许列表状态的 Webhooks

图QL 文档运行在引用上 [`graphql`](https://www.npmjs.com/package/graphql) 与Healthie用手写的一套计划相对应 选择集,别名, 碎片,变量, `__typename` 和验证错误的行为 健康, 模拟器只返回文档要求的字段 .

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/healthie/SUPPORT.md)
-   健康出版SDL但无OpenAPI. `openapi.yaml` 描述 HTTP 侧: 一个 GraphQL 操作和文件下载路径。 GraphQL 计划为 `HEALTHIE_SDL`。 。 。 .

> **这值得测试吗?** 目录(S23)将"健康"标为"遗产". 任用和 供应商搬到了Medplum。 剩下的是遗留的签名、密码重置、配置和 地址、ODX文档上传、管理导出和迁移。 检查一个套房仍然 练习这些路径,然后将模拟器接入堆栈。 已充分执行 无论是哪种方式.

## 安装

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

仅限无害环境管理。 节点 22或 Bun 1.2. 单程依赖之外 `hono` 是大众 `graphql` 软件包(以16.11.0为基准,我们的后端使用版本)。 见 [为什么 `graphql`](https://npmcn.com/package/%40crvouga/mockingbird-service-healthie/#readme-why-graphql-is-a-runtime-dependency){\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}为它服务 `npx mockingbird-healthie serve`, (中文(简体) ), `createServer` 从 `./server` (节点),或 `createRuntime` 与任何获取服务器.

## 使用量

点 `HEALTHIE_API_URL` 时间 `http://127.0.0.1:8816/graphql`。这需要缝合 **G-H1级** 第一条: 后端的Joi和zod计划目前只接受中转或推进的URL,以及 `HEALTHIE_WEBHOOK_IP_ADDRESS` 只有两个IP列表。 设定 `HEALTHIE_API_AUTH_TOKEN` 在应用程序中 并传递与 `--api-key`。 。 。 .

```bash
npx mockingbird-healthie serve --port 8816 \
  --api-key "$HEALTHIE_API_AUTH_TOKEN" \
  --webhook-base-url http://127.0.0.1:3000 \
  --webhook-ip 18.206.70.225
```

```ts
import { GraphQLClient, gql } from "graphql-request"
import { createRuntime, SEED } from "@crvouga/mockingbird-service-healthie"

// Test setup: the emulator, in this process.
const emulator = createRuntime({
  settings: { orgApiKeys: ["gh_sbox_test_org"] },
  webhooks: { baseUrl: "http://127.0.0.1:3000", ip: "18.206.70.225" },
})

// Application code: the GraphQL client the app already uses (here graphql-request). Only its
// fetch changes: requests reach the emulator instead of api.gethealthie.com.
const healthie = new GraphQLClient("https://api.gethealthie.com/graphql", {
  headers: { AuthorizationSource: "API" },
  fetch: ((url: RequestInfo | URL, init?: RequestInit) =>
    emulator.fetch(new Request(url, init))) as typeof fetch,
})

// The seeded demo patient signs in and gets an API key, as the member app does.
const signedIn = await healthie.request<{ signIn: { api_key: string; user: { id: string } } }>(
  gql`
    mutation ($e: String, $p: String) {
      signIn(input: { email: $e, password: $p, generate_api_token: true }) {
        api_key
        user { id active }
      }
    }
  `,
  { e: SEED.patientEmail, p: SEED.patientPassword },
)

// Test control: ask Healthie to request a form from the patient. POST /forms/webhooks/status
// follows.
await emulator.fetch(
  new Request("http://healthie.test/__admin/requested-forms", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ recipient_id: SEED.patientId }),
  }),
)
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `POST /graphql` | 以JSON形式发出的每一份请求文件 `{query, variables, operationName}` 或作为 [图QL 多部分请求](https://github.com/jaydenseric/graphql-multipart-request-spec) (单位:千美元)`operations`, (中文(简体) ), `map`,文件部分)用于 `Upload` 变量。 这个 `Authorization` 标题将 API 密钥作为 `Bearer <key>`, (中文(简体) ), `Basic <key>` 或空钥匙. `AuthorizationSource: API` 被接受和忽略。 错误会随着HTTP 200而出现,如Healthie. 一个不是GraphQL的身体得到一个400. |
| `GET /files/{token}` | 后面的字节 `document.expiring_url` 财务报告和审定财务报表 `user.avatar_url`,这里关于请求本身的来源(与 `/__admin/ns/<name>` 当名称空格。 链接在模拟器时钟上签名并过期( L)`expiringUrlSeconds`,默认为300). 被篡改或过期的链接得到一个403,被删除的文件得到一个404. 每次下载都会增加一个条目 `document.opens`。 。 。 . |

图QL 根字段 : `currentUser`, (中文(简体) ), `user(id)`, (中文(简体) ), `users(keywords, should_paginate, …)`, (中文(简体) ), `location(id)`, (中文(简体) ), `locations`, (中文(简体) ), `documents(…)`, (中文(简体) ), `document(id)`, (中文(简体) ), `folders(…)`, (中文(简体) ), `requestedFormCompletion(id)`, (中文(简体) ), `formAnswerGroups(user_id, …)`, (中文(简体) ), `formAnswerGroup(id)`, (中文(简体) ), `initialFormAnswers(custom_module_form_id, incomplete_form_id, user_id)`, (中文(简体) ), `offerings(client_visibility, offering_id, …)` 财务报告和审定财务报表 `billingItems(offerings_only, client_id, status)`。 。 。 .

变异 :

-   `signIn(input)`数字 : `generate_api_token` 财务报告和审定财务报表 `allow_multiple_api_keys` 将受优待 `namespace` 当一个被设定的时候.
-   `updateUser(input)`: 设置配置字段, 上传一个外观为 `Upload`,用 `avatar: null`,或更改密码。 密码变体发送出否 `id` 检查 `current_password` 财务报告和审定财务报表 `password_confirmation`。 。 。 .
-   `updateClient(input)`数字 : `metadata`, (中文(简体) ), `phone_number`, (中文(简体) ), `password`, (中文(简体) ), `other_provider_ids`, (中文(简体) ), `user_group_id`, (中文(简体) ), `dietitian_id`, (中文(简体) ), `active`,以及 `location` 作为 `ClientLocationInput`。 。 。 .
-   `createLocation` 财务报告和审定财务报表 `updateLocation`。 。 。 .
-   `createFolder`: 剖析 `share_users` 以 `"user-<id>,…"`。 。 。 .
-   `createDocument`: 取一个 `Upload` 或一个 `file_string` 数据 URL,加 `share_users` 财务报告和审定财务报表 `rel_user_id`。 。 。 .
-   `deleteDocument`。 。 。 .
-   `updateBillingItem`数字 : `is_paused`, (中文(简体) ), `is_canceled`, (中文(简体) ), `note` 财务报告和审定财务报表 `state`我们的客户发送它作为 两个别名在一个文档中的变异; 每个发出 `billing_item.updated`。 。 。 .

行为我们的代码分支:

-   **坏键 :** 未知的 API 密钥返回 `errors: [{message: "API Key is Invalid"}]`,哪个 我们的客户端地图401.
-   **无密钥 :** `currentUser` 实值 `null`,列表为空和变异,但 `signIn` 失败. 我们 `listFiles` 转动 `null` 变成401.
-   **验证 :** 失败归来作为 `messages: [{field, message}]` 带有 `null` 有效载荷, 我们的客户标到400. `messages` 实值 `null` 成功;我们 `getFolderByPath` 治疗 任何非虚值为失败.
-   **签名 :** 错误的电子邮件或密码返回 `user: null`,我们的客户端地图 `INVALID_SIGN_IN_CREDENTIALS`。一个存档的用户标志 `active: false`,哪个地图 `USER_ARCHIVED`。 。 。 .
-   **谁看到什么:** 患者键只看到自己的用户、护理团队、自己的文件以及 任何与它分享的东西。 组织的关键看到了一切.

### 网络呼号

保健活动作为 `{resource_id, resource_id_type, event_type, changed_fields?}`。 。 。 . `resource_id` 作为字符串发送,因为我们的 DTO 验证 `@IsString()`。每项请求 携带 `x-forwarded-for: <ip>`,而那个信头是 我们的接收器的唯一检查 `HEALTHIE_WEBHOOK_IP_ADDRESS`没有签名.

| 活动 | 接收人(`--webhook-base-url` +路径) | 发件人 |
| --- | --- | --- |
| `patient.created`, (中文(简体) ), `patient.updated` | `/users/webhook/status` | `updateUser`, (中文(简体) ), `updateClient`, (中文(简体) ), `POST /__admin/users`,存档和无存档 |
| `requested_form_completion.created`, (中文(简体) ), `form_answer_group.created` | `/forms/webhooks/status` | `POST /__admin/requested-forms`, (中文(简体) ), `POST /__admin/form-answer-groups` |
| `billing_item.updated` | (默认无;添加一个为 `PUT /__admin/webhook-endpoints`(中文(简体) ) | `updateBillingItem` |

`POST /__admin/events {event_type, resource_id, resource_id_type}` 发出任何事件。 交货 然后在5秒、5分、30分和2分之后再审。 标准管理员路线 还适用: `GET /__admin/webhooks`, (中文(简体) ), `…/events`, (中文(简体) ), `…/:id/replay` 财务报告和审定财务报表 `…/flush`。 。 。 .

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

| 路线 | 效果 |
| --- | --- |
| `GET /__admin/users`, (中文(简体) ), `POST /__admin/users` | 列表用户(从未密码). 从 `{email, password, first_name?, last_name?, role?: patient | provider, active?, dietitian_id?, …}` 回来 `{user, api_key}`。 。 。 . |
| `POST /__admin/users/:id/archive` | `/unarchive` | 设定 `active` (存档用户与 `active: false`) (中文(简体) ). |
| `POST /__admin/users/:id/api-keys` | 为用户发行另一个 API 密钥 . |
| `POST /__admin/offerings` | `{name, price?, billing_frequency?, visibility_status?}`。 。 。 . |
| `POST /__admin/billing-items` | `{sender_id, offering_id?, amount_paid?, state?, is_recurring?, next_payment_date?}`。 。 。 . |
| `POST /__admin/form-answer-groups` | `{user_id, custom_module_form_id?, filler_id?, answers?: {<label or module id>: answer}}` (内容为webhook表格). |
| `POST /__admin/requested-forms` | `{recipient_id, sender_id?, custom_module_form_id?}` (内容为webhook表格). |
| `POST /__admin/events` | 放弃任何健康活动. |
| `GET /__admin/documents` | 命名空间的文档元数据 . |
| `GET` | `PUT /__admin/settings` | `{orgApiKeys?, namespace?: string | null, expiringUrlSeconds?}`。 。 。 . |

种子数据`SEED`),在重置时重制:

-   `100001`: 组织管理员,与每个组织挂钩 `orgApiKeys` 条目(默认) `gh_sbox_org_api_key`) (中文(简体) ).
-   `100002`(原始内容存档于2018-03-26). : Datitian Dana Rivera, MD.
-   `100003`: 演示病人 `patient@healthie.mock` 编号 : `Password123!`。 。 。 .
-   提供 `200001` 和 `200002` (加上,隐去也.
-   申请表 `300001`。 。 。 .

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`:

-   `invalid_api_key`
-   `graphql_500`: 包含 `500`为了我们的500个分支.
-   `validation_messages`
-   `current_user_null`
-   `expired_urls`
-   `http_500`
-   `rate_limited` (429个)
-   `server_error`
-   `webhook_duplicate`, (中文(简体) ), `webhook_reorder`, (中文(简体) ), `webhook_drop`

### 命名空间

选择三种命名空间:

-   页:1 `x-mockingbird-namespace` 页眉;
-   (单位:千美元) `/__admin/ns/<name>/graphql` 前缀在 `HEALTHIE_API_URL` (文件 URL 保留前缀);
-   按 API 键,使用 `PUT /__admin/credentials {"credentials": {"<key>": "<namespace>"}}`。 。 。 .

`signIn` 发送没有密钥, 所以并行的套件, 在需要时签名头或路径前缀 .

### 客户

健康没有正式的节点SDK. 我们的后端通过它说话 `graphql-request` 7.2.0 联合国 页:1 `awesome-graphql-client` 0.14.1(多个部分) `Upload` 页:1 这个 接受测试将模拟器通过这些精确的版本,被固定为devdependents 后端的文档逐字复制( q)`test/consumer.ts`) (中文(简体) ). 一个单独的 SDK 滴入测试 重复他们.

### 为什么 `graphql` 是一个运行时间依赖

我们消费者的文件需要真正的GraphQL语义: 验证一个计划, 每个选择的分辨率,别名(两个) `updateBillingItem`s 在一个文件中, `__typename`, (中文(简体) ), 和多变的强迫。 包括投放未申报变量的图ql-js,其中之一 我们的文件在不知不觉中依赖.

一个手卷式的解析器会从这些规则中漂移出来,而这正是平等必须达到的目的 保护. `graphql` 是一个公开的,无依赖的 npm 软件包, 绑在版本我们的 后端使用,所以它是正常的 `dependency` 而不是被捆绑.

### 在我们的消费者中发现的差别(模仿者跟随销售商,测试结果为他们定下钉子)

-   `createLocation` 发送 `city: line2` 永远不要宣布 `$line2`因此,健康储存 第二地址线作为城市.
-   `updateCheckoutPatientById` 发送一个 `timezone` 变量,文档从未声明, 所以健康忽略了这一点.
-   `FormsService.formRequestStatus` 读取 `recipient.id`,其查询从不选择。 这个 因此它删除的缓存密钥是 `…:undefined`。 。 。 .
-   `pauseBillingItem` 类型 `isPaused` 作为弦. 一个字符串发送到 `$is_paused: Boolean` 会被GraphQL可变强制拒绝. 该方法今天没有呼叫者.

### 故意不模拟

-   我们的消费者不再用预约 提供商 计量标准, 目标 图表 聊天 网络游戏管理 花脸卡突变, `createClient`编号 :`signUp`, (中文(简体) ), `userGroup`, (中文(简体) ), `offeringCoupons`, (中文(简体) ), `createApiKey`, (中文(简体) ), `updateFolder`编号 :`deleteFolder`, (中文(简体) ), `updateDocument`。查询一个失败 GraphQL 验证,就像一个打字机那样.
-   健康网的签名(`Content-Digest` 编号 : `Signature`) (中文(简体) ). 我们的接收器只验证 源IP,所以交付没有签名.
-   真实的页形光标 : `should_paginate` 10页 `offset`。模糊的关键字搜索是 在电子邮件和姓名上进行大小写不敏感子字符串匹配.
-   上载流量 苹果健康与Google适切链接:永远 `null`。 。 。 .
-   真实兽类的活数据. 种子数据是合成的; 通过管理员添加用户和记录 路线.

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `HealthieAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `userForKey(key)`, (中文(简体) ), `emit(event)`, (中文(简体) ), `fileUrl(origin, fileId)`, (中文(简体) ), `state`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `publicNamespace`, (中文(简体) ), `settings`, (中文(简体) ), `onEvent`。 。 。 . |
| `createRuntime` | 函数 | 全面服务合同的仿真器(健康、管理、命名空间、证书、预设、网络呼号)。 选项 : `settings`, (中文(简体) ), `webhooks: {baseUrl, ip?, retryDelaysMs?, fetch?}`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`。 。 。 . |
| `HEALTHIE_PRESETS` | 对象 | 每个命名的断层预设. |
| `HEALTHIE_EVENT_ROUTES` | 对象 | 接收路径 – 事件类型 . |
| `healthieEndpoints` | 函数 | 后端基址和源 IP 的 Webhook 端点 . |
| `DEFAULT_WEBHOOK_IP` | 字符串 | `18.206.70.225`默认值 `x-forwarded-for`。 。 。 . |
| `HEALTHIE_NAMESPACE` | 字符串 | 服务名称, `"healthie"`。 。 。 . |
| `INVALID_API_KEY` | 字符串 | `"API Key is Invalid"`。 。 。 . |
| `HEALTHIE_SDL`, (中文(简体) ), `healthieSchema` | 数值 | GraphQL 子集( SDL 和已建) `GraphQLSchema`) (中文(简体) ). |
| `Upload` | 类 | 文件绑入 `Upload` 变量由多段运算. |
| `apiKeyOf` | 函数 | API 密钥 a `Authorization` 头带( 如何将证书映射到命名空间) . |
| `healthieTimestamp` | 函数 | 卫生 `YYYY-MM-DD HH:MM:SS +0000` 时间戳格式. |
| `parseShareUsers` | 函数 | `"user-1,user-2"` → `["1", "2"]`。 。 。 . |
| `SEED`, (中文(简体) ), `DEFAULT_SETTINGS` | 对象 | 种子代号与证书; 默认设置. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | HTTP合同及其操作代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标; 第8816口. |

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

## 常见问题

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

Healthie GraphQL API \(Legacy surface\) 的状态仿真器: 签名 In, 用户, 当前用户, 更新 User/ updateClient\( 包括多部分的avatar\), 地址, 文件和文件夹, 服务下载, 格式答案, 提供, 计费项目, IP- allowl

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

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

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

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

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

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

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

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

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

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

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

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

