@bensandee/forgejo-cli 0.5.3 → 0.5.4

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.
Files changed (2) hide show
  1. package/dist/bin.mjs +21 -21
  2. package/package.json +4 -4
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.3",
165
+ version: "0.5.4",
166
166
  description: "bst-fj: Forgejo API commands without the rest of bst",
167
167
  license: "MIT",
168
168
  repository: {
@@ -192,13 +192,13 @@ const parsed = z.object({ version: z.string() }).safeParse({
192
192
  dependencies: {
193
193
  "@bensandee/common": "0.2.0",
194
194
  "citty": "^0.2.2",
195
- "zod": "^4.6.5"
195
+ "zod": "^4.6.7"
196
196
  },
197
197
  devDependencies: {
198
198
  "@bensandee/cli-kit": "workspace:*",
199
199
  "@bensandee/forgejo": "workspace:*",
200
- "@types/node": "24.19.1",
201
- "tsdown": "0.23.0"
200
+ "@types/node": "24.19.2",
201
+ "tsdown": "0.23.1"
202
202
  }
203
203
  });
204
204
  if (!parsed.success) throw new UnexpectedError(`@bensandee/forgejo-cli's package.json has no string version.`);
@@ -896,7 +896,8 @@ function resolveRepoUrlFrom(readOrigin, readPackageUrl) {
896
896
  const originUrl = normalizeGitUrl(readOrigin() ?? "");
897
897
  if (originUrl !== null && parseGitUrl(originUrl) !== null) return originUrl;
898
898
  const pkgUrl = readPackageUrl();
899
- return pkgUrl !== null && parseGitUrl(pkgUrl) !== null ? pkgUrl : null;
899
+ if (pkgUrl === null || parseGitUrl(pkgUrl) === null) return null;
900
+ return normalizeGitUrl(pkgUrl);
900
901
  }
901
902
  function resolveForgejoConnection(env, repoUrl) {
902
903
  const serverUrl = env["FORGEJO_SERVER_URL"];
@@ -987,10 +988,11 @@ function resolveIssueTarget(refTarget, repo) {
987
988
  throw new RepoTargetMismatchError(`${repoTarget.serverUrl}/${repoTarget.repository}`, `${refTarget.serverUrl}/${refTarget.repository}`);
988
989
  }
989
990
  function normalizeGitUrl(raw) {
990
- const sshMatch = raw.match(/^git@([^:]+):(.+?)(?:\.git)?$/);
991
+ const value = raw.startsWith("git+") ? raw.slice(4) : raw;
992
+ const sshMatch = value.match(/^git@([^:]+):(.+?)(?:\.git)?$/);
991
993
  if (sshMatch) return `https://${sshMatch[1]}/${sshMatch[2]}`;
992
994
  try {
993
- const url = new URL(raw);
995
+ const url = new URL(value);
994
996
  url.pathname = url.pathname.replace(/\.git$/, "");
995
997
  url.username = "";
996
998
  url.password = "";
@@ -2576,10 +2578,9 @@ const releaseCreateCommand = defineCommand({
2576
2578
  });
2577
2579
  //#endregion
2578
2580
  //#region ../forgejo/src/secrets.ts
2579
- const ActionSecretListSchema = z.object({
2580
- secrets: z.array(z.object({ name: z.string() })),
2581
- total_count: z.number()
2582
- });
2581
+ const ActionSecretListSchema = z.array(z.object({ name: z.string() }));
2582
+ const SECRETS_PAGE_SIZE = 50;
2583
+ const SECRETS_MAX_PAGES = 20;
2583
2584
  z.object({ sha1: z.string() });
2584
2585
  const NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
2585
2586
  const FORBIDDEN_PREFIX_PATTERN = /^(FORGEJO_|GITEA_|GITHUB_|[0-9])/i;
@@ -2605,10 +2606,8 @@ async function setActionSecret(executor, conn, secretName, secretValue) {
2605
2606
  async function listActionSecrets(executor, conn) {
2606
2607
  const [owner, repo] = conn.repository.split("/");
2607
2608
  const names = [];
2608
- let page = 1;
2609
- const limit = 50;
2610
- for (;;) {
2611
- const url = `${conn.serverUrl}/api/v1/repos/${owner}/${repo}/actions/secrets?page=${String(page)}&limit=${String(limit)}`;
2609
+ for (let page = 1; page <= 21; page++) {
2610
+ const url = `${conn.serverUrl}/api/v1/repos/${owner}/${repo}/actions/secrets?page=${String(page)}&limit=${String(SECRETS_PAGE_SIZE)}`;
2612
2611
  const res = await executor.fetch(url, { headers: { Authorization: `token ${conn.token}` } });
2613
2612
  if (!res.ok) throw new TransientError(await forgejoErrorMessage(res, {
2614
2613
  verb: "list secrets",
@@ -2616,9 +2615,9 @@ async function listActionSecrets(executor, conn) {
2616
2615
  }));
2617
2616
  const parsed = ActionSecretListSchema.safeParse(await res.json());
2618
2617
  if (!parsed.success) throw new UnexpectedError(`Unexpected secrets list response: ${parsed.error.message}`);
2619
- for (const secret of parsed.data.secrets) names.push(secret.name);
2620
- if (names.length >= parsed.data.total_count) break;
2621
- page++;
2618
+ for (const secret of parsed.data) names.push(secret.name);
2619
+ if (parsed.data.length === 0) break;
2620
+ if (page === 21) throw new UnexpectedError(`${owner}/${repo} still lists secrets after ${String(SECRETS_MAX_PAGES)} pages; refusing to report a prefix of them`);
2622
2621
  }
2623
2622
  return names;
2624
2623
  }
@@ -2879,11 +2878,11 @@ async function hasAdminAccess(executor, conn) {
2879
2878
  const OrgSchema = z.object({ username: z.string() });
2880
2879
  const OrgListSchema = z.array(OrgSchema);
2881
2880
  const PAGE_LIMIT = 50;
2881
+ const MAX_PAGES = 100;
2882
2882
  async function paginate(executor, conn, endpoint, verb, extract) {
2883
2883
  const all = [];
2884
- let page = 1;
2885
2884
  const separator = endpoint.includes("?") ? "&" : "?";
2886
- for (;;) {
2885
+ for (let page = 1; page <= 101; page++) {
2887
2886
  const url = `${conn.serverUrl}/api/v1${endpoint}${separator}page=${String(page)}&limit=${String(PAGE_LIMIT)}`;
2888
2887
  const res = await executor.fetch(url, { headers: { Authorization: `token ${conn.token}` } });
2889
2888
  if (!res.ok) throw new TransientError(await forgejoErrorMessage(res, {
@@ -2893,7 +2892,7 @@ async function paginate(executor, conn, endpoint, verb, extract) {
2893
2892
  const items = extract(await res.json());
2894
2893
  all.push(...items);
2895
2894
  if (items.length < PAGE_LIMIT) break;
2896
- page++;
2895
+ if (page === 101) throw new UnexpectedError(`${endpoint} still returns full pages after ${String(MAX_PAGES)} pages; refusing to report a prefix of it`);
2897
2896
  }
2898
2897
  return all;
2899
2898
  }
@@ -3516,6 +3515,7 @@ function collectInputArgs(rawArgs) {
3516
3515
  for (let i = 0; i < rawArgs.length; i += 1) {
3517
3516
  const arg = rawArgs[i];
3518
3517
  if (arg === void 0) continue;
3518
+ if (arg === "--") break;
3519
3519
  if (arg === INPUT_FLAG) {
3520
3520
  const next = rawArgs[i + 1];
3521
3521
  if (next === void 0) throw new FatalError("Missing value for --input: expected `--input key=value`");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/forgejo-cli",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "bst-fj: Forgejo API commands without the rest of bst",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,13 +29,13 @@
29
29
  "dependencies": {
30
30
  "@bensandee/common": "0.2.0",
31
31
  "citty": "^0.2.2",
32
- "zod": "^4.6.5"
32
+ "zod": "^4.6.7"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@bensandee/cli-kit": "0.0.0",
36
36
  "@bensandee/forgejo": "0.7.0",
37
- "@types/node": "24.19.1",
38
- "tsdown": "0.23.0"
37
+ "@types/node": "24.19.2",
38
+ "tsdown": "0.23.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsdown",