@socketsecurity/lib
Version:
Core utilities and infrastructure for Socket.dev security tools
205 lines (204 loc) • 6.91 kB
JavaScript
;
/* Socket Lib - Built with esbuild */
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var github_exports = {};
__export(github_exports, {
cacheFetchGhsa: () => cacheFetchGhsa,
clearRefCache: () => clearRefCache,
fetchGhsaDetails: () => fetchGhsaDetails,
fetchGitHub: () => fetchGitHub,
getGhsaUrl: () => getGhsaUrl,
getGitHubToken: () => getGitHubToken,
getGitHubTokenFromGitConfig: () => getGitHubTokenFromGitConfig,
getGitHubTokenWithFallback: () => getGitHubTokenWithFallback,
resolveRefToSha: () => resolveRefToSha
});
module.exports = __toCommonJS(github_exports);
var import_cache_with_ttl = require("./cache-with-ttl");
var import_github = require("#env/github");
var import_socket_cli = require("#env/socket-cli");
var import_http_request = require("./http-request");
var import_spawn = require("./spawn");
const GITHUB_API_BASE_URL = "https://api.github.com";
const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
let _githubCache;
function getGithubCache() {
if (_githubCache === void 0) {
_githubCache = (0, import_cache_with_ttl.createTtlCache)({
memoize: true,
prefix: "github-refs",
ttl: DEFAULT_CACHE_TTL_MS
});
}
return _githubCache;
}
function getGitHubToken() {
return (0, import_github.getGithubToken)() || (0, import_github.getGhToken)() || (0, import_socket_cli.getSocketCliGithubToken)() || void 0;
}
async function fetchGitHub(url, options) {
const opts = { __proto__: null, ...options };
const token = opts.token || getGitHubToken();
const headers = {
Accept: "application/vnd.github.v3+json",
"User-Agent": "socket-registry-github-client",
...opts.headers
};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
const response = await (0, import_http_request.httpRequest)(url, { headers });
if (!response.ok) {
if (response.status === 403) {
const rateLimit = response.headers["x-ratelimit-remaining"];
const rateLimitStr = typeof rateLimit === "string" ? rateLimit : rateLimit?.[0];
if (rateLimitStr === "0") {
const resetTime = response.headers["x-ratelimit-reset"];
const resetTimeStr = typeof resetTime === "string" ? resetTime : resetTime?.[0];
const resetDate = resetTimeStr ? new Date(Number(resetTimeStr) * 1e3) : void 0;
const error = new Error(
`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 Error(
`GitHub API error ${response.status}: ${response.statusText}`
);
}
return JSON.parse(response.body.toString("utf8"));
}
async function resolveRefToSha(owner, repo, ref, options) {
const opts = {
__proto__: null,
...options
};
const cacheKey = `${owner}/${repo}@${ref}`;
if (process.env["DISABLE_GITHUB_CACHE"]) {
return await fetchRefSha(owner, repo, ref, opts);
}
const cache = getGithubCache();
return await cache.getOrFetch(cacheKey, async () => {
return await fetchRefSha(owner, repo, ref, opts);
});
}
async function fetchRefSha(owner, repo, ref, options) {
const fetchOptions = {
token: options.token
};
try {
const tagUrl = `${GITHUB_API_BASE_URL}/repos/${owner}/${repo}/git/refs/tags/${ref}`;
const tagData = await fetchGitHub(tagUrl, fetchOptions);
if (tagData.object.type === "tag") {
const tagObject = await fetchGitHub(
tagData.object.url,
fetchOptions
);
return tagObject.object.sha;
}
return tagData.object.sha;
} catch {
try {
const branchUrl = `${GITHUB_API_BASE_URL}/repos/${owner}/${repo}/git/refs/heads/${ref}`;
const branchData = await fetchGitHub(branchUrl, fetchOptions);
return branchData.object.sha;
} catch {
try {
const commitUrl = `${GITHUB_API_BASE_URL}/repos/${owner}/${repo}/commits/${ref}`;
const commitData = await fetchGitHub(
commitUrl,
fetchOptions
);
return commitData.sha;
} catch (e) {
throw new Error(
`failed to resolve ref "${ref}" for ${owner}/${repo}: ${e instanceof Error ? e.message : String(e)}`
);
}
}
}
}
async function clearRefCache() {
if (_githubCache) {
await _githubCache.clear({ memoOnly: true });
}
}
async function getGitHubTokenFromGitConfig(options) {
try {
const result = await (0, import_spawn.spawn)("git", ["config", "github.token"], {
...options,
stdio: "pipe"
});
if (result.code === 0 && result.stdout) {
return result.stdout.toString().trim();
}
} catch {
}
return void 0;
}
async function getGitHubTokenWithFallback() {
return getGitHubToken() || await getGitHubTokenFromGitConfig();
}
function getGhsaUrl(ghsaId) {
return `https://github.com/advisories/${ghsaId}`;
}
async function fetchGhsaDetails(ghsaId, options) {
const url = `https://api.github.com/advisories/${ghsaId}`;
const data = await 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 || []
};
}
async function cacheFetchGhsa(ghsaId, options) {
const cache = getGithubCache();
const key = `ghsa:${ghsaId}`;
if (!process.env["DISABLE_GITHUB_CACHE"]) {
const cached = await cache.get(key);
if (cached) {
return JSON.parse(cached);
}
}
const data = await fetchGhsaDetails(ghsaId, options);
await cache.set(key, JSON.stringify(data));
return data;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
cacheFetchGhsa,
clearRefCache,
fetchGhsaDetails,
fetchGitHub,
getGhsaUrl,
getGitHubToken,
getGitHubTokenFromGitConfig,
getGitHubTokenWithFallback,
resolveRefToSha
});