dce-reactkit 3.5.1-beta.1 → 3.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +0 -2
- package/dist/cjs/index.js +320 -27
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/client/initClient.d.ts +1 -1
- package/dist/cjs/types/components/AppWrapper.d.ts +6 -6
- package/dist/cjs/types/components/ButtonInputGroup.d.ts +1 -1
- package/dist/cjs/types/components/CSVDownloadButton.d.ts +1 -1
- package/dist/cjs/types/components/CheckboxButton.d.ts +1 -1
- package/dist/cjs/types/components/CopiableBox.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/AddOrEditDBEntry/CreatableMultiselect.d.ts +7 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/AddOrEditDBEntry/index.d.ts +5 -4
- package/dist/cjs/types/components/DBEntryManagerPanel/helpers/generateEndpointPath.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/index.d.ts +13 -2
- package/dist/cjs/types/components/DBEntryManagerPanel/types/DBEntry.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/types/DBEntryField.d.ts +1 -1
- package/dist/cjs/types/components/Drawer.d.ts +1 -1
- package/dist/cjs/types/components/ErrorBox.d.ts +1 -1
- package/dist/cjs/types/components/IntelliTable.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/NestableItemList.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/index.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/types/PickableItem.d.ts +1 -1
- package/dist/cjs/types/components/LogReviewer.d.ts +1 -1
- package/dist/cjs/types/components/Modal.d.ts +1 -1
- package/dist/cjs/types/components/PopFailureMark.d.ts +1 -1
- package/dist/cjs/types/components/PopPendingMark.d.ts +1 -1
- package/dist/cjs/types/components/PopSuccessMark.d.ts +1 -1
- package/dist/cjs/types/components/RadioButton.d.ts +1 -1
- package/dist/cjs/types/components/SimpleDateChooser.d.ts +1 -1
- package/dist/cjs/types/components/TabBox.d.ts +1 -1
- package/dist/cjs/types/helpers/abbreviate.test.d.ts +5 -0
- package/dist/cjs/types/helpers/addDBEditorEndpoints.d.ts +4 -3
- package/dist/cjs/types/helpers/avg.test.d.ts +5 -0
- package/dist/cjs/types/helpers/canReviewLogs.d.ts +5 -0
- package/dist/cjs/types/helpers/canReviewLogs.test.d.ts +5 -0
- package/dist/cjs/types/helpers/ceilToNumDecimals.test.d.ts +5 -0
- package/dist/cjs/types/helpers/compareArraysByProp.d.ts +3 -2
- package/dist/cjs/types/helpers/compareArraysByProp.test.d.ts +5 -0
- package/dist/cjs/types/helpers/extractProp.test.d.ts +5 -0
- package/dist/cjs/types/helpers/floorToNumDecimals.test.d.ts +5 -0
- package/dist/cjs/types/helpers/forceNumIntoBounds.test.d.ts +5 -0
- package/dist/cjs/types/helpers/genCSV.test.d.ts +5 -0
- package/dist/cjs/types/helpers/genCommaList.d.ts +12 -0
- package/dist/cjs/types/helpers/genCommaList.test.d.ts +1 -0
- package/dist/cjs/types/helpers/genRouteHandler.d.ts +7 -7
- package/dist/cjs/types/helpers/getHumanReadableDate.d.ts +1 -1
- package/dist/cjs/types/helpers/getHumanReadableDate.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getLocalTimeInfo.d.ts +1 -1
- package/dist/cjs/types/helpers/getLocalTimeInfo.test.d.ts +6 -0
- package/dist/cjs/types/helpers/getMonthName.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getOrdinal.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getPartOfDay.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getTimeInfoInET.d.ts +1 -1
- package/dist/cjs/types/helpers/getTimeInfoInET.test.d.ts +5 -0
- package/dist/cjs/types/helpers/parallelLimit.d.ts +1 -1
- package/dist/cjs/types/helpers/validators/shared/constants/ERROR_MESSAGES.d.ts +10 -0
- package/dist/cjs/types/helpers/validators/shared/helpers/validateRegex.d.ts +19 -0
- package/dist/cjs/types/helpers/validators/shared/types/ValidationResult.d.ts +12 -0
- package/dist/cjs/types/helpers/validators/validateEmail.d.ts +11 -0
- package/dist/cjs/types/helpers/validators/validateEmail.test.d.ts +1 -0
- package/dist/cjs/types/helpers/validators/validatePhoneNumber.d.ts +11 -0
- package/dist/cjs/types/helpers/validators/validatePhoneNumber.test.d.ts +1 -0
- package/dist/cjs/types/helpers/validators/validateString.d.ts +22 -0
- package/dist/cjs/types/helpers/validators/validateString.test.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +5 -1
- package/dist/cjs/types/server/initServer.d.ts +1 -1
- package/dist/cjs/types/types/IntelliTableColumn.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogMainInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogSourceSpecificInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogTypeSpecificInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/index.d.ts +1 -1
- package/dist/cjs/types/types/LogFunction.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataContextMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataTagMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataTargetMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataType.d.ts +1 -1
- package/dist/esm/index.js +317 -28
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/client/initClient.d.ts +1 -1
- package/dist/esm/types/components/AppWrapper.d.ts +6 -6
- package/dist/esm/types/components/ButtonInputGroup.d.ts +1 -1
- package/dist/esm/types/components/CSVDownloadButton.d.ts +1 -1
- package/dist/esm/types/components/CheckboxButton.d.ts +1 -1
- package/dist/esm/types/components/CopiableBox.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/AddOrEditDBEntry/CreatableMultiselect.d.ts +7 -1
- package/dist/esm/types/components/DBEntryManagerPanel/AddOrEditDBEntry/index.d.ts +5 -4
- package/dist/esm/types/components/DBEntryManagerPanel/helpers/generateEndpointPath.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/index.d.ts +13 -2
- package/dist/esm/types/components/DBEntryManagerPanel/types/DBEntry.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/types/DBEntryField.d.ts +1 -1
- package/dist/esm/types/components/Drawer.d.ts +1 -1
- package/dist/esm/types/components/ErrorBox.d.ts +1 -1
- package/dist/esm/types/components/IntelliTable.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/NestableItemList.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/index.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/types/PickableItem.d.ts +1 -1
- package/dist/esm/types/components/LogReviewer.d.ts +1 -1
- package/dist/esm/types/components/Modal.d.ts +1 -1
- package/dist/esm/types/components/PopFailureMark.d.ts +1 -1
- package/dist/esm/types/components/PopPendingMark.d.ts +1 -1
- package/dist/esm/types/components/PopSuccessMark.d.ts +1 -1
- package/dist/esm/types/components/RadioButton.d.ts +1 -1
- package/dist/esm/types/components/SimpleDateChooser.d.ts +1 -1
- package/dist/esm/types/components/TabBox.d.ts +1 -1
- package/dist/esm/types/helpers/abbreviate.test.d.ts +5 -0
- package/dist/esm/types/helpers/addDBEditorEndpoints.d.ts +4 -3
- package/dist/esm/types/helpers/avg.test.d.ts +5 -0
- package/dist/esm/types/helpers/canReviewLogs.d.ts +5 -0
- package/dist/esm/types/helpers/canReviewLogs.test.d.ts +5 -0
- package/dist/esm/types/helpers/ceilToNumDecimals.test.d.ts +5 -0
- package/dist/esm/types/helpers/compareArraysByProp.d.ts +3 -2
- package/dist/esm/types/helpers/compareArraysByProp.test.d.ts +5 -0
- package/dist/esm/types/helpers/extractProp.test.d.ts +5 -0
- package/dist/esm/types/helpers/floorToNumDecimals.test.d.ts +5 -0
- package/dist/esm/types/helpers/forceNumIntoBounds.test.d.ts +5 -0
- package/dist/esm/types/helpers/genCSV.test.d.ts +5 -0
- package/dist/esm/types/helpers/genCommaList.d.ts +12 -0
- package/dist/esm/types/helpers/genCommaList.test.d.ts +1 -0
- package/dist/esm/types/helpers/genRouteHandler.d.ts +7 -7
- package/dist/esm/types/helpers/getHumanReadableDate.d.ts +1 -1
- package/dist/esm/types/helpers/getHumanReadableDate.test.d.ts +5 -0
- package/dist/esm/types/helpers/getLocalTimeInfo.d.ts +1 -1
- package/dist/esm/types/helpers/getLocalTimeInfo.test.d.ts +6 -0
- package/dist/esm/types/helpers/getMonthName.test.d.ts +5 -0
- package/dist/esm/types/helpers/getOrdinal.test.d.ts +5 -0
- package/dist/esm/types/helpers/getPartOfDay.test.d.ts +5 -0
- package/dist/esm/types/helpers/getTimeInfoInET.d.ts +1 -1
- package/dist/esm/types/helpers/getTimeInfoInET.test.d.ts +5 -0
- package/dist/esm/types/helpers/parallelLimit.d.ts +1 -1
- package/dist/esm/types/helpers/validators/shared/constants/ERROR_MESSAGES.d.ts +10 -0
- package/dist/esm/types/helpers/validators/shared/helpers/validateRegex.d.ts +19 -0
- package/dist/esm/types/helpers/validators/shared/types/ValidationResult.d.ts +12 -0
- package/dist/esm/types/helpers/validators/validateEmail.d.ts +11 -0
- package/dist/esm/types/helpers/validators/validateEmail.test.d.ts +1 -0
- package/dist/esm/types/helpers/validators/validatePhoneNumber.d.ts +11 -0
- package/dist/esm/types/helpers/validators/validatePhoneNumber.test.d.ts +1 -0
- package/dist/esm/types/helpers/validators/validateString.d.ts +22 -0
- package/dist/esm/types/helpers/validators/validateString.test.d.ts +1 -0
- package/dist/esm/types/index.d.ts +5 -1
- package/dist/esm/types/server/initServer.d.ts +1 -1
- package/dist/esm/types/types/IntelliTableColumn.d.ts +1 -1
- package/dist/esm/types/types/Log/LogMainInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/LogSourceSpecificInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/LogTypeSpecificInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/index.d.ts +1 -1
- package/dist/esm/types/types/LogFunction.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataContextMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataTagMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataTargetMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataType.d.ts +1 -1
- package/dist/index.d.ts +134 -56
- package/package.json +14 -13
- package/src/components/ItemPicker/index.test.tsx +10 -10
- package/src/helpers/abbreviate.test.ts +26 -0
- package/src/helpers/avg.test.ts +24 -0
- package/src/helpers/canReviewLogs.test.ts +67 -0
- package/src/helpers/canReviewLogs.ts +20 -0
- package/src/helpers/ceilToNumDecimals.test.ts +39 -0
- package/src/helpers/compareArraysByProp.test.ts +147 -0
- package/src/helpers/compareArraysByProp.ts +41 -22
- package/src/helpers/extractProp.test.ts +34 -0
- package/src/helpers/floorToNumDecimals.test.ts +39 -0
- package/src/helpers/forceNumIntoBounds.test.ts +34 -0
- package/src/helpers/genCSV.test.ts +61 -0
- package/src/helpers/genCSV.ts +5 -2
- package/src/helpers/genCommaList.test.ts +57 -0
- package/src/helpers/genCommaList.ts +21 -0
- package/src/helpers/getHumanReadableDate.test.ts +29 -0
- package/src/helpers/getLocalTimeInfo.test.ts +48 -0
- package/src/helpers/getMonthName.test.ts +79 -0
- package/src/helpers/getOrdinal.test.ts +84 -0
- package/src/helpers/{getOrdinal.tsx → getOrdinal.ts} +1 -0
- package/src/helpers/getPartOfDay.test.ts +56 -0
- package/src/helpers/getTimeInfoInET.test.ts +72 -0
- package/src/helpers/validators/shared/constants/ERROR_MESSAGES.ts +18 -0
- package/src/helpers/validators/shared/helpers/validateRegex.ts +47 -0
- package/src/helpers/validators/shared/types/ValidationResult.ts +20 -0
- package/src/helpers/validators/validateEmail.test.ts +110 -0
- package/src/helpers/validators/validateEmail.ts +47 -0
- package/src/helpers/validators/validatePhoneNumber.test.ts +94 -0
- package/src/helpers/validators/validatePhoneNumber.ts +49 -0
- package/src/helpers/validators/validateString.test.ts +173 -0
- package/src/helpers/validators/validateString.ts +171 -0
- package/src/index.ts +8 -0
- package/tsconfig.json +6 -2
- /package/src/helpers/{abbreviate.tsx → abbreviate.ts} +0 -0
- /package/src/helpers/{avg.tsx → avg.ts} +0 -0
- /package/src/helpers/{ceilToNumDecimals.tsx → ceilToNumDecimals.ts} +0 -0
- /package/src/helpers/{floorToNumDecimals.tsx → floorToNumDecimals.ts} +0 -0
- /package/src/helpers/{forceNumIntoBounds.tsx → forceNumIntoBounds.ts} +0 -0
- /package/src/helpers/{getLocalTimeInfo.tsx → getLocalTimeInfo.ts} +0 -0
- /package/src/helpers/{getTimeInfoInET.tsx → getTimeInfoInET.ts} +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Import types
|
|
2
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
3
|
+
|
|
4
|
+
// Import constants
|
|
5
|
+
import { INVALID_EMAIL_ERROR } from './shared/constants/ERROR_MESSAGES';
|
|
6
|
+
|
|
7
|
+
// Import function
|
|
8
|
+
import validateEmail from './validateEmail';
|
|
9
|
+
|
|
10
|
+
/*------------------------------------------------------------------------*/
|
|
11
|
+
/* ---------------------------- Valid Tests --------------------------- */
|
|
12
|
+
/*------------------------------------------------------------------------*/
|
|
13
|
+
|
|
14
|
+
const validEmailPairs: { input: string, cleaned: string }[] = [
|
|
15
|
+
{
|
|
16
|
+
input: 'username@gmail.com',
|
|
17
|
+
cleaned: 'username@gmail.com',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
input: 'u@hotmail.org',
|
|
21
|
+
cleaned: 'u@hotmail.org',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
input: ' username@gmail.com',
|
|
25
|
+
cleaned: 'username@gmail.com',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
input: 'username@gmail.com ',
|
|
29
|
+
cleaned: 'username@gmail.com',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
input: ' username@gmail.com ',
|
|
33
|
+
cleaned: 'username@gmail.com',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
input: 'username@harvard.edu',
|
|
37
|
+
cleaned: 'username@harvard.edu',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
input: 'username@harvard.subdomain.edu',
|
|
41
|
+
cleaned: 'username@harvard.subdomain.edu',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
input: '\nusername@harvard.subdomain.edu',
|
|
45
|
+
cleaned: 'username@harvard.subdomain.edu',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
input: '\n\tusername@harvard.subdomain.edu',
|
|
49
|
+
cleaned: 'username@harvard.subdomain.edu',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
input: 'username@harvard.subdomain.edu\n',
|
|
53
|
+
cleaned: 'username@harvard.subdomain.edu',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
input: 'username@harvard.subdomain.edu\n\t',
|
|
57
|
+
cleaned: 'username@harvard.subdomain.edu',
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
test(
|
|
62
|
+
'Returns true for a given valid email and removes any leading or trailing whitespace.',
|
|
63
|
+
async () => {
|
|
64
|
+
validEmailPairs.forEach((pair) => {
|
|
65
|
+
const validResponse: ValidationResult<string> = {
|
|
66
|
+
isValid: true,
|
|
67
|
+
cleanedValue: pair.cleaned,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
expect(validateEmail(pair.input)).toStrictEqual(validResponse);
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
/*------------------------------------------------------------------------*/
|
|
76
|
+
/* ---------------------------- Invalid Tests --------------------------- */
|
|
77
|
+
/*------------------------------------------------------------------------*/
|
|
78
|
+
|
|
79
|
+
const invalidEmails: string[] = [
|
|
80
|
+
'',
|
|
81
|
+
' ',
|
|
82
|
+
'gmail.com',
|
|
83
|
+
'@gmail.com ',
|
|
84
|
+
'username',
|
|
85
|
+
'username@.com',
|
|
86
|
+
'user name@gmail.com',
|
|
87
|
+
'username @gmail.com',
|
|
88
|
+
'username@ gmail.com',
|
|
89
|
+
'username@gmail .com',
|
|
90
|
+
'username\t@gmail.com',
|
|
91
|
+
'username\n@gmail.com',
|
|
92
|
+
'username@gmail\n.com',
|
|
93
|
+
'username@gmail.\tcom',
|
|
94
|
+
'user\nname@gmail.com',
|
|
95
|
+
'user\tname@gmail.com',
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
const invalidResponse: ValidationResult<string> = {
|
|
99
|
+
isValid: false,
|
|
100
|
+
errorMessage: INVALID_EMAIL_ERROR,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
test(
|
|
104
|
+
'Returns false for a given invalid email.',
|
|
105
|
+
async () => {
|
|
106
|
+
invalidEmails.forEach((email) => {
|
|
107
|
+
expect(validateEmail(email)).toStrictEqual(invalidResponse);
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Import helpers
|
|
2
|
+
import validateRegex from './shared/helpers/validateRegex';
|
|
3
|
+
|
|
4
|
+
// Import constants
|
|
5
|
+
import { INVALID_EMAIL_ERROR } from './shared/constants/ERROR_MESSAGES';
|
|
6
|
+
|
|
7
|
+
// Import types
|
|
8
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Determines whether a given email address is valid.
|
|
12
|
+
* @author Austen Money
|
|
13
|
+
* @param email email address to validate
|
|
14
|
+
* @returns whether email fulfills proper formatting requirements, includes a
|
|
15
|
+
* cleaned version of the address without leading or trailing
|
|
16
|
+
* whitespace if valid or an error message if invalid.
|
|
17
|
+
*/
|
|
18
|
+
const validateEmail = (
|
|
19
|
+
email: string,
|
|
20
|
+
): ValidationResult<string> => {
|
|
21
|
+
// validation regex, sourced from HTML living standard: http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#e-mail-state-(type=email)
|
|
22
|
+
// eslint-disable-next-line max-len
|
|
23
|
+
const emailRegex = /^[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])?)*$/;
|
|
24
|
+
|
|
25
|
+
// remove leading and trailing whitespace
|
|
26
|
+
const cleanedValue: string = email.replace(/^\s+|\s+$/g, '');
|
|
27
|
+
|
|
28
|
+
// validate email with regex, and return error if not valid
|
|
29
|
+
return (
|
|
30
|
+
validateRegex(
|
|
31
|
+
{
|
|
32
|
+
input: cleanedValue,
|
|
33
|
+
regex: emailRegex,
|
|
34
|
+
},
|
|
35
|
+
).isValid
|
|
36
|
+
? {
|
|
37
|
+
isValid: true,
|
|
38
|
+
cleanedValue,
|
|
39
|
+
}
|
|
40
|
+
: {
|
|
41
|
+
isValid: false,
|
|
42
|
+
errorMessage: INVALID_EMAIL_ERROR,
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default validateEmail;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Import types
|
|
2
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
3
|
+
|
|
4
|
+
// Import constants
|
|
5
|
+
import { INVALID_PHONE_ERROR } from './shared/constants/ERROR_MESSAGES';
|
|
6
|
+
|
|
7
|
+
// Import function
|
|
8
|
+
import validatePhoneNumber from './validatePhoneNumber';
|
|
9
|
+
|
|
10
|
+
/*------------------------------------------------------------------------*/
|
|
11
|
+
/* ---------------------------- Valid Tests --------------------------- */
|
|
12
|
+
/*------------------------------------------------------------------------*/
|
|
13
|
+
|
|
14
|
+
const cleanedNumber = '1234567890';
|
|
15
|
+
const cleanedNumberExt = '11234567890';
|
|
16
|
+
|
|
17
|
+
const validPhoneNumbers: { input: string, cleaned: string }[] = [
|
|
18
|
+
{
|
|
19
|
+
input: '1234567890',
|
|
20
|
+
cleaned: cleanedNumber,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
input: '(123)-456-7890',
|
|
24
|
+
cleaned: cleanedNumber,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
input: '123-456-7890',
|
|
28
|
+
cleaned: cleanedNumber,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
input: '(123)456-7890',
|
|
32
|
+
cleaned: cleanedNumber,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
input: '(123)4567890',
|
|
36
|
+
cleaned: cleanedNumber,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
input: ' 123456-7890 ',
|
|
40
|
+
cleaned: cleanedNumber,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
input: '+1 123 456 7890',
|
|
44
|
+
cleaned: cleanedNumberExt,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
input: '+1123456 7890',
|
|
48
|
+
cleaned: cleanedNumberExt,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
input: '+1(123)456-7890',
|
|
52
|
+
cleaned: cleanedNumberExt,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
test(
|
|
57
|
+
'Returns true for a given valid phone number and removes any non-digit characters.',
|
|
58
|
+
async () => {
|
|
59
|
+
validPhoneNumbers.forEach((pair) => {
|
|
60
|
+
const validResponse: ValidationResult<string> = {
|
|
61
|
+
isValid: true,
|
|
62
|
+
cleanedValue: pair.cleaned,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
expect(validatePhoneNumber(pair.input)).toStrictEqual(validResponse);
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/*------------------------------------------------------------------------*/
|
|
71
|
+
/* ---------------------------- Invalid Tests --------------------------- */
|
|
72
|
+
/*------------------------------------------------------------------------*/
|
|
73
|
+
|
|
74
|
+
const invalidPhoneNumbers: string[] = [
|
|
75
|
+
'123456789',
|
|
76
|
+
'1234567894567890',
|
|
77
|
+
'1234-567-890',
|
|
78
|
+
'123456m78',
|
|
79
|
+
'123 4567 890',
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
const invalidResponse: ValidationResult<string> = {
|
|
83
|
+
isValid: false,
|
|
84
|
+
errorMessage: INVALID_PHONE_ERROR,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
test(
|
|
88
|
+
'Returns false for a given valid phone number.',
|
|
89
|
+
async () => {
|
|
90
|
+
invalidPhoneNumbers.forEach((phoneNumber) => {
|
|
91
|
+
expect(validatePhoneNumber(phoneNumber)).toStrictEqual(invalidResponse);
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Import helpers
|
|
2
|
+
import validateRegex from './shared/helpers/validateRegex';
|
|
3
|
+
|
|
4
|
+
// Import constants
|
|
5
|
+
import { INVALID_PHONE_ERROR } from './shared/constants/ERROR_MESSAGES';
|
|
6
|
+
|
|
7
|
+
// Import types
|
|
8
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Determines whether a given phone number is valid.
|
|
12
|
+
* @author Austen Money
|
|
13
|
+
* @param phoneNumber phone number to validate
|
|
14
|
+
* @returns whether phone number is considered valid - if valid, also returns
|
|
15
|
+
* a cleaned version of the number without any formatting. If invalid,
|
|
16
|
+
* returns an error message.
|
|
17
|
+
*/
|
|
18
|
+
const validatePhoneNumber = (
|
|
19
|
+
phoneNumber: string,
|
|
20
|
+
): ValidationResult<string> => {
|
|
21
|
+
// regex to validate phone number
|
|
22
|
+
const validationRegex = /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/;
|
|
23
|
+
|
|
24
|
+
// validate phone number with regex
|
|
25
|
+
const validationResponse = validateRegex(
|
|
26
|
+
{
|
|
27
|
+
input: phoneNumber,
|
|
28
|
+
regex: validationRegex,
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// remove all non-digits from number
|
|
33
|
+
const cleanedValue: string = phoneNumber.replace(/\D/g, '');
|
|
34
|
+
|
|
35
|
+
// return cleaned value if valid, or error message if invalid
|
|
36
|
+
return (
|
|
37
|
+
validationResponse.isValid
|
|
38
|
+
? {
|
|
39
|
+
isValid: true,
|
|
40
|
+
cleanedValue,
|
|
41
|
+
}
|
|
42
|
+
: {
|
|
43
|
+
isValid: false,
|
|
44
|
+
errorMessage: INVALID_PHONE_ERROR,
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default validatePhoneNumber;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Import helpers
|
|
2
|
+
import genCommaList from '../genCommaList';
|
|
3
|
+
|
|
4
|
+
// Import types
|
|
5
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
6
|
+
|
|
7
|
+
// Import constants
|
|
8
|
+
import { INVALID_STRING_ERRORS, INVALID_REGEX_ERROR } from './shared/constants/ERROR_MESSAGES';
|
|
9
|
+
|
|
10
|
+
// Import function
|
|
11
|
+
import validateString from './validateString';
|
|
12
|
+
|
|
13
|
+
/*------------------------------------------------------------------------*/
|
|
14
|
+
/* ---------------------------- Valid Tests --------------------------- */
|
|
15
|
+
/*------------------------------------------------------------------------*/
|
|
16
|
+
|
|
17
|
+
const validStrings: string[] = [
|
|
18
|
+
'users',
|
|
19
|
+
'username',
|
|
20
|
+
'MyValidString',
|
|
21
|
+
'HereisAnotherValidString',
|
|
22
|
+
'WoahAnotherValidStringIsHere',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const validReqs: {
|
|
26
|
+
// whitespace is removed from input before checking and returning
|
|
27
|
+
ignoreWhitespace?: boolean,
|
|
28
|
+
// input length must be at least minLen
|
|
29
|
+
minLen?: number,
|
|
30
|
+
// input length must be at most maxLen
|
|
31
|
+
maxLen?: number,
|
|
32
|
+
// input must only contain letters
|
|
33
|
+
lettersOnly?: boolean,
|
|
34
|
+
// input must only contain numbers
|
|
35
|
+
numbersOnly?: boolean,
|
|
36
|
+
// input must match given regExp
|
|
37
|
+
regexTest?: RegExp,
|
|
38
|
+
// description of regExp test, used to customize error messages
|
|
39
|
+
regexDescription?: string,
|
|
40
|
+
}[] = [
|
|
41
|
+
{
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
minLen: 5,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
minLen: 5,
|
|
48
|
+
maxLen: 30,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
minLen: 5,
|
|
52
|
+
maxLen: 30,
|
|
53
|
+
lettersOnly: true,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
minLen: 5,
|
|
57
|
+
maxLen: 30,
|
|
58
|
+
lettersOnly: true,
|
|
59
|
+
numbersOnly: false,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
minLen: 5,
|
|
63
|
+
maxLen: 30,
|
|
64
|
+
lettersOnly: true,
|
|
65
|
+
numbersOnly: false,
|
|
66
|
+
ignoreWhitespace: false,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
test(
|
|
71
|
+
'Returns true for a given valid string.',
|
|
72
|
+
async () => {
|
|
73
|
+
validStrings.forEach((validString) => {
|
|
74
|
+
validReqs.forEach((validReq) => {
|
|
75
|
+
const validResponse: ValidationResult<string> = {
|
|
76
|
+
isValid: true,
|
|
77
|
+
cleanedValue: validString,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
expect(validateString(validString, validReq)).toStrictEqual(validResponse);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const validString = 'A string with whitespace!';
|
|
85
|
+
|
|
86
|
+
const validResponse: ValidationResult<string> = {
|
|
87
|
+
isValid: true,
|
|
88
|
+
cleanedValue: 'Astringwithwhitespace!',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const validOpt = {
|
|
92
|
+
maxLen: 22,
|
|
93
|
+
ignoreWhitespace: true,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
expect(validateString(validString, validOpt)).toStrictEqual(validResponse);
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
/*------------------------------------------------------------------------*/
|
|
101
|
+
/* ---------------------------- Invalid Tests --------------------------- */
|
|
102
|
+
/*------------------------------------------------------------------------*/
|
|
103
|
+
|
|
104
|
+
const invalidStrings: {
|
|
105
|
+
input: string,
|
|
106
|
+
reqs: {
|
|
107
|
+
// whitespace is removed from input before checking and returning
|
|
108
|
+
ignoreWhitespace?: boolean,
|
|
109
|
+
// input length must be at least minLen
|
|
110
|
+
minLen?: number,
|
|
111
|
+
// input length must be at most maxLen
|
|
112
|
+
maxLen?: number,
|
|
113
|
+
// input must only contain letters
|
|
114
|
+
lettersOnly?: boolean,
|
|
115
|
+
// input must only contain numbers
|
|
116
|
+
numbersOnly?: boolean,
|
|
117
|
+
// input must match given regExp
|
|
118
|
+
regexTest?: RegExp,
|
|
119
|
+
// description of regExp test, used to customize error messages
|
|
120
|
+
regexDescription?: string,
|
|
121
|
+
},
|
|
122
|
+
error: string[]
|
|
123
|
+
}[] = [
|
|
124
|
+
{
|
|
125
|
+
input: 'ûšër',
|
|
126
|
+
reqs: {
|
|
127
|
+
minLen: 5,
|
|
128
|
+
lettersOnly: true,
|
|
129
|
+
},
|
|
130
|
+
error: [INVALID_STRING_ERRORS.MIN_LEN(5)],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
input: '123456789',
|
|
134
|
+
reqs: {
|
|
135
|
+
minLen: 10,
|
|
136
|
+
maxLen: 5,
|
|
137
|
+
lettersOnly: true,
|
|
138
|
+
},
|
|
139
|
+
error: [INVALID_STRING_ERRORS.MIN_LEN(10), INVALID_STRING_ERRORS.MAX_LEN(5), INVALID_STRING_ERRORS.LETTERS_ONLY],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
input: 'String with non-letters!!',
|
|
143
|
+
reqs: {
|
|
144
|
+
lettersOnly: true,
|
|
145
|
+
numbersOnly: true,
|
|
146
|
+
ignoreWhitespace: true,
|
|
147
|
+
},
|
|
148
|
+
error: [INVALID_STRING_ERRORS.LETTERS_ONLY, INVALID_STRING_ERRORS.NUMBERS_ONLY],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
input: '12345678',
|
|
152
|
+
reqs: {
|
|
153
|
+
lettersOnly: true,
|
|
154
|
+
regexTest: /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/,
|
|
155
|
+
regexDescription: 'should be a phone number',
|
|
156
|
+
},
|
|
157
|
+
error: [INVALID_STRING_ERRORS.LETTERS_ONLY, `${INVALID_REGEX_ERROR}: should be a phone number`],
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
test(
|
|
162
|
+
'Returns false for a given invalid string.',
|
|
163
|
+
async () => {
|
|
164
|
+
invalidStrings.forEach((triple) => {
|
|
165
|
+
const invalidResponse: ValidationResult<string> = {
|
|
166
|
+
isValid: false,
|
|
167
|
+
errorMessage: `${INVALID_STRING_ERRORS.MESSAGE_INTRO}${genCommaList(triple.error)}.`,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
expect(validateString(triple.input, triple.reqs)).toStrictEqual(invalidResponse);
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
);
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// Import helpers
|
|
2
|
+
import validateRegex from './shared/helpers/validateRegex';
|
|
3
|
+
import genCommaList from '../genCommaList';
|
|
4
|
+
|
|
5
|
+
// Import constants
|
|
6
|
+
import { INVALID_STRING_ERRORS } from './shared/constants/ERROR_MESSAGES';
|
|
7
|
+
|
|
8
|
+
// Import types
|
|
9
|
+
import ValidationResult from './shared/types/ValidationResult';
|
|
10
|
+
|
|
11
|
+
/*------------------------------------------------------------------------*/
|
|
12
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
13
|
+
/*------------------------------------------------------------------------*/
|
|
14
|
+
|
|
15
|
+
// define minimum and maximum range for lowercase ASCII chars
|
|
16
|
+
const LOWERCASE_MIN = 65;
|
|
17
|
+
const LOWERCASE_MAX = 90;
|
|
18
|
+
|
|
19
|
+
// define minimum and maximum range for uppercase ASCII chars
|
|
20
|
+
const UPPERCASE_MIN = 97;
|
|
21
|
+
const UPPERCASE_MAX = 122;
|
|
22
|
+
|
|
23
|
+
// define minimum and maximum range for ASCII digits
|
|
24
|
+
const DIGIT_MIN = 48;
|
|
25
|
+
const DIGIT_MAX = 57;
|
|
26
|
+
|
|
27
|
+
/*------------------------------------------------------------------------*/
|
|
28
|
+
/* ---------------------------- Main Function --------------------------- */
|
|
29
|
+
/*------------------------------------------------------------------------*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Determines whether a given input string is considered valid based on
|
|
33
|
+
* the provided requirements.
|
|
34
|
+
* @author Austen Money
|
|
35
|
+
* @param input input string
|
|
36
|
+
* @param opts options for validation
|
|
37
|
+
* @returns whether input is considered valid according to reqs - if
|
|
38
|
+
* valid, returns a cleaned version of input; if invalid, returns
|
|
39
|
+
* a string containing error messages describing which requirements
|
|
40
|
+
* were not met.
|
|
41
|
+
*/
|
|
42
|
+
const validateString = (
|
|
43
|
+
input: string,
|
|
44
|
+
opts: {
|
|
45
|
+
// whitespace is removed from input before checking and returning
|
|
46
|
+
ignoreWhitespace?: boolean,
|
|
47
|
+
// input length must be at least minLen
|
|
48
|
+
minLen?: number,
|
|
49
|
+
// input length must be at most maxLen
|
|
50
|
+
maxLen?: number,
|
|
51
|
+
// input must only contain letters
|
|
52
|
+
// (future TODO: add option for passing in an array of permitted chars)
|
|
53
|
+
lettersOnly?: boolean,
|
|
54
|
+
// input must only contain numbers
|
|
55
|
+
numbersOnly?: boolean,
|
|
56
|
+
// input must match given regExp
|
|
57
|
+
regexTest?: RegExp,
|
|
58
|
+
// description of regExp test, used to customize error messages
|
|
59
|
+
regexDescription?: string,
|
|
60
|
+
},
|
|
61
|
+
): ValidationResult<string> => {
|
|
62
|
+
// stores all invalid input errors
|
|
63
|
+
const errorMessages: string[] = [];
|
|
64
|
+
|
|
65
|
+
// contains version of input that will be returned
|
|
66
|
+
let cleanedValue: string = input;
|
|
67
|
+
|
|
68
|
+
// remove whitespace if required
|
|
69
|
+
if (opts.ignoreWhitespace) {
|
|
70
|
+
cleanedValue = input.replace(/\s+/g, '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// apply max char requirement
|
|
74
|
+
if (opts.minLen) {
|
|
75
|
+
if (cleanedValue.length < opts.minLen) {
|
|
76
|
+
errorMessages.push(INVALID_STRING_ERRORS.MIN_LEN(opts.minLen));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// apply max char requirement
|
|
81
|
+
if (opts.maxLen) {
|
|
82
|
+
if (cleanedValue.length > opts.maxLen) {
|
|
83
|
+
errorMessages.push(INVALID_STRING_ERRORS.MAX_LEN(opts.maxLen));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// apply alphabetical requirement
|
|
88
|
+
if (opts.lettersOnly) {
|
|
89
|
+
// remove diacritics
|
|
90
|
+
cleanedValue = cleanedValue.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
91
|
+
|
|
92
|
+
const containsNonLetters = (
|
|
93
|
+
cleanedValue
|
|
94
|
+
// split into characters
|
|
95
|
+
.split('')
|
|
96
|
+
// convert into character codes
|
|
97
|
+
.map((curr) => {
|
|
98
|
+
return curr.charCodeAt(0);
|
|
99
|
+
})
|
|
100
|
+
// check for non-letters
|
|
101
|
+
.some((currCode) => {
|
|
102
|
+
return (
|
|
103
|
+
!(currCode >= LOWERCASE_MIN && currCode <= LOWERCASE_MAX)
|
|
104
|
+
&& !(currCode >= UPPERCASE_MIN && currCode <= UPPERCASE_MAX)
|
|
105
|
+
);
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (containsNonLetters) {
|
|
110
|
+
errorMessages.push(INVALID_STRING_ERRORS.LETTERS_ONLY);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// apply numerical requirement
|
|
115
|
+
if (opts.numbersOnly) {
|
|
116
|
+
const containsNonNumbers = (
|
|
117
|
+
cleanedValue
|
|
118
|
+
// split into characters
|
|
119
|
+
.split('')
|
|
120
|
+
// convert into character codes
|
|
121
|
+
.map((curr) => {
|
|
122
|
+
return curr.charCodeAt(0);
|
|
123
|
+
})
|
|
124
|
+
// check for non-numbers
|
|
125
|
+
.some((currCode) => {
|
|
126
|
+
return (
|
|
127
|
+
!(currCode >= DIGIT_MIN && currCode <= DIGIT_MAX)
|
|
128
|
+
);
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
if (containsNonNumbers) {
|
|
133
|
+
errorMessages.push(INVALID_STRING_ERRORS.NUMBERS_ONLY);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// apply regex requirement
|
|
138
|
+
if (opts.regexTest) {
|
|
139
|
+
const regex = opts.regexTest;
|
|
140
|
+
|
|
141
|
+
// validate and create customized error message if description is provided
|
|
142
|
+
const result = validateRegex({
|
|
143
|
+
input: cleanedValue,
|
|
144
|
+
regex,
|
|
145
|
+
regexDescription: opts.regexDescription,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// if string did not pass regex validation, add error message
|
|
149
|
+
if (result.isValid === false) {
|
|
150
|
+
errorMessages.push(result.errorMessage);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// combine all error messages into one string to return
|
|
155
|
+
const errorMessage = `${INVALID_STRING_ERRORS.MESSAGE_INTRO}${genCommaList(errorMessages)}.`;
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
// if no error messages, string is valid; if not, it is invalid
|
|
159
|
+
errorMessages.length === 0
|
|
160
|
+
? {
|
|
161
|
+
isValid: true,
|
|
162
|
+
cleanedValue,
|
|
163
|
+
}
|
|
164
|
+
: {
|
|
165
|
+
isValid: false,
|
|
166
|
+
errorMessage,
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default validateString;
|
package/src/index.ts
CHANGED
|
@@ -66,6 +66,10 @@ import extractProp from './helpers/extractProp';
|
|
|
66
66
|
import compareArraysByProp from './helpers/compareArraysByProp';
|
|
67
67
|
import getLocalTimeInfo from './helpers/getLocalTimeInfo';
|
|
68
68
|
import addDBEditorEndpoints from './helpers/addDBEditorEndpoints';
|
|
69
|
+
import genCommaList from './helpers/genCommaList';
|
|
70
|
+
import validateEmail from './helpers/validators/validateEmail';
|
|
71
|
+
import validatePhoneNumber from './helpers/validators/validatePhoneNumber';
|
|
72
|
+
import validateString from './helpers/validators/validateString';
|
|
69
73
|
|
|
70
74
|
// Import types
|
|
71
75
|
import ModalButtonType from './types/ModalButtonType';
|
|
@@ -149,6 +153,10 @@ export {
|
|
|
149
153
|
isMobileOrTablet,
|
|
150
154
|
extractProp,
|
|
151
155
|
compareArraysByProp,
|
|
156
|
+
genCommaList,
|
|
157
|
+
validateEmail,
|
|
158
|
+
validatePhoneNumber,
|
|
159
|
+
validateString,
|
|
152
160
|
getLocalTimeInfo,
|
|
153
161
|
// Client helpers
|
|
154
162
|
initClient,
|
package/tsconfig.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|