@socketsecurity/lib 2.10.4 → 3.0.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +50 -24
  2. package/README.md +231 -40
  3. package/dist/constants/platform.js +1 -1
  4. package/dist/constants/platform.js.map +3 -3
  5. package/dist/cover/code.js +1 -1
  6. package/dist/cover/code.js.map +3 -3
  7. package/dist/debug.js +2 -2
  8. package/dist/debug.js.map +3 -3
  9. package/dist/dlx-binary.d.ts +29 -6
  10. package/dist/dlx-binary.js +6 -6
  11. package/dist/dlx-binary.js.map +3 -3
  12. package/dist/dlx-package.d.ts +16 -1
  13. package/dist/dlx-package.js +6 -6
  14. package/dist/dlx-package.js.map +3 -3
  15. package/dist/dlx.js +1 -1
  16. package/dist/dlx.js.map +3 -3
  17. package/dist/env/rewire.js +1 -1
  18. package/dist/env/rewire.js.map +3 -3
  19. package/dist/external/yoctocolors-cjs.d.ts +14 -0
  20. package/dist/fs.d.ts +2 -2
  21. package/dist/fs.js.map +1 -1
  22. package/dist/git.js +1 -1
  23. package/dist/git.js.map +3 -3
  24. package/dist/http-request.js +1 -1
  25. package/dist/http-request.js.map +3 -3
  26. package/dist/index.d.ts +6 -5
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +3 -3
  29. package/dist/ipc.js +1 -1
  30. package/dist/ipc.js.map +3 -3
  31. package/dist/links/index.d.ts +65 -0
  32. package/dist/links/index.js +3 -0
  33. package/dist/links/index.js.map +7 -0
  34. package/dist/logger.d.ts +21 -18
  35. package/dist/logger.js +1 -1
  36. package/dist/logger.js.map +3 -3
  37. package/dist/packages/isolation.js +1 -1
  38. package/dist/packages/isolation.js.map +3 -3
  39. package/dist/paths.js +1 -1
  40. package/dist/paths.js.map +2 -2
  41. package/dist/process-lock.js +2 -2
  42. package/dist/process-lock.js.map +3 -3
  43. package/dist/promises.d.ts +6 -21
  44. package/dist/promises.js +1 -1
  45. package/dist/promises.js.map +2 -2
  46. package/dist/prompts/index.d.ts +115 -0
  47. package/dist/prompts/index.js +3 -0
  48. package/dist/prompts/index.js.map +7 -0
  49. package/dist/spinner.d.ts +33 -23
  50. package/dist/spinner.js +1 -1
  51. package/dist/spinner.js.map +3 -3
  52. package/dist/stdio/mask.d.ts +2 -2
  53. package/dist/stdio/mask.js +4 -4
  54. package/dist/stdio/mask.js.map +3 -3
  55. package/dist/stdio/stdout.js +1 -1
  56. package/dist/stdio/stdout.js.map +3 -3
  57. package/dist/themes/context.d.ts +80 -0
  58. package/dist/themes/context.js +3 -0
  59. package/dist/themes/context.js.map +7 -0
  60. package/dist/themes/index.d.ts +53 -0
  61. package/dist/themes/index.js +3 -0
  62. package/dist/themes/index.js.map +7 -0
  63. package/dist/themes/themes.d.ts +49 -0
  64. package/dist/themes/themes.js +3 -0
  65. package/dist/themes/themes.js.map +7 -0
  66. package/dist/themes/types.d.ts +92 -0
  67. package/dist/themes/types.js +3 -0
  68. package/dist/themes/types.js.map +7 -0
  69. package/dist/themes/utils.d.ts +78 -0
  70. package/dist/themes/utils.js +3 -0
  71. package/dist/themes/utils.js.map +7 -0
  72. package/package.json +39 -11
  73. package/dist/download-lock.d.ts +0 -49
  74. package/dist/download-lock.js +0 -10
  75. package/dist/download-lock.js.map +0 -7
  76. package/dist/packages/registry.d.ts +0 -8
  77. package/dist/packages/registry.js +0 -3
  78. package/dist/packages/registry.js.map +0 -7
