From 7e05e1bf0c7f0b9b5056a050718a5124ae1da1ca Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 2 Dec 2024 00:41:12 +0100 Subject: [PATCH] Use random port for dev server --- .../keycloakify/generateFtl/generateFtl.ts | 7 +++- .../kcContextDeclarationTemplate.ftl | 4 +- src/bin/start-keycloak/start-keycloak.ts | 21 ++++++----- src/bin/start-keycloak/startViteDevServer.ts | 37 ++++++++++++++++--- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts index 71331b7a..b73ee7d7 100644 --- a/src/bin/keycloakify/generateFtl/generateFtl.ts +++ b/src/bin/keycloakify/generateFtl/generateFtl.ts @@ -11,7 +11,11 @@ import * as fs from "fs"; import { join as pathJoin } from "path"; import type { BuildContext } from "../../shared/buildContext"; import { assert } from "tsafe/assert"; -import { type ThemeType, WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../shared/constants"; +import { + type ThemeType, + WELL_KNOWN_DIRECTORY_BASE_NAME, + KEYCLOAKIFY_SPA_DEV_SERVER_PORT +} from "../../shared/constants"; import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath"; export type BuildContextLike = BuildContextLike_replaceImportsInJsCode & @@ -116,6 +120,7 @@ export function generateFtlFilesCodeFactory(params: { .replace("{{themeVersion}}", buildContext.themeVersion) .replace("{{fieldNames}}", fieldNames.map(name => `"${name}"`).join(", ")) .replace("{{RESOURCES_COMMON}}", WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON) + .replace("{{KEYCLOAKIFY_SPA_DEV_SERVER_PORT}}", KEYCLOAKIFY_SPA_DEV_SERVER_PORT) .replace( "{{userDefinedExclusions}}", buildContext.kcContextExclusionsFtlCode ?? "" diff --git a/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl b/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl index 782baac5..1dce06db 100644 --- a/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +++ b/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl @@ -101,7 +101,7 @@ redirect_to_dev_server: { break redirect_to_dev_server; } - const devSeverPort = kcContext.properties.KEYCLOAKIFY_SPA_DEV_SERVER_PORT; + const devSeverPort = kcContext.properties.{{KEYCLOAKIFY_SPA_DEV_SERVER_PORT}}; if( !devSeverPort ){ break redirect_to_dev_server; @@ -115,7 +115,7 @@ redirect_to_dev_server: { console.log(kcContext); - redirectUrl.searchParams.set("kcContext", encodeURIComponent(JSON.stringify(kcContext)) ); + redirectUrl.searchParams.set("kcContext", encodeURIComponent(JSON.stringify(kcContext))); window.location.href = redirectUrl.toString(); diff --git a/src/bin/start-keycloak/start-keycloak.ts b/src/bin/start-keycloak/start-keycloak.ts index 2d812a38..42326c93 100644 --- a/src/bin/start-keycloak/start-keycloak.ts +++ b/src/bin/start-keycloak/start-keycloak.ts @@ -380,14 +380,14 @@ export async function command(params: { const port = cliCommandOptions.port ?? buildContext.startKeycloakOptions.port ?? DEFAULT_PORT; - const devServerPort = (() => { + const doStartDevServer = (() => { const hasSpaUi = buildContext.implementedThemeTypes.admin.isImplemented || (buildContext.implementedThemeTypes.account.isImplemented && buildContext.implementedThemeTypes.account.type === "Single-Page"); if (!hasSpaUi) { - return undefined; + return false; } if (buildContext.bundler !== "vite") { @@ -401,7 +401,7 @@ export async function command(params: { ) ); - return undefined; + return false; } if (keycloakMajorVersionNumber < 25) { @@ -415,17 +415,18 @@ export async function command(params: { ) ); - return undefined; + return false; } - return port + 1; + return true; })(); - if (devServerPort !== undefined) { - startViteDevServer({ - buildContext, - port: devServerPort - }); + let devServerPort: number | undefined = undefined; + + if (doStartDevServer) { + const { port } = await startViteDevServer({ buildContext }); + + devServerPort = port; } const SPACE_PLACEHOLDER = "SPACE_PLACEHOLDER_xKLmdPd"; diff --git a/src/bin/start-keycloak/startViteDevServer.ts b/src/bin/start-keycloak/startViteDevServer.ts index 7e96d288..0a5cff6e 100644 --- a/src/bin/start-keycloak/startViteDevServer.ts +++ b/src/bin/start-keycloak/startViteDevServer.ts @@ -3,6 +3,7 @@ import { assert } from "tsafe/assert"; import type { BuildContext } from "../shared/buildContext"; import chalk from "chalk"; import { VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES } from "../shared/constants"; +import { Deferred } from "evt/tools/Deferred"; export type BuildContextLike = { projectDirPath: string; @@ -12,13 +13,12 @@ assert(); export function startViteDevServer(params: { buildContext: BuildContextLike; - port: number; -}): void { - const { buildContext, port } = params; +}): Promise<{ port: number }> { + const { buildContext } = params; - console.log(chalk.blue(`$ npx vite dev --port ${port}`)); + console.log(chalk.blue(`$ npx vite dev`)); - const child = child_process.spawn("npx", ["vite", "dev", "--port", `${port}`], { + const child = child_process.spawn("npx", ["vite", "dev"], { cwd: buildContext.projectDirPath, env: { ...process.env, @@ -36,4 +36,31 @@ export function startViteDevServer(params: { }); child.stderr.on("data", data => process.stderr.write(data)); + + const dPort = new Deferred(); + + { + const onData = (data: Buffer) => { + //Local: http://localhost:8083/ + const match = data + .toString("utf8") + .match(/Local:\s*http:\/\/(?:localhost|127\.0\.0\.1):(\d+)\//); + + if (match === null) { + return; + } + + child.stdout.off("data", onData); + + const port = parseInt(match[1]); + + assert(!isNaN(port)); + + dPort.resolve(port); + }; + + child.stdout.on("data", onData); + } + + return dPort.pr.then(port => ({ port })); }