diff --git a/.changeset/spaced-union-types.md b/.changeset/spaced-union-types.md new file mode 100644 index 00000000..6c831a97 --- /dev/null +++ b/.changeset/spaced-union-types.md @@ -0,0 +1,5 @@ +--- +'@node-core/doc-kit': patch +--- + +Space union separators in type annotation values (`{string|URL}` is now rendered as `string | URL`). diff --git a/src/utils/type-annotations/__tests__/remark.test.mjs b/src/utils/type-annotations/__tests__/remark.test.mjs index 60070c84..3197166f 100644 --- a/src/utils/type-annotations/__tests__/remark.test.mjs +++ b/src/utils/type-annotations/__tests__/remark.test.mjs @@ -28,11 +28,21 @@ describe('remarkTypeAnnotations', () => { it('parses multiple annotations in one paragraph', () => { assert.deepEqual(valuesIn('{string} and {Buffer|Blob} and {integer}'), [ 'string', - 'Buffer|Blob', + 'Buffer | Blob', 'integer', ]); }); + it('spaces union separators, without touching `||`', () => { + assert.deepEqual(valuesIn('Takes {string|URL} or {string | URL}.'), [ + 'string | URL', + 'string | URL', + ]); + assert.deepEqual(valuesIn("Defaults to {req.url || '/'}."), [ + "req.url || '/'", + ]); + }); + it('supports nested braces (object literal types)', () => { assert.deepEqual(valuesIn('Takes {Record} maps.'), [ 'Record', @@ -62,7 +72,7 @@ describe('remarkTypeAnnotations', () => { '| `flag` | {string\\|number} |', ].join('\n'); - assert.deepEqual(valuesIn(markdown), ['string|number']); + assert.deepEqual(valuesIn(markdown), ['string | number']); }); it('normalizes interior line breaks to spaces', () => { @@ -122,6 +132,6 @@ describe('remarkTypeAnnotations', () => { processor.parse('Returns: {Promise} on success.') ); - assert.match(output, /\{Promise\}/); + assert.match(output, /\{Promise\}/); }); }); diff --git a/src/utils/type-annotations/mdast.mjs b/src/utils/type-annotations/mdast.mjs index 203a6b21..eed7a8ae 100644 --- a/src/utils/type-annotations/mdast.mjs +++ b/src/utils/type-annotations/mdast.mjs @@ -5,12 +5,17 @@ // and the mandatory `\|` inside GFM table cells must be decoded here. const CHARACTER_ESCAPE = /\\([!-/:-@[-`{-~])/g; +// A single union separator, with any surrounding whitespace. Lookarounds +// exclude `||` (logical OR in default-value prose). +const UNION_SEPARATOR = /(? ({ node.value = node.value .replace(/\s+/g, ' ') .trim() - .replace(CHARACTER_ESCAPE, '$1'); + .replace(CHARACTER_ESCAPE, '$1') + .replace(UNION_SEPARATOR, ' | '); this.exit(token); },