@aemforms/af-core 0.22.15 → 0.22.17
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/BaseNode.d.ts +11 -0
- package/lib/BaseNode.js +51 -2
- package/lib/Checkbox.d.ts +8 -0
- package/lib/Container.d.ts +43 -7
- package/lib/Container.js +24 -0
- package/lib/Field.d.ts +12 -12
- package/lib/Field.js +33 -38
- package/lib/FileObject.d.ts +3 -2
- package/lib/FileObject.js +8 -2
- package/lib/FileUpload.d.ts +2 -12
- package/lib/FileUpload.js +25 -130
- package/lib/Form.d.ts +8 -18
- package/lib/Form.js +12 -35
- package/lib/FormInstance.d.ts +1 -1
- package/lib/FormInstance.js +3 -25
- package/lib/Scriptable.js +1 -1
- package/lib/controller/Controller.d.ts +1 -0
- package/lib/controller/Controller.js +3 -0
- package/lib/controller/EventQueue.d.ts +1 -1
- package/lib/controller/EventQueue.js +2 -2
- package/lib/controller/Logger.d.ts +17 -0
- package/lib/controller/Logger.js +36 -0
- package/lib/data/DataValue.d.ts +1 -1
- package/lib/data/DataValue.js +4 -2
- package/lib/index.d.ts +2 -1
- package/lib/index.js +4 -1
- package/lib/rules/FunctionRuntime.d.ts +8 -4
- package/lib/rules/FunctionRuntime.js +85 -26
- package/lib/rules/RuleEngine.js +2 -5
- package/lib/types/Json.d.ts +1 -0
- package/lib/types/Model.d.ts +7 -2
- package/lib/utils/FormUtils.d.ts +4 -12
- package/lib/utils/FormUtils.js +56 -52
- package/lib/utils/ValidationUtils.d.ts +17 -0
- package/lib/utils/ValidationUtils.js +87 -11
- package/package.json +3 -2
|
@@ -16,7 +16,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
16
16
|
});
|
|
17
17
|
};
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.submit = exports.request = void 0;
|
|
19
|
+
exports.FunctionRuntime = exports.submit = exports.request = void 0;
|
|
20
20
|
/**
|
|
21
21
|
* Implementation of function runtime in rule engine
|
|
22
22
|
*/
|
|
@@ -26,6 +26,13 @@ const Fetch_1 = require("../utils/Fetch");
|
|
|
26
26
|
const FileObject_1 = require("../FileObject");
|
|
27
27
|
const FormUtils_1 = require("../utils/FormUtils");
|
|
28
28
|
const JsonUtils_1 = require("../utils/JsonUtils");
|
|
29
|
+
const getCustomEventName = (name) => {
|
|
30
|
+
const eName = name;
|
|
31
|
+
if (eName.length > 0 && eName.startsWith('custom:')) {
|
|
32
|
+
return eName.substring('custom:'.length);
|
|
33
|
+
}
|
|
34
|
+
return eName;
|
|
35
|
+
};
|
|
29
36
|
/**
|
|
30
37
|
* Implementation of generic request API. This API can be used to make external web request
|
|
31
38
|
* @param context expression execution context(consists of current form, current field, current event)
|
|
@@ -34,10 +41,11 @@ const JsonUtils_1 = require("../utils/JsonUtils");
|
|
|
34
41
|
* @param payload request payload
|
|
35
42
|
* @param success success handler
|
|
36
43
|
* @param error error handler
|
|
37
|
-
* @param
|
|
44
|
+
* @param headers headers
|
|
38
45
|
* @private
|
|
39
46
|
*/
|
|
40
|
-
const request = (context, uri, httpVerb, payload, success, error,
|
|
47
|
+
const request = (context, uri, httpVerb, payload, success, error, headers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
var _a;
|
|
41
49
|
const endpoint = uri;
|
|
42
50
|
const requestOptions = {
|
|
43
51
|
method: httpVerb
|
|
@@ -55,24 +63,50 @@ const request = (context, uri, httpVerb, payload, success, error, payloadContent
|
|
|
55
63
|
inputPayload = payload;
|
|
56
64
|
}
|
|
57
65
|
else if (payload && typeof payload === 'object' && Object.keys(payload).length > 0) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
const headerNames = Object.keys(headers);
|
|
67
|
+
if (headerNames.length > 0) {
|
|
68
|
+
requestOptions.headers = Object.assign(Object.assign({}, headers), (headerNames.indexOf('Content-Type') === -1 ? { 'Content-Type': 'application/json' } : {}) // this should match content type of the payload
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
requestOptions.headers = { 'Content-Type': 'application/json' };
|
|
73
|
+
}
|
|
74
|
+
const contentType = ((_a = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.headers) === null || _a === void 0 ? void 0 : _a['Content-Type']) || 'application/json';
|
|
75
|
+
if (contentType === 'application/json') {
|
|
76
|
+
inputPayload = JSON.stringify(payload);
|
|
77
|
+
}
|
|
78
|
+
else if (contentType.indexOf('multipart/form-data') > -1) {
|
|
79
|
+
inputPayload = multipartFormData(payload);
|
|
80
|
+
}
|
|
81
|
+
else if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
|
|
82
|
+
inputPayload = urlEncoded(payload);
|
|
62
83
|
}
|
|
63
|
-
inputPayload = JSON.stringify(payload);
|
|
64
84
|
}
|
|
65
85
|
result = yield (0, Fetch_1.request)(endpoint, inputPayload, requestOptions);
|
|
66
86
|
}
|
|
67
87
|
catch (e) {
|
|
68
88
|
//todo: define error payload
|
|
69
89
|
context.form.logger.error('Error invoking a rest API');
|
|
70
|
-
|
|
90
|
+
const eName = getCustomEventName(error);
|
|
91
|
+
context.form.dispatch(new Controller_1.CustomEvent(eName, {}, true));
|
|
71
92
|
return;
|
|
72
93
|
}
|
|
73
|
-
|
|
94
|
+
const eName = getCustomEventName(success);
|
|
95
|
+
context.form.dispatch(new Controller_1.CustomEvent(eName, result, true));
|
|
74
96
|
});
|
|
75
97
|
exports.request = request;
|
|
98
|
+
const urlEncoded = (data) => {
|
|
99
|
+
const formData = new URLSearchParams();
|
|
100
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
101
|
+
if (value != null && typeof value === 'object') {
|
|
102
|
+
formData.append(key, (0, JsonUtils_1.jsonString)(value));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
formData.append(key, value);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return formData;
|
|
109
|
+
};
|
|
76
110
|
/**
|
|
77
111
|
* Create multi part form data using form data and form attachments
|
|
78
112
|
* @param data form data
|
|
@@ -99,16 +133,18 @@ const multipartFormData = (data, attachments) => {
|
|
|
99
133
|
formData.append(attIdentifier, objValue.data);
|
|
100
134
|
}
|
|
101
135
|
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
136
|
+
if (attachments) {
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
Object.keys(attachments).reduce((acc, curr) => {
|
|
139
|
+
const objValue = attachments[curr];
|
|
140
|
+
if (objValue && objValue instanceof Array) {
|
|
141
|
+
return [...acc, ...objValue.map((x) => addAttachmentToFormData(x, formData))];
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
return [...acc, addAttachmentToFormData(objValue, formData)];
|
|
145
|
+
}
|
|
146
|
+
}, []);
|
|
147
|
+
}
|
|
112
148
|
return formData;
|
|
113
149
|
};
|
|
114
150
|
const submit = (context, success, error, submitAs = 'multipart/form-data', input_data = null) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -131,7 +167,9 @@ const submit = (context, success, error, submitAs = 'multipart/form-data', input
|
|
|
131
167
|
}
|
|
132
168
|
// submitContentType = submitAs;
|
|
133
169
|
// note: don't send multipart/form-data let browser decide on the content type
|
|
134
|
-
yield (0, exports.request)(context, endpoint, 'POST', formData, success, error,
|
|
170
|
+
yield (0, exports.request)(context, endpoint, 'POST', formData, success, error, {
|
|
171
|
+
'Content-Type': submitContentType
|
|
172
|
+
});
|
|
135
173
|
});
|
|
136
174
|
exports.submit = submit;
|
|
137
175
|
/**
|
|
@@ -232,6 +270,19 @@ class FunctionRuntimeImpl {
|
|
|
232
270
|
},
|
|
233
271
|
_signature: []
|
|
234
272
|
},
|
|
273
|
+
setFocus: {
|
|
274
|
+
_func: (args, data, interpreter) => {
|
|
275
|
+
const element = args[0];
|
|
276
|
+
try {
|
|
277
|
+
const field = interpreter.globals.form.getElement(element.$id);
|
|
278
|
+
interpreter.globals.form.setFocus(field);
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
interpreter.globals.form.logger.error('Invalid argument passed in setFocus. An element is expected');
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
_signature: []
|
|
285
|
+
},
|
|
235
286
|
getData: {
|
|
236
287
|
_func: (args, data, interpreter) => {
|
|
237
288
|
// deprecated. left for backward compatability.
|
|
@@ -279,9 +330,18 @@ class FunctionRuntimeImpl {
|
|
|
279
330
|
const uri = toString(args[0]);
|
|
280
331
|
const httpVerb = toString(args[1]);
|
|
281
332
|
const payload = valueOf(args[2]);
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
333
|
+
let success, error, headers = {};
|
|
334
|
+
if (typeof (args[3]) === 'string') {
|
|
335
|
+
interpreter.globals.form.logger.warn('This usage of request is deprecated. Please see the documentation and update');
|
|
336
|
+
success = valueOf(args[3]);
|
|
337
|
+
error = valueOf(args[4]);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
headers = valueOf(args[3]);
|
|
341
|
+
success = valueOf(args[4]);
|
|
342
|
+
error = valueOf(args[5]);
|
|
343
|
+
}
|
|
344
|
+
(0, exports.request)(interpreter.globals, uri, httpVerb, payload, success, error, headers);
|
|
285
345
|
return {};
|
|
286
346
|
},
|
|
287
347
|
_signature: []
|
|
@@ -327,5 +387,4 @@ class FunctionRuntimeImpl {
|
|
|
327
387
|
return Object.assign(Object.assign({}, defaultFunctions), this.customFunctions);
|
|
328
388
|
}
|
|
329
389
|
}
|
|
330
|
-
|
|
331
|
-
exports.default = FunctionRuntime;
|
|
390
|
+
exports.FunctionRuntime = new FunctionRuntimeImpl();
|
package/lib/rules/RuleEngine.js
CHANGED
|
@@ -6,12 +6,9 @@
|
|
|
6
6
|
*
|
|
7
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
8
|
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
10
|
const json_formula_1 = require("@adobe/json-formula");
|
|
14
|
-
const FunctionRuntime_1 =
|
|
11
|
+
const FunctionRuntime_1 = require("./FunctionRuntime");
|
|
15
12
|
/**
|
|
16
13
|
* Implementation of rule engine
|
|
17
14
|
* @private
|
|
@@ -25,7 +22,7 @@ class RuleEngine {
|
|
|
25
22
|
];
|
|
26
23
|
}
|
|
27
24
|
compileRule(rule) {
|
|
28
|
-
const customFunctions = FunctionRuntime_1.
|
|
25
|
+
const customFunctions = FunctionRuntime_1.FunctionRuntime.getFunctions();
|
|
29
26
|
return new json_formula_1.Formula(rule, customFunctions, undefined, this._globalNames);
|
|
30
27
|
}
|
|
31
28
|
execute(node, data, globals, useValueOf = false) {
|
package/lib/types/Json.d.ts
CHANGED
|
@@ -103,6 +103,7 @@ export declare type FieldJson = BaseJson & TranslationFieldJson & {
|
|
|
103
103
|
export declare type ContainerJson = BaseJson & {
|
|
104
104
|
items: Array<FieldJson | ContainerJson>;
|
|
105
105
|
initialItems?: number;
|
|
106
|
+
activeChild?: string;
|
|
106
107
|
};
|
|
107
108
|
/** Type for `form metadata` based on `adaptive form specification` */
|
|
108
109
|
export declare type MetaDataJson = {
|
package/lib/types/Model.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ConstraintsJson, ContainerJson, FieldJson, FieldsetJson, FormJson, Labe
|
|
|
5
5
|
import RuleEngine from '../rules/RuleEngine';
|
|
6
6
|
import EventQueue from '../controller/EventQueue';
|
|
7
7
|
import DataGroup from '../data/DataGroup';
|
|
8
|
-
import { Logger } from '../
|
|
8
|
+
import { Logger } from '../controller/Logger';
|
|
9
9
|
/**
|
|
10
10
|
* Generic Scriptable field interface. All non-transparent fields which support rule/events
|
|
11
11
|
* should implement this interface
|
|
@@ -124,6 +124,10 @@ export interface BaseModel extends ConstraintsJson, WithController {
|
|
|
124
124
|
* The index of the Field within its parent.
|
|
125
125
|
*/
|
|
126
126
|
readonly index: number;
|
|
127
|
+
/**
|
|
128
|
+
*
|
|
129
|
+
*/
|
|
130
|
+
readonly qualifiedName: string;
|
|
127
131
|
/**
|
|
128
132
|
* Label to be used for the field.
|
|
129
133
|
*/
|
|
@@ -276,6 +280,7 @@ export interface ContainerModel extends BaseModel, ScriptableField {
|
|
|
276
280
|
*/
|
|
277
281
|
indexOf(f: FieldModel | FieldsetModel): number;
|
|
278
282
|
isTransparent(): boolean;
|
|
283
|
+
activeChild: BaseModel | null;
|
|
279
284
|
}
|
|
280
285
|
/**
|
|
281
286
|
* Generic field set model interface.
|
|
@@ -339,7 +344,7 @@ export interface IFileObject {
|
|
|
339
344
|
/**
|
|
340
345
|
* Media type of the file data
|
|
341
346
|
*/
|
|
342
|
-
|
|
347
|
+
type: string;
|
|
343
348
|
/**
|
|
344
349
|
* Data of the file attachment. It can be uri or any file interface specific to channel (in web, it is file object).
|
|
345
350
|
*/
|
package/lib/utils/FormUtils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ContainerModel } from '../types';
|
|
2
|
-
import { FileObject } from '../FileObject';
|
|
3
2
|
/**
|
|
4
3
|
* Utility to generate a random word from seed
|
|
5
4
|
* @param l seed value
|
|
@@ -24,13 +23,6 @@ export declare const getAttachments: (input: ContainerModel) => any;
|
|
|
24
23
|
* @returns file size as bytes (in kb) based on IEC specification
|
|
25
24
|
*/
|
|
26
25
|
export declare const getFileSizeInBytes: (str: any) => number;
|
|
27
|
-
/**
|
|
28
|
-
* Converts number to bytes based on the symbol as per IEC specification
|
|
29
|
-
* @param size size as number
|
|
30
|
-
* @param symbol symbol to use (for example, kb, mb, gb or tb)
|
|
31
|
-
* @returns number as bytes based on the symbol
|
|
32
|
-
*/
|
|
33
|
-
export declare const sizeToBytes: (size: number, symbol: string) => number;
|
|
34
26
|
/**
|
|
35
27
|
* ID Generator
|
|
36
28
|
* @param initial
|
|
@@ -40,16 +32,16 @@ export declare const sizeToBytes: (size: number, symbol: string) => number;
|
|
|
40
32
|
export declare const IdGenerator: (initial?: number) => Generator<string, void, string>;
|
|
41
33
|
/**
|
|
42
34
|
* Utility to extract {@link FileObject} from string or HTML File data type
|
|
43
|
-
* @param
|
|
35
|
+
* @param file
|
|
44
36
|
* @returns list of {@link FileObject}
|
|
45
37
|
*/
|
|
46
|
-
export declare const extractFileInfo: (
|
|
38
|
+
export declare const extractFileInfo: (file: any) => any;
|
|
47
39
|
/**
|
|
48
40
|
* Utility to convert data URI to a `blob` object
|
|
49
41
|
* @param dataURI uri to convert to blob
|
|
50
42
|
* @returns `Blob` object for the data URI
|
|
51
43
|
*/
|
|
52
44
|
export declare const dataURItoBlob: (dataURI: string) => {
|
|
53
|
-
blob: Blob;
|
|
54
45
|
name: string;
|
|
55
|
-
|
|
46
|
+
blob: Blob;
|
|
47
|
+
} | null;
|
package/lib/utils/FormUtils.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
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
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.dataURItoBlob = exports.extractFileInfo = exports.IdGenerator = exports.
|
|
10
|
+
exports.dataURItoBlob = exports.extractFileInfo = exports.IdGenerator = exports.getFileSizeInBytes = exports.getAttachments = exports.isEmpty = exports.randomWord = void 0;
|
|
11
11
|
/**
|
|
12
12
|
* Defines generic utilities to interact with form runtime model
|
|
13
13
|
*/
|
|
@@ -85,7 +85,7 @@ const getFileSizeInBytes = (str) => {
|
|
|
85
85
|
if (typeof str === 'string') {
|
|
86
86
|
const matches = fileSizeRegex.exec(str.trim());
|
|
87
87
|
if (matches != null) {
|
|
88
|
-
retVal =
|
|
88
|
+
retVal = sizeToBytes(parseFloat(matches[1]), (matches[2] || 'kb').toUpperCase());
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
return retVal;
|
|
@@ -103,7 +103,6 @@ const sizeToBytes = (size, symbol) => {
|
|
|
103
103
|
const i = Math.pow(1024, sizes[symbol]);
|
|
104
104
|
return Math.round(size * i);
|
|
105
105
|
};
|
|
106
|
-
exports.sizeToBytes = sizeToBytes;
|
|
107
106
|
/**
|
|
108
107
|
* ID Generator
|
|
109
108
|
* @param initial
|
|
@@ -138,12 +137,11 @@ const IdGenerator = function* (initial = 50) {
|
|
|
138
137
|
exports.IdGenerator = IdGenerator;
|
|
139
138
|
/**
|
|
140
139
|
* Utility to extract {@link FileObject} from string or HTML File data type
|
|
141
|
-
* @param
|
|
140
|
+
* @param file
|
|
142
141
|
* @returns list of {@link FileObject}
|
|
143
142
|
*/
|
|
144
|
-
const extractFileInfo = (
|
|
145
|
-
|
|
146
|
-
.map((file) => {
|
|
143
|
+
const extractFileInfo = (file) => {
|
|
144
|
+
if (file !== null) {
|
|
147
145
|
let retVal = null;
|
|
148
146
|
if (file instanceof FileObject_1.FileObject) {
|
|
149
147
|
retVal = file;
|
|
@@ -152,20 +150,23 @@ const extractFileInfo = (files) => {
|
|
|
152
150
|
// case: file object
|
|
153
151
|
retVal = {
|
|
154
152
|
name: file.name,
|
|
155
|
-
|
|
153
|
+
type: file.type,
|
|
156
154
|
size: file.size,
|
|
157
155
|
data: file
|
|
158
156
|
};
|
|
159
157
|
}
|
|
160
158
|
else if (typeof file === 'string' && (0, ValidationUtils_1.isDataUrl)(file)) {
|
|
161
159
|
// case: data URL
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
name
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
const result = (0, exports.dataURItoBlob)(file);
|
|
161
|
+
if (result !== null) {
|
|
162
|
+
const { blob, name } = result;
|
|
163
|
+
retVal = {
|
|
164
|
+
name: name,
|
|
165
|
+
type: blob.type,
|
|
166
|
+
size: blob.size,
|
|
167
|
+
data: blob
|
|
168
|
+
};
|
|
169
|
+
}
|
|
169
170
|
}
|
|
170
171
|
else {
|
|
171
172
|
// case: string as file object
|
|
@@ -179,20 +180,23 @@ const extractFileInfo = (files) => {
|
|
|
179
180
|
}
|
|
180
181
|
if (typeof (jFile === null || jFile === void 0 ? void 0 : jFile.data) === 'string' && (0, ValidationUtils_1.isDataUrl)(jFile === null || jFile === void 0 ? void 0 : jFile.data)) {
|
|
181
182
|
// case: data URL
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
183
|
+
const result = (0, exports.dataURItoBlob)(jFile === null || jFile === void 0 ? void 0 : jFile.data);
|
|
184
|
+
if (result !== null) {
|
|
185
|
+
const blob = result.blob;
|
|
186
|
+
retVal = {
|
|
187
|
+
name: jFile === null || jFile === void 0 ? void 0 : jFile.name,
|
|
188
|
+
type: jFile === null || jFile === void 0 ? void 0 : jFile.type,
|
|
189
|
+
size: blob.size,
|
|
190
|
+
data: blob
|
|
191
|
+
};
|
|
192
|
+
}
|
|
189
193
|
}
|
|
190
194
|
else if (typeof jFile === 'string') {
|
|
191
195
|
// case: data as external url
|
|
192
196
|
const fileName = jFile.split('/').pop();
|
|
193
197
|
retVal = {
|
|
194
198
|
name: fileName,
|
|
195
|
-
|
|
199
|
+
type: 'application/octet-stream',
|
|
196
200
|
size: 0,
|
|
197
201
|
data: jFile
|
|
198
202
|
};
|
|
@@ -201,14 +205,20 @@ const extractFileInfo = (files) => {
|
|
|
201
205
|
// todo: just added for ease of integration for the view layer
|
|
202
206
|
retVal = {
|
|
203
207
|
name: jFile === null || jFile === void 0 ? void 0 : jFile.name,
|
|
204
|
-
|
|
208
|
+
type: jFile === null || jFile === void 0 ? void 0 : jFile.type,
|
|
205
209
|
size: jFile === null || jFile === void 0 ? void 0 : jFile.size,
|
|
206
210
|
data: jFile === null || jFile === void 0 ? void 0 : jFile.data
|
|
207
211
|
};
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
if (retVal !== null && retVal.data != null) {
|
|
215
|
+
return new FileObject_1.FileObject(retVal);
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
212
222
|
};
|
|
213
223
|
exports.extractFileInfo = extractFileInfo;
|
|
214
224
|
/**
|
|
@@ -217,34 +227,28 @@ exports.extractFileInfo = extractFileInfo;
|
|
|
217
227
|
* @returns `Blob` object for the data URI
|
|
218
228
|
*/
|
|
219
229
|
const dataURItoBlob = (dataURI) => {
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
const regex = /^data:([a-z]+\/[a-z0-9-+.]+)?(?:;name=([^;]+))?(;base64)?,(.+)$/;
|
|
231
|
+
const groups = regex.exec(dataURI);
|
|
232
|
+
if (groups !== null) {
|
|
233
|
+
const type = groups[1] || '';
|
|
234
|
+
const name = groups[2] || 'unknown';
|
|
235
|
+
const isBase64 = typeof groups[3] === 'string';
|
|
236
|
+
if (isBase64) {
|
|
237
|
+
const binary = atob(groups[4]);
|
|
238
|
+
const array = [];
|
|
239
|
+
for (let i = 0; i < binary.length; i++) {
|
|
240
|
+
array.push(binary.charCodeAt(i));
|
|
241
|
+
}
|
|
242
|
+
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
243
|
+
return { name, blob };
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
const blob = new window.Blob([groups[4]], { type });
|
|
247
|
+
return { name, blob };
|
|
248
|
+
}
|
|
234
249
|
}
|
|
235
250
|
else {
|
|
236
|
-
|
|
237
|
-
// we only have the name case here.
|
|
238
|
-
name = properties[0].split('=')[1];
|
|
239
|
-
}
|
|
240
|
-
// Built the Uint8Array Blob parameter from the base64 string.
|
|
241
|
-
const binary = atob(splitted[1]);
|
|
242
|
-
const array = [];
|
|
243
|
-
for (let i = 0; i < binary.length; i++) {
|
|
244
|
-
array.push(binary.charCodeAt(i));
|
|
251
|
+
return null;
|
|
245
252
|
}
|
|
246
|
-
// Create the blob object
|
|
247
|
-
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
248
|
-
return { blob, name };
|
|
249
253
|
};
|
|
250
254
|
exports.dataURItoBlob = dataURItoBlob;
|
|
@@ -149,5 +149,22 @@ export declare const Constraints: {
|
|
|
149
149
|
valid: boolean;
|
|
150
150
|
value: any;
|
|
151
151
|
};
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* @param constraint
|
|
155
|
+
* @param value
|
|
156
|
+
*/
|
|
157
|
+
accept: (constraint: string[], value: any) => {
|
|
158
|
+
valid: boolean;
|
|
159
|
+
value: any;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* @param constraint
|
|
163
|
+
* @param value
|
|
164
|
+
*/
|
|
165
|
+
maxFileSize: (constraint: number | string, value: any) => {
|
|
166
|
+
valid: boolean;
|
|
167
|
+
value: any;
|
|
168
|
+
};
|
|
152
169
|
};
|
|
153
170
|
export {};
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.Constraints = exports.ValidConstraints = exports.isDataUrl = void 0;
|
|
11
|
+
const FormUtils_1 = require("./FormUtils");
|
|
12
|
+
const FileObject_1 = require("../FileObject");
|
|
11
13
|
/**
|
|
12
14
|
* Defines generic utilities to validate form runtime model based on the constraints defined
|
|
13
15
|
* as per `adaptive form specification`
|
|
@@ -56,6 +58,16 @@ const checkNumber = (inputVal) => {
|
|
|
56
58
|
value, valid
|
|
57
59
|
};
|
|
58
60
|
};
|
|
61
|
+
const checkInteger = (inputVal) => {
|
|
62
|
+
let value = parseFloat(inputVal);
|
|
63
|
+
const valid = !isNaN(value) && Math.round(value) === value;
|
|
64
|
+
if (!valid) {
|
|
65
|
+
value = inputVal;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
value, valid
|
|
69
|
+
};
|
|
70
|
+
};
|
|
59
71
|
/**
|
|
60
72
|
* Wraps a non-null value and not an array value into an array
|
|
61
73
|
* @param inputVal input value
|
|
@@ -88,6 +100,33 @@ const checkBool = (inputVal) => {
|
|
|
88
100
|
const value = typeof inputVal === 'boolean' ? inputVal : (valid ? inputVal === 'true' : inputVal);
|
|
89
101
|
return { valid, value };
|
|
90
102
|
};
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
* @param inputVal
|
|
106
|
+
*/
|
|
107
|
+
const checkFile = (inputVal) => {
|
|
108
|
+
const value = (0, FormUtils_1.extractFileInfo)(inputVal);
|
|
109
|
+
const valid = value !== null;
|
|
110
|
+
return {
|
|
111
|
+
value: valid ? value : inputVal,
|
|
112
|
+
valid
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* validates whether the mediaType is one present in the accepts list
|
|
117
|
+
* @param mediaType
|
|
118
|
+
* @param accepts
|
|
119
|
+
*/
|
|
120
|
+
const matchMediaType = (mediaType, accepts) => {
|
|
121
|
+
return !mediaType || accepts.some((accept) => {
|
|
122
|
+
const trimmedAccept = accept.trim();
|
|
123
|
+
const prefixAccept = trimmedAccept.split('/')[0];
|
|
124
|
+
const suffixAccept = trimmedAccept.split('.')[1];
|
|
125
|
+
return ((trimmedAccept.includes('*') && mediaType.startsWith(prefixAccept)) ||
|
|
126
|
+
(trimmedAccept.includes('.') && mediaType.endsWith(suffixAccept)) ||
|
|
127
|
+
(trimmedAccept === mediaType));
|
|
128
|
+
});
|
|
129
|
+
};
|
|
91
130
|
/**
|
|
92
131
|
* Validates an array of values using a validator function.
|
|
93
132
|
* @param inputVal
|
|
@@ -154,18 +193,25 @@ exports.Constraints = {
|
|
|
154
193
|
value = res.value;
|
|
155
194
|
break;
|
|
156
195
|
case 'integer':
|
|
157
|
-
|
|
158
|
-
valid =
|
|
159
|
-
|
|
160
|
-
value = inputVal;
|
|
161
|
-
}
|
|
196
|
+
res = checkInteger(inputVal);
|
|
197
|
+
valid = res.valid;
|
|
198
|
+
value = res.value;
|
|
162
199
|
break;
|
|
163
|
-
case '
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
200
|
+
case 'integer[]':
|
|
201
|
+
res = partitionArray(inputVal, checkInteger);
|
|
202
|
+
valid = res[1].length === 0;
|
|
203
|
+
value = valid ? res[0] : inputVal;
|
|
204
|
+
break;
|
|
205
|
+
case 'file':
|
|
206
|
+
// for file types only, we support setting value via an array
|
|
207
|
+
res = checkFile(inputVal instanceof Array ? inputVal[0] : inputVal);
|
|
208
|
+
valid = res.valid;
|
|
209
|
+
value = res.value;
|
|
210
|
+
break;
|
|
211
|
+
case 'file[]':
|
|
212
|
+
res = partitionArray(inputVal, checkFile);
|
|
213
|
+
valid = res[1].length === 0;
|
|
214
|
+
value = valid ? res[0] : inputVal;
|
|
169
215
|
break;
|
|
170
216
|
case 'number[]':
|
|
171
217
|
res = partitionArray(inputVal, checkNumber);
|
|
@@ -338,5 +384,35 @@ exports.Constraints = {
|
|
|
338
384
|
valid: constraint.indexOf(value) > -1,
|
|
339
385
|
value
|
|
340
386
|
};
|
|
387
|
+
},
|
|
388
|
+
/**
|
|
389
|
+
*
|
|
390
|
+
* @param constraint
|
|
391
|
+
* @param value
|
|
392
|
+
*/
|
|
393
|
+
accept: (constraint, value) => {
|
|
394
|
+
if (!constraint || constraint.length === 0 || value === null || value === undefined) {
|
|
395
|
+
return {
|
|
396
|
+
valid: true,
|
|
397
|
+
value
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const tempValue = value instanceof Array ? value : [value];
|
|
401
|
+
const invalidFile = tempValue.some((file) => !matchMediaType(file.type, constraint));
|
|
402
|
+
return {
|
|
403
|
+
valid: !invalidFile,
|
|
404
|
+
value
|
|
405
|
+
};
|
|
406
|
+
},
|
|
407
|
+
/**
|
|
408
|
+
* @param constraint
|
|
409
|
+
* @param value
|
|
410
|
+
*/
|
|
411
|
+
maxFileSize: (constraint, value) => {
|
|
412
|
+
const sizeLimit = typeof constraint === 'string' ? (0, FormUtils_1.getFileSizeInBytes)(constraint) : constraint;
|
|
413
|
+
return {
|
|
414
|
+
valid: !(value instanceof FileObject_1.FileObject) || value.size <= sizeLimit,
|
|
415
|
+
value
|
|
416
|
+
};
|
|
341
417
|
}
|
|
342
418
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aemforms/af-core",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.17",
|
|
4
4
|
"description": "Core Module for Forms Runtime",
|
|
5
5
|
"author": "Adobe Systems",
|
|
6
6
|
"license": "Adobe Proprietary",
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@adobe/json-formula": "^0.1.44",
|
|
38
|
-
"@aemforms/af-formatters": "^0.22.
|
|
38
|
+
"@aemforms/af-formatters": "^0.22.17"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/jest": "^27.5.1",
|
|
42
42
|
"@types/lodash": "^4.14.171",
|
|
43
43
|
"@typescript-eslint/eslint-plugin": "^4.28.2",
|
|
44
44
|
"@typescript-eslint/parser": "^4.28.2",
|
|
45
|
+
"blob-polyfill": "^7.0.20220408",
|
|
45
46
|
"eslint": "^7.30.0",
|
|
46
47
|
"eslint-config-standard": "^16.0.3",
|
|
47
48
|
"eslint-plugin-import": "^2.23.4",
|