gangtise-openapi-cli 0.5.1 → 0.7.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/README.md +43 -16
- package/dist/src/cli.js +156 -69
- package/dist/src/core/args.js +0 -1
- package/dist/src/core/auth.js +0 -1
- package/dist/src/core/client.js +14 -22
- package/dist/src/core/config.js +0 -1
- package/dist/src/core/endpoints.js +67 -12
- package/dist/src/core/errors.js +0 -1
- package/dist/src/core/lookupData/announcement-categories.js +554 -0
- package/dist/src/core/lookupData/broker-orgs.js +722 -0
- package/dist/src/core/lookupData/index.js +19 -0
- package/dist/src/core/lookupData/industries.js +157 -0
- package/dist/src/core/lookupData/industry-codes.js +126 -0
- package/dist/src/core/lookupData/meeting-orgs.js +522 -0
- package/dist/src/core/lookupData/regions.js +78 -0
- package/dist/src/core/lookupData/research-areas.js +266 -0
- package/dist/src/core/lookupData/theme-ids.js +1614 -0
- package/dist/src/core/lookupData/types.js +1 -0
- package/dist/src/core/normalize.js +0 -1
- package/dist/src/core/output.js +0 -1
- package/package.json +2 -3
- package/dist/src/cli.js.map +0 -1
- package/dist/src/core/args.js.map +0 -1
- package/dist/src/core/auth.js.map +0 -1
- package/dist/src/core/client.js.map +0 -1
- package/dist/src/core/config.js.map +0 -1
- package/dist/src/core/endpoints.js.map +0 -1
- package/dist/src/core/errors.js.map +0 -1
- package/dist/src/core/lookupData.js +0 -1816
- package/dist/src/core/lookupData.js.map +0 -1
- package/dist/src/core/normalize.js.map +0 -1
- package/dist/src/core/output.js.map +0 -1
package/README.md
CHANGED
|
@@ -44,6 +44,7 @@ export GANGTISE_TOKEN="Bearer xxx"
|
|
|
44
44
|
- `gangtise quote ...`
|
|
45
45
|
- `gangtise fundamental ...`
|
|
46
46
|
- `gangtise ai ...`
|
|
47
|
+
- `gangtise vault ...`
|
|
47
48
|
- `gangtise raw call ...`
|
|
48
49
|
|
|
49
50
|
其中 `lookup` 下的研究方向、机构、行业枚举已内置在项目中,无需额外本地文档文件。
|
|
@@ -84,7 +85,7 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
|
|
|
84
85
|
- `insight foreign-report list`
|
|
85
86
|
- `insight announcement list`
|
|
86
87
|
- `ai security-clue`
|
|
87
|
-
- `
|
|
88
|
+
- `vault drive-list`
|
|
88
89
|
|
|
89
90
|
规则:
|
|
90
91
|
- **有时间范围时**(传了 `--start-time/--end-time` 或 `--start-date/--end-date`):**省略 `--size`**,CLI 自动翻页查全
|
|
@@ -93,7 +94,7 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
|
|
|
93
94
|
|
|
94
95
|
## 智能文件命名
|
|
95
96
|
|
|
96
|
-
下载命令(`summary download`、`research download`、`foreign-report download`、`announcement download`、`
|
|
97
|
+
下载命令(`summary download`、`research download`、`foreign-report download`、`announcement download`、`vault drive-download`)省略 `--output` 时,自动使用真实标题作为文件名:
|
|
97
98
|
|
|
98
99
|
1. **缓存优先** — 如果之前执行过对应的 `list` 命令,标题已缓存在 `~/.config/gangtise/title-cache.json`,直接使用,无额外 API 调用
|
|
99
100
|
2. **API 回查** — 缓存未命中时,自动查询最近 200 条记录匹配标题
|
|
@@ -146,14 +147,26 @@ gangtise insight roadshow list --institution C100000017
|
|
|
146
147
|
|
|
147
148
|
```bash
|
|
148
149
|
gangtise quote day-kline --security 600519.SH --start-date 2026-03-01 --end-date 2026-03-31
|
|
150
|
+
# 不传 --security 默认返回全市场,不传 --start-date 默认往前一年,不传 --end-date 默认最新
|
|
151
|
+
gangtise quote day-kline --format json
|
|
152
|
+
# 港股日K线
|
|
153
|
+
gangtise quote day-kline-hk --security 00700.HK --start-date 2026-03-01 --end-date 2026-03-31
|
|
149
154
|
```
|
|
150
155
|
|
|
151
156
|
### Fundamental
|
|
152
157
|
|
|
153
158
|
```bash
|
|
154
159
|
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2025 --period q3 --field netProfit
|
|
155
|
-
#
|
|
156
|
-
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2024 --
|
|
160
|
+
# 多年度:同时查2023-2025年报净利润
|
|
161
|
+
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2023 --fiscal-year 2024 --fiscal-year 2025 --period annual --field netProfit
|
|
162
|
+
# 最新一期完整利润表
|
|
163
|
+
gangtise fundamental income-statement --security-code 600519.SH --format json
|
|
164
|
+
gangtise fundamental balance-sheet --security-code 600519.SH --fiscal-year 2025 --period q3 --field totalCurrAssets --field totalCurrLiab
|
|
165
|
+
# 最新一期完整资产负债表
|
|
166
|
+
gangtise fundamental balance-sheet --security-code 600519.SH --format json
|
|
167
|
+
gangtise fundamental cash-flow --security-code 600519.SH --fiscal-year 2025 --period q3 --field netOpCashFlows --field netInvCashFlows --field netFinCashFlows
|
|
168
|
+
# 最新一期完整现金流量表
|
|
169
|
+
gangtise fundamental cash-flow --security-code 600519.SH --format json
|
|
157
170
|
gangtise fundamental main-business --security-code 600519.SH --breakdown region
|
|
158
171
|
gangtise fundamental valuation-analysis --security-code 600519.SH --indicator peTtm
|
|
159
172
|
```
|
|
@@ -168,14 +181,22 @@ gangtise ai security-clue --start-time "2026-04-01 00:00:00" --end-time "2026-04
|
|
|
168
181
|
gangtise ai one-pager --security-code 600519.SH
|
|
169
182
|
gangtise ai investment-logic --security-code 600519.SH
|
|
170
183
|
gangtise ai peer-comparison --security-code 600519.SH
|
|
171
|
-
gangtise ai
|
|
184
|
+
gangtise ai earnings-review --security-code 600519.SH --period 2025q3
|
|
185
|
+
gangtise ai theme-tracking --theme-id 121000131 --date 2026-03-01 --type morning
|
|
186
|
+
gangtise ai research-outline --security-code 600519.SH
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Vault
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
gangtise vault drive-list --keyword 部门文档 --space-type 1 --file-type 1
|
|
172
193
|
|
|
173
194
|
# 云盘下载:自动使用文件标题命名
|
|
174
|
-
gangtise
|
|
195
|
+
gangtise vault drive-download --file-id 62130
|
|
175
196
|
# → 2028 全球智能危机 一份来自未来的金融史思想实验 .pdf
|
|
197
|
+
```
|
|
176
198
|
|
|
177
199
|
gangtise ai knowledge-resource-download --resource-type 60 --source-id 3052524 --output ./resource.txt
|
|
178
|
-
# 若接口返回外链 URL,也会直接输出 URL 或按 --output 保存
|
|
179
200
|
```
|
|
180
201
|
|
|
181
202
|
### Raw
|
|
@@ -192,9 +213,10 @@ gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'
|
|
|
192
213
|
- auth: `login` / `status`
|
|
193
214
|
- lookup: `research-area list` / `broker-org list` / `meeting-org list` / `industry list` / `industry-code list` / `region list` / `announcement-category list`
|
|
194
215
|
- insight: `opinion list` / `summary list` / `summary download` / `roadshow list` / `site-visit list` / `strategy list` / `forum list` / `research list` / `research download` / `foreign-report list` / `foreign-report download` / `announcement list` / `announcement download`
|
|
195
|
-
- quote: `day-kline`
|
|
216
|
+
- quote: `day-kline` / `day-kline-hk`
|
|
196
217
|
- fundamental: `income-statement` / `main-business` / `valuation-analysis`
|
|
197
|
-
- ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `
|
|
218
|
+
- ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `theme-tracking` / `research-outline`
|
|
219
|
+
- vault: `drive-list` / `drive-download`
|
|
198
220
|
|
|
199
221
|
注意:`knowledge-resource-download` 依赖正确的 `resourceType + sourceId` 组合;错误组合会返回 `433007 不支持该数据源`。
|
|
200
222
|
|
|
@@ -210,17 +232,22 @@ gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'
|
|
|
210
232
|
|
|
211
233
|
## Claude Code Skill
|
|
212
234
|
|
|
213
|
-
本项目包含一个 [Claude Code](https://claude.ai/claude-code) skill 定义(`SKILL.md`),可让 AI agent 自动调用 `gangtise` CLI 完成投研数据查询。
|
|
235
|
+
本项目包含一个 [Claude Code](https://claude.ai/claude-code) skill 定义(`gangtise-openapi/SKILL.md`),可让 AI agent 自动调用 `gangtise` CLI 完成投研数据查询。
|
|
236
|
+
|
|
237
|
+
Skill 目录结构:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
gangtise-openapi/
|
|
241
|
+
├── SKILL.md # 主 skill 文件(命令参考、参数枚举、使用规则)
|
|
242
|
+
└── references/
|
|
243
|
+
└── lookup-ids.md # 常用 ID 速查表(行业/券商/机构/公告分类等)
|
|
244
|
+
```
|
|
214
245
|
|
|
215
246
|
安装到 Claude Code:
|
|
216
247
|
|
|
217
248
|
```bash
|
|
218
|
-
#
|
|
219
|
-
cp
|
|
220
|
-
|
|
221
|
-
# 方式二:手动创建目录并复制
|
|
222
|
-
mkdir -p ~/.claude/skills/gangtise-openapi
|
|
223
|
-
cp SKILL.md ~/.claude/skills/gangtise-openapi/
|
|
249
|
+
# 从项目根目录复制整个 skill 目录
|
|
250
|
+
cp -r gangtise-openapi ~/.claude/skills/gangtise-openapi
|
|
224
251
|
```
|
|
225
252
|
|
|
226
253
|
安装后,在 Claude Code 中可以用自然语言触发,例如:
|
package/dist/src/cli.js
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command, Option } from "commander";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import os from "node:os";
|
|
5
|
-
import path, { extname } from "node:path";
|
|
6
3
|
import { collectKeyValue, collectList, collectNumberList, maybeArray, toTimestamp13 } from "./core/args.js";
|
|
7
|
-
import { readTokenCache } from "./core/auth.js";
|
|
8
|
-
import { GangtiseClient } from "./core/client.js";
|
|
9
4
|
import { loadConfig } from "./core/config.js";
|
|
10
5
|
import { ApiError, ConfigError, DownloadError } from "./core/errors.js";
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
// --- Lazy-loaded modules (deferred to action handlers) ---
|
|
7
|
+
async function createClient() {
|
|
8
|
+
const { GangtiseClient } = await import("./core/client.js");
|
|
9
|
+
return new GangtiseClient(loadConfig());
|
|
10
|
+
}
|
|
11
|
+
async function readTokenCache(...args) {
|
|
12
|
+
return (await import("./core/auth.js")).readTokenCache(...args);
|
|
13
|
+
}
|
|
14
|
+
async function normalizeRows(...args) {
|
|
15
|
+
return (await import("./core/normalize.js")).normalizeRows(...args);
|
|
16
|
+
}
|
|
17
|
+
async function renderOutput(...args) {
|
|
18
|
+
return (await import("./core/output.js")).renderOutput(...args);
|
|
19
|
+
}
|
|
20
|
+
async function saveOutputIfNeeded(...args) {
|
|
21
|
+
return (await import("./core/output.js")).saveOutputIfNeeded(...args);
|
|
22
|
+
}
|
|
13
23
|
function parseFormat(value) {
|
|
14
24
|
const format = value ?? "table";
|
|
15
25
|
if (["table", "json", "jsonl", "csv", "markdown"].includes(format)) {
|
|
@@ -18,21 +28,32 @@ function parseFormat(value) {
|
|
|
18
28
|
throw new ConfigError(`Unsupported format: ${format}`);
|
|
19
29
|
}
|
|
20
30
|
// --- Title cache: list writes, download reads ---
|
|
21
|
-
|
|
31
|
+
let _titleCachePath;
|
|
32
|
+
function getTitleCachePath() {
|
|
33
|
+
if (!_titleCachePath) {
|
|
34
|
+
const path = require("node:path");
|
|
35
|
+
const os = require("node:os");
|
|
36
|
+
_titleCachePath = path.join(os.homedir(), ".config", "gangtise", "title-cache.json");
|
|
37
|
+
}
|
|
38
|
+
return _titleCachePath;
|
|
39
|
+
}
|
|
22
40
|
const TITLE_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
23
41
|
async function readTitleCache() {
|
|
24
42
|
try {
|
|
25
|
-
|
|
43
|
+
const fs = await import("node:fs/promises");
|
|
44
|
+
return JSON.parse(await fs.readFile(getTitleCachePath(), "utf8"));
|
|
26
45
|
}
|
|
27
46
|
catch {
|
|
28
47
|
return {};
|
|
29
48
|
}
|
|
30
49
|
}
|
|
31
50
|
async function writeTitleCache(endpoint, titles) {
|
|
51
|
+
const fs = await import("node:fs/promises");
|
|
52
|
+
const path = await import("node:path");
|
|
32
53
|
const data = await readTitleCache();
|
|
33
54
|
data[endpoint] = { titles, ts: Date.now() };
|
|
34
|
-
await fs.mkdir(path.dirname(
|
|
35
|
-
await fs.writeFile(
|
|
55
|
+
await fs.mkdir(path.dirname(getTitleCachePath()), { recursive: true });
|
|
56
|
+
await fs.writeFile(getTitleCachePath(), JSON.stringify(data), "utf8");
|
|
36
57
|
}
|
|
37
58
|
function lookupTitleCache(data, endpoint, id) {
|
|
38
59
|
const entry = data[endpoint];
|
|
@@ -41,7 +62,7 @@ function lookupTitleCache(data, endpoint, id) {
|
|
|
41
62
|
return entry.titles[id];
|
|
42
63
|
}
|
|
43
64
|
async function printData(data, format, output, cache) {
|
|
44
|
-
const normalized = normalizeRows(data);
|
|
65
|
+
const normalized = await normalizeRows(data);
|
|
45
66
|
// Populate title cache from list results
|
|
46
67
|
if (cache && Array.isArray(normalized)) {
|
|
47
68
|
const titleField = cache.titleField ?? "title";
|
|
@@ -58,7 +79,7 @@ async function printData(data, format, output, cache) {
|
|
|
58
79
|
if (Object.keys(titles).length > 0)
|
|
59
80
|
writeTitleCache(cache.endpointKey, titles).catch(() => { });
|
|
60
81
|
}
|
|
61
|
-
const content = renderOutput(normalized, format);
|
|
82
|
+
const content = await renderOutput(normalized, format);
|
|
62
83
|
if (output) {
|
|
63
84
|
await saveOutputIfNeeded(content, output);
|
|
64
85
|
process.stdout.write(`${output}\n`);
|
|
@@ -100,6 +121,7 @@ function extFromContentType(contentType) {
|
|
|
100
121
|
}
|
|
101
122
|
/** Resolve a human-readable filename by looking up the title from cache or list endpoint. */
|
|
102
123
|
async function resolveTitle(client, result, listEndpoint, idField, idValue, titleField = "title") {
|
|
124
|
+
const { extname } = await import("node:path");
|
|
103
125
|
const file = result;
|
|
104
126
|
const serverExt = file.filename ? extname(file.filename) : extFromContentType(file.contentType);
|
|
105
127
|
function buildFilename(rawTitle) {
|
|
@@ -166,30 +188,15 @@ function addTimeFilters(command) {
|
|
|
166
188
|
.option("--keyword <keyword>", "Keyword");
|
|
167
189
|
}
|
|
168
190
|
const program = new Command();
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
function loadPackageVersion() {
|
|
172
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
173
|
-
const req = createRequire(import.meta.url);
|
|
174
|
-
// Works from both src/ (dev) and dist/src/ (built)
|
|
175
|
-
try {
|
|
176
|
-
return req(path.resolve(__dirname, "../package.json")).version;
|
|
177
|
-
}
|
|
178
|
-
catch { }
|
|
179
|
-
try {
|
|
180
|
-
return req(path.resolve(__dirname, "../../package.json")).version;
|
|
181
|
-
}
|
|
182
|
-
catch { }
|
|
183
|
-
return "0.0.0";
|
|
184
|
-
}
|
|
185
|
-
program.name("gangtise").description("Gangtise OpenAPI CLI").version(loadPackageVersion());
|
|
191
|
+
const CLI_VERSION = "0.6.0";
|
|
192
|
+
program.name("gangtise").description("Gangtise OpenAPI CLI").version(CLI_VERSION);
|
|
186
193
|
program
|
|
187
194
|
.command("auth")
|
|
188
195
|
.description("Authentication commands")
|
|
189
196
|
.addCommand(new Command("login")
|
|
190
197
|
.option("--format <format>", "Output format", "json")
|
|
191
198
|
.action(async (options) => {
|
|
192
|
-
const client =
|
|
199
|
+
const client = await createClient();
|
|
193
200
|
await printData(await client.login(), parseFormat(options.format));
|
|
194
201
|
}))
|
|
195
202
|
.addCommand(new Command("status")
|
|
@@ -202,32 +209,36 @@ program
|
|
|
202
209
|
const lookup = new Command("lookup").description("Lookup helper APIs");
|
|
203
210
|
lookup
|
|
204
211
|
.addCommand(new Command("research-area").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
205
|
-
const client =
|
|
212
|
+
const client = await createClient();
|
|
206
213
|
await printData(await client.call("lookup.research-areas.list"), parseFormat(options.format));
|
|
207
214
|
})))
|
|
208
215
|
.addCommand(new Command("broker-org").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
209
|
-
const client =
|
|
216
|
+
const client = await createClient();
|
|
210
217
|
await printData(await client.call("lookup.broker-orgs.list"), parseFormat(options.format));
|
|
211
218
|
})))
|
|
212
219
|
.addCommand(new Command("meeting-org").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
213
|
-
const client =
|
|
220
|
+
const client = await createClient();
|
|
214
221
|
await printData(await client.call("lookup.meeting-orgs.list"), parseFormat(options.format));
|
|
215
222
|
})))
|
|
216
223
|
.addCommand(new Command("industry").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
217
|
-
const client =
|
|
224
|
+
const client = await createClient();
|
|
218
225
|
await printData(await client.call("lookup.industries.list"), parseFormat(options.format));
|
|
219
226
|
})))
|
|
220
227
|
.addCommand(new Command("region").description("Foreign report region codes").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
221
|
-
const client =
|
|
228
|
+
const client = await createClient();
|
|
222
229
|
await printData(await client.call("lookup.regions.list"), parseFormat(options.format));
|
|
223
230
|
})))
|
|
224
231
|
.addCommand(new Command("announcement-category").description("Announcement category codes").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
225
|
-
const client =
|
|
232
|
+
const client = await createClient();
|
|
226
233
|
await printData(await client.call("lookup.announcement-categories.list"), parseFormat(options.format));
|
|
227
234
|
})))
|
|
228
235
|
.addCommand(new Command("industry-code").description("Shenwan industry codes for security-clue --gts-code").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
229
|
-
const client =
|
|
236
|
+
const client = await createClient();
|
|
230
237
|
await printData(await client.call("lookup.industry-codes.list"), parseFormat(options.format));
|
|
238
|
+
})))
|
|
239
|
+
.addCommand(new Command("theme-id").description("Theme IDs for theme-tracking --theme-id").addCommand(new Command("list").option("--format <format>", "Output format", "table").action(async (options) => {
|
|
240
|
+
const client = await createClient();
|
|
241
|
+
await printData(await client.call("lookup.theme-ids.list"), parseFormat(options.format));
|
|
231
242
|
})));
|
|
232
243
|
program.addCommand(lookup);
|
|
233
244
|
const insight = new Command("insight").description("Insight APIs");
|
|
@@ -241,7 +252,7 @@ const research = new Command("research");
|
|
|
241
252
|
const foreignReport = new Command("foreign-report");
|
|
242
253
|
const announcement = new Command("announcement");
|
|
243
254
|
addTimeFilters(opinion.command("list").option("--rank-type <number>", "Rank type", "1").option("--research-area <id>", "Research area ID", collectList, []).option("--chief <id>", "Chief ID", collectList, []).option("--security <code>", "Security code", collectList, []).option("--broker <id>", "Broker ID", collectList, []).option("--industry <id>", "Industry ID", collectList, []).option("--concept <id>", "Concept ID", collectList, []).option("--llm-tag <tag>", "Semantic tag", collectList, []).option("--source <source>", "Source", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
244
|
-
const client =
|
|
255
|
+
const client = await createClient();
|
|
245
256
|
await printData(await client.call("insight.opinion.list", {
|
|
246
257
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime,
|
|
247
258
|
rankType: Number(options.rankType), keyword: options.keyword, researchAreaList: maybeArray(options.researchArea), chiefList: maybeArray(options.chief),
|
|
@@ -250,7 +261,7 @@ addTimeFilters(opinion.command("list").option("--rank-type <number>", "Rank type
|
|
|
250
261
|
}), parseFormat(options.format), options.output);
|
|
251
262
|
});
|
|
252
263
|
addTimeFilters(summary.command("list").option("--search-type <number>", "Search type", "1").option("--rank-type <number>", "Rank type", "1").option("--source <number>", "Source type", collectNumberList, []).option("--research-area <id>", "Research area", collectList, []).option("--security <code>", "Security code", collectList, []).option("--institution <id>", "Institution ID", collectList, []).option("--category <name>", "Category", collectList, []).option("--market <name>", "Market", collectList, []).option("--participant-role <name>", "Participant role", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
253
|
-
const client =
|
|
264
|
+
const client = await createClient();
|
|
254
265
|
await printData(await client.call("insight.summary.list", {
|
|
255
266
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime,
|
|
256
267
|
searchType: Number(options.searchType), rankType: Number(options.rankType), keyword: options.keyword, sourceList: options.source.length ? options.source : undefined,
|
|
@@ -259,13 +270,13 @@ addTimeFilters(summary.command("list").option("--search-type <number>", "Search
|
|
|
259
270
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.summary.list", idField: "summaryId" });
|
|
260
271
|
});
|
|
261
272
|
summary.command("download").requiredOption("--summary-id <id>").option("--output <path>").action(async (options) => {
|
|
262
|
-
const client =
|
|
273
|
+
const client = await createClient();
|
|
263
274
|
const result = await client.call("insight.summary.download", undefined, { summaryId: options.summaryId });
|
|
264
275
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.summary.list", "summaryId", options.summaryId);
|
|
265
276
|
await saveDownloadResult(result, `summary-${options.summaryId}`, options.output ?? title);
|
|
266
277
|
});
|
|
267
278
|
const addScheduleList = (command, endpointKey) => addTimeFilters(command.command("list").option("--research-area <id>", "Research area", collectList, []).option("--institution <id>", "Institution ID", collectList, []).option("--security <code>", "Security code", collectList, []).option("--category <name>", "Category", collectList, []).option("--market <name>", "Market", collectList, []).option("--participant-role <name>", "Participant role", collectList, []).option("--broker-type <name>", "Broker type", collectList, []).option("--object <type>", "Object type: company/industry", collectList, []).option("--permission <number>", "Permission", collectNumberList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
268
|
-
const client =
|
|
279
|
+
const client = await createClient();
|
|
269
280
|
await printData(await client.call(endpointKey, {
|
|
270
281
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
271
282
|
researchAreaList: maybeArray(options.researchArea), institutionList: maybeArray(options.institution), securityList: maybeArray(options.security),
|
|
@@ -278,7 +289,7 @@ addScheduleList(siteVisit, "insight.site-visit.list");
|
|
|
278
289
|
addScheduleList(strategy, "insight.strategy.list");
|
|
279
290
|
addScheduleList(forum, "insight.forum.list");
|
|
280
291
|
addTimeFilters(research.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--broker <id>", "Broker ID", collectList, []).option("--security <code>", "Security code", collectList, []).option("--industry <id>", "Industry ID", collectList, []).option("--category <name>", "Report category", collectList, []).option("--llm-tag <tag>", "Semantic tag", collectList, []).option("--rating <name>", "Rating", collectList, []).option("--rating-change <name>", "Rating change", collectList, []).option("--min-pages <number>", "Min report pages").option("--max-pages <number>", "Max report pages").option("--source <type>", "Source type", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
281
|
-
const client =
|
|
292
|
+
const client = await createClient();
|
|
282
293
|
await printData(await client.call("insight.research.list", {
|
|
283
294
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
284
295
|
searchType: Number(options.searchType), rankType: Number(options.rankType),
|
|
@@ -289,13 +300,13 @@ addTimeFilters(research.command("list").option("--search-type <number>", "Search
|
|
|
289
300
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.research.list", idField: "reportId" });
|
|
290
301
|
});
|
|
291
302
|
research.command("download").requiredOption("--report-id <id>").option("--file-type <number>", "File type: 1=PDF 2=Markdown", "1").option("--output <path>").action(async (options) => {
|
|
292
|
-
const client =
|
|
303
|
+
const client = await createClient();
|
|
293
304
|
const result = await client.call("insight.research.download", undefined, { reportId: options.reportId, fileType: Number(options.fileType) });
|
|
294
305
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.research.list", "reportId", options.reportId);
|
|
295
306
|
await saveDownloadResult(result, `research-${options.reportId}`, options.output ?? title);
|
|
296
307
|
});
|
|
297
308
|
addTimeFilters(foreignReport.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--security <code>", "Security code", collectList, []).option("--region <id>", "Region ID", collectList, []).option("--category <name>", "Report category", collectList, []).option("--industry <id>", "Industry ID", collectList, []).option("--broker <id>", "Broker ID", collectList, []).option("--llm-tag <tag>", "Semantic tag", collectList, []).option("--rating <name>", "Rating", collectList, []).option("--rating-change <name>", "Rating change", collectList, []).option("--min-pages <number>", "Min report pages").option("--max-pages <number>", "Max report pages").option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
298
|
-
const client =
|
|
309
|
+
const client = await createClient();
|
|
299
310
|
await printData(await client.call("insight.foreign-report.list", {
|
|
300
311
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
301
312
|
searchType: Number(options.searchType), rankType: Number(options.rankType),
|
|
@@ -306,13 +317,13 @@ addTimeFilters(foreignReport.command("list").option("--search-type <number>", "S
|
|
|
306
317
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.foreign-report.list", idField: "reportId" });
|
|
307
318
|
});
|
|
308
319
|
foreignReport.command("download").requiredOption("--report-id <id>").option("--file-type <number>", "File type: 1=PDF 2=Markdown 3=CN-PDF 4=CN-Markdown", "1").option("--output <path>").action(async (options) => {
|
|
309
|
-
const client =
|
|
320
|
+
const client = await createClient();
|
|
310
321
|
const result = await client.call("insight.foreign-report.download", undefined, { reportId: options.reportId, fileType: Number(options.fileType) });
|
|
311
322
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.foreign-report.list", "reportId", options.reportId);
|
|
312
323
|
await saveDownloadResult(result, `foreign-report-${options.reportId}`, options.output ?? title);
|
|
313
324
|
});
|
|
314
325
|
addTimeFilters(announcement.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--security <code>", "Security code", collectList, []).option("--announcement-type <type>", "Announcement type", collectList, []).option("--category <id>", "Category ID", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action(async (options) => {
|
|
315
|
-
const client =
|
|
326
|
+
const client = await createClient();
|
|
316
327
|
await printData(await client.call("insight.announcement.list", {
|
|
317
328
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size),
|
|
318
329
|
startTime: toTimestamp13(options.startTime), endTime: toTimestamp13(options.endTime),
|
|
@@ -321,7 +332,7 @@ addTimeFilters(announcement.command("list").option("--search-type <number>", "Se
|
|
|
321
332
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.announcement.list", idField: "announcementId" });
|
|
322
333
|
});
|
|
323
334
|
announcement.command("download").requiredOption("--announcement-id <id>").option("--file-type <number>", "File type: 1=PDF 2=Markdown", "1").option("--output <path>").action(async (options) => {
|
|
324
|
-
const client =
|
|
335
|
+
const client = await createClient();
|
|
325
336
|
const result = await client.call("insight.announcement.download", undefined, { announcementId: options.announcementId, fileType: Number(options.fileType) });
|
|
326
337
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.announcement.list", "announcementId", options.announcementId);
|
|
327
338
|
await saveDownloadResult(result, `announcement-${options.announcementId}`, options.output ?? title);
|
|
@@ -337,63 +348,140 @@ insight.addCommand(foreignReport);
|
|
|
337
348
|
insight.addCommand(announcement);
|
|
338
349
|
program.addCommand(insight);
|
|
339
350
|
const quote = new Command("quote").description("Quote APIs");
|
|
340
|
-
quote.command("day-kline").option("--security <code>", "Security code", collectList, []).option("--start-date <date>").option("--end-date <date>").option("--limit <number>").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
341
|
-
const client =
|
|
351
|
+
quote.command("day-kline").option("--security <code>", "Security code (A-share only: .SH/.SZ/.BJ)", collectList, []).option("--start-date <date>", "Start date (default: 1 year before end-date)").option("--end-date <date>", "End date (default: latest)").option("--limit <number>", "Max rows per request (default: 5000, max: 10000)").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
352
|
+
const client = await createClient();
|
|
342
353
|
await printData(await client.call("quote.day-kline", { securityList: maybeArray(options.security), startDate: options.startDate, endDate: options.endDate, limit: options.limit ? Number(options.limit) : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
343
354
|
});
|
|
355
|
+
quote.command("day-kline-hk").option("--security <code>", "Security code (HK stock only: .HK)", collectList, []).option("--start-date <date>", "Start date (default: 1 year before end-date)").option("--end-date <date>", "End date (default: latest)").option("--limit <number>", "Max rows per request (default: 5000, max: 10000)").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
356
|
+
const client = await createClient();
|
|
357
|
+
await printData(await client.call("quote.day-kline-hk", { securityList: maybeArray(options.security), startDate: options.startDate, endDate: options.endDate, limit: options.limit ? Number(options.limit) : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
358
|
+
});
|
|
344
359
|
program.addCommand(quote);
|
|
345
360
|
const fundamental = new Command("fundamental").description("Fundamental APIs");
|
|
346
361
|
fundamental.command("income-statement").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period", collectList, []).option("--report-type <type>", "Report type", collectList, []).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
347
|
-
const client =
|
|
348
|
-
await printData(await client.call("fundamental.income-statement", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, fiscalYear: maybeArray(options.fiscalYear), period: options.period.length ? options.period :
|
|
362
|
+
const client = await createClient();
|
|
363
|
+
await printData(await client.call("fundamental.income-statement", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, fiscalYear: maybeArray(options.fiscalYear), period: options.period.length ? options.period : undefined, reportType: options.reportType.length ? options.reportType : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
364
|
+
});
|
|
365
|
+
fundamental.command("balance-sheet").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period", collectList, []).option("--report-type <type>", "Report type", collectList, []).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
366
|
+
const client = await createClient();
|
|
367
|
+
await printData(await client.call("fundamental.balance-sheet", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, fiscalYear: maybeArray(options.fiscalYear), period: options.period.length ? options.period : undefined, reportType: options.reportType.length ? options.reportType : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
368
|
+
});
|
|
369
|
+
fundamental.command("cash-flow").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period", collectList, []).option("--report-type <type>", "Report type", collectList, []).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
370
|
+
const client = await createClient();
|
|
371
|
+
await printData(await client.call("fundamental.cash-flow", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, fiscalYear: maybeArray(options.fiscalYear), period: options.period.length ? options.period : undefined, reportType: options.reportType.length ? options.reportType : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
349
372
|
});
|
|
350
373
|
fundamental.command("main-business").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).addOption(new Option("--breakdown <type>", "Breakdown: product/industry/region").choices(["product", "industry", "region"]).default("product")).addOption(new Option("--period <type>", "Period: interim/annual").choices(["interim", "annual"])).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
351
|
-
const client =
|
|
374
|
+
const client = await createClient();
|
|
352
375
|
await printData(await client.call("fundamental.main-business", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, fiscalYear: maybeArray(options.fiscalYear), breakdown: options.breakdown, period: options.period, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
353
376
|
});
|
|
354
377
|
fundamental.command("valuation-analysis").requiredOption("--security-code <code>").addOption(new Option("--indicator <name>", "Indicator").choices(["peTtm", "pbMrq", "peg", "psTtm", "pcfTtm", "em"]).makeOptionMandatory()).option("--start-date <date>").option("--end-date <date>").option("--limit <number>").option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
355
|
-
const client =
|
|
378
|
+
const client = await createClient();
|
|
356
379
|
await printData(await client.call("fundamental.valuation-analysis", { securityCode: options.securityCode, indicator: options.indicator, startDate: options.startDate, endDate: options.endDate, limit: options.limit ? Number(options.limit) : undefined, fieldList: maybeArray(options.field) }), parseFormat(options.format), options.output);
|
|
357
380
|
});
|
|
358
381
|
program.addCommand(fundamental);
|
|
359
382
|
const ai = new Command("ai").description("AI APIs");
|
|
360
383
|
ai.command("knowledge-batch").requiredOption("--query <text>", "Query", collectList, []).option("--top <number>", "Top", "10").option("--resource-type <number>", "Resource type", collectNumberList, []).option("--knowledge-name <name>", "Knowledge name", collectList, []).option("--start-time <ms>").option("--end-time <ms>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
361
|
-
const client =
|
|
384
|
+
const client = await createClient();
|
|
362
385
|
await printData(await client.call("ai.knowledge-batch", { queries: options.query, top: Number(options.top), resourceTypes: options.resourceType.length ? options.resourceType : undefined, knowledgeNames: maybeArray(options.knowledgeName), startTime: options.startTime ? Number(options.startTime) : undefined, endTime: options.endTime ? Number(options.endTime) : undefined }), parseFormat(options.format), options.output);
|
|
363
386
|
});
|
|
364
387
|
ai.command("knowledge-resource-download").requiredOption("--resource-type <number>").requiredOption("--source-id <id>").option("--output <path>").action(async (options) => {
|
|
365
|
-
const client =
|
|
388
|
+
const client = await createClient();
|
|
366
389
|
await saveDownloadResult(await client.call("ai.knowledge-resource.download", undefined, { resourceType: Number(options.resourceType), sourceId: options.sourceId }), `resource-${options.sourceId}`, options.output);
|
|
367
390
|
});
|
|
368
391
|
ai.command("security-clue").option("--from <number>", "Starting offset", "0").option("--size <number>", "Total rows to return; omit to fetch all").requiredOption("--start-time <datetime>").requiredOption("--end-time <datetime>").addOption(new Option("--query-mode <mode>").choices(["bySecurity", "byIndustry"]).makeOptionMandatory()).option("--gts-code <code>", "GTS code", collectList, []).option("--source <name>", "Source", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
369
|
-
const client =
|
|
392
|
+
const client = await createClient();
|
|
370
393
|
await printData(await client.call("ai.security-clue.list", { from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, queryMode: options.queryMode, gtsCodeList: maybeArray(options.gtsCode), source: maybeArray(options.source) }), parseFormat(options.format), options.output);
|
|
371
394
|
});
|
|
372
395
|
ai.command("one-pager").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
373
|
-
const client =
|
|
396
|
+
const client = await createClient();
|
|
374
397
|
await printData(await client.call("ai.one-pager", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
375
398
|
});
|
|
376
399
|
ai.command("investment-logic").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
377
|
-
const client =
|
|
400
|
+
const client = await createClient();
|
|
378
401
|
await printData(await client.call("ai.investment-logic", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
379
402
|
});
|
|
380
403
|
ai.command("peer-comparison").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
381
|
-
const client =
|
|
404
|
+
const client = await createClient();
|
|
382
405
|
await printData(await client.call("ai.peer-comparison", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
383
406
|
});
|
|
384
|
-
ai.command("
|
|
385
|
-
const client =
|
|
386
|
-
|
|
407
|
+
ai.command("earnings-review").requiredOption("--security-code <code>").requiredOption("--period <period>", "Report period (e.g. 2025q3, 2025interim, 2025annual)").option("--wait", "Wait for content generation (blocking, up to 3 min)").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
408
|
+
const client = await createClient();
|
|
409
|
+
// Step 1: get dataId
|
|
410
|
+
const idResult = await client.call("ai.earnings-review.get-id", { securityCode: options.securityCode, period: options.period });
|
|
411
|
+
const dataId = idResult?.dataId;
|
|
412
|
+
if (!dataId) {
|
|
413
|
+
process.stderr.write("Failed to get earnings review ID. The report may not be available yet.\n");
|
|
414
|
+
process.exitCode = 1;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
// Non-blocking: return dataId immediately
|
|
418
|
+
if (!options.wait) {
|
|
419
|
+
process.stderr.write(`Earnings review task submitted. dataId: ${dataId}\n`);
|
|
420
|
+
process.stdout.write(`${JSON.stringify({ dataId, status: "pending", hint: `Run 'gangtise ai earnings-review-check --data-id ${dataId}' in ~2 minutes to get results` })}\n`);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
// Blocking (--wait): poll for content
|
|
424
|
+
process.stderr.write(`Got dataId: ${dataId}, waiting for content generation...\n`);
|
|
425
|
+
let attempts = 0;
|
|
426
|
+
const maxAttempts = 12;
|
|
427
|
+
const delayMs = 15_000;
|
|
428
|
+
while (attempts < maxAttempts) {
|
|
429
|
+
attempts++;
|
|
430
|
+
const contentResult = await client.call("ai.earnings-review.get-content", { dataId });
|
|
431
|
+
if (contentResult?.data?.content) {
|
|
432
|
+
await printData(contentResult.data, parseFormat(options.format), options.output);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (attempts < maxAttempts) {
|
|
436
|
+
process.stderr.write(`Attempt ${attempts}/${maxAttempts}: content not ready, retrying in 15s...\n`);
|
|
437
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
process.stderr.write(`Content not available after ${maxAttempts} attempts. Try again later with: gangtise ai earnings-review-check --data-id ${dataId}\n`);
|
|
441
|
+
process.exitCode = 1;
|
|
442
|
+
});
|
|
443
|
+
ai.command("earnings-review-check").requiredOption("--data-id <id>", "dataId from earnings-review").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
444
|
+
const client = await createClient();
|
|
445
|
+
try {
|
|
446
|
+
const contentResult = await client.call("ai.earnings-review.get-content", { dataId: options.dataId });
|
|
447
|
+
if (contentResult?.data?.content) {
|
|
448
|
+
await printData(contentResult.data, parseFormat(options.format), options.output);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
process.stdout.write(`${JSON.stringify({ dataId: options.dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
if (error instanceof ApiError && (error.code === "410110" || error.message?.includes("生成中"))) {
|
|
455
|
+
process.stdout.write(`${JSON.stringify({ dataId: options.dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
throw error;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
ai.command("theme-tracking").requiredOption("--theme-id <id>", "Theme ID (use lookup theme-id list)").requiredOption("--date <date>", "Date (yyyy-MM-dd)").option("--type <name>", "Report type: morning/night", collectList, []).option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
462
|
+
const client = await createClient();
|
|
463
|
+
const typeList = options.type.length ? options.type : undefined;
|
|
464
|
+
await printData(await client.call("ai.theme-tracking", { themeId: options.themeId, date: options.date, type: typeList }), parseFormat(options.format), options.output);
|
|
465
|
+
});
|
|
466
|
+
ai.command("research-outline").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
467
|
+
const client = await createClient();
|
|
468
|
+
await printData(await client.call("ai.research-outline", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
469
|
+
});
|
|
470
|
+
const vault = new Command("vault").description("Vault APIs");
|
|
471
|
+
vault.command("drive-list").option("--from <number>", "Starting offset", "0").option("--size <number>", "Total rows to return; omit to fetch all").option("--start-time <datetime>").option("--end-time <datetime>").option("--keyword <text>").option("--file-type <number>", "File type", collectNumberList, []).option("--space-type <number>", "Space type", collectNumberList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
|
|
472
|
+
const client = await createClient();
|
|
473
|
+
await printData(await client.call("vault.drive.list", { from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword, fileTypeList: options.fileType.length ? options.fileType : undefined, spaceTypeList: options.spaceType.length ? options.spaceType : undefined }), parseFormat(options.format), options.output, { endpointKey: "vault.drive.list", idField: "fileId" });
|
|
387
474
|
});
|
|
388
|
-
|
|
389
|
-
const client =
|
|
390
|
-
const result = await client.call("
|
|
391
|
-
const title = options.output ? undefined : await resolveTitle(client, result, "
|
|
475
|
+
vault.command("drive-download").requiredOption("--file-id <id>").option("--output <path>").action(async (options) => {
|
|
476
|
+
const client = await createClient();
|
|
477
|
+
const result = await client.call("vault.drive.download", undefined, { fileId: options.fileId });
|
|
478
|
+
const title = options.output ? undefined : await resolveTitle(client, result, "vault.drive.list", "fileId", options.fileId);
|
|
392
479
|
await saveDownloadResult(result, `file-${options.fileId}`, options.output ?? title);
|
|
393
480
|
});
|
|
481
|
+
program.addCommand(vault);
|
|
394
482
|
program.addCommand(ai);
|
|
395
483
|
program.command("raw").description("Raw API calls").addCommand(new Command("call").argument("<endpointKey>").option("--body <json>").option("--query <key=value>", "Query string pair", collectKeyValue, {}).option("--format <format>", "Output format", "json").option("--output <path>").action(async (endpointKey, options) => {
|
|
396
|
-
const client =
|
|
484
|
+
const client = await createClient();
|
|
397
485
|
const body = options.body ? JSON.parse(options.body) : undefined;
|
|
398
486
|
const data = await client.call(endpointKey, body, options.query);
|
|
399
487
|
if (data && typeof data === "object" && "data" in data && data.data instanceof Uint8Array) {
|
|
@@ -423,4 +511,3 @@ async function main() {
|
|
|
423
511
|
}
|
|
424
512
|
}
|
|
425
513
|
void main();
|
|
426
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/src/core/args.js
CHANGED
package/dist/src/core/auth.js
CHANGED