dependabot-npm_and_yarn 0.303.0 → 0.304.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.
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "set"
@@ -11,7 +11,8 @@ require "dependabot/update_checkers/base"
11
11
 
12
12
  module Dependabot
13
13
  module NpmAndYarn
14
- class UpdateChecker < Dependabot::UpdateCheckers::Base
14
+ class UpdateChecker < Dependabot::UpdateCheckers::Base # rubocop:disable Metrics/ClassLength
15
+ extend T::Sig
15
16
  require_relative "update_checker/requirements_updater"
16
17
  require_relative "update_checker/library_detector"
17
18
  require_relative "update_checker/latest_version_finder"
@@ -20,6 +21,48 @@ module Dependabot
20
21
  require_relative "update_checker/conflicting_dependency_resolver"
21
22
  require_relative "update_checker/vulnerability_auditor"
22
23
 
24
+ sig do
25
+ params(
26
+ dependency: Dependabot::Dependency,
27
+ dependency_files: T::Array[Dependabot::DependencyFile],
28
+ credentials: T::Array[Dependabot::Credential],
29
+ repo_contents_path: T.nilable(String),
30
+ ignored_versions: T::Array[String],
31
+ raise_on_ignored: T::Boolean,
32
+ security_advisories: T::Array[Dependabot::SecurityAdvisory],
33
+ requirements_update_strategy: T.nilable(Dependabot::RequirementsUpdateStrategy),
34
+ dependency_group: T.nilable(Dependabot::DependencyGroup),
35
+ update_cooldown: T.nilable(Dependabot::Package::ReleaseCooldownOptions),
36
+ options: T::Hash[Symbol, T.untyped]
37
+ )
38
+ .void
39
+ end
40
+ def initialize(dependency:, dependency_files:, credentials:, # rubocop:disable Metrics/AbcSize
41
+ repo_contents_path: nil, ignored_versions: [],
42
+ raise_on_ignored: false, security_advisories: [],
43
+ requirements_update_strategy: nil, dependency_group: nil,
44
+ update_cooldown: nil, options: {})
45
+ @latest_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
46
+ @latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
47
+ @updated_requirements = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
48
+ @vulnerability_audit = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
49
+ @vulnerable_versions = T.let(nil, T.nilable(T::Array[T.any(String, Gem::Version)]))
50
+
51
+ @latest_version_for_git_dependency = T.let(nil, T.nilable(T.any(String, Gem::Version)))
52
+ @latest_released_version = T.let(nil, T.nilable(Gem::Version))
53
+ @latest_version_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
54
+ @latest_version_finder = T.let(
55
+ nil, T.nilable(T.any(LatestVersionFinder, PackageLatestVersionFinder))
56
+ )
57
+ @version_resolver = T.let(nil, T.nilable(VersionResolver))
58
+ @subdependency_version_resolver = T.let(nil, T.nilable(SubdependencyVersionResolver))
59
+ @library = T.let(nil, T.nilable(T::Boolean))
60
+ @package_json = T.let(nil, T.nilable(Dependabot::DependencyFile))
61
+ @git_commit_checker = T.let(nil, T.nilable(Dependabot::GitCommitChecker))
62
+ super
63
+ end
64
+
65
+ sig { returns(T::Boolean) }
23
66
  def up_to_date?
24
67
  return false if security_update? &&
25
68
  dependency.version &&
@@ -30,10 +73,12 @@ module Dependabot
30
73
  super
31
74
  end
32
75
 
76
+ sig { returns(T::Boolean) }
33
77
  def vulnerable?
34
78
  super || vulnerable_versions.any?
35
79
  end
36
80
 
81
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
37
82
  def latest_version
38
83
  @latest_version ||=
39
84
  if git_dependency?
@@ -43,6 +88,7 @@ module Dependabot
43
88
  end
44
89
  end
45
90
 
91
+ sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
46
92
  def latest_resolvable_version
47
93
  return unless latest_version
48
94
 
@@ -56,13 +102,15 @@ module Dependabot
56
102
  end
57
103
  end
58
104
 
105
+ sig { override.returns(T.nilable(Dependabot::Version)) }
59
106
  def lowest_security_fix_version
60
107
  # This will require a full unlock to update multiple top level ancestors.
61
108
  return if vulnerability_audit["fix_available"] && vulnerability_audit["top_level_ancestors"].count > 1
