feat: add calendar widget (#663)

* feat: add calendar widget

* feat: add artifacts to gitignore
This commit is contained in:
Manuel
2024-07-02 12:13:13 +02:00
committed by GitHub
parent 83ee03b192
commit dba97a3bd6
37 changed files with 707 additions and 9 deletions

View File

@@ -49,6 +49,7 @@ export const createManyIntegrationMiddleware = <TKind extends IntegrationKind>(.
where: and(inArray(integrations.id, input.integrationIds), inArray(integrations.kind, kinds)),
with: {
secrets: true,
items: true,
},
});
@@ -74,3 +75,49 @@ export const createManyIntegrationMiddleware = <TKind extends IntegrationKind>(.
});
});
};
export const createManyIntegrationOfOneItemMiddleware = <TKind extends IntegrationKind>(...kinds: TKind[]) => {
return publicProcedure
.input(z.object({ integrationIds: z.array(z.string()).min(1), itemId: z.string() }))
.use(async ({ ctx, input, next }) => {
const dbIntegrations = await ctx.db.query.integrations.findMany({
where: and(inArray(integrations.id, input.integrationIds), inArray(integrations.kind, kinds)),
with: {
secrets: true,
items: true,
},
});
const offset = input.integrationIds.length - dbIntegrations.length;
if (offset !== 0) {
throw new TRPCError({
code: "NOT_FOUND",
message: `${offset} of the specified integrations not found or not of kinds ${kinds.join(",")}`,
});
}
const dbIntegrationWithItem = dbIntegrations.filter((integration) =>
integration.items.some((item) => item.itemId === input.itemId),
);
if (dbIntegrationWithItem.length === 0) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Integration for item was not found",
});
}
return next({
ctx: {
integrations: dbIntegrationWithItem.map(({ secrets, kind, ...rest }) => ({
...rest,
kind: kind as TKind,
decryptedSecrets: secrets.map((secret) => ({
...secret,
value: decryptSecret(secret.value),
})),
})),
},
});
});
};

View File

@@ -0,0 +1,20 @@
import type { CalendarEvent } from "@homarr/integrations/types";
import { createItemWithIntegrationChannel } from "@homarr/redis";
import { createManyIntegrationOfOneItemMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
export const calendarRouter = createTRPCRouter({
findAllEvents: publicProcedure
.unstable_concat(createManyIntegrationOfOneItemMiddleware("sonarr", "radarr", "readarr", "lidarr"))
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.flatMap(async (integration) => {
for (const item of integration.items) {
const cache = createItemWithIntegrationChannel<CalendarEvent[]>(item.itemId, integration.id);
return await cache.getAsync();
}
}),
);
}),
});

View File

@@ -1,5 +1,6 @@
import { createTRPCRouter } from "../../trpc";
import { appRouter } from "./app";
import { calendarRouter } from "./calendar";
import { dnsHoleRouter } from "./dns-hole";
import { notebookRouter } from "./notebook";
import { smartHomeRouter } from "./smart-home";
@@ -11,4 +12,5 @@ export const widgetRouter = createTRPCRouter({
app: appRouter,
dnsHole: dnsHoleRouter,
smartHome: smartHomeRouter,
calendar: calendarRouter,
});