11'use strict' ;
22
3- import { u as createTree } from 'unist-builder' ;
4- import { findAfter } from 'unist-util-find-after' ;
5- import { remove } from 'unist-util-remove' ;
6- import { selectAll } from 'unist-util-select' ;
7- import { SKIP , visit } from 'unist-util-visit' ;
8-
9- import { createNodeSlugger } from '../../utils/slugger/index.mjs' ;
10- import { getRemark } from '../../utils/remark.mjs' ;
11- import createQueries from '../../utils/queries/index.mjs' ;
12- import createMetadata from '../../metadata.mjs' ;
3+ import { parseApiDoc } from './utils/parse.mjs' ;
134
145/**
156 * This generator generates a flattened list of metadata entries from a API doc
167 *
17- * @typedef {ParserOutput<import('mdast').Root> } Input
8+ * @typedef {ParserOutput<import('mdast').Root>[] } Input
189 *
1910 * @type {GeneratorMetadata<Input, ApiDocMetadataEntry[]> }
2011 */
@@ -28,140 +19,10 @@ export default {
2819 dependsOn : 'ast' ,
2920
3021 /**
31- * @param {Input } input
22+ * @param {Input } inputs
3223 * @returns {Promise<ApiDocMetadataEntry[]> }
3324 */
34- async generate ( { file, tree } ) {
35- const {
36- setHeadingMetadata,
37- addYAMLMetadata,
38- updateMarkdownLink,
39- updateTypeReference,
40- updateLinkReference,
41- addStabilityMetadata,
42- } = createQueries ( ) ;
43-
44- // Creates an instance of the Remark processor with GFM support
45- // which is used for stringifying the AST tree back to Markdown
46- const remarkProcessor = getRemark ( ) ;
47-
48- /**
49- * This holds references to all the Metadata entries for a given file
50- * this is used so we can traverse the AST tree and keep mutating things
51- * and then stringify the whole api doc file at once without creating sub traversals
52- *
53- * Then once we have the whole file parsed, we can split the resulting string into sections
54- * and seal the Metadata Entries (`.create()`) and return the result to the caller of parae.
55- *
56- * @type {Array<ApiDocMetadataEntry> }
57- */
58- const metadataCollection = [ ] ;
59-
60- // Creates a new Slugger instance for the current API doc file
61- const nodeSlugger = createNodeSlugger ( ) ;
62-
63- // Get all Markdown Footnote definitions from the tree
64- const markdownDefinitions = selectAll ( 'definition' , tree ) ;
65-
66- // Get all Markdown Heading entries from the tree
67- const headingNodes = selectAll ( 'heading' , tree ) ;
68-
69- // Handles Markdown link references and updates them to be plain links
70- visit ( tree , createQueries . UNIST . isLinkReference , node =>
71- updateLinkReference ( node , markdownDefinitions )
72- ) ;
73-
74- // Removes all the original definitions from the tree as they are not needed
75- // anymore, since all link references got updated to be plain links
76- remove ( tree , markdownDefinitions ) ;
77-
78- // Handles the normalisation URLs that reference to API doc files with .md extension
79- // to replace the .md into .html, since the API doc files get eventually compiled as HTML
80- visit ( tree , createQueries . UNIST . isMarkdownUrl , node =>
81- updateMarkdownLink ( node )
82- ) ;
83-
84- // If the document has no headings but it has content, we add a fake heading to the top
85- // so that our parsing logic can work correctly, and generate content for the whole file
86- if ( headingNodes . length === 0 && tree . children . length > 0 ) {
87- tree . children . unshift ( createTree ( 'heading' , { depth : 1 } , [ ] ) ) ;
88- }
89-
90- // Handles iterating the tree and creating subtrees for each API doc entry
91- // where an API doc entry is defined by a Heading Node
92- // (so all elements after a Heading until the next Heading)
93- // and then it creates and updates a Metadata entry for each API doc entry
94- // and then generates the final content for each API doc entry and pushes it to the collection
95- visit ( tree , createQueries . UNIST . isHeading , ( headingNode , index ) => {
96- // Creates a new Metadata entry for the current API doc file
97- const apiEntryMetadata = createMetadata ( nodeSlugger ) ;
98-
99- // Adds the Metadata of the current Heading Node to the Metadata entry
100- setHeadingMetadata ( headingNode , apiEntryMetadata ) ;
101-
102- // We retrieve the immediate next Heading if it exists
103- // This is used for ensuring that we don't include items that would
104- // belong only to the next heading to the current Heading metadata
105- // Note that if there is no next heading, we use the current node as the next one
106- const nextHeadingNode =
107- findAfter ( tree , index , createQueries . UNIST . isHeading ) ?? headingNode ;
108-
109- // This is the cutover index of the subtree that we should get
110- // of all the Nodes within the AST tree that belong to this section
111- // If `next` is equals the current heading, it means there's no next heading
112- // and we are reaching the end of the document, hence the cutover should be the end of
113- // the document itself.
114- const stop =
115- headingNode === nextHeadingNode
116- ? tree . children . length
117- : tree . children . indexOf ( nextHeadingNode ) ;
118-
119- // Retrieves all the nodes that should belong to the current API docs section
120- // `index + 1` is used to skip the current Heading Node
121- const subTree = createTree ( 'root' , tree . children . slice ( index , stop ) ) ;
122-
123- // Visits all Stability Index nodes from the current subtree if there's any
124- // and then apply the Stability Index metadata to the current metadata entry
125- visit ( subTree , createQueries . UNIST . isStabilityNode , node =>
126- addStabilityMetadata ( node , apiEntryMetadata )
127- ) ;
128-
129- // Visits all HTML nodes from the current subtree and if there's any that matches
130- // our YAML metadata structure, it transforms into YAML metadata
131- // and then apply the YAML Metadata to the current Metadata entry
132- visit ( subTree , createQueries . UNIST . isYamlNode , node => {
133- // TODO: Is there always only one YAML node?
134- apiEntryMetadata . setYamlPosition ( node . position ) ;
135- addYAMLMetadata ( node , apiEntryMetadata ) ;
136- } ) ;
137-
138- // Visits all Text nodes from the current subtree and if there's any that matches
139- // any API doc type reference and then updates the type reference to be a Markdown link
140- visit ( subTree , createQueries . UNIST . isTextWithType , ( node , _ , parent ) =>
141- updateTypeReference ( node , parent )
142- ) ;
143-
144- // Removes already parsed items from the subtree so that they aren't included in the final content
145- remove ( subTree , [ createQueries . UNIST . isYamlNode ] ) ;
146-
147- // Applies the AST transformations to the subtree based on the API doc entry Metadata
148- // Note that running the transformation on the subtree isn't costly as it is a reduced tree
149- // and the GFM transformations aren't that heavy
150- const parsedSubTree = remarkProcessor . runSync ( subTree ) ;
151-
152- // We seal and create the API doc entry Metadata and push them to the collection
153- const parsedApiEntryMetadata = apiEntryMetadata . create (
154- file ,
155- parsedSubTree
156- ) ;
157-
158- // We push the parsed API doc entry Metadata to the collection
159- metadataCollection . push ( parsedApiEntryMetadata ) ;
160-
161- return SKIP ;
162- } ) ;
163-
164- // Returns the Metadata entries for the given API doc file
165- return metadataCollection ;
25+ async generate ( inputs ) {
26+ return inputs . flatMap ( input => parseApiDoc ( input ) ) ;
16627 } ,
16728} ;
0 commit comments