@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,187 @@
|
|
|
1
|
+
import { isFile } from './JsonUtils.js';
|
|
2
|
+
import { FileObject } from '../FileObject.js';
|
|
3
|
+
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'.split('');
|
|
4
|
+
const fileSizeRegex = /^(\d*\.?\d+)(\\?(?=[KMGT])([KMGT])(?:i?B)?|B?)$/i;
|
|
5
|
+
export const randomWord = (l) => {
|
|
6
|
+
const ret = [];
|
|
7
|
+
for (let i = 0; i <= l; i++) {
|
|
8
|
+
const randIndex = Math.floor(Math.random() * (chars.length));
|
|
9
|
+
ret.push(chars[randIndex]);
|
|
10
|
+
}
|
|
11
|
+
return ret.join('');
|
|
12
|
+
};
|
|
13
|
+
export const isEmpty = (value) => {
|
|
14
|
+
return value === '' || value === null || value === undefined;
|
|
15
|
+
};
|
|
16
|
+
export const getAttachments = (input) => {
|
|
17
|
+
const items = input.items || [];
|
|
18
|
+
return items?.reduce((acc, item) => {
|
|
19
|
+
let ret = null;
|
|
20
|
+
if (item.isContainer) {
|
|
21
|
+
ret = getAttachments(item);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
if (isFile(item.getState())) {
|
|
25
|
+
ret = {};
|
|
26
|
+
const name = item.name || '';
|
|
27
|
+
const dataRef = (item.dataRef != null)
|
|
28
|
+
? item.dataRef
|
|
29
|
+
: (name.length > 0 ? item.name : undefined);
|
|
30
|
+
if (item.value instanceof Array) {
|
|
31
|
+
ret[item.id] = item.value.map((x) => {
|
|
32
|
+
return { ...x, 'dataRef': dataRef };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else if (item.value != null) {
|
|
36
|
+
ret[item.id] = { ...item.value, 'dataRef': dataRef };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return Object.assign(acc, ret);
|
|
41
|
+
}, {});
|
|
42
|
+
};
|
|
43
|
+
export const getFileSizeInBytes = (str) => {
|
|
44
|
+
let retVal = 0;
|
|
45
|
+
if (typeof str === 'string') {
|
|
46
|
+
const matches = fileSizeRegex.exec(str.trim());
|
|
47
|
+
if (matches != null) {
|
|
48
|
+
retVal = sizeToBytes(parseFloat(matches[1]), (matches[2] || 'kb').toUpperCase());
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return retVal;
|
|
52
|
+
};
|
|
53
|
+
const sizeToBytes = (size, symbol) => {
|
|
54
|
+
const sizes = { 'KB': 1, 'MB': 2, 'GB': 3, 'TB': 4 };
|
|
55
|
+
const i = Math.pow(1024, sizes[symbol]);
|
|
56
|
+
return Math.round(size * i);
|
|
57
|
+
};
|
|
58
|
+
export const IdGenerator = function* (initial = 50) {
|
|
59
|
+
const initialize = function () {
|
|
60
|
+
const arr = [];
|
|
61
|
+
for (let i = 0; i < initial; i++) {
|
|
62
|
+
arr.push(randomWord(10));
|
|
63
|
+
}
|
|
64
|
+
return arr;
|
|
65
|
+
};
|
|
66
|
+
const passedIds = {};
|
|
67
|
+
let ids = initialize();
|
|
68
|
+
do {
|
|
69
|
+
let x = ids.pop();
|
|
70
|
+
while (x in passedIds) {
|
|
71
|
+
if (ids.length === 0) {
|
|
72
|
+
ids = initialize();
|
|
73
|
+
}
|
|
74
|
+
x = ids.pop();
|
|
75
|
+
}
|
|
76
|
+
passedIds[x] = true;
|
|
77
|
+
yield ids.pop();
|
|
78
|
+
if (ids.length === 0) {
|
|
79
|
+
ids = initialize();
|
|
80
|
+
}
|
|
81
|
+
} while (ids.length > 0);
|
|
82
|
+
};
|
|
83
|
+
export const isDataUrl = (str) => {
|
|
84
|
+
const dataUrlRegex = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base64,(.*)$/;
|
|
85
|
+
return dataUrlRegex.exec(str.trim()) != null;
|
|
86
|
+
};
|
|
87
|
+
export const extractFileInfo = (file) => {
|
|
88
|
+
if (file !== null) {
|
|
89
|
+
let retVal = null;
|
|
90
|
+
if (file instanceof FileObject) {
|
|
91
|
+
retVal = file;
|
|
92
|
+
}
|
|
93
|
+
else if (typeof File !== 'undefined' && file instanceof File) {
|
|
94
|
+
retVal = {
|
|
95
|
+
name: file.name,
|
|
96
|
+
mediaType: file.type,
|
|
97
|
+
size: file.size,
|
|
98
|
+
data: file
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
else if (typeof file === 'string' && isDataUrl(file)) {
|
|
102
|
+
const result = dataURItoBlob(file);
|
|
103
|
+
if (result !== null) {
|
|
104
|
+
const { blob, name } = result;
|
|
105
|
+
retVal = {
|
|
106
|
+
name: name,
|
|
107
|
+
mediaType: blob.type,
|
|
108
|
+
size: blob.size,
|
|
109
|
+
data: blob
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
let jFile = file;
|
|
115
|
+
try {
|
|
116
|
+
jFile = JSON.parse(file);
|
|
117
|
+
retVal = jFile;
|
|
118
|
+
if (!retVal.mediaType) {
|
|
119
|
+
retVal.mediaType = retVal.type;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (ex) {
|
|
123
|
+
}
|
|
124
|
+
if (typeof jFile?.data === 'string' && isDataUrl(jFile?.data)) {
|
|
125
|
+
const result = dataURItoBlob(jFile?.data);
|
|
126
|
+
if (result !== null) {
|
|
127
|
+
const blob = result.blob;
|
|
128
|
+
retVal = {
|
|
129
|
+
name: jFile?.name,
|
|
130
|
+
mediaType: jFile?.type || jFile?.mediaType,
|
|
131
|
+
size: blob.size,
|
|
132
|
+
data: blob
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (typeof jFile === 'string') {
|
|
137
|
+
const fileName = jFile.split('/').pop();
|
|
138
|
+
retVal = {
|
|
139
|
+
name: fileName,
|
|
140
|
+
mediaType: 'application/octet-stream',
|
|
141
|
+
size: 0,
|
|
142
|
+
data: jFile
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
else if (typeof jFile === 'object') {
|
|
146
|
+
retVal = {
|
|
147
|
+
name: jFile?.name,
|
|
148
|
+
mediaType: jFile?.type || jFile?.mediaType,
|
|
149
|
+
size: jFile?.size,
|
|
150
|
+
data: jFile?.data
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (retVal !== null && retVal.data != null) {
|
|
155
|
+
return new FileObject(retVal);
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
export const dataURItoBlob = (dataURI) => {
|
|
164
|
+
const regex = /^data:([a-z]+\/[a-z0-9-+.]+)?(?:;name=([^;]+))?(;base64)?,(.+)$/;
|
|
165
|
+
const groups = regex.exec(dataURI);
|
|
166
|
+
if (groups !== null) {
|
|
167
|
+
const type = groups[1] || '';
|
|
168
|
+
const name = groups[2] || 'unknown';
|
|
169
|
+
const isBase64 = typeof groups[3] === 'string';
|
|
170
|
+
if (isBase64) {
|
|
171
|
+
const binary = atob(groups[4]);
|
|
172
|
+
const array = [];
|
|
173
|
+
for (let i = 0; i < binary.length; i++) {
|
|
174
|
+
array.push(binary.charCodeAt(i));
|
|
175
|
+
}
|
|
176
|
+
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
177
|
+
return { name, blob };
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const blob = new window.Blob([groups[4]], { type });
|
|
181
|
+
return { name, blob };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FieldsetJson, FieldJson } from '../types/index.js';
|
|
2
|
+
export declare const getProperty: <P>(data: any, key: string, def: P) => P;
|
|
3
|
+
export declare const isFile: (item: FieldsetJson | FieldJson) => boolean;
|
|
4
|
+
export declare const checkIfConstraintsArePresent: (item: FieldsetJson | FieldJson) => boolean;
|
|
5
|
+
export declare const isCheckbox: (item: FieldsetJson | FieldJson) => boolean;
|
|
6
|
+
export declare const isCheckboxGroup: (item: FieldsetJson | FieldJson) => boolean;
|
|
7
|
+
export declare const isDateField: (item: FieldsetJson | FieldJson) => boolean;
|
|
8
|
+
export declare function deepClone(obj: any, idGenerator?: () => string): any;
|
|
9
|
+
export declare function checkIfKeyAdded(currentObj: any, prevObj: any, objKey: string): boolean;
|
|
10
|
+
export declare const jsonString: (obj: any) => string;
|
|
11
|
+
export declare const isRepeatable: (obj: FieldsetJson | FieldJson) => boolean;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { constraintProps } from '../types/index.js';
|
|
2
|
+
import { defaultFieldTypes } from './SchemaUtils.js';
|
|
3
|
+
export const getProperty = (data, key, def) => {
|
|
4
|
+
if (key in data) {
|
|
5
|
+
return data[key];
|
|
6
|
+
}
|
|
7
|
+
else if (!key.startsWith(':')) {
|
|
8
|
+
const prefixedKey = `:${key}`;
|
|
9
|
+
if (prefixedKey in data) {
|
|
10
|
+
return data[prefixedKey];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return def;
|
|
14
|
+
};
|
|
15
|
+
export const isFile = function (item) {
|
|
16
|
+
return (item?.type === 'file' || item?.type === 'file[]') ||
|
|
17
|
+
((item?.type === 'string' || item?.type === 'string[]') &&
|
|
18
|
+
(item?.format === 'binary' || item?.format === 'data-url'));
|
|
19
|
+
};
|
|
20
|
+
export const checkIfConstraintsArePresent = function (item) {
|
|
21
|
+
return constraintProps.some(cp => item[cp] !== undefined);
|
|
22
|
+
};
|
|
23
|
+
export const isCheckbox = function (item) {
|
|
24
|
+
const fieldType = item?.fieldType || defaultFieldTypes(item);
|
|
25
|
+
return fieldType === 'checkbox';
|
|
26
|
+
};
|
|
27
|
+
export const isCheckboxGroup = function (item) {
|
|
28
|
+
const fieldType = item?.fieldType || defaultFieldTypes(item);
|
|
29
|
+
return fieldType === 'checkbox-group';
|
|
30
|
+
};
|
|
31
|
+
export const isDateField = function (item) {
|
|
32
|
+
const fieldType = item?.fieldType || defaultFieldTypes(item);
|
|
33
|
+
return (fieldType === 'text-input' && item?.format === 'date') || fieldType === 'date-input';
|
|
34
|
+
};
|
|
35
|
+
export function deepClone(obj, idGenerator) {
|
|
36
|
+
let result;
|
|
37
|
+
if (obj instanceof Array) {
|
|
38
|
+
result = [];
|
|
39
|
+
result = obj.map(x => deepClone(x, idGenerator));
|
|
40
|
+
}
|
|
41
|
+
else if (typeof obj === 'object' && obj !== null) {
|
|
42
|
+
result = {};
|
|
43
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
44
|
+
result[key] = deepClone(value, idGenerator);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
result = obj;
|
|
49
|
+
}
|
|
50
|
+
if (idGenerator && result && result.id) {
|
|
51
|
+
result.id = idGenerator();
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
export function checkIfKeyAdded(currentObj, prevObj, objKey) {
|
|
56
|
+
if (currentObj != null && prevObj != null) {
|
|
57
|
+
const newPrvObj = { ...prevObj };
|
|
58
|
+
newPrvObj[objKey] = currentObj[objKey];
|
|
59
|
+
const newJsonStr = jsonString(currentObj).replace(jsonString(newPrvObj), '');
|
|
60
|
+
return newJsonStr === '';
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export const jsonString = (obj) => {
|
|
67
|
+
return JSON.stringify(obj, null, 2);
|
|
68
|
+
};
|
|
69
|
+
export const isRepeatable = (obj) => {
|
|
70
|
+
return ((obj.repeatable &&
|
|
71
|
+
((obj.minOccur === undefined && obj.maxOccur === undefined) ||
|
|
72
|
+
(obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.maxOccur !== 0) ||
|
|
73
|
+
(obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.minOccur !== 0 && obj.maxOccur !== 0) ||
|
|
74
|
+
(obj.minOccur !== undefined && obj.minOccur >= 0) ||
|
|
75
|
+
(obj.maxOccur !== undefined && obj.maxOccur !== 0))) || false);
|
|
76
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const objToMap = (o) => new Map(Object.entries(o));
|
|
2
|
+
const stringViewTypes = objToMap({ 'date': 'date-input', 'data-url': 'file-input', 'binary': 'file-input' });
|
|
3
|
+
const typeToViewTypes = objToMap({
|
|
4
|
+
'number': 'number-input',
|
|
5
|
+
'boolean': 'checkbox',
|
|
6
|
+
'object': 'panel',
|
|
7
|
+
'array': 'panel',
|
|
8
|
+
'file': 'file-input',
|
|
9
|
+
'file[]': 'file-input'
|
|
10
|
+
});
|
|
11
|
+
const arrayTypes = ['string[]', 'boolean[]', 'number[]', 'array'];
|
|
12
|
+
export const defaultFieldTypes = (schema) => {
|
|
13
|
+
const type = schema.type || 'string';
|
|
14
|
+
if ('enum' in schema) {
|
|
15
|
+
const enums = schema.enum;
|
|
16
|
+
if (enums.length > 2 || arrayTypes.indexOf(type) > -1) {
|
|
17
|
+
return 'drop-down';
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return 'checkbox';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (type === 'string' || type === 'string[]') {
|
|
24
|
+
return stringViewTypes.get(schema.format) || 'text-input';
|
|
25
|
+
}
|
|
26
|
+
return typeToViewTypes.get(type) || 'text-input';
|
|
27
|
+
};
|
|
28
|
+
const fieldSchema = (input) => {
|
|
29
|
+
if ('items' in input) {
|
|
30
|
+
const fieldset = input;
|
|
31
|
+
const items = fieldset.items;
|
|
32
|
+
if (fieldset.type === 'array') {
|
|
33
|
+
return {
|
|
34
|
+
type: 'array',
|
|
35
|
+
items: fieldSchema(items[0]),
|
|
36
|
+
minItems: fieldset?.minItems,
|
|
37
|
+
maxItems: fieldset?.maxItems
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const iter = items.filter(x => x.name != null);
|
|
42
|
+
return {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: Object.fromEntries(iter.map(item => [item.name, fieldSchema(item)])),
|
|
45
|
+
required: iter.filter(x => x.required).map(x => x.name)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const field = input;
|
|
51
|
+
const schemaProps = ['type', 'maxLength', 'minLength', 'minimum', 'maximum', 'format', 'pattern', 'step', 'enum'];
|
|
52
|
+
const schema = schemaProps.reduce((acc, prop) => {
|
|
53
|
+
const p = prop;
|
|
54
|
+
if (prop in field && field[p] != undefined) {
|
|
55
|
+
acc[prop] = field[p];
|
|
56
|
+
}
|
|
57
|
+
return acc;
|
|
58
|
+
}, {});
|
|
59
|
+
if (field.dataRef === 'none' || Object.keys(schema).length == 0) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
title: field.label?.value,
|
|
64
|
+
description: field.description,
|
|
65
|
+
...schema
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export const exportDataSchema = (form) => {
|
|
70
|
+
return fieldSchema(form);
|
|
71
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FieldJson, FieldsetJson, FormJson } from '../types/index.js';
|
|
2
|
+
export declare const TRANSLATION_TOKEN = "##";
|
|
3
|
+
export declare const TRANSLATION_ID = "afs:translationIds";
|
|
4
|
+
export declare const CUSTOM_PROPS_KEY = "properties";
|
|
5
|
+
declare type formElementJson = FieldJson | FieldsetJson | FormJson | any;
|
|
6
|
+
export declare const invalidateTranslation: (input: formElementJson, updates: any) => void;
|
|
7
|
+
export declare const addTranslationId: (input: formElementJson, additionalTranslationProps?: string[]) => formElementJson;
|
|
8
|
+
export declare const getOrElse: (input: any, key: string | string[], defaultValue?: any) => any;
|
|
9
|
+
export declare const createTranslationObj: (input: formElementJson, additionalTranslationProps?: string[]) => any;
|
|
10
|
+
export declare const createTranslationObject: (input: formElementJson, additionalTranslationProps?: string[], bcp47LangTags?: string[]) => any;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { translationProps } from '../types/index.js';
|
|
2
|
+
export const TRANSLATION_TOKEN = '##';
|
|
3
|
+
export const TRANSLATION_ID = 'afs:translationIds';
|
|
4
|
+
export const CUSTOM_PROPS_KEY = 'properties';
|
|
5
|
+
const defaultBcp47LangTags = [
|
|
6
|
+
'de-DE',
|
|
7
|
+
'en-US',
|
|
8
|
+
'es-ES',
|
|
9
|
+
'fr-FR',
|
|
10
|
+
'it-IT',
|
|
11
|
+
'ja-JP',
|
|
12
|
+
'ko-KR',
|
|
13
|
+
'pt-BR',
|
|
14
|
+
'zh-CN',
|
|
15
|
+
'zh-TW'
|
|
16
|
+
];
|
|
17
|
+
export const invalidateTranslation = (input, updates) => {
|
|
18
|
+
translationProps.forEach((prop) => {
|
|
19
|
+
if (prop in updates && input?.[CUSTOM_PROPS_KEY]?.[TRANSLATION_ID]?.[prop]) {
|
|
20
|
+
delete input?.[CUSTOM_PROPS_KEY]?.[TRANSLATION_ID]?.[prop];
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
export const addTranslationId = (input, additionalTranslationProps = []) => {
|
|
25
|
+
const model = input;
|
|
26
|
+
const transProps = [...translationProps, ...additionalTranslationProps];
|
|
27
|
+
_createTranslationId(model, '', transProps);
|
|
28
|
+
return model;
|
|
29
|
+
};
|
|
30
|
+
const _createTranslationId = (input, path, transProps) => {
|
|
31
|
+
Object.entries(input).forEach(([key, value]) => {
|
|
32
|
+
if (typeof value == 'object') {
|
|
33
|
+
if (input instanceof Array) {
|
|
34
|
+
if (value && 'name' in value) {
|
|
35
|
+
_createTranslationId(value, `${path === '' ? path : path + TRANSLATION_TOKEN}${value.name}`, transProps);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
_createTranslationId(value, ((key === 'items') ? path : `${path === '' ? path : path + TRANSLATION_TOKEN}${key}`), transProps);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
if (':type' in input ||
|
|
44
|
+
'type' in input ||
|
|
45
|
+
'fieldType' in input) {
|
|
46
|
+
for (const transProp of transProps) {
|
|
47
|
+
if (getOrElse(input, transProp) != null) {
|
|
48
|
+
if (!(CUSTOM_PROPS_KEY in input)) {
|
|
49
|
+
input[CUSTOM_PROPS_KEY] = {};
|
|
50
|
+
}
|
|
51
|
+
if (!(TRANSLATION_ID in input[CUSTOM_PROPS_KEY])) {
|
|
52
|
+
input[CUSTOM_PROPS_KEY][TRANSLATION_ID] = {};
|
|
53
|
+
}
|
|
54
|
+
if (!(transProp in input[CUSTOM_PROPS_KEY][TRANSLATION_ID])) {
|
|
55
|
+
input[CUSTOM_PROPS_KEY][TRANSLATION_ID][transProp] = `${path}${TRANSLATION_TOKEN}${transProp}${TRANSLATION_TOKEN}${Math.floor(Math.random() * 10000) + 1}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
const _createTranslationObj = (input, translationObj, translationProps) => {
|
|
64
|
+
Object.values(input).forEach((value) => {
|
|
65
|
+
if (typeof value == 'object') {
|
|
66
|
+
_createTranslationObj(value, translationObj, translationProps);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
for (const translationProp of translationProps) {
|
|
70
|
+
const objValue = getOrElse(input, translationProp);
|
|
71
|
+
if (objValue && input?.[CUSTOM_PROPS_KEY]?.[TRANSLATION_ID]?.[translationProp]) {
|
|
72
|
+
if (objValue instanceof Array) {
|
|
73
|
+
objValue.forEach((item, index) => {
|
|
74
|
+
if (typeof item === 'string') {
|
|
75
|
+
translationObj[`${input[CUSTOM_PROPS_KEY][TRANSLATION_ID][translationProp]}${TRANSLATION_TOKEN}${index}`] = item;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
translationObj[`${input[CUSTOM_PROPS_KEY][TRANSLATION_ID][translationProp]}`] = objValue;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
export const getOrElse = (input, key, defaultValue = null) => {
|
|
88
|
+
if (!key) {
|
|
89
|
+
return defaultValue;
|
|
90
|
+
}
|
|
91
|
+
const arr = Array.isArray(key) ? key : key.split('.');
|
|
92
|
+
let objValue = input, index = 0;
|
|
93
|
+
while (index < arr.length && objValue.hasOwnProperty(arr[index])) {
|
|
94
|
+
objValue = objValue[arr[index]];
|
|
95
|
+
index++;
|
|
96
|
+
}
|
|
97
|
+
return index == arr.length ? objValue : defaultValue;
|
|
98
|
+
};
|
|
99
|
+
export const createTranslationObj = (input, additionalTranslationProps = []) => {
|
|
100
|
+
const obj = {};
|
|
101
|
+
const transProps = [...translationProps, ...additionalTranslationProps];
|
|
102
|
+
_createTranslationObj(input, obj, transProps);
|
|
103
|
+
return obj;
|
|
104
|
+
};
|
|
105
|
+
export const createTranslationObject = (input, additionalTranslationProps = [], bcp47LangTags = []) => {
|
|
106
|
+
const transProps = [...translationProps, ...additionalTranslationProps];
|
|
107
|
+
const inputCopy = JSON.parse(JSON.stringify(input));
|
|
108
|
+
const obj = createTranslationObj(addTranslationId(inputCopy, additionalTranslationProps), transProps);
|
|
109
|
+
const langTags = [...defaultBcp47LangTags, ...bcp47LangTags];
|
|
110
|
+
const allLangs = {};
|
|
111
|
+
for (const langTag of langTags) {
|
|
112
|
+
allLangs[langTag] = JSON.parse(JSON.stringify(obj));
|
|
113
|
+
}
|
|
114
|
+
return [inputCopy, allLangs];
|
|
115
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare type ValidationResult = {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
value: any;
|
|
4
|
+
};
|
|
5
|
+
export declare const coerceType: (param: any, type: 'string' | 'number' | 'boolean') => string | number | boolean;
|
|
6
|
+
declare type ValidConstraintsType = {
|
|
7
|
+
date: ValidationConstraints[];
|
|
8
|
+
string: ValidationConstraints[];
|
|
9
|
+
number: ValidationConstraints[];
|
|
10
|
+
array: ValidationConstraints[];
|
|
11
|
+
file: ValidationConstraints[];
|
|
12
|
+
};
|
|
13
|
+
export declare const ValidConstraints: ValidConstraintsType;
|
|
14
|
+
export declare type ValidationConstraints = 'type' | 'format' | 'minimum' | 'maximum' | 'exclusiveMinimum' | 'exclusiveMaximum' | 'minItems' | 'maxItems' | 'uniqueItems' | 'minLength' | 'maxLength' | 'pattern' | 'required' | 'enum' | 'accept' | 'maxFileSize';
|
|
15
|
+
declare type ConstraintsObject = {
|
|
16
|
+
[key in ValidationConstraints]: (constraint: any, inputVal: any) => ValidationResult;
|
|
17
|
+
};
|
|
18
|
+
export declare const Constraints: ConstraintsObject;
|
|
19
|
+
export {};
|