kopia lustrzana https://github.com/badgen/badgen.net
				
				
				
			
		
			
				
	
	
		
			112 wiersze
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			112 wiersze
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
import { badgen } from 'badgen'
 | 
						|
import icons from 'badgen-icons'
 | 
						|
import originalUrl from 'original-url'
 | 
						|
 | 
						|
import { BadgenParams } from './types'
 | 
						|
 | 
						|
import type { NextApiRequest, NextApiResponse } from 'next'
 | 
						|
 | 
						|
type ServeBadgeOptions = {
 | 
						|
  code?: number
 | 
						|
  sMaxAge?: number,
 | 
						|
  params: BadgenParams
 | 
						|
}
 | 
						|
 | 
						|
export function serveBadgeNext (req: NextApiRequest, res: NextApiResponse, options: ServeBadgeOptions) {
 | 
						|
  const { code = 200, sMaxAge = 3600, params } = options
 | 
						|
  const { subject, status, color } = params
 | 
						|
 | 
						|
  const query = req.query
 | 
						|
  const { list, scale, cache } = req.query
 | 
						|
  const iconMeta = resolveIcon(query.icon, query.iconWidth)
 | 
						|
 | 
						|
  const badgeParams = {
 | 
						|
    labelColor: resolveColor(query.labelColor, '555'),
 | 
						|
    subject: formatSVGText(typeof query.label === 'string' ? query.label : subject),
 | 
						|
    status: formatSVGText(transformStatus(status, { list })),
 | 
						|
    color: resolveColor(query.color || color, 'blue'),
 | 
						|
    style: resolveBadgeStyle(req),
 | 
						|
    icon: iconMeta.src,
 | 
						|
    iconWidth: iconMeta.width,
 | 
						|
    scale: parseFloat(String(scale)) || 1,
 | 
						|
  }
 | 
						|
 | 
						|
  const badgeSVGString = badgen(badgeParams)
 | 
						|
 | 
						|
  // Minimum s-maxage is set to 300s(5m)
 | 
						|
  if (res.getHeader('cache-control') === undefined) {
 | 
						|
    const cacheMaxAge = cache ? Math.max(parseInt(String(cache)), 300) : sMaxAge
 | 
						|
    res.setHeader('cache-control', `public, max-age=86400, s-maxage=${cacheMaxAge}, stale-while-revalidate=86400`)
 | 
						|
  }
 | 
						|
 | 
						|
  res.setHeader('Content-Type', 'image/svg+xml;charset=utf-8')
 | 
						|
  res.statusCode = code
 | 
						|
  res.send(badgeSVGString)
 | 
						|
}
 | 
						|
 | 
						|
function resolveBadgeStyle (req: NextApiRequest, style?: string | string[]): 'flat' | 'classic' {
 | 
						|
  if (style === 'flat') {
 | 
						|
    return 'flat'
 | 
						|
  }
 | 
						|
 | 
						|
  if (process.env.BADGE_STYLE === 'flat') {
 | 
						|
    return 'flat'
 | 
						|
  }
 | 
						|
 | 
						|
  if (originalUrl(req).hostname.includes('flat')) {
 | 
						|
    return 'flat'
 | 
						|
  }
 | 
						|
 | 
						|
  return 'classic'
 | 
						|
}
 | 
						|
 | 
						|
function formatSVGText (text: string): string {
 | 
						|
  return text
 | 
						|
    .replace(/%2F/g, '/') // simple decode
 | 
						|
}
 | 
						|
 | 
						|
function transformStatus (status: any, { list }): string {
 | 
						|
  status = String(status)
 | 
						|
 | 
						|
  if (list !== undefined) {
 | 
						|
    if (list === '1' || list === '') list = '|' // compatible
 | 
						|
    status = status.replace(/,/g, ` ${list} `)
 | 
						|
  }
 | 
						|
 | 
						|
  return status
 | 
						|
}
 | 
						|
 | 
						|
function resolveColor (color: string | string[] | undefined, defaultColor: string): string {
 | 
						|
 | 
						|
  if (color !== undefined) {
 | 
						|
    return String(color)
 | 
						|
  }
 | 
						|
 | 
						|
  return defaultColor
 | 
						|
}
 | 
						|
 | 
						|
type ResolvedIcon = {
 | 
						|
  src?: string
 | 
						|
  width?: number
 | 
						|
}
 | 
						|
 | 
						|
function resolveIcon (icon?: string | string[], width?: string | string[]): ResolvedIcon {
 | 
						|
  const iconArg = String(icon) || ''
 | 
						|
  const widthNum = parseInt(String(width)) || 10
 | 
						|
 | 
						|
  const builtinIcon = icons[icon]
 | 
						|
 | 
						|
  if (builtinIcon) {
 | 
						|
    return {
 | 
						|
      src: builtinIcon.base64,
 | 
						|
      width: widthNum || builtinIcon.width
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (iconArg.startsWith('data:image/')) {
 | 
						|
    return { src: iconArg, width: widthNum }
 | 
						|
  }
 | 
						|
 | 
						|
  return {}
 | 
						|
}
 |