clone

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

dependabot/npm_and_yarn/npm-f01a459b0f
bindws / src / git-limits.ts
git-limits.ts 3.4K
1// Retained Git capacity is separate from the work admitted in one request.2// Values are bytes (not decimal MB); the console presents MiB/GiB.3export interface GitLimits {4 maxRepositories: number;5 maxRelayBytes: number;6 maxPackBytes: number;7 maxObjectBytes: number;8 maxObjects: number;9 maxRawBytes: number;10 maxTransactionRawBytes: number;11 maxTransactionObjects: number;12 maxCompressedBytes: number;13 maxMetadataBytes: number;14 maxRefs: number;15 maxGraphEdges: number;16 maxFetchBytes: number;17}1819export const MiB = 1024 * 1024;20export const GiB = 1024 * MiB;2122export const DEFAULT_GIT_LIMITS: Readonly<GitLimits> = Object.freeze({23 maxRepositories: 128,24 maxRelayBytes: 2 * GiB,25 maxPackBytes: 16 * MiB,26 maxObjectBytes: 16 * MiB,27 maxObjects: 100_000,28 maxRawBytes: 4 * GiB,29 maxTransactionRawBytes: 32 * MiB,30 maxTransactionObjects: 20_000,31 maxCompressedBytes: GiB,32 maxMetadataBytes: 128 * MiB,33 maxRefs: 4096,34 maxGraphEdges: 1_000_000,35 maxFetchBytes: 2 * GiB,36});3738// Keep headroom under the 10 GiB physical SQLite database ceiling. Request39// bounds are independent of that allowance and remain subject to memory/CPU.40export const MAX_GIT_LIMITS: Readonly<GitLimits> = Object.freeze({41 maxRepositories: 4096,42 maxRelayBytes: 6 * GiB,43 maxPackBytes: 95 * MiB,44 maxObjectBytes: 64 * MiB,45 maxObjects: 500_000,46 maxRawBytes: 64 * GiB,47 maxTransactionRawBytes: 64 * MiB,48 maxTransactionObjects: 100_000,49 maxCompressedBytes: 6 * GiB,50 maxMetadataBytes: GiB,51 maxRefs: 16_384,52 maxGraphEdges: 4_000_000,53 maxFetchBytes: 6 * GiB,54});5556// Reject a malformed patch as a unit rather than silently accepting a typo57// or making an owner believe a higher limit was applied. Empty patches are58// valid, and omitted fields preserve the current relay's choices.59export function gitLimitPatch(raw: unknown, current: Readonly<GitLimits> = DEFAULT_GIT_LIMITS): GitLimits | undefined {60 if (!raw || typeof raw !== "object" || Array.isArray(raw)) return undefined;61 const next = { ...current };62 for (const [key, value] of Object.entries(raw)) {63 if (!Object.hasOwn(MAX_GIT_LIMITS, key)) return undefined;64 const field = key as keyof GitLimits;65 if (!Number.isSafeInteger(value) || value < 1 || value > MAX_GIT_LIMITS[field]) return undefined;66 next[field] = value;67 }68 return next;69}7071export function gitPackLimits(limits: Readonly<GitLimits>) {72 return {73 maxPackBytes: limits.maxPackBytes,74 maxObjectBytes: limits.maxObjectBytes,75 maxTotalObjectBytes: limits.maxTransactionRawBytes,76 maxObjects: limits.maxTransactionObjects,77 maxPacks: 1,78 maxTotalPackBytes: limits.maxPackBytes,79 };80}8182// Lower intake quotas without stranding objects already stored under a larger83// policy. Fetch still has its own explicit response-byte limit and platform84// object/graph bounds; the backend enforces current quotas on each new write.85export function gitHttpLimits(limits: Readonly<GitLimits>) {86 return {87 maxBodyBytes: limits.maxPackBytes + 256 * 1024,88 maxResponseBytes: limits.maxFetchBytes,89 maxRefs: MAX_GIT_LIMITS.maxRefs,90 maxObjects: MAX_GIT_LIMITS.maxObjects,91 maxGraphEdges: MAX_GIT_LIMITS.maxGraphEdges,92 gitLimits: gitPackLimits(limits),93 fetchLimits: {94 maxPackBytes: limits.maxFetchBytes,95 maxObjectBytes: MAX_GIT_LIMITS.maxObjectBytes,96 maxTotalObjectBytes: MAX_GIT_LIMITS.maxRawBytes,97 maxObjects: MAX_GIT_LIMITS.maxObjects,98 maxPacks: 1,99 maxTotalPackBytes: limits.maxFetchBytes,100 },101 };102}