@ui5/task-adaptation 1.4.3 → 1.5.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.
- package/CHANGELOG.md +6 -2
- package/README.md +16 -12
- package/dist/annotationManager.js +1 -3
- package/dist/annotations/serviceRequestor.js +3 -15
- package/dist/appVariantManager.d.ts +18 -11
- package/dist/appVariantManager.js +77 -80
- package/dist/baseAppManager.d.ts +16 -16
- package/dist/baseAppManager.js +57 -79
- package/dist/bundle.js +58 -42
- package/dist/cache/cacheHolder.d.ts +18 -0
- package/dist/cache/cacheHolder.js +80 -0
- package/dist/i18nManager.js +11 -9
- package/dist/index.js +26 -9
- package/dist/model/appVariantIdHierarchyItem.d.ts +5 -0
- package/dist/model/appVariantIdHierarchyItem.js +2 -0
- package/dist/model/language.d.ts +3 -3
- package/dist/model/language.js +11 -4
- package/dist/model/types.d.ts +2 -0
- package/dist/processors/abapProcessor.d.ts +4 -4
- package/dist/processors/abapProcessor.js +17 -6
- package/dist/processors/cfProcessor.d.ts +4 -4
- package/dist/processors/cfProcessor.js +21 -5
- package/dist/processors/processor.d.ts +4 -2
- package/dist/processors/processor.js +2 -4
- package/dist/repositories/abapRepoManager.d.ts +3 -1
- package/dist/repositories/abapRepoManager.js +24 -5
- package/dist/util/cfUtil.js +1 -1
- package/dist/util/commonUtil.d.ts +3 -2
- package/dist/util/commonUtil.js +17 -9
- package/dist/util/i18nMerger.d.ts +15 -20
- package/dist/util/i18nMerger.js +46 -64
- package/dist/util/resourceUtil.d.ts +3 -1
- package/dist/util/resourceUtil.js +15 -2
- package/eslint.config.js +2 -5
- package/package.json +16 -11
- package/types/ui5.d.ts +10 -0
- package/dist/cache/annotationsCacheManager.d.ts +0 -8
- package/dist/cache/annotationsCacheManager.js +0 -16
- package/dist/cache/baseAppFilesCacheManager.d.ts +0 -6
- package/dist/cache/baseAppFilesCacheManager.js +0 -12
- package/dist/cache/cacheManager.d.ts +0 -16
- package/dist/cache/cacheManager.js +0 -65
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
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.
|
|
5
|
+
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.5.1...HEAD).
|
|
6
|
+
|
|
7
|
+
<a name="v1.5.1"></a>
|
|
8
|
+
## [v1.5.1] - 2025-08-06
|
|
6
9
|
|
|
7
10
|
<a name="v1.4.3"></a>
|
|
8
|
-
## [v1.4.3] - 2025-04-
|
|
11
|
+
## [v1.4.3] - 2025-04-17
|
|
9
12
|
### Bug Fixes
|
|
10
13
|
- Handling undefined oAuthScopes ([#122](https://github.com/SAP/ui5-task-adaptation/issues/122)) [`ea6296b`](https://github.com/SAP/ui5-task-adaptation/commit/ea6296b143e7fcbf8ce3902499be2d4c2fea61a5)
|
|
11
14
|
- Better error handling in CF ([#121](https://github.com/SAP/ui5-task-adaptation/issues/121)) [`8ce564f`](https://github.com/SAP/ui5-task-adaptation/commit/8ce564fa847a512f4de341f14b1788bca3075da8)
|
|
@@ -116,6 +119,7 @@ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task
|
|
|
116
119
|
<a name="v1.0.0"></a>
|
|
117
120
|
## v1.0.0 - 2020-12-09
|
|
118
121
|
|
|
122
|
+
[v1.5.1]: https://github.com/SAP/ui5-task-adaptation/compare/v1.4.3...v1.5.1
|
|
119
123
|
[v1.4.3]: https://github.com/SAP/ui5-task-adaptation/compare/v1.4.2...v1.4.3
|
|
120
124
|
[v1.4.2]: https://github.com/SAP/ui5-task-adaptation/compare/v1.4.0...v1.4.2
|
|
121
125
|
[v1.4.0]: https://github.com/SAP/ui5-task-adaptation/compare/v1.3.3...v1.4.0
|
package/README.md
CHANGED
|
@@ -4,28 +4,29 @@
|
|
|
4
4
|
[](https://badge.fury.io/js/@ui5%2Ftask-adaptation)
|
|
5
5
|
|
|
6
6
|
## Description
|
|
7
|
-
A custom task for [ui5-builder](https://github.com/SAP/ui5-builder) that allows
|
|
7
|
+
A custom task for [ui5-builder](https://github.com/SAP/ui5-builder) that allows you to build SAPUI5 adaptation projects for [SAP S/4HANA Cloud](https://help.sap.com/docs/bas/584e0bcbfd4a4aff91c815cefa0bce2d/6fc4e11a4b1941efa8e37a428d046f8f.html?locale=en-US&state=PRODUCTION&version=Cloud) and [SAP BTP, Cloud Foundry environment](https://help.sap.com/viewer/584e0bcbfd4a4aff91c815cefa0bce2d/Cloud/en-US/019b0c38a6b043d1a66b11d992eed290.html).
|
|
8
8
|
|
|
9
9
|
### Configuration
|
|
10
|
-
####
|
|
11
|
-
|
|
10
|
+
#### Connection
|
|
11
|
+
When creating an adaptation project, the Yeoman generator automatically generates the following connection configurations in the `ui5.yaml` file, depending on your IDE:
|
|
12
|
+
|
|
13
|
+
For local IDEs like VS Code:
|
|
12
14
|
```yaml
|
|
13
15
|
target:
|
|
14
16
|
url: example.com,
|
|
15
|
-
authenticationType:
|
|
17
|
+
authenticationType: reentranceTicket,
|
|
16
18
|
ignoreCertErrors: true | false
|
|
17
19
|
```
|
|
18
|
-
|
|
20
|
+
In SAP Business Application Studio:
|
|
19
21
|
```yaml
|
|
20
22
|
target:
|
|
21
23
|
destination: abc
|
|
22
24
|
```
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Whereas S4/Hana uses `authenticationType: reentranceTicket` to authentificate. A browser window will be opened.
|
|
25
|
+
|
|
26
|
+
For more information, see [Create an Adaptation Project](https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/create-project) (on SAP S/4HANA Cloud) or [Create an Adaptation Project](https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/create-adaptation-project-c7b455d488bc4229af7efe0311546752) (on SAP BTP, Cloud Foundry environment).
|
|
27
|
+
> [!NOTE]
|
|
28
|
+
> For SAP S/4HANA (on-premise) systems, a different builder is used.
|
|
29
|
+
|
|
29
30
|
|
|
30
31
|
## How to obtain support
|
|
31
32
|
In case you need any support, please create a [GitHub issue](https://github.com/SAP/ui5-task-adaptation/issues).
|
|
@@ -34,4 +35,7 @@ In case you need any support, please create a [GitHub issue](https://github.com/
|
|
|
34
35
|
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file and all other files in this repository are licensed under the Apache License, v 2.0 except as noted otherwise in the [LICENSE file](LICENSE).
|
|
35
36
|
|
|
36
37
|
## Release History
|
|
37
|
-
See [CHANGELOG.md](CHANGELOG.md).
|
|
38
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
39
|
+
|
|
40
|
+
## Contributing
|
|
41
|
+
Please refer to the [SAP Contribution Guidelines](https://github.com/SAP/.github/blob/main/CONTRIBUTING.md) for instructions on how to contribute to ui5-task-adaptation.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import BaseAppManager from "./baseAppManager.js";
|
|
2
1
|
import DataSourceManager from "./annotations/dataSource/dataSourceManager.js";
|
|
3
2
|
import I18nManager from "./i18nManager.js";
|
|
4
3
|
import ServiceRequestor from "./annotations/serviceRequestor.js";
|
|
@@ -15,8 +14,7 @@ export default class AnnotationManager {
|
|
|
15
14
|
}
|
|
16
15
|
ANNOTATIONS_FOLDER = "annotations";
|
|
17
16
|
async process(renamedBaseAppManifest, languages) {
|
|
18
|
-
const { id } =
|
|
19
|
-
BaseAppManager.validateProperty(id, "sap.app/id");
|
|
17
|
+
const { id } = renamedBaseAppManifest["sap.app"];
|
|
20
18
|
const normalisedId = this.normalizeAppVariantId(id);
|
|
21
19
|
//TODO: switch to this after resolving @i18n custom model
|
|
22
20
|
const modelName = I18N_DEFAULT_MODEL_NAME; //`i18n_a9n_${normalisedId}`;
|
|
@@ -4,7 +4,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
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
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import AnnotationsCacheManager from "../cache/annotationsCacheManager.js";
|
|
8
7
|
import ServerError from "../model/serverError.js";
|
|
9
8
|
import { getLogger } from "@ui5/logger";
|
|
10
9
|
import { writeTempAnnotations } from "../util/commonUtil.js";
|
|
@@ -46,20 +45,9 @@ export default class ServiceRequestor {
|
|
|
46
45
|
//old decorators are already subject of compiler error, but it works. So we
|
|
47
46
|
//wait till esbuild implement it correctly.
|
|
48
47
|
async downloadAnnotation(uri, name, language) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
cacheName += `-${language.sap}`;
|
|
53
|
-
}
|
|
54
|
-
const cacheManager = new AnnotationsCacheManager(this.configuration, cacheName);
|
|
55
|
-
log.verbose(`Getting annotation '${cacheName}' ${language} by '${uri}'`);
|
|
56
|
-
let files;
|
|
57
|
-
if (this.configuration.enableAnnotationCache) {
|
|
58
|
-
files = await cacheManager.getFiles(() => this.abapRepoManager.getAnnotationMetadata(uri), () => this.abapRepoManager.downloadAnnotationFile(uri));
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
files = await this.abapRepoManager.downloadAnnotationFile(uri);
|
|
62
|
-
}
|
|
48
|
+
uri += `?sap-language=${language.sap}`;
|
|
49
|
+
log.verbose(`Getting annotation '${name}' ${language} by '${uri}'`);
|
|
50
|
+
let files = await this.abapRepoManager.downloadAnnotationFile(uri);
|
|
63
51
|
if (!files || files.size === 0) {
|
|
64
52
|
throw new Error(`No files were fetched for '${name}' by '${uri}'`);
|
|
65
53
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { IChange } from "./model/types.js";
|
|
2
|
+
import TaskUtil from "@ui5/project/build/helpers/TaskUtil";
|
|
3
|
+
export default class AppVariant {
|
|
4
|
+
readonly files: ReadonlyMap<string, string>;
|
|
5
|
+
readonly resources?: ReadonlyArray<Resource>;
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly reference: string;
|
|
8
|
+
readonly layer: any;
|
|
9
|
+
readonly content: any;
|
|
10
|
+
static fromWorkspace(workspace: IWorkspace, projectNamespace: string): Promise<AppVariant>;
|
|
11
|
+
static fromFiles(files: ReadonlyMap<string, string>): AppVariant;
|
|
12
|
+
private constructor();
|
|
13
|
+
getProcessedFiles(): Map<string, string>;
|
|
14
|
+
getProcessedManifestChanges(): IChange[];
|
|
15
|
+
private validateManifest;
|
|
16
|
+
private updateRelativePaths;
|
|
17
|
+
private isManifestChange;
|
|
18
|
+
omitDeletedResources(files: ReadonlyMap<string, string>, projectNamespace: string, taskUtil: TaskUtil): void;
|
|
12
19
|
}
|
|
@@ -1,101 +1,98 @@
|
|
|
1
1
|
import ResourceUtil from "./util/resourceUtil.js";
|
|
2
2
|
import { posix as path } from "path";
|
|
3
|
-
import {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
import { rename } from "./util/commonUtil.js";
|
|
4
|
+
const CHANGES_DIR = "changes/";
|
|
5
|
+
const CHANGES_EXT = ".change";
|
|
6
|
+
const MANIFEST_CHANGE = "appdescr_";
|
|
7
|
+
export default class AppVariant {
|
|
8
|
+
files;
|
|
9
|
+
resources;
|
|
10
|
+
id;
|
|
11
|
+
reference;
|
|
12
|
+
layer;
|
|
13
|
+
content;
|
|
14
|
+
static async fromWorkspace(workspace, projectNamespace) {
|
|
15
|
+
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";
|
|
16
|
+
const resources = await workspace.byGlob(`/**/*.{${EXTENSIONS_TO_PROCESS}}`);
|
|
17
|
+
const files = await ResourceUtil.toFileMap(resources, projectNamespace);
|
|
18
|
+
return new AppVariant(files, resources);
|
|
19
|
+
}
|
|
20
|
+
static fromFiles(files) {
|
|
21
|
+
return new AppVariant(files);
|
|
12
22
|
}
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
constructor(files, resources) {
|
|
24
|
+
this.files = files;
|
|
25
|
+
this.resources = resources;
|
|
26
|
+
const manifestString = files.get("manifest.appdescr_variant");
|
|
27
|
+
this.validateManifest(manifestString);
|
|
28
|
+
const { reference, id, layer, content } = JSON.parse(manifestString);
|
|
29
|
+
this.reference = reference;
|
|
30
|
+
this.id = id;
|
|
31
|
+
this.layer = layer;
|
|
32
|
+
this.content = content;
|
|
15
33
|
}
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
manifest = await ResourceUtil.getJson(resource);
|
|
34
|
+
getProcessedFiles() {
|
|
35
|
+
const files = new Map();
|
|
36
|
+
this.files.forEach((content, filename) => {
|
|
37
|
+
if (filename.startsWith(CHANGES_DIR)) {
|
|
38
|
+
if (!this.isManifestChange(filename, content)) {
|
|
39
|
+
files.set(filename, rename(content, this.reference, this.id));
|
|
40
|
+
}
|
|
24
41
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (basename.startsWith(changesFolder)) {
|
|
28
|
-
changes.set(resourcePath, await ResourceUtil.getString(resource));
|
|
29
|
-
resourcesByPath.set(resourcePath, resource);
|
|
42
|
+
else if (filename !== "manifest.appdescr_variant") {
|
|
43
|
+
files.set(filename, content);
|
|
30
44
|
}
|
|
31
|
-
}
|
|
32
|
-
this.updateRelativePaths(changes, projectNamespace);
|
|
33
|
-
this.validateManifest(manifest);
|
|
34
|
-
const renamedChanges = renameResources(changes, manifest.reference, manifest.id);
|
|
35
|
-
renamedChanges.forEach((renamedContent, resourcePath) => {
|
|
36
|
-
const resource = resourcesByPath.get(resourcePath);
|
|
37
|
-
ResourceUtil.setString(resource, renamedContent);
|
|
38
45
|
});
|
|
46
|
+
return files;
|
|
39
47
|
}
|
|
40
|
-
|
|
41
|
-
const changesManifestFolder = path.join("changes", "manifest");
|
|
42
|
-
const resourcePath = typeof resource === "string" ? resource : resource.getPath();
|
|
43
|
-
const dirname = path.dirname(resourcePath);
|
|
44
|
-
return dirname.endsWith(changesManifestFolder);
|
|
45
|
-
}
|
|
46
|
-
static isManifestAppVariant(resource) {
|
|
47
|
-
const MANIFEST_APP_VARIANT = "manifest.appdescr_variant";
|
|
48
|
-
const basename = path.basename(resource.getPath());
|
|
49
|
-
return basename === MANIFEST_APP_VARIANT;
|
|
50
|
-
}
|
|
51
|
-
static async getAppVariantInfo(appVariantResources) {
|
|
52
|
-
let manifest;
|
|
53
|
-
const manifestChanges = [];
|
|
54
|
-
for (const resource of appVariantResources) {
|
|
55
|
-
if (this.isManifestAppVariant(resource)) {
|
|
56
|
-
manifest = await ResourceUtil.getJson(resource);
|
|
57
|
-
}
|
|
58
|
-
else if (this.isManifestChange(resource)) {
|
|
59
|
-
const content = await ResourceUtil.getString(resource);
|
|
60
|
-
manifestChanges.push(JSON.parse(content));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
this.validateManifest(manifest);
|
|
48
|
+
getProcessedManifestChanges() {
|
|
64
49
|
// Order is important: apply manifest.json changes first, then *.change
|
|
65
50
|
// files. UI5 does the same.
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
const manifestChanges = structuredClone(this.content) ?? [];
|
|
52
|
+
this.files.forEach((content, filename) => {
|
|
53
|
+
if (this.isManifestChange(filename, content)) {
|
|
54
|
+
const change = JSON.parse(rename(content, this.reference, this.id));
|
|
55
|
+
this.updateRelativePaths(change, filename);
|
|
56
|
+
manifestChanges.push(change);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
if (this.layer) {
|
|
60
|
+
manifestChanges.forEach(change => change.layer = this.layer ?? change.layer);
|
|
61
|
+
}
|
|
62
|
+
return manifestChanges;
|
|
73
63
|
}
|
|
74
|
-
|
|
64
|
+
validateManifest(manifest) {
|
|
75
65
|
if (!manifest) {
|
|
76
66
|
throw new Error("Adaptation project should contain manifest.appdescr_variant");
|
|
77
67
|
}
|
|
78
68
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!dataSource.uri.startsWith("/")) {
|
|
87
|
-
const basepath = path.dirname(ResourceUtil.relativeToRoot(resourcePath, projectNamespace));
|
|
88
|
-
dataSource.uri = path.join(basepath.replace(/^\//, ""), dataSource.uri);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
changes.set(resourcePath, JSON.stringify(change));
|
|
69
|
+
updateRelativePaths(change, filename) {
|
|
70
|
+
// TODO In future this should be handled by merger which needs to know change and target location
|
|
71
|
+
if (change.changeType === "appdescr_app_addAnnotationsToOData") {
|
|
72
|
+
for (const dataSource of Object.values(change?.content?.dataSource)) {
|
|
73
|
+
if (!dataSource.uri.startsWith("/")) {
|
|
74
|
+
const basepath = path.dirname(filename);
|
|
75
|
+
dataSource.uri = path.join(basepath.replace(/^\//, ""), dataSource.uri);
|
|
92
76
|
}
|
|
93
77
|
}
|
|
94
|
-
}
|
|
78
|
+
}
|
|
95
79
|
}
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
|
|
80
|
+
isManifestChange(filename, content) {
|
|
81
|
+
if (filename.endsWith(CHANGES_EXT)) {
|
|
82
|
+
const change = JSON.parse(content);
|
|
83
|
+
return change.changeType?.startsWith(MANIFEST_CHANGE);
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
omitDeletedResources(files, projectNamespace, taskUtil) {
|
|
88
|
+
if (!this.resources) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
for (const resource of this.resources) {
|
|
92
|
+
const relativePath = ResourceUtil.relativeToRoot(resource.getPath(), projectNamespace);
|
|
93
|
+
if (!files.has(relativePath)) {
|
|
94
|
+
taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
|
|
95
|
+
}
|
|
99
96
|
}
|
|
100
97
|
}
|
|
101
98
|
}
|
package/dist/baseAppManager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AppVariant from "./appVariantManager.js";
|
|
2
2
|
import IProcessor from "./processors/processor.js";
|
|
3
3
|
export interface IBaseAppResources {
|
|
4
4
|
resources: any[];
|
|
@@ -11,19 +11,19 @@ export interface IManifestIdVersion {
|
|
|
11
11
|
export interface IManifestInfo extends IManifestIdVersion {
|
|
12
12
|
i18nPath: string;
|
|
13
13
|
}
|
|
14
|
-
export default class
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
private
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
14
|
+
export default class BaseApp {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly version: string;
|
|
17
|
+
readonly i18nPath: string;
|
|
18
|
+
readonly files: ReadonlyMap<string, string>;
|
|
19
|
+
static fromFiles(files: ReadonlyMap<string, string>): BaseApp;
|
|
20
|
+
private constructor();
|
|
21
|
+
adapt(appVariant: AppVariant, processor: IProcessor): Promise<ReadonlyMap<string, string>>;
|
|
22
|
+
private updateAdaptationProperties;
|
|
23
|
+
private extractI18nPathFromManifest;
|
|
24
|
+
private fillAppVariantIdHierarchy;
|
|
25
|
+
private VALIDATION_RULES;
|
|
26
|
+
private validateProperty;
|
|
27
|
+
private applyDescriptorChanges;
|
|
28
|
+
private adjustAddNewModelEnhanceWith;
|
|
29
29
|
}
|
package/dist/baseAppManager.js
CHANGED
|
@@ -1,29 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dotToUnderscore,
|
|
1
|
+
import { AppDescriptorChange, Applier, RegistrationBuild } from "../dist/bundle.js";
|
|
2
|
+
import { dotToUnderscore, trimExtension } from "./util/commonUtil.js";
|
|
3
3
|
import BuildStrategy from "./buildStrategy.js";
|
|
4
|
-
import ResourceUtil from "./util/resourceUtil.js";
|
|
5
4
|
import { getLogger } from "@ui5/logger";
|
|
6
5
|
import { renameResources } from "./util/commonUtil.js";
|
|
7
6
|
const log = getLogger("@ui5/task-adaptation::BaseAppManager");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
renamedBaseAppFiles.set(filepath, JSON.stringify(content));
|
|
21
|
-
return {
|
|
22
|
-
resources: this.writeToWorkspace(renamedBaseAppFiles, options.projectNamespace),
|
|
23
|
-
manifestInfo: this.getManifestInfo(content)
|
|
24
|
-
};
|
|
7
|
+
const IGNORE_FILES = [
|
|
8
|
+
"manifest-bundle.zip",
|
|
9
|
+
"Component-preload.js",
|
|
10
|
+
"sap-ui-cachebuster-info.json"
|
|
11
|
+
];
|
|
12
|
+
export default class BaseApp {
|
|
13
|
+
id;
|
|
14
|
+
version;
|
|
15
|
+
i18nPath;
|
|
16
|
+
files;
|
|
17
|
+
static fromFiles(files) {
|
|
18
|
+
return new BaseApp(files);
|
|
25
19
|
}
|
|
26
|
-
|
|
20
|
+
constructor(files) {
|
|
21
|
+
this.files = new Map([...files].filter(([filename]) => !IGNORE_FILES.includes(filename)));
|
|
22
|
+
const manifestString = files.get("manifest.json");
|
|
23
|
+
if (!manifestString) {
|
|
24
|
+
throw new Error("Original application should have manifest.json in root folder");
|
|
25
|
+
}
|
|
26
|
+
const manifest = JSON.parse(manifestString);
|
|
27
|
+
this.id = manifest["sap.app"]?.id;
|
|
28
|
+
this.version = manifest["sap.app"]?.applicationVersion?.version;
|
|
29
|
+
this.validateProperty(this.id, "sap.app/id");
|
|
30
|
+
this.validateProperty(this.version, "sap.app/applicationVersion/version");
|
|
31
|
+
this.i18nPath = this.extractI18nPathFromManifest(this.id, manifest["sap.app"]?.i18n);
|
|
32
|
+
}
|
|
33
|
+
async adapt(appVariant, processor) {
|
|
34
|
+
const files = renameResources(this.files, appVariant.reference, appVariant.id);
|
|
35
|
+
const manifest = JSON.parse(files.get("manifest.json"));
|
|
36
|
+
await processor.updateLandscapeSpecificContent(manifest, files);
|
|
37
|
+
this.fillAppVariantIdHierarchy(processor, this.id, this.version, manifest);
|
|
38
|
+
this.updateAdaptationProperties(manifest);
|
|
39
|
+
await this.applyDescriptorChanges(manifest, appVariant);
|
|
40
|
+
files.set("manifest.json", JSON.stringify(manifest));
|
|
41
|
+
return files;
|
|
42
|
+
}
|
|
43
|
+
updateAdaptationProperties(content) {
|
|
27
44
|
if (content["sap.fiori"]?.cloudDevAdaptationStatus) {
|
|
28
45
|
delete content["sap.fiori"].cloudDevAdaptationStatus;
|
|
29
46
|
}
|
|
@@ -32,42 +49,21 @@ export default class BaseAppManager {
|
|
|
32
49
|
}
|
|
33
50
|
content["sap.ui5"].isCloudDevAdaptation = true;
|
|
34
51
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
static extractI18nPathFromManifest(sapAppId, i18nNode) {
|
|
47
|
-
if (typeof i18nNode === "object") {
|
|
48
|
-
return i18nNode["bundleUrl"] ? this.extractI18NFromBundleUrl(i18nNode) : this.extractI18NFromBundleName(i18nNode, sapAppId);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
return `${sapAppId?.replaceAll(".", "/")}/${i18nNode}`;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
static extractI18NFromBundleName(i18nNode, sapAppId) {
|
|
55
|
-
return i18nNode["bundleName"].replace(sapAppId, "").replaceAll(".", "/").substring(1);
|
|
56
|
-
}
|
|
57
|
-
static extractI18NFromBundleUrl(i18nNode) {
|
|
58
|
-
return removePropertiesExtension(i18nNode["bundleUrl"]);
|
|
59
|
-
}
|
|
60
|
-
static getBaseAppManifest(baseAppFiles) {
|
|
61
|
-
const manifestContent = baseAppFiles.get("manifest.json");
|
|
62
|
-
if (manifestContent) {
|
|
63
|
-
return {
|
|
64
|
-
content: JSON.parse(manifestContent),
|
|
65
|
-
filepath: "manifest.json"
|
|
66
|
-
};
|
|
52
|
+
extractI18nPathFromManifest(sapAppId, i18nNode) {
|
|
53
|
+
if (i18nNode) {
|
|
54
|
+
if (i18nNode["bundleUrl"]) {
|
|
55
|
+
return trimExtension(i18nNode["bundleUrl"]);
|
|
56
|
+
}
|
|
57
|
+
else if (i18nNode["bundleName"]) {
|
|
58
|
+
return i18nNode["bundleName"].replace(sapAppId, "").replaceAll(".", "/").substring(1);
|
|
59
|
+
}
|
|
60
|
+
else if (typeof i18nNode === "string") {
|
|
61
|
+
return trimExtension(i18nNode);
|
|
62
|
+
}
|
|
67
63
|
}
|
|
68
|
-
|
|
64
|
+
return "i18n/i18n";
|
|
69
65
|
}
|
|
70
|
-
|
|
66
|
+
fillAppVariantIdHierarchy(processor, id, version, baseAppManifest) {
|
|
71
67
|
log.verbose("Filling up app variant hierarchy in manifest.json");
|
|
72
68
|
if (baseAppManifest["sap.ui5"] == null) {
|
|
73
69
|
baseAppManifest["sap.ui5"] = {};
|
|
@@ -78,12 +74,12 @@ export default class BaseAppManager {
|
|
|
78
74
|
const appVariantIdHierarchyItem = processor.createAppVariantHierarchyItem(id, version);
|
|
79
75
|
baseAppManifest["sap.ui5"].appVariantIdHierarchy.unshift(appVariantIdHierarchyItem);
|
|
80
76
|
}
|
|
81
|
-
|
|
77
|
+
VALIDATION_RULES = new Map([["sap.app/id", (value) => {
|
|
82
78
|
if (!value.includes(".")) {
|
|
83
79
|
throw new Error(`The original application id '${value}' should consist of multiple segments split by dot, e.g.: original.id`);
|
|
84
80
|
}
|
|
85
81
|
}]]);
|
|
86
|
-
|
|
82
|
+
validateProperty(value, property) {
|
|
87
83
|
if (!value) {
|
|
88
84
|
throw new Error(`Original application manifest should have ${property}`);
|
|
89
85
|
}
|
|
@@ -92,14 +88,11 @@ export default class BaseAppManager {
|
|
|
92
88
|
validatationRule(value);
|
|
93
89
|
}
|
|
94
90
|
}
|
|
95
|
-
|
|
91
|
+
async applyDescriptorChanges(baseAppManifest, appVariant) {
|
|
96
92
|
log.verbose("Applying appVariant changes");
|
|
97
93
|
const changesContent = new Array();
|
|
98
|
-
const i18nBundleName = dotToUnderscore(id);
|
|
99
|
-
for (const change of
|
|
100
|
-
if (layer) {
|
|
101
|
-
change.layer = layer;
|
|
102
|
-
}
|
|
94
|
+
const i18nBundleName = dotToUnderscore(appVariant.id);
|
|
95
|
+
for (const change of appVariant.getProcessedManifestChanges()) {
|
|
103
96
|
changesContent.push(new AppDescriptorChange(change));
|
|
104
97
|
this.adjustAddNewModelEnhanceWith(change, i18nBundleName);
|
|
105
98
|
}
|
|
@@ -108,7 +101,7 @@ export default class BaseAppManager {
|
|
|
108
101
|
await Applier.applyChanges(baseAppManifest, changesContent, strategy);
|
|
109
102
|
}
|
|
110
103
|
}
|
|
111
|
-
|
|
104
|
+
adjustAddNewModelEnhanceWith(change, i18nBundleName) {
|
|
112
105
|
if (change.changeType === "appdescr_ui5_addNewModelEnhanceWith") {
|
|
113
106
|
if (change.texts == null) {
|
|
114
107
|
// We need to add texts properties to changes because not all
|
|
@@ -120,20 +113,5 @@ export default class BaseAppManager {
|
|
|
120
113
|
change.texts.i18n = i18nBundleName + "/" + change.texts.i18n;
|
|
121
114
|
}
|
|
122
115
|
}
|
|
123
|
-
static writeToWorkspace(baseAppFiles, projectNamespace) {
|
|
124
|
-
const IGNORE_FILES = [
|
|
125
|
-
"manifest-bundle.zip",
|
|
126
|
-
"Component-preload.js",
|
|
127
|
-
"sap-ui-cachebuster-info.json"
|
|
128
|
-
];
|
|
129
|
-
const resources = [];
|
|
130
|
-
for (let filename of baseAppFiles.keys()) {
|
|
131
|
-
if (!IGNORE_FILES.includes(filename)) {
|
|
132
|
-
const resource = ResourceUtil.createResource(filename, projectNamespace, baseAppFiles.get(filename));
|
|
133
|
-
resources.push(resource);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return resources;
|
|
137
|
-
}
|
|
138
116
|
}
|
|
139
117
|
//# sourceMappingURL=baseAppManager.js.map
|