diff --git a/src/generators/metadata/utils/__tests__/transformers.test.mjs b/src/generators/metadata/utils/__tests__/transformers.test.mjs index 79f25ac5..ef625d4c 100644 --- a/src/generators/metadata/utils/__tests__/transformers.test.mjs +++ b/src/generators/metadata/utils/__tests__/transformers.test.mjs @@ -61,4 +61,18 @@ describe('transformTypeToReferenceLink', () => { '[``](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#string_type) | [``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#number_type)> | [``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#boolean_type)' ); }); + + it('should transform an intersection type joined with & into linked parts', () => { + strictEqual( + transformTypeToReferenceLink('{string&boolean}', {}), + '[``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#string_type) & [``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#boolean_type)' + ); + }); + + it('should handle an intersection with generics like {Map&Array}', () => { + strictEqual( + transformTypeToReferenceLink('{Map&Array}', {}), + '[``](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)<[``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#string_type), [``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#number_type)> & [``](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[``](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures#string_type)>' + ); + }); }); diff --git a/src/generators/metadata/utils/transformers.mjs b/src/generators/metadata/utils/transformers.mjs index 8b8e51a3..7fac4e85 100644 --- a/src/generators/metadata/utils/transformers.mjs +++ b/src/generators/metadata/utils/transformers.mjs @@ -23,31 +23,34 @@ export const transformUnixManualToLink = ( return `[\`${text}\`](${DOC_MAN_BASE_URL}${sectionNumber}/${command}.${sectionNumber}${sectionLetter}.html)`; }; /** - * Safely splits the string by `|`, ignoring pipes that are inside `< >` + * Safely splits the string by `|` or `&` at the top level (ignoring those + * inside `< >`), and returns both the pieces and the separator used. * * @param {string} str The type string to split - * @returns {string[]} An array of type pieces + * @returns {{ pieces: string[], separator: string }} The split pieces and the separator string used to join them (` | ` or ` & `) */ -const splitByOuterUnion = str => { - const result = []; +const splitByOuterSeparator = str => { + const pieces = []; let current = ''; let depth = 0; + let separator; for (const char of str) { if (char === '<') { depth++; } else if (char === '>') { depth--; - } else if (char === '|' && depth === 0) { - result.push(current); + } else if ((char === '|' || char === '&') && depth === 0) { + pieces.push(current); current = ''; + separator ??= ` ${char} `; continue; } current += char; } - result.push(current); - return result; + pieces.push(current); + return { pieces, separator }; }; /** @@ -147,7 +150,9 @@ export const transformTypeToReferenceLink = (type, record) => { return ''; }; - const typePieces = splitByOuterUnion(typeInput).map(piece => { + const { pieces: outerPieces, separator } = splitByOuterSeparator(typeInput); + + const typePieces = outerPieces.map(piece => { // This is the content to render as the text of the Markdown link const trimmedPiece = piece.trim(); @@ -169,8 +174,8 @@ export const transformTypeToReferenceLink = (type, record) => { }); // Filter out pieces that we failed to map and then join the valid ones - // into different links separated by a ` | ` - const markdownLinks = typePieces.filter(Boolean).join(' | '); + // using the same separator that appeared in the original type string + const markdownLinks = typePieces.filter(Boolean).join(separator); // Return the replaced links or the original content if they all failed to be replaced // Note that if some failed to get replaced, only the valid ones will be returned