From 5c8129904fcbe6ec089b29b8e02901aff747c7b5 Mon Sep 17 00:00:00 2001 From: chris48s Date: Mon, 24 Jun 2024 14:53:31 +0100 Subject: [PATCH] Expose `logoBase64` and `links` in badge-maker NPM package (#10283) * expose `logoBase64` and `links` in badge-maker NPM package * add test assertion for logoBase64 * pass (public) `logoBase64` as (internal) `logo` * badge-maker 4.0.0 release --------- Co-authored-by: Sergey Kupletsky --- badge-maker/CHANGELOG.md | 8 +++++++- badge-maker/README.md | 2 ++ badge-maker/index.d.ts | 2 ++ badge-maker/lib/index.js | 37 +++++++++++++++++++++++++++++++---- badge-maker/lib/index.spec.js | 30 ++++++++++++++++++++++++++++ badge-maker/package.json | 2 +- package-lock.json | 2 +- 7 files changed, 76 insertions(+), 7 deletions(-) diff --git a/badge-maker/CHANGELOG.md b/badge-maker/CHANGELOG.md index 3fb2671f75abb..ad347fc3a7916 100644 --- a/badge-maker/CHANGELOG.md +++ b/badge-maker/CHANGELOG.md @@ -1,9 +1,15 @@ # Changelog -## 4.0.0 [WIP] +## 4.0.0 + +### Breaking Changes - Drop compatibility with Node < 16 +### Features + +- Add `links` and `logoBase64` params + ## 3.3.1 - Improve font measuring in for-the-badge and social styles diff --git a/badge-maker/README.md b/badge-maker/README.md index bb6ec1378c94d..5a8c50631ebb0 100644 --- a/badge-maker/README.md +++ b/badge-maker/README.md @@ -67,6 +67,8 @@ The format is the following: message: 'passed', // (Required) Badge message labelColor: '#555', // (Optional) Label color color: '#4c1', // (Optional) Message color + logoBase64: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iOCIgZmlsbD0iI2IxY2U1NiIvPjxwYXRoIGQ9Ik04IDBoMjR2NjRIOGMtNC40MzIgMC04LTMuNTY4LTgtOFY4YzAtNC40MzIgMy41NjgtOCA4LTh6IiBmaWxsPSIjNWQ1ZDVkIi8+PC9zdmc+' // (Optional) Any custom logo can be passed in a URL parameter by base64 encoding + links: ['https://example.com', 'https://example.com'], // (Optional) Links array of maximum two links // (Optional) One of: 'plastic', 'flat', 'flat-square', 'for-the-badge' or 'social' // Each offers a different visual design. diff --git a/badge-maker/index.d.ts b/badge-maker/index.d.ts index 38d71e22b8344..5a1b6872ebe81 100644 --- a/badge-maker/index.d.ts +++ b/badge-maker/index.d.ts @@ -4,6 +4,8 @@ interface Format { labelColor?: string color?: string style?: 'plastic' | 'flat' | 'flat-square' | 'for-the-badge' | 'social' + logoBase64?: string + links?: Array } export declare class ValidationError extends Error {} diff --git a/badge-maker/lib/index.js b/badge-maker/lib/index.js index 051c3d84e9c7b..fa9caec94bf75 100644 --- a/badge-maker/lib/index.js +++ b/badge-maker/lib/index.js @@ -16,13 +16,30 @@ function _validate(format) { throw new ValidationError('Field `message` is required') } - const stringFields = ['labelColor', 'color', 'message', 'label'] + const stringFields = ['labelColor', 'color', 'message', 'label', 'logoBase64'] stringFields.forEach(function (field) { if (field in format && typeof format[field] !== 'string') { throw new ValidationError(`Field \`${field}\` must be of type string`) } }) + if ('links' in format) { + if (!Array.isArray(format.links)) { + throw new ValidationError('Field `links` must be an array of strings') + } else { + if (format.links.length > 2) { + throw new ValidationError( + 'Field `links` must not have more than 2 elements', + ) + } + format.links.forEach(function (field) { + if (typeof field !== 'string') { + throw new ValidationError('Field `links` must be an array of strings') + } + }) + } + } + const styleValues = [ 'plastic', 'flat', @@ -38,11 +55,21 @@ function _validate(format) { } function _clean(format) { - const expectedKeys = ['label', 'message', 'labelColor', 'color', 'style'] + const expectedKeys = [ + 'label', + 'message', + 'labelColor', + 'color', + 'style', + 'logoBase64', + 'links', + ] const cleaned = {} Object.keys(format).forEach(key => { - if (format[key] != null && expectedKeys.includes(key)) { + if (format[key] != null && key === 'logoBase64') { + cleaned.logo = format[key] + } else if (format[key] != null && expectedKeys.includes(key)) { cleaned[key] = format[key] } else { throw new ValidationError( @@ -65,7 +92,9 @@ function _clean(format) { * @param {string} format.message (Required) Badge message (e.g: 'passing') * @param {string} format.labelColor (Optional) Label color * @param {string} format.color (Optional) Message color - * @param {string} format.style (Optional) Visual style e.g: 'flat' + * @param {string} format.style (Optional) Visual style (e.g: 'flat') + * @param {string} format.logoBase64 (Optional) Logo data URL + * @param {Array} format.links (Optional) Links array (e.g: ['https://example.com', 'https://example.com']) * @returns {string} Badge in SVG format * @see https://github.com/badges/shields/tree/master/badge-maker/README.md */ diff --git a/badge-maker/lib/index.spec.js b/badge-maker/lib/index.spec.js index 839aa061e4ff1..5e63453c6c0e9 100644 --- a/badge-maker/lib/index.spec.js +++ b/badge-maker/lib/index.spec.js @@ -25,6 +25,21 @@ describe('makeBadge function', function () { style: 'flat', }), ).to.satisfy(isSvg) + expect( + makeBadge({ + label: 'build', + message: 'passed', + color: 'green', + style: 'flat', + labelColor: 'blue', + logoBase64: 'data:image/svg+xml;base64,PHN2ZyB4bWxu', + links: ['https://example.com', 'https://example.com'], + }), + ) + .to.satisfy(isSvg) + // explicitly make an assertion about logoBase64 + // this param is not a straight passthrough + .and.to.include('data:image/svg+xml;base64,PHN2ZyB4bWxu') }) it('should throw a ValidationError with invalid inputs', function () { @@ -46,6 +61,21 @@ describe('makeBadge function', function () { expect(() => makeBadge({ label: 'build', message: 'passed', labelColor: 7 }), ).to.throw(ValidationError, 'Field `labelColor` must be of type string') + expect(() => + makeBadge({ label: 'build', message: 'passed', logoBase64: 7 }), + ).to.throw(ValidationError, 'Field `logoBase64` must be of type string') + expect(() => + makeBadge({ label: 'build', message: 'passed', links: 'test' }), + ).to.throw(ValidationError, 'Field `links` must be an array of strings') + expect(() => + makeBadge({ label: 'build', message: 'passed', links: [1] }), + ).to.throw(ValidationError, 'Field `links` must be an array of strings') + expect(() => + makeBadge({ label: 'build', message: 'passed', links: ['1', '2', '3'] }), + ).to.throw( + ValidationError, + 'Field `links` must not have more than 2 elements', + ) expect(() => makeBadge({ label: 'build', message: 'passed', format: 'png' }), ).to.throw(ValidationError, "Unexpected field 'format'") diff --git a/badge-maker/package.json b/badge-maker/package.json index 2183feda3bb75..56ec5bfd7249f 100644 --- a/badge-maker/package.json +++ b/badge-maker/package.json @@ -1,6 +1,6 @@ { "name": "badge-maker", - "version": "3.3.1", + "version": "4.0.0", "description": "Shields.io badge library", "keywords": [ "GitHub", diff --git a/package-lock.json b/package-lock.json index d9f6b377809d3..0829a9e6c008d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -133,7 +133,7 @@ } }, "badge-maker": { - "version": "3.3.1", + "version": "4.0.0", "license": "CC0-1.0", "dependencies": { "anafanafo": "2.0.0",