@jigubao/cli
v1.0.1
Published
CLI for real-time-fund
Maintainers
Readme
基估宝命令行工具 (@jigubao/cli)
@jigubao/cli 是基估宝(real-time-fund)项目的官方终端命令行客户端。它基于 Node.js 编写,专为开发者和终端极客设计,提供快速便捷的基金数据查询和云端数据同步管理,并且支持完美的 JSON 输出以方便自动化脚本调用。
📖 目录
✨ 核心特性
- 无密码邮箱验证码 (Email OTP) 登录:借助 Supabase Auth 服务,直接使用个人邮箱获取 6 位数验证码,无需设置/输入密码即可完成安全登录。
- 安全退出登录 (
logout):清除本地存储的用户 Session 信息,同时向 Supabase 发送登出请求使云端会话失效。 - 登录状态查询 (
status):快速校验本地会话的有效性,并输出当前登录的账户邮箱及 UUID。 - 基金模糊搜索 (
search <keyword>):支持基金名称或 6 位基金代码的高效模糊搜索。 - 实时估值与涨跌幅查询 (
price <code>):快速获取指定基金的最新估值、日涨跌幅和估值更新时间。 - 云端资产同步列表查询 (
portfolio list):查看在基估宝网页端/移动端同步并保存在云端的自选基金、持仓份额及交易详情。 - 完美的 JSON 输出支持 (
--json):除交互式的login和logout外,所有查询命令均原生支持--json参数,将结果以标准 JSON 格式输出,方便进行脚本解析与二次自动化开发。
🚀 快速开始
1. 安装与依赖准备
进入 cli 目录,安装运行所需的依赖包:
cd cli
npm install2. 运行方式
方式 A:本地直接运行
在 cli 目录中,可以使用 node 命令直接运行:
node bin/jgb.js <command> [options]或者使用 npm run start(或 npm start)以传递参数的方式启动:
npm run start -- <command> [options]
# 或者
npm start -- <command> [options]方式 B:全局链接/安装 (推荐)
如果希望在系统的任何位置都能直接使用 jgb 命令,可以使用 npm link 进行全局链接:
npm link链接成功后,即可在系统的任意终端中直接使用 jgb:
jgb <command> [options]⚙️ 配置与环境变量
用户会话保存位置
本工具会自动管理登录会话,登录后的 accessToken 和 refreshToken 会自动存储在用户家目录下的配置文件中:
- 路径:
~/.jgb-cli/config.json - 该文件会在首次运行
jgb login并成功登录后自动创建。
环境变量配置
为了能够正常连接云端 Supabase 数据库,CLI 需要读取 Supabase 配置。它支持两种方式自动加载环境变量:
- 读取
cli/目录下的.env文件。 - 读取项目根目录下的
.env.local文件。
你可以复制根目录下的 env.example 模板并填充对应值:
SUPABASE_URL=你的Supabase项目地址
SUPABASE_ANON_KEY=你的Supabase匿名Key
# 或者 Next.js 兼容格式
NEXT_PUBLIC_SUPABASE_URL=你的Supabase项目地址
NEXT_PUBLIC_SUPABASE_ANON_KEY=你的Supabase匿名Key🔧 命令详解
1. 登录账户 (login)
启动无密码邮箱验证码 (Email OTP) 登录流程。
jgb login注:login 属于强交互式命令,不支持 --json 参数。
2. 退出登录 (logout)
清除本地 Session 会话,并向 Supabase 发起登出使该 Session 彻底失效。
jgb logout注:logout 属于操作类命令,不支持 --json 参数。
3. 状态查询 (status)
查询当前登录的账户状态。
jgb status [--json]JSON 输出示例:
{
"email": "[email protected]",
"id": "12345678-abcd-1234-abcd-123456789abc"
}4. 基金模糊搜索 (search)
根据关键字(基金名称或代码)搜索基金。
jgb search <keyword> [--json]JSON 输出示例:
[
{
"CODE": "161725",
"NAME": "招商中证白酒指数(LOF)A",
"CATEGORY": 700,
"FundBaseInfo": {
"FTYPE": "混合型-偏股"
}
}
]5. 实时估值查询 (price)
查询指定 6 位基金代码的实时估值(净值估算)、估算涨跌幅及时间。
jgb price <code> [--json]JSON 输出示例:
{
"fundcode": "161725",
"name": "招商中证白酒指数(LOF)A",
"jzrq": "2026-06-05",
"dwjz": "1.2192",
"gsz": "1.2345",
"gszzl": "1.25",
"gztime": "2026-06-07 15:00"
}6. 云端资产查询 (portfolio)
查询当前登录用户在云端同步的自选基金和持仓列表。
jgb portfolio list [--json]JSON 输出示例:
{
"localFunds": [
"161725",
"000001"
],
"holdings": {
"161725": {
"share": 5000.00,
"cost": 1.21
},
"000001": {
"share": 0,
"cost": 0
}
},
"transactions": {
"161725": []
}
}7. 全局选项 (Global Options)
--json:以标准 JSON 格式输出结果,避免人机交互提示,适用于自动化脚本.-h, --help:显示帮助信息。-v, --version:显示当前 CLI 版本号。
🏗️ 代码架构与模块图解
1. 代码目录结构
在 cli/ 下,核心源码结构清晰:
- bin/jgb.js — 命令行工具的可执行入口文件,配置了
#!/usr/bin/env node。 - src/index.js — 命令行逻辑核心,定义了所有子指令(
login,status,search,price,portfolio)及全局配置参数(如--json)。 - src/auth.js — 封装用户认证模块,负责与 Supabase 进行邮箱 OTP 交互登录、读取并校验 session 状态。
- src/api.js — 第三方接口抓取服务,获取实时基金列表搜索和估值情况。
- src/portfolio.js — 云端数据同步服务,连接 Supabase 获取用户同步配置(持仓和自选列表)。
- src/config.js — 本地存储管理,将会话状态写入本地家目录
~/.jgb-cli/config.json下。 - src/supabase.js — 环境变量加载与 Supabase 客户端初始化。
- src/utils.js — 命令行通用输出处理器与异常捕获。
2. 模块调用图
@jigubao/cli 各模块间的调用与依赖关系如下:
graph TD
bin[bin/jgb.js Entry] --> index[src/index.js App Controller]
index --> cac[cac CLI Parser]
index --> auth[src/auth.js Auth Manager]
index --> api[src/api.js Financial Fetcher]
index --> portfolio[src/portfolio.js Portfolio Sync]
auth --> config[src/config.js Config Loader]
auth --> sb[src/supabase.js Supabase SDK]
portfolio --> config
portfolio --> sb
config --> jsonFile[~/.jgb-cli/config.json]
sb --> envFiles[.env / .env.local]
api --> webAPIs[东财/天天基金 HTTP 接口]
portfolio --> db[(Supabase 云端配置表)]💡 核心工作原理
1. 绕过浏览器端 CORS 限制
- 网页端方案:基估宝网页端受制于浏览器的同源策略(CORS),必须通过
<script>标签动态注入、利用 JSONP 的形式来绕过东财或天天基金的接口限制。 - CLI 方案:
@jigubao/cli运行在 Node.js 环境下,不存在浏览器的 CORS 安全模型。因此,src/api.js 使用原生fetch直接发出 HTTP 报文请求。获取到原始 JSONP 形式的 JavaScript 字符串后,再通过简单的字符串截取与正则替换,将其还原为标准 JSON 格式,最后通过JSON.parse进行解析。
2. Supabase 邮箱 OTP 登录与 RLS 会话验证
- 登录流程:
sequenceDiagram
actor User as 用户 (Terminal)
participant CLI as @jigubao/cli (src/auth.js)
participant Config as config.json
participant SB as Supabase Auth
User->>CLI: jgb login
CLI->>User: 提示输入邮箱
User->>CLI: [email protected]
CLI->>SB: signInWithOtp(email)
SB-->>User: 发送6位OTP验证码到邮箱
CLI->>User: 提示输入验证码
User->>CLI: 123456
CLI->>SB: verifyOtp(email, token)
SB-->>CLI: 返回 Session (AccessToken + RefreshToken)
CLI->>Config: 写入 ~/.jgb-cli/config.json
CLI->>User: 提示登录成功- 云端查询与 RLS 鉴权:
Supabase 数据库的
user_configs表启用了行级安全(Row Level Security, RLS)。用户查询云端资产列表时的流程如下:
sequenceDiagram
actor User as 用户 (Terminal)
participant CLI as @jigubao/cli (src/portfolio.js)
participant Config as config.json
participant SB as Supabase Client
participant DB as user_configs Table
User->>CLI: jgb portfolio list
CLI->>Config: 读取本地 AccessToken
CLI->>SB: setSession(AccessToken)
CLI->>SB: select('data').eq('user_id', user.id)
SB->>DB: 触发 RLS 校验 (Row Level Security)
DB-->>CLI: 返回持仓及自选数据
CLI->>User: 解析并展示持仓列表 / JSON 输出- 安全退出登录流程:
退出登录时,除了清空本地的
config.json配置文件外,还会尝试调用 Supabase 的signOut()使服务器端的会话失效:
sequenceDiagram
actor User as 用户 (Terminal)
participant CLI as @jigubao/cli (src/auth.js)
participant Config as config.json
participant SB as Supabase Auth
User->>CLI: jgb logout
CLI->>Config: 读取本地 AccessToken/RefreshToken
Note over CLI, SB: 恢复会话并向 Supabase 发送登出请求
CLI->>SB: setSession() & signOut()
SB-->>CLI: 确认登出 (会话在服务器端失效)
CLI->>Config: 删除本地 ~/.jgb-cli/config.json
CLI->>User: 提示登出成功🛠️ 高级技巧与自动化脚本
通过原生支持的 --json 开关,你可以非常方便地将 @jigubao/cli 与其他 Unix/Linux 经典命令行工具整合,完成复杂工作流。
1. 使用 jq 过滤特定基金的持仓份额
假设你想知道基金代码 161725 的云端持仓份额:
jgb portfolio list --json | jq '.holdings["161725"].share'2. 利用 watch 实时监控基金估值变动
每隔 60 秒刷新一次招商中证白酒基金的估值:
watch -n 60 "jgb price 161725"或者如果你只需要涨跌幅:
watch -n 60 "jgb price 161725 --json | jq -r '.gszzl + \"%\"'"3. 编写一个自动基金净值波动通知脚本
编写简单的 Bash 脚本,当估值涨跌幅超过设定阈值时发出警告通知(例如使用 osascript 弹出 macOS 系统通知):
#!/bin/bash
FUND_CODE="161725"
THRESHOLD="1.5" # 1.5%
# 获取实时跌幅(去掉负号取绝对值)
GROWTH=$(jgb price $FUND_CODE --json | jq -r '.gszzl')
ABS_GROWTH=$(echo ${GROWTH#-} | cut -d'.' -f1) # 简易绝对值整数部分
# 比较大小(判断绝对值是否超过阈值)
if [ "$ABS_GROWTH" -ge "1" ]; then
osascript -e "display notification \"当前估值涨跌幅已达: $GROWTH%\" with title \"基金 $FUND_CODE 净值波动提醒\""
fi🧪 自动化测试 (Testing)
为了保证脚本修改的稳健性,项目集成了 Node.js 原生测试运行器 (node:test + node:assert),对 CLI 核心功能进行了高覆盖率的单元测试与集成测试。
1. 运行测试
在 cli 目录下直接执行以下命令运行所有测试用例:
npm test2. 测试套件说明
测试用例存放在 cli/tests/ 目录下,包含以下四个核心测试套件:
- config.test.js:测试本地配置的读写、保存与清理。测试中通过 Mock 覆盖
os.homedir(),使测试配置均在临时沙箱目录内进行,不影响用户的实际~/.jgb-cli/config.json文件。 - api.test.js:通过拦截并 Mock 全局
fetch函数,模拟东财模糊搜索和天天基金估值查询返回的 JSONP JavaScript 字符串,测试正则提取和过滤逻辑。 - auth.test.js:测试邮箱 OTP 登录、登出以及状态校验。该套件 Mock 了 Supabase Auth 方法,封装拦截了
@clack/prompts命令行交互式输入,并通过覆盖process.exit抛出错误以防止测试执行过程中提前退出。 - portfolio.test.js:测试从 Supabase 获取持仓和自选数据。通过链式调用存根 (Stub) 模拟了 Supabase
supabase.from().select().eq().single()的查询构造器模型。
⚠️ 常见错误与排查指南
1. 报错:Missing Supabase configuration.
[!WARNING] 排查步骤:
- CLI 未能正确找到 Supabase 环境变量。检查
cli/目录下是否包含.env,或者项目根目录下是否存在.env.local。- 确保配置了有效的
SUPABASE_URL/NEXT_PUBLIC_SUPABASE_URL以及对应 Anon Key。
2. 报错:Not logged in. 或 Session has expired
[!IMPORTANT] 排查步骤:
- 说明本地保存的 Session token 已失效或不存在。请在终端直接执行
jgb login重新进行 OTP 验证码登录。- 如多次尝试后依然失效,可执行
rm -rf ~/.jgb-cli清理本地失效的配置文件后重试。
3. Node.js 版本兼容性问题
[!CAUTION] 本工具核心网络模块采用原生
fetch接口。若本地 Node.js 版本低于20.9.0,将会抛出未定义fetch的错误。请使用node -v确保版本符合规范。推荐使用nvm对 Node.js 进行版本升级。
