@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.
Files changed (211) hide show
  1. package/LICENSE +201 -0
  2. package/Readme.md +35 -0
  3. package/dist/avt/annotations.d.ts +72 -0
  4. package/dist/avt/annotations.d.ts.map +1 -0
  5. package/dist/avt/annotations.js +508 -0
  6. package/dist/avt/annotations.js.map +1 -0
  7. package/dist/avt/expressions.d.ts +13 -0
  8. package/dist/avt/expressions.d.ts.map +1 -0
  9. package/dist/avt/expressions.js +34 -0
  10. package/dist/avt/expressions.js.map +1 -0
  11. package/dist/avt/find.d.ts +39 -0
  12. package/dist/avt/find.d.ts.map +1 -0
  13. package/dist/avt/find.js +130 -0
  14. package/dist/avt/find.js.map +1 -0
  15. package/dist/avt/index.d.ts +9 -0
  16. package/dist/avt/index.d.ts.map +1 -0
  17. package/dist/avt/index.js +32 -0
  18. package/dist/avt/index.js.map +1 -0
  19. package/dist/avt/metadata.d.ts +10 -0
  20. package/dist/avt/metadata.d.ts.map +1 -0
  21. package/dist/avt/metadata.js +346 -0
  22. package/dist/avt/metadata.js.map +1 -0
  23. package/dist/avt/pointer.d.ts +12 -0
  24. package/dist/avt/pointer.d.ts.map +1 -0
  25. package/dist/avt/pointer.js +188 -0
  26. package/dist/avt/pointer.js.map +1 -0
  27. package/dist/avt/to-internal.d.ts +81 -0
  28. package/dist/avt/to-internal.d.ts.map +1 -0
  29. package/dist/avt/to-internal.js +340 -0
  30. package/dist/avt/to-internal.js.map +1 -0
  31. package/dist/avt/types.d.ts +3 -0
  32. package/dist/avt/types.d.ts.map +1 -0
  33. package/dist/avt/types.js +3 -0
  34. package/dist/avt/types.js.map +1 -0
  35. package/dist/avt/utils.d.ts +61 -0
  36. package/dist/avt/utils.d.ts.map +1 -0
  37. package/dist/avt/utils.js +87 -0
  38. package/dist/avt/utils.js.map +1 -0
  39. package/dist/cds/adapter.d.ts +112 -0
  40. package/dist/cds/adapter.d.ts.map +1 -0
  41. package/dist/cds/adapter.js +703 -0
  42. package/dist/cds/adapter.js.map +1 -0
  43. package/dist/cds/cds-compiler-tokens.d.ts +30 -0
  44. package/dist/cds/cds-compiler-tokens.d.ts.map +1 -0
  45. package/dist/cds/cds-compiler-tokens.js +57 -0
  46. package/dist/cds/cds-compiler-tokens.js.map +1 -0
  47. package/dist/cds/change.d.ts +347 -0
  48. package/dist/cds/change.d.ts.map +1 -0
  49. package/dist/cds/change.js +232 -0
  50. package/dist/cds/change.js.map +1 -0
  51. package/dist/cds/comments.d.ts +15 -0
  52. package/dist/cds/comments.d.ts.map +1 -0
  53. package/dist/cds/comments.js +56 -0
  54. package/dist/cds/comments.js.map +1 -0
  55. package/dist/cds/deletion.d.ts +59 -0
  56. package/dist/cds/deletion.d.ts.map +1 -0
  57. package/dist/cds/deletion.js +821 -0
  58. package/dist/cds/deletion.js.map +1 -0
  59. package/dist/cds/document.d.ts +52 -0
  60. package/dist/cds/document.d.ts.map +1 -0
  61. package/dist/cds/document.js +98 -0
  62. package/dist/cds/document.js.map +1 -0
  63. package/dist/cds/indent.d.ts +20 -0
  64. package/dist/cds/indent.d.ts.map +1 -0
  65. package/dist/cds/indent.js +86 -0
  66. package/dist/cds/indent.js.map +1 -0
  67. package/dist/cds/index.d.ts +3 -0
  68. package/dist/cds/index.d.ts.map +1 -0
  69. package/dist/cds/index.js +21 -0
  70. package/dist/cds/index.js.map +1 -0
  71. package/dist/cds/pointer.d.ts +23 -0
  72. package/dist/cds/pointer.d.ts.map +1 -0
  73. package/dist/cds/pointer.js +438 -0
  74. package/dist/cds/pointer.js.map +1 -0
  75. package/dist/cds/preprocessor.d.ts +12 -0
  76. package/dist/cds/preprocessor.d.ts.map +1 -0
  77. package/dist/cds/preprocessor.js +338 -0
  78. package/dist/cds/preprocessor.js.map +1 -0
  79. package/dist/cds/references.d.ts +35 -0
  80. package/dist/cds/references.d.ts.map +1 -0
  81. package/dist/cds/references.js +413 -0
  82. package/dist/cds/references.js.map +1 -0
  83. package/dist/cds/service.d.ts +11 -0
  84. package/dist/cds/service.d.ts.map +1 -0
  85. package/dist/cds/service.js +37 -0
  86. package/dist/cds/service.js.map +1 -0
  87. package/dist/cds/utils.d.ts +35 -0
  88. package/dist/cds/utils.d.ts.map +1 -0
  89. package/dist/cds/utils.js +75 -0
  90. package/dist/cds/utils.js.map +1 -0
  91. package/dist/cds/writer.d.ts +104 -0
  92. package/dist/cds/writer.d.ts.map +1 -0
  93. package/dist/cds/writer.js +1086 -0
  94. package/dist/cds/writer.js.map +1 -0
  95. package/dist/change-converter.d.ts +54 -0
  96. package/dist/change-converter.d.ts.map +1 -0
  97. package/dist/change-converter.js +639 -0
  98. package/dist/change-converter.js.map +1 -0
  99. package/dist/error.d.ts +35 -0
  100. package/dist/error.d.ts.map +1 -0
  101. package/dist/error.js +64 -0
  102. package/dist/error.js.map +1 -0
  103. package/dist/fiori-service.d.ts +130 -0
  104. package/dist/fiori-service.d.ts.map +1 -0
  105. package/dist/fiori-service.js +362 -0
  106. package/dist/fiori-service.js.map +1 -0
  107. package/dist/index.d.ts +5 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +25 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/protected.d.ts +3 -0
  112. package/dist/protected.d.ts.map +1 -0
  113. package/dist/protected.js +11 -0
  114. package/dist/protected.js.map +1 -0
  115. package/dist/types/adapter.d.ts +46 -0
  116. package/dist/types/adapter.d.ts.map +1 -0
  117. package/dist/types/adapter.js +3 -0
  118. package/dist/types/adapter.js.map +1 -0
  119. package/dist/types/change.d.ts +187 -0
  120. package/dist/types/change.d.ts.map +1 -0
  121. package/dist/types/change.js +52 -0
  122. package/dist/types/change.js.map +1 -0
  123. package/dist/types/index.d.ts +7 -0
  124. package/dist/types/index.d.ts.map +1 -0
  125. package/dist/types/index.js +33 -0
  126. package/dist/types/index.js.map +1 -0
  127. package/dist/types/internal-change.d.ts +98 -0
  128. package/dist/types/internal-change.d.ts.map +1 -0
  129. package/dist/types/internal-change.js +18 -0
  130. package/dist/types/internal-change.js.map +1 -0
  131. package/dist/types/project-info.d.ts +6 -0
  132. package/dist/types/project-info.d.ts.map +1 -0
  133. package/dist/types/project-info.js +3 -0
  134. package/dist/types/project-info.js.map +1 -0
  135. package/dist/types/service.d.ts +27 -0
  136. package/dist/types/service.d.ts.map +1 -0
  137. package/dist/types/service.js +3 -0
  138. package/dist/types/service.js.map +1 -0
  139. package/dist/types/text-file.d.ts +12 -0
  140. package/dist/types/text-file.d.ts.map +1 -0
  141. package/dist/types/text-file.js +3 -0
  142. package/dist/types/text-file.js.map +1 -0
  143. package/dist/utils/constants.d.ts +2 -0
  144. package/dist/utils/constants.d.ts.map +1 -0
  145. package/dist/utils/constants.js +24 -0
  146. package/dist/utils/constants.js.map +1 -0
  147. package/dist/utils/indent.d.ts +10 -0
  148. package/dist/utils/indent.d.ts.map +1 -0
  149. package/dist/utils/indent.js +36 -0
  150. package/dist/utils/indent.js.map +1 -0
  151. package/dist/utils/index.d.ts +7 -0
  152. package/dist/utils/index.d.ts.map +1 -0
  153. package/dist/utils/index.js +16 -0
  154. package/dist/utils/index.js.map +1 -0
  155. package/dist/utils/path.d.ts +8 -0
  156. package/dist/utils/path.d.ts.map +1 -0
  157. package/dist/utils/path.js +31 -0
  158. package/dist/utils/path.js.map +1 -0
  159. package/dist/utils/pointer.d.ts +11 -0
  160. package/dist/utils/pointer.d.ts.map +1 -0
  161. package/dist/utils/pointer.js +26 -0
  162. package/dist/utils/pointer.js.map +1 -0
  163. package/dist/utils/reference.d.ts +10 -0
  164. package/dist/utils/reference.d.ts.map +1 -0
  165. package/dist/utils/reference.js +20 -0
  166. package/dist/utils/reference.js.map +1 -0
  167. package/dist/utils/text-edits.d.ts +12 -0
  168. package/dist/utils/text-edits.d.ts.map +1 -0
  169. package/dist/utils/text-edits.js +29 -0
  170. package/dist/utils/text-edits.js.map +1 -0
  171. package/dist/vocabularies.d.ts +11 -0
  172. package/dist/vocabularies.d.ts.map +1 -0
  173. package/dist/vocabularies.js +26 -0
  174. package/dist/vocabularies.js.map +1 -0
  175. package/dist/xml/adapter.d.ts +85 -0
  176. package/dist/xml/adapter.d.ts.map +1 -0
  177. package/dist/xml/adapter.js +579 -0
  178. package/dist/xml/adapter.js.map +1 -0
  179. package/dist/xml/changes.d.ts +117 -0
  180. package/dist/xml/changes.d.ts.map +1 -0
  181. package/dist/xml/changes.js +34 -0
  182. package/dist/xml/changes.js.map +1 -0
  183. package/dist/xml/comments.d.ts +17 -0
  184. package/dist/xml/comments.d.ts.map +1 -0
  185. package/dist/xml/comments.js +49 -0
  186. package/dist/xml/comments.js.map +1 -0
  187. package/dist/xml/document.d.ts +11 -0
  188. package/dist/xml/document.d.ts.map +1 -0
  189. package/dist/xml/document.js +3 -0
  190. package/dist/xml/document.js.map +1 -0
  191. package/dist/xml/index.d.ts +3 -0
  192. package/dist/xml/index.d.ts.map +1 -0
  193. package/dist/xml/index.js +8 -0
  194. package/dist/xml/index.js.map +1 -0
  195. package/dist/xml/pointer.d.ts +10 -0
  196. package/dist/xml/pointer.d.ts.map +1 -0
  197. package/dist/xml/pointer.js +29 -0
  198. package/dist/xml/pointer.js.map +1 -0
  199. package/dist/xml/references.d.ts +9 -0
  200. package/dist/xml/references.d.ts.map +1 -0
  201. package/dist/xml/references.js +87 -0
  202. package/dist/xml/references.js.map +1 -0
  203. package/dist/xml/service.d.ts +12 -0
  204. package/dist/xml/service.d.ts.map +1 -0
  205. package/dist/xml/service.js +55 -0
  206. package/dist/xml/service.js.map +1 -0
  207. package/dist/xml/writer.d.ts +39 -0
  208. package/dist/xml/writer.d.ts.map +1 -0
  209. package/dist/xml/writer.js +855 -0
  210. package/dist/xml/writer.js.map +1 -0
  211. package/package.json +47 -0
