project/lib/ui5Framework/Openui5Resolver.js

  1. import path from "node:path";
  2. import os from "node:os";
  3. import AbstractResolver from "./AbstractResolver.js";
  4. import Installer from "./npm/Installer.js";
  5. const OPENUI5_CORE_PACKAGE = "@openui5/sap.ui.core";
  6. /**
  7. * Resolver for the OpenUI5 framework
  8. *
  9. * @public
  10. * @class
  11. * @alias @ui5/project/ui5Framework/Openui5Resolver
  12. * @extends @ui5/project/ui5Framework/AbstractResolver
  13. */
  14. class Openui5Resolver extends AbstractResolver {
  15. /**
  16. * @param {*} options options
  17. * @param {string} options.version OpenUI5 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. * @param {string} [options.cacheDir] Where to store temp/cached packages.
  22. * @param {string} [options.packagesDir] Where to install packages
  23. * @param {string} [options.stagingDir] The staging directory for the packages
  24. */
  25. constructor(options) {
  26. super(options);
  27. const {cacheDir, packagesDir, stagingDir} = options;
  28. this._installer = new Installer({
  29. cwd: this._cwd,
  30. ui5HomeDir: this._ui5HomeDir,
  31. cacheDir, packagesDir, stagingDir
  32. });
  33. this._loadLibraryMetadata = Object.create(null);
  34. }
  35. static _getNpmPackageName(libraryName) {
  36. return "@openui5/" + libraryName;
  37. }
  38. static _getLibaryName(pkgName) {
  39. return pkgName.replace(/^@openui5\//, "");
  40. }
  41. getLibraryMetadata(libraryName) {
  42. if (!this._loadLibraryMetadata[libraryName]) {
  43. this._loadLibraryMetadata[libraryName] = Promise.resolve().then(async () => {
  44. // Trigger manifest request to gather transitive dependencies
  45. const pkgName = Openui5Resolver._getNpmPackageName(libraryName);
  46. const libraryManifest = await this._installer.fetchPackageManifest({pkgName, version: this._version});
  47. let dependencies = [];
  48. if (libraryManifest.dependencies) {
  49. const depNames = Object.keys(libraryManifest.dependencies);
  50. dependencies = depNames.map(Openui5Resolver._getLibaryName);
  51. }
  52. // npm devDependencies are handled as "optionalDependencies"
  53. // in terms of the UI5 framework metadata structure
  54. let optionalDependencies = [];
  55. if (libraryManifest.devDependencies) {
  56. const devDepNames = Object.keys(libraryManifest.devDependencies);
  57. optionalDependencies = devDepNames.map(Openui5Resolver._getLibaryName);
  58. }
  59. return {
  60. id: pkgName,
  61. version: this._version,
  62. dependencies,
  63. optionalDependencies
  64. };
  65. });
  66. }
  67. return this._loadLibraryMetadata[libraryName];
  68. }
  69. async handleLibrary(libraryName) {
  70. const pkgName = Openui5Resolver._getNpmPackageName(libraryName);
  71. return {
  72. // Trigger metadata request
  73. metadata: this.getLibraryMetadata(libraryName),
  74. // Also trigger installation of package
  75. install: this._installer.installPackage({
  76. pkgName,
  77. version: this._version
  78. })
  79. };
  80. }
  81. static async fetchAllVersions(options) {
  82. const installer = this._getInstaller(options);
  83. return await installer.fetchPackageVersions({pkgName: OPENUI5_CORE_PACKAGE});
  84. }
  85. static async fetchAllTags(options) {
  86. const installer = this._getInstaller(options);
  87. return installer.fetchPackageDistTags({pkgName: OPENUI5_CORE_PACKAGE});
  88. }
  89. static _getInstaller({ui5HomeDir, cwd} = {}) {
  90. return new Installer({
  91. cwd: cwd ? path.resolve(cwd) : process.cwd(),
  92. ui5HomeDir:
  93. ui5HomeDir ? path.resolve(ui5HomeDir) :
  94. path.join(os.homedir(), ".ui5")
  95. });
  96. }
  97. }
  98. export default Openui5Resolver;