@invinite-org/invinite-data-cli 0.4.0 → 0.5.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.
Files changed (84) hide show
  1. package/README.md +90 -802
  2. package/claude-plugin/agents/invinite-data.md +1 -1
  3. package/claude-plugin/commands/analyze-earnings-call.md +3 -3
  4. package/claude-plugin/skills/invinite-data-cli/SKILL.md +444 -187
  5. package/dist/src/cli.d.ts +6 -0
  6. package/dist/src/cli.js +21 -31
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/client/api-client.d.ts +2 -4
  9. package/dist/src/client/api-client.js +15 -15
  10. package/dist/src/client/api-client.js.map +1 -1
  11. package/dist/src/client/pagination.d.ts +23 -0
  12. package/dist/src/client/pagination.js +76 -7
  13. package/dist/src/client/pagination.js.map +1 -1
  14. package/dist/src/commands/earnings.d.ts +0 -3
  15. package/dist/src/commands/earnings.js +46 -524
  16. package/dist/src/commands/earnings.js.map +1 -1
  17. package/dist/src/generated/cli-manifest.json +4983 -0
  18. package/dist/src/hand-written-commands.d.ts +43 -0
  19. package/dist/src/hand-written-commands.js +21 -0
  20. package/dist/src/hand-written-commands.js.map +1 -0
  21. package/dist/src/shared/errors.d.ts +12 -1
  22. package/dist/src/shared/errors.js +27 -1
  23. package/dist/src/shared/errors.js.map +1 -1
  24. package/dist/src/shared/options.d.ts +0 -13
  25. package/dist/src/shared/options.js +0 -13
  26. package/dist/src/shared/options.js.map +1 -1
  27. package/dist/src/spec-commands.d.ts +10 -0
  28. package/dist/src/spec-commands.js +224 -0
  29. package/dist/src/spec-commands.js.map +1 -0
  30. package/dist/src/spec-flags.d.ts +6 -0
  31. package/dist/src/spec-flags.js +9 -0
  32. package/dist/src/spec-flags.js.map +1 -0
  33. package/dist/src/spec-manifest.d.ts +382 -0
  34. package/dist/src/spec-manifest.js +65 -0
  35. package/dist/src/spec-manifest.js.map +1 -0
  36. package/package.json +7 -3
  37. package/dist/src/commands/company.d.ts +0 -2
  38. package/dist/src/commands/company.js +0 -220
  39. package/dist/src/commands/company.js.map +0 -1
  40. package/dist/src/commands/earnings-selector.d.ts +0 -15
  41. package/dist/src/commands/earnings-selector.js +0 -29
  42. package/dist/src/commands/earnings-selector.js.map +0 -1
  43. package/dist/src/commands/filings.d.ts +0 -2
  44. package/dist/src/commands/filings.js +0 -139
  45. package/dist/src/commands/filings.js.map +0 -1
  46. package/dist/src/commands/financials.d.ts +0 -2
  47. package/dist/src/commands/financials.js +0 -162
  48. package/dist/src/commands/financials.js.map +0 -1
  49. package/dist/src/commands/health.d.ts +0 -2
  50. package/dist/src/commands/health.js +0 -18
  51. package/dist/src/commands/health.js.map +0 -1
  52. package/dist/src/commands/insider-trades.d.ts +0 -2
  53. package/dist/src/commands/insider-trades.js +0 -56
  54. package/dist/src/commands/insider-trades.js.map +0 -1
  55. package/dist/src/commands/ipos.d.ts +0 -2
  56. package/dist/src/commands/ipos.js +0 -42
  57. package/dist/src/commands/ipos.js.map +0 -1
  58. package/dist/src/commands/market.d.ts +0 -2
  59. package/dist/src/commands/market.js +0 -34
  60. package/dist/src/commands/market.js.map +0 -1
  61. package/dist/src/commands/metadata.d.ts +0 -2
  62. package/dist/src/commands/metadata.js +0 -39
  63. package/dist/src/commands/metadata.js.map +0 -1
  64. package/dist/src/commands/metrics.d.ts +0 -2
  65. package/dist/src/commands/metrics.js +0 -158
  66. package/dist/src/commands/metrics.js.map +0 -1
  67. package/dist/src/commands/ownership.d.ts +0 -2
  68. package/dist/src/commands/ownership.js +0 -152
  69. package/dist/src/commands/ownership.js.map +0 -1
  70. package/dist/src/commands/segments.d.ts +0 -2
  71. package/dist/src/commands/segments.js +0 -64
  72. package/dist/src/commands/segments.js.map +0 -1
  73. package/dist/src/commands/usage.d.ts +0 -38
  74. package/dist/src/commands/usage.js +0 -82
  75. package/dist/src/commands/usage.js.map +0 -1
  76. package/dist/src/commands/webhooks.d.ts +0 -16
  77. package/dist/src/commands/webhooks.js +0 -186
  78. package/dist/src/commands/webhooks.js.map +0 -1
  79. package/dist/src/formatters/sparkline.d.ts +0 -2
  80. package/dist/src/formatters/sparkline.js +0 -11
  81. package/dist/src/formatters/sparkline.js.map +0 -1
  82. package/dist/src/formatters/tree-formatter.d.ts +0 -11
  83. package/dist/src/formatters/tree-formatter.js +0 -30
  84. package/dist/src/formatters/tree-formatter.js.map +0 -1
