Fix link formatting (#13210)

closes https://github.com/twentyhq/twenty/issues/13207

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Paul Rastoin
2025-07-15 12:27:00 +02:00
committed by GitHub
parent eed502778a
commit d916ec0af9
12 changed files with 87 additions and 60 deletions

View File

@ -1,4 +1,4 @@
import { FieldMetadataType } from "@/types";
import { FieldMetadataType } from '@/types';
export const LABEL_IDENTIFIER_FIELD_METADATA_TYPES = [
FieldMetadataType.TEXT,

View File

@ -105,11 +105,7 @@ describe('removeUndefinedFields', () => {
},
expected: {
names: ['John', 'Jane', null],
tags: [
{ id: 1, label: 'active' },
{ label: 'pending' },
{ id: 3 },
],
tags: [{ id: 1, label: 'active' }, { label: 'pending' }, { id: 3 }],
},
},
{
@ -131,4 +127,4 @@ describe('removeUndefinedFields', () => {
expect(removeUndefinedFields(input)).toEqual(expected);
});
});
});
});

View File

@ -0,0 +1,7 @@
export const getURLSafely = (url: string) => {
try {
return new URL(url);
} catch (e: unknown) {
return null;
}
};

View File

@ -9,6 +9,7 @@
export { assertUnreachable } from './assertUnreachable';
export { isFieldMetadataDateKind } from './fieldMetadata/isFieldMetadataDateKind';
export { getURLSafely } from './getURLSafely';
export { getImageAbsoluteURI } from './image/getImageAbsoluteURI';
export {
sanitizeURL,
@ -26,7 +27,7 @@ export { getAbsoluteUrlOrThrow } from './url/getAbsoluteUrlOrThrow';
export { getUrlHostnameOrThrow } from './url/getUrlHostnameOrThrow';
export { isValidHostname } from './url/isValidHostname';
export { isValidUrl } from './url/isValidUrl';
export { lowercaseUrlAndRemoveTrailingSlash } from './url/lowercaseUrlAndRemoveTrailingSlash';
export { lowercaseUrlOriginAndRemoveTrailingSlash } from './url/lowercaseUrlOriginAndRemoveTrailingSlash';
export { isDefined } from './validation/isDefined';
export { isLabelIdentifierFieldMetadataTypes } from './validation/isLabelIdentifierFieldMetadataTypes';
export { isValidLocale } from './validation/isValidLocale';

View File

@ -1,24 +0,0 @@
import { lowercaseUrlAndRemoveTrailingSlash } from '@/utils/url/lowercaseUrlAndRemoveTrailingSlash';
describe('lowercaseUrlAndRemoveTrailingSlash', () => {
it('should leave lowcased domain unchanged', () => {
const primaryLinkUrl = 'https://www.example.com/test';
const result = lowercaseUrlAndRemoveTrailingSlash(primaryLinkUrl);
expect(result).toBe('https://www.example.com/test');
});
it('should lowercase the domain of the primary link url', () => {
const primaryLinkUrl = 'htTps://wwW.exAmple.coM/TEST';
const result = lowercaseUrlAndRemoveTrailingSlash(primaryLinkUrl);
expect(result).toBe('https://www.example.com/TEST');
});
it('should not add a trailing slash', () => {
const primaryLinkUrl = 'https://www.example.com';
const result = lowercaseUrlAndRemoveTrailingSlash(primaryLinkUrl);
expect(result).toBe('https://www.example.com');
});
});

View File

@ -0,0 +1,44 @@
import { lowercaseUrlOriginAndRemoveTrailingSlash } from '@/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash';
interface TestContext {
title: string;
input: string;
expected: string;
}
describe('lowercaseUrlOriginAndRemoveTrailingSlash', () => {
test.each<TestContext>([
{
title: 'should leave lowcased domain unchanged',
input: 'https://www.example.com/test',
expected: 'https://www.example.com/test',
},
{
title: 'should lowercase the domain while preserving path case',
input: 'htTps://wwW.exAmple.coM/TEST',
expected: 'https://www.example.com/TEST',
},
{
title: 'should not add a trailing slash',
input: 'https://www.example.com',
expected: 'https://www.example.com',
},
{
title: 'should remove trailing slash',
input: 'https://www.example.com/',
expected: 'https://www.example.com',
},
{
title: 'should handle query parameters',
input: 'htTps://wwW.exAmple.coM/TEST?Param=Value',
expected: 'https://www.example.com/TEST?Param=Value',
},
{
title: 'should handle hash fragments',
input: 'htTps://wwW.exAmple.coM/TEST#Hash',
expected: 'https://www.example.com/TEST#Hash',
},
])('$title', ({ input, expected }) => {
expect(lowercaseUrlOriginAndRemoveTrailingSlash(input)).toBe(expected);
});
});

View File

@ -1,7 +0,0 @@
export const lowercaseUrlAndRemoveTrailingSlash = (url: string) => {
try {
return new URL(url).toString().toLowerCase().replace(/\/$/, '');
} catch {
return url.toLowerCase();
}
};

View File

@ -0,0 +1,15 @@
import { getURLSafely } from '@/utils/getURLSafely';
import { isDefined } from '@/utils/validation';
export const lowercaseUrlOriginAndRemoveTrailingSlash = (rawUrl: string) => {
const url = getURLSafely(rawUrl);
if (!isDefined(url)) {
return rawUrl;
}
const lowercaseOrigin = url.origin.toLowerCase();
const path = url.pathname + url.search + url.hash;
return (lowercaseOrigin + path).replace(/\/$/, '');
};