"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_error = require('../primordials/error.js');
const require_primordials_date = require('../primordials/date.js');
const require_primordials_json = require('../primordials/json.js');
const require_errors_message = require('../errors/message.js');
const require_http_request_request = require('../http-request/request.js');
const require_github_errors = require('./errors.js');
const require_github_token = require('./token.js');

//#region src/github/fetch.ts
/**
* @file Authenticated GitHub REST fetch. `fetchGitHub` is the single entry
*   point that the rest of the github/ modules go through for REST calls. It
*   handles four things the callers shouldn't have to repeat:
*
*   1. Token resolution (env → git config) when the caller doesn't pass an
*      explicit token.
*   2. Standard headers (Accept, User-Agent) merged with caller- supplied headers.
*   3. Rate-limit detection — when GitHub returns 403 with `x-ratelimit-remaining:
*      0`, throw a typed `GitHubRateLimitError` so callers can react (set
*      GITHUB_TOKEN, retry after reset).
*   4. Empty-body detection — 200 OK + zero-byte body is the documented incident
*      shape (see GitHubEmptyBodyError JSDoc). Raised as a typed error so the
*      ref / GHSA modules can fall back to GraphQL on a different backend.
*      `getGhsaUrl` lives here because it's the URL counterpart to the GHSA
*      fetch path — the only other consumer is the GHSA module.
*/
/**
* Fetch data from GitHub API with automatic authentication and rate limit
* handling. Makes authenticated requests to the GitHub REST API with proper
* error handling.
*
* Features: - Automatic token injection from environment if not provided - Rate
* limit detection with helpful error messages - Standard GitHub API headers
* (Accept, User-Agent) - JSON response parsing.
*
* @example
*   ```ts
*   // Fetch repository information
*   interface Repo {
*   name: string
*   full_name: string
*   default_branch: string
*   }
*   const repo = await fetchGitHub<Repo>(
*   'https://api.github.com/repos/owner/repo',
*   )
*   console.log(`Default branch: ${repo.default_branch}`)
*   ```
*
* @example
*   ;```ts
*   // With custom token and headers
*   const data = await fetchGitHub('https://api.github.com/user', {
*     token: 'ghp_customtoken',
*     headers: { 'X-Custom-Header': 'value' },
*   })
*   ```
*
* @example
*   ```ts
*   // Handle rate limit errors
*   try {
*   await fetchGitHub('https://api.github.com/repos/owner/repo')
*   } catch (e) {
*   if (e.status === 403 && e.resetTime) {
*   console.error(`Rate limited until ${e.resetTime}`)
*   }
*   }
*   ```
*
* @template T - Expected response type (defaults to `unknown`)
*
* @param url - Full GitHub API URL (e.g.,
*   'https://api.github.com/repos/owner/repo')
* @param options - Fetch options including token and custom headers.
*
* @returns Parsed JSON response of type `T`
*
* @throws {GitHubRateLimitError} When API rate limit is exceeded (status 403)
* @throws {Error} For other API errors with status code and message
*/
async function fetchGitHub(url, options) {
	const opts = {
		__proto__: null,
		...options
	};
	const token = opts.token || require_github_token.getGitHubToken();
	const headers = {
		Accept: "application/vnd.github.v3+json",
		"User-Agent": "socket-registry-github-client",
		...opts.headers
	};
	if (token) headers["Authorization"] = `Bearer ${token}`;
	/* c8 ignore start - External GitHub API call */
	const response = await require_http_request_request.httpRequest(url, { headers });
	/* c8 ignore stop */
	if (!response.ok) {
		if (response.status === 403) {
			const rateLimit = response.headers["x-ratelimit-remaining"];
			if ((typeof rateLimit === "string" ? rateLimit : rateLimit?.[0]) === "0") {
				const resetTime = response.headers["x-ratelimit-reset"];
				const resetTimeStr = typeof resetTime === "string" ? resetTime : resetTime?.[0];
				const resetDate = resetTimeStr ? new require_primordials_date.DateCtor(Number(resetTimeStr) * 1e3) : void 0;
				const error = new require_primordials_error.ErrorCtor(`GitHub API rate limit exceeded${resetDate ? `. Resets at ${resetDate.toLocaleString()}` : ""}. Use GITHUB_TOKEN environment variable to increase rate limit.`);
				error.status = 403;
				error.resetTime = resetDate;
				throw error;
			}
		}
		throw new require_primordials_error.ErrorCtor(`GitHub API error ${response.status}: ${response.statusText}`);
	}
	if (response.body.byteLength === 0) throw new require_github_errors.GitHubEmptyBodyError(url);
	try {
		return require_primordials_json.JSONParse(response.body.toString("utf8"));
	} catch (e) {
		throw new require_primordials_error.ErrorCtor(`Failed to parse GitHub API response: ${require_errors_message.errorMessage(e)}\nURL: ${url}\nResponse may be malformed or incomplete.`, { cause: e });
	}
}
/**
* Generate GitHub Security Advisory URL from GHSA ID. Constructs the public
* advisory URL for a given GHSA identifier.
*
* @example
*   ;```ts
*   const url = getGhsaUrl('GHSA-1234-5678-90ab')
*   console.log(url) // 'https://github.com/advisories/GHSA-1234-5678-90ab'
*   ```
*
* @param ghsaId - GHSA identifier (e.g., 'GHSA-xxxx-yyyy-zzzz')
*
* @returns Full URL to the advisory page
*/
function getGhsaUrl(ghsaId) {
	return `https://github.com/advisories/${ghsaId}`;
}

//#endregion
exports.fetchGitHub = fetchGitHub;
exports.getGhsaUrl = getGhsaUrl;