@scolladon/tsgit 0.9.0
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 +169 -0
- package/dist/cjs/adapters/browser/index.cjs +2 -0
- package/dist/cjs/adapters/browser/index.cjs.map +1 -0
- package/dist/cjs/adapters/memory/index.cjs +2 -0
- package/dist/cjs/adapters/memory/index.cjs.map +1 -0
- package/dist/cjs/adapters/node/index.cjs +2 -0
- package/dist/cjs/adapters/node/index.cjs.map +1 -0
- package/dist/cjs/chunks/browser-http-transport-BBF8uw-f.cjs +2 -0
- package/dist/cjs/chunks/browser-http-transport-BBF8uw-f.cjs.map +1 -0
- package/dist/cjs/chunks/context-BcoAzPuU.cjs +2 -0
- package/dist/cjs/chunks/context-BcoAzPuU.cjs.map +1 -0
- package/dist/cjs/chunks/error-DL4SHCBJ.cjs +2 -0
- package/dist/cjs/chunks/error-DL4SHCBJ.cjs.map +1 -0
- package/dist/cjs/chunks/error-DN8Vnwr4.cjs +2 -0
- package/dist/cjs/chunks/error-DN8Vnwr4.cjs.map +1 -0
- package/dist/cjs/chunks/index-iUd-bwwm.cjs +2 -0
- package/dist/cjs/chunks/index-iUd-bwwm.cjs.map +1 -0
- package/dist/cjs/chunks/logger-Cz9r6yt5.cjs +2 -0
- package/dist/cjs/chunks/logger-Cz9r6yt5.cjs.map +1 -0
- package/dist/cjs/chunks/lru-cache-1OU7JhD8.cjs +2 -0
- package/dist/cjs/chunks/lru-cache-1OU7JhD8.cjs.map +1 -0
- package/dist/cjs/chunks/memory-http-transport-DGll7Af4.cjs +2 -0
- package/dist/cjs/chunks/memory-http-transport-DGll7Af4.cjs.map +1 -0
- package/dist/cjs/chunks/merge-base-DlGWnkxP.cjs +2 -0
- package/dist/cjs/chunks/merge-base-DlGWnkxP.cjs.map +1 -0
- package/dist/cjs/chunks/node-http-transport-CuOgJlws.cjs +2 -0
- package/dist/cjs/chunks/node-http-transport-CuOgJlws.cjs.map +1 -0
- package/dist/cjs/chunks/progress-CK7CT9vU.cjs +2 -0
- package/dist/cjs/chunks/progress-CK7CT9vU.cjs.map +1 -0
- package/dist/cjs/chunks/repository-Cbzk-Qwz.cjs +2 -0
- package/dist/cjs/chunks/repository-Cbzk-Qwz.cjs.map +1 -0
- package/dist/cjs/commands/index.cjs +2 -0
- package/dist/cjs/commands/index.cjs.map +1 -0
- package/dist/cjs/index.browser.cjs +2 -0
- package/dist/cjs/index.browser.cjs.map +1 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.default.cjs +2 -0
- package/dist/cjs/index.default.cjs.map +1 -0
- package/dist/cjs/index.node.cjs +2 -0
- package/dist/cjs/index.node.cjs.map +1 -0
- package/dist/cjs/operators/index.cjs +2 -0
- package/dist/cjs/operators/index.cjs.map +1 -0
- package/dist/cjs/primitives/index.cjs +2 -0
- package/dist/cjs/primitives/index.cjs.map +1 -0
- package/dist/cjs/transport/index.cjs +2 -0
- package/dist/cjs/transport/index.cjs.map +1 -0
- package/dist/esm/adapters/browser/index.js +2 -0
- package/dist/esm/adapters/browser/index.js.map +1 -0
- package/dist/esm/adapters/memory/index.js +2 -0
- package/dist/esm/adapters/memory/index.js.map +1 -0
- package/dist/esm/adapters/node/index.js +2 -0
- package/dist/esm/adapters/node/index.js.map +1 -0
- package/dist/esm/chunks/browser-http-transport-CRPPmib5.js +2 -0
- package/dist/esm/chunks/browser-http-transport-CRPPmib5.js.map +1 -0
- package/dist/esm/chunks/context-CumKOV7K.js +2 -0
- package/dist/esm/chunks/context-CumKOV7K.js.map +1 -0
- package/dist/esm/chunks/error-CAlAXhN3.js +2 -0
- package/dist/esm/chunks/error-CAlAXhN3.js.map +1 -0
- package/dist/esm/chunks/error-DVZkS_ub.js +2 -0
- package/dist/esm/chunks/error-DVZkS_ub.js.map +1 -0
- package/dist/esm/chunks/index-gUdap5AF.js +2 -0
- package/dist/esm/chunks/index-gUdap5AF.js.map +1 -0
- package/dist/esm/chunks/logger-Cg7fUh8D.js +2 -0
- package/dist/esm/chunks/logger-Cg7fUh8D.js.map +1 -0
- package/dist/esm/chunks/lru-cache-Cy7C7Lx2.js +2 -0
- package/dist/esm/chunks/lru-cache-Cy7C7Lx2.js.map +1 -0
- package/dist/esm/chunks/memory-http-transport-Cv1sbkCX.js +2 -0
- package/dist/esm/chunks/memory-http-transport-Cv1sbkCX.js.map +1 -0
- package/dist/esm/chunks/merge-base-opORz-S1.js +2 -0
- package/dist/esm/chunks/merge-base-opORz-S1.js.map +1 -0
- package/dist/esm/chunks/node-http-transport-CuXVJf0s.js +2 -0
- package/dist/esm/chunks/node-http-transport-CuXVJf0s.js.map +1 -0
- package/dist/esm/chunks/progress-OxUHmDV4.js +2 -0
- package/dist/esm/chunks/progress-OxUHmDV4.js.map +1 -0
- package/dist/esm/chunks/repository-BaEhU6zt.js +2 -0
- package/dist/esm/chunks/repository-BaEhU6zt.js.map +1 -0
- package/dist/esm/commands/index.js +2 -0
- package/dist/esm/commands/index.js.map +1 -0
- package/dist/esm/index.browser.js +2 -0
- package/dist/esm/index.browser.js.map +1 -0
- package/dist/esm/index.default.js +2 -0
- package/dist/esm/index.default.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.node.js +2 -0
- package/dist/esm/index.node.js.map +1 -0
- package/dist/esm/operators/index.js +2 -0
- package/dist/esm/operators/index.js.map +1 -0
- package/dist/esm/primitives/index.js +2 -0
- package/dist/esm/primitives/index.js.map +1 -0
- package/dist/esm/transport/index.js +2 -0
- package/dist/esm/transport/index.js.map +1 -0
- package/dist/types/adapters/browser/index.d.cts +67 -0
- package/dist/types/adapters/browser/index.d.ts +67 -0
- package/dist/types/adapters/memory/index.d.cts +95 -0
- package/dist/types/adapters/memory/index.d.ts +95 -0
- package/dist/types/adapters/node/index.d.cts +75 -0
- package/dist/types/adapters/node/index.d.ts +75 -0
- package/dist/types/chunks/context-C6df52Qs.d.ts +354 -0
- package/dist/types/chunks/context-Ku1aP8Ie.d.cts +354 -0
- package/dist/types/chunks/diff-change-BwO75AgS.d.cts +59 -0
- package/dist/types/chunks/diff-change-CUWN3OSK.d.ts +59 -0
- package/dist/types/chunks/http-transport--_NdQOiw.d.cts +20 -0
- package/dist/types/chunks/http-transport--_NdQOiw.d.ts +20 -0
- package/dist/types/chunks/repository-BBKJnr8a.d.ts +89 -0
- package/dist/types/chunks/repository-Cv4Y0T9t.d.cts +89 -0
- package/dist/types/commands/index.d.cts +336 -0
- package/dist/types/commands/index.d.ts +336 -0
- package/dist/types/index.browser.d.cts +26 -0
- package/dist/types/index.browser.d.ts +26 -0
- package/dist/types/index.d.cts +68 -0
- package/dist/types/index.d.ts +68 -0
- package/dist/types/index.default.d.cts +35 -0
- package/dist/types/index.default.d.ts +35 -0
- package/dist/types/index.node.d.cts +23 -0
- package/dist/types/index.node.d.ts +23 -0
- package/dist/types/operators/index.d.cts +36 -0
- package/dist/types/operators/index.d.ts +36 -0
- package/dist/types/primitives/index.d.cts +217 -0
- package/dist/types/primitives/index.d.ts +217 -0
- package/dist/types/transport/index.d.cts +62 -0
- package/dist/types/transport/index.d.ts +62 -0
- package/package.json +524 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { H as HttpTransport } from './http-transport--_NdQOiw.cjs';
|
|
2
|
+
|
|
3
|
+
interface InflateStreamResult {
|
|
4
|
+
/** The fully-inflated output bytes. */
|
|
5
|
+
readonly output: Uint8Array;
|
|
6
|
+
/** The number of input bytes consumed, counted from `offset`. */
|
|
7
|
+
readonly bytesConsumed: number;
|
|
8
|
+
}
|
|
9
|
+
interface Compressor {
|
|
10
|
+
/** Deflate (compress) data using zlib deflate format (RFC 1950). */
|
|
11
|
+
readonly deflate: (data: Uint8Array) => Promise<Uint8Array>;
|
|
12
|
+
/** Inflate (decompress) zlib-compressed data. */
|
|
13
|
+
readonly inflate: (data: Uint8Array) => Promise<Uint8Array>;
|
|
14
|
+
/**
|
|
15
|
+
* Inflate one zlib stream starting at `offset` in `bytes`, stopping at the
|
|
16
|
+
* zlib terminator. Used by the pack-file resolver, where each entry is a
|
|
17
|
+
* separate zlib stream concatenated with other entries; the resolver does
|
|
18
|
+
* not know the compressed length of a single entry a priori.
|
|
19
|
+
*
|
|
20
|
+
* Returns the inflated output and the number of input bytes consumed
|
|
21
|
+
* (measured from `offset`). Throws DECOMPRESS_FAILED when the input at
|
|
22
|
+
* `offset` is not a valid zlib stream.
|
|
23
|
+
*/
|
|
24
|
+
readonly streamInflate: (bytes: Uint8Array, offset: number) => Promise<InflateStreamResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Create a streaming inflate transform.
|
|
27
|
+
* Returns a TransformStream that inflates chunks incrementally.
|
|
28
|
+
* Used for large packfile entries to avoid buffering entire objects.
|
|
29
|
+
*/
|
|
30
|
+
readonly createInflateStream: () => TransformStream<Uint8Array, Uint8Array>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Metadata returned by stat operations. */
|
|
34
|
+
interface FileStat {
|
|
35
|
+
readonly ctimeMs: number;
|
|
36
|
+
readonly mtimeMs: number;
|
|
37
|
+
readonly dev: number;
|
|
38
|
+
readonly ino: number;
|
|
39
|
+
readonly mode: number;
|
|
40
|
+
readonly uid: number;
|
|
41
|
+
readonly gid: number;
|
|
42
|
+
readonly size: number;
|
|
43
|
+
readonly isFile: boolean;
|
|
44
|
+
readonly isDirectory: boolean;
|
|
45
|
+
readonly isSymbolicLink: boolean;
|
|
46
|
+
/** Nanosecond-precision ctime. Populated by Node adapter (fs.stat({ bigint: true })). Undefined on platforms without ns support. */
|
|
47
|
+
readonly ctimeNs?: bigint;
|
|
48
|
+
/** Nanosecond-precision mtime. Populated by Node adapter. Undefined on platforms without ns support. */
|
|
49
|
+
readonly mtimeNs?: bigint;
|
|
50
|
+
}
|
|
51
|
+
/** A single entry from a directory listing. */
|
|
52
|
+
interface DirEntry {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly isFile: boolean;
|
|
55
|
+
readonly isDirectory: boolean;
|
|
56
|
+
readonly isSymbolicLink: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Minimal subset of Node's `fs/promises` FileHandle. Returned by `openWithNoFollow`.
|
|
60
|
+
*
|
|
61
|
+
* Lifetime: callers MUST `close()` the handle in a `finally` block. Holding handles open
|
|
62
|
+
* across async boundaries can leak file descriptors on Node — keep usage tight.
|
|
63
|
+
*/
|
|
64
|
+
interface FileHandle {
|
|
65
|
+
/** Read up to `length` bytes into `buffer` at `offset` (in the buffer). */
|
|
66
|
+
readonly read: (buffer: Uint8Array, offset: number, length: number, position?: number) => Promise<number>;
|
|
67
|
+
/** Write the buffer to the file. */
|
|
68
|
+
readonly write: (buffer: Uint8Array) => Promise<void>;
|
|
69
|
+
/** Stat the open file (cheap — uses fstat on Node). */
|
|
70
|
+
readonly stat: () => Promise<FileStat>;
|
|
71
|
+
/** Release the underlying file descriptor. Idempotent — safe to call twice. */
|
|
72
|
+
readonly close: () => Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
interface FileSystem {
|
|
75
|
+
/** Read entire file as bytes. Throws FILE_NOT_FOUND if not found. */
|
|
76
|
+
readonly read: (path: string) => Promise<Uint8Array>;
|
|
77
|
+
/** Read a byte slice from a file at the given offset. Throws FILE_NOT_FOUND if not found. */
|
|
78
|
+
readonly readSlice: (path: string, offset: number, length: number) => Promise<Uint8Array>;
|
|
79
|
+
/** Read entire file as UTF-8 string. Throws FILE_NOT_FOUND if not found. */
|
|
80
|
+
readonly readUtf8: (path: string) => Promise<string>;
|
|
81
|
+
/** Write bytes to file, creating parent directories as needed. Overwrites if exists. */
|
|
82
|
+
readonly write: (path: string, data: Uint8Array) => Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Write bytes to file. Fails with FILE_EXISTS if the file already exists (exclusive create).
|
|
85
|
+
*
|
|
86
|
+
* Contract obligations (Phase 7 §14.17):
|
|
87
|
+
* - **Parent-directory creation:** the adapter MUST ensure parent directories exist before the
|
|
88
|
+
* exclusive write. Equivalent to `mkdir -p dirname(path)` before `open(path, O_EXCL)`. If the
|
|
89
|
+
* parent is removed between the implicit mkdir and the open (e.g. concurrent `git gc` prunes
|
|
90
|
+
* the fanout), the adapter retries once: re-create the parent, re-attempt the open. On a second
|
|
91
|
+
* ENOENT the error propagates as FILE_NOT_FOUND.
|
|
92
|
+
* - **Symlink-safe ancestor check:** the adapter MUST reject writes where any ancestor directory
|
|
93
|
+
* of `path` is a symbolic link whose resolved target is outside the containment root. This
|
|
94
|
+
* closes the attack where an attacker replaces `objects/xx/` with a symlink pointing elsewhere.
|
|
95
|
+
* Implementation: lstat-walk the ancestor chain, or use `openat`-style relative opens.
|
|
96
|
+
*/
|
|
97
|
+
readonly writeExclusive: (path: string, data: Uint8Array) => Promise<void>;
|
|
98
|
+
/** Write UTF-8 string to file, creating parent directories as needed. */
|
|
99
|
+
readonly writeUtf8: (path: string, content: string) => Promise<void>;
|
|
100
|
+
/** Check if path exists. */
|
|
101
|
+
readonly exists: (path: string) => Promise<boolean>;
|
|
102
|
+
/** Get file/directory metadata. Throws FILE_NOT_FOUND if not found. Follows symlinks. */
|
|
103
|
+
readonly stat: (path: string) => Promise<FileStat>;
|
|
104
|
+
/** Get file/directory metadata. Throws FILE_NOT_FOUND if not found. Does NOT follow symlinks. */
|
|
105
|
+
readonly lstat: (path: string) => Promise<FileStat>;
|
|
106
|
+
/** List directory entries. Throws NOT_A_DIRECTORY if not a directory. */
|
|
107
|
+
readonly readdir: (path: string) => Promise<ReadonlyArray<DirEntry>>;
|
|
108
|
+
/** Create directory and all parents. No-op if already exists. */
|
|
109
|
+
readonly mkdir: (path: string) => Promise<void>;
|
|
110
|
+
/** Remove file or empty directory. Throws FILE_NOT_FOUND if not found. */
|
|
111
|
+
readonly rm: (path: string) => Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Rename `src` to `dst`. Atomic where the platform supports it (Node: yes on POSIX;
|
|
114
|
+
* Browser OPFS: no — emulated as read + write + rm, caller must tolerate partial
|
|
115
|
+
* failure between steps). Both paths must be on the same logical root.
|
|
116
|
+
*/
|
|
117
|
+
readonly rename: (src: string, dst: string) => Promise<void>;
|
|
118
|
+
/** Read the target of a symbolic link. Throws FILE_NOT_FOUND if not a symlink. */
|
|
119
|
+
readonly readlink: (path: string) => Promise<string>;
|
|
120
|
+
/** Create a symbolic link. Creates parent directories as needed. */
|
|
121
|
+
readonly symlink: (target: string, path: string) => Promise<void>;
|
|
122
|
+
/** Set file permissions. No-op on platforms without permission support (OPFS). */
|
|
123
|
+
readonly chmod: (path: string, mode: number) => Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Recursively remove a file or directory tree.
|
|
126
|
+
*
|
|
127
|
+
* Idempotent: a missing path returns void (no error).
|
|
128
|
+
*
|
|
129
|
+
* Symlink-safe: does NOT follow symlinks during traversal. When a directory entry is a
|
|
130
|
+
* symlink, the symlink itself is removed (the link, not its target), and the walk does
|
|
131
|
+
* not descend into it. This prevents an attacker who plants a symlink under a doomed
|
|
132
|
+
* directory from having `rmRecursive` reach outside the containment root.
|
|
133
|
+
*/
|
|
134
|
+
readonly rmRecursive: (path: string) => Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Open a file with the platform equivalent of `O_NOFOLLOW` — refuses to open the path
|
|
137
|
+
* if its leaf is a symbolic link. Used by callers that must read/write a regular file
|
|
138
|
+
* without crossing a symlink hop (e.g., lockfile creation under the git dir).
|
|
139
|
+
*
|
|
140
|
+
* - Node: `fs.open(path, O_NOFOLLOW | (mode === 'write' ? O_WRONLY : O_RDONLY))`.
|
|
141
|
+
* - Memory: rejects with `PERMISSION_DENIED` when the leaf is a memory symlink entry.
|
|
142
|
+
* - Browser OPFS: throws `UNSUPPORTED_OPERATION` (OPFS has no symlinks; callers can
|
|
143
|
+
* fall back to a plain `read`/`write` because the no-follow guarantee holds vacuously).
|
|
144
|
+
*
|
|
145
|
+
* Throws `FILE_NOT_FOUND` if the leaf does not exist (in `read` mode).
|
|
146
|
+
* Throws `PERMISSION_DENIED` if the leaf is a symlink.
|
|
147
|
+
*/
|
|
148
|
+
readonly openWithNoFollow: (path: string, mode: 'read' | 'write') => Promise<FileHandle>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Incremental hash computation context. Single-use: consumed after digest. */
|
|
152
|
+
interface Hasher {
|
|
153
|
+
/** Feed data into the hash. Can be called multiple times before digest. Throws HASH_FAILED if called after digest/digestHex. */
|
|
154
|
+
readonly update: (data: Uint8Array) => void;
|
|
155
|
+
/** Finalize and return the raw digest bytes. Consumes the hasher — no further update/digest calls allowed. */
|
|
156
|
+
readonly digest: () => Promise<Uint8Array>;
|
|
157
|
+
/** Finalize and return the hex-encoded digest. Consumes the hasher — no further update/digest calls allowed. */
|
|
158
|
+
readonly digestHex: () => Promise<string>;
|
|
159
|
+
}
|
|
160
|
+
interface HashService {
|
|
161
|
+
/** Compute the digest of data in one shot. Returns raw bytes (20 for SHA-1, 32 for SHA-256). */
|
|
162
|
+
readonly hash: (data: Uint8Array) => Promise<Uint8Array>;
|
|
163
|
+
/** Compute the hex-encoded digest of data in one shot. */
|
|
164
|
+
readonly hashHex: (data: Uint8Array) => Promise<string>;
|
|
165
|
+
/** Create an incremental hasher for streaming hash computation. */
|
|
166
|
+
readonly createHasher: () => Hasher;
|
|
167
|
+
/** The hash algorithm name. */
|
|
168
|
+
readonly algorithm: 'sha1' | 'sha256';
|
|
169
|
+
/** Digest length in bytes (20 for SHA-1, 32 for SHA-256). */
|
|
170
|
+
readonly digestLength: 20 | 32;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
type ObjectId = string & {
|
|
174
|
+
readonly __brand: unique symbol;
|
|
175
|
+
};
|
|
176
|
+
declare const ObjectId: {
|
|
177
|
+
readonly from: (hex: string) => ObjectId;
|
|
178
|
+
readonly fromRaw: (bytes: Uint8Array) => ObjectId;
|
|
179
|
+
};
|
|
180
|
+
type RefName = string & {
|
|
181
|
+
readonly __brand: unique symbol;
|
|
182
|
+
};
|
|
183
|
+
declare const RefName: {
|
|
184
|
+
readonly from: (name: string) => RefName;
|
|
185
|
+
};
|
|
186
|
+
type FilePath = string & {
|
|
187
|
+
readonly __brand: unique symbol;
|
|
188
|
+
};
|
|
189
|
+
declare const FilePath: {
|
|
190
|
+
readonly from: (path: string) => FilePath;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
interface HashConfig {
|
|
194
|
+
readonly digestLength: 20 | 32;
|
|
195
|
+
readonly hexLength: 40 | 64;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
interface LruCache<V> {
|
|
199
|
+
get(key: string): V | undefined;
|
|
200
|
+
set(key: string, value: V, byteSize: number): void;
|
|
201
|
+
has(key: string): boolean;
|
|
202
|
+
delete(key: string): boolean;
|
|
203
|
+
clear(): void;
|
|
204
|
+
readonly currentSize: number;
|
|
205
|
+
readonly maxSize: number;
|
|
206
|
+
readonly entryCount: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* General-purpose level-based logger consumed by the facade and any cross-cutting
|
|
211
|
+
* concern (dispose, validation, lifecycle). Independent from the transport-tier
|
|
212
|
+
* `Logger` in `transport/types.ts`, which is event-based and HTTP-shaped.
|
|
213
|
+
*
|
|
214
|
+
* The facade wraps user-supplied loggers with sanitization at construction time
|
|
215
|
+
* (see Phase 10 design §8.5). Implementations should be tolerant of high call
|
|
216
|
+
* frequency and MUST NOT throw — a throwing logger crashes nothing.
|
|
217
|
+
*/
|
|
218
|
+
interface Logger {
|
|
219
|
+
readonly debug?: (message: string, context?: Readonly<Record<string, unknown>>) => void;
|
|
220
|
+
readonly info?: (message: string, context?: Readonly<Record<string, unknown>>) => void;
|
|
221
|
+
readonly warn?: (message: string, context?: Readonly<Record<string, unknown>>) => void;
|
|
222
|
+
readonly error?: (message: string, context?: Readonly<Record<string, unknown>>) => void;
|
|
223
|
+
}
|
|
224
|
+
/** No-op Logger — every level method is absent (callers use optional chaining). */
|
|
225
|
+
declare const noopLogger: Logger;
|
|
226
|
+
/**
|
|
227
|
+
* Wrap a user-supplied logger so every `message` + every string value in the
|
|
228
|
+
* `context` object passes through `sanitize()` (Phase 9 §4.7) before reaching
|
|
229
|
+
* the sink. Per design §8.5 the facade applies this at construction time so no
|
|
230
|
+
* downstream caller ever feeds raw control bytes to a user-controlled sink.
|
|
231
|
+
*
|
|
232
|
+
* Methods that the user did not supply are absent on the wrapper (preserves
|
|
233
|
+
* the optional-method contract). Throws from the underlying sink are caught
|
|
234
|
+
* and dropped — a faulty logger must not crash the operation.
|
|
235
|
+
*/
|
|
236
|
+
declare const wrapLoggerSanitizer: (logger: Logger) => Logger;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Progress reporter shape consumed by long-running commands. The facade
|
|
240
|
+
* (Phase 10) accepts a user-supplied implementation via
|
|
241
|
+
* `OpenRepositoryOptions.progress` and plumbs it onto `Context.progress`.
|
|
242
|
+
*
|
|
243
|
+
* Reporters are synchronous and fire-and-forget. The facade wraps every call
|
|
244
|
+
* site in try/catch; a throwing reporter never crashes the operation.
|
|
245
|
+
*/
|
|
246
|
+
interface ProgressReporter {
|
|
247
|
+
/**
|
|
248
|
+
* Called once before the first work unit of a sub-task. `op` is a stable
|
|
249
|
+
* internal identifier (e.g., 'clone:write-objects'). `total`, when known,
|
|
250
|
+
* lets consumers render a percentage; absent for indeterminate work.
|
|
251
|
+
*/
|
|
252
|
+
readonly start: (op: string, total?: number) => void;
|
|
253
|
+
/**
|
|
254
|
+
* Called periodically during the sub-task. `current` is the count of items
|
|
255
|
+
* processed so far; `total` may be undefined when not known. `text`, when
|
|
256
|
+
* provided, is sideband-style auxiliary text (sanitized by built-in reporters).
|
|
257
|
+
*/
|
|
258
|
+
readonly update: (op: string, current: number, total?: number, text?: string) => void;
|
|
259
|
+
/** Called when the sub-task completes (success OR failure). */
|
|
260
|
+
readonly end: (op: string) => void;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Repository physical layout — where the working tree and .git directory live.
|
|
265
|
+
* Renamed in Phase 10 from the previous `RepositoryConfig` (port-tier) to free that
|
|
266
|
+
* name for the facade-tier `RepositoryConfig` shape (auth/parallelism/etc.).
|
|
267
|
+
*/
|
|
268
|
+
interface RepositoryLayout {
|
|
269
|
+
/** Absolute path to the repository root (working tree). */
|
|
270
|
+
readonly workDir: string;
|
|
271
|
+
/** Absolute path to the .git directory (usually `${workDir}/.git`, but may differ for bare repos or worktrees). */
|
|
272
|
+
readonly gitDir: string;
|
|
273
|
+
/** Whether this is a bare repository. */
|
|
274
|
+
readonly bare: boolean;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Author / committer identity — Phase 9 §4.7 shape.
|
|
278
|
+
*/
|
|
279
|
+
interface AuthorIdentity {
|
|
280
|
+
readonly name: string;
|
|
281
|
+
readonly email: string;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Authentication strategy for transport — narrowed shape consumed by withAuth.
|
|
285
|
+
*/
|
|
286
|
+
type AuthStrategy = {
|
|
287
|
+
readonly type: 'bearer';
|
|
288
|
+
readonly token: string;
|
|
289
|
+
} | {
|
|
290
|
+
readonly type: 'basic';
|
|
291
|
+
readonly username: string;
|
|
292
|
+
readonly password: string;
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Facade-tier configuration. Phase 10 introduces this shape; it carries the
|
|
296
|
+
* auth/parallelism/SSRF/network options the facade plumbs into network-pipeline.
|
|
297
|
+
* All fields are optional — primitives and commands consult only the keys they need.
|
|
298
|
+
*/
|
|
299
|
+
interface RepositoryConfig {
|
|
300
|
+
readonly user?: AuthorIdentity;
|
|
301
|
+
readonly auth?: AuthStrategy;
|
|
302
|
+
/** Bounded parallelism for fan-out work. 1..32, default 8 (enforced by facade validation). */
|
|
303
|
+
readonly parallelism?: number;
|
|
304
|
+
readonly upstreamRef?: RefName;
|
|
305
|
+
readonly allowInsecure?: boolean;
|
|
306
|
+
readonly allowPrivateNetworks?: boolean;
|
|
307
|
+
readonly maxResponseBytes?: number;
|
|
308
|
+
readonly maxObjectsPerPack?: number;
|
|
309
|
+
readonly detectRenames?: boolean;
|
|
310
|
+
readonly breakStaleLockMs?: number;
|
|
311
|
+
readonly dnsResolver?: (host: string) => Promise<ReadonlyArray<string>>;
|
|
312
|
+
/** Hard cap on `dnsResolver` return-array length to bound resolver-amplification DoS. Default 64. */
|
|
313
|
+
readonly maxDnsResults?: number;
|
|
314
|
+
}
|
|
315
|
+
interface Context {
|
|
316
|
+
readonly fs: FileSystem;
|
|
317
|
+
readonly hash: HashService;
|
|
318
|
+
readonly compressor: Compressor;
|
|
319
|
+
readonly transport: HttpTransport;
|
|
320
|
+
readonly progress: ProgressReporter;
|
|
321
|
+
/** Repository physical layout. Required — every primitive needs gitDir/workDir. */
|
|
322
|
+
readonly layout: RepositoryLayout;
|
|
323
|
+
/** User-supplied working directory (may be a sub-path of layout.workDir). Defaults to layout.workDir when not set by the facade. */
|
|
324
|
+
readonly cwd: string;
|
|
325
|
+
/** Object serialization parameters (sha1 vs sha256 digest+hex sizes). */
|
|
326
|
+
readonly hashConfig: HashConfig;
|
|
327
|
+
/** Shared delta-base LRU cache; consumed by primitives' iterative delta walker. */
|
|
328
|
+
readonly deltaCache: LruCache<Uint8Array>;
|
|
329
|
+
/** Optional facade-tier configuration (auth, parallelism, SSRF, …). Populated by openRepository. */
|
|
330
|
+
readonly config?: RepositoryConfig;
|
|
331
|
+
/** Optional sanitized logger. Populated by openRepository. */
|
|
332
|
+
readonly logger?: Logger;
|
|
333
|
+
/** Optional abort signal for cancelling long-running operations. */
|
|
334
|
+
readonly signal?: AbortSignal;
|
|
335
|
+
}
|
|
336
|
+
interface CreateContextParts {
|
|
337
|
+
readonly fs: FileSystem;
|
|
338
|
+
readonly hash: HashService;
|
|
339
|
+
readonly compressor: Compressor;
|
|
340
|
+
readonly transport: HttpTransport;
|
|
341
|
+
readonly progress: ProgressReporter;
|
|
342
|
+
readonly layout: RepositoryLayout;
|
|
343
|
+
readonly cwd?: string;
|
|
344
|
+
readonly hashConfig: HashConfig;
|
|
345
|
+
readonly deltaCache: LruCache<Uint8Array>;
|
|
346
|
+
readonly config?: RepositoryConfig;
|
|
347
|
+
readonly logger?: Logger;
|
|
348
|
+
readonly signal?: AbortSignal;
|
|
349
|
+
}
|
|
350
|
+
/** Assemble a frozen Context from its constituent ports + layout. */
|
|
351
|
+
declare function createContext(parts: CreateContextParts): Context;
|
|
352
|
+
|
|
353
|
+
export { ObjectId as O, FilePath as b, createContext as i, RefName as j, noopLogger as n, wrapLoggerSanitizer as w };
|
|
354
|
+
export type { AuthStrategy as A, Compressor as C, DirEntry as D, FileSystem as F, HashService as H, InflateStreamResult as I, Logger as L, ProgressReporter as P, RepositoryConfig as R, Context as a, FileStat as c, FileHandle as d, Hasher as e, AuthorIdentity as f, CreateContextParts as g, RepositoryLayout as h };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { b as FilePath, O as ObjectId } from './context-Ku1aP8Ie.cjs';
|
|
2
|
+
|
|
3
|
+
interface AuthorIdentity {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly email: string;
|
|
6
|
+
readonly timestamp: number;
|
|
7
|
+
readonly timezoneOffset: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare const FILE_MODE: {
|
|
11
|
+
readonly REGULAR: "100644";
|
|
12
|
+
readonly EXECUTABLE: "100755";
|
|
13
|
+
readonly SYMLINK: "120000";
|
|
14
|
+
readonly DIRECTORY: "40000";
|
|
15
|
+
readonly GITLINK: "160000";
|
|
16
|
+
};
|
|
17
|
+
type FileMode = (typeof FILE_MODE)[keyof typeof FILE_MODE];
|
|
18
|
+
|
|
19
|
+
interface AddChange {
|
|
20
|
+
readonly type: 'add';
|
|
21
|
+
readonly newPath: FilePath;
|
|
22
|
+
readonly newId: ObjectId;
|
|
23
|
+
readonly newMode: FileMode;
|
|
24
|
+
}
|
|
25
|
+
interface DeleteChange {
|
|
26
|
+
readonly type: 'delete';
|
|
27
|
+
readonly oldPath: FilePath;
|
|
28
|
+
readonly oldId: ObjectId;
|
|
29
|
+
readonly oldMode: FileMode;
|
|
30
|
+
}
|
|
31
|
+
interface ModifyChange {
|
|
32
|
+
readonly type: 'modify';
|
|
33
|
+
readonly path: FilePath;
|
|
34
|
+
readonly oldId: ObjectId;
|
|
35
|
+
readonly newId: ObjectId;
|
|
36
|
+
readonly oldMode: FileMode;
|
|
37
|
+
readonly newMode: FileMode;
|
|
38
|
+
}
|
|
39
|
+
interface RenameChange {
|
|
40
|
+
readonly type: 'rename';
|
|
41
|
+
readonly oldPath: FilePath;
|
|
42
|
+
readonly newPath: FilePath;
|
|
43
|
+
readonly id: ObjectId;
|
|
44
|
+
readonly mode: FileMode;
|
|
45
|
+
}
|
|
46
|
+
interface TypeChangeChange {
|
|
47
|
+
readonly type: 'type-change';
|
|
48
|
+
readonly path: FilePath;
|
|
49
|
+
readonly oldId: ObjectId;
|
|
50
|
+
readonly newId: ObjectId;
|
|
51
|
+
readonly oldMode: FileMode;
|
|
52
|
+
readonly newMode: FileMode;
|
|
53
|
+
}
|
|
54
|
+
type DiffChange = AddChange | DeleteChange | ModifyChange | RenameChange | TypeChangeChange;
|
|
55
|
+
interface TreeDiff {
|
|
56
|
+
readonly changes: ReadonlyArray<DiffChange>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type { AuthorIdentity as A, FileMode as F, TreeDiff as T };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { b as FilePath, O as ObjectId } from './context-C6df52Qs.js';
|
|
2
|
+
|
|
3
|
+
interface AuthorIdentity {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly email: string;
|
|
6
|
+
readonly timestamp: number;
|
|
7
|
+
readonly timezoneOffset: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare const FILE_MODE: {
|
|
11
|
+
readonly REGULAR: "100644";
|
|
12
|
+
readonly EXECUTABLE: "100755";
|
|
13
|
+
readonly SYMLINK: "120000";
|
|
14
|
+
readonly DIRECTORY: "40000";
|
|
15
|
+
readonly GITLINK: "160000";
|
|
16
|
+
};
|
|
17
|
+
type FileMode = (typeof FILE_MODE)[keyof typeof FILE_MODE];
|
|
18
|
+
|
|
19
|
+
interface AddChange {
|
|
20
|
+
readonly type: 'add';
|
|
21
|
+
readonly newPath: FilePath;
|
|
22
|
+
readonly newId: ObjectId;
|
|
23
|
+
readonly newMode: FileMode;
|
|
24
|
+
}
|
|
25
|
+
interface DeleteChange {
|
|
26
|
+
readonly type: 'delete';
|
|
27
|
+
readonly oldPath: FilePath;
|
|
28
|
+
readonly oldId: ObjectId;
|
|
29
|
+
readonly oldMode: FileMode;
|
|
30
|
+
}
|
|
31
|
+
interface ModifyChange {
|
|
32
|
+
readonly type: 'modify';
|
|
33
|
+
readonly path: FilePath;
|
|
34
|
+
readonly oldId: ObjectId;
|
|
35
|
+
readonly newId: ObjectId;
|
|
36
|
+
readonly oldMode: FileMode;
|
|
37
|
+
readonly newMode: FileMode;
|
|
38
|
+
}
|
|
39
|
+
interface RenameChange {
|
|
40
|
+
readonly type: 'rename';
|
|
41
|
+
readonly oldPath: FilePath;
|
|
42
|
+
readonly newPath: FilePath;
|
|
43
|
+
readonly id: ObjectId;
|
|
44
|
+
readonly mode: FileMode;
|
|
45
|
+
}
|
|
46
|
+
interface TypeChangeChange {
|
|
47
|
+
readonly type: 'type-change';
|
|
48
|
+
readonly path: FilePath;
|
|
49
|
+
readonly oldId: ObjectId;
|
|
50
|
+
readonly newId: ObjectId;
|
|
51
|
+
readonly oldMode: FileMode;
|
|
52
|
+
readonly newMode: FileMode;
|
|
53
|
+
}
|
|
54
|
+
type DiffChange = AddChange | DeleteChange | ModifyChange | RenameChange | TypeChangeChange;
|
|
55
|
+
interface TreeDiff {
|
|
56
|
+
readonly changes: ReadonlyArray<DiffChange>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type { AuthorIdentity as A, FileMode as F, TreeDiff as T };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface HttpRequest {
|
|
2
|
+
readonly url: string;
|
|
3
|
+
readonly method: 'GET' | 'POST';
|
|
4
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
5
|
+
readonly body?: Uint8Array;
|
|
6
|
+
/** Optional abort signal for request cancellation. */
|
|
7
|
+
readonly signal?: AbortSignal;
|
|
8
|
+
}
|
|
9
|
+
interface HttpResponse {
|
|
10
|
+
readonly statusCode: number;
|
|
11
|
+
/** Response headers. All keys MUST be lowercased by the adapter. */
|
|
12
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
13
|
+
readonly body: ReadableStream<Uint8Array>;
|
|
14
|
+
}
|
|
15
|
+
interface HttpTransport {
|
|
16
|
+
/** Send an HTTP request and return the response. */
|
|
17
|
+
readonly request: (req: HttpRequest) => Promise<HttpResponse>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type { HttpTransport as H, HttpRequest as a, HttpResponse as b };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface HttpRequest {
|
|
2
|
+
readonly url: string;
|
|
3
|
+
readonly method: 'GET' | 'POST';
|
|
4
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
5
|
+
readonly body?: Uint8Array;
|
|
6
|
+
/** Optional abort signal for request cancellation. */
|
|
7
|
+
readonly signal?: AbortSignal;
|
|
8
|
+
}
|
|
9
|
+
interface HttpResponse {
|
|
10
|
+
readonly statusCode: number;
|
|
11
|
+
/** Response headers. All keys MUST be lowercased by the adapter. */
|
|
12
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
13
|
+
readonly body: ReadableStream<Uint8Array>;
|
|
14
|
+
}
|
|
15
|
+
interface HttpTransport {
|
|
16
|
+
/** Send an HTTP request and return the response. */
|
|
17
|
+
readonly request: (req: HttpRequest) => Promise<HttpResponse>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type { HttpTransport as H, HttpRequest as a, HttpResponse as b };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { add, branch, checkout, clone, commit, diff, fetch, init, log, merge, push, reset, revParse, rm, status, tag } from '../commands/index.js';
|
|
2
|
+
import { createCommit, diffTrees, getRepoRoot, mergeBase, readBlob, readIndex, readObject, readTree, resolveRef, updateRef, walkCommits, walkTree, writeObject, writeSymbolicRef, writeTree } from '../primitives/index.js';
|
|
3
|
+
import { F as FileSystem, H as HashService, C as Compressor, R as RepositoryConfig, L as Logger, P as ProgressReporter, a as Context } from './context-C6df52Qs.js';
|
|
4
|
+
import { H as HttpTransport } from './http-transport--_NdQOiw.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Helper that strips the leading `Context` parameter from a function type so
|
|
8
|
+
* the bound version on `Repository` exposes the user-facing signature.
|
|
9
|
+
*/
|
|
10
|
+
type BindCtx<F> = F extends (ctx: Context, ...rest: infer A) => infer R ? (...args: A) => R : never;
|
|
11
|
+
/**
|
|
12
|
+
* User-facing options passed to `openRepository`. Subset of the design's
|
|
13
|
+
* `OpenRepositoryOptions` that this Step 3 implementation honors. Every field
|
|
14
|
+
* is optional; the facade fills sensible defaults. Field-level validation runs
|
|
15
|
+
* eagerly before the Repository is returned (Phase 10 §8.1).
|
|
16
|
+
*/
|
|
17
|
+
interface OpenRepositoryOptions {
|
|
18
|
+
/** Working directory. Default: `process.cwd()` on Node, `'/'` on browser/memory. */
|
|
19
|
+
readonly cwd?: string;
|
|
20
|
+
/** Adapter overrides. Each is optional; missing slots fall back to runtime detection. */
|
|
21
|
+
readonly fs?: FileSystem;
|
|
22
|
+
readonly hash?: HashService;
|
|
23
|
+
readonly compressor?: Compressor;
|
|
24
|
+
readonly transport?: HttpTransport;
|
|
25
|
+
/** Repository config (auth, parallelism, SSRF allowlist, etc.). Frozen via deepFreeze. */
|
|
26
|
+
readonly config?: RepositoryConfig;
|
|
27
|
+
/** Logger for diagnostics. Wrapped to prevent mutation post-construction. */
|
|
28
|
+
readonly logger?: Logger;
|
|
29
|
+
/** Progress reporter; defaults to `noopProgress`. */
|
|
30
|
+
readonly progress?: ProgressReporter;
|
|
31
|
+
/** AbortSignal threaded into every bound method's ctx.signal. */
|
|
32
|
+
readonly signal?: AbortSignal;
|
|
33
|
+
/**
|
|
34
|
+
* Opt OUT of adapter validator wrapping for `fs` and `transport`. NEVER set
|
|
35
|
+
* with adapters whose code you do not control; a raw transport receives
|
|
36
|
+
* `config.auth` credentials with no SSRF guard.
|
|
37
|
+
*/
|
|
38
|
+
readonly unsafeRawAdapters?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The frozen repository handle returned by `openRepository`. Every command
|
|
42
|
+
* and primitive is bound to a Context constructed at facade-creation time;
|
|
43
|
+
* users never see Context except through `repo.ctx`.
|
|
44
|
+
*/
|
|
45
|
+
interface Repository {
|
|
46
|
+
readonly add: BindCtx<typeof add>;
|
|
47
|
+
readonly branch: BindCtx<typeof branch>;
|
|
48
|
+
readonly checkout: BindCtx<typeof checkout>;
|
|
49
|
+
readonly clone: BindCtx<typeof clone>;
|
|
50
|
+
readonly commit: BindCtx<typeof commit>;
|
|
51
|
+
readonly diff: BindCtx<typeof diff>;
|
|
52
|
+
readonly fetch: BindCtx<typeof fetch>;
|
|
53
|
+
readonly init: BindCtx<typeof init>;
|
|
54
|
+
readonly log: BindCtx<typeof log>;
|
|
55
|
+
readonly merge: BindCtx<typeof merge>;
|
|
56
|
+
readonly push: BindCtx<typeof push>;
|
|
57
|
+
readonly reset: BindCtx<typeof reset>;
|
|
58
|
+
readonly revParse: BindCtx<typeof revParse>;
|
|
59
|
+
readonly rm: BindCtx<typeof rm>;
|
|
60
|
+
readonly status: BindCtx<typeof status>;
|
|
61
|
+
readonly tag: BindCtx<typeof tag>;
|
|
62
|
+
readonly primitives: {
|
|
63
|
+
readonly createCommit: BindCtx<typeof createCommit>;
|
|
64
|
+
readonly diffTrees: BindCtx<typeof diffTrees>;
|
|
65
|
+
readonly getRepoRoot: BindCtx<typeof getRepoRoot>;
|
|
66
|
+
readonly mergeBase: BindCtx<typeof mergeBase>;
|
|
67
|
+
readonly readBlob: BindCtx<typeof readBlob>;
|
|
68
|
+
readonly readIndex: BindCtx<typeof readIndex>;
|
|
69
|
+
readonly readObject: BindCtx<typeof readObject>;
|
|
70
|
+
readonly readTree: BindCtx<typeof readTree>;
|
|
71
|
+
readonly resolveRef: BindCtx<typeof resolveRef>;
|
|
72
|
+
readonly updateRef: BindCtx<typeof updateRef>;
|
|
73
|
+
readonly walkCommits: BindCtx<typeof walkCommits>;
|
|
74
|
+
readonly walkTree: BindCtx<typeof walkTree>;
|
|
75
|
+
readonly writeObject: BindCtx<typeof writeObject>;
|
|
76
|
+
readonly writeSymbolicRef: BindCtx<typeof writeSymbolicRef>;
|
|
77
|
+
readonly writeTree: BindCtx<typeof writeTree>;
|
|
78
|
+
};
|
|
79
|
+
/** The frozen Context backing every binding. Exposed for advanced use. */
|
|
80
|
+
readonly ctx: Context;
|
|
81
|
+
/**
|
|
82
|
+
* Dispose the repository. Aborts `ctx.signal` synchronously, yields a
|
|
83
|
+
* macrotask, then runs `disposeAdapters`. Idempotent. After dispose
|
|
84
|
+
* resolves, every bound method throws `REPOSITORY_DISPOSED`.
|
|
85
|
+
*/
|
|
86
|
+
readonly dispose: () => Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type { OpenRepositoryOptions as O, Repository as R };
|