@@ -153,36 +153,70 @@ async function downloadPackage() {
153153function downloadDependenciesScript() {
154154 if (! props .dependencies ?.length ) return
155155
156- const lines = [
157- ' #!/bin/bash' ,
158- ` # Download dependencies for ${props .packageName }@${props .version .version } ` ,
159- ' mkdir -p node_modules' ,
160- ' ' ,
161- ]
156+ const tarballs: { name: string ; version: string ; url: string }[] = []
162157
163- // Add root package
164158 const rootTarball = props .version .dist .tarball
165159 if (rootTarball ) {
166- lines .push (` # ${props .packageName }@${props .version .version } ` )
167- lines .push (
168- ` curl -L "${rootTarball }" -o "${props .packageName .replace (/ \/ / g , ' __' )}-${props .version .version }.tgz" ` ,
169- )
160+ tarballs .push ({ name: props .packageName , version: props .version .version , url: rootTarball })
170161 }
171162
172- // Add dependencies
173163 props .dependencies .forEach (dep => {
174164 if (! dep .tarballUrl ) return
175- lines .push (` # ${dep .name }@${dep .version } ` )
176- lines .push (
177- ` curl -L "${dep .tarballUrl }" -o "${dep .name .replace (/ \/ / g , ' __' )}-${dep .version }.tgz" ` ,
178- )
165+ tarballs .push ({ name: dep .name , version: dep .version , url: dep .tarballUrl })
179166 })
180167
181- const blob = new Blob ([lines .join (' \n ' )], { type: ' text/x-shellscript' })
168+ const sanitize = (name : string ) => name .replace (/ \/ / g , ' __' )
169+
170+ // Node.js script — works on all platforms
171+ const lines = [
172+ ' #!/usr/bin/env node' ,
173+ ` // Download dependencies for ${props .packageName }@${props .version .version } ` ,
174+ ' // Run: node <filename>' ,
175+ ' ' ,
176+ " const { mkdirSync, createWriteStream } = require('fs');" ,
177+ " const https = require('https');" ,
178+ " const http = require('http');" ,
179+ " const { basename } = require('path');" ,
180+ ' ' ,
181+ " const dir = 'tarballs';" ,
182+ ' mkdirSync(dir, { recursive: true });' ,
183+ ' ' ,
184+ ' const tarballs = [' ,
185+ ... tarballs .map (t => ` { name: '${t .name }', version: '${t .version }', url: '${t .url }' }, ` ),
186+ ' ];' ,
187+ ' ' ,
188+ ' function download(url, dest) {' ,
189+ ' return new Promise((resolve, reject) => {' ,
190+ " const client = url.startsWith('https') ? https : http;" ,
191+ ' client.get(url, (res) => {' ,
192+ ' if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {' ,
193+ ' return download(res.headers.location, dest).then(resolve, reject);' ,
194+ ' }' ,
195+ ' if (res.statusCode !== 200) {' ,
196+ ' return reject(new Error(`HTTP ${res.statusCode} for ${url}`));' ,
197+ ' }' ,
198+ ' const file = createWriteStream(dest);' ,
199+ " res.pipe(file).on('finish', () => file.close(resolve));" ,
200+ ' }).on("error", reject);' ,
201+ ' });' ,
202+ ' }' ,
203+ ' ' ,
204+ ' (async () => {' ,
205+ ' for (const t of tarballs) {' ,
206+ " const filename = `${t.name.replace(/\\ //g, '__')}-${t.version}.tgz`;" ,
207+ ' const dest = `${dir}/${filename}`;' ,
208+ ' console.log(`Downloading ${t.name}@${t.version}...`);' ,
209+ ' await download(t.url, dest);' ,
210+ ' }' ,
211+ ' console.log(`Done! ${tarballs.length} tarball(s) saved to ${dir}/`);' ,
212+ ' })();' ,
213+ ]
214+
215+ const blob = new Blob ([lines .join (' \n ' )], { type: ' application/javascript' })
182216 const url = URL .createObjectURL (blob )
183217 const link = document .createElement (' a' )
184218 link .href = url
185- link .download = ` download-${props .packageName . replace ( / \/ / g , ' __ ' )}-deps.sh `
219+ link .download = ` download-${sanitize ( props .packageName )}-deps.js `
186220 document .body .appendChild (link )
187221 link .click ()
188222 document .body .removeChild (link )
0 commit comments