badgen.net/libs/serve-badge.ts

82 wiersze
2.3 KiB
TypeScript

import { badgen } from 'badgen'
2019-05-14 01:36:25 +00:00
import icons from 'badgen-icons'
import originalUrl from 'original-url'
2018-06-29 16:52:17 +00:00
import { IncomingMessage, ServerResponse } from 'http'
2019-05-14 01:36:25 +00:00
import { BadgenParams } from './types'
2018-07-31 13:12:45 +00:00
2019-05-14 01:36:25 +00:00
type ServeBadgeOptions = {
code?: number
sMaxAge?: number,
2019-10-28 16:19:11 +00:00
query?: { [key: string]: string | undefined },
2019-06-03 14:19:17 +00:00
params: BadgenParams
2019-05-14 01:36:25 +00:00
}
export default function (req: IncomingMessage, res: ServerResponse, options: ServeBadgeOptions) {
const { code = 200, sMaxAge = 21600, query = {}, params } = options
2019-06-03 14:19:17 +00:00
const { subject, status, color } = params
const { label, labelColor, icon, iconWidth, list, scale, cache } = query
const _icon = resolveIcon(icon, iconWidth)
2019-06-13 11:07:24 +00:00
// TODO: review usage of list
2019-06-20 03:42:08 +00:00
list && console.log(`FEAT-LIST ${req.url}`)
2019-06-13 11:07:24 +00:00
2018-07-31 13:21:04 +00:00
const badge = badgen({
2019-07-06 10:12:35 +00:00
labelColor,
subject: typeof label !== 'undefined' ? label : subject,
2019-06-13 11:07:24 +00:00
status: transformStatus(status, { list }),
2019-06-10 16:13:27 +00:00
color: query.color || color,
style: autoBadgeStyle(req, query.style),
icon: _icon.src,
2019-10-04 09:50:20 +00:00
iconWidth: parseInt(iconWidth || _icon.width || '13', 10),
scale: parseFloat(scale || '1'),
2018-07-31 13:21:04 +00:00
})
const cacheMaxAge = cache ? Math.max(parseInt(cache as string) || 0, 300) : sMaxAge
res.setHeader('Cache-Control', `public, max-age=120, s-maxage=${cacheMaxAge}, stale-while-revalidate=86400`)
2018-07-25 05:34:22 +00:00
res.setHeader('Content-Type', 'image/svg+xml;charset=utf-8')
2019-05-14 01:36:25 +00:00
res.statusCode = code
res.end(badge)
2018-06-29 16:52:17 +00:00
}
type BadgeStyle = 'flat' | undefined
function autoBadgeStyle (req: IncomingMessage, fallbackValue?: string): BadgeStyle {
const isFlat = (fallbackValue || process.env.BADGE_STYLE === 'flat')
|| originalUrl(req).hostname.includes('flat')
return isFlat ? 'flat' : undefined
}
2019-06-13 11:07:24 +00:00
function transformStatus (status: any, { list }) {
status = String(status)
if (list !== undefined) {
2019-06-20 03:17:59 +00:00
if (list === '1' || list === '') list = '|' // compatible
2019-06-13 11:07:24 +00:00
status = status.replace(/,/g, ` ${list} `)
}
return status
}
type ResolvedIcon = {
src?: string
width?: string
}
2019-10-28 16:19:11 +00:00
function resolveIcon (icon: string | undefined, width?: string): ResolvedIcon {
const builtinIcon = icons[icon]
if (builtinIcon) {
return {
src: builtinIcon.base64,
width: width || builtinIcon.width
}
}
2019-06-20 03:33:53 +00:00
if (String(icon).startsWith('data:image/')) {
return { src: icon, width }
}
return {}
}