62
109
 
63
- latest_version_finder.lowest_security_fix_version
110
+ T.unsafe(latest_version_finder.lowest_security_fix_version)
64
111
  end
65
112
 
113
+ sig { override.returns(T.nilable(Dependabot::Version)) }
66
114
  def lowest_resolvable_security_fix_version
67
115
  raise "Dependency not vulnerable!" unless vulnerable?
68
116
 
@@ -83,6 +131,7 @@ module Dependabot
83
131
  lowest_security_fix_version
84
132
  end
85
133
 
134
+ sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
86
135
  def latest_resolvable_version_with_no_unlock
87
136
  return latest_resolvable_version unless dependency.top_level?
88
137
 
@@ -91,10 +140,15 @@ module Dependabot
91
140
  latest_version_finder.latest_version_with_no_unlock
92
141
  end
93
142
 
143
+ sig do
144
+ params(updated_version: T.any(String, Gem::Version))
145
+ .returns(T.nilable(T.any(String, T.untyped)))
146
+ end
94
147
  def latest_resolvable_previous_version(updated_version)
95
- version_resolver.latest_resolvable_previous_version(updated_version)
148
+ T.unsafe(version_resolver.latest_resolvable_previous_version(updated_version))
96
149
  end
97
150
 
151
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
98
152
  def updated_requirements
99
153
  resolvable_version =
100
154
  if preferred_resolvable_version.is_a?(version_class)
@@ -117,10 +171,12 @@ module Dependabot
117
171
  ).updated_requirements
118
172
  end
119
173
 
174
+ sig { returns(T::Boolean) }
120
175
  def requirements_unlocked_or_can_be?
121
- !requirements_update_strategy.lockfile_only?
176
+ !requirements_update_strategy&.lockfile_only?
122
177
  end
123
178
 
179
+ sig { returns(T.nilable(Dependabot::RequirementsUpdateStrategy)) }
124
180
  def requirements_update_strategy
125
181
  # If passed in as an option (in the base class) honour that option
126
182
  return @requirements_update_strategy if @requirements_update_strategy
@@ -129,6 +185,7 @@ module Dependabot
129
185
  library? ? RequirementsUpdateStrategy::WidenRanges : RequirementsUpdateStrategy::BumpVersions
130
186
  end
131
187
 
188
+ sig { override.returns(T::Array[T::Hash[String, String]]) }
132
189
  def conflicting_dependencies