package/dist/src/cli.d.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import { Command } from 'commander';
2
+ import { type Manifest } from './spec-manifest.js';
2
3
  /** `package.json` sits one level up under tsx (`src/cli.ts`), two in the build (`dist/src/cli.js`). */
3
4
  export declare function packageVersion(): string;
5
+ /**
6
+ * The committed command manifest, parsed once. Resolved next to this file: `src/generated/` under tsx,
7
+ * `dist/src/generated/` in the build (`scripts/copy-manifest.mjs` puts it there — `tsc` copies no JSON).
8
+ */
9
+ export declare function loadManifest(): Manifest;
4
10
  export declare function createProgram(): Command;
package/dist/src/cli.js CHANGED
@@ -3,23 +3,12 @@ import { Command } from 'commander';
3
3
  import { setJsonMode } from './shared/spinner.js';
4
4
  import { formatCreditUsage, takeCreditUsage } from './client/api-client.js';
5
5
  import { registerConfigCommands } from './commands/config.js';
6
- import { registerHealthCommand } from './commands/health.js';
7
- import { registerCompanyCommands } from './commands/company.js';
8
- import { registerFinancialsCommands } from './commands/financials.js';
9
- import { registerMetricsCommands } from './commands/metrics.js';
10
- import { registerSegmentsCommands } from './commands/segments.js';
11
- import { registerIposCommands } from './commands/ipos.js';
12
- import { registerOwnershipCommands } from './commands/ownership.js';
13
- import { registerInsiderTradesCommands } from './commands/insider-trades.js';
14
- import { registerFilingsCommands } from './commands/filings.js';
15
6
  import { registerEarningsCommands } from './commands/earnings.js';
16
- import { registerMarketCommands } from './commands/market.js';
17
- import { registerMetadataCommands } from './commands/metadata.js';
18
- import { registerWebhooksCommands } from './commands/webhooks.js';
19
- import { registerWsCommands } from './commands/ws.js';
20
- import { registerPluginCommands } from './commands/plugin.js';
21
7
  import { registerLoginCommands } from './commands/login.js';
22
- import { registerUsageCommands } from './commands/usage.js';
8
+ import { registerPluginCommands } from './commands/plugin.js';
9
+ import { registerWsCommands } from './commands/ws.js';
10
+ import { registerSpecCommands } from './spec-commands.js';
11
+ import { parseManifest } from './spec-manifest.js';
23
12
  const PACKAGE_NAME = '@invinite-org/invinite-data-cli';
