@m8t-stack/cli 0.2.133 → 0.2.134

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.js CHANGED
@@ -1454,7 +1454,7 @@ function installFoundryDnsShim() {
1454
1454
  }
1455
1455
 
1456
1456
  // src/lib/package-version.ts
1457
- var CLI_VERSION = "0.2.133";
1457
+ var CLI_VERSION = "0.2.134";
1458
1458
 
1459
1459
  // src/lib/render-error.ts
1460
1460
  init_errors();
@@ -21082,17 +21082,63 @@ async function fetchPublicTags(repo, fetchImpl = fetch) {
21082
21082
  hint: "Make the package public (deploy/ghcr-package-visibility.md), then retry."
21083
21083
  });
21084
21084
  }
21085
- const tagsRes = await fetchImpl(`https://ghcr.io/v2/${path47}/tags/list`, {
21086
- headers: { Authorization: `Bearer ${token}` }
21087
- });
21088
- if (!tagsRes.ok) {
21089
- throw new LocalCliError({
21090
- code: "PLATFORM_GHCR_TAGS_FAILED",
21091
- message: `Could not list tags for ${repo} (HTTP ${tagsRes.status.toString()}).`
21085
+ const expectedPath = `/v2/${path47}/tags/list`;
21086
+ let pageUrl = new URL(`https://ghcr.io${expectedPath}`);
21087
+ pageUrl.searchParams.set("n", "1000");
21088
+ const visited = /* @__PURE__ */ new Set();
21089
+ const tags = /* @__PURE__ */ new Set();
21090
+ const maxPages = 100;
21091
+ for (let page = 0; page < maxPages; page += 1) {
21092
+ const href = pageUrl.toString();
21093
+ if (visited.has(href)) {
21094
+ throw new LocalCliError({
21095
+ code: "PLATFORM_GHCR_TAGS_PAGINATION_LOOP",
21096
+ message: `GHCR returned a pagination loop while listing tags for ${repo}.`
21097
+ });
21098
+ }
21099
+ visited.add(href);
21100
+ const tagsRes = await fetchImpl(href, {
21101
+ headers: { Authorization: `Bearer ${token}` }
21092
21102
  });
21103
+ if (!tagsRes.ok) {
21104
+ throw new LocalCliError({
21105
+ code: "PLATFORM_GHCR_TAGS_FAILED",
21106
+ message: `Could not list tags for ${repo} (HTTP ${tagsRes.status.toString()}).`
21107
+ });
21108
+ }
21109
+ const body = await tagsRes.json();
21110
+ if (body.tags !== void 0 && (!Array.isArray(body.tags) || body.tags.some((tag) => typeof tag !== "string"))) {
21111
+ throw new LocalCliError({
21112
+ code: "PLATFORM_GHCR_TAGS_INVALID",
21113
+ message: `GHCR returned an invalid tags list for ${repo}.`
21114
+ });
21115
+ }
21116
+ for (const tag of body.tags ?? []) tags.add(tag);
21117
+ const next = nextLink(tagsRes.headers.get("link"));
21118
+ if (!next) return [...tags];
21119
+ const nextUrl = new URL(next, pageUrl);
21120
+ if (nextUrl.origin !== "https://ghcr.io" || nextUrl.pathname !== expectedPath || nextUrl.username !== "" || nextUrl.password !== "" || nextUrl.hash !== "") {
21121
+ throw new LocalCliError({
21122
+ code: "PLATFORM_GHCR_TAGS_PAGINATION_UNSAFE",
21123
+ message: `GHCR returned an unsafe pagination link while listing tags for ${repo}.`
21124
+ });
21125
+ }
21126
+ pageUrl = nextUrl;
21093
21127
  }
21094
- const body = await tagsRes.json();
21095
- return body.tags ?? [];
21128
+ throw new LocalCliError({
21129
+ code: "PLATFORM_GHCR_TAGS_PAGINATION_LIMIT",
21130
+ message: `GHCR returned more than ${maxPages.toString()} tag pages for ${repo}.`
21131
+ });
21132
+ }
21133
+ function nextLink(header) {
21134
+ if (!header) return null;
21135
+ for (const entry of header.split(/,(?=\s*<)/)) {
21136
+ const target = /^\s*<([^>]+)>/.exec(entry)?.[1];
21137
+ if (!target) continue;
21138
+ const rel = entry.split(";").slice(1).map((parameter) => /^\s*rel\s*=\s*"?([^";]+)"?\s*$/i.exec(parameter)?.[1]).find((value) => value !== void 0);
21139
+ if (rel?.split(/\s+/).includes("next")) return target;
21140
+ }
21141
+ return null;
21096
21142
  }
21097
21143
 
21098
21144
  // src/lib/release-channel.ts