{
  "version": 3,
  "sources": ["../../../../src/packages/git-resolver/index.ts"],
  "sourcesContent": ["import type {\n  TarballResolution,\n  GitResolution,\n  ResolveResult,\n  WorkspaceResolveResult,\n} from '../resolver-base/index.ts';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport git from 'graceful-git';\nimport semver from 'semver';\nimport { parsePref, type HostedPackageSpec } from './parsePref.ts';\nimport { createGitHostedPkgId } from './createGitHostedPkgId.ts';\nimport type { AgentOptions } from '../network.agent/index.ts';\nimport type { PkgResolutionId } from '../types/index.ts';\n\nexport { createGitHostedPkgId };\n\nexport type { HostedPackageSpec };\n\nexport type GitResolver = (wantedDependency: {\n  pref: string;\n}) => Promise<ResolveResult | WorkspaceResolveResult | null>;\n\nexport function createGitResolver(opts: AgentOptions): GitResolver {\n  return async function resolveGit(\n    wantedDependency\n  ): Promise<ResolveResult | WorkspaceResolveResult | null> {\n    const parsedSpec = await parsePref(wantedDependency.pref, opts);\n\n    if (parsedSpec == null) return null;\n\n    const pref =\n      parsedSpec.gitCommittish == null || parsedSpec.gitCommittish === ''\n        ? 'HEAD'\n        : parsedSpec.gitCommittish;\n    const commit = await resolveRef(\n      parsedSpec.fetchSpec,\n      pref,\n      parsedSpec.gitRange\n    );\n\n    let resolution: TarballResolution | GitResolution | undefined;\n\n    if (parsedSpec.hosted != null && !isSsh(parsedSpec.fetchSpec)) {\n      // don't use tarball for ssh url, they are likely private repo\n      const hosted = parsedSpec.hosted;\n\n      // use resolved committish\n      hosted.committish = commit;\n\n      const tarball = hosted.tarball?.();\n\n      if (typeof tarball === 'string') {\n        resolution = { tarball } as TarballResolution;\n      }\n    }\n\n    if (resolution == null) {\n      resolution = {\n        commit,\n        repo: parsedSpec.fetchSpec,\n        type: 'git',\n      } as GitResolution;\n    }\n\n    if (typeof parsedSpec.path === 'string') {\n      resolution.path = parsedSpec.path;\n    }\n\n    let id: PkgResolutionId;\n\n    if ('tarball' in resolution) {\n      id = resolution.tarball as PkgResolutionId;\n\n      if (typeof resolution.path === 'string') {\n        id = `${id}#path:${resolution.path}` as PkgResolutionId;\n      }\n    } else {\n      id = createGitHostedPkgId(resolution);\n    }\n\n    return {\n      id,\n      normalizedPref: parsedSpec.normalizedPref,\n      resolution,\n      resolvedVia: 'git-repository',\n    };\n  };\n}\n\nfunction resolveVTags(vTags: string[], range: string): string | null {\n  return semver.maxSatisfying(vTags, range, true);\n}\n\nasync function getRepoRefs(\n  repo: string,\n  ref: string | null\n): Promise<Record<string, string>> {\n  const gitArgs = [repo];\n\n  if (ref !== 'HEAD') {\n    gitArgs.unshift('--refs');\n  }\n\n  if (typeof ref === 'string') {\n    gitArgs.push(ref);\n  }\n\n  // graceful-git by default retries 10 times, reduce to single retry\n  const result = await git(['ls-remote', ...gitArgs], { retries: 1 });\n\n  const refs: Record<string, string> = {};\n\n  for (const line of result.stdout.split('\\n')) {\n    const [commit, refName] = line.split('\\t');\n    refs[refName] = commit;\n  }\n\n  return refs;\n}\n\nasync function resolveRef(\n  repo: string,\n  ref: string,\n  range?: string | undefined\n): Promise<string> {\n  if (ref.match(/^[\\da-f]{7,40}$/) != null) {\n    return ref;\n  }\n\n  const refs = await getRepoRefs(repo, typeof range === 'string' ? null : ref);\n\n  return resolveRefFromRefs(refs, repo, ref, range);\n}\n\nfunction resolveRefFromRefs(\n  refs: { [ref: string]: string },\n  repo: string,\n  ref: string,\n  range?: string | undefined\n): string {\n  if (typeof range === 'undefined' || range === '') {\n    const commitId =\n      refs[ref] ??\n      refs[`refs/${ref}`] ??\n      refs[`refs/tags/${ref}^{}`] ?? // prefer annotated tags\n      refs[`refs/tags/${ref}`] ??\n      refs[`refs/heads/${ref}`];\n\n    if (typeof commitId !== 'string' || commitId === '') {\n      throw new Error(`Could not resolve ${ref} to a commit of ${repo}.`);\n    }\n\n    return commitId;\n  }\n\n  const vTags = Object.keys(refs)\n    // using the same semantics of version tags as https://github.com/zkat/pacote\n    .filter((key: string) =>\n      /^refs\\/tags\\/v?\\d+\\.\\d+\\.\\d+(?:[+-].+)?(?:\\^{})?$/.test(key)\n    )\n    .map((key: string) => {\n      return key.replace(/^refs\\/tags\\//, '').replace(/\\^{}$/, ''); // accept annotated tags\n    })\n    .filter((key: string) => {\n      return semver.valid(key, true) !== null;\n    });\n\n  const refVTag = resolveVTags(vTags, range);\n  const commitId =\n    refVTag !== null &&\n    (refs[`refs/tags/${refVTag}^{}`] ?? // prefer annotated tags\n      refs[`refs/tags/${refVTag}`]);\n\n  if (typeof commitId !== 'string' || commitId === '') {\n    throw new Error(\n      `Could not resolve ${range} to a commit of ${repo}. Available versions are: ${vTags.join(', ')}`\n    );\n  }\n\n  return commitId;\n}\n\nfunction isSsh(gitSpec: string): boolean {\n  return (\n    gitSpec.slice(0, 10) === 'git+ssh://' || gitSpec.slice(0, 4) === 'git@'\n  );\n}\n"],
  "mappings": "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",
  "names": ["commitId"]
}
