Merge remote-tracking branch 'origin/release/v2' into feat/pr6582-nice-changes-release

# Conflicts:
#	apps/nextjs/src/components/board/items/item-select-modal.tsx
This commit is contained in:
Thomas Camlong committed 2026-08-17 12:29:50 +02:00
commit 510845d3b9
55 files changed
+2566 -1731

No files matched your search

@@ -1,4 +1,5 @@
import { TRPCError } from "@trpc/server";
import { parse as parseSuperJson } from "superjson";
import { z } from "zod/v4";
import { encryptSecret } from "@homarr/common/server";
@@ -26,6 +27,32 @@ export const transferProcedures = {
return parseStoredCustomWidgetDefinition(definition);
}),
exportLegacy: permissionRequiredProcedure
.requiresPermission("admin")
.input(z.object({ id: z.string() }))
.query(async ({ ctx, input }) => {
const definition = await ctx.db.query.legacyCustomWidgetDefinitions.findFirst({
where: eq(legacyCustomWidgetDefinitions.id, input.id),
with: { secrets: true },
});
if (!definition) throw new TRPCError({ code: "NOT_FOUND", message: "Legacy custom widget not found" });
return {
$schema: "homarr-custom-widget-v1" as const,
name: definition.name,
description: definition.description,
iconUrl: definition.iconUrl,
url: definition.url,
authType: definition.authType,
headerName: definition.headerName,
method: definition.method,
requestBody: definition.requestBody,
displayType: definition.displayType,
displayConfig: parseLegacyDisplayConfig(definition.displayConfig),
configuredSecretKinds: definition.secrets.map(({ kind }) => kind),
};
}),
import: permissionRequiredProcedure
.requiresPermission("admin")
.input(z.object({ widget: customWidgetImportSchema, secrets: customWidgetSecretsInputSchema.default([]) }))
@@ -117,6 +144,14 @@ export const transferProcedures = {
}),
};
function parseLegacyDisplayConfig(value: string): unknown {
try {
return parseSuperJson(value);
} catch {
return value;
}
}
function canPreserveLegacySecrets(
legacy: typeof legacyCustomWidgetDefinitions.$inferSelect,
widget: z.infer<typeof customWidgetImportSchema>,