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.
- checksums.yaml +4 -4
- data/helpers/.eslintrc +11 -0
- data/helpers/README.md +29 -0
- data/helpers/build +26 -0
- data/helpers/jest.config.js +5 -0
- data/helpers/lib/npm/conflicting-dependency-parser.js +78 -0
- data/helpers/lib/npm/index.js +9 -0
- data/helpers/lib/npm/vulnerability-auditor.js +291 -0
- data/helpers/lib/npm6/helpers.js +25 -0
- data/helpers/lib/npm6/index.js +9 -0
- data/helpers/lib/npm6/peer-dependency-checker.js +111 -0
- data/helpers/lib/npm6/remove-dependencies-from-lockfile.js +22 -0
- data/helpers/lib/npm6/subdependency-updater.js +78 -0
- data/helpers/lib/npm6/updater.js +199 -0
- data/helpers/lib/pnpm/index.js +5 -0
- data/helpers/lib/pnpm/lockfile-parser.js +82 -0
- data/helpers/lib/yarn/conflicting-dependency-parser.js +176 -0
- data/helpers/lib/yarn/fix-duplicates.js +80 -0
- data/helpers/lib/yarn/helpers.js +54 -0
- data/helpers/lib/yarn/index.js +14 -0
- data/helpers/lib/yarn/lockfile-parser.js +21 -0
- data/helpers/lib/yarn/peer-dependency-checker.js +132 -0
- data/helpers/lib/yarn/replace-lockfile-declaration.js +57 -0
- data/helpers/lib/yarn/subdependency-updater.js +83 -0
- data/helpers/lib/yarn/updater.js +209 -0
- data/helpers/package-lock.json +28519 -0
- data/helpers/package.json +29 -0
- data/helpers/patches/npm++pacote+9.5.12.patch +14 -0
- data/helpers/run.js +30 -0
- data/helpers/test/npm6/conflicting-dependency-parser.test.js +66 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package-lock.json +591 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package-lock.json +188 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package-lock.json +27 -0
- data/helpers/test/npm6/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
- data/helpers/test/npm6/fixtures/updater/original/package-lock.json +16 -0
- data/helpers/test/npm6/fixtures/updater/original/package.json +9 -0
- data/helpers/test/npm6/fixtures/updater/updated/package-lock.json +16 -0
- data/helpers/test/npm6/helpers.js +21 -0
- data/helpers/test/npm6/updater.test.js +30 -0
- data/helpers/test/pnpm/fixtures/parser/empty_version/pnpm-lock.yaml +72 -0
- data/helpers/test/pnpm/fixtures/parser/no_lockfile_change/pnpm-lock.yaml +2744 -0
- data/helpers/test/pnpm/fixtures/parser/only_dev_dependencies/pnpm-lock.yaml +16 -0
- data/helpers/test/pnpm/fixtures/parser/peer_disambiguation/pnpm-lock.yaml +855 -0
- data/helpers/test/pnpm/lockfile-parser.test.js +62 -0
- data/helpers/test/yarn/conflicting-dependency-parser.test.js +83 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/package.json +14 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/deeply-nested/yarn.lock +496 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/package.json +14 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/dev-dependencies/yarn.lock +21 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/package.json +14 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/nested/yarn.lock +183 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/package.json +14 -0
- data/helpers/test/yarn/fixtures/conflicting-dependency-parser/simple/yarn.lock +21 -0
- data/helpers/test/yarn/fixtures/updater/illegal_character/package.json +8 -0
- data/helpers/test/yarn/fixtures/updater/illegal_character/yarn.lock +14 -0
- data/helpers/test/yarn/fixtures/updater/original/package.json +6 -0
- data/helpers/test/yarn/fixtures/updater/original/yarn.lock +11 -0
- data/helpers/test/yarn/fixtures/updater/updated/yarn.lock +12 -0
- data/helpers/test/yarn/fixtures/updater/with-version-comments/package.json +5 -0
- data/helpers/test/yarn/fixtures/updater/with-version-comments/yarn.lock +13 -0
- data/helpers/test/yarn/helpers.js +18 -0
- data/helpers/test/yarn/updater.test.js +117 -0
- data/lib/dependabot/bun/bun_package_manager.rb +47 -0
- data/lib/dependabot/bun/constraint_helper.rb +359 -0
- data/lib/dependabot/bun/dependency_files_filterer.rb +157 -0
- data/lib/dependabot/bun/file_fetcher/path_dependency_builder.rb +184 -0
- data/lib/dependabot/bun/file_fetcher.rb +402 -0
- data/lib/dependabot/bun/file_parser/bun_lock.rb +140 -0
- data/lib/dependabot/bun/file_parser/lockfile_parser.rb +105 -0
- data/lib/dependabot/bun/file_parser.rb +477 -0
- data/lib/dependabot/bun/file_updater/bun_lockfile_updater.rb +144 -0
- data/lib/dependabot/bun/file_updater/npmrc_builder.rb +256 -0
- data/lib/dependabot/bun/file_updater/package_json_preparer.rb +88 -0
- data/lib/dependabot/bun/file_updater/package_json_updater.rb +378 -0
- data/lib/dependabot/bun/file_updater.rb +203 -0
- data/lib/dependabot/bun/helpers.rb +93 -0
- data/lib/dependabot/bun/language.rb +45 -0
- data/lib/dependabot/bun/metadata_finder.rb +214 -0
- data/lib/dependabot/bun/native_helpers.rb +19 -0
- data/lib/dependabot/bun/package_manager.rb +280 -0
- data/lib/dependabot/bun/package_name.rb +118 -0
- data/lib/dependabot/bun/pnpm_package_manager.rb +55 -0
- data/lib/dependabot/bun/registry_helper.rb +188 -0
- data/lib/dependabot/bun/registry_parser.rb +93 -0
- data/lib/dependabot/bun/requirement.rb +146 -0
- data/lib/dependabot/bun/sub_dependency_files_filterer.rb +82 -0
- data/lib/dependabot/bun/update_checker/conflicting_dependency_resolver.rb +59 -0
- data/lib/dependabot/bun/update_checker/dependency_files_builder.rb +79 -0
- data/lib/dependabot/bun/update_checker/latest_version_finder.rb +448 -0
- data/lib/dependabot/bun/update_checker/library_detector.rb +76 -0
- data/lib/dependabot/bun/update_checker/registry_finder.rb +279 -0
- data/lib/dependabot/bun/update_checker/requirements_updater.rb +206 -0
- data/lib/dependabot/bun/update_checker/subdependency_version_resolver.rb +154 -0
- data/lib/dependabot/bun/update_checker/version_resolver.rb +583 -0
- data/lib/dependabot/bun/update_checker/vulnerability_auditor.rb +164 -0
- data/lib/dependabot/bun/update_checker.rb +455 -0
- data/lib/dependabot/bun/version.rb +138 -0
- data/lib/dependabot/bun/version_selector.rb +61 -0
- data/lib/dependabot/bun.rb +337 -35
- metadata +108 -65
- data/lib/dependabot/javascript/bun/file_fetcher.rb +0 -77
- data/lib/dependabot/javascript/bun/file_parser/bun_lock.rb +0 -156
- data/lib/dependabot/javascript/bun/file_parser/lockfile_parser.rb +0 -55
- data/lib/dependabot/javascript/bun/file_parser.rb +0 -74
- data/lib/dependabot/javascript/bun/file_updater/lockfile_updater.rb +0 -138
- data/lib/dependabot/javascript/bun/file_updater.rb +0 -75
- data/lib/dependabot/javascript/bun/helpers.rb +0 -72
- data/lib/dependabot/javascript/bun/package_manager.rb +0 -48
- data/lib/dependabot/javascript/bun/requirement.rb +0 -11
- data/lib/dependabot/javascript/bun/update_checker/conflicting_dependency_resolver.rb +0 -64
- data/lib/dependabot/javascript/bun/update_checker/dependency_files_builder.rb +0 -47
- data/lib/dependabot/javascript/bun/update_checker/latest_version_finder.rb +0 -450
- data/lib/dependabot/javascript/bun/update_checker/library_detector.rb +0 -76
- data/lib/dependabot/javascript/bun/update_checker/requirements_updater.rb +0 -203
- data/lib/dependabot/javascript/bun/update_checker/subdependency_version_resolver.rb +0 -144
- data/lib/dependabot/javascript/bun/update_checker/version_resolver.rb +0 -525
- data/lib/dependabot/javascript/bun/update_checker/vulnerability_auditor.rb +0 -165
- data/lib/dependabot/javascript/bun/update_checker.rb +0 -440
- data/lib/dependabot/javascript/bun/version.rb +0 -11
- data/lib/dependabot/javascript/shared/constraint_helper.rb +0 -359
- data/lib/dependabot/javascript/shared/dependency_files_filterer.rb +0 -164
- data/lib/dependabot/javascript/shared/file_fetcher.rb +0 -283
- data/lib/dependabot/javascript/shared/file_parser/lockfile_parser.rb +0 -106
- data/lib/dependabot/javascript/shared/file_parser.rb +0 -454
- data/lib/dependabot/javascript/shared/file_updater/npmrc_builder.rb +0 -394
- data/lib/dependabot/javascript/shared/file_updater/package_json_preparer.rb +0 -87
- data/lib/dependabot/javascript/shared/file_updater/package_json_updater.rb +0 -376
- data/lib/dependabot/javascript/shared/file_updater.rb +0 -179
- data/lib/dependabot/javascript/shared/language.rb +0 -45
- data/lib/dependabot/javascript/shared/metadata_finder.rb +0 -209
- data/lib/dependabot/javascript/shared/native_helpers.rb +0 -21
- data/lib/dependabot/javascript/shared/package_manager_detector.rb +0 -72
- data/lib/dependabot/javascript/shared/package_name.rb +0 -118
- data/lib/dependabot/javascript/shared/registry_helper.rb +0 -190
- data/lib/dependabot/javascript/shared/registry_parser.rb +0 -93
- data/lib/dependabot/javascript/shared/requirement.rb +0 -144
- data/lib/dependabot/javascript/shared/sub_dependency_files_filterer.rb +0 -79
- data/lib/dependabot/javascript/shared/update_checker/dependency_files_builder.rb +0 -87
- data/lib/dependabot/javascript/shared/update_checker/registry_finder.rb +0 -358
- data/lib/dependabot/javascript/shared/version.rb +0 -133
- data/lib/dependabot/javascript/shared/version_selector.rb +0 -60
- 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
|