@@ -0,0 +1,703 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CDSAnnotationServiceAdapter = void 0;
14
+ const url_1 = require("url");
15
+ const path_1 = require("path");
16
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
17
+ const ux_cds_compiler_facade_1 = require("@sap/ux-cds-compiler-facade");
18
+ const odata_annotation_core_types_1 = require("@sap-ux/odata-annotation-core-types");
19
+ const odata_entity_model_1 = require("@sap-ux/odata-entity-model");
20
+ const cds_annotation_parser_1 = require("@sap-ux/cds-annotation-parser");
21
+ const odata_annotation_core_1 = require("@sap-ux/odata-annotation-core");
22
+ const cds_odata_annotation_converter_1 = require("@sap-ux/cds-odata-annotation-converter");
23
+ const types_1 = require("../types");
24
+ const error_1 = require("../error");
25
+ const writer_1 = require("./writer");
26
+ const references_1 = require("./references");
27
+ const vocabularies_1 = require("../vocabularies");
28
+ const document_1 = require("./document");
29
+ const pointer_1 = require("./pointer");
30
+ const utils_1 = require("../utils");
31
+ const change_1 = require("./change");
32
+ const internal_change_1 = require("../types/internal-change");
33
+ /**
34
+ *
35
+ */
36
+ class CDSAnnotationServiceAdapter {
37
+ /**
38
+ *
39
+ * @param service - CDS service structure.
40
+ * @param project - Project structure.
41
+ * @param vocabularyService - Vocabulary API.
42
+ * @param appName - Name of the application.
43
+ */
44
+ constructor(service, project, vocabularyService, appName) {
45
+ this.service = service;
46
+ this.project = project;
47
+ this.vocabularyService = vocabularyService;
48
+ this.appName = appName;
49
+ this.metadataService = new odata_entity_model_1.MetadataService();
50
+ this.splitAnnotationSupport = true;
51
+ this.documents = new Map();
52
+ this.metadata = [];
53
+ this.missingReferences = {};
54
+ this[_a] = (writer, document, change) => {
55
+ var _p, _q, _r;
56
+ const aliasInfo = getAliasInfo(document.annotationFile, this.metadataService, this.vocabularyService);
57
+ const missingReferences = (0, references_1.getMissingRefs)(this.documents, change.uri, change.target.name, change.target, aliasInfo, this.metadataService, {
58
+ apps: Object.keys(this.project.apps),
59
+ projectRoot: this.project.root,
60
+ appName: this.appName
61
+ });
62
+ this.addMissingReferences(document.uri, missingReferences);
63
+ // This has to happen after getting refs, because currently it depends on OData path syntax
64
+ const targetName = change.target.name;
65
+ const pathSegments = targetName.split('/');
66
+ const pathBase = (_p = pathSegments.shift()) !== null && _p !== void 0 ? _p : '';
67
+ const parsedName = (0, odata_annotation_core_1.parseIdentifier)(pathBase);
68
+ const fullyQualifiedPath = (_q = (0, odata_annotation_core_1.toFullyQualifiedName)(aliasInfo.aliasMap, aliasInfo.currentFileNamespace, parsedName)) !== null && _q !== void 0 ? _q : '';
69
+ const metadataElement = this.metadataService.getMetadataElement(fullyQualifiedPath);
70
+ const pathBaseOriginal = (0, odata_annotation_core_1.toAliasQualifiedName)((_r = metadataElement === null || metadataElement === void 0 ? void 0 : metadataElement.originalName) !== null && _r !== void 0 ? _r : pathBase, aliasInfo);
71
+ change.target.name = [pathBaseOriginal, ...pathSegments].join('/');
72
+ writer.addChange((0, change_1.createInsertTargetChange)('target', change.target));
73
+ };
74
+ this[_b] = (writer, document, change) => {
75
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
76
+ const [currentAstNode, parentAstNode] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).reverse();
77
+ if ((currentAstNode === null || currentAstNode === void 0 ? void 0 : currentAstNode.type) === cds_annotation_parser_1.RECORD_PROPERTY_TYPE) {
78
+ writer.addChange({
79
+ type: 'delete-record-property',
80
+ pointer: pointer
81
+ });
82
+ }
83
+ else if ((currentAstNode === null || currentAstNode === void 0 ? void 0 : currentAstNode.type) === cds_annotation_parser_1.ANNOTATION_TYPE && parentAstNode.type === cds_annotation_parser_1.RECORD_TYPE) {
84
+ // embedded annotation
85
+ writer.addChange({
86
+ type: 'delete-embedded-annotation',
87
+ pointer: pointer
88
+ });
89
+ }
90
+ else if (currentAstNode.type === cds_odata_annotation_converter_1.TARGET_TYPE) {
91
+ writer.addChange({
92
+ type: 'delete-target',
93
+ pointer: pointer
94
+ });
95
+ }
96
+ else if (((currentAstNode === null || currentAstNode === void 0 ? void 0 : currentAstNode.type) === cds_annotation_parser_1.ANNOTATION_TYPE && parentAstNode.type === cds_odata_annotation_converter_1.TARGET_TYPE) ||
97
+ ((currentAstNode === null || currentAstNode === void 0 ? void 0 : currentAstNode.type) === cds_annotation_parser_1.ANNOTATION_TYPE && parentAstNode.type === cds_annotation_parser_1.ANNOTATION_GROUP_ITEMS_TYPE)) {
98
+ writer.addChange({
99
+ type: 'delete-annotation',
100
+ pointer: pointer,
101
+ target: change.target
102
+ });
103
+ }
104
+ else if ((currentAstNode === null || currentAstNode === void 0 ? void 0 : currentAstNode.type) === cds_annotation_parser_1.RECORD_TYPE) {
105
+ writer.addChange({
106
+ type: 'delete-record',
107
+ pointer: pointer
108
+ });
109
+ }
110
+ else if (currentAstNode.type === 'boolean' ||
111
+ currentAstNode.type === 'string' ||
112
+ currentAstNode.type === 'path' ||
113
+ currentAstNode.type === 'enum' ||
114
+ currentAstNode.type === 'token' ||
115
+ currentAstNode.type === 'number') {
116
+ writer.addChange({
117
+ type: 'delete-primitive-value',
118
+ pointer: pointer
119
+ });
120
+ }
121
+ else {
122
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} `, error_1.ApiErrorCode.General);
123
+ }
124
+ };
125
+ this[_c] = (writer, document, change) => {
126
+ const { pointer, containsFlattenedNodes } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
127
+ const [currentAstNode] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).slice(-1);
128
+ if (containsFlattenedNodes) {
129
+ this.insertInFlattenedStructure(writer, document, change, pointer);
130
+ }
131
+ else if (currentAstNode.type === cds_odata_annotation_converter_1.TARGET_TYPE) {
132
+ writer.addChange({
133
+ type: 'insert-annotation',
134
+ pointer: pointer,
135
+ element: change.element
136
+ });
137
+ }
138
+ else if (currentAstNode.type === cds_annotation_parser_1.ANNOTATION_TYPE) {
139
+ this.insertAnnotation(writer, change, pointer);
140
+ }
141
+ else if (currentAstNode.type === cds_annotation_parser_1.RECORD_TYPE) {
142
+ this.insertRecord(writer, change, pointer);
143
+ }
144
+ else if (currentAstNode.type === cds_annotation_parser_1.RECORD_PROPERTY_TYPE) {
145
+ if (utils_1.PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
146
+ writer.addChange({
147
+ type: change_1.INSERT_PRIMITIVE_VALUE_TYPE,
148
+ pointer: pointer, // point to properties
149
+ element: change.element,
150
+ index: change.index
151
+ });
152
+ }
153
+ }
154
+ else if (currentAstNode.type === cds_annotation_parser_1.COLLECTION_TYPE) {
155
+ if (change.element.name === "Record" /* Edm.Record */) {
156
+ writer.addChange({
157
+ type: 'insert-record',
158
+ pointer: pointer,
159
+ element: change.element,
160
+ index: change.index
161
+ });
162
+ }
163
+ else if (utils_1.PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
164
+ writer.addChange({
165
+ type: change_1.INSERT_PRIMITIVE_VALUE_TYPE,
166
+ pointer: pointer,
167
+ element: change.element,
168
+ index: change.index
169
+ });
170
+ }
171
+ }
172
+ else {
173
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.element.name}`, error_1.ApiErrorCode.General);
174
+ }
175
+ const aliasInfo = getAliasInfo(document.annotationFile, this.metadataService, this.vocabularyService);
176
+ const missingReferences = (0, references_1.getMissingRefs)(this.documents, change.uri, change.target, change.element, aliasInfo, this.metadataService, { apps: Object.keys(this.project.apps), projectRoot: this.project.root, appName: '' });
177
+ this.addMissingReferences(document.uri, missingReferences);
178
+ };
179
+ this[_d] = (writer, document, change) => {
180
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
181
+ const [currentAstNode] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).slice(-1);
182
+ if (pointer) {
183
+ if (currentAstNode.type === cds_annotation_parser_1.ANNOTATION_TYPE && change.name === "Qualifier" /* Edm.Qualifier */) {
184
+ writer.addChange({
185
+ type: 'insert-qualifier',
186
+ pointer: pointer,
187
+ value: change.value
188
+ });
189
+ }
190
+ if (currentAstNode.type === cds_annotation_parser_1.RECORD_PROPERTY_TYPE ||
191
+ (currentAstNode.type === cds_annotation_parser_1.ANNOTATION_TYPE && change.name !== "Qualifier" /* Edm.Qualifier */)) {
192
+ writer.addChange({
193
+ type: 'insert-primitive-value',
194
+ pointer: pointer,
195
+ element: (0, odata_annotation_core_types_1.createElementNode)({
196
+ name: change.name,
197
+ content: [(0, odata_annotation_core_types_1.createTextNode)(change.value)]
198
+ })
199
+ });
200
+ }
201
+ if (currentAstNode.type === cds_annotation_parser_1.RECORD_TYPE && change.name === "Type" /* Edm.Type */) {
202
+ writer.addChange({
203
+ type: 'insert-record-property',
204
+ pointer: pointer + '/properties',
205
+ index: 0,
206
+ element: (0, odata_annotation_core_types_1.createElementNode)({
207
+ name: 'PropertyValue',
208
+ attributes: {
209
+ Property: (0, odata_annotation_core_types_1.createAttributeNode)('Property', '$Type')
210
+ },
211
+ content: [(0, odata_annotation_core_types_1.createElementNode)({ name: 'String', content: [(0, odata_annotation_core_types_1.createTextNode)(change.value)] })]
212
+ })
213
+ });
214
+ }
215
+ }
216
+ else {
217
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.name}`, error_1.ApiErrorCode.General);
218
+ }
219
+ };
220
+ this[_e] = (writer, document, change) => {
221
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
222
+ const [node] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).slice(-1);
223
+ if (pointer && (node === null || node === void 0 ? void 0 : node.type) === cds_annotation_parser_1.QUALIFIER_TYPE) {
224
+ writer.addChange((0, change_1.createDeleteQualifierChange)(pointer));
225
+ }
226
+ else {
227
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer}`, error_1.ApiErrorCode.General);
228
+ }
229
+ };
230
+ this[_f] = (writer, document, change) => {
231
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
232
+ if (pointer) {
233
+ writer.addChange((0, change_1.createUpdatePrimitiveValueChange)(pointer, change.newValue));
234
+ }
235
+ else {
236
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newValue}`, error_1.ApiErrorCode.General);
237
+ }
238
+ };
239
+ this[_g] = (writer, document, change) => {
240
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
241
+ const [currentAstNode] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).slice(-1);
242
+ if (pointer) {
243
+ if (currentAstNode.type === cds_annotation_parser_1.RECORD_PROPERTY_TYPE && change.newAttributeValue) {
244
+ writer.addChange({
245
+ type: 'update-primitive-value',
246
+ pointer: pointer,
247
+ newValue: change.newAttributeValue
248
+ });
249
+ }
250
+ }
251
+ else {
252
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer}`, error_1.ApiErrorCode.General);
253
+ }
254
+ };
255
+ this[_h] = (writer, document, change) => {
256
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
257
+ const currentAFNode = (0, utils_1.getGenericNodeFromPointer)(document.annotationFile, change.pointer);
258
+ if (pointer) {
259
+ if ((currentAFNode === null || currentAFNode === void 0 ? void 0 : currentAFNode.type) === odata_annotation_core_types_1.ELEMENT_TYPE && currentAFNode.name === "PropertyValue" /* Edm.PropertyValue */) {
260
+ writer.addChange({
261
+ type: 'replace-record-property',
262
+ pointer: pointer,
263
+ newProperty: change.newElement
264
+ });
265
+ }
266
+ else {
267
+ writer.addChange({
268
+ type: 'replace-node',
269
+ pointer: pointer,
270
+ newElement: change.newElement
271
+ });
272
+ }
273
+ }
274
+ else {
275
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newElement.name}`, error_1.ApiErrorCode.General);
276
+ }
277
+ };
278
+ this[_j] = (writer, document, change) => {
279
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
280
+ const segments = change.pointer.split('/');
281
+ const lastSegment = segments.pop();
282
+ const annotationFileNode = (0, utils_1.getGenericNodeFromPointer)(document.annotationFile, segments.join('/'));
283
+ if (pointer) {
284
+ if (lastSegment === 'text' && elementHasFlags(annotationFileNode)) {
285
+ // CDS has specific syntax for flags and
286
+ writer.addChange({
287
+ type: 'set-flags',
288
+ pointer: pointer,
289
+ value: change.text.text
290
+ });
291
+ }
292
+ else {
293
+ writer === null || writer === void 0 ? void 0 : writer.addChange({
294
+ type: 'replace-text-value',
295
+ pointer: pointer,
296
+ newValue: change.text.text
297
+ });
298
+ }
299
+ }
300
+ else {
301
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.text}`, error_1.ApiErrorCode.General);
302
+ }
303
+ };
304
+ this[_k] = (writer, document, change) => {
305
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, change.pointer, document.ast);
306
+ const [currentAstNode] = (0, pointer_1.getAstNodesFromPointer)(document.ast, pointer).slice(-1);
307
+ const annotationFileNode = (0, utils_1.getGenericNodeFromPointer)(document.annotationFile, change.pointer);
308
+ const newValue = change.newValue[0];
309
+ if (pointer && currentAstNode && (newValue === null || newValue === void 0 ? void 0 : newValue.type) === odata_annotation_core_types_1.TEXT_TYPE) {
310
+ if ((annotationFileNode === null || annotationFileNode === void 0 ? void 0 : annotationFileNode.type) === odata_annotation_core_types_1.ELEMENT_TYPE && annotationFileNode.name === "EnumMember" /* Edm.EnumMember */) {
311
+ if (elementHasFlags(annotationFileNode)) {
312
+ writer.addChange({
313
+ type: 'set-flags',
314
+ pointer: pointer,
315
+ value: newValue.text
316
+ });
317
+ }
318
+ else {
319
+ writer.addChange({
320
+ type: 'replace-text-value',
321
+ pointer: pointer,
322
+ newValue: newValue.text
323
+ });
324
+ }
325
+ }
326
+ else {
327
+ writer.addChange({
328
+ type: 'update-primitive-value',
329
+ pointer: pointer,
330
+ newValue: newValue.text
331
+ });
332
+ }
333
+ }
334
+ else {
335
+ throw new error_1.ApiError(`Could not process change ${change.type} ${change.uri} ${change.pointer} ${change.newValue}`, error_1.ApiErrorCode.General);
336
+ }
337
+ };
338
+ this[_l] = (writer, document, change) => {
339
+ const { pointer, index } = change;
340
+ const { pointer: toPointer } = (0, pointer_1.convertPointer)(document.annotationFile, pointer, document.ast);
341
+ const toNode = (0, utils_1.getGenericNodeFromPointer)(document.annotationFile, pointer);
342
+ if (toPointer && (0, odata_annotation_core_1.isElementWithName)(toNode, 'Collection')) {
343
+ writer.addChange({
344
+ type: 'move-collection-value',
345
+ pointer: toPointer,
346
+ index,
347
+ fromPointers: change.fromPointers.map((ptr) => {
348
+ const { pointer } = (0, pointer_1.convertPointer)(document.annotationFile, ptr, document.ast);
349
+ return pointer;
350
+ })
351
+ });
352
+ }
353
+ };
354
+ this[_m] = () => {
355
+ // noop, such changes have no effect in CDS
356
+ };
357
+ this[_o] = () => {
358
+ // noop, such changes are not supported in CDS
359
+ };
360
+ this.fileCache = new Map();
361
+ this._fileSequence = service.serviceFiles;
362
+ }
363
+ setFileCache(fileCache) {
364
+ this.fileCache = fileCache;
365
+ }
366
+ setFacade(facade) {
367
+ this.facade = facade;
368
+ }
369
+ /**
370
+ * @returns Compiled CDS service.
371
+ */
372
+ get compiledService() {
373
+ if (!this._compiledService) {
374
+ this._compiledService = this._getCompiledService();
375
+ }
376
+ return this._compiledService;
377
+ }
378
+ set compiledService(v) {
379
+ this._compiledService = v;
380
+ }
381
+ /**
382
+ * Refreshes internal data structures from the provided project files.
383
+ *
384
+ * @param fileCache - File uri mapped to file content.
385
+ * @returns Sync errors
386
+ */
387
+ sync(fileCache) {
388
+ return __awaiter(this, void 0, void 0, function* () {
389
+ const paths = [...this.service.serviceFiles.map((file) => (0, url_1.fileURLToPath)(file.uri))];
390
+ const facade = yield (0, ux_cds_compiler_facade_1.createCdsCompilerFacadeForRoot)(this.project.root, paths, fileCache);
391
+ this.setFacade(facade);
392
+ const compileErrors = facade.getCompilerErrors(this.project.root);
393
+ const relevantErrors = [...compileErrors].filter(([file, compilerMessage]) => {
394
+ return (compilerMessage.messages.filter((value) => value.severity === odata_annotation_core_types_1.DiagnosticSeverity.Error).length &&
395
+ !file.startsWith('../'));
396
+ });
397
+ if (relevantErrors.length > 0) {
398
+ // if model has compiler errors
399
+ for (const [relativePath, compilerMessage] of relevantErrors) {
400
+ console.log(`Compile errors in: ${relativePath}`);
401
+ for (const [fileUri, content] of fileCache) {
402
+ if (fileUri.endsWith(relativePath)) {
403
+ console.log(content);
404
+ }
405
+ }
406
+ console.log(JSON.stringify(compilerMessage, undefined, 2));
407
+ }
408
+ return compileErrors;
409
+ }
410
+ this.documents.clear();
411
+ this.invalidateCaches();
412
+ this.updateFileSequence(facade);
413
+ this.setFileCache(fileCache);
414
+ const metadataElementMap = facade.getMetadata(this.service.serviceName);
415
+ // We collect already full metadata from compile model, we don't need to build it based on paths.
416
+ const metadataCollector = (0, ux_cds_compiler_facade_1.createMetadataCollector)(new Map(), facade);
417
+ const { propagationMap, sourceUris } = facade.getPropagatedTargetMap(this.service.serviceName);
418
+ for (const file of this.service.serviceFiles) {
419
+ const document = (0, document_1.getDocument)(this.service.serviceName, this.vocabularyService, facade, fileCache, file, metadataCollector);
420
+ this.documents.set(file.uri, document);
421
+ // ghost files
422
+ if (sourceUris.has((0, path_1.relative)(this.project.root, (0, url_1.fileURLToPath)(file.uri)))) {
423
+ const ghostDoc = (0, document_1.getGhostFileDocument)(this.service.serviceName, this.vocabularyService, facade, fileCache, file, metadataCollector, propagationMap);
424
+ this.documents.set(ghostDoc.annotationFile.uri, ghostDoc);
425
+ }
426
+ }
427
+ const metadataElements = (0, ux_cds_compiler_facade_1.getMetadataElementsFromMap)(metadataElementMap);
428
+ this.metadataService = new odata_entity_model_1.MetadataService({ uriMap: (facade === null || facade === void 0 ? void 0 : facade.getUriMap()) || new Map() });
429
+ this.metadataService.import(metadataElements, 'DummyMetadataFileUri');
430
+ return new Map();
431
+ });
432
+ }
433
+ /**
434
+ * Returns all relevant service files.
435
+ *
436
+ * @param includeGhostFiles - Flag indicating if ghost files should be included.
437
+ * @returns All relevant service files.
438
+ */
439
+ getAllFiles(includeGhostFiles) {
440
+ if (includeGhostFiles) {
441
+ const annotationFiles = [...this.compiledService.annotationFiles];
442
+ annotationFiles.reverse();
443
+ return annotationFiles.map((file) => {
444
+ var _p, _q;
445
+ return ({
446
+ uri: file.uri,
447
+ isReadOnly:
448
+ // ghost files are readOnly and should not be in service files
449
+ (_q = (_p = this.service.serviceFiles.find((serviceFile) => serviceFile.uri === file.uri)) === null || _p === void 0 ? void 0 : _p.isReadOnly) !== null && _q !== void 0 ? _q : true
450
+ });
451
+ });
452
+ }
453
+ return [...this.service.serviceFiles];
454
+ }
455
+ /**
456
+ * Creates empty annotation file content for the given service.
457
+ *
458
+ * @param serviceName - Name of the service.
459
+ * @param uri - URI for the new annotation file.
460
+ * @returns New annotation file content.
461
+ */
462
+ getInitialFileContent(serviceName, uri) {
463
+ var _p;
464
+ if (this.facade) {
465
+ const fileName = (_p = this.facade.getFileName(serviceName)) !== null && _p !== void 0 ? _p : '';
466
+ let path = (0, path_1.relative)((0, path_1.dirname)(uri), (0, path_1.join)(this.project.root, (0, path_1.dirname)(fileName))).replace(/\\/g, '/');
467
+ path = (0, path_1.join)(path, (0, path_1.basename)(fileName, '.cds'));
468
+ path = path.split(path_1.sep).join('/'); // always use '/' instead of platform specific separator
469
+ return `using ${serviceName} as service from '${path}';\n`;
470
+ }
471
+ return '';
472
+ }
473
+ /**
474
+ * Converts changes to workspace edits.
475
+ *
476
+ * @param changes - Internal changes.
477
+ * @returns Workspace edits.
478
+ */
479
+ getWorkspaceEdit(changes) {
480
+ var _p;
481
+ return __awaiter(this, void 0, void 0, function* () {
482
+ const workspaceChanges = {};
483
+ this.clearState();
484
+ const writers = new Map();
485
+ for (const change of changes) {
486
+ let writer = writers.get(change.uri);
487
+ const document = this.documents.get(change.uri);
488
+ const cachedFile = (_p = this.fileCache) === null || _p === void 0 ? void 0 : _p.get(change.uri);
489
+ if (!document || cachedFile === undefined || !this.facade) {
490
+ continue;
491
+ }
492
+ if (!writer) {
493
+ //writable cds document (augment)
494
+ const textDocument = vscode_languageserver_textdocument_1.TextDocument.create(change.uri, 'cds', 0, cachedFile);
495
+ writer = new writer_1.CDSWriter(this.facade, this.vocabularyService, document.ast, document.comments, document.tokens, textDocument, this.project.root, document.annotationFile);
496
+ writers.set(change.uri, writer);
497
+ }
498
+ const changeHandler = this[change.type];
499
+ changeHandler(writer, document, change);
500
+ }
501
+ for (const [uri, writer] of writers.entries()) {
502
+ const document = this.documents.get(uri);
503
+ if (!document) {
504
+ continue;
505
+ }
506
+ this.processMissingReferences(uri, writer);
507
+ const edits = yield writer.getTextEdits();
508
+ workspaceChanges[uri] = edits;
509
+ }
510
+ return {
511
+ changes: workspaceChanges
512
+ };
513
+ });
514
+ }
515
+ /**
516
+ * Checks if there are no compile errors in the files after update.
517
+ *
518
+ * @param fileCache - Updated file content.
519
+ * @returns Errors.
520
+ */
521
+ validateChanges(fileCache) {
522
+ return __awaiter(this, void 0, void 0, function* () {
523
+ return this.sync(fileCache);
524
+ });
525
+ }
526
+ /**
527
+ * Converts annotation object to a string.
528
+ *
529
+ * @param target - Content of an 'Annotations' element.
530
+ * @returns CDS representation of the annotations.
531
+ */
532
+ serializeTarget(target) {
533
+ return (0, cds_odata_annotation_converter_1.printTarget)(target);
534
+ }
535
+ _getCompiledService() {
536
+ var _p;
537
+ const annotationFiles = [];
538
+ for (const file of (_p = this._fileSequence) !== null && _p !== void 0 ? _p : []) {
539
+ const document = this.documents.get(file.uri);
540
+ const ghostDocument = this.documents.get('!' + file.uri);
541
+ if (ghostDocument) {
542
+ annotationFiles.push(ghostDocument.annotationFile);
543
+ }
544
+ if (document) {
545
+ annotationFiles.push(document.annotationFile);
546
+ }
547
+ else {
548
+ throw new error_1.ApiError(`Could not compile service. Missing document ${file.uri}`, error_1.ApiErrorCode.General);
549
+ }
550
+ }
551
+ annotationFiles.reverse();
552
+ return Object.freeze({
553
+ odataVersion: '4.0',
554
+ annotationFiles,
555
+ metadata: this.metadata
556
+ });
557
+ }
558
+ clearState() {
559
+ this.missingReferences = {};
560
+ }
561
+ invalidateCaches() {
562
+ this._compiledService = undefined;
563
+ this._fileSequence = undefined;
564
+ }
565
+ updateFileSequence(facade) {
566
+ this._fileSequence = facade.getFileSequence().map((uri) => ({
567
+ uri: (0, url_1.pathToFileURL)(uri).toString(),
568
+ isReadOnly: uri.indexOf('node_modules') !== -1
569
+ }));
570
+ this.service.serviceFiles = [...this._fileSequence];
571
+ }
572
+ processMissingReferences(uri, writer) {
573
+ const missingReferences = this.missingReferences[uri];
574
+ if (missingReferences === null || missingReferences === void 0 ? void 0 : missingReferences.size) {
575
+ const pointer = '/references';
576
+ const normalizedReferences = [...missingReferences].map((reference) => {
577
+ if (reference.startsWith('file://')) {
578
+ // uri => convert to relative path to root
579
+ const path = (0, utils_1.pathFromUri)(reference);
580
+ return (0, path_1.relative)(this.project.root, path);
581
+ }
582
+ else {
583
+ return reference;
584
+ }
585
+ });
586
+ writer.addChange((0, change_1.createInsertReferenceChange)(pointer, normalizedReferences));
587
+ }
588
+ }
589
+ addMissingReferences(uri, references) {
590
+ var _p;
591
+ var _q;
592
+ const missingReferences = ((_p = (_q = this.missingReferences)[uri]) !== null && _p !== void 0 ? _p : (_q[uri] = new Set()));
593
+ for (const reference of references) {
594
+ missingReferences.add(reference);
595
+ }
596
+ }
597
+ insertInFlattenedStructure(writer, document, change, pointer) {
598
+ const targetPointer = pointer.split('/').slice(0, 3).join('/');
599
+ const termPointer = change.pointer.split('/').slice(0, 5).join('/');
600
+ const annotationValuePointer = change.pointer.split('/').slice(5).join('/');
601
+ const element = (0, utils_1.getGenericNodeFromPointer)(document.annotationFile, termPointer);
602
+ if ((element === null || element === void 0 ? void 0 : element.type) === odata_annotation_core_types_1.ELEMENT_TYPE) {
603
+ const annotation = buildAnnotation(element, annotationValuePointer, change.element);
604
+ if (annotation) {
605
+ writer.addChange({
606
+ type: 'insert-annotation',
607
+ element: annotation,
608
+ pointer: targetPointer
609
+ });
610
+ }
611
+ }
612
+ }
613
+ insertAnnotation(writer, change, pointer) {
614
+ // insert annotation value
615
+ if (change.element.name === "Annotation" /* Edm.Annotation */) {
616
+ writer.addChange((0, change_1.createInsertEmbeddedAnnotationChange)(pointer, change.element));
617
+ }
618
+ else if (change.element.name === "Collection" /* Edm.Collection */) {
619
+ writer.addChange((0, change_1.createInsertCollectionChange)(pointer, change.element));
620
+ }
621
+ else if (change.element.name === "Record" /* Edm.Record */) {
622
+ writer.addChange((0, change_1.createInsertRecordChange)(pointer, change.element));
623
+ }
624
+ else if (utils_1.PRIMITIVE_TYPE_NAMES.includes(change.element.name)) {
625
+ writer.addChange((0, change_1.createInsertPrimitiveValueChange)(pointer, change.element));
626
+ }
627
+ }
628
+ insertRecord(writer, change, pointer) {
629
+ var _p;
630
+ if (change.element.name === "PropertyValue" /* Edm.PropertyValue */) {
631
+ const modifiedPointer = [...pointer.split('/'), 'properties'].join('/'); // pointer is record
632
+ writer.addChange((0, change_1.createInsertRecordPropertyChange)(modifiedPointer, change.element, change.index));
633
+ }
634
+ else if (change.element.name === "Annotation" /* Edm.Annotation */) {
635
+ writer.addChange((0, change_1.createInsertEmbeddedAnnotationChange)(pointer, change.element, change.index));
636
+ }
637
+ else if (change.element.name === "Record" /* Edm.Record */) {
638
+ const segment = pointer.split('/');
639
+ const changeIndex = parseInt((_p = segment.pop()) !== null && _p !== void 0 ? _p : '', 10);
640
+ const modifiedPointer = segment.join('/'); //point to annotations
641
+ writer.addChange((0, change_1.createInsertRecordChange)(modifiedPointer, change.element, changeIndex));
642
+ }
643
+ }
644
+ }
645
+ exports.CDSAnnotationServiceAdapter = CDSAnnotationServiceAdapter;
646
+ _a = types_1.INSERT_TARGET, _b = types_1.DELETE_ELEMENT, _c = types_1.INSERT_ELEMENT, _d = types_1.INSERT_ATTRIBUTE, _e = types_1.DELETE_ATTRIBUTE, _f = types_1.UPDATE_ATTRIBUTE_VALUE, _g = internal_change_1.REPLACE_ATTRIBUTE, _h = internal_change_1.REPLACE_ELEMENT, _j = internal_change_1.REPLACE_TEXT, _k = internal_change_1.REPLACE_ELEMENT_CONTENT, _l = internal_change_1.MOVE_ELEMENT, _m = internal_change_1.UPDATE_ELEMENT_NAME, _o = internal_change_1.DELETE_REFERENCE;
647
+ function getAliasInfo(annotationFileInternal, metadataService, vocabularyAPI) {
648
+ const namespaces = (0, odata_annotation_core_1.getAllNamespacesAndReferences)(annotationFileInternal.namespace, annotationFileInternal.references);
649
+ const aliasInfo = (0, odata_annotation_core_1.getAliasInformation)(namespaces, metadataService.getNamespaces());
650
+ return (0, vocabularies_1.addAllVocabulariesToAliasInformation)(aliasInfo, vocabularyAPI.getVocabularies());
651
+ }
652
+ function elementHasFlags(element) {
653
+ if (!element || element.type !== 'element') {
654
+ return false;
655
+ }
656
+ const content = element.content[0];
657
+ if ((content === null || content === void 0 ? void 0 : content.type) === 'text' && element.name === "EnumMember" /* Edm.EnumMember */) {
658
+ return content.text.split(' ').length > 1;
659
+ }
660
+ return false;
661
+ }
662
+ function buildAnnotation(root, pointer, lastContent) {
663
+ const segments = pointer.split('/');
664
+ let node = root;
665
+ if (node.type !== odata_annotation_core_types_1.ELEMENT_TYPE) {
666
+ return undefined;
667
+ }
668
+ const result = buildElement(node);
669
+ let current = result;
670
+ for (const segment of segments) {
671
+ const next = node[segment];
672
+ if (next) {
673
+ node = next;
674
+ if (node.type === odata_annotation_core_types_1.ELEMENT_TYPE) {
675
+ const nextElement = buildElement(node);
676
+ current.content.push(nextElement);
677
+ current = nextElement;
678
+ }
679
+ else if (!Array.isArray(node)) {
680
+ return undefined;
681
+ }
682
+ }
683
+ else {
684
+ return undefined;
685
+ }
686
+ }
687
+ current.content.push(lastContent);
688
+ return result;
689
+ }
690
+ function buildElement(node) {
691
+ const result = (0, odata_annotation_core_types_1.createElementNode)({ name: node.name });
692
+ if (node.name === "Annotation" /* Edm.Annotation */) {
693
+ result.attributes["Term" /* Edm.Term */] = node.attributes["Term" /* Edm.Term */];
694
+ if (node.attributes["Qualifier" /* Edm.Qualifier */]) {
695
+ result.attributes["Qualifier" /* Edm.Qualifier */] = node.attributes["Qualifier" /* Edm.Qualifier */];
696
+ }
697
+ }
698
+ if (node.name === "PropertyValue" /* Edm.PropertyValue */) {
699
+ result.attributes["Property" /* Edm.Property */] = node.attributes["Property" /* Edm.Property */];
700
+ }
701
+ return result;
702
+ }
703
+ //# sourceMappingURL=adapter.js.map