2021-06-14 21:24:56 +02:00
|
|
|
import cheerio from "cheerio";
|
2022-08-16 14:41:06 +07:00
|
|
|
import { replaceImportsFromStaticInJsCode } from "../replacers/replaceImportsFromStaticInJsCode";
|
|
|
|
import { generateCssCodeToDefineGlobals } from "../replacers/replaceImportsInCssCode";
|
|
|
|
import { replaceImportsInInlineCssCode } from "../replacers/replaceImportsInInlineCssCode";
|
2022-07-29 23:10:35 +02:00
|
|
|
import * as fs from "fs";
|
2021-06-14 21:24:56 +02:00
|
|
|
import { join as pathJoin } from "path";
|
2021-06-28 04:04:48 +02:00
|
|
|
import { objectKeys } from "tsafe/objectKeys";
|
2021-06-14 21:24:56 +02:00
|
|
|
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
2022-08-16 14:41:06 +07:00
|
|
|
import type { BuildOptions } from "../BuildOptions";
|
|
|
|
import { assert } from "tsafe/assert";
|
2023-09-03 07:14:57 +02:00
|
|
|
import type { ThemeType } from "../../constants";
|
2023-03-16 22:13:46 +01:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
export type BuildOptionsLike = {
|
|
|
|
themeVersion: string;
|
|
|
|
urlPathname: string | undefined;
|
|
|
|
};
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-04-01 13:31:35 +02:00
|
|
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2021-10-11 21:35:40 +02:00
|
|
|
export function generateFtlFilesCodeFactory(params: {
|
2023-09-04 01:19:21 +02:00
|
|
|
themeName: string;
|
2021-10-11 21:35:40 +02:00
|
|
|
indexHtmlCode: string;
|
2022-08-16 14:41:06 +07:00
|
|
|
//NOTE: Expected to be an empty object if external assets mode is enabled.
|
|
|
|
cssGlobalsToDefine: Record<string, string>;
|
|
|
|
buildOptions: BuildOptionsLike;
|
2023-04-04 01:40:55 +02:00
|
|
|
keycloakifyVersion: string;
|
2023-04-27 11:52:02 +02:00
|
|
|
themeType: ThemeType;
|
2023-06-19 00:09:21 +02:00
|
|
|
fieldNames: string[];
|
2021-10-11 21:35:40 +02:00
|
|
|
}) {
|
2023-09-04 01:19:21 +02:00
|
|
|
const { themeName, cssGlobalsToDefine, indexHtmlCode, buildOptions, keycloakifyVersion, themeType, fieldNames } = params;
|
2021-06-14 21:24:56 +02:00
|
|
|
|
|
|
|
const $ = cheerio.load(indexHtmlCode);
|
|
|
|
|
2022-08-16 14:41:06 +07:00
|
|
|
fix_imports_statements: {
|
|
|
|
$("script:not([src])").each((...[, element]) => {
|
2023-08-21 05:54:17 +02:00
|
|
|
const jsCode = $(element).html();
|
|
|
|
|
|
|
|
assert(jsCode !== null);
|
|
|
|
|
2024-01-27 18:49:29 +01:00
|
|
|
const { fixedJsCode } = replaceImportsFromStaticInJsCode({ jsCode, "bundler": "vite" });
|
2021-06-14 21:24:56 +02:00
|
|
|
|
2022-08-16 14:41:06 +07:00
|
|
|
$(element).text(fixedJsCode);
|
2021-06-14 21:24:56 +02:00
|
|
|
});
|
|
|
|
|
2022-08-16 14:41:06 +07:00
|
|
|
$("style").each((...[, element]) => {
|
2023-08-21 05:54:17 +02:00
|
|
|
const cssCode = $(element).html();
|
|
|
|
|
|
|
|
assert(cssCode !== null);
|
|
|
|
|
2022-08-16 14:41:06 +07:00
|
|
|
const { fixedCssCode } = replaceImportsInInlineCssCode({
|
2023-08-21 05:54:17 +02:00
|
|
|
cssCode,
|
2022-08-20 11:44:48 +07:00
|
|
|
buildOptions
|
2022-08-16 14:41:06 +07:00
|
|
|
});
|
2021-06-14 21:24:56 +02:00
|
|
|
|
2022-08-16 14:41:06 +07:00
|
|
|
$(element).text(fixedCssCode);
|
|
|
|
});
|
|
|
|
|
|
|
|
(
|
|
|
|
[
|
|
|
|
["link", "href"],
|
2022-08-20 11:44:48 +07:00
|
|
|
["script", "src"]
|
2022-08-16 14:41:06 +07:00
|
|
|
] as const
|
|
|
|
).forEach(([selector, attrName]) =>
|
|
|
|
$(selector).each((...[, element]) => {
|
|
|
|
const href = $(element).attr(attrName);
|
|
|
|
|
|
|
|
if (href === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$(element).attr(
|
|
|
|
attrName,
|
2023-08-21 05:54:17 +02:00
|
|
|
href.replace(new RegExp(`^${(buildOptions.urlPathname ?? "/").replace(/\//g, "\\/")}`), "${url.resourcesPath}/build/")
|
2022-08-16 14:41:06 +07:00
|
|
|
);
|
2022-08-20 11:44:48 +07:00
|
|
|
})
|
2022-08-16 14:41:06 +07:00
|
|
|
);
|
|
|
|
|
|
|
|
if (Object.keys(cssGlobalsToDefine).length !== 0) {
|
|
|
|
$("head").prepend(
|
|
|
|
[
|
|
|
|
"",
|
|
|
|
"<style>",
|
|
|
|
generateCssCodeToDefineGlobals({
|
|
|
|
cssGlobalsToDefine,
|
2022-08-20 11:44:48 +07:00
|
|
|
buildOptions
|
2022-08-16 14:41:06 +07:00
|
|
|
}).cssCodeToPrependInHead,
|
|
|
|
"</style>",
|
2022-08-20 11:44:48 +07:00
|
|
|
""
|
|
|
|
].join("\n")
|
2021-06-14 21:24:56 +02:00
|
|
|
);
|
2022-08-16 14:41:06 +07:00
|
|
|
}
|
|
|
|
}
|
2021-06-14 21:24:56 +02:00
|
|
|
|
|
|
|
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
2021-12-08 10:30:36 +03:00
|
|
|
const replaceValueBySearchValue = {
|
|
|
|
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': fs
|
|
|
|
.readFileSync(pathJoin(__dirname, "ftl_object_to_js_code_declaring_an_object.ftl"))
|
|
|
|
.toString("utf8")
|
2023-04-01 13:31:35 +02:00
|
|
|
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1]
|
2023-06-19 00:09:21 +02:00
|
|
|
.replace("FIELD_NAMES_eKsIY4ZsZ4xeM", fieldNames.map(name => `"${name}"`).join(", "))
|
2023-04-06 16:38:13 +02:00
|
|
|
.replace("KEYCLOAKIFY_VERSION_xEdKd3xEdr", keycloakifyVersion)
|
2023-04-27 11:52:02 +02:00
|
|
|
.replace("KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx", buildOptions.themeVersion)
|
2023-06-08 23:09:14 +02:00
|
|
|
.replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType)
|
2023-09-04 01:19:21 +02:00
|
|
|
.replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", themeName),
|
2021-10-11 21:35:40 +02:00
|
|
|
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
|
|
|
|
"<#if scripts??>",
|
|
|
|
" <#list scripts as script>",
|
|
|
|
' <script src="${script}" type="text/javascript"></script>',
|
|
|
|
" </#list>",
|
2022-08-20 11:44:48 +07:00
|
|
|
"</#if>"
|
|
|
|
].join("\n")
|
2021-06-14 21:24:56 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
$("head").prepend(
|
|
|
|
[
|
2021-06-22 12:37:21 +02:00
|
|
|
"<script>",
|
2021-12-08 10:30:36 +03:00
|
|
|
` window.${ftlValuesGlobalName}= ${objectKeys(replaceValueBySearchValue)[0]};`,
|
2021-10-11 21:35:40 +02:00
|
|
|
"</script>",
|
|
|
|
"",
|
2022-08-20 11:44:48 +07:00
|
|
|
objectKeys(replaceValueBySearchValue)[1]
|
|
|
|
].join("\n")
|
2021-06-14 21:24:56 +02:00
|
|
|
);
|
|
|
|
|
2023-11-19 03:27:40 +01:00
|
|
|
// Remove part of the document marked as ignored.
|
|
|
|
{
|
|
|
|
const startTags = $('meta[name="keycloakify-ignore-start"]');
|
|
|
|
|
|
|
|
startTags.each((...[, startTag]) => {
|
|
|
|
const $startTag = $(startTag);
|
|
|
|
const $endTag = $startTag.nextAll('meta[name="keycloakify-ignore-end"]').first();
|
|
|
|
|
|
|
|
if ($endTag.length) {
|
|
|
|
let currentNode = $startTag.next();
|
|
|
|
while (currentNode.length && !currentNode.is($endTag)) {
|
|
|
|
currentNode.remove();
|
|
|
|
currentNode = $startTag.next();
|
|
|
|
}
|
|
|
|
|
|
|
|
$startTag.remove();
|
|
|
|
$endTag.remove();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-06-14 21:24:56 +02:00
|
|
|
const partiallyFixedIndexHtmlCode = $.html();
|
|
|
|
|
2021-10-11 21:35:40 +02:00
|
|
|
function generateFtlFilesCode(params: { pageId: string }): {
|
|
|
|
ftlCode: string;
|
|
|
|
} {
|
2021-06-14 21:24:56 +02:00
|
|
|
const { pageId } = params;
|
|
|
|
|
|
|
|
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
|
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
let ftlCode = $.html();
|
|
|
|
|
|
|
|
Object.entries({
|
|
|
|
...replaceValueBySearchValue,
|
2022-08-20 11:44:48 +07:00
|
|
|
"PAGE_ID_xIgLsPgGId9D8e": pageId
|
2021-12-08 10:30:36 +03:00
|
|
|
}).map(([searchValue, replaceValue]) => (ftlCode = ftlCode.replace(searchValue, replaceValue)));
|
2021-06-14 21:24:56 +02:00
|
|
|
|
|
|
|
return { ftlCode };
|
|
|
|
}
|
|
|
|
|
|
|
|
return { generateFtlFilesCode };
|
2021-10-11 21:35:40 +02:00
|
|
|
}
|