Files
twenty/packages/twenty-shared/src/utils/url/absoluteUrlSchema.ts
T
nitin 3d57c90e04 refactor: Webhooks (#12487)
Closes #12303

### What’s Changed
- Replace auto‐save with explicit Save / Cancel
Webhook forms now use manual “Save” and “Cancel” buttons instead of the
old debounced auto‐save/update.

- Separate “New” and “Detail” routes
Two dedicated paths `/settings/webhooks/new` for creation and
/`settings/webhooks/:webhookId` for editing, making the UX clearer.

- URL hint & normalization
If a user omits the http(s):// scheme, we display a “Will be saved as
https://…” hint and automatically default to HTTPS.

- Centralized validation with Zod
Introduced a `webhookFormSchema` for client‐side URL, operations, and
secret validation.

- Storybook coverage
Added stories for both “New Webhook” and “Webhook Detail”

- Unit tests
Added tests for the new `useWebhookForm` hook
2025-06-13 05:37:25 +00:00

46 lines
1.1 KiB
TypeScript

import { getAbsoluteUrl } from '@/utils/url/getAbsoluteUrl';
import { isValidHostname } from '@/utils/url/isValidHostname';
import { z } from 'zod';
export const absoluteUrlSchema = z.string().transform((value, ctx) => {
const trimmedValue = value.trim();
const absoluteUrl = getAbsoluteUrl(trimmedValue);
const valueWithoutProtocol = absoluteUrl
.replace('https://', '')
.replace('http://', '');
if (/^\d+(?:\/[a-zA-Z]*)?$/.test(valueWithoutProtocol)) {
// if the hostname is a number, it's not a valid url
// if we let URL() parse it, it will throw cast an IP address and we lose the information
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'domain is not a valid url',
});
return z.NEVER;
}
try {
const url = new URL(absoluteUrl);
if (isValidHostname(url.hostname)) {
return absoluteUrl;
}
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'domain is not a valid url',
});
return z.NEVER;
} catch (error) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'domain is not a valid url',
});
return z.NEVER;
}
});