@ghfs/cli 0.0.1 → 0.0.2
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/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +2277 -0
- package/dist/factory-CNz1r4PQ.mjs +428 -0
- package/dist/index.d.mts +194 -0
- package/dist/index.mjs +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import { retry } from "@octokit/plugin-retry";
|
|
2
|
+
import { throttling } from "@octokit/plugin-throttling";
|
|
3
|
+
import { Octokit } from "octokit";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/repo.ts
|
|
6
|
+
function splitRepo(repo) {
|
|
7
|
+
const [owner, name] = repo.split("/");
|
|
8
|
+
if (!owner || !name) throw new Error(`Invalid repo slug: ${repo}`);
|
|
9
|
+
return {
|
|
10
|
+
owner,
|
|
11
|
+
repo: name
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/providers/helpers.ts
|
|
17
|
+
async function collectPages(pages) {
|
|
18
|
+
const items = [];
|
|
19
|
+
for await (const page of pages) items.push(...page);
|
|
20
|
+
return items;
|
|
21
|
+
}
|
|
22
|
+
async function* iteratePages(pages) {
|
|
23
|
+
for await (const page of pages) for (const item of page) yield item;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/providers/github/client.ts
|
|
28
|
+
const BaseOctokit = Octokit.plugin(retry, throttling);
|
|
29
|
+
function createGitHubClient(token) {
|
|
30
|
+
return new BaseOctokit({
|
|
31
|
+
auth: token,
|
|
32
|
+
throttle: {
|
|
33
|
+
onRateLimit: (retryAfter, options) => {
|
|
34
|
+
if ((options.request.retryCount ?? 0) < 2) return true;
|
|
35
|
+
return false;
|
|
36
|
+
},
|
|
37
|
+
onSecondaryRateLimit: () => {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
retry: {
|
|
42
|
+
doNotRetry: [401, 403],
|
|
43
|
+
retries: 2
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/providers/github/provider.ts
|
|
50
|
+
function createGitHubProvider(options) {
|
|
51
|
+
const octokit = createGitHubClient(options.token);
|
|
52
|
+
const { owner, repo } = options;
|
|
53
|
+
let requestCount = 0;
|
|
54
|
+
const bumpRequestCount = () => {
|
|
55
|
+
requestCount += 1;
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
paginateItems: (paginateOptions) => paginateItems(octokit, owner, repo, paginateOptions, bumpRequestCount),
|
|
59
|
+
fetchItems: (paginateOptions) => fetchItems(octokit, owner, repo, paginateOptions, bumpRequestCount),
|
|
60
|
+
eachItem: (paginateOptions) => eachItem(octokit, owner, repo, paginateOptions, bumpRequestCount),
|
|
61
|
+
fetchItemsByNumbers: (numbers) => fetchItemsByNumbers(octokit, owner, repo, numbers, bumpRequestCount),
|
|
62
|
+
fetchComments: (number) => fetchComments(octokit, owner, repo, number, bumpRequestCount),
|
|
63
|
+
fetchPullMetadata: (number) => fetchPullMetadata(octokit, owner, repo, number, bumpRequestCount),
|
|
64
|
+
fetchPullPatch: (number) => fetchPullPatch(octokit, owner, repo, number, bumpRequestCount),
|
|
65
|
+
fetchItemSnapshot: (number) => fetchItemSnapshot(octokit, owner, repo, number, bumpRequestCount),
|
|
66
|
+
fetchRepository: () => fetchRepository(octokit, owner, repo, bumpRequestCount),
|
|
67
|
+
fetchRepositoryLabels: () => fetchRepositoryLabels(octokit, owner, repo, bumpRequestCount),
|
|
68
|
+
fetchRepositoryMilestones: () => fetchRepositoryMilestones(octokit, owner, repo, bumpRequestCount),
|
|
69
|
+
getRequestCount: () => requestCount,
|
|
70
|
+
actionClose: (number) => actionClose(octokit, owner, repo, number, bumpRequestCount),
|
|
71
|
+
actionReopen: (number) => actionReopen(octokit, owner, repo, number, bumpRequestCount),
|
|
72
|
+
actionSetTitle: (number, title) => actionSetTitle(octokit, owner, repo, number, title, bumpRequestCount),
|
|
73
|
+
actionSetBody: (number, body) => actionSetBody(octokit, owner, repo, number, body, bumpRequestCount),
|
|
74
|
+
actionAddComment: (number, body) => actionAddComment(octokit, owner, repo, number, body, bumpRequestCount),
|
|
75
|
+
actionAddLabels: (number, labels) => actionAddLabels(octokit, owner, repo, number, labels, bumpRequestCount),
|
|
76
|
+
actionRemoveLabels: (number, labels) => actionRemoveLabels(octokit, owner, repo, number, labels, bumpRequestCount),
|
|
77
|
+
actionSetLabels: (number, labels) => actionSetLabels(octokit, owner, repo, number, labels, bumpRequestCount),
|
|
78
|
+
actionAddAssignees: (number, assignees) => actionAddAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
|
|
79
|
+
actionRemoveAssignees: (number, assignees) => actionRemoveAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
|
|
80
|
+
actionSetAssignees: (number, assignees) => actionSetAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
|
|
81
|
+
actionSetMilestone: (number, milestone) => actionSetMilestone(octokit, owner, repo, number, milestone, bumpRequestCount),
|
|
82
|
+
actionClearMilestone: (number) => actionClearMilestone(octokit, owner, repo, number, bumpRequestCount),
|
|
83
|
+
actionLock: (number, reason) => actionLock(octokit, owner, repo, number, reason, bumpRequestCount),
|
|
84
|
+
actionUnlock: (number) => actionUnlock(octokit, owner, repo, number, bumpRequestCount),
|
|
85
|
+
actionRequestReviewers: (number, reviewers) => actionRequestReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount),
|
|
86
|
+
actionRemoveReviewers: (number, reviewers) => actionRemoveReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount),
|
|
87
|
+
actionMarkReadyForReview: (number) => actionMarkReadyForReview(octokit, owner, repo, number, bumpRequestCount),
|
|
88
|
+
actionConvertToDraft: (number) => actionConvertToDraft(octokit, owner, repo, number, bumpRequestCount)
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async function* paginateItems(octokit, owner, repo, options, bumpRequestCount) {
|
|
92
|
+
const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
|
|
93
|
+
owner,
|
|
94
|
+
repo,
|
|
95
|
+
state: options.state,
|
|
96
|
+
sort: "updated",
|
|
97
|
+
direction: "asc",
|
|
98
|
+
per_page: 100,
|
|
99
|
+
since: options.since
|
|
100
|
+
});
|
|
101
|
+
for await (const page of iterator) {
|
|
102
|
+
bumpRequestCount();
|
|
103
|
+
yield page.data.map(mapIssue);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function fetchItems(octokit, owner, repo, options, bumpRequestCount) {
|
|
107
|
+
return await collectPages(paginateItems(octokit, owner, repo, options, bumpRequestCount));
|
|
108
|
+
}
|
|
109
|
+
async function* eachItem(octokit, owner, repo, options, bumpRequestCount) {
|
|
110
|
+
yield* iteratePages(paginateItems(octokit, owner, repo, options, bumpRequestCount));
|
|
111
|
+
}
|
|
112
|
+
async function fetchItemsByNumbers(octokit, owner, repo, numbers, bumpRequestCount) {
|
|
113
|
+
return (await Promise.all(numbers.map(async (number) => {
|
|
114
|
+
bumpRequestCount();
|
|
115
|
+
return mapIssue((await octokit.rest.issues.get({
|
|
116
|
+
owner,
|
|
117
|
+
repo,
|
|
118
|
+
issue_number: number
|
|
119
|
+
})).data);
|
|
120
|
+
}))).sort((a, b) => a.number - b.number);
|
|
121
|
+
}
|
|
122
|
+
async function fetchComments(octokit, owner, repo, number, bumpRequestCount) {
|
|
123
|
+
bumpRequestCount();
|
|
124
|
+
return (await octokit.paginate(octokit.rest.issues.listComments, {
|
|
125
|
+
owner,
|
|
126
|
+
repo,
|
|
127
|
+
issue_number: number,
|
|
128
|
+
per_page: 100
|
|
129
|
+
})).map(mapComment);
|
|
130
|
+
}
|
|
131
|
+
async function fetchPullMetadata(octokit, owner, repo, number, bumpRequestCount) {
|
|
132
|
+
bumpRequestCount();
|
|
133
|
+
const pull = (await octokit.rest.pulls.get({
|
|
134
|
+
owner,
|
|
135
|
+
repo,
|
|
136
|
+
pull_number: number
|
|
137
|
+
})).data;
|
|
138
|
+
return {
|
|
139
|
+
isDraft: pull.draft,
|
|
140
|
+
merged: pull.merged,
|
|
141
|
+
mergedAt: pull.merged_at,
|
|
142
|
+
baseRef: pull.base.ref,
|
|
143
|
+
headRef: pull.head.ref,
|
|
144
|
+
requestedReviewers: pull.requested_reviewers.map((reviewer) => reviewer.login)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
async function fetchPullPatch(octokit, owner, repo, number, bumpRequestCount) {
|
|
148
|
+
bumpRequestCount();
|
|
149
|
+
const result = await octokit.request("GET /repos/{owner}/{repo}/pulls/{pull_number}", {
|
|
150
|
+
owner,
|
|
151
|
+
repo,
|
|
152
|
+
pull_number: number,
|
|
153
|
+
mediaType: { format: "patch" }
|
|
154
|
+
});
|
|
155
|
+
if (typeof result.data === "string") return result.data;
|
|
156
|
+
throw new Error(`Unexpected patch response for pull #${number}`);
|
|
157
|
+
}
|
|
158
|
+
async function fetchItemSnapshot(octokit, owner, repo, number, bumpRequestCount) {
|
|
159
|
+
bumpRequestCount();
|
|
160
|
+
const issue = (await octokit.rest.issues.get({
|
|
161
|
+
owner,
|
|
162
|
+
repo,
|
|
163
|
+
issue_number: number
|
|
164
|
+
})).data;
|
|
165
|
+
return {
|
|
166
|
+
number,
|
|
167
|
+
kind: issue.pull_request ? "pull" : "issue",
|
|
168
|
+
updatedAt: issue.updated_at ?? null
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async function fetchRepository(octokit, owner, repo, bumpRequestCount) {
|
|
172
|
+
bumpRequestCount();
|
|
173
|
+
return (await octokit.rest.repos.get({
|
|
174
|
+
owner,
|
|
175
|
+
repo
|
|
176
|
+
})).data;
|
|
177
|
+
}
|
|
178
|
+
async function fetchRepositoryLabels(octokit, owner, repo, bumpRequestCount) {
|
|
179
|
+
bumpRequestCount();
|
|
180
|
+
return await octokit.paginate(octokit.rest.issues.listLabelsForRepo, {
|
|
181
|
+
owner,
|
|
182
|
+
repo,
|
|
183
|
+
per_page: 100
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
async function fetchRepositoryMilestones(octokit, owner, repo, bumpRequestCount) {
|
|
187
|
+
bumpRequestCount();
|
|
188
|
+
return await octokit.paginate(octokit.rest.issues.listMilestones, {
|
|
189
|
+
owner,
|
|
190
|
+
repo,
|
|
191
|
+
state: "all",
|
|
192
|
+
per_page: 100
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async function actionClose(octokit, owner, repo, number, bumpRequestCount) {
|
|
196
|
+
bumpRequestCount();
|
|
197
|
+
await octokit.rest.issues.update({
|
|
198
|
+
owner,
|
|
199
|
+
repo,
|
|
200
|
+
issue_number: number,
|
|
201
|
+
state: "closed"
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async function actionReopen(octokit, owner, repo, number, bumpRequestCount) {
|
|
205
|
+
bumpRequestCount();
|
|
206
|
+
await octokit.rest.issues.update({
|
|
207
|
+
owner,
|
|
208
|
+
repo,
|
|
209
|
+
issue_number: number,
|
|
210
|
+
state: "open"
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async function actionSetTitle(octokit, owner, repo, number, title, bumpRequestCount) {
|
|
214
|
+
bumpRequestCount();
|
|
215
|
+
await octokit.rest.issues.update({
|
|
216
|
+
owner,
|
|
217
|
+
repo,
|
|
218
|
+
issue_number: number,
|
|
219
|
+
title
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async function actionSetBody(octokit, owner, repo, number, body, bumpRequestCount) {
|
|
223
|
+
bumpRequestCount();
|
|
224
|
+
await octokit.rest.issues.update({
|
|
225
|
+
owner,
|
|
226
|
+
repo,
|
|
227
|
+
issue_number: number,
|
|
228
|
+
body
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async function actionAddComment(octokit, owner, repo, number, body, bumpRequestCount) {
|
|
232
|
+
bumpRequestCount();
|
|
233
|
+
await octokit.rest.issues.createComment({
|
|
234
|
+
owner,
|
|
235
|
+
repo,
|
|
236
|
+
issue_number: number,
|
|
237
|
+
body
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
async function actionAddLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
|
|
241
|
+
bumpRequestCount();
|
|
242
|
+
await octokit.rest.issues.addLabels({
|
|
243
|
+
owner,
|
|
244
|
+
repo,
|
|
245
|
+
issue_number: number,
|
|
246
|
+
labels
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async function actionRemoveLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
|
|
250
|
+
for (const label of labels) try {
|
|
251
|
+
bumpRequestCount();
|
|
252
|
+
await octokit.rest.issues.removeLabel({
|
|
253
|
+
owner,
|
|
254
|
+
repo,
|
|
255
|
+
issue_number: number,
|
|
256
|
+
name: label
|
|
257
|
+
});
|
|
258
|
+
} catch (error) {
|
|
259
|
+
if (error.status !== 404) throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async function actionSetLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
|
|
263
|
+
bumpRequestCount();
|
|
264
|
+
await octokit.rest.issues.setLabels({
|
|
265
|
+
owner,
|
|
266
|
+
repo,
|
|
267
|
+
issue_number: number,
|
|
268
|
+
labels
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
async function actionAddAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
|
|
272
|
+
bumpRequestCount();
|
|
273
|
+
await octokit.rest.issues.addAssignees({
|
|
274
|
+
owner,
|
|
275
|
+
repo,
|
|
276
|
+
issue_number: number,
|
|
277
|
+
assignees
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async function actionRemoveAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
|
|
281
|
+
bumpRequestCount();
|
|
282
|
+
await octokit.rest.issues.removeAssignees({
|
|
283
|
+
owner,
|
|
284
|
+
repo,
|
|
285
|
+
issue_number: number,
|
|
286
|
+
assignees
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
async function actionSetAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
|
|
290
|
+
bumpRequestCount();
|
|
291
|
+
await octokit.rest.issues.update({
|
|
292
|
+
owner,
|
|
293
|
+
repo,
|
|
294
|
+
issue_number: number,
|
|
295
|
+
assignees
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async function actionSetMilestone(octokit, owner, repo, number, milestone, bumpRequestCount) {
|
|
299
|
+
const resolvedMilestone = await resolveMilestone(octokit, owner, repo, milestone, bumpRequestCount);
|
|
300
|
+
bumpRequestCount();
|
|
301
|
+
await octokit.rest.issues.update({
|
|
302
|
+
owner,
|
|
303
|
+
repo,
|
|
304
|
+
issue_number: number,
|
|
305
|
+
milestone: resolvedMilestone
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
async function actionClearMilestone(octokit, owner, repo, number, bumpRequestCount) {
|
|
309
|
+
bumpRequestCount();
|
|
310
|
+
await octokit.rest.issues.update({
|
|
311
|
+
owner,
|
|
312
|
+
repo,
|
|
313
|
+
issue_number: number,
|
|
314
|
+
milestone: null
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
async function actionLock(octokit, owner, repo, number, reason, bumpRequestCount) {
|
|
318
|
+
bumpRequestCount();
|
|
319
|
+
await octokit.rest.issues.lock({
|
|
320
|
+
owner,
|
|
321
|
+
repo,
|
|
322
|
+
issue_number: number,
|
|
323
|
+
lock_reason: normalizeLockReason(reason)
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
async function actionUnlock(octokit, owner, repo, number, bumpRequestCount) {
|
|
327
|
+
bumpRequestCount();
|
|
328
|
+
await octokit.rest.issues.unlock({
|
|
329
|
+
owner,
|
|
330
|
+
repo,
|
|
331
|
+
issue_number: number
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async function actionRequestReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount) {
|
|
335
|
+
bumpRequestCount();
|
|
336
|
+
await octokit.rest.pulls.requestReviewers({
|
|
337
|
+
owner,
|
|
338
|
+
repo,
|
|
339
|
+
pull_number: number,
|
|
340
|
+
reviewers
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
async function actionRemoveReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount) {
|
|
344
|
+
bumpRequestCount();
|
|
345
|
+
await octokit.rest.pulls.removeRequestedReviewers({
|
|
346
|
+
owner,
|
|
347
|
+
repo,
|
|
348
|
+
pull_number: number,
|
|
349
|
+
reviewers
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
async function actionMarkReadyForReview(octokit, owner, repo, number, bumpRequestCount) {
|
|
353
|
+
bumpRequestCount();
|
|
354
|
+
await octokit.request("POST /repos/{owner}/{repo}/pulls/{pull_number}/ready_for_review", {
|
|
355
|
+
owner,
|
|
356
|
+
repo,
|
|
357
|
+
pull_number: number
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
async function actionConvertToDraft(octokit, owner, repo, number, bumpRequestCount) {
|
|
361
|
+
bumpRequestCount();
|
|
362
|
+
await octokit.request("POST /repos/{owner}/{repo}/pulls/{pull_number}/convert-to-draft", {
|
|
363
|
+
owner,
|
|
364
|
+
repo,
|
|
365
|
+
pull_number: number
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async function resolveMilestone(octokit, owner, repo, value, bumpRequestCount) {
|
|
369
|
+
if (typeof value === "number") return value;
|
|
370
|
+
if (/^\d+$/.test(value)) return Number(value);
|
|
371
|
+
bumpRequestCount();
|
|
372
|
+
const matched = (await octokit.paginate(octokit.rest.issues.listMilestones, {
|
|
373
|
+
owner,
|
|
374
|
+
repo,
|
|
375
|
+
state: "all",
|
|
376
|
+
per_page: 100
|
|
377
|
+
})).find((item) => item.title === value);
|
|
378
|
+
if (!matched) throw new Error(`Milestone not found: ${value}`);
|
|
379
|
+
return matched.number;
|
|
380
|
+
}
|
|
381
|
+
function normalizeLockReason(reason) {
|
|
382
|
+
if (!reason) return void 0;
|
|
383
|
+
if (reason === "too-heated") return "too heated";
|
|
384
|
+
return reason;
|
|
385
|
+
}
|
|
386
|
+
function mapIssue(issue) {
|
|
387
|
+
return {
|
|
388
|
+
number: issue.number,
|
|
389
|
+
kind: issue.pull_request ? "pull" : "issue",
|
|
390
|
+
...issue.html_url ? { url: issue.html_url } : {},
|
|
391
|
+
state: issue.state === "closed" ? "closed" : "open",
|
|
392
|
+
updatedAt: issue.updated_at,
|
|
393
|
+
createdAt: issue.created_at,
|
|
394
|
+
closedAt: issue.closed_at,
|
|
395
|
+
title: issue.title,
|
|
396
|
+
body: issue.body,
|
|
397
|
+
author: issue.user?.login ?? null,
|
|
398
|
+
labels: issue.labels.map((label) => {
|
|
399
|
+
if (typeof label === "string") return label;
|
|
400
|
+
return label.name ?? void 0;
|
|
401
|
+
}).filter((label) => Boolean(label)),
|
|
402
|
+
assignees: (issue.assignees ?? []).map((assignee) => assignee.login),
|
|
403
|
+
milestone: issue.milestone?.title ?? null
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function mapComment(comment) {
|
|
407
|
+
return {
|
|
408
|
+
id: comment.id,
|
|
409
|
+
body: comment.body,
|
|
410
|
+
createdAt: comment.created_at,
|
|
411
|
+
updatedAt: comment.updated_at,
|
|
412
|
+
author: comment.user?.login ?? null
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/providers/factory.ts
|
|
418
|
+
function createRepositoryProvider(options) {
|
|
419
|
+
const { owner, repo } = splitRepo(options.repo);
|
|
420
|
+
return createGitHubProvider({
|
|
421
|
+
token: options.token,
|
|
422
|
+
owner,
|
|
423
|
+
repo
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
//#endregion
|
|
428
|
+
export { createRepositoryProvider as t };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
//#region src/types/config.d.ts
|
|
2
|
+
interface GhfsUserConfig {
|
|
3
|
+
/**
|
|
4
|
+
* The repository to sync.
|
|
5
|
+
*
|
|
6
|
+
* Will try to detect the repository from the current working directory or the `package.json` file.
|
|
7
|
+
*/
|
|
8
|
+
repo?: string;
|
|
9
|
+
/**
|
|
10
|
+
* The directory to store the synced issues and pull requests.
|
|
11
|
+
*
|
|
12
|
+
* @default '.ghfs'
|
|
13
|
+
*/
|
|
14
|
+
directory?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The authentication configuration.
|
|
17
|
+
*/
|
|
18
|
+
auth?: {
|
|
19
|
+
/**
|
|
20
|
+
* The GitHub personal access token to use for authentication.
|
|
21
|
+
*
|
|
22
|
+
* When not provided, will try to get the token from `gh auth token` or the environment variables `GH_TOKEN` or `GITHUB_TOKEN`.
|
|
23
|
+
*/
|
|
24
|
+
token?: string;
|
|
25
|
+
};
|
|
26
|
+
sync?: {
|
|
27
|
+
/**
|
|
28
|
+
* Whether to sync issues.
|
|
29
|
+
*
|
|
30
|
+
* @default true
|
|
31
|
+
*/
|
|
32
|
+
issues?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to sync pull requests.
|
|
35
|
+
*
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
pulls?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* When to sync closed issues and pull requests.
|
|
41
|
+
*
|
|
42
|
+
* - `'existing'`: only sync closed issues and pull requests that already exist in the local filesystem.
|
|
43
|
+
* - `'all'`: sync all closed issues and pull requests.
|
|
44
|
+
* - `false`: don't sync any closed issues and pull requests. And delete any existing closed issues and pull requests from the local filesystem.
|
|
45
|
+
*
|
|
46
|
+
* @default 'existing'
|
|
47
|
+
*/
|
|
48
|
+
closed?: 'existing' | 'all' | false;
|
|
49
|
+
/**
|
|
50
|
+
* When to download the pull request patch files.
|
|
51
|
+
*
|
|
52
|
+
* - `'open'`: only download open pull request patch files.
|
|
53
|
+
* - `'all'`: download all pull request patch files.
|
|
54
|
+
* - `false`: don't download any pull request patch files.
|
|
55
|
+
*
|
|
56
|
+
* @default 'open'
|
|
57
|
+
*/
|
|
58
|
+
patches?: 'open' | 'all' | false;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
type GhfsResolvedConfig = Required<GhfsUserConfig> & {
|
|
62
|
+
cwd: string;
|
|
63
|
+
auth: Required<GhfsUserConfig['auth']>;
|
|
64
|
+
sync: Required<GhfsUserConfig['sync']>;
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/types/issue.d.ts
|
|
68
|
+
type IssueKind = 'issue' | 'pull';
|
|
69
|
+
type IssueState = 'open' | 'closed';
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/types/provider.d.ts
|
|
72
|
+
interface ProviderItem {
|
|
73
|
+
number: number;
|
|
74
|
+
kind: IssueKind;
|
|
75
|
+
url?: string;
|
|
76
|
+
state: IssueState;
|
|
77
|
+
updatedAt: string;
|
|
78
|
+
createdAt: string;
|
|
79
|
+
closedAt: string | null;
|
|
80
|
+
title: string;
|
|
81
|
+
body: string | null;
|
|
82
|
+
author: string | null;
|
|
83
|
+
labels: string[];
|
|
84
|
+
assignees: string[];
|
|
85
|
+
milestone: string | null;
|
|
86
|
+
}
|
|
87
|
+
interface ProviderComment {
|
|
88
|
+
id: number;
|
|
89
|
+
body: string | null;
|
|
90
|
+
createdAt: string;
|
|
91
|
+
updatedAt: string;
|
|
92
|
+
author: string | null;
|
|
93
|
+
}
|
|
94
|
+
interface ProviderPullMetadata {
|
|
95
|
+
isDraft: boolean;
|
|
96
|
+
merged: boolean;
|
|
97
|
+
mergedAt: string | null;
|
|
98
|
+
baseRef: string;
|
|
99
|
+
headRef: string;
|
|
100
|
+
requestedReviewers: string[];
|
|
101
|
+
}
|
|
102
|
+
interface ProviderRepository {
|
|
103
|
+
name: string;
|
|
104
|
+
full_name: string;
|
|
105
|
+
description: string | null;
|
|
106
|
+
private: boolean;
|
|
107
|
+
archived: boolean;
|
|
108
|
+
default_branch: string;
|
|
109
|
+
html_url: string;
|
|
110
|
+
fork: boolean;
|
|
111
|
+
open_issues_count: number;
|
|
112
|
+
has_issues: boolean;
|
|
113
|
+
has_projects: boolean;
|
|
114
|
+
has_wiki: boolean;
|
|
115
|
+
created_at: string;
|
|
116
|
+
updated_at: string;
|
|
117
|
+
pushed_at: string | null;
|
|
118
|
+
owner: {
|
|
119
|
+
login: string;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
interface ProviderLabel {
|
|
123
|
+
name: string;
|
|
124
|
+
color: string;
|
|
125
|
+
description: string | null;
|
|
126
|
+
default: boolean;
|
|
127
|
+
}
|
|
128
|
+
interface ProviderMilestone {
|
|
129
|
+
number: number;
|
|
130
|
+
title: string;
|
|
131
|
+
state: 'open' | 'closed';
|
|
132
|
+
description: string | null;
|
|
133
|
+
due_on: string | null;
|
|
134
|
+
open_issues: number;
|
|
135
|
+
closed_issues: number;
|
|
136
|
+
created_at: string;
|
|
137
|
+
updated_at: string;
|
|
138
|
+
closed_at: string | null;
|
|
139
|
+
}
|
|
140
|
+
interface ProviderItemSnapshot {
|
|
141
|
+
number: number;
|
|
142
|
+
kind: IssueKind;
|
|
143
|
+
updatedAt: string | null;
|
|
144
|
+
}
|
|
145
|
+
type ProviderLockReason = 'resolved' | 'off-topic' | 'too heated' | 'too-heated' | 'spam';
|
|
146
|
+
interface PaginateItemsOptions {
|
|
147
|
+
state: IssueState | 'all';
|
|
148
|
+
since?: string;
|
|
149
|
+
}
|
|
150
|
+
interface RepositoryProvider {
|
|
151
|
+
paginateItems: (options: PaginateItemsOptions) => AsyncIterable<ProviderItem[]>;
|
|
152
|
+
fetchItems: (options: PaginateItemsOptions) => Promise<ProviderItem[]>;
|
|
153
|
+
eachItem: (options: PaginateItemsOptions) => AsyncIterable<ProviderItem>;
|
|
154
|
+
fetchItemsByNumbers: (numbers: number[]) => Promise<ProviderItem[]>;
|
|
155
|
+
fetchComments: (number: number) => Promise<ProviderComment[]>;
|
|
156
|
+
fetchPullMetadata: (number: number) => Promise<ProviderPullMetadata>;
|
|
157
|
+
fetchPullPatch: (number: number) => Promise<string>;
|
|
158
|
+
fetchItemSnapshot: (number: number) => Promise<ProviderItemSnapshot>;
|
|
159
|
+
fetchRepository: () => Promise<ProviderRepository>;
|
|
160
|
+
fetchRepositoryLabels: () => Promise<ProviderLabel[]>;
|
|
161
|
+
fetchRepositoryMilestones: () => Promise<ProviderMilestone[]>;
|
|
162
|
+
getRequestCount: () => number;
|
|
163
|
+
actionClose: (number: number) => Promise<void>;
|
|
164
|
+
actionReopen: (number: number) => Promise<void>;
|
|
165
|
+
actionSetTitle: (number: number, title: string) => Promise<void>;
|
|
166
|
+
actionSetBody: (number: number, body: string) => Promise<void>;
|
|
167
|
+
actionAddComment: (number: number, body: string) => Promise<void>;
|
|
168
|
+
actionAddLabels: (number: number, labels: string[]) => Promise<void>;
|
|
169
|
+
actionRemoveLabels: (number: number, labels: string[]) => Promise<void>;
|
|
170
|
+
actionSetLabels: (number: number, labels: string[]) => Promise<void>;
|
|
171
|
+
actionAddAssignees: (number: number, assignees: string[]) => Promise<void>;
|
|
172
|
+
actionRemoveAssignees: (number: number, assignees: string[]) => Promise<void>;
|
|
173
|
+
actionSetAssignees: (number: number, assignees: string[]) => Promise<void>;
|
|
174
|
+
actionSetMilestone: (number: number, milestone: string | number) => Promise<void>;
|
|
175
|
+
actionClearMilestone: (number: number) => Promise<void>;
|
|
176
|
+
actionLock: (number: number, reason?: ProviderLockReason) => Promise<void>;
|
|
177
|
+
actionUnlock: (number: number) => Promise<void>;
|
|
178
|
+
actionRequestReviewers: (number: number, reviewers: string[]) => Promise<void>;
|
|
179
|
+
actionRemoveReviewers: (number: number, reviewers: string[]) => Promise<void>;
|
|
180
|
+
actionMarkReadyForReview: (number: number) => Promise<void>;
|
|
181
|
+
actionConvertToDraft: (number: number) => Promise<void>;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/providers/factory.d.ts
|
|
185
|
+
interface CreateRepositoryProviderOptions {
|
|
186
|
+
token: string;
|
|
187
|
+
repo: string;
|
|
188
|
+
}
|
|
189
|
+
declare function createRepositoryProvider(options: CreateRepositoryProviderOptions): RepositoryProvider;
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/index.d.ts
|
|
192
|
+
declare function defineConfig(config: GhfsUserConfig): GhfsUserConfig;
|
|
193
|
+
//#endregion
|
|
194
|
+
export { type GhfsResolvedConfig, type GhfsUserConfig, type IssueKind, type IssueState, type PaginateItemsOptions, type ProviderComment, type ProviderItem, type ProviderItemSnapshot, type ProviderLockReason, type ProviderPullMetadata, type RepositoryProvider, createRepositoryProvider, defineConfig };
|
package/dist/index.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghfs/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|