@ui5/task-adaptation
Version:
Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment
139 lines • 6.59 kB
JavaScript
import { Applier, AppDescriptorChange, RegistrationBuild } from "../dist/bundle.js";
import { dotToUnderscore, removePropertiesExtension } from "./util/commonUtil.js";
import BuildStrategy from "./buildStrategy.js";
import ResourceUtil from "./util/resourceUtil.js";
import { getLogger } from "@ui5/logger";
import { renameResources } from "./util/commonUtil.js";
const log = getLogger("@ui5/task-adaptation::BaseAppManager");
export default class BaseAppManager {
static async process(baseAppFiles, appVariantInfo, options, processor) {
const baseAppManifest = this.getBaseAppManifest(baseAppFiles);
const { id, version } = this.getIdVersion(baseAppManifest.content);
this.validateProperty(id, "sap.app/id");
this.validateProperty(version, "sap.app/applicationVersion/version");
const renamedBaseAppFiles = renameResources(baseAppFiles, appVariantInfo.reference, appVariantInfo.id);
const { filepath, content } = this.getBaseAppManifest(renamedBaseAppFiles);
await processor.updateLandscapeSpecificContent(content, renamedBaseAppFiles);
this.fillAppVariantIdHierarchy(processor, id, version, content);
this.updateAdaptationProperties(content);
await this.applyDescriptorChanges(content, appVariantInfo);
renamedBaseAppFiles.set(filepath, JSON.stringify(content));
return {
resources: this.writeToWorkspace(renamedBaseAppFiles, options.projectNamespace),
manifestInfo: this.getManifestInfo(content)
};
}
static updateAdaptationProperties(content) {
if (content["sap.fiori"]?.cloudDevAdaptationStatus) {
delete content["sap.fiori"].cloudDevAdaptationStatus;
}
if (content["sap.ui5"] == null) {
content["sap.ui5"] = {};
}
content["sap.ui5"].isCloudDevAdaptation = true;
}
static getIdVersion(manifest) {
const id = manifest["sap.app"]?.id;
const version = manifest["sap.app"]?.applicationVersion?.version;
return { id, version };
}
static getManifestInfo(manifest) {
const { id, version } = this.getIdVersion(manifest);
const i18nNode = manifest["sap.app"]?.i18n;
const i18nPath = this.extractI18nPathFromManifest(id, i18nNode);
return { id, version, i18nPath };
}
static extractI18nPathFromManifest(sapAppId, i18nNode) {
if (typeof i18nNode === "object") {
return i18nNode["bundleUrl"] ? this.extractI18NFromBundleUrl(i18nNode) : this.extractI18NFromBundleName(i18nNode, sapAppId);
}
else {
return `${sapAppId?.replaceAll(".", "/")}/${i18nNode}`;
}
}
static extractI18NFromBundleName(i18nNode, sapAppId) {
return i18nNode["bundleName"].replace(sapAppId, "").replaceAll(".", "/").substring(1);
}
static extractI18NFromBundleUrl(i18nNode) {
return removePropertiesExtension(i18nNode["bundleUrl"]);
}
static getBaseAppManifest(baseAppFiles) {
const manifestContent = baseAppFiles.get("manifest.json");
if (manifestContent) {
return {
content: JSON.parse(manifestContent),
filepath: "manifest.json"
};
}
throw new Error("Original application should have manifest.json in root folder");
}
static fillAppVariantIdHierarchy(processor, id, version, baseAppManifest) {
log.verbose("Filling up app variant hierarchy in manifest.json");
if (baseAppManifest["sap.ui5"] == null) {
baseAppManifest["sap.ui5"] = {};
}
if (baseAppManifest["sap.ui5"].appVariantIdHierarchy == null) {
baseAppManifest["sap.ui5"].appVariantIdHierarchy = [];
}
const appVariantIdHierarchyItem = processor.createAppVariantHierarchyItem(id, version);
baseAppManifest["sap.ui5"].appVariantIdHierarchy.unshift(appVariantIdHierarchyItem);
}
static VALIDATION_RULES = new Map([["sap.app/id", (value) => {
if (!value.includes(".")) {
throw new Error(`The original application id '${value}' should consist of multiple segments split by dot, e.g.: original.id`);
}
}]]);
static validateProperty(value, property) {
if (!value) {
throw new Error(`Original application manifest should have ${property}`);
}
let validatationRule = this.VALIDATION_RULES.get(property);
if (validatationRule) {
validatationRule(value);
}
}
static async applyDescriptorChanges(baseAppManifest, { layer, changes, id }) {
log.verbose("Applying appVariant changes");
const changesContent = new Array();
const i18nBundleName = dotToUnderscore(id);
for (const change of structuredClone(changes)) {
if (layer) {
change.layer = layer;
}
changesContent.push(new AppDescriptorChange(change));
this.adjustAddNewModelEnhanceWith(change, i18nBundleName);
}
if (changesContent.length > 0) {
const strategy = new BuildStrategy(RegistrationBuild);
await Applier.applyChanges(baseAppManifest, changesContent, strategy);
}
}
static adjustAddNewModelEnhanceWith(change, i18nBundleName) {
if (change.changeType === "appdescr_ui5_addNewModelEnhanceWith") {
if (change.texts == null) {
// We need to add texts properties to changes because not all
// have texts property. Changes without texts property can
// causes issues in bundle.js This is needed for now, and will
// be removed as soon as change merger in openUI5 is updated
change.texts = { i18n: change.content?.bundleUrl || "i18n/i18n.properties" };
}
change.texts.i18n = i18nBundleName + "/" + change.texts.i18n;
}
}
static writeToWorkspace(baseAppFiles, projectNamespace) {
const IGNORE_FILES = [
"manifest-bundle.zip",
"Component-preload.js",
"sap-ui-cachebuster-info.json"
];
const resources = [];
for (let filename of baseAppFiles.keys()) {
if (!IGNORE_FILES.includes(filename)) {
const resource = ResourceUtil.createResource(filename, projectNamespace, baseAppFiles.get(filename));
resources.push(resource);
}
}
return resources;
}
}
//# sourceMappingURL=baseAppManager.js.map