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,209 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require "excon"
5
- require "time"
6
-
7
- module Dependabot
8
- module Javascript
9
- module Shared
10
- class MetadataFinder < Dependabot::MetadataFinders::Base
11
- def homepage_url
12
- # Attempt to use version_listing first, as fetching the entire listing
13
- # array can be slow (if it's large)
14
- return latest_version_listing["homepage"] if latest_version_listing["homepage"]
15
-
16
- listing = all_version_listings.find { |_, l| l["homepage"] }
17
- listing&.last&.fetch("homepage", nil) || super
18
- end
19
-
20
- def maintainer_changes
21
- return unless npm_releaser
22
- return unless npm_listing.dig("time", dependency.version)
23
- return if previous_releasers.include?(npm_releaser)
24
-
25
- "This version was pushed to npm by " \
26
- "[#{npm_releaser}](https://www.npmjs.com/~#{npm_releaser}), a new " \
27
- "releaser for #{dependency.name} since your current version."
28
- end
29
-
30
- private
31
-
32
- def look_up_source
33
- return find_source_from_registry if new_source.nil?
34
-
35
- source_type = new_source[:type] || new_source.fetch("type")
36
-
37
- case source_type
38
- when "git" then find_source_from_git_url
39
- when "registry" then find_source_from_registry
40
- else raise "Unexpected source type: #{source_type}"
41
- end
42
- end
43
-
44
- def npm_releaser
45
- all_version_listings
46
- .find { |v, _| v == dependency.version }
47
- &.last&.fetch("_npmUser", nil)&.fetch("name", nil)
48
- end
49
-
50
- def previous_releasers
51
- times = npm_listing.fetch("time")
52
-
53
- cutoff =
54
- if dependency.previous_version && times[dependency.previous_version]
55
- Time.parse(times[dependency.previous_version])
56
- elsif times[dependency.version]
57
- Time.parse(times[dependency.version]) - 1
58
- end
59
- return unless cutoff
60
-
61
- all_version_listings
62
- .reject { |v, _| Time.parse(times[v]) > cutoff }
63
- .filter_map { |_, d| d.fetch("_npmUser", nil)&.fetch("name", nil) }
64
- end
65
-
66
- def find_source_from_registry
67
- # Attempt to use version_listing first, as fetching the entire listing
68
- # array can be slow (if it's large)
69
- potential_sources =
70
- [
71
- get_source(latest_version_listing["repository"]),
72
- get_source(latest_version_listing["homepage"]),
73
- get_source(latest_version_listing["bugs"])
74
- ].compact
75
-
76
- return potential_sources.first if potential_sources.any?
77
-
78
- potential_sources =
79
- all_version_listings.flat_map do |_, listing|
80
- [
81
- get_source(listing["repository"]),
82
- get_source(listing["homepage"]),
83
- get_source(listing["bugs"])
84
- ]
85
- end.compact
86
-
87
- potential_sources.first
88
- end
89
-
90
- def new_source
91
- sources = dependency.requirements
92
- .map { |r| r.fetch(:source) }.uniq.compact
93
- .sort_by do |source|
94
- UpdateChecker::RegistryFinder.central_registry?(source[:url]) ? 1 : 0
95
- end
96
-
97
- sources.first
98
- end
99
-
100
- def get_source(details)
101
- potential_url = get_url(details)
102
- return unless potential_url
103
-
104
- potential_source = Source.from_url(potential_url)
105
- return unless potential_source
106
-
107
- potential_source.directory = get_directory(details)
108
- potential_source
109
- end
110
-
111
- def get_url(details)
112
- url =
113
- case details
114
- when String then details
115
- when Hash then details.fetch("url", nil)
116
- end
117
- return url unless url&.match?(%r{^[\w.-]+/[\w.-]+$})
118
-
119
- "https://github.com/" + url
120
- end
121
-
122
- def get_directory(details)
123
- # Only return a directory if it is explicitly specified
124
- return unless details.is_a?(Hash)
125
-
126
- details.fetch("directory", nil)
127
- end
128
-
129
- def find_source_from_git_url
130
- url = new_source[:url] || new_source.fetch("url")
131
- Source.from_url(url)
132
- end
133
-
134
- def latest_version_listing
135
- return @latest_version_listing if defined?(@latest_version_listing)
136
-
137
- response = Dependabot::RegistryClient.get(url: "#{dependency_url}/latest", headers: registry_auth_headers)
138
- return @latest_version_listing = JSON.parse(response.body) if response.status == 200
139
-
140
- @latest_version_listing = {}
141
- rescue JSON::ParserError, Excon::Error::Timeout
142
- @latest_version_listing = {}
143
- end
144
-
145
- def all_version_listings
146
- return [] if npm_listing["versions"].nil?
147
-
148
- npm_listing["versions"]
149
- .reject { |_, details| details["deprecated"] }
150
- .sort_by { |version, _| Version.new(version) }
151
- .reverse
152
- end
153
-
154
- def npm_listing
155
- return @npm_listing unless @npm_listing.nil?
156
-
157
- response = Dependabot::RegistryClient.get(url: dependency_url, headers: registry_auth_headers)
158
- return @npm_listing = {} if response.status >= 500
159
-
160
- begin
161
- @npm_listing = JSON.parse(response.body)
162
- rescue JSON::ParserError
163
- raise unless non_standard_registry?
164
-
165
- @npm_listing = {}
166
- end
167
- rescue Excon::Error::Timeout
168
- @npm_listing = {}
169
- end
170
-
171
- def dependency_url
172
- registry_url =
173
- if new_source.nil? then "https://registry.npmjs.org"
174
- else
175
- new_source.fetch(:url)
176
- end
177
-
178
- # NPM registries expect slashes to be escaped
179
- escaped_dependency_name = dependency.name.gsub("/", "%2F")
180
- "#{registry_url}/#{escaped_dependency_name}"
181
- end
182
-
183
- def registry_auth_headers
184
- return {} unless auth_token
185
-
186
- { "Authorization" => "Bearer #{auth_token}" }
187
- end
188
-
189
- def dependency_registry
190
- if new_source.nil? then "registry.npmjs.org"
191
- else
192
- new_source.fetch(:url).gsub("https://", "").gsub("http://", "")
193
- end
194
- end
195
-
196
- def auth_token
197
- credentials
198
- .select { |cred| cred["type"] == "npm_registry" }
199
- .find { |cred| cred["registry"] == dependency_registry }
200
- &.fetch("token", nil)
201
- end
202
-
203
- def non_standard_registry?
204
- dependency_registry != "registry.npmjs.org"
205
- end
206
- end
207
- end
208
- end
209
- end
@@ -1,21 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Dependabot
5
- module Javascript
6
- module Shared
7
- module NativeHelpers
8
- def self.helper_path
9
- "node #{File.join(native_helpers_root, 'run.js')}"
10
- end
11
-
12
- def self.native_helpers_root
13
- helpers_root = ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", nil)
14
- return File.join(helpers_root, "javascript", "shared") unless helpers_root.nil?
15
-
16
- File.join(__dir__, "../../../helpers")
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,72 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Dependabot
5
- module Javascript
6
- module Shared
7
- class PackageManagerDetector
8
- extend T::Sig
9
- extend T::Helpers
10
-
11
- sig do
12
- params(
13
- lockfiles: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
14
- package_json: T.nilable(T::Hash[String, T.untyped])
15
- ).void
16
- end
17
- def initialize(lockfiles, package_json)
18
- @lockfiles = lockfiles
19
- @package_json = package_json
20
- @manifest_package_manager = T.let(package_json&.fetch(MANIFEST_PACKAGE_MANAGER_KEY, nil), T.nilable(String))
21
- @engines = T.let(package_json&.fetch(MANIFEST_ENGINES_KEY, {}), T::Hash[String, T.untyped])
22
- end
23
-
24
- # Returns npm, yarn, or pnpm based on the lockfiles, package.json, and engines
25
- # Defaults to npm if no package manager is detected
26
- sig { returns(String) }
27
- def detect_package_manager
28
- package_manager = name_from_lockfiles ||
29
- name_from_package_manager_attr ||
30
- name_from_engines
31
-
32
- if package_manager
33
- Dependabot.logger.info("Detected package manager: #{package_manager}")
34
- else
35
- package_manager = DEFAULT_PACKAGE_MANAGER
36
- Dependabot.logger.info("Default package manager used: #{package_manager}")
37
- end
38
- package_manager
39
- rescue StandardError => e
40
- Dependabot.logger.error("Error detecting package manager: #{e.message}")
41
- DEFAULT_PACKAGE_MANAGER
42
- end
43
-
44
- private
45
-
46
- sig { returns(T.nilable(String)) }
47
- def name_from_lockfiles
48
- PACKAGE_MANAGER_CLASSES.keys.map(&:to_s).find { |manager_name| @lockfiles[manager_name.to_sym] }
49
- end
50
-
51
- sig { returns(T.nilable(String)) }
52
- def name_from_package_manager_attr
53
- return unless @manifest_package_manager
54
-
55
- PACKAGE_MANAGER_CLASSES.keys.map(&:to_s).find do |manager_name|
56
- @manifest_package_manager.start_with?("#{manager_name}@")
57
- end
58
- end
59
-
60
- sig { returns(T.nilable(String)) }
61
- def name_from_engines
62
- return unless @engines.is_a?(Hash)
63
-
64
- PACKAGE_MANAGER_CLASSES.each_key do |manager_name|
65
- return manager_name if @engines[manager_name]
66
- end
67
- nil
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,118 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module Dependabot
5
- module Javascript
6
- module Shared
7
- class PackageName
8
- extend T::Sig
9
-
10
- # NPM package naming rules are defined by the following projects:
11
- # - https://github.com/npm/npm-user-validate
12
- # - https://github.com/npm/validate-npm-package-name
13
- PACKAGE_NAME_REGEX = %r{
14
- \A # beginning of string
15
- (?=.{1,214}\z) # enforce length (1 - 214)
16
- (@(?<scope> # capture 'scope' if present
17
- [a-z0-9\-\_\.\!\~\*\'\(\)]+ # URL-safe characters in scope
18
- )\/)? # scope must be followed by slash
19
- (?<name> # capture package name
20
- (?(<scope>) # if scope is present
21
- [a-z0-9\-\_\.\!\~\*\'\(\)]+ # scoped names can start with any URL-safe character
22
- | # if no scope
23
- [a-z0-9\-\!\~\*\'\(\)] # non-scoped names cannot start with . or _
24
- [a-z0-9\-\_\.\!\~\*\'\(\)]* # subsequent characters can be any URL-safe character
25
- )
26
- )
27
- \z # end of string
28
- }xi # multi-line/case-insensitive
29
-
30
- TYPES_PACKAGE_NAME_REGEX = %r{
31
- \A # beginning of string
32
- @types\/ # starts with @types/
33
- ((?<scope>.+)__)? # capture scope
34
- (?<name>.+) # capture name
35
- \z # end of string
36
- }xi # multi-line/case-insensitive
37
-
38
- class InvalidPackageName < StandardError; end
39
-
40
- sig { params(string: String).void }
41
- def initialize(string)
42
- match = PACKAGE_NAME_REGEX.match(string.to_s)
43
- raise InvalidPackageName unless match
44
-
45
- @scope = T.let(match[:scope], T.nilable(String))
46
- @name = T.let(match[:name], T.nilable(String))
47
- end
48
-
49
- sig { returns(String) }
50
- def to_s
51
- if scoped?
52
- "@#{@scope}/#{@name}"
53
- else
54
- @name.to_s
55
- end
56
- end
57
-
58
- sig { params(other: PackageName).returns(T::Boolean) }
59
- def eql?(other)
60
- self.class == other.class && to_s == other.to_s
61
- end
62
-
63
- sig { returns(Integer) }
64
- def hash
65
- to_s.downcase.hash
66
- end
67
-
68
- sig { params(other: PackageName).returns(T.nilable(Integer)) }
69
- def <=>(other)
70
- to_s.casecmp(other.to_s)
71
- end
72
-
73
- sig { returns(T.nilable(PackageName)) }
74
- def library_name
75
- return unless types_package?
76
- return @library_name if defined?(@library_name)
77
-
78
- lib_name =
79
- begin
80
- match = T.must(TYPES_PACKAGE_NAME_REGEX.match(to_s))
81
- if match[:scope]
82
- self.class.new("@#{match[:scope]}/#{match[:name]}")
83
- else
84
- self.class.new(match[:name].to_s)
85
- end
86
- end
87
-
88
- @library_name ||= T.let(lib_name, T.nilable(PackageName))
89
- end
90
-
91
- sig { returns(T.nilable(PackageName)) }
92
- def types_package_name
93
- return if types_package?
94
-
95
- @types_package_name ||= T.let(
96
- if scoped?
97
- self.class.new("@types/#{@scope}__#{@name}")
98
- else
99
- self.class.new("@types/#{@name}")
100
- end, T.nilable(PackageName)
101
- )
102
- end
103
-
104
- private
105
-
106
- sig { returns(T::Boolean) }
107
- def scoped?
108
- !@scope.nil?
109
- end
110
-
111
- sig { returns(T.nilable(T::Boolean)) }
112
- def types_package?
113
- "types".casecmp?(@scope)
114
- end
115
- end
116
- end
117
- end
118
- end
@@ -1,190 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "yaml"
5
- require "dependabot/dependency_file"
6
- require "sorbet-runtime"
7
-
8
- module Dependabot
9
- module Javascript
10
- module Shared
11
- class RegistryHelper
12
- extend T::Sig
13
-
14
- # Keys for configurations
15
- REGISTRY_KEY = "registry"
16
- AUTH_KEY = "authToken"
17
-
18
- # Yarn-specific keys
19
- NPM_AUTH_TOKEN_KEY_FOR_YARN = "npmAuthToken"
20
- NPM_SCOPE_KEY_FOR_YARN = "npmScopes"
21
- NPM_REGISTER_KEY_FOR_YARN = "npmRegistryServer"
22
-
23
- # Environment variable keys
24
- COREPACK_NPM_REGISTRY_ENV = "COREPACK_NPM_REGISTRY"
25
- COREPACK_NPM_TOKEN_ENV = "COREPACK_NPM_TOKEN"
26
-
27
- sig do
28
- params(
29
- registry_config_files: T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)],
30
- credentials: T.nilable(T::Array[Dependabot::Credential])
31
- ).void
32
- end
33
- def initialize(registry_config_files, credentials)
34
- @registry_config_files = T.let(registry_config_files, T::Hash[Symbol, T.nilable(Dependabot::DependencyFile)])
35
- @credentials = T.let(credentials, T.nilable(T::Array[Dependabot::Credential]))
36
- end
37
-
38
- sig { returns(T::Hash[String, String]) }
39
- def find_corepack_env_variables
40
- registry_info = find_registry_and_token
41
-
42
- env_variables = {}
43
- env_variables[COREPACK_NPM_REGISTRY_ENV] = registry_info[:registry] if registry_info[:registry]
44
- env_variables[COREPACK_NPM_TOKEN_ENV] = registry_info[:auth_token] if registry_info[:auth_token]
45
-
46
- env_variables
47
- end
48
-
49
- private
50
-
51
- sig { returns(T::Hash[Symbol, T.nilable(String)]) }
52
- def find_registry_and_token
53
- # Step 1: Check dependabot.yml configuration
54
- dependabot_config = config_npm_registry_and_token
55
- return dependabot_config if dependabot_config[:registry]
56
-
57
- # Step 2: Check .npmrc
58
- npmrc_config = @registry_config_files[:npmrc]
59
- npmrc_result = parse_registry_from_npmrc_yarnrc(npmrc_config, "=", "npm")
60
-
61
- return npmrc_result if npmrc_result[:registry]
62
-
63
- # Step 3: Check .yarnrc
64
- yarnrc_config = @registry_config_files[:yarnrc]
65
- yarnrc_result = parse_registry_from_npmrc_yarnrc(yarnrc_config, " ", "npm")
66
- return yarnrc_result if yarnrc_result[:registry]
67
-
68
- # Step 4: Check yarnrc.yml
69
- yarnrc_yml_config = @registry_config_files[:yarnrc_yml]
70
- yarnrc_yml_result = parse_npm_from_yarnrc_yml(yarnrc_yml_config)
71
- return yarnrc_yml_result if yarnrc_yml_result[:registry]
72
-
73
- # Default values if no registry is found
74
- {}
75
- end
76
-
77
- sig { returns(T::Hash[Symbol, T.nilable(String)]) }
78
- def config_npm_registry_and_token
79
- registries = {}
80
-
81
- return registries unless @credentials&.any?
82
-
83
- @credentials.each do |cred|
84
- next unless cred["type"] == "npm_registry" # Skip if not an npm registry
85
- next unless cred["replaces-base"] # Skip if not a reverse-proxy registry
86
-
87
- # Set the registry if it's not already set
88
- registries[:registry] ||= cred["registry"]
89
-
90
- # Set the token if it's not already set
91
- registries[:auth_token] ||= cred["token"]
92
- end
93
- registries
94
- end
95
-
96
- # Find registry and token in .npmrc or .yarnrc file
97
- sig do
98
- params(
99
- file: T.nilable(Dependabot::DependencyFile),
100
- separator: String
101
- ).returns(T::Hash[Symbol, T.nilable(String)])
102
- end
103
- def parse_npm_from_npm_or_yarn_rc(file, separator = "=")
104
- parse_registry_from_npmrc_yarnrc(file, separator, "npm")
105
- end
106
-
107
- # Find registry and token in .npmrc or .yarnrc file
108
- sig do
109
- params(
110
- file: T.nilable(Dependabot::DependencyFile),
111
- separator: String,
112
- scope: T.nilable(String)
113
- ).returns(T::Hash[Symbol, T.nilable(String)])
114
- end
115
- def parse_registry_from_npmrc_yarnrc(file, separator = "=", scope = nil)
116
- content = file&.content
117
- return { registry: nil, auth_token: nil } unless content
118
-
119
- global_registry = T.let(nil, T.nilable(String))
120
- scoped_registry = T.let(nil, T.nilable(String))
121
- auth_token = T.let(nil, T.nilable(String))
122
-
123
- content.split("\n").each do |line|
124
- # Split using the provided separator
125
- key, value = line.strip.split(separator, 2)
126
- next unless key && value
127
-
128
- # Remove surrounding quotes from keys and values
129
- cleaned_key = key.strip.gsub(/\A["']|["']\z/, "")
130
- cleaned_value = value.strip.gsub(/\A["']|["']\z/, "")
131
-
132
- case cleaned_key
133
- when "registry"
134
- # Case 1: Found a global registry
135
- global_registry = cleaned_value
136
- when "_authToken"
137
- # Case 2: Found an auth token
138
- auth_token = cleaned_value
139
- else
140
- # Handle scoped registry if a scope is provided
141
- scoped_registry = cleaned_value if scope && cleaned_key == "@#{scope}:registry"
142
- end
143
- end
144
-
145
- # Determine the registry to return (global first, fallback to scoped)
146
- registry = global_registry || scoped_registry
147
-
148
- { registry: registry, auth_token: auth_token }
149
- end
150
-
151
- # rubocop:disable Metrics/PerceivedComplexity
152
- sig { params(file: T.nilable(Dependabot::DependencyFile)).returns(T::Hash[Symbol, T.nilable(String)]) }
153
- def parse_npm_from_yarnrc_yml(file)
154
- content = file&.content
155
- return { registry: nil, auth_token: nil } unless content
156
-
157
- result = {}
158
- yaml_data = safe_load_yaml(content)
159
-
160
- # Step 1: Extract global registry and auth token
161
- result[:registry] = yaml_data[NPM_REGISTER_KEY_FOR_YARN] if yaml_data.key?(NPM_REGISTER_KEY_FOR_YARN)
162
- result[:auth_token] = yaml_data[NPM_AUTH_TOKEN_KEY_FOR_YARN] if yaml_data.key?(NPM_AUTH_TOKEN_KEY_FOR_YARN)
163
-
164
- # Step 2: Fallback to any scoped registry and auth token if global is missing
165
- if result[:registry].nil? && yaml_data.key?(NPM_SCOPE_KEY_FOR_YARN)
166
- yaml_data[NPM_SCOPE_KEY_FOR_YARN].each do |_current_scope, config|
167
- next unless config.is_a?(Hash)
168
-
169
- result[:registry] ||= config[NPM_REGISTER_KEY_FOR_YARN]
170
- result[:auth_token] ||= config[NPM_AUTH_TOKEN_KEY_FOR_YARN]
171
- end
172
- end
173
-
174
- result
175
- end
176
- # rubocop:enable Metrics/PerceivedComplexity
177
-
178
- # Safely loads the YAML content and logs any parsing errors
179
- sig { params(content: String).returns(T::Hash[String, T.untyped]) }
180
- def safe_load_yaml(content)
181
- YAML.safe_load(content, permitted_classes: [Symbol, String]) || {}
182
- rescue Psych::SyntaxError => e
183
- # Log the error instead of raising it
184
- Dependabot.logger.error("YAML parsing error: #{e.message}")
185
- {}
186
- end
187
- end
188
- end
189
- end
190
- end