Skip to content
File

Blob: src/worker/git/receive/support.ts

typescript61 lines
1import type { Logger } from "@/worker/common/logger";
2import type { ReceiveCommand, ReceiveStatus } from "@/worker/git/operations/validation";
3 
4import { concatChunks, flushPkt, pktLine } from "@/worker/git/core/pktline";
5import { isResolveAbortedError } from "@/worker/git/pack/indexer";
6 
7export function throwIfReceiveAborted(request: Request, log: Logger, stage: string): void {
8 if (!request.signal.aborted) return;
9 log.debug("receive:aborted", { stage });
10 const error = new Error(`receive: aborted during ${stage}`);
11 error.name = "AbortError";
12 throw error;
13}
14 
15export function isReceiveAbort(request: Request, error: unknown): boolean {
16 if (request.signal.aborted) return true;
17 if (isResolveAbortedError(error)) return true;
18 return error instanceof Error && error.name === "AbortError";
19}
20 
21export function buildReceiveReportStatus(args: {
22 unpackOk: boolean;
23 unpackMessage?: string;
24 commands: ReceiveCommand[];
25 statuses: ReceiveStatus[];
26}): Uint8Array {
27 const chunks: Uint8Array[] = [];
28 chunks.push(
29 pktLine(args.unpackOk ? "unpack ok\n" : `unpack error ${args.unpackMessage || "failed"}\n`)
30 );
31 for (let index = 0; index < args.commands.length; index++) {
32 const command = args.commands[index];
33 const status = args.statuses[index];
34 if (status?.ok) {
35 chunks.push(pktLine(`ok ${command.ref}\n`));
36 continue;
37 }
38 chunks.push(pktLine(`ng ${command.ref} ${status?.msg || "rejected"}\n`));
39 }
40 chunks.push(flushPkt());
41 return concatChunks(chunks);
42}
43 
44export function buildReceiveUnpackFailureReport(
45 commands: ReceiveCommand[],
46 unpackMessage: string,
47 statusMessage: string = "unpack-failed"
48): Uint8Array {
49 const statuses: ReceiveStatus[] = commands.map((command) => ({
50 ref: command.ref,
51 ok: false,
52 msg: statusMessage,
53 }));
54 return buildReceiveReportStatus({
55 unpackOk: false,
56 unpackMessage,
57 commands,
58 statuses,
59 });
60}