envoc-form 2.0.1-7 → 2.0.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.
Files changed (143) hide show
  1. package/README.md +7 -7
  2. package/dist/css/envoc-form-styles.css +43 -5
  3. package/dist/css/envoc-form-styles.css.map +1 -1
  4. package/es/AddressInput/AddressInput.js +7 -6
  5. package/es/ConfirmBaseForm/ConfirmBaseForm.js +3 -2
  6. package/es/ConfirmDeleteForm/ConfirmDeleteForm.js +2 -1
  7. package/es/DatePickerInput/DatePickerInput.js +22 -5
  8. package/es/FileInput/DefaultFileList.js +12 -8
  9. package/es/FileInput/DropzoneFileInput.js +24 -23
  10. package/es/FileInput/FileInput.js +31 -9
  11. package/es/Form/Form.js +4 -2
  12. package/es/FormGroupWrapper.js +2 -1
  13. package/es/FormInput/FormInput.js +12 -6
  14. package/es/FormInputArray/FormInputArray.js +39 -24
  15. package/es/IconInput.js +2 -1
  16. package/es/ReactSelectField/ReactSelectField.js +6 -3
  17. package/es/SubmitFormButton.js +2 -1
  18. package/es/__Tests__/FormTestBase.js +5 -2
  19. package/es/normalizers.js +10 -5
  20. package/es/useStandardFormInput.js +4 -2
  21. package/es/utils/objectToFormData.js +10 -2
  22. package/lib/AddressInput/AddressInput.js +14 -8
  23. package/lib/ConfirmBaseForm/ConfirmBaseForm.js +4 -2
  24. package/lib/ConfirmDeleteForm/ConfirmDeleteForm.js +3 -1
  25. package/lib/DatePickerInput/DatePickerInput.js +25 -5
  26. package/lib/FileInput/DefaultFileList.js +20 -13
  27. package/lib/FileInput/DropzoneFileInput.js +25 -25
  28. package/lib/FileInput/FileInput.js +39 -10
  29. package/lib/Form/Form.js +11 -4
  30. package/lib/Form/FormBasedPreventNavigation.js +5 -1
  31. package/lib/FormGroupWrapper.js +3 -1
  32. package/lib/FormInput/FormInput.js +13 -6
  33. package/lib/FormInputArray/FormInputArray.js +47 -26
  34. package/lib/FormSection.js +5 -1
  35. package/lib/IconInput.js +3 -1
  36. package/lib/ReactSelectField/ReactSelectField.js +13 -5
  37. package/lib/ReactSelectField/index.js +6 -2
  38. package/lib/SubmitFormButton.js +3 -1
  39. package/lib/__Tests__/FormTestBase.js +6 -2
  40. package/lib/index.js +7 -3
  41. package/lib/normalizers.js +10 -5
  42. package/lib/useStandardFormInput.js +5 -2
  43. package/lib/utils/objectToFormData.js +10 -2
  44. package/lib/validators/index.js +5 -1
  45. package/package.json +99 -93
  46. package/src/AddressInput/AddesssInput.test.js +23 -23
  47. package/src/AddressInput/AddressInput.js +73 -73
  48. package/src/AddressInput/UsStates.js +53 -53
  49. package/src/AddressInput/__snapshots__/AddesssInput.test.js.snap +207 -207
  50. package/src/AddressInput/index.js +2 -2
  51. package/src/BoolInput/BoolInput.js +7 -7
  52. package/src/BoolInput/BoolInput.test.js +23 -23
  53. package/src/BoolInput/InlineBoolInput.js +7 -7
  54. package/src/BoolInput/__snapshots__/BoolInput.test.js.snap +89 -89
  55. package/src/BoolInput/boolOptions.js +6 -6
  56. package/src/BoolInput/index.js +4 -4
  57. package/src/ConfirmBaseForm/ConfirmBaseForm.js +37 -37
  58. package/src/ConfirmBaseForm/ConfirmBaseForm.test.js +14 -14
  59. package/src/ConfirmBaseForm/__snapshots__/ConfirmBaseForm.test.js.snap +23 -23
  60. package/src/ConfirmBaseForm/index.js +1 -1
  61. package/src/ConfirmDeleteForm/ConfirmDeleteForm.js +39 -39
  62. package/src/ConfirmDeleteForm/ConfirmDeleteForm.test.js +24 -24
  63. package/src/ConfirmDeleteForm/__snapshots__/ConfirmDeleteForm.test.js.snap +25 -25
  64. package/src/ConfirmDeleteForm/index.js +1 -1
  65. package/src/DatePickerInput/DatePickerInput.js +58 -46
  66. package/src/DatePickerInput/DatePickerInput.test.js +74 -74
  67. package/src/DatePickerInput/__snapshots__/DatePickerInput.test.js.snap +134 -134
  68. package/src/DatePickerInput/date-picker-input.scss +42 -42
  69. package/src/DatePickerInput/index.js +3 -3
  70. package/src/ErrorScrollTarget.js +6 -6
  71. package/src/FileInput/DefaultFileList.js +39 -39
  72. package/src/FileInput/DropzoneFileInput.js +56 -59
  73. package/src/FileInput/DropzoneFileInput.test.js +24 -0
  74. package/src/FileInput/FileInput.js +77 -49
  75. package/src/FileInput/FileInput.test.js +24 -15
  76. package/src/FileInput/__snapshots__/DropzoneFileInput.test.js.snap +57 -0
  77. package/src/FileInput/__snapshots__/FileInput.test.js.snap +58 -22
  78. package/src/FileInput/file-input.scss +58 -17
  79. package/src/FileInput/index.js +4 -4
  80. package/src/Form/FocusError.js +48 -48
  81. package/src/Form/Form.js +139 -138
  82. package/src/Form/Form.test.js +23 -23
  83. package/src/Form/FormBasedPreventNavigation.js +25 -25
  84. package/src/Form/ServerErrorContext.js +7 -7
  85. package/src/Form/__snapshots__/Form.test.js.snap +9 -9
  86. package/src/Form/index.js +3 -3
  87. package/src/FormGroup.js +30 -30
  88. package/src/FormGroupWrapper.js +28 -28
  89. package/src/FormInput/FormInput.js +144 -144
  90. package/src/FormInput/FormInput.test.js +66 -66
  91. package/src/FormInput/__snapshots__/FormInput.test.js.snap +323 -316
  92. package/src/FormInput/form-input.scss +9 -9
  93. package/src/FormInput/index.js +2 -2
  94. package/src/FormInputArray/FormInputArray.js +224 -210
  95. package/src/FormInputArray/FormInputArray.test.js +108 -59
  96. package/src/FormInputArray/__snapshots__/FormInputArray.test.js.snap +52 -40
  97. package/src/FormInputArray/form-input-array.scss +13 -8
  98. package/src/FormInputArray/index.js +2 -2
  99. package/src/FormSection.js +13 -13
  100. package/src/IconInput.js +31 -31
  101. package/src/InlineFormInput/InlineFormInput.js +6 -6
  102. package/src/InlineFormInput/InlineFormInput.test.js +23 -23
  103. package/src/InlineFormInput/__snapshots__/InlineFormInput.test.js.snap +26 -26
  104. package/src/InlineFormInput/index.js +3 -3
  105. package/src/InlineFormInput/inline-form-input.scss +3 -3
  106. package/src/MoneyInput/InlineMoneyInput.js +7 -7
  107. package/src/MoneyInput/MoneyInput.js +7 -7
  108. package/src/MoneyInput/MoneyInputs.test.js +43 -43
  109. package/src/MoneyInput/__snapshots__/MoneyInputs.test.js.snap +81 -81
  110. package/src/MoneyInput/index.js +4 -4
  111. package/src/MoneyInput/money-input.scss +3 -3
  112. package/src/MoneyInput/moneyInputProps.js +12 -12
  113. package/src/NestedFormFieldContext.js +6 -6
  114. package/src/ReactSelectField/ReactSelectField.js +122 -120
  115. package/src/ReactSelectField/index.js +6 -6
  116. package/src/ReactSelectField/react-select-field.scss +5 -5
  117. package/src/StandardFormActions.js +27 -27
  118. package/src/SubmitFormButton.js +28 -28
  119. package/src/__Tests__/FormTestBase.js +14 -11
  120. package/src/__Tests__/IconInput.test.js +23 -23
  121. package/src/__Tests__/StandardFormActions.test.js +23 -23
  122. package/src/__Tests__/SubmitFormButton.test.js +23 -23
  123. package/src/__Tests__/__snapshots__/IconInput.test.js.snap +38 -38
  124. package/src/__Tests__/__snapshots__/StandardFormActions.test.js.snap +25 -25
  125. package/src/__Tests__/__snapshots__/SubmitFormButton.test.js.snap +18 -18
  126. package/src/__Tests__/index.js +2 -2
  127. package/src/_variables.scss +11 -11
  128. package/src/index.js +33 -33
  129. package/src/normalizers.js +42 -32
  130. package/src/selectors.js +3 -3
  131. package/src/styles.scss +7 -7
  132. package/src/useStandardFormInput.js +118 -118
  133. package/src/utils/index.js +3 -3
  134. package/src/utils/objectContainsNonSerializableProperty.js +15 -15
  135. package/src/utils/objectContainsNonSerializableProperty.test.js +49 -49
  136. package/src/utils/objectToFormData.js +89 -83
  137. package/src/utils/objectToFormData.test.js +76 -47
  138. package/src/utils/typeChecks.js +18 -18
  139. package/src/validators/index.js +2 -2
  140. package/src/validators/validators.js +93 -93
  141. package/src/validators/validators.test.js +79 -79
  142. package/CHANGELOG.json +0 -95
  143. package/CHANGELOG.md +0 -58
