@ui5/task-adaptation 1.0.23 → 1.1.1

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 (71) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/dist/annotationManager.d.ts +0 -3
  3. package/dist/annotationManager.js +8 -43
  4. package/dist/annotations/comparator/comparator.d.ts +47 -0
  5. package/dist/annotations/comparator/comparator.js +276 -0
  6. package/dist/annotations/comparator/diffCase.d.ts +4 -0
  7. package/dist/annotations/comparator/diffCase.js +3 -0
  8. package/dist/annotations/comparator/interchangableCase.d.ts +25 -0
  9. package/dist/annotations/comparator/interchangableCase.js +65 -0
  10. package/dist/annotations/converter/metadataJsonReferenceUtil.d.ts +12 -0
  11. package/dist/annotations/converter/metadataJsonReferenceUtil.js +50 -0
  12. package/dist/annotations/converter/metadataJsonUtil.d.ts +30 -0
  13. package/dist/annotations/converter/metadataJsonUtil.js +73 -0
  14. package/dist/annotations/converter/ui5JsonConverter.d.ts +21 -0
  15. package/dist/annotations/converter/ui5JsonConverter.js +253 -0
  16. package/dist/annotations/converter/ui5MetadataJsonUtil.d.ts +3 -0
  17. package/dist/annotations/converter/ui5MetadataJsonUtil.js +13 -0
  18. package/dist/annotations/converter/ui5XmlConverter.d.ts +5 -0
  19. package/dist/annotations/converter/ui5XmlConverter.js +17 -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 +13 -0
  23. package/dist/annotations/dataSource/dataSourceManager.js +50 -0
  24. package/dist/annotations/dataSource/dataSourceOData.d.ts +17 -0
  25. package/dist/annotations/dataSource/dataSourceOData.js +47 -0
  26. package/dist/annotations/dataSource/dataSourceODataAnnotation.d.ts +6 -0
  27. package/dist/annotations/dataSource/dataSourceODataAnnotation.js +18 -0
  28. package/dist/annotations/serviceRequestor.d.ts +1 -9
  29. package/dist/annotations/serviceRequestor.js +8 -4
  30. package/dist/annotations/transformers/convertV2ToV4.d.ts +4 -0
  31. package/dist/annotations/transformers/convertV2ToV4.js +16 -0
  32. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.d.ts +6 -0
  33. package/dist/annotations/transformers/makeAnnotationNamespaceUnique.js +44 -0
  34. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.d.ts +4 -0
  35. package/dist/annotations/transformers/removeAllSchemaNodesExceptAnnotations.js +17 -0
  36. package/dist/annotations/transformers/transformer.d.ts +12 -0
  37. package/dist/annotations/transformers/transformer.js +3 -0
  38. package/dist/annotations/transformers/traverseReferences.d.ts +10 -0
  39. package/dist/annotations/transformers/traverseReferences.js +75 -0
  40. package/dist/appVariantManager.d.ts +4 -9
  41. package/dist/appVariantManager.js +45 -37
  42. package/dist/baseAppManager.d.ts +3 -1
  43. package/dist/baseAppManager.js +36 -24
  44. package/dist/bundle-odata.js +5498 -0
  45. package/dist/bundle.js +1786 -13
  46. package/dist/i18nManager.d.ts +5 -7
  47. package/dist/i18nManager.js +29 -32
  48. package/dist/index.js +4 -3
  49. package/dist/model/annotationDiffStructureError.js +2 -0
  50. package/dist/model/language.js +1 -1
  51. package/dist/model/types.d.ts +13 -2
  52. package/dist/util/commonUtil.d.ts +7 -0
  53. package/dist/util/commonUtil.js +72 -18
  54. package/dist/util/i18nMerger.d.ts +1 -1
  55. package/dist/util/i18nMerger.js +3 -4
  56. package/dist/util/resourceUtil.d.ts +3 -0
  57. package/dist/util/resourceUtil.js +13 -0
  58. package/package.json +5 -4
  59. package/scripts/bundler.ts +4 -33
  60. package/scripts/metadataDownloadHelper.ts +7 -5
  61. package/scripts/rollup/bundleDefinition-odata.js +9 -0
  62. package/scripts/rollup/overrides/sap/ui/performance/Measurement.js +4 -0
  63. package/scripts/rollup/ui5Resolve.ts +34 -5
  64. package/scripts/rollup.ts +12 -3
  65. package/dist/annotations/oDataModel.d.ts +0 -20
  66. package/dist/annotations/oDataModel.js +0 -46
  67. package/dist/annotations/oDataV2Model.d.ts +0 -4
  68. package/dist/annotations/oDataV2Model.js +0 -13
  69. package/dist/util/jsonDiffUtil.d.ts +0 -28
  70. package/dist/util/jsonDiffUtil.js +0 -74
  71. package/scripts/rollup/overrides/sap/ui/thirdparty/URI.js +0 -16
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const annotationsCacheManager_1 = require("../cache/annotationsCacheManager");
4
+ const commonUtil_1 = require("../util/commonUtil");
4
5
  const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::ServiceRequestor");
