keycloak_theme/src/bin/build-keycloak-theme/generateKeycloakThemeResources.ts

198 lines
5.8 KiB
TypeScript
Raw Normal View History

2021-02-28 18:40:57 +01:00
import { transformCodebase } from "../tools/transformCodebase";
2021-02-21 18:55:06 +01:00
import * as fs from "fs";
2021-03-10 22:45:09 +01:00
import { join as pathJoin } from "path";
2021-02-21 18:55:06 +01:00
import {
replaceImportsInCssCode,
replaceImportsFromStaticInJsCode,
2021-02-21 18:55:06 +01:00
} from "./replaceImportFromStatic";
2021-03-26 15:29:17 +01:00
import { generateFtlFilesCodeFactory, pageIds } from "./generateFtl";
import { downloadBuiltinKeycloakTheme } from "../download-builtin-keycloak-theme";
2021-03-02 01:05:15 +01:00
import * as child_process from "child_process";
import {
resourcesCommonPath,
resourcesPath,
subDirOfPublicDirBasename,
} from "../../lib/getKcContext/kcContextMocks/urlResourcesPath";
2021-03-22 20:54:28 +01:00
import { isInside } from "../tools/isInside";
export function generateKeycloakThemeResources(params: {
themeName: string;
reactAppBuildDirPath: string;
keycloakThemeBuildingDirPath: string;
urlPathname: string;
//If urlOrigin is not undefined then it means --externals-assets
urlOrigin: undefined | string;
extraPagesId: string[];
extraThemeProperties: string[];
keycloakVersion: "11.0.3" | "15.0.2";
}) {
const {
themeName,
reactAppBuildDirPath,
keycloakThemeBuildingDirPath,
urlPathname,
urlOrigin,
extraPagesId,
extraThemeProperties,
keycloakVersion,
} = params;
2021-02-21 18:55:06 +01:00
const themeDirPath = pathJoin(
keycloakThemeBuildingDirPath,
"src",
"main",
"resources",
"theme",
themeName,
"login",
);
2021-02-21 18:55:06 +01:00
let allCssGlobalsToDefine: Record<string, string> = {};
transformCodebase({
2021-04-11 18:18:52 +02:00
"destDirPath":
urlOrigin === undefined
? pathJoin(themeDirPath, "resources", "build")
: reactAppBuildDirPath,
2021-02-21 18:55:06 +01:00
"srcDirPath": reactAppBuildDirPath,
2021-03-03 02:31:02 +01:00
"transformSourceCode": ({ filePath, sourceCode }) => {
//NOTE: Prevent cycles, excludes the folder we generated for debug in public/
if (
2021-04-11 18:18:52 +02:00
urlOrigin === undefined &&
isInside({
"dirPath": pathJoin(
reactAppBuildDirPath,
subDirOfPublicDirBasename,
),
filePath,
})
) {
return undefined;
}
2021-04-11 18:18:52 +02:00
if (urlOrigin === undefined && /\.css?$/i.test(filePath)) {
const { cssGlobalsToDefine, fixedCssCode } =
replaceImportsInCssCode({
"cssCode": sourceCode.toString("utf8"),
});
2021-02-21 18:55:06 +01:00
allCssGlobalsToDefine = {
...allCssGlobalsToDefine,
...cssGlobalsToDefine,
};
2021-02-21 18:55:06 +01:00
return {
"modifiedSourceCode": Buffer.from(fixedCssCode, "utf8"),
};
2021-03-28 13:37:02 +02:00
}
2021-02-21 18:55:06 +01:00
2021-03-28 13:37:02 +02:00
if (/\.js?$/i.test(filePath)) {
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
"jsCode": sourceCode.toString("utf8"),
urlOrigin,
2021-03-28 13:37:02 +02:00
});
return {
"modifiedSourceCode": Buffer.from(fixedJsCode, "utf8"),
};
2021-02-21 18:55:06 +01:00
}
return urlOrigin === undefined
? { "modifiedSourceCode": sourceCode }
: undefined;
},
2021-02-21 18:55:06 +01:00
});
const { generateFtlFilesCode } = generateFtlFilesCodeFactory({
"cssGlobalsToDefine": allCssGlobalsToDefine,
"indexHtmlCode": fs
.readFileSync(pathJoin(reactAppBuildDirPath, "index.html"))
.toString("utf8"),
2021-04-11 18:18:52 +02:00
urlPathname,
urlOrigin,
2021-02-21 18:55:06 +01:00
});
[...pageIds, ...extraPagesId].forEach(pageId => {
2021-03-06 22:41:36 +01:00
const { ftlCode } = generateFtlFilesCode({ pageId });
2021-02-21 18:55:06 +01:00
2021-04-11 18:18:52 +02:00
fs.mkdirSync(themeDirPath, { "recursive": true });
2021-02-21 18:55:06 +01:00
fs.writeFileSync(
2021-03-06 22:41:36 +01:00
pathJoin(themeDirPath, pageId),
Buffer.from(ftlCode, "utf8"),
2021-03-07 01:47:03 +01:00
);
2021-02-21 18:55:06 +01:00
});
2021-03-02 01:05:15 +01:00
{
2021-03-03 02:31:02 +01:00
const tmpDirPath = pathJoin(themeDirPath, "..", "tmp_xxKdLpdIdLd");
2021-03-02 01:05:15 +01:00
downloadBuiltinKeycloakTheme({
keycloakVersion,
"destDirPath": tmpDirPath,
2021-03-02 01:05:15 +01:00
});
const themeResourcesDirPath = pathJoin(themeDirPath, "resources");
2021-03-08 00:09:52 +01:00
2021-03-03 02:31:02 +01:00
transformCodebase({
"srcDirPath": pathJoin(
tmpDirPath,
"keycloak",
"login",
"resources",
),
"destDirPath": themeResourcesDirPath,
2021-03-08 00:09:52 +01:00
});
const reactAppPublicDirPath = pathJoin(
reactAppBuildDirPath,
"..",
"public",
);
2021-03-08 00:09:52 +01:00
transformCodebase({
"srcDirPath": themeResourcesDirPath,
"destDirPath": pathJoin(reactAppPublicDirPath, resourcesPath),
2021-03-08 00:09:52 +01:00
});
transformCodebase({
"srcDirPath": pathJoin(
tmpDirPath,
"keycloak",
"common",
"resources",
),
"destDirPath": pathJoin(reactAppPublicDirPath, resourcesCommonPath),
2021-03-03 02:31:02 +01:00
});
2021-03-02 01:05:15 +01:00
const keycloakResourcesWithinPublicDirPath = pathJoin(
reactAppPublicDirPath,
subDirOfPublicDirBasename,
);
2021-03-08 00:09:52 +01:00
fs.writeFileSync(
pathJoin(keycloakResourcesWithinPublicDirPath, "README.txt"),
Buffer.from(
[
"This is just a test folder that helps develop",
"the login and register page without having to yarn build",
].join(" "),
),
2021-03-08 00:09:52 +01:00
);
2021-03-10 22:45:09 +01:00
fs.writeFileSync(
pathJoin(keycloakResourcesWithinPublicDirPath, ".gitignore"),
Buffer.from("*", "utf8"),
2021-03-10 22:45:09 +01:00
);
2021-03-03 02:31:02 +01:00
child_process.execSync(`rm -r ${tmpDirPath}`);
2021-03-02 01:05:15 +01:00
}
2021-02-22 00:35:52 +01:00
fs.writeFileSync(
pathJoin(themeDirPath, "theme.properties"),
Buffer.from(
"parent=keycloak".concat("\n\n", extraThemeProperties.join("\n\n")),
"utf8",
),
2021-02-22 00:35:52 +01:00
);
2021-02-21 18:55:06 +01:00
}