From fb4885d79df649bc6a6741f8537824b39f0fa554 Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Tue, 7 Apr 2026 13:33:20 +0200 Subject: [PATCH] fix(build): filter unmirrorable notes --- scripts/build/mirror.js | 34 ++++++++++++++--- scripts/build/mirror.test.js | 71 +++++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/scripts/build/mirror.js b/scripts/build/mirror.js index c8188a893cd067..45553e16fdbd2c 100644 --- a/scripts/build/mirror.js +++ b/scripts/build/mirror.js @@ -156,23 +156,43 @@ export const getMatchingBrowserVersion = (targetBrowser, sourceVersion) => { * @param {(string) => (string | false)} versionMapper - Receives the source browser version and returns the target browser version. * @returns {Notes | null} The notes with replacement performed */ -const updateNotes = (notes, regex, replace, versionMapper) => { +export const updateNotes = (notes, regex, replace, versionMapper) => { if (!notes) { return null; } if (Array.isArray(notes)) { - return /** @type {Notes} */ ( - notes.map((note) => updateNotes(note, regex, replace, versionMapper)) - ); + const mapped = notes + .map((note) => updateNotes(note, regex, replace, versionMapper)) + .filter(Boolean); + + if (mapped.length === 0) { + return null; + } + + if (mapped.length === 1) { + return /** @type {Notes} */ (mapped[0]); + } + + return /** @type {Notes} */ (mapped); } - return notes + let hasUnmappedVersion = false; + const result = notes .replace(regex, replace) .replace( new RegExp(`(${replace}|version)\\s(\\d+)`, 'g'), - (match, p1, p2) => p1 + ' ' + versionMapper(p2), + (match, p1, p2) => { + const mapped = versionMapper(p2); + if (mapped === false) { + hasUnmappedVersion = true; + return match; + } + return p1 + ' ' + mapped; + }, ); + + return hasUnmappedVersion ? null : result; }; /** @@ -306,6 +326,8 @@ export const bumpSupport = (sourceData, sourceBrowser, destination) => { ); if (newNotes) { newData.notes = newNotes; + } else { + delete newData.notes; } } diff --git a/scripts/build/mirror.test.js b/scripts/build/mirror.test.js index 30468fe4bda99e..41c7d21e81037c 100644 --- a/scripts/build/mirror.test.js +++ b/scripts/build/mirror.test.js @@ -10,7 +10,7 @@ import assert from 'node:assert/strict'; import bcd from '../../index.js'; -import mirrorSupport, { isOSLimitation } from './mirror.js'; +import mirrorSupport, { isOSLimitation, updateNotes } from './mirror.js'; describe('mirror', () => { describe('isOSLimitation', () => { @@ -172,6 +172,75 @@ describe('mirror', () => { } }); + describe('updateNotes', () => { + /** @type {(string) => (string | false)} */ + const versionMapper = (v) => (v === '99' ? false : String(Number(v) + 1)); + const regex = /\bChrome\b/g; + + it('notes with unmapped versions are filtered out', () => { + assert.equal( + updateNotes( + 'Supported since Chrome 99.', + regex, + 'Opera', + versionMapper, + ), + null, + ); + }); + + it('notes without version references are kept unchanged', () => { + assert.equal( + updateNotes( + 'Supported on ChromeOS, macOS, and Windows.', + regex, + 'Opera', + versionMapper, + ), + 'Supported on ChromeOS, macOS, and Windows.', + ); + }); + + it('notes with mapped versions are updated', () => { + assert.equal( + updateNotes( + 'Supported since Chrome 70.', + regex, + 'Opera', + versionMapper, + ), + 'Supported since Opera 71.', + ); + }); + + it('in an array, only notes with unmapped versions are filtered out', () => { + assert.deepEqual( + updateNotes( + [ + 'Supported on ChromeOS, macOS, and Windows.', + 'Supported since Chrome 99.', + ], + regex, + 'Opera', + versionMapper, + ), + 'Supported on ChromeOS, macOS, and Windows.', + ); + }); + + it('returns null when all array notes are filtered out', () => { + assert.equal( + updateNotes( + ['Supported since Chrome 99.', 'Available since Chrome 99.'], + regex, + 'Opera', + versionMapper, + ), + null, + ); + }); + }); + describe('Notes', () => { it('version numbers in notes are mapped', () => { /** @type {InternalSupportBlock} */