@pierre/storage 0.7.0 → 0.8.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 +75 -0
- package/dist/index.cjs +317 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +250 -2
- package/dist/index.d.ts +250 -2
- package/dist/index.js +317 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +342 -1
- package/src/schemas.ts +45 -0
- package/src/types.ts +87 -1
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,20 +9,25 @@ import snakecaseKeys from 'snakecase-keys';
|
|
|
9
9
|
import { createCommitBuilder, FetchCommitTransport, resolveCommitTtlSeconds } from './commit';
|
|
10
10
|
import { FetchDiffCommitTransport, sendCommitFromDiff } from './diff-commit';
|
|
11
11
|
import { RefUpdateError } from './errors';
|
|
12
|
-
import { ApiFetcher } from './fetch';
|
|
12
|
+
import { ApiError, ApiFetcher } from './fetch';
|
|
13
13
|
import type { RestoreCommitAckRaw } from './schemas';
|
|
14
14
|
import {
|
|
15
15
|
branchDiffResponseSchema,
|
|
16
16
|
commitDiffResponseSchema,
|
|
17
17
|
createBranchResponseSchema,
|
|
18
|
+
errorEnvelopeSchema,
|
|
18
19
|
grepResponseSchema,
|
|
19
20
|
listBranchesResponseSchema,
|
|
20
21
|
listCommitsResponseSchema,
|
|
21
22
|
listFilesResponseSchema,
|
|
23
|
+
listReposResponseSchema,
|
|
24
|
+
noteReadResponseSchema,
|
|
25
|
+
noteWriteResponseSchema,
|
|
22
26
|
restoreCommitAckSchema,
|
|
23
27
|
restoreCommitResponseSchema,
|
|
24
28
|
} from './schemas';
|
|
25
29
|
import type {
|
|
30
|
+
AppendNoteOptions,
|
|
26
31
|
BranchInfo,
|
|
27
32
|
CommitBuilder,
|
|
28
33
|
CommitInfo,
|
|
@@ -32,7 +37,9 @@ import type {
|
|
|
32
37
|
CreateBranchResult,
|
|
33
38
|
CreateCommitFromDiffOptions,
|
|
34
39
|
CreateCommitOptions,
|
|
40
|
+
CreateNoteOptions,
|
|
35
41
|
CreateRepoOptions,
|
|
42
|
+
DeleteNoteOptions,
|
|
36
43
|
DeleteRepoOptions,
|
|
37
44
|
DeleteRepoResult,
|
|
38
45
|
DiffFileState,
|
|
@@ -46,6 +53,8 @@ import type {
|
|
|
46
53
|
GetCommitDiffResponse,
|
|
47
54
|
GetCommitDiffResult,
|
|
48
55
|
GetFileOptions,
|
|
56
|
+
GetNoteOptions,
|
|
57
|
+
GetNoteResult,
|
|
49
58
|
GetRemoteURLOptions,
|
|
50
59
|
GitStorageOptions,
|
|
51
60
|
GrepFileMatch,
|
|
@@ -60,6 +69,10 @@ import type {
|
|
|
60
69
|
ListCommitsResult,
|
|
61
70
|
ListFilesOptions,
|
|
62
71
|
ListFilesResult,
|
|
72
|
+
ListReposOptions,
|
|
73
|
+
ListReposResponse,
|
|
74
|
+
ListReposResult,
|
|
75
|
+
NoteWriteResult,
|
|
63
76
|
PullUpstreamOptions,
|
|
64
77
|
RawBranchInfo,
|
|
65
78
|
RawCommitInfo,
|
|
@@ -114,6 +127,23 @@ const RESTORE_COMMIT_ALLOWED_STATUS = [
|
|
|
114
127
|
504, // Gateway Timeout - long-running storage operations
|
|
115
128
|
] as const;
|
|
116
129
|
|
|
130
|
+
const NOTE_WRITE_ALLOWED_STATUS = [
|
|
131
|
+
400, // Bad Request - validation errors
|
|
132
|
+
401, // Unauthorized - missing/invalid auth header
|
|
133
|
+
403, // Forbidden - missing git:write scope
|
|
134
|
+
404, // Not Found - repo or note lookup failures
|
|
135
|
+
408, // Request Timeout - client cancelled
|
|
136
|
+
409, // Conflict - concurrent ref updates
|
|
137
|
+
412, // Precondition Failed - optimistic concurrency
|
|
138
|
+
422, // Unprocessable Entity - metadata issues
|
|
139
|
+
429, // Too Many Requests - upstream throttling
|
|
140
|
+
499, // Client Closed Request - storage cancellation
|
|
141
|
+
500, // Internal Server Error - generic failure
|
|
142
|
+
502, // Bad Gateway - storage/gateway bridge issues
|
|
143
|
+
503, // Service Unavailable - storage selection failures
|
|
144
|
+
504, // Gateway Timeout - long-running storage operations
|
|
145
|
+
] as const;
|
|
146
|
+
|
|
117
147
|
function resolveInvocationTtlSeconds(
|
|
118
148
|
options?: { ttl?: number },
|
|
119
149
|
defaultValue: number = DEFAULT_TOKEN_TTL_SECONDS,
|
|
@@ -337,6 +367,26 @@ function transformCreateBranchResult(raw: CreateBranchResponse): CreateBranchRes
|
|
|
337
367
|
};
|
|
338
368
|
}
|
|
339
369
|
|
|
370
|
+
function transformListReposResult(raw: ListReposResponse): ListReposResult {
|
|
371
|
+
return {
|
|
372
|
+
repos: raw.repos.map((repo) => ({
|
|
373
|
+
repoId: repo.repo_id,
|
|
374
|
+
url: repo.url,
|
|
375
|
+
defaultBranch: repo.default_branch,
|
|
376
|
+
createdAt: repo.created_at,
|
|
377
|
+
baseRepo: repo.base_repo
|
|
378
|
+
? {
|
|
379
|
+
provider: repo.base_repo.provider,
|
|
380
|
+
owner: repo.base_repo.owner,
|
|
381
|
+
name: repo.base_repo.name,
|
|
382
|
+
}
|
|
383
|
+
: undefined,
|
|
384
|
+
})),
|
|
385
|
+
nextCursor: raw.next_cursor ?? undefined,
|
|
386
|
+
hasMore: raw.has_more,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
340
390
|
function transformGrepLine(raw: { line_number: number; text: string; type: string }): GrepLine {
|
|
341
391
|
return {
|
|
342
392
|
lineNumber: raw.line_number,
|
|
@@ -355,6 +405,119 @@ function transformGrepFileMatch(raw: {
|
|
|
355
405
|
};
|
|
356
406
|
}
|
|
357
407
|
|
|
408
|
+
function transformNoteReadResult(raw: {
|
|
409
|
+
sha: string;
|
|
410
|
+
note: string;
|
|
411
|
+
ref_sha: string;
|
|
412
|
+
}): GetNoteResult {
|
|
413
|
+
return {
|
|
414
|
+
sha: raw.sha,
|
|
415
|
+
note: raw.note,
|
|
416
|
+
refSha: raw.ref_sha,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function transformNoteWriteResult(raw: {
|
|
421
|
+
sha: string;
|
|
422
|
+
target_ref: string;
|
|
423
|
+
base_commit?: string;
|
|
424
|
+
new_ref_sha: string;
|
|
425
|
+
result: { success: boolean; status: string; message?: string };
|
|
426
|
+
}): NoteWriteResult {
|
|
427
|
+
return {
|
|
428
|
+
sha: raw.sha,
|
|
429
|
+
targetRef: raw.target_ref,
|
|
430
|
+
baseCommit: raw.base_commit,
|
|
431
|
+
newRefSha: raw.new_ref_sha,
|
|
432
|
+
result: {
|
|
433
|
+
success: raw.result.success,
|
|
434
|
+
status: raw.result.status,
|
|
435
|
+
message: raw.result.message,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function buildNoteWriteBody(
|
|
441
|
+
sha: string,
|
|
442
|
+
note: string,
|
|
443
|
+
action: 'add' | 'append',
|
|
444
|
+
options: { expectedRefSha?: string; author?: { name: string; email: string } },
|
|
445
|
+
): Record<string, unknown> {
|
|
446
|
+
const body: Record<string, unknown> = {
|
|
447
|
+
sha,
|
|
448
|
+
action,
|
|
449
|
+
note,
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const expectedRefSha = options.expectedRefSha?.trim();
|
|
453
|
+
if (expectedRefSha) {
|
|
454
|
+
body.expected_ref_sha = expectedRefSha;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (options.author) {
|
|
458
|
+
const authorName = options.author.name?.trim();
|
|
459
|
+
const authorEmail = options.author.email?.trim();
|
|
460
|
+
if (!authorName || !authorEmail) {
|
|
461
|
+
throw new Error('note author name and email are required when provided');
|
|
462
|
+
}
|
|
463
|
+
body.author = {
|
|
464
|
+
name: authorName,
|
|
465
|
+
email: authorEmail,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return body;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async function parseNoteWriteResponse(
|
|
473
|
+
response: Response,
|
|
474
|
+
method: 'POST' | 'DELETE',
|
|
475
|
+
): Promise<NoteWriteResult> {
|
|
476
|
+
let jsonBody: unknown;
|
|
477
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
478
|
+
try {
|
|
479
|
+
if (contentType.includes('application/json')) {
|
|
480
|
+
jsonBody = await response.json();
|
|
481
|
+
} else {
|
|
482
|
+
jsonBody = await response.text();
|
|
483
|
+
}
|
|
484
|
+
} catch {
|
|
485
|
+
jsonBody = undefined;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (jsonBody && typeof jsonBody === 'object') {
|
|
489
|
+
const parsed = noteWriteResponseSchema.safeParse(jsonBody);
|
|
490
|
+
if (parsed.success) {
|
|
491
|
+
return transformNoteWriteResult(parsed.data);
|
|
492
|
+
}
|
|
493
|
+
const parsedError = errorEnvelopeSchema.safeParse(jsonBody);
|
|
494
|
+
if (parsedError.success) {
|
|
495
|
+
throw new ApiError({
|
|
496
|
+
message: parsedError.data.error,
|
|
497
|
+
status: response.status,
|
|
498
|
+
statusText: response.statusText,
|
|
499
|
+
method,
|
|
500
|
+
url: response.url,
|
|
501
|
+
body: jsonBody,
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const fallbackMessage =
|
|
507
|
+
typeof jsonBody === 'string' && jsonBody.trim() !== ''
|
|
508
|
+
? jsonBody.trim()
|
|
509
|
+
: `Request ${method} ${response.url} failed with status ${response.status} ${response.statusText}`;
|
|
510
|
+
|
|
511
|
+
throw new ApiError({
|
|
512
|
+
message: fallbackMessage,
|
|
513
|
+
status: response.status,
|
|
514
|
+
statusText: response.statusText,
|
|
515
|
+
method,
|
|
516
|
+
url: response.url,
|
|
517
|
+
body: jsonBody,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
358
521
|
/**
|
|
359
522
|
* Implementation of the Repo interface
|
|
360
523
|
*/
|
|
@@ -500,6 +663,154 @@ class RepoImpl implements Repo {
|
|
|
500
663
|
});
|
|
501
664
|
}
|
|
502
665
|
|
|
666
|
+
async getNote(options: GetNoteOptions): Promise<GetNoteResult> {
|
|
667
|
+
const sha = options?.sha?.trim();
|
|
668
|
+
if (!sha) {
|
|
669
|
+
throw new Error('getNote sha is required');
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
673
|
+
const jwt = await this.generateJWT(this.id, {
|
|
674
|
+
permissions: ['git:read'],
|
|
675
|
+
ttl,
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
const response = await this.api.get({ path: 'repos/notes', params: { sha } }, jwt);
|
|
679
|
+
const raw = noteReadResponseSchema.parse(await response.json());
|
|
680
|
+
return transformNoteReadResult(raw);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
async createNote(options: CreateNoteOptions): Promise<NoteWriteResult> {
|
|
684
|
+
const sha = options?.sha?.trim();
|
|
685
|
+
if (!sha) {
|
|
686
|
+
throw new Error('createNote sha is required');
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const note = options?.note?.trim();
|
|
690
|
+
if (!note) {
|
|
691
|
+
throw new Error('createNote note is required');
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
695
|
+
const jwt = await this.generateJWT(this.id, {
|
|
696
|
+
permissions: ['git:write'],
|
|
697
|
+
ttl,
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const body = buildNoteWriteBody(sha, note, 'add', {
|
|
701
|
+
expectedRefSha: options.expectedRefSha,
|
|
702
|
+
author: options.author,
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
const response = await this.api.post({ path: 'repos/notes', body }, jwt, {
|
|
706
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS],
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
const result = await parseNoteWriteResponse(response, 'POST');
|
|
710
|
+
if (!result.result.success) {
|
|
711
|
+
throw new RefUpdateError(
|
|
712
|
+
result.result.message ?? `createNote failed with status ${result.result.status}`,
|
|
713
|
+
{
|
|
714
|
+
status: result.result.status,
|
|
715
|
+
message: result.result.message,
|
|
716
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha),
|
|
717
|
+
},
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
return result;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
async appendNote(options: AppendNoteOptions): Promise<NoteWriteResult> {
|
|
724
|
+
const sha = options?.sha?.trim();
|
|
725
|
+
if (!sha) {
|
|
726
|
+
throw new Error('appendNote sha is required');
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const note = options?.note?.trim();
|
|
730
|
+
if (!note) {
|
|
731
|
+
throw new Error('appendNote note is required');
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
735
|
+
const jwt = await this.generateJWT(this.id, {
|
|
736
|
+
permissions: ['git:write'],
|
|
737
|
+
ttl,
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
const body = buildNoteWriteBody(sha, note, 'append', {
|
|
741
|
+
expectedRefSha: options.expectedRefSha,
|
|
742
|
+
author: options.author,
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
const response = await this.api.post({ path: 'repos/notes', body }, jwt, {
|
|
746
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS],
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
const result = await parseNoteWriteResponse(response, 'POST');
|
|
750
|
+
if (!result.result.success) {
|
|
751
|
+
throw new RefUpdateError(
|
|
752
|
+
result.result.message ?? `appendNote failed with status ${result.result.status}`,
|
|
753
|
+
{
|
|
754
|
+
status: result.result.status,
|
|
755
|
+
message: result.result.message,
|
|
756
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha),
|
|
757
|
+
},
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
return result;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
async deleteNote(options: DeleteNoteOptions): Promise<NoteWriteResult> {
|
|
764
|
+
const sha = options?.sha?.trim();
|
|
765
|
+
if (!sha) {
|
|
766
|
+
throw new Error('deleteNote sha is required');
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
770
|
+
const jwt = await this.generateJWT(this.id, {
|
|
771
|
+
permissions: ['git:write'],
|
|
772
|
+
ttl,
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
const body: Record<string, unknown> = {
|
|
776
|
+
sha,
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
const expectedRefSha = options.expectedRefSha?.trim();
|
|
780
|
+
if (expectedRefSha) {
|
|
781
|
+
body.expected_ref_sha = expectedRefSha;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (options.author) {
|
|
785
|
+
const authorName = options.author.name?.trim();
|
|
786
|
+
const authorEmail = options.author.email?.trim();
|
|
787
|
+
if (!authorName || !authorEmail) {
|
|
788
|
+
throw new Error('deleteNote author name and email are required when provided');
|
|
789
|
+
}
|
|
790
|
+
body.author = {
|
|
791
|
+
name: authorName,
|
|
792
|
+
email: authorEmail,
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
const response = await this.api.delete({ path: 'repos/notes', body }, jwt, {
|
|
797
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS],
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
const result = await parseNoteWriteResponse(response, 'DELETE');
|
|
801
|
+
if (!result.result.success) {
|
|
802
|
+
throw new RefUpdateError(
|
|
803
|
+
result.result.message ?? `deleteNote failed with status ${result.result.status}`,
|
|
804
|
+
{
|
|
805
|
+
status: result.result.status,
|
|
806
|
+
message: result.result.message,
|
|
807
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha),
|
|
808
|
+
},
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
return result;
|
|
812
|
+
}
|
|
813
|
+
|
|
503
814
|
async getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResult> {
|
|
504
815
|
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
505
816
|
const jwt = await this.generateJWT(this.id, {
|
|
@@ -916,6 +1227,36 @@ export class GitStorage {
|
|
|
916
1227
|
return new RepoImpl(repoId, defaultBranch, this.options, this.generateJWT.bind(this));
|
|
917
1228
|
}
|
|
918
1229
|
|
|
1230
|
+
/**
|
|
1231
|
+
* List repositories for the authenticated organization
|
|
1232
|
+
* @returns Paginated repositories list
|
|
1233
|
+
*/
|
|
1234
|
+
async listRepos(options?: ListReposOptions): Promise<ListReposResult> {
|
|
1235
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1236
|
+
const jwt = await this.generateJWT('org', {
|
|
1237
|
+
permissions: ['org:read'],
|
|
1238
|
+
ttl,
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
let params: Record<string, string> | undefined;
|
|
1242
|
+
if (options?.cursor || typeof options?.limit === 'number') {
|
|
1243
|
+
params = {};
|
|
1244
|
+
if (options.cursor) {
|
|
1245
|
+
params.cursor = options.cursor;
|
|
1246
|
+
}
|
|
1247
|
+
if (typeof options.limit === 'number') {
|
|
1248
|
+
params.limit = options.limit.toString();
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
const response = await this.api.get({ path: 'repos', params }, jwt);
|
|
1253
|
+
const raw = listReposResponseSchema.parse(await response.json());
|
|
1254
|
+
return transformListReposResult({
|
|
1255
|
+
...raw,
|
|
1256
|
+
next_cursor: raw.next_cursor ?? undefined,
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
|
|
919
1260
|
/**
|
|
920
1261
|
* Find a repository by ID
|
|
921
1262
|
* @param options The search options
|
package/src/schemas.ts
CHANGED
|
@@ -34,6 +34,46 @@ export const listCommitsResponseSchema = z.object({
|
|
|
34
34
|
has_more: z.boolean(),
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
export const repoBaseInfoSchema = z.object({
|
|
38
|
+
provider: z.string(),
|
|
39
|
+
owner: z.string(),
|
|
40
|
+
name: z.string(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const repoInfoSchema = z.object({
|
|
44
|
+
repo_id: z.string(),
|
|
45
|
+
url: z.string(),
|
|
46
|
+
default_branch: z.string(),
|
|
47
|
+
created_at: z.string(),
|
|
48
|
+
base_repo: repoBaseInfoSchema.optional().nullable(),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const listReposResponseSchema = z.object({
|
|
52
|
+
repos: z.array(repoInfoSchema),
|
|
53
|
+
next_cursor: z.string().nullable().optional(),
|
|
54
|
+
has_more: z.boolean(),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const noteReadResponseSchema = z.object({
|
|
58
|
+
sha: z.string(),
|
|
59
|
+
note: z.string(),
|
|
60
|
+
ref_sha: z.string(),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export const noteResultSchema = z.object({
|
|
64
|
+
success: z.boolean(),
|
|
65
|
+
status: z.string(),
|
|
66
|
+
message: z.string().optional(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export const noteWriteResponseSchema = z.object({
|
|
70
|
+
sha: z.string(),
|
|
71
|
+
target_ref: z.string(),
|
|
72
|
+
base_commit: z.string().optional(),
|
|
73
|
+
new_ref_sha: z.string(),
|
|
74
|
+
result: noteResultSchema,
|
|
75
|
+
});
|
|
76
|
+
|
|
37
77
|
export const diffStatsSchema = z.object({
|
|
38
78
|
files: z.number(),
|
|
39
79
|
additions: z.number(),
|
|
@@ -162,6 +202,11 @@ export type RawBranchInfo = z.infer<typeof branchInfoSchema>;
|
|
|
162
202
|
export type ListBranchesResponseRaw = z.infer<typeof listBranchesResponseSchema>;
|
|
163
203
|
export type RawCommitInfo = z.infer<typeof commitInfoRawSchema>;
|
|
164
204
|
export type ListCommitsResponseRaw = z.infer<typeof listCommitsResponseSchema>;
|
|
205
|
+
export type RawRepoBaseInfo = z.infer<typeof repoBaseInfoSchema>;
|
|
206
|
+
export type RawRepoInfo = z.infer<typeof repoInfoSchema>;
|
|
207
|
+
export type ListReposResponseRaw = z.infer<typeof listReposResponseSchema>;
|
|
208
|
+
export type NoteReadResponseRaw = z.infer<typeof noteReadResponseSchema>;
|
|
209
|
+
export type NoteWriteResponseRaw = z.infer<typeof noteWriteResponseSchema>;
|
|
165
210
|
export type RawFileDiff = z.infer<typeof diffFileRawSchema>;
|
|
166
211
|
export type RawFilteredFile = z.infer<typeof filteredFileRawSchema>;
|
|
167
212
|
export type GetBranchDiffResponseRaw = z.infer<typeof branchDiffResponseSchema>;
|
package/src/types.ts
CHANGED
|
@@ -9,10 +9,15 @@ import type {
|
|
|
9
9
|
ListBranchesResponseRaw,
|
|
10
10
|
ListCommitsResponseRaw,
|
|
11
11
|
ListFilesResponseRaw,
|
|
12
|
+
ListReposResponseRaw,
|
|
13
|
+
NoteReadResponseRaw,
|
|
14
|
+
NoteWriteResponseRaw,
|
|
12
15
|
RawBranchInfo as SchemaRawBranchInfo,
|
|
13
16
|
RawCommitInfo as SchemaRawCommitInfo,
|
|
14
17
|
RawFileDiff as SchemaRawFileDiff,
|
|
15
18
|
RawFilteredFile as SchemaRawFilteredFile,
|
|
19
|
+
RawRepoBaseInfo as SchemaRawRepoBaseInfo,
|
|
20
|
+
RawRepoInfo as SchemaRawRepoInfo,
|
|
16
21
|
} from './schemas';
|
|
17
22
|
|
|
18
23
|
export interface OverrideableGitStorageOptions {
|
|
@@ -31,7 +36,7 @@ export interface GitStorageOptions extends OverrideableGitStorageOptions {
|
|
|
31
36
|
export type ValidAPIVersion = 1;
|
|
32
37
|
|
|
33
38
|
export interface GetRemoteURLOptions {
|
|
34
|
-
permissions?: ('git:write' | 'git:read' | 'repo:write')[];
|
|
39
|
+
permissions?: ('git:write' | 'git:read' | 'repo:write' | 'org:read')[];
|
|
35
40
|
ttl?: number;
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -45,6 +50,10 @@ export interface Repo {
|
|
|
45
50
|
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
46
51
|
listBranches(options?: ListBranchesOptions): Promise<ListBranchesResult>;
|
|
47
52
|
listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult>;
|
|
53
|
+
getNote(options: GetNoteOptions): Promise<GetNoteResult>;
|
|
54
|
+
createNote(options: CreateNoteOptions): Promise<NoteWriteResult>;
|
|
55
|
+
appendNote(options: AppendNoteOptions): Promise<NoteWriteResult>;
|
|
56
|
+
deleteNote(options: DeleteNoteOptions): Promise<NoteWriteResult>;
|
|
48
57
|
getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResult>;
|
|
49
58
|
getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResult>;
|
|
50
59
|
grep(options: GrepOptions): Promise<GrepResult>;
|
|
@@ -84,6 +93,37 @@ export interface BaseRepo {
|
|
|
84
93
|
defaultBranch?: string;
|
|
85
94
|
}
|
|
86
95
|
|
|
96
|
+
export interface ListReposOptions extends GitStorageInvocationOptions {
|
|
97
|
+
cursor?: string;
|
|
98
|
+
limit?: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type RawRepoBaseInfo = SchemaRawRepoBaseInfo;
|
|
102
|
+
|
|
103
|
+
export interface RepoBaseInfo {
|
|
104
|
+
provider: string;
|
|
105
|
+
owner: string;
|
|
106
|
+
name: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type RawRepoInfo = SchemaRawRepoInfo;
|
|
110
|
+
|
|
111
|
+
export interface RepoInfo {
|
|
112
|
+
repoId: string;
|
|
113
|
+
url: string;
|
|
114
|
+
defaultBranch: string;
|
|
115
|
+
createdAt: string;
|
|
116
|
+
baseRepo?: RepoBaseInfo;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type ListReposResponse = ListReposResponseRaw;
|
|
120
|
+
|
|
121
|
+
export interface ListReposResult {
|
|
122
|
+
repos: RepoInfo[];
|
|
123
|
+
nextCursor?: string;
|
|
124
|
+
hasMore: boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
87
127
|
export interface CreateRepoOptions extends GitStorageInvocationOptions {
|
|
88
128
|
id?: string;
|
|
89
129
|
baseRepo?: BaseRepo;
|
|
@@ -192,6 +232,52 @@ export interface ListCommitsResult {
|
|
|
192
232
|
hasMore: boolean;
|
|
193
233
|
}
|
|
194
234
|
|
|
235
|
+
// Git notes API types
|
|
236
|
+
export interface GetNoteOptions extends GitStorageInvocationOptions {
|
|
237
|
+
sha: string;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export type GetNoteResponse = NoteReadResponseRaw;
|
|
241
|
+
|
|
242
|
+
export interface GetNoteResult {
|
|
243
|
+
sha: string;
|
|
244
|
+
note: string;
|
|
245
|
+
refSha: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
interface NoteWriteBaseOptions extends GitStorageInvocationOptions {
|
|
249
|
+
sha: string;
|
|
250
|
+
note: string;
|
|
251
|
+
expectedRefSha?: string;
|
|
252
|
+
author?: CommitSignature;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type CreateNoteOptions = NoteWriteBaseOptions;
|
|
256
|
+
|
|
257
|
+
export type AppendNoteOptions = NoteWriteBaseOptions;
|
|
258
|
+
|
|
259
|
+
export interface DeleteNoteOptions extends GitStorageInvocationOptions {
|
|
260
|
+
sha: string;
|
|
261
|
+
expectedRefSha?: string;
|
|
262
|
+
author?: CommitSignature;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface NoteWriteResultPayload {
|
|
266
|
+
success: boolean;
|
|
267
|
+
status: string;
|
|
268
|
+
message?: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export type NoteWriteResponse = NoteWriteResponseRaw;
|
|
272
|
+
|
|
273
|
+
export interface NoteWriteResult {
|
|
274
|
+
sha: string;
|
|
275
|
+
targetRef: string;
|
|
276
|
+
baseCommit?: string;
|
|
277
|
+
newRefSha: string;
|
|
278
|
+
result: NoteWriteResultPayload;
|
|
279
|
+
}
|
|
280
|
+
|
|
195
281
|
// Branch Diff API types
|
|
196
282
|
export interface GetBranchDiffOptions extends GitStorageInvocationOptions {
|
|
197
283
|
branch: string;
|