@availity/yup 3.2.1 → 4.2.0
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/CHANGELOG.md +43 -0
- package/README.md +9 -3
- package/dist/date.d.ts +23 -0
- package/dist/date.d.ts.map +1 -0
- package/dist/date.js +123 -0
- package/dist/date.js.map +1 -0
- package/dist/dateRange.d.ts +43 -0
- package/dist/dateRange.d.ts.map +1 -0
- package/dist/dateRange.js +203 -0
- package/dist/dateRange.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/{src → dist}/index.js +4 -8
- package/dist/index.js.map +1 -0
- package/dist/isRequired.d.ts +4 -0
- package/dist/isRequired.d.ts.map +1 -0
- package/dist/isRequired.js +24 -0
- package/dist/isRequired.js.map +1 -0
- package/dist/npi.d.ts +4 -0
- package/dist/npi.d.ts.map +1 -0
- package/dist/npi.js +43 -0
- package/dist/npi.js.map +1 -0
- package/dist/phone.d.ts +4 -0
- package/dist/phone.d.ts.map +1 -0
- package/dist/phone.js +15 -0
- package/dist/phone.js.map +1 -0
- package/lib/date.js +24 -8
- package/lib/dateRange.js +89 -62
- package/lib/index.js +15 -15
- package/lib/isRequired.js +11 -6
- package/lib/npi.js +8 -3
- package/lib/phone.js +5 -0
- package/package.json +28 -11
- package/src/{date.js → date.ts} +18 -16
- package/src/dateRange.ts +215 -0
- package/src/index.ts +67 -0
- package/src/isRequired.ts +26 -0
- package/src/{npi.js → npi.ts} +5 -1
- package/src/{phone.js → phone.ts} +3 -1
- package/tsconfig.build.json +8 -0
- package/src/dateRange.js +0 -184
- package/src/isRequired.js +0 -22
- package/types/date.d.ts +0 -21
- package/types/dateRange.d.ts +0 -40
- package/types/index.d.ts +0 -25
package/src/{date.js → date.ts}
RENAMED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
1
2
|
import { MixedSchema } from 'yup';
|
|
2
|
-
import moment from 'moment';
|
|
3
|
-
|
|
4
|
-
const defaultOpts = {
|
|
5
|
-
format: 'MM/DD/YYYY',
|
|
6
|
-
};
|
|
3
|
+
import moment, { Moment } from 'moment';
|
|
7
4
|
|
|
8
5
|
const formats = ['YYYY-MM-DD', 'MMDDYYYY', 'YYYYMMDD', 'MM-DD-YYYY'];
|
|
9
6
|
|
|
10
|
-
export default class AvDateSchema extends MixedSchema {
|
|
11
|
-
|
|
7
|
+
export default class AvDateSchema extends MixedSchema<Moment> {
|
|
8
|
+
format: string;
|
|
9
|
+
|
|
10
|
+
constructor({ format = 'MM/DD/YYYY' }: Options = {}) {
|
|
12
11
|
super({
|
|
13
12
|
type: 'avDate',
|
|
14
13
|
});
|
|
15
14
|
|
|
16
15
|
this.format = format;
|
|
17
|
-
this.getValidDate = this.getValidDate.bind(this);
|
|
18
16
|
|
|
19
17
|
this.withMutation((schema) => {
|
|
20
18
|
if (!schema.tests.some((test) => test?.OPTIONS?.name === 'typeError')) {
|
|
@@ -26,7 +24,7 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
26
24
|
});
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
_typeCheck(value) {
|
|
27
|
+
_typeCheck(value: Moment & { _i: string }): value is Moment & { _i: string } {
|
|
30
28
|
// So as long as the passed in value is defined, moment._i will contain a string value to validate.
|
|
31
29
|
// If user enters a date and then removes it, should not show a typeError
|
|
32
30
|
// Note: this does not prevent other tests, like isRequired, from showing messages
|
|
@@ -34,11 +32,11 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
34
32
|
return value.isValid() || value._i === '';
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
getValidDate(value) {
|
|
35
|
+
getValidDate(value: string | Date | Moment) {
|
|
38
36
|
return moment(value, [this.format, ...formats], true);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
min(min, message) {
|
|
39
|
+
min(min: string, message?: string) {
|
|
42
40
|
const minDate = this.getValidDate(min);
|
|
43
41
|
|
|
44
42
|
return this.test({
|
|
@@ -50,12 +48,12 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
50
48
|
if (!min || !minDate.isValid()) {
|
|
51
49
|
return true;
|
|
52
50
|
}
|
|
53
|
-
return value === null || minDate.isSameOrBefore(value
|
|
51
|
+
return value === null || minDate.isSameOrBefore(value);
|
|
54
52
|
},
|
|
55
53
|
});
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
max(max, message) {
|
|
56
|
+
max(max: string, message?: string) {
|
|
59
57
|
const maxDate = this.getValidDate(max);
|
|
60
58
|
|
|
61
59
|
return this.test({
|
|
@@ -72,7 +70,7 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
72
70
|
});
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
isRequired(isRequired = true, msg) {
|
|
73
|
+
isRequired(isRequired = true, msg?: string) {
|
|
76
74
|
return this.test({
|
|
77
75
|
name: 'isRequired',
|
|
78
76
|
exclusive: true,
|
|
@@ -87,9 +85,8 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
87
85
|
});
|
|
88
86
|
}
|
|
89
87
|
|
|
90
|
-
between(min, max, msg, inclusivity = '()') {
|
|
88
|
+
between(min: string, max: string, msg?: string, inclusivity: Inclusivity = '()') {
|
|
91
89
|
const minDate = this.getValidDate(min);
|
|
92
|
-
|
|
93
90
|
const maxDate = this.getValidDate(max);
|
|
94
91
|
|
|
95
92
|
// Can't use arrow function because we rely on 'this' referencing yup's internals
|
|
@@ -108,3 +105,8 @@ export default class AvDateSchema extends MixedSchema {
|
|
|
108
105
|
});
|
|
109
106
|
}
|
|
110
107
|
}
|
|
108
|
+
|
|
109
|
+
export type Inclusivity = '()' | '[)' | '(]' | '[]';
|
|
110
|
+
type Options = { format?: string };
|
|
111
|
+
|
|
112
|
+
export const avDate = (opts?: Options): AvDateSchema => new AvDateSchema(opts);
|
package/src/dateRange.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
2
|
+
import { MixedSchema, ValidationError } from 'yup';
|
|
3
|
+
import moment, { Moment, unitOfTime } from 'moment';
|
|
4
|
+
import get from 'lodash/get';
|
|
5
|
+
import merge from 'lodash/merge';
|
|
6
|
+
|
|
7
|
+
const defaultOptions = {
|
|
8
|
+
startKey: 'startDate',
|
|
9
|
+
endKey: 'endDate',
|
|
10
|
+
format: 'MM/DD/YYYY',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const formats = ['YYYY-MM-DD', 'MMDDYYYY', 'YYYYMMDD'];
|
|
14
|
+
|
|
15
|
+
export default class DateRangeSchema extends MixedSchema<DateRange> {
|
|
16
|
+
startKey: string;
|
|
17
|
+
|
|
18
|
+
endKey: string;
|
|
19
|
+
|
|
20
|
+
format: string;
|
|
21
|
+
|
|
22
|
+
constructor(options?: Options) {
|
|
23
|
+
super({
|
|
24
|
+
type: 'dateRange',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const { startKey, endKey, format } = merge({}, defaultOptions, options);
|
|
28
|
+
|
|
29
|
+
// Assign them here so we can use in schema.transform
|
|
30
|
+
this.startKey = startKey;
|
|
31
|
+
this.endKey = endKey;
|
|
32
|
+
this.format = format;
|
|
33
|
+
|
|
34
|
+
this.withMutation((schema) => {
|
|
35
|
+
schema.transform(function mutate(value) {
|
|
36
|
+
const start = get(value, startKey);
|
|
37
|
+
const end = get(value, endKey);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
startDate: start ? schema.getValidDate(start) : start,
|
|
41
|
+
endDate: end ? schema.getValidDate(end) : end,
|
|
42
|
+
supportedFormats: [schema.format, ...formats],
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Convert the string to a moment object
|
|
49
|
+
getValidDate(value: string | Date | Moment) {
|
|
50
|
+
return moment(value, [this.format, ...formats], true);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
distance({
|
|
54
|
+
min: { value: minValue, units: minUnits = 'day', errorMessage: minErrorMessage } = { value: 0 },
|
|
55
|
+
max: { value: maxValue, units: maxUnits = 'day', errorMessage: maxErrorMessage } = { value: 0 },
|
|
56
|
+
}: DistanceOptions = {}) {
|
|
57
|
+
return this.test({
|
|
58
|
+
name: 'distance',
|
|
59
|
+
exclusive: true,
|
|
60
|
+
test({ endDate, startDate } = {}) {
|
|
61
|
+
// check if we have min or max set and if both dates are present
|
|
62
|
+
if ((!minValue && !maxValue) || !startDate || !endDate) return true;
|
|
63
|
+
|
|
64
|
+
// if we have a max then check distance between end and start
|
|
65
|
+
if (maxValue && endDate.isAfter(startDate.add(maxValue, maxUnits), 'day')) {
|
|
66
|
+
return new ValidationError(
|
|
67
|
+
maxErrorMessage ||
|
|
68
|
+
`The end date must be within ${maxValue} ${maxUnits}${maxValue > 1 ? 's' : ''} of the start date`,
|
|
69
|
+
{
|
|
70
|
+
startDate,
|
|
71
|
+
endDate,
|
|
72
|
+
},
|
|
73
|
+
this.path
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// if we have a min the check distance between end and start
|
|
78
|
+
if (minValue && endDate.isBefore(startDate.add(minValue, minUnits), 'day')) {
|
|
79
|
+
return new ValidationError(
|
|
80
|
+
minErrorMessage ||
|
|
81
|
+
`The end date must be greater than ${minValue} ${minUnits}${minValue > 1 ? 's' : ''} of the start date`,
|
|
82
|
+
{ startDate, endDate },
|
|
83
|
+
this.path
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return true;
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
min(min: string, message?: string) {
|
|
93
|
+
// it works for date, but not daterange. maybe that can tell us more about what is going on
|
|
94
|
+
// const minDate = this.getValidDate(min);
|
|
95
|
+
|
|
96
|
+
return this.test({
|
|
97
|
+
message: message || (({ min }: { min: string }) => `Date Range must start on or after ${min}`),
|
|
98
|
+
name: 'min',
|
|
99
|
+
exclusive: true,
|
|
100
|
+
params: { min },
|
|
101
|
+
test({ startDate, supportedFormats } = {}) {
|
|
102
|
+
// return true when no startDate or min set
|
|
103
|
+
if (!startDate || !min) return true;
|
|
104
|
+
|
|
105
|
+
// otherwise check if min is correct format and is after given startDate
|
|
106
|
+
const minDate = moment(min, supportedFormats, true);
|
|
107
|
+
|
|
108
|
+
return minDate.isValid() && minDate.isSameOrBefore(startDate);
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
max(max: string, message?: string) {
|
|
114
|
+
// const maxDate = this.getValidDate(max);
|
|
115
|
+
|
|
116
|
+
return this.test({
|
|
117
|
+
message: message || (({ max }: { max: string }) => `Date Range must end on or before ${max}`),
|
|
118
|
+
name: 'max',
|
|
119
|
+
exclusive: true,
|
|
120
|
+
params: { max },
|
|
121
|
+
test({ endDate, supportedFormats } = {}) {
|
|
122
|
+
// return true when no endDate given or max set
|
|
123
|
+
if (!endDate || !max) return true;
|
|
124
|
+
|
|
125
|
+
// otherwise check if max is correct format and is after given endDate
|
|
126
|
+
const maxDate = moment(max, supportedFormats, true);
|
|
127
|
+
|
|
128
|
+
return maxDate.isValid() && maxDate.isSameOrAfter(endDate);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
between(min: string, max: string, message?: string) {
|
|
134
|
+
// const minDate = this.getValidDate(min);
|
|
135
|
+
// const maxDate = this.getValidDate(max);
|
|
136
|
+
|
|
137
|
+
return this.test({
|
|
138
|
+
message:
|
|
139
|
+
message || (({ min, max }: { min: string; max: string }) => `Date Range must be between ${min} and ${max}`),
|
|
140
|
+
name: 'between',
|
|
141
|
+
exclusive: true,
|
|
142
|
+
params: { min, max },
|
|
143
|
+
test({ startDate, endDate, supportedFormats } = {}) {
|
|
144
|
+
if (!startDate || !endDate || !min || !max) return true;
|
|
145
|
+
|
|
146
|
+
const minDate = moment(min, supportedFormats, true);
|
|
147
|
+
const maxDate = moment(max, supportedFormats, true);
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
maxDate.isValid() && minDate.isValid() && maxDate.isSameOrAfter(endDate) && minDate.isSameOrBefore(startDate)
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
isRequired(isRequired = true, msg?: string) {
|
|
157
|
+
return this.test({
|
|
158
|
+
name: 'isRequired',
|
|
159
|
+
exclusive: true,
|
|
160
|
+
message: msg || 'This field is required.',
|
|
161
|
+
test({ startDate, endDate } = {}) {
|
|
162
|
+
return !isRequired || !!(startDate && endDate);
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
typeError({ message }: { message: string }) {
|
|
168
|
+
return this.test({
|
|
169
|
+
name: 'typeError',
|
|
170
|
+
exclusive: true,
|
|
171
|
+
test({ startDate, endDate } = {}) {
|
|
172
|
+
// Set to `any` to pass to ValidationErrors. Docs state string[] is accepted,
|
|
173
|
+
// but types do not allow string[]
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
175
|
+
const errors: any = [];
|
|
176
|
+
|
|
177
|
+
if ((!startDate || !endDate) && (startDate || endDate)) {
|
|
178
|
+
errors.push(message || 'Start and End Date are required.');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (startDate && endDate && !startDate.isSameOrBefore(endDate)) {
|
|
182
|
+
errors.push('Start date must come before end date.');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (startDate && !startDate.isValid()) {
|
|
186
|
+
errors.push('Start Date is invalid.');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (endDate && !endDate.isValid()) {
|
|
190
|
+
errors.push('End Date is invalid.');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return errors.length > 0 ? new ValidationError(errors, { startDate, endDate }, this.path) : true;
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
_typeCheck(range: { startDate?: Moment; endDate?: Moment } = {}): range is DateRange {
|
|
199
|
+
const { startDate, endDate } = range;
|
|
200
|
+
|
|
201
|
+
return !!startDate && !!endDate && startDate.isValid() && endDate.isValid();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
type Options = { startKey?: string; endKey?: string; format?: string };
|
|
206
|
+
type DateRange = { startDate?: Moment; endDate?: Moment; supportedFormats?: string[] };
|
|
207
|
+
type DistanceValue = {
|
|
208
|
+
value: number;
|
|
209
|
+
// unitOfTime namespace is provided by moment library
|
|
210
|
+
units?: unitOfTime.DurationConstructor;
|
|
211
|
+
errorMessage?: string;
|
|
212
|
+
};
|
|
213
|
+
type DistanceOptions = { min?: DistanceValue; max?: DistanceValue };
|
|
214
|
+
|
|
215
|
+
export const dateRange = (opts?: Options): DateRangeSchema => new DateRangeSchema(opts);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { addMethod, array, number, object, string } from 'yup';
|
|
2
|
+
import { AnyObject, Maybe, Optionals } from 'yup/lib/types';
|
|
3
|
+
import BaseSchema, { AnySchema } from 'yup/lib/schema';
|
|
4
|
+
import { Asserts, TypeOf } from 'yup/lib/util/types';
|
|
5
|
+
import { AssertsShape, ObjectShape, TypeOfShape } from 'yup/lib/object';
|
|
6
|
+
import Lazy from 'yup/lib/Lazy';
|
|
7
|
+
|
|
8
|
+
import { avDate } from './date';
|
|
9
|
+
import { dateRange } from './dateRange';
|
|
10
|
+
import isRequired from './isRequired';
|
|
11
|
+
import npi from './npi';
|
|
12
|
+
import phone from './phone';
|
|
13
|
+
|
|
14
|
+
export { avDate, dateRange };
|
|
15
|
+
|
|
16
|
+
addMethod(array, 'isRequired', isRequired);
|
|
17
|
+
addMethod(number, 'isRequired', isRequired);
|
|
18
|
+
addMethod(object, 'isRequired', isRequired);
|
|
19
|
+
addMethod(string, 'isRequired', isRequired);
|
|
20
|
+
|
|
21
|
+
addMethod(number, 'npi', npi);
|
|
22
|
+
addMethod(string, 'npi', npi);
|
|
23
|
+
|
|
24
|
+
addMethod(number, 'phone', phone);
|
|
25
|
+
addMethod(string, 'phone', phone);
|
|
26
|
+
|
|
27
|
+
// Add definitions to yup
|
|
28
|
+
declare module 'yup' {
|
|
29
|
+
interface StringSchema<
|
|
30
|
+
TType extends Maybe<string> = string | undefined,
|
|
31
|
+
TContext extends AnyObject = AnyObject,
|
|
32
|
+
TOut extends TType = TType
|
|
33
|
+
> extends BaseSchema<TType, TContext, TOut> {
|
|
34
|
+
isRequired(required?: boolean, errorMessage?: string): StringSchema<TType, TContext>;
|
|
35
|
+
npi(errorMessage?: string): StringSchema<TType, TContext>;
|
|
36
|
+
phone(errorMessage?: string): StringSchema<TType, TContext>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface NumberSchema<
|
|
40
|
+
TType extends Maybe<number> = number | undefined,
|
|
41
|
+
TContext extends AnyObject = AnyObject,
|
|
42
|
+
TOut extends TType = TType
|
|
43
|
+
> extends BaseSchema<TType, TContext, TOut> {
|
|
44
|
+
isRequired(required?: boolean, errorMessage?: string): NumberSchema<TType, TContext, TOut>;
|
|
45
|
+
npi(errorMessage?: string): NumberSchema<TType, TContext, TOut>;
|
|
46
|
+
phone(errorMessage?: string): NumberSchema<TType, TContext, TOut>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ArraySchema<
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
T extends AnySchema | Lazy<any, any>,
|
|
52
|
+
C extends AnyObject = AnyObject,
|
|
53
|
+
TIn extends Maybe<TypeOf<T>[]> = TypeOf<T>[] | undefined,
|
|
54
|
+
TOut extends Maybe<Asserts<T>[]> = Asserts<T>[] | Optionals<TIn>
|
|
55
|
+
> extends BaseSchema<TIn, C, TOut> {
|
|
56
|
+
isRequired(required?: boolean, errorMessage?: string): ArraySchema<T, C, TIn, TOut>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface ObjectSchema<
|
|
60
|
+
TShape extends ObjectShape,
|
|
61
|
+
TContext extends AnyObject = AnyObject,
|
|
62
|
+
TIn extends Maybe<TypeOfShape<TShape>> = TypeOfShape<TShape>,
|
|
63
|
+
TOut extends Maybe<AssertsShape<TShape>> = AssertsShape<TShape> | Optionals<TIn>
|
|
64
|
+
> extends BaseSchema<TIn, TContext, TOut> {
|
|
65
|
+
isRequired(required?: boolean, errorMessage?: string): ObjectSchema<TShape, TContext, TIn, TOut>;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseSchema } from 'yup';
|
|
2
|
+
|
|
3
|
+
function isRequired<Schema extends BaseSchema>(this: Schema, isRequired = true, msg?: string): Schema {
|
|
4
|
+
return this.test({
|
|
5
|
+
name: 'isRequired',
|
|
6
|
+
exclusive: true,
|
|
7
|
+
message: msg || 'This field is required.',
|
|
8
|
+
test(value) {
|
|
9
|
+
if (isRequired) {
|
|
10
|
+
// array and string have custom logic
|
|
11
|
+
if (this.schema.type === 'array') {
|
|
12
|
+
return Array.isArray(value) ? value.length > 0 : value !== undefined;
|
|
13
|
+
}
|
|
14
|
+
if (this.schema.type === 'string') {
|
|
15
|
+
return value !== undefined && value !== '';
|
|
16
|
+
}
|
|
17
|
+
// default logic for all other types
|
|
18
|
+
return value !== undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return true;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default isRequired;
|
package/src/{npi.js → npi.ts}
RENAMED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { BaseSchema } from 'yup';
|
|
2
|
+
|
|
1
3
|
const INTEGER_REGEX = /^\d*$/;
|
|
2
4
|
|
|
3
|
-
function npi(msg) {
|
|
5
|
+
function npi<Schema extends BaseSchema>(this: Schema, msg?: string): Schema {
|
|
4
6
|
return this.test({
|
|
5
7
|
name: 'npi',
|
|
6
8
|
exclusive: true,
|
|
@@ -10,10 +12,12 @@ function npi(msg) {
|
|
|
10
12
|
|
|
11
13
|
value += '';
|
|
12
14
|
|
|
15
|
+
// is it a number and 10 digits long
|
|
13
16
|
if (!INTEGER_REGEX.test(value) || value.length !== 10) {
|
|
14
17
|
return false;
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
// is the first digit 1-4
|
|
17
21
|
const firstDigit = value.charAt(0);
|
|
18
22
|
if (['1', '2', '3', '4'].indexOf(firstDigit) < 0) {
|
|
19
23
|
return false;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { BaseSchema } from 'yup';
|
|
2
|
+
|
|
1
3
|
const NANP_REGEXP = /^(\+?1[\s.-]?)?\(?[2-9]\d{2}[\s).-]?\s?[2-9]\d{2}[\s.-]?\d{4}$/;
|
|
2
4
|
|
|
3
|
-
function phone(msg) {
|
|
5
|
+
function phone<Schema extends BaseSchema>(this: Schema, msg: string): Schema {
|
|
4
6
|
return this.test({
|
|
5
7
|
name: 'phone',
|
|
6
8
|
exclusive: true,
|
package/src/dateRange.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { MixedSchema, ValidationError } from 'yup';
|
|
2
|
-
import moment from 'moment';
|
|
3
|
-
import get from 'lodash/get';
|
|
4
|
-
import merge from 'lodash/merge';
|
|
5
|
-
|
|
6
|
-
const defaultOptions = {
|
|
7
|
-
startKey: 'startDate',
|
|
8
|
-
endKey: 'endDate',
|
|
9
|
-
format: 'MM/DD/YYYY',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const defaultValue = {};
|
|
13
|
-
|
|
14
|
-
const formats = ['YYYY-MM-DD', 'MMDDYYYY', 'YYYYMMDD'];
|
|
15
|
-
|
|
16
|
-
export default class DateRangeSchema extends MixedSchema {
|
|
17
|
-
constructor(options) {
|
|
18
|
-
super({
|
|
19
|
-
type: 'dateRange',
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const { startKey, endKey, format } = merge({}, defaultOptions, options);
|
|
23
|
-
|
|
24
|
-
this.startKey = startKey;
|
|
25
|
-
this.endKey = endKey;
|
|
26
|
-
this.format = format;
|
|
27
|
-
this.getValidDate = this.getValidDate.bind(this);
|
|
28
|
-
|
|
29
|
-
this.withMutation((schema) => {
|
|
30
|
-
schema.transform(function mutate(value) {
|
|
31
|
-
const start = get(value, startKey);
|
|
32
|
-
const end = get(value, endKey);
|
|
33
|
-
|
|
34
|
-
let startDate;
|
|
35
|
-
let endDate;
|
|
36
|
-
if (start) {
|
|
37
|
-
startDate = schema.getValidDate(start);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (end) {
|
|
41
|
-
endDate = schema.getValidDate(end);
|
|
42
|
-
}
|
|
43
|
-
return { startDate, endDate };
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getValidDate(value) {
|
|
49
|
-
return moment(value, [this.format, ...formats], true);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
distance({
|
|
53
|
-
min: { value: minValue, units: minUnits = 'day', errorMessage: minErrorMessage } = {},
|
|
54
|
-
max: { value: maxValue, units: maxUnits = 'day', errorMessage: maxErrorMessage } = {},
|
|
55
|
-
} = defaultValue) {
|
|
56
|
-
return this.test({
|
|
57
|
-
name: 'distance',
|
|
58
|
-
exclusive: true,
|
|
59
|
-
test({ endDate, startDate } = defaultValue) {
|
|
60
|
-
if ((!minValue && !maxValue) || !startDate || !endDate) return true;
|
|
61
|
-
|
|
62
|
-
if (maxValue && endDate.isAfter(startDate.add(maxValue, maxUnits), 'day')) {
|
|
63
|
-
return new ValidationError(
|
|
64
|
-
maxErrorMessage ||
|
|
65
|
-
`The end date must be within ${maxValue} ${maxUnits}${maxValue > 1 ? 's' : ''} of the start date`,
|
|
66
|
-
{
|
|
67
|
-
startDate,
|
|
68
|
-
endDate,
|
|
69
|
-
},
|
|
70
|
-
this.path
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
if (minValue && endDate.isBefore(startDate.add(minValue, minUnits), 'day')) {
|
|
74
|
-
return new ValidationError(
|
|
75
|
-
minErrorMessage ||
|
|
76
|
-
`The end date must be greater than ${minValue} ${minUnits}${minValue > 1 ? 's' : ''} of the start date`,
|
|
77
|
-
{ startDate, endDate },
|
|
78
|
-
this.path
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return true;
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
min(min, message) {
|
|
88
|
-
const { format } = this;
|
|
89
|
-
|
|
90
|
-
const minDate = this.getValidDate(min);
|
|
91
|
-
return this.test({
|
|
92
|
-
message: message || `Date Range must start on or after ${minDate.format(format)}`,
|
|
93
|
-
name: 'min',
|
|
94
|
-
exclusive: true,
|
|
95
|
-
params: { min },
|
|
96
|
-
test({ startDate } = defaultValue) {
|
|
97
|
-
if (!startDate || !min) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
return minDate.isValid() && minDate.isSameOrBefore(startDate);
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
max(max, message) {
|
|
106
|
-
const { format } = this;
|
|
107
|
-
|
|
108
|
-
const maxDate = this.getValidDate(max);
|
|
109
|
-
|
|
110
|
-
return this.test({
|
|
111
|
-
message: message || `Date Range must end on or before ${maxDate.format(format)}`,
|
|
112
|
-
name: 'max',
|
|
113
|
-
exclusive: true,
|
|
114
|
-
params: { max },
|
|
115
|
-
test({ endDate } = defaultValue) {
|
|
116
|
-
if (!endDate || !max) return true;
|
|
117
|
-
return maxDate.isValid() && maxDate.isSameOrAfter(endDate);
|
|
118
|
-
},
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
between(min, max, message) {
|
|
123
|
-
const { format } = this;
|
|
124
|
-
|
|
125
|
-
const minDate = this.getValidDate(min);
|
|
126
|
-
const maxDate = this.getValidDate(max);
|
|
127
|
-
|
|
128
|
-
return this.test({
|
|
129
|
-
message: message || `Date Range must be between ${minDate.format(format)} and ${maxDate.format(format)}`,
|
|
130
|
-
name: 'between',
|
|
131
|
-
exclusive: true,
|
|
132
|
-
params: { min, max },
|
|
133
|
-
test({ startDate, endDate } = defaultValue) {
|
|
134
|
-
if (!startDate || !endDate || !min || !max) return true;
|
|
135
|
-
return (
|
|
136
|
-
maxDate.isValid() && minDate.isValid() && maxDate.isSameOrAfter(endDate) && minDate.isSameOrBefore(startDate)
|
|
137
|
-
);
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
isRequired(isRequired = true, msg) {
|
|
143
|
-
return this.test({
|
|
144
|
-
name: 'isRequired',
|
|
145
|
-
exclusive: true,
|
|
146
|
-
message: msg || 'This field is required.',
|
|
147
|
-
test({ startDate, endDate } = defaultValue) {
|
|
148
|
-
return !isRequired || (startDate && endDate);
|
|
149
|
-
},
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
typeError() {
|
|
154
|
-
return this.test({
|
|
155
|
-
name: 'typeError',
|
|
156
|
-
exclusive: true,
|
|
157
|
-
test({ startDate, endDate } = defaultValue) {
|
|
158
|
-
const errors = [];
|
|
159
|
-
|
|
160
|
-
if ((!startDate || !endDate) && (startDate || endDate)) {
|
|
161
|
-
errors.push('Start and End Date are required.');
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (startDate && endDate && !startDate.isSameOrBefore(endDate)) {
|
|
165
|
-
errors.push('Start date must come before end date.');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (startDate && !startDate.isValid()) {
|
|
169
|
-
errors.push('Start Date is invalid.');
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (endDate && !endDate.isValid()) {
|
|
173
|
-
errors.push('End Date is invalid.');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return errors.length > 0 ? new ValidationError(errors, { startDate, endDate }, this.path) : true;
|
|
177
|
-
},
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
_typeCheck({ startDate, endDate } = defaultValue) {
|
|
182
|
-
return startDate && endDate && startDate.isValid() && endDate.isValid();
|
|
183
|
-
}
|
|
184
|
-
}
|
package/src/isRequired.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
function isRequired(isRequired = true, msg) {
|
|
2
|
-
return this.test({
|
|
3
|
-
name: 'isRequired',
|
|
4
|
-
exclusive: true,
|
|
5
|
-
message: msg || 'This field is required.',
|
|
6
|
-
test(value) {
|
|
7
|
-
if (isRequired) {
|
|
8
|
-
if (typeof value === 'number') {
|
|
9
|
-
return value !== undefined;
|
|
10
|
-
}
|
|
11
|
-
if (Array.isArray(value)) {
|
|
12
|
-
return value.length > 0;
|
|
13
|
-
}
|
|
14
|
-
// String ( If you want to check for null add nullable )
|
|
15
|
-
return value !== undefined && value !== '';
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default isRequired;
|
package/types/date.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as yup from 'yup';
|
|
2
|
-
|
|
3
|
-
declare module 'yup' {
|
|
4
|
-
interface DateOpts {
|
|
5
|
-
format?: string | 'MM/DD/YYYY';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface AvDateSchema<T extends string | null | undefined = string> extends MixedSchema<T> {
|
|
9
|
-
min(date: string, errorMessage?: string): DateRangeSchema<T>;
|
|
10
|
-
max(date: string, errorMessage?: string): DateRangeSchema<T>;
|
|
11
|
-
between(minDate: string, maxDate: string, errorMessage?: string): AvDateSchema<T>;
|
|
12
|
-
isRequired(required?: boolean, errorMessage?: string): AvDateSchema<T>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface AvDateSchemaConstructor {
|
|
16
|
-
(opts: DateOpts): AvDateSchema;
|
|
17
|
-
new (opts: DateOpts): AvDateSchema;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const avDate: AvDateSchemaConstructor;
|
|
21
|
-
}
|