diff options
Diffstat (limited to 'app/presenters/packages/npm/package_presenter.rb')
-rw-r--r-- | app/presenters/packages/npm/package_presenter.rb | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/app/presenters/packages/npm/package_presenter.rb b/app/presenters/packages/npm/package_presenter.rb new file mode 100644 index 00000000000..a3ab10d3913 --- /dev/null +++ b/app/presenters/packages/npm/package_presenter.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module Packages + module Npm + class PackagePresenter + include API::Helpers::RelatedResourcesHelpers + + attr_reader :name, :packages + + NPM_VALID_DEPENDENCY_TYPES = %i[dependencies devDependencies bundleDependencies peerDependencies].freeze + + def initialize(name, packages) + @name = name + @packages = packages + end + + def versions + package_versions = {} + + packages.each do |package| + package_file = package.package_files.last + + next unless package_file + + package_versions[package.version] = build_package_version(package, package_file) + end + + package_versions + end + + def dist_tags + build_package_tags.tap { |t| t["latest"] ||= sorted_versions.last } + end + + private + + def build_package_tags + Hash[ + package_tags.map { |tag| [tag.name, tag.package.version] } + ] + end + + def build_package_version(package, package_file) + { + name: package.name, + version: package.version, + dist: { + shasum: package_file.file_sha1, + tarball: tarball_url(package, package_file) + } + }.tap do |package_version| + package_version.merge!(build_package_dependencies(package)) + end + end + + def tarball_url(package, package_file) + expose_url "#{api_v4_projects_path(id: package.project_id)}" \ + "/packages/npm/#{package.name}" \ + "/-/#{package_file.file_name}" + end + + def build_package_dependencies(package) + dependencies = Hash.new { |h, key| h[key] = {} } + dependency_links = package.dependency_links + .with_dependency_type(NPM_VALID_DEPENDENCY_TYPES) + .includes_dependency + + dependency_links.find_each do |dependency_link| + dependency = dependency_link.dependency + dependencies[dependency_link.dependency_type][dependency.name] = dependency.version_pattern + end + + dependencies + end + + def sorted_versions + versions = packages.map(&:version).compact + VersionSorter.sort(versions) + end + + def package_tags + Packages::Tag.for_packages(packages) + .preload_package + end + end + end +end |