@@ -82,6 +82,13 @@ export interface DlxBinaryOptions {
8282 */
8383 integrity ?: string | undefined
8484
85+ /**
86+ * Expected SHA-256 hex checksum for verification.
87+ * Passed to httpDownload for inline verification during download.
88+ * This is more secure than post-download verification as it fails early.
89+ */
90+ sha256 ?: string | undefined
91+
8592 /**
8693 * Cache TTL in milliseconds (default: 7 days).
8794 */
@@ -263,6 +270,7 @@ export async function dlxBinary(
263270 force : userForce = false ,
264271 integrity,
265272 name,
273+ sha256,
266274 spawnOptions,
267275 url,
268276 yes,
@@ -346,7 +354,12 @@ export async function dlxBinary(
346354 }
347355
348356 // Download the binary.
349- computedIntegrity = await downloadBinaryFile ( url , binaryPath , integrity )
357+ computedIntegrity = await downloadBinaryFile (
358+ url ,
359+ binaryPath ,
360+ integrity ,
361+ sha256 ,
362+ )
350363
351364 // Get file size for metadata.
352365 const stats = await fs . promises . stat ( binaryPath )
@@ -412,6 +425,7 @@ export async function downloadBinary(
412425 force = false ,
413426 integrity,
414427 name,
428+ sha256,
415429 url,
416430 } = { __proto__ : null , ...options } as DlxBinaryOptions
417431 const fs = getFs ( )
@@ -466,6 +480,7 @@ export async function downloadBinary(
466480 url ,
467481 binaryPath ,
468482 integrity ,
483+ sha256 ,
469484 )
470485
471486 // Get file size for metadata.
@@ -490,11 +505,18 @@ export async function downloadBinary(
490505 * Download a file from a URL with integrity checking and concurrent download protection.
491506 * Uses processLock to prevent multiple processes from downloading the same binary simultaneously.
492507 * Internal helper function for downloading binary files.
508+ *
509+ * Supports two integrity verification methods:
510+ * - sha256: Hex SHA-256 checksum (verified inline during download via httpDownload)
511+ * - integrity: SRI format sha512-<base64> (verified post-download)
512+ *
513+ * The sha256 option is preferred as it fails early during download if the checksum doesn't match.
493514 */
494515export async function downloadBinaryFile (
495516 url : string ,
496517 destPath : string ,
497518 integrity ?: string | undefined ,
519+ sha256 ?: string | undefined ,
498520) : Promise < string > {
499521 // Use process lock to prevent concurrent downloads.
500522 // Lock is placed in the cache entry directory as 'concurrency.lock'.
@@ -521,9 +543,11 @@ export async function downloadBinaryFile(
521543 }
522544 }
523545
524- // Download the file.
546+ // Download the file with optional SHA-256 verification.
547+ // The sha256 option enables inline verification during download,
548+ // which is more secure as it fails early if the checksum doesn't match.
525549 try {
526- await httpDownload ( url , destPath )
550+ await httpDownload ( url , destPath , sha256 ? { sha256 } : undefined )
527551 } catch ( e ) {
528552 throw new Error (
529553 `Failed to download binary from ${ url } \n` +
0 commit comments