11/** @fileoverview DLX binary execution utilities for Socket ecosystem. */
22
3- import { createHash } from 'crypto'
4-
5- import os from 'os'
6-
7- import path from 'path'
8-
9- import { WIN32 } from '../constants/platform'
3+ import { getArch , getPlatform , WIN32 } from '../constants/platform'
104import { DLX_BINARY_CACHE_TTL } from '../constants/time'
115
126import { generateCacheKey } from './cache'
@@ -17,25 +11,61 @@ import { isObjectObject } from '../objects'
1711import { normalizePath } from '../paths/normalize'
1812import { getSocketDlxDir } from '../paths/socket'
1913import { processLock } from '../process-lock'
20- import type { SpawnExtra , SpawnOptions } from '../spawn'
2114import { spawn } from '../spawn'
2215
23- let _fs : typeof import ( 'fs' ) | undefined
16+ import type { ChecksumAlgorithm } from './manifest'
17+ import type { SpawnExtra , SpawnOptions } from '../spawn'
18+
19+ let _crypto : typeof import ( 'node:crypto' ) | undefined
20+ /**
21+ * Lazily load the crypto module to avoid Webpack errors.
22+ * Uses non-'node:' prefixed require to prevent Webpack bundling issues.
23+ *
24+ * @private
25+ */
26+ /*@__NO_SIDE_EFFECTS__ */
27+ function getCrypto ( ) {
28+ if ( _crypto === undefined ) {
29+ // Use non-'node:' prefixed require to avoid Webpack errors.
30+
31+ _crypto = /*@__PURE__ */ require ( 'crypto' )
32+ }
33+ return _crypto as typeof import ( 'node:crypto' )
34+ }
35+
36+ let _fs : typeof import ( 'node:fs' ) | undefined
2437/**
2538 * Lazily load the fs module to avoid Webpack errors.
2639 * Uses non-'node:' prefixed require to prevent Webpack bundling issues.
2740 *
28- * @returns The Node.js fs module
2941 * @private
3042 */
3143/*@__NO_SIDE_EFFECTS__ */
3244function getFs ( ) {
3345 if ( _fs === undefined ) {
3446 // Use non-'node:' prefixed require to avoid Webpack errors.
3547
36- _fs = /*@__PURE__ */ require ( 'node: fs' )
48+ _fs = /*@__PURE__ */ require ( 'fs' )
3749 }
38- return _fs as typeof import ( 'fs' )
50+ return _fs as typeof import ( 'node:fs' )
51+ }
52+
53+ let _path : typeof import ( 'node:path' ) | undefined
54+ /**
55+ * Lazily load the path module to avoid Webpack errors.
56+ * Uses non-'node:' prefixed require to prevent Webpack bundling issues.
57+ *
58+ * @returns The Node.js path module
59+ * @private
60+ */
61+ /*@__NO_SIDE_EFFECTS__ */
62+ function getPath ( ) {
63+ if ( _path === undefined ) {
64+ // Use non-'node:' prefixed require to avoid Webpack errors.
65+
66+ _path = /*@__PURE__ */ require ( 'path' )
67+ }
68+ return _path as typeof import ( 'node:path' )
3969}
4070
4171export interface DlxBinaryOptions {
@@ -180,7 +210,7 @@ export interface DlxMetadata {
180210 * Get metadata file path for a cached binary.
181211 */
182212function getMetadataPath ( cacheEntryPath : string ) : string {
183- return path . join ( cacheEntryPath , '.dlx-metadata.json' )
213+ return getPath ( ) . join ( cacheEntryPath , '.dlx-metadata.json' )
184214}
185215
186216/**
@@ -227,20 +257,22 @@ async function downloadBinaryFile(
227257) : Promise < string > {
228258 // Use process lock to prevent concurrent downloads.
229259 // Lock is placed in the cache entry directory as 'concurrency.lock'.
260+ const crypto = getCrypto ( )
261+ const fs = getFs ( )
262+ const path = getPath ( )
230263 const cacheEntryDir = path . dirname ( destPath )
231264 const lockPath = path . join ( cacheEntryDir , 'concurrency.lock' )
232265
233266 return await processLock . withLock (
234267 lockPath ,
235268 async ( ) => {
236- const fs = getFs ( )
237269 // Check if file was downloaded while waiting for lock.
238270 if ( fs . existsSync ( destPath ) ) {
239271 const stats = await fs . promises . stat ( destPath )
240272 if ( stats . size > 0 ) {
241273 // File exists, compute and return checksum.
242274 const fileBuffer = await fs . promises . readFile ( destPath )
243- const hasher = createHash ( 'sha256' )
275+ const hasher = crypto . createHash ( 'sha256' )
244276 hasher . update ( fileBuffer )
245277 return hasher . digest ( 'hex' )
246278 }
@@ -260,7 +292,7 @@ async function downloadBinaryFile(
260292
261293 // Compute checksum of downloaded file.
262294 const fileBuffer = await fs . promises . readFile ( destPath )
263- const hasher = createHash ( 'sha256' )
295+ const hasher = crypto . createHash ( 'sha256' )
264296 hasher . update ( fileBuffer )
265297 const actualChecksum = hasher . digest ( 'hex' )
266298
@@ -312,9 +344,9 @@ async function writeMetadata(
312344 cache_key : cacheKey ,
313345 timestamp : Date . now ( ) ,
314346 checksum,
315- checksum_algorithm : 'sha256' ,
316- platform : os . platform ( ) ,
317- arch : os . arch ( ) ,
347+ checksum_algorithm : 'sha256' as ChecksumAlgorithm ,
348+ platform : getPlatform ( ) ,
349+ arch : getArch ( ) ,
318350 size,
319351 source : {
320352 type : 'download' ,
@@ -329,9 +361,9 @@ async function writeMetadata(
329361 const spec = `${ url } :${ binaryName } `
330362 await dlxManifest . setBinaryEntry ( spec , cacheKey , {
331363 checksum,
332- checksum_algorithm : 'sha256' ,
333- platform : os . platform ( ) ,
334- arch : os . arch ( ) ,
364+ checksum_algorithm : metadata . checksum_algorithm ,
365+ platform : metadata . platform ,
366+ arch : metadata . arch ,
335367 size,
336368 source : {
337369 type : 'download' ,
@@ -359,6 +391,7 @@ export async function cleanDlxCache(
359391
360392 let cleaned = 0
361393 const now = Date . now ( )
394+ const path = getPath ( )
362395 const entries = await fs . promises . readdir ( cacheDir )
363396
364397 for ( const entry of entries ) {
@@ -428,19 +461,18 @@ export async function dlxBinary(
428461 url,
429462 yes,
430463 } = { __proto__ : null , ...options } as DlxBinaryOptions
431-
464+ const fs = getFs ( )
465+ const path = getPath ( )
432466 // Map --yes flag to force behavior (auto-approve/skip prompts)
433467 const force = yes === true ? true : userForce
434-
435468 // Generate cache paths similar to pnpm/npx structure.
436469 const cacheDir = getDlxCachePath ( )
437- const binaryName = name || `binary-${ process . platform } -${ os . arch ( ) } `
470+ const binaryName = name || `binary-${ process . platform } -${ getArch ( ) } `
438471 // Create spec from URL and binary name for unique cache identity.
439472 const spec = `${ url } :${ binaryName } `
440473 const cacheKey = generateCacheKey ( spec )
441474 const cacheEntryDir = path . join ( cacheDir , cacheKey )
442475 const binaryPath = normalizePath ( path . join ( cacheEntryDir , binaryName ) )
443- const fs = getFs ( )
444476
445477 let downloaded = false
446478 let computedChecksum = checksum
@@ -542,7 +574,7 @@ export async function dlxBinary(
542574 ...spawnOptions ,
543575 env : {
544576 ...spawnOptions ?. env ,
545- PATH : `${ cacheEntryDir } ${ path . delimiter } ${ process . env [ 'PATH' ] || '' } ` ,
577+ PATH : `${ cacheEntryDir } ${ getPath ( ) . delimiter } ${ process . env [ 'PATH' ] || '' } ` ,
546578 } ,
547579 shell : true ,
548580 }
@@ -572,16 +604,16 @@ export async function downloadBinary(
572604 name,
573605 url,
574606 } = { __proto__ : null , ...options } as DlxBinaryOptions
575-
607+ const fs = getFs ( )
608+ const path = getPath ( )
576609 // Generate cache paths similar to pnpm/npx structure.
577610 const cacheDir = getDlxCachePath ( )
578- const binaryName = name || `binary-${ process . platform } -${ os . arch ( ) } `
611+ const binaryName = name || `binary-${ process . platform } -${ getArch ( ) } `
579612 // Create spec from URL and binary name for unique cache identity.
580613 const spec = `${ url } :${ binaryName } `
581614 const cacheKey = generateCacheKey ( spec )
582615 const cacheEntryDir = path . join ( cacheDir , cacheKey )
583616 const binaryPath = normalizePath ( path . join ( cacheEntryDir , binaryName ) )
584- const fs = getFs ( )
585617
586618 let downloaded = false
587619
@@ -670,6 +702,7 @@ export function executeBinary(
670702 //
671703 // Since our binaries are downloaded to a custom cache directory that's not in PATH,
672704 // we must prepend the cache directory to PATH so cmd.exe can locate the binary.
705+ const path = getPath ( )
673706 const cacheEntryDir = path . dirname ( binaryPath )
674707 const finalSpawnOptions = needsShell
675708 ? {
@@ -717,6 +750,7 @@ export async function listDlxCache(): Promise<
717750
718751 const results = [ ]
719752 const now = Date . now ( )
753+ const path = getPath ( )
720754 const entries = await fs . promises . readdir ( cacheDir )
721755
722756 for ( const entry of entries ) {
0 commit comments