@ui5/task-adaptation 1.6.4-rc.3 → 1.6.4

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 (51) hide show
  1. package/CHANGELOG.md +6 -45
  2. package/README.md +1 -0
  3. package/dist/adapters/abapAdapter.d.ts +4 -2
  4. package/dist/adapters/abapAdapter.js +4 -2
  5. package/dist/adapters/commands/downloadAnnotationsCommand.d.ts +4 -2
  6. package/dist/adapters/commands/downloadAnnotationsCommand.js +6 -2
  7. package/dist/annotationManager.d.ts +17 -0
  8. package/dist/{annotations/abapAnnotationManager.js → annotationManager.js} +10 -12
  9. package/dist/annotations/serviceRequestor.d.ts +3 -3
  10. package/dist/annotations/serviceRequestor.js +4 -4
  11. package/dist/appVariantManager.js +5 -2
  12. package/dist/bundle.js +6 -6
  13. package/dist/index.js +6 -5
  14. package/dist/model/configuration.d.ts +0 -2
  15. package/dist/model/types.d.ts +1 -0
  16. package/dist/previewManager.d.ts +2 -2
  17. package/dist/previewManager.js +14 -8
  18. package/dist/processors/abapProcessor.d.ts +18 -0
  19. package/dist/processors/abapProcessor.js +43 -0
  20. package/dist/processors/cfProcessor.d.ts +14 -0
  21. package/dist/processors/cfProcessor.js +46 -0
  22. package/dist/processors/previewProcessor.d.ts +8 -0
  23. package/dist/processors/previewProcessor.js +11 -0
  24. package/dist/processors/processor.d.ts +10 -0
  25. package/dist/processors/processor.js +39 -0
  26. package/dist/repositories/{abapRepository.d.ts → abapRepoManager.d.ts} +3 -5
  27. package/dist/repositories/{abapRepository.js → abapRepoManager.js} +4 -17
  28. package/dist/repositories/html5RepoManager.d.ts +12 -0
  29. package/dist/repositories/{html5Repository.js → html5RepoManager.js} +27 -58
  30. package/dist/util/commonUtil.d.ts +0 -1
  31. package/dist/util/commonUtil.js +0 -3
  32. package/dist/util/filesUtil.d.ts +2 -0
  33. package/dist/util/filesUtil.js +7 -0
  34. package/dist/util/fsUtil.d.ts +0 -2
  35. package/dist/util/fsUtil.js +0 -34
  36. package/package.json +4 -7
  37. package/rollup/overrides/sap/ui/fl/apply/_internal/changes/descriptor/app/AddNewDataSource.js +157 -0
  38. package/dist/annotations/abapAnnotationManager.d.ts +0 -17
  39. package/dist/annotations/annotationManager.d.ts +0 -3
  40. package/dist/annotations/annotationManager.js +0 -2
  41. package/dist/annotations/localAnnotationManager.d.ts +0 -4
  42. package/dist/annotations/localAnnotationManager.js +0 -7
  43. package/dist/landscapeConfiguration.d.ts +0 -9
  44. package/dist/landscapeConfiguration.js +0 -65
  45. package/dist/repositories/html5Repository.d.ts +0 -18
  46. package/dist/repositories/localRepository.d.ts +0 -16
  47. package/dist/repositories/localRepository.js +0 -66
  48. package/dist/repositories/repository.d.ts +0 -8
  49. package/dist/repositories/repository.js +0 -2
  50. package/scripts/publish.ts +0 -256
  51. package/scripts/test-integration-prep.sh +0 -4