5
6
  class ServiceRequestor {
6
7
  constructor(configuration, abapRepoManager) {
@@ -8,12 +9,13 @@ class ServiceRequestor {
8
9
  this.configuration = configuration;
9
10
  }
10
11
  async downloadAnnotation(uri, name, language) {
12
+ let cacheName = name;
11
13
  if (language.sap) {
12
14
  uri += `?sap-language=${language.sap}`;
13
- name += `-${language.sap}`;
15
+ cacheName += `-${language.sap}`;
14
16
  }
15
- const cacheManager = new annotationsCacheManager_1.default(this.configuration, name);
16
- log.verbose(`Getting annotation '${name}' ${language.sap} by '${uri}'`);
17
+ const cacheManager = new annotationsCacheManager_1.default(this.configuration, cacheName);
18
+ log.verbose(`Getting annotation '${cacheName}' ${language} by '${uri}'`);
17
19
  try {
18
20
  let files;
19
21
  if (this.configuration.enableAnnotationCache) {
@@ -25,7 +27,9 @@ class ServiceRequestor {
25
27
  if (!files || files.size === 0) {
26
28
  throw new Error(`No files were fetched for '${name}' by '${uri}'`);
27
29
  }
28
- return { language, xml: [...files][0][1] };
30
+ const xml = [...files][0][1];
31
+ (0, commonUtil_1.writeTempAnnotations)(this.configuration, name, language, xml);
32
+ return xml;
29
33
  }
30
34
  catch (error) {
31
35
  throw new Error(`Failed to fetch annotation by '${uri}': ${error.message}`);
@@ -0,0 +1,4 @@
1
+ import Transformer, { TransformerInput } from "./transformer";
2
+ export default class ConvertV2ToV4 implements Transformer {
3
+ transform({ json, xml }: TransformerInput): any;
4
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const metadataJsonUtil_1 = require("../converter/metadataJsonUtil");
4
+ const ui5JsonConverter_1 = require("../converter/ui5JsonConverter");
5
+ const ui5XmlConverter_1 = require("../converter/ui5XmlConverter");
6
+ class ConvertV2ToV4 {
7
+ transform({ json, xml }) {
8
+ if (metadataJsonUtil_1.default.getVersion(json) !== "4.0") {
9
+ const annotationsV4 = ui5JsonConverter_1.default.convertAnnotations(ui5XmlConverter_1.default.convertV2(xml));
10
+ metadataJsonUtil_1.default.setAnnotations(json, annotationsV4);
11
+ }
12
+ return json;
13
+ }
14
+ }
15
+ exports.default = ConvertV2ToV4;
16
+ //# sourceMappingURL=convertV2ToV4.js.map
@@ -0,0 +1,6 @@
1
+ import Transformer, { TransformerInput } from "./transformer";
2
+ export default class MakeAnnotationNamespaceUnique implements Transformer {
3
+ transform({ json, uri }: TransformerInput): any;
4
+ private createReference;
5
+ private getReferences;
6
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const metadataJsonUtil_1 = require("../converter/metadataJsonUtil");
4
+ const crc16_1 = require("crc/crc16");
5
+ class MakeAnnotationNamespaceUnique {
6
+ transform({ json, uri }) {
7
+ const uniquePart = (0, crc16_1.default)(uri).toString(16);
8
+ // First add current schema as reference
9
+ const schema = metadataJsonUtil_1.default.getSchemaNode(json);
10
+ const references = this.getReferences(json);
11
+ references.push(this.createReference(schema, uri));
12
+ // Then rename the namespace/alias
13
+ schema._attributes.Namespace += "." + uniquePart;
14
+ delete schema._attributes["Alias"];
15
+ return json;
16
+ }
17
+ createReference(schema, uri) {
18
+ const attributes = {
19
+ Namespace: schema._attributes.Namespace
20
+ };
21
+ if (schema._attributes.Alias) {
22
+ attributes.Alias = schema._attributes.Alias;
23
+ }
24
+ ;
25
+ return {
26
+ _attributes: {
27
+ Uri: uri
28
+ },
29
+ "edmx:Include": {
30
+ _attributes: attributes
31
+ }
32
+ };
33
+ }
34
+ getReferences(json) {
35
+ const REFERENCE_NODE_NAME = "edmx:Reference";
36
+ const references = metadataJsonUtil_1.default.getEdmx(json)[REFERENCE_NODE_NAME];
37
+ if (!Array.isArray(references)) {
38
+ metadataJsonUtil_1.default.getEdmx(json)[REFERENCE_NODE_NAME] = [references];
39
+ }
40
+ return metadataJsonUtil_1.default.getEdmx(json)[REFERENCE_NODE_NAME];
41
+ }
42
+ }
43
+ exports.default = MakeAnnotationNamespaceUnique;
44
+ //# sourceMappingURL=makeAnnotationNamespaceUnique.js.map
@@ -0,0 +1,4 @@
1
+ import Transformer, { TransformerInput } from "./transformer";
2
+ export default class RemoveAllSchemaNodesExceptAnnotations implements Transformer {
3
+ transform({ json }: TransformerInput): any;
4
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const metadataJsonUtil_1 = require("../converter/metadataJsonUtil");
4
+ class RemoveAllSchemaNodesExceptAnnotations {
5
+ transform({ json }) {
6
+ const schema = metadataJsonUtil_1.default.getSchemaNode(json);
7
+ for (const key of Object.keys(schema)) {
8
+ if (key !== "_attributes" && key !== "Annotations") {
9
+ delete schema[key];
10
+ }
11
+ }
12
+ return json;
13
+ // TODO: remove also references not used in annotations
14
+ }
15
+ }
16
+ exports.default = RemoveAllSchemaNodesExceptAnnotations;
17
+ //# sourceMappingURL=removeAllSchemaNodesExceptAnnotations.js.map
@@ -0,0 +1,12 @@
1
+ import Language from "../../model/language";
2
+ import ServiceRequestor from "../serviceRequestor";
3
+ export interface TransformerInput {
4
+ uri: string;
5
+ json: any;
6
+ xml: string;
7
+ language: Language;
8
+ serviceRequestor: ServiceRequestor;
9
+ }
10
+ export default interface Transformer {
11
+ transform(input: TransformerInput): any;
12
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=transformer.js.map
@@ -0,0 +1,10 @@
1
+ import Transformer, { TransformerInput } from "../transformers/transformer";
2
+ export default class TraverseReferences implements Transformer {
3
+ private metadataUrl?;
4
+ constructor(metadataUrl?: string);
5
+ transform({ json, language, serviceRequestor, uri: parentUrl }: TransformerInput): Promise<void>;
6
+ private isReferenceToMetadata;
7
+ static joinUrls(relativeUrl: string, parentUrl: string): any;
8
+ private mergeAnnotations;
9
+ private static isTraversable;
10
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const metadataJsonUtil_1 = require("../converter/metadataJsonUtil");
4
+ const dataSourceODataAnnotation_1 = require("../dataSource/dataSourceODataAnnotation");
5
+ const { URI } = require("../../../dist/bundle-odata");
6
+ class TraverseReferences {
7
+ constructor(metadataUrl) {
8
+ this.metadataUrl = metadataUrl;
9
+ }
10
+ async transform({ json, language, serviceRequestor, uri: parentUrl }) {
11
+ const references = metadataJsonUtil_1.default.getReferences(json).filter(TraverseReferences.isTraversable);
12
+ const promises = [];
13
+ for (const { includes, uri: relativeUrl } of references) {
14
+ const absoluteUrl = TraverseReferences.joinUrls(relativeUrl, parentUrl);
15
+ if (this.isReferenceToMetadata(parentUrl, absoluteUrl, this.metadataUrl)) {
16
+ // If ODataAnnotation has reference to metadata, don't traverse
17
+ continue;
18
+ }
19
+ const name = includes[0]?.namespace;
20
+ const dataSource = new dataSourceODataAnnotation_1.default(name, absoluteUrl, {}, this.metadataUrl);
21
+ promises.push(dataSource.downloadAnnotation(language, serviceRequestor)
22
+ .then(childAnnotation => ({ name, childAnnotation })));
23
+ }
24
+ const childAnnotations = await Promise.all(promises);
25
+ for (const { childAnnotation } of childAnnotations) {
26
+ this.mergeAnnotations(json, childAnnotation);
27
+ }
28
+ return json;
29
+ }
30
+ isReferenceToMetadata(parentUrl, absoluteUrl, metadataUrl) {
31
+ const isEqual = (a, b) => a && b && a.toLowerCase() === b.toLowerCase();
32
+ return isEqual(parentUrl, metadataUrl) || isEqual(absoluteUrl, metadataUrl);
33
+ }
34
+ static joinUrls(relativeUrl, parentUrl) {
35
+ // Remove trailing slash, otherwise url join can be incorrect Remove
36
+ // trailing slash, otherwise url join can be incorrect Annotation URLs
37
+ // defined in manifest might end with .../$value/ or .../$value and both
38
+ // are accepted by Gateway and produce the same content with same
39
+ // relative URLs. The first case is actually incorrect and we have to
40
+ // sanitize the same way as UI5.
41
+ return new URI(relativeUrl).absoluteTo(parentUrl.replace(/\/$/, "")).toString();
42
+ }
43
+ mergeAnnotations(parentJson, nestedJson) {
44
+ const parentAnnotations = metadataJsonUtil_1.default.getAnnotations(parentJson);
45
+ const parentMapByTarget = metadataJsonUtil_1.default.mapAnnotationsPerTarget(parentJson);
46
+ const nestedMapByTarget = metadataJsonUtil_1.default.mapAnnotationsPerTarget(nestedJson);
47
+ for (const nested of [...nestedMapByTarget].map(([target, { json }]) => ({ target, json }))) {
48
+ // If we found parent annotation with the same target - we extend it
49
+ // with missing <Annotation> nodes. If not, just add it to the end.
50
+ // Annotations do not have a merge logic If same target & term is in
51
+ // parent and nested, parent wins (same logic as UI5 in
52
+ // sap/ui/model/odata/v4/ODataMetaModel.js mergeAnnotations).
53
+ const parent = parentMapByTarget.get(nested.target);
54
+ if (parent) {
55
+ metadataJsonUtil_1.default.toArrayTransform(parent.json, "Annotation");
56
+ const parentTerms = parent.json.Annotation.map((item) => item._attributes.Term);
57
+ for (const nestedAnnotation of metadataJsonUtil_1.default.toArrayReadOnly(nested.json.Annotation)) {
58
+ if (!parentTerms.includes(nestedAnnotation._attributes.Term)) {
59
+ parent.json.Annotation.push(nestedAnnotation);
60
+ }
61
+ }
62
+ }
63
+ else {
64
+ parentAnnotations.push(nested.json);
65
+ }
66
+ }
67
+ metadataJsonUtil_1.default.setAnnotations(parentJson, parentAnnotations);
68
+ }
69
+ static isTraversable(reference) {
70
+ const IGNORED_NAMESPACES = ["com.sap.vocabularies.", "Org.OData."];
71
+ return !reference.includes.some(include => IGNORED_NAMESPACES.some(namespace => include.namespace.startsWith(namespace)));
72
+ }
73
+ }
74
+ exports.default = TraverseReferences;
75
+ //# sourceMappingURL=traverseReferences.js.map
@@ -1,17 +1,12 @@
1
1
  import { IAppVariantInfo } from "./model/types";
2
2
  export default class AppVariantManager {
3
3
  static process(appVariantResources: any[], projectNamespace: string, taskUtil: any): Promise<IAppVariantInfo>;
4
- static getAppVariantResources(workspace: any): Promise<any[]>;
5
- static renameChanges(appVariantResources: any[], projectNamespace: string, appVariantInfo: IAppVariantInfo): Promise<void>;
4
+ static getAppVariantResourcesToProcess(workspace: any): Promise<any[]>;
5
+ static updateChanges(appVariantResources: any[], projectNamespace: string): Promise<void>;
6
6
  private static isManifestChange;
7
7
  private static isManifestAppVariant;
8
8
  static getAppVariantInfo(appVariantResources: any[]): Promise<IAppVariantInfo>;
9
+ private static validateManifest;
10
+ private static updateRelativePaths;
9
11
  private static omitFiles;
10
- /**
11
- * We need to add texts properties to changes because not all have texts property.
12
- * Changes without texts property can causes issues in bundle.js
13
- * This is needed for now, and will be removed as soon as change merger in openUI5 is updated
14
- * @param changes
15
- */
16
- private static patchMissingTextsNode;
17
12
  }
@@ -1,28 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const commonUtil_1 = require("./util/commonUtil");
4
3
  const resourceUtil_1 = require("./util/resourceUtil");
5
4
  const path_1 = require("path");
6
- const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::AppVariantManager");
7
- const EXTENSIONS = "js,json,xml,html,properties,change,appdescr_variant";
5
+ const commonUtil_1 = require("./util/commonUtil");
6
+ const EXTENSIONS_TO_PROCESS = "js,json,xml,html,properties,change,appdescr_variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change,variant,fioriversion,codeChange,xmlViewChange,context";
8
7
  class AppVariantManager {
9
8
  static async process(appVariantResources, projectNamespace, taskUtil) {
10
- const appVariantInfo = await this.getAppVariantInfo(appVariantResources);
11
9
  for (const resource of appVariantResources) {
12
10
  this.omitFiles(resource, taskUtil);
13
11
  }
14
- this.patchMissingTextsNode(appVariantInfo?.manifest?.content ?? []);
15
- await this.renameChanges(appVariantResources, projectNamespace, appVariantInfo);
16
- return appVariantInfo;
12
+ await this.updateChanges(appVariantResources, projectNamespace);
13
+ return this.getAppVariantInfo(appVariantResources);
17
14
  }
18
- static getAppVariantResources(workspace) {
19
- return workspace.byGlob(`/**/*.{${EXTENSIONS}}`);
15
+ static getAppVariantResourcesToProcess(workspace) {
16
+ return workspace.byGlob(`/**/*.{${EXTENSIONS_TO_PROCESS}}`);
20
17
  }
21
- static async renameChanges(appVariantResources, projectNamespace, appVariantInfo) {
18
+ static async updateChanges(appVariantResources, projectNamespace) {
22
19
  const changesFolder = resourceUtil_1.default.getResourcePath(projectNamespace, "changes");
23
20
  const changes = new Map();
24
21
  const resourcesByPath = new Map();
22
+ let manifest;
25
23
  for (const resource of appVariantResources) {
24
+ if (this.isManifestAppVariant(resource)) {
25
+ manifest = await resourceUtil_1.default.getJson(resource);
26
+ }
26
27
  const resourcePath = resource.getPath();
27
28
  const basename = path_1.posix.dirname(resourcePath);
28
29
  if (basename.startsWith(changesFolder)) {
@@ -30,7 +31,9 @@ class AppVariantManager {
30
31
  resourcesByPath.set(resourcePath, resource);
31
32
  }
32
33
  }
33
- const renamedChanges = (0, commonUtil_1.renameResources)(changes, appVariantInfo.reference, appVariantInfo.id);
34
+ this.updateRelativePaths(changes, projectNamespace);
35
+ this.validateManifest(manifest);
36
+ const renamedChanges = (0, commonUtil_1.renameResources)(changes, manifest.reference, manifest.id);
34
37
  renamedChanges.forEach((renamedContent, resourcePath) => {
35
38
  const resource = resourcesByPath.get(resourcePath);
36
39
  resourceUtil_1.default.setString(resource, renamedContent);
@@ -38,7 +41,8 @@ class AppVariantManager {
38
41
  }
39
42
  static isManifestChange(resource) {
40
43
  const changesManifestFolder = path_1.posix.join("changes", "manifest");
41
- const dirname = path_1.posix.dirname(resource.getPath());
44
+ const resourcePath = typeof resource === "string" ? resource : resource.getPath();
45
+ const dirname = path_1.posix.dirname(resourcePath);
42
46
  return dirname.endsWith(changesManifestFolder);
43
47
  }
44
48
  static isManifestAppVariant(resource) {
@@ -51,42 +55,46 @@ class AppVariantManager {
51
55
  const manifestChanges = [];
52
56
  for (const resource of appVariantResources) {
53
57
  if (this.isManifestAppVariant(resource)) {
54
- manifest = await resourceUtil_1.default.getString(resource).then(JSON.parse);
58
+ manifest = await resourceUtil_1.default.getJson(resource);
55
59
  }
56
60
  else if (this.isManifestChange(resource)) {
57
61
  const content = await resourceUtil_1.default.getString(resource);
58
62
  manifestChanges.push(JSON.parse(content));
59
63
  }
60
64
  }
61
- if (manifest) {
62
- return {
63
- id: manifest.id,
64
- reference: manifest.reference,
65
- manifest,
66
- manifestChanges
67
- };
68
- }
69
- throw new Error("Adaptation project should contain manifest.appdescr_variant");
65
+ this.validateManifest(manifest);
66
+ return {
67
+ id: manifest.id,
68
+ reference: manifest.reference,
69
+ layer: manifest.layer,
70
+ changes: manifestChanges.concat(manifest.content)
71
+ };
70
72
  }
71
- static omitFiles(resource, taskUtil) {
72
- if (this.isManifestAppVariant(resource) || this.isManifestChange(resource)) {
73
- taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
73
+ static validateManifest(manifest) {
74
+ if (!manifest) {
75
+ throw new Error("Adaptation project should contain manifest.appdescr_variant");
74
76
  }
75
77
  }
76
- /**
77
- * We need to add texts properties to changes because not all have texts property.
78
- * Changes without texts property can causes issues in bundle.js
79
- * This is needed for now, and will be removed as soon as change merger in openUI5 is updated
80
- * @param changes
81
- */
82
- static patchMissingTextsNode(changes) {
83
- log.verbose("Adjusting appdescr_ui5_addNewModelEnhanceWith with module");
84
- for (const change of changes) {
85
- if (change.changeType === "appdescr_ui5_addNewModelEnhanceWith") {
86
- if (!change.texts && change.content?.bundleUrl) {
87
- change.texts = { i18n: change.content.bundleUrl };
78
+ // TODO In future this should be handled by merger which needs to know change and target location
79
+ static updateRelativePaths(changes, projectNamespace) {
80
+ changes.forEach((jsonString, resourcePath) => {
81
+ if (this.isManifestChange(resourcePath)) {
82
+ const change = JSON.parse(jsonString);
83
+ if (change.changeType === "appdescr_app_addAnnotationsToOData") {
84
+ for (const dataSource of Object.values(change.content.dataSource)) {
85
+ if (!dataSource.uri.startsWith("/")) {
86
+ const basepath = path_1.posix.dirname(resourceUtil_1.default.relativeToRoot(resourcePath, projectNamespace));
87
+ dataSource.uri = path_1.posix.join(basepath.replace(/^\//, ""), dataSource.uri);
88
+ }
89
+ }
90
+ changes.set(resourcePath, JSON.stringify(change));
88
91
  }
89
92
  }
93
+ });
94
+ }
95
+ static omitFiles(resource, taskUtil) {
96
+ if (this.isManifestAppVariant(resource) || this.isManifestChange(resource)) {
97
+ taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
90
98
  }
91
99
  }
92
100
  }
@@ -21,7 +21,9 @@ export default class BaseAppManager {
21
21
  private static extractI18NFromBundleUrl;
22
22
  private static getBaseAppManifest;
23
23
  private static fillAppVariantIdHierarchy;
24
+ private static VALIDATION_RULES;
24
25
  static validateProperty(value: string, property: string): void;
25
- static applyDescriptorChanges(baseAppManifest: any, appVariantInfo: IAppVariantInfo): Promise<void>;
26
+ static applyDescriptorChanges(baseAppManifest: any, { layer, changes, id }: IAppVariantInfo): Promise<void>;
27
+ private static adjustAddNewModelEnhanceWith;
26
28
  static writeToWorkspace(baseAppFiles: Map<string, string>, projectNamespace: string): any[];
27
29
  }
@@ -3,16 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const commonUtil_1 = require("./util/commonUtil");
4
4
  const buildStrategy_1 = require("./buildStrategy");
5
5
  const resourceUtil_1 = require("./util/resourceUtil");
6
- const path_1 = require("path");
7
6
  const commonUtil_2 = require("./util/commonUtil");
8
7
  const { RegistrationBuild, Applier, Change } = require("../dist/bundle");
9
- const resourceFactory = require("@ui5/fs/lib/resourceFactory");
10
8
  const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::BaseAppManager");
11
9
  class BaseAppManager {
12
10
  static async process(baseAppFiles, appVariantInfo, options, processor) {
13
11
  const baseAppManifest = this.getBaseAppManifest(baseAppFiles);
14
12
  const { id, version } = this.getIdVersion(baseAppManifest.content);
15
- const renamedBaseAppFiles = (0, commonUtil_1.renameResources)(baseAppFiles, appVariantInfo.reference, appVariantInfo.id);
13
+ this.validateProperty(id, "sap.app/id");
14
+ this.validateProperty(version, "sap.app/applicationVersion/version");
15
+ const renamedBaseAppFiles = (0, commonUtil_2.renameResources)(baseAppFiles, appVariantInfo.reference, appVariantInfo.id);
16
16
  const { filepath, content } = this.getBaseAppManifest(renamedBaseAppFiles);
17
17
  await processor.updateLandscapeSpecificContent(content, renamedBaseAppFiles);
18
18
  this.fillAppVariantIdHierarchy(processor, id, version, content);
@@ -56,7 +56,7 @@ class BaseAppManager {
56
56
  return i18nNode["bundleName"].replace(sapAppId, "").replaceAll(".", "/").substring(1);
57
57
  }
58
58
  static extractI18NFromBundleUrl(i18nNode) {
59
- return (0, commonUtil_2.removePropertiesExtension)(i18nNode["bundleUrl"]);
59
+ return (0, commonUtil_1.removePropertiesExtension)(i18nNode["bundleUrl"]);
60
60
  }
61
61
  static getBaseAppManifest(baseAppFiles) {
62
62
  let filepath = [...baseAppFiles.keys()].find(filepath => filepath.endsWith("manifest.json"));
@@ -70,8 +70,6 @@ class BaseAppManager {
70
70
  }
71
71
  static fillAppVariantIdHierarchy(processor, id, version, baseAppManifest) {
72
72
  log.verbose("Filling up app variant hierarchy in manifest.json");
73
- this.validateProperty(id, "sap.app/id");
74
- this.validateProperty(version, "sap.app/applicationVersion/version");
75
73
  if (baseAppManifest["sap.ui5"] == null) {
76
74
  baseAppManifest["sap.ui5"] = {};
77
75
  }
@@ -85,23 +83,39 @@ class BaseAppManager {
85
83
  if (!value) {
86
84
  throw new Error(`Original application manifest should have ${property}`);
87
85
  }
86
+ let validatationRule = this.VALIDATION_RULES.get(property);
87
+ if (validatationRule) {
88
+ validatationRule(value);
89
+ }
88
90
  }
89
- static async applyDescriptorChanges(baseAppManifest, appVariantInfo) {
91
+ static async applyDescriptorChanges(baseAppManifest, { layer, changes, id }) {
90
92
  log.verbose("Applying appVariant changes");
91
- const strategy = new buildStrategy_1.default(RegistrationBuild);
92
- const { manifest } = appVariantInfo;
93
- const allChanges = [
94
- ...manifest.content,
95
- ...appVariantInfo.manifestChanges
96
- ];
97
- if (manifest.layer) {
98
- allChanges.forEach(item => item.layer = manifest.layer);
93
+ const changesContent = new Array();
94
+ const i18nBundleName = (0, commonUtil_1.dotToUnderscore)(id);
95
+ for (const change of structuredClone(changes)) {
96
+ if (layer) {
97
+ change.layer = layer;
98
+ }
99
+ changesContent.push(new Change(change));
100
+ this.adjustAddNewModelEnhanceWith(change, i18nBundleName);
99
101
  }
100
- const changesContent = allChanges.map(change => new Change(change));
101
102
  if (changesContent.length > 0) {
103
+ const strategy = new buildStrategy_1.default(RegistrationBuild);
102
104
  await Applier.applyChanges(baseAppManifest, changesContent, strategy);
103
105
  }
104
106
  }
107
+ static adjustAddNewModelEnhanceWith(change, i18nBundleName) {
108
+ if (change.changeType === "appdescr_ui5_addNewModelEnhanceWith") {
109
+ if (change.texts == null) {
110
+ // We need to add texts properties to changes because not all
111
+ // have texts property. Changes without texts property can
112
+ // causes issues in bundle.js This is needed for now, and will
113
+ // be removed as soon as change merger in openUI5 is updated
114
+ change.texts = { i18n: change.content?.bundleUrl || "i18n/i18n.properties" };
115
+ }
116
+ change.texts.i18n = i18nBundleName + "/" + change.texts.i18n;
117
+ }
118
+ }
105
119
  static writeToWorkspace(baseAppFiles, projectNamespace) {
106
120
  const IGNORE_FILES = [
107
121
  "/manifest-bundle.zip",
@@ -111,10 +125,7 @@ class BaseAppManager {
111
125
  const resources = [];
112
126
  for (let filename of baseAppFiles.keys()) {
113
127
  if (!IGNORE_FILES.includes(filename)) {
114
- const resource = resourceFactory.createResource({
115
- path: getPath(filename, projectNamespace),
116
- string: baseAppFiles.get(filename)
117
- });
128
+ const resource = resourceUtil_1.default.createResource(filename, projectNamespace, baseAppFiles.get(filename));
118
129
  resources.push(resource);
119
130
  }
120
131
  }
@@ -122,8 +133,9 @@ class BaseAppManager {
122
133
  }
123
134
  }
124
135
  exports.default = BaseAppManager;
125
- const getPath = (filename, projectNamespace) => {
126
- const rootFolder = resourceUtil_1.default.getRootFolder(projectNamespace);
127
- return path_1.posix.join(rootFolder, filename);
128
- };
136
+ BaseAppManager.VALIDATION_RULES = new Map([["sap.app/id", (value) => {
137
+ if (!value.includes(".")) {
138
+ throw new Error(`The original application id '${value}' should consist of multiple segments split by dot, e.g.: original.id`);
139
+ }
140
+ }]]);
129
141
  //# sourceMappingURL=baseAppManager.js.map