dependabot-bun 0.381.0 → 0.383.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c54b6f5779dd69e7bf57b6d84c31cb0423036cc6c9d4ec91b3533c1bbfee20bc
4
- data.tar.gz: 3f342ce13012ef46e9217e3820ae68b4897ad6d216effc5f81c7a7e259d534d4
3
+ metadata.gz: a134971ae7d59b607f29131dd5154cfe58103aee0e00119ce6c110d5375f40af
4
+ data.tar.gz: 222bf7c881b859998596d439158d23ae057c473739f9429e72341c2b07b64d2e
5
5
  SHA512:
6
- metadata.gz: 631d537ea8a25dcf0bc80552838d164fa567aa94f3f9ddfcc1090cc09a7152f85f6f8f70b0b9b77fda89c99a1cece272ef2de0ea0bb4d5be5f777eb775b40bd7
7
- data.tar.gz: a746e9199c513c37616937412a6c857708b04be39dfa6434a34fafdf666180d8ff174a277f7d7b34fa3d34669543fcf776f22e8c4a9e645d3a4be0030d4e98a9
6
+ metadata.gz: '06584381c0b42dad6050cbbe91d79e90ca6964becb15b9c1c8c5abc9229c5486cc96184e10fbdc632fa9fb85536e748dc26f568c43368159d18ee4c558347c10'
7
+ data.tar.gz: 7b9bdd03f58a4e0aa3a655b8adf704abafe3401ddfb033b8ecb161c049715cbac8083447ac7900d5b75510011ea2381dfa88e90b152bd720e463fd5dff5c7cbf
@@ -72,7 +72,7 @@ function nameVerDevFromPkgSnapshot(depPath, pkgSnapshot, projectSnapshots) {
72
72
  return {
73
73
  name: name,
74
74
  version: version,
75
- resolved: pkgSnapshot.resolution.tarball,
75
+ resolved: pkgSnapshot.resolution?.tarball,
76
76
  dev: pkgSnapshot.dev,
77
77
  specifiers: specifiers,
78
78
  aliased: aliased
@@ -0,0 +1,23 @@
1
+ lockfileVersion: '9.0'
2
+
3
+ settings:
4
+ autoInstallPeers: true
5
+ excludeLinksFromLockfile: false
6
+
7
+ importers:
8
+
9
+ .:
10
+ devDependencies:
11
+ etag:
12
+ specifier: ^1.0.0
13
+ version: 1.8.1
14
+
15
+ packages:
16
+
17
+ etag@1.8.1:
18
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
19
+ engines: {node: '>= 0.6'}
20
+
21
+ snapshots:
22
+
23
+ etag@1.8.1: {}
@@ -59,4 +59,21 @@ describe("generates an updated pnpm lock for the original file", () => {
59
59
  expect(result.length).toEqual(9);
60
60
  })
61
61
 
62
+ // pnpm v9+ lockfiles don't have resolution.tarball for npm packages
63
+ it("that uses lockfileVersion 9.0 format without resolution.tarball", async () =>{
64
+ copyDependencies("lockfile_v9", tempDir);
65
+ const result = await parseLockfile(tempDir);
66
+
67
+ expect(result).toEqual([
68
+ {
69
+ name: 'etag',
70
+ version: '1.8.1',
71
+ resolved: undefined,
72
+ dev: undefined,
73
+ specifiers: [ '^1.0.0' ],
74
+ aliased: false
75
+ }
76
+ ]);
77
+ })
78
+
62
79
  })
@@ -6,6 +6,8 @@ require "sorbet-runtime"
6
6
  module Dependabot
7
7
  module Bun
8
8
  class RegistryParser
9
+ # NOTE: npm_and_yarn has an equivalent implementation in
10
+ # npm_and_yarn/registry_parser.rb. Keep both in sync.
9
11
  extend T::Sig
10
12
 
11
13
  sig { params(resolved_url: String, credentials: T::Array[Dependabot::Credential]).void }
@@ -60,34 +62,68 @@ module Dependabot
60
62
  sig { returns(T::Array[Dependabot::Credential]) }
61
63
  attr_reader :credentials
62
64
 
63
- # rubocop:disable Metrics/PerceivedComplexity
64
65
  sig { returns(T.nilable(String)) }
65
66
  def url_for_relevant_cred
66
- resolved_url_host = URI(resolved_url).host
67
+ resolved_uri = URI(resolved_url)
67
68
 
68
69
  credential_matching_url =
69
70
  credentials
70
71
  .select { |cred| cred["type"] == "npm_registry" && cred["registry"] }
71
72
  .sort_by { |cred| cred.fetch("registry").length }
72
- .find do |details|
73
- next true if resolved_url_host == details["registry"]
74
-
75
- uri = if details["registry"]&.include?("://")
76
- URI(details.fetch("registry"))
77
- else
78
- URI("https://#{details['registry']}")
79
- end
80
- resolved_url_host == uri.host && resolved_url.include?(details.fetch("registry"))
81
- end
73
+ .find { |details| credential_matches?(details, resolved_uri: resolved_uri) }
82
74
 
