diff --git a/package.json b/package.json index bf9da4a..cccbcb0 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "@types/tar-js": "^0.3.5", "axios": "^1.6.2", "commander": "^11.1.0", + "compare-versions": "^6.1.0", "dockerode": "^4.0.2", "env-paths": "^2.2.1", "formdata-node": "^6.0.3", diff --git a/src/cli/utils.ts b/src/cli/utils.ts index e221079..8753a0f 100644 --- a/src/cli/utils.ts +++ b/src/cli/utils.ts @@ -9,6 +9,7 @@ import { type Duplex, Writable } from "stream"; import { fileURLToPath } from "url"; import axios from "axios"; +import { compareVersions } from "compare-versions"; import Docker from "dockerode"; import type { Schema } from "jsonschema"; import nunjucks from "nunjucks"; @@ -494,21 +495,36 @@ export async function getDockerImageTags( repository: string, username: string = "sindrilabs", ): Promise { - const url = `https://hub.docker.com/v2/repositories/${username}/${repository}/tags/`; - const { - data: { results }, - } = await axios.get<{ - results: Array<{ - last_updated: string; - name: string; - tag_status: string; - }>; - }>(url); + let url: string | undefined = + `https://hub.docker.com/v2/repositories/${username}/${repository}/tags/?page_size=1`; + interface Result { + last_updated: string; + name: string; + tag_status: string; + } + interface Response { + count: number; + next?: string; + previous: string | null; + results: Result[]; + } + let results: Result[] = []; + + while (url) { + const response: { data: Response } = await axios.get(url); + + results = results.concat(response.data.results); + url = response.data.next; // Update the URL for the next request, or null if no more pages + } + return results .filter(({ tag_status }) => tag_status === "active") .filter(({ name }) => name !== "dev") .sort((a, b) => a.last_updated.localeCompare(b.last_updated)) - .map(({ name }) => name); + .map(({ name }) => name) + .sort((a, b) => + a === "latest" ? 1 : b === "latest" ? -1 : compareVersions(a, b), + ); } /** diff --git a/yarn.lock b/yarn.lock index 8b16ae6..fe733aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1670,6 +1670,11 @@ common-path-prefix@^3.0.0: resolved "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz" integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== +compare-versions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.0.tgz#3f2131e3ae93577df111dba133e6db876ffe127a" + integrity sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"