@@ -21,13 +21,14 @@ SOFTWARE.
2121*/
2222'use strict'
2323
24- const { decodeURIComponent } = require ( './decode' )
24+ const { decodePurlComponent } = require ( './decode' )
2525const { isObject, recursiveFreeze } = require ( './objects' )
2626const { isBlank, isNonEmptyString, trimLeadingSlashes } = require ( './strings' )
2727
2828const { PurlComponent } = require ( './purl-component' )
2929const { PurlQualifierNames } = require ( './purl-qualifier-names' )
3030const { PurlType } = require ( './purl-type' )
31+ const { PurlError } = require ( './error' )
3132
3233class PackageURL {
3334 static Component = recursiveFreeze ( PurlComponent )
@@ -149,31 +150,28 @@ class PackageURL {
149150 ? url
150151 : new URL ( purlStr )
151152 } catch ( e ) {
152- throw new Error ( 'Invalid purl: failed to parse as URL', {
153+ throw new PurlError ( ' failed to parse as URL', {
153154 cause : e
154155 } )
155156 }
156157 }
157158 // The scheme is a constant with the value "pkg".
158159 if ( url ?. protocol !== 'pkg:' ) {
159- throw new Error (
160- 'Invalid purl: missing required "pkg" scheme component'
161- )
160+ throw new PurlError ( 'missing required "pkg" scheme component' )
162161 }
163162 // A purl must NOT contain a URL Authority i.e. there is no support for
164163 // username, password, host and port components.
165164 if (
166165 maybeUrlWithAuth . username !== '' ||
167166 maybeUrlWithAuth . password !== ''
168167 ) {
169- throw new Error (
170- 'Invalid purl: cannot contain a "user:pass@host:port"'
171- )
168+ throw new PurlError ( 'cannot contain a "user:pass@host:port"' )
172169 }
173170
174171 const { pathname } = url
175172 const firstSlashIndex = pathname . indexOf ( '/' )
176- const rawType = decodeURIComponent (
173+ const rawType = decodePurlComponent (
174+ 'type' ,
177175 firstSlashIndex === - 1
178176 ? pathname
179177 : pathname . slice ( 0 , firstSlashIndex )
@@ -206,29 +204,37 @@ class PackageURL {
206204 )
207205 if ( atSignIndex !== - 1 ) {
208206 // Split the remainder once from right on '@'.
209- rawVersion = decodeURIComponent ( pathname . slice ( atSignIndex + 1 ) )
207+ rawVersion = decodePurlComponent (
208+ 'version' ,
209+ pathname . slice ( atSignIndex + 1 )
210+ )
210211 }
211212
212213 let rawNamespace
213214 let rawName
214215 const lastSlashIndex = beforeVersion . lastIndexOf ( '/' )
215216 if ( lastSlashIndex === - 1 ) {
216217 // Split the remainder once from right on '/'.
217- rawName = decodeURIComponent ( beforeVersion )
218+ rawName = decodePurlComponent ( 'name' , beforeVersion )
218219 } else {
219220 // Split the remainder once from right on '/'.
220- rawName = decodeURIComponent (
221+ rawName = decodePurlComponent (
222+ 'name' ,
221223 beforeVersion . slice ( lastSlashIndex + 1 )
222224 )
223225 // Split the remainder on '/'.
224- rawNamespace = decodeURIComponent (
226+ rawNamespace = decodePurlComponent (
227+ 'namespace' ,
225228 beforeVersion . slice ( 0 , lastSlashIndex )
226229 )
227230 }
228231
229232 let rawQualifiers
230233 const { searchParams } = url
231234 if ( searchParams . size !== 0 ) {
235+ searchParams . forEach ( ( value ) =>
236+ decodePurlComponent ( 'qualifiers' , value )
237+ )
232238 // Split the remainder once from right on '?'.
233239 rawQualifiers = searchParams
234240 }
@@ -237,7 +243,7 @@ class PackageURL {
237243 const { hash } = url
238244 if ( hash . length !== 0 ) {
239245 // Split the purl string once from right on '#'.
240- rawSubpath = decodeURIComponent ( hash . slice ( 1 ) )
246+ rawSubpath = decodePurlComponent ( 'subpath' , hash . slice ( 1 ) )
241247 }
242248
243249 return [
0 commit comments