@aemforms/af-core 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +34 -0
- package/lib/BaseNode.d.ts +117 -0
- package/lib/BaseNode.js +368 -0
- package/lib/Checkbox.d.ts +80 -0
- package/lib/Checkbox.js +49 -0
- package/lib/CheckboxGroup.d.ts +30 -0
- package/lib/CheckboxGroup.js +40 -0
- package/lib/Container.d.ts +336 -0
- package/lib/Container.js +279 -0
- package/lib/Field.d.ts +185 -0
- package/lib/Field.js +432 -0
- package/lib/Fieldset.d.ts +31 -0
- package/lib/Fieldset.js +97 -0
- package/lib/FileObject.d.ts +17 -0
- package/lib/FileObject.js +30 -0
- package/lib/FileUpload.d.ts +42 -0
- package/lib/FileUpload.js +299 -0
- package/lib/Form.d.ts +413 -0
- package/lib/Form.js +247 -0
- package/lib/FormInstance.d.ts +26 -0
- package/lib/FormInstance.js +116 -0
- package/lib/FormMetaData.d.ts +11 -0
- package/lib/FormMetaData.js +28 -0
- package/lib/Node.d.ts +12 -0
- package/lib/Node.js +27 -0
- package/lib/Scriptable.d.ts +27 -0
- package/lib/Scriptable.js +216 -0
- package/lib/controller/Controller.d.ts +207 -0
- package/lib/controller/Controller.js +263 -0
- package/lib/controller/EventQueue.d.ts +24 -0
- package/lib/controller/EventQueue.js +99 -0
- package/lib/controller/index.d.ts +1 -0
- package/lib/controller/index.js +24 -0
- package/lib/data/DataGroup.d.ts +25 -0
- package/lib/data/DataGroup.js +74 -0
- package/lib/data/DataValue.d.ts +22 -0
- package/lib/data/DataValue.js +50 -0
- package/lib/data/EmptyDataValue.d.ts +14 -0
- package/lib/data/EmptyDataValue.js +46 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +59 -0
- package/lib/rules/FunctionRuntime.d.ts +44 -0
- package/lib/rules/FunctionRuntime.js +271 -0
- package/lib/rules/RuleEngine.d.ts +23 -0
- package/lib/rules/RuleEngine.js +67 -0
- package/lib/types/Json.d.ts +126 -0
- package/lib/types/Json.js +16 -0
- package/lib/types/Model.d.ts +352 -0
- package/lib/types/Model.js +20 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.js +25 -0
- package/lib/utils/DataRefParser.d.ts +30 -0
- package/lib/utils/DataRefParser.js +249 -0
- package/lib/utils/Fetch.d.ts +7 -0
- package/lib/utils/Fetch.js +29 -0
- package/lib/utils/FormUtils.d.ts +47 -0
- package/lib/utils/FormUtils.js +172 -0
- package/lib/utils/JsonUtils.d.ts +55 -0
- package/lib/utils/JsonUtils.js +128 -0
- package/lib/utils/LogUtils.d.ts +7 -0
- package/lib/utils/LogUtils.js +17 -0
- package/lib/utils/SchemaUtils.d.ts +16 -0
- package/lib/utils/SchemaUtils.js +92 -0
- package/lib/utils/TranslationUtils.d.ts +34 -0
- package/lib/utils/TranslationUtils.js +156 -0
- package/lib/utils/ValidationUtils.d.ts +153 -0
- package/lib/utils/ValidationUtils.js +339 -0
- package/package.json +60 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines generic interface's for form runtime model
|
|
3
|
+
*/
|
|
4
|
+
import { ConstraintsJson, ContainerJson, FieldJson, FieldsetJson, FormJson, Label, MetaDataJson } from './Json';
|
|
5
|
+
import RuleEngine from '../rules/RuleEngine';
|
|
6
|
+
import EventQueue from '../controller/EventQueue';
|
|
7
|
+
import DataGroup from '../data/DataGroup';
|
|
8
|
+
import { Logger } from '../Form';
|
|
9
|
+
/**
|
|
10
|
+
* Generic Scriptable field interface. All non-transparent fields which support rule/events
|
|
11
|
+
* should implement this interface
|
|
12
|
+
*/
|
|
13
|
+
export interface ScriptableField {
|
|
14
|
+
/**
|
|
15
|
+
* Rules that modify the property of the object dynamically. The rules are evaluated whenever the dependency changes.
|
|
16
|
+
*/
|
|
17
|
+
rules?: {
|
|
18
|
+
[key: string]: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Events is a dictionary of eventName to the actions to perform.
|
|
22
|
+
*/
|
|
23
|
+
events?: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Instance of rule engine
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
ruleEngine: RuleEngine;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generic interface which defines {@link State | form object state}.
|
|
34
|
+
* @typeparam T type of the form object (for example, {@link FieldJson | form field}
|
|
35
|
+
*/
|
|
36
|
+
interface WithState<T> {
|
|
37
|
+
/**
|
|
38
|
+
* {@link State | state} of the form object
|
|
39
|
+
*/
|
|
40
|
+
getState: () => State<T>;
|
|
41
|
+
}
|
|
42
|
+
/** Generic type for a form object state */
|
|
43
|
+
export declare type State<T> = T extends ContainerJson ? T & {
|
|
44
|
+
id: string;
|
|
45
|
+
items: Array<State<FieldJson | ContainerJson>>;
|
|
46
|
+
} : T & {
|
|
47
|
+
id: string;
|
|
48
|
+
':type': string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
export declare type Subscription = {
|
|
54
|
+
unsubscribe(): void;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Generic Action/Event interface.
|
|
58
|
+
* Defines common properties that each action/event should have
|
|
59
|
+
*/
|
|
60
|
+
export interface Action {
|
|
61
|
+
/**
|
|
62
|
+
* Name of the event.
|
|
63
|
+
*/
|
|
64
|
+
type: string;
|
|
65
|
+
/**
|
|
66
|
+
* Event payload as defined by the event.
|
|
67
|
+
*/
|
|
68
|
+
payload: any;
|
|
69
|
+
/**
|
|
70
|
+
* Event metadata.
|
|
71
|
+
*/
|
|
72
|
+
metadata: any;
|
|
73
|
+
/**
|
|
74
|
+
* Is the event custom
|
|
75
|
+
*/
|
|
76
|
+
readonly isCustomEvent: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The field element on which the event is triggered.
|
|
79
|
+
*/
|
|
80
|
+
readonly target: FormModel | FieldModel | FieldsetModel;
|
|
81
|
+
/**
|
|
82
|
+
* Original event. If the event is dispatched, this refers the original event
|
|
83
|
+
*/
|
|
84
|
+
readonly originalAction?: Action;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
export declare type callbackFn = (action: Action) => void;
|
|
90
|
+
/**
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
export interface WithController {
|
|
94
|
+
/**
|
|
95
|
+
* @param callback
|
|
96
|
+
* @param eventName
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
subscribe(callback: callbackFn, eventName?: string): Subscription;
|
|
100
|
+
/**
|
|
101
|
+
* @param action
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
dispatch(action: Action): void;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Generic base model interface.
|
|
108
|
+
* Defines common properties that each form field should have
|
|
109
|
+
*/
|
|
110
|
+
export interface BaseModel extends ConstraintsJson, WithController {
|
|
111
|
+
/**
|
|
112
|
+
* Name of the form field.
|
|
113
|
+
*/
|
|
114
|
+
readonly name?: string;
|
|
115
|
+
/**
|
|
116
|
+
* To map the field’s value to a property in the data model.
|
|
117
|
+
*/
|
|
118
|
+
readonly dataRef?: string | null;
|
|
119
|
+
/**
|
|
120
|
+
* Unique id of the form field.
|
|
121
|
+
*/
|
|
122
|
+
readonly id: string;
|
|
123
|
+
/**
|
|
124
|
+
* The index of the Field within its parent.
|
|
125
|
+
*/
|
|
126
|
+
readonly index: number;
|
|
127
|
+
/**
|
|
128
|
+
* Label to be used for the field.
|
|
129
|
+
*/
|
|
130
|
+
label?: Label;
|
|
131
|
+
/**
|
|
132
|
+
* Extra description to be shown to the user to aid in form filling experience. It can be rich text.
|
|
133
|
+
*/
|
|
134
|
+
description?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Whether the field should be readOnly to end user or not.
|
|
137
|
+
*/
|
|
138
|
+
readOnly?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Whether the field is enabled and takes part in rules, events etc.
|
|
141
|
+
*/
|
|
142
|
+
enabled?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the field should be visible to author or not.
|
|
145
|
+
*/
|
|
146
|
+
visible?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* The placeholder to show on the widget.
|
|
149
|
+
*/
|
|
150
|
+
placeholder?: string;
|
|
151
|
+
/**
|
|
152
|
+
* The current validation state of the Field. The property is always computed after merging the Data Model with the Form
|
|
153
|
+
*/
|
|
154
|
+
valid?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Custom widget type show to the user for capturing the data.
|
|
157
|
+
*/
|
|
158
|
+
readonly ':type': string;
|
|
159
|
+
/**
|
|
160
|
+
* Type of field to capture the user data.
|
|
161
|
+
*/
|
|
162
|
+
readonly 'fieldType': string;
|
|
163
|
+
/**
|
|
164
|
+
* Custom properties of the form field.
|
|
165
|
+
*/
|
|
166
|
+
properties: {
|
|
167
|
+
[key: string]: any;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Whether the form field is container or not
|
|
171
|
+
*/
|
|
172
|
+
readonly isContainer: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* The Parent Panel of the Field/Panel.
|
|
175
|
+
*/
|
|
176
|
+
readonly parent: ContainerModel | null;
|
|
177
|
+
/**
|
|
178
|
+
* Array containing Fields or Panels.
|
|
179
|
+
*/
|
|
180
|
+
readonly items?: Array<FieldsetModel | FieldModel>;
|
|
181
|
+
/**
|
|
182
|
+
* The current value of the Field. The property is serialized in the Data Model.
|
|
183
|
+
*/
|
|
184
|
+
value: any;
|
|
185
|
+
/**
|
|
186
|
+
* Default value of the Field.
|
|
187
|
+
*/
|
|
188
|
+
readonly default?: any;
|
|
189
|
+
/**
|
|
190
|
+
* Validates the given form field
|
|
191
|
+
* @returns list of {@link ValidationError | validation errors}
|
|
192
|
+
*/
|
|
193
|
+
validate(): Array<ValidationError>;
|
|
194
|
+
/**
|
|
195
|
+
* Imports data to the form field
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
importData(a?: DataGroup): any;
|
|
199
|
+
/**
|
|
200
|
+
* @private
|
|
201
|
+
*/
|
|
202
|
+
getRuleNode(): any;
|
|
203
|
+
/**
|
|
204
|
+
* @private
|
|
205
|
+
*/
|
|
206
|
+
ruleNodeReference(): any;
|
|
207
|
+
/**
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
_initialize(): any;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Generic field model interface.
|
|
214
|
+
* Defines properties that each form field should have
|
|
215
|
+
*/
|
|
216
|
+
export interface FieldModel extends BaseModel, ScriptableField, WithState<FieldJson> {
|
|
217
|
+
/**
|
|
218
|
+
* Parent of the current field
|
|
219
|
+
*/
|
|
220
|
+
parent: ContainerModel;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Defines form meta data properties
|
|
224
|
+
*/
|
|
225
|
+
export interface FormMetaDataModel {
|
|
226
|
+
/**
|
|
227
|
+
* Version of the adaptive form specification
|
|
228
|
+
*/
|
|
229
|
+
readonly version: string;
|
|
230
|
+
/**
|
|
231
|
+
* Version of the rule grammar
|
|
232
|
+
*/
|
|
233
|
+
readonly grammar: string;
|
|
234
|
+
/**
|
|
235
|
+
* Form locale
|
|
236
|
+
*/
|
|
237
|
+
readonly locale: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Generic container model interface.
|
|
241
|
+
* Defines properties that each container should have
|
|
242
|
+
*/
|
|
243
|
+
export interface ContainerModel extends BaseModel, ScriptableField {
|
|
244
|
+
/**
|
|
245
|
+
* Defines the children/items of the container
|
|
246
|
+
*/
|
|
247
|
+
items: Array<FieldsetModel | FieldModel>;
|
|
248
|
+
/**
|
|
249
|
+
* Defines the parent of the container
|
|
250
|
+
*/
|
|
251
|
+
parent: ContainerModel;
|
|
252
|
+
/**
|
|
253
|
+
* Returns the index of the {@link FieldModel | child item} or the {@link FieldsetModel | child container}
|
|
254
|
+
* @param f child item
|
|
255
|
+
* @returns `index` of the item
|
|
256
|
+
*/
|
|
257
|
+
indexOf(f: FieldModel | FieldsetModel): number;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Generic field set model interface.
|
|
261
|
+
* Defines properties that each field set should have
|
|
262
|
+
*/
|
|
263
|
+
export interface FieldsetModel extends ContainerModel, WithState<FieldsetJson> {
|
|
264
|
+
type?: 'array' | 'object';
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Defines the interface for form model
|
|
268
|
+
*/
|
|
269
|
+
export interface FormModel extends ContainerModel, WithState<FormJson> {
|
|
270
|
+
/**
|
|
271
|
+
* Id of the form.
|
|
272
|
+
*/
|
|
273
|
+
readonly id: string;
|
|
274
|
+
/**
|
|
275
|
+
* Form data
|
|
276
|
+
*/
|
|
277
|
+
readonly data?: any;
|
|
278
|
+
/**
|
|
279
|
+
* Form metadata
|
|
280
|
+
*/
|
|
281
|
+
readonly metadata?: MetaDataJson;
|
|
282
|
+
/**
|
|
283
|
+
* Form title.
|
|
284
|
+
*/
|
|
285
|
+
readonly title: string;
|
|
286
|
+
readonly logger: Logger;
|
|
287
|
+
/**
|
|
288
|
+
* Imports the given form data
|
|
289
|
+
* @param data form data
|
|
290
|
+
*/
|
|
291
|
+
importData(data: any): any;
|
|
292
|
+
/**
|
|
293
|
+
* Exports the form data
|
|
294
|
+
*/
|
|
295
|
+
exportData(): any;
|
|
296
|
+
/**
|
|
297
|
+
* Get form element model based on the id of the form element
|
|
298
|
+
* @param id id of the form element
|
|
299
|
+
*/
|
|
300
|
+
getElement(id: string): FieldModel | FormModel | FieldsetModel;
|
|
301
|
+
/**
|
|
302
|
+
* @private
|
|
303
|
+
*/
|
|
304
|
+
getUniqueId(): string;
|
|
305
|
+
/**
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
308
|
+
getEventQueue(): EventQueue;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Defines file object interface.
|
|
312
|
+
*/
|
|
313
|
+
export interface IFileObject {
|
|
314
|
+
/**
|
|
315
|
+
* Name of the file
|
|
316
|
+
*/
|
|
317
|
+
name: string;
|
|
318
|
+
/**
|
|
319
|
+
* Media type of the file data
|
|
320
|
+
*/
|
|
321
|
+
mediaType: string;
|
|
322
|
+
/**
|
|
323
|
+
* Data of the file attachment. It can be uri or any file interface specific to channel (in web, it is file object).
|
|
324
|
+
*/
|
|
325
|
+
data?: any;
|
|
326
|
+
/**
|
|
327
|
+
* Size of the file binary as per iec specification.
|
|
328
|
+
*/
|
|
329
|
+
size?: number;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Defines Validation Error interface.
|
|
333
|
+
*/
|
|
334
|
+
export interface IValidationError {
|
|
335
|
+
/**
|
|
336
|
+
* {@link FieldModel.id | name} of the field
|
|
337
|
+
*/
|
|
338
|
+
fieldName: string;
|
|
339
|
+
/**
|
|
340
|
+
* List of error messages
|
|
341
|
+
*/
|
|
342
|
+
errorMessages: Array<string>;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Implementation of {@link IValidationError | Validation Error} interface
|
|
346
|
+
*/
|
|
347
|
+
export declare class ValidationError implements IValidationError {
|
|
348
|
+
fieldName: string;
|
|
349
|
+
errorMessages: Array<string>;
|
|
350
|
+
constructor(fieldName?: string, errorMessages?: Array<any>);
|
|
351
|
+
}
|
|
352
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2022 Adobe, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Your access and use of this software is governed by the Adobe Customer Feedback Program Terms and Conditions or other Beta License Agreement signed by your employer and Adobe, Inc.. This software is NOT open source and may not be used without one of the foregoing licenses. Even with a foregoing license, your access and use of this file is limited to the earlier of (a) 180 days, (b) general availability of the product(s) which utilize this software (i.e. AEM Forms), (c) January 1, 2023, (d) Adobe providing notice to you that you may no longer use the software or that your beta trial has otherwise ended.
|
|
6
|
+
*
|
|
7
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ADOBE NOR ITS THIRD PARTY PROVIDERS AND PARTNERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ValidationError = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Implementation of {@link IValidationError | Validation Error} interface
|
|
13
|
+
*/
|
|
14
|
+
class ValidationError {
|
|
15
|
+
constructor(fieldName = '', errorMessages = []) {
|
|
16
|
+
this.errorMessages = errorMessages;
|
|
17
|
+
this.fieldName = fieldName;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.ValidationError = ValidationError;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2022 Adobe, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Your access and use of this software is governed by the Adobe Customer Feedback Program Terms and Conditions or other Beta License Agreement signed by your employer and Adobe, Inc.. This software is NOT open source and may not be used without one of the foregoing licenses. Even with a foregoing license, your access and use of this file is limited to the earlier of (a) 180 days, (b) general availability of the product(s) which utilize this software (i.e. AEM Forms), (c) January 1, 2023, (d) Adobe providing notice to you that you may no longer use the software or that your beta trial has otherwise ended.
|
|
6
|
+
*
|
|
7
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ADOBE NOR ITS THIRD PARTY PROVIDERS AND PARTNERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
__exportStar(require("./Json"), exports);
|
|
25
|
+
__exportStar(require("./Model"), exports);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines utilities to parse form data
|
|
3
|
+
*/
|
|
4
|
+
import DataGroup from '../data/DataGroup';
|
|
5
|
+
import DataValue from '../data/DataValue';
|
|
6
|
+
declare type TokenType = string;
|
|
7
|
+
export declare const TOK_GLOBAL: TokenType;
|
|
8
|
+
export declare type Token = {
|
|
9
|
+
type: TokenType;
|
|
10
|
+
value: string | number;
|
|
11
|
+
start: number;
|
|
12
|
+
};
|
|
13
|
+
export declare const identifier: (value: string, start: number) => {
|
|
14
|
+
type: string;
|
|
15
|
+
value: string;
|
|
16
|
+
start: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const bracket: (value: number, start: number) => {
|
|
19
|
+
type: string;
|
|
20
|
+
value: number;
|
|
21
|
+
start: number;
|
|
22
|
+
};
|
|
23
|
+
export declare const global$: () => {
|
|
24
|
+
type: string;
|
|
25
|
+
start: number;
|
|
26
|
+
value: string;
|
|
27
|
+
};
|
|
28
|
+
export declare const tokenize: (stream: string) => Token[];
|
|
29
|
+
export declare const resolveData: <T extends DataValue>(data: DataGroup, input: Token[] | string, create?: T | undefined) => DataGroup | DataValue | undefined;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2022 Adobe, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Your access and use of this software is governed by the Adobe Customer Feedback Program Terms and Conditions or other Beta License Agreement signed by your employer and Adobe, Inc.. This software is NOT open source and may not be used without one of the foregoing licenses. Even with a foregoing license, your access and use of this file is limited to the earlier of (a) 180 days, (b) general availability of the product(s) which utilize this software (i.e. AEM Forms), (c) January 1, 2023, (d) Adobe providing notice to you that you may no longer use the software or that your beta trial has otherwise ended.
|
|
6
|
+
*
|
|
7
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ADOBE NOR ITS THIRD PARTY PROVIDERS AND PARTNERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.resolveData = exports.tokenize = exports.global$ = exports.bracket = exports.identifier = exports.TOK_GLOBAL = void 0;
|
|
14
|
+
/**
|
|
15
|
+
* Defines utilities to parse form data
|
|
16
|
+
*/
|
|
17
|
+
const DataGroup_1 = __importDefault(require("../data/DataGroup"));
|
|
18
|
+
const TOK_DOT = 'DOT';
|
|
19
|
+
const TOK_IDENTIFIER = 'Identifier';
|
|
20
|
+
exports.TOK_GLOBAL = 'Global';
|
|
21
|
+
const TOK_BRACKET = 'bracket';
|
|
22
|
+
const TOK_NUMBER = 'Number';
|
|
23
|
+
const globalStartToken = '$';
|
|
24
|
+
const identifier = (value, start) => {
|
|
25
|
+
return {
|
|
26
|
+
type: TOK_IDENTIFIER,
|
|
27
|
+
value,
|
|
28
|
+
start
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
exports.identifier = identifier;
|
|
32
|
+
const bracket = (value, start) => {
|
|
33
|
+
return {
|
|
34
|
+
type: TOK_BRACKET,
|
|
35
|
+
value,
|
|
36
|
+
start
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
exports.bracket = bracket;
|
|
40
|
+
const global$ = () => {
|
|
41
|
+
return {
|
|
42
|
+
type: exports.TOK_GLOBAL,
|
|
43
|
+
start: 0,
|
|
44
|
+
value: globalStartToken
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
exports.global$ = global$;
|
|
48
|
+
const isAlphaNum = function (ch) {
|
|
49
|
+
return (ch >= 'a' && ch <= 'z')
|
|
50
|
+
|| (ch >= 'A' && ch <= 'Z')
|
|
51
|
+
|| (ch >= '0' && ch <= '9')
|
|
52
|
+
|| ch === '_';
|
|
53
|
+
};
|
|
54
|
+
const isGlobal = (prev, stream, pos) => {
|
|
55
|
+
// global tokens occur only at the start of an expression
|
|
56
|
+
return prev === null && stream[pos] === globalStartToken;
|
|
57
|
+
};
|
|
58
|
+
const isIdentifier = (stream, pos) => {
|
|
59
|
+
const ch = stream[pos];
|
|
60
|
+
// $ is special -- it's allowed to be part of an identifier if it's the first character
|
|
61
|
+
if (ch === '$') {
|
|
62
|
+
return stream.length > pos && isAlphaNum(stream[pos + 1]);
|
|
63
|
+
}
|
|
64
|
+
// return whether character 'isAlpha'
|
|
65
|
+
return (ch >= 'a' && ch <= 'z')
|
|
66
|
+
|| (ch >= 'A' && ch <= 'Z')
|
|
67
|
+
|| ch === '_';
|
|
68
|
+
};
|
|
69
|
+
const isNum = (ch) => {
|
|
70
|
+
return (ch >= '0' && ch <= '9');
|
|
71
|
+
};
|
|
72
|
+
class Tokenizer {
|
|
73
|
+
constructor(stream) {
|
|
74
|
+
this.stream = stream;
|
|
75
|
+
this._tokens = [];
|
|
76
|
+
this._result_tokens = [];
|
|
77
|
+
this._current = 0;
|
|
78
|
+
}
|
|
79
|
+
_consumeGlobal() {
|
|
80
|
+
this._current += 1;
|
|
81
|
+
return (0, exports.global$)();
|
|
82
|
+
}
|
|
83
|
+
_consumeUnquotedIdentifier(stream) {
|
|
84
|
+
const start = this._current;
|
|
85
|
+
this._current += 1;
|
|
86
|
+
while (this._current < stream.length && isAlphaNum(stream[this._current])) {
|
|
87
|
+
this._current += 1;
|
|
88
|
+
}
|
|
89
|
+
return (0, exports.identifier)(stream.slice(start, this._current), start);
|
|
90
|
+
}
|
|
91
|
+
_consumeQuotedIdentifier(stream) {
|
|
92
|
+
const start = this._current;
|
|
93
|
+
this._current += 1;
|
|
94
|
+
const maxLength = stream.length;
|
|
95
|
+
while (stream[this._current] !== '"' && this._current < maxLength) {
|
|
96
|
+
// You can escape a double quote and you can escape an escape.
|
|
97
|
+
let current = this._current;
|
|
98
|
+
if (stream[current] === '\\' && (stream[current + 1] === '\\'
|
|
99
|
+
|| stream[current + 1] === '"')) {
|
|
100
|
+
current += 2;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
current += 1;
|
|
104
|
+
}
|
|
105
|
+
this._current = current;
|
|
106
|
+
}
|
|
107
|
+
this._current += 1;
|
|
108
|
+
return (0, exports.identifier)(JSON.parse(stream.slice(start, this._current)), start);
|
|
109
|
+
}
|
|
110
|
+
_consumeNumber(stream) {
|
|
111
|
+
const start = this._current;
|
|
112
|
+
this._current += 1;
|
|
113
|
+
const maxLength = stream.length;
|
|
114
|
+
while (isNum(stream[this._current]) && this._current < maxLength) {
|
|
115
|
+
this._current += 1;
|
|
116
|
+
}
|
|
117
|
+
const n = stream.slice(start, this._current);
|
|
118
|
+
const value = parseInt(n, 10);
|
|
119
|
+
return { type: TOK_NUMBER, value, start };
|
|
120
|
+
}
|
|
121
|
+
_consumeBracket(stream) {
|
|
122
|
+
const start = this._current;
|
|
123
|
+
this._current += 1;
|
|
124
|
+
let value;
|
|
125
|
+
if (isNum(stream[this._current])) {
|
|
126
|
+
value = this._consumeNumber(stream).value;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
throw new Error(`unexpected exception at position ${this._current}. Must be a character`);
|
|
130
|
+
}
|
|
131
|
+
if (this._current < this.stream.length && stream[this._current] !== ']') {
|
|
132
|
+
throw new Error(`unexpected exception at position ${this._current}. Must be a character`);
|
|
133
|
+
}
|
|
134
|
+
this._current++;
|
|
135
|
+
return (0, exports.bracket)(value, start);
|
|
136
|
+
}
|
|
137
|
+
tokenize() {
|
|
138
|
+
const stream = this.stream;
|
|
139
|
+
while (this._current < stream.length) {
|
|
140
|
+
const prev = this._tokens.length ? this._tokens.slice(-1)[0] : null;
|
|
141
|
+
if (isGlobal(prev, stream, this._current)) {
|
|
142
|
+
const token = this._consumeGlobal();
|
|
143
|
+
this._tokens.push(token);
|
|
144
|
+
this._result_tokens.push(token);
|
|
145
|
+
}
|
|
146
|
+
else if (isIdentifier(stream, this._current)) {
|
|
147
|
+
const token = this._consumeUnquotedIdentifier(stream);
|
|
148
|
+
this._tokens.push(token);
|
|
149
|
+
this._result_tokens.push(token);
|
|
150
|
+
}
|
|
151
|
+
else if (stream[this._current] === '.' && prev != null && prev.type !== TOK_DOT) {
|
|
152
|
+
this._tokens.push({
|
|
153
|
+
type: TOK_DOT,
|
|
154
|
+
value: '.',
|
|
155
|
+
start: this._current
|
|
156
|
+
});
|
|
157
|
+
this._current += 1;
|
|
158
|
+
}
|
|
159
|
+
else if (stream[this._current] === '[') {
|
|
160
|
+
// No need to increment this._current. This happens
|
|
161
|
+
// in _consumeLBracket
|
|
162
|
+
const token = this._consumeBracket(stream);
|
|
163
|
+
this._tokens.push(token);
|
|
164
|
+
this._result_tokens.push(token);
|
|
165
|
+
}
|
|
166
|
+
else if (stream[this._current] === '"') {
|
|
167
|
+
const token = this._consumeQuotedIdentifier(stream);
|
|
168
|
+
this._tokens.push(token);
|
|
169
|
+
this._result_tokens.push(token);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const p = Math.max(0, this._current - 2);
|
|
173
|
+
const s = Math.min(this.stream.length, this._current + 2);
|
|
174
|
+
throw new Error(`Exception at parsing stream ${this.stream.slice(p, s)}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return this._result_tokens;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const tokenize = (stream) => {
|
|
181
|
+
return new Tokenizer(stream).tokenize();
|
|
182
|
+
};
|
|
183
|
+
exports.tokenize = tokenize;
|
|
184
|
+
const resolveData = (data, input, create) => {
|
|
185
|
+
let tokens;
|
|
186
|
+
if (typeof input === 'string') {
|
|
187
|
+
tokens = (0, exports.tokenize)(input);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
tokens = input;
|
|
191
|
+
}
|
|
192
|
+
let result = data;
|
|
193
|
+
let i = 0;
|
|
194
|
+
const createIntermediateNode = (token, nextToken, create) => {
|
|
195
|
+
return nextToken === null ? create :
|
|
196
|
+
(nextToken.type === TOK_BRACKET) ? new DataGroup_1.default(token.value, [], 'array') :
|
|
197
|
+
new DataGroup_1.default(token.value, {});
|
|
198
|
+
};
|
|
199
|
+
while (i < tokens.length && result != null) {
|
|
200
|
+
const token = tokens[i];
|
|
201
|
+
if (token.type === exports.TOK_GLOBAL) {
|
|
202
|
+
result = data;
|
|
203
|
+
}
|
|
204
|
+
else if (token.type === TOK_IDENTIFIER) {
|
|
205
|
+
if (result instanceof DataGroup_1.default && result.$type === 'object') {
|
|
206
|
+
//@ts-ignore
|
|
207
|
+
if (result.$containsDataNode(token.value) && result.$getDataNode(token.value).$value !== null) {
|
|
208
|
+
result = result.$getDataNode(token.value);
|
|
209
|
+
}
|
|
210
|
+
else if (create) {
|
|
211
|
+
const nextToken = i < tokens.length - 1 ? tokens[i + 1] : null;
|
|
212
|
+
const toCreate = createIntermediateNode(token, nextToken, create);
|
|
213
|
+
result.$addDataNode(token.value, toCreate);
|
|
214
|
+
result = toCreate;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
result = undefined;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
throw new Error(`Looking for ${token.value} in ${result.$value}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else if (token.type === TOK_BRACKET) {
|
|
225
|
+
if (result instanceof DataGroup_1.default && result.$type === 'array') {
|
|
226
|
+
const index = token.value;
|
|
227
|
+
if (index < result.$length) {
|
|
228
|
+
//@ts-ignore
|
|
229
|
+
result = result.$getDataNode(index);
|
|
230
|
+
}
|
|
231
|
+
else if (create) {
|
|
232
|
+
const nextToken = i < tokens.length - 1 ? tokens[i + 1] : null;
|
|
233
|
+
const toCreate = createIntermediateNode(token, nextToken, create);
|
|
234
|
+
result.$addDataNode(index, toCreate);
|
|
235
|
+
result = toCreate;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
result = undefined;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
throw new Error(`Looking for index ${token.value} in non array${result.$value}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
i += 1;
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
};
|
|
249
|
+
exports.resolveData = resolveData;
|