24
13
  /** `package.json` sits one level up under tsx (`src/cli.ts`), two in the build (`dist/src/cli.js`). */
25
14
  export function packageVersion() {
@@ -36,6 +25,15 @@ export function packageVersion() {
36
25
  }
37
26
  return '0.0.0';
38
27
  }
28
+ let manifest;
29
+ /**
30
+ * The committed command manifest, parsed once. Resolved next to this file: `src/generated/` under tsx,
31
+ * `dist/src/generated/` in the build (`scripts/copy-manifest.mjs` puts it there — `tsc` copies no JSON).
32
+ */
33
+ export function loadManifest() {
34
+ manifest ??= parseManifest(createRequire(import.meta.url)('./generated/cli-manifest.json'));
35
+ return manifest;
36
+ }
39
37
  export function createProgram() {
40
38
  const program = new Command();
41
39
  program
@@ -45,6 +43,8 @@ export function createProgram() {
45
43
  .option('--json', 'Output raw JSON (pipe-friendly)')
46
44
  .option('--all', 'Auto-paginate through all results')
47
45
  .option('--show-cost', 'Print the credits a command cost to stderr (or set INVD_SHOW_COST=1)')
46
+ // Inherited by every group, so rostered and generated commands list alphabetically together.
47
+ .configureHelp({ sortSubcommands: true })
48
48
  .hook('preAction', (thisCommand) => {
49
49
  const opts = thisCommand.opts();
50
50
  if (opts.json) {
@@ -58,24 +58,14 @@ export function createProgram() {
58
58
  return;
59
59
  console.error(formatCreditUsage(usage));
60
60
  });
61
+ // The hand-written roster (`src/hand-written-commands.ts`) first, then every manifest operation; a generated
62
+ // `earnings` action attaches to the group `registerEarningsCommands` created.
63
+ registerLoginCommands(program);
61
64
  registerConfigCommands(program);
62
- registerHealthCommand(program);
63
- registerCompanyCommands(program);
64
- registerFinancialsCommands(program);
65
- registerMetricsCommands(program);
66
- registerSegmentsCommands(program);
67
- registerIposCommands(program);
68
- registerOwnershipCommands(program);
69
- registerInsiderTradesCommands(program);
70
- registerFilingsCommands(program);
71
- registerEarningsCommands(program);
72
- registerMarketCommands(program);
73
- registerMetadataCommands(program);
74
- registerWebhooksCommands(program);
75
- registerWsCommands(program);
76
65
  registerPluginCommands(program);
77
- registerLoginCommands(program);
78
- registerUsageCommands(program);
66
+ registerWsCommands(program);
67
+ registerEarningsCommands(program);
68
+ registerSpecCommands(program, loadManifest());
79
69
  return program;
80
70
  }
81
71
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,YAAY,GAAG,iCAAiC,CAAC;AAEvD,uGAAuG;AACvG,MAAM,UAAU,cAAc;IAC5B,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,KAAK,MAAM,SAAS,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAwC,CAAC;YAC1E,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,OAAO;gBAAE,OAAO,GAAG,CAAC,OAAO,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,yCAAyC,CAAC;SACtD,OAAO,CAAC,cAAc,EAAE,CAAC;SACzB,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;SACnD,MAAM,CAAC,OAAO,EAAE,mCAAmC,CAAC;SACpD,MAAM,CAAC,aAAa,EAAE,sEAAsE,CAAC;SAC7F,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,EAAE;QAClC,0FAA0F;QAC1F,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,GAAG,CAAC;YAAE,OAAO;QAC3F,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEL,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACnC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ export interface RequestOptions {
3
3
  /** An array value is sent as a repeated parameter (`status=a&status=b`). */
4
4
  params?: Record<string, string | string[] | undefined>;
5
5
  silent?: boolean;
6
+ /** `false` for a public operation: no API key is resolved or sent (default `true`). */
7
+ auth?: boolean;
6
8
  }
7
9
  export interface CreditUsage {
8
10
  /** `X-Credits-Charged`, summed over every request of this invocation (`--all` pages included). */
@@ -17,10 +19,6 @@ export interface CreditUsage {
17
19
  /** What this invocation's requests cost so far, then reset; `null` when no response carried a credit header. */
18
20
  export declare function takeCreditUsage(): CreditUsage | null;
19
21
  export declare function formatCreditUsage(usage: CreditUsage): string;
20
- /** Same auth / URL building as `apiGet`, without the JSON parse; a non-2xx throws `ApiError`. */
21
- export declare function apiGetRaw(opts: RequestOptions & {
22
- accept?: string;
23
- }): Promise<Response>;
24
22
  export declare function apiGet<T = unknown>(opts: RequestOptions): Promise<T>;
25
23
  export interface ApiRequestOptions extends RequestOptions {
26
24
  method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
@@ -1,6 +1,6 @@
1
1
  import { getApiKey } from '../config/auth.js';
2
2
  import { getBaseUrl } from '../config/config-manager.js';
3
- import { ApiError } from '../shared/errors.js';
3
+ import { ApiError, parseRetryAfter } from '../shared/errors.js';
4
4
  import { createSpinner } from '../shared/spinner.js';
5
5
  function buildUrl(path, params) {
6
6
  const base = getBaseUrl().replace(/\/+$/, '');
@@ -16,20 +16,26 @@ function buildUrl(path, params) {
16
16
  }
17
17
  return url.toString();
18
18
  }
19
+ const stringField = (body, key) => {
20
+ if (typeof body !== 'object' || body === null)
21
+ return undefined;
22
+ const value = Reflect.get(body, key);
23
+ return typeof value === 'string' && value !== '' ? value : undefined;
24
+ };
19
25
  async function apiErrorFrom(response) {
20
26
  const body = await response.json().catch(() => null);
21
- return new ApiError(response.status, body?.error || response.statusText || 'Unknown Error', body?.message || `Request failed with status ${response.status}`);
27
+ return new ApiError(response.status, stringField(body, 'error') ?? (response.statusText || 'Unknown Error'), stringField(body, 'message') ?? `Request failed with status ${response.status}`, parseRetryAfter(response.headers?.get('Retry-After')));
22
28
  }
23
29
  let creditUsage = null;
24
30
  function recordCredits(response) {
25
- const charged = response.headers?.get('X-Credits-Charged');
26
- const remaining = response.headers?.get('X-Credits-Included-Remaining');
27
- if (charged == null && remaining == null)
31
+ const charged = response.headers?.get('X-Credits-Charged') ?? null;
32
+ const remaining = response.headers?.get('X-Credits-Included-Remaining') ?? null;
33
+ if (charged === null && remaining === null)
28
34
  return;
29
35
  const chargedCredits = Number(charged) || 0;
30
36
  creditUsage = {
31
37
  charged: (creditUsage?.charged ?? 0) + chargedCredits,
32
- includedRemaining: remaining == null
38
+ includedRemaining: remaining === null
33
39
  ? creditUsage?.includedRemaining ?? null
34
40
  : Math.max(0, (Number(remaining) || 0) - chargedCredits),
35
41
  };
@@ -44,12 +50,10 @@ export function formatCreditUsage(usage) {
44
50
  return `credits: ${usage.charged} · included left: ${usage.includedRemaining ?? '—'}`;
45
51
  }
46
52
  async function request(opts, accept, init = {}) {
47
- const apiKey = await getApiKey();
48
53
  const url = buildUrl(opts.path, opts.params);
49
- const headers = {
50
- 'Authorization': `Bearer ${apiKey}`,
51
- 'Accept': accept,
52
- };
54
+ const headers = { 'Accept': accept };
55
+ if (opts.auth !== false)
56
+ headers['Authorization'] = `Bearer ${await getApiKey()}`;
53
57
  if (init.body !== undefined)
54
58
  headers['Content-Type'] = 'application/json';
55
59
  const response = await fetch(url, {
@@ -63,10 +67,6 @@ async function request(opts, accept, init = {}) {
63
67
  }
64
68
  return response;
65
69
  }
66
- /** Same auth / URL building as `apiGet`, without the JSON parse; a non-2xx throws `ApiError`. */
67
- export async function apiGetRaw(opts) {
68
- return request(opts, opts.accept ?? '*/*');
69
- }
70
70
  export async function apiGet(opts) {
71
71
  const spinner = opts.silent ? null : createSpinner('Fetching data...');
72
72
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/client/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AASrD,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAiC;IAC/D,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IACtC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAkB;IAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAQ,CAAC;IAC5D,OAAO,IAAI,QAAQ,CACjB,QAAQ,CAAC,MAAM,EACf,IAAI,EAAE,KAAK,IAAI,QAAQ,CAAC,UAAU,IAAI,eAAe,EACrD,IAAI,EAAE,OAAO,IAAI,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CACjE,CAAC;AACJ,CAAC;AAaD,IAAI,WAAW,GAAuB,IAAI,CAAC;AAE3C,SAAS,aAAa,CAAC,QAAkB;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACxE,IAAI,OAAO,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI;QAAE,OAAO;IACjD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,GAAG;QACZ,OAAO,EAAE,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,CAAC,GAAG,cAAc;QACrD,iBAAiB,EAAE,SAAS,IAAI,IAAI;YAClC,CAAC,CAAC,WAAW,EAAE,iBAAiB,IAAI,IAAI;YACxC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,cAAc,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,eAAe;IAC7B,MAAM,KAAK,GAAG,WAAW,CAAC;IAC1B,WAAW,GAAG,IAAI,CAAC;IACnB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IAClD,OAAO,YAAY,KAAK,CAAC,OAAO,qBAAqB,KAAK,CAAC,iBAAiB,IAAI,GAAG,EAAE,CAAC;AACxF,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,IAAoB,EACpB,MAAc,EACd,OAA4C,EAAE;IAE9C,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAA2B;QACtC,eAAe,EAAE,UAAU,MAAM,EAAE;QACnC,QAAQ,EAAE,MAAM;KACjB,CAAC;IACF,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC1E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO;QACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC,CAAC;IACH,aAAa,CAAC,QAAQ,CAAC,CAAC;IACxB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAA0C;IACxE,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAc,IAAoB;IAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;QACxC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAQD,+GAA+G;AAC/G,MAAM,CAAC,KAAK,UAAU,UAAU,CAAc,IAAuB;IACnE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnG,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAM,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/client/api-client.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,26 @@
1
+ import { ApiError } from '../shared/errors.js';
1
2
  type NextUrlExtractor<T> = (data: T) => string | undefined;
3
+ /**
4
+ * How `--all` waits out a refused page instead of dropping the pages it already holds: a 429 (the API's admission
5
+ * limit) or 503 is retried up to `retries` times, each after the answer's `Retry-After`, else `baseDelayMs * 2^n`,
6
+ * never longer than `maxDelayMs`. Any other error, or the last refusal, ends the walk.
7
+ */
8
+ export declare const PAGE_RETRY: {
9
+ readonly retries: 5;
10
+ readonly baseDelayMs: 1000;
11
+ readonly maxDelayMs: 30000;
12
+ };
13
+ /** The wait before retry number `retry` (0-based) of a refused page. */
14
+ export declare function pageRetryDelayMs(error: ApiError, retry: number): number;
2
15
  export declare function fetchAllPages<T>(initialData: T, extractNextUrl: NextUrlExtractor<T>, mergeResults: (accumulated: T, page: T) => T): Promise<T>;
16
+ /**
17
+ * `--all` over a response that pages with a top-level `next_url`: every `itemsPaths` array is concatenated across
18
+ * pages (a path a page does not carry adds nothing); the other fields come from the last page.
19
+ */
20
+ export declare function fetchAllTopPages(initialData: unknown, itemsPaths: readonly string[]): Promise<unknown>;
21
+ /**
22
+ * `--all` over a multi-company response (`companies[].next_url`): follows `companies[0].next_url` and concatenates
23
+ * each company's `itemsPaths` arrays by index, carrying each company's own `next_url` forward.
24
+ */
25
+ export declare function fetchAllCompanyPages(initialData: unknown, itemsPaths: readonly string[]): Promise<unknown>;
3
26
  export {};
@@ -1,19 +1,49 @@
1
1
  import { apiGet } from './api-client.js';
2
+ import { ApiError } from '../shared/errors.js';
2
3
  import { createSpinner } from '../shared/spinner.js';
4
+ import { pick } from '../formatters/flatten.js';
5
+ /**
6
+ * How `--all` waits out a refused page instead of dropping the pages it already holds: a 429 (the API's admission
7
+ * limit) or 503 is retried up to `retries` times, each after the answer's `Retry-After`, else `baseDelayMs * 2^n`,
8
+ * never longer than `maxDelayMs`. Any other error, or the last refusal, ends the walk.
9
+ */
10
+ export const PAGE_RETRY = { retries: 5, baseDelayMs: 1_000, maxDelayMs: 30_000 };
11
+ const isRetryable = (error) => error instanceof ApiError && (error.statusCode === 429 || error.statusCode === 503);
12
+ /** The wait before retry number `retry` (0-based) of a refused page. */
13
+ export function pageRetryDelayMs(error, retry) {
14
+ return Math.min(PAGE_RETRY.maxDelayMs, error.retryAfterMs ?? PAGE_RETRY.baseDelayMs * 2 ** retry);
15
+ }
16
+ const sleep = (ms) => new Promise(done => setTimeout(done, ms));
17
+ async function fetchPage(nextUrl, onWait) {
18
+ // nextUrl is absolute: re-issue its path + query against the configured base URL. Repeated keys
19
+ // (`status=a&status=b`) stay repeated.
20
+ const url = new URL(nextUrl);
21
+ const params = {};
22
+ url.searchParams.forEach((v, k) => { (params[k] ??= []).push(v); });
23
+ for (let retry = 0;; retry += 1) {
24
+ try {
25
+ return await apiGet({ path: url.pathname, params, silent: true });
26
+ }
27
+ catch (error) {
28
+ if (!isRetryable(error) || retry >= PAGE_RETRY.retries)
29
+ throw error;
30
+ const delay = pageRetryDelayMs(error, retry);
31
+ onWait(Math.ceil(delay / 1000), retry + 1);
32
+ await sleep(delay);
33
+ }
34
+ }
35
+ }
3
36
  export async function fetchAllPages(initialData, extractNextUrl, mergeResults) {
4
37
  let result = initialData;
5
38
  let nextUrl = extractNextUrl(result);
6
39
  let page = 1;
7
40
  while (nextUrl) {
8
- page++;
41
+ page += 1;
9
42
  const spinner = createSpinner(`Fetching page ${page}...`);
10
43
  try {
11
- // nextUrl is absolute, extract path+query
12
- const url = new URL(nextUrl);
13
- // Repeated keys (`status=a&status=b`) stay repeated.
14
- const params = {};
15
- url.searchParams.forEach((v, k) => { (params[k] ??= []).push(v); });
16
- const pageData = await apiGet({ path: url.pathname, params, silent: true });
44
+ const pageData = await fetchPage(nextUrl, (seconds, retry) => {
45
+ spinner.text = `Page ${page} refused (rate limit) — retry ${retry}/${PAGE_RETRY.retries} in ${seconds}s...`;
46
+ });
17
47
  result = mergeResults(result, pageData);
18
48
  nextUrl = extractNextUrl(pageData);
19
49
  spinner.succeed(`Page ${page} fetched`);
@@ -25,4 +55,43 @@ export async function fetchAllPages(initialData, extractNextUrl, mergeResults) {
25
55
  }
26
56
  return result;
27
57
  }
58
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
59
+ const arrayAt = (value, path) => {
60
+ const found = pick(value, path);
61
+ return Array.isArray(found) ? found : [];
62
+ };
63
+ /** A copy of `target` with `value` at the dotted `path` (missing objects on the way are created). */
64
+ function withValueAt(target, path, value) {
65
+ const [head, ...rest] = path.split('.');
66
+ if (rest.length === 0)
67
+ return { ...target, [head]: value };
68
+ const child = target[head];
69
+ return { ...target, [head]: withValueAt(isRecord(child) ? child : {}, rest.join('.'), value) };
70
+ }
71
+ const nextUrlAt = (value, path) => {
72
+ const found = pick(value, path);
73
+ return typeof found === 'string' && found !== '' ? found : undefined;
74
+ };
75
+ /**
76
+ * `--all` over a response that pages with a top-level `next_url`: every `itemsPaths` array is concatenated across
77
+ * pages (a path a page does not carry adds nothing); the other fields come from the last page.
78
+ */
79
+ export async function fetchAllTopPages(initialData, itemsPaths) {
80
+ return fetchAllPages(initialData, data => nextUrlAt(data, 'next_url'), (accumulated, page) => itemsPaths.reduce((merged, path) => withValueAt(merged, path, [...arrayAt(accumulated, path), ...arrayAt(page, path)]), isRecord(page) ? page : {}));
81
+ }
82
+ /**
83
+ * `--all` over a multi-company response (`companies[].next_url`): follows `companies[0].next_url` and concatenates
84
+ * each company's `itemsPaths` arrays by index, carrying each company's own `next_url` forward.
85
+ */
86
+ export async function fetchAllCompanyPages(initialData, itemsPaths) {
87
+ return fetchAllPages(initialData, data => nextUrlAt(data, 'companies.0.next_url'), (accumulated, page) => {
88
+ const base = isRecord(accumulated) ? accumulated : {};
89
+ const companies = arrayAt(accumulated, 'companies').map((company, index) => {
90
+ const pageCompany = pick(page, `companies.${index}`);
91
+ const merged = itemsPaths.reduce((acc, path) => withValueAt(acc, path, [...arrayAt(company, path), ...arrayAt(pageCompany, path)]), isRecord(company) ? company : {});
92
+ return { ...merged, next_url: pick(pageCompany, 'next_url') };
93
+ });
94
+ return { ...base, companies };
95
+ });
96
+ }
28
97
  //# sourceMappingURL=pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/client/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAc,EACd,cAAmC,EACnC,YAA4C;IAE5C,IAAI,MAAM,GAAG,WAAW,CAAC;IACzB,IAAI,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,OAAO,EAAE,CAAC;QACf,IAAI,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,0CAA0C;YAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7B,qDAAqD;YACrD,MAAM,MAAM,GAA6B,EAAE,CAAC;YAC5C,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAI,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/E,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACxC,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;YACnC,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;YACpC,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/client/pagination.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,5 @@
1
1
  import { Command } from 'commander';
2
- import { ApiError } from '../shared/errors.js';
3
2
  type Row = Record<string, any>;
4
- /** One dim line after a 403 whose message names the plan the route needs. */
5
- export declare function planHint(error: ApiError): string | undefined;
6
3
  /** "Q&A starts at m:ss" for the transcript header; undefined without a Q&A boundary. */
7
4
  export declare function qaStartLine(qaStartMs: unknown): string | undefined;
8
5
  /** Plain-text rendering of a transcript `data` (console and `--output`); `words` stays JSON. */