Refactor checkpoint

This commit is contained in:
Joseph Garrone
2024-09-08 00:06:47 +02:00
parent 8340608045
commit 93c1c56279
28 changed files with 402 additions and 897 deletions

View File

@ -4,6 +4,7 @@ import { join } from "path";
import { assert } from "tsafe/assert";
import { transformCodebase } from "../src/bin/tools/transformCodebase";
import chalk from "chalk";
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../src/bin/shared/constants";
console.log(chalk.cyan("Building Keycloakify..."));
@ -136,9 +137,17 @@ fs.rmSync(join("dist", "ncc_out"), { recursive: true });
assert(hasBeenPatched);
}
fs.rmSync(join("dist", "src"), { recursive: true, force: true });
for (const dirBasename of [
"src",
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES,
WELL_KNOWN_DIRECTORY_BASE_NAME.ACCOUNT_V1
]) {
const destDirPath = join("dist", dirBasename);
fs.cpSync("src", join("dist", "src"), { recursive: true });
fs.rmSync(destDirPath, { recursive: true, force: true });
fs.cpSync(dirBasename, destDirPath, { recursive: true });
}
transformCodebase({
srcDirPath: join("stories"),

View File

@ -0,0 +1,4 @@
export const KEYCLOAK_VERSION = {
FOR_LOGIN_THEME: "25.0.4",
FOR_ACCOUNT_MULTI_PAGE: "21.1.2"
};

View File

@ -0,0 +1,77 @@
import * as fs from "fs";
import { join as pathJoin } from "path";
import { KEYCLOAK_VERSION } from "./constants";
import { transformCodebase } from "../../src/bin/tools/transformCodebase";
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../src/bin/shared/constants";
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
import { accountMultiPageSupportedLanguages } from "./generateI18nMessages";
export async function createAccountV1Dir() {
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
keycloakVersion: KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE
});
// TODO: Exclude unused resources.
const destDirPath = pathJoin(
getThisCodebaseRootDirPath(),
WELL_KNOWN_DIRECTORY_BASE_NAME.ACCOUNT_V1
);
transformCodebase({
srcDirPath: pathJoin(extractedDirPath, "base", "account"),
destDirPath
});
transformCodebase({
srcDirPath: pathJoin(extractedDirPath, "keycloak", "account", "resources"),
destDirPath: pathJoin(destDirPath, "resources")
});
transformCodebase({
srcDirPath: pathJoin(extractedDirPath, "keycloak", "common", "resources"),
destDirPath: pathJoin(
destDirPath,
"resources",
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON
)
});
fs.writeFileSync(
pathJoin(destDirPath, "theme.properties"),
Buffer.from(
[
"accountResourceProvider=account-v1",
"",
`locales=${accountMultiPageSupportedLanguages.join(",")}`,
"",
"styles=" +
[
"css/account.css",
"img/icon-sidebar-active.png",
"img/logo.png",
...[
"patternfly.min.css",
"patternfly-additions.min.css",
"patternfly-additions.min.css"
].map(
fileBasename =>
`${WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON}/node_modules/patternfly/dist/css/${fileBasename}`
)
].join(" "),
"",
"##### css classes for form buttons",
"# main class used for all buttons",
"kcButtonClass=btn",
"# classes defining priority of the button - primary or default (there is typically only one priority button for the form)",
"kcButtonPrimaryClass=btn-primary",
"kcButtonDefaultClass=btn-default",
"# classes defining size of the button",
"kcButtonLargeClass=btn-lg",
""
].join("\n"),
"utf8"
)
);
}

View File

@ -0,0 +1,70 @@
import { join as pathJoin } from "path";
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
import { KEYCLOAK_VERSION } from "./constants";
import { transformCodebase } from "../../src/bin/tools/transformCodebase";
import { existsAsync } from "../../src/bin/tools/fs.existsAsync";
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../src/bin/shared/constants";
import { assert, type Equals } from "tsafe/assert";
export async function createResourcesDir() {
await Promise.all(
(["login", "account"] as const).map(async themeType => {
const keycloakVersion = (() => {
switch (themeType) {
case "login":
return KEYCLOAK_VERSION.FOR_LOGIN_THEME;
case "account":
return KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE;
}
assert<Equals<typeof themeType, never>>();
})();
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
keycloakVersion
});
const destDirPath = pathJoin(
getThisCodebaseRootDirPath(),
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES,
themeType
);
base_resources: {
const srcDirPath = pathJoin(
extractedDirPath,
"base",
themeType,
"resources"
);
if (!(await existsAsync(srcDirPath))) {
break base_resources;
}
transformCodebase({
srcDirPath,
destDirPath
});
}
transformCodebase({
srcDirPath: pathJoin(
extractedDirPath,
"keycloak",
themeType,
"resources"
),
destDirPath
});
transformCodebase({
srcDirPath: pathJoin(extractedDirPath, "keycloak", "common", "resources"),
destDirPath: pathJoin(
destDirPath,
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON
)
});
})
);
}

