101 lines
3.8 KiB
TypeScript
101 lines
3.8 KiB
TypeScript
import { contentProcedures } from "./content-procedures";
|
|
import { nativeProcedures } from "./native-procedures";
|
|
import { workshopUpdateProcedures } from "./workshop-update-procedures";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { z } from "zod/v4";
|
|
|
|
import { createId } from "@homarr/common";
|
|
import { createLogger } from "@homarr/core/infrastructure/logs";
|
|
import { eq } from "@homarr/db";
|
|
import { customWidgetDefinitions } from "@homarr/db/schema";
|
|
|
|
import { createTRPCRouter, permissionRequiredProcedure } from "../../trpc";
|
|
import { creationProcedures } from "./creation-procedures";
|
|
import { managementQueryProcedures } from "./management-queries";
|
|
import { metadataProcedures } from "./metadata-procedures";
|
|
import { previewActionProcedures } from "./preview-action-procedures";
|
|
import { previewBaseProcedures } from "./preview-base-procedures";
|
|
import { previewQueryProcedures } from "./preview-query-procedures";
|
|
import {
|
|
parseStoredCustomWidgetDefinition,
|
|
safeParseStoredCustomWidgetDefinition,
|
|
serializeCustomWidgetDefinition,
|
|
} from "./stored-definition";
|
|
import { templateProcedures } from "./template-procedures";
|
|
import { transferProcedures } from "./transfer-procedures";
|
|
import { secretProcedures } from "./secret-procedures";
|
|
import { workshopProcedures } from "./workshop-procedures";
|
|
import { updateCustomWidgetProcedure } from "./definition-update-procedure";
|
|
|
|
const logger = createLogger({ module: "custom-widget" });
|
|
|
|
export const customWidgetRouter = createTRPCRouter({
|
|
...metadataProcedures,
|
|
...nativeProcedures,
|
|
...contentProcedures,
|
|
...managementQueryProcedures,
|
|
...creationProcedures,
|
|
|
|
update: updateCustomWidgetProcedure,
|
|
|
|
...secretProcedures,
|
|
...workshopProcedures,
|
|
...workshopUpdateProcedures,
|
|
|
|
toggleEnabled: permissionRequiredProcedure
|
|
.requiresPermission("admin")
|
|
.input(z.object({ id: z.string(), enabled: z.boolean() }))
|
|
.mutation(async ({ ctx, input }) => {
|
|
if (input.enabled) {
|
|
const definition = await ctx.db.query.customWidgetDefinitions.findFirst({
|
|
where: eq(customWidgetDefinitions.id, input.id),
|
|
});
|
|
if (!definition) throw new TRPCError({ code: "NOT_FOUND" });
|
|
if (!safeParseStoredCustomWidgetDefinition(definition).success) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Invalid custom widget definition cannot be enabled",
|
|
});
|
|
}
|
|
}
|
|
|
|
await ctx.db
|
|
.update(customWidgetDefinitions)
|
|
.set({ enabled: input.enabled, updatedAt: new Date() })
|
|
.where(eq(customWidgetDefinitions.id, input.id));
|
|
}),
|
|
|
|
delete: permissionRequiredProcedure
|
|
.requiresPermission("admin")
|
|
.meta({ mcp: { enabled: true, description: "Delete one Custom JSX widget." } })
|
|
.input(z.object({ id: z.string() }))
|
|
.mutation(async ({ ctx, input }) => {
|
|
await ctx.db.delete(customWidgetDefinitions).where(eq(customWidgetDefinitions.id, input.id));
|
|
logger.info("Deleted custom widget definition", { id: input.id });
|
|
}),
|
|
|
|
duplicate: permissionRequiredProcedure
|
|
.requiresPermission("admin")
|
|
.input(z.object({ id: z.string() }))
|
|
.mutation(async ({ ctx, input }) => {
|
|
const existing = await ctx.db.query.customWidgetDefinitions.findFirst({
|
|
where: eq(customWidgetDefinitions.id, input.id),
|
|
});
|
|
if (!existing) throw new TRPCError({ code: "NOT_FOUND" });
|
|
const current = parseStoredCustomWidgetDefinition(existing);
|
|
const id = createId();
|
|
await ctx.db.insert(customWidgetDefinitions).values({
|
|
id,
|
|
...serializeCustomWidgetDefinition({ ...current, name: `${current.name} (copy)` }),
|
|
creatorId: ctx.session.user.id,
|
|
});
|
|
return { id, name: `${current.name} (copy)` };
|
|
}),
|
|
|
|
...templateProcedures,
|
|
...transferProcedures,
|
|
...previewBaseProcedures,
|
|
...previewQueryProcedures,
|
|
...previewActionProcedures,
|
|
});
|