import type * as d from '../../declarations' ; import { catchError } from '@utils' ; export const crawlAnchorsForNextUrls = ( prerenderConfig , diagnostics , baseUrl , currentUrl , parsedAnchors ) => { if ( ! Array . isArray ( parsedAnchors ) || parsedAnchors . length === 0 ) { return [ ] ; } const basePathParts = baseUrl . pathname . split ( '/' ) ; return parsedAnchors . filter ( ( anchor ) => { if ( typeof prerenderConfig . filterAnchor === 'function' ) { try { const userFilterAnchor = prerenderConfig . filterAnchor ( anchor , currentUrl ) ; if ( userFilterAnchor === false ) { return false ; } } catch ( e ) { catchError ( diagnostics , e ) ; return false ; } } return standardFilterAnchor ( diagnostics , anchor , currentUrl ) ; } ) . map ( ( anchor ) => { if ( typeof prerenderConfig . normalizeUrl === 'function' ) { try { const userNormalizedUrl = prerenderConfig . normalizeUrl ( anchor . href , currentUrl ) ; return standardNormalizeUrl ( diagnostics , userNormalizedUrl . href , currentUrl ) ; } catch ( e ) { catchError ( diagnostics , e ) ; } } return standardNormalizeUrl ( diagnostics , anchor . href , currentUrl ) ; } ) . filter ( ( url ) => { if ( typeof prerenderConfig . filterUrl === 'function' ) { try { const userFilterUrl = prerenderConfig . filterUrl ( url , currentUrl ) ; if ( userFilterUrl === false ) { return false ; } } catch ( e ) { catchError ( diagnostics , e ) ; return false ; } } return standardFilterUrl ( diagnostics , url , currentUrl , basePathParts ) ; } ) . map ( ( url ) => { return standardNormalizeHref ( prerenderConfig , diagnostics , url ) ; } ) . reduce ( ( hrefs , href ) => { if ( ! hrefs . includes ( href ) ) { hrefs . push ( href ) ; } return hrefs ; } , [ ] as string [ ] ) . sort ( ( a , b ) => { const partsA = a . split ( '/' ) . length ; const partsB = b . split ( '/' ) . length ; if ( partsA < partsB ) return - 1 ; if ( partsA > partsB ) return 1 ; if ( a < b ) return - 1 ; if ( a > b ) return 1 ; return 0 ; } ) ; } ; const standardFilterAnchor = ( diagnostics , attrs , _base ) => { try { let href = attrs . href ; if ( typeof attrs . download === 'string' ) { return false ; } if ( typeof href === 'string' ) { href = href . trim ( ) ; if ( href !== '' && ! href . startsWith ( '#' ) && ! href . startsWith ( '?' ) ) { const target = attrs . target ; if ( typeof target === 'string' && attrs . target . trim ( ) . toLowerCase ( ) !== '_self' ) { return false ; } return true ; } } } catch ( e ) { catchError ( diagnostics , e ) ; } return false ; } ; const standardNormalizeUrl = ( diagnostics , href , currentUrl ) => { if ( typeof href === 'string' ) { try { const outputUrl = new URL ( href , currentUrl . href ) ; outputUrl . protocol = currentUrl . href ; outputUrl . hash = '' ; outputUrl . search = '' ; const parts = outputUrl . pathname . split ( '/' ) ; const lastPart = parts [ parts . length - 1 ] ; if ( lastPart === 'index.html' || lastPart === 'index.htm' ) { parts . pop ( ) ; outputUrl . pathname = parts . join ( '/' ) ; } return outputUrl ; } catch ( e ) { catchError ( diagnostics , e ) ; } } return null ; } ; const standardFilterUrl = ( diagnostics , url , currentUrl , basePathParts ) => { try { if ( url . hostname != null && currentUrl . hostname != null && url . hostname !== currentUrl . hostname ) { return false ; } if ( shouldSkipExtension ( url . pathname ) ) { return false ; } const inputPathParts = url . pathname . split ( '/' ) ; if ( inputPathParts . length < basePathParts . length ) { return false ; } for ( let i = 0 ; i < basePathParts . length ; i ++ ) { const basePathPart = basePathParts [ i ] ; const inputPathPart = inputPathParts [ i ] ; if ( basePathParts . length - 1 === i && basePathPart === '' ) { break ; } if ( basePathPart !== inputPathPart ) { return false ; } } return true ; } catch ( e ) { catchError ( diagnostics , e ) ; } return false ; } ; export const standardNormalizeHref = ( prerenderConfig , diagnostics , url ) => { try { if ( url != null && typeof url . href === 'string' ) { let href = url . href . trim ( ) ; if ( prerenderConfig . trailingSlash ) { if ( ! href . endsWith ( '/' ) ) { const parts = url . pathname . split ( '/' ) ; const lastPart = parts [ parts . length - 1 ] ; if ( ! lastPart . includes ( '.' ) ) { href += '/' ; } } } else { if ( href . endsWith ( '/' ) && url . pathname !== '/' ) { href = href . substr ( 0 , href . length - 1 ) ; } } return href ; } } catch ( e ) { catchError ( diagnostics , e ) ; } return null ; } ; const shouldSkipExtension = ( filename ) => SKIP_EXT . has ( extname ( filename ) . toLowerCase ( ) ) ; const extname = ( str ) => { const parts = str . split ( '.' ) ; return parts [ parts . length - 1 ] . toLowerCase ( ) ; } ; const SKIP_EXT = new Set ( [ 'zip' , 'rar' , 'tar' , 'gz' , 'bz2' , 'png' , 'jpeg' , 'jpg' , 'gif' , 'pdf' , 'tiff' , 'psd' ] ) ;