"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_primordials_error = require('../primordials/error.js');
const require_primordials_json = require('../primordials/json.js');
const require_http_request_request = require('../http-request/request.js');
const require_github_constants = require('./constants.js');
const require_github_errors = require('./errors.js');
const require_github_token = require('./token.js');
const require_github_fetch = require('./fetch.js');
const require_github_refs_cache = require('./refs-cache.js');
let node_process = require("node:process");
node_process = require_runtime.__toESM(node_process);

//#region src/github/ghsa.ts
/**
* @file GitHub Security Advisory (GHSA) lookups. Three layers, narrowest first:
*
*   - `cacheFetchGhsa` — caches GHSA fetches in the same `TtlCache` used by ref
*     resolution (5-minute TTL, two-tier).
*   - `fetchGhsaDetails` — REST `/advisories/:id` with the same empty-body
*     fallback to GraphQL that ref resolution uses.
*   - `fetchGhsaDetailsViaGraphQL` — GraphQL `securityAdvisory(...)` with shape
*     normalization back to the REST surface so callers don't have to know
*     which transport ran.
*/
/**
* Fetch GitHub Security Advisory details with caching. Retrieves advisory
* information with two-tier caching (in-memory + persistent). Cached results
* are stored with the default TTL (5 minutes).
*
* Caching behavior:
*
* - Checks in-memory cache first for immediate response
* - Falls back to persistent disk cache if not in memory
* - Fetches from API only if not cached
* - Stores result in both cache tiers
* - Respects `DISABLE_GITHUB_CACHE` env var
*
* @example
*   ;```ts
*   // First call hits API
*   const advisory = await cacheFetchGhsa('GHSA-1234-5678-90ab')
*
*   // Second call within 5 minutes returns cached data
*   const cached = await cacheFetchGhsa('GHSA-1234-5678-90ab')
*   ```
*
* @example
*   ;```ts
*   // Disable caching for fresh data
*   process.env.DISABLE_GITHUB_CACHE = '1'
*   const advisory = await cacheFetchGhsa('GHSA-xxxx-yyyy-zzzz')
*   ```
*
* @param ghsaId - GHSA identifier to fetch.
* @param options - Fetch options including authentication token.
*
* @returns Complete advisory details
*
* @throws {Error} If advisory cannot be found or API request fails
* @throws {GitHubRateLimitError} When API rate limit is exceeded
*/
async function cacheFetchGhsa(ghsaId, options) {
	const cache = require_github_refs_cache.getGithubCache();
	const key = `ghsa:${ghsaId}`;
	/* c8 ignore next 3 */
	if (node_process.default.env["DISABLE_GITHUB_CACHE"]) return await fetchGhsaDetails(ghsaId, options);
	return await cache.getOrFetch(key, async () => {
		return await fetchGhsaDetails(ghsaId, options);
	});
}
/**
* Fetch GitHub Security Advisory details from the API. Retrieves complete
* advisory information including severity, affected packages, CVSS scores, and
* CWE classifications.
*
* @example
*   ```ts
*   const advisory = await fetchGhsaDetails('GHSA-1234-5678-90ab')
*   console.log(`Severity: ${advisory.severity}`)
*   console.log(`Affects: ${advisory.vulnerabilities.length} packages`)
*   if (advisory.cvss) {
*   console.log(`CVSS Score: ${advisory.cvss.score}`)
*   }
*   ```
*
* @example
*   ```ts
*   // Check if vulnerability is patched
*   const advisory = await fetchGhsaDetails('GHSA-xxxx-yyyy-zzzz')
*   for (const vuln of advisory.vulnerabilities) {
*   if (vuln.firstPatchedVersion) {
*   console.log(
*   `Patched in ${vuln.package.name}@${vuln.firstPatchedVersion.identifier}`,
*   )
*   }
*   }
*   ```
*
* @param ghsaId - GHSA identifier to fetch (e.g., 'GHSA-xxxx-yyyy-zzzz')
* @param options - Fetch options including authentication token.
*
* @returns Complete advisory details with normalized field names
*
* @throws {Error} If advisory cannot be found or API request fails
* @throws {GitHubRateLimitError} When API rate limit is exceeded
*/
async function fetchGhsaDetails(ghsaId, options) {
	/* c8 ignore start - External GitHub API call */
	const url = `https://api.github.com/advisories/${ghsaId}`;
	try {
		const data = await require_github_fetch.fetchGitHub(url, options);
		return {
			ghsaId: data.ghsa_id,
			summary: data.summary,
			details: data.details,
			severity: data.severity,
			aliases: data.aliases || [],
			publishedAt: data.published_at,
			updatedAt: data.updated_at,
			withdrawnAt: data.withdrawn_at,
			references: data.references || [],
			vulnerabilities: data.vulnerabilities || [],
			cvss: data.cvss,
			cwes: data.cwes || []
		};
	} catch (e) {
		if (e instanceof require_github_errors.GitHubEmptyBodyError) try {
			return await fetchGhsaDetailsViaGraphQL(ghsaId, options);
		} catch (cause) {
			throw new require_primordials_error.ErrorCtor(`Failed to fetch advisory ${ghsaId}: both REST and GraphQL backends degraded`, { cause });
		}
		throw e;
	}
	/* c8 ignore stop */
}
/**
* GraphQL counterpart for `fetchGhsaDetails`.
*
* What it does: Queries the GraphQL `securityAdvisory(ghsaId)` connection and
* reshapes the response to match the REST `/advisories/:id` JSON so callers
* don't have to know which transport ran.
*
* Three normalizations the REST shape differs from GraphQL on:
*
* 1. Severity case REST returns lowercase strings like "moderate", "high". GraphQL
*    returns SCREAMING_CASE enum values: "MODERATE", "HIGH", "CRITICAL". We
*    `.toLowerCase()` so callers can compare against a single canonical form.
* 2. Identifiers vs. aliases REST has an `aliases: ["CVE-2024-..."]` array — a
*    flat list of non-GHSA IDs (CVEs, etc.) for the same vulnerability. GraphQL
*    has `identifiers: [{type, value}]` which INCLUDES the advisory's own GHSA
*    id alongside CVE ids. We filter out the GHSA self-reference so the list
*    matches REST.
* 3. Connection wrapping GraphQL wraps array fields in `{ nodes: [...] }`
*    connection objects (it's how pagination works in GraphQL). REST returns
*    plain arrays. We unwrap with `?.nodes ?? []`.
*
* `description` (GraphQL) maps to `details` (REST) — same data, different field
* name. The mapping below renames it.
*
* Token handling: We re-derive the token from `options.token ||
* getGitHubToken()` because this function may be called from places that didn't
* thread an explicit token through. GraphQL queries to private data require
* auth even when the equivalent REST GET works anonymously, so the auth header
* is mandatory in practice.
*/
async function fetchGhsaDetailsViaGraphQL(ghsaId, options) {
	const opts = {
		__proto__: null,
		...options
	};
	const token = opts.token || require_github_token.getGitHubToken();
	const headers = {
		Accept: "application/vnd.github.v3+json",
		"Content-Type": "application/json",
		"User-Agent": "socket-registry-github-client",
		...opts.headers
	};
	if (token) headers["Authorization"] = `Bearer ${token}`;
	const response = await require_http_request_request.httpRequest(require_github_constants.GITHUB_GRAPHQL_URL, {
		body: require_primordials_json.JSONStringify({
			query: `query($ghsaId: String!) {
    securityAdvisory(ghsaId: $ghsaId) {
      ghsaId
      summary
      description
      severity
      publishedAt
      updatedAt
      withdrawnAt
      cvss { score vectorString }
      cwes(first: 50) { nodes { cweId name description } }
      references { url }
      vulnerabilities(first: 100) {
        nodes {
          package { ecosystem name }
          vulnerableVersionRange
          firstPatchedVersion { identifier }
        }
      }
      identifiers { type value }
    }
  }`,
			variables: { ghsaId }
		}),
		headers,
		method: "POST"
	});
	if (!response.ok) throw new require_primordials_error.ErrorCtor(`GitHub GraphQL API error ${response.status}: ${response.statusText}`);
	if (response.body.byteLength === 0) throw new require_github_errors.GitHubEmptyBodyError(require_github_constants.GITHUB_GRAPHQL_URL);
	let parsed;
	try {
		parsed = require_primordials_json.JSONParse(response.body.toString("utf8"));
	} catch (cause) {
		throw new require_primordials_error.ErrorCtor(`Failed to parse GitHub GraphQL response for advisory ${ghsaId}`, { cause });
	}
	if (parsed.errors?.length) throw new require_primordials_error.ErrorCtor(`GraphQL securityAdvisory(${ghsaId}) returned errors: ${parsed.errors.map((e) => e.message).join("; ")}`);
	const adv = parsed.data?.securityAdvisory;
	/* c8 ignore next 3 */
	if (!adv) throw new require_primordials_error.ErrorCtor(`GHSA ${ghsaId} not found`);
	/* c8 ignore start */
	return {
		ghsaId: adv.ghsaId,
		summary: adv.summary,
		details: adv.description,
		severity: adv.severity.toLowerCase(),
		aliases: adv.identifiers?.filter((i) => i.type !== "GHSA").map((i) => i.value) ?? [],
		publishedAt: adv.publishedAt,
		updatedAt: adv.updatedAt,
		withdrawnAt: adv.withdrawnAt ?? "",
		references: adv.references ?? [],
		vulnerabilities: adv.vulnerabilities?.nodes ?? [],
		cvss: adv.cvss ?? null,
		cwes: adv.cwes?.nodes ?? []
	};
	/* c8 ignore stop */
}

//#endregion
exports.cacheFetchGhsa = cacheFetchGhsa;
exports.fetchGhsaDetails = fetchGhsaDetails;
exports.fetchGhsaDetailsViaGraphQL = fetchGhsaDetailsViaGraphQL;