1
1
'use strict' ;
2
2
3
- // External dependencies
4
3
import { h as createElement } from 'hastscript' ;
5
4
import { u as createTree } from 'unist-builder' ;
6
5
import { SKIP , visit } from 'unist-util-visit' ;
6
+ import { rcompare } from 'semver' ;
7
7
8
- // Internal dependencies
9
- import createQueries from '../../../utils/queries/index.mjs' ;
8
+ import { UNIST } from '../../../utils/queries/index.mjs' ;
10
9
import { createJSXElement } from './ast.mjs' ;
11
10
import { ICON_SYMBOL_MAP , STABILITY_LEVELS } from '../constants.mjs' ;
12
11
import { DOC_NODE_BLOB_BASE_URL } from '../../../constants.mjs' ;
12
+ import { enforceArray } from '../../../utils/generators.mjs' ;
13
13
14
14
/**
15
15
* Transforms a stability node into an AlertBox JSX element
@@ -28,28 +28,75 @@ function visitStabilityNode(node, index, parent) {
28
28
}
29
29
30
30
/**
31
- * Adds the metadata around the header node
31
+ * Builds a history of changes for an API element
32
32
*
33
- * @param {ApiDocMetadataEntry } entry - The content object to process
34
- * @param {import('mdast').Heading } node - The stability node to transform
33
+ * @param {ApiDocMetadataEntry } entry - The metadata entry containing change information
34
+ */
35
+ function buildChangeElement ( entry ) {
36
+ // Create change entries from version fields (added, deprecated, etc.)
37
+ const changeTypes = {
38
+ added_in : 'Added in' ,
39
+ deprecated_in : 'Deprecated in' ,
40
+ removed_in : 'Removed in' ,
41
+ introduced_in : 'Introduced in' ,
42
+ } ;
43
+
44
+ const history = Object . entries ( changeTypes )
45
+ . filter ( ( [ field ] ) => entry [ field ] )
46
+ . map ( ( [ field , label ] ) => {
47
+ const versions = enforceArray ( entry [ field ] ) ;
48
+ return {
49
+ versions,
50
+ label : `${ label } : ${ versions . join ( ', ' ) } ` ,
51
+ } ;
52
+ } ) ;
53
+
54
+ // Add explicit changes
55
+ if ( entry . changes ) {
56
+ const changesHistory = entry . changes . map ( change => ( {
57
+ versions : enforceArray ( change . version ) ,
58
+ label : change . description ,
59
+ url : change [ 'pr-url' ] ,
60
+ } ) ) ;
61
+ history . push ( ...changesHistory ) ;
62
+ }
63
+
64
+ // Sort by version, newest first
65
+ return createJSXElement ( 'ChangeHistory' , {
66
+ changes : history . sort ( ( a , b ) => rcompare ( a . versions [ 0 ] , b . versions [ 0 ] ) ) ,
67
+ } ) ;
68
+ }
69
+
70
+ /**
71
+ * Enhances a heading node with metadata, source links, and styling
72
+ *
73
+ * @param {ApiDocMetadataEntry } entry - The API metadata entry
74
+ * @param {import('mdast').Heading } node - The heading node to transform
35
75
* @param {number } index - The index of the node in its parent's children array
36
- * @param {import('unist').Node } parent - The parent node containing the stability node
76
+ * @param {import('unist').Node } parent - The parent node containing the heading
37
77
*/
38
- function visitHeadingNode ( entry , { data, children } , index , parent ) {
39
- console . error ( data ) ;
78
+ function visitHeadingNode ( entry , node , index , parent ) {
79
+ const { data, children } = node ;
80
+ const headerChildren = [
81
+ createElement ( `h${ data . depth + 1 } ` , [
82
+ createElement ( `a.mark#${ data . slug } ` , { href : `#${ data . slug } ` } , children ) ,
83
+ ] ) ,
84
+ ] ;
85
+
40
86
// Add type icon if available
41
87
if ( ICON_SYMBOL_MAP [ data . type ] ) {
42
- // TODO: This hasn't been implemented yet. This is an assumption of what a
43
- // potential implementation could look like
44
- children . unshift (
88
+ headerChildren . unshift (
45
89
createJSXElement ( 'CircularIcon' , ICON_SYMBOL_MAP [ data . type ] )
46
90
) ;
47
91
}
48
92
49
- // Replace node with proper heading and anchor
50
- parent . children [ index ] = createElement ( `h${ data . depth + 1 } ` , [
51
- createElement ( `a.mark#${ data . slug } ` , { href : `#${ data . slug } ` } , children ) ,
52
- ] ) ;
93
+ const changeElement = buildChangeElement ( entry ) ;
94
+ if ( changeElement ) {
95
+ headerChildren . push ( changeElement ) ;
96
+ }
97
+
98
+ // Replace node with new heading and anchor
99
+ parent . children [ index ] = createElement ( 'div' , headerChildren ) ;
53
100
54
101
// Add source link if available
55
102
if ( entry . source_link ) {
@@ -71,14 +118,13 @@ function visitHeadingNode(entry, { data, children }, index, parent) {
71
118
}
72
119
73
120
/**
74
- * Processes content by transforming stability nodes
121
+ * Processes an API documentation entry by applying transformations to its content
75
122
*
76
- * @param {ApiDocMetadataEntry } entry - The entry
123
+ * @param {ApiDocMetadataEntry } entry - The API metadata entry to process
77
124
*/
78
125
function process ( entry ) {
79
- // Create a shallow copy to avoid modifying the original
126
+ // Create a deep copy to avoid modifying the original
80
127
const content = structuredClone ( entry . content ) ;
81
- const { UNIST } = createQueries ;
82
128
83
129
// Apply all transformations to the content
84
130
visit ( content , UNIST . isStabilityNode , visitStabilityNode ) ;
@@ -92,10 +138,23 @@ function process(entry) {
92
138
/**
93
139
* Transforms API metadata entries into processed MDX content
94
140
*
95
- * @param {Array< ApiDocMetadataEntry> } metadataEntries - API documentation metadata entries
141
+ * @param {ApiDocMetadataEntry[] } metadataEntries - API documentation metadata entries
96
142
* @param {import('unified').Processor } remark - Remark processor instance for markdown processing
97
143
*/
98
144
export default function buildContent ( metadataEntries , remark ) {
99
- const rootNode = createTree ( 'root' , metadataEntries . map ( process ) ) ;
100
- return remark . stringify ( remark . runSync ( rootNode ) ) ;
145
+ const root = createTree ( 'root' , [
146
+ createJSXElement ( 'NavBar' ) ,
147
+ createJSXElement ( 'MainLayout' , {
148
+ children : [
149
+ createJSXElement ( 'SideBar' ) ,
150
+ createElement ( 'div' , [
151
+ createElement ( 'main' , metadataEntries . map ( process ) ) ,
152
+ createElement ( 'MetaBar' ) ,
153
+ ] ) ,
154
+ createJSXElement ( 'Footer' ) ,
155
+ ] ,
156
+ } ) ,
157
+ ] ) ;
158
+
159
+ return remark . stringify ( remark . runSync ( root ) ) ;
101
160
}
0 commit comments