packageurl-js
Advanced tools
Comparing version 0.0.7 to 1.0.0
@@ -0,1 +1,5 @@ | ||
# 1.0.0 | ||
### Features | ||
* Add enum-like static readonly property `KnownQualifierNames` to reflect known qualifier names [#34](https://github.com/package-url/packageurl-js/pull/34) | ||
# 0.0.7 | ||
@@ -2,0 +6,0 @@ ### Bug Fixes |
{ | ||
"name": "packageurl-js", | ||
"version": "0.0.7", | ||
"version": "1.0.0", | ||
"description": "JavaScript library to parse and build \"purl\" aka. package URLs. This is a microlibrary implementing the purl spec at https://github.com/package-url", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -34,2 +34,14 @@ /*! | ||
/** | ||
* Known qualifiers names. | ||
* @see {@link https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs specification} | ||
*/ | ||
static KnownQualifierNames: Readonly<{ | ||
RepositoryUrl:'repository_url', | ||
DownloadUrl: 'download_url', | ||
VcsUrl: 'vcs_url', | ||
FileName: 'file_name', | ||
Checksum: 'checksum' | ||
}> | ||
/** | ||
* the package "type" or package "protocol" such as maven, npm, nuget, gem, pypi, etc. Required. | ||
@@ -66,7 +78,7 @@ */ | ||
constructor(type: string, | ||
namespace: string | undefined | null, | ||
name: string, | ||
constructor(type: string, | ||
namespace: string | undefined | null, | ||
name: string, | ||
version: string | undefined | null, | ||
qualifiers: { [key: string]: string; } | undefined | null, | ||
qualifiers: { [key: string]: string; } | undefined | null, | ||
subpath: string | undefined | null); | ||
@@ -73,0 +85,0 @@ |
@@ -22,4 +22,19 @@ /*! | ||
*/ | ||
const KnownQualifierNames = Object.freeze({ | ||
// known qualifiers as defined here: | ||
// https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs | ||
RepositoryUrl: 'repository_url', | ||
DownloadUrl: 'download_url', | ||
VcsUrl: 'vcs_url', | ||
FileName: 'file_name', | ||
Checksum: 'checksum' | ||
}); | ||
class PackageURL { | ||
static get KnownQualifierNames() { | ||
return KnownQualifierNames; | ||
} | ||
constructor(type, namespace, name, version, qualifiers, subpath) { | ||
@@ -112,3 +127,3 @@ let required = { 'type': type, 'name': name }; | ||
var [scheme, remainder] = purl.split(':'); | ||
let [scheme, remainder] = purl.split(':', 2); | ||
if (scheme !== 'pkg') { | ||
@@ -121,4 +136,4 @@ throw new Error('purl is missing the required "pkg" scheme component.'); | ||
let type = remainder.split('/')[0]; | ||
var remainder = remainder.split('/').slice(1).join('/'); | ||
let type | ||
[type, remainder] = remainder.split('/', 2); | ||
if (!type || !remainder) { | ||
@@ -125,0 +140,0 @@ throw new Error('purl is missing the required "type" component.'); |
@@ -24,56 +24,115 @@ /*! | ||
const assert = require('assert'); | ||
const TEST_FILE = require(__dirname + '/data/test-suite-data.json'); | ||
const TEST_FILE = require('./data/test-suite-data.json'); | ||
/** @type {import('../src/package-url')} */ | ||
const PackageURL = require('../src/package-url'); | ||
describe('PackageURL', function () { | ||
TEST_FILE.forEach(function (obj) { | ||
if (obj.is_invalid) { | ||
it('should not be possible to create invalid PackageURLs', function () { | ||
try { | ||
describe('fromString()', function () { | ||
it('with qualifiers.checksums', function () { | ||
const purlString = 'pkg:npm/packageurl-js@0.0.7?checksums=sha512:b9c27369720d948829a98118e9a35fd09d9018711e30dc2df5f8ae85bb19b2ade4679351c4d96768451ee9e841e5f5a36114a9ef98f4fe5256a5f4ca981736a0' | ||
const purl = PackageURL.fromString(purlString) | ||
assert.strictEqual(purl.type, 'npm') | ||
assert.strictEqual(purl.namespace, null) | ||
assert.strictEqual(purl.name, 'packageurl-js') | ||
assert.strictEqual(purl.version, '0.0.7') | ||
assert.deepStrictEqual(purl.qualifiers, { | ||
checksums: 'sha512:b9c27369720d948829a98118e9a35fd09d9018711e30dc2df5f8ae85bb19b2ade4679351c4d96768451ee9e841e5f5a36114a9ef98f4fe5256a5f4ca981736a0' | ||
}) | ||
}); | ||
it('with qualifiers.vcs_url', function () { | ||
const purlString = 'pkg:npm/packageurl-js@0.0.7?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2Fpackage-url%2Fpackageurl-js.git' | ||
const purl = PackageURL.fromString(purlString) | ||
assert.strictEqual(purl.type, 'npm') | ||
assert.strictEqual(purl.namespace, null) | ||
assert.strictEqual(purl.name, 'packageurl-js') | ||
assert.strictEqual(purl.version, '0.0.7') | ||
assert.deepStrictEqual(purl.qualifiers, { | ||
vcs_url: 'git+https://github.com/package-url/packageurl-js.git' | ||
}) | ||
}); | ||
}); | ||
describe('test-suite-data', function () { | ||
TEST_FILE.forEach(function (obj) { | ||
if (obj.is_invalid) { | ||
it('should not be possible to create invalid PackageURLs', function () { | ||
try { | ||
var purl = new PackageURL(obj.type, obj.namespace, obj.name, obj.version, obj.qualifiers, obj.subpath); | ||
assert.fail(); | ||
} catch (e) { | ||
assert.equal(true, e.toString().includes('is a required field') || e.toString().includes('Invalid purl')); | ||
} | ||
}); | ||
it('should not be possible to parse invalid PackageURLs', function () { | ||
try { | ||
PackageURL.fromString(obj.purl); | ||
} catch (e) { | ||
assert.equal(true, e.toString().includes('Error: purl is missing the required') || e.toString().includes('Invalid purl')); | ||
} | ||
}); | ||
} else { | ||
it('should be able to create valid PackageURLs', function () { | ||
var purl = new PackageURL(obj.type, obj.namespace, obj.name, obj.version, obj.qualifiers, obj.subpath); | ||
assert.fail(); | ||
} catch (e) { | ||
assert.equal(true, e.toString().includes('is a required field') || e.toString().includes('Invalid purl')); | ||
} | ||
assert.equal(obj.type, purl.type); | ||
assert.equal(obj.name, purl.name); | ||
assert.equal(obj.namespace, purl.namespace); | ||
assert.equal(obj.version, purl.version); | ||
assert.equal(JSON.stringify(obj.qualifiers), JSON.stringify(purl.qualifiers)); | ||
assert.equal(obj.subpath, purl.subpath); | ||
}); | ||
it('should be able to convert valid PackageURLs to a string', function () { | ||
var purl = new PackageURL(obj.type, obj.namespace, obj.name, obj.version, obj.qualifiers, obj.subpath); | ||
assert.equal(obj.canonical_purl, purl.toString()); | ||
}); | ||
it('should be able to parse valid PackageURLs', function () { | ||
var purl = PackageURL.fromString(obj.canonical_purl); | ||
assert.equal(purl.toString(), obj.canonical_purl); | ||
assert.equal(purl.type, obj.type); | ||
assert.equal(purl.name, obj.name); | ||
assert.equal(purl.namespace, obj.namespace); | ||
assert.equal(purl.version, obj.version); | ||
assert.equal(JSON.stringify(purl.qualifiers), JSON.stringify(obj.qualifiers)); | ||
assert.equal(purl.subpath, obj.subpath); | ||
}); | ||
it('should handle pypi package-urls per the purl-spec', function () { | ||
const purlMixedCasing = PackageURL.fromString('pkg:pypi/PYYaml@5.3.0'); | ||
assert.strictEqual(purlMixedCasing.toString(), 'pkg:pypi/pyyaml@5.3.0'); | ||
const purlWithUnderscore = PackageURL.fromString('pkg:pypi/typing_extensions_blah@1.0.0'); | ||
assert.strictEqual(purlWithUnderscore.toString(), 'pkg:pypi/typing-extensions-blah@1.0.0'); | ||
}); | ||
} | ||
}) | ||
}); | ||
describe('KnownQualifierNames', function () { | ||
describe('check access', function () { | ||
[ | ||
['RepositoryUrl', 'repository_url'], | ||
['DownloadUrl', 'download_url'], | ||
['VcsUrl', 'vcs_url'], | ||
['FileName', 'file_name'], | ||
['Checksum', 'checksum'] | ||
].forEach(function ([name, expectedValue]) { | ||
it(`maps: ${name} => ${expectedValue}`, function () { | ||
assert.strictEqual(PackageURL.KnownQualifierNames[name], expectedValue); | ||
}); | ||
}); | ||
it('should not be possible to parse invalid PackageURLs', function () { | ||
try { | ||
PackageURL.fromString(obj.purl); | ||
} catch (e) { | ||
assert.equal(true, e.toString().includes('Error: purl is missing the required') || e.toString().includes('Invalid purl')); | ||
} | ||
}); | ||
} else { | ||
it('should be able to create valid PackageURLs', function () { | ||
var purl = new PackageURL(obj.type, obj.namespace, obj.name, obj.version, obj.qualifiers, obj.subpath); | ||
assert.equal(obj.type, purl.type); | ||
assert.equal(obj.name, purl.name); | ||
assert.equal(obj.namespace, purl.namespace); | ||
assert.equal(obj.version, purl.version); | ||
assert.equal(JSON.stringify(obj.qualifiers), JSON.stringify(purl.qualifiers)); | ||
assert.equal(obj.subpath, purl.subpath); | ||
}); | ||
it('should be able to convert valid PackageURLs to a string', function () { | ||
var purl = new PackageURL(obj.type, obj.namespace, obj.name, obj.version, obj.qualifiers, obj.subpath); | ||
assert.equal(obj.canonical_purl, purl.toString()); | ||
}); | ||
it('should be able to parse valid PackageURLs', function () { | ||
var purl = PackageURL.fromString(obj.canonical_purl); | ||
assert.equal(purl.toString(), obj.canonical_purl); | ||
assert.equal(purl.type, obj.type); | ||
assert.equal(purl.name, obj.name); | ||
assert.equal(purl.namespace, obj.namespace); | ||
assert.equal(purl.version, obj.version); | ||
assert.equal(JSON.stringify(purl.qualifiers), JSON.stringify(obj.qualifiers)); | ||
assert.equal(purl.subpath, obj.subpath); | ||
}); | ||
it('should handle pypi package-urls per the purl-spec', function () { | ||
const purlMixedCasing = PackageURL.fromString('pkg:pypi/PYYaml@5.3.0'); | ||
assert.strictEqual(purlMixedCasing.toString(), 'pkg:pypi/pyyaml@5.3.0'); | ||
const purlWithUnderscore = PackageURL.fromString('pkg:pypi/typing_extensions_blah@1.0.0'); | ||
assert.strictEqual(purlWithUnderscore.toString(), 'pkg:pypi/typing-extensions-blah@1.0.0'); | ||
}); | ||
} | ||
}); | ||
it('readonly: cannot be written', function () { | ||
PackageURL.KnownQualifierNames = {foo: 'bar'}; | ||
assert.notDeepStrictEqual(PackageURL.KnownQualifierNames, {foo: 'bar'}) | ||
}); | ||
it('frozen: cannot be modified', function () { | ||
PackageURL.KnownQualifierNames.foo = 'bar'; | ||
assert.strictEqual(PackageURL.KnownQualifierNames.foo, undefined) | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
36132
14
780
0
0