diff --git a/src/bin/main.ts b/src/bin/main.ts index 3ff5c163..eac850d2 100644 --- a/src/bin/main.ts +++ b/src/bin/main.ts @@ -5,9 +5,6 @@ import { readThisNpmPackageVersion } from "./tools/readThisNpmPackageVersion"; import * as child_process from "child_process"; import { assertNoPnpmDlx } from "./tools/assertNoPnpmDlx"; import { getBuildContext } from "./shared/buildContext"; -import { SemVer } from "./tools/SemVer"; -import { assert, is } from "tsafe/assert"; -import chalk from "chalk"; type CliCommandOptions = { projectDirPath: string | undefined; @@ -137,47 +134,11 @@ program handler: async ({ projectDirPath, keycloakVersion, port, realmJsonFilePath }) => { const { command } = await import("./start-keycloak"); - validate_keycloak_version: { - if (keycloakVersion === undefined) { - break validate_keycloak_version; - } - - const isValidVersion = (() => { - if (typeof keycloakVersion === "number") { - return false; - } - - try { - SemVer.parse(keycloakVersion); - } catch { - return false; - } - - return; - })(); - - if (isValidVersion) { - break validate_keycloak_version; - } - - console.log( - chalk.red( - [ - `Invalid Keycloak version: ${keycloakVersion}`, - "It should be a valid semver version example: 26.0.4" - ].join(" ") - ) - ); - - process.exit(1); - } - - assert(is(keycloakVersion)); - await command({ buildContext: getBuildContext({ projectDirPath }), cliCommandOptions: { - keycloakVersion, + keycloakVersion: + keycloakVersion === undefined ? undefined : `${keycloakVersion}`, port, realmJsonFilePath } diff --git a/src/bin/start-keycloak/getSupportedDockerImageTags.ts b/src/bin/start-keycloak/getSupportedDockerImageTags.ts index fdc33cb1..22e02238 100644 --- a/src/bin/start-keycloak/getSupportedDockerImageTags.ts +++ b/src/bin/start-keycloak/getSupportedDockerImageTags.ts @@ -10,6 +10,7 @@ import { join as pathJoin, dirname as pathDirname } from "path"; import * as fs from "fs/promises"; import { existsAsync } from "../tools/fs.existsAsync"; import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion"; +import type { ReturnType } from "tsafe"; export type BuildContextLike = { fetchOptions: BuildContext["fetchOptions"]; @@ -20,7 +21,10 @@ assert; export async function getSupportedDockerImageTags(params: { buildContext: BuildContextLike; -}) { +}): Promise<{ + allSupportedTags: string[]; + latestMajorTags: string[]; +}> { const { buildContext } = params; { @@ -31,14 +35,14 @@ export async function getSupportedDockerImageTags(params: { } } - const tags: string[] = []; + const tags_queryResponse: string[] = []; await (async function callee(url: string) { const r = await fetch(url, buildContext.fetchOptions); await Promise.all([ (async () => { - tags.push( + tags_queryResponse.push( ...z .object({ tags: z.array(z.string()) @@ -70,7 +74,9 @@ export async function getSupportedDockerImageTags(params: { ]); })("https://quay.io/v2/keycloak/keycloak/tags/list"); - const arr = tags + const supportedKeycloakMajorVersions = getSupportedKeycloakMajorVersions(); + + const allSupportedTags_withVersion = tags_queryResponse .map(tag => ({ tag, version: (() => { @@ -86,28 +92,35 @@ export async function getSupportedDockerImageTags(params: { return undefined; } + if (tag.split(".").length !== 3) { + return undefined; + } + + if (!supportedKeycloakMajorVersions.includes(version.major)) { + return undefined; + } + return version; })() })) .map(({ tag, version }) => (version === undefined ? undefined : { tag, version })) - .filter(exclude(undefined)); + .filter(exclude(undefined)) + .sort(({ version: a }, { version: b }) => SemVer.compare(b, a)); - const versionByMajor: Record = {}; + const latestTagByMajor: Record = {}; - for (const { version } of arr) { - const version_current = versionByMajor[version.major]; + for (const { version } of allSupportedTags_withVersion) { + const version_current = latestTagByMajor[version.major]; if ( version_current === undefined || SemVer.compare(version_current, version) === -1 ) { - versionByMajor[version.major] = version; + latestTagByMajor[version.major] = version; } } - const supportedKeycloakMajorVersions = getSupportedKeycloakMajorVersions(); - - const result = Object.entries(versionByMajor) + const latestMajorTags = Object.entries(latestTagByMajor) .sort(([a], [b]) => parseInt(b) - parseInt(a)) .map(([, version]) => version) .map(version => { @@ -121,16 +134,40 @@ export async function getSupportedDockerImageTags(params: { }) .filter(exclude(undefined)); + const allSupportedTags = allSupportedTags_withVersion.map(({ tag }) => tag); + + const result = { + latestMajorTags, + allSupportedTags + }; + await setCachedValue({ cacheDirPath: buildContext.cacheDirPath, result }); return result; } const { getCachedValue, setCachedValue } = (() => { + type Result = ReturnType; + + const zResult = (() => { + type TargetType = Result; + + const zTargetType = z.object({ + allSupportedTags: z.array(z.string()), + latestMajorTags: z.array(z.string()) + }); + + type InferredType = z.infer; + + assert>; + + return id>(zTargetType); + })(); + type Cache = { keycloakifyVersion: string; time: number; - result: string[]; + result: Result; }; const zCache = (() => { @@ -139,7 +176,7 @@ const { getCachedValue, setCachedValue } = (() => { const zTargetType = z.object({ keycloakifyVersion: z.string(), time: z.number(), - result: z.array(z.string()) + result: zResult }); type InferredType = z.infer; diff --git a/src/bin/start-keycloak/start-keycloak.ts b/src/bin/start-keycloak/start-keycloak.ts index a4b88a58..f8880a43 100644 --- a/src/bin/start-keycloak/start-keycloak.ts +++ b/src/bin/start-keycloak/start-keycloak.ts @@ -97,7 +97,7 @@ export async function command(params: { const { cliCommandOptions, buildContext } = params; - const availableTags = await getSupportedDockerImageTags({ + const { allSupportedTags, latestMajorTags } = await getSupportedDockerImageTags({ buildContext }); @@ -105,7 +105,7 @@ export async function command(params: { if (cliCommandOptions.keycloakVersion !== undefined) { const cliCommandOptions_keycloakVersion = cliCommandOptions.keycloakVersion; - const tag = availableTags.find(tag => + const tag = allSupportedTags.find(tag => tag.startsWith(cliCommandOptions_keycloakVersion) ); @@ -143,7 +143,7 @@ export async function command(params: { ); const { value: tag } = await cliSelect({ - values: availableTags + values: latestMajorTags }).catch(() => { process.exit(-1); });