@bensandee/forgejo-cli 0.5.4 → 0.5.6
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/bin.mjs +37 -25
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -162,7 +162,7 @@ function loadEnvFileForBin(rawArgs, bin, io = processIo) {
|
|
|
162
162
|
//#region src/version.ts
|
|
163
163
|
const parsed = z.object({ version: z.string() }).safeParse({
|
|
164
164
|
name: "@bensandee/forgejo-cli",
|
|
165
|
-
version: "0.5.
|
|
165
|
+
version: "0.5.6",
|
|
166
166
|
description: "bst-fj: Forgejo API commands without the rest of bst",
|
|
167
167
|
license: "MIT",
|
|
168
168
|
repository: {
|
|
@@ -1664,6 +1664,16 @@ const commitStatusCommand = defineCommand({
|
|
|
1664
1664
|
}
|
|
1665
1665
|
});
|
|
1666
1666
|
//#endregion
|
|
1667
|
+
//#region ../forgejo/src/fetcher.ts
|
|
1668
|
+
const LONG_FETCH_TIMEOUT_MS = 6e5;
|
|
1669
|
+
function morePagesFollow(res, pageLength, received, pageSize) {
|
|
1670
|
+
if (pageLength === 0) return false;
|
|
1671
|
+
const raw = res.headers.get("x-total-count")?.trim() ?? "";
|
|
1672
|
+
const total = raw === "" ? NaN : Number(raw);
|
|
1673
|
+
if (!Number.isSafeInteger(total) || total < 0) return pageLength >= pageSize;
|
|
1674
|
+
return received < total;
|
|
1675
|
+
}
|
|
1676
|
+
//#endregion
|
|
1667
1677
|
//#region ../forgejo/src/label-provisioning.ts
|
|
1668
1678
|
const LabelSchema = z.object({
|
|
1669
1679
|
id: z.number(),
|
|
@@ -1673,7 +1683,7 @@ const LabelSchema = z.object({
|
|
|
1673
1683
|
exclusive: z.boolean().optional()
|
|
1674
1684
|
});
|
|
1675
1685
|
const LabelListSchema = z.array(LabelSchema);
|
|
1676
|
-
const LABELS_PAGE_SIZE =
|
|
1686
|
+
const LABELS_PAGE_SIZE = 50;
|
|
1677
1687
|
const LABELS_MAX_PAGES = 20;
|
|
1678
1688
|
async function fetchAllForgejoLabels(executor, conn) {
|
|
1679
1689
|
const labels = [];
|
|
@@ -1686,7 +1696,7 @@ async function fetchAllForgejoLabels(executor, conn) {
|
|
|
1686
1696
|
const parsed = LabelListSchema.safeParse(await res.json());
|
|
1687
1697
|
if (!parsed.success) throw new UnexpectedError(`Unexpected label-list response: ${parsed.error.message}`);
|
|
1688
1698
|
labels.push(...parsed.data);
|
|
1689
|
-
if (parsed.data.length
|
|
1699
|
+
if (!morePagesFollow(res, parsed.data.length, labels.length, LABELS_PAGE_SIZE)) break;
|
|
1690
1700
|
}
|
|
1691
1701
|
return labels;
|
|
1692
1702
|
}
|
|
@@ -1900,7 +1910,10 @@ async function fetchIssueListPage(executor, conn, params) {
|
|
|
1900
1910
|
verb: "list issues",
|
|
1901
1911
|
resource: conn.repository
|
|
1902
1912
|
}, repoNotFoundMessage(conn));
|
|
1903
|
-
return
|
|
1913
|
+
return {
|
|
1914
|
+
raw: parseIssueListOrThrow(await res.json()),
|
|
1915
|
+
res
|
|
1916
|
+
};
|
|
1904
1917
|
}
|
|
1905
1918
|
function normalizeDetailedIssues(raw, type) {
|
|
1906
1919
|
const normalized = raw.map(normalizeIssue);
|
|
@@ -1911,7 +1924,7 @@ const DETAILED_LIST_MAX_PAGES = 20;
|
|
|
1911
1924
|
async function listForgejoIssuesDetailedPaged(executor, conn, query, options) {
|
|
1912
1925
|
const issues = [];
|
|
1913
1926
|
for (let page = 1; page <= DETAILED_LIST_MAX_PAGES; page++) {
|
|
1914
|
-
const raw = await fetchIssueListPage(executor, conn, issueListParams(query.type, {
|
|
1927
|
+
const { raw } = await fetchIssueListPage(executor, conn, issueListParams(query.type, {
|
|
1915
1928
|
...query,
|
|
1916
1929
|
limit: DETAILED_LIST_PAGE_SIZE,
|
|
1917
1930
|
page
|
|
@@ -2301,9 +2314,6 @@ const labelsCommand = defineCommand({
|
|
|
2301
2314
|
}
|
|
2302
2315
|
});
|
|
2303
2316
|
//#endregion
|
|
2304
|
-
//#region ../forgejo/src/fetcher.ts
|
|
2305
|
-
const LONG_FETCH_TIMEOUT_MS = 6e5;
|
|
2306
|
-
//#endregion
|
|
2307
2317
|
//#region ../forgejo/src/releases.ts
|
|
2308
2318
|
const SETTLE_ATTEMPTS = 4;
|
|
2309
2319
|
const SETTLE_BASE_DELAY_MS = 2e3;
|
|
@@ -2794,7 +2804,7 @@ const deleteCommand = defineCommand({
|
|
|
2794
2804
|
const secretsCommand = defineCommand({
|
|
2795
2805
|
meta: {
|
|
2796
2806
|
name: "secrets",
|
|
2797
|
-
description: "Low-level CRUD for individual Forgejo Actions secrets (set, list, delete). Use bst setup:secrets (in @bensandee/tooling) for initial repo onboarding"
|
|
2807
|
+
description: "Low-level CRUD for individual Forgejo Actions secrets (set, list, delete). Use pnpm exec bst setup:secrets (in @bensandee/tooling) for initial repo onboarding"
|
|
2798
2808
|
},
|
|
2799
2809
|
args: { json: {
|
|
2800
2810
|
type: "boolean",
|
|
@@ -2891,7 +2901,7 @@ async function paginate(executor, conn, endpoint, verb, extract) {
|
|
|
2891
2901
|
}));
|
|
2892
2902
|
const items = extract(await res.json());
|
|
2893
2903
|
all.push(...items);
|
|
2894
|
-
if (items.length
|
|
2904
|
+
if (!morePagesFollow(res, items.length, all.length, PAGE_LIMIT)) break;
|
|
2895
2905
|
if (page === 101) throw new UnexpectedError(`${endpoint} still returns full pages after ${String(MAX_PAGES)} pages; refusing to report a prefix of it`);
|
|
2896
2906
|
}
|
|
2897
2907
|
return all;
|
|
@@ -3876,7 +3886,7 @@ async function listForgejoComments(executor, conn, number, options = {}) {
|
|
|
3876
3886
|
}, issueNotFoundMessage(conn, number));
|
|
3877
3887
|
const parsed = parseCommentListOrThrow(await res.json());
|
|
3878
3888
|
comments.push(...parsed.map(normalizeComment));
|
|
3879
|
-
if (parsed.length
|
|
3889
|
+
if (!morePagesFollow(res, parsed.length, comments.length, COMMENTS_PAGE_SIZE)) break;
|
|
3880
3890
|
if (page === COMMENTS_MAX_PAGES) {
|
|
3881
3891
|
log.warn(`Comment listing for #${String(number)} hit the ${String(COMMENTS_MAX_PAGES)}-page cap; results may be truncated`);
|
|
3882
3892
|
options.onPageCap?.();
|
|
@@ -4505,7 +4515,7 @@ function formatIssueList(result) {
|
|
|
4505
4515
|
//#endregion
|
|
4506
4516
|
//#region src/issue-transport.ts
|
|
4507
4517
|
function githubRefusal(command) {
|
|
4508
|
-
return `bst-fj is Forgejo-only -- use \`gh\` or \`bst ${command}\` for a github.com repository.`;
|
|
4518
|
+
return `bst-fj is Forgejo-only -- use \`gh\` or \`pnpm exec bst ${command}\` for a github.com repository.`;
|
|
4509
4519
|
}
|
|
4510
4520
|
function forgejoIssueTarget(cwd, target, command) {
|
|
4511
4521
|
const conn = requireForgejoTarget(cwd, target, githubRefusal(command));
|
|
@@ -4580,7 +4590,7 @@ const issueCommentCommand = defineCommand({
|
|
|
4580
4590
|
out.json(result);
|
|
4581
4591
|
out.text(formatIssueComment(result, dryRun));
|
|
4582
4592
|
} catch (error) {
|
|
4583
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("bst-fj issue:comment 273"));
|
|
4593
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("pnpm exec bst-fj issue:comment 273"));
|
|
4584
4594
|
throw error;
|
|
4585
4595
|
}
|
|
4586
4596
|
}
|
|
@@ -4807,7 +4817,7 @@ const issueDownloadCommand = defineCommand({
|
|
|
4807
4817
|
out.json(result);
|
|
4808
4818
|
out.text(formatDownload(result, dryRun));
|
|
4809
4819
|
} catch (error) {
|
|
4810
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("bst-fj issue:download 273"));
|
|
4820
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("pnpm exec bst-fj issue:download 273"));
|
|
4811
4821
|
if (error instanceof AttachmentExistsError) throw new FatalError(describeAttachmentExists(error, "--force"));
|
|
4812
4822
|
throw error;
|
|
4813
4823
|
}
|
|
@@ -4987,7 +4997,7 @@ function defineIssueLabelCommand(action) {
|
|
|
4987
4997
|
out.json(result);
|
|
4988
4998
|
out.text(formatIssueLabel(result, dryRun));
|
|
4989
4999
|
} catch (error) {
|
|
4990
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired(`bst-fj ${name} 273 agent/implement`));
|
|
5000
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired(`pnpm exec bst-fj ${name} 273 agent/implement`));
|
|
4991
5001
|
throw error;
|
|
4992
5002
|
}
|
|
4993
5003
|
}
|
|
@@ -5050,7 +5060,7 @@ const issueSetLabelsCommand = defineCommand({
|
|
|
5050
5060
|
out.json(result);
|
|
5051
5061
|
out.text(formatIssueSetLabels(result, dryRun));
|
|
5052
5062
|
} catch (error) {
|
|
5053
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("bst-fj issue:set-labels 273 agent/plan"));
|
|
5063
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("pnpm exec bst-fj issue:set-labels 273 agent/plan"));
|
|
5054
5064
|
if (error instanceof NoLabelsGivenError) throw new FatalError(describeNoLabelsGiven(error, "--clear"));
|
|
5055
5065
|
throw error;
|
|
5056
5066
|
}
|
|
@@ -5214,10 +5224,10 @@ function defineIssueStateCommand(action) {
|
|
|
5214
5224
|
out.text(formatIssueState(result, dryRun));
|
|
5215
5225
|
if (dryRun && comment !== void 0 && result.comment?.posted === true) out.text(`[dry-run] Comment that would be posted:\n${comment}`);
|
|
5216
5226
|
} catch (error) {
|
|
5217
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired(`bst-fj ${name} 273`));
|
|
5227
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired(`pnpm exec bst-fj ${name} 273`));
|
|
5218
5228
|
if (error instanceof EmptyCommentError) throw new FatalError(describeEmptyComment(flags));
|
|
5219
5229
|
if (error instanceof PullRequestStateError) {
|
|
5220
|
-
const advice = action === "close" ? `Run \`bst-fj pr:close ${String(error.number)}\` to close it.` : "Use the forge UI to change a pull request's state.";
|
|
5230
|
+
const advice = action === "close" ? `Run \`pnpm exec bst-fj pr:close ${String(error.number)}\` to close it.` : "Use the forge UI to change a pull request's state.";
|
|
5221
5231
|
throw new FatalError(describePullRequestState(error, {
|
|
5222
5232
|
command: `bst-fj ${name}`,
|
|
5223
5233
|
advice
|
|
@@ -5351,7 +5361,7 @@ const issueUpdateCommand = defineCommand({
|
|
|
5351
5361
|
out.text(`[dry-run] Current body:\n${current}`);
|
|
5352
5362
|
}
|
|
5353
5363
|
} catch (error) {
|
|
5354
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("bst-fj issue:update 273 --title '...'"));
|
|
5364
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("pnpm exec bst-fj issue:update 273 --title '...'"));
|
|
5355
5365
|
if (error instanceof NothingToUpdateError) throw new FatalError(describeNothingToUpdate({
|
|
5356
5366
|
title: "--title",
|
|
5357
5367
|
body: "--body",
|
|
@@ -5399,7 +5409,7 @@ const issueSubCommands = {
|
|
|
5399
5409
|
out.json(view);
|
|
5400
5410
|
out.text(formatIssue(view));
|
|
5401
5411
|
} catch (error) {
|
|
5402
|
-
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("bst-fj issue:view 273"));
|
|
5412
|
+
if (error instanceof IssueNumberRequiredError) throw new FatalError(describeIssueNumberRequired("pnpm exec bst-fj issue:view 273"));
|
|
5403
5413
|
throw error;
|
|
5404
5414
|
}
|
|
5405
5415
|
}
|
|
@@ -5776,7 +5786,7 @@ const prCloseCommand = defineCommand({
|
|
|
5776
5786
|
if (dryRun && comment !== void 0 && result.comment?.posted === true) out.text(`[dry-run] Comment that would be posted:\n${comment}`);
|
|
5777
5787
|
} catch (error) {
|
|
5778
5788
|
if (error instanceof EmptyCommentError) throw new FatalError(describeEmptyComment(flags));
|
|
5779
|
-
if (error instanceof NotAPullRequestError) throw new FatalError(`#${String(error.number)} is an issue, not a pull request -- pr:close refuses to write issue state. Use \`bst-fj issue:close ${String(error.number)}\` to close it.`);
|
|
5789
|
+
if (error instanceof NotAPullRequestError) throw new FatalError(`#${String(error.number)} is an issue, not a pull request -- pr:close refuses to write issue state. Use \`pnpm exec bst-fj issue:close ${String(error.number)}\` to close it.`);
|
|
5780
5790
|
throw error;
|
|
5781
5791
|
}
|
|
5782
5792
|
}
|
|
@@ -6327,8 +6337,8 @@ function cliGit() {
|
|
|
6327
6337
|
//#endregion
|
|
6328
6338
|
//#region src/pr-run.ts
|
|
6329
6339
|
const COMMANDS = {
|
|
6330
|
-
create: "bst-fj pr:create",
|
|
6331
|
-
update: "bst-fj pr:update"
|
|
6340
|
+
create: "pnpm exec bst-fj pr:create",
|
|
6341
|
+
update: "pnpm exec bst-fj pr:update"
|
|
6332
6342
|
};
|
|
6333
6343
|
const FLAGS = {
|
|
6334
6344
|
body: "--body",
|
|
@@ -6411,7 +6421,7 @@ const prCreateCommand = defineCommand({
|
|
|
6411
6421
|
async run({ args }) {
|
|
6412
6422
|
const out = createCliOutput(args.json === true);
|
|
6413
6423
|
const body = readBodySource(args.body ?? void 0, args["body-file"] ?? void 0);
|
|
6414
|
-
const result = await runForgejoPr("bst-fj pr:create works on Forgejo only. Use `gh pr create` on GitHub, or `bst pr:create`, which covers both.", {
|
|
6424
|
+
const result = await runForgejoPr("bst-fj pr:create works on Forgejo only. Use `gh pr create` on GitHub, or `pnpm exec bst pr:create`, which covers both.", {
|
|
6415
6425
|
mode: args.upsert === true ? "upsert" : "create",
|
|
6416
6426
|
title: args.title ?? void 0,
|
|
6417
6427
|
body,
|
|
@@ -6434,6 +6444,7 @@ const prCreateCommand = defineCommand({
|
|
|
6434
6444
|
const DEFAULT_LIMIT = 100;
|
|
6435
6445
|
const PrFileEntrySchema = z.object({
|
|
6436
6446
|
filename: z.string(),
|
|
6447
|
+
previous_filename: z.string().nullish(),
|
|
6437
6448
|
status: z.string().nullish(),
|
|
6438
6449
|
additions: z.number().default(0),
|
|
6439
6450
|
deletions: z.number().default(0)
|
|
@@ -6466,6 +6477,7 @@ async function readPrFilesPage(executor, conn, prNumber, page, limit) {
|
|
|
6466
6477
|
return {
|
|
6467
6478
|
files: parsed.data.map((file) => ({
|
|
6468
6479
|
filename: file.filename,
|
|
6480
|
+
previousFilename: file.previous_filename ?? null,
|
|
6469
6481
|
status: file.status ?? null,
|
|
6470
6482
|
additions: file.additions,
|
|
6471
6483
|
deletions: file.deletions
|
|
@@ -7144,7 +7156,7 @@ const prSubCommands = {
|
|
|
7144
7156
|
const out = createCliOutput(args.json === true);
|
|
7145
7157
|
const body = readBodySource(args.body ?? void 0, args["body-file"] ?? void 0);
|
|
7146
7158
|
const rewrites = args.title !== void 0 || body !== void 0;
|
|
7147
|
-
const result = await runForgejoPr("bst-fj pr:update works on Forgejo only. Use `gh pr edit` on GitHub, or `bst pr:update`, which covers both.", {
|
|
7159
|
+
const result = await runForgejoPr("bst-fj pr:update works on Forgejo only. Use `gh pr edit` on GitHub, or `pnpm exec bst pr:update`, which covers both.", {
|
|
7148
7160
|
mode: "update",
|
|
7149
7161
|
title: args.title ?? void 0,
|
|
7150
7162
|
body,
|