refactor: replace deprecated unsable_concat with concat for trpc middlewares (#2991)

This commit is contained in:
Meier Lukas
2025-05-01 10:08:41 +02:00
committed by GitHub
parent 547a8c34c5
commit 48aef9e862
23 changed files with 66 additions and 70 deletions

View File

@@ -20,7 +20,7 @@ export type IntegrationAction = "query" | "interact";
* @param action query for showing data or interact for mutating data
* @param kinds kinds of integrations that are supported
* @returns middleware that can be used with trpc
* @example publicProcedure.unstable_concat(createOneIntegrationMiddleware("query", "piHole", "homeAssistant")).query(...)
* @example publicProcedure.concat(createOneIntegrationMiddleware("query", "piHole", "homeAssistant")).query(...)
* @throws TRPCError NOT_FOUND if the integration was not found
* @throws TRPCError FORBIDDEN if the user does not have permission to perform the specified action on the specified integration
*/
@@ -82,7 +82,7 @@ export const createOneIntegrationMiddleware = <TKind extends IntegrationKind>(
* @param action query for showing data or interact for mutating data
* @param kinds kinds of integrations that are supported
* @returns middleware that can be used with trpc
* @example publicProcedure.unstable_concat(createManyIntegrationMiddleware("query", "piHole", "homeAssistant")).query(...)
* @example publicProcedure.concat(createManyIntegrationMiddleware("query", "piHole", "homeAssistant")).query(...)
* @throws TRPCError NOT_FOUND if the integration was not found
* @throws TRPCError FORBIDDEN if the user does not have permission to perform the specified action on at least one of the specified integrations
*/

View File

@@ -18,7 +18,7 @@ const dockerCache = createCacheChannel<{
export const dockerRouter = createTRPCRouter({
getContainers: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.query(async () => {
const result = await dockerCache
.consumeAsync(async () => {
@@ -81,14 +81,14 @@ export const dockerRouter = createTRPCRouter({
}),
invalidate: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.mutation(async () => {
await dockerCache.invalidateAsync();
return;
}),
startAll: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.input(z.object({ ids: z.array(z.string()) }))
.mutation(async ({ input }) => {
await Promise.allSettled(
@@ -102,7 +102,7 @@ export const dockerRouter = createTRPCRouter({
}),
stopAll: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.input(z.object({ ids: z.array(z.string()) }))
.mutation(async ({ input }) => {
await Promise.allSettled(
@@ -116,7 +116,7 @@ export const dockerRouter = createTRPCRouter({
}),
restartAll: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.input(z.object({ ids: z.array(z.string()) }))
.mutation(async ({ input }) => {
await Promise.allSettled(
@@ -130,7 +130,7 @@ export const dockerRouter = createTRPCRouter({
}),
removeAll: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(dockerMiddleware())
.concat(dockerMiddleware())
.input(z.object({ ids: z.array(z.string()) }))
.mutation(async ({ input }) => {
await Promise.allSettled(

View File

@@ -467,7 +467,7 @@ export const integrationRouter = createTRPCRouter({
});
}),
searchInIntegration: protectedProcedure
.unstable_concat(createOneIntegrationMiddleware("query", ...getIntegrationKindsByCategory("search")))
.concat(createOneIntegrationMiddleware("query", ...getIntegrationKindsByCategory("search")))
.input(z.object({ integrationId: z.string(), query: z.string() }))
.query(async ({ ctx, input }) => {
const integrationInstance = await createIntegrationAsync(ctx.integration);

View File

@@ -13,7 +13,7 @@ import { MemoryResourceParser } from "../resource-parser/memory-resource-parser"
export const clusterRouter = createTRPCRouter({
getCluster: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesCluster> => {
const { coreApi, metricsApi, versionApi, kubeConfig } = KubernetesClient.getInstance();

View File

@@ -10,7 +10,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const configMapsRouter = createTRPCRouter({
getConfigMaps: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesBaseResource[]> => {
const { coreApi } = KubernetesClient.getInstance();

View File

@@ -11,7 +11,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const ingressesRouter = createTRPCRouter({
getIngresses: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesIngress[]> => {
const { networkingApi } = KubernetesClient.getInstance();
try {

View File

@@ -10,7 +10,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const namespacesRouter = createTRPCRouter({
getNamespaces: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesNamespace[]> => {
const { coreApi } = KubernetesClient.getInstance();

View File

@@ -12,7 +12,7 @@ import { MemoryResourceParser } from "../resource-parser/memory-resource-parser"
export const nodesRouter = createTRPCRouter({
getNodes: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesNode[]> => {
const { coreApi, metricsApi } = KubernetesClient.getInstance();

View File

@@ -12,7 +12,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const podsRouter = createTRPCRouter({
getPods: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesPod[]> => {
const { coreApi, kubeConfig } = KubernetesClient.getInstance();
try {

View File

@@ -10,7 +10,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const secretsRouter = createTRPCRouter({
getSecrets: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesSecret[]> => {
const { coreApi } = KubernetesClient.getInstance();
try {

View File

@@ -10,7 +10,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const servicesRouter = createTRPCRouter({
getServices: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesService[]> => {
const { coreApi } = KubernetesClient.getInstance();

View File

@@ -10,7 +10,7 @@ import { KubernetesClient } from "../kubernetes-client";
export const volumesRouter = createTRPCRouter({
getVolumes: permissionRequiredProcedure
.requiresPermission("admin")
.unstable_concat(kubernetesMiddleware())
.concat(kubernetesMiddleware())
.query(async (): Promise<KubernetesVolume[]> => {
const { coreApi } = KubernetesClient.getInstance();

View File

@@ -133,14 +133,14 @@ export const searchEngineRouter = createTRPCRouter({
});
}),
getMediaRequestOptions: protectedProcedure
.unstable_concat(createOneIntegrationMiddleware("query", "jellyseerr", "overseerr"))
.concat(createOneIntegrationMiddleware("query", "jellyseerr", "overseerr"))
.input(mediaRequestOptionsSchema)
.query(async ({ ctx, input }) => {
const integration = await createIntegrationAsync(ctx.integration);
return await integration.getSeriesInformationAsync(input.mediaType, input.mediaId);
}),
requestMedia: protectedProcedure
.unstable_concat(createOneIntegrationMiddleware("interact", "jellyseerr", "overseerr"))
.concat(createOneIntegrationMiddleware("interact", "jellyseerr", "overseerr"))
.input(mediaRequestRequestSchema)
.mutation(async ({ ctx, input }) => {
const integration = await createIntegrationAsync(ctx.integration);

View File

@@ -17,7 +17,7 @@ export const calendarRouter = createTRPCRouter({
showUnmonitored: z.boolean(),
}),
)
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("calendar")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("calendar")))
.query(async ({ ctx, input }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {

View File

@@ -14,7 +14,7 @@ import { createTRPCRouter, protectedProcedure, publicProcedure } from "../../trp
export const dnsHoleRouter = createTRPCRouter({
summary: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("dnsHole")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("dnsHole")))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -36,7 +36,7 @@ export const dnsHoleRouter = createTRPCRouter({
}),
subscribeToSummary: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("dnsHole")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("dnsHole")))
.subscription(({ ctx }) => {
return observable<{
integration: Modify<Integration, { kind: IntegrationKindByCategory<"dnsHole"> }>;
@@ -63,7 +63,7 @@ export const dnsHoleRouter = createTRPCRouter({
}),
enable: protectedProcedure
.unstable_concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("dnsHole")))
.concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("dnsHole")))
.mutation(async ({ ctx: { integration } }) => {
const client = await createIntegrationAsync(integration);
await client.enableAsync();
@@ -81,7 +81,7 @@ export const dnsHoleRouter = createTRPCRouter({
duration: z.number().optional(),
}),
)
.unstable_concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("dnsHole")))
.concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("dnsHole")))
.mutation(async ({ ctx: { integration }, input }) => {
const client = await createIntegrationAsync(integration);
await client.disableAsync(input.duration);

View File

@@ -18,7 +18,7 @@ const createDownloadClientIntegrationMiddleware = (action: IntegrationAction) =>
export const downloadsRouter = createTRPCRouter({
getJobsAndStatuses: publicProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("query"))
.concat(createDownloadClientIntegrationMiddleware("query"))
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -39,7 +39,7 @@ export const downloadsRouter = createTRPCRouter({
);
}),
subscribeToJobsAndStatuses: publicProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("query"))
.concat(createDownloadClientIntegrationMiddleware("query"))
.subscription(({ ctx }) => {
return observable<{
integration: Modify<Integration, { kind: IntegrationKindByCategory<"downloadClient"> }>;
@@ -64,18 +64,16 @@ export const downloadsRouter = createTRPCRouter({
};
});
}),
pause: protectedProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("interact"))
.mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {
const integrationInstance = await createIntegrationAsync(integration);
await integrationInstance.pauseQueueAsync();
}),
);
}),
pause: protectedProcedure.concat(createDownloadClientIntegrationMiddleware("interact")).mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {
const integrationInstance = await createIntegrationAsync(integration);
await integrationInstance.pauseQueueAsync();
}),
);
}),
pauseItem: protectedProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("interact"))
.concat(createDownloadClientIntegrationMiddleware("interact"))
.input(z.object({ item: downloadClientItemSchema }))
.mutation(async ({ ctx, input }) => {
await Promise.all(
@@ -85,18 +83,16 @@ export const downloadsRouter = createTRPCRouter({
}),
);
}),
resume: protectedProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("interact"))
.mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {
const integrationInstance = await createIntegrationAsync(integration);
await integrationInstance.resumeQueueAsync();
}),
);
}),
resume: protectedProcedure.concat(createDownloadClientIntegrationMiddleware("interact")).mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {
const integrationInstance = await createIntegrationAsync(integration);
await integrationInstance.resumeQueueAsync();
}),
);
}),
resumeItem: protectedProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("interact"))
.concat(createDownloadClientIntegrationMiddleware("interact"))
.input(z.object({ item: downloadClientItemSchema }))
.mutation(async ({ ctx, input }) => {
await Promise.all(
@@ -107,7 +103,7 @@ export const downloadsRouter = createTRPCRouter({
);
}),
deleteItem: protectedProcedure
.unstable_concat(createDownloadClientIntegrationMiddleware("interact"))
.concat(createDownloadClientIntegrationMiddleware("interact"))
.input(z.object({ item: downloadClientItemSchema, fromDisk: z.boolean() }))
.mutation(async ({ ctx, input }) => {
await Promise.all(

View File

@@ -9,7 +9,7 @@ import { createTRPCRouter, publicProcedure } from "../../trpc";
export const healthMonitoringRouter = createTRPCRouter({
getSystemHealthStatus: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot"))
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot"))
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -26,7 +26,7 @@ export const healthMonitoringRouter = createTRPCRouter({
);
}),
subscribeSystemHealthStatus: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot"))
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot"))
.subscription(({ ctx }) => {
return observable<{ integrationId: string; healthInfo: HealthMonitoring; timestamp: Date }>((emit) => {
const unsubscribes: (() => void)[] = [];
@@ -49,14 +49,14 @@ export const healthMonitoringRouter = createTRPCRouter({
});
}),
getClusterHealthStatus: publicProcedure
.unstable_concat(createOneIntegrationMiddleware("query", "proxmox"))
.concat(createOneIntegrationMiddleware("query", "proxmox"))
.query(async ({ ctx }) => {
const innerHandler = clusterInfoRequestHandler.handler(ctx.integration, {});
const { data } = await innerHandler.getCachedOrUpdatedDataAsync({ forceUpdate: false });
return data;
}),
subscribeClusterHealthStatus: publicProcedure
.unstable_concat(createOneIntegrationMiddleware("query", "proxmox"))
.concat(createOneIntegrationMiddleware("query", "proxmox"))
.subscription(({ ctx }) => {
return observable<ProxmoxClusterInfo>((emit) => {
const unsubscribes: (() => void)[] = [];

View File

@@ -16,7 +16,7 @@ const createIndexerManagerIntegrationMiddleware = (action: IntegrationAction) =>
export const indexerManagerRouter = createTRPCRouter({
getIndexersStatus: publicProcedure
.unstable_concat(createIndexerManagerIntegrationMiddleware("query"))
.concat(createIndexerManagerIntegrationMiddleware("query"))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -33,7 +33,7 @@ export const indexerManagerRouter = createTRPCRouter({
}),
subscribeIndexersStatus: publicProcedure
.unstable_concat(createIndexerManagerIntegrationMiddleware("query"))
.concat(createIndexerManagerIntegrationMiddleware("query"))
.subscription(({ ctx }) => {
return observable<{ integrationId: string; indexers: Indexer[] }>((emit) => {
const unsubscribes: (() => void)[] = [];
@@ -55,7 +55,7 @@ export const indexerManagerRouter = createTRPCRouter({
});
}),
testAllIndexers: protectedProcedure
.unstable_concat(createIndexerManagerIntegrationMiddleware("interact"))
.concat(createIndexerManagerIntegrationMiddleware("interact"))
.mutation(async ({ ctx }) => {
await Promise.all(
ctx.integrations.map(async (integration) => {

View File

@@ -12,7 +12,7 @@ import { createTRPCRouter, protectedProcedure, publicProcedure } from "../../trp
export const mediaRequestsRouter = createTRPCRouter({
getLatestRequests: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -39,7 +39,7 @@ export const mediaRequestsRouter = createTRPCRouter({
});
}),
subscribeToLatestRequests: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.subscription(({ ctx }) => {
return observable<{
integrationId: string;
@@ -65,7 +65,7 @@ export const mediaRequestsRouter = createTRPCRouter({
});
}),
getStats: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRequest")))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -91,7 +91,7 @@ export const mediaRequestsRouter = createTRPCRouter({
};
}),
answerRequest: protectedProcedure
.unstable_concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("mediaRequest")))
.concat(createOneIntegrationMiddleware("interact", ...getIntegrationKindsByCategory("mediaRequest")))
.input(z.object({ requestId: z.number(), answer: z.enum(["approve", "decline"]) }))
.mutation(async ({ ctx: { integration }, input }) => {
const integrationInstance = await createIntegrationAsync(integration);

View File

@@ -14,7 +14,7 @@ const createMediaServerIntegrationMiddleware = (action: IntegrationAction) =>
export const mediaServerRouter = createTRPCRouter({
getCurrentStreams: publicProcedure
.unstable_concat(createMediaServerIntegrationMiddleware("query"))
.concat(createMediaServerIntegrationMiddleware("query"))
.input(z.object({ showOnlyPlaying: z.boolean() }))
.query(async ({ ctx, input }) => {
return await Promise.all(
@@ -32,7 +32,7 @@ export const mediaServerRouter = createTRPCRouter({
);
}),
subscribeToCurrentStreams: publicProcedure
.unstable_concat(createMediaServerIntegrationMiddleware("query"))
.concat(createMediaServerIntegrationMiddleware("query"))
.input(z.object({ showOnlyPlaying: z.boolean() }))
.subscription(({ ctx, input }) => {
return observable<{ integrationId: string; data: StreamSession[] }>((emit) => {

View File

@@ -11,7 +11,7 @@ const createIndexerManagerIntegrationMiddleware = (action: IntegrationAction) =>
export const mediaTranscodingRouter = createTRPCRouter({
getDataAsync: publicProcedure
.unstable_concat(createIndexerManagerIntegrationMiddleware("query"))
.concat(createIndexerManagerIntegrationMiddleware("query"))
.input(paginatedSchema.pick({ page: true, pageSize: true }))
.query(async ({ ctx, input }) => {
const innerHandler = mediaTranscodingRequestHandler.handler(ctx.integration, {

View File

@@ -12,7 +12,7 @@ import { createTRPCRouter, publicProcedure } from "../../trpc";
export const networkControllerRouter = createTRPCRouter({
summary: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("networkController")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("networkController")))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
@@ -34,7 +34,7 @@ export const networkControllerRouter = createTRPCRouter({
}),
subscribeToSummary: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("networkController")))
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("networkController")))
.subscription(({ ctx }) => {
return observable<{
integration: Modify<Integration, { kind: IntegrationKindByCategory<"networkController"> }>;

View File

@@ -15,14 +15,14 @@ const createSmartHomeIntegrationMiddleware = (action: IntegrationAction) =>
export const smartHomeRouter = createTRPCRouter({
entityState: publicProcedure
.input(z.object({ entityId: z.string() }))
.unstable_concat(createSmartHomeIntegrationMiddleware("query"))
.concat(createSmartHomeIntegrationMiddleware("query"))
.query(async ({ ctx: { integration }, input }) => {
const innerHandler = smartHomeEntityStateRequestHandler.handler(integration, { entityId: input.entityId });
const { data } = await innerHandler.getCachedOrUpdatedDataAsync({ forceUpdate: false });
return data;
}),
subscribeEntityState: publicProcedure
.unstable_concat(createSmartHomeIntegrationMiddleware("query"))
.concat(createSmartHomeIntegrationMiddleware("query"))
.input(z.object({ entityId: z.string() }))
.subscription(({ input, ctx }) => {
return observable<{
@@ -42,7 +42,7 @@ export const smartHomeRouter = createTRPCRouter({
});
}),
switchEntity: protectedProcedure
.unstable_concat(createSmartHomeIntegrationMiddleware("interact"))
.concat(createSmartHomeIntegrationMiddleware("interact"))
.input(z.object({ entityId: z.string() }))
.mutation(async ({ ctx: { integration }, input }) => {
const client = await createIntegrationAsync(integration);
@@ -54,7 +54,7 @@ export const smartHomeRouter = createTRPCRouter({
return success;
}),
executeAutomation: protectedProcedure
.unstable_concat(createSmartHomeIntegrationMiddleware("interact"))
.concat(createSmartHomeIntegrationMiddleware("interact"))
.input(z.object({ automationId: z.string() }))
.mutation(async ({ ctx: { integration }, input }) => {
const client = await createIntegrationAsync(integration);