@@ -2,42 +2,65 @@ import * as fsPromises from 'fs/promises';
22import * as fs from 'fs' ;
33import * as path from 'path' ;
44import * as tar from 'tar' ;
5- import axios , { AxiosRequestConfig } from 'axios' ;
65import * as unzipper from 'unzipper' ;
76import { logger } from "../wrapper/loggerConfig" ;
8- import { finished } from 'stream/promises' ;
7+ import { Client } from "../client/Client" ;
98
109type SupportedPlatforms = 'win32' | 'darwin' | 'linux' ;
1110
11+ interface PlatformData {
12+ platform : string ;
13+ extension : string ;
14+ }
15+
1216export class CxInstaller {
13- private readonly platform : string ;
17+ private readonly platform : SupportedPlatforms ;
1418 private cliVersion : string ;
1519 private readonly resourceDirPath : string ;
1620 private readonly installedCLIVersionFileName = 'cli-version' ;
17- private readonly cliDefaultVersion = '2.2.5' ; // This will be used if the version file is not found. Should be updated with the latest version.
18-
19- constructor ( platform : string ) {
20- this . platform = platform ;
21- this . resourceDirPath = path . join ( __dirname , `../wrapper/resources` ) ;
21+ private readonly cliDefaultVersion = '2.2.5' ; // Update this with the latest version.
22+ private readonly client ;
23+
24+ private static readonly PLATFORMS : Record < SupportedPlatforms , PlatformData > = {
25+ win32 : { platform : 'windows' , extension : 'zip' } ,
26+ darwin : { platform : 'darwin' , extension : 'tar.gz' } ,
27+ linux : { platform : 'linux' , extension : 'tar.gz' }
28+ } ;
29+
30+ constructor ( platform : string , client : Client ) {
31+ this . platform = platform as SupportedPlatforms ;
32+ this . resourceDirPath = path . join ( __dirname , '../wrapper/resources' ) ;
33+ this . client = client ;
2234 }
2335
2436 private async getDownloadURL ( ) : Promise < string > {
2537 const cliVersion = await this . readASTCLIVersion ( ) ;
38+ const platformData = CxInstaller . PLATFORMS [ this . platform ] ;
2639
27- const platforms : Record < SupportedPlatforms , { platform : string ; extension : string } > = {
28- win32 : { platform : 'windows' , extension : 'zip' } ,
29- darwin : { platform : 'darwin' , extension : 'tar.gz' } ,
30- linux : { platform : 'linux' , extension : 'tar.gz' }
31- } ;
32-
33- const platformKey = this . platform as SupportedPlatforms ;
34-
35- const platformData = platforms [ platformKey ] ;
3640 if ( ! platformData ) {
3741 throw new Error ( 'Unsupported platform or architecture' ) ;
3842 }
3943
40- return `https://download.checkmarx.com/CxOne/CLI/${ cliVersion } /ast-cli_${ cliVersion } _${ platformData . platform } _x64.${ platformData . extension } ` ;
44+ const arch = this . getArchitecture ( ) ;
45+ logger . info ( `Platform: ${ this . platform } , Arch: ${ arch } ` ) ;
46+
47+ return `https://download.checkmarx.com/CxOne/CLI/${ cliVersion } /ast-cli_${ cliVersion } _${ platformData . platform } _${ arch } .${ platformData . extension } ` ;
48+ }
49+
50+ private getArchitecture ( ) : string {
51+ // For non-linux platforms we default to x64.
52+ if ( this . platform !== 'linux' ) {
53+ return 'x64' ;
54+ }
55+
56+ switch ( process . arch ) {
57+ case 'arm64' :
58+ return 'arm64' ;
59+ case 'arm' :
60+ return 'armv6' ;
61+ default :
62+ return 'x64' ;
63+ }
4164 }
4265
4366 public getExecutablePath ( ) : string {
@@ -62,7 +85,7 @@ export class CxInstaller {
6285 const url = await this . getDownloadURL ( ) ;
6386 const zipPath = path . join ( this . resourceDirPath , this . getCompressFolderName ( ) ) ;
6487
65- await this . downloadFile ( url , zipPath ) ;
88+ await this . client . downloadFile ( url , zipPath ) ;
6689 logger . info ( 'Downloaded CLI to:' , zipPath ) ;
6790
6891 await this . extractArchive ( zipPath , this . resourceDirPath ) ;
@@ -147,59 +170,6 @@ export class CxInstaller {
147170 }
148171 }
149172
150- private async downloadFile ( url : string , outputPath : string ) {
151- logger . info ( `Starting download from URL: ${ url } ` ) ;
152- const writer = fs . createWriteStream ( outputPath ) ;
153-
154- try {
155- // Create base Axios configuration
156- const axiosConfig : AxiosRequestConfig = {
157- url,
158- responseType : 'stream' ,
159- } ;
160-
161- // Configure proxy if HTTP_PROXY environment variable is set
162- const proxyUrl = process . env . HTTP_PROXY ;
163- if ( proxyUrl ) {
164- logger . info ( `Detected proxy configuration in HTTP_PROXY` ) ;
165- const parsedProxy = new URL ( proxyUrl ) ;
166-
167- axiosConfig . proxy = {
168- host : parsedProxy . hostname ,
169- port : parseInt ( parsedProxy . port , 10 ) ,
170- protocol : parsedProxy . protocol . replace ( ':' , '' ) , // remove the colon
171- auth : parsedProxy . username && parsedProxy . password
172- ? { username : parsedProxy . username , password : parsedProxy . password }
173- : undefined , // Only include auth if credentials are provided
174- } ;
175-
176- logger . info (
177- `Using proxy - Host: ${ axiosConfig . proxy . host } , Port: ${ axiosConfig . proxy . port } , ` +
178- `Protocol: ${ axiosConfig . proxy . protocol } , Auth: ${ axiosConfig . proxy . auth ? 'Yes' : 'No' } `
179- ) ;
180- } else {
181- logger . info ( 'No proxy configuration detected.' ) ;
182- }
183-
184- // Perform the download request
185- logger . info ( `Initiating download request to: ${ url } ` ) ;
186- const response = await axios ( axiosConfig ) ;
187-
188- // Pipe the response data to the output file
189- response . data . pipe ( writer ) ;
190-
191- // Await the completion of the write stream
192- await finished ( writer ) ;
193- logger . info ( `Download completed successfully. File saved to: ${ outputPath } ` ) ;
194- } catch ( error ) {
195- logger . error ( `Error downloading file from ${ url } : ${ error . message || error } ` ) ;
196- } finally {
197- writer . close ( ) ;
198- logger . info ( 'Write stream closed.' ) ;
199- }
200- }
201-
202-
203173 private checkExecutableExists ( ) : boolean {
204174 return fs . existsSync ( this . getExecutablePath ( ) ) ;
205175 }
0 commit comments