dependabot-bun 0.296.2 → 0.296.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/.eslintrc +11 -0
  3. data/helpers/README.md +29 -0
  4. data/helpers/build +26 -0
  5. data/helpers/jest.config.js +5 -0
  6. data/helpers/lib/npm/conflicting-dependency-parser.js +78 -0
  7. data/helpers/lib/npm/index.js +9 -0
  8. data/helpers/lib/npm/vulnerability-auditor.js +291 -0
  9. data/helpers/lib/npm6/helpers.js +25 -0
  10. data/helpers/lib/npm6/index.js +9 -0
  11. data/helpers/lib/npm6/peer-dependency-checker.js +111 -0
  12. data/helpers/lib/npm6/remove-dependencies-from-lockfile.js +22 -0
  13. data/helpers/lib/npm6/subdependency-updater.js +78 -0
  14. data/helpers/lib/npm6/updater.js +199 -0
  15. data/helpers/lib/pnpm/index.js +5 -0
  16. data/helpers/lib/pnpm/lockfile-parser.js +82 -0
  17. data/helpers/lib/yarn/conflicting-dependency-parser.js +176 -0
  18. data/helpers/lib/yarn/fix-duplicates.js +80 -0
  19. data/helpers/lib/yarn/helpers.js +54 -0
  20. data/helpers/lib/yarn/index.js +14 -0
  21. data/helpers/lib/yarn/lockfile-parser.js +21 -0
  22. data/helpers/lib/yarn/peer-dependency-checker.js +132 -0
  23. data/helpers/lib/yarn/replace-lockfile-declaration.js +57 -0
  24. data/helpers/lib/yarn/subdependency-updater.js +83 -0
  25. data/helpers/lib/yarn/updater.js +209 -0
  26. data/helpers/package-lock.json +28519 -0
  27. data/helpers/package.json +29 -0
  28. data/helpers/patches/npm++pacote+9.5.12.patch +14 -0
  29. data/helpers/run.js +30 -0
  30. data/helpers/test/npm6/conflicting-dependency-parser.test.js +66 -0
  31. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package-lock.json +591 -0
  32. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
  33. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package-lock.json +188 -0
  34. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
  35. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package-lock.json +27 -0
  36. data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
  37. data/helpers/test/npm6/fixtures/updater/original/package-lock.json +16 -0
  38. data/helpers/test/npm6/fixtures/updater/original/package.json +9 -0
  39. data/helpers/test/npm6/fixtures/updater/updated/package-lock.json +16 -0
  40. data/helpers/test/npm6/helpers.js +21 -0
  41. data/helpers/test/npm6/updater.test.js +30 -0
  42. data/helpers/test/pnpm/fixtures/parser/empty_version/pnpm-lock.yaml +72 -0
  43. data/helpers/test/pnpm/fixtures/parser/no_lockfile_change/pnpm-lock.yaml +2744 -0
  44. data/helpers/test/pnpm/fixtures/parser/only_dev_dependencies/pnpm-lock.yaml +16 -0
  45. data/helpers/test/pnpm/fixtures/parser/peer_disambiguation/pnpm-lock.yaml +855 -0
  46. data/helpers/test/pnpm/lockfile-parser.test.js +62 -0
  47. data/helpers/test/yarn/conflicting-dependency-parser.test.js +83 -0
  48. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
  49. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/yarn.lock +496 -0
  50. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/package.json +14 -0
  51. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/yarn.lock +21 -0
  52. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
  53. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/yarn.lock +183 -0
  54. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
  55. data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/yarn.lock +21 -0
  56. data/helpers/test/yarn/fixtures/updater/illegal_character/package.json +8 -0
  57. data/helpers/test/yarn/fixtures/updater/illegal_character/yarn.lock +14 -0
  58. data/helpers/test/yarn/fixtures/updater/original/package.json +6 -0
  59. data/helpers/test/yarn/fixtures/updater/original/yarn.lock +11 -0
  60. data/helpers/test/yarn/fixtures/updater/updated/yarn.lock +12 -0
  61. data/helpers/test/yarn/fixtures/updater/with-version-comments/package.json +5 -0
  62. data/helpers/test/yarn/fixtures/updater/with-version-comments/yarn.lock +13 -0
  63. data/helpers/test/yarn/helpers.js +18 -0
  64. data/helpers/test/yarn/updater.test.js +117 -0
  65. data/lib/dependabot/bun/bun_package_manager.rb +47 -0
  66. data/lib/dependabot/bun/constraint_helper.rb +359 -0
  67. data/lib/dependabot/bun/dependency_files_filterer.rb +157 -0
  68. data/lib/dependabot/bun/file_fetcher/path_dependency_builder.rb +184 -0
  69. data/lib/dependabot/bun/file_fetcher.rb +402 -0
  70. data/lib/dependabot/bun/file_parser/bun_lock.rb +140 -0
  71. data/lib/dependabot/bun/file_parser/lockfile_parser.rb +105 -0
  72. data/lib/dependabot/bun/file_parser.rb +477 -0
  73. data/lib/dependabot/bun/file_updater/bun_lockfile_updater.rb +144 -0
  74. data/lib/dependabot/bun/file_updater/npmrc_builder.rb +256 -0
  75. data/lib/dependabot/bun/file_updater/package_json_preparer.rb +88 -0
  76. data/lib/dependabot/bun/file_updater/package_json_updater.rb +378 -0
  77. data/lib/dependabot/bun/file_updater.rb +203 -0
  78. data/lib/dependabot/bun/helpers.rb +93 -0
  79. data/lib/dependabot/bun/language.rb +45 -0
  80. data/lib/dependabot/bun/metadata_finder.rb +214 -0
  81. data/lib/dependabot/bun/native_helpers.rb +19 -0
  82. data/lib/dependabot/bun/package_manager.rb +280 -0
  83. data/lib/dependabot/bun/package_name.rb +118 -0
  84. data/lib/dependabot/bun/pnpm_package_manager.rb +55 -0
  85. data/lib/dependabot/bun/registry_helper.rb +188 -0
  86. data/lib/dependabot/bun/registry_parser.rb +93 -0
  87. data/lib/dependabot/bun/requirement.rb +146 -0
  88. data/lib/dependabot/bun/sub_dependency_files_filterer.rb +82 -0
  89. data/lib/dependabot/bun/update_checker/conflicting_dependency_resolver.rb +59 -0
  90. data/lib/dependabot/bun/update_checker/dependency_files_builder.rb +79 -0
  91. data/lib/dependabot/bun/update_checker/latest_version_finder.rb +448 -0
  92. data/lib/dependabot/bun/update_checker/library_detector.rb +76 -0
  93. data/lib/dependabot/bun/update_checker/registry_finder.rb +279 -0
  94. data/lib/dependabot/bun/update_checker/requirements_updater.rb +206 -0
  95. data/lib/dependabot/bun/update_checker/subdependency_version_resolver.rb +154 -0
  96. data/lib/dependabot/bun/update_checker/version_resolver.rb +583 -0
  97. data/lib/dependabot/bun/update_checker/vulnerability_auditor.rb +164 -0
  98. data/lib/dependabot/bun/update_checker.rb +455 -0
  99. data/lib/dependabot/bun/version.rb +138 -0
  100. data/lib/dependabot/bun/version_selector.rb +61 -0
  101. data/lib/dependabot/bun.rb +337 -35
  102. metadata +108 -65
  103. data/lib/dependabot/javascript/bun/file_fetcher.rb +0 -77
  104. data/lib/dependabot/javascript/bun/file_parser/bun_lock.rb +0 -156
  105. data/lib/dependabot/javascript/bun/file_parser/lockfile_parser.rb +0 -55
  106. data/lib/dependabot/javascript/bun/file_parser.rb +0 -74
  107. data/lib/dependabot/javascript/bun/file_updater/lockfile_updater.rb +0 -138
  108. data/lib/dependabot/javascript/bun/file_updater.rb +0 -75
  109. data/lib/dependabot/javascript/bun/helpers.rb +0 -72
  110. data/lib/dependabot/javascript/bun/package_manager.rb +0 -48
  111. data/lib/dependabot/javascript/bun/requirement.rb +0 -11
  112. data/lib/dependabot/javascript/bun/update_checker/conflicting_dependency_resolver.rb +0 -64
  113. data/lib/dependabot/javascript/bun/update_checker/dependency_files_builder.rb +0 -47
  114. data/lib/dependabot/javascript/bun/update_checker/latest_version_finder.rb +0 -450
  115. data/lib/dependabot/javascript/bun/update_checker/library_detector.rb +0 -76
  116. data/lib/dependabot/javascript/bun/update_checker/requirements_updater.rb +0 -203
  117. data/lib/dependabot/javascript/bun/update_checker/subdependency_version_resolver.rb +0 -144
  118. data/lib/dependabot/javascript/bun/update_checker/version_resolver.rb +0 -525
  119. data/lib/dependabot/javascript/bun/update_checker/vulnerability_auditor.rb +0 -165
  120. data/lib/dependabot/javascript/bun/update_checker.rb +0 -440
  121. data/lib/dependabot/javascript/bun/version.rb +0 -11
  122. data/lib/dependabot/javascript/shared/constraint_helper.rb +0 -359
  123. data/lib/dependabot/javascript/shared/dependency_files_filterer.rb +0 -164
  124. data/lib/dependabot/javascript/shared/file_fetcher.rb +0 -283
  125. data/lib/dependabot/javascript/shared/file_parser/lockfile_parser.rb +0 -106
  126. data/lib/dependabot/javascript/shared/file_parser.rb +0 -454
  127. data/lib/dependabot/javascript/shared/file_updater/npmrc_builder.rb +0 -394
  128. data/lib/dependabot/javascript/shared/file_updater/package_json_preparer.rb +0 -87
  129. data/lib/dependabot/javascript/shared/file_updater/package_json_updater.rb +0 -376
  130. data/lib/dependabot/javascript/shared/file_updater.rb +0 -179
  131. data/lib/dependabot/javascript/shared/language.rb +0 -45
  132. data/lib/dependabot/javascript/shared/metadata_finder.rb +0 -209
  133. data/lib/dependabot/javascript/shared/native_helpers.rb +0 -21
  134. data/lib/dependabot/javascript/shared/package_manager_detector.rb +0 -72
  135. data/lib/dependabot/javascript/shared/package_name.rb +0 -118
  136. data/lib/dependabot/javascript/shared/registry_helper.rb +0 -190
  137. data/lib/dependabot/javascript/shared/registry_parser.rb +0 -93
  138. data/lib/dependabot/javascript/shared/requirement.rb +0 -144
  139. data/lib/dependabot/javascript/shared/sub_dependency_files_filterer.rb +0 -79
  140. data/lib/dependabot/javascript/shared/update_checker/dependency_files_builder.rb +0 -87
  141. data/lib/dependabot/javascript/shared/update_checker/registry_finder.rb +0 -358
  142. data/lib/dependabot/javascript/shared/version.rb +0 -133
  143. data/lib/dependabot/javascript/shared/version_selector.rb +0 -60
  144. data/lib/dependabot/javascript.rb +0 -39
