2022-08-16 14:41:06 +07:00
|
|
|
import { assert } from "tsafe/assert";
|
|
|
|
import { id } from "tsafe/id";
|
|
|
|
import { parse as urlParse } from "url";
|
2023-02-04 17:44:02 +01:00
|
|
|
import { typeGuard } from "tsafe/typeGuard";
|
2023-02-04 18:02:39 +01:00
|
|
|
import { symToStr } from "tsafe/symToStr";
|
2023-04-01 14:02:32 +02:00
|
|
|
import { bundlers, getParsedPackageJson, type Bundler } from "./parsedPackageJson";
|
2023-04-02 03:10:16 +02:00
|
|
|
import { join as pathJoin, sep as pathSep } from "path";
|
2023-04-19 05:04:11 +02:00
|
|
|
import parseArgv from "minimist";
|
2022-08-16 14:41:06 +07:00
|
|
|
|
|
|
|
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
2023-08-21 05:54:17 +02:00
|
|
|
export type BuildOptions = {
|
|
|
|
isSilent: boolean;
|
|
|
|
themeVersion: string;
|
|
|
|
themeName: string;
|
|
|
|
extraThemeNames: string[];
|
|
|
|
extraThemeProperties: string[] | undefined;
|
|
|
|
groupId: string;
|
|
|
|
artifactId: string;
|
|
|
|
bundler: Bundler;
|
2023-09-03 07:14:57 +02:00
|
|
|
loginThemeDefaultResourcesFromKeycloakVersion: string;
|
2023-08-21 05:54:17 +02:00
|
|
|
/** Directory of your built react project. Defaults to {cwd}/build */
|
|
|
|
reactAppBuildDirPath: string;
|
|
|
|
/** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
|
|
|
|
keycloakifyBuildDirPath: string;
|
|
|
|
/** If your app is hosted under a subpath, it's the case in CRA if you have "homepage": "https://example.com/my-app" in your package.json
|
|
|
|
* In this case the urlPathname will be "/my-app/" */
|
|
|
|
urlPathname: string | undefined;
|
|
|
|
};
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-04-19 05:04:11 +02:00
|
|
|
export function readBuildOptions(params: { projectDirPath: string; processArgv: string[] }): BuildOptions {
|
|
|
|
const { projectDirPath, processArgv } = params;
|
2023-04-18 03:10:29 +02:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
const { isSilentCliParamProvided } = (() => {
|
2023-04-19 05:04:11 +02:00
|
|
|
const argv = parseArgv(processArgv);
|
|
|
|
|
|
|
|
return {
|
2023-08-21 05:54:17 +02:00
|
|
|
"isSilentCliParamProvided": typeof argv["silent"] === "boolean" ? argv["silent"] : false
|
2023-04-19 05:04:11 +02:00
|
|
|
};
|
|
|
|
})();
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-04-02 03:10:16 +02:00
|
|
|
const parsedPackageJson = getParsedPackageJson({ projectDirPath });
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
const { name, keycloakify = {}, version, homepage } = parsedPackageJson;
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-09-03 07:14:57 +02:00
|
|
|
const {
|
|
|
|
extraThemeProperties,
|
|
|
|
groupId,
|
|
|
|
artifactId,
|
|
|
|
bundler,
|
|
|
|
keycloakVersionDefaultAssets,
|
|
|
|
loginThemeDefaultResourcesFromKeycloakVersion,
|
|
|
|
extraThemeNames = []
|
|
|
|
} = keycloakify ?? {};
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
const themeName =
|
|
|
|
keycloakify.themeName ??
|
|
|
|
name
|
|
|
|
.replace(/^@(.*)/, "$1")
|
|
|
|
.split("/")
|
|
|
|
.join("-");
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
return {
|
|
|
|
themeName,
|
|
|
|
extraThemeNames,
|
|
|
|
"bundler": (() => {
|
|
|
|
const { KEYCLOAKIFY_BUNDLER } = process.env;
|
2023-04-02 03:10:16 +02:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
assert(
|
|
|
|
typeGuard<Bundler | undefined>(KEYCLOAKIFY_BUNDLER, [undefined, ...id<readonly string[]>(bundlers)].includes(KEYCLOAKIFY_BUNDLER)),
|
|
|
|
`${symToStr({ KEYCLOAKIFY_BUNDLER })} should be one of ${bundlers.join(", ")}`
|
|
|
|
);
|
|
|
|
|
|
|
|
return KEYCLOAKIFY_BUNDLER ?? bundler ?? "keycloakify";
|
|
|
|
})(),
|
|
|
|
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? artifactId ?? `${themeName}-keycloak-theme`,
|
|
|
|
"groupId": (() => {
|
|
|
|
const fallbackGroupId = `${themeName}.keycloak`;
|
|
|
|
|
|
|
|
return (
|
|
|
|
process.env.KEYCLOAKIFY_GROUP_ID ??
|
|
|
|
groupId ??
|
|
|
|
(!homepage
|
|
|
|
? fallbackGroupId
|
|
|
|
: urlParse(homepage)
|
|
|
|
.host?.replace(/:[0-9]+$/, "")
|
|
|
|
?.split(".")
|
|
|
|
.reverse()
|
|
|
|
.join(".") ?? fallbackGroupId) + ".keycloak"
|
|
|
|
);
|
|
|
|
})(),
|
|
|
|
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? process.env.KEYCLOAKIFY_VERSION ?? version ?? "0.0.0",
|
|
|
|
extraThemeProperties,
|
|
|
|
"isSilent": isSilentCliParamProvided,
|
2023-09-03 07:14:57 +02:00
|
|
|
"loginThemeDefaultResourcesFromKeycloakVersion": loginThemeDefaultResourcesFromKeycloakVersion ?? keycloakVersionDefaultAssets ?? "11.0.3",
|
2023-08-21 05:54:17 +02:00
|
|
|
"reactAppBuildDirPath": (() => {
|
|
|
|
let { reactAppBuildDirPath = undefined } = parsedPackageJson.keycloakify ?? {};
|
|
|
|
|
|
|
|
if (reactAppBuildDirPath === undefined) {
|
|
|
|
return pathJoin(projectDirPath, "build");
|
2023-04-02 03:10:16 +02:00
|
|
|
}
|
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (pathSep === "\\") {
|
|
|
|
reactAppBuildDirPath = reactAppBuildDirPath.replace(/\//g, pathSep);
|
|
|
|
}
|
2023-04-02 03:10:16 +02:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (reactAppBuildDirPath.startsWith(`.${pathSep}`)) {
|
|
|
|
return pathJoin(projectDirPath, reactAppBuildDirPath);
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
return reactAppBuildDirPath;
|
|
|
|
})(),
|
|
|
|
"keycloakifyBuildDirPath": (() => {
|
|
|
|
let { keycloakifyBuildDirPath = undefined } = parsedPackageJson.keycloakify ?? {};
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (keycloakifyBuildDirPath === undefined) {
|
|
|
|
return pathJoin(projectDirPath, "build_keycloak");
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (pathSep === "\\") {
|
|
|
|
keycloakifyBuildDirPath = keycloakifyBuildDirPath.replace(/\//g, pathSep);
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (keycloakifyBuildDirPath.startsWith(`.${pathSep}`)) {
|
|
|
|
return pathJoin(projectDirPath, keycloakifyBuildDirPath);
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
return keycloakifyBuildDirPath;
|
|
|
|
})(),
|
|
|
|
"urlPathname": (() => {
|
|
|
|
const { homepage } = parsedPackageJson;
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
let url: URL | undefined = undefined;
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (homepage !== undefined) {
|
|
|
|
url = new URL(homepage);
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
if (url === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
2022-08-16 14:41:06 +07:00
|
|
|
|
2023-08-21 05:54:17 +02:00
|
|
|
const out = url.pathname.replace(/([^/])$/, "$1/");
|
|
|
|
return out === "/" ? undefined : out;
|
|
|
|
})()
|
|
|
|
};
|
2022-08-16 14:41:06 +07:00
|
|
|
}
|