keycloak_theme/src/vite-plugin/vite-plugin.ts

129 lines
4.8 KiB
TypeScript
Raw Normal View History

2024-01-30 05:54:36 +01:00
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
2024-01-30 06:55:26 +01:00
import { readParsedPackageJson } from "../bin/keycloakify/buildOptions/parsedPackageJson";
2024-01-30 00:06:17 +01:00
import type { Plugin } from "vite";
import { assert } from "tsafe/assert";
2024-01-27 18:49:29 +01:00
import * as fs from "fs";
import { resolvedViteConfigJsonBasename, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, keycloak_resources } from "../bin/constants";
2024-01-30 06:55:26 +01:00
import type { ResolvedViteConfig } from "../bin/keycloakify/buildOptions/resolvedViteConfig";
import { getKeycloakifyBuildDirPath } from "../bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath";
2024-01-30 00:06:17 +01:00
import { replaceAll } from "../bin/tools/String.prototype.replaceAll";
2024-01-30 05:54:36 +01:00
import { id } from "tsafe/id";
import { rm } from "../bin/tools/fs.rm";
2024-01-27 18:49:29 +01:00
export function keycloakify(): Plugin {
2024-01-30 05:54:36 +01:00
let reactAppRootDirPath: string | undefined = undefined;
let urlPathname: string | undefined = undefined;
let buildDirPath: string | undefined = undefined;
2024-01-27 18:49:29 +01:00
return {
"name": "keycloakify",
"apply": "build",
2024-01-27 18:49:29 +01:00
"configResolved": resolvedConfig => {
2024-01-30 05:54:36 +01:00
reactAppRootDirPath = resolvedConfig.root;
urlPathname = (() => {
let out = resolvedConfig.env.BASE_URL;
2024-01-30 00:06:17 +01:00
2024-01-30 05:54:36 +01:00
if (out === undefined) {
return undefined;
}
2024-01-30 00:06:17 +01:00
2024-01-30 05:54:36 +01:00
if (!out.startsWith("/")) {
out = "/" + out;
}
2024-01-30 00:06:17 +01:00
2024-01-30 05:54:36 +01:00
if (!out.endsWith("/")) {
out += "/";
2024-01-30 00:06:17 +01:00
}
2024-01-27 18:49:29 +01:00
2024-01-30 05:54:36 +01:00
return out;
2024-01-30 00:06:17 +01:00
})();
2024-01-27 18:49:29 +01:00
buildDirPath = pathJoin(reactAppRootDirPath, resolvedConfig.build.outDir);
2024-01-30 05:54:36 +01:00
const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({
2024-01-30 06:55:26 +01:00
"parsedPackageJson_keycloakify_keycloakifyBuildDirPath": readParsedPackageJson({ reactAppRootDirPath }).keycloakify
2024-01-30 05:54:36 +01:00
?.keycloakifyBuildDirPath,
reactAppRootDirPath,
"bundler": "vite"
});
2024-01-30 00:06:17 +01:00
if (!fs.existsSync(keycloakifyBuildDirPath)) {
fs.mkdirSync(keycloakifyBuildDirPath);
}
fs.writeFileSync(
2024-01-30 06:04:05 +01:00
pathJoin(keycloakifyBuildDirPath, resolvedViteConfigJsonBasename),
2024-01-30 05:54:36 +01:00
Buffer.from(
JSON.stringify(
2024-01-30 06:04:05 +01:00
id<ResolvedViteConfig>({
2024-01-30 05:54:36 +01:00
"publicDir": pathRelative(reactAppRootDirPath, resolvedConfig.publicDir),
"assetsDir": resolvedConfig.build.assetsDir,
"buildDir": resolvedConfig.build.outDir,
urlPathname
}),
null,
2
),
"utf8"
)
2024-01-30 00:06:17 +01:00
);
2024-01-27 18:49:29 +01:00
},
2024-01-30 00:06:17 +01:00
"transform": (code, id) => {
2024-01-30 05:54:36 +01:00
assert(reactAppRootDirPath !== undefined);
2024-01-27 18:49:29 +01:00
2024-01-30 00:06:17 +01:00
let transformedCode: string | undefined = undefined;
replace_import_meta_env_base_url_in_source_code: {
{
2024-01-30 05:54:36 +01:00
const isWithinSourceDirectory = id.startsWith(pathJoin(reactAppRootDirPath, "src") + pathSep);
2024-01-30 00:06:17 +01:00
if (!isWithinSourceDirectory) {
break replace_import_meta_env_base_url_in_source_code;
}
}
const isJavascriptFile = id.endsWith(".js") || id.endsWith(".jsx");
{
const isTypeScriptFile = id.endsWith(".ts") || id.endsWith(".tsx");
2024-01-27 18:49:29 +01:00
2024-01-30 00:06:17 +01:00
if (!isTypeScriptFile && !isJavascriptFile) {
break replace_import_meta_env_base_url_in_source_code;
}
}
const windowToken = isJavascriptFile ? "window" : "(window as any)";
if (transformedCode === undefined) {
transformedCode = code;
}
transformedCode = replaceAll(
transformedCode,
"import.meta.env.BASE_URL",
[
`(`,
`(${windowToken}.${nameOfTheGlobal} === undefined || import.meta.env.MODE === "development") ?`,
2024-01-30 05:54:36 +01:00
` "${urlPathname ?? "/"}" :`,
2024-01-30 00:06:17 +01:00
` \`\${${windowToken}.${nameOfTheGlobal}.url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/\``,
`)`
].join("")
);
}
2024-01-30 05:54:36 +01:00
if (transformedCode === undefined) {
return;
2024-01-30 00:06:17 +01:00
}
2024-01-30 05:54:36 +01:00
return {
"code": transformedCode
};
},
"buildEnd": async () => {
assert(buildDirPath !== undefined);
await rm(pathJoin(buildDirPath, keycloak_resources), { "recursive": true, "force": true });
2024-01-30 00:06:17 +01:00
}
2024-01-27 18:49:29 +01:00
};
}