11import { DOC_MAN_BASE_URL , DOC_API_HEADING_TYPES } from '../constants.mjs' ;
22import { slug } from './slugger.mjs' ;
3+ import { parseType } from './typeParser.mjs' ;
34import { transformNodesToString } from '../../../utils/unist.mjs' ;
45import BUILTIN_TYPE_MAP from '../maps/builtin.json' with { type : 'json' } ;
56import MDN_TYPE_MAP from '../maps/mdn.json' with { type : 'json' } ;
@@ -19,129 +20,6 @@ export const transformUnixManualToLink = (
1920 return `[\`${ text } \`](${ DOC_MAN_BASE_URL } ${ sectionNumber } /${ command } .${ sectionNumber } ${ sectionLetter } .html)` ;
2021} ;
2122
22- /**
23- * Safely splits a string by a given set of separators at depth 0 (ignoring those inside < > or ( )).
24- *
25- * @param {string } str The string to split
26- * @param {string } separator The separator to split by (e.g., '|', '&', ',', '=>')
27- * @returns {string[] } The split pieces
28- */
29- const splitByOuterSeparator = ( str , separator ) => {
30- const pieces = [ ] ;
31- let current = '' ;
32- let depth = 0 ;
33-
34- for ( let i = 0 ; i < str . length ; i ++ ) {
35- const char = str [ i ] ;
36-
37- // Track depth using brackets and parentheses
38- if ( char === '<' || char === '(' ) {
39- depth ++ ;
40- } else if ( ( char === '>' && str [ i - 1 ] !== '=' ) || char === ')' ) {
41- depth -- ;
42- }
43-
44- // Check for multi-character separators like '=>'
45- const isArrow = separator === '=>' && char === '=' && str [ i + 1 ] === '>' ;
46- // Check for single-character separators
47- const isCharSeparator = separator === char ;
48-
49- if ( depth === 0 && ( isCharSeparator || isArrow ) ) {
50- pieces . push ( current . trim ( ) ) ;
51- current = '' ;
52- if ( isArrow ) {
53- i ++ ;
54- } // skip the '>' part of '=>'
55- continue ;
56- }
57-
58- current += char ;
59- }
60-
61- pieces . push ( current . trim ( ) ) ;
62- return pieces ;
63- } ;
64-
65- /**
66- * Recursively parses advanced TypeScript types, including Unions, Intersections, Functions, and Nested Generics.
67- * * @param {string } typeString The plain type string to evaluate
68- * @param {Function } transformType The function used to resolve individual types into links
69- * @returns {string|null } The formatted Markdown link(s), or null if the base type doesn't map
70- */
71- const parseAdvancedType = ( typeString , transformType ) => {
72- const trimmed = typeString . trim ( ) ;
73- if ( ! trimmed ) {
74- return null ;
75- }
76-
77- // Handle Unions (|)
78- if ( trimmed . includes ( '|' ) ) {
79- const parts = splitByOuterSeparator ( trimmed , '|' ) ;
80- if ( parts . length > 1 ) {
81- // Re-evaluate each part recursively and join with ' | '
82- const resolvedParts = parts . map (
83- p => parseAdvancedType ( p , transformType ) || `\`<${ p } >\``
84- ) ;
85- return resolvedParts . join ( ' | ' ) ;
86- }
87- }
88-
89- // Handle Intersections (&)
90- if ( trimmed . includes ( '&' ) ) {
91- const parts = splitByOuterSeparator ( trimmed , '&' ) ;
92- if ( parts . length > 1 ) {
93- // Re-evaluate each part recursively and join with ' & '
94- const resolvedParts = parts . map (
95- p => parseAdvancedType ( p , transformType ) || `\`<${ p } >\``
96- ) ;
97- return resolvedParts . join ( ' & ' ) ;
98- }
99- }
100-
101- // Handle Functions (=>)
102- if ( trimmed . includes ( '=>' ) ) {
103- const parts = splitByOuterSeparator ( trimmed , '=>' ) ;
104- if ( parts . length === 2 ) {
105- const params = parts [ 0 ] ;
106- const returnType = parts [ 1 ] ;
107-
108- // Preserve the function signature, just link the return type for now
109- // (Mapping param types inside the signature string is complex and often unnecessary for simple docs)
110- const parsedReturn =
111- parseAdvancedType ( returnType , transformType ) || `\`<${ returnType } >\`` ;
112- return `${ params } => ${ parsedReturn } ` ;
113- }
114- }
115-
116- // 3. Handle Generics (Base<Inner, Inner>)
117- if ( trimmed . includes ( '<' ) && trimmed . endsWith ( '>' ) ) {
118- const firstBracketIndex = trimmed . indexOf ( '<' ) ;
119- const baseType = trimmed . slice ( 0 , firstBracketIndex ) . trim ( ) ;
120- const innerType = trimmed . slice ( firstBracketIndex + 1 , - 1 ) . trim ( ) ;
121-
122- const baseResult = transformType ( baseType . replace ( / \[ \] $ / , '' ) ) ;
123- const baseFormatted = baseResult
124- ? `[\`<${ baseType } >\`](${ baseResult } )`
125- : `\`<${ baseType } >\`` ;
126-
127- // Split arguments safely by comma
128- const innerArgs = splitByOuterSeparator ( innerType , ',' ) ;
129- const innerFormatted = innerArgs
130- . map ( arg => parseAdvancedType ( arg , transformType ) || `\`<${ arg } >\`` )
131- . join ( ', ' ) ;
132-
133- return `${ baseFormatted } <${ innerFormatted } >` ;
134- }
135-
136- // Base Case: Plain Type (e.g., string, Buffer, Function)
137- const result = transformType ( trimmed . replace ( / \[ \] $ / , '' ) ) ;
138- if ( trimmed . length && result ) {
139- return `[\`<${ trimmed } >\`](${ result } )` ;
140- }
141-
142- return null ;
143- } ;
144-
14523/**
14624 * This method replaces plain text Types within the Markdown content into Markdown links
14725 * that link to the actual relevant reference for such type (either internal or external link)
@@ -192,8 +70,7 @@ export const transformTypeToReferenceLink = (type, record) => {
19270 return '' ;
19371 } ;
19472
195- // Kick off the recursive parser on the cleaned input
196- const markdownLinks = parseAdvancedType ( typeInput , transformType ) ;
73+ const markdownLinks = parseType ( typeInput , transformType ) ;
19774
19875 // Return the replaced links or the original content if they all failed to be replaced
19976 // Note that if some failed to get replaced, only the valid ones will be returned
0 commit comments