@@ -14,12 +14,17 @@ const BUNDLEPHOBIA_API = 'https://bundlephobia.com/api/size'
1414const NPMS_API = 'https://api.npms.io/v2/package'
1515
1616const SafeStringSchema = v . pipe ( v . string ( ) , v . regex ( / ^ [ ^ < > " & ] * $ / , 'Invalid characters' ) )
17+ const SafeColorSchema = v . pipe (
18+ v . string ( ) ,
19+ v . transform ( value => ( value . startsWith ( '#' ) ? value : `#${ value } ` ) ) ,
20+ v . hexColor ( ) ,
21+ )
1722
1823const QUERY_SCHEMA = v . object ( {
19- color : v . optional ( SafeStringSchema ) ,
2024 name : v . optional ( v . string ( ) ) ,
21- labelColor : v . optional ( SafeStringSchema ) ,
2225 label : v . optional ( SafeStringSchema ) ,
26+ color : v . optional ( SafeColorSchema ) ,
27+ labelColor : v . optional ( SafeColorSchema ) ,
2328} )
2429
2530const COLORS = {
@@ -184,26 +189,26 @@ function renderShieldsBadgeSvg(params: {
184189 const rightTextLengthAttr = rightTextLength * 10
185190
186191 return `
187- <svg xmlns="http://www.w3.org/2000/svg" width="${ totalWidth } " height="${ height } " role="img" aria-label="${ title } ">
188- <linearGradient id="s" x2="0" y2="100%">
189- <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
190- <stop offset="1" stop-opacity=".1"/>
191- </linearGradient>
192- <clipPath id="r">
193- <rect width="${ totalWidth } " height="${ height } " rx="3" fill="#fff"/>
194- </clipPath>
195- <g clip-path="url(#r)">
196- <rect width="${ leftWidth } " height="${ height } " fill="${ finalLabelColor } "/>
197- <rect x="${ leftWidth } " width="${ rightWidth } " height="${ height } " fill="${ finalColor } "/>
198- <rect width="${ totalWidth } " height="${ height } " fill="url(#s)"/>
199- </g>
200- <g text-anchor="middle" font-family="Verdana, Geneva, DejaVu Sans, sans-serif" text-rendering="geometricPrecision" font-size="110">
201- <text aria-hidden="true" x="${ leftCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
202- <text x="${ leftCenter } " y="140" transform="scale(.1)" fill="${ labelTextColor } " textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
203- <text aria-hidden="true" x="${ rightCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
204- <text x="${ rightCenter } " y="140" transform="scale(.1)" fill="${ valueTextColor } " textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
205- </g>
206- </svg>
192+ <svg xmlns="http://www.w3.org/2000/svg" width="${ totalWidth } " height="${ height } " role="img" aria-label="${ title } ">
193+ <linearGradient id="s" x2="0" y2="100%">
194+ <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
195+ <stop offset="1" stop-opacity=".1"/>
196+ </linearGradient>
197+ <clipPath id="r">
198+ <rect width="${ totalWidth } " height="${ height } " rx="3" fill="#fff"/>
199+ </clipPath>
200+ <g clip-path="url(#r)">
201+ <rect width="${ leftWidth } " height="${ height } " fill="${ finalLabelColor } "/>
202+ <rect x="${ leftWidth } " width="${ rightWidth } " height="${ height } " fill="${ finalColor } "/>
203+ <rect width="${ totalWidth } " height="${ height } " fill="url(#s)"/>
204+ </g>
205+ <g text-anchor="middle" font-family="Verdana, Geneva, DejaVu Sans, sans-serif" text-rendering="geometricPrecision" font-size="110">
206+ <text aria-hidden="true" x="${ leftCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
207+ <text x="${ leftCenter } " y="140" transform="scale(.1)" fill="${ labelTextColor } " textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
208+ <text aria-hidden="true" x="${ rightCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
209+ <text x="${ rightCenter } " y="140" transform="scale(.1)" fill="${ valueTextColor } " textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
210+ </g>
211+ </svg>
207212 ` . trim ( )
208213}
209214
0 commit comments