@@ -61,7 +61,7 @@ function getGitHubToken() {
6161 return null ;
6262}
6363
64- function httpsGet ( url , token = null ) {
64+ function httpsGet ( url , token = null , isBinaryDownload = false ) {
6565 return new Promise ( ( resolve , reject ) => {
6666 const headers = { "User-Agent" : "relay-dedup-installer" } ;
6767
@@ -70,19 +70,20 @@ function httpsGet(url, token = null) {
7070 headers [ "Authorization" ] = `token ${ token } ` ;
7171 }
7272
73- // For GitHub release assets, we need to accept the binary
74- if ( url . includes ( "github.com" ) && url . includes ( "/releases/download/" ) ) {
73+ // For downloading binary assets from API URL
74+ if ( isBinaryDownload ) {
7575 headers [ "Accept" ] = "application/octet-stream" ;
7676 }
7777
7878 https
7979 . get ( url , { headers } , ( res ) => {
80- // Follow redirects (pass token only for same-origin redirects )
80+ // Follow redirects (don't pass token to external domains like S3 )
8181 if ( res . statusCode === 301 || res . statusCode === 302 ) {
8282 const redirectUrl = res . headers . location ;
83- // Don't pass token to external domains (like S3)
84- const sameOrigin = redirectUrl . includes ( "github.com" ) ;
85- return httpsGet ( redirectUrl , sameOrigin ? token : null )
83+ const sameOrigin =
84+ redirectUrl . includes ( "github.com" ) ||
85+ redirectUrl . includes ( "api.github.com" ) ;
86+ return httpsGet ( redirectUrl , sameOrigin ? token : null , isBinaryDownload )
8687 . then ( resolve )
8788 . catch ( reject ) ;
8889 }
@@ -99,21 +100,44 @@ function httpsGet(url, token = null) {
99100 } ) ;
100101}
101102
103+ async function getAssetUrl ( version , assetName , token ) {
104+ // For private repos, we need to use the API to get the asset download URL
105+ const apiUrl = `https://api.github.com/repos/${ REPO } /releases/tags/v${ version } ` ;
106+
107+ const response = await httpsGet ( apiUrl , token ) ;
108+ const release = JSON . parse ( response . toString ( ) ) ;
109+
110+ if ( ! release . assets ) {
111+ throw new Error ( `No assets found in release v${ version } ` ) ;
112+ }
113+
114+ const asset = release . assets . find ( ( a ) => a . name === assetName ) ;
115+ if ( ! asset ) {
116+ const available = release . assets . map ( ( a ) => a . name ) . join ( ", " ) ;
117+ throw new Error ( `Asset ${ assetName } not found. Available: ${ available } ` ) ;
118+ }
119+
120+ // Return the API URL for downloading (works for private repos)
121+ return asset . url ;
122+ }
123+
102124async function downloadBinary ( ) {
103125 const target = getTarget ( ) ;
104126 const version = getVersion ( ) ;
105127 const token = getGitHubToken ( ) ;
106128 const assetName = `${ BINARY_NAME } -${ target } .tar.gz` ;
107- const url = `https://github.com/${ REPO } /releases/download/v${ version } /${ assetName } ` ;
108129
109130 console . log ( `Downloading ${ BINARY_NAME } v${ version } for ${ getPlatformKey ( ) } ...` ) ;
110- console . log ( ` ${ url } ` ) ;
111131 if ( token ) {
112132 console . log ( ` (using GitHub token for authentication)` ) ;
113133 }
114134
115135 try {
116- const tarGz = await httpsGet ( url , token ) ;
136+ // Get the asset download URL from the API
137+ const assetUrl = await getAssetUrl ( version , assetName , token ) ;
138+ console . log ( ` ${ assetUrl } ` ) ;
139+
140+ const tarGz = await httpsGet ( assetUrl , token , true ) ;
117141
118142 // Extract tar.gz
119143 const tar = zlib . gunzipSync ( tarGz ) ;
0 commit comments