reportify-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,673 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ APIError: () => APIError,
24
+ AuthenticationError: () => AuthenticationError,
25
+ DocsModule: () => DocsModule,
26
+ KBModule: () => KBModule,
27
+ NotFoundError: () => NotFoundError,
28
+ RateLimitError: () => RateLimitError,
29
+ Reportify: () => Reportify,
30
+ ReportifyError: () => ReportifyError,
31
+ StockModule: () => StockModule,
32
+ TimelineModule: () => TimelineModule
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/stock.ts
37
+ var StockModule = class {
38
+ constructor(client) {
39
+ this.client = client;
40
+ }
41
+ // ===========================================================================
42
+ // Company Information
43
+ // ===========================================================================
44
+ /**
45
+ * Get company overview including business description, sector, and key metrics
46
+ *
47
+ * @param symbol - Stock symbol (e.g., "US:AAPL", "HK:0700")
48
+ */
49
+ async overview(symbol) {
50
+ return this.client.post("/v1/stock/company-overview", {
51
+ symbol
52
+ });
53
+ }
54
+ /**
55
+ * Get list of major shareholders
56
+ *
57
+ * @param symbol - Stock symbol
58
+ */
59
+ async shareholders(symbol) {
60
+ const response = await this.client.post(
61
+ "/v1/stock/company-shareholders",
62
+ { symbol }
63
+ );
64
+ return Array.isArray(response) ? response : response.shareholders || [];
65
+ }
66
+ // ===========================================================================
67
+ // Financial Statements
68
+ // ===========================================================================
69
+ /**
70
+ * Get income statement data
71
+ *
72
+ * @param symbol - Stock symbol
73
+ * @param options.period - "annual" or "quarterly"
74
+ * @param options.limit - Number of periods to return
75
+ */
76
+ async incomeStatement(symbol, options = {}) {
77
+ const response = await this.client.post(
78
+ "/v1/stock/company-income-statement",
79
+ {
80
+ symbol,
81
+ period: options.period || "annual",
82
+ limit: options.limit || 10
83
+ }
84
+ );
85
+ return this.normalizeArrayResponse(response);
86
+ }
87
+ /**
88
+ * Get balance sheet data
89
+ *
90
+ * @param symbol - Stock symbol
91
+ * @param options.period - "annual" or "quarterly"
92
+ * @param options.limit - Number of periods to return
93
+ */
94
+ async balanceSheet(symbol, options = {}) {
95
+ const response = await this.client.post(
96
+ "/v1/stock/company-balance-sheet",
97
+ {
98
+ symbol,
99
+ period: options.period || "annual",
100
+ limit: options.limit || 10
101
+ }
102
+ );
103
+ return this.normalizeArrayResponse(response);
104
+ }
105
+ /**
106
+ * Get cash flow statement data
107
+ *
108
+ * @param symbol - Stock symbol
109
+ * @param options.period - "annual" or "quarterly"
110
+ * @param options.limit - Number of periods to return
111
+ */
112
+ async cashflowStatement(symbol, options = {}) {
113
+ const response = await this.client.post(
114
+ "/v1/stock/company-cashflow-statement",
115
+ {
116
+ symbol,
117
+ period: options.period || "annual",
118
+ limit: options.limit || 10
119
+ }
120
+ );
121
+ return this.normalizeArrayResponse(response);
122
+ }
123
+ /**
124
+ * Get revenue breakdown by segment, product, or region
125
+ *
126
+ * @param symbol - Stock symbol
127
+ * @param options.breakdownType - Type of breakdown
128
+ */
129
+ async revenueBreakdown(symbol, options = {}) {
130
+ const response = await this.client.post(
131
+ "/v1/stock/company-revenue-breakdown",
132
+ {
133
+ symbol,
134
+ breakdown_type: options.breakdownType || "segment"
135
+ }
136
+ );
137
+ return this.normalizeArrayResponse(response);
138
+ }
139
+ // ===========================================================================
140
+ // Price Data
141
+ // ===========================================================================
142
+ /**
143
+ * Get historical stock prices
144
+ *
145
+ * @param symbol - Stock symbol
146
+ * @param options - Query options
147
+ */
148
+ async prices(symbol, options = {}) {
149
+ const response = await this.client.post(
150
+ "/v1/stock/company-prices",
151
+ {
152
+ symbol,
153
+ start_date: options.startDate,
154
+ end_date: options.endDate,
155
+ limit: options.limit || 100
156
+ }
157
+ );
158
+ return this.normalizeArrayResponse(response);
159
+ }
160
+ /**
161
+ * Get K-line (candlestick) data
162
+ *
163
+ * @param symbol - Stock symbol
164
+ * @param options - Query options
165
+ */
166
+ async kline(symbol, options = {}) {
167
+ const response = await this.client.post(
168
+ "/v1/stock/kline",
169
+ {
170
+ symbol,
171
+ interval: options.interval || "1d",
172
+ adjust: options.adjust || "forward",
173
+ start_date: options.startDate,
174
+ end_date: options.endDate,
175
+ limit: options.limit || 100
176
+ }
177
+ );
178
+ return this.normalizeArrayResponse(response);
179
+ }
180
+ /**
181
+ * Get real-time stock quotes
182
+ *
183
+ * @param symbols - Single symbol or array of symbols
184
+ */
185
+ async quote(symbols) {
186
+ const symbolList = Array.isArray(symbols) ? symbols : [symbols];
187
+ const response = await this.client.post(
188
+ "/v1/stock/quote-realtime",
189
+ { symbols: symbolList }
190
+ );
191
+ return this.normalizeArrayResponse(response);
192
+ }
193
+ /**
194
+ * Get stock index prices
195
+ *
196
+ * @param symbol - Index symbol
197
+ * @param options - Query options
198
+ */
199
+ async indexPrices(symbol, options = {}) {
200
+ const response = await this.client.post(
201
+ "/v1/stock/index-prices",
202
+ {
203
+ symbol,
204
+ start_date: options.startDate,
205
+ end_date: options.endDate,
206
+ limit: options.limit || 100
207
+ }
208
+ );
209
+ return this.normalizeArrayResponse(response);
210
+ }
211
+ // ===========================================================================
212
+ // Screening and Calendar
213
+ // ===========================================================================
214
+ /**
215
+ * Screen stocks based on various criteria
216
+ */
217
+ async screener(options = {}) {
218
+ const response = await this.client.post(
219
+ "/v1/stock/screener",
220
+ {
221
+ market: options.market,
222
+ sector: options.sector,
223
+ min_market_cap: options.minMarketCap,
224
+ max_market_cap: options.maxMarketCap,
225
+ min_pe: options.minPe,
226
+ max_pe: options.maxPe,
227
+ limit: options.limit || 50
228
+ }
229
+ );
230
+ return this.normalizeArrayResponse(response);
231
+ }
232
+ /**
233
+ * Get earnings announcement calendar
234
+ */
235
+ async earningsCalendar(options = {}) {
236
+ const response = await this.client.post(
237
+ "/v1/stock/earnings-calendar",
238
+ {
239
+ area: options.area || "us",
240
+ start_date: options.startDate,
241
+ end_date: options.endDate,
242
+ symbol: options.symbol
243
+ }
244
+ );
245
+ return this.normalizeArrayResponse(response);
246
+ }
247
+ /**
248
+ * Get Hong Kong IPO calendar
249
+ */
250
+ async ipoCalendarHK(status = "Filing") {
251
+ const response = await this.client.post(
252
+ "/v1/stock/ipo-calendar-hk",
253
+ { status }
254
+ );
255
+ return this.normalizeArrayResponse(response);
256
+ }
257
+ // ===========================================================================
258
+ // Helper Methods
259
+ // ===========================================================================
260
+ normalizeArrayResponse(response) {
261
+ if (Array.isArray(response)) {
262
+ return response;
263
+ }
264
+ if ("data" in response) {
265
+ return response.data;
266
+ }
267
+ if ("items" in response) {
268
+ return response.items;
269
+ }
270
+ if ("records" in response) {
271
+ return response.records;
272
+ }
273
+ return [];
274
+ }
275
+ };
276
+
277
+ // src/timeline.ts
278
+ var TimelineModule = class {
279
+ constructor(client) {
280
+ this.client = client;
281
+ }
282
+ /**
283
+ * Get timeline for followed companies
284
+ *
285
+ * Returns recent content related to companies the user is following.
286
+ *
287
+ * @param options.num - Number of items to return (default: 10, max: 100)
288
+ */
289
+ async companies(options = {}) {
290
+ const response = await this.client.post(
291
+ "/v1/tools/timeline/companies",
292
+ { num: options.num || 10 }
293
+ );
294
+ return response.docs || [];
295
+ }
296
+ /**
297
+ * Get timeline for followed topics
298
+ *
299
+ * Returns recent content related to custom topics the user is following.
300
+ *
301
+ * @param options.num - Number of items to return
302
+ */
303
+ async topics(options = {}) {
304
+ const response = await this.client.post(
305
+ "/v1/tools/timeline/topics",
306
+ { num: options.num || 10 }
307
+ );
308
+ return response.docs || [];
309
+ }
310
+ /**
311
+ * Get timeline for followed professional institutes
312
+ *
313
+ * Returns recent content from research institutions, banks, etc.
314
+ *
315
+ * @param options.num - Number of items to return
316
+ */
317
+ async institutes(options = {}) {
318
+ const response = await this.client.post(
319
+ "/v1/tools/timeline/institutes",
320
+ { num: options.num || 10 }
321
+ );
322
+ return response.docs || [];
323
+ }
324
+ /**
325
+ * Get timeline for followed public media
326
+ *
327
+ * Returns recent content from public media accounts.
328
+ *
329
+ * @param options.num - Number of items to return
330
+ */
331
+ async publicMedia(options = {}) {
332
+ const response = await this.client.post(
333
+ "/v1/tools/timeline/public-media",
334
+ { num: options.num || 10 }
335
+ );
336
+ return response.docs || [];
337
+ }
338
+ /**
339
+ * Get timeline for followed social media
340
+ *
341
+ * Returns recent content from social media accounts.
342
+ *
343
+ * @param options.num - Number of items to return
344
+ */
345
+ async socialMedia(options = {}) {
346
+ const response = await this.client.post(
347
+ "/v1/tools/timeline/social-media",
348
+ { num: options.num || 10 }
349
+ );
350
+ return response.docs || [];
351
+ }
352
+ };
353
+
354
+ // src/kb.ts
355
+ var KBModule = class {
356
+ constructor(client) {
357
+ this.client = client;
358
+ }
359
+ /**
360
+ * Search user's knowledge base
361
+ *
362
+ * Performs semantic search across documents the user has uploaded.
363
+ *
364
+ * @param query - Search query string
365
+ * @param options - Search options
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * const results = await client.kb.search('quarterly revenue', { num: 5 });
370
+ * results.forEach(chunk => console.log(chunk.content));
371
+ * ```
372
+ */
373
+ async search(query, options = {}) {
374
+ const response = await this.client.post(
375
+ "/v1/tools/kb/search",
376
+ {
377
+ query,
378
+ folder_ids: options.folderIds,
379
+ doc_ids: options.docIds,
380
+ start_date: options.startDate,
381
+ end_date: options.endDate,
382
+ num: options.num || 10
383
+ }
384
+ );
385
+ return response.chunks || [];
386
+ }
387
+ };
388
+
389
+ // src/docs.ts
390
+ var DocsModule = class {
391
+ constructor(client) {
392
+ this.client = client;
393
+ }
394
+ /**
395
+ * Get document content and metadata
396
+ *
397
+ * @param docId - Document ID
398
+ */
399
+ async get(docId) {
400
+ return this.client.get(`/v1/docs/${docId}`);
401
+ }
402
+ /**
403
+ * Get document summary
404
+ *
405
+ * @param docId - Document ID
406
+ */
407
+ async summary(docId) {
408
+ return this.client.get(`/v1/docs/${docId}/summary`);
409
+ }
410
+ /**
411
+ * Get raw document content
412
+ *
413
+ * @param docId - Document ID
414
+ */
415
+ async rawContent(docId) {
416
+ return this.client.get(`/v1/docs/${docId}/raw-content`);
417
+ }
418
+ /**
419
+ * List documents with filters
420
+ *
421
+ * @param options - Filter options
422
+ */
423
+ async list(options = {}) {
424
+ const response = await this.client.post("/v1/docs", {
425
+ symbols: options.symbols,
426
+ categories: options.categories,
427
+ start_date: options.startDate,
428
+ end_date: options.endDate,
429
+ page_num: options.page || 1,
430
+ page_size: options.pageSize || 20
431
+ });
432
+ return {
433
+ items: response.docs || [],
434
+ total: response.total || 0,
435
+ page: response.page_num || 1,
436
+ pageSize: response.page_size || 20
437
+ };
438
+ }
439
+ /**
440
+ * Search document chunks semantically
441
+ *
442
+ * @param query - Search query string
443
+ * @param options - Search options
444
+ */
445
+ async searchChunks(query, options = {}) {
446
+ const response = await this.client.post("/v1/search/chunks", {
447
+ query,
448
+ symbols: options.symbols,
449
+ categories: options.categories,
450
+ start_date: options.startDate,
451
+ end_date: options.endDate,
452
+ num: options.num || 10
453
+ });
454
+ return response.chunks || [];
455
+ }
456
+ };
457
+
458
+ // src/types.ts
459
+ var ReportifyError = class extends Error {
460
+ statusCode;
461
+ constructor(message, statusCode) {
462
+ super(message);
463
+ this.name = "ReportifyError";
464
+ this.statusCode = statusCode;
465
+ }
466
+ };
467
+ var AuthenticationError = class extends ReportifyError {
468
+ constructor(message = "Invalid or missing API key") {
469
+ super(message, 401);
470
+ this.name = "AuthenticationError";
471
+ }
472
+ };
473
+ var RateLimitError = class extends ReportifyError {
474
+ constructor(message = "Rate limit exceeded") {
475
+ super(message, 429);
476
+ this.name = "RateLimitError";
477
+ }
478
+ };
479
+ var NotFoundError = class extends ReportifyError {
480
+ constructor(message = "Resource not found") {
481
+ super(message, 404);
482
+ this.name = "NotFoundError";
483
+ }
484
+ };
485
+ var APIError = class extends ReportifyError {
486
+ constructor(message, statusCode) {
487
+ super(message, statusCode);
488
+ this.name = "APIError";
489
+ }
490
+ };
491
+
492
+ // src/client.ts
493
+ var DEFAULT_BASE_URL = "https://api.reportify.cn";
494
+ var DEFAULT_TIMEOUT = 3e4;
495
+ var Reportify = class {
496
+ apiKey;
497
+ baseUrl;
498
+ timeout;
499
+ // Sub-modules
500
+ stock;
501
+ timeline;
502
+ kb;
503
+ docs;
504
+ constructor(config) {
505
+ if (!config.apiKey) {
506
+ throw new AuthenticationError("API key is required");
507
+ }
508
+ this.apiKey = config.apiKey;
509
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
510
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
511
+ this.stock = new StockModule(this);
512
+ this.timeline = new TimelineModule(this);
513
+ this.kb = new KBModule(this);
514
+ this.docs = new DocsModule(this);
515
+ }
516
+ /**
517
+ * Make an HTTP request to the API
518
+ */
519
+ async request(method, path, options = {}) {
520
+ const url = new URL(path, this.baseUrl);
521
+ if (options.params) {
522
+ Object.entries(options.params).forEach(([key, value]) => {
523
+ if (value !== void 0 && value !== null) {
524
+ url.searchParams.set(key, String(value));
525
+ }
526
+ });
527
+ }
528
+ const controller = new AbortController();
529
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
530
+ try {
531
+ const response = await fetch(url.toString(), {
532
+ method,
533
+ headers: {
534
+ Authorization: `Bearer ${this.apiKey}`,
535
+ "Content-Type": "application/json",
536
+ "User-Agent": "reportify-sdk-js/0.1.0"
537
+ },
538
+ body: options.body ? JSON.stringify(options.body) : void 0,
539
+ signal: controller.signal
540
+ });
541
+ clearTimeout(timeoutId);
542
+ if (response.status === 401) {
543
+ throw new AuthenticationError();
544
+ }
545
+ if (response.status === 429) {
546
+ throw new RateLimitError();
547
+ }
548
+ if (response.status === 404) {
549
+ throw new NotFoundError();
550
+ }
551
+ if (!response.ok) {
552
+ let errorMessage = response.statusText;
553
+ try {
554
+ const errorData = await response.json();
555
+ errorMessage = errorData.detail || errorData.message || errorMessage;
556
+ } catch {
557
+ }
558
+ throw new APIError(errorMessage, response.status);
559
+ }
560
+ return response.json();
561
+ } catch (error) {
562
+ clearTimeout(timeoutId);
563
+ if (error instanceof Error && error.name === "AbortError") {
564
+ throw new APIError("Request timeout", 408);
565
+ }
566
+ throw error;
567
+ }
568
+ }
569
+ /**
570
+ * Make a GET request
571
+ */
572
+ async get(path, params) {
573
+ return this.request("GET", path, { params });
574
+ }
575
+ /**
576
+ * Make a POST request
577
+ */
578
+ async post(path, body) {
579
+ return this.request("POST", path, { body });
580
+ }
581
+ // ===========================================================================
582
+ // Search Methods
583
+ // ===========================================================================
584
+ /**
585
+ * Search documents across all categories
586
+ *
587
+ * @param query - Search query string
588
+ * @param options - Search options
589
+ * @returns List of matching documents
590
+ *
591
+ * @example
592
+ * ```typescript
593
+ * const docs = await client.search('Tesla earnings', { num: 10 });
594
+ * docs.forEach(doc => console.log(doc.title));
595
+ * ```
596
+ */
597
+ async search(query, options = {}) {
598
+ const response = await this.post("/v2/search", {
599
+ query,
600
+ num: options.num || 10,
601
+ categories: options.categories,
602
+ symbols: options.symbols,
603
+ start_date: options.startDate,
604
+ end_date: options.endDate
605
+ });
606
+ return response.docs || [];
607
+ }
608
+ /**
609
+ * Search news articles
610
+ */
611
+ async searchNews(query, options = {}) {
612
+ const response = await this.post("/v2/search/news", {
613
+ query,
614
+ num: options.num || 10,
615
+ symbols: options.symbols,
616
+ start_date: options.startDate,
617
+ end_date: options.endDate
618
+ });
619
+ return response.docs || [];
620
+ }
621
+ /**
622
+ * Search research reports
623
+ */
624
+ async searchReports(query, options = {}) {
625
+ const response = await this.post("/v2/search/reports", {
626
+ query,
627
+ num: options.num || 10,
628
+ symbols: options.symbols,
629
+ start_date: options.startDate,
630
+ end_date: options.endDate
631
+ });
632
+ return response.docs || [];
633
+ }
634
+ /**
635
+ * Search company filings
636
+ */
637
+ async searchFilings(query, options = {}) {
638
+ const response = await this.post("/v2/search/filings", {
639
+ query,
640
+ num: options.num || 10,
641
+ symbols: options.symbols,
642
+ start_date: options.startDate,
643
+ end_date: options.endDate
644
+ });
645
+ return response.docs || [];
646
+ }
647
+ /**
648
+ * Search earnings call transcripts
649
+ */
650
+ async searchTranscripts(query, options = {}) {
651
+ const response = await this.post("/v2/search/conference-calls", {
652
+ query,
653
+ num: options.num || 10,
654
+ symbols: options.symbols,
655
+ start_date: options.startDate,
656
+ end_date: options.endDate
657
+ });
658
+ return response.docs || [];
659
+ }
660
+ };
661
+ // Annotate the CommonJS export names for ESM import in node:
662
+ 0 && (module.exports = {
663
+ APIError,
664
+ AuthenticationError,
665
+ DocsModule,
666
+ KBModule,
667
+ NotFoundError,
668
+ RateLimitError,
669
+ Reportify,
670
+ ReportifyError,
671
+ StockModule,
672
+ TimelineModule
673
+ });