package/dist/git.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/git.ts"],
4
- "sourcesContent": ["import path from 'node:path'\n\nimport { WIN32 } from '#constants/platform'\nimport { debugNs } from './debug'\nimport { getGlobMatcher } from './globs'\nimport { normalizePath } from './path'\nimport { spawn, spawnSync } from './spawn'\nimport { stripAnsi } from './strings'\n\n/**\n * Options for git diff operations.\n *\n * Controls how git diff results are processed and returned.\n *\n * @example\n * ```typescript\n * // Get absolute file paths\n * const files = await getChangedFiles({ absolute: true })\n * // => ['/path/to/repo/src/file.ts']\n *\n * // Get relative paths with caching disabled\n * const files = await getChangedFiles({ cache: false })\n * // => ['src/file.ts']\n *\n * // Get files from specific directory\n * const files = await getChangedFiles({ cwd: '/path/to/repo/src' })\n * ```\n */\nexport interface GitDiffOptions {\n /**\n * Return absolute file paths instead of relative paths.\n *\n * @default false\n */\n absolute?: boolean | undefined\n /**\n * Cache git diff results to avoid repeated git subprocess calls.\n *\n * Caching is keyed by the git command and options used, so different\n * option combinations maintain separate cache entries.\n *\n * @default true\n */\n cache?: boolean | undefined\n /**\n * Working directory for git operations.\n *\n * Git operations will be run from this directory, and returned paths\n * will be relative to the git repository root. Symlinks are resolved\n * using `fs.realpathSync()`.\n *\n * @default process.cwd()\n */\n cwd?: string | undefined\n /**\n * Parse git porcelain format output (status codes like `M`, `A`, `??`).\n *\n * When `true`, strips the two-character status code and space from the\n * beginning of each line. Automatically enabled for `getChangedFiles()`.\n *\n * @default false\n */\n porcelain?: boolean | undefined\n /**\n * Return results as a `Set` instead of an array.\n *\n * @default false\n */\n asSet?: boolean | undefined\n /**\n * Additional options passed to glob matcher.\n *\n * Supports options like `dot`, `ignore`, `nocase` for filtering results.\n */\n [key: string]: unknown\n}\n\n/**\n * Options for filtering packages by git changes.\n *\n * Used to determine which packages in a monorepo have changed files.\n *\n * @example\n * ```typescript\n * // Filter packages with changes\n * const changed = filterPackagesByChanges(packages)\n *\n * // Force include all packages\n * const all = filterPackagesByChanges(packages, { force: true })\n *\n * // Use custom package key\n * const changed = filterPackagesByChanges(\n * packages,\n * { packageKey: 'directory' }\n * )\n * ```\n */\nexport interface FilterPackagesByChangesOptions {\n /**\n * Force include all packages regardless of changes.\n *\n * @default false\n */\n force?: boolean | undefined\n /**\n * Key to access package path in package objects.\n *\n * @default 'path'\n */\n packageKey?: string | undefined\n /**\n * Additional options for filtering.\n */\n [key: string]: unknown\n}\n\ntype SpawnArgs = [string, string[], Record<string, unknown>]\n\ninterface GitDiffSpawnArgs {\n all: SpawnArgs\n unstaged: SpawnArgs\n staged: SpawnArgs\n}\n\nconst gitDiffCache = new Map<string, string[]>()\n\nlet _fs: typeof import('fs') | undefined\n/**\n * Lazily load the `fs` module to avoid Webpack errors.\n *\n * Uses non-`node:` prefixed require internally to prevent Webpack from\n * attempting to bundle Node.js built-in modules.\n *\n * @returns The Node.js `fs` module.\n *\n * @example\n * ```typescript\n * const fs = getFs()\n * const exists = fs.existsSync('/path/to/file')\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFs() {\n if (_fs === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _fs = /*@__PURE__*/ require('node:fs')\n }\n return _fs as typeof import('fs')\n}\n\nlet _path: typeof import('path') | undefined\n/**\n * Lazily load the `path` module to avoid Webpack errors.\n *\n * Uses non-`node:` prefixed require internally to prevent Webpack from\n * attempting to bundle Node.js built-in modules.\n *\n * @returns The Node.js `path` module.\n *\n * @example\n * ```typescript\n * const path = getPath()\n * const joined = path.join('/foo', 'bar')\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path as typeof import('path')\n}\n\n/**\n * Get the git executable path.\n *\n * Currently always returns `'git'`, relying on the system PATH to resolve\n * the git binary location. This may be extended in the future to support\n * custom git paths.\n *\n * @returns The git executable name or path.\n *\n * @example\n * ```typescript\n * const git = getGitPath()\n * // => 'git'\n * ```\n */\nfunction getGitPath(): string {\n return 'git'\n}\n\n/**\n * Get the current working directory for git operations.\n *\n * Returns the real path to handle symlinks correctly. This is important\n * because symlinked directories like `/tmp -> /private/tmp` can cause\n * path mismatches when comparing git output.\n *\n * @returns The resolved real path of `process.cwd()`.\n *\n * @example\n * ```typescript\n * const cwd = getCwd()\n * // In /tmp (symlink to /private/tmp):\n * // => '/private/tmp'\n * ```\n */\nfunction getCwd(): string {\n return getFs().realpathSync(process.cwd())\n}\n\n/**\n * Get spawn arguments for different git diff operations.\n *\n * Prepares argument arrays for `spawn()`/`spawnSync()` calls that retrieve:\n * - `all`: All changed files (staged, unstaged, untracked) via `git status --porcelain`\n * - `unstaged`: Unstaged modifications via `git diff --name-only`\n * - `staged`: Staged changes via `git diff --cached --name-only`\n *\n * Automatically resolves symlinks in the provided `cwd` and enables shell\n * mode on Windows for proper command execution.\n *\n * @param cwd - Working directory for git operations, defaults to `process.cwd()`.\n * @returns Object containing spawn arguments for all, unstaged, and staged operations.\n */\nfunction getGitDiffSpawnArgs(cwd?: string | undefined): GitDiffSpawnArgs {\n const resolvedCwd = cwd ? getFs().realpathSync(cwd) : getCwd()\n return {\n all: [\n getGitPath(),\n ['status', '--porcelain'],\n {\n cwd: resolvedCwd,\n shell: WIN32,\n },\n ],\n unstaged: [\n getGitPath(),\n ['diff', '--name-only'],\n {\n cwd: resolvedCwd,\n },\n ],\n staged: [\n getGitPath(),\n ['diff', '--cached', '--name-only'],\n {\n cwd: resolvedCwd,\n shell: WIN32,\n },\n ],\n }\n}\n\n/**\n * Execute git diff command asynchronously and parse results.\n *\n * Internal helper for async git operations. Handles caching, command execution,\n * and result parsing. Returns empty array on git command failure.\n *\n * @param args - Spawn arguments tuple `[command, args, options]`.\n * @param options - Git diff options for caching and parsing.\n * @returns Promise resolving to array of file paths.\n */\nasync function innerDiff(\n args: SpawnArgs,\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const { cache = true, ...parseOptions } = { __proto__: null, ...options }\n const cacheKey = cache ? JSON.stringify({ args, parseOptions }) : undefined\n if (cache && cacheKey) {\n const result = gitDiffCache.get(cacheKey)\n if (result) {\n return result\n }\n }\n let result: string[]\n try {\n // Use stdioString: false to get raw Buffer, then convert ourselves to preserve exact output.\n const spawnResult = await spawn(args[0], args[1], {\n ...args[2],\n stdioString: false,\n })\n const stdout = Buffer.isBuffer(spawnResult.stdout)\n ? spawnResult.stdout.toString('utf8')\n : String(spawnResult.stdout)\n // Extract spawn cwd from args to pass to parser\n const spawnCwd =\n typeof args[2]['cwd'] === 'string' ? args[2]['cwd'] : undefined\n result = parseGitDiffStdout(stdout, parseOptions, spawnCwd)\n } catch (e) {\n // Git command failed. This is expected if:\n // - Not in a git repository\n // - Git is not installed\n // - Permission issues accessing .git directory\n // Log warning in debug mode for troubleshooting.\n debugNs(\n 'git',\n `Git command failed (${args[0]} ${args[1].join(' ')}): ${(e as Error).message}`,\n )\n return []\n }\n if (cache && cacheKey) {\n gitDiffCache.set(cacheKey, result)\n }\n return result\n}\n\n/**\n * Execute git diff command synchronously and parse results.\n *\n * Internal helper for sync git operations. Handles caching, command execution,\n * and result parsing. Returns empty array on git command failure.\n *\n * @param args - Spawn arguments tuple `[command, args, options]`.\n * @param options - Git diff options for caching and parsing.\n * @returns Array of file paths.\n */\nfunction innerDiffSync(\n args: SpawnArgs,\n options?: GitDiffOptions | undefined,\n): string[] {\n const { cache = true, ...parseOptions } = { __proto__: null, ...options }\n const cacheKey = cache ? JSON.stringify({ args, parseOptions }) : undefined\n if (cache && cacheKey) {\n const result = gitDiffCache.get(cacheKey)\n if (result) {\n return result\n }\n }\n let result: string[]\n try {\n // Use stdioString: false to get raw Buffer, then convert ourselves to preserve exact output.\n const spawnResult = spawnSync(args[0], args[1], {\n ...args[2],\n stdioString: false,\n })\n const stdout = Buffer.isBuffer(spawnResult.stdout)\n ? spawnResult.stdout.toString('utf8')\n : String(spawnResult.stdout)\n // Extract spawn cwd from args to pass to parser\n const spawnCwd =\n typeof args[2]['cwd'] === 'string' ? args[2]['cwd'] : undefined\n result = parseGitDiffStdout(stdout, parseOptions, spawnCwd)\n } catch (e) {\n // Git command failed. This is expected if:\n // - Not in a git repository\n // - Git is not installed\n // - Permission issues accessing .git directory\n // Log warning in debug mode for troubleshooting.\n debugNs(\n 'git',\n `Git command failed (${args[0]} ${args[1].join(' ')}): ${(e as Error).message}`,\n )\n return []\n }\n if (cache && cacheKey) {\n gitDiffCache.set(cacheKey, result)\n }\n return result\n}\n\n/**\n * Find git repository root by walking up from the given directory.\n *\n * Searches for a `.git` directory or file by traversing parent directories\n * upward until found or filesystem root is reached. Returns the original path\n * if no git repository is found.\n *\n * This function is exported primarily for testing purposes.\n *\n * @param startPath - Directory path to start searching from.\n * @returns Git repository root path, or `startPath` if not found.\n *\n * @example\n * ```typescript\n * const root = findGitRoot('/path/to/repo/src/subdir')\n * // => '/path/to/repo'\n *\n * const notFound = findGitRoot('/not/a/repo')\n * // => '/not/a/repo'\n * ```\n */\nexport function findGitRoot(startPath: string): string {\n const fs = getFs()\n const path = getPath()\n let currentPath = startPath\n // Walk up the directory tree looking for .git\n while (true) {\n try {\n const gitPath = path.join(currentPath, '.git')\n if (fs.existsSync(gitPath)) {\n return currentPath\n }\n } catch {\n // Ignore errors and continue walking up\n }\n const parentPath = path.dirname(currentPath)\n // Stop if we've reached the root or can't go up anymore\n if (parentPath === currentPath) {\n // Return original path if no .git found\n return startPath\n }\n currentPath = parentPath\n }\n}\n\n/**\n * Parse git diff stdout output into file path array.\n *\n * Internal helper that processes raw git command output by:\n * 1. Finding git repository root from spawn cwd\n * 2. Stripping ANSI codes and splitting into lines\n * 3. Parsing porcelain format status codes if requested\n * 4. Normalizing and optionally making paths absolute\n * 5. Filtering paths based on cwd and glob options\n *\n * Git always returns paths relative to the repository root, regardless of\n * where the command was executed. This function handles the path resolution\n * correctly by finding the repo root and adjusting paths accordingly.\n *\n * @param stdout - Raw stdout from git command.\n * @param options - Git diff options for path processing.\n * @param spawnCwd - Working directory where git command was executed.\n * @returns Array of processed file paths.\n */\nfunction parseGitDiffStdout(\n stdout: string,\n options?: GitDiffOptions | undefined,\n spawnCwd?: string | undefined,\n): string[] {\n // Find git repo root from spawnCwd. Git always returns paths relative to the repo root,\n // not the cwd where it was run. So we need to find the repo root to correctly parse paths.\n const defaultRoot = spawnCwd ? findGitRoot(spawnCwd) : getCwd()\n const {\n absolute = false,\n cwd: cwdOption = defaultRoot,\n porcelain = false,\n ...matcherOptions\n } = { __proto__: null, ...options }\n // Resolve cwd to handle symlinks.\n const cwd =\n cwdOption === defaultRoot ? defaultRoot : getFs().realpathSync(cwdOption)\n const rootPath = defaultRoot\n // Split into lines without trimming to preserve leading spaces in porcelain format.\n let rawFiles = stdout\n ? stripAnsi(stdout)\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line)\n : []\n // Parse porcelain format: strip status codes.\n // Git status --porcelain format is: XY filename\n // where X and Y are single characters and there's a space before the filename.\n if (porcelain) {\n rawFiles = rawFiles.map(line => {\n // Status is first 2 chars, then space, then filename.\n return line.length > 3 ? line.substring(3) : line\n })\n }\n const files = absolute\n ? rawFiles.map(relPath => normalizePath(path.join(rootPath, relPath)))\n : rawFiles.map(relPath => normalizePath(relPath))\n if (cwd === rootPath) {\n return files\n }\n const relPath = normalizePath(path.relative(rootPath, cwd))\n const matcher = getGlobMatcher([`${relPath}/**`], {\n ...(matcherOptions as {\n dot?: boolean\n ignore?: string[]\n nocase?: boolean\n }),\n absolute,\n cwd: rootPath,\n } as {\n absolute?: boolean\n cwd?: string\n dot?: boolean\n ignore?: string[]\n nocase?: boolean\n })\n const filtered: string[] = []\n for (const filepath of files) {\n if (matcher(filepath)) {\n filtered.push(filepath)\n }\n }\n return filtered\n}\n\n/**\n * Get all changed files including staged, unstaged, and untracked files.\n *\n * Uses `git status --porcelain` which returns the full working tree status\n * with status codes:\n * - `M` - Modified\n * - `A` - Added\n * - `D` - Deleted\n * - `??` - Untracked\n * - `R` - Renamed\n * - `C` - Copied\n *\n * This is the most comprehensive check - captures everything that differs\n * from the last commit, including:\n * - Files modified and staged with `git add`\n * - Files modified but not staged\n * - New files not yet tracked by git\n *\n * Status codes are automatically stripped from the output.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of changed file paths.\n *\n * @example\n * ```typescript\n * // Get all changed files as relative paths\n * const files = await getChangedFiles()\n * // => ['src/foo.ts', 'src/bar.ts', 'newfile.ts']\n *\n * // Get absolute paths\n * const files = await getChangedFiles({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n *\n * // Get changed files in specific directory\n * const files = await getChangedFiles({ cwd: '/path/to/repo/src' })\n * // => ['foo.ts', 'bar.ts']\n * ```\n */\nexport async function getChangedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).all\n return await innerDiff(args, {\n __proto__: null,\n ...options,\n porcelain: true,\n })\n}\n\n/**\n * Get all changed files including staged, unstaged, and untracked files.\n *\n * Synchronous version of `getChangedFiles()`. Uses `git status --porcelain`\n * which returns the full working tree status with status codes:\n * - `M` - Modified\n * - `A` - Added\n * - `D` - Deleted\n * - `??` - Untracked\n * - `R` - Renamed\n * - `C` - Copied\n *\n * This is the most comprehensive check - captures everything that differs\n * from the last commit, including:\n * - Files modified and staged with `git add`\n * - Files modified but not staged\n * - New files not yet tracked by git\n *\n * Status codes are automatically stripped from the output.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of changed file paths.\n *\n * @example\n * ```typescript\n * // Get all changed files as relative paths\n * const files = getChangedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts', 'newfile.ts']\n *\n * // Get absolute paths\n * const files = getChangedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n *\n * // Get changed files in specific directory\n * const files = getChangedFilesSync({ cwd: '/path/to/repo/src' })\n * // => ['foo.ts', 'bar.ts']\n * ```\n */\nexport function getChangedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).all\n return innerDiffSync(args, {\n __proto__: null,\n ...options,\n porcelain: true,\n })\n}\n\n/**\n * Get unstaged modified files (changes not yet staged for commit).\n *\n * Uses `git diff --name-only` which returns only unstaged modifications\n * to tracked files. Does NOT include:\n * - Untracked files (new files not added to git)\n * - Staged changes (files added with `git add`)\n *\n * This is a focused check for uncommitted changes to existing tracked files.\n * Useful for detecting work-in-progress modifications before staging.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of unstaged file paths.\n *\n * @example\n * ```typescript\n * // Get unstaged files\n * const files = await getUnstagedFiles()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // After staging some files\n * await spawn('git', ['add', 'src/foo.ts'])\n * const files = await getUnstagedFiles()\n * // => ['src/bar.ts'] (foo.ts no longer included)\n *\n * // Get absolute paths\n * const files = await getUnstagedFiles({ absolute: true })\n * // => ['/path/to/repo/src/bar.ts']\n * ```\n */\nexport async function getUnstagedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).unstaged\n return await innerDiff(args, options)\n}\n\n/**\n * Get unstaged modified files (changes not yet staged for commit).\n *\n * Synchronous version of `getUnstagedFiles()`. Uses `git diff --name-only`\n * which returns only unstaged modifications to tracked files. Does NOT include:\n * - Untracked files (new files not added to git)\n * - Staged changes (files added with `git add`)\n *\n * This is a focused check for uncommitted changes to existing tracked files.\n * Useful for detecting work-in-progress modifications before staging.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of unstaged file paths.\n *\n * @example\n * ```typescript\n * // Get unstaged files\n * const files = getUnstagedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // After staging some files\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const files = getUnstagedFilesSync()\n * // => ['src/bar.ts'] (foo.ts no longer included)\n *\n * // Get absolute paths\n * const files = getUnstagedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/bar.ts']\n * ```\n */\nexport function getUnstagedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).unstaged\n return innerDiffSync(args, options)\n}\n\n/**\n * Get staged files ready for commit (changes added with `git add`).\n *\n * Uses `git diff --cached --name-only` which returns only staged changes.\n * Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not added to git)\n *\n * This is a focused check for what will be included in the next commit.\n * Useful for validating changes before committing or running pre-commit hooks.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of staged file paths.\n *\n * @example\n * ```typescript\n * // Get currently staged files\n * const files = await getStagedFiles()\n * // => ['src/foo.ts']\n *\n * // Stage more files\n * await spawn('git', ['add', 'src/bar.ts'])\n * const files = await getStagedFiles()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // Get absolute paths\n * const files = await getStagedFiles({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n * ```\n */\nexport async function getStagedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).staged\n return await innerDiff(args, options)\n}\n\n/**\n * Get staged files ready for commit (changes added with `git add`).\n *\n * Synchronous version of `getStagedFiles()`. Uses `git diff --cached --name-only`\n * which returns only staged changes. Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not added to git)\n *\n * This is a focused check for what will be included in the next commit.\n * Useful for validating changes before committing or running pre-commit hooks.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of staged file paths.\n *\n * @example\n * ```typescript\n * // Get currently staged files\n * const files = getStagedFilesSync()\n * // => ['src/foo.ts']\n *\n * // Stage more files\n * spawnSync('git', ['add', 'src/bar.ts'])\n * const files = getStagedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // Get absolute paths\n * const files = getStagedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n * ```\n */\nexport function getStagedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).staged\n return innerDiffSync(args, options)\n}\n\n/**\n * Check if a file or directory has any git changes.\n *\n * Checks if the given pathname has any changes including:\n * - Staged modifications (added with `git add`)\n * - Unstaged modifications (not yet staged)\n * - Untracked status (new file/directory not in git)\n *\n * For directories, returns `true` if ANY file within the directory has changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git status check.\n * @returns Promise resolving to `true` if path has any changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is changed\n * const changed = await isChanged('src/foo.ts')\n * // => true\n *\n * // Check if directory has any changes\n * const changed = await isChanged('src/')\n * // => true (if any file in src/ is changed)\n *\n * // Check from different cwd\n * const changed = await isChanged(\n * '/path/to/repo/src/foo.ts',\n * { cwd: '/path/to/repo' }\n * )\n * ```\n */\nexport async function isChanged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getChangedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has any git changes.\n *\n * Synchronous version of `isChanged()`. Checks if the given pathname has\n * any changes including:\n * - Staged modifications (added with `git add`)\n * - Unstaged modifications (not yet staged)\n * - Untracked status (new file/directory not in git)\n *\n * For directories, returns `true` if ANY file within the directory has changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git status check.\n * @returns `true` if path has any changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is changed\n * const changed = isChangedSync('src/foo.ts')\n * // => true\n *\n * // Check if directory has any changes\n * const changed = isChangedSync('src/')\n * // => true (if any file in src/ is changed)\n *\n * // Check from different cwd\n * const changed = isChangedSync(\n * '/path/to/repo/src/foo.ts',\n * { cwd: '/path/to/repo' }\n * )\n * ```\n */\nexport function isChangedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getChangedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has unstaged changes.\n *\n * Checks if the given pathname has modifications that are not yet staged\n * for commit (changes not added with `git add`). Does NOT include:\n * - Staged changes (already added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory has\n * unstaged changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns Promise resolving to `true` if path has unstaged changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file has unstaged changes\n * const unstaged = await isUnstaged('src/foo.ts')\n * // => true\n *\n * // After staging the file\n * await spawn('git', ['add', 'src/foo.ts'])\n * const unstaged = await isUnstaged('src/foo.ts')\n * // => false\n *\n * // Check directory\n * const unstaged = await isUnstaged('src/')\n * // => true (if any file in src/ has unstaged changes)\n * ```\n */\nexport async function isUnstaged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getUnstagedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has unstaged changes.\n *\n * Synchronous version of `isUnstaged()`. Checks if the given pathname has\n * modifications that are not yet staged for commit (changes not added with\n * `git add`). Does NOT include:\n * - Staged changes (already added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory has\n * unstaged changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns `true` if path has unstaged changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file has unstaged changes\n * const unstaged = isUnstagedSync('src/foo.ts')\n * // => true\n *\n * // After staging the file\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const unstaged = isUnstagedSync('src/foo.ts')\n * // => false\n *\n * // Check directory\n * const unstaged = isUnstagedSync('src/')\n * // => true (if any file in src/ has unstaged changes)\n * ```\n */\nexport function isUnstagedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getUnstagedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory is staged for commit.\n *\n * Checks if the given pathname has changes staged with `git add` that will\n * be included in the next commit. Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory is staged.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns Promise resolving to `true` if path is staged, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is staged\n * const staged = await isStaged('src/foo.ts')\n * // => false\n *\n * // Stage the file\n * await spawn('git', ['add', 'src/foo.ts'])\n * const staged = await isStaged('src/foo.ts')\n * // => true\n *\n * // Check directory\n * const staged = await isStaged('src/')\n * // => true (if any file in src/ is staged)\n * ```\n */\nexport async function isStaged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getStagedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory is staged for commit.\n *\n * Synchronous version of `isStaged()`. Checks if the given pathname has\n * changes staged with `git add` that will be included in the next commit.\n * Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory is staged.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns `true` if path is staged, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is staged\n * const staged = isStagedSync('src/foo.ts')\n * // => false\n *\n * // Stage the file\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const staged = isStagedSync('src/foo.ts')\n * // => true\n *\n * // Check directory\n * const staged = isStagedSync('src/')\n * // => true (if any file in src/ is staged)\n * ```\n */\nexport function isStagedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getStagedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n"],
5
- "mappings": "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",
6
- "names": ["git_exports", "__export", "findGitRoot", "getChangedFiles", "getChangedFilesSync", "getStagedFiles", "getStagedFilesSync", "getUnstagedFiles", "getUnstagedFilesSync", "isChanged", "isChangedSync", "isStaged", "isStagedSync", "isUnstaged", "isUnstagedSync", "__toCommonJS", "import_node_path", "import_platform", "import_debug", "import_globs", "import_path", "import_spawn", "import_strings", "gitDiffCache", "_fs", "getFs", "_path", "getPath", "getGitPath", "getCwd", "getGitDiffSpawnArgs", "cwd", "resolvedCwd", "innerDiff", "args", "options", "cache", "parseOptions", "cacheKey", "result", "spawnResult", "stdout", "spawnCwd", "parseGitDiffStdout", "e", "innerDiffSync", "startPath", "fs", "path", "currentPath", "gitPath", "parentPath", "defaultRoot", "absolute", "cwdOption", "porcelain", "matcherOptions", "rootPath", "rawFiles", "line", "files", "relPath", "matcher", "filtered", "filepath", "pathname", "resolvedPathname", "baseCwd", "relativePath"]
4
+ "sourcesContent": ["import path from 'path'\n\nimport { WIN32 } from '#constants/platform'\nimport { debugNs } from './debug'\nimport { getGlobMatcher } from './globs'\nimport { normalizePath } from './path'\nimport { spawn, spawnSync } from './spawn'\nimport { stripAnsi } from './strings'\n\n/**\n * Options for git diff operations.\n *\n * Controls how git diff results are processed and returned.\n *\n * @example\n * ```typescript\n * // Get absolute file paths\n * const files = await getChangedFiles({ absolute: true })\n * // => ['/path/to/repo/src/file.ts']\n *\n * // Get relative paths with caching disabled\n * const files = await getChangedFiles({ cache: false })\n * // => ['src/file.ts']\n *\n * // Get files from specific directory\n * const files = await getChangedFiles({ cwd: '/path/to/repo/src' })\n * ```\n */\nexport interface GitDiffOptions {\n /**\n * Return absolute file paths instead of relative paths.\n *\n * @default false\n */\n absolute?: boolean | undefined\n /**\n * Cache git diff results to avoid repeated git subprocess calls.\n *\n * Caching is keyed by the git command and options used, so different\n * option combinations maintain separate cache entries.\n *\n * @default true\n */\n cache?: boolean | undefined\n /**\n * Working directory for git operations.\n *\n * Git operations will be run from this directory, and returned paths\n * will be relative to the git repository root. Symlinks are resolved\n * using `fs.realpathSync()`.\n *\n * @default process.cwd()\n */\n cwd?: string | undefined\n /**\n * Parse git porcelain format output (status codes like `M`, `A`, `??`).\n *\n * When `true`, strips the two-character status code and space from the\n * beginning of each line. Automatically enabled for `getChangedFiles()`.\n *\n * @default false\n */\n porcelain?: boolean | undefined\n /**\n * Return results as a `Set` instead of an array.\n *\n * @default false\n */\n asSet?: boolean | undefined\n /**\n * Additional options passed to glob matcher.\n *\n * Supports options like `dot`, `ignore`, `nocase` for filtering results.\n */\n [key: string]: unknown\n}\n\n/**\n * Options for filtering packages by git changes.\n *\n * Used to determine which packages in a monorepo have changed files.\n *\n * @example\n * ```typescript\n * // Filter packages with changes\n * const changed = filterPackagesByChanges(packages)\n *\n * // Force include all packages\n * const all = filterPackagesByChanges(packages, { force: true })\n *\n * // Use custom package key\n * const changed = filterPackagesByChanges(\n * packages,\n * { packageKey: 'directory' }\n * )\n * ```\n */\nexport interface FilterPackagesByChangesOptions {\n /**\n * Force include all packages regardless of changes.\n *\n * @default false\n */\n force?: boolean | undefined\n /**\n * Key to access package path in package objects.\n *\n * @default 'path'\n */\n packageKey?: string | undefined\n /**\n * Additional options for filtering.\n */\n [key: string]: unknown\n}\n\ntype SpawnArgs = [string, string[], Record<string, unknown>]\n\ninterface GitDiffSpawnArgs {\n all: SpawnArgs\n unstaged: SpawnArgs\n staged: SpawnArgs\n}\n\nconst gitDiffCache = new Map<string, string[]>()\n\nlet _fs: typeof import('fs') | undefined\n/**\n * Lazily load the `fs` module to avoid Webpack errors.\n *\n * Uses non-`node:` prefixed require internally to prevent Webpack from\n * attempting to bundle Node.js built-in modules.\n *\n * @returns The Node.js `fs` module.\n *\n * @example\n * ```typescript\n * const fs = getFs()\n * const exists = fs.existsSync('/path/to/file')\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFs() {\n if (_fs === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _fs = /*@__PURE__*/ require('node:fs')\n }\n return _fs as typeof import('fs')\n}\n\nlet _path: typeof import('path') | undefined\n/**\n * Lazily load the `path` module to avoid Webpack errors.\n *\n * Uses non-`node:` prefixed require internally to prevent Webpack from\n * attempting to bundle Node.js built-in modules.\n *\n * @returns The Node.js `path` module.\n *\n * @example\n * ```typescript\n * const path = getPath()\n * const joined = path.join('/foo', 'bar')\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path as typeof import('path')\n}\n\n/**\n * Get the git executable path.\n *\n * Currently always returns `'git'`, relying on the system PATH to resolve\n * the git binary location. This may be extended in the future to support\n * custom git paths.\n *\n * @returns The git executable name or path.\n *\n * @example\n * ```typescript\n * const git = getGitPath()\n * // => 'git'\n * ```\n */\nfunction getGitPath(): string {\n return 'git'\n}\n\n/**\n * Get the current working directory for git operations.\n *\n * Returns the real path to handle symlinks correctly. This is important\n * because symlinked directories like `/tmp -> /private/tmp` can cause\n * path mismatches when comparing git output.\n *\n * @returns The resolved real path of `process.cwd()`.\n *\n * @example\n * ```typescript\n * const cwd = getCwd()\n * // In /tmp (symlink to /private/tmp):\n * // => '/private/tmp'\n * ```\n */\nfunction getCwd(): string {\n return getFs().realpathSync(process.cwd())\n}\n\n/**\n * Get spawn arguments for different git diff operations.\n *\n * Prepares argument arrays for `spawn()`/`spawnSync()` calls that retrieve:\n * - `all`: All changed files (staged, unstaged, untracked) via `git status --porcelain`\n * - `unstaged`: Unstaged modifications via `git diff --name-only`\n * - `staged`: Staged changes via `git diff --cached --name-only`\n *\n * Automatically resolves symlinks in the provided `cwd` and enables shell\n * mode on Windows for proper command execution.\n *\n * @param cwd - Working directory for git operations, defaults to `process.cwd()`.\n * @returns Object containing spawn arguments for all, unstaged, and staged operations.\n */\nfunction getGitDiffSpawnArgs(cwd?: string | undefined): GitDiffSpawnArgs {\n const resolvedCwd = cwd ? getFs().realpathSync(cwd) : getCwd()\n return {\n all: [\n getGitPath(),\n ['status', '--porcelain'],\n {\n cwd: resolvedCwd,\n shell: WIN32,\n },\n ],\n unstaged: [\n getGitPath(),\n ['diff', '--name-only'],\n {\n cwd: resolvedCwd,\n },\n ],\n staged: [\n getGitPath(),\n ['diff', '--cached', '--name-only'],\n {\n cwd: resolvedCwd,\n shell: WIN32,\n },\n ],\n }\n}\n\n/**\n * Execute git diff command asynchronously and parse results.\n *\n * Internal helper for async git operations. Handles caching, command execution,\n * and result parsing. Returns empty array on git command failure.\n *\n * @param args - Spawn arguments tuple `[command, args, options]`.\n * @param options - Git diff options for caching and parsing.\n * @returns Promise resolving to array of file paths.\n */\nasync function innerDiff(\n args: SpawnArgs,\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const { cache = true, ...parseOptions } = { __proto__: null, ...options }\n const cacheKey = cache ? JSON.stringify({ args, parseOptions }) : undefined\n if (cache && cacheKey) {\n const result = gitDiffCache.get(cacheKey)\n if (result) {\n return result\n }\n }\n let result: string[]\n try {\n // Use stdioString: false to get raw Buffer, then convert ourselves to preserve exact output.\n const spawnResult = await spawn(args[0], args[1], {\n ...args[2],\n stdioString: false,\n })\n const stdout = Buffer.isBuffer(spawnResult.stdout)\n ? spawnResult.stdout.toString('utf8')\n : String(spawnResult.stdout)\n // Extract spawn cwd from args to pass to parser\n const spawnCwd =\n typeof args[2]['cwd'] === 'string' ? args[2]['cwd'] : undefined\n result = parseGitDiffStdout(stdout, parseOptions, spawnCwd)\n } catch (e) {\n // Git command failed. This is expected if:\n // - Not in a git repository\n // - Git is not installed\n // - Permission issues accessing .git directory\n // Log warning in debug mode for troubleshooting.\n debugNs(\n 'git',\n `Git command failed (${args[0]} ${args[1].join(' ')}): ${(e as Error).message}`,\n )\n return []\n }\n if (cache && cacheKey) {\n gitDiffCache.set(cacheKey, result)\n }\n return result\n}\n\n/**\n * Execute git diff command synchronously and parse results.\n *\n * Internal helper for sync git operations. Handles caching, command execution,\n * and result parsing. Returns empty array on git command failure.\n *\n * @param args - Spawn arguments tuple `[command, args, options]`.\n * @param options - Git diff options for caching and parsing.\n * @returns Array of file paths.\n */\nfunction innerDiffSync(\n args: SpawnArgs,\n options?: GitDiffOptions | undefined,\n): string[] {\n const { cache = true, ...parseOptions } = { __proto__: null, ...options }\n const cacheKey = cache ? JSON.stringify({ args, parseOptions }) : undefined\n if (cache && cacheKey) {\n const result = gitDiffCache.get(cacheKey)\n if (result) {\n return result\n }\n }\n let result: string[]\n try {\n // Use stdioString: false to get raw Buffer, then convert ourselves to preserve exact output.\n const spawnResult = spawnSync(args[0], args[1], {\n ...args[2],\n stdioString: false,\n })\n const stdout = Buffer.isBuffer(spawnResult.stdout)\n ? spawnResult.stdout.toString('utf8')\n : String(spawnResult.stdout)\n // Extract spawn cwd from args to pass to parser\n const spawnCwd =\n typeof args[2]['cwd'] === 'string' ? args[2]['cwd'] : undefined\n result = parseGitDiffStdout(stdout, parseOptions, spawnCwd)\n } catch (e) {\n // Git command failed. This is expected if:\n // - Not in a git repository\n // - Git is not installed\n // - Permission issues accessing .git directory\n // Log warning in debug mode for troubleshooting.\n debugNs(\n 'git',\n `Git command failed (${args[0]} ${args[1].join(' ')}): ${(e as Error).message}`,\n )\n return []\n }\n if (cache && cacheKey) {\n gitDiffCache.set(cacheKey, result)\n }\n return result\n}\n\n/**\n * Find git repository root by walking up from the given directory.\n *\n * Searches for a `.git` directory or file by traversing parent directories\n * upward until found or filesystem root is reached. Returns the original path\n * if no git repository is found.\n *\n * This function is exported primarily for testing purposes.\n *\n * @param startPath - Directory path to start searching from.\n * @returns Git repository root path, or `startPath` if not found.\n *\n * @example\n * ```typescript\n * const root = findGitRoot('/path/to/repo/src/subdir')\n * // => '/path/to/repo'\n *\n * const notFound = findGitRoot('/not/a/repo')\n * // => '/not/a/repo'\n * ```\n */\nexport function findGitRoot(startPath: string): string {\n const fs = getFs()\n const path = getPath()\n let currentPath = startPath\n // Walk up the directory tree looking for .git\n while (true) {\n try {\n const gitPath = path.join(currentPath, '.git')\n if (fs.existsSync(gitPath)) {\n return currentPath\n }\n } catch {\n // Ignore errors and continue walking up\n }\n const parentPath = path.dirname(currentPath)\n // Stop if we've reached the root or can't go up anymore\n if (parentPath === currentPath) {\n // Return original path if no .git found\n return startPath\n }\n currentPath = parentPath\n }\n}\n\n/**\n * Parse git diff stdout output into file path array.\n *\n * Internal helper that processes raw git command output by:\n * 1. Finding git repository root from spawn cwd\n * 2. Stripping ANSI codes and splitting into lines\n * 3. Parsing porcelain format status codes if requested\n * 4. Normalizing and optionally making paths absolute\n * 5. Filtering paths based on cwd and glob options\n *\n * Git always returns paths relative to the repository root, regardless of\n * where the command was executed. This function handles the path resolution\n * correctly by finding the repo root and adjusting paths accordingly.\n *\n * @param stdout - Raw stdout from git command.\n * @param options - Git diff options for path processing.\n * @param spawnCwd - Working directory where git command was executed.\n * @returns Array of processed file paths.\n */\nfunction parseGitDiffStdout(\n stdout: string,\n options?: GitDiffOptions | undefined,\n spawnCwd?: string | undefined,\n): string[] {\n // Find git repo root from spawnCwd. Git always returns paths relative to the repo root,\n // not the cwd where it was run. So we need to find the repo root to correctly parse paths.\n const defaultRoot = spawnCwd ? findGitRoot(spawnCwd) : getCwd()\n const {\n absolute = false,\n cwd: cwdOption = defaultRoot,\n porcelain = false,\n ...matcherOptions\n } = { __proto__: null, ...options }\n // Resolve cwd to handle symlinks.\n const cwd =\n cwdOption === defaultRoot ? defaultRoot : getFs().realpathSync(cwdOption)\n const rootPath = defaultRoot\n // Split into lines without trimming to preserve leading spaces in porcelain format.\n let rawFiles = stdout\n ? stripAnsi(stdout)\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line)\n : []\n // Parse porcelain format: strip status codes.\n // Git status --porcelain format is: XY filename\n // where X and Y are single characters and there's a space before the filename.\n if (porcelain) {\n rawFiles = rawFiles.map(line => {\n // Status is first 2 chars, then space, then filename.\n return line.length > 3 ? line.substring(3) : line\n })\n }\n const files = absolute\n ? rawFiles.map(relPath => normalizePath(path.join(rootPath, relPath)))\n : rawFiles.map(relPath => normalizePath(relPath))\n if (cwd === rootPath) {\n return files\n }\n const relPath = normalizePath(path.relative(rootPath, cwd))\n const matcher = getGlobMatcher([`${relPath}/**`], {\n ...(matcherOptions as {\n dot?: boolean\n ignore?: string[]\n nocase?: boolean\n }),\n absolute,\n cwd: rootPath,\n } as {\n absolute?: boolean\n cwd?: string\n dot?: boolean\n ignore?: string[]\n nocase?: boolean\n })\n const filtered: string[] = []\n for (const filepath of files) {\n if (matcher(filepath)) {\n filtered.push(filepath)\n }\n }\n return filtered\n}\n\n/**\n * Get all changed files including staged, unstaged, and untracked files.\n *\n * Uses `git status --porcelain` which returns the full working tree status\n * with status codes:\n * - `M` - Modified\n * - `A` - Added\n * - `D` - Deleted\n * - `??` - Untracked\n * - `R` - Renamed\n * - `C` - Copied\n *\n * This is the most comprehensive check - captures everything that differs\n * from the last commit, including:\n * - Files modified and staged with `git add`\n * - Files modified but not staged\n * - New files not yet tracked by git\n *\n * Status codes are automatically stripped from the output.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of changed file paths.\n *\n * @example\n * ```typescript\n * // Get all changed files as relative paths\n * const files = await getChangedFiles()\n * // => ['src/foo.ts', 'src/bar.ts', 'newfile.ts']\n *\n * // Get absolute paths\n * const files = await getChangedFiles({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n *\n * // Get changed files in specific directory\n * const files = await getChangedFiles({ cwd: '/path/to/repo/src' })\n * // => ['foo.ts', 'bar.ts']\n * ```\n */\nexport async function getChangedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).all\n return await innerDiff(args, {\n __proto__: null,\n ...options,\n porcelain: true,\n })\n}\n\n/**\n * Get all changed files including staged, unstaged, and untracked files.\n *\n * Synchronous version of `getChangedFiles()`. Uses `git status --porcelain`\n * which returns the full working tree status with status codes:\n * - `M` - Modified\n * - `A` - Added\n * - `D` - Deleted\n * - `??` - Untracked\n * - `R` - Renamed\n * - `C` - Copied\n *\n * This is the most comprehensive check - captures everything that differs\n * from the last commit, including:\n * - Files modified and staged with `git add`\n * - Files modified but not staged\n * - New files not yet tracked by git\n *\n * Status codes are automatically stripped from the output.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of changed file paths.\n *\n * @example\n * ```typescript\n * // Get all changed files as relative paths\n * const files = getChangedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts', 'newfile.ts']\n *\n * // Get absolute paths\n * const files = getChangedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n *\n * // Get changed files in specific directory\n * const files = getChangedFilesSync({ cwd: '/path/to/repo/src' })\n * // => ['foo.ts', 'bar.ts']\n * ```\n */\nexport function getChangedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).all\n return innerDiffSync(args, {\n __proto__: null,\n ...options,\n porcelain: true,\n })\n}\n\n/**\n * Get unstaged modified files (changes not yet staged for commit).\n *\n * Uses `git diff --name-only` which returns only unstaged modifications\n * to tracked files. Does NOT include:\n * - Untracked files (new files not added to git)\n * - Staged changes (files added with `git add`)\n *\n * This is a focused check for uncommitted changes to existing tracked files.\n * Useful for detecting work-in-progress modifications before staging.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of unstaged file paths.\n *\n * @example\n * ```typescript\n * // Get unstaged files\n * const files = await getUnstagedFiles()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // After staging some files\n * await spawn('git', ['add', 'src/foo.ts'])\n * const files = await getUnstagedFiles()\n * // => ['src/bar.ts'] (foo.ts no longer included)\n *\n * // Get absolute paths\n * const files = await getUnstagedFiles({ absolute: true })\n * // => ['/path/to/repo/src/bar.ts']\n * ```\n */\nexport async function getUnstagedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).unstaged\n return await innerDiff(args, options)\n}\n\n/**\n * Get unstaged modified files (changes not yet staged for commit).\n *\n * Synchronous version of `getUnstagedFiles()`. Uses `git diff --name-only`\n * which returns only unstaged modifications to tracked files. Does NOT include:\n * - Untracked files (new files not added to git)\n * - Staged changes (files added with `git add`)\n *\n * This is a focused check for uncommitted changes to existing tracked files.\n * Useful for detecting work-in-progress modifications before staging.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of unstaged file paths.\n *\n * @example\n * ```typescript\n * // Get unstaged files\n * const files = getUnstagedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // After staging some files\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const files = getUnstagedFilesSync()\n * // => ['src/bar.ts'] (foo.ts no longer included)\n *\n * // Get absolute paths\n * const files = getUnstagedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/bar.ts']\n * ```\n */\nexport function getUnstagedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).unstaged\n return innerDiffSync(args, options)\n}\n\n/**\n * Get staged files ready for commit (changes added with `git add`).\n *\n * Uses `git diff --cached --name-only` which returns only staged changes.\n * Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not added to git)\n *\n * This is a focused check for what will be included in the next commit.\n * Useful for validating changes before committing or running pre-commit hooks.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Promise resolving to array of staged file paths.\n *\n * @example\n * ```typescript\n * // Get currently staged files\n * const files = await getStagedFiles()\n * // => ['src/foo.ts']\n *\n * // Stage more files\n * await spawn('git', ['add', 'src/bar.ts'])\n * const files = await getStagedFiles()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // Get absolute paths\n * const files = await getStagedFiles({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n * ```\n */\nexport async function getStagedFiles(\n options?: GitDiffOptions | undefined,\n): Promise<string[]> {\n const args = getGitDiffSpawnArgs(options?.cwd).staged\n return await innerDiff(args, options)\n}\n\n/**\n * Get staged files ready for commit (changes added with `git add`).\n *\n * Synchronous version of `getStagedFiles()`. Uses `git diff --cached --name-only`\n * which returns only staged changes. Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not added to git)\n *\n * This is a focused check for what will be included in the next commit.\n * Useful for validating changes before committing or running pre-commit hooks.\n *\n * @param options - Options controlling path format and filtering.\n * @returns Array of staged file paths.\n *\n * @example\n * ```typescript\n * // Get currently staged files\n * const files = getStagedFilesSync()\n * // => ['src/foo.ts']\n *\n * // Stage more files\n * spawnSync('git', ['add', 'src/bar.ts'])\n * const files = getStagedFilesSync()\n * // => ['src/foo.ts', 'src/bar.ts']\n *\n * // Get absolute paths\n * const files = getStagedFilesSync({ absolute: true })\n * // => ['/path/to/repo/src/foo.ts', ...]\n * ```\n */\nexport function getStagedFilesSync(\n options?: GitDiffOptions | undefined,\n): string[] {\n const args = getGitDiffSpawnArgs(options?.cwd).staged\n return innerDiffSync(args, options)\n}\n\n/**\n * Check if a file or directory has any git changes.\n *\n * Checks if the given pathname has any changes including:\n * - Staged modifications (added with `git add`)\n * - Unstaged modifications (not yet staged)\n * - Untracked status (new file/directory not in git)\n *\n * For directories, returns `true` if ANY file within the directory has changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git status check.\n * @returns Promise resolving to `true` if path has any changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is changed\n * const changed = await isChanged('src/foo.ts')\n * // => true\n *\n * // Check if directory has any changes\n * const changed = await isChanged('src/')\n * // => true (if any file in src/ is changed)\n *\n * // Check from different cwd\n * const changed = await isChanged(\n * '/path/to/repo/src/foo.ts',\n * { cwd: '/path/to/repo' }\n * )\n * ```\n */\nexport async function isChanged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getChangedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has any git changes.\n *\n * Synchronous version of `isChanged()`. Checks if the given pathname has\n * any changes including:\n * - Staged modifications (added with `git add`)\n * - Unstaged modifications (not yet staged)\n * - Untracked status (new file/directory not in git)\n *\n * For directories, returns `true` if ANY file within the directory has changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git status check.\n * @returns `true` if path has any changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is changed\n * const changed = isChangedSync('src/foo.ts')\n * // => true\n *\n * // Check if directory has any changes\n * const changed = isChangedSync('src/')\n * // => true (if any file in src/ is changed)\n *\n * // Check from different cwd\n * const changed = isChangedSync(\n * '/path/to/repo/src/foo.ts',\n * { cwd: '/path/to/repo' }\n * )\n * ```\n */\nexport function isChangedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getChangedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has unstaged changes.\n *\n * Checks if the given pathname has modifications that are not yet staged\n * for commit (changes not added with `git add`). Does NOT include:\n * - Staged changes (already added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory has\n * unstaged changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns Promise resolving to `true` if path has unstaged changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file has unstaged changes\n * const unstaged = await isUnstaged('src/foo.ts')\n * // => true\n *\n * // After staging the file\n * await spawn('git', ['add', 'src/foo.ts'])\n * const unstaged = await isUnstaged('src/foo.ts')\n * // => false\n *\n * // Check directory\n * const unstaged = await isUnstaged('src/')\n * // => true (if any file in src/ has unstaged changes)\n * ```\n */\nexport async function isUnstaged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getUnstagedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory has unstaged changes.\n *\n * Synchronous version of `isUnstaged()`. Checks if the given pathname has\n * modifications that are not yet staged for commit (changes not added with\n * `git add`). Does NOT include:\n * - Staged changes (already added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory has\n * unstaged changes.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns `true` if path has unstaged changes, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file has unstaged changes\n * const unstaged = isUnstagedSync('src/foo.ts')\n * // => true\n *\n * // After staging the file\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const unstaged = isUnstagedSync('src/foo.ts')\n * // => false\n *\n * // Check directory\n * const unstaged = isUnstagedSync('src/')\n * // => true (if any file in src/ has unstaged changes)\n * ```\n */\nexport function isUnstagedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getUnstagedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory is staged for commit.\n *\n * Checks if the given pathname has changes staged with `git add` that will\n * be included in the next commit. Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory is staged.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns Promise resolving to `true` if path is staged, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is staged\n * const staged = await isStaged('src/foo.ts')\n * // => false\n *\n * // Stage the file\n * await spawn('git', ['add', 'src/foo.ts'])\n * const staged = await isStaged('src/foo.ts')\n * // => true\n *\n * // Check directory\n * const staged = await isStaged('src/')\n * // => true (if any file in src/ is staged)\n * ```\n */\nexport async function isStaged(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): Promise<boolean> {\n const files = await getStagedFiles({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n\n/**\n * Check if a file or directory is staged for commit.\n *\n * Synchronous version of `isStaged()`. Checks if the given pathname has\n * changes staged with `git add` that will be included in the next commit.\n * Does NOT include:\n * - Unstaged modifications (changes not added with `git add`)\n * - Untracked files (new files not in git)\n *\n * For directories, returns `true` if ANY file within the directory is staged.\n *\n * Symlinks in the pathname and cwd are automatically resolved using\n * `fs.realpathSync()` before comparison.\n *\n * @param pathname - File or directory path to check.\n * @param options - Options for the git diff check.\n * @returns `true` if path is staged, `false` otherwise.\n *\n * @example\n * ```typescript\n * // Check if file is staged\n * const staged = isStagedSync('src/foo.ts')\n * // => false\n *\n * // Stage the file\n * spawnSync('git', ['add', 'src/foo.ts'])\n * const staged = isStagedSync('src/foo.ts')\n * // => true\n *\n * // Check directory\n * const staged = isStagedSync('src/')\n * // => true (if any file in src/ is staged)\n * ```\n */\nexport function isStagedSync(\n pathname: string,\n options?: GitDiffOptions | undefined,\n): boolean {\n const files = getStagedFilesSync({\n __proto__: null,\n ...options,\n absolute: false,\n })\n // Resolve pathname to handle symlinks before computing relative path.\n const resolvedPathname = getFs().realpathSync(pathname)\n const baseCwd = options?.cwd ? getFs().realpathSync(options['cwd']) : getCwd()\n const relativePath = normalizePath(path.relative(baseCwd, resolvedPathname))\n return files.includes(relativePath)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["git_exports", "__export", "findGitRoot", "getChangedFiles", "getChangedFilesSync", "getStagedFiles", "getStagedFilesSync", "getUnstagedFiles", "getUnstagedFilesSync", "isChanged", "isChangedSync", "isStaged", "isStagedSync", "isUnstaged", "isUnstagedSync", "__toCommonJS", "import_path", "import_platform", "import_debug", "import_globs", "import_spawn", "import_strings", "gitDiffCache", "_fs", "getFs", "_path", "getPath", "getGitPath", "getCwd", "getGitDiffSpawnArgs", "cwd", "resolvedCwd", "innerDiff", "args", "options", "cache", "parseOptions", "cacheKey", "result", "spawnResult", "stdout", "spawnCwd", "parseGitDiffStdout", "e", "innerDiffSync", "startPath", "fs", "path", "currentPath", "gitPath", "parentPath", "defaultRoot", "absolute", "cwdOption", "porcelain", "matcherOptions", "rootPath", "rawFiles", "line", "files", "relPath", "matcher", "filtered", "filepath", "pathname", "resolvedPathname", "baseCwd", "relativePath"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  /* Socket Lib - Built with esbuild */
2
- var T=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var S=(o,r)=>{for(var t in r)T(o,t,{get:r[t],enumerable:!0})},P=(o,r,t,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of _(r))!N.call(o,i)&&i!==t&&T(o,i,{get:()=>r[i],enumerable:!(d=q(r,i))||d.enumerable});return o};var U=o=>P(T({},"__esModule",{value:!0}),o);var G={};S(G,{httpDownload:()=>$,httpGetJson:()=>M,httpGetText:()=>v,httpRequest:()=>O});module.exports=U(G);var b=require("node:fs");let R,H;function k(){return R===void 0&&(R=require("node:http")),R}function x(){return H===void 0&&(H=require("node:https")),H}async function O(o,r){const{body:t,followRedirects:d=!0,headers:i={},maxRedirects:m=5,method:y="GET",retries:a=0,retryDelay:u=1e3,timeout:h=3e4}={__proto__:null,...r};let f;for(let w=0;w<=a;w++)try{return await C(o,{body:t,followRedirects:d,headers:i,maxRedirects:m,method:y,timeout:h})}catch(p){if(f=p,w===a)break;const E=u*2**w;await new Promise(c=>setTimeout(c,E))}throw f||new Error("Request failed after retries")}async function C(o,r){const{body:t,followRedirects:d=!0,headers:i={},maxRedirects:m=5,method:y="GET",timeout:a=3e4}={__proto__:null,...r};return await new Promise((u,h)=>{const f=new URL(o),p=f.protocol==="https:"?x():k(),E={headers:{"User-Agent":"socket-registry/1.0",...i},hostname:f.hostname,method:y,path:f.pathname+f.search,port:f.port,timeout:a},c=p.request(E,n=>{if(d&&n.statusCode&&n.statusCode>=300&&n.statusCode<400&&n.headers.location){if(m<=0){h(new Error(`Too many redirects (exceeded maximum: ${m})`));return}const e=n.headers.location.startsWith("http")?n.headers.location:new URL(n.headers.location,o).toString();u(C(e,{body:t,followRedirects:d,headers:i,maxRedirects:m-1,method:y,timeout:a}));return}const s=[];n.on("data",e=>{s.push(e)}),n.on("end",()=>{const e=Buffer.concat(s),l=n.statusCode!==void 0&&n.statusCode>=200&&n.statusCode<300,g={arrayBuffer(){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)},body:e,headers:n.headers,json(){return JSON.parse(e.toString("utf8"))},ok:l,status:n.statusCode||0,statusText:n.statusMessage||"",text(){return e.toString("utf8")}};u(g)})});c.on("error",n=>{const s=n.code;let e=`HTTP request failed for ${o}: ${n.message}
2
+ var T=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var S=(o,r)=>{for(var t in r)T(o,t,{get:r[t],enumerable:!0})},P=(o,r,t,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of _(r))!N.call(o,i)&&i!==t&&T(o,i,{get:()=>r[i],enumerable:!(d=q(r,i))||d.enumerable});return o};var U=o=>P(T({},"__esModule",{value:!0}),o);var G={};S(G,{httpDownload:()=>$,httpGetJson:()=>M,httpGetText:()=>v,httpRequest:()=>O});module.exports=U(G);var b=require("fs");let R,H;function k(){return R===void 0&&(R=require("node:http")),R}function x(){return H===void 0&&(H=require("node:https")),H}async function O(o,r){const{body:t,followRedirects:d=!0,headers:i={},maxRedirects:m=5,method:y="GET",retries:a=0,retryDelay:u=1e3,timeout:h=3e4}={__proto__:null,...r};let f;for(let w=0;w<=a;w++)try{return await C(o,{body:t,followRedirects:d,headers:i,maxRedirects:m,method:y,timeout:h})}catch(p){if(f=p,w===a)break;const E=u*2**w;await new Promise(c=>setTimeout(c,E))}throw f||new Error("Request failed after retries")}async function C(o,r){const{body:t,followRedirects:d=!0,headers:i={},maxRedirects:m=5,method:y="GET",timeout:a=3e4}={__proto__:null,...r};return await new Promise((u,h)=>{const f=new URL(o),p=f.protocol==="https:"?x():k(),E={headers:{"User-Agent":"socket-registry/1.0",...i},hostname:f.hostname,method:y,path:f.pathname+f.search,port:f.port,timeout:a},c=p.request(E,n=>{if(d&&n.statusCode&&n.statusCode>=300&&n.statusCode<400&&n.headers.location){if(m<=0){h(new Error(`Too many redirects (exceeded maximum: ${m})`));return}const e=n.headers.location.startsWith("http")?n.headers.location:new URL(n.headers.location,o).toString();u(C(e,{body:t,followRedirects:d,headers:i,maxRedirects:m-1,method:y,timeout:a}));return}const s=[];n.on("data",e=>{s.push(e)}),n.on("end",()=>{const e=Buffer.concat(s),l=n.statusCode!==void 0&&n.statusCode>=200&&n.statusCode<300,g={arrayBuffer(){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)},body:e,headers:n.headers,json(){return JSON.parse(e.toString("utf8"))},ok:l,status:n.statusCode||0,statusText:n.statusMessage||"",text(){return e.toString("utf8")}};u(g)})});c.on("error",n=>{const s=n.code;let e=`HTTP request failed for ${o}: ${n.message}
3
3
  `;s==="ENOTFOUND"?e+="DNS lookup failed. Check the hostname and your network connection.":s==="ECONNREFUSED"?e+="Connection refused. Verify the server is running and accessible.":s==="ETIMEDOUT"?e+="Request timed out. Check your network or increase the timeout value.":s==="ECONNRESET"?e+="Connection reset. The server may have closed the connection unexpectedly.":e+="Check your network connection and verify the URL is correct.",h(new Error(e,{cause:n}))}),c.on("timeout",()=>{c.destroy(),h(new Error(`Request timed out after ${a}ms`))}),t&&c.write(t),c.end()})}async function $(o,r,t){const{headers:d={},onProgress:i,retries:m=0,retryDelay:y=1e3,timeout:a=12e4}={__proto__:null,...t};let u;for(let h=0;h<=m;h++)try{return await B(o,r,{headers:d,onProgress:i,timeout:a})}catch(f){if(u=f,h===m)break;const w=y*2**h;await new Promise(p=>setTimeout(p,w))}throw u||new Error("Download failed after retries")}async function B(o,r,t){const{headers:d={},onProgress:i,timeout:m=12e4}={__proto__:null,...t};return await new Promise((y,a)=>{const u=new URL(o),f=u.protocol==="https:"?x():k(),w={headers:{"User-Agent":"socket-registry/1.0",...d},hostname:u.hostname,method:"GET",path:u.pathname+u.search,port:u.port,timeout:m};let p,E=!1;const c=()=>{!E&&p&&(E=!0,p.close())},n=f.request(w,s=>{if(!s.statusCode||s.statusCode<200||s.statusCode>=300){c(),a(new Error(`Download failed: HTTP ${s.statusCode} ${s.statusMessage}`));return}const e=Number.parseInt(s.headers["content-length"]||"0",10);let l=0;p=(0,b.createWriteStream)(r),p.on("error",g=>{c();const D=new Error(`Failed to write file: ${g.message}`,{cause:g});a(D)}),s.on("data",g=>{l+=g.length,i&&e>0&&i(l,e)}),s.on("end",()=>{p?.close(()=>{E=!0,y({path:r,size:l})})}),s.on("error",g=>{c(),a(g)}),s.pipe(p)});n.on("error",s=>{c();const e=s.code;let l=`HTTP download failed for ${o}: ${s.message}
4
4
  `;e==="ENOTFOUND"?l+="DNS lookup failed. Check the hostname and your network connection.":e==="ECONNREFUSED"?l+="Connection refused. Verify the server is running and accessible.":e==="ETIMEDOUT"?l+="Request timed out. Check your network or increase the timeout value.":e==="ECONNRESET"?l+="Connection reset. The server may have closed the connection unexpectedly.":l+="Check your network connection and verify the URL is correct.",a(new Error(l,{cause:s}))}),n.on("timeout",()=>{n.destroy(),c(),a(new Error(`Download timed out after ${m}ms`))}),n.end()})}async function M(o,r){const t=await O(o,{...r,method:"GET"});if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);try{return t.json()}catch(d){throw new Error("Failed to parse JSON response",{cause:d})}}async function v(o,r){const t=await O(o,{...r,method:"GET"});if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);return t.text()}0&&(module.exports={httpDownload,httpGetJson,httpGetText,httpRequest});
5
5
  //# sourceMappingURL=http-request.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/http-request.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview HTTP/HTTPS request utilities using Node.js built-in modules with retry logic, redirects, and download support.\n *\n * This module provides a fetch-like API built on top of Node.js native `http` and `https` modules.\n * It supports automatic retries with exponential backoff, redirect following, streaming downloads,\n * and provides a familiar fetch-style response interface.\n *\n * Key Features:\n * - Automatic retries with exponential backoff for failed requests.\n * - Redirect following with configurable max redirects.\n * - Streaming downloads with progress callbacks.\n * - Fetch-like response interface (`.json()`, `.text()`, `.arrayBuffer()`).\n * - Timeout support for all operations.\n * - Zero dependencies on external HTTP libraries.\n */\n\nimport { createWriteStream } from 'node:fs'\n\nimport type { IncomingMessage } from 'node:http'\n\nlet _http: typeof import('http') | undefined\nlet _https: typeof import('https') | undefined\n/**\n * Lazily load http and https modules to avoid Webpack errors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getHttp() {\n if (_http === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _http = /*@__PURE__*/ require('node:http')\n }\n return _http as typeof import('http')\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction getHttps() {\n if (_https === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _https = /*@__PURE__*/ require('node:https')\n }\n return _https as typeof import('https')\n}\n\n/**\n * Configuration options for HTTP/HTTPS requests.\n */\nexport interface HttpRequestOptions {\n /**\n * Request body to send.\n * Can be a string (e.g., JSON) or Buffer (e.g., binary data).\n *\n * @example\n * ```ts\n * // Send JSON data\n * await httpRequest('https://api.example.com/data', {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Alice' }),\n * headers: { 'Content-Type': 'application/json' }\n * })\n *\n * // Send binary data\n * const buffer = Buffer.from([0x00, 0x01, 0x02])\n * await httpRequest('https://api.example.com/upload', {\n * method: 'POST',\n * body: buffer\n * })\n * ```\n */\n body?: Buffer | string | undefined\n /**\n * Whether to automatically follow HTTP redirects (3xx status codes).\n *\n * @default true\n *\n * @example\n * ```ts\n * // Follow redirects (default)\n * await httpRequest('https://example.com/redirect')\n *\n * // Don't follow redirects\n * const response = await httpRequest('https://example.com/redirect', {\n * followRedirects: false\n * })\n * console.log(response.status) // 301 or 302\n * ```\n */\n followRedirects?: boolean | undefined\n /**\n * HTTP headers to send with the request.\n * A `User-Agent` header is automatically added if not provided.\n *\n * @example\n * ```ts\n * await httpRequest('https://api.example.com/data', {\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'Content-Type': 'application/json',\n * 'Accept': 'application/json'\n * }\n * })\n * ```\n */\n headers?: Record<string, string> | undefined\n /**\n * Maximum number of redirects to follow before throwing an error.\n * Only relevant when `followRedirects` is `true`.\n *\n * @default 5\n *\n * @example\n * ```ts\n * // Allow up to 10 redirects\n * await httpRequest('https://example.com/many-redirects', {\n * maxRedirects: 10\n * })\n * ```\n */\n maxRedirects?: number | undefined\n /**\n * HTTP method to use for the request.\n *\n * @default 'GET'\n *\n * @example\n * ```ts\n * // GET request (default)\n * await httpRequest('https://api.example.com/data')\n *\n * // POST request\n * await httpRequest('https://api.example.com/data', {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Alice' })\n * })\n *\n * // DELETE request\n * await httpRequest('https://api.example.com/data/123', {\n * method: 'DELETE'\n * })\n * ```\n */\n method?: string | undefined\n /**\n * Number of retry attempts for failed requests.\n * Uses exponential backoff: delay = `retryDelay` * 2^attempt.\n *\n * @default 0\n *\n * @example\n * ```ts\n * // Retry up to 3 times with exponential backoff\n * await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000 // 1s, then 2s, then 4s\n * })\n * ```\n */\n retries?: number | undefined\n /**\n * Initial delay in milliseconds before first retry.\n * Subsequent retries use exponential backoff.\n *\n * @default 1000\n *\n * @example\n * ```ts\n * // Start with 2 second delay, then 4s, 8s, etc.\n * await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 2000\n * })\n * ```\n */\n retryDelay?: number | undefined\n /**\n * Request timeout in milliseconds.\n * If the request takes longer than this, it will be aborted.\n *\n * @default 30000\n *\n * @example\n * ```ts\n * // 60 second timeout\n * await httpRequest('https://api.example.com/slow-endpoint', {\n * timeout: 60000\n * })\n * ```\n */\n timeout?: number | undefined\n}\n\n/**\n * HTTP response object with fetch-like interface.\n * Provides multiple ways to access the response body.\n */\nexport interface HttpResponse {\n /**\n * Get response body as ArrayBuffer.\n * Useful for binary data or when you need compatibility with browser APIs.\n *\n * @returns The response body as an ArrayBuffer\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/image.png')\n * const arrayBuffer = response.arrayBuffer()\n * console.log(arrayBuffer.byteLength)\n * ```\n */\n arrayBuffer(): ArrayBuffer\n /**\n * Raw response body as Buffer.\n * Direct access to the underlying Node.js Buffer.\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/data')\n * console.log(response.body.length) // Size in bytes\n * console.log(response.body.toString('hex')) // View as hex\n * ```\n */\n body: Buffer\n /**\n * HTTP response headers.\n * Keys are lowercase header names, values can be strings or string arrays.\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.headers['content-type'])\n * console.log(response.headers['set-cookie']) // May be string[]\n * ```\n */\n headers: Record<string, string | string[] | undefined>\n /**\n * Parse response body as JSON.\n * Type parameter `T` allows specifying the expected JSON structure.\n *\n * @template T - Expected JSON type (defaults to `unknown`)\n * @returns Parsed JSON data\n * @throws {SyntaxError} When response body is not valid JSON\n *\n * @example\n * ```ts\n * interface User { name: string; id: number }\n * const response = await httpRequest('https://api.example.com/user')\n * const user = response.json<User>()\n * console.log(user.name, user.id)\n * ```\n */\n json<T = unknown>(): T\n /**\n * Whether the request was successful (status code 200-299).\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/data')\n * if (response.ok) {\n * console.log('Success:', response.json())\n * } else {\n * console.error('Failed:', response.status, response.statusText)\n * }\n * ```\n */\n ok: boolean\n /**\n * HTTP status code (e.g., 200, 404, 500).\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.status) // 200, 404, etc.\n * ```\n */\n status: number\n /**\n * HTTP status message (e.g., \"OK\", \"Not Found\", \"Internal Server Error\").\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.statusText) // \"OK\"\n * ```\n */\n statusText: string\n /**\n * Get response body as UTF-8 text string.\n *\n * @returns The response body as a string\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * const html = response.text()\n * console.log(html.includes('<html>'))\n * ```\n */\n text(): string\n}\n\n/**\n * Configuration options for file downloads.\n */\nexport interface HttpDownloadOptions {\n /**\n * HTTP headers to send with the download request.\n * A `User-Agent` header is automatically added if not provided.\n *\n * @example\n * ```ts\n * await httpDownload('https://example.com/file.zip', '/tmp/file.zip', {\n * headers: {\n * 'Authorization': 'Bearer token123'\n * }\n * })\n * ```\n */\n headers?: Record<string, string> | undefined\n /**\n * Callback for tracking download progress.\n * Called periodically as data is received.\n *\n * @param downloaded - Number of bytes downloaded so far\n * @param total - Total file size in bytes (from Content-Length header)\n *\n * @example\n * ```ts\n * await httpDownload('https://example.com/large-file.zip', '/tmp/file.zip', {\n * onProgress: (downloaded, total) => {\n * const percent = ((downloaded / total) * 100).toFixed(1)\n * console.log(`Progress: ${percent}%`)\n * }\n * })\n * ```\n */\n onProgress?: ((downloaded: number, total: number) => void) | undefined\n /**\n * Number of retry attempts for failed downloads.\n * Uses exponential backoff: delay = `retryDelay` * 2^attempt.\n *\n * @default 0\n *\n * @example\n * ```ts\n * // Retry up to 3 times for unreliable connections\n * await httpDownload('https://example.com/file.zip', '/tmp/file.zip', {\n * retries: 3,\n * retryDelay: 2000\n * })\n * ```\n */\n retries?: number | undefined\n /**\n * Initial delay in milliseconds before first retry.\n * Subsequent retries use exponential backoff.\n *\n * @default 1000\n */\n retryDelay?: number | undefined\n /**\n * Download timeout in milliseconds.\n * If the download takes longer than this, it will be aborted.\n *\n * @default 120000\n *\n * @example\n * ```ts\n * // 5 minute timeout for large files\n * await httpDownload('https://example.com/huge-file.zip', '/tmp/file.zip', {\n * timeout: 300000\n * })\n * ```\n */\n timeout?: number | undefined\n}\n\n/**\n * Result of a successful file download.\n */\nexport interface HttpDownloadResult {\n /**\n * Absolute path where the file was saved.\n *\n * @example\n * ```ts\n * const result = await httpDownload('https://example.com/file.zip', '/tmp/file.zip')\n * console.log(`Downloaded to: ${result.path}`)\n * ```\n */\n path: string\n /**\n * Total size of downloaded file in bytes.\n *\n * @example\n * ```ts\n * const result = await httpDownload('https://example.com/file.zip', '/tmp/file.zip')\n * console.log(`Downloaded ${result.size} bytes`)\n * ```\n */\n size: number\n}\n\n/**\n * Make an HTTP/HTTPS request with retry logic and redirect support.\n * Provides a fetch-like API using Node.js native http/https modules.\n *\n * This is the main entry point for making HTTP requests. It handles retries,\n * redirects, timeouts, and provides a fetch-compatible response interface.\n *\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to response object with `.json()`, `.text()`, etc.\n * @throws {Error} When all retries are exhausted, timeout occurs, or non-retryable error happens\n *\n * @example\n * ```ts\n * // Simple GET request\n * const response = await httpRequest('https://api.example.com/data')\n * const data = response.json()\n *\n * // POST with JSON body\n * const response = await httpRequest('https://api.example.com/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice', email: 'alice@example.com' })\n * })\n *\n * // With retries and timeout\n * const response = await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000,\n * timeout: 60000\n * })\n *\n * // Don't follow redirects\n * const response = await httpRequest('https://example.com/redirect', {\n * followRedirects: false\n * })\n * console.log(response.status) // 301, 302, etc.\n * ```\n */\nexport async function httpRequest(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<HttpResponse> {\n const {\n body,\n followRedirects = true,\n headers = {},\n maxRedirects = 5,\n method = 'GET',\n retries = 0,\n retryDelay = 1000,\n timeout = 30_000,\n } = { __proto__: null, ...options } as HttpRequestOptions\n\n // Retry logic with exponential backoff\n let lastError: Error | undefined\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await httpRequestAttempt(url, {\n body,\n followRedirects,\n headers,\n maxRedirects,\n method,\n timeout,\n })\n } catch (e) {\n lastError = e as Error\n\n // Last attempt - throw error\n if (attempt === retries) {\n break\n }\n\n // Retry with exponential backoff\n const delayMs = retryDelay * 2 ** attempt\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, delayMs))\n }\n }\n\n throw lastError || new Error('Request failed after retries')\n}\n\n/**\n * Single HTTP request attempt (used internally by httpRequest with retry logic).\n * @private\n */\nasync function httpRequestAttempt(\n url: string,\n options: HttpRequestOptions,\n): Promise<HttpResponse> {\n const {\n body,\n followRedirects = true,\n headers = {},\n maxRedirects = 5,\n method = 'GET',\n timeout = 30_000,\n } = { __proto__: null, ...options } as HttpRequestOptions\n\n return await new Promise((resolve, reject) => {\n const parsedUrl = new URL(url)\n const isHttps = parsedUrl.protocol === 'https:'\n const httpModule = isHttps ? getHttps() : getHttp()\n\n const requestOptions = {\n headers: {\n 'User-Agent': 'socket-registry/1.0',\n ...headers,\n },\n hostname: parsedUrl.hostname,\n method,\n path: parsedUrl.pathname + parsedUrl.search,\n port: parsedUrl.port,\n timeout,\n }\n\n const request = httpModule.request(\n requestOptions,\n (res: IncomingMessage) => {\n // Handle redirects\n if (\n followRedirects &&\n res.statusCode &&\n res.statusCode >= 300 &&\n res.statusCode < 400 &&\n res.headers.location\n ) {\n if (maxRedirects <= 0) {\n reject(\n new Error(\n `Too many redirects (exceeded maximum: ${maxRedirects})`,\n ),\n )\n return\n }\n\n // Follow redirect\n const redirectUrl = res.headers.location.startsWith('http')\n ? res.headers.location\n : new URL(res.headers.location, url).toString()\n\n resolve(\n httpRequestAttempt(redirectUrl, {\n body,\n followRedirects,\n headers,\n maxRedirects: maxRedirects - 1,\n method,\n timeout,\n }),\n )\n return\n }\n\n // Collect response data\n const chunks: Buffer[] = []\n res.on('data', (chunk: Buffer) => {\n chunks.push(chunk)\n })\n\n res.on('end', () => {\n const responseBody = Buffer.concat(chunks)\n const ok =\n res.statusCode !== undefined &&\n res.statusCode >= 200 &&\n res.statusCode < 300\n\n const response: HttpResponse = {\n arrayBuffer(): ArrayBuffer {\n return responseBody.buffer.slice(\n responseBody.byteOffset,\n responseBody.byteOffset + responseBody.byteLength,\n )\n },\n body: responseBody,\n headers: res.headers as Record<\n string,\n string | string[] | undefined\n >,\n json<T = unknown>(): T {\n return JSON.parse(responseBody.toString('utf8')) as T\n },\n ok,\n status: res.statusCode || 0,\n statusText: res.statusMessage || '',\n text(): string {\n return responseBody.toString('utf8')\n },\n }\n\n resolve(response)\n })\n },\n )\n\n request.on('error', (error: Error) => {\n const code = (error as NodeJS.ErrnoException).code\n let message = `HTTP request failed for ${url}: ${error.message}\\n`\n\n if (code === 'ENOTFOUND') {\n message +=\n 'DNS lookup failed. Check the hostname and your network connection.'\n } else if (code === 'ECONNREFUSED') {\n message +=\n 'Connection refused. Verify the server is running and accessible.'\n } else if (code === 'ETIMEDOUT') {\n message +=\n 'Request timed out. Check your network or increase the timeout value.'\n } else if (code === 'ECONNRESET') {\n message +=\n 'Connection reset. The server may have closed the connection unexpectedly.'\n } else {\n message +=\n 'Check your network connection and verify the URL is correct.'\n }\n\n reject(new Error(message, { cause: error }))\n })\n\n request.on('timeout', () => {\n request.destroy()\n reject(new Error(`Request timed out after ${timeout}ms`))\n })\n\n // Send body if present\n if (body) {\n request.write(body)\n }\n\n request.end()\n })\n}\n\n/**\n * Download a file from a URL to a local path with retry logic and progress callbacks.\n * Uses streaming to avoid loading entire file in memory.\n *\n * The download is streamed directly to disk, making it memory-efficient even for\n * large files. Progress callbacks allow for real-time download status updates.\n *\n * @param url - The URL to download from (must start with http:// or https://)\n * @param destPath - Absolute path where the file should be saved\n * @param options - Download configuration options\n * @returns Promise resolving to download result with path and size\n * @throws {Error} When all retries are exhausted, download fails, or file cannot be written\n *\n * @example\n * ```ts\n * // Simple download\n * const result = await httpDownload(\n * 'https://example.com/file.zip',\n * '/tmp/file.zip'\n * )\n * console.log(`Downloaded ${result.size} bytes to ${result.path}`)\n *\n * // With progress tracking\n * await httpDownload(\n * 'https://example.com/large-file.zip',\n * '/tmp/file.zip',\n * {\n * onProgress: (downloaded, total) => {\n * const percent = ((downloaded / total) * 100).toFixed(1)\n * console.log(`Progress: ${percent}% (${downloaded}/${total} bytes)`)\n * }\n * }\n * )\n *\n * // With retries and custom timeout\n * await httpDownload(\n * 'https://example.com/file.zip',\n * '/tmp/file.zip',\n * {\n * retries: 3,\n * retryDelay: 2000,\n * timeout: 300000, // 5 minutes\n * headers: { 'Authorization': 'Bearer token123' }\n * }\n * )\n * ```\n */\nexport async function httpDownload(\n url: string,\n destPath: string,\n options?: HttpDownloadOptions | undefined,\n): Promise<HttpDownloadResult> {\n const {\n headers = {},\n onProgress,\n retries = 0,\n retryDelay = 1000,\n timeout = 120_000,\n } = { __proto__: null, ...options } as HttpDownloadOptions\n\n // Retry logic with exponential backoff\n let lastError: Error | undefined\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await httpDownloadAttempt(url, destPath, {\n headers,\n onProgress,\n timeout,\n })\n } catch (e) {\n lastError = e as Error\n\n // Last attempt - throw error\n if (attempt === retries) {\n break\n }\n\n // Retry with exponential backoff\n const delayMs = retryDelay * 2 ** attempt\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, delayMs))\n }\n }\n\n throw lastError || new Error('Download failed after retries')\n}\n\n/**\n * Single download attempt (used internally by httpDownload with retry logic).\n * @private\n */\nasync function httpDownloadAttempt(\n url: string,\n destPath: string,\n options: HttpDownloadOptions,\n): Promise<HttpDownloadResult> {\n const {\n headers = {},\n onProgress,\n timeout = 120_000,\n } = { __proto__: null, ...options } as HttpDownloadOptions\n\n return await new Promise((resolve, reject) => {\n const parsedUrl = new URL(url)\n const isHttps = parsedUrl.protocol === 'https:'\n const httpModule = isHttps ? getHttps() : getHttp()\n\n const requestOptions = {\n headers: {\n 'User-Agent': 'socket-registry/1.0',\n ...headers,\n },\n hostname: parsedUrl.hostname,\n method: 'GET',\n path: parsedUrl.pathname + parsedUrl.search,\n port: parsedUrl.port,\n timeout,\n }\n\n let fileStream: ReturnType<typeof createWriteStream> | undefined\n let streamClosed = false\n\n const closeStream = () => {\n if (!streamClosed && fileStream) {\n streamClosed = true\n fileStream.close()\n }\n }\n\n const request = httpModule.request(\n requestOptions,\n (res: IncomingMessage) => {\n // Check status code\n if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {\n closeStream()\n reject(\n new Error(\n `Download failed: HTTP ${res.statusCode} ${res.statusMessage}`,\n ),\n )\n return\n }\n\n const totalSize = Number.parseInt(\n res.headers['content-length'] || '0',\n 10,\n )\n let downloadedSize = 0\n\n // Create write stream\n fileStream = createWriteStream(destPath)\n\n fileStream.on('error', (error: Error) => {\n closeStream()\n const err = new Error(`Failed to write file: ${error.message}`, {\n cause: error,\n })\n reject(err)\n })\n\n res.on('data', (chunk: Buffer) => {\n downloadedSize += chunk.length\n if (onProgress && totalSize > 0) {\n onProgress(downloadedSize, totalSize)\n }\n })\n\n res.on('end', () => {\n fileStream?.close(() => {\n streamClosed = true\n resolve({\n path: destPath,\n size: downloadedSize,\n })\n })\n })\n\n res.on('error', (error: Error) => {\n closeStream()\n reject(error)\n })\n\n // Pipe response to file\n res.pipe(fileStream)\n },\n )\n\n request.on('error', (error: Error) => {\n closeStream()\n const code = (error as NodeJS.ErrnoException).code\n let message = `HTTP download failed for ${url}: ${error.message}\\n`\n\n if (code === 'ENOTFOUND') {\n message +=\n 'DNS lookup failed. Check the hostname and your network connection.'\n } else if (code === 'ECONNREFUSED') {\n message +=\n 'Connection refused. Verify the server is running and accessible.'\n } else if (code === 'ETIMEDOUT') {\n message +=\n 'Request timed out. Check your network or increase the timeout value.'\n } else if (code === 'ECONNRESET') {\n message +=\n 'Connection reset. The server may have closed the connection unexpectedly.'\n } else {\n message +=\n 'Check your network connection and verify the URL is correct.'\n }\n\n reject(new Error(message, { cause: error }))\n })\n\n request.on('timeout', () => {\n request.destroy()\n closeStream()\n reject(new Error(`Download timed out after ${timeout}ms`))\n })\n\n request.end()\n })\n}\n\n/**\n * Perform a GET request and parse JSON response.\n * Convenience wrapper around `httpRequest` for common JSON API calls.\n *\n * @template T - Expected JSON response type (defaults to `unknown`)\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to parsed JSON data\n * @throws {Error} When request fails, response is not ok (status < 200 or >= 300), or JSON parsing fails\n *\n * @example\n * ```ts\n * // Simple JSON GET\n * const data = await httpGetJson('https://api.example.com/data')\n * console.log(data)\n *\n * // With type safety\n * interface User { id: number; name: string; email: string }\n * const user = await httpGetJson<User>('https://api.example.com/user/123')\n * console.log(user.name, user.email)\n *\n * // With custom headers\n * const data = await httpGetJson('https://api.example.com/data', {\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'Accept': 'application/json'\n * }\n * })\n *\n * // With retries\n * const data = await httpGetJson('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000\n * })\n * ```\n */\nexport async function httpGetJson<T = unknown>(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<T> {\n const response = await httpRequest(url, { ...options, method: 'GET' })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n try {\n return response.json<T>()\n } catch (e) {\n throw new Error('Failed to parse JSON response', { cause: e })\n }\n}\n\n/**\n * Perform a GET request and return text response.\n * Convenience wrapper around `httpRequest` for fetching text content.\n *\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to response body as UTF-8 string\n * @throws {Error} When request fails or response is not ok (status < 200 or >= 300)\n *\n * @example\n * ```ts\n * // Fetch HTML\n * const html = await httpGetText('https://example.com')\n * console.log(html.includes('<!DOCTYPE html>'))\n *\n * // Fetch plain text\n * const text = await httpGetText('https://example.com/file.txt')\n * console.log(text)\n *\n * // With custom headers\n * const text = await httpGetText('https://example.com/data.txt', {\n * headers: {\n * 'Authorization': 'Bearer token123'\n * }\n * })\n *\n * // With timeout\n * const text = await httpGetText('https://example.com/large-file.txt', {\n * timeout: 60000 // 1 minute\n * })\n * ```\n */\nexport async function httpGetText(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<string> {\n const response = await httpRequest(url, { ...options, method: 'GET' })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n return response.text()\n}\n"],
5
- "mappings": "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",
6
- "names": ["http_request_exports", "__export", "httpDownload", "httpGetJson", "httpGetText", "httpRequest", "__toCommonJS", "import_node_fs", "_http", "_https", "getHttp", "getHttps", "url", "options", "body", "followRedirects", "headers", "maxRedirects", "method", "retries", "retryDelay", "timeout", "lastError", "attempt", "httpRequestAttempt", "e", "delayMs", "resolve", "reject", "parsedUrl", "httpModule", "requestOptions", "request", "res", "redirectUrl", "chunks", "chunk", "responseBody", "ok", "response", "error", "code", "message", "destPath", "onProgress", "httpDownloadAttempt", "fileStream", "streamClosed", "closeStream", "totalSize", "downloadedSize", "err"]
4
+ "sourcesContent": ["/**\n * @fileoverview HTTP/HTTPS request utilities using Node.js built-in modules with retry logic, redirects, and download support.\n *\n * This module provides a fetch-like API built on top of Node.js native `http` and `https` modules.\n * It supports automatic retries with exponential backoff, redirect following, streaming downloads,\n * and provides a familiar fetch-style response interface.\n *\n * Key Features:\n * - Automatic retries with exponential backoff for failed requests.\n * - Redirect following with configurable max redirects.\n * - Streaming downloads with progress callbacks.\n * - Fetch-like response interface (`.json()`, `.text()`, `.arrayBuffer()`).\n * - Timeout support for all operations.\n * - Zero dependencies on external HTTP libraries.\n */\n\nimport { createWriteStream } from 'fs'\n\nimport type { IncomingMessage } from 'http'\n\nlet _http: typeof import('http') | undefined\nlet _https: typeof import('https') | undefined\n/**\n * Lazily load http and https modules to avoid Webpack errors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getHttp() {\n if (_http === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _http = /*@__PURE__*/ require('node:http')\n }\n return _http as typeof import('http')\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction getHttps() {\n if (_https === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _https = /*@__PURE__*/ require('node:https')\n }\n return _https as typeof import('https')\n}\n\n/**\n * Configuration options for HTTP/HTTPS requests.\n */\nexport interface HttpRequestOptions {\n /**\n * Request body to send.\n * Can be a string (e.g., JSON) or Buffer (e.g., binary data).\n *\n * @example\n * ```ts\n * // Send JSON data\n * await httpRequest('https://api.example.com/data', {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Alice' }),\n * headers: { 'Content-Type': 'application/json' }\n * })\n *\n * // Send binary data\n * const buffer = Buffer.from([0x00, 0x01, 0x02])\n * await httpRequest('https://api.example.com/upload', {\n * method: 'POST',\n * body: buffer\n * })\n * ```\n */\n body?: Buffer | string | undefined\n /**\n * Whether to automatically follow HTTP redirects (3xx status codes).\n *\n * @default true\n *\n * @example\n * ```ts\n * // Follow redirects (default)\n * await httpRequest('https://example.com/redirect')\n *\n * // Don't follow redirects\n * const response = await httpRequest('https://example.com/redirect', {\n * followRedirects: false\n * })\n * console.log(response.status) // 301 or 302\n * ```\n */\n followRedirects?: boolean | undefined\n /**\n * HTTP headers to send with the request.\n * A `User-Agent` header is automatically added if not provided.\n *\n * @example\n * ```ts\n * await httpRequest('https://api.example.com/data', {\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'Content-Type': 'application/json',\n * 'Accept': 'application/json'\n * }\n * })\n * ```\n */\n headers?: Record<string, string> | undefined\n /**\n * Maximum number of redirects to follow before throwing an error.\n * Only relevant when `followRedirects` is `true`.\n *\n * @default 5\n *\n * @example\n * ```ts\n * // Allow up to 10 redirects\n * await httpRequest('https://example.com/many-redirects', {\n * maxRedirects: 10\n * })\n * ```\n */\n maxRedirects?: number | undefined\n /**\n * HTTP method to use for the request.\n *\n * @default 'GET'\n *\n * @example\n * ```ts\n * // GET request (default)\n * await httpRequest('https://api.example.com/data')\n *\n * // POST request\n * await httpRequest('https://api.example.com/data', {\n * method: 'POST',\n * body: JSON.stringify({ name: 'Alice' })\n * })\n *\n * // DELETE request\n * await httpRequest('https://api.example.com/data/123', {\n * method: 'DELETE'\n * })\n * ```\n */\n method?: string | undefined\n /**\n * Number of retry attempts for failed requests.\n * Uses exponential backoff: delay = `retryDelay` * 2^attempt.\n *\n * @default 0\n *\n * @example\n * ```ts\n * // Retry up to 3 times with exponential backoff\n * await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000 // 1s, then 2s, then 4s\n * })\n * ```\n */\n retries?: number | undefined\n /**\n * Initial delay in milliseconds before first retry.\n * Subsequent retries use exponential backoff.\n *\n * @default 1000\n *\n * @example\n * ```ts\n * // Start with 2 second delay, then 4s, 8s, etc.\n * await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 2000\n * })\n * ```\n */\n retryDelay?: number | undefined\n /**\n * Request timeout in milliseconds.\n * If the request takes longer than this, it will be aborted.\n *\n * @default 30000\n *\n * @example\n * ```ts\n * // 60 second timeout\n * await httpRequest('https://api.example.com/slow-endpoint', {\n * timeout: 60000\n * })\n * ```\n */\n timeout?: number | undefined\n}\n\n/**\n * HTTP response object with fetch-like interface.\n * Provides multiple ways to access the response body.\n */\nexport interface HttpResponse {\n /**\n * Get response body as ArrayBuffer.\n * Useful for binary data or when you need compatibility with browser APIs.\n *\n * @returns The response body as an ArrayBuffer\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/image.png')\n * const arrayBuffer = response.arrayBuffer()\n * console.log(arrayBuffer.byteLength)\n * ```\n */\n arrayBuffer(): ArrayBuffer\n /**\n * Raw response body as Buffer.\n * Direct access to the underlying Node.js Buffer.\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/data')\n * console.log(response.body.length) // Size in bytes\n * console.log(response.body.toString('hex')) // View as hex\n * ```\n */\n body: Buffer\n /**\n * HTTP response headers.\n * Keys are lowercase header names, values can be strings or string arrays.\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.headers['content-type'])\n * console.log(response.headers['set-cookie']) // May be string[]\n * ```\n */\n headers: Record<string, string | string[] | undefined>\n /**\n * Parse response body as JSON.\n * Type parameter `T` allows specifying the expected JSON structure.\n *\n * @template T - Expected JSON type (defaults to `unknown`)\n * @returns Parsed JSON data\n * @throws {SyntaxError} When response body is not valid JSON\n *\n * @example\n * ```ts\n * interface User { name: string; id: number }\n * const response = await httpRequest('https://api.example.com/user')\n * const user = response.json<User>()\n * console.log(user.name, user.id)\n * ```\n */\n json<T = unknown>(): T\n /**\n * Whether the request was successful (status code 200-299).\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com/data')\n * if (response.ok) {\n * console.log('Success:', response.json())\n * } else {\n * console.error('Failed:', response.status, response.statusText)\n * }\n * ```\n */\n ok: boolean\n /**\n * HTTP status code (e.g., 200, 404, 500).\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.status) // 200, 404, etc.\n * ```\n */\n status: number\n /**\n * HTTP status message (e.g., \"OK\", \"Not Found\", \"Internal Server Error\").\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * console.log(response.statusText) // \"OK\"\n * ```\n */\n statusText: string\n /**\n * Get response body as UTF-8 text string.\n *\n * @returns The response body as a string\n *\n * @example\n * ```ts\n * const response = await httpRequest('https://example.com')\n * const html = response.text()\n * console.log(html.includes('<html>'))\n * ```\n */\n text(): string\n}\n\n/**\n * Configuration options for file downloads.\n */\nexport interface HttpDownloadOptions {\n /**\n * HTTP headers to send with the download request.\n * A `User-Agent` header is automatically added if not provided.\n *\n * @example\n * ```ts\n * await httpDownload('https://example.com/file.zip', '/tmp/file.zip', {\n * headers: {\n * 'Authorization': 'Bearer token123'\n * }\n * })\n * ```\n */\n headers?: Record<string, string> | undefined\n /**\n * Callback for tracking download progress.\n * Called periodically as data is received.\n *\n * @param downloaded - Number of bytes downloaded so far\n * @param total - Total file size in bytes (from Content-Length header)\n *\n * @example\n * ```ts\n * await httpDownload('https://example.com/large-file.zip', '/tmp/file.zip', {\n * onProgress: (downloaded, total) => {\n * const percent = ((downloaded / total) * 100).toFixed(1)\n * console.log(`Progress: ${percent}%`)\n * }\n * })\n * ```\n */\n onProgress?: ((downloaded: number, total: number) => void) | undefined\n /**\n * Number of retry attempts for failed downloads.\n * Uses exponential backoff: delay = `retryDelay` * 2^attempt.\n *\n * @default 0\n *\n * @example\n * ```ts\n * // Retry up to 3 times for unreliable connections\n * await httpDownload('https://example.com/file.zip', '/tmp/file.zip', {\n * retries: 3,\n * retryDelay: 2000\n * })\n * ```\n */\n retries?: number | undefined\n /**\n * Initial delay in milliseconds before first retry.\n * Subsequent retries use exponential backoff.\n *\n * @default 1000\n */\n retryDelay?: number | undefined\n /**\n * Download timeout in milliseconds.\n * If the download takes longer than this, it will be aborted.\n *\n * @default 120000\n *\n * @example\n * ```ts\n * // 5 minute timeout for large files\n * await httpDownload('https://example.com/huge-file.zip', '/tmp/file.zip', {\n * timeout: 300000\n * })\n * ```\n */\n timeout?: number | undefined\n}\n\n/**\n * Result of a successful file download.\n */\nexport interface HttpDownloadResult {\n /**\n * Absolute path where the file was saved.\n *\n * @example\n * ```ts\n * const result = await httpDownload('https://example.com/file.zip', '/tmp/file.zip')\n * console.log(`Downloaded to: ${result.path}`)\n * ```\n */\n path: string\n /**\n * Total size of downloaded file in bytes.\n *\n * @example\n * ```ts\n * const result = await httpDownload('https://example.com/file.zip', '/tmp/file.zip')\n * console.log(`Downloaded ${result.size} bytes`)\n * ```\n */\n size: number\n}\n\n/**\n * Make an HTTP/HTTPS request with retry logic and redirect support.\n * Provides a fetch-like API using Node.js native http/https modules.\n *\n * This is the main entry point for making HTTP requests. It handles retries,\n * redirects, timeouts, and provides a fetch-compatible response interface.\n *\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to response object with `.json()`, `.text()`, etc.\n * @throws {Error} When all retries are exhausted, timeout occurs, or non-retryable error happens\n *\n * @example\n * ```ts\n * // Simple GET request\n * const response = await httpRequest('https://api.example.com/data')\n * const data = response.json()\n *\n * // POST with JSON body\n * const response = await httpRequest('https://api.example.com/users', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice', email: 'alice@example.com' })\n * })\n *\n * // With retries and timeout\n * const response = await httpRequest('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000,\n * timeout: 60000\n * })\n *\n * // Don't follow redirects\n * const response = await httpRequest('https://example.com/redirect', {\n * followRedirects: false\n * })\n * console.log(response.status) // 301, 302, etc.\n * ```\n */\nexport async function httpRequest(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<HttpResponse> {\n const {\n body,\n followRedirects = true,\n headers = {},\n maxRedirects = 5,\n method = 'GET',\n retries = 0,\n retryDelay = 1000,\n timeout = 30_000,\n } = { __proto__: null, ...options } as HttpRequestOptions\n\n // Retry logic with exponential backoff\n let lastError: Error | undefined\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await httpRequestAttempt(url, {\n body,\n followRedirects,\n headers,\n maxRedirects,\n method,\n timeout,\n })\n } catch (e) {\n lastError = e as Error\n\n // Last attempt - throw error\n if (attempt === retries) {\n break\n }\n\n // Retry with exponential backoff\n const delayMs = retryDelay * 2 ** attempt\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, delayMs))\n }\n }\n\n throw lastError || new Error('Request failed after retries')\n}\n\n/**\n * Single HTTP request attempt (used internally by httpRequest with retry logic).\n * @private\n */\nasync function httpRequestAttempt(\n url: string,\n options: HttpRequestOptions,\n): Promise<HttpResponse> {\n const {\n body,\n followRedirects = true,\n headers = {},\n maxRedirects = 5,\n method = 'GET',\n timeout = 30_000,\n } = { __proto__: null, ...options } as HttpRequestOptions\n\n return await new Promise((resolve, reject) => {\n const parsedUrl = new URL(url)\n const isHttps = parsedUrl.protocol === 'https:'\n const httpModule = isHttps ? getHttps() : getHttp()\n\n const requestOptions = {\n headers: {\n 'User-Agent': 'socket-registry/1.0',\n ...headers,\n },\n hostname: parsedUrl.hostname,\n method,\n path: parsedUrl.pathname + parsedUrl.search,\n port: parsedUrl.port,\n timeout,\n }\n\n const request = httpModule.request(\n requestOptions,\n (res: IncomingMessage) => {\n // Handle redirects\n if (\n followRedirects &&\n res.statusCode &&\n res.statusCode >= 300 &&\n res.statusCode < 400 &&\n res.headers.location\n ) {\n if (maxRedirects <= 0) {\n reject(\n new Error(\n `Too many redirects (exceeded maximum: ${maxRedirects})`,\n ),\n )\n return\n }\n\n // Follow redirect\n const redirectUrl = res.headers.location.startsWith('http')\n ? res.headers.location\n : new URL(res.headers.location, url).toString()\n\n resolve(\n httpRequestAttempt(redirectUrl, {\n body,\n followRedirects,\n headers,\n maxRedirects: maxRedirects - 1,\n method,\n timeout,\n }),\n )\n return\n }\n\n // Collect response data\n const chunks: Buffer[] = []\n res.on('data', (chunk: Buffer) => {\n chunks.push(chunk)\n })\n\n res.on('end', () => {\n const responseBody = Buffer.concat(chunks)\n const ok =\n res.statusCode !== undefined &&\n res.statusCode >= 200 &&\n res.statusCode < 300\n\n const response: HttpResponse = {\n arrayBuffer(): ArrayBuffer {\n return responseBody.buffer.slice(\n responseBody.byteOffset,\n responseBody.byteOffset + responseBody.byteLength,\n )\n },\n body: responseBody,\n headers: res.headers as Record<\n string,\n string | string[] | undefined\n >,\n json<T = unknown>(): T {\n return JSON.parse(responseBody.toString('utf8')) as T\n },\n ok,\n status: res.statusCode || 0,\n statusText: res.statusMessage || '',\n text(): string {\n return responseBody.toString('utf8')\n },\n }\n\n resolve(response)\n })\n },\n )\n\n request.on('error', (error: Error) => {\n const code = (error as NodeJS.ErrnoException).code\n let message = `HTTP request failed for ${url}: ${error.message}\\n`\n\n if (code === 'ENOTFOUND') {\n message +=\n 'DNS lookup failed. Check the hostname and your network connection.'\n } else if (code === 'ECONNREFUSED') {\n message +=\n 'Connection refused. Verify the server is running and accessible.'\n } else if (code === 'ETIMEDOUT') {\n message +=\n 'Request timed out. Check your network or increase the timeout value.'\n } else if (code === 'ECONNRESET') {\n message +=\n 'Connection reset. The server may have closed the connection unexpectedly.'\n } else {\n message +=\n 'Check your network connection and verify the URL is correct.'\n }\n\n reject(new Error(message, { cause: error }))\n })\n\n request.on('timeout', () => {\n request.destroy()\n reject(new Error(`Request timed out after ${timeout}ms`))\n })\n\n // Send body if present\n if (body) {\n request.write(body)\n }\n\n request.end()\n })\n}\n\n/**\n * Download a file from a URL to a local path with retry logic and progress callbacks.\n * Uses streaming to avoid loading entire file in memory.\n *\n * The download is streamed directly to disk, making it memory-efficient even for\n * large files. Progress callbacks allow for real-time download status updates.\n *\n * @param url - The URL to download from (must start with http:// or https://)\n * @param destPath - Absolute path where the file should be saved\n * @param options - Download configuration options\n * @returns Promise resolving to download result with path and size\n * @throws {Error} When all retries are exhausted, download fails, or file cannot be written\n *\n * @example\n * ```ts\n * // Simple download\n * const result = await httpDownload(\n * 'https://example.com/file.zip',\n * '/tmp/file.zip'\n * )\n * console.log(`Downloaded ${result.size} bytes to ${result.path}`)\n *\n * // With progress tracking\n * await httpDownload(\n * 'https://example.com/large-file.zip',\n * '/tmp/file.zip',\n * {\n * onProgress: (downloaded, total) => {\n * const percent = ((downloaded / total) * 100).toFixed(1)\n * console.log(`Progress: ${percent}% (${downloaded}/${total} bytes)`)\n * }\n * }\n * )\n *\n * // With retries and custom timeout\n * await httpDownload(\n * 'https://example.com/file.zip',\n * '/tmp/file.zip',\n * {\n * retries: 3,\n * retryDelay: 2000,\n * timeout: 300000, // 5 minutes\n * headers: { 'Authorization': 'Bearer token123' }\n * }\n * )\n * ```\n */\nexport async function httpDownload(\n url: string,\n destPath: string,\n options?: HttpDownloadOptions | undefined,\n): Promise<HttpDownloadResult> {\n const {\n headers = {},\n onProgress,\n retries = 0,\n retryDelay = 1000,\n timeout = 120_000,\n } = { __proto__: null, ...options } as HttpDownloadOptions\n\n // Retry logic with exponential backoff\n let lastError: Error | undefined\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await httpDownloadAttempt(url, destPath, {\n headers,\n onProgress,\n timeout,\n })\n } catch (e) {\n lastError = e as Error\n\n // Last attempt - throw error\n if (attempt === retries) {\n break\n }\n\n // Retry with exponential backoff\n const delayMs = retryDelay * 2 ** attempt\n // eslint-disable-next-line no-await-in-loop\n await new Promise(resolve => setTimeout(resolve, delayMs))\n }\n }\n\n throw lastError || new Error('Download failed after retries')\n}\n\n/**\n * Single download attempt (used internally by httpDownload with retry logic).\n * @private\n */\nasync function httpDownloadAttempt(\n url: string,\n destPath: string,\n options: HttpDownloadOptions,\n): Promise<HttpDownloadResult> {\n const {\n headers = {},\n onProgress,\n timeout = 120_000,\n } = { __proto__: null, ...options } as HttpDownloadOptions\n\n return await new Promise((resolve, reject) => {\n const parsedUrl = new URL(url)\n const isHttps = parsedUrl.protocol === 'https:'\n const httpModule = isHttps ? getHttps() : getHttp()\n\n const requestOptions = {\n headers: {\n 'User-Agent': 'socket-registry/1.0',\n ...headers,\n },\n hostname: parsedUrl.hostname,\n method: 'GET',\n path: parsedUrl.pathname + parsedUrl.search,\n port: parsedUrl.port,\n timeout,\n }\n\n let fileStream: ReturnType<typeof createWriteStream> | undefined\n let streamClosed = false\n\n const closeStream = () => {\n if (!streamClosed && fileStream) {\n streamClosed = true\n fileStream.close()\n }\n }\n\n const request = httpModule.request(\n requestOptions,\n (res: IncomingMessage) => {\n // Check status code\n if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {\n closeStream()\n reject(\n new Error(\n `Download failed: HTTP ${res.statusCode} ${res.statusMessage}`,\n ),\n )\n return\n }\n\n const totalSize = Number.parseInt(\n res.headers['content-length'] || '0',\n 10,\n )\n let downloadedSize = 0\n\n // Create write stream\n fileStream = createWriteStream(destPath)\n\n fileStream.on('error', (error: Error) => {\n closeStream()\n const err = new Error(`Failed to write file: ${error.message}`, {\n cause: error,\n })\n reject(err)\n })\n\n res.on('data', (chunk: Buffer) => {\n downloadedSize += chunk.length\n if (onProgress && totalSize > 0) {\n onProgress(downloadedSize, totalSize)\n }\n })\n\n res.on('end', () => {\n fileStream?.close(() => {\n streamClosed = true\n resolve({\n path: destPath,\n size: downloadedSize,\n })\n })\n })\n\n res.on('error', (error: Error) => {\n closeStream()\n reject(error)\n })\n\n // Pipe response to file\n res.pipe(fileStream)\n },\n )\n\n request.on('error', (error: Error) => {\n closeStream()\n const code = (error as NodeJS.ErrnoException).code\n let message = `HTTP download failed for ${url}: ${error.message}\\n`\n\n if (code === 'ENOTFOUND') {\n message +=\n 'DNS lookup failed. Check the hostname and your network connection.'\n } else if (code === 'ECONNREFUSED') {\n message +=\n 'Connection refused. Verify the server is running and accessible.'\n } else if (code === 'ETIMEDOUT') {\n message +=\n 'Request timed out. Check your network or increase the timeout value.'\n } else if (code === 'ECONNRESET') {\n message +=\n 'Connection reset. The server may have closed the connection unexpectedly.'\n } else {\n message +=\n 'Check your network connection and verify the URL is correct.'\n }\n\n reject(new Error(message, { cause: error }))\n })\n\n request.on('timeout', () => {\n request.destroy()\n closeStream()\n reject(new Error(`Download timed out after ${timeout}ms`))\n })\n\n request.end()\n })\n}\n\n/**\n * Perform a GET request and parse JSON response.\n * Convenience wrapper around `httpRequest` for common JSON API calls.\n *\n * @template T - Expected JSON response type (defaults to `unknown`)\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to parsed JSON data\n * @throws {Error} When request fails, response is not ok (status < 200 or >= 300), or JSON parsing fails\n *\n * @example\n * ```ts\n * // Simple JSON GET\n * const data = await httpGetJson('https://api.example.com/data')\n * console.log(data)\n *\n * // With type safety\n * interface User { id: number; name: string; email: string }\n * const user = await httpGetJson<User>('https://api.example.com/user/123')\n * console.log(user.name, user.email)\n *\n * // With custom headers\n * const data = await httpGetJson('https://api.example.com/data', {\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'Accept': 'application/json'\n * }\n * })\n *\n * // With retries\n * const data = await httpGetJson('https://api.example.com/data', {\n * retries: 3,\n * retryDelay: 1000\n * })\n * ```\n */\nexport async function httpGetJson<T = unknown>(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<T> {\n const response = await httpRequest(url, { ...options, method: 'GET' })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n try {\n return response.json<T>()\n } catch (e) {\n throw new Error('Failed to parse JSON response', { cause: e })\n }\n}\n\n/**\n * Perform a GET request and return text response.\n * Convenience wrapper around `httpRequest` for fetching text content.\n *\n * @param url - The URL to request (must start with http:// or https://)\n * @param options - Request configuration options\n * @returns Promise resolving to response body as UTF-8 string\n * @throws {Error} When request fails or response is not ok (status < 200 or >= 300)\n *\n * @example\n * ```ts\n * // Fetch HTML\n * const html = await httpGetText('https://example.com')\n * console.log(html.includes('<!DOCTYPE html>'))\n *\n * // Fetch plain text\n * const text = await httpGetText('https://example.com/file.txt')\n * console.log(text)\n *\n * // With custom headers\n * const text = await httpGetText('https://example.com/data.txt', {\n * headers: {\n * 'Authorization': 'Bearer token123'\n * }\n * })\n *\n * // With timeout\n * const text = await httpGetText('https://example.com/large-file.txt', {\n * timeout: 60000 // 1 minute\n * })\n * ```\n */\nexport async function httpGetText(\n url: string,\n options?: HttpRequestOptions | undefined,\n): Promise<string> {\n const response = await httpRequest(url, { ...options, method: 'GET' })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n return response.text()\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["http_request_exports", "__export", "httpDownload", "httpGetJson", "httpGetText", "httpRequest", "__toCommonJS", "import_fs", "_http", "_https", "getHttp", "getHttps", "url", "options", "body", "followRedirects", "headers", "maxRedirects", "method", "retries", "retryDelay", "timeout", "lastError", "attempt", "httpRequestAttempt", "e", "delayMs", "resolve", "reject", "parsedUrl", "httpModule", "requestOptions", "request", "res", "redirectUrl", "chunks", "chunk", "responseBody", "ok", "response", "error", "code", "message", "destPath", "onProgress", "httpDownloadAttempt", "fileStream", "streamClosed", "closeStream", "totalSize", "downloadedSize", "err"]
7
7
  }
package/dist/index.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  /**
2
- * @fileoverview Main entry point for Socket Registry v2.0.
2
+ * @fileoverview Main entry point for @socketsecurity/lib.
3
3
  * Clean, organized exports for better developer experience.
4
4
  */
5
- // Direct exports for commonly used items
6
- // Alias for backward compatibility with GitHub version
7
- export { SocketRegistry, SocketRegistry as SocketSecurityRegistry, } from './packages/registry';
5
+ // Export logger utilities for convenience
6
+ export { getDefaultLogger, Logger, LOG_SYMBOLS } from './logger';
7
+ // Export spinner utilities for convenience
8
+ export { getDefaultSpinner, Spinner } from './spinner';
8
9
  // Export types
9
10
  export * from './types';
10
11
  // Manifest data helper function
11
12
  export declare function getManifestData(ecosystem?: string, packageName?: string): any;
12
13
  // Version export
13
- export declare const version = "2.0.0";
14
+ export declare const version = "3.0.1";
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /* Socket Lib - Built with esbuild */
2
- var c=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var x=(t,r)=>{for(var n in r)c(t,n,{get:r[n],enumerable:!0})},s=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of g(r))!p.call(t,i)&&i!==n&&c(t,i,{get:()=>r[i],enumerable:!(e=y(r,i))||e.enumerable});return t},f=(t,r,n)=>(s(t,r,"default"),n&&s(n,r,"default"));var D=t=>s(c({},"__esModule",{value:!0}),t);var o={};x(o,{SocketRegistry:()=>u.SocketRegistry,SocketSecurityRegistry:()=>u.SocketRegistry,getManifestData:()=>S,version:()=>R});module.exports=D(o);var u=require("./packages/registry");f(o,require("./types"),module.exports);function S(t,r){try{const n=require("./manifest.json");if(!t)return n;const e=n[t];if(!e)return;if(!r)return e;if(Array.isArray(e)){const d=e.find(([k,a])=>a.package===r);return d?d[1]:void 0}const i=e[r];return i?[r,i]:void 0}catch{return}}const R="2.0.0";0&&(module.exports={SocketRegistry,SocketSecurityRegistry,getManifestData,version,...require("./types")});
2
+ var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var L=(n,r)=>{for(var t in r)a(n,t,{get:r[t],enumerable:!0})},s=(n,r,t,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of D(r))!x.call(n,i)&&i!==t&&a(n,i,{get:()=>r[i],enumerable:!(e=c(r,i))||e.enumerable});return n},o=(n,r,t)=>(s(n,r,"default"),t&&s(t,r,"default"));var S=n=>s(a({},"__esModule",{value:!0}),n);var f={};L(f,{LOG_SYMBOLS:()=>u.LOG_SYMBOLS,Logger:()=>u.Logger,Spinner:()=>d.Spinner,getDefaultLogger:()=>u.getDefaultLogger,getDefaultSpinner:()=>d.getDefaultSpinner,getManifestData:()=>l,version:()=>y});module.exports=S(f);var u=require("./logger"),d=require("./spinner");o(f,require("./types"),module.exports);function l(n,r){try{const t=require("./manifest.json");if(!n)return t;const e=t[n];if(!e)return;if(!r)return e;if(Array.isArray(e)){const g=e.find(([A,p])=>p.package===r);return g?g[1]:void 0}const i=e[r];return i?[r,i]:void 0}catch{return}}const y="3.0.1";0&&(module.exports={LOG_SYMBOLS,Logger,Spinner,getDefaultLogger,getDefaultSpinner,getManifestData,version,...require("./types")});
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Main entry point for Socket Registry v2.0.\n * Clean, organized exports for better developer experience.\n */\n\n// Direct exports for commonly used items\n// Alias for backward compatibility with GitHub version\nexport {\n SocketRegistry,\n SocketRegistry as SocketSecurityRegistry,\n} from './packages/registry'\n// Export types\nexport * from './types'\n\n// Manifest data helper function\nexport function getManifestData(ecosystem?: string, packageName?: string) {\n try {\n const manifestData = require('../manifest.json')\n\n if (!ecosystem) {\n return manifestData\n }\n\n const ecoData = manifestData[ecosystem]\n if (!ecoData) {\n return undefined\n }\n\n if (!packageName) {\n return ecoData\n }\n\n // ecoData is an array of [purl, data] entries\n if (Array.isArray(ecoData)) {\n const entry = ecoData.find(\n ([_purl, data]) => data.package === packageName,\n )\n return entry ? entry[1] : undefined\n }\n\n // Fallback for object-based structure\n const pkgData = ecoData[packageName]\n return pkgData ? [packageName, pkgData] : undefined\n } catch {\n return undefined\n }\n}\n\n// Version export\nexport const version = '2.0.0'\n"],
5
- "mappings": ";8cAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qGAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GAOA,IAAAK,EAGO,+BAEPC,EAAAN,EAAc,mBAZd,gBAeO,SAASE,EAAgBK,EAAoBC,EAAsB,CACxE,GAAI,CACF,MAAMC,EAAe,QAAQ,kBAAkB,EAE/C,GAAI,CAACF,EACH,OAAOE,EAGT,MAAMC,EAAUD,EAAaF,CAAS,EACtC,GAAI,CAACG,EACH,OAGF,GAAI,CAACF,EACH,OAAOE,EAIT,GAAI,MAAM,QAAQA,CAAO,EAAG,CAC1B,MAAMC,EAAQD,EAAQ,KACpB,CAAC,CAACE,EAAOC,CAAI,IAAMA,EAAK,UAAYL,CACtC,EACA,OAAOG,EAAQA,EAAM,CAAC,EAAI,MAC5B,CAGA,MAAMG,EAAUJ,EAAQF,CAAW,EACnC,OAAOM,EAAU,CAACN,EAAaM,CAAO,EAAI,MAC5C,MAAQ,CACN,MACF,CACF,CAGO,MAAMX,EAAU",
6
- "names": ["index_exports", "__export", "getManifestData", "version", "__toCommonJS", "import_registry", "__reExport", "ecosystem", "packageName", "manifestData", "ecoData", "entry", "_purl", "data", "pkgData"]
4
+ "sourcesContent": ["/**\n * @fileoverview Main entry point for @socketsecurity/lib.\n * Clean, organized exports for better developer experience.\n */\n\n// Export logger utilities for convenience\nexport { getDefaultLogger, Logger, LOG_SYMBOLS } from './logger'\n// Export spinner utilities for convenience\nexport { getDefaultSpinner, Spinner } from './spinner'\n// Export types\nexport * from './types'\n\n// Manifest data helper function\nexport function getManifestData(ecosystem?: string, packageName?: string) {\n try {\n const manifestData = require('../manifest.json')\n\n if (!ecosystem) {\n return manifestData\n }\n\n const ecoData = manifestData[ecosystem]\n if (!ecoData) {\n return undefined\n }\n\n if (!packageName) {\n return ecoData\n }\n\n // ecoData is an array of [purl, data] entries\n if (Array.isArray(ecoData)) {\n const entry = ecoData.find(\n ([_purl, data]) => data.package === packageName,\n )\n return entry ? entry[1] : undefined\n }\n\n // Fallback for object-based structure\n const pkgData = ecoData[packageName]\n return pkgData ? [packageName, pkgData] : undefined\n } catch {\n return undefined\n }\n}\n\n// Version export\nexport const version = '3.0.1'\n"],
5
+ "mappings": ";8cAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+KAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GAMA,IAAAK,EAAsD,oBAEtDC,EAA2C,qBAE3CC,EAAAP,EAAc,mBAVd,gBAaO,SAASE,EAAgBM,EAAoBC,EAAsB,CACxE,GAAI,CACF,MAAMC,EAAe,QAAQ,kBAAkB,EAE/C,GAAI,CAACF,EACH,OAAOE,EAGT,MAAMC,EAAUD,EAAaF,CAAS,EACtC,GAAI,CAACG,EACH,OAGF,GAAI,CAACF,EACH,OAAOE,EAIT,GAAI,MAAM,QAAQA,CAAO,EAAG,CAC1B,MAAMC,EAAQD,EAAQ,KACpB,CAAC,CAACE,EAAOC,CAAI,IAAMA,EAAK,UAAYL,CACtC,EACA,OAAOG,EAAQA,EAAM,CAAC,EAAI,MAC5B,CAGA,MAAMG,EAAUJ,EAAQF,CAAW,EACnC,OAAOM,EAAU,CAACN,EAAaM,CAAO,EAAI,MAC5C,MAAQ,CACN,MACF,CACF,CAGO,MAAMZ,EAAU",
6
+ "names": ["index_exports", "__export", "getManifestData", "version", "__toCommonJS", "import_logger", "import_spinner", "__reExport", "ecosystem", "packageName", "manifestData", "ecoData", "entry", "_purl", "data", "pkgData"]
7
7
  }
