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

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

版本：0\.4\.0
npm 元数据更新时间：2026-11-11T02:31:18.491Z
中文译文更新时间：2026-11-11T09:58:21.529Z
软件包许可：MIT

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

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

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

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

## 中文简介

Stateful Polar AccessLink v3 模拟器:OAuth同意和代码交换,用户注册和30天练习窗口.

## 安装

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

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

## README

# @crvouga/嘲笑鸟-服务-极地

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

WIP Polar AccessLink v3 模拟器:OAuth 2.0授权代码,用户注册和练习端点,带有30天的能见度窗口.

## 安装

`bun add @crvouga/mockingbird-service-polar`

## 使用量

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

// Test setup: a local Polar. The user is registered with the client ten days ago and has an
// exercise uploaded afterwards. Seeds, presets and the clock are the only emulator-specific lines.
const now = Date.now()
const server = await createServer({
  registrations: [
    { xUserId: 1001, memberId: "m-1", registeredAt: new Date(now - 10 * 86_400_000).toISOString() },
  ],
  exercises: [
    {
      xUserId: 1001,
      id: "2AC312F",
      upload_time: new Date(now - 86_400_000).toISOString(),
      start_time: "2026-01-30T08:00:00",
      duration: "PT2H44M",
    },
  ],
})

// Application code: the same three origins, each pointed at the emulator.
const apiOrigin = server.url
const tokenUrl = `${server.url}/v2/oauth2/token`
const authorizeUrl = `${server.url}/oauth2/authorization`

const consent = await fetch(
  `${authorizeUrl}?response_type=code&client_id=mock_client&redirect_uri=https://app.example.com/cb&state=s1&scope=accesslink.read_all`,
  { redirect: "manual" },
)
const code = new URL(consent.headers.get("location") ?? "").searchParams.get("code") ?? ""
const tokenResponse = await fetch(tokenUrl, {
  method: "POST",
  headers: {
    "content-type": "application/x-www-form-urlencoded",
    authorization: `Basic ${btoa("mock_client:mock_client_secret")}`,
  },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code,
    redirect_uri: "https://app.example.com/cb",
  }),
})
const { access_token } = (await tokenResponse.json()) as { access_token: string }
const exercises = await fetch(`${apiOrigin}/v3/exercises?samples=false&zones=false&route=false`, {
  headers: { authorization: `Bearer ${access_token}`, accept: "application/json" },
})
console.log(await exercises.json())

