@@ -8,6 +8,12 @@ const WINDOWS_RESERVED_RE = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i;
88const WINDOWS_TRAILING_RE = / [ \. ] + $ / ;
99const DEFAULT_REPLACEMENT = "-" ;
1010
11+ let BASE_SCOPE : string ;
12+
13+ export function setBaseScope ( scope : string ) : void {
14+ BASE_SCOPE = scope ;
15+ }
16+
1117export function sanitizeUrlAsFilename (
1218 url : string ,
1319 options ?: SanitizeOptions ,
@@ -19,17 +25,53 @@ export function sanitizeUrlAsFilename(
1925 return DEFAULT_REPLACEMENT ;
2026 }
2127 let filenameBase = url ;
22- try {
23- const urlObj = new URL ( url ) ;
24- const pathAndSearch = `${ urlObj . pathname } ${ urlObj . search } ` ;
25- if ( pathAndSearch === "/" || pathAndSearch === "" ) {
26- filenameBase = urlObj . hostname ;
28+ if ( filenameBase === BASE_SCOPE ) {
29+ filenameBase = new URL ( filenameBase ) . hostname . replace ( / ^ w w w \. / , "" ) ;
30+ } else {
31+ const pathAndSearch = url . replace ( BASE_SCOPE , "" ) . replace ( / ^ \/ + / , "" ) ;
32+ if ( ! pathAndSearch || pathAndSearch === "/" ) {
33+ filenameBase = url . split ( "/" ) . filter ( Boolean ) . pop ( ) || url ;
2734 } else {
2835 filenameBase = pathAndSearch ;
2936 }
30- } catch ( _error ) {
31- // If it's not a valid URL, use as-is
3237 }
38+
39+ const replacement = validReplacementOrDefault (
40+ options ?. replacement ?? DEFAULT_REPLACEMENT ,
41+ ) ;
42+ let sanitized = filenameBase
43+ . replace ( / \/ $ / , "" )
44+ . replace ( ILLEGAL_RE , replacement )
45+ . replace ( CONTROL_RE , replacement )
46+ . replace ( RESERVED_RE , replacement )
47+ . replace ( WINDOWS_RESERVED_RE , replacement )
48+ . replace ( WINDOWS_TRAILING_RE , replacement )
49+ . trim ( ) ;
50+ if ( sanitized . length === 0 ) {
51+ return replacement ;
52+ }
53+ const trimmedName = sanitized . replace ( / ^ [ - _ ] + / , "" ) || sanitized ;
54+ if (
55+ options ?. lengthThreshold &&
56+ trimmedName . length > options . lengthThreshold
57+ ) {
58+ const hash = crypto
59+ . createHash ( "sha1" )
60+ . update ( url )
61+ . digest ( "hex" )
62+ . slice ( 0 , 9 ) ;
63+ const prefix = trimmedName . slice ( 0 , options . lengthThreshold - 10 ) ;
64+ return `${ prefix } _${ hash } ` ;
65+ }
66+ return trimmedName ;
67+ }
68+
69+ export function sanitizeUrlAsDirectoryName (
70+ url : string ,
71+ options ?: SanitizeOptions ,
72+ ) : string {
73+ let filenameBase = url ;
74+ filenameBase = filenameBase . replace ( / ^ ( h t t p s ? : \/ \/ ) ? ( w w w \. ) ? / , "" ) ;
3375 const replacement = validReplacementOrDefault (
3476 options ?. replacement ?? DEFAULT_REPLACEMENT ,
3577 ) ;
0 commit comments