@availity/yup 5.0.0 → 5.1.1

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 CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [5.1.1](https://github.com/Availity/sdk-js/compare/@availity/yup@5.1.0...@availity/yup@5.1.1) (2022-05-24)
6
+
7
+
8
+
9
+ # [5.1.0](https://github.com/Availity/sdk-js/compare/@availity/yup@5.0.1...@availity/yup@5.1.0) (2022-05-20)
10
+
11
+
12
+ ### Features
13
+
14
+ * **yup:** update how accepted formats are handled for dates ([91006e5](https://github.com/Availity/sdk-js/commit/91006e564766e2bb66cdabc24dd2cdd69bc8b150))
15
+
16
+
17
+
18
+ ## [5.0.1](https://github.com/Availity/sdk-js/compare/@availity/yup@5.0.0...@availity/yup@5.0.1) (2022-04-28)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * add browser field for output ([0ce7170](https://github.com/Availity/sdk-js/commit/0ce717075a82675b8707e4db0cc07cd4af370f3d))
24
+
25
+
26
+
5
27
  # [5.0.0](https://github.com/Availity/sdk-js/compare/@availity/yup@4.2.0...@availity/yup@5.0.0) (2022-04-28)
6
28
 
7
29
 
package/dist/index.d.ts CHANGED
@@ -6,36 +6,64 @@ import Lazy from 'yup/lib/Lazy';
6
6
  import { MixedSchema } from 'yup';
7
7
  import moment, { Moment, unitOfTime } from 'moment';
8
8
 
9
- declare class AvDateSchema extends MixedSchema<Moment> {
10
- format: string;
11
- constructor({ format }?: Options$1);
12
- _typeCheck(value: Moment & {
13
- _i: string;
14
- }): value is Moment & {
15
- _i: string;
16
- };
17
- getValidDate(value: string | Date | Moment): moment.Moment;
9
+ declare class MomentDateSchema extends MixedSchema<Moment> {
10
+ _validFormats: string[];
11
+ constructor({ format, typeError }?: Options$1);
12
+ _typeCheck(value: unknown): value is Moment;
13
+ /**
14
+ * Validate if the date is on or after a specified min
15
+ */
18
16
  min(min: string, message?: string): this;
17
+ /**
18
+ * Validate if the date is on or before a specified max
19
+ */
19
20
  max(max: string, message?: string): this;
20
- isRequired(isRequired?: boolean, msg?: string): this;
21
- between(min: string, max: string, msg?: string, inclusivity?: Inclusivity): this;
21
+ /**
22
+ * Validate if the date is between a specified min or max
23
+ *
24
+ * For Inlcusivity: `[]` === include & `()` === exclude
25
+ */
26
+ between(min: string, max: string, message?: string, inclusivity?: Inclusivity): this;
27
+ /**
28
+ * Set if the field is required and add a custom message
29
+ */
30
+ isRequired(isRequired?: boolean, message?: string): this;
22
31
  }
23
32
  declare type Inclusivity = '()' | '[)' | '(]' | '[]';
24
33
  declare type Options$1 = {
25
- format?: string;
34
+ format?: string | string[];
35
+ typeError?: string;
26
36
  };
27
- declare const avDate: (opts?: Options$1 | undefined) => AvDateSchema;
37
+ declare const avDate: (options?: Options$1 | undefined) => MomentDateSchema;
28
38
 
29
39
  declare class DateRangeSchema extends MixedSchema<DateRange> {
30
40
  startKey: string;
31
41
  endKey: string;
32
42
  format: string;
33
43
  constructor(options?: Options);
44
+ /**
45
+ * Convert the string to a moment object
46
+ */
34
47
  getValidDate(value: string | Date | Moment): moment.Moment;
48
+ /**
49
+ * Validate based on min and max distance between dates
50
+ */
35
51
  distance({ min: { value: minValue, units: minUnits, errorMessage: minErrorMessage }, max: { value: maxValue, units: maxUnits, errorMessage: maxErrorMessage }, }?: DistanceOptions): this;
52
+ /**
53
+ * Validate start date is after given min
54
+ */
36
55
  min(min: string, message?: string): this;
56
+ /**
57
+ * Validate end date is before given max
58
+ */
37
59
  max(max: string, message?: string): this;
60
+ /**
61
+ * Validate dates are between the set min and max
62
+ */
38
63
  between(min: string, max: string, message?: string): this;
64
+ /**
65
+ * Set the field to be required or not
66
+ */
39
67
  isRequired(isRequired?: boolean, msg?: string): this;
40
68
  typeError({ message }: {
41
69
  message: string;
package/dist/index.js CHANGED
@@ -31,91 +31,82 @@ var import_yup3 = require("yup");
31
31
  // src/date.ts
32
32
  var import_yup = require("yup");
33
33
  var import_moment = __toESM(require("moment"));
34
- var formats = ["YYYY-MM-DD", "MMDDYYYY", "YYYYMMDD", "MM-DD-YYYY"];
35
- var AvDateSchema = class extends import_yup.MixedSchema {
36
- constructor({ format = "MM/DD/YYYY" } = {}) {
37
- super({
38
- type: "avDate"
39
- });
40
- this.format = format;
34
+ var defaultFormats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"];
35
+ var MomentDateSchema = class extends import_yup.MixedSchema {
36
+ constructor({ format = [], typeError = "The date entered is in an invalid format." } = {}) {
37
+ super({ type: "avDate" });
38
+ const formats2 = Array.isArray(format) ? format : [format];
39
+ this._validFormats = [...defaultFormats, ...formats2];
41
40
  this.withMutation((schema) => {
42
- if (!schema.tests.some((test) => {
43
- var _a;
44
- return ((_a = test == null ? void 0 : test.OPTIONS) == null ? void 0 : _a.name) === "typeError";
45
- })) {
46
- super.typeError("Date is invalid.");
47
- }
48
- schema.transform(function mutate(value) {
49
- return schema.getValidDate(value);
41
+ schema.typeError(typeError);
42
+ schema.transform(function transform(value, originalValue) {
43
+ if (value && this.isType(value)) {
44
+ return value;
45
+ }
46
+ return (0, import_moment.default)(originalValue, schema._validFormats, true);
50
47
  });
51
48
  });
52
49
  }
53
50
  _typeCheck(value) {
54
- return value.isValid() || value._i === "";
55
- }
56
- getValidDate(value) {
57
- return (0, import_moment.default)(value, [this.format, ...formats], true);
51
+ return import_moment.default.isMoment(value) && (value.isValid() || value._i === "");
58
52
  }
59
53
  min(min, message) {
60
- const minDate = this.getValidDate(min);
61
54
  return this.test({
62
- message: message || `Date must be ${minDate.format(this.format)} or later.`,
55
+ message: ({ min: minDate }) => message || `Date must be ${minDate} or later.`,
63
56
  name: "min",
64
57
  exclusive: true,
65
58
  params: { min },
66
59
  test(value) {
67
- if (!min || !minDate.isValid()) {
60
+ if (!min || !value || !value.isValid()) {
68
61
  return true;
69
62
  }
70
- return value === null || minDate.isSameOrBefore(value);
63
+ return value.isSameOrAfter(min);
71
64
  }
72
65
  });
73
66
  }
74
67
  max(max, message) {
75
- const maxDate = this.getValidDate(max);
76
68
  return this.test({
77
- message: message || `Date must be ${maxDate.format(this.format)} or earlier.`,
69
+ message: ({ max: maxDate }) => message || `Date must be ${maxDate} or earlier.`,
78
70
  name: "max",
79
71
  exclusive: true,
80
72
  params: { max },
81
73
  test(value) {
82
- if (!max || !maxDate.isValid()) {
74
+ if (!max || !value || !value.isValid()) {
83
75
  return true;
84
76
  }
85
- return value === null || maxDate.isSameOrAfter(value);
77
+ return value.isSameOrBefore(max);
86
78
  }
87
79
  });
88
80
  }
89
- isRequired(isRequired2 = true, msg) {
81
+ between(min, max, message, inclusivity = "()") {
90
82
  return this.test({
91
- name: "isRequired",
83
+ name: "between",
92
84
  exclusive: true,
93
- message: msg || "This field is required.",
85
+ message: ({ min: minDate, max: maxDate }) => message || `Date must be between ${minDate} and ${maxDate}.`,
86
+ params: { min, max },
94
87
  test(value) {
95
- if (!isRequired2) {
88
+ if (!value || !value.isValid() || !min || !max) {
96
89
  return true;
97
90
  }
98
- return value !== void 0;
91
+ return value.isBetween(min, max, void 0, inclusivity);
99
92
  }
100
93
  });
101
94
  }
102
- between(min, max, msg, inclusivity = "()") {
103
- const minDate = this.getValidDate(min);
104
- const maxDate = this.getValidDate(max);
95
+ isRequired(isRequired2 = true, message) {
105
96
  return this.test({
106
- name: "between",
97
+ name: "isRequired",
107
98
  exclusive: true,
108
- message: msg || `Date must be between ${minDate.format(this.format)} and ${maxDate.format(this.format)}.`,
99
+ message: message || "This field is required.",
109
100
  test(value) {
110
- if (!value || !min || !max || !minDate.isValid() || !maxDate.isValid()) {
101
+ if (!isRequired2) {
111
102
  return true;
112
103
  }
113
- return value.isBetween(minDate, maxDate, void 0, inclusivity);
104
+ return value ? !!value._i : false;
114
105
  }
115
106
  });
116
107
  }
117
108
  };
118
- var avDate = (opts) => new AvDateSchema(opts);
109
+ var avDate = (options) => new MomentDateSchema(options);
119
110
 
120
111
  // src/dateRange.ts
121
112
  var import_yup2 = require("yup");
@@ -127,7 +118,7 @@ var defaultOptions = {
127
118
  endKey: "endDate",
128
119
  format: "MM/DD/YYYY"
129
120
  };
130
- var formats2 = ["YYYY-MM-DD", "MMDDYYYY", "YYYYMMDD"];
121
+ var formats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"];
131
122
  var DateRangeSchema = class extends import_yup2.MixedSchema {
132
123
  constructor(options) {
133
124
  super({
@@ -144,13 +135,13 @@ var DateRangeSchema = class extends import_yup2.MixedSchema {
144
135
  return {
145
136
  startDate: start ? schema.getValidDate(start) : start,
146
137
  endDate: end ? schema.getValidDate(end) : end,
147
- supportedFormats: [schema.format, ...formats2]
138
+ supportedFormats: [schema.format, ...formats]
148
139
  };
149
140
  });
150
141
  });
151
142
  }
152
143
  getValidDate(value) {
153
- return (0, import_moment2.default)(value, [this.format, ...formats2], true);
144
+ return (0, import_moment2.default)(value, [this.format, ...formats], true);
154
145
  }
155
146
  distance({
156
147
  min: { value: minValue, units: minUnits = "day", errorMessage: minErrorMessage } = { value: 0 },
package/dist/index.mjs CHANGED
@@ -4,91 +4,82 @@ import { addMethod, array, number, object, string } from "yup";
4
4
  // src/date.ts
5
5
  import { MixedSchema } from "yup";
6
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;
7
+ var defaultFormats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"];
8
+ var MomentDateSchema = class extends MixedSchema {
9
+ constructor({ format = [], typeError = "The date entered is in an invalid format." } = {}) {
10
+ super({ type: "avDate" });
11
+ const formats2 = Array.isArray(format) ? format : [format];
12
+ this._validFormats = [...defaultFormats, ...formats2];
14
13
  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);
14
+ schema.typeError(typeError);
15
+ schema.transform(function transform(value, originalValue) {
16
+ if (value && this.isType(value)) {
17
+ return value;
18
+ }
19
+ return moment(originalValue, schema._validFormats, true);
23
20
  });
24
21
  });
25
22
  }
26
23
  _typeCheck(value) {
27
- return value.isValid() || value._i === "";
28
- }
29
- getValidDate(value) {
30
- return moment(value, [this.format, ...formats], true);
24
+ return moment.isMoment(value) && (value.isValid() || value._i === "");
31
25
  }
32
26
  min(min, message) {
33
- const minDate = this.getValidDate(min);
34
27
  return this.test({
35
- message: message || `Date must be ${minDate.format(this.format)} or later.`,
28
+ message: ({ min: minDate }) => message || `Date must be ${minDate} or later.`,
36
29
  name: "min",
37
30
  exclusive: true,
38
31
  params: { min },
39
32
  test(value) {
40
- if (!min || !minDate.isValid()) {
33
+ if (!min || !value || !value.isValid()) {
41
34
  return true;
42
35
  }
43
- return value === null || minDate.isSameOrBefore(value);
36
+ return value.isSameOrAfter(min);
44
37
  }
45
38
  });
46
39
  }
47
40
  max(max, message) {
48
- const maxDate = this.getValidDate(max);
49
41
  return this.test({
50
- message: message || `Date must be ${maxDate.format(this.format)} or earlier.`,
42
+ message: ({ max: maxDate }) => message || `Date must be ${maxDate} or earlier.`,
51
43
  name: "max",
52
44
  exclusive: true,
53
45
  params: { max },
54
46
  test(value) {
55
- if (!max || !maxDate.isValid()) {
47
+ if (!max || !value || !value.isValid()) {
56
48
  return true;
57
49
  }
58
- return value === null || maxDate.isSameOrAfter(value);
50
+ return value.isSameOrBefore(max);
59
51
  }
60
52
  });
61
53
  }
62
- isRequired(isRequired2 = true, msg) {
54
+ between(min, max, message, inclusivity = "()") {
63
55
  return this.test({
64
- name: "isRequired",
56
+ name: "between",
65
57
  exclusive: true,
66
- message: msg || "This field is required.",
58
+ message: ({ min: minDate, max: maxDate }) => message || `Date must be between ${minDate} and ${maxDate}.`,
59
+ params: { min, max },
67
60
  test(value) {
68
- if (!isRequired2) {
61
+ if (!value || !value.isValid() || !min || !max) {
69
62
  return true;
70
63
  }
71
- return value !== void 0;
64
+ return value.isBetween(min, max, void 0, inclusivity);
72
65
  }
73
66
  });
74
67
  }
75
- between(min, max, msg, inclusivity = "()") {
76
- const minDate = this.getValidDate(min);
77
- const maxDate = this.getValidDate(max);
68
+ isRequired(isRequired2 = true, message) {
78
69
  return this.test({
79
- name: "between",
70
+ name: "isRequired",
80
71
  exclusive: true,
81
- message: msg || `Date must be between ${minDate.format(this.format)} and ${maxDate.format(this.format)}.`,
72
+ message: message || "This field is required.",
82
73
  test(value) {
83
- if (!value || !min || !max || !minDate.isValid() || !maxDate.isValid()) {
74
+ if (!isRequired2) {
84
75
  return true;
85
76
  }
86
- return value.isBetween(minDate, maxDate, void 0, inclusivity);
77
+ return value ? !!value._i : false;
87
78
  }
88
79
  });
89
80
  }
90
81
  };
91
- var avDate = (opts) => new AvDateSchema(opts);
82
+ var avDate = (options) => new MomentDateSchema(options);
92
83
 
93
84
  // src/dateRange.ts
94
85
  import { MixedSchema as MixedSchema2, ValidationError } from "yup";
@@ -100,7 +91,7 @@ var defaultOptions = {
100
91
  endKey: "endDate",
101
92
  format: "MM/DD/YYYY"
102
93
  };
103
- var formats2 = ["YYYY-MM-DD", "MMDDYYYY", "YYYYMMDD"];
94
+ var formats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"];
104
95
  var DateRangeSchema = class extends MixedSchema2 {
105
96
  constructor(options) {
106
97
  super({
@@ -117,13 +108,13 @@ var DateRangeSchema = class extends MixedSchema2 {
117
108
  return {
118
109
  startDate: start ? schema.getValidDate(start) : start,
119
110
  endDate: end ? schema.getValidDate(end) : end,
120
- supportedFormats: [schema.format, ...formats2]
111
+ supportedFormats: [schema.format, ...formats]
121
112
  };
122
113
  });
123
114
  });
124
115
  }
125
116
  getValidDate(value) {
126
- return moment2(value, [this.format, ...formats2], true);
117
+ return moment2(value, [this.format, ...formats], true);
127
118
  }
128
119
  distance({
129
120
  min: { value: minValue, units: minUnits = "day", errorMessage: minErrorMessage } = { value: 0 },
package/jest.config.js CHANGED
@@ -1,11 +1,7 @@
1
+ const global = require('../../jest.config');
2
+
1
3
  module.exports = {
4
+ ...global,
2
5
  displayName: 'yup',
3
- preset: '../../jest.preset.js',
4
- globals: {
5
- 'ts-jest': {
6
- tsconfig: '<rootDir>/tsconfig.spec.json',
7
- },
8
- },
9
6
  coverageDirectory: '../../coverage/yup',
10
- coverageReporters: ['json'],
11
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@availity/yup",
3
- "version": "5.0.0",
3
+ "version": "5.1.1",
4
4
  "description": "Additional methods for yup validation library",
5
5
  "keywords": [
6
6
  "yup",
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "author": "Kyle Gray <kyle.gray@availity.com>",
21
+ "browser": "./dist/index.js",
21
22
  "main": "./dist/index.js",
22
23
  "module": "./dist/index.mjs",
23
24
  "types": "./dist/index.d.ts",
@@ -36,8 +37,8 @@
36
37
  },
37
38
  "devDependencies": {
38
39
  "moment": "^2.24.0",
39
- "tsup": "^5.10.1",
40
- "typescript": "^4.5.3"
40
+ "tsup": "^5.12.8",
41
+ "typescript": "^4.6.4"
41
42
  },
42
43
  "peerDependencies": {
43
44
  "moment": "^2.24.0"
package/project.json CHANGED
@@ -18,6 +18,22 @@
18
18
  "tagPrefix": "@availity/${projectName}@",
19
19
  "baseBranch": "master"
20
20
  }
21
+ },
22
+ "lint": {
23
+ "executor": "@nrwl/linter:eslint",
24
+ "options": {
25
+ "eslintConfig": ".eslintrc.yaml",
26
+ "lintFilePatterns": ["packages/yup/**/*.{js,ts}"],
27
+ "silent": false,
28
+ "fix": false,
29
+ "cache": true,
30
+ "cacheLocation": "./node_modules/.cache/yup/.eslintcache",
31
+ "maxWarnings": -1,
32
+ "quiet": false,
33
+ "noEslintrc": false,
34
+ "hasTypeAwareRules": true,
35
+ "cacheStrategy": "metadata"
36
+ }
21
37
  }
22
38
  }
23
39
  }
package/src/date.ts CHANGED
@@ -1,112 +1,120 @@
1
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2
1
  import { MixedSchema } from 'yup';
3
- import moment, { Moment } from 'moment';
2
+ import moment from 'moment';
3
+ import type { Moment } from 'moment';
4
4
 
5
- const formats = ['YYYY-MM-DD', 'MMDDYYYY', 'YYYYMMDD', 'MM-DD-YYYY'];
5
+ const defaultFormats = ['YYYY-MM-DD', 'YYYYMMDD', 'MMDDYYYY', 'MM-DD-YYYY', 'MM/DD/YYYY'];
6
6
 
7
- export default class AvDateSchema extends MixedSchema<Moment> {
8
- format: string;
7
+ export default class MomentDateSchema extends MixedSchema<Moment> {
8
+ _validFormats: string[];
9
9
 
10
- constructor({ format = 'MM/DD/YYYY' }: Options = {}) {
11
- super({
12
- type: 'avDate',
13
- });
10
+ constructor({ format = [], typeError = 'The date entered is in an invalid format.' }: Options = {}) {
11
+ super({ type: 'avDate' });
14
12
 
15
- this.format = format;
13
+ const formats = Array.isArray(format) ? format : [format];
14
+ this._validFormats = [...defaultFormats, ...formats];
16
15
 
17
16
  this.withMutation((schema) => {
18
- if (!schema.tests.some((test) => test?.OPTIONS?.name === 'typeError')) {
19
- super.typeError('Date is invalid.');
20
- }
21
- schema.transform(function mutate(value) {
22
- return schema.getValidDate(value);
17
+ // Set error message for when _typeCheck fails
18
+ schema.typeError(typeError);
19
+
20
+ // Transform value into a moment object
21
+ schema.transform(function transform(value, originalValue) {
22
+ if (value && this.isType(value)) {
23
+ return value;
24
+ }
25
+ return moment(originalValue, schema._validFormats, true);
23
26
  });
24
27
  });
25
28
  }
26
29
 
27
- _typeCheck(value: Moment & { _i: string }): value is Moment & { _i: string } {
28
- // So as long as the passed in value is defined, moment._i will contain a string value to validate.
29
- // If user enters a date and then removes it, should not show a typeError
30
- // Note: this does not prevent other tests, like isRequired, from showing messages
31
- // If user has touched a required field, required error message should still show
32
- return value.isValid() || value._i === '';
33
- }
34
-
35
- getValidDate(value: string | Date | Moment) {
36
- return moment(value, [this.format, ...formats], true);
30
+ // Check if the date is a valid moment object or an empty string
31
+ _typeCheck(value: unknown): value is Moment {
32
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
33
+ // @ts-ignore
34
+ return moment.isMoment(value) && (value.isValid() || value._i === '');
37
35
  }
38
36
 
37
+ /**
38
+ * Validate if the date is on or after a specified min
39
+ */
39
40
  min(min: string, message?: string) {
40
- const minDate = this.getValidDate(min);
41
-
42
41
  return this.test({
43
- message: message || `Date must be ${minDate.format(this.format)} or later.`,
42
+ message: ({ min: minDate }) => message || `Date must be ${minDate} or later.`,
44
43
  name: 'min',
45
44
  exclusive: true,
46
45
  params: { min },
47
46
  test(value) {
48
- if (!min || !minDate.isValid()) {
47
+ // First check if min is defined and we have a valid date
48
+ if (!min || !value || !value.isValid()) {
49
49
  return true;
50
50
  }
51
- return value === null || minDate.isSameOrBefore(value);
51
+ return value.isSameOrAfter(min);
52
52
  },
53
53
  });
54
54
  }
55
55
 
56
+ /**
57
+ * Validate if the date is on or before a specified max
58
+ */
56
59
  max(max: string, message?: string) {
57
- const maxDate = this.getValidDate(max);
58
-
59
60
  return this.test({
60
- message: message || `Date must be ${maxDate.format(this.format)} or earlier.`,
61
+ message: ({ max: maxDate }) => message || `Date must be ${maxDate} or earlier.`,
61
62
  name: 'max',
62
63
  exclusive: true,
63
64
  params: { max },
64
65
  test(value) {
65
- if (!max || !maxDate.isValid()) {
66
+ // First check if max is defined and we have a valid date
67
+ if (!max || !value || !value.isValid()) {
66
68
  return true;
67
69
  }
68
- return value === null || maxDate.isSameOrAfter(value);
70
+ return value.isSameOrBefore(max);
69
71
  },
70
72
  });
71
73
  }
72
74
 
73
- isRequired(isRequired = true, msg?: string) {
75
+ /**
76
+ * Validate if the date is between a specified min or max
77
+ *
78
+ * For Inlcusivity: `[]` === include & `()` === exclude
79
+ */
80
+ between(min: string, max: string, message?: string, inclusivity: Inclusivity = '()') {
74
81
  return this.test({
75
- name: 'isRequired',
82
+ name: 'between',
76
83
  exclusive: true,
77
- message: msg || 'This field is required.',
84
+ message: ({ min: minDate, max: maxDate }) => message || `Date must be between ${minDate} and ${maxDate}.`,
85
+ params: { min, max },
78
86
  test(value) {
79
- if (!isRequired) {
87
+ // First check if min and max are defined and we have a valid date
88
+ if (!value || !value.isValid() || !min || !max) {
80
89
  return true;
81
90
  }
82
91
 
83
- return value !== undefined;
92
+ return value.isBetween(min, max, undefined, inclusivity);
84
93
  },
85
94
  });
86
95
  }
87
96
 
88
- between(min: string, max: string, msg?: string, inclusivity: Inclusivity = '()') {
89
- const minDate = this.getValidDate(min);
90
- const maxDate = this.getValidDate(max);
91
-
92
- // Can't use arrow function because we rely on 'this' referencing yup's internals
97
+ /**
98
+ * Set if the field is required and add a custom message
99
+ */
100
+ isRequired(isRequired = true, message?: string) {
93
101
  return this.test({
94
- name: 'between',
95
- exclusive: true, // Validation errors don't stack
96
- // NOTE: Intentional use of single quotes - yup will handle the string interpolation
97
- message: msg || `Date must be between ${minDate.format(this.format)} and ${maxDate.format(this.format)}.`,
102
+ name: 'isRequired',
103
+ exclusive: true,
104
+ message: message || 'This field is required.',
98
105
  test(value) {
99
- if (!value || !min || !max || !minDate.isValid() || !maxDate.isValid()) {
106
+ if (!isRequired) {
100
107
  return true;
101
108
  }
102
-
103
- return value.isBetween(minDate, maxDate, undefined, inclusivity);
109
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
110
+ // @ts-ignore
111
+ return value ? !!value._i : false;
104
112
  },
105
113
  });
106
114
  }
107
115
  }
108
116
 
109
117
  export type Inclusivity = '()' | '[)' | '(]' | '[]';
110
- type Options = { format?: string };
118
+ type Options = { format?: string | string[]; typeError?: string };
111
119
 
112
- export const avDate = (opts?: Options): AvDateSchema => new AvDateSchema(opts);
120
+ export const avDate = (options?: Options) => new MomentDateSchema(options);
package/src/dateRange.ts CHANGED
@@ -1,6 +1,6 @@
1
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2
1
  import { MixedSchema, ValidationError } from 'yup';
3
- import moment, { Moment, unitOfTime } from 'moment';
2
+ import moment, { unitOfTime } from 'moment';
3
+ import type { Moment } from 'moment';
4
4
  import get from 'lodash/get';
5
5
  import merge from 'lodash/merge';
6
6
 
@@ -10,7 +10,7 @@ const defaultOptions = {
10
10
  format: 'MM/DD/YYYY',
11
11
  };
12
12
 
13
- const formats = ['YYYY-MM-DD', 'MMDDYYYY', 'YYYYMMDD'];
13
+ const formats = ['YYYY-MM-DD', 'YYYYMMDD', 'MMDDYYYY', 'MM-DD-YYYY', 'MM/DD/YYYY'];
14
14
 
15
15
  export default class DateRangeSchema extends MixedSchema<DateRange> {
16
16
  startKey: string;
@@ -45,11 +45,16 @@ export default class DateRangeSchema extends MixedSchema<DateRange> {
45
45
  });
46
46
  }
47
47
 
48
- // Convert the string to a moment object
48
+ /**
49
+ * Convert the string to a moment object
50
+ */
49
51
  getValidDate(value: string | Date | Moment) {
50
52
  return moment(value, [this.format, ...formats], true);
51
53
  }
52
54
 
55
+ /**
56
+ * Validate based on min and max distance between dates
57
+ */
53
58
  distance({
54
59
  min: { value: minValue, units: minUnits = 'day', errorMessage: minErrorMessage } = { value: 0 },
55
60
  max: { value: maxValue, units: maxUnits = 'day', errorMessage: maxErrorMessage } = { value: 0 },
@@ -89,20 +94,20 @@ export default class DateRangeSchema extends MixedSchema<DateRange> {
89
94
  });
90
95
  }
91
96
 
97
+ /**
98
+ * Validate start date is after given min
99
+ */
92
100
  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
101
  return this.test({
97
102
  message: message || (({ min }: { min: string }) => `Date Range must start on or after ${min}`),
98
103
  name: 'min',
99
104
  exclusive: true,
100
105
  params: { min },
101
106
  test({ startDate, supportedFormats } = {}) {
102
- // return true when no startDate or min set
107
+ // Only validate if startDate and min are defined
103
108
  if (!startDate || !min) return true;
104
109
 
105
- // otherwise check if min is correct format and is after given startDate
110
+ // Otherwise check if min is correct format and is after given startDate
106
111
  const minDate = moment(min, supportedFormats, true);
107
112
 
108
113
  return minDate.isValid() && minDate.isSameOrBefore(startDate);
@@ -110,6 +115,9 @@ export default class DateRangeSchema extends MixedSchema<DateRange> {
110
115
  });
111
116
  }
112
117
 
118
+ /**
119
+ * Validate end date is before given max
120
+ */
113
121
  max(max: string, message?: string) {
114
122
  // const maxDate = this.getValidDate(max);
115
123
 
@@ -130,6 +138,9 @@ export default class DateRangeSchema extends MixedSchema<DateRange> {
130
138
  });
131
139
  }
132
140
 
141
+ /**
142
+ * Validate dates are between the set min and max
143
+ */
133
144
  between(min: string, max: string, message?: string) {
134
145
  // const minDate = this.getValidDate(min);
135
146
  // const maxDate = this.getValidDate(max);
@@ -153,6 +164,9 @@ export default class DateRangeSchema extends MixedSchema<DateRange> {
153
164
  });
154
165
  }
155
166
 
167
+ /**
168
+ * Set the field to be required or not
169
+ */
156
170
  isRequired(isRequired = true, msg?: string) {
157
171
  return this.test({
158
172
  name: 'isRequired',
@@ -206,7 +220,6 @@ type Options = { startKey?: string; endKey?: string; format?: string };
206
220
  type DateRange = { startDate?: Moment; endDate?: Moment; supportedFormats?: string[] };
207
221
  type DistanceValue = {
208
222
  value: number;
209
- // unitOfTime namespace is provided by moment library
210
223
  units?: unitOfTime.DurationConstructor;
211
224
  errorMessage?: string;
212
225
  };
package/.eslintrc.yml DELETED
@@ -1,2 +0,0 @@
1
- extends: ../../.eslintrc.yml
2
- ignorePatterns: ['!**/*', 'node_modules/', 'lib/', 'dist/']