@ui5/task-adaptation 1.3.1 → 1.3.2

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 (94) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/dist/annotationManager.d.ts +18 -0
  3. package/dist/annotationManager.js +79 -0
  4. package/dist/annotations/comparator/comparator.d.ts +47 -0
  5. package/dist/annotations/comparator/comparator.js +283 -0
  6. package/dist/annotations/comparator/diffCase.d.ts +4 -0
  7. package/dist/annotations/comparator/diffCase.js +2 -0
  8. package/dist/annotations/comparator/interchangableCase.d.ts +25 -0
  9. package/dist/annotations/comparator/interchangableCase.js +60 -0
  10. package/dist/annotations/converter/metadataJsonReferenceUtil.d.ts +12 -0
  11. package/dist/annotations/converter/metadataJsonReferenceUtil.js +48 -0
  12. package/dist/annotations/converter/metadataJsonUtil.d.ts +30 -0
  13. package/dist/annotations/converter/metadataJsonUtil.js +70 -0
  14. package/dist/annotations/converter/ui5JsonConverter.d.ts +21 -0
  15. package/dist/annotations/converter/ui5JsonConverter.js +252 -0
  16. package/dist/annotations/converter/ui5MetadataJsonUtil.d.ts +3 -0
  17. package/dist/annotations/converter/ui5MetadataJsonUtil.js +10 -0
  18. package/dist/annotations/converter/ui5XmlConverter.d.ts +5 -0
  19. package/dist/annotations/converter/ui5XmlConverter.js +14 -0
  20. package/dist/annotations/dataSource/dataSource.d.ts +34 -0
  21. package/dist/annotations/dataSource/dataSource.js +62 -0
  22. package/dist/annotations/dataSource/dataSourceManager.d.ts +12 -0
  23. package/dist/annotations/dataSource/dataSourceManager.js +45 -0
  24. package/dist/annotations/dataSource/dataSourceOData.d.ts +17 -0
  25. package/dist/annotations/dataSource/dataSourceOData.js +45 -0
  26. package/dist/annotations/dataSource/dataSourceODataAnnotation.d.ts +6 -0
  27. package/dist/annotations/dataSource/dataSourceODataAnnotation.js +16 -0
  28. package/dist/annotations/serviceRequestor.d.ts +9 -0
  29. package/dist/annotations/serviceRequestor.js +73 -0
  30. package/dist/annotations/transformers/convertV2ToV4.d.ts +4 -0
  31. package/dist/annotations/transformers/convertV2ToV4.js +13 -0
  32. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.d.ts +6 -0
  33. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.js +41 -0
  34. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.d.ts +4 -0
  35. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.js +14 -0
  36. package/dist/annotations/transformers/transformer.d.ts +12 -0
  37. package/dist/annotations/transformers/transformer.js +2 -0
  38. package/dist/annotations/transformers/traverseReferences.d.ts +9 -0
  39. package/dist/annotations/transformers/traverseReferences.js +66 -0
  40. package/dist/appVariantManager.d.ts +12 -0
  41. package/dist/appVariantManager.js +102 -0
  42. package/dist/baseAppManager.d.ts +29 -0
  43. package/dist/baseAppManager.js +139 -0
  44. package/dist/buildStrategy.d.ts +7 -0
  45. package/dist/buildStrategy.js +19 -0
  46. package/dist/bundle.d.ts +25 -0
  47. package/dist/bundle.js +6975 -0
  48. package/dist/cache/annotationsCacheManager.d.ts +8 -0
  49. package/dist/cache/annotationsCacheManager.js +16 -0
  50. package/dist/cache/baseAppFilesCacheManager.d.ts +6 -0
  51. package/dist/cache/baseAppFilesCacheManager.js +12 -0
  52. package/dist/cache/cacheManager.d.ts +16 -0
  53. package/dist/cache/cacheManager.js +65 -0
  54. package/dist/i18nManager.d.ts +43 -0
  55. package/dist/i18nManager.js +203 -0
  56. package/dist/index.d.ts +6 -0
  57. package/dist/index.js +25 -0
  58. package/dist/model/annotationDiffStructureError.d.ts +3 -0
  59. package/dist/model/annotationDiffStructureError.js +8 -0
  60. package/dist/model/language.d.ts +13 -0
  61. package/dist/model/language.js +37 -0
  62. package/dist/model/noAuthorizationProvidedError.d.ts +3 -0
  63. package/dist/model/noAuthorizationProvidedError.js +6 -0
  64. package/dist/model/serverError.d.ts +3 -0
  65. package/dist/model/serverError.js +6 -0
  66. package/dist/model/types.d.ts +119 -0
  67. package/dist/model/types.js +2 -0
  68. package/dist/processors/abapProcessor.d.ts +21 -0
  69. package/dist/processors/abapProcessor.js +37 -0
  70. package/dist/processors/cfProcessor.d.ts +17 -0
  71. package/dist/processors/cfProcessor.js +45 -0
  72. package/dist/processors/processor.d.ts +7 -0
  73. package/dist/processors/processor.js +32 -0
  74. package/dist/repositories/abapRepoManager.d.ts +13 -0
  75. package/dist/repositories/abapRepoManager.js +82 -0
  76. package/dist/repositories/html5RepoManager.d.ts +11 -0
  77. package/dist/repositories/html5RepoManager.js +87 -0
  78. package/dist/util/cfUtil.d.ts +30 -0
  79. package/dist/util/cfUtil.js +171 -0
  80. package/dist/util/commonUtil.d.ts +13 -0
  81. package/dist/util/commonUtil.js +118 -0
  82. package/dist/util/i18nMerger.d.ts +32 -0
  83. package/dist/util/i18nMerger.js +99 -0
  84. package/dist/util/requestUtil.d.ts +8 -0
  85. package/dist/util/requestUtil.js +54 -0
  86. package/dist/util/resourceUtil.d.ts +11 -0
  87. package/dist/util/resourceUtil.js +62 -0
  88. package/dist/util/urlUtil.d.ts +4 -0
  89. package/dist/util/urlUtil.js +18 -0
  90. package/dist/util/xmlUtil.d.ts +4 -0
  91. package/dist/util/xmlUtil.js +21 -0
  92. package/dist/util/zipUtil.d.ts +2 -0
  93. package/dist/util/zipUtil.js +16 -0
  94. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -2,7 +2,10 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4
