feat: add releases widget (#2497)

Co-authored-by: Andre Silva <asilva01@acuitysso.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
This commit is contained in:
Andre Silva
2025-04-25 19:49:32 +01:00
committed by GitHub
parent d97e74047d
commit 3dcee8cb86
19 changed files with 2068 additions and 7 deletions

View File

@@ -12,6 +12,7 @@ import { minecraftRouter } from "./minecraft";
import { networkControllerRouter } from "./network-controller";
import { notebookRouter } from "./notebook";
import { optionsRouter } from "./options";
import { releasesRouter } from "./releases";
import { rssFeedRouter } from "./rssFeed";
import { smartHomeRouter } from "./smart-home";
import { stockPriceRouter } from "./stocks";
@@ -34,5 +35,6 @@ export const widgetRouter = createTRPCRouter({
mediaTranscoding: mediaTranscodingRouter,
minecraft: minecraftRouter,
options: optionsRouter,
releases: releasesRouter,
networkController: networkControllerRouter,
});

View File

@@ -0,0 +1,53 @@
import { escapeForRegEx } from "@tiptap/react";
import { z } from "zod";
import { releasesRequestHandler } from "@homarr/request-handler/releases";
import { createTRPCRouter, publicProcedure } from "../../trpc";
const formatVersionFilterRegex = (versionFilter: z.infer<typeof _releaseVersionFilterSchema> | undefined) => {
if (!versionFilter) return undefined;
const escapedPrefix = versionFilter.prefix ? escapeForRegEx(versionFilter.prefix) : "";
const precision = "[0-9]+\\.".repeat(versionFilter.precision).slice(0, -2);
const escapedSuffix = versionFilter.suffix ? escapeForRegEx(versionFilter.suffix) : "";
return `^${escapedPrefix}${precision}${escapedSuffix}$`;
};
const _releaseVersionFilterSchema = z.object({
prefix: z.string().optional(),
precision: z.number(),
suffix: z.string().optional(),
});
export const releasesRouter = createTRPCRouter({
getLatest: publicProcedure
.input(
z.object({
repositories: z.array(
z.object({
providerKey: z.string(),
identifier: z.string(),
versionFilter: _releaseVersionFilterSchema.optional(),
}),
),
}),
)
.query(async ({ input }) => {
const result = await Promise.all(
input.repositories.map(async (repository) => {
const innerHandler = releasesRequestHandler.handler({
providerKey: repository.providerKey,
identifier: repository.identifier,
versionRegex: formatVersionFilterRegex(repository.versionFilter),
});
return await innerHandler.getCachedOrUpdatedDataAsync({
forceUpdate: false,
});
}),
);
return result;
}),
});