ejv 1.1.9 → 1.1.11

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/src/tester.ts CHANGED
@@ -1,302 +1,302 @@
1
- import { DataType } from './constants';
2
-
3
- export const typeTester = (value : any, type : DataType) : boolean => {
4
- let valid : boolean;
5
-
6
- switch (type) {
7
- case DataType.BOOLEAN:
8
- valid = booleanTester(value);
9
- break;
10
-
11
- case DataType.NUMBER:
12
- valid = numberTester(value);
13
- break;
14
-
15
- case DataType.STRING:
16
- valid = stringTester(value);
17
- break;
18
-
19
- case DataType.OBJECT:
20
- valid = objectTester(value);
21
- break;
22
-
23
- case DataType.DATE:
24
- valid = dateTester(value);
25
- break;
26
-
27
- case DataType.REGEXP:
28
- valid = regExpTester(value);
29
- break;
30
-
31
- case DataType.ARRAY:
32
- valid = arrayTester(value);
33
- break;
34
- }
35
-
36
- return valid;
37
- };
38
-
39
- export const definedTester = (value : any) : value is boolean => {
40
- return value !== undefined;
41
- };
42
-
43
- export const enumTester = <T> (value : T, arr : T[]) : boolean => {
44
- return arr.includes(value);
45
- };
46
-
47
- export const lengthTester = (value : string | any[], length : number) : boolean => {
48
- return value.length === length;
49
- };
50
-
51
- export const minLengthTester = (value : string | any[], minLength : number) : boolean => {
52
- return value.length >= minLength;
53
- };
54
-
55
- export const maxLengthTester = (value : string | any[], maxLength : number) : boolean => {
56
- return value.length <= maxLength;
57
- };
58
-
59
- export const booleanTester = (value : any) : boolean => {
60
- return typeof value === 'boolean';
61
- };
62
-
63
- export const numberTester = (value : any) : value is number => {
64
- return typeof value === 'number';
65
- };
66
-
67
- export const integerTester = (value : number) : boolean => {
68
- return +value.toFixed(0) === value;
69
- };
70
-
71
- export const indexTester = (value : number) : value is number => {
72
- return integerTester(value) && value >= 0;
73
- };
74
-
75
- export const minNumberTester = (value : number, min : number) : boolean => {
76
- return value >= min;
77
- };
78
-
79
- export const exclusiveMinNumberTester = (value : number, min : number) : boolean => {
80
- return value > min;
81
- };
82
-
83
- export const maxNumberTester = (value : number, max : number) : boolean => {
84
- return value <= max;
85
- };
86
-
87
- export const exclusiveMaxNumberTester = (value : number, max : number) : boolean => {
88
- return value < max;
89
- };
90
-
91
- export const stringTester = (value : any) : value is string => {
92
- return typeof value === 'string';
93
- };
94
-
95
- export const stringRegExpTester = (value : string, regExp : string | RegExp) : boolean => {
96
- let valid : boolean = false;
97
-
98
- let _regExp : RegExp | undefined = undefined;
99
-
100
- if (regExpTester(regExp)) {
101
- _regExp = regExp as RegExp;
102
- }
103
- else if (stringTester(regExp)) {
104
- _regExp = new RegExp(regExp);
105
- }
106
-
107
- if (!!_regExp && regExpTester(_regExp)) {
108
- valid = _regExp.test(value);
109
- }
110
-
111
- return valid;
112
- };
113
-
114
- // RFC 5322, 3.4.1. spec
115
- export const emailTester = (value : string) : boolean => {
116
- let valid : boolean = false;
117
-
118
- if (stringTester(value) && stringRegExpTester(value, /^.+@.+$/)) {
119
- const valueAsString : string = value as string;
120
-
121
- const atIndex : number = valueAsString.lastIndexOf('@');
122
- const localPart : string = valueAsString.substr(0, atIndex);
123
- const domain : string = valueAsString.substr(atIndex + 1);
124
-
125
- // regular expression sources
126
- // const aTextRegExpStr : string = '[-a-zA-Z0-9!#$%&\\\'*+/=?^_`{|}~]+';
127
-
128
- const dotAtomRegExp : RegExp = /^(\.?[-a-zA-Z0-9!#$%&'*+/=?^_`{|}~]+)*$/;
129
- const quotedStringRegExp : RegExp = /^"[\u0020-\u005b\u005d-\u007e\\]*"$/; // include space (\u005b)
130
- const domainLiteralRegExp : RegExp = /^\[[\u0020-\u005a\u005c-\u007e\\]*]$/;
131
-
132
- const validLocalPart : boolean = localPart.length <= 64
133
- && (
134
- dotAtomRegExp.test(localPart)
135
- || quotedStringRegExp.test(localPart)
136
- );
137
-
138
- const validDomain : boolean = !domain.startsWith('.') && !domain.endsWith('.')
139
- && (
140
- dotAtomRegExp.test(domain)
141
- || domainLiteralRegExp.test(domain)
142
- );
143
-
144
- valid = validLocalPart && validDomain;
145
- }
146
-
147
- return valid;
148
- };
149
-
150
- // RFC 3339 (https://www.ietf.org/rfc/rfc3339.txt) : YYYY-MM-DDThh:mm:ss[.SSSZ]
151
- const rfc3339Tester = (value : string) : boolean => {
152
- return /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:([0-5][0-9])){2}(\.\d+)?(Z|[-+]\d{2}:\d{2})?$/.test(value);
153
- };
154
-
155
- const iso8601DateTester = (value : string) : boolean => {
156
- const years : string = '(\\d{4})';
157
- const months : string = '(0[1-9]|1[0-2])';
158
- const dates : string = '(0[1-9]|[1-2][0-9]|3[0-1])';
159
- const dateOfYear : string = '(00[1-9]|0[1-9][0-9]|[1-2]\\d{2}|3[0-5]\\d|36[0-6])'; // 366 for leap year
160
- const weeks : string = '(W(0[1-9]|[2-4][0-9]|5[0-3]))';
161
- const days : string = '[1-7]';
162
-
163
- return [
164
- new RegExp(`^[-+]?${ years }$`), // years : YYYY, +YYYY, -YYYY
165
- new RegExp(`^${ years }-${ months }(-${ dates })?$`), // calendar dates : YYYY-MM-DD, YYYY-MM
166
- new RegExp(`^${ years }${ months }${ dates }$`), // calendar dates : YYYYMMDD
167
- new RegExp(`^--${ months }-?${ dates }$`), // calendar dates : --MM-DD, --MMDD
168
- new RegExp(`^${ years }-${ weeks }(-${ days })?$`), // week dates : YYYY-Www, YYYY-Www-D
169
- new RegExp(`^${ years }${ weeks }(${ days })?$`), // week dates : YYYYWww, YYYYWwwD
170
- new RegExp(`^${ years }-?${ dateOfYear }$`) // ordinal dates : YYYY-DDD, YYYYDDD
171
- ].some((regExp : RegExp) => {
172
- return regExp.test(value);
173
- });
174
- };
175
-
176
- const iso8601TimeTester = (value : string) : boolean => {
177
- const hours : string = '([0-1]\\d|2[0-3])';
178
- const minutes : string = '([0-5]\\d)';
179
- const seconds : string = '([0-5]\\d|60)'; // 60 for leap second
180
- const ms : string = '(\\.[0-9]+)';
181
-
182
- return [
183
- new RegExp(`^(${ hours }|24)$`), // hh
184
- new RegExp(`^((${ hours }:${ minutes })|24:00)$`), // hh:mm
185
- new RegExp(`^((${ hours }:${ minutes }:${ seconds })|24:00:00)$`), // hh:mm:ss
186
- new RegExp(`^((${ hours }:${ minutes }:${ seconds }${ ms })|24:00:00\.0+)$`), // hh:mm:ss
187
-
188
- new RegExp(`^(${ hours }${ minutes }|2400)$`), // hhmm
189
- new RegExp(`^(${ hours }${ minutes }${ seconds }|240000)$`), // hhmmss
190
- new RegExp(`^(${ hours }${ minutes }${ seconds }${ ms }|240000\.0+)$`) // hhmmss.sss
191
- ]
192
- .some((regExp : RegExp) => {
193
- return regExp.test(value);
194
- });
195
- };
196
-
197
- const iso8601DateTimeTester = (value : string) : boolean => {
198
- let valid : boolean = false;
199
-
200
- if (/.+T.+/.test(value) // should have 1 'T'
201
- && /(Z|[-+]\d{2}:?\d{2})$/.test(value) // should end with 'Z' or timezone
202
- ) {
203
- let [date, time] = value.split('T');
204
-
205
- if (time.endsWith('Z')) {
206
- time = time.replace('Z', '');
207
- }
208
- else {
209
- const timezoneStartIndex : number = time.includes('+') ? time.indexOf('+') : time.indexOf('-');
210
-
211
- time = time.substr(0, timezoneStartIndex);
212
- }
213
-
214
- valid = iso8601DateTester(date) && iso8601TimeTester(time);
215
- }
216
-
217
- return valid;
218
- };
219
-
220
- export const dateFormatTester = (value : string) : boolean => {
221
- return iso8601DateTester(value);
222
- };
223
-
224
- export const timeFormatTester = (value : string) : boolean => {
225
- return iso8601TimeTester(value);
226
- };
227
-
228
- export const dateTimeFormatTester = (value : string) : boolean => {
229
- return rfc3339Tester(value) || iso8601DateTimeTester(value);
230
- };
231
-
232
- // // with port
233
- // export const urlTester = (value : any) : boolean => {
234
- // return stringTester(value)
235
- // && /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
236
- // };
237
- //
238
- // // TODO: with port
239
- // export const ipv4Tester = (value : any) : boolean => {
240
- // return stringTester(value)
241
- // && /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(value);
242
- // };
243
- //
244
- // export const ipv6Tester = (value : any) : boolean => {
245
- // return stringTester(value)
246
- // && /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$;/.test(value);
247
- // };
248
- //
249
- // export const ipTester = (value : any) : boolean => {
250
- // return ipv4Tester(value) || ipv6Tester(value);
251
- // };
252
-
253
- export const objectTester = (value : any) : value is { [key : string] : any } => {
254
- return typeof value === 'object';
255
- };
256
-
257
- export const hasPropertyTester = (value : object) : boolean => {
258
- return Object.keys(value).length > 0;
259
- };
260
-
261
- export const dateTester = (value : any) : value is Date => {
262
- return objectTester(value)
263
- && value !== null
264
- && typeof value.getFullYear === 'function'
265
- && !isNaN(value.getFullYear());
266
- };
267
-
268
- export const minDateTester = (value : Date, min : Date) : boolean => {
269
- return +value >= +min;
270
- };
271
-
272
- export const exclusiveMinDateTester = (value : Date, min : Date) : boolean => {
273
- return +value > +min;
274
- };
275
-
276
- export const maxDateTester = (value : Date, max : Date) : boolean => {
277
- return +value <= +max;
278
- };
279
-
280
- export const exclusiveMaxDateTester = (value : Date, max : Date) : boolean => {
281
- return +value < +max;
282
- };
283
-
284
- export const arrayTester = (value : any) : value is any[] => {
285
- return Array.isArray(value);
286
- };
287
-
288
- export const arrayTypeOfTester = (array : any[], type : DataType) : boolean => {
289
- return array.every((item : any) => {
290
- return typeTester(item, type);
291
- });
292
- };
293
-
294
- export const uniqueItemsTester = (array : any[]) : boolean => {
295
- return array.every(item => {
296
- return array.filter((target : any) => target === item).length === 1;
297
- });
298
- };
299
-
300
- export const regExpTester = (value : any) : value is RegExp => {
301
- return value instanceof RegExp;
302
- };
1
+ import { DataType } from './constants';
2
+
3
+ export const typeTester = (value : any, type : DataType) : boolean => {
4
+ let valid : boolean;
5
+
6
+ switch (type) {
7
+ case DataType.BOOLEAN:
8
+ valid = booleanTester(value);
9
+ break;
10
+
11
+ case DataType.NUMBER:
12
+ valid = numberTester(value);
13
+ break;
14
+
15
+ case DataType.STRING:
16
+ valid = stringTester(value);
17
+ break;
18
+
19
+ case DataType.OBJECT:
20
+ valid = objectTester(value);
21
+ break;
22
+
23
+ case DataType.DATE:
24
+ valid = dateTester(value);
25
+ break;
26
+
27
+ case DataType.REGEXP:
28
+ valid = regExpTester(value);
29
+ break;
30
+
31
+ case DataType.ARRAY:
32
+ valid = arrayTester(value);
33
+ break;
34
+ }
35
+
36
+ return valid;
37
+ };
38
+
39
+ export const definedTester = (value : any) : value is boolean => {
40
+ return value !== undefined;
41
+ };
42
+
43
+ export const enumTester = <T> (value : T, arr : T[]) : boolean => {
44
+ return arr.includes(value);
45
+ };
46
+
47
+ export const lengthTester = (value : string | any[], length : number) : boolean => {
48
+ return value.length === length;
49
+ };
50
+
51
+ export const minLengthTester = (value : string | any[], minLength : number) : boolean => {
52
+ return value.length >= minLength;
53
+ };
54
+
55
+ export const maxLengthTester = (value : string | any[], maxLength : number) : boolean => {
56
+ return value.length <= maxLength;
57
+ };
58
+
59
+ export const booleanTester = (value : any) : boolean => {
60
+ return typeof value === 'boolean';
61
+ };
62
+
63
+ export const numberTester = (value : any) : value is number => {
64
+ return typeof value === 'number' && !isNaN(value);
65
+ };
66
+
67
+ export const integerTester = (value : number) : boolean => {
68
+ return +value.toFixed(0) === value;
69
+ };
70
+
71
+ export const indexTester = (value : number) : value is number => {
72
+ return integerTester(value) && value >= 0;
73
+ };
74
+
75
+ export const minNumberTester = (value : number, min : number) : boolean => {
76
+ return value >= min;
77
+ };
78
+
79
+ export const exclusiveMinNumberTester = (value : number, min : number) : boolean => {
80
+ return value > min;
81
+ };
82
+
83
+ export const maxNumberTester = (value : number, max : number) : boolean => {
84
+ return value <= max;
85
+ };
86
+
87
+ export const exclusiveMaxNumberTester = (value : number, max : number) : boolean => {
88
+ return value < max;
89
+ };
90
+
91
+ export const stringTester = (value : any) : value is string => {
92
+ return typeof value === 'string';
93
+ };
94
+
95
+ export const stringRegExpTester = (value : string, regExp : string | RegExp) : boolean => {
96
+ let valid : boolean = false;
97
+
98
+ let _regExp : RegExp | undefined = undefined;
99
+
100
+ if (regExpTester(regExp)) {
101
+ _regExp = regExp as RegExp;
102
+ }
103
+ else if (stringTester(regExp)) {
104
+ _regExp = new RegExp(regExp);
105
+ }
106
+
107
+ if (!!_regExp && regExpTester(_regExp)) {
108
+ valid = _regExp.test(value);
109
+ }
110
+
111
+ return valid;
112
+ };
113
+
114
+ // RFC 5322, 3.4.1. spec
115
+ export const emailTester = (value : string) : boolean => {
116
+ let valid : boolean = false;
117
+
118
+ if (stringTester(value) && stringRegExpTester(value, /^.+@.+$/)) {
119
+ const valueAsString : string = value as string;
120
+
121
+ const atIndex : number = valueAsString.lastIndexOf('@');
122
+ const localPart : string = valueAsString.substr(0, atIndex);
123
+ const domain : string = valueAsString.substr(atIndex + 1);
124
+
125
+ // regular expression sources
126
+ // const aTextRegExpStr : string = '[-a-zA-Z0-9!#$%&\\\'*+/=?^_`{|}~]+';
127
+
128
+ const dotAtomRegExp : RegExp = /^(\.?[-a-zA-Z0-9!#$%&'*+/=?^_`{|}~]+)*$/;
129
+ const quotedStringRegExp : RegExp = /^"[\u0020-\u005b\u005d-\u007e\\]*"$/; // include space (\u005b)
130
+ const domainLiteralRegExp : RegExp = /^\[[\u0020-\u005a\u005c-\u007e\\]*]$/;
131
+
132
+ const validLocalPart : boolean = localPart.length <= 64
133
+ && (
134
+ dotAtomRegExp.test(localPart)
135
+ || quotedStringRegExp.test(localPart)
136
+ );
137
+
138
+ const validDomain : boolean = !domain.startsWith('.') && !domain.endsWith('.')
139
+ && (
140
+ dotAtomRegExp.test(domain)
141
+ || domainLiteralRegExp.test(domain)
142
+ );
143
+
144
+ valid = validLocalPart && validDomain;
145
+ }
146
+
147
+ return valid;
148
+ };
149
+
150
+ // RFC 3339 (https://www.ietf.org/rfc/rfc3339.txt) : YYYY-MM-DDThh:mm:ss[.SSSZ]
151
+ const rfc3339Tester = (value : string) : boolean => {
152
+ return /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(:([0-5][0-9])){2}(\.\d+)?(Z|[-+]\d{2}:\d{2})?$/.test(value);
153
+ };
154
+
155
+ const iso8601DateTester = (value : string) : boolean => {
156
+ const years : string = '(\\d{4})';
157
+ const months : string = '(0[1-9]|1[0-2])';
158
+ const dates : string = '(0[1-9]|[1-2][0-9]|3[0-1])';
159
+ const dateOfYear : string = '(00[1-9]|0[1-9][0-9]|[1-2]\\d{2}|3[0-5]\\d|36[0-6])'; // 366 for leap year
160
+ const weeks : string = '(W(0[1-9]|[2-4][0-9]|5[0-3]))';
161
+ const days : string = '[1-7]';
162
+
163
+ return [
164
+ new RegExp(`^[-+]?${ years }$`), // years : YYYY, +YYYY, -YYYY
165
+ new RegExp(`^${ years }-${ months }(-${ dates })?$`), // calendar dates : YYYY-MM-DD, YYYY-MM
166
+ new RegExp(`^${ years }${ months }${ dates }$`), // calendar dates : YYYYMMDD
167
+ new RegExp(`^--${ months }-?${ dates }$`), // calendar dates : --MM-DD, --MMDD
168
+ new RegExp(`^${ years }-${ weeks }(-${ days })?$`), // week dates : YYYY-Www, YYYY-Www-D
169
+ new RegExp(`^${ years }${ weeks }(${ days })?$`), // week dates : YYYYWww, YYYYWwwD
170
+ new RegExp(`^${ years }-?${ dateOfYear }$`) // ordinal dates : YYYY-DDD, YYYYDDD
171
+ ].some((regExp : RegExp) => {
172
+ return regExp.test(value);
173
+ });
174
+ };
175
+
176
+ const iso8601TimeTester = (value : string) : boolean => {
177
+ const hours : string = '([0-1]\\d|2[0-3])';
178
+ const minutes : string = '([0-5]\\d)';
179
+ const seconds : string = '([0-5]\\d|60)'; // 60 for leap second
180
+ const ms : string = '(\\.[0-9]+)';
181
+
182
+ return [
183
+ new RegExp(`^(${ hours }|24)$`), // hh
184
+ new RegExp(`^((${ hours }:${ minutes })|24:00)$`), // hh:mm
185
+ new RegExp(`^((${ hours }:${ minutes }:${ seconds })|24:00:00)$`), // hh:mm:ss
186
+ new RegExp(`^((${ hours }:${ minutes }:${ seconds }${ ms })|24:00:00\.0+)$`), // hh:mm:ss
187
+
188
+ new RegExp(`^(${ hours }${ minutes }|2400)$`), // hhmm
189
+ new RegExp(`^(${ hours }${ minutes }${ seconds }|240000)$`), // hhmmss
190
+ new RegExp(`^(${ hours }${ minutes }${ seconds }${ ms }|240000\.0+)$`) // hhmmss.sss
191
+ ]
192
+ .some((regExp : RegExp) => {
193
+ return regExp.test(value);
194
+ });
195
+ };
196
+
197
+ const iso8601DateTimeTester = (value : string) : boolean => {
198
+ let valid : boolean = false;
199
+
200
+ if (/.+T.+/.test(value) // should have 1 'T'
201
+ && /(Z|[-+]\d{2}:?\d{2})$/.test(value) // should end with 'Z' or timezone
202
+ ) {
203
+ let [date, time] = value.split('T');
204
+
205
+ if (time.endsWith('Z')) {
206
+ time = time.replace('Z', '');
207
+ }
208
+ else {
209
+ const timezoneStartIndex : number = time.includes('+') ? time.indexOf('+') : time.indexOf('-');
210
+
211
+ time = time.substr(0, timezoneStartIndex);
212
+ }
213
+
214
+ valid = iso8601DateTester(date) && iso8601TimeTester(time);
215
+ }
216
+
217
+ return valid;
218
+ };
219
+
220
+ export const dateFormatTester = (value : string) : boolean => {
221
+ return iso8601DateTester(value);
222
+ };
223
+
224
+ export const timeFormatTester = (value : string) : boolean => {
225
+ return iso8601TimeTester(value);
226
+ };
227
+
228
+ export const dateTimeFormatTester = (value : string) : boolean => {
229
+ return rfc3339Tester(value) || iso8601DateTimeTester(value);
230
+ };
231
+
232
+ // // with port
233
+ // export const urlTester = (value : any) : boolean => {
234
+ // return stringTester(value)
235
+ // && /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
236
+ // };
237
+ //
238
+ // // TODO: with port
239
+ // export const ipv4Tester = (value : any) : boolean => {
240
+ // return stringTester(value)
241
+ // && /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(value);
242
+ // };
243
+ //
244
+ // export const ipv6Tester = (value : any) : boolean => {
245
+ // return stringTester(value)
246
+ // && /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$;/.test(value);
247
+ // };
248
+ //
249
+ // export const ipTester = (value : any) : boolean => {
250
+ // return ipv4Tester(value) || ipv6Tester(value);
251
+ // };
252
+
253
+ export const objectTester = (value : any) : value is { [key : string] : any } => {
254
+ return typeof value === 'object';
255
+ };
256
+
257
+ export const hasPropertyTester = (value : object) : boolean => {
258
+ return Object.keys(value).length > 0;
259
+ };
260
+
261
+ export const dateTester = (value : any) : value is Date => {
262
+ return objectTester(value)
263
+ && value !== null
264
+ && typeof value.getFullYear === 'function'
265
+ && !isNaN(value.getFullYear());
266
+ };
267
+
268
+ export const minDateTester = (value : Date, min : Date) : boolean => {
269
+ return +value >= +min;
270
+ };
271
+
272
+ export const exclusiveMinDateTester = (value : Date, min : Date) : boolean => {
273
+ return +value > +min;
274
+ };
275
+
276
+ export const maxDateTester = (value : Date, max : Date) : boolean => {
277
+ return +value <= +max;
278
+ };
279
+
280
+ export const exclusiveMaxDateTester = (value : Date, max : Date) : boolean => {
281
+ return +value < +max;
282
+ };
283
+
284
+ export const arrayTester = (value : any) : value is any[] => {
285
+ return Array.isArray(value);
286
+ };
287
+
288
+ export const arrayTypeOfTester = (array : any[], type : DataType) : boolean => {
289
+ return array.every((item : any) => {
290
+ return typeTester(item, type);
291
+ });
292
+ };
293
+
294
+ export const uniqueItemsTester = (array : any[]) : boolean => {
295
+ return array.every(item => {
296
+ return array.filter((target : any) => target === item).length === 1;
297
+ });
298
+ };
299
+
300
+ export const regExpTester = (value : any) : value is RegExp => {
301
+ return value instanceof RegExp;
302
+ };