83
75
  return unless credential_matching_url
84
76
 
85
- # Trim the resolved URL so that it ends at the same point as the
86
- # credential registry
87
77
  reg = credential_matching_url.fetch("registry")
88
- resolved_url.gsub(/#{Regexp.quote(reg)}.*/, "") + reg
78
+ # When the credential registry already includes an explicit scheme, return
79
+ # it directly — the gsub pattern would not match and would produce a
80
+ # malformed string if it ran.
81
+ return reg if reg.include?("://")
82
+
83
+ build_registry_url(registry: reg, resolved_uri: resolved_uri)
84
+ end
85
+
86
+ sig { params(registry: String, resolved_uri: URI::Generic).returns(String) }
87
+ def build_registry_url(registry:, resolved_uri:)
88
+ credential_uri = URI("https://#{registry}")
89
+ normalized_path = credential_uri.path.to_s.chomp("/")
90
+
91
+ "#{resolved_uri.scheme}://#{resolved_uri.authority}#{normalized_path}"
92
+ end
93
+
94
+ # Enforce npm registry credential boundaries by matching on host, optional
95
+ # explicit scheme, and full path segments so sibling paths on the same host
96
+ # cannot inherit credentials configured for a different registry scope.
97
+ sig { params(details: Dependabot::Credential, resolved_uri: URI::Generic).returns(T::Boolean) }
98
+ def credential_matches?(details, resolved_uri:)
99
+ resolved_url_host = resolved_uri.host
100
+ return true if resolved_url_host == details["registry"]
101
+
102
+ registry_has_scheme = details["registry"]&.include?("://")
103
+ uri = if registry_has_scheme
104
+ URI(details.fetch("registry"))
105
+ else
106
+ URI("https://#{details['registry']}")
107
+ end
108
+ return false unless resolved_url_host == uri.host
109
+ # When the credential includes an explicit scheme, require scheme
110
+ # equality so we do not attribute a URL to credentials configured for
111
+ # a different transport protocol.
112
+ return false if registry_has_scheme && resolved_uri.scheme != uri.scheme
113
+
114
+ # Use path-segment-aware matching to prevent credentials configured
115
+ # for one path-scoped registry from being applied to sibling paths
116
+ # on the same host (e.g., /victim-npm should not match /victim-npm-evil).
117
+ credential_path_match?(uri: uri, resolved_url_path: resolved_uri.path.to_s)
118
+ end
119
+
120
+ sig { params(uri: URI::Generic, resolved_url_path: String).returns(T::Boolean) }
121
+ def credential_path_match?(uri:, resolved_url_path:)
122
+ registry_path = uri.path.to_s.chomp("/")
123
+ registry_path.empty? ||
124
+ resolved_url_path.start_with?("#{registry_path}/") ||
125
+ resolved_url_path == registry_path
89
126
  end
90
- # rubocop:enable Metrics/PerceivedComplexity
91
127
  end
92
128
  end
93
129
  end
@@ -11,6 +11,7 @@ require "sorbet-runtime"
11
11
  require "dependabot/bun/requirement"
12
12
  require "dependabot/bun/update_checker"
13
13
  require "dependabot/bun/version"
14
+ require "dependabot/dependency_requirement"
14
15
  require "dependabot/requirements_update_strategy"
15
16
 
16
17
  module Dependabot
@@ -33,7 +34,7 @@ module Dependabot
33
34
 
34
35
  sig do
35
36
  params(
36
- requirements: T::Array[T::Hash[Symbol, T.untyped]],
37
+ requirements: T::Array[Dependabot::DependencyRequirement],
37
38
  updated_source: T.nilable(T::Hash[Symbol, T.untyped]),
38
39
  update_strategy: Dependabot::RequirementsUpdateStrategy,
39
40
  latest_resolvable_version: T.nilable(T.any(String, Gem::Version))
@@ -46,7 +47,10 @@ module Dependabot
46
47
  update_strategy:,
47
48
  latest_resolvable_version:
48
49
  )
49
- @requirements = requirements
50
+ @requirements = T.let(
51
+ requirements.map { |req| Dependabot::DependencyRequirement.create(req) },
52
+ T::Array[Dependabot::DependencyRequirement]
53
+ )
50
54
  @updated_source = updated_source
51
55
  @update_strategy = update_strategy
52
56
 
@@ -60,12 +64,12 @@ module Dependabot
60
64
  )
61
65
  end
62
66
 
63
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
67
+ sig { returns(T::Array[Dependabot::DependencyRequirement]) }
64
68
  def updated_requirements
65
69
  return requirements if update_strategy.lockfile_only?
66
70
 
67
71
  requirements.map do |req|
68
- req = req.merge(source: updated_source)
72
+ req = Dependabot::DependencyRequirement.create(req.merge(source: updated_source))
69
73
  next req unless latest_resolvable_version
70
74
  next initial_req_after_source_change(req) unless req[:requirement]
