1+ import * as fs from 'node:fs' ;
12import yargs from 'yargs' ;
23import { hideBin } from 'yargs/helpers' ;
34import * as rae from '../src' ;
45
5- const INCLUDE_EXTERNAL = false ;
6-
76interface RunOptions {
8- files : string [ ] ;
7+ files ? : string [ ] ;
98 configPath : string ;
109 includeExternal : boolean ;
10+ out ?: string ;
1111}
1212
1313function run ( options : RunOptions ) {
14- const program = rae . createProgram ( options . files , rae . loadConfig ( options . configPath ) ) ;
14+ const config = rae . loadConfig ( options . configPath ) ;
15+ const files = options . files ?? config . fileNames ;
16+
17+ const program = rae . createProgram ( files , config . options ) ;
18+
19+ const components : any [ ] = [ ] ;
20+ const hooks : any [ ] = [ ] ;
1521
16- for ( const file of options . files ) {
17- const ast = rae . parseFromProgram ( file , program ) ;
22+ let errorCounter = 0 ;
1823
19- const translated = ast . body . map ( ( component ) => {
20- return {
21- name : component . name ,
22- props : component . types
23- . map ( ( prop ) => {
24+ for ( const file of files ) {
25+ console . log ( `Processing ${ file } ` ) ;
26+ console . group ( ) ;
27+ try {
28+ const ast = rae . parseFromProgram ( file , program ) ;
29+
30+ const componentsApi = ast . body . filter ( rae . isComponentNode ) . map ( ( component ) => {
31+ return {
32+ name : component . name ,
33+ props : component . props
34+ . map ( ( prop ) => {
35+ return {
36+ ...prop ,
37+ filenames : Array . from ( prop . filenames ) ,
38+ } ;
39+ } )
40+ . filter (
41+ ( prop ) =>
42+ options . includeExternal ||
43+ ! Array . from ( prop . filenames ) . some ( ( filename ) => filename . includes ( '/node_modules/' ) ) ,
44+ ) ,
45+ } ;
46+ } ) ;
47+
48+ const hooksApi = ast . body . filter ( rae . isHookNode ) . map ( ( hook ) => {
49+ return {
50+ name : hook . name ,
51+ parameters : hook . callSignatures [ 0 ] . parameters . map ( ( parameter ) => {
2452 return {
25- ...prop ,
26- filenames : Array . from ( prop . filenames ) ,
53+ ...parameter ,
2754 } ;
28- } )
29- . filter (
55+ } ) ,
56+ /* .filter(
3057 (prop) =>
3158 options.includeExternal ||
3259 !Array.from(prop.filenames).some((filename) => filename.includes('/node_modules/')),
33- ) ,
34- } ;
35- } ) ;
60+ ),*/
61+ } ;
62+ } ) ;
63+
64+ components . push ( ...componentsApi ) ;
65+ hooks . push ( ...hooksApi ) ;
66+ } catch ( e ) {
67+ console . error ( `⛔ Error processing ${ file } : ${ e . message } ` ) ;
68+ ++ errorCounter ;
69+ } finally {
70+ console . groupEnd ( ) ;
71+ }
72+ }
73+
74+ const outputJSON = JSON . stringify ( { components, hooks } , null , 2 ) ;
75+ if ( options . out ) {
76+ fs . writeFileSync ( options . out , outputJSON ) ;
77+ console . log ( `Output written to ${ options . out } ` ) ;
78+ } else {
79+ console . log ( outputJSON ) ;
80+ }
3681
37- console . log ( JSON . stringify ( translated , null , 2 ) ) ;
82+ console . log ( `\nProcessed ${ files . length } files.` ) ;
83+ if ( errorCounter > 0 ) {
84+ console . log ( `❌ Found ${ errorCounter } errors.` ) ;
85+ process . exit ( 1 ) ;
3886 }
3987}
4088
@@ -47,8 +95,9 @@ yargs(hideBin(process.argv))
4795 . option ( 'files' , {
4896 alias : 'f' ,
4997 type : 'array' ,
50- demandOption : true ,
51- description : 'The files to extract the API descriptions from' ,
98+ demandOption : false ,
99+ description :
100+ 'The files to extract the API descriptions from. If not provided, all files in the tsconfig.json are used' ,
52101 } )
53102 . option ( 'configPath' , {
54103 alias : 'c' ,
@@ -61,6 +110,11 @@ yargs(hideBin(process.argv))
61110 type : 'boolean' ,
62111 default : false ,
63112 description : 'Include props defined outside of the project' ,
113+ } )
114+ . option ( 'out' , {
115+ alias : 'o' ,
116+ type : 'string' ,
117+ description : 'The output file. If not provided, the output is printed to the console' ,
64118 } ) ;
65119 } ,
66120 run ,
0 commit comments