Skip to content
File

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

typescript66 lines
1import type { ReceiveCommand } from "@/worker/git/operations/validation";
2 
3export type ReceiveNegotiatedCapabilities = {
4 reportStatus: boolean;
5 sideBand64k: boolean;
6 quiet: boolean;
7 atomic: boolean;
8 ofsDelta: boolean;
9 agent?: string;
10};
11 
12export type ParsedReceiveRequest = {
13 commands: ReceiveCommand[];
14 capabilities: ReceiveNegotiatedCapabilities;
15};
16 
17export type ReceiveCommandList = ReceiveCommand[];
18 
19function parseCapabilities(firstLine: string): ReceiveNegotiatedCapabilities {
20 const nulIndex = firstLine.indexOf("\0");
21 const capabilityText = nulIndex >= 0 ? firstLine.slice(nulIndex + 1).trim() : "";
22 const tokens = capabilityText.length > 0 ? capabilityText.split(/\s+/) : [];
23 
24 let agent: string | undefined;
25 for (const token of tokens) {
26 if (token.startsWith("agent=")) {
27 agent = token;
28 break;
29 }
30 }
31 
32 return {
33 reportStatus: tokens.includes("report-status"),
34 sideBand64k: tokens.includes("side-band-64k"),
35 quiet: tokens.includes("quiet"),
36 atomic: tokens.includes("atomic"),
37 ofsDelta: tokens.includes("ofs-delta"),
38 agent,
39 };
40}
41 
42export function parseReceiveRequest(lines: string[]): ParsedReceiveRequest {
43 const commands: ReceiveCommand[] = [];
44 const capabilities = parseCapabilities(lines[0] || "");
45 
46 for (let index = 0; index < lines.length; index++) {
47 let line = lines[index] || "";
48 if (index === 0) {
49 const nulIndex = line.indexOf("\0");
50 if (nulIndex >= 0) {
51 line = line.slice(0, nulIndex);
52 }
53 }
54 
55 const parts = line.trim().split(/\s+/);
56 if (parts.length < 3) continue;
57 commands.push({
58 oldOid: parts[0] || "",
59 newOid: parts[1] || "",
60 ref: parts.slice(2).join(" "),
61 });
62 }
63 
64 return { commands, capabilities };
65}