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

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

版本：3\.11\.0
npm 元数据更新时间：2026-11-11T02:15:00.197Z
中文译文更新时间：2026-11-11T04:54:08.306Z
软件包许可：MIT

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

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

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

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

## 中文简介

全写实验室订购API的模拟者:每个练习者OAuth,诊所,会话补助金,有结果的仅转发实验室订单,实验室订购事件,过期结果PDF,和全写-签名网络呼号.

## 安装

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

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

## README

# @crvouga/mockingbird-service-全写

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

国家模拟器 **正式标注** 测试套房的实验室订购API:每名练习生 OAuth (同意重新定向, `authorization_code` 旋转 `refresh_token` 赠款、撤销、 诊所、可嵌入式会诊补助金、附有检测结果的实验室订单、实验室订单事件,到期 结果PDF,以及 `Fullscript-Signature` 面对挑战,我们接收者 执行。 实验室命令只能通过 完全的全写状态前进 当测试表明 所以说.

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/fullscript/SUPPORT.md)
-   合同`openapi.yaml`) 由EMR消费者亲笔撰写 (单位:千美元)`fullscript-api-client.ts`, (中文(简体) ), `fullscript-event-model.ts`, (中文(简体) ), `fullscript-webhook-signature.ts`, (中文(简体) ), `routers/v1/fullscript/webhook-controller.ts`, (中文(简体) ), `fullscript-result-storage.ts`) (中文(简体) ).

## 安装

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

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

## 使用量

与 `FEATURE_FULLSCRIPT_LABS_ENABLED=true`点 `FULLSCRIPT_API_URL` 在模拟者那里 `FULLSCRIPT_OAUTH_AUTHORIZE_URL` 联合国 `/oauth/authorize`; 设置 `FULLSCRIPT_WEBHOOK_SECRET` 财务报告和审定财务报表 `FULLSCRIPT_WEBHOOK_CHALLENGE_KEY` 并传递与 `--webhook-secret` 编号 : `--webhook-challenge`。EMR将这些 URL 验证为 **网页** 而下载结果仅为 PDF 从允许的列表主机覆盖 https (默认情况下) `fullscript.com`, (中文(简体) ), `fullscript.io` 财务报告和审定财务报表 `FULLSCRIPT_API_URL`模拟器所在的宿主,所以在模拟器前用 TLS 或 设定 `--results-base-url`。 。 。 .

```bash
npx mockingbird-fullscript serve --port 8819 \
  --webhook-url http://127.0.0.1:4000/v1/fullscript/webhooks \
  --webhook-secret "$FULLSCRIPT_WEBHOOK_SECRET" --webhook-challenge "$FULLSCRIPT_WEBHOOK_CHALLENGE_KEY"
```

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

// Test setup: the emulator, a lab order moved to results, and the code an OAuth redirect delivers.
const server = await createServer({
  webhooks: { url: "http://127.0.0.1:4000/v1/fullscript/webhooks", secret: "whsec", challenge: "chal" },
})
const admin = (path: string, body: unknown) =>
  fetch(`${server.url}/__admin${path}`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body),
  })
const order = (await (await admin("/lab-orders", { patientId: "fs_pat_1", treatmentPlanId: "tp_1" })).json()) as { id: string }
await admin(`/lab-orders/${order.id}/transition`, { to: "purchased" }) // order.placed + lab_order.updated
await admin(`/lab-orders/${order.id}/transition`, { to: "results_ready" }) // results + PDF URLs
const { code } = (await (await admin("/oauth/codes", { clientId: "emr-client" })).json()) as { code: string }

