@ui5/task-adaptation 1.0.15 → 1.0.17
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 +8 -4
- package/README.md +1 -1
- package/dist/annotationManager.d.ts +32 -0
- package/dist/annotationManager.js +276 -0
- package/dist/appVariantManager.js +18 -32
- package/dist/baseAppManager.d.ts +8 -4
- package/dist/baseAppManager.js +37 -62
- package/dist/buildStrategy.js +3 -0
- package/dist/bundle-resourceBundle.js +692 -0
- package/dist/bundle.js +247 -106
- package/dist/cache/annotationsCacheManager.d.ts +8 -0
- package/dist/cache/annotationsCacheManager.js +18 -0
- package/dist/cache/baseAppFilesCacheManager.d.ts +6 -0
- package/dist/cache/baseAppFilesCacheManager.js +15 -0
- package/dist/cache/cacheManager.d.ts +16 -0
- package/dist/cache/cacheManager.js +67 -0
- package/dist/index.js +10 -18
- package/dist/model/noAuthorizationProvidedError.d.ts +3 -0
- package/dist/model/noAuthorizationProvidedError.js +9 -0
- package/dist/model/types.d.ts +13 -1
- package/dist/processors/abapProcessor.d.ts +21 -0
- package/dist/processors/abapProcessor.js +36 -0
- package/dist/processors/cfProcessor.d.ts +17 -0
- package/dist/processors/cfProcessor.js +46 -0
- package/dist/processors/processor.d.ts +7 -0
- package/dist/processors/processor.js +36 -0
- package/dist/repositories/abapRepoManager.d.ts +13 -0
- package/dist/repositories/abapRepoManager.js +81 -0
- package/dist/{html5RepoManager.d.ts → repositories/html5RepoManager.d.ts} +2 -2
- package/dist/repositories/html5RepoManager.js +89 -0
- package/dist/util/cfUtil.js +109 -138
- package/dist/util/commonUtil.js +1 -1
- package/dist/util/requestUtil.d.ts +6 -3
- package/dist/util/requestUtil.js +43 -24
- package/dist/util/resourceUtil.d.ts +2 -10
- package/dist/util/resourceUtil.js +6 -49
- package/dist/util/zipUtil.d.ts +2 -0
- package/dist/util/zipUtil.js +20 -0
- package/package.json +10 -5
- package/scripts/bundler.ts +75 -0
- package/scripts/rollup/bundleDefinition-resourceBundle.js +5 -0
- package/scripts/rollup/overrides/sap/base/i18n/Localization.js +1 -0
- package/scripts/rollup/overrides/sap/base/string/formatMessage.js +1 -0
- package/scripts/rollup/overrides/sap/base/util/Properties.js +1 -0
- package/scripts/rollup/overrides/sap/base/util/merge.js +1 -0
- package/scripts/rollup/project/ui5.yaml +1 -1
- package/scripts/rollup.ts +26 -50
- package/dist/html5RepoManager.js +0 -113
- package/dist/updateCache.d.ts +0 -5
- package/dist/updateCache.js +0 -36
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.0.
|
|
5
|
+
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task-adaptation/compare/v1.0.17...HEAD).
|
|
6
6
|
|
|
7
|
-
<a name="v1.0.
|
|
8
|
-
## [v1.0.
|
|
7
|
+
<a name="v1.0.17"></a>
|
|
8
|
+
## [v1.0.17] - 2023-08-16
|
|
9
|
+
|
|
10
|
+
<a name="v1.0.16"></a>
|
|
11
|
+
## [v1.0.16] - 2023-08-15
|
|
9
12
|
|
|
10
13
|
<a name="v1.0.11"></a>
|
|
11
14
|
## [v1.0.11] - 2022-03-01
|
|
@@ -46,7 +49,8 @@ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task
|
|
|
46
49
|
<a name="v1.0.0"></a>
|
|
47
50
|
## v1.0.0 - 2020-12-09
|
|
48
51
|
|
|
49
|
-
[v1.0.
|
|
52
|
+
[v1.0.17]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.16...v1.0.17
|
|
53
|
+
[v1.0.16]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.11...v1.0.16
|
|
50
54
|
[v1.0.11]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.10...v1.0.11
|
|
51
55
|
[v1.0.10]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.9...v1.0.10
|
|
52
56
|
[v1.0.9]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.8...v1.0.9
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
A custom task for [ui5-builder](https://github.com/SAP/ui5-builder) that allows building [UI5 Flexibility adaptation projects](https://help.sap.com/viewer/584e0bcbfd4a4aff91c815cefa0bce2d/Cloud/en-US/019b0c38a6b043d1a66b11d992eed290.html) for SAP BTP, Cloud Foundry environment.
|
|
8
8
|
|
|
9
9
|
## How to obtain support
|
|
10
|
-
In case you need any support, please create a GitHub issue.
|
|
10
|
+
In case you need any support, please create a [GitHub issue](https://github.com/SAP/ui5-task-adaptation/issues).
|
|
11
11
|
|
|
12
12
|
## License
|
|
13
13
|
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).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import AbapRepoManager from "./repositories/abapRepoManager";
|
|
2
|
+
import { IConfiguration } from "./model/types";
|
|
3
|
+
export interface IAnnotationFiles {
|
|
4
|
+
annotationName: string;
|
|
5
|
+
annotationFileName: string;
|
|
6
|
+
}
|
|
7
|
+
export default class AnnotationManager {
|
|
8
|
+
private abapRepoManager;
|
|
9
|
+
private configuration;
|
|
10
|
+
constructor(configuration: IConfiguration, abapRepoManager: AbapRepoManager);
|
|
11
|
+
ANNOTATIONS_FOLDER: string;
|
|
12
|
+
process(renamedBaseAppManifest: any, languages: string[]): Promise<Map<string, string>>;
|
|
13
|
+
private createI18nFiles;
|
|
14
|
+
private normalizeAppVariantId;
|
|
15
|
+
private createAnnotationFile;
|
|
16
|
+
private getNormalisedLanguage;
|
|
17
|
+
private getAdaptedAnnotation;
|
|
18
|
+
private getUniqueKeyForPath;
|
|
19
|
+
private downloadAnnotations;
|
|
20
|
+
private updateManifest;
|
|
21
|
+
private updateManifestDataSources;
|
|
22
|
+
private createManifestModel;
|
|
23
|
+
private enhanceManifestModel;
|
|
24
|
+
private downloadAnnotation;
|
|
25
|
+
private getODataAnnotations;
|
|
26
|
+
static traverseJson(obj: any, path: string): {
|
|
27
|
+
subject: any;
|
|
28
|
+
property: string;
|
|
29
|
+
};
|
|
30
|
+
private getDiffJsonPaths;
|
|
31
|
+
private traverseDiff;
|
|
32
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const convert = require("xml-js");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const annotationsCacheManager_1 = require("./cache/annotationsCacheManager");
|
|
6
|
+
const baseAppManager_1 = require("./baseAppManager");
|
|
7
|
+
const json_diff_1 = require("json-diff");
|
|
8
|
+
const util_1 = require("util");
|
|
9
|
+
const { ResourceBundle } = require("../dist/bundle-resourceBundle");
|
|
10
|
+
const I18N_DEFAULT_PATH = "i18n/annotations";
|
|
11
|
+
const I18N_DEFAULT_MODEL_NAME = "@i18n";
|
|
12
|
+
const SAPUI5 = "sap.ui5";
|
|
13
|
+
const SAPAPP = "sap.app";
|
|
14
|
+
const XML_OPTIONS = { compact: true, spaces: 4 };
|
|
15
|
+
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::AnnotationManager");
|
|
16
|
+
class AnnotationManager {
|
|
17
|
+
constructor(configuration, abapRepoManager) {
|
|
18
|
+
this.ANNOTATIONS_FOLDER = "annotations";
|
|
19
|
+
this.configuration = configuration;
|
|
20
|
+
this.abapRepoManager = abapRepoManager;
|
|
21
|
+
}
|
|
22
|
+
async process(renamedBaseAppManifest, languages) {
|
|
23
|
+
const { id } = baseAppManager_1.default.getManifestInfo(renamedBaseAppManifest);
|
|
24
|
+
baseAppManager_1.default.validateProperty(id, "sap.app/id");
|
|
25
|
+
const normalisedId = this.normalizeAppVariantId(id);
|
|
26
|
+
//TODO: switch to this after resolving @i18n custom model
|
|
27
|
+
const oDataAnnotations = this.getODataAnnotations(renamedBaseAppManifest);
|
|
28
|
+
const promises = this.downloadAnnotations(oDataAnnotations, languages);
|
|
29
|
+
const modelName = I18N_DEFAULT_MODEL_NAME; //`i18n_a9n_${normalisedId}`;
|
|
30
|
+
const i18nPathName = path.join(I18N_DEFAULT_PATH, normalisedId);
|
|
31
|
+
const keys = new Array();
|
|
32
|
+
const propertiesPerLanguage = new Map();
|
|
33
|
+
const annotationFiles = new Map();
|
|
34
|
+
const metaInfo = new Array();
|
|
35
|
+
for (const { promisesPerLanguage, annotationName } of promises) {
|
|
36
|
+
const annotationXml = await this.createAnnotationFile(promisesPerLanguage, keys, modelName, propertiesPerLanguage, id);
|
|
37
|
+
const annotationFileName = `annotations/annotation_${annotationName}.xml`;
|
|
38
|
+
annotationFiles.set(annotationFileName, annotationXml);
|
|
39
|
+
metaInfo.push({ annotationFileName, annotationName });
|
|
40
|
+
}
|
|
41
|
+
if (metaInfo.length > 0) {
|
|
42
|
+
this.updateManifest(renamedBaseAppManifest, metaInfo, modelName, i18nPathName);
|
|
43
|
+
}
|
|
44
|
+
const i18nFiles = this.createI18nFiles(propertiesPerLanguage, i18nPathName);
|
|
45
|
+
return new Map([...annotationFiles, ...i18nFiles]);
|
|
46
|
+
}
|
|
47
|
+
createI18nFiles(propertiesPerLanguage, i18nPathName) {
|
|
48
|
+
const files = new Map();
|
|
49
|
+
propertiesPerLanguage.forEach((i18nLines, language) => {
|
|
50
|
+
i18nLines.sort();
|
|
51
|
+
let filename = "i18n";
|
|
52
|
+
const normalisedLanguage = this.getNormalisedLanguage(language);
|
|
53
|
+
if (normalisedLanguage) {
|
|
54
|
+
filename += "_" + normalisedLanguage;
|
|
55
|
+
}
|
|
56
|
+
const filepath = path.join(i18nPathName, filename + ".properties");
|
|
57
|
+
files.set(filepath, i18nLines.join("\n"));
|
|
58
|
+
});
|
|
59
|
+
return files;
|
|
60
|
+
}
|
|
61
|
+
normalizeAppVariantId(id, replaceWith = "") {
|
|
62
|
+
return id.replace(/[.\W]+/gi, replaceWith);
|
|
63
|
+
}
|
|
64
|
+
async createAnnotationFile(promisesPerLanguage, keys, modelName, propertiesPerLanguage, appVariantId) {
|
|
65
|
+
const annotationJsons = new Map();
|
|
66
|
+
for (const promise of promisesPerLanguage) {
|
|
67
|
+
const { language, xml } = await promise;
|
|
68
|
+
annotationJsons.set(language, JSON.parse(convert.xml2json(xml, XML_OPTIONS)));
|
|
69
|
+
}
|
|
70
|
+
const paths = this.getDiffJsonPaths([...annotationJsons.values()]);
|
|
71
|
+
const { annotationJson, languageI18nContentMap } = this.getAdaptedAnnotation(paths, keys, annotationJsons, modelName, appVariantId);
|
|
72
|
+
languageI18nContentMap.forEach((i18nLines, language) => {
|
|
73
|
+
const properties = propertiesPerLanguage.get(language);
|
|
74
|
+
if (properties) {
|
|
75
|
+
properties.push(...i18nLines);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
propertiesPerLanguage.set(language, i18nLines);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return convert.json2xml(annotationJson, XML_OPTIONS);
|
|
82
|
+
}
|
|
83
|
+
getNormalisedLanguage(language) {
|
|
84
|
+
const normalisedLanguages = ResourceBundle._getFallbackLocales(language);
|
|
85
|
+
if (normalisedLanguages?.length > 0 && normalisedLanguages[0] != null && normalisedLanguages[0].length > 0) {
|
|
86
|
+
return normalisedLanguages[0].toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
getAdaptedAnnotation(paths, keys, annotationJsons, modelName, appVariantId) {
|
|
90
|
+
const pathKeyMap = new Map();
|
|
91
|
+
const languageI18nContentMap = new Map();
|
|
92
|
+
for (const [language, json] of [...annotationJsons]) {
|
|
93
|
+
const lines = [];
|
|
94
|
+
for (const path of paths) {
|
|
95
|
+
const { subject, property } = AnnotationManager.traverseJson(json, path);
|
|
96
|
+
const value = subject[property];
|
|
97
|
+
const key = appVariantId + "_" + this.getUniqueKeyForPath(pathKeyMap, path, keys, value);
|
|
98
|
+
lines.push(key + "=" + value);
|
|
99
|
+
subject[property] = `{${modelName}>${key}}`;
|
|
100
|
+
}
|
|
101
|
+
if (lines.length > 0) {
|
|
102
|
+
languageI18nContentMap.set(language, lines);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { annotationJson: [...annotationJsons][0][1], languageI18nContentMap };
|
|
106
|
+
}
|
|
107
|
+
getUniqueKeyForPath(pathKeyMap, path, keys, value) {
|
|
108
|
+
if (pathKeyMap.has(path)) {
|
|
109
|
+
return pathKeyMap.get(path);
|
|
110
|
+
}
|
|
111
|
+
const propertyName = value.replace(/\W/gi, "_").toUpperCase();
|
|
112
|
+
let suffix = "";
|
|
113
|
+
while (keys.includes(propertyName + suffix)) {
|
|
114
|
+
suffix = suffix === "" ? "0" : (parseInt(suffix) + 1).toString();
|
|
115
|
+
}
|
|
116
|
+
const key = propertyName + suffix;
|
|
117
|
+
pathKeyMap.set(path, key);
|
|
118
|
+
keys.push(key);
|
|
119
|
+
return key;
|
|
120
|
+
}
|
|
121
|
+
downloadAnnotations(annotations, languages) {
|
|
122
|
+
return [...annotations].map(([name, { uri }]) => ({
|
|
123
|
+
promisesPerLanguage: languages.map(language => this.downloadAnnotation(uri, name, language)),
|
|
124
|
+
annotationName: name
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
updateManifest(renamedBaseAppManifest, metaInfo, modelName, i18nPathName) {
|
|
128
|
+
const uri = `${i18nPathName}/i18n.properties`;
|
|
129
|
+
this.enhanceManifestModel(renamedBaseAppManifest, modelName, uri);
|
|
130
|
+
//TODO: switch to this after resolving @i18n custom model
|
|
131
|
+
//this.createManifestModel(renamedBaseAppManifest, modelName, uri);
|
|
132
|
+
this.updateManifestDataSources(renamedBaseAppManifest, metaInfo);
|
|
133
|
+
}
|
|
134
|
+
updateManifestDataSources(renamedBaseAppManifest, metaInfo) {
|
|
135
|
+
const dataSources = renamedBaseAppManifest[SAPAPP]?.dataSources;
|
|
136
|
+
for (const { annotationName, annotationFileName } of metaInfo) {
|
|
137
|
+
dataSources[annotationName].uri = annotationFileName;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
createManifestModel(manifest, modelName, uri) {
|
|
141
|
+
let sapui5 = manifest[SAPUI5] == null ? manifest[SAPUI5] = {} : manifest[SAPUI5];
|
|
142
|
+
if (sapui5.models == null) {
|
|
143
|
+
sapui5.models = {};
|
|
144
|
+
}
|
|
145
|
+
if (sapui5.models[modelName] == null) {
|
|
146
|
+
sapui5.models[modelName] = {};
|
|
147
|
+
}
|
|
148
|
+
sapui5.models[modelName].type = "sap.ui.model.resource.ResourceModel";
|
|
149
|
+
if (uri) {
|
|
150
|
+
sapui5.models[modelName].uri = uri;
|
|
151
|
+
}
|
|
152
|
+
return sapui5.models[modelName];
|
|
153
|
+
}
|
|
154
|
+
enhanceManifestModel(manifest, modelToEnhance, bundleUrl) {
|
|
155
|
+
let model = manifest[SAPUI5]?.models[modelToEnhance];
|
|
156
|
+
if (model) {
|
|
157
|
+
if (model.settings == null) {
|
|
158
|
+
model.settings = {};
|
|
159
|
+
}
|
|
160
|
+
if (model.settings.enhanceWith == null) {
|
|
161
|
+
model.settings.enhanceWith = [];
|
|
162
|
+
}
|
|
163
|
+
if (model.settings.enhanceWith.every((bundle) => bundle.bundleUrl !== bundleUrl)) {
|
|
164
|
+
model.settings.enhanceWith.push({
|
|
165
|
+
bundleUrl,
|
|
166
|
+
bundleUrlRelativeTo: "component"
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
this.createManifestModel(manifest, modelToEnhance, bundleUrl);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async downloadAnnotation(uri, name, language) {
|
|
175
|
+
let annotationUri = `https://${this.configuration.destination}.dest${uri}`;
|
|
176
|
+
let cacheFilename = name;
|
|
177
|
+
if (language) {
|
|
178
|
+
annotationUri += `?sap-language=${language}`;
|
|
179
|
+
cacheFilename += `-${language}`;
|
|
180
|
+
}
|
|
181
|
+
const cacheManager = new annotationsCacheManager_1.default(this.configuration, cacheFilename);
|
|
182
|
+
log.verbose(`Getting annotation '${name}' ${language} by '${annotationUri}'`);
|
|
183
|
+
try {
|
|
184
|
+
const files = await cacheManager.getFiles(() => this.abapRepoManager.getAnnotationMetadata(annotationUri), () => this.abapRepoManager.downloadAnnotationFile(annotationUri));
|
|
185
|
+
if (!files || files.size === 0) {
|
|
186
|
+
throw new Error(`No files were fetched for '${name}' by '${annotationUri}'`);
|
|
187
|
+
}
|
|
188
|
+
return { language, xml: [...files][0][1] };
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
throw new Error(`Failed to fetch annotation '${name}' by '${annotationUri}': ${error.message}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
getODataAnnotations(renamedBaseAppManifest) {
|
|
195
|
+
const oDataAnnotations = new Map();
|
|
196
|
+
const dataSources = renamedBaseAppManifest[SAPAPP]?.dataSources;
|
|
197
|
+
if (dataSources) {
|
|
198
|
+
for (const key of Object.keys(dataSources)) {
|
|
199
|
+
const annotation = dataSources[key];
|
|
200
|
+
if (annotation?.type === "ODataAnnotation" && annotation?.uri?.startsWith("/")) {
|
|
201
|
+
oDataAnnotations.set(key, dataSources[key]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return oDataAnnotations;
|
|
206
|
+
}
|
|
207
|
+
static traverseJson(obj, path) {
|
|
208
|
+
const checkArrayIndex = (part) => {
|
|
209
|
+
if (Array.isArray(subject)) {
|
|
210
|
+
const item = parseInt(part);
|
|
211
|
+
if (isNaN(item)) {
|
|
212
|
+
throw new Error(`Array index '${part}' is not a number in path '${path}' for ${json}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const json = (0, util_1.inspect)(obj, true, 100, false);
|
|
217
|
+
const pathParts = path.split("/");
|
|
218
|
+
if (path.endsWith("/")) {
|
|
219
|
+
pathParts.pop();
|
|
220
|
+
}
|
|
221
|
+
let property = pathParts.pop();
|
|
222
|
+
let subject = obj;
|
|
223
|
+
for (const part of pathParts) {
|
|
224
|
+
let item = part;
|
|
225
|
+
checkArrayIndex(part);
|
|
226
|
+
subject = subject[item];
|
|
227
|
+
if (subject == null) {
|
|
228
|
+
throw new Error(`Property '${item}' is undefined in path '${path}' for ${json}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
checkArrayIndex(property);
|
|
232
|
+
if (subject[property] == null) {
|
|
233
|
+
throw new Error(`Target property '${property}' is undefined in path '${path}' for ${json}`);
|
|
234
|
+
}
|
|
235
|
+
return { subject, property };
|
|
236
|
+
}
|
|
237
|
+
getDiffJsonPaths(jsons) {
|
|
238
|
+
const paths = new Set();
|
|
239
|
+
if (jsons.length > 1) {
|
|
240
|
+
for (let j = 1; j < jsons.length; j++) {
|
|
241
|
+
const diffResult = (0, json_diff_1.diff)(jsons[0], jsons[j], { full: false, sort: false });
|
|
242
|
+
// if diffResult is undefined -> jsons are the same
|
|
243
|
+
if (diffResult) {
|
|
244
|
+
for (const path of this.traverseDiff(diffResult)) {
|
|
245
|
+
paths.add(path);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return [...paths];
|
|
251
|
+
}
|
|
252
|
+
traverseDiff(obj, path = "") {
|
|
253
|
+
const branches = [];
|
|
254
|
+
if (Array.isArray(obj)) {
|
|
255
|
+
for (let i = 0; i < obj.length; i++) {
|
|
256
|
+
const item = obj[i];
|
|
257
|
+
if (item[0] == "~") {
|
|
258
|
+
branches.push(...this.traverseDiff(item[1], path + `${i}/`));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
for (const key of Object.keys(obj)) {
|
|
264
|
+
if (key == "__old" || key == "__new") {
|
|
265
|
+
branches.push(path);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
branches.push(...this.traverseDiff(obj[key], path + `${key}/`));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return branches;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports.default = AnnotationManager;
|
|
276
|
+
//# sourceMappingURL=annotationManager.js.map
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const path = require("path");
|
|
13
4
|
const resourceUtil_1 = require("./util/resourceUtil");
|
|
@@ -18,34 +9,29 @@ const OMIT_FOLDERS = [];
|
|
|
18
9
|
const EXTENSIONS = "js,json,xml,html,properties,change,appdescr_variant";
|
|
19
10
|
const MANIFEST_APP_VARIANT = "manifest.appdescr_variant";
|
|
20
11
|
class AppVariantManager {
|
|
21
|
-
static process(appVariantResources, projectNamespace, taskUtil) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.adjustAddNewModelEnhanceWith((_b = (_a = appVariantInfo === null || appVariantInfo === void 0 ? void 0 : appVariantInfo.manifest) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : [], i18nBundleName);
|
|
31
|
-
return appVariantInfo;
|
|
32
|
-
});
|
|
12
|
+
static async process(appVariantResources, projectNamespace, taskUtil) {
|
|
13
|
+
const appVariantInfo = await this.getAppVariantInfo(appVariantResources);
|
|
14
|
+
const i18nBundleName = (0, commonUtil_1.replaceDots)(appVariantInfo.id);
|
|
15
|
+
for (const resource of appVariantResources) {
|
|
16
|
+
this.writeI18nToModule(resource, projectNamespace, i18nBundleName);
|
|
17
|
+
this.omitFiles(resource, taskUtil);
|
|
18
|
+
}
|
|
19
|
+
this.adjustAddNewModelEnhanceWith(appVariantInfo?.manifest?.content ?? [], i18nBundleName);
|
|
20
|
+
return appVariantInfo;
|
|
33
21
|
}
|
|
34
22
|
static getAppVariantResources(workspace) {
|
|
35
23
|
return workspace.byGlob(`/**/*.{${EXTENSIONS}}`);
|
|
36
24
|
}
|
|
37
|
-
static getAppVariantInfo(appVariantResources) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return { id, reference, manifest };
|
|
45
|
-
}
|
|
25
|
+
static async getAppVariantInfo(appVariantResources) {
|
|
26
|
+
for (const resource of appVariantResources) {
|
|
27
|
+
const basename = path.basename(resource.getPath());
|
|
28
|
+
if (basename === MANIFEST_APP_VARIANT) {
|
|
29
|
+
const manifest = await resource.getBuffer().then((buffer) => buffer.toString("utf8")).then(JSON.parse);
|
|
30
|
+
const { id, reference } = manifest;
|
|
31
|
+
return { id, reference, manifest };
|
|
46
32
|
}
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
}
|
|
34
|
+
throw new Error("Application variant should contain manifest.appdescr_variant");
|
|
49
35
|
}
|
|
50
36
|
static writeI18nToModule(resource, projectNamespace, i18nBundleName) {
|
|
51
37
|
if (path.extname(resource.getPath()) === ".properties") {
|
package/dist/baseAppManager.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { IAppVariantInfo, IAppVariantManifest, IProjectOptions } from "./model/types";
|
|
2
|
+
import IProcessor from "./processors/processor";
|
|
2
3
|
export default class BaseAppManager {
|
|
3
|
-
static process(baseAppFiles: Map<string, string>, appVariantInfo: IAppVariantInfo, options: IProjectOptions): Promise<any[]>;
|
|
4
|
-
private static
|
|
4
|
+
static process(baseAppFiles: Map<string, string>, appVariantInfo: IAppVariantInfo, options: IProjectOptions, processor: IProcessor): Promise<any[]>;
|
|
5
|
+
private static updateAdaptationProperties;
|
|
6
|
+
static getManifestInfo(manifest: any): {
|
|
7
|
+
id: string;
|
|
8
|
+
version: string;
|
|
9
|
+
};
|
|
5
10
|
static renameBaseApp(baseAppFiles: Map<string, string>, search: string, replacement: string): Map<string, string>;
|
|
6
11
|
private static getBaseAppManifest;
|
|
7
|
-
private static updateCloudPlatform;
|
|
8
12
|
private static fillAppVariantIdHierarchy;
|
|
9
|
-
|
|
13
|
+
static validateProperty(value: string, property: string): void;
|
|
10
14
|
static applyDescriptorChanges(baseAppManifest: any, appVariantManifest: IAppVariantManifest, i18nBundleName: string): Promise<void>;
|
|
11
15
|
static writeToWorkspace(baseAppFiles: Map<string, string>, projectNamespace: string): any[];
|
|
12
16
|
}
|
package/dist/baseAppManager.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const path = require("path");
|
|
13
4
|
const buildStrategy_1 = require("./buildStrategy");
|
|
@@ -17,24 +8,31 @@ const { RegistrationBuild, ApplyUtil, Applier, Change } = require("../dist/bundl
|
|
|
17
8
|
const resourceFactory = require("@ui5/fs/lib/resourceFactory");
|
|
18
9
|
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::BaseAppManager");
|
|
19
10
|
class BaseAppManager {
|
|
20
|
-
static process(baseAppFiles, appVariantInfo, options) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
static async process(baseAppFiles, appVariantInfo, options, processor) {
|
|
12
|
+
const baseAppManifest = this.getBaseAppManifest(baseAppFiles);
|
|
13
|
+
const { id, version } = this.getManifestInfo(baseAppManifest.content);
|
|
14
|
+
const renamedBaseAppFiles = this.renameBaseApp(baseAppFiles, appVariantInfo.reference, appVariantInfo.id);
|
|
15
|
+
const { filepath, content } = this.getBaseAppManifest(renamedBaseAppFiles);
|
|
16
|
+
await processor.updateLandscapeSpecificContent(content, renamedBaseAppFiles);
|
|
17
|
+
this.fillAppVariantIdHierarchy(processor, id, version, content);
|
|
18
|
+
this.updateAdaptationProperties(content);
|
|
19
|
+
const i18nBundleName = (0, commonUtil_1.replaceDots)(appVariantInfo.id);
|
|
20
|
+
await this.applyDescriptorChanges(content, appVariantInfo.manifest, i18nBundleName);
|
|
21
|
+
renamedBaseAppFiles.set(filepath, JSON.stringify(content));
|
|
22
|
+
return this.writeToWorkspace(renamedBaseAppFiles, options.projectNamespace);
|
|
23
|
+
}
|
|
24
|
+
static updateAdaptationProperties(content) {
|
|
25
|
+
if (content["sap.fiori"]?.cloudDevAdaptationStatus) {
|
|
26
|
+
delete content["sap.fiori"].cloudDevAdaptationStatus;
|
|
27
|
+
}
|
|
28
|
+
if (content["sap.ui5"] == null) {
|
|
29
|
+
content["sap.ui5"] = {};
|
|
30
|
+
}
|
|
31
|
+
content["sap.ui5"].isCloudDevAdaptation = true;
|
|
33
32
|
}
|
|
34
33
|
static getManifestInfo(manifest) {
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const version = (_c = (_b = manifest["sap.app"]) === null || _b === void 0 ? void 0 : _b.applicationVersion) === null || _c === void 0 ? void 0 : _c.version;
|
|
34
|
+
const id = manifest["sap.app"]?.id;
|
|
35
|
+
const version = manifest["sap.app"]?.applicationVersion?.version;
|
|
38
36
|
return { id, version };
|
|
39
37
|
}
|
|
40
38
|
static renameBaseApp(baseAppFiles, search, replacement) {
|
|
@@ -67,24 +65,7 @@ class BaseAppManager {
|
|
|
67
65
|
}
|
|
68
66
|
throw new Error("Original application should have manifest.json in root folder");
|
|
69
67
|
}
|
|
70
|
-
static
|
|
71
|
-
var _a;
|
|
72
|
-
const sapCloudService = (_a = baseAppManifest["sap.cloud"]) === null || _a === void 0 ? void 0 : _a.service;
|
|
73
|
-
const sapPlatformCf = baseAppManifest["sap.platform.cf"];
|
|
74
|
-
if (sapPlatformCf && sapCloudService) {
|
|
75
|
-
sapPlatformCf.oAuthScopes = sapPlatformCf.oAuthScopes.map((scope) => scope.replace(`$XSAPPNAME.`, `$XSAPPNAME('${sapCloudService}').`));
|
|
76
|
-
}
|
|
77
|
-
if (configuration.sapCloudService) {
|
|
78
|
-
if (baseAppManifest["sap.cloud"] == null) {
|
|
79
|
-
baseAppManifest["sap.cloud"] = {};
|
|
80
|
-
}
|
|
81
|
-
baseAppManifest["sap.cloud"].service = configuration.sapCloudService;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
delete baseAppManifest["sap.cloud"];
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
static fillAppVariantIdHierarchy(id, version, baseAppManifest) {
|
|
68
|
+
static fillAppVariantIdHierarchy(processor, id, version, baseAppManifest) {
|
|
88
69
|
log.verbose("Filling up app variant hierarchy in manifest.json");
|
|
89
70
|
this.validateProperty(id, "sap.app/id");
|
|
90
71
|
this.validateProperty(version, "sap.app/applicationVersion/version");
|
|
@@ -94,36 +75,30 @@ class BaseAppManager {
|
|
|
94
75
|
if (baseAppManifest["sap.ui5"].appVariantIdHierarchy == null) {
|
|
95
76
|
baseAppManifest["sap.ui5"].appVariantIdHierarchy = [];
|
|
96
77
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
version
|
|
100
|
-
});
|
|
78
|
+
const appVariantIdHierarchyItem = processor.createAppVariantHierarchyItem(id, version);
|
|
79
|
+
baseAppManifest["sap.ui5"].appVariantIdHierarchy.unshift(appVariantIdHierarchyItem);
|
|
101
80
|
}
|
|
102
81
|
static validateProperty(value, property) {
|
|
103
82
|
if (!value) {
|
|
104
83
|
throw new Error(`Original application manifest should have ${property}`);
|
|
105
84
|
}
|
|
106
85
|
}
|
|
107
|
-
static applyDescriptorChanges(baseAppManifest, appVariantManifest, i18nBundleName) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
yield Applier.applyChanges(baseAppManifest, changesContent, strategy);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
86
|
+
static async applyDescriptorChanges(baseAppManifest, appVariantManifest, i18nBundleName) {
|
|
87
|
+
log.verbose("Applying appVariant changes");
|
|
88
|
+
const strategy = new buildStrategy_1.default(RegistrationBuild, ApplyUtil, i18nBundleName);
|
|
89
|
+
if (appVariantManifest.layer) {
|
|
90
|
+
appVariantManifest.content?.forEach(item => item.layer = appVariantManifest.layer);
|
|
91
|
+
}
|
|
92
|
+
const changesContent = appVariantManifest.content?.map((change) => new Change(change));
|
|
93
|
+
if (changesContent) {
|
|
94
|
+
await Applier.applyChanges(baseAppManifest, changesContent, strategy);
|
|
95
|
+
}
|
|
120
96
|
}
|
|
121
97
|
static writeToWorkspace(baseAppFiles, projectNamespace) {
|
|
122
98
|
const IGNORE_FILES = [
|
|
123
99
|
"/manifest-bundle.zip",
|
|
124
100
|
"/Component-preload.js",
|
|
125
|
-
"/sap-ui-cachebuster-info.json"
|
|
126
|
-
`/${resourceUtil_1.default.METADATA_FILENAME}`
|
|
101
|
+
"/sap-ui-cachebuster-info.json"
|
|
127
102
|
];
|
|
128
103
|
const resources = [];
|
|
129
104
|
for (let filename of baseAppFiles.keys()) {
|
package/dist/buildStrategy.js
CHANGED
|
@@ -16,6 +16,9 @@ class BuildStrategy {
|
|
|
16
16
|
if (typeof manifest["sap.app"].i18n === "string") {
|
|
17
17
|
manifest["sap.app"].i18n = { bundleUrl: manifest["sap.app"].i18n };
|
|
18
18
|
}
|
|
19
|
+
if (manifest["sap.app"].i18n == null) {
|
|
20
|
+
manifest["sap.app"].i18n = {};
|
|
21
|
+
}
|
|
19
22
|
if (manifest["sap.app"].i18n.enhanceWith == null) {
|
|
20
23
|
manifest["sap.app"].i18n.enhanceWith = [];
|
|
21
24
|
}
|