@@ -13,6 +13,7 @@ var currentModulePaths = require('current-module-paths');
1313var toSpawnArgs = require ( 'object-to-spawn-args' ) ;
1414var cp = require ( 'child_process' ) ;
1515var util = require ( 'node:util' ) ;
16+ var streamReadAll = require ( 'stream-read-all' ) ;
1617
1718var _documentCurrentScript = typeof document !== 'undefined' ? document . currentScript : null ;
1819class TempFile {
@@ -100,7 +101,7 @@ class JsdocCommand {
100101 }
101102}
102103
103- const exec = util . promisify ( cp . exec ) ;
104+ util . promisify ( cp . exec ) ;
104105
105106class Explain extends JsdocCommand {
106107 async getOutput ( ) {
@@ -120,25 +121,38 @@ class Explain extends JsdocCommand {
120121 }
121122
122123 async _runJsdoc ( ) {
123- const cmd = this . options . source . length
124- ? `node "${ this . jsdocPath } " ${ toSpawnArgs ( this . jsdocOptions ) . join ( ' ' ) } -X ${ this . tempFileSet . files . join ( ' ' ) } `
125- : `node "${ this . jsdocPath } " ${ toSpawnArgs ( this . jsdocOptions ) . join ( ' ' ) } -X ${ this . inputFileSet . files . join ( ' ' ) } ` ;
126-
127- let jsdocOutput = { stdout : '' , stderr : '' } ;
128- try {
129- jsdocOutput = await exec ( cmd , { maxBuffer : 1024 * 1024 * 100 } ) ; /* 100MB */
130- const explainOutput = JSON . parse ( jsdocOutput . stdout ) ;
131- if ( this . options . cache ) {
132- await this . cache . write ( this . cacheKey , explainOutput ) ;
133- }
134- return explainOutput
135- } catch ( err ) {
136- const firstLineOfStdout = jsdocOutput . stdout . split ( / \r ? \n / ) [ 0 ] ;
137- const jsdocErr = new Error ( jsdocOutput . stderr . trim ( ) || firstLineOfStdout || 'Jsdoc failed.' ) ;
138- jsdocErr . name = 'JSDOC_ERROR' ;
139- jsdocErr . cause = err ;
140- throw jsdocErr
141- }
124+ return new Promise ( ( resolve , reject ) => {
125+ const jsdocArgs = [
126+ this . jsdocPath ,
127+ ...toSpawnArgs ( this . jsdocOptions ) ,
128+ '-X' ,
129+ ...( this . options . source . length ? this . tempFileSet . files : this . inputFileSet . files )
130+ ] ;
131+ let jsdocOutput = { stdout : '' , stderr : '' } ;
132+ const handle = cp . spawn ( 'node' , jsdocArgs ) ;
133+ streamReadAll . streamReadText ( handle . stdout ) . then ( stdout => jsdocOutput . stdout = stdout ) ;
134+ streamReadAll . streamReadText ( handle . stderr ) . then ( stderr => jsdocOutput . stderr = stderr ) ;
135+ handle . on ( 'close' , ( code ) => {
136+ try {
137+ if ( code > 0 ) {
138+ throw new Error ( 'jsdoc exited with non-zero code: ' + code )
139+ } else {
140+ const explainOutput = JSON . parse ( jsdocOutput . stdout ) ;
141+ if ( this . options . cache ) {
142+ this . cache . write ( this . cacheKey , explainOutput ) . then ( ( ) => resolve ( explainOutput ) ) ;
143+ } else {
144+ resolve ( explainOutput ) ;
145+ }
146+ }
147+ } catch ( err ) {
148+ const firstLineOfStdout = jsdocOutput . stdout . split ( / \r ? \n / ) [ 0 ] ;
149+ const jsdocErr = new Error ( jsdocOutput . stderr . trim ( ) || firstLineOfStdout || 'Jsdoc failed.' ) ;
150+ jsdocErr . name = 'JSDOC_ERROR' ;
151+ jsdocErr . cause = err ;
152+ reject ( jsdocErr ) ;
153+ }
154+ } ) ;
155+ } )
142156 }
143157
144158 async readCache ( ) {
0 commit comments