Files
homarr/packages/custom-widgets/src/server/preview-session-template.ts
T
Thomas 5e23659d99 feat(assistant): optimize MCP and custom widget authoring (#6743)
* feat(assistant): optimize MCP and custom widget authoring

* fix(assistant): isolate server-safe JSX analyzer

* refactor(assistant): generate MCP tool staging

* fix(assistant): preserve widget placement follow-up

* fix(ci): allow fast gate to finish

* fix(custom-widgets): address review findings

* fix(custom-widgets): split preview evidence module

* style: format assistant custom widget files

* fix(custom-widgets): sync formatted skill schema
2026-08-30 23:43:29 +02:00

39 lines
1.4 KiB
TypeScript

import { customWidgetDefinitionSchema } from "../core";
import type { CustomJsxRequest, CustomWidgetOptions, CustomWidgetSource } from "../core";
import { CustomWidgetDomainError } from "./errors";
interface PreviewTemplateContext {
name: string;
description?: string;
iconUrl?: string;
sources: Record<string, CustomWidgetSource>;
requests: Record<string, CustomJsxRequest>;
optionDefinitions: CustomWidgetOptions;
template: string;
}
export function validatePreviewTemplateRevision(current: PreviewTemplateContext, template: string) {
const parsed = customWidgetDefinitionSchema.safeParse({
$schema: "homarr-custom-widget-v2",
name: current.name,
description: current.description,
iconUrl: current.iconUrl,
sources: current.sources,
requests: current.requests,
options: current.optionDefinitions,
template,
});
if (!parsed.success) {
const issue = parsed.error.issues[0];
const path = issue?.path.length ? `${issue.path.join(".")}: ` : "";
throw new CustomWidgetDomainError({
code: "BAD_REQUEST",
message: `Revised preview template is invalid: ${path}${issue?.message ?? "Unknown validation error"}`,
});
}
if (parsed.data.template === current.template) {
throw new CustomWidgetDomainError({ code: "BAD_REQUEST", message: "Revised preview template is unchanged" });
}
return parsed.data.template;
}