gangtise-openapi-cli 0.21.0 → 0.22.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.
@@ -1,7 +1,8 @@
1
- export const ENDPOINTS = {
1
+ // Registry entries omit `key`: it is derived from the record key when ENDPOINTS is
2
+ // built below, so the two can never drift.
3
+ const ENDPOINT_DEFS = {
2
4
  // ─── auth ───
3
5
  "auth.login": {
4
- key: "auth.login",
5
6
  method: "POST",
6
7
  path: "/application/auth/oauth/open/loginV2",
7
8
  kind: "json",
@@ -9,14 +10,12 @@ export const ENDPOINTS = {
9
10
  },
10
11
  // ─── lookup (served from local data, not HTTP) ───
11
12
  "lookup.broker-orgs.list": {
12
- key: "lookup.broker-orgs.list",
13
13
  method: "GET",
14
14
  path: "/guide/broker-orgs-local",
15
15
  kind: "json",
16
16
  description: "List broker orgs from local docs",
17
17
  },
18
18
  "lookup.meeting-orgs.list": {
19
- key: "lookup.meeting-orgs.list",
20
19
  method: "GET",
21
20
  path: "/guide/meeting-orgs-local",
22
21
  kind: "json",
@@ -24,7 +23,6 @@ export const ENDPOINTS = {
24
23
  },
25
24
  // ─── insight ───
26
25
  "insight.opinion.list": {
27
- key: "insight.opinion.list",
28
26
  method: "POST",
29
27
  path: "/application/open-insight/chief-opinion/getList",
30
28
  kind: "json",
@@ -32,7 +30,6 @@ export const ENDPOINTS = {
32
30
  pagination: { enabled: true, maxPageSize: 50 },
33
31
  },
34
32
  "insight.summary.list": {
35
- key: "insight.summary.list",
36
33
  method: "POST",
37
34
  path: "/application/open-insight/summary/v2/getList",
38
35
  kind: "json",
@@ -40,14 +37,12 @@ export const ENDPOINTS = {
40
37
  pagination: { enabled: true, maxPageSize: 50 },
41
38
  },
42
39
  "insight.summary.download": {
43
- key: "insight.summary.download",
44
40
  method: "GET",
45
41
  path: "/application/open-insight/summary/v2/download/file",
46
42
  kind: "download",
47
43
  description: "Download summary file",
48
44
  },
49
45
  "insight.roadshow.list": {
50
- key: "insight.roadshow.list",
51
46
  method: "POST",
52
47
  path: "/application/open-insight/schedule/roadshow/getList",
53
48
  kind: "json",
@@ -55,7 +50,6 @@ export const ENDPOINTS = {
55
50
  pagination: { enabled: true, maxPageSize: 50 },
56
51
  },
57
52
  "insight.site-visit.list": {
58
- key: "insight.site-visit.list",
59
53
  method: "POST",
60
54
  path: "/application/open-insight/schedule/site-visit/getList",
61
55
  kind: "json",
@@ -63,7 +57,6 @@ export const ENDPOINTS = {
63
57
  pagination: { enabled: true, maxPageSize: 50 },
64
58
  },
65
59
  "insight.strategy.list": {
66
- key: "insight.strategy.list",
67
60
  method: "POST",
68
61
  path: "/application/open-insight/schedule/strategy-meeting/getList",
69
62
  kind: "json",
@@ -71,7 +64,6 @@ export const ENDPOINTS = {
71
64
  pagination: { enabled: true, maxPageSize: 50 },
72
65
  },
73
66
  "insight.forum.list": {
74
- key: "insight.forum.list",
75
67
  method: "POST",
76
68
  path: "/application/open-insight/schedule/forum/getList",
77
69
  kind: "json",
@@ -79,7 +71,6 @@ export const ENDPOINTS = {
79
71
  pagination: { enabled: true, maxPageSize: 50 },
80
72
  },
81
73
  "insight.research.list": {
82
- key: "insight.research.list",
83
74
  method: "POST",
84
75
  path: "/application/open-insight/broker-report/getList",
85
76
  kind: "json",
@@ -87,14 +78,12 @@ export const ENDPOINTS = {
87
78
  pagination: { enabled: true, maxPageSize: 50 },
88
79
  },
89
80
  "insight.research.download": {
90
- key: "insight.research.download",
91
81
  method: "GET",
92
82
  path: "/application/open-insight/broker-report/download/file",
93
83
  kind: "download",
94
84
  description: "Download broker research report",
95
85
  },
96
86
  "insight.foreign-report.list": {
97
- key: "insight.foreign-report.list",
98
87
  method: "POST",
99
88
  path: "/application/open-insight/foreign-report/getList",
100
89
  kind: "json",
@@ -102,14 +91,12 @@ export const ENDPOINTS = {
102
91
  pagination: { enabled: true, maxPageSize: 50 },
103
92
  },
104
93
  "insight.foreign-report.download": {
105
- key: "insight.foreign-report.download",
106
94
  method: "GET",
107
95
  path: "/application/open-insight/foreign-report/download/file",
108
96
  kind: "download",
109
97
  description: "Download foreign report",
110
98
  },
111
99
  "insight.announcement.list": {
112
- key: "insight.announcement.list",
113
100
  method: "POST",
114
101
  path: "/application/open-insight/announcement/getList",
115
102
  kind: "json",
@@ -117,14 +104,12 @@ export const ENDPOINTS = {
117
104
  pagination: { enabled: true, maxPageSize: 50 },
118
105
  },
119
106
  "insight.announcement.download": {
120
- key: "insight.announcement.download",
121
107
  method: "GET",
122
108
  path: "/application/open-insight/announcement/download/file",
123
109
  kind: "download",
124
110
  description: "Download A-share announcement file",
125
111
  },
126
112
  "insight.announcement-hk.list": {
127
- key: "insight.announcement-hk.list",
128
113
  method: "POST",
129
114
  path: "/application/open-insight/announcement-hk/getList",
130
115
  kind: "json",
@@ -132,14 +117,12 @@ export const ENDPOINTS = {
132
117
  pagination: { enabled: true, maxPageSize: 50 },
133
118
  },
134
119
  "insight.announcement-hk.download": {
135
- key: "insight.announcement-hk.download",
136
120
  method: "GET",
137
121
  path: "/application/open-insight/announcement-hk/download/file",
138
122
  kind: "download",
139
123
  description: "Download HK announcement file",
140
124
  },
141
125
  "insight.announcement-us.list": {
142
- key: "insight.announcement-us.list",
143
126
  method: "POST",
144
127
  path: "/application/open-insight/announcement-us/getList",
145
128
  kind: "json",
@@ -147,14 +130,12 @@ export const ENDPOINTS = {
147
130
  pagination: { enabled: true, maxPageSize: 50 },
148
131
  },
149
132
  "insight.announcement-us.download": {
150
- key: "insight.announcement-us.download",
151
133
  method: "GET",
152
134
  path: "/application/open-insight/announcement-us/download/file",
153
135
  kind: "download",
154
136
  description: "Download US announcement file",
155
137
  },
156
138
  "insight.foreign-opinion.list": {
157
- key: "insight.foreign-opinion.list",
158
139
  method: "POST",
159
140
  path: "/application/open-insight/foreign-opinion/getList",
160
141
  kind: "json",
@@ -162,7 +143,6 @@ export const ENDPOINTS = {
162
143
  pagination: { enabled: true, maxPageSize: 50 },
163
144
  },
164
145
  "insight.independent-opinion.list": {
165
- key: "insight.independent-opinion.list",
166
146
  method: "POST",
167
147
  path: "/application/open-insight/independent-opinion/getList",
168
148
  kind: "json",
@@ -170,14 +150,12 @@ export const ENDPOINTS = {
170
150
  pagination: { enabled: true, maxPageSize: 50 },
171
151
  },
172
152
  "insight.independent-opinion.download": {
173
- key: "insight.independent-opinion.download",
174
153
  method: "GET",
175
154
  path: "/application/open-insight/independent-opinion/download/file",
176
155
  kind: "download",
177
156
  description: "Download foreign independent opinion file",
178
157
  },
179
158
  "insight.official-account.list": {
180
- key: "insight.official-account.list",
181
159
  method: "POST",
182
160
  path: "/application/open-insight/officialAccount/getList",
183
161
  kind: "json",
@@ -185,7 +163,6 @@ export const ENDPOINTS = {
185
163
  pagination: { enabled: true, maxPageSize: 50 },
186
164
  },
187
165
  "insight.official-account.download": {
188
- key: "insight.official-account.download",
189
166
  method: "GET",
190
167
  path: "/application/open-insight/officialAccount/download/file",
191
168
  kind: "download",
@@ -193,49 +170,42 @@ export const ENDPOINTS = {
193
170
  },
194
171
  // ─── reference ───
195
172
  "reference.securities-search": {
196
- key: "reference.securities-search",
197
173
  method: "POST",
198
174
  path: "/application/open-reference/securities/search",
199
175
  kind: "json",
200
176
  description: "Search GTS codes (securities)",
201
177
  },
202
178
  "reference.chiefs-search": {
203
- key: "reference.chiefs-search",
204
179
  method: "POST",
205
180
  path: "/application/open-reference/chiefs/search",
206
181
  kind: "json",
207
182
  description: "Search chief analyst IDs by name / institution / team",
208
183
  },
209
184
  "reference.constant-category": {
210
- key: "reference.constant-category",
211
185
  method: "GET",
212
186
  path: "/application/open-reference/constants/category",
213
187
  kind: "json",
214
188
  description: "List constant categories and their API usage scopes",
215
189
  },
216
190
  "reference.constant-list": {
217
- key: "reference.constant-list",
218
191
  method: "POST",
219
192
  path: "/application/open-reference/constants/getList",
220
193
  kind: "json",
221
194
  description: "List all constant values of a category",
222
195
  },
223
196
  "reference.concept-search": {
224
- key: "reference.concept-search",
225
197
  method: "POST",
226
198
  path: "/application/open-reference/concepts/search",
227
199
  kind: "json",
228
200
  description: "Search concept (theme) IDs by keyword",
229
201
  },
230
202
  "reference.sector-search": {
231
- key: "reference.sector-search",
232
203
  method: "POST",
233
204
  path: "/application/open-reference/sectors/search",
234
205
  kind: "json",
235
206
  description: "Search sector IDs by keyword",
236
207
  },
237
208
  "reference.sector-constituents": {
238
- key: "reference.sector-constituents",
239
209
  method: "POST",
240
210
  path: "/application/open-reference/sectors/constituents",
241
211
  kind: "json",
@@ -243,42 +213,36 @@ export const ENDPOINTS = {
243
213
  },
244
214
  // ─── quote ───
245
215
  "quote.day-kline": {
246
- key: "quote.day-kline",
247
216
  method: "POST",
248
217
  path: "/application/open-quote/kline/daily",
249
218
  kind: "json",
250
219
  description: "Query A-share historical daily kline (SH/SZ/BJ)",
251
220
  },
252
221
  "quote.day-kline-hk": {
253
- key: "quote.day-kline-hk",
254
222
  method: "POST",
255
223
  path: "/application/open-quote/kline-hk/daily",
256
224
  kind: "json",
257
225
  description: "Query HK stock historical daily kline (HK)",
258
226
  },
259
227
  "quote.day-kline-us": {
260
- key: "quote.day-kline-us",
261
228
  method: "POST",
262
229
  path: "/application/open-quote/kline-us/daily",
263
230
  kind: "json",
264
231
  description: "Query US stock historical daily kline (NYSE/NASDAQ/AMEX)",
265
232
  },
266
233
  "quote.index-day-kline": {
267
- key: "quote.index-day-kline",
268
234
  method: "POST",
269
235
  path: "/application/open-quote/index/kline/daily",
270
236
  kind: "json",
271
237
  description: "Query SH/SZ/BJ index daily kline",
272
238
  },
273
239
  "quote.minute-kline": {
274
- key: "quote.minute-kline",
275
240
  method: "POST",
276
241
  path: "/application/open-quote/kline/minute",
277
242
  kind: "json",
278
243
  description: "Query A-share minute kline (SH/SZ/BJ)",
279
244
  },
280
245
  "quote.realtime": {
281
- key: "quote.realtime",
282
246
  method: "POST",
283
247
  path: "/application/open-quote/quote/realtime",
284
248
  kind: "json",
@@ -286,105 +250,90 @@ export const ENDPOINTS = {
286
250
  },
287
251
  // ─── fundamental ───
288
252
  "fundamental.income-statement": {
289
- key: "fundamental.income-statement",
290
253
  method: "POST",
291
254
  path: "/application/open-fundamental/financial-report/income-statement/accumulated",
292
255
  kind: "json",
293
256
  description: "Query A-share income statement (accumulated)",
294
257
  },
295
258
  "fundamental.income-statement-quarterly": {
296
- key: "fundamental.income-statement-quarterly",
297
259
  method: "POST",
298
260
  path: "/application/open-fundamental/financial-report/income-statement/quarterly",
299
261
  kind: "json",
300
262
  description: "Query A-share income statement (quarterly)",
301
263
  },
302
264
  "fundamental.balance-sheet": {
303
- key: "fundamental.balance-sheet",
304
265
  method: "POST",
305
266
  path: "/application/open-fundamental/financial-report/balance-sheet/accumulated",
306
267
  kind: "json",
307
268
  description: "Query A-share balance sheet (accumulated)",
308
269
  },
309
270
  "fundamental.cash-flow": {
310
- key: "fundamental.cash-flow",
311
271
  method: "POST",
312
272
  path: "/application/open-fundamental/financial-report/cash-flow-statement/accumulated",
313
273
  kind: "json",
314
274
  description: "Query A-share cash flow statement (accumulated)",
315
275
  },
316
276
  "fundamental.cash-flow-quarterly": {
317
- key: "fundamental.cash-flow-quarterly",
318
277
  method: "POST",
319
278
  path: "/application/open-fundamental/financial-report/cash-flow-statement/quarterly",
320
279
  kind: "json",
321
280
  description: "Query A-share cash flow statement (quarterly)",
322
281
  },
323
282
  "fundamental.income-statement-hk": {
324
- key: "fundamental.income-statement-hk",
325
283
  method: "POST",
326
284
  path: "/application/open-fundamental/financial-report/income-statement/hk",
327
285
  kind: "json",
328
286
  description: "Query HK income statement (China GAAP)",
329
287
  },
330
288
  "fundamental.balance-sheet-hk": {
331
- key: "fundamental.balance-sheet-hk",
332
289
  method: "POST",
333
290
  path: "/application/open-fundamental/financial-report/balance-sheet/hk",
334
291
  kind: "json",
335
292
  description: "Query HK balance sheet (China GAAP)",
336
293
  },
337
294
  "fundamental.cash-flow-hk": {
338
- key: "fundamental.cash-flow-hk",
339
295
  method: "POST",
340
296
  path: "/application/open-fundamental/financial-report/cash-flow-statement/hk",
341
297
  kind: "json",
342
298
  description: "Query HK cash flow statement (China GAAP)",
343
299
  },
344
300
  "fundamental.income-statement-us": {
345
- key: "fundamental.income-statement-us",
346
301
  method: "POST",
347
302
  path: "/application/open-fundamental/financial-report/income-statement/us",
348
303
  kind: "json",
349
304
  description: "Query US income statement",
350
305
  },
351
306
  "fundamental.balance-sheet-us": {
352
- key: "fundamental.balance-sheet-us",
353
307
  method: "POST",
354
308
  path: "/application/open-fundamental/financial-report/balance-sheet/us",
355
309
  kind: "json",
356
310
  description: "Query US balance sheet",
357
311
  },
358
312
  "fundamental.cash-flow-us": {
359
- key: "fundamental.cash-flow-us",
360
313
  method: "POST",
361
314
  path: "/application/open-fundamental/financial-report/cash-flow-statement/us",
362
315
  kind: "json",
363
316
  description: "Query US cash flow statement",
364
317
  },
365
318
  "fundamental.main-business": {
366
- key: "fundamental.main-business",
367
319
  method: "POST",
368
320
  path: "/application/open-fundamental/main-business",
369
321
  kind: "json",
370
322
  description: "Query main business composition",
371
323
  },
372
324
  "fundamental.valuation-analysis": {
373
- key: "fundamental.valuation-analysis",
374
325
  method: "POST",
375
326
  path: "/application/open-fundamental/valuation-analysis",
376
327
  kind: "json",
377
328
  description: "Query valuation analysis",
378
329
  },
379
330
  "fundamental.top-holders": {
380
- key: "fundamental.top-holders",
381
331
  method: "POST",
382
332
  path: "/application/open-fundamental/capital-structure/top-holders",
383
333
  kind: "json",
384
334
  description: "Query top holders (top10 / top10 float)",
385
335
  },
386
336
  "fundamental.earning-forecast": {
387
- key: "fundamental.earning-forecast",
388
337
  method: "POST",
389
338
  path: "/application/open-fundamental/earning-forecast",
390
339
  kind: "json",
@@ -392,28 +341,24 @@ export const ENDPOINTS = {
392
341
  },
393
342
  // ─── ai ───
394
343
  "ai.stock-summary.list": {
395
- key: "ai.stock-summary.list",
396
344
  method: "POST",
397
345
  path: "/application/open-ai/stock-summary/getList",
398
346
  kind: "json",
399
347
  description: "Stock highlights (refined research summary per security)",
400
348
  },
401
349
  "ai.knowledge-batch": {
402
- key: "ai.knowledge-batch",
403
350
  method: "POST",
404
351
  path: "/application/open-data/ai/search/knowledge/batch",
405
352
  kind: "json",
406
353
  description: "Batch knowledge search",
407
354
  },
408
355
  "ai.knowledge-resource.download": {
409
- key: "ai.knowledge-resource.download",
410
356
  method: "GET",
411
357
  path: "/application/open-data/ai/resource/download",
412
358
  kind: "download",
413
359
  description: "Download knowledge resource",
414
360
  },
415
361
  "ai.security-clue.list": {
416
- key: "ai.security-clue.list",
417
362
  method: "POST",
418
363
  path: "/application/open-ai/security-clue/getList",
419
364
  kind: "json",
@@ -421,56 +366,48 @@ export const ENDPOINTS = {
421
366
  pagination: { enabled: true, maxPageSize: 500 },
422
367
  },
423
368
  "ai.one-pager": {
424
- key: "ai.one-pager",
425
369
  method: "POST",
426
370
  path: "/application/open-ai/agent/one-pager",
427
371
  kind: "json",
428
372
  description: "Generate one pager",
429
373
  },
430
374
  "ai.investment-logic": {
431
- key: "ai.investment-logic",
432
375
  method: "POST",
433
376
  path: "/application/open-ai/agent/investment-logic",
434
377
  kind: "json",
435
378
  description: "Generate investment logic",
436
379
  },
437
380
  "ai.peer-comparison": {
438
- key: "ai.peer-comparison",
439
381
  method: "POST",
440
382
  path: "/application/open-ai/agent/peer-comparison",
441
383
  kind: "json",
442
384
  description: "Generate peer comparison",
443
385
  },
444
386
  "ai.earnings-review.get-id": {
445
- key: "ai.earnings-review.get-id",
446
387
  method: "POST",
447
388
  path: "/application/open-ai/agent/earnings-review-getid",
448
389
  kind: "json",
449
390
  description: "Get earnings review ID",
450
391
  },
451
392
  "ai.earnings-review.get-content": {
452
- key: "ai.earnings-review.get-content",
453
393
  method: "POST",
454
394
  path: "/application/open-ai/agent/earnings-review-getcontent",
455
395
  kind: "json",
456
396
  description: "Get earnings review content",
457
397
  },
458
398
  "ai.theme-tracking": {
459
- key: "ai.theme-tracking",
460
399
  method: "POST",
461
400
  path: "/application/open-ai/agent/theme-tracking",
462
401
  kind: "json",
463
402
  description: "Get theme tracking daily report",
464
403
  },
465
404
  "ai.research-outline": {
466
- key: "ai.research-outline",
467
405
  method: "POST",
468
406
  path: "/application/open-ai/agent/research-outline",
469
407
  kind: "json",
470
408
  description: "Get company research outline",
471
409
  },
472
410
  "ai.hot-topic": {
473
- key: "ai.hot-topic",
474
411
  method: "POST",
475
412
  path: "/application/open-ai/hot-topic/getList",
476
413
  kind: "json",
@@ -478,28 +415,24 @@ export const ENDPOINTS = {
478
415
  pagination: { enabled: true, maxPageSize: 20 },
479
416
  },
480
417
  "ai.management-discuss-announcement": {
481
- key: "ai.management-discuss-announcement",
482
418
  method: "POST",
483
419
  path: "/application/open-ai/management-discuss/from-announcement",
484
420
  kind: "json",
485
421
  description: "Management discussion from financial reports (half-year/annual)",
486
422
  },
487
423
  "ai.management-discuss-earnings-call": {
488
- key: "ai.management-discuss-earnings-call",
489
424
  method: "POST",
490
425
  path: "/application/open-ai/management-discuss/from-earningsCall",
491
426
  kind: "json",
492
427
  description: "Management discussion from earnings calls",
493
428
  },
494
429
  "ai.viewpoint-debate.get-id": {
495
- key: "ai.viewpoint-debate.get-id",
496
430
  method: "POST",
497
431
  path: "/application/open-ai/agent/viewpoint-debate-getid",
498
432
  kind: "json",
499
433
  description: "Get viewpoint debate ID",
500
434
  },
501
435
  "ai.viewpoint-debate.get-content": {
502
- key: "ai.viewpoint-debate.get-content",
503
436
  method: "POST",
504
437
  path: "/application/open-ai/agent/viewpoint-debate-getcontent",
505
438
  kind: "json",
@@ -507,7 +440,6 @@ export const ENDPOINTS = {
507
440
  },
508
441
  // ─── vault ───
509
442
  "vault.drive.list": {
510
- key: "vault.drive.list",
511
443
  method: "POST",
512
444
  path: "/application/open-vault/drive/getList",
513
445
  kind: "json",
@@ -515,14 +447,12 @@ export const ENDPOINTS = {
515
447
  pagination: { enabled: true, maxPageSize: 50 },
516
448
  },
517
449
  "vault.drive.download": {
518
- key: "vault.drive.download",
519
450
  method: "GET",
520
451
  path: "/application/open-vault/drive/download/file",
521
452
  kind: "download",
522
453
  description: "Download vault drive file",
523
454
  },
524
455
  "vault.record.list": {
525
- key: "vault.record.list",
526
456
  method: "POST",
527
457
  path: "/application/open-vault/record/getList",
528
458
  kind: "json",
@@ -530,14 +460,12 @@ export const ENDPOINTS = {
530
460
  pagination: { enabled: true, maxPageSize: 50 },
531
461
  },
532
462
  "vault.record.download": {
533
- key: "vault.record.download",
534
463
  method: "GET",
535
464
  path: "/application/open-vault/record/download/file",
536
465
  kind: "download",
537
466
  description: "Download voice recording transcription file",
538
467
  },
539
468
  "vault.my-conference.list": {
540
- key: "vault.my-conference.list",
541
469
  method: "POST",
542
470
  path: "/application/open-vault/my-conference/getList",
543
471
  kind: "json",
@@ -545,14 +473,12 @@ export const ENDPOINTS = {
545
473
  pagination: { enabled: true, maxPageSize: 50 },
546
474
  },
547
475
  "vault.my-conference.download": {
548
- key: "vault.my-conference.download",
549
476
  method: "GET",
550
477
  path: "/application/open-vault/my-conference/download/file",
551
478
  kind: "download",
552
479
  description: "Download my conference resource",
553
480
  },
554
481
  "vault.wechat-message.list": {
555
- key: "vault.wechat-message.list",
556
482
  method: "POST",
557
483
  path: "/application/open-vault/wechatgroupmsg/list",
558
484
  kind: "json",
@@ -560,7 +486,6 @@ export const ENDPOINTS = {
560
486
  pagination: { enabled: true, maxPageSize: 50 },
561
487
  },
562
488
  "vault.wechat-chatroom.list": {
563
- key: "vault.wechat-chatroom.list",
564
489
  method: "POST",
565
490
  path: "/application/open-vault/wechatgroupmsg/chatroomId",
566
491
  kind: "json",
@@ -569,14 +494,12 @@ export const ENDPOINTS = {
569
494
  pagination: { enabled: true, maxPageSize: 50, sequential: true, listKey: "chatRoomList" },
570
495
  },
571
496
  "vault.stock-pool.list": {
572
- key: "vault.stock-pool.list",
573
497
  method: "POST",
574
498
  path: "/application/open-vault/stock-pool/getPoolList",
575
499
  kind: "json",
576
500
  description: "List user stock pool IDs and names",
577
501
  },
578
502
  "vault.stock-pool.stocks": {
579
- key: "vault.stock-pool.stocks",
580
503
  method: "POST",
581
504
  path: "/application/open-vault/stock-pool/getStockList",
582
505
  kind: "json",
@@ -584,28 +507,24 @@ export const ENDPOINTS = {
584
507
  },
585
508
  // ─── alternative ───
586
509
  "alternative.edb-search": {
587
- key: "alternative.edb-search",
588
510
  method: "POST",
589
511
  path: "/application/open-alternative/EDB/search",
590
512
  kind: "json",
591
513
  description: "Search industry indicator list by keyword",
592
514
  },
593
515
  "alternative.edb-data": {
594
- key: "alternative.edb-data",
595
516
  method: "POST",
596
517
  path: "/application/open-alternative/EDB/getData",
597
518
  kind: "json",
598
519
  description: "Get industry indicator time-series data by indicator ID list",
599
520
  },
600
521
  "alternative.concept-info": {
601
- key: "alternative.concept-info",
602
522
  method: "POST",
603
523
  path: "/application/open-alternative/concept/info",
604
524
  kind: "json",
605
525
  description: "Query latest concept (theme index) profile by conceptId",
606
526
  },
607
527
  "alternative.concept-securities": {
608
- key: "alternative.concept-securities",
609
528
  method: "POST",
610
529
  path: "/application/open-alternative/concept/securities",
611
530
  kind: "json",
@@ -613,24 +532,22 @@ export const ENDPOINTS = {
613
532
  },
614
533
  // ─── indicator (EDE: security-level data indicators) ───
615
534
  "indicator.search": {
616
- key: "indicator.search",
617
535
  method: "POST",
618
536
  path: "/application/open-indicator/EDE/search",
619
537
  kind: "json",
620
538
  description: "Search data indicators by keyword (returns indicatorCode + params)",
621
539
  },
622
540
  "indicator.cross-section": {
623
- key: "indicator.cross-section",
624
541
  method: "POST",
625
542
  path: "/application/open-indicator/EDE/cross-section",
626
543
  kind: "json",
627
544
  description: "Get cross-section data (multi-indicator x multi-security, single date)",
628
545
  },
629
546
  "indicator.time-series": {
630
- key: "indicator.time-series",
631
547
  method: "POST",
632
548
  path: "/application/open-indicator/EDE/time-series",
633
549
  kind: "json",
634
550
  description: "Get time-series data (multi-indicator x single-security OR single-indicator x multi-security)",
635
551
  },
636
552
  };
553
+ export const ENDPOINTS = Object.fromEntries(Object.entries(ENDPOINT_DEFS).map(([key, def]) => [key, { key, ...def }]));
@@ -2,19 +2,24 @@ import { ApiError } from "./errors.js";
2
2
  // The EDE endpoints double-wrap on success: the shared client strips the outer
3
3
  // envelope but leaves an inner { code, status, data } around the real payload.
4
4
  // Peel that inner envelope so the list (search) / matrix (cross-section,
5
- // time-series) is reachable. Observed errors arrive single-enveloped (the
6
- // client throws on those), but a failure code carried only by the inner
7
- // envelope must still surface instead of rendering its null payload as success.
5
+ // time-series) is reachable. A failure code carried only by the inner envelope
6
+ // must still surface instead of rendering its null payload as success.
8
7
  export function unwrapIndicatorData(raw) {
9
8
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
10
9
  const record = raw;
11
- if ("data" in record && ("code" in record || "status" in record)) {
10
+ if ("code" in record || "status" in record) {
12
11
  const code = record.code === undefined ? undefined : String(record.code);
13
12
  const ok = record.status === true || code === "000000" || code === "0";
14
- if (!ok) {
13
+ // A failure envelope may omit `data` entirely ({ code, status: false, msg })
14
+ // — gating on the data key would let a permission/quota error flow through
15
+ // as "successful" payload. Still require some envelope evidence
16
+ // (status/msg/data) so a non-envelope object that merely carries a `code`
17
+ // field can't be misread as a failure.
18
+ if (!ok && ("status" in record || "msg" in record || "data" in record)) {
15
19
  throw new ApiError(typeof record.msg === "string" && record.msg ? record.msg : "Indicator API request failed", code);
16
20
  }
17
- return record.data;
21
+ if (ok && "data" in record)
22
+ return record.data;
18
23
  }
19
24
  }
20
25
  return raw;