133
190
  conflicts = ConflictingDependencyResolver.new(
134
191
  dependency_files: dependency_files,
@@ -148,10 +205,12 @@ module Dependabot
148
205
 
149
206
  private
150
207
 
208
+ sig { returns(T::Boolean) }
151
209
  def vulnerability_audit_performed?
152
- defined?(@vulnerability_audit)
210
+ !!defined?(@vulnerability_audit)
153
211
  end
154
212
 
213
+ sig { returns(T::Hash[String, T.untyped]) }
155
214
  def vulnerability_audit
156
215
  @vulnerability_audit ||=
157
216
  VulnerabilityAuditor.new(
@@ -163,6 +222,7 @@ module Dependabot
163
222
  )
164
223
  end
165
224
 
225
+ sig { returns(T::Array[T.any(String, Gem::Version)]) }
166
226
  def vulnerable_versions
167
227
  @vulnerable_versions ||=
168
228
  begin
@@ -175,6 +235,7 @@ module Dependabot
175
235
  end
176
236
  end
177
237
 
238
+ sig { override.returns(T::Boolean) }
178
239
  def latest_version_resolvable_with_full_unlock?
179
240
  return false unless latest_version
180
241
 
@@ -185,14 +246,16 @@ module Dependabot
185
246
  vulnerability_audit["fix_available"]
186
247
  end
187
248
 
249
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
188
250
  def updated_dependencies_after_full_unlock
189
251
  return conflicting_updated_dependencies if security_advisories.any? && vulnerability_audit["fix_available"]
190
252
 
191
- version_resolver.dependency_updates_from_full_unlock
192
- .map { |update_details| build_updated_dependency(update_details) }
253
+ T.must(version_resolver.dependency_updates_from_full_unlock)
254
+ .map { |update_details| build_updated_dependency(update_details.transform_keys(&:to_sym)) }
193
255
  end
194
256
 
195
257
  # rubocop:disable Metrics/AbcSize
258
+ sig { returns(T::Array[Dependabot::Dependency]) }
196
259
  def conflicting_updated_dependencies
197
260
  top_level_dependencies = top_level_dependency_lookup
198
261
 
@@ -233,6 +296,7 @@ module Dependabot
233
296
  updated_deps.reject { |dep| dep.name == dependency.name }
234
297
  end
235
298
 
299
+ sig { returns(T::Hash[String, Dependabot::Dependency]) }
236
300
  def top_level_dependency_lookup
237
301
  top_level_dependencies = FileParser.new(
238
302
  dependency_files: dependency_files,
@@ -243,6 +307,11 @@ module Dependabot
243
307
  top_level_dependencies.to_h { |dep| [dep.name, dep] }
244
308
  end
245
309
 
310
+ sig do
311
+ params(
312
+ update_details: T::Hash[Symbol, T.untyped]
313
+ ).returns(Dependabot::Dependency)
314
+ end
246
315
  def build_updated_dependency(update_details)
247
316
  original_dep = update_details.fetch(:dependency)
248
317
  removed = update_details.fetch(:removed, false)
@@ -267,9 +336,15 @@ module Dependabot
267
336
  )
268
337
  end
269
338
 
339
+ sig { returns(T.nilable(T.any(String, Gem::Version, T.untyped))) }
270
340
  def latest_resolvable_transitive_security_fix_version_with_no_unlock
341
+ versions = T.let([], T::Array[Gem::Version])
342
+
343
+ latest = latest_released_version
344
+ versions.push(latest) if latest
345
+
271
346
  fix_possible = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(
272
- [latest_resolvable_version].compact,
347
+ versions,
273
348
  security_advisories
274
349
  ).any?
275
350
  return nil unless fix_possible
@@ -277,6 +352,7 @@ module Dependabot
277
352
  latest_resolvable_version
278
353
  end
279
354
 
355
+ sig { returns(T.nilable(T.any(String, Dependabot::Version))) }
280
356
  def latest_resolvable_version_with_no_unlock_for_git_dependency
281
357
  reqs = dependency.requirements.filter_map do |r|
282
358
  next if r.fetch(:requirement).nil?
@@ -300,21 +376,24 @@ module Dependabot
300
376
  git_commit_checker.head_commit_for_current_branch
301
377
  end
302
378
 
379
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
303
380
  def latest_version_for_git_dependency
304
381
  @latest_version_for_git_dependency ||=
305
382
  if version_class.correct?(dependency.version)
306
- latest_git_version_details[:version] &&
307
- version_class.new(latest_git_version_details[:version])
383
+ T.unsafe(latest_git_version_details[:version] &&
384
+ version_class.new(latest_git_version_details[:version]))
308
385
  else
309
386
  latest_git_version_details[:sha]
310
387
  end
311
388
  end
312
389
 
390
+ sig { returns(T.nilable(Gem::Version)) }
313
391
  def latest_released_version
314
392
  @latest_released_version ||=
315
393
  latest_version_finder.latest_version_from_registry
316
394
  end
317
395
 
396
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
318
397
  def latest_version_details
319
398
  @latest_version_details ||=
320
399
  if git_dependency?
@@ -324,18 +403,37 @@ module Dependabot
324
403
  end
325
404
  end
326
405
 
406
+ sig { returns(T.any(LatestVersionFinder, PackageLatestVersionFinder)) }
327
407
  def latest_version_finder
328
408
  @latest_version_finder ||=
329
- LatestVersionFinder.new(
330
- dependency: dependency,
331
- credentials: credentials,
332
- dependency_files: dependency_files,
333
- ignored_versions: ignored_versions,
334
- raise_on_ignored: raise_on_ignored,
335
- security_advisories: security_advisories
336
- )
409
+ if enable_cooldown?
410
+ PackageLatestVersionFinder.new(
411
+ dependency: dependency,
412
+ credentials: credentials,
413
+ dependency_files: dependency_files,
414
+ ignored_versions: ignored_versions,
415
+ raise_on_ignored: raise_on_ignored,
416
+ security_advisories: security_advisories,
417
+ cooldown_options: @update_cooldown
418
+ )
419
+ else
420
+ LatestVersionFinder.new(
421
+ dependency: dependency,
422
+ credentials: credentials,
423
+ dependency_files: dependency_files,
424
+ ignored_versions: ignored_versions,
425
+ raise_on_ignored: raise_on_ignored,
426
+ security_advisories: security_advisories
427
+ )
428
+ end
429
+ end
430
+
431
+ sig { returns(T::Boolean) }
432
+ def enable_cooldown?
433
+ Dependabot::Experiments.enabled?(:enable_cooldown_for_npm_and_yarn)
337
434
  end
338
435
 
436
+ sig { returns(VersionResolver) }
339
437
  def version_resolver
340
438
  @version_resolver ||=
341
439
  VersionResolver.new(
@@ -345,10 +443,13 @@ module Dependabot
345
443
  latest_allowable_version: latest_version,
346
444
  latest_version_finder: latest_version_finder,
347
445
  repo_contents_path: repo_contents_path,
348
- dependency_group: dependency_group
446
+ dependency_group: dependency_group,
447
+ raise_on_ignored: raise_on_ignored,
448
+ update_cooldown: @update_cooldown
349
449
  )
350
450
  end
351
451
 
452
+ sig { returns(SubdependencyVersionResolver) }
352
453
  def subdependency_version_resolver
353
454
  @subdependency_version_resolver ||=
354
455
  SubdependencyVersionResolver.new(
@@ -361,10 +462,12 @@ module Dependabot
361
462
  )
362
463
  end
363
464
 
465
+ sig { returns(T::Boolean) }
364
466
  def git_dependency?
365
467
  git_commit_checker.git_dependency?
366
468
  end
367
469
 
470
+ sig { returns(T::Hash[Symbol, T.untyped]) }
368
471
  def latest_git_version_details
369
472
  semver_req =
370
473
  dependency.requirements
@@ -390,6 +493,7 @@ module Dependabot
390
493
  { sha: dependency.version }
391
494
  end
392
495
 
496
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
393
497
  def updated_source
394
498
  # Never need to update source, unless a git_dependency
395
499
  return dependency_source_details unless git_dependency?
@@ -398,13 +502,14 @@ module Dependabot
398
502
  if git_commit_checker.pinned_ref_looks_like_version? &&
399
503
  !git_commit_checker.local_tag_for_latest_version.nil?
400
504
  new_tag = git_commit_checker.local_tag_for_latest_version
401
- return dependency_source_details.merge(ref: new_tag.fetch(:tag))
505
+ return dependency_source_details&.merge(ref: new_tag&.fetch(:tag))
402
506
  end
403
507
 
404
508
  # Otherwise return the original source
405
509
  dependency_source_details
406
510
  end
407
511
 
512
+ sig { returns(T::Boolean) }
408
513
  def library?
409
514
  return true unless dependency.version
410
515
  return true if dependency_files.any? { |f| f.name == "lerna.json" }
@@ -417,14 +522,20 @@ module Dependabot
417
522
  ).library?
