just-git 1.1.11 → 1.2.3
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/README.md +42 -181
- package/dist/{hooks-OMCbhUGB.d.ts → hooks-4DvkF2xT.d.ts} +159 -5
- package/dist/index.d.ts +63 -22
- package/dist/index.js +413 -382
- package/dist/repo/index.d.ts +27 -1
- package/dist/repo/index.js +13 -13
- package/dist/server/index.d.ts +74 -112
- package/dist/server/index.js +48 -25
- package/package.json +3 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as GitRepo, X as Rejection } from '../hooks-
|
|
1
|
+
import { f as GitRepo, X as Rejection } from '../hooks-4DvkF2xT.js';
|
|
2
2
|
|
|
3
3
|
interface GitServerConfig {
|
|
4
4
|
/**
|
|
@@ -37,6 +37,14 @@ interface GitServerConfig {
|
|
|
37
37
|
/** Delta window size (default 10). Smaller = faster, worse compression ratio. */
|
|
38
38
|
deltaWindow?: number;
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Called when the server catches an unhandled error.
|
|
42
|
+
*
|
|
43
|
+
* Defaults to logging `err.message` (no stack trace) to `console.error`.
|
|
44
|
+
* Override to integrate with your own logging, or set to `false` to
|
|
45
|
+
* suppress all error output.
|
|
46
|
+
*/
|
|
47
|
+
onError?: false | ((err: unknown, request: Request) => void);
|
|
40
48
|
}
|
|
41
49
|
interface GitServer {
|
|
42
50
|
/** Standard fetch-API handler: (Request) => Response */
|
|
@@ -67,32 +75,43 @@ interface ServerHooks {
|
|
|
67
75
|
*/
|
|
68
76
|
advertiseRefs?: (event: AdvertiseRefsEvent) => RefAdvertisement[] | void | Promise<RefAdvertisement[] | void>;
|
|
69
77
|
}
|
|
78
|
+
/** A single ref update within a push. */
|
|
70
79
|
interface RefUpdate {
|
|
80
|
+
/** Full ref name, e.g. "refs/heads/main". */
|
|
71
81
|
ref: string;
|
|
82
|
+
/** Previous hash, or null if creating a new ref. */
|
|
72
83
|
oldHash: string | null;
|
|
84
|
+
/** New hash being pushed. */
|
|
73
85
|
newHash: string;
|
|
86
|
+
/** Whether the update is a fast-forward. */
|
|
74
87
|
isFF: boolean;
|
|
88
|
+
/** Whether this creates a new ref. */
|
|
75
89
|
isCreate: boolean;
|
|
90
|
+
/** Whether this deletes an existing ref. */
|
|
76
91
|
isDelete: boolean;
|
|
77
92
|
}
|
|
93
|
+
/** Fired after objects are unpacked but before refs are updated. */
|
|
78
94
|
interface PreReceiveEvent {
|
|
79
95
|
repo: GitRepo;
|
|
80
96
|
repoPath: string;
|
|
81
97
|
updates: readonly RefUpdate[];
|
|
82
98
|
request: Request;
|
|
83
99
|
}
|
|
100
|
+
/** Fired per-ref after preReceive passes. */
|
|
84
101
|
interface UpdateEvent {
|
|
85
102
|
repo: GitRepo;
|
|
86
103
|
repoPath: string;
|
|
87
104
|
update: RefUpdate;
|
|
88
105
|
request: Request;
|
|
89
106
|
}
|
|
107
|
+
/** Fired after all ref updates succeed. */
|
|
90
108
|
interface PostReceiveEvent {
|
|
91
109
|
repo: GitRepo;
|
|
92
110
|
repoPath: string;
|
|
93
111
|
updates: readonly RefUpdate[];
|
|
94
112
|
request: Request;
|
|
95
113
|
}
|
|
114
|
+
/** Fired during ref advertisement (info/refs). */
|
|
96
115
|
interface AdvertiseRefsEvent {
|
|
97
116
|
repo: GitRepo;
|
|
98
117
|
repoPath: string;
|
|
@@ -100,6 +119,7 @@ interface AdvertiseRefsEvent {
|
|
|
100
119
|
service: "git-upload-pack" | "git-receive-pack";
|
|
101
120
|
request: Request;
|
|
102
121
|
}
|
|
122
|
+
/** A ref name and hash advertised to clients during fetch/push discovery. */
|
|
103
123
|
interface RefAdvertisement {
|
|
104
124
|
name: string;
|
|
105
125
|
hash: string;
|
|
@@ -161,94 +181,33 @@ declare function toNodeHandler(server: GitServer): (req: NodeHttpRequest, res: N
|
|
|
161
181
|
declare function composeHooks(...hookSets: (ServerHooks | undefined)[]): ServerHooks;
|
|
162
182
|
|
|
163
183
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* Each operation accepts a `GitRepo` (ObjectStore + RefStore)
|
|
167
|
-
* and returns protocol-level results. The handler layer is
|
|
168
|
-
* responsible for hook invocation and ref application.
|
|
184
|
+
* Opinionated hook presets built on top of the minimal ServerHooks interface.
|
|
169
185
|
*/
|
|
170
186
|
|
|
171
|
-
|
|
172
|
-
packData: Uint8Array;
|
|
173
|
-
objectCount: number;
|
|
174
|
-
deltaCount: number;
|
|
175
|
-
}
|
|
187
|
+
type ResolveRepo = GitServerConfig["resolveRepo"];
|
|
176
188
|
/**
|
|
177
|
-
*
|
|
189
|
+
* Wrap a `resolveRepo` function with an authorization check that
|
|
190
|
+
* gates **all** access (clone, fetch, and push).
|
|
178
191
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
192
|
+
* The `authorize` callback receives the raw `Request` and returns:
|
|
193
|
+
* - `true` — request is allowed, delegate to the inner `resolveRepo`
|
|
194
|
+
* - `false` — respond with 403 Forbidden
|
|
195
|
+
* - `Response` — send as-is (e.g. 401 with `WWW-Authenticate` header)
|
|
182
196
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* the want set on the next client request, producing a cache miss.
|
|
186
|
-
*/
|
|
187
|
-
declare class PackCache {
|
|
188
|
-
private entries;
|
|
189
|
-
private currentBytes;
|
|
190
|
-
private maxBytes;
|
|
191
|
-
private hits;
|
|
192
|
-
private misses;
|
|
193
|
-
constructor(maxBytes?: number);
|
|
194
|
-
/** Build a cache key. Returns null for requests with haves (not cacheable). */
|
|
195
|
-
static key(repoPath: string, wants: string[], haves: string[]): string | null;
|
|
196
|
-
get(key: string): PackCacheEntry | undefined;
|
|
197
|
-
set(key: string, entry: PackCacheEntry): void;
|
|
198
|
-
get stats(): {
|
|
199
|
-
entries: number;
|
|
200
|
-
bytes: number;
|
|
201
|
-
hits: number;
|
|
202
|
-
misses: number;
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
interface RefsData {
|
|
206
|
-
refs: RefAdvertisement[];
|
|
207
|
-
headTarget?: string;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Collect the structured ref list from a repo (no wire encoding).
|
|
211
|
-
* The handler can pass this through an advertiseRefs hook to filter,
|
|
212
|
-
* then call `buildRefAdvertisementBytes` to produce the wire format.
|
|
213
|
-
*/
|
|
214
|
-
declare function collectRefs(repo: GitRepo): Promise<RefsData>;
|
|
215
|
-
/**
|
|
216
|
-
* Build the wire-format ref advertisement from a (possibly filtered) ref list.
|
|
217
|
-
*/
|
|
218
|
-
declare function buildRefAdvertisementBytes(refs: RefAdvertisement[], service: "git-upload-pack" | "git-receive-pack", headTarget?: string): Uint8Array;
|
|
219
|
-
interface UploadPackOptions {
|
|
220
|
-
/** Pack cache instance. When provided, full clones (no haves) are cached. */
|
|
221
|
-
cache?: PackCache;
|
|
222
|
-
/** Repo path used as part of the cache key. Required when cache is set. */
|
|
223
|
-
cacheKey?: string;
|
|
224
|
-
/** Skip delta compression — faster pack generation, larger output. */
|
|
225
|
-
noDelta?: boolean;
|
|
226
|
-
/** Delta window size (default 10). Ignored when noDelta is true. */
|
|
227
|
-
deltaWindow?: number;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Handle a `POST /git-upload-pack` request.
|
|
197
|
+
* For push-only authorization, use `createStandardHooks({ authorizePush })`.
|
|
198
|
+
* The two compose naturally:
|
|
231
199
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Ingest a receive-pack request: parse commands, ingest the packfile,
|
|
243
|
-
* and compute enriched RefUpdate objects. Does NOT apply ref updates —
|
|
244
|
-
* the handler runs hooks first, then applies surviving updates.
|
|
245
|
-
*/
|
|
246
|
-
declare function ingestReceivePack(repo: GitRepo, requestBody: Uint8Array): Promise<ReceivePackResult>;
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Opinionated hook presets built on top of the minimal ServerHooks interface.
|
|
200
|
+
* ```ts
|
|
201
|
+
* const server = createGitServer({
|
|
202
|
+
* resolveRepo: withAuth(
|
|
203
|
+
* (req) => req.headers.get("Authorization") === `Bearer ${token}`,
|
|
204
|
+
* (repoPath) => storage.repo(repoPath),
|
|
205
|
+
* ),
|
|
206
|
+
* hooks: createStandardHooks({ protectedBranches: ["main"] }),
|
|
207
|
+
* });
|
|
208
|
+
* ```
|
|
250
209
|
*/
|
|
251
|
-
|
|
210
|
+
declare function withAuth(authorize: (request: Request) => boolean | Response | Promise<boolean | Response>, resolveRepo: ResolveRepo): ResolveRepo;
|
|
252
211
|
interface StandardHooksConfig {
|
|
253
212
|
/** Branches that cannot be force-pushed to or deleted. */
|
|
254
213
|
protectedBranches?: string[];
|
|
@@ -275,7 +234,7 @@ declare function createStandardHooks(config: StandardHooksConfig): ServerHooks;
|
|
|
275
234
|
/**
|
|
276
235
|
* Abstract storage backend for multi-repo git object and ref storage.
|
|
277
236
|
*
|
|
278
|
-
* Implemented by `
|
|
237
|
+
* Implemented by `BunSqliteStorage`, `BetterSqlite3Storage`, and `PgStorage`.
|
|
279
238
|
*/
|
|
280
239
|
interface Storage {
|
|
281
240
|
/** Get a `GitRepo` scoped to a specific repo. */
|
|
@@ -306,76 +265,79 @@ declare class MemoryStorage implements Storage {
|
|
|
306
265
|
private getRefs;
|
|
307
266
|
}
|
|
308
267
|
|
|
309
|
-
interface
|
|
268
|
+
/** Minimal prepared statement interface matching `bun:sqlite`. */
|
|
269
|
+
interface BunSqliteStatement {
|
|
310
270
|
run(...params: any[]): void;
|
|
311
271
|
get(...params: any[]): any;
|
|
312
272
|
all(...params: any[]): any[];
|
|
313
273
|
}
|
|
314
|
-
interface
|
|
274
|
+
/** Minimal database interface matching `bun:sqlite`'s `Database` class. */
|
|
275
|
+
interface BunSqliteDatabase {
|
|
315
276
|
run(sql: string): void;
|
|
316
|
-
prepare(sql: string):
|
|
277
|
+
prepare(sql: string): BunSqliteStatement;
|
|
317
278
|
transaction<F extends (...args: any[]) => any>(fn: F): (...args: Parameters<F>) => ReturnType<F>;
|
|
318
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* SQLite-backed git storage using `bun:sqlite`.
|
|
282
|
+
*
|
|
283
|
+
* ```ts
|
|
284
|
+
* import { Database } from "bun:sqlite";
|
|
285
|
+
* const storage = new BunSqliteStorage(new Database("repos.db"));
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
declare class BunSqliteStorage implements Storage {
|
|
289
|
+
private db;
|
|
290
|
+
private stmts;
|
|
291
|
+
private ingestTx;
|
|
292
|
+
constructor(db: BunSqliteDatabase);
|
|
293
|
+
repo(repoId: string): GitRepo;
|
|
294
|
+
deleteRepo(repoId: string): Promise<void>;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Minimal prepared statement interface matching `better-sqlite3`. */
|
|
319
298
|
interface BetterSqlite3Statement {
|
|
320
299
|
run(...params: any[]): any;
|
|
321
300
|
get(...params: any[]): any;
|
|
322
301
|
all(...params: any[]): any[];
|
|
323
302
|
}
|
|
303
|
+
/** Minimal database interface matching the `better-sqlite3` `Database` class. */
|
|
324
304
|
interface BetterSqlite3Database {
|
|
325
305
|
exec(sql: string): any;
|
|
326
306
|
prepare(sql: string): BetterSqlite3Statement;
|
|
327
307
|
transaction<F extends (...args: any[]) => any>(fn: F): (...args: Parameters<F>) => ReturnType<F>;
|
|
328
308
|
}
|
|
329
309
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* Adapts `exec` → `run` and coerces `get` results from `undefined`
|
|
333
|
-
* to `null` to match the `bun:sqlite` convention.
|
|
310
|
+
* SQLite-backed git storage using `better-sqlite3`.
|
|
334
311
|
*
|
|
335
312
|
* ```ts
|
|
336
313
|
* import Database from "better-sqlite3";
|
|
337
|
-
* const
|
|
338
|
-
* const storage = new SqliteStorage(db);
|
|
314
|
+
* const storage = new BetterSqlite3Storage(new Database("repos.db"));
|
|
339
315
|
* ```
|
|
340
316
|
*/
|
|
341
|
-
declare
|
|
342
|
-
/**
|
|
343
|
-
* SQLite-backed git storage with multi-repo support.
|
|
344
|
-
*
|
|
345
|
-
* Creates and manages `git_objects` and `git_refs` tables in the
|
|
346
|
-
* provided database. Multiple repos are partitioned by `repo_id`.
|
|
347
|
-
*
|
|
348
|
-
* ```ts
|
|
349
|
-
* const db = new Database("repos.sqlite");
|
|
350
|
-
* const storage = new SqliteStorage(db);
|
|
351
|
-
* const server = createGitServer({
|
|
352
|
-
* resolve: async (repoPath) => storage.repo(repoPath),
|
|
353
|
-
* });
|
|
354
|
-
* ```
|
|
355
|
-
*/
|
|
356
|
-
declare class SqliteStorage implements Storage {
|
|
317
|
+
declare class BetterSqlite3Storage implements Storage {
|
|
357
318
|
private db;
|
|
358
319
|
private stmts;
|
|
359
320
|
private ingestTx;
|
|
360
|
-
constructor(db:
|
|
361
|
-
/** Get a `GitRepo` scoped to a specific repo. */
|
|
321
|
+
constructor(db: BetterSqlite3Database);
|
|
362
322
|
repo(repoId: string): GitRepo;
|
|
363
|
-
/** Delete all objects and refs for a repo. */
|
|
364
323
|
deleteRepo(repoId: string): Promise<void>;
|
|
365
324
|
}
|
|
366
325
|
|
|
326
|
+
/** Minimal database interface for PostgreSQL. Use {@link wrapPgPool} to adapt a `pg` Pool. */
|
|
367
327
|
interface PgDatabase {
|
|
368
328
|
query<T = any>(text: string, values?: any[]): Promise<{
|
|
369
329
|
rows: T[];
|
|
370
330
|
}>;
|
|
371
331
|
transaction<R>(fn: (tx: PgDatabase) => Promise<R>): Promise<R>;
|
|
372
332
|
}
|
|
333
|
+
/** Minimal pool interface matching the `pg` package's `Pool` class. */
|
|
373
334
|
interface PgPool {
|
|
374
335
|
query(text: string, values?: any[]): Promise<{
|
|
375
336
|
rows: any[];
|
|
376
337
|
}>;
|
|
377
338
|
connect(): Promise<PgPoolClient>;
|
|
378
339
|
}
|
|
340
|
+
/** Minimal pool client interface matching the `pg` package's `PoolClient`. */
|
|
379
341
|
interface PgPoolClient {
|
|
380
342
|
query(text: string, values?: any[]): Promise<{
|
|
381
343
|
rows: any[];
|
|
@@ -421,4 +383,4 @@ declare class PgStorage implements Storage {
|
|
|
421
383
|
deleteRepo(repoId: string): Promise<void>;
|
|
422
384
|
}
|
|
423
385
|
|
|
424
|
-
export { type AdvertiseRefsEvent, type BetterSqlite3Database, type BetterSqlite3Statement, type
|
|
386
|
+
export { type AdvertiseRefsEvent, type BetterSqlite3Database, type BetterSqlite3Statement, BetterSqlite3Storage, type BunSqliteDatabase, type BunSqliteStatement, BunSqliteStorage, type GitServer, type GitServerConfig, MemoryStorage, type PgDatabase, type PgPool, type PgPoolClient, PgStorage, type PostReceiveEvent, type PreReceiveEvent, type RefAdvertisement, type RefUpdate, Rejection, type ServerHooks, type StandardHooksConfig, type Storage, type UpdateEvent, composeHooks, createGitServer, createStandardHooks, toNodeHandler, withAuth, wrapPgPool };
|