@@ -1,358 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "excon"
5
-
6
- module Dependabot
7
- module Javascript
8
- module Shared
9
- module UpdateChecker
10
- class RegistryFinder
11
- extend T::Sig
12
-
13
- CENTRAL_REGISTRIES = %w(
14
- https://registry.npmjs.org
15
- http://registry.npmjs.org
16
- https://registry.yarnpkg.com
17
- http://registry.yarnpkg.com
18
- ).freeze
19
- NPM_AUTH_TOKEN_REGEX = %r{//(?<registry>.*)/:_authToken=(?<token>.*)$}
20
- NPM_GLOBAL_REGISTRY_REGEX = /^registry\s*=\s*['"]?(?<registry>.*?)['"]?$/
21
- YARN_GLOBAL_REGISTRY_REGEX = /^(?:--)?registry\s+((['"](?<registry>.*)['"])|(?<registry>.*))/
22
- NPM_SCOPED_REGISTRY_REGEX = /^(?<scope>@[^:]+)\s*:registry\s*=\s*['"]?(?<registry>.*?)['"]?$/
23
- YARN_SCOPED_REGISTRY_REGEX = /['"](?<scope>@[^:]+):registry['"]\s((['"](?<registry>.*)['"])|(?<registry>.*))/
24
-
25
- Registry = T.type_alias { String }
26
- RegistrySyntax = T.type_alias { T.any(Regexp, String) }
27
-
28
- sig do
29
- params(
30
- dependency: T.nilable(Dependency),
31
- credentials: T::Array[Credential],
32
- rc_file: T.nilable(DependencyFile)
33
- ).void
34
- end
35
- def initialize(dependency:, credentials:, rc_file:)
36
- @dependency = dependency
37
- @credentials = credentials
38
- @rc_file = rc_file
39
-
40
- @npmrc_file = T.let(
41
- rc_file&.name&.end_with?(".npmrc") ? rc_file : nil,
42
- T.nilable(DependencyFile)
43
- )
44
- end
45
-
46
- sig { returns(T.nilable(Registry)) }
47
- def registry
48
- @registry ||= T.let(
49
- locked_registry || configured_registry || first_registry_with_dependency_details,
50
- T.nilable(Registry)
51
- )
52
- end
53
-
54
- sig { returns(T::Hash[String, String]) }
55
- def auth_headers
56
- auth_header_for(auth_token)
57
- end
58
-
59
- sig { returns(String) }
60
- def dependency_url
61
- "#{registry_url}/#{escaped_dependency_name}"
62
- end
63
-
64
- sig { params(version: Version).returns(String) }
65
- def tarball_url(version)
66
- version_without_build_metadata = version.to_s.gsub(/\+.*/, "")
67
-
68
- # Dependency name needs to be unescaped since tarball URLs don't always work with escaped slashes
69
- "#{registry_url}/#{dependency&.name}/-/#{scopeless_name}-#{version_without_build_metadata}.tgz"
70
- end
71
-
72
- sig { params(registry: String).returns(T::Boolean) }
73
- def self.central_registry?(registry)
74
- CENTRAL_REGISTRIES.any? do |r|
75
- r.include?(registry)
76
- end
77
- end
78
-
79
- sig { params(dependency_name: String).returns(T.nilable(String)) }
80
- def registry_from_rc(dependency_name)
81
- explicit_registry_from_rc(dependency_name) || global_registry
82
- end
83
-
84
- private
85
-
86
- sig { returns(T.nilable(Dependency)) }
87
- attr_reader :dependency
88
-
89
- sig { returns(T::Array[Credential]) }
90
- attr_reader :credentials
91
-
92
- sig { returns(T.nilable(DependencyFile)) }
93
- attr_reader :rc_file
94
-
95
- sig { returns(T.nilable(DependencyFile)) }
96
- attr_reader :npmrc_file
97
-
98
- sig { params(dependency_name: T.nilable(String)).returns(T.nilable(String)) }
99
- def explicit_registry_from_rc(dependency_name)
100
- if dependency_name&.start_with?("@") && dependency_name.include?("/")
101
- scope = dependency_name.split("/").first
102
- scoped_registry(scope) || configured_global_registry
103
- else
104
- configured_global_registry
105
- end
106
- end
107
-
108
- sig { returns(T.nilable(Registry)) }
109
- def first_registry_with_dependency_details
110
- @first_registry_with_dependency_details ||= T.let(
111
- known_registries.find do |details|
112
- url = "#{details['registry'].gsub(%r{/+$}, '')}/#{escaped_dependency_name}"
113
- url = "https://#{url}" unless url.start_with?("http")
114
- response = Dependabot::RegistryClient.get(
115
- url: url,
116
- headers: auth_header_for(details["token"])
117
- )
118
- response.status < 400 && JSON.parse(response.body)
119
- rescue Excon::Error::Timeout,
120
- Excon::Error::Socket,
121
- JSON::ParserError
122
- nil
123
- rescue URI::InvalidURIError => e
124
- raise DependencyFileNotResolvable, e.message
125
- end&.fetch("registry"),
126
- T.nilable(Registry)
127
- )
128
-
129
- @first_registry_with_dependency_details ||= global_registry.to_s.sub(%r{/+$}, "").sub(%r{^.*?//}, "")
130
- end
131
-
132
- sig { returns(T.nilable(String)) }
133
- def registry_url
134
- url =
135
- if registry&.start_with?("http")
136
- registry
137
- else
138
- protocol =
139
- if registry_source_url
140
- registry_source_url&.split("://")&.first
141
- else
142
- "https"
143
- end
144
-
145
- "#{protocol}://#{registry}"
146
- end
147
-
148
- url&.gsub(%r{/+$}, "")
149
- end
150
-
151
- sig { params(token: T.nilable(String)).returns(T::Hash[String, String]) }
152
- def auth_header_for(token)
153
- return {} unless token
154
-
155
- if token.include?(":")
156
- encoded_token = Base64.encode64(token).delete("\n")
157
- { "Authorization" => "Basic #{encoded_token}" }
158
- elsif Base64.decode64(token).ascii_only? &&
159
- Base64.decode64(token).include?(":")
160
- { "Authorization" => "Basic #{token.delete("\n")}" }
161
- else
162
- { "Authorization" => "Bearer #{token}" }
163
- end
164
- end
165
-
166
- sig { returns(T.nilable(String)) }
167
- def auth_token
168
- known_registries
169
- .find { |cred| cred["registry"] == registry }
170
- &.fetch("token", nil)
171
- end
172
-
173
- sig { returns(T.nilable(Registry)) }
174
- def locked_registry
175
- return unless registry_source_url
176
-
177
- lockfile_registry =
178
- T.must(registry_source_url)
179
- .gsub("https://", "")
180
- .gsub("http://", "")
181
- detailed_registry =
182
- known_registries
183
- .find { |h| h["registry"].include?(lockfile_registry) }
184
- &.fetch("registry")
185
-
186
- detailed_registry || lockfile_registry
187
- end
188
-
189
- sig { returns(T.nilable(String)) }
190
- def configured_registry
191
- configured_registry_url = explicit_registry_from_rc(dependency&.name)
192
- return unless configured_registry_url
193
-
194
- normalize_configured_registry(configured_registry_url)
195
- end
196
-
197
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
198
- def known_registries
199
- @known_registries ||= T.let(
200
- begin
201
- registries = []
202
- registries += credentials
203
- .select { |cred| cred["type"] == "npm_registry" && cred["registry"] }
204
- .tap { |arr| arr.each { |c| c["token"] ||= nil } }
205
- registries += npmrc_registries
206
-
207
- unique_registries(registries)
208
- end,
209
- T.nilable(T::Array[T::Hash[String, T.untyped]])
210
- )
211
- end
212
-
213
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
214
- def npmrc_registries
215
- return [] unless npmrc_file
216
-
217
- registries = []
218
- T.must(npmrc_file).content&.scan(NPM_AUTH_TOKEN_REGEX) do
219
- next if Regexp.last_match&.[](:registry)&.include?("${")
220
-
221
- registry = T.must(Regexp.last_match)[:registry]
222
- token = T.must(Regexp.last_match)[:token]&.strip
223
-
224
- registries << {
225
- "type" => "npm_registry",
226
- "registry" => registry&.gsub(/\s+/, "%20"),
227
- "token" => token
228
- }
229
- end
230
-
231
- registries += npmrc_global_registries
232
- end
233
-
234
- sig { params(registries: T::Array[T::Hash[String, T.untyped]]).returns(T::Array[T::Hash[String, T.untyped]]) }
235
- def unique_registries(registries)
236
- registries.uniq.reject do |registry|
237
- next if registry["token"]
238
-
239
- # Reject this entry if an identical one with a token exists
240
- registries.any? do |r|
241
- r["token"] && r["registry"] == registry["registry"]
242
- end
243
- end
244
- end
245
-
246
- sig { returns(T.nilable(String)) }
247
- def global_registry
248
- return @global_registry if defined? @global_registry
249
-
250
- @global_registry ||= T.let(configured_global_registry || "https://registry.npmjs.org", T.nilable(String))
251
- end
252
-
253
- sig { returns(T.nilable(String)) }
254
- def configured_global_registry
255
- return @configured_global_registry if defined? @configured_global_registry
256
-
257
- @configured_global_registry = T.let(
258
- npmrc_file && npmrc_global_registries.first&.fetch("url"),
259
- T.nilable(String)
260
- )
261
- return @configured_global_registry if @configured_global_registry
262
-
263
- replaces_base = credentials.find { |cred| cred["type"] == "npm_registry" && cred.replaces_base? }
264
- if replaces_base
265
- registry = replaces_base["registry"]
266
- registry = "https://#{registry}" unless registry&.start_with?("http")
267
- return @configured_global_registry = registry
268
- end
269
-
270
- @configured_global_registry = nil
271
- end
272
-
273
- sig { returns(T::Array[T::Hash[String, T.nilable(String)]]) }
274
- def npmrc_global_registries
275
- return [] unless npmrc_file
276
-
277
- global_rc_registries(T.must(npmrc_file), syntax: NPM_GLOBAL_REGISTRY_REGEX)
278
- end
279
-
280
- sig { params(scope: T.nilable(String)).returns(T.nilable(String)) }
281
- def scoped_registry(scope)
282
- scoped_rc_registry(npmrc_file, syntax: NPM_SCOPED_REGISTRY_REGEX, scope: scope)
283
- end
284
-
285
- sig do
286
- params(file: DependencyFile, syntax: RegistrySyntax)
287
- .returns(T::Array[T::Hash[String, T.nilable(String)]])
288
- end
289
- def global_rc_registries(file, syntax:)
290
- registries = []
291
-
292
- file.content&.scan(syntax) do
293
- next if Regexp.last_match&.[](:registry)&.include?("${")
294
-
295
- url = T.must(T.must(Regexp.last_match)[:registry]).strip
296
- registry = normalize_configured_registry(url)
297
- registries << {
298
- "type" => "npm_registry",
299
- "registry" => registry,
300
- "url" => url,
301
- "token" => nil
302
- }
303
- end
304
-
305
- registries
306
- end
307
-
308
- sig do
309
- params(file: T.nilable(DependencyFile), syntax: RegistrySyntax, scope: T.nilable(String))
310
- .returns(T.nilable(String))
311
- end
312
- def scoped_rc_registry(file, syntax:, scope:)
313
- file&.content.to_s.scan(syntax) do
314
- next if Regexp.last_match&.[](:registry)&.include?("${") || Regexp.last_match&.[](:scope) != scope
315
-
316
- return T.must(T.must(Regexp.last_match)[:registry]).strip
317
- end
318
-
319
- nil
320
- end
321
-
322
- # npm registries expect slashes to be escaped
323
- sig { returns(T.nilable(String)) }
324
- def escaped_dependency_name
325
- return unless dependency
326
-
327
- T.must(dependency).name.gsub("/", "%2F")
328
- end
329
-
330
- sig { returns(T.nilable(String)) }
331
- def scopeless_name
332
- return unless dependency
333
-
334
- T.must(dependency).name.split("/").last
335
- end
336
-
337
- sig { returns(T.nilable(String)) }
338
- def registry_source_url
339
- return unless dependency
340
-
341
- sources = T.must(dependency).requirements
342
- .map { |r| r.fetch(:source) }.uniq.compact
343
- .sort_by { |source| self.class.central_registry?(source[:url]) ? 1 : 0 }
344
-
345
- sources.find { |s| s[:type] == "registry" }&.fetch(:url)
346
- end
347
-
348
- sig { params(url: String).returns(String) }
349
- def normalize_configured_registry(url)
350
- url.sub(%r{/+$}, "")
351
- .sub(%r{^.*?//}, "")
352
- .gsub(/\s+/, "%20")
353
- end
354
- end
355
- end
356
- end
357
- end
358
- end
@@ -1,133 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- # JavaScript pre-release versions use 1.0.1-rc1 syntax, which Gem::Version
5
- # converts into 1.0.1.pre.rc1. We override the `to_s` method to stop that
6
- # alteration.
7
- #
8
- # See https://semver.org/ for details of node's version syntax.
9
-
10
- module Dependabot
11
- module Javascript
12
- module Shared
13
- class Version < Dependabot::Version
14
- extend T::Sig
15
-
16
- sig { returns(T.nilable(String)) }
17
- attr_reader :build_info
18
-
19
- # These are possible npm versioning tags that can be used in place of a version.
20
- # See https://docs.npmjs.com/cli/v10/commands/npm-dist-tag#purpose for more details.
21
- VERSION_TAGS = T.let([
22
- "alpha", # Alpha version, early testing phase
23
- "beta", # Beta version, more stable than alpha
24
- "canary", # Canary version, often used for cutting-edge builds
25
- "dev", # Development version, ongoing development
26
- "experimental", # Experimental version, unstable and new features
27
- "latest", # Latest stable version, used by npm to identify the current version of a package
28
- "legacy", # Legacy version, older version maintained for compatibility
29
- "next", # Next version, used by some projects to identify the upcoming version
30
- "nightly", # Nightly build, daily builds often including latest changes
31
- "rc", # Release candidate, potential final version
32
- "release", # General release version
33
- "stable" # Stable version, thoroughly tested and stable
34
- ].freeze.map(&:freeze), T::Array[String])
35
-
36
- VERSION_PATTERN = T.let(Gem::Version::VERSION_PATTERN + '(\+[0-9a-zA-Z\-.]+)?', String)
37
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
38
-
39
- sig { override.params(version: VersionParameter).returns(T::Boolean) }
40
- def self.correct?(version)
41
- version = version.gsub(/^v/, "") if version.is_a?(String)
42
-
43
- return false if version.nil?
44
-
45
- version.to_s.match?(ANCHORED_VERSION_PATTERN)
46
- end
47
-
48
- sig { params(version: VersionParameter).returns(VersionParameter) }
49
- def self.semver_for(version)
50
- # The next two lines are to guard against improperly formatted
51
- # versions in a lockfile, such as an empty string or additional
52
- # characters. NPM/yarn fixes these when running an update, so we can
53
- # safely ignore these versions.
54
- return if version == ""
55
- return unless correct?(version)
56
-
57
- version
58
- end
59
-
60
- sig { override.params(version: VersionParameter).void }
61
- def initialize(version)
62
- version = clean_version(version)
63
-
64
- @version_string = T.let(version.to_s, String)
65
-
66
- @build_info = T.let(nil, T.nilable(String))
67
-
68
- version, @build_info = version.to_s.split("+") if version.to_s.include?("+")
69
-
70
- super(T.must(version))
71
- end
72
-
73
- sig { params(version: VersionParameter).returns(VersionParameter) }
74
- def clean_version(version)
75
- # Check if version is a string before attempting to match
76
- if version.is_a?(String)
77
- # Matches @ followed by x.y.z (digits separated by dots)
78
- if (match = version.match(/@(\d+\.\d+\.\d+)/))
79
- version = match[1] # Just "4.5.3"
80
-
81
- # Extract version in case the output contains Corepack verbose data
82
- elsif version.include?("Corepack")
83
- version = T.must(T.must(version.tr("\n", " ").match(/(\d+\.\d+\.\d+)/))[-1])
84
- end
85
- version = version&.gsub(/^v/, "")
86
- end
87
-
88
- version
89
- end
90
-
91
- sig { override.params(version: VersionParameter).returns(Version) }
92
- def self.new(version)
93
- T.cast(super, Version)
94
- end
95
-
96
- sig { returns(Integer) }
97
- def major
98
- @major ||= T.let(segments[0].to_i, T.nilable(Integer))
99
- end
100
-
101
- sig { returns(Integer) }
102
- def minor
103
- @minor ||= T.let(segments[1].to_i, T.nilable(Integer))
104
- end
105
-
106
- sig { returns(Integer) }
107
- def patch
108
- @patch ||= T.let(segments[2].to_i, T.nilable(Integer))
109
- end
110
-
111
- sig { params(other: Version).returns(T::Boolean) }
112
- def backwards_compatible_with?(other)
113
- case major
114
- when 0
115
- self == other
116
- else
117
- major == other.major && minor >= other.minor
118
- end
119
- end
120
-
121
- sig { override.returns(String) }
122
- def to_s
123
- @version_string
124
- end
125
-
126
- sig { override.returns(String) }
127
- def inspect
128
- "#<#{self.class} #{@version_string}>"
129
- end
130
- end
131
- end
132
- end
133
- end
@@ -1,60 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Dependabot
5
- module Javascript
6
- module Shared
7
- class VersionSelector
8
- extend T::Sig
9
- extend T::Helpers
10
-
11
- # For limited testing, allowing only specific versions defined in engines in package.json
12
- # such as "20.8.7", "8.1.2", "8.21.2",
13
- NODE_ENGINE_SUPPORTED_REGEX = /^\d+(?:\.\d+)*$/
14
-
15
- # Sets up engine versions from the given manifest JSON.
16
- #
17
- # @param manifest_json [Hash] The manifest JSON containing version information.
18
- # @param name [String] The engine name to match.
19
- # @return [Hash] A hash with selected versions, if found.
20
- sig do
21
- params(
22
- manifest_json: T::Hash[String, T.untyped],
23
- name: String,
24
- dependabot_versions: T.nilable(T::Array[Dependabot::Version])
25
- )
26
- .returns(T::Hash[Symbol, T.untyped])
27
- end
28
- def setup(manifest_json, name, dependabot_versions = nil)
29
- engine_versions = manifest_json["engines"]
30
-
31
- # Return an empty hash if no engine versions are specified
32
- return {} if engine_versions.nil?
33
-
34
- versions = {}
35
-
36
- if Dependabot::Experiments.enabled?(:enable_engine_version_detection)
37
- engine_versions.each do |engine, value|
38
- next unless engine.to_s.match(name)
39
-
40
- versions[name] = ConstraintHelper.find_highest_version_from_constraint_expression(
41
- value, dependabot_versions
42
- )
43
- end
44
- else
45
- versions = engine_versions.select do |engine, value|
46
- engine.to_s.match(name) && valid_extracted_version?(value)
47
- end
48
- end
49
-
50
- versions
51
- end
52
-
53
- sig { params(version: String).returns(T::Boolean) }
54
- def valid_extracted_version?(version)
55
- version.match?(NODE_ENGINE_SUPPORTED_REGEX)
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,39 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/bun"
5
-
6
- module Dependabot
7
- module Javascript
8
- DEFAULT_PACKAGE_MANAGER = "npm"
9
- ERROR_MALFORMED_VERSION_NUMBER = "Malformed version number"
10
- MANIFEST_ENGINES_KEY = "engines"
11
- MANIFEST_FILENAME = "package.json"
12
- MANIFEST_PACKAGE_MANAGER_KEY = "packageManager"
13
-
14
- # Define a type alias for the expected class interface
15
- JavascriptPackageManagerClassType = T.type_alias do
16
- T.class_of(Bun::PackageManager)
17
- end
18
-
19
- PACKAGE_MANAGER_CLASSES = T.let({
20
- Bun::PackageManager::NAME => Bun::PackageManager
21
- }.freeze, T::Hash[String, JavascriptPackageManagerClassType])
22
-
23
- PACKAGE_MANAGER_VERSION_REGEX = /
24
- ^ # Start of string
25
- (?<major>\d+) # Major version (required, numeric)
26
- \. # Separator between major and minor versions
27
- (?<minor>\d+) # Minor version (required, numeric)
28
- \. # Separator between minor and patch versions
29
- (?<patch>\d+) # Patch version (required, numeric)
30
- ( # Start pre-release section
31
- -(?<pre_release>[a-zA-Z0-9.]+) # Pre-release label (optional, alphanumeric or dot-separated)
32
- )?
33
- ( # Start build metadata section
34
- \+(?<build>[a-zA-Z0-9.]+) # Build metadata (optional, alphanumeric or dot-separated)
35
- )?
36
- $ # End of string
37
- /x # Extended mode for readability
38
- end
39
- end