@sap-ux/preview-middleware 0.19.40 → 0.19.42
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/dist/client/cpe/changes/generic-change.js +328 -0
- package/dist/client/cpe/changes/generic-change.ts +462 -0
- package/dist/client/cpe/changes/service.js +75 -237
- package/dist/client/cpe/changes/service.ts +141 -403
- package/dist/client/cpe/outline/service.ts +0 -1
- package/dist/client/messagebundle.properties +21 -0
- package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +2 -4
- package/dist/client/tsconfig.tsbuildinfo +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import type { ChangeDefinition } from 'sap/ui/fl/Change';
|
|
2
|
+
import { TextBundle } from '../../i18n';
|
|
3
|
+
import { getUi5Version, isLowerThanMinimalUi5Version } from '../../utils/version';
|
|
4
|
+
import FlexChange from 'sap/ui/fl/Change';
|
|
5
|
+
import JsControlTreeModifier from 'sap/ui/core/util/reflection/JsControlTreeModifier';
|
|
6
|
+
import Log from 'sap/base/Log';
|
|
7
|
+
import { getError } from '../../utils/error';
|
|
8
|
+
import { AppComponent } from 'sap/ui/rta/RuntimeAuthoring';
|
|
9
|
+
import { getConfigMapControlIdMap } from '../../utils/fe-v4';
|
|
10
|
+
import { PropertyValue } from '@sap-ux-private/control-property-editor-common';
|
|
11
|
+
|
|
12
|
+
export const ADD_NEW_ANNOTATION_FILE_CHANGE = 'appdescr_app_addAnnotationsToOData';
|
|
13
|
+
export const RENAME_CHANGE = 'rename';
|
|
14
|
+
export const MOVE_CHANGE = 'moveControls';
|
|
15
|
+
export const ADD_XML_CHANGE = 'addXML';
|
|
16
|
+
export const PROPERTY_CHANGE = 'propertyChange';
|
|
17
|
+
export const PROPERTY_BINDING_CHANGE = 'propertyBindingChange';
|
|
18
|
+
export const MANIFEST_V4_CHANGE = 'appdescr_fe_changePageConfiguration';
|
|
19
|
+
export const MANIFEST_V2_CHANGE = 'appdescr_ui_generic_app_changePageConfiguration';
|
|
20
|
+
|
|
21
|
+
type Properties<T extends object> = { [K in keyof T]-?: K extends string ? K : never }[keyof T];
|
|
22
|
+
|
|
23
|
+
interface BaseChange extends ChangeDefinition {
|
|
24
|
+
creation: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ChangeContent {
|
|
28
|
+
property: string;
|
|
29
|
+
newValue: string;
|
|
30
|
+
newBinding: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface AddXml extends BaseChange {
|
|
34
|
+
changeType: typeof ADD_XML_CHANGE;
|
|
35
|
+
content: {
|
|
36
|
+
targetAggregation: string;
|
|
37
|
+
fragmentPath: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface RenameChange extends BaseChange {
|
|
41
|
+
changeType: typeof RENAME_CHANGE;
|
|
42
|
+
texts: {
|
|
43
|
+
newText: {
|
|
44
|
+
value: string;
|
|
45
|
+
type: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface V2ConfigChange extends BaseChange {
|
|
50
|
+
changeType: typeof MANIFEST_V2_CHANGE;
|
|
51
|
+
propertyName: string;
|
|
52
|
+
content: {
|
|
53
|
+
entityPropertyChange: {
|
|
54
|
+
propertyPath: string;
|
|
55
|
+
propertyValue: Record<string, string>;
|
|
56
|
+
};
|
|
57
|
+
parentPage: {
|
|
58
|
+
component: string;
|
|
59
|
+
entitySet: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface ConfigurationChangeContent {
|
|
65
|
+
page: string;
|
|
66
|
+
entityPropertyChange: {
|
|
67
|
+
propertyPath: string;
|
|
68
|
+
operation: 'UPSERT' | 'DELETE' | 'INSERT' | 'UPDATE';
|
|
69
|
+
propertyValue: string | Record<string, string>;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ConfigChange extends BaseChange {
|
|
74
|
+
changeType: typeof MANIFEST_V4_CHANGE;
|
|
75
|
+
propertyName: string;
|
|
76
|
+
content: ConfigurationChangeContent;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface NewAnnotationFileChange extends BaseChange {
|
|
80
|
+
changeType: typeof ADD_NEW_ANNOTATION_FILE_CHANGE;
|
|
81
|
+
content: {
|
|
82
|
+
dataSourceId: string;
|
|
83
|
+
dataSource: {
|
|
84
|
+
[key: string]: {
|
|
85
|
+
uri: string;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface MoveControlsChange extends BaseChange {
|
|
92
|
+
changeType: typeof MOVE_CHANGE;
|
|
93
|
+
content: {
|
|
94
|
+
movedElements: {
|
|
95
|
+
selector: {
|
|
96
|
+
id: string;
|
|
97
|
+
};
|
|
98
|
+
sourceIndex: string;
|
|
99
|
+
targetIndex: string;
|
|
100
|
+
}[];
|
|
101
|
+
target: {
|
|
102
|
+
selector: {
|
|
103
|
+
id: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface PropertyChange extends BaseChange {
|
|
110
|
+
changeType: typeof PROPERTY_CHANGE | typeof PROPERTY_BINDING_CHANGE;
|
|
111
|
+
controlId: string;
|
|
112
|
+
controlName: string;
|
|
113
|
+
propertyName: string;
|
|
114
|
+
content: ChangeContent;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface ChangeHandlerOptions {
|
|
118
|
+
appComponent: AppComponent;
|
|
119
|
+
textBundle: TextBundle;
|
|
120
|
+
configPropertyControlIdMap?: Map<string, string[]>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type GenericChange =
|
|
124
|
+
| NewAnnotationFileChange
|
|
125
|
+
| RenameChange
|
|
126
|
+
| MoveControlsChange
|
|
127
|
+
| AddXml
|
|
128
|
+
| PropertyChange
|
|
129
|
+
| ConfigChange
|
|
130
|
+
| V2ConfigChange;
|
|
131
|
+
|
|
132
|
+
export type changeType = GenericChange['changeType'];
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Returns a shortened version of the given configuration path segments by removing excess segments,
|
|
136
|
+
* leaving only the most relevant parts for display. For example, the configuration path
|
|
137
|
+
* `controlConfiguration/com.sap.UI.v1.LineItem/tableSettings` will be shortened to
|
|
138
|
+
* `LineItem/tableSettings`.
|
|
139
|
+
*
|
|
140
|
+
* @param propertyPathSeg string[]
|
|
141
|
+
* @returns string
|
|
142
|
+
*/
|
|
143
|
+
function getCompactV4ConfigPath(propertyPathSeg: string[]): string {
|
|
144
|
+
return propertyPathSeg.join('/').replace(/^controlConfiguration\/(?:([^/]+\/))?@[^/]+\.v1\./, '$1');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function assertProperties<T extends object>(properties: Properties<T>[], target: T): void {
|
|
148
|
+
for (const property of properties) {
|
|
149
|
+
const value = target[property];
|
|
150
|
+
if (value === null || value === undefined) {
|
|
151
|
+
throw new Error(`Invalid change, missing ${property} in the change file`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Assert change for its validity. Throws error if no value found in saved changes.
|
|
157
|
+
*
|
|
158
|
+
* @param change Change object
|
|
159
|
+
*/
|
|
160
|
+
export function assertChange(change: PropertyChange): void {
|
|
161
|
+
assertProperties(['fileName', 'selector', 'content'], change);
|
|
162
|
+
assertProperties(['id'], change.selector);
|
|
163
|
+
assertProperties(['property'], change.content);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function assertManifestChange(change: ConfigChange): void {
|
|
167
|
+
assertProperties(['fileName', 'content'], change);
|
|
168
|
+
assertProperties(['page', 'entityPropertyChange'], change.content);
|
|
169
|
+
assertProperties(['propertyPath', 'operation', 'propertyValue'], change.content.entityPropertyChange);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get FlexObject from change object based on UI5 version.
|
|
174
|
+
*
|
|
175
|
+
* @param change change object
|
|
176
|
+
* @returns FlexChange
|
|
177
|
+
*/
|
|
178
|
+
export async function getFlexObject(change: object): Promise<FlexChange<ChangeContent>> {
|
|
179
|
+
if (isLowerThanMinimalUi5Version(await getUi5Version(), { major: 1, minor: 109 })) {
|
|
180
|
+
const Change = (await import('sap/ui/fl/Change')).default;
|
|
181
|
+
return new Change(change);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const FlexObjectFactory = (await import('sap/ui/fl/apply/_internal/flexObjects/FlexObjectFactory')).default;
|
|
185
|
+
return FlexObjectFactory.createFromFileContent(change) as FlexChange<ChangeContent>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get element id by change.
|
|
190
|
+
*
|
|
191
|
+
* @param change to be executed for creating change
|
|
192
|
+
* @param appComponent app component
|
|
193
|
+
* @returns element id or empty string
|
|
194
|
+
*/
|
|
195
|
+
export async function getControlIdByChange(
|
|
196
|
+
change: FlexChange<ChangeContent>,
|
|
197
|
+
appComponent: AppComponent
|
|
198
|
+
): Promise<string | undefined> {
|
|
199
|
+
const selector = typeof change.getSelector === 'function' ? change.getSelector() : undefined;
|
|
200
|
+
const changeType = change.getChangeType();
|
|
201
|
+
const layer = change.getLayer();
|
|
202
|
+
|
|
203
|
+
if (!selector?.id) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
let control = JsControlTreeModifier.bySelector(selector, appComponent);
|
|
209
|
+
if (!control) {
|
|
210
|
+
return selector.id;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const changeHandlerAPI = (await import('sap/ui/fl/write/api/ChangesWriteAPI')).default;
|
|
214
|
+
|
|
215
|
+
if (typeof changeHandlerAPI?.getChangeHandler !== 'function') {
|
|
216
|
+
return selector.id;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const changeHandler = await changeHandlerAPI.getChangeHandler({
|
|
220
|
+
changeType,
|
|
221
|
+
element: control,
|
|
222
|
+
modifier: JsControlTreeModifier,
|
|
223
|
+
layer
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
if (changeHandler && typeof changeHandler.getChangeVisualizationInfo === 'function') {
|
|
227
|
+
const result: { affectedControls?: [string] } = await changeHandler.getChangeVisualizationInfo(
|
|
228
|
+
change,
|
|
229
|
+
appComponent
|
|
230
|
+
);
|
|
231
|
+
return JsControlTreeModifier.getControlIdBySelector(
|
|
232
|
+
result?.affectedControls?.[0] ?? selector,
|
|
233
|
+
appComponent
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return JsControlTreeModifier.getControlIdBySelector(selector, appComponent);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
Log.error('Getting element ID from change has failed:', getError(error));
|
|
240
|
+
return selector.id;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface GenericChangeHandlerReturnType {
|
|
245
|
+
changeTitle: string;
|
|
246
|
+
controlId?: string | string[];
|
|
247
|
+
changeType?: string;
|
|
248
|
+
subtitle?: string;
|
|
249
|
+
properties: { label: string; value?: PropertyValue; displayValueWithIcon?: boolean }[];
|
|
250
|
+
}
|
|
251
|
+
export type ChangeHandler<Change> = (
|
|
252
|
+
change: Change,
|
|
253
|
+
options: ChangeHandlerOptions
|
|
254
|
+
) => Promise<GenericChangeHandlerReturnType> | GenericChangeHandlerReturnType;
|
|
255
|
+
type GenericChangeHandler = {
|
|
256
|
+
[Change in GenericChange as Change['changeType']]: ChangeHandler<Change>;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
async function getPropertyChange(
|
|
260
|
+
change: PropertyChange,
|
|
261
|
+
{ appComponent }: ChangeHandlerOptions
|
|
262
|
+
): Promise<GenericChangeHandlerReturnType> {
|
|
263
|
+
const propertyChange = change;
|
|
264
|
+
const flexObject = await getFlexObject(change);
|
|
265
|
+
const selectorId = await getControlIdByChange(flexObject, appComponent);
|
|
266
|
+
const changeTitle = change.selector.type ? (change.selector.type.split('.').pop() as string) : '';
|
|
267
|
+
assertChange(propertyChange);
|
|
268
|
+
if (
|
|
269
|
+
[propertyChange.content.newValue, propertyChange.content.newBinding].every(
|
|
270
|
+
(item) => item === undefined || item === null
|
|
271
|
+
)
|
|
272
|
+
) {
|
|
273
|
+
throw new Error('Invalid change, missing new value in the change file');
|
|
274
|
+
}
|
|
275
|
+
if (change.changeType !== PROPERTY_CHANGE && change.changeType !== PROPERTY_BINDING_CHANGE) {
|
|
276
|
+
throw new Error('Unknown Change Type');
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
changeTitle: changeTitle,
|
|
280
|
+
controlId: selectorId,
|
|
281
|
+
changeType: 'property',
|
|
282
|
+
properties: [
|
|
283
|
+
{
|
|
284
|
+
label: propertyChange.content.property,
|
|
285
|
+
value: propertyChange.content.newValue ?? propertyChange.content.newBinding,
|
|
286
|
+
displayValueWithIcon: true
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function getV2ConfigurationChange(
|
|
293
|
+
change: V2ConfigChange,
|
|
294
|
+
{ textBundle }: ChangeHandlerOptions
|
|
295
|
+
): GenericChangeHandlerReturnType {
|
|
296
|
+
const { entityPropertyChange, parentPage } = change.content;
|
|
297
|
+
const propertyPathSegments = entityPropertyChange.propertyPath.split('/');
|
|
298
|
+
const propertyName =
|
|
299
|
+
Object.keys(entityPropertyChange.propertyValue)?.[0] ?? propertyPathSegments[propertyPathSegments.length - 1];
|
|
300
|
+
const propertyValue = entityPropertyChange.propertyValue?.[propertyName] ?? entityPropertyChange.propertyValue;
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
changeTitle: textBundle?.getText('CONFIGURATION_CHANGE'),
|
|
304
|
+
controlId: [],
|
|
305
|
+
changeType: 'configuration',
|
|
306
|
+
subtitle: entityPropertyChange.propertyPath ?? parentPage.component,
|
|
307
|
+
properties: [
|
|
308
|
+
{
|
|
309
|
+
label: propertyName ?? '',
|
|
310
|
+
value: propertyValue,
|
|
311
|
+
displayValueWithIcon: true
|
|
312
|
+
}
|
|
313
|
+
]
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function getV4ConfigurationChange(
|
|
318
|
+
change: ConfigChange,
|
|
319
|
+
{ configPropertyControlIdMap, textBundle }: ChangeHandlerOptions
|
|
320
|
+
): GenericChangeHandlerReturnType {
|
|
321
|
+
assertManifestChange(change);
|
|
322
|
+
if ([change.content.entityPropertyChange.propertyValue].every((item) => item === undefined || item === null)) {
|
|
323
|
+
throw new Error('Invalid change, missing property value on change file');
|
|
324
|
+
}
|
|
325
|
+
const propertyPathSegments = change.content.entityPropertyChange.propertyPath.split('/');
|
|
326
|
+
const propertyName = propertyPathSegments.pop();
|
|
327
|
+
if (!propertyName) {
|
|
328
|
+
throw new Error('No property name found');
|
|
329
|
+
}
|
|
330
|
+
const configMapKey = getConfigMapControlIdMap(change.content.page, propertyPathSegments);
|
|
331
|
+
const controlIds = configPropertyControlIdMap?.get(configMapKey) || [];
|
|
332
|
+
let value = change.content.entityPropertyChange.propertyValue;
|
|
333
|
+
const properties =
|
|
334
|
+
typeof value === 'object'
|
|
335
|
+
? [
|
|
336
|
+
{
|
|
337
|
+
label: propertyName,
|
|
338
|
+
displayValueWithIcon: true
|
|
339
|
+
},
|
|
340
|
+
...Object.keys(value)
|
|
341
|
+
.map((key: string) => {
|
|
342
|
+
if (typeof value[key] === 'object') {
|
|
343
|
+
return undefined;
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
label: key,
|
|
347
|
+
value: value[key],
|
|
348
|
+
displayValueWithIcon: true
|
|
349
|
+
};
|
|
350
|
+
})
|
|
351
|
+
.filter((item) => !!item)
|
|
352
|
+
]
|
|
353
|
+
: [
|
|
354
|
+
{
|
|
355
|
+
label: propertyName,
|
|
356
|
+
value,
|
|
357
|
+
displayValueWithIcon: true
|
|
358
|
+
}
|
|
359
|
+
];
|
|
360
|
+
return {
|
|
361
|
+
changeTitle: textBundle?.getText('CONFIGURATION_CHANGE'),
|
|
362
|
+
controlId: controlIds,
|
|
363
|
+
changeType: 'configuration',
|
|
364
|
+
subtitle: getCompactV4ConfigPath(propertyPathSegments),
|
|
365
|
+
properties
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export const GENERIC_CHANGE_HANDLER: GenericChangeHandler = {
|
|
370
|
+
[ADD_NEW_ANNOTATION_FILE_CHANGE]: (annotationFileChange, { textBundle }) => {
|
|
371
|
+
const dataSourceId = annotationFileChange.content.dataSourceId;
|
|
372
|
+
const sourceKey = Object.keys(annotationFileChange.content.dataSource)[0];
|
|
373
|
+
return {
|
|
374
|
+
changeTitle: textBundle?.getText('ADD_NEW_ANNOTATION_FILE'),
|
|
375
|
+
changeType: 'configuration',
|
|
376
|
+
properties: [
|
|
377
|
+
{
|
|
378
|
+
label: textBundle?.getText('SERVICE_NAME'),
|
|
379
|
+
value: dataSourceId
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
label: textBundle?.getText('ANNOTATION_FILE_URI'),
|
|
383
|
+
value: annotationFileChange.content.dataSource[sourceKey].uri
|
|
384
|
+
}
|
|
385
|
+
]
|
|
386
|
+
};
|
|
387
|
+
},
|
|
388
|
+
[RENAME_CHANGE]: (renameChange, { textBundle }) => {
|
|
389
|
+
const selectorId = renameChange.selector.id;
|
|
390
|
+
return {
|
|
391
|
+
changeTitle: textBundle?.getText('RENAME_CHANGE'),
|
|
392
|
+
controlId: selectorId,
|
|
393
|
+
properties: [
|
|
394
|
+
{
|
|
395
|
+
label: textBundle?.getText('SELECTOR_ID'),
|
|
396
|
+
value: selectorId
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
label: textBundle?.getText('NEW_VALUE'),
|
|
400
|
+
value: renameChange.texts.newText.value
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
label: textBundle?.getText('TEXT_TYPE'),
|
|
404
|
+
value: renameChange.texts.newText.type
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
};
|
|
408
|
+
},
|
|
409
|
+
[MOVE_CHANGE]: (moveChange, { textBundle }) => {
|
|
410
|
+
const movedControlId = moveChange.content.movedElements[0].selector.id;
|
|
411
|
+
return {
|
|
412
|
+
changeTitle: textBundle?.getText('MOVE_CONTROLS_CHANGE'),
|
|
413
|
+
controlId: movedControlId,
|
|
414
|
+
properties: [
|
|
415
|
+
{
|
|
416
|
+
label: textBundle?.getText('TARGET_CONTROL_ID'),
|
|
417
|
+
value: moveChange.content.target.selector.id
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
label: textBundle?.getText('MOVE_FROM_INDEX'),
|
|
421
|
+
value: String(moveChange.content.movedElements[0].sourceIndex)
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
label: textBundle?.getText('MOVE_TO_INDEX'),
|
|
425
|
+
value: String(moveChange.content.movedElements[0].targetIndex)
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
label: textBundle?.getText('MOVED_CONTROL_ID'),
|
|
429
|
+
value: movedControlId
|
|
430
|
+
}
|
|
431
|
+
]
|
|
432
|
+
};
|
|
433
|
+
},
|
|
434
|
+
[ADD_XML_CHANGE]: (addXmlChange, { textBundle }) => {
|
|
435
|
+
return {
|
|
436
|
+
changeTitle: textBundle?.getText('ADD_XML_CHANGE'),
|
|
437
|
+
controlId: addXmlChange.selector.id,
|
|
438
|
+
properties: [
|
|
439
|
+
{
|
|
440
|
+
label: textBundle?.getText('AGGREGATION'),
|
|
441
|
+
value: addXmlChange.content.targetAggregation
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
label: textBundle?.getText('FRAGMENT_PATH'),
|
|
445
|
+
value: addXmlChange.content.fragmentPath
|
|
446
|
+
}
|
|
447
|
+
]
|
|
448
|
+
};
|
|
449
|
+
},
|
|
450
|
+
[PROPERTY_CHANGE]: async (change, handlerOptions) => {
|
|
451
|
+
return getPropertyChange(change, handlerOptions);
|
|
452
|
+
},
|
|
453
|
+
[PROPERTY_BINDING_CHANGE]: async (change, handlerOptions) => {
|
|
454
|
+
return getPropertyChange(change, handlerOptions);
|
|
455
|
+
},
|
|
456
|
+
[MANIFEST_V4_CHANGE]: (change, handlerOptions) => {
|
|
457
|
+
return getV4ConfigurationChange(change, handlerOptions);
|
|
458
|
+
},
|
|
459
|
+
[MANIFEST_V2_CHANGE]: (change, handlerOptions) => {
|
|
460
|
+
return getV2ConfigurationChange(change, handlerOptions);
|
|
461
|
+
}
|
|
462
|
+
};
|