keycloakify 10.0.0-rc.63 → 10.0.0-rc.65
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/account/KcContext/KcContext.d.ts +1 -0
- package/account/KcContext/KcContext.js.map +1 -1
- package/account/KcContext/kcContextMocks.js +2 -1
- package/account/KcContext/kcContextMocks.js.map +1 -1
- package/account/pages/Totp.js +2 -7
- package/account/pages/Totp.js.map +1 -1
- package/bin/190.index.js +67 -101
- package/bin/{991.index.js → 203.index.js} +40 -19
- package/bin/{952.index.js → 363.index.js} +174 -154
- package/bin/{214.index.js → 430.index.js} +2 -161
- package/bin/526.index.js +130 -90
- package/bin/538.index.js +37 -28
- package/bin/{98.index.js → 827.index.js} +39 -187
- package/bin/{941.index.js → 890.index.js} +159 -2
- package/bin/932.index.js +104 -129
- package/bin/97.index.js +1 -1
- package/bin/main.js +7 -7
- package/package.json +9 -8
- package/src/account/KcContext/KcContext.ts +1 -0
- package/src/account/KcContext/kcContextMocks.ts +2 -1
- package/src/account/pages/Totp.tsx +1 -7
- package/src/bin/add-story.ts +1 -1
- package/src/bin/keycloakify/buildJars/buildJar.ts +24 -27
- package/src/bin/keycloakify/buildJars/buildJars.ts +5 -5
- package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +8 -6
- package/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +33 -32
- package/src/bin/keycloakify/generateResources/generateResourcesForThemeVariant.ts +22 -26
- package/src/bin/shared/downloadKeycloakDefaultTheme.ts +135 -108
- package/src/bin/shared/getImplementedThemeTypes.ts +38 -0
- package/src/bin/shared/getThemeSrcDirPath.ts +44 -32
- package/src/bin/shared/metaInfKeycloakThemes.ts +16 -60
- package/src/bin/start-keycloak/keycloakifyBuild.ts +1 -1
- package/src/bin/start-keycloak/start-keycloak.ts +35 -70
- package/vite-plugin/index.js +1917 -100
@@ -0,0 +1,38 @@
|
|
1
|
+
import { join as pathJoin } from "path";
|
2
|
+
import { objectFromEntries } from "tsafe/objectFromEntries";
|
3
|
+
import * as fs from "fs";
|
4
|
+
import { type ThemeType } from "./constants";
|
5
|
+
import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
|
6
|
+
|
7
|
+
type ImplementedThemeTypes = Readonly<Record<ThemeType | "email", boolean>>;
|
8
|
+
|
9
|
+
let cache:
|
10
|
+
| { projectDirPath: string; implementedThemeTypes: ImplementedThemeTypes }
|
11
|
+
| undefined;
|
12
|
+
|
13
|
+
export function getImplementedThemeTypes(params: { projectDirPath: string }) {
|
14
|
+
const { projectDirPath } = params;
|
15
|
+
|
16
|
+
if (cache !== undefined && cache.projectDirPath === projectDirPath) {
|
17
|
+
const { implementedThemeTypes } = cache;
|
18
|
+
return { implementedThemeTypes };
|
19
|
+
}
|
20
|
+
|
21
|
+
cache = undefined;
|
22
|
+
|
23
|
+
const { themeSrcDirPath } = getThemeSrcDirPath({
|
24
|
+
projectDirPath
|
25
|
+
});
|
26
|
+
|
27
|
+
const implementedThemeTypes: Readonly<Record<ThemeType | "email", boolean>> =
|
28
|
+
objectFromEntries(
|
29
|
+
(["login", "account", "email"] as const).map(themeType => [
|
30
|
+
themeType,
|
31
|
+
fs.existsSync(pathJoin(themeSrcDirPath, themeType))
|
32
|
+
])
|
33
|
+
);
|
34
|
+
|
35
|
+
cache = { projectDirPath, implementedThemeTypes };
|
36
|
+
|
37
|
+
return { implementedThemeTypes };
|
38
|
+
}
|
@@ -3,48 +3,60 @@ import { exclude } from "tsafe";
|
|
3
3
|
import { crawl } from "../tools/crawl";
|
4
4
|
import { join as pathJoin } from "path";
|
5
5
|
import { themeTypes } from "./constants";
|
6
|
+
import chalk from "chalk";
|
6
7
|
|
7
|
-
|
8
|
+
let cache: { projectDirPath: string; themeSrcDirPath: string } | undefined = undefined;
|
8
9
|
|
9
10
|
/** Can't catch error, if the directory isn't found, this function will just exit the process with an error message. */
|
10
11
|
export function getThemeSrcDirPath(params: { projectDirPath: string }) {
|
11
12
|
const { projectDirPath } = params;
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
const themeSrcDirPath: string | undefined = crawl({
|
16
|
-
dirPath: srcDirPath,
|
17
|
-
returnedPathsType: "relative to dirPath"
|
18
|
-
})
|
19
|
-
.map(fileRelativePath => {
|
20
|
-
for (const themeSrcDirBasename of themeSrcDirBasenames) {
|
21
|
-
const split = fileRelativePath.split(themeSrcDirBasename);
|
22
|
-
if (split.length === 2) {
|
23
|
-
return pathJoin(srcDirPath, split[0] + themeSrcDirBasename);
|
24
|
-
}
|
25
|
-
}
|
26
|
-
return undefined;
|
27
|
-
})
|
28
|
-
.filter(exclude(undefined))[0];
|
29
|
-
|
30
|
-
if (themeSrcDirPath !== undefined) {
|
14
|
+
if (cache !== undefined && cache.projectDirPath === projectDirPath) {
|
15
|
+
const { themeSrcDirPath } = cache;
|
31
16
|
return { themeSrcDirPath };
|
32
17
|
}
|
33
18
|
|
34
|
-
|
35
|
-
|
36
|
-
|
19
|
+
cache = undefined;
|
20
|
+
|
21
|
+
const { themeSrcDirPath } = (() => {
|
22
|
+
const srcDirPath = pathJoin(projectDirPath, "src");
|
23
|
+
|
24
|
+
const themeSrcDirPath: string | undefined = crawl({
|
25
|
+
dirPath: srcDirPath,
|
26
|
+
returnedPathsType: "relative to dirPath"
|
27
|
+
})
|
28
|
+
.map(fileRelativePath => {
|
29
|
+
for (const themeSrcDirBasename of themeSrcDirBasenames) {
|
30
|
+
const split = fileRelativePath.split(themeSrcDirBasename);
|
31
|
+
if (split.length === 2) {
|
32
|
+
return pathJoin(srcDirPath, split[0] + themeSrcDirBasename);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
return undefined;
|
36
|
+
})
|
37
|
+
.filter(exclude(undefined))[0];
|
38
|
+
|
39
|
+
if (themeSrcDirPath !== undefined) {
|
40
|
+
return { themeSrcDirPath };
|
41
|
+
}
|
42
|
+
|
43
|
+
for (const themeType of [...themeTypes, "email"]) {
|
44
|
+
if (!fs.existsSync(pathJoin(srcDirPath, themeType))) {
|
45
|
+
continue;
|
46
|
+
}
|
47
|
+
return { themeSrcDirPath: srcDirPath };
|
37
48
|
}
|
38
|
-
return { themeSrcDirPath: srcDirPath };
|
39
|
-
}
|
40
49
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
"src/ or src/keycloak-theme or src/keycloak_theme.",
|
45
|
-
"Example in the starter: https://github.com/keycloakify/keycloakify-starter/tree/main/src/keycloak-theme"
|
46
|
-
].join("\n")
|
47
|
-
);
|
50
|
+
console.log(
|
51
|
+
chalk.red("Can't locate your theme source directory. It should be either: ")
|
52
|
+
);
|
48
53
|
|
49
|
-
|
54
|
+
process.exit(-1);
|
55
|
+
})();
|
56
|
+
|
57
|
+
cache = { projectDirPath, themeSrcDirPath };
|
58
|
+
|
59
|
+
return { themeSrcDirPath };
|
50
60
|
}
|
61
|
+
|
62
|
+
const themeSrcDirBasenames = ["keycloak-theme", "keycloak_theme"];
|
@@ -1,84 +1,40 @@
|
|
1
1
|
import { join as pathJoin, dirname as pathDirname } from "path";
|
2
2
|
import type { ThemeType } from "./constants";
|
3
3
|
import * as fs from "fs";
|
4
|
-
import { assert } from "tsafe/assert";
|
5
|
-
import { extractArchive } from "../tools/extractArchive";
|
6
4
|
|
7
5
|
export type MetaInfKeycloakTheme = {
|
8
6
|
themes: { name: string; types: (ThemeType | "email")[] }[];
|
9
7
|
};
|
10
8
|
|
11
|
-
export function
|
12
|
-
resourcesDirPath: string;
|
13
|
-
}) {
|
14
|
-
const { resourcesDirPath } = params;
|
15
|
-
|
16
|
-
return pathJoin(
|
17
|
-
resourcesDirPath === "." ? "" : resourcesDirPath,
|
18
|
-
"META-INF",
|
19
|
-
"keycloak-themes.json"
|
20
|
-
);
|
21
|
-
}
|
22
|
-
|
23
|
-
export function readMetaInfKeycloakThemes_fromResourcesDirPath(params: {
|
9
|
+
export function writeMetaInfKeycloakThemes(params: {
|
24
10
|
resourcesDirPath: string;
|
11
|
+
getNewMetaInfKeycloakTheme: (params: {
|
12
|
+
metaInfKeycloakTheme: MetaInfKeycloakTheme | undefined;
|
13
|
+
}) => MetaInfKeycloakTheme;
|
25
14
|
}) {
|
26
|
-
const { resourcesDirPath } = params;
|
27
|
-
|
28
|
-
return JSON.parse(
|
29
|
-
fs
|
30
|
-
.readFileSync(
|
31
|
-
getMetaInfKeycloakThemesJsonFilePath({
|
32
|
-
resourcesDirPath
|
33
|
-
})
|
34
|
-
)
|
35
|
-
.toString("utf8")
|
36
|
-
) as MetaInfKeycloakTheme;
|
37
|
-
}
|
15
|
+
const { resourcesDirPath, getNewMetaInfKeycloakTheme } = params;
|
38
16
|
|
39
|
-
|
40
|
-
jarFilePath: string;
|
41
|
-
}): Promise<MetaInfKeycloakTheme> {
|
42
|
-
const { jarFilePath } = params;
|
43
|
-
let metaInfKeycloakThemes: MetaInfKeycloakTheme | undefined = undefined;
|
17
|
+
const filePath = pathJoin(resourcesDirPath, "META-INF", "keycloak-themes.json");
|
44
18
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
getMetaInfKeycloakThemesJsonFilePath({ resourcesDirPath: "." })
|
51
|
-
) {
|
52
|
-
metaInfKeycloakThemes = JSON.parse((await readFile()).toString("utf8"));
|
53
|
-
earlyExit();
|
54
|
-
}
|
55
|
-
}
|
56
|
-
});
|
57
|
-
|
58
|
-
assert(metaInfKeycloakThemes !== undefined);
|
59
|
-
|
60
|
-
return metaInfKeycloakThemes;
|
61
|
-
}
|
62
|
-
|
63
|
-
export function writeMetaInfKeycloakThemes(params: {
|
64
|
-
resourcesDirPath: string;
|
65
|
-
metaInfKeycloakThemes: MetaInfKeycloakTheme;
|
66
|
-
}) {
|
67
|
-
const { resourcesDirPath, metaInfKeycloakThemes } = params;
|
19
|
+
const currentMetaInfKeycloakTheme = !fs.existsSync(filePath)
|
20
|
+
? undefined
|
21
|
+
: (JSON.parse(
|
22
|
+
fs.readFileSync(filePath).toString("utf8")
|
23
|
+
) as MetaInfKeycloakTheme);
|
68
24
|
|
69
|
-
const
|
70
|
-
|
25
|
+
const newMetaInfKeycloakThemes = getNewMetaInfKeycloakTheme({
|
26
|
+
metaInfKeycloakTheme: currentMetaInfKeycloakTheme
|
71
27
|
});
|
72
28
|
|
73
29
|
{
|
74
|
-
const dirPath = pathDirname(
|
30
|
+
const dirPath = pathDirname(filePath);
|
75
31
|
if (!fs.existsSync(dirPath)) {
|
76
32
|
fs.mkdirSync(dirPath, { recursive: true });
|
77
33
|
}
|
78
34
|
}
|
79
35
|
|
80
36
|
fs.writeFileSync(
|
81
|
-
|
82
|
-
Buffer.from(JSON.stringify(
|
37
|
+
filePath,
|
38
|
+
Buffer.from(JSON.stringify(newMetaInfKeycloakThemes, null, 2), "utf8")
|
83
39
|
);
|
84
40
|
}
|
@@ -14,7 +14,7 @@ export type BuildContextLike = {
|
|
14
14
|
assert<BuildContext extends BuildContextLike ? true : false>();
|
15
15
|
|
16
16
|
export async function keycloakifyBuild(params: {
|
17
|
-
onlyBuildJarFileBasename: string
|
17
|
+
onlyBuildJarFileBasename: string;
|
18
18
|
buildContext: BuildContextLike;
|
19
19
|
}): Promise<{ isKeycloakifyBuildSuccess: boolean }> {
|
20
20
|
const { buildContext, onlyBuildJarFileBasename } = params;
|
@@ -2,7 +2,7 @@ import { getBuildContext } from "../shared/buildContext";
|
|
2
2
|
import { exclude } from "tsafe/exclude";
|
3
3
|
import type { CliCommandOptions as CliCommandOptions_common } from "../main";
|
4
4
|
import { promptKeycloakVersion } from "../shared/promptKeycloakVersion";
|
5
|
-
import {
|
5
|
+
import { getImplementedThemeTypes } from "../shared/getImplementedThemeTypes";
|
6
6
|
import { accountV1ThemeName, containerName } from "../shared/constants";
|
7
7
|
import { SemVer } from "../tools/SemVer";
|
8
8
|
import type { KeycloakVersionRange } from "../shared/KeycloakVersionRange";
|
@@ -91,66 +91,8 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
91
91
|
|
92
92
|
const buildContext = getBuildContext({ cliCommandOptions });
|
93
93
|
|
94
|
-
{
|
95
|
-
const { isAppBuildSuccess } = await appBuild({
|
96
|
-
buildContext
|
97
|
-
});
|
98
|
-
|
99
|
-
if (!isAppBuildSuccess) {
|
100
|
-
console.log(
|
101
|
-
chalk.red(
|
102
|
-
`App build failed, exiting. Try running 'yarn build-keycloak-theme' and see what's wrong.`
|
103
|
-
)
|
104
|
-
);
|
105
|
-
process.exit(1);
|
106
|
-
}
|
107
|
-
|
108
|
-
const { isKeycloakifyBuildSuccess } = await keycloakifyBuild({
|
109
|
-
onlyBuildJarFileBasename: undefined,
|
110
|
-
buildContext
|
111
|
-
});
|
112
|
-
|
113
|
-
if (!isKeycloakifyBuildSuccess) {
|
114
|
-
console.log(
|
115
|
-
chalk.red(
|
116
|
-
`Keycloakify build failed, exiting. Try running 'yarn build-keycloak-theme' and see what's wrong.`
|
117
|
-
)
|
118
|
-
);
|
119
|
-
process.exit(1);
|
120
|
-
}
|
121
|
-
}
|
122
|
-
|
123
|
-
const { doesImplementAccountTheme } = await (async () => {
|
124
|
-
const latestJarFilePath = fs
|
125
|
-
.readdirSync(buildContext.keycloakifyBuildDirPath)
|
126
|
-
.filter(fileBasename => fileBasename.endsWith(".jar"))
|
127
|
-
.map(fileBasename =>
|
128
|
-
pathJoin(buildContext.keycloakifyBuildDirPath, fileBasename)
|
129
|
-
)
|
130
|
-
.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs)[0];
|
131
|
-
|
132
|
-
assert(latestJarFilePath !== undefined);
|
133
|
-
|
134
|
-
const metaInfKeycloakThemes = await readMetaInfKeycloakThemes_fromJar({
|
135
|
-
jarFilePath: latestJarFilePath
|
136
|
-
});
|
137
|
-
|
138
|
-
const mainThemeEntry = metaInfKeycloakThemes.themes.find(
|
139
|
-
({ name }) => name === buildContext.themeNames[0]
|
140
|
-
);
|
141
|
-
|
142
|
-
assert(mainThemeEntry !== undefined);
|
143
|
-
|
144
|
-
const doesImplementAccountTheme = mainThemeEntry.types.includes("account");
|
145
|
-
|
146
|
-
return { doesImplementAccountTheme };
|
147
|
-
})();
|
148
|
-
|
149
94
|
const { keycloakVersion, keycloakMajorNumber: keycloakMajorVersionNumber } =
|
150
|
-
await (async
|
151
|
-
keycloakVersion: string;
|
152
|
-
keycloakMajorNumber: number;
|
153
|
-
}> {
|
95
|
+
await (async () => {
|
154
96
|
if (cliCommandOptions.keycloakVersion !== undefined) {
|
155
97
|
return {
|
156
98
|
keycloakVersion: cliCommandOptions.keycloakVersion,
|
@@ -173,20 +115,14 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
173
115
|
|
174
116
|
const keycloakMajorNumber = SemVer.parse(keycloakVersion).major;
|
175
117
|
|
176
|
-
if (doesImplementAccountTheme && keycloakMajorNumber === 22) {
|
177
|
-
console.log(
|
178
|
-
[
|
179
|
-
"Unfortunately, Keycloakify themes that implements an account theme do not work on Keycloak 22",
|
180
|
-
"Please select any other Keycloak version"
|
181
|
-
].join(" ")
|
182
|
-
);
|
183
|
-
return getKeycloakMajor();
|
184
|
-
}
|
185
|
-
|
186
118
|
return { keycloakVersion, keycloakMajorNumber };
|
187
119
|
})();
|
188
120
|
|
189
121
|
const keycloakVersionRange: KeycloakVersionRange = (() => {
|
122
|
+
const doesImplementAccountTheme = getImplementedThemeTypes({
|
123
|
+
projectDirPath: buildContext.projectDirPath
|
124
|
+
}).implementedThemeTypes.account;
|
125
|
+
|
190
126
|
if (doesImplementAccountTheme) {
|
191
127
|
const keycloakVersionRange = (() => {
|
192
128
|
if (keycloakMajorVersionNumber <= 21) {
|
@@ -233,6 +169,35 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
233
169
|
|
234
170
|
const { jarFileBasename } = getJarFileBasename({ keycloakVersionRange });
|
235
171
|
|
172
|
+
{
|
173
|
+
const { isAppBuildSuccess } = await appBuild({
|
174
|
+
buildContext
|
175
|
+
});
|
176
|
+
|
177
|
+
if (!isAppBuildSuccess) {
|
178
|
+
console.log(
|
179
|
+
chalk.red(
|
180
|
+
`App build failed, exiting. Try running 'npm run build-keycloak-theme' and see what's wrong.`
|
181
|
+
)
|
182
|
+
);
|
183
|
+
process.exit(1);
|
184
|
+
}
|
185
|
+
|
186
|
+
const { isKeycloakifyBuildSuccess } = await keycloakifyBuild({
|
187
|
+
onlyBuildJarFileBasename: jarFileBasename,
|
188
|
+
buildContext
|
189
|
+
});
|
190
|
+
|
191
|
+
if (!isKeycloakifyBuildSuccess) {
|
192
|
+
console.log(
|
193
|
+
chalk.red(
|
194
|
+
`Keycloakify build failed, exiting. Try running 'npm run build-keycloak-theme' and see what's wrong.`
|
195
|
+
)
|
196
|
+
);
|
197
|
+
process.exit(1);
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
236
201
|
console.log(`Using Keycloak ${chalk.bold(jarFileBasename)}`);
|
237
202
|
|
238
203
|
const realmJsonFilePath = await (async () => {
|