@@ -25,7 +25,7 @@ export class TypeDocReader implements OptionsReader {
2525 */
2626 read ( container : Options , logger : Logger ) : void {
2727 const path = container . getValue ( 'options' ) ;
28- const file = this . findTypedocFile ( path , logger ) ;
28+ const file = this . findTypedocFile ( path ) ;
2929
3030 if ( ! file ) {
3131 if ( ! container . isDefault ( 'options' ) ) {
@@ -34,15 +34,43 @@ export class TypeDocReader implements OptionsReader {
3434 return ;
3535 }
3636
37- let data : any = require ( file ) ;
38- if ( typeof data !== 'object' ) {
37+ const seen = new Set < string > ( ) ;
38+ this . readFile ( file , container , logger , seen ) ;
39+ }
40+
41+ /**
42+ * Read the given options file + any extended files.
43+ * @param file
44+ * @param container
45+ * @param logger
46+ */
47+ private readFile ( file : string , container : Options , logger : Logger , seen : Set < string > ) {
48+ if ( seen . has ( file ) ) {
49+ logger . error ( `Tried to load the options file ${ file } multiple times.` ) ;
50+ return ;
51+ }
52+ seen . add ( file ) ;
53+
54+ const data : unknown = require ( file ) ;
55+
56+ if ( typeof data !== 'object' || ! data ) {
3957 logger . error ( `The file ${ file } is not an object.` ) ;
4058 return ;
4159 }
60+
61+ if ( 'extends' in data ) {
62+ const extended : string [ ] = getStringArray ( data [ 'extends' ] ) ;
63+ for ( const extendedFile of extended ) {
64+ // Extends is relative to the file it appears in.
65+ this . readFile ( Path . resolve ( Path . dirname ( file ) , extendedFile ) , container , logger , seen ) ;
66+ }
67+ delete data [ 'extends' ] ;
68+ }
69+
4270 // deprecate: data.src is alias to inputFiles as of 0.16, warn in 0.17, remove in 0.19
4371 if ( 'src' in data && ! ( 'inputFiles' in data ) ) {
44- data . inputFiles = Array . isArray ( data . src ) ? data . src : [ data . src ] ;
45- delete data . src ;
72+ data [ ' inputFiles' ] = getStringArray ( data [ ' src' ] ) ;
73+ delete data [ ' src' ] ;
4674 }
4775
4876 container . setValues ( data ) . match ( {
@@ -63,7 +91,7 @@ export class TypeDocReader implements OptionsReader {
6391 * @param logger
6492 * @return the typedoc.(js|json) file path or undefined
6593 */
66- private findTypedocFile ( path : string , logger : Logger ) : string | undefined {
94+ private findTypedocFile ( path : string ) : string | undefined {
6795 path = Path . resolve ( path ) ;
6896
6997 return [
@@ -73,3 +101,7 @@ export class TypeDocReader implements OptionsReader {
73101 ] . find ( path => FS . existsSync ( path ) && FS . statSync ( path ) . isFile ( ) ) ;
74102 }
75103}
104+
105+ function getStringArray ( arg : unknown ) : string [ ] {
106+ return Array . isArray ( arg ) ? arg . map ( String ) : [ String ( arg ) ] ;
107+ }
0 commit comments