keycloak_theme/src/bin/keycloakify/BuildOptions.ts

139 lines
5.1 KiB
TypeScript
Raw Normal View History

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";
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";
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;
keycloakVersionDefaultAssets: string;
/** 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
export function readBuildOptions(params: { projectDirPath: string; processArgv: string[] }): BuildOptions {
const { projectDirPath, processArgv } = params;
2023-08-21 05:54:17 +02:00
const { isSilentCliParamProvided } = (() => {
const argv = parseArgv(processArgv);
return {
2023-08-21 05:54:17 +02:00
"isSilentCliParamProvided": typeof argv["silent"] === "boolean" ? argv["silent"] : false
};
})();
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-08-21 05:54:17 +02:00
const { extraThemeProperties, groupId, artifactId, bundler, keycloakVersionDefaultAssets, 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,
"keycloakVersionDefaultAssets": keycloakVersionDefaultAssets ?? "11.0.3",
"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
}