@@ -66,6 +66,163 @@ export interface DownloadUrl {
6666 * ```
6767 */
6868export class UrlConverter {
69+ /**
70+ * Get all available URLs for a PackageURL.
71+ *
72+ * This convenience method returns both repository and download URLs
73+ * in a single call, useful when you need to check all URL options.
74+ */
75+ static getAllUrls ( purl : PackageURL ) : {
76+ download : DownloadUrl | null
77+ repository : RepositoryUrl | null
78+ } {
79+ return {
80+ download : this . toDownloadUrl ( purl ) ,
81+ repository : this . toRepositoryUrl ( purl ) ,
82+ }
83+ }
84+
85+ /**
86+ * Check if a PackageURL type supports download URL conversion.
87+ *
88+ * This method checks if the given package type has download URL
89+ * conversion logic implemented.
90+ */
91+ static supportsDownloadUrl ( type : string ) : boolean {
92+ const supportedTypes = [
93+ 'npm' ,
94+ 'pypi' ,
95+ 'maven' ,
96+ 'gem' ,
97+ 'cargo' ,
98+ 'nuget' ,
99+ 'composer' ,
100+ 'hex' ,
101+ 'pub' ,
102+ 'golang' ,
103+ ]
104+ return supportedTypes . includes ( type )
105+ }
106+
107+ /**
108+ * Check if a PackageURL type supports repository URL conversion.
109+ *
110+ * This method checks if the given package type has repository URL
111+ * conversion logic implemented.
112+ */
113+ static supportsRepositoryUrl ( type : string ) : boolean {
114+ const supportedTypes = [
115+ 'npm' ,
116+ 'pypi' ,
117+ 'maven' ,
118+ 'gem' ,
119+ 'golang' ,
120+ 'cargo' ,
121+ 'nuget' ,
122+ 'composer' ,
123+ 'github' ,
124+ 'gitlab' ,
125+ 'bitbucket' ,
126+ 'hex' ,
127+ 'pub' ,
128+ 'luarocks' ,
129+ ]
130+ return supportedTypes . includes ( type )
131+ }
132+
133+ /**
134+ * Convert a PackageURL to a download URL if possible.
135+ *
136+ * This method attempts to generate a download URL where the package's
137+ * artifact (binary, archive, etc.) can be obtained. Requires a version
138+ * to be present in the PackageURL.
139+ */
140+ static toDownloadUrl ( purl : PackageURL ) : DownloadUrl | null {
141+ const { name, namespace, type, version } = purl
142+
143+ if ( ! version ) {
144+ return null
145+ }
146+
147+ switch ( type ) {
148+ case 'npm' : {
149+ const npmName = namespace ? `${ namespace } /${ name } ` : name
150+ return {
151+ type : 'tarball' ,
152+ url : `https://registry.npmjs.org/${ npmName } /-/${ name } -${ version } .tgz` ,
153+ }
154+ }
155+
156+ case 'pypi' :
157+ return {
158+ type : 'wheel' ,
159+ url : `https://pypi.org/simple/${ name } /` ,
160+ }
161+
162+ case 'maven' : {
163+ if ( ! namespace ) {
164+ return null
165+ }
166+ const groupPath = namespace . replace ( / \. / g, '/' )
167+ return {
168+ type : 'jar' ,
169+ url : `https://repo1.maven.org/maven2/${ groupPath } /${ name } /${ version } /${ name } -${ version } .jar` ,
170+ }
171+ }
172+
173+ case 'gem' :
174+ return {
175+ type : 'gem' ,
176+ url : `https://rubygems.org/downloads/${ name } -${ version } .gem` ,
177+ }
178+
179+ case 'cargo' :
180+ return {
181+ type : 'tarball' ,
182+ url : `https://crates.io/api/v1/crates/${ name } /${ version } /download` ,
183+ }
184+
185+ case 'nuget' :
186+ return {
187+ type : 'zip' ,
188+ url : `https://nuget.org/packages/${ name } /${ version } /download` ,
189+ }
190+
191+ case 'composer' :
192+ if ( ! namespace ) {
193+ return null
194+ }
195+ return {
196+ type : 'other' ,
197+ url : `https://repo.packagist.org/p2/${ namespace } /${ name } .json` ,
198+ }
199+
200+ case 'hex' :
201+ return {
202+ type : 'tarball' ,
203+ url : `https://repo.hex.pm/tarballs/${ name } -${ version } .tar` ,
204+ }
205+
206+ case 'pub' :
207+ return {
208+ type : 'tarball' ,
209+ url : `https://pub.dev/packages/${ name } /versions/${ version } .tar.gz` ,
210+ }
211+
212+ case 'golang' :
213+ if ( ! namespace ) {
214+ return null
215+ }
216+ return {
217+ type : 'zip' ,
218+ url : `https://proxy.golang.org/${ namespace } /${ name } /@v/${ version } .zip` ,
219+ }
220+
221+ default :
222+ return null
223+ }
224+ }
225+
69226 /**
70227 * Convert a PackageURL to a repository URL if possible.
71228 *
@@ -182,161 +339,4 @@ export class UrlConverter {
182339 return null
183340 }
184341 }
185-
186- /**
187- * Convert a PackageURL to a download URL if possible.
188- *
189- * This method attempts to generate a download URL where the package's
190- * artifact (binary, archive, etc.) can be obtained. Requires a version
191- * to be present in the PackageURL.
192- */
193- static toDownloadUrl ( purl : PackageURL ) : DownloadUrl | null {
194- const { name, namespace, type, version } = purl
195-
196- if ( ! version ) {
197- return null
198- }
199-
200- switch ( type ) {
201- case 'npm' : {
202- const npmName = namespace ? `${ namespace } /${ name } ` : name
203- return {
204- type : 'tarball' ,
205- url : `https://registry.npmjs.org/${ npmName } /-/${ name } -${ version } .tgz` ,
206- }
207- }
208-
209- case 'pypi' :
210- return {
211- type : 'wheel' ,
212- url : `https://pypi.org/simple/${ name } /` ,
213- }
214-
215- case 'maven' : {
216- if ( ! namespace ) {
217- return null
218- }
219- const groupPath = namespace . replace ( / \. / g, '/' )
220- return {
221- type : 'jar' ,
222- url : `https://repo1.maven.org/maven2/${ groupPath } /${ name } /${ version } /${ name } -${ version } .jar` ,
223- }
224- }
225-
226- case 'gem' :
227- return {
228- type : 'gem' ,
229- url : `https://rubygems.org/downloads/${ name } -${ version } .gem` ,
230- }
231-
232- case 'cargo' :
233- return {
234- type : 'tarball' ,
235- url : `https://crates.io/api/v1/crates/${ name } /${ version } /download` ,
236- }
237-
238- case 'nuget' :
239- return {
240- type : 'zip' ,
241- url : `https://nuget.org/packages/${ name } /${ version } /download` ,
242- }
243-
244- case 'composer' :
245- if ( ! namespace ) {
246- return null
247- }
248- return {
249- type : 'other' ,
250- url : `https://repo.packagist.org/p2/${ namespace } /${ name } .json` ,
251- }
252-
253- case 'hex' :
254- return {
255- type : 'tarball' ,
256- url : `https://repo.hex.pm/tarballs/${ name } -${ version } .tar` ,
257- }
258-
259- case 'pub' :
260- return {
261- type : 'tarball' ,
262- url : `https://pub.dev/packages/${ name } /versions/${ version } .tar.gz` ,
263- }
264-
265- case 'golang' :
266- if ( ! namespace ) {
267- return null
268- }
269- return {
270- type : 'zip' ,
271- url : `https://proxy.golang.org/${ namespace } /${ name } /@v/${ version } .zip` ,
272- }
273-
274- default :
275- return null
276- }
277- }
278-
279- /**
280- * Get all available URLs for a PackageURL.
281- *
282- * This convenience method returns both repository and download URLs
283- * in a single call, useful when you need to check all URL options.
284- */
285- static getAllUrls ( purl : PackageURL ) : {
286- download : DownloadUrl | null
287- repository : RepositoryUrl | null
288- } {
289- return {
290- download : this . toDownloadUrl ( purl ) ,
291- repository : this . toRepositoryUrl ( purl ) ,
292- }
293- }
294-
295- /**
296- * Check if a PackageURL type supports repository URL conversion.
297- *
298- * This method checks if the given package type has repository URL
299- * conversion logic implemented.
300- */
301- static supportsRepositoryUrl ( type : string ) : boolean {
302- const supportedTypes = [
303- 'npm' ,
304- 'pypi' ,
305- 'maven' ,
306- 'gem' ,
307- 'golang' ,
308- 'cargo' ,
309- 'nuget' ,
310- 'composer' ,
311- 'github' ,
312- 'gitlab' ,
313- 'bitbucket' ,
314- 'hex' ,
315- 'pub' ,
316- 'luarocks' ,
317- ]
318- return supportedTypes . includes ( type )
319- }
320-
321- /**
322- * Check if a PackageURL type supports download URL conversion.
323- *
324- * This method checks if the given package type has download URL
325- * conversion logic implemented.
326- */
327- static supportsDownloadUrl ( type : string ) : boolean {
328- const supportedTypes = [
329- 'npm' ,
330- 'pypi' ,
331- 'maven' ,
332- 'gem' ,
333- 'cargo' ,
334- 'nuget' ,
335- 'composer' ,
336- 'hex' ,
337- 'pub' ,
338- 'golang' ,
339- ]
340- return supportedTypes . includes ( type )
341- }
342342}
0 commit comments