Build the app when running npx keycloak start-keycloak
This commit is contained in:
128
src/bin/start-keycloak/appBuild.ts
Normal file
128
src/bin/start-keycloak/appBuild.ts
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import * as child_process from "child_process";
|
||||||
|
import { Deferred } from "evt/tools/Deferred";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import { is } from "tsafe/is";
|
||||||
|
import type { BuildOptions } from "../shared/buildOptions";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
|
||||||
|
export type BuildOptionsLike = {
|
||||||
|
reactAppRootDirPath: string;
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
bundler: "vite" | "webpack";
|
||||||
|
npmWorkspaceRootDirPath: string;
|
||||||
|
reactAppBuildDirPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
||||||
|
|
||||||
|
export async function appBuild(params: {
|
||||||
|
doSkipIfReactAppBuildDirExists: boolean;
|
||||||
|
buildOptions: BuildOptionsLike;
|
||||||
|
}): Promise<{ isAppBuildSuccess: boolean }> {
|
||||||
|
const { doSkipIfReactAppBuildDirExists, buildOptions } = params;
|
||||||
|
|
||||||
|
if (
|
||||||
|
doSkipIfReactAppBuildDirExists &&
|
||||||
|
fs.existsSync(buildOptions.reactAppBuildDirPath)
|
||||||
|
) {
|
||||||
|
return { isAppBuildSuccess: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { bundler } = buildOptions;
|
||||||
|
|
||||||
|
const { command, args, cwd } = (() => {
|
||||||
|
switch (bundler) {
|
||||||
|
case "vite":
|
||||||
|
return {
|
||||||
|
command: "npx",
|
||||||
|
args: ["vite", "build"],
|
||||||
|
cwd: buildOptions.reactAppRootDirPath
|
||||||
|
};
|
||||||
|
case "webpack": {
|
||||||
|
for (const dirPath of [
|
||||||
|
buildOptions.reactAppRootDirPath,
|
||||||
|
buildOptions.npmWorkspaceRootDirPath
|
||||||
|
]) {
|
||||||
|
try {
|
||||||
|
const parsedPackageJson = JSON.parse(
|
||||||
|
fs
|
||||||
|
.readFileSync(pathJoin(dirPath, "package.json"))
|
||||||
|
.toString("utf8")
|
||||||
|
);
|
||||||
|
|
||||||
|
const [scriptName] =
|
||||||
|
Object.entries(parsedPackageJson.scripts).find(
|
||||||
|
([, scriptValue]) => {
|
||||||
|
assert(is<string>(scriptValue));
|
||||||
|
if (
|
||||||
|
scriptValue.includes("webpack") &&
|
||||||
|
scriptValue.includes("--mode production")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
scriptValue.includes("react-scripts") &&
|
||||||
|
scriptValue.includes("build")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
scriptValue.includes("react-app-rewired") &&
|
||||||
|
scriptValue.includes("build")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
scriptValue.includes("craco") &&
|
||||||
|
scriptValue.includes("build")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) ?? [];
|
||||||
|
|
||||||
|
if (scriptName === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
command: "npm",
|
||||||
|
args: ["run", scriptName],
|
||||||
|
cwd: dirPath
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
"Keycloakify was unable to determine which script is responsible for building the app."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
const dResult = new Deferred<{ isSuccess: boolean }>();
|
||||||
|
|
||||||
|
const child = child_process.spawn(command, args, { cwd });
|
||||||
|
|
||||||
|
child.stdout.on("data", data => {
|
||||||
|
if (data.toString("utf8").includes("gzip:")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.stdout.write(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stderr.on("data", data => process.stderr.write(data));
|
||||||
|
|
||||||
|
child.on("exit", code => dResult.resolve({ isSuccess: code === 0 }));
|
||||||
|
|
||||||
|
const { isSuccess } = await dResult.pr;
|
||||||
|
|
||||||
|
return { isAppBuildSuccess: isSuccess };
|
||||||
|
}
|
51
src/bin/start-keycloak/keycloakifyBuild.ts
Normal file
51
src/bin/start-keycloak/keycloakifyBuild.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { skipBuildJarsEnvName } from "../shared/constants";
|
||||||
|
import * as child_process from "child_process";
|
||||||
|
import chalk from "chalk";
|
||||||
|
import { Deferred } from "evt/tools/Deferred";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import type { BuildOptions } from "../shared/buildOptions";
|
||||||
|
|
||||||
|
export type BuildOptionsLike = {
|
||||||
|
reactAppRootDirPath: string;
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
bundler: "vite" | "webpack";
|
||||||
|
npmWorkspaceRootDirPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
||||||
|
|
||||||
|
export async function keycloakifyBuild(params: {
|
||||||
|
doSkipBuildJars: boolean;
|
||||||
|
buildOptions: BuildOptionsLike;
|
||||||
|
}): Promise<{ isKeycloakifyBuildSuccess: boolean }> {
|
||||||
|
const { buildOptions, doSkipBuildJars } = params;
|
||||||
|
|
||||||
|
const dResult = new Deferred<{ isSuccess: boolean }>();
|
||||||
|
|
||||||
|
const child = child_process.spawn("npx", ["keycloakify", "build"], {
|
||||||
|
cwd: buildOptions.reactAppRootDirPath,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
...(doSkipBuildJars ? {} : { [skipBuildJarsEnvName]: "true" })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stdout.on("data", data => process.stdout.write(data));
|
||||||
|
|
||||||
|
child.stderr.on("data", data => process.stderr.write(data));
|
||||||
|
|
||||||
|
child.on("exit", code => {
|
||||||
|
if (code !== 0) {
|
||||||
|
console.log(chalk.yellow("Theme not updated, build failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(chalk.green("Rebuild done"));
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on("exit", code => dResult.resolve({ isSuccess: code === 0 }));
|
||||||
|
|
||||||
|
const { isSuccess } = await dResult.pr;
|
||||||
|
|
||||||
|
return { isKeycloakifyBuildSuccess: isSuccess };
|
||||||
|
}
|
Reference in New Issue
Block a user