From be7eef7028de618bf8219a155a1fbd07b41cccf7 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Sat, 25 Apr 2026 11:26:16 +0200 Subject: [PATCH] refactor(webhooks): headers as array --- app/client/api-client/types.gen.ts | 28 ++++++------ .../components/webhook-request-preview.tsx | 25 +++++++++++ .../create-schedule-form/advanced-section.tsx | 26 ++++++++--- .../components/create-schedule-form/index.tsx | 8 ++-- .../components/create-schedule-form/types.ts | 44 ++++++------------- .../components/create-schedule-form/utils.ts | 21 +++------ .../routes/__tests__/edit-backup.test.tsx | 4 +- .../notification-forms/generic-form.tsx | 19 ++++---- .../backups.service.execution.test.ts | 8 ++-- .../backups/__tests__/backups.service.test.ts | 8 ++-- .../modules/backups/backups.controller.ts | 9 ++-- app/server/modules/backups/backups.dto.ts | 6 +-- apps/agent/src/commands/backup-run.test.ts | 14 ++++-- .../src/backup-hooks/__tests__/hooks.test.ts | 2 +- packages/core/src/backup-hooks/index.ts | 13 ++++-- 15 files changed, 129 insertions(+), 106 deletions(-) create mode 100644 app/client/components/webhook-request-preview.tsx diff --git a/app/client/api-client/types.gen.ts b/app/client/api-client/types.gen.ts index d63fc595..4ada52f3 100644 --- a/app/client/api-client/types.gen.ts +++ b/app/client/api-client/types.gen.ts @@ -2436,12 +2436,12 @@ export type ListBackupSchedulesResponses = { customResticParams: Array | null; preBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries: number; @@ -2724,12 +2724,12 @@ export type CreateBackupScheduleData = { customResticParams?: Array; preBackupWebhook?: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook?: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries?: number; @@ -2769,12 +2769,12 @@ export type CreateBackupScheduleResponses = { customResticParams: Array | null; preBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries: number; @@ -2848,12 +2848,12 @@ export type GetBackupScheduleResponses = { customResticParams: Array | null; preBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries: number; @@ -3135,12 +3135,12 @@ export type UpdateBackupScheduleData = { customResticParams?: Array; preBackupWebhook?: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook?: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries?: number; @@ -3182,12 +3182,12 @@ export type UpdateBackupScheduleResponses = { customResticParams: Array | null; preBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries: number; @@ -3241,12 +3241,12 @@ export type GetBackupScheduleForVolumeResponses = { customResticParams: Array | null; preBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; postBackupWebhook: { url: string; - headers?: Record; + headers?: Array; body?: string; } | null; maxRetries: number; diff --git a/app/client/components/webhook-request-preview.tsx b/app/client/components/webhook-request-preview.tsx new file mode 100644 index 00000000..1b1c132f --- /dev/null +++ b/app/client/components/webhook-request-preview.tsx @@ -0,0 +1,25 @@ +import { CodeBlock } from "~/client/components/ui/code-block"; +import { Label } from "~/client/components/ui/label"; + +type WebhookRequestPreviewProps = { + method: string; + url?: string; + contentType?: string; + headers?: string[]; + body: string; +}; + +export const WebhookRequestPreview = ({ method, url, contentType, headers, body }: WebhookRequestPreviewProps) => { + const headerLines = [contentType ? `Content-Type: ${contentType}` : undefined, ...(headers ?? [])].filter(Boolean); + const previewCode = `${method} ${url || "https://api.example.com/webhook"}${headerLines.length > 0 ? `\n${headerLines.join("\n")}` : ""} + +${body}`; + + return ( +
+ + +

This is a preview of the HTTP request that will be sent.

+
+ ); +}; diff --git a/app/client/modules/backups/components/create-schedule-form/advanced-section.tsx b/app/client/modules/backups/components/create-schedule-form/advanced-section.tsx index aa5aae3f..5c868e3f 100644 --- a/app/client/modules/backups/components/create-schedule-form/advanced-section.tsx +++ b/app/client/modules/backups/components/create-schedule-form/advanced-section.tsx @@ -1,6 +1,6 @@ import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "~/client/components/ui/form"; import { Textarea } from "~/client/components/ui/textarea"; -import type { UseFormReturn } from "react-hook-form"; +import { useWatch, type UseFormReturn } from "react-hook-form"; import type { InternalFormValues } from "./types"; import { Input } from "~/client/components/ui/input"; @@ -9,6 +9,10 @@ type AdvancedSectionProps = { }; export const AdvancedSection = ({ form }: AdvancedSectionProps) => { + const values = useWatch({ control: form.control }); + const preBackupWebhookBody = values.preBackupWebhookBody?.trim(); + const postBackupWebhookBody = values.postBackupWebhookBody?.trim(); + return ( <> { /> ( Pre-backup webhook headers