diff --git a/src/package-url.d.ts b/src/package-url.d.ts index 63802bf..e0b44c1 100644 --- a/src/package-url.d.ts +++ b/src/package-url.d.ts @@ -120,12 +120,14 @@ declare module "packageurl-js" { static Type: PurlType /** - * The package "type" or package "protocol" such as maven, npm, nuget, gem, pypi, etc. Required. + * The package "type" or package "protocol" such as maven, npm, nuget, gem, + * pypi, etc. Required. */ type: string /** - * Some name prefix such as a Maven groupid, a Docker image owner, a GitHub user or organization. Optional and type-specific. + * Some name prefix such as a Maven groupid, a Docker image owner, a GitHub + * user or organization. Optional and type-specific. */ namespace: string | undefined @@ -140,7 +142,8 @@ declare module "packageurl-js" { version: string | undefined /** - * Extra qualifying data for a package such as an OS, architecture, a distro, etc. Optional and type-specific. + * Extra qualifying data for a package such as an OS, architecture, a distro, + * etc. Optional and type-specific. */ qualifiers: PurlQualifiers | undefined @@ -165,9 +168,20 @@ declare module "packageurl-js" { /** * Parses a purl string into a PackageURL instance. - * @param purlStr string to parse */ static fromString(purlStr: string): PackageURL + + /** + * Parses a purl string into a PackageURL arguments array. + */ + static parseString(purlStr: string): [ + type: string | undefined, + namespace: string | undefined, + name: string | undefined, + version: string | undefined, + qualifiers: PurlQualifiers | undefined, + subpath: string | undefined + ] } export const PurlComponent = {} diff --git a/src/package-url.js b/src/package-url.js index 1887c93..e15e431 100644 --- a/src/package-url.js +++ b/src/package-url.js @@ -481,10 +481,24 @@ class PackageURL { } static fromString(purlStr) { + return new PackageURL(...PackageURL.parseString(purlStr)) + } + + static parseString(purlStr) { // https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#how-to-parse-a-purl-string-in-its-components - if (typeof purlStr !== 'string' || isBlank(purlStr)) { + if (typeof purlStr !== 'string') { throw new Error('A purl string argument is required.') } + if (isBlank(purlStr)) { + return [ + undefined, + undefined, + undefined, + undefined, + undefined, + undefined + ] + } // Split the remainder once from left on ':'. const colonIndex = purlStr.indexOf(':') @@ -510,7 +524,7 @@ class PackageURL { // The scheme is a constant with the value "pkg". if (url.protocol !== 'pkg:') { throw new Error( - 'purl is missing the required "pkg" scheme component.' + 'Invalid purl: missing required "pkg" scheme component' ) } @@ -524,10 +538,20 @@ class PackageURL { const { pathname } = url const firstSlashIndex = pathname.indexOf('/') + const rawType = + firstSlashIndex === -1 + ? pathname + : pathname.slice(0, firstSlashIndex) if (firstSlashIndex < 1) { - throw new Error('Invalid purl: missing required "type" component') + return [ + rawType, + undefined, + undefined, + undefined, + undefined, + undefined + ] } - const rawType = pathname.slice(0, firstSlashIndex) let rawVersion let atSignIndex = pathname.lastIndexOf('@') @@ -576,14 +600,14 @@ class PackageURL { rawSubpath = hash.slice(1) } - return new PackageURL( + return [ rawType, rawNamespace, rawName, rawVersion, rawQualifiers, rawSubpath - ) + ] } }