Fix some errors implementing the new account SPA feature
This commit is contained in:
parent
488dd2c6b9
commit
c87b6153bb
@ -37,10 +37,10 @@ import {
|
||||
} from "../../shared/metaInfKeycloakThemes";
|
||||
import { objectEntries } from "tsafe/objectEntries";
|
||||
import { escapeStringForPropertiesFile } from "../../tools/escapeStringForPropertiesFile";
|
||||
import * as child_process from "child_process";
|
||||
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
||||
import propertiesParser from "properties-parser";
|
||||
import { createObjectThatThrowsIfAccessed } from "../../tools/createObjectThatThrowsIfAccessed";
|
||||
import { listInstalledModules } from "../../tools/listInstalledModules";
|
||||
|
||||
export type BuildContextLike = BuildContextLike_kcContextExclusionsFtlCode &
|
||||
BuildContextLike_generateMessageProperties & {
|
||||
@ -238,9 +238,9 @@ export async function generateResources(params: {
|
||||
|
||||
let languageTags: string[] | undefined = undefined;
|
||||
|
||||
i18n_messages_generation: {
|
||||
i18n_multi_page: {
|
||||
if (isSpa) {
|
||||
break i18n_messages_generation;
|
||||
break i18n_multi_page;
|
||||
}
|
||||
|
||||
assert(themeType !== "admin");
|
||||
@ -257,23 +257,43 @@ export async function generateResources(params: {
|
||||
writeMessagePropertiesFiles;
|
||||
}
|
||||
|
||||
bring_in_account_spa_messages: {
|
||||
let isLegacyAccountSpa = false;
|
||||
|
||||
// NOTE: Eventually remove this block.
|
||||
i18n_single_page_account_legacy: {
|
||||
if (!isSpa) {
|
||||
break bring_in_account_spa_messages;
|
||||
break i18n_single_page_account_legacy;
|
||||
}
|
||||
|
||||
if (themeType !== "account") {
|
||||
break bring_in_account_spa_messages;
|
||||
break i18n_single_page_account_legacy;
|
||||
}
|
||||
|
||||
const accountUiDirPath = child_process
|
||||
.execSync(`npm list @keycloakify/keycloak-account-ui --parseable`, {
|
||||
cwd: pathDirname(buildContext.packageJsonFilePath)
|
||||
})
|
||||
.toString("utf8")
|
||||
.trim();
|
||||
const [moduleMeta] = await listInstalledModules({
|
||||
packageJsonFilePath: buildContext.packageJsonFilePath,
|
||||
filter: ({ moduleName }) =>
|
||||
moduleName === "@keycloakify/keycloak-account-ui"
|
||||
});
|
||||
|
||||
const messageDirPath_defaults = pathJoin(accountUiDirPath, "messages");
|
||||
assert(
|
||||
moduleMeta !== undefined,
|
||||
`@keycloakify/keycloak-account-ui is supposed to be installed`
|
||||
);
|
||||
|
||||
{
|
||||
const [majorStr] = moduleMeta.version.split(".");
|
||||
|
||||
if (majorStr.length === 6) {
|
||||
// NOTE: Now we use the format MMmmpp (Major, minor, patch) for example for
|
||||
// 26.0.7 it would be 260007.
|
||||
break i18n_single_page_account_legacy;
|
||||
} else {
|
||||
// 25.0.4-rc.5 or later
|
||||
isLegacyAccountSpa = true;
|
||||
}
|
||||
}
|
||||
|
||||
const messageDirPath_defaults = pathJoin(moduleMeta.dirPath, "messages");
|
||||
|
||||
if (!fs.existsSync(messageDirPath_defaults)) {
|
||||
throw new Error(
|
||||
@ -281,6 +301,8 @@ export async function generateResources(params: {
|
||||
);
|
||||
}
|
||||
|
||||
isLegacyAccountSpa = true;
|
||||
|
||||
const messagesDirPath_dest = pathJoin(
|
||||
getThemeTypeDirPath({ themeName, themeType: "account" }),
|
||||
"messages"
|
||||
@ -342,14 +364,20 @@ export async function generateResources(params: {
|
||||
);
|
||||
}
|
||||
|
||||
bring_in_admin_messages: {
|
||||
if (themeType !== "admin") {
|
||||
break bring_in_admin_messages;
|
||||
i18n_single_page: {
|
||||
if (!isSpa) {
|
||||
break i18n_single_page;
|
||||
}
|
||||
|
||||
if (isLegacyAccountSpa) {
|
||||
break i18n_single_page;
|
||||
}
|
||||
|
||||
assert(themeType === "account" || themeType === "admin");
|
||||
|
||||
const messagesDirPath_theme = pathJoin(
|
||||
buildContext.themeSrcDirPath,
|
||||
"admin",
|
||||
themeType,
|
||||
"i18n"
|
||||
);
|
||||
|
||||
@ -423,7 +451,7 @@ export async function generateResources(params: {
|
||||
|
||||
propertiesByLang[parsedBasename.lang] ??= {
|
||||
base: createObjectThatThrowsIfAccessed<Buffer>({
|
||||
debugMessage: `No base ${parsedBasename.lang} translation for admin theme`
|
||||
debugMessage: `No base ${parsedBasename.lang} translation for ${themeType} theme`
|
||||
}),
|
||||
override: undefined,
|
||||
overrideByThemeName: {}
|
||||
@ -446,7 +474,9 @@ export async function generateResources(params: {
|
||||
] = buffer;
|
||||
});
|
||||
|
||||
writeMessagePropertiesFilesByThemeType.admin = ({
|
||||
languageTags = Object.keys(propertiesByLang);
|
||||
|
||||
writeMessagePropertiesFilesByThemeType[themeType] = ({
|
||||
messageDirPath,
|
||||
themeName
|
||||
}) => {
|
||||
@ -456,8 +486,6 @@ export async function generateResources(params: {
|
||||
|
||||
Object.entries(propertiesByLang).forEach(
|
||||
([lang, { base, override, overrideByThemeName }]) => {
|
||||
(languageTags ??= []).push(lang);
|
||||
|
||||
const messages = propertiesParser.parse(base.toString("utf8"));
|
||||
|
||||
if (override !== undefined) {
|
||||
|
@ -124,8 +124,7 @@ async function command_own(params: Params_subcommands) {
|
||||
] of targetFileRelativePathsByExtensionModuleMeta.entries()) {
|
||||
const extensionModuleDirPath = await getInstalledModuleDirPath({
|
||||
moduleName: extensionModuleMeta.moduleName,
|
||||
packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath),
|
||||
projectDirPath: buildContext.projectDirPath
|
||||
packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath)
|
||||
});
|
||||
|
||||
for (const fileRelativePath of fileRelativePaths) {
|
||||
|
@ -109,7 +109,6 @@ export async function getExtensionModuleMetas(params: {
|
||||
const installedExtensionModules = await (async () => {
|
||||
const installedModulesWithKeycloakifyInTheName = await listInstalledModules({
|
||||
packageJsonFilePath: buildContext.packageJsonFilePath,
|
||||
projectDirPath: buildContext.packageJsonFilePath,
|
||||
filter: ({ moduleName }) =>
|
||||
moduleName.includes("keycloakify") && moduleName !== "keycloakify"
|
||||
});
|
||||
|
@ -2,40 +2,42 @@ import { join as pathJoin } from "path";
|
||||
import { existsAsync } from "./fs.existsAsync";
|
||||
import * as child_process from "child_process";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { getIsRootPath } from "../tools/isRootPath";
|
||||
|
||||
export async function getInstalledModuleDirPath(params: {
|
||||
moduleName: string;
|
||||
packageJsonDirPath: string;
|
||||
projectDirPath: string;
|
||||
}) {
|
||||
const { moduleName, packageJsonDirPath, projectDirPath } = params;
|
||||
const { moduleName, packageJsonDirPath } = params;
|
||||
|
||||
common_case: {
|
||||
const dirPath = pathJoin(
|
||||
...[packageJsonDirPath, "node_modules", ...moduleName.split("/")]
|
||||
);
|
||||
{
|
||||
let dirPath = packageJsonDirPath;
|
||||
|
||||
if (!(await existsAsync(dirPath))) {
|
||||
break common_case;
|
||||
while (true) {
|
||||
const dirPath_candidate = pathJoin(
|
||||
dirPath,
|
||||
"node_modules",
|
||||
...moduleName.split("/")
|
||||
);
|
||||
|
||||
let doesExist: boolean;
|
||||
|
||||
try {
|
||||
doesExist = await existsAsync(dirPath_candidate);
|
||||
} catch {
|
||||
doesExist = false;
|
||||
}
|
||||
|
||||
if (doesExist) {
|
||||
return dirPath_candidate;
|
||||
}
|
||||
|
||||
if (getIsRootPath(dirPath)) {
|
||||
break;
|
||||
}
|
||||
|
||||
dirPath = pathJoin(dirPath, "..");
|
||||
}
|
||||
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
node_modules_at_root_case: {
|
||||
if (projectDirPath === packageJsonDirPath) {
|
||||
break node_modules_at_root_case;
|
||||
}
|
||||
|
||||
const dirPath = pathJoin(
|
||||
...[projectDirPath, "node_modules", ...moduleName.split("/")]
|
||||
);
|
||||
|
||||
if (!(await existsAsync(dirPath))) {
|
||||
break node_modules_at_root_case;
|
||||
}
|
||||
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
const dirPath = child_process
|
||||
|
22
src/bin/tools/isRootPath.ts
Normal file
22
src/bin/tools/isRootPath.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { normalize as pathNormalize } from "path";
|
||||
|
||||
export function getIsRootPath(filePath: string): boolean {
|
||||
const path_normalized = pathNormalize(filePath);
|
||||
|
||||
// Unix-like root ("/")
|
||||
if (path_normalized === "/") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for Windows drive root (e.g., "C:\\")
|
||||
if (/^[a-zA-Z]:\\$/.test(path_normalized)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for UNC root (e.g., "\\server\share")
|
||||
if (/^\\\\[^\\]+\\[^\\]+\\?$/.test(path_normalized)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -8,7 +8,6 @@ import { exclude } from "tsafe/exclude";
|
||||
|
||||
export async function listInstalledModules(params: {
|
||||
packageJsonFilePath: string;
|
||||
projectDirPath: string;
|
||||
filter: (params: { moduleName: string }) => boolean;
|
||||
}): Promise<
|
||||
{
|
||||
@ -18,7 +17,7 @@ export async function listInstalledModules(params: {
|
||||
peerDependencies: Record<string, string>;
|
||||
}[]
|
||||
> {
|
||||
const { packageJsonFilePath, projectDirPath, filter } = params;
|
||||
const { packageJsonFilePath, filter } = params;
|
||||
|
||||
const parsedPackageJson = await readPackageJsonDependencies({
|
||||
packageJsonFilePath
|
||||
@ -36,8 +35,7 @@ export async function listInstalledModules(params: {
|
||||
extensionModuleNames.map(async moduleName => {
|
||||
const dirPath = await getInstalledModuleDirPath({
|
||||
moduleName,
|
||||
packageJsonDirPath: pathDirname(packageJsonFilePath),
|
||||
projectDirPath
|
||||
packageJsonDirPath: pathDirname(packageJsonFilePath)
|
||||
});
|
||||
|
||||
const { version, peerDependencies } =
|
||||
|
Loading…
x
Reference in New Issue
Block a user