@mhalle/vost 0.8.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 +191 -0
- package/README.md +24 -0
- package/dist/batch.d.ts +82 -0
- package/dist/batch.js +152 -0
- package/dist/batch.js.map +1 -0
- package/dist/copy.d.ts +242 -0
- package/dist/copy.js +1229 -0
- package/dist/copy.js.map +1 -0
- package/dist/exclude.d.ts +68 -0
- package/dist/exclude.js +157 -0
- package/dist/exclude.js.map +1 -0
- package/dist/fileobj.d.ts +82 -0
- package/dist/fileobj.js +127 -0
- package/dist/fileobj.js.map +1 -0
- package/dist/fs.d.ts +581 -0
- package/dist/fs.js +1318 -0
- package/dist/fs.js.map +1 -0
- package/dist/gitstore.d.ts +74 -0
- package/dist/gitstore.js +131 -0
- package/dist/gitstore.js.map +1 -0
- package/dist/glob.d.ts +14 -0
- package/dist/glob.js +68 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/lock.d.ts +15 -0
- package/dist/lock.js +71 -0
- package/dist/lock.js.map +1 -0
- package/dist/mirror.d.ts +53 -0
- package/dist/mirror.js +270 -0
- package/dist/mirror.js.map +1 -0
- package/dist/notes.d.ts +148 -0
- package/dist/notes.js +508 -0
- package/dist/notes.js.map +1 -0
- package/dist/paths.d.ts +16 -0
- package/dist/paths.js +44 -0
- package/dist/paths.js.map +1 -0
- package/dist/refdict.d.ts +117 -0
- package/dist/refdict.js +267 -0
- package/dist/refdict.js.map +1 -0
- package/dist/reflog.d.ts +33 -0
- package/dist/reflog.js +83 -0
- package/dist/reflog.js.map +1 -0
- package/dist/tree.d.ts +79 -0
- package/dist/tree.js +283 -0
- package/dist/tree.js.map +1 -0
- package/dist/types.d.ts +354 -0
- package/dist/types.js +302 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/dist/mirror.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror (backup/restore) operations for vost.
|
|
3
|
+
*
|
|
4
|
+
* Uses isomorphic-git's push/fetch for HTTP transport.
|
|
5
|
+
* Each ref is pushed/fetched individually to achieve mirror semantics.
|
|
6
|
+
*/
|
|
7
|
+
import git from 'isomorphic-git';
|
|
8
|
+
/**
|
|
9
|
+
* Inject credentials into an HTTPS URL if available.
|
|
10
|
+
*
|
|
11
|
+
* Tries `git credential fill` first (works with any configured helper:
|
|
12
|
+
* osxkeychain, wincred, libsecret, `gh auth setup-git`, etc.). Falls
|
|
13
|
+
* back to `gh auth token` for GitHub hosts. Non-HTTPS URLs and URLs
|
|
14
|
+
* that already contain credentials are returned unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Requires Node.js — returns the original URL unchanged in browser
|
|
17
|
+
* environments where `child_process` is not available.
|
|
18
|
+
*
|
|
19
|
+
* @param url - The URL to resolve credentials for.
|
|
20
|
+
* @returns The URL with credentials injected, or the original URL.
|
|
21
|
+
*/
|
|
22
|
+
export async function resolveCredentials(url) {
|
|
23
|
+
if (!url.startsWith('https://'))
|
|
24
|
+
return url;
|
|
25
|
+
const parsed = new URL(url);
|
|
26
|
+
if (parsed.username)
|
|
27
|
+
return url; // already has credentials
|
|
28
|
+
const hostname = parsed.hostname;
|
|
29
|
+
let execFileSync;
|
|
30
|
+
try {
|
|
31
|
+
const cp = await import('node:child_process');
|
|
32
|
+
execFileSync = cp.execFileSync;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return url; // Not in Node.js
|
|
36
|
+
}
|
|
37
|
+
// Try git credential fill
|
|
38
|
+
try {
|
|
39
|
+
const input = `protocol=https\nhost=${hostname}\n\n`;
|
|
40
|
+
const output = execFileSync('git', ['credential', 'fill'], {
|
|
41
|
+
input,
|
|
42
|
+
timeout: 5000,
|
|
43
|
+
encoding: 'utf-8',
|
|
44
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
45
|
+
});
|
|
46
|
+
const creds = {};
|
|
47
|
+
for (const line of output.trim().split('\n')) {
|
|
48
|
+
const eq = line.indexOf('=');
|
|
49
|
+
if (eq > 0)
|
|
50
|
+
creds[line.slice(0, eq)] = line.slice(eq + 1);
|
|
51
|
+
}
|
|
52
|
+
if (creds.username && creds.password) {
|
|
53
|
+
parsed.username = creds.username;
|
|
54
|
+
parsed.password = creds.password;
|
|
55
|
+
return parsed.toString();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// git credential fill failed or not available
|
|
60
|
+
}
|
|
61
|
+
// Fallback: gh auth token (GitHub-specific)
|
|
62
|
+
try {
|
|
63
|
+
const token = execFileSync('gh', ['auth', 'token', '--hostname', hostname], {
|
|
64
|
+
timeout: 5000,
|
|
65
|
+
encoding: 'utf-8',
|
|
66
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
67
|
+
}).trim();
|
|
68
|
+
if (token) {
|
|
69
|
+
parsed.username = 'x-access-token';
|
|
70
|
+
parsed.password = token;
|
|
71
|
+
return parsed.toString();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// gh not available or not authenticated
|
|
76
|
+
}
|
|
77
|
+
return url;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Push all local refs to url, creating an exact mirror.
|
|
81
|
+
* Remote-only refs are deleted.
|
|
82
|
+
*
|
|
83
|
+
* @param store - The GitStore to backup from.
|
|
84
|
+
* @param url - Remote repository URL (HTTPS or local path).
|
|
85
|
+
* @param opts - Options: `http` client, `dryRun` to compute diff without pushing,
|
|
86
|
+
* and optional `onAuth` callback for credentials.
|
|
87
|
+
* @returns A {@link MirrorDiff} describing what changed (or would change).
|
|
88
|
+
*/
|
|
89
|
+
export async function backup(store, url, opts) {
|
|
90
|
+
const diff = await diffRefs(store, url, 'push', opts);
|
|
91
|
+
if (!opts.dryRun) {
|
|
92
|
+
// Push all local branches
|
|
93
|
+
const branches = await store.branches.list();
|
|
94
|
+
for (const branch of branches) {
|
|
95
|
+
await git.push({
|
|
96
|
+
fs: store._fsModule,
|
|
97
|
+
gitdir: store._gitdir,
|
|
98
|
+
http: opts.http,
|
|
99
|
+
url,
|
|
100
|
+
ref: `refs/heads/${branch}`,
|
|
101
|
+
remoteRef: `refs/heads/${branch}`,
|
|
102
|
+
force: true,
|
|
103
|
+
onAuth: opts.onAuth,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Push all tags
|
|
107
|
+
const tags = await store.tags.list();
|
|
108
|
+
for (const tag of tags) {
|
|
109
|
+
await git.push({
|
|
110
|
+
fs: store._fsModule,
|
|
111
|
+
gitdir: store._gitdir,
|
|
112
|
+
http: opts.http,
|
|
113
|
+
url,
|
|
114
|
+
ref: `refs/tags/${tag}`,
|
|
115
|
+
remoteRef: `refs/tags/${tag}`,
|
|
116
|
+
force: true,
|
|
117
|
+
onAuth: opts.onAuth,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// Delete stale remote refs
|
|
121
|
+
for (const change of diff.delete) {
|
|
122
|
+
try {
|
|
123
|
+
await git.push({
|
|
124
|
+
fs: store._fsModule,
|
|
125
|
+
gitdir: store._gitdir,
|
|
126
|
+
http: opts.http,
|
|
127
|
+
url,
|
|
128
|
+
ref: change.ref,
|
|
129
|
+
delete: true,
|
|
130
|
+
onAuth: opts.onAuth,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Ignore delete failures
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return diff;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Fetch all remote refs from url, overwriting local state.
|
|
142
|
+
* Local-only refs are deleted.
|
|
143
|
+
*
|
|
144
|
+
* @param store - The GitStore to restore into.
|
|
145
|
+
* @param url - Remote repository URL (HTTPS or local path).
|
|
146
|
+
* @param opts - Options: `http` client, `dryRun` to compute diff without fetching,
|
|
147
|
+
* and optional `onAuth` callback for credentials.
|
|
148
|
+
* @returns A {@link MirrorDiff} describing what changed (or would change).
|
|
149
|
+
*/
|
|
150
|
+
export async function restore(store, url, opts) {
|
|
151
|
+
const diff = await diffRefs(store, url, 'pull', opts);
|
|
152
|
+
if (!opts.dryRun) {
|
|
153
|
+
// Fetch all remote refs
|
|
154
|
+
await git.fetch({
|
|
155
|
+
fs: store._fsModule,
|
|
156
|
+
gitdir: store._gitdir,
|
|
157
|
+
http: opts.http,
|
|
158
|
+
url,
|
|
159
|
+
tags: true,
|
|
160
|
+
prune: true,
|
|
161
|
+
onAuth: opts.onAuth,
|
|
162
|
+
});
|
|
163
|
+
// Update local refs to match remote
|
|
164
|
+
const remoteRefs = await git.listServerRefs({
|
|
165
|
+
http: opts.http,
|
|
166
|
+
url,
|
|
167
|
+
onAuth: opts.onAuth,
|
|
168
|
+
});
|
|
169
|
+
const remoteRefMap = new Map();
|
|
170
|
+
for (const ref of remoteRefs) {
|
|
171
|
+
if (ref.ref !== 'HEAD' && !ref.ref.endsWith('^{}')) {
|
|
172
|
+
remoteRefMap.set(ref.ref, ref.oid);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Set local refs to match remote
|
|
176
|
+
for (const [ref, oid] of remoteRefMap) {
|
|
177
|
+
await git.writeRef({
|
|
178
|
+
fs: store._fsModule,
|
|
179
|
+
gitdir: store._gitdir,
|
|
180
|
+
ref,
|
|
181
|
+
value: oid,
|
|
182
|
+
force: true,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// Delete local refs not on remote
|
|
186
|
+
const localBranches = await store.branches.list();
|
|
187
|
+
for (const branch of localBranches) {
|
|
188
|
+
if (!remoteRefMap.has(`refs/heads/${branch}`)) {
|
|
189
|
+
await git.deleteRef({
|
|
190
|
+
fs: store._fsModule,
|
|
191
|
+
gitdir: store._gitdir,
|
|
192
|
+
ref: `refs/heads/${branch}`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const localTags = await store.tags.list();
|
|
197
|
+
for (const tag of localTags) {
|
|
198
|
+
if (!remoteRefMap.has(`refs/tags/${tag}`)) {
|
|
199
|
+
await git.deleteRef({
|
|
200
|
+
fs: store._fsModule,
|
|
201
|
+
gitdir: store._gitdir,
|
|
202
|
+
ref: `refs/tags/${tag}`,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return diff;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Compare local and remote refs.
|
|
211
|
+
*/
|
|
212
|
+
async function diffRefs(store, url, direction, opts) {
|
|
213
|
+
// Get remote refs
|
|
214
|
+
let remoteRefs;
|
|
215
|
+
try {
|
|
216
|
+
const refs = await git.listServerRefs({
|
|
217
|
+
http: opts.http,
|
|
218
|
+
url,
|
|
219
|
+
onAuth: opts.onAuth,
|
|
220
|
+
});
|
|
221
|
+
remoteRefs = new Map();
|
|
222
|
+
for (const ref of refs) {
|
|
223
|
+
if (ref.ref !== 'HEAD' && !ref.ref.endsWith('^{}')) {
|
|
224
|
+
remoteRefs.set(ref.ref, ref.oid);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
remoteRefs = new Map();
|
|
230
|
+
}
|
|
231
|
+
// Get local refs
|
|
232
|
+
const localRefs = new Map();
|
|
233
|
+
const branches = await store.branches.list();
|
|
234
|
+
for (const branch of branches) {
|
|
235
|
+
const oid = await git.resolveRef({
|
|
236
|
+
fs: store._fsModule,
|
|
237
|
+
gitdir: store._gitdir,
|
|
238
|
+
ref: `refs/heads/${branch}`,
|
|
239
|
+
});
|
|
240
|
+
localRefs.set(`refs/heads/${branch}`, oid);
|
|
241
|
+
}
|
|
242
|
+
const tags = await store.tags.list();
|
|
243
|
+
for (const tag of tags) {
|
|
244
|
+
const oid = await git.resolveRef({
|
|
245
|
+
fs: store._fsModule,
|
|
246
|
+
gitdir: store._gitdir,
|
|
247
|
+
ref: `refs/tags/${tag}`,
|
|
248
|
+
});
|
|
249
|
+
localRefs.set(`refs/tags/${tag}`, oid);
|
|
250
|
+
}
|
|
251
|
+
const [src, dest] = direction === 'push' ? [localRefs, remoteRefs] : [remoteRefs, localRefs];
|
|
252
|
+
const add = [];
|
|
253
|
+
const update = [];
|
|
254
|
+
const del = [];
|
|
255
|
+
for (const [ref, sha] of src) {
|
|
256
|
+
if (!dest.has(ref)) {
|
|
257
|
+
add.push({ ref, newTarget: sha });
|
|
258
|
+
}
|
|
259
|
+
else if (dest.get(ref) !== sha) {
|
|
260
|
+
update.push({ ref, oldTarget: dest.get(ref), newTarget: sha });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
for (const [ref] of dest) {
|
|
264
|
+
if (!src.has(ref)) {
|
|
265
|
+
del.push({ ref, oldTarget: dest.get(ref) });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return { add, update, delete: del };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../src/mirror.ts"],"names":[],"mappings":"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"}
|
package/dist/notes.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git notes support: per-namespace mapping of commit hashes to note text.
|
|
3
|
+
*
|
|
4
|
+
* Notes live at `refs/notes/<namespace>`, mapping commit hashes to UTF-8
|
|
5
|
+
* text blobs. Reads handle both flat (40-char filename) and 2/38 fanout
|
|
6
|
+
* layouts. Writes always use flat. Each mutation creates a commit on the
|
|
7
|
+
* namespace's notes ref chain, or batch() defers to a single commit.
|
|
8
|
+
*/
|
|
9
|
+
import type { GitStore } from './gitstore.js';
|
|
10
|
+
/**
|
|
11
|
+
* One git notes namespace, backed by `refs/notes/<name>`.
|
|
12
|
+
*
|
|
13
|
+
* Maps 40-char hex commit hashes to UTF-8 note text.
|
|
14
|
+
* Supports `get`, `set`, `delete`, `has`, `list`, and `batch()`.
|
|
15
|
+
*/
|
|
16
|
+
export declare class NoteNamespace {
|
|
17
|
+
/** @internal */ _store: GitStore;
|
|
18
|
+
/** @internal */ _namespace: string;
|
|
19
|
+
/** @internal */ _ref: string;
|
|
20
|
+
constructor(store: GitStore, namespace: string);
|
|
21
|
+
toString(): string;
|
|
22
|
+
private get _fs();
|
|
23
|
+
private get _gitdir();
|
|
24
|
+
/** Resolve the notes ref to a commit OID, or null. */
|
|
25
|
+
private _tipOid;
|
|
26
|
+
/** @internal Read the tree OID from the tip commit, or null. */
|
|
27
|
+
_treeOid(): Promise<string | null>;
|
|
28
|
+
/** Find the blob OID for `hash` in a tree, handling flat and fanout. */
|
|
29
|
+
private _findNoteInTree;
|
|
30
|
+
/** Yield all [hash, blobOid] pairs from the tree. */
|
|
31
|
+
private _iterNotes;
|
|
32
|
+
/** @internal Build a new note tree from a base tree + writes + deletes. */
|
|
33
|
+
_buildNoteTree(baseTreeOid: string | null, writes: Map<string, string>, // hash → text
|
|
34
|
+
deletes: Set<string>): Promise<string>;
|
|
35
|
+
/** @internal Commit a new tree to the notes ref under repo lock. */
|
|
36
|
+
_commitNoteTree(newTreeOid: string, message: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the note text for a commit hash.
|
|
39
|
+
*
|
|
40
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
41
|
+
* @returns The note text (UTF-8).
|
|
42
|
+
* @throws {GitStoreError} If no note exists for the hash.
|
|
43
|
+
*/
|
|
44
|
+
get(hash: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Set or overwrite the note text for a commit hash.
|
|
47
|
+
*
|
|
48
|
+
* Creates a commit on the namespace's notes ref.
|
|
49
|
+
*
|
|
50
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
51
|
+
* @param text - Note text (UTF-8 string).
|
|
52
|
+
*/
|
|
53
|
+
set(hash: string, text: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Delete the note for a commit hash.
|
|
56
|
+
*
|
|
57
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
58
|
+
* @throws {GitStoreError} If no note exists for the hash.
|
|
59
|
+
*/
|
|
60
|
+
delete(hash: string): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a note exists for a commit hash.
|
|
63
|
+
*
|
|
64
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
65
|
+
* @returns True if a note exists.
|
|
66
|
+
*/
|
|
67
|
+
has(hash: string): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* List all commit hashes that have notes in this namespace.
|
|
70
|
+
*
|
|
71
|
+
* @returns Array of 40-char hex commit hashes.
|
|
72
|
+
*/
|
|
73
|
+
list(): Promise<string[]>;
|
|
74
|
+
/** Return the number of notes in this namespace. */
|
|
75
|
+
size(): Promise<number>;
|
|
76
|
+
/**
|
|
77
|
+
* Get the note for the current HEAD commit.
|
|
78
|
+
*
|
|
79
|
+
* @returns The note text.
|
|
80
|
+
* @throws {GitStoreError} If HEAD is dangling or no note exists.
|
|
81
|
+
*/
|
|
82
|
+
getForCurrentBranch(): Promise<string>;
|
|
83
|
+
/**
|
|
84
|
+
* Set the note for the current HEAD commit.
|
|
85
|
+
*
|
|
86
|
+
* @param text - Note text (UTF-8 string).
|
|
87
|
+
* @throws {GitStoreError} If HEAD is dangling.
|
|
88
|
+
*/
|
|
89
|
+
setForCurrentBranch(text: string): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Return a NotesBatch that collects writes/deletes and applies them
|
|
92
|
+
* in a single commit when `commit()` is called.
|
|
93
|
+
*
|
|
94
|
+
* @returns A new {@link NotesBatch} instance.
|
|
95
|
+
*/
|
|
96
|
+
batch(): NotesBatch;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Collects note writes and deletes, applying them in one commit.
|
|
100
|
+
*
|
|
101
|
+
* Call `set()` and `delete()` to stage changes, then `commit()` to flush.
|
|
102
|
+
*/
|
|
103
|
+
export declare class NotesBatch {
|
|
104
|
+
private _ns;
|
|
105
|
+
private _writes;
|
|
106
|
+
private _deletes;
|
|
107
|
+
private _closed;
|
|
108
|
+
constructor(ns: NoteNamespace);
|
|
109
|
+
/**
|
|
110
|
+
* Stage a note write.
|
|
111
|
+
*
|
|
112
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
113
|
+
* @param text - Note text (UTF-8 string).
|
|
114
|
+
*/
|
|
115
|
+
set(hash: string, text: string): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Stage a note deletion.
|
|
118
|
+
*
|
|
119
|
+
* @param hash - 40-char lowercase hex commit hash.
|
|
120
|
+
*/
|
|
121
|
+
delete(hash: string): void;
|
|
122
|
+
/**
|
|
123
|
+
* Commit all staged writes and deletes in a single commit.
|
|
124
|
+
*
|
|
125
|
+
* After calling this the batch is closed and no further changes are allowed.
|
|
126
|
+
*/
|
|
127
|
+
commit(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Outer container for git notes namespaces on a GitStore.
|
|
131
|
+
*
|
|
132
|
+
* `store.notes.commits` returns the default namespace (`refs/notes/commits`).
|
|
133
|
+
* `store.notes.namespace('reviews')` returns a custom namespace.
|
|
134
|
+
*/
|
|
135
|
+
export declare class NoteDict {
|
|
136
|
+
private _store;
|
|
137
|
+
constructor(store: GitStore);
|
|
138
|
+
toString(): string;
|
|
139
|
+
/** The default `refs/notes/commits` namespace. */
|
|
140
|
+
get commits(): NoteNamespace;
|
|
141
|
+
/**
|
|
142
|
+
* Access a custom notes namespace.
|
|
143
|
+
*
|
|
144
|
+
* @param name - Namespace name (e.g. 'reviews').
|
|
145
|
+
* @returns NoteNamespace for `refs/notes/<name>`.
|
|
146
|
+
*/
|
|
147
|
+
namespace(name: string): NoteNamespace;
|
|
148
|
+
}
|