keycloakify 9.3.0 → 9.4.0-rc.0
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/README.md +5 -0
- package/account/kcContext/getKcContextFromWindow.js +2 -2
- package/account/kcContext/getKcContextFromWindow.js.map +1 -1
- package/bin/constants.d.ts +4 -1
- package/bin/constants.js +5 -2
- package/bin/constants.js.map +1 -1
- package/bin/copy-keycloak-resources-to-public.js +3 -4
- package/bin/copy-keycloak-resources-to-public.js.map +1 -1
- package/bin/download-builtin-keycloak-theme.js +98 -31
- package/bin/download-builtin-keycloak-theme.js.map +1 -1
- package/bin/eject-keycloak-page.js +2 -2
- package/bin/eject-keycloak-page.js.map +1 -1
- package/bin/{getSrcDirPath.js → getThemeSrcDirPath.js} +1 -1
- package/bin/getThemeSrcDirPath.js.map +1 -0
- package/bin/initialize-email-theme.js +6 -5
- package/bin/initialize-email-theme.js.map +1 -1
- package/bin/keycloakify/{BuildOptions.d.ts → buildOptions/buildOptions.d.ts} +2 -1
- package/bin/keycloakify/buildOptions/buildOptions.js +136 -0
- package/bin/keycloakify/buildOptions/buildOptions.js.map +1 -0
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.d.ts +7 -0
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js +27 -0
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js.map +1 -0
- package/bin/keycloakify/buildOptions/index.d.ts +1 -0
- package/bin/keycloakify/{generateJavaStackFiles → buildOptions}/index.js +1 -1
- package/bin/keycloakify/buildOptions/index.js.map +1 -0
- package/bin/keycloakify/buildOptions/parsedPackageJson.d.ts +19 -0
- package/bin/keycloakify/{parsedPackageJson.js → buildOptions/parsedPackageJson.js} +6 -7
- package/bin/keycloakify/buildOptions/parsedPackageJson.js.map +1 -0
- package/bin/keycloakify/buildOptions/resolvedViteConfig.d.ts +12 -0
- package/bin/keycloakify/buildOptions/resolvedViteConfig.js +82 -0
- package/bin/keycloakify/buildOptions/resolvedViteConfig.js.map +1 -0
- package/bin/keycloakify/generateFtl/generateFtl.d.ts +4 -1
- package/bin/keycloakify/generateFtl/generateFtl.js +5 -5
- package/bin/keycloakify/generateFtl/generateFtl.js.map +1 -1
- package/bin/keycloakify/generatePom.d.ts +12 -0
- package/bin/keycloakify/generatePom.js +59 -0
- package/bin/keycloakify/generatePom.js.map +1 -0
- package/bin/keycloakify/{generateJavaStackFiles → generateTheme}/bringInAccountV1.d.ts +2 -1
- package/bin/keycloakify/{generateJavaStackFiles → generateTheme}/bringInAccountV1.js +21 -67
- package/bin/keycloakify/generateTheme/bringInAccountV1.js.map +1 -0
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts +0 -3
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js +5 -34
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map +1 -1
- package/bin/keycloakify/generateTheme/generateTheme.d.ts +4 -1
- package/bin/keycloakify/generateTheme/generateTheme.js +123 -70
- package/bin/keycloakify/generateTheme/generateTheme.js.map +1 -1
- package/bin/keycloakify/keycloakify.js +13 -72
- package/bin/keycloakify/keycloakify.js.map +1 -1
- package/bin/keycloakify/replacers/replaceImportsInCssCode.js +2 -1
- package/bin/keycloakify/replacers/replaceImportsInCssCode.js.map +1 -1
- package/bin/keycloakify/replacers/replaceImportsInInlineCssCode.js +2 -1
- package/bin/keycloakify/replacers/replaceImportsInInlineCssCode.js.map +1 -1
- package/bin/keycloakify/replacers/replaceImportsInJsCode/index.d.ts +1 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/index.js +18 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/index.js.map +1 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.d.ts +12 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.js +70 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.js.map +1 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.d.ts +13 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.js +95 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.js.map +1 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.d.ts +12 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.js +108 -0
- package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.js.map +1 -0
- package/bin/promptKeycloakVersion.js +0 -1
- package/bin/promptKeycloakVersion.js.map +1 -1
- package/bin/tools/OptionalIfCanBeUndefined.d.ts +14 -0
- package/bin/tools/OptionalIfCanBeUndefined.js +3 -0
- package/bin/tools/OptionalIfCanBeUndefined.js.map +1 -0
- package/bin/tools/SemVer.d.ts +26 -0
- package/bin/tools/{NpmModuleVersion.js → SemVer.js} +39 -23
- package/bin/tools/SemVer.js.map +1 -0
- package/bin/tools/String.prototype.replaceAll.d.ts +1 -0
- package/bin/tools/String.prototype.replaceAll.js +29 -0
- package/bin/tools/String.prototype.replaceAll.js.map +1 -0
- package/bin/tools/crawl.js +9 -9
- package/bin/tools/crawl.js.map +1 -1
- package/bin/tools/downloadAndUnzip.js +30 -19
- package/bin/tools/downloadAndUnzip.js.map +1 -1
- package/bin/tools/fs.rm.d.ts +8 -0
- package/bin/tools/fs.rm.js +151 -0
- package/bin/tools/fs.rm.js.map +1 -0
- package/bin/tools/fs.rmSync.d.ts +8 -0
- package/bin/tools/fs.rmSync.js +58 -0
- package/bin/tools/fs.rmSync.js.map +1 -0
- package/bin/tools/getAbsoluteAndInOsFormatPath.js +1 -0
- package/bin/tools/getAbsoluteAndInOsFormatPath.js.map +1 -1
- package/bin/tools/octokit-addons/getLatestsSemVersionedTag.d.ts +2 -3
- package/bin/tools/octokit-addons/getLatestsSemVersionedTag.js +6 -6
- package/bin/tools/octokit-addons/getLatestsSemVersionedTag.js.map +1 -1
- package/bin/tools/transformCodebase.d.ts +5 -1
- package/bin/tools/transformCodebase.js +31 -13
- package/bin/tools/transformCodebase.js.map +1 -1
- package/login/kcContext/getKcContextFromWindow.js +2 -2
- package/login/kcContext/getKcContextFromWindow.js.map +1 -1
- package/login/lib/useGetClassName.js +1 -1
- package/login/lib/useGetClassName.js.map +1 -1
- package/login/pages/LoginOtp.js +5 -43
- package/login/pages/LoginOtp.js.map +1 -1
- package/package.json +104 -53
- package/src/account/kcContext/getKcContextFromWindow.ts +2 -2
- package/src/bin/constants.ts +4 -1
- package/src/bin/copy-keycloak-resources-to-public.ts +2 -3
- package/src/bin/download-builtin-keycloak-theme.ts +96 -48
- package/src/bin/eject-keycloak-page.ts +1 -1
- package/src/bin/initialize-email-theme.ts +4 -3
- package/src/bin/keycloakify/buildOptions/buildOptions.ts +185 -0
- package/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +33 -0
- package/src/bin/keycloakify/buildOptions/index.ts +1 -0
- package/src/bin/keycloakify/{parsedPackageJson.ts → buildOptions/parsedPackageJson.ts} +4 -6
- package/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts +85 -0
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +12 -8
- package/src/bin/keycloakify/generatePom.ts +70 -0
- package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +1 -1
- package/src/bin/keycloakify/generateTheme/bringInAccountV1.ts +83 -0
- package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +11 -52
- package/src/bin/keycloakify/generateTheme/generateTheme.ts +141 -51
- package/src/bin/keycloakify/keycloakify.ts +11 -58
- package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +3 -2
- package/src/bin/keycloakify/replacers/replaceImportsInInlineCssCode.ts +3 -2
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/index.ts +1 -0
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +66 -0
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +85 -0
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +90 -0
- package/src/bin/promptKeycloakVersion.ts +0 -1
- package/src/bin/tools/OptionalIfCanBeUndefined.ts +12 -0
- package/src/bin/tools/SemVer.ts +99 -0
- package/src/bin/tools/String.prototype.replaceAll.ts +30 -0
- package/src/bin/tools/crawl.ts +8 -8
- package/src/bin/tools/downloadAndUnzip.ts +11 -4
- package/src/bin/tools/fs.rm.ts +43 -0
- package/src/bin/tools/fs.rmSync.ts +34 -0
- package/src/bin/tools/getAbsoluteAndInOsFormatPath.ts +2 -0
- package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +9 -9
- package/src/bin/tools/transformCodebase.ts +35 -14
- package/src/login/kcContext/getKcContextFromWindow.ts +2 -2
- package/src/login/lib/useGetClassName.ts +1 -1
- package/src/login/pages/LoginOtp.tsx +64 -94
- package/src/tsconfig.json +1 -1
- package/src/vite-plugin/config.json +232 -0
- package/src/vite-plugin/index.ts +1 -0
- package/src/vite-plugin/tsconfig.json +18 -0
- package/src/vite-plugin/vite-plugin.ts +128 -0
- package/vite-plugin/index.d.ts +1 -0
- package/vite-plugin/index.js +18 -0
- package/vite-plugin/index.js.map +1 -0
- package/vite-plugin/tsconfig.tsbuildinfo +1 -0
- package/vite-plugin/vite-plugin.d.ts +2 -0
- package/vite-plugin/vite-plugin.js +118 -0
- package/vite-plugin/vite-plugin.js.map +1 -0
- package/bin/getSrcDirPath.js.map +0 -1
- package/bin/keycloakify/BuildOptions.js +0 -113
- package/bin/keycloakify/BuildOptions.js.map +0 -1
- package/bin/keycloakify/ftlValuesGlobalName.d.ts +0 -1
- package/bin/keycloakify/ftlValuesGlobalName.js +0 -5
- package/bin/keycloakify/ftlValuesGlobalName.js.map +0 -1
- package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js.map +0 -1
- package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.d.ts +0 -16
- package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js +0 -205
- package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js.map +0 -1
- package/bin/keycloakify/generateJavaStackFiles/index.d.ts +0 -1
- package/bin/keycloakify/generateJavaStackFiles/index.js.map +0 -1
- package/bin/keycloakify/generateTheme/readStaticResourcesUsage.d.ts +0 -15
- package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js +0 -158
- package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js.map +0 -1
- package/bin/keycloakify/parsedPackageJson.d.ts +0 -108
- package/bin/keycloakify/parsedPackageJson.js.map +0 -1
- package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.d.ts +0 -5
- package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js +0 -74
- package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js.map +0 -1
- package/bin/tools/NpmModuleVersion.d.ts +0 -22
- package/bin/tools/NpmModuleVersion.js.map +0 -1
- package/src/bin/keycloakify/BuildOptions.ts +0 -157
- package/src/bin/keycloakify/ftlValuesGlobalName.ts +0 -1
- package/src/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.ts +0 -101
- package/src/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.ts +0 -141
- package/src/bin/keycloakify/generateJavaStackFiles/index.ts +0 -1
- package/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +0 -76
- package/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts +0 -51
- package/src/bin/tools/NpmModuleVersion.ts +0 -73
- /package/bin/{getSrcDirPath.d.ts → getThemeSrcDirPath.d.ts} +0 -0
- /package/src/bin/{getSrcDirPath.ts → getThemeSrcDirPath.ts} +0 -0
@@ -1,28 +1,38 @@
|
|
1
1
|
import { transformCodebase } from "../../tools/transformCodebase";
|
2
2
|
import * as fs from "fs";
|
3
|
-
import { join as pathJoin, basename as pathBasename, resolve as pathResolve } from "path";
|
4
|
-
import {
|
3
|
+
import { join as pathJoin, basename as pathBasename, resolve as pathResolve, dirname as pathDirname } from "path";
|
4
|
+
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
5
5
|
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
6
6
|
import { generateFtlFilesCodeFactory, loginThemePageIds, accountThemePageIds } from "../generateFtl";
|
7
|
-
import {
|
7
|
+
import {
|
8
|
+
type ThemeType,
|
9
|
+
lastKeycloakVersionWithAccountV1,
|
10
|
+
keycloak_resources,
|
11
|
+
retrocompatPostfix,
|
12
|
+
accountV1ThemeName,
|
13
|
+
basenameOfTheKeycloakifyResourcesDir
|
14
|
+
} from "../../constants";
|
8
15
|
import { isInside } from "../../tools/isInside";
|
9
|
-
import type { BuildOptions } from "../
|
16
|
+
import type { BuildOptions } from "../buildOptions";
|
10
17
|
import { assert, type Equals } from "tsafe/assert";
|
11
18
|
import { downloadKeycloakStaticResources } from "./downloadKeycloakStaticResources";
|
12
19
|
import { readFieldNameUsage } from "./readFieldNameUsage";
|
13
20
|
import { readExtraPagesNames } from "./readExtraPageNames";
|
14
21
|
import { generateMessageProperties } from "./generateMessageProperties";
|
15
|
-
import {
|
22
|
+
import { bringInAccountV1 } from "./bringInAccountV1";
|
16
23
|
|
17
24
|
export type BuildOptionsLike = {
|
25
|
+
bundler: "vite" | "webpack";
|
18
26
|
extraThemeProperties: string[] | undefined;
|
19
27
|
themeVersion: string;
|
20
28
|
loginThemeResourcesFromKeycloakVersion: string;
|
21
|
-
urlPathname: string | undefined;
|
22
29
|
keycloakifyBuildDirPath: string;
|
23
30
|
reactAppBuildDirPath: string;
|
24
31
|
cacheDirPath: string;
|
32
|
+
assetsDirPath: string;
|
33
|
+
urlPathname: string | undefined;
|
25
34
|
doBuildRetrocompatAccountTheme: boolean;
|
35
|
+
themeNames: string[];
|
26
36
|
};
|
27
37
|
|
28
38
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
@@ -49,29 +59,47 @@ export async function generateTheme(params: {
|
|
49
59
|
);
|
50
60
|
};
|
51
61
|
|
52
|
-
|
62
|
+
const cssGlobalsToDefine: Record<string, string> = {};
|
53
63
|
|
54
|
-
|
64
|
+
const implementedThemeTypes: Record<ThemeType | "email", boolean> = {
|
65
|
+
"login": false,
|
66
|
+
"account": false,
|
67
|
+
"email": false
|
68
|
+
};
|
55
69
|
|
56
|
-
for (const themeType of
|
70
|
+
for (const themeType of ["login", "account"] as const) {
|
57
71
|
if (!fs.existsSync(pathJoin(themeSrcDirPath, themeType))) {
|
58
72
|
continue;
|
59
73
|
}
|
60
74
|
|
61
|
-
|
75
|
+
implementedThemeTypes[themeType] = true;
|
62
76
|
|
63
|
-
|
64
|
-
const isFirstPass = themeType.indexOf(themeType) === 0;
|
77
|
+
const themeTypeDirPath = getThemeTypeDirPath({ themeType });
|
65
78
|
|
66
|
-
|
67
|
-
|
79
|
+
apply_replacers_and_move_to_theme_resources: {
|
80
|
+
if (themeType === "account" && implementedThemeTypes.login) {
|
81
|
+
// NOTE: We prevend doing it twice, it has been done for the login theme.
|
82
|
+
|
83
|
+
transformCodebase({
|
84
|
+
"srcDirPath": pathJoin(
|
85
|
+
getThemeTypeDirPath({
|
86
|
+
"themeType": "login"
|
87
|
+
}),
|
88
|
+
"resources",
|
89
|
+
basenameOfTheKeycloakifyResourcesDir
|
90
|
+
),
|
91
|
+
"destDirPath": pathJoin(themeTypeDirPath, "resources", basenameOfTheKeycloakifyResourcesDir)
|
92
|
+
});
|
93
|
+
|
94
|
+
break apply_replacers_and_move_to_theme_resources;
|
68
95
|
}
|
69
96
|
|
70
97
|
transformCodebase({
|
71
|
-
"destDirPath": pathJoin(themeTypeDirPath, "resources", "build"),
|
72
98
|
"srcDirPath": buildOptions.reactAppBuildDirPath,
|
99
|
+
"destDirPath": pathJoin(themeTypeDirPath, "resources", basenameOfTheKeycloakifyResourcesDir),
|
73
100
|
"transformSourceCode": ({ filePath, sourceCode }) => {
|
74
101
|
//NOTE: Prevent cycles, excludes the folder we generated for debug in public/
|
102
|
+
// This should not happen if users follow the new instruction setup but we keep it for retrocompatibility.
|
75
103
|
if (
|
76
104
|
isInside({
|
77
105
|
"dirPath": pathJoin(buildOptions.reactAppBuildDirPath, keycloak_resources),
|
@@ -82,27 +110,21 @@ export async function generateTheme(params: {
|
|
82
110
|
}
|
83
111
|
|
84
112
|
if (/\.css?$/i.test(filePath)) {
|
85
|
-
const { cssGlobalsToDefine, fixedCssCode } = replaceImportsInCssCode({
|
113
|
+
const { cssGlobalsToDefine: cssGlobalsToDefineForThisFile, fixedCssCode } = replaceImportsInCssCode({
|
86
114
|
"cssCode": sourceCode.toString("utf8")
|
87
115
|
});
|
88
116
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
}
|
93
|
-
|
94
|
-
allCssGlobalsToDefine = {
|
95
|
-
...allCssGlobalsToDefine,
|
96
|
-
...cssGlobalsToDefine
|
97
|
-
};
|
98
|
-
}
|
117
|
+
Object.entries(cssGlobalsToDefineForThisFile).forEach(([key, value]) => {
|
118
|
+
cssGlobalsToDefine[key] = value;
|
119
|
+
});
|
99
120
|
|
100
121
|
return { "modifiedSourceCode": Buffer.from(fixedCssCode, "utf8") };
|
101
122
|
}
|
102
123
|
|
103
124
|
if (/\.js?$/i.test(filePath)) {
|
104
|
-
const { fixedJsCode } =
|
105
|
-
"jsCode": sourceCode.toString("utf8")
|
125
|
+
const { fixedJsCode } = replaceImportsInJsCode({
|
126
|
+
"jsCode": sourceCode.toString("utf8"),
|
127
|
+
buildOptions
|
106
128
|
});
|
107
129
|
|
108
130
|
return { "modifiedSourceCode": Buffer.from(fixedJsCode, "utf8") };
|
@@ -113,22 +135,19 @@ export async function generateTheme(params: {
|
|
113
135
|
});
|
114
136
|
}
|
115
137
|
|
116
|
-
const generateFtlFilesCode =
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
themeType
|
130
|
-
})
|
131
|
-
}).generateFtlFilesCode;
|
138
|
+
const { generateFtlFilesCode } = generateFtlFilesCodeFactory({
|
139
|
+
themeName,
|
140
|
+
"indexHtmlCode": fs.readFileSync(pathJoin(buildOptions.reactAppBuildDirPath, "index.html")).toString("utf8"),
|
141
|
+
cssGlobalsToDefine,
|
142
|
+
buildOptions,
|
143
|
+
keycloakifyVersion,
|
144
|
+
themeType,
|
145
|
+
"fieldNames": readFieldNameUsage({
|
146
|
+
keycloakifySrcDirPath,
|
147
|
+
themeSrcDirPath,
|
148
|
+
themeType
|
149
|
+
})
|
150
|
+
});
|
132
151
|
|
133
152
|
[
|
134
153
|
...(() => {
|
@@ -175,11 +194,6 @@ export async function generateTheme(params: {
|
|
175
194
|
})(),
|
176
195
|
"themeDirPath": pathResolve(pathJoin(themeTypeDirPath, "..")),
|
177
196
|
themeType,
|
178
|
-
"usedResources": readStaticResourcesUsage({
|
179
|
-
keycloakifySrcDirPath,
|
180
|
-
themeSrcDirPath,
|
181
|
-
themeType
|
182
|
-
}),
|
183
197
|
buildOptions
|
184
198
|
});
|
185
199
|
|
@@ -190,7 +204,7 @@ export async function generateTheme(params: {
|
|
190
204
|
`parent=${(() => {
|
191
205
|
switch (themeType) {
|
192
206
|
case "account":
|
193
|
-
return
|
207
|
+
return accountV1ThemeName;
|
194
208
|
case "login":
|
195
209
|
return "keycloak";
|
196
210
|
}
|
@@ -209,7 +223,10 @@ export async function generateTheme(params: {
|
|
209
223
|
"transformSourceCode": ({ filePath, sourceCode }) => {
|
210
224
|
if (pathBasename(filePath) === "theme.properties") {
|
211
225
|
return {
|
212
|
-
"modifiedSourceCode": Buffer.from(
|
226
|
+
"modifiedSourceCode": Buffer.from(
|
227
|
+
sourceCode.toString("utf8").replace(`parent=${accountV1ThemeName}`, "parent=keycloak"),
|
228
|
+
"utf8"
|
229
|
+
)
|
213
230
|
};
|
214
231
|
}
|
215
232
|
|
@@ -226,9 +243,82 @@ export async function generateTheme(params: {
|
|
226
243
|
break email;
|
227
244
|
}
|
228
245
|
|
246
|
+
implementedThemeTypes.email = true;
|
247
|
+
|
229
248
|
transformCodebase({
|
230
249
|
"srcDirPath": emailThemeSrcDirPath,
|
231
250
|
"destDirPath": getThemeTypeDirPath({ "themeType": "email" })
|
232
251
|
});
|
233
252
|
}
|
253
|
+
|
254
|
+
const parsedKeycloakThemeJson: { themes: { name: string; types: string[] }[] } = { "themes": [] };
|
255
|
+
|
256
|
+
buildOptions.themeNames.forEach(themeName =>
|
257
|
+
parsedKeycloakThemeJson.themes.push({
|
258
|
+
"name": themeName,
|
259
|
+
"types": Object.entries(implementedThemeTypes)
|
260
|
+
.filter(([, isImplemented]) => isImplemented)
|
261
|
+
.map(([themeType]) => themeType)
|
262
|
+
})
|
263
|
+
);
|
264
|
+
|
265
|
+
account_specific_extra_work: {
|
266
|
+
if (!implementedThemeTypes.account) {
|
267
|
+
break account_specific_extra_work;
|
268
|
+
}
|
269
|
+
|
270
|
+
await bringInAccountV1({ buildOptions });
|
271
|
+
|
272
|
+
parsedKeycloakThemeJson.themes.push({
|
273
|
+
"name": accountV1ThemeName,
|
274
|
+
"types": ["account"]
|
275
|
+
});
|
276
|
+
|
277
|
+
add_retrocompat_account_theme: {
|
278
|
+
if (!buildOptions.doBuildRetrocompatAccountTheme) {
|
279
|
+
break add_retrocompat_account_theme;
|
280
|
+
}
|
281
|
+
|
282
|
+
transformCodebase({
|
283
|
+
"srcDirPath": getThemeTypeDirPath({ "themeType": "account" }),
|
284
|
+
"destDirPath": getThemeTypeDirPath({ "themeType": "account", "isRetrocompat": true }),
|
285
|
+
"transformSourceCode": ({ filePath, sourceCode }) => {
|
286
|
+
if (pathBasename(filePath) === "theme.properties") {
|
287
|
+
return {
|
288
|
+
"modifiedSourceCode": Buffer.from(
|
289
|
+
sourceCode.toString("utf8").replace(`parent=${accountV1ThemeName}`, "parent=keycloak"),
|
290
|
+
"utf8"
|
291
|
+
)
|
292
|
+
};
|
293
|
+
}
|
294
|
+
|
295
|
+
return { "modifiedSourceCode": sourceCode };
|
296
|
+
}
|
297
|
+
});
|
298
|
+
|
299
|
+
buildOptions.themeNames.forEach(themeName =>
|
300
|
+
parsedKeycloakThemeJson.themes.push({
|
301
|
+
"name": `${themeName}${retrocompatPostfix}`,
|
302
|
+
"types": ["account"]
|
303
|
+
})
|
304
|
+
);
|
305
|
+
}
|
306
|
+
}
|
307
|
+
|
308
|
+
{
|
309
|
+
const keycloakThemeJsonFilePath = pathJoin(
|
310
|
+
buildOptions.keycloakifyBuildDirPath,
|
311
|
+
"src",
|
312
|
+
"main",
|
313
|
+
"resources",
|
314
|
+
"META-INF",
|
315
|
+
"keycloak-themes.json"
|
316
|
+
);
|
317
|
+
|
318
|
+
try {
|
319
|
+
fs.mkdirSync(pathDirname(keycloakThemeJsonFilePath));
|
320
|
+
} catch {}
|
321
|
+
|
322
|
+
fs.writeFileSync(keycloakThemeJsonFilePath, Buffer.from(JSON.stringify(parsedKeycloakThemeJson, null, 2), "utf8"));
|
323
|
+
}
|
234
324
|
}
|
@@ -1,15 +1,14 @@
|
|
1
1
|
import { generateTheme } from "./generateTheme";
|
2
|
-
import {
|
2
|
+
import { generatePom } from "./generatePom";
|
3
3
|
import { join as pathJoin, relative as pathRelative, basename as pathBasename, dirname as pathDirname, sep as pathSep } from "path";
|
4
4
|
import * as child_process from "child_process";
|
5
5
|
import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
|
6
6
|
import * as fs from "fs";
|
7
|
-
import { readBuildOptions } from "./
|
7
|
+
import { readBuildOptions } from "./buildOptions";
|
8
8
|
import { getLogger } from "../tools/logger";
|
9
9
|
import { assert } from "tsafe/assert";
|
10
|
-
import { getThemeSrcDirPath } from "../
|
10
|
+
import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
11
11
|
import { getProjectRoot } from "../tools/getProjectRoot";
|
12
|
-
import { objectKeys } from "tsafe/objectKeys";
|
13
12
|
|
14
13
|
export async function main() {
|
15
14
|
const reactAppRootDirPath = process.cwd();
|
@@ -42,25 +41,13 @@ export async function main() {
|
|
42
41
|
});
|
43
42
|
}
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
for (const themeType of objectKeys(implementedThemeTypes)) {
|
54
|
-
if (!fs.existsSync(pathJoin(themeSrcDirPath, themeType))) {
|
55
|
-
continue;
|
56
|
-
}
|
57
|
-
implementedThemeTypes[themeType] = true;
|
58
|
-
}
|
59
|
-
|
60
|
-
return implementedThemeTypes;
|
61
|
-
})(),
|
62
|
-
buildOptions
|
63
|
-
});
|
44
|
+
{
|
45
|
+
const { pomFileCode } = generatePom({ buildOptions });
|
46
|
+
|
47
|
+
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
48
|
+
}
|
49
|
+
|
50
|
+
const jarFilePath = pathJoin(buildOptions.keycloakifyBuildDirPath, "target", `${buildOptions.artifactId}-${buildOptions.themeVersion}.jar`);
|
64
51
|
|
65
52
|
if (buildOptions.doCreateJar) {
|
66
53
|
child_process.execSync("mvn clean install", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
@@ -96,39 +83,7 @@ export async function main() {
|
|
96
83
|
"",
|
97
84
|
...(!buildOptions.doCreateJar
|
98
85
|
? []
|
99
|
-
: [
|
100
|
-
`✅ Your keycloak theme has been generated and bundled into .${pathSep}${pathRelative(reactAppRootDirPath, jarFilePath)} 🚀`,
|
101
|
-
`It is to be placed in "/opt/keycloak/providers" in the container running a quay.io/keycloak/keycloak Docker image.`,
|
102
|
-
""
|
103
|
-
]),
|
104
|
-
//TODO: Restore when we find a good Helm chart for Keycloak.
|
105
|
-
//"Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:",
|
106
|
-
"",
|
107
|
-
"value.yaml: ",
|
108
|
-
" extraInitContainers: |",
|
109
|
-
" - name: realm-ext-provider",
|
110
|
-
" image: curlimages/curl",
|
111
|
-
" imagePullPolicy: IfNotPresent",
|
112
|
-
" command:",
|
113
|
-
" - sh",
|
114
|
-
" args:",
|
115
|
-
" - -c",
|
116
|
-
` - curl -L -f -S -o /extensions/${pathBasename(jarFilePath)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`,
|
117
|
-
" volumeMounts:",
|
118
|
-
" - name: extensions",
|
119
|
-
" mountPath: /extensions",
|
120
|
-
" ",
|
121
|
-
" extraVolumeMounts: |",
|
122
|
-
" - name: extensions",
|
123
|
-
" mountPath: /opt/keycloak/providers",
|
124
|
-
" extraEnv: |",
|
125
|
-
" - name: KEYCLOAK_USER",
|
126
|
-
" value: admin",
|
127
|
-
" - name: KEYCLOAK_PASSWORD",
|
128
|
-
" value: xxxxxxxxx",
|
129
|
-
" - name: JAVA_OPTS",
|
130
|
-
" value: -Dkeycloak.profile=preview",
|
131
|
-
"",
|
86
|
+
: [`✅ Your keycloak theme has been generated and bundled into .${pathSep}${pathRelative(reactAppRootDirPath, jarFilePath)} 🚀`]),
|
132
87
|
"",
|
133
88
|
`To test your theme locally you can spin up a Keycloak ${containerKeycloakVersion} container image with the theme pre loaded by running:`,
|
134
89
|
"",
|
@@ -136,8 +91,6 @@ export async function main() {
|
|
136
91
|
reactAppRootDirPath,
|
137
92
|
pathJoin(buildOptions.keycloakifyBuildDirPath, generateStartKeycloakTestingContainer.basename)
|
138
93
|
)} 👈`,
|
139
|
-
"",
|
140
|
-
`Test with different Keycloak versions by editing the .sh file. see available versions here: https://quay.io/repository/keycloak/keycloak?tab=tags`,
|
141
94
|
``,
|
142
95
|
`Once your container is up and running: `,
|
143
96
|
"- Log into the admin console 👉 http://localhost:8080/admin username: admin, password: admin 👈",
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import * as crypto from "crypto";
|
2
|
-
import type { BuildOptions } from "../
|
2
|
+
import type { BuildOptions } from "../buildOptions";
|
3
3
|
import { assert } from "tsafe/assert";
|
4
|
+
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
4
5
|
|
5
6
|
export type BuildOptionsLike = {
|
6
7
|
urlPathname: string | undefined;
|
@@ -45,7 +46,7 @@ export function generateCssCodeToDefineGlobals(params: { cssGlobalsToDefine: Rec
|
|
45
46
|
`--${cssVariableName}:`,
|
46
47
|
cssGlobalsToDefine[cssVariableName].replace(
|
47
48
|
new RegExp(`url\\(${(buildOptions.urlPathname ?? "/").replace(/\//g, "\\/")}`, "g"),
|
48
|
-
|
49
|
+
`url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/`
|
49
50
|
)
|
50
51
|
].join(" ")
|
51
52
|
)
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import type { BuildOptions } from "../
|
1
|
+
import type { BuildOptions } from "../buildOptions";
|
2
2
|
import { assert } from "tsafe/assert";
|
3
|
+
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
3
4
|
|
4
5
|
export type BuildOptionsLike = {
|
5
6
|
urlPathname: string | undefined;
|
@@ -16,7 +17,7 @@ export function replaceImportsInInlineCssCode(params: { cssCode: string; buildOp
|
|
16
17
|
buildOptions.urlPathname === undefined
|
17
18
|
? /url\(["']?\/([^/][^)"']+)["']?\)/g
|
18
19
|
: new RegExp(`url\\(["']?${buildOptions.urlPathname}([^)"']+)["']?\\)`, "g"),
|
19
|
-
(...[, group]) => `url(\${url.resourcesPath}
|
20
|
+
(...[, group]) => `url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/${group})`
|
20
21
|
);
|
21
22
|
|
22
23
|
return { fixedCssCode };
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./replaceImportsInJsCode";
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { assert } from "tsafe/assert";
|
2
|
+
import type { BuildOptions } from "../../buildOptions";
|
3
|
+
import { replaceImportsInJsCode_vite } from "./vite";
|
4
|
+
import { replaceImportsInJsCode_webpack } from "./webpack";
|
5
|
+
import * as fs from "fs";
|
6
|
+
|
7
|
+
export type BuildOptionsLike = {
|
8
|
+
reactAppBuildDirPath: string;
|
9
|
+
assetsDirPath: string;
|
10
|
+
urlPathname: string | undefined;
|
11
|
+
bundler: "vite" | "webpack";
|
12
|
+
};
|
13
|
+
|
14
|
+
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
15
|
+
|
16
|
+
export function replaceImportsInJsCode(params: { jsCode: string; buildOptions: BuildOptionsLike }) {
|
17
|
+
const { jsCode, buildOptions } = params;
|
18
|
+
|
19
|
+
const { fixedJsCode } = (() => {
|
20
|
+
switch (buildOptions.bundler) {
|
21
|
+
case "vite":
|
22
|
+
return replaceImportsInJsCode_vite({
|
23
|
+
jsCode,
|
24
|
+
buildOptions,
|
25
|
+
"basenameOfAssetsFiles": readAssetsDirSync({
|
26
|
+
"assetsDirPath": params.buildOptions.assetsDirPath
|
27
|
+
})
|
28
|
+
});
|
29
|
+
case "webpack":
|
30
|
+
return replaceImportsInJsCode_webpack({
|
31
|
+
jsCode,
|
32
|
+
buildOptions
|
33
|
+
});
|
34
|
+
}
|
35
|
+
})();
|
36
|
+
|
37
|
+
return { fixedJsCode };
|
38
|
+
}
|
39
|
+
|
40
|
+
const { readAssetsDirSync } = (() => {
|
41
|
+
let cache:
|
42
|
+
| {
|
43
|
+
assetsDirPath: string;
|
44
|
+
basenameOfAssetsFiles: string[];
|
45
|
+
}
|
46
|
+
| undefined = undefined;
|
47
|
+
|
48
|
+
function readAssetsDirSync(params: { assetsDirPath: string }): string[] {
|
49
|
+
const { assetsDirPath } = params;
|
50
|
+
|
51
|
+
if (cache !== undefined && cache.assetsDirPath === assetsDirPath) {
|
52
|
+
return cache.basenameOfAssetsFiles;
|
53
|
+
}
|
54
|
+
|
55
|
+
const basenameOfAssetsFiles = fs.readdirSync(assetsDirPath);
|
56
|
+
|
57
|
+
cache = {
|
58
|
+
assetsDirPath,
|
59
|
+
basenameOfAssetsFiles
|
60
|
+
};
|
61
|
+
|
62
|
+
return basenameOfAssetsFiles;
|
63
|
+
}
|
64
|
+
|
65
|
+
return { readAssetsDirSync };
|
66
|
+
})();
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
2
|
+
import { assert } from "tsafe/assert";
|
3
|
+
import type { BuildOptions } from "../../buildOptions";
|
4
|
+
import * as nodePath from "path";
|
5
|
+
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
6
|
+
|
7
|
+
export type BuildOptionsLike = {
|
8
|
+
reactAppBuildDirPath: string;
|
9
|
+
assetsDirPath: string;
|
10
|
+
urlPathname: string | undefined;
|
11
|
+
};
|
12
|
+
|
13
|
+
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
14
|
+
|
15
|
+
export function replaceImportsInJsCode_vite(params: {
|
16
|
+
jsCode: string;
|
17
|
+
buildOptions: BuildOptionsLike;
|
18
|
+
basenameOfAssetsFiles: string[];
|
19
|
+
systemType?: "posix" | "win32";
|
20
|
+
}): {
|
21
|
+
fixedJsCode: string;
|
22
|
+
} {
|
23
|
+
const { jsCode, buildOptions, basenameOfAssetsFiles, systemType = nodePath.sep === "/" ? "posix" : "win32" } = params;
|
24
|
+
|
25
|
+
const { relative: pathRelative, sep: pathSep } = nodePath[systemType];
|
26
|
+
|
27
|
+
let fixedJsCode = jsCode;
|
28
|
+
|
29
|
+
replace_base_javacript_import: {
|
30
|
+
if (buildOptions.urlPathname === undefined) {
|
31
|
+
break replace_base_javacript_import;
|
32
|
+
}
|
33
|
+
// Optimization
|
34
|
+
if (!jsCode.includes(buildOptions.urlPathname)) {
|
35
|
+
break replace_base_javacript_import;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Replace `Hv=function(e){return"/abcde12345/"+e}` by `Hv=function(e){return"/"+e}`
|
39
|
+
fixedJsCode = fixedJsCode.replace(
|
40
|
+
new RegExp(
|
41
|
+
`([\\w\\$][\\w\\d\\$]*)=function\\(([\\w\\$][\\w\\d\\$]*)\\)\\{return"${replaceAll(buildOptions.urlPathname, "/", "\\/")}"\\+\\2\\}`,
|
42
|
+
"g"
|
43
|
+
),
|
44
|
+
(...[, funcName, paramName]) => `${funcName}=function(${paramName}){return"/"+${paramName}}`
|
45
|
+
);
|
46
|
+
}
|
47
|
+
|
48
|
+
replace_javascript_relatives_import_paths: {
|
49
|
+
// Example: "assets/ or "foo/bar/"
|
50
|
+
const staticDir = (() => {
|
51
|
+
let out = pathRelative(buildOptions.reactAppBuildDirPath, buildOptions.assetsDirPath);
|
52
|
+
|
53
|
+
out = replaceAll(out, pathSep, "/") + "/";
|
54
|
+
|
55
|
+
if (out === "/") {
|
56
|
+
throw new Error(`The assetsDirPath must be a subdirectory of reactAppBuildDirPath`);
|
57
|
+
}
|
58
|
+
|
59
|
+
return out;
|
60
|
+
})();
|
61
|
+
|
62
|
+
// Optimization
|
63
|
+
if (!jsCode.includes(staticDir)) {
|
64
|
+
break replace_javascript_relatives_import_paths;
|
65
|
+
}
|
66
|
+
|
67
|
+
basenameOfAssetsFiles
|
68
|
+
.map(basenameOfAssetsFile => `${staticDir}${basenameOfAssetsFile}`)
|
69
|
+
.forEach(relativePathOfAssetFile => {
|
70
|
+
fixedJsCode = replaceAll(
|
71
|
+
fixedJsCode,
|
72
|
+
`"${relativePathOfAssetFile}"`,
|
73
|
+
`(window.${nameOfTheGlobal}.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")`
|
74
|
+
);
|
75
|
+
|
76
|
+
fixedJsCode = replaceAll(
|
77
|
+
fixedJsCode,
|
78
|
+
`"${buildOptions.urlPathname ?? "/"}${relativePathOfAssetFile}"`,
|
79
|
+
`(window.${nameOfTheGlobal}.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")`
|
80
|
+
);
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
return { fixedJsCode };
|
85
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
2
|
+
import { assert } from "tsafe/assert";
|
3
|
+
import type { BuildOptions } from "../../buildOptions";
|
4
|
+
import * as nodePath from "path";
|
5
|
+
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
6
|
+
|
7
|
+
export type BuildOptionsLike = {
|
8
|
+
reactAppBuildDirPath: string;
|
9
|
+
assetsDirPath: string;
|
10
|
+
urlPathname: string | undefined;
|
11
|
+
};
|
12
|
+
|
13
|
+
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
14
|
+
|
15
|
+
export function replaceImportsInJsCode_webpack(params: { jsCode: string; buildOptions: BuildOptionsLike; systemType?: "posix" | "win32" }): {
|
16
|
+
fixedJsCode: string;
|
17
|
+
} {
|
18
|
+
const { jsCode, buildOptions, systemType = nodePath.sep === "/" ? "posix" : "win32" } = params;
|
19
|
+
|
20
|
+
const { relative: pathRelative, sep: pathSep } = nodePath[systemType];
|
21
|
+
|
22
|
+
let fixedJsCode = jsCode;
|
23
|
+
|
24
|
+
if (buildOptions.urlPathname !== undefined) {
|
25
|
+
// "__esModule",{value:!0})},n.p="/foo-bar/",function(){if("undefined" -> ... n.p="/" ...
|
26
|
+
fixedJsCode = fixedJsCode.replace(
|
27
|
+
new RegExp(`,([a-zA-Z]\\.[a-zA-Z])="${replaceAll(buildOptions.urlPathname, "/", "\\/")}",`, "g"),
|
28
|
+
(...[, assignTo]) => `,${assignTo}="/",`
|
29
|
+
);
|
30
|
+
}
|
31
|
+
|
32
|
+
// d={NODE_ENV:"production",PUBLIC_URL:"/foo-bar",WDS_SOCKET_HOST
|
33
|
+
// d={NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST
|
34
|
+
// ->
|
35
|
+
// ... PUBLIC_URL:window.kcContext.url.resourcesPath+"/build" ...
|
36
|
+
fixedJsCode = fixedJsCode.replace(
|
37
|
+
new RegExp(
|
38
|
+
`NODE_ENV:"production",PUBLIC_URL:"${
|
39
|
+
buildOptions.urlPathname !== undefined ? replaceAll(buildOptions.urlPathname.slice(0, -1), "/", "\\/") : ""
|
40
|
+
}"`,
|
41
|
+
"g"
|
42
|
+
),
|
43
|
+
`NODE_ENV:"production",PUBLIC_URL:window.${nameOfTheGlobal}.url.resourcesPath+"/${basenameOfTheKeycloakifyResourcesDir}"`
|
44
|
+
);
|
45
|
+
|
46
|
+
// Example: "static/ or "foo/bar/"
|
47
|
+
const staticDir = (() => {
|
48
|
+
let out = pathRelative(buildOptions.reactAppBuildDirPath, buildOptions.assetsDirPath);
|
49
|
+
|
50
|
+
out = replaceAll(out, pathSep, "/") + "/";
|
51
|
+
|
52
|
+
if (out === "/") {
|
53
|
+
throw new Error(`The assetsDirPath must be a subdirectory of reactAppBuildDirPath`);
|
54
|
+
}
|
55
|
+
|
56
|
+
return out;
|
57
|
+
})();
|
58
|
+
|
59
|
+
const getReplaceArgs = (language: "js" | "css"): Parameters<typeof String.prototype.replace> => [
|
60
|
+
new RegExp(`([a-zA-Z_]+)\\.([a-zA-Z]+)=(function\\(([a-z]+)\\){return|([a-z]+)=>)"${staticDir.replace(/\//g, "\\/")}${language}\\/"`, "g"),
|
61
|
+
(...[, n, u, matchedFunction, eForFunction]) => {
|
62
|
+
const isArrowFunction = matchedFunction.includes("=>");
|
63
|
+
const e = isArrowFunction ? matchedFunction.replace("=>", "").trim() : eForFunction;
|
64
|
+
|
65
|
+
return `
|
66
|
+
${n}[(function(){
|
67
|
+
var pd = Object.getOwnPropertyDescriptor(${n}, "p");
|
68
|
+
if( pd === undefined || pd.configurable ){
|
69
|
+
Object.defineProperty(${n}, "p", {
|
70
|
+
get: function() { return window.${nameOfTheGlobal}.url.resourcesPath; },
|
71
|
+
set: function() {}
|
72
|
+
});
|
73
|
+
}
|
74
|
+
return "${u}";
|
75
|
+
})()] = ${isArrowFunction ? `${e} =>` : `function(${e}) { return `} "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}${language}/"`
|
76
|
+
.replace(/\s+/g, " ")
|
77
|
+
.trim();
|
78
|
+
}
|
79
|
+
];
|
80
|
+
|
81
|
+
fixedJsCode = fixedJsCode
|
82
|
+
.replace(...getReplaceArgs("js"))
|
83
|
+
.replace(...getReplaceArgs("css"))
|
84
|
+
.replace(
|
85
|
+
new RegExp(`[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`, "g"),
|
86
|
+
`window.${nameOfTheGlobal}.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}`
|
87
|
+
);
|
88
|
+
|
89
|
+
return { fixedJsCode };
|
90
|
+
}
|