import http from 'http' import matchRoute from 'my-way' import { serveMarked } from 'serve-marked' import serve404 from '../libs/serve-404' import { BadgenServeConfig } from '../libs/create-badgen-handler' const { GA_MEASUREMENT_ID = 'G-PD7EFJDYFV' } = process.env export default function serveDoc (conf: BadgenServeConfig): http.RequestListener { return (req, res) => { const helpMarkdown = generateHelpMarkdown(conf) if (helpMarkdown) { res.setHeader('Cache-Control', 'public, max-age=86400, s-maxage=604800, stale-while-revalidate=86400') return serveMarked(helpMarkdown, { title: `${conf.title} badge | Badgen`, inlineCSS, beforeHeadEnd: ` `, beforeBodyEnd: helpFooter, })(req, res) } serve404(req, res) } } function generateHelpMarkdown ({ title, help, examples, handlers }: BadgenServeConfig): string { const mainTitle = `# ${title} Badge` const customHelp = help || '' const exampleTitle = `## Examples` const routes = Object.keys(handlers) const categorizedExamples = Object.entries(examples).reduce((accu, [url, desc]) => { const scheme = routes.find(route => matchRoute(route, url)) if (scheme) { accu[scheme] ? accu[scheme].push({ url, desc }) : accu[scheme] = [{ url, desc }] } return accu }, {}) const examplesSection = Object.entries(categorizedExamples).reduce((accu, [header, list]) => { const hash = hashify(header) const h4 = `

${header.replace(/

` const ul = (list as Array).reduce((acc, { url, desc }) => { return `${acc}\n- ![${url}](${url}) [${url}](${url}) ${desc}` }, '') return `${accu}\n\n${h4}\n\n${ul}` }, '') return [mainTitle, customHelp, exampleTitle, examplesSection].join('\n\n') } // turn `/github/:topic/:owner/:repo/:ref?` // into `github-topic-commits-last-commit-owner-repo-ref` function hashify (str: string) { // return str.replace(/[^\w]/g, '') return str.split(/[^\w]+/).filter(Boolean).join('-') } const inlineCSS = ` html, body { scroll-behavior: smooth } .markdown-body { max-width: 960px; min-height: calc(100vh - 348px) } .markdown-body h1 { margin-bottom: 42px } li > img { vertical-align: middle; margin: 0.2em 0; font-size: 12px; float: right } li > img + a { font-family: monospace; font-size: 0.9em } li > img + a + i { color: #AAA } h4 a code { color: #333; font-size: 1rem } h4 a:hover { text-decoration: none !important } h4 { padding: 4px 0 } ` const helpFooter = ` `