@socketsecurity/lib 2.8.4 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/dist/bin.js +9 -1
- package/dist/bin.js.map +2 -2
- package/dist/constants/socket.d.ts +8 -0
- package/dist/constants/socket.js +1 -1
- package/dist/constants/socket.js.map +3 -3
- package/dist/dlx-binary.js +7 -1
- package/dist/dlx-binary.js.map +3 -3
- package/dist/dlx-package.d.ts +19 -0
- package/dist/dlx-package.js +8 -1
- package/dist/dlx-package.js.map +3 -3
- package/dist/dlx.js +11 -1
- package/dist/dlx.js.map +3 -3
- package/dist/download-lock.js +8 -1
- package/dist/download-lock.js.map +3 -3
- package/dist/fs.js +7 -3
- package/dist/fs.js.map +3 -3
- package/dist/git.js +2 -2
- package/dist/git.js.map +3 -3
- package/dist/http-request.js +3 -1
- package/dist/http-request.js.map +3 -3
- package/dist/process-lock.js +12 -1
- package/dist/process-lock.js.map +3 -3
- package/package.json +1 -1
package/dist/dlx-package.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var v=Object.create;var
|
|
2
|
+
var v=Object.create;var h=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var N=(e,n)=>{for(var t in n)h(e,t,{get:n[t],enumerable:!0})},w=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of C(n))!_.call(e,r)&&r!==t&&h(e,r,{get:()=>n[r],enumerable:!(i=$(n,r))||i.enumerable});return e};var y=(e,n,t)=>(t=e!=null?v(I(e)):{},w(n||!e||!e.__esModule?h(t,"default",{value:e,enumerable:!0}):t,e)),T=e=>w(h({},"__esModule",{value:!0}),e);var V={};N(V,{dlxPackage:()=>M,downloadPackage:()=>j,executePackage:()=>S});module.exports=T(V);var d=require("node:fs"),p=y(require("node:path")),k=require("./constants/platform"),P=require("./constants/packages"),E=require("./dlx"),x=y(require("./external/pacote")),b=require("./fs"),u=require("./path"),D=require("./paths"),O=require("./process-lock"),R=require("./spawn");const A=/[~^><=xX* ]|\|\|/;function J(e){if(e.startsWith("@")){const t=e.split("@");return t.length===3?{name:t[1],version:t[2]}:t.length===2?{name:`@${t[1]}`,version:void 0}:{name:`@${t[1]}`,version:t[2]}}const n=e.lastIndexOf("@");return n===-1?{name:e,version:void 0}:{name:e.slice(0,n),version:e.slice(n+1)}}async function F(e,n,t){const i=(0,E.generateCacheKey)(n),r=(0,u.normalizePath)(p.default.join((0,D.getSocketDlxDir)(),i)),c=(0,u.normalizePath)(p.default.join(r,"node_modules",e));try{await d.promises.mkdir(r,{recursive:!0})}catch(a){const o=a.code;throw o==="EACCES"||o==="EPERM"?new Error(`Permission denied creating package directory: ${r}
|
|
3
|
+
Please check directory permissions or run with appropriate access.`,{cause:a}):o==="EROFS"?new Error(`Cannot create package directory on read-only filesystem: ${r}
|
|
4
|
+
Ensure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.`,{cause:a}):new Error(`Failed to create package directory: ${r}`,{cause:a})}const l=p.default.join(r,"concurrency.lock");return await O.processLock.withLock(l,async()=>{if(!t&&(0,d.existsSync)(c)){const o=p.default.join(c,"package.json");if((0,d.existsSync)(o))return{installed:!1,packageDir:r}}const a=(0,P.getPacoteCachePath)();try{await x.default.extract(n,c,{cache:a||p.default.join(r,".cache")})}catch(o){const s=o.code;throw s==="E404"||s==="ETARGET"?new Error(`Package not found: ${n}
|
|
5
|
+
Verify the package exists on npm registry and check the version.
|
|
6
|
+
Visit https://www.npmjs.com/package/${e} to see available versions.`,{cause:o}):s==="ENOTFOUND"||s==="ETIMEDOUT"||s==="EAI_AGAIN"?new Error(`Network error installing ${n}
|
|
7
|
+
Check your internet connection and try again.`,{cause:o}):new Error(`Failed to install package: ${n}
|
|
8
|
+
Destination: ${c}
|
|
9
|
+
Check npm registry connectivity or package name.`,{cause:o})}return{installed:!0,packageDir:r}},{staleMs:5e3,touchIntervalMs:2e3})}function K(e,n,t){const i=(0,u.normalizePath)(p.default.join(e,"node_modules",n)),r=p.default.join(i,"package.json"),l=(0,b.readJsonSync)(r).bin;let a;if(typeof l=="string")a=l;else if(typeof l=="object"&&l!==null){const o=l,s=Object.keys(o);if(s.length===1)a=o[s[0]];else{const m=n.split("/").pop(),g=[t,m,n.replace(/^@[^/]+\//,"")].filter(Boolean);for(const f of g)if(f&&o[f]){a=o[f];break}!a&&s.length>0&&(a=o[s[0]])}}if(!a)throw new Error(`No binary found for package "${n}"`);return(0,u.normalizePath)(p.default.join(i,a))}async function M(e,n,t){const i=await j(n),r=S(i.binaryPath,e,n?.spawnOptions,t);return{...i,spawnPromise:r}}async function j(e){const{binaryName:n,force:t,package:i}={__proto__:null,...e},{name:r,version:c}=J(i),l=c!==void 0&&A.test(c),a=t!==void 0?t:l,o=c?`${r}@${c}`:r,{installed:s,packageDir:m}=await F(r,o,a),g=K(m,r,n);if(!k.WIN32&&(0,d.existsSync)(g)){const{chmodSync:f}=require("node:fs");try{f(g,493)}catch{}}return{binaryPath:g,installed:s,packageDir:m}}function S(e,n,t,i){return(0,R.spawn)(e,n,t,i)}0&&(module.exports={dlxPackage,downloadPackage,executePackage});
|
|
3
10
|
//# sourceMappingURL=dlx-package.js.map
|
package/dist/dlx-package.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/dlx-package.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview DLX package execution - Install and execute npm packages.\n *\n * This module provides functionality to install and execute npm packages\n * in the ~/.socket/_dlx directory, similar to npx but with Socket's own cache.\n *\n * Uses content-addressed storage like npm's _npx:\n * - Hash is generated from package spec (name@version)\n * - Each unique spec gets its own directory: ~/.socket/_dlx/<hash>/\n * - Allows caching multiple versions of the same package\n *\n * Concurrency protection:\n * - Uses process-lock to prevent concurrent installation corruption\n * - Lock file created at ~/.socket/_dlx/<hash>/.lock\n * - Aligned with npm npx's concurrency.lock strategy (5s stale, 2s touching)\n * - Prevents multiple processes from corrupting the same package installation\n *\n * Version range handling:\n * - Exact versions (1.0.0) use cache if available\n * - Range versions (^1.0.0, ~1.0.0) auto-force to get latest within range\n * - User can override with explicit force: false\n *\n * Key difference from dlx-binary.ts:\n * - dlx-binary.ts: Downloads standalone binaries from URLs\n * - dlx-package.ts: Installs npm packages from registries\n *\n * Implementation:\n * - Uses pacote for package installation (no npm CLI required)\n * - Split into downloadPackage() and executePackage() for flexibility\n * - dlxPackage() combines both for convenience\n */\n\nimport { existsSync, promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nimport { WIN32 } from './constants/platform'\nimport { getPacoteCachePath } from './constants/packages'\nimport { generateCacheKey } from './dlx'\nimport pacote from './external/pacote'\nimport { readJsonSync } from './fs'\nimport { normalizePath } from './path'\nimport { getSocketDlxDir } from './paths'\nimport { processLock } from './process-lock'\nimport type { SpawnExtra, SpawnOptions } from './spawn'\nimport { spawn } from './spawn'\n\n/**\n * Regex to check if a version string contains range operators.\n * Matches any version with range operators: ~, ^, >, <, =, x, X, *, spaces, or ||.\n */\nconst rangeOperatorsRegExp = /[~^><=xX* ]|\\|\\|/\n\nexport interface DownloadPackageResult {\n /** Path to the installed package directory. */\n packageDir: string\n /** Path to the binary. */\n binaryPath: string\n /** Whether the package was newly installed. */\n installed: boolean\n}\n\nexport interface DlxPackageOptions {\n /**\n * Package to install (e.g., '@cyclonedx/cdxgen@10.0.0').\n */\n package: string\n /**\n * Force reinstallation even if package exists.\n */\n force?: boolean | undefined\n /**\n * Additional spawn options for the execution.\n */\n spawnOptions?: SpawnOptions | undefined\n}\n\nexport interface DlxPackageResult {\n /** Path to the installed package directory. */\n packageDir: string\n /** Path to the binary that was executed. */\n binaryPath: string\n /** Whether the package was newly installed. */\n installed: boolean\n /** The spawn promise for the running process. */\n spawnPromise: ReturnType<typeof spawn>\n}\n\n/**\n * Parse package spec into name and version.\n * Examples:\n * - 'lodash@4.17.21' \u2192 { name: 'lodash', version: '4.17.21' }\n * - '@scope/pkg@1.0.0' \u2192 { name: '@scope/pkg', version: '1.0.0' }\n * - 'lodash' \u2192 { name: 'lodash', version: undefined }\n */\nfunction parsePackageSpec(spec: string): {\n name: string\n version: string | undefined\n} {\n // Handle scoped packages (@scope/name@version).\n if (spec.startsWith('@')) {\n const parts = spec.split('@')\n if (parts.length === 3) {\n // @scope@version -> Invalid, but handle gracefully.\n return { name: parts[1], version: parts[2] }\n }\n if (parts.length === 2) {\n // @scope/name with no version.\n return { name: `@${parts[1]}`, version: undefined }\n }\n // @scope/name@version.\n const scopeAndName = `@${parts[1]}`\n return { name: scopeAndName, version: parts[2] }\n }\n\n // Handle unscoped packages (name@version).\n const atIndex = spec.lastIndexOf('@')\n if (atIndex === -1) {\n return { name: spec, version: undefined }\n }\n\n return {\n name: spec.slice(0, atIndex),\n version: spec.slice(atIndex + 1),\n }\n}\n\n/**\n * Install package to ~/.socket/_dlx/<hash>/ if not already installed.\n * Uses pacote for installation (no npm CLI required).\n * Protected by process lock to prevent concurrent installation corruption.\n */\nasync function ensurePackageInstalled(\n packageName: string,\n packageSpec: string,\n force: boolean,\n): Promise<{ installed: boolean; packageDir: string }> {\n const cacheKey = generateCacheKey(packageSpec)\n const packageDir = normalizePath(path.join(getSocketDlxDir(), cacheKey))\n const installedDir = normalizePath(\n path.join(packageDir, 'node_modules', packageName),\n )\n\n // Use process lock to prevent concurrent installations.\n // Similar to npm npx's concurrency.lock approach.\n const lockPath = path.join(packageDir, '.lock')\n\n return await processLock.withLock(\n lockPath,\n async () => {\n // Double-check if already installed (unless force).\n // Another process may have installed while waiting for lock.\n if (!force && existsSync(installedDir)) {\n // Verify package.json exists.\n const pkgJsonPath = path.join(installedDir, 'package.json')\n if (existsSync(pkgJsonPath)) {\n return { installed: false, packageDir }\n }\n }\n\n // Ensure package directory exists.\n await fs.mkdir(packageDir, { recursive: true })\n\n // Use pacote to extract the package.\n // Pacote leverages npm cache when available but doesn't require npm CLI.\n const pacoteCachePath = getPacoteCachePath()\n await pacote.extract(packageSpec, installedDir, {\n // Use consistent pacote cache path (respects npm cache locations when available).\n cache: pacoteCachePath || path.join(packageDir, '.cache'),\n })\n\n return { installed: true, packageDir }\n },\n {\n // Align with npm npx locking strategy.\n staleMs: 5000,\n touchIntervalMs: 2000,\n },\n )\n}\n\n/**\n * Find the binary path for an installed package.\n */\nfunction findBinaryPath(\n packageDir: string,\n packageName: string,\n binaryName?: string,\n): string {\n const installedDir = normalizePath(\n path.join(packageDir, 'node_modules', packageName),\n )\n const pkgJsonPath = path.join(installedDir, 'package.json')\n\n // Read package.json to find bin entry.\n const pkgJson = readJsonSync(pkgJsonPath) as Record<string, unknown>\n const bin = pkgJson['bin']\n\n let binPath: string | undefined\n\n if (typeof bin === 'string') {\n // Single binary.\n binPath = bin\n } else if (typeof bin === 'object' && bin !== null) {\n // Multiple binaries - use binaryName or package name.\n const binName = binaryName || packageName.split('/').pop()\n binPath = (bin as Record<string, string>)[binName!]\n }\n\n if (!binPath) {\n throw new Error(`No binary found for package \"${packageName}\"`)\n }\n\n return normalizePath(path.join(installedDir, binPath))\n}\n\n/**\n * Execute a package via DLX - install if needed and run its binary.\n *\n * This is the Socket equivalent of npx/pnpm dlx/yarn dlx, but using\n * our own cache directory (~/.socket/_dlx) and installation logic.\n *\n * Auto-forces reinstall for version ranges to get latest within range.\n *\n * @example\n * ```typescript\n * // Download and execute cdxgen\n * const result = await dlxPackage(\n * ['--version'],\n * { package: '@cyclonedx/cdxgen@10.0.0' }\n * )\n * await result.spawnPromise\n * ```\n */\nexport async function dlxPackage(\n args: readonly string[] | string[],\n options?: DlxPackageOptions | undefined,\n spawnExtra?: SpawnExtra | undefined,\n): Promise<DlxPackageResult> {\n // Download the package.\n const downloadResult = await downloadPackage(options!)\n\n // Execute the binary.\n const spawnPromise = executePackage(\n downloadResult.binaryPath,\n args,\n options?.spawnOptions,\n spawnExtra,\n )\n\n return {\n ...downloadResult,\n spawnPromise,\n }\n}\n\n/**\n * Download and install a package without executing it.\n * This is useful for self-update or when you need the package files\n * but don't want to run the binary immediately.\n *\n * @example\n * ```typescript\n * // Install @socketsecurity/cli without running it\n * const result = await downloadPackage({\n * package: '@socketsecurity/cli@1.2.0',\n * force: true\n * })\n * console.log('Installed to:', result.packageDir)\n * console.log('Binary at:', result.binaryPath)\n * ```\n */\nexport async function downloadPackage(\n options: DlxPackageOptions,\n): Promise<DownloadPackageResult> {\n const { force: userForce, package: packageSpec } = {\n __proto__: null,\n ...options,\n } as DlxPackageOptions\n\n // Parse package spec.\n const { name: packageName, version: packageVersion } =\n parsePackageSpec(packageSpec)\n\n // Auto-force for version ranges to get latest within range.\n // User can still override with explicit force: false if they want cache.\n const isVersionRange =\n packageVersion !== undefined && rangeOperatorsRegExp.test(packageVersion)\n const force = userForce !== undefined ? userForce : isVersionRange\n\n // Build full package spec for installation.\n const fullPackageSpec = packageVersion\n ? `${packageName}@${packageVersion}`\n : packageName\n\n // Ensure package is installed.\n const { installed, packageDir } = await ensurePackageInstalled(\n packageName,\n fullPackageSpec,\n force,\n )\n\n // Find binary path.\n const binaryPath = findBinaryPath(packageDir, packageName)\n\n // Make binary executable on Unix systems.\n if (!WIN32 && existsSync(binaryPath)) {\n const { chmodSync } = require('node:fs')\n try {\n chmodSync(binaryPath, 0o755)\n } catch {\n // Ignore chmod errors.\n }\n }\n\n return {\n binaryPath,\n installed,\n packageDir,\n }\n}\n\n/**\n * Execute a package's binary.\n * The package must already be installed (use downloadPackage first).\n *\n * @example\n * ```typescript\n * // Execute an already-installed package\n * const downloaded = await downloadPackage({ package: 'cowsay@1.5.0' })\n * const result = await executePackage(\n * downloaded.binaryPath,\n * ['Hello World'],\n * { stdio: 'inherit' }\n * )\n * ```\n */\nexport function executePackage(\n binaryPath: string,\n args: readonly string[] | string[],\n spawnOptions?: SpawnOptions | undefined,\n spawnExtra?: SpawnExtra | undefined,\n): ReturnType<typeof spawn> {\n return spawn(binaryPath, args, spawnOptions, spawnExtra)\n}\n"],
|
|
5
|
-
"mappings": ";6iBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,EAAA,oBAAAC,EAAA,mBAAAC,IAAA,eAAAC,EAAAL,GAgCA,IAAAM,EAA2C,mBAC3CC,EAAiB,wBAEjBC,EAAsB,gCACtBC,EAAmC,gCACnCC,EAAiC,iBACjCC,EAAmB,gCACnBC,EAA6B,gBAC7BC,EAA8B,kBAC9BC,EAAgC,mBAChCC,EAA4B,0BAE5BC,EAAsB,mBAMtB,MAAMC,EAAuB,
|
|
6
|
-
"names": ["dlx_package_exports", "__export", "dlxPackage", "downloadPackage", "executePackage", "__toCommonJS", "import_node_fs", "import_node_path", "import_platform", "import_packages", "import_dlx", "import_pacote", "import_fs", "import_path", "import_paths", "import_process_lock", "import_spawn", "rangeOperatorsRegExp", "parsePackageSpec", "spec", "parts", "atIndex", "ensurePackageInstalled", "packageName", "packageSpec", "force", "cacheKey", "packageDir", "path", "installedDir", "
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview DLX package execution - Install and execute npm packages.\n *\n * This module provides functionality to install and execute npm packages\n * in the ~/.socket/_dlx directory, similar to npx but with Socket's own cache.\n *\n * Uses content-addressed storage like npm's _npx:\n * - Hash is generated from package spec (name@version)\n * - Each unique spec gets its own directory: ~/.socket/_dlx/<hash>/\n * - Allows caching multiple versions of the same package\n *\n * Concurrency protection:\n * - Uses process-lock to prevent concurrent installation corruption\n * - Lock file created at ~/.socket/_dlx/<hash>/concurrency.lock\n * - Uses npm npx's concurrency.lock naming convention (5s stale, 2s touching)\n * - Prevents multiple processes from corrupting the same package installation\n *\n * Version range handling:\n * - Exact versions (1.0.0) use cache if available\n * - Range versions (^1.0.0, ~1.0.0) auto-force to get latest within range\n * - User can override with explicit force: false\n *\n * Key difference from dlx-binary.ts:\n * - dlx-binary.ts: Downloads standalone binaries from URLs\n * - dlx-package.ts: Installs npm packages from registries\n *\n * Implementation:\n * - Uses pacote for package installation (no npm CLI required)\n * - Split into downloadPackage() and executePackage() for flexibility\n * - dlxPackage() combines both for convenience\n */\n\nimport { existsSync, promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nimport { WIN32 } from './constants/platform'\nimport { getPacoteCachePath } from './constants/packages'\nimport { generateCacheKey } from './dlx'\nimport pacote from './external/pacote'\nimport { readJsonSync } from './fs'\nimport { normalizePath } from './path'\nimport { getSocketDlxDir } from './paths'\nimport { processLock } from './process-lock'\nimport type { SpawnExtra, SpawnOptions } from './spawn'\nimport { spawn } from './spawn'\n\n/**\n * Regex to check if a version string contains range operators.\n * Matches any version with range operators: ~, ^, >, <, =, x, X, *, spaces, or ||.\n */\nconst rangeOperatorsRegExp = /[~^><=xX* ]|\\|\\|/\n\nexport interface DownloadPackageResult {\n /** Path to the installed package directory. */\n packageDir: string\n /** Path to the binary. */\n binaryPath: string\n /** Whether the package was newly installed. */\n installed: boolean\n}\n\nexport interface DlxPackageOptions {\n /**\n * Package to install (e.g., '@cyclonedx/cdxgen@10.0.0').\n */\n package: string\n /**\n * Binary name to execute (optional - auto-detected in most cases).\n *\n * Auto-detection logic:\n * 1. If package has only one binary, uses it automatically\n * 2. Tries user-provided binaryName\n * 3. Tries last segment of package name (e.g., 'cli' from '@socketsecurity/cli')\n * 4. Falls back to first binary\n *\n * Only needed when package has multiple binaries and auto-detection fails.\n *\n * @example\n * // Auto-detected (single binary)\n * { package: '@socketsecurity/cli' } // Finds 'socket' binary automatically\n *\n * // Explicit (multiple binaries)\n * { package: 'some-tool', binaryName: 'specific-tool' }\n */\n binaryName?: string | undefined\n /**\n * Force reinstallation even if package exists.\n */\n force?: boolean | undefined\n /**\n * Additional spawn options for the execution.\n */\n spawnOptions?: SpawnOptions | undefined\n}\n\nexport interface DlxPackageResult {\n /** Path to the installed package directory. */\n packageDir: string\n /** Path to the binary that was executed. */\n binaryPath: string\n /** Whether the package was newly installed. */\n installed: boolean\n /** The spawn promise for the running process. */\n spawnPromise: ReturnType<typeof spawn>\n}\n\n/**\n * Parse package spec into name and version.\n * Examples:\n * - 'lodash@4.17.21' \u2192 { name: 'lodash', version: '4.17.21' }\n * - '@scope/pkg@1.0.0' \u2192 { name: '@scope/pkg', version: '1.0.0' }\n * - 'lodash' \u2192 { name: 'lodash', version: undefined }\n */\nfunction parsePackageSpec(spec: string): {\n name: string\n version: string | undefined\n} {\n // Handle scoped packages (@scope/name@version).\n if (spec.startsWith('@')) {\n const parts = spec.split('@')\n if (parts.length === 3) {\n // @scope@version -> Invalid, but handle gracefully.\n return { name: parts[1], version: parts[2] }\n }\n if (parts.length === 2) {\n // @scope/name with no version.\n return { name: `@${parts[1]}`, version: undefined }\n }\n // @scope/name@version.\n const scopeAndName = `@${parts[1]}`\n return { name: scopeAndName, version: parts[2] }\n }\n\n // Handle unscoped packages (name@version).\n const atIndex = spec.lastIndexOf('@')\n if (atIndex === -1) {\n return { name: spec, version: undefined }\n }\n\n return {\n name: spec.slice(0, atIndex),\n version: spec.slice(atIndex + 1),\n }\n}\n\n/**\n * Install package to ~/.socket/_dlx/<hash>/ if not already installed.\n * Uses pacote for installation (no npm CLI required).\n * Protected by process lock to prevent concurrent installation corruption.\n */\nasync function ensurePackageInstalled(\n packageName: string,\n packageSpec: string,\n force: boolean,\n): Promise<{ installed: boolean; packageDir: string }> {\n const cacheKey = generateCacheKey(packageSpec)\n const packageDir = normalizePath(path.join(getSocketDlxDir(), cacheKey))\n const installedDir = normalizePath(\n path.join(packageDir, 'node_modules', packageName),\n )\n\n // Ensure package directory exists before creating lock.\n // The lock directory will be created inside this directory.\n try {\n await fs.mkdir(packageDir, { recursive: true })\n } catch (e) {\n const code = (e as NodeJS.ErrnoException).code\n if (code === 'EACCES' || code === 'EPERM') {\n throw new Error(\n `Permission denied creating package directory: ${packageDir}\\n` +\n 'Please check directory permissions or run with appropriate access.',\n { cause: e },\n )\n }\n if (code === 'EROFS') {\n throw new Error(\n `Cannot create package directory on read-only filesystem: ${packageDir}\\n` +\n 'Ensure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.',\n { cause: e },\n )\n }\n throw new Error(`Failed to create package directory: ${packageDir}`, {\n cause: e,\n })\n }\n\n // Use process lock to prevent concurrent installations.\n // Uses npm npx's concurrency.lock naming convention.\n const lockPath = path.join(packageDir, 'concurrency.lock')\n\n return await processLock.withLock(\n lockPath,\n async () => {\n // Double-check if already installed (unless force).\n // Another process may have installed while waiting for lock.\n if (!force && existsSync(installedDir)) {\n // Verify package.json exists.\n const pkgJsonPath = path.join(installedDir, 'package.json')\n if (existsSync(pkgJsonPath)) {\n return { installed: false, packageDir }\n }\n }\n\n // Use pacote to extract the package.\n // Pacote leverages npm cache when available but doesn't require npm CLI.\n const pacoteCachePath = getPacoteCachePath()\n try {\n await pacote.extract(packageSpec, installedDir, {\n // Use consistent pacote cache path (respects npm cache locations when available).\n cache: pacoteCachePath || path.join(packageDir, '.cache'),\n })\n } catch (e) {\n const code = (e as any).code\n if (code === 'E404' || code === 'ETARGET') {\n throw new Error(\n `Package not found: ${packageSpec}\\n` +\n 'Verify the package exists on npm registry and check the version.\\n' +\n `Visit https://www.npmjs.com/package/${packageName} to see available versions.`,\n { cause: e },\n )\n }\n if (\n code === 'ENOTFOUND' ||\n code === 'ETIMEDOUT' ||\n code === 'EAI_AGAIN'\n ) {\n throw new Error(\n `Network error installing ${packageSpec}\\n` +\n 'Check your internet connection and try again.',\n { cause: e },\n )\n }\n throw new Error(\n `Failed to install package: ${packageSpec}\\n` +\n `Destination: ${installedDir}\\n` +\n 'Check npm registry connectivity or package name.',\n { cause: e },\n )\n }\n\n return { installed: true, packageDir }\n },\n {\n // Align with npm npx locking strategy.\n staleMs: 5000,\n touchIntervalMs: 2000,\n },\n )\n}\n\n/**\n * Find the binary path for an installed package.\n * Intelligently handles packages with single or multiple binaries.\n */\nfunction findBinaryPath(\n packageDir: string,\n packageName: string,\n binaryName?: string,\n): string {\n const installedDir = normalizePath(\n path.join(packageDir, 'node_modules', packageName),\n )\n const pkgJsonPath = path.join(installedDir, 'package.json')\n\n // Read package.json to find bin entry.\n const pkgJson = readJsonSync(pkgJsonPath) as Record<string, unknown>\n const bin = pkgJson['bin']\n\n let binPath: string | undefined\n\n if (typeof bin === 'string') {\n // Single binary - use it directly.\n binPath = bin\n } else if (typeof bin === 'object' && bin !== null) {\n const binObj = bin as Record<string, string>\n const binKeys = Object.keys(binObj)\n\n // If only one binary, use it regardless of name.\n if (binKeys.length === 1) {\n binPath = binObj[binKeys[0]!]\n } else {\n // Multiple binaries - try to find the right one:\n // 1. User-provided binaryName\n // 2. Last segment of package name (e.g., 'cli' from '@socketsecurity/cli')\n // 3. Full package name without scope (e.g., 'cli' from '@socketsecurity/cli')\n // 4. First binary as fallback\n const lastSegment = packageName.split('/').pop()\n const candidates = [\n binaryName,\n lastSegment,\n packageName.replace(/^@[^/]+\\//, ''),\n ].filter(Boolean)\n\n for (const candidate of candidates) {\n if (candidate && binObj[candidate]) {\n binPath = binObj[candidate]\n break\n }\n }\n\n // Fallback to first binary if nothing matched.\n if (!binPath && binKeys.length > 0) {\n binPath = binObj[binKeys[0]!]\n }\n }\n }\n\n if (!binPath) {\n throw new Error(`No binary found for package \"${packageName}\"`)\n }\n\n return normalizePath(path.join(installedDir, binPath))\n}\n\n/**\n * Execute a package via DLX - install if needed and run its binary.\n *\n * This is the Socket equivalent of npx/pnpm dlx/yarn dlx, but using\n * our own cache directory (~/.socket/_dlx) and installation logic.\n *\n * Auto-forces reinstall for version ranges to get latest within range.\n *\n * @example\n * ```typescript\n * // Download and execute cdxgen\n * const result = await dlxPackage(\n * ['--version'],\n * { package: '@cyclonedx/cdxgen@10.0.0' }\n * )\n * await result.spawnPromise\n * ```\n */\nexport async function dlxPackage(\n args: readonly string[] | string[],\n options?: DlxPackageOptions | undefined,\n spawnExtra?: SpawnExtra | undefined,\n): Promise<DlxPackageResult> {\n // Download the package.\n const downloadResult = await downloadPackage(options!)\n\n // Execute the binary.\n const spawnPromise = executePackage(\n downloadResult.binaryPath,\n args,\n options?.spawnOptions,\n spawnExtra,\n )\n\n return {\n ...downloadResult,\n spawnPromise,\n }\n}\n\n/**\n * Download and install a package without executing it.\n * This is useful for self-update or when you need the package files\n * but don't want to run the binary immediately.\n *\n * @example\n * ```typescript\n * // Install @socketsecurity/cli without running it\n * const result = await downloadPackage({\n * package: '@socketsecurity/cli@1.2.0',\n * force: true\n * })\n * console.log('Installed to:', result.packageDir)\n * console.log('Binary at:', result.binaryPath)\n * ```\n */\nexport async function downloadPackage(\n options: DlxPackageOptions,\n): Promise<DownloadPackageResult> {\n const {\n binaryName,\n force: userForce,\n package: packageSpec,\n } = {\n __proto__: null,\n ...options,\n } as DlxPackageOptions\n\n // Parse package spec.\n const { name: packageName, version: packageVersion } =\n parsePackageSpec(packageSpec)\n\n // Auto-force for version ranges to get latest within range.\n // User can still override with explicit force: false if they want cache.\n const isVersionRange =\n packageVersion !== undefined && rangeOperatorsRegExp.test(packageVersion)\n const force = userForce !== undefined ? userForce : isVersionRange\n\n // Build full package spec for installation.\n const fullPackageSpec = packageVersion\n ? `${packageName}@${packageVersion}`\n : packageName\n\n // Ensure package is installed.\n const { installed, packageDir } = await ensurePackageInstalled(\n packageName,\n fullPackageSpec,\n force,\n )\n\n // Find binary path.\n const binaryPath = findBinaryPath(packageDir, packageName, binaryName)\n\n // Make binary executable on Unix systems.\n if (!WIN32 && existsSync(binaryPath)) {\n const { chmodSync } = require('node:fs')\n try {\n chmodSync(binaryPath, 0o755)\n } catch {\n // Ignore chmod errors.\n }\n }\n\n return {\n binaryPath,\n installed,\n packageDir,\n }\n}\n\n/**\n * Execute a package's binary.\n * The package must already be installed (use downloadPackage first).\n *\n * @example\n * ```typescript\n * // Execute an already-installed package\n * const downloaded = await downloadPackage({ package: 'cowsay@1.5.0' })\n * const result = await executePackage(\n * downloaded.binaryPath,\n * ['Hello World'],\n * { stdio: 'inherit' }\n * )\n * ```\n */\nexport function executePackage(\n binaryPath: string,\n args: readonly string[] | string[],\n spawnOptions?: SpawnOptions | undefined,\n spawnExtra?: SpawnExtra | undefined,\n): ReturnType<typeof spawn> {\n return spawn(binaryPath, args, spawnOptions, spawnExtra)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["dlx_package_exports", "__export", "dlxPackage", "downloadPackage", "executePackage", "__toCommonJS", "import_node_fs", "import_node_path", "import_platform", "import_packages", "import_dlx", "import_pacote", "import_fs", "import_path", "import_paths", "import_process_lock", "import_spawn", "rangeOperatorsRegExp", "parsePackageSpec", "spec", "parts", "atIndex", "ensurePackageInstalled", "packageName", "packageSpec", "force", "cacheKey", "packageDir", "path", "installedDir", "fs", "e", "code", "lockPath", "pkgJsonPath", "pacoteCachePath", "pacote", "findBinaryPath", "binaryName", "bin", "binPath", "binObj", "binKeys", "lastSegment", "candidates", "candidate", "args", "options", "spawnExtra", "downloadResult", "spawnPromise", "userForce", "packageVersion", "isVersionRange", "fullPackageSpec", "installed", "binaryPath", "chmodSync", "spawnOptions"]
|
|
7
7
|
}
|
package/dist/dlx.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var
|
|
2
|
+
var f=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var E=(r,e)=>{for(var t in e)f(r,t,{get:e[t],enumerable:!0})},S=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of v(e))!w.call(r,n)&&n!==t&&f(r,n,{get:()=>e[n],enumerable:!(i=k(e,n))||i.enumerable});return r};var b=r=>S(f({},"__esModule",{value:!0}),r);var J={};E(J,{clearDlx:()=>C,clearDlxSync:()=>j,dlxDirExists:()=>A,dlxDirExistsAsync:()=>F,ensureDlxDir:()=>I,ensureDlxDirSync:()=>L,generateCacheKey:()=>$,getDlxInstalledPackageDir:()=>l,getDlxPackageDir:()=>p,getDlxPackageJsonPath:()=>T,getDlxPackageNodeModulesDir:()=>m,isDlxPackageInstalled:()=>q,isDlxPackageInstalledAsync:()=>M,isInSocketDlx:()=>X,listDlxPackages:()=>y,listDlxPackagesAsync:()=>h,removeDlxPackage:()=>D,removeDlxPackageSync:()=>P});module.exports=b(J);var d=require("node:crypto"),s=require("node:fs"),u=require("./fs"),a=require("./path"),o=require("./paths"),x=require("./promises");function $(r){return(0,d.createHash)("sha512").update(r).digest("hex").substring(0,16)}let g;function c(){return g===void 0&&(g=require("node:path")),g}async function C(){const r=await h();await(0,x.pEach)(r,e=>D(e))}function j(){const r=y();for(const e of r)P(e)}function A(){return(0,s.existsSync)((0,o.getSocketDlxDir)())}async function F(){try{return await s.promises.access((0,o.getSocketDlxDir)()),!0}catch{return!1}}async function I(){await s.promises.mkdir((0,o.getSocketDlxDir)(),{recursive:!0})}function L(){const{mkdirSync:r}=require("node:fs");r((0,o.getSocketDlxDir)(),{recursive:!0})}function l(r){return(0,a.normalizePath)(c().join(m(r),r))}function p(r){return(0,a.normalizePath)(c().join((0,o.getSocketDlxDir)(),r))}function T(r){return(0,a.normalizePath)(c().join(l(r),"package.json"))}function m(r){return(0,a.normalizePath)(c().join(p(r),"node_modules"))}function X(r){if(!r)return!1;const e=c(),t=(0,o.getSocketDlxDir)();return e.resolve(r).startsWith(t+e.sep)}function q(r){return(0,s.existsSync)(l(r))}async function M(r){try{return await s.promises.access(l(r)),!0}catch{return!1}}function y(){try{return(0,u.readDirNamesSync)((0,o.getSocketDlxDir)(),{sort:!0})}catch{return[]}}async function h(){try{return(await s.promises.readdir((0,o.getSocketDlxDir)(),{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name).sort()}catch{return[]}}async function D(r){const e=p(r);try{await(0,u.safeDelete)(e,{recursive:!0,force:!0})}catch(t){throw new Error(`Failed to remove DLX package "${r}"`,{cause:t})}}function P(r){const{rmSync:e}=require("node:fs"),t=p(r);try{e(t,{recursive:!0,force:!0})}catch(i){const n=i.code;throw n==="EACCES"||n==="EPERM"?new Error(`Permission denied removing DLX package "${r}"
|
|
3
|
+
Directory: ${t}
|
|
4
|
+
To resolve:
|
|
5
|
+
1. Check file/directory permissions
|
|
6
|
+
2. Close any programs using files in this directory
|
|
7
|
+
3. Try running with elevated privileges if necessary
|
|
8
|
+
4. Manually remove: rm -rf "${t}"`,{cause:i}):n==="EROFS"?new Error(`Cannot remove DLX package "${r}" from read-only filesystem
|
|
9
|
+
Directory: ${t}
|
|
10
|
+
The filesystem is mounted read-only.`,{cause:i}):new Error(`Failed to remove DLX package "${r}"
|
|
11
|
+
Directory: ${t}
|
|
12
|
+
Check permissions and ensure no programs are using this directory.`,{cause:i})}}0&&(module.exports={clearDlx,clearDlxSync,dlxDirExists,dlxDirExistsAsync,ensureDlxDir,ensureDlxDirSync,generateCacheKey,getDlxInstalledPackageDir,getDlxPackageDir,getDlxPackageJsonPath,getDlxPackageNodeModulesDir,isDlxPackageInstalled,isDlxPackageInstalledAsync,isInSocketDlx,listDlxPackages,listDlxPackagesAsync,removeDlxPackage,removeDlxPackageSync});
|
|
3
13
|
//# sourceMappingURL=dlx.js.map
|
package/dist/dlx.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/dlx.ts"],
|
|
4
|
-
"sourcesContent": ["/** @fileoverview DLX (execute package) utilities for Socket ecosystem shared installations. */\n\nimport { createHash } from 'node:crypto'\nimport { existsSync, promises as fs } from 'node:fs'\n\nimport { readDirNamesSync, safeDelete } from './fs'\nimport { normalizePath } from './path'\nimport { getSocketDlxDir } from './paths'\nimport { pEach } from './promises'\n\n/**\n * Generate a cache directory name using npm/npx approach.\n * Uses first 16 characters of SHA-512 hash (like npm/npx).\n *\n * Rationale for SHA-512 truncated (vs full SHA-256):\n * - Matches npm/npx ecosystem behavior\n * - Shorter paths for Windows MAX_PATH compatibility (260 chars)\n * - 16 hex chars = 64 bits = acceptable collision risk for local cache\n * - Collision probability ~1 in 18 quintillion with 1000 entries\n *\n * Input strategy (aligned with npx):\n * - npx uses package spec strings (e.g., '@scope/pkg@1.0.0', 'prettier@3.0.0')\n * - Caller provides complete spec string with version for accurate cache keying\n * - For package installs: Use PURL-style spec with version\n * Examples: 'npm:prettier@3.0.0', 'pypi:requests@2.31.0', 'gem:rails@7.0.0'\n * Note: Socket uses shorthand format without 'pkg:' prefix\n * (handled by @socketregistry/packageurl-js)\n * - For binary downloads: Use URL:name for uniqueness\n *\n * Reference: npm/cli v11.6.2 libnpmexec/lib/index.js#L233-L244\n * https://github.com/npm/cli/blob/v11.6.2/workspaces/libnpmexec/lib/index.js#L233-L244\n * Implementation: packages.map().sort().join('\\n') \u2192 SHA-512 \u2192 slice(0,16)\n * npx hashes the package spec (name@version), not just name\n */\nexport function generateCacheKey(spec: string): string {\n return createHash('sha512').update(spec).digest('hex').substring(0, 16)\n}\n\nlet _path: typeof import('path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path!\n}\n\n/**\n * Clear all DLX package installations.\n */\nexport async function clearDlx(): Promise<void> {\n const packages = await listDlxPackagesAsync()\n await pEach(packages, pkg => removeDlxPackage(pkg))\n}\n\n/**\n * Clear all DLX package installations synchronously.\n */\nexport function clearDlxSync(): void {\n const packages = listDlxPackages()\n for (const pkg of packages) {\n removeDlxPackageSync(pkg)\n }\n}\n\n/**\n * Check if the DLX directory exists.\n */\nexport function dlxDirExists(): boolean {\n return existsSync(getSocketDlxDir())\n}\n\n/**\n * Check if the DLX directory exists asynchronously.\n */\nexport async function dlxDirExistsAsync(): Promise<boolean> {\n try {\n await fs.access(getSocketDlxDir())\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Ensure the DLX directory exists, creating it if necessary.\n */\nexport async function ensureDlxDir(): Promise<void> {\n await fs.mkdir(getSocketDlxDir(), { recursive: true })\n}\n\n/**\n * Ensure the DLX directory exists synchronously, creating it if necessary.\n */\nexport function ensureDlxDirSync(): void {\n const { mkdirSync } = require('node:fs')\n mkdirSync(getSocketDlxDir(), { recursive: true })\n}\n\n/**\n * Get the installed package directory within DLX node_modules.\n */\nexport function getDlxInstalledPackageDir(packageName: string): string {\n const path = getPath()\n return normalizePath(\n path.join(getDlxPackageNodeModulesDir(packageName), packageName),\n )\n}\n\n/**\n * Get the DLX installation directory for a specific package.\n */\nexport function getDlxPackageDir(packageName: string): string {\n const path = getPath()\n return normalizePath(path.join(getSocketDlxDir(), packageName))\n}\n\n/**\n * Get the package.json path for a DLX installed package.\n */\nexport function getDlxPackageJsonPath(packageName: string): string {\n const path = getPath()\n return normalizePath(\n path.join(getDlxInstalledPackageDir(packageName), 'package.json'),\n )\n}\n\n/**\n * Get the node_modules directory for a DLX package installation.\n */\nexport function getDlxPackageNodeModulesDir(packageName: string): string {\n const path = getPath()\n return normalizePath(path.join(getDlxPackageDir(packageName), 'node_modules'))\n}\n\n/**\n * Check if a file path is within the Socket DLX directory.\n * This is useful for determining if a binary or file is managed by Socket's DLX system.\n *\n * @param filePath - Absolute or relative path to check\n * @returns true if the path is within ~/.socket/_dlx/, false otherwise\n *\n * @example\n * ```typescript\n * isInSocketDlx('/home/user/.socket/_dlx/abc123/bin/socket') // true\n * isInSocketDlx('/usr/local/bin/socket') // false\n * isInSocketDlx(process.argv[0]) // Check if current binary is in DLX\n * ```\n */\nexport function isInSocketDlx(filePath: string): boolean {\n if (!filePath) {\n return false\n }\n\n const path = getPath()\n const dlxDir = getSocketDlxDir()\n const absolutePath = path.resolve(filePath)\n\n // Check if the absolute path starts with the DLX directory.\n return absolutePath.startsWith(dlxDir + path.sep)\n}\n\n/**\n * Check if a package is installed in DLX.\n */\nexport function isDlxPackageInstalled(packageName: string): boolean {\n return existsSync(getDlxInstalledPackageDir(packageName))\n}\n\n/**\n * Check if a package is installed in DLX asynchronously.\n */\nexport async function isDlxPackageInstalledAsync(\n packageName: string,\n): Promise<boolean> {\n try {\n await fs.access(getDlxInstalledPackageDir(packageName))\n return true\n } catch {\n return false\n }\n}\n\n/**\n * List all packages installed in DLX.\n */\nexport function listDlxPackages(): string[] {\n try {\n return readDirNamesSync(getSocketDlxDir(), { sort: true })\n } catch {\n return []\n }\n}\n\n/**\n * List all packages installed in DLX asynchronously.\n */\nexport async function listDlxPackagesAsync(): Promise<string[]> {\n try {\n const entries = await fs.readdir(getSocketDlxDir(), {\n withFileTypes: true,\n })\n return entries\n .filter(e => e.isDirectory())\n .map(e => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * Remove a DLX package installation.\n */\nexport async function removeDlxPackage(packageName: string): Promise<void> {\n const packageDir = getDlxPackageDir(packageName)\n try {\n await safeDelete(packageDir, { recursive: true, force: true })\n } catch (e) {\n throw new Error(`Failed to remove DLX package \"${packageName}\"`, {\n cause: e,\n })\n }\n}\n\n/**\n * Remove a DLX package installation synchronously.\n */\nexport function removeDlxPackageSync(packageName: string): void {\n const { rmSync } = require('node:fs')\n const packageDir = getDlxPackageDir(packageName)\n try {\n rmSync(packageDir, { recursive: true, force: true })\n } catch (e) {\n throw new Error(`Failed to remove DLX package \"${packageName}\"
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["dlx_exports", "__export", "clearDlx", "clearDlxSync", "dlxDirExists", "dlxDirExistsAsync", "ensureDlxDir", "ensureDlxDirSync", "generateCacheKey", "getDlxInstalledPackageDir", "getDlxPackageDir", "getDlxPackageJsonPath", "getDlxPackageNodeModulesDir", "isDlxPackageInstalled", "isDlxPackageInstalledAsync", "isInSocketDlx", "listDlxPackages", "listDlxPackagesAsync", "removeDlxPackage", "removeDlxPackageSync", "__toCommonJS", "import_node_crypto", "import_node_fs", "import_fs", "import_path", "import_paths", "import_promises", "spec", "_path", "getPath", "packages", "pkg", "fs", "mkdirSync", "packageName", "filePath", "path", "dlxDir", "
|
|
4
|
+
"sourcesContent": ["/** @fileoverview DLX (execute package) utilities for Socket ecosystem shared installations. */\n\nimport { createHash } from 'node:crypto'\nimport { existsSync, promises as fs } from 'node:fs'\n\nimport { readDirNamesSync, safeDelete } from './fs'\nimport { normalizePath } from './path'\nimport { getSocketDlxDir } from './paths'\nimport { pEach } from './promises'\n\n/**\n * Generate a cache directory name using npm/npx approach.\n * Uses first 16 characters of SHA-512 hash (like npm/npx).\n *\n * Rationale for SHA-512 truncated (vs full SHA-256):\n * - Matches npm/npx ecosystem behavior\n * - Shorter paths for Windows MAX_PATH compatibility (260 chars)\n * - 16 hex chars = 64 bits = acceptable collision risk for local cache\n * - Collision probability ~1 in 18 quintillion with 1000 entries\n *\n * Input strategy (aligned with npx):\n * - npx uses package spec strings (e.g., '@scope/pkg@1.0.0', 'prettier@3.0.0')\n * - Caller provides complete spec string with version for accurate cache keying\n * - For package installs: Use PURL-style spec with version\n * Examples: 'npm:prettier@3.0.0', 'pypi:requests@2.31.0', 'gem:rails@7.0.0'\n * Note: Socket uses shorthand format without 'pkg:' prefix\n * (handled by @socketregistry/packageurl-js)\n * - For binary downloads: Use URL:name for uniqueness\n *\n * Reference: npm/cli v11.6.2 libnpmexec/lib/index.js#L233-L244\n * https://github.com/npm/cli/blob/v11.6.2/workspaces/libnpmexec/lib/index.js#L233-L244\n * Implementation: packages.map().sort().join('\\n') \u2192 SHA-512 \u2192 slice(0,16)\n * npx hashes the package spec (name@version), not just name\n */\nexport function generateCacheKey(spec: string): string {\n return createHash('sha512').update(spec).digest('hex').substring(0, 16)\n}\n\nlet _path: typeof import('path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path!\n}\n\n/**\n * Clear all DLX package installations.\n */\nexport async function clearDlx(): Promise<void> {\n const packages = await listDlxPackagesAsync()\n await pEach(packages, pkg => removeDlxPackage(pkg))\n}\n\n/**\n * Clear all DLX package installations synchronously.\n */\nexport function clearDlxSync(): void {\n const packages = listDlxPackages()\n for (const pkg of packages) {\n removeDlxPackageSync(pkg)\n }\n}\n\n/**\n * Check if the DLX directory exists.\n */\nexport function dlxDirExists(): boolean {\n return existsSync(getSocketDlxDir())\n}\n\n/**\n * Check if the DLX directory exists asynchronously.\n */\nexport async function dlxDirExistsAsync(): Promise<boolean> {\n try {\n await fs.access(getSocketDlxDir())\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Ensure the DLX directory exists, creating it if necessary.\n */\nexport async function ensureDlxDir(): Promise<void> {\n await fs.mkdir(getSocketDlxDir(), { recursive: true })\n}\n\n/**\n * Ensure the DLX directory exists synchronously, creating it if necessary.\n */\nexport function ensureDlxDirSync(): void {\n const { mkdirSync } = require('node:fs')\n mkdirSync(getSocketDlxDir(), { recursive: true })\n}\n\n/**\n * Get the installed package directory within DLX node_modules.\n */\nexport function getDlxInstalledPackageDir(packageName: string): string {\n const path = getPath()\n return normalizePath(\n path.join(getDlxPackageNodeModulesDir(packageName), packageName),\n )\n}\n\n/**\n * Get the DLX installation directory for a specific package.\n */\nexport function getDlxPackageDir(packageName: string): string {\n const path = getPath()\n return normalizePath(path.join(getSocketDlxDir(), packageName))\n}\n\n/**\n * Get the package.json path for a DLX installed package.\n */\nexport function getDlxPackageJsonPath(packageName: string): string {\n const path = getPath()\n return normalizePath(\n path.join(getDlxInstalledPackageDir(packageName), 'package.json'),\n )\n}\n\n/**\n * Get the node_modules directory for a DLX package installation.\n */\nexport function getDlxPackageNodeModulesDir(packageName: string): string {\n const path = getPath()\n return normalizePath(path.join(getDlxPackageDir(packageName), 'node_modules'))\n}\n\n/**\n * Check if a file path is within the Socket DLX directory.\n * This is useful for determining if a binary or file is managed by Socket's DLX system.\n *\n * @param filePath - Absolute or relative path to check\n * @returns true if the path is within ~/.socket/_dlx/, false otherwise\n *\n * @example\n * ```typescript\n * isInSocketDlx('/home/user/.socket/_dlx/abc123/bin/socket') // true\n * isInSocketDlx('/usr/local/bin/socket') // false\n * isInSocketDlx(process.argv[0]) // Check if current binary is in DLX\n * ```\n */\nexport function isInSocketDlx(filePath: string): boolean {\n if (!filePath) {\n return false\n }\n\n const path = getPath()\n const dlxDir = getSocketDlxDir()\n const absolutePath = path.resolve(filePath)\n\n // Check if the absolute path starts with the DLX directory.\n return absolutePath.startsWith(dlxDir + path.sep)\n}\n\n/**\n * Check if a package is installed in DLX.\n */\nexport function isDlxPackageInstalled(packageName: string): boolean {\n return existsSync(getDlxInstalledPackageDir(packageName))\n}\n\n/**\n * Check if a package is installed in DLX asynchronously.\n */\nexport async function isDlxPackageInstalledAsync(\n packageName: string,\n): Promise<boolean> {\n try {\n await fs.access(getDlxInstalledPackageDir(packageName))\n return true\n } catch {\n return false\n }\n}\n\n/**\n * List all packages installed in DLX.\n */\nexport function listDlxPackages(): string[] {\n try {\n return readDirNamesSync(getSocketDlxDir(), { sort: true })\n } catch {\n return []\n }\n}\n\n/**\n * List all packages installed in DLX asynchronously.\n */\nexport async function listDlxPackagesAsync(): Promise<string[]> {\n try {\n const entries = await fs.readdir(getSocketDlxDir(), {\n withFileTypes: true,\n })\n return entries\n .filter(e => e.isDirectory())\n .map(e => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * Remove a DLX package installation.\n */\nexport async function removeDlxPackage(packageName: string): Promise<void> {\n const packageDir = getDlxPackageDir(packageName)\n try {\n await safeDelete(packageDir, { recursive: true, force: true })\n } catch (e) {\n throw new Error(`Failed to remove DLX package \"${packageName}\"`, {\n cause: e,\n })\n }\n}\n\n/**\n * Remove a DLX package installation synchronously.\n */\nexport function removeDlxPackageSync(packageName: string): void {\n const { rmSync } = require('node:fs')\n const packageDir = getDlxPackageDir(packageName)\n try {\n rmSync(packageDir, { recursive: true, force: true })\n } catch (e) {\n const code = (e as NodeJS.ErrnoException).code\n if (code === 'EACCES' || code === 'EPERM') {\n throw new Error(\n `Permission denied removing DLX package \"${packageName}\"\\n` +\n `Directory: ${packageDir}\\n` +\n 'To resolve:\\n' +\n ' 1. Check file/directory permissions\\n' +\n ' 2. Close any programs using files in this directory\\n' +\n ' 3. Try running with elevated privileges if necessary\\n' +\n ` 4. Manually remove: rm -rf \"${packageDir}\"`,\n { cause: e },\n )\n }\n if (code === 'EROFS') {\n throw new Error(\n `Cannot remove DLX package \"${packageName}\" from read-only filesystem\\n` +\n `Directory: ${packageDir}\\n` +\n 'The filesystem is mounted read-only.',\n { cause: e },\n )\n }\n throw new Error(\n `Failed to remove DLX package \"${packageName}\"\\n` +\n `Directory: ${packageDir}\\n` +\n 'Check permissions and ensure no programs are using this directory.',\n { cause: e },\n )\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["dlx_exports", "__export", "clearDlx", "clearDlxSync", "dlxDirExists", "dlxDirExistsAsync", "ensureDlxDir", "ensureDlxDirSync", "generateCacheKey", "getDlxInstalledPackageDir", "getDlxPackageDir", "getDlxPackageJsonPath", "getDlxPackageNodeModulesDir", "isDlxPackageInstalled", "isDlxPackageInstalledAsync", "isInSocketDlx", "listDlxPackages", "listDlxPackagesAsync", "removeDlxPackage", "removeDlxPackageSync", "__toCommonJS", "import_node_crypto", "import_node_fs", "import_fs", "import_path", "import_paths", "import_promises", "spec", "_path", "getPath", "packages", "pkg", "fs", "mkdirSync", "packageName", "filePath", "path", "dlxDir", "packageDir", "e", "rmSync", "code"]
|
|
7
7
|
}
|
package/dist/download-lock.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var
|
|
2
|
+
var D=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var y=(o,t)=>{for(var n in t)D(o,n,{get:t[n],enumerable:!0})},I=(o,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of h(t))!L.call(o,r)&&r!==n&&D(o,r,{get:()=>t[r],enumerable:!(i=T(t,r))||i.enumerable});return o};var b=o=>I(D({},"__esModule",{value:!0}),o);var z={};y(z,{downloadWithLock:()=>x});module.exports=b(z);var f=require("node:fs"),e=require("node:fs/promises"),u=require("node:path"),g=require("./http-request");function O(o,t){const n=o.replace(/[^\w.-]/g,"_"),i=t||(0,u.join)((0,u.dirname)(o),".locks",n);return(0,u.join)(i,"concurrency.lock")}function S(o,t){if(Date.now()-o.startTime>t)return!0;try{return process.kill(o.pid,0),!1}catch{return!0}}async function $(o,t,n){const{lockTimeout:i,locksDir:r,pollInterval:m,staleTimeout:p}=n,s=O(o,r),w=(0,u.dirname)(s);await(0,e.mkdir)(w,{recursive:!0});const c=Date.now();for(;;)try{if((0,f.existsSync)(s)){const d=await(0,e.readFile)(s,"utf8"),l=JSON.parse(d);if(S(l,p))await(0,e.rm)(s,{force:!0});else{if(Date.now()-c>i){const k=Date.now()-l.startTime;throw new Error(`Download lock timed out after ${i}ms
|
|
3
|
+
Lock held by process ${l.pid} for ${k}ms
|
|
4
|
+
Resource: ${l.url}
|
|
5
|
+
Started: ${new Date(l.startTime).toISOString()}
|
|
6
|
+
To resolve:
|
|
7
|
+
1. Check if process ${l.pid} is still running: ps -p ${l.pid}
|
|
8
|
+
2. If stale, remove lock file: rm "${s}"
|
|
9
|
+
3. Or increase lockTimeout option`)}await new Promise(k=>setTimeout(k,m));continue}}const a={pid:process.pid,startTime:Date.now(),url:t};return await(0,e.writeFile)(s,JSON.stringify(a,null,2),{flag:"wx"}),s}catch(a){if(a.code==="EEXIST"){if(Date.now()-c>i)throw new Error(`Lock acquisition timed out after ${i}ms`);await new Promise(d=>setTimeout(d,m));continue}throw a}}async function v(o){try{await(0,e.rm)(o,{force:!0})}catch{}}async function x(o,t,n){const{lockTimeout:i=6e4,locksDir:r,pollInterval:m=1e3,staleTimeout:p=1e4,...s}={__proto__:null,...n};if((0,f.existsSync)(t)){const c=await(0,e.stat)(t).catch(()=>null);if(c&&c.size>0)return{path:t,size:c.size}}const w=await $(t,o,{lockTimeout:i,locksDir:r,pollInterval:m,staleTimeout:p});try{if((0,f.existsSync)(t)){const a=await(0,e.stat)(t).catch(()=>null);if(a&&a.size>0)return{path:t,size:a.size}}return await(0,g.httpDownload)(o,t,s)}finally{await v(w)}}0&&(module.exports={downloadWithLock});
|
|
3
10
|
//# sourceMappingURL=download-lock.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/download-lock.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";4ZAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["download_lock_exports", "__export", "downloadWithLock", "__toCommonJS", "import_node_fs", "import_promises", "import_node_path", "import_http_request", "getLockFilePath", "destPath", "locksDir", "
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Download locking utilities to prevent concurrent downloads of the same resource. Uses file-based locking for cross-process synchronization.\n * @deprecated This module is deprecated in favor of `process-lock.ts` which uses\n * directory-based locking (via `mkdir()`) that's more reliable across all filesystems\n * including NFS. See process-lock.ts for detailed explanation of why directory-based\n * locking is superior to file-based locking.\n *\n * Migration: Use `processLock.withLock()` from `./process-lock` instead of\n * `downloadWithLock()` from this module.\n */\n\nimport { existsSync } from 'node:fs'\nimport { mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport type { HttpDownloadOptions, HttpDownloadResult } from './http-request'\nimport { httpDownload } from './http-request'\n\nexport interface DownloadLockInfo {\n pid: number\n startTime: number\n url: string\n}\n\nexport interface DownloadWithLockOptions extends HttpDownloadOptions {\n /**\n * Maximum time to wait for lock acquisition in milliseconds.\n * @default 60000 (1 minute)\n */\n lockTimeout?: number | undefined\n /**\n * Directory where lock files are stored.\n * @default '<destPath>.locks'\n */\n locksDir?: string | undefined\n /**\n * Interval for checking stale locks in milliseconds.\n * @default 1000 (1 second)\n */\n pollInterval?: number | undefined\n /**\n * Maximum age of a lock before it's considered stale in milliseconds.\n * Aligned with npm's npx locking strategy (5-10 seconds).\n * @default 10000 (10 seconds)\n */\n staleTimeout?: number | undefined\n}\n\n/**\n * Get the path to the lock file for a destination path.\n * Uses npm npx's concurrency.lock naming convention.\n * For downloads, we use a subdirectory per destination to isolate locks.\n */\nfunction getLockFilePath(destPath: string, locksDir?: string): string {\n // Create a unique subdirectory for each destination using sanitized path.\n const sanitized = destPath.replace(/[^\\w.-]/g, '_')\n const dir = locksDir || join(dirname(destPath), '.locks', sanitized)\n return join(dir, 'concurrency.lock')\n}\n\n/**\n * Check if a lock is stale (process no longer exists or too old).\n */\nfunction isLockStale(\n lockInfo: DownloadLockInfo,\n staleTimeout: number,\n): boolean {\n // Check if lock is too old\n const age = Date.now() - lockInfo.startTime\n if (age > staleTimeout) {\n return true\n }\n\n // Check if process still exists (Node.js specific)\n try {\n // process.kill(pid, 0) doesn't actually kill the process\n // It just checks if the process exists\n process.kill(lockInfo.pid, 0)\n return false\n } catch {\n // Process doesn't exist\n return true\n }\n}\n\n/**\n * Acquire a lock for downloading to a destination path.\n * @throws {Error} When lock cannot be acquired within timeout.\n */\nasync function acquireLock(\n destPath: string,\n url: string,\n options: {\n lockTimeout: number\n locksDir?: string | undefined\n pollInterval: number\n staleTimeout: number\n },\n): Promise<string> {\n const { lockTimeout, locksDir, pollInterval, staleTimeout } = options\n const lockPath = getLockFilePath(destPath, locksDir)\n const lockDir = dirname(lockPath)\n\n // Ensure lock directory exists\n await mkdir(lockDir, { recursive: true })\n\n const startTime = Date.now()\n\n while (true) {\n try {\n // Try to read existing lock\n if (existsSync(lockPath)) {\n // eslint-disable-next-line no-await-in-loop\n const lockContent = await readFile(lockPath, 'utf8')\n const lockInfo: DownloadLockInfo = JSON.parse(lockContent)\n\n // Check if lock is stale\n if (isLockStale(lockInfo, staleTimeout)) {\n // Remove stale lock\n // eslint-disable-next-line no-await-in-loop\n await rm(lockPath, { force: true })\n } else {\n // Lock is valid, check timeout\n if (Date.now() - startTime > lockTimeout) {\n const lockAge = Date.now() - lockInfo.startTime\n throw new Error(\n `Download lock timed out after ${lockTimeout}ms\\n` +\n `Lock held by process ${lockInfo.pid} for ${lockAge}ms\\n` +\n `Resource: ${lockInfo.url}\\n` +\n `Started: ${new Date(lockInfo.startTime).toISOString()}\\n` +\n 'To resolve:\\n' +\n ` 1. Check if process ${lockInfo.pid} is still running: ps -p ${lockInfo.pid}\\n` +\n ` 2. If stale, remove lock file: rm \"${lockPath}\"\\n` +\n ' 3. Or increase lockTimeout option',\n )\n }\n\n // Wait and retry\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, pollInterval))\n continue\n }\n }\n\n // Try to create lock file\n const lockInfo: DownloadLockInfo = {\n pid: process.pid,\n startTime: Date.now(),\n url,\n }\n\n // eslint-disable-next-line no-await-in-loop\n await writeFile(lockPath, JSON.stringify(lockInfo, null, 2), {\n // Use 'wx' flag to fail if file exists (atomic operation)\n flag: 'wx',\n })\n\n // Successfully acquired lock\n return lockPath\n } catch (e) {\n // If file already exists, another process created it first\n if ((e as NodeJS.ErrnoException).code === 'EEXIST') {\n if (Date.now() - startTime > lockTimeout) {\n throw new Error(`Lock acquisition timed out after ${lockTimeout}ms`)\n }\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, pollInterval))\n continue\n }\n\n // Other error\n throw e\n }\n }\n}\n\n/**\n * Release a lock by removing the lock file.\n */\nasync function releaseLock(lockPath: string): Promise<void> {\n try {\n await rm(lockPath, { force: true })\n } catch {\n // Ignore errors when releasing lock\n }\n}\n\n/**\n * Download a file with locking to prevent concurrent downloads of the same resource.\n * If another process is already downloading to the same destination, this will wait\n * for the download to complete (up to lockTimeout) before proceeding.\n *\n * @throws {Error} When download fails or lock cannot be acquired.\n *\n * @example\n * ```typescript\n * const result = await downloadWithLock(\n * 'https://example.com/file.tar.gz',\n * '/tmp/downloads/file.tar.gz',\n * {\n * retries: 3,\n * lockTimeout: 60000, // Wait up to 1 minute for other downloads\n * }\n * )\n * ```\n */\nexport async function downloadWithLock(\n url: string,\n destPath: string,\n options?: DownloadWithLockOptions | undefined,\n): Promise<HttpDownloadResult> {\n const {\n lockTimeout = 60_000,\n locksDir,\n pollInterval = 1000,\n // Aligned with npm's npx locking (5-10s range).\n staleTimeout = 10_000,\n ...downloadOptions\n } = { __proto__: null, ...options } as DownloadWithLockOptions\n\n // If file already exists and has content, return immediately\n if (existsSync(destPath)) {\n const statResult = await stat(destPath).catch(() => null)\n if (statResult && statResult.size > 0) {\n return {\n path: destPath,\n size: statResult.size,\n }\n }\n }\n\n // Acquire lock\n const lockPath = await acquireLock(destPath, url, {\n lockTimeout,\n locksDir,\n pollInterval,\n staleTimeout,\n })\n\n try {\n // Check again if file was created while we were waiting for lock\n if (existsSync(destPath)) {\n const statResult = await stat(destPath).catch(() => null)\n if (statResult && statResult.size > 0) {\n return {\n path: destPath,\n size: statResult.size,\n }\n }\n }\n\n // Perform download\n const result = await httpDownload(url, destPath, downloadOptions)\n\n return result\n } finally {\n // Always release lock\n await releaseLock(lockPath)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["download_lock_exports", "__export", "downloadWithLock", "__toCommonJS", "import_node_fs", "import_promises", "import_node_path", "import_http_request", "getLockFilePath", "destPath", "locksDir", "sanitized", "dir", "isLockStale", "lockInfo", "staleTimeout", "acquireLock", "url", "options", "lockTimeout", "pollInterval", "lockPath", "lockDir", "startTime", "lockContent", "lockAge", "resolve", "e", "releaseLock", "downloadOptions", "statResult"]
|
|
7
7
|
}
|
package/dist/fs.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var F=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var B=(n,e)=>{for(var t in e)F(n,t,{get:e[t],enumerable:!0})},q=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of T(e))!$.call(n,o)&&o!==t&&F(n,o,{get:()=>e[o],enumerable:!(i=W(e,o))||i.enumerable});return n};var M=n=>q(F({},"__esModule",{value:!0}),n);var ue={};B(ue,{findUp:()=>V,findUpSync:()=>G,invalidatePathCache:()=>U,isDir:()=>z,isDirEmptySync:()=>j,isDirSync:()=>K,isSymLinkSync:()=>H,readDirNames:()=>X,readDirNamesSync:()=>Y,readFileBinary:()=>Z,readFileBinarySync:()=>ne,readFileUtf8:()=>ee,readFileUtf8Sync:()=>te,readJson:()=>ie,readJsonSync:()=>re,safeDelete:()=>oe,safeDeleteSync:()=>se,safeReadFile:()=>ae,safeReadFileSync:()=>ce,safeStats:()=>C,safeStatsSync:()=>I,uniqueSync:()=>de,validateFiles:()=>Q,writeJson:()=>fe,writeJsonSync:()=>le});module.exports=M(ue);var v=require("#constants/process"),m=require("./arrays"),S=require("./globs"),b=require("./json"),D=require("./objects"),p=require("./path"),E=require("./paths/rewire"),k=require("./sorts");const w=(0,v.getAbortSignal)(),L=(0,D.objectFreeze)({__proto__:null,force:!0,maxRetries:3,recursive:!0,retryDelay:200});let P;function l(){return P===void 0&&(P=require("node:fs")),P}let R;function _(){return R===void 0&&(R=require("node:path")),R}function J(n,e,t){const{ignore:i,includeEmpty:o=!0,sort:s=!0}={__proto__:null,...t},c=_(),a=n.filter(r=>r.isDirectory()&&(o||!j(c.join(e||r.parentPath,r.name),{ignore:i}))).map(r=>r.name);return s?a.sort(k.naturalCompare):a}function A(n,e,t,i,o=2){const s=t?e:"";return`${JSON.stringify(n,i,o).replace(/\n/g,e)}${s}`}async function V(n,e){const{cwd:t=process.cwd(),signal:i=w}={__proto__:null,...e};let{onlyDirectories:o=!1,onlyFiles:s=!0}={__proto__:null,...e};o&&(s=!1),s&&(o=!1);const c=l(),a=_();let r=a.resolve(t);const{root:d}=a.parse(r),f=(0,m.isArray)(n)?n:[n];for(;r&&r!==d;){for(const y of f){if(i?.aborted)return;const u=a.join(r,y);try{const g=await c.promises.stat(u);if(!o&&g.isFile())return(0,p.normalizePath)(u);if(!s&&g.isDirectory())return(0,p.normalizePath)(u)}catch{}}r=a.dirname(r)}}function G(n,e){const{cwd:t=process.cwd(),stopAt:i}={__proto__:null,...e};let{onlyDirectories:o=!1,onlyFiles:s=!0}={__proto__:null,...e};o&&(s=!1),s&&(o=!1);const c=l(),a=_();let r=a.resolve(t);const{root:d}=a.parse(r),f=i?a.resolve(i):void 0,y=(0,m.isArray)(n)?n:[n];for(;r&&r!==d;){if(f&&r===f){for(const u of y){const g=a.join(r,u);try{const h=c.statSync(g);if(!o&&h.isFile())return(0,p.normalizePath)(g);if(!s&&h.isDirectory())return(0,p.normalizePath)(g)}catch{}}return}for(const u of y){const g=a.join(r,u);try{const h=c.statSync(g);if(!o&&h.isFile())return(0,p.normalizePath)(g);if(!s&&h.isDirectory())return(0,p.normalizePath)(g)}catch{}}r=a.dirname(r)}}async function z(n){return!!(await C(n))?.isDirectory()}function K(n){return!!I(n)?.isDirectory()}function j(n,e){const{ignore:t=S.defaultIgnore}={__proto__:null,...e},i=l();try{const o=i.readdirSync(n),{length:s}=o;if(s===0)return!0;const c=(0,S.getGlobMatcher)(t,{cwd:(0,p.pathLikeToString)(n)});let a=0;for(let r=0;r<s;r+=1){const d=o[r];d&&c(d)&&(a+=1)}return a===s}catch{return!1}}function H(n){const e=l();try{return e.lstatSync(n).isSymbolicLink()}catch{}return!1}function Q(n){const e=l(),t=[],i=[],{R_OK:o}=e.constants;for(const s of n)try{e.accessSync(s,o),t.push(s)}catch{i.push(s)}return{__proto__:null,validPaths:t,invalidPaths:i}}async function X(n,e){const t=l();try{return J(await t.promises.readdir(n,{__proto__:null,encoding:"utf8",withFileTypes:!0}),String(n),e)}catch{}return[]}function Y(n,e){const t=l();try{return J(t.readdirSync(n,{__proto__:null,encoding:"utf8",withFileTypes:!0}),String(n),e)}catch{}return[]}async function Z(n,e){const t=typeof e=="string"?{encoding:e}:e;return await l().promises.readFile(n,{signal:w,...t,encoding:null})}async function ee(n,e){const t=typeof e=="string"?{encoding:e}:e;return await l().promises.readFile(n,{signal:w,...t,encoding:"utf8"})}function ne(n,e){const t=typeof e=="string"?{encoding:e}:e;return l().readFileSync(n,{...t,encoding:null})}function te(n,e){const t=typeof e=="string"?{encoding:e}:e;return l().readFileSync(n,{...t,encoding:"utf8"})}async function ie(n,e){const t=typeof e=="string"?{encoding:e}:e,{reviver:i,throws:o,...s}={__proto__:null,...t},c=o===void 0||!!o,a=l();let r="";try{r=await a.promises.readFile(n,{__proto__:null,encoding:"utf8",...s})}catch(d){if(c){const f=d.code;throw f==="ENOENT"?new Error(`JSON file not found: ${n}
|
|
3
|
+
Ensure the file exists or create it with the expected structure.`,{cause:d}):f==="EACCES"||f==="EPERM"?new Error(`Permission denied reading JSON file: ${n}
|
|
4
|
+
Check file permissions or run with appropriate access.`,{cause:d}):d}return}return(0,b.jsonParse)(r,{filepath:String(n),reviver:i,throws:c})}function re(n,e){const t=typeof e=="string"?{encoding:e}:e,{reviver:i,throws:o,...s}={__proto__:null,...t},c=o===void 0||!!o,a=l();let r="";try{r=a.readFileSync(n,{__proto__:null,encoding:"utf8",...s})}catch(d){if(c){const f=d.code;throw f==="ENOENT"?new Error(`JSON file not found: ${n}
|
|
5
|
+
Ensure the file exists or create it with the expected structure.`,{cause:d}):f==="EACCES"||f==="EPERM"?new Error(`Permission denied reading JSON file: ${n}
|
|
6
|
+
Check file permissions or run with appropriate access.`,{cause:d}):d}return}return(0,b.jsonParse)(r,{filepath:String(n),reviver:i,throws:c})}let O;function N(){if(O===void 0){const n=_(),{getOsTmpDir:e,getSocketCacacheDir:t,getSocketUserDir:i}=require("#lib/paths");O=[n.resolve(e()),n.resolve(t()),n.resolve(i())]}return O}function U(){O=void 0}(0,E.registerCacheInvalidation)(U);async function oe(n,e){const t=require("./external/del"),{deleteAsync:i}=t,o={__proto__:null,...e},s=(0,m.isArray)(n)?n.map(p.pathLikeToString):[(0,p.pathLikeToString)(n)];let c=o.force!==!1;if(!c&&s.length>0){const a=_(),r=N();s.every(f=>{const y=a.resolve(f);for(const u of r){const g=y.startsWith(u+a.sep)||y===u,x=a.relative(u,y).startsWith("..");if(g&&!x)return!0}return!1})&&(c=!0)}await i(s,{concurrency:o.maxRetries||L.maxRetries,dryRun:!1,force:c,onlyFiles:!1})}function se(n,e){const t=require("./external/del"),{deleteSync:i}=t,o={__proto__:null,...e},s=(0,m.isArray)(n)?n.map(p.pathLikeToString):[(0,p.pathLikeToString)(n)];let c=o.force!==!1;if(!c&&s.length>0){const a=_(),r=N();s.every(f=>{const y=a.resolve(f);for(const u of r){const g=y.startsWith(u+a.sep)||y===u,x=a.relative(u,y).startsWith("..");if(g&&!x)return!0}return!1})&&(c=!0)}i(s,{concurrency:o.maxRetries||L.maxRetries,dryRun:!1,force:c,onlyFiles:!1})}async function ae(n,e){const t=typeof e=="string"?{encoding:e}:e,i=l();try{return await i.promises.readFile(n,{signal:w,...t})}catch{}}async function C(n){const e=l();try{return await e.promises.stat(n)}catch{}}function I(n,e){const t=typeof e=="string"?{encoding:e}:e,i=l();try{return i.statSync(n,{__proto__:null,throwIfNoEntry:!1,...t})}catch{}}function ce(n,e){const t=typeof e=="string"?{encoding:e}:e,i=l();try{return i.readFileSync(n,{__proto__:null,...t})}catch{}}function de(n){const e=l(),t=_(),i=String(n);if(!e.existsSync(i))return(0,p.normalizePath)(i);const o=t.dirname(i),s=t.extname(i),c=t.basename(i,s);let a=1,r;do r=t.join(o,`${c}-${a}${s}`),a++;while(e.existsSync(r));return(0,p.normalizePath)(r)}async function fe(n,e,t){const i=typeof t=="string"?{encoding:t}:t,{EOL:o,finalEOL:s,replacer:c,spaces:a,...r}={__proto__:null,...i},d=l(),f=A(e,o||`
|
|
7
|
+
`,s!==void 0?s:!0,c,a);await d.promises.writeFile(n,f,{encoding:"utf8",...r,__proto__:null})}function le(n,e,t){const i=typeof t=="string"?{encoding:t}:t,{EOL:o,finalEOL:s,replacer:c,spaces:a,...r}={__proto__:null,...i},d=l(),f=A(e,o||`
|
|
8
|
+
`,s!==void 0?s:!0,c,a);d.writeFileSync(n,f,{encoding:"utf8",...r,__proto__:null})}0&&(module.exports={findUp,findUpSync,invalidatePathCache,isDir,isDirEmptySync,isDirSync,isSymLinkSync,readDirNames,readDirNamesSync,readFileBinary,readFileBinarySync,readFileUtf8,readFileUtf8Sync,readJson,readJsonSync,safeDelete,safeDeleteSync,safeReadFile,safeReadFileSync,safeStats,safeStatsSync,uniqueSync,validateFiles,writeJson,writeJsonSync});
|
|
5
9
|
//# sourceMappingURL=fs.js.map
|