2024-09-08 00:06:47 +02:00
|
|
|
import { relative as pathRelative } from "path";
|
|
|
|
import { downloadAndExtractArchive } from "../../src/bin/tools/downloadAndExtractArchive";
|
|
|
|
import { getProxyFetchOptions } from "../../src/bin/tools/fetchProxyOptions";
|
|
|
|
import { join as pathJoin } from "path";
|
|
|
|
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
|
2024-09-08 12:40:28 +02:00
|
|
|
import { assert, type Equals } from "tsafe/assert";
|
2024-09-08 00:06:47 +02:00
|
|
|
|
2024-09-08 12:40:28 +02:00
|
|
|
const KEYCLOAK_VERSION = {
|
|
|
|
FOR_LOGIN_THEME: "25.0.4",
|
2024-09-08 14:41:45 +02:00
|
|
|
FOR_ACCOUNT_MULTI_PAGE: "21.1.2",
|
|
|
|
LAST_24: "24.0.4"
|
2024-09-08 12:40:28 +02:00
|
|
|
} as const;
|
|
|
|
|
|
|
|
export async function downloadKeycloakDefaultTheme(params: {
|
|
|
|
keycloakVersionId: keyof typeof KEYCLOAK_VERSION;
|
|
|
|
}) {
|
|
|
|
const { keycloakVersionId } = params;
|
|
|
|
|
|
|
|
const keycloakVersion = KEYCLOAK_VERSION[keycloakVersionId];
|
|
|
|
|
|
|
|
let kcNodeModulesKeepFilePaths: Set<string> | undefined = undefined;
|
|
|
|
let kcNodeModulesKeepFilePaths_lastAccountV1: Set<string> | undefined = undefined;
|
2024-09-08 00:06:47 +02:00
|
|
|
|
|
|
|
const { extractedDirPath } = await downloadAndExtractArchive({
|
|
|
|
url: `https://repo1.maven.org/maven2/org/keycloak/keycloak-themes/${keycloakVersion}/keycloak-themes-${keycloakVersion}.jar`,
|
|
|
|
cacheDirPath: pathJoin(
|
|
|
|
getThisCodebaseRootDirPath(),
|
|
|
|
"node_modules",
|
|
|
|
".cache",
|
|
|
|
"scripts"
|
|
|
|
),
|
|
|
|
fetchOptions: getProxyFetchOptions({
|
|
|
|
npmConfigGetCwd: getThisCodebaseRootDirPath()
|
|
|
|
}),
|
2024-09-08 12:00:07 +02:00
|
|
|
uniqueIdOfOnArchiveFile: "extractOnlyRequiredFiles",
|
2024-09-08 12:40:28 +02:00
|
|
|
onArchiveFile: async params => {
|
|
|
|
const fileRelativePath = pathRelative("theme", params.fileRelativePath);
|
|
|
|
|
|
|
|
if (fileRelativePath.startsWith("..")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { readFile, writeFile } = params;
|
2024-09-08 00:06:47 +02:00
|
|
|
|
2024-09-08 12:40:28 +02:00
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith("base") &&
|
|
|
|
!fileRelativePath.startsWith("keycloak")
|
|
|
|
) {
|
2024-09-08 00:06:47 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-09-08 12:40:28 +02:00
|
|
|
switch (keycloakVersion) {
|
|
|
|
case KEYCLOAK_VERSION.FOR_LOGIN_THEME:
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(pathJoin("base", "login")) &&
|
|
|
|
!fileRelativePath.startsWith(pathJoin("keycloak", "login")) &&
|
|
|
|
!fileRelativePath.startsWith(pathJoin("keycloak", "common"))
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fileRelativePath.endsWith(".ftl")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE:
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(pathJoin("base", "account")) &&
|
|
|
|
!fileRelativePath.startsWith(pathJoin("keycloak", "account")) &&
|
|
|
|
!fileRelativePath.startsWith(pathJoin("keycloak", "common"))
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-09-08 14:41:45 +02:00
|
|
|
break;
|
|
|
|
case KEYCLOAK_VERSION.LAST_24:
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(
|
|
|
|
pathJoin("base", "login", "resources", "js")
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2024-09-08 12:40:28 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert<Equals<typeof keycloakVersion, never>>(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
last_account_v1_transformations: {
|
|
|
|
if (keycloakVersion !== KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE) {
|
|
|
|
break last_account_v1_transformations;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_web_modules: {
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(
|
|
|
|
pathJoin("keycloak", "common", "resources", "web_modules")
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
break skip_web_modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_lib: {
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(
|
|
|
|
pathJoin("keycloak", "common", "resources", "lib")
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
break skip_lib;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_node_modules: {
|
|
|
|
const nodeModulesRelativeDirPath = pathJoin(
|
|
|
|
"keycloak",
|
|
|
|
"common",
|
|
|
|
"resources",
|
|
|
|
"node_modules"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
|
|
|
|
break skip_node_modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (kcNodeModulesKeepFilePaths_lastAccountV1 === undefined) {
|
|
|
|
kcNodeModulesKeepFilePaths_lastAccountV1 = new Set([
|
|
|
|
pathJoin("patternfly", "dist", "css", "patternfly.min.css"),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"css",
|
|
|
|
"patternfly-additions.min.css"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Regular-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Bold-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Light-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Semibold-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"PatternFlyIcons-webfont.ttf"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"PatternFlyIcons-webfont.woff"
|
|
|
|
)
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
const fileRelativeToNodeModulesPath = fileRelativePath.substring(
|
|
|
|
nodeModulesRelativeDirPath.length + 1
|
|
|
|
);
|
|
|
|
|
|
|
|
if (
|
|
|
|
kcNodeModulesKeepFilePaths_lastAccountV1.has(
|
|
|
|
fileRelativeToNodeModulesPath
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
break skip_node_modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
patch_account_css: {
|
|
|
|
if (
|
|
|
|
fileRelativePath !==
|
|
|
|
pathJoin("keycloak", "account", "resources", "css", "account.css")
|
|
|
|
) {
|
|
|
|
break patch_account_css;
|
|
|
|
}
|
|
|
|
|
|
|
|
await writeFile({
|
|
|
|
fileRelativePath,
|
|
|
|
modifiedData: Buffer.from(
|
|
|
|
(await readFile())
|
|
|
|
.toString("utf8")
|
|
|
|
.replace("top: -34px;", "top: -34px !important;"),
|
|
|
|
"utf8"
|
|
|
|
)
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_unused_resources: {
|
|
|
|
if (keycloakVersion !== KEYCLOAK_VERSION.FOR_LOGIN_THEME) {
|
|
|
|
break skip_unused_resources;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_node_modules: {
|
|
|
|
const nodeModulesRelativeDirPath = pathJoin(
|
|
|
|
"keycloak",
|
|
|
|
"common",
|
|
|
|
"resources",
|
|
|
|
"node_modules"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
|
|
|
|
break skip_node_modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (kcNodeModulesKeepFilePaths === undefined) {
|
|
|
|
kcNodeModulesKeepFilePaths = new Set([
|
|
|
|
pathJoin("@patternfly", "patternfly", "patternfly.min.css"),
|
|
|
|
pathJoin("patternfly", "dist", "css", "patternfly.min.css"),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"css",
|
|
|
|
"patternfly-additions.min.css"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Regular-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Light-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Bold-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Bold-webfont.woff"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Bold-webfont.ttf"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"fontawesome-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"PatternFlyIcons-webfont.ttf"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"PatternFlyIcons-webfont.woff"
|
|
|
|
),
|
|
|
|
pathJoin(
|
|
|
|
"patternfly",
|
|
|
|
"dist",
|
|
|
|
"fonts",
|
|
|
|
"OpenSans-Semibold-webfont.woff2"
|
|
|
|
),
|
|
|
|
pathJoin("patternfly", "dist", "img", "bg-login.jpg"),
|
|
|
|
pathJoin("jquery", "dist", "jquery.min.js")
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
const fileRelativeToNodeModulesPath = fileRelativePath.substring(
|
|
|
|
nodeModulesRelativeDirPath.length + 1
|
|
|
|
);
|
|
|
|
|
|
|
|
if (kcNodeModulesKeepFilePaths.has(fileRelativeToNodeModulesPath)) {
|
|
|
|
break skip_node_modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_vendor: {
|
|
|
|
if (
|
|
|
|
!fileRelativePath.startsWith(
|
|
|
|
pathJoin("keycloak", "common", "resources", "vendor")
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
break skip_vendor;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
skip_rollup_config: {
|
|
|
|
if (
|
|
|
|
fileRelativePath !==
|
|
|
|
pathJoin("keycloak", "common", "resources", "rollup.config.js")
|
|
|
|
) {
|
|
|
|
break skip_rollup_config;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await writeFile({ fileRelativePath });
|
2024-09-08 00:06:47 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return { extractedDirPath };
|
|
|
|
}
|