@crvouga/mockingbird-service-polar

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

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

中文使用文档
文档目录7 节
  1. 安装
  2. 使用量
  3. 路线和状态
  4. 测试控制
  5. 甲骨文和测试
  6. 故意不模拟
  7. API 密码

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

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

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

安装

bun add @crvouga/mockingbird-service-polar

使用量

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 引用 以及消费者的电线形状(问题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 共发布 14 个版本,首次发布于 2026/10/22;过去 12 个月发布了 14 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.0latest2026/11/11今天
0.3.92026/11/038 天前
0.3.82026/11/038 天前
0.3.72026/11/038 天前
0.3.62026/11/038 天前
0.3.52026/11/038 天前

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

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