#354: Feature theme variant
This commit is contained in:
parent
69c3befb2d
commit
ed48669ae1
@ -8,6 +8,7 @@ export declare namespace KcContext {
|
|||||||
export type Common = {
|
export type Common = {
|
||||||
keycloakifyVersion: string;
|
keycloakifyVersion: string;
|
||||||
themeType: "account";
|
themeType: "account";
|
||||||
|
themeName: string;
|
||||||
locale?: {
|
locale?: {
|
||||||
supported: {
|
supported: {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -9,6 +9,7 @@ const PUBLIC_URL = process.env["PUBLIC_URL"] ?? "/";
|
|||||||
export const kcContextCommonMock: KcContext.Common = {
|
export const kcContextCommonMock: KcContext.Common = {
|
||||||
"keycloakifyVersion": "0.0.0",
|
"keycloakifyVersion": "0.0.0",
|
||||||
"themeType": "account",
|
"themeType": "account",
|
||||||
|
"themeName": "my-theme-name",
|
||||||
"url": {
|
"url": {
|
||||||
"resourcesPath": pathJoin(PUBLIC_URL, resourcesDirPathRelativeToPublicDir),
|
"resourcesPath": pathJoin(PUBLIC_URL, resourcesDirPathRelativeToPublicDir),
|
||||||
"resourcesCommonPath": pathJoin(PUBLIC_URL, resourcesCommonDirPathRelativeToPublicDir),
|
"resourcesCommonPath": pathJoin(PUBLIC_URL, resourcesCommonDirPathRelativeToPublicDir),
|
||||||
|
@ -16,6 +16,7 @@ export namespace BuildOptions {
|
|||||||
isSilent: boolean;
|
isSilent: boolean;
|
||||||
themeVersion: string;
|
themeVersion: string;
|
||||||
themeName: string;
|
themeName: string;
|
||||||
|
extraThemeNames: string[];
|
||||||
extraLoginPages: string[] | undefined;
|
extraLoginPages: string[] | undefined;
|
||||||
extraAccountPages: string[] | undefined;
|
extraAccountPages: string[] | undefined;
|
||||||
extraThemeProperties?: string[];
|
extraThemeProperties?: string[];
|
||||||
@ -108,8 +109,17 @@ export function readBuildOptions(params: { projectDirPath: string; processArgv:
|
|||||||
const common: BuildOptions.Common = (() => {
|
const common: BuildOptions.Common = (() => {
|
||||||
const { name, keycloakify = {}, version, homepage } = parsedPackageJson;
|
const { name, keycloakify = {}, version, homepage } = parsedPackageJson;
|
||||||
|
|
||||||
const { extraPages, extraLoginPages, extraAccountPages, extraThemeProperties, groupId, artifactId, bundler, keycloakVersionDefaultAssets } =
|
const {
|
||||||
keycloakify ?? {};
|
extraPages,
|
||||||
|
extraLoginPages,
|
||||||
|
extraAccountPages,
|
||||||
|
extraThemeProperties,
|
||||||
|
groupId,
|
||||||
|
artifactId,
|
||||||
|
bundler,
|
||||||
|
keycloakVersionDefaultAssets,
|
||||||
|
extraThemeNames = []
|
||||||
|
} = keycloakify ?? {};
|
||||||
|
|
||||||
const themeName =
|
const themeName =
|
||||||
keycloakify.themeName ??
|
keycloakify.themeName ??
|
||||||
@ -120,6 +130,7 @@ export function readBuildOptions(params: { projectDirPath: string; processArgv:
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
themeName,
|
themeName,
|
||||||
|
extraThemeNames,
|
||||||
"bundler": (() => {
|
"bundler": (() => {
|
||||||
const { KEYCLOAKIFY_BUNDLER } = process.env;
|
const { KEYCLOAKIFY_BUNDLER } = process.env;
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
out["keycloakifyVersion"] = "KEYCLOAKIFY_VERSION_xEdKd3xEdr";
|
out["keycloakifyVersion"] = "KEYCLOAKIFY_VERSION_xEdKd3xEdr";
|
||||||
out["themeVersion"] = "KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx";
|
out["themeVersion"] = "KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx";
|
||||||
out["themeType"] = "KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr";
|
out["themeType"] = "KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr";
|
||||||
|
out["themeName"] = "KEYCLOAKIFY_THEME_NAME_cXxKd3xEer";
|
||||||
out["pageId"] = "${pageId}";
|
out["pageId"] = "${pageId}";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -17,6 +17,7 @@ export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.Ex
|
|||||||
|
|
||||||
export namespace BuildOptionsLike {
|
export namespace BuildOptionsLike {
|
||||||
export type Common = {
|
export type Common = {
|
||||||
|
themeName: string;
|
||||||
customUserAttributes: string[];
|
customUserAttributes: string[];
|
||||||
themeVersion: string;
|
themeVersion: string;
|
||||||
};
|
};
|
||||||
@ -134,7 +135,8 @@ export function generateFtlFilesCodeFactory(params: {
|
|||||||
)
|
)
|
||||||
.replace("KEYCLOAKIFY_VERSION_xEdKd3xEdr", keycloakifyVersion)
|
.replace("KEYCLOAKIFY_VERSION_xEdKd3xEdr", keycloakifyVersion)
|
||||||
.replace("KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx", buildOptions.themeVersion)
|
.replace("KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx", buildOptions.themeVersion)
|
||||||
.replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType),
|
.replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType)
|
||||||
|
.replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", buildOptions.themeName),
|
||||||
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
|
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
|
||||||
"<#if scripts??>",
|
"<#if scripts??>",
|
||||||
" <#list scripts as script>",
|
" <#list scripts as script>",
|
||||||
|
@ -7,6 +7,7 @@ import type { BuildOptions } from "./BuildOptions";
|
|||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
themeName: string;
|
themeName: string;
|
||||||
|
extraThemeNames: string[];
|
||||||
groupId: string;
|
groupId: string;
|
||||||
artifactId?: string;
|
artifactId?: string;
|
||||||
themeVersion: string;
|
themeVersion: string;
|
||||||
@ -26,7 +27,7 @@ export function generateJavaStackFiles(params: {
|
|||||||
jarFilePath: string;
|
jarFilePath: string;
|
||||||
} {
|
} {
|
||||||
const {
|
const {
|
||||||
buildOptions: { groupId, themeName, themeVersion, artifactId },
|
buildOptions: { groupId, themeName, extraThemeNames, themeVersion, artifactId },
|
||||||
keycloakThemeBuildingDirPath,
|
keycloakThemeBuildingDirPath,
|
||||||
doBundlesEmailTemplate
|
doBundlesEmailTemplate
|
||||||
} = params;
|
} = params;
|
||||||
@ -67,12 +68,12 @@ export function generateJavaStackFiles(params: {
|
|||||||
Buffer.from(
|
Buffer.from(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
{
|
{
|
||||||
"themes": [
|
"themes": [themeName, ...extraThemeNames].map(themeName => [
|
||||||
{
|
{
|
||||||
"name": themeName,
|
"name": themeName,
|
||||||
"types": [...themeTypes, ...(doBundlesEmailTemplate ? ["email"] : [])]
|
"types": [...themeTypes, ...(doBundlesEmailTemplate ? ["email"] : [])]
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
2
|
2
|
||||||
|
@ -6,6 +6,7 @@ import type { BuildOptions } from "./BuildOptions";
|
|||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
themeName: string;
|
themeName: string;
|
||||||
|
extraThemeNames: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -27,11 +28,9 @@ export function generateStartKeycloakTestingContainer(params: {
|
|||||||
const {
|
const {
|
||||||
keycloakThemeBuildingDirPath,
|
keycloakThemeBuildingDirPath,
|
||||||
keycloakVersion,
|
keycloakVersion,
|
||||||
buildOptions: { themeName }
|
buildOptions: { themeName, extraThemeNames }
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
const keycloakThemePath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", themeName).replace(/\\/g, "/");
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
pathJoin(keycloakThemeBuildingDirPath, generateStartKeycloakTestingContainer.basename),
|
pathJoin(keycloakThemeBuildingDirPath, generateStartKeycloakTestingContainer.basename),
|
||||||
|
|
||||||
@ -49,7 +48,13 @@ export function generateStartKeycloakTestingContainer(params: {
|
|||||||
" -e KEYCLOAK_ADMIN=admin \\",
|
" -e KEYCLOAK_ADMIN=admin \\",
|
||||||
" -e KEYCLOAK_ADMIN_PASSWORD=admin \\",
|
" -e KEYCLOAK_ADMIN_PASSWORD=admin \\",
|
||||||
" -e JAVA_OPTS=-Dkeycloak.profile=preview \\",
|
" -e JAVA_OPTS=-Dkeycloak.profile=preview \\",
|
||||||
` -v "${keycloakThemePath}":"/opt/keycloak/themes/${themeName}":rw \\`,
|
...[themeName, ...extraThemeNames].map(
|
||||||
|
themeName =>
|
||||||
|
` -v "${pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", themeName).replace(
|
||||||
|
/\\/g,
|
||||||
|
"/"
|
||||||
|
)}":"/opt/keycloak/themes/${themeName}":rw \\`
|
||||||
|
),
|
||||||
` -it quay.io/keycloak/keycloak:${keycloakVersion} \\`,
|
` -it quay.io/keycloak/keycloak:${keycloakVersion} \\`,
|
||||||
` start-dev`,
|
` start-dev`,
|
||||||
""
|
""
|
||||||
|
@ -23,27 +23,38 @@ export async function main() {
|
|||||||
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
||||||
logger.log("🔏 Building the keycloak theme...⌚");
|
logger.log("🔏 Building the keycloak theme...⌚");
|
||||||
|
|
||||||
const { doBundlesEmailTemplate } = await generateTheme({
|
let doBundlesEmailTemplate: boolean | undefined;
|
||||||
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
|
||||||
"emailThemeSrcDirPath": (() => {
|
|
||||||
const { emailThemeSrcDirPath } = getEmailThemeSrcDirPath({ projectDirPath });
|
|
||||||
|
|
||||||
if (emailThemeSrcDirPath === undefined || !fs.existsSync(emailThemeSrcDirPath)) {
|
for (const themeName of [buildOptions.themeName, ...buildOptions.extraThemeNames]) {
|
||||||
return;
|
const { doBundlesEmailTemplate: doBundlesEmailTemplate_ } = await generateTheme({
|
||||||
}
|
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
||||||
|
"emailThemeSrcDirPath": (() => {
|
||||||
|
const { emailThemeSrcDirPath } = getEmailThemeSrcDirPath({ projectDirPath });
|
||||||
|
|
||||||
return emailThemeSrcDirPath;
|
if (emailThemeSrcDirPath === undefined || !fs.existsSync(emailThemeSrcDirPath)) {
|
||||||
})(),
|
return;
|
||||||
"reactAppBuildDirPath": buildOptions.reactAppBuildDirPath,
|
}
|
||||||
buildOptions,
|
|
||||||
"keycloakifyVersion": (() => {
|
|
||||||
const version = JSON.parse(fs.readFileSync(pathJoin(getProjectRoot(), "package.json")).toString("utf8"))["version"];
|
|
||||||
|
|
||||||
assert(typeof version === "string");
|
return emailThemeSrcDirPath;
|
||||||
|
})(),
|
||||||
|
"reactAppBuildDirPath": buildOptions.reactAppBuildDirPath,
|
||||||
|
"buildOptions": {
|
||||||
|
...buildOptions,
|
||||||
|
"themeName": themeName
|
||||||
|
},
|
||||||
|
"keycloakifyVersion": (() => {
|
||||||
|
const version = JSON.parse(fs.readFileSync(pathJoin(getProjectRoot(), "package.json")).toString("utf8"))["version"];
|
||||||
|
|
||||||
return version;
|
assert(typeof version === "string");
|
||||||
})()
|
|
||||||
});
|
return version;
|
||||||
|
})()
|
||||||
|
});
|
||||||
|
|
||||||
|
doBundlesEmailTemplate ??= doBundlesEmailTemplate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(doBundlesEmailTemplate !== undefined);
|
||||||
|
|
||||||
const { jarFilePath } = generateJavaStackFiles({
|
const { jarFilePath } = generateJavaStackFiles({
|
||||||
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
||||||
|
@ -25,6 +25,7 @@ export type ParsedPackageJson = {
|
|||||||
keycloakifyBuildDirPath?: string;
|
keycloakifyBuildDirPath?: string;
|
||||||
customUserAttributes?: string[];
|
customUserAttributes?: string[];
|
||||||
themeName?: string;
|
themeName?: string;
|
||||||
|
extraThemeNames?: string[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,7 +47,8 @@ export const zParsedPackageJson = z.object({
|
|||||||
"reactAppBuildDirPath": z.string().optional(),
|
"reactAppBuildDirPath": z.string().optional(),
|
||||||
"keycloakifyBuildDirPath": z.string().optional(),
|
"keycloakifyBuildDirPath": z.string().optional(),
|
||||||
"customUserAttributes": z.array(z.string()).optional(),
|
"customUserAttributes": z.array(z.string()).optional(),
|
||||||
"themeName": z.string().optional()
|
"themeName": z.string().optional(),
|
||||||
|
"extraThemeNames": z.array(z.string()).optional()
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,7 @@ export declare namespace KcContext {
|
|||||||
export type Common = {
|
export type Common = {
|
||||||
keycloakifyVersion: string;
|
keycloakifyVersion: string;
|
||||||
themeType: "login";
|
themeType: "login";
|
||||||
|
themeName: string;
|
||||||
url: {
|
url: {
|
||||||
loginAction: string;
|
loginAction: string;
|
||||||
resourcesPath: string;
|
resourcesPath: string;
|
||||||
|
@ -105,6 +105,7 @@ const attributesByName = Object.fromEntries(attributes.map(attribute => [attribu
|
|||||||
export const kcContextCommonMock: KcContext.Common = {
|
export const kcContextCommonMock: KcContext.Common = {
|
||||||
"keycloakifyVersion": "0.0.0",
|
"keycloakifyVersion": "0.0.0",
|
||||||
"themeType": "login",
|
"themeType": "login",
|
||||||
|
"themeName": "my-theme-name",
|
||||||
"url": {
|
"url": {
|
||||||
"loginAction": "#",
|
"loginAction": "#",
|
||||||
"resourcesPath": pathJoin(PUBLIC_URL, resourcesDirPathRelativeToPublicDir),
|
"resourcesPath": pathJoin(PUBLIC_URL, resourcesDirPathRelativeToPublicDir),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user