Class: Dependabot::NpmAndYarn::Package::PackageDetailsFetcher

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Includes:
RegistryCredentialHelpers
Defined in:
lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb

Constant Summary collapse

GLOBAL_REGISTRY =
"registry.npmjs.org"
NPM_OFFICIAL_WEBSITE =
"https://www.npmjs.com"
API_AUTHORIZATION_KEY =
"Authorization"
API_AUTHORIZATION_VALUE_BASIC_PREFIX =
"Basic"
API_RESPONSE_STATUS_SUCCESS_PREFIX =
"2"
RELEASE_DIST_TAGS_LATEST_KEY =
"latest"
RELEASE_LANGUAGE_KEY =
"node"
REGISTRY_FILE_NPMRC =
".npmrc"
REGISTRY_FILE_YARNRC =
".yarnrc"
REGISTRY_FILE_YARNRC_YML =
".yarnrc.yml"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dependency:, dependency_files:, credentials:) ⇒ PackageDetailsFetcher

Returns a new instance of PackageDetailsFetcher.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 41

def initialize(
  dependency:,
  dependency_files:,
  credentials:
)
  @dependency = dependency
  @dependency_files = dependency_files
  @credentials = credentials

  @npm_details = T.let(nil, T.nilable(Dependabot::Package::NpmRegistryPackage))
  @dist_tags = T.let(nil, T.nilable(T::Hash[String, String]))
  @registry_finder = T.let(nil, T.nilable(Package::RegistryFinder))
  @version_endpoint_working = T.let(nil, T.nilable(T::Boolean))
  @yanked = T.let({}, T::Hash[Gem::Version, T.nilable(T::Boolean)])
end

Instance Attribute Details

#credentialsObject (readonly)

Returns the value of attribute credentials.



61
62
63
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 61

def credentials
  @credentials
end

#dependencyObject (readonly)

Returns the value of attribute dependency.



58
59
60
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 58

def dependency
  @dependency
end

#dependency_filesObject (readonly)

Returns the value of attribute dependency_files.



64
65
66
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 64

def dependency_files
  @dependency_files
end

Instance Method Details

#custom_registry?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 87

def custom_registry?
  registry_finder.custom_registry?
end

#dependency_urlObject



92
93
94
95
96
97
98
99
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 92

def dependency_url
  if (configured_registry = configured_registry_from_credentials)
    escaped_dependency_name = dependency.name.gsub("/", "%2F")
    return "#{configured_registry}/#{escaped_dependency_name}"
  end

  registry_finder.dependency_url
end

#fetchObject



67
68
69
70
71
72
73
74
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 67

def fetch
  package_data = npm_details
  Dependabot::Package::PackageDetails.new(
    dependency: @dependency,
    releases: package_data ? parse_versions(package_data) : [],
    dist_tags: dist_tags
  )
end

#npm_detailsObject



82
83
84
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 82

def npm_details
  @npm_details ||= fetch_npm_details
end

#valid_npm_details?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 77

def valid_npm_details?
  !dist_tags.nil?
end

#yanked?(version) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/dependabot/npm_and_yarn/package/package_details_fetcher.rb', line 102

def yanked?(version)
  return @yanked[version] || false if @yanked.key?(version)

  @yanked[version] =
    begin
      if dependency_registry == GLOBAL_REGISTRY
        status = Dependabot::RegistryClient.head(
          url: registry_finder.tarball_url(version),
          headers: registry_auth_headers
        ).status
      else
        status = Dependabot::RegistryClient.get(
          url: dependency_url + "/#{version}",
          headers: registry_auth_headers
        ).status

        if status == 404
          # Some registries don't handle escaped package names properly
          status = Dependabot::RegistryClient.get(
            url: dependency_url.gsub("%2F", "/") + "/#{version}",
            headers: registry_auth_headers
          ).status
        end
      end

      version_not_found = status == 404
      version_not_found && version_endpoint_working?
    rescue Excon::Error::Timeout, Excon::Error::Socket
      # Give the benefit of the doubt if the registry is playing up
      false
    end

  @yanked[version] || false
end