gangtise-openapi-cli 0.10.5 → 0.10.7

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/dist/src/cli.js CHANGED
@@ -86,7 +86,7 @@ async function printData(data, format, output, cache) {
86
86
  }
87
87
  if (normalized && typeof normalized === "object" && !Array.isArray(normalized)) {
88
88
  const meta = normalized;
89
- if (typeof meta.total === "number") {
89
+ if (typeof meta.total === "number" && format !== "json") {
90
90
  const listLen = Array.isArray(meta.list) ? meta.list.length : 0;
91
91
  process.stderr.write(`Total: ${meta.total}, showing: ${listLen}\n`);
92
92
  }
@@ -193,19 +193,25 @@ async function saveDownloadResult(result, fallbackName, output) {
193
193
  }
194
194
  const POLL_MAX_ATTEMPTS = 12;
195
195
  const POLL_DELAY_MS = 15_000;
196
+ function isAsyncPending(error) {
197
+ return error instanceof ApiError && error.code === "410110";
198
+ }
196
199
  async function pollAsyncContent(client, getContentEndpoint, dataId, format, output) {
197
200
  for (let attempt = 1; attempt <= POLL_MAX_ATTEMPTS; attempt++) {
198
201
  try {
199
202
  const result = await client.call(getContentEndpoint, { dataId });
200
- if (result?.content) {
203
+ if (result?.content != null) {
201
204
  await printData(result, format, output);
202
205
  return true;
203
206
  }
204
207
  }
205
208
  catch (error) {
206
- if (!(error instanceof ApiError && (error.code === "410110" || error.message?.includes("生成中")))) {
207
- throw error;
209
+ if (error instanceof ApiError && error.code === "410111") {
210
+ process.stderr.write("Content generation failed (terminal). Do not retry.\n");
211
+ return false;
208
212
  }
213
+ if (!isAsyncPending(error))
214
+ throw error;
209
215
  }
210
216
  if (attempt < POLL_MAX_ATTEMPTS) {
211
217
  process.stderr.write(`Attempt ${attempt}/${POLL_MAX_ATTEMPTS}: content not ready, retrying in 15s...\n`);
@@ -214,22 +220,24 @@ async function pollAsyncContent(client, getContentEndpoint, dataId, format, outp
214
220
  }
215
221
  return false;
216
222
  }
217
- function checkAsyncContent(client, getContentEndpoint, dataId, format, output) {
218
- return (async () => {
219
- try {
220
- const result = await client.call(getContentEndpoint, { dataId });
221
- if (result?.content) {
222
- await printData(result, format, output);
223
- return;
224
- }
223
+ async function checkAsyncContent(client, getContentEndpoint, dataId, format, output) {
224
+ try {
225
+ const result = await client.call(getContentEndpoint, { dataId });
226
+ if (result?.content != null) {
227
+ await printData(result, format, output);
228
+ return;
225
229
  }
226
- catch (error) {
227
- if (!(error instanceof ApiError && (error.code === "410110" || error.message?.includes("生成中")))) {
228
- throw error;
229
- }
230
+ }
231
+ catch (error) {
232
+ if (error instanceof ApiError && error.code === "410111") {
233
+ process.stderr.write("Content generation failed (terminal). Do not retry.\n");
234
+ process.exitCode = 1;
235
+ return;
230
236
  }
231
- process.stdout.write(`${JSON.stringify({ dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
232
- })();
237
+ if (!isAsyncPending(error))
238
+ throw error;
239
+ }
240
+ process.stdout.write(`${JSON.stringify({ dataId, status: "pending", hint: "Content not ready yet, retry in ~2 minutes" })}\n`);
233
241
  }
234
242
  function addTimeFilters(command) {
235
243
  return command
@@ -438,9 +446,25 @@ fundamental.command("main-business").requiredOption("--security-code <code>").op
438
446
  const client = await createClient();
439
447
  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) }), parseFormat(options.format), options.output);
440
448
  });
441
- 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) => {
442
- const client = await createClient();
443
- 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);
449
+ 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("--skip-null", "Drop rows where value or percentileRank is null").option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
450
+ const client = await createClient();
451
+ let data = 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) });
452
+ if (options.skipNull) {
453
+ const normalized = await normalizeRows(data);
454
+ if (normalized && typeof normalized === "object" && !Array.isArray(normalized)) {
455
+ const rec = normalized;
456
+ if (Array.isArray(rec.list)) {
457
+ const filtered = rec.list.filter((row) => {
458
+ if (!row || typeof row !== "object")
459
+ return false;
460
+ const r = row;
461
+ return r.value != null && r.percentileRank != null;
462
+ });
463
+ data = { ...rec, list: filtered, total: filtered.length };
464
+ }
465
+ }
466
+ }
467
+ await printData(data, parseFormat(options.format), options.output);
444
468
  });
445
469
  fundamental.command("earning-forecast").requiredOption("--security-code <code>").option("--start-date <date>", "Start date (default: 1 year before end-date)").option("--end-date <date>", "End date (default: today)").option("--consensus <name>", "Consensus indicator: netIncome/netIncomeYoy/eps/pe/bps/pb/peg/roe/ps", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>").action(async (options) => {
446
470
  const client = await createClient();
@@ -1,2 +1,2 @@
1
1
  // Auto-generated — DO NOT EDIT
2
- export const CLI_VERSION = "0.10.5";
2
+ export const CLI_VERSION = "0.10.7";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gangtise-openapi-cli",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "CLI for Gangtise OpenAPI",
5
5
  "license": "MIT",
6
6
  "repository": {