@aemforms/af-core 0.15.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.
Files changed (69) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +34 -0
  3. package/lib/BaseNode.d.ts +117 -0
  4. package/lib/BaseNode.js +368 -0
  5. package/lib/Checkbox.d.ts +80 -0
  6. package/lib/Checkbox.js +49 -0
  7. package/lib/CheckboxGroup.d.ts +30 -0
  8. package/lib/CheckboxGroup.js +40 -0
  9. package/lib/Container.d.ts +336 -0
  10. package/lib/Container.js +279 -0
  11. package/lib/Field.d.ts +185 -0
  12. package/lib/Field.js +432 -0
  13. package/lib/Fieldset.d.ts +31 -0
  14. package/lib/Fieldset.js +97 -0
  15. package/lib/FileObject.d.ts +17 -0
  16. package/lib/FileObject.js +30 -0
  17. package/lib/FileUpload.d.ts +42 -0
  18. package/lib/FileUpload.js +299 -0
  19. package/lib/Form.d.ts +413 -0
  20. package/lib/Form.js +247 -0
  21. package/lib/FormInstance.d.ts +26 -0
  22. package/lib/FormInstance.js +116 -0
  23. package/lib/FormMetaData.d.ts +11 -0
  24. package/lib/FormMetaData.js +28 -0
  25. package/lib/Node.d.ts +12 -0
  26. package/lib/Node.js +27 -0
  27. package/lib/Scriptable.d.ts +27 -0
  28. package/lib/Scriptable.js +216 -0
  29. package/lib/controller/Controller.d.ts +207 -0
  30. package/lib/controller/Controller.js +263 -0
  31. package/lib/controller/EventQueue.d.ts +24 -0
  32. package/lib/controller/EventQueue.js +99 -0
  33. package/lib/controller/index.d.ts +1 -0
  34. package/lib/controller/index.js +24 -0
  35. package/lib/data/DataGroup.d.ts +25 -0
  36. package/lib/data/DataGroup.js +74 -0
  37. package/lib/data/DataValue.d.ts +22 -0
  38. package/lib/data/DataValue.js +50 -0
  39. package/lib/data/EmptyDataValue.d.ts +14 -0
  40. package/lib/data/EmptyDataValue.js +46 -0
  41. package/lib/index.d.ts +27 -0
  42. package/lib/index.js +59 -0
  43. package/lib/rules/FunctionRuntime.d.ts +44 -0
  44. package/lib/rules/FunctionRuntime.js +271 -0
  45. package/lib/rules/RuleEngine.d.ts +23 -0
  46. package/lib/rules/RuleEngine.js +67 -0
  47. package/lib/types/Json.d.ts +126 -0
  48. package/lib/types/Json.js +16 -0
  49. package/lib/types/Model.d.ts +352 -0
  50. package/lib/types/Model.js +20 -0
  51. package/lib/types/index.d.ts +2 -0
  52. package/lib/types/index.js +25 -0
  53. package/lib/utils/DataRefParser.d.ts +30 -0
  54. package/lib/utils/DataRefParser.js +249 -0
  55. package/lib/utils/Fetch.d.ts +7 -0
  56. package/lib/utils/Fetch.js +29 -0
  57. package/lib/utils/FormUtils.d.ts +47 -0
  58. package/lib/utils/FormUtils.js +172 -0
  59. package/lib/utils/JsonUtils.d.ts +55 -0
  60. package/lib/utils/JsonUtils.js +128 -0
  61. package/lib/utils/LogUtils.d.ts +7 -0
  62. package/lib/utils/LogUtils.js +17 -0
  63. package/lib/utils/SchemaUtils.d.ts +16 -0
  64. package/lib/utils/SchemaUtils.js +92 -0
  65. package/lib/utils/TranslationUtils.d.ts +34 -0
  66. package/lib/utils/TranslationUtils.js +156 -0
  67. package/lib/utils/ValidationUtils.d.ts +153 -0
  68. package/lib/utils/ValidationUtils.js +339 -0
  69. package/package.json +60 -0
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2022 Adobe, Inc.
4
+ *
5
+ * Your access and use of this software is governed by the Adobe Customer Feedback Program Terms and Conditions or other Beta License Agreement signed by your employer and Adobe, Inc.. This software is NOT open source and may not be used without one of the foregoing licenses. Even with a foregoing license, your access and use of this file is limited to the earlier of (a) 180 days, (b) general availability of the product(s) which utilize this software (i.e. AEM Forms), (c) January 1, 2023, (d) Adobe providing notice to you that you may no longer use the software or that your beta trial has otherwise ended.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ADOBE NOR ITS THIRD PARTY PROVIDERS AND PARTNERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createTranslationObject = exports.createTranslationObj = exports.addTranslationId = exports.invalidateTranslation = exports.CUSTOM_PROPS_KEY = exports.TRANSLATION_ID = exports.TRANSLATION_TOKEN = void 0;
11
+ /**
12
+ * Defines generic utilities to translated form model definition
13
+ */
14
+ // todo: The API's defined in this file could move to a different package later on
15
+ const types_1 = require("../types");
16
+ /** Token used while creating translation specific properties from `adaptive form specification` */
17
+ exports.TRANSLATION_TOKEN = '##';
18
+ /** Name of the object which holds all translation specific properties */
19
+ exports.TRANSLATION_ID = 'afs:translationIds';
20
+ exports.CUSTOM_PROPS_KEY = 'properties';
21
+ const defaultBcp47LangTags = [
22
+ 'de-DE',
23
+ 'en-US',
24
+ 'es-ES',
25
+ 'fr-FR',
26
+ 'it-IT',
27
+ 'ja-JP',
28
+ 'ko-KR',
29
+ 'pt-BR',
30
+ 'zh-CN',
31
+ 'zh-TW'
32
+ ];
33
+ /**
34
+ * @private
35
+ */
36
+ const invalidateTranslation = (input, updates) => {
37
+ types_1.translationProps.forEach((prop) => {
38
+ var _a, _b, _c, _d;
39
+ if (prop in updates && ((_b = (_a = input === null || input === void 0 ? void 0 : input[exports.CUSTOM_PROPS_KEY]) === null || _a === void 0 ? void 0 : _a[exports.TRANSLATION_ID]) === null || _b === void 0 ? void 0 : _b[prop])) {
40
+ (_d = (_c = input === null || input === void 0 ? void 0 : input[exports.CUSTOM_PROPS_KEY]) === null || _c === void 0 ? void 0 : _c[exports.TRANSLATION_ID]) === null || _d === void 0 ? true : delete _d[prop];
41
+ }
42
+ });
43
+ };
44
+ exports.invalidateTranslation = invalidateTranslation;
45
+ /**
46
+ * @private
47
+ */
48
+ const addTranslationId = (input, additionalTranslationProps = []) => {
49
+ // don't create a schema copy, add it to the existing
50
+ const model = input;
51
+ const transProps = [...types_1.translationProps, ...additionalTranslationProps];
52
+ _createTranslationId(model, '', transProps);
53
+ return model;
54
+ };
55
+ exports.addTranslationId = addTranslationId;
56
+ /**
57
+ * @private
58
+ */
59
+ const _createTranslationId = (input, path, transProps) => {
60
+ Object.entries(input).forEach(([key, value]) => {
61
+ if (typeof value == 'object') {
62
+ _createTranslationId(value, ((key === 'items') ? path : `${path === '' ? path : path + exports.TRANSLATION_TOKEN}${key}${exports.TRANSLATION_TOKEN}${Math.floor(Math.random() * 10000) + 1}`), transProps);
63
+ }
64
+ else {
65
+ // set it only if either of type or fieldType properties is present
66
+ if ('type' in input ||
67
+ 'fieldType' in input) {
68
+ for (const transProp of transProps) {
69
+ // if property exist add it
70
+ if (input[transProp] != null) {
71
+ // if translation id is not yet set, set it
72
+ if (!(exports.CUSTOM_PROPS_KEY in input)) {
73
+ input[exports.CUSTOM_PROPS_KEY] = {};
74
+ }
75
+ if (!(exports.TRANSLATION_ID in input[exports.CUSTOM_PROPS_KEY])) {
76
+ input[exports.CUSTOM_PROPS_KEY][exports.TRANSLATION_ID] = {};
77
+ }
78
+ // if transprop is not yet set, set it
79
+ // this is done to prevent overwrite
80
+ if (!(transProp in input[exports.CUSTOM_PROPS_KEY][exports.TRANSLATION_ID])) {
81
+ input[exports.CUSTOM_PROPS_KEY][exports.TRANSLATION_ID][transProp] = `${path}${exports.TRANSLATION_TOKEN}${transProp}${exports.TRANSLATION_TOKEN}${Math.floor(Math.random() * 10000) + 1}`;
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ });
88
+ };
89
+ /**
90
+ * @param input
91
+ * @param translationObj
92
+ * @param translationProps
93
+ * @private
94
+ */
95
+ const _createTranslationObj = (input, translationObj, translationProps) => {
96
+ Object.values(input).forEach((value) => {
97
+ var _a, _b;
98
+ if (typeof value == 'object') {
99
+ _createTranslationObj(value, translationObj, translationProps);
100
+ }
101
+ else {
102
+ for (const translationProp of translationProps) {
103
+ if (translationProp in input && ((_b = (_a = input === null || input === void 0 ? void 0 : input[exports.CUSTOM_PROPS_KEY]) === null || _a === void 0 ? void 0 : _a[exports.TRANSLATION_ID]) === null || _b === void 0 ? void 0 : _b[translationProp])) {
104
+ // todo: right now we create only for english
105
+ if (input[translationProp] instanceof Array) {
106
+ input[translationProp].forEach((item, index) => {
107
+ if (typeof item === 'string') { // only if string, then convert, since values can also be boolean
108
+ // @ts-ignore
109
+ translationObj[`${input[exports.CUSTOM_PROPS_KEY][exports.TRANSLATION_ID][translationProp]}${exports.TRANSLATION_TOKEN}${index}`] = item;
110
+ }
111
+ });
112
+ }
113
+ else {
114
+ // @ts-ignore
115
+ translationObj[`${input[exports.CUSTOM_PROPS_KEY][exports.TRANSLATION_ID][translationProp]}`] = input[translationProp];
116
+ }
117
+ }
118
+ }
119
+ }
120
+ });
121
+ };
122
+ /**
123
+ * @param input
124
+ * @param additionalTranslationProps
125
+ * @private
126
+ */
127
+ const createTranslationObj = (input, additionalTranslationProps = []) => {
128
+ const obj = {};
129
+ const transProps = [...types_1.translationProps, ...additionalTranslationProps];
130
+ _createTranslationObj(input, obj, transProps);
131
+ return obj;
132
+ };
133
+ exports.createTranslationObj = createTranslationObj;
134
+ /**
135
+ * Creates translation object with [BCP 47](https://tools.ietf.org/search/bcp47) language tags as key and value is a translation object. Key of translation object is
136
+ * generated based on the form hierarchy and it is separated by "##" token to signify that the id is machine generated (ie its not a human generated string)
137
+ * @param input form model definition
138
+ * @param additionalTranslationProps optional properties which needs to be translated, by default, only OOTB properties of form model definition is translated
139
+ * @param bcp47LangTags optional additional language tags
140
+ * @returns translation object for each bcp 47 language tag
141
+ */
142
+ const createTranslationObject = (input, additionalTranslationProps = [], bcp47LangTags = []) => {
143
+ const transProps = [...types_1.translationProps, ...additionalTranslationProps];
144
+ // create a copy of the input
145
+ const inputCopy = JSON.parse(JSON.stringify(input));
146
+ const obj = (0, exports.createTranslationObj)((0, exports.addTranslationId)(inputCopy), transProps);
147
+ const langTags = [...defaultBcp47LangTags, ...bcp47LangTags];
148
+ const allLangs = {};
149
+ for (const langTag of langTags) {
150
+ // todo: added temporarily to test
151
+ // todo: need to fix this as per machine translation
152
+ allLangs[langTag] = JSON.parse(JSON.stringify(obj));
153
+ }
154
+ return [inputCopy, allLangs];
155
+ };
156
+ exports.createTranslationObject = createTranslationObject;
@@ -0,0 +1,153 @@
1
+ /** Validation result type **/
2
+ declare type ValidationResult = {
3
+ valid: boolean;
4
+ value: any;
5
+ };
6
+ export declare const isDataUrl: (str: string) => boolean;
7
+ export declare const ValidConstraints: {
8
+ date: string[];
9
+ string: string[];
10
+ number: string[];
11
+ array: string[];
12
+ file: string[];
13
+ };
14
+ /**
15
+ * Implementation of all constraints defined by `adaptive form specification`
16
+ */
17
+ export declare const Constraints: {
18
+ /**
19
+ * Implementation of type constraint
20
+ * @param constraint `type` property of the form object
21
+ * @param inputVal value of the form object
22
+ * @return {@link ValidationResult | validation result}
23
+ */
24
+ type: (constraint: string, inputVal: any) => ValidationResult;
25
+ /**
26
+ * Implementation of format constraint
27
+ * @param constraint `format` property of the form object
28
+ * @param input value of the form object
29
+ * @return {@link ValidationResult | validation result}
30
+ */
31
+ format: (constraint: string, input: string) => {
32
+ valid: boolean;
33
+ value: string;
34
+ };
35
+ /**
36
+ * Implementation of minimum constraint
37
+ * @param constraint `minimum` property of the form object
38
+ * @param value value of the form object
39
+ * @return {@link ValidationResult | validation result}
40
+ */
41
+ minimum: (constraint: number, value: number) => {
42
+ valid: boolean;
43
+ value: number;
44
+ };
45
+ /**
46
+ * Implementation of maximum constraint
47
+ * @param constraint `maximum` property of the form object
48
+ * @param value value of the form object
49
+ * @return {@link ValidationResult | validation result}
50
+ */
51
+ maximum: (constraint: number, value: number) => {
52
+ valid: boolean;
53
+ value: number;
54
+ };
55
+ /**
56
+ * Implementation of exclusiveMinimum constraint
57
+ * @param constraint `minimum` property of the form object
58
+ * @param value value of the form object
59
+ * @return {@link ValidationResult | validation result}
60
+ */
61
+ exclusiveMinimum: (constraint: number, value: number) => {
62
+ valid: boolean;
63
+ value: number;
64
+ };
65
+ /**
66
+ * Implementation of exclusiveMaximum constraint
67
+ * @param constraint `maximum` property of the form object
68
+ * @param value value of the form object
69
+ * @return {@link ValidationResult | validation result}
70
+ */
71
+ exclusiveMaximum: (constraint: number, value: number) => {
72
+ valid: boolean;
73
+ value: number;
74
+ };
75
+ /**
76
+ * Implementation of the minItems constraint
77
+ * @param constraint `minItems` constraint from object
78
+ * @param value value of the form object
79
+ */
80
+ minItems: <T>(constraint: number, value: T[]) => {
81
+ valid: boolean;
82
+ value: T[];
83
+ };
84
+ /**
85
+ * Implementation of the maxItems constraint
86
+ * @param constraint `maxItems` constraint from object
87
+ * @param value value of the form object
88
+ */
89
+ maxItems: <T_1>(constraint: number, value: T_1[]) => {
90
+ valid: boolean;
91
+ value: T_1[];
92
+ };
93
+ /**
94
+ * Implementation of the uniqueItems constraint
95
+ * @param constraint `uniqueItems` constraint from object
96
+ * @param value value of the form object
97
+ */
98
+ uniqueItems: <T_2>(constraint: boolean, value: T_2[]) => {
99
+ valid: boolean;
100
+ value: T_2[];
101
+ };
102
+ /**
103
+ * Implementation of minLength constraint
104
+ * @param constraint `minLength` property of the form object
105
+ * @param value value of the form object
106
+ * @return {@link ValidationResult | validation result}
107
+ */
108
+ minLength: (constraint: number, value: string) => {
109
+ value: string;
110
+ valid: boolean;
111
+ };
112
+ /**
113
+ * Implementation of maxLength constraint
114
+ * @param constraint `maxLength` property of the form object
115
+ * @param value value of the form object
116
+ * @return {@link ValidationResult | validation result}
117
+ */
118
+ maxLength: (constraint: number, value: string) => {
119
+ value: string;
120
+ valid: boolean;
121
+ };
122
+ /**
123
+ * Implementation of pattern constraint
124
+ * @param constraint `pattern` property of the form object
125
+ * @param value value of the form object
126
+ * @return {@link ValidationResult | validation result}
127
+ */
128
+ pattern: (constraint: RegExp | string, value: string) => {
129
+ valid: boolean;
130
+ value: string;
131
+ };
132
+ /**
133
+ * Implementation of required constraint
134
+ * @param constraint `required` property of the form object
135
+ * @param value value of the form object
136
+ * @return {@link ValidationResult | validation result}
137
+ */
138
+ required: (constraint: boolean, value: any) => {
139
+ valid: boolean;
140
+ value: any;
141
+ };
142
+ /**
143
+ * Implementation of enum constraint
144
+ * @param constraint `enum` property of the form object
145
+ * @param value value of the form object
146
+ * @return {@link ValidationResult | validation result}
147
+ */
148
+ enum: (constraint: any[], value: any) => {
149
+ valid: boolean;
150
+ value: any;
151
+ };
152
+ };
153
+ export {};
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2022 Adobe, Inc.
4
+ *
5
+ * Your access and use of this software is governed by the Adobe Customer Feedback Program Terms and Conditions or other Beta License Agreement signed by your employer and Adobe, Inc.. This software is NOT open source and may not be used without one of the foregoing licenses. Even with a foregoing license, your access and use of this file is limited to the earlier of (a) 180 days, (b) general availability of the product(s) which utilize this software (i.e. AEM Forms), (c) January 1, 2023, (d) Adobe providing notice to you that you may no longer use the software or that your beta trial has otherwise ended.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ADOBE NOR ITS THIRD PARTY PROVIDERS AND PARTNERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.Constraints = exports.ValidConstraints = exports.isDataUrl = void 0;
11
+ /**
12
+ * Defines generic utilities to validate form runtime model based on the constraints defined
13
+ * as per `adaptive form specification`
14
+ */
15
+ // issue with import
16
+ //import {FieldJson, isFileObject} from '../types';
17
+ const dateRegex = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
18
+ const dataUrlRegex = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base64,(.*)$/;
19
+ const days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
20
+ const daysInMonth = (leapYear, month) => {
21
+ if (leapYear && month == 2) {
22
+ return 29;
23
+ }
24
+ return days[month - 1];
25
+ };
26
+ const isLeapYear = (year) => {
27
+ return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;
28
+ };
29
+ const isDataUrl = (str) => {
30
+ return dataUrlRegex.exec(str.trim()) != null;
31
+ };
32
+ exports.isDataUrl = isDataUrl;
33
+ /**
34
+ * Checks whether inputVal is valid number value or not
35
+ *
36
+ * ```
37
+ * const x = checkNumber('12')
38
+ * ```
39
+ * would return
40
+ * ```
41
+ * {
42
+ * value : 12,
43
+ * valid : true
44
+ * }
45
+ * ```
46
+ * @param inputVal input value
47
+ * @returns {@link ValidationResult | Validation result}
48
+ */
49
+ const checkNumber = (inputVal) => {
50
+ let value = parseFloat(inputVal);
51
+ const valid = !isNaN(value);
52
+ if (!valid) {
53
+ value = inputVal;
54
+ }
55
+ return {
56
+ value, valid
57
+ };
58
+ };
59
+ /**
60
+ * Wraps a non-null value and not an array value into an array
61
+ * @param inputVal input value
62
+ * @returns wraps the input value into an array
63
+ */
64
+ const toArray = (inputVal) => {
65
+ if (inputVal != null && !(inputVal instanceof Array)) {
66
+ return [inputVal];
67
+ }
68
+ return inputVal;
69
+ };
70
+ /**
71
+ * Checks whether inputVal is valid boolean value or not
72
+ *
73
+ * ```
74
+ * const x = checkBool('false')
75
+ * ```
76
+ * would return
77
+ * ```
78
+ * {
79
+ * value : false,
80
+ * valid : true
81
+ * }
82
+ * ```
83
+ * @param inputVal input value
84
+ * @returns {@link ValidationResult | Validation result}
85
+ */
86
+ const checkBool = (inputVal) => {
87
+ const valid = typeof inputVal === 'boolean' || inputVal === 'true' || inputVal === 'false';
88
+ const value = typeof inputVal === 'boolean' ? inputVal : (valid ? inputVal === 'true' : inputVal);
89
+ return { valid, value };
90
+ };
91
+ /**
92
+ * Validates an array of values using a validator function.
93
+ * @param inputVal
94
+ * @param validatorFn
95
+ * @return an array containing two arrays, the first one with all the valid values and the second one with one invalid
96
+ * value (if there is).
97
+ */
98
+ const partitionArray = (inputVal, validatorFn) => {
99
+ const value = toArray(inputVal);
100
+ if (value == null) {
101
+ return [[], [value]];
102
+ }
103
+ return value.reduce((acc, x) => {
104
+ if (acc[1].length == 0) {
105
+ const r = validatorFn(x);
106
+ const index = r.valid ? 0 : 1;
107
+ acc[index].push(r.value);
108
+ }
109
+ return acc;
110
+ }, [[], []]);
111
+ };
112
+ exports.ValidConstraints = {
113
+ date: ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'format'],
114
+ string: ['minLength', 'maxLength', 'pattern'],
115
+ number: ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum'],
116
+ array: ['minItems', 'maxItems', 'uniqueItems'],
117
+ file: ['accept', 'maxFileSize']
118
+ };
119
+ /**
120
+ * Implementation of all constraints defined by `adaptive form specification`
121
+ */
122
+ exports.Constraints = {
123
+ /**
124
+ * Implementation of type constraint
125
+ * @param constraint `type` property of the form object
126
+ * @param inputVal value of the form object
127
+ * @return {@link ValidationResult | validation result}
128
+ */
129
+ type: (constraint, inputVal) => {
130
+ let value = inputVal;
131
+ if (inputVal == undefined) {
132
+ return {
133
+ valid: true,
134
+ value: inputVal
135
+ };
136
+ }
137
+ let valid = true, res;
138
+ switch (constraint) {
139
+ case 'string':
140
+ valid = true;
141
+ value = inputVal.toString();
142
+ break;
143
+ case 'string[]':
144
+ value = toArray(inputVal);
145
+ break;
146
+ case 'number':
147
+ res = checkNumber(inputVal);
148
+ value = res.value;
149
+ valid = res.valid;
150
+ break;
151
+ case 'boolean':
152
+ res = checkBool(inputVal);
153
+ valid = res.valid;
154
+ value = res.value;
155
+ break;
156
+ case 'integer':
157
+ value = parseFloat(inputVal);
158
+ valid = !isNaN(value) && Math.round(value) === value;
159
+ if (!valid) {
160
+ value = inputVal;
161
+ }
162
+ break;
163
+ case 'file' || 'file[]':
164
+ valid = true;
165
+ //valid = isFileObject(value);
166
+ if (!valid) {
167
+ value = inputVal;
168
+ }
169
+ break;
170
+ case 'number[]':
171
+ res = partitionArray(inputVal, checkNumber);
172
+ valid = res[1].length === 0;
173
+ value = valid ? res[0] : inputVal;
174
+ break;
175
+ case 'boolean[]':
176
+ res = partitionArray(inputVal, checkBool);
177
+ valid = res[1].length === 0;
178
+ value = valid ? res[0] : inputVal;
179
+ break;
180
+ }
181
+ return {
182
+ valid,
183
+ value
184
+ };
185
+ },
186
+ /**
187
+ * Implementation of format constraint
188
+ * @param constraint `format` property of the form object
189
+ * @param input value of the form object
190
+ * @return {@link ValidationResult | validation result}
191
+ */
192
+ format: (constraint, input) => {
193
+ let valid = true;
194
+ const value = input;
195
+ let res;
196
+ switch (constraint) {
197
+ case 'date':
198
+ res = dateRegex.exec(input.trim());
199
+ if (res != null) {
200
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
201
+ const [match, year, month, date] = res;
202
+ const [nMonth, nDate] = [+month, +date];
203
+ const leapYear = isLeapYear(+year);
204
+ valid = (nMonth >= 1 && nMonth <= 12) &&
205
+ (nDate >= 1 && nDate <= daysInMonth(leapYear, nMonth));
206
+ }
207
+ else {
208
+ valid = false;
209
+ }
210
+ break;
211
+ case 'data-url':
212
+ // todo: input is of type file, do we need this format ? since value is always of type file object
213
+ //res = dataUrlRegex.exec(input.trim());
214
+ //valid = res != null;
215
+ valid = true;
216
+ break;
217
+ }
218
+ return { valid, value };
219
+ },
220
+ //todo : add support for date
221
+ /**
222
+ * Implementation of minimum constraint
223
+ * @param constraint `minimum` property of the form object
224
+ * @param value value of the form object
225
+ * @return {@link ValidationResult | validation result}
226
+ */
227
+ minimum: (constraint, value) => {
228
+ return { valid: value >= constraint, value };
229
+ },
230
+ //todo : add support for date
231
+ /**
232
+ * Implementation of maximum constraint
233
+ * @param constraint `maximum` property of the form object
234
+ * @param value value of the form object
235
+ * @return {@link ValidationResult | validation result}
236
+ */
237
+ maximum: (constraint, value) => {
238
+ return { valid: value <= constraint, value };
239
+ },
240
+ /**
241
+ * Implementation of exclusiveMinimum constraint
242
+ * @param constraint `minimum` property of the form object
243
+ * @param value value of the form object
244
+ * @return {@link ValidationResult | validation result}
245
+ */
246
+ exclusiveMinimum: (constraint, value) => {
247
+ return { valid: value > constraint, value };
248
+ },
249
+ //todo : add support for date
250
+ /**
251
+ * Implementation of exclusiveMaximum constraint
252
+ * @param constraint `maximum` property of the form object
253
+ * @param value value of the form object
254
+ * @return {@link ValidationResult | validation result}
255
+ */
256
+ exclusiveMaximum: (constraint, value) => {
257
+ return { valid: value < constraint, value };
258
+ },
259
+ /**
260
+ * Implementation of the minItems constraint
261
+ * @param constraint `minItems` constraint from object
262
+ * @param value value of the form object
263
+ */
264
+ minItems: (constraint, value) => {
265
+ return { valid: (value instanceof Array) && value.length >= constraint, value };
266
+ },
267
+ /**
268
+ * Implementation of the maxItems constraint
269
+ * @param constraint `maxItems` constraint from object
270
+ * @param value value of the form object
271
+ */
272
+ maxItems: (constraint, value) => {
273
+ return { valid: (value instanceof Array) && value.length <= constraint, value };
274
+ },
275
+ /**
276
+ * Implementation of the uniqueItems constraint
277
+ * @param constraint `uniqueItems` constraint from object
278
+ * @param value value of the form object
279
+ */
280
+ uniqueItems: (constraint, value) => {
281
+ return { valid: !constraint || ((value instanceof Array) && value.length === new Set(value).size), value };
282
+ },
283
+ /**
284
+ * Implementation of minLength constraint
285
+ * @param constraint `minLength` property of the form object
286
+ * @param value value of the form object
287
+ * @return {@link ValidationResult | validation result}
288
+ */
289
+ minLength: (constraint, value) => {
290
+ return Object.assign(Object.assign({}, exports.Constraints.minimum(constraint, typeof value === 'string' ? value.length : 0)), { value });
291
+ },
292
+ /**
293
+ * Implementation of maxLength constraint
294
+ * @param constraint `maxLength` property of the form object
295
+ * @param value value of the form object
296
+ * @return {@link ValidationResult | validation result}
297
+ */
298
+ maxLength: (constraint, value) => {
299
+ return Object.assign(Object.assign({}, exports.Constraints.maximum(constraint, typeof value === 'string' ? value.length : 0)), { value });
300
+ },
301
+ /**
302
+ * Implementation of pattern constraint
303
+ * @param constraint `pattern` property of the form object
304
+ * @param value value of the form object
305
+ * @return {@link ValidationResult | validation result}
306
+ */
307
+ pattern: (constraint, value) => {
308
+ let regex;
309
+ if (typeof constraint === 'string') {
310
+ regex = new RegExp(constraint);
311
+ }
312
+ else {
313
+ regex = constraint;
314
+ }
315
+ return { valid: regex.test(value), value };
316
+ },
317
+ /**
318
+ * Implementation of required constraint
319
+ * @param constraint `required` property of the form object
320
+ * @param value value of the form object
321
+ * @return {@link ValidationResult | validation result}
322
+ */
323
+ required: (constraint, value) => {
324
+ const valid = constraint ? value != null && value !== '' : true;
325
+ return { valid, value };
326
+ },
327
+ /**
328
+ * Implementation of enum constraint
329
+ * @param constraint `enum` property of the form object
330
+ * @param value value of the form object
331
+ * @return {@link ValidationResult | validation result}
332
+ */
333
+ enum: (constraint, value) => {
334
+ return {
335
+ valid: constraint.indexOf(value) > -1,
336
+ value
337
+ };
338
+ }
339
+ };