keycloakify 10.0.0-rc.44 → 10.0.0-rc.45

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.
Files changed (32) hide show
  1. package/bin/{322.index.js → 190.index.js} +58 -61
  2. package/bin/193.index.js +0 -51
  3. package/bin/3.index.js +83 -94
  4. package/bin/526.index.js +76 -48
  5. package/bin/538.index.js +5 -3
  6. package/bin/932.index.js +535 -1
  7. package/bin/98.index.js +5 -3
  8. package/bin/{944.index.js → 991.index.js} +74 -5
  9. package/bin/main.js +4 -16
  10. package/bin/shared/buildContext.d.ts +1 -1
  11. package/bin/shared/constants.d.ts +1 -1
  12. package/bin/shared/constants.js +1 -1
  13. package/bin/shared/constants.js.map +1 -1
  14. package/package.json +3 -6
  15. package/src/bin/keycloakify/buildJars/buildJar.ts +9 -21
  16. package/src/bin/keycloakify/buildJars/buildJars.ts +15 -4
  17. package/src/bin/keycloakify/generateSrcMainResources/bringInAccountV1.ts +6 -7
  18. package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResources.ts +11 -3
  19. package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForMainTheme.ts +6 -18
  20. package/src/bin/keycloakify/generateSrcMainResources/generateSrcMainResourcesForThemeVariant.ts +9 -15
  21. package/src/bin/keycloakify/keycloakify.ts +20 -9
  22. package/src/bin/main.ts +0 -14
  23. package/src/bin/shared/buildContext.ts +7 -3
  24. package/src/bin/shared/constants.ts +1 -1
  25. package/src/bin/shared/metaInfKeycloakThemes.ts +37 -14
  26. package/src/bin/start-keycloak/keycloakifyBuild.ts +4 -4
  27. package/src/bin/start-keycloak/start-keycloak.ts +57 -66
  28. package/src/vite-plugin/vite-plugin.ts +4 -0
  29. package/vite-plugin/index.js +6 -3
  30. package/bin/961.index.js +0 -263
  31. package/src/bin/download-keycloak-default-theme.ts +0 -63
  32. package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +0 -74
package/src/bin/main.ts CHANGED
@@ -134,20 +134,6 @@ program
134
134
  }
135
135
  });
136
136
 
137
- program
138
- .command({
139
- name: "download-keycloak-default-theme",
140
- description: "Download the built-in Keycloak theme."
141
- })
142
- .task({
143
- skip,
144
- handler: async cliCommandOptions => {
145
- const { command } = await import("./download-keycloak-default-theme");
146
-
147
- await command({ cliCommandOptions });
148
- }
149
- });
150
-
151
137
  program
