UNPKG

@ui5/task-adaptation

Version:

Custom task for ui5-builder which allows building UI5 Flexibility Adaptation Projects for SAP BTP, Cloud Foundry environment

66 lines 3.63 kB
import MetadataJsonUtil from "../converter/metadataJsonUtil.js"; import DataSourceODataAnnotation from "../dataSource/dataSourceODataAnnotation.js"; import UrlUtil from "../../util/urlUtil.js"; export default class TraverseReferences { metadataUrl; constructor(metadataUrl) { this.metadataUrl = metadataUrl; } async transform({ json, language, serviceRequestor, uri: parentUrl }) { const references = MetadataJsonUtil.getReferences(json).filter(TraverseReferences.isTraversable); const promises = []; for (const { includes, uri: relativeUrl } of references) { const resourcePath = UrlUtil.getResourcePath(relativeUrl); const absoluteUrl = UrlUtil.join(resourcePath, parentUrl); if (this.shouldIgnoreUrl(absoluteUrl, [parentUrl, this.metadataUrl])) { // If reference to metadata or its parent, don't traverse continue; } const name = includes[0]?.namespace; const dataSource = new DataSourceODataAnnotation(name, absoluteUrl, {}, this.metadataUrl); promises.push(dataSource.downloadAnnotation(language, serviceRequestor) .then(childAnnotation => ({ name, childAnnotation }))); } const childAnnotations = await Promise.all(promises); for (const { childAnnotation } of childAnnotations) { this.mergeAnnotations(json, childAnnotation); } return json; } shouldIgnoreUrl(referenceUrl, urlsToIgnore) { const toResourcePath = (url) => url && UrlUtil.getResourcePath(url); const isEqual = (a, b) => a && b && a.toLowerCase() === b.toLowerCase(); return urlsToIgnore.map(toResourcePath).some(url => isEqual(referenceUrl, url)); } mergeAnnotations(parentJson, nestedJson) { const parentAnnotations = MetadataJsonUtil.getAnnotations(parentJson); const parentMapByTarget = MetadataJsonUtil.mapAnnotationsPerTarget(parentJson); const nestedMapByTarget = MetadataJsonUtil.mapAnnotationsPerTarget(nestedJson); for (const nested of [...nestedMapByTarget].map(([target, { json }]) => ({ target, json }))) { // If we found parent annotation with the same target - we extend it // with missing <Annotation> nodes. If not, just add it to the end. // Annotations do not have a merge logic If same target & term is in // parent and nested, parent wins (same logic as UI5 in // sap/ui/model/odata/v4/ODataMetaModel.js mergeAnnotations). const parent = parentMapByTarget.get(nested.target); if (parent) { MetadataJsonUtil.toArrayTransform(parent.json, "Annotation"); const parentTerms = parent.json.Annotation.map((item) => item._attributes.Term); for (const nestedAnnotation of MetadataJsonUtil.toArrayReadOnly(nested.json.Annotation)) { if (!parentTerms.includes(nestedAnnotation._attributes.Term)) { parent.json.Annotation.push(nestedAnnotation); } } } else { parentAnnotations.push(nested.json); } } MetadataJsonUtil.setAnnotations(parentJson, parentAnnotations); } static isTraversable(reference) { const IGNORED_NAMESPACES = ["com.sap.vocabularies.", "Org.OData."]; return !reference.includes.some(include => IGNORED_NAMESPACES.some(namespace => include.namespace.startsWith(namespace))); } } //# sourceMappingURL=traverseReferences.js.map