@sap-ux/fiori-annotation-api 0.11.0 → 1.0.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/dist/annotation-provider.d.ts +1 -1
- package/dist/annotation-provider.d.ts.map +1 -1
- package/dist/annotation-provider.js +30 -36
- package/dist/annotation-provider.js.map +1 -1
- package/dist/avt/annotations.js +53 -56
- package/dist/avt/annotations.js.map +1 -1
- package/dist/avt/expressions.js +3 -7
- package/dist/avt/expressions.js.map +1 -1
- package/dist/avt/find.d.ts +2 -2
- package/dist/avt/find.d.ts.map +1 -1
- package/dist/avt/find.js +16 -20
- package/dist/avt/find.js.map +1 -1
- package/dist/avt/index.d.ts +8 -8
- package/dist/avt/index.d.ts.map +1 -1
- package/dist/avt/index.js +7 -31
- package/dist/avt/index.js.map +1 -1
- package/dist/avt/metadata.js +1 -4
- package/dist/avt/metadata.js.map +1 -1
- package/dist/avt/pointer.d.ts +1 -1
- package/dist/avt/pointer.d.ts.map +1 -1
- package/dist/avt/pointer.js +12 -15
- package/dist/avt/pointer.js.map +1 -1
- package/dist/avt/to-internal.d.ts +1 -1
- package/dist/avt/to-internal.d.ts.map +1 -1
- package/dist/avt/to-internal.js +53 -65
- package/dist/avt/to-internal.js.map +1 -1
- package/dist/avt/types.js +1 -2
- package/dist/avt/utils.d.ts +2 -2
- package/dist/avt/utils.d.ts.map +1 -1
- package/dist/avt/utils.js +11 -20
- package/dist/avt/utils.js.map +1 -1
- package/dist/cds/adapter.d.ts +5 -5
- package/dist/cds/adapter.d.ts.map +1 -1
- package/dist/cds/adapter.js +184 -187
- package/dist/cds/adapter.js.map +1 -1
- package/dist/cds/cds-compiler-tokens.js +11 -21
- package/dist/cds/cds-compiler-tokens.js.map +1 -1
- package/dist/cds/change.d.ts +1 -1
- package/dist/cds/change.d.ts.map +1 -1
- package/dist/cds/change.js +63 -79
- package/dist/cds/change.js.map +1 -1
- package/dist/cds/comments.d.ts +1 -1
- package/dist/cds/comments.d.ts.map +1 -1
- package/dist/cds/comments.js +4 -7
- package/dist/cds/comments.js.map +1 -1
- package/dist/cds/deletion.d.ts +1 -1
- package/dist/cds/deletion.d.ts.map +1 -1
- package/dist/cds/deletion.js +74 -61
- package/dist/cds/deletion.js.map +1 -1
- package/dist/cds/document.d.ts +4 -4
- package/dist/cds/document.d.ts.map +1 -1
- package/dist/cds/document.js +20 -27
- package/dist/cds/document.js.map +1 -1
- package/dist/cds/indent.d.ts +2 -2
- package/dist/cds/indent.d.ts.map +1 -1
- package/dist/cds/indent.js +16 -20
- package/dist/cds/indent.js.map +1 -1
- package/dist/cds/index.d.ts +2 -2
- package/dist/cds/index.d.ts.map +1 -1
- package/dist/cds/index.js +4 -22
- package/dist/cds/index.js.map +1 -1
- package/dist/cds/pointer.d.ts +1 -1
- package/dist/cds/pointer.d.ts.map +1 -1
- package/dist/cds/pointer.js +38 -42
- package/dist/cds/pointer.js.map +1 -1
- package/dist/cds/preprocessor.d.ts +3 -3
- package/dist/cds/preprocessor.d.ts.map +1 -1
- package/dist/cds/preprocessor.js +91 -95
- package/dist/cds/preprocessor.js.map +1 -1
- package/dist/cds/references.d.ts +2 -2
- package/dist/cds/references.d.ts.map +1 -1
- package/dist/cds/references.js +49 -55
- package/dist/cds/references.js.map +1 -1
- package/dist/cds/service.d.ts +1 -1
- package/dist/cds/service.d.ts.map +1 -1
- package/dist/cds/service.js +6 -8
- package/dist/cds/service.js.map +1 -1
- package/dist/cds/utils.d.ts +2 -2
- package/dist/cds/utils.d.ts.map +1 -1
- package/dist/cds/utils.js +20 -24
- package/dist/cds/utils.js.map +1 -1
- package/dist/cds/writer.d.ts +6 -6
- package/dist/cds/writer.d.ts.map +1 -1
- package/dist/cds/writer.js +199 -202
- package/dist/cds/writer.js.map +1 -1
- package/dist/change-converter.d.ts +1 -1
- package/dist/change-converter.d.ts.map +1 -1
- package/dist/change-converter.js +124 -128
- package/dist/change-converter.js.map +1 -1
- package/dist/error.js +3 -7
- package/dist/error.js.map +1 -1
- package/dist/external-services.d.ts +1 -1
- package/dist/external-services.d.ts.map +1 -1
- package/dist/external-services.js +10 -13
- package/dist/external-services.js.map +1 -1
- package/dist/fiori-service.d.ts +4 -4
- package/dist/fiori-service.d.ts.map +1 -1
- package/dist/fiori-service.js +41 -45
- package/dist/fiori-service.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -31
- package/dist/index.js.map +1 -1
- package/dist/logger.js +2 -5
- package/dist/logger.js.map +1 -1
- package/dist/protected.d.ts +2 -2
- package/dist/protected.d.ts.map +1 -1
- package/dist/protected.js +2 -8
- package/dist/protected.js.map +1 -1
- package/dist/sap/builders.d.ts +1 -1
- package/dist/sap/builders.d.ts.map +1 -1
- package/dist/sap/builders.js +22 -30
- package/dist/sap/builders.js.map +1 -1
- package/dist/sap/collector.d.ts +1 -1
- package/dist/sap/collector.d.ts.map +1 -1
- package/dist/sap/collector.js +50 -53
- package/dist/sap/collector.js.map +1 -1
- package/dist/sap/converter.d.ts +1 -1
- package/dist/sap/converter.d.ts.map +1 -1
- package/dist/sap/converter.js +37 -42
- package/dist/sap/converter.js.map +1 -1
- package/dist/sap/index.d.ts +1 -1
- package/dist/sap/index.d.ts.map +1 -1
- package/dist/sap/index.js +1 -6
- package/dist/sap/index.js.map +1 -1
- package/dist/sap/types.js +5 -8
- package/dist/sap/types.js.map +1 -1
- package/dist/types/adapter.d.ts +3 -3
- package/dist/types/adapter.d.ts.map +1 -1
- package/dist/types/adapter.js +1 -2
- package/dist/types/change.js +11 -14
- package/dist/types/change.js.map +1 -1
- package/dist/types/index.d.ts +6 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -32
- package/dist/types/index.js.map +1 -1
- package/dist/types/internal-change.d.ts +1 -1
- package/dist/types/internal-change.d.ts.map +1 -1
- package/dist/types/internal-change.js +13 -16
- package/dist/types/internal-change.js.map +1 -1
- package/dist/types/project-info.js +1 -2
- package/dist/types/service.d.ts +1 -1
- package/dist/types/service.d.ts.map +1 -1
- package/dist/types/service.js +1 -2
- package/dist/types/text-file.js +1 -2
- package/dist/utils/constants.js +20 -22
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/indent.js +1 -4
- package/dist/utils/indent.js.map +1 -1
- package/dist/utils/index.d.ts +7 -7
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +7 -17
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/metadata.js +1 -4
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/path.js +5 -8
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/pointer.d.ts +1 -1
- package/dist/utils/pointer.d.ts.map +1 -1
- package/dist/utils/pointer.js +1 -4
- package/dist/utils/pointer.js.map +1 -1
- package/dist/utils/range.js +1 -4
- package/dist/utils/range.js.map +1 -1
- package/dist/utils/reference.d.ts +1 -1
- package/dist/utils/reference.d.ts.map +1 -1
- package/dist/utils/reference.js +1 -4
- package/dist/utils/reference.js.map +1 -1
- package/dist/vocabularies.js +1 -4
- package/dist/vocabularies.js.map +1 -1
- package/dist/xml/adapter.d.ts +2 -2
- package/dist/xml/adapter.d.ts.map +1 -1
- package/dist/xml/adapter.js +92 -96
- package/dist/xml/adapter.js.map +1 -1
- package/dist/xml/changes.d.ts +1 -1
- package/dist/xml/changes.d.ts.map +1 -1
- package/dist/xml/changes.js +11 -15
- package/dist/xml/changes.js.map +1 -1
- package/dist/xml/comments.js +3 -6
- package/dist/xml/comments.js.map +1 -1
- package/dist/xml/document.d.ts +1 -1
- package/dist/xml/document.d.ts.map +1 -1
- package/dist/xml/document.js +1 -2
- package/dist/xml/index.d.ts +2 -2
- package/dist/xml/index.d.ts.map +1 -1
- package/dist/xml/index.js +4 -9
- package/dist/xml/index.js.map +1 -1
- package/dist/xml/pointer.js +1 -4
- package/dist/xml/pointer.js.map +1 -1
- package/dist/xml/references.js +15 -18
- package/dist/xml/references.js.map +1 -1
- package/dist/xml/service.d.ts +1 -1
- package/dist/xml/service.d.ts.map +1 -1
- package/dist/xml/service.js +4 -7
- package/dist/xml/service.js.map +1 -1
- package/dist/xml/writer.d.ts +2 -2
- package/dist/xml/writer.d.ts.map +1 -1
- package/dist/xml/writer.js +100 -104
- package/dist/xml/writer.js.map +1 -1
- package/package.json +13 -11
package/dist/cds/adapter.js
CHANGED
|
@@ -1,38 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const change_1 = require("./change");
|
|
24
|
-
const internal_change_1 = require("../types/internal-change");
|
|
1
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
2
|
+
import { basename, dirname, join, relative, sep } from 'node:path';
|
|
3
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
4
|
+
import cdsCompilerFacade from '@sap/ux-cds-compiler-facade';
|
|
5
|
+
const { createCdsCompilerFacadeForRoot, createMetadataCollector, getMetadataElementsFromMap } = cdsCompilerFacade;
|
|
6
|
+
import { TEXT_TYPE, ELEMENT_TYPE, DiagnosticSeverity, createAttributeNode, createElementNode, createTextNode, ANNOTATION_FILE_TYPE, Range } from '@sap-ux/odata-annotation-core-types';
|
|
7
|
+
import { MetadataService } from '@sap-ux/odata-entity-model';
|
|
8
|
+
import { ANNOTATION_GROUP_ITEMS_TYPE, ANNOTATION_GROUP_TYPE, ANNOTATION_TYPE, COLLECTION_TYPE, QUALIFIER_TYPE, RECORD_PROPERTY_TYPE, RECORD_TYPE, isReservedProperty } from '@sap-ux/cds-annotation-parser';
|
|
9
|
+
import { Edm, getAliasInformation, getAllNamespacesAndReferences, getElementAttribute, getElementAttributeValue, isElementWithName, parseIdentifier, toFullyQualifiedName } from '@sap-ux/odata-annotation-core';
|
|
10
|
+
import { TARGET_TYPE, printTarget } from '@sap-ux/cds-odata-annotation-converter';
|
|
11
|
+
import { convertTargets } from '../sap/index.js';
|
|
12
|
+
import { logger } from '../logger.js';
|
|
13
|
+
import { INSERT_TARGET, DELETE_ELEMENT, INSERT_ELEMENT, INSERT_ATTRIBUTE, DELETE_ATTRIBUTE, UPDATE_ATTRIBUTE_VALUE } from '../types/index.js';
|
|
14
|
+
import { ApiError, ApiErrorCode } from '../error.js';
|
|
15
|
+
import { CDSWriter } from './writer.js';
|
|
16
|
+
import { getMissingRefs } from './references.js';
|
|
17
|
+
import { addAllVocabulariesToAliasInformation } from '../vocabularies.js';
|
|
18
|
+
import { CDS_DOCUMENT_TYPE, getDocument, getGhostFileDocument } from './document.js';
|
|
19
|
+
import { convertPointer, getAstNodesFromPointer } from './pointer.js';
|
|
20
|
+
import { getGenericNodeFromPointer, pathFromUri, PRIMITIVE_TYPE_NAMES } from '../utils/index.js';
|
|
21
|
+
import { INSERT_PRIMITIVE_VALUE_TYPE, INSERT_TARGET_CHANGE_TYPE, createDeleteAnnotationChange, createDeleteQualifierChange, createInsertCollectionChange, createInsertEmbeddedAnnotationChange, createInsertPrimitiveValueChange, createInsertRecordChange, createInsertRecordPropertyChange, createInsertReferenceChange, createInsertTargetChange, createUpdatePrimitiveValueChange } from './change.js';
|
|
22
|
+
import { DELETE_REFERENCE, MOVE_ELEMENT, REPLACE_ATTRIBUTE, REPLACE_ELEMENT, REPLACE_ELEMENT_CONTENT, REPLACE_TEXT, UPDATE_ELEMENT_NAME } from '../types/internal-change.js';
|
|
25
23
|
/**
|
|
26
24
|
*
|
|
27
25
|
*/
|
|
28
|
-
class CDSAnnotationServiceAdapter {
|
|
26
|
+
export class CDSAnnotationServiceAdapter {
|
|
29
27
|
service;
|
|
30
28
|
project;
|
|
31
29
|
vocabularyService;
|
|
32
30
|
appName;
|
|
33
31
|
writeSapAnnotations;
|
|
34
32
|
ignoreChangedFileInitialContent;
|
|
35
|
-
metadataService = new
|
|
33
|
+
metadataService = new MetadataService();
|
|
36
34
|
splitAnnotationSupport = true;
|
|
37
35
|
fileCache;
|
|
38
36
|
documents = new Map();
|
|
@@ -85,24 +83,24 @@ class CDSAnnotationServiceAdapter {
|
|
|
85
83
|
* @returns Sync errors
|
|
86
84
|
*/
|
|
87
85
|
async sync(fileCache) {
|
|
88
|
-
const paths = [...this.service.serviceFiles.map((file) =>
|
|
89
|
-
const facade = await
|
|
86
|
+
const paths = [...this.service.serviceFiles.map((file) => fileURLToPath(file.uri))];
|
|
87
|
+
const facade = await createCdsCompilerFacadeForRoot(this.project.root, paths, fileCache);
|
|
90
88
|
this.setFacade(facade);
|
|
91
89
|
const compileErrors = facade.getCompilerErrors(this.project.root);
|
|
92
90
|
const relevantErrors = [...compileErrors].filter(([file, compilerMessage]) => {
|
|
93
|
-
return (compilerMessage.messages.filter((value) => value.severity ===
|
|
91
|
+
return (compilerMessage.messages.filter((value) => value.severity === DiagnosticSeverity.Error).length &&
|
|
94
92
|
!file.startsWith('../'));
|
|
95
93
|
});
|
|
96
94
|
if (relevantErrors.length > 0) {
|
|
97
95
|
// if model has compiler errors
|
|
98
96
|
for (const [relativePath, compilerMessage] of relevantErrors) {
|
|
99
|
-
|
|
97
|
+
logger.log(`Compile errors in: ${relativePath}`);
|
|
100
98
|
for (const [fileUri, content] of fileCache) {
|
|
101
99
|
if (fileUri.endsWith(relativePath)) {
|
|
102
|
-
|
|
100
|
+
logger.log(content);
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
|
-
|
|
103
|
+
logger.log(JSON.stringify(compilerMessage, undefined, 2));
|
|
106
104
|
}
|
|
107
105
|
return compileErrors;
|
|
108
106
|
}
|
|
@@ -112,19 +110,19 @@ class CDSAnnotationServiceAdapter {
|
|
|
112
110
|
this.setFileCache(fileCache);
|
|
113
111
|
const metadataElementMap = facade.getMetadata(this.service.serviceName);
|
|
114
112
|
// We collect already full metadata from compile model, we don't need to build it based on paths.
|
|
115
|
-
const metadataCollector =
|
|
113
|
+
const metadataCollector = createMetadataCollector(new Map(), facade);
|
|
116
114
|
const { propagationMap, sourceUris } = facade.getPropagatedTargetMap(this.service.serviceName);
|
|
117
115
|
for (const file of this.service.serviceFiles) {
|
|
118
|
-
const document =
|
|
116
|
+
const document = getDocument(this.service.serviceName, this.vocabularyService, facade, fileCache, file, metadataCollector);
|
|
119
117
|
this.documents.set(file.uri, document);
|
|
120
118
|
// ghost files
|
|
121
|
-
if (sourceUris.has(
|
|
122
|
-
const ghostDoc =
|
|
119
|
+
if (sourceUris.has(relative(this.project.root, fileURLToPath(file.uri)))) {
|
|
120
|
+
const ghostDoc = getGhostFileDocument(this.service.serviceName, this.vocabularyService, facade, fileCache, file, metadataCollector, propagationMap);
|
|
123
121
|
this.documents.set(ghostDoc.annotationFile.uri, ghostDoc);
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
|
-
const metadataElements =
|
|
127
|
-
this.metadataService = new
|
|
124
|
+
const metadataElements = getMetadataElementsFromMap(metadataElementMap);
|
|
125
|
+
this.metadataService = new MetadataService({ uriMap: facade?.getUriMap() || new Map() });
|
|
128
126
|
this.metadataService.import(metadataElements, 'DummyMetadataFileUri');
|
|
129
127
|
return new Map();
|
|
130
128
|
}
|
|
@@ -169,9 +167,9 @@ class CDSAnnotationServiceAdapter {
|
|
|
169
167
|
getInitialFileContent(serviceName, uri) {
|
|
170
168
|
if (this.facade) {
|
|
171
169
|
const fileName = this.facade.getFileName(serviceName) ?? '';
|
|
172
|
-
let path =
|
|
173
|
-
path =
|
|
174
|
-
path = path.split(
|
|
170
|
+
let path = relative(dirname(uri), join(this.project.root, dirname(fileName))).replace(/\\/g, '/');
|
|
171
|
+
path = join(path, basename(fileName, '.cds'));
|
|
172
|
+
path = path.split(sep).join('/'); // always use '/' instead of platform specific separator
|
|
175
173
|
return `using ${serviceName} as service from '${path}';\n`;
|
|
176
174
|
}
|
|
177
175
|
return '';
|
|
@@ -244,13 +242,13 @@ class CDSAnnotationServiceAdapter {
|
|
|
244
242
|
// only writing to a single files is supported
|
|
245
243
|
const uri = changes[0].uri;
|
|
246
244
|
const writer = this.getWriterForChange(writers, changes[0]);
|
|
247
|
-
const targets =
|
|
245
|
+
const targets = convertTargets({
|
|
248
246
|
[uri]: changes
|
|
249
247
|
.map((change) => {
|
|
250
|
-
if (change.type ===
|
|
248
|
+
if (change.type === INSERT_TARGET) {
|
|
251
249
|
const annotationFile = this.documents.get(change.uri)?.annotationFile ?? this.createEmptyAnnotationFile(change);
|
|
252
250
|
const aliasInfo = getAliasInfo(annotationFile, this.metadataService, this.vocabularyService);
|
|
253
|
-
const missingReferences =
|
|
251
|
+
const missingReferences = getMissingRefs(this.documents, change.uri, change.target.name, change.target, aliasInfo, this.metadataService, {
|
|
254
252
|
apps: Object.keys(this.project.apps),
|
|
255
253
|
projectRoot: this.project.root,
|
|
256
254
|
appName: this.appName
|
|
@@ -258,13 +256,13 @@ class CDSAnnotationServiceAdapter {
|
|
|
258
256
|
this.addMissingReferences(change.uri, missingReferences);
|
|
259
257
|
return change.target;
|
|
260
258
|
}
|
|
261
|
-
|
|
259
|
+
logger.warn(`Change type "${change.type}" is not supported when "writeSapAnnotations" parameter is set.`);
|
|
262
260
|
return undefined;
|
|
263
261
|
})
|
|
264
262
|
.filter((target) => !!target)
|
|
265
263
|
});
|
|
266
264
|
for (const target of targets) {
|
|
267
|
-
writer.addChange(
|
|
265
|
+
writer.addChange(createInsertTargetChange('target', target));
|
|
268
266
|
}
|
|
269
267
|
}
|
|
270
268
|
getWriterForChange(writers, change) {
|
|
@@ -278,7 +276,7 @@ class CDSAnnotationServiceAdapter {
|
|
|
278
276
|
}
|
|
279
277
|
createEmptyAnnotationFile(change) {
|
|
280
278
|
return {
|
|
281
|
-
type:
|
|
279
|
+
type: ANNOTATION_FILE_TYPE,
|
|
282
280
|
uri: change.uri,
|
|
283
281
|
references: [],
|
|
284
282
|
targets: []
|
|
@@ -290,16 +288,16 @@ class CDSAnnotationServiceAdapter {
|
|
|
290
288
|
if (!this.facade) {
|
|
291
289
|
throw new Error(`CDS facade not available!`);
|
|
292
290
|
}
|
|
293
|
-
if (change.type !==
|
|
291
|
+
if (change.type !== INSERT_TARGET_CHANGE_TYPE) {
|
|
294
292
|
throw new Error(`Change "${change.type}" type is not supported with parameter "${this.ignoreChangedFileInitialContent}".`);
|
|
295
293
|
}
|
|
296
|
-
const textDocument =
|
|
297
|
-
return new
|
|
298
|
-
type:
|
|
294
|
+
const textDocument = TextDocument.create(change.uri, 'cds', 0, '');
|
|
295
|
+
return new CDSWriter(this.facade, this.vocabularyService, {
|
|
296
|
+
type: CDS_DOCUMENT_TYPE,
|
|
299
297
|
uri: change.uri,
|
|
300
298
|
references: [],
|
|
301
299
|
targets: [],
|
|
302
|
-
range:
|
|
300
|
+
range: Range.create(0, 0, 0, 0)
|
|
303
301
|
}, [], [], textDocument, this.project.root, this.createEmptyAnnotationFile(change));
|
|
304
302
|
}
|
|
305
303
|
else {
|
|
@@ -307,8 +305,8 @@ class CDSAnnotationServiceAdapter {
|
|
|
307
305
|
if (!document || cachedFile === undefined || !this.facade) {
|
|
308
306
|
throw new Error(`CDS document "${change.uri}" is not found!`);
|
|
309
307
|
}
|
|
310
|
-
const textDocument =
|
|
311
|
-
return new
|
|
308
|
+
const textDocument = TextDocument.create(change.uri, 'cds', 0, cachedFile);
|
|
309
|
+
return new CDSWriter(this.facade, this.vocabularyService, document.ast, document.comments, document.tokens, textDocument, this.project.root, document.annotationFile);
|
|
312
310
|
}
|
|
313
311
|
}
|
|
314
312
|
/**
|
|
@@ -327,7 +325,7 @@ class CDSAnnotationServiceAdapter {
|
|
|
327
325
|
* @returns CDS representation of the annotations.
|
|
328
326
|
*/
|
|
329
327
|
serializeTarget(target) {
|
|
330
|
-
return
|
|
328
|
+
return printTarget(target);
|
|
331
329
|
}
|
|
332
330
|
_getCompiledService() {
|
|
333
331
|
const annotationFiles = [];
|
|
@@ -341,7 +339,7 @@ class CDSAnnotationServiceAdapter {
|
|
|
341
339
|
annotationFiles.push(document.annotationFile);
|
|
342
340
|
}
|
|
343
341
|
else {
|
|
344
|
-
throw new
|
|
342
|
+
throw new ApiError(`Could not compile service. Missing document ${file.uri}`, ApiErrorCode.General);
|
|
345
343
|
}
|
|
346
344
|
}
|
|
347
345
|
annotationFiles.reverse();
|
|
@@ -360,7 +358,7 @@ class CDSAnnotationServiceAdapter {
|
|
|
360
358
|
}
|
|
361
359
|
updateFileSequence(facade) {
|
|
362
360
|
this._fileSequence = facade.getFileSequence().map((uri) => ({
|
|
363
|
-
uri:
|
|
361
|
+
uri: pathToFileURL(uri).toString(),
|
|
364
362
|
isReadOnly: uri.indexOf('node_modules') !== -1
|
|
365
363
|
}));
|
|
366
364
|
this.service.serviceFiles = [...this._fileSequence];
|
|
@@ -372,14 +370,14 @@ class CDSAnnotationServiceAdapter {
|
|
|
372
370
|
const normalizedReferences = [...missingReferences].map((reference) => {
|
|
373
371
|
if (reference.startsWith('file://')) {
|
|
374
372
|
// uri => convert to relative path to root
|
|
375
|
-
const path =
|
|
376
|
-
return
|
|
373
|
+
const path = pathFromUri(reference);
|
|
374
|
+
return relative(this.project.root, path);
|
|
377
375
|
}
|
|
378
376
|
else {
|
|
379
377
|
return reference;
|
|
380
378
|
}
|
|
381
379
|
});
|
|
382
|
-
writer.addChange(
|
|
380
|
+
writer.addChange(createInsertReferenceChange(pointer, normalizedReferences));
|
|
383
381
|
}
|
|
384
382
|
}
|
|
385
383
|
addMissingReferences(uri, references) {
|
|
@@ -388,9 +386,9 @@ class CDSAnnotationServiceAdapter {
|
|
|
388
386
|
missingReferences.add(reference);
|
|
389
387
|
}
|
|
390
388
|
}
|
|
391
|
-
[
|
|
389
|
+
[INSERT_TARGET] = (writer, document, change) => {
|
|
392
390
|
const aliasInfo = getAliasInfo(document.annotationFile, this.metadataService, this.vocabularyService);
|
|
393
|
-
const missingReferences =
|
|
391
|
+
const missingReferences = getMissingRefs(this.documents, change.uri, change.target.name, change.target, aliasInfo, this.metadataService, {
|
|
394
392
|
apps: Object.keys(this.project.apps),
|
|
395
393
|
projectRoot: this.project.root,
|
|
396
394
|
appName: this.appName
|
|
@@ -400,8 +398,8 @@ class CDSAnnotationServiceAdapter {
|
|
|
400
398
|
const targetName = change.target.name;
|
|
401
399
|
const pathSegments = targetName.split('/');
|
|
402
400
|
const pathBase = pathSegments.shift() ?? '';
|
|
403
|
-
const parsedName =
|
|
404
|
-
const fullyQualifiedPath =
|
|
401
|
+
const parsedName = parseIdentifier(pathBase);
|
|
402
|
+
const fullyQualifiedPath = toFullyQualifiedName(aliasInfo.aliasMap, aliasInfo.currentFileNamespace, parsedName) ?? '';
|
|
405
403
|
const metadataElement = this.metadataService.getMetadataElement(fullyQualifiedPath);
|
|
406
404
|
const fqName = metadataElement?.originalName ?? pathBase;
|
|
407
405
|
let originalPathBase = fqName;
|
|
@@ -418,37 +416,37 @@ class CDSAnnotationServiceAdapter {
|
|
|
418
416
|
const complexType = this.metadataService.getMetadataElement(`${fqName}/${segments[0]}`);
|
|
419
417
|
if (complexType?.structuredType && complexType.isComplexType) {
|
|
420
418
|
const element = this.metadataService.getMetadataElement(`${fqName}/${pathSegments[0]}`);
|
|
421
|
-
if (element?.kind ===
|
|
419
|
+
if (element?.kind === ELEMENT_TYPE) {
|
|
422
420
|
complexTypePathSegments = pathSegments[0].split('_');
|
|
423
421
|
}
|
|
424
422
|
}
|
|
425
423
|
}
|
|
426
|
-
writer.addChange(
|
|
424
|
+
writer.addChange(createInsertTargetChange('target', change.target, undefined, complexTypePathSegments));
|
|
427
425
|
};
|
|
428
|
-
[
|
|
429
|
-
const { pointer } =
|
|
430
|
-
const [currentAstNode, parentAstNode, , greatGrandParentAstNode] =
|
|
431
|
-
if (currentAstNode?.type ===
|
|
426
|
+
[DELETE_ELEMENT] = (writer, document, change) => {
|
|
427
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
428
|
+
const [currentAstNode, parentAstNode, , greatGrandParentAstNode] = getAstNodesFromPointer(document.ast, pointer).reverse();
|
|
429
|
+
if (currentAstNode?.type === RECORD_PROPERTY_TYPE) {
|
|
432
430
|
writer.addChange({
|
|
433
431
|
type: 'delete-record-property',
|
|
434
432
|
pointer: pointer
|
|
435
433
|
});
|
|
436
434
|
}
|
|
437
|
-
else if (currentAstNode?.type ===
|
|
435
|
+
else if (currentAstNode?.type === ANNOTATION_TYPE && parentAstNode.type === RECORD_TYPE) {
|
|
438
436
|
// embedded annotation
|
|
439
437
|
writer.addChange({
|
|
440
438
|
type: 'delete-embedded-annotation',
|
|
441
439
|
pointer: pointer
|
|
442
440
|
});
|
|
443
441
|
}
|
|
444
|
-
else if (currentAstNode.type ===
|
|
442
|
+
else if (currentAstNode.type === TARGET_TYPE) {
|
|
445
443
|
writer.addChange({
|
|
446
444
|
type: 'delete-target',
|
|
447
445
|
pointer: pointer
|
|
448
446
|
});
|
|
449
447
|
}
|
|
450
|
-
else if ((currentAstNode?.type ===
|
|
451
|
-
(currentAstNode?.type ===
|
|
448
|
+
else if ((currentAstNode?.type === ANNOTATION_TYPE && parentAstNode.type === TARGET_TYPE) ||
|
|
449
|
+
(currentAstNode?.type === ANNOTATION_TYPE && parentAstNode.type === ANNOTATION_GROUP_ITEMS_TYPE)) {
|
|
452
450
|
writer.addChange({
|
|
453
451
|
type: 'delete-annotation',
|
|
454
452
|
pointer: pointer,
|
|
@@ -456,7 +454,7 @@ class CDSAnnotationServiceAdapter {
|
|
|
456
454
|
});
|
|
457
455
|
checkAndDeleteFlattenedStructures(writer, document, change, parentAstNode, greatGrandParentAstNode);
|
|
458
456
|
}
|
|
459
|
-
else if (currentAstNode?.type ===
|
|
457
|
+
else if (currentAstNode?.type === RECORD_TYPE) {
|
|
460
458
|
writer.addChange({
|
|
461
459
|
type: 'delete-record',
|
|
462
460
|
pointer: pointer
|
|
@@ -474,40 +472,40 @@ class CDSAnnotationServiceAdapter {
|
|
|
474
472
|
});
|
|
475
473
|
}
|
|
476
474
|
else {
|
|
477
|
-
throw new
|
|
475
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} `, ApiErrorCode.General);
|
|
478
476
|
}
|
|
479
477
|
};
|
|
480
|
-
[
|
|
481
|
-
const { pointer, containsFlattenedNodes } =
|
|
482
|
-
const [currentAstNode] =
|
|
478
|
+
[INSERT_ELEMENT] = (writer, document, change) => {
|
|
479
|
+
const { pointer, containsFlattenedNodes } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
480
|
+
const [currentAstNode] = getAstNodesFromPointer(document.ast, pointer).slice(-1);
|
|
483
481
|
if (containsFlattenedNodes) {
|
|
484
482
|
this.insertInFlattenedStructure(writer, document, change, pointer);
|
|
485
483
|
}
|
|
486
|
-
else if (currentAstNode.type ===
|
|
484
|
+
else if (currentAstNode.type === TARGET_TYPE) {
|
|
487
485
|
writer.addChange({
|
|
488
486
|
type: 'insert-annotation',
|
|
489
487
|
pointer: pointer,
|
|
490
488
|
element: change.element
|
|
491
489
|
});
|
|
492
490
|
}
|
|
493
|
-
else if (currentAstNode.type ===
|
|
491
|
+
else if (currentAstNode.type === ANNOTATION_TYPE) {
|
|
494
492
|
this.insertAnnotation(writer, change, pointer);
|
|
495
493
|
}
|
|
496
|
-
else if (currentAstNode.type ===
|
|
494
|
+
else if (currentAstNode.type === RECORD_TYPE) {
|
|
497
495
|
this.insertRecord(writer, change, pointer, currentAstNode);
|
|
498
496
|
}
|
|
499
|
-
else if (currentAstNode.type ===
|
|
500
|
-
if (
|
|
497
|
+
else if (currentAstNode.type === RECORD_PROPERTY_TYPE) {
|
|
498
|
+
if (PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
|
|
501
499
|
writer.addChange({
|
|
502
|
-
type:
|
|
500
|
+
type: INSERT_PRIMITIVE_VALUE_TYPE,
|
|
503
501
|
pointer: pointer, // point to properties
|
|
504
502
|
element: change.element,
|
|
505
503
|
index: change.index
|
|
506
504
|
});
|
|
507
505
|
}
|
|
508
506
|
}
|
|
509
|
-
else if (currentAstNode.type ===
|
|
510
|
-
if (change.element.name ===
|
|
507
|
+
else if (currentAstNode.type === COLLECTION_TYPE) {
|
|
508
|
+
if (change.element.name === Edm.Record) {
|
|
511
509
|
writer.addChange({
|
|
512
510
|
type: 'insert-record',
|
|
513
511
|
pointer: pointer,
|
|
@@ -515,9 +513,9 @@ class CDSAnnotationServiceAdapter {
|
|
|
515
513
|
index: change.index
|
|
516
514
|
});
|
|
517
515
|
}
|
|
518
|
-
else if (
|
|
516
|
+
else if (PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
|
|
519
517
|
writer.addChange({
|
|
520
|
-
type:
|
|
518
|
+
type: INSERT_PRIMITIVE_VALUE_TYPE,
|
|
521
519
|
pointer: pointer,
|
|
522
520
|
element: change.element,
|
|
523
521
|
index: change.index
|
|
@@ -525,18 +523,18 @@ class CDSAnnotationServiceAdapter {
|
|
|
525
523
|
}
|
|
526
524
|
}
|
|
527
525
|
else {
|
|
528
|
-
throw new
|
|
526
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.element.name}`, ApiErrorCode.General);
|
|
529
527
|
}
|
|
530
528
|
const aliasInfo = getAliasInfo(document.annotationFile, this.metadataService, this.vocabularyService);
|
|
531
|
-
const missingReferences =
|
|
529
|
+
const missingReferences = getMissingRefs(this.documents, change.uri, change.target, change.element, aliasInfo, this.metadataService, { apps: Object.keys(this.project.apps), projectRoot: this.project.root, appName: '' });
|
|
532
530
|
this.addMissingReferences(document.uri, missingReferences);
|
|
533
531
|
};
|
|
534
532
|
insertInFlattenedStructure(writer, document, change, pointer) {
|
|
535
533
|
const targetPointer = pointer.split('/').slice(0, 3).join('/');
|
|
536
534
|
const termPointer = change.pointer.split('/').slice(0, 5).join('/');
|
|
537
535
|
const annotationValuePointer = change.pointer.split('/').slice(5).join('/');
|
|
538
|
-
const element =
|
|
539
|
-
if (element?.type ===
|
|
536
|
+
const element = getGenericNodeFromPointer(document.annotationFile, termPointer);
|
|
537
|
+
if (element?.type === ELEMENT_TYPE) {
|
|
540
538
|
const annotation = buildAnnotation(element, annotationValuePointer, change.element);
|
|
541
539
|
if (annotation) {
|
|
542
540
|
writer.addChange({
|
|
@@ -549,101 +547,101 @@ class CDSAnnotationServiceAdapter {
|
|
|
549
547
|
}
|
|
550
548
|
insertAnnotation(writer, change, pointer) {
|
|
551
549
|
// insert annotation value
|
|
552
|
-
if (change.element.name ===
|
|
553
|
-
writer.addChange(
|
|
550
|
+
if (change.element.name === Edm.Annotation) {
|
|
551
|
+
writer.addChange(createInsertEmbeddedAnnotationChange(pointer, change.element));
|
|
554
552
|
}
|
|
555
|
-
else if (change.element.name ===
|
|
556
|
-
writer.addChange(
|
|
553
|
+
else if (change.element.name === Edm.Collection) {
|
|
554
|
+
writer.addChange(createInsertCollectionChange(pointer, change.element));
|
|
557
555
|
}
|
|
558
|
-
else if (change.element.name ===
|
|
559
|
-
writer.addChange(
|
|
556
|
+
else if (change.element.name === Edm.Record) {
|
|
557
|
+
writer.addChange(createInsertRecordChange(pointer, change.element));
|
|
560
558
|
}
|
|
561
|
-
else if (
|
|
562
|
-
writer.addChange(
|
|
559
|
+
else if (PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
|
|
560
|
+
writer.addChange(createInsertPrimitiveValueChange(pointer, change.element));
|
|
563
561
|
}
|
|
564
562
|
}
|
|
565
563
|
insertRecord(writer, change, pointer, record) {
|
|
566
|
-
if (change.element.name ===
|
|
564
|
+
if (change.element.name === Edm.PropertyValue) {
|
|
567
565
|
const index = adaptRecordPropertyIndex(record, change.index);
|
|
568
566
|
const modifiedPointer = [...pointer.split('/'), 'properties'].join('/'); // pointer is record
|
|
569
|
-
writer.addChange(
|
|
567
|
+
writer.addChange(createInsertRecordPropertyChange(modifiedPointer, change.element, index));
|
|
570
568
|
}
|
|
571
|
-
else if (change.element.name ===
|
|
569
|
+
else if (change.element.name === Edm.Annotation) {
|
|
572
570
|
const index = adaptRecordPropertyIndex(record, change.index);
|
|
573
|
-
writer.addChange(
|
|
571
|
+
writer.addChange(createInsertEmbeddedAnnotationChange(pointer, change.element, index));
|
|
574
572
|
}
|
|
575
|
-
else if (change.element.name ===
|
|
573
|
+
else if (change.element.name === Edm.Record) {
|
|
576
574
|
const segment = pointer.split('/');
|
|
577
575
|
const changeIndex = Number.parseInt(segment.pop() ?? '', 10);
|
|
578
576
|
const modifiedPointer = segment.join('/'); //point to annotations
|
|
579
|
-
writer.addChange(
|
|
577
|
+
writer.addChange(createInsertRecordChange(modifiedPointer, change.element, changeIndex));
|
|
580
578
|
}
|
|
581
579
|
}
|
|
582
|
-
[
|
|
583
|
-
const { pointer } =
|
|
584
|
-
const [currentAstNode] =
|
|
580
|
+
[INSERT_ATTRIBUTE] = (writer, document, change) => {
|
|
581
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
582
|
+
const [currentAstNode] = getAstNodesFromPointer(document.ast, pointer).slice(-1);
|
|
585
583
|
if (pointer) {
|
|
586
|
-
if (currentAstNode.type ===
|
|
584
|
+
if (currentAstNode.type === ANNOTATION_TYPE && change.name === Edm.Qualifier) {
|
|
587
585
|
writer.addChange({
|
|
588
586
|
type: 'insert-qualifier',
|
|
589
587
|
pointer: pointer,
|
|
590
588
|
value: change.value
|
|
591
589
|
});
|
|
592
590
|
}
|
|
593
|
-
if (currentAstNode.type ===
|
|
594
|
-
(currentAstNode.type ===
|
|
591
|
+
if (currentAstNode.type === RECORD_PROPERTY_TYPE ||
|
|
592
|
+
(currentAstNode.type === ANNOTATION_TYPE && change.name !== Edm.Qualifier)) {
|
|
595
593
|
writer.addChange({
|
|
596
594
|
type: 'insert-primitive-value',
|
|
597
595
|
pointer: pointer,
|
|
598
|
-
element:
|
|
596
|
+
element: createElementNode({
|
|
599
597
|
name: change.name,
|
|
600
|
-
content: [
|
|
598
|
+
content: [createTextNode(change.value)]
|
|
601
599
|
})
|
|
602
600
|
});
|
|
603
601
|
}
|
|
604
|
-
if (currentAstNode.type ===
|
|
602
|
+
if (currentAstNode.type === RECORD_TYPE && change.name === Edm.Type) {
|
|
605
603
|
writer.addChange({
|
|
606
604
|
type: 'insert-record-property',
|
|
607
605
|
pointer: pointer + '/properties',
|
|
608
606
|
index: 0,
|
|
609
|
-
element:
|
|
607
|
+
element: createElementNode({
|
|
610
608
|
name: 'PropertyValue',
|
|
611
609
|
attributes: {
|
|
612
|
-
Property:
|
|
610
|
+
Property: createAttributeNode('Property', '$Type')
|
|
613
611
|
},
|
|
614
|
-
content: [
|
|
612
|
+
content: [createElementNode({ name: 'String', content: [createTextNode(change.value)] })]
|
|
615
613
|
})
|
|
616
614
|
});
|
|
617
615
|
}
|
|
618
616
|
}
|
|
619
617
|
else {
|
|
620
|
-
throw new
|
|
618
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.name}`, ApiErrorCode.General);
|
|
621
619
|
}
|
|
622
620
|
};
|
|
623
|
-
[
|
|
624
|
-
const { pointer } =
|
|
625
|
-
const [node] =
|
|
626
|
-
if (pointer && node?.type ===
|
|
627
|
-
writer.addChange(
|
|
621
|
+
[DELETE_ATTRIBUTE] = (writer, document, change) => {
|
|
622
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
623
|
+
const [node] = getAstNodesFromPointer(document.ast, pointer).slice(-1);
|
|
624
|
+
if (pointer && node?.type === QUALIFIER_TYPE) {
|
|
625
|
+
writer.addChange(createDeleteQualifierChange(pointer));
|
|
628
626
|
}
|
|
629
627
|
else {
|
|
630
|
-
throw new
|
|
628
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer}`, ApiErrorCode.General);
|
|
631
629
|
}
|
|
632
630
|
};
|
|
633
|
-
[
|
|
634
|
-
const { pointer } =
|
|
631
|
+
[UPDATE_ATTRIBUTE_VALUE] = (writer, document, change) => {
|
|
632
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
635
633
|
if (pointer) {
|
|
636
|
-
writer.addChange(
|
|
634
|
+
writer.addChange(createUpdatePrimitiveValueChange(pointer, change.newValue));
|
|
637
635
|
}
|
|
638
636
|
else {
|
|
639
|
-
throw new
|
|
637
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newValue}`, ApiErrorCode.General);
|
|
640
638
|
}
|
|
641
639
|
};
|
|
642
|
-
[
|
|
643
|
-
const { pointer } =
|
|
644
|
-
const [currentAstNode] =
|
|
640
|
+
[REPLACE_ATTRIBUTE] = (writer, document, change) => {
|
|
641
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
642
|
+
const [currentAstNode] = getAstNodesFromPointer(document.ast, pointer).slice(-1);
|
|
645
643
|
if (pointer) {
|
|
646
|
-
if (currentAstNode.type ===
|
|
644
|
+
if (currentAstNode.type === RECORD_PROPERTY_TYPE && change.newAttributeValue) {
|
|
647
645
|
writer.addChange({
|
|
648
646
|
type: 'update-primitive-value',
|
|
649
647
|
pointer: pointer,
|
|
@@ -652,14 +650,14 @@ class CDSAnnotationServiceAdapter {
|
|
|
652
650
|
}
|
|
653
651
|
}
|
|
654
652
|
else {
|
|
655
|
-
throw new
|
|
653
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer}`, ApiErrorCode.General);
|
|
656
654
|
}
|
|
657
655
|
};
|
|
658
|
-
[
|
|
659
|
-
const { pointer } =
|
|
660
|
-
const currentAFNode =
|
|
656
|
+
[REPLACE_ELEMENT] = (writer, document, change) => {
|
|
657
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
658
|
+
const currentAFNode = getGenericNodeFromPointer(document.annotationFile, change.pointer);
|
|
661
659
|
if (pointer) {
|
|
662
|
-
if (currentAFNode?.type ===
|
|
660
|
+
if (currentAFNode?.type === ELEMENT_TYPE && currentAFNode.name === Edm.PropertyValue) {
|
|
663
661
|
writer.addChange({
|
|
664
662
|
type: 'replace-record-property',
|
|
665
663
|
pointer: pointer,
|
|
@@ -675,14 +673,14 @@ class CDSAnnotationServiceAdapter {
|
|
|
675
673
|
}
|
|
676
674
|
}
|
|
677
675
|
else {
|
|
678
|
-
throw new
|
|
676
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newElement.name}`, ApiErrorCode.General);
|
|
679
677
|
}
|
|
680
678
|
};
|
|
681
|
-
[
|
|
682
|
-
const { pointer } =
|
|
679
|
+
[REPLACE_TEXT] = (writer, document, change) => {
|
|
680
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
683
681
|
const segments = change.pointer.split('/');
|
|
684
682
|
const lastSegment = segments.pop();
|
|
685
|
-
const annotationFileNode =
|
|
683
|
+
const annotationFileNode = getGenericNodeFromPointer(document.annotationFile, segments.join('/'));
|
|
686
684
|
if (pointer) {
|
|
687
685
|
if (lastSegment === 'text' && elementHasFlags(annotationFileNode)) {
|
|
688
686
|
// CDS has specific syntax for flags and
|
|
@@ -701,16 +699,16 @@ class CDSAnnotationServiceAdapter {
|
|
|
701
699
|
}
|
|
702
700
|
}
|
|
703
701
|
else {
|
|
704
|
-
throw new
|
|
702
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.text}`, ApiErrorCode.General);
|
|
705
703
|
}
|
|
706
704
|
};
|
|
707
|
-
[
|
|
708
|
-
const { pointer } =
|
|
709
|
-
const [currentAstNode] =
|
|
710
|
-
const annotationFileNode =
|
|
705
|
+
[REPLACE_ELEMENT_CONTENT] = (writer, document, change) => {
|
|
706
|
+
const { pointer } = convertPointer(document.annotationFile, change.pointer, document.ast);
|
|
707
|
+
const [currentAstNode] = getAstNodesFromPointer(document.ast, pointer).slice(-1);
|
|
708
|
+
const annotationFileNode = getGenericNodeFromPointer(document.annotationFile, change.pointer);
|
|
711
709
|
const newValue = change.newValue[0];
|
|
712
|
-
if (pointer && currentAstNode && newValue?.type ===
|
|
713
|
-
if (annotationFileNode?.type ===
|
|
710
|
+
if (pointer && currentAstNode && newValue?.type === TEXT_TYPE) {
|
|
711
|
+
if (annotationFileNode?.type === ELEMENT_TYPE && annotationFileNode.name === Edm.EnumMember) {
|
|
714
712
|
if (elementHasFlags(annotationFileNode)) {
|
|
715
713
|
writer.addChange({
|
|
716
714
|
type: 'set-flags',
|
|
@@ -729,10 +727,10 @@ class CDSAnnotationServiceAdapter {
|
|
|
729
727
|
else {
|
|
730
728
|
const text =
|
|
731
729
|
// annotation paths are currently converted to strings and for those separators do not need to be replaced
|
|
732
|
-
annotationFileNode?.type ===
|
|
733
|
-
(annotationFileNode.name ===
|
|
734
|
-
annotationFileNode.name ===
|
|
735
|
-
annotationFileNode.name ===
|
|
730
|
+
annotationFileNode?.type === ELEMENT_TYPE &&
|
|
731
|
+
(annotationFileNode.name === Edm.Path ||
|
|
732
|
+
annotationFileNode.name === Edm.PropertyPath ||
|
|
733
|
+
annotationFileNode.name === Edm.NavigationPropertyPath)
|
|
736
734
|
? newValue.text.replaceAll('/', '.')
|
|
737
735
|
: newValue.text;
|
|
738
736
|
writer.addChange({
|
|
@@ -743,44 +741,43 @@ class CDSAnnotationServiceAdapter {
|
|
|
743
741
|
}
|
|
744
742
|
}
|
|
745
743
|
else {
|
|
746
|
-
throw new
|
|
744
|
+
throw new ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newValue}`, ApiErrorCode.General);
|
|
747
745
|
}
|
|
748
746
|
};
|
|
749
|
-
[
|
|
747
|
+
[MOVE_ELEMENT] = (writer, document, change) => {
|
|
750
748
|
const { pointer, index } = change;
|
|
751
|
-
const { pointer: toPointer } =
|
|
752
|
-
const toNode =
|
|
753
|
-
if (toPointer &&
|
|
749
|
+
const { pointer: toPointer } = convertPointer(document.annotationFile, pointer, document.ast);
|
|
750
|
+
const toNode = getGenericNodeFromPointer(document.annotationFile, pointer);
|
|
751
|
+
if (toPointer && isElementWithName(toNode, 'Collection')) {
|
|
754
752
|
writer.addChange({
|
|
755
753
|
type: 'move-collection-value',
|
|
756
754
|
pointer: toPointer,
|
|
757
755
|
index,
|
|
758
756
|
fromPointers: change.fromPointers.map((ptr) => {
|
|
759
|
-
const { pointer } =
|
|
757
|
+
const { pointer } = convertPointer(document.annotationFile, ptr, document.ast);
|
|
760
758
|
return pointer;
|
|
761
759
|
})
|
|
762
760
|
});
|
|
763
761
|
}
|
|
764
762
|
};
|
|
765
|
-
[
|
|
763
|
+
[UPDATE_ELEMENT_NAME] = () => {
|
|
766
764
|
// noop, such changes have no effect in CDS
|
|
767
765
|
};
|
|
768
|
-
[
|
|
766
|
+
[DELETE_REFERENCE] = () => {
|
|
769
767
|
// noop, such changes are not supported in CDS
|
|
770
768
|
};
|
|
771
769
|
}
|
|
772
|
-
exports.CDSAnnotationServiceAdapter = CDSAnnotationServiceAdapter;
|
|
773
770
|
function getAliasInfo(annotationFileInternal, metadataService, vocabularyAPI) {
|
|
774
|
-
const namespaces =
|
|
775
|
-
const aliasInfo =
|
|
776
|
-
return
|
|
771
|
+
const namespaces = getAllNamespacesAndReferences(annotationFileInternal.namespace, annotationFileInternal.references);
|
|
772
|
+
const aliasInfo = getAliasInformation(namespaces, metadataService.getNamespaces());
|
|
773
|
+
return addAllVocabulariesToAliasInformation(aliasInfo, vocabularyAPI.getVocabularies());
|
|
777
774
|
}
|
|
778
775
|
function elementHasFlags(element) {
|
|
779
776
|
if (element?.type !== 'element') {
|
|
780
777
|
return false;
|
|
781
778
|
}
|
|
782
779
|
const content = element.content[0];
|
|
783
|
-
if (content?.type === 'text' && element.name ===
|
|
780
|
+
if (content?.type === 'text' && element.name === Edm.EnumMember) {
|
|
784
781
|
return content.text.split(' ').length > 1;
|
|
785
782
|
}
|
|
786
783
|
return false;
|
|
@@ -788,7 +785,7 @@ function elementHasFlags(element) {
|
|
|
788
785
|
function buildAnnotation(root, pointer, lastContent) {
|
|
789
786
|
const segments = pointer.split('/');
|
|
790
787
|
let node = root;
|
|
791
|
-
if (node.type !==
|
|
788
|
+
if (node.type !== ELEMENT_TYPE) {
|
|
792
789
|
return undefined;
|
|
793
790
|
}
|
|
794
791
|
const result = buildElement(node);
|
|
@@ -797,7 +794,7 @@ function buildAnnotation(root, pointer, lastContent) {
|
|
|
797
794
|
const next = node[segment];
|
|
798
795
|
if (next) {
|
|
799
796
|
node = next;
|
|
800
|
-
if (node.type ===
|
|
797
|
+
if (node.type === ELEMENT_TYPE) {
|
|
801
798
|
const nextElement = buildElement(node);
|
|
802
799
|
current.content.push(nextElement);
|
|
803
800
|
current = nextElement;
|
|
@@ -814,15 +811,15 @@ function buildAnnotation(root, pointer, lastContent) {
|
|
|
814
811
|
return result;
|
|
815
812
|
}
|
|
816
813
|
function buildElement(node) {
|
|
817
|
-
const result =
|
|
818
|
-
if (node.name ===
|
|
819
|
-
result.attributes[
|
|
820
|
-
if (node.attributes[
|
|
821
|
-
result.attributes[
|
|
814
|
+
const result = createElementNode({ name: node.name });
|
|
815
|
+
if (node.name === Edm.Annotation) {
|
|
816
|
+
result.attributes[Edm.Term] = node.attributes[Edm.Term];
|
|
817
|
+
if (node.attributes[Edm.Qualifier]) {
|
|
818
|
+
result.attributes[Edm.Qualifier] = node.attributes[Edm.Qualifier];
|
|
822
819
|
}
|
|
823
820
|
}
|
|
824
|
-
if (node.name ===
|
|
825
|
-
result.attributes[
|
|
821
|
+
if (node.name === Edm.PropertyValue) {
|
|
822
|
+
result.attributes[Edm.Property] = node.attributes[Edm.Property];
|
|
826
823
|
}
|
|
827
824
|
return result;
|
|
828
825
|
}
|
|
@@ -833,25 +830,25 @@ function adaptRecordPropertyIndex(record, currentIndex) {
|
|
|
833
830
|
let adaptedIdx = currentIndex;
|
|
834
831
|
for (let index = 0; index < record.properties.length; index++) {
|
|
835
832
|
const propertyName = record.properties[index].name.value;
|
|
836
|
-
if (
|
|
833
|
+
if (isReservedProperty(propertyName) && index <= adaptedIdx) {
|
|
837
834
|
adaptedIdx = adaptedIdx + 1;
|
|
838
835
|
}
|
|
839
836
|
}
|
|
840
837
|
return adaptedIdx;
|
|
841
838
|
}
|
|
842
839
|
function checkAndDeleteFlattenedStructures(writer, document, change, parentAstNode, greatGrandParentAstNode) {
|
|
843
|
-
const element =
|
|
844
|
-
if (element?.type ===
|
|
840
|
+
const element = getGenericNodeFromPointer(document.annotationFile, change.pointer);
|
|
841
|
+
if (element?.type === ELEMENT_TYPE) {
|
|
845
842
|
let targetNode;
|
|
846
|
-
if (parentAstNode.type ===
|
|
843
|
+
if (parentAstNode.type === TARGET_TYPE) {
|
|
847
844
|
targetNode = parentAstNode;
|
|
848
845
|
}
|
|
849
|
-
else if (greatGrandParentAstNode.type ===
|
|
846
|
+
else if (greatGrandParentAstNode.type === TARGET_TYPE) {
|
|
850
847
|
targetNode = greatGrandParentAstNode;
|
|
851
848
|
}
|
|
852
849
|
if (targetNode) {
|
|
853
|
-
const termName =
|
|
854
|
-
const qualifier =
|
|
850
|
+
const termName = getElementAttributeValue(element, Edm.Term);
|
|
851
|
+
const qualifier = getElementAttribute(element, Edm.Qualifier);
|
|
855
852
|
if (termName) {
|
|
856
853
|
deleteChildFlattenedStructures(targetNode.name, termName, qualifier?.value, document.ast, writer);
|
|
857
854
|
}
|
|
@@ -869,14 +866,14 @@ function deleteChildFlattenedStructures(targetName, term, qualifier, ast, writer
|
|
|
869
866
|
for (let assignmentIndex = 0; assignmentIndex < target.assignments.length; assignmentIndex++) {
|
|
870
867
|
const assignment = target.assignments[assignmentIndex];
|
|
871
868
|
if (isMatchingAnnotation(assignment, term, undefined, qualifier)) {
|
|
872
|
-
writer.addChange(
|
|
869
|
+
writer.addChange(createDeleteAnnotationChange(`/targets/${targetIndex}/assignments/${assignmentIndex}`, targetName));
|
|
873
870
|
}
|
|
874
|
-
else if (assignment.type ===
|
|
871
|
+
else if (assignment.type === ANNOTATION_GROUP_TYPE) {
|
|
875
872
|
for (let groupItemIndex = 0; groupItemIndex < assignment.items.items.length; groupItemIndex++) {
|
|
876
873
|
const item = assignment.items.items[groupItemIndex];
|
|
877
874
|
const combinedTerm = `${assignment.name.value}.${item.term.value}`;
|
|
878
875
|
if (isMatchingAnnotation(item, term, combinedTerm, qualifier)) {
|
|
879
|
-
writer.addChange(
|
|
876
|
+
writer.addChange(createDeleteAnnotationChange(`/targets/${targetIndex}/assignments/${assignmentIndex}/items/items/${groupItemIndex}`, targetName));
|
|
880
877
|
}
|
|
881
878
|
}
|
|
882
879
|
}
|
|
@@ -884,7 +881,7 @@ function deleteChildFlattenedStructures(targetName, term, qualifier, ast, writer
|
|
|
884
881
|
}
|
|
885
882
|
}
|
|
886
883
|
function isMatchingAnnotation(node, prefix, term, qualifier) {
|
|
887
|
-
if (node.type !==
|
|
884
|
+
if (node.type !== ANNOTATION_TYPE) {
|
|
888
885
|
return false;
|
|
889
886
|
}
|
|
890
887
|
term ??= node.term.value;
|