keycloakify 10.0.0-rc.17 → 10.0.0-rc.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PUBLIC_URL.js.map +1 -1
- package/account/Template.js +5 -5
- package/account/Template.js.map +1 -1
- package/account/i18n/i18n.js +37 -29
- package/account/i18n/i18n.js.map +1 -1
- package/account/kcContext/KcContext.js.map +1 -1
- package/account/kcContext/createGetKcContext.js +20 -15
- package/account/kcContext/createGetKcContext.js.map +1 -1
- package/account/kcContext/getKcContext.js.map +1 -1
- package/account/kcContext/getKcContextFromWindow.d.ts +3 -1
- package/account/kcContext/getKcContextFromWindow.js.map +1 -1
- package/account/kcContext/kcContextMocks.js +148 -144
- package/account/kcContext/kcContextMocks.js.map +1 -1
- package/account/lib/useGetClassName.js +14 -14
- package/account/lib/useGetClassName.js.map +1 -1
- package/account/pages/Account.js +1 -1
- package/account/pages/Account.js.map +1 -1
- package/account/pages/Password.js +7 -7
- package/account/pages/Password.js.map +1 -1
- package/account/pages/Totp.js +4 -4
- package/account/pages/Totp.js.map +1 -1
- package/bin/main.js +2066 -2165
- package/bin/shared/constants.d.ts +1 -0
- package/bin/shared/constants.js +4 -3
- package/bin/shared/constants.js.map +1 -1
- package/lib/isStorybook.js +2 -1
- package/lib/isStorybook.js.map +1 -1
- package/lib/useGetClassName.js.map +1 -1
- package/login/Template.js +13 -13
- package/login/Template.js.map +1 -1
- package/login/UserProfileFormFields.js +43 -41
- package/login/UserProfileFormFields.js.map +1 -1
- package/login/i18n/baseMessages/ca.d.ts +1 -1
- package/login/i18n/baseMessages/ca.js +1 -1
- package/login/i18n/baseMessages/el.d.ts +0 -1
- package/login/i18n/baseMessages/el.js +0 -1
- package/login/i18n/baseMessages/el.js.map +1 -1
- package/login/i18n/baseMessages/en.d.ts +1 -1
- package/login/i18n/baseMessages/en.js +1 -1
- package/login/i18n/baseMessages/es.d.ts +1 -1
- package/login/i18n/baseMessages/es.js +1 -1
- package/login/i18n/baseMessages/fa.d.ts +0 -1
- package/login/i18n/baseMessages/fa.js +0 -1
- package/login/i18n/baseMessages/fa.js.map +1 -1
- package/login/i18n/baseMessages/hu.d.ts +1 -1
- package/login/i18n/baseMessages/hu.js +1 -1
- package/login/i18n/baseMessages/index.d.ts +1 -2
- package/login/i18n/baseMessages/zh-CN.d.ts +1 -1
- package/login/i18n/baseMessages/zh-CN.js +1 -1
- package/login/i18n/i18n.js +39 -31
- package/login/i18n/i18n.js.map +1 -1
- package/login/kcContext/KcContext.js.map +1 -1
- package/login/kcContext/createGetKcContext.js +30 -22
- package/login/kcContext/createGetKcContext.js.map +1 -1
- package/login/kcContext/getKcContext.js.map +1 -1
- package/login/kcContext/getKcContextFromWindow.d.ts +3 -1
- package/login/kcContext/getKcContextFromWindow.js.map +1 -1
- package/login/kcContext/kcContextMocks.js +233 -231
- package/login/kcContext/kcContextMocks.js.map +1 -1
- package/login/lib/useDownloadTerms.js.map +1 -1
- package/login/lib/useGetClassName.js +112 -112
- package/login/lib/useGetClassName.js.map +1 -1
- package/login/lib/useUserProfileForm.js +181 -181
- package/login/lib/useUserProfileForm.js.map +1 -1
- package/login/pages/DeleteAccountConfirm.js +5 -1
- package/login/pages/DeleteAccountConfirm.js.map +1 -1
- package/login/pages/FrontchannelLogout.js +1 -1
- package/login/pages/FrontchannelLogout.js.map +1 -1
- package/login/pages/Login.js.map +1 -1
- package/login/pages/LoginRecoveryAuthnCodeConfig.js +3 -3
- package/login/pages/LoginRecoveryAuthnCodeConfig.js.map +1 -1
- package/login/pages/LoginResetPassword.js.map +1 -1
- package/login/pages/LoginUsername.js.map +1 -1
- package/login/pages/WebauthnAuthenticate.js +11 -8
- package/login/pages/WebauthnAuthenticate.js.map +1 -1
- package/login/pages/WebauthnRegister.js +7 -7
- package/login/pages/WebauthnRegister.js.map +1 -1
- package/package.json +230 -226
- package/src/PUBLIC_URL.ts +4 -1
- package/src/account/Template.tsx +5 -5
- package/src/account/TemplateProps.ts +4 -1
- package/src/account/i18n/i18n.tsx +40 -30
- package/src/account/kcContext/KcContext.ts +4 -1
- package/src/account/kcContext/createGetKcContext.ts +48 -22
- package/src/account/kcContext/getKcContext.ts +3 -1
- package/src/account/kcContext/getKcContextFromWindow.ts +6 -2
- package/src/account/kcContext/kcContextMocks.ts +164 -160
- package/src/account/lib/useGetClassName.ts +15 -14
- package/src/account/pages/Account.tsx +2 -2
- package/src/account/pages/Password.tsx +8 -8
- package/src/account/pages/Totp.tsx +4 -6
- package/src/bin/copy-keycloak-resources-to-public.ts +2 -2
- package/src/bin/download-keycloak-default-theme.ts +30 -8
- package/src/bin/eject-page.ts +48 -11
- package/src/bin/initialize-email-theme.ts +25 -17
- package/src/bin/keycloakify/buildJars/buildJar.ts +179 -104
- package/src/bin/keycloakify/buildJars/buildJars.ts +35 -16
- package/src/bin/keycloakify/buildJars/extensionVersions.ts +2 -1
- package/src/bin/keycloakify/buildJars/generatePom.ts +11 -3
- package/src/bin/keycloakify/buildJars/getKeycloakVersionRangeForJar.ts +33 -8
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +49 -12
- package/src/bin/keycloakify/generateSrcMainResources/bringInAccountV1.ts +29 -18
- package/src/bin/keycloakify/generateSrcMainResources/generateMessageProperties.ts +35 -12
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResources.ts +3 -1
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForMainTheme.ts +86 -41
- package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForThemeVariant.ts +39 -15
- package/src/bin/keycloakify/generateSrcMainResources/readExtraPageNames.ts +21 -7
- package/src/bin/keycloakify/generateSrcMainResources/readFieldNameUsage.ts +34 -7
- package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +19 -5
- package/src/bin/keycloakify/keycloakify.ts +28 -9
- package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +24 -5
- package/src/bin/keycloakify/replacers/replaceImportsInInlineCssCode.ts +6 -2
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +6 -3
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +24 -6
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +49 -11
- package/src/bin/main.ts +78 -41
- package/src/bin/shared/KeycloakVersionRange.ts +3 -1
- package/src/bin/shared/buildOptions.ts +70 -43
- package/src/bin/shared/constants.ts +4 -2
- package/src/bin/shared/copyKeycloakResourcesToPublic.ts +27 -13
- package/src/bin/shared/downloadKeycloakDefaultTheme.ts +161 -218
- package/src/bin/shared/downloadKeycloakStaticResources.ts +25 -21
- package/src/bin/shared/getJarFileBasename.ts +3 -1
- package/src/bin/shared/getThemeSrcDirPath.ts +5 -2
- package/src/bin/shared/metaInfKeycloakThemes.ts +35 -8
- package/src/bin/shared/promptKeycloakVersion.ts +33 -14
- package/src/bin/start-keycloak/index.ts +1 -0
- package/src/bin/start-keycloak/myrealm-realm-23.json +2142 -0
- package/src/bin/start-keycloak/myrealm-realm-24.json +2318 -0
- package/src/bin/start-keycloak/start-keycloak.ts +467 -0
- package/src/bin/tools/SemVer.ts +32 -13
- package/src/bin/tools/String.prototype.replaceAll.ts +9 -2
- package/src/bin/tools/crawl.ts +4 -1
- package/src/bin/tools/crc32.ts +42 -24
- package/src/bin/tools/downloadAndExtractArchive/downloadAndExtractArchive.ts +262 -0
- package/src/bin/tools/downloadAndExtractArchive/fetchProxyOptions.ts +96 -0
- package/src/bin/tools/downloadAndExtractArchive/index.ts +1 -0
- package/src/bin/tools/extractArchive.ts +120 -0
- package/src/bin/tools/fetchProxyOptions.ts +31 -8
- package/src/bin/tools/getAbsoluteAndInOsFormatPath.ts +10 -2
- package/src/bin/tools/getNpmWorkspaceRootDirPath.ts +18 -5
- package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +8 -2
- package/src/bin/tools/octokit-addons/listTags.ts +15 -4
- package/src/bin/tools/partitionPromiseSettledResults.ts +12 -3
- package/src/bin/tools/readThisNpmPackageVersion.ts +5 -1
- package/src/bin/tools/transformCodebase.ts +29 -10
- package/src/bin/tools/trimIndent.ts +4 -1
- package/src/lib/isStorybook.ts +3 -1
- package/src/lib/useGetClassName.ts +12 -3
- package/src/login/Template.tsx +14 -14
- package/src/login/TemplateProps.ts +4 -1
- package/src/login/UserProfileFormFields.tsx +44 -42
- package/src/login/i18n/baseMessages/ca.ts +1 -1
- package/src/login/i18n/baseMessages/el.ts +0 -1
- package/src/login/i18n/baseMessages/en.ts +1 -1
- package/src/login/i18n/baseMessages/es.ts +1 -1
- package/src/login/i18n/baseMessages/fa.ts +0 -1
- package/src/login/i18n/baseMessages/hu.ts +1 -1
- package/src/login/i18n/baseMessages/zh-CN.ts +1 -1
- package/src/login/i18n/i18n.tsx +42 -32
- package/src/login/kcContext/KcContext.ts +8 -2
- package/src/login/kcContext/createGetKcContext.ts +84 -37
- package/src/login/kcContext/getKcContext.ts +3 -1
- package/src/login/kcContext/getKcContextFromWindow.ts +6 -2
- package/src/login/kcContext/kcContextMocks.ts +339 -325
- package/src/login/lib/useDownloadTerms.ts +6 -4
- package/src/login/lib/useGetClassName.ts +119 -112
- package/src/login/lib/useUserProfileForm.tsx +219 -205
- package/src/login/pages/DeleteAccountConfirm.tsx +9 -3
- package/src/login/pages/FrontchannelLogout.tsx +1 -1
- package/src/login/pages/Login.tsx +2 -2
- package/src/login/pages/LoginRecoveryAuthnCodeConfig.tsx +3 -3
- package/src/login/pages/LoginResetPassword.tsx +2 -2
- package/src/login/pages/LoginUsername.tsx +2 -2
- package/src/login/pages/WebauthnAuthenticate.tsx +11 -8
- package/src/login/pages/WebauthnRegister.tsx +7 -7
- package/src/tools/AndByDiscriminatingKey.ts +12 -6
- package/src/tools/Array.prototype.every.ts +4 -1
- package/src/tools/LazyOrNot.ts +3 -1
- package/src/tools/clsx.ts +7 -1
- package/src/tools/deepAssign.ts +15 -8
- package/src/tools/deepClone.ts +3 -1
- package/src/tools/formatNumber.ts +4 -1
- package/src/tools/useConstCallback.ts +3 -1
- package/src/tools/useInsertLinkTags.ts +20 -7
- package/src/tools/useInsertScriptTags.ts +7 -2
- package/src/tools/useSetClassName.ts +4 -1
- package/src/vite-plugin/vite-plugin.ts +45 -21
- package/tools/Array.prototype.every.js +2 -1
- package/tools/Array.prototype.every.js.map +1 -1
- package/tools/clsx.js.map +1 -1
- package/tools/deepAssign.js +9 -7
- package/tools/deepAssign.js.map +1 -1
- package/tools/deepClone.js.map +1 -1
- package/tools/formatNumber.js.map +1 -1
- package/tools/useConstCallback.js.map +1 -1
- package/tools/useInsertLinkTags.js +5 -4
- package/tools/useInsertLinkTags.js.map +1 -1
- package/tools/useInsertScriptTags.js +5 -2
- package/tools/useInsertScriptTags.js.map +1 -1
- package/tools/useSetClassName.js.map +1 -1
- package/vite-plugin/index.js +975 -1651
- package/src/bin/shared/downloadAndUnzip.ts +0 -203
- package/src/bin/start-keycloak.ts +0 -309
- package/src/bin/tools/unzip.ts +0 -141
package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForThemeVariant.ts
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
import { join as pathJoin, extname as pathExtname, sep as pathSep } from "path";
|
2
2
|
import { transformCodebase } from "../../tools/transformCodebase";
|
3
3
|
import type { BuildOptions } from "../../shared/buildOptions";
|
4
|
-
import {
|
4
|
+
import {
|
5
|
+
readMetaInfKeycloakThemes,
|
6
|
+
writeMetaInfKeycloakThemes
|
7
|
+
} from "../../shared/metaInfKeycloakThemes";
|
5
8
|
import { assert } from "tsafe/assert";
|
6
9
|
|
7
10
|
export type BuildOptionsLike = {
|
@@ -10,20 +13,37 @@ export type BuildOptionsLike = {
|
|
10
13
|
|
11
14
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
12
15
|
|
13
|
-
export function generateSrcMainResourcesForThemeVariant(params: {
|
16
|
+
export function generateSrcMainResourcesForThemeVariant(params: {
|
17
|
+
themeName: string;
|
18
|
+
themeVariantName: string;
|
19
|
+
buildOptions: BuildOptionsLike;
|
20
|
+
}) {
|
14
21
|
const { themeName, themeVariantName, buildOptions } = params;
|
15
22
|
|
16
|
-
const mainThemeDirPath = pathJoin(
|
23
|
+
const mainThemeDirPath = pathJoin(
|
24
|
+
buildOptions.keycloakifyBuildDirPath,
|
25
|
+
"src",
|
26
|
+
"main",
|
27
|
+
"resources",
|
28
|
+
"theme",
|
29
|
+
themeName
|
30
|
+
);
|
17
31
|
|
18
32
|
transformCodebase({
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if (
|
33
|
+
srcDirPath: mainThemeDirPath,
|
34
|
+
destDirPath: pathJoin(mainThemeDirPath, "..", themeVariantName),
|
35
|
+
transformSourceCode: ({ fileRelativePath, sourceCode }) => {
|
36
|
+
if (
|
37
|
+
pathExtname(fileRelativePath) === ".ftl" &&
|
38
|
+
fileRelativePath.split(pathSep).length === 2
|
39
|
+
) {
|
23
40
|
const modifiedSourceCode = Buffer.from(
|
24
41
|
Buffer.from(sourceCode)
|
25
42
|
.toString("utf-8")
|
26
|
-
.replace(
|
43
|
+
.replace(
|
44
|
+
`out["themeName"] = "${themeName}";`,
|
45
|
+
`out["themeName"] = "${themeVariantName}";`
|
46
|
+
),
|
27
47
|
"utf8"
|
28
48
|
);
|
29
49
|
|
@@ -32,25 +52,29 @@ export function generateSrcMainResourcesForThemeVariant(params: { themeName: str
|
|
32
52
|
return { modifiedSourceCode };
|
33
53
|
}
|
34
54
|
|
35
|
-
return {
|
55
|
+
return { modifiedSourceCode: sourceCode };
|
36
56
|
}
|
37
57
|
});
|
38
58
|
|
39
59
|
{
|
40
|
-
const updatedMetaInfKeycloakThemes = readMetaInfKeycloakThemes({
|
60
|
+
const updatedMetaInfKeycloakThemes = readMetaInfKeycloakThemes({
|
61
|
+
keycloakifyBuildDirPath: buildOptions.keycloakifyBuildDirPath
|
62
|
+
});
|
41
63
|
|
42
64
|
updatedMetaInfKeycloakThemes.themes.push({
|
43
|
-
|
44
|
-
|
45
|
-
const theme = updatedMetaInfKeycloakThemes.themes.find(
|
65
|
+
name: themeVariantName,
|
66
|
+
types: (() => {
|
67
|
+
const theme = updatedMetaInfKeycloakThemes.themes.find(
|
68
|
+
({ name }) => name === themeName
|
69
|
+
);
|
46
70
|
assert(theme !== undefined);
|
47
71
|
return theme.types;
|
48
72
|
})()
|
49
73
|
});
|
50
74
|
|
51
75
|
writeMetaInfKeycloakThemes({
|
52
|
-
|
53
|
-
|
76
|
+
keycloakifyBuildDirPath: buildOptions.keycloakifyBuildDirPath,
|
77
|
+
metaInfKeycloakThemes: updatedMetaInfKeycloakThemes
|
54
78
|
});
|
55
79
|
}
|
56
80
|
}
|
@@ -3,17 +3,26 @@ import { id } from "tsafe/id";
|
|
3
3
|
import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
4
4
|
import * as fs from "fs";
|
5
5
|
import { join as pathJoin } from "path";
|
6
|
-
import {
|
7
|
-
|
8
|
-
|
6
|
+
import {
|
7
|
+
type ThemeType,
|
8
|
+
accountThemePageIds,
|
9
|
+
loginThemePageIds
|
10
|
+
} from "../../shared/constants";
|
11
|
+
|
12
|
+
export function readExtraPagesNames(params: {
|
13
|
+
themeSrcDirPath: string;
|
14
|
+
themeType: ThemeType;
|
15
|
+
}): string[] {
|
9
16
|
const { themeSrcDirPath, themeType } = params;
|
10
17
|
|
11
18
|
const filePaths = crawl({
|
12
|
-
|
13
|
-
|
19
|
+
dirPath: pathJoin(themeSrcDirPath, themeType),
|
20
|
+
returnedPathsType: "absolute"
|
14
21
|
}).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
15
22
|
|
16
|
-
const candidateFilePaths = filePaths.filter(filePath =>
|
23
|
+
const candidateFilePaths = filePaths.filter(filePath =>
|
24
|
+
/kcContext\.[^.]+$/.test(filePath)
|
25
|
+
);
|
17
26
|
|
18
27
|
if (candidateFilePaths.length === 0) {
|
19
28
|
candidateFilePaths.push(...filePaths);
|
@@ -24,7 +33,12 @@ export function readExtraPagesNames(params: { themeSrcDirPath: string; themeType
|
|
24
33
|
for (const candidateFilPath of candidateFilePaths) {
|
25
34
|
const rawSourceFile = fs.readFileSync(candidateFilPath).toString("utf8");
|
26
35
|
|
27
|
-
extraPages.push(
|
36
|
+
extraPages.push(
|
37
|
+
...Array.from(
|
38
|
+
rawSourceFile.matchAll(/["']?pageId["']?\s*:\s*["']([^.]+.ftl)["']/g),
|
39
|
+
m => m[1]
|
40
|
+
)
|
41
|
+
);
|
28
42
|
}
|
29
43
|
|
30
44
|
return extraPages.reduce(...removeDuplicates<string>()).filter(pageId => {
|
@@ -5,13 +5,22 @@ import type { ThemeType } from "../../shared/constants";
|
|
5
5
|
import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
|
6
6
|
|
7
7
|
/** Assumes the theme type exists */
|
8
|
-
export function readFieldNameUsage(params: {
|
8
|
+
export function readFieldNameUsage(params: {
|
9
|
+
themeSrcDirPath: string;
|
10
|
+
themeType: ThemeType;
|
11
|
+
}): string[] {
|
9
12
|
const { themeSrcDirPath, themeType } = params;
|
10
13
|
|
11
14
|
const fieldNames = new Set<string>();
|
12
15
|
|
13
|
-
for (const srcDirPath of [
|
14
|
-
|
16
|
+
for (const srcDirPath of [
|
17
|
+
pathJoin(getThisCodebaseRootDirPath(), "src", themeType),
|
18
|
+
pathJoin(themeSrcDirPath, themeType)
|
19
|
+
]) {
|
20
|
+
const filePaths = crawl({
|
21
|
+
dirPath: srcDirPath,
|
22
|
+
returnedPathsType: "absolute"
|
23
|
+
}).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
15
24
|
|
16
25
|
for (const filePath of filePaths) {
|
17
26
|
const rawSourceFile = fs.readFileSync(filePath).toString("utf8");
|
@@ -20,7 +29,13 @@ export function readFieldNameUsage(params: { themeSrcDirPath: string; themeType:
|
|
20
29
|
continue;
|
21
30
|
}
|
22
31
|
|
23
|
-
for (const functionName of [
|
32
|
+
for (const functionName of [
|
33
|
+
"printIfExists",
|
34
|
+
"existsError",
|
35
|
+
"get",
|
36
|
+
"exists",
|
37
|
+
"getFirstError"
|
38
|
+
] as const) {
|
24
39
|
if (!rawSourceFile.includes(functionName)) {
|
25
40
|
continue;
|
26
41
|
}
|
@@ -40,9 +55,21 @@ export function readFieldNameUsage(params: { themeSrcDirPath: string; themeType:
|
|
40
55
|
return part
|
41
56
|
.split(",")
|
42
57
|
.map(a => a.trim())
|
43
|
-
.filter((...[, i]) =>
|
44
|
-
|
45
|
-
|
58
|
+
.filter((...[, i]) =>
|
59
|
+
functionName !== "printIfExists" ? true : i === 0
|
60
|
+
)
|
61
|
+
.filter(
|
62
|
+
a =>
|
63
|
+
a.startsWith('"') ||
|
64
|
+
a.startsWith("'") ||
|
65
|
+
a.startsWith("`")
|
66
|
+
)
|
67
|
+
.filter(
|
68
|
+
a =>
|
69
|
+
a.endsWith('"') ||
|
70
|
+
a.endsWith("'") ||
|
71
|
+
a.endsWith("`")
|
72
|
+
)
|
46
73
|
.map(a => a.slice(1).slice(0, -1));
|
47
74
|
})
|
48
75
|
.flat()
|
@@ -1,5 +1,9 @@
|
|
1
1
|
import * as fs from "fs";
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
join as pathJoin,
|
4
|
+
relative as pathRelative,
|
5
|
+
basename as pathBasename
|
6
|
+
} from "path";
|
3
7
|
import { assert } from "tsafe/assert";
|
4
8
|
import type { BuildOptions } from "../shared/buildOptions";
|
5
9
|
import { accountV1ThemeName } from "../shared/constants";
|
@@ -27,7 +31,10 @@ export function generateStartKeycloakTestingContainer(params: {
|
|
27
31
|
const themeRelativeDirPath = pathJoin("src", "main", "resources", "theme");
|
28
32
|
|
29
33
|
fs.writeFileSync(
|
30
|
-
pathJoin(
|
34
|
+
pathJoin(
|
35
|
+
buildOptions.keycloakifyBuildDirPath,
|
36
|
+
generateStartKeycloakTestingContainer.basename
|
37
|
+
),
|
31
38
|
Buffer.from(
|
32
39
|
[
|
33
40
|
"#!/usr/bin/env bash",
|
@@ -45,9 +52,16 @@ export function generateStartKeycloakTestingContainer(params: {
|
|
45
52
|
"$(pwd)",
|
46
53
|
pathRelative(buildOptions.keycloakifyBuildDirPath, jarFilePath)
|
47
54
|
)}":"/opt/keycloak/providers/${pathBasename(jarFilePath)}" \\`,
|
48
|
-
[
|
55
|
+
[
|
56
|
+
...(doesImplementAccountTheme ? [accountV1ThemeName] : []),
|
57
|
+
...buildOptions.themeNames
|
58
|
+
].map(
|
49
59
|
themeName =>
|
50
|
-
` -v "${pathJoin(
|
60
|
+
` -v "${pathJoin(
|
61
|
+
"$(pwd)",
|
62
|
+
themeRelativeDirPath,
|
63
|
+
themeName
|
64
|
+
).replace(/\\/g, "/")}":"/opt/keycloak/themes/${themeName}":rw \\`
|
51
65
|
),
|
52
66
|
` -it quay.io/keycloak/keycloak:${keycloakVersion} \\`,
|
53
67
|
` start-dev`,
|
@@ -55,6 +69,6 @@ export function generateStartKeycloakTestingContainer(params: {
|
|
55
69
|
].join("\n"),
|
56
70
|
"utf8"
|
57
71
|
),
|
58
|
-
{
|
72
|
+
{ mode: 0o755 }
|
59
73
|
);
|
60
74
|
}
|
@@ -15,7 +15,9 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
15
15
|
let commandOutput: Buffer | undefined = undefined;
|
16
16
|
|
17
17
|
try {
|
18
|
-
commandOutput = child_process.execSync("mvn --version", {
|
18
|
+
commandOutput = child_process.execSync("mvn --version", {
|
19
|
+
stdio: ["ignore", "pipe", "ignore"]
|
20
|
+
});
|
19
21
|
} catch {}
|
20
22
|
|
21
23
|
if (commandOutput?.toString("utf8").includes("Apache Maven")) {
|
@@ -34,7 +36,11 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
34
36
|
}
|
35
37
|
})();
|
36
38
|
|
37
|
-
console.log(
|
39
|
+
console.log(
|
40
|
+
`${chalk.red("Apache Maven required.")} Install it with \`${chalk.bold(
|
41
|
+
installationCommand
|
42
|
+
)}\` (for example)`
|
43
|
+
);
|
38
44
|
|
39
45
|
process.exit(1);
|
40
46
|
}
|
@@ -46,7 +52,12 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
46
52
|
console.log(
|
47
53
|
[
|
48
54
|
chalk.cyan(`keycloakify v${readThisNpmPackageVersion()}`),
|
49
|
-
chalk.green(
|
55
|
+
chalk.green(
|
56
|
+
`Building the keycloak theme in .${pathSep}${pathRelative(
|
57
|
+
process.cwd(),
|
58
|
+
buildOptions.keycloakifyBuildDirPath
|
59
|
+
)} ...`
|
60
|
+
)
|
50
61
|
].join(" ")
|
51
62
|
);
|
52
63
|
|
@@ -54,10 +65,15 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
54
65
|
|
55
66
|
{
|
56
67
|
if (!fs.existsSync(buildOptions.keycloakifyBuildDirPath)) {
|
57
|
-
fs.mkdirSync(buildOptions.keycloakifyBuildDirPath, {
|
68
|
+
fs.mkdirSync(buildOptions.keycloakifyBuildDirPath, {
|
69
|
+
recursive: true
|
70
|
+
});
|
58
71
|
}
|
59
72
|
|
60
|
-
fs.writeFileSync(
|
73
|
+
fs.writeFileSync(
|
74
|
+
pathJoin(buildOptions.keycloakifyBuildDirPath, ".gitignore"),
|
75
|
+
Buffer.from("*", "utf8")
|
76
|
+
);
|
61
77
|
}
|
62
78
|
|
63
79
|
await generateSrcMainResources({ buildOptions });
|
@@ -68,10 +84,11 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
68
84
|
}
|
69
85
|
|
70
86
|
child_process.execSync("npx vite", {
|
71
|
-
|
72
|
-
|
87
|
+
cwd: buildOptions.reactAppRootDirPath,
|
88
|
+
env: {
|
73
89
|
...process.env,
|
74
|
-
[vitePluginSubScriptEnvNames.runPostBuildScript]:
|
90
|
+
[vitePluginSubScriptEnvNames.runPostBuildScript]:
|
91
|
+
JSON.stringify(buildOptions)
|
75
92
|
}
|
76
93
|
});
|
77
94
|
}
|
@@ -84,5 +101,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
84
101
|
await buildJars({ buildOptions });
|
85
102
|
}
|
86
103
|
|
87
|
-
console.log(
|
104
|
+
console.log(
|
105
|
+
chalk.green(`✓ built in ${((Date.now() - startTime) / 1000).toFixed(2)}s`)
|
106
|
+
);
|
88
107
|
}
|
@@ -18,7 +18,15 @@ export function replaceImportsInCssCode(params: { cssCode: string }): {
|
|
18
18
|
const cssGlobalsToDefine: Record<string, string> = {};
|
19
19
|
|
20
20
|
new Set(cssCode.match(/url\(["']?\/[^/][^)"']+["']?\)[^;}]*?/g) ?? []).forEach(
|
21
|
-
match =>
|
21
|
+
match =>
|
22
|
+
(cssGlobalsToDefine[
|
23
|
+
"url" +
|
24
|
+
crypto
|
25
|
+
.createHash("sha256")
|
26
|
+
.update(match)
|
27
|
+
.digest("hex")
|
28
|
+
.substring(0, 15)
|
29
|
+
] = match)
|
22
30
|
);
|
23
31
|
|
24
32
|
let fixedCssCode = cssCode;
|
@@ -26,26 +34,37 @@ export function replaceImportsInCssCode(params: { cssCode: string }): {
|
|
26
34
|
Object.keys(cssGlobalsToDefine).forEach(
|
27
35
|
cssVariableName =>
|
28
36
|
//NOTE: split/join pattern ~ replace all
|
29
|
-
(fixedCssCode = fixedCssCode
|
37
|
+
(fixedCssCode = fixedCssCode
|
38
|
+
.split(cssGlobalsToDefine[cssVariableName])
|
39
|
+
.join(`var(--${cssVariableName})`))
|
30
40
|
);
|
31
41
|
|
32
42
|
return { fixedCssCode, cssGlobalsToDefine };
|
33
43
|
}
|
34
44
|
|
35
|
-
export function generateCssCodeToDefineGlobals(params: {
|
45
|
+
export function generateCssCodeToDefineGlobals(params: {
|
46
|
+
cssGlobalsToDefine: Record<string, string>;
|
47
|
+
buildOptions: BuildOptionsLike;
|
48
|
+
}): {
|
36
49
|
cssCodeToPrependInHead: string;
|
37
50
|
} {
|
38
51
|
const { cssGlobalsToDefine, buildOptions } = params;
|
39
52
|
|
40
53
|
return {
|
41
|
-
|
54
|
+
cssCodeToPrependInHead: [
|
42
55
|
":root {",
|
43
56
|
...Object.keys(cssGlobalsToDefine)
|
44
57
|
.map(cssVariableName =>
|
45
58
|
[
|
46
59
|
`--${cssVariableName}:`,
|
47
60
|
cssGlobalsToDefine[cssVariableName].replace(
|
48
|
-
new RegExp(
|
61
|
+
new RegExp(
|
62
|
+
`url\\(${(buildOptions.urlPathname ?? "/").replace(
|
63
|
+
/\//g,
|
64
|
+
"\\/"
|
65
|
+
)}`,
|
66
|
+
"g"
|
67
|
+
),
|
49
68
|
`url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/`
|
50
69
|
)
|
51
70
|
].join(" ")
|
@@ -8,7 +8,10 @@ export type BuildOptionsLike = {
|
|
8
8
|
|
9
9
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
10
10
|
|
11
|
-
export function replaceImportsInInlineCssCode(params: {
|
11
|
+
export function replaceImportsInInlineCssCode(params: {
|
12
|
+
cssCode: string;
|
13
|
+
buildOptions: BuildOptionsLike;
|
14
|
+
}): {
|
12
15
|
fixedCssCode: string;
|
13
16
|
} {
|
14
17
|
const { cssCode, buildOptions } = params;
|
@@ -17,7 +20,8 @@ export function replaceImportsInInlineCssCode(params: { cssCode: string; buildOp
|
|
17
20
|
buildOptions.urlPathname === undefined
|
18
21
|
? /url\(["']?\/([^/][^)"']+)["']?\)/g
|
19
22
|
: new RegExp(`url\\(["']?${buildOptions.urlPathname}([^)"']+)["']?\\)`, "g"),
|
20
|
-
(...[, group]) =>
|
23
|
+
(...[, group]) =>
|
24
|
+
`url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/${group})`
|
21
25
|
);
|
22
26
|
|
23
27
|
return { fixedCssCode };
|
@@ -13,7 +13,10 @@ export type BuildOptionsLike = {
|
|
13
13
|
|
14
14
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
15
15
|
|
16
|
-
export function replaceImportsInJsCode(params: {
|
16
|
+
export function replaceImportsInJsCode(params: {
|
17
|
+
jsCode: string;
|
18
|
+
buildOptions: BuildOptionsLike;
|
19
|
+
}) {
|
17
20
|
const { jsCode, buildOptions } = params;
|
18
21
|
|
19
22
|
const { fixedJsCode } = (() => {
|
@@ -22,8 +25,8 @@ export function replaceImportsInJsCode(params: { jsCode: string; buildOptions: B
|
|
22
25
|
return replaceImportsInJsCode_vite({
|
23
26
|
jsCode,
|
24
27
|
buildOptions,
|
25
|
-
|
26
|
-
|
28
|
+
basenameOfAssetsFiles: readAssetsDirSync({
|
29
|
+
assetsDirPath: params.buildOptions.assetsDirPath
|
27
30
|
})
|
28
31
|
});
|
29
32
|
case "webpack":
|
@@ -1,4 +1,7 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
nameOfTheGlobal,
|
3
|
+
basenameOfTheKeycloakifyResourcesDir
|
4
|
+
} from "../../../shared/constants";
|
2
5
|
import { assert } from "tsafe/assert";
|
3
6
|
import type { BuildOptions } from "../../../shared/buildOptions";
|
4
7
|
import * as nodePath from "path";
|
@@ -20,7 +23,12 @@ export function replaceImportsInJsCode_vite(params: {
|
|
20
23
|
}): {
|
21
24
|
fixedJsCode: string;
|
22
25
|
} {
|
23
|
-
const {
|
26
|
+
const {
|
27
|
+
jsCode,
|
28
|
+
buildOptions,
|
29
|
+
basenameOfAssetsFiles,
|
30
|
+
systemType = nodePath.sep === "/" ? "posix" : "win32"
|
31
|
+
} = params;
|
24
32
|
|
25
33
|
const { relative: pathRelative, sep: pathSep } = nodePath[systemType];
|
26
34
|
|
@@ -38,22 +46,32 @@ export function replaceImportsInJsCode_vite(params: {
|
|
38
46
|
// Replace `Hv=function(e){return"/abcde12345/"+e}` by `Hv=function(e){return"/"+e}`
|
39
47
|
fixedJsCode = fixedJsCode.replace(
|
40
48
|
new RegExp(
|
41
|
-
`([\\w\\$][\\w\\d\\$]*)=function\\(([\\w\\$][\\w\\d\\$]*)\\)\\{return"${replaceAll(
|
49
|
+
`([\\w\\$][\\w\\d\\$]*)=function\\(([\\w\\$][\\w\\d\\$]*)\\)\\{return"${replaceAll(
|
50
|
+
buildOptions.urlPathname,
|
51
|
+
"/",
|
52
|
+
"\\/"
|
53
|
+
)}"\\+\\2\\}`,
|
42
54
|
"g"
|
43
55
|
),
|
44
|
-
(...[, funcName, paramName]) =>
|
56
|
+
(...[, funcName, paramName]) =>
|
57
|
+
`${funcName}=function(${paramName}){return"/"+${paramName}}`
|
45
58
|
);
|
46
59
|
}
|
47
60
|
|
48
61
|
replace_javascript_relatives_import_paths: {
|
49
62
|
// Example: "assets/ or "foo/bar/"
|
50
63
|
const staticDir = (() => {
|
51
|
-
let out = pathRelative(
|
64
|
+
let out = pathRelative(
|
65
|
+
buildOptions.reactAppBuildDirPath,
|
66
|
+
buildOptions.assetsDirPath
|
67
|
+
);
|
52
68
|
|
53
69
|
out = replaceAll(out, pathSep, "/") + "/";
|
54
70
|
|
55
71
|
if (out === "/") {
|
56
|
-
throw new Error(
|
72
|
+
throw new Error(
|
73
|
+
`The assetsDirPath must be a subdirectory of reactAppBuildDirPath`
|
74
|
+
);
|
57
75
|
}
|
58
76
|
|
59
77
|
return out;
|
@@ -1,4 +1,7 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
nameOfTheGlobal,
|
3
|
+
basenameOfTheKeycloakifyResourcesDir
|
4
|
+
} from "../../../shared/constants";
|
2
5
|
import { assert } from "tsafe/assert";
|
3
6
|
import type { BuildOptions } from "../../../shared/buildOptions";
|
4
7
|
import * as nodePath from "path";
|
@@ -12,10 +15,18 @@ export type BuildOptionsLike = {
|
|
12
15
|
|
13
16
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
14
17
|
|
15
|
-
export function replaceImportsInJsCode_webpack(params: {
|
18
|
+
export function replaceImportsInJsCode_webpack(params: {
|
19
|
+
jsCode: string;
|
20
|
+
buildOptions: BuildOptionsLike;
|
21
|
+
systemType?: "posix" | "win32";
|
22
|
+
}): {
|
16
23
|
fixedJsCode: string;
|
17
24
|
} {
|
18
|
-
const {
|
25
|
+
const {
|
26
|
+
jsCode,
|
27
|
+
buildOptions,
|
28
|
+
systemType = nodePath.sep === "/" ? "posix" : "win32"
|
29
|
+
} = params;
|
19
30
|
|
20
31
|
const { relative: pathRelative, sep: pathSep } = nodePath[systemType];
|
21
32
|
|
@@ -24,29 +35,51 @@ export function replaceImportsInJsCode_webpack(params: { jsCode: string; buildOp
|
|
24
35
|
if (buildOptions.urlPathname !== undefined) {
|
25
36
|
// "__esModule",{value:!0})},n.p="/foo-bar/",function(){if("undefined" -> ... n.p="/" ...
|
26
37
|
fixedJsCode = fixedJsCode.replace(
|
27
|
-
new RegExp(
|
38
|
+
new RegExp(
|
39
|
+
`,([a-zA-Z]\\.[a-zA-Z])="${replaceAll(
|
40
|
+
buildOptions.urlPathname,
|
41
|
+
"/",
|
42
|
+
"\\/"
|
43
|
+
)}",`,
|
44
|
+
"g"
|
45
|
+
),
|
28
46
|
(...[, assignTo]) => `,${assignTo}="/",`
|
29
47
|
);
|
30
48
|
}
|
31
49
|
|
32
50
|
// Example: "static/ or "foo/bar/"
|
33
51
|
const staticDir = (() => {
|
34
|
-
let out = pathRelative(
|
52
|
+
let out = pathRelative(
|
53
|
+
buildOptions.reactAppBuildDirPath,
|
54
|
+
buildOptions.assetsDirPath
|
55
|
+
);
|
35
56
|
|
36
57
|
out = replaceAll(out, pathSep, "/") + "/";
|
37
58
|
|
38
59
|
if (out === "/") {
|
39
|
-
throw new Error(
|
60
|
+
throw new Error(
|
61
|
+
`The assetsDirPath must be a subdirectory of reactAppBuildDirPath`
|
62
|
+
);
|
40
63
|
}
|
41
64
|
|
42
65
|
return out;
|
43
66
|
})();
|
44
67
|
|
45
|
-
const getReplaceArgs = (
|
46
|
-
|
68
|
+
const getReplaceArgs = (
|
69
|
+
language: "js" | "css"
|
70
|
+
): Parameters<typeof String.prototype.replace> => [
|
71
|
+
new RegExp(
|
72
|
+
`([a-zA-Z_]+)\\.([a-zA-Z]+)=(function\\(([a-z]+)\\){return|([a-z]+)=>)"${staticDir.replace(
|
73
|
+
/\//g,
|
74
|
+
"\\/"
|
75
|
+
)}${language}\\/"`,
|
76
|
+
"g"
|
77
|
+
),
|
47
78
|
(...[, n, u, matchedFunction, eForFunction]) => {
|
48
79
|
const isArrowFunction = matchedFunction.includes("=>");
|
49
|
-
const e = isArrowFunction
|
80
|
+
const e = isArrowFunction
|
81
|
+
? matchedFunction.replace("=>", "").trim()
|
82
|
+
: eForFunction;
|
50
83
|
|
51
84
|
return `
|
52
85
|
${n}[(function(){
|
@@ -58,7 +91,9 @@ export function replaceImportsInJsCode_webpack(params: { jsCode: string; buildOp
|
|
58
91
|
});
|
59
92
|
}
|
60
93
|
return "${u}";
|
61
|
-
})()] = ${
|
94
|
+
})()] = ${
|
95
|
+
isArrowFunction ? `${e} =>` : `function(${e}) { return `
|
96
|
+
} "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}${language}/"`
|
62
97
|
.replace(/\s+/g, " ")
|
63
98
|
.trim();
|
64
99
|
}
|
@@ -68,7 +103,10 @@ export function replaceImportsInJsCode_webpack(params: { jsCode: string; buildOp
|
|
68
103
|
.replace(...getReplaceArgs("js"))
|
69
104
|
.replace(...getReplaceArgs("css"))
|
70
105
|
.replace(
|
71
|
-
new RegExp(
|
106
|
+
new RegExp(
|
107
|
+
`[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`,
|
108
|
+
"g"
|
109
|
+
),
|
72
110
|
`window.${nameOfTheGlobal}.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}`
|
73
111
|
);
|
74
112
|
|