@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
|
@@ -0,0 +1,116 @@
|
|
|
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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
+
if (mod && mod.__esModule) return mod;
|
|
27
|
+
var result = {};
|
|
28
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
+
__setModuleDefault(result, mod);
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.fetchForm = exports.validateFormInstance = exports.createFormInstance = void 0;
|
|
37
|
+
const Form_1 = __importStar(require("./Form"));
|
|
38
|
+
const JsonUtils_1 = require("./utils/JsonUtils");
|
|
39
|
+
const Fetch_1 = require("./utils/Fetch");
|
|
40
|
+
const RuleEngine_1 = __importDefault(require("./rules/RuleEngine"));
|
|
41
|
+
const EventQueue_1 = __importDefault(require("./controller/EventQueue"));
|
|
42
|
+
/**
|
|
43
|
+
* Creates form instance using form model definition as per `adaptive form specification`
|
|
44
|
+
* @param formModel form model definition
|
|
45
|
+
* @param callback a callback that recieves the FormModel instance that gets executed before any event in the Form
|
|
46
|
+
* is executed
|
|
47
|
+
* @param logLevel Logging Level for the form. Setting it off will disable the logging
|
|
48
|
+
* @param fModel existing form model, this is additional optimization to prevent creation of form instance
|
|
49
|
+
* @returns {@link FormModel | form model}
|
|
50
|
+
*/
|
|
51
|
+
const createFormInstance = (formModel, callback, logLevel = 'error', fModel = undefined) => {
|
|
52
|
+
try {
|
|
53
|
+
let f = fModel;
|
|
54
|
+
if (f == null) {
|
|
55
|
+
f = new Form_1.default(Object.assign({}, formModel), new RuleEngine_1.default(), new EventQueue_1.default(new Form_1.Logger(logLevel)), logLevel);
|
|
56
|
+
}
|
|
57
|
+
const formData = formModel === null || formModel === void 0 ? void 0 : formModel.data;
|
|
58
|
+
if (formData) {
|
|
59
|
+
f.importData(formData);
|
|
60
|
+
}
|
|
61
|
+
if (typeof callback === 'function') {
|
|
62
|
+
callback(f);
|
|
63
|
+
}
|
|
64
|
+
// Once the field or panel is initialized, execute the initialization script
|
|
65
|
+
// this means initialization happens after prefill and restore
|
|
66
|
+
// Before execution of calcExp, visibleExp, enabledExp, validate, options, navigationChange, we execute init script
|
|
67
|
+
//f.queueEvent(new Initialize(undefined, true));
|
|
68
|
+
//f.queueEvent(new ExecuteRule(undefined, true));
|
|
69
|
+
f.getEventQueue().runPendingQueue();
|
|
70
|
+
return f;
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error(`Unable to create an instance of the Form ${e}`);
|
|
74
|
+
throw new Error(e);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
exports.createFormInstance = createFormInstance;
|
|
78
|
+
/**
|
|
79
|
+
* Validates Form model definition with the given data
|
|
80
|
+
* @param formModel form model definition
|
|
81
|
+
* @param data form data
|
|
82
|
+
* @returns `true`, if form is valid against the given form data, `false` otherwise
|
|
83
|
+
*/
|
|
84
|
+
const validateFormInstance = (formModel, data) => {
|
|
85
|
+
try {
|
|
86
|
+
const f = new Form_1.default(Object.assign({}, formModel), new RuleEngine_1.default());
|
|
87
|
+
if (data) {
|
|
88
|
+
f.importData(data);
|
|
89
|
+
}
|
|
90
|
+
return f.validate().length === 0;
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
throw new Error(e);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
exports.validateFormInstance = validateFormInstance;
|
|
97
|
+
/**
|
|
98
|
+
* Helper API to fetch form model definition from an AEM instance
|
|
99
|
+
* @param url URL of the instance
|
|
100
|
+
* @param headers HTTP headers to pass to the aem instance
|
|
101
|
+
* @returns promise which resolves to the form model definition
|
|
102
|
+
*/
|
|
103
|
+
const fetchForm = (url, headers = {}) => {
|
|
104
|
+
const headerObj = new Headers();
|
|
105
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
106
|
+
headerObj.append(key, value);
|
|
107
|
+
});
|
|
108
|
+
return (0, Fetch_1.request)(`${url}.model.json`, null, { headers }).then((formObj) => {
|
|
109
|
+
if ('model' in formObj) {
|
|
110
|
+
const { model } = formObj;
|
|
111
|
+
formObj = model;
|
|
112
|
+
}
|
|
113
|
+
return (0, JsonUtils_1.jsonString)(formObj);
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
exports.fetchForm = fetchForm;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FormMetaDataModel, MetaDataJson } from './types';
|
|
2
|
+
import Node from './Node';
|
|
3
|
+
/**
|
|
4
|
+
* Defines form metadata which implements {@link FormMetaDataModel | Form MetaData Model}
|
|
5
|
+
*/
|
|
6
|
+
declare class FormMetaData extends Node<MetaDataJson> implements FormMetaDataModel {
|
|
7
|
+
get version(): string;
|
|
8
|
+
get locale(): string;
|
|
9
|
+
get grammar(): string;
|
|
10
|
+
}
|
|
11
|
+
export default FormMetaData;
|
|
@@ -0,0 +1,28 @@
|
|
|
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 Node_1 = __importDefault(require("./Node"));
|
|
14
|
+
/**
|
|
15
|
+
* Defines form metadata which implements {@link FormMetaDataModel | Form MetaData Model}
|
|
16
|
+
*/
|
|
17
|
+
class FormMetaData extends Node_1.default {
|
|
18
|
+
get version() {
|
|
19
|
+
return this.getP('version', '');
|
|
20
|
+
}
|
|
21
|
+
get locale() {
|
|
22
|
+
return this.getP('locale', '');
|
|
23
|
+
}
|
|
24
|
+
get grammar() {
|
|
25
|
+
return this.getP('grammar', '');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.default = FormMetaData;
|
package/lib/Node.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines generic form object class which any form runtime model (like textbox, checkbox etc)
|
|
3
|
+
* should extend from.
|
|
4
|
+
* @typeparam T type of the node (for example, {@link MetaDataJson | form meta data}
|
|
5
|
+
*/
|
|
6
|
+
declare class Node<T> {
|
|
7
|
+
protected _jsonModel: T;
|
|
8
|
+
constructor(inputModel: T);
|
|
9
|
+
protected getP<S>(key: string, def: S): S;
|
|
10
|
+
get isContainer(): boolean;
|
|
11
|
+
}
|
|
12
|
+
export default Node;
|
package/lib/Node.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
const JsonUtils_1 = require("./utils/JsonUtils");
|
|
11
|
+
/**
|
|
12
|
+
* Defines generic form object class which any form runtime model (like textbox, checkbox etc)
|
|
13
|
+
* should extend from.
|
|
14
|
+
* @typeparam T type of the node (for example, {@link MetaDataJson | form meta data}
|
|
15
|
+
*/
|
|
16
|
+
class Node {
|
|
17
|
+
constructor(inputModel) {
|
|
18
|
+
this._jsonModel = Object.assign({}, inputModel);
|
|
19
|
+
}
|
|
20
|
+
getP(key, def) {
|
|
21
|
+
return (0, JsonUtils_1.getProperty)(this._jsonModel, key, def);
|
|
22
|
+
}
|
|
23
|
+
get isContainer() {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = Node;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Action, RulesJson, ScriptableField } from './types';
|
|
2
|
+
import { BaseNode } from './BaseNode';
|
|
3
|
+
declare abstract class Scriptable<T extends RulesJson> extends BaseNode<T> implements ScriptableField {
|
|
4
|
+
private _events;
|
|
5
|
+
private _rules;
|
|
6
|
+
get rules(): import("./types").Items<string>;
|
|
7
|
+
private getCompiledRule;
|
|
8
|
+
private getCompiledEvent;
|
|
9
|
+
private applyUpdates;
|
|
10
|
+
protected executeAllRules(context: any): void;
|
|
11
|
+
private getExpressionScope;
|
|
12
|
+
private executeEvent;
|
|
13
|
+
/**
|
|
14
|
+
* Executes the given rule
|
|
15
|
+
* @param event
|
|
16
|
+
* @param context
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
executeRule(event: Action, context: any): void;
|
|
20
|
+
executeExpression(expr: string): any;
|
|
21
|
+
/**
|
|
22
|
+
* Executes the given action
|
|
23
|
+
* @param action {@link Action | event object}
|
|
24
|
+
*/
|
|
25
|
+
executeAction(action: Action): void;
|
|
26
|
+
}
|
|
27
|
+
export default Scriptable;
|
|
@@ -0,0 +1,216 @@
|
|
|
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
|
+
const BaseNode_1 = require("./BaseNode");
|
|
11
|
+
/**
|
|
12
|
+
* Defines scriptable aspects (ie rules, events) of form runtime model. Any form runtime object which requires
|
|
13
|
+
* execution of rules/events should extend from this class.
|
|
14
|
+
*/
|
|
15
|
+
const dynamicProps = ['label',
|
|
16
|
+
'enum',
|
|
17
|
+
'enumNames',
|
|
18
|
+
'enforceEnum',
|
|
19
|
+
'exclusiveMinimum',
|
|
20
|
+
'exclusiveMaximum',
|
|
21
|
+
'maxLength',
|
|
22
|
+
'maximum',
|
|
23
|
+
'maxItems',
|
|
24
|
+
'minLength',
|
|
25
|
+
'minimum',
|
|
26
|
+
'minItems',
|
|
27
|
+
'required',
|
|
28
|
+
'step',
|
|
29
|
+
'description',
|
|
30
|
+
'properties',
|
|
31
|
+
'readOnly',
|
|
32
|
+
'value',
|
|
33
|
+
'visible',
|
|
34
|
+
'enabled',
|
|
35
|
+
'placeholder'];
|
|
36
|
+
class Scriptable extends BaseNode_1.BaseNode {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this._events = {};
|
|
40
|
+
this._rules = {};
|
|
41
|
+
}
|
|
42
|
+
get rules() {
|
|
43
|
+
return this._jsonModel.rules || {};
|
|
44
|
+
}
|
|
45
|
+
getCompiledRule(eName, rule) {
|
|
46
|
+
if (!(eName in this._rules)) {
|
|
47
|
+
const eString = rule || this.rules[eName];
|
|
48
|
+
if (typeof eString === 'string' && eString.length > 0) {
|
|
49
|
+
try {
|
|
50
|
+
this._rules[eName] = this.ruleEngine.compileRule(eString);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
this.form.logger.error(`Unable to compile rule \`"${eName}" : "${eString}"\` Exception : ${e}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error(`only expression strings are supported. ${typeof (eString)} types are not supported`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return this._rules[eName];
|
|
61
|
+
}
|
|
62
|
+
getCompiledEvent(eName) {
|
|
63
|
+
var _a;
|
|
64
|
+
if (!(eName in this._events)) {
|
|
65
|
+
let eString = (_a = this._jsonModel.events) === null || _a === void 0 ? void 0 : _a[eName];
|
|
66
|
+
if (typeof eString === 'string' && eString.length > 0) {
|
|
67
|
+
eString = [eString];
|
|
68
|
+
}
|
|
69
|
+
if (typeof eString !== 'undefined' && eString.length > 0) {
|
|
70
|
+
this._events[eName] = eString.map(x => {
|
|
71
|
+
try {
|
|
72
|
+
return this.ruleEngine.compileRule(x);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
this.form.logger.error(`Unable to compile expression \`"${eName}" : "${eString}"\` Exception : ${e}`);
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}).filter(x => x !== null);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return this._events[eName] || [];
|
|
82
|
+
}
|
|
83
|
+
applyUpdates(updates) {
|
|
84
|
+
Object.entries(updates).forEach(([key, value]) => {
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
// the first check is to disable accessing this.value & this.items property
|
|
87
|
+
// otherwise that will trigger dependency tracking
|
|
88
|
+
if (key in dynamicProps || (key in this && typeof this[key] !== 'function')) {
|
|
89
|
+
try {
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
this[key] = value;
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
console.error(e);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
executeAllRules(context) {
|
|
100
|
+
const entries = Object.entries(this.rules);
|
|
101
|
+
if (entries.length > 0) {
|
|
102
|
+
const scope = this.getExpressionScope();
|
|
103
|
+
const values = entries.map(([prop, rule]) => {
|
|
104
|
+
const node = this.getCompiledRule(prop, rule);
|
|
105
|
+
let newVal;
|
|
106
|
+
if (node) {
|
|
107
|
+
newVal = this.ruleEngine.execute(node, scope, context, true);
|
|
108
|
+
if (dynamicProps.indexOf(prop) > -1) {
|
|
109
|
+
//@ts-ignore
|
|
110
|
+
this[prop] = newVal;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
114
|
+
}).filter(x => x.length == 2);
|
|
115
|
+
this.applyUpdates(Object.fromEntries(values));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
getExpressionScope() {
|
|
119
|
+
var _a;
|
|
120
|
+
const target = {
|
|
121
|
+
self: this.getRuleNode(),
|
|
122
|
+
siblings: ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.ruleNodeReference()) || {}
|
|
123
|
+
};
|
|
124
|
+
const scope = new Proxy(target, {
|
|
125
|
+
get: (target, prop) => {
|
|
126
|
+
if (prop === Symbol.toStringTag) {
|
|
127
|
+
return 'Object';
|
|
128
|
+
}
|
|
129
|
+
prop = prop;
|
|
130
|
+
// The order of resolution is
|
|
131
|
+
// 1. property
|
|
132
|
+
// 2. sibling
|
|
133
|
+
// 3. child
|
|
134
|
+
if (prop.startsWith('$')) {
|
|
135
|
+
//this returns children as well, so adding an explicit check for property name
|
|
136
|
+
return target.self[prop];
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (prop in target.siblings) {
|
|
140
|
+
return target.siblings[prop];
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
return target.self[prop];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
has: (target, prop) => {
|
|
148
|
+
prop = prop;
|
|
149
|
+
const selfPropertyOrChild = target.self[prop];
|
|
150
|
+
const sibling = target.siblings[prop];
|
|
151
|
+
return typeof selfPropertyOrChild != 'undefined' || typeof sibling != 'undefined';
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return scope;
|
|
155
|
+
}
|
|
156
|
+
executeEvent(context, node) {
|
|
157
|
+
let updates;
|
|
158
|
+
if (node) {
|
|
159
|
+
updates = this.ruleEngine.execute(node, this.getExpressionScope(), context);
|
|
160
|
+
}
|
|
161
|
+
if (typeof updates !== 'undefined') {
|
|
162
|
+
this.applyUpdates(updates);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Executes the given rule
|
|
167
|
+
* @param event
|
|
168
|
+
* @param context
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
executeRule(event, context) {
|
|
172
|
+
if (typeof event.payload.ruleName === 'undefined') {
|
|
173
|
+
this.executeAllRules(context);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
executeExpression(expr) {
|
|
177
|
+
const ruleContext = {
|
|
178
|
+
'form': this.form,
|
|
179
|
+
'$form': this.form.getRuleNode(),
|
|
180
|
+
'$field': this.getRuleNode(),
|
|
181
|
+
'field': this
|
|
182
|
+
};
|
|
183
|
+
const node = this.ruleEngine.compileRule(expr);
|
|
184
|
+
return this.ruleEngine.execute(node, this.getExpressionScope(), ruleContext);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Executes the given action
|
|
188
|
+
* @param action {@link Action | event object}
|
|
189
|
+
*/
|
|
190
|
+
executeAction(action) {
|
|
191
|
+
const context = {
|
|
192
|
+
'form': this.form,
|
|
193
|
+
'$form': this.form.getRuleNode(),
|
|
194
|
+
'$field': this.getRuleNode(),
|
|
195
|
+
'field': this,
|
|
196
|
+
'$event': {
|
|
197
|
+
type: action.type,
|
|
198
|
+
payload: action.payload,
|
|
199
|
+
target: this.getRuleNode()
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const eventName = action.isCustomEvent ? `custom:${action.type}` : action.type;
|
|
203
|
+
const funcName = action.isCustomEvent ? `custom_${action.type}` : action.type;
|
|
204
|
+
const node = this.getCompiledEvent(eventName);
|
|
205
|
+
//todo: apply all the updates at the end or
|
|
206
|
+
// not trigger the change event until the execution is finished
|
|
207
|
+
node.forEach((n) => this.executeEvent(context, n));
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
if (funcName in this && typeof this[funcName] === 'function') {
|
|
210
|
+
//@ts-ignore
|
|
211
|
+
this[funcName](action, context);
|
|
212
|
+
}
|
|
213
|
+
this.notifyDependents(action);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.default = Scriptable;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines all form events
|
|
3
|
+
*/
|
|
4
|
+
import { Action, BaseJson, FieldModel, FieldsetModel, FormModel, ValidationError } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Implementation of generic event
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
export declare class ActionImpl implements Action {
|
|
10
|
+
private _metadata?;
|
|
11
|
+
protected _type: string;
|
|
12
|
+
private _payload?;
|
|
13
|
+
private _target;
|
|
14
|
+
constructor(payload: any, type: string, _metadata?: any);
|
|
15
|
+
get type(): string;
|
|
16
|
+
get payload(): any;
|
|
17
|
+
get metadata(): any;
|
|
18
|
+
get target(): FormModel | FieldModel | FieldsetModel;
|
|
19
|
+
get isCustomEvent(): boolean;
|
|
20
|
+
protected payloadToJson(): any;
|
|
21
|
+
toJson(): {
|
|
22
|
+
payload: any;
|
|
23
|
+
type: string;
|
|
24
|
+
isCustomEvent: boolean;
|
|
25
|
+
};
|
|
26
|
+
toString(): string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Payload of change event
|
|
30
|
+
*/
|
|
31
|
+
export declare type ChangePayload = {
|
|
32
|
+
/**
|
|
33
|
+
* List of changes
|
|
34
|
+
*/
|
|
35
|
+
changes: Array<{
|
|
36
|
+
/**
|
|
37
|
+
* Name of the property which has changed
|
|
38
|
+
*/
|
|
39
|
+
propertyName: string;
|
|
40
|
+
/**
|
|
41
|
+
* Previous value of the property changed
|
|
42
|
+
*/
|
|
43
|
+
prevValue?: any;
|
|
44
|
+
/**
|
|
45
|
+
* Current value of the property changed
|
|
46
|
+
*/
|
|
47
|
+
currentValue: any;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Implementation of `change` event. The change event is triggered on the field whenever the value of the field is changed
|
|
52
|
+
*/
|
|
53
|
+
export declare class Change extends ActionImpl {
|
|
54
|
+
/**
|
|
55
|
+
* @constructor
|
|
56
|
+
* @param [payload] event payload
|
|
57
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
58
|
+
*/
|
|
59
|
+
constructor(payload: ChangePayload, dispatch?: boolean);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Implementation of `invalid` event. The invalid event is triggered when a Field’s value becomes invalid after a change event or whenever its value property change
|
|
63
|
+
*/
|
|
64
|
+
export declare class Invalid extends ActionImpl {
|
|
65
|
+
/**
|
|
66
|
+
* @constructor
|
|
67
|
+
* @param [payload] event payload
|
|
68
|
+
*/
|
|
69
|
+
constructor(payload?: any);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Implementation of `valid` event. The valid event is triggered whenever the field’s valid state is changed from invalid to valid.
|
|
73
|
+
*/
|
|
74
|
+
export declare class Valid extends ActionImpl {
|
|
75
|
+
/**
|
|
76
|
+
* @constructor
|
|
77
|
+
* @param [payload] event payload
|
|
78
|
+
*/
|
|
79
|
+
constructor(payload?: any);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Implementation of an ExecuteRule event.
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
export declare class ExecuteRule extends ActionImpl {
|
|
86
|
+
/**
|
|
87
|
+
* @constructor
|
|
88
|
+
* @param [payload] event payload
|
|
89
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
90
|
+
*/
|
|
91
|
+
constructor(payload?: any, dispatch?: boolean);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a change event
|
|
95
|
+
* @param propertyName name of the form field property
|
|
96
|
+
* @param currentValue current value
|
|
97
|
+
* @param prevValue previous value
|
|
98
|
+
* @returns {@link Change} change event
|
|
99
|
+
*/
|
|
100
|
+
export declare const propertyChange: (propertyName: string, currentValue: any, prevValue?: any) => Change;
|
|
101
|
+
/**
|
|
102
|
+
* Implementation of `initialize` event. The event is triggered on all the fields when the form initialisation is complete
|
|
103
|
+
*/
|
|
104
|
+
export declare class Initialize extends ActionImpl {
|
|
105
|
+
/**
|
|
106
|
+
* @constructor
|
|
107
|
+
* @param [payload] event payload
|
|
108
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
109
|
+
*/
|
|
110
|
+
constructor(payload?: any, dispatch?: boolean);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Implementation of `click` event. The event is triggered when user clicks on an element.
|
|
114
|
+
*/
|
|
115
|
+
export declare class Click extends ActionImpl {
|
|
116
|
+
/**
|
|
117
|
+
* @constructor
|
|
118
|
+
* @param [payload] event payload
|
|
119
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
120
|
+
*/
|
|
121
|
+
constructor(payload?: any, dispatch?: boolean);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Implementation of `blur` event. The event is triggered when the element loses focus.
|
|
125
|
+
*/
|
|
126
|
+
export declare class Blur extends ActionImpl {
|
|
127
|
+
/**
|
|
128
|
+
* @constructor
|
|
129
|
+
* @param [payload] event payload
|
|
130
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
131
|
+
*/
|
|
132
|
+
constructor(payload?: any, dispatch?: boolean);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Implementation of `ValidationComplete` event. The ValidationComplete event is triggered once validation is completed
|
|
136
|
+
* on the form.
|
|
137
|
+
*
|
|
138
|
+
* An example of using this event,
|
|
139
|
+
* ```
|
|
140
|
+
* function onValidationComplete(event) {
|
|
141
|
+
* const x = event.payload[0].id;
|
|
142
|
+
* // do something with the invalid field
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare class ValidationComplete extends ActionImpl {
|
|
147
|
+
/**
|
|
148
|
+
* @constructor
|
|
149
|
+
* @param [payload] event payload (ie) list of {@link ValidationError | validation errors}
|
|
150
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
151
|
+
*/
|
|
152
|
+
constructor(payload?: Array<ValidationError>, dispatch?: boolean);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Implementation of `submit` event. The submit event is triggered on the Form.
|
|
156
|
+
* To trigger the submit event, submit function needs to be invoked or one can invoke dispatchEvent API.
|
|
157
|
+
*/
|
|
158
|
+
export declare class Submit extends ActionImpl {
|
|
159
|
+
/**
|
|
160
|
+
* @constructor
|
|
161
|
+
* @param [payload] event payload
|
|
162
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
163
|
+
*/
|
|
164
|
+
constructor(payload?: any, dispatch?: boolean);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Implementation of `fieldChanged` event. The field changed event is triggered on the field which it has changed.
|
|
168
|
+
*/
|
|
169
|
+
export declare class FieldChanged extends ActionImpl {
|
|
170
|
+
constructor(changes: ChangePayload, field: BaseJson);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Implementation of `custom event`.
|
|
174
|
+
*/
|
|
175
|
+
export declare class CustomEvent extends ActionImpl {
|
|
176
|
+
/**
|
|
177
|
+
* @constructor
|
|
178
|
+
* @param [eventName] name of the event
|
|
179
|
+
* @param [payload] event payload
|
|
180
|
+
* @param [dispatch] true to trigger the event on all the fields in DFS order starting from the top level form element, false otherwise
|
|
181
|
+
*/
|
|
182
|
+
constructor(eventName: string, payload?: any, dispatch?: boolean);
|
|
183
|
+
/**
|
|
184
|
+
* Defines if the event is custom
|
|
185
|
+
*/
|
|
186
|
+
get isCustomEvent(): boolean;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Implementation of `addItem` event. The event is triggered on a panel to add a new instance of items inside it.
|
|
190
|
+
*/
|
|
191
|
+
export declare class AddItem extends ActionImpl {
|
|
192
|
+
/**
|
|
193
|
+
* @constructor
|
|
194
|
+
* @param [payload] event payload
|
|
195
|
+
*/
|
|
196
|
+
constructor(payload?: number);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Implementation of `removeItem` event. The event is triggered on a panel to remove an instance of items inside it.
|
|
200
|
+
*/
|
|
201
|
+
export declare class RemoveItem extends ActionImpl {
|
|
202
|
+
/**
|
|
203
|
+
* @constructor
|
|
204
|
+
* @param [payload] event payload
|
|
205
|
+
*/
|
|
206
|
+
constructor(payload?: number);
|
|
207
|
+
}
|