clone

nostr relays on demand at <name>.bind.ws: claim one with your key, pay in zaps past the free allowance

dependabot/github_actions/actions-9b61906d8b
bindws / src / git-objects.ts
git-objects.ts 2.9K
1// Git object reads share one bounded view. Indexed repositories fetch by ID;2// legacy repositories decode their bounded retained pack set once per view.3import { DEFAULT_GIT_LIMITS, type GitLimits } from "./git-limits.ts";4import { sha1 } from "@noble/hashes/legacy.js";5import { bytesToHex } from "@noble/hashes/utils.js";6import { readObjects, objectLinks, LimitError, IntegrityError, type GitRepository, type GitObject, type GitObjectInfo } from "ntig";78export async function gitObjects(repository: GitRepository) {9 const fallback = repository.getObject && repository.getObjectInfo ? null : await readObjects((await repository.load()).packs);10 return {11 get: async (oid: string): Promise<GitObject | null> => fallback ? fallback.get(oid) ?? null : repository.getObject!(oid),12 info: async (oid: string): Promise<GitObjectInfo | null> => {13 if (!fallback) return repository.getObjectInfo!(oid);14 const object = fallback.get(oid);15 return object ? { oid, type: object.type, size: object.data.length, links: objectLinks(object) } : null;16 },17 };18}1920// gitGraph reads only the requested dependency graph, with the same decoded21// byte budget as a received pack. It also serves local GRASP-06 reconciliation.22export async function gitGraph(repository: GitRepository, roots: readonly string[], limits: Readonly<GitLimits> = DEFAULT_GIT_LIMITS): Promise<GitObject[]> {23 const reader = await gitObjects(repository);24 const seen = new Map<string, GitObjectInfo["type"]>(), queue = roots.map(oid => ({ oid, type: undefined as GitObjectInfo["type"] | undefined })), result: GitObject[] = [];25 let bytes = 0, edges = 0;26 while (queue.length) {27 const { oid, type } = queue.pop()!;28 if (seen.has(oid)) { if (type && seen.get(oid) !== type) throw new IntegrityError("Git dependency type mismatch"); continue; }29 if (seen.size >= limits.maxTransactionObjects) throw new LimitError("Git graph object limit reached");30 const info = await reader.info(oid);31 if (!info || info.oid !== oid || (type && info.type !== type)) throw new IntegrityError("Git graph dependency is missing");32 if (!Number.isSafeInteger(info.size) || info.size < 0 || info.size > limits.maxObjectBytes || bytes + info.size > limits.maxTransactionRawBytes) throw new LimitError("Git graph byte limit reached");33 bytes += info.size;34 edges += info.links.length;35 if (edges > limits.maxGraphEdges) throw new LimitError("Git graph edge limit reached");36 const object = await reader.get(oid);37 if (!object || object.oid !== oid || object.type !== info.type || object.data.length !== info.size) throw new IntegrityError("Git graph changed during read");38 if (bytesToHex(sha1.create().update(new TextEncoder().encode(`${object.type} ${object.data.length}\0`)).update(object.data).digest()) !== oid) throw new IntegrityError("Git object hash mismatch");39 seen.set(oid, info.type);40 result.push(object);41 for (const link of info.links) queue.push(link);42 }43 return result;44}