laplace-api 4.0.0 โ†’ 4.2.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.
@@ -0,0 +1,37 @@
1
+ name: Publish Package to NPM
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+
13
+ - name: Use Node.js
14
+ uses: actions/setup-node@v4
15
+ with:
16
+ node-version: '20.x'
17
+ registry-url: 'https://registry.npmjs.org'
18
+ cache: 'npm'
19
+
20
+ - name: Update version in package.json
21
+ run: |
22
+ # Get version from GitHub release tag
23
+ VERSION=${GITHUB_REF_NAME#v}
24
+ echo "Updating to version: $VERSION"
25
+ # Update package.json version
26
+ npm version $VERSION --no-git-tag-version --allow-same-version
27
+
28
+ - name: Install dependencies
29
+ run: npm ci
30
+
31
+ - name: Build
32
+ run: npm run build --if-present
33
+
34
+ - name: Publish to NPM
35
+ run: npm publish --access public
36
+ env:
37
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,25 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ node-version: [18.x, 20.x]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Use Node.js ${{ matrix.node-version }}
19
+ uses: actions/setup-node@v4
20
+ with:
21
+ node-version: ${{ matrix.node-version }}
22
+ cache: 'npm'
23
+ - run: npm ci
24
+
25
+ - run: npm test -- -t "Mock Tests"
package/README.md CHANGED
@@ -1,2 +1,461 @@
1
- # laplace-api-js
2
- Client library for Laplace API for the US stock market and BIST (Istanbul stock market) fundamental financial data.
1
+ # Laplace TypeScript/JavaScript SDK
2
+
3
+ [![Node.js Version](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
5
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![npm version](https://img.shields.io/npm/v/laplace-api-js.svg)](https://www.npmjs.com/package/laplace-api-js)
7
+
8
+ The official TypeScript/JavaScript SDK for the Laplace stock data platform. Get easy access to stock data, collections, financials, funds, and AI-powered insights.
9
+
10
+ ## Features
11
+
12
+ - ๐Ÿš€ **Easy to use**: Simple, intuitive API with TypeScript/JavaScript idioms
13
+ - ๐Ÿ“Š **Comprehensive data**: Stocks, collections, financials, funds, and AI insights
14
+ - ๐Ÿ”ง **Well-typed**: Full TypeScript type safety with comprehensive interfaces
15
+ - ๐Ÿงช **Well-tested**: Comprehensive test coverage with real API integration
16
+ - ๐ŸŒ **Multi-region**: Support for US and Turkish markets
17
+ - โšก **Fast**: High-performance HTTP requests
18
+ - ๐Ÿ“š **Well-documented**: Complete documentation for all public methods
19
+ - ๐Ÿ”„ **Real-time**: Live price streaming with Server-Sent Events
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install laplace-api-js
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { createClient } from "laplace-api-js";
31
+ import { LaplaceConfiguration } from "laplace-api-js";
32
+ import { Logger } from "winston";
33
+
34
+ // Initialize the client
35
+ const config: LaplaceConfiguration = {
36
+ apiKey: "your-api-key-here",
37
+ baseURL: "https://api.laplace.finfree.co",
38
+ };
39
+
40
+ const logger: Logger = {
41
+ info: console.log,
42
+ error: console.error,
43
+ warn: console.warn,
44
+ debug: console.log,
45
+ } as Logger;
46
+
47
+ const client = createClient(config, logger);
48
+
49
+ // Get stock details
50
+ async function getStockDetails() {
51
+ try {
52
+ const stock = await client.getStockDetailBySymbol(
53
+ "AAPL",
54
+ "equity",
55
+ "us",
56
+ "en"
57
+ );
58
+ console.log(`${stock.name}: ${stock.description}`);
59
+ } catch (error) {
60
+ console.error("Error fetching stock:", error);
61
+ }
62
+ }
63
+
64
+ // Get all stocks in a region
65
+ async function getAllStocks() {
66
+ try {
67
+ const stocks = await client.getAllStocks("us", 1, 10);
68
+ stocks.forEach((stock) => {
69
+ console.log(`${stock.symbol}: ${stock.name}`);
70
+ });
71
+ } catch (error) {
72
+ console.error("Error fetching stocks:", error);
73
+ }
74
+ }
75
+
76
+ // Get collections
77
+ async function getCollections() {
78
+ try {
79
+ const collections = await client.getAllCollections("tr", "en");
80
+ collections.forEach((collection) => {
81
+ console.log(`${collection.title}: ${collection.numStocks} stocks`);
82
+ });
83
+ } catch (error) {
84
+ console.error("Error fetching collections:", error);
85
+ }
86
+ }
87
+
88
+ // Get live price data
89
+ async function getLivePrices() {
90
+ try {
91
+ const liveClient = client.getLivePriceForBIST(["THYAO", "GARAN"]);
92
+
93
+ for await (const data of liveClient.receive()) {
94
+ console.log("Live price:", data);
95
+ break; // Get first data and exit
96
+ }
97
+
98
+ liveClient.close();
99
+ } catch (error) {
100
+ console.error("Error getting live prices:", error);
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## API Reference
106
+
107
+ ### Stocks Client
108
+
109
+ ```typescript
110
+ // Get all stocks with pagination
111
+ const stocks = await client.getAllStocks("us", 1, 10);
112
+
113
+ // Get stock detail by symbol
114
+ const stock = await client.getStockDetailBySymbol("AAPL", "equity", "us", "en");
115
+
116
+ // Get stock detail by ID
117
+ const stock = await client.getStockDetailByID("stock-id", "en");
118
+
119
+ // Get historical prices
120
+ const prices = await client.getHistoricalPrices(["AAPL", "GOOGL"], "us", [
121
+ "1d",
122
+ "1w",
123
+ ]);
124
+
125
+ // Get historical prices with custom interval
126
+ const prices = await client.getCustomHistoricalPrices(
127
+ "AAPL",
128
+ "us",
129
+ "2024-01-01",
130
+ "2024-01-31",
131
+ "1m",
132
+ true
133
+ );
134
+
135
+ // Get tick rules (Turkey only)
136
+ const rules = await client.getTickRules("THYAO", "tr");
137
+
138
+ // Get restrictions (Turkey only)
139
+ const restrictions = await client.getStockRestrictions("THYAO", "tr");
140
+ ```
141
+
142
+ ### Collections Client
143
+
144
+ ```typescript
145
+ // Get all collections
146
+ const collections = await client.getAllCollections("tr", "en");
147
+
148
+ // Get collection detail
149
+ const detail = await client.getCollectionDetail("collection-id", "tr", "en");
150
+
151
+ // Get themes
152
+ const themes = await client.getAllThemes("tr", "en");
153
+
154
+ // Get theme detail
155
+ const themeDetail = await client.getThemeDetail("theme-id", "tr", "en");
156
+
157
+ // Get industries
158
+ const industries = await client.getAllIndustries("tr", "en");
159
+
160
+ // Get industry detail
161
+ const industryDetail = await client.getIndustryDetail(
162
+ "industry-id",
163
+ "tr",
164
+ "en"
165
+ );
166
+
167
+ // Get sectors
168
+ const sectors = await client.getAllSectors("tr", "en");
169
+
170
+ // Get sector detail
171
+ const sectorDetail = await client.getSectorDetail("sector-id", "tr", "en");
172
+ ```
173
+
174
+ ### Funds Client
175
+
176
+ ```typescript
177
+ // Get all funds
178
+ const funds = await client.getFunds("tr", 1, 10);
179
+
180
+ // Get fund statistics
181
+ const stats = await client.getFundStats("fund-symbol", "tr");
182
+
183
+ // Get fund distribution
184
+ const distribution = await client.getFundDistribution("fund-symbol", "tr");
185
+
186
+ // Get historical fund prices
187
+ const prices = await client.getHistoricalFundPrices("fund-symbol", "tr", "1y");
188
+ ```
189
+
190
+ ### Financial Data Client
191
+
192
+ ```typescript
193
+ // Get financial ratios
194
+ const ratios = await client.getHistoricalRatios(
195
+ "AAPL",
196
+ ["pe-ratio"],
197
+ "us",
198
+ "en"
199
+ );
200
+
201
+ // Get financial ratio comparisons
202
+ const comparisons = await client.getFinancialRatioComparison(
203
+ "AAPL",
204
+ "us",
205
+ "sector"
206
+ );
207
+
208
+ // Get stock dividends
209
+ const dividends = await client.getStockDividends("AAPL", "us");
210
+
211
+ // Get stock statistics
212
+ const stats = await client.getStockStats(["AAPL", "GOOGL"], "us");
213
+
214
+ // Get top movers
215
+ const movers = await client.getTopMovers(
216
+ "us",
217
+ 1,
218
+ 10,
219
+ "gainers",
220
+ "stock",
221
+ "equity"
222
+ );
223
+ ```
224
+
225
+ ### Live Price Client
226
+
227
+ ```typescript
228
+ // Get live prices for BIST stocks
229
+ const bistClient = client.getLivePriceForBIST(["THYAO", "GARAN"]);
230
+
231
+ // Get live prices for US stocks
232
+ const usClient = client.getLivePriceForUS(["AAPL", "GOOGL"]);
233
+
234
+ // Receive live data
235
+ for await (const data of bistClient.receive()) {
236
+ console.log("Received BIST data:", data);
237
+ // data.s - symbol, data.p - price, data.ch - change, data.d - date
238
+ }
239
+
240
+ // Subscribe to different symbols
241
+ await bistClient.subscribe(["AKBNK", "EREGL"]);
242
+
243
+ // Close connection
244
+ bistClient.close();
245
+ ```
246
+
247
+ ### Brokers Client
248
+
249
+ ```typescript
250
+ // Get all brokers
251
+ const brokers = await client.getBrokers("tr", 1, 10);
252
+
253
+ // Get market stocks with broker statistics
254
+ const marketStocks = await client.getMarketStocks(
255
+ "tr",
256
+ "netAmount",
257
+ "desc",
258
+ "2024-01-01",
259
+ "2024-01-31",
260
+ 1,
261
+ 10
262
+ );
263
+
264
+ // Get brokers by stock
265
+ const brokersByStock = await client.getBrokersByStock(
266
+ "THYAO",
267
+ "tr",
268
+ "netAmount",
269
+ "desc",
270
+ "2024-01-01",
271
+ "2024-01-31",
272
+ 1,
273
+ 10
274
+ );
275
+ ```
276
+
277
+ ### Search Client
278
+
279
+ ```typescript
280
+ // Search across stocks, collections, sectors, and industries
281
+ const results = await client.search(
282
+ "technology",
283
+ ["stock", "collection"],
284
+ "us",
285
+ "en"
286
+ );
287
+ ```
288
+
289
+ ### WebSocket Client
290
+
291
+ ```typescript
292
+ // Create WebSocket client for real-time data
293
+ const webSocketClient = new LivePriceWebSocketClient();
294
+
295
+ // Connect to WebSocket
296
+ await webSocketClient.connect("ws://example.com/websocket");
297
+
298
+ // Subscribe to live price feeds
299
+ const unsubscribe = webSocketClient.subscribe(
300
+ ["THYAO", "GARAN"],
301
+ "live_price_tr",
302
+ (data) => {
303
+ console.log("Received live data:", data);
304
+ }
305
+ );
306
+
307
+ // Close connection
308
+ await webSocketClient.close();
309
+ ```
310
+
311
+ ### Capital Increase Client
312
+
313
+ ```typescript
314
+ // Get all capital increases
315
+ const increases = await client.getAllCapitalIncreases(1, 10, "tr");
316
+
317
+ // Get capital increases for a specific instrument
318
+ const instrumentIncreases = await client.getCapitalIncreasesForInstrument(
319
+ "THYAO",
320
+ 1,
321
+ 10,
322
+ "tr"
323
+ );
324
+
325
+ // Get active rights for an instrument
326
+ const rights = await client.getActiveRightsForInstrument(
327
+ "THYAO",
328
+ "2024-01-15",
329
+ "tr"
330
+ );
331
+ ```
332
+
333
+ ### Custom Themes Client
334
+
335
+ ```typescript
336
+ // Get all custom themes
337
+ const themes = await client.getAllCustomThemes("en");
338
+
339
+ // Get custom theme detail
340
+ const themeDetail = await client.getCustomThemeDetail("theme-id", "en", null);
341
+
342
+ // Create a custom theme
343
+ const id = await client.createCustomTheme({
344
+ title: { en: "My Tech Portfolio" },
345
+ description: { en: "Technology stocks portfolio" },
346
+ region: ["us"],
347
+ stocks: ["stock-id-1", "stock-id-2"],
348
+ status: "active",
349
+ });
350
+
351
+ // Update a custom theme
352
+ await client.updateCustomTheme(id, {
353
+ title: { en: "Updated Tech Portfolio" },
354
+ stockIds: ["stock-id-1", "stock-id-2"],
355
+ });
356
+
357
+ // Delete a custom theme
358
+ await client.deleteCustomTheme(id);
359
+ ```
360
+
361
+ ### Key Insights Client
362
+
363
+ ```typescript
364
+ // Get key insights for a stock
365
+ const insights = await client.getKeyInsights("AAPL", "us");
366
+ ```
367
+
368
+ ## Supported Regions
369
+
370
+ - **US**: United States stock market
371
+ - **TR**: Turkey stock market (Borsa Istanbul)
372
+
373
+ ## Error Handling
374
+
375
+ ```typescript
376
+ import { createClient } from "laplace-api-js";
377
+ import { LaplaceHTTPError } from "laplace-api-js";
378
+
379
+ const client = createClient(config, logger);
380
+
381
+ try {
382
+ const stock = await client.getStockDetailBySymbol(
383
+ "INVALID",
384
+ "equity",
385
+ "us",
386
+ "en"
387
+ );
388
+ } catch (error) {
389
+ if (error instanceof LaplaceHTTPError) {
390
+ console.log(`API Error: ${error.message}`);
391
+ console.log(`Status Code: ${error.httpStatus}`);
392
+ } else {
393
+ console.log(`Error: ${error}`);
394
+ }
395
+ }
396
+ ```
397
+
398
+ ## Authentication
399
+
400
+ Get your API key from the Laplace platform and initialize the client:
401
+
402
+ ```typescript
403
+ import { createClient } from "laplace-api-js";
404
+ import { LaplaceConfiguration } from "laplace-api-js";
405
+
406
+ const config: LaplaceConfiguration = {
407
+ apiKey: "your-api-key-here",
408
+ baseURL: "https://api.laplace.finfree.co",
409
+ };
410
+
411
+ const client = createClient(config, logger);
412
+ ```
413
+
414
+ ## Configuration
415
+
416
+ You can also load configuration from environment variables:
417
+
418
+ ```typescript
419
+ import { loadGlobal } from "laplace-api-js";
420
+
421
+ const config = loadGlobal();
422
+ const client = createClient(config, logger);
423
+ ```
424
+
425
+ Environment variables:
426
+
427
+ - `API_KEY`: Your API key
428
+ - `BASE_URL`: API base URL
429
+
430
+ ## Development
431
+
432
+ ### Setup
433
+
434
+ ```bash
435
+ git clone https://github.com/Laplace-Analytics/laplace-api-js.git
436
+ cd laplace-api-js
437
+ npm install
438
+ ```
439
+
440
+ ### Building
441
+
442
+ ```bash
443
+ # Build the project
444
+ npm run build
445
+
446
+ # Build with type checking
447
+ npm run build:check
448
+ ```
449
+
450
+ ## Requirements
451
+
452
+ - Node.js 18+
453
+ - TypeScript 5.0+
454
+
455
+ ## Documentation
456
+
457
+ Full API documentation is available at [laplace.finfree.co/en/docs](https://laplace.finfree.co/en/docs)
458
+
459
+ ## License
460
+
461
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "laplace-api",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "Client library for Laplace API for the US stock market and BIST (Istanbul stock market) fundamental financial data.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -24,6 +24,7 @@ export interface Broker {
24
24
  name: string;
25
25
  longName: string;
26
26
  logo: string;
27
+ supportedAssetClasses?: AssetClass[]
27
28
  }
28
29
 
29
30
  export interface BrokerStock {
@@ -55,20 +56,21 @@ export interface BrokerList extends PaginatedResponse<BrokerItem> {
55
56
  }
56
57
 
57
58
  export class BrokerClient extends Client {
58
- private static readonly BASE = "/api/v1/brokers";
59
59
 
60
60
  async getBrokers(
61
61
  region: Region,
62
62
  page: number,
63
- size: number
63
+ size: number,
64
+ assetClass?: AssetClass
64
65
  ): Promise<PaginatedResponse<Broker>> {
65
66
  return this.sendRequest<PaginatedResponse<Broker>>({
66
67
  method: "GET",
67
- url: BrokerClient.BASE,
68
+ url: "/api/v1/brokers",
68
69
  params: {
69
70
  region,
70
71
  page,
71
72
  size,
73
+ assetClass
72
74
  },
73
75
  });
74
76
  }
@@ -84,7 +86,7 @@ export class BrokerClient extends Client {
84
86
  ): Promise<BrokerList> {
85
87
  return this.sendRequest<BrokerList>({
86
88
  method: "GET",
87
- url: BrokerClient.BASE + "/market/stock",
89
+ url: "/api/v1/brokers/market/stock",
88
90
  params: {
89
91
  region,
90
92
  sortBy,
@@ -108,7 +110,7 @@ export class BrokerClient extends Client {
108
110
  ): Promise<BrokerList> {
109
111
  return this.sendRequest<BrokerList>({
110
112
  method: "GET",
111
- url: BrokerClient.BASE + "/market",
113
+ url: "/api/v1/brokers/market",
112
114
  params: {
113
115
  region,
114
116
  sortBy,
@@ -133,7 +135,7 @@ export class BrokerClient extends Client {
133
135
  ): Promise<BrokerList> {
134
136
  return this.sendRequest<BrokerList>({
135
137
  method: "GET",
136
- url: BrokerClient.BASE + "/" + symbol,
138
+ url: `/api/v1/brokers/${symbol}`,
137
139
  params: {
138
140
  symbol,
139
141
  region,
@@ -159,7 +161,7 @@ export class BrokerClient extends Client {
159
161
  ): Promise<BrokerList> {
160
162
  return this.sendRequest<BrokerList>({
161
163
  method: "GET",
162
- url: BrokerClient.BASE + "/stock/" + symbol,
164
+ url: `/api/v1/brokers/stock/${symbol}`,
163
165
  params: {
164
166
  symbol,
165
167
  region,
@@ -1,10 +1,5 @@
1
- import { Client } from './client';
2
- import { Region } from './collections';
3
-
4
- // type PaginatedResponse[T any] struct {
5
- // RecordCount int `json:"recordCount"`
6
- // Items []T `json:"items"`
7
- // }
1
+ import { Client } from "./client";
2
+ import { Region } from "./collections";
8
3
 
9
4
  export interface PaginatedResponse<T> {
10
5
  recordCount: number;
@@ -48,8 +43,8 @@ export class CapitalIncreaseClient extends Client {
48
43
  region: Region
49
44
  ): Promise<PaginatedResponse<CapitalIncrease>> {
50
45
  return this.sendRequest<PaginatedResponse<CapitalIncrease>>({
51
- method: 'GET',
52
- url: '/api/v1/capital-increase/all',
46
+ method: "GET",
47
+ url: "/api/v1/capital-increase/all",
53
48
  params: { region, page, size },
54
49
  });
55
50
  }
@@ -58,11 +53,11 @@ export class CapitalIncreaseClient extends Client {
58
53
  symbol: string,
59
54
  page: number,
60
55
  size: number,
61
- region: Region,
56
+ region: Region
62
57
  ): Promise<PaginatedResponse<CapitalIncrease>> {
63
58
  return this.sendRequest<PaginatedResponse<CapitalIncrease>>({
64
59
  method: 'GET',
65
- url: '/api/v1/capital-increase/' + symbol,
60
+ url: `/api/v1/capital-increase/${symbol}`,
66
61
  params: { region, page, size },
67
62
  });
68
63
  }
@@ -74,7 +69,7 @@ export class CapitalIncreaseClient extends Client {
74
69
  ): Promise<CapitalIncrease[]> {
75
70
  return this.sendRequest<CapitalIncrease[]>({
76
71
  method: 'GET',
77
- url: '/api/v1/rights/active/' + symbol,
72
+ url: `/api/v1/rights/active/${symbol}`,
78
73
  params: { date, region },
79
74
  });
80
75
  }