Skip to content

Commit 085462b

Browse files
authored
feat: email validator and a string formatter (#656)
* feat: validator for emails and a string formatter
1 parent 5d93503 commit 085462b

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

projects/common/src/public-api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,6 @@ export * from './time/time-range.service';
106106
export * from './time/time-range.type';
107107
export * from './time/time-unit.type';
108108
export * from './time/time';
109+
110+
// Validators
111+
export * from './utilities/validators/email-validator';

projects/common/src/utilities/formatters/string/string-formatter.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { displayString, titleCaseFromKebabCase, titleCaseFromSnakeCase } from './string-formatter';
1+
import {
2+
displayString,
3+
getStringsFromCommaSeparatedList,
4+
titleCaseFromKebabCase,
5+
titleCaseFromSnakeCase
6+
} from './string-formatter';
27

38
describe('String formatter', () => {
49
test('can convert from kebab case to title case', () => {
@@ -26,4 +31,12 @@ describe('String formatter', () => {
2631
expect(displayString(Symbol('test symbol'))).toBe('Symbol(test symbol)');
2732
expect(displayString(false)).toBe('false');
2833
});
34+
35+
test('creates string array correctly from comma separated list', () => {
36+
expect(getStringsFromCommaSeparatedList('first,second, third ')).toEqual(
37+
expect.arrayContaining(['first', 'second', 'third'])
38+
);
39+
expect(getStringsFromCommaSeparatedList('first,second, ')).toEqual(expect.arrayContaining(['first', 'second']));
40+
expect(getStringsFromCommaSeparatedList('first')).toEqual(expect.arrayContaining(['first']));
41+
});
2942
});

projects/common/src/utilities/formatters/string/string-formatter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,10 @@ export const displayString = (provided?: unknown): string => {
4242
export const collapseWhitespace = (str: string): string =>
4343
// Replace all whitespace with a single space
4444
str.replace(/\s\s+/g, ' ');
45+
46+
export const getStringsFromCommaSeparatedList = (text: string): string[] =>
47+
text
48+
.trim()
49+
.split(',')
50+
.map(part => part.trim())
51+
.filter(part => part !== '');
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { areEmailAddressesValid, isEmailAddressValid } from '@hypertrace/common';
2+
3+
describe('Email validator', () => {
4+
test('can validate email correctly', () => {
5+
expect(isEmailAddressValid('[email protected]')).toBe(true);
6+
expect(isEmailAddressValid('[email protected]')).toBe(true);
7+
expect(isEmailAddressValid('[email protected]')).toBe(true);
8+
expect(isEmailAddressValid('test@test.')).toBe(false);
9+
expect(isEmailAddressValid('test')).toBe(false);
10+
expect(isEmailAddressValid('test@test-')).toBe(false);
11+
expect(isEmailAddressValid('tes\t@test-')).toBe(false);
12+
expect(isEmailAddressValid('test@@test.ai')).toBe(false);
13+
expect(isEmailAddressValid('test@@test.ai')).toBe(false);
14+
});
15+
16+
test('can validate email lists correctly', () => {
17+
expect(areEmailAddressesValid(['[email protected]', '[email protected]'])).toBe(true);
18+
expect(areEmailAddressesValid(['[email protected]', 'test.email@@test.ai'])).toBe(false);
19+
});
20+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const isEmailAddressValid = (emailAddress: string) => {
2+
// Regex as per W3C spec for email field
3+
// Source: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
4+
const regex: RegExp = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
5+
6+
return regex.test(emailAddress);
7+
};
8+
9+
export const areEmailAddressesValid = (emailAddresses: string[]) =>
10+
emailAddresses.filter(emailAddress => !isEmailAddressValid(emailAddress)).length === 0;

0 commit comments

Comments
 (0)