const express = require('express');
const axios = require('axios');
const helmet = require('helmet');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(helmet({
crossOriginResourcePolicy: false,
}));
app.get('/badge', async (req, res) => {
const {
icon = 'simpleicons',
label = 'Simple Icons',
style = 'rect', // badge stílusa: rect (négyzetes), flat (lekerekített sarkok)
bgicon = 'none', // ikon háttérszín, alap: világosszürke
bglabel = 'none', // label háttérszín, alap: sötétszürke
color = '#000000',
size = 24,
labelpos = 'right',
fontweight = 'normal',
} = req.query;
try {
// download icon SVG from SimpleIcons CDN
const iconUrl = `https://cdn.simpleicons.org/${icon}?viewbox=auto&size=${size}`;
const iconResponse = await axios.get(iconUrl, { responseType: 'text' });
if (iconResponse.status !== 200) {
return res.status(404).send('Icon not found');
}
const iconSVG = iconResponse.data;
// if there is no label query, use the title from the SVG
let effectiveLabel = label;
if (!req.query.label || req.query.label === 'Simple Icons') {
const titleMatch = iconSVG.match(/
([^<]+)<\/title>/i);
if (titleMatch && titleMatch[1]) {
effectiveLabel = titleMatch[1];
}
}
// Badge size
const padding = 10;
const iconSize = parseInt(size);
const fontSize = Math.round(iconSize * 0.6);
const textPadding = Math.round(iconSize * 0.4);
const radius = 0;
const approxCharWidth = fontSize * 0.6;
const textWidth = effectiveLabel.length * approxCharWidth;
// Kinyerjük az ikon SVG-ből a width és height attribútumokat (ha vannak)
let iconViewBoxWidth = iconSize;
let iconViewBoxHeight = iconSize;
const widthMatch = iconSVG.match(/width="(\d+\.?\d*)"/);
const heightMatch = iconSVG.match(/height="(\d+\.?\d*)"/);
if (widthMatch) iconViewBoxWidth = parseFloat(widthMatch[1]);
if (heightMatch) iconViewBoxHeight = parseFloat(heightMatch[1]);
// Ikon doboz mérete
const iconBoxWidth = iconViewBoxWidth + 5;
const iconBoxHeight = iconViewBoxHeight + 5;
// Ha a color paraméter nincs megadva, próbáljuk kinyerni az ikon színét
let effectiveColor = color;
if (!req.query.color || req.query.color === '#000000') {
const match = iconSVG.match(/fill="([^"]+)"/);
if (match && match[1]) {
effectiveColor = match[1];
} else {
effectiveColor = "#222"; // fallback
}
}
// doboz magasság 5 pixellel nagyobb legyen az ikon méreténél
const iconSizeAndPadding = iconSize + 5;
const labelRectHeight = fontSize + padding;
let width, height, iconGroup, textElem;
const fontFamily = "Verdana,Geneva,DejaVu Sans,sans-serif";
const fontWeight = fontweight; // paraméterből
if (labelpos === 'left') {
// Külön dobozok: padding csak a széleken kell, a dobozokon belül nem!
textElem = `
${effectiveLabel}`;
iconGroup = `
${iconSVG}
`;
} else if (labelpos === 'above' || labelpos === 'below') {
// Felső vagy alsó label: ikon doboz magassága = iconSize + 5, szélessége = szöveg doboz szélessége
width = Math.max(iiconSizeAndPadding, textWidth);
const iconRectY = labelpos === 'above'
? labelRectHeight
: 0;
const labelRectY = labelpos === 'above'
? 0
: iiconSizeAndPadding;
height = iconSizeAndPadding + textPadding + labelRectHeight;
// Label háttér
const labelRect = ``;
// Ikon háttér
const iconRect = ``;
// Szöveg
const textY = labelpos === 'above'
? labelRectY + 5 + labelRectHeight / 2
: labelRectY + 5 + labelRectHeight / 2;
textElem = `
${labelRect}
${effectiveLabel}
`;
// Ikon
iconGroup = `
${iconRect}
${iconSVG}
`;
} else {
// Alapértelmezett: ikon balra, szöveg jobbra (függőleges közép)
iconGroup = `
${iconSVG}
`;
textElem = `
${effectiveLabel}`;
}
// SVG badge string összefűzéssel, szöveg árnyékkal
const svg = `