bin general reresh, introducing termost
This commit is contained in:
@ -2,9 +2,9 @@ import { assert, type Equals } from "tsafe/assert";
|
||||
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
||||
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||
import { transformCodebase } from "../../tools/transformCodebase";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import * as fs from "fs/promises";
|
||||
import { accountV1ThemeName } from "../../constants";
|
||||
import { accountV1ThemeName } from "../../shared/constants";
|
||||
import { generatePom, BuildOptionsLike as BuildOptionsLike_generatePom } from "./generatePom";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { isInside } from "../../tools/isInside";
|
||||
|
@ -3,7 +3,7 @@ import { exclude } from "tsafe/exclude";
|
||||
import { keycloakAccountV1Versions, keycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
||||
import { getKeycloakVersionRangeForJar } from "./getKeycloakVersionRangeForJar";
|
||||
import { buildJar, BuildOptionsLike as BuildOptionsLike_buildJar } from "./buildJar";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
|
||||
export type BuildOptionsLike = BuildOptionsLike_buildJar & {
|
||||
keycloakifyBuildDirPath: string;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
|
@ -1,21 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export type UserProvidedBuildOptions = {
|
||||
extraThemeProperties?: string[];
|
||||
artifactId?: string;
|
||||
groupId?: string;
|
||||
loginThemeResourcesFromKeycloakVersion?: string;
|
||||
reactAppBuildDirPath?: string;
|
||||
keycloakifyBuildDirPath?: string;
|
||||
themeName?: string | string[];
|
||||
};
|
||||
|
||||
export const zUserProvidedBuildOptions = z.object({
|
||||
"extraThemeProperties": z.array(z.string()).optional(),
|
||||
"artifactId": z.string().optional(),
|
||||
"groupId": z.string().optional(),
|
||||
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
||||
"reactAppBuildDirPath": z.string().optional(),
|
||||
"keycloakifyBuildDirPath": z.string().optional(),
|
||||
"themeName": z.union([z.string(), z.array(z.string())]).optional()
|
||||
});
|
@ -1,189 +0,0 @@
|
||||
import { parse as urlParse } from "url";
|
||||
import { readParsedPackageJson } from "./parsedPackageJson";
|
||||
import { join as pathJoin } from "path";
|
||||
import parseArgv from "minimist";
|
||||
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
||||
import { readResolvedViteConfig } from "./resolvedViteConfig";
|
||||
import * as fs from "fs";
|
||||
import { getCacheDirPath } from "./getCacheDirPath";
|
||||
import { getReactAppRootDirPath } from "./getReactAppRootDirPath";
|
||||
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
||||
|
||||
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
||||
export type BuildOptions = {
|
||||
bundler: "vite" | "webpack";
|
||||
isSilent: boolean;
|
||||
themeVersion: string;
|
||||
themeNames: string[];
|
||||
extraThemeProperties: string[] | undefined;
|
||||
groupId: string;
|
||||
artifactId: string;
|
||||
loginThemeResourcesFromKeycloakVersion: string;
|
||||
reactAppRootDirPath: string;
|
||||
reactAppBuildDirPath: string;
|
||||
/** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
|
||||
keycloakifyBuildDirPath: string;
|
||||
publicDirPath: string;
|
||||
cacheDirPath: 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;
|
||||
assetsDirPath: string;
|
||||
npmWorkspaceRootDirPath: string;
|
||||
};
|
||||
|
||||
export function readBuildOptions(params: { processArgv: string[] }): BuildOptions {
|
||||
const { processArgv } = params;
|
||||
|
||||
const { reactAppRootDirPath } = getReactAppRootDirPath({ processArgv });
|
||||
|
||||
const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath });
|
||||
|
||||
const { resolvedViteConfig } = readResolvedViteConfig({ cacheDirPath });
|
||||
|
||||
if (resolvedViteConfig === undefined && fs.existsSync(pathJoin(reactAppRootDirPath, "vite.config.ts"))) {
|
||||
throw new Error("Keycloakify's Vite plugin output not found");
|
||||
}
|
||||
|
||||
const { keycloakify: userProvidedBuildOptionsFromPackageJson, ...parsedPackageJson } = readParsedPackageJson({ reactAppRootDirPath });
|
||||
|
||||
const userProvidedBuildOptions = {
|
||||
...userProvidedBuildOptionsFromPackageJson,
|
||||
...resolvedViteConfig?.userProvidedBuildOptions
|
||||
};
|
||||
|
||||
const themeNames = (() => {
|
||||
if (userProvidedBuildOptions.themeName === undefined) {
|
||||
return [
|
||||
parsedPackageJson.name
|
||||
.replace(/^@(.*)/, "$1")
|
||||
.split("/")
|
||||
.join("-")
|
||||
];
|
||||
}
|
||||
|
||||
if (typeof userProvidedBuildOptions.themeName === "string") {
|
||||
return [userProvidedBuildOptions.themeName];
|
||||
}
|
||||
|
||||
return userProvidedBuildOptions.themeName;
|
||||
})();
|
||||
|
||||
const reactAppBuildDirPath = (() => {
|
||||
webpack: {
|
||||
if (resolvedViteConfig !== undefined) {
|
||||
break webpack;
|
||||
}
|
||||
|
||||
if (userProvidedBuildOptions.reactAppBuildDirPath !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": userProvidedBuildOptions.reactAppBuildDirPath,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
|
||||
return pathJoin(reactAppRootDirPath, "build");
|
||||
}
|
||||
|
||||
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
||||
})();
|
||||
|
||||
const argv = parseArgv(processArgv);
|
||||
|
||||
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
||||
|
||||
return {
|
||||
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
||||
"isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
||||
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
|
||||
themeNames,
|
||||
"extraThemeProperties": userProvidedBuildOptions.extraThemeProperties,
|
||||
"groupId": (() => {
|
||||
const fallbackGroupId = `${themeNames[0]}.keycloak`;
|
||||
|
||||
return (
|
||||
process.env.KEYCLOAKIFY_GROUP_ID ??
|
||||
userProvidedBuildOptions.groupId ??
|
||||
(parsedPackageJson.homepage === undefined
|
||||
? fallbackGroupId
|
||||
: urlParse(parsedPackageJson.homepage)
|
||||
.host?.replace(/:[0-9]+$/, "")
|
||||
?.split(".")
|
||||
.reverse()
|
||||
.join(".") ?? fallbackGroupId) + ".keycloak"
|
||||
);
|
||||
})(),
|
||||
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? userProvidedBuildOptions.artifactId ?? `${themeNames[0]}-keycloak-theme`,
|
||||
"loginThemeResourcesFromKeycloakVersion": userProvidedBuildOptions.loginThemeResourcesFromKeycloakVersion ?? "24.0.4",
|
||||
reactAppRootDirPath,
|
||||
reactAppBuildDirPath,
|
||||
"keycloakifyBuildDirPath": (() => {
|
||||
if (userProvidedBuildOptions.keycloakifyBuildDirPath !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": userProvidedBuildOptions.keycloakifyBuildDirPath,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
|
||||
return pathJoin(
|
||||
reactAppRootDirPath,
|
||||
resolvedViteConfig?.buildDir === undefined ? "build_keycloak" : `${resolvedViteConfig.buildDir}_keycloak`
|
||||
);
|
||||
})(),
|
||||
"publicDirPath": (() => {
|
||||
webpack: {
|
||||
if (resolvedViteConfig !== undefined) {
|
||||
break webpack;
|
||||
}
|
||||
|
||||
if (process.env.PUBLIC_DIR_PATH !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": process.env.PUBLIC_DIR_PATH,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
|
||||
return pathJoin(reactAppRootDirPath, "public");
|
||||
}
|
||||
|
||||
return pathJoin(reactAppRootDirPath, resolvedViteConfig.publicDir);
|
||||
})(),
|
||||
cacheDirPath,
|
||||
"urlPathname": (() => {
|
||||
webpack: {
|
||||
if (resolvedViteConfig !== undefined) {
|
||||
break webpack;
|
||||
}
|
||||
|
||||
const { homepage } = parsedPackageJson;
|
||||
|
||||
let url: URL | undefined = undefined;
|
||||
|
||||
if (homepage !== undefined) {
|
||||
url = new URL(homepage);
|
||||
}
|
||||
|
||||
if (url === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const out = url.pathname.replace(/([^/])$/, "$1/");
|
||||
return out === "/" ? undefined : out;
|
||||
}
|
||||
|
||||
return resolvedViteConfig.urlPathname;
|
||||
})(),
|
||||
"assetsDirPath": (() => {
|
||||
webpack: {
|
||||
if (resolvedViteConfig !== undefined) {
|
||||
break webpack;
|
||||
}
|
||||
|
||||
return pathJoin(reactAppBuildDirPath, "static");
|
||||
}
|
||||
|
||||
return pathJoin(reactAppBuildDirPath, resolvedViteConfig.assetsDir);
|
||||
})(),
|
||||
npmWorkspaceRootDirPath
|
||||
};
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { join as pathJoin } from "path";
|
||||
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
||||
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
||||
|
||||
export function getCacheDirPath(params: { reactAppRootDirPath: string }) {
|
||||
const { reactAppRootDirPath } = params;
|
||||
|
||||
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
||||
|
||||
const cacheDirPath = pathJoin(
|
||||
(() => {
|
||||
if (process.env.XDG_CACHE_HOME !== undefined) {
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": process.env.XDG_CACHE_HOME,
|
||||
"cwd": reactAppRootDirPath
|
||||
});
|
||||
}
|
||||
|
||||
return pathJoin(npmWorkspaceRootDirPath, "node_modules", ".cache");
|
||||
})(),
|
||||
"keycloakify"
|
||||
);
|
||||
|
||||
return { cacheDirPath };
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import * as child_process from "child_process";
|
||||
import { join as pathJoin, resolve as pathResolve, sep as pathSep } from "path";
|
||||
import { assert } from "tsafe/assert";
|
||||
|
||||
let cache:
|
||||
| {
|
||||
reactAppRootDirPath: string;
|
||||
npmWorkspaceRootDirPath: string;
|
||||
}
|
||||
| undefined = undefined;
|
||||
|
||||
export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string }) {
|
||||
const { reactAppRootDirPath } = params;
|
||||
|
||||
use_cache: {
|
||||
if (cache === undefined || cache.reactAppRootDirPath !== reactAppRootDirPath) {
|
||||
break use_cache;
|
||||
}
|
||||
|
||||
const { npmWorkspaceRootDirPath } = cache;
|
||||
|
||||
return { npmWorkspaceRootDirPath };
|
||||
}
|
||||
|
||||
const npmWorkspaceRootDirPath = (function callee(depth: number): string {
|
||||
const cwd = pathResolve(pathJoin(...[reactAppRootDirPath, ...Array(depth).fill("..")]));
|
||||
|
||||
try {
|
||||
child_process.execSync("npm config get", { cwd, "stdio": ["pipe", "pipe", "pipe"] });
|
||||
} catch (error) {
|
||||
if (String(error).includes("ENOWORKSPACES")) {
|
||||
assert(cwd !== pathSep, "NPM workspace not found");
|
||||
|
||||
return callee(depth + 1);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
return cwd;
|
||||
})(0);
|
||||
|
||||
cache = {
|
||||
reactAppRootDirPath,
|
||||
npmWorkspaceRootDirPath
|
||||
};
|
||||
|
||||
return { npmWorkspaceRootDirPath };
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import parseArgv from "minimist";
|
||||
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
||||
|
||||
export function getReactAppRootDirPath(params: { processArgv: string[] }) {
|
||||
const { processArgv } = params;
|
||||
|
||||
const argv = parseArgv(processArgv);
|
||||
|
||||
const reactAppRootDirPath = (() => {
|
||||
const arg = argv["project"] ?? argv["p"];
|
||||
|
||||
if (typeof arg !== "string") {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
return getAbsoluteAndInOsFormatPath({
|
||||
"pathIsh": arg,
|
||||
"cwd": process.cwd()
|
||||
});
|
||||
})();
|
||||
|
||||
return { reactAppRootDirPath };
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from "./buildOptions";
|
@ -1,32 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
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?: UserProvidedBuildOptions;
|
||||
};
|
||||
|
||||
const zParsedPackageJson = z.object({
|
||||
"name": z.string(),
|
||||
"version": z.string().optional(),
|
||||
"homepage": z.string().optional(),
|
||||
"keycloakify": zUserProvidedBuildOptions.optional()
|
||||
});
|
||||
|
||||
assert<Equals<ReturnType<(typeof zParsedPackageJson)["parse"]>, ParsedPackageJson>>();
|
||||
|
||||
let parsedPackageJson: undefined | ParsedPackageJson;
|
||||
export function readParsedPackageJson(params: { reactAppRootDirPath: string }) {
|
||||
const { reactAppRootDirPath } = params;
|
||||
if (parsedPackageJson) {
|
||||
return parsedPackageJson;
|
||||
}
|
||||
parsedPackageJson = zParsedPackageJson.parse(JSON.parse(fs.readFileSync(pathJoin(reactAppRootDirPath, "package.json")).toString("utf8")));
|
||||
return parsedPackageJson;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import { assert } from "tsafe";
|
||||
import type { Equals } from "tsafe";
|
||||
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(),
|
||||
"userProvidedBuildOptions": zUserProvidedBuildOptions
|
||||
});
|
||||
|
||||
{
|
||||
type Got = ReturnType<(typeof zResolvedViteConfig)["parse"]>;
|
||||
type Expected = OptionalIfCanBeUndefined<ResolvedViteConfig>;
|
||||
|
||||
assert<Equals<Got, Expected>>();
|
||||
}
|
||||
|
||||
export function readResolvedViteConfig(params: { cacheDirPath: string }): {
|
||||
resolvedViteConfig: ResolvedViteConfig | undefined;
|
||||
} {
|
||||
const { cacheDirPath } = params;
|
||||
|
||||
const resolvedViteConfigJsonFilePath = pathJoin(cacheDirPath, resolvedViteConfigJsonBasename);
|
||||
|
||||
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
||||
return { "resolvedViteConfig": undefined };
|
||||
}
|
||||
|
||||
const resolvedViteConfig = (() => {
|
||||
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
||||
throw new Error("Missing Keycloakify Vite plugin output.");
|
||||
}
|
||||
|
||||
let out: ResolvedViteConfig;
|
||||
|
||||
try {
|
||||
out = JSON.parse(fs.readFileSync(resolvedViteConfigJsonFilePath).toString("utf8"));
|
||||
} catch {
|
||||
throw new Error("The output of the Keycloakify Vite plugin is not a valid JSON.");
|
||||
}
|
||||
|
||||
try {
|
||||
const zodParseReturn = zResolvedViteConfig.parse(out);
|
||||
|
||||
// So that objectKeys from tsafe return the expected result no matter what.
|
||||
Object.keys(zodParseReturn)
|
||||
.filter(key => !(key in out))
|
||||
.forEach(key => {
|
||||
delete (out as any)[key];
|
||||
});
|
||||
} catch {
|
||||
throw new Error("The output of the Keycloakify Vite plugin do not match the expected schema.");
|
||||
}
|
||||
|
||||
return out;
|
||||
})();
|
||||
|
||||
return { resolvedViteConfig };
|
||||
}
|
@ -4,9 +4,9 @@ import { generateCssCodeToDefineGlobals } from "../replacers/replaceImportsInCss
|
||||
import { replaceImportsInInlineCssCode } from "../replacers/replaceImportsInInlineCssCode";
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin } from "path";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, resources_common } from "../../constants";
|
||||
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, resources_common } from "../../shared/constants";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
bundler: "vite" | "webpack";
|
||||
|
@ -1,2 +1 @@
|
||||
export * from "./generateFtl";
|
||||
export * from "./pageId";
|
||||
|
@ -1,49 +0,0 @@
|
||||
export const loginThemePageIds = [
|
||||
"login.ftl",
|
||||
"login-username.ftl",
|
||||
"login-password.ftl",
|
||||
"webauthn-authenticate.ftl",
|
||||
"webauthn-register.ftl",
|
||||
"register.ftl",
|
||||
"info.ftl",
|
||||
"error.ftl",
|
||||
"login-reset-password.ftl",
|
||||
"login-verify-email.ftl",
|
||||
"terms.ftl",
|
||||
"login-oauth2-device-verify-user-code.ftl",
|
||||
"login-oauth-grant.ftl",
|
||||
"login-otp.ftl",
|
||||
"login-update-profile.ftl",
|
||||
"login-update-password.ftl",
|
||||
"login-idp-link-confirm.ftl",
|
||||
"login-idp-link-email.ftl",
|
||||
"login-page-expired.ftl",
|
||||
"login-config-totp.ftl",
|
||||
"logout-confirm.ftl",
|
||||
"idp-review-user-profile.ftl",
|
||||
"update-email.ftl",
|
||||
"select-authenticator.ftl",
|
||||
"saml-post-form.ftl",
|
||||
"delete-credential.ftl",
|
||||
"code.ftl",
|
||||
"delete-account-confirm.ftl",
|
||||
"frontchannel-logout.ftl",
|
||||
"login-recovery-authn-code-config.ftl",
|
||||
"login-recovery-authn-code-input.ftl",
|
||||
"login-reset-otp.ftl",
|
||||
"login-x509-info.ftl",
|
||||
"webauthn-error.ftl"
|
||||
] as const;
|
||||
|
||||
export const accountThemePageIds = [
|
||||
"password.ftl",
|
||||
"account.ftl",
|
||||
"sessions.ftl",
|
||||
"totp.ftl",
|
||||
"applications.ftl",
|
||||
"log.ftl",
|
||||
"federatedIdentity.ftl"
|
||||
] as const;
|
||||
|
||||
export type LoginThemePageId = (typeof loginThemePageIds)[number];
|
||||
export type AccountThemePageId = (typeof accountThemePageIds)[number];
|
@ -1,8 +1,8 @@
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "./buildOptions";
|
||||
import { accountV1ThemeName } from "../constants";
|
||||
import type { BuildOptions } from "../shared/buildOptions";
|
||||
import { accountV1ThemeName } from "../shared/constants";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
keycloakifyBuildDirPath: string;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin } from "path";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import { resources_common, lastKeycloakVersionWithAccountV1, accountV1ThemeName } from "../../constants";
|
||||
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { resources_common, lastKeycloakVersionWithAccountV1, accountV1ThemeName } from "../../shared/constants";
|
||||
import { downloadBuiltinKeycloakTheme } from "../../shared/downloadBuiltinKeycloakTheme";
|
||||
import { transformCodebase } from "../../tools/transformCodebase";
|
||||
import { rmSync } from "../../tools/fs.rmSync";
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
import { transformCodebase } from "../../tools/transformCodebase";
|
||||
import { join as pathJoin } from "path";
|
||||
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
||||
import { resources_common, type ThemeType } from "../../constants";
|
||||
import { BuildOptions } from "../buildOptions";
|
||||
import { assert } from "tsafe/assert";
|
||||
import * as crypto from "crypto";
|
||||
import { rmSync } from "../../tools/fs.rmSync";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
cacheDirPath: string;
|
||||
npmWorkspaceRootDirPath: string;
|
||||
};
|
||||
|
||||
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
||||
|
||||
export async function downloadKeycloakStaticResources(params: {
|
||||
themeType: ThemeType;
|
||||
themeDirPath: string;
|
||||
keycloakVersion: string;
|
||||
buildOptions: BuildOptionsLike;
|
||||
}) {
|
||||
const { themeType, themeDirPath, keycloakVersion, buildOptions } = params;
|
||||
|
||||
const tmpDirPath = pathJoin(
|
||||
themeDirPath,
|
||||
`tmp_suLeKsxId_${crypto.createHash("sha256").update(`${themeType}-${keycloakVersion}`).digest("hex").slice(0, 8)}`
|
||||
);
|
||||
|
||||
await downloadBuiltinKeycloakTheme({
|
||||
keycloakVersion,
|
||||
"destDirPath": tmpDirPath,
|
||||
buildOptions
|
||||
});
|
||||
|
||||
const resourcesPath = pathJoin(themeDirPath, themeType, "resources");
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": pathJoin(tmpDirPath, "keycloak", themeType, "resources"),
|
||||
"destDirPath": resourcesPath
|
||||
});
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": pathJoin(tmpDirPath, "keycloak", "common", "resources"),
|
||||
"destDirPath": pathJoin(resourcesPath, resources_common)
|
||||
});
|
||||
|
||||
rmSync(tmpDirPath, { "recursive": true, "force": true });
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import type { ThemeType } from "../../constants";
|
||||
import type { ThemeType } from "../../shared/constants";
|
||||
import { crawl } from "../../tools/crawl";
|
||||
import { join as pathJoin } from "path";
|
||||
import { readFileSync } from "fs";
|
||||
|
@ -3,18 +3,19 @@ import * as fs from "fs";
|
||||
import { join as pathJoin, resolve as pathResolve, dirname as pathDirname } from "path";
|
||||
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
||||
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
||||
import { generateFtlFilesCodeFactory, loginThemePageIds, accountThemePageIds } from "../generateFtl";
|
||||
import { generateFtlFilesCodeFactory } from "../generateFtl";
|
||||
import { loginThemePageIds, accountThemePageIds } from "../../shared/pageIds";
|
||||
import {
|
||||
type ThemeType,
|
||||
lastKeycloakVersionWithAccountV1,
|
||||
keycloak_resources,
|
||||
accountV1ThemeName,
|
||||
basenameOfTheKeycloakifyResourcesDir
|
||||
} from "../../constants";
|
||||
} from "../../shared/constants";
|
||||
import { isInside } from "../../tools/isInside";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { assert, type Equals } from "tsafe/assert";
|
||||
import { downloadKeycloakStaticResources } from "./downloadKeycloakStaticResources";
|
||||
import { downloadKeycloakStaticResources } from "../../shared/downloadKeycloakStaticResources";
|
||||
import { readFieldNameUsage } from "./readFieldNameUsage";
|
||||
import { readExtraPagesNames } from "./readExtraPageNames";
|
||||
import { generateMessageProperties } from "./generateMessageProperties";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { join as pathJoin } from "path";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { generateSrcMainResources, type BuildOptionsLike as BuildOptionsLike_generateSrcMainResources } from "./generateSrcMainResources";
|
||||
import { generateThemeVariations } from "./generateThemeVariants";
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { crawl } from "../../tools/crawl";
|
||||
import { accountThemePageIds, loginThemePageIds } from "../generateFtl";
|
||||
import { accountThemePageIds, loginThemePageIds } from "../../shared/pageIds";
|
||||
import { id } from "tsafe/id";
|
||||
import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
||||
import * as fs from "fs";
|
||||
import { join as pathJoin } from "path";
|
||||
import type { ThemeType } from "../../constants";
|
||||
import type { ThemeType } from "../../shared/constants";
|
||||
|
||||
export function readExtraPagesNames(params: { themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||
const { themeSrcDirPath, themeType } = params;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { crawl } from "../../tools/crawl";
|
||||
import { join as pathJoin } from "path";
|
||||
import * as fs from "fs";
|
||||
import type { ThemeType } from "../../constants";
|
||||
import type { ThemeType } from "../../shared/constants";
|
||||
|
||||
/** Assumes the theme type exists */
|
||||
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||
|
@ -1,8 +1 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
export * from "./keycloakify";
|
||||
import { main } from "./keycloakify";
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
@ -3,18 +3,19 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path
|
||||
import * as child_process from "child_process";
|
||||
import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
|
||||
import * as fs from "fs";
|
||||
import { readBuildOptions } from "./buildOptions";
|
||||
import { readBuildOptions } from "../shared/buildOptions";
|
||||
import { getLogger } from "../tools/logger";
|
||||
import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
||||
import { getThemeSrcDirPath } from "../shared/getThemeSrcDirPath";
|
||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
||||
import { vitePluginSubScriptEnvNames } from "../shared/constants";
|
||||
import { buildJars } from "./buildJars";
|
||||
import type { CliCommandOptions } from "../main";
|
||||
|
||||
export async function main() {
|
||||
const buildOptions = readBuildOptions({
|
||||
"processArgv": process.argv.slice(2)
|
||||
});
|
||||
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||
const { cliCommandOptions } = params;
|
||||
|
||||
const buildOptions = readBuildOptions({ cliCommandOptions });
|
||||
|
||||
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
||||
logger.log("🔏 Building the keycloak theme...⌚");
|
||||
@ -45,7 +46,7 @@ export async function main() {
|
||||
"cwd": buildOptions.reactAppRootDirPath,
|
||||
"env": {
|
||||
...process.env,
|
||||
[keycloakifyBuildOptionsForPostPostBuildScriptEnvName]: JSON.stringify(buildOptions)
|
||||
[vitePluginSubScriptEnvNames.runPostBuildScript]: JSON.stringify(buildOptions)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as crypto from "crypto";
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../shared/constants";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
urlPathname: string | undefined;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { BuildOptions } from "../buildOptions";
|
||||
import type { BuildOptions } from "../../shared/buildOptions";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../shared/constants";
|
||||
|
||||
export type BuildOptionsLike = {
|
||||
urlPathname: string | undefined;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../../buildOptions";
|
||||
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||
import { replaceImportsInJsCode_vite } from "./vite";
|
||||
import { replaceImportsInJsCode_webpack } from "./webpack";
|
||||
import * as fs from "fs";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../shared/constants";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../../buildOptions";
|
||||
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||
import * as nodePath from "path";
|
||||
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../shared/constants";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { BuildOptions } from "../../buildOptions";
|
||||
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||
import * as nodePath from "path";
|
||||
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
||||
|
||||
|
Reference in New Issue
Block a user