Skip to content

Commit

Permalink
add function to return pacakge purl
Browse files Browse the repository at this point in the history
Signed-off-by: Brian DeHamer <bdehamer@github.com>
  • Loading branch information
bdehamer committed Nov 29, 2022
1 parent 103c0fd commit e54906b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ included then the default is `latest`.

**Throws** if the package name is invalid, a dist-tag is invalid or a URL's protocol is not supported.

### var purl = npa.toPurl(*name*, *spec*)

Returns the purl (package URL) form of the given pacakge name/spec.

* *name* - The name of the module you want to install. For example: `foo` or `@bar/foo`.
* *spec* - The specifier indicating the semver-formatted version of the module. Something like:
`1.2` or `1.7.17`.

**Throws** if the package name is invalid, or the supplied version is not a valid semver value.

## RESULT OBJECT

The objects that are returned by npm-package-arg contain the following
Expand Down
25 changes: 25 additions & 0 deletions lib/npa.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'
module.exports = npa
module.exports.resolve = resolve
module.exports.toPurl = toPurl
module.exports.Result = Result

const url = require('url')
Expand Down Expand Up @@ -87,6 +88,23 @@ function resolve (name, spec, where, arg) {
}
}

function toPurl (name, spec) {
const raw = name + '@' + spec

const valid = validatePackageName(name)
if (!valid.validForNewPackages) {
throw invalidPackageName(name, valid, raw)
}

const version = semver.valid(spec, true)
if (!version) {
throw invalidVersion(version, raw)
}

// URI-encode leading @ of scoped packages
return 'pkg:npm/' + name.replace(/^@/, '%40') + '@' + version
}

function invalidPackageName (name, valid, raw) {
// eslint-disable-next-line max-len
const err = new Error(`Invalid package name "${name}" of package "${raw}": ${valid.errors.join('; ')}.`)
Expand All @@ -101,6 +119,13 @@ function invalidTagName (name, raw) {
return err
}

function invalidVersion (version, raw) {
// eslint-disable-next-line max-len
const err = new Error(`Invalid version "${version}" of package "${raw}": Version must be a valid semver value.`)
err.code = 'EINVALIDVERSION'
return err
}

function Result (opts) {
this.type = opts.type
this.registry = opts.registry
Expand Down
27 changes: 27 additions & 0 deletions test/purl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict'
var test = require('tap').test
var npa = require('..')

test('toPurl - valid', function (t) {
// Unscoped package
t.equal(npa.toPurl('foo', '1.2.3'), 'pkg:npm/foo@1.2.3')

// Scoped package
t.equal(npa.toPurl('@foo/bar', '1.2.3-alpha.1'), 'pkg:npm/%40foo/bar@1.2.3-alpha.1')

t.end()
})

test('toPurl - invalid', function (t) {
// Invalid version
t.throws(() => npa.toPurl('foo/bar', '1.2.3'), {
code: 'EINVALIDPACKAGENAME',
})

// Invalid version
t.throws(() => npa.toPurl('foo', 'a.b.c'), {
code: 'EINVALIDVERSION',
})

t.end()
})

0 comments on commit e54906b

Please sign in to comment.