gitx.do 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/durable-object/object-store.d.ts +113 -0
- package/dist/durable-object/object-store.d.ts.map +1 -0
- package/dist/durable-object/object-store.js +387 -0
- package/dist/durable-object/object-store.js.map +1 -0
- package/dist/durable-object/schema.d.ts +17 -0
- package/dist/durable-object/schema.d.ts.map +1 -0
- package/dist/durable-object/schema.js +43 -0
- package/dist/durable-object/schema.js.map +1 -0
- package/dist/durable-object/wal.d.ts +111 -0
- package/dist/durable-object/wal.d.ts.map +1 -0
- package/dist/durable-object/wal.js +200 -0
- package/dist/durable-object/wal.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/adapter.d.ts +231 -0
- package/dist/mcp/adapter.d.ts.map +1 -0
- package/dist/mcp/adapter.js +502 -0
- package/dist/mcp/adapter.js.map +1 -0
- package/dist/mcp/sandbox.d.ts +261 -0
- package/dist/mcp/sandbox.d.ts.map +1 -0
- package/dist/mcp/sandbox.js +983 -0
- package/dist/mcp/sandbox.js.map +1 -0
- package/dist/mcp/sdk-adapter.d.ts +413 -0
- package/dist/mcp/sdk-adapter.d.ts.map +1 -0
- package/dist/mcp/sdk-adapter.js +672 -0
- package/dist/mcp/sdk-adapter.js.map +1 -0
- package/dist/mcp/tools.d.ts +133 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +1604 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/ops/blame.d.ts +148 -0
- package/dist/ops/blame.d.ts.map +1 -0
- package/dist/ops/blame.js +754 -0
- package/dist/ops/blame.js.map +1 -0
- package/dist/ops/branch.d.ts +215 -0
- package/dist/ops/branch.d.ts.map +1 -0
- package/dist/ops/branch.js +608 -0
- package/dist/ops/branch.js.map +1 -0
- package/dist/ops/commit-traversal.d.ts +209 -0
- package/dist/ops/commit-traversal.d.ts.map +1 -0
- package/dist/ops/commit-traversal.js +755 -0
- package/dist/ops/commit-traversal.js.map +1 -0
- package/dist/ops/commit.d.ts +221 -0
- package/dist/ops/commit.d.ts.map +1 -0
- package/dist/ops/commit.js +606 -0
- package/dist/ops/commit.js.map +1 -0
- package/dist/ops/merge-base.d.ts +223 -0
- package/dist/ops/merge-base.d.ts.map +1 -0
- package/dist/ops/merge-base.js +581 -0
- package/dist/ops/merge-base.js.map +1 -0
- package/dist/ops/merge.d.ts +385 -0
- package/dist/ops/merge.d.ts.map +1 -0
- package/dist/ops/merge.js +1203 -0
- package/dist/ops/merge.js.map +1 -0
- package/dist/ops/tag.d.ts +182 -0
- package/dist/ops/tag.d.ts.map +1 -0
- package/dist/ops/tag.js +608 -0
- package/dist/ops/tag.js.map +1 -0
- package/dist/ops/tree-builder.d.ts +82 -0
- package/dist/ops/tree-builder.d.ts.map +1 -0
- package/dist/ops/tree-builder.js +246 -0
- package/dist/ops/tree-builder.js.map +1 -0
- package/dist/ops/tree-diff.d.ts +243 -0
- package/dist/ops/tree-diff.d.ts.map +1 -0
- package/dist/ops/tree-diff.js +657 -0
- package/dist/ops/tree-diff.js.map +1 -0
- package/dist/pack/delta.d.ts +68 -0
- package/dist/pack/delta.d.ts.map +1 -0
- package/dist/pack/delta.js +343 -0
- package/dist/pack/delta.js.map +1 -0
- package/dist/pack/format.d.ts +84 -0
- package/dist/pack/format.d.ts.map +1 -0
- package/dist/pack/format.js +261 -0
- package/dist/pack/format.js.map +1 -0
- package/dist/pack/full-generation.d.ts +327 -0
- package/dist/pack/full-generation.d.ts.map +1 -0
- package/dist/pack/full-generation.js +1159 -0
- package/dist/pack/full-generation.js.map +1 -0
- package/dist/pack/generation.d.ts +118 -0
- package/dist/pack/generation.d.ts.map +1 -0
- package/dist/pack/generation.js +459 -0
- package/dist/pack/generation.js.map +1 -0
- package/dist/pack/index.d.ts +181 -0
- package/dist/pack/index.d.ts.map +1 -0
- package/dist/pack/index.js +552 -0
- package/dist/pack/index.js.map +1 -0
- package/dist/refs/branch.d.ts +224 -0
- package/dist/refs/branch.d.ts.map +1 -0
- package/dist/refs/branch.js +170 -0
- package/dist/refs/branch.js.map +1 -0
- package/dist/refs/storage.d.ts +208 -0
- package/dist/refs/storage.d.ts.map +1 -0
- package/dist/refs/storage.js +421 -0
- package/dist/refs/storage.js.map +1 -0
- package/dist/refs/tag.d.ts +230 -0
- package/dist/refs/tag.d.ts.map +1 -0
- package/dist/refs/tag.js +188 -0
- package/dist/refs/tag.js.map +1 -0
- package/dist/storage/lru-cache.d.ts +188 -0
- package/dist/storage/lru-cache.d.ts.map +1 -0
- package/dist/storage/lru-cache.js +410 -0
- package/dist/storage/lru-cache.js.map +1 -0
- package/dist/storage/object-index.d.ts +140 -0
- package/dist/storage/object-index.d.ts.map +1 -0
- package/dist/storage/object-index.js +166 -0
- package/dist/storage/object-index.js.map +1 -0
- package/dist/storage/r2-pack.d.ts +394 -0
- package/dist/storage/r2-pack.d.ts.map +1 -0
- package/dist/storage/r2-pack.js +1062 -0
- package/dist/storage/r2-pack.js.map +1 -0
- package/dist/tiered/cdc-pipeline.d.ts +316 -0
- package/dist/tiered/cdc-pipeline.d.ts.map +1 -0
- package/dist/tiered/cdc-pipeline.js +771 -0
- package/dist/tiered/cdc-pipeline.js.map +1 -0
- package/dist/tiered/migration.d.ts +242 -0
- package/dist/tiered/migration.d.ts.map +1 -0
- package/dist/tiered/migration.js +592 -0
- package/dist/tiered/migration.js.map +1 -0
- package/dist/tiered/parquet-writer.d.ts +248 -0
- package/dist/tiered/parquet-writer.d.ts.map +1 -0
- package/dist/tiered/parquet-writer.js +555 -0
- package/dist/tiered/parquet-writer.js.map +1 -0
- package/dist/tiered/read-path.d.ts +141 -0
- package/dist/tiered/read-path.d.ts.map +1 -0
- package/dist/tiered/read-path.js +204 -0
- package/dist/tiered/read-path.js.map +1 -0
- package/dist/types/objects.d.ts +53 -0
- package/dist/types/objects.d.ts.map +1 -0
- package/dist/types/objects.js +291 -0
- package/dist/types/objects.js.map +1 -0
- package/dist/types/storage.d.ts +117 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +8 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/utils/hash.d.ts +31 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +60 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/sha1.d.ts +26 -0
- package/dist/utils/sha1.d.ts.map +1 -0
- package/dist/utils/sha1.js +127 -0
- package/dist/utils/sha1.js.map +1 -0
- package/dist/wire/capabilities.d.ts +236 -0
- package/dist/wire/capabilities.d.ts.map +1 -0
- package/dist/wire/capabilities.js +437 -0
- package/dist/wire/capabilities.js.map +1 -0
- package/dist/wire/pkt-line.d.ts +67 -0
- package/dist/wire/pkt-line.d.ts.map +1 -0
- package/dist/wire/pkt-line.js +145 -0
- package/dist/wire/pkt-line.js.map +1 -0
- package/dist/wire/receive-pack.d.ts +302 -0
- package/dist/wire/receive-pack.d.ts.map +1 -0
- package/dist/wire/receive-pack.js +885 -0
- package/dist/wire/receive-pack.js.map +1 -0
- package/dist/wire/smart-http.d.ts +321 -0
- package/dist/wire/smart-http.d.ts.map +1 -0
- package/dist/wire/smart-http.js +654 -0
- package/dist/wire/smart-http.js.map +1 -0
- package/dist/wire/upload-pack.d.ts +333 -0
- package/dist/wire/upload-pack.d.ts.map +1 -0
- package/dist/wire/upload-pack.js +850 -0
- package/dist/wire/upload-pack.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git wire protocol capability negotiation
|
|
3
|
+
*
|
|
4
|
+
* Capabilities are used during the initial handshake between git client and server
|
|
5
|
+
* to determine what features are supported by both sides.
|
|
6
|
+
*
|
|
7
|
+
* Protocol v1: Capabilities are sent as a space-separated list after the first ref
|
|
8
|
+
* Protocol v2: Capabilities are advertised line by line in the initial handshake
|
|
9
|
+
*
|
|
10
|
+
* Reference: https://git-scm.com/docs/protocol-capabilities
|
|
11
|
+
* Reference: https://git-scm.com/docs/protocol-v2
|
|
12
|
+
*/
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/** Default client capabilities for fetch (protocol v1) */
|
|
17
|
+
export const DEFAULT_FETCH_CAPABILITIES_V1 = [
|
|
18
|
+
'multi_ack_detailed',
|
|
19
|
+
'side-band-64k',
|
|
20
|
+
'thin-pack',
|
|
21
|
+
'ofs-delta',
|
|
22
|
+
'agent',
|
|
23
|
+
];
|
|
24
|
+
/** Default client capabilities for push (protocol v1) */
|
|
25
|
+
export const DEFAULT_PUSH_CAPABILITIES_V1 = [
|
|
26
|
+
'report-status',
|
|
27
|
+
'side-band-64k',
|
|
28
|
+
'agent',
|
|
29
|
+
'quiet',
|
|
30
|
+
];
|
|
31
|
+
/** Minimum required capabilities for basic fetch */
|
|
32
|
+
export const REQUIRED_FETCH_CAPABILITIES = [];
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Parsing Functions
|
|
35
|
+
// ============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Parse a capability string from ref advertisement (protocol v1).
|
|
38
|
+
*
|
|
39
|
+
* Format: "<oid> <refname>\0<cap1> <cap2> cap3=value..."
|
|
40
|
+
*
|
|
41
|
+
* @param line - The ref advertisement line with capabilities
|
|
42
|
+
* @returns Parsed capabilities
|
|
43
|
+
*/
|
|
44
|
+
export function parseCapabilityString(line) {
|
|
45
|
+
// Find the NUL byte that separates ref info from capabilities
|
|
46
|
+
const nulIndex = line.indexOf('\0');
|
|
47
|
+
if (nulIndex === -1) {
|
|
48
|
+
throw new Error('Invalid capability string: missing NUL byte separator');
|
|
49
|
+
}
|
|
50
|
+
// Extract the capability portion after the NUL byte
|
|
51
|
+
const capString = line.slice(nulIndex + 1);
|
|
52
|
+
// Parse the capabilities
|
|
53
|
+
const entries = parseCapabilities(capString);
|
|
54
|
+
// Build the capability map
|
|
55
|
+
const capabilities = new Map();
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
capabilities.set(entry.name, entry.value);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
version: 1,
|
|
61
|
+
capabilities,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parse individual capability entries from a space-separated string.
|
|
66
|
+
*
|
|
67
|
+
* @param capString - Space-separated capability string
|
|
68
|
+
* @returns Array of capability entries
|
|
69
|
+
*/
|
|
70
|
+
export function parseCapabilities(capString) {
|
|
71
|
+
// Trim and split by whitespace
|
|
72
|
+
const trimmed = capString.trim();
|
|
73
|
+
if (trimmed === '') {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
// Split by whitespace (handles multiple spaces)
|
|
77
|
+
const parts = trimmed.split(/\s+/);
|
|
78
|
+
return parts.map((part) => {
|
|
79
|
+
const eqIndex = part.indexOf('=');
|
|
80
|
+
if (eqIndex === -1) {
|
|
81
|
+
return { name: part };
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return {
|
|
85
|
+
name: part.slice(0, eqIndex),
|
|
86
|
+
value: part.slice(eqIndex + 1),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Parse a ref advertisement line (protocol v1).
|
|
93
|
+
*
|
|
94
|
+
* First line format: "<oid> <refname>\0<capabilities>"
|
|
95
|
+
* Subsequent lines: "<oid> <refname>"
|
|
96
|
+
*
|
|
97
|
+
* @param line - The pkt-line data (without length prefix)
|
|
98
|
+
* @param isFirst - Whether this is the first line (contains capabilities)
|
|
99
|
+
* @returns Parsed ref advertisement
|
|
100
|
+
*/
|
|
101
|
+
export function parseRefAdvertisement(line, isFirst) {
|
|
102
|
+
// Remove trailing newline if present
|
|
103
|
+
const cleanLine = line.replace(/\n$/, '');
|
|
104
|
+
let oid;
|
|
105
|
+
let name;
|
|
106
|
+
let capabilities;
|
|
107
|
+
if (isFirst) {
|
|
108
|
+
// First line has capabilities after NUL byte
|
|
109
|
+
const nulIndex = cleanLine.indexOf('\0');
|
|
110
|
+
if (nulIndex === -1) {
|
|
111
|
+
throw new Error('First ref advertisement line must contain NUL byte');
|
|
112
|
+
}
|
|
113
|
+
const refPart = cleanLine.slice(0, nulIndex);
|
|
114
|
+
const spaceIndex = refPart.indexOf(' ');
|
|
115
|
+
if (spaceIndex === -1) {
|
|
116
|
+
throw new Error('Invalid ref advertisement format: missing space between OID and refname');
|
|
117
|
+
}
|
|
118
|
+
oid = refPart.slice(0, spaceIndex);
|
|
119
|
+
name = refPart.slice(spaceIndex + 1);
|
|
120
|
+
// Validate OID length (should be 40 hex chars for SHA-1)
|
|
121
|
+
if (oid.length !== 40) {
|
|
122
|
+
throw new Error('Invalid OID length in ref advertisement');
|
|
123
|
+
}
|
|
124
|
+
capabilities = parseCapabilityString(cleanLine);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Subsequent lines: just "<oid> <refname>"
|
|
128
|
+
const spaceIndex = cleanLine.indexOf(' ');
|
|
129
|
+
if (spaceIndex === -1) {
|
|
130
|
+
throw new Error('Invalid ref advertisement format: missing space between OID and refname');
|
|
131
|
+
}
|
|
132
|
+
oid = cleanLine.slice(0, spaceIndex);
|
|
133
|
+
name = cleanLine.slice(spaceIndex + 1);
|
|
134
|
+
// Validate OID length
|
|
135
|
+
if (oid.length !== 40) {
|
|
136
|
+
throw new Error('Invalid OID length in ref advertisement');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
oid,
|
|
141
|
+
name,
|
|
142
|
+
capabilities,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parse protocol v2 capability advertisement.
|
|
147
|
+
*
|
|
148
|
+
* Format:
|
|
149
|
+
* version 2
|
|
150
|
+
* agent=git/2.30.0
|
|
151
|
+
* ls-refs
|
|
152
|
+
* fetch=...
|
|
153
|
+
* server-option
|
|
154
|
+
* object-format=sha1
|
|
155
|
+
*
|
|
156
|
+
* @param lines - Array of pkt-line data
|
|
157
|
+
* @returns Parsed server capabilities
|
|
158
|
+
*/
|
|
159
|
+
export function parseServerCapabilitiesV2(lines) {
|
|
160
|
+
if (lines.length === 0 || lines[0] !== 'version 2') {
|
|
161
|
+
throw new Error('Invalid protocol v2 response: must start with "version 2"');
|
|
162
|
+
}
|
|
163
|
+
const commands = [];
|
|
164
|
+
const capabilities = new Map();
|
|
165
|
+
let agent;
|
|
166
|
+
let objectFormat;
|
|
167
|
+
// Process each line after "version 2"
|
|
168
|
+
for (let i = 1; i < lines.length; i++) {
|
|
169
|
+
const line = lines[i];
|
|
170
|
+
const eqIndex = line.indexOf('=');
|
|
171
|
+
if (eqIndex === -1) {
|
|
172
|
+
// This is a command without a value
|
|
173
|
+
commands.push(line);
|
|
174
|
+
capabilities.set(line, undefined);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
const name = line.slice(0, eqIndex);
|
|
178
|
+
const value = line.slice(eqIndex + 1);
|
|
179
|
+
if (name === 'agent') {
|
|
180
|
+
agent = value;
|
|
181
|
+
}
|
|
182
|
+
else if (name === 'object-format') {
|
|
183
|
+
objectFormat = value;
|
|
184
|
+
}
|
|
185
|
+
else if (name === 'fetch' || name === 'ls-refs' || name === 'server-option') {
|
|
186
|
+
// Commands with sub-capabilities
|
|
187
|
+
commands.push(name);
|
|
188
|
+
capabilities.set(name, value);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
capabilities.set(name, value);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
version: 2,
|
|
197
|
+
commands,
|
|
198
|
+
agent,
|
|
199
|
+
objectFormat,
|
|
200
|
+
capabilities,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
// ============================================================================
|
|
204
|
+
// Building Functions
|
|
205
|
+
// ============================================================================
|
|
206
|
+
/**
|
|
207
|
+
* Build a capability string for want/have request (protocol v1).
|
|
208
|
+
*
|
|
209
|
+
* @param capabilities - Capabilities to include
|
|
210
|
+
* @returns Space-separated capability string
|
|
211
|
+
*/
|
|
212
|
+
export function buildCapabilityString(capabilities) {
|
|
213
|
+
return capabilities
|
|
214
|
+
.map((cap) => {
|
|
215
|
+
if (cap.value !== undefined) {
|
|
216
|
+
return `${cap.name}=${cap.value}`;
|
|
217
|
+
}
|
|
218
|
+
return cap.name;
|
|
219
|
+
})
|
|
220
|
+
.join(' ');
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Build a want line with capabilities (first want only).
|
|
224
|
+
*
|
|
225
|
+
* Format: "want <oid> <capabilities>\n"
|
|
226
|
+
*
|
|
227
|
+
* @param oid - The object ID to want
|
|
228
|
+
* @param capabilities - Capabilities to include
|
|
229
|
+
* @returns Formatted want line
|
|
230
|
+
*/
|
|
231
|
+
export function buildWantLine(oid, capabilities) {
|
|
232
|
+
if (capabilities && capabilities.length > 0) {
|
|
233
|
+
const capString = buildCapabilityString(capabilities);
|
|
234
|
+
return `want ${oid} ${capString}\n`;
|
|
235
|
+
}
|
|
236
|
+
return `want ${oid}\n`;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Build a have line for negotiation.
|
|
240
|
+
*
|
|
241
|
+
* Format: "have <oid>\n"
|
|
242
|
+
*
|
|
243
|
+
* @param oid - The object ID we have
|
|
244
|
+
* @returns Formatted have line
|
|
245
|
+
*/
|
|
246
|
+
export function buildHaveLine(oid) {
|
|
247
|
+
return `have ${oid.toLowerCase()}\n`;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Build a complete want/have request.
|
|
251
|
+
*
|
|
252
|
+
* @param request - The want request with capabilities
|
|
253
|
+
* @returns Array of pkt-line format strings
|
|
254
|
+
*/
|
|
255
|
+
export function buildFetchRequest(request) {
|
|
256
|
+
const lines = [];
|
|
257
|
+
for (let i = 0; i < request.wants.length; i++) {
|
|
258
|
+
const oid = request.wants[i];
|
|
259
|
+
if (i === 0) {
|
|
260
|
+
// First want line includes capabilities
|
|
261
|
+
lines.push(buildWantLine(oid, request.capabilities));
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// Subsequent want lines don't include capabilities
|
|
265
|
+
lines.push(buildWantLine(oid));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return lines;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Build protocol v2 command request.
|
|
272
|
+
*
|
|
273
|
+
* Format:
|
|
274
|
+
* command=<cmd>
|
|
275
|
+
* capability1
|
|
276
|
+
* capability2=value
|
|
277
|
+
* 0001 (delimiter)
|
|
278
|
+
* <command-specific args>
|
|
279
|
+
* 0000 (flush)
|
|
280
|
+
*
|
|
281
|
+
* @param command - The v2 command (e.g., 'fetch', 'ls-refs')
|
|
282
|
+
* @param capabilities - Client capabilities
|
|
283
|
+
* @param args - Command-specific arguments
|
|
284
|
+
* @returns Array of pkt-line format strings
|
|
285
|
+
*/
|
|
286
|
+
export function buildV2CommandRequest(command, capabilities, args) {
|
|
287
|
+
const lines = [];
|
|
288
|
+
// Add command line
|
|
289
|
+
lines.push(`command=${command}`);
|
|
290
|
+
// Add capabilities
|
|
291
|
+
for (const cap of capabilities) {
|
|
292
|
+
if (cap.value !== undefined) {
|
|
293
|
+
lines.push(`${cap.name}=${cap.value}`);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
lines.push(cap.name);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Add arguments if present
|
|
300
|
+
if (args && args.length > 0) {
|
|
301
|
+
for (const arg of args) {
|
|
302
|
+
lines.push(arg);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return lines;
|
|
306
|
+
}
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// Negotiation Functions
|
|
309
|
+
// ============================================================================
|
|
310
|
+
/**
|
|
311
|
+
* Negotiate protocol version with server.
|
|
312
|
+
*
|
|
313
|
+
* @param serverAdvertisement - First line from server
|
|
314
|
+
* @param preferredVersion - Client's preferred version
|
|
315
|
+
* @returns Negotiation result
|
|
316
|
+
*/
|
|
317
|
+
export function negotiateVersion(serverAdvertisement, preferredVersion = 2) {
|
|
318
|
+
const serverSupportsV2 = serverAdvertisement.startsWith('version 2');
|
|
319
|
+
let version;
|
|
320
|
+
if (serverSupportsV2 && preferredVersion === 2) {
|
|
321
|
+
version = 2;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
version = 1;
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
version,
|
|
328
|
+
serverSupportsV2,
|
|
329
|
+
commonCapabilities: [],
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Find common capabilities between client and server.
|
|
334
|
+
*
|
|
335
|
+
* @param clientCaps - Client capabilities
|
|
336
|
+
* @param serverCaps - Server capabilities
|
|
337
|
+
* @returns Array of common capability names
|
|
338
|
+
*/
|
|
339
|
+
export function findCommonCapabilities(clientCaps, serverCaps) {
|
|
340
|
+
const common = [];
|
|
341
|
+
for (const clientCap of clientCaps) {
|
|
342
|
+
if (serverCaps.capabilities.has(clientCap.name)) {
|
|
343
|
+
common.push(clientCap.name);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return common;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Check if a specific capability is supported.
|
|
350
|
+
*
|
|
351
|
+
* @param capSet - The capability set to check
|
|
352
|
+
* @param name - The capability name
|
|
353
|
+
* @returns True if capability is supported
|
|
354
|
+
*/
|
|
355
|
+
export function hasCapability(capSet, name) {
|
|
356
|
+
return capSet.capabilities.has(name);
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Get the value of a capability (if it has one).
|
|
360
|
+
*
|
|
361
|
+
* @param capSet - The capability set
|
|
362
|
+
* @param name - The capability name
|
|
363
|
+
* @returns The capability value or undefined
|
|
364
|
+
*/
|
|
365
|
+
export function getCapabilityValue(capSet, name) {
|
|
366
|
+
return capSet.capabilities.get(name);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Create a capability set from entries.
|
|
370
|
+
*
|
|
371
|
+
* @param version - Protocol version
|
|
372
|
+
* @param entries - Capability entries
|
|
373
|
+
* @returns CapabilitySet
|
|
374
|
+
*/
|
|
375
|
+
export function createCapabilitySet(version, entries) {
|
|
376
|
+
const capabilities = new Map();
|
|
377
|
+
for (const entry of entries) {
|
|
378
|
+
capabilities.set(entry.name, entry.value);
|
|
379
|
+
}
|
|
380
|
+
return {
|
|
381
|
+
version,
|
|
382
|
+
capabilities,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Select optimal capabilities for a fetch operation.
|
|
387
|
+
*
|
|
388
|
+
* @param serverCaps - Server advertised capabilities
|
|
389
|
+
* @param clientPrefs - Client preferred capabilities (in priority order)
|
|
390
|
+
* @returns Selected capabilities to use
|
|
391
|
+
*/
|
|
392
|
+
export function selectFetchCapabilities(serverCaps, clientPrefs) {
|
|
393
|
+
const selected = [];
|
|
394
|
+
for (const pref of clientPrefs) {
|
|
395
|
+
if (serverCaps.capabilities.has(pref.name)) {
|
|
396
|
+
// Use the client's value, not the server's
|
|
397
|
+
selected.push(pref);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return selected;
|
|
401
|
+
}
|
|
402
|
+
// ============================================================================
|
|
403
|
+
// Validation Functions
|
|
404
|
+
// ============================================================================
|
|
405
|
+
/**
|
|
406
|
+
* Validate that a capability name is well-formed.
|
|
407
|
+
*
|
|
408
|
+
* @param name - The capability name to validate
|
|
409
|
+
* @returns True if valid
|
|
410
|
+
*/
|
|
411
|
+
export function isValidCapabilityName(name) {
|
|
412
|
+
if (name === '') {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
// Check for invalid characters (spaces, NUL, newlines)
|
|
416
|
+
if (/[\s\0\n]/.test(name)) {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Validate that required capabilities are present.
|
|
423
|
+
*
|
|
424
|
+
* @param capSet - The capability set to check
|
|
425
|
+
* @param required - Required capability names
|
|
426
|
+
* @returns Array of missing capability names
|
|
427
|
+
*/
|
|
428
|
+
export function validateRequiredCapabilities(capSet, required) {
|
|
429
|
+
const missing = [];
|
|
430
|
+
for (const reqCap of required) {
|
|
431
|
+
if (!capSet.capabilities.has(reqCap)) {
|
|
432
|
+
missing.push(reqCap);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return missing;
|
|
436
|
+
}
|
|
437
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/wire/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgHH,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,0DAA0D;AAC1D,MAAM,CAAC,MAAM,6BAA6B,GAAmB;IAC3D,oBAAoB;IACpB,eAAe;IACf,WAAW;IACX,WAAW;IACX,OAAO;CACR,CAAA;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,4BAA4B,GAAmB;IAC1D,eAAe;IACf,eAAe;IACf,OAAO;IACP,OAAO;CACR,CAAA;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,2BAA2B,GAAmB,EAAE,CAAA;AAE7D,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAC1E,CAAC;IAED,oDAAoD;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAA;IAE1C,yBAAyB;IACzB,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAA;IAE5C,2BAA2B;IAC3B,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAA;IAC1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO;QACL,OAAO,EAAE,CAAC;QACV,YAAY;KACb,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,+BAA+B;IAC/B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAA;IAChC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,gDAAgD;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAElC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACjC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QACvB,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;gBAC5B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;aAC/B,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,OAAgB;IAClE,qCAAqC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAEzC,IAAI,GAAW,CAAA;IACf,IAAI,IAAY,CAAA;IAChB,IAAI,YAAuC,CAAA;IAE3C,IAAI,OAAO,EAAE,CAAC;QACZ,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;QACvE,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;QAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;QAC5F,CAAC;QAED,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QAClC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;QAEpC,yDAAyD;QACzD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;QAC5D,CAAC;QAED,YAAY,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAA;IACjD,CAAC;SAAM,CAAC;QACN,2CAA2C;QAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;QAC5F,CAAC;QAED,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QACpC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;QAEtC,sBAAsB;QACtB,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG;QACH,IAAI;QACJ,YAAY;KACb,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAe;IACvD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;IAC9E,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAA;IAC1D,IAAI,KAAyB,CAAA;IAC7B,IAAI,YAA2C,CAAA;IAE/C,sCAAsC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAEjC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,oCAAoC;YACpC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACnB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACnC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;YAErC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,KAAK,GAAG,KAAK,CAAA;YACf,CAAC;iBAAM,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;gBACpC,YAAY,GAAG,KAA0B,CAAA;YAC3C,CAAC;iBAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC9E,iCAAiC;gBACjC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACnB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC/B,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,CAAC;QACV,QAAQ;QACR,KAAK;QACL,YAAY;QACZ,YAAY;KACb,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAA+B;IACnE,OAAO,YAAY;SAChB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAA;QACnC,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,YAAgC;IACzE,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;QACrD,OAAO,QAAQ,GAAG,IAAI,SAAS,IAAI,CAAA;IACrC,CAAC;IACD,OAAO,QAAQ,GAAG,IAAI,CAAA;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,QAAQ,GAAG,CAAC,WAAW,EAAE,IAAI,CAAA;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC5B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,wCAAwC;YACxC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;QACtD,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAe,EACf,YAA+B,EAC/B,IAAe;IAEf,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,mBAAmB;IACnB,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,EAAE,CAAC,CAAA;IAEhC,mBAAmB;IACnB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,CAAA;QACxC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,mBAA2B,EAC3B,mBAAoC,CAAC;IAErC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAEpE,IAAI,OAAwB,CAAA;IAC5B,IAAI,gBAAgB,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,GAAG,CAAC,CAAA;IACb,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,CAAA;IACb,CAAC;IAED,OAAO;QACL,OAAO;QACP,gBAAgB;QAChB,kBAAkB,EAAE,EAAE;KACvB,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAA6B,EAC7B,UAAyB;IAEzB,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAAqB,EAAE,IAAY;IAC/D,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAqB,EAAE,IAAY;IACpE,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAwB,EACxB,OAA0B;IAE1B,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAA;IAE1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO;QACL,OAAO;QACP,YAAY;KACb,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAyB,EACzB,WAA8B;IAE9B,MAAM,QAAQ,GAAsB,EAAE,CAAA;IAEtC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,2CAA2C;YAC3C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,uDAAuD;IACvD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAqB,EACrB,QAAkB;IAElB,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git pkt-line protocol implementation
|
|
3
|
+
*
|
|
4
|
+
* The pkt-line format is used in Git's wire protocol for communication.
|
|
5
|
+
* Each packet starts with a 4-byte hex length prefix (including the 4 bytes itself).
|
|
6
|
+
*
|
|
7
|
+
* Special packets:
|
|
8
|
+
* - flush-pkt (0000): Indicates end of a message section
|
|
9
|
+
* - delim-pkt (0001): Delimiter used in protocol v2
|
|
10
|
+
*
|
|
11
|
+
* Reference: https://git-scm.com/docs/protocol-common#_pkt_line_format
|
|
12
|
+
*/
|
|
13
|
+
/** Flush packet - indicates end of section */
|
|
14
|
+
export declare const FLUSH_PKT = "0000";
|
|
15
|
+
/** Delimiter packet - used in protocol v2 */
|
|
16
|
+
export declare const DELIM_PKT = "0001";
|
|
17
|
+
/** Maximum pkt-line data size (65516 bytes = 65520 - 4 for length prefix) */
|
|
18
|
+
export declare const MAX_PKT_LINE_DATA = 65516;
|
|
19
|
+
type PktLineInput = string | Uint8Array;
|
|
20
|
+
interface DecodedPktLine {
|
|
21
|
+
data: string | null;
|
|
22
|
+
type?: 'flush' | 'delim' | 'incomplete';
|
|
23
|
+
bytesRead: number;
|
|
24
|
+
}
|
|
25
|
+
interface StreamPacket {
|
|
26
|
+
data: string | null;
|
|
27
|
+
type: 'data' | 'flush' | 'delim';
|
|
28
|
+
}
|
|
29
|
+
interface PktLineStreamResult {
|
|
30
|
+
packets: StreamPacket[];
|
|
31
|
+
remaining: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Encode data into pkt-line format.
|
|
35
|
+
*
|
|
36
|
+
* The format is: 4 hex chars (total length including prefix) + data
|
|
37
|
+
*
|
|
38
|
+
* @param data - The data to encode (string or Uint8Array)
|
|
39
|
+
* @returns Encoded pkt-line as string (for text) or Uint8Array (for binary with non-printable chars)
|
|
40
|
+
*/
|
|
41
|
+
export declare function encodePktLine(data: PktLineInput): string | Uint8Array;
|
|
42
|
+
/**
|
|
43
|
+
* Decode a pkt-line format message.
|
|
44
|
+
*
|
|
45
|
+
* @param input - The input to decode (string or Uint8Array)
|
|
46
|
+
* @returns Object with decoded data, packet type (if special), and bytes consumed
|
|
47
|
+
*/
|
|
48
|
+
export declare function decodePktLine(input: PktLineInput): DecodedPktLine;
|
|
49
|
+
/**
|
|
50
|
+
* Create a flush-pkt (0000).
|
|
51
|
+
* Used to indicate end of a message section.
|
|
52
|
+
*/
|
|
53
|
+
export declare function encodeFlushPkt(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Create a delim-pkt (0001).
|
|
56
|
+
* Used as a delimiter in protocol v2.
|
|
57
|
+
*/
|
|
58
|
+
export declare function encodeDelimPkt(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Parse a stream of pkt-lines.
|
|
61
|
+
*
|
|
62
|
+
* @param input - The input stream to parse
|
|
63
|
+
* @returns Object with parsed packets and any remaining unparsed data
|
|
64
|
+
*/
|
|
65
|
+
export declare function pktLineStream(input: PktLineInput): PktLineStreamResult;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=pkt-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkt-line.d.ts","sourceRoot":"","sources":["../../src/wire/pkt-line.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,SAAS,SAAS,CAAA;AAE/B,6CAA6C;AAC7C,eAAO,MAAM,SAAS,SAAS,CAAA;AAE/B,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,QAAQ,CAAA;AAEtC,KAAK,YAAY,GAAG,MAAM,GAAG,UAAU,CAAA;AAEvC,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,CAAA;IACvC,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;CACjC;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CA0BrE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,cAAc,CA8CjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,CAkCtE"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git pkt-line protocol implementation
|
|
3
|
+
*
|
|
4
|
+
* The pkt-line format is used in Git's wire protocol for communication.
|
|
5
|
+
* Each packet starts with a 4-byte hex length prefix (including the 4 bytes itself).
|
|
6
|
+
*
|
|
7
|
+
* Special packets:
|
|
8
|
+
* - flush-pkt (0000): Indicates end of a message section
|
|
9
|
+
* - delim-pkt (0001): Delimiter used in protocol v2
|
|
10
|
+
*
|
|
11
|
+
* Reference: https://git-scm.com/docs/protocol-common#_pkt_line_format
|
|
12
|
+
*/
|
|
13
|
+
/** Flush packet - indicates end of section */
|
|
14
|
+
export const FLUSH_PKT = '0000';
|
|
15
|
+
/** Delimiter packet - used in protocol v2 */
|
|
16
|
+
export const DELIM_PKT = '0001';
|
|
17
|
+
/** Maximum pkt-line data size (65516 bytes = 65520 - 4 for length prefix) */
|
|
18
|
+
export const MAX_PKT_LINE_DATA = 65516;
|
|
19
|
+
/**
|
|
20
|
+
* Encode data into pkt-line format.
|
|
21
|
+
*
|
|
22
|
+
* The format is: 4 hex chars (total length including prefix) + data
|
|
23
|
+
*
|
|
24
|
+
* @param data - The data to encode (string or Uint8Array)
|
|
25
|
+
* @returns Encoded pkt-line as string (for text) or Uint8Array (for binary with non-printable chars)
|
|
26
|
+
*/
|
|
27
|
+
export function encodePktLine(data) {
|
|
28
|
+
if (typeof data === 'string') {
|
|
29
|
+
// String encoding - simple case
|
|
30
|
+
const length = 4 + data.length;
|
|
31
|
+
const hexLength = length.toString(16).padStart(4, '0');
|
|
32
|
+
return hexLength + data;
|
|
33
|
+
}
|
|
34
|
+
// Uint8Array encoding
|
|
35
|
+
const length = 4 + data.length;
|
|
36
|
+
const hexLength = length.toString(16).padStart(4, '0');
|
|
37
|
+
// Check if data contains only printable ASCII
|
|
38
|
+
const isPrintable = data.every(byte => byte >= 0x20 && byte <= 0x7e || byte === 0x0a || byte === 0x0d);
|
|
39
|
+
if (isPrintable) {
|
|
40
|
+
// Return as string for printable content
|
|
41
|
+
return hexLength + new TextDecoder().decode(data);
|
|
42
|
+
}
|
|
43
|
+
// Return as Uint8Array for binary content
|
|
44
|
+
const result = new Uint8Array(4 + data.length);
|
|
45
|
+
const encoder = new TextEncoder();
|
|
46
|
+
result.set(encoder.encode(hexLength), 0);
|
|
47
|
+
result.set(data, 4);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Decode a pkt-line format message.
|
|
52
|
+
*
|
|
53
|
+
* @param input - The input to decode (string or Uint8Array)
|
|
54
|
+
* @returns Object with decoded data, packet type (if special), and bytes consumed
|
|
55
|
+
*/
|
|
56
|
+
export function decodePktLine(input) {
|
|
57
|
+
// Convert to string for easier parsing
|
|
58
|
+
let str;
|
|
59
|
+
if (typeof input === 'string') {
|
|
60
|
+
str = input;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
str = new TextDecoder().decode(input);
|
|
64
|
+
}
|
|
65
|
+
// Need at least 4 bytes for length prefix
|
|
66
|
+
if (str.length < 4) {
|
|
67
|
+
return { data: null, type: 'incomplete', bytesRead: 0 };
|
|
68
|
+
}
|
|
69
|
+
const hexLength = str.slice(0, 4);
|
|
70
|
+
// Check for special packets
|
|
71
|
+
if (hexLength === '0000') {
|
|
72
|
+
return { data: null, type: 'flush', bytesRead: 4 };
|
|
73
|
+
}
|
|
74
|
+
if (hexLength === '0001') {
|
|
75
|
+
return { data: null, type: 'delim', bytesRead: 4 };
|
|
76
|
+
}
|
|
77
|
+
// Parse the length
|
|
78
|
+
const length = parseInt(hexLength, 16);
|
|
79
|
+
if (isNaN(length) || length < 4) {
|
|
80
|
+
return { data: null, type: 'incomplete', bytesRead: 0 };
|
|
81
|
+
}
|
|
82
|
+
// Validate packet size to prevent DoS attacks
|
|
83
|
+
if (length > MAX_PKT_LINE_DATA + 4) {
|
|
84
|
+
throw new Error(`Packet too large: ${length} bytes exceeds maximum ${MAX_PKT_LINE_DATA + 4}`);
|
|
85
|
+
}
|
|
86
|
+
// Check if we have enough data
|
|
87
|
+
if (str.length < length) {
|
|
88
|
+
return { data: null, type: 'incomplete', bytesRead: 0 };
|
|
89
|
+
}
|
|
90
|
+
// Extract data (length includes the 4-byte prefix)
|
|
91
|
+
const data = str.slice(4, length);
|
|
92
|
+
return { data, bytesRead: length };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create a flush-pkt (0000).
|
|
96
|
+
* Used to indicate end of a message section.
|
|
97
|
+
*/
|
|
98
|
+
export function encodeFlushPkt() {
|
|
99
|
+
return FLUSH_PKT;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create a delim-pkt (0001).
|
|
103
|
+
* Used as a delimiter in protocol v2.
|
|
104
|
+
*/
|
|
105
|
+
export function encodeDelimPkt() {
|
|
106
|
+
return DELIM_PKT;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Parse a stream of pkt-lines.
|
|
110
|
+
*
|
|
111
|
+
* @param input - The input stream to parse
|
|
112
|
+
* @returns Object with parsed packets and any remaining unparsed data
|
|
113
|
+
*/
|
|
114
|
+
export function pktLineStream(input) {
|
|
115
|
+
const packets = [];
|
|
116
|
+
// Convert to string for parsing
|
|
117
|
+
let str;
|
|
118
|
+
if (typeof input === 'string') {
|
|
119
|
+
str = input;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
str = new TextDecoder().decode(input);
|
|
123
|
+
}
|
|
124
|
+
let offset = 0;
|
|
125
|
+
while (offset < str.length) {
|
|
126
|
+
const remaining = str.slice(offset);
|
|
127
|
+
const result = decodePktLine(remaining);
|
|
128
|
+
if (result.type === 'incomplete') {
|
|
129
|
+
// Return remaining unparsed data
|
|
130
|
+
return { packets, remaining: remaining };
|
|
131
|
+
}
|
|
132
|
+
if (result.type === 'flush') {
|
|
133
|
+
packets.push({ data: null, type: 'flush' });
|
|
134
|
+
}
|
|
135
|
+
else if (result.type === 'delim') {
|
|
136
|
+
packets.push({ data: null, type: 'delim' });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
packets.push({ data: result.data, type: 'data' });
|
|
140
|
+
}
|
|
141
|
+
offset += result.bytesRead;
|
|
142
|
+
}
|
|
143
|
+
return { packets, remaining: '' };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=pkt-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkt-line.js","sourceRoot":"","sources":["../../src/wire/pkt-line.ts"],"names":[],"mappings":"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"}
|