@crvouga/mockingbird-service-fullscript

中文文档
3.11.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 3190

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

中文使用文档
文档目录8 节
  1. 安装
  2. 使用量
  3. 路线
  4. 网络呼号
  5. 管理员(超过标准合同)
  6. 命名空间
  7. 故意不模拟
  8. API 密码

@crvouga/mockingbird-service-全写

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

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

  • 行动范围: 支助
  • 合同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) (中文(简体) ).

安装

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。 。 。 .

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"
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_grants201 (韩语) {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.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-fullscript 共发布 42 个版本,首次发布于 2026/09/23;过去 12 个月发布了 42 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/11/11今天
3.10.92026/11/037 天前
3.10.82026/11/038 天前
3.10.72026/11/038 天前
3.10.62026/11/038 天前
3.10.52026/11/038 天前

关于 @crvouga/mockingbird-service-fullscript 的常见问题

@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 和提交记录判断。