71
75
  next req if req[:requirement].match?(/^([A-Za-uw-z]|v[^\d])/)
@@ -82,7 +86,7 @@ module Dependabot
82
86
 
83
87
  private
84
88
 
85
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
89
+ sig { returns(T::Array[Dependabot::DependencyRequirement]) }
86
90
  attr_reader :requirements
87
91
 
88
92
  sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
@@ -109,15 +113,15 @@ module Dependabot
109
113
  original_source&.fetch(:type) == "git"
110
114
  end
111
115
 
112
- sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
116
+ sig { params(req: Dependabot::DependencyRequirement).returns(Dependabot::DependencyRequirement) }
113
117
  def initial_req_after_source_change(req)
114
118
  return req unless updating_from_git_to_npm?
115
119
  return req unless req[:requirement].nil?
116
120
 
117
- req.merge(requirement: "^#{latest_resolvable_version}")
121
+ Dependabot::DependencyRequirement.create(req.merge(requirement: "^#{latest_resolvable_version}"))
118
122
  end
119
123
 
120
- sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
124
+ sig { params(req: Dependabot::DependencyRequirement).returns(Dependabot::DependencyRequirement) }
121
125
  def update_version_requirement(req)
122
126
  current_requirement = req[:requirement]
123
127
 
@@ -126,14 +130,14 @@ module Dependabot
126
130
  return req if ruby_req&.satisfied_by?(latest_resolvable_version)
127
131
 
128
132
  updated_req = update_range_requirement(current_requirement)
129
- return req.merge(requirement: updated_req)
133
+ return Dependabot::DependencyRequirement.create(req.merge(requirement: updated_req))
130
134
  end
131
135
 
132
136
  reqs = current_requirement.strip.split(SEPARATOR).map(&:strip)
133
- req.merge(requirement: update_version_string(reqs.first))
137
+ Dependabot::DependencyRequirement.create(req.merge(requirement: update_version_string(reqs.first)))
134
138
  end
135
139
 
136
- sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
140
+ sig { params(req: Dependabot::DependencyRequirement).returns(Dependabot::DependencyRequirement) }
137
141
  def update_version_requirement_if_needed(req)
138
142
  current_requirement = req[:requirement]
139
143
  version = latest_resolvable_version
@@ -145,7 +149,7 @@ module Dependabot
145
149
  update_version_requirement(req)
146
150
  end
147
151
 
148
- sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
152
+ sig { params(req: Dependabot::DependencyRequirement).returns(Dependabot::DependencyRequirement) }
149
153
  def widen_requirement(req)
150
154
  current_requirement = req[:requirement]
151
155
  version = latest_resolvable_version
@@ -165,7 +169,7 @@ module Dependabot
165
169
  current_requirement
166
170
  end
167
171
 
168
- req.merge(requirement: updated_requirement)
172
+ Dependabot::DependencyRequirement.create(req.merge(requirement: updated_requirement))
169
173
  end
170
174
 
171
175
  sig { params(requirement_string: String).returns(T::Array[Bun::Requirement]) }
@@ -51,7 +51,7 @@ module Dependabot
51
51
  )
52
52
  @latest_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
53
53
  @latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
54
- @updated_requirements = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
54
+ @updated_requirements = T.let(nil, T.nilable(T::Array[Dependabot::DependencyRequirement]))
55
55
  @vulnerability_audit = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
56
56
  @vulnerable_versions = T.let(nil, T.nilable(T::Array[T.any(String, Gem::Version)]))
57
57
 
@@ -161,7 +161,7 @@ module Dependabot
161
161
  T.unsafe(version_resolver.latest_resolvable_previous_version(updated_version))
162
162
  end
163
163
 
164
- sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
164
+ sig { override.returns(T::Array[Dependabot::DependencyRequirement]) }
165
165
  def updated_requirements
166
166
  resolvable_version =
167
167
  if preferred_resolvable_version.is_a?(version_class)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-bun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.381.0
4
+ version: 0.383.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.381.0
18
+ version: 0.383.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.381.0
25
+ version: 0.383.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -282,6 +282,7 @@ files:
282
282
  - helpers/test/npm6/helpers.js
283
283
  - helpers/test/npm6/updater.test.js
284
284
  - helpers/test/pnpm/fixtures/parser/empty_version/pnpm-lock.yaml
285
+ - helpers/test/pnpm/fixtures/parser/lockfile_v9/pnpm-lock.yaml
285
286
  - helpers/test/pnpm/fixtures/parser/no_lockfile_change/pnpm-lock.yaml
286
287
  - helpers/test/pnpm/fixtures/parser/only_dev_dependencies/pnpm-lock.yaml
287
288
  - helpers/test/pnpm/fixtures/parser/peer_disambiguation/pnpm-lock.yaml
@@ -349,7 +350,7 @@ licenses:
349
350
  - MIT
350
351
  metadata:
351
352
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
352
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.381.0
353
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.383.0
353
354
  rdoc_options: []
354
355
  require_paths:
355
356
  - lib