feat: stock price widget (#2579)
* feat: added stock price widget * fix: formatting * fix: broken lock file * fix: requested changes * fix: added parsing schema * fix: improve time range and interval inputs * fix: only return required data * fix: formatting * fix: deepsource tests * fix: moved all time frames into one location * fix: formatting * fix: requested changes * fix: formatting * fix: parse response data * fix: update packages * fix: typescript issues * fix: formatting * fix: broken lockfile --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
58
packages/request-handler/src/stock-price.ts
Normal file
58
packages/request-handler/src/stock-price.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import dayjs from "dayjs";
|
||||
import { z } from "zod";
|
||||
|
||||
import { fetchWithTimeout } from "@homarr/common";
|
||||
|
||||
import { createCachedWidgetRequestHandler } from "./lib/cached-widget-request-handler";
|
||||
|
||||
export const fetchStockPriceHandler = createCachedWidgetRequestHandler({
|
||||
queryKey: "fetchStockPriceResult",
|
||||
widgetKind: "stockPrice",
|
||||
async requestAsync(input: { stock: string; timeRange: string; timeInterval: string }) {
|
||||
const response = await fetchWithTimeout(
|
||||
`https://query1.finance.yahoo.com/v8/finance/chart/${input.stock}?range=${input.timeRange}&interval=${input.timeInterval}`,
|
||||
);
|
||||
const data = dataSchema.parse(await response.json());
|
||||
|
||||
if ("error" in data) {
|
||||
throw new Error(data.error.description);
|
||||
}
|
||||
if (data.chart.result.length !== 1) {
|
||||
throw new Error("Received multiple results");
|
||||
}
|
||||
if (!data.chart.result[0]) {
|
||||
throw new Error("Received invalid data");
|
||||
}
|
||||
|
||||
return data.chart.result[0];
|
||||
},
|
||||
cacheDuration: dayjs.duration(5, "minutes"),
|
||||
});
|
||||
|
||||
const dataSchema = z
|
||||
.object({
|
||||
error: z.object({
|
||||
description: z.string(),
|
||||
}),
|
||||
})
|
||||
.or(
|
||||
z.object({
|
||||
chart: z.object({
|
||||
result: z.array(
|
||||
z.object({
|
||||
indicators: z.object({
|
||||
quote: z.array(
|
||||
z.object({
|
||||
close: z.array(z.number()),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
meta: z.object({
|
||||
symbol: z.string(),
|
||||
shortName: z.string(),
|
||||
}),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user