@@ -0,0 +1,39 @@
1
+ import AbapProcessor from "./abapProcessor.js";
2
+ import AbapRepoManager from "../repositories/abapRepoManager.js";
3
+ import AnnotationManager from "../annotationManager.js";
4
+ import CFProcessor from "./cfProcessor.js";
5
+ import PreviewProcessor from "./previewProcessor.js";
6
+ export function determineProcessor(configuration) {
7
+ const abapRepoManager = new AbapRepoManager(configuration);
8
+ const annotationManager = new AnnotationManager(configuration, abapRepoManager);
9
+ const processors = [
10
+ new CFProcessor(configuration),
11
+ new AbapProcessor(configuration, abapRepoManager, annotationManager)
12
+ ];
13
+ if (isPreviewMode()) {
14
+ const processor = new PreviewProcessor(configuration);
15
+ processor.validateConfiguration();
16
+ return processor;
17
+ }
18
+ let processor = processors.find(processor => processor.getConfigurationType() === configuration.type);
19
+ if (processor) {
20
+ processor.validateConfiguration();
21
+ return processor;
22
+ }
23
+ else {
24
+ for (const processor of processors) {
25
+ try {
26
+ processor.validateConfiguration();
27
+ return processor;
28
+ }
29
+ catch (_error) {
30
+ continue;
31
+ }
32
+ }
33
+ }
34
+ throw new Error("ui5.yaml configuration should correspond either ABAP or SAP BTP landscape");
35
+ }
36
+ function isPreviewMode() {
37
+ return process.env.ADP_BUILDER_MODE === "preview";
38
+ }
39
+ //# sourceMappingURL=processor.js.map
@@ -1,15 +1,13 @@
1
- import { IConfiguration, IMetadata, IReuseLibInfo } from "../model/types.js";
1
+ import { IConfiguration, IMetadata } from "../model/types.js";
2
2
  import AbapProvider from "./abapProvider.js";
3
3
  import { IAppVariantIdHierarchyItem } from "../model/appVariantIdHierarchyItem.js";
