import { NextPage , GetStaticPropsResult , GetStaticPropsContext } from 'next' ; import Head from 'next/head' ; import PackagePage from '../../components/pages/package/PackagePage' ; import { PackageProps , Versions , License , Homepage } from '../../components/pages/package/common' ; import axios from 'axios' ; import hljs from 'highlight.js' ; import cheerio , { CheerioAPI } from 'cheerio' ; import unescape from 'lodash/unescape' ; const Page = ( props ) => { return ( < > < Head > < title > { props . id } - Hackage : The Haskell community ’ s package registry < /title> < meta name = "description" content = { props . shortDescription || props . name } > < /meta> < /Head> < PackagePage { ... props } /> < />); } ; export async function getStaticProps ( props ) { const packageId = props . params ! . packageId as string ; let html = '' ; try { html = await ( await axios ( `https://hackage.haskell.org/package/${ encodeURIComponent ( packageId ) }` ) ) . data ; } catch ( err ) { console . log ( err ) ; } const $ = cheerio . load ( html ) ; monkeyPatchDocument ( $ ) ; const docContent = $ ( '#content' ) ; const name = $ ( 'h1 a' , docContent ) . html ( ) ?. trim ( ) || '' ; const shortDescription = $ ( 'h1 small' , docContent ) . html ( ) ?. trim ( ) || null ; const longDescriptionHtml = $ ( '#description' ) . html ( ) ?. trim ( ) || null ; return { props : { id : packageId , name , versions : getVersions ( $ ) , license : getLicense ( $ ) , homepage : getHomepage ( $ ) , repositoryUrl : getRepositoryUrl ( $ ) , bugReportsUrl : getBugReports ( $ ) , updatedAt : getUpdatedAt ( $ ) , shortDescription , longDescriptionHtml } , revalidate : 10 } ; } export async function getStaticPaths ( ) { return { paths : [ ] , fallback : 'blocking' } ; } const languagesToHighlight = [ 'Haskell' , 'Shell' , 'Bash' , 'Diff' , 'JSON' , 'LaTeX' , 'Protocol Buffers' , 'TOML' , 'XML' , 'YAML' , 'Nix' ] ; function monkeyPatchDocument ( $ ) { $ ( 'a' ) . map ( ( _ , a ) => { $ ( a ) . attr ( 'href' , $ ( a ) . attr ( 'href' ) ?. replace ( 'https://hackage.haskell.org/package/' , '/package/' ) || '#' ) ; } ) ; $ ( 'code, pre' ) . map ( ( _ , el ) => { if ( $ ( el ) . children ( ) . length ) { return el ; } const highlightedHtml = hljs . highlightAuto ( unescape ( $ ( el ) . html ( ) as string ) , languagesToHighlight ) . value ; $ ( el ) . html ( highlightedHtml ) ; $ ( el ) . addClass ( 'hljs' ) ; } ) ; const description = $ ( '#content #description' ) ; const newDescriptionHtml = ( description . html ( ) || '' ) . replace ( `<hr>
    [<a href="#readme">Skip to Readme</a>]` , '' ) . trim ( ) ; description . html ( newDescriptionHtml ) ; } function getVersions ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('Version') + td` , propertiesElement ) . get ( 0 ) ; const current = $ ( `strong` , tableTd ) . text ( ) . trim ( ) ; const available = $ ( '*' , tableTd ) . map ( ( _ , el ) => $ ( el ) . text ( ) . trim ( ) ) . toArray ( ) ; return { current , available } ; } function getLicense ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('License') + td` , propertiesElement ) . get ( 0 ) ; if ( ! tableTd ) { return null ; } const licenseEl = $ ( `> *` , tableTd ) ; return { name : licenseEl . text ( ) , url : licenseEl . attr ( 'href' ) || null } ; } function getHomepage ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('Home page') + td` , propertiesElement ) . get ( 0 ) ; if ( ! tableTd ) { return null ; } const homepageLink = $ ( `a` , tableTd ) ; return { text : homepageLink . text ( ) . trim ( ) , url : homepageLink . attr ( 'href' ) ?. trim ( ) || '#' } ; } function getRepositoryUrl ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('Source') + td` , propertiesElement ) . get ( 0 ) ; if ( ! tableTd ) { return null ; } const repositoryLink = $ ( `a` , tableTd ) ; return repositoryLink . attr ( 'href' ) ?. trim ( ) || null ; } function getBugReports ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('Bug') + td` , propertiesElement ) . get ( 0 ) ; if ( ! tableTd ) { return null ; } const repositoryLink = $ ( `a` , tableTd ) ; return repositoryLink . attr ( 'href' ) ?. trim ( ) || null ; } function getUpdatedAt ( $ ) { const propertiesElement = $ ( '#properties' ) . get ( 0 ) ; const tableTd = $ ( `th:contains('Uploaded') + td` , propertiesElement ) . get ( 0 ) ; if ( ! tableTd ) { return null ; } return $ ( tableTd ) . text ( ) . replace ( /^by .* at / , '' ) . trim ( ) ; } export default Page ;