laplace-api 5.2.3 → 5.3.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/package.json +1 -1
- package/src/client/news.ts +54 -12
- package/src/test/news.test.ts +92 -29
package/package.json
CHANGED
package/src/client/news.ts
CHANGED
|
@@ -22,6 +22,23 @@ export enum NewsType {
|
|
|
22
22
|
|
|
23
23
|
export enum NewsOrderBy {
|
|
24
24
|
TIMESTAMP = "timestamp",
|
|
25
|
+
QUALITY_SCORE = "quality_score",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface GetNewsV2Params {
|
|
29
|
+
newsType?: NewsType;
|
|
30
|
+
orderBy?: NewsOrderBy;
|
|
31
|
+
orderByDirection?: SortDirection;
|
|
32
|
+
symbols?: string;
|
|
33
|
+
categories?: string;
|
|
34
|
+
sectors?: string;
|
|
35
|
+
industries?: string;
|
|
36
|
+
qualityScoreMin?: number;
|
|
37
|
+
qualityScoreMax?: number;
|
|
38
|
+
timestampFrom?: string;
|
|
39
|
+
timestampTo?: string;
|
|
40
|
+
page?: number;
|
|
41
|
+
size?: number;
|
|
25
42
|
}
|
|
26
43
|
|
|
27
44
|
export interface News {
|
|
@@ -80,6 +97,11 @@ export interface NewsIndustry {
|
|
|
80
97
|
meanType: number;
|
|
81
98
|
}
|
|
82
99
|
|
|
100
|
+
export interface NewsCategory {
|
|
101
|
+
id: string;
|
|
102
|
+
name: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
83
105
|
export class NewsClient extends Client {
|
|
84
106
|
async getHighlights(
|
|
85
107
|
region: Region,
|
|
@@ -96,6 +118,16 @@ export class NewsClient extends Client {
|
|
|
96
118
|
}
|
|
97
119
|
|
|
98
120
|
|
|
121
|
+
async getNewsCategories(locale?: Locale): Promise<NewsCategory[]> {
|
|
122
|
+
return this.sendRequest<NewsCategory[]>({
|
|
123
|
+
method: "GET",
|
|
124
|
+
url: "/api/v1/news/categories",
|
|
125
|
+
params: {
|
|
126
|
+
...(locale != null && { locale }),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
99
131
|
async getNews(
|
|
100
132
|
region: Region,
|
|
101
133
|
locale: Locale,
|
|
@@ -127,22 +159,32 @@ export class NewsClient extends Client {
|
|
|
127
159
|
async getNewsV2(
|
|
128
160
|
region: Region,
|
|
129
161
|
locale: Locale,
|
|
130
|
-
|
|
131
|
-
page?: number,
|
|
132
|
-
size?: number,
|
|
133
|
-
orderBy?: NewsOrderBy,
|
|
134
|
-
orderByDirection?: SortDirection,
|
|
135
|
-
extraFilters?: string
|
|
162
|
+
options?: GetNewsV2Params
|
|
136
163
|
): Promise<PaginatedResponse<NewsV2>> {
|
|
137
164
|
const params = {
|
|
138
165
|
region,
|
|
139
166
|
locale,
|
|
140
|
-
...(newsType != null && { newsType }),
|
|
141
|
-
...(
|
|
142
|
-
...(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
...(
|
|
167
|
+
...(options?.newsType != null && { newsType: options.newsType }),
|
|
168
|
+
...(options?.orderBy != null && { orderBy: options.orderBy }),
|
|
169
|
+
...(options?.orderByDirection != null && {
|
|
170
|
+
orderByDirection: options.orderByDirection,
|
|
171
|
+
}),
|
|
172
|
+
...(options?.symbols != null && { symbols: options.symbols }),
|
|
173
|
+
...(options?.categories != null && { categories: options.categories }),
|
|
174
|
+
...(options?.sectors != null && { sectors: options.sectors }),
|
|
175
|
+
...(options?.industries != null && { industries: options.industries }),
|
|
176
|
+
...(options?.qualityScoreMin != null && {
|
|
177
|
+
qualityScoreMin: options.qualityScoreMin,
|
|
178
|
+
}),
|
|
179
|
+
...(options?.qualityScoreMax != null && {
|
|
180
|
+
qualityScoreMax: options.qualityScoreMax,
|
|
181
|
+
}),
|
|
182
|
+
...(options?.timestampFrom != null && {
|
|
183
|
+
timestampFrom: options.timestampFrom,
|
|
184
|
+
}),
|
|
185
|
+
...(options?.timestampTo != null && { timestampTo: options.timestampTo }),
|
|
186
|
+
...(options?.page != null && { page: options.page }),
|
|
187
|
+
...(options?.size != null && { size: options.size }),
|
|
146
188
|
};
|
|
147
189
|
|
|
148
190
|
return this.sendRequest<PaginatedResponse<NewsV2>>({
|
package/src/test/news.test.ts
CHANGED
|
@@ -34,6 +34,13 @@ const mockNewsHighlightsResponse = {
|
|
|
34
34
|
]
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const mockNewsCategoriesResponse = [
|
|
38
|
+
{ id: "13702", name: "General News" },
|
|
39
|
+
{ id: "13703", name: "Sector News" },
|
|
40
|
+
{ id: "13704", name: "Market News" },
|
|
41
|
+
{ id: "13705", name: "Stock Spesific News" }
|
|
42
|
+
];
|
|
43
|
+
|
|
37
44
|
const mockNewsResponse = {
|
|
38
45
|
items: [
|
|
39
46
|
{
|
|
@@ -107,6 +114,17 @@ describe("NewsClient", () => {
|
|
|
107
114
|
if (first != null) expect(typeof first).toBe("string");
|
|
108
115
|
});
|
|
109
116
|
|
|
117
|
+
test("getNewsCategories returns valid data", async () => {
|
|
118
|
+
const resp = await client.getNewsCategories(Locale.En);
|
|
119
|
+
|
|
120
|
+
expect(Array.isArray(resp)).toBe(true);
|
|
121
|
+
expect(resp.length).toBeGreaterThan(0);
|
|
122
|
+
|
|
123
|
+
const c = resp[0];
|
|
124
|
+
expect(typeof c.id).toBe("string");
|
|
125
|
+
expect(typeof c.name).toBe("string");
|
|
126
|
+
});
|
|
127
|
+
|
|
110
128
|
test("getNews returns valid paginated data", async () => {
|
|
111
129
|
const resp = await client.getNews(
|
|
112
130
|
Region.Us,
|
|
@@ -197,15 +215,13 @@ describe("NewsClient", () => {
|
|
|
197
215
|
});
|
|
198
216
|
|
|
199
217
|
test("getNewsV2 returns valid paginated data", async () => {
|
|
200
|
-
const resp = await client.getNewsV2(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
SortDirection.Desc
|
|
208
|
-
);
|
|
218
|
+
const resp = await client.getNewsV2(Region.Us, Locale.Tr, {
|
|
219
|
+
newsType: NewsType.BRIEFS,
|
|
220
|
+
page: 0,
|
|
221
|
+
size: 10,
|
|
222
|
+
orderBy: NewsOrderBy.TIMESTAMP,
|
|
223
|
+
orderByDirection: SortDirection.Desc,
|
|
224
|
+
});
|
|
209
225
|
|
|
210
226
|
expect(resp).toBeDefined();
|
|
211
227
|
expect(typeof resp.recordCount).toBe("number");
|
|
@@ -300,6 +316,42 @@ describe("NewsClient", () => {
|
|
|
300
316
|
});
|
|
301
317
|
});
|
|
302
318
|
|
|
319
|
+
describe("getNewsCategories", () => {
|
|
320
|
+
test("calls correct endpoint/params and matches raw response", async () => {
|
|
321
|
+
cli.request.mockResolvedValueOnce({ data: mockNewsCategoriesResponse });
|
|
322
|
+
|
|
323
|
+
const resp = await client.getNewsCategories(Locale.En);
|
|
324
|
+
|
|
325
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
326
|
+
const call = cli.request.mock.calls[0][0];
|
|
327
|
+
|
|
328
|
+
expect(call.method).toBe("GET");
|
|
329
|
+
expect(call.url).toBe("/api/v1/news/categories");
|
|
330
|
+
expect(call.params).toEqual({ locale: Locale.En });
|
|
331
|
+
|
|
332
|
+
expect(resp).toEqual(mockNewsCategoriesResponse);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test("does not send locale when undefined", async () => {
|
|
336
|
+
cli.request.mockResolvedValueOnce({ data: mockNewsCategoriesResponse });
|
|
337
|
+
|
|
338
|
+
await client.getNewsCategories();
|
|
339
|
+
|
|
340
|
+
const call = cli.request.mock.calls[0][0];
|
|
341
|
+
expect(call.params).toEqual({});
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
test("bubbles up request error", async () => {
|
|
345
|
+
cli.request.mockRejectedValueOnce(new Error("Failed to fetch categories"));
|
|
346
|
+
|
|
347
|
+
await expect(client.getNewsCategories(Locale.En)).rejects.toThrow(
|
|
348
|
+
"Failed to fetch categories"
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
303
355
|
describe("getNews", () => {
|
|
304
356
|
test("calls correct endpoint/params and matches raw response", async () => {
|
|
305
357
|
cli.request.mockResolvedValueOnce({ data: mockNewsResponse });
|
|
@@ -406,16 +458,21 @@ describe("NewsClient", () => {
|
|
|
406
458
|
test("calls correct endpoint/params and matches raw response", async () => {
|
|
407
459
|
cli.request.mockResolvedValueOnce({ data: mockNewsV2Response });
|
|
408
460
|
|
|
409
|
-
const resp = await client.getNewsV2(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
461
|
+
const resp = await client.getNewsV2(Region.Tr, Locale.Tr, {
|
|
462
|
+
newsType: NewsType.BRIEFS,
|
|
463
|
+
page: 1,
|
|
464
|
+
size: 10,
|
|
465
|
+
orderBy: NewsOrderBy.TIMESTAMP,
|
|
466
|
+
orderByDirection: SortDirection.Desc,
|
|
467
|
+
symbols: "AAPL,MSFT",
|
|
468
|
+
categories: "Sector News",
|
|
469
|
+
sectors: "Technology",
|
|
470
|
+
industries: "Software",
|
|
471
|
+
qualityScoreMin: 7,
|
|
472
|
+
qualityScoreMax: 10,
|
|
473
|
+
timestampFrom: "2026-05-01",
|
|
474
|
+
timestampTo: "2026-06-01",
|
|
475
|
+
});
|
|
419
476
|
|
|
420
477
|
expect(cli.request).toHaveBeenCalledTimes(1);
|
|
421
478
|
const call = cli.request.mock.calls[0][0];
|
|
@@ -429,7 +486,15 @@ describe("NewsClient", () => {
|
|
|
429
486
|
page: 1,
|
|
430
487
|
size: 10,
|
|
431
488
|
orderBy: NewsOrderBy.TIMESTAMP,
|
|
432
|
-
orderByDirection: SortDirection.Desc
|
|
489
|
+
orderByDirection: SortDirection.Desc,
|
|
490
|
+
symbols: "AAPL,MSFT",
|
|
491
|
+
categories: "Sector News",
|
|
492
|
+
sectors: "Technology",
|
|
493
|
+
industries: "Software",
|
|
494
|
+
qualityScoreMin: 7,
|
|
495
|
+
qualityScoreMax: 10,
|
|
496
|
+
timestampFrom: "2026-05-01",
|
|
497
|
+
timestampTo: "2026-06-01",
|
|
433
498
|
});
|
|
434
499
|
|
|
435
500
|
expect(resp.recordCount).toBe(352);
|
|
@@ -457,15 +522,13 @@ describe("NewsClient", () => {
|
|
|
457
522
|
cli.request.mockRejectedValueOnce(new Error("Failed to fetch news v2"));
|
|
458
523
|
|
|
459
524
|
await expect(
|
|
460
|
-
client.getNewsV2(
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
SortDirection.Desc
|
|
468
|
-
)
|
|
525
|
+
client.getNewsV2(Region.Tr, Locale.Tr, {
|
|
526
|
+
newsType: NewsType.REUTERS,
|
|
527
|
+
page: 0,
|
|
528
|
+
size: 10,
|
|
529
|
+
orderBy: NewsOrderBy.TIMESTAMP,
|
|
530
|
+
orderByDirection: SortDirection.Desc,
|
|
531
|
+
})
|
|
469
532
|
).rejects.toThrow("Failed to fetch news v2");
|
|
470
533
|
|
|
471
534
|
expect(cli.request).toHaveBeenCalledTimes(1);
|