package/dist/ipc.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /* Socket Lib - Built with esbuild */
2
- var P=Object.create;var m=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var J=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},y=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of B(e))!A.call(t,s)&&s!==n&&m(t,s,{get:()=>e[s],enumerable:!(o=N(e,s))||o.enumerable});return t};var k=(t,e,n)=>(n=t!=null?P(O(t)):{},y(e||!t||!t.__esModule?m(n,"default",{value:t,enumerable:!0}):n,t)),$=t=>y(m({},"__esModule",{value:!0}),t);var L={};J(L,{IpcHandshakeSchema:()=>E,cleanupIpcStubs:()=>z,createIpcChannelId:()=>F,createIpcMessage:()=>G,getIpcStubPath:()=>x,hasIpcChannel:()=>K,onIpc:()=>S,parseIpcMessage:()=>v,readIpcStub:()=>W,sendIpc:()=>_,waitForIpc:()=>q,writeIpcStub:()=>H});module.exports=$(L);var l=k(require("node:crypto")),c=require("node:fs"),p=k(require("node:path")),g=require("./fs"),h=require("./paths"),i=require("./zod");const w=i.z.object({id:i.z.string().min(1),timestamp:i.z.number().positive(),type:i.z.string().min(1),data:i.z.unknown()}),E=w.extend({type:i.z.literal("handshake"),data:i.z.object({version:i.z.string(),pid:i.z.number().int().positive(),apiToken:i.z.string().optional(),appName:i.z.string()})}),I=i.z.object({pid:i.z.number().int().positive(),timestamp:i.z.number().positive(),data:i.z.unknown()});function F(t="socket"){return`${t}-${process.pid}-${l.default.randomBytes(8).toString("hex")}`}function x(t){const e=(0,h.getOsTmpDir)(),n=p.default.join(e,".socket-ipc",t);return p.default.join(n,`stub-${process.pid}.json`)}async function C(t){const e=p.default.dirname(t);await c.promises.mkdir(e,{recursive:!0})}async function H(t,e){const n=x(t);await C(n);const o={data:e,pid:process.pid,timestamp:Date.now()},s=I.parse(o);return await c.promises.writeFile(n,JSON.stringify(s,null,2),"utf8"),n}async function W(t){try{const e=await c.promises.readFile(t,"utf8"),n=JSON.parse(e),o=I.parse(n),s=Date.now()-o.timestamp,a=300*1e3;if(s>a){try{(0,g.safeDeleteSync)(t,{force:!0})}catch{}return null}return o.data}catch{return null}}async function z(t){const e=(0,h.getOsTmpDir)(),n=p.default.join(e,".socket-ipc",t);try{const o=await c.promises.readdir(n),s=Date.now(),a=300*1e3;await Promise.all(o.map(async r=>{if(r.startsWith("stub-")&&r.endsWith(".json")){const u=p.default.join(n,r);try{const b=await c.promises.stat(u);let f=s-b.mtimeMs>a;try{const M=await c.promises.readFile(u,"utf8"),T=JSON.parse(M),D=I.parse(T),j=s-D.timestamp;f=f||j>a}catch{}f&&(0,g.safeDeleteSync)(u,{force:!0})}catch{}}}))}catch{}}function _(t,e){if(t&&typeof t=="object"&&"send"in t&&typeof t.send=="function")try{const n=w.parse(e);return t.send(n)}catch{return!1}return!1}function S(t){const e=n=>{const o=v(n);o&&t(o)};return process.on("message",e),()=>{process.off("message",e)}}function q(t,e={}){const{timeout:n=3e4}=e;return new Promise((o,s)=>{let a=null,r=null;const u=()=>{a&&a(),s(new Error(`IPC timeout waiting for message type: ${t}`))};a=S(d=>{d.type===t&&(r&&clearTimeout(r),a&&a(),o(d.data))}),n>0&&(r=setTimeout(u,n))})}function G(t,e){return{id:l.default.randomBytes(16).toString("hex"),timestamp:Date.now(),type:t,data:e}}function K(t){return!!(t&&typeof t=="object"&&"send"in t&&typeof t.send=="function"&&"channel"in t&&t.channel!==void 0)}function v(t){try{return w.parse(t)}catch{return null}}0&&(module.exports={IpcHandshakeSchema,cleanupIpcStubs,createIpcChannelId,createIpcMessage,getIpcStubPath,hasIpcChannel,onIpc,parseIpcMessage,readIpcStub,sendIpc,waitForIpc,writeIpcStub});
2
+ var P=Object.create;var m=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var J=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},y=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of B(e))!A.call(t,s)&&s!==n&&m(t,s,{get:()=>e[s],enumerable:!(o=N(e,s))||o.enumerable});return t};var k=(t,e,n)=>(n=t!=null?P(O(t)):{},y(e||!t||!t.__esModule?m(n,"default",{value:t,enumerable:!0}):n,t)),$=t=>y(m({},"__esModule",{value:!0}),t);var L={};J(L,{IpcHandshakeSchema:()=>E,cleanupIpcStubs:()=>z,createIpcChannelId:()=>F,createIpcMessage:()=>G,getIpcStubPath:()=>x,hasIpcChannel:()=>K,onIpc:()=>S,parseIpcMessage:()=>v,readIpcStub:()=>W,sendIpc:()=>_,waitForIpc:()=>q,writeIpcStub:()=>H});module.exports=$(L);var l=k(require("crypto")),c=require("fs"),p=k(require("path")),g=require("./fs"),h=require("./paths"),i=require("./zod");const w=i.z.object({id:i.z.string().min(1),timestamp:i.z.number().positive(),type:i.z.string().min(1),data:i.z.unknown()}),E=w.extend({type:i.z.literal("handshake"),data:i.z.object({version:i.z.string(),pid:i.z.number().int().positive(),apiToken:i.z.string().optional(),appName:i.z.string()})}),I=i.z.object({pid:i.z.number().int().positive(),timestamp:i.z.number().positive(),data:i.z.unknown()});function F(t="socket"){return`${t}-${process.pid}-${l.default.randomBytes(8).toString("hex")}`}function x(t){const e=(0,h.getOsTmpDir)(),n=p.default.join(e,".socket-ipc",t);return p.default.join(n,`stub-${process.pid}.json`)}async function C(t){const e=p.default.dirname(t);await c.promises.mkdir(e,{recursive:!0})}async function H(t,e){const n=x(t);await C(n);const o={data:e,pid:process.pid,timestamp:Date.now()},s=I.parse(o);return await c.promises.writeFile(n,JSON.stringify(s,null,2),"utf8"),n}async function W(t){try{const e=await c.promises.readFile(t,"utf8"),n=JSON.parse(e),o=I.parse(n),s=Date.now()-o.timestamp,a=300*1e3;if(s>a){try{(0,g.safeDeleteSync)(t,{force:!0})}catch{}return null}return o.data}catch{return null}}async function z(t){const e=(0,h.getOsTmpDir)(),n=p.default.join(e,".socket-ipc",t);try{const o=await c.promises.readdir(n),s=Date.now(),a=300*1e3;await Promise.all(o.map(async r=>{if(r.startsWith("stub-")&&r.endsWith(".json")){const u=p.default.join(n,r);try{const b=await c.promises.stat(u);let f=s-b.mtimeMs>a;try{const M=await c.promises.readFile(u,"utf8"),T=JSON.parse(M),D=I.parse(T),j=s-D.timestamp;f=f||j>a}catch{}f&&(0,g.safeDeleteSync)(u,{force:!0})}catch{}}}))}catch{}}function _(t,e){if(t&&typeof t=="object"&&"send"in t&&typeof t.send=="function")try{const n=w.parse(e);return t.send(n)}catch{return!1}return!1}function S(t){const e=n=>{const o=v(n);o&&t(o)};return process.on("message",e),()=>{process.off("message",e)}}function q(t,e={}){const{timeout:n=3e4}=e;return new Promise((o,s)=>{let a=null,r=null;const u=()=>{a&&a(),s(new Error(`IPC timeout waiting for message type: ${t}`))};a=S(d=>{d.type===t&&(r&&clearTimeout(r),a&&a(),o(d.data))}),n>0&&(r=setTimeout(u,n))})}function G(t,e){return{id:l.default.randomBytes(16).toString("hex"),timestamp:Date.now(),type:t,data:e}}function K(t){return!!(t&&typeof t=="object"&&"send"in t&&typeof t.send=="function"&&"channel"in t&&t.channel!==void 0)}function v(t){try{return w.parse(t)}catch{return null}}0&&(module.exports={IpcHandshakeSchema,cleanupIpcStubs,createIpcChannelId,createIpcMessage,getIpcStubPath,hasIpcChannel,onIpc,parseIpcMessage,readIpcStub,sendIpc,waitForIpc,writeIpcStub});
3
3
  //# sourceMappingURL=ipc.js.map