dependabot-bun 0.304.0 → 0.305.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,7 +64,7 @@ module Dependabot
64
64
  end
65
65
 
66
66
  def registry
67
- Bun::UpdateChecker::RegistryFinder.new(
67
+ Bun::Package::RegistryFinder.new(
68
68
  dependency: nil,
69
69
  credentials: credentials,
70
70
  npmrc_file: dependency_files.find { |f| f.name.end_with?(".npmrc") }
@@ -427,9 +427,12 @@ module Dependabot
427
427
 
428
428
  def original_source(updated_dependency)
429
429
  sources =
430
- updated_dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
431
- .sort_by { |source| RegistryFinder.central_registry?(source[:url]) ? 1 : 0 }
432
-
430
+ updated_dependency
431
+ .requirements.map { |r| r.fetch(:source) }
432
+ .uniq.compact
433
+ .sort_by do |source|
434
+ Package::RegistryFinder.central_registry?(source[:url]) ? 1 : 0
435
+ end
433
436
  sources.first
434
437
  end
435
438
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-bun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.304.0
4
+ version: 0.305.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-03 00:00:00.000000000 Z
11
+ date: 2025-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.304.0
19
+ version: 0.305.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.304.0
26
+ version: 0.305.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -323,6 +323,8 @@ files:
323
323
  - lib/dependabot/bun/language.rb
324
324
  - lib/dependabot/bun/metadata_finder.rb
325
325
  - lib/dependabot/bun/native_helpers.rb
326
+ - lib/dependabot/bun/package/package_details_fetcher.rb
327
+ - lib/dependabot/bun/package/registry_finder.rb
326
328
  - lib/dependabot/bun/package_manager.rb
327
329
  - lib/dependabot/bun/package_name.rb
328
330
  - lib/dependabot/bun/pnpm_package_manager.rb
@@ -335,7 +337,6 @@ files:
335
337
  - lib/dependabot/bun/update_checker/dependency_files_builder.rb
336
338
  - lib/dependabot/bun/update_checker/latest_version_finder.rb
337
339
  - lib/dependabot/bun/update_checker/library_detector.rb
338
- - lib/dependabot/bun/update_checker/registry_finder.rb
339
340
  - lib/dependabot/bun/update_checker/requirements_updater.rb
340
341
  - lib/dependabot/bun/update_checker/subdependency_version_resolver.rb
341
342
  - lib/dependabot/bun/update_checker/version_resolver.rb
@@ -347,7 +348,7 @@ licenses:
347
348
  - MIT
348
349
  metadata:
349
350
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
350
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.304.0
351
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.305.0
351
352
  post_install_message:
352
353
  rdoc_options: []
353
354
  require_paths:
@@ -1,279 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require "excon"
5
- require "dependabot/bun/update_checker"
6
- require "dependabot/registry_client"
7
-
8
- module Dependabot
9
- module Bun
10
- class UpdateChecker
11
- class RegistryFinder
12
- CENTRAL_REGISTRIES = %w(
13
- https://registry.npmjs.org
14
- http://registry.npmjs.org
15
- ).freeze
16
- NPM_AUTH_TOKEN_REGEX = %r{//(?<registry>.*)/:_authToken=(?<token>.*)$}
17
- NPM_GLOBAL_REGISTRY_REGEX = /^registry\s*=\s*['"]?(?<registry>.*?)['"]?$/
18
- NPM_SCOPED_REGISTRY_REGEX = /^(?<scope>@[^:]+)\s*:registry\s*=\s*['"]?(?<registry>.*?)['"]?$/
19
-
20
- def initialize(dependency:, credentials:, npmrc_file: nil)
21
- @dependency = dependency
22
- @credentials = credentials
23
- @npmrc_file = npmrc_file
24
- end
25
-
26
- def registry
27
- @registry ||= locked_registry || configured_registry || first_registry_with_dependency_details
28
- end
29
-
30
- def auth_headers
31
- auth_header_for(auth_token)
32
- end
33
-
34
- def dependency_url
35
- "#{registry_url}/#{escaped_dependency_name}"
36
- end
37
-
38
- def tarball_url(version)
39
- version_without_build_metadata = version.to_s.gsub(/\+.*/, "")
40
-
41
- # Dependency name needs to be unescaped since tarball URLs don't always work with escaped slashes
42
- "#{registry_url}/#{dependency.name}/-/#{scopeless_name}-#{version_without_build_metadata}.tgz"
43
- end
44
-
45
- def self.central_registry?(registry)
46
- CENTRAL_REGISTRIES.any? do |r|
47
- r.include?(registry)
48
- end
49
- end
50
-
51
- def registry_from_rc(dependency_name)
52
- explicit_registry_from_rc(dependency_name) || global_registry
53
- end
54
-
55
- private
56
-
57
- attr_reader :dependency
58
- attr_reader :credentials
59
- attr_reader :npmrc_file
60
-
61
- def explicit_registry_from_rc(dependency_name)
62
- if dependency_name.start_with?("@") && dependency_name.include?("/")
63
- scope = dependency_name.split("/").first
64
- scoped_registry(scope) || configured_global_registry
65
- else
66
- configured_global_registry
67
- end
68
- end
69
-
70
- def first_registry_with_dependency_details
71
- @first_registry_with_dependency_details ||=
72
- known_registries.find do |details|
73
- url = "#{details['registry'].gsub(%r{/+$}, '')}/#{escaped_dependency_name}"
74
- url = "https://#{url}" unless url.start_with?("http")
75
- response = Dependabot::RegistryClient.get(
76
- url: url,
77
- headers: auth_header_for(details["token"])
78
- )
79
- response.status < 400 && JSON.parse(response.body)
80
- rescue Excon::Error::Timeout,
81
- Excon::Error::Socket,
82
- JSON::ParserError
83
- nil
84
- rescue URI::InvalidURIError => e
85
- raise DependencyFileNotResolvable, e.message
86
- end&.fetch("registry")
87
-
88
- @first_registry_with_dependency_details ||= global_registry.sub(%r{/+$}, "").sub(%r{^.*?//}, "")
89
- end
90
-
91
- def registry_url
92
- url =
93
- if registry.start_with?("http")
94
- registry
95
- else
96
- protocol =
97
- if registry_source_url
98
- registry_source_url.split("://").first
99
- else
100
- "https"
101
- end
102
-
103
- "#{protocol}://#{registry}"
104
- end
105
-
106
- url.gsub(%r{/+$}, "")
107
- end
108
-
109
- def auth_header_for(token)
110
- return {} unless token
111
-
112
- if token.include?(":")
113
- encoded_token = Base64.encode64(token).delete("\n")
114
- { "Authorization" => "Basic #{encoded_token}" }
115
- elsif Base64.decode64(token).ascii_only? &&
116
- Base64.decode64(token).include?(":")
117
- { "Authorization" => "Basic #{token.delete("\n")}" }
118
- else
119
- { "Authorization" => "Bearer #{token}" }
120
- end
121
- end
122
-
123
- def auth_token
124
- known_registries
125
- .find { |cred| cred["registry"] == registry }
126
- &.fetch("token", nil)
127
- end
128
-
129
- def locked_registry
130
- return unless registry_source_url
131
-
132
- lockfile_registry =
133
- registry_source_url
134
- .gsub("https://", "")
135
- .gsub("http://", "")
136
- detailed_registry =
137
- known_registries
138
- .find { |h| h["registry"].include?(lockfile_registry) }
139
- &.fetch("registry")
140
-
141
- detailed_registry || lockfile_registry
142
- end
143
-
144
- def configured_registry
145
- configured_registry_url = explicit_registry_from_rc(dependency.name)
146
- return unless configured_registry_url
147
-
148
- normalize_configured_registry(configured_registry_url)
149
- end
150
-
151
- def known_registries
152
- @known_registries ||=
153
- begin
154
- registries = []
155
- registries += credentials
156
- .select { |cred| cred["type"] == "npm_registry" && cred["registry"] }
157
- .tap { |arr| arr.each { |c| c["token"] ||= nil } }
158
- registries += npmrc_registries
159
-
160
- unique_registries(registries)
161
- end
162
- end
163
-
164
- def npmrc_registries
165
- return [] unless npmrc_file
166
-
167
- registries = []
168
- npmrc_file.content.scan(NPM_AUTH_TOKEN_REGEX) do
169
- next if Regexp.last_match&.[](:registry)&.include?("${")
170
-
171
- registry = T.must(Regexp.last_match)[:registry]
172
- token = T.must(Regexp.last_match)[:token]&.strip
173
-
174
- registries << {
175
- "type" => "npm_registry",
176
- "registry" => registry&.gsub(/\s+/, "%20"),
177
- "token" => token
178
- }
179
- end
180
-
181
- registries += npmrc_global_registries
182
- end
183
-
184
- def unique_registries(registries)
185
- registries.uniq.reject do |registry|
186
- next if registry["token"]
187
-
188
- # Reject this entry if an identical one with a token exists
189
- registries.any? do |r|
190
- r["token"] && r["registry"] == registry["registry"]
191
- end
192
- end
193
- end
194
-
195
- def global_registry
196
- return @global_registry if defined? @global_registry
197
-
198
- @global_registry ||= configured_global_registry || "https://registry.npmjs.org"
199
- end
200
-
201
- def configured_global_registry
202
- return @configured_global_registry if defined? @configured_global_registry
203
-
204
- @configured_global_registry = npmrc_file && npmrc_global_registries.first&.fetch("url")
205
- return @configured_global_registry if @configured_global_registry
206
-
207
- replaces_base = credentials.find { |cred| cred["type"] == "npm_registry" && cred.replaces_base? }
208
- if replaces_base
209
- registry = replaces_base["registry"]
210
- registry = "https://#{registry}" unless registry.start_with?("http")
211
- return @configured_global_registry = registry
212
- end
213
-
214
- @configured_global_registry = nil
215
- end
216
-
217
- def npmrc_global_registries
218
- global_rc_registries(npmrc_file, syntax: NPM_GLOBAL_REGISTRY_REGEX)
219
- end
220
-
221
- def scoped_registry(scope)
222
- scoped_rc_registry(npmrc_file, syntax: NPM_SCOPED_REGISTRY_REGEX, scope: scope)
223
- end
224
-
225
- def global_rc_registries(file, syntax:)
226
- registries = []
227
-
228
- file.content.scan(syntax) do
229
- next if Regexp.last_match&.[](:registry)&.include?("${")
230
-
231
- url = T.must(T.must(Regexp.last_match)[:registry]).strip
232
- registry = normalize_configured_registry(url)
233
- registries << {
234
- "type" => "npm_registry",
235
- "registry" => registry,
236
- "url" => url,
237
- "token" => nil
238
- }
239
- end
240
-
241
- registries
242
- end
243
-
244
- def scoped_rc_registry(file, syntax:, scope:)
245
- file&.content.to_s.scan(syntax) do
246
- next if Regexp.last_match&.[](:registry)&.include?("${") || Regexp.last_match&.[](:scope) != scope
247
-
248
- return T.must(T.must(Regexp.last_match)[:registry]).strip
249
- end
250
-
251
- nil
252
- end
253
-
254
- # npm registries expect slashes to be escaped
255
- def escaped_dependency_name
256
- dependency.name.gsub("/", "%2F")
257
- end
258
-
259
- def scopeless_name
260
- dependency.name.split("/").last
261
- end
262
-
263
- def registry_source_url
264
- sources = dependency.requirements
265
- .map { |r| r.fetch(:source) }.uniq.compact
266
- .sort_by { |source| self.class.central_registry?(source[:url]) ? 1 : 0 }
267
-
268
- sources.find { |s| s[:type] == "registry" }&.fetch(:url)
269
- end
270
-
271
- def normalize_configured_registry(url)
272
- url.sub(%r{/+$}, "")
273
- .sub(%r{^.*?//}, "")
274
- .gsub(/\s+/, "%20")
275
- end
276
- end
277
- end
278
- end
279
- end