152
138
  .command({
153
139
  name: "eject-page",
@@ -12,7 +12,7 @@ import { vitePluginSubScriptEnvNames } from "./constants";
12
12
  export type BuildContext = {
13
13
  bundler: "vite" | "webpack";
14
14
  themeVersion: string;
15
- themeNames: string[];
15
+ themeNames: [string, ...string[]];
16
16
  extraThemeProperties: string[] | undefined;
17
17
  groupId: string;
18
18
  artifactId: string;
@@ -147,7 +147,7 @@ export function getBuildContext(params: {
147
147
  ...resolvedViteConfig?.buildOptions
148
148
  };
149
149
 
150
- const themeNames = (() => {
150
+ const themeNames = ((): [string, ...string[]] => {
151
151
  if (buildOptions.themeName === undefined) {
152
152
  return [
153
153
  parsedPackageJson.name
@@ -161,7 +161,11 @@ export function getBuildContext(params: {
161
161
  return [buildOptions.themeName];
162
162
  }
163
163
 
164
- return buildOptions.themeName;
164
+ const [mainThemeName, ...themeVariantNames] = buildOptions.themeName;
165
+
166
+ assert(mainThemeName !== undefined);
167
+
168
+ return [mainThemeName, ...themeVariantNames];
165
169
  })();
166
170
 
167
171
  const projectBuildDirPath = (() => {
@@ -16,7 +16,7 @@ export const vitePluginSubScriptEnvNames = {
16
16
  resolveViteConfig: "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
17
17
  } as const;
18
18
 
19
- export const skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
19
+ export const onlyBuildJarFileBasenameEnvName = "KEYCLOAKIFY_ONLY_BUILD_JAR_FILE_BASENAME";
20
20
 
21
21
  export const loginThemePageIds = [
22
22
  "login.ftl",
@@ -1,50 +1,73 @@
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";
4
6
 
5
7
  export type MetaInfKeycloakTheme = {
6
8
  themes: { name: string; types: (ThemeType | "email")[] }[];
7
9
  };
8
10
 
9
11
  export function getMetaInfKeycloakThemesJsonFilePath(params: {
10
- keycloakifyBuildDirPath: string;
12
+ resourcesDirPath: string;
11
13
  }) {
12
- const { keycloakifyBuildDirPath } = params;
14
+ const { resourcesDirPath } = params;
13
15
 
14
16
  return pathJoin(
15
- keycloakifyBuildDirPath === "." ? "" : keycloakifyBuildDirPath,
16
- "src",
17
- "main",
18
- "resources",
17
+ resourcesDirPath === "." ? "" : resourcesDirPath,
19
18
  "META-INF",
20
19
  "keycloak-themes.json"
21
20
  );
22
21
  }
23
22
 
24
- export function readMetaInfKeycloakThemes(params: {
25
- keycloakifyBuildDirPath: string;
26
- }): MetaInfKeycloakTheme {
27
- const { keycloakifyBuildDirPath } = params;
23
+ export function readMetaInfKeycloakThemes_fromResourcesDirPath(params: {
24
+ resourcesDirPath: string;
25
+ }) {
26
+ const { resourcesDirPath } = params;
28
27
 
29
28
  return JSON.parse(
30
29
  fs
31
30
  .readFileSync(
32
31
  getMetaInfKeycloakThemesJsonFilePath({
33
- keycloakifyBuildDirPath
32
+ resourcesDirPath
34
33
  })
35
34
  )
36
35
  .toString("utf8")
37
36
  ) as MetaInfKeycloakTheme;
38
37
  }
39
38
 
39
+ export async function readMetaInfKeycloakThemes_fromJar(params: {
40
+ jarFilePath: string;
41
+ }): Promise<MetaInfKeycloakTheme> {
42
+ const { jarFilePath } = params;
43
+ let metaInfKeycloakThemes: MetaInfKeycloakTheme | undefined = undefined;
44
+
45
+ await extractArchive({
46
+ archiveFilePath: jarFilePath,
47
+ onArchiveFile: async ({ relativeFilePathInArchive, readFile, earlyExit }) => {
48
+ if (
49
+ relativeFilePathInArchive ===
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
+
40
63
  export function writeMetaInfKeycloakThemes(params: {
41
- keycloakifyBuildDirPath: string;
64
+ resourcesDirPath: string;
42
65
  metaInfKeycloakThemes: MetaInfKeycloakTheme;
43
66
  }) {
44
- const { keycloakifyBuildDirPath, metaInfKeycloakThemes } = params;
67
+ const { resourcesDirPath, metaInfKeycloakThemes } = params;
45
68
 
46
69
  const metaInfKeycloakThemesJsonPath = getMetaInfKeycloakThemesJsonFilePath({
47
- keycloakifyBuildDirPath
70
+ resourcesDirPath
48
71
  });
49
72
 
50
73
  {
@@ -1,4 +1,4 @@
1
- import { skipBuildJarsEnvName } from "../shared/constants";
1
+ import { onlyBuildJarFileBasenameEnvName } from "../shared/constants";
2
2
  import * as child_process from "child_process";
3
3
  import { Deferred } from "evt/tools/Deferred";
4
4
  import { assert } from "tsafe/assert";
@@ -14,10 +14,10 @@ export type BuildContextLike = {
14
14
  assert<BuildContext extends BuildContextLike ? true : false>();
15
15
 
16
16
  export async function keycloakifyBuild(params: {
17
- doSkipBuildJars: boolean;
17
+ onlyBuildJarFileBasename: string | undefined;
18
18
  buildContext: BuildContextLike;
19
19
  }): Promise<{ isKeycloakifyBuildSuccess: boolean }> {
20
- const { buildContext, doSkipBuildJars } = params;
20
+ const { buildContext, onlyBuildJarFileBasename } = params;
21
21
 
22
22
  const dResult = new Deferred<{ isSuccess: boolean }>();
23
23
 
@@ -25,7 +25,7 @@ export async function keycloakifyBuild(params: {
25
25
  cwd: buildContext.projectDirPath,
26
26
  env: {
27
27
  ...process.env,
28
- ...(doSkipBuildJars ? { [skipBuildJarsEnvName]: "true" } : {})
28
+ [onlyBuildJarFileBasenameEnvName]: onlyBuildJarFileBasename
29
29
  }
30
30
  });
31
31
 
@@ -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 { readMetaInfKeycloakThemes } from "../shared/metaInfKeycloakThemes";
5
+ import { readMetaInfKeycloakThemes_fromJar } from "../shared/metaInfKeycloakThemes";
6
6
  import { accountV1ThemeName, containerName } from "../shared/constants";
7
7
  import { SemVer } from "../tools/SemVer";
8
8
  import type { KeycloakVersionRange } from "../shared/KeycloakVersionRange";
@@ -21,6 +21,9 @@ import * as runExclusive from "run-exclusive";
21
21
  import { extractArchive } from "../tools/extractArchive";
22
22
  import { appBuild } from "./appBuild";
23
23
  import { keycloakifyBuild } from "./keycloakifyBuild";
24
+ import { isInside } from "../tools/isInside";
25
+ import { existsAsync } from "../tools/fs.existsAsync";
26
+ import { rm } from "../tools/fs.rm";
24
27
 
25
28
  export type CliCommandOptions = CliCommandOptions_common & {
26
29
  port: number;
@@ -98,7 +101,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
98
101
  }
99
102
 
100
103
  const { isKeycloakifyBuildSuccess } = await keycloakifyBuild({
101
- doSkipBuildJars: false,
104
+ onlyBuildJarFileBasename: undefined,
102
105
  buildContext
103
106
  });
104
107
 
@@ -112,13 +115,31 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
112
115
  }
113
116
  }
114
117
 
115
- const metaInfKeycloakThemes = readMetaInfKeycloakThemes({
116
- keycloakifyBuildDirPath: buildContext.keycloakifyBuildDirPath
117
- });
118
+ const { doesImplementAccountTheme } = await (async () => {
119
+ const latestJarFilePath = fs
120
+ .readdirSync(buildContext.keycloakifyBuildDirPath)
121
+ .filter(fileBasename => fileBasename.endsWith(".jar"))
122
+ .map(fileBasename =>
123
+ pathJoin(buildContext.keycloakifyBuildDirPath, fileBasename)
124
+ )
125
+ .sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs)[0];
126
+
127
+ assert(latestJarFilePath !== undefined);
118
128
 
119
- const doesImplementAccountTheme = metaInfKeycloakThemes.themes.some(
120
- ({ name }) => name === accountV1ThemeName
121
- );
129
+ const metaInfKeycloakThemes = await readMetaInfKeycloakThemes_fromJar({
130
+ jarFilePath: latestJarFilePath
131
+ });
132
+
133
+ const mainThemeEntry = metaInfKeycloakThemes.themes.find(
134
+ ({ name }) => name === buildContext.themeNames[0]
135
+ );
136
+
137
+ assert(mainThemeEntry !== undefined);
138
+
139
+ const doesImplementAccountTheme = mainThemeEntry.types.includes("account");
140
+
141
+ return { doesImplementAccountTheme };
142
+ })();
122
143
 
123
144
  const { keycloakVersion, keycloakMajorNumber: keycloakMajorVersionNumber } =
124
145
  await (async function getKeycloakMajor(): Promise<{
@@ -262,65 +283,30 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
262
283
 
263
284
  const jarFilePath = pathJoin(buildContext.keycloakifyBuildDirPath, jarFileBasename);
264
285
 
265
- const { doUseBuiltInAccountV1Theme } = await (async () => {
266
- let doUseBuiltInAccountV1Theme = false;
267
-
286
+ async function extractThemeResourcesFromJar() {
268
287
  await extractArchive({
269
288
  archiveFilePath: jarFilePath,
270
- onArchiveFile: async ({ relativeFilePathInArchive, readFile, earlyExit }) => {
271
- for (const themeName of buildContext.themeNames) {
272
- if (
273
- relativeFilePathInArchive ===
274
- pathJoin("theme", themeName, "account", "theme.properties")
275
- ) {
276
- if (
277
- (await readFile())
278
- .toString("utf8")
279
- .includes("parent=keycloak")
280
- ) {
281
- doUseBuiltInAccountV1Theme = true;
282
- }
283
-
284
- earlyExit();
285
- }
289
+ onArchiveFile: async ({ relativeFilePathInArchive, writeFile }) => {
290
+ if (isInside({ dirPath: "theme", filePath: relativeFilePathInArchive })) {
291
+ await writeFile({
292
+ filePath: pathJoin(
293
+ buildContext.keycloakifyBuildDirPath,
294
+ relativeFilePathInArchive
295
+ )
296
+ });
286
297
  }
287
298
  }
288
299
  });
300
+ }
289
301
 
290
- return { doUseBuiltInAccountV1Theme };
291
- })();
302
+ {
303
+ const destDirPath = pathJoin(buildContext.keycloakifyBuildDirPath, "theme");
304
+ if (await existsAsync(destDirPath)) {
305
+ await rm(destDirPath, { recursive: true });
306
+ }
307
+ }
292
308
 
293
- const accountThemePropertyPatch = !doUseBuiltInAccountV1Theme
294
- ? undefined
295
- : () => {
296
- for (const themeName of buildContext.themeNames) {
297
- const filePath = pathJoin(
298
- buildContext.keycloakifyBuildDirPath,
299
- "src",
300
- "main",
301
- "resources",
302
- "theme",
303
- themeName,
304
- "account",
305
- "theme.properties"
306
- );
307
-
308
- const sourceCode = fs.readFileSync(filePath);
309
-
310
- const modifiedSourceCode = Buffer.from(
311
- sourceCode
312
- .toString("utf8")
313
- .replace(`parent=${accountV1ThemeName}`, "parent=keycloak"),
314
- "utf8"
315
- );
316
-
317
- assert(Buffer.compare(modifiedSourceCode, sourceCode) !== 0);
318
-
319
- fs.writeFileSync(filePath, modifiedSourceCode);
320
- }
321
- };
322
-
323
- accountThemePropertyPatch?.();
309
+ await extractThemeResourcesFromJar();
324
310
 
325
311
  try {
326
312
  child_process.execSync(`docker rm --force ${containerName}`, {
@@ -348,14 +334,19 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
348
334
  : []),
349
335
  ...[
350
336
  ...buildContext.themeNames,
351
- ...(doUseBuiltInAccountV1Theme ? [] : [accountV1ThemeName])
337
+ ...(fs.existsSync(
338
+ pathJoin(
339
+ buildContext.keycloakifyBuildDirPath,
340
+ "theme",
341
+ accountV1ThemeName
342
+ )
343
+ )
344
+ ? [accountV1ThemeName]
345
+ : [])
352
346
  ]
353
347
  .map(themeName => ({
354
348
  localDirPath: pathJoin(
355
349
  buildContext.keycloakifyBuildDirPath,
356
- "src",
357
- "main",
358
- "resources",
359
350
  "theme",
360
351
  themeName
361
352
  ),
@@ -451,7 +442,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
451
442
  }
452
443
 
453
444
  const { isKeycloakifyBuildSuccess } = await keycloakifyBuild({
454
- doSkipBuildJars: true,
445
+ onlyBuildJarFileBasename: jarFileBasename,
455
446
  buildContext
456
447
  });
457
448
 
@@ -459,7 +450,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
459
450
  return;
460
451
  }
461
452
 
462
- accountThemePropertyPatch?.();
453
+ await extractThemeResourcesFromJar();
463
454
 
464
455
  console.log(chalk.green("Theme rebuilt and updated in Keycloak."));
465
456
  });
@@ -47,6 +47,10 @@ export function keycloakify(params?: Params) {
47
47
 
48
48
  const buildContext = JSON.parse(envValue) as BuildContext;
49
49
 
50
+ process.chdir(
51
+ pathJoin(buildContext.keycloakifyBuildDirPath, "resources")
52
+ );
53
+
50
54
  await postBuild?.(buildContext);
51
55
 
52
56
  process.exit(0);
@@ -4128,7 +4128,9 @@ function getBuildContext(params) {
4128
4128
  if (typeof buildOptions.themeName === "string") {
4129
4129
  return [buildOptions.themeName];
4130
4130
  }
4131
- return buildOptions.themeName;
4131
+ const [mainThemeName, ...themeVariantNames] = buildOptions.themeName;
4132
+ (0,tsafe.assert)(mainThemeName !== undefined);
4133
+ return [mainThemeName, ...themeVariantNames];
4132
4134
  })();
4133
4135
  const projectBuildDirPath = (() => {
4134
4136
  var _a;
@@ -4268,8 +4270,8 @@ __nccwpck_require__.r(__webpack_exports__);
4268
4270
  /* harmony export */ "loginThemePageIds": () => (/* binding */ loginThemePageIds),
4269
4271
  /* harmony export */ "nameOfTheGlobal": () => (/* binding */ nameOfTheGlobal),
4270
4272
  /* harmony export */ "nameOfTheLocalizationRealmOverridesUserProfileProperty": () => (/* binding */ nameOfTheLocalizationRealmOverridesUserProfileProperty),
4273
+ /* harmony export */ "onlyBuildJarFileBasenameEnvName": () => (/* binding */ onlyBuildJarFileBasenameEnvName),
4271
4274
  /* harmony export */ "resources_common": () => (/* binding */ resources_common),
4272
- /* harmony export */ "skipBuildJarsEnvName": () => (/* binding */ skipBuildJarsEnvName),
4273
4275
  /* harmony export */ "themeTypes": () => (/* binding */ themeTypes),
4274
4276
  /* harmony export */ "vitePluginSubScriptEnvNames": () => (/* binding */ vitePluginSubScriptEnvNames)
4275
4277
  /* harmony export */ });
@@ -4285,7 +4287,7 @@ const vitePluginSubScriptEnvNames = {
4285
4287
  runPostBuildScript: "KEYCLOAKIFY_RUN_POST_BUILD_SCRIPT",
4286
4288
  resolveViteConfig: "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
4287
4289
  };
4288
- const skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
4290
+ const onlyBuildJarFileBasenameEnvName = "KEYCLOAKIFY_ONLY_BUILD_JAR_FILE_BASENAME";
4289
4291
  const loginThemePageIds = [
4290
4292
  "login.ftl",
4291
4293
  "login-username.ftl",
@@ -5429,6 +5431,7 @@ function keycloakify(params) {
5429
5431
  break run_post_build_script_case;
5430
5432
  }
5431
5433
  const buildContext = JSON.parse(envValue);
5434
+ process.chdir((0, path_1.join)(buildContext.keycloakifyBuildDirPath, "resources"));
5432
5435
  await (postBuild === null || postBuild === void 0 ? void 0 : postBuild(buildContext));
5433
5436
  process.exit(0);
5434
5437
  }