gangtise-openapi-cli 0.11.0 → 0.11.1

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 CHANGED
@@ -255,7 +255,7 @@ gangtise insight roadshow list --institution C100000017
255
255
 
256
256
  ```bash
257
257
  gangtise quote day-kline --security 600519.SH --start-date 2026-03-01 --end-date 2026-03-31
258
- # 不传 --security 默认返回全市场,不传 --start-date 默认往前一年,不传 --end-date 默认最新
258
+ # 查最近/最新 K 线建议显式传 --start-date/--end-date;只传 --limit 会截取查询窗口开头,不等于最近N条
259
259
  gangtise quote day-kline --format json
260
260
  # 全市场查询(--security all)
261
261
  gangtise quote day-kline --security all --start-date 2026-04-01 --end-date 2026-04-01 --limit 100 --format json
package/dist/src/cli.js CHANGED
@@ -6,6 +6,7 @@ import { collectKeyValue, collectList, collectNumberList, maybeArray, parseFrom,
6
6
  import { buildQuoteKlineBody, buildWechatChatroomListBody, buildWechatMessageListBody } from "./core/commandBodies.js";
7
7
  import { loadConfig } from "./core/config.js";
8
8
  import { resolveTitle, saveDownloadResult } from "./core/download.js";
9
+ import { ENDPOINTS } from "./core/endpoints.js";
9
10
  import { ApiError, ConfigError } from "./core/errors.js";
10
11
  import { normalizeRows } from "./core/normalize.js";
11
12
  import { parseOutputFormat } from "./core/output.js";
@@ -202,26 +203,15 @@ quote.command("minute-kline").option("--security <code>", "Security code (A-shar
202
203
  });
203
204
  program.addCommand(quote);
204
205
  const fundamental = new Command("fundamental").description("Fundamental APIs");
205
- 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) => {
206
+ const addFinancialReport = (name, endpointKey, periodHelp = "Period") => fundamental.command(name).requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", periodHelp, 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) => {
206
207
  const client = await createClient();
207
- 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) }), parseOutputFormat(options.format), options.output);
208
- });
209
- fundamental.command("income-statement-quarterly").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period: q1/q2/q3/q4/latest", 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) => {
210
- const client = await createClient();
211
- await printData(await client.call("fundamental.income-statement-quarterly", { 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) }), parseOutputFormat(options.format), options.output);
212
- });
213
- 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) => {
214
- const client = await createClient();
215
- 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) }), parseOutputFormat(options.format), options.output);
216
- });
217
- 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) => {
218
- const client = await createClient();
219
- 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) }), parseOutputFormat(options.format), options.output);
220
- });
221
- fundamental.command("cash-flow-quarterly").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").option("--fiscal-year <year>", "Fiscal year", collectList, []).option("--period <period>", "Period: q1/q2/q3/q4/latest", 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) => {
222
- const client = await createClient();
223
- await printData(await client.call("fundamental.cash-flow-quarterly", { 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) }), parseOutputFormat(options.format), options.output);
208
+ await printData(await client.call(endpointKey, { 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) }), parseOutputFormat(options.format), options.output);
224
209
  });
210
+ addFinancialReport("income-statement", "fundamental.income-statement");
211
+ addFinancialReport("income-statement-quarterly", "fundamental.income-statement-quarterly", "Period: q1/q2/q3/q4/latest");
212
+ addFinancialReport("balance-sheet", "fundamental.balance-sheet");
213
+ addFinancialReport("cash-flow", "fundamental.cash-flow");
214
+ addFinancialReport("cash-flow-quarterly", "fundamental.cash-flow-quarterly", "Period: q1/q2/q3/q4/latest");
225
215
  fundamental.command("main-business").requiredOption("--security-code <code>").option("--start-date <date>").option("--end-date <date>").addOption(new Option("--breakdown <type>", "Breakdown: product/industry/region").choices(["product", "industry", "region"]).default("product")).option("--period <type>", "Period: interim/annual", collectList, []).option("--field <field>", "Field", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
226
216
  const client = await createClient();
227
217
  await printData(await client.call("fundamental.main-business", { securityCode: options.securityCode, startDate: options.startDate, endDate: options.endDate, breakdown: options.breakdown, periodList: maybeArray(options.period), fieldList: maybeArray(options.field) }), parseOutputFormat(options.format), options.output);
@@ -410,6 +400,10 @@ vault.command("wechat-chatroom-list").option("--from <number>", "Starting offset
410
400
  program.addCommand(vault);
411
401
  program.addCommand(ai);
412
402
  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) => {
403
+ const endpoint = ENDPOINTS[endpointKey];
404
+ if (!endpoint) {
405
+ throw new ConfigError(`Unknown endpoint key: ${endpointKey}`);
406
+ }
413
407
  const client = await createClient();
414
408
  let body;
415
409
  if (options.body) {
@@ -421,13 +415,39 @@ program.command("raw").description("Raw API calls").addCommand(new Command("call
421
415
  }
422
416
  }
423
417
  const data = await client.call(endpointKey, body, options.query);
424
- if (data && typeof data === "object" && "data" in data && data.data instanceof Uint8Array) {
418
+ if (endpoint.kind === "download") {
425
419
  await saveDownloadResult(data, "download.bin", options.output);
426
420
  return;
427
421
  }
428
422
  await printData(data, parseOutputFormat(options.format), options.output);
429
423
  }));
424
+ async function checkForUpdate(timeoutMs = 2000) {
425
+ const https = await import("node:https");
426
+ await new Promise((resolve) => {
427
+ const req = https.get("https://registry.npmjs.org/gangtise-openapi-cli/latest", (res) => {
428
+ let body = "";
429
+ res.on("data", (chunk) => { body += chunk; });
430
+ res.on("end", () => {
431
+ try {
432
+ const latest = JSON.parse(body).version;
433
+ if (latest && latest !== CLI_VERSION) {
434
+ process.stderr.write(`Update available: ${CLI_VERSION} → ${latest}\nRun: npm update -g gangtise-openapi-cli\n`);
435
+ }
436
+ }
437
+ catch { /* ignore */ }
438
+ resolve();
439
+ });
440
+ });
441
+ req.on("error", () => resolve());
442
+ req.setTimeout(timeoutMs, () => { req.destroy(); resolve(); });
443
+ });
444
+ }
430
445
  async function main() {
446
+ if (process.argv.includes("--version") || process.argv.includes("-V")) {
447
+ process.stdout.write(`${CLI_VERSION}\n`);
448
+ await checkForUpdate();
449
+ return;
450
+ }
431
451
  try {
432
452
  await program.parseAsync(process.argv);
433
453
  }
@@ -448,23 +468,3 @@ async function main() {
448
468
  }
449
469
  }
450
470
  void main();
451
- // Background update check on --version
452
- if (process.argv.includes("--version") || process.argv.includes("-V")) {
453
- import("node:https").then((https) => {
454
- const req = https.get("https://registry.npmjs.org/gangtise-openapi-cli/latest", (res) => {
455
- let body = "";
456
- res.on("data", (chunk) => { body += chunk; });
457
- res.on("end", () => {
458
- try {
459
- const latest = JSON.parse(body).version;
460
- if (latest && latest !== CLI_VERSION) {
461
- process.stderr.write(`\nUpdate available: ${CLI_VERSION} → ${latest}\nRun: npm update -g gangtise-openapi-cli\n`);
462
- }
463
- }
464
- catch { /* ignore */ }
465
- });
466
- });
467
- req.on("error", () => { });
468
- req.setTimeout(3000, () => { req.destroy(); });
469
- }).catch(() => { });
470
- }
@@ -10,10 +10,7 @@ export async function readTokenCache(filePath) {
10
10
  }
11
11
  return null;
12
12
  }
13
- catch (error) {
14
- if (error.code === "ENOENT") {
15
- return null;
16
- }
13
+ catch {
17
14
  return null;
18
15
  }
19
16
  }
@@ -1,7 +1,7 @@
1
1
  import { request } from "undici";
2
2
  import { isTokenCacheValid, normalizeToken, readTokenCache, requireAccessCredentials, writeTokenCache } from "./auth.js";
3
3
  import { ApiError, ValidationError } from "./errors.js";
4
- import { ENDPOINTS, ENDPOINT_REGISTRY } from "./endpoints.js";
4
+ import { ENDPOINTS } from "./endpoints.js";
5
5
  import { getLookupData } from "./lookupData/index.js";
6
6
  export class GangtiseClient {
7
7
  config;
@@ -24,7 +24,7 @@ export class GangtiseClient {
24
24
  }
25
25
  async doTokenRefresh() {
26
26
  const credentials = requireAccessCredentials(this.config.accessKey, this.config.secretKey);
27
- const envelope = await this.requestJson(ENDPOINTS.authLogin, {
27
+ const envelope = await this.requestJson(ENDPOINTS["auth.login"], {
28
28
  accessKey: credentials.accessKey,
29
29
  secretKey: credentials.secretKey,
30
30
  }, false);
@@ -38,7 +38,12 @@ export class GangtiseClient {
38
38
  return accessToken;
39
39
  }
40
40
  isEnvelope(parsed) {
41
- return Boolean(parsed && typeof parsed === 'object' && 'code' in parsed);
41
+ if (!parsed || typeof parsed !== 'object')
42
+ return false;
43
+ const obj = parsed;
44
+ if (!('code' in obj))
45
+ return false;
46
+ return 'msg' in obj || 'data' in obj || 'success' in obj || 'status' in obj;
42
47
  }
43
48
  throwHttpError(parsed, statusCode) {
44
49
  if (this.isEnvelope(parsed)) {
@@ -251,7 +256,7 @@ export class GangtiseClient {
251
256
  };
252
257
  }
253
258
  async call(endpointKey, body, query) {
254
- const endpoint = ENDPOINT_REGISTRY[endpointKey];
259
+ const endpoint = ENDPOINTS[endpointKey];
255
260
  if (!endpoint) {
256
261
  throw new ApiError(`Unknown endpoint key: ${endpointKey}`);
257
262
  }
@@ -1,68 +1,71 @@
1
1
  export const ENDPOINTS = {
2
- authLogin: {
2
+ // ─── auth ───
3
+ "auth.login": {
3
4
  key: "auth.login",
4
5
  method: "POST",
5
6
  path: "/application/auth/oauth/open/loginV2",
6
7
  kind: "json",
7
8
  description: "Get access token",
8
9
  },
9
- lookupResearchAreas: {
10
+ // ─── lookup (served from local data, not HTTP) ───
11
+ "lookup.research-areas.list": {
10
12
  key: "lookup.research-areas.list",
11
13
  method: "GET",
12
14
  path: "/guide/research-area-local",
13
15
  kind: "json",
14
16
  description: "List research areas from local docs",
15
17
  },
16
- lookupBrokerOrgs: {
18
+ "lookup.broker-orgs.list": {
17
19
  key: "lookup.broker-orgs.list",
18
20
  method: "GET",
19
21
  path: "/guide/broker-orgs-local",
20
22
  kind: "json",
21
23
  description: "List broker orgs from local docs",
22
24
  },
23
- lookupMeetingOrgs: {
25
+ "lookup.meeting-orgs.list": {
24
26
  key: "lookup.meeting-orgs.list",
25
27
  method: "GET",
26
28
  path: "/guide/meeting-orgs-local",
27
29
  kind: "json",
28
30
  description: "List meeting orgs from local docs",
29
31
  },
30
- lookupIndustries: {
32
+ "lookup.industries.list": {
31
33
  key: "lookup.industries.list",
32
34
  method: "GET",
33
35
  path: "/guide/industries-local",
34
36
  kind: "json",
35
37
  description: "List industries from local docs",
36
38
  },
37
- lookupRegions: {
39
+ "lookup.regions.list": {
38
40
  key: "lookup.regions.list",
39
41
  method: "GET",
40
42
  path: "/guide/regions-local",
41
43
  kind: "json",
42
44
  description: "List regions from local docs",
43
45
  },
44
- lookupAnnouncementCategories: {
46
+ "lookup.announcement-categories.list": {
45
47
  key: "lookup.announcement-categories.list",
46
48
  method: "GET",
47
49
  path: "/guide/announcement-categories-local",
48
50
  kind: "json",
49
51
  description: "List announcement categories from local docs",
50
52
  },
51
- lookupIndustryCodes: {
53
+ "lookup.industry-codes.list": {
52
54
  key: "lookup.industry-codes.list",
53
55
  method: "GET",
54
56
  path: "/guide/industry-codes-local",
55
57
  kind: "json",
56
58
  description: "List Shenwan industry codes from local docs",
57
59
  },
58
- lookupThemeIds: {
60
+ "lookup.theme-ids.list": {
59
61
  key: "lookup.theme-ids.list",
60
62
  method: "GET",
61
63
  path: "/guide/theme-ids-local",
62
64
  kind: "json",
63
65
  description: "List theme IDs from local docs",
64
66
  },
65
- insightOpinionList: {
67
+ // ─── insight ───
68
+ "insight.opinion.list": {
66
69
  key: "insight.opinion.list",
67
70
  method: "POST",
68
71
  path: "/application/open-insight/chief-opinion/getList",
@@ -70,7 +73,7 @@ export const ENDPOINTS = {
70
73
  description: "List chief opinions",
71
74
  pagination: { enabled: true, maxPageSize: 50 },
72
75
  },
73
- insightSummaryList: {
76
+ "insight.summary.list": {
74
77
  key: "insight.summary.list",
75
78
  method: "POST",
76
79
  path: "/application/open-insight/summary/v2/getList",
@@ -78,14 +81,14 @@ export const ENDPOINTS = {
78
81
  description: "List summaries",
79
82
  pagination: { enabled: true, maxPageSize: 50 },
80
83
  },
81
- insightSummaryDownload: {
84
+ "insight.summary.download": {
82
85
  key: "insight.summary.download",
83
86
  method: "GET",
84
87
  path: "/application/open-insight/summary/v2/download/file",
85
88
  kind: "download",
86
89
  description: "Download summary file",
87
90
  },
88
- insightRoadshowList: {
91
+ "insight.roadshow.list": {
89
92
  key: "insight.roadshow.list",
90
93
  method: "POST",
91
94
  path: "/application/open-insight/schedule/roadshow/getList",
@@ -93,7 +96,7 @@ export const ENDPOINTS = {
93
96
  description: "List roadshows",
94
97
  pagination: { enabled: true, maxPageSize: 50 },
95
98
  },
96
- insightSiteVisitList: {
99
+ "insight.site-visit.list": {
97
100
  key: "insight.site-visit.list",
98
101
  method: "POST",
99
102
  path: "/application/open-insight/schedule/site-visit/getList",
@@ -101,7 +104,7 @@ export const ENDPOINTS = {
101
104
  description: "List site visits",
102
105
  pagination: { enabled: true, maxPageSize: 50 },
103
106
  },
104
- insightStrategyList: {
107
+ "insight.strategy.list": {
105
108
  key: "insight.strategy.list",
106
109
  method: "POST",
107
110
  path: "/application/open-insight/schedule/strategy-meeting/getList",
@@ -109,7 +112,7 @@ export const ENDPOINTS = {
109
112
  description: "List strategy meetings",
110
113
  pagination: { enabled: true, maxPageSize: 50 },
111
114
  },
112
- insightForumList: {
115
+ "insight.forum.list": {
113
116
  key: "insight.forum.list",
114
117
  method: "POST",
115
118
  path: "/application/open-insight/schedule/forum/getList",
@@ -117,7 +120,7 @@ export const ENDPOINTS = {
117
120
  description: "List forums",
118
121
  pagination: { enabled: true, maxPageSize: 50 },
119
122
  },
120
- insightResearchList: {
123
+ "insight.research.list": {
121
124
  key: "insight.research.list",
122
125
  method: "POST",
123
126
  path: "/application/open-insight/broker-report/getList",
@@ -125,14 +128,14 @@ export const ENDPOINTS = {
125
128
  description: "List broker research reports",
126
129
  pagination: { enabled: true, maxPageSize: 50 },
127
130
  },
128
- insightResearchDownload: {
131
+ "insight.research.download": {
129
132
  key: "insight.research.download",
130
133
  method: "GET",
131
134
  path: "/application/open-insight/broker-report/download/file",
132
135
  kind: "download",
133
136
  description: "Download broker research report",
134
137
  },
135
- insightForeignReportList: {
138
+ "insight.foreign-report.list": {
136
139
  key: "insight.foreign-report.list",
137
140
  method: "POST",
138
141
  path: "/application/open-insight/foreign-report/getList",
@@ -140,14 +143,14 @@ export const ENDPOINTS = {
140
143
  description: "List foreign reports",
141
144
  pagination: { enabled: true, maxPageSize: 50 },
142
145
  },
143
- insightForeignReportDownload: {
146
+ "insight.foreign-report.download": {
144
147
  key: "insight.foreign-report.download",
145
148
  method: "GET",
146
149
  path: "/application/open-insight/foreign-report/download/file",
147
150
  kind: "download",
148
151
  description: "Download foreign report",
149
152
  },
150
- insightAnnouncementList: {
153
+ "insight.announcement.list": {
151
154
  key: "insight.announcement.list",
152
155
  method: "POST",
153
156
  path: "/application/open-insight/announcement/getList",
@@ -155,98 +158,122 @@ export const ENDPOINTS = {
155
158
  description: "List announcements",
156
159
  pagination: { enabled: true, maxPageSize: 50 },
157
160
  },
158
- insightAnnouncementDownload: {
161
+ "insight.announcement.download": {
159
162
  key: "insight.announcement.download",
160
163
  method: "GET",
161
164
  path: "/application/open-insight/announcement/download/file",
162
165
  kind: "download",
163
166
  description: "Download announcement file",
164
167
  },
165
- quoteDayKline: {
168
+ // ─── quote ───
169
+ "quote.day-kline": {
166
170
  key: "quote.day-kline",
167
171
  method: "POST",
168
172
  path: "/application/open-quote/kline/daily",
169
173
  kind: "json",
170
174
  description: "Query A-share daily kline (SH/SZ/BJ)",
171
175
  },
172
- quoteDayKlineHk: {
176
+ "quote.day-kline-hk": {
173
177
  key: "quote.day-kline-hk",
174
178
  method: "POST",
175
179
  path: "/application/open-quote/kline-hk/daily",
176
180
  kind: "json",
177
181
  description: "Query HK stock daily kline (HK)",
178
182
  },
179
- quoteIndexDayKline: {
183
+ "quote.index-day-kline": {
180
184
  key: "quote.index-day-kline",
181
185
  method: "POST",
182
186
  path: "/application/open-quote/index/kline/daily",
183
187
  kind: "json",
184
188
  description: "Query SH/SZ/BJ index daily kline",
185
189
  },
186
- fundamentalIncomeStatement: {
190
+ "quote.minute-kline": {
191
+ key: "quote.minute-kline",
192
+ method: "POST",
193
+ path: "/application/open-quote/kline/minute",
194
+ kind: "json",
195
+ description: "Query A-share minute kline (SH/SZ/BJ)",
196
+ },
197
+ // ─── fundamental ───
198
+ "fundamental.income-statement": {
187
199
  key: "fundamental.income-statement",
188
200
  method: "POST",
189
201
  path: "/application/open-fundamental/financial-report/income-statement/accumulated",
190
202
  kind: "json",
191
203
  description: "Query income statement (accumulated)",
192
204
  },
193
- fundamentalBalanceSheet: {
205
+ "fundamental.income-statement-quarterly": {
206
+ key: "fundamental.income-statement-quarterly",
207
+ method: "POST",
208
+ path: "/application/open-fundamental/financial-report/income-statement/quarterly",
209
+ kind: "json",
210
+ description: "Query income statement (quarterly)",
211
+ },
212
+ "fundamental.balance-sheet": {
194
213
  key: "fundamental.balance-sheet",
195
214
  method: "POST",
196
215
  path: "/application/open-fundamental/financial-report/balance-sheet/accumulated",
197
216
  kind: "json",
198
217
  description: "Query balance sheet (accumulated)",
199
218
  },
200
- fundamentalCashFlow: {
219
+ "fundamental.cash-flow": {
201
220
  key: "fundamental.cash-flow",
202
221
  method: "POST",
203
222
  path: "/application/open-fundamental/financial-report/cash-flow-statement/accumulated",
204
223
  kind: "json",
205
224
  description: "Query cash flow statement (accumulated)",
206
225
  },
207
- fundamentalMainBusiness: {
208
- key: "fundamental.main-business",
226
+ "fundamental.cash-flow-quarterly": {
227
+ key: "fundamental.cash-flow-quarterly",
209
228
  method: "POST",
210
- path: "/application/open-fundamental/main-business",
229
+ path: "/application/open-fundamental/financial-report/cash-flow-statement/quarterly",
211
230
  kind: "json",
212
- description: "Query main business composition",
231
+ description: "Query cash flow statement (quarterly)",
213
232
  },
214
- fundamentalEarningForecast: {
215
- key: "fundamental.earning-forecast",
233
+ "fundamental.main-business": {
234
+ key: "fundamental.main-business",
216
235
  method: "POST",
217
- path: "/application/open-fundamental/earning-forecast",
236
+ path: "/application/open-fundamental/main-business",
218
237
  kind: "json",
219
- description: "Query earning forecast (consensus estimates)",
238
+ description: "Query main business composition",
220
239
  },
221
- fundamentalValuationAnalysis: {
240
+ "fundamental.valuation-analysis": {
222
241
  key: "fundamental.valuation-analysis",
223
242
  method: "POST",
224
243
  path: "/application/open-fundamental/valuation-analysis",
225
244
  kind: "json",
226
245
  description: "Query valuation analysis",
227
246
  },
228
- fundamentalTopHolders: {
247
+ "fundamental.top-holders": {
229
248
  key: "fundamental.top-holders",
230
249
  method: "POST",
231
250
  path: "/application/open-fundamental/capital-structure/top-holders",
232
251
  kind: "json",
233
252
  description: "Query top holders (top10 / top10 float)",
234
253
  },
235
- aiKnowledgeBatch: {
254
+ "fundamental.earning-forecast": {
255
+ key: "fundamental.earning-forecast",
256
+ method: "POST",
257
+ path: "/application/open-fundamental/earning-forecast",
258
+ kind: "json",
259
+ description: "Query earning forecast (consensus estimates)",
260
+ },
261
+ // ─── ai ───
262
+ "ai.knowledge-batch": {
236
263
  key: "ai.knowledge-batch",
237
264
  method: "POST",
238
265
  path: "/application/open-data/ai/search/knowledge/batch",
239
266
  kind: "json",
240
267
  description: "Batch knowledge search",
241
268
  },
242
- aiKnowledgeResource: {
269
+ "ai.knowledge-resource.download": {
243
270
  key: "ai.knowledge-resource.download",
244
271
  method: "GET",
245
272
  path: "/application/open-data/ai/resource/download",
246
273
  kind: "download",
247
274
  description: "Download knowledge resource",
248
275
  },
249
- aiSecurityClue: {
276
+ "ai.security-clue.list": {
250
277
  key: "ai.security-clue.list",
251
278
  method: "POST",
252
279
  path: "/application/open-ai/security-clue/getList",
@@ -254,56 +281,56 @@ export const ENDPOINTS = {
254
281
  description: "List security clues",
255
282
  pagination: { enabled: true, maxPageSize: 500 },
256
283
  },
257
- aiOnePager: {
284
+ "ai.one-pager": {
258
285
  key: "ai.one-pager",
259
286
  method: "POST",
260
287
  path: "/application/open-ai/agent/one-pager",
261
288
  kind: "json",
262
289
  description: "Generate one pager",
263
290
  },
264
- aiInvestmentLogic: {
291
+ "ai.investment-logic": {
265
292
  key: "ai.investment-logic",
266
293
  method: "POST",
267
294
  path: "/application/open-ai/agent/investment-logic",
268
295
  kind: "json",
269
296
  description: "Generate investment logic",
270
297
  },
271
- aiPeerComparison: {
298
+ "ai.peer-comparison": {
272
299
  key: "ai.peer-comparison",
273
300
  method: "POST",
274
301
  path: "/application/open-ai/agent/peer-comparison",
275
302
  kind: "json",
276
303
  description: "Generate peer comparison",
277
304
  },
278
- aiEarningsReviewGetId: {
305
+ "ai.earnings-review.get-id": {
279
306
  key: "ai.earnings-review.get-id",
280
307
  method: "POST",
281
308
  path: "/application/open-ai/agent/earnings-review-getid",
282
309
  kind: "json",
283
310
  description: "Get earnings review ID",
284
311
  },
285
- aiEarningsReviewGetContent: {
312
+ "ai.earnings-review.get-content": {
286
313
  key: "ai.earnings-review.get-content",
287
314
  method: "POST",
288
315
  path: "/application/open-ai/agent/earnings-review-getcontent",
289
316
  kind: "json",
290
317
  description: "Get earnings review content",
291
318
  },
292
- aiThemeTracking: {
319
+ "ai.theme-tracking": {
293
320
  key: "ai.theme-tracking",
294
321
  method: "POST",
295
322
  path: "/application/open-ai/agent/theme-tracking",
296
323
  kind: "json",
297
324
  description: "Get theme tracking daily report",
298
325
  },
299
- aiResearchOutline: {
326
+ "ai.research-outline": {
300
327
  key: "ai.research-outline",
301
328
  method: "POST",
302
329
  path: "/application/open-ai/agent/research-outline",
303
330
  kind: "json",
304
331
  description: "Get company research outline",
305
332
  },
306
- aiHotTopic: {
333
+ "ai.hot-topic": {
307
334
  key: "ai.hot-topic",
308
335
  method: "POST",
309
336
  path: "/application/open-ai/hot-topic/getList",
@@ -311,56 +338,36 @@ export const ENDPOINTS = {
311
338
  description: "List hot topic reports",
312
339
  pagination: { enabled: true, maxPageSize: 20 },
313
340
  },
314
- aiManagementDiscussAnnouncement: {
341
+ "ai.management-discuss-announcement": {
315
342
  key: "ai.management-discuss-announcement",
316
343
  method: "POST",
317
344
  path: "/application/open-ai/management-discuss/from-announcement",
318
345
  kind: "json",
319
346
  description: "Management discussion from financial reports (half-year/annual)",
320
347
  },
321
- aiManagementDiscussEarningsCall: {
348
+ "ai.management-discuss-earnings-call": {
322
349
  key: "ai.management-discuss-earnings-call",
323
350
  method: "POST",
324
351
  path: "/application/open-ai/management-discuss/from-earningsCall",
325
352
  kind: "json",
326
353
  description: "Management discussion from earnings calls",
327
354
  },
328
- aiViewpointDebateGetId: {
355
+ "ai.viewpoint-debate.get-id": {
329
356
  key: "ai.viewpoint-debate.get-id",
330
357
  method: "POST",
331
358
  path: "/application/open-ai/agent/viewpoint-debate-getid",
332
359
  kind: "json",
333
360
  description: "Get viewpoint debate ID",
334
361
  },
335
- aiViewpointDebateGetContent: {
362
+ "ai.viewpoint-debate.get-content": {
336
363
  key: "ai.viewpoint-debate.get-content",
337
364
  method: "POST",
338
365
  path: "/application/open-ai/agent/viewpoint-debate-getcontent",
339
366
  kind: "json",
340
367
  description: "Get viewpoint debate content",
341
368
  },
342
- quoteMinuteKline: {
343
- key: "quote.minute-kline",
344
- method: "POST",
345
- path: "/application/open-quote/kline/minute",
346
- kind: "json",
347
- description: "Query A-share minute kline (SH/SZ/BJ)",
348
- },
349
- fundamentalIncomeStatementQuarterly: {
350
- key: "fundamental.income-statement-quarterly",
351
- method: "POST",
352
- path: "/application/open-fundamental/financial-report/income-statement/quarterly",
353
- kind: "json",
354
- description: "Query income statement (quarterly)",
355
- },
356
- fundamentalCashFlowQuarterly: {
357
- key: "fundamental.cash-flow-quarterly",
358
- method: "POST",
359
- path: "/application/open-fundamental/financial-report/cash-flow-statement/quarterly",
360
- kind: "json",
361
- description: "Query cash flow statement (quarterly)",
362
- },
363
- vaultDriveList: {
369
+ // ─── vault ───
370
+ "vault.drive.list": {
364
371
  key: "vault.drive.list",
365
372
  method: "POST",
366
373
  path: "/application/open-vault/drive/getList",
@@ -368,14 +375,14 @@ export const ENDPOINTS = {
368
375
  description: "List vault drive files",
369
376
  pagination: { enabled: true, maxPageSize: 50 },
370
377
  },
371
- vaultDriveDownload: {
378
+ "vault.drive.download": {
372
379
  key: "vault.drive.download",
373
380
  method: "GET",
374
381
  path: "/application/open-vault/drive/download/file",
375
382
  kind: "download",
376
383
  description: "Download vault drive file",
377
384
  },
378
- vaultRecordList: {
385
+ "vault.record.list": {
379
386
  key: "vault.record.list",
380
387
  method: "POST",
381
388
  path: "/application/open-vault/record/getList",
@@ -383,14 +390,14 @@ export const ENDPOINTS = {
383
390
  description: "List voice recording transcriptions",
384
391
  pagination: { enabled: true, maxPageSize: 50 },
385
392
  },
386
- vaultRecordDownload: {
393
+ "vault.record.download": {
387
394
  key: "vault.record.download",
388
395
  method: "GET",
389
396
  path: "/application/open-vault/record/download/file",
390
397
  kind: "download",
391
398
  description: "Download voice recording transcription file",
392
399
  },
393
- vaultMyConferenceList: {
400
+ "vault.my-conference.list": {
394
401
  key: "vault.my-conference.list",
395
402
  method: "POST",
396
403
  path: "/application/open-vault/my-conference/getList",
@@ -398,14 +405,14 @@ export const ENDPOINTS = {
398
405
  description: "List my conferences",
399
406
  pagination: { enabled: true, maxPageSize: 50 },
400
407
  },
401
- vaultMyConferenceDownload: {
408
+ "vault.my-conference.download": {
402
409
  key: "vault.my-conference.download",
403
410
  method: "GET",
404
411
  path: "/application/open-vault/my-conference/download/file",
405
412
  kind: "download",
406
413
  description: "Download my conference resource",
407
414
  },
408
- vaultWechatMessageList: {
415
+ "vault.wechat-message.list": {
409
416
  key: "vault.wechat-message.list",
410
417
  method: "POST",
411
418
  path: "/application/open-vault/wechatgroupmsg/list",
@@ -413,7 +420,7 @@ export const ENDPOINTS = {
413
420
  description: "List WeChat group messages",
414
421
  pagination: { enabled: true, maxPageSize: 50 },
415
422
  },
416
- vaultWechatChatroomList: {
423
+ "vault.wechat-chatroom.list": {
417
424
  key: "vault.wechat-chatroom.list",
418
425
  method: "POST",
419
426
  path: "/application/open-vault/wechatgroupmsg/chatroomId",
@@ -421,7 +428,3 @@ export const ENDPOINTS = {
421
428
  description: "List WeChat group chatroom IDs",
422
429
  },
423
430
  };
424
- export const ENDPOINT_REGISTRY = Object.values(ENDPOINTS).reduce((accumulator, endpoint) => {
425
- accumulator[endpoint.key] = endpoint;
426
- return accumulator;
427
- }, {});
@@ -1,2 +1,2 @@
1
1
  // Auto-generated — DO NOT EDIT
2
- export const CLI_VERSION = "0.11.0";
2
+ export const CLI_VERSION = "0.11.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gangtise-openapi-cli",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "CLI for Gangtise OpenAPI",
5
5
  "license": "MIT",
6
6
  "repository": {