UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

295 lines (255 loc) 9.56 kB
/*! * OpenUI5 * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ sap.ui.define(['sap/base/util/LoaderExtensions'], function (LoaderExtensions) { "use strict"; /** * @alias module:sap/ui/VersionInfo * @namespace * @since 1.56.0 * @public */ var VersionInfo = {}; /** * Loads the version info asynchronously from resource "sap-ui-version.json". * * By default, the returned promise will resolve with the whole version info file's content. * If a library name is specified in the options, then the promise will resolve with the * version info for that library only or with <code>undefined</code>, if the named library * is not listed in the version info file. * * If loading the version info file fails, the promise will be rejected with the corresponding * error. * * @param {object} [mOptions] Map of options * @param {string} [mOptions.library] Name of a library (e.g. "sap.ui.core") * @returns {Promise<object|undefined>} * A promise which resolves with the full version info or with the library specific version * info or <code>undefined</code> if the library is not listed; if an error occurred during * loading, then the promise is rejected. * @since 1.56.0 * @public * @static */ VersionInfo.load = function (mOptions) { mOptions = mOptions || {}; mOptions.async = true; return VersionInfo._load(mOptions); }; /** * Stores the loading Promise for "sap-ui-version.json". * @see sap.ui.getVersionInfo * @private */ var oVersionInfoPromise = null; var oVersionInfo; /** * Mapping of library name to it's dependencies. * Extracted from the loaded version info. */ var mKnownLibs; /** * Mapping of component names to it's dependencies. * Extracted from the loaded version info. */ var mKnownComponents; function updateVersionInfo(oNewVersionInfo) { // Persist the info object oVersionInfo = oNewVersionInfo; // reset known libs and components mKnownLibs = null; mKnownComponents = null; } Object.defineProperty(sap.ui, "versioninfo", { configurable: true, enumerable: true, get: function() { return oVersionInfo; }, set: function(oNewVersionInfo) { updateVersionInfo(oNewVersionInfo); } }); /** * Version retrieval. Used by {@link sap.ui.getVersionInfo} and {@link module:sap/ui/VersionInfo.load} * * @param {string|object} [mOptions] name of the library (e.g. "sap.ui.core") or an object map (see below) * @param {boolean} [mOptions.library] name of the library (e.g. "sap.ui.core") * @param {boolean} [mOptions.async=false] whether "sap-ui-version.json" should be loaded asynchronously * @param {boolean} [mOptions.failOnError=true] whether to propagate load errors or not (not relevant for async loading) * @return {object|undefined|Promise} the full version info, the library specific one, * undefined (if library is not listed or there was an error and "failOnError" is set to "false") * or a Promise which resolves with one of them * @private * @static */ VersionInfo._load = function(mOptions) { // Check for no parameter / library name as string if (typeof mOptions !== "object") { mOptions = { library: mOptions }; } // Cast "async" to boolean (defaults to false) mOptions.async = mOptions.async === true; // Cast "failOnError" to boolean (defaults to true) mOptions.failOnError = mOptions.failOnError !== false; if (!oVersionInfo) { // Load and cache the versioninfo // When async is enabled and the file is currently being loaded // return the promise and make sure the requested options are passed. // This is to prevent returning the full object as requested in a // first call (which created this promise) to the one requested just a // single lib in a second call (which re-uses this same promise) or vice versa. if (mOptions.async && oVersionInfoPromise instanceof Promise) { return oVersionInfoPromise.then(function() { return VersionInfo._load(mOptions); }); } var fnHandleSuccess = function(oNewVersionInfo) { // Remove the stored Promise as the version info is now cached. // This allows reloading the file by clearing "sap.ui.versioninfo" // (however this is not documented and therefore not supported). oVersionInfoPromise = null; // "LoaderExtensions.loadResource" returns "null" in case of an error when // "failOnError" is set to "false". In this case the won't be persisted // and undefined will be returned. if (oNewVersionInfo === null) { return undefined; } updateVersionInfo(oNewVersionInfo); // Calling the function again with the same arguments will return the // cached value from the loaded version info. return VersionInfo._load(mOptions); }; var fnHandleError = function(oError) { // Remove the stored Promise as the version info couldn't be loaded // and should be requested again the next time. oVersionInfoPromise = null; // Re-throw the error to give it to the user throw oError; }; var vReturn = LoaderExtensions.loadResource("sap-ui-version.json", { async: mOptions.async, // "failOnError" only applies for sync mode, async should always fail (reject) failOnError: mOptions.async || mOptions.failOnError }); if (vReturn instanceof Promise) { oVersionInfoPromise = vReturn; return vReturn.then(fnHandleSuccess, fnHandleError); } else { return fnHandleSuccess(vReturn); } } else { // Return the cached versioninfo var oResult; if (typeof mOptions.library !== "undefined") { // Find the version of the individual library var aLibs = oVersionInfo.libraries; if (aLibs) { for (var i = 0, l = aLibs.length; i < l; i++) { if (aLibs[i].name === mOptions.library) { oResult = aLibs[i]; break; } } } } else { // Return the full version info oResult = oVersionInfo; } return mOptions.async ? Promise.resolve(oResult) : oResult; } }; /** * Transforms the loaded version info to an easier consumable map. */ function transformVersionInfo() { if (oVersionInfo){ // get the transitive dependencies of the given libs from the loaded version info // only do this once if mKnownLibs is not created yet if (oVersionInfo.libraries && !mKnownLibs) { // flatten dependency lists for all libs mKnownLibs = {}; oVersionInfo.libraries.forEach(function(oLib, i) { mKnownLibs[oLib.name] = {}; var mDeps = oLib.manifestHints && oLib.manifestHints.dependencies && oLib.manifestHints.dependencies.libs; for (var sDep in mDeps) { if (!mDeps[sDep].lazy) { mKnownLibs[oLib.name][sDep] = true; } } }); } // get transitive dependencies for a component if (oVersionInfo.components && !mKnownComponents) { mKnownComponents = {}; Object.keys(oVersionInfo.components).forEach(function(sComponentName) { var oComponentInfo = oVersionInfo.components[sComponentName]; mKnownComponents[sComponentName] = { library: oComponentInfo.library, hasOwnPreload: oComponentInfo.hasOwnPreload || false, dependencies: [] }; var mDeps = oComponentInfo.manifestHints && oComponentInfo.manifestHints.dependencies && oComponentInfo.manifestHints.dependencies.libs; for (var sDep in mDeps) { if (!mDeps[sDep].lazy) { mKnownComponents[sComponentName].dependencies.push(sDep); } } }); } } } /** * Gets all additional transitive dependencies for the given list of libraries. * Returns a new array. * @param {string[]} aLibraries a list of libraries for which the transitive * dependencies will be extracted from the loaded version info * @returns {string[]} the list of all transitive dependencies for the given initial * list of libraries * @static * @private * @ui5-restricted sap.ui.core */ VersionInfo._getTransitiveDependencyForLibraries = function(aLibraries) { transformVersionInfo(); if (mKnownLibs) { var mClosure = aLibraries.reduce(function(all, lib) { all[lib] = true; return Object.assign(all, mKnownLibs[lib]); }, {}); aLibraries = Object.keys(mClosure); } return aLibraries; }; /** * If the given component is part of the version-info, an object with library and dependency information is returned. * * The object has three properties: * <ul> * <li><code>library</code> contains the name of the library which contains the component implementation</li> * <li><code>dependencies</code> is an array with all transitive dependencies of the component</li> * <li><code>hasOwnPreload</code> is a boolean indicating whether the component has its own Component-preload bundle</li> * </ul> * * @param {string} sComponentName the component name * @returns {{library: string, hasOwnPreload: boolean, dependencies: string[]}|undefined} * An info object containing the located library and all transitive dependencies for the given component * or <code>undefined</code> if the component is not part of the version-info. * @static * @private * @ui5-restricted sap.ui.core */ VersionInfo._getTransitiveDependencyForComponent = function(sComponentName) { transformVersionInfo(); if (mKnownComponents) { return mKnownComponents[sComponentName]; } }; return VersionInfo; });