From 9613a97f4a0168e59992fbf27c6e646a3ba21734 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 13 Apr 2026 17:30:48 -0400 Subject: [PATCH] docs(dlx): add @example blocks to dlx module exports --- src/dlx/binary.ts | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/dlx/cache.ts | 6 ++++ src/dlx/detect.ts | 33 ++++++++++++++++++ src/dlx/dir.ts | 34 ++++++++++++++++++ src/dlx/manifest.ts | 16 +++++++++ src/dlx/package.ts | 43 +++++++++++++++++++++++ src/dlx/packages.ts | 36 +++++++++++++++++++ src/dlx/paths.ts | 20 +++++++++++ 8 files changed, 272 insertions(+) diff --git a/src/dlx/binary.ts b/src/dlx/binary.ts index 58a99b83..cd84a6e0 100644 --- a/src/dlx/binary.ts +++ b/src/dlx/binary.ts @@ -191,6 +191,15 @@ export interface DlxMetadata { /** * Clean expired entries from the DLX cache. + * + * @example + * ```typescript + * // Remove cache entries older than the default TTL + * const removed = await cleanDlxCache() + * + * // Remove entries older than 1 hour + * const removed2 = await cleanDlxCache(60 * 60 * 1000) + * ``` */ export async function cleanDlxCache( maxAge: number = DLX_BINARY_CACHE_TTL, @@ -260,6 +269,15 @@ export async function cleanDlxCache( /** * Download and execute a binary from a URL with caching. + * + * @example + * ```typescript + * const result = await dlxBinary(['--version'], { + * url: 'https://example.com/tool-linux-x64', + * name: 'tool', + * }) + * await result.spawnPromise + * ``` */ export async function dlxBinary( args: readonly string[] | string[], @@ -417,6 +435,15 @@ export async function dlxBinary( * Similar to downloadPackage from dlx-package. * * @returns Object containing the path to the cached binary and whether it was downloaded + * + * @example + * ```typescript + * const { binaryPath, downloaded } = await downloadBinary({ + * url: 'https://example.com/tool-linux-x64', + * name: 'tool', + * }) + * console.log(`Binary at: ${binaryPath}, fresh: ${downloaded}`) + * ``` */ export async function downloadBinary( options: Omit, @@ -512,6 +539,15 @@ export async function downloadBinary( * - integrity: SRI format sha512- (verified post-download) * * The sha256 option is preferred as it fails early during download if the checksum doesn't match. + * + * @example + * ```typescript + * const integrity = await downloadBinaryFile( + * 'https://example.com/tool-linux-x64', + * '/tmp/dlx-cache/tool' + * ) + * console.log(`Integrity: ${integrity}`) + * ``` */ export async function downloadBinaryFile( url: string, @@ -608,6 +644,15 @@ export async function downloadBinaryFile( * @param spawnOptions Spawn options for execution * @param spawnExtra Extra spawn configuration * @returns The spawn promise for the running process + * + * @example + * ```typescript + * const { binaryPath } = await downloadBinary({ + * url: 'https://example.com/tool-linux-x64', + * name: 'tool', + * }) + * const result = executeBinary(binaryPath, ['--help']) + * ``` */ export function executeBinary( binaryPath: string, @@ -647,6 +692,11 @@ export function executeBinary( * Get the DLX binary cache directory path. * Returns normalized path for cross-platform compatibility. * Uses same directory as dlx-package for unified DLX storage. + * + * @example + * ```typescript + * const cachePath = getDlxCachePath() + * ``` */ export function getDlxCachePath(): string { return getSocketDlxDir() @@ -654,6 +704,12 @@ export function getDlxCachePath(): string { /** * Get metadata file path for a cached binary. + * + * @example + * ```typescript + * const metaPath = getBinaryCacheMetadataPath('/tmp/dlx-cache/a1b2c3d4') + * // '/tmp/dlx-cache/a1b2c3d4/.dlx-metadata.json' + * ``` */ export function getBinaryCacheMetadataPath(cacheEntryPath: string): string { return getPath().join(cacheEntryPath, '.dlx-metadata.json') @@ -661,6 +717,15 @@ export function getBinaryCacheMetadataPath(cacheEntryPath: string): string { /** * Check if a cached binary is still valid. + * + * @example + * ```typescript + * const ttl = 7 * 24 * 60 * 60 * 1000 + * const valid = await isBinaryCacheValid('/tmp/dlx-cache/a1b2c3d4', ttl) + * if (!valid) { + * // Re-download the binary + * } + * ``` */ export async function isBinaryCacheValid( cacheEntryPath: string, @@ -696,6 +761,14 @@ export async function isBinaryCacheValid( /** * Get information about cached binaries. + * + * @example + * ```typescript + * const entries = await listDlxCache() + * for (const entry of entries) { + * console.log(`${entry.name}: ${entry.size} bytes`) + * } + * ``` */ export async function listDlxCache(): Promise< Array<{ @@ -773,6 +846,17 @@ export async function listDlxCache(): Promise< * Write metadata for a cached binary. * Uses unified schema shared with C++ decompressor and CLI dlxBinary. * Schema documentation: See DlxMetadata interface in this file (exported). + * + * @example + * ```typescript + * await writeBinaryCacheMetadata( + * '/tmp/dlx-cache/a1b2c3d4', + * 'a1b2c3d4', + * 'https://example.com/tool', + * 'sha512-abc123...', + * 15000000 + * ) + * ``` */ export async function writeBinaryCacheMetadata( cacheEntryPath: string, diff --git a/src/dlx/cache.ts b/src/dlx/cache.ts index c0674f47..d415375c 100644 --- a/src/dlx/cache.ts +++ b/src/dlx/cache.ts @@ -38,6 +38,12 @@ function getCrypto() { * https://github.com/npm/cli/blob/v11.6.2/workspaces/libnpmexec/lib/index.js#L233-L244 * Implementation: packages.map().sort().join('\n') → SHA-512 → slice(0,16) * npx hashes the package spec (name@version), not just name + * + * @example + * ```typescript + * const key = generateCacheKey('prettier@3.0.0') + * // e.g. 'a1b2c3d4e5f67890' + * ``` */ export function generateCacheKey(spec: string): string { const crypto = getCrypto() diff --git a/src/dlx/detect.ts b/src/dlx/detect.ts index 907bfcf7..366d41ef 100644 --- a/src/dlx/detect.ts +++ b/src/dlx/detect.ts @@ -144,6 +144,12 @@ function readPackageJson(packageJsonPath: string): object | null { * * @param filePath - Path within DLX cache (~/.socket/_dlx/) * @returns Detection result + * + * @example + * ```typescript + * const result = detectDlxExecutableType('/tmp/.socket/_dlx/a1b2c3d4/tool') + * console.log(result.type) // 'package' or 'binary' + * ``` */ export function detectDlxExecutableType( filePath: string, @@ -210,6 +216,14 @@ export function detectExecutableType( * * @param filePath - Local filesystem path (not in DLX cache) * @returns Detection result + * + * @example + * ```typescript + * const result = detectLocalExecutableType('/usr/local/bin/tool') + * if (result.type === 'package') { + * console.log('Node.js package at:', result.packageJsonPath) + * } + * ``` */ export function detectLocalExecutableType( filePath: string, @@ -253,6 +267,13 @@ export function detectLocalExecutableType( * * @param filePath - Path to check * @returns True if file has .js, .mjs, or .cjs extension + * + * @example + * ```typescript + * isJsFilePath('index.js') // true + * isJsFilePath('lib.mjs') // true + * isJsFilePath('tool.exe') // false + * ``` */ export function isJsFilePath(filePath: string): boolean { const path = getPath() @@ -265,6 +286,12 @@ export function isJsFilePath(filePath: string): boolean { * * @param filePath - Path to check * @returns True if detected as native binary (not Node.js package) + * + * @example + * ```typescript + * isNativeBinary('/usr/local/bin/tool') // true + * isNativeBinary('/tmp/project/index.js') // false + * ``` */ export function isNativeBinary(filePath: string): boolean { return detectExecutableType(filePath).type === 'binary' @@ -275,6 +302,12 @@ export function isNativeBinary(filePath: string): boolean { * * @param filePath - Path to check * @returns True if detected as Node.js package + * + * @example + * ```typescript + * isNodePackage('/tmp/project/index.js') // true + * isNodePackage('/usr/local/bin/tool') // false + * ``` */ export function isNodePackage(filePath: string): boolean { return detectExecutableType(filePath).type === 'package' diff --git a/src/dlx/dir.ts b/src/dlx/dir.ts index b3c30088..7bac1ca7 100644 --- a/src/dlx/dir.ts +++ b/src/dlx/dir.ts @@ -30,6 +30,11 @@ function getFs() { /** * Clear all DLX package installations. + * + * @example + * ```typescript + * await clearDlx() + * ``` */ export async function clearDlx(): Promise { const packages = await listDlxPackagesAsync() @@ -38,6 +43,11 @@ export async function clearDlx(): Promise { /** * Clear all DLX package installations synchronously. + * + * @example + * ```typescript + * clearDlxSync() + * ``` */ export function clearDlxSync(): void { const packages = listDlxPackages() @@ -48,6 +58,13 @@ export function clearDlxSync(): void { /** * Check if the DLX directory exists. + * + * @example + * ```typescript + * if (dlxDirExists()) { + * console.log('DLX directory is present') + * } + * ``` */ export function dlxDirExists(): boolean { const fs = getFs() @@ -56,6 +73,13 @@ export function dlxDirExists(): boolean { /** * Check if the DLX directory exists asynchronously. + * + * @example + * ```typescript + * if (await dlxDirExistsAsync()) { + * console.log('DLX directory is present') + * } + * ``` */ export async function dlxDirExistsAsync(): Promise { const fs = getFs() @@ -69,6 +93,11 @@ export async function dlxDirExistsAsync(): Promise { /** * Ensure the DLX directory exists, creating it if necessary. + * + * @example + * ```typescript + * await ensureDlxDir() + * ``` */ export async function ensureDlxDir(): Promise { await safeMkdir(getSocketDlxDir()) @@ -76,6 +105,11 @@ export async function ensureDlxDir(): Promise { /** * Ensure the DLX directory exists synchronously, creating it if necessary. + * + * @example + * ```typescript + * ensureDlxDirSync() + * ``` */ export function ensureDlxDirSync(): void { safeMkdirSync(getSocketDlxDir()) diff --git a/src/dlx/manifest.ts b/src/dlx/manifest.ts index 70149890..5b8f620a 100644 --- a/src/dlx/manifest.ts +++ b/src/dlx/manifest.ts @@ -124,6 +124,14 @@ export interface DlxManifestOptions { /** * Type guard for binary entries. + * + * @example + * ```typescript + * const entry = manifest.getManifestEntry('https://example.com/tool') + * if (entry && isBinaryEntry(entry)) { + * console.log(entry.details.integrity) + * } + * ``` */ export function isBinaryEntry( entry: ManifestEntry, @@ -133,6 +141,14 @@ export function isBinaryEntry( /** * Type guard for package entries. + * + * @example + * ```typescript + * const entry = manifest.getManifestEntry('@socketsecurity/cli@^2.0.0') + * if (entry && isPackageEntry(entry)) { + * console.log(entry.details.installed_version) + * } + * ``` */ export function isPackageEntry( entry: ManifestEntry, diff --git a/src/dlx/package.ts b/src/dlx/package.ts index 17a7a575..37e170bf 100644 --- a/src/dlx/package.ts +++ b/src/dlx/package.ts @@ -265,6 +265,16 @@ export async function downloadPackage( * Install package to ~/.socket/_dlx// if not already installed. * Uses pacote for installation (no npm CLI required). * Protected by process lock to prevent concurrent installation corruption. + * + * @example + * ```typescript + * const { installed, packageDir } = await ensurePackageInstalled( + * 'prettier', + * 'prettier@3.0.0', + * false + * ) + * console.log(`Installed: ${installed}, dir: ${packageDir}`) + * ``` */ export async function ensurePackageInstalled( packageName: string, @@ -439,6 +449,15 @@ export function executePackage( * 2. Fall back to user-provided binaryName if npm's strategy fails * 3. Try last segment of package name as final fallback * 4. Use first binary as last resort + * + * @example + * ```typescript + * const binPath = findBinaryPath( + * '/tmp/.socket/_dlx/a1b2c3d4', + * 'prettier' + * ) + * console.log(`Binary: ${binPath}`) + * ``` */ export function findBinaryPath( packageDir: string, @@ -532,6 +551,14 @@ export function findBinaryPath( * References: * - npm cmd-shim: https://github.com/npm/cmd-shim/blob/main/lib/index.js * - npm getBinFromManifest: https://github.com/npm/libnpmexec/blob/main/lib/get-bin-from-manifest.js + * + * @example + * ```typescript + * makePackageBinsExecutable( + * '/tmp/.socket/_dlx/a1b2c3d4', + * 'prettier' + * ) + * ``` */ export function makePackageBinsExecutable( packageDir: string, @@ -591,6 +618,15 @@ export function makePackageBinsExecutable( * - 'lodash@4.17.21' → { name: 'lodash', version: '4.17.21' } * - '@scope/pkg@1.0.0' → { name: '@scope/pkg', version: '1.0.0' } * - 'lodash' → { name: 'lodash', version: undefined } + * + * @example + * ```typescript + * parsePackageSpec('lodash@4.17.21') + * // { name: 'lodash', version: '4.17.21' } + * + * parsePackageSpec('@scope/pkg') + * // { name: '@scope/pkg', version: undefined } + * ``` */ export function parsePackageSpec(spec: string): { name: string @@ -638,6 +674,13 @@ const binaryPathCache = new Map() * On Unix, uses path directly. * * Aligns with npm/npx binary resolution strategy. + * + * @example + * ```typescript + * const resolved = resolveBinaryPath('/tmp/.socket/_dlx/a1b2c3d4/prettier') + * // On Windows: may resolve to '.cmd' or '.ps1' wrapper + * // On Unix: returns the path unchanged + * ``` */ export function resolveBinaryPath(basePath: string): string { if (!WIN32) { diff --git a/src/dlx/packages.ts b/src/dlx/packages.ts index 0162d6d0..3ad60182 100644 --- a/src/dlx/packages.ts +++ b/src/dlx/packages.ts @@ -24,6 +24,13 @@ function getFs() { /** * Check if a package is installed in DLX. + * + * @example + * ```typescript + * if (isDlxPackageInstalled('prettier')) { + * console.log('prettier is installed') + * } + * ``` */ export function isDlxPackageInstalled(packageName: string): boolean { const fs = getFs() @@ -32,6 +39,13 @@ export function isDlxPackageInstalled(packageName: string): boolean { /** * Check if a package is installed in DLX asynchronously. + * + * @example + * ```typescript + * if (await isDlxPackageInstalledAsync('prettier')) { + * console.log('prettier is installed') + * } + * ``` */ export async function isDlxPackageInstalledAsync( packageName: string, @@ -47,6 +61,12 @@ export async function isDlxPackageInstalledAsync( /** * List all packages installed in DLX. + * + * @example + * ```typescript + * const packages = listDlxPackages() + * console.log('Installed:', packages.join(', ')) + * ``` */ export function listDlxPackages(): string[] { try { @@ -58,6 +78,12 @@ export function listDlxPackages(): string[] { /** * List all packages installed in DLX asynchronously. + * + * @example + * ```typescript + * const packages = await listDlxPackagesAsync() + * console.log('Installed:', packages.join(', ')) + * ``` */ export async function listDlxPackagesAsync(): Promise { const fs = getFs() @@ -76,6 +102,11 @@ export async function listDlxPackagesAsync(): Promise { /** * Remove a DLX package installation. + * + * @example + * ```typescript + * await removeDlxPackage('prettier') + * ``` */ export async function removeDlxPackage(packageName: string): Promise { const packageDir = getDlxPackageDir(packageName) @@ -90,6 +121,11 @@ export async function removeDlxPackage(packageName: string): Promise { /** * Remove a DLX package installation synchronously. + * + * @example + * ```typescript + * removeDlxPackageSync('prettier') + * ``` */ export function removeDlxPackageSync(packageName: string): void { const fs = getFs() diff --git a/src/dlx/paths.ts b/src/dlx/paths.ts index a08f4791..f783f947 100644 --- a/src/dlx/paths.ts +++ b/src/dlx/paths.ts @@ -20,6 +20,11 @@ function getPath() { /** * Get the installed package directory within DLX node_modules. + * + * @example + * ```typescript + * const dir = getDlxInstalledPackageDir('prettier') + * ``` */ export function getDlxInstalledPackageDir(packageName: string): string { const path = getPath() @@ -30,6 +35,11 @@ export function getDlxInstalledPackageDir(packageName: string): string { /** * Get the DLX installation directory for a specific package. + * + * @example + * ```typescript + * const dir = getDlxPackageDir('a1b2c3d4') + * ``` */ export function getDlxPackageDir(packageName: string): string { const path = getPath() @@ -38,6 +48,11 @@ export function getDlxPackageDir(packageName: string): string { /** * Get the package.json path for a DLX installed package. + * + * @example + * ```typescript + * const jsonPath = getDlxPackageJsonPath('prettier') + * ``` */ export function getDlxPackageJsonPath(packageName: string): string { const path = getPath() @@ -48,6 +63,11 @@ export function getDlxPackageJsonPath(packageName: string): string { /** * Get the node_modules directory for a DLX package installation. + * + * @example + * ```typescript + * const nmDir = getDlxPackageNodeModulesDir('a1b2c3d4') + * ``` */ export function getDlxPackageNodeModulesDir(packageName: string): string { const path = getPath()