A PURL (Package URL) parser and serializer, implementing the TC54 PURL specification.
npm install purl
purl [options] <input>
input - An npm package specifier or PURL string--check, -c - Validate the package exists on its registry and show latest version--json - Output only JSON to stdout (no colored PURL output)--help - Show help message--version - Show version number--json, outputs only JSON to stdout (useful for scripting)purl lodash@4.17.21 # outputs pkg:npm/lodash@4.17.21
purl @babel/core@7.0.0 # outputs pkg:npm/%40babel/core@7.0.0
purl express # outputs pkg:npm/express
purl 'pkg:pypi/requests@2.28' # outputs pkg:pypi/requests@2.28
purl -c lodash@4.17.21 # validates package exists, then outputs PURL
--check)npm, pypi, gem, cargo, nuget, hex, maven, composer, pub, hackage, cocoapods
import {
PURL,
parse,
stringify,
valid,
normalize,
eq,
compare,
type,
namespace,
name,
version,
qualifiers,
subpath,
fromNPM,
url,
validate,
validateTypes,
} from 'purl';
PURL classimport PURL from 'purl/purl';
const purl = new PURL('pkg:npm/lodash@4.17.21');
purl.type; // 'npm'
purl.namespace; // null
purl.name; // 'lodash'
purl.version; // '4.17.21'
purl.qualifiers; // null
purl.subpath; // null
String(purl); // 'pkg:npm/lodash@4.17.21'
// From components
const purl2 = new PURL({
type: 'npm',
namespace: '@babel',
name: 'core',
version: '7.0.0',
});
String(purl2); // 'pkg:npm/%40babel/core@7.0.0'
// Instance methods
purl.equals(other); // boolean
purl.compare(other); // -1 | 0 | 1
parse(purl)Parse a PURL string into a PURL object. Returns null if invalid.
import parse from 'purl/parse';
parse('pkg:npm/lodash@4.17.21'); // PURL instance
parse('invalid'); // null
stringify(components)Convert PURL components to a canonical PURL string.
import stringify from 'purl/stringify';
stringify({ type: 'npm', name: 'lodash', version: '4.17.21' });
// 'pkg:npm/lodash@4.17.21'
valid(purl)Returns the normalized PURL string if valid, null otherwise.
import valid from 'purl/valid';
valid('pkg:NPM/lodash@4.17.21'); // 'pkg:npm/lodash@4.17.21'
valid('invalid'); // null
normalize(purl)Normalize a PURL string. Throws if invalid.
import normalize from 'purl/normalize';
normalize('pkg:NPM/lodash@4.17.21'); // 'pkg:npm/lodash@4.17.21'
normalize('invalid'); // throws
eq(a, b)Compare two PURLs for equality.
import eq from 'purl/eq';
eq('pkg:npm/lodash@4.17.21', 'pkg:NPM/lodash@4.17.21'); // true
eq('pkg:npm/lodash@4.17.21', 'pkg:npm/lodash@4.17.20'); // false
compare(a, b)Compare two PURLs for sorting. Returns -1, 0, or 1.
import compare from 'purl/compare';
['pkg:npm/bbb', 'pkg:npm/aaa'].sort(compare);
// ['pkg:npm/aaa', 'pkg:npm/bbb']
Each accessor returns the component value or null if invalid/missing.
import type from 'purl/type';
import namespace from 'purl/namespace';
import name from 'purl/name';
import version from 'purl/version';
import qualifiers from 'purl/qualifiers';
import subpath from 'purl/subpath';
type('pkg:npm/lodash@4.17.21'); // 'npm'
namespace('pkg:npm/%40babel/core'); // '@babel'
name('pkg:npm/lodash@4.17.21'); // 'lodash'
version('pkg:npm/lodash@4.17.21'); // '4.17.21'
qualifiers('pkg:npm/foo?a=b'); // { a: 'b' }
subpath('pkg:npm/foo#lib/index.js'); // 'lib/index.js'
fromNPM(specifier)Convert an npm package specifier to a PURL object.
import fromNPM from 'purl/from-npm';
fromNPM('lodash@4.17.21'); // PURL for pkg:npm/lodash@4.17.21
fromNPM('@babel/core@7.0.0'); // PURL for pkg:npm/%40babel/core@7.0.0
fromNPM('lodash@^4.0.0'); // PURL for pkg:npm/lodash (no version for ranges)
url(purl)Get the registry URL for a PURL.
import url from 'purl/url';
url('pkg:npm/lodash@4.17.21'); // 'https://www.npmjs.com/package/lodash/v/4.17.21'
url('pkg:pypi/requests@2.28.0'); // 'https://pypi.org/project/requests/2.28.0/'
url('pkg:github/ljharb/qs@6.11.0'); // 'https://github.com/ljharb/qs/tree/6.11.0'
validate(purl)Validate a PURL against its package registry. Returns a promise.
import validate, { supportedTypes } from 'purl/validate';
const result = await validate('pkg:npm/lodash@4.17.21');
// { valid: true, latestVersion: '4.17.21' }
const result2 = await validate('pkg:npm/nonexistent-package-xyz');
// { valid: false, error: 'Package "nonexistent-package-xyz" not found on npm', latestVersion: null }
supportedTypes; // ['npm', 'pypi', 'gem', 'cargo', 'nuget', 'hex', 'maven', 'composer', 'pub', 'hackage', 'cocoapods']
Clone the repo, npm install, and run npm test.
Prior to v2, purl was a different package.
v0 was just a placeholder, but v1 can be found both on archive.org and on the original branch of this repo.