@@ -1,83 +1,89 @@
1
- //https://github.com/therealparmesh/object-to-formdata/blob/master/src/index.js
2
- import {
3
- isUndefined,
4
- isNull,
5
- isBoolean,
6
- isObject,
7
- isArray,
8
- isDate,
9
- isBlob,
10
- isFile,
11
- } from './typeChecks';
12
-
13
- const serialize = (obj, cfg, fd, pre) => {
14
- cfg = cfg || {};
15
-
16
- cfg.indices = isUndefined(cfg.indices) ? false : cfg.indices;
17
-
18
- cfg.nullsAsUndefineds = isUndefined(cfg.nullsAsUndefineds)
19
- ? false
20
- : cfg.nullsAsUndefineds;
21
-
22
- cfg.booleansAsIntegers = isUndefined(cfg.booleansAsIntegers)
23
- ? false
24
- : cfg.booleansAsIntegers;
25
-
26
- cfg.allowEmptyArrays = isUndefined(cfg.allowEmptyArrays)
27
- ? false
28
- : cfg.allowEmptyArrays;
29
-
30
- //reverse of normal because we want a different default
31
- cfg.dotNotation = isUndefined(cfg.dotNotation) ? true : cfg.dotNotation;
32
-
33
- fd = fd || new FormData();
34
-
35
- if (isUndefined(obj)) {
36
- return fd;
37
- } else if (isNull(obj)) {
38
- if (!cfg.nullsAsUndefineds) {
39
- fd.append(pre, '');
40
- }
41
- } else if (isBoolean(obj)) {
42
- if (cfg.booleansAsIntegers) {
43
- fd.append(pre, obj ? 1 : 0);
44
- } else {
45
- fd.append(pre, obj);
46
- }
47
- } else if (isArray(obj)) {
48
- if (obj.length) {
49
- obj.forEach((value, index) => {
50
- const key = pre + '[' + (cfg.indices ? index : '') + ']';
51
- serialize(value, cfg, fd, key);
52
- });
53
- } else if (cfg.allowEmptyArrays) {
54
- fd.append(pre + '[]', '');
55
- }
56
- } else if (isDate(obj)) {
57
- fd.append(pre, obj.toISOString());
58
- } else if (isObject(obj) && !isFile(obj) && !isBlob(obj)) {
59
- Object.keys(obj).forEach((prop) => {
60
- const value = obj[prop];
61
-
62
- if (isArray(value)) {
63
- while (prop.length > 2 && prop.lastIndexOf('[]') === prop.length - 2) {
64
- prop = prop.substring(0, prop.length - 2);
65
- }
66
- }
67
-
68
- const key = pre
69
- ? cfg.dotNotation
70
- ? pre + '.' + prop
71
- : pre + '[' + prop + ']'
72
- : prop;
73
-
74
- serialize(value, cfg, fd, key);
75
- });
76
- } else {
77
- fd.append(pre, obj);
78
- }
79
-
80
- return fd;
81
- };
82
-
83
- export default serialize;
1
+ // Original: https://github.com/therealparmesh/object-to-formdata/blob/master/src/index.js
2
+ // With Multiple Form File Fix: https://github.com/therealparmesh/object-to-formdata/pull/94/files
3
+ import {
4
+ isUndefined,
5
+ isNull,
6
+ isBoolean,
7
+ isObject,
8
+ isArray,
9
+ isDate,
10
+ isBlob,
11
+ isFile,
12
+ } from './typeChecks';
13
+
14
+ const serialize = (obj, cfg, fd, pre) => {
15
+ cfg = cfg || {};
16
+
17
+ cfg.indices = isUndefined(cfg.indices) ? false : cfg.indices;
18
+
19
+ cfg.nullsAsUndefineds = isUndefined(cfg.nullsAsUndefineds)
20
+ ? false
21
+ : cfg.nullsAsUndefineds;
22
+
23
+ cfg.booleansAsIntegers = isUndefined(cfg.booleansAsIntegers)
24
+ ? false
25
+ : cfg.booleansAsIntegers;
26
+
27
+ cfg.allowEmptyArrays = isUndefined(cfg.allowEmptyArrays)
28
+ ? false
29
+ : cfg.allowEmptyArrays;
30
+
31
+ //reverse of normal because we want a different default
32
+ cfg.dotNotation = isUndefined(cfg.dotNotation) ? true : cfg.dotNotation;
33
+
34
+ fd = fd || new FormData();
35
+
36
+ if (isUndefined(obj)) {
37
+ return fd;
38
+ } else if (isNull(obj)) {
39
+ if (!cfg.nullsAsUndefineds) {
40
+ fd.append(pre, '');
41
+ }
42
+ } else if (isBoolean(obj)) {
43
+ if (cfg.booleansAsIntegers) {
44
+ fd.append(pre, obj ? 1 : 0);
45
+ } else {
46
+ fd.append(pre, obj);
47
+ }
48
+ } else if (isArray(obj)) {
49
+ if (obj.length) {
50
+ obj.forEach((value, index) => {
51
+ let key;
52
+ if (cfg.noFileListBrackets && isFile(value)) {
53
+ key = pre;
54
+ } else {
55
+ key = pre + '[' + (cfg.indices ? index : '') + ']';
56
+ }
57
+ serialize(value, cfg, fd, key);
58
+ });
59
+ } else if (cfg.allowEmptyArrays) {
60
+ fd.append(pre + '[]', '');
61
+ }
62
+ } else if (isDate(obj)) {
63
+ fd.append(pre, obj.toISOString());
64
+ } else if (isObject(obj) && !isFile(obj) && !isBlob(obj)) {
65
+ Object.keys(obj).forEach((prop) => {
66
+ const value = obj[prop];
67
+
68
+ if (isArray(value)) {
69
+ while (prop.length > 2 && prop.lastIndexOf('[]') === prop.length - 2) {
70
+ prop = prop.substring(0, prop.length - 2);
71
+ }
72
+ }
73
+
74
+ const key = pre
75
+ ? cfg.dotNotation
76
+ ? pre + '.' + prop
77
+ : pre + '[' + prop + ']'
78
+ : prop;
79
+
80
+ serialize(value, cfg, fd, key);
81
+ });
82
+ } else {
83
+ fd.append(pre, obj);
84
+ }
85
+
86
+ return fd;
87
+ };
88
+
89
+ export default serialize;
@@ -1,47 +1,76 @@
1
- import serialize from './objectToFormData';
2
-
3
- const options = {
4
- indices: true,
5
- dotNotation: true,
6
- allowEmptyArrays: true,
7
- };
8
-
9
- describe('Object To Form Data', () => {
10
- it('properly serializes a simple object', () => {
11
- const object = {
12
- name: 'Bob',
13
- age: 20,
14
- };
15
-
16
- const result = serialize(object, options);
17
- expect(result.get('name')).toBe(object.name);
18
- expect(result.get('age')).toBe('20');
19
- });
20
-
21
- it('properly serializes an object with an array property', () => {
22
- const object = {
23
- name: 'Bob',
24
- age: 20,
25
- favoriteFoods: ['Hamburger', 'Pizza'],
26
- };
27
-
28
- const result = serialize(object, options);
29
- expect(result.get('name')).toBe(object.name);
30
- expect(result.has('favoriteFoods[0]')).toBe(true);
31
- expect(result.get('favoriteFoods[0]')).toBe('Hamburger');
32
- expect(result.has('favoriteFoods[1]')).toBe(true);
33
- expect(result.get('favoriteFoods[1]')).toBe('Pizza');
34
- });
35
-
36
- it('properly serializes a file in a form', () => {
37
- const object = {
38
- a: new File(['foo'], 'foo.txt', {
39
- type: 'text/plain',
40
- }),
41
- };
42
-
43
- const result = serialize(object, options);
44
- expect(result.has('a')).toBe(true);
45
- expect(result.get('a')).toBeInstanceOf(File);
46
- });
47
- });
1
+ import serialize from './objectToFormData';
2
+
3
+ const options = {
4
+ indices: true,
5
+ dotNotation: true,
6
+ allowEmptyArrays: true,
7
+ noFileListBrackets: true,
8
+ };
9
+
10
+ const formDataAppend = global.FormData.prototype.append;
11
+
12
+ beforeEach(() => {
13
+ global.FormData.prototype.append = jest.fn(formDataAppend);
14
+ });
15
+
16
+ describe('Object To Form Data', () => {
17
+ it('properly serializes a simple object', () => {
18
+ const object = {
19
+ name: 'Bob',
20
+ age: 20,
21
+ };
22
+
23
+ const result = serialize(object, options);
24
+ expect(result.get('name')).toBe(object.name);
25
+ expect(result.get('age')).toBe('20');
26
+ });
27
+
28
+ it('properly serializes an object with a non-file array property', () => {
29
+ const object = {
30
+ name: 'Bob',
31
+ age: 20,
32
+ favoriteFoods: ['Hamburger', 'Pizza'],
33
+ };
34
+
35
+ const result = serialize(object, options);
36
+ expect(result.get('name')).toBe(object.name);
37
+ expect(result.has('favoriteFoods[0]')).toBe(true);
38
+ expect(result.get('favoriteFoods[0]')).toBe('Hamburger');
39
+ expect(result.has('favoriteFoods[1]')).toBe(true);
40
+ expect(result.get('favoriteFoods[1]')).toBe('Pizza');
41
+ });
42
+
43
+ it('properly serializes a file in a form', () => {
44
+ const object = {
45
+ a: new File(['foo'], 'foo.txt', {
46
+ type: 'text/plain',
47
+ }),
48
+ };
49
+
50
+ const result = serialize(object, options);
51
+ expect(result.has('a')).toBe(true);
52
+ expect(result.get('a')).toBeInstanceOf(File);
53
+ });
54
+
55
+ it('properly serializes an object with a file array property', () => {
56
+ const foo = new File(['foo'], 'foo.txt', {
57
+ type: 'text/plain',
58
+ });
59
+ const bar = new File(['bar'], 'bar.txt', {
60
+ type: 'text/plain',
61
+ });
62
+ const object = {
63
+ fileArray: [foo, bar],
64
+ };
65
+
66
+ const result = serialize(object, options);
67
+ expect(result.append).toHaveBeenCalledTimes(2);
68
+ expect(result.append).toHaveBeenNthCalledWith(1, 'fileArray', foo);
69
+ expect(result.append).toHaveBeenNthCalledWith(2, 'fileArray', bar);
70
+ expect(result.has('fileArray[]')).toBe(false);
71
+ expect(result.has('fileArray[0]')).toBe(false);
72
+ expect(result.has('fileArray[1]')).toBe(false);
73
+ expect(result.has('fileArray')).toBe(true);
74
+ expect(result.getAll('fileArray')).toEqual(object.fileArray);
75
+ });
76
+ });
@@ -1,18 +1,18 @@
1
- export const isUndefined = (value) => value === undefined;
2
- export const isNull = (value) => value === null;
3
- export const isBoolean = (value) => typeof value === 'boolean';
4
- export const isObject = (value) => value === Object(value);
5
- export const isArray = (value) => Array.isArray(value);
6
- export const isDate = (value) => value instanceof Date;
7
-
8
- export const isBlob = (value) =>
9
- value &&
10
- typeof value.size === 'number' &&
11
- typeof value.type === 'string' &&
12
- typeof value.slice === 'function';
13
-
14
- export const isFile = (value) =>
15
- isBlob(value) &&
16
- typeof value.name === 'string' &&
17
- (typeof value.lastModifiedDate === 'object' ||
18
- typeof value.lastModified === 'number');
1
+ export const isUndefined = (value) => value === undefined;
2
+ export const isNull = (value) => value === null;
3
+ export const isBoolean = (value) => typeof value === 'boolean';
4
+ export const isObject = (value) => value === Object(value);
5
+ export const isArray = (value) => Array.isArray(value);
6
+ export const isDate = (value) => value instanceof Date;
7
+
8
+ export const isBlob = (value) =>
9
+ value &&
10
+ typeof value.size === 'number' &&
11
+ typeof value.type === 'string' &&
12
+ typeof value.slice === 'function';
13
+
14
+ export const isFile = (value) =>
15
+ isBlob(value) &&
16
+ typeof value.name === 'string' &&
17
+ (typeof value.lastModifiedDate === 'object' ||
18
+ typeof value.lastModified === 'number');
@@ -1,2 +1,2 @@
1
- import * as validators from './validators';
2
- export default validators;
1
+ import * as validators from './validators';
2
+ export default validators;
@@ -1,93 +1,93 @@
1
- export const required = (value) =>
2
- value || value === false || value === 0 ? undefined : 'Required';
3
-
4
- //asserts that the value is a certain number of characters. numbers are coerced to a string
5
- export const length = (len) => (value) => {
6
- let val = value;
7
- const type = typeof val;
8
- switch (type) {
9
- case 'undefined':
10
- return undefined;
11
- case 'string':
12
- break;
13
- case 'number':
14
- val = val.toString();
15
- break;
16
- default:
17
- console.error(`Invalid value type: ${type} passed to length validator`);
18
- }
19
- return val.length === len ? undefined : `Length must be ${len}`;
20
- };
21
-
22
- export const integer = (val) => {
23
- if (!Number.isInteger(parseFloat(val))) {
24
- return 'Must be a whole number';
25
- }
26
- };
27
-
28
- export const maxLength = function maxLength(length) {
29
- return (value) => {
30
- if (value) {
31
- return value.length <= length
32
- ? undefined
33
- : `Maximum length ${length} exceeded`;
34
- } else {
35
- return undefined;
36
- }
37
- };
38
- };
39
-
40
- export function maxCount(count) {
41
- return (value) => {
42
- return !value || value.filter((x) => !x.isDeleted).length <= count
43
- ? undefined
44
- : `Should not have more than ${count}`;
45
- };
46
- }
47
-
48
- export function minCount(count) {
49
- return (value) => {
50
- return value && value.filter((x) => !x.isDeleted).length >= count
51
- ? undefined
52
- : `Should have at least ${count}`;
53
- };
54
- }
55
-
56
- export const maxValue = function maxValue(value) {
57
- return (inputValue) => {
58
- if (inputValue && value) {
59
- return inputValue <= value
60
- ? undefined
61
- : `Maximum value ${value} exceeded`;
62
- } else {
63
- return undefined;
64
- }
65
- };
66
- };
67
-
68
- export const minValue = function minValue(value) {
69
- return (inputValue) => {
70
- if (inputValue && value) {
71
- return inputValue >= value ? undefined : `Minimum value ${value} not met`;
72
- } else {
73
- return undefined;
74
- }
75
- };
76
- };
77
-
78
- export const zipCode = (value) => {
79
- return value && !/^[0-9]{5}(?:-[0-9]{4})?$/.test(value)
80
- ? 'Invalid ZIP Code'
81
- : undefined;
82
- };
83
-
84
- //one of the validators provided must be true
85
- export const any = (...validatorList) => (value) => {
86
- if (validatorList.length === 0 || !value) {
87
- return;
88
- }
89
- return validatorList.reduce(
90
- (isAnyTrue, any) => (isAnyTrue ? isAnyTrue : any(value)),
91
- false
92
- );
93
- };
1
+ export const required = (value) =>
2
+ value || value === false || value === 0 ? undefined : 'Required';
3
+
4
+ //asserts that the value is a certain number of characters. numbers are coerced to a string
5
+ export const length = (len) => (value) => {
6
+ let val = value;
7
+ const type = typeof val;
8
+ switch (type) {
9
+ case 'undefined':
10
+ return undefined;
11
+ case 'string':
12
+ break;
13
+ case 'number':
14
+ val = val.toString();
15
+ break;
16
+ default:
17
+ console.error(`Invalid value type: ${type} passed to length validator`);
18
+ }
19
+ return val.length === len ? undefined : `Length must be ${len}`;
20
+ };
21
+
22
+ export const integer = (val) => {
23
+ if (!Number.isInteger(parseFloat(val))) {
24
+ return 'Must be a whole number';
25
+ }
26
+ };
27
+
28
+ export const maxLength = function maxLength(length) {
29
+ return (value) => {
30
+ if (value) {
31
+ return value.length <= length
32
+ ? undefined
33
+ : `Maximum length ${length} exceeded`;
34
+ } else {
35
+ return undefined;
36
+ }
37
+ };
38
+ };
39
+
40
+ export function maxCount(count) {
41
+ return (value) => {
42
+ return !value || value.filter((x) => !x.isDeleted).length <= count
43
+ ? undefined
44
+ : `Should not have more than ${count}`;
45
+ };
46
+ }
47
+
48
+ export function minCount(count) {
49
+ return (value) => {
50
+ return value && value.filter((x) => !x.isDeleted).length >= count
51
+ ? undefined
52
+ : `Should have at least ${count}`;
53
+ };
54
+ }
55
+
56
+ export const maxValue = function maxValue(value) {
57
+ return (inputValue) => {
58
+ if (inputValue && value) {
59
+ return inputValue <= value
60
+ ? undefined
61
+ : `Maximum value ${value} exceeded`;
62
+ } else {
63
+ return undefined;
64
+ }
65
+ };
66
+ };
67
+
68
+ export const minValue = function minValue(value) {
69
+ return (inputValue) => {
70
+ if (inputValue && value) {
71
+ return inputValue >= value ? undefined : `Minimum value ${value} not met`;
72
+ } else {
73
+ return undefined;
74
+ }
75
+ };
76
+ };
77
+
78
+ export const zipCode = (value) => {
79
+ return value && !/^[0-9]{5}(?:-[0-9]{4})?$/.test(value)
80
+ ? 'Invalid ZIP Code'
81
+ : undefined;
82
+ };
83
+
84
+ //one of the validators provided must be true
85
+ export const any = (...validatorList) => (value) => {
86
+ if (validatorList.length === 0 || !value) {
87
+ return;
88
+ }
89
+ return validatorList.reduce(
90
+ (isAnyTrue, any) => (isAnyTrue ? isAnyTrue : any(value)),
91
+ false
92
+ );
93
+ };