@aemforms/af-core 0.22.25 → 0.22.26
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/lib/browser/afb-events.js +151 -0
- package/lib/browser/afb-runtime.js +3620 -0
- package/lib/cjs/index.cjs +8886 -0
- package/lib/esm/BaseNode.d.ts +93 -0
- package/lib/esm/BaseNode.js +454 -0
- package/lib/esm/Checkbox.d.ts +79 -0
- package/lib/esm/Checkbox.js +27 -0
- package/lib/esm/CheckboxGroup.d.ts +18 -0
- package/lib/esm/CheckboxGroup.js +23 -0
- package/lib/esm/Container.d.ts +53 -0
- package/lib/esm/Container.js +290 -0
- package/lib/esm/DateField.d.ts +5 -0
- package/lib/esm/DateField.js +21 -0
- package/lib/esm/Field.d.ts +206 -0
- package/lib/esm/Field.js +656 -0
- package/lib/esm/Fieldset.d.ts +16 -0
- package/lib/esm/Fieldset.js +45 -0
- package/lib/esm/FileObject.d.ts +16 -0
- package/lib/esm/FileObject.js +26 -0
- package/lib/esm/FileUpload.d.ts +22 -0
- package/lib/esm/FileUpload.js +108 -0
- package/lib/esm/Form.d.ts +113 -0
- package/lib/esm/Form.js +176 -0
- package/lib/esm/FormInstance.d.ts +13 -0
- package/lib/esm/FormInstance.js +81 -0
- package/lib/esm/FormMetaData.d.ts +7 -0
- package/lib/esm/FormMetaData.js +10 -0
- package/lib/esm/InstanceManager.d.ts +9 -0
- package/lib/esm/InstanceManager.js +31 -0
- package/lib/esm/Node.d.ts +7 -0
- package/lib/esm/Node.js +16 -0
- package/lib/esm/Scriptable.d.ts +17 -0
- package/lib/esm/Scriptable.js +163 -0
- package/lib/esm/controller/EventQueue.d.ts +17 -0
- package/lib/esm/controller/EventQueue.js +86 -0
- package/lib/esm/controller/Events.d.ts +85 -0
- package/lib/esm/controller/Events.js +149 -0
- package/lib/esm/controller/Logger.d.ts +11 -0
- package/lib/esm/controller/Logger.js +30 -0
- package/lib/esm/data/DataGroup.d.ts +20 -0
- package/lib/esm/data/DataGroup.js +77 -0
- package/lib/esm/data/DataValue.d.ts +16 -0
- package/lib/esm/data/DataValue.js +46 -0
- package/lib/esm/data/EmptyDataValue.d.ts +14 -0
- package/lib/esm/data/EmptyDataValue.js +29 -0
- package/lib/esm/index.d.ts +21 -0
- package/lib/esm/index.js +21 -0
- package/lib/esm/rules/FunctionRuntime.d.ts +51 -0
- package/lib/esm/rules/FunctionRuntime.js +320 -0
- package/lib/esm/rules/RuleEngine.d.ts +12 -0
- package/lib/esm/rules/RuleEngine.js +47 -0
- package/lib/esm/types/Json.d.ts +119 -0
- package/lib/esm/types/Json.js +7 -0
- package/lib/esm/types/Model.d.ts +131 -0
- package/lib/esm/types/Model.js +8 -0
- package/lib/esm/types/index.d.ts +2 -0
- package/lib/esm/types/index.js +2 -0
- package/lib/esm/utils/DataRefParser.d.ts +27 -0
- package/lib/esm/utils/DataRefParser.js +222 -0
- package/lib/esm/utils/Fetch.d.ts +8 -0
- package/lib/esm/utils/Fetch.js +61 -0
- package/lib/esm/utils/FormCreationUtils.d.ts +9 -0
- package/lib/esm/utils/FormCreationUtils.js +74 -0
- package/lib/esm/utils/FormUtils.d.ts +12 -0
- package/lib/esm/utils/FormUtils.js +187 -0
- package/lib/esm/utils/JsonUtils.d.ts +11 -0
- package/lib/esm/utils/JsonUtils.js +76 -0
- package/lib/esm/utils/LogUtils.d.ts +4 -0
- package/lib/esm/utils/LogUtils.js +6 -0
- package/lib/esm/utils/SchemaUtils.d.ts +3 -0
- package/lib/esm/utils/SchemaUtils.js +71 -0
- package/lib/esm/utils/TranslationUtils.d.ts +11 -0
- package/lib/esm/utils/TranslationUtils.js +115 -0
- package/lib/esm/utils/ValidationUtils.d.ts +19 -0
- package/lib/esm/utils/ValidationUtils.js +274 -0
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export default class DataValue {
|
|
2
|
+
$_name;
|
|
3
|
+
$_value;
|
|
4
|
+
$_type;
|
|
5
|
+
$_fields = [];
|
|
6
|
+
constructor($_name, $_value, $_type = typeof $_value) {
|
|
7
|
+
this.$_name = $_name;
|
|
8
|
+
this.$_value = $_value;
|
|
9
|
+
this.$_type = $_type;
|
|
10
|
+
}
|
|
11
|
+
valueOf() {
|
|
12
|
+
return this.$_value;
|
|
13
|
+
}
|
|
14
|
+
get $name() {
|
|
15
|
+
return this.$_name;
|
|
16
|
+
}
|
|
17
|
+
get $value() {
|
|
18
|
+
const enabled = this.$_fields.find(x => x.enabled !== false);
|
|
19
|
+
if (!enabled && this.$_fields.length) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
return this.$_value;
|
|
23
|
+
}
|
|
24
|
+
setValue(typedValue, originalValue, fromField) {
|
|
25
|
+
this.$_value = typedValue;
|
|
26
|
+
this.$_fields.forEach(x => {
|
|
27
|
+
if (fromField !== x) {
|
|
28
|
+
x.value = originalValue;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
get $type() {
|
|
33
|
+
return this.$_type;
|
|
34
|
+
}
|
|
35
|
+
$bindToField(field) {
|
|
36
|
+
if (this.$_fields.indexOf(field) === -1) {
|
|
37
|
+
this.$_fields.push(field);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
$convertToDataValue() {
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
get $isDataGroup() {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import DataValue from './DataValue.js';
|
|
2
|
+
declare class NullDataValueClass extends DataValue {
|
|
3
|
+
constructor();
|
|
4
|
+
setValue(): void;
|
|
5
|
+
$bindToField(): void;
|
|
6
|
+
$length(): number;
|
|
7
|
+
$convertToDataValue(): DataValue;
|
|
8
|
+
$addDataNode(): void;
|
|
9
|
+
$removeDataNode(): void;
|
|
10
|
+
$getDataNode(): this;
|
|
11
|
+
$containsDataNode(): boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const NullDataValue: NullDataValueClass;
|
|
14
|
+
export default NullDataValue;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import DataValue from './DataValue.js';
|
|
2
|
+
const value = Symbol('NullValue');
|
|
3
|
+
class NullDataValueClass extends DataValue {
|
|
4
|
+
constructor() {
|
|
5
|
+
super('', value, 'null');
|
|
6
|
+
}
|
|
7
|
+
setValue() {
|
|
8
|
+
}
|
|
9
|
+
$bindToField() {
|
|
10
|
+
}
|
|
11
|
+
$length() {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
$convertToDataValue() {
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
$addDataNode() {
|
|
18
|
+
}
|
|
19
|
+
$removeDataNode() {
|
|
20
|
+
}
|
|
21
|
+
$getDataNode() {
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
$containsDataNode() {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const NullDataValue = new NullDataValueClass();
|
|
29
|
+
export default NullDataValue;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from './FormInstance.js';
|
|
2
|
+
export * from './types/index.js';
|
|
3
|
+
export * from './controller/Events.js';
|
|
4
|
+
export * from './utils/TranslationUtils.js';
|
|
5
|
+
export * from './utils/JsonUtils.js';
|
|
6
|
+
export * from './utils/SchemaUtils.js';
|
|
7
|
+
import { getFileSizeInBytes, extractFileInfo, isEmpty } from './utils/FormUtils.js';
|
|
8
|
+
import { BaseNode } from './BaseNode.js';
|
|
9
|
+
import Checkbox from './Checkbox.js';
|
|
10
|
+
import CheckboxGroup from './CheckboxGroup.js';
|
|
11
|
+
import Container from './Container.js';
|
|
12
|
+
import Field from './Field.js';
|
|
13
|
+
import { Fieldset } from './Fieldset.js';
|
|
14
|
+
import { FileObject } from './FileObject.js';
|
|
15
|
+
import FileUpload from './FileUpload.js';
|
|
16
|
+
import FormMetaData from './FormMetaData.js';
|
|
17
|
+
import Node from './Node.js';
|
|
18
|
+
import Scriptable from './Scriptable.js';
|
|
19
|
+
import Form from './Form.js';
|
|
20
|
+
import { FunctionRuntime, request } from './rules/FunctionRuntime.js';
|
|
21
|
+
export { Form, BaseNode, Checkbox, CheckboxGroup, Container, Field, Fieldset, FileObject, FileUpload, FormMetaData, Node, Scriptable, getFileSizeInBytes, extractFileInfo, FunctionRuntime, request, isEmpty };
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from './FormInstance.js';
|
|
2
|
+
export * from './types/index.js';
|
|
3
|
+
export * from './controller/Events.js';
|
|
4
|
+
export * from './utils/TranslationUtils.js';
|
|
5
|
+
export * from './utils/JsonUtils.js';
|
|
6
|
+
export * from './utils/SchemaUtils.js';
|
|
7
|
+
import { getFileSizeInBytes, extractFileInfo, isEmpty } from './utils/FormUtils.js';
|
|
8
|
+
import { BaseNode } from './BaseNode.js';
|
|
9
|
+
import Checkbox from './Checkbox.js';
|
|
10
|
+
import CheckboxGroup from './CheckboxGroup.js';
|
|
11
|
+
import Container from './Container.js';
|
|
12
|
+
import Field from './Field.js';
|
|
13
|
+
import { Fieldset } from './Fieldset.js';
|
|
14
|
+
import { FileObject } from './FileObject.js';
|
|
15
|
+
import FileUpload from './FileUpload.js';
|
|
16
|
+
import FormMetaData from './FormMetaData.js';
|
|
17
|
+
import Node from './Node.js';
|
|
18
|
+
import Scriptable from './Scriptable.js';
|
|
19
|
+
import Form from './Form.js';
|
|
20
|
+
import { FunctionRuntime, request } from './rules/FunctionRuntime.js';
|
|
21
|
+
export { Form, BaseNode, Checkbox, CheckboxGroup, Container, Field, Fieldset, FileObject, FileUpload, FormMetaData, Node, Scriptable, getFileSizeInBytes, extractFileInfo, FunctionRuntime, request, isEmpty };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
declare type HTTP_VERB = 'GET' | 'POST';
|
|
2
|
+
export declare const request: (context: any, uri: string, httpVerb: HTTP_VERB, payload: any, success: string, error: string, headers: any) => Promise<void>;
|
|
3
|
+
export declare const submit: (context: any, success: string, error: string, submitAs?: 'application/json' | 'multipart/form-data', input_data?: any) => Promise<void>;
|
|
4
|
+
export declare type CustomFunction = Function;
|
|
5
|
+
export declare type FunctionDefinition = {
|
|
6
|
+
_func: CustomFunction;
|
|
7
|
+
_signature: Array<any>;
|
|
8
|
+
};
|
|
9
|
+
declare class FunctionRuntimeImpl {
|
|
10
|
+
private customFunctions;
|
|
11
|
+
registerFunctions(functions: {
|
|
12
|
+
[key: string]: FunctionDefinition | CustomFunction;
|
|
13
|
+
}): void;
|
|
14
|
+
unregisterFunctions(...names: string[]): void;
|
|
15
|
+
getFunctions(): {
|
|
16
|
+
validate: {
|
|
17
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
|
|
18
|
+
_signature: never[];
|
|
19
|
+
};
|
|
20
|
+
setFocus: {
|
|
21
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => void;
|
|
22
|
+
_signature: never[];
|
|
23
|
+
};
|
|
24
|
+
getData: {
|
|
25
|
+
_func: (args: unknown, data: unknown, interpreter: any) => any;
|
|
26
|
+
_signature: never[];
|
|
27
|
+
};
|
|
28
|
+
exportData: {
|
|
29
|
+
_func: (args: unknown, data: unknown, interpreter: any) => any;
|
|
30
|
+
_signature: never[];
|
|
31
|
+
};
|
|
32
|
+
importData: {
|
|
33
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
|
|
34
|
+
_signature: never[];
|
|
35
|
+
};
|
|
36
|
+
submitForm: {
|
|
37
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
|
|
38
|
+
_signature: never[];
|
|
39
|
+
};
|
|
40
|
+
request: {
|
|
41
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
|
|
42
|
+
_signature: never[];
|
|
43
|
+
};
|
|
44
|
+
dispatchEvent: {
|
|
45
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => {};
|
|
46
|
+
_signature: never[];
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export declare const FunctionRuntime: FunctionRuntimeImpl;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { AddInstance, AddItem, Change, Click, CustomEvent, RemoveInstance, RemoveItem, Reset, Submit } from '../controller/Events.js';
|
|
2
|
+
import { request as fRequest } from '../utils/Fetch.js';
|
|
3
|
+
import { FileObject } from '../FileObject.js';
|
|
4
|
+
import { getAttachments } from '../utils/FormUtils.js';
|
|
5
|
+
import { jsonString } from '../utils/JsonUtils.js';
|
|
6
|
+
const getCustomEventName = (name) => {
|
|
7
|
+
const eName = name;
|
|
8
|
+
if (eName.length > 0 && eName.startsWith('custom:')) {
|
|
9
|
+
return eName.substring('custom:'.length);
|
|
10
|
+
}
|
|
11
|
+
return eName;
|
|
12
|
+
};
|
|
13
|
+
export const request = async (context, uri, httpVerb, payload, success, error, headers) => {
|
|
14
|
+
const endpoint = uri;
|
|
15
|
+
const requestOptions = {
|
|
16
|
+
method: httpVerb
|
|
17
|
+
};
|
|
18
|
+
let result;
|
|
19
|
+
let inputPayload;
|
|
20
|
+
try {
|
|
21
|
+
if (payload && payload instanceof FileObject && payload.data instanceof File) {
|
|
22
|
+
const formData = new FormData();
|
|
23
|
+
formData.append(payload.name, payload.data);
|
|
24
|
+
inputPayload = formData;
|
|
25
|
+
}
|
|
26
|
+
else if (payload instanceof FormData) {
|
|
27
|
+
inputPayload = payload;
|
|
28
|
+
}
|
|
29
|
+
else if (payload && typeof payload === 'object' && Object.keys(payload).length > 0) {
|
|
30
|
+
const headerNames = Object.keys(headers);
|
|
31
|
+
if (headerNames.length > 0) {
|
|
32
|
+
requestOptions.headers = {
|
|
33
|
+
...headers,
|
|
34
|
+
...(headerNames.indexOf('Content-Type') === -1 ? { 'Content-Type': 'application/json' } : {})
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
requestOptions.headers = { 'Content-Type': 'application/json' };
|
|
39
|
+
}
|
|
40
|
+
const contentType = requestOptions?.headers?.['Content-Type'] || 'application/json';
|
|
41
|
+
if (contentType === 'application/json') {
|
|
42
|
+
inputPayload = JSON.stringify(payload);
|
|
43
|
+
}
|
|
44
|
+
else if (contentType.indexOf('multipart/form-data') > -1) {
|
|
45
|
+
inputPayload = multipartFormData(payload);
|
|
46
|
+
}
|
|
47
|
+
else if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
|
|
48
|
+
inputPayload = urlEncoded(payload);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
result = await fRequest(endpoint, inputPayload, requestOptions);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
context.form.logger.error('Error invoking a rest API');
|
|
55
|
+
const eName = getCustomEventName(error);
|
|
56
|
+
context.form.dispatch(new CustomEvent(eName, {}, true));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const eName = getCustomEventName(success);
|
|
60
|
+
context.form.dispatch(new CustomEvent(eName, result, true));
|
|
61
|
+
};
|
|
62
|
+
const urlEncoded = (data) => {
|
|
63
|
+
const formData = new URLSearchParams();
|
|
64
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
65
|
+
if (value != null && typeof value === 'object') {
|
|
66
|
+
formData.append(key, jsonString(value));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
formData.append(key, value);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return formData;
|
|
73
|
+
};
|
|
74
|
+
const multipartFormData = (data, attachments) => {
|
|
75
|
+
const formData = new FormData();
|
|
76
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
77
|
+
if (value != null && typeof value === 'object') {
|
|
78
|
+
formData.append(key, jsonString(value));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
formData.append(key, value);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
const addAttachmentToFormData = (objValue, formData) => {
|
|
85
|
+
if (objValue?.data instanceof File) {
|
|
86
|
+
let attIdentifier = `${objValue?.dataRef}/${objValue?.name}`;
|
|
87
|
+
if (!attIdentifier.startsWith('/')) {
|
|
88
|
+
attIdentifier = `/${attIdentifier}`;
|
|
89
|
+
}
|
|
90
|
+
formData.append(attIdentifier, objValue.data);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
if (attachments) {
|
|
94
|
+
Object.keys(attachments).reduce((acc, curr) => {
|
|
95
|
+
const objValue = attachments[curr];
|
|
96
|
+
if (objValue && objValue instanceof Array) {
|
|
97
|
+
return [...acc, ...objValue.map((x) => addAttachmentToFormData(x, formData))];
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return [...acc, addAttachmentToFormData(objValue, formData)];
|
|
101
|
+
}
|
|
102
|
+
}, []);
|
|
103
|
+
}
|
|
104
|
+
return formData;
|
|
105
|
+
};
|
|
106
|
+
export const submit = async (context, success, error, submitAs = 'multipart/form-data', input_data = null) => {
|
|
107
|
+
const endpoint = context.form.action;
|
|
108
|
+
let data = input_data;
|
|
109
|
+
if (typeof data != 'object' || data == null) {
|
|
110
|
+
data = context.form.exportData();
|
|
111
|
+
}
|
|
112
|
+
const attachments = getAttachments(context.form);
|
|
113
|
+
let submitContentType = submitAs;
|
|
114
|
+
const submitDataAndMetaData = { 'data': data, 'submitMetadata': { 'lang': context.form.lang } };
|
|
115
|
+
let formData = submitDataAndMetaData;
|
|
116
|
+
if (Object.keys(attachments).length > 0 || submitAs === 'multipart/form-data') {
|
|
117
|
+
formData = multipartFormData(submitDataAndMetaData, attachments);
|
|
118
|
+
submitContentType = 'multipart/form-data';
|
|
119
|
+
}
|
|
120
|
+
await request(context, endpoint, 'POST', formData, success, error, {
|
|
121
|
+
'Content-Type': submitContentType
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
const createAction = (name, payload = {}) => {
|
|
125
|
+
switch (name) {
|
|
126
|
+
case 'change':
|
|
127
|
+
return new Change(payload);
|
|
128
|
+
case 'submit':
|
|
129
|
+
return new Submit(payload);
|
|
130
|
+
case 'click':
|
|
131
|
+
return new Click(payload);
|
|
132
|
+
case 'addItem':
|
|
133
|
+
return new AddItem(payload);
|
|
134
|
+
case 'removeItem':
|
|
135
|
+
return new RemoveItem(payload);
|
|
136
|
+
case 'reset':
|
|
137
|
+
return new Reset(payload);
|
|
138
|
+
case 'addInstance':
|
|
139
|
+
return new AddInstance(payload);
|
|
140
|
+
case 'removeInstance':
|
|
141
|
+
return new RemoveInstance(payload);
|
|
142
|
+
default:
|
|
143
|
+
console.error('invalid action');
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
class FunctionRuntimeImpl {
|
|
147
|
+
customFunctions = {};
|
|
148
|
+
registerFunctions(functions) {
|
|
149
|
+
Object.entries(functions).forEach(([name, funcDef]) => {
|
|
150
|
+
let finalFunction = funcDef;
|
|
151
|
+
if (typeof funcDef === 'function') {
|
|
152
|
+
finalFunction = {
|
|
153
|
+
_func: (args) => {
|
|
154
|
+
return funcDef(...args);
|
|
155
|
+
},
|
|
156
|
+
_signature: []
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (!finalFunction.hasOwnProperty('_func')) {
|
|
160
|
+
console.warn(`Unable to register function with name ${name}.`);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
this.customFunctions[name] = finalFunction;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
unregisterFunctions(...names) {
|
|
167
|
+
names.forEach(name => {
|
|
168
|
+
if (name in this.customFunctions) {
|
|
169
|
+
delete this.customFunctions[name];
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
getFunctions() {
|
|
174
|
+
function isArray(obj) {
|
|
175
|
+
if (obj !== null) {
|
|
176
|
+
return Object.prototype.toString.call(obj) === '[object Array]';
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
function valueOf(a) {
|
|
181
|
+
if (a === null || a === undefined) {
|
|
182
|
+
return a;
|
|
183
|
+
}
|
|
184
|
+
if (isArray(a)) {
|
|
185
|
+
return a.map(i => valueOf(i));
|
|
186
|
+
}
|
|
187
|
+
return a.valueOf();
|
|
188
|
+
}
|
|
189
|
+
function toString(a) {
|
|
190
|
+
if (a === null || a === undefined) {
|
|
191
|
+
return '';
|
|
192
|
+
}
|
|
193
|
+
return a.toString();
|
|
194
|
+
}
|
|
195
|
+
const defaultFunctions = {
|
|
196
|
+
validate: {
|
|
197
|
+
_func: (args, data, interpreter) => {
|
|
198
|
+
const element = args[0];
|
|
199
|
+
let validation;
|
|
200
|
+
if (typeof element === 'string' || typeof element === 'undefined') {
|
|
201
|
+
validation = interpreter.globals.form.validate();
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
validation = interpreter.globals.form.getElement(element.$id).validate();
|
|
205
|
+
}
|
|
206
|
+
if (Array.isArray(validation) && validation.length) {
|
|
207
|
+
interpreter.globals.form.logger.error('Form Validation Error');
|
|
208
|
+
}
|
|
209
|
+
return validation;
|
|
210
|
+
},
|
|
211
|
+
_signature: []
|
|
212
|
+
},
|
|
213
|
+
setFocus: {
|
|
214
|
+
_func: (args, data, interpreter) => {
|
|
215
|
+
const element = args[0];
|
|
216
|
+
try {
|
|
217
|
+
const field = interpreter.globals.form.getElement(element.$id);
|
|
218
|
+
interpreter.globals.form.setFocus(field);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
interpreter.globals.form.logger.error('Invalid argument passed in setFocus. An element is expected');
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
_signature: []
|
|
225
|
+
},
|
|
226
|
+
getData: {
|
|
227
|
+
_func: (args, data, interpreter) => {
|
|
228
|
+
interpreter.globals.form.logger.warn('The `getData` function is depricated. Use `exportData` instead.');
|
|
229
|
+
return interpreter.globals.form.exportData();
|
|
230
|
+
},
|
|
231
|
+
_signature: []
|
|
232
|
+
},
|
|
233
|
+
exportData: {
|
|
234
|
+
_func: (args, data, interpreter) => {
|
|
235
|
+
return interpreter.globals.form.exportData();
|
|
236
|
+
},
|
|
237
|
+
_signature: []
|
|
238
|
+
},
|
|
239
|
+
importData: {
|
|
240
|
+
_func: (args, data, interpreter) => {
|
|
241
|
+
const inputData = args[0];
|
|
242
|
+
if (typeof inputData === 'object' && inputData !== null) {
|
|
243
|
+
interpreter.globals.form.importData(inputData);
|
|
244
|
+
}
|
|
245
|
+
return {};
|
|
246
|
+
},
|
|
247
|
+
_signature: []
|
|
248
|
+
},
|
|
249
|
+
submitForm: {
|
|
250
|
+
_func: (args, data, interpreter) => {
|
|
251
|
+
const success = toString(args[0]);
|
|
252
|
+
const error = toString(args[1]);
|
|
253
|
+
const submit_as = args.length > 2 ? toString(args[2]) : 'multipart/form-data';
|
|
254
|
+
const submit_data = args.length > 3 ? valueOf(args[3]) : null;
|
|
255
|
+
interpreter.globals.form.dispatch(new Submit({
|
|
256
|
+
success,
|
|
257
|
+
error,
|
|
258
|
+
submit_as,
|
|
259
|
+
data: submit_data
|
|
260
|
+
}));
|
|
261
|
+
return {};
|
|
262
|
+
},
|
|
263
|
+
_signature: []
|
|
264
|
+
},
|
|
265
|
+
request: {
|
|
266
|
+
_func: (args, data, interpreter) => {
|
|
267
|
+
const uri = toString(args[0]);
|
|
268
|
+
const httpVerb = toString(args[1]);
|
|
269
|
+
const payload = valueOf(args[2]);
|
|
270
|
+
let success, error, headers = {};
|
|
271
|
+
if (typeof (args[3]) === 'string') {
|
|
272
|
+
interpreter.globals.form.logger.warn('This usage of request is deprecated. Please see the documentation and update');
|
|
273
|
+
success = valueOf(args[3]);
|
|
274
|
+
error = valueOf(args[4]);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
headers = valueOf(args[3]);
|
|
278
|
+
success = valueOf(args[4]);
|
|
279
|
+
error = valueOf(args[5]);
|
|
280
|
+
}
|
|
281
|
+
request(interpreter.globals, uri, httpVerb, payload, success, error, headers);
|
|
282
|
+
return {};
|
|
283
|
+
},
|
|
284
|
+
_signature: []
|
|
285
|
+
},
|
|
286
|
+
dispatchEvent: {
|
|
287
|
+
_func: (args, data, interpreter) => {
|
|
288
|
+
const element = args[0];
|
|
289
|
+
let eventName = valueOf(args[1]);
|
|
290
|
+
let payload = args.length > 2 ? valueOf(args[2]) : undefined;
|
|
291
|
+
let dispatch = false;
|
|
292
|
+
if (typeof element === 'string') {
|
|
293
|
+
payload = eventName;
|
|
294
|
+
eventName = element;
|
|
295
|
+
dispatch = true;
|
|
296
|
+
}
|
|
297
|
+
let event;
|
|
298
|
+
if (eventName.startsWith('custom:')) {
|
|
299
|
+
event = new CustomEvent(eventName.substring('custom:'.length), payload, dispatch);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
event = createAction(eventName, payload);
|
|
303
|
+
}
|
|
304
|
+
if (event != null) {
|
|
305
|
+
if (typeof element === 'string') {
|
|
306
|
+
interpreter.globals.form.dispatch(event);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
interpreter.globals.form.getElement(element.$id).dispatch(event);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return {};
|
|
313
|
+
},
|
|
314
|
+
_signature: []
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
return { ...defaultFunctions, ...this.customFunctions };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
export const FunctionRuntime = new FunctionRuntimeImpl();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseModel } from '../types/index.js';
|
|
2
|
+
declare class RuleEngine {
|
|
3
|
+
private _context;
|
|
4
|
+
private _globalNames;
|
|
5
|
+
private formulaEngine;
|
|
6
|
+
private debugInfo;
|
|
7
|
+
constructor();
|
|
8
|
+
compileRule(rule: string): any;
|
|
9
|
+
execute(node: any, data: any, globals: any, useValueOf?: boolean): any;
|
|
10
|
+
trackDependency(subscriber: BaseModel): void;
|
|
11
|
+
}
|
|
12
|
+
export default RuleEngine;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import Formula from '@adobe/json-formula';
|
|
2
|
+
import { FunctionRuntime } from './FunctionRuntime.js';
|
|
3
|
+
class RuleEngine {
|
|
4
|
+
_context;
|
|
5
|
+
_globalNames = [
|
|
6
|
+
'$form',
|
|
7
|
+
'$field',
|
|
8
|
+
'$event'
|
|
9
|
+
];
|
|
10
|
+
formulaEngine;
|
|
11
|
+
debugInfo = [];
|
|
12
|
+
constructor() {
|
|
13
|
+
const customFunctions = FunctionRuntime.getFunctions();
|
|
14
|
+
this.formulaEngine = new Formula(customFunctions, undefined, this.debugInfo);
|
|
15
|
+
}
|
|
16
|
+
compileRule(rule) {
|
|
17
|
+
return this.formulaEngine.compile(rule, this._globalNames);
|
|
18
|
+
}
|
|
19
|
+
execute(node, data, globals, useValueOf = false) {
|
|
20
|
+
const oldContext = this._context;
|
|
21
|
+
this._context = globals;
|
|
22
|
+
let res = undefined;
|
|
23
|
+
try {
|
|
24
|
+
res = this.formulaEngine.run(node, data, 'en-US', globals);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
this._context?.form?.logger?.error(err);
|
|
28
|
+
}
|
|
29
|
+
while (this.debugInfo.length > 0) {
|
|
30
|
+
this._context?.form?.logger?.debug(this.debugInfo.pop());
|
|
31
|
+
}
|
|
32
|
+
let finalRes = res;
|
|
33
|
+
if (useValueOf) {
|
|
34
|
+
if (typeof res === 'object' && res !== null) {
|
|
35
|
+
finalRes = Object.getPrototypeOf(res).valueOf.call(res);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
this._context = oldContext;
|
|
39
|
+
return finalRes;
|
|
40
|
+
}
|
|
41
|
+
trackDependency(subscriber) {
|
|
42
|
+
if (this._context && this._context.field !== undefined && this._context.field !== subscriber) {
|
|
43
|
+
subscriber._addDependent(this._context.field);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export default RuleEngine;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export declare type Items<T> = {
|
|
2
|
+
[key: string]: T;
|
|
3
|
+
};
|
|
4
|
+
export declare type Primitives = string | number | boolean | null | undefined;
|
|
5
|
+
export declare type Label = {
|
|
6
|
+
value: string;
|
|
7
|
+
richText?: boolean;
|
|
8
|
+
visible?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare type TranslationConstraintsJson = {
|
|
11
|
+
enumNames?: string[];
|
|
12
|
+
enum?: any[];
|
|
13
|
+
};
|
|
14
|
+
export declare type ConstraintsJson = TranslationConstraintsJson & {
|
|
15
|
+
accept?: string[];
|
|
16
|
+
enforceEnum?: boolean;
|
|
17
|
+
exclusiveMinimum?: number;
|
|
18
|
+
exclusiveMaximum?: number;
|
|
19
|
+
format?: string;
|
|
20
|
+
maxFileSize?: number | string;
|
|
21
|
+
maxLength?: number;
|
|
22
|
+
maximum?: number;
|
|
23
|
+
maxItems?: number;
|
|
24
|
+
minOccur?: number;
|
|
25
|
+
maxOccur?: number;
|
|
26
|
+
minLength?: number;
|
|
27
|
+
minimum?: number;
|
|
28
|
+
minItems?: number;
|
|
29
|
+
pattern?: string;
|
|
30
|
+
required?: boolean;
|
|
31
|
+
step?: number;
|
|
32
|
+
type?: string;
|
|
33
|
+
validationExpression?: string;
|
|
34
|
+
uniqueItems?: boolean;
|
|
35
|
+
};
|
|
36
|
+
export declare type ConstraintsMessages = {
|
|
37
|
+
accept?: string;
|
|
38
|
+
enum?: string;
|
|
39
|
+
exclusiveMinimum?: string;
|
|
40
|
+
exclusiveMaximum?: string;
|
|
41
|
+
format?: string;
|
|
42
|
+
maxFileSize?: string;
|
|
43
|
+
maxLength?: string;
|
|
44
|
+
maximum?: string;
|
|
45
|
+
maxItems?: string;
|
|
46
|
+
minLength?: string;
|
|
47
|
+
minimum?: string;
|
|
48
|
+
minItems?: string;
|
|
49
|
+
uniqueItems?: string;
|
|
50
|
+
pattern?: string;
|
|
51
|
+
required?: string;
|
|
52
|
+
step?: string;
|
|
53
|
+
type?: string;
|
|
54
|
+
validationExpression?: string;
|
|
55
|
+
};
|
|
56
|
+
export declare type RulesJson = {
|
|
57
|
+
rules?: Items<string>;
|
|
58
|
+
events?: Items<string[] | string | undefined>;
|
|
59
|
+
};
|
|
60
|
+
declare type TranslationBaseJson = {
|
|
61
|
+
description?: string;
|
|
62
|
+
};
|
|
63
|
+
export declare type BaseJson = TranslationBaseJson & RulesJson & ConstraintsJson & {
|
|
64
|
+
dataRef?: string | null;
|
|
65
|
+
':type'?: string;
|
|
66
|
+
label?: Label;
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
visible?: boolean;
|
|
69
|
+
name?: string;
|
|
70
|
+
constraintMessages?: ConstraintsMessages;
|
|
71
|
+
fieldType?: string;
|
|
72
|
+
errorMessage?: string;
|
|
73
|
+
properties?: {
|
|
74
|
+
[key: string]: any;
|
|
75
|
+
};
|
|
76
|
+
repeatable?: boolean;
|
|
77
|
+
screenReaderText?: string;
|
|
78
|
+
tooltip?: string;
|
|
79
|
+
altText?: string;
|
|
80
|
+
viewType?: string;
|
|
81
|
+
};
|
|
82
|
+
declare type TranslationFieldJson = {
|
|
83
|
+
placeholder?: string;
|
|
84
|
+
};
|
|
85
|
+
export declare type FieldJson = BaseJson & TranslationFieldJson & {
|
|
86
|
+
readOnly?: boolean;
|
|
87
|
+
valid?: boolean;
|
|
88
|
+
default?: any;
|
|
89
|
+
value?: any;
|
|
90
|
+
displayFormat?: string;
|
|
91
|
+
editFormat?: string;
|
|
92
|
+
editValue?: string;
|
|
93
|
+
displayValue?: string;
|
|
94
|
+
emptyValue?: 'null' | 'undefined' | '';
|
|
95
|
+
};
|
|
96
|
+
export declare type ContainerJson = BaseJson & {
|
|
97
|
+
items: Array<FieldJson | ContainerJson>;
|
|
98
|
+
initialItems?: number;
|
|
99
|
+
activeChild?: string;
|
|
100
|
+
};
|
|
101
|
+
export declare type MetaDataJson = {
|
|
102
|
+
version?: string;
|
|
103
|
+
grammar?: string;
|
|
104
|
+
};
|
|
105
|
+
export declare type FieldsetJson = ContainerJson & {
|
|
106
|
+
'type'?: 'array' | 'object';
|
|
107
|
+
};
|
|
108
|
+
export declare type FormJson = ContainerJson & {
|
|
109
|
+
metadata?: MetaDataJson;
|
|
110
|
+
data?: any;
|
|
111
|
+
title?: string;
|
|
112
|
+
action?: string;
|
|
113
|
+
adaptiveForm?: string;
|
|
114
|
+
lang?: string;
|
|
115
|
+
};
|
|
116
|
+
export declare type TranslationJson = TranslationBaseJson & TranslationFieldJson & TranslationConstraintsJson;
|
|
117
|
+
export declare const translationProps: string[];
|
|
118
|
+
export declare const constraintProps: string[];
|
|
119
|
+
export {};
|