1
1
import fs from "fs/promises" ;
2
-
3
2
const basePath = new URL (
4
3
"../../inputfiles/mdn/files/en-us/web/api/" ,
5
4
import . meta. url ,
@@ -52,33 +51,48 @@ function extractSummary(markdown: string): string {
52
51
53
52
async function walkDirectory ( dir : URL ) : Promise < URL [ ] > {
54
53
const entries = await fs . readdir ( dir , { withFileTypes : true } ) ;
54
+ const parentDirName = dir . pathname . split ( "/" ) . filter ( Boolean ) . slice ( - 1 ) [ 0 ] ;
55
55
let results : URL [ ] = [ ] ;
56
56
57
57
for ( const entry of entries ) {
58
- const fullPath = new URL ( `${ entry . name } /` , dir ) ;
59
- const fullFile = new URL ( entry . name , dir ) ;
60
-
61
58
if ( entry . isDirectory ( ) ) {
62
- results = results . concat ( await walkDirectory ( fullPath ) ) ;
59
+ if ( entry . name === parentDirName ) continue ;
60
+ const subDir = new URL ( `${ entry . name } /` , dir ) ;
61
+ results = results . concat ( await walkDirectory ( subDir ) ) ;
63
62
} else if ( entry . isFile ( ) && entry . name === "index.md" ) {
64
- results . push ( fullFile ) ;
63
+ results . push ( new URL ( entry . name , dir ) ) ;
65
64
}
66
65
}
67
66
68
67
return results ;
69
68
}
70
69
70
+ const types : Record < string , string > = {
71
+ property : "properties" ,
72
+ method : "methods" ,
73
+ } ;
74
+
75
+ function generateTypes ( content : string ) : string [ ] | undefined {
76
+ const pageType = content . match ( / p a g e - t y p e : \s * [ " ' ] ? ( [ ^ " ' \n ] + ) [ " ' ] ? / ) ;
77
+ if ( ! pageType ) throw new Error ( "pageType not found" ) ;
78
+
79
+ const type = pageType [ 1 ] . split ( "-" ) . pop ( ) ! ;
80
+ const plural = types [ type ] ;
81
+ if ( ! plural ) return ;
82
+
83
+ return [ plural , type ] ;
84
+ }
85
+
71
86
function generateSlug ( content : string ) : string [ ] {
72
- const match = content . match ( / s l u g : \s * [ " ' ] ? ( [ ^ " ' \n ] + ) [ " ' ] ? / ) ! ;
87
+ const match = content . match ( / s l u g : \s * [ " ' ] ? ( [ ^ " ' \n ] + ) [ " ' ] ? / ) ;
88
+ if ( ! match ) throw new Error ( "Slug not found" ) ;
89
+
73
90
const url = match [ 1 ] . split ( ":" ) . pop ( ) ! ;
74
- const parts = url . split ( "/" ) . slice ( 2 ) ; // remove first 2 segments
75
- return parts ;
91
+ const parts = url . split ( "/" ) . slice ( 2 ) ; // skip `/en-US/web/api/...`
92
+ return parts ; // Keep only top-level and method
76
93
}
77
94
78
- function ensureLeaf (
79
- obj : Record < string , any > ,
80
- keys : string [ ] ,
81
- ) : Record < string , any > {
95
+ function ensureLeaf ( obj : Record < string , any > , keys : string [ ] ) {
82
96
let leaf = obj ;
83
97
for ( const key of keys ) {
84
98
leaf [ key ] ??= { } ;
@@ -87,7 +101,29 @@ function ensureLeaf(
87
101
return leaf ;
88
102
}
89
103
90
- export async function generateDescriptions ( ) : Promise < Record < string , any > > {
104
+ function insertComment (
105
+ root : Record < string , any > ,
106
+ slug : string [ ] ,
107
+ summary : string ,
108
+ types ?: string [ ] ,
109
+ ) {
110
+ if ( slug . length === 1 || ! types ) {
111
+ const iface = ensureLeaf ( root , slug ) ;
112
+ iface . __comment = summary ;
113
+ } else {
114
+ const [ ifaceName , memberName ] = slug ;
115
+ const iface = ensureLeaf ( root , [ ifaceName , ...types ] ) ;
116
+
117
+ const mainComment = root [ ifaceName ] ?. __comment ;
118
+ if ( mainComment !== summary ) {
119
+ iface [ memberName ] = { comment : summary } ;
120
+ }
121
+ }
122
+ }
123
+
124
+ export async function generateDescriptions ( removedComments : string [ ] ) : Promise < {
125
+ interfaces : { interface : Record < string , any > } ;
126
+ } > {
91
127
const stats = await fs . stat ( basePath ) ;
92
128
if ( ! stats . isDirectory ( ) ) {
93
129
throw new Error (
@@ -99,23 +135,24 @@ export async function generateDescriptions(): Promise<Record<string, any>> {
99
135
try {
100
136
const indexPaths = await walkDirectory ( basePath ) ;
101
137
102
- const promises = indexPaths . map ( async ( fileURL ) => {
103
- try {
104
- const content = await fs . readFile ( fileURL , "utf-8" ) ;
105
- const slug = generateSlug ( content ) ;
106
- const summary = extractSummary ( content ) ;
107
- const leaf = ensureLeaf ( results , slug ) ;
108
- leaf . __comment = summary ;
109
- } catch ( error ) {
110
- console . warn ( `Skipping ${ fileURL . href } : ${ error } ` ) ;
111
- }
112
- } ) ;
113
-
114
- // Wait for all file processing to finish
115
- await Promise . all ( promises ) ;
116
- } catch ( error ) {
117
- console . error ( "Error generating API descriptions:" , error ) ;
138
+ await Promise . all (
139
+ indexPaths . map ( async ( fileURL ) => {
140
+ try {
141
+ const content = await fs . readFile ( fileURL , "utf-8" ) ;
142
+ const slug = generateSlug ( content ) ;
143
+ const types = generateTypes ( content ) ;
144
+
145
+ if ( removedComments . includes ( slug [ 0 ] ) ) return ;
146
+
147
+ const summary = extractSummary ( content ) ;
148
+ insertComment ( results , slug , summary , types ) ;
149
+ } catch ( error ) {
150
+ console . error ( "Error generating API descriptions:" , error ) ;
151
+ }
152
+ } ) ,
153
+ ) ;
154
+ } catch ( err ) {
155
+ console . error ( "Error generating API descriptions:" , err ) ;
118
156
}
119
-
120
- return results ;
157
+ return { interfaces : { interface : results } } ;
121
158
}
0 commit comments