1- import { Octokit } from "octokit"
1+ import { Octokit } from "@ octokit/core" ;
22import {
33 PackageCache ,
44 Package ,
@@ -11,16 +11,30 @@ import path from 'path';
1111import { tmpdir } from 'os' ;
1212import { StringDecoder } from 'node:string_decoder' ;
1313
14- export default class ComponentDetection {
15- public static componentDetectionPath = process . platform === "win32" ? './component-detection.exe' : './component-detection' ;
16- public static outputPath = path . join ( tmpdir ( ) , `component-detection-output-${ Date . now ( ) } .json` ) ;
14+ export default class ComponentDetection {
15+ public componentDetectionPath : string = process . platform === "win32" ? './component-detection.exe' : './component-detection' ;
16+ public outputPath : string ;
17+ octokit : Octokit ;
18+ baseUrl : string ;
1719
18- // This is the default entry point for this class.
19- // If executablePath is provided, use it directly and skip download.
20- static async scanAndGetManifests ( path : string , executablePath ?: string ) : Promise < Manifest [ ] | undefined > {
20+ constructor ( octokit : Octokit , baseUrl : string , executablePath ?: string ) {
21+ this . octokit = octokit ;
22+ this . baseUrl = baseUrl ;
2123 if ( executablePath ) {
2224 this . componentDetectionPath = executablePath ;
23- } else {
25+ }
26+
27+ // Set the output path
28+ this . outputPath = ( ( ) => {
29+ const tmpDir = fs . mkdtempSync ( path . join ( tmpdir ( ) , 'component-detection-' ) ) ;
30+ return path . join ( tmpDir , 'output.json' ) ;
31+ } ) ( ) ;
32+ }
33+
34+ // This is the default entry point for this class.
35+ // If executablePath is provided, use it directly and skip download.
36+ async scanAndGetManifests ( path : string ) : Promise < Manifest [ ] | undefined > {
37+ if ( ! this . componentDetectionPath ) {
2438 await this . downloadLatestRelease ( ) ;
2539 }
2640
@@ -34,7 +48,7 @@ export default class ComponentDetection {
3448 return await this . getManifestsFromResults ( this . outputPath , path ) ;
3549 }
3650 // Get the latest release from the component-detection repo, download the tarball, and extract it
37- public static async downloadLatestRelease ( ) {
51+ public async downloadLatestRelease ( ) {
3852 try {
3953 const statResult = fs . statSync ( this . componentDetectionPath ) ;
4054 if ( statResult && statResult . isFile ( ) ) {
@@ -54,14 +68,14 @@ export default class ComponentDetection {
5468
5569 // Write the blob to a file
5670 console . debug ( `Writing binary to file ${ this . componentDetectionPath } ` ) ;
57- await fs . writeFileSync ( this . componentDetectionPath , buffer , { mode : 0o777 , flag : 'w' } ) ;
71+ await fs . writeFileSync ( this . componentDetectionPath , buffer , { mode : 0o755 , flag : 'w' } ) ;
5872 } catch ( error : any ) {
5973 console . error ( error ) ;
6074 }
6175 }
6276
6377 // Run the component-detection CLI on the path specified
64- public static runComponentDetection ( path : string ) : Promise < boolean > {
78+ public runComponentDetection ( path : string ) : Promise < boolean > {
6579 console . debug ( `Running component-detection on ${ path } ` ) ;
6680
6781 console . debug ( `Writing to output file: ${ this . outputPath } ` ) ;
@@ -102,7 +116,7 @@ export default class ComponentDetection {
102116 } ) ;
103117 }
104118
105- public static async getManifestsFromResults ( file : string , path : string ) : Promise < Manifest [ ] | undefined > {
119+ public async getManifestsFromResults ( file : string , path : string ) : Promise < Manifest [ ] | undefined > {
106120 console . debug ( `Reading results from ${ file } ` ) ;
107121 const results = await fs . readFileSync ( file , 'utf8' ) ;
108122 const json : any = JSON . parse ( results ) ;
@@ -112,7 +126,7 @@ export default class ComponentDetection {
112126 return this . processComponentsToManifests ( json . componentsFound , dependencyGraphs ) ;
113127 }
114128
115- public static processComponentsToManifests ( componentsFound : any [ ] , dependencyGraphs : DependencyGraphs ) : Manifest [ ] {
129+ public processComponentsToManifests ( componentsFound : any [ ] , dependencyGraphs : DependencyGraphs ) : Manifest [ ] {
116130 // Parse the result file and add the packages to the package cache
117131 const packageCache = new PackageCache ( ) ;
118132 const packages : Array < ComponentDetectionPackage > = [ ] ;
@@ -193,7 +207,7 @@ export default class ComponentDetection {
193207 return manifests ;
194208 }
195209
196- private static addPackagesToManifests ( packages : Array < ComponentDetectionPackage > , manifests : Array < Manifest > , dependencyGraphs : DependencyGraphs ) : void {
210+ private addPackagesToManifests ( packages : Array < ComponentDetectionPackage > , manifests : Array < Manifest > , dependencyGraphs : DependencyGraphs ) : void {
197211 packages . forEach ( ( pkg : ComponentDetectionPackage ) => {
198212 pkg . locationsFoundAt . forEach ( ( location : any ) => {
199213 // Use the normalized path (remove leading slash if present)
@@ -250,7 +264,7 @@ export default class ComponentDetection {
250264 }
251265
252266 try {
253- var packageUrl = `${ packageUrlJson . Scheme } :${ packageUrlJson . Type } /` ;
267+ let packageUrl = `${ packageUrlJson . Scheme } :${ packageUrlJson . Type } /` ;
254268 if ( packageUrlJson . Namespace ) {
255269 packageUrl += `${ packageUrlJson . Namespace . replaceAll ( "@" , "%40" ) } /` ;
256270 }
@@ -274,28 +288,23 @@ export default class ComponentDetection {
274288 }
275289 }
276290
277- private static async getLatestReleaseURL ( ) : Promise < string > {
278- let githubToken = process . env . GITHUB_TOKEN || "" ;
279-
280- const githubAPIURL = process . env . GITHUB_API_URL || 'https://api.github.com' ;
281-
282- let ghesMode = process . env . GITHUB_API_URL != githubAPIURL ;
283- // If the we're running in GHES, then use an empty string as the token
284- if ( ghesMode ) {
285- githubToken = "" ;
291+ private async getLatestReleaseURL ( ) : Promise < string > {
292+ let octokit : Octokit = this . octokit ;
293+
294+ if ( this . baseUrl !== 'https://api.github.com' ) {
295+ octokit = new Octokit ( {
296+ auth : "" , request : { fetch : fetch } , log : {
297+ debug : console . debug ,
298+ info : console . info ,
299+ warn : console . warn ,
300+ error : console . error
301+ } ,
302+ } ) ;
286303 }
287- const octokit = new Octokit ( {
288- auth : githubToken , baseUrl : githubAPIURL , request : { fetch : fetch } , log : {
289- debug : console . debug ,
290- info : console . info ,
291- warn : console . warn ,
292- error : console . error
293- } ,
294- } ) ;
295304
296305 const owner = "microsoft" ;
297306 const repo = "component-detection" ;
298- console . debug ( " Attempting to download latest release from " + githubAPIURL ) ;
307+ console . debug ( ` Attempting to download latest release from ${ owner } / ${ repo } ` ) ;
299308
300309 try {
301310 const latestRelease = await octokit . request ( "GET /repos/{owner}/{repo}/releases/latest" , { owner, repo } ) ;
@@ -325,7 +334,7 @@ export default class ComponentDetection {
325334 * @param filePathInput The filePath input (relative or absolute) from the action configuration.
326335 * @returns A new DependencyGraphs object with relative path keys.
327336 */
328- public static normalizeDependencyGraphPaths (
337+ public normalizeDependencyGraphPaths (
329338 dependencyGraphs : DependencyGraphs ,
330339 filePathInput : string
331340 ) : DependencyGraphs {
0 commit comments