You've already forked dynamic-badges-action
This adds the posibility of saving an SVG badge generated by the same shields.io dirictly to the gist. Instead of prepering a JSON file to be sent to their service, we use their library directly, which outputs an SVG file that we can save to the user’s gist. Filenames ending in `.svg` will use this library automatically. Additionally there is a major refactoring where the older `node:http` library has been swapped out for `fetch`. Also swap from node 16 to node 20 fixes #24
77 lines
2.0 KiB
JavaScript
77 lines
2.0 KiB
JavaScript
/**
|
|
* @module
|
|
*/
|
|
|
|
'use strict'
|
|
|
|
function stripXmlWhitespace(xml) {
|
|
return xml.replace(/>\s+/g, '>').replace(/<\s+/g, '<').trim()
|
|
}
|
|
|
|
function escapeXml(s) {
|
|
if (typeof s === 'number') {
|
|
return s
|
|
} else if (s === undefined || typeof s !== 'string') {
|
|
return undefined
|
|
} else {
|
|
return s
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Representation of an XML element
|
|
*/
|
|
class XmlElement {
|
|
/**
|
|
* Xml Element Constructor
|
|
*
|
|
* @param {object} attrs Refer to individual attrs
|
|
* @param {string} attrs.name
|
|
* Name of the XML tag
|
|
* @param {Array.<string|module:badge-maker/lib/xml-element~XmlElement>} [attrs.content=[]]
|
|
* Array of objects to render inside the tag. content may contain a mix of
|
|
* string and XmlElement objects. If content is `[]` or ommitted the
|
|
* element will be rendered as a self-closing element.
|
|
* @param {object} [attrs.attrs={}]
|
|
* Object representing the tag's attributes as name/value pairs
|
|
*/
|
|
constructor({ name, content = [], attrs = {} }) {
|
|
this.name = name
|
|
this.content = content
|
|
this.attrs = attrs
|
|
}
|
|
|
|
/**
|
|
* Render the XML element to a string, applying appropriate escaping
|
|
*
|
|
* @returns {string} String representation of the XML element
|
|
*/
|
|
render() {
|
|
const attrsStr = Object.entries(this.attrs)
|
|
.map(([k, v]) => ` ${k}="${escapeXml(v)}"`)
|
|
.join('')
|
|
if (this.content.length > 0) {
|
|
const content = this.content
|
|
.map(function (el) {
|
|
if (el instanceof XmlElement) {
|
|
return el.render()
|
|
} else {
|
|
return escapeXml(el)
|
|
}
|
|
})
|
|
.join(' ')
|
|
return stripXmlWhitespace(
|
|
`<${this.name}${attrsStr}>${content}</${this.name}>`
|
|
)
|
|
}
|
|
return stripXmlWhitespace(`<${this.name}${attrsStr}/>`)
|
|
}
|
|
}
|
|
|
|
module.exports = { escapeXml, stripXmlWhitespace, XmlElement }
|