View File

@ -0,0 +1,34 @@
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";
export async function downloadKeycloakDefaultTheme(params: { keycloakVersion: string }) {
const { keycloakVersion } = params;
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()
}),
uniqueIdOfOnArchiveFile: "downloadKeycloakDefaultTheme",
onArchiveFile: async ({ fileRelativePath, writeFile }) => {
const fileRelativePath_target = pathRelative("theme", fileRelativePath);
if (fileRelativePath_target.startsWith("..")) {
return;
}
await writeFile({ fileRelativePath: fileRelativePath_target });
}
});
return { extractedDirPath };
}

View File

@ -8,15 +8,12 @@ import {
} from "path";
import { assert } from "tsafe/assert";
import { same } from "evt/tools/inDepth";
import { crawl } from "../src/bin/tools/crawl";
import { downloadKeycloakDefaultTheme } from "../src/bin/shared/downloadKeycloakDefaultTheme";
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
import { deepAssign } from "../src/tools/deepAssign";
import { getProxyFetchOptions } from "../src/bin/tools/fetchProxyOptions";
import {
THEME_TYPES,
LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1
} from "../src/bin/shared/constants";
import { crawl } from "../../src/bin/tools/crawl";
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
import { deepAssign } from "../../src/tools/deepAssign";
import { THEME_TYPES } from "../../src/bin/shared/constants";
import { KEYCLOAK_VERSION } from "./constants";
// NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files,
// update the version array for generating for newer version.
@ -24,7 +21,7 @@ import {
//@ts-ignore
const propertiesParser = require("properties-parser");
async function main() {
export async function generateI18nMessages() {
const thisCodebaseRootDirPath = getThisCodebaseRootDirPath();
type Dictionary = { [idiomId: string]: string };
@ -32,30 +29,19 @@ async function main() {
const record: { [themeType: string]: { [language: string]: Dictionary } } = {};
for (const themeType of THEME_TYPES) {
const { defaultThemeDirPath } = await downloadKeycloakDefaultTheme({
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
keycloakVersion: (() => {
switch (themeType) {
case "login":
return "25.0.4";
return KEYCLOAK_VERSION.FOR_LOGIN_THEME;
case "account":
return LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1;
return KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE;
}
})(),
buildContext: {
cacheDirPath: pathJoin(
thisCodebaseRootDirPath,
"node_modules",
".cache",
"keycloakify"
),
fetchOptions: getProxyFetchOptions({
npmConfigGetCwd: thisCodebaseRootDirPath
})
}
})()
});
{
const baseThemeDirPath = pathJoin(defaultThemeDirPath, "base");
const baseThemeDirPath = pathJoin(extractedDirPath, "base");
const re = new RegExp(
`^([^\\${pathSep}]+)\\${pathSep}messages\\${pathSep}messages_([^.]+).properties$`
);
@ -597,30 +583,34 @@ const keycloakifyExtraMessages_login: Record<
/* spell-checker: enable */
};
export const accountMultiPageSupportedLanguages = [
"en",
"ar",
"ca",
"cs",
"da",
"de",
"es",
"fi",
"fr",
"hu",
"it",
"ja",
"lt",
"lv",
"nl",
"no",
"pl",
"pt-BR",
"ru",
"sk",
"sv",
"tr",
"zh-CN"
] as const;
const keycloakifyExtraMessages_account: Record<
| "en"
| "ar"
| "ca"
| "cs"
| "da"
| "de"
| "es"
| "fi"
| "fr"
| "hu"
| "it"
| "ja"
| "lt"
| "lv"
| "nl"
| "no"
| "pl"
| "pt-BR"
| "ru"
| "sk"
| "sv"
| "tr"
| "zh-CN",
(typeof accountMultiPageSupportedLanguages)[number],
Record<"newPasswordSameAsOld" | "passwordConfirmNotMatch", string>
> = {
en: {
@ -719,7 +709,3 @@ const keycloakifyExtraMessages_account: Record<
}
/* spell-checker: enable */
};
if (require.main === module) {
main();
}

13
scripts/prepare/main.ts Normal file
View File

@ -0,0 +1,13 @@
import { generateI18nMessages } from "./generateI18nMessages";
import { createAccountV1Dir } from "./createAccountV1Dir";
import { createResourcesDir } from "./createResourcesDir";
(async () => {
console.log("Pulling i18n messages...");
await generateI18nMessages();
console.log("Creating account-v1 dir...");
await createAccountV1Dir();
console.log("Creating resources dir...");
await createResourcesDir();
console.log("Done!");
})();