@ricequant2026/rqdata-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +231 -0
- package/LICENSE +21 -0
- package/README.md +375 -0
- package/bin/rqdata.js +41 -0
- package/package.json +49 -0
- package/scripts/npm/build-packages.js +108 -0
- package/scripts/npm/link-platform-package.js +32 -0
- package/scripts/npm/pack-all.js +31 -0
- package/scripts/npm/platforms.js +74 -0
- package/scripts/npm/publish-all.js +39 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.0] - 2026-03-27
|
|
4
|
+
|
|
5
|
+
### 首次发布
|
|
6
|
+
|
|
7
|
+
**核心特性**
|
|
8
|
+
- Go 实现的高性能 CLI 工具
|
|
9
|
+
- 支持 68 个金融数据 API 命令
|
|
10
|
+
- NDJSON/JSON/CSV 多格式输出
|
|
11
|
+
- 系统 Keyring 集成,安全存储凭证
|
|
12
|
+
- 自动 Token 管理和刷新
|
|
13
|
+
- Schema 自动生成,含中文参数描述
|
|
14
|
+
|
|
15
|
+
**数据覆盖**
|
|
16
|
+
- 指数数据(8 个命令)
|
|
17
|
+
- A股数据(23 个命令)
|
|
18
|
+
- 港股数据(8 个命令)
|
|
19
|
+
- 交易日历(5 个命令)
|
|
20
|
+
- 基金数据(9 个命令)
|
|
21
|
+
- 期货数据(8 个命令)
|
|
22
|
+
- 期权数据(7 个命令)
|
|
23
|
+
- 宏观数据(6 个命令)
|
|
24
|
+
|
|
25
|
+
**技术亮点**
|
|
26
|
+
- 单文件可执行,静态编译
|
|
27
|
+
- 跨平台支持(Linux/macOS/Windows)
|
|
28
|
+
- 类型安全的参数验证
|
|
29
|
+
- AI Agent 友好的 NDJSON 输出
|
|
30
|
+
|
|
31
|
+
**文档**
|
|
32
|
+
- 完整的快速上手指南
|
|
33
|
+
- 68 个命令的详细参考文档
|
|
34
|
+
- Go 构建指南
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
#### 核心功能
|
|
40
|
+
- ✨ 完整的 RQData HTTP API 支持
|
|
41
|
+
- 🚀 CURL 连接复用优化(QPS 提升 44.4%)
|
|
42
|
+
- ⚡ Daemon 模式支持(长连接服务)
|
|
43
|
+
- 📊 多种输出格式(NDJSON、JSON、CSV)
|
|
44
|
+
- 🔒 严格的 Schema 验证
|
|
45
|
+
- 🎯 字段过滤功能(`--fields` 参数)
|
|
46
|
+
|
|
47
|
+
#### 数据模块
|
|
48
|
+
- 📈 **Index(指数)** - 指数列表、行情、成分股、权重
|
|
49
|
+
- 📊 **Stock CN(A股)** - 行情、财务、分红、融资融券、北向资金、停牌
|
|
50
|
+
- 🇭🇰 **Stock HK(港股)** - 行情、财务、分红
|
|
51
|
+
- 📅 **Calendar(交易日历)** - 交易日列表、前后交易日查询
|
|
52
|
+
- 📉 **Macro(宏观)** - Shibor、CPI、PPI、GDP
|
|
53
|
+
|
|
54
|
+
#### 认证系统
|
|
55
|
+
- 🔑 环境变量认证(推荐)
|
|
56
|
+
- 🔐 交互式登录
|
|
57
|
+
- 💾 Token 缓存机制
|
|
58
|
+
- ⏰ 自动 Token 刷新
|
|
59
|
+
|
|
60
|
+
#### 性能优化
|
|
61
|
+
- 🔄 CURL 连接复用
|
|
62
|
+
- 🌐 TCP Keep-Alive
|
|
63
|
+
- 📡 HTTP 持久连接
|
|
64
|
+
- ⚡ Daemon 模式(批量查询性能提升 25%)
|
|
65
|
+
|
|
66
|
+
#### 测试覆盖
|
|
67
|
+
- ✅ 74 个功能测试(100% 通过率)
|
|
68
|
+
- 📊 5 个性能测试场景
|
|
69
|
+
- 🔬 三方性能对比(CLI vs Daemon vs Python)
|
|
70
|
+
- 🧪 全模块性能验证
|
|
71
|
+
|
|
72
|
+
### Performance
|
|
73
|
+
|
|
74
|
+
#### 性能基准
|
|
75
|
+
- **单次请求**: 0.140s(优化前 0.154s,提升 9.1%)
|
|
76
|
+
- **连续请求**: 0.150s/次(优化前 0.200s/次,提升 25%)
|
|
77
|
+
- **平均 QPS**: 7.22 req/s(优化前 5 req/s,提升 44.4%)
|
|
78
|
+
- **大数据吞吐**: 7,652 行/秒
|
|
79
|
+
|
|
80
|
+
#### 场景性能
|
|
81
|
+
- **1-3次查询**: CLI 直接模式最快(比 Python 快 68-78%)
|
|
82
|
+
- **3-10次查询**: CLI Daemon 模式最快(比 Python 快 60-78%)
|
|
83
|
+
- **20+次高频**: Python API 最快(比 CLI 快 12倍)
|
|
84
|
+
- **大数据量**: Python API 最快(比 CLI 快 2.5倍)
|
|
85
|
+
|
|
86
|
+
### Documentation
|
|
87
|
+
|
|
88
|
+
- 📖 完整的 README.md
|
|
89
|
+
- 📚 API 文档
|
|
90
|
+
- 🔧 开发指南
|
|
91
|
+
- 📊 性能测试报告
|
|
92
|
+
- 🤝 贡献指南
|
|
93
|
+
- 📝 更新日志
|
|
94
|
+
|
|
95
|
+
### Technical Details
|
|
96
|
+
|
|
97
|
+
#### 架构
|
|
98
|
+
- C++17 标准
|
|
99
|
+
- CMake 构建系统
|
|
100
|
+
- vcpkg 依赖管理
|
|
101
|
+
- 模块化设计
|
|
102
|
+
|
|
103
|
+
#### 依赖库
|
|
104
|
+
- libcurl - HTTP 客户端
|
|
105
|
+
- nlohmann-json - JSON 处理
|
|
106
|
+
- CLI11 - 命令行解析
|
|
107
|
+
- csv-parser - CSV 解析
|
|
108
|
+
- fmt - 格式化输出
|
|
109
|
+
|
|
110
|
+
#### 平台支持
|
|
111
|
+
- ✅ macOS (Apple Silicon & Intel)
|
|
112
|
+
- ✅ Linux (x86_64)
|
|
113
|
+
- 🚧 Windows (计划中)
|
|
114
|
+
|
|
115
|
+
### Testing
|
|
116
|
+
|
|
117
|
+
#### 功能测试
|
|
118
|
+
- Index 模块: 8/8 通过 ✅
|
|
119
|
+
- Stock CN 模块: 23/23 通过 ✅
|
|
120
|
+
- Stock HK 模块: 8/8 通过 ✅
|
|
121
|
+
- Calendar 模块: 5/5 通过 ✅
|
|
122
|
+
- Fund 模块: 9/9 通过 ✅
|
|
123
|
+
- Futures 模块: 8/8 通过 ✅
|
|
124
|
+
- Options 模块: 7/7 通过 ✅
|
|
125
|
+
- Macro 模块: 6/6 通过 ✅
|
|
126
|
+
- **总计**: 74/74 通过(100%)✅
|
|
127
|
+
|
|
128
|
+
#### 性能测试
|
|
129
|
+
- 单次请求性能测试 ✅
|
|
130
|
+
- 连续请求性能测试 ✅
|
|
131
|
+
- 大数据量性能测试 ✅
|
|
132
|
+
- 高频请求性能测试 ✅
|
|
133
|
+
- 三方对比测试 ✅
|
|
134
|
+
|
|
135
|
+
### Known Issues
|
|
136
|
+
|
|
137
|
+
- Stock HK 模块性能相对较慢(QPS 3.17)- 受 API 响应速度限制
|
|
138
|
+
- 高频场景(20+次/秒)性能不如 Python API - 受进程启动开销限制
|
|
139
|
+
|
|
140
|
+
### Recommendations
|
|
141
|
+
|
|
142
|
+
#### 使用建议
|
|
143
|
+
- **临时查询(1-3次)**: 使用 CLI 直接模式
|
|
144
|
+
- **批量脚本(3-20次)**: 使用 CLI Daemon 模式
|
|
145
|
+
- **高频查询(20+次)**: 使用 Python API
|
|
146
|
+
- **大数据量(10K+行)**: 使用 Python API
|
|
147
|
+
|
|
148
|
+
## [1.0.1] - 2026-03-10
|
|
149
|
+
|
|
150
|
+
### Fixed
|
|
151
|
+
|
|
152
|
+
#### 财务数据功能修复
|
|
153
|
+
- 🐛 **修复 `stock cn financial` 命令 HTTP 400 错误**
|
|
154
|
+
- 问题:`get_pit_financials_ex` API 要求 `fields` 必填,但 CLI 在构建请求时把 `fields` 从 payload 中剔除
|
|
155
|
+
- 修复:针对 `get_pit_financials_ex` 方法,保留 payload 中的 `fields` 参数传给 API
|
|
156
|
+
- 影响:现在可以正常获取三大表财务数据(资产负债表、利润表、现金流量表)
|
|
157
|
+
|
|
158
|
+
- 🐛 **修复 `stock cn financial-indicator` 命令 HTTP 400 错误**
|
|
159
|
+
- 问题:使用了错误的 method `get_factor`(参数格式不匹配)
|
|
160
|
+
- 修复:改用 `get_pit_financials_ex` + 衍生指标字段
|
|
161
|
+
- 影响:现在可以正常获取 ROE、毛利率、净利率等财务衍生指标
|
|
162
|
+
|
|
163
|
+
#### 认证问题修复
|
|
164
|
+
- 🐛 **修复 Token 过期导致的 HTTP 401 错误**
|
|
165
|
+
- 问题:缓存的 token 过期后,CLI 继续使用导致认证失败
|
|
166
|
+
- 解决方案:删除 `~/.rqdata/token.cache` 后,CLI 自动重新认证获取新 token
|
|
167
|
+
- 建议:如遇 401 错误,运行 `rm -f ~/.rqdata/token.cache` 清除过期缓存
|
|
168
|
+
|
|
169
|
+
### Added
|
|
170
|
+
|
|
171
|
+
#### 完整的 HALO 策略支持
|
|
172
|
+
- ✅ 现在可以用纯 CLI 完成 HALO 策略筛选
|
|
173
|
+
- ✅ 支持获取三大表财务数据
|
|
174
|
+
- ✅ 支持获取财务衍生指标(ROE、毛利率等)
|
|
175
|
+
- ✅ 支持批量查询 20 只股票的财务数据
|
|
176
|
+
|
|
177
|
+
### Documentation
|
|
178
|
+
|
|
179
|
+
- 📝 添加财务数据 API 使用说明
|
|
180
|
+
- 📝 添加衍生指标字段名参考
|
|
181
|
+
- 📝 添加 Token 过期问题排查指南
|
|
182
|
+
|
|
183
|
+
### Technical Details
|
|
184
|
+
|
|
185
|
+
#### 代码修改
|
|
186
|
+
- `src/commands/stock_cn.cpp` 第 71-84 行:修改 `execute_stock_cn_command` 函数,针对 `get_pit_financials_ex` 保留 `fields` 参数
|
|
187
|
+
- `src/commands/stock_cn.cpp` 第 426 行:`financial-indicator` 命令改用 `get_pit_financials_ex` 方法
|
|
188
|
+
|
|
189
|
+
#### 测试验证
|
|
190
|
+
- ✅ `stock cn financial` 命令测试通过
|
|
191
|
+
- ✅ `stock cn financial-indicator` 命令测试通过
|
|
192
|
+
- ✅ HALO 策略 20 只股票批量查询测试通过
|
|
193
|
+
|
|
194
|
+
### Notes
|
|
195
|
+
|
|
196
|
+
#### 衍生指标字段名
|
|
197
|
+
- 使用完整名称:`return_on_equity_weighted_average`(不是 `roe`)
|
|
198
|
+
- TTM 字段使用大写:`net_profitTTM`(不是 `net_profit_ttm`)
|
|
199
|
+
- Quarter 格式使用小写:`2024q3`(不是 `2024Q3`)
|
|
200
|
+
|
|
201
|
+
## [Unreleased]
|
|
202
|
+
|
|
203
|
+
### Planned Features
|
|
204
|
+
|
|
205
|
+
- 🚧 Windows 平台支持
|
|
206
|
+
- 🚧 批量 API 支持
|
|
207
|
+
- 🚧 并行请求支持
|
|
208
|
+
- 🚧 MCP Server 支持
|
|
209
|
+
- 🚧 更多输出格式(Parquet、Arrow)
|
|
210
|
+
|
|
211
|
+
### Future Optimizations
|
|
212
|
+
|
|
213
|
+
- 🔮 CSV 解析优化
|
|
214
|
+
- 🔮 二进制数据格式支持
|
|
215
|
+
- 🔮 内存池优化
|
|
216
|
+
- 🔮 并发连接池
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Version History
|
|
221
|
+
|
|
222
|
+
- **v1.0.1** (2026-03-10) - 财务数据修复
|
|
223
|
+
- **v1.0.0** (2026-03-10) - 初始版本发布
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Links
|
|
228
|
+
|
|
229
|
+
- [Repository](http://git.ricequant.com/projects/RQAI/repos/rqdata-cli)
|
|
230
|
+
- [Documentation](http://git.ricequant.com/projects/RQAI/repos/rqdata-cli/browse/docs)
|
|
231
|
+
- [Issues](https://jira.ricequant.com)(RiceQuant 内部 Jira)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 rq-cli contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# RQData CLI
|
|
2
|
+
|
|
3
|
+
> 高性能的 RQData 命令行工具,为量化研究和 AI Agent 设计
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://golang.org)
|
|
7
|
+
[]()
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 📖 文档导航
|
|
12
|
+
|
|
13
|
+
- **[🚀 快速上手指南](docs/QUICKSTART.md)** - 5分钟完成安装和第一次查询
|
|
14
|
+
- **[🔧 Go 构建指南](BUILD_GO.md)** - Go 版本编译说明
|
|
15
|
+
- **[📝 更新日志](CHANGELOG.md)** - 版本历史和变更记录
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## ✨ 特性
|
|
20
|
+
|
|
21
|
+
- 🚀 **高性能** - Go 原生实现,单文件可执行,无依赖
|
|
22
|
+
- 🤖 **AI Agent 友好** - NDJSON 流式输出,JSON Payload 输入
|
|
23
|
+
- 📊 **全面数据覆盖** - A股、港股、期货、期权、基金、指数、宏观数据
|
|
24
|
+
- 🔒 **类型安全** - 严格的 Schema 验证,自动参数类型推断
|
|
25
|
+
- 🎯 **字段过滤** - `--fields` 参数精确控制返回数据
|
|
26
|
+
- 📖 **自文档化** - `--schema` 标志输出完整 API 文档(含中文描述)
|
|
27
|
+
- 🔐 **安全认证** - 系统 Keyring 集成,Token 自动管理
|
|
28
|
+
|
|
29
|
+
## 📦 快速安装
|
|
30
|
+
|
|
31
|
+
### 通过 npm 安装(推荐)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g @ricequant2026/rqdata-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
安装完成后即可直接使用:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
rqdata --version
|
|
41
|
+
rqdata --help
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 从源码编译
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 克隆仓库
|
|
48
|
+
git clone http://git.ricequant.com/scm/RQAI/rqdata-cli.git
|
|
49
|
+
cd rqdata-cli
|
|
50
|
+
|
|
51
|
+
# 编译(需要 Go 1.21+)
|
|
52
|
+
VERSION=1.0.0 ./build.sh
|
|
53
|
+
|
|
54
|
+
# 安装到系统路径
|
|
55
|
+
sudo mv rqdata /usr/local/bin/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 跨平台构建
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Linux
|
|
62
|
+
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w -X github.com/rqdata/rqdata-cli/cmd.Version=1.0.0" -o rqdata-linux main.go
|
|
63
|
+
|
|
64
|
+
# macOS (Intel)
|
|
65
|
+
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags="-s -w -X github.com/rqdata/rqdata-cli/cmd.Version=1.0.0" -o rqdata-macos-amd64 main.go
|
|
66
|
+
|
|
67
|
+
# macOS (Apple Silicon)
|
|
68
|
+
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags="-s -w -X github.com/rqdata/rqdata-cli/cmd.Version=1.0.0" -o rqdata-macos-arm64 main.go
|
|
69
|
+
|
|
70
|
+
# Windows
|
|
71
|
+
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-s -w -X github.com/rqdata/rqdata-cli/cmd.Version=1.0.0" -o rqdata.exe main.go
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
详见 [BUILD_GO.md](BUILD_GO.md)
|
|
75
|
+
|
|
76
|
+
### 验证安装
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
rqdata --version
|
|
80
|
+
rqdata --help
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 🔑 认证配置
|
|
84
|
+
|
|
85
|
+
### 环境变量(推荐)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# 添加到 ~/.zshrc 或 ~/.bashrc
|
|
89
|
+
export RQDATA_USERNAME="your_phone_or_email"
|
|
90
|
+
export RQDATA_PASSWORD="your_password"
|
|
91
|
+
|
|
92
|
+
# 重新加载
|
|
93
|
+
source ~/.zshrc
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 交互式登录
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
rqdata auth login
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 验证
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
rqdata auth status
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> 💡 没有账号?访问 [ricequant.com](https://www.ricequant.com) 申请试用
|
|
109
|
+
|
|
110
|
+
## 🚀 快速开始
|
|
111
|
+
|
|
112
|
+
### 示例 1: 获取股票行情
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
rqdata stock cn price --payload '{
|
|
116
|
+
"order_book_ids": ["600000.XSHG", "000001.XSHE"],
|
|
117
|
+
"start_date": "2024-01-01",
|
|
118
|
+
"end_date": "2024-01-31"
|
|
119
|
+
}'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 示例 2: 获取指数成分股
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
rqdata index constituents --payload '{
|
|
126
|
+
"order_book_id": "000300.XSHG",
|
|
127
|
+
"date": "2024-01-31"
|
|
128
|
+
}'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 示例 3: 获取宏观数据
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
rqdata macro shibor --payload '{
|
|
135
|
+
"start_date": "2024-01-01",
|
|
136
|
+
"end_date": "2024-12-31"
|
|
137
|
+
}'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 示例 4: 查看命令文档
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 查看所有命令
|
|
144
|
+
rqdata --help
|
|
145
|
+
|
|
146
|
+
# 查看特定命令的参数说明
|
|
147
|
+
rqdata stock cn price --schema
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
> 📖 更多示例请查看 [快速上手指南](docs/QUICKSTART.md)
|
|
151
|
+
|
|
152
|
+
## 📚 支持的命令
|
|
153
|
+
|
|
154
|
+
### 🔐 认证管理
|
|
155
|
+
- `rqdata auth login` - 交互式登录
|
|
156
|
+
- `rqdata auth status` - 查看认证状态
|
|
157
|
+
|
|
158
|
+
### ⚡ Daemon 模式
|
|
159
|
+
- `rqdata daemon start` - 启动 daemon(批量查询性能提升 25%)
|
|
160
|
+
- `rqdata daemon stop` - 停止 daemon
|
|
161
|
+
- `rqdata daemon status` - 查看状态
|
|
162
|
+
|
|
163
|
+
### 📈 指数数据(4个命令)
|
|
164
|
+
- `rqdata index instruments` - 获取指数列表
|
|
165
|
+
- `rqdata index price` - 获取指数行情
|
|
166
|
+
- `rqdata index constituents` - 获取成分股列表
|
|
167
|
+
- `rqdata index weights` - 获取成分股权重
|
|
168
|
+
|
|
169
|
+
### 📊 A股数据(8个命令)
|
|
170
|
+
- `rqdata stock cn instruments` - 获取股票列表
|
|
171
|
+
- `rqdata stock cn price` - 获取股票行情
|
|
172
|
+
- `rqdata stock cn dividends` - 获取分红数据
|
|
173
|
+
- `rqdata stock cn financials` - 获取财务数据
|
|
174
|
+
- `rqdata stock cn shares` - 获取股本结构
|
|
175
|
+
- `rqdata stock cn margin` - 获取融资融券
|
|
176
|
+
- `rqdata stock cn suspended` - 获取停牌信息
|
|
177
|
+
- `rqdata stock cn northbound` - 获取北向资金
|
|
178
|
+
|
|
179
|
+
### 🇭🇰 港股数据(4个命令)
|
|
180
|
+
- `rqdata stock hk instruments` - 获取港股列表
|
|
181
|
+
- `rqdata stock hk price` - 获取港股行情
|
|
182
|
+
- `rqdata stock hk dividends` - 获取分红数据
|
|
183
|
+
- `rqdata stock hk financials` - 获取财务数据
|
|
184
|
+
|
|
185
|
+
### 📅 交易日历(3个命令)
|
|
186
|
+
- `rqdata calendar dates` - 获取交易日列表
|
|
187
|
+
- `rqdata calendar prev` - 获取前一交易日
|
|
188
|
+
- `rqdata calendar next` - 获取后一交易日
|
|
189
|
+
|
|
190
|
+
### 📉 宏观数据(4个命令)
|
|
191
|
+
- `rqdata macro shibor` - 获取 Shibor 利率
|
|
192
|
+
- `rqdata macro price-cpi` - 获取 CPI 数据
|
|
193
|
+
- `rqdata macro price-ppi` - 获取 PPI 数据
|
|
194
|
+
- `rqdata macro gdp` - 获取 GDP 数据
|
|
195
|
+
|
|
196
|
+
> 📖 **总计 26 个命令**,完整文档请查看 [快速上手指南](docs/QUICKSTART.md)
|
|
197
|
+
|
|
198
|
+
## 🎨 输出格式
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# NDJSON(默认,适合流式处理)
|
|
202
|
+
rqdata stock cn price --payload '{...}'
|
|
203
|
+
|
|
204
|
+
# JSON(结构化数组)
|
|
205
|
+
rqdata stock cn price --payload '{...}' --format json
|
|
206
|
+
|
|
207
|
+
# CSV(原始格式)
|
|
208
|
+
rqdata stock cn price --payload '{...}' --format csv
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 🎨 高级功能
|
|
212
|
+
|
|
213
|
+
### Schema 自动生成
|
|
214
|
+
|
|
215
|
+
使用 Python 脚本从 rqdatac 自动生成参数 schema:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# 生成 schema.json(需要 rqdatac 环境)
|
|
219
|
+
/home/lhz/.miniconda3/envs/zz1000/bin/python scripts/generate_schema_json.py
|
|
220
|
+
|
|
221
|
+
# 查看命令参数说明
|
|
222
|
+
rqdata stock cn price --schema
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
输出包含完整的中文参数描述和类型信息。
|
|
226
|
+
|
|
227
|
+
### 批量查询示例
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# 批量查询多个股票
|
|
231
|
+
for stock in 000001.XSHE 600000.XSHG 600519.XSHG; do
|
|
232
|
+
rqdata stock cn price --payload "{
|
|
233
|
+
\"order_book_ids\": [\"$stock\"],
|
|
234
|
+
\"start_date\": \"2024-01-01\",
|
|
235
|
+
\"end_date\": \"2024-01-31\"
|
|
236
|
+
}" > "${stock}.ndjson"
|
|
237
|
+
done
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## 🛠️ 开发
|
|
241
|
+
|
|
242
|
+
### 技术栈
|
|
243
|
+
|
|
244
|
+
- **语言**: Go 1.21+
|
|
245
|
+
- **依赖**:
|
|
246
|
+
- `github.com/spf13/cobra` - CLI 框架
|
|
247
|
+
- `github.com/zalando/go-keyring` - 系统 Keyring 集成
|
|
248
|
+
- `golang.org/x/term` - 终端交互
|
|
249
|
+
- **配置**:
|
|
250
|
+
- `internal/configs/commands.json` - 命令定义
|
|
251
|
+
- `internal/configs/schema.json` - 参数 Schema(自动生成)
|
|
252
|
+
|
|
253
|
+
### 项目结构
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
rqdata-cli/
|
|
257
|
+
├── main.go # 入口文件
|
|
258
|
+
├── cmd/ # 命令定义
|
|
259
|
+
├── internal/ # 内部包
|
|
260
|
+
│ ├── auth/ # 认证模块
|
|
261
|
+
│ ├── client/ # HTTP 客户端
|
|
262
|
+
│ ├── configs/ # 配置文件(commands.json, schema.json)
|
|
263
|
+
│ ├── executor/ # 命令执行器
|
|
264
|
+
│ ├── formatter/ # 输出格式化
|
|
265
|
+
│ └── loader/ # 配置加载器
|
|
266
|
+
├── scripts/ # 工具脚本
|
|
267
|
+
│ └── generate_schema_json.py # Schema 生成脚本
|
|
268
|
+
├── tests/ # 测试
|
|
269
|
+
└── docs/ # 文档
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 构建与测试
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# 编译
|
|
276
|
+
VERSION=dev ./build.sh
|
|
277
|
+
|
|
278
|
+
# 运行
|
|
279
|
+
./rqdata --help
|
|
280
|
+
|
|
281
|
+
# 测试
|
|
282
|
+
./rqdata auth status
|
|
283
|
+
./rqdata stock cn price --schema
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## 📖 文档
|
|
287
|
+
|
|
288
|
+
- [Go 构建指南](BUILD_GO.md)
|
|
289
|
+
- [快速上手](docs/QUICKSTART.md)
|
|
290
|
+
- [命令列表](docs/rqdata_cli_commands.md)
|
|
291
|
+
- [更新日志](CHANGELOG.md)
|
|
292
|
+
|
|
293
|
+
## 🚢 npm 发布
|
|
294
|
+
|
|
295
|
+
项目现在采用“主包 + 平台包”的发布方式:
|
|
296
|
+
|
|
297
|
+
- `@ricequant2026/rqdata-cli`:主包,只包含 JS wrapper 和平台依赖声明
|
|
298
|
+
- `@ricequant2026/rqdata-cli-linux-x64`
|
|
299
|
+
- `@ricequant2026/rqdata-cli-darwin-x64`
|
|
300
|
+
- `@ricequant2026/rqdata-cli-darwin-arm64`
|
|
301
|
+
- `@ricequant2026/rqdata-cli-win32-x64`
|
|
302
|
+
|
|
303
|
+
发布时先发平台包,再发主包:
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
npm version patch
|
|
307
|
+
npm run publish:all
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`publish:all` 内部会对所有 scoped 包使用 `npm publish --access public`。
|
|
311
|
+
|
|
312
|
+
如果只是先测试发布流程,建议先用预发布版本和 `next` tag:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
npm version prerelease --preid rc
|
|
316
|
+
npm run publish:next
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
如果只想验证发布命令本身而不真正上传:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npm run publish:dry-run
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
如果只想本地生成所有 tarball:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
npm run pack:all
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
如果只想本地验证当前平台的主包执行链路:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npm run build:npm
|
|
335
|
+
npm run link:platform
|
|
336
|
+
node bin/rqdata.js --version
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## 📝 更新日志
|
|
340
|
+
|
|
341
|
+
### v2.0.0 (2026-03-27) - Go 重写版本
|
|
342
|
+
|
|
343
|
+
- ✨ 使用 Go 完全重写,单文件可执行
|
|
344
|
+
- 🔐 系统 Keyring 集成,安全存储凭证
|
|
345
|
+
- 📖 Schema 自动生成,支持中文参数描述
|
|
346
|
+
- 🚀 静态编译,跨平台分发
|
|
347
|
+
- 🔧 修复 HTML 转义问题(`array<string>` 显示正确)
|
|
348
|
+
- 📊 完整的数据覆盖(指数、A股、港股、期货、期权、基金、宏观)
|
|
349
|
+
|
|
350
|
+
### v1.0.0 (2026-03-10) - C++ 版本
|
|
351
|
+
|
|
352
|
+
- ✨ 初始 C++ 版本发布
|
|
353
|
+
- 🚀 CURL 连接复用优化
|
|
354
|
+
- 📊 完整的数据覆盖
|
|
355
|
+
|
|
356
|
+
详见 [CHANGELOG.md](CHANGELOG.md)
|
|
357
|
+
|
|
358
|
+
## 📄 许可证
|
|
359
|
+
|
|
360
|
+
MIT License - 详见 [LICENSE](LICENSE)
|
|
361
|
+
|
|
362
|
+
## 🙏 致谢
|
|
363
|
+
|
|
364
|
+
- [RQData](https://www.ricequant.com) - 提供数据 API
|
|
365
|
+
- [CLI11](https://github.com/CLIUtils/CLI11) - 命令行解析
|
|
366
|
+
- [nlohmann/json](https://github.com/nlohmann/json) - JSON 处理
|
|
367
|
+
|
|
368
|
+
## 📞 支持
|
|
369
|
+
|
|
370
|
+
- 🐛 Issues: [Jira](https://jira.ricequant.com)(RiceQuant 内部)
|
|
371
|
+
- 📚 文档: [项目文档](http://git.ricequant.com/projects/RQAI/repos/rqdata-cli/browse/docs)
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
**注意**: 使用本工具需要有效的 RQData 账号。访问 [ricequant.com](https://www.ricequant.com) 申请试用或购买。
|
package/bin/rqdata.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require('node:child_process');
|
|
4
|
+
const { findCurrentTarget } = require('../scripts/npm/platforms');
|
|
5
|
+
|
|
6
|
+
function resolveBinary() {
|
|
7
|
+
const target = findCurrentTarget();
|
|
8
|
+
|
|
9
|
+
if (!target) {
|
|
10
|
+
console.error(`Unsupported platform: ${process.platform}-${process.arch}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let binary;
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
({ binary } = require(target.packageName));
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error(`Missing platform package: ${target.packageName}`);
|
|
20
|
+
console.error('Reinstall the package on a supported platform or verify optional dependencies are enabled.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!binary) {
|
|
25
|
+
console.error('rqdata binary is missing. Reinstall the package or rebuild release artifacts.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return binary;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const result = spawnSync(resolveBinary(), process.argv.slice(2), {
|
|
33
|
+
stdio: 'inherit'
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (result.error) {
|
|
37
|
+
console.error(result.error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ricequant2026/rqdata-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "RQData CLI for AI agents and quantitative research",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"rqdata": "bin/rqdata.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"scripts/npm/",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
16
|
+
"optionalDependencies": {
|
|
17
|
+
"@ricequant2026/rqdata-cli-linux-x64": "1.0.0",
|
|
18
|
+
"@ricequant2026/rqdata-cli-darwin-x64": "1.0.0",
|
|
19
|
+
"@ricequant2026/rqdata-cli-darwin-arm64": "1.0.0",
|
|
20
|
+
"@ricequant2026/rqdata-cli-win32-x64": "1.0.0"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build:npm": "node scripts/npm/build-packages.js",
|
|
24
|
+
"link:platform": "node scripts/npm/link-platform-package.js",
|
|
25
|
+
"pack:all": "node scripts/npm/pack-all.js",
|
|
26
|
+
"publish:all": "node scripts/npm/publish-all.js",
|
|
27
|
+
"publish:next": "NPM_TAG=next node scripts/npm/publish-all.js",
|
|
28
|
+
"publish:dry-run": "NPM_TAG=next NPM_DRY_RUN=1 node scripts/npm/publish-all.js",
|
|
29
|
+
"pack:dry-run": "npm pack --dry-run"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"rqdata",
|
|
33
|
+
"cli",
|
|
34
|
+
"finance",
|
|
35
|
+
"quant",
|
|
36
|
+
"agent"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/rqdata/rqdata-cli.git"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/rqdata/rqdata-cli",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/rqdata/rqdata-cli/issues"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { mkdirSync, rmSync, readFileSync, writeFileSync, copyFileSync, chmodSync } = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { spawnSync } = require('node:child_process');
|
|
6
|
+
const { DIST_DIR, PLATFORM_TARGETS, PACKAGES_DIR } = require('./platforms');
|
|
7
|
+
|
|
8
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
9
|
+
const pkg = JSON.parse(readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
10
|
+
const VERSION = process.env.VERSION || pkg.version;
|
|
11
|
+
const GOCACHE_DIR = process.env.GOCACHE_DIR || path.join(ROOT, '.cache', 'go-build');
|
|
12
|
+
|
|
13
|
+
function run(command, args, options = {}) {
|
|
14
|
+
const result = spawnSync(command, args, {
|
|
15
|
+
cwd: options.cwd || ROOT,
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
env: {
|
|
18
|
+
...process.env,
|
|
19
|
+
...options.env
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (result.status !== 0) {
|
|
24
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function buildTargets() {
|
|
29
|
+
rmSync(DIST_DIR, { recursive: true, force: true });
|
|
30
|
+
mkdirSync(DIST_DIR, { recursive: true });
|
|
31
|
+
mkdirSync(GOCACHE_DIR, { recursive: true });
|
|
32
|
+
|
|
33
|
+
for (const target of PLATFORM_TARGETS) {
|
|
34
|
+
const outputPath = path.join(DIST_DIR, target.output);
|
|
35
|
+
const ldflags = `-s -w -X github.com/rqdata/rqdata-cli/cmd.Version=${VERSION}`;
|
|
36
|
+
|
|
37
|
+
console.log(`Building ${target.key} -> ${target.output}`);
|
|
38
|
+
run('go', ['build', '-trimpath', '-ldflags', ldflags, '-o', outputPath, 'main.go'], {
|
|
39
|
+
env: {
|
|
40
|
+
CGO_ENABLED: '0',
|
|
41
|
+
GOCACHE: GOCACHE_DIR,
|
|
42
|
+
GOOS: target.goos,
|
|
43
|
+
GOARCH: target.goarch
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function writePlatformPackage(target) {
|
|
50
|
+
const packageDir = target.packageDir;
|
|
51
|
+
const binarySource = path.join(DIST_DIR, target.output);
|
|
52
|
+
const binaryTarget = path.join(packageDir, 'bin', target.binName);
|
|
53
|
+
|
|
54
|
+
rmSync(packageDir, { recursive: true, force: true });
|
|
55
|
+
mkdirSync(path.join(packageDir, 'bin'), { recursive: true });
|
|
56
|
+
|
|
57
|
+
copyFileSync(binarySource, binaryTarget);
|
|
58
|
+
if (target.os !== 'win32') {
|
|
59
|
+
chmodSync(binaryTarget, 0o755);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
writeFileSync(
|
|
63
|
+
path.join(packageDir, 'index.js'),
|
|
64
|
+
[
|
|
65
|
+
"const path = require('node:path');",
|
|
66
|
+
'',
|
|
67
|
+
`module.exports.binary = path.join(__dirname, 'bin', '${target.binName}');`,
|
|
68
|
+
''
|
|
69
|
+
].join('\n')
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
writeFileSync(
|
|
73
|
+
path.join(packageDir, 'README.md'),
|
|
74
|
+
`# ${target.packageName}\n\nPlatform binary package for @ricequant2026/rqdata-cli.\n`
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
writeFileSync(
|
|
78
|
+
path.join(packageDir, 'package.json'),
|
|
79
|
+
JSON.stringify(
|
|
80
|
+
{
|
|
81
|
+
name: target.packageName,
|
|
82
|
+
version: VERSION,
|
|
83
|
+
description: `Platform binary for @ricequant2026/rqdata-cli (${target.key})`,
|
|
84
|
+
license: pkg.license,
|
|
85
|
+
os: [target.os],
|
|
86
|
+
cpu: [target.cpu],
|
|
87
|
+
files: ['bin/', 'index.js', 'README.md', 'LICENSE'],
|
|
88
|
+
main: 'index.js'
|
|
89
|
+
},
|
|
90
|
+
null,
|
|
91
|
+
2
|
|
92
|
+
) + '\n'
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
copyFileSync(path.join(ROOT, 'LICENSE'), path.join(packageDir, 'LICENSE'));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function materializePackages() {
|
|
99
|
+
rmSync(PACKAGES_DIR, { recursive: true, force: true });
|
|
100
|
+
mkdirSync(PACKAGES_DIR, { recursive: true });
|
|
101
|
+
|
|
102
|
+
for (const target of PLATFORM_TARGETS) {
|
|
103
|
+
writePlatformPackage(target);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
buildTargets();
|
|
108
|
+
materializePackages();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { mkdirSync, rmSync, symlinkSync, existsSync } = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { findCurrentTarget } = require('./platforms');
|
|
6
|
+
|
|
7
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
8
|
+
const NODE_MODULES = path.join(ROOT, 'node_modules');
|
|
9
|
+
|
|
10
|
+
const target = findCurrentTarget();
|
|
11
|
+
|
|
12
|
+
if (!target) {
|
|
13
|
+
console.warn(`Unsupported platform for local link: ${process.platform}-${process.arch}`);
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const destination = path.join(NODE_MODULES, target.packageName);
|
|
18
|
+
const destinationDir = path.dirname(destination);
|
|
19
|
+
|
|
20
|
+
mkdirSync(NODE_MODULES, { recursive: true });
|
|
21
|
+
mkdirSync(destinationDir, { recursive: true });
|
|
22
|
+
rmSync(destination, { recursive: true, force: true });
|
|
23
|
+
rmSync(path.join(NODE_MODULES, target.packageName.split('/').pop()), { recursive: true, force: true });
|
|
24
|
+
|
|
25
|
+
if (!existsSync(target.packageDir)) {
|
|
26
|
+
console.error(`Platform package has not been built: ${target.packageDir}`);
|
|
27
|
+
console.error('Run `npm run build:npm` first.');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
symlinkSync(target.packageDir, destination, 'dir');
|
|
32
|
+
console.log(`Linked ${target.packageName} -> ${target.packageDir}`);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { readFileSync } = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { spawnSync } = require('node:child_process');
|
|
6
|
+
const { PLATFORM_TARGETS } = require('./platforms');
|
|
7
|
+
|
|
8
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
9
|
+
const pkg = JSON.parse(readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
10
|
+
|
|
11
|
+
function run(command, args, cwd = ROOT) {
|
|
12
|
+
const result = spawnSync(command, args, {
|
|
13
|
+
cwd,
|
|
14
|
+
stdio: 'inherit',
|
|
15
|
+
env: process.env
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (result.status !== 0) {
|
|
19
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
run('node', ['scripts/npm/build-packages.js']);
|
|
24
|
+
|
|
25
|
+
for (const target of PLATFORM_TARGETS) {
|
|
26
|
+
run('npm', ['pack'], target.packageDir);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
run('npm', ['pack']);
|
|
30
|
+
|
|
31
|
+
console.log(`Packed ${pkg.name}@${pkg.version} and ${PLATFORM_TARGETS.length} platform packages.`);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
|
|
3
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
4
|
+
const DIST_DIR = path.join(ROOT, 'dist');
|
|
5
|
+
const PACKAGES_DIR = path.join(ROOT, 'npm');
|
|
6
|
+
const NPM_SCOPE = '@ricequant2026';
|
|
7
|
+
|
|
8
|
+
const PLATFORM_TARGETS = [
|
|
9
|
+
{
|
|
10
|
+
key: 'linux-x64',
|
|
11
|
+
goos: 'linux',
|
|
12
|
+
goarch: 'amd64',
|
|
13
|
+
os: 'linux',
|
|
14
|
+
cpu: 'x64',
|
|
15
|
+
packageName: `${NPM_SCOPE}/rqdata-cli-linux-x64`,
|
|
16
|
+
packageDir: path.join(PACKAGES_DIR, 'rqdata-cli-linux-x64'),
|
|
17
|
+
output: 'rqdata-linux-amd64',
|
|
18
|
+
binName: 'rqdata'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: 'darwin-x64',
|
|
22
|
+
goos: 'darwin',
|
|
23
|
+
goarch: 'amd64',
|
|
24
|
+
os: 'darwin',
|
|
25
|
+
cpu: 'x64',
|
|
26
|
+
packageName: `${NPM_SCOPE}/rqdata-cli-darwin-x64`,
|
|
27
|
+
packageDir: path.join(PACKAGES_DIR, 'rqdata-cli-darwin-x64'),
|
|
28
|
+
output: 'rqdata-macos-amd64',
|
|
29
|
+
binName: 'rqdata'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'darwin-arm64',
|
|
33
|
+
goos: 'darwin',
|
|
34
|
+
goarch: 'arm64',
|
|
35
|
+
os: 'darwin',
|
|
36
|
+
cpu: 'arm64',
|
|
37
|
+
packageName: `${NPM_SCOPE}/rqdata-cli-darwin-arm64`,
|
|
38
|
+
packageDir: path.join(PACKAGES_DIR, 'rqdata-cli-darwin-arm64'),
|
|
39
|
+
output: 'rqdata-macos-arm64',
|
|
40
|
+
binName: 'rqdata'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
key: 'win32-x64',
|
|
44
|
+
goos: 'windows',
|
|
45
|
+
goarch: 'amd64',
|
|
46
|
+
os: 'win32',
|
|
47
|
+
cpu: 'x64',
|
|
48
|
+
packageName: `${NPM_SCOPE}/rqdata-cli-win32-x64`,
|
|
49
|
+
packageDir: path.join(PACKAGES_DIR, 'rqdata-cli-win32-x64'),
|
|
50
|
+
output: 'rqdata-windows-amd64.exe',
|
|
51
|
+
binName: 'rqdata.exe'
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
function currentPlatformKey() {
|
|
56
|
+
return `${process.platform}-${process.arch}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function findCurrentTarget() {
|
|
60
|
+
return PLATFORM_TARGETS.find((target) => target.key === currentPlatformKey()) || null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function findTargetByKey(key) {
|
|
64
|
+
return PLATFORM_TARGETS.find((target) => target.key === key) || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
DIST_DIR,
|
|
69
|
+
NPM_SCOPE,
|
|
70
|
+
PACKAGES_DIR,
|
|
71
|
+
PLATFORM_TARGETS,
|
|
72
|
+
findTargetByKey,
|
|
73
|
+
findCurrentTarget
|
|
74
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { spawnSync } = require('node:child_process');
|
|
5
|
+
const { PLATFORM_TARGETS } = require('./platforms');
|
|
6
|
+
|
|
7
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
8
|
+
const NPM_TAG = process.env.NPM_TAG || 'latest';
|
|
9
|
+
const NPM_DRY_RUN = process.env.NPM_DRY_RUN === '1';
|
|
10
|
+
|
|
11
|
+
function run(command, args, cwd = ROOT) {
|
|
12
|
+
const result = spawnSync(command, args, {
|
|
13
|
+
cwd,
|
|
14
|
+
stdio: 'inherit',
|
|
15
|
+
env: process.env
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (result.status !== 0) {
|
|
19
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function publishArgs() {
|
|
24
|
+
const args = ['publish', '--access', 'public', '--tag', NPM_TAG];
|
|
25
|
+
|
|
26
|
+
if (NPM_DRY_RUN) {
|
|
27
|
+
args.push('--dry-run');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
run('node', ['scripts/npm/build-packages.js']);
|
|
34
|
+
|
|
35
|
+
for (const target of PLATFORM_TARGETS) {
|
|
36
|
+
run('npm', publishArgs(), target.packageDir);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
run('npm', publishArgs());
|