@socketsecurity/lib 3.2.2 → 3.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/abort.js +1 -1
- package/dist/agent.js +1 -1
- package/dist/ansi.js +1 -1
- package/dist/argv/flags.js +1 -1
- package/dist/argv/parse.js +1 -1
- package/dist/arrays.js +1 -1
- package/dist/bin.js +1 -1
- package/dist/cacache.js +1 -1
- package/dist/cache-with-ttl.js +1 -1
- package/dist/constants/agents.js +1 -1
- package/dist/constants/core.js +1 -1
- package/dist/constants/encoding.js +1 -1
- package/dist/constants/github.js +1 -1
- package/dist/constants/licenses.js +1 -1
- package/dist/constants/node.js +1 -1
- package/dist/constants/packages.js +1 -1
- package/dist/constants/paths.js +1 -1
- package/dist/constants/platform.js +1 -1
- package/dist/constants/process.js +1 -1
- package/dist/constants/socket.js +1 -1
- package/dist/constants/testing.js +1 -1
- package/dist/constants/time.js +1 -1
- package/dist/constants/typescript.js +1 -1
- package/dist/cover/code.js +1 -1
- package/dist/cover/formatters.js +1 -1
- package/dist/cover/type.js +1 -1
- package/dist/cover/types.js +1 -1
- package/dist/debug.js +1 -1
- package/dist/dlx-binary.js +1 -1
- package/dist/dlx-manifest.js +1 -1
- package/dist/dlx-package.js +1 -1
- package/dist/dlx.js +1 -1
- package/dist/effects/pulse-frames.js +4 -4
- package/dist/effects/text-shimmer.js +1 -1
- package/dist/effects/types.js +1 -1
- package/dist/effects/ultra.js +1 -1
- package/dist/env/ci.js +1 -1
- package/dist/env/debug.js +1 -1
- package/dist/env/github.js +1 -1
- package/dist/env/helpers.js +1 -1
- package/dist/env/home.js +1 -1
- package/dist/env/locale.js +1 -1
- package/dist/env/node-auth-token.js +1 -1
- package/dist/env/node-env.js +1 -1
- package/dist/env/npm.js +1 -1
- package/dist/env/package-manager.js +1 -1
- package/dist/env/path.js +1 -1
- package/dist/env/pre-commit.js +1 -1
- package/dist/env/rewire.js +1 -1
- package/dist/env/shell.js +1 -1
- package/dist/env/socket-cli-shadow.js +1 -1
- package/dist/env/socket-cli.js +1 -1
- package/dist/env/socket.js +1 -1
- package/dist/env/temp-dir.js +1 -1
- package/dist/env/term.js +1 -1
- package/dist/env/test.js +1 -1
- package/dist/env/windows.js +1 -1
- package/dist/env/xdg.js +1 -1
- package/dist/env.js +1 -1
- package/dist/external/@inquirer/confirm.js +16 -15
- package/dist/external/@inquirer/input.js +16 -15
- package/dist/external/@inquirer/password.js +17 -16
- package/dist/external/@inquirer/search.js +18 -17
- package/dist/external/@inquirer/select.js +19 -18
- package/dist/external/@npmcli/package-json/lib/read-package.js +7 -1
- package/dist/external/@npmcli/package-json/lib/sort.js +6 -1
- package/dist/external/@npmcli/package-json.js +18 -0
- package/dist/external/@npmcli/promise-spawn.js +2 -1
- package/dist/external/@socketregistry/is-unicode-supported.js +2 -1
- package/dist/external/@socketregistry/packageurl-js.js +3 -2
- package/dist/external/@socketregistry/yocto-spinner.js +5 -4
- package/dist/external/@yarnpkg/extensions.js +2 -1
- package/dist/external/cacache.js +10 -9
- package/dist/external/debug.js +2 -5
- package/dist/external/del.js +3 -2
- package/dist/external/fast-glob.js +3 -2
- package/dist/external/fast-sort.js +2 -1
- package/dist/external/get-east-asian-width.js +2 -1
- package/dist/external/libnpmexec.js +6 -0
- package/dist/external/libnpmpack.js +68 -71
- package/dist/external/make-fetch-happen.js +17 -20
- package/dist/external/normalize-package-data.js +3 -2
- package/dist/external/npm-package-arg.js +3 -2
- package/dist/external/pacote.js +38 -41
- package/dist/external/picomatch.js +2 -1
- package/dist/external/semver.js +2 -1
- package/dist/external/spdx-correct.js +2 -1
- package/dist/external/spdx-expression-parse.js +2 -1
- package/dist/external/streaming-iterables.js +2 -1
- package/dist/external/validate-npm-package-name.js +2 -1
- package/dist/external/which.js +2 -1
- package/dist/external/yargs-parser.js +2 -1
- package/dist/external/yoctocolors-cjs.js +2 -1
- package/dist/external/zod.js +10 -9
- package/dist/fs.js +1 -1
- package/dist/functions.js +1 -1
- package/dist/git.js +1 -1
- package/dist/github.js +1 -1
- package/dist/globs.js +1 -1
- package/dist/http-request.js +1 -1
- package/dist/ipc.js +1 -1
- package/dist/json.js +1 -1
- package/dist/links/index.js +1 -1
- package/dist/logger.d.ts +29 -4
- package/dist/logger.js +34 -5
- package/dist/maintained-node-versions.js +1 -1
- package/dist/memoization.js +1 -1
- package/dist/objects.js +1 -1
- package/dist/packages/editable.js +1 -1
- package/dist/packages/exports.js +1 -1
- package/dist/packages/isolation.js +1 -1
- package/dist/packages/licenses.js +1 -1
- package/dist/packages/manifest.js +1 -1
- package/dist/packages/normalize.js +1 -1
- package/dist/packages/operations.js +1 -1
- package/dist/packages/paths.js +1 -1
- package/dist/packages/provenance.js +1 -1
- package/dist/packages/specs.js +1 -1
- package/dist/packages/validation.js +1 -1
- package/dist/packages.js +1 -1
- package/dist/path.js +1 -1
- package/dist/paths/rewire.js +1 -1
- package/dist/paths.js +1 -1
- package/dist/performance.js +1 -1
- package/dist/process-lock.js +1 -1
- package/dist/promise-queue.js +1 -1
- package/dist/promises.js +1 -1
- package/dist/regexps.js +1 -1
- package/dist/sea.js +1 -1
- package/dist/shadow.js +1 -1
- package/dist/signal-exit.js +1 -1
- package/dist/sorts.js +1 -1
- package/dist/spawn.js +1 -1
- package/dist/spinner.js +1 -1
- package/dist/ssri.js +1 -1
- package/dist/stdio/clear.js +1 -1
- package/dist/stdio/divider.js +1 -1
- package/dist/stdio/footer.js +1 -1
- package/dist/stdio/header.js +1 -1
- package/dist/stdio/mask.js +1 -1
- package/dist/stdio/progress.js +1 -1
- package/dist/stdio/prompts.js +1 -1
- package/dist/stdio/stderr.js +1 -1
- package/dist/stdio/stdout.js +1 -1
- package/dist/streams.js +1 -1
- package/dist/strings.js +1 -1
- package/dist/suppress-warnings.js +1 -1
- package/dist/tables.js +1 -1
- package/dist/temporary-executor.js +1 -1
- package/dist/themes/context.js +1 -1
- package/dist/themes/index.js +1 -1
- package/dist/themes/themes.js +1 -1
- package/dist/themes/types.js +1 -1
- package/dist/themes/utils.js +1 -1
- package/dist/types.js +1 -1
- package/dist/url.js +1 -1
- package/dist/utils/get-ipc.js +1 -1
- package/dist/validation/json-parser.js +1 -1
- package/dist/validation/types.js +1 -1
- package/dist/versions.js +1 -1
- package/dist/words.js +1 -1
- package/dist/zod.js +1 -1
- package/package.json +1 -1
- package/dist/abort.js.map +0 -7
- package/dist/agent.js.map +0 -7
- package/dist/ansi.js.map +0 -7
- package/dist/argv/flags.js.map +0 -7
- package/dist/argv/parse.js.map +0 -7
- package/dist/arrays.js.map +0 -7
- package/dist/bin.js.map +0 -7
- package/dist/cacache.js.map +0 -7
- package/dist/cache-with-ttl.js.map +0 -7
- package/dist/constants/agents.js.map +0 -7
- package/dist/constants/core.js.map +0 -7
- package/dist/constants/encoding.js.map +0 -7
- package/dist/constants/github.js.map +0 -7
- package/dist/constants/licenses.js.map +0 -7
- package/dist/constants/node.js.map +0 -7
- package/dist/constants/packages.js.map +0 -7
- package/dist/constants/paths.js.map +0 -7
- package/dist/constants/platform.js.map +0 -7
- package/dist/constants/process.js.map +0 -7
- package/dist/constants/socket.js.map +0 -7
- package/dist/constants/testing.js.map +0 -7
- package/dist/constants/time.js.map +0 -7
- package/dist/constants/typescript.js.map +0 -7
- package/dist/cover/code.js.map +0 -7
- package/dist/cover/formatters.js.map +0 -7
- package/dist/cover/type.js.map +0 -7
- package/dist/cover/types.js.map +0 -7
- package/dist/debug.js.map +0 -7
- package/dist/dlx-binary.js.map +0 -7
- package/dist/dlx-manifest.js.map +0 -7
- package/dist/dlx-package.js.map +0 -7
- package/dist/dlx.js.map +0 -7
- package/dist/effects/pulse-frames.js.map +0 -7
- package/dist/effects/text-shimmer.js.map +0 -7
- package/dist/effects/types.js.map +0 -7
- package/dist/effects/ultra.js.map +0 -7
- package/dist/env/ci.js.map +0 -7
- package/dist/env/debug.js.map +0 -7
- package/dist/env/github.js.map +0 -7
- package/dist/env/helpers.js.map +0 -7
- package/dist/env/home.js.map +0 -7
- package/dist/env/locale.js.map +0 -7
- package/dist/env/node-auth-token.js.map +0 -7
- package/dist/env/node-env.js.map +0 -7
- package/dist/env/npm.js.map +0 -7
- package/dist/env/package-manager.js.map +0 -7
- package/dist/env/path.js.map +0 -7
- package/dist/env/pre-commit.js.map +0 -7
- package/dist/env/rewire.js.map +0 -7
- package/dist/env/shell.js.map +0 -7
- package/dist/env/socket-cli-shadow.js.map +0 -7
- package/dist/env/socket-cli.js.map +0 -7
- package/dist/env/socket.js.map +0 -7
- package/dist/env/temp-dir.js.map +0 -7
- package/dist/env/term.js.map +0 -7
- package/dist/env/test.js.map +0 -7
- package/dist/env/windows.js.map +0 -7
- package/dist/env/xdg.js.map +0 -7
- package/dist/env.js.map +0 -7
- package/dist/external/@npmcli/package-json/index.js +0 -1
- package/dist/external/@socketregistry/is-unicode-supported.d.ts +0 -2
- package/dist/external/@socketregistry/yocto-spinner.d.ts +0 -12
- package/dist/external/@yarnpkg/extensions.d.ts +0 -4
- package/dist/external/cacache.d.ts +0 -86
- package/dist/external/debug.d.ts +0 -22
- package/dist/external/del.d.ts +0 -1
- package/dist/external/fast-sort.d.ts +0 -3
- package/dist/external/get-east-asian-width.d.ts +0 -5
- package/dist/external/libnpmexec.d.ts +0 -33
- package/dist/external/libnpmpack.d.ts +0 -2
- package/dist/external/make-fetch-happen.d.ts +0 -15
- package/dist/external/pacote.d.ts +0 -14
- package/dist/external/semver.d.ts +0 -2
- package/dist/external/yargs-parser.d.ts +0 -2
- package/dist/external/yoctocolors-cjs.d.ts +0 -52
- package/dist/external/zod.d.ts +0 -1
- package/dist/fs.js.map +0 -7
- package/dist/functions.js.map +0 -7
- package/dist/git.js.map +0 -7
- package/dist/github.js.map +0 -7
- package/dist/globs.js.map +0 -7
- package/dist/http-request.js.map +0 -7
- package/dist/ipc.js.map +0 -7
- package/dist/json.js.map +0 -7
- package/dist/links/index.js.map +0 -7
- package/dist/logger.js.map +0 -7
- package/dist/maintained-node-versions.js.map +0 -7
- package/dist/memoization.js.map +0 -7
- package/dist/objects.js.map +0 -7
- package/dist/packages/editable.js.map +0 -7
- package/dist/packages/exports.js.map +0 -7
- package/dist/packages/isolation.js.map +0 -7
- package/dist/packages/licenses.js.map +0 -7
- package/dist/packages/manifest.js.map +0 -7
- package/dist/packages/normalize.js.map +0 -7
- package/dist/packages/operations.js.map +0 -7
- package/dist/packages/paths.js.map +0 -7
- package/dist/packages/provenance.js.map +0 -7
- package/dist/packages/specs.js.map +0 -7
- package/dist/packages/validation.js.map +0 -7
- package/dist/packages.js.map +0 -7
- package/dist/path.js.map +0 -7
- package/dist/paths/rewire.js.map +0 -7
- package/dist/paths.js.map +0 -7
- package/dist/performance.js.map +0 -7
- package/dist/process-lock.js.map +0 -7
- package/dist/promise-queue.js.map +0 -7
- package/dist/promises.js.map +0 -7
- package/dist/regexps.js.map +0 -7
- package/dist/sea.js.map +0 -7
- package/dist/shadow.js.map +0 -7
- package/dist/signal-exit.js.map +0 -7
- package/dist/sorts.js.map +0 -7
- package/dist/spawn.js.map +0 -7
- package/dist/spinner.js.map +0 -7
- package/dist/ssri.js.map +0 -7
- package/dist/stdio/clear.js.map +0 -7
- package/dist/stdio/divider.js.map +0 -7
- package/dist/stdio/footer.js.map +0 -7
- package/dist/stdio/header.js.map +0 -7
- package/dist/stdio/mask.js.map +0 -7
- package/dist/stdio/progress.js.map +0 -7
- package/dist/stdio/prompts.js.map +0 -7
- package/dist/stdio/stderr.js.map +0 -7
- package/dist/stdio/stdout.js.map +0 -7
- package/dist/streams.js.map +0 -7
- package/dist/strings.js.map +0 -7
- package/dist/suppress-warnings.js.map +0 -7
- package/dist/tables.js.map +0 -7
- package/dist/temporary-executor.js.map +0 -7
- package/dist/themes/context.js.map +0 -7
- package/dist/themes/index.js.map +0 -7
- package/dist/themes/themes.js.map +0 -7
- package/dist/themes/types.js.map +0 -7
- package/dist/themes/utils.js.map +0 -7
- package/dist/types.js.map +0 -7
- package/dist/url.js.map +0 -7
- package/dist/utils/get-ipc.js.map +0 -7
- package/dist/validation/json-parser.js.map +0 -7
- package/dist/validation/types.js.map +0 -7
- package/dist/versions.js.map +0 -7
- package/dist/words.js.map +0 -7
- package/dist/zod.js.map +0 -7
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/packages/operations.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package operations including extraction, packing, and I/O.\n */\n\nimport {\n getPackageExtensions,\n getPackumentCache,\n getPacoteCachePath,\n} from '#constants/packages'\nimport { getAbortSignal } from '#constants/process'\nimport { REGISTRY_SCOPE_DELIMITER } from '#constants/socket'\n\nconst abortSignal = getAbortSignal()\nconst packageExtensions = getPackageExtensions()\nconst packumentCache = getPackumentCache()\nconst pacoteCachePath = getPacoteCachePath()\n\nimport { readJson, readJsonSync } from '../fs'\nimport { isObjectObject, merge } from '../objects'\nimport type {\n ExtractOptions,\n NormalizeOptions,\n PackageJson,\n PacoteOptions,\n ReadPackageJsonOptions,\n} from '../packages'\nimport { normalizePackageJson } from './normalize'\nimport { resolvePackageJsonPath } from './paths'\nimport {\n getRepoUrlDetails,\n gitHubTagRefUrl,\n gitHubTgzUrl,\n isGitHubTgzSpec,\n isGitHubUrlSpec,\n} from './specs'\n\nlet _cacache: typeof import('cacache') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getCacache() {\n if (_cacache === undefined) {\n _cacache = /*@__PURE__*/ require('../external/cacache')\n }\n return _cacache as typeof import('cacache')\n}\n\n// Type for make-fetch-happen fetcher function.\ntype MakeFetchHappenFetcher = ((\n url: string,\n opts?: unknown,\n) => Promise<Response>) & {\n defaults: (opts: unknown) => MakeFetchHappenFetcher\n delete: (url: string, opts?: unknown) => Promise<boolean>\n}\n\nlet _fetcher: MakeFetchHappenFetcher | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFetcher() {\n if (_fetcher === undefined) {\n const makeFetchHappen =\n /*@__PURE__*/ require('../external/make-fetch-happen')\n _fetcher = makeFetchHappen.defaults({\n cachePath: pacoteCachePath,\n // Prefer-offline: Staleness checks for cached data will be bypassed, but\n // missing data will be requested from the server.\n // https://github.com/npm/make-fetch-happen?tab=readme-ov-file#--optscache\n cache: 'force-cache',\n })\n }\n return _fetcher as MakeFetchHappenFetcher\n}\n\nlet _npmPackageArg: typeof import('npm-package-arg') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getNpmPackageArg() {\n if (_npmPackageArg === undefined) {\n _npmPackageArg = /*@__PURE__*/ require('../external/npm-package-arg')\n }\n return _npmPackageArg as typeof import('npm-package-arg')\n}\n\nlet _pack: typeof import('../external/libnpmpack') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPack() {\n if (_pack === undefined) {\n _pack = /*@__PURE__*/ require('../external/libnpmpack')\n }\n return _pack as typeof import('../external/libnpmpack')\n}\n\nlet _PackageURL:\n | typeof import('@socketregistry/packageurl-js').PackageURL\n | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPackageURL() {\n if (_PackageURL === undefined) {\n // The 'packageurl-js' package is browser safe.\n const packageUrlJs =\n /*@__PURE__*/ require('../external/@socketregistry/packageurl-js')\n _PackageURL = packageUrlJs.PackageURL\n }\n return _PackageURL as typeof import('@socketregistry/packageurl-js').PackageURL\n}\n\nlet _pacote: typeof import('pacote') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPacote() {\n if (_pacote === undefined) {\n _pacote = /*@__PURE__*/ require('../external/pacote')\n }\n return _pacote as typeof import('pacote')\n}\n\nlet _semver: typeof import('semver') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getSemver() {\n if (_semver === undefined) {\n // The 'semver' package is browser safe.\n _semver = /*@__PURE__*/ require('../external/semver')\n }\n return _semver as typeof import('semver')\n}\n\nlet _toEditablePackageJson:\n | ((pkgJson: PackageJson, options?: unknown) => Promise<PackageJson>)\n | undefined\n/**\n * Get the toEditablePackageJson function from editable module.\n * Lazy loaded to avoid circular dependency.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction _getToEditablePackageJson() {\n if (_toEditablePackageJson === undefined) {\n // Use path alias for reliable resolution in both test and production environments.\n _toEditablePackageJson =\n /*@__PURE__*/ require('#packages/editable').toEditablePackageJson\n }\n return _toEditablePackageJson as (\n pkgJson: PackageJson,\n options?: unknown,\n ) => Promise<PackageJson>\n}\n\nlet _toEditablePackageJsonSync:\n | ((pkgJson: PackageJson, options?: unknown) => PackageJson)\n | undefined\n/**\n * Get the toEditablePackageJsonSync function from editable module.\n * Lazy loaded to avoid circular dependency.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction _getToEditablePackageJsonSync() {\n if (_toEditablePackageJsonSync === undefined) {\n // Use path alias for reliable resolution in both test and production environments.\n _toEditablePackageJsonSync =\n /*@__PURE__*/ require('#packages/editable').toEditablePackageJsonSync\n }\n return _toEditablePackageJsonSync as (\n pkgJson: PackageJson,\n options?: unknown,\n ) => PackageJson\n}\n\n/**\n * Extract a package to a destination directory.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function extractPackage(\n pkgNameOrId: string,\n options?: ExtractOptions,\n callback?: (destPath: string) => Promise<unknown>,\n): Promise<void> {\n let actualCallback = callback\n let actualOptions = options\n // biome-ignore lint/complexity/noArguments: Function overload support.\n if (arguments.length === 2 && typeof options === 'function') {\n actualCallback = options\n actualOptions = undefined\n }\n const { dest, tmpPrefix, ...extractOptions_ } = {\n __proto__: null,\n ...actualOptions,\n } as ExtractOptions\n const extractOptions = {\n packumentCache,\n preferOffline: true,\n ...extractOptions_,\n }\n const pacote = getPacote()\n if (typeof dest === 'string') {\n await pacote.extract(pkgNameOrId, dest, extractOptions)\n if (typeof actualCallback === 'function') {\n await actualCallback(dest)\n }\n } else {\n // The DefinitelyTyped types for cacache.tmp.withTmp are incorrect.\n // It DOES returns a promise.\n const cacache = getCacache()\n await cacache.tmp.withTmp(\n pacoteCachePath,\n { tmpPrefix },\n async (tmpDirPath: string) => {\n await pacote.extract(pkgNameOrId, tmpDirPath, extractOptions)\n if (typeof actualCallback === 'function') {\n await actualCallback(tmpDirPath)\n }\n },\n )\n }\n}\n\n/**\n * Find package extensions for a given package.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function findPackageExtensions(\n pkgName: string,\n pkgVer: string,\n): unknown {\n let result: unknown\n for (const entry of packageExtensions) {\n const selector = String(entry[0])\n const ext = entry[1]\n const lastAtSignIndex = selector.lastIndexOf('@')\n const name = selector.slice(0, lastAtSignIndex)\n if (pkgName === name) {\n const semver = getSemver()\n const range = selector.slice(lastAtSignIndex + 1)\n if (semver.satisfies(pkgVer, range)) {\n if (result === undefined) {\n result = {}\n }\n if (typeof ext === 'object' && ext !== null) {\n merge(result as object, ext)\n }\n }\n }\n }\n return result\n}\n\n/**\n * Get the release tag for a version.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function getReleaseTag(spec: string): string {\n if (!spec) {\n return ''\n }\n // Handle scoped packages like @scope/package vs @scope/package@tag.\n let atIndex = -1\n if (spec.startsWith('@')) {\n // Find the second @ for scoped packages.\n atIndex = spec.indexOf('@', 1)\n } else {\n // Find the first @ for unscoped packages.\n atIndex = spec.indexOf('@')\n }\n if (atIndex !== -1) {\n return spec.slice(atIndex + 1)\n }\n return ''\n}\n\n/**\n * Pack a package tarball using pacote.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function packPackage(\n spec: string,\n options?: PacoteOptions,\n): Promise<unknown> {\n const pack = getPack()\n return await pack(spec, {\n __proto__: null,\n signal: abortSignal,\n ...options,\n packumentCache,\n preferOffline: true,\n } as PacoteOptions)\n}\n\n/**\n * Read and parse a package.json file asynchronously.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function readPackageJson(\n filepath: string,\n options?: ReadPackageJsonOptions,\n): Promise<PackageJson | undefined> {\n const { editable, normalize, throws, ...normalizeOptions } = {\n __proto__: null,\n ...options,\n } as ReadPackageJsonOptions\n const pkgJson = (await readJson(resolvePackageJsonPath(filepath), {\n throws,\n })) as PackageJson | undefined\n if (pkgJson) {\n if (editable) {\n const toEditablePackageJson = _getToEditablePackageJson()\n return await toEditablePackageJson(pkgJson, {\n path: filepath,\n normalize,\n ...normalizeOptions,\n })\n }\n return normalize ? normalizePackageJson(pkgJson, normalizeOptions) : pkgJson\n }\n return undefined\n}\n\n/**\n * Read and parse package.json from a file path synchronously.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function readPackageJsonSync(\n filepath: string,\n options?: NormalizeOptions & { editable?: boolean; throws?: boolean },\n): PackageJson | undefined {\n const { editable, normalize, throws, ...normalizeOptions } = {\n __proto__: null,\n ...options,\n } as NormalizeOptions & {\n editable?: boolean\n throws?: boolean\n normalize?: boolean\n }\n const pkgJson = readJsonSync(resolvePackageJsonPath(filepath), { throws }) as\n | PackageJson\n | undefined\n if (pkgJson) {\n if (editable) {\n const toEditablePackageJsonSync = _getToEditablePackageJsonSync()\n return toEditablePackageJsonSync(pkgJson, {\n path: filepath,\n normalize,\n ...normalizeOptions,\n })\n }\n return normalize ? normalizePackageJson(pkgJson, normalizeOptions) : pkgJson\n }\n return undefined\n}\n\n/**\n * Resolve GitHub tarball URL for a package specifier.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function resolveGitHubTgzUrl(\n pkgNameOrId: string,\n where?: unknown,\n): Promise<string> {\n const whereIsPkgJson = isObjectObject(where)\n const pkgJson = whereIsPkgJson\n ? where\n : await readPackageJson(where as string, { normalize: true })\n if (!pkgJson) {\n return ''\n }\n const { version } = pkgJson\n const npmPackageArg = getNpmPackageArg()\n const parsedSpec = npmPackageArg(\n pkgNameOrId,\n whereIsPkgJson ? undefined : (where as string),\n )\n const isTarballUrl = isGitHubTgzSpec(parsedSpec)\n if (isTarballUrl) {\n return parsedSpec.saveSpec || ''\n }\n const isGitHubUrl = isGitHubUrlSpec(parsedSpec)\n const repository = pkgJson.repository as { url?: string }\n const { project, user } = (isGitHubUrl\n ? parsedSpec.hosted\n : getRepoUrlDetails(repository?.url)) || { project: '', user: '' }\n\n if (user && project) {\n let apiUrl = ''\n if (isGitHubUrl) {\n apiUrl = gitHubTagRefUrl(user, project, parsedSpec.gitCommittish || '')\n } else {\n const fetcher = getFetcher()\n const versionStr = version as string\n // First try to resolve the sha for a tag starting with \"v\", e.g. v1.2.3.\n apiUrl = gitHubTagRefUrl(user, project, `v${versionStr}`)\n if (!(await fetcher(apiUrl, { method: 'head' })).ok) {\n // If a sha isn't found, try again with the \"v\" removed, e.g. 1.2.3.\n apiUrl = gitHubTagRefUrl(user, project, versionStr)\n if (!(await fetcher(apiUrl, { method: 'head' })).ok) {\n apiUrl = ''\n }\n }\n }\n if (apiUrl) {\n const fetcher = getFetcher()\n const resp = await fetcher(apiUrl)\n const json = (await resp.json()) as { object?: { sha?: string } }\n const sha = json?.object?.sha\n if (sha) {\n return gitHubTgzUrl(user, project, sha)\n }\n }\n }\n return ''\n}\n\n/**\n * Resolve full package name from a PURL object with custom delimiter.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolvePackageName(\n purlObj: { name: string; namespace?: string },\n delimiter: string = '/',\n): string {\n const { name, namespace } = purlObj\n return `${namespace ? `${namespace}${delimiter}` : ''}${name}`\n}\n\n/**\n * Convert npm package name to Socket registry format with delimiter.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRegistryPackageName(pkgName: string): string {\n const purlObj = getPackageURL().fromString(`pkg:npm/${pkgName}`)\n return purlObj.namespace\n ? `${purlObj.namespace.slice(1)}${REGISTRY_SCOPE_DELIMITER}${purlObj.name}`\n : pkgName\n}\n\n// Re-export types from lib/packages.\nexport type { PackageJson } from '../packages'\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/packages/paths.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package.json path resolution utilities.\n */\n\nimport { normalizePath } from '../path'\n\nlet _path: typeof import('path') | undefined\n/**\n * Get the path module.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path as typeof import('path')\n}\n\n/**\n * Resolve directory path from a package.json file path.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolvePackageJsonDirname(filepath: string): string {\n if (filepath.endsWith('package.json')) {\n const path = getPath()\n return normalizePath(path.dirname(filepath))\n }\n return normalizePath(filepath)\n}\n\n/**\n * Resolve full path to package.json from a directory or file path.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolvePackageJsonPath(filepath: string): string {\n if (filepath.endsWith('package.json')) {\n return normalizePath(filepath)\n }\n const path = getPath()\n return normalizePath(path.join(filepath, 'package.json'))\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kBAA8B;AAE9B,IAAI;AAAA;AAKJ,SAAS,UAAU;AACjB,MAAI,UAAU,QAAW;AAGvB,YAAsB,QAAQ,WAAW;AAAA,EAC3C;AACA,SAAO;AACT;AAAA;AAMO,SAAS,0BAA0B,UAA0B;AAClE,MAAI,SAAS,SAAS,cAAc,GAAG;AACrC,UAAM,OAAO,wBAAQ;AACrB,eAAO,2BAAc,KAAK,QAAQ,QAAQ,CAAC;AAAA,EAC7C;AACA,aAAO,2BAAc,QAAQ;AAC/B;AAAA;AAMO,SAAS,uBAAuB,UAA0B;AAC/D,MAAI,SAAS,SAAS,cAAc,GAAG;AACrC,eAAO,2BAAc,QAAQ;AAAA,EAC/B;AACA,QAAM,OAAO,wBAAQ;AACrB,aAAO,2BAAc,KAAK,KAAK,UAAU,cAAc,CAAC;AAC1D;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/packages/provenance.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package provenance and attestation verification utilities.\n */\n\nimport { NPM_REGISTRY_URL } from '#constants/agents'\n\nimport { createCompositeAbortSignal, createTimeoutSignal } from '../abort'\nimport type { ProvenanceOptions } from '../packages'\nimport { parseUrl } from '../url'\n\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ArrayIsArray = Array.isArray\n\nconst SLSA_PROVENANCE_V0_2 = 'https://slsa.dev/provenance/v0.2'\nconst SLSA_PROVENANCE_V1_0 = 'https://slsa.dev/provenance/v1'\n\nlet _fetcher: typeof import('make-fetch-happen') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFetcher() {\n if (_fetcher === undefined) {\n const makeFetchHappen =\n /*@__PURE__*/ require('../external/make-fetch-happen')\n // Lazy load constants to avoid circular dependencies.\n const { getPacoteCachePath } =\n /*@__PURE__*/ require('../constants/packages')\n _fetcher = makeFetchHappen.defaults({\n cachePath: getPacoteCachePath(),\n // Prefer-offline: Staleness checks for cached data will be bypassed, but\n // missing data will be requested from the server.\n // https://github.com/npm/make-fetch-happen?tab=readme-ov-file#--optscache\n cache: 'force-cache',\n })\n }\n return _fetcher as typeof import('make-fetch-happen')\n}\n\n/**\n * Extract and filter SLSA provenance attestations from attestation data.\n */\nfunction getAttestations(attestationData: unknown): unknown[] {\n const data = attestationData as { attestations?: unknown[] }\n if (!data.attestations || !ArrayIsArray(data.attestations)) {\n return []\n }\n\n return data.attestations.filter((attestation: unknown) => {\n const att = attestation as { predicateType?: string }\n return (\n att.predicateType === SLSA_PROVENANCE_V0_2 ||\n att.predicateType === SLSA_PROVENANCE_V1_0\n )\n })\n}\n\n/**\n * Find the first attestation with valid provenance data.\n */\nfunction findProvenance(attestations: unknown[]): unknown {\n for (const attestation of attestations) {\n const att = attestation as {\n bundle?: { dsseEnvelope?: { payload?: string } }\n predicate?: unknown\n }\n try {\n let predicate = att.predicate\n\n // If predicate is not directly available, try to decode from DSSE envelope\n if (!predicate && att.bundle?.dsseEnvelope?.payload) {\n try {\n const decodedPayload = Buffer.from(\n att.bundle.dsseEnvelope.payload,\n 'base64',\n ).toString('utf8')\n const statement = JSON.parse(decodedPayload)\n predicate = statement.predicate\n } catch {\n // Failed to decode, continue to next attestation\n continue\n }\n }\n\n const predicateData = predicate as {\n buildDefinition?: { externalParameters?: unknown }\n }\n if (predicateData?.buildDefinition?.externalParameters) {\n return {\n predicate,\n externalParameters: predicateData.buildDefinition.externalParameters,\n }\n }\n // c8 ignore start - Error handling for malformed attestation data should continue processing other attestations.\n } catch {\n // Continue checking other attestations if one fails to parse\n }\n // c8 ignore stop\n }\n return undefined\n}\n\n/**\n * Check if a value indicates a trusted publisher (GitHub or GitLab).\n */\nfunction isTrustedPublisher(value: unknown): boolean {\n if (typeof value !== 'string' || !value) {\n return false\n }\n\n let url = parseUrl(value)\n let hostname = url?.hostname\n\n // Handle GitHub workflow refs with @ syntax by trying the first part.\n // Example: \"https://github.com/owner/repo/.github/workflows/ci.yml@refs/heads/main\"\n if (!url && value.includes('@')) {\n const firstPart = value.split('@')[0]\n if (firstPart) {\n url = parseUrl(firstPart)\n }\n if (url) {\n hostname = url.hostname\n }\n }\n\n // Try common URL prefixes if not already a complete URL.\n if (!url) {\n const httpsUrl = parseUrl(`https://${value}`)\n if (httpsUrl) {\n hostname = httpsUrl.hostname\n }\n }\n\n if (hostname) {\n return (\n hostname === 'github.com' ||\n hostname.endsWith('.github.com') ||\n hostname === 'gitlab.com' ||\n hostname.endsWith('.gitlab.com')\n )\n }\n\n // Fallback: check for provider keywords in non-URL strings.\n return value.includes('github') || value.includes('gitlab')\n}\n\n/**\n * Convert raw attestation data to user-friendly provenance details.\n */\nexport function getProvenanceDetails(attestationData: unknown): unknown {\n const attestations = getAttestations(attestationData)\n if (!attestations.length) {\n return undefined\n }\n // Find the first attestation with valid provenance data.\n const provenance = findProvenance(attestations)\n if (!provenance) {\n return { level: 'attested' }\n }\n\n const provenanceData = provenance as {\n externalParameters?: {\n context?: string\n ref?: string\n repository?: string\n run_id?: string\n sha?: string\n workflow?: {\n ref?: string\n repository?: string\n }\n workflow_ref?: string\n }\n predicate?: {\n buildDefinition?: { buildType?: string }\n }\n }\n const { externalParameters, predicate } = provenanceData\n const def = predicate?.buildDefinition\n\n // Handle both SLSA v0.2 (direct properties) and v1 (nested workflow object)\n const workflow = externalParameters?.workflow\n const workflowRef = workflow?.ref || externalParameters?.workflow_ref\n const workflowUrl = externalParameters?.context\n const workflowPlatform = def?.buildType\n const repository = workflow?.repository || externalParameters?.repository\n const gitRef = externalParameters?.ref || workflow?.ref\n const commitSha = externalParameters?.sha\n const workflowRunId = externalParameters?.run_id\n\n // Check for trusted publishers (GitHub Actions, GitLab CI/CD).\n const trusted =\n isTrustedPublisher(workflowRef) ||\n isTrustedPublisher(workflowUrl) ||\n isTrustedPublisher(workflowPlatform) ||\n isTrustedPublisher(repository)\n\n return {\n commitSha,\n gitRef,\n level: trusted ? 'trusted' : 'attested',\n repository,\n workflowRef,\n workflowUrl,\n workflowPlatform,\n workflowRunId,\n }\n}\n\n/**\n * Fetch package provenance information from npm registry.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function fetchPackageProvenance(\n pkgName: string,\n pkgVersion: string,\n options?: ProvenanceOptions,\n): Promise<unknown> {\n const { signal, timeout = 10_000 } = {\n __proto__: null,\n ...options,\n } as ProvenanceOptions\n\n if (signal?.aborted) {\n return undefined\n }\n\n // Create composite signal combining external signal with timeout\n const timeoutSignal = createTimeoutSignal(timeout)\n const compositeSignal = createCompositeAbortSignal(signal, timeoutSignal)\n const fetcher = getFetcher()\n\n try {\n const response = await fetcher(\n // The npm registry attestations API endpoint.\n `${NPM_REGISTRY_URL}/-/npm/v1/attestations/${encodeURIComponent(pkgName)}@${encodeURIComponent(pkgVersion)}`,\n {\n method: 'GET',\n signal: compositeSignal,\n headers: {\n 'User-Agent': 'socket-registry',\n },\n } as {\n method: string\n signal: AbortSignal\n headers: Record<string, string>\n },\n )\n if (response.ok) {\n return getProvenanceDetails(await response.json())\n }\n } catch {}\n return undefined\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/packages/specs.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package spec parsing and GitHub URL utilities.\n */\n\nimport { isObjectObject } from '../objects'\nimport { isNonEmptyString } from '../strings'\n\nlet _npmPackageArg: typeof import('npm-package-arg') | undefined\n/**\n * Get the npm-package-arg module.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getNpmPackageArg() {\n if (_npmPackageArg === undefined) {\n _npmPackageArg = /*@__PURE__*/ require('../external/npm-package-arg')\n }\n return _npmPackageArg as typeof import('npm-package-arg')\n}\n\n/**\n * Extract user and project from GitHub repository URL.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function getRepoUrlDetails(repoUrl: string = ''): {\n user: string\n project: string\n} {\n const userAndRepo = repoUrl.replace(/^.+github.com\\//, '').split('/')\n const user = userAndRepo[0] || ''\n const project =\n userAndRepo.length > 1 ? userAndRepo[1]?.slice(0, -'.git'.length) || '' : ''\n return { user, project }\n}\n\n/**\n * Generate GitHub API URL for a tag reference.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function gitHubTagRefUrl(\n user: string,\n project: string,\n tag: string,\n): string {\n return `https://api.github.com/repos/${user}/${project}/git/ref/tags/${tag}`\n}\n\n/**\n * Generate GitHub tarball download URL for a commit SHA.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function gitHubTgzUrl(\n user: string,\n project: string,\n sha: string,\n): string {\n return `https://github.com/${user}/${project}/archive/${sha}.tar.gz`\n}\n\n/**\n * Check if a package specifier is a GitHub tarball URL.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isGitHubTgzSpec(spec: unknown, where?: string): boolean {\n let parsedSpec: unknown\n if (isObjectObject(spec)) {\n parsedSpec = spec\n } else {\n const npmPackageArg = getNpmPackageArg()\n parsedSpec = npmPackageArg(spec as string, where)\n }\n const typedSpec = parsedSpec as { type?: string; saveSpec?: string }\n return (\n typedSpec.type === 'remote' && !!typedSpec.saveSpec?.endsWith('.tar.gz')\n )\n}\n\n/**\n * Check if a package specifier is a GitHub URL with committish.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isGitHubUrlSpec(spec: unknown, where?: string): boolean {\n let parsedSpec: unknown\n if (isObjectObject(spec)) {\n parsedSpec = spec\n } else {\n const npmPackageArg = getNpmPackageArg()\n parsedSpec = npmPackageArg(spec as string, where)\n }\n const typedSpec = parsedSpec as {\n gitCommittish?: string\n hosted?: { domain?: string }\n type?: string\n }\n return (\n typedSpec.type === 'git' &&\n typedSpec.hosted?.domain === 'github.com' &&\n isNonEmptyString(typedSpec.gitCommittish)\n )\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,qBAA+B;AAC/B,qBAAiC;AAEjC,IAAI;AAAA;AAKJ,SAAS,mBAAmB;AAC1B,MAAI,mBAAmB,QAAW;AAChC,qBAA+B,QAAQ,6BAA6B;AAAA,EACtE;AACA,SAAO;AACT;AAAA;AAMO,SAAS,kBAAkB,UAAkB,IAGlD;AACA,QAAM,cAAc,QAAQ,QAAQ,mBAAmB,EAAE,EAAE,MAAM,GAAG;AACpE,QAAM,OAAO,YAAY,CAAC,KAAK;AAC/B,QAAM,UACJ,YAAY,SAAS,IAAI,YAAY,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,MAAM,KAAK,KAAK;AAC5E,SAAO,EAAE,MAAM,QAAQ;AACzB;AAAA;AAMO,SAAS,gBACd,MACA,SACA,KACQ;AACR,SAAO,gCAAgC,IAAI,IAAI,OAAO,iBAAiB,GAAG;AAC5E;AAAA;AAMO,SAAS,aACd,MACA,SACA,KACQ;AACR,SAAO,sBAAsB,IAAI,IAAI,OAAO,YAAY,GAAG;AAC7D;AAAA;AAMO,SAAS,gBAAgB,MAAe,OAAyB;AACtE,MAAI;AACJ,UAAI,+BAAe,IAAI,GAAG;AACxB,iBAAa;AAAA,EACf,OAAO;AACL,UAAM,gBAAgB,iCAAiB;AACvC,iBAAa,cAAc,MAAgB,KAAK;AAAA,EAClD;AACA,QAAM,YAAY;AAClB,SACE,UAAU,SAAS,YAAY,CAAC,CAAC,UAAU,UAAU,SAAS,SAAS;AAE3E;AAAA;AAMO,SAAS,gBAAgB,MAAe,OAAyB;AACtE,MAAI;AACJ,UAAI,+BAAe,IAAI,GAAG;AACxB,iBAAa;AAAA,EACf,OAAO;AACL,UAAM,gBAAgB,iCAAiB;AACvC,iBAAa,cAAc,MAAgB,KAAK;AAAA,EAClD;AACA,QAAM,YAAY;AAKlB,SACE,UAAU,SAAS,SACnB,UAAU,QAAQ,WAAW,oBAC7B,iCAAiB,UAAU,aAAa;AAE5C;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/packages/validation.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package name validation utilities.\n */\n\nlet _validateNpmPackageName:\n | typeof import('validate-npm-package-name')\n | undefined\n/**\n * Get the validate-npm-package-name module.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getValidateNpmPackageName() {\n if (_validateNpmPackageName === undefined) {\n _validateNpmPackageName =\n /*@__PURE__*/ require('../external/validate-npm-package-name')\n }\n return _validateNpmPackageName as typeof import('validate-npm-package-name')\n}\n\n/**\n * Check if package name is a blessed Socket.dev package.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isBlessedPackageName(name: unknown): boolean {\n return (\n typeof name === 'string' &&\n (name === 'sfw' ||\n name === 'socket' ||\n name.startsWith('@socketoverride/') ||\n name.startsWith('@socketregistry/') ||\n name.startsWith('@socketsecurity/'))\n )\n}\n\n/**\n * Check if a type string represents a registry fetcher type.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isRegistryFetcherType(type: string): boolean {\n // RegistryFetcher spec.type check based on:\n // https://github.com/npm/pacote/blob/v19.0.0/lib/fetcher.js#L467-L488\n return (\n type === 'alias' || type === 'range' || type === 'tag' || type === 'version'\n )\n}\n\n/**\n * Check if a package name is valid according to npm naming rules.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isValidPackageName(name: string): boolean {\n const validateNpmPackageName = getValidateNpmPackageName()\n return validateNpmPackageName(name).validForOldPackages\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,IAAI;AAAA;AAOJ,SAAS,4BAA4B;AACnC,MAAI,4BAA4B,QAAW;AACzC,8BACgB,QAAQ,uCAAuC;AAAA,EACjE;AACA,SAAO;AACT;AAAA;AAMO,SAAS,qBAAqB,MAAwB;AAC3D,SACE,OAAO,SAAS,aACf,SAAS,SACR,SAAS,YACT,KAAK,WAAW,kBAAkB,KAClC,KAAK,WAAW,kBAAkB,KAClC,KAAK,WAAW,kBAAkB;AAExC;AAAA;AAMO,SAAS,sBAAsB,MAAuB;AAG3D,SACE,SAAS,WAAW,SAAS,WAAW,SAAS,SAAS,SAAS;AAEvE;AAAA;AAMO,SAAS,mBAAmB,MAAuB;AACxD,QAAM,yBAAyB,0CAA0B;AACzD,SAAO,uBAAuB,IAAI,EAAE;AACtC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/packages.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/packages.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Package registry management with Socket.dev specific utilities.\n * Provides npm package analysis, dependency resolution, and registry operations.\n */\n\nimport type { CategoryString } from '#types'\n\nimport {\n getEditablePackageJsonClass,\n pkgJsonToEditable,\n toEditablePackageJson,\n toEditablePackageJsonSync,\n} from './packages/editable'\nimport {\n findTypesForSubpath,\n getExportFilePaths,\n getSubpaths,\n isConditionalExports,\n isSubpathExports,\n resolvePackageJsonEntryExports,\n} from './packages/exports'\nimport { isolatePackage } from './packages/isolation'\nimport {\n collectIncompatibleLicenses,\n collectLicenseWarnings,\n createAstNode,\n createBinaryOperationNode,\n createLicenseNode,\n parseSpdxExp,\n resolvePackageLicenses,\n visitLicenses,\n} from './packages/licenses'\nimport {\n createPackageJson,\n fetchPackageManifest,\n fetchPackagePackument,\n} from './packages/manifest'\nimport {\n normalizePackageJson,\n resolveEscapedScope,\n resolveOriginalPackageName,\n unescapeScope,\n} from './packages/normalize'\nimport {\n extractPackage,\n findPackageExtensions,\n getReleaseTag,\n packPackage,\n readPackageJson,\n readPackageJsonSync,\n resolveGitHubTgzUrl,\n resolvePackageName,\n resolveRegistryPackageName,\n} from './packages/operations'\nimport {\n resolvePackageJsonDirname,\n resolvePackageJsonPath,\n} from './packages/paths'\nimport {\n fetchPackageProvenance,\n getProvenanceDetails,\n} from './packages/provenance'\nimport {\n getRepoUrlDetails,\n gitHubTagRefUrl,\n gitHubTgzUrl,\n isGitHubTgzSpec,\n isGitHubUrlSpec,\n} from './packages/specs'\nimport {\n isBlessedPackageName,\n isRegistryFetcherType,\n isValidPackageName,\n} from './packages/validation'\n\n// Type for package.json exports field.\ntype PackageExports = {\n [path: string]: unknown\n}\n\n// Re-export the EditablePackageJson instance type for convenient access\nexport type EditablePackageJson =\n import('./packages/editable').EditablePackageJsonInstance\n\n/**\n * Extended PackageJson type based on NPMCliPackageJson.Content with Socket-specific additions.\n * @extends NPMCliPackageJson.Content (from @npmcli/package-json)\n * @property socket - Optional Socket.dev specific configuration\n */\nexport type PackageJson = {\n // Core npm fields\n [key: string]: unknown\n name?: string | undefined\n version?: string | undefined\n description?: string | undefined\n main?: string | undefined\n module?: string | undefined\n types?: string | undefined\n typings?: string | undefined\n bin?: string | Record<string, string> | undefined\n\n // Author and contributors\n author?: string | { name?: string; email?: string; url?: string } | undefined\n contributors?:\n | Array<string | { name?: string; email?: string; url?: string }>\n | undefined\n maintainers?:\n | Array<string | { name?: string; email?: string; url?: string }>\n | undefined\n\n // Repository and URLs\n repository?:\n | string\n | { type?: string; url?: string; directory?: string }\n | undefined\n homepage?: string | undefined\n bugs?: string | { url?: string; email?: string } | undefined\n\n // License\n license?: string | undefined\n licenses?: Array<{ type?: string; url?: string }> | undefined\n\n // Scripts\n scripts?: Record<string, string> | undefined\n\n // Dependencies\n dependencies?: Record<string, string> | undefined\n devDependencies?: Record<string, string> | undefined\n peerDependencies?: Record<string, string> | undefined\n optionalDependencies?: Record<string, string> | undefined\n bundledDependencies?: string[] | undefined\n bundleDependencies?: string[] | undefined\n\n // Package managers specific\n overrides?: Record<string, string> | undefined\n resolutions?: Record<string, string> | undefined\n pnpm?: Record<string, unknown> | undefined\n\n // Module system\n exports?: PackageExports | string | string[] | undefined\n imports?: Record<string, unknown> | undefined\n type?: 'module' | 'commonjs' | undefined\n\n // Publishing\n private?: boolean | undefined\n publishConfig?: Record<string, unknown> | undefined\n files?: string[] | undefined\n\n // Engines and OS\n engines?: Record<string, string> | undefined\n os?: string[] | undefined\n cpu?: string[] | undefined\n\n // Package manager\n packageManager?: string | undefined\n\n // Workspaces\n workspaces?: string[] | { packages?: string[] } | undefined\n\n // Socket.dev specific\n socket?:\n | {\n categories?: CategoryString | CategoryString[]\n interop?: string | string[]\n [key: string]: unknown\n }\n | undefined\n}\n\nexport type SaveOptions = {\n ignoreWhitespace?: boolean | undefined\n sort?: boolean | undefined\n}\n\nexport type EditablePackageJsonOptions = {\n normalize?: boolean | undefined\n path?: string | undefined\n preserve?: string[] | readonly string[] | undefined\n create?: boolean | undefined\n data?: PackageJson | undefined\n}\n\nexport type ExtractOptions = {\n dest?: string | undefined\n tmpPrefix?: string | undefined\n signal?: AbortSignal | undefined\n packumentCache?: Map<string, unknown> | undefined\n preferOffline?: boolean | undefined\n}\n\nexport type NormalizeOptions = {\n preserve?: string[] | readonly string[] | undefined\n}\n\nexport type ReadPackageJsonOptions = NormalizeOptions & {\n editable?: boolean | undefined\n normalize?: boolean | undefined\n throws?: boolean | undefined\n}\n\nexport type ProvenanceOptions = {\n signal?: AbortSignal | undefined\n timeout?: number | undefined\n}\n\nexport type LicenseNode = {\n license: string\n exception?: string | undefined\n inFile?: string | undefined\n plus?: boolean | undefined\n}\n\nexport type PacoteOptions = {\n signal?: AbortSignal | undefined\n packumentCache?: Map<string, unknown> | undefined\n preferOffline?: boolean | undefined\n fullMetadata?: boolean | undefined\n}\n\nexport type {\n IsolatePackageOptions,\n IsolatePackageResult,\n} from './packages/isolation'\n\nexport type {\n InternalAstNode,\n InternalBinaryOperationNode,\n InternalLicenseNode,\n LicenseVisitor,\n SpdxAstNode,\n SpdxBinaryOperationNode,\n SpdxLicenseNode,\n} from './packages/licenses'\n\nexport {\n collectIncompatibleLicenses,\n collectLicenseWarnings,\n createAstNode,\n createBinaryOperationNode,\n createLicenseNode,\n createPackageJson,\n extractPackage,\n fetchPackageManifest,\n fetchPackagePackument,\n fetchPackageProvenance,\n findPackageExtensions,\n findTypesForSubpath,\n getEditablePackageJsonClass,\n getExportFilePaths,\n getProvenanceDetails,\n getReleaseTag,\n getRepoUrlDetails,\n getSubpaths,\n gitHubTagRefUrl,\n gitHubTgzUrl,\n isBlessedPackageName,\n isConditionalExports,\n isGitHubTgzSpec,\n isGitHubUrlSpec,\n isolatePackage,\n isRegistryFetcherType,\n isSubpathExports,\n isValidPackageName,\n normalizePackageJson,\n packPackage,\n parseSpdxExp,\n pkgJsonToEditable,\n readPackageJson,\n readPackageJsonSync,\n resolveEscapedScope,\n resolveGitHubTgzUrl,\n resolveOriginalPackageName,\n resolvePackageName,\n resolvePackageJsonDirname,\n resolvePackageJsonPath,\n resolvePackageJsonEntryExports,\n resolvePackageLicenses,\n resolveRegistryPackageName,\n toEditablePackageJson,\n toEditablePackageJsonSync,\n unescapeScope,\n visitLicenses,\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,sBAKO;AACP,qBAOO;AACP,uBAA+B;AAC/B,sBASO;AACP,sBAIO;AACP,uBAKO;AACP,wBAUO;AACP,mBAGO;AACP,wBAGO;AACP,mBAMO;AACP,wBAIO;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/path.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/path.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Path manipulation utilities with cross-platform support.\n * Provides path normalization, validation, and file extension handling.\n */\n\nimport { WIN32 } from '#constants/platform'\n\nimport { search } from './strings'\n\n// Character code constants.\n// '\\'\nconst CHAR_BACKWARD_SLASH = 92\n// ':'\nconst CHAR_COLON = 58\n// '/'\nconst CHAR_FORWARD_SLASH = 47\n// 'a'\nconst CHAR_LOWERCASE_A = 97\n// 'z'\nconst CHAR_LOWERCASE_Z = 122\n// 'A'\nconst CHAR_UPPERCASE_A = 65\n// 'Z'\nconst CHAR_UPPERCASE_Z = 90\n\n// Regular expressions.\nconst slashRegExp = /[/\\\\]/\nconst nodeModulesPathRegExp = /(?:^|[/\\\\])node_modules(?:[/\\\\]|$)/\n\n/**\n * Check if a character code represents a path separator.\n *\n * Determines whether the given character code is either a forward slash (/) or\n * backslash (\\), which are used as path separators across different platforms.\n *\n * @param {number} code - The character code to check\n * @returns {boolean} `true` if the code represents a path separator, `false` otherwise\n *\n * @example\n * ```typescript\n * isPathSeparator(47) // true - forward slash '/'\n * isPathSeparator(92) // true - backslash '\\'\n * isPathSeparator(65) // false - letter 'A'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction isPathSeparator(code: number): boolean {\n return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH\n}\n\n/**\n * Check if a character code represents a Windows device root letter.\n *\n * Tests whether the given character code falls within the valid range for\n * Windows drive letters (A-Z or a-z). These letters are used at the start\n * of Windows absolute paths (e.g., `C:\\`, `D:\\`).\n *\n * @param {number} code - The character code to check\n * @returns {boolean} `true` if the code is a valid drive letter, `false` otherwise\n *\n * @example\n * ```typescript\n * isWindowsDeviceRoot(67) // true - letter 'C'\n * isWindowsDeviceRoot(99) // true - letter 'c'\n * isWindowsDeviceRoot(58) // false - colon ':'\n * isWindowsDeviceRoot(47) // false - forward slash '/'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction isWindowsDeviceRoot(code: number): boolean {\n return (\n (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||\n (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z)\n )\n}\n\nlet _buffer: typeof import('node:buffer') | undefined\n/**\n * Lazily load the buffer module.\n *\n * Performs on-demand loading of Node.js buffer module to avoid initialization\n * overhead and potential Webpack bundling errors.\n *\n * @private\n * @returns {typeof import('node:buffer')} The buffer module\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getBuffer() {\n if (_buffer === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _buffer = /*@__PURE__*/ require('node:buffer')\n }\n return _buffer as typeof import('node:buffer')\n}\n\nlet _url: typeof import('node:url') | undefined\n/**\n * Lazily load the url module.\n *\n * Performs on-demand loading of Node.js url module to avoid initialization\n * overhead and potential Webpack bundling errors.\n *\n * @private\n * @returns {typeof import('node:url')} The url module\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getUrl() {\n if (_url === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _url = /*@__PURE__*/ require('node:url')\n }\n return _url as typeof import('node:url')\n}\n\n/**\n * Check if a path contains node_modules directory.\n *\n * Detects whether a given path includes a `node_modules` directory segment.\n * This is useful for identifying npm package dependencies and filtering\n * dependency-related paths.\n *\n * The check matches `node_modules` appearing as a complete path segment,\n * ensuring it is either at the start, end, or surrounded by path separators.\n *\n * @param {string | Buffer | URL} pathLike - The path to check\n * @returns {boolean} `true` if the path contains `node_modules`, `false` otherwise\n *\n * @example\n * ```typescript\n * isNodeModules('/project/node_modules/package') // true\n * isNodeModules('node_modules/package/index.js') // true\n * isNodeModules('/src/my_node_modules_backup') // false\n * isNodeModules('/project/src/index.js') // false\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isNodeModules(pathLike: string | Buffer | URL): boolean {\n const filepath = pathLikeToString(pathLike)\n return nodeModulesPathRegExp.test(filepath)\n}\n\n/**\n * Check if a path is absolute.\n *\n * An absolute path is one that specifies a location from the root of the file system.\n * This function handles both POSIX and Windows path formats.\n *\n * POSIX absolute paths:\n * - Start with forward slash '/'\n * - Examples: '/home/user', '/usr/bin/node'\n *\n * Windows absolute paths (3 types):\n * 1. Drive-letter paths: Start with drive letter + colon + separator\n * - Format: [A-Za-z]:[\\\\/]\n * - Examples: 'C:\\Windows', 'D:/data', 'c:\\Program Files'\n * - Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names\n *\n * 2. UNC paths: Start with double backslash (handled by backslash check)\n * - Format: \\\\server\\share\n * - Examples: '\\\\server\\share\\file', '\\\\?\\C:\\path'\n * - Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#unc-names\n *\n * 3. Device paths: Start with backslash\n * - Examples: '\\Windows', '\\\\.\\device'\n * - Note: Single backslash paths are relative to current drive\n *\n * @param {string | Buffer | URL} pathLike - The path to check\n * @returns {boolean} `true` if the path is absolute, `false` otherwise\n *\n * @example\n * ```typescript\n * // POSIX paths\n * isAbsolute('/home/user') // true\n * isAbsolute('/usr/bin/node') // true\n *\n * // Windows paths\n * isAbsolute('C:\\\\Windows') // true\n * isAbsolute('D:/data') // true\n * isAbsolute('\\\\\\\\server\\\\share') // true\n *\n * // Relative paths\n * isAbsolute('../relative') // false\n * isAbsolute('relative/path') // false\n * isAbsolute('.') // false\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isAbsolute(pathLike: string | Buffer | URL): boolean {\n const filepath = pathLikeToString(pathLike)\n const { length } = filepath\n\n // Empty paths are not absolute.\n if (length === 0) {\n return false\n }\n\n const code = filepath.charCodeAt(0)\n\n // POSIX: absolute paths start with forward slash '/'.\n // This is the simplest case and works for all UNIX-like systems.\n if (code === CHAR_FORWARD_SLASH) {\n return true\n }\n\n // Windows: absolute paths can start with backslash '\\'.\n // This includes UNC paths (\\\\server\\share) and device paths (\\\\.\\ or \\\\?\\).\n // Single backslash is technically relative to current drive, but treated as absolute.\n if (code === CHAR_BACKWARD_SLASH) {\n return true\n }\n\n // Windows: drive-letter absolute paths (e.g., C:\\, D:\\).\n // Format: [A-Za-z]:[\\\\/]\n // Requires at least 3 characters: drive letter + colon + separator.\n // Only treat as absolute on Windows platforms.\n if (WIN32 && length > 2) {\n // Check if first character is a letter (A-Z or a-z).\n // Check if second character is colon ':'.\n // Check if third character is a path separator (forward or backslash).\n // This matches patterns like 'C:\\', 'D:/', 'c:\\Users', etc.\n if (\n isWindowsDeviceRoot(code) &&\n filepath.charCodeAt(1) === CHAR_COLON &&\n isPathSeparator(filepath.charCodeAt(2))\n ) {\n return true\n }\n }\n\n // Not an absolute path.\n return false\n}\n\n/**\n * Check if a value is a valid file path (absolute or relative).\n *\n * Determines whether a given value represents a valid file system path.\n * This function distinguishes between file paths and other string formats\n * like package names, URLs, or bare module specifiers.\n *\n * Valid paths include:\n * - Absolute paths (e.g., `/usr/bin`, `C:\\Windows`)\n * - Relative paths with separators (e.g., `./src`, `../lib`)\n * - Special relative paths (`.`, `..`)\n * - Paths starting with `@` that have subpaths (e.g., `@scope/name/file`)\n *\n * Not considered paths:\n * - URLs with protocols (e.g., `http://`, `file://`, `git:`)\n * - Bare package names (e.g., `lodash`, `react`)\n * - Scoped package names without subpaths (e.g., `@scope/name`)\n *\n * @param {string | Buffer | URL} pathLike - The value to check\n * @returns {boolean} `true` if the value is a valid file path, `false` otherwise\n *\n * @example\n * ```typescript\n * // Valid paths\n * isPath('/absolute/path') // true\n * isPath('./relative/path') // true\n * isPath('../parent/dir') // true\n * isPath('.') // true\n * isPath('..') // true\n * isPath('@scope/name/subpath') // true\n * isPath('C:\\\\Windows') // true (Windows)\n *\n * // Not paths\n * isPath('lodash') // false - bare package name\n * isPath('@scope/package') // false - scoped package name\n * isPath('http://example.com') // false - URL\n * isPath('file://path') // false - file URL\n * isPath('') // false - empty string\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isPath(pathLike: string | Buffer | URL): boolean {\n const filepath = pathLikeToString(pathLike)\n if (typeof filepath !== 'string' || filepath.length === 0) {\n return false\n }\n\n // Exclude URLs with protocols (file:, http:, https:, git:, etc.).\n // These should be handled by package spec parsers, not treated as file paths.\n // Require at least 2 characters before colon to exclude Windows drive letters (C:, D:).\n if (/^[a-z][a-z0-9+.-]+:/i.test(filepath)) {\n return false\n }\n\n // Special relative paths.\n if (filepath === '.' || filepath === '..') {\n return true\n }\n\n // Absolute paths are always valid paths.\n if (isAbsolute(filepath)) {\n return true\n }\n\n // Contains path separators, so it's a path.\n if (filepath.includes('/') || filepath.includes('\\\\')) {\n // Distinguish scoped package names from paths starting with '@'.\n // Scoped packages: @scope/name (exactly 2 parts, no backslashes).\n // Paths: @scope/name/subpath (3+ parts) or @scope\\name (Windows backslash).\n // Special case: '@/' is a valid path (already handled by separator check).\n if (filepath.startsWith('@') && !filepath.startsWith('@/')) {\n const parts = filepath.split('/')\n // If exactly @scope/name with no Windows separators, it's a package name.\n if (parts.length <= 2 && !parts[1]?.includes('\\\\')) {\n return false\n }\n }\n return true\n }\n\n // Bare names without separators are package names, not paths.\n return false\n}\n\n/**\n * Check if a path is relative.\n *\n * Determines whether a given path is relative (i.e., not absolute). A path\n * is considered relative if it does not specify a location from the root of\n * the file system.\n *\n * Relative paths include:\n * - Paths starting with `.` or `..` (e.g., `./src`, `../lib`)\n * - Paths without leading separators (e.g., `src/file.js`)\n * - Empty strings (treated as relative)\n *\n * @param {string | Buffer | URL} pathLike - The path to check\n * @returns {boolean} `true` if the path is relative, `false` if absolute\n *\n * @example\n * ```typescript\n * // Relative paths\n * isRelative('./src/index.js') // true\n * isRelative('../lib/util.js') // true\n * isRelative('src/file.js') // true\n * isRelative('') // true\n *\n * // Absolute paths\n * isRelative('/home/user') // false\n * isRelative('C:\\\\Windows') // false (Windows)\n * isRelative('\\\\\\\\server\\\\share') // false (Windows UNC)\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isRelative(pathLike: string | Buffer | URL): boolean {\n const filepath = pathLikeToString(pathLike)\n if (typeof filepath !== 'string') {\n return false\n }\n // Empty string is considered relative.\n if (filepath.length === 0) {\n return true\n }\n // A path is relative if it's not absolute.\n return !isAbsolute(filepath)\n}\n\n/**\n * Normalize a path by converting backslashes to forward slashes and collapsing segments.\n *\n * This function performs several normalization operations:\n * - Converts all backslashes (`\\`) to forward slashes (`/`)\n * - Collapses repeated slashes into single slashes\n * - Resolves `.` (current directory) segments\n * - Resolves `..` (parent directory) segments\n * - Preserves UNC path prefixes (`//server/share`)\n * - Preserves Windows namespace prefixes (`//./`, `//?/`)\n * - Returns `.` for empty or collapsed paths\n *\n * Special handling:\n * - UNC paths: Maintains double leading slashes for `//server/share` format\n * - Windows namespaces: Preserves `//./` and `//?/` prefixes\n * - Leading `..` segments: Preserved in relative paths without prefix\n * - Trailing components: Properly handled when resolving `..`\n *\n * @param {string | Buffer | URL} pathLike - The path to normalize\n * @returns {string} The normalized path with forward slashes and collapsed segments\n *\n * @example\n * ```typescript\n * // Basic normalization\n * normalizePath('foo/bar//baz') // 'foo/bar/baz'\n * normalizePath('foo/./bar') // 'foo/bar'\n * normalizePath('foo/bar/../baz') // 'foo/baz'\n *\n * // Windows paths\n * normalizePath('C:\\\\Users\\\\username\\\\file.txt') // 'C:/Users/username/file.txt'\n * normalizePath('foo\\\\bar\\\\baz') // 'foo/bar/baz'\n *\n * // UNC paths\n * normalizePath('\\\\\\\\server\\\\share\\\\file') // '//server/share/file'\n *\n * // Edge cases\n * normalizePath('') // '.'\n * normalizePath('.') // '.'\n * normalizePath('..') // '..'\n * normalizePath('///foo///bar///') // '/foo/bar'\n * normalizePath('foo/../..') // '..'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizePath(pathLike: string | Buffer | URL): string {\n const filepath = pathLikeToString(pathLike)\n const { length } = filepath\n if (length === 0) {\n return '.'\n }\n if (length < 2) {\n return length === 1 && filepath.charCodeAt(0) === 92 /*'\\\\'*/\n ? '/'\n : filepath\n }\n\n let code = 0\n let start = 0\n\n // Ensure win32 namespaces have two leading slashes so they are handled properly\n // by path.win32.parse() after being normalized.\n // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#namespaces\n // UNC paths, paths starting with double slashes, e.g. \"\\\\\\\\wsl.localhost\\\\Ubuntu\\home\\\\\",\n // are okay to convert to forward slashes.\n // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions\n let prefix = ''\n if (length > 4 && filepath.charCodeAt(3) === 92 /*'\\\\'*/) {\n const code2 = filepath.charCodeAt(2)\n // Look for \\\\?\\ or \\\\.\\\n if (\n (code2 === 63 /*'?'*/ || code2 === 46) /*'.'*/ &&\n filepath.charCodeAt(0) === 92 /*'\\\\'*/ &&\n filepath.charCodeAt(1) === 92 /*'\\\\'*/\n ) {\n start = 2\n prefix = '//'\n }\n }\n if (start === 0) {\n // Check for UNC paths first (\\\\server\\share or //server/share)\n // UNC paths must start with exactly two slashes, not more\n if (\n length > 2 &&\n ((filepath.charCodeAt(0) === 92 /*'\\\\'*/ &&\n filepath.charCodeAt(1) === 92 /*'\\\\'*/ &&\n filepath.charCodeAt(2) !== 92) /*'\\\\'*/ ||\n (filepath.charCodeAt(0) === 47 /*'/'*/ &&\n filepath.charCodeAt(1) === 47 /*'/'*/ &&\n filepath.charCodeAt(2) !== 47)) /*'/'*/\n ) {\n // Check if this is a valid UNC path: must have server/share format\n // Find the first segment (server name) and second segment (share name)\n let firstSegmentEnd = -1\n let hasSecondSegment = false\n\n // Skip leading slashes after the initial double slash\n let i = 2\n while (\n i < length &&\n (filepath.charCodeAt(i) === 47 /*'/'*/ ||\n filepath.charCodeAt(i) === 92) /*'\\\\'*/\n ) {\n i++\n }\n\n // Find the end of first segment (server name)\n while (i < length) {\n const char = filepath.charCodeAt(i)\n if (char === 47 /*'/'*/ || char === 92 /*'\\\\'*/) {\n firstSegmentEnd = i\n break\n }\n i++\n }\n\n if (firstSegmentEnd > 2) {\n // Skip slashes after server name\n i = firstSegmentEnd\n while (\n i < length &&\n (filepath.charCodeAt(i) === 47 /*'/'*/ ||\n filepath.charCodeAt(i) === 92) /*'\\\\'*/\n ) {\n i++\n }\n // Check if there's a share name (second segment)\n if (i < length) {\n hasSecondSegment = true\n }\n }\n\n if (firstSegmentEnd > 2 && hasSecondSegment) {\n // Valid UNC path - preserve double leading slashes\n start = 2\n prefix = '//'\n } else {\n // Just repeated slashes, treat as regular path\n code = filepath.charCodeAt(start)\n while (code === 47 /*'/'*/ || code === 92 /*'\\\\'*/) {\n start += 1\n code = filepath.charCodeAt(start)\n }\n if (start) {\n prefix = '/'\n }\n }\n } else {\n // Trim leading slashes for regular paths\n code = filepath.charCodeAt(start)\n while (code === 47 /*'/'*/ || code === 92 /*'\\\\'*/) {\n start += 1\n code = filepath.charCodeAt(start)\n }\n if (start) {\n prefix = '/'\n }\n }\n }\n let nextIndex = search(filepath, slashRegExp, { fromIndex: start })\n if (nextIndex === -1) {\n const segment = filepath.slice(start)\n if (segment === '.' || segment.length === 0) {\n return prefix || '.'\n }\n if (segment === '..') {\n return prefix ? prefix.slice(0, -1) || '/' : '..'\n }\n return prefix + segment\n }\n // Process segments and handle '.', '..', and empty segments.\n let collapsed = ''\n let segmentCount = 0\n let leadingDotDots = 0\n while (nextIndex !== -1) {\n const segment = filepath.slice(start, nextIndex)\n if (segment.length > 0 && segment !== '.') {\n if (segment === '..') {\n // Handle '..' by removing the last segment if possible.\n if (segmentCount > 0) {\n // Find the last separator and remove the last segment.\n const lastSeparatorIndex = collapsed.lastIndexOf('/')\n if (lastSeparatorIndex === -1) {\n // Only one segment, remove it entirely.\n collapsed = ''\n segmentCount = 0\n // Check if this was a leading '..', restore it.\n if (leadingDotDots > 0 && !prefix) {\n collapsed = '..'\n leadingDotDots = 1\n }\n } else {\n const lastSegmentStart = lastSeparatorIndex + 1\n const lastSegmentValue = collapsed.slice(lastSegmentStart)\n // Don't collapse leading '..' segments.\n if (lastSegmentValue === '..') {\n // Preserve the '..' and add another one.\n collapsed = `${collapsed}/${segment}`\n leadingDotDots += 1\n } else {\n // Normal collapse: remove the last segment.\n collapsed = collapsed.slice(0, lastSeparatorIndex)\n segmentCount -= 1\n }\n }\n } else if (!prefix) {\n // Preserve '..' for relative paths.\n collapsed = collapsed + (collapsed.length === 0 ? '' : '/') + segment\n leadingDotDots += 1\n }\n } else {\n collapsed = collapsed + (collapsed.length === 0 ? '' : '/') + segment\n segmentCount += 1\n }\n }\n start = nextIndex + 1\n code = filepath.charCodeAt(start)\n while (code === 47 /*'/'*/ || code === 92 /*'\\\\'*/) {\n start += 1\n code = filepath.charCodeAt(start)\n }\n nextIndex = search(filepath, slashRegExp, { fromIndex: start })\n }\n const lastSegment = filepath.slice(start)\n if (lastSegment.length > 0 && lastSegment !== '.') {\n if (lastSegment === '..') {\n if (segmentCount > 0) {\n const lastSeparatorIndex = collapsed.lastIndexOf('/')\n if (lastSeparatorIndex === -1) {\n collapsed = ''\n segmentCount = 0\n // Check if this was a leading '..', restore it.\n if (leadingDotDots > 0 && !prefix) {\n collapsed = '..'\n leadingDotDots = 1\n }\n } else {\n const lastSegmentStart = lastSeparatorIndex + 1\n const lastSegmentValue = collapsed.slice(lastSegmentStart)\n // Don't collapse leading '..' segments.\n if (lastSegmentValue === '..') {\n // Preserve the '..' and add another one.\n collapsed = `${collapsed}/${lastSegment}`\n leadingDotDots += 1\n } else {\n // Normal collapse: remove the last segment.\n collapsed = collapsed.slice(0, lastSeparatorIndex)\n segmentCount -= 1\n }\n }\n } else if (!prefix) {\n collapsed =\n collapsed + (collapsed.length === 0 ? '' : '/') + lastSegment\n leadingDotDots += 1\n }\n } else {\n collapsed = collapsed + (collapsed.length === 0 ? '' : '/') + lastSegment\n segmentCount += 1\n }\n }\n\n if (collapsed.length === 0) {\n return prefix || '.'\n }\n return prefix + collapsed\n}\n\n/**\n * Convert a path-like value to a string.\n *\n * Converts various path-like types (string, Buffer, URL) into a normalized\n * string representation. This function handles different input formats and\n * provides consistent string output for path operations.\n *\n * Supported input types:\n * - `string`: Returned as-is\n * - `Buffer`: Decoded as UTF-8 string\n * - `URL`: Converted using `fileURLToPath()`, with fallback for malformed URLs\n * - `null` / `undefined`: Returns empty string\n *\n * URL handling:\n * - Valid file URLs are converted via `url.fileURLToPath()`\n * - Malformed URLs fall back to pathname extraction with decoding\n * - Windows drive letters in URLs are handled specially\n * - Percent-encoded characters are decoded (e.g., `%20` becomes space)\n *\n * @param {string | Buffer | URL | null | undefined} pathLike - The path-like value to convert\n * @returns {string} The string representation of the path, or empty string for null/undefined\n *\n * @example\n * ```typescript\n * // String input\n * pathLikeToString('/home/user') // '/home/user'\n *\n * // Buffer input\n * pathLikeToString(Buffer.from('/tmp/file')) // '/tmp/file'\n *\n * // URL input\n * pathLikeToString(new URL('file:///home/user')) // '/home/user'\n * pathLikeToString(new URL('file:///C:/Windows')) // 'C:/Windows' (Windows)\n *\n * // Null/undefined input\n * pathLikeToString(null) // ''\n * pathLikeToString(undefined) // ''\n *\n * // Percent-encoded URLs\n * pathLikeToString(new URL('file:///path%20with%20spaces')) // '/path with spaces'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function pathLikeToString(\n pathLike: string | Buffer | URL | null | undefined,\n): string {\n if (pathLike === null || pathLike === undefined) {\n return ''\n }\n if (typeof pathLike === 'string') {\n return pathLike\n }\n const { Buffer } = getBuffer()\n if (Buffer.isBuffer(pathLike)) {\n return pathLike.toString('utf8')\n }\n const url = getUrl()\n if (pathLike instanceof URL) {\n try {\n return url.fileURLToPath(pathLike)\n } catch {\n // On Windows, file URLs like `file:///C:/path` include drive letters.\n // If a file URL is missing its drive letter (malformed), fileURLToPath() throws an error.\n // This fallback extracts the pathname directly from the URL object.\n //\n // Example flows:\n // - Unix: file:///home/user \u2192 pathname '/home/user' \u2192 keep as-is\n // - Windows valid: file:///C:/path \u2192 handled by fileURLToPath()\n // - Windows invalid: file:///path \u2192 pathname '/path' \u2192 strips to 'path'\n const pathname = pathLike.pathname\n\n // Decode percent-encoded characters (e.g., %20 \u2192 space).\n // The pathname property keeps URL encoding, but file paths need decoded characters.\n // This is not platform-specific; all URLs use percent-encoding regardless of OS.\n const decodedPathname = decodeURIComponent(pathname)\n\n // URL pathnames always start with `/`.\n // On Windows, strip the leading slash only for malformed URLs that lack drive letters\n // (e.g., `/path` should be `path`, but `/C:/path` should be `C:/path`).\n // On Unix, keep the leading slash for absolute paths (e.g., `/home/user`).\n if (WIN32 && decodedPathname.startsWith('/')) {\n // Check for drive letter pattern following Node.js source: /[a-zA-Z]:/\n // Character at index 1 should be a letter, character at index 2 should be ':'\n // Convert to lowercase\n const letter = decodedPathname.charCodeAt(1) | 0x20\n const hasValidDriveLetter =\n decodedPathname.length >= 3 &&\n letter >= 97 &&\n // 'a' to 'z'\n letter <= 122 &&\n decodedPathname.charAt(2) === ':'\n\n if (!hasValidDriveLetter) {\n // On Windows, preserve Unix-style absolute paths that don't start with a drive letter.\n // Only strip the leading slash for truly malformed Windows paths.\n // Since fileURLToPath() failed, this is likely a valid Unix-style absolute path.\n return decodedPathname\n }\n }\n return decodedPathname\n }\n }\n return String(pathLike)\n}\n\n/**\n * Split a path into an array of segments.\n *\n * Divides a path into individual components by splitting on path separators\n * (both forward slashes and backslashes). This is useful for path traversal,\n * analysis, and manipulation.\n *\n * The function handles:\n * - Forward slashes (`/`) on all platforms\n * - Backslashes (`\\`) on Windows\n * - Mixed separators in a single path\n * - Empty paths (returns empty array)\n *\n * Note: The resulting array may contain empty strings if the path has leading,\n * trailing, or consecutive separators (e.g., `/foo//bar/` becomes `['', 'foo', '', 'bar', '']`).\n *\n * @param {string | Buffer | URL} pathLike - The path to split\n * @returns {string[]} Array of path segments, or empty array for empty paths\n *\n * @example\n * ```typescript\n * // POSIX paths\n * splitPath('/home/user/file.txt') // ['', 'home', 'user', 'file.txt']\n * splitPath('src/lib/util.js') // ['src', 'lib', 'util.js']\n *\n * // Windows paths\n * splitPath('C:\\\\Users\\\\John') // ['C:', 'Users', 'John']\n * splitPath('folder\\\\file.txt') // ['folder', 'file.txt']\n *\n * // Mixed separators\n * splitPath('path/to\\\\file') // ['path', 'to', 'file']\n *\n * // Edge cases\n * splitPath('') // []\n * splitPath('/') // ['', '']\n * splitPath('/foo//bar/') // ['', 'foo', '', 'bar', '']\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function splitPath(pathLike: string | Buffer | URL): string[] {\n const filepath = pathLikeToString(pathLike)\n if (filepath === '') {\n return []\n }\n return filepath.split(slashRegExp)\n}\n\n/**\n * Remove leading ./ or ../ from a path.\n *\n * Strips the `./` or `.\\` prefix from relative paths. This is useful for\n * normalizing paths when the current directory reference is implicit or\n * unwanted.\n *\n * Note: This function only removes a single leading `./` or `.\\`. It does\n * not remove `../` prefixes or process the rest of the path.\n *\n * @param {string | Buffer | URL} pathLike - The path to process\n * @returns {string} The path without leading `./` or `.\\`, or unchanged if no such prefix\n *\n * @example\n * ```typescript\n * // Remove ./ prefix\n * trimLeadingDotSlash('./src/index.js') // 'src/index.js'\n * trimLeadingDotSlash('.\\\\src\\\\file.txt') // 'src\\\\file.txt'\n *\n * // Preserve ../ prefix\n * trimLeadingDotSlash('../lib/util.js') // '../lib/util.js'\n *\n * // No change for other paths\n * trimLeadingDotSlash('/absolute/path') // '/absolute/path'\n * trimLeadingDotSlash('relative/path') // 'relative/path'\n * trimLeadingDotSlash('.') // '.'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function trimLeadingDotSlash(pathLike: string | Buffer | URL): string {\n const filepath = pathLikeToString(pathLike)\n // Only trim ./ not ../\n if (filepath.startsWith('./') || filepath.startsWith('.\\\\')) {\n return filepath.slice(2)\n }\n return filepath\n}\n\n/**\n * Resolve an absolute path from path segments.\n *\n * This function mimics Node.js `path.resolve()` behavior by building an\n * absolute path from the given segments. It processes segments from right\n * to left, stopping when an absolute path is encountered. If no absolute\n * path is found, it prepends the current working directory.\n *\n * Algorithm:\n * 1. Process segments from right to left\n * 2. Stop when an absolute path is found\n * 3. Prepend current working directory if no absolute path found\n * 4. Normalize the final path\n *\n * Key behaviors:\n * - Later segments override earlier ones (e.g., `resolve('/foo', '/bar')` returns `/bar`)\n * - Empty or non-string segments are skipped\n * - Result is always an absolute path\n * - Path separators are normalized to forward slashes\n *\n * @param {...string} segments - Path segments to resolve\n * @returns {string} The resolved absolute path\n *\n * @example\n * ```typescript\n * // Basic resolution\n * resolve('foo', 'bar', 'baz') // '/cwd/foo/bar/baz' (assuming cwd is '/cwd')\n * resolve('/foo', 'bar', 'baz') // '/foo/bar/baz'\n * resolve('foo', '/bar', 'baz') // '/bar/baz'\n *\n * // Windows paths\n * resolve('C:\\\\foo', 'bar') // 'C:/foo/bar'\n *\n * // Empty segments\n * resolve('foo', '', 'bar') // '/cwd/foo/bar'\n * resolve() // '/cwd' (current directory)\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction resolve(...segments: string[]): string {\n let resolvedPath = ''\n let resolvedAbsolute = false\n\n // Process segments from right to left until we find an absolute path.\n // This allows later segments to override earlier ones.\n // Example: resolve('/foo', '/bar') returns '/bar', not '/foo/bar'.\n for (let i = segments.length - 1; i >= 0 && !resolvedAbsolute; i -= 1) {\n const segment = segments[i]\n\n // Skip empty or non-string segments.\n if (typeof segment !== 'string' || segment.length === 0) {\n continue\n }\n\n // Prepend the segment to the resolved path.\n // Use forward slashes as separators (normalized later).\n resolvedPath =\n segment + (resolvedPath.length === 0 ? '' : `/${resolvedPath}`)\n\n // Check if this segment is absolute.\n // Absolute paths stop the resolution process.\n resolvedAbsolute = isAbsolute(segment)\n }\n\n // If no absolute path was found in segments, prepend current working directory.\n // This ensures the final path is always absolute.\n if (!resolvedAbsolute) {\n const cwd = /*@__PURE__*/ require('node:process').cwd()\n resolvedPath = cwd + (resolvedPath.length === 0 ? '' : `/${resolvedPath}`)\n }\n\n // Normalize the resolved path (collapse '..' and '.', convert separators).\n return normalizePath(resolvedPath)\n}\n\n/**\n * Calculate the relative path from one path to another.\n *\n * This function computes how to get from the `from` path to the `to` path\n * using relative path notation. Both paths are first resolved to absolute\n * paths, then compared to find the common base path, and finally a relative\n * path is constructed using `../` for parent directory traversal.\n *\n * Algorithm:\n * 1. Resolve both paths to absolute\n * 2. Find the longest common path prefix (up to a separator)\n * 3. For each remaining directory in `from`, add `../` to go up\n * 4. Append the remaining path from `to`\n *\n * Windows-specific behavior:\n * - File system paths are case-insensitive on Windows (NTFS, FAT32)\n * - `C:\\Foo` and `c:\\foo` are considered the same path\n * - Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file\n * - Case is preserved but not significant for comparison\n *\n * @param {string} from - The source path (starting point)\n * @param {string} to - The destination path (target)\n * @returns {string} The relative path from `from` to `to`, or empty string if paths are identical\n *\n * @example\n * ```typescript\n * // Basic relative paths\n * relative('/foo/bar', '/foo/baz') // '../baz'\n * relative('/foo/bar/baz', '/foo') // '../..'\n * relative('/foo', '/foo/bar') // 'bar'\n *\n * // Same paths\n * relative('/foo/bar', '/foo/bar') // ''\n *\n * // Windows case-insensitive\n * relative('C:\\\\Foo\\\\bar', 'C:\\\\foo\\\\baz') // '../baz' (Windows)\n *\n * // Root paths\n * relative('/', '/foo/bar') // 'foo/bar'\n * relative('/foo/bar', '/') // '../..'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction relative(from: string, to: string): string {\n // Quick return if paths are already identical.\n if (from === to) {\n return ''\n }\n\n // Resolve both paths to absolute.\n // This handles relative paths, '.', '..', and ensures consistent format.\n const actualFrom = resolve(from)\n const actualTo = resolve(to)\n\n // Check again after resolution (paths might have been equivalent).\n if (actualFrom === actualTo) {\n return ''\n }\n\n // Windows: perform case-insensitive comparison.\n // NTFS and FAT32 preserve case but are case-insensitive for lookups.\n // This means 'C:\\Foo\\bar.txt' and 'c:\\foo\\BAR.TXT' refer to the same file.\n // Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#case-sensitivity\n if (WIN32) {\n const fromLower = actualFrom.toLowerCase()\n const toLower = actualTo.toLowerCase()\n if (fromLower === toLower) {\n return ''\n }\n }\n\n // Skip the leading separator for comparison.\n // We compare paths starting after the root separator to find common directories.\n // Example: '/foo/bar' becomes 'foo/bar' for comparison (index 1).\n const fromStart = 1\n const fromEnd = actualFrom.length\n const fromLen = fromEnd - fromStart\n const toStart = 1\n const toEnd = actualTo.length\n const toLen = toEnd - toStart\n\n // Compare paths character by character to find the longest common prefix.\n // We only consider a common prefix valid if it ends at a directory separator.\n const length = fromLen < toLen ? fromLen : toLen\n // Index of last common directory separator.\n let lastCommonSep = -1\n let i = 0\n\n for (; i < length; i += 1) {\n let fromCode = actualFrom.charCodeAt(fromStart + i)\n let toCode = actualTo.charCodeAt(toStart + i)\n\n // Paths diverge at this character.\n // On Windows, perform case-insensitive comparison.\n if (WIN32) {\n // Normalize to lowercase for case-insensitive comparison.\n // Convert A-Z (65-90) to a-z (97-122).\n if (fromCode >= CHAR_UPPERCASE_A && fromCode <= CHAR_UPPERCASE_Z) {\n fromCode += 32\n }\n if (toCode >= CHAR_UPPERCASE_A && toCode <= CHAR_UPPERCASE_Z) {\n toCode += 32\n }\n }\n\n if (fromCode !== toCode) {\n break\n }\n\n // Track directory separators (both forward and backslash for Windows compatibility).\n // We need this to ensure we only split at directory boundaries.\n // Use original fromCode from actualFrom (before case normalization).\n if (isPathSeparator(actualFrom.charCodeAt(fromStart + i))) {\n lastCommonSep = i\n }\n }\n\n // Handle edge cases where one path is a prefix of the other.\n if (i === length) {\n if (toLen > length) {\n // Destination path is longer.\n const toCode = actualTo.charCodeAt(toStart + i)\n if (isPathSeparator(toCode)) {\n // `from` is the exact base path for `to`.\n // Example: from='/foo/bar'; to='/foo/bar/baz' \u2192 'baz'\n // Skip the separator character (+1) to get just the relative portion.\n return actualTo.slice(toStart + i + 1)\n }\n if (i === 0) {\n // `from` is the root directory.\n // Example: from='/'; to='/foo' \u2192 'foo'\n return actualTo.slice(toStart + i)\n }\n } else if (fromLen > length) {\n // Source path is longer.\n const fromCode = actualFrom.charCodeAt(fromStart + i)\n if (isPathSeparator(fromCode)) {\n // `to` is the exact base path for `from`.\n // Example: from='/foo/bar/baz'; to='/foo/bar' \u2192 '..'\n // We need to go up from the extra directory.\n lastCommonSep = i\n } else if (i === 0) {\n // `to` is the root directory.\n // Example: from='/foo'; to='/' \u2192 '..'\n lastCommonSep = 0\n }\n }\n }\n\n // Generate the relative path by constructing '../' segments.\n let out = ''\n\n // Count the number of directories in `from` after the common base.\n // For each directory, we need to go up one level ('../').\n // Example: from='/a/b/c', to='/a/x' \u2192 common='a', need '../..' (up from c, up from b)\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; i += 1) {\n const code = actualFrom.charCodeAt(i)\n\n // At the end of the path or at a separator, add '../'.\n if (i === fromEnd || isPathSeparator(code)) {\n out += out.length === 0 ? '..' : '/..'\n }\n }\n\n // Append the rest of the destination path after the common base.\n // This gives us the path from the common ancestor to the destination.\n return out + actualTo.slice(toStart + lastCommonSep)\n}\n\n/**\n * Get the relative path from one path to another.\n *\n * Computes the relative path from `from` to `to` and normalizes the result.\n * This is a convenience wrapper around the `relative()` function that adds\n * path normalization (converting separators and collapsing segments).\n *\n * The function:\n * 1. Calculates the relative path using `relative()`\n * 2. Normalizes the result using `normalizePath()`\n * 3. Preserves empty strings (same path) without converting to `.`\n *\n * @param {string} from - The source path (starting point)\n * @param {string} to - The destination path (target)\n * @returns {string} The normalized relative path from `from` to `to`, or empty string if paths are identical\n *\n * @example\n * ```typescript\n * // Basic usage\n * relativeResolve('/foo/bar', '/foo/baz') // '../baz'\n * relativeResolve('/foo/bar/baz', '/foo') // '../..'\n * relativeResolve('/foo', '/foo/bar') // 'bar'\n *\n * // Same paths\n * relativeResolve('/foo/bar', '/foo/bar') // ''\n *\n * // Windows paths (normalized)\n * relativeResolve('C:\\\\foo\\\\bar', 'C:\\\\foo\\\\baz') // '../baz'\n *\n * // With normalization\n * relativeResolve('/foo/./bar', '/foo/baz') // '../baz'\n * relativeResolve('/foo/bar/../baz', '/foo/qux') // '../qux'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function relativeResolve(from: string, to: string): string {\n const rel = relative(from, to)\n // Empty string means same path - don't normalize to '.'\n if (rel === '') {\n return ''\n }\n return normalizePath(rel)\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["Buffer"]
|
|
7
|
-
}
|
package/dist/paths/rewire.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/paths/rewire.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Path rewiring utilities for testing.\n * Allows tests to override os.tmpdir() and os.homedir() without directly modifying them.\n *\n * Features:\n * - Test-friendly setPath/clearPath/resetPaths that work in beforeEach/afterEach\n * - Automatic cache invalidation for path-dependent modules\n * - Thread-safe for concurrent test execution\n */\n\n// Per-test overrides\n// Each test file gets its own instance due to Vitest's module isolation\nconst testOverrides = new Map<string, string | undefined>()\n\n// Cache for computed values (cleared when overrides change)\nconst valueCache = new Map<string, string>()\n\n// Cache invalidation callbacks - registered by modules that need to clear their caches\nconst cacheInvalidationCallbacks: Array<() => void> = []\n\n/**\n * Clear a specific path override.\n */\nexport function clearPath(key: string): void {\n testOverrides.delete(key)\n // Invalidate all path-related caches\n invalidateCaches()\n}\n\n/**\n * Get a path value, checking overrides first.\n *\n * Resolution order:\n * 1. Test overrides (set via setPath in beforeEach)\n * 2. Cached value (for performance)\n * 3. Original function call (cached for subsequent calls)\n *\n * @internal Used by path getters to support test rewiring\n */\nexport function getPathValue(key: string, originalFn: () => string): string {\n // Check test overrides first\n if (testOverrides.has(key)) {\n return testOverrides.get(key) as string\n }\n\n // Check cache\n if (valueCache.has(key)) {\n return valueCache.get(key) as string\n }\n\n // Compute and cache\n const value = originalFn()\n valueCache.set(key, value)\n return value\n}\n\n/**\n * Check if a path has been overridden.\n */\nexport function hasOverride(key: string): boolean {\n return testOverrides.has(key)\n}\n\n/**\n * Invalidate all cached paths.\n * Called automatically when setPath/clearPath/resetPaths are used.\n * Can also be called manually for advanced testing scenarios.\n *\n * @internal Primarily for internal use, but exported for advanced testing\n */\nexport function invalidateCaches(): void {\n // Clear the value cache\n valueCache.clear()\n\n // Call registered callbacks\n for (const callback of cacheInvalidationCallbacks) {\n try {\n callback()\n } catch {\n // Ignore errors from cache invalidation\n }\n }\n}\n\n/**\n * Register a cache invalidation callback.\n * Called by modules that need to clear their caches when paths change.\n *\n * @internal Used by paths.ts and fs.ts\n */\nexport function registerCacheInvalidation(callback: () => void): void {\n cacheInvalidationCallbacks.push(callback)\n}\n\n/**\n * Clear all path overrides and reset caches.\n * Useful in afterEach hooks to ensure clean test state.\n *\n * @example\n * ```typescript\n * import { resetPaths } from '#paths/rewire'\n *\n * afterEach(() => {\n * resetPaths()\n * })\n * ```\n */\nexport function resetPaths(): void {\n testOverrides.clear()\n // Invalidate all path-related caches\n invalidateCaches()\n}\n\n/**\n * Set a path override for testing.\n * This triggers cache invalidation for path-dependent modules.\n *\n * @example\n * ```typescript\n * import { setPath, resetPaths } from '#paths/rewire'\n * import { getOsTmpDir } from '#lib/paths'\n *\n * beforeEach(() => {\n * setPath('tmpdir', '/custom/tmp')\n * })\n *\n * afterEach(() => {\n * resetPaths()\n * })\n *\n * it('should use custom temp directory', () => {\n * expect(getOsTmpDir()).toBe('/custom/tmp')\n * })\n * ```\n */\nexport function setPath(key: string, value: string | undefined): void {\n testOverrides.set(key, value)\n // Invalidate all path-related caches\n invalidateCaches()\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,MAAM,gBAAgB,oBAAI,IAAgC;AAG1D,MAAM,aAAa,oBAAI,IAAoB;AAG3C,MAAM,6BAAgD,CAAC;AAKhD,SAAS,UAAU,KAAmB;AAC3C,gBAAc,OAAO,GAAG;AAExB,mBAAiB;AACnB;AAYO,SAAS,aAAa,KAAa,YAAkC;AAE1E,MAAI,cAAc,IAAI,GAAG,GAAG;AAC1B,WAAO,cAAc,IAAI,GAAG;AAAA,EAC9B;AAGA,MAAI,WAAW,IAAI,GAAG,GAAG;AACvB,WAAO,WAAW,IAAI,GAAG;AAAA,EAC3B;AAGA,QAAM,QAAQ,WAAW;AACzB,aAAW,IAAI,KAAK,KAAK;AACzB,SAAO;AACT;AAKO,SAAS,YAAY,KAAsB;AAChD,SAAO,cAAc,IAAI,GAAG;AAC9B;AASO,SAAS,mBAAyB;AAEvC,aAAW,MAAM;AAGjB,aAAW,YAAY,4BAA4B;AACjD,QAAI;AACF,eAAS;AAAA,IACX,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAQO,SAAS,0BAA0B,UAA4B;AACpE,6BAA2B,KAAK,QAAQ;AAC1C;AAeO,SAAS,aAAmB;AACjC,gBAAc,MAAM;AAEpB,mBAAiB;AACnB;AAwBO,SAAS,QAAQ,KAAa,OAAiC;AACpE,gBAAc,IAAI,KAAK,KAAK;AAE5B,mBAAiB;AACnB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/paths.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/paths.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Path utilities for Socket ecosystem directories.\n * Provides platform-aware path resolution for Socket tools' shared directory structure.\n *\n * Directory Structure:\n * ~/.socket/\n * \u251C\u2500\u2500 _cacache/ # Content-addressable cache for npm packages\n * \u251C\u2500\u2500 _dlx/ # DLX installations (content-addressed by hash)\n * \u2502 \u251C\u2500\u2500 <hash>/ # npm package installs (dlx-package)\n * \u2502 \u2514\u2500\u2500 <hash>/ # binary downloads (dlx-binary)\n * \u251C\u2500\u2500 _socket/ # Socket CLI app directory\n * \u251C\u2500\u2500 _registry/ # Socket Registry app directory\n * \u2514\u2500\u2500 _sfw/ # Socket Firewall app directory\n */\n\nimport * as os from 'os'\nimport * as path from 'path'\n\nimport { getHome } from '#env/home'\nimport {\n getSocketCacacheDir as getSocketCacacheDirEnv,\n getSocketDlxDirEnv,\n} from '#env/socket'\nimport { getUserprofile } from '#env/windows'\n\nimport { normalizePath } from './path'\nimport { getPathValue, registerCacheInvalidation } from './paths/rewire'\n\n/**\n * Get the OS home directory.\n * Can be overridden in tests using setPath('homedir', ...) from paths/rewire.\n */\nexport function getOsHomeDir(): string {\n // Always check for overrides - don't cache when using rewire\n return getPathValue('homedir', () => os.homedir())\n}\n\n/**\n * Get the OS temporary directory.\n * Can be overridden in tests using setPath('tmpdir', ...) from paths/rewire.\n */\nexport function getOsTmpDir(): string {\n // Always check for overrides - don't cache when using rewire\n return getPathValue('tmpdir', () => os.tmpdir())\n}\n\n/**\n * Get the Socket home directory (~/.socket).\n * Alias for getSocketUserDir() for consistency across Socket projects.\n */\nexport function getSocketHomePath(): string {\n return getSocketUserDir()\n}\n\nlet _cachedSocketUserDir: string | undefined\n\n/**\n * Get the Socket user directory (~/.socket).\n * Result is memoized for performance.\n */\nexport function getSocketUserDir(): string {\n if (_cachedSocketUserDir === undefined) {\n _cachedSocketUserDir = normalizePath(\n path.join(\n getUserHomeDir(),\n /*@__INLINE__*/ require('#constants/paths').DOT_SOCKET_DIR,\n ),\n )\n }\n return _cachedSocketUserDir\n}\n\n/**\n * Get a Socket app directory (~/.socket/_<appName>).\n */\nexport function getSocketAppDir(appName: string): string {\n return normalizePath(\n path.join(\n getSocketUserDir(),\n `${/*@__INLINE__*/ require('#constants/socket').SOCKET_APP_PREFIX}${appName}`,\n ),\n )\n}\n\nlet _cachedSocketCacacheDir: string | undefined\n\n/**\n * Get the Socket cacache directory (~/.socket/_cacache).\n * Can be overridden with SOCKET_CACACHE_DIR environment variable for testing.\n * Result is memoized for performance.\n */\nexport function getSocketCacacheDir(): string {\n if (_cachedSocketCacacheDir === undefined) {\n if (getSocketCacacheDirEnv()) {\n _cachedSocketCacacheDir = normalizePath(\n getSocketCacacheDirEnv() as string,\n )\n } else {\n _cachedSocketCacacheDir = normalizePath(\n path.join(\n getSocketUserDir(),\n `${/*@__INLINE__*/ require('#constants/socket').SOCKET_APP_PREFIX}cacache`,\n ),\n )\n }\n }\n return _cachedSocketCacacheDir\n}\n\n/**\n * Get the Socket DLX directory (~/.socket/_dlx).\n * Can be overridden with SOCKET_DLX_DIR environment variable for testing.\n */\nexport function getSocketDlxDir(): string {\n if (getSocketDlxDirEnv()) {\n return normalizePath(getSocketDlxDirEnv() as string)\n }\n return normalizePath(\n path.join(\n getSocketUserDir(),\n `${/*@__INLINE__*/ require('#constants/socket').SOCKET_APP_PREFIX}${/*@__INLINE__*/ require('#constants/socket').SOCKET_DLX_APP_NAME}`,\n ),\n )\n}\n\n/**\n * Get a Socket app cache directory (~/.socket/_<appName>/cache).\n */\nexport function getSocketAppCacheDir(appName: string): string {\n return normalizePath(\n path.join(\n getSocketAppDir(appName),\n /*@__INLINE__*/ require('#constants/paths').CACHE_DIR,\n ),\n )\n}\n\n/**\n * Get a Socket app TTL cache directory (~/.socket/_<appName>/cache/ttl).\n */\nexport function getSocketAppCacheTtlDir(appName: string): string {\n return normalizePath(\n path.join(\n getSocketAppCacheDir(appName),\n /*@__INLINE__*/ require('#constants/paths').CACHE_TTL_DIR,\n ),\n )\n}\n\n/**\n * Get the Socket CLI directory (~/.socket/_socket).\n */\nexport function getSocketCliDir(): string {\n return getSocketAppDir(\n /*@__INLINE__*/ require('#constants/socket').SOCKET_CLI_APP_NAME,\n )\n}\n\n/**\n * Get the Socket Registry directory (~/.socket/_registry).\n */\nexport function getSocketRegistryDir(): string {\n return getSocketAppDir(\n /*@__INLINE__*/ require('#constants/socket').SOCKET_REGISTRY_APP_NAME,\n )\n}\n\n/**\n * Get the Socket Registry GitHub cache directory (~/.socket/_registry/cache/ttl/github).\n */\nexport function getSocketRegistryGithubCacheDir(): string {\n return normalizePath(\n path.join(\n getSocketAppCacheTtlDir(\n /*@__INLINE__*/ require('#constants/socket').SOCKET_REGISTRY_APP_NAME,\n ),\n /*@__INLINE__*/ require('#constants/github').CACHE_GITHUB_DIR,\n ),\n )\n}\n\n/**\n * Get the user's home directory.\n * Uses environment variables directly to support test mocking.\n * Falls back to os.homedir() if env vars not set.\n */\nexport function getUserHomeDir(): string {\n // Try HOME first (Unix)\n const home = getHome()\n if (home) {\n return home\n }\n // Try USERPROFILE (Windows)\n const userProfile = getUserprofile()\n if (userProfile) {\n return userProfile\n }\n // Fallback to os.homedir()\n return getOsHomeDir()\n}\n\n/**\n * Invalidate all cached path values.\n * Called automatically by the paths/rewire module when setPath/clearPath/resetPaths are used.\n *\n * @internal Used for test rewiring\n */\nexport function invalidateCache(): void {\n _cachedSocketUserDir = undefined\n _cachedSocketCacacheDir = undefined\n}\n\n// Register cache invalidation with the rewire module\nregisterCacheInvalidation(invalidateCache)\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["getSocketCacacheDirEnv"]
|
|
7
|
-
}
|
package/dist/performance.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/performance.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Performance monitoring utilities for profiling and optimization.\n * Provides timing, profiling, and performance metric collection for identifying bottlenecks.\n */\n\nimport { debugLog } from './debug'\n\n/**\n * Performance metrics collected during execution.\n */\ntype PerformanceMetrics = {\n operation: string\n duration: number\n timestamp: number\n metadata?: Record<string, unknown>\n}\n\n/**\n * Global metrics collection (only in debug mode).\n */\nconst performanceMetrics: PerformanceMetrics[] = []\n\n/**\n * Check if performance tracking is enabled.\n */\nfunction isPerfEnabled(): boolean {\n return process.env['DEBUG']?.includes('perf') || false\n}\n\n/**\n * Start a performance timer for an operation.\n * Returns a stop function that records the duration.\n *\n * @param operation - Name of the operation being timed\n * @param metadata - Optional metadata to attach to the metric\n * @returns Stop function that completes the timing\n *\n * @example\n * import { perfTimer } from '@socketsecurity/lib/performance'\n *\n * const stop = perfTimer('api-call')\n * await fetchData()\n * stop({ endpoint: '/npm/lodash/score' })\n */\nexport function perfTimer(\n operation: string,\n metadata?: Record<string, unknown>,\n): (additionalMetadata?: Record<string, unknown>) => void {\n if (!isPerfEnabled()) {\n // No-op if perf tracking disabled\n return () => {}\n }\n\n const start = performance.now()\n debugLog(`[perf] [START] ${operation}`)\n\n return (additionalMetadata?: Record<string, unknown>) => {\n const duration = performance.now() - start\n const metric: PerformanceMetrics = {\n operation,\n // Round to 2 decimals\n duration: Math.round(duration * 100) / 100,\n timestamp: Date.now(),\n metadata: { ...metadata, ...additionalMetadata },\n }\n\n performanceMetrics.push(metric)\n debugLog(`[perf] [END] ${operation} - ${metric.duration}ms`)\n }\n}\n\n/**\n * Measure execution time of an async function.\n *\n * @param operation - Name of the operation\n * @param fn - Async function to measure\n * @param metadata - Optional metadata\n * @returns Result of the function and duration\n *\n * @example\n * import { measure } from '@socketsecurity/lib/performance'\n *\n * const { result, duration } = await measure('fetch-packages', async () => {\n * return await fetchPackages()\n * })\n * console.log(`Fetched packages in ${duration}ms`)\n */\nexport async function measure<T>(\n operation: string,\n fn: () => Promise<T>,\n metadata?: Record<string, unknown>,\n): Promise<{ result: T; duration: number }> {\n const stop = perfTimer(operation, metadata)\n\n try {\n const result = await fn()\n stop({ success: true })\n\n const metric = performanceMetrics[performanceMetrics.length - 1]\n return { result, duration: metric?.duration || 0 }\n } catch (e) {\n stop({\n success: false,\n error: e instanceof Error ? e.message : 'Unknown',\n })\n throw e\n }\n}\n\n/**\n * Measure synchronous function execution time.\n *\n * @param operation - Name of the operation\n * @param fn - Synchronous function to measure\n * @param metadata - Optional metadata\n * @returns Result of the function and duration\n *\n * @example\n * import { measureSync } from '@socketsecurity/lib/performance'\n *\n * const { result, duration } = measureSync('parse-json', () => {\n * return JSON.parse(data)\n * })\n */\nexport function measureSync<T>(\n operation: string,\n fn: () => T,\n metadata?: Record<string, unknown>,\n): { result: T; duration: number } {\n const stop = perfTimer(operation, metadata)\n\n try {\n const result = fn()\n stop({ success: true })\n\n const metric = performanceMetrics[performanceMetrics.length - 1]\n return { result, duration: metric?.duration || 0 }\n } catch (e) {\n stop({\n success: false,\n error: e instanceof Error ? e.message : 'Unknown',\n })\n throw e\n }\n}\n\n/**\n * Get all collected performance metrics.\n * Only available when DEBUG=perf is enabled.\n *\n * @returns Array of performance metrics\n *\n * @example\n * import { getPerformanceMetrics } from '@socketsecurity/lib/performance'\n *\n * const metrics = getPerformanceMetrics()\n * console.log(metrics)\n */\nexport function getPerformanceMetrics(): PerformanceMetrics[] {\n return [...performanceMetrics]\n}\n\n/**\n * Clear all collected performance metrics.\n *\n * @example\n * import { clearPerformanceMetrics } from '@socketsecurity/lib/performance'\n *\n * clearPerformanceMetrics()\n */\nexport function clearPerformanceMetrics(): void {\n performanceMetrics.length = 0\n debugLog('[perf] Cleared performance metrics')\n}\n\n/**\n * Get performance summary statistics.\n *\n * @returns Summary of metrics grouped by operation\n *\n * @example\n * import { getPerformanceSummary } from '@socketsecurity/lib/performance'\n *\n * const summary = getPerformanceSummary()\n * console.log(summary)\n * // {\n * // 'api-call': { count: 5, total: 1234, avg: 246.8, min: 100, max: 500 },\n * // 'file-read': { count: 10, total: 50, avg: 5, min: 2, max: 15 }\n * // }\n */\nexport function getPerformanceSummary(): Record<\n string,\n {\n count: number\n total: number\n avg: number\n min: number\n max: number\n }\n> {\n const summary: Record<\n string,\n { count: number; total: number; min: number; max: number }\n > = Object.create(null)\n\n for (const metric of performanceMetrics) {\n const { duration, operation } = metric\n\n if (!summary[operation]) {\n summary[operation] = {\n count: 0,\n total: 0,\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n }\n }\n\n const stats = summary[operation] as {\n count: number\n total: number\n min: number\n max: number\n }\n stats.count++\n stats.total += duration\n stats.min = Math.min(stats.min, duration)\n stats.max = Math.max(stats.max, duration)\n }\n\n // Calculate averages and return with proper typing\n const result: Record<\n string,\n { count: number; total: number; avg: number; min: number; max: number }\n > = Object.create(null)\n\n for (const { 0: operation, 1: stats } of Object.entries(summary)) {\n result[operation] = {\n count: stats.count,\n total: Math.round(stats.total * 100) / 100,\n avg: Math.round((stats.total / stats.count) * 100) / 100,\n min: Math.round(stats.min * 100) / 100,\n max: Math.round(stats.max * 100) / 100,\n }\n }\n\n return result\n}\n\n/**\n * Print performance summary to console.\n * Only prints when DEBUG=perf is enabled.\n *\n * @example\n * import { printPerformanceSummary } from '@socketsecurity/lib/performance'\n *\n * printPerformanceSummary()\n * // Performance Summary:\n * // api-call: 5 calls, avg 246.8ms (min 100ms, max 500ms, total 1234ms)\n * // file-read: 10 calls, avg 5ms (min 2ms, max 15ms, total 50ms)\n */\nexport function printPerformanceSummary(): void {\n if (!isPerfEnabled() || performanceMetrics.length === 0) {\n return\n }\n\n const summary = getPerformanceSummary()\n const operations = Object.keys(summary).sort()\n\n debugLog('[perf]\\n=== Performance Summary ===')\n\n for (const operation of operations) {\n const stats = summary[operation] as {\n count: number\n total: number\n avg: number\n min: number\n max: number\n }\n debugLog(\n `[perf] ${operation}: ${stats.count} calls, avg ${stats.avg}ms (min ${stats.min}ms, max ${stats.max}ms, total ${stats.total}ms)`,\n )\n }\n\n debugLog('[perf] =========================\\n')\n}\n\n/**\n * Mark a checkpoint in performance tracking.\n * Useful for tracking progress through complex operations.\n *\n * @param checkpoint - Name of the checkpoint\n * @param metadata - Optional metadata\n *\n * @example\n * import { perfCheckpoint } from '@socketsecurity/lib/performance'\n *\n * perfCheckpoint('start-scan')\n * // ... do work ...\n * perfCheckpoint('fetch-packages', { count: 50 })\n * // ... do work ...\n * perfCheckpoint('analyze-issues', { issueCount: 10 })\n * perfCheckpoint('end-scan')\n */\nexport function perfCheckpoint(\n checkpoint: string,\n metadata?: Record<string, unknown>,\n): void {\n if (!isPerfEnabled()) {\n return\n }\n\n const metric: PerformanceMetrics = {\n operation: `checkpoint:${checkpoint}`,\n duration: 0,\n timestamp: Date.now(),\n ...(metadata ? { metadata } : {}),\n }\n\n performanceMetrics.push(metric)\n debugLog(`[perf] [CHECKPOINT] ${checkpoint}`)\n}\n\n/**\n * Track memory usage at a specific point.\n * Only available when DEBUG=perf is enabled.\n *\n * @param label - Label for this memory snapshot\n * @returns Memory usage in MB\n *\n * @example\n * import { trackMemory } from '@socketsecurity/lib/performance'\n *\n * const memBefore = trackMemory('before-operation')\n * await heavyOperation()\n * const memAfter = trackMemory('after-operation')\n * console.log(`Memory increased by ${memAfter - memBefore}MB`)\n */\nexport function trackMemory(label: string): number {\n if (!isPerfEnabled()) {\n return 0\n }\n\n const usage = process.memoryUsage()\n const heapUsedMB = Math.round((usage.heapUsed / 1024 / 1024) * 100) / 100\n\n debugLog(`[perf] [MEMORY] ${label}: ${heapUsedMB}MB heap used`)\n\n const metric: PerformanceMetrics = {\n operation: `checkpoint:memory:${label}`,\n duration: 0,\n timestamp: Date.now(),\n metadata: {\n heapUsed: heapUsedMB,\n heapTotal: Math.round((usage.heapTotal / 1024 / 1024) * 100) / 100,\n external: Math.round((usage.external / 1024 / 1024) * 100) / 100,\n },\n }\n\n performanceMetrics.push(metric)\n\n return heapUsedMB\n}\n\n/**\n * Create a performance report for the current execution.\n * Only available when DEBUG=perf is enabled.\n *\n * @returns Formatted performance report\n *\n * @example\n * import { generatePerformanceReport } from '@socketsecurity/lib/performance'\n *\n * console.log(generatePerformanceReport())\n * // \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n * // \u2551 Performance Report \u2551\n * // \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n * //\n * // api-call:\n * // Calls: 5\n * // Avg: 246.8ms\n * // Min: 100ms\n * // Max: 500ms\n * // Total: 1234ms\n */\nexport function generatePerformanceReport(): string {\n if (!isPerfEnabled() || performanceMetrics.length === 0) {\n return '(no performance data collected - enable with DEBUG=perf)'\n }\n\n const summary = getPerformanceSummary()\n const operations = Object.keys(summary).sort()\n\n let report = '\\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\\n'\n report += '\u2551 Performance Report \u2551\\n'\n report += '\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\\n\\n'\n\n for (const operation of operations) {\n const stats = summary[operation] as {\n count: number\n total: number\n avg: number\n min: number\n max: number\n }\n report += `${operation}:\\n`\n report += ` Calls: ${stats.count}\\n`\n report += ` Avg: ${stats.avg}ms\\n`\n report += ` Min: ${stats.min}ms\\n`\n report += ` Max: ${stats.max}ms\\n`\n report += ` Total: ${stats.total}ms\\n\\n`\n }\n\n const totalDuration = Object.values(summary).reduce(\n (sum, s) => sum + s.total,\n 0,\n )\n report += `Total measured time: ${Math.round(totalDuration * 100) / 100}ms\\n`\n\n return report\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/process-lock.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/process-lock.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Process locking utilities with stale detection and exit cleanup.\n * Provides cross-platform inter-process synchronization using directory-based locks.\n * Aligned with npm's npx locking strategy (5-second stale timeout, periodic touching).\n *\n * ## Why directories instead of files?\n *\n * This implementation uses `mkdir()` to create lock directories (not files) because:\n *\n * 1. **Atomic guarantee**: `mkdir()` is guaranteed atomic across ALL filesystems,\n * including NFS. Only ONE process can successfully create the directory. If it\n * exists, `mkdir()` fails with EEXIST instantly with no race conditions.\n *\n * 2. **File-based locking issues**:\n * - `writeFile()` with `flag: 'wx'` - atomicity can fail on NFS\n * - `open()` with `O_EXCL` - not guaranteed atomic on older NFS\n * - Traditional lockfiles - can have race conditions on network filesystems\n *\n * 3. **Simplicity**: No need to write/read file content, track PIDs, or manage\n * file descriptors. Just create/delete directory and check mtime.\n *\n * 4. **Historical precedent**: Well-known Unix locking pattern used by package\n * managers for decades. Git uses similar approach for `.git/index.lock`.\n *\n * ## The mtime trick\n *\n * We periodically update the lock directory's mtime (modification time) by\n * \"touching\" it to signal \"I'm still actively working\". This prevents other\n * processes from treating the lock as stale and removing it.\n *\n * **The lock directory remains empty** - it's just a sentinel that signals\n * \"locked\". The mtime is the only data needed to track lock freshness.\n *\n * ## npm npx compatibility\n *\n * This implementation matches npm npx's concurrency.lock approach:\n * - Lock created via `mkdir(path.join(installDir, 'concurrency.lock'))`\n * - 5-second stale timeout (if mtime is older than 5s, lock is stale)\n * - 2-second touching interval (updates mtime every 2s to keep lock fresh)\n * - Automatic cleanup on process exit\n */\n\nimport { existsSync, mkdirSync, statSync, utimesSync } from 'fs'\n\nimport { safeDeleteSync } from './fs'\nimport { getDefaultLogger } from './logger'\nimport { pRetry } from './promises'\nimport { onExit } from './signal-exit'\n\nconst logger = getDefaultLogger()\n\n/**\n * Lock acquisition options.\n */\nexport interface ProcessLockOptions {\n /**\n * Maximum number of retry attempts.\n * @default 3\n */\n retries?: number | undefined\n\n /**\n * Base delay between retries in milliseconds.\n * @default 100\n */\n baseDelayMs?: number | undefined\n\n /**\n * Maximum delay between retries in milliseconds.\n * @default 1000\n */\n maxDelayMs?: number | undefined\n\n /**\n * Stale lock timeout in milliseconds.\n * Locks older than this are considered abandoned and can be reclaimed.\n * Aligned with npm's npx locking strategy (5 seconds).\n * @default 5000 (5 seconds)\n */\n staleMs?: number | undefined\n\n /**\n * Interval for touching lock file to keep it fresh in milliseconds.\n * Set to 0 to disable periodic touching.\n * @default 2000 (2 seconds)\n */\n touchIntervalMs?: number | undefined\n}\n\n/**\n * Process lock manager with stale detection and exit cleanup.\n * Provides cross-platform inter-process synchronization using file-system\n * based locks.\n */\nclass ProcessLockManager {\n private activeLocks = new Set<string>()\n private touchTimers = new Map<string, NodeJS.Timeout>()\n private exitHandlerRegistered = false\n\n /**\n * Ensure process exit handler is registered for cleanup.\n * Registers a handler that cleans up all active locks when the process exits.\n */\n private ensureExitHandler() {\n if (this.exitHandlerRegistered) {\n return\n }\n\n onExit(() => {\n // Clear all touch timers.\n for (const timer of this.touchTimers.values()) {\n clearInterval(timer)\n }\n this.touchTimers.clear()\n\n // Clean up all active locks.\n for (const lockPath of this.activeLocks) {\n try {\n if (existsSync(lockPath)) {\n safeDeleteSync(lockPath, { recursive: true })\n }\n } catch {\n // Ignore cleanup errors during exit.\n }\n }\n })\n\n this.exitHandlerRegistered = true\n }\n\n /**\n * Touch a lock file to update its mtime.\n * This prevents the lock from being detected as stale during long operations.\n *\n * @param lockPath - Path to the lock directory\n */\n private touchLock(lockPath: string): void {\n try {\n if (existsSync(lockPath)) {\n const now = new Date()\n utimesSync(lockPath, now, now)\n }\n } catch (error) {\n logger.warn(\n `Failed to touch lock ${lockPath}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n\n /**\n * Start periodic touching of a lock file.\n * Aligned with npm npx strategy to prevent false stale detection.\n *\n * @param lockPath - Path to the lock directory\n * @param intervalMs - Touch interval in milliseconds\n */\n private startTouchTimer(lockPath: string, intervalMs: number): void {\n if (intervalMs <= 0 || this.touchTimers.has(lockPath)) {\n return\n }\n\n const timer = setInterval(() => {\n this.touchLock(lockPath)\n }, intervalMs)\n\n // Prevent timer from keeping process alive.\n timer.unref()\n\n this.touchTimers.set(lockPath, timer)\n }\n\n /**\n * Stop periodic touching of a lock file.\n *\n * @param lockPath - Path to the lock directory\n */\n private stopTouchTimer(lockPath: string): void {\n const timer = this.touchTimers.get(lockPath)\n if (timer) {\n clearInterval(timer)\n this.touchTimers.delete(lockPath)\n }\n }\n\n /**\n * Check if a lock is stale based on mtime.\n * Uses second-level granularity to avoid APFS floating-point precision issues.\n * Aligned with npm's npx locking strategy.\n *\n * @param lockPath - Path to the lock directory\n * @param staleMs - Stale timeout in milliseconds\n * @returns True if lock exists and is stale\n */\n private isStale(lockPath: string, staleMs: number): boolean {\n try {\n if (!existsSync(lockPath)) {\n return false\n }\n\n const stats = statSync(lockPath)\n // Use second-level granularity to avoid APFS issues.\n const ageSeconds = Math.floor((Date.now() - stats.mtime.getTime()) / 1000)\n const staleSeconds = Math.floor(staleMs / 1000)\n return ageSeconds > staleSeconds\n } catch {\n return false\n }\n }\n\n /**\n * Acquire a lock using mkdir for atomic operation.\n * Handles stale locks and includes exit cleanup.\n *\n * This method attempts to create a lock directory atomically. If the lock\n * already exists, it checks if it's stale and removes it before retrying.\n * Uses exponential backoff with jitter for retry attempts.\n *\n * @param lockPath - Path to the lock directory\n * @param options - Lock acquisition options\n * @returns Release function to unlock\n * @throws Error if lock cannot be acquired after all retries\n *\n * @example\n * ```typescript\n * const release = await processLock.acquire('/tmp/my-lock')\n * try {\n * // Critical section\n * } finally {\n * release()\n * }\n * ```\n */\n async acquire(\n lockPath: string,\n options: ProcessLockOptions = {},\n ): Promise<() => void> {\n const {\n baseDelayMs = 100,\n maxDelayMs = 1000,\n retries = 3,\n staleMs = 5000,\n touchIntervalMs = 2000,\n } = options\n\n // Ensure exit handler is registered before any lock acquisition.\n this.ensureExitHandler()\n\n return await pRetry(\n async () => {\n try {\n // Check for stale lock and remove if necessary.\n if (existsSync(lockPath) && this.isStale(lockPath, staleMs)) {\n logger.log(`Removing stale lock: ${lockPath}`)\n try {\n safeDeleteSync(lockPath, { recursive: true })\n } catch {\n // Ignore errors removing stale lock - will retry.\n }\n }\n\n // Check if lock already exists before creating.\n if (existsSync(lockPath)) {\n throw new Error(`Lock already exists: ${lockPath}`)\n }\n\n // Atomic lock acquisition via mkdir with recursive to create parent dirs.\n mkdirSync(lockPath, { recursive: true })\n\n // Track lock for cleanup.\n this.activeLocks.add(lockPath)\n\n // Start periodic touching to prevent stale detection.\n this.startTouchTimer(lockPath, touchIntervalMs)\n\n // Return release function.\n return () => this.release(lockPath)\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code\n\n // Handle lock contention - lock already exists.\n if (code === 'EEXIST') {\n if (this.isStale(lockPath, staleMs)) {\n throw new Error(`Stale lock detected: ${lockPath}`)\n }\n throw new Error(`Lock already exists: ${lockPath}`)\n }\n\n // Handle permission errors - not retryable.\n if (code === 'EACCES' || code === 'EPERM') {\n throw new Error(\n `Permission denied creating lock: ${lockPath}. ` +\n 'Check directory permissions or run with appropriate access.',\n { cause: error },\n )\n }\n\n // Handle read-only filesystem - not retryable.\n if (code === 'EROFS') {\n throw new Error(\n `Cannot create lock on read-only filesystem: ${lockPath}`,\n { cause: error },\n )\n }\n\n // Handle parent path issues - not retryable.\n if (code === 'ENOTDIR') {\n const parentDir = lockPath.slice(0, lockPath.lastIndexOf('/'))\n throw new Error(\n `Cannot create lock directory: ${lockPath}\\n` +\n 'A path component is a file when it should be a directory.\\n' +\n `Parent path: ${parentDir}\\n` +\n 'To resolve:\\n' +\n ` 1. Check if \"${parentDir}\" contains a file instead of a directory\\n` +\n ' 2. Remove any conflicting files in the path\\n' +\n ' 3. Ensure the full parent directory structure exists',\n { cause: error },\n )\n }\n\n if (code === 'ENOENT') {\n const parentDir = lockPath.slice(0, lockPath.lastIndexOf('/'))\n throw new Error(\n `Cannot create lock directory: ${lockPath}\\n` +\n `Parent directory does not exist: ${parentDir}\\n` +\n 'To resolve:\\n' +\n ` 1. Ensure the parent directory \"${parentDir}\" exists\\n` +\n ` 2. Create the directory structure: mkdir -p \"${parentDir}\"\\n` +\n ' 3. Check filesystem permissions allow directory creation',\n { cause: error },\n )\n }\n\n // Re-throw other errors with context.\n throw new Error(`Failed to acquire lock: ${lockPath}`, {\n cause: error,\n })\n }\n },\n {\n retries,\n baseDelayMs,\n maxDelayMs,\n jitter: true,\n },\n )\n }\n\n /**\n * Release a lock and remove from tracking.\n * Stops periodic touching and removes the lock directory.\n *\n * @param lockPath - Path to the lock directory\n *\n * @example\n * ```typescript\n * processLock.release('/tmp/my-lock')\n * ```\n */\n release(lockPath: string): void {\n // Stop periodic touching.\n this.stopTouchTimer(lockPath)\n\n try {\n if (existsSync(lockPath)) {\n safeDeleteSync(lockPath, { recursive: true })\n }\n this.activeLocks.delete(lockPath)\n } catch (error) {\n logger.warn(\n `Failed to release lock ${lockPath}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n }\n\n /**\n * Execute a function with exclusive lock protection.\n * Automatically handles lock acquisition, execution, and cleanup.\n *\n * This is the recommended way to use process locks, as it guarantees\n * cleanup even if the callback throws an error.\n *\n * @param lockPath - Path to the lock directory\n * @param fn - Function to execute while holding the lock\n * @param options - Lock acquisition options\n * @returns Result of the callback function\n * @throws Error from callback or lock acquisition failure\n *\n * @example\n * ```typescript\n * const result = await processLock.withLock('/tmp/my-lock', async () => {\n * // Critical section\n * return someValue\n * })\n * ```\n */\n async withLock<T>(\n lockPath: string,\n fn: () => Promise<T>,\n options?: ProcessLockOptions,\n ): Promise<T> {\n const release = await this.acquire(lockPath, options)\n try {\n return await fn()\n } finally {\n release()\n }\n }\n}\n\n// Export singleton instance.\nexport const processLock = new ProcessLockManager()\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_fs"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/promise-queue.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * A promise queue that limits concurrent execution of async tasks.\n * Based on patterns from coana-package-manager for resource-aware async operations.\n */\n\ntype QueuedTask<T> = {\n fn: () => Promise<T>\n resolve: (value: T) => void\n reject: (error: unknown) => void\n}\n\nexport class PromiseQueue {\n private queue: Array<QueuedTask<unknown>> = []\n private running = 0\n\n private readonly maxConcurrency: number\n private readonly maxQueueLength: number | undefined\n\n /**\n * Creates a new PromiseQueue\n * @param maxConcurrency - Maximum number of promises that can run concurrently\n * @param maxQueueLength - Maximum queue size (older tasks are dropped if exceeded)\n */\n constructor(maxConcurrency: number, maxQueueLength?: number | undefined) {\n this.maxConcurrency = maxConcurrency\n this.maxQueueLength = maxQueueLength\n if (maxConcurrency < 1) {\n throw new Error('maxConcurrency must be at least 1')\n }\n }\n\n /**\n * Add a task to the queue\n * @param fn - Async function to execute\n * @returns Promise that resolves with the function's result\n */\n async add<T>(fn: () => Promise<T>): Promise<T> {\n return await new Promise<T>((resolve, reject) => {\n const task: QueuedTask<T> = { fn, resolve, reject }\n\n if (this.maxQueueLength && this.queue.length >= this.maxQueueLength) {\n // Drop oldest task to prevent memory buildup\n const droppedTask = this.queue.shift()\n if (droppedTask) {\n droppedTask.reject(new Error('Task dropped: queue length exceeded'))\n }\n }\n\n this.queue.push(task as QueuedTask<unknown>)\n this.runNext()\n })\n }\n\n private runNext(): void {\n if (this.running >= this.maxConcurrency || this.queue.length === 0) {\n return\n }\n\n const task = this.queue.shift()\n if (!task) {\n return\n }\n\n this.running++\n\n task\n .fn()\n .then(task.resolve)\n .catch(task.reject)\n .finally(() => {\n this.running--\n this.runNext()\n })\n }\n\n /**\n * Wait for all queued and running tasks to complete\n */\n async onIdle(): Promise<void> {\n return await new Promise<void>(resolve => {\n const check = () => {\n if (this.running === 0 && this.queue.length === 0) {\n resolve()\n } else {\n setImmediate(check)\n }\n }\n check()\n })\n }\n\n /**\n * Get the number of tasks currently running\n */\n get activeCount(): number {\n return this.running\n }\n\n /**\n * Get the number of tasks waiting in the queue\n */\n get pendingCount(): number {\n return this.queue.length\n }\n\n /**\n * Clear all pending tasks from the queue (does not affect running tasks)\n */\n clear(): void {\n this.queue = []\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,MAAM,aAAa;AAAA,EAChB,QAAoC,CAAC;AAAA,EACrC,UAAU;AAAA,EAED;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,gBAAwB,gBAAqC;AACvE,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AACtB,QAAI,iBAAiB,GAAG;AACtB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IAAO,IAAkC;AAC7C,WAAO,MAAM,IAAI,QAAW,CAAC,SAAS,WAAW;AAC/C,YAAM,OAAsB,EAAE,IAAI,SAAS,OAAO;AAElD,UAAI,KAAK,kBAAkB,KAAK,MAAM,UAAU,KAAK,gBAAgB;AAEnE,cAAM,cAAc,KAAK,MAAM,MAAM;AACrC,YAAI,aAAa;AACf,sBAAY,OAAO,IAAI,MAAM,qCAAqC,CAAC;AAAA,QACrE;AAAA,MACF;AAEA,WAAK,MAAM,KAAK,IAA2B;AAC3C,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEQ,UAAgB;AACtB,QAAI,KAAK,WAAW,KAAK,kBAAkB,KAAK,MAAM,WAAW,GAAG;AAClE;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,SAAK;AAEL,SACG,GAAG,EACH,KAAK,KAAK,OAAO,EACjB,MAAM,KAAK,MAAM,EACjB,QAAQ,MAAM;AACb,WAAK;AACL,WAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAwB;AAC5B,WAAO,MAAM,IAAI,QAAc,aAAW;AACxC,YAAM,QAAQ,MAAM;AAClB,YAAI,KAAK,YAAY,KAAK,KAAK,MAAM,WAAW,GAAG;AACjD,kBAAQ;AAAA,QACV,OAAO;AACL,uBAAa,KAAK;AAAA,QACpB;AAAA,MACF;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,eAAuB;AACzB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,QAAQ,CAAC;AAAA,EAChB;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/promises.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/promises.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Promise utilities including chunked iteration and timers.\n * Provides async control flow helpers and promise-based timing functions.\n */\n\nimport { UNDEFINED_TOKEN } from '#constants/core'\nimport { getAbortSignal } from '#constants/process'\n\nimport { arrayChunk } from './arrays'\n\nconst abortSignal = getAbortSignal()\n\n/**\n * Configuration options for retry behavior with exponential backoff.\n *\n * Controls how failed operations are retried, including timing, backoff strategy,\n * and callback hooks for observing or modifying retry behavior.\n */\nexport interface RetryOptions {\n /**\n * Arguments to pass to the callback function on each attempt.\n *\n * @default []\n */\n args?: unknown[] | undefined\n\n /**\n * Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n * Each retry waits `baseDelayMs * (backoffFactor ** attemptNumber)`.\n *\n * @default 2\n * @example\n * // With backoffFactor: 2, baseDelayMs: 100\n * // Retry 1: 100ms\n * // Retry 2: 200ms\n * // Retry 3: 400ms\n */\n backoffFactor?: number | undefined\n\n /**\n * Initial delay before the first retry (in milliseconds).\n * This is the base value for exponential backoff calculations.\n *\n * @default 200\n */\n baseDelayMs?: number | undefined\n\n // REMOVED: Deprecated `factor` option\n // Migration: Use `backoffFactor` instead\n\n /**\n * Whether to apply randomness to spread out retries and avoid thundering herd.\n * When `true`, adds random delay between 0 and current delay value.\n *\n * @default true\n * @example\n * // With jitter: true, delay: 100ms\n * // Actual wait: 100ms + random(0-100ms) = 100-200ms\n */\n jitter?: boolean | undefined\n\n /**\n * Upper limit for any backoff delay (in milliseconds).\n * Prevents exponential backoff from growing unbounded.\n *\n * @default 10000\n */\n maxDelayMs?: number | undefined\n\n // REMOVED: Deprecated `maxTimeout` option\n // Migration: Use `maxDelayMs` instead\n\n // REMOVED: Deprecated `minTimeout` option\n // Migration: Use `baseDelayMs` instead\n\n /**\n * Callback invoked on each retry attempt.\n * Can observe errors, customize delays, or cancel retries.\n *\n * @param attempt - The current attempt number (1-based: 1, 2, 3, ...)\n * @param error - The error that triggered this retry\n * @param delay - The calculated delay in milliseconds before next retry\n * @returns `false` to cancel retries (if `onRetryCancelOnFalse` is `true`),\n * a number to override the delay, or `undefined` to use calculated delay\n *\n * @example\n * // Log each retry\n * onRetry: (attempt, error, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms: ${error}`)\n * }\n *\n * @example\n * // Cancel retries for specific errors\n * onRetry: (attempt, error) => {\n * if (error instanceof ValidationError) return false\n * }\n *\n * @example\n * // Use custom delay\n * onRetry: (attempt) => attempt * 1000 // 1s, 2s, 3s, ...\n */\n onRetry?:\n | ((\n attempt: number,\n error: unknown,\n delay: number,\n ) => boolean | number | undefined)\n | undefined\n\n /**\n * Whether `onRetry` can cancel retries by returning `false`.\n * When `true`, returning `false` from `onRetry` stops retry attempts.\n *\n * @default false\n */\n onRetryCancelOnFalse?: boolean | undefined\n\n /**\n * Whether errors thrown by `onRetry` should propagate.\n * When `true`, exceptions in `onRetry` terminate the retry loop.\n * When `false`, exceptions in `onRetry` are silently caught.\n *\n * @default false\n */\n onRetryRethrow?: boolean | undefined\n\n /**\n * Number of retry attempts (0 = no retries, only initial attempt).\n * The callback is executed `retries + 1` times total (initial + retries).\n *\n * @default 0\n * @example\n * // retries: 0 -> 1 total attempt (no retries)\n * // retries: 3 -> 4 total attempts (1 initial + 3 retries)\n */\n retries?: number | undefined\n\n /**\n * AbortSignal to support cancellation of retry operations.\n * When aborted, immediately stops retrying and returns `undefined`.\n *\n * @default process abort signal\n * @example\n * const controller = new AbortController()\n * pRetry(fn, { signal: controller.signal })\n * // Later: controller.abort() to cancel\n */\n signal?: AbortSignal | undefined\n}\n\n/**\n * Configuration options for iteration functions with concurrency control.\n *\n * Controls how array operations are parallelized and retried.\n */\nexport interface IterationOptions {\n /**\n * The number of concurrent executions performed at one time.\n * Higher values increase parallelism but may overwhelm resources.\n *\n * @default 1\n * @example\n * // Process 5 items at a time\n * await pEach(items, processItem, { concurrency: 5 })\n */\n concurrency?: number | undefined\n\n /**\n * Retry configuration as a number (retry count) or full options object.\n * Applied to each individual item's callback execution.\n *\n * @default 0 (no retries)\n * @example\n * // Simple: retry each item up to 3 times\n * await pEach(items, fetchItem, { retries: 3 })\n *\n * @example\n * // Advanced: custom backoff for each item\n * await pEach(items, fetchItem, {\n * retries: {\n * retries: 3,\n * baseDelayMs: 1000,\n * backoffFactor: 2\n * }\n * })\n */\n retries?: number | RetryOptions | undefined\n\n /**\n * AbortSignal to support cancellation of the entire iteration.\n * When aborted, stops processing remaining items.\n *\n * @default process abort signal\n */\n signal?: AbortSignal | undefined\n}\n\nlet _timers: typeof import('node:timers/promises') | undefined\n/**\n * Get the timers/promises module.\n * Uses lazy loading to avoid Webpack bundling issues.\n *\n * @private\n * @returns The Node.js timers/promises module\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getTimers() {\n if (_timers === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _timers = /*@__PURE__*/ require('node:timers/promises')\n }\n return _timers as typeof import('node:timers/promises')\n}\n\n/**\n * Normalize options for iteration functions.\n *\n * Converts various option formats into a consistent structure with defaults applied.\n * Handles number shorthand for concurrency and ensures minimum values.\n *\n * @param options - Concurrency as number, or full options object, or undefined\n * @returns Normalized options with concurrency, retries, and signal\n *\n * @example\n * // Number shorthand for concurrency\n * normalizeIterationOptions(5)\n * // => { concurrency: 5, retries: {...}, signal: AbortSignal }\n *\n * @example\n * // Full options\n * normalizeIterationOptions({ concurrency: 3, retries: 2 })\n * // => { concurrency: 3, retries: {...}, signal: AbortSignal }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeIterationOptions(\n options?: number | IterationOptions | undefined,\n): { concurrency: number; retries: RetryOptions; signal: AbortSignal } {\n // Handle number as concurrency shorthand\n const opts = typeof options === 'number' ? { concurrency: options } : options\n\n const {\n // The number of concurrent executions performed at one time.\n concurrency = 1,\n // Retries as a number or options object.\n retries,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = { __proto__: null, ...opts } as IterationOptions\n\n // Ensure concurrency is at least 1\n const normalizedConcurrency = Math.max(1, concurrency)\n const retryOpts = resolveRetryOptions(retries)\n return {\n __proto__: null,\n concurrency: normalizedConcurrency,\n retries: normalizeRetryOptions({ signal, ...retryOpts }),\n signal,\n } as { concurrency: number; retries: RetryOptions; signal: AbortSignal }\n}\n\n/**\n * Normalize options for retry functionality.\n *\n * Converts various retry option formats into a complete configuration with all defaults.\n * Handles legacy property names (`factor`, `minTimeout`, `maxTimeout`) and merges them\n * with modern equivalents.\n *\n * @param options - Retry count as number, or full options object, or undefined\n * @returns Normalized retry options with all properties set\n *\n * @example\n * // Number shorthand\n * normalizeRetryOptions(3)\n * // => { retries: 3, baseDelayMs: 200, backoffFactor: 2, ... }\n *\n * @example\n * // Full options with defaults filled in\n * normalizeRetryOptions({ retries: 5, baseDelayMs: 500 })\n * // => { retries: 5, baseDelayMs: 500, backoffFactor: 2, jitter: true, ... }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeRetryOptions(\n options?: number | RetryOptions | undefined,\n): RetryOptions {\n const resolved = resolveRetryOptions(options)\n const {\n // Arguments to pass to the callback function.\n args = [],\n // Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n backoffFactor = 2,\n // Initial delay before the first retry (in milliseconds).\n baseDelayMs = 200,\n // Whether to apply randomness to spread out retries.\n jitter = true,\n // Upper limit for any backoff delay (in milliseconds).\n maxDelayMs = 10_000,\n // Optional callback invoked on each retry attempt:\n // (attempt: number, error: unknown, delay: number) => void\n onRetry,\n // Whether onRetry can cancel retries by returning `false`.\n onRetryCancelOnFalse = false,\n // Whether onRetry will rethrow errors.\n onRetryRethrow = false,\n // Number of retry attempts (0 = no retries, only initial attempt).\n retries = 0,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = resolved\n return {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } as RetryOptions\n}\n\n/**\n * Resolve retry options from various input formats.\n *\n * Converts shorthand and partial options into a base configuration that can be\n * further normalized. This is an internal helper for option processing.\n *\n * @param options - Retry count as number, or partial options object, or undefined\n * @returns Resolved retry options with defaults for basic properties\n *\n * @example\n * resolveRetryOptions(3)\n * // => { retries: 3, minTimeout: 200, maxTimeout: 10000, factor: 2 }\n *\n * @example\n * resolveRetryOptions({ retries: 5, maxTimeout: 5000 })\n * // => { retries: 5, minTimeout: 200, maxTimeout: 5000, factor: 2 }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRetryOptions(\n options?: number | RetryOptions | undefined,\n): RetryOptions {\n const defaults = {\n __proto__: null,\n retries: 0,\n baseDelayMs: 200,\n maxDelayMs: 10_000,\n backoffFactor: 2,\n }\n\n if (typeof options === 'number') {\n return { ...defaults, retries: options }\n }\n\n return options ? { ...defaults, ...options } : defaults\n}\n\n/**\n * Execute an async function for each array element with concurrency control.\n *\n * Processes array items in parallel batches (chunks) with configurable concurrency.\n * Each item's callback can be retried independently on failure. Similar to\n * `Promise.all(array.map(fn))` but with controlled parallelism.\n *\n * @template T - The type of array elements\n * @param array - The array to iterate over\n * @param callbackFn - Async function to execute for each item\n * @param options - Concurrency as number, or full iteration options, or undefined\n * @returns Promise that resolves when all items are processed\n *\n * @example\n * // Process items serially (concurrency: 1)\n * await pEach(urls, async (url) => {\n * await fetch(url)\n * })\n *\n * @example\n * // Process 5 items at a time\n * await pEach(files, async (file) => {\n * await processFile(file)\n * }, 5)\n *\n * @example\n * // With retries and cancellation\n * const controller = new AbortController()\n * await pEach(tasks, async (task) => {\n * await executeTask(task)\n * }, {\n * concurrency: 3,\n * retries: 2,\n * signal: controller.signal\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEach<T>(\n array: T[],\n callbackFn: (item: T) => Promise<unknown>,\n options?: number | IterationOptions | undefined,\n): Promise<void> {\n const iterOpts = normalizeIterationOptions(options)\n const { concurrency, retries, signal } = iterOpts\n\n // Process items with concurrency control.\n const chunks = arrayChunk(array, concurrency)\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // Process each item in the chunk concurrently.\n // eslint-disable-next-line no-await-in-loop\n await Promise.allSettled(\n chunk.map((item: T) =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retries,\n args: [item],\n signal,\n }),\n ),\n )\n }\n}\n\n/**\n * Filter an array asynchronously with concurrency control.\n *\n * Tests each element with an async predicate function, processing items in parallel\n * batches. Returns a new array with only items that pass the test. Similar to\n * `array.filter()` but for async predicates with controlled concurrency.\n *\n * @template T - The type of array elements\n * @param array - The array to filter\n * @param callbackFn - Async predicate function returning true to keep item\n * @param options - Concurrency as number, or full iteration options, or undefined\n * @returns Promise resolving to filtered array\n *\n * @example\n * // Filter serially\n * const activeUsers = await pFilter(users, async (user) => {\n * return await isUserActive(user.id)\n * })\n *\n * @example\n * // Filter with concurrency\n * const validFiles = await pFilter(filePaths, async (path) => {\n * try {\n * await fs.access(path)\n * return true\n * } catch {\n * return false\n * }\n * }, 10)\n *\n * @example\n * // With retries for flaky checks\n * const reachable = await pFilter(endpoints, async (url) => {\n * const response = await fetch(url)\n * return response.ok\n * }, {\n * concurrency: 5,\n * retries: 2\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilter<T>(\n array: T[],\n callbackFn: (item: T) => Promise<boolean>,\n options?: number | IterationOptions | undefined,\n): Promise<T[]> {\n const iterOpts = normalizeIterationOptions(options)\n return (\n await pFilterChunk(\n arrayChunk(array, iterOpts.concurrency),\n callbackFn,\n iterOpts.retries,\n )\n ).flat()\n}\n\n/**\n * Process array in chunks with an async callback.\n *\n * Divides the array into fixed-size chunks and processes each chunk sequentially\n * with the callback. Useful for batch operations like bulk database inserts or\n * API calls with payload size limits.\n *\n * @template T - The type of array elements\n * @param array - The array to process in chunks\n * @param callbackFn - Async function to execute for each chunk\n * @param options - Chunk size and retry options\n * @returns Promise that resolves when all chunks are processed\n *\n * @example\n * // Insert records in batches of 100\n * await pEachChunk(records, async (chunk) => {\n * await db.batchInsert(chunk)\n * }, { chunkSize: 100 })\n *\n * @example\n * // Upload files in batches with retries\n * await pEachChunk(files, async (batch) => {\n * await uploadBatch(batch)\n * }, {\n * chunkSize: 50,\n * retries: 3,\n * baseDelayMs: 1000\n * })\n *\n * @example\n * // Process with cancellation support\n * const controller = new AbortController()\n * await pEachChunk(items, async (chunk) => {\n * await processChunk(chunk)\n * }, {\n * chunkSize: 25,\n * signal: controller.signal\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEachChunk<T>(\n array: T[],\n callbackFn: (chunk: T[]) => Promise<unknown>,\n options?: (RetryOptions & { chunkSize?: number | undefined }) | undefined,\n): Promise<void> {\n const { chunkSize = 100, ...retryOpts } = options || {}\n const chunks = arrayChunk(array, chunkSize)\n const normalizedRetryOpts = normalizeRetryOptions(retryOpts)\n const { signal } = normalizedRetryOpts\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n await pRetry((...args: unknown[]) => callbackFn(args[0] as T[]), {\n ...normalizedRetryOpts,\n args: [chunk],\n })\n }\n}\n\n/**\n * Filter chunked arrays with an async predicate.\n *\n * Internal helper for `pFilter`. Processes pre-chunked arrays, applying the\n * predicate to each element within each chunk with retry support.\n *\n * @template T - The type of array elements\n * @param chunks - Pre-chunked array (array of arrays)\n * @param callbackFn - Async predicate function\n * @param options - Retry count as number, or full retry options, or undefined\n * @returns Promise resolving to array of filtered chunks\n *\n * @example\n * const chunks = [[1, 2], [3, 4], [5, 6]]\n * const filtered = await pFilterChunk(chunks, async (n) => n % 2 === 0)\n * // => [[2], [4], [6]]\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilterChunk<T>(\n chunks: T[][],\n callbackFn: (value: T) => Promise<boolean>,\n options?: number | RetryOptions | undefined,\n): Promise<T[][]> {\n const retryOpts = normalizeRetryOptions(options)\n const { signal } = retryOpts\n const { length } = chunks\n const filteredChunks = Array(length)\n for (let i = 0; i < length; i += 1) {\n // Process each chunk, filtering based on the callback function.\n if (signal?.aborted) {\n filteredChunks[i] = []\n } else {\n const chunk = chunks[i] as T[]\n // eslint-disable-next-line no-await-in-loop\n const settled = await Promise.allSettled(\n chunk.map(value =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retryOpts,\n args: [value],\n }),\n ),\n )\n const predicateResults = settled.map(r =>\n r.status === 'fulfilled' ? r.value : false,\n )\n filteredChunks[i] = chunk.filter((_v, i) => predicateResults[i])\n }\n }\n return filteredChunks\n}\n\n/**\n * Retry an async function with exponential backoff.\n *\n * Attempts to execute a function multiple times with increasing delays between attempts.\n * Implements exponential backoff with optional jitter to prevent thundering herd problems.\n * Supports custom retry logic via `onRetry` callback.\n *\n * The delay calculation follows: `min(baseDelayMs * (backoffFactor ** attempt), maxDelayMs)`\n * With jitter: adds random value between 0 and calculated delay.\n *\n * @template T - The return type of the callback function\n * @param callbackFn - Async function to retry\n * @param options - Retry count as number, or full retry options, or undefined\n * @returns Promise resolving to callback result, or `undefined` if aborted\n *\n * @throws {Error} The last error if all retry attempts fail\n *\n * @example\n * // Simple retry: 3 attempts with default backoff\n * const data = await pRetry(async () => {\n * return await fetchData()\n * }, 3)\n *\n * @example\n * // Custom backoff strategy\n * const result = await pRetry(async () => {\n * return await unreliableOperation()\n * }, {\n * retries: 5,\n * baseDelayMs: 1000, // Start at 1 second\n * backoffFactor: 2, // Double each time\n * maxDelayMs: 30000, // Cap at 30 seconds\n * jitter: true // Add randomness\n * })\n * // Delays: ~1s, ~2s, ~4s, ~8s, ~16s (each \u00B1 random jitter)\n *\n * @example\n * // With custom retry logic\n * const data = await pRetry(async () => {\n * return await apiCall()\n * }, {\n * retries: 3,\n * onRetry: (attempt, error, delay) => {\n * console.log(`Attempt ${attempt} failed: ${error}`)\n * console.log(`Waiting ${delay}ms before retry...`)\n *\n * // Cancel retries for client errors (4xx)\n * if (error.statusCode >= 400 && error.statusCode < 500) {\n * return false\n * }\n *\n * // Use longer delay for rate limit errors\n * if (error.statusCode === 429) {\n * return 60000 // Wait 1 minute\n * }\n * },\n * onRetryCancelOnFalse: true\n * })\n *\n * @example\n * // With cancellation support\n * const controller = new AbortController()\n * setTimeout(() => controller.abort(), 5000) // Cancel after 5s\n *\n * const result = await pRetry(async ({ signal }) => {\n * return await longRunningTask(signal)\n * }, {\n * retries: 10,\n * signal: controller.signal\n * })\n * // Returns undefined if aborted\n *\n * @example\n * // Pass arguments to callback\n * const result = await pRetry(\n * async (url, options) => {\n * return await fetch(url, options)\n * },\n * {\n * retries: 3,\n * args: ['https://api.example.com', { method: 'POST' }]\n * }\n * )\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pRetry<T>(\n callbackFn: (...args: unknown[]) => Promise<T>,\n options?: number | RetryOptions | undefined,\n): Promise<T | undefined> {\n const {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } = normalizeRetryOptions(options)\n if (signal?.aborted) {\n return undefined\n }\n if (retries === 0) {\n return await callbackFn(...(args || []), { signal })\n }\n\n const timers = getTimers()\n\n let attempts = retries as number\n let delay = baseDelayMs as number\n let error: unknown = UNDEFINED_TOKEN\n\n while (attempts-- >= 0) {\n // Check abort before attempt.\n if (signal?.aborted) {\n return undefined\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n return await callbackFn(...(args || []), { signal })\n } catch (e) {\n if (error === UNDEFINED_TOKEN) {\n error = e\n }\n if (attempts < 0) {\n break\n }\n let waitTime = delay\n if (jitter) {\n // Add randomness: Pick a value between 0 and `delay`.\n waitTime += Math.floor(Math.random() * delay)\n }\n // Clamp wait time to max delay.\n waitTime = Math.min(waitTime, maxDelayMs as number)\n if (typeof onRetry === 'function') {\n try {\n const result = onRetry((retries as number) - attempts, e, waitTime)\n if (result === false && onRetryCancelOnFalse) {\n break\n }\n // If onRetry returns a number, use it as the custom delay.\n if (typeof result === 'number' && result >= 0) {\n waitTime = Math.min(result, maxDelayMs as number)\n }\n } catch (e) {\n if (onRetryRethrow) {\n throw e\n }\n }\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n await timers.setTimeout(waitTime, undefined, { signal })\n } catch {\n // setTimeout was aborted.\n return undefined\n }\n\n // Check abort again after delay.\n if (signal?.aborted) {\n return undefined\n }\n\n // Exponentially increase the delay for the next attempt, capping at maxDelayMs.\n delay = Math.min(delay * (backoffFactor as number), maxDelayMs as number)\n }\n }\n if (error !== UNDEFINED_TOKEN) {\n throw error\n }\n return undefined\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["i", "e"]
|
|
7
|
-
}
|
package/dist/regexps.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/regexps.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Regular expression utilities including escape-string-regexp implementation.\n * Provides regex escaping and pattern matching helpers.\n */\n\n// Inlined escape-string-regexp:\n// https://socket.dev/npm/package/escape-string-regexp/overview/5.0.0\n// MIT License\n// Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n\n/**\n * Escape special characters in a string for use in a regular expression.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function escapeRegExp(str: string): string {\n // Escape characters with special meaning either inside or outside character sets.\n // Use a simple backslash escape when it's always valid, and a `\\xnn` escape when\n // the simpler form would be disallowed by Unicode patterns' stricter grammar.\n return str.replace(/[\\\\|{}()[\\]^$+*?.]/g, '\\\\$&')\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,SAAS,aAAa,KAAqB;AAIhD,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/sea.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/sea.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview SEA (Single Executable Application) detection utilities for Socket ecosystem.\n * Provides reliable detection of whether the current process is running\n * as a Node.js Single Executable Application.\n */\n\nimport { normalizePath } from './path'\n\n/**\n * Cached SEA detection result.\n */\nlet _isSea: boolean | undefined\n\n/**\n * Get the current SEA binary path.\n * Only valid when running as a SEA binary.\n */\nexport function getSeaBinaryPath(): string | undefined {\n return isSeaBinary() && process.argv[0]\n ? normalizePath(process.argv[0])\n : undefined\n}\n\n/**\n * Detect if the current process is running as a SEA binary.\n * Uses Node.js 24+ native API with caching for performance.\n */\nexport function isSeaBinary(): boolean {\n if (_isSea === undefined) {\n try {\n // Use Node.js 24+ native SEA detection API.\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const seaModule = require('node:sea')\n _isSea = seaModule.isSea()\n } catch {\n // Node.js < 24 or SEA module not available.\n _isSea = false\n }\n }\n return _isSea ?? false\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,kBAA8B;AAK9B,IAAI;AAMG,SAAS,mBAAuC;AACrD,SAAO,YAAY,KAAK,QAAQ,KAAK,CAAC,QAClC,2BAAc,QAAQ,KAAK,CAAC,CAAC,IAC7B;AACN;AAMO,SAAS,cAAuB;AACrC,MAAI,WAAW,QAAW;AACxB,QAAI;AAGF,YAAM,YAAY,QAAQ,UAAU;AACpC,eAAS,UAAU,MAAM;AAAA,IAC3B,QAAQ;AAEN,eAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO,UAAU;AACnB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/shadow.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/shadow.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Shadow binary installation utilities for Socket ecosystem.\n * Provides logic to determine when shadow binary installation should be skipped.\n */\n\nimport { normalizePath } from './path'\n\nexport interface ShadowInstallationOptions {\n cwd?: string | undefined\n win32?: boolean | undefined\n}\n\n/**\n * Determines if shadow binaries should be installed.\n * Shadows should NOT be installed when:\n * - Running in a temporary execution context (exec/npx/dlx)\n * - On Windows with an existing binary path (required for Windows to function)\n *\n * @param binPath - Path to the binary being shadowed\n * @param options - Configuration options\n * @param options.cwd - Current working directory path to check\n * @param options.win32 - Whether running on Windows\n * @returns true if shadow installation should be skipped\n */\nexport function shouldSkipShadow(\n binPath: string,\n options?: ShadowInstallationOptions | undefined,\n): boolean {\n const { cwd = process.cwd(), win32 = false } = {\n __proto__: null,\n ...options,\n } as ShadowInstallationOptions\n\n // Windows compatibility: Skip shadow installation if binary is already found.\n //\n // This check is required because Windows handles executables differently than Unix:\n // 1. File locking - Windows locks running executables, so cmd-shim creation would\n // fail with EBUSY/EACCES errors when trying to create wrapper files.\n // 2. PATH conflicts - Attempting to shadow an already-resolved binary can create\n // circular references or ambiguous command resolution.\n // 3. Registry integration - Windows package managers often use system-level\n // integrations beyond just PATH that our shadowing would interfere with.\n //\n // Without this check, users would see \"Access Denied\" or file locking errors\n // that are difficult to debug. This is not a performance optimization - the\n // shadow installation will fail without it.\n if (win32 && binPath) {\n return true\n }\n\n // Check environment variable for exec/npx/dlx indicators.\n const userAgent = process.env['npm_config_user_agent']\n if (\n userAgent?.includes('exec') ||\n userAgent?.includes('npx') ||\n userAgent?.includes('dlx')\n ) {\n return true\n }\n\n // Normalize the cwd path for consistent checking across platforms.\n const normalizedCwd = normalizePath(cwd)\n\n // Check if running from npm's npx cache.\n const npmCache = process.env['npm_config_cache']\n if (npmCache && normalizedCwd.includes(normalizePath(npmCache))) {\n return true\n }\n\n // Check common temporary execution path patterns.\n const tempPatterns = [\n // npm's npx cache directory\n '_npx',\n // pnpm dlx temporary store\n '.pnpm-store',\n // Common dlx directory prefix\n 'dlx-',\n // Yarn Berry PnP virtual packages.\n '.yarn/$$',\n // Yarn on Windows uses normalized forward slash paths.\n 'AppData/Local/Temp/xfs-',\n ]\n\n return tempPatterns.some(pattern => normalizedCwd.includes(pattern))\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,kBAA8B;AAmBvB,SAAS,iBACd,SACA,SACS;AACT,QAAM,EAAE,MAAM,QAAQ,IAAI,GAAG,QAAQ,MAAM,IAAI;AAAA,IAC7C,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AAeA,MAAI,SAAS,SAAS;AACpB,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,QAAQ,IAAI,uBAAuB;AACrD,MACE,WAAW,SAAS,MAAM,KAC1B,WAAW,SAAS,KAAK,KACzB,WAAW,SAAS,KAAK,GACzB;AACA,WAAO;AAAA,EACT;AAGA,QAAM,oBAAgB,2BAAc,GAAG;AAGvC,QAAM,WAAW,QAAQ,IAAI,kBAAkB;AAC/C,MAAI,YAAY,cAAc,aAAS,2BAAc,QAAQ,CAAC,GAAG;AAC/D,WAAO;AAAA,EACT;AAGA,QAAM,eAAe;AAAA;AAAA,IAEnB;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AAEA,SAAO,aAAa,KAAK,aAAW,cAAc,SAAS,OAAO,CAAC;AACrE;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|