// Application code: FULLSCRIPT_API_URL is server.url. Exchange the code, then read the order.
const apiUrl = server.url
const token = await fetch(`${apiUrl}/api/oauth/token`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    grant_type: "authorization_code",
    client_id: "emr-client",
    client_secret: "emr-secret",
    code,
  }),
})
const { oauth } = (await token.json()) as { oauth: { access_token: string } }
const read = await fetch(`${apiUrl}/api/clinic/labs/orders/${order.id}`, {
  headers: { authorization: `Bearer ${oauth.access_token}` },
})
const { order: labOrder } = (await read.json()) as { order: { state: string } }
// labOrder.state is "results_ready"; labOrder.results[].pdf_url are served by the emulator.
await server.close()
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `GET /oauth/authorize` | 自动同意为 `practitioner_id` (默认) `prac_mock_1`)并重定向到 `redirect_uri?code=…&state=…`。 。 。 . |
| `POST /api/oauth/token` | 贾森 `{grant_type, client_id, client_secret, code | refresh_token, redirect_uri}` → `{oauth: {access_token, token_type: "Bearer", expires_in: 7200, refresh_token, scope, created_at, resource_owner: {id, type, clinic_id}}}`。代码是单用,10分钟后到期,必须匹配重定向的 URI;刷新符号旋转(一个用完的符号是 `invalid_grant`。错误: 400 `{error: "invalid_grant" | "invalid_request"}`, 401 (中文(简体) ) `invalid_client`。 。 。 . |
| `POST /api/oauth/revoke` | `{client_id, client_secret, token}` - 200个 `{}`; 符号停止工作. |
| `GET /api/clinic` | `{clinic: {id, name}}` 给信物的从业者. |
| `POST /api/clinic/embeddable/session_grants` | 201 (韩语) `{secret_token, expires_at}`。 。 。 . |
| `GET /api/clinic/labs/orders` | `?patient_id=&page[number]=&page[size]=` → `{orders: [{id, state, treatment_plan_id, …}], meta: {current_page, next_page, …}}`。 。 。 . |
| `GET /api/clinic/labs/orders/{id}` | `{order: {…, collection_method, tests, results: [{id, name, state, pdf_url}], latest_aggregated_result: {id, artifact_id, pdf_url, status}}}`。 。 。 . |
| `GET /api/events/lab_orders` | `?order_by=DESC|ASC&page[number]=&page[size]=` - 诊所的 `lab_order.updated` 事件. |
| `GET /api/events/{id}` | `{event: {id, type, clinic_id, created_at, data}}`。 。 。 . |
| `GET /results/{artifact}?expires&signature` | 结果 PDF(`application/pdf`,一个真实的一页PDF),直到URL到期(15分钟),然后403. |

API 错误是 `{errors: [{code, message}]}` (401美元) `unauthorized` 编号 : `invalid_token` 编号 : `token_expired`页:1 `not_found`));我们的客户阅读了代码.

**国家** (向前只允许跳出): `not_purchased` → `purchased` → `schedule_appointment` → `upcoming_appointment` → `processing` → `partial_results` (第一届) 试验结果) `results_ready` (每项结果+一项综合结果) + `interpretation_shared` → `results_amended` (一出新的综合文物).

### 网络呼号

每个动作都发出 `lab_order.updated` (单位:千美元)`data.lab_order: {id, state, treatment_plan_id, patient_id}`)),以及离开 `not_purchased` 还发出 `order.placed` (单位:千美元)`data: {id, treatment_plan_ids, patient_id, line_items: [{type: "labs"}]}`) (中文(简体) ). 交付员额 `{event_payload: {event}}` 与 `Fullscript-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>." + body)>` (墙上小时) `t`) (中文(简体) ). 带有挑战键,只有在 接收回复 `{challenge: <key>}` (否则记录为502并重审). `POST /__admin/webhooks/verify` 发送全字标的空机名 每个终点是否都与挑战相呼应. `GET /__admin/webhooks`, (中文(简体) ), `…/events`, (中文(简体) ), `…/replay`, (中文(简体) ), `…/flush` 和往常一样.

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

