Restore realm configuration
This commit is contained in:
@ -68,7 +68,11 @@ program
|
||||
});
|
||||
|
||||
program
|
||||
.command<{ port: number; keycloakVersion: string | undefined }>({
|
||||
.command<{
|
||||
port: number;
|
||||
keycloakVersion: string | undefined;
|
||||
realmJsonFilePath: string | undefined;
|
||||
}>({
|
||||
"name": "start-keycloak",
|
||||
"description": "Spin up a pre configured Docker image of Keycloak to test your theme."
|
||||
})
|
||||
@ -81,7 +85,7 @@ program
|
||||
|
||||
return name;
|
||||
})(),
|
||||
"description": "Keycloak server port.",
|
||||
"description": ["Keycloak server port.", "Example `--port 8085`"].join(" "),
|
||||
"defaultValue": 8080
|
||||
})
|
||||
.option({
|
||||
@ -93,9 +97,21 @@ program
|
||||
|
||||
return name;
|
||||
})(),
|
||||
"description": "Use a specific version of Keycloak.",
|
||||
"description": ["Use a specific version of Keycloak.", "Example `--keycloak-version 21.1.1`"].join(" "),
|
||||
"defaultValue": undefined
|
||||
})
|
||||
.option({
|
||||
"key": "realmJsonFilePath",
|
||||
"name": (() => {
|
||||
const name = "import";
|
||||
|
||||
optionsKeys.push(name);
|
||||
|
||||
return name;
|
||||
})(),
|
||||
"defaultValue": undefined,
|
||||
"description": ["Import your own realm configuration file", "Example `--import path/to/myrealm-realm.json`"].join(" ")
|
||||
})
|
||||
.task({
|
||||
skip,
|
||||
"handler": async cliCommandOptions => {
|
||||
|
@ -65,3 +65,5 @@ export const accountThemePageIds = [
|
||||
|
||||
export type LoginThemePageId = (typeof loginThemePageIds)[number];
|
||||
export type AccountThemePageId = (typeof accountThemePageIds)[number];
|
||||
|
||||
export const containerName = "keycloak-keycloakify";
|
||||
|
1
src/bin/start-keycloak/index.ts
Normal file
1
src/bin/start-keycloak/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./start-keycloak";
|
2247
src/bin/start-keycloak/myrealm-realm-24.json
Normal file
2247
src/bin/start-keycloak/myrealm-realm-24.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
import { readBuildOptions } from "./shared/buildOptions";
|
||||
import type { CliCommandOptions as CliCommandOptions_common } from "./main";
|
||||
import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
|
||||
import { readMetaInfKeycloakThemes } from "./shared/metaInfKeycloakThemes";
|
||||
import { accountV1ThemeName, skipBuildJarsEnvName } from "./shared/constants";
|
||||
import { SemVer } from "./tools/SemVer";
|
||||
import type { KeycloakVersionRange } from "./shared/KeycloakVersionRange";
|
||||
import { getJarFileBasename } from "./shared/getJarFileBasename";
|
||||
import { readBuildOptions } from "../shared/buildOptions";
|
||||
import type { CliCommandOptions as CliCommandOptions_common } from "../main";
|
||||
import { promptKeycloakVersion } from "../shared/promptKeycloakVersion";
|
||||
import { readMetaInfKeycloakThemes } from "../shared/metaInfKeycloakThemes";
|
||||
import { accountV1ThemeName, skipBuildJarsEnvName, containerName } from "../shared/constants";
|
||||
import { SemVer } from "../tools/SemVer";
|
||||
import type { KeycloakVersionRange } from "../shared/KeycloakVersionRange";
|
||||
import { getJarFileBasename } from "../shared/getJarFileBasename";
|
||||
import { assert, type Equals } from "tsafe/assert";
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin, relative as pathRelative, sep as pathSep, posix as pathPosix } from "path";
|
||||
@ -13,12 +13,16 @@ import * as child_process from "child_process";
|
||||
import chalk from "chalk";
|
||||
import chokidar from "chokidar";
|
||||
import { waitForDebounceFactory } from "powerhooks/tools/waitForDebounce";
|
||||
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
|
||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||
import { Deferred } from "evt/tools/Deferred";
|
||||
import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
|
||||
import cliSelect from "cli-select";
|
||||
import { isInside } from "../tools/isInside";
|
||||
|
||||
export type CliCommandOptions = CliCommandOptions_common & {
|
||||
port: number;
|
||||
keycloakVersion: string | undefined;
|
||||
realmJsonFilePath: string | undefined;
|
||||
};
|
||||
|
||||
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||
@ -84,7 +88,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
|
||||
const doesImplementAccountTheme = metaInfKeycloakThemes.themes.some(({ name }) => name === accountV1ThemeName);
|
||||
|
||||
const { keycloakVersion, keycloakMajorNumber } = await (async function getKeycloakMajor(): Promise<{
|
||||
const { keycloakVersion, keycloakMajorNumber: keycloakMajorVersionNumber } = await (async function getKeycloakMajor(): Promise<{
|
||||
keycloakVersion: string;
|
||||
keycloakMajorNumber: number;
|
||||
}> {
|
||||
@ -122,13 +126,13 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
const keycloakVersionRange: KeycloakVersionRange = (() => {
|
||||
if (doesImplementAccountTheme) {
|
||||
const keycloakVersionRange = (() => {
|
||||
if (keycloakMajorNumber <= 21) {
|
||||
if (keycloakMajorVersionNumber <= 21) {
|
||||
return "21-and-below" as const;
|
||||
}
|
||||
|
||||
assert(keycloakMajorNumber !== 22);
|
||||
assert(keycloakMajorVersionNumber !== 22);
|
||||
|
||||
if (keycloakMajorNumber === 23) {
|
||||
if (keycloakMajorVersionNumber === 23) {
|
||||
return "23" as const;
|
||||
}
|
||||
|
||||
@ -140,7 +144,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
return keycloakVersionRange;
|
||||
} else {
|
||||
const keycloakVersionRange = (() => {
|
||||
if (keycloakMajorNumber <= 21) {
|
||||
if (keycloakMajorVersionNumber <= 21) {
|
||||
return "21-and-below" as const;
|
||||
}
|
||||
|
||||
@ -187,13 +191,46 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
})
|
||||
.flat();
|
||||
|
||||
const containerName = "keycloak-keycloakify";
|
||||
|
||||
try {
|
||||
child_process.execSync(`docker rm --force ${containerName}`, { "stdio": "ignore" });
|
||||
} catch {}
|
||||
|
||||
const spawnParams = [
|
||||
const realmJsonFilePath = await (async () => {
|
||||
if (cliCommandOptions.realmJsonFilePath !== undefined) {
|
||||
console.log(chalk.green(`Using realm json file: ${cliCommandOptions.realmJsonFilePath}`));
|
||||
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": cliCommandOptions.realmJsonFilePath,
|
||||
"cwd": process.cwd()
|
||||
});
|
||||
}
|
||||
|
||||
const dirPath = pathJoin(getThisCodebaseRootDirPath(), "src", "bin", "start-keycloak");
|
||||
|
||||
const filePath = pathJoin(dirPath, `myrealm-realm-${keycloakMajorVersionNumber}.json`);
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
console.log(`${chalk.yellow(`Keycloakify do not have a realm configuration for Keycloak ${keycloakMajorVersionNumber} yet.`)}`);
|
||||
|
||||
console.log(chalk.cyan("Select what configuration to use:"));
|
||||
|
||||
const { value } = await cliSelect<string>({
|
||||
"values": [...fs.readdirSync(dirPath).filter(fileBasename => fileBasename.endsWith(".json")), "none"]
|
||||
}).catch(() => {
|
||||
process.exit(-1);
|
||||
});
|
||||
|
||||
if (value === "none") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return pathJoin(dirPath, value);
|
||||
})();
|
||||
|
||||
const spawnArgs = [
|
||||
"docker",
|
||||
[
|
||||
"run",
|
||||
@ -201,19 +238,23 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
...["--name", containerName],
|
||||
...["-e", "KEYCLOAK_ADMIN=admin"],
|
||||
...["-e", "KEYCLOAK_ADMIN_PASSWORD=admin"],
|
||||
...(realmJsonFilePath === undefined ? [] : ["-v", `${realmJsonFilePath}:/opt/keycloak/data/import/myrealm-realm.json`]),
|
||||
...["-v", `${pathJoin(buildOptions.keycloakifyBuildDirPath, jarFileBasename)}:/opt/keycloak/providers/keycloak-theme.jar`],
|
||||
...(keycloakMajorNumber <= 20 ? ["-e", "JAVA_OPTS=-Dkeycloak.profile=preview"] : []),
|
||||
...(keycloakMajorVersionNumber <= 20 ? ["-e", "JAVA_OPTS=-Dkeycloak.profile=preview"] : []),
|
||||
...mountTargets.map(({ localPath, containerPath }) => ["-v", `${localPath}:${containerPath}:rw`]).flat(),
|
||||
`quay.io/keycloak/keycloak:${keycloakVersion}`,
|
||||
"start-dev",
|
||||
...(21 <= keycloakMajorNumber && keycloakMajorNumber < 24 ? ["--features=declarative-user-profile"] : [])
|
||||
...(21 <= keycloakMajorVersionNumber && keycloakMajorVersionNumber < 24 ? ["--features=declarative-user-profile"] : []),
|
||||
...(realmJsonFilePath === undefined ? [] : ["--import-realm"])
|
||||
],
|
||||
{
|
||||
"cwd": buildOptions.keycloakifyBuildDirPath
|
||||
}
|
||||
] as const;
|
||||
|
||||
const child = child_process.spawn(...spawnParams);
|
||||
console.log(JSON.stringify(spawnArgs, null, 2));
|
||||
|
||||
const child = child_process.spawn(...spawnArgs);
|
||||
|
||||
child.stdout.on("data", data => process.stdout.write(data));
|
||||
|
||||
@ -247,7 +288,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
`- user: ${chalk.cyan.bold("admin")}`,
|
||||
`- password: ${chalk.cyan.bold("admin")}`,
|
||||
"",
|
||||
`Watching for changes in ${chalk.bold(`.${pathSep}${pathRelative(process.cwd(), srcDirPath)}`)} ...`
|
||||
`Watching for changes in ${chalk.bold(`.${pathSep}${pathRelative(process.cwd(), srcDirPath)}`)}`
|
||||
].join("\n")
|
||||
);
|
||||
};
|
||||
@ -258,7 +299,20 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
{
|
||||
const { waitForDebounce } = waitForDebounceFactory({ "delay": 400 });
|
||||
|
||||
chokidar.watch([srcDirPath, getThisCodebaseRootDirPath()], { "ignoreInitial": true }).on("all", async () => {
|
||||
chokidar.watch([srcDirPath, getThisCodebaseRootDirPath()], { "ignoreInitial": true }).on("all", async (...[, filePath]) => {
|
||||
if (
|
||||
isInside({
|
||||
"dirPath": pathJoin(getThisCodebaseRootDirPath(), "src", "bin"),
|
||||
filePath
|
||||
}) ||
|
||||
isInside({
|
||||
"dirPath": pathJoin(getThisCodebaseRootDirPath(), "bin"),
|
||||
filePath
|
||||
})
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
await waitForDebounce();
|
||||
|
||||
console.log(chalk.cyan("Detected changes in the theme. Rebuilding ..."));
|
||||
@ -271,7 +325,13 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
||||
"env": process.env
|
||||
});
|
||||
|
||||
child.stdout.on("data", data => process.stdout.write(data));
|
||||
child.stdout.on("data", data => {
|
||||
if (data.toString("utf8").includes("gzip:")) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.stdout.write(data);
|
||||
});
|
||||
|
||||
child.stderr.on("data", data => process.stderr.write(data));
|
||||
|
Reference in New Issue
Block a user