@aemforms/af-core 0.22.16 → 0.22.18
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 +22 -0
- package/lib/BaseNode.js +86 -9
- package/lib/Checkbox.d.ts +8 -0
- package/lib/CheckboxGroup.js +3 -0
- package/lib/Container.d.ts +39 -196
- package/lib/Container.js +30 -3
- package/lib/Field.d.ts +36 -20
- package/lib/Field.js +211 -50
- package/lib/FileObject.d.ts +2 -0
- package/lib/FileObject.js +9 -0
- package/lib/FileUpload.d.ts +4 -13
- package/lib/FileUpload.js +29 -131
- package/lib/Form.d.ts +41 -212
- package/lib/Form.js +12 -35
- package/lib/FormInstance.d.ts +1 -1
- package/lib/FormInstance.js +3 -25
- package/lib/Scriptable.d.ts +1 -1
- package/lib/Scriptable.js +4 -4
- 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/rules/FunctionRuntime.d.ts +4 -0
- package/lib/rules/FunctionRuntime.js +13 -0
- package/lib/types/Json.d.ts +4 -0
- package/lib/types/Model.d.ts +12 -6
- package/lib/utils/FormUtils.d.ts +4 -12
- package/lib/utils/FormUtils.js +56 -49
- package/lib/utils/ValidationUtils.d.ts +17 -0
- package/lib/utils/ValidationUtils.js +101 -11
- package/package.json +3 -2
package/lib/Scriptable.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { BaseNode } from './BaseNode';
|
|
|
7
7
|
declare abstract class Scriptable<T extends RulesJson> extends BaseNode<T> implements ScriptableField {
|
|
8
8
|
private _events;
|
|
9
9
|
private _rules;
|
|
10
|
-
|
|
10
|
+
getRules(): import("./types").Items<string>;
|
|
11
11
|
private getCompiledRule;
|
|
12
12
|
private getCompiledEvent;
|
|
13
13
|
private applyUpdates;
|
package/lib/Scriptable.js
CHANGED
|
@@ -18,12 +18,12 @@ class Scriptable extends BaseNode_1.BaseNode {
|
|
|
18
18
|
this._events = {};
|
|
19
19
|
this._rules = {};
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
return this._jsonModel.rules
|
|
21
|
+
getRules() {
|
|
22
|
+
return typeof this._jsonModel.rules !== 'object' ? {} : this._jsonModel.rules;
|
|
23
23
|
}
|
|
24
24
|
getCompiledRule(eName, rule) {
|
|
25
25
|
if (!(eName in this._rules)) {
|
|
26
|
-
const eString = rule || this.
|
|
26
|
+
const eString = rule || this.getRules()[eName];
|
|
27
27
|
if (typeof eString === 'string' && eString.length > 0) {
|
|
28
28
|
try {
|
|
29
29
|
this._rules[eName] = this.ruleEngine.compileRule(eString);
|
|
@@ -76,7 +76,7 @@ class Scriptable extends BaseNode_1.BaseNode {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
executeAllRules(context) {
|
|
79
|
-
const entries = Object.entries(this.
|
|
79
|
+
const entries = Object.entries(this.getRules());
|
|
80
80
|
if (entries.length > 0) {
|
|
81
81
|
const scope = this.getExpressionScope();
|
|
82
82
|
entries.forEach(([prop, rule]) => {
|
|
@@ -57,6 +57,7 @@ export declare class Change extends ActionImpl {
|
|
|
57
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
58
|
*/
|
|
59
59
|
constructor(payload: ChangePayload, dispatch?: boolean);
|
|
60
|
+
withAdditionalChange(change: Change): Change;
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
63
|
* 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
|
|
@@ -60,6 +60,9 @@ class Change extends ActionImpl {
|
|
|
60
60
|
constructor(payload, dispatch = false) {
|
|
61
61
|
super(payload, 'change', { dispatch });
|
|
62
62
|
}
|
|
63
|
+
withAdditionalChange(change) {
|
|
64
|
+
return new Change(this.payload.changes.concat(change.payload.changes), this.metadata);
|
|
65
|
+
}
|
|
63
66
|
}
|
|
64
67
|
exports.Change = Change;
|
|
65
68
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Action, BaseJson } from '../types';
|
|
5
5
|
import { BaseNode } from '../BaseNode';
|
|
6
|
-
import { Logger } from '
|
|
6
|
+
import { Logger } from './Logger';
|
|
7
7
|
/**
|
|
8
8
|
* Implementation of event queue. When a user event, like change or click, is captured the expression to be evaluated
|
|
9
9
|
* must be put in an Event Queue and then evaluated.
|
|
@@ -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
|
-
const
|
|
10
|
+
const Logger_1 = require("./Logger");
|
|
11
11
|
/**
|
|
12
12
|
* Implementation of event node
|
|
13
13
|
* @private
|
|
@@ -39,7 +39,7 @@ class EventNode {
|
|
|
39
39
|
* @private
|
|
40
40
|
*/
|
|
41
41
|
class EventQueue {
|
|
42
|
-
constructor(logger = new
|
|
42
|
+
constructor(logger = new Logger_1.Logger('off')) {
|
|
43
43
|
this.logger = logger;
|
|
44
44
|
this._isProcessing = false;
|
|
45
45
|
this._pendingEvents = [];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare type LogFunction = 'info' | 'warn' | 'error' | 'debug';
|
|
2
|
+
/**
|
|
3
|
+
* Logging levels.
|
|
4
|
+
*/
|
|
5
|
+
export declare type LogLevel = 'off' | LogFunction;
|
|
6
|
+
/**
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
export declare class Logger {
|
|
10
|
+
debug(msg: string): void;
|
|
11
|
+
info(msg: string): void;
|
|
12
|
+
warn(msg: string): void;
|
|
13
|
+
error(msg: string): void;
|
|
14
|
+
log(msg: string, level: LogFunction): void;
|
|
15
|
+
private logLevel;
|
|
16
|
+
constructor(logLevel?: LogLevel);
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Logger = void 0;
|
|
4
|
+
const levels = {
|
|
5
|
+
off: 0,
|
|
6
|
+
debug: 1,
|
|
7
|
+
info: 2,
|
|
8
|
+
warn: 3,
|
|
9
|
+
error: 4
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
class Logger {
|
|
15
|
+
constructor(logLevel = 'off') {
|
|
16
|
+
this.logLevel = levels[logLevel];
|
|
17
|
+
}
|
|
18
|
+
debug(msg) {
|
|
19
|
+
this.log(msg, 'debug');
|
|
20
|
+
}
|
|
21
|
+
info(msg) {
|
|
22
|
+
this.log(msg, 'info');
|
|
23
|
+
}
|
|
24
|
+
warn(msg) {
|
|
25
|
+
this.log(msg, 'warn');
|
|
26
|
+
}
|
|
27
|
+
error(msg) {
|
|
28
|
+
this.log(msg, 'error');
|
|
29
|
+
}
|
|
30
|
+
log(msg, level) {
|
|
31
|
+
if (this.logLevel !== 0 && this.logLevel <= levels[level]) {
|
|
32
|
+
console[level](msg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.Logger = Logger;
|
package/lib/data/DataValue.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export default class DataValue {
|
|
|
14
14
|
valueOf(): any;
|
|
15
15
|
get $name(): string | number;
|
|
16
16
|
get $value(): any;
|
|
17
|
-
setValue(typedValue: any, originalValue: any): void;
|
|
17
|
+
setValue(typedValue: any, originalValue: any, fromField: FieldModel): void;
|
|
18
18
|
get $type(): string;
|
|
19
19
|
$bindToField(field: FieldModel): void;
|
|
20
20
|
$convertToDataValue(): DataValue;
|
package/lib/data/DataValue.js
CHANGED
|
@@ -26,10 +26,12 @@ class DataValue {
|
|
|
26
26
|
get $value() {
|
|
27
27
|
return this.$_value;
|
|
28
28
|
}
|
|
29
|
-
setValue(typedValue, originalValue) {
|
|
29
|
+
setValue(typedValue, originalValue, fromField) {
|
|
30
30
|
this.$_value = typedValue;
|
|
31
31
|
this.$_fields.forEach(x => {
|
|
32
|
-
x
|
|
32
|
+
if (fromField !== x) {
|
|
33
|
+
x.value = originalValue;
|
|
34
|
+
}
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
37
|
get $type() {
|
|
@@ -32,6 +32,10 @@ declare class FunctionRuntimeImpl {
|
|
|
32
32
|
_func: (args: Array<unknown>, data: unknown, interpreter: any) => any;
|
|
33
33
|
_signature: never[];
|
|
34
34
|
};
|
|
35
|
+
setFocus: {
|
|
36
|
+
_func: (args: Array<unknown>, data: unknown, interpreter: any) => void;
|
|
37
|
+
_signature: never[];
|
|
38
|
+
};
|
|
35
39
|
getData: {
|
|
36
40
|
_func: (args: unknown, data: unknown, interpreter: any) => any;
|
|
37
41
|
_signature: never[];
|
|
@@ -270,6 +270,19 @@ class FunctionRuntimeImpl {
|
|
|
270
270
|
},
|
|
271
271
|
_signature: []
|
|
272
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
|
+
},
|
|
273
286
|
getData: {
|
|
274
287
|
_func: (args, data, interpreter) => {
|
|
275
288
|
// deprecated. left for backward compatability.
|
package/lib/types/Json.d.ts
CHANGED
|
@@ -82,6 +82,9 @@ export declare type BaseJson = TranslationBaseJson & RulesJson & ConstraintsJson
|
|
|
82
82
|
properties?: {
|
|
83
83
|
[key: string]: any;
|
|
84
84
|
};
|
|
85
|
+
screenReaderText?: string;
|
|
86
|
+
tooltip?: string;
|
|
87
|
+
altText?: string;
|
|
85
88
|
};
|
|
86
89
|
/** Type for `form field properties`which can be translated based on `adaptive form specification` */
|
|
87
90
|
declare type TranslationFieldJson = {
|
|
@@ -103,6 +106,7 @@ export declare type FieldJson = BaseJson & TranslationFieldJson & {
|
|
|
103
106
|
export declare type ContainerJson = BaseJson & {
|
|
104
107
|
items: Array<FieldJson | ContainerJson>;
|
|
105
108
|
initialItems?: number;
|
|
109
|
+
activeChild?: string;
|
|
106
110
|
};
|
|
107
111
|
/** Type for `form metadata` based on `adaptive form specification` */
|
|
108
112
|
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
|
|
@@ -39,14 +39,15 @@ interface WithState<T> {
|
|
|
39
39
|
*/
|
|
40
40
|
getState: () => State<T>;
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
export declare type State<T> = T extends ContainerJson ? T & {
|
|
44
|
-
id: string;
|
|
45
|
-
items: Array<State<FieldJson | ContainerJson>>;
|
|
46
|
-
} : T & {
|
|
42
|
+
declare type stateProps = {
|
|
47
43
|
id: string;
|
|
44
|
+
index: number;
|
|
48
45
|
':type': string;
|
|
49
46
|
};
|
|
47
|
+
/** Generic type for a form object state */
|
|
48
|
+
export declare type State<T> = stateProps & (T extends ContainerJson ? T & {
|
|
49
|
+
items: Array<State<FieldJson | ContainerJson>>;
|
|
50
|
+
} : T);
|
|
50
51
|
/**
|
|
51
52
|
* @private
|
|
52
53
|
*/
|
|
@@ -124,6 +125,10 @@ export interface BaseModel extends ConstraintsJson, WithController {
|
|
|
124
125
|
* The index of the Field within its parent.
|
|
125
126
|
*/
|
|
126
127
|
readonly index: number;
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
*/
|
|
131
|
+
readonly qualifiedName: string;
|
|
127
132
|
/**
|
|
128
133
|
* Label to be used for the field.
|
|
129
134
|
*/
|
|
@@ -276,6 +281,7 @@ export interface ContainerModel extends BaseModel, ScriptableField {
|
|
|
276
281
|
*/
|
|
277
282
|
indexOf(f: FieldModel | FieldsetModel): number;
|
|
278
283
|
isTransparent(): boolean;
|
|
284
|
+
activeChild: BaseModel | null;
|
|
279
285
|
}
|
|
280
286
|
/**
|
|
281
287
|
* Generic field set model interface.
|
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;
|
|
@@ -159,13 +157,16 @@ const extractFileInfo = (files) => {
|
|
|
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
|
+
mediaType: blob.type,
|
|
166
|
+
size: blob.size,
|
|
167
|
+
data: blob
|
|
168
|
+
};
|
|
169
|
+
}
|
|
169
170
|
}
|
|
170
171
|
else {
|
|
171
172
|
// case: string as file object
|
|
@@ -173,19 +174,25 @@ const extractFileInfo = (files) => {
|
|
|
173
174
|
try {
|
|
174
175
|
jFile = JSON.parse(file);
|
|
175
176
|
retVal = jFile;
|
|
177
|
+
if (!retVal.mediaType) {
|
|
178
|
+
retVal.mediaType = retVal.type;
|
|
179
|
+
}
|
|
176
180
|
}
|
|
177
181
|
catch (ex) {
|
|
178
182
|
// do nothing
|
|
179
183
|
}
|
|
180
184
|
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
185
|
// case: data URL
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
const result = (0, exports.dataURItoBlob)(jFile === null || jFile === void 0 ? void 0 : jFile.data);
|
|
187
|
+
if (result !== null) {
|
|
188
|
+
const blob = result.blob;
|
|
189
|
+
retVal = {
|
|
190
|
+
name: jFile === null || jFile === void 0 ? void 0 : jFile.name,
|
|
191
|
+
mediaType: (jFile === null || jFile === void 0 ? void 0 : jFile.type) || (jFile === null || jFile === void 0 ? void 0 : jFile.mediaType),
|
|
192
|
+
size: blob.size,
|
|
193
|
+
data: blob
|
|
194
|
+
};
|
|
195
|
+
}
|
|
189
196
|
}
|
|
190
197
|
else if (typeof jFile === 'string') {
|
|
191
198
|
// case: data as external url
|
|
@@ -207,8 +214,14 @@ const extractFileInfo = (files) => {
|
|
|
207
214
|
};
|
|
208
215
|
}
|
|
209
216
|
}
|
|
210
|
-
|
|
211
|
-
|
|
217
|
+
if (retVal !== null && retVal.data != null) {
|
|
218
|
+
return new FileObject_1.FileObject(retVal);
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
212
225
|
};
|
|
213
226
|
exports.extractFileInfo = extractFileInfo;
|
|
214
227
|
/**
|
|
@@ -217,34 +230,28 @@ exports.extractFileInfo = extractFileInfo;
|
|
|
217
230
|
* @returns `Blob` object for the data URI
|
|
218
231
|
*/
|
|
219
232
|
const dataURItoBlob = (dataURI) => {
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
233
|
+
const regex = /^data:([a-z]+\/[a-z0-9-+.]+)?(?:;name=([^;]+))?(;base64)?,(.+)$/;
|
|
234
|
+
const groups = regex.exec(dataURI);
|
|
235
|
+
if (groups !== null) {
|
|
236
|
+
const type = groups[1] || '';
|
|
237
|
+
const name = groups[2] || 'unknown';
|
|
238
|
+
const isBase64 = typeof groups[3] === 'string';
|
|
239
|
+
if (isBase64) {
|
|
240
|
+
const binary = atob(groups[4]);
|
|
241
|
+
const array = [];
|
|
242
|
+
for (let i = 0; i < binary.length; i++) {
|
|
243
|
+
array.push(binary.charCodeAt(i));
|
|
244
|
+
}
|
|
245
|
+
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
246
|
+
return { name, blob };
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
const blob = new window.Blob([groups[4]], { type });
|
|
250
|
+
return { name, blob };
|
|
251
|
+
}
|
|
234
252
|
}
|
|
235
253
|
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));
|
|
254
|
+
return null;
|
|
245
255
|
}
|
|
246
|
-
// Create the blob object
|
|
247
|
-
const blob = new window.Blob([new Uint8Array(array)], { type });
|
|
248
|
-
return { blob, name };
|
|
249
256
|
};
|
|
250
257
|
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`
|
|
@@ -47,6 +49,11 @@ exports.isDataUrl = isDataUrl;
|
|
|
47
49
|
* @returns {@link ValidationResult | Validation result}
|
|
48
50
|
*/
|
|
49
51
|
const checkNumber = (inputVal) => {
|
|
52
|
+
if (inputVal === '' || inputVal == null) {
|
|
53
|
+
return {
|
|
54
|
+
value: '', valid: true
|
|
55
|
+
};
|
|
56
|
+
}
|
|
50
57
|
let value = parseFloat(inputVal);
|
|
51
58
|
const valid = !isNaN(value);
|
|
52
59
|
if (!valid) {
|
|
@@ -56,6 +63,25 @@ const checkNumber = (inputVal) => {
|
|
|
56
63
|
value, valid
|
|
57
64
|
};
|
|
58
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @param inputVal
|
|
69
|
+
*/
|
|
70
|
+
const checkInteger = (inputVal) => {
|
|
71
|
+
if (inputVal == '' || inputVal == null) {
|
|
72
|
+
return {
|
|
73
|
+
value: '', valid: true
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
let value = parseFloat(inputVal);
|
|
77
|
+
const valid = !isNaN(value) && Math.round(value) === value;
|
|
78
|
+
if (!valid) {
|
|
79
|
+
value = inputVal;
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
value, valid
|
|
83
|
+
};
|
|
84
|
+
};
|
|
59
85
|
/**
|
|
60
86
|
* Wraps a non-null value and not an array value into an array
|
|
61
87
|
* @param inputVal input value
|
|
@@ -88,6 +114,33 @@ const checkBool = (inputVal) => {
|
|
|
88
114
|
const value = typeof inputVal === 'boolean' ? inputVal : (valid ? inputVal === 'true' : inputVal);
|
|
89
115
|
return { valid, value };
|
|
90
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
*
|
|
119
|
+
* @param inputVal
|
|
120
|
+
*/
|
|
121
|
+
const checkFile = (inputVal) => {
|
|
122
|
+
const value = (0, FormUtils_1.extractFileInfo)(inputVal);
|
|
123
|
+
const valid = value !== null;
|
|
124
|
+
return {
|
|
125
|
+
value: valid ? value : inputVal,
|
|
126
|
+
valid
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* validates whether the mediaType is one present in the accepts list
|
|
131
|
+
* @param mediaType
|
|
132
|
+
* @param accepts
|
|
133
|
+
*/
|
|
134
|
+
const matchMediaType = (mediaType, accepts) => {
|
|
135
|
+
return !mediaType || accepts.some((accept) => {
|
|
136
|
+
const trimmedAccept = accept.trim();
|
|
137
|
+
const prefixAccept = trimmedAccept.split('/')[0];
|
|
138
|
+
const suffixAccept = trimmedAccept.split('.')[1];
|
|
139
|
+
return ((trimmedAccept.includes('*') && mediaType.startsWith(prefixAccept)) ||
|
|
140
|
+
(trimmedAccept.includes('.') && mediaType.endsWith(suffixAccept)) ||
|
|
141
|
+
(trimmedAccept === mediaType));
|
|
142
|
+
});
|
|
143
|
+
};
|
|
91
144
|
/**
|
|
92
145
|
* Validates an array of values using a validator function.
|
|
93
146
|
* @param inputVal
|
|
@@ -154,18 +207,25 @@ exports.Constraints = {
|
|
|
154
207
|
value = res.value;
|
|
155
208
|
break;
|
|
156
209
|
case 'integer':
|
|
157
|
-
|
|
158
|
-
valid =
|
|
159
|
-
|
|
160
|
-
value = inputVal;
|
|
161
|
-
}
|
|
210
|
+
res = checkInteger(inputVal);
|
|
211
|
+
valid = res.valid;
|
|
212
|
+
value = res.value;
|
|
162
213
|
break;
|
|
163
|
-
case '
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
214
|
+
case 'integer[]':
|
|
215
|
+
res = partitionArray(inputVal, checkInteger);
|
|
216
|
+
valid = res[1].length === 0;
|
|
217
|
+
value = valid ? res[0] : inputVal;
|
|
218
|
+
break;
|
|
219
|
+
case 'file':
|
|
220
|
+
// for file types only, we support setting value via an array
|
|
221
|
+
res = checkFile(inputVal instanceof Array ? inputVal[0] : inputVal);
|
|
222
|
+
valid = res.valid;
|
|
223
|
+
value = res.value;
|
|
224
|
+
break;
|
|
225
|
+
case 'file[]':
|
|
226
|
+
res = partitionArray(inputVal, checkFile);
|
|
227
|
+
valid = res[1].length === 0;
|
|
228
|
+
value = valid ? res[0] : inputVal;
|
|
169
229
|
break;
|
|
170
230
|
case 'number[]':
|
|
171
231
|
res = partitionArray(inputVal, checkNumber);
|
|
@@ -338,5 +398,35 @@ exports.Constraints = {
|
|
|
338
398
|
valid: constraint.indexOf(value) > -1,
|
|
339
399
|
value
|
|
340
400
|
};
|
|
401
|
+
},
|
|
402
|
+
/**
|
|
403
|
+
*
|
|
404
|
+
* @param constraint
|
|
405
|
+
* @param value
|
|
406
|
+
*/
|
|
407
|
+
accept: (constraint, value) => {
|
|
408
|
+
if (!constraint || constraint.length === 0 || value === null || value === undefined) {
|
|
409
|
+
return {
|
|
410
|
+
valid: true,
|
|
411
|
+
value
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const tempValue = value instanceof Array ? value : [value];
|
|
415
|
+
const invalidFile = tempValue.some((file) => !matchMediaType(file.type, constraint));
|
|
416
|
+
return {
|
|
417
|
+
valid: !invalidFile,
|
|
418
|
+
value
|
|
419
|
+
};
|
|
420
|
+
},
|
|
421
|
+
/**
|
|
422
|
+
* @param constraint
|
|
423
|
+
* @param value
|
|
424
|
+
*/
|
|
425
|
+
maxFileSize: (constraint, value) => {
|
|
426
|
+
const sizeLimit = typeof constraint === 'string' ? (0, FormUtils_1.getFileSizeInBytes)(constraint) : constraint;
|
|
427
|
+
return {
|
|
428
|
+
valid: !(value instanceof FileObject_1.FileObject) || value.size <= sizeLimit,
|
|
429
|
+
value
|
|
430
|
+
};
|
|
341
431
|
}
|
|
342
432
|
};
|