gangtise-openapi-cli 0.5.0 → 0.6.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 +39 -17
- package/dist/src/cli.js +145 -96
- package/dist/src/core/args.js +0 -1
- package/dist/src/core/auth.js +0 -1
- package/dist/src/core/client.js +14 -19
- package/dist/src/core/config.js +0 -1
- package/dist/src/core/endpoints.js +58 -3
- 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 -1783
- 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
|
@@ -57,6 +57,8 @@ gangtise lookup research-area list
|
|
|
57
57
|
gangtise lookup broker-org list
|
|
58
58
|
gangtise lookup meeting-org list
|
|
59
59
|
gangtise lookup industry list
|
|
60
|
+
gangtise lookup region list # 外资研报区域
|
|
61
|
+
gangtise lookup announcement-category list # 公告分类
|
|
60
62
|
gangtise lookup industry-code list # 申万行业代码(用于 security-clue --gts-code)
|
|
61
63
|
```
|
|
62
64
|
|
|
@@ -85,10 +87,9 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
|
|
|
85
87
|
- `ai cloud-disk-list`
|
|
86
88
|
|
|
87
89
|
规则:
|
|
88
|
-
- `--
|
|
89
|
-
- `--size
|
|
90
|
-
-
|
|
91
|
-
- 如果传了 `--size`,即使超过接口单次上限,CLI 也会自动翻页,直到累计记录数达到 `size` 或数据取完
|
|
90
|
+
- **有时间范围时**(传了 `--start-time/--end-time` 或 `--start-date/--end-date`):**省略 `--size`**,CLI 自动翻页查全
|
|
91
|
+
- **无时间范围时**(未传时间参数):默认 `--size 200`,防止一次查询数据量过大
|
|
92
|
+
- 如果显式传了 `--size`,则按指定值翻页,直到达到 `size` 或数据取完
|
|
92
93
|
|
|
93
94
|
## 智能文件命名
|
|
94
95
|
|
|
@@ -112,11 +113,14 @@ gangtise auth status
|
|
|
112
113
|
### Insight
|
|
113
114
|
|
|
114
115
|
```bash
|
|
115
|
-
#
|
|
116
|
-
gangtise insight research list --start-time "2026-04-
|
|
116
|
+
# 有时间范围 → 省略 --size,自动查全
|
|
117
|
+
gangtise insight research list --start-time "2026-04-01 00:00:00" --end-time "2026-04-09 23:59:59"
|
|
117
118
|
|
|
118
|
-
#
|
|
119
|
-
gangtise insight research list --
|
|
119
|
+
# 无时间范围 → 默认 --size 200
|
|
120
|
+
gangtise insight research list --industry 104270000 --category company --llm-tag inDepth --rating buy
|
|
121
|
+
|
|
122
|
+
# 多值 List 模式:一次查多家券商 + 多个行业 + 多个评级
|
|
123
|
+
gangtise insight research list --broker C100000027 --broker C100000014 --industry 104340000 --industry 104370000 --rating buy --rating overweight --format json
|
|
120
124
|
|
|
121
125
|
gangtise insight opinion list --keyword AI
|
|
122
126
|
gangtise insight summary list --keyword 算力
|
|
@@ -125,8 +129,12 @@ gangtise insight summary list --keyword 算力
|
|
|
125
129
|
gangtise insight summary download --summary-id 4902586
|
|
126
130
|
# → 超颖电子:2026年4月7日投资者关系活动记录表.txt
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
# 下载 Markdown 版本
|
|
133
|
+
gangtise insight research download --report-id 432092410345574400 --file-type 2
|
|
134
|
+
# 下载外资研报中文翻译版
|
|
135
|
+
gangtise insight foreign-report download --report-id RPT20260401001 --file-type 4
|
|
136
|
+
# 下载公告 Markdown 版本
|
|
137
|
+
gangtise insight announcement download --announcement-id 123456 --file-type 2
|
|
130
138
|
|
|
131
139
|
# 也可手动指定文件名
|
|
132
140
|
gangtise insight research download --report-id 12345 --output ./report.pdf
|
|
@@ -144,7 +152,17 @@ gangtise quote day-kline --security 600519.SH --start-date 2026-03-01 --end-date
|
|
|
144
152
|
|
|
145
153
|
```bash
|
|
146
154
|
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2025 --period q3 --field netProfit
|
|
147
|
-
|
|
155
|
+
# 多年度:同时查2023-2025年报净利润
|
|
156
|
+
gangtise fundamental income-statement --security-code 600519.SH --fiscal-year 2023 --fiscal-year 2024 --fiscal-year 2025 --period annual --field netProfit
|
|
157
|
+
# 最新一期完整利润表
|
|
158
|
+
gangtise fundamental income-statement --security-code 600519.SH --format json
|
|
159
|
+
gangtise fundamental balance-sheet --security-code 600519.SH --fiscal-year 2025 --period q3 --field totalCurrAssets --field totalCurrLiab
|
|
160
|
+
# 最新一期完整资产负债表
|
|
161
|
+
gangtise fundamental balance-sheet --security-code 600519.SH --format json
|
|
162
|
+
gangtise fundamental cash-flow --security-code 600519.SH --fiscal-year 2025 --period q3 --field netOpCashFlows --field netInvCashFlows --field netFinCashFlows
|
|
163
|
+
# 最新一期完整现金流量表
|
|
164
|
+
gangtise fundamental cash-flow --security-code 600519.SH --format json
|
|
165
|
+
gangtise fundamental main-business --security-code 600519.SH --breakdown region
|
|
148
166
|
gangtise fundamental valuation-analysis --security-code 600519.SH --indicator peTtm
|
|
149
167
|
```
|
|
150
168
|
|
|
@@ -152,12 +170,16 @@ gangtise fundamental valuation-analysis --security-code 600519.SH --indicator pe
|
|
|
152
170
|
|
|
153
171
|
```bash
|
|
154
172
|
gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
|
|
155
|
-
|
|
156
|
-
gangtise ai
|
|
173
|
+
# 多 resource-type:同时搜索券商研报和外资研报
|
|
174
|
+
gangtise ai knowledge-batch --query 新能源汽车 --resource-type 10 --resource-type 11 --top 10
|
|
175
|
+
gangtise ai security-clue --start-time "2026-04-01 00:00:00" --end-time "2026-04-09 23:59:59" --query-mode byIndustry --gts-code 821035.SWI --source researchReport --source announcement
|
|
157
176
|
gangtise ai one-pager --security-code 600519.SH
|
|
158
177
|
gangtise ai investment-logic --security-code 600519.SH
|
|
159
178
|
gangtise ai peer-comparison --security-code 600519.SH
|
|
160
|
-
gangtise ai
|
|
179
|
+
gangtise ai earnings-review --security-code 600519.SH --period 2025q3
|
|
180
|
+
gangtise ai theme-tracking --theme-id 121000131 --date 2026-03-01 --type morning
|
|
181
|
+
gangtise ai research-outline --security-code 600519.SH
|
|
182
|
+
gangtise ai cloud-disk-list --keyword 部门文档 --space-type 1 --file-type 1
|
|
161
183
|
|
|
162
184
|
# 云盘下载:自动使用文件标题命名
|
|
163
185
|
gangtise ai cloud-disk-download --file-id 62130
|
|
@@ -178,12 +200,12 @@ gangtise raw call insight.opinion.list --body '{"from":0,"size":120}'
|
|
|
178
200
|
## 已验证的真实联调
|
|
179
201
|
|
|
180
202
|
已真实跑通:
|
|
181
|
-
- auth: `login`
|
|
182
|
-
- lookup: `research-area list` / `broker-org list` / `meeting-org list` / `industry list` / `industry-code list`
|
|
203
|
+
- auth: `login` / `status`
|
|
204
|
+
- lookup: `research-area list` / `broker-org list` / `meeting-org list` / `industry list` / `industry-code list` / `region list` / `announcement-category list`
|
|
183
205
|
- 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`
|
|
184
206
|
- quote: `day-kline`
|
|
185
207
|
- fundamental: `income-statement` / `main-business` / `valuation-analysis`
|
|
186
|
-
- ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `cloud-disk-list` / `cloud-disk-download` / `one-pager` / `investment-logic` / `peer-comparison`
|
|
208
|
+
- ai: `knowledge-batch` / `knowledge-resource-download` / `security-clue` / `cloud-disk-list` / `cloud-disk-download` / `one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `theme-tracking` / `research-outline`
|
|
187
209
|
|
|
188
210
|
注意:`knowledge-resource-download` 依赖正确的 `resourceType + sourceId` 组合;错误组合会返回 `433007 不支持该数据源`。
|
|
189
211
|
|
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,64 +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
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
{ name: "申万汽车", code: "821036.SWI" },
|
|
236
|
-
{ name: "申万家用电器", code: "821037.SWI" },
|
|
237
|
-
{ name: "申万食品饮料", code: "821038.SWI" },
|
|
238
|
-
{ name: "申万纺织服饰", code: "821039.SWI" },
|
|
239
|
-
{ name: "申万轻工制造", code: "821040.SWI" },
|
|
240
|
-
{ name: "申万医药生物", code: "821041.SWI" },
|
|
241
|
-
{ name: "申万公用事业", code: "821042.SWI" },
|
|
242
|
-
{ name: "申万交通运输", code: "821043.SWI" },
|
|
243
|
-
{ name: "申万房地产", code: "821044.SWI" },
|
|
244
|
-
{ name: "申万商贸零售", code: "821045.SWI" },
|
|
245
|
-
{ name: "申万社会服务", code: "821046.SWI" },
|
|
246
|
-
{ name: "申万银行", code: "821047.SWI" },
|
|
247
|
-
{ name: "申万非银金融", code: "821048.SWI" },
|
|
248
|
-
{ name: "申万综合", code: "821049.SWI" },
|
|
249
|
-
{ name: "申万建筑材料", code: "821050.SWI" },
|
|
250
|
-
{ name: "申万建筑装饰", code: "821051.SWI" },
|
|
251
|
-
{ name: "申万电力设备", code: "821052.SWI" },
|
|
252
|
-
{ name: "申万机械设备", code: "821053.SWI" },
|
|
253
|
-
{ name: "申万国防军工", code: "821054.SWI" },
|
|
254
|
-
{ name: "申万计算机", code: "821055.SWI" },
|
|
255
|
-
{ name: "申万传媒", code: "821056.SWI" },
|
|
256
|
-
{ name: "申万通信", code: "821057.SWI" },
|
|
257
|
-
{ name: "申万煤炭", code: "821058.SWI" },
|
|
258
|
-
{ name: "申万石油石化", code: "821059.SWI" },
|
|
259
|
-
{ name: "申万环保", code: "821060.SWI" },
|
|
260
|
-
{ name: "申万美容护理", code: "821061.SWI" },
|
|
261
|
-
];
|
|
262
|
-
await printData(data, parseFormat(options.format));
|
|
236
|
+
const client = await createClient();
|
|
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));
|
|
263
242
|
})));
|
|
264
243
|
program.addCommand(lookup);
|
|
265
244
|
const insight = new Command("insight").description("Insight APIs");
|
|
@@ -273,7 +252,7 @@ const research = new Command("research");
|
|
|
273
252
|
const foreignReport = new Command("foreign-report");
|
|
274
253
|
const announcement = new Command("announcement");
|
|
275
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) => {
|
|
276
|
-
const client =
|
|
255
|
+
const client = await createClient();
|
|
277
256
|
await printData(await client.call("insight.opinion.list", {
|
|
278
257
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime,
|
|
279
258
|
rankType: Number(options.rankType), keyword: options.keyword, researchAreaList: maybeArray(options.researchArea), chiefList: maybeArray(options.chief),
|
|
@@ -282,7 +261,7 @@ addTimeFilters(opinion.command("list").option("--rank-type <number>", "Rank type
|
|
|
282
261
|
}), parseFormat(options.format), options.output);
|
|
283
262
|
});
|
|
284
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) => {
|
|
285
|
-
const client =
|
|
264
|
+
const client = await createClient();
|
|
286
265
|
await printData(await client.call("insight.summary.list", {
|
|
287
266
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime,
|
|
288
267
|
searchType: Number(options.searchType), rankType: Number(options.rankType), keyword: options.keyword, sourceList: options.source.length ? options.source : undefined,
|
|
@@ -291,13 +270,13 @@ addTimeFilters(summary.command("list").option("--search-type <number>", "Search
|
|
|
291
270
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.summary.list", idField: "summaryId" });
|
|
292
271
|
});
|
|
293
272
|
summary.command("download").requiredOption("--summary-id <id>").option("--output <path>").action(async (options) => {
|
|
294
|
-
const client =
|
|
273
|
+
const client = await createClient();
|
|
295
274
|
const result = await client.call("insight.summary.download", undefined, { summaryId: options.summaryId });
|
|
296
275
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.summary.list", "summaryId", options.summaryId);
|
|
297
276
|
await saveDownloadResult(result, `summary-${options.summaryId}`, options.output ?? title);
|
|
298
277
|
});
|
|
299
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) => {
|
|
300
|
-
const client =
|
|
279
|
+
const client = await createClient();
|
|
301
280
|
await printData(await client.call(endpointKey, {
|
|
302
281
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
303
282
|
researchAreaList: maybeArray(options.researchArea), institutionList: maybeArray(options.institution), securityList: maybeArray(options.security),
|
|
@@ -310,7 +289,7 @@ addScheduleList(siteVisit, "insight.site-visit.list");
|
|
|
310
289
|
addScheduleList(strategy, "insight.strategy.list");
|
|
311
290
|
addScheduleList(forum, "insight.forum.list");
|
|
312
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) => {
|
|
313
|
-
const client =
|
|
292
|
+
const client = await createClient();
|
|
314
293
|
await printData(await client.call("insight.research.list", {
|
|
315
294
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
316
295
|
searchType: Number(options.searchType), rankType: Number(options.rankType),
|
|
@@ -321,13 +300,13 @@ addTimeFilters(research.command("list").option("--search-type <number>", "Search
|
|
|
321
300
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.research.list", idField: "reportId" });
|
|
322
301
|
});
|
|
323
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) => {
|
|
324
|
-
const client =
|
|
303
|
+
const client = await createClient();
|
|
325
304
|
const result = await client.call("insight.research.download", undefined, { reportId: options.reportId, fileType: Number(options.fileType) });
|
|
326
305
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.research.list", "reportId", options.reportId);
|
|
327
306
|
await saveDownloadResult(result, `research-${options.reportId}`, options.output ?? title);
|
|
328
307
|
});
|
|
329
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) => {
|
|
330
|
-
const client =
|
|
309
|
+
const client = await createClient();
|
|
331
310
|
await printData(await client.call("insight.foreign-report.list", {
|
|
332
311
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
333
312
|
searchType: Number(options.searchType), rankType: Number(options.rankType),
|
|
@@ -338,13 +317,13 @@ addTimeFilters(foreignReport.command("list").option("--search-type <number>", "S
|
|
|
338
317
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.foreign-report.list", idField: "reportId" });
|
|
339
318
|
});
|
|
340
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) => {
|
|
341
|
-
const client =
|
|
320
|
+
const client = await createClient();
|
|
342
321
|
const result = await client.call("insight.foreign-report.download", undefined, { reportId: options.reportId, fileType: Number(options.fileType) });
|
|
343
322
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.foreign-report.list", "reportId", options.reportId);
|
|
344
323
|
await saveDownloadResult(result, `foreign-report-${options.reportId}`, options.output ?? title);
|
|
345
324
|
});
|
|
346
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) => {
|
|
347
|
-
const client =
|
|
326
|
+
const client = await createClient();
|
|
348
327
|
await printData(await client.call("insight.announcement.list", {
|
|
349
328
|
from: Number(options.from), size: options.size === undefined ? undefined : Number(options.size),
|
|
350
329
|
startTime: toTimestamp13(options.startTime), endTime: toTimestamp13(options.endTime),
|
|
@@ -353,7 +332,7 @@ addTimeFilters(announcement.command("list").option("--search-type <number>", "Se
|
|
|
353
332
|
}), parseFormat(options.format), options.output, { endpointKey: "insight.announcement.list", idField: "announcementId" });
|
|
354
333
|
});
|
|
355
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) => {
|
|
356
|
-
const client =
|
|
335
|
+
const client = await createClient();
|
|
357
336
|
const result = await client.call("insight.announcement.download", undefined, { announcementId: options.announcementId, fileType: Number(options.fileType) });
|
|
358
337
|
const title = options.output ? undefined : await resolveTitle(client, result, "insight.announcement.list", "announcementId", options.announcementId);
|
|
359
338
|
await saveDownloadResult(result, `announcement-${options.announcementId}`, options.output ?? title);
|
|
@@ -370,62 +349,133 @@ insight.addCommand(announcement);
|
|
|
370
349
|
program.addCommand(insight);
|
|
371
350
|
const quote = new Command("quote").description("Quote APIs");
|
|
372
351
|
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) => {
|
|
373
|
-
const client =
|
|
352
|
+
const client = await createClient();
|
|
374
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);
|
|
375
354
|
});
|
|
376
355
|
program.addCommand(quote);
|
|
377
356
|
const fundamental = new Command("fundamental").description("Fundamental APIs");
|
|
378
357
|
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) => {
|
|
379
|
-
const client =
|
|
380
|
-
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 :
|
|
358
|
+
const client = await createClient();
|
|
359
|
+
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);
|
|
360
|
+
});
|
|
361
|
+
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) => {
|
|
362
|
+
const client = await createClient();
|
|
363
|
+
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);
|
|
364
|
+
});
|
|
365
|
+
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) => {
|
|
366
|
+
const client = await createClient();
|
|
367
|
+
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);
|
|
381
368
|
});
|
|
382
369
|
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) => {
|
|
383
|
-
const client =
|
|
370
|
+
const client = await createClient();
|
|
384
371
|
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);
|
|
385
372
|
});
|
|
386
373
|
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) => {
|
|
387
|
-
const client =
|
|
374
|
+
const client = await createClient();
|
|
388
375
|
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);
|
|
389
376
|
});
|
|
390
377
|
program.addCommand(fundamental);
|
|
391
378
|
const ai = new Command("ai").description("AI APIs");
|
|
392
379
|
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) => {
|
|
393
|
-
const client =
|
|
380
|
+
const client = await createClient();
|
|
394
381
|
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);
|
|
395
382
|
});
|
|
396
383
|
ai.command("knowledge-resource-download").requiredOption("--resource-type <number>").requiredOption("--source-id <id>").option("--output <path>").action(async (options) => {
|
|
397
|
-
const client =
|
|
384
|
+
const client = await createClient();
|
|
398
385
|
await saveDownloadResult(await client.call("ai.knowledge-resource.download", undefined, { resourceType: Number(options.resourceType), sourceId: options.sourceId }), `resource-${options.sourceId}`, options.output);
|
|
399
386
|
});
|
|
400
387
|
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) => {
|
|
401
|
-
const client =
|
|
388
|
+
const client = await createClient();
|
|
402
389
|
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);
|
|
403
390
|
});
|
|
404
391
|
ai.command("one-pager").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
405
|
-
const client =
|
|
392
|
+
const client = await createClient();
|
|
406
393
|
await printData(await client.call("ai.one-pager", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
407
394
|
});
|
|
408
395
|
ai.command("investment-logic").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
409
|
-
const client =
|
|
396
|
+
const client = await createClient();
|
|
410
397
|
await printData(await client.call("ai.investment-logic", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
411
398
|
});
|
|
412
399
|
ai.command("peer-comparison").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
413
|
-
const client =
|
|
400
|
+
const client = await createClient();
|
|
414
401
|
await printData(await client.call("ai.peer-comparison", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
415
402
|
});
|
|
403
|
+
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) => {
|
|
404
|
+
const client = await createClient();
|
|
405
|
+
// Step 1: get dataId
|
|
406
|
+
const idResult = await client.call("ai.earnings-review.get-id", { securityCode: options.securityCode, period: options.period });
|
|
407
|
+
const dataId = idResult?.dataId;
|
|
408
|
+
if (!dataId) {
|
|
409
|
+
process.stderr.write("Failed to get earnings review ID. The report may not be available yet.\n");
|
|
410
|
+
process.exitCode = 1;
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
// Non-blocking: return dataId immediately
|
|
414
|
+
if (!options.wait) {
|
|
415
|
+
process.stderr.write(`Earnings review task submitted. dataId: ${dataId}\n`);
|
|
416
|
+
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`);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
// Blocking (--wait): poll for content
|
|
420
|
+
process.stderr.write(`Got dataId: ${dataId}, waiting for content generation...\n`);
|
|
421
|
+
let attempts = 0;
|
|
422
|
+
const maxAttempts = 12;
|
|
423
|
+
const delayMs = 15_000;
|
|
424
|
+
while (attempts < maxAttempts) {
|
|
425
|
+
attempts++;
|
|
426
|
+
const contentResult = await client.call("ai.earnings-review.get-content", { dataId });
|
|
427
|
+
if (contentResult?.data?.content) {
|
|
428
|
+
await printData(contentResult.data, parseFormat(options.format), options.output);
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
if (attempts < maxAttempts) {
|
|
432
|
+
process.stderr.write(`Attempt ${attempts}/${maxAttempts}: content not ready, retrying in 15s...\n`);
|
|
433
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
process.stderr.write(`Content not available after ${maxAttempts} attempts. Try again later with: gangtise ai earnings-review-check --data-id ${dataId}\n`);
|
|
437
|
+
process.exitCode = 1;
|
|
438
|
+
});
|
|
439
|
+
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) => {
|
|
440
|
+
const client = await createClient();
|
|
441
|
+
try {
|
|
442
|
+
const contentResult = await client.call("ai.earnings-review.get-content", { dataId: options.dataId });
|
|
443
|
+
if (contentResult?.data?.content) {
|
|
444
|
+
await printData(contentResult.data, parseFormat(options.format), options.output);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
process.stdout.write(`${JSON.stringify({ dataId: options.dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
if (error instanceof ApiError && (error.code === "410110" || error.message?.includes("生成中"))) {
|
|
451
|
+
process.stdout.write(`${JSON.stringify({ dataId: options.dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
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) => {
|
|
458
|
+
const client = await createClient();
|
|
459
|
+
const typeList = options.type.length ? options.type : undefined;
|
|
460
|
+
await printData(await client.call("ai.theme-tracking", { themeId: options.themeId, date: options.date, type: typeList }), parseFormat(options.format), options.output);
|
|
461
|
+
});
|
|
462
|
+
ai.command("research-outline").requiredOption("--security-code <code>").option("--format <format>", "Output format", "json").option("--output <path>").action(async (options) => {
|
|
463
|
+
const client = await createClient();
|
|
464
|
+
await printData(await client.call("ai.research-outline", { securityCode: options.securityCode }), parseFormat(options.format), options.output);
|
|
465
|
+
});
|
|
416
466
|
ai.command("cloud-disk-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) => {
|
|
417
|
-
const client =
|
|
467
|
+
const client = await createClient();
|
|
418
468
|
await printData(await client.call("ai.cloud-disk.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: "ai.cloud-disk.list", idField: "fileId" });
|
|
419
469
|
});
|
|
420
470
|
ai.command("cloud-disk-download").requiredOption("--file-id <id>").option("--output <path>").action(async (options) => {
|
|
421
|
-
const client =
|
|
471
|
+
const client = await createClient();
|
|
422
472
|
const result = await client.call("ai.cloud-disk.download", undefined, { fileId: options.fileId });
|
|
423
473
|
const title = options.output ? undefined : await resolveTitle(client, result, "ai.cloud-disk.list", "fileId", options.fileId);
|
|
424
474
|
await saveDownloadResult(result, `file-${options.fileId}`, options.output ?? title);
|
|
425
475
|
});
|
|
426
476
|
program.addCommand(ai);
|
|
427
477
|
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) => {
|
|
428
|
-
const client =
|
|
478
|
+
const client = await createClient();
|
|
429
479
|
const body = options.body ? JSON.parse(options.body) : undefined;
|
|
430
480
|
const data = await client.call(endpointKey, body, options.query);
|
|
431
481
|
if (data && typeof data === "object" && "data" in data && data.data instanceof Uint8Array) {
|
|
@@ -455,4 +505,3 @@ async function main() {
|
|
|
455
505
|
}
|
|
456
506
|
}
|
|
457
507
|
void main();
|
|
458
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/src/core/args.js
CHANGED
package/dist/src/core/auth.js
CHANGED