1- const { execSync } = require ( 'child_process' )
1+ const { ZipReader , BlobReader , Uint8ArrayWriter } = require ( '@zip.js/zip.js' ) ;
22const { createHash } = require ( 'crypto' )
33const fs = require ( 'fs' )
44const https = require ( 'https' )
55const path = require ( 'path' )
6- const { promisify } = require ( 'util' )
7- const { pipeline } = require ( 'stream' )
8- const streamPipeline = promisify ( pipeline )
9-
6+ const os = require ( 'os' )
107const tag = require ( './package.json' ) . version
11- const os = process . platform
8+
9+ const platform = process . platform
1210const cpu = process . arch
1311
1412// Map Node.js platform and architecture to binary names
1513function getBinaryInfo ( ) {
16- const buildMap = {
17- 'linux-ia32' : 'linux-32-bit' ,
18- 'linux-x32' : 'linux-32-bit' ,
19- 'linux-x64' : 'linux-64-bit' ,
20- 'linux-arm64' : 'linux-arm' ,
21- 'darwin-x64' : 'macos-64-bit' ,
22- 'darwin-arm64' : 'macos-arm' ,
23- 'win32-ia32' : 'windows-32-bit' ,
24- 'win32-x32' : 'windows-32-bit' ,
25- 'win32-x64' : 'windows-64-bit' ,
26- }
27-
28- const key = `${ os } -${ cpu } `
29- const build = buildMap [ key ]
30-
31- if ( ! build ) {
32- throw new Error ( `Unsupported platform: ${ os } -${ cpu } ` )
14+ let build = ''
15+ if ( platform === 'darwin' ) {
16+ if ( cpu === 'arm64' ) {
17+ build = 'macos-arm'
18+ } else {
19+ build = 'macos-64-bit'
20+ }
21+ } else if ( platform === 'win32' ) {
22+ if ( cpu === 'x64' ) {
23+ build = 'windows-64-bit'
24+ } else {
25+ build = 'windows-32-bit'
26+ }
27+ } else if ( platform === 'linux' ) {
28+ if ( cpu === 'x64' ) {
29+ build = 'linux-64-bit'
30+ } else if ( cpu === 'arm64' ) {
31+ build = 'linux-arm'
32+ } else {
33+ build = 'linux-32-bit'
34+ }
35+ } else {
36+ throw new Error ( `Unsupported platform: ${ platform } -${ cpu } ` )
3337 }
3438
3539 return {
3640 build,
3741 filename : `sqlx-ts-v${ tag } -${ build } .zip` ,
38- binaryName : os === 'win32' ? 'sqlx-ts.exe' : 'sqlx-ts'
42+ binaryName : platform === 'win32' ? 'sqlx-ts.exe' : 'sqlx-ts'
3943 }
4044}
4145
4246// Download file from URL
43- function downloadFile ( url , destination ) {
47+ function downloadFile ( url , destination , redirectCount = 0 ) {
4448 return new Promise ( ( resolve , reject ) => {
49+ if ( redirectCount > 5 ) {
50+ return reject ( new Error ( "Too many redirects while downloading file" ) )
51+ }
52+
4553 const file = fs . createWriteStream ( destination )
4654 https . get ( url , ( response ) => {
4755 if ( response . statusCode === 302 || response . statusCode === 301 ) {
48- // Handle redirect
56+ // Handle redirects
57+ // Close the current file and delete it
58+ // Then download from the new location
4959 file . close ( )
5060 fs . unlinkSync ( destination )
51- return downloadFile ( response . headers . location , destination )
61+ return downloadFile ( response . headers . location , destination , redirectCount + 1 )
5262 . then ( resolve )
5363 . catch ( reject )
5464 }
@@ -82,7 +92,6 @@ function calculateSHA256(filePath) {
8292 } )
8393}
8494
85- // Verify file hash
8695async function verifyHash ( filePath , expectedHash ) {
8796 const actualHash = await calculateSHA256 ( filePath )
8897
@@ -98,38 +107,40 @@ async function verifyHash(filePath, expectedHash) {
98107 return true
99108}
100109
101- // Extract binary from zip
102- function extractBinary ( zipPath , binaryName , targetPath ) {
103- const AdmZip = require ( 'adm-zip' )
104- const zip = new AdmZip ( zipPath )
105- const zipEntries = zip . getEntries ( )
106-
107- for ( const entry of zipEntries ) {
108- if ( entry . entryName . endsWith ( binaryName ) ) {
109- // Extract the entry's content directly
110- const data = entry . getData ( )
111- fs . writeFileSync ( targetPath , data )
112- fs . chmodSync ( targetPath , 0o755 )
113- return
110+ async function extractBinary ( zipPath , binaryName , targetPath ) {
111+ const zipData = fs . readFileSync ( zipPath ) ;
112+ const reader = new ZipReader ( new BlobReader ( new Blob ( [ zipData ] ) ) ) ;
113+
114+ const entries = await reader . getEntries ( ) ;
115+
116+ for ( const entry of entries ) {
117+ if ( entry . filename . endsWith ( binaryName ) ) {
118+ const writer = new Uint8ArrayWriter ( ) ;
119+ const data = await entry . getData ( writer ) ;
120+ fs . writeFileSync ( targetPath , Buffer . from ( data ) ) ;
121+ fs . chmodSync ( targetPath , 0o755 ) ;
122+ await reader . close ( ) ;
123+ return ;
114124 }
115125 }
116126
117- throw new Error ( `Binary ${ binaryName } not found in archive` )
127+ throw new Error ( `Binary ${ binaryName } not found in zip` ) ;
118128}
119129
120130async function install ( ) {
121131 try {
122- const { build , filename, binaryName } = getBinaryInfo ( )
132+ const { filename, binaryName } = getBinaryInfo ( )
123133 const baseUrl = `https://github.com/JasonShin/sqlx-ts/releases/download/v${ tag } `
124134 const zipUrl = `${ baseUrl } /${ filename } `
125135 const checksumUrl = `${ zipUrl } .sha256`
126136
127- const tmpDir = fs . mkdtempSync ( path . join ( require ( 'os' ) . tmpdir ( ) , 'sqlx-ts-' ) )
137+ const tmpDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'sqlx-ts-' ) )
128138 const zipPath = path . join ( tmpDir , filename )
129139 const checksumPath = path . join ( tmpDir , `${ filename } .sha256` )
130- const targetPath = path . join ( __dirname , 'sqlx-ts' + ( os === 'win32' ? '.exe' : '' ) )
140+ console . log ( 'checking checksum url:' , checksumUrl )
141+ const targetPath = path . join ( __dirname , 'sqlx-ts' + ( platform === 'win32' ? '.exe' : '' ) )
131142
132- console . info ( `Downloading sqlx-ts v${ tag } for ${ os } -${ cpu } ...` )
143+ console . info ( `Downloading sqlx-ts v${ tag } for ${ platform } -${ cpu } ...` )
133144 console . info ( `URL: ${ zipUrl } ` )
134145
135146 // Download the zip file
@@ -156,12 +167,13 @@ async function install() {
156167
157168 // Extract the binary
158169 console . info ( 'Extracting binary...' )
159- extractBinary ( zipPath , binaryName , targetPath )
170+ await extractBinary ( zipPath , binaryName , targetPath )
160171
161172 // Cleanup
162173 fs . rmSync ( tmpDir , { recursive : true , force : true } )
163174
164175 console . info ( 'sqlx-ts installation successful' )
176+ process . exit ( 0 )
165177 } catch ( error ) {
166178 console . error ( 'Installation failed:' , error . message )
167179 process . exit ( 1 )
0 commit comments