418
523
  end
419
524
 
525
+ sig { returns(T::Boolean) }
420
526
  def security_update?
421
527
  security_advisories.any?
422
528
  end
423
529
 
530
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
424
531
  def dependency_source_details
425
532
  original_source(dependency)
426
533
  end
427
534
 
535
+ sig do
536
+ params(updated_dependency: Dependabot::Dependency)
537
+ .returns(T.nilable(T::Hash[Symbol, T.untyped]))
538
+ end
428
539
  def original_source(updated_dependency)
429
540
  sources =
430
541
  updated_dependency
@@ -437,11 +548,13 @@ module Dependabot
437
548
  sources.first
438
549
  end
439
550
 
551
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
440
552
  def package_json
441
553
  @package_json ||=
442
554
  dependency_files.find { |f| f.name == "package.json" }
443
555
  end
444
556
 
557
+ sig { returns(Dependabot::GitCommitChecker) }
445
558
  def git_commit_checker
446
559
  @git_commit_checker ||=
447
560
  GitCommitChecker.new(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-npm_and_yarn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.303.0
4
+ version: 0.304.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-03-27 00:00:00.000000000 Z
11
+ date: 2025-04-03 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.303.0
19
+ version: 0.304.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.303.0
26
+ version: 0.304.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -357,7 +357,7 @@ licenses:
357
357
  - MIT
358
358
  metadata:
359
359
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
360
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.303.0
360
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.304.0
361
361
  post_install_message:
362
362
  rdoc_options: []
363
363
  require_paths: