dependabot-npm_and_yarn 0.309.0 → 0.311.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.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/lib/dependabot/npm_and_yarn/file_parser/json_lock.rb +1 -1
  3. data/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb +60 -19
  4. data/lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb +37 -16
  5. data/lib/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater.rb +60 -19
  6. data/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb +4 -50
  7. data/lib/dependabot/npm_and_yarn/file_updater/package_json_preparer.rb +16 -4
  8. data/lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb +161 -51
  9. data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +211 -60
  10. data/lib/dependabot/npm_and_yarn/file_updater.rb +1 -1
  11. data/lib/dependabot/npm_and_yarn/helpers.rb +12 -59
  12. data/lib/dependabot/npm_and_yarn/metadata_finder.rb +64 -15
  13. data/lib/dependabot/npm_and_yarn/native_helpers.rb +8 -1
  14. data/lib/dependabot/npm_and_yarn/package/registry_finder.rb +1 -1
  15. data/lib/dependabot/npm_and_yarn/requirement.rb +23 -9
  16. data/lib/dependabot/npm_and_yarn/update_checker/conflicting_dependency_resolver.rb +36 -9
  17. data/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb +82 -24
  18. data/lib/dependabot/npm_and_yarn/update_checker/library_detector.rb +35 -5
  19. data/lib/dependabot/npm_and_yarn/update_checker/requirements_updater.rb +61 -24
  20. data/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +66 -37
  21. data/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +1 -1
  22. data/lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb +60 -7
  23. data/lib/dependabot/npm_and_yarn/update_checker.rb +18 -8
  24. metadata +9 -9
@@ -1,7 +1,9 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "stringio"
5
+ require "sorbet-runtime"
6
+
5
7
  require "dependabot/dependency"
6
8
  require "dependabot/errors"
7
9
  require "dependabot/logger"
@@ -16,6 +18,15 @@ module Dependabot
16
18
  module NpmAndYarn
17
19
  class UpdateChecker < Dependabot::UpdateCheckers::Base
18
20
  class VulnerabilityAuditor
21
+ extend T::Sig
22
+
23
+ sig do
24
+ params(
25
+ dependency_files: T::Array[Dependabot::DependencyFile],
26
+ credentials: T::Array[Dependabot::Credential]
27
+ )
28
+ .void
29
+ end
19
30
  def initialize(dependency_files:, credentials:)
20
31
  @dependency_files = dependency_files
21
32
  @credentials = credentials
@@ -43,6 +54,13 @@ module Dependabot
43
54
  # * :top_level_ancestors [Array<String>] the names of all top-level dependencies with a transitive
44
55
  # dependency on the dependency
45
56
  # * :explanation [String] an explanation for why the project failed the vulnerability auditor run
57
+ sig do
58
+ params(
59
+ dependency: Dependabot::Dependency,
60
+ security_advisories: T::Array[Dependabot::SecurityAdvisory]
61
+ )
62
+ .returns(T::Hash[String, T.untyped])
63
+ end
46
64
  def audit(dependency:, security_advisories:)
47
65
  Dependabot.logger.info("VulnerabilityAuditor: starting audit")
48
66
 
@@ -76,10 +94,13 @@ module Dependabot
76
94
  }
77
95
  end
78
96
 
79
- audit_result = SharedHelpers.run_helper_subprocess(
80
- command: NativeHelpers.helper_path,
81
- function: "npm:vulnerabilityAuditor",
82
- args: [Dir.pwd, vuln_versions]
97
+ audit_result = T.cast(
98
+ SharedHelpers.run_helper_subprocess(
99
+ command: NativeHelpers.helper_path,
100
+ function: "npm:vulnerabilityAuditor",
101
+ args: [Dir.pwd, vuln_versions]
102
+ ),
103
+ T::Hash[String, T.untyped]
83
104
  )
84
105
 
85
106
  validation_result = validate_audit_result(audit_result, security_advisories)
@@ -94,24 +115,36 @@ module Dependabot
94
115
  end
95
116
  rescue SharedHelpers::HelperSubprocessFailed => e
96
117
  log_helper_subprocess_failure(dependency, e)
97
- fix_unavailable
118
+ T.must(fix_unavailable)
98
119
  end
99
120
  # rubocop:enable Metrics/MethodLength
100
121
 
101
122
  private
102
123
 
124
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
103
125
  attr_reader :dependency_files
126
+
127
+ sig { returns(T::Array[Dependabot::Credential]) }
104
128
  attr_reader :credentials
105
129
 
130
+ sig { params(validation_result: Symbol, dependency: Dependabot::Dependency).returns(String) }
106
131
  def explain_fix_unavailable(validation_result, dependency)
107
132
  case validation_result
108
133
  when :fix_unavailable, :dependency_still_vulnerable, :downgrades_dependencies
109
134
  "No patched version available for #{dependency.name}"
110
135
  when :fix_incomplete
111
136
  "The lockfile might be out of sync?"
137
+ else
138
+ raise "Unexpected validation result: #{validation_result}"
112
139
  end
113
140
  end
114
141
 
142
+ sig do
143
+ params(
144
+ audit_result: T::Hash[String, T.untyped],
145
+ security_advisories: T::Array[Dependabot::SecurityAdvisory]
146
+ ).returns(Symbol)
147
+ end
115
148
  def validate_audit_result(audit_result, security_advisories)
116
149
  return :fix_unavailable unless audit_result["fix_available"]
117
150
  return :dependency_still_vulnerable if dependency_still_vulnerable?(audit_result, security_advisories)
@@ -121,6 +154,13 @@ module Dependabot
121
154
  :viable
122
155
  end
123
156
 
157
+ sig do
158
+ params(
159
+ audit_result: T::Hash[String, T.untyped],
160
+ security_advisories: T::Array[Dependabot::SecurityAdvisory]
161
+ )
162
+ .returns(T::Boolean)
163
+ end
124
164
  def dependency_still_vulnerable?(audit_result, security_advisories)
125
165
  # vulnerable dependency is removed if the target version is nil
126
166
  return false unless audit_result["target_version"]
@@ -129,6 +169,7 @@ module Dependabot
129
169
  security_advisories.any? { |a| a.vulnerable?(version) }
130
170
  end
131
171
 
172
+ sig { params(audit_result: T::Hash[String, T.untyped]).returns(T::Boolean) }
132
173
  def downgrades_dependencies?(audit_result)
133
174
  return true if downgrades_version?(audit_result["current_version"], audit_result["target_version"])
134
175
 
@@ -137,6 +178,13 @@ module Dependabot
137
178
  end
138
179
  end
139
180
 
181
+ sig do
182
+ params(
183
+ current_version: T.nilable(T.any(String, Integer, Gem::Version)),
184
+ target_version: T.nilable(T.any(String, Integer, Gem::Version))
185
+ )
186
+ .returns(T::Boolean)
187
+ end
140
188
  def downgrades_version?(current_version, target_version)
141
189
  return false unless target_version
142
190
 
@@ -145,14 +193,19 @@ module Dependabot
145
193
  current > target
146
194
  end
147
195
 
196
+ sig { params(audit_result: T::Hash[String, T.untyped]).returns(T::Boolean) }
148
197
  def fix_incomplete?(audit_result)
149
198
  audit_result["fix_updates"].any? { |update| !update.key?("target_version") } ||
150
199
  audit_result["fix_updates"].empty?
151
200
  end
152
201
 
202
+ sig do
203
+ params(dependency: Dependabot::Dependency,
204
+ error: Dependabot::SharedHelpers::HelperSubprocessFailed).void
205
+ end
153
206
  def log_helper_subprocess_failure(dependency, error)
154
207
  # See `Dependabot::SharedHelpers.run_helper_subprocess` for details on error context
155
- context = error.error_context || {}
208
+ context = error.error_context
156
209
 
157
210
  builder = ::StringIO.new
158
211
  builder << "VulnerabilityAuditor: "
@@ -43,7 +43,7 @@ module Dependabot
43
43
  requirements_update_strategy: nil, dependency_group: nil,
44
44
  update_cooldown: nil, options: {})
45
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)))
46
+ @latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
47
47
  @updated_requirements = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
48
48
  @vulnerability_audit = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
49
49
  @vulnerable_versions = T.let(nil, T.nilable(T::Array[T.any(String, Gem::Version)]))
@@ -88,17 +88,23 @@ module Dependabot
88
88
  end
89
89
  end
90
90
 
91
- sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
91
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
92
92
  def latest_resolvable_version
93
93
  return unless latest_version
94
94
 
95
95
  @latest_resolvable_version ||=
96
96
  if dependency.top_level?
97
- version_resolver.latest_resolvable_version
97
+ T.cast(
98
+ version_resolver.latest_resolvable_version,
99
+ T.nilable(T.any(String, Dependabot::Version))
100
+ )
98
101
  else
99
102
  # If the dependency is indirect its version is constrained by the
100
103
  # requirements placed on it by dependencies lower down the tree
101
- subdependency_version_resolver.latest_resolvable_version
104
+ T.cast(
105
+ subdependency_version_resolver.latest_resolvable_version,
106
+ T.nilable(T.any(String, Dependabot::Version))
107
+ )
102
108
  end
103
109
  end
104
110
 
@@ -133,7 +139,11 @@ module Dependabot
133
139
 
134
140
  sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
135
141
  def latest_resolvable_version_with_no_unlock
136
- return latest_resolvable_version unless dependency.top_level?
142
+ unless dependency.top_level?
143
+ # TODO: We should use `Dependabot::Version` everywhere
144
+ return T.cast(latest_resolvable_version,
145
+ T.nilable(T.any(String, Dependabot::Version)))
146
+ end
137
147
 
138
148
  return latest_resolvable_version_with_no_unlock_for_git_dependency if git_dependency?
139
149
 
@@ -167,7 +177,7 @@ module Dependabot
167
177
  requirements: dependency.requirements,
168
178
  updated_source: updated_source,
169
179
  latest_resolvable_version: resolvable_version,
170
- update_strategy: requirements_update_strategy
180
+ update_strategy: T.must(requirements_update_strategy)
171
181
  ).updated_requirements
172
182
  end
173
183
 
@@ -326,7 +336,7 @@ module Dependabot
326
336
  requirements: original_dep.requirements,
327
337
  updated_source: original_dep == dependency ? updated_source : original_source(original_dep),
328
338
  latest_resolvable_version: version,
329
- update_strategy: requirements_update_strategy
339
+ update_strategy: T.must(requirements_update_strategy)
330
340
  ).updated_requirements,
331
341
  previous_version: previous_version,
332
342
  previous_requirements: original_dep.requirements,
@@ -516,7 +526,7 @@ module Dependabot
516
526
 
517
527
  @library =
518
528
  LibraryDetector.new(
519
- package_json_file: package_json,
529
+ package_json_file: T.must(package_json),
520
530
  credentials: credentials,
521
531
  dependency_files: dependency_files
522
532
  ).library?
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-npm_and_yarn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.309.0
4
+ version: 0.311.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-17 00:00:00.000000000 Z
10
+ date: 2025-05-01 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dependabot-common
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.309.0
18
+ version: 0.311.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.309.0
25
+ version: 0.311.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -223,16 +223,16 @@ dependencies:
223
223
  name: webrick
224
224
  requirement: !ruby/object:Gem::Requirement
225
225
  requirements:
226
- - - ">="
226
+ - - "~>"
227
227
  - !ruby/object:Gem::Version
228
- version: '1.7'
228
+ version: '1.9'
229
229
  type: :development
230
230
  prerelease: false
231
231
  version_requirements: !ruby/object:Gem::Requirement
232
232
  requirements:
233
- - - ">="
233
+ - - "~>"
234
234
  - !ruby/object:Gem::Version
235
- version: '1.7'
235
+ version: '1.9'
236
236
  description: Dependabot-NPM_And_Yarn provides support for bumping Javascript (npm
237
237
  and yarn) libraries via Dependabot. If you want support for multiple package managers,
238
238
  you probably want the meta-gem dependabot-omnibus.
@@ -356,7 +356,7 @@ licenses:
356
356
  - MIT
357
357
  metadata:
358
358
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
359
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.309.0
359
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.311.0
360
360
  rdoc_options: []
361
361
  require_paths:
362
362
  - lib