4
 
5
- A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.3.1...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.3.2...HEAD).
6
+
7
+ <a name="v1.3.2"></a>
8
+ ## [v1.3.2] - 2024-06-04
6
9
 
7
10
  <a name="v1.3.1"></a>
8
11
  ## [v1.3.1] - 2024-06-04
@@ -91,6 +94,7 @@ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task
91
94
  <a name="v1.0.0"></a>
92
95
  ## v1.0.0 - 2020-12-09
93
96
 
97
+ [v1.3.2]: https://github.com/SAP/ui5-task-adaptation/compare/v1.3.1...v1.3.2
94
98
  [v1.3.1]: https://github.com/SAP/ui5-task-adaptation/compare/v1.3.0...v1.3.1
95
99
  [v1.3.0]: https://github.com/SAP/ui5-task-adaptation/compare/v1.2.0...v1.3.0
96
100
  [v1.2.0]: https://github.com/SAP/ui5-task-adaptation/compare/v1.1.3...v1.2.0
@@ -0,0 +1,18 @@
1
+ import AbapRepoManager from "./repositories/abapRepoManager.js";
2
+ import { IConfiguration } from "./model/types.js";
3
+ import Language from "./model/language.js";
4
+ export interface IAnnotationFiles {
5
+ annotationName: string;
6
+ annotationFileName: string;
7
+ }
8
+ export default class AnnotationManager {
9
+ private abapRepoManager;
10
+ private configuration;
11
+ constructor(configuration: IConfiguration, abapRepoManager: AbapRepoManager);
12
+ ANNOTATIONS_FOLDER: string;
13
+ process(renamedBaseAppManifest: any, languages: Language[]): Promise<Map<string, string>>;
14
+ private normalizeAppVariantId;
15
+ private updateManifestModel;
16
+ private createManifestModel;
17
+ private enhanceManifestModel;
18
+ }
@@ -0,0 +1,79 @@
1
+ import BaseAppManager from "./baseAppManager.js";
2
+ import DataSourceManager from "./annotations/dataSource/dataSourceManager.js";
3
+ import I18nManager from "./i18nManager.js";
4
+ import ServiceRequestor from "./annotations/serviceRequestor.js";
5
+ import { posix as path } from "path";
6
+ const I18N_DEFAULT_PATH = "i18n/annotations";
7
+ const I18N_DEFAULT_MODEL_NAME = "@i18n";
8
+ const SAPUI5 = "sap.ui5";
9
+ export default class AnnotationManager {
10
+ abapRepoManager;
11
+ configuration;
12
+ constructor(configuration, abapRepoManager) {
13
+ this.configuration = configuration;
14
+ this.abapRepoManager = abapRepoManager;
15
+ }
16
+ ANNOTATIONS_FOLDER = "annotations";
17
+ async process(renamedBaseAppManifest, languages) {
18
+ const { id } = BaseAppManager.getIdVersion(renamedBaseAppManifest);
19
+ BaseAppManager.validateProperty(id, "sap.app/id");
20
+ const normalisedId = this.normalizeAppVariantId(id);
21
+ //TODO: switch to this after resolving @i18n custom model
22
+ const modelName = I18N_DEFAULT_MODEL_NAME; //`i18n_a9n_${normalisedId}`;
23
+ const i18nPathName = path.join(I18N_DEFAULT_PATH, normalisedId);
24
+ const i18nManager = new I18nManager(modelName, id, languages);
25
+ const serviceRequestor = new ServiceRequestor(this.configuration, this.abapRepoManager);
26
+ const dataSourceManager = new DataSourceManager();
27
+ dataSourceManager.addDataSources(renamedBaseAppManifest["sap.app"]?.dataSources);
28
+ const annotationFiles = await dataSourceManager.createAnnotationFiles(languages, i18nManager, serviceRequestor);
29
+ const i18nFiles = i18nManager.createFiles(i18nPathName);
30
+ if (i18nManager.hasTranslations()) {
31
+ this.updateManifestModel(renamedBaseAppManifest, modelName, i18nPathName);
32
+ }
33
+ return new Map([...annotationFiles, ...i18nFiles]);
34
+ }
35
+ normalizeAppVariantId(id, replaceWith = "") {
36
+ return id.replace(/[.\W]+/gi, replaceWith);
37
+ }
38
+ updateManifestModel(renamedBaseAppManifest, modelName, i18nPathName) {
39
+ const uri = `${i18nPathName}/i18n.properties`;
40
+ this.enhanceManifestModel(renamedBaseAppManifest, modelName, uri);
41
+ //TODO: switch to this after resolving @i18n custom model
42
+ //this.createManifestModel(renamedBaseAppManifest, modelName, uri);
43
+ }
44
+ createManifestModel(manifest, modelName, uri) {
45
+ let sapui5 = manifest[SAPUI5] == null ? manifest[SAPUI5] = {} : manifest[SAPUI5];
46
+ if (sapui5.models == null) {
47
+ sapui5.models = {};
48
+ }
49
+ if (sapui5.models[modelName] == null) {
50
+ sapui5.models[modelName] = {};
51
+ }
52
+ sapui5.models[modelName].type = "sap.ui.model.resource.ResourceModel";
53
+ if (uri) {
54
+ sapui5.models[modelName].uri = uri;
55
+ }
56
+ return sapui5.models[modelName];
57
+ }
58
+ enhanceManifestModel(manifest, modelToEnhance, bundleUrl) {
59
+ let model = manifest[SAPUI5]?.models[modelToEnhance];
60
+ if (model) {
61
+ if (model.settings == null) {
62
+ model.settings = {};
63
+ }
64
+ if (model.settings.enhanceWith == null) {
65
+ model.settings.enhanceWith = [];
66
+ }
67
+ if (model.settings.enhanceWith.every((bundle) => bundle.bundleUrl !== bundleUrl)) {
68
+ model.settings.enhanceWith.push({
69
+ bundleUrl,
70
+ bundleUrlRelativeTo: "component"
71
+ });
72
+ }
73
+ }
74
+ else {
75
+ this.createManifestModel(manifest, modelToEnhance, bundleUrl);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=annotationManager.js.map
@@ -0,0 +1,47 @@
1
+ export interface IDiffProperty {
2
+ object: any;
3
+ property: string | number;
4
+ }
5
+ export declare class Diff {
6
+ __old: string;
7
+ __new: string;
8
+ constructor(__old: string, __new: string);
9
+ toString(): string;
10
+ }
11
+ export interface DiffJson {
12
+ json: any;
13
+ properties: Set<IDiffProperty>;
14
+ }
15
+ export default class Comparator {
16
+ private diffs;
17
+ private xml_a;
18
+ private xml_b;
19
+ constructor(xml_a: string, xml_b: string);
20
+ compare(): DiffJson;
21
+ private traverseCompare;
22
+ /**
23
+ * If one language annotation has one property it is an object, if other
24
+ * language same annotation consists of multiple properties, we need to
25
+ * equal them, so they are both arrays (see test 01-04).
26
+ */
27
+ private arrayIfNeeded;
28
+ /**
29
+ * If some node (Annotations, Annotation, PropertyValue, LabeledElement) has
30
+ * an id, we can compare by id, so the items order doesn't matter anymore.
31
+ * @param a array of nodes with id of one language
32
+ * @param b array of nodes with id of the other language
33
+ * @param idProperty property which value is an id (e.g. Target="<unique-id>")
34
+ * @param property node name (Annotations, Annotation, PropertyValue, ...)
35
+ */
36
+ private traverseById;
37
+ /**
38
+ * Some nodes, like Annotations, Annotation, PropertyValue have unique id
39
+ * among other same nodes. We can use it to know what to compare with what
40
+ * even if the order is different. IdProperty is a property name of that id,
41
+ * e.g. for Annotations it will be Target (like in
42
+ * Target="<some-unique-id>").
43
+ * @param property node which might have an id: Annotations, PropertyValue
44
+ * @return the property name which represents id: Target, Property
45
+ */
46
+ private getIdProperty;
47
+ }
@@ -0,0 +1,283 @@
1
+ import { insertInArray, traverse } from "../../util/commonUtil.js";
2
+ import AnnotationDiffStructureError from "../../model/annotationDiffStructureError.js";
3
+ import InterchangableCase from "./interchangableCase.js";
4
+ import MetadataJsonUtil from "../converter/metadataJsonUtil.js";
5
+ import XmlUtil from "../../util/xmlUtil.js";
6
+ export class Diff {
7
+ __old;
8
+ __new;
9
+ constructor(__old, __new) {
10
+ this.__old = __old;
11
+ this.__new = __new;
12
+ }
13
+ toString() {
14
+ return `{ __old: ${this.__old}, __new: ${this.__new} }`;
15
+ }
16
+ }
17
+ export default class Comparator {
18
+ diffs = new Set();
19
+ xml_a;
20
+ xml_b;
21
+ constructor(xml_a, xml_b) {
22
+ this.xml_a = xml_a;
23
+ this.xml_b = xml_b;
24
+ }
25
+ compare() {
26
+ const json_a = typeof this.xml_a === "string" ? XmlUtil.xmlToJson(this.xml_a) : this.xml_a;
27
+ const json_b = typeof this.xml_b === "string" ? XmlUtil.xmlToJson(this.xml_b) : this.xml_b;
28
+ const scheme_a = MetadataJsonUtil.getSchemaNode(json_a);
29
+ const scheme_b = MetadataJsonUtil.getSchemaNode(json_b);
30
+ if (scheme_a && scheme_b) {
31
+ // we compare only Annotations, other types are left as it is
32
+ this.traverseCompare(scheme_a, scheme_b, "Annotations");
33
+ }
34
+ return {
35
+ json: json_a,
36
+ properties: this.diffs
37
+ };
38
+ }
39
+ traverseCompare(obj_a, obj_b, property) {
40
+ let a = obj_a[property];
41
+ let b = obj_b[property];
42
+ if (typeof a === "object" && !(a instanceof Diff) && typeof b !== "object" ||
43
+ typeof b === "object" && !(b instanceof Diff) && typeof a !== "object" ||
44
+ a == null || b == null) {
45
+ // When during traversing we end up in primitives like string, we
46
+ // compare the values. If one of them is not primitive or oone of
47
+ // them is undefined, we throw exception (see test 06, 07).
48
+ throw new AnnotationDiffStructureError({ a, b });
49
+ }
50
+ else if (typeof a !== "object" && typeof b !== "object") {
51
+ // If primitive values are not same - we assume they are
52
+ // translations, so we save them.
53
+ if (a !== b) {
54
+ obj_a[property] = new Diff(a, b);
55
+ this.diffs.add({ object: obj_a, property });
56
+ }
57
+ }
58
+ else {
59
+ a = this.arrayIfNeeded(obj_a, obj_b, property);
60
+ b = this.arrayIfNeeded(obj_b, obj_a, property);
61
+ if (Array.isArray(a)) {
62
+ let idProperty = this.getIdProperty(property);
63
+ if (idProperty) {
64
+ this.traverseById(a, b, idProperty, property);
65
+ }
66
+ else {
67
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
68
+ if (a[i] && b[i]) {
69
+ this.traverseCompare(a, b, i);
70
+ }
71
+ else {
72
+ // If the number of items of nodes without id are
73
+ // different, we throw error (see test 08).
74
+ throw new AnnotationDiffStructureError({ a, b });
75
+ }
76
+ }
77
+ }
78
+ }
79
+ else {
80
+ for (const key of Object.keys(a)) {
81
+ this.traverseCompare(a, b, key);
82
+ }
83
+ }
84
+ }
85
+ }
86
+ /**
87
+ * If one language annotation has one property it is an object, if other
88
+ * language same annotation consists of multiple properties, we need to
89
+ * equal them, so they are both arrays (see test 01-04).
90
+ */
91
+ arrayIfNeeded(obj_a, obj_b, property) {
92
+ if (!Array.isArray(obj_a[property])) {
93
+ // If node with id - make array anyway, so it's easier to compare (see test 04).
94
+ if (simpleIdentifiers.has(property) || Array.isArray(obj_b[property])) {
95
+ obj_a[property] = [obj_a[property]];
96
+ }
97
+ }
98
+ return obj_a[property];
99
+ }
100
+ /**
101
+ * If some node (Annotations, Annotation, PropertyValue, LabeledElement) has
102
+ * an id, we can compare by id, so the items order doesn't matter anymore.
103
+ * @param a array of nodes with id of one language
104
+ * @param b array of nodes with id of the other language
105
+ * @param idProperty property which value is an id (e.g. Target="<unique-id>")
106
+ * @param property node name (Annotations, Annotation, PropertyValue, ...)
107
+ */
108
+ traverseById(a, b, idProperty, property) {
109
+ if (typeof property !== "string") {
110
+ return;
111
+ }
112
+ let items_a = new Items(a, idProperty);
113
+ let items_b = new Items(b, idProperty);
114
+ const includer_a = new Includer(a, property);
115
+ const includer_b = new Includer(b, property);
116
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
117
+ // There might be an exceptional case, when the object doesn't
118
+ // contain attributes. In this case we continue traversing, like
119
+ // UI5 does.
120
+ const id_a = a[i]?._attributes?.[idProperty];
121
+ const id_b = b[i]?._attributes?.[idProperty];
122
+ if (id_a !== id_b) {
123
+ // We go down the array and if suddenly the ids for comparing
124
+ // items are not the same, we need to find the item with the
125
+ // same id if it exists.
126
+ if (items_b.has(id_a) && items_a.has(id_b)) {
127
+ // If we found the item with the same id, we swap places
128
+ // with current item (see test 05).
129
+ items_b.swap(id_a, i);
130
+ }
131
+ else if (!items_a.has(id_b) && id_b) {
132
+ // If 1st language missing the item, include it from 2nd (see test 02).
133
+ includer_a.include(b, i);
134
+ }
135
+ else if (!items_b.has(id_a) && id_a) {
136
+ // If 2nd language missing the item, include it from 1st (see test 03).
137
+ includer_b.include(a, i);
138
+ }
139
+ }
140
+ this.traverseCompare(a, b, i);
141
+ }
142
+ }
143
+ /**
144
+ * Some nodes, like Annotations, Annotation, PropertyValue have unique id
145
+ * among other same nodes. We can use it to know what to compare with what
146
+ * even if the order is different. IdProperty is a property name of that id,
147
+ * e.g. for Annotations it will be Target (like in
148
+ * Target="<some-unique-id>").
149
+ * @param property node which might have an id: Annotations, PropertyValue
150
+ * @return the property name which represents id: Target, Property
151
+ */
152
+ getIdProperty(property) {
153
+ return simpleIdentifiers.get(property);
154
+ }
155
+ }
156
+ class Includer {
157
+ ALL_DIFF_CASES = [
158
+ new InterchangableCase()
159
+ ];
160
+ diffCases = new Array();
161
+ shouldClear;
162
+ target;
163
+ property;
164
+ /**
165
+ * It will decide what to do with the item missing in one language.
166
+ * @param target an array which might miss the item
167
+ * @param property the node name needed to decide how to include the missing
168
+ * item in array
169
+ * @param shouldClear if the item is missing and it's not Label or QuickInfo
170
+ * or Heading, we clear all the properties except Ids, so in i18n.properties
171
+ * they will have empty values. Because we don't know what should be there.
172
+ */
173
+ constructor(target, property, shouldClear = true) {
174
+ this.shouldClear = shouldClear;
175
+ this.target = target;
176
+ this.property = property;
177
+ for (const diffCase of this.ALL_DIFF_CASES) {
178
+ if (diffCase.canAccept(target, property)) {
179
+ this.diffCases.push(diffCase);
180
+ }
181
+ }
182
+ }
183
+ /**
184
+ * If in some language some array missing the item, we include the missing
185
+ * item from other language array with the same id.
186
+ * @param source the item from other language array that is missed in target
187
+ * @param index here to put it in the array
188
+ */
189
+ include(source, index) {
190
+ // Insert node with empty value (see test 02) if missing in default
191
+ // language or default language value if missing in other language
192
+ // (see test 03).
193
+ const clone = Includer.cloneAndClear(source[index], this.shouldClear);
194
+ insertInArray(this.target, index, clone);
195
+ // Some annotations like Label, QuickInfo or Heading are
196
+ // interchangable so if QuickInfo is missing we can copy the value
197
+ // from Label or Heading (see test 01).
198
+ for (const diffCase of this.diffCases) {
199
+ diffCase.accept(this.target, index, this.property);
200
+ }
201
+ }
202
+ /**
203
+ * if the item is missing in default language, and it's not Label or
204
+ * QuickInfo or Heading, we clear all the properties except Ids, so in
205
+ * i18n.properties they will have empty values. Because we don't know what
206
+ * should be there. But if the item is missing in language other than
207
+ * default, we include the copy of item from default language and not
208
+ * clearing them (see test 02, 04).
209
+ */
210
+ static cloneAndClear(obj, shouldClear = true) {
211
+ const clone = structuredClone(obj);
212
+ if (shouldClear) {
213
+ traverse(clone, [], (json, key) => {
214
+ if (typeof key !== "string" || !simpleIdentifiersReversed.has(key)) {
215
+ json[key] = "";
216
+ }
217
+ });
218
+ }
219
+ return clone;
220
+ }
221
+ }
222
+ class Items {
223
+ idProperty;
224
+ array;
225
+ objectMap = null;
226
+ /**
227
+ * Map of id per item which is lazy initialized if needed
228
+ * @param array
229
+ * @param idProperty
230
+ */
231
+ constructor(array, idProperty) {
232
+ this.array = array;
233
+ this.idProperty = idProperty;
234
+ }
235
+ /**
236
+ * Find the item with by id and swap their places.
237
+ * @param id of the item which seems like not in the place it should be
238
+ * @param newIndex new place where the item should actually be
239
+ */
240
+ swap(id, newIndex) {
241
+ const oldIndex = this.initMap().get(id);
242
+ const temp = this.array[newIndex];
243
+ this.array[newIndex] = this.array[oldIndex];
244
+ this.array[oldIndex] = temp;
245
+ this.initMap(true);
246
+ }
247
+ has(idProperty) {
248
+ return this.initMap().has(idProperty);
249
+ }
250
+ get(idProperty) {
251
+ return this.array[this.initMap().get(idProperty)];
252
+ }
253
+ /**
254
+ * Lazy init the map only if the order of items are messed up, which
255
+ * actually an eexception, so will make it lazy way.
256
+ * @param force force to update.
257
+ * @returns the map id per item index.
258
+ */
259
+ initMap(force = false) {
260
+ if (this.objectMap == null || force) {
261
+ this.objectMap = new Map(this.array.map((item, index) => [item._attributes[this.idProperty], index]));
262
+ }
263
+ return this.objectMap;
264
+ }
265
+ }
266
+ class Identifiers extends Map {
267
+ has(property) {
268
+ return typeof property === "string" && super.has(property);
269
+ }
270
+ get(property) {
271
+ return typeof property === "string" ? super.get(property) : undefined;
272
+ }
273
+ }
274
+ // According to OData schema some nodes MUST have the ids, by these nodes the
275
+ // property which contains the id is named differently as you can see.
276
+ const simpleIdentifiers = new Identifiers([
277
+ ["Annotations", "Target"],
278
+ ["Annotation", "Term"],
279
+ ["LabeledElement", "Name"],
280
+ ["PropertyValue", "Property"]
281
+ ]);
282
+ const simpleIdentifiersReversed = new Identifiers([...simpleIdentifiers].map(([name, idProperty]) => [idProperty, name]));
283
+ //# sourceMappingURL=comparator.js.map
@@ -0,0 +1,4 @@
1
+ export default interface DiffCase {
2
+ accept(target: any[], i: number, name?: string): void;
3
+ canAccept(target: any[], name?: string): boolean;
4
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=diffCase.js.map
@@ -0,0 +1,25 @@
1
+ import DiffCase from "./diffCase.js";
2
+ export default class InterchangableCase implements DiffCase {
3
+ accept(target: any[], i: number, name: string): void;
4
+ /**
5
+ * When default language source is already compared, it contains diff, e.g.
6
+ * { __old: value, __new: wert 1 }, if target annotation in other language
7
+ * has other value, it should also reflect the value, be { __old: value,
8
+ * __new: wert 2 }, not { __old: value, __new: wert 1 }. So we remove the
9
+ * diff completely from value and let it be compared again. Other language
10
+ * source will be empty anyway.
11
+ */
12
+ private getSourceValue;
13
+ /**
14
+ * If the array doesn't have any other annotations to take the values from,
15
+ * we just don't do it and include the annotations from other language as it
16
+ * is. E.g. we include Label but there are no Heading or QuickInfo to take
17
+ * values from. So we just don't do it.
18
+ * @param target where to put the missing item
19
+ * @param property node name
20
+ * @returns true if there are some annotations to take the values from.
21
+ */
22
+ canAccept(target: any[], property: string): boolean;
23
+ private interchangableTerms;
24
+ private findByPriority;
25
+ }
@@ -0,0 +1,60 @@
1
+ import { Diff } from "./comparator.js";
2
+ export default class InterchangableCase {
3
+ accept(target, i, name) {
4
+ if (name === "Annotation" && this.interchangableTerms.includes(target[i]?._attributes?.Term)) {
5
+ const source = this.findByPriority(target, i);
6
+ if (source) {
7
+ for (const attribute of Object.keys(source._attributes)) {
8
+ if (attribute !== "Term") {
9
+ const sourceValue = this.getSourceValue(source, attribute);
10
+ target[i]._attributes[attribute] = sourceValue;
11
+ }
12
+ }
13
+ }
14
+ }
15
+ }
16
+ /**
17
+ * When default language source is already compared, it contains diff, e.g.
18
+ * { __old: value, __new: wert 1 }, if target annotation in other language
19
+ * has other value, it should also reflect the value, be { __old: value,
20
+ * __new: wert 2 }, not { __old: value, __new: wert 1 }. So we remove the
21
+ * diff completely from value and let it be compared again. Other language
22
+ * source will be empty anyway.
23
+ */
24
+ getSourceValue(source, attribute) {
25
+ let value = source._attributes[attribute];
26
+ if (value instanceof Diff) {
27
+ value = value.__old;
28
+ }
29
+ return value;
30
+ }
31
+ /**
32
+ * If the array doesn't have any other annotations to take the values from,
33
+ * we just don't do it and include the annotations from other language as it
34
+ * is. E.g. we include Label but there are no Heading or QuickInfo to take
35
+ * values from. So we just don't do it.
36
+ * @param target where to put the missing item
37
+ * @param property node name
38
+ * @returns true if there are some annotations to take the values from.
39
+ */
40
+ canAccept(target, property) {
41
+ return property === "Annotation" && target
42
+ .map(item => item._attributes?.Term)
43
+ .some(term => this.interchangableTerms.includes(term));
44
+ }
45
+ // If one of the terms is missing, its values can be filled by others.
46
+ // Usually Heading or QuickInfo is missing. So we order terms by source
47
+ // priority (take from label first).
48
+ interchangableTerms = ["SAP__common.Label", "SAP__common.Heading", "SAP__common.QuickInfo"];
49
+ findByPriority(annotations, index) {
50
+ for (const interchangableTerm of this.interchangableTerms) {
51
+ for (const annotation of annotations) {
52
+ if (annotation._attributes?.Term === interchangableTerm &&
53
+ annotation !== annotations[index]) {
54
+ return annotation;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ //# sourceMappingURL=interchangableCase.js.map
@@ -0,0 +1,12 @@
1
+ export default class MetadataJsonReferenceUtil {
2
+ private json;
3
+ private aliases;
4
+ private namespaces;
5
+ constructor(json: any);
6
+ aliasToNamespace(target: string): string;
7
+ namespaceToAlias(target: string): string;
8
+ private convertReference;
9
+ private getAliases;
10
+ private getNamespaces;
11
+ private initReferences;
12
+ }
@@ -0,0 +1,48 @@
1
+ import MetadataJsonUtil from "./metadataJsonUtil.js";
2
+ export default class MetadataJsonReferenceUtil {
3
+ json;
4
+ aliases = null;
5
+ namespaces = null;
6
+ constructor(json) {
7
+ this.json = json;
8
+ }
9
+ aliasToNamespace(target) {
10
+ return this.convertReference(this.getAliases(), target);
11
+ }
12
+ namespaceToAlias(target) {
13
+ return this.convertReference(this.getNamespaces(), target);
14
+ }
15
+ convertReference(references, target) {
16
+ for (const alias of references.keys()) {
17
+ target = target.replaceAll(alias + ".", references.get(alias) + ".");
18
+ }
19
+ return target;
20
+ }
21
+ getAliases() {
22
+ this.initReferences();
23
+ return this.aliases;
24
+ }
25
+ getNamespaces() {
26
+ this.initReferences();
27
+ return this.namespaces;
28
+ }
29
+ initReferences() {
30
+ if (!this.aliases || !this.namespaces) {
31
+ const references = new Array();
32
+ for (const ref of MetadataJsonUtil.getReferences(this.json)) {
33
+ references.push(...ref.includes);
34
+ }
35
+ references.push(MetadataJsonUtil.getSchemaReference(this.json));
36
+ this.aliases = new Map();
37
+ this.namespaces = new Map();
38
+ for (const mapping of references) {
39
+ if (mapping.alias && mapping.namespace) {
40
+ const { alias, namespace } = mapping;
41
+ this.aliases.set(alias, namespace);
42
+ this.namespaces.set(namespace, alias);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ //# sourceMappingURL=metadataJsonReferenceUtil.js.map
@@ -0,0 +1,30 @@
1
+ export default class MetadataJsonUtil {
2
+ static mapAnnotationsPerTarget(json: any): Map<string, IJsonIndex>;
3
+ static getVersion(json: any): any;
4
+ static getAnnotations(json: any): any[];
5
+ static setAnnotations(json: any, annotations: any[]): void;
6
+ static getSchemaNode(json: any): any;
7
+ static getSchemaReference(json: any): MetadataInclude;
8
+ static getEdmx(json: any): any;
9
+ static getDataServices(json: any): any;
10
+ static getReferences(json: any): MetadataReference[];
11
+ static toArrayReadOnly(json: any): any[];
12
+ static toArrayTransform(json: any, property: string): void;
13
+ }
14
+ export declare class MetadataReference {
15
+ uri: string;
16
+ includes: MetadataInclude[];
17
+ constructor(referenceJson: any);
18
+ getAlias(namespace: string): string | undefined;
19
+ }
20
+ export declare class MetadataInclude {
21
+ namespace: string;
22
+ alias: string;
23
+ constructor(alias: string, namespace: string);
24
+ equals(other: MetadataInclude): boolean;
25
+ static fromJson(json: any): MetadataInclude;
26
+ }
27
+ export interface IJsonIndex {
28
+ json: any;
29
+ index: number;
30
+ }