@pierre/storage 0.7.0 → 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/README.md +98 -0
- package/dist/index.cjs +358 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +257 -3
- package/dist/index.d.ts +257 -3
- package/dist/index.js +358 -9
- package/dist/index.js.map +1 -1
- package/package.json +38 -39
- package/src/index.ts +383 -10
- package/src/schemas.ts +45 -0
- package/src/types.ts +96 -2
package/README.md
CHANGED
|
@@ -40,6 +40,16 @@ console.log(repo.id); // e.g., '123e4567-e89b-12d3-a456-426614174000'
|
|
|
40
40
|
// Create a repository with custom ID
|
|
41
41
|
const customRepo = await store.createRepo({ id: 'my-custom-repo' });
|
|
42
42
|
console.log(customRepo.id); // 'my-custom-repo'
|
|
43
|
+
|
|
44
|
+
// Create a repository by forking an existing repo
|
|
45
|
+
const forkedRepo = await store.createRepo({
|
|
46
|
+
id: 'my-fork', // optional
|
|
47
|
+
baseRepo: {
|
|
48
|
+
id: 'my-template-id',
|
|
49
|
+
ref: 'main', // optional
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
// If defaultBranch is omitted, the SDK returns "main".
|
|
43
53
|
```
|
|
44
54
|
|
|
45
55
|
### Finding a Repository
|
|
@@ -116,6 +126,10 @@ const repo = await store.createRepo();
|
|
|
116
126
|
// or
|
|
117
127
|
const repo = await store.findOne({ id: 'existing-repo-id' });
|
|
118
128
|
|
|
129
|
+
// List repositories for the org
|
|
130
|
+
const repos = await store.listRepos({ limit: 20 });
|
|
131
|
+
console.log(repos.repos);
|
|
132
|
+
|
|
119
133
|
// Get file content (streaming)
|
|
120
134
|
const resp = await repo.getFileStream({
|
|
121
135
|
path: 'README.md',
|
|
@@ -145,6 +159,27 @@ const commits = await repo.listCommits({
|
|
|
145
159
|
});
|
|
146
160
|
console.log(commits.commits);
|
|
147
161
|
|
|
162
|
+
// Read a git note for a commit
|
|
163
|
+
const note = await repo.getNote({ sha: 'abc123...' });
|
|
164
|
+
console.log(note.note);
|
|
165
|
+
|
|
166
|
+
// Add a git note
|
|
167
|
+
const noteResult = await repo.createNote({
|
|
168
|
+
sha: 'abc123...',
|
|
169
|
+
note: 'Release QA approved',
|
|
170
|
+
author: { name: 'Release Bot', email: 'release@example.com' },
|
|
171
|
+
});
|
|
172
|
+
console.log(noteResult.newRefSha);
|
|
173
|
+
|
|
174
|
+
// Append to an existing git note
|
|
175
|
+
await repo.appendNote({
|
|
176
|
+
sha: 'abc123...',
|
|
177
|
+
note: 'Follow-up review complete',
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Delete a git note
|
|
181
|
+
await repo.deleteNote({ sha: 'abc123...' });
|
|
182
|
+
|
|
148
183
|
// Get branch diff
|
|
149
184
|
const branchDiff = await repo.getBranchDiff({
|
|
150
185
|
branch: 'feature-branch',
|
|
@@ -312,6 +347,19 @@ interface GitStorageOptions {
|
|
|
312
347
|
|
|
313
348
|
interface CreateRepoOptions {
|
|
314
349
|
id?: string; // Optional custom repository ID
|
|
350
|
+
baseRepo?:
|
|
351
|
+
| {
|
|
352
|
+
id: string; // Fork source repo ID
|
|
353
|
+
ref?: string; // Optional ref to fork from
|
|
354
|
+
sha?: string; // Optional commit SHA to fork from
|
|
355
|
+
}
|
|
356
|
+
| {
|
|
357
|
+
owner: string; // GitHub owner
|
|
358
|
+
name: string; // GitHub repository name
|
|
359
|
+
defaultBranch?: string;
|
|
360
|
+
provider?: 'github';
|
|
361
|
+
};
|
|
362
|
+
defaultBranch?: string; // Optional default branch name (defaults to "main")
|
|
315
363
|
}
|
|
316
364
|
|
|
317
365
|
interface FindOneOptions {
|
|
@@ -327,6 +375,10 @@ interface Repo {
|
|
|
327
375
|
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
328
376
|
listBranches(options?: ListBranchesOptions): Promise<ListBranchesResult>;
|
|
329
377
|
listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult>;
|
|
378
|
+
getNote(options: GetNoteOptions): Promise<GetNoteResult>;
|
|
379
|
+
createNote(options: CreateNoteOptions): Promise<NoteWriteResult>;
|
|
380
|
+
appendNote(options: AppendNoteOptions): Promise<NoteWriteResult>;
|
|
381
|
+
deleteNote(options: DeleteNoteOptions): Promise<NoteWriteResult>;
|
|
330
382
|
getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResult>;
|
|
331
383
|
getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResult>;
|
|
332
384
|
}
|
|
@@ -360,6 +412,52 @@ interface ListFilesResult {
|
|
|
360
412
|
ref: string;
|
|
361
413
|
}
|
|
362
414
|
|
|
415
|
+
interface GetNoteOptions {
|
|
416
|
+
sha: string; // Commit SHA to look up notes for
|
|
417
|
+
ttl?: number;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
interface GetNoteResult {
|
|
421
|
+
sha: string;
|
|
422
|
+
note: string;
|
|
423
|
+
refSha: string;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
interface CreateNoteOptions {
|
|
427
|
+
sha: string;
|
|
428
|
+
note: string;
|
|
429
|
+
expectedRefSha?: string;
|
|
430
|
+
author?: { name: string; email: string };
|
|
431
|
+
ttl?: number;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
interface AppendNoteOptions {
|
|
435
|
+
sha: string;
|
|
436
|
+
note: string;
|
|
437
|
+
expectedRefSha?: string;
|
|
438
|
+
author?: { name: string; email: string };
|
|
439
|
+
ttl?: number;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
interface DeleteNoteOptions {
|
|
443
|
+
sha: string;
|
|
444
|
+
expectedRefSha?: string;
|
|
445
|
+
author?: { name: string; email: string };
|
|
446
|
+
ttl?: number;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
interface NoteWriteResult {
|
|
450
|
+
sha: string;
|
|
451
|
+
targetRef: string;
|
|
452
|
+
baseCommit?: string;
|
|
453
|
+
newRefSha: string;
|
|
454
|
+
result: {
|
|
455
|
+
success: boolean;
|
|
456
|
+
status: string;
|
|
457
|
+
message?: string;
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
363
461
|
interface ListBranchesOptions {
|
|
364
462
|
cursor?: string;
|
|
365
463
|
limit?: number;
|
package/dist/index.cjs
CHANGED
|
@@ -76,6 +76,40 @@ var listCommitsResponseSchema = zod.z.object({
|
|
|
76
76
|
next_cursor: zod.z.string().nullable().optional(),
|
|
77
77
|
has_more: zod.z.boolean()
|
|
78
78
|
});
|
|
79
|
+
var repoBaseInfoSchema = zod.z.object({
|
|
80
|
+
provider: zod.z.string(),
|
|
81
|
+
owner: zod.z.string(),
|
|
82
|
+
name: zod.z.string()
|
|
83
|
+
});
|
|
84
|
+
var repoInfoSchema = zod.z.object({
|
|
85
|
+
repo_id: zod.z.string(),
|
|
86
|
+
url: zod.z.string(),
|
|
87
|
+
default_branch: zod.z.string(),
|
|
88
|
+
created_at: zod.z.string(),
|
|
89
|
+
base_repo: repoBaseInfoSchema.optional().nullable()
|
|
90
|
+
});
|
|
91
|
+
var listReposResponseSchema = zod.z.object({
|
|
92
|
+
repos: zod.z.array(repoInfoSchema),
|
|
93
|
+
next_cursor: zod.z.string().nullable().optional(),
|
|
94
|
+
has_more: zod.z.boolean()
|
|
95
|
+
});
|
|
96
|
+
var noteReadResponseSchema = zod.z.object({
|
|
97
|
+
sha: zod.z.string(),
|
|
98
|
+
note: zod.z.string(),
|
|
99
|
+
ref_sha: zod.z.string()
|
|
100
|
+
});
|
|
101
|
+
var noteResultSchema = zod.z.object({
|
|
102
|
+
success: zod.z.boolean(),
|
|
103
|
+
status: zod.z.string(),
|
|
104
|
+
message: zod.z.string().optional()
|
|
105
|
+
});
|
|
106
|
+
var noteWriteResponseSchema = zod.z.object({
|
|
107
|
+
sha: zod.z.string(),
|
|
108
|
+
target_ref: zod.z.string(),
|
|
109
|
+
base_commit: zod.z.string().optional(),
|
|
110
|
+
new_ref_sha: zod.z.string(),
|
|
111
|
+
result: noteResultSchema
|
|
112
|
+
});
|
|
79
113
|
var diffStatsSchema = zod.z.object({
|
|
80
114
|
files: zod.z.number(),
|
|
81
115
|
additions: zod.z.number(),
|
|
@@ -472,7 +506,7 @@ function concatChunks(a, b) {
|
|
|
472
506
|
|
|
473
507
|
// package.json
|
|
474
508
|
var package_default = {
|
|
475
|
-
version: "0.
|
|
509
|
+
version: "0.9.0"};
|
|
476
510
|
|
|
477
511
|
// src/version.ts
|
|
478
512
|
var PACKAGE_NAME = "code-storage-sdk";
|
|
@@ -1364,6 +1398,36 @@ var RESTORE_COMMIT_ALLOWED_STATUS = [
|
|
|
1364
1398
|
504
|
|
1365
1399
|
// Gateway Timeout - long-running storage operations
|
|
1366
1400
|
];
|
|
1401
|
+
var NOTE_WRITE_ALLOWED_STATUS = [
|
|
1402
|
+
400,
|
|
1403
|
+
// Bad Request - validation errors
|
|
1404
|
+
401,
|
|
1405
|
+
// Unauthorized - missing/invalid auth header
|
|
1406
|
+
403,
|
|
1407
|
+
// Forbidden - missing git:write scope
|
|
1408
|
+
404,
|
|
1409
|
+
// Not Found - repo or note lookup failures
|
|
1410
|
+
408,
|
|
1411
|
+
// Request Timeout - client cancelled
|
|
1412
|
+
409,
|
|
1413
|
+
// Conflict - concurrent ref updates
|
|
1414
|
+
412,
|
|
1415
|
+
// Precondition Failed - optimistic concurrency
|
|
1416
|
+
422,
|
|
1417
|
+
// Unprocessable Entity - metadata issues
|
|
1418
|
+
429,
|
|
1419
|
+
// Too Many Requests - upstream throttling
|
|
1420
|
+
499,
|
|
1421
|
+
// Client Closed Request - storage cancellation
|
|
1422
|
+
500,
|
|
1423
|
+
// Internal Server Error - generic failure
|
|
1424
|
+
502,
|
|
1425
|
+
// Bad Gateway - storage/gateway bridge issues
|
|
1426
|
+
503,
|
|
1427
|
+
// Service Unavailable - storage selection failures
|
|
1428
|
+
504
|
|
1429
|
+
// Gateway Timeout - long-running storage operations
|
|
1430
|
+
];
|
|
1367
1431
|
function resolveInvocationTtlSeconds(options, defaultValue = DEFAULT_TOKEN_TTL_SECONDS) {
|
|
1368
1432
|
if (typeof options?.ttl === "number" && options.ttl > 0) {
|
|
1369
1433
|
return options.ttl;
|
|
@@ -1551,6 +1615,23 @@ function transformCreateBranchResult(raw) {
|
|
|
1551
1615
|
commitSha: raw.commit_sha ?? void 0
|
|
1552
1616
|
};
|
|
1553
1617
|
}
|
|
1618
|
+
function transformListReposResult(raw) {
|
|
1619
|
+
return {
|
|
1620
|
+
repos: raw.repos.map((repo) => ({
|
|
1621
|
+
repoId: repo.repo_id,
|
|
1622
|
+
url: repo.url,
|
|
1623
|
+
defaultBranch: repo.default_branch,
|
|
1624
|
+
createdAt: repo.created_at,
|
|
1625
|
+
baseRepo: repo.base_repo ? {
|
|
1626
|
+
provider: repo.base_repo.provider,
|
|
1627
|
+
owner: repo.base_repo.owner,
|
|
1628
|
+
name: repo.base_repo.name
|
|
1629
|
+
} : void 0
|
|
1630
|
+
})),
|
|
1631
|
+
nextCursor: raw.next_cursor ?? void 0,
|
|
1632
|
+
hasMore: raw.has_more
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1554
1635
|
function transformGrepLine(raw) {
|
|
1555
1636
|
return {
|
|
1556
1637
|
lineNumber: raw.line_number,
|
|
@@ -1564,6 +1645,88 @@ function transformGrepFileMatch(raw) {
|
|
|
1564
1645
|
lines: raw.lines.map(transformGrepLine)
|
|
1565
1646
|
};
|
|
1566
1647
|
}
|
|
1648
|
+
function transformNoteReadResult(raw) {
|
|
1649
|
+
return {
|
|
1650
|
+
sha: raw.sha,
|
|
1651
|
+
note: raw.note,
|
|
1652
|
+
refSha: raw.ref_sha
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
function transformNoteWriteResult(raw) {
|
|
1656
|
+
return {
|
|
1657
|
+
sha: raw.sha,
|
|
1658
|
+
targetRef: raw.target_ref,
|
|
1659
|
+
baseCommit: raw.base_commit,
|
|
1660
|
+
newRefSha: raw.new_ref_sha,
|
|
1661
|
+
result: {
|
|
1662
|
+
success: raw.result.success,
|
|
1663
|
+
status: raw.result.status,
|
|
1664
|
+
message: raw.result.message
|
|
1665
|
+
}
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
function buildNoteWriteBody(sha, note, action, options) {
|
|
1669
|
+
const body = {
|
|
1670
|
+
sha,
|
|
1671
|
+
action,
|
|
1672
|
+
note
|
|
1673
|
+
};
|
|
1674
|
+
const expectedRefSha = options.expectedRefSha?.trim();
|
|
1675
|
+
if (expectedRefSha) {
|
|
1676
|
+
body.expected_ref_sha = expectedRefSha;
|
|
1677
|
+
}
|
|
1678
|
+
if (options.author) {
|
|
1679
|
+
const authorName = options.author.name?.trim();
|
|
1680
|
+
const authorEmail = options.author.email?.trim();
|
|
1681
|
+
if (!authorName || !authorEmail) {
|
|
1682
|
+
throw new Error("note author name and email are required when provided");
|
|
1683
|
+
}
|
|
1684
|
+
body.author = {
|
|
1685
|
+
name: authorName,
|
|
1686
|
+
email: authorEmail
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
return body;
|
|
1690
|
+
}
|
|
1691
|
+
async function parseNoteWriteResponse(response, method) {
|
|
1692
|
+
let jsonBody;
|
|
1693
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
1694
|
+
try {
|
|
1695
|
+
if (contentType.includes("application/json")) {
|
|
1696
|
+
jsonBody = await response.json();
|
|
1697
|
+
} else {
|
|
1698
|
+
jsonBody = await response.text();
|
|
1699
|
+
}
|
|
1700
|
+
} catch {
|
|
1701
|
+
jsonBody = void 0;
|
|
1702
|
+
}
|
|
1703
|
+
if (jsonBody && typeof jsonBody === "object") {
|
|
1704
|
+
const parsed = noteWriteResponseSchema.safeParse(jsonBody);
|
|
1705
|
+
if (parsed.success) {
|
|
1706
|
+
return transformNoteWriteResult(parsed.data);
|
|
1707
|
+
}
|
|
1708
|
+
const parsedError = errorEnvelopeSchema.safeParse(jsonBody);
|
|
1709
|
+
if (parsedError.success) {
|
|
1710
|
+
throw new ApiError({
|
|
1711
|
+
message: parsedError.data.error,
|
|
1712
|
+
status: response.status,
|
|
1713
|
+
statusText: response.statusText,
|
|
1714
|
+
method,
|
|
1715
|
+
url: response.url,
|
|
1716
|
+
body: jsonBody
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
const fallbackMessage = typeof jsonBody === "string" && jsonBody.trim() !== "" ? jsonBody.trim() : `Request ${method} ${response.url} failed with status ${response.status} ${response.statusText}`;
|
|
1721
|
+
throw new ApiError({
|
|
1722
|
+
message: fallbackMessage,
|
|
1723
|
+
status: response.status,
|
|
1724
|
+
statusText: response.statusText,
|
|
1725
|
+
method,
|
|
1726
|
+
url: response.url,
|
|
1727
|
+
body: jsonBody
|
|
1728
|
+
});
|
|
1729
|
+
}
|
|
1567
1730
|
var RepoImpl = class {
|
|
1568
1731
|
constructor(id, defaultBranch, options, generateJWT) {
|
|
1569
1732
|
this.id = id;
|
|
@@ -1679,6 +1842,132 @@ var RepoImpl = class {
|
|
|
1679
1842
|
next_cursor: raw.next_cursor ?? void 0
|
|
1680
1843
|
});
|
|
1681
1844
|
}
|
|
1845
|
+
async getNote(options) {
|
|
1846
|
+
const sha = options?.sha?.trim();
|
|
1847
|
+
if (!sha) {
|
|
1848
|
+
throw new Error("getNote sha is required");
|
|
1849
|
+
}
|
|
1850
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1851
|
+
const jwt = await this.generateJWT(this.id, {
|
|
1852
|
+
permissions: ["git:read"],
|
|
1853
|
+
ttl
|
|
1854
|
+
});
|
|
1855
|
+
const response = await this.api.get({ path: "repos/notes", params: { sha } }, jwt);
|
|
1856
|
+
const raw = noteReadResponseSchema.parse(await response.json());
|
|
1857
|
+
return transformNoteReadResult(raw);
|
|
1858
|
+
}
|
|
1859
|
+
async createNote(options) {
|
|
1860
|
+
const sha = options?.sha?.trim();
|
|
1861
|
+
if (!sha) {
|
|
1862
|
+
throw new Error("createNote sha is required");
|
|
1863
|
+
}
|
|
1864
|
+
const note = options?.note?.trim();
|
|
1865
|
+
if (!note) {
|
|
1866
|
+
throw new Error("createNote note is required");
|
|
1867
|
+
}
|
|
1868
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1869
|
+
const jwt = await this.generateJWT(this.id, {
|
|
1870
|
+
permissions: ["git:write"],
|
|
1871
|
+
ttl
|
|
1872
|
+
});
|
|
1873
|
+
const body = buildNoteWriteBody(sha, note, "add", {
|
|
1874
|
+
expectedRefSha: options.expectedRefSha,
|
|
1875
|
+
author: options.author
|
|
1876
|
+
});
|
|
1877
|
+
const response = await this.api.post({ path: "repos/notes", body }, jwt, {
|
|
1878
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS]
|
|
1879
|
+
});
|
|
1880
|
+
const result = await parseNoteWriteResponse(response, "POST");
|
|
1881
|
+
if (!result.result.success) {
|
|
1882
|
+
throw new RefUpdateError(
|
|
1883
|
+
result.result.message ?? `createNote failed with status ${result.result.status}`,
|
|
1884
|
+
{
|
|
1885
|
+
status: result.result.status,
|
|
1886
|
+
message: result.result.message,
|
|
1887
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha)
|
|
1888
|
+
}
|
|
1889
|
+
);
|
|
1890
|
+
}
|
|
1891
|
+
return result;
|
|
1892
|
+
}
|
|
1893
|
+
async appendNote(options) {
|
|
1894
|
+
const sha = options?.sha?.trim();
|
|
1895
|
+
if (!sha) {
|
|
1896
|
+
throw new Error("appendNote sha is required");
|
|
1897
|
+
}
|
|
1898
|
+
const note = options?.note?.trim();
|
|
1899
|
+
if (!note) {
|
|
1900
|
+
throw new Error("appendNote note is required");
|
|
1901
|
+
}
|
|
1902
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1903
|
+
const jwt = await this.generateJWT(this.id, {
|
|
1904
|
+
permissions: ["git:write"],
|
|
1905
|
+
ttl
|
|
1906
|
+
});
|
|
1907
|
+
const body = buildNoteWriteBody(sha, note, "append", {
|
|
1908
|
+
expectedRefSha: options.expectedRefSha,
|
|
1909
|
+
author: options.author
|
|
1910
|
+
});
|
|
1911
|
+
const response = await this.api.post({ path: "repos/notes", body }, jwt, {
|
|
1912
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS]
|
|
1913
|
+
});
|
|
1914
|
+
const result = await parseNoteWriteResponse(response, "POST");
|
|
1915
|
+
if (!result.result.success) {
|
|
1916
|
+
throw new RefUpdateError(
|
|
1917
|
+
result.result.message ?? `appendNote failed with status ${result.result.status}`,
|
|
1918
|
+
{
|
|
1919
|
+
status: result.result.status,
|
|
1920
|
+
message: result.result.message,
|
|
1921
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha)
|
|
1922
|
+
}
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
return result;
|
|
1926
|
+
}
|
|
1927
|
+
async deleteNote(options) {
|
|
1928
|
+
const sha = options?.sha?.trim();
|
|
1929
|
+
if (!sha) {
|
|
1930
|
+
throw new Error("deleteNote sha is required");
|
|
1931
|
+
}
|
|
1932
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1933
|
+
const jwt = await this.generateJWT(this.id, {
|
|
1934
|
+
permissions: ["git:write"],
|
|
1935
|
+
ttl
|
|
1936
|
+
});
|
|
1937
|
+
const body = {
|
|
1938
|
+
sha
|
|
1939
|
+
};
|
|
1940
|
+
const expectedRefSha = options.expectedRefSha?.trim();
|
|
1941
|
+
if (expectedRefSha) {
|
|
1942
|
+
body.expected_ref_sha = expectedRefSha;
|
|
1943
|
+
}
|
|
1944
|
+
if (options.author) {
|
|
1945
|
+
const authorName = options.author.name?.trim();
|
|
1946
|
+
const authorEmail = options.author.email?.trim();
|
|
1947
|
+
if (!authorName || !authorEmail) {
|
|
1948
|
+
throw new Error("deleteNote author name and email are required when provided");
|
|
1949
|
+
}
|
|
1950
|
+
body.author = {
|
|
1951
|
+
name: authorName,
|
|
1952
|
+
email: authorEmail
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
const response = await this.api.delete({ path: "repos/notes", body }, jwt, {
|
|
1956
|
+
allowedStatus: [...NOTE_WRITE_ALLOWED_STATUS]
|
|
1957
|
+
});
|
|
1958
|
+
const result = await parseNoteWriteResponse(response, "DELETE");
|
|
1959
|
+
if (!result.result.success) {
|
|
1960
|
+
throw new RefUpdateError(
|
|
1961
|
+
result.result.message ?? `deleteNote failed with status ${result.result.status}`,
|
|
1962
|
+
{
|
|
1963
|
+
status: result.result.status,
|
|
1964
|
+
message: result.result.message,
|
|
1965
|
+
refUpdate: toPartialRefUpdate(result.targetRef, result.baseCommit, result.newRefSha)
|
|
1966
|
+
}
|
|
1967
|
+
);
|
|
1968
|
+
}
|
|
1969
|
+
return result;
|
|
1970
|
+
}
|
|
1682
1971
|
async getBranchDiff(options) {
|
|
1683
1972
|
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
1684
1973
|
const jwt = await this.generateJWT(this.id, {
|
|
@@ -1984,23 +2273,83 @@ var GitStorage = class _GitStorage {
|
|
|
1984
2273
|
permissions: ["repo:write"],
|
|
1985
2274
|
ttl
|
|
1986
2275
|
});
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
2276
|
+
const baseRepo = options?.baseRepo;
|
|
2277
|
+
const isFork = baseRepo ? "id" in baseRepo : false;
|
|
2278
|
+
let baseRepoOptions = null;
|
|
2279
|
+
let resolvedDefaultBranch;
|
|
2280
|
+
if (baseRepo) {
|
|
2281
|
+
if ("id" in baseRepo) {
|
|
2282
|
+
const baseRepoToken = await this.generateJWT(baseRepo.id, {
|
|
2283
|
+
permissions: ["git:read"],
|
|
2284
|
+
ttl
|
|
2285
|
+
});
|
|
2286
|
+
baseRepoOptions = {
|
|
2287
|
+
provider: "code",
|
|
2288
|
+
name: baseRepo.id,
|
|
2289
|
+
operation: "fork",
|
|
2290
|
+
auth: { token: baseRepoToken },
|
|
2291
|
+
...baseRepo.ref ? { ref: baseRepo.ref } : {},
|
|
2292
|
+
...baseRepo.sha ? { sha: baseRepo.sha } : {}
|
|
2293
|
+
};
|
|
2294
|
+
} else {
|
|
2295
|
+
baseRepoOptions = {
|
|
2296
|
+
provider: "github",
|
|
2297
|
+
...snakecaseKeys__default.default(baseRepo)
|
|
2298
|
+
};
|
|
2299
|
+
resolvedDefaultBranch = baseRepo.defaultBranch;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
if (!resolvedDefaultBranch) {
|
|
2303
|
+
if (options?.defaultBranch) {
|
|
2304
|
+
resolvedDefaultBranch = options.defaultBranch;
|
|
2305
|
+
} else if (!isFork) {
|
|
2306
|
+
resolvedDefaultBranch = "main";
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
const createRepoPath = baseRepoOptions || resolvedDefaultBranch ? {
|
|
1993
2310
|
path: "repos",
|
|
1994
2311
|
body: {
|
|
1995
2312
|
...baseRepoOptions && { base_repo: baseRepoOptions },
|
|
1996
|
-
default_branch:
|
|
2313
|
+
...resolvedDefaultBranch && { default_branch: resolvedDefaultBranch }
|
|
1997
2314
|
}
|
|
1998
2315
|
} : "repos";
|
|
1999
2316
|
const resp = await this.api.post(createRepoPath, jwt, { allowedStatus: [409] });
|
|
2000
2317
|
if (resp.status === 409) {
|
|
2001
2318
|
throw new Error("Repository already exists");
|
|
2002
2319
|
}
|
|
2003
|
-
return new RepoImpl(
|
|
2320
|
+
return new RepoImpl(
|
|
2321
|
+
repoId,
|
|
2322
|
+
resolvedDefaultBranch ?? "main",
|
|
2323
|
+
this.options,
|
|
2324
|
+
this.generateJWT.bind(this)
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* List repositories for the authenticated organization
|
|
2329
|
+
* @returns Paginated repositories list
|
|
2330
|
+
*/
|
|
2331
|
+
async listRepos(options) {
|
|
2332
|
+
const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
|
|
2333
|
+
const jwt = await this.generateJWT("org", {
|
|
2334
|
+
permissions: ["org:read"],
|
|
2335
|
+
ttl
|
|
2336
|
+
});
|
|
2337
|
+
let params;
|
|
2338
|
+
if (options?.cursor || typeof options?.limit === "number") {
|
|
2339
|
+
params = {};
|
|
2340
|
+
if (options.cursor) {
|
|
2341
|
+
params.cursor = options.cursor;
|
|
2342
|
+
}
|
|
2343
|
+
if (typeof options.limit === "number") {
|
|
2344
|
+
params.limit = options.limit.toString();
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
const response = await this.api.get({ path: "repos", params }, jwt);
|
|
2348
|
+
const raw = listReposResponseSchema.parse(await response.json());
|
|
2349
|
+
return transformListReposResult({
|
|
2350
|
+
...raw,
|
|
2351
|
+
next_cursor: raw.next_cursor ?? void 0
|
|
2352
|
+
});
|
|
2004
2353
|
}
|
|
2005
2354
|
/**
|
|
2006
2355
|
* Find a repository by ID
|