@ui5/task-adaptation 1.0.21 → 1.1.0
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 +12 -1
- package/dist/annotationManager.d.ts +3 -4
- package/dist/annotationManager.js +20 -56
- package/dist/annotations/oDataModel.d.ts +20 -0
- package/dist/annotations/oDataModel.js +46 -0
- package/dist/annotations/oDataV2Model.d.ts +4 -0
- package/dist/annotations/oDataV2Model.js +13 -0
- package/dist/annotations/serviceRequestor.d.ts +17 -0
- package/dist/annotations/serviceRequestor.js +36 -0
- package/dist/appVariantManager.d.ts +0 -7
- package/dist/appVariantManager.js +2 -20
- package/dist/baseAppManager.d.ts +1 -0
- package/dist/baseAppManager.js +22 -5
- package/dist/i18nManager.d.ts +11 -10
- package/dist/i18nManager.js +19 -19
- package/dist/index.js +2 -0
- package/dist/model/language.d.ts +13 -0
- package/dist/model/language.js +37 -0
- package/dist/model/types.d.ts +1 -1
- package/dist/processors/abapProcessor.js +2 -2
- package/dist/repositories/abapRepoManager.js +2 -1
- package/dist/util/cfUtil.js +1 -1
- package/dist/util/commonUtil.d.ts +1 -0
- package/dist/util/commonUtil.js +13 -1
- package/dist/util/jsonDiffUtil.d.ts +14 -3
- package/dist/util/jsonDiffUtil.js +29 -9
- package/package.json +4 -3
- package/scripts/metadataDownloadHelper.ts +85 -0
- package/scripts/rollup.ts +0 -9
- package/dist/bundle-resourceBundle.js +0 -692
- package/scripts/rollup/bundleDefinition-resourceBundle.js +0 -5
- package/scripts/rollup/overrides/sap/base/i18n/Localization.js +0 -1
- package/scripts/rollup/overrides/sap/base/string/formatMessage.js +0 -1
- package/scripts/rollup/overrides/sap/base/util/Properties.js +0 -1
- package/scripts/rollup/overrides/sap/base/util/merge.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
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.1.0...HEAD).
|
|
6
|
+
|
|
7
|
+
<a name="v1.1.0"></a>
|
|
8
|
+
## [v1.1.0] - 2024-01-30
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
- Include app variant id in bundle name [`afab97a`](https://github.com/SAP/ui5-task-adaptation/commit/afab97a10867a58b6e96eb4310f288d29773cf66)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
<a name="v1.0.23"></a>
|
|
14
|
+
## [v1.0.23] - 2024-01-19
|
|
6
15
|
|
|
7
16
|
<a name="v1.0.21"></a>
|
|
8
17
|
## [v1.0.21] - 2024-01-03
|
|
@@ -64,6 +73,8 @@ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-task
|
|
|
64
73
|
<a name="v1.0.0"></a>
|
|
65
74
|
## v1.0.0 - 2020-12-09
|
|
66
75
|
|
|
76
|
+
[v1.1.0]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.23...v1.1.0
|
|
77
|
+
[v1.0.23]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.21...v1.0.23
|
|
67
78
|
[v1.0.21]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.20...v1.0.21
|
|
68
79
|
[v1.0.20]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.19...v1.0.20
|
|
69
80
|
[v1.0.19]: https://github.com/SAP/ui5-task-adaptation/compare/v1.0.18...v1.0.19
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import AbapRepoManager from "./repositories/abapRepoManager";
|
|
2
2
|
import { IConfiguration } from "./model/types";
|
|
3
|
+
import Language from "./model/language";
|
|
3
4
|
export interface IAnnotationFiles {
|
|
4
5
|
annotationName: string;
|
|
5
6
|
annotationFileName: string;
|
|
@@ -9,14 +10,12 @@ export default class AnnotationManager {
|
|
|
9
10
|
private configuration;
|
|
10
11
|
constructor(configuration: IConfiguration, abapRepoManager: AbapRepoManager);
|
|
11
12
|
ANNOTATIONS_FOLDER: string;
|
|
12
|
-
process(renamedBaseAppManifest: any, languages:
|
|
13
|
+
process(renamedBaseAppManifest: any, languages: Language[]): Promise<Map<string, string>>;
|
|
13
14
|
private normalizeAppVariantId;
|
|
14
15
|
private createAnnotationFile;
|
|
15
|
-
private downloadAnnotations;
|
|
16
16
|
private updateManifestModel;
|
|
17
17
|
private updateManifestDataSources;
|
|
18
18
|
private createManifestModel;
|
|
19
19
|
private enhanceManifestModel;
|
|
20
|
-
private
|
|
21
|
-
private getODataAnnotations;
|
|
20
|
+
private createODataModels;
|
|
22
21
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const annotationsCacheManager_1 = require("./cache/annotationsCacheManager");
|
|
4
3
|
const baseAppManager_1 = require("./baseAppManager");
|
|
5
4
|
const i18nManager_1 = require("./i18nManager");
|
|
5
|
+
const oDataV2Model_1 = require("./annotations/oDataV2Model");
|
|
6
|
+
const serviceRequestor_1 = require("./annotations/serviceRequestor");
|
|
6
7
|
const xmlUtil_1 = require("./util/xmlUtil");
|
|
7
8
|
const path_1 = require("path");
|
|
8
9
|
const I18N_DEFAULT_PATH = "i18n/annotations";
|
|
9
10
|
const I18N_DEFAULT_MODEL_NAME = "@i18n";
|
|
10
11
|
const SAPUI5 = "sap.ui5";
|
|
11
12
|
const SAPAPP = "sap.app";
|
|
12
|
-
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::AnnotationManager");
|
|
13
13
|
class AnnotationManager {
|
|
14
14
|
constructor(configuration, abapRepoManager) {
|
|
15
15
|
this.ANNOTATIONS_FOLDER = "annotations";
|
|
@@ -21,18 +21,19 @@ class AnnotationManager {
|
|
|
21
21
|
baseAppManager_1.default.validateProperty(id, "sap.app/id");
|
|
22
22
|
const normalisedId = this.normalizeAppVariantId(id);
|
|
23
23
|
//TODO: switch to this after resolving @i18n custom model
|
|
24
|
-
const oDataAnnotations = this.getODataAnnotations(renamedBaseAppManifest);
|
|
25
|
-
const promises = this.downloadAnnotations(oDataAnnotations, languages);
|
|
26
24
|
const modelName = I18N_DEFAULT_MODEL_NAME; //`i18n_a9n_${normalisedId}`;
|
|
27
25
|
const i18nPathName = path_1.posix.join(I18N_DEFAULT_PATH, normalisedId);
|
|
28
26
|
const annotationFiles = new Map();
|
|
29
27
|
const metaInfo = new Array();
|
|
30
28
|
const i18nManager = new i18nManager_1.default(modelName, id, languages);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
const oDataModels = this.createODataModels(renamedBaseAppManifest);
|
|
30
|
+
for (const oDataModel of oDataModels) {
|
|
31
|
+
for (const { annotationJsons, annotationName } of oDataModel.getAnnotationJsons(languages)) {
|
|
32
|
+
const annotationXml = await this.createAnnotationFile(await annotationJsons, i18nManager);
|
|
33
|
+
const annotationFileName = `annotations/annotation_${annotationName}.xml`;
|
|
34
|
+
annotationFiles.set(annotationFileName, annotationXml);
|
|
35
|
+
metaInfo.push({ annotationFileName, annotationName });
|
|
36
|
+
}
|
|
36
37
|
}
|
|
37
38
|
if (metaInfo.length > 0) {
|
|
38
39
|
this.updateManifestDataSources(renamedBaseAppManifest, metaInfo);
|
|
@@ -46,21 +47,10 @@ class AnnotationManager {
|
|
|
46
47
|
normalizeAppVariantId(id, replaceWith = "") {
|
|
47
48
|
return id.replace(/[.\W]+/gi, replaceWith);
|
|
48
49
|
}
|
|
49
|
-
async createAnnotationFile(
|
|
50
|
-
const annotationJsons = new Map();
|
|
51
|
-
for (const promise of promisesPerLanguage) {
|
|
52
|
-
const { language, xml } = await promise;
|
|
53
|
-
annotationJsons.set(language, xmlUtil_1.default.xmlToJson(xml));
|
|
54
|
-
}
|
|
50
|
+
async createAnnotationFile(annotationJsons, i18nManager) {
|
|
55
51
|
const annotationJson = i18nManager.populateTranslations(annotationJsons);
|
|
56
52
|
return xmlUtil_1.default.jsonToXml(annotationJson.json);
|
|
57
53
|
}
|
|
58
|
-
downloadAnnotations(annotations, languages) {
|
|
59
|
-
return [...annotations].map(([name, { uri }]) => ({
|
|
60
|
-
promisesPerLanguage: languages.map(language => this.downloadAnnotation(uri, name, language)),
|
|
61
|
-
annotationName: name
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
54
|
updateManifestModel(renamedBaseAppManifest, modelName, i18nPathName) {
|
|
65
55
|
const uri = `${i18nPathName}/i18n.properties`;
|
|
66
56
|
this.enhanceManifestModel(renamedBaseAppManifest, modelName, uri);
|
|
@@ -107,44 +97,18 @@ class AnnotationManager {
|
|
|
107
97
|
this.createManifestModel(manifest, modelToEnhance, bundleUrl);
|
|
108
98
|
}
|
|
109
99
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
const cacheManager = new annotationsCacheManager_1.default(this.configuration, cacheFilename);
|
|
118
|
-
log.verbose(`Getting annotation '${name}' ${language} by '${annotationUri}'`);
|
|
119
|
-
try {
|
|
120
|
-
let files;
|
|
121
|
-
if (this.configuration.enableAnnotationCache) {
|
|
122
|
-
files = await cacheManager.getFiles(() => this.abapRepoManager.getAnnotationMetadata(annotationUri), () => this.abapRepoManager.downloadAnnotationFile(annotationUri));
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
files = await this.abapRepoManager.downloadAnnotationFile(annotationUri);
|
|
126
|
-
}
|
|
127
|
-
if (!files || files.size === 0) {
|
|
128
|
-
throw new Error(`No files were fetched for '${name}' by '${annotationUri}'`);
|
|
129
|
-
}
|
|
130
|
-
return { language, xml: [...files][0][1] };
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
throw new Error(`Failed to fetch annotation '${name}' by '${annotationUri}': ${error.message}`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
getODataAnnotations(renamedBaseAppManifest) {
|
|
137
|
-
const oDataAnnotations = new Map();
|
|
138
|
-
const dataSources = renamedBaseAppManifest[SAPAPP]?.dataSources;
|
|
100
|
+
createODataModels(renamedBaseAppManifest) {
|
|
101
|
+
const serviceRequestor = new serviceRequestor_1.default(this.configuration, this.abapRepoManager);
|
|
102
|
+
const oDataModels = [
|
|
103
|
+
new oDataV2Model_1.default(serviceRequestor)
|
|
104
|
+
];
|
|
105
|
+
const dataSources = renamedBaseAppManifest["sap.app"]?.dataSources;
|
|
139
106
|
if (dataSources) {
|
|
140
|
-
for (const
|
|
141
|
-
|
|
142
|
-
if (annotation?.type === "ODataAnnotation" && annotation?.uri?.startsWith("/")) {
|
|
143
|
-
oDataAnnotations.set(key, dataSources[key]);
|
|
144
|
-
}
|
|
107
|
+
for (const name of Object.keys(dataSources)) {
|
|
108
|
+
oDataModels.forEach(model => model.addDataSource(dataSources[name], name));
|
|
145
109
|
}
|
|
146
110
|
}
|
|
147
|
-
return
|
|
111
|
+
return oDataModels;
|
|
148
112
|
}
|
|
149
113
|
}
|
|
150
114
|
exports.default = AnnotationManager;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import ServiceRequestor, { ILanguageJsonContent, ILanguageXmlContent } from "./serviceRequestor";
|
|
2
|
+
import Language from "../model/language";
|
|
3
|
+
export default class ODataModel {
|
|
4
|
+
protected oDataAnnotations: Map<string, any>;
|
|
5
|
+
private serviceRequestor;
|
|
6
|
+
constructor(serviceRequestor: ServiceRequestor);
|
|
7
|
+
getAnnotationJsons(languages: Language[]): AnnotationJsonPerName[];
|
|
8
|
+
private getPromisesPerLanguage;
|
|
9
|
+
private createAnnotationJsons;
|
|
10
|
+
protected afterXmlDownload({ language, xml }: ILanguageXmlContent): Promise<ILanguageJsonContent>;
|
|
11
|
+
protected transformJsons(annotationJsons: Map<Language, any>): Promise<Map<Language, any>>;
|
|
12
|
+
}
|
|
13
|
+
export interface PromisePerAnnotation {
|
|
14
|
+
promisesPerLanguage: Promise<ILanguageXmlContent>[];
|
|
15
|
+
annotationName: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AnnotationJsonPerName {
|
|
18
|
+
annotationName: string;
|
|
19
|
+
annotationJsons: Promise<Map<Language, any>>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const xmlUtil_1 = require("../util/xmlUtil");
|
|
4
|
+
class ODataModel {
|
|
5
|
+
constructor(serviceRequestor) {
|
|
6
|
+
this.oDataAnnotations = new Map();
|
|
7
|
+
this.serviceRequestor = serviceRequestor;
|
|
8
|
+
}
|
|
9
|
+
getAnnotationJsons(languages) {
|
|
10
|
+
const result = [];
|
|
11
|
+
const promisesPerLanguagePerName = this.getPromisesPerLanguage(languages);
|
|
12
|
+
for (const { promisesPerLanguage, annotationName } of promisesPerLanguagePerName) {
|
|
13
|
+
result.push({
|
|
14
|
+
annotationName,
|
|
15
|
+
annotationJsons: this.createAnnotationJsons(promisesPerLanguage)
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
getPromisesPerLanguage(languages) {
|
|
21
|
+
return [...this.oDataAnnotations].map(([annotationName, uri]) => ({
|
|
22
|
+
promisesPerLanguage: languages.map(language => this.serviceRequestor.downloadAnnotation(uri, annotationName, language)
|
|
23
|
+
.then(this.afterXmlDownload)),
|
|
24
|
+
annotationName
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
async createAnnotationJsons(promisesPerLanguage) {
|
|
28
|
+
const annotationJsons = new Map();
|
|
29
|
+
for (const promise of promisesPerLanguage) {
|
|
30
|
+
const { language, json } = await promise;
|
|
31
|
+
annotationJsons.set(language, json);
|
|
32
|
+
}
|
|
33
|
+
return this.transformJsons(annotationJsons);
|
|
34
|
+
}
|
|
35
|
+
async afterXmlDownload({ language, xml }) {
|
|
36
|
+
return {
|
|
37
|
+
json: xmlUtil_1.default.xmlToJson(xml),
|
|
38
|
+
language
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async transformJsons(annotationJsons) {
|
|
42
|
+
return annotationJsons;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = ODataModel;
|
|
46
|
+
//# sourceMappingURL=oDataModel.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const oDataModel_1 = require("./oDataModel");
|
|
4
|
+
class ODataV2Model extends oDataModel_1.default {
|
|
5
|
+
addDataSource({ uri, type }, name) {
|
|
6
|
+
if (uri?.startsWith("/") &&
|
|
7
|
+
type === "ODataAnnotation") {
|
|
8
|
+
this.oDataAnnotations.set(name, uri);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.default = ODataV2Model;
|
|
13
|
+
//# sourceMappingURL=oDataV2Model.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import AbapRepoManager from "../repositories/abapRepoManager";
|
|
2
|
+
import { IConfiguration } from "../model/types";
|
|
3
|
+
import Language from "../model/language";
|
|
4
|
+
export interface ILanguageXmlContent {
|
|
5
|
+
language: Language;
|
|
6
|
+
xml: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ILanguageJsonContent {
|
|
9
|
+
language: Language;
|
|
10
|
+
json: any;
|
|
11
|
+
}
|
|
12
|
+
export default class ServiceRequestor {
|
|
13
|
+
private abapRepoManager;
|
|
14
|
+
private configuration;
|
|
15
|
+
constructor(configuration: IConfiguration, abapRepoManager: AbapRepoManager);
|
|
16
|
+
downloadAnnotation(uri: string, name: string, language: Language): Promise<ILanguageXmlContent>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const annotationsCacheManager_1 = require("../cache/annotationsCacheManager");
|
|
4
|
+
const log = require("@ui5/logger").getLogger("@ui5/task-adaptation::ServiceRequestor");
|
|
5
|
+
class ServiceRequestor {
|
|
6
|
+
constructor(configuration, abapRepoManager) {
|
|
7
|
+
this.abapRepoManager = abapRepoManager;
|
|
8
|
+
this.configuration = configuration;
|
|
9
|
+
}
|
|
10
|
+
async downloadAnnotation(uri, name, language) {
|
|
11
|
+
if (language.sap) {
|
|
12
|
+
uri += `?sap-language=${language.sap}`;
|
|
13
|
+
name += `-${language.sap}`;
|
|
14
|
+
}
|
|
15
|
+
const cacheManager = new annotationsCacheManager_1.default(this.configuration, name);
|
|
16
|
+
log.verbose(`Getting annotation '${name}' ${language.sap} by '${uri}'`);
|
|
17
|
+
try {
|
|
18
|
+
let files;
|
|
19
|
+
if (this.configuration.enableAnnotationCache) {
|
|
20
|
+
files = await cacheManager.getFiles(() => this.abapRepoManager.getAnnotationMetadata(uri), () => this.abapRepoManager.downloadAnnotationFile(uri));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
files = await this.abapRepoManager.downloadAnnotationFile(uri);
|
|
24
|
+
}
|
|
25
|
+
if (!files || files.size === 0) {
|
|
26
|
+
throw new Error(`No files were fetched for '${name}' by '${uri}'`);
|
|
27
|
+
}
|
|
28
|
+
return { language, xml: [...files][0][1] };
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`Failed to fetch annotation by '${uri}': ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = ServiceRequestor;
|
|
36
|
+
//# sourceMappingURL=serviceRequestor.js.map
|
|
@@ -7,11 +7,4 @@ export default class AppVariantManager {
|
|
|
7
7
|
private static isManifestAppVariant;
|
|
8
8
|
static getAppVariantInfo(appVariantResources: any[]): Promise<IAppVariantInfo>;
|
|
9
9
|
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
10
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
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
|
|
5
|
+
const commonUtil_1 = require("./util/commonUtil");
|
|
7
6
|
const EXTENSIONS = "js,json,xml,html,properties,change,appdescr_variant";
|
|
8
7
|
class AppVariantManager {
|
|
9
8
|
static async process(appVariantResources, projectNamespace, taskUtil) {
|
|
@@ -11,7 +10,6 @@ class AppVariantManager {
|
|
|
11
10
|
for (const resource of appVariantResources) {
|
|
12
11
|
this.omitFiles(resource, taskUtil);
|
|
13
12
|
}
|
|
14
|
-
this.patchMissingTextsNode(appVariantInfo?.manifest?.content ?? []);
|
|
15
13
|
await this.renameChanges(appVariantResources, projectNamespace, appVariantInfo);
|
|
16
14
|
return appVariantInfo;
|
|
17
15
|
}
|
|
@@ -25,7 +23,7 @@ class AppVariantManager {
|
|
|
25
23
|
for (const resource of appVariantResources) {
|
|
26
24
|
const resourcePath = resource.getPath();
|
|
27
25
|
const basename = path_1.posix.dirname(resourcePath);
|
|
28
|
-
if (changesFolder
|
|
26
|
+
if (basename.startsWith(changesFolder)) {
|
|
29
27
|
changes.set(resourcePath, await resourceUtil_1.default.getString(resource));
|
|
30
28
|
resourcesByPath.set(resourcePath, resource);
|
|
31
29
|
}
|
|
@@ -73,22 +71,6 @@ class AppVariantManager {
|
|
|
73
71
|
taskUtil.setTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult, true);
|
|
74
72
|
}
|
|
75
73
|
}
|
|
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 };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
74
|
}
|
|
93
75
|
exports.default = AppVariantManager;
|
|
94
76
|
//# sourceMappingURL=appVariantManager.js.map
|
package/dist/baseAppManager.d.ts
CHANGED
|
@@ -23,5 +23,6 @@ export default class BaseAppManager {
|
|
|
23
23
|
private static fillAppVariantIdHierarchy;
|
|
24
24
|
static validateProperty(value: string, property: string): void;
|
|
25
25
|
static applyDescriptorChanges(baseAppManifest: any, appVariantInfo: IAppVariantInfo): Promise<void>;
|
|
26
|
+
private static adjustAddNewModelEnhanceWith;
|
|
26
27
|
static writeToWorkspace(baseAppFiles: Map<string, string>, projectNamespace: string): any[];
|
|
27
28
|
}
|
package/dist/baseAppManager.js
CHANGED
|
@@ -12,7 +12,7 @@ class BaseAppManager {
|
|
|
12
12
|
static async process(baseAppFiles, appVariantInfo, options, processor) {
|
|
13
13
|
const baseAppManifest = this.getBaseAppManifest(baseAppFiles);
|
|
14
14
|
const { id, version } = this.getIdVersion(baseAppManifest.content);
|
|
15
|
-
const renamedBaseAppFiles = (0,
|
|
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,
|
|
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"));
|
|
@@ -94,14 +94,31 @@ class BaseAppManager {
|
|
|
94
94
|
...manifest.content,
|
|
95
95
|
...appVariantInfo.manifestChanges
|
|
96
96
|
];
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
const changesContent = new Array();
|
|
98
|
+
const i18nBundleName = (0, commonUtil_1.dotToUnderscore)(appVariantInfo.id);
|
|
99
|
+
for (const change of structuredClone(allChanges)) {
|
|
100
|
+
if (manifest.layer) {
|
|
101
|
+
change.layer = manifest.layer;
|
|
102
|
+
}
|
|
103
|
+
this.adjustAddNewModelEnhanceWith(change, i18nBundleName);
|
|
104
|
+
changesContent.push(new Change(change));
|
|
99
105
|
}
|
|
100
|
-
const changesContent = allChanges.map(change => new Change(change));
|
|
101
106
|
if (changesContent.length > 0) {
|
|
102
107
|
await Applier.applyChanges(baseAppManifest, changesContent, strategy);
|
|
103
108
|
}
|
|
104
109
|
}
|
|
110
|
+
static adjustAddNewModelEnhanceWith(change, i18nBundleName) {
|
|
111
|
+
if (change.changeType === "appdescr_ui5_addNewModelEnhanceWith") {
|
|
112
|
+
if (change.texts == null) {
|
|
113
|
+
// We need to add texts properties to changes because not all
|
|
114
|
+
// have texts property. Changes without texts property can
|
|
115
|
+
// causes issues in bundle.js This is needed for now, and will
|
|
116
|
+
// be removed as soon as change merger in openUI5 is updated
|
|
117
|
+
change.texts = { i18n: change.content?.bundleUrl || "i18n/i18n.properties" };
|
|
118
|
+
}
|
|
119
|
+
change.texts.i18n = i18nBundleName + "/" + change.texts.i18n;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
105
122
|
static writeToWorkspace(baseAppFiles, projectNamespace) {
|
|
106
123
|
const IGNORE_FILES = [
|
|
107
124
|
"/manifest-bundle.zip",
|
package/dist/i18nManager.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { IDiffProperty, IJsonContent } from "./util/jsonDiffUtil";
|
|
2
|
+
import Language from "./model/language";
|
|
2
3
|
export declare class PropertyValue {
|
|
3
4
|
value: string;
|
|
4
5
|
isReference: boolean;
|
|
5
6
|
qualifier: string;
|
|
6
|
-
language:
|
|
7
|
+
language: Language;
|
|
7
8
|
private static OLD;
|
|
8
9
|
private static NEW;
|
|
9
10
|
private constructor();
|
|
10
11
|
get isOld(): boolean;
|
|
11
12
|
set(diff: any, references: Map<string, string>): void;
|
|
12
|
-
static oldFrom(language:
|
|
13
|
-
static newFrom(language:
|
|
13
|
+
static oldFrom(language: Language, value?: string): PropertyValue;
|
|
14
|
+
static newFrom(language: Language, value?: string): PropertyValue;
|
|
14
15
|
}
|
|
15
16
|
export declare class I18nFileContent {
|
|
16
17
|
private properties;
|
|
17
|
-
constructor(languages:
|
|
18
|
+
constructor(languages: Language[]);
|
|
18
19
|
add(prop: PropertyValue, key: string): void;
|
|
19
20
|
private initKeyValuesForOtherLanguages;
|
|
20
21
|
hasTranslations(): boolean;
|
|
@@ -27,15 +28,15 @@ export default class I18nManager {
|
|
|
27
28
|
private references;
|
|
28
29
|
private existingKeys;
|
|
29
30
|
private i18nFileContent;
|
|
30
|
-
constructor(modelName: string, appVariantId: string, languages:
|
|
31
|
-
processDiff(properties: Set<IDiffProperty>, previousLanguage:
|
|
31
|
+
constructor(modelName: string, appVariantId: string, languages: Language[]);
|
|
32
|
+
processDiff(properties: Set<IDiffProperty>, previousLanguage: Language, currentLanguage: Language): void;
|
|
32
33
|
createFiles(i18nPathName: string): Map<string, string>;
|
|
33
|
-
populateTranslations(annotationJsons: Map<
|
|
34
|
-
populate(annotationJsons: [
|
|
35
|
-
language:
|
|
34
|
+
populateTranslations(annotationJsons: Map<Language, any>): IJsonContent;
|
|
35
|
+
populate(annotationJsons: [Language, any][], defaultAnnotation: IJsonContent): {
|
|
36
|
+
language: Language;
|
|
36
37
|
json: any;
|
|
37
38
|
};
|
|
38
|
-
static extractDefaultLanguageAnnotation(annotationJsons: Map<
|
|
39
|
+
static extractDefaultLanguageAnnotation(annotationJsons: Map<Language, any>): IJsonContent;
|
|
39
40
|
private replaceWithModelReference;
|
|
40
41
|
private createReference;
|
|
41
42
|
getUniqueKeyForValue(value: string): string;
|
package/dist/i18nManager.js
CHANGED
|
@@ -6,7 +6,6 @@ const annotationDiffStructureError_1 = require("./model/annotationDiffStructureE
|
|
|
6
6
|
const posix_1 = require("path/posix"); // Ensure standardized dir separators to ensure Windows compatibility
|
|
7
7
|
// To generate keys, english language is more common, so compare all other
|
|
8
8
|
// languages with it
|
|
9
|
-
const DEFAULT_LANGUAGES = ["", "EN", "EN_US", "EN_GB"];
|
|
10
9
|
class PropertyValue {
|
|
11
10
|
constructor(qualifier, language, value) {
|
|
12
11
|
this.isReference = false;
|
|
@@ -71,8 +70,8 @@ class I18nFileContent {
|
|
|
71
70
|
if (this.hasTranslations()) {
|
|
72
71
|
this.properties.forEach((i18nLines, language) => {
|
|
73
72
|
let filename = "i18n";
|
|
74
|
-
if (language) {
|
|
75
|
-
filename += "_" + language.
|
|
73
|
+
if (language.i18n) {
|
|
74
|
+
filename += "_" + language.i18n;
|
|
76
75
|
}
|
|
77
76
|
const filepath = (0, posix_1.join)(i18nPathName, filename + ".properties");
|
|
78
77
|
files.set(filepath, [...i18nLines].map(([key, value]) => `${key}=${value}`).join("\n"));
|
|
@@ -143,7 +142,7 @@ class I18nManager {
|
|
|
143
142
|
}
|
|
144
143
|
catch (error) {
|
|
145
144
|
if (error instanceof annotationDiffStructureError_1.default) {
|
|
146
|
-
throw new Error(`The structure of the oData annotation xml of language '${p.language}' is different from xml of language '${c.language}' near element: ${error.message}`);
|
|
145
|
+
throw new Error(`The structure of the oData annotation xml of language '${p.language.sap}' is different from xml of language '${c.language.sap}' near element: ${error.message}`);
|
|
147
146
|
}
|
|
148
147
|
throw error;
|
|
149
148
|
}
|
|
@@ -151,9 +150,8 @@ class I18nManager {
|
|
|
151
150
|
}
|
|
152
151
|
static extractDefaultLanguageAnnotation(annotationJsons) {
|
|
153
152
|
let json = null;
|
|
154
|
-
for (const language of
|
|
155
|
-
|
|
156
|
-
if (json != null) {
|
|
153
|
+
for (const [language, json] of annotationJsons) {
|
|
154
|
+
if (language.isDefault) {
|
|
157
155
|
annotationJsons.delete(language);
|
|
158
156
|
return { json, language };
|
|
159
157
|
}
|
|
@@ -163,18 +161,20 @@ class I18nManager {
|
|
|
163
161
|
annotationJsons.delete(language);
|
|
164
162
|
return { json, language };
|
|
165
163
|
}
|
|
166
|
-
replaceWithModelReference({ object, property }, propertyValues) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
164
|
+
replaceWithModelReference({ object, property, type }, propertyValues) {
|
|
165
|
+
if (type === jsonDiffUtil_1.DiffTypeEnum.DELTA) {
|
|
166
|
+
const diff = object[property];
|
|
167
|
+
this.initPropertyValues(diff, propertyValues);
|
|
168
|
+
// If there are already generated key, like on step 3. above comment, we
|
|
169
|
+
// take it (from __old), so we don't need to generate new
|
|
170
|
+
const propReference = propertyValues.find(prop => prop.isReference);
|
|
171
|
+
let reference = propReference?.value ?? this.createReference(diff.__old);
|
|
172
|
+
object[property] = reference;
|
|
173
|
+
// Other values, which are not references, are extracted to .properties
|
|
174
|
+
const key = this.references.get(reference);
|
|
175
|
+
if (key) {
|
|
176
|
+
propertyValues.filter(prop => !prop.isReference).forEach(prop => this.i18nFileContent.add(prop, key));
|
|
177
|
+
}
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
createReference(value) {
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,14 @@ const appVariantManager_1 = require("./appVariantManager");
|
|
|
5
5
|
const baseAppManager_1 = require("./baseAppManager");
|
|
6
6
|
const processor_1 = require("./processors/processor");
|
|
7
7
|
const i18nMerger_1 = require("./util/i18nMerger");
|
|
8
|
+
const commonUtil_1 = require("./util/commonUtil");
|
|
8
9
|
/**
|
|
9
10
|
* Creates an appVariant bundle from the provided resources.
|
|
10
11
|
*/
|
|
11
12
|
module.exports = ({ workspace, options, taskUtil }) => {
|
|
12
13
|
dotenv.config();
|
|
13
14
|
async function process(workspace, taskUtil) {
|
|
15
|
+
await (0, commonUtil_1.logBuilderVersion)();
|
|
14
16
|
const processor = (0, processor_1.determineProcessor)(options.configuration);
|
|
15
17
|
const appVariantResources = await appVariantManager_1.default.getAppVariantResources(workspace);
|
|
16
18
|
const appVariantInfo = await appVariantManager_1.default.process(appVariantResources, options.projectNamespace, taskUtil);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default class Language {
|
|
2
|
+
sap: string;
|
|
3
|
+
i18n: string;
|
|
4
|
+
isDefault: boolean;
|
|
5
|
+
constructor(sap: string, i18n: string);
|
|
6
|
+
/**
|
|
7
|
+
* Create a language array from languages in configuration and default language.
|
|
8
|
+
* @param languages Typically an array of objects. Probably could be undefined.
|
|
9
|
+
* @returns An array of type Language, where the default language is placed first,
|
|
10
|
+
* followed by the passed config languages.
|
|
11
|
+
*/
|
|
12
|
+
static create(languages: any[] | undefined): Language[];
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class Language {
|
|
4
|
+
constructor(sap, i18n) {
|
|
5
|
+
this.sap = sap;
|
|
6
|
+
this.i18n = i18n;
|
|
7
|
+
this.isDefault = sap === "";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a language array from languages in configuration and default language.
|
|
11
|
+
* @param languages Typically an array of objects. Probably could be undefined.
|
|
12
|
+
* @returns An array of type Language, where the default language is placed first,
|
|
13
|
+
* followed by the passed config languages.
|
|
14
|
+
*/
|
|
15
|
+
static create(languages) {
|
|
16
|
+
const defaultLanguage = new Language("", "");
|
|
17
|
+
let configLanguages = [];
|
|
18
|
+
if (languages !== undefined) {
|
|
19
|
+
configLanguages = languages.map(item => {
|
|
20
|
+
if (typeof item === 'string') {
|
|
21
|
+
// For legacy language format support which is just a string and doesn't contain i18n
|
|
22
|
+
return new Language(item, item.toLowerCase());
|
|
23
|
+
}
|
|
24
|
+
else if (item.sap !== undefined && item.i18n !== undefined) {
|
|
25
|
+
return new Language(item.sap, item.i18n);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error("Can not parse languages from ui5.yaml configuration. Please use the 'AdaptationProject: Create wizard' to generate the project.");
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return [defaultLanguage, ...configLanguages];
|
|
33
|
+
}
|
|
34
|
+
;
|
|
35
|
+
}
|
|
36
|
+
exports.default = Language;
|
|
37
|
+
//# sourceMappingURL=language.js.map
|
package/dist/model/types.d.ts
CHANGED