| 路线 | 效果 |
| --- | --- |
| `POST /__admin/lab-orders` | `{patientId, id?, clinicId?, treatmentPlanId?, name?, collectionMethod?, tests?: [names]}` − a 个 `not_purchased` 秩序。 秩序. |
| `POST /__admin/lab-orders/:id/transition` | `{to: <state>}`;后或同态为409. |
| `GET /__admin/lab-orders`, (中文(简体) ), `GET /__admin/events` | 名字空间的命令与事件. |
| `POST /__admin/oauth/codes` | `{practitionerId?, clientId?, redirectUri?}` → `{code}` 没有浏览器重定向. |
| `POST /__admin/practitioners` | `{id, clinicId, type?, clinicName?}`。 。 。 . |
| `POST /__admin/webhooks/verify` | 注册电话(见Webhooks). |
| `GET/PUT /__admin/settings` | `{clients?, accessTokenTtlSeconds?, codeTtlSeconds?, pdfUrlTtlSeconds?, resultsBaseUrl?}`。 。 。 . |

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`: `token_expired`, (中文(简体) ), `invalid_grant`, (中文(简体) ), `rate_limited`, (中文(简体) ), `server_error`, (中文(简体) ), `events_schema_drift`, (中文(简体) ), `pdf_not_pdf`, (中文(简体) ), `pdf_redirect`, (中文(简体) ), `pdf_expired`, (中文(简体) ), `connection_drop`, (中文(简体) ), `slow`, (中文(简体) ), `webhook_duplicate`, (中文(简体) ), `webhook_reorder`, (中文(简体) ), `webhook_drop`。 。 。 .

### 命名空间

A 类 `/__admin/ns/<name>/` 打开后缀 `FULLSCRIPT_API_URL` (我们的客户解决相对 `api/…` 路径,所以 前缀存活下来,PDF URL保存它), `x-mockingbird-namespace`,或 OAuth 客户端为 API 调用 (`PUT /__admin/credentials {"credentials": {"<FULLSCRIPT_CLIENT_ID>": "<ns>"}}`· ; 代币背负着被发行给的客户. 托肯请求只包含客户端 身体,所以他们需要前缀或头.

### 故意不模拟

-   分类、治疗计划、病人、药房订单和每个非实验室终点 嵌入式部件本身(会议赠款是不透明的符号).
-   实验室结果值(仅限PDF),请购和预约.
-   真实同意屏幕 : `/oauth/authorize` 立即批准 立即批准.

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `FullscriptAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `issueCode(practitionerId, clientId, redirectUri)`, (中文(简体) ), `createOrder(input)`, (中文(简体) ), `transition(orderId, state)`, (中文(简体) ), `seedOrder(seed)`, (中文(简体) ), `labOrders()`, (中文(简体) ), `eventsList()`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `publicNamespace`, (中文(简体) ), `settings`, (中文(简体) ), `orders`, (中文(简体) ), `onEvent`。 。 。 . |
| `createRuntime` | 函数 | 全面服务合同的仿真器(健康、管理、命名空间、证书、预设、网络呼号)。 选项 : `webhooks: {url, secret, challenge?, retryDelaysMs?, fetch?}`, (中文(简体) ), `settings`, (中文(简体) ), `orders`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`, (中文(简体) ), `sqlite`。 。 。 . |
| `FULLSCRIPT_PRESETS` | 对象 | 每个命名的断层预设. |
| `FULLSCRIPT_NAMESPACE` | 字符串 | 服务名称, `"fullscript"`。 。 。 . |
| `SIGNATURE_HEADER` | 字符串 | `Fullscript-Signature`。 。 。 . |
| `LAB_ORDER_STATES`, (中文(简体) ), `isLabOrderState` | 数值 | 远出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出. |
| `DEFAULT_CLINIC`, (中文(简体) ), `DEFAULT_PRACTITIONER` | 对象 | 种子诊所和医生. |
| `RESULT_PDF` | 字节 | PDF 每个结果 URL 服务. |
| `issueAccessToken` | 函数 | 薄荷(用于测试和对等)自我验证访问符. |
| `tokenCredential` | 函数 | OAuth 客户端被发给了无记名符号(如何将证书映射到命名空间). |
| `envelope`, (中文(简体) ), `publicEvent` | 函数 | 事件"网钩"身体和API形状. |
| `apiErrors`, (中文(简体) ), `oauthError` | 函数 | Build Fullscript的API和OAuth错误响应. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | OpenAPI合同及其操作代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标(`--webhook-url`, (中文(简体) ), `--webhook-secret`, (中文(简体) ), `--webhook-challenge`, (中文(简体) ), `--client`, (中文(简体) ), `--results-base-url`; 港号8819. |

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

## 常见问题

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

全写实验室订购API的模拟者:每个练习者OAuth,诊所,会话补助金,有结果的仅转发实验室订单,实验室订购事件,过期结果PDF,和全写-签名网络呼号\.

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

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

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

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

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

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

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

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

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

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

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

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

