@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.
- package/LICENSE +5 -0
- package/README.md +34 -0
- package/lib/BaseNode.d.ts +117 -0
- package/lib/BaseNode.js +368 -0
- package/lib/Checkbox.d.ts +80 -0
- package/lib/Checkbox.js +49 -0
- package/lib/CheckboxGroup.d.ts +30 -0
- package/lib/CheckboxGroup.js +40 -0
- package/lib/Container.d.ts +336 -0
- package/lib/Container.js +279 -0
- package/lib/Field.d.ts +185 -0
- package/lib/Field.js +432 -0
- package/lib/Fieldset.d.ts +31 -0
- package/lib/Fieldset.js +97 -0
- package/lib/FileObject.d.ts +17 -0
- package/lib/FileObject.js +30 -0
- package/lib/FileUpload.d.ts +42 -0
- package/lib/FileUpload.js +299 -0
- package/lib/Form.d.ts +413 -0
- package/lib/Form.js +247 -0
- package/lib/FormInstance.d.ts +26 -0
- package/lib/FormInstance.js +116 -0
- package/lib/FormMetaData.d.ts +11 -0
- package/lib/FormMetaData.js +28 -0
- package/lib/Node.d.ts +12 -0
- package/lib/Node.js +27 -0
- package/lib/Scriptable.d.ts +27 -0
- package/lib/Scriptable.js +216 -0
- package/lib/controller/Controller.d.ts +207 -0
- package/lib/controller/Controller.js +263 -0
- package/lib/controller/EventQueue.d.ts +24 -0
- package/lib/controller/EventQueue.js +99 -0
- package/lib/controller/index.d.ts +1 -0
- package/lib/controller/index.js +24 -0
- package/lib/data/DataGroup.d.ts +25 -0
- package/lib/data/DataGroup.js +74 -0
- package/lib/data/DataValue.d.ts +22 -0
- package/lib/data/DataValue.js +50 -0
- package/lib/data/EmptyDataValue.d.ts +14 -0
- package/lib/data/EmptyDataValue.js +46 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +59 -0
- package/lib/rules/FunctionRuntime.d.ts +44 -0
- package/lib/rules/FunctionRuntime.js +271 -0
- package/lib/rules/RuleEngine.d.ts +23 -0
- package/lib/rules/RuleEngine.js +67 -0
- package/lib/types/Json.d.ts +126 -0
- package/lib/types/Json.js +16 -0
- package/lib/types/Model.d.ts +352 -0
- package/lib/types/Model.js +20 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.js +25 -0
- package/lib/utils/DataRefParser.d.ts +30 -0
- package/lib/utils/DataRefParser.js +249 -0
- package/lib/utils/Fetch.d.ts +7 -0
- package/lib/utils/Fetch.js +29 -0
- package/lib/utils/FormUtils.d.ts +47 -0
- package/lib/utils/FormUtils.js +172 -0
- package/lib/utils/JsonUtils.d.ts +55 -0
- package/lib/utils/JsonUtils.js +128 -0
- package/lib/utils/LogUtils.d.ts +7 -0
- package/lib/utils/LogUtils.js +17 -0
- package/lib/utils/SchemaUtils.d.ts +16 -0
- package/lib/utils/SchemaUtils.js +92 -0
- package/lib/utils/TranslationUtils.d.ts +34 -0
- package/lib/utils/TranslationUtils.js +156 -0
- package/lib/utils/ValidationUtils.d.ts +153 -0
- package/lib/utils/ValidationUtils.js +339 -0
- package/package.json +60 -0
package/lib/Field.d.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { ConstraintsMessages, ContainerModel, FieldJson, FieldModel, FormModel, ValidationError } from './types';
|
|
2
|
+
import Scriptable from './Scriptable';
|
|
3
|
+
import DataValue from './data/DataValue';
|
|
4
|
+
import DataGroup from './data/DataGroup';
|
|
5
|
+
/**
|
|
6
|
+
* Defines a form object field which implements {@link FieldModel | field model} interface
|
|
7
|
+
*/
|
|
8
|
+
declare class Field extends Scriptable<FieldJson> implements FieldModel {
|
|
9
|
+
/**
|
|
10
|
+
* @param params
|
|
11
|
+
* @param _options
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
constructor(params: FieldJson, _options: {
|
|
15
|
+
form: FormModel;
|
|
16
|
+
parent: ContainerModel;
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
_initialize(): any;
|
|
22
|
+
protected _getDefaults(): {
|
|
23
|
+
readOnly: boolean;
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
visible: boolean;
|
|
26
|
+
type: string | undefined;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Returns the fallback type to be used for this field, in case type is not defined. Otherwise returns
|
|
30
|
+
* undefined
|
|
31
|
+
* @protected
|
|
32
|
+
*/
|
|
33
|
+
protected _getFallbackType(): string | undefined;
|
|
34
|
+
protected _applyDefaults(): void;
|
|
35
|
+
get readOnly(): boolean | undefined;
|
|
36
|
+
set readOnly(e: boolean | undefined);
|
|
37
|
+
get enabled(): boolean | undefined;
|
|
38
|
+
set enabled(e: boolean | undefined);
|
|
39
|
+
get valid(): boolean | undefined;
|
|
40
|
+
get emptyValue(): "" | null | undefined;
|
|
41
|
+
get enum(): any[] | undefined;
|
|
42
|
+
set enum(e: any[] | undefined);
|
|
43
|
+
get enumNames(): string[] | undefined;
|
|
44
|
+
set enumNames(e: string[] | undefined);
|
|
45
|
+
get required(): boolean;
|
|
46
|
+
set required(r: boolean);
|
|
47
|
+
get maximum(): number | undefined;
|
|
48
|
+
set maximum(m: number | undefined);
|
|
49
|
+
get minimum(): number | undefined;
|
|
50
|
+
set minimum(m: number | undefined);
|
|
51
|
+
/**
|
|
52
|
+
* returns whether the value is empty. Empty value is either a '', undefined or null
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
private isEmpty;
|
|
56
|
+
get value(): any;
|
|
57
|
+
set value(v: any);
|
|
58
|
+
valueOf(): any;
|
|
59
|
+
toString(): any;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the error message for a given constraint
|
|
62
|
+
* @param constraint
|
|
63
|
+
*/
|
|
64
|
+
getErrorMessage(constraint: keyof (ConstraintsMessages)): string;
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
_getConstraintObject(): {
|
|
70
|
+
type: (constraint: string, inputVal: any) => {
|
|
71
|
+
valid: boolean;
|
|
72
|
+
value: any;
|
|
73
|
+
};
|
|
74
|
+
format: (constraint: string, input: string) => {
|
|
75
|
+
valid: boolean;
|
|
76
|
+
value: string;
|
|
77
|
+
};
|
|
78
|
+
minimum: (constraint: number, value: number) => {
|
|
79
|
+
valid: boolean;
|
|
80
|
+
value: number;
|
|
81
|
+
};
|
|
82
|
+
maximum: (constraint: number, value: number) => {
|
|
83
|
+
valid: boolean;
|
|
84
|
+
value: number;
|
|
85
|
+
};
|
|
86
|
+
exclusiveMinimum: (constraint: number, value: number) => {
|
|
87
|
+
valid: boolean;
|
|
88
|
+
value: number;
|
|
89
|
+
};
|
|
90
|
+
exclusiveMaximum: (constraint: number, value: number) => {
|
|
91
|
+
valid: boolean;
|
|
92
|
+
value: number;
|
|
93
|
+
};
|
|
94
|
+
minItems: <T>(constraint: number, value: T[]) => {
|
|
95
|
+
valid: boolean;
|
|
96
|
+
value: T[];
|
|
97
|
+
};
|
|
98
|
+
maxItems: <T_1>(constraint: number, value: T_1[]) => {
|
|
99
|
+
valid: boolean;
|
|
100
|
+
value: T_1[];
|
|
101
|
+
};
|
|
102
|
+
uniqueItems: <T_2>(constraint: boolean, value: T_2[]) => {
|
|
103
|
+
valid: boolean;
|
|
104
|
+
value: T_2[];
|
|
105
|
+
};
|
|
106
|
+
minLength: (constraint: number, value: string) => {
|
|
107
|
+
value: string;
|
|
108
|
+
valid: boolean;
|
|
109
|
+
};
|
|
110
|
+
maxLength: (constraint: number, value: string) => {
|
|
111
|
+
value: string;
|
|
112
|
+
valid: boolean;
|
|
113
|
+
};
|
|
114
|
+
pattern: (constraint: string | RegExp, value: string) => {
|
|
115
|
+
valid: boolean;
|
|
116
|
+
value: string;
|
|
117
|
+
};
|
|
118
|
+
required: (constraint: boolean, value: any) => {
|
|
119
|
+
valid: boolean;
|
|
120
|
+
value: any;
|
|
121
|
+
};
|
|
122
|
+
enum: (constraint: any[], value: any) => {
|
|
123
|
+
valid: boolean;
|
|
124
|
+
value: any;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* returns whether the field is array type or not
|
|
129
|
+
* @private
|
|
130
|
+
*/
|
|
131
|
+
private isArrayType;
|
|
132
|
+
/**
|
|
133
|
+
*
|
|
134
|
+
* @param value
|
|
135
|
+
* @param constraints
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
private checkEnum;
|
|
139
|
+
/**
|
|
140
|
+
* checks whether the value can be achieved by stepping the min/default value by the step constraint.
|
|
141
|
+
* Basically to find a integer solution for n in the equation
|
|
142
|
+
* initialValue + n * step = value
|
|
143
|
+
* @param constraints
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
private checkStep;
|
|
147
|
+
/**
|
|
148
|
+
* checks whether the validation expression returns a boolean value or not
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
private checkValidationExpression;
|
|
152
|
+
/**
|
|
153
|
+
* Returns the applicable constraints for a given type
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
private getConstraints;
|
|
157
|
+
/**
|
|
158
|
+
* returns the format constraint
|
|
159
|
+
*/
|
|
160
|
+
get format(): string;
|
|
161
|
+
/**
|
|
162
|
+
* @private
|
|
163
|
+
*/
|
|
164
|
+
protected evaluateConstraints(): any;
|
|
165
|
+
triggerValidationEvent(changes: any): void;
|
|
166
|
+
/**
|
|
167
|
+
* Checks whether there are any updates in the properties. If there are applies them to the
|
|
168
|
+
* json model as well.
|
|
169
|
+
* @param propNames
|
|
170
|
+
* @param updates
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
protected _applyUpdates(propNames: string[], updates: any): any;
|
|
174
|
+
/**
|
|
175
|
+
* Validates the current form object
|
|
176
|
+
*/
|
|
177
|
+
validate(): ValidationError[];
|
|
178
|
+
importData(contextualDataModel: DataGroup): void;
|
|
179
|
+
/**
|
|
180
|
+
* @param name
|
|
181
|
+
* @private
|
|
182
|
+
*/
|
|
183
|
+
defaultDataModel(name: string | number): DataValue;
|
|
184
|
+
}
|
|
185
|
+
export default Field;
|
package/lib/Field.js
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const types_1 = require("./types");
|
|
14
|
+
const ValidationUtils_1 = require("./utils/ValidationUtils");
|
|
15
|
+
const controller_1 = require("./controller");
|
|
16
|
+
const Scriptable_1 = __importDefault(require("./Scriptable"));
|
|
17
|
+
const SchemaUtils_1 = require("./utils/SchemaUtils");
|
|
18
|
+
const DataValue_1 = __importDefault(require("./data/DataValue"));
|
|
19
|
+
const BaseNode_1 = require("./BaseNode");
|
|
20
|
+
const EmptyDataValue_1 = __importDefault(require("./data/EmptyDataValue"));
|
|
21
|
+
/**
|
|
22
|
+
* Defines a form object field which implements {@link FieldModel | field model} interface
|
|
23
|
+
*/
|
|
24
|
+
class Field extends Scriptable_1.default {
|
|
25
|
+
/**
|
|
26
|
+
* @param params
|
|
27
|
+
* @param _options
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
constructor(params, _options) {
|
|
31
|
+
super(params, _options);
|
|
32
|
+
this._applyDefaults();
|
|
33
|
+
this.queueEvent(new controller_1.Initialize());
|
|
34
|
+
this.queueEvent(new controller_1.ExecuteRule());
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
_initialize() {
|
|
40
|
+
super._initialize();
|
|
41
|
+
this.setupRuleNode();
|
|
42
|
+
}
|
|
43
|
+
_getDefaults() {
|
|
44
|
+
return {
|
|
45
|
+
readOnly: false,
|
|
46
|
+
enabled: true,
|
|
47
|
+
visible: true,
|
|
48
|
+
type: this._getFallbackType()
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the fallback type to be used for this field, in case type is not defined. Otherwise returns
|
|
53
|
+
* undefined
|
|
54
|
+
* @protected
|
|
55
|
+
*/
|
|
56
|
+
_getFallbackType() {
|
|
57
|
+
const type = this._jsonModel.type;
|
|
58
|
+
if (typeof type !== 'string') {
|
|
59
|
+
const _enum = this.enum;
|
|
60
|
+
return _enum && _enum.length > 0 ? typeof _enum[0] : 'string';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
_applyDefaults() {
|
|
64
|
+
Object.entries(this._getDefaults()).map(([key, value]) => {
|
|
65
|
+
//@ts-ignore
|
|
66
|
+
if (this._jsonModel[key] === undefined && value !== undefined) {
|
|
67
|
+
//@ts-ignore
|
|
68
|
+
this._jsonModel[key] = value;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const value = this._jsonModel.value;
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
this._jsonModel.value = this._jsonModel.default;
|
|
74
|
+
}
|
|
75
|
+
if (this._jsonModel.fieldType === undefined) {
|
|
76
|
+
//@ts-ignore
|
|
77
|
+
if (this._jsonModel.viewType) {
|
|
78
|
+
//@ts-ignore
|
|
79
|
+
if (this._jsonModel.viewType.startsWith('custom:')) {
|
|
80
|
+
this.form.logger.error('viewType property has been removed. For custom types, use :type property');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.form.logger.error('viewType property has been removed. Use fieldType property');
|
|
84
|
+
}
|
|
85
|
+
//@ts-ignore
|
|
86
|
+
this._jsonModel.fieldType = this._jsonModel.viewType;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this._jsonModel.fieldType = (0, SchemaUtils_1.defaultFieldTypes)(this._jsonModel);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (this._jsonModel.enum === undefined) {
|
|
93
|
+
const type = this._jsonModel.type;
|
|
94
|
+
if (type === 'boolean') {
|
|
95
|
+
this._jsonModel.enum = [true, false];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (typeof this._jsonModel.step !== 'number' || this._jsonModel.type !== 'number') {
|
|
99
|
+
this._jsonModel.step = undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
get readOnly() {
|
|
103
|
+
return this._jsonModel.readOnly;
|
|
104
|
+
}
|
|
105
|
+
set readOnly(e) {
|
|
106
|
+
this._setProperty('readOnly', e);
|
|
107
|
+
}
|
|
108
|
+
get enabled() {
|
|
109
|
+
return this._jsonModel.enabled;
|
|
110
|
+
}
|
|
111
|
+
set enabled(e) {
|
|
112
|
+
this._setProperty('enabled', e);
|
|
113
|
+
}
|
|
114
|
+
get valid() {
|
|
115
|
+
return this._jsonModel.valid;
|
|
116
|
+
}
|
|
117
|
+
get emptyValue() {
|
|
118
|
+
if (this._jsonModel.emptyValue === 'null') {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
else if (this._jsonModel.emptyValue === '' && this.type === 'string') {
|
|
122
|
+
return '';
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
get enum() {
|
|
129
|
+
return this._jsonModel.enum;
|
|
130
|
+
}
|
|
131
|
+
set enum(e) {
|
|
132
|
+
this._setProperty('enum', e);
|
|
133
|
+
}
|
|
134
|
+
get enumNames() {
|
|
135
|
+
return this._jsonModel.enumNames;
|
|
136
|
+
}
|
|
137
|
+
set enumNames(e) {
|
|
138
|
+
this._setProperty('enumNames', e);
|
|
139
|
+
}
|
|
140
|
+
get required() {
|
|
141
|
+
return this._jsonModel.required || false;
|
|
142
|
+
}
|
|
143
|
+
set required(r) {
|
|
144
|
+
this._setProperty('required', r);
|
|
145
|
+
}
|
|
146
|
+
get maximum() {
|
|
147
|
+
return this._jsonModel.maximum;
|
|
148
|
+
}
|
|
149
|
+
set maximum(m) {
|
|
150
|
+
this._setProperty('maximum', m);
|
|
151
|
+
}
|
|
152
|
+
get minimum() {
|
|
153
|
+
return this._jsonModel.minimum;
|
|
154
|
+
}
|
|
155
|
+
set minimum(m) {
|
|
156
|
+
this._setProperty('minimum', m);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* returns whether the value is empty. Empty value is either a '', undefined or null
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
isEmpty() {
|
|
163
|
+
return this._jsonModel.value === undefined || this._jsonModel.value === null || this._jsonModel.value === '';
|
|
164
|
+
}
|
|
165
|
+
get value() {
|
|
166
|
+
//@ts-ignore
|
|
167
|
+
this.ruleEngine.trackDependency(this);
|
|
168
|
+
if (this._jsonModel.value === undefined) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return this._jsonModel.value;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
set value(v) {
|
|
176
|
+
const Constraints = this._getConstraintObject();
|
|
177
|
+
const typeRes = Constraints.type(this._jsonModel.type || 'string', v);
|
|
178
|
+
const changes = this._setProperty('value', typeRes.value, false);
|
|
179
|
+
if (changes.length > 0) {
|
|
180
|
+
const dataNode = this.getDataNode();
|
|
181
|
+
if (typeof dataNode !== 'undefined') {
|
|
182
|
+
dataNode.setValue(this.isEmpty() ? this.emptyValue : this._jsonModel.value, this._jsonModel.value);
|
|
183
|
+
}
|
|
184
|
+
let updates;
|
|
185
|
+
if (typeRes.valid) {
|
|
186
|
+
updates = this.evaluateConstraints();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const changes = {
|
|
190
|
+
'valid': typeRes.valid,
|
|
191
|
+
'errorMessage': typeRes.valid ? '' : this.getErrorMessage('type')
|
|
192
|
+
};
|
|
193
|
+
updates = this._applyUpdates(['valid', 'errorMessage'], changes);
|
|
194
|
+
}
|
|
195
|
+
if (updates.valid) {
|
|
196
|
+
this.triggerValidationEvent(updates);
|
|
197
|
+
}
|
|
198
|
+
const changeAction = new controller_1.Change({ changes: changes.concat(Object.values(updates)) });
|
|
199
|
+
this.dispatch(changeAction);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
valueOf() {
|
|
203
|
+
// @ts-ignore
|
|
204
|
+
const obj = this[BaseNode_1.target];
|
|
205
|
+
const actualField = obj === undefined ? this : obj;
|
|
206
|
+
actualField.ruleEngine.trackDependency(actualField);
|
|
207
|
+
return actualField._jsonModel.value || null;
|
|
208
|
+
}
|
|
209
|
+
toString() {
|
|
210
|
+
var _a;
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
const obj = this[BaseNode_1.target];
|
|
213
|
+
const actualField = obj === undefined ? this : obj;
|
|
214
|
+
return ((_a = actualField._jsonModel.value) === null || _a === void 0 ? void 0 : _a.toString()) || '';
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Returns the error message for a given constraint
|
|
218
|
+
* @param constraint
|
|
219
|
+
*/
|
|
220
|
+
getErrorMessage(constraint) {
|
|
221
|
+
var _a;
|
|
222
|
+
return ((_a = this._jsonModel.constraintMessages) === null || _a === void 0 ? void 0 : _a[constraint]) || '';
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
* @private
|
|
227
|
+
*/
|
|
228
|
+
_getConstraintObject() {
|
|
229
|
+
return ValidationUtils_1.Constraints;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* returns whether the field is array type or not
|
|
233
|
+
* @private
|
|
234
|
+
*/
|
|
235
|
+
isArrayType() {
|
|
236
|
+
return this.type ? this.type.indexOf('[]') > -1 : false;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
*
|
|
240
|
+
* @param value
|
|
241
|
+
* @param constraints
|
|
242
|
+
* @private
|
|
243
|
+
*/
|
|
244
|
+
checkEnum(value, constraints) {
|
|
245
|
+
if (this._jsonModel.enforceEnum === true && value != null) {
|
|
246
|
+
const fn = constraints.enum;
|
|
247
|
+
if (value instanceof Array && this.isArrayType()) {
|
|
248
|
+
return value.every(x => fn(this.enum || [], x).valid);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
return fn(this.enum || [], value).valid;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* checks whether the value can be achieved by stepping the min/default value by the step constraint.
|
|
258
|
+
* Basically to find a integer solution for n in the equation
|
|
259
|
+
* initialValue + n * step = value
|
|
260
|
+
* @param constraints
|
|
261
|
+
* @private
|
|
262
|
+
*/
|
|
263
|
+
checkStep() {
|
|
264
|
+
const value = this._jsonModel.value;
|
|
265
|
+
if (typeof this._jsonModel.step === 'number') {
|
|
266
|
+
const initialValue = this._jsonModel.minimum || this._jsonModel.default || 0;
|
|
267
|
+
return (value - initialValue) % this._jsonModel.step === 0;
|
|
268
|
+
}
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* checks whether the validation expression returns a boolean value or not
|
|
273
|
+
* @private
|
|
274
|
+
*/
|
|
275
|
+
checkValidationExpression() {
|
|
276
|
+
if (typeof this._jsonModel.validationExpression === 'string') {
|
|
277
|
+
return this.executeExpression(this._jsonModel.validationExpression);
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Returns the applicable constraints for a given type
|
|
283
|
+
* @private
|
|
284
|
+
*/
|
|
285
|
+
getConstraints() {
|
|
286
|
+
switch (this.type) {
|
|
287
|
+
case 'string':
|
|
288
|
+
switch (this.format) {
|
|
289
|
+
case 'date':
|
|
290
|
+
return ValidationUtils_1.ValidConstraints.date;
|
|
291
|
+
case 'binary':
|
|
292
|
+
return ValidationUtils_1.ValidConstraints.file;
|
|
293
|
+
case 'data-url':
|
|
294
|
+
return ValidationUtils_1.ValidConstraints.file;
|
|
295
|
+
default:
|
|
296
|
+
return ValidationUtils_1.ValidConstraints.string;
|
|
297
|
+
}
|
|
298
|
+
case 'number':
|
|
299
|
+
return ValidationUtils_1.ValidConstraints.number;
|
|
300
|
+
}
|
|
301
|
+
if (this.isArrayType()) {
|
|
302
|
+
return ValidationUtils_1.ValidConstraints.array;
|
|
303
|
+
}
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* returns the format constraint
|
|
308
|
+
*/
|
|
309
|
+
get format() {
|
|
310
|
+
return this._jsonModel.format || '';
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* @private
|
|
314
|
+
*/
|
|
315
|
+
evaluateConstraints() {
|
|
316
|
+
let constraint = 'type';
|
|
317
|
+
const elem = this._jsonModel;
|
|
318
|
+
const value = this._jsonModel.value;
|
|
319
|
+
const Constraints = this._getConstraintObject();
|
|
320
|
+
const supportedConstraints = this.getConstraints();
|
|
321
|
+
let valid = true;
|
|
322
|
+
if (valid) {
|
|
323
|
+
valid = Constraints.required(this.required, value).valid &&
|
|
324
|
+
(this.isArrayType() && this.required ? value.length > 0 : true);
|
|
325
|
+
constraint = 'required';
|
|
326
|
+
}
|
|
327
|
+
if (valid) {
|
|
328
|
+
const invalidConstraint = supportedConstraints.find(key => {
|
|
329
|
+
if (key in elem) {
|
|
330
|
+
// @ts-ignore
|
|
331
|
+
const restriction = elem[key];
|
|
332
|
+
// @ts-ignore
|
|
333
|
+
const fn = Constraints[key];
|
|
334
|
+
if (value instanceof Array && this.isArrayType()) {
|
|
335
|
+
return value.some(x => !(fn(restriction, x).valid));
|
|
336
|
+
}
|
|
337
|
+
else if (typeof fn === 'function') {
|
|
338
|
+
return !fn(restriction, value).valid;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
if (invalidConstraint != null) {
|
|
349
|
+
valid = false;
|
|
350
|
+
constraint = invalidConstraint;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
valid = this.checkEnum(value, Constraints);
|
|
354
|
+
constraint = 'enum';
|
|
355
|
+
if (valid && this.type === 'number') {
|
|
356
|
+
valid = this.checkStep();
|
|
357
|
+
constraint = 'step';
|
|
358
|
+
}
|
|
359
|
+
if (valid) {
|
|
360
|
+
valid = this.checkValidationExpression();
|
|
361
|
+
constraint = 'validationExpression';
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (!valid) {
|
|
366
|
+
//@ts-ignore
|
|
367
|
+
this.form.logger.log(`${constraint} constraint evaluation failed ${this[constraint]}. Received ${this._jsonModel.value}`);
|
|
368
|
+
}
|
|
369
|
+
const changes = {
|
|
370
|
+
'valid': valid,
|
|
371
|
+
'errorMessage': valid ? '' : this.getErrorMessage(constraint)
|
|
372
|
+
};
|
|
373
|
+
return this._applyUpdates(['valid', 'errorMessage'], changes);
|
|
374
|
+
}
|
|
375
|
+
triggerValidationEvent(changes) {
|
|
376
|
+
if (changes.valid) {
|
|
377
|
+
if (this.valid) {
|
|
378
|
+
this.dispatch(new controller_1.Valid());
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
this.dispatch(new controller_1.Invalid());
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Checks whether there are any updates in the properties. If there are applies them to the
|
|
387
|
+
* json model as well.
|
|
388
|
+
* @param propNames
|
|
389
|
+
* @param updates
|
|
390
|
+
* @private
|
|
391
|
+
*/
|
|
392
|
+
_applyUpdates(propNames, updates) {
|
|
393
|
+
return propNames.reduce((acc, propertyName) => {
|
|
394
|
+
//@ts-ignore
|
|
395
|
+
const currentValue = updates[propertyName];
|
|
396
|
+
const changes = this._setProperty(propertyName, currentValue, false);
|
|
397
|
+
if (changes.length > 0) {
|
|
398
|
+
acc[propertyName] = changes[0];
|
|
399
|
+
}
|
|
400
|
+
return acc;
|
|
401
|
+
}, {});
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Validates the current form object
|
|
405
|
+
*/
|
|
406
|
+
validate() {
|
|
407
|
+
const changes = this.evaluateConstraints();
|
|
408
|
+
if (changes.valid) {
|
|
409
|
+
this.triggerValidationEvent(changes);
|
|
410
|
+
this.notifyDependents(new controller_1.Change({ changes: Object.values(changes) }));
|
|
411
|
+
}
|
|
412
|
+
return this.valid ? [new types_1.ValidationError()] : [new types_1.ValidationError(this.id, [this._jsonModel.errorMessage])];
|
|
413
|
+
}
|
|
414
|
+
importData(contextualDataModel) {
|
|
415
|
+
this._bindToDataModel(contextualDataModel);
|
|
416
|
+
const dataNode = this.getDataNode();
|
|
417
|
+
// only if the value has changed, queue change event
|
|
418
|
+
if (dataNode !== undefined && dataNode !== EmptyDataValue_1.default && dataNode.$value !== this._jsonModel.value) {
|
|
419
|
+
const changeAction = (0, controller_1.propertyChange)('value', dataNode.$value, this._jsonModel.value);
|
|
420
|
+
this._jsonModel.value = dataNode.$value;
|
|
421
|
+
this.queueEvent(changeAction);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* @param name
|
|
426
|
+
* @private
|
|
427
|
+
*/
|
|
428
|
+
defaultDataModel(name) {
|
|
429
|
+
return new DataValue_1.default(name, this.isEmpty() ? this.emptyValue : this._jsonModel.value, this.type || 'string');
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
exports.default = Field;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Container from './Container';
|
|
2
|
+
import { ContainerModel, FieldJson, FieldModel, FieldsetJson, FieldsetModel, FormModel } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a child model inside the given parent
|
|
5
|
+
* @param child
|
|
6
|
+
* @param options
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
export declare const createChild: (child: FieldsetJson | FieldJson, options: {
|
|
10
|
+
form: FormModel;
|
|
11
|
+
parent: ContainerModel;
|
|
12
|
+
}) => FieldModel | FieldsetModel;
|
|
13
|
+
/**
|
|
14
|
+
* Defines a field set class which extends from {@link Container | container}
|
|
15
|
+
*/
|
|
16
|
+
export declare class Fieldset extends Container<FieldsetJson> implements FieldsetModel {
|
|
17
|
+
/**
|
|
18
|
+
* @param params
|
|
19
|
+
* @param _options
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
constructor(params: FieldsetJson, _options: {
|
|
23
|
+
form: FormModel;
|
|
24
|
+
parent: ContainerModel;
|
|
25
|
+
});
|
|
26
|
+
private _applyDefaults;
|
|
27
|
+
get type(): "array" | "object" | undefined;
|
|
28
|
+
protected _createChild(child: FieldsetJson | FieldJson, options: any): FieldModel | FieldsetModel;
|
|
29
|
+
get items(): (FieldModel | FieldsetModel)[];
|
|
30
|
+
get value(): null;
|
|
31
|
+
}
|