@sap-ux/fiori-annotation-api 0.1.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 +201 -0
- package/Readme.md +35 -0
- package/dist/avt/annotations.d.ts +72 -0
- package/dist/avt/annotations.d.ts.map +1 -0
- package/dist/avt/annotations.js +508 -0
- package/dist/avt/annotations.js.map +1 -0
- package/dist/avt/expressions.d.ts +13 -0
- package/dist/avt/expressions.d.ts.map +1 -0
- package/dist/avt/expressions.js +34 -0
- package/dist/avt/expressions.js.map +1 -0
- package/dist/avt/find.d.ts +39 -0
- package/dist/avt/find.d.ts.map +1 -0
- package/dist/avt/find.js +130 -0
- package/dist/avt/find.js.map +1 -0
- package/dist/avt/index.d.ts +9 -0
- package/dist/avt/index.d.ts.map +1 -0
- package/dist/avt/index.js +32 -0
- package/dist/avt/index.js.map +1 -0
- package/dist/avt/metadata.d.ts +10 -0
- package/dist/avt/metadata.d.ts.map +1 -0
- package/dist/avt/metadata.js +346 -0
- package/dist/avt/metadata.js.map +1 -0
- package/dist/avt/pointer.d.ts +12 -0
- package/dist/avt/pointer.d.ts.map +1 -0
- package/dist/avt/pointer.js +188 -0
- package/dist/avt/pointer.js.map +1 -0
- package/dist/avt/to-internal.d.ts +81 -0
- package/dist/avt/to-internal.d.ts.map +1 -0
- package/dist/avt/to-internal.js +340 -0
- package/dist/avt/to-internal.js.map +1 -0
- package/dist/avt/types.d.ts +3 -0
- package/dist/avt/types.d.ts.map +1 -0
- package/dist/avt/types.js +3 -0
- package/dist/avt/types.js.map +1 -0
- package/dist/avt/utils.d.ts +61 -0
- package/dist/avt/utils.d.ts.map +1 -0
- package/dist/avt/utils.js +87 -0
- package/dist/avt/utils.js.map +1 -0
- package/dist/cds/adapter.d.ts +112 -0
- package/dist/cds/adapter.d.ts.map +1 -0
- package/dist/cds/adapter.js +703 -0
- package/dist/cds/adapter.js.map +1 -0
- package/dist/cds/cds-compiler-tokens.d.ts +30 -0
- package/dist/cds/cds-compiler-tokens.d.ts.map +1 -0
- package/dist/cds/cds-compiler-tokens.js +57 -0
- package/dist/cds/cds-compiler-tokens.js.map +1 -0
- package/dist/cds/change.d.ts +347 -0
- package/dist/cds/change.d.ts.map +1 -0
- package/dist/cds/change.js +232 -0
- package/dist/cds/change.js.map +1 -0
- package/dist/cds/comments.d.ts +15 -0
- package/dist/cds/comments.d.ts.map +1 -0
- package/dist/cds/comments.js +56 -0
- package/dist/cds/comments.js.map +1 -0
- package/dist/cds/deletion.d.ts +59 -0
- package/dist/cds/deletion.d.ts.map +1 -0
- package/dist/cds/deletion.js +821 -0
- package/dist/cds/deletion.js.map +1 -0
- package/dist/cds/document.d.ts +52 -0
- package/dist/cds/document.d.ts.map +1 -0
- package/dist/cds/document.js +98 -0
- package/dist/cds/document.js.map +1 -0
- package/dist/cds/indent.d.ts +20 -0
- package/dist/cds/indent.d.ts.map +1 -0
- package/dist/cds/indent.js +86 -0
- package/dist/cds/indent.js.map +1 -0
- package/dist/cds/index.d.ts +3 -0
- package/dist/cds/index.d.ts.map +1 -0
- package/dist/cds/index.js +21 -0
- package/dist/cds/index.js.map +1 -0
- package/dist/cds/pointer.d.ts +23 -0
- package/dist/cds/pointer.d.ts.map +1 -0
- package/dist/cds/pointer.js +438 -0
- package/dist/cds/pointer.js.map +1 -0
- package/dist/cds/preprocessor.d.ts +12 -0
- package/dist/cds/preprocessor.d.ts.map +1 -0
- package/dist/cds/preprocessor.js +338 -0
- package/dist/cds/preprocessor.js.map +1 -0
- package/dist/cds/references.d.ts +35 -0
- package/dist/cds/references.d.ts.map +1 -0
- package/dist/cds/references.js +413 -0
- package/dist/cds/references.js.map +1 -0
- package/dist/cds/service.d.ts +11 -0
- package/dist/cds/service.d.ts.map +1 -0
- package/dist/cds/service.js +37 -0
- package/dist/cds/service.js.map +1 -0
- package/dist/cds/utils.d.ts +35 -0
- package/dist/cds/utils.d.ts.map +1 -0
- package/dist/cds/utils.js +75 -0
- package/dist/cds/utils.js.map +1 -0
- package/dist/cds/writer.d.ts +104 -0
- package/dist/cds/writer.d.ts.map +1 -0
- package/dist/cds/writer.js +1086 -0
- package/dist/cds/writer.js.map +1 -0
- package/dist/change-converter.d.ts +54 -0
- package/dist/change-converter.d.ts.map +1 -0
- package/dist/change-converter.js +639 -0
- package/dist/change-converter.js.map +1 -0
- package/dist/error.d.ts +35 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +64 -0
- package/dist/error.js.map +1 -0
- package/dist/fiori-service.d.ts +130 -0
- package/dist/fiori-service.d.ts.map +1 -0
- package/dist/fiori-service.js +362 -0
- package/dist/fiori-service.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/protected.d.ts +3 -0
- package/dist/protected.d.ts.map +1 -0
- package/dist/protected.js +11 -0
- package/dist/protected.js.map +1 -0
- package/dist/types/adapter.d.ts +46 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +3 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/change.d.ts +187 -0
- package/dist/types/change.d.ts.map +1 -0
- package/dist/types/change.js +52 -0
- package/dist/types/change.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +33 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/internal-change.d.ts +98 -0
- package/dist/types/internal-change.d.ts.map +1 -0
- package/dist/types/internal-change.js +18 -0
- package/dist/types/internal-change.js.map +1 -0
- package/dist/types/project-info.d.ts +6 -0
- package/dist/types/project-info.d.ts.map +1 -0
- package/dist/types/project-info.js +3 -0
- package/dist/types/project-info.js.map +1 -0
- package/dist/types/service.d.ts +27 -0
- package/dist/types/service.d.ts.map +1 -0
- package/dist/types/service.js +3 -0
- package/dist/types/service.js.map +1 -0
- package/dist/types/text-file.d.ts +12 -0
- package/dist/types/text-file.d.ts.map +1 -0
- package/dist/types/text-file.js +3 -0
- package/dist/types/text-file.js.map +1 -0
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +24 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/indent.d.ts +10 -0
- package/dist/utils/indent.d.ts.map +1 -0
- package/dist/utils/indent.js +36 -0
- package/dist/utils/indent.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +16 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/path.d.ts +8 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +31 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/pointer.d.ts +11 -0
- package/dist/utils/pointer.d.ts.map +1 -0
- package/dist/utils/pointer.js +26 -0
- package/dist/utils/pointer.js.map +1 -0
- package/dist/utils/reference.d.ts +10 -0
- package/dist/utils/reference.d.ts.map +1 -0
- package/dist/utils/reference.js +20 -0
- package/dist/utils/reference.js.map +1 -0
- package/dist/utils/text-edits.d.ts +12 -0
- package/dist/utils/text-edits.d.ts.map +1 -0
- package/dist/utils/text-edits.js +29 -0
- package/dist/utils/text-edits.js.map +1 -0
- package/dist/vocabularies.d.ts +11 -0
- package/dist/vocabularies.d.ts.map +1 -0
- package/dist/vocabularies.js +26 -0
- package/dist/vocabularies.js.map +1 -0
- package/dist/xml/adapter.d.ts +85 -0
- package/dist/xml/adapter.d.ts.map +1 -0
- package/dist/xml/adapter.js +579 -0
- package/dist/xml/adapter.js.map +1 -0
- package/dist/xml/changes.d.ts +117 -0
- package/dist/xml/changes.d.ts.map +1 -0
- package/dist/xml/changes.js +34 -0
- package/dist/xml/changes.js.map +1 -0
- package/dist/xml/comments.d.ts +17 -0
- package/dist/xml/comments.d.ts.map +1 -0
- package/dist/xml/comments.js +49 -0
- package/dist/xml/comments.js.map +1 -0
- package/dist/xml/document.d.ts +11 -0
- package/dist/xml/document.d.ts.map +1 -0
- package/dist/xml/document.js +3 -0
- package/dist/xml/document.js.map +1 -0
- package/dist/xml/index.d.ts +3 -0
- package/dist/xml/index.d.ts.map +1 -0
- package/dist/xml/index.js +8 -0
- package/dist/xml/index.js.map +1 -0
- package/dist/xml/pointer.d.ts +10 -0
- package/dist/xml/pointer.d.ts.map +1 -0
- package/dist/xml/pointer.js +29 -0
- package/dist/xml/pointer.js.map +1 -0
- package/dist/xml/references.d.ts +9 -0
- package/dist/xml/references.d.ts.map +1 -0
- package/dist/xml/references.js +87 -0
- package/dist/xml/references.js.map +1 -0
- package/dist/xml/service.d.ts +12 -0
- package/dist/xml/service.d.ts.map +1 -0
- package/dist/xml/service.js +55 -0
- package/dist/xml/service.js.map +1 -0
- package/dist/xml/writer.d.ts +39 -0
- package/dist/xml/writer.d.ts.map +1 -0
- package/dist/xml/writer.js +855 -0
- package/dist/xml/writer.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChangeConverter = void 0;
|
|
4
|
+
const odata_annotation_core_types_1 = require("@sap-ux/odata-annotation-core-types");
|
|
5
|
+
const odata_annotation_core_1 = require("@sap-ux/odata-annotation-core");
|
|
6
|
+
const avt_1 = require("./avt");
|
|
7
|
+
const vocabularies_1 = require("./vocabularies");
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
const error_1 = require("./error");
|
|
11
|
+
/**
|
|
12
|
+
* Converts changes to the internal change format.
|
|
13
|
+
*/
|
|
14
|
+
class ChangeConverter {
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param serviceName Name of the service.
|
|
18
|
+
* @param vocabularyAPI Vocabulary API instance.
|
|
19
|
+
* @param metadataService Metadata service.
|
|
20
|
+
* @param splitAnnotationSupport Flag indicating if partial annotation definitions are supported.
|
|
21
|
+
*/
|
|
22
|
+
constructor(serviceName, vocabularyAPI, metadataService, splitAnnotationSupport) {
|
|
23
|
+
this.serviceName = serviceName;
|
|
24
|
+
this.vocabularyAPI = vocabularyAPI;
|
|
25
|
+
this.metadataService = metadataService;
|
|
26
|
+
this.splitAnnotationSupport = splitAnnotationSupport;
|
|
27
|
+
this.aliasInfoCache = {};
|
|
28
|
+
this.newTargetChanges = new Map();
|
|
29
|
+
this.annotationFileChanges = [];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Converts changes to the internal change format.
|
|
33
|
+
*
|
|
34
|
+
* @param compiledService Service in internal format.
|
|
35
|
+
* @param fileMergeMaps Maps containing references of merged split annotations.
|
|
36
|
+
* @param schemaProvider Function which returns current service RawMetadata.
|
|
37
|
+
* @param changes AVT changes to be converted.
|
|
38
|
+
* @returns Annotation file changes.
|
|
39
|
+
*/
|
|
40
|
+
convert(compiledService, fileMergeMaps, schemaProvider, changes) {
|
|
41
|
+
this.reset();
|
|
42
|
+
const mergedChanges = mergeChanges(changes);
|
|
43
|
+
for (const change of mergedChanges) {
|
|
44
|
+
const file = compiledService.annotationFiles.find((file) => file.uri === change.uri);
|
|
45
|
+
if (!file) {
|
|
46
|
+
throw new Error(`Invalid change. File ${change.uri} does not exist.`);
|
|
47
|
+
}
|
|
48
|
+
const aliasInfoMod = this.getAliasInformation(file);
|
|
49
|
+
if (change.kind === types_1.ChangeType.InsertAnnotation) {
|
|
50
|
+
this.insertAnnotation(compiledService, aliasInfoMod, change);
|
|
51
|
+
}
|
|
52
|
+
else if (change.kind === types_1.ChangeType.InsertEmbeddedAnnotation) {
|
|
53
|
+
this.insertEmbeddedAnnotation(file, fileMergeMaps, aliasInfoMod, change);
|
|
54
|
+
}
|
|
55
|
+
else if (change.kind === types_1.ChangeType.Insert) {
|
|
56
|
+
this.convertInsert(file, fileMergeMaps, aliasInfoMod, change);
|
|
57
|
+
}
|
|
58
|
+
else if (change.kind === types_1.ChangeType.Delete) {
|
|
59
|
+
this.convertDelete(file, fileMergeMaps, aliasInfoMod, change);
|
|
60
|
+
}
|
|
61
|
+
else if (change.kind === types_1.ChangeType.Update) {
|
|
62
|
+
this.convertUpdate(file, fileMergeMaps, aliasInfoMod, schemaProvider, change);
|
|
63
|
+
}
|
|
64
|
+
else if (change.kind === types_1.ChangeType.Move) {
|
|
65
|
+
this.convertMove(file, fileMergeMaps, aliasInfoMod, change);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
this.addTargetChanges(compiledService);
|
|
69
|
+
return this.annotationFileChanges;
|
|
70
|
+
}
|
|
71
|
+
insertAnnotation(compiledService, aliasInfo, change) {
|
|
72
|
+
const annotationFile = compiledService.annotationFiles.find((file) => file.uri === change.uri);
|
|
73
|
+
const targetName = (0, odata_annotation_core_1.toAliasQualifiedName)(change.content.target, aliasInfo);
|
|
74
|
+
const targetIndex = annotationFile === null || annotationFile === void 0 ? void 0 : annotationFile.targets.findIndex((target) => (0, odata_annotation_core_1.toAliasQualifiedName)(target.name, aliasInfo) === targetName);
|
|
75
|
+
if (targetIndex === -1) {
|
|
76
|
+
// no existing target found, we need to create one
|
|
77
|
+
const changesForUri = this.newTargetChanges.get(change.uri);
|
|
78
|
+
if (!changesForUri) {
|
|
79
|
+
this.newTargetChanges.set(change.uri, new Map([[targetName, [change]]]));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const changesForTarget = changesForUri.get(targetName);
|
|
83
|
+
if (changesForTarget) {
|
|
84
|
+
changesForTarget.push(change);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
changesForUri.set(targetName, [change]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// add annotation to existing target
|
|
93
|
+
const internal = {
|
|
94
|
+
type: types_1.INSERT_ELEMENT,
|
|
95
|
+
uri: change.uri,
|
|
96
|
+
target: targetName,
|
|
97
|
+
pointer: `/targets/${targetIndex}`,
|
|
98
|
+
element: (0, avt_1.convertAnnotationToInternal)(change.content.value, aliasInfo)
|
|
99
|
+
};
|
|
100
|
+
this.annotationFileChanges.push(internal);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
insertEmbeddedAnnotation(file, fileMergeMaps, aliasInfo, change) {
|
|
104
|
+
const { reference, content } = change;
|
|
105
|
+
const { targetPointer, internalPointer } = (0, avt_1.findAnnotationByReference)(aliasInfo, file, fileMergeMaps[change.uri], reference, change.pointer, this.splitAnnotationSupport);
|
|
106
|
+
const internal = {
|
|
107
|
+
type: types_1.INSERT_ELEMENT,
|
|
108
|
+
uri: change.uri,
|
|
109
|
+
target: change.reference.target,
|
|
110
|
+
element: (0, avt_1.convertAnnotationToInternal)(content.value, aliasInfo),
|
|
111
|
+
pointer: targetPointer + internalPointer
|
|
112
|
+
};
|
|
113
|
+
this.annotationFileChanges.push(internal);
|
|
114
|
+
}
|
|
115
|
+
convertInsert(file, fileMergeMaps, aliasInfoMod, change) {
|
|
116
|
+
const { reference, content } = change;
|
|
117
|
+
const { element, targetPointer: pointer, internalPointer } = (0, avt_1.findAnnotationByReference)(aliasInfoMod, file, fileMergeMaps[change.uri], reference, change.pointer, this.splitAnnotationSupport);
|
|
118
|
+
if (content.type === 'record') {
|
|
119
|
+
const internal = {
|
|
120
|
+
type: types_1.INSERT_ELEMENT,
|
|
121
|
+
uri: change.uri,
|
|
122
|
+
target: change.reference.target,
|
|
123
|
+
pointer: pointer + internalPointer,
|
|
124
|
+
element: (0, avt_1.convertRecordToInternal)(aliasInfoMod, content.value),
|
|
125
|
+
index: change.kind === types_1.ChangeType.Insert ? change.index : undefined
|
|
126
|
+
};
|
|
127
|
+
this.annotationFileChanges.push(internal);
|
|
128
|
+
}
|
|
129
|
+
else if (content.type === 'property-value') {
|
|
130
|
+
const internal = {
|
|
131
|
+
type: types_1.INSERT_ELEMENT,
|
|
132
|
+
uri: change.uri,
|
|
133
|
+
target: change.reference.target,
|
|
134
|
+
pointer: pointer + internalPointer,
|
|
135
|
+
element: (0, avt_1.convertPropertyValueToInternal)(aliasInfoMod, content.value),
|
|
136
|
+
index: change.kind === types_1.ChangeType.Insert ? change.index : undefined
|
|
137
|
+
};
|
|
138
|
+
this.annotationFileChanges.push(internal);
|
|
139
|
+
}
|
|
140
|
+
else if (content.type === 'collection') {
|
|
141
|
+
const internal = {
|
|
142
|
+
type: types_1.INSERT_ELEMENT,
|
|
143
|
+
uri: change.uri,
|
|
144
|
+
target: change.reference.target,
|
|
145
|
+
pointer: pointer + internalPointer,
|
|
146
|
+
element: (0, avt_1.convertCollectionToInternal)(aliasInfoMod, content.value),
|
|
147
|
+
index: change.kind === types_1.ChangeType.Insert ? change.index : undefined
|
|
148
|
+
};
|
|
149
|
+
this.annotationFileChanges.push(internal);
|
|
150
|
+
}
|
|
151
|
+
else if (content.type === 'expression') {
|
|
152
|
+
this.convertInsertExpression(file, aliasInfoMod, pointer + internalPointer, change, content);
|
|
153
|
+
}
|
|
154
|
+
else if (content.type === 'primitive') {
|
|
155
|
+
this.convertInsertPrimitive(element, aliasInfoMod, pointer, internalPointer, change, content);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
convertInsertExpression(file, aliasInfoMod, pointer, change, content) {
|
|
159
|
+
const node = (0, utils_1.getGenericNodeFromPointer)(file, pointer);
|
|
160
|
+
if ((node === null || node === void 0 ? void 0 : node.type) === odata_annotation_core_types_1.ELEMENT_TYPE && node.name === "Collection" /* Edm.Collection */) {
|
|
161
|
+
const expression = (0, avt_1.convertExpressionToInternal)(aliasInfoMod, content.value);
|
|
162
|
+
if (expression) {
|
|
163
|
+
const internal = {
|
|
164
|
+
type: types_1.INSERT_ELEMENT,
|
|
165
|
+
uri: change.uri,
|
|
166
|
+
target: change.reference.target,
|
|
167
|
+
pointer: pointer,
|
|
168
|
+
element: expression
|
|
169
|
+
};
|
|
170
|
+
this.annotationFileChanges.push(internal);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const container = (0, avt_1.convertExpressionToInternal)(aliasInfoMod, content.value, (0, odata_annotation_core_types_1.createElementNode)({ name: 'placeholder' }));
|
|
175
|
+
if (container) {
|
|
176
|
+
const expression = container.content[0];
|
|
177
|
+
if ((expression === null || expression === void 0 ? void 0 : expression.type) === odata_annotation_core_types_1.ELEMENT_TYPE) {
|
|
178
|
+
const internal = {
|
|
179
|
+
type: types_1.INSERT_ELEMENT,
|
|
180
|
+
uri: change.uri,
|
|
181
|
+
target: change.reference.target,
|
|
182
|
+
pointer: pointer,
|
|
183
|
+
element: expression
|
|
184
|
+
};
|
|
185
|
+
this.annotationFileChanges.push(internal);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
else if (Object.keys(container.attributes).length > 0) {
|
|
189
|
+
const attribute = container.attributes[Object.keys(container.attributes)[0]];
|
|
190
|
+
const internal = {
|
|
191
|
+
type: types_1.INSERT_ATTRIBUTE,
|
|
192
|
+
uri: change.uri,
|
|
193
|
+
pointer: pointer,
|
|
194
|
+
name: attribute.name,
|
|
195
|
+
value: attribute.value
|
|
196
|
+
};
|
|
197
|
+
this.annotationFileChanges.push(internal);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
convertInsertPrimitive(element, aliasInfoMod, pointer, internalPointer, change, content) {
|
|
204
|
+
if (content.expressionType === types_1.ExpressionType.Unknown) {
|
|
205
|
+
const attributePointer = (0, avt_1.convertPointerInAnnotationToInternal)(element,
|
|
206
|
+
// last segment is used to determine attribute name
|
|
207
|
+
change.pointer.split('/').slice(0, -1).join('/'));
|
|
208
|
+
const attributeName = getAttributeNameFromPointer(change.pointer);
|
|
209
|
+
if (attributeName) {
|
|
210
|
+
const value = (0, avt_1.convertPrimitiveValueToInternal)(attributeName, content.value, aliasInfoMod);
|
|
211
|
+
const internal = {
|
|
212
|
+
type: types_1.INSERT_ATTRIBUTE,
|
|
213
|
+
uri: change.uri,
|
|
214
|
+
pointer: pointer + attributePointer,
|
|
215
|
+
name: attributeName,
|
|
216
|
+
value: value
|
|
217
|
+
};
|
|
218
|
+
this.annotationFileChanges.push(internal);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else if (content.expressionType === types_1.ExpressionType.Null) {
|
|
222
|
+
const internal = {
|
|
223
|
+
type: types_1.INSERT_ELEMENT,
|
|
224
|
+
uri: change.uri,
|
|
225
|
+
target: change.reference.target,
|
|
226
|
+
pointer: pointer + internalPointer,
|
|
227
|
+
element: (0, odata_annotation_core_types_1.createElementNode)({ name: "Null" /* Edm.Null */ })
|
|
228
|
+
};
|
|
229
|
+
this.annotationFileChanges.push(internal);
|
|
230
|
+
}
|
|
231
|
+
else if (typeof content.expressionType === 'string') {
|
|
232
|
+
const internal = {
|
|
233
|
+
type: types_1.INSERT_ATTRIBUTE,
|
|
234
|
+
uri: change.uri,
|
|
235
|
+
pointer: pointer + internalPointer,
|
|
236
|
+
name: content.expressionType,
|
|
237
|
+
value: content.value.toString()
|
|
238
|
+
};
|
|
239
|
+
this.annotationFileChanges.push(internal);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
convertDelete(file, fileMergeMaps, aliasInfo, change) {
|
|
243
|
+
const { reference } = change;
|
|
244
|
+
const { target, targetPointer: pointer, internalPointer } = (0, avt_1.findAnnotationByReference)(aliasInfo, file, fileMergeMaps[change.uri], reference, change.pointer, this.splitAnnotationSupport);
|
|
245
|
+
// look for attribute pointer suffix e.g attributes/Qualifier/value
|
|
246
|
+
const suffix = internalPointer.split('/').slice(-3);
|
|
247
|
+
if (suffix[0] === 'attributes' && suffix.length === 3) {
|
|
248
|
+
// its an attribute change
|
|
249
|
+
const [, , property] = suffix;
|
|
250
|
+
if (property === 'value') {
|
|
251
|
+
const internal = {
|
|
252
|
+
type: types_1.DELETE_ATTRIBUTE,
|
|
253
|
+
uri: change.uri,
|
|
254
|
+
pointer: pointer + internalPointer.split('/').slice(0, -1).join('/')
|
|
255
|
+
};
|
|
256
|
+
this.annotationFileChanges.push(internal);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else if (change.pointer === '') {
|
|
260
|
+
const internal = {
|
|
261
|
+
type: types_1.DELETE_ELEMENT,
|
|
262
|
+
target: target.name,
|
|
263
|
+
uri: change.uri,
|
|
264
|
+
pointer: pointer
|
|
265
|
+
};
|
|
266
|
+
this.annotationFileChanges.push(internal);
|
|
267
|
+
}
|
|
268
|
+
else if (internalPointer !== '') {
|
|
269
|
+
const internal = {
|
|
270
|
+
type: types_1.DELETE_ELEMENT,
|
|
271
|
+
uri: change.uri,
|
|
272
|
+
target: target.name,
|
|
273
|
+
pointer: pointer + internalPointer
|
|
274
|
+
};
|
|
275
|
+
this.annotationFileChanges.push(internal);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
convertUpdate(file, fileMergeMaps, aliasInfo, schemaProvider, change) {
|
|
279
|
+
var _a;
|
|
280
|
+
const { reference, content } = change;
|
|
281
|
+
const valueType = this.getValueType(schemaProvider, change);
|
|
282
|
+
const { element, targetPointer: pointer, internalPointer } = (0, avt_1.findAnnotationByReference)(aliasInfo, file, fileMergeMaps[change.uri], reference, change.pointer, this.splitAnnotationSupport, valueType);
|
|
283
|
+
if (internalPointer === '') {
|
|
284
|
+
// value does not exist, treat this as insert
|
|
285
|
+
this.convertInsert(file, fileMergeMaps, aliasInfo, change);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
// look for attribute pointer suffix e.g attributes/Qualifier/value
|
|
289
|
+
const suffix = internalPointer.split('/').slice(-3);
|
|
290
|
+
if (suffix[0] === 'attributes' && suffix.length === 3) {
|
|
291
|
+
// its an attribute change
|
|
292
|
+
const [, attributeName, property] = suffix;
|
|
293
|
+
this.convertUpdateAttribute(aliasInfo, attributeName, property, pointer, internalPointer, change);
|
|
294
|
+
}
|
|
295
|
+
else if (content.type === 'expression' && content.value.type === 'Collection') {
|
|
296
|
+
const node = (0, utils_1.getGenericNodeFromPointer)(file, pointer + internalPointer);
|
|
297
|
+
const newElement = (0, avt_1.convertExpressionToInternal)(aliasInfo, content.value);
|
|
298
|
+
if ((node === null || node === void 0 ? void 0 : node.type) === odata_annotation_core_types_1.ELEMENT_TYPE && newElement) {
|
|
299
|
+
const internalChange = {
|
|
300
|
+
type: types_1.REPLACE_ELEMENT,
|
|
301
|
+
uri: change.uri,
|
|
302
|
+
pointer: pointer + internalPointer,
|
|
303
|
+
newElement
|
|
304
|
+
};
|
|
305
|
+
this.annotationFileChanges.push(internalChange);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
else if (content.type === 'expression') {
|
|
309
|
+
this.convertUpdateExpression(file, aliasInfo, content, pointer + internalPointer, valueType);
|
|
310
|
+
}
|
|
311
|
+
else if (content.type === 'primitive' && content.value !== undefined) {
|
|
312
|
+
const internalPointerForPrimitiveValues = (0, avt_1.convertPointerInAnnotationToInternal)(element, change.pointer, content.expressionType);
|
|
313
|
+
const newValue = (0, avt_1.convertPrimitiveValueToInternal)((_a = content.expressionType) !== null && _a !== void 0 ? _a : '', content.value, aliasInfo);
|
|
314
|
+
const internal = {
|
|
315
|
+
type: types_1.REPLACE_TEXT,
|
|
316
|
+
uri: change.uri,
|
|
317
|
+
pointer: pointer + internalPointerForPrimitiveValues + '/text',
|
|
318
|
+
text: (0, odata_annotation_core_types_1.createTextNode)(newValue)
|
|
319
|
+
};
|
|
320
|
+
this.annotationFileChanges.push(internal);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
const element = convertChangeToElement(aliasInfo, file, change);
|
|
324
|
+
if (element) {
|
|
325
|
+
const internal = {
|
|
326
|
+
type: types_1.REPLACE_ELEMENT,
|
|
327
|
+
uri: change.uri,
|
|
328
|
+
pointer: pointer + internalPointer,
|
|
329
|
+
newElement: element
|
|
330
|
+
};
|
|
331
|
+
this.annotationFileChanges.push(internal);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
convertUpdateAttribute(aliasInfo, attributeName, property, pointer, internalPointer, change) {
|
|
336
|
+
var _a;
|
|
337
|
+
const value = this.getAttributeValue(change.content);
|
|
338
|
+
if (property === 'value' && value !== undefined) {
|
|
339
|
+
const type = (_a = this.getPrimitiveValueType(change.content)) !== null && _a !== void 0 ? _a : attributeName;
|
|
340
|
+
const newValue = (0, avt_1.convertPrimitiveValueToInternal)(type, value, aliasInfo);
|
|
341
|
+
const internal = {
|
|
342
|
+
type: types_1.UPDATE_ATTRIBUTE_VALUE,
|
|
343
|
+
uri: change.uri,
|
|
344
|
+
pointer: pointer + internalPointer.split('/').slice(0, -1).join('/'),
|
|
345
|
+
newValue
|
|
346
|
+
};
|
|
347
|
+
this.annotationFileChanges.push(internal);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
getPrimitiveValueType(content) {
|
|
351
|
+
if (content.type === 'primitive') {
|
|
352
|
+
if (content.expressionType === types_1.ExpressionType.Unknown) {
|
|
353
|
+
return undefined;
|
|
354
|
+
}
|
|
355
|
+
return content.expressionType;
|
|
356
|
+
}
|
|
357
|
+
if (content.type === 'expression') {
|
|
358
|
+
if (content.value.type === types_1.ExpressionType.Unknown) {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
return content.value.type;
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
getAttributeValue(content) {
|
|
366
|
+
if (content.type === 'primitive') {
|
|
367
|
+
return content.value;
|
|
368
|
+
}
|
|
369
|
+
if (content.type === 'expression') {
|
|
370
|
+
return this.getExpressionValue(content);
|
|
371
|
+
}
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
374
|
+
getExpressionValue(content) {
|
|
375
|
+
return content.value[content.value.type]; // There is always a property with on the object as type name, Typescript does not infer this case as expected
|
|
376
|
+
}
|
|
377
|
+
convertUpdateExpression(file, aliasInfo, content, pointer, valueType) {
|
|
378
|
+
const rawPrimitiveValue = this.getExpressionValue(content);
|
|
379
|
+
const newValue = (0, avt_1.convertPrimitiveValueToInternal)(content.value.type, rawPrimitiveValue, aliasInfo);
|
|
380
|
+
const type = valueType !== null && valueType !== void 0 ? valueType : content.value.type;
|
|
381
|
+
const node = (0, utils_1.getGenericNodeFromPointer)(file, pointer);
|
|
382
|
+
if ((node === null || node === void 0 ? void 0 : node.type) === odata_annotation_core_types_1.ELEMENT_TYPE) {
|
|
383
|
+
const onlyChangeValue = content.previousType === undefined && content.value.type === valueType;
|
|
384
|
+
if (onlyChangeValue && node.attributes[type]) {
|
|
385
|
+
// attribute notation
|
|
386
|
+
const internalChange = {
|
|
387
|
+
type: types_1.UPDATE_ATTRIBUTE_VALUE,
|
|
388
|
+
uri: file.uri,
|
|
389
|
+
pointer: pointer + `/attributes/${type}`,
|
|
390
|
+
newValue
|
|
391
|
+
};
|
|
392
|
+
this.annotationFileChanges.push(internalChange);
|
|
393
|
+
}
|
|
394
|
+
else if (onlyChangeValue && node.name === valueType) {
|
|
395
|
+
// element notation
|
|
396
|
+
const internalChange = {
|
|
397
|
+
type: types_1.REPLACE_ELEMENT_CONTENT,
|
|
398
|
+
uri: file.uri,
|
|
399
|
+
pointer: pointer,
|
|
400
|
+
newValue: [(0, odata_annotation_core_types_1.createTextNode)(newValue)]
|
|
401
|
+
};
|
|
402
|
+
this.annotationFileChanges.push(internalChange);
|
|
403
|
+
}
|
|
404
|
+
else if (node.attributes[type]) {
|
|
405
|
+
// attribute notation
|
|
406
|
+
const internalChange = {
|
|
407
|
+
type: types_1.REPLACE_ATTRIBUTE,
|
|
408
|
+
uri: file.uri,
|
|
409
|
+
pointer: pointer + `/attributes/${type}`,
|
|
410
|
+
newAttributeName: content.value.type,
|
|
411
|
+
newAttributeValue: newValue
|
|
412
|
+
};
|
|
413
|
+
this.annotationFileChanges.push(internalChange);
|
|
414
|
+
}
|
|
415
|
+
else if (node.name === valueType) {
|
|
416
|
+
// element notation
|
|
417
|
+
const internalChange = {
|
|
418
|
+
type: types_1.REPLACE_ELEMENT,
|
|
419
|
+
uri: file.uri,
|
|
420
|
+
pointer: pointer,
|
|
421
|
+
newElement: (0, odata_annotation_core_types_1.createElementNode)({
|
|
422
|
+
name: content.value.type,
|
|
423
|
+
content: [(0, odata_annotation_core_types_1.createTextNode)(newValue)]
|
|
424
|
+
})
|
|
425
|
+
};
|
|
426
|
+
this.annotationFileChanges.push(internalChange);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else if ((node === null || node === void 0 ? void 0 : node.type) === odata_annotation_core_types_1.ATTRIBUTE_TYPE) {
|
|
430
|
+
if (content.previousType === undefined && content.value.type === valueType) {
|
|
431
|
+
// attribute notation
|
|
432
|
+
const internalChange = {
|
|
433
|
+
type: types_1.UPDATE_ATTRIBUTE_VALUE,
|
|
434
|
+
uri: file.uri,
|
|
435
|
+
pointer: pointer,
|
|
436
|
+
newValue
|
|
437
|
+
};
|
|
438
|
+
this.annotationFileChanges.push(internalChange);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
// attribute notation
|
|
442
|
+
const internalChange = {
|
|
443
|
+
type: types_1.REPLACE_ATTRIBUTE,
|
|
444
|
+
uri: file.uri,
|
|
445
|
+
pointer: pointer,
|
|
446
|
+
newAttributeName: content.value.type,
|
|
447
|
+
newAttributeValue: newValue
|
|
448
|
+
};
|
|
449
|
+
this.annotationFileChanges.push(internalChange);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
convertMove(file, fileMergeMaps, aliasInfo, change) {
|
|
454
|
+
const { reference, index, moveReference } = change;
|
|
455
|
+
const { targetPointer: pointer, internalPointer } = (0, avt_1.findAnnotationByReference)(aliasInfo, file, fileMergeMaps[change.uri], reference, change.pointer, this.splitAnnotationSupport);
|
|
456
|
+
const internal = {
|
|
457
|
+
type: types_1.MOVE_ELEMENT,
|
|
458
|
+
uri: change.uri,
|
|
459
|
+
pointer: pointer + internalPointer,
|
|
460
|
+
index: index,
|
|
461
|
+
fromPointers: moveReference.reduce((acc, moveRef) => {
|
|
462
|
+
acc.push(...moveRef.fromPointer.map((fromPointer) => {
|
|
463
|
+
var _a;
|
|
464
|
+
const { targetPointer: fromTargetPointer, internalPointer: internalFromPointer } = (0, avt_1.findAnnotationByReference)(aliasInfo, file, fileMergeMaps[change.uri], (_a = moveRef.reference) !== null && _a !== void 0 ? _a : change.reference, fromPointer, this.splitAnnotationSupport);
|
|
465
|
+
return fromTargetPointer + internalFromPointer;
|
|
466
|
+
}));
|
|
467
|
+
return acc;
|
|
468
|
+
}, new Array())
|
|
469
|
+
};
|
|
470
|
+
this.annotationFileChanges.push(internal);
|
|
471
|
+
}
|
|
472
|
+
addTargetChanges(compiledService) {
|
|
473
|
+
const insertTargetChanges = [];
|
|
474
|
+
for (const [uri, changesForUri] of this.newTargetChanges) {
|
|
475
|
+
const file = compiledService.annotationFiles.find((file) => file.uri === uri);
|
|
476
|
+
if (!file) {
|
|
477
|
+
throw new Error(`Invalid change. File ${uri} does not exist.`);
|
|
478
|
+
}
|
|
479
|
+
const aliasInfoMod = this.getAliasInformation(file);
|
|
480
|
+
for (const [targetName, inserts] of changesForUri) {
|
|
481
|
+
const target = (0, odata_annotation_core_types_1.createTarget)(targetName);
|
|
482
|
+
target.terms = inserts.map((change) => (0, avt_1.convertAnnotationToInternal)(change.content.value, aliasInfoMod));
|
|
483
|
+
const internal = {
|
|
484
|
+
type: types_1.INSERT_TARGET,
|
|
485
|
+
uri: uri,
|
|
486
|
+
target
|
|
487
|
+
};
|
|
488
|
+
insertTargetChanges.push(internal);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
this.annotationFileChanges.unshift(...insertTargetChanges);
|
|
492
|
+
}
|
|
493
|
+
getValueType(schemaProvider, change) {
|
|
494
|
+
var _a;
|
|
495
|
+
const { reference, content, uri, pointer } = change;
|
|
496
|
+
if (content.type === 'expression') {
|
|
497
|
+
if (content.previousType) {
|
|
498
|
+
return content.previousType;
|
|
499
|
+
}
|
|
500
|
+
const annotationLists = (_a = schemaProvider().schema.annotations[uri]) !== null && _a !== void 0 ? _a : [];
|
|
501
|
+
const annotation = (0, avt_1.findAnnotation)(annotationLists, reference);
|
|
502
|
+
if (!annotation) {
|
|
503
|
+
const refString = (0, utils_1.annotationReferenceToString)(reference, uri);
|
|
504
|
+
throw new error_1.ApiError(`Could not find annotation '${refString}' in file '${uri}'.`, error_1.ApiErrorCode.General);
|
|
505
|
+
}
|
|
506
|
+
const node = (0, avt_1.getAvtNodeFromPointer)(annotation, pointer);
|
|
507
|
+
if (!node) {
|
|
508
|
+
const refString = (0, utils_1.annotationReferenceToString)(reference, uri);
|
|
509
|
+
throw new error_1.ApiError(`Could not resolve pointer '${pointer}' from annotation '${refString}'.`, error_1.ApiErrorCode.General);
|
|
510
|
+
}
|
|
511
|
+
if (this.isExpression(node)) {
|
|
512
|
+
return node.type;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return undefined;
|
|
516
|
+
}
|
|
517
|
+
isExpression(node) {
|
|
518
|
+
return typeof node.type !== 'undefined' && typeof node.propertyValues === 'undefined';
|
|
519
|
+
}
|
|
520
|
+
getAliasInformation(file) {
|
|
521
|
+
var _a;
|
|
522
|
+
const cachedValue = this.aliasInfoCache[file.uri];
|
|
523
|
+
if (cachedValue) {
|
|
524
|
+
return cachedValue;
|
|
525
|
+
}
|
|
526
|
+
const namespaces = (0, odata_annotation_core_1.getAllNamespacesAndReferences)((_a = file.namespace) !== null && _a !== void 0 ? _a : { name: this.serviceName, type: 'namespace' }, file.references);
|
|
527
|
+
const aliasInfo = (0, odata_annotation_core_1.getAliasInformation)(namespaces, this.metadataService.getNamespaces());
|
|
528
|
+
const aliasInfoWithAllVocabularies = (0, vocabularies_1.addAllVocabulariesToAliasInformation)(aliasInfo, this.vocabularyAPI.getVocabularies());
|
|
529
|
+
this.aliasInfoCache[file.uri] = aliasInfoWithAllVocabularies;
|
|
530
|
+
return aliasInfoWithAllVocabularies;
|
|
531
|
+
}
|
|
532
|
+
reset() {
|
|
533
|
+
this.aliasInfoCache = {};
|
|
534
|
+
this.newTargetChanges = new Map();
|
|
535
|
+
this.annotationFileChanges = [];
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
exports.ChangeConverter = ChangeConverter;
|
|
539
|
+
function mergeChanges(changes) {
|
|
540
|
+
const result = [];
|
|
541
|
+
const inserts = changes
|
|
542
|
+
.filter((change) => change.kind === types_1.ChangeType.InsertAnnotation)
|
|
543
|
+
.reduce((acc, change) => {
|
|
544
|
+
const reference = {
|
|
545
|
+
target: change.content.target,
|
|
546
|
+
term: change.content.value.term,
|
|
547
|
+
qualifier: change.content.value.qualifier
|
|
548
|
+
};
|
|
549
|
+
const key = (0, utils_1.annotationReferenceToString)(reference, change.uri);
|
|
550
|
+
acc.set(key, change);
|
|
551
|
+
return acc;
|
|
552
|
+
}, new Map());
|
|
553
|
+
for (const change of changes) {
|
|
554
|
+
if (change.kind === types_1.ChangeType.InsertAnnotation) {
|
|
555
|
+
// don't do anything with annotation inserts
|
|
556
|
+
result.push(change);
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
const key = (0, utils_1.annotationReferenceToString)(change.reference, change.uri);
|
|
560
|
+
const insert = inserts.get(key);
|
|
561
|
+
if (!insert) {
|
|
562
|
+
// reference should exist -> continue normally
|
|
563
|
+
result.push(change);
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
// new annotation should exist only in memory -> merge changes
|
|
567
|
+
mergeChange(insert, change);
|
|
568
|
+
}
|
|
569
|
+
return result;
|
|
570
|
+
}
|
|
571
|
+
function mergeChange(target, source) {
|
|
572
|
+
const reference = (0, utils_1.annotationReferenceToString)(source.reference, source.uri);
|
|
573
|
+
switch (source.kind) {
|
|
574
|
+
case types_1.ChangeType.InsertEmbeddedAnnotation: {
|
|
575
|
+
if (target.content.value.annotations) {
|
|
576
|
+
target.content.value.annotations.push(source.content.value);
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
target.content.value.annotations = [source.content.value];
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
case types_1.ChangeType.Insert: {
|
|
584
|
+
const node = (0, avt_1.getAvtNodeFromPointer)(target.content.value, source.pointer);
|
|
585
|
+
if (!node) {
|
|
586
|
+
throw new error_1.ApiError(`Change merge for '${reference}' failed! Could not resolve '${source.pointer}'.`, error_1.ApiErrorCode.General);
|
|
587
|
+
}
|
|
588
|
+
if (Array.isArray(node) && source.content.type === 'record') {
|
|
589
|
+
if (source.index === undefined || source.index >= node.length) {
|
|
590
|
+
node.push(source.content.value);
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
node.splice(source.index, 0, source.content.value);
|
|
594
|
+
}
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
throw new error_1.ApiError(`Change merge for '${reference}' failed! Change value type '${source.content.type}' is not supported.`, error_1.ApiErrorCode.General);
|
|
598
|
+
}
|
|
599
|
+
default:
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
throw new error_1.ApiError(`Change merge for '${reference}' failed! Change type '${source.kind}' is not supported.`, error_1.ApiErrorCode.General);
|
|
603
|
+
}
|
|
604
|
+
function convertChangeToElement(aliasInfoMod, file, change) {
|
|
605
|
+
if (change.content.type === 'record') {
|
|
606
|
+
const { content } = change;
|
|
607
|
+
return (0, avt_1.convertRecordToInternal)(aliasInfoMod, content.value);
|
|
608
|
+
}
|
|
609
|
+
else if (change.content.type === 'property-value') {
|
|
610
|
+
const { content } = change;
|
|
611
|
+
return (0, avt_1.convertPropertyValueToInternal)(aliasInfoMod, content.value);
|
|
612
|
+
}
|
|
613
|
+
else if (change.content.type === 'collection') {
|
|
614
|
+
const { content } = change;
|
|
615
|
+
return (0, avt_1.convertCollectionToInternal)(aliasInfoMod, content.value);
|
|
616
|
+
}
|
|
617
|
+
else if (change.content.type === 'expression') {
|
|
618
|
+
const { content } = change;
|
|
619
|
+
return (0, avt_1.convertExpressionToInternal)(aliasInfoMod, content.value);
|
|
620
|
+
}
|
|
621
|
+
else if (change.content.type === 'primitive') {
|
|
622
|
+
const { content } = change;
|
|
623
|
+
if (content.expressionType === types_1.ExpressionType.Null) {
|
|
624
|
+
return (0, odata_annotation_core_types_1.createElementNode)({ name: "Null" /* Edm.Null */ });
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return undefined;
|
|
628
|
+
}
|
|
629
|
+
function getAttributeNameFromPointer(pointer) {
|
|
630
|
+
const lastSegment = pointer.split('/').slice(-1)[0];
|
|
631
|
+
// new primitive value: can always be added as attributes, namespaces are already replaced
|
|
632
|
+
if (lastSegment === null || lastSegment === void 0 ? void 0 : lastSegment.length) {
|
|
633
|
+
// convert property names used in AVT types to attribute names (e.g. 'type', 'term' and 'qualifier')
|
|
634
|
+
// (EDMX Attribute names always start with upper case letter)
|
|
635
|
+
return lastSegment.substring(0, 1).toUpperCase() + lastSegment.substring(1);
|
|
636
|
+
}
|
|
637
|
+
return undefined;
|
|
638
|
+
}
|
|
639
|
+
//# sourceMappingURL=change-converter.js.map
|