Enable to provide the configuration to the Vite plugin, enable user to provide a post build script #148
This commit is contained in:
parent
69936750d5
commit
ae757ee371
@ -10,3 +10,5 @@ export const retrocompatPostfix = "_retrocompat";
|
||||
export const accountV1ThemeName = "account-v1";
|
||||
|
||||
export type ThemeType = (typeof themeTypes)[number];
|
||||
|
||||
export const keycloakifyBuildOptionsForPostPostBuildScriptEnvName = "KEYCLOAKIFY_BUILD_OPTIONS_POST_POST_BUILD_SCRIPT";
|
||||
|
25
src/bin/keycloakify/buildOptions/UserProvidedBuildOptions.ts
Normal file
25
src/bin/keycloakify/buildOptions/UserProvidedBuildOptions.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export type UserProvidedBuildOptions = {
|
||||
extraThemeProperties?: string[];
|
||||
artifactId?: string;
|
||||
groupId?: string;
|
||||
doCreateJar?: boolean;
|
||||
loginThemeResourcesFromKeycloakVersion?: string;
|
||||
reactAppBuildDirPath?: string;
|
||||
keycloakifyBuildDirPath?: string;
|
||||
themeName?: string | string[];
|
||||
doBuildRetrocompatAccountTheme?: boolean;
|
||||
};
|
||||
|
||||
export const zUserProvidedBuildOptions = z.object({
|
||||
"extraThemeProperties": z.array(z.string()).optional(),
|
||||
"artifactId": z.string().optional(),
|
||||
"groupId": z.string().optional(),
|
||||
"doCreateJar": z.boolean().optional(),
|
||||
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
||||
"reactAppBuildDirPath": z.string().optional(),
|
||||
"keycloakifyBuildDirPath": z.string().optional(),
|
||||
"themeName": z.union([z.string(), z.array(z.string())]).optional(),
|
||||
"doBuildRetrocompatAccountTheme": z.boolean().optional()
|
||||
});
|
@ -47,10 +47,15 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
throw new Error("Keycloakify's Vite plugin output not found");
|
||||
}
|
||||
|
||||
const parsedPackageJson = readParsedPackageJson({ reactAppRootDirPath });
|
||||
const { keycloakify: userProvidedBuildOptionsFromPackageJson, ...parsedPackageJson } = readParsedPackageJson({ reactAppRootDirPath });
|
||||
|
||||
const userProvidedBuildOptions = {
|
||||
...userProvidedBuildOptionsFromPackageJson,
|
||||
...resolvedViteConfig?.userProvidedBuildOptions
|
||||
};
|
||||
|
||||
const themeNames = (() => {
|
||||
if (parsedPackageJson.keycloakify?.themeName === undefined) {
|
||||
if (userProvidedBuildOptions.themeName === undefined) {
|
||||
return [
|
||||
parsedPackageJson.name
|
||||
.replace(/^@(.*)/, "$1")
|
||||
@ -59,11 +64,11 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
];
|
||||
}
|
||||
|
||||
if (typeof parsedPackageJson.keycloakify.themeName === "string") {
|
||||
return [parsedPackageJson.keycloakify.themeName];
|
||||
if (typeof userProvidedBuildOptions.themeName === "string") {
|
||||
return [userProvidedBuildOptions.themeName];
|
||||
}
|
||||
|
||||
return parsedPackageJson.keycloakify.themeName;
|
||||
return userProvidedBuildOptions.themeName;
|
||||
})();
|
||||
|
||||
const reactAppBuildDirPath = (() => {
|
||||
@ -72,9 +77,9 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
break webpack;
|
||||
}
|
||||
|
||||
if (parsedPackageJson.keycloakify?.reactAppBuildDirPath !== undefined) {
|
||||
if (userProvidedBuildOptions.reactAppBuildDirPath !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": parsedPackageJson.keycloakify?.reactAppBuildDirPath,
|
||||
"pathIsh": userProvidedBuildOptions.reactAppBuildDirPath,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
@ -94,13 +99,13 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
"isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
||||
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
|
||||
themeNames,
|
||||
"extraThemeProperties": parsedPackageJson.keycloakify?.extraThemeProperties,
|
||||
"extraThemeProperties": userProvidedBuildOptions.extraThemeProperties,
|
||||
"groupId": (() => {
|
||||
const fallbackGroupId = `${themeNames[0]}.keycloak`;
|
||||
|
||||
return (
|
||||
process.env.KEYCLOAKIFY_GROUP_ID ??
|
||||
parsedPackageJson.keycloakify?.groupId ??
|
||||
userProvidedBuildOptions.groupId ??
|
||||
(parsedPackageJson.homepage === undefined
|
||||
? fallbackGroupId
|
||||
: urlParse(parsedPackageJson.homepage)
|
||||
@ -110,15 +115,15 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
.join(".") ?? fallbackGroupId) + ".keycloak"
|
||||
);
|
||||
})(),
|
||||
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? parsedPackageJson.keycloakify?.artifactId ?? `${themeNames[0]}-keycloak-theme`,
|
||||
"doCreateJar": parsedPackageJson.keycloakify?.doCreateJar ?? true,
|
||||
"loginThemeResourcesFromKeycloakVersion": parsedPackageJson.keycloakify?.loginThemeResourcesFromKeycloakVersion ?? "11.0.3",
|
||||
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? userProvidedBuildOptions.artifactId ?? `${themeNames[0]}-keycloak-theme`,
|
||||
"doCreateJar": userProvidedBuildOptions.doCreateJar ?? true,
|
||||
"loginThemeResourcesFromKeycloakVersion": userProvidedBuildOptions.loginThemeResourcesFromKeycloakVersion ?? "11.0.3",
|
||||
reactAppRootDirPath,
|
||||
reactAppBuildDirPath,
|
||||
"keycloakifyBuildDirPath": (() => {
|
||||
if (parsedPackageJson.keycloakify?.keycloakifyBuildDirPath !== undefined) {
|
||||
if (userProvidedBuildOptions.keycloakifyBuildDirPath !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
|
||||
"pathIsh": userProvidedBuildOptions.keycloakifyBuildDirPath,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
@ -179,7 +184,7 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
||||
|
||||
return pathJoin(reactAppBuildDirPath, resolvedViteConfig.assetsDir);
|
||||
})(),
|
||||
"doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true,
|
||||
"doBuildRetrocompatAccountTheme": userProvidedBuildOptions.doBuildRetrocompatAccountTheme ?? true,
|
||||
npmWorkspaceRootDirPath
|
||||
};
|
||||
}
|
||||
|
@ -3,41 +3,20 @@ import { assert } from "tsafe";
|
||||
import type { Equals } from "tsafe";
|
||||
import { z } from "zod";
|
||||
import { join as pathJoin } from "path";
|
||||
import { type UserProvidedBuildOptions, zUserProvidedBuildOptions } from "./UserProvidedBuildOptions";
|
||||
|
||||
export type ParsedPackageJson = {
|
||||
name: string;
|
||||
version?: string;
|
||||
homepage?: string;
|
||||
keycloakify?: {
|
||||
extraThemeProperties?: string[];
|
||||
artifactId?: string;
|
||||
groupId?: string;
|
||||
doCreateJar?: boolean;
|
||||
loginThemeResourcesFromKeycloakVersion?: string;
|
||||
reactAppBuildDirPath?: string;
|
||||
keycloakifyBuildDirPath?: string;
|
||||
themeName?: string | string[];
|
||||
doBuildRetrocompatAccountTheme?: boolean;
|
||||
};
|
||||
keycloakify?: UserProvidedBuildOptions;
|
||||
};
|
||||
|
||||
const zParsedPackageJson = z.object({
|
||||
"name": z.string(),
|
||||
"version": z.string().optional(),
|
||||
"homepage": z.string().optional(),
|
||||
"keycloakify": z
|
||||
.object({
|
||||
"extraThemeProperties": z.array(z.string()).optional(),
|
||||
"artifactId": z.string().optional(),
|
||||
"groupId": z.string().optional(),
|
||||
"doCreateJar": z.boolean().optional(),
|
||||
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
||||
"reactAppBuildDirPath": z.string().optional(),
|
||||
"keycloakifyBuildDirPath": z.string().optional(),
|
||||
"themeName": z.union([z.string(), z.array(z.string())]).optional(),
|
||||
"doBuildRetrocompatAccountTheme": z.boolean().optional()
|
||||
})
|
||||
.optional()
|
||||
"keycloakify": zUserProvidedBuildOptions.optional()
|
||||
});
|
||||
|
||||
assert<Equals<ReturnType<(typeof zParsedPackageJson)["parse"]>, ParsedPackageJson>>();
|
||||
|
@ -5,19 +5,22 @@ import { z } from "zod";
|
||||
import { join as pathJoin } from "path";
|
||||
import { resolvedViteConfigJsonBasename } from "../../constants";
|
||||
import type { OptionalIfCanBeUndefined } from "../../tools/OptionalIfCanBeUndefined";
|
||||
import { UserProvidedBuildOptions, zUserProvidedBuildOptions } from "./UserProvidedBuildOptions";
|
||||
|
||||
export type ResolvedViteConfig = {
|
||||
buildDir: string;
|
||||
publicDir: string;
|
||||
assetsDir: string;
|
||||
urlPathname: string | undefined;
|
||||
userProvidedBuildOptions: UserProvidedBuildOptions;
|
||||
};
|
||||
|
||||
const zResolvedViteConfig = z.object({
|
||||
"buildDir": z.string(),
|
||||
"publicDir": z.string(),
|
||||
"assetsDir": z.string(),
|
||||
"urlPathname": z.string().optional()
|
||||
"urlPathname": z.string().optional(),
|
||||
"userProvidedBuildOptions": zUserProvidedBuildOptions
|
||||
});
|
||||
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ import { getLogger } from "../tools/logger";
|
||||
import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
||||
|
||||
export async function main() {
|
||||
const buildOptions = readBuildOptions({
|
||||
@ -36,9 +37,30 @@ export async function main() {
|
||||
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
||||
}
|
||||
|
||||
const containerKeycloakVersion = "23.0.6";
|
||||
|
||||
const jarFilePath = pathJoin(buildOptions.keycloakifyBuildDirPath, "target", `${buildOptions.artifactId}-${buildOptions.themeVersion}.jar`);
|
||||
|
||||
if (buildOptions.doCreateJar) {
|
||||
generateStartKeycloakTestingContainer({
|
||||
"keycloakVersion": containerKeycloakVersion,
|
||||
jarFilePath,
|
||||
buildOptions
|
||||
});
|
||||
|
||||
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
||||
|
||||
child_process.execSync("npx vite", {
|
||||
"env": {
|
||||
...process.env,
|
||||
[keycloakifyBuildOptionsForPostPostBuildScriptEnvName]: JSON.stringify(buildOptions)
|
||||
}
|
||||
});
|
||||
|
||||
create_jar: {
|
||||
if (!buildOptions.doCreateJar) {
|
||||
break create_jar;
|
||||
}
|
||||
|
||||
child_process.execSync("mvn clean install", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
||||
|
||||
const jarDirPath = pathDirname(jarFilePath);
|
||||
@ -59,16 +81,6 @@ export async function main() {
|
||||
);
|
||||
}
|
||||
|
||||
const containerKeycloakVersion = "23.0.6";
|
||||
|
||||
generateStartKeycloakTestingContainer({
|
||||
"keycloakVersion": containerKeycloakVersion,
|
||||
jarFilePath,
|
||||
buildOptions
|
||||
});
|
||||
|
||||
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
||||
|
||||
logger.log(
|
||||
[
|
||||
"",
|
||||
|
@ -1,7 +1,13 @@
|
||||
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
|
||||
import type { Plugin } from "vite";
|
||||
import * as fs from "fs";
|
||||
import { resolvedViteConfigJsonBasename, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, keycloak_resources } from "../bin/constants";
|
||||
import {
|
||||
resolvedViteConfigJsonBasename,
|
||||
nameOfTheGlobal,
|
||||
basenameOfTheKeycloakifyResourcesDir,
|
||||
keycloak_resources,
|
||||
keycloakifyBuildOptionsForPostPostBuildScriptEnvName
|
||||
} from "../bin/constants";
|
||||
import type { ResolvedViteConfig } from "../bin/keycloakify/buildOptions/resolvedViteConfig";
|
||||
import { getCacheDirPath } from "../bin/keycloakify/buildOptions/getCacheDirPath";
|
||||
import { replaceAll } from "../bin/tools/String.prototype.replaceAll";
|
||||
@ -9,8 +15,16 @@ import { id } from "tsafe/id";
|
||||
import { rm } from "../bin/tools/fs.rm";
|
||||
import { copyKeycloakResourcesToPublic } from "../bin/copy-keycloak-resources-to-public";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../bin/keycloakify/buildOptions";
|
||||
import type { UserProvidedBuildOptions } from "../bin/keycloakify/buildOptions/UserProvidedBuildOptions";
|
||||
|
||||
export type Params = UserProvidedBuildOptions & {
|
||||
postBuildScript?: (buildOptions: Omit<BuildOptions, "bundler">) => Promise<void>;
|
||||
};
|
||||
|
||||
export function keycloakify(params: Params) {
|
||||
const { postBuildScript, ...userProvidedBuildOptions } = params;
|
||||
|
||||
export function keycloakify() {
|
||||
let reactAppRootDirPath: string | undefined = undefined;
|
||||
let urlPathname: string | undefined = undefined;
|
||||
let buildDirPath: string | undefined = undefined;
|
||||
@ -19,6 +33,24 @@ export function keycloakify() {
|
||||
const plugin = {
|
||||
"name": "keycloakify" as const,
|
||||
"configResolved": async resolvedConfig => {
|
||||
run_post_build_script: {
|
||||
const buildOptionJson = process.env[keycloakifyBuildOptionsForPostPostBuildScriptEnvName];
|
||||
|
||||
if (buildOptionJson === undefined) {
|
||||
break run_post_build_script;
|
||||
}
|
||||
|
||||
if (params.postBuildScript === undefined) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const buildOptions: BuildOptions = JSON.parse(buildOptionJson);
|
||||
|
||||
await params.postBuildScript(buildOptions);
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
command = resolvedConfig.command;
|
||||
|
||||
reactAppRootDirPath = resolvedConfig.root;
|
||||
@ -67,7 +99,8 @@ export function keycloakify() {
|
||||
"publicDir": pathRelative(reactAppRootDirPath, resolvedConfig.publicDir),
|
||||
"assetsDir": resolvedConfig.build.assetsDir,
|
||||
"buildDir": resolvedConfig.build.outDir,
|
||||
urlPathname
|
||||
urlPathname,
|
||||
userProvidedBuildOptions
|
||||
}),
|
||||
null,
|
||||
2
|
||||
|
Loading…
x
Reference in New Issue
Block a user