1- import { spawn } from 'child_process' ;
2- import { join } from 'path' ;
1+ import { spawn } from '@sourcemeta/jsonschema' ;
32import { CommandResult } from '../../../protocol/types' ;
43
54/**
65 * Execute a CLI command and return the result
76 */
87export class CommandExecutor {
9- private readonly extensionPath : string ;
10- private readonly cliPath : string ;
11-
12- constructor ( extensionPath : string ) {
13- this . extensionPath = extensionPath ;
14- this . cliPath = join ( extensionPath , 'node_modules' , '@sourcemeta' , 'jsonschema' , 'npm' , 'cli.js' ) ;
15- }
16-
178 /**
189 * Execute a command with given arguments
1910 */
20- private async executeCommand ( args : string [ ] ) : Promise < CommandResult > {
21- return new Promise ( ( resolve , reject ) => {
22- const child = spawn ( process . execPath , [ this . cliPath , ...args ] , {
23- cwd : this . extensionPath ,
24- shell : false ,
25- // Do not open a command prompt on spawning
26- windowsHide : true
27- } ) ;
28-
29- let stdout = '' ;
30- let stderr = '' ;
31-
32- child . stdout . on ( 'data' , ( data ) => {
33- stdout += data . toString ( ) ;
34- } ) ;
35-
36- child . stderr . on ( 'data' , ( data ) => {
37- stderr += data . toString ( ) ;
38- } ) ;
39-
40- child . on ( 'close' , ( code ) => {
41- const output = stdout || stderr || 'No output' ;
42- resolve ( {
43- output : output . trim ( ) ,
44- exitCode : code
45- } ) ;
46- } ) ;
47-
48- child . on ( 'error' , ( error ) => {
49- reject ( error ) ;
50- } ) ;
51- } ) ;
11+ private async executeCommand ( args : string [ ] , json : boolean = true ) : Promise < CommandResult > {
12+ try {
13+ const result = await spawn ( args , { json } ) ;
14+ const output = json && typeof result . stdout !== 'string'
15+ ? JSON . stringify ( result . stdout )
16+ : ( result . stdout || result . stderr || 'No output' ) ;
17+ return {
18+ output : typeof output === 'string' ? output . trim ( ) : JSON . stringify ( output ) . trim ( ) ,
19+ exitCode : result . code
20+ } ;
21+ } catch ( error ) {
22+ throw error ;
23+ }
5224 }
5325
5426 /**
5527 * Get the JSON Schema CLI version
5628 */
5729 async getVersion ( ) : Promise < string > {
5830 try {
59- const result = await this . executeCommand ( [ 'version' ] ) ;
31+ const result = await this . executeCommand ( [ 'version' ] , false ) ;
6032 return result . exitCode === 0 ? result . output . trim ( ) : `Error: ${ result . output } ` ;
6133 } catch ( error ) {
6234 return `Error: ${ ( error as Error ) . message } ` ;
@@ -68,12 +40,12 @@ export class CommandExecutor {
6840 */
6941 async lint ( filePath : string , useHttp : boolean = true ) : Promise < string > {
7042 try {
71- const args = [ 'lint' , '--json' ] ;
43+ const args = [ 'lint' ] ;
7244 if ( useHttp ) {
7345 args . push ( '--http' ) ;
7446 }
7547 args . push ( filePath ) ;
76- const result = await this . executeCommand ( args ) ;
48+ const result = await this . executeCommand ( args , true ) ;
7749 return result . output ;
7850 } catch ( error ) {
7951 throw error ;
@@ -85,12 +57,12 @@ export class CommandExecutor {
8557 */
8658 async formatCheck ( filePath : string , useHttp : boolean = true ) : Promise < CommandResult > {
8759 try {
88- const args = [ 'fmt' , '--check' , '--json' ] ;
60+ const args = [ 'fmt' , '--check' ] ;
8961 if ( useHttp ) {
9062 args . push ( '--http' ) ;
9163 }
9264 args . push ( filePath ) ;
93- return await this . executeCommand ( args ) ;
65+ return await this . executeCommand ( args , true ) ;
9466 } catch ( error ) {
9567 throw error ;
9668 }
@@ -100,12 +72,12 @@ export class CommandExecutor {
10072 * Run format command on a file
10173 */
10274 async format ( filePath : string , useHttp : boolean = true ) : Promise < void > {
103- const args = [ 'fmt' , '--json' ] ;
75+ const args = [ 'fmt' ] ;
10476 if ( useHttp ) {
10577 args . push ( '--http' ) ;
10678 }
10779 args . push ( filePath ) ;
108- const result = await this . executeCommand ( args ) ;
80+ const result = await this . executeCommand ( args , true ) ;
10981 if ( result . exitCode !== 0 ) {
11082 try {
11183 const errorObj = JSON . parse ( result . output ) ;
@@ -124,12 +96,12 @@ export class CommandExecutor {
12496 */
12597 async metaschema ( filePath : string , useHttp : boolean = true ) : Promise < CommandResult > {
12698 try {
127- const args = [ 'metaschema' , '--json' ] ;
99+ const args = [ 'metaschema' ] ;
128100 if ( useHttp ) {
129101 args . push ( '--http' ) ;
130102 }
131103 args . push ( filePath ) ;
132- return await this . executeCommand ( args ) ;
104+ return await this . executeCommand ( args , true ) ;
133105 } catch ( error ) {
134106 throw error ;
135107 }
0 commit comments