project/lib/ui5Framework/Sapui5Resolver.js

  1. const path = require("path");
  2. const semver = require("semver");
  3. const AbstractResolver = require("./AbstractResolver");
  4. const Installer = require("./npm/Installer");
  5. const log = require("@ui5/logger").getLogger("normalizer:ui5Framework:Sapui5Resolver");
  6. const DIST_PKG_NAME = "@sapui5/distribution-metadata";
  7. /**
  8. * Resolver for the SAPUI5 framework
  9. *
  10. * @public
  11. * @memberof module:@ui5/project.ui5Framework
  12. * @augments module:@ui5/project.ui5Framework.AbstractResolver
  13. */
  14. class Sapui5Resolver extends AbstractResolver {
  15. /**
  16. * @param {*} options options
  17. * @param {string} options.version SAPUI5 version to use
  18. * @param {string} [options.cwd=process.cwd()] Working directory to resolve configurations like .npmrc
  19. * @param {string} [options.ui5HomeDir="~/.ui5"] UI5 home directory location. This will be used to store packages,
  20. * metadata and configuration used by the resolvers. Relative to `process.cwd()`
  21. */
  22. constructor(options) {
  23. super(options);
  24. this._installer = new Installer({
  25. cwd: this._cwd,
  26. ui5HomeDir: this._ui5HomeDir
  27. });
  28. this._loadDistMetadata = null;
  29. }
  30. loadDistMetadata() {
  31. if (!this._loadDistMetadata) {
  32. this._loadDistMetadata = Promise.resolve().then(async () => {
  33. const version = this._version;
  34. log.verbose(`Installing ${DIST_PKG_NAME} in version ${version}...`);
  35. const pkgName = DIST_PKG_NAME;
  36. const {pkgPath} = await this._installer.installPackage({
  37. pkgName,
  38. version
  39. });
  40. const metadata = await this._installer.readJson(path.join(pkgPath, "metadata.json"));
  41. return metadata;
  42. });
  43. }
  44. return this._loadDistMetadata;
  45. }
  46. async getLibraryMetadata(libraryName) {
  47. const distMetadata = await this.loadDistMetadata();
  48. const metadata = distMetadata.libraries[libraryName];
  49. if (!metadata) {
  50. throw new Error(`Could not find library "${libraryName}"`);
  51. }
  52. if (metadata.npmPackageName.startsWith("@openui5/") &&
  53. semver.satisfies(this._version, "1.77.x")) {
  54. // TODO 3.0: Remove this workaround
  55. // 1.77.x (at least 1.77.0-1.77.2) distribution metadata.json is missing
  56. // dependency information for all OpenUI5 libraries.
  57. // Therefore we need to request those from the registry like it is done
  58. // for OpenUI5 projects.
  59. const Openui5Resolver = require("./Openui5Resolver");
  60. const openui5Resolver = new Openui5Resolver({
  61. cwd: this._cwd,
  62. version: metadata.version
  63. });
  64. const openui5Metadata = await openui5Resolver.getLibraryMetadata(libraryName);
  65. return {
  66. npmPackageName: openui5Metadata.id,
  67. version: openui5Metadata.version,
  68. dependencies: openui5Metadata.dependencies,
  69. optionalDependencies: openui5Metadata.optionalDependencies
  70. };
  71. }
  72. return metadata;
  73. }
  74. async handleLibrary(libraryName) {
  75. const metadata = await this.getLibraryMetadata(libraryName);
  76. return {
  77. metadata: Promise.resolve({
  78. id: metadata.npmPackageName,
  79. version: metadata.version,
  80. dependencies: metadata.dependencies,
  81. optionalDependencies: metadata.optionalDependencies
  82. }),
  83. // Trigger installation of package
  84. install: this._installer.installPackage({
  85. pkgName: metadata.npmPackageName,
  86. version: metadata.version
  87. })
  88. };
  89. }
  90. static async fetchAllVersions({ui5HomeDir, cwd} = {}) {
  91. const installer = new Installer({
  92. cwd: cwd ? path.resolve(cwd) : process.cwd(),
  93. ui5HomeDir:
  94. ui5HomeDir ? path.resolve(ui5HomeDir) :
  95. path.join(require("os").homedir(), ".ui5")
  96. });
  97. return await installer.fetchPackageVersions({pkgName: DIST_PKG_NAME});
  98. }
  99. }
  100. module.exports = Sapui5Resolver;