148 lines
4.9 KiB
TypeScript
Raw Normal View History

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";
import * as fs from "fs";
import { join as pathJoin } from "path";
import { objectKeys } from "tsafe/objectKeys";
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
2022-08-16 14:41:06 +07:00
import type { BuildOptions } from "../BuildOptions";
import { assert } from "tsafe/assert";
export const themeTypes = ["login", "account"] as const;
export type ThemeType = (typeof themeTypes)[number];
2023-08-21 05:54:17 +02:00
export type BuildOptionsLike = {
themeName: string;
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
export function generateFtlFilesCodeFactory(params: {
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;
keycloakifyVersion: string;
2023-04-27 11:52:02 +02:00
themeType: ThemeType;
fieldNames: string[];
}) {
const { cssGlobalsToDefine, indexHtmlCode, buildOptions, keycloakifyVersion, themeType, fieldNames } = params;
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);
const { fixedJsCode } = replaceImportsFromStaticInJsCode({ jsCode });
2022-08-16 14:41:06 +07:00
$(element).text(fixedJsCode);
});
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,
buildOptions
2022-08-16 14:41:06 +07:00
});
2022-08-16 14:41:06 +07:00
$(element).text(fixedCssCode);
});
(
[
["link", "href"],
["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-16 14:41:06 +07:00
);
if (Object.keys(cssGlobalsToDefine).length !== 0) {
$("head").prepend(
[
"",
"<style>",
generateCssCodeToDefineGlobals({
cssGlobalsToDefine,
buildOptions
2022-08-16 14:41:06 +07:00
}).cssCodeToPrependInHead,
"</style>",
""
].join("\n")
);
2022-08-16 14:41:06 +07:00
}
}
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
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]
.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)
.replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", buildOptions.themeName),
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
"<#if scripts??>",
" <#list scripts as script>",
' <script src="${script}" type="text/javascript"></script>',
" </#list>",
"</#if>"
].join("\n")
};
$("head").prepend(
[
"<script>",
` window.${ftlValuesGlobalName}= ${objectKeys(replaceValueBySearchValue)[0]};`,
"</script>",
"",
objectKeys(replaceValueBySearchValue)[1]
].join("\n")
);
const partiallyFixedIndexHtmlCode = $.html();
function generateFtlFilesCode(params: { pageId: string }): {
ftlCode: string;
} {
const { pageId } = params;
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
let ftlCode = $.html();
Object.entries({
...replaceValueBySearchValue,
"PAGE_ID_xIgLsPgGId9D8e": pageId
}).map(([searchValue, replaceValue]) => (ftlCode = ftlCode.replace(searchValue, replaceValue)));
return { ftlCode };
}
return { generateFtlFilesCode };
}