Refactor checkpoint
This commit is contained in:
parent
8340608045
commit
93c1c56279
2
.gitignore
vendored
2
.gitignore
vendored
@ -50,6 +50,8 @@ jspm_packages
|
|||||||
|
|
||||||
/src/login/i18n/messages_defaultSet/
|
/src/login/i18n/messages_defaultSet/
|
||||||
/src/account/i18n/messages_defaultSet/
|
/src/account/i18n/messages_defaultSet/
|
||||||
|
/resources/
|
||||||
|
/account-v1/
|
||||||
|
|
||||||
# VS Code devcontainers
|
# VS Code devcontainers
|
||||||
.devcontainer
|
.devcontainer
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"url": "git://github.com/keycloakify/keycloakify.git"
|
"url": "git://github.com/keycloakify/keycloakify.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "tsx scripts/generate-i18n-messages.ts",
|
"prepare": "tsx scripts/prepare/main.ts",
|
||||||
"build": "tsx scripts/build.ts",
|
"build": "tsx scripts/build.ts",
|
||||||
"storybook": "tsx scripts/start-storybook.ts",
|
"storybook": "tsx scripts/start-storybook.ts",
|
||||||
"link-in-starter": "tsx scripts/link-in-starter.ts",
|
"link-in-starter": "tsx scripts/link-in-starter.ts",
|
||||||
|
@ -4,6 +4,7 @@ import { join } from "path";
|
|||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { transformCodebase } from "../src/bin/tools/transformCodebase";
|
import { transformCodebase } from "../src/bin/tools/transformCodebase";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../src/bin/shared/constants";
|
||||||
|
|
||||||
console.log(chalk.cyan("Building Keycloakify..."));
|
console.log(chalk.cyan("Building Keycloakify..."));
|
||||||
|
|
||||||
@ -136,9 +137,17 @@ fs.rmSync(join("dist", "ncc_out"), { recursive: true });
|
|||||||
assert(hasBeenPatched);
|
assert(hasBeenPatched);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.rmSync(join("dist", "src"), { recursive: true, force: true });
|
for (const dirBasename of [
|
||||||
|
"src",
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES,
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.ACCOUNT_V1
|
||||||
|
]) {
|
||||||
|
const destDirPath = join("dist", dirBasename);
|
||||||
|
|
||||||
fs.cpSync("src", join("dist", "src"), { recursive: true });
|
fs.rmSync(destDirPath, { recursive: true, force: true });
|
||||||
|
|
||||||
|
fs.cpSync(dirBasename, destDirPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
transformCodebase({
|
transformCodebase({
|
||||||
srcDirPath: join("stories"),
|
srcDirPath: join("stories"),
|
||||||
|
4
scripts/prepare/constants.ts
Normal file
4
scripts/prepare/constants.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export const KEYCLOAK_VERSION = {
|
||||||
|
FOR_LOGIN_THEME: "25.0.4",
|
||||||
|
FOR_ACCOUNT_MULTI_PAGE: "21.1.2"
|
||||||
|
};
|
77
scripts/prepare/createAccountV1Dir.ts
Normal file
77
scripts/prepare/createAccountV1Dir.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { KEYCLOAK_VERSION } from "./constants";
|
||||||
|
import { transformCodebase } from "../../src/bin/tools/transformCodebase";
|
||||||
|
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
|
||||||
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../src/bin/shared/constants";
|
||||||
|
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
|
import { accountMultiPageSupportedLanguages } from "./generateI18nMessages";
|
||||||
|
|
||||||
|
export async function createAccountV1Dir() {
|
||||||
|
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
|
||||||
|
keycloakVersion: KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Exclude unused resources.
|
||||||
|
|
||||||
|
const destDirPath = pathJoin(
|
||||||
|
getThisCodebaseRootDirPath(),
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.ACCOUNT_V1
|
||||||
|
);
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: pathJoin(extractedDirPath, "base", "account"),
|
||||||
|
destDirPath
|
||||||
|
});
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: pathJoin(extractedDirPath, "keycloak", "account", "resources"),
|
||||||
|
destDirPath: pathJoin(destDirPath, "resources")
|
||||||
|
});
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: pathJoin(extractedDirPath, "keycloak", "common", "resources"),
|
||||||
|
destDirPath: pathJoin(
|
||||||
|
destDirPath,
|
||||||
|
"resources",
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
pathJoin(destDirPath, "theme.properties"),
|
||||||
|
Buffer.from(
|
||||||
|
[
|
||||||
|
"accountResourceProvider=account-v1",
|
||||||
|
"",
|
||||||
|
`locales=${accountMultiPageSupportedLanguages.join(",")}`,
|
||||||
|
"",
|
||||||
|
"styles=" +
|
||||||
|
[
|
||||||
|
"css/account.css",
|
||||||
|
"img/icon-sidebar-active.png",
|
||||||
|
"img/logo.png",
|
||||||
|
...[
|
||||||
|
"patternfly.min.css",
|
||||||
|
"patternfly-additions.min.css",
|
||||||
|
"patternfly-additions.min.css"
|
||||||
|
].map(
|
||||||
|
fileBasename =>
|
||||||
|
`${WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON}/node_modules/patternfly/dist/css/${fileBasename}`
|
||||||
|
)
|
||||||
|
].join(" "),
|
||||||
|
"",
|
||||||
|
"##### css classes for form buttons",
|
||||||
|
"# main class used for all buttons",
|
||||||
|
"kcButtonClass=btn",
|
||||||
|
"# classes defining priority of the button - primary or default (there is typically only one priority button for the form)",
|
||||||
|
"kcButtonPrimaryClass=btn-primary",
|
||||||
|
"kcButtonDefaultClass=btn-default",
|
||||||
|
"# classes defining size of the button",
|
||||||
|
"kcButtonLargeClass=btn-lg",
|
||||||
|
""
|
||||||
|
].join("\n"),
|
||||||
|
"utf8"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
70
scripts/prepare/createResourcesDir.ts
Normal file
70
scripts/prepare/createResourcesDir.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
|
||||||
|
import { KEYCLOAK_VERSION } from "./constants";
|
||||||
|
import { transformCodebase } from "../../src/bin/tools/transformCodebase";
|
||||||
|
import { existsAsync } from "../../src/bin/tools/fs.existsAsync";
|
||||||
|
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../src/bin/shared/constants";
|
||||||
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
|
|
||||||
|
export async function createResourcesDir() {
|
||||||
|
await Promise.all(
|
||||||
|
(["login", "account"] as const).map(async themeType => {
|
||||||
|
const keycloakVersion = (() => {
|
||||||
|
switch (themeType) {
|
||||||
|
case "login":
|
||||||
|
return KEYCLOAK_VERSION.FOR_LOGIN_THEME;
|
||||||
|
case "account":
|
||||||
|
return KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE;
|
||||||
|
}
|
||||||
|
assert<Equals<typeof themeType, never>>();
|
||||||
|
})();
|
||||||
|
|
||||||
|
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
|
||||||
|
keycloakVersion
|
||||||
|
});
|
||||||
|
|
||||||
|
const destDirPath = pathJoin(
|
||||||
|
getThisCodebaseRootDirPath(),
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES,
|
||||||
|
themeType
|
||||||
|
);
|
||||||
|
|
||||||
|
base_resources: {
|
||||||
|
const srcDirPath = pathJoin(
|
||||||
|
extractedDirPath,
|
||||||
|
"base",
|
||||||
|
themeType,
|
||||||
|
"resources"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!(await existsAsync(srcDirPath))) {
|
||||||
|
break base_resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath,
|
||||||
|
destDirPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: pathJoin(
|
||||||
|
extractedDirPath,
|
||||||
|
"keycloak",
|
||||||
|
themeType,
|
||||||
|
"resources"
|
||||||
|
),
|
||||||
|
destDirPath
|
||||||
|
});
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: pathJoin(extractedDirPath, "keycloak", "common", "resources"),
|
||||||
|
destDirPath: pathJoin(
|
||||||
|
destDirPath,
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON
|
||||||
|
)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
34
scripts/prepare/downloadKeycloakDefaultTheme.ts
Normal file
34
scripts/prepare/downloadKeycloakDefaultTheme.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { relative as pathRelative } from "path";
|
||||||
|
import { downloadAndExtractArchive } from "../../src/bin/tools/downloadAndExtractArchive";
|
||||||
|
import { getProxyFetchOptions } from "../../src/bin/tools/fetchProxyOptions";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
|
|
||||||
|
export async function downloadKeycloakDefaultTheme(params: { keycloakVersion: string }) {
|
||||||
|
const { keycloakVersion } = params;
|
||||||
|
|
||||||
|
const { extractedDirPath } = await downloadAndExtractArchive({
|
||||||
|
url: `https://repo1.maven.org/maven2/org/keycloak/keycloak-themes/${keycloakVersion}/keycloak-themes-${keycloakVersion}.jar`,
|
||||||
|
cacheDirPath: pathJoin(
|
||||||
|
getThisCodebaseRootDirPath(),
|
||||||
|
"node_modules",
|
||||||
|
".cache",
|
||||||
|
"scripts"
|
||||||
|
),
|
||||||
|
fetchOptions: getProxyFetchOptions({
|
||||||
|
npmConfigGetCwd: getThisCodebaseRootDirPath()
|
||||||
|
}),
|
||||||
|
uniqueIdOfOnArchiveFile: "downloadKeycloakDefaultTheme",
|
||||||
|
onArchiveFile: async ({ fileRelativePath, writeFile }) => {
|
||||||
|
const fileRelativePath_target = pathRelative("theme", fileRelativePath);
|
||||||
|
|
||||||
|
if (fileRelativePath_target.startsWith("..")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile({ fileRelativePath: fileRelativePath_target });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { extractedDirPath };
|
||||||
|
}
|
@ -8,15 +8,12 @@ import {
|
|||||||
} from "path";
|
} from "path";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { same } from "evt/tools/inDepth";
|
import { same } from "evt/tools/inDepth";
|
||||||
import { crawl } from "../src/bin/tools/crawl";
|
import { crawl } from "../../src/bin/tools/crawl";
|
||||||
import { downloadKeycloakDefaultTheme } from "../src/bin/shared/downloadKeycloakDefaultTheme";
|
import { downloadKeycloakDefaultTheme } from "./downloadKeycloakDefaultTheme";
|
||||||
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
import { deepAssign } from "../src/tools/deepAssign";
|
import { deepAssign } from "../../src/tools/deepAssign";
|
||||||
import { getProxyFetchOptions } from "../src/bin/tools/fetchProxyOptions";
|
import { THEME_TYPES } from "../../src/bin/shared/constants";
|
||||||
import {
|
import { KEYCLOAK_VERSION } from "./constants";
|
||||||
THEME_TYPES,
|
|
||||||
LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1
|
|
||||||
} from "../src/bin/shared/constants";
|
|
||||||
|
|
||||||
// NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files,
|
// NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files,
|
||||||
// update the version array for generating for newer version.
|
// update the version array for generating for newer version.
|
||||||
@ -24,7 +21,7 @@ import {
|
|||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const propertiesParser = require("properties-parser");
|
const propertiesParser = require("properties-parser");
|
||||||
|
|
||||||
async function main() {
|
export async function generateI18nMessages() {
|
||||||
const thisCodebaseRootDirPath = getThisCodebaseRootDirPath();
|
const thisCodebaseRootDirPath = getThisCodebaseRootDirPath();
|
||||||
|
|
||||||
type Dictionary = { [idiomId: string]: string };
|
type Dictionary = { [idiomId: string]: string };
|
||||||
@ -32,30 +29,19 @@ async function main() {
|
|||||||
const record: { [themeType: string]: { [language: string]: Dictionary } } = {};
|
const record: { [themeType: string]: { [language: string]: Dictionary } } = {};
|
||||||
|
|
||||||
for (const themeType of THEME_TYPES) {
|
for (const themeType of THEME_TYPES) {
|
||||||
const { defaultThemeDirPath } = await downloadKeycloakDefaultTheme({
|
const { extractedDirPath } = await downloadKeycloakDefaultTheme({
|
||||||
keycloakVersion: (() => {
|
keycloakVersion: (() => {
|
||||||
switch (themeType) {
|
switch (themeType) {
|
||||||
case "login":
|
case "login":
|
||||||
return "25.0.4";
|
return KEYCLOAK_VERSION.FOR_LOGIN_THEME;
|
||||||
case "account":
|
case "account":
|
||||||
return LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1;
|
return KEYCLOAK_VERSION.FOR_ACCOUNT_MULTI_PAGE;
|
||||||
}
|
|
||||||
})(),
|
|
||||||
buildContext: {
|
|
||||||
cacheDirPath: pathJoin(
|
|
||||||
thisCodebaseRootDirPath,
|
|
||||||
"node_modules",
|
|
||||||
".cache",
|
|
||||||
"keycloakify"
|
|
||||||
),
|
|
||||||
fetchOptions: getProxyFetchOptions({
|
|
||||||
npmConfigGetCwd: thisCodebaseRootDirPath
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
const baseThemeDirPath = pathJoin(defaultThemeDirPath, "base");
|
const baseThemeDirPath = pathJoin(extractedDirPath, "base");
|
||||||
const re = new RegExp(
|
const re = new RegExp(
|
||||||
`^([^\\${pathSep}]+)\\${pathSep}messages\\${pathSep}messages_([^.]+).properties$`
|
`^([^\\${pathSep}]+)\\${pathSep}messages\\${pathSep}messages_([^.]+).properties$`
|
||||||
);
|
);
|
||||||
@ -597,30 +583,34 @@ const keycloakifyExtraMessages_login: Record<
|
|||||||
/* spell-checker: enable */
|
/* spell-checker: enable */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const accountMultiPageSupportedLanguages = [
|
||||||
|
"en",
|
||||||
|
"ar",
|
||||||
|
"ca",
|
||||||
|
"cs",
|
||||||
|
"da",
|
||||||
|
"de",
|
||||||
|
"es",
|
||||||
|
"fi",
|
||||||
|
"fr",
|
||||||
|
"hu",
|
||||||
|
"it",
|
||||||
|
"ja",
|
||||||
|
"lt",
|
||||||
|
"lv",
|
||||||
|
"nl",
|
||||||
|
"no",
|
||||||
|
"pl",
|
||||||
|
"pt-BR",
|
||||||
|
"ru",
|
||||||
|
"sk",
|
||||||
|
"sv",
|
||||||
|
"tr",
|
||||||
|
"zh-CN"
|
||||||
|
] as const;
|
||||||
|
|
||||||
const keycloakifyExtraMessages_account: Record<
|
const keycloakifyExtraMessages_account: Record<
|
||||||
| "en"
|
(typeof accountMultiPageSupportedLanguages)[number],
|
||||||
| "ar"
|
|
||||||
| "ca"
|
|
||||||
| "cs"
|
|
||||||
| "da"
|
|
||||||
| "de"
|
|
||||||
| "es"
|
|
||||||
| "fi"
|
|
||||||
| "fr"
|
|
||||||
| "hu"
|
|
||||||
| "it"
|
|
||||||
| "ja"
|
|
||||||
| "lt"
|
|
||||||
| "lv"
|
|
||||||
| "nl"
|
|
||||||
| "no"
|
|
||||||
| "pl"
|
|
||||||
| "pt-BR"
|
|
||||||
| "ru"
|
|
||||||
| "sk"
|
|
||||||
| "sv"
|
|
||||||
| "tr"
|
|
||||||
| "zh-CN",
|
|
||||||
Record<"newPasswordSameAsOld" | "passwordConfirmNotMatch", string>
|
Record<"newPasswordSameAsOld" | "passwordConfirmNotMatch", string>
|
||||||
> = {
|
> = {
|
||||||
en: {
|
en: {
|
||||||
@ -719,7 +709,3 @@ const keycloakifyExtraMessages_account: Record<
|
|||||||
}
|
}
|
||||||
/* spell-checker: enable */
|
/* spell-checker: enable */
|
||||||
};
|
};
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
main();
|
|
||||||
}
|
|
13
scripts/prepare/main.ts
Normal file
13
scripts/prepare/main.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { generateI18nMessages } from "./generateI18nMessages";
|
||||||
|
import { createAccountV1Dir } from "./createAccountV1Dir";
|
||||||
|
import { createResourcesDir } from "./createResourcesDir";
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
console.log("Pulling i18n messages...");
|
||||||
|
await generateI18nMessages();
|
||||||
|
console.log("Creating account-v1 dir...");
|
||||||
|
await createAccountV1Dir();
|
||||||
|
console.log("Creating resources dir...");
|
||||||
|
await createResourcesDir();
|
||||||
|
console.log("Done!");
|
||||||
|
})();
|
@ -1,10 +1,10 @@
|
|||||||
import "keycloakify/tools/Object.fromEntries";
|
import "keycloakify/tools/Object.fromEntries";
|
||||||
import { RESOURCES_COMMON, KEYCLOAK_RESOURCES } from "keycloakify/bin/shared/constants";
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "keycloakify/bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import type { KcContext } from "./KcContext";
|
import type { KcContext } from "./KcContext";
|
||||||
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
||||||
|
|
||||||
const resourcesPath = `${BASE_URL}${KEYCLOAK_RESOURCES}/account/resources`;
|
const resourcesPath = `${BASE_URL}${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY}/account`;
|
||||||
|
|
||||||
export const kcContextCommonMock: KcContext.Common = {
|
export const kcContextCommonMock: KcContext.Common = {
|
||||||
themeVersion: "0.0.0",
|
themeVersion: "0.0.0",
|
||||||
@ -13,7 +13,7 @@ export const kcContextCommonMock: KcContext.Common = {
|
|||||||
themeName: "my-theme-name",
|
themeName: "my-theme-name",
|
||||||
url: {
|
url: {
|
||||||
resourcesPath,
|
resourcesPath,
|
||||||
resourcesCommonPath: `${resourcesPath}/${RESOURCES_COMMON}`,
|
resourcesCommonPath: `${resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON}`,
|
||||||
resourceUrl: "#",
|
resourceUrl: "#",
|
||||||
accountUrl: "#",
|
accountUrl: "#",
|
||||||
applicationsUrl: "#",
|
applicationsUrl: "#",
|
||||||
|
@ -7,7 +7,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
|
|
||||||
const buildContext = getBuildContext({ cliCommandOptions });
|
const buildContext = getBuildContext({ cliCommandOptions });
|
||||||
|
|
||||||
await copyKeycloakResourcesToPublic({
|
copyKeycloakResourcesToPublic({
|
||||||
buildContext
|
buildContext
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,7 @@ import * as fs from "fs";
|
|||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import type { BuildContext } from "../../shared/buildContext";
|
import type { BuildContext } from "../../shared/buildContext";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import {
|
import { type ThemeType, WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../shared/constants";
|
||||||
type ThemeType,
|
|
||||||
BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR,
|
|
||||||
RESOURCES_COMMON
|
|
||||||
} from "../../shared/constants";
|
|
||||||
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
||||||
|
|
||||||
export type BuildContextLike = BuildContextLike_replaceImportsInJsCode &
|
export type BuildContextLike = BuildContextLike_replaceImportsInJsCode &
|
||||||
@ -94,7 +90,7 @@ export function generateFtlFilesCodeFactory(params: {
|
|||||||
new RegExp(
|
new RegExp(
|
||||||
`^${(buildContext.urlPathname ?? "/").replace(/\//g, "\\/")}`
|
`^${(buildContext.urlPathname ?? "/").replace(/\//g, "\\/")}`
|
||||||
),
|
),
|
||||||
`\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/`
|
`\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
@ -119,7 +115,7 @@ export function generateFtlFilesCodeFactory(params: {
|
|||||||
.replace("{{keycloakifyVersion}}", keycloakifyVersion)
|
.replace("{{keycloakifyVersion}}", keycloakifyVersion)
|
||||||
.replace("{{themeVersion}}", buildContext.themeVersion)
|
.replace("{{themeVersion}}", buildContext.themeVersion)
|
||||||
.replace("{{fieldNames}}", fieldNames.map(name => `"${name}"`).join(", "))
|
.replace("{{fieldNames}}", fieldNames.map(name => `"${name}"`).join(", "))
|
||||||
.replace("{{RESOURCES_COMMON}}", RESOURCES_COMMON)
|
.replace("{{RESOURCES_COMMON}}", WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON)
|
||||||
.replace(
|
.replace(
|
||||||
"{{userDefinedExclusions}}",
|
"{{userDefinedExclusions}}",
|
||||||
buildContext.kcContextExclusionsFtlCode ?? ""
|
buildContext.kcContextExclusionsFtlCode ?? ""
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
import * as fs from "fs";
|
|
||||||
import { join as pathJoin } from "path";
|
|
||||||
import { assert } from "tsafe/assert";
|
|
||||||
import type { BuildContext } from "../../shared/buildContext";
|
|
||||||
import {
|
|
||||||
RESOURCES_COMMON,
|
|
||||||
LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1,
|
|
||||||
ACCOUNT_V1_THEME_NAME
|
|
||||||
} from "../../shared/constants";
|
|
||||||
import {
|
|
||||||
downloadKeycloakDefaultTheme,
|
|
||||||
BuildContextLike as BuildContextLike_downloadKeycloakDefaultTheme
|
|
||||||
} from "../../shared/downloadKeycloakDefaultTheme";
|
|
||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
|
||||||
|
|
||||||
export type BuildContextLike = BuildContextLike_downloadKeycloakDefaultTheme;
|
|
||||||
|
|
||||||
assert<BuildContext extends BuildContextLike ? true : false>();
|
|
||||||
|
|
||||||
export async function bringInAccountV1(params: {
|
|
||||||
resourcesDirPath: string;
|
|
||||||
buildContext: BuildContextLike;
|
|
||||||
}) {
|
|
||||||
const { resourcesDirPath, buildContext } = params;
|
|
||||||
|
|
||||||
const { defaultThemeDirPath } = await downloadKeycloakDefaultTheme({
|
|
||||||
keycloakVersion: LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1,
|
|
||||||
buildContext
|
|
||||||
});
|
|
||||||
|
|
||||||
const accountV1DirPath = pathJoin(
|
|
||||||
resourcesDirPath,
|
|
||||||
"theme",
|
|
||||||
ACCOUNT_V1_THEME_NAME,
|
|
||||||
"account"
|
|
||||||
);
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath: pathJoin(defaultThemeDirPath, "base", "account"),
|
|
||||||
destDirPath: accountV1DirPath
|
|
||||||
});
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath: pathJoin(defaultThemeDirPath, "keycloak", "account", "resources"),
|
|
||||||
destDirPath: pathJoin(accountV1DirPath, "resources")
|
|
||||||
});
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath: pathJoin(defaultThemeDirPath, "keycloak", "common", "resources"),
|
|
||||||
destDirPath: pathJoin(accountV1DirPath, "resources", RESOURCES_COMMON)
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(accountV1DirPath, "theme.properties"),
|
|
||||||
Buffer.from(
|
|
||||||
[
|
|
||||||
"accountResourceProvider=account-v1",
|
|
||||||
"",
|
|
||||||
"locales=ar,ca,cs,da,de,en,es,fr,fi,hu,it,ja,lt,nl,no,pl,pt-BR,ru,sk,sv,tr,zh-CN",
|
|
||||||
"",
|
|
||||||
"styles=" +
|
|
||||||
[
|
|
||||||
"css/account.css",
|
|
||||||
"img/icon-sidebar-active.png",
|
|
||||||
"img/logo.png",
|
|
||||||
...[
|
|
||||||
"patternfly.min.css",
|
|
||||||
"patternfly-additions.min.css",
|
|
||||||
"patternfly-additions.min.css"
|
|
||||||
].map(
|
|
||||||
fileBasename =>
|
|
||||||
`${RESOURCES_COMMON}/node_modules/patternfly/dist/css/${fileBasename}`
|
|
||||||
)
|
|
||||||
].join(" "),
|
|
||||||
"",
|
|
||||||
"##### css classes for form buttons",
|
|
||||||
"# main class used for all buttons",
|
|
||||||
"kcButtonClass=btn",
|
|
||||||
"# classes defining priority of the button - primary or default (there is typically only one priority button for the form)",
|
|
||||||
"kcButtonPrimaryClass=btn-primary",
|
|
||||||
"kcButtonDefaultClass=btn-default",
|
|
||||||
"# classes defining size of the button",
|
|
||||||
"kcButtonLargeClass=btn-lg",
|
|
||||||
""
|
|
||||||
].join("\n"),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,11 +1,6 @@
|
|||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
import { transformCodebase } from "../../tools/transformCodebase";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {
|
import { join as pathJoin, relative as pathRelative, dirname as pathDirname } from "path";
|
||||||
join as pathJoin,
|
|
||||||
resolve as pathResolve,
|
|
||||||
relative as pathRelative,
|
|
||||||
dirname as pathDirname
|
|
||||||
} from "path";
|
|
||||||
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
||||||
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
||||||
import {
|
import {
|
||||||
@ -14,26 +9,15 @@ import {
|
|||||||
} from "../generateFtl";
|
} from "../generateFtl";
|
||||||
import {
|
import {
|
||||||
type ThemeType,
|
type ThemeType,
|
||||||
LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1,
|
|
||||||
KEYCLOAK_RESOURCES,
|
|
||||||
ACCOUNT_V1_THEME_NAME,
|
|
||||||
BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR,
|
|
||||||
LOGIN_THEME_PAGE_IDS,
|
LOGIN_THEME_PAGE_IDS,
|
||||||
ACCOUNT_THEME_PAGE_IDS
|
ACCOUNT_THEME_PAGE_IDS,
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME
|
||||||
} from "../../shared/constants";
|
} from "../../shared/constants";
|
||||||
import type { BuildContext } from "../../shared/buildContext";
|
import type { BuildContext } from "../../shared/buildContext";
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
import {
|
|
||||||
downloadKeycloakStaticResources,
|
|
||||||
type BuildContextLike as BuildContextLike_downloadKeycloakStaticResources
|
|
||||||
} from "../../shared/downloadKeycloakStaticResources";
|
|
||||||
import { readFieldNameUsage } from "./readFieldNameUsage";
|
import { readFieldNameUsage } from "./readFieldNameUsage";
|
||||||
import { readExtraPagesNames } from "./readExtraPageNames";
|
import { readExtraPagesNames } from "./readExtraPageNames";
|
||||||
import { generateMessageProperties } from "./generateMessageProperties";
|
import { generateMessageProperties } from "./generateMessageProperties";
|
||||||
import {
|
|
||||||
bringInAccountV1,
|
|
||||||
type BuildContextLike as BuildContextLike_bringInAccountV1
|
|
||||||
} from "./bringInAccountV1";
|
|
||||||
import { rmSync } from "../../tools/fs.rmSync";
|
import { rmSync } from "../../tools/fs.rmSync";
|
||||||
import { readThisNpmPackageVersion } from "../../tools/readThisNpmPackageVersion";
|
import { readThisNpmPackageVersion } from "../../tools/readThisNpmPackageVersion";
|
||||||
import {
|
import {
|
||||||
@ -43,12 +27,10 @@ import {
|
|||||||
import { objectEntries } from "tsafe/objectEntries";
|
import { objectEntries } from "tsafe/objectEntries";
|
||||||
import { escapeStringForPropertiesFile } from "../../tools/escapeStringForPropertiesFile";
|
import { escapeStringForPropertiesFile } from "../../tools/escapeStringForPropertiesFile";
|
||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
|
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
||||||
|
|
||||||
export type BuildContextLike = BuildContextLike_kcContextExclusionsFtlCode &
|
export type BuildContextLike = BuildContextLike_kcContextExclusionsFtlCode & {
|
||||||
BuildContextLike_downloadKeycloakStaticResources &
|
|
||||||
BuildContextLike_bringInAccountV1 & {
|
|
||||||
extraThemeProperties: string[] | undefined;
|
extraThemeProperties: string[] | undefined;
|
||||||
loginThemeResourcesFromKeycloakVersion: string;
|
|
||||||
projectDirPath: string;
|
projectDirPath: string;
|
||||||
projectBuildDirPath: string;
|
projectBuildDirPath: string;
|
||||||
environmentVariables: { name: string; default: string }[];
|
environmentVariables: { name: string; default: string }[];
|
||||||
@ -88,7 +70,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
const destDirPath = pathJoin(
|
const destDirPath = pathJoin(
|
||||||
themeTypeDirPath,
|
themeTypeDirPath,
|
||||||
"resources",
|
"resources",
|
||||||
BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR
|
WELL_KNOWN_DIRECTORY_BASE_NAME.DIST
|
||||||
);
|
);
|
||||||
|
|
||||||
// NOTE: Prevent accumulation of files in the assets dir, as names are hashed they pile up.
|
// NOTE: Prevent accumulation of files in the assets dir, as names are hashed they pile up.
|
||||||
@ -106,7 +88,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
themeType: "login"
|
themeType: "login"
|
||||||
}),
|
}),
|
||||||
"resources",
|
"resources",
|
||||||
BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR
|
WELL_KNOWN_DIRECTORY_BASE_NAME.DIST
|
||||||
),
|
),
|
||||||
destDirPath
|
destDirPath
|
||||||
});
|
});
|
||||||
@ -117,7 +99,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
{
|
{
|
||||||
const dirPath = pathJoin(
|
const dirPath = pathJoin(
|
||||||
buildContext.projectBuildDirPath,
|
buildContext.projectBuildDirPath,
|
||||||
KEYCLOAK_RESOURCES
|
WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY
|
||||||
);
|
);
|
||||||
|
|
||||||
if (fs.existsSync(dirPath)) {
|
if (fs.existsSync(dirPath)) {
|
||||||
@ -125,7 +107,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
[
|
[
|
||||||
`Keycloakify build error: The ${KEYCLOAK_RESOURCES} directory shouldn't exist in your build directory.`,
|
`Keycloakify build error: The ${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY} directory shouldn't exist in your build directory.`,
|
||||||
`(${pathRelative(process.cwd(), dirPath)}).\n`,
|
`(${pathRelative(process.cwd(), dirPath)}).\n`,
|
||||||
`Theses assets are only required for local development with Storybook.",
|
`Theses assets are only required for local development with Storybook.",
|
||||||
"Please remove this directory as an additional step of your command.\n`,
|
"Please remove this directory as an additional step of your command.\n`,
|
||||||
@ -232,23 +214,50 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bring_in_account_v3_i18n_messages: {
|
||||||
|
if (!buildContext.implementedThemeTypes.account.isImplemented) {
|
||||||
|
break bring_in_account_v3_i18n_messages;
|
||||||
|
}
|
||||||
|
if (buildContext.implementedThemeTypes.account.type !== "Single-Page") {
|
||||||
|
break bring_in_account_v3_i18n_messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountUiDirPath = child_process
|
||||||
|
.execSync("npm list @keycloakify/keycloak-account-ui --parseable", {
|
||||||
|
cwd: pathDirname(buildContext.packageJsonFilePath)
|
||||||
|
})
|
||||||
|
.toString("utf8")
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
const messagesDirPath = pathJoin(accountUiDirPath, "messages");
|
||||||
|
|
||||||
|
if (!fs.existsSync(messagesDirPath)) {
|
||||||
|
throw new Error(
|
||||||
|
`Please update @keycloakify/keycloak-account-ui to 25.0.4-rc.5 or later.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
srcDirPath: messagesDirPath,
|
||||||
|
destDirPath: pathJoin(
|
||||||
|
getThemeTypeDirPath({ themeType: "account" }),
|
||||||
|
"messages"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
keycloak_static_resources: {
|
keycloak_static_resources: {
|
||||||
if (isForAccountSpa) {
|
if (isForAccountSpa) {
|
||||||
break keycloak_static_resources;
|
break keycloak_static_resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
await downloadKeycloakStaticResources({
|
transformCodebase({
|
||||||
keycloakVersion: (() => {
|
srcDirPath: pathJoin(
|
||||||
switch (themeType) {
|
getThisCodebaseRootDirPath(),
|
||||||
case "account":
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES,
|
||||||
return LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1;
|
themeType
|
||||||
case "login":
|
),
|
||||||
return buildContext.loginThemeResourcesFromKeycloakVersion;
|
destDirPath: pathJoin(themeTypeDirPath, "resources")
|
||||||
}
|
|
||||||
})(),
|
|
||||||
themeDirPath: pathResolve(pathJoin(themeTypeDirPath, "..")),
|
|
||||||
themeType,
|
|
||||||
buildContext
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +268,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
`parent=${(() => {
|
`parent=${(() => {
|
||||||
switch (themeType) {
|
switch (themeType) {
|
||||||
case "account":
|
case "account":
|
||||||
return isForAccountSpa ? "base" : ACCOUNT_V1_THEME_NAME;
|
return isForAccountSpa ? "base" : "account-v1";
|
||||||
case "login":
|
case "login":
|
||||||
return "keycloak";
|
return "keycloak";
|
||||||
}
|
}
|
||||||
@ -299,41 +308,12 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
break bring_in_account_v1;
|
break bring_in_account_v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
await bringInAccountV1({
|
|
||||||
resourcesDirPath,
|
|
||||||
buildContext
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bring_in_account_v3_i18n_messages: {
|
|
||||||
if (!buildContext.implementedThemeTypes.account.isImplemented) {
|
|
||||||
break bring_in_account_v3_i18n_messages;
|
|
||||||
}
|
|
||||||
if (buildContext.implementedThemeTypes.account.type !== "Single-Page") {
|
|
||||||
break bring_in_account_v3_i18n_messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
const accountUiDirPath = child_process
|
|
||||||
.execSync("npm list @keycloakify/keycloak-account-ui --parseable", {
|
|
||||||
cwd: pathDirname(buildContext.packageJsonFilePath)
|
|
||||||
})
|
|
||||||
.toString("utf8")
|
|
||||||
.trim();
|
|
||||||
|
|
||||||
const messagesDirPath = pathJoin(accountUiDirPath, "messages");
|
|
||||||
|
|
||||||
if (!fs.existsSync(messagesDirPath)) {
|
|
||||||
throw new Error(
|
|
||||||
`Please update @keycloakify/keycloak-account-ui to 25.0.4-rc.5 or later.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
transformCodebase({
|
transformCodebase({
|
||||||
srcDirPath: messagesDirPath,
|
srcDirPath: pathJoin(
|
||||||
destDirPath: pathJoin(
|
getThisCodebaseRootDirPath(),
|
||||||
getThemeTypeDirPath({ themeType: "account" }),
|
WELL_KNOWN_DIRECTORY_BASE_NAME.ACCOUNT_V1
|
||||||
"messages"
|
),
|
||||||
)
|
destDirPath: pathJoin(resourcesDirPath, "theme", "account-v1", "account")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +329,7 @@ export async function generateResourcesForMainTheme(params: {
|
|||||||
|
|
||||||
if (buildContext.implementedThemeTypes.account.isImplemented) {
|
if (buildContext.implementedThemeTypes.account.isImplemented) {
|
||||||
metaInfKeycloakThemes.themes.push({
|
metaInfKeycloakThemes.themes.push({
|
||||||
name: ACCOUNT_V1_THEME_NAME,
|
name: "account-v1",
|
||||||
types: ["account"]
|
types: ["account"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { BuildContext } from "../../shared/buildContext";
|
import type { BuildContext } from "../../shared/buildContext";
|
||||||
import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../shared/constants";
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { posix } from "path";
|
import { posix } from "path";
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export function replaceImportsInCssCode(params: {
|
|||||||
break inline_style_in_html;
|
break inline_style_in_html;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}${assetFileAbsoluteUrlPathname}")`;
|
return `url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}${assetFileAbsoluteUrlPathname}")`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const assetFileRelativeUrlPathname = posix.relative(
|
const assetFileRelativeUrlPathname = posix.relative(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../../shared/constants";
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../../shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildContext } from "../../../shared/buildContext";
|
import type { BuildContext } from "../../../shared/buildContext";
|
||||||
import * as nodePath from "path";
|
import * as nodePath from "path";
|
||||||
@ -85,13 +85,13 @@ export function replaceImportsInJsCode_vite(params: {
|
|||||||
fixedJsCode = replaceAll(
|
fixedJsCode = replaceAll(
|
||||||
fixedJsCode,
|
fixedJsCode,
|
||||||
`"${relativePathOfAssetFile}"`,
|
`"${relativePathOfAssetFile}"`,
|
||||||
`(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${relativePathOfAssetFile}")`
|
`(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${relativePathOfAssetFile}")`
|
||||||
);
|
);
|
||||||
|
|
||||||
fixedJsCode = replaceAll(
|
fixedJsCode = replaceAll(
|
||||||
fixedJsCode,
|
fixedJsCode,
|
||||||
`"${buildContext.urlPathname ?? "/"}${relativePathOfAssetFile}"`,
|
`"${buildContext.urlPathname ?? "/"}${relativePathOfAssetFile}"`,
|
||||||
`(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${relativePathOfAssetFile}")`
|
`(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${relativePathOfAssetFile}")`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../../shared/constants";
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../../shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildContext } from "../../../shared/buildContext";
|
import type { BuildContext } from "../../../shared/buildContext";
|
||||||
import * as nodePath from "path";
|
import * as nodePath from "path";
|
||||||
@ -90,7 +90,7 @@ export function replaceImportsInJsCode_webpack(params: {
|
|||||||
return "${u}";
|
return "${u}";
|
||||||
})()] = ${
|
})()] = ${
|
||||||
isArrowFunction ? `${e} =>` : `function(${e}) { return `
|
isArrowFunction ? `${e} =>` : `function(${e}) { return `
|
||||||
} "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${staticDir}${language}/"`
|
} "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${staticDir}${language}/"`
|
||||||
.replace(/\s+/g, " ")
|
.replace(/\s+/g, " ")
|
||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ export function replaceImportsInJsCode_webpack(params: {
|
|||||||
`[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`,
|
`[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`,
|
||||||
"g"
|
"g"
|
||||||
),
|
),
|
||||||
`window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${staticDir}`
|
`window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${staticDir}`
|
||||||
);
|
);
|
||||||
|
|
||||||
return { fixedJsCode };
|
return { fixedJsCode };
|
||||||
|
@ -14,8 +14,7 @@ import { assert, type Equals } from "tsafe/assert";
|
|||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import {
|
import {
|
||||||
VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES,
|
VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES,
|
||||||
BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME,
|
BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME
|
||||||
LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT
|
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import type { KeycloakVersionRange } from "./KeycloakVersionRange";
|
import type { KeycloakVersionRange } from "./KeycloakVersionRange";
|
||||||
import { exclude } from "tsafe";
|
import { exclude } from "tsafe";
|
||||||
@ -33,7 +32,6 @@ export type BuildContext = {
|
|||||||
extraThemeProperties: string[] | undefined;
|
extraThemeProperties: string[] | undefined;
|
||||||
groupId: string;
|
groupId: string;
|
||||||
artifactId: string;
|
artifactId: string;
|
||||||
loginThemeResourcesFromKeycloakVersion: string;
|
|
||||||
projectDirPath: string;
|
projectDirPath: string;
|
||||||
projectBuildDirPath: string;
|
projectBuildDirPath: string;
|
||||||
/** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
|
/** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
|
||||||
@ -85,7 +83,6 @@ export type BuildOptions = {
|
|||||||
extraThemeProperties?: string[];
|
extraThemeProperties?: string[];
|
||||||
artifactId?: string;
|
artifactId?: string;
|
||||||
groupId?: string;
|
groupId?: string;
|
||||||
loginThemeResourcesFromKeycloakVersion?: string;
|
|
||||||
keycloakifyBuildDirPath?: string;
|
keycloakifyBuildDirPath?: string;
|
||||||
kcContextExclusionsFtl?: string;
|
kcContextExclusionsFtl?: string;
|
||||||
startKeycloakOptions?: {
|
startKeycloakOptions?: {
|
||||||
@ -357,7 +354,6 @@ export function getBuildContext(params: {
|
|||||||
extraThemeProperties: z.array(z.string()).optional(),
|
extraThemeProperties: z.array(z.string()).optional(),
|
||||||
artifactId: z.string().optional(),
|
artifactId: z.string().optional(),
|
||||||
groupId: z.string().optional(),
|
groupId: z.string().optional(),
|
||||||
loginThemeResourcesFromKeycloakVersion: z.string().optional(),
|
|
||||||
keycloakifyBuildDirPath: z.string().optional(),
|
keycloakifyBuildDirPath: z.string().optional(),
|
||||||
kcContextExclusionsFtl: z.string().optional(),
|
kcContextExclusionsFtl: z.string().optional(),
|
||||||
startKeycloakOptions: zStartKeycloakOptions.optional()
|
startKeycloakOptions: zStartKeycloakOptions.optional()
|
||||||
@ -545,9 +541,6 @@ export function getBuildContext(params: {
|
|||||||
process.env.KEYCLOAKIFY_ARTIFACT_ID ??
|
process.env.KEYCLOAKIFY_ARTIFACT_ID ??
|
||||||
buildOptions.artifactId ??
|
buildOptions.artifactId ??
|
||||||
`${themeNames[0]}-keycloak-theme`,
|
`${themeNames[0]}-keycloak-theme`,
|
||||||
loginThemeResourcesFromKeycloakVersion:
|
|
||||||
buildOptions.loginThemeResourcesFromKeycloakVersion ??
|
|
||||||
LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT,
|
|
||||||
projectDirPath,
|
projectDirPath,
|
||||||
projectBuildDirPath,
|
projectBuildDirPath,
|
||||||
keycloakifyBuildDirPath: (() => {
|
keycloakifyBuildDirPath: (() => {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
export const KEYCLOAK_RESOURCES = "keycloak-resources";
|
export const WELL_KNOWN_DIRECTORY_BASE_NAME = {
|
||||||
export const RESOURCES_COMMON = "resources-common";
|
DOT_KEYCLOAKIFY: ".keycloakify",
|
||||||
export const LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 = "21.1.2";
|
RESOURCES_COMMON: "resources-common",
|
||||||
export const BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR = "dist";
|
DIST: "dist",
|
||||||
|
RESOURCES: "resources",
|
||||||
|
ACCOUNT_V1: "account-v1"
|
||||||
|
};
|
||||||
|
|
||||||
export const THEME_TYPES = ["login", "account"] as const;
|
export const THEME_TYPES = ["login", "account"] as const;
|
||||||
export const ACCOUNT_V1_THEME_NAME = "account-v1";
|
|
||||||
|
|
||||||
export type ThemeType = (typeof THEME_TYPES)[number];
|
export type ThemeType = (typeof THEME_TYPES)[number];
|
||||||
|
|
||||||
@ -71,5 +73,3 @@ export type AccountThemePageId = (typeof ACCOUNT_THEME_PAGE_IDS)[number];
|
|||||||
export const CONTAINER_NAME = "keycloak-keycloakify";
|
export const CONTAINER_NAME = "keycloak-keycloakify";
|
||||||
|
|
||||||
export const FALLBACK_LANGUAGE_TAG = "en";
|
export const FALLBACK_LANGUAGE_TAG = "en";
|
||||||
|
|
||||||
export const LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT = "24.0.4";
|
|
||||||
|
@ -1,44 +1,34 @@
|
|||||||
import {
|
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||||
downloadKeycloakStaticResources,
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../shared/constants";
|
||||||
type BuildContextLike as BuildContextLike_downloadKeycloakStaticResources
|
|
||||||
} from "./downloadKeycloakStaticResources";
|
|
||||||
import { join as pathJoin, relative as pathRelative } from "path";
|
|
||||||
import {
|
|
||||||
THEME_TYPES,
|
|
||||||
KEYCLOAK_RESOURCES,
|
|
||||||
LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1
|
|
||||||
} from "../shared/constants";
|
|
||||||
import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
|
import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { rmSync } from "../tools/fs.rmSync";
|
import { rmSync } from "../tools/fs.rmSync";
|
||||||
import type { BuildContext } from "./buildContext";
|
import type { BuildContext } from "./buildContext";
|
||||||
|
import { transformCodebase } from "../tools/transformCodebase";
|
||||||
|
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||||
|
|
||||||
export type BuildContextLike = BuildContextLike_downloadKeycloakStaticResources & {
|
export type BuildContextLike = {
|
||||||
loginThemeResourcesFromKeycloakVersion: string;
|
|
||||||
publicDirPath: string;
|
publicDirPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
assert<BuildContext extends BuildContextLike ? true : false>();
|
assert<BuildContext extends BuildContextLike ? true : false>();
|
||||||
|
|
||||||
export async function copyKeycloakResourcesToPublic(params: {
|
export function copyKeycloakResourcesToPublic(params: {
|
||||||
buildContext: BuildContextLike;
|
buildContext: BuildContextLike;
|
||||||
}) {
|
}) {
|
||||||
const { buildContext } = params;
|
const { buildContext } = params;
|
||||||
|
|
||||||
const destDirPath = pathJoin(buildContext.publicDirPath, KEYCLOAK_RESOURCES);
|
const destDirPath = pathJoin(
|
||||||
|
buildContext.publicDirPath,
|
||||||
|
WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY
|
||||||
|
);
|
||||||
|
|
||||||
const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
|
const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
|
||||||
|
|
||||||
const keycloakifyBuildinfoRaw = JSON.stringify(
|
const keycloakifyBuildinfoRaw = JSON.stringify(
|
||||||
{
|
{
|
||||||
destDirPath,
|
keycloakifyVersion: readThisNpmPackageVersion()
|
||||||
keycloakifyVersion: readThisNpmPackageVersion(),
|
|
||||||
buildContext: {
|
|
||||||
loginThemeResourcesFromKeycloakVersion: readThisNpmPackageVersion(),
|
|
||||||
cacheDirPath: pathRelative(destDirPath, buildContext.cacheDirPath),
|
|
||||||
fetchOptions: buildContext.fetchOptions
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
2
|
2
|
||||||
@ -62,35 +52,33 @@ export async function copyKeycloakResourcesToPublic(params: {
|
|||||||
|
|
||||||
rmSync(destDirPath, { force: true, recursive: true });
|
rmSync(destDirPath, { force: true, recursive: true });
|
||||||
|
|
||||||
|
// NOTE: To remove in a while, remove the legacy keycloak-resources directory
|
||||||
|
rmSync(pathJoin(pathDirname(destDirPath), "keycloak-resources"), {
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
|
||||||
fs.mkdirSync(destDirPath, { recursive: true });
|
fs.mkdirSync(destDirPath, { recursive: true });
|
||||||
|
|
||||||
fs.writeFileSync(pathJoin(destDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
fs.writeFileSync(pathJoin(destDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
||||||
|
|
||||||
for (const themeType of THEME_TYPES) {
|
transformCodebase({
|
||||||
await downloadKeycloakStaticResources({
|
srcDirPath: pathJoin(
|
||||||
keycloakVersion: (() => {
|
getThisCodebaseRootDirPath(),
|
||||||
switch (themeType) {
|
WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES
|
||||||
case "login":
|
),
|
||||||
return buildContext.loginThemeResourcesFromKeycloakVersion;
|
destDirPath
|
||||||
case "account":
|
|
||||||
return LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
themeType,
|
|
||||||
themeDirPath: destDirPath,
|
|
||||||
buildContext
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
pathJoin(destDirPath, "README.txt"),
|
pathJoin(destDirPath, "README.txt"),
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
[
|
[
|
||||||
"This is just a test folder that helps develop",
|
"This directory is only used in dev mode by Keycloakify",
|
||||||
"the login and register page without having to run a Keycloak container\n",
|
"It won't be included in your final build.",
|
||||||
"This directory will be automatically excluded from the final build."
|
"Do not modify anything in this directory.",
|
||||||
].join(" ")
|
].join("\n")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,338 +0,0 @@
|
|||||||
import { join as pathJoin, relative as pathRelative } from "path";
|
|
||||||
import { type BuildContext } from "../buildContext";
|
|
||||||
import { assert } from "tsafe/assert";
|
|
||||||
import { LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 } from "../constants";
|
|
||||||
import { downloadAndExtractArchive } from "../../tools/downloadAndExtractArchive";
|
|
||||||
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
|
||||||
import * as fsPr from "fs/promises";
|
|
||||||
|
|
||||||
export type BuildContextLike = {
|
|
||||||
cacheDirPath: string;
|
|
||||||
fetchOptions: BuildContext["fetchOptions"];
|
|
||||||
};
|
|
||||||
|
|
||||||
assert<BuildContext extends BuildContextLike ? true : false>();
|
|
||||||
|
|
||||||
export async function downloadKeycloakDefaultTheme(params: {
|
|
||||||
keycloakVersion: string;
|
|
||||||
buildContext: BuildContextLike;
|
|
||||||
}): Promise<{ defaultThemeDirPath: string }> {
|
|
||||||
const { keycloakVersion, buildContext } = params;
|
|
||||||
|
|
||||||
let kcNodeModulesKeepFilePaths: Set<string> | undefined = undefined;
|
|
||||||
let kcNodeModulesKeepFilePaths_lastAccountV1: Set<string> | undefined = undefined;
|
|
||||||
|
|
||||||
let areExtraAssetsFor24Copied = false;
|
|
||||||
|
|
||||||
const { extractedDirPath } = await downloadAndExtractArchive({
|
|
||||||
url: `https://repo1.maven.org/maven2/org/keycloak/keycloak-themes/${keycloakVersion}/keycloak-themes-${keycloakVersion}.jar`,
|
|
||||||
cacheDirPath: buildContext.cacheDirPath,
|
|
||||||
fetchOptions: buildContext.fetchOptions,
|
|
||||||
uniqueIdOfOnArchiveFile: "downloadKeycloakDefaultTheme",
|
|
||||||
onArchiveFile: async params => {
|
|
||||||
const fileRelativePath = pathRelative("theme", params.fileRelativePath);
|
|
||||||
|
|
||||||
if (fileRelativePath.startsWith("..")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_keycloak_v2: {
|
|
||||||
if (!fileRelativePath.startsWith(pathJoin("keycloak.v2"))) {
|
|
||||||
break skip_keycloak_v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { readFile, writeFile } = params;
|
|
||||||
|
|
||||||
last_account_v1_transformations: {
|
|
||||||
if (LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 !== keycloakVersion) {
|
|
||||||
break last_account_v1_transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_web_modules: {
|
|
||||||
if (
|
|
||||||
!fileRelativePath.startsWith(
|
|
||||||
pathJoin("keycloak", "common", "resources", "web_modules")
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break skip_web_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_lib: {
|
|
||||||
if (
|
|
||||||
!fileRelativePath.startsWith(
|
|
||||||
pathJoin("keycloak", "common", "resources", "lib")
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break skip_lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_node_modules: {
|
|
||||||
const nodeModulesRelativeDirPath = pathJoin(
|
|
||||||
"keycloak",
|
|
||||||
"common",
|
|
||||||
"resources",
|
|
||||||
"node_modules"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
|
|
||||||
break skip_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kcNodeModulesKeepFilePaths_lastAccountV1 === undefined) {
|
|
||||||
kcNodeModulesKeepFilePaths_lastAccountV1 = new Set([
|
|
||||||
pathJoin("patternfly", "dist", "css", "patternfly.min.css"),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"css",
|
|
||||||
"patternfly-additions.min.css"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Regular-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Bold-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Light-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Semibold-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"PatternFlyIcons-webfont.ttf"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"PatternFlyIcons-webfont.woff"
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileRelativeToNodeModulesPath = fileRelativePath.substring(
|
|
||||||
nodeModulesRelativeDirPath.length + 1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
kcNodeModulesKeepFilePaths_lastAccountV1.has(
|
|
||||||
fileRelativeToNodeModulesPath
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break skip_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
patch_account_css: {
|
|
||||||
if (
|
|
||||||
fileRelativePath !==
|
|
||||||
pathJoin("keycloak", "account", "resources", "css", "account.css")
|
|
||||||
) {
|
|
||||||
break patch_account_css;
|
|
||||||
}
|
|
||||||
|
|
||||||
await writeFile({
|
|
||||||
fileRelativePath,
|
|
||||||
modifiedData: Buffer.from(
|
|
||||||
(await readFile())
|
|
||||||
.toString("utf8")
|
|
||||||
.replace("top: -34px;", "top: -34px !important;"),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_extra_assets: {
|
|
||||||
if (keycloakVersion !== "24.0.4") {
|
|
||||||
break copy_extra_assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (areExtraAssetsFor24Copied) {
|
|
||||||
break copy_extra_assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
const extraAssetsDirPath = pathJoin(
|
|
||||||
getThisCodebaseRootDirPath(),
|
|
||||||
"src",
|
|
||||||
"bin",
|
|
||||||
"shared",
|
|
||||||
"downloadKeycloakDefaultTheme",
|
|
||||||
"extra-assets"
|
|
||||||
);
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
["webauthnAuthenticate.js", "passkeysConditionalAuth.js"].map(
|
|
||||||
async fileBasename =>
|
|
||||||
writeFile({
|
|
||||||
fileRelativePath: pathJoin(
|
|
||||||
"base",
|
|
||||||
"login",
|
|
||||||
"resources",
|
|
||||||
"js",
|
|
||||||
fileBasename
|
|
||||||
),
|
|
||||||
modifiedData: await fsPr.readFile(
|
|
||||||
pathJoin(extraAssetsDirPath, fileBasename)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_unused_resources: {
|
|
||||||
if (keycloakVersion !== "24.0.4") {
|
|
||||||
break skip_unused_resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_node_modules: {
|
|
||||||
const nodeModulesRelativeDirPath = pathJoin(
|
|
||||||
"keycloak",
|
|
||||||
"common",
|
|
||||||
"resources",
|
|
||||||
"node_modules"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
|
|
||||||
break skip_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kcNodeModulesKeepFilePaths === undefined) {
|
|
||||||
kcNodeModulesKeepFilePaths = new Set([
|
|
||||||
pathJoin("@patternfly", "patternfly", "patternfly.min.css"),
|
|
||||||
pathJoin("patternfly", "dist", "css", "patternfly.min.css"),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"css",
|
|
||||||
"patternfly-additions.min.css"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Regular-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Light-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Bold-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Bold-webfont.woff"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Bold-webfont.ttf"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"fontawesome-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"PatternFlyIcons-webfont.ttf"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"PatternFlyIcons-webfont.woff"
|
|
||||||
),
|
|
||||||
pathJoin(
|
|
||||||
"patternfly",
|
|
||||||
"dist",
|
|
||||||
"fonts",
|
|
||||||
"OpenSans-Semibold-webfont.woff2"
|
|
||||||
),
|
|
||||||
pathJoin("patternfly", "dist", "img", "bg-login.jpg"),
|
|
||||||
pathJoin("jquery", "dist", "jquery.min.js")
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileRelativeToNodeModulesPath = fileRelativePath.substring(
|
|
||||||
nodeModulesRelativeDirPath.length + 1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (kcNodeModulesKeepFilePaths.has(fileRelativeToNodeModulesPath)) {
|
|
||||||
break skip_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_vendor: {
|
|
||||||
if (
|
|
||||||
!fileRelativePath.startsWith(
|
|
||||||
pathJoin("keycloak", "common", "resources", "vendor")
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break skip_vendor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_rollup_config: {
|
|
||||||
if (
|
|
||||||
fileRelativePath !==
|
|
||||||
pathJoin("keycloak", "common", "resources", "rollup.config.js")
|
|
||||||
) {
|
|
||||||
break skip_rollup_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await writeFile({ fileRelativePath });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return { defaultThemeDirPath: extractedDirPath };
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
import { base64url } from "rfc4648";
|
|
||||||
import { returnSuccess, returnFailure } from "./webauthnAuthenticate.js";
|
|
||||||
|
|
||||||
export function initAuthenticate(input) {
|
|
||||||
// Check if WebAuthn is supported by this browser
|
|
||||||
if (!window.PublicKeyCredential) {
|
|
||||||
returnFailure(input.errmsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (input.isUserIdentified || typeof PublicKeyCredential.isConditionalMediationAvailable === "undefined") {
|
|
||||||
document.getElementById("kc-form-passkey-button").style.display = 'block';
|
|
||||||
} else {
|
|
||||||
tryAutoFillUI(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function doAuthenticate(input) {
|
|
||||||
// Check if WebAuthn is supported by this browser
|
|
||||||
if (!window.PublicKeyCredential) {
|
|
||||||
returnFailure(input.errmsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const publicKey = {
|
|
||||||
rpId : input.rpId,
|
|
||||||
challenge: base64url.parse(input.challenge, { loose: true })
|
|
||||||
};
|
|
||||||
|
|
||||||
publicKey.allowCredentials = !input.isUserIdentified ? [] : getAllowCredentials();
|
|
||||||
|
|
||||||
if (input.createTimeout !== 0) {
|
|
||||||
publicKey.timeout = input.createTimeout * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.userVerification !== 'not specified') {
|
|
||||||
publicKey.userVerification = input.userVerification;
|
|
||||||
}
|
|
||||||
|
|
||||||
return navigator.credentials.get({
|
|
||||||
publicKey: publicKey,
|
|
||||||
...input.additionalOptions
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function tryAutoFillUI(input) {
|
|
||||||
const isConditionalMediationAvailable = await PublicKeyCredential.isConditionalMediationAvailable();
|
|
||||||
if (isConditionalMediationAvailable) {
|
|
||||||
document.getElementById("kc-form-login").style.display = "block";
|
|
||||||
input.additionalOptions = { mediation: 'conditional'};
|
|
||||||
try {
|
|
||||||
const result = await doAuthenticate(input);
|
|
||||||
returnSuccess(result);
|
|
||||||
} catch (error) {
|
|
||||||
returnFailure(error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
document.getElementById("kc-form-passkey-button").style.display = 'block';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAllowCredentials() {
|
|
||||||
const allowCredentials = [];
|
|
||||||
const authnUse = document.forms['authn_select'].authn_use_chk;
|
|
||||||
if (authnUse !== undefined) {
|
|
||||||
if (authnUse.length === undefined) {
|
|
||||||
allowCredentials.push({
|
|
||||||
id: base64url.parse(authnUse.value, {loose: true}),
|
|
||||||
type: 'public-key',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
authnUse.forEach((entry) =>
|
|
||||||
allowCredentials.push({
|
|
||||||
id: base64url.parse(entry.value, {loose: true}),
|
|
||||||
type: 'public-key',
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allowCredentials;
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
import { base64url } from "rfc4648";
|
|
||||||
|
|
||||||
export async function authenticateByWebAuthn(input) {
|
|
||||||
if (!input.isUserIdentified) {
|
|
||||||
try {
|
|
||||||
const result = await doAuthenticate([], input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
|
|
||||||
returnSuccess(result);
|
|
||||||
} catch (error) {
|
|
||||||
returnFailure(error);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkAllowCredentials(input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkAllowCredentials(challenge, userVerification, rpId, createTimeout, errmsg) {
|
|
||||||
const allowCredentials = [];
|
|
||||||
const authnUse = document.forms['authn_select'].authn_use_chk;
|
|
||||||
if (authnUse !== undefined) {
|
|
||||||
if (authnUse.length === undefined) {
|
|
||||||
allowCredentials.push({
|
|
||||||
id: base64url.parse(authnUse.value, {loose: true}),
|
|
||||||
type: 'public-key',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
authnUse.forEach((entry) =>
|
|
||||||
allowCredentials.push({
|
|
||||||
id: base64url.parse(entry.value, {loose: true}),
|
|
||||||
type: 'public-key',
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const result = await doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg);
|
|
||||||
returnSuccess(result);
|
|
||||||
} catch (error) {
|
|
||||||
returnFailure(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg) {
|
|
||||||
// Check if WebAuthn is supported by this browser
|
|
||||||
if (!window.PublicKeyCredential) {
|
|
||||||
returnFailure(errmsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const publicKey = {
|
|
||||||
rpId : rpId,
|
|
||||||
challenge: base64url.parse(challenge, { loose: true })
|
|
||||||
};
|
|
||||||
|
|
||||||
if (createTimeout !== 0) {
|
|
||||||
publicKey.timeout = createTimeout * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowCredentials.length) {
|
|
||||||
publicKey.allowCredentials = allowCredentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userVerification !== 'not specified') {
|
|
||||||
publicKey.userVerification = userVerification;
|
|
||||||
}
|
|
||||||
|
|
||||||
return navigator.credentials.get({publicKey});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function returnSuccess(result) {
|
|
||||||
document.getElementById("clientDataJSON").value = base64url.stringify(new Uint8Array(result.response.clientDataJSON), { pad: false });
|
|
||||||
document.getElementById("authenticatorData").value = base64url.stringify(new Uint8Array(result.response.authenticatorData), { pad: false });
|
|
||||||
document.getElementById("signature").value = base64url.stringify(new Uint8Array(result.response.signature), { pad: false });
|
|
||||||
document.getElementById("credentialId").value = result.id;
|
|
||||||
if (result.response.userHandle) {
|
|
||||||
document.getElementById("userHandle").value = base64url.stringify(new Uint8Array(result.response.userHandle), { pad: false });
|
|
||||||
}
|
|
||||||
document.getElementById("webauth").submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function returnFailure(err) {
|
|
||||||
document.getElementById("error").value = err;
|
|
||||||
document.getElementById("webauth").submit();
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from "./downloadKeycloakDefaultTheme";
|
|
@ -1,53 +0,0 @@
|
|||||||
import { transformCodebase } from "../tools/transformCodebase";
|
|
||||||
import { join as pathJoin } from "path";
|
|
||||||
import {
|
|
||||||
downloadKeycloakDefaultTheme,
|
|
||||||
type BuildContextLike as BuildContextLike_downloadKeycloakDefaultTheme
|
|
||||||
} from "./downloadKeycloakDefaultTheme";
|
|
||||||
import { RESOURCES_COMMON, type ThemeType } from "./constants";
|
|
||||||
import type { BuildContext } from "./buildContext";
|
|
||||||
import { assert } from "tsafe/assert";
|
|
||||||
import { existsAsync } from "../tools/fs.existsAsync";
|
|
||||||
|
|
||||||
export type BuildContextLike = BuildContextLike_downloadKeycloakDefaultTheme & {};
|
|
||||||
|
|
||||||
assert<BuildContext extends BuildContextLike ? true : false>();
|
|
||||||
|
|
||||||
export async function downloadKeycloakStaticResources(params: {
|
|
||||||
themeType: ThemeType;
|
|
||||||
themeDirPath: string;
|
|
||||||
keycloakVersion: string;
|
|
||||||
buildContext: BuildContextLike;
|
|
||||||
}) {
|
|
||||||
const { themeType, themeDirPath, keycloakVersion, buildContext } = params;
|
|
||||||
|
|
||||||
const { defaultThemeDirPath } = await downloadKeycloakDefaultTheme({
|
|
||||||
keycloakVersion,
|
|
||||||
buildContext
|
|
||||||
});
|
|
||||||
|
|
||||||
const resourcesDirPath = pathJoin(themeDirPath, themeType, "resources");
|
|
||||||
|
|
||||||
repatriate_base_resources: {
|
|
||||||
const srcDirPath = pathJoin(defaultThemeDirPath, "base", themeType, "resources");
|
|
||||||
|
|
||||||
if (!(await existsAsync(srcDirPath))) {
|
|
||||||
break repatriate_base_resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath,
|
|
||||||
destDirPath: resourcesDirPath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath: pathJoin(defaultThemeDirPath, "keycloak", themeType, "resources"),
|
|
||||||
destDirPath: resourcesDirPath
|
|
||||||
});
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
srcDirPath: pathJoin(defaultThemeDirPath, "keycloak", "common", "resources"),
|
|
||||||
destDirPath: pathJoin(resourcesDirPath, RESOURCES_COMMON)
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,8 +1,7 @@
|
|||||||
import "keycloakify/tools/Object.fromEntries";
|
import "keycloakify/tools/Object.fromEntries";
|
||||||
import type { KcContext, Attribute } from "./KcContext";
|
import type { KcContext, Attribute } from "./KcContext";
|
||||||
import {
|
import {
|
||||||
RESOURCES_COMMON,
|
WELL_KNOWN_DIRECTORY_BASE_NAME,
|
||||||
KEYCLOAK_RESOURCES,
|
|
||||||
type LoginThemePageId
|
type LoginThemePageId
|
||||||
} from "keycloakify/bin/shared/constants";
|
} from "keycloakify/bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
@ -76,7 +75,7 @@ const attributesByName = Object.fromEntries(
|
|||||||
]).map(attribute => [attribute.name, attribute])
|
]).map(attribute => [attribute.name, attribute])
|
||||||
);
|
);
|
||||||
|
|
||||||
const resourcesPath = `${BASE_URL}${KEYCLOAK_RESOURCES}/login/resources`;
|
const resourcesPath = `${BASE_URL}${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY}/login`;
|
||||||
|
|
||||||
export const kcContextCommonMock: KcContext.Common = {
|
export const kcContextCommonMock: KcContext.Common = {
|
||||||
themeVersion: "0.0.0",
|
themeVersion: "0.0.0",
|
||||||
@ -86,7 +85,7 @@ export const kcContextCommonMock: KcContext.Common = {
|
|||||||
url: {
|
url: {
|
||||||
loginAction: "#",
|
loginAction: "#",
|
||||||
resourcesPath,
|
resourcesPath,
|
||||||
resourcesCommonPath: `${resourcesPath}/${RESOURCES_COMMON}`,
|
resourcesCommonPath: `${resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON}`,
|
||||||
loginRestartFlowUrl: "#",
|
loginRestartFlowUrl: "#",
|
||||||
loginUrl: "#",
|
loginUrl: "#",
|
||||||
ssoLoginInOtherTabsUrl: "#"
|
ssoLoginInOtherTabsUrl: "#"
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
|
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
|
||||||
import type { Plugin } from "vite";
|
import type { Plugin } from "vite";
|
||||||
import {
|
import {
|
||||||
BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR,
|
WELL_KNOWN_DIRECTORY_BASE_NAME,
|
||||||
KEYCLOAK_RESOURCES,
|
|
||||||
VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES
|
VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES
|
||||||
} from "../bin/shared/constants";
|
} from "../bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
@ -128,14 +127,8 @@ export function keycloakify(params: keycloakify.Params) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
copyKeycloakResourcesToPublic({ buildContext }),
|
||||||
copyKeycloakResourcesToPublic({
|
await generateKcGenTs({ buildContext });
|
||||||
buildContext
|
|
||||||
}),
|
|
||||||
generateKcGenTs({
|
|
||||||
buildContext
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
transform: (code, id) => {
|
transform: (code, id) => {
|
||||||
assert(command !== undefined);
|
assert(command !== undefined);
|
||||||
@ -174,7 +167,7 @@ export function keycloakify(params: keycloakify.Params) {
|
|||||||
`(`,
|
`(`,
|
||||||
`(window.kcContext === undefined || import.meta.env.MODE === "development")?`,
|
`(window.kcContext === undefined || import.meta.env.MODE === "development")?`,
|
||||||
`"${urlPathname ?? "/"}":`,
|
`"${urlPathname ?? "/"}":`,
|
||||||
`(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/")`,
|
`(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/")`,
|
||||||
`)`
|
`)`
|
||||||
].join("")
|
].join("")
|
||||||
);
|
);
|
||||||
@ -207,10 +200,13 @@ export function keycloakify(params: keycloakify.Params) {
|
|||||||
|
|
||||||
assert(buildDirPath !== undefined);
|
assert(buildDirPath !== undefined);
|
||||||
|
|
||||||
await rm(pathJoin(buildDirPath, KEYCLOAK_RESOURCES), {
|
await rm(
|
||||||
|
pathJoin(buildDirPath, WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY),
|
||||||
|
{
|
||||||
recursive: true,
|
recursive: true,
|
||||||
force: true
|
force: true
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} satisfies Plugin;
|
} satisfies Plugin;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { replaceImportsInJsCode_vite } from "keycloakify/bin/keycloakify/replace
|
|||||||
import { replaceImportsInJsCode_webpack } from "keycloakify/bin/keycloakify/replacers/replaceImportsInJsCode/webpack";
|
import { replaceImportsInJsCode_webpack } from "keycloakify/bin/keycloakify/replacers/replaceImportsInJsCode/webpack";
|
||||||
import { replaceImportsInCssCode } from "keycloakify/bin/keycloakify/replacers/replaceImportsInCssCode";
|
import { replaceImportsInCssCode } from "keycloakify/bin/keycloakify/replacers/replaceImportsInCssCode";
|
||||||
import { expect, it, describe } from "vitest";
|
import { expect, it, describe } from "vitest";
|
||||||
import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "keycloakify/bin/shared/constants";
|
import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "keycloakify/bin/shared/constants";
|
||||||
|
|
||||||
describe("js replacer - vite", () => {
|
describe("js replacer - vite", () => {
|
||||||
it("replaceImportsInJsCode_vite - 1", () => {
|
it("replaceImportsInJsCode_vite - 1", () => {
|
||||||
@ -87,13 +87,13 @@ describe("js replacer - vite", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fixedJsCodeExpected = `
|
const fixedJsCodeExpected = `
|
||||||
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
||||||
|
|
||||||
function __vite__mapDeps(indexes) {
|
function __vite__mapDeps(indexes) {
|
||||||
if (!__vite__mapDeps.viteFileDeps) {
|
if (!__vite__mapDeps.viteFileDeps) {
|
||||||
__vite__mapDeps.viteFileDeps = [
|
__vite__mapDeps.viteFileDeps = [
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/Login-dJpPRzM4.js"),
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/Login-dJpPRzM4.js"),
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/index-XwzrZ5Gu.js")
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/index-XwzrZ5Gu.js")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
||||||
@ -146,13 +146,13 @@ describe("js replacer - vite", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fixedJsCodeExpected = `
|
const fixedJsCodeExpected = `
|
||||||
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/foo/bar/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/foo/bar/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
||||||
|
|
||||||
function __vite__mapDeps(indexes) {
|
function __vite__mapDeps(indexes) {
|
||||||
if (!__vite__mapDeps.viteFileDeps) {
|
if (!__vite__mapDeps.viteFileDeps) {
|
||||||
__vite__mapDeps.viteFileDeps = [
|
__vite__mapDeps.viteFileDeps = [
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/foo/bar/Login-dJpPRzM4.js"),
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/foo/bar/Login-dJpPRzM4.js"),
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/foo/bar/index-XwzrZ5Gu.js")
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/foo/bar/index-XwzrZ5Gu.js")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
||||||
@ -205,13 +205,13 @@ describe("js replacer - vite", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fixedJsCodeExpected = `
|
const fixedJsCodeExpected = `
|
||||||
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
S=(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{
|
||||||
|
|
||||||
function __vite__mapDeps(indexes) {
|
function __vite__mapDeps(indexes) {
|
||||||
if (!__vite__mapDeps.viteFileDeps) {
|
if (!__vite__mapDeps.viteFileDeps) {
|
||||||
__vite__mapDeps.viteFileDeps = [
|
__vite__mapDeps.viteFileDeps = [
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/Login-dJpPRzM4.js"),
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/Login-dJpPRzM4.js"),
|
||||||
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/index-XwzrZ5Gu.js")
|
(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/index-XwzrZ5Gu.js")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
||||||
@ -267,13 +267,13 @@ describe("js replacer - webpack", () => {
|
|||||||
|
|
||||||
const fixedJsCodeExpected = `
|
const fixedJsCodeExpected = `
|
||||||
function f() {
|
function f() {
|
||||||
return window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/js/" + ({}[e] || e) + "." + {
|
return window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/js/" + ({}[e] || e) + "." + {
|
||||||
3: "0664cdc0"
|
3: "0664cdc0"
|
||||||
}[e] + ".chunk.js"
|
}[e] + ".chunk.js"
|
||||||
}
|
}
|
||||||
|
|
||||||
function sameAsF() {
|
function sameAsF() {
|
||||||
return window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/js/" + ({}[e] || e) + "." + {
|
return window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/js/" + ({}[e] || e) + "." + {
|
||||||
3: "0664cdc0"
|
3: "0664cdc0"
|
||||||
}[e] + ".chunk.js"
|
}[e] + ".chunk.js"
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ describe("js replacer - webpack", () => {
|
|||||||
}
|
}
|
||||||
return "u";
|
return "u";
|
||||||
})()] = function(e) {
|
})()] = function(e) {
|
||||||
return "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/js/" + e + "." + {
|
return "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/js/" + e + "." + {
|
||||||
147: "6c5cee76",
|
147: "6c5cee76",
|
||||||
787: "8da10fcf",
|
787: "8da10fcf",
|
||||||
922: "be170a73"
|
922: "be170a73"
|
||||||
@ -305,7 +305,7 @@ describe("js replacer - webpack", () => {
|
|||||||
}
|
}
|
||||||
return "miniCssF";
|
return "miniCssF";
|
||||||
})()] = function(e) {
|
})()] = function(e) {
|
||||||
return "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/css/" + e + "." + {
|
return "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/css/" + e + "." + {
|
||||||
164:"dcfd7749",
|
164:"dcfd7749",
|
||||||
908:"67c9ed2c"
|
908:"67c9ed2c"
|
||||||
} [e] + ".chunk.css"
|
} [e] + ".chunk.css"
|
||||||
@ -320,7 +320,7 @@ describe("js replacer - webpack", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return "u";
|
return "u";
|
||||||
})()] = e => "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/js/"+e+"."+{69:"4f205f87",128:"49264537",453:"b2fed72e",482:"f0106901"}[e]+".chunk.js"
|
})()] = e => "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/js/"+e+"."+{69:"4f205f87",128:"49264537",453:"b2fed72e",482:"f0106901"}[e]+".chunk.js"
|
||||||
|
|
||||||
t[(function(){
|
t[(function(){
|
||||||
var pd = Object.getOwnPropertyDescriptor(t, "p");
|
var pd = Object.getOwnPropertyDescriptor(t, "p");
|
||||||
@ -331,7 +331,7 @@ describe("js replacer - webpack", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return "miniCssF";
|
return "miniCssF";
|
||||||
})()] = e => "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/static/css/"+e+"."+{164:"dcfd7749",908:"67c9ed2c"}[e]+".chunk.css"
|
})()] = e => "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/static/css/"+e+"."+{164:"dcfd7749",908:"67c9ed2c"}[e]+".chunk.css"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
|
expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
|
||||||
@ -495,15 +495,15 @@ describe("css replacer", () => {
|
|||||||
|
|
||||||
const fixedCssCodeExpected = `
|
const fixedCssCodeExpected = `
|
||||||
.my-div {
|
.my-div {
|
||||||
background: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/background.png") no-repeat center center;
|
background: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/background.png") no-repeat center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-div2 {
|
.my-div2 {
|
||||||
background: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/background.png") repeat center center;
|
background: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/background.png") repeat center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-div3 {
|
.my-div3 {
|
||||||
background-image: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/media/something.svg");
|
background-image: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/media/something.svg");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -533,15 +533,15 @@ describe("css replacer", () => {
|
|||||||
|
|
||||||
const fixedCssCodeExpected = `
|
const fixedCssCodeExpected = `
|
||||||
.my-div {
|
.my-div {
|
||||||
background: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/background.png") no-repeat center center;
|
background: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/background.png") no-repeat center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-div2 {
|
.my-div2 {
|
||||||
background: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/background.png") repeat center center;
|
background: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/background.png") repeat center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.my-div3 {
|
.my-div3 {
|
||||||
background-image: url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/assets/media/something.svg");
|
background-image: url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/assets/media/something.svg");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user