Better prettier params (changelog ignore)
This commit is contained in:
@ -1,15 +1,8 @@
|
||||
import { generateKeycloakThemeResources } from "./generateKeycloakThemeResources";
|
||||
import { generateJavaStackFiles } from "./generateJavaStackFiles";
|
||||
import {
|
||||
join as pathJoin,
|
||||
relative as pathRelative,
|
||||
basename as pathBasename,
|
||||
} from "path";
|
||||
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
||||
import * as child_process from "child_process";
|
||||
import {
|
||||
generateDebugFiles,
|
||||
containerLaunchScriptBasename,
|
||||
} from "./generateDebugFiles";
|
||||
import { generateDebugFiles, containerLaunchScriptBasename } from "./generateDebugFiles";
|
||||
import { URL } from "url";
|
||||
|
||||
type ParsedPackageJson = {
|
||||
@ -20,18 +13,11 @@ type ParsedPackageJson = {
|
||||
|
||||
const reactProjectDirPath = process.cwd();
|
||||
|
||||
const doUseExternalAssets =
|
||||
process.argv[2]?.toLowerCase() === "--external-assets";
|
||||
const doUseExternalAssets = process.argv[2]?.toLowerCase() === "--external-assets";
|
||||
|
||||
const parsedPackageJson: ParsedPackageJson = require(pathJoin(
|
||||
reactProjectDirPath,
|
||||
"package.json",
|
||||
));
|
||||
const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));
|
||||
|
||||
export const keycloakThemeBuildingDirPath = pathJoin(
|
||||
reactProjectDirPath,
|
||||
"build_keycloak",
|
||||
);
|
||||
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
|
||||
|
||||
function sanitizeThemeName(name: string) {
|
||||
return name
|
||||
@ -43,11 +29,8 @@ function sanitizeThemeName(name: string) {
|
||||
export function main() {
|
||||
console.log("🔏 Building the keycloak theme...⌚");
|
||||
|
||||
const extraPagesId: string[] =
|
||||
(parsedPackageJson as any)["keycloakify"]?.["extraPages"] ?? [];
|
||||
const extraThemeProperties: string[] =
|
||||
(parsedPackageJson as any)["keycloakify"]?.["extraThemeProperties"] ??
|
||||
[];
|
||||
const extraPagesId: string[] = (parsedPackageJson as any)["keycloakify"]?.["extraPages"] ?? [];
|
||||
const extraThemeProperties: string[] = (parsedPackageJson as any)["keycloakify"]?.["extraThemeProperties"] ?? [];
|
||||
const themeName = sanitizeThemeName(parsedPackageJson.name);
|
||||
|
||||
generateKeycloakThemeResources({
|
||||
@ -62,17 +45,12 @@ export function main() {
|
||||
})();
|
||||
|
||||
return {
|
||||
"urlPathname":
|
||||
url === undefined
|
||||
? "/"
|
||||
: url.pathname.replace(/([^/])$/, "$1/"),
|
||||
"urlPathname": url === undefined ? "/" : url.pathname.replace(/([^/])$/, "$1/"),
|
||||
"urlOrigin": !doUseExternalAssets
|
||||
? undefined
|
||||
: (() => {
|
||||
if (url === undefined) {
|
||||
console.error(
|
||||
"ERROR: You must specify 'homepage' in your package.json",
|
||||
);
|
||||
console.error("ERROR: You must specify 'homepage' in your package.json");
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
@ -108,10 +86,7 @@ export function main() {
|
||||
console.log(
|
||||
[
|
||||
"",
|
||||
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(
|
||||
reactProjectDirPath,
|
||||
jarFilePath,
|
||||
)} 🚀`,
|
||||
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
|
||||
`It is to be placed in "/opt/jboss/keycloak/standalone/deployments" in the container running a jboss/keycloak Docker image.`,
|
||||
"",
|
||||
"Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:",
|
||||
@ -125,9 +100,7 @@ export function main() {
|
||||
" - sh",
|
||||
" args:",
|
||||
" - -c",
|
||||
` - curl -L -f -S -o /extensions/${pathBasename(
|
||||
jarFilePath,
|
||||
)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`,
|
||||
` - curl -L -f -S -o /extensions/${pathBasename(jarFilePath)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`,
|
||||
" volumeMounts:",
|
||||
" - name: extensions",
|
||||
" mountPath: /extensions",
|
||||
@ -146,13 +119,7 @@ export function main() {
|
||||
"",
|
||||
"To test your theme locally, with hot reloading, you can spin up a Keycloak container image with the theme loaded by running:",
|
||||
"",
|
||||
`👉 $ ./${pathRelative(
|
||||
reactProjectDirPath,
|
||||
pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
containerLaunchScriptBasename,
|
||||
),
|
||||
)} 👈`,
|
||||
`👉 $ ./${pathRelative(reactProjectDirPath, pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename))} 👈`,
|
||||
"",
|
||||
'To enable the theme within keycloak log into the admin console ( 👉 http://localhost:8080 username: admin, password: admin 👈), create a realm (called "myrealm" for example),',
|
||||
`go to your realm settings, click on the theme tab then select ${themeName}.`,
|
||||
|
@ -1,15 +1,10 @@
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||
|
||||
export const containerLaunchScriptBasename =
|
||||
"start_keycloak_testing_container.sh";
|
||||
export const containerLaunchScriptBasename = "start_keycloak_testing_container.sh";
|
||||
|
||||
/** Files for being able to run a hot reload keycloak container */
|
||||
export function generateDebugFiles(params: {
|
||||
keycloakVersion: "11.0.3" | "15.0.2";
|
||||
themeName: string;
|
||||
keycloakThemeBuildingDirPath: string;
|
||||
}) {
|
||||
export function generateDebugFiles(params: { keycloakVersion: "11.0.3" | "15.0.2"; themeName: string; keycloakThemeBuildingDirPath: string }) {
|
||||
const { themeName, keycloakThemeBuildingDirPath, keycloakVersion } = params;
|
||||
|
||||
fs.writeFileSync(
|
||||
@ -67,11 +62,7 @@ export function generateDebugFiles(params: {
|
||||
{ "mode": 0o755 },
|
||||
);
|
||||
|
||||
const standaloneHaFilePath = pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
"configuration",
|
||||
`standalone-ha.xml`,
|
||||
);
|
||||
const standaloneHaFilePath = pathJoin(keycloakThemeBuildingDirPath, "configuration", `standalone-ha.xml`);
|
||||
|
||||
try {
|
||||
fs.mkdirSync(pathDirname(standaloneHaFilePath));
|
||||
@ -80,24 +71,14 @@ export function generateDebugFiles(params: {
|
||||
fs.writeFileSync(
|
||||
standaloneHaFilePath,
|
||||
fs
|
||||
.readFileSync(
|
||||
pathJoin(__dirname, `standalone-ha_${keycloakVersion}.xml`),
|
||||
)
|
||||
.readFileSync(pathJoin(__dirname, `standalone-ha_${keycloakVersion}.xml`))
|
||||
.toString("utf8")
|
||||
.replace(
|
||||
new RegExp(
|
||||
[
|
||||
"<staticMaxAge>2592000</staticMaxAge>",
|
||||
"<cacheThemes>true</cacheThemes>",
|
||||
"<cacheTemplates>true</cacheTemplates>",
|
||||
].join("\\s*"),
|
||||
["<staticMaxAge>2592000</staticMaxAge>", "<cacheThemes>true</cacheThemes>", "<cacheTemplates>true</cacheTemplates>"].join("\\s*"),
|
||||
"g",
|
||||
),
|
||||
[
|
||||
"<staticMaxAge>-1</staticMaxAge>",
|
||||
"<cacheThemes>false</cacheThemes>",
|
||||
"<cacheTemplates>false</cacheTemplates>",
|
||||
].join("\n"),
|
||||
["<staticMaxAge>-1</staticMaxAge>", "<cacheThemes>false</cacheThemes>", "<cacheTemplates>false</cacheTemplates>"].join("\n"),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
import cheerio from "cheerio";
|
||||
import {
|
||||
replaceImportsFromStaticInJsCode,
|
||||
replaceImportsInInlineCssCode,
|
||||
generateCssCodeToDefineGlobals,
|
||||
} from "../replaceImportFromStatic";
|
||||
import { replaceImportsFromStaticInJsCode, replaceImportsInInlineCssCode, generateCssCodeToDefineGlobals } from "../replaceImportFromStatic";
|
||||
import fs from "fs";
|
||||
import { join as pathJoin } from "path";
|
||||
import { objectKeys } from "tsafe/objectKeys";
|
||||
@ -35,8 +31,7 @@ export function generateFtlFilesCodeFactory(params: {
|
||||
urlPathname: string;
|
||||
urlOrigin: undefined | string;
|
||||
}) {
|
||||
const { cssGlobalsToDefine, indexHtmlCode, urlPathname, urlOrigin } =
|
||||
params;
|
||||
const { cssGlobalsToDefine, indexHtmlCode, urlPathname, urlOrigin } = params;
|
||||
|
||||
const $ = cheerio.load(indexHtmlCode);
|
||||
|
||||
@ -76,19 +71,14 @@ export function generateFtlFilesCodeFactory(params: {
|
||||
attrName,
|
||||
urlOrigin !== undefined
|
||||
? href.replace(/^\//, `${urlOrigin}/`)
|
||||
: href.replace(
|
||||
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
|
||||
"${url.resourcesPath}/build/",
|
||||
),
|
||||
: href.replace(new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`), "${url.resourcesPath}/build/"),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
||||
const ftlPlaceholders = {
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadAdjacentFile(
|
||||
"common.ftl",
|
||||
).match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1],
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadAdjacentFile("common.ftl").match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1],
|
||||
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
|
||||
"<#if scripts??>",
|
||||
" <#list scripts as script>",
|
||||
@ -98,8 +88,7 @@ export function generateFtlFilesCodeFactory(params: {
|
||||
].join("\n"),
|
||||
};
|
||||
|
||||
const pageSpecificCodePlaceholder =
|
||||
"<!-- dIddLqMeOedErIdLsPdNdI9dSl42sw -->";
|
||||
const pageSpecificCodePlaceholder = "<!-- dIddLqMeOedErIdLsPdNdI9dSl42sw -->";
|
||||
|
||||
$("head").prepend(
|
||||
[
|
||||
@ -152,9 +141,7 @@ export function generateFtlFilesCodeFactory(params: {
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
objectKeys(ftlPlaceholders).forEach(
|
||||
id => (ftlCode = ftlCode.replace(id, ftlPlaceholders[id])),
|
||||
);
|
||||
objectKeys(ftlPlaceholders).forEach(id => (ftlCode = ftlCode.replace(id, ftlPlaceholders[id])));
|
||||
|
||||
return { ftlCode };
|
||||
}
|
||||
|
@ -2,14 +2,10 @@ import * as url from "url";
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||
|
||||
export function generateJavaStackFiles(params: {
|
||||
version: string;
|
||||
themeName: string;
|
||||
homepage?: string;
|
||||
keycloakThemeBuildingDirPath: string;
|
||||
}): { jarFilePath: string } {
|
||||
const { themeName, version, homepage, keycloakThemeBuildingDirPath } =
|
||||
params;
|
||||
export function generateJavaStackFiles(params: { version: string; themeName: string; homepage?: string; keycloakThemeBuildingDirPath: string }): {
|
||||
jarFilePath: string;
|
||||
} {
|
||||
const { themeName, version, homepage, keycloakThemeBuildingDirPath } = params;
|
||||
|
||||
{
|
||||
const { pomFileCode } = (function generatePomFileCode(): {
|
||||
@ -49,21 +45,11 @@ export function generateJavaStackFiles(params: {
|
||||
return { pomFileCode };
|
||||
})();
|
||||
|
||||
fs.writeFileSync(
|
||||
pathJoin(keycloakThemeBuildingDirPath, "pom.xml"),
|
||||
Buffer.from(pomFileCode, "utf8"),
|
||||
);
|
||||
fs.writeFileSync(pathJoin(keycloakThemeBuildingDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
||||
}
|
||||
|
||||
{
|
||||
const themeManifestFilePath = pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
"src",
|
||||
"main",
|
||||
"resources",
|
||||
"META-INF",
|
||||
"keycloak-themes.json",
|
||||
);
|
||||
const themeManifestFilePath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "META-INF", "keycloak-themes.json");
|
||||
|
||||
try {
|
||||
fs.mkdirSync(pathDirname(themeManifestFilePath));
|
||||
@ -90,10 +76,6 @@ export function generateJavaStackFiles(params: {
|
||||
}
|
||||
|
||||
return {
|
||||
"jarFilePath": pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
"target",
|
||||
`${themeName}-${version}.jar`,
|
||||
),
|
||||
"jarFilePath": pathJoin(keycloakThemeBuildingDirPath, "target", `${themeName}-${version}.jar`),
|
||||
};
|
||||
}
|
||||
|
@ -1,18 +1,11 @@
|
||||
import { transformCodebase } from "../tools/transformCodebase";
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin } from "path";
|
||||
import {
|
||||
replaceImportsInCssCode,
|
||||
replaceImportsFromStaticInJsCode,
|
||||
} from "./replaceImportFromStatic";
|
||||
import { replaceImportsInCssCode, replaceImportsFromStaticInJsCode } from "./replaceImportFromStatic";
|
||||
import { generateFtlFilesCodeFactory, pageIds } from "./generateFtl";
|
||||
import { downloadBuiltinKeycloakTheme } from "../download-builtin-keycloak-theme";
|
||||
import * as child_process from "child_process";
|
||||
import {
|
||||
resourcesCommonPath,
|
||||
resourcesPath,
|
||||
subDirOfPublicDirBasename,
|
||||
} from "../../lib/getKcContext/kcContextMocks/urlResourcesPath";
|
||||
import { resourcesCommonPath, resourcesPath, subDirOfPublicDirBasename } from "../../lib/getKcContext/kcContextMocks/urlResourcesPath";
|
||||
import { isInside } from "../tools/isInside";
|
||||
|
||||
export function generateKeycloakThemeResources(params: {
|
||||
@ -37,33 +30,19 @@ export function generateKeycloakThemeResources(params: {
|
||||
keycloakVersion,
|
||||
} = params;
|
||||
|
||||
const themeDirPath = pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
"src",
|
||||
"main",
|
||||
"resources",
|
||||
"theme",
|
||||
themeName,
|
||||
"login",
|
||||
);
|
||||
const themeDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", themeName, "login");
|
||||
|
||||
let allCssGlobalsToDefine: Record<string, string> = {};
|
||||
|
||||
transformCodebase({
|
||||
"destDirPath":
|
||||
urlOrigin === undefined
|
||||
? pathJoin(themeDirPath, "resources", "build")
|
||||
: reactAppBuildDirPath,
|
||||
"destDirPath": urlOrigin === undefined ? pathJoin(themeDirPath, "resources", "build") : reactAppBuildDirPath,
|
||||
"srcDirPath": reactAppBuildDirPath,
|
||||
"transformSourceCode": ({ filePath, sourceCode }) => {
|
||||
//NOTE: Prevent cycles, excludes the folder we generated for debug in public/
|
||||
if (
|
||||
urlOrigin === undefined &&
|
||||
isInside({
|
||||
"dirPath": pathJoin(
|
||||
reactAppBuildDirPath,
|
||||
subDirOfPublicDirBasename,
|
||||
),
|
||||
"dirPath": pathJoin(reactAppBuildDirPath, subDirOfPublicDirBasename),
|
||||
filePath,
|
||||
})
|
||||
) {
|
||||
@ -71,10 +50,9 @@ export function generateKeycloakThemeResources(params: {
|
||||
}
|
||||
|
||||
if (urlOrigin === undefined && /\.css?$/i.test(filePath)) {
|
||||
const { cssGlobalsToDefine, fixedCssCode } =
|
||||
replaceImportsInCssCode({
|
||||
"cssCode": sourceCode.toString("utf8"),
|
||||
});
|
||||
const { cssGlobalsToDefine, fixedCssCode } = replaceImportsInCssCode({
|
||||
"cssCode": sourceCode.toString("utf8"),
|
||||
});
|
||||
|
||||
allCssGlobalsToDefine = {
|
||||
...allCssGlobalsToDefine,
|
||||
@ -97,17 +75,13 @@ export function generateKeycloakThemeResources(params: {
|
||||
};
|
||||
}
|
||||
|
||||
return urlOrigin === undefined
|
||||
? { "modifiedSourceCode": sourceCode }
|
||||
: undefined;
|
||||
return urlOrigin === undefined ? { "modifiedSourceCode": sourceCode } : undefined;
|
||||
},
|
||||
});
|
||||
|
||||
const { generateFtlFilesCode } = generateFtlFilesCodeFactory({
|
||||
"cssGlobalsToDefine": allCssGlobalsToDefine,
|
||||
"indexHtmlCode": fs
|
||||
.readFileSync(pathJoin(reactAppBuildDirPath, "index.html"))
|
||||
.toString("utf8"),
|
||||
"indexHtmlCode": fs.readFileSync(pathJoin(reactAppBuildDirPath, "index.html")).toString("utf8"),
|
||||
urlPathname,
|
||||
urlOrigin,
|
||||
});
|
||||
@ -117,10 +91,7 @@ export function generateKeycloakThemeResources(params: {
|
||||
|
||||
fs.mkdirSync(themeDirPath, { "recursive": true });
|
||||
|
||||
fs.writeFileSync(
|
||||
pathJoin(themeDirPath, pageId),
|
||||
Buffer.from(ftlCode, "utf8"),
|
||||
);
|
||||
fs.writeFileSync(pathJoin(themeDirPath, pageId), Buffer.from(ftlCode, "utf8"));
|
||||
});
|
||||
|
||||
{
|
||||
@ -134,20 +105,11 @@ export function generateKeycloakThemeResources(params: {
|
||||
const themeResourcesDirPath = pathJoin(themeDirPath, "resources");
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": pathJoin(
|
||||
tmpDirPath,
|
||||
"keycloak",
|
||||
"login",
|
||||
"resources",
|
||||
),
|
||||
"srcDirPath": pathJoin(tmpDirPath, "keycloak", "login", "resources"),
|
||||
"destDirPath": themeResourcesDirPath,
|
||||
});
|
||||
|
||||
const reactAppPublicDirPath = pathJoin(
|
||||
reactAppBuildDirPath,
|
||||
"..",
|
||||
"public",
|
||||
);
|
||||
const reactAppPublicDirPath = pathJoin(reactAppBuildDirPath, "..", "public");
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": themeResourcesDirPath,
|
||||
@ -155,43 +117,24 @@ export function generateKeycloakThemeResources(params: {
|
||||
});
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": pathJoin(
|
||||
tmpDirPath,
|
||||
"keycloak",
|
||||
"common",
|
||||
"resources",
|
||||
),
|
||||
"srcDirPath": pathJoin(tmpDirPath, "keycloak", "common", "resources"),
|
||||
"destDirPath": pathJoin(reactAppPublicDirPath, resourcesCommonPath),
|
||||
});
|
||||
|
||||
const keycloakResourcesWithinPublicDirPath = pathJoin(
|
||||
reactAppPublicDirPath,
|
||||
subDirOfPublicDirBasename,
|
||||
);
|
||||
const keycloakResourcesWithinPublicDirPath = pathJoin(reactAppPublicDirPath, subDirOfPublicDirBasename);
|
||||
|
||||
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(" "),
|
||||
),
|
||||
Buffer.from(["This is just a test folder that helps develop", "the login and register page without having to yarn build"].join(" ")),
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
pathJoin(keycloakResourcesWithinPublicDirPath, ".gitignore"),
|
||||
Buffer.from("*", "utf8"),
|
||||
);
|
||||
fs.writeFileSync(pathJoin(keycloakResourcesWithinPublicDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
||||
|
||||
child_process.execSync(`rm -r ${tmpDirPath}`);
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
pathJoin(themeDirPath, "theme.properties"),
|
||||
Buffer.from(
|
||||
"parent=keycloak".concat("\n\n", extraThemeProperties.join("\n\n")),
|
||||
"utf8",
|
||||
),
|
||||
Buffer.from("parent=keycloak".concat("\n\n", extraThemeProperties.join("\n\n")), "utf8"),
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
import * as crypto from "crypto";
|
||||
import { ftlValuesGlobalName } from "./ftlValuesGlobalName";
|
||||
|
||||
export function replaceImportsFromStaticInJsCode(params: {
|
||||
jsCode: string;
|
||||
urlOrigin: undefined | string;
|
||||
}): { fixedJsCode: string } {
|
||||
export function replaceImportsFromStaticInJsCode(params: { jsCode: string; urlOrigin: undefined | string }): { fixedJsCode: string } {
|
||||
/*
|
||||
NOTE:
|
||||
|
||||
@ -25,34 +22,23 @@ export function replaceImportsFromStaticInJsCode(params: {
|
||||
? `window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/`
|
||||
: `("${ftlValuesGlobalName}" in window ? "${urlOrigin}" : "") + ${group} + "static/`,
|
||||
)
|
||||
.replace(
|
||||
/".chunk.css",([a-z])+=([a-z]+\.[a-z]+)\+([a-z]+),/,
|
||||
(...[, group1, group2, group3]) =>
|
||||
urlOrigin === undefined
|
||||
? `".chunk.css",${group1} = window.${ftlValuesGlobalName}.url.resourcesPath + "/build/" + ${group3},`
|
||||
: `".chunk.css",${group1} = ("${ftlValuesGlobalName}" in window ? "${urlOrigin}" : "") + ${group2} + ${group3},`,
|
||||
.replace(/".chunk.css",([a-z])+=([a-z]+\.[a-z]+)\+([a-z]+),/, (...[, group1, group2, group3]) =>
|
||||
urlOrigin === undefined
|
||||
? `".chunk.css",${group1} = window.${ftlValuesGlobalName}.url.resourcesPath + "/build/" + ${group3},`
|
||||
: `".chunk.css",${group1} = ("${ftlValuesGlobalName}" in window ? "${urlOrigin}" : "") + ${group2} + ${group3},`,
|
||||
);
|
||||
|
||||
return { fixedJsCode };
|
||||
}
|
||||
|
||||
export function replaceImportsInInlineCssCode(params: {
|
||||
cssCode: string;
|
||||
urlPathname: string;
|
||||
urlOrigin: undefined | string;
|
||||
}): { fixedCssCode: string } {
|
||||
export function replaceImportsInInlineCssCode(params: { cssCode: string; urlPathname: string; urlOrigin: undefined | string }): {
|
||||
fixedCssCode: string;
|
||||
} {
|
||||
const { cssCode, urlPathname, urlOrigin } = params;
|
||||
|
||||
const fixedCssCode = cssCode.replace(
|
||||
urlPathname === "/"
|
||||
? /url\(\/([^/][^)]+)\)/g
|
||||
: new RegExp(`url\\(${urlPathname}([^)]+)\\)`, "g"),
|
||||
(...[, group]) =>
|
||||
`url(${
|
||||
urlOrigin === undefined
|
||||
? "${url.resourcesPath}/build/" + group
|
||||
: params.urlOrigin + urlPathname + group
|
||||
})`,
|
||||
urlPathname === "/" ? /url\(\/([^/][^)]+)\)/g : new RegExp(`url\\(${urlPathname}([^)]+)\\)`, "g"),
|
||||
(...[, group]) => `url(${urlOrigin === undefined ? "${url.resourcesPath}/build/" + group : params.urlOrigin + urlPathname + group})`,
|
||||
);
|
||||
|
||||
return { fixedCssCode };
|
||||
@ -67,15 +53,7 @@ export function replaceImportsInCssCode(params: { cssCode: string }): {
|
||||
const cssGlobalsToDefine: Record<string, string> = {};
|
||||
|
||||
new Set(cssCode.match(/url\(\/[^/][^)]+\)[^;}]*/g) ?? []).forEach(
|
||||
match =>
|
||||
(cssGlobalsToDefine[
|
||||
"url" +
|
||||
crypto
|
||||
.createHash("sha256")
|
||||
.update(match)
|
||||
.digest("hex")
|
||||
.substring(0, 15)
|
||||
] = match),
|
||||
match => (cssGlobalsToDefine["url" + crypto.createHash("sha256").update(match).digest("hex").substring(0, 15)] = match),
|
||||
);
|
||||
|
||||
let fixedCssCode = cssCode;
|
||||
@ -83,18 +61,13 @@ export function replaceImportsInCssCode(params: { cssCode: string }): {
|
||||
Object.keys(cssGlobalsToDefine).forEach(
|
||||
cssVariableName =>
|
||||
//NOTE: split/join pattern ~ replace all
|
||||
(fixedCssCode = fixedCssCode
|
||||
.split(cssGlobalsToDefine[cssVariableName])
|
||||
.join(`var(--${cssVariableName})`)),
|
||||
(fixedCssCode = fixedCssCode.split(cssGlobalsToDefine[cssVariableName]).join(`var(--${cssVariableName})`)),
|
||||
);
|
||||
|
||||
return { fixedCssCode, cssGlobalsToDefine };
|
||||
}
|
||||
|
||||
export function generateCssCodeToDefineGlobals(params: {
|
||||
cssGlobalsToDefine: Record<string, string>;
|
||||
urlPathname: string;
|
||||
}): {
|
||||
export function generateCssCodeToDefineGlobals(params: { cssGlobalsToDefine: Record<string, string>; urlPathname: string }): {
|
||||
cssCodeToPrependInHead: string;
|
||||
} {
|
||||
const { cssGlobalsToDefine, urlPathname } = params;
|
||||
@ -107,10 +80,7 @@ export function generateCssCodeToDefineGlobals(params: {
|
||||
[
|
||||
`--${cssVariableName}:`,
|
||||
cssGlobalsToDefine[cssVariableName].replace(
|
||||
new RegExp(
|
||||
`url\\(${urlPathname.replace(/\//g, "\\/")}`,
|
||||
"g",
|
||||
),
|
||||
new RegExp(`url\\(${urlPathname.replace(/\//g, "\\/")}`, "g"),
|
||||
"url(${url.resourcesPath}/build/",
|
||||
),
|
||||
].join(" "),
|
||||
|
@ -5,10 +5,7 @@ import { join as pathJoin } from "path";
|
||||
import { downloadAndUnzip } from "./tools/downloadAndUnzip";
|
||||
import type { KeycloakVersion } from "./KeycloakVersion";
|
||||
|
||||
export function downloadBuiltinKeycloakTheme(params: {
|
||||
keycloakVersion: KeycloakVersion;
|
||||
destDirPath: string;
|
||||
}) {
|
||||
export function downloadBuiltinKeycloakTheme(params: { keycloakVersion: KeycloakVersion; destDirPath: string }) {
|
||||
const { keycloakVersion, destDirPath } = params;
|
||||
|
||||
for (const ext of ["", "-community"]) {
|
||||
@ -31,17 +28,9 @@ if (require.main === module) {
|
||||
return keycloakVersion;
|
||||
})();
|
||||
|
||||
const destDirPath = pathJoin(
|
||||
keycloakThemeBuildingDirPath,
|
||||
"src",
|
||||
"main",
|
||||
"resources",
|
||||
"theme",
|
||||
);
|
||||
const destDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme");
|
||||
|
||||
console.log(
|
||||
`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`,
|
||||
);
|
||||
console.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
|
||||
|
||||
downloadBuiltinKeycloakTheme({
|
||||
keycloakVersion,
|
||||
|
@ -24,16 +24,13 @@ for (const keycloakVersion of keycloakVersions) {
|
||||
|
||||
type Dictionary = { [idiomId: string]: string };
|
||||
|
||||
const record: { [typeOfPage: string]: { [language: string]: Dictionary } } =
|
||||
{};
|
||||
const record: { [typeOfPage: string]: { [language: string]: Dictionary } } = {};
|
||||
|
||||
{
|
||||
const baseThemeDirPath = pathJoin(tmpDirPath, "base");
|
||||
|
||||
crawl(baseThemeDirPath).forEach(filePath => {
|
||||
const match = filePath.match(
|
||||
/^([^/]+)\/messages\/messages_([^.]+)\.properties$/,
|
||||
);
|
||||
const match = filePath.match(/^([^/]+)\/messages\/messages_([^.]+)\.properties$/);
|
||||
|
||||
if (match === null) {
|
||||
return;
|
||||
@ -41,34 +38,17 @@ for (const keycloakVersion of keycloakVersions) {
|
||||
|
||||
const [, typeOfPage, language] = match;
|
||||
|
||||
(record[typeOfPage] ??= {})[language.replace(/_/g, "-")] =
|
||||
Object.fromEntries(
|
||||
Object.entries(
|
||||
propertiesParser.parse(
|
||||
fs
|
||||
.readFileSync(
|
||||
pathJoin(baseThemeDirPath, filePath),
|
||||
)
|
||||
.toString("utf8"),
|
||||
),
|
||||
).map(([key, value]: any) => [
|
||||
key,
|
||||
value.replace(/''/g, "'"),
|
||||
]),
|
||||
);
|
||||
(record[typeOfPage] ??= {})[language.replace(/_/g, "-")] = Object.fromEntries(
|
||||
Object.entries(propertiesParser.parse(fs.readFileSync(pathJoin(baseThemeDirPath, filePath)).toString("utf8"))).map(
|
||||
([key, value]: any) => [key, value.replace(/''/g, "'")],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
rm_r(tmpDirPath);
|
||||
|
||||
const targetDirPath = pathJoin(
|
||||
getProjectRoot(),
|
||||
"src",
|
||||
"lib",
|
||||
"i18n",
|
||||
"generated_kcMessages",
|
||||
keycloakVersion,
|
||||
);
|
||||
const targetDirPath = pathJoin(getProjectRoot(), "src", "lib", "i18n", "generated_kcMessages", keycloakVersion);
|
||||
|
||||
fs.mkdirSync(targetDirPath, { "recursive": true });
|
||||
|
||||
@ -79,18 +59,11 @@ for (const keycloakVersion of keycloakVersions) {
|
||||
filePath,
|
||||
Buffer.from(
|
||||
[
|
||||
`//This code was automatically generated by running ${pathRelative(
|
||||
getProjectRoot(),
|
||||
__filename,
|
||||
)}`,
|
||||
`//This code was automatically generated by running ${pathRelative(getProjectRoot(), __filename)}`,
|
||||
"//PLEASE DO NOT EDIT MANUALLY",
|
||||
"",
|
||||
"/* spell-checker: disable */",
|
||||
`export const kcMessages= ${JSON.stringify(
|
||||
record[pageType],
|
||||
null,
|
||||
2,
|
||||
)};`,
|
||||
`export const kcMessages= ${JSON.stringify(record[pageType], null, 2)};`,
|
||||
"/* spell-checker: enable */",
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
|
@ -9,13 +9,7 @@ fs.writeFileSync(
|
||||
Buffer.from(
|
||||
JSON.stringify(
|
||||
(() => {
|
||||
const packageJsonParsed = JSON.parse(
|
||||
fs
|
||||
.readFileSync(
|
||||
pathJoin(keycloakifyDirPath, "package.json"),
|
||||
)
|
||||
.toString("utf8"),
|
||||
);
|
||||
const packageJsonParsed = JSON.parse(fs.readFileSync(pathJoin(keycloakifyDirPath, "package.json")).toString("utf8"));
|
||||
|
||||
return {
|
||||
...packageJsonParsed,
|
||||
@ -32,29 +26,14 @@ fs.writeFileSync(
|
||||
|
||||
const commonThirdPartyDeps = (() => {
|
||||
const namespaceModuleNames = ["@emotion"];
|
||||
const standaloneModuleNames = [
|
||||
"react",
|
||||
"@types/react",
|
||||
"powerhooks",
|
||||
"tss-react",
|
||||
"evt",
|
||||
];
|
||||
const standaloneModuleNames = ["react", "@types/react", "powerhooks", "tss-react", "evt"];
|
||||
|
||||
return [
|
||||
...namespaceModuleNames
|
||||
.map(namespaceModuleName =>
|
||||
fs
|
||||
.readdirSync(
|
||||
pathJoin(
|
||||
keycloakifyDirPath,
|
||||
"node_modules",
|
||||
namespaceModuleName,
|
||||
),
|
||||
)
|
||||
.map(
|
||||
submoduleName =>
|
||||
`${namespaceModuleName}/${submoduleName}`,
|
||||
),
|
||||
.readdirSync(pathJoin(keycloakifyDirPath, "node_modules", namespaceModuleName))
|
||||
.map(submoduleName => `${namespaceModuleName}/${submoduleName}`),
|
||||
)
|
||||
.reduce((prev, curr) => [...prev, ...curr], []),
|
||||
...standaloneModuleNames,
|
||||
@ -63,22 +42,14 @@ const commonThirdPartyDeps = (() => {
|
||||
|
||||
const yarnHomeDirPath = pathJoin(keycloakifyDirPath, ".yarn_home");
|
||||
|
||||
execSync(
|
||||
["rm -rf", "mkdir"].map(cmd => `${cmd} ${yarnHomeDirPath}`).join(" && "),
|
||||
);
|
||||
execSync(["rm -rf", "mkdir"].map(cmd => `${cmd} ${yarnHomeDirPath}`).join(" && "));
|
||||
|
||||
const execYarnLink = (params: { targetModuleName?: string; cwd: string }) => {
|
||||
const { targetModuleName, cwd } = params;
|
||||
|
||||
const cmd = [
|
||||
"yarn",
|
||||
"link",
|
||||
...(targetModuleName !== undefined ? [targetModuleName] : []),
|
||||
].join(" ");
|
||||
const cmd = ["yarn", "link", ...(targetModuleName !== undefined ? [targetModuleName] : [])].join(" ");
|
||||
|
||||
console.log(
|
||||
`$ cd ${pathRelative(keycloakifyDirPath, cwd) || "."} && ${cmd}`,
|
||||
);
|
||||
console.log(`$ cd ${pathRelative(keycloakifyDirPath, cwd) || "."} && ${cmd}`);
|
||||
|
||||
execSync(cmd, {
|
||||
cwd,
|
||||
@ -91,12 +62,9 @@ const execYarnLink = (params: { targetModuleName?: string; cwd: string }) => {
|
||||
|
||||
const testAppNames = ["keycloakify-demo-app"] as const;
|
||||
|
||||
const getTestAppPath = (testAppName: typeof testAppNames[number]) =>
|
||||
pathJoin(keycloakifyDirPath, "..", testAppName);
|
||||
const getTestAppPath = (testAppName: typeof testAppNames[number]) => pathJoin(keycloakifyDirPath, "..", testAppName);
|
||||
|
||||
testAppNames.forEach(testAppName =>
|
||||
execSync("yarn install", { "cwd": getTestAppPath(testAppName) }),
|
||||
);
|
||||
testAppNames.forEach(testAppName => execSync("yarn install", { "cwd": getTestAppPath(testAppName) }));
|
||||
|
||||
console.log("=== Linking common dependencies ===");
|
||||
|
||||
@ -109,13 +77,7 @@ commonThirdPartyDeps.forEach(commonThirdPartyDep => {
|
||||
console.log(`${current}/${total} ${commonThirdPartyDep}`);
|
||||
|
||||
const localInstallPath = pathJoin(
|
||||
...[
|
||||
keycloakifyDirPath,
|
||||
"node_modules",
|
||||
...(commonThirdPartyDep.startsWith("@")
|
||||
? commonThirdPartyDep.split("/")
|
||||
: [commonThirdPartyDep]),
|
||||
],
|
||||
...[keycloakifyDirPath, "node_modules", ...(commonThirdPartyDep.startsWith("@") ? commonThirdPartyDep.split("/") : [commonThirdPartyDep])],
|
||||
);
|
||||
|
||||
execYarnLink({ "cwd": localInstallPath });
|
||||
|
@ -5,11 +5,7 @@ import { transformCodebase } from "../tools/transformCodebase";
|
||||
import { rm_rf, rm, rm_r } from "./rm";
|
||||
|
||||
/** assert url ends with .zip */
|
||||
export function downloadAndUnzip(params: {
|
||||
url: string;
|
||||
destDirPath: string;
|
||||
pathOfDirToExtractInArchive?: string;
|
||||
}) {
|
||||
export function downloadAndUnzip(params: { url: string; destDirPath: string; pathOfDirToExtractInArchive?: string }) {
|
||||
const { url, destDirPath, pathOfDirToExtractInArchive } = params;
|
||||
|
||||
const tmpDirPath = pathJoin(destDirPath, "..", "tmp_xxKdOxnEdx");
|
||||
@ -20,22 +16,14 @@ export function downloadAndUnzip(params: {
|
||||
|
||||
execSync(`wget ${url}`, { "cwd": tmpDirPath });
|
||||
|
||||
execSync(
|
||||
`unzip ${pathBasename(url)}${
|
||||
pathOfDirToExtractInArchive === undefined
|
||||
? ""
|
||||
: ` "${pathOfDirToExtractInArchive}/*"`
|
||||
}`,
|
||||
{ "cwd": tmpDirPath },
|
||||
);
|
||||
execSync(`unzip ${pathBasename(url)}${pathOfDirToExtractInArchive === undefined ? "" : ` "${pathOfDirToExtractInArchive}/*"`}`, {
|
||||
"cwd": tmpDirPath,
|
||||
});
|
||||
|
||||
rm(pathBasename(url), { "cwd": tmpDirPath });
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath":
|
||||
pathOfDirToExtractInArchive === undefined
|
||||
? tmpDirPath
|
||||
: pathJoin(tmpDirPath, pathOfDirToExtractInArchive),
|
||||
"srcDirPath": pathOfDirToExtractInArchive === undefined ? tmpDirPath : pathJoin(tmpDirPath, pathOfDirToExtractInArchive),
|
||||
destDirPath,
|
||||
});
|
||||
|
||||
|
@ -2,9 +2,7 @@ import { getProjectRoot } from "./getProjectRoot";
|
||||
import { join as pathJoin } from "path";
|
||||
import child_process from "child_process";
|
||||
|
||||
Object.entries<string>(
|
||||
require(pathJoin(getProjectRoot(), "package.json"))["bin"],
|
||||
).forEach(([, scriptPath]) =>
|
||||
Object.entries<string>(require(pathJoin(getProjectRoot(), "package.json"))["bin"]).forEach(([, scriptPath]) =>
|
||||
child_process.execSync(`chmod +x ${scriptPath}`, {
|
||||
"cwd": getProjectRoot(),
|
||||
}),
|
||||
|
@ -1,16 +1,9 @@
|
||||
import { execSync } from "child_process";
|
||||
|
||||
function rmInternal(params: {
|
||||
pathToRemove: string;
|
||||
args: string | undefined;
|
||||
cwd: string | undefined;
|
||||
}) {
|
||||
function rmInternal(params: { pathToRemove: string; args: string | undefined; cwd: string | undefined }) {
|
||||
const { pathToRemove, args, cwd } = params;
|
||||
|
||||
execSync(
|
||||
`rm ${args ? `-${args} ` : ""}${pathToRemove.replace(/ /g, "\\ ")}`,
|
||||
cwd !== undefined ? { cwd } : undefined,
|
||||
);
|
||||
execSync(`rm ${args ? `-${args} ` : ""}${pathToRemove.replace(/ /g, "\\ ")}`, cwd !== undefined ? { cwd } : undefined);
|
||||
}
|
||||
|
||||
export function rm(pathToRemove: string, options?: { cwd: string }) {
|
||||
|
@ -3,10 +3,7 @@ import * as path from "path";
|
||||
import { crawl } from "./crawl";
|
||||
import { id } from "tsafe/id";
|
||||
|
||||
type TransformSourceCode = (params: {
|
||||
sourceCode: Buffer;
|
||||
filePath: string;
|
||||
}) =>
|
||||
type TransformSourceCode = (params: { sourceCode: Buffer; filePath: string }) =>
|
||||
| {
|
||||
modifiedSourceCode: Buffer;
|
||||
newFileName?: string;
|
||||
@ -14,11 +11,7 @@ type TransformSourceCode = (params: {
|
||||
| undefined;
|
||||
|
||||
/** Apply a transformation function to every file of directory */
|
||||
export function transformCodebase(params: {
|
||||
srcDirPath: string;
|
||||
destDirPath: string;
|
||||
transformSourceCode?: TransformSourceCode;
|
||||
}) {
|
||||
export function transformCodebase(params: { srcDirPath: string; destDirPath: string; transformSourceCode?: TransformSourceCode }) {
|
||||
const {
|
||||
srcDirPath,
|
||||
destDirPath,
|
||||
@ -46,10 +39,7 @@ export function transformCodebase(params: {
|
||||
const { newFileName, modifiedSourceCode } = transformSourceCodeResult;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(
|
||||
path.dirname(path.join(destDirPath, file_relative_path)),
|
||||
newFileName ?? path.basename(file_relative_path),
|
||||
),
|
||||
path.join(path.dirname(path.join(destDirPath, file_relative_path)), newFileName ?? path.basename(file_relative_path)),
|
||||
modifiedSourceCode,
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user