4
- import IRepository from "./repository.js";
5
- export default class AbapRepository implements IRepository {
4
+ export default class AbapRepoManager {
6
5
  private configuration;
7
6
  private abapProvider;
8
7
  constructor(configuration: IConfiguration, abapProvider?: AbapProvider);
9
- fetchReuseLib(_libName: string, _cachebusterToken: string, _lib: IReuseLibInfo): Promise<Map<string, string>>;
10
8
  getAppVariantIdHierarchy(id: string): Promise<IAppVariantIdHierarchyItem[]>;
11
9
  getAnnotationMetadata(uri: string): Promise<IMetadata>;
12
10
  downloadAnnotationFile(uri: string): Promise<Map<string, any>>;
13
11
  getMetadata(id: string): Promise<IMetadata>;
14
- fetch(repoName: string, _cachebusterToken: string): Promise<Map<string, string>>;
12
+ fetch(repoName: string): Promise<Map<string, string>>;
15
13
  }
@@ -1,14 +1,7 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
1
  import AbapProvider from "./abapProvider.js";
8
2
  import { getLogger } from "@ui5/logger";
9
3
  import { unzipZipEntries } from "../util/zipUtil.js";
10
- import { cached } from "../cache/cacheHolder.js";
11
- const log = getLogger("@ui5/task-adaptation::AbapRepository");
4
+ const log = getLogger("@ui5/task-adaptation::AbapRepoManager");
12
5
  const REQUEST_OPTIONS_XML = {
13
6
  responseType: "text",
14
7
  headers: {
@@ -20,16 +13,13 @@ const REQUEST_OPTIONS_JSON = {
20
13
  "Accept": "application/json"
21
14
  }
22
15
  };
23
- export default class AbapRepository {
16
+ export default class AbapRepoManager {
24
17
  configuration;
25
18
  abapProvider;
26
19
  constructor(configuration, abapProvider) {
27
20
  this.configuration = configuration;
28
21
  this.abapProvider = abapProvider ? abapProvider : new AbapProvider();
29
22
  }
30
- fetchReuseLib(_libName, _cachebusterToken, _lib) {
31
- throw new Error("Preview is not available on SAP S/4HANA On-Premise or Cloud Systems. Please create a ticket on CA-UI5-FL-ADP-BAS component.");
32
- }
33
23
  async getAppVariantIdHierarchy(id) {
34
24
  const provider = await this.abapProvider.get(this.configuration);
35
25
  const lrep = provider.getLayeredRepository();
@@ -78,7 +68,7 @@ export default class AbapRepository {
78
68
  id
79
69
  };
80
70
  }
81
- async fetch(repoName, _cachebusterToken) {
71
+ async fetch(repoName) {
82
72
  const encodedRepoName = encodeURIComponent(repoName);
83
73
  const provider = await this.abapProvider.get(this.configuration);
84
74
  const ui5Repo = provider.getUi5AbapRepository();
@@ -97,7 +87,4 @@ export default class AbapRepository {
97
87
  throw new Error(`App '${repoName}' doesn't contain files`);
98
88
  }
99
89
  }
100
- __decorate([
101
- cached()
102
- ], AbapRepository.prototype, "fetch", null);
103
- //# sourceMappingURL=abapRepository.js.map
90
+ //# sourceMappingURL=abapRepoManager.js.map
@@ -0,0 +1,12 @@
1
+ import { IConfiguration, IReuseLibInfo } from "./../model/types.js";
2
+ export default class HTML5RepoManager {
3
+ static getBaseAppFiles(configuration: IConfiguration): Promise<Map<string, string>>;
4
+ static getMetadata(configuration: IConfiguration): Promise<any>;
5
+ static getReuseLibFiles(configuration: IConfiguration, lib: IReuseLibInfo): Promise<Map<string, string>>;
6
+ private static getHtml5RepoInfo;
7
+ private static getHTML5Credentials;
8
+ private static getToken;
9
+ private static requestMetadata;
10
+ private static getAppZipEntries;
11
+ private static download;
12
+ }
@@ -1,41 +1,24 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import CFUtil from "../util/cfUtil.js";
8
- import RequestUtil from "../util/requestUtil.js";
1
+ import CFUtil from "./../util/cfUtil.js";
2
+ import RequestUtil from "./../util/requestUtil.js";
9
3
  import { getLogger } from "@ui5/logger";
10
- import { unzipZipEntries } from "../util/zipUtil.js";
11
- import { cached } from "../cache/cacheHolder.js";
12
- import { validateConfiguration } from "../util/commonUtil.js";
13
- const log = getLogger("@ui5/task-adaptation::HTML5Repository");
14
- export default class HTML5Repository {
15
- configuration;
16
- constructor(configuration) {
17
- this.configuration = configuration;
18
- validateConfiguration(configuration, ["appHostId", "appName", "appVersion"]);
19
- }
20
- async getAppVariantIdHierarchy(appId) {
21
- const metadata = await this.getMetadata();
22
- return [{
23
- repoName: this.configuration.appName,
24
- appVariantId: appId,
25
- cachebusterToken: metadata.changedOn
26
- }];
27
- }
28
- async fetch(_repoName, _cachebusterToken) {
29
- const { token, baseUri } = await this.getHtml5RepoInfo();
30
- const appData = {
31
- appName: this.configuration.appName,
32
- appVersion: this.configuration.appVersion,
33
- appHostId: this.configuration.appHostId
4
+ import { unzipZipEntries } from "./../util/zipUtil.js";
5
+ const log = getLogger("@ui5/task-adaptation::HTML5RepoManager");
6
+ export default class HTML5RepoManager {
7
+ static async getBaseAppFiles(configuration) {
8
+ const { token, baseUri } = await this.getHtml5RepoInfo(configuration);
9
+ const app = {
10
+ appName: configuration.appName,
11
+ appVersion: configuration.appVersion,
12
+ appHostId: configuration.appHostId
34
13
  };
35
- return this.getAppZipEntries(appData, baseUri, token);
14
+ return this.getAppZipEntries(app, baseUri, token);
15
+ }
16
+ static async getMetadata(configuration) {
17
+ const { token, baseUri } = await this.getHtml5RepoInfo(configuration);
18
+ return this.requestMetadata(configuration, baseUri, token);
36
19
  }
37
- async fetchReuseLib(_libName, _cachebusterToken, lib) {
38
- const { token, baseUri } = await this.getHtml5RepoInfo();
20
+ static async getReuseLibFiles(configuration, lib) {
21
+ const { token, baseUri } = await this.getHtml5RepoInfo(configuration);
39
22
  const libAppData = {
40
23
  appName: lib.html5AppName,
41
24
  appVersion: lib.html5AppVersion,
@@ -43,12 +26,8 @@ export default class HTML5Repository {
43
26
  };
44
27
  return this.getAppZipEntries(libAppData, baseUri, token);
45
28
  }
46
- async getMetadata() {
47
- const { token, baseUri } = await this.getHtml5RepoInfo();
48
- return this.requestMetadata(baseUri, token);
49
- }
50
- async getHtml5RepoInfo() {
51
- const spaceGuid = await CFUtil.getSpaceGuid(this.configuration?.space);
29
+ static async getHtml5RepoInfo(configuration) {
30
+ const spaceGuid = await CFUtil.getSpaceGuid(configuration?.space);
52
31
  const credentials = await this.getHTML5Credentials(spaceGuid);
53
32
  const token = await this.getToken(credentials);
54
33
  if (!token || token.length === 0) {
@@ -62,7 +41,7 @@ export default class HTML5Repository {
62
41
  baseUri: credentials.uri
63
42
  };
64
43
  }
65
- async getHTML5Credentials(spaceGuid) {
44
+ static async getHTML5Credentials(spaceGuid) {
66
45
  log.verbose("Getting HTML5 Repo Runtime credentials from space " + spaceGuid);
67
46
  const PLAN_NAME = "app-runtime";
68
47
  const SERVIСE_INSTANCE_NAME = "html5-apps-repo-runtime";
@@ -81,7 +60,7 @@ export default class HTML5Repository {
81
60
  const serviceKeys = await CFUtil.getServiceInstanceKeys(getParams, createParams);
82
61
  return serviceKeys.credentials;
83
62
  }
84
- async getToken({ uaa }) {
63
+ static async getToken({ uaa }) {
85
64
  log.verbose("Getting HTML5 Repo token");
86
65
  const auth = Buffer.from(uaa.clientid + ":" + uaa.clientsecret);
87
66
  const options = {
@@ -93,8 +72,8 @@ export default class HTML5Repository {
93
72
  const uri = `${uaa.url}/oauth/token?grant_type=client_credentials`;
94
73
  return RequestUtil.get(uri, options).then((json) => json["access_token"]);
95
74
  }
96
- async requestMetadata(html5RepoBaseUri, token) {
97
- const { appHostId, appName, appVersion } = this.configuration;
75
+ static async requestMetadata(options, html5RepoBaseUri, token) {
76
+ const { appHostId, appName, appVersion } = options;
98
77
  const uri = `${html5RepoBaseUri}/applications/metadata/`;
99
78
  const requestOptions = {
100
79
  headers: {
@@ -106,12 +85,12 @@ export default class HTML5Repository {
106
85
  const metadata = await RequestUtil.get(uri, requestOptions);
107
86
  return metadata.find((item) => item.appHostId === appHostId && item.applicationName === appName && item.applicationVersion === appVersion);
108
87
  }
109
- async getAppZipEntries(app, html5RepoBaseUri, token) {
88
+ static async getAppZipEntries(app, html5RepoBaseUri, token) {
110
89
  const uri = `${html5RepoBaseUri}/applications/content/${app.appName}-${app.appVersion}/`;
111
90
  const zip = await this.download(token, app.appHostId, uri);
112
91
  return unzipZipEntries(zip);
113
92
  }
114
- async download(token, appHostId, uri) {
93
+ static async download(token, appHostId, uri) {
115
94
  if (!token) {
116
95
  throw new Error("HTML5 token is undefined");
117
96
  }
@@ -124,15 +103,5 @@ export default class HTML5Repository {
124
103
  }
125
104
  });
126
105
  }
127
- downloadAnnotationFile(_uri) {
128
- log.verbose("No annotation processing in CF");
129
- return Promise.resolve(new Map());
130
- }
131
106
  }
132
- __decorate([
133
- cached()
134
- ], HTML5Repository.prototype, "fetch", null);
135
- __decorate([
136
- cached()
137
- ], HTML5Repository.prototype, "fetchReuseLib", null);
138
- //# sourceMappingURL=html5Repository.js.map
107
+ //# sourceMappingURL=html5RepoManager.js.map
@@ -1,7 +1,6 @@
1
1
  import { IConfiguration } from "../model/types.js";
2
2
  import Language from "../model/language.js";
3
3
  export declare function dotToUnderscore(value: string): string;
4
- export declare function validateConfiguration<T extends object>(options: T, properties: Array<keyof T>): void;
5
4
  export declare function validateObject<T extends object>(options: T, properties: Array<keyof T>, message: string): void;
6
5
  export declare function escapeRegex(update: string): string;
7
6
  export declare function insertInArray<T>(array: T[], index: number, insert: T): void;
@@ -9,9 +9,6 @@ const MANIFEST_CHANGE = "appdescr_";
9
9
  export function dotToUnderscore(value) {
10
10
  return value.replace(/\./g, "_");
11
11
  }
12
- export function validateConfiguration(options, properties) {
13
- validateObject(options, properties, "should be specified in ui5.yaml configuration");
14
- }
15
12
  export function validateObject(options, properties, message) {
16
13
  for (const property of properties) {
17
14
  if (!options[property]) {
@@ -1,5 +1,7 @@
1
+ import { IChange } from "../model/types.js";
1
2
  export default class FilesUtil {
2
3
  static filter(files: ReadonlyMap<string, string>): ReadonlyMap<string, string>;
4
+ static sortByTimeStamp(a: IChange, b: IChange): number;
3
5
  /**
4
6
  * 1p. i18n.properties are not renamed and property keys are ignored during
5
7
  * the renaming across the files.
@@ -23,6 +23,13 @@ export default class FilesUtil {
23
23
  });
24
24
  return result;
25
25
  }
26
+ static sortByTimeStamp(a, b) {
27
+ if (a.creation < b.creation)
28
+ return -1;
29
+ if (a.creation > b.creation)
30
+ return 1;
31
+ return 0;
32
+ }
26
33
  /**
27
34
  * 1p. i18n.properties are not renamed and property keys are ignored during
28
35
  * the renaming across the files.
@@ -6,6 +6,4 @@ export default class FsUtil {
6
6
  * @returns true if the path exists, false if not
7
7
  */
8
8
  private static fileExists;
9
- static readFilesRecursively(rootDirectory: string): Promise<Map<string, string>>;
10
- static exists(filePath: string): Promise<boolean>;
11
9
  }
@@ -36,39 +36,5 @@ export default class FsUtil {
36
36
  throw e;
37
37
  }
38
38
  }
39
- static async readFilesRecursively(rootDirectory) {
40
- const directoriesToScan = [rootDirectory];
41
- const fileReadTasks = [];
42
- while (directoriesToScan.length > 0) {
43
- const currentDirectory = directoriesToScan.pop();
44
- if (!currentDirectory) {
45
- continue;
46
- }
47
- const entries = await fs.readdir(currentDirectory, { withFileTypes: true });
48
- for (const entry of entries) {
49
- const entryPath = path.join(currentDirectory, entry.name);
50
- if (entry.isDirectory()) {
51
- directoriesToScan.push(entryPath);
52
- }
53
- else if (entry.isFile()) {
54
- fileReadTasks.push((async () => {
55
- const relativeFilePath = path.relative(rootDirectory, entryPath);
56
- const content = await fs.readFile(entryPath, "utf-8");
57
- return [relativeFilePath, content];
58
- })());
59
- }
60
- }
61
- }
62
- return new Map(await Promise.all(fileReadTasks));
63
- }
64
- static async exists(filePath) {
65
- try {
66
- await fs.access(filePath);
67
- return true;
68
- }
69
- catch {
70
- return false;
71
- }
72
- }
73
39
  }
74
40
  //# sourceMappingURL=fsUtil.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/task-adaptation",
3
- "version": "1.6.4-rc.3",
3
+ "version": "1.6.4",
4
4
  "description": "Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -84,8 +84,8 @@
84
84
  "sinon": "^18.0.1",
85
85
  "source-map-support": "^0.5.19",
86
86
  "tsx": "^4.21.0",
87
- "typescript": "^5.9.3",
88
- "typescript-eslint": "^8.48.1",
87
+ "typescript": "^6.0.2",
88
+ "typescript-eslint": "^8.58.0",
89
89
  "yargs": "^17.7.2"
90
90
  },
91
91
  "c8": {
@@ -115,10 +115,7 @@
115
115
  "src/model/configuration.ts",
116
116
  "src/model/appVariantIdHierarchyItem.ts",
117
117
  "src/adapters/adapter.ts",
118
- "src/adapters/previewAdapter.ts",
119
- "src/repositories/repository.ts",
120
- "src/annotations/annotationManager.ts",
121
- "src/processors/processor.ts"
118
+ "src/adapters/previewAdapter.ts"
122
119
  ],
123
120
  "check-coverage": true,
124
121
  "statements": 85,
@@ -0,0 +1,157 @@
1
+ /*!
2
+ * ${copyright}
3
+ */
4
+
5
+ sap.ui.define([
6
+ "sap/ui/fl/util/DescriptorChangeCheck"
7
+ ], function(
8
+ DescriptorChangeCheck
9
+ ) {
10
+ "use strict";
11
+
12
+ const MANDATORY_PROPERTIES = ["uri"];
13
+ const SUPPORTED_PROPERTIES = [...MANDATORY_PROPERTIES, "type", "settings", "customType"];
14
+ const PROPERTIES_PATTERNS = {
15
+ type: "^(OData|ODataAnnotation|INA|XML|JSON|FHIR|WebSocket|http)$",
16
+ customType: "^false$"
17
+ };
18
+ const SUPPORTED_TYPES = {
19
+ uri: "string",
20
+ type: "string",
21
+ settings: "object",
22
+ dataSourceCustom: "boolean",
23
+ annotations: "array"
24
+ };
25
+
26
+ function isDataSourceIdExistingInManifest(oManifestDataSources, sDataSourceId) {
27
+ return Object.keys(oManifestDataSources).includes(sDataSourceId);
28
+ }
29
+
30
+ function getDataSourceType(oDataSource) {
31
+ return oDataSource.type || "OData";
32
+ }
33
+
34
+ function getDataSourceNameByType(oChangeDataSource, sType) {
35
+ const [sDataSourceName] = Object.entries(oChangeDataSource).find(([, oDataSource]) => getDataSourceType(oDataSource) === sType) || [];
36
+ return sDataSourceName;
37
+ }
38
+
39
+ function checkDefinedAnnotationsExistInManifest(oManifestDataSources, sDataSourceOfTypeOData, aToBeCheckedInManifestAnnotations) {
40
+ aToBeCheckedInManifestAnnotations.forEach(function(sAnnotation) {
41
+ if (!isDataSourceIdExistingInManifest(oManifestDataSources, sAnnotation)) {
42
+ throw new Error(`Referenced annotation '${sAnnotation}' in the annotation array of data source '${sDataSourceOfTypeOData}' does not exist in the manifest.`);
43
+ }
44
+ });
45
+ }
46
+
47
+ function checksWhenAddingTwoDataSources(oManifestDataSources, oChangeDataSource) {
48
+ const sDataSourceOfTypeOData = getDataSourceNameByType(oChangeDataSource, "OData");
49
+ const sDataSourceOfTypeODataAnnotation = getDataSourceNameByType(oChangeDataSource, "ODataAnnotation");
50
+
51
+ if (!(sDataSourceOfTypeOData && sDataSourceOfTypeODataAnnotation)) {
52
+ throw new Error("When adding two data sources it is only allowed to add a data source with type 'OData' and the other one must be of type 'ODataAnnotation'.");
53
+ }
54
+
55
+ if (!oChangeDataSource[sDataSourceOfTypeOData]?.settings?.annotations?.includes(sDataSourceOfTypeODataAnnotation)) {
56
+ throw new Error(`Data source '${sDataSourceOfTypeOData}' does not include annotation '${sDataSourceOfTypeODataAnnotation}' under 'settings/annotations' array.`);
57
+ }
58
+
59
+ const aToBeCheckedInManifestAnnotations = oChangeDataSource[sDataSourceOfTypeOData].settings.annotations.filter(function(sAnnotation) {
60
+ return sAnnotation !== sDataSourceOfTypeODataAnnotation;
61
+ });
62
+ checkDefinedAnnotationsExistInManifest(oManifestDataSources, sDataSourceOfTypeOData, aToBeCheckedInManifestAnnotations);
63
+ }
64
+
65
+ function checksWhenAddingOneDataSource(oManifestDataSources, oChangeDataSource) {
66
+ const [sDataSourceName, oDataSource] = Object.entries(oChangeDataSource)[0];
67
+ if (oDataSource.settings?.annotations) {
68
+ checkDefinedAnnotationsExistInManifest(oManifestDataSources, sDataSourceName, oDataSource.settings.annotations);
69
+ }
70
+ }
71
+
72
+ function postChecks(oManifestDataSources, oChangeDataSource, aDataSources) {
73
+ aDataSources.forEach(function(sDataSource) {
74
+ if (isDataSourceIdExistingInManifest(oManifestDataSources, sDataSource)) {
75
+ throw new Error(`There is already a dataSource '${sDataSource}' existing in the manifest.`);
76
+ }
77
+
78
+ checkIfAnnotationsPropertyIsAnArray(oChangeDataSource, sDataSource);
79
+ });
80
+ if (aDataSources.length === 1) {
81
+ checksWhenAddingOneDataSource(oManifestDataSources, oChangeDataSource);
82
+ }
83
+ if (aDataSources.length === 2) {
84
+ checksWhenAddingTwoDataSources(oManifestDataSources, oChangeDataSource);
85
+ }
86
+ }
87
+
88
+ function checkIfAnnotationsPropertyIsAnArray(oChangeDataSource, sDataSource) {
89
+ const sDataSourceType = getDataSourceType(oChangeDataSource[sDataSource]);
90
+
91
+ if (oChangeDataSource[sDataSource].settings?.annotations) {
92
+ if (sDataSourceType !== "OData") {
93
+ throw new Error(`Data source '${sDataSource}' which is of type '${sDataSourceType}' contains the annotations array. Only data sources with type 'OData' could contain the 'settings/annotations' array.`);
94
+ }
95
+
96
+ if (!Array.isArray(oChangeDataSource[sDataSource].settings.annotations)) {
97
+ throw new Error("Property 'annotations' must be of type 'array'.");
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Descriptor change merger for change type <code>appdescr_app_addNewDataSource</code>.
104
+ * Adds a new data source to the manifest.json file under the path sap.app.dataSources.
105
+ *
106
+ * Available only for build {@link sap.ui.fl.apply._internal.changes.descriptor.RegistrationBuild}.
107
+ *
108
+ * @namespace
109
+ * @alias sap.ui.fl.apply._internal.changes.descriptor.app.AddNewDataSource
110
+ * @since 1.87
111
+ * @version ${version}
112
+ * @private
113
+ * @ui5-restricted sap.ui.fl.apply._internal
114
+ */
115
+ const AddNewDataSource = {
116
+
117
+ /**
118
+ * Applies the <code>appdescr_app_addNewDataSource</code> change to the manifest.
119
+ *
120
+ * @param {object} oManifest - Original manifest
121
+ * @param {sap.ui.fl.apply._internal.flexObjects.AppDescriptorChange} oChange - Change with type <code>appdescr_app_addNewDataSource</code>
122
+ * @param {object} oChange.content - Details of the change
123
+ * @param {object} oChange.content.dataSource - Data source of <code>sap.app/dataSource</code> that is being changed
124
+ * @returns {object} Updated manifest with changed <code>sap.app/dataSource</code>
125
+ *
126
+ * @private
127
+ * @ui5-restricted sap.ui.fl.apply._internal
128
+ */
129
+ applyChange(oManifest, oChange) {
130
+ oManifest["sap.app"].dataSources ||= {};
131
+ const oChangeContent = oChange.getContent();
132
+
133
+ const aDataSources = DescriptorChangeCheck.getAndCheckContentObject(oChangeContent, {
134
+ sKey: "dataSource",
135
+ sChangeType: oChange.getChangeType(),
136
+ iMaxNumberOfKeys: 2,
137
+ aMandatoryProperties: MANDATORY_PROPERTIES,
138
+ aSupportedProperties: SUPPORTED_PROPERTIES,
139
+ oSupportedPropertyPattern: PROPERTIES_PATTERNS,
140
+ oSupportedPropertyTypes: SUPPORTED_TYPES
141
+ });
142
+
143
+ aDataSources.forEach(function(sDataSource) {
144
+ DescriptorChangeCheck.checkIdNamespaceCompliance(sDataSource, oChange);
145
+ });
146
+
147
+ postChecks(oManifest["sap.app"].dataSources, oChangeContent.dataSource, aDataSources);
148
+
149
+ Object.assign(oManifest["sap.app"].dataSources, oChangeContent.dataSource);
150
+
151
+ return oManifest;
152
+ }
153
+
154
+ };
155
+
156
+ return AddNewDataSource;
157
+ });
@@ -1,17 +0,0 @@
1
- import { IConfiguration } from "../model/types.js";
2
- import IAnnotationManager from "./annotationManager.js";
3
- import IRepository from "../repositories/repository.js";
4
- export interface IAnnotationFiles {
5
- annotationName: string;
6
- annotationFileName: string;
7
- }
8
- export default class AbapAnnotationManager implements IAnnotationManager {
9
- private repository;
10
- private configuration;
11
- constructor(configuration: IConfiguration, repository: IRepository);
12
- ANNOTATIONS_FOLDER: string;
13
- process(baseAppManifest: any, appVariantId: string, prefix: string): Promise<Map<string, string>>;
14
- private updateManifestModel;
15
- private createManifestModel;
16
- private enhanceManifestModel;
17
- }
@@ -1,3 +0,0 @@
1
- export default interface IAnnotationManager {
2
- process(baseAppManifest: any, appVariantId: string, prefix: string): Promise<Map<string, string>>;
3
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=annotationManager.js.map
@@ -1,4 +0,0 @@
1
- import IAnnotationManager from "./annotationManager.js";
2
- export default class LocalAnnotationManager implements IAnnotationManager {
3
- process(_baseAppManifest: any, _appVariantId: string, _prefix: string): Promise<Map<string, string>>;
4
- }
@@ -1,7 +0,0 @@
1
- export default class LocalAnnotationManager {
2
- async process(_baseAppManifest, _appVariantId, _prefix) {
3
- // No annotation processing needed for local
4
- return new Map();
5
- }
6
- }
7
- //# sourceMappingURL=localAnnotationManager.js.map
@@ -1,9 +0,0 @@
1
- import { IConfiguration } from "./model/types.js";
2
- import { IAdapter } from "./adapters/adapter.js";
3
- import IRepository from "./repositories/repository.js";
4
- import IAnnotationManager from "./annotations/annotationManager.js";
5
- export declare function initialize(configuration: IConfiguration): {
6
- adapter: IAdapter;
7
- repository: IRepository;
8
- annotationManager: IAnnotationManager;
9
- };
@@ -1,65 +0,0 @@
1
- import AbapAdapter from "./adapters/abapAdapter.js";
2
- import CFAdapter from "./adapters/cfAdapter.js";
3
- import PreviewAdapter from "./adapters/previewAdapter.js";
4
- import AbapRepository from "./repositories/abapRepository.js";
5
- import HTML5Repository from "./repositories/html5Repository.js";
6
- import LocalRepository from "./repositories/localRepository.js";
7
- import AbapAnnotationManager from "./annotations/abapAnnotationManager.js";
8
- import LocalAnnotationManager from "./annotations/localAnnotationManager.js";
9
- import { validateObject } from "./util/commonUtil.js";
10
- export function initialize(configuration) {
11
- validateObject(configuration, ["type"], "should be specified in ui5.yaml configuration: 'cf' or 'abap'");
12
- const repository = getRepository(configuration);
13
- const annotationManager = getAnnotationManager(configuration, repository);
14
- return {
15
- adapter: getAdapter(configuration, annotationManager),
16
- repository,
17
- annotationManager
18
- };
19
- }
20
- function getAdapter(configuration, annotationManager) {
21
- if (isPreview(configuration)) {
22
- return new PreviewAdapter(configuration);
23
- }
24
- switch (configuration.type) {
25
- case "abap":
26
- return new AbapAdapter(annotationManager);
27
- case "cf":
28
- return new CFAdapter(configuration);
29
- default:
30
- throw new Error(`No adapter found for the given configuration type '${configuration.type}'`);
31
- }
32
- }
33
- function getRepository(configuration) {
34
- if (isLocal(configuration)) {
35
- return new LocalRepository(configuration);
36
- }
37
- switch (configuration.type) {
38
- case "abap":
39
- return new AbapRepository(configuration);
40
- case "cf":
41
- return new HTML5Repository(configuration);
42
- default:
43
- throw new Error(`No repository found for the given configuration type '${configuration.type}'`);
44
- }
45
- }
46
- function getAnnotationManager(configuration, repository) {
47
- if (isLocal(configuration)) {
48
- return new LocalAnnotationManager();
49
- }
50
- switch (configuration.type) {
51
- case "abap":
52
- return new AbapAnnotationManager(configuration, repository);
53
- case "cf":
54
- return new LocalAnnotationManager();
55
- default:
56
- throw new Error(`No annotation manager found for the given configuration type '${configuration.type}'`);
57
- }
58
- }
59
- function isLocal(configuration) {
60
- return process.env.ADP_BUILDER_MODE === "local" || configuration.mode === "local";
61
- }
62
- function isPreview(configuration) {
63
- return process.env.ADP_BUILDER_MODE === "preview" || configuration.mode === "preview";
64
- }
65
- //# sourceMappingURL=landscapeConfiguration.js.map