@availity/yup 4.1.0 → 5.0.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/dist/index.mjs ADDED
@@ -0,0 +1,325 @@
1
+ // src/index.ts
2
+ import { addMethod, array, number, object, string } from "yup";
3
+
4
+ // src/date.ts
5
+ import { MixedSchema } from "yup";
6
+ import moment from "moment";
7
+ var formats = ["YYYY-MM-DD", "MMDDYYYY", "YYYYMMDD", "MM-DD-YYYY"];
8
+ var AvDateSchema = class extends MixedSchema {
9
+ constructor({ format = "MM/DD/YYYY" } = {}) {
10
+ super({
11
+ type: "avDate"
12
+ });
13
+ this.format = format;
14
+ this.withMutation((schema) => {
15
+ if (!schema.tests.some((test) => {
16
+ var _a;
17
+ return ((_a = test == null ? void 0 : test.OPTIONS) == null ? void 0 : _a.name) === "typeError";
18
+ })) {
19
+ super.typeError("Date is invalid.");
20
+ }
21
+ schema.transform(function mutate(value) {
22
+ return schema.getValidDate(value);
23
+ });
24
+ });
25
+ }
26
+ _typeCheck(value) {
27
+ return value.isValid() || value._i === "";
28
+ }
29
+ getValidDate(value) {
30
+ return moment(value, [this.format, ...formats], true);
31
+ }
32
+ min(min, message) {
33
+ const minDate = this.getValidDate(min);
34
+ return this.test({
35
+ message: message || `Date must be ${minDate.format(this.format)} or later.`,
36
+ name: "min",
37
+ exclusive: true,
38
+ params: { min },
39
+ test(value) {
40
+ if (!min || !minDate.isValid()) {
41
+ return true;
42
+ }
43
+ return value === null || minDate.isSameOrBefore(value);
44
+ }
45
+ });
46
+ }
47
+ max(max, message) {
48
+ const maxDate = this.getValidDate(max);
49
+ return this.test({
50
+ message: message || `Date must be ${maxDate.format(this.format)} or earlier.`,
51
+ name: "max",
52
+ exclusive: true,
53
+ params: { max },
54
+ test(value) {
55
+ if (!max || !maxDate.isValid()) {
56
+ return true;
57
+ }
58
+ return value === null || maxDate.isSameOrAfter(value);
59
+ }
60
+ });
61
+ }
62
+ isRequired(isRequired2 = true, msg) {
63
+ return this.test({
64
+ name: "isRequired",
65
+ exclusive: true,
66
+ message: msg || "This field is required.",
67
+ test(value) {
68
+ if (!isRequired2) {
69
+ return true;
70
+ }
71
+ return value !== void 0;
72
+ }
73
+ });
74
+ }
75
+ between(min, max, msg, inclusivity = "()") {
76
+ const minDate = this.getValidDate(min);
77
+ const maxDate = this.getValidDate(max);
78
+ return this.test({
79
+ name: "between",
80
+ exclusive: true,
81
+ message: msg || `Date must be between ${minDate.format(this.format)} and ${maxDate.format(this.format)}.`,
82
+ test(value) {
83
+ if (!value || !min || !max || !minDate.isValid() || !maxDate.isValid()) {
84
+ return true;
85
+ }
86
+ return value.isBetween(minDate, maxDate, void 0, inclusivity);
87
+ }
88
+ });
89
+ }
90
+ };
91
+ var avDate = (opts) => new AvDateSchema(opts);
92
+
93
+ // src/dateRange.ts
94
+ import { MixedSchema as MixedSchema2, ValidationError } from "yup";
95
+ import moment2 from "moment";
96
+ import get from "lodash/get";
97
+ import merge from "lodash/merge";
98
+ var defaultOptions = {
99
+ startKey: "startDate",
100
+ endKey: "endDate",
101
+ format: "MM/DD/YYYY"
102
+ };
103
+ var formats2 = ["YYYY-MM-DD", "MMDDYYYY", "YYYYMMDD"];
104
+ var DateRangeSchema = class extends MixedSchema2 {
105
+ constructor(options) {
106
+ super({
107
+ type: "dateRange"
108
+ });
109
+ const { startKey, endKey, format } = merge({}, defaultOptions, options);
110
+ this.startKey = startKey;
111
+ this.endKey = endKey;
112
+ this.format = format;
113
+ this.withMutation((schema) => {
114
+ schema.transform(function mutate(value) {
115
+ const start = get(value, startKey);
116
+ const end = get(value, endKey);
117
+ return {
118
+ startDate: start ? schema.getValidDate(start) : start,
119
+ endDate: end ? schema.getValidDate(end) : end,
120
+ supportedFormats: [schema.format, ...formats2]
121
+ };
122
+ });
123
+ });
124
+ }
125
+ getValidDate(value) {
126
+ return moment2(value, [this.format, ...formats2], true);
127
+ }
128
+ distance({
129
+ min: { value: minValue, units: minUnits = "day", errorMessage: minErrorMessage } = { value: 0 },
130
+ max: { value: maxValue, units: maxUnits = "day", errorMessage: maxErrorMessage } = { value: 0 }
131
+ } = {}) {
132
+ return this.test({
133
+ name: "distance",
134
+ exclusive: true,
135
+ test({ endDate, startDate } = {}) {
136
+ if (!minValue && !maxValue || !startDate || !endDate)
137
+ return true;
138
+ if (maxValue && endDate.isAfter(startDate.add(maxValue, maxUnits), "day")) {
139
+ return new ValidationError(maxErrorMessage || `The end date must be within ${maxValue} ${maxUnits}${maxValue > 1 ? "s" : ""} of the start date`, {
140
+ startDate,
141
+ endDate
142
+ }, this.path);
143
+ }
144
+ if (minValue && endDate.isBefore(startDate.add(minValue, minUnits), "day")) {
145
+ return new ValidationError(minErrorMessage || `The end date must be greater than ${minValue} ${minUnits}${minValue > 1 ? "s" : ""} of the start date`, { startDate, endDate }, this.path);
146
+ }
147
+ return true;
148
+ }
149
+ });
150
+ }
151
+ min(min, message) {
152
+ return this.test({
153
+ message: message || (({ min: min2 }) => `Date Range must start on or after ${min2}`),
154
+ name: "min",
155
+ exclusive: true,
156
+ params: { min },
157
+ test({ startDate, supportedFormats } = {}) {
158
+ if (!startDate || !min)
159
+ return true;
160
+ const minDate = moment2(min, supportedFormats, true);
161
+ return minDate.isValid() && minDate.isSameOrBefore(startDate);
162
+ }
163
+ });
164
+ }
165
+ max(max, message) {
166
+ return this.test({
167
+ message: message || (({ max: max2 }) => `Date Range must end on or before ${max2}`),
168
+ name: "max",
169
+ exclusive: true,
170
+ params: { max },
171
+ test({ endDate, supportedFormats } = {}) {
172
+ if (!endDate || !max)
173
+ return true;
174
+ const maxDate = moment2(max, supportedFormats, true);
175
+ return maxDate.isValid() && maxDate.isSameOrAfter(endDate);
176
+ }
177
+ });
178
+ }
179
+ between(min, max, message) {
180
+ return this.test({
181
+ message: message || (({ min: min2, max: max2 }) => `Date Range must be between ${min2} and ${max2}`),
182
+ name: "between",
183
+ exclusive: true,
184
+ params: { min, max },
185
+ test({ startDate, endDate, supportedFormats } = {}) {
186
+ if (!startDate || !endDate || !min || !max)
187
+ return true;
188
+ const minDate = moment2(min, supportedFormats, true);
189
+ const maxDate = moment2(max, supportedFormats, true);
190
+ return maxDate.isValid() && minDate.isValid() && maxDate.isSameOrAfter(endDate) && minDate.isSameOrBefore(startDate);
191
+ }
192
+ });
193
+ }
194
+ isRequired(isRequired2 = true, msg) {
195
+ return this.test({
196
+ name: "isRequired",
197
+ exclusive: true,
198
+ message: msg || "This field is required.",
199
+ test({ startDate, endDate } = {}) {
200
+ return !isRequired2 || !!(startDate && endDate);
201
+ }
202
+ });
203
+ }
204
+ typeError({ message }) {
205
+ return this.test({
206
+ name: "typeError",
207
+ exclusive: true,
208
+ test({ startDate, endDate } = {}) {
209
+ const errors = [];
210
+ if ((!startDate || !endDate) && (startDate || endDate)) {
211
+ errors.push(message || "Start and End Date are required.");
212
+ }
213
+ if (startDate && endDate && !startDate.isSameOrBefore(endDate)) {
214
+ errors.push("Start date must come before end date.");
215
+ }
216
+ if (startDate && !startDate.isValid()) {
217
+ errors.push("Start Date is invalid.");
218
+ }
219
+ if (endDate && !endDate.isValid()) {
220
+ errors.push("End Date is invalid.");
221
+ }
222
+ return errors.length > 0 ? new ValidationError(errors, { startDate, endDate }, this.path) : true;
223
+ }
224
+ });
225
+ }
226
+ _typeCheck(range = {}) {
227
+ const { startDate, endDate } = range;
228
+ return !!startDate && !!endDate && startDate.isValid() && endDate.isValid();
229
+ }
230
+ };
231
+ var dateRange = (opts) => new DateRangeSchema(opts);
232
+
233
+ // src/isRequired.ts
234
+ function isRequired(isRequired2 = true, msg) {
235
+ return this.test({
236
+ name: "isRequired",
237
+ exclusive: true,
238
+ message: msg || "This field is required.",
239
+ test(value) {
240
+ if (isRequired2) {
241
+ if (this.schema.type === "array") {
242
+ return Array.isArray(value) ? value.length > 0 : value !== void 0;
243
+ }
244
+ if (this.schema.type === "string") {
245
+ return value !== void 0 && value !== "";
246
+ }
247
+ return value !== void 0;
248
+ }
249
+ return true;
250
+ }
251
+ });
252
+ }
253
+ var isRequired_default = isRequired;
254
+
255
+ // src/npi.ts
256
+ var INTEGER_REGEX = /^\d*$/;
257
+ function npi(msg) {
258
+ return this.test({
259
+ name: "npi",
260
+ exclusive: true,
261
+ message: msg || "This field is invalid.",
262
+ test(value) {
263
+ if (!value)
264
+ return true;
265
+ value += "";
266
+ if (!INTEGER_REGEX.test(value) || value.length !== 10) {
267
+ return false;
268
+ }
269
+ const firstDigit = value.charAt(0);
270
+ if (["1", "2", "3", "4"].indexOf(firstDigit) < 0) {
271
+ return false;
272
+ }
273
+ const digit = Number.parseInt(value.charAt(9), 10);
274
+ value = value.substring(0, 9);
275
+ value = `80840${value}`;
276
+ let alternate = true;
277
+ let total = 0;
278
+ for (let i = value.length; i > 0; i--) {
279
+ let next = Number.parseInt(value.charAt(i - 1), 10);
280
+ if (alternate) {
281
+ next *= 2;
282
+ if (next > 9) {
283
+ next = next % 10 + 1;
284
+ }
285
+ }
286
+ total += next;
287
+ alternate = !alternate;
288
+ }
289
+ const roundUp = Math.ceil(total / 10) * 10;
290
+ const calculatedCheck = roundUp - total;
291
+ return calculatedCheck === digit;
292
+ }
293
+ });
294
+ }
295
+ var npi_default = npi;
296
+
297
+ // src/phone.ts
298
+ var NANP_REGEXP = /^(\+?1[\s.-]?)?\(?[2-9]\d{2}[\s).-]?\s?[2-9]\d{2}[\s.-]?\d{4}$/;
299
+ function phone(msg) {
300
+ return this.test({
301
+ name: "phone",
302
+ exclusive: true,
303
+ message: msg || "This field is invalid",
304
+ test(value) {
305
+ if (!value)
306
+ return true;
307
+ return NANP_REGEXP.test(value);
308
+ }
309
+ });
310
+ }
311
+ var phone_default = phone;
312
+
313
+ // src/index.ts
314
+ addMethod(array, "isRequired", isRequired_default);
315
+ addMethod(number, "isRequired", isRequired_default);
316
+ addMethod(object, "isRequired", isRequired_default);
317
+ addMethod(string, "isRequired", isRequired_default);
318
+ addMethod(number, "npi", npi_default);
319
+ addMethod(string, "npi", npi_default);
320
+ addMethod(number, "phone", phone_default);
321
+ addMethod(string, "phone", phone_default);
322
+ export {
323
+ avDate,
324
+ dateRange
325
+ };
package/jest.config.js ADDED
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ displayName: 'yup',
3
+ preset: '../../jest.preset.js',
4
+ globals: {
5
+ 'ts-jest': {
6
+ tsconfig: '<rootDir>/tsconfig.spec.json',
7
+ },
8
+ },
9
+ coverageDirectory: '../../coverage/yup',
10
+ coverageReporters: ['json'],
11
+ };
package/package.json CHANGED
@@ -1,31 +1,48 @@
1
1
  {
2
2
  "name": "@availity/yup",
3
- "version": "4.1.0",
4
- "description": "Additional Methods for Yup validation library",
5
- "main": "lib/index.js",
6
- "module": "src/index.js",
7
- "types": "types/index.d.ts",
3
+ "version": "5.0.0",
4
+ "description": "Additional methods for yup validation library",
8
5
  "keywords": [
9
6
  "yup",
10
- "availity"
7
+ "availity",
8
+ "validation"
11
9
  ],
12
- "author": "Kyle Gray <kyle.gray@availity.com>",
10
+ "homepage": "https://availity.github.io/sdk-js/resources/yup",
11
+ "bugs": {
12
+ "url": "https://github.com/Availity/sdk-js/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/Availity/sdk-js.git",
17
+ "directory": "packages/yup"
18
+ },
13
19
  "license": "MIT",
14
- "publishConfig": {
15
- "access": "public"
20
+ "author": "Kyle Gray <kyle.gray@availity.com>",
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.mjs",
23
+ "types": "./dist/index.d.ts",
24
+ "scripts": {
25
+ "build": "tsup src/index.ts --format esm,cjs --dts",
26
+ "dev": "tsup src/index.ts --format esm,cjs --watch --dts",
27
+ "lint": "eslint src",
28
+ "lint:fix": "eslint src --fix",
29
+ "clean": "rm -rf node_modules && rm -rf dist",
30
+ "bundlesize": "bundlesize",
31
+ "publish": "yarn npm publish --tolerate-republish --access public"
16
32
  },
17
33
  "dependencies": {
18
- "@babel/runtime": "^7.10.2",
19
- "core-js": "^3.12.1",
20
- "lodash": "^4.17.21"
34
+ "lodash": "^4.17.21",
35
+ "yup": "^0.32.0"
21
36
  },
22
37
  "devDependencies": {
23
38
  "moment": "^2.24.0",
24
- "yup": "^0.32.9"
39
+ "tsup": "^5.10.1",
40
+ "typescript": "^4.5.3"
25
41
  },
26
42
  "peerDependencies": {
27
- "moment": "^2.24.0",
28
- "yup": "^0.32.9"
43
+ "moment": "^2.24.0"
29
44
  },
30
- "gitHead": "3b66243750e10849b5fbd109d65f935c99f10abf"
31
- }
45
+ "publishConfig": {
46
+ "access": "public"
47
+ }
48
+ }
package/project.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "root": "packages/yup",
3
+ "projectType": "library",
4
+ "targets": {
5
+ "test": {
6
+ "executor": "@nrwl/jest:jest",
7
+ "outputs": ["coverage/yup"],
8
+ "options": {
9
+ "jestConfig": "packages/yup/jest.config.js",
10
+ "passWithNoTests": true
11
+ }
12
+ },
13
+ "version": {
14
+ "executor": "@jscutlery/semver:version",
15
+ "options": {
16
+ "preset": "angular",
17
+ "commitMessageFormat": "chore(${projectName}): release version ${version} [skip ci]",
18
+ "tagPrefix": "@availity/${projectName}@",
19
+ "baseBranch": "master"
20
+ }
21
+ }
22
+ }
23
+ }
@@ -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
- constructor({ format = 'MM/DD/YYYY' } = defaultOpts) {
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, 'MM/DD/YYYY');
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);