@gitgov/core 2.1.2 → 2.2.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/README.md +53 -6
- package/dist/src/{agent_runner-ByOUWOt6.d.ts → agent_runner-Cs5HXt4h.d.ts} +2 -1
- package/dist/src/fs.d.ts +11 -20
- package/dist/src/fs.js +9 -0
- package/dist/src/fs.js.map +1 -1
- package/dist/src/github.d.ts +472 -0
- package/dist/src/github.js +1281 -0
- package/dist/src/github.js.map +1 -0
- package/dist/src/{index--ahcnsG3.d.ts → index-D1RVufxB.d.ts} +38 -234
- package/dist/src/index.d.ts +10 -7
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/key_provider-CRpHFGjN.d.ts +227 -0
- package/dist/src/memory.d.ts +10 -4
- package/dist/src/memory.js +9 -1
- package/dist/src/memory.js.map +1 -1
- package/dist/src/{memory_file_lister-BkQ_C3ZU.d.ts → memory_file_lister-CfHtByeZ.d.ts} +2 -1
- package/package.json +6 -1
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { Octokit } from '@octokit/rest';
|
|
2
|
+
export { Octokit, RestEndpointMethodTypes } from '@octokit/rest';
|
|
3
|
+
import { h as FileLister, i as FileListOptions, j as FileStats, I as IdEncoder, R as RecordStore, a as IGitModule, d as ChangedFile, e as GetCommitHistoryOptions, f as CommitInfo, g as CommitAuthor, E as ExecOptions, c as ExecResult, C as ConfigStore, G as GitGovConfig } from './index-D1RVufxB.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Types for GitHubFileLister module.
|
|
7
|
+
*
|
|
8
|
+
* @module file_lister/github/github_file_lister.types
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configuration options for GitHubFileLister.
|
|
12
|
+
* Auth and API base URL are configured on the Octokit instance, not here.
|
|
13
|
+
*/
|
|
14
|
+
type GitHubFileListerOptions = {
|
|
15
|
+
/** GitHub repository owner (user or org) */
|
|
16
|
+
owner: string;
|
|
17
|
+
/** GitHub repository name */
|
|
18
|
+
repo: string;
|
|
19
|
+
/** Git ref to use (branch, tag, or SHA). Default: 'gitgov-state' */
|
|
20
|
+
ref?: string;
|
|
21
|
+
/** Base path within the repo to scope operations. Default: '' (repo root) */
|
|
22
|
+
basePath?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* GitHubFileLister - GitHub REST API implementation of FileLister
|
|
27
|
+
*
|
|
28
|
+
* Provides file listing and reading operations via GitHub's REST API
|
|
29
|
+
* for SaaS environments where direct filesystem access is not available.
|
|
30
|
+
*
|
|
31
|
+
* Uses the Git Trees API for listing (with caching) and the Contents API
|
|
32
|
+
* for reading individual files. Falls back to the Blobs API for files
|
|
33
|
+
* larger than 1MB where the Contents API returns null content.
|
|
34
|
+
*
|
|
35
|
+
* @module file_lister/github/github_file_lister
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* GitHubFileLister - GitHub REST API FileLister implementation.
|
|
40
|
+
*
|
|
41
|
+
* Implements the FileLister interface using GitHub's REST API endpoints:
|
|
42
|
+
* - Trees API for listing files (cached)
|
|
43
|
+
* - Contents API for reading, stat, and exists
|
|
44
|
+
* - Blobs API as fallback for large files (>1MB)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { Octokit } from '@octokit/rest';
|
|
49
|
+
* const octokit = new Octokit({ auth: 'ghp_xxx' });
|
|
50
|
+
* const lister = new GitHubFileLister({
|
|
51
|
+
* owner: 'myorg',
|
|
52
|
+
* repo: 'myrepo',
|
|
53
|
+
* ref: 'gitgov-state',
|
|
54
|
+
* basePath: '.gitgov',
|
|
55
|
+
* }, octokit);
|
|
56
|
+
*
|
|
57
|
+
* const files = await lister.list(['**\/*.ts']);
|
|
58
|
+
* const content = await lister.read('config.json');
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare class GitHubFileLister implements FileLister {
|
|
62
|
+
private readonly owner;
|
|
63
|
+
private readonly repo;
|
|
64
|
+
private readonly ref;
|
|
65
|
+
private readonly basePath;
|
|
66
|
+
private readonly octokit;
|
|
67
|
+
/** Cached tree entries from the Trees API */
|
|
68
|
+
private treeCache;
|
|
69
|
+
constructor(options: GitHubFileListerOptions, octokit: Octokit);
|
|
70
|
+
/**
|
|
71
|
+
* [EARS-A1] Lists files matching glob patterns.
|
|
72
|
+
* [EARS-B1] Uses Trees API with recursive=1 and picomatch filter.
|
|
73
|
+
* [EARS-B3] Applies basePath prefix for tree entries, strips from results.
|
|
74
|
+
* [EARS-B6] Caches tree between list() calls.
|
|
75
|
+
*/
|
|
76
|
+
list(patterns: string[], options?: FileListOptions): Promise<string[]>;
|
|
77
|
+
/**
|
|
78
|
+
* [EARS-A2] Checks if a file exists via Contents API.
|
|
79
|
+
* [EARS-B4] Returns false for 404 responses.
|
|
80
|
+
*/
|
|
81
|
+
exists(filePath: string): Promise<boolean>;
|
|
82
|
+
/**
|
|
83
|
+
* [EARS-A3] Reads file content as string.
|
|
84
|
+
* [EARS-B2] Decodes base64 content from Contents API.
|
|
85
|
+
* [EARS-B7] Falls back to Blobs API for files >1MB (null content).
|
|
86
|
+
*/
|
|
87
|
+
read(filePath: string): Promise<string>;
|
|
88
|
+
/**
|
|
89
|
+
* [EARS-A4] Gets file statistics via Contents API.
|
|
90
|
+
* Returns size from API, mtime as 0 (not available via Contents API), isFile as true.
|
|
91
|
+
*/
|
|
92
|
+
stat(filePath: string): Promise<FileStats>;
|
|
93
|
+
/**
|
|
94
|
+
* Builds the full file path including basePath prefix.
|
|
95
|
+
*/
|
|
96
|
+
private buildFullPath;
|
|
97
|
+
/**
|
|
98
|
+
* [EARS-B6] Fetches and caches the full repository tree.
|
|
99
|
+
* [EARS-C3] Throws READ_ERROR if the tree response is truncated.
|
|
100
|
+
*/
|
|
101
|
+
private fetchTree;
|
|
102
|
+
/**
|
|
103
|
+
* [EARS-B7] Reads file content via the Blobs API (fallback for >1MB files).
|
|
104
|
+
*/
|
|
105
|
+
private readViaBlobs;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Options for GitHubRecordStore.
|
|
110
|
+
* Auth and API base URL are configured on the Octokit instance, not here.
|
|
111
|
+
*/
|
|
112
|
+
type GitHubRecordStoreOptions = {
|
|
113
|
+
/** GitHub repository owner (user or org) */
|
|
114
|
+
owner: string;
|
|
115
|
+
/** GitHub repository name */
|
|
116
|
+
repo: string;
|
|
117
|
+
/** Branch ref (default: 'gitgov-state') */
|
|
118
|
+
ref?: string;
|
|
119
|
+
/** Base directory path in the repo (e.g., '.gitgov/actors') */
|
|
120
|
+
basePath: string;
|
|
121
|
+
/** File extension for records (default: '.json') */
|
|
122
|
+
extension?: string;
|
|
123
|
+
/** ID encoder for filename-safe IDs (default: undefined = no encoding) */
|
|
124
|
+
idEncoder?: IdEncoder;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Result returned by write operations (put, putMany, delete) on GitHubRecordStore.
|
|
128
|
+
* Contains the commit SHA from the GitHub API response.
|
|
129
|
+
*/
|
|
130
|
+
type GitHubWriteResult = {
|
|
131
|
+
/** SHA of the commit created by the write operation */
|
|
132
|
+
commitSha?: string;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Options for write operations on GitHubRecordStore.
|
|
136
|
+
*/
|
|
137
|
+
type GitHubWriteOpts = {
|
|
138
|
+
/** Custom commit message (default: auto-generated) */
|
|
139
|
+
commitMessage?: string;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* GitHubRecordStore<V> - GitHub Contents API implementation of RecordStore<V, GitHubWriteResult, GitHubWriteOpts>
|
|
144
|
+
*
|
|
145
|
+
* Persists records as JSON files in a GitHub repository via Octokit.
|
|
146
|
+
* Supports SHA caching to avoid redundant GET calls before PUT/DELETE.
|
|
147
|
+
*/
|
|
148
|
+
declare class GitHubRecordStore<V> implements RecordStore<V, GitHubWriteResult, GitHubWriteOpts> {
|
|
149
|
+
private readonly owner;
|
|
150
|
+
private readonly repo;
|
|
151
|
+
private readonly ref;
|
|
152
|
+
private readonly basePath;
|
|
153
|
+
private readonly extension;
|
|
154
|
+
private readonly idEncoder;
|
|
155
|
+
private readonly octokit;
|
|
156
|
+
/** SHA cache keyed by full file path (basePath/encoded + extension) */
|
|
157
|
+
private readonly shaCache;
|
|
158
|
+
/** IGitModule dependency for putMany() atomic commits. Optional — only needed for putMany(). */
|
|
159
|
+
private readonly gitModule;
|
|
160
|
+
constructor(options: GitHubRecordStoreOptions, octokit: Octokit, gitModule?: IGitModule);
|
|
161
|
+
get(id: string): Promise<V | null>;
|
|
162
|
+
put(id: string, value: V, opts?: GitHubWriteOpts): Promise<GitHubWriteResult>;
|
|
163
|
+
/**
|
|
164
|
+
* [EARS-A11, EARS-A12, EARS-B8] Persists multiple records in a single atomic commit.
|
|
165
|
+
* Uses GitHubGitModule staging buffer: add() with contentMap, then commit().
|
|
166
|
+
* Empty entries array returns { commitSha: undefined } without API calls.
|
|
167
|
+
* Requires gitModule dependency — throws if not injected.
|
|
168
|
+
*/
|
|
169
|
+
putMany(entries: Array<{
|
|
170
|
+
id: string;
|
|
171
|
+
value: V;
|
|
172
|
+
}>, opts?: GitHubWriteOpts): Promise<GitHubWriteResult>;
|
|
173
|
+
delete(id: string, opts?: GitHubWriteOpts): Promise<GitHubWriteResult>;
|
|
174
|
+
list(): Promise<string[]>;
|
|
175
|
+
exists(id: string): Promise<boolean>;
|
|
176
|
+
private validateId;
|
|
177
|
+
private buildFilePath;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Types for GitHubGitModule.
|
|
182
|
+
* All EARS prefixes map to github_git_module.md
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* Configuration for GitHubGitModule.
|
|
186
|
+
* All operations target the specified owner/repo via GitHub REST API.
|
|
187
|
+
* Note: defaultBranch (not ref) because GitModule tracks which branch
|
|
188
|
+
* operations target, switchable via checkoutBranch().
|
|
189
|
+
*/
|
|
190
|
+
type GitHubGitModuleOptions = {
|
|
191
|
+
/** GitHub repository owner (user or organization) */
|
|
192
|
+
owner: string;
|
|
193
|
+
/** GitHub repository name */
|
|
194
|
+
repo: string;
|
|
195
|
+
/** Default branch name (default: 'gitgov-state') */
|
|
196
|
+
defaultBranch?: string;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* GitHubGitModule - GitHub REST API implementation of IGitModule
|
|
201
|
+
*
|
|
202
|
+
* Implements IGitModule for SaaS environments where direct filesystem
|
|
203
|
+
* and git CLI are not available. Uses GitHub REST API via Octokit for all operations.
|
|
204
|
+
*
|
|
205
|
+
* Method categories:
|
|
206
|
+
* - Category A (Implement): Real API calls — getFileContent, getCommitHash, etc.
|
|
207
|
+
* - Category B (No-op): Return sensible defaults — push, fetch, stash, etc.
|
|
208
|
+
* - Category C (Not Supported): Throw GitError — rebase, resetHard, etc.
|
|
209
|
+
*
|
|
210
|
+
* All EARS prefixes map to github_git_module.md
|
|
211
|
+
*
|
|
212
|
+
* @module git/github
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
declare class GitHubGitModule implements IGitModule {
|
|
216
|
+
private readonly owner;
|
|
217
|
+
private readonly repo;
|
|
218
|
+
private readonly defaultBranch;
|
|
219
|
+
private readonly octokit;
|
|
220
|
+
/** Staging buffer: path → content (null = delete) */
|
|
221
|
+
private stagingBuffer;
|
|
222
|
+
/** Active ref for operations (can be changed via checkoutBranch) */
|
|
223
|
+
private activeRef;
|
|
224
|
+
constructor(options: GitHubGitModuleOptions, octokit: Octokit);
|
|
225
|
+
/** Category C: Not supported via GitHub API */
|
|
226
|
+
private notSupported;
|
|
227
|
+
/**
|
|
228
|
+
* [EARS-A1] Read file content via Contents API + base64 decode
|
|
229
|
+
* [EARS-A2] Fallback to Blobs API for files >1MB
|
|
230
|
+
*/
|
|
231
|
+
getFileContent(commitHash: string, filePath: string): Promise<string>;
|
|
232
|
+
/**
|
|
233
|
+
* [EARS-A3] Get commit SHA from branch via Refs API
|
|
234
|
+
* [EARS-B4] Return SHA directly if already a 40-char hex
|
|
235
|
+
*/
|
|
236
|
+
getCommitHash(ref?: string): Promise<string>;
|
|
237
|
+
/**
|
|
238
|
+
* [EARS-A4] List changed files via Compare API
|
|
239
|
+
*/
|
|
240
|
+
getChangedFiles(fromCommit: string, toCommit: string, pathFilter: string): Promise<ChangedFile[]>;
|
|
241
|
+
/**
|
|
242
|
+
* [EARS-A5] Get commit history via Commits API
|
|
243
|
+
*/
|
|
244
|
+
getCommitHistory(branch: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
|
|
245
|
+
/**
|
|
246
|
+
* [EARS-B3] Get commit history between two commits via Compare API
|
|
247
|
+
*/
|
|
248
|
+
getCommitHistoryRange(fromHash: string, toHash: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
|
|
249
|
+
/**
|
|
250
|
+
* [EARS-A6] Get commit message via Commits API
|
|
251
|
+
*/
|
|
252
|
+
getCommitMessage(commitHash: string): Promise<string>;
|
|
253
|
+
/**
|
|
254
|
+
* [EARS-B1] Check if branch exists via Branches API
|
|
255
|
+
*/
|
|
256
|
+
branchExists(branchName: string): Promise<boolean>;
|
|
257
|
+
/**
|
|
258
|
+
* [EARS-B2] List remote branches via Branches API
|
|
259
|
+
* remoteName is ignored — repo itself is the implicit remote
|
|
260
|
+
*/
|
|
261
|
+
listRemoteBranches(_remoteName: string): Promise<string[]>;
|
|
262
|
+
/** [EARS-C1] Read file content and store in staging buffer */
|
|
263
|
+
add(filePaths: string[], options?: {
|
|
264
|
+
force?: boolean;
|
|
265
|
+
contentMap?: Record<string, string>;
|
|
266
|
+
}): Promise<void>;
|
|
267
|
+
/** [EARS-C2] Mark files as deleted in staging buffer */
|
|
268
|
+
rm(filePaths: string[]): Promise<void>;
|
|
269
|
+
/** [EARS-C7] Return staged file paths from buffer */
|
|
270
|
+
getStagedFiles(): Promise<string[]>;
|
|
271
|
+
/**
|
|
272
|
+
* [EARS-C6] Create branch via Refs API POST
|
|
273
|
+
*/
|
|
274
|
+
createBranch(branchName: string, startPoint?: string): Promise<void>;
|
|
275
|
+
/**
|
|
276
|
+
* Internal commit implementation shared by commit() and commitAllowEmpty().
|
|
277
|
+
*
|
|
278
|
+
* [EARS-C3] 6-step atomic transaction
|
|
279
|
+
* [EARS-C4] Clears staging buffer after successful commit
|
|
280
|
+
* [EARS-C5] Throws if staging buffer is empty (unless allowEmpty)
|
|
281
|
+
*/
|
|
282
|
+
private commitInternal;
|
|
283
|
+
/**
|
|
284
|
+
* [EARS-C3] Commit staged changes via 6-step atomic transaction
|
|
285
|
+
* [EARS-C5] Throws if staging buffer is empty
|
|
286
|
+
*/
|
|
287
|
+
commit(message: string, author?: CommitAuthor): Promise<string>;
|
|
288
|
+
/** [EARS-D5] exec not supported in API mode */
|
|
289
|
+
exec(_command: string, _args: string[], _options?: ExecOptions): Promise<ExecResult>;
|
|
290
|
+
/** No-op: repos are created via GitHub API, not initialized locally */
|
|
291
|
+
init(): Promise<void>;
|
|
292
|
+
/** [EARS-D1] Return virtual path representing the repo */
|
|
293
|
+
getRepoRoot(): Promise<string>;
|
|
294
|
+
/** [EARS-D1] Return active ref (starts as defaultBranch) */
|
|
295
|
+
getCurrentBranch(): Promise<string>;
|
|
296
|
+
/** No-op: git config doesn't apply to GitHub API */
|
|
297
|
+
setConfig(_key: string, _value: string, _scope?: 'local' | 'global' | 'system'): Promise<void>;
|
|
298
|
+
/** [EARS-D1] Return true if staging buffer has entries */
|
|
299
|
+
hasUncommittedChanges(_pathFilter?: string): Promise<boolean>;
|
|
300
|
+
/** No-op: GitHub API doesn't have rebase-in-progress concept */
|
|
301
|
+
isRebaseInProgress(): Promise<boolean>;
|
|
302
|
+
/** [EARS-D1] GitHub repos always have 'origin' conceptually */
|
|
303
|
+
isRemoteConfigured(_remoteName: string): Promise<boolean>;
|
|
304
|
+
/** No-op: always 'origin' */
|
|
305
|
+
getBranchRemote(_branchName: string): Promise<string | null>;
|
|
306
|
+
/** No-op: GitHub API handles merges atomically */
|
|
307
|
+
getConflictedFiles(): Promise<string[]>;
|
|
308
|
+
/** [EARS-D2] Update activeRef for subsequent operations */
|
|
309
|
+
checkoutBranch(branchName: string): Promise<void>;
|
|
310
|
+
/** No-op: GitHub API doesn't have stash concept */
|
|
311
|
+
stash(_message?: string): Promise<string | null>;
|
|
312
|
+
/** No-op */
|
|
313
|
+
stashPop(): Promise<boolean>;
|
|
314
|
+
/** No-op */
|
|
315
|
+
stashDrop(_stashHash?: string): Promise<void>;
|
|
316
|
+
/** No-op: API always fresh */
|
|
317
|
+
fetch(_remote: string): Promise<void>;
|
|
318
|
+
/** No-op: API mode */
|
|
319
|
+
pull(_remote: string, _branchName: string): Promise<void>;
|
|
320
|
+
/** No-op: API mode */
|
|
321
|
+
pullRebase(_remote: string, _branchName: string): Promise<void>;
|
|
322
|
+
/** [EARS-D4] No-op: commits via API are already remote */
|
|
323
|
+
push(_remote: string, _branchName: string): Promise<void>;
|
|
324
|
+
/** [EARS-D4] No-op: commits via API are already remote */
|
|
325
|
+
pushWithUpstream(_remote: string, _branchName: string): Promise<void>;
|
|
326
|
+
/** No-op: API mode */
|
|
327
|
+
setUpstream(_branchName: string, _remote: string, _remoteBranch: string): Promise<void>;
|
|
328
|
+
/** No-op */
|
|
329
|
+
rebaseAbort(): Promise<void>;
|
|
330
|
+
/** [EARS-D1] Delegates to commitInternal, allowing empty staging buffer */
|
|
331
|
+
commitAllowEmpty(message: string, author?: CommitAuthor): Promise<string>;
|
|
332
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
333
|
+
rebase(_targetBranch: string): Promise<void>;
|
|
334
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
335
|
+
rebaseContinue(): Promise<string>;
|
|
336
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
337
|
+
resetHard(_target: string): Promise<void>;
|
|
338
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
339
|
+
checkoutOrphanBranch(_branchName: string): Promise<void>;
|
|
340
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
341
|
+
checkoutFilesFromBranch(_sourceBranch: string, _filePaths: string[]): Promise<void>;
|
|
342
|
+
/** [EARS-D3] Not supported via GitHub API */
|
|
343
|
+
getMergeBase(_branchA: string, _branchB: string): Promise<string>;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* GitHubConfigStore Types
|
|
348
|
+
*
|
|
349
|
+
* Configuration types for the GitHub-backed ConfigStore implementation.
|
|
350
|
+
* Auth (token) and base URL are configured via the Octokit instance.
|
|
351
|
+
*/
|
|
352
|
+
/**
|
|
353
|
+
* Options for constructing a GitHubConfigStore instance.
|
|
354
|
+
* Auth and API base URL are configured on the Octokit instance, not here.
|
|
355
|
+
*/
|
|
356
|
+
type GitHubConfigStoreOptions = {
|
|
357
|
+
/** GitHub repository owner (user or organization) */
|
|
358
|
+
owner: string;
|
|
359
|
+
/** GitHub repository name */
|
|
360
|
+
repo: string;
|
|
361
|
+
/** Branch to read from / write to (default: 'gitgov-state'). Must be a branch name for saves. */
|
|
362
|
+
ref?: string;
|
|
363
|
+
/** Base path within the repo (default: '.gitgov') */
|
|
364
|
+
basePath?: string;
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* Result returned by saveConfig on GitHubConfigStore.
|
|
368
|
+
* Contains the commit SHA from the GitHub API response.
|
|
369
|
+
*/
|
|
370
|
+
type GitHubSaveResult = {
|
|
371
|
+
/**
|
|
372
|
+
* SHA of the commit created by the save operation.
|
|
373
|
+
* Always present — saveConfig either creates a commit (success) or throws (failure).
|
|
374
|
+
* Contrast with GitHubWriteResult.commitSha which is optional (idempotent delete).
|
|
375
|
+
*/
|
|
376
|
+
commitSha: string;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* GitHubConfigStore - GitHub Contents API implementation of ConfigStore
|
|
381
|
+
*
|
|
382
|
+
* Persists config.json to a GitHub repository via Octokit.
|
|
383
|
+
* Used by SaaS/server-side environments where the project lives on GitHub
|
|
384
|
+
* and direct filesystem access is not available.
|
|
385
|
+
*
|
|
386
|
+
* Key behaviors:
|
|
387
|
+
* - loadConfig: GET contents, base64 decode, JSON parse. Fail-safe on 404/invalid JSON.
|
|
388
|
+
* - saveConfig: JSON serialize + base64 encode, PUT contents with optional SHA for updates.
|
|
389
|
+
* - Caches blob SHA from loadConfig for subsequent saveConfig (optimistic concurrency).
|
|
390
|
+
*/
|
|
391
|
+
|
|
392
|
+
declare class GitHubConfigStore implements ConfigStore<GitHubSaveResult> {
|
|
393
|
+
private readonly owner;
|
|
394
|
+
private readonly repo;
|
|
395
|
+
private readonly ref;
|
|
396
|
+
private readonly basePath;
|
|
397
|
+
private readonly octokit;
|
|
398
|
+
/** Cached blob SHA from the last loadConfig call, used for PUT updates */
|
|
399
|
+
private cachedSha;
|
|
400
|
+
constructor(options: GitHubConfigStoreOptions, octokit: Octokit);
|
|
401
|
+
/**
|
|
402
|
+
* Load project configuration from GitHub Contents API.
|
|
403
|
+
*
|
|
404
|
+
* [EARS-A1] Returns GitGovConfig when valid JSON is found.
|
|
405
|
+
* [EARS-A2] Returns null on 404 (fail-safe).
|
|
406
|
+
* [EARS-A3] Returns null on invalid JSON (fail-safe).
|
|
407
|
+
* [EARS-B1] Fetches via Contents API with base64 decode.
|
|
408
|
+
* [EARS-B2] Caches SHA from response for subsequent saveConfig.
|
|
409
|
+
*/
|
|
410
|
+
loadConfig(): Promise<GitGovConfig | null>;
|
|
411
|
+
/**
|
|
412
|
+
* Save project configuration to GitHub via Contents API PUT.
|
|
413
|
+
*
|
|
414
|
+
* [EARS-A4] Writes config via PUT to Contents API.
|
|
415
|
+
* [EARS-B3] Includes cached SHA for updates (optimistic concurrency).
|
|
416
|
+
* [EARS-B4] Omits SHA for initial creation.
|
|
417
|
+
* [EARS-C1] Throws PERMISSION_DENIED on 401/403.
|
|
418
|
+
* [EARS-C2] Throws CONFLICT on 409.
|
|
419
|
+
* [EARS-C3] Throws SERVER_ERROR on 5xx.
|
|
420
|
+
*/
|
|
421
|
+
saveConfig(config: GitGovConfig): Promise<GitHubSaveResult>;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* GitHub API implementations for @gitgov/core/github
|
|
426
|
+
*
|
|
427
|
+
* This module exports all implementations that use GitHub REST API.
|
|
428
|
+
* Suitable for SaaS environments, Forge apps, GitHub Actions,
|
|
429
|
+
* and any context without local filesystem access.
|
|
430
|
+
*
|
|
431
|
+
* Usage:
|
|
432
|
+
* import { GitHubFileLister, GitHubRecordStore, GitHubGitModule, GitHubConfigStore } from '@gitgov/core/github';
|
|
433
|
+
*
|
|
434
|
+
* Each implementation receives an `Octokit` instance for testability and shared auth/base-URL config.
|
|
435
|
+
*/
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Error codes for GitHub API errors.
|
|
439
|
+
* Semantic codes that abstract HTTP status codes.
|
|
440
|
+
*/
|
|
441
|
+
type GitHubApiErrorCode = 'PERMISSION_DENIED' | 'NOT_FOUND' | 'CONFLICT' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'INVALID_ID' | 'INVALID_RESPONSE';
|
|
442
|
+
/**
|
|
443
|
+
* Typed error for GitHub API operations.
|
|
444
|
+
* Used by RecordStore, ConfigStore, and other modules that
|
|
445
|
+
* interact with GitHub Contents API directly.
|
|
446
|
+
*/
|
|
447
|
+
declare class GitHubApiError extends Error {
|
|
448
|
+
/** Semantic error code */
|
|
449
|
+
readonly code: GitHubApiErrorCode;
|
|
450
|
+
/** HTTP status code (if applicable) */
|
|
451
|
+
readonly statusCode?: number | undefined;
|
|
452
|
+
constructor(message: string,
|
|
453
|
+
/** Semantic error code */
|
|
454
|
+
code: GitHubApiErrorCode,
|
|
455
|
+
/** HTTP status code (if applicable) */
|
|
456
|
+
statusCode?: number | undefined);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Type guard: checks if an error is an Octokit RequestError (duck-typing).
|
|
460
|
+
* Avoids runtime import of ESM-only @octokit/request-error.
|
|
461
|
+
*/
|
|
462
|
+
declare function isOctokitRequestError(error: unknown): error is {
|
|
463
|
+
status: number;
|
|
464
|
+
message: string;
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* Maps Octokit RequestError (and unknown errors) to GitHubApiError.
|
|
468
|
+
* Shared utility used by all GitHub backend modules.
|
|
469
|
+
*/
|
|
470
|
+
declare function mapOctokitError(error: unknown, context: string): GitHubApiError;
|
|
471
|
+
|
|
472
|
+
export { GitHubApiError, type GitHubApiErrorCode, GitHubConfigStore, type GitHubConfigStoreOptions, GitHubFileLister, type GitHubFileListerOptions, GitHubGitModule, type GitHubGitModuleOptions, GitHubRecordStore, type GitHubRecordStoreOptions, type GitHubSaveResult, type GitHubWriteOpts, type GitHubWriteResult, isOctokitRequestError, mapOctokitError };
|