1
0
mirror of synced 2026-01-03 15:05:54 -05:00
Files
docs/middleware/product-icons.js
Peter Bengtsson 07a3e2a48c Preview hover cards (#34702)
Co-authored-by: Grace Park <gracepark@github.com>
Co-authored-by: Joe Oak <41307427+joeoak@users.noreply.github.com>
2023-03-21 19:59:49 +00:00

44 lines
1.3 KiB
JavaScript

import express from 'express'
import octicons from '@primer/octicons'
import { defaultCacheControl } from './cache-control.js'
const router = express.Router()
const SVG_CONTENT_TYPE = 'image/svg+xml'
// Returns a client side redirect if one exists for the given path.
router.get('/react/:name', function productIcons(req, res) {
let { name } = req.params
if (name.endsWith('.svg')) {
name = name.replace(/\.svg$/, '')
}
// If the name is `FooBarIcon`, as a key in `octicons` it becomes
// `foo-bar`. The `Icon` is dropped and the capitalization is replaced with
// hyphens.
const asOcticonName = name
.replace(/Icon$/, '')
.replaceAll(/[a-z]([A-Z])/g, (whole, firstLetter) => {
return whole.replace(firstLetter, `-${firstLetter.toLowerCase()}`)
})
.toLowerCase()
// To avoid a "object injection attack", don't just use the square
// bracket. E.g. `someObject['constructor']` is truthy even
// when `const someObject = {foo: "bar"}`.
if (!Object.prototype.hasOwnProperty.call(octicons, asOcticonName)) {
return res.status(404).send('not found')
}
const asIcon = octicons[asOcticonName]
const asSVG = asIcon.toSVG({
xmlns: 'http://www.w3.org/2000/svg',
})
defaultCacheControl(res)
res.set('content-type', SVG_CONTENT_TYPE)
res.status(200).send(Buffer.from(asSVG.trim()))
})
export default router