{
  "version": 3,
  "sources": ["../../../../src/packages/audit/index.ts"],
  "sourcesContent": ["import assert from 'node:assert';\nimport path from 'node:path';\nimport util from 'node:util';\nimport { PnpmError } from '../error/index.ts';\nimport {\n  type AgentOptions,\n  fetchWithAgent,\n  type RetryTimeoutOptions,\n} from '../fetch/index.ts';\nimport type { GetAuthHeader } from '../fetching-types/index.ts';\nimport type { LockfileObject } from '../lockfile.types/index.ts';\nimport { globalWarn } from '../logger/index.ts';\nimport type { DependenciesField } from '../types/index.ts';\nimport { lockfileToAuditTree } from './lockfileToAuditTree.ts';\nimport type { AuditReport } from './types.ts';\nimport { searchForPackages, flattenSearchedPackages } from '../list/index.ts';\n\nexport * from './types.ts';\n\nexport async function audit(\n  lockfile: LockfileObject,\n  getAuthHeader: GetAuthHeader,\n  opts: {\n    agentOptions?: AgentOptions | undefined;\n    include?: { [dependenciesField in DependenciesField]: boolean } | undefined;\n    lockfileDir: string;\n    registry: string;\n    retry?: RetryTimeoutOptions | undefined;\n    timeout?: number | undefined;\n    virtualStoreDirMaxLength: number;\n  }\n): Promise<AuditReport> {\n  const auditTree = await lockfileToAuditTree(lockfile, {\n    include: opts.include,\n    lockfileDir: opts.lockfileDir,\n  });\n\n  const registry = opts.registry.endsWith('/')\n    ? opts.registry\n    : `${opts.registry}/`;\n\n  const auditUrl = `${registry}-/npm/v1/security/audits`;\n\n  const authHeaderValue = getAuthHeader(registry);\n\n  const authHeaders = getAuthHeaders(authHeaderValue);\n\n  const headers: Record<string, string> = {\n    'Content-Type': 'application/json',\n  };\n\n  if (typeof authHeaders.authorization !== 'undefined') {\n    headers.authorization = authHeaders.authorization;\n  }\n\n  const res = await fetchWithAgent(auditUrl, {\n    agentOptions: opts.agentOptions ?? {},\n    body: JSON.stringify(auditTree),\n    headers,\n    method: 'post',\n    retry: opts.retry,\n    timeout: opts.timeout,\n  });\n\n  if (res.status === 404) {\n    throw new AuditEndpointNotExistsError(auditUrl);\n  }\n\n  if (res.status !== 200) {\n    throw new PnpmError(\n      'AUDIT_BAD_RESPONSE',\n      `The audit endpoint (at ${auditUrl}) responded with ${res.status}: ${await res.text()}`\n    );\n  }\n\n  // TODO: valibot schema\n  const auditReport: AuditReport = (await res.json()) as AuditReport;\n\n  try {\n    return await extendWithDependencyPaths(auditReport, {\n      lockfile,\n      lockfileDir: opts.lockfileDir,\n      include: opts.include,\n      virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,\n    });\n  } catch (err: unknown) {\n    assert(util.types.isNativeError(err));\n\n    globalWarn(\n      `Failed to extend audit report with dependency paths: ${err.message}`\n    );\n\n    return auditReport;\n  }\n}\n\ntype AuthHeaders = {\n  authorization?: string | undefined;\n};\n\nfunction getAuthHeaders(authHeaderValue: string | undefined): AuthHeaders {\n  const headers: AuthHeaders = {};\n\n  if (typeof authHeaderValue === 'string') {\n    headers.authorization = authHeaderValue;\n  }\n\n  return headers;\n}\n\nasync function extendWithDependencyPaths(\n  auditReport: AuditReport,\n  opts: {\n    lockfile: LockfileObject;\n    lockfileDir: string;\n    include?: { [dependenciesField in DependenciesField]: boolean } | undefined;\n    virtualStoreDirMaxLength: number;\n  }\n): Promise<AuditReport> {\n  const { advisories } = auditReport;\n\n  if (!Object.keys(advisories).length) {\n    return auditReport;\n  }\n\n  const projectDirs = Object.keys(opts.lockfile.importers ?? {}).map(\n    (importerId) => {\n      return path.join(opts.lockfileDir, importerId);\n    }\n  );\n\n  const searchOpts = {\n    lockfileDir: opts.lockfileDir,\n    depth: Number.POSITIVE_INFINITY,\n    include: opts.include,\n    virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,\n  };\n\n  const _searchPackagePaths = searchPackagePaths.bind(\n    null,\n    searchOpts,\n    projectDirs\n  );\n\n  await Promise.all(\n    Object.values(advisories).map(async ({ findings, module_name }) => {\n      await Promise.all(\n        findings.map(async (finding) => {\n          finding.paths = await _searchPackagePaths(\n            `${module_name}@${finding.version}`\n          );\n        })\n      );\n    })\n  );\n\n  return auditReport;\n}\n\nasync function searchPackagePaths(\n  searchOpts: {\n    lockfileDir: string;\n    depth: number;\n    include?: { [dependenciesField in DependenciesField]: boolean } | undefined;\n    virtualStoreDirMaxLength: number;\n  },\n  projectDirs: string[],\n  pkg: string\n): Promise<string[]> {\n  const pkgs = await searchForPackages([pkg], projectDirs, searchOpts);\n\n  return flattenSearchedPackages(pkgs, {\n    lockfileDir: searchOpts.lockfileDir,\n  }).map(({ depPath }) => depPath);\n}\n\nexport class AuditEndpointNotExistsError extends PnpmError {\n  constructor(endpoint: string) {\n    const message = `The audit endpoint (at ${endpoint}) is doesn't exist.`;\n\n    super('AUDIT_ENDPOINT_NOT_EXISTS', message, {\n      hint: \"This issue is probably because you are using a private npm registry and that endpoint doesn't have an implementation of audit.\",\n    });\n  }\n}\n"],
  "mappings": "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",
  "names": []
}