await server.close()
```

运行 `mockingbird-polar serve --port 12157`。消费者有三种来源设置:设置 API 来源,符号 URL(`<origin>/v2/oauth2/token`)和授权的URL(`<origin>/oauth2/authorization`)给模仿者. 一个模拟器服务于所有三个路由集,所以它们共享了源. 同意页是一个浏览器重定向,所以浏览器无法发送 `x-mockingbird-namespace`: 使用 `/__admin/ns/<name>` 前缀( e)`<origin>/__admin/ns/<name>/oauth2/authorization`为它选择一个命名空间.

## 路线和状态

默认: 客户端 `mock_client` 编号 : `mock_client_secret` (任何方向调整 URI 除非客户列表 `redirectUris`),用户 `x_user_id` 1001(未注册)和访问符 `mock_polar_token` 给那个用户. `GET /oauth2/authorization` 重定向到 `redirect_uri?code=<code>&state=<state>` 作为第一个(或 `consentUser`)用户;代码是一次性的,在模拟器时钟上10分钟良好. `POST /v2/oauth2/token` 以窗体和 Basic 客户验证并回答 `{access_token, token_type: "bearer", expires_in: 31535999, x_user_id}` (输入;无) `refresh_token`,没有 `scope`) (中文(简体) ). Tokens 永远不会过期;只有在被撤销时才会停止工作. 代码的第二次使用, 不同的客户端代码或不匹配 `redirect_uri` 为 400 `invalid_grant`;未知客户端或错误的秘密是400 `invalid_client`; 非形体, 缺失 `grant_type`,或除 `authorization_code` (包括 `refresh_token`)为400 `invalid_request`。 。 。 .

`POST /v3/users` 与 `{"member-id": "..."}` 在仿真器时钟的即时端用符的客户端登记符的用户,并用配置文件回答200个(`polar-user-id`, (中文(简体) ), `member-id`, (中文(简体) ), `registration-date`, (中文(简体) ), `first-name`(中文(简体) ). 已经注册的用户,或 `member-id` 该客户持有的另一个用户是409个。 没有尸体 `member-id` 400;非JSON体为415.

`GET /v3/exercises` 返回在注册时或注册后上传的、在模拟时钟前不超过30天(确切的30天仍在返回),最古老的上传功能的 JSON 系列; `[]` 当没有. `GET /v3/exercises/{id}` 返回一个,或404用于未知的id,另一个用户的练习,或该窗口外的一个. `samples`, (中文(简体) ), `zones` 财务报告和审定财务报表 `route` 默认为假并必须读取 `true` 或者说 `false` (以四百计),当物有所收获的时候 `samples`, (中文(简体) ), `heart_rate_zones` 或者说 `route` (来自种子, `[]` (没有) 其用户未在客户端注册的代币在两者上都可获得403. 物品总是携带 `id`, (中文(简体) ), `upload_time`, (中文(简体) ), `polar_user`, (中文(简体) ), `device`, (中文(简体) ), `sport`, (中文(简体) ), `start_time`, (中文(简体) ), `start_time_utc_offset` 财务报告和审定财务报表 `duration`; 省略的种子 `device`, (中文(简体) ), `device_id`, (中文(简体) ), `sport`, (中文(简体) ), `detailed_sport_info`, (中文(简体) ), `start_time_utc_offset`, (中文(简体) ), `duration`, (中文(简体) ), `calories`, (中文(简体) ), `distance`, (中文(简体) ), `heart_rate` 或者说 `has_route` 获得合成默认值(一个极地范特克V,运行30分钟).

每个API路由都以401来回答一个缺失,未知或被撤销的代币.

## 测试控制

通过选项进行种子( E)`clients`, (中文(简体) ), `users`, (中文(简体) ), `registrations`, (中文(简体) ), `exercises`, (中文(简体) ), `tokens`, (中文(简体) ), `codes`, (中文(简体) ), `settings`)或下面的管理员路线;所有状态显示 `GET /__admin/state`. 管理路线(可与管理前缀相对):

-   `GET|PUT /__admin/settings`数字 : `{consent: "approve" | "deny" | "error", consentUser: <x_user_id> | null}`。 。 。 . `deny` 重定向为 `error=access_denied`, (中文(简体) ), `error` 与 `error=server_error`,两者携带 `state`。 。 。 .
-   `POST /__admin/users` `{xUserId, firstName?, lastName?, birthdate?, gender?, weight?, height?}`。 。 。 .
-   `POST /__admin/registrations` `{xUserId, memberId, registeredAt, clientId?}` (ISO 8601) (英语).
-   `POST /__admin/exercises` `{xUserId, id, upload_time, start_time, ...fields}`种子在注册前上传了1个种子,超过30天就会被排除在外.
-   `POST /__admin/tokens/revoke` `{token}`:从那时起,这个符号回答401.
-   钟( C)`POST /__admin/clock`)移动30天窗口和代码寿命.

预设`POST /__admin/faults {"preset": ..., "count": n}`: `unauthorized` (401个), `rate_limited` (429处) `RateLimit-Usage`, (中文(简体) ), `RateLimit-Limit`, (中文(简体) ), `RateLimit-Reset`,没有 `Retry-After`, (中文(简体) ), `rate_limited_retry_after` (同样的加法) `Retry-After: 5`, (中文(简体) ), `server_error` (500个)和 `connection_drop`普通断层加任何其他状态、标题或间隔。 标题命名空间( E)`x-mockingbird-namespace`, (中文(简体) ), `/__admin/ns/<name>` 路径和无记名绘图`PUT /__admin/credentials`隔离用户、注册、练习和标志。 日记记录元数据,不是机构. 没有网友.

## 甲骨文和测试

来源于 [AccessLink 引用](https://www.polar.com/accesslink-api/) 以及消费者的电线形状(问题546). **没有使用现场证明;这里没有任何证据可以核实.** 以下为最佳猜测,而非甲骨文验证: `invalid_request` 错误 `grant_type=refresh_token`; 403用于未注册用户的练习电话; 200和 `[]` 用于未练习的注册用户; 404 用于未知练习 id; API 错误机构的 JSON 形状(`{"error": {"timestamp", "status", "errorType", "message"}}`; 基于方向调整 `invalid_scope`, (中文(简体) ), `unsupported_response_type` 财务报告和审定财务报表 `server_error` 同意页; 十分钟代码寿命; 省略 `redirect_uri` 在接受的符号终点 `RateLimit-*` 429个预设值(记录的默认限额为每15分钟500个,每24小时5000个,已用尽)和否 `Retry-After` 默认值429(`rate_limited_retry_after` 是变体). 成功的对策永远没有 `RateLimit-*` 头.

`bun test` 运行接受测试(请求的每一个编号行为,通过 `test/consumer.ts`),全操作自平(同意页为浏览器重定向并被从随机行走中排除)和分差检测. `bun run parity` 需求 `POLAR_ACCESS_TOKEN` ,并进行只读操作列表信封检查而不打印数据.

## 故意不模拟

被贬值的交易API(创建交易,承诺),日常活动,连续心率,心电荷载,睡眠,夜充,SleepWise和Elixir数据,FIT/TCX/GPX下载,webhooks,用户删除和v4动态API. 并且: 真正的登录或同意 UI(同意页从 `consent` 设定、极地流动账户和设备、费率限额核算( `RateLimit-*` 标题只出现在强迫的429s上 `training_load`, (中文(简体) ), `fat_percentage`\- 样式可选练习场(必要时种子;经过),和标志过期(`expires_in` 是一个常数).

## API 密码

根运行时间导出 : `PolarAPI`, (中文(简体) ), `POLAR_NAMESPACE`, (中文(简体) ), `POLAR_SCOPE`, (中文(简体) ), `EXPIRES_IN`, (中文(简体) ), `EXERCISE_WINDOW_MS`, (中文(简体) ), `CODE_TTL_MS`, (中文(简体) ), `DEFAULT_SETTINGS`, (中文(简体) ), `createRuntime`, (中文(简体) ), `POLAR_PRESETS`, (中文(简体) ), `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds`。类型 : `PolarAPIOptions`, (中文(简体) ), `Client`, (中文(简体) ), `User`, (中文(简体) ), `RegistrationSeed`, (中文(简体) ), `Registration`, (中文(简体) ), `TokenGrant`, (中文(简体) ), `OAuthCode`, (中文(简体) ), `ExerciseSeed`, (中文(简体) ), `ExerciseRow`, (中文(简体) ), `ConsentMode`, (中文(简体) ), `Settings`, (中文(简体) ), `PolarRuntimeOptions`, (中文(简体) ), `PolarRuntime`, (中文(简体) ), `OperationId`, (中文(简体) ), `SupportedOperationId`。 。 。 .

`/server`数字 : `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT`; 类型 `PolarServerOptions`, (中文(简体) ), `PolarServer`。 。 。 .

## 常见问题

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

Stateful Polar AccessLink v3 模拟器:OAuth同意和代码交换,用户注册和30天练习窗口\.

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

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

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

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

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

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

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

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

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

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

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

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

