Skip to content

Commit 286f607

Browse files
committed
refactor: simplify username validation logic and enhance error handling
1 parent 5628c0b commit 286f607

File tree

2 files changed

+86
-204
lines changed

2 files changed

+86
-204
lines changed

src/validateUsername.ts

Lines changed: 27 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,59 @@
11
import { ValidateFunctions } from "./types";
22

3-
const regexHasSpaces: RegExp = /\s/;
4-
const regexOnlyNumbers: RegExp = /^\d+$/;
5-
const regexStartsWithNumber: RegExp = /^\d/;
63
const defaultErrorMsg: string[] = [
74
"Username cannot be empty",
85
"Username too short",
96
"This username is too long",
10-
"Username cannot contain spaces",
11-
"Cannot start with a number",
12-
"Cannot contain only numbers",
7+
"Invalid username",
138
];
149

1510
interface OptionsParams {
1611
minLength?: number;
1712
maxLength?: number;
13+
cbValidate?: (username: string) => boolean;
1814
errorMsg?: (string | null)[];
1915
}
2016

2117
const defaultOptionsParams: OptionsParams = {
2218
minLength: undefined,
2319
maxLength: undefined,
20+
cbValidate: undefined,
2421
errorMsg: defaultErrorMsg,
2522
};
2623

2724
/**
2825
* @param username
2926
* @param minLength optional
3027
* @param maxLength optional
28+
* @param cbValidate optional
3129
* @param errorMsg optional
3230
* @default minLength number: 1
3331
* @default maxLength number: Infinity
34-
* @example validateUsername('User999', { minLength: 8, maxLength: 20 });
35-
* @example validateUsername('User999', { minLength: 8, maxLength: 20, errorMsg: ['My own errorsMsg'] });
32+
* @default cbValidate function: undefined
3633
* @info minLength cannot be greater than maxLength
37-
* @description This function returns 7 errors in the following order,
34+
* @description This function returns 4 errors in the following order,
3835
*
3936
* If you want to use a default parameter, use null.
4037
*
4138
* Default:
42-
* [
43-
'Username cannot be empty',
44-
'Username must be between ${maxLenthUsername} and ${maxLenthUsername} characters',
45-
'Username must be between ${maxLenthUsername} and ${maxLenthUsername} characters',
46-
'Username cannot contain spaces',
47-
'Cannot start with a number',
48-
'Cannot contain only numbers',
39+
* [
40+
"Username cannot be empty",
41+
"Username must be between ${maxLenthUsername} and ${maxLenthUsername} characters",
42+
"Username must be between ${maxLenthUsername} and ${maxLenthUsername} characters",
43+
"Invalid username",
4944
];
5045
*
5146
* Create a list of errors separated by commas in strings
52-
* @returns An object with 'isValid' (boolean) and 'errorMsg' (string) properties.
47+
* @returns An object with "isValid" (boolean) and "errorMsg" (string) properties.
5348
*/
5449
function validateUsername(
5550
username: string,
56-
{ minLength, maxLength, errorMsg }: OptionsParams = defaultOptionsParams,
51+
{
52+
minLength,
53+
maxLength,
54+
cbValidate,
55+
errorMsg,
56+
}: OptionsParams = defaultOptionsParams,
5757
): ValidateFunctions {
5858
if (typeof username !== "string") {
5959
throw new TypeError("The input should be a string.");
@@ -78,39 +78,6 @@ function validateUsername(
7878

7979
validateLengthParams(minLenthUsername, maxLenthUsername);
8080

81-
if (regexHasSpaces.test(username)) {
82-
return {
83-
isValid: false,
84-
errorMsg: getErrorMessage(
85-
3,
86-
errorMsg,
87-
minLenthUsername,
88-
maxLenthUsername,
89-
),
90-
};
91-
}
92-
if (regexOnlyNumbers.test(username)) {
93-
return {
94-
isValid: false,
95-
errorMsg: getErrorMessage(
96-
5,
97-
errorMsg,
98-
minLenthUsername,
99-
maxLenthUsername,
100-
),
101-
};
102-
}
103-
if (regexStartsWithNumber.test(username)) {
104-
return {
105-
isValid: false,
106-
errorMsg: getErrorMessage(
107-
4,
108-
errorMsg,
109-
minLenthUsername,
110-
maxLenthUsername,
111-
),
112-
};
113-
}
11481
if (username.length < minLenthUsername) {
11582
return {
11683
isValid: false,
@@ -134,10 +101,15 @@ function validateUsername(
134101
};
135102
}
136103

137-
if (containsMultipleSpecialChars(username)) {
104+
if (cbValidate && !cbValidate(username)) {
138105
return {
139106
isValid: false,
140-
errorMsg: "Username cannot contain multiple special characters",
107+
errorMsg: getErrorMessage(
108+
3,
109+
errorMsg,
110+
minLenthUsername,
111+
maxLenthUsername,
112+
),
141113
};
142114
}
143115

@@ -171,9 +143,11 @@ function validateLengthParams(
171143
) {
172144
throw new Error("maxLength or minLength must be a number");
173145
}
146+
174147
if (minLenthUsername > maxLenthUsername) {
175148
throw new Error("Minimum cannot be greater than maximum");
176149
}
150+
177151
if (minLenthUsername < 1 || maxLenthUsername < 1) {
178152
throw new Error("Size parameters cannot be less than one");
179153
}
@@ -197,50 +171,4 @@ function getErrorMessage(
197171
return errorMessage ?? defaultErrorMsg[index];
198172
}
199173

200-
function containsMultipleSpecialChars(username: string): boolean {
201-
const specialChars: string[] = [
202-
"!",
203-
"@",
204-
"#",
205-
"$",
206-
"%",
207-
"^",
208-
"&",
209-
"*",
210-
"(",
211-
")",
212-
"-",
213-
"_",
214-
"=",
215-
"+",
216-
"[",
217-
"]",
218-
"{",
219-
"}",
220-
"|",
221-
"\\",
222-
";",
223-
":",
224-
"'",
225-
'"',
226-
",",
227-
".",
228-
"<",
229-
">",
230-
"/",
231-
"?",
232-
];
233-
234-
const charCount: { [key: string]: number } = {};
235-
236-
for (const char of username) {
237-
if (specialChars.includes(char)) {
238-
charCount[char] = (charCount[char] || 0) + 1;
239-
if (charCount[char] > 2) {
240-
return true;
241-
}
242-
}
243-
}
244-
return false;
245-
}
246174
export default validateUsername;

0 commit comments

Comments
 (0)