keycloakify 9.3.1 → 9.4.0-rc.1

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 (176) hide show
  1. package/README.md +4 -0
  2. package/account/kcContext/getKcContextFromWindow.js +2 -2
  3. package/account/kcContext/getKcContextFromWindow.js.map +1 -1
  4. package/bin/constants.d.ts +4 -1
  5. package/bin/constants.js +5 -2
  6. package/bin/constants.js.map +1 -1
  7. package/bin/copy-keycloak-resources-to-public.js +3 -4
  8. package/bin/copy-keycloak-resources-to-public.js.map +1 -1
  9. package/bin/download-builtin-keycloak-theme.js +163 -53
  10. package/bin/download-builtin-keycloak-theme.js.map +1 -1
  11. package/bin/eject-keycloak-page.js +2 -2
  12. package/bin/eject-keycloak-page.js.map +1 -1
  13. package/bin/{getSrcDirPath.js → getThemeSrcDirPath.js} +1 -1
  14. package/bin/getThemeSrcDirPath.js.map +1 -0
  15. package/bin/initialize-email-theme.js +6 -5
  16. package/bin/initialize-email-theme.js.map +1 -1
  17. package/bin/keycloakify/{BuildOptions.d.ts → buildOptions/buildOptions.d.ts} +2 -1
  18. package/bin/keycloakify/buildOptions/buildOptions.js +136 -0
  19. package/bin/keycloakify/buildOptions/buildOptions.js.map +1 -0
  20. package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.d.ts +7 -0
  21. package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js +27 -0
  22. package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js.map +1 -0
  23. package/bin/keycloakify/buildOptions/index.d.ts +1 -0
  24. package/bin/keycloakify/{generateJavaStackFiles → buildOptions}/index.js +1 -1
  25. package/bin/keycloakify/buildOptions/index.js.map +1 -0
  26. package/bin/keycloakify/buildOptions/parsedPackageJson.d.ts +19 -0
  27. package/bin/keycloakify/{parsedPackageJson.js → buildOptions/parsedPackageJson.js} +6 -7
  28. package/bin/keycloakify/buildOptions/parsedPackageJson.js.map +1 -0
  29. package/bin/keycloakify/buildOptions/resolvedViteConfig.d.ts +12 -0
  30. package/bin/keycloakify/buildOptions/resolvedViteConfig.js +82 -0
  31. package/bin/keycloakify/buildOptions/resolvedViteConfig.js.map +1 -0
  32. package/bin/keycloakify/generateFtl/generateFtl.d.ts +4 -1
  33. package/bin/keycloakify/generateFtl/generateFtl.js +5 -5
  34. package/bin/keycloakify/generateFtl/generateFtl.js.map +1 -1
  35. package/bin/keycloakify/generatePom.d.ts +12 -0
  36. package/bin/keycloakify/generatePom.js +59 -0
  37. package/bin/keycloakify/generatePom.js.map +1 -0
  38. package/bin/keycloakify/{generateJavaStackFiles → generateTheme}/bringInAccountV1.d.ts +2 -1
  39. package/bin/keycloakify/{generateJavaStackFiles → generateTheme}/bringInAccountV1.js +21 -67
  40. package/bin/keycloakify/generateTheme/bringInAccountV1.js.map +1 -0
  41. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts +0 -3
  42. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js +5 -34
  43. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map +1 -1
  44. package/bin/keycloakify/generateTheme/generateTheme.d.ts +4 -1
  45. package/bin/keycloakify/generateTheme/generateTheme.js +123 -70
  46. package/bin/keycloakify/generateTheme/generateTheme.js.map +1 -1
  47. package/bin/keycloakify/keycloakify.js +13 -72
  48. package/bin/keycloakify/keycloakify.js.map +1 -1
  49. package/bin/keycloakify/replacers/replaceImportsInCssCode.js +2 -1
  50. package/bin/keycloakify/replacers/replaceImportsInCssCode.js.map +1 -1
  51. package/bin/keycloakify/replacers/replaceImportsInInlineCssCode.js +2 -1
  52. package/bin/keycloakify/replacers/replaceImportsInInlineCssCode.js.map +1 -1
  53. package/bin/keycloakify/replacers/replaceImportsInJsCode/index.d.ts +1 -0
  54. package/bin/keycloakify/replacers/replaceImportsInJsCode/index.js +18 -0
  55. package/bin/keycloakify/replacers/replaceImportsInJsCode/index.js.map +1 -0
  56. package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.d.ts +12 -0
  57. package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.js +70 -0
  58. package/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.js.map +1 -0
  59. package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.d.ts +13 -0
  60. package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.js +95 -0
  61. package/bin/keycloakify/replacers/replaceImportsInJsCode/vite.js.map +1 -0
  62. package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.d.ts +12 -0
  63. package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.js +108 -0
  64. package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.js.map +1 -0
  65. package/bin/promptKeycloakVersion.js +0 -1
  66. package/bin/promptKeycloakVersion.js.map +1 -1
  67. package/bin/tools/OptionalIfCanBeUndefined.d.ts +14 -0
  68. package/bin/tools/OptionalIfCanBeUndefined.js +3 -0
  69. package/bin/tools/OptionalIfCanBeUndefined.js.map +1 -0
  70. package/bin/tools/SemVer.d.ts +26 -0
  71. package/bin/tools/{NpmModuleVersion.js → SemVer.js} +39 -23
  72. package/bin/tools/SemVer.js.map +1 -0
  73. package/bin/tools/String.prototype.replaceAll.d.ts +1 -0
  74. package/bin/tools/String.prototype.replaceAll.js +29 -0
  75. package/bin/tools/String.prototype.replaceAll.js.map +1 -0
  76. package/bin/tools/crawl.js +9 -9
  77. package/bin/tools/crawl.js.map +1 -1
  78. package/bin/tools/downloadAndUnzip.js +127 -32
  79. package/bin/tools/downloadAndUnzip.js.map +1 -1
  80. package/bin/tools/fs.rm.d.ts +8 -0
  81. package/bin/tools/fs.rm.js +151 -0
  82. package/bin/tools/fs.rm.js.map +1 -0
  83. package/bin/tools/fs.rmSync.d.ts +8 -0
  84. package/bin/tools/fs.rmSync.js +58 -0
  85. package/bin/tools/fs.rmSync.js.map +1 -0
  86. package/bin/tools/getAbsoluteAndInOsFormatPath.js +1 -0
  87. package/bin/tools/getAbsoluteAndInOsFormatPath.js.map +1 -1
  88. package/bin/tools/octokit-addons/getLatestsSemVersionedTag.d.ts +2 -3
  89. package/bin/tools/octokit-addons/getLatestsSemVersionedTag.js +6 -6
  90. package/bin/tools/octokit-addons/getLatestsSemVersionedTag.js.map +1 -1
  91. package/bin/tools/transformCodebase.d.ts +5 -1
  92. package/bin/tools/transformCodebase.js +31 -13
  93. package/bin/tools/transformCodebase.js.map +1 -1
  94. package/login/kcContext/getKcContextFromWindow.js +2 -2
  95. package/login/kcContext/getKcContextFromWindow.js.map +1 -1
  96. package/package.json +104 -53
  97. package/src/account/kcContext/getKcContextFromWindow.ts +2 -2
  98. package/src/bin/constants.ts +4 -1
  99. package/src/bin/copy-keycloak-resources-to-public.ts +2 -3
  100. package/src/bin/download-builtin-keycloak-theme.ts +161 -73
  101. package/src/bin/eject-keycloak-page.ts +1 -1
  102. package/src/bin/initialize-email-theme.ts +4 -3
  103. package/src/bin/keycloakify/buildOptions/buildOptions.ts +185 -0
  104. package/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +33 -0
  105. package/src/bin/keycloakify/buildOptions/index.ts +1 -0
  106. package/src/bin/keycloakify/{parsedPackageJson.ts → buildOptions/parsedPackageJson.ts} +4 -6
  107. package/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts +85 -0
  108. package/src/bin/keycloakify/generateFtl/generateFtl.ts +12 -8
  109. package/src/bin/keycloakify/generatePom.ts +70 -0
  110. package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +1 -1
  111. package/src/bin/keycloakify/generateTheme/bringInAccountV1.ts +83 -0
  112. package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +11 -52
  113. package/src/bin/keycloakify/generateTheme/generateTheme.ts +141 -51
  114. package/src/bin/keycloakify/keycloakify.ts +11 -58
  115. package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +3 -2
  116. package/src/bin/keycloakify/replacers/replaceImportsInInlineCssCode.ts +3 -2
  117. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/index.ts +1 -0
  118. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +66 -0
  119. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +85 -0
  120. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +90 -0
  121. package/src/bin/promptKeycloakVersion.ts +0 -1
  122. package/src/bin/tools/OptionalIfCanBeUndefined.ts +12 -0
  123. package/src/bin/tools/SemVer.ts +99 -0
  124. package/src/bin/tools/String.prototype.replaceAll.ts +30 -0
  125. package/src/bin/tools/crawl.ts +8 -8
  126. package/src/bin/tools/downloadAndUnzip.ts +78 -9
  127. package/src/bin/tools/fs.rm.ts +43 -0
  128. package/src/bin/tools/fs.rmSync.ts +34 -0
  129. package/src/bin/tools/getAbsoluteAndInOsFormatPath.ts +2 -0
  130. package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +9 -9
  131. package/src/bin/tools/transformCodebase.ts +35 -14
  132. package/src/login/kcContext/getKcContextFromWindow.ts +2 -2
  133. package/src/tsconfig.json +1 -1
  134. package/src/vite-plugin/config.json +232 -0
  135. package/src/vite-plugin/index.ts +1 -0
  136. package/src/vite-plugin/tsconfig.json +18 -0
  137. package/src/vite-plugin/vite-plugin.ts +128 -0
  138. package/vite-plugin/index.d.ts +1 -0
  139. package/vite-plugin/index.js +18 -0
  140. package/vite-plugin/index.js.map +1 -0
  141. package/vite-plugin/tsconfig.tsbuildinfo +1 -0
  142. package/vite-plugin/vite-plugin.d.ts +2 -0
  143. package/vite-plugin/vite-plugin.js +118 -0
  144. package/vite-plugin/vite-plugin.js.map +1 -0
  145. package/bin/getSrcDirPath.js.map +0 -1
  146. package/bin/keycloakify/BuildOptions.js +0 -113
  147. package/bin/keycloakify/BuildOptions.js.map +0 -1
  148. package/bin/keycloakify/ftlValuesGlobalName.d.ts +0 -1
  149. package/bin/keycloakify/ftlValuesGlobalName.js +0 -5
  150. package/bin/keycloakify/ftlValuesGlobalName.js.map +0 -1
  151. package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js.map +0 -1
  152. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.d.ts +0 -16
  153. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js +0 -205
  154. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js.map +0 -1
  155. package/bin/keycloakify/generateJavaStackFiles/index.d.ts +0 -1
  156. package/bin/keycloakify/generateJavaStackFiles/index.js.map +0 -1
  157. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.d.ts +0 -15
  158. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js +0 -158
  159. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js.map +0 -1
  160. package/bin/keycloakify/parsedPackageJson.d.ts +0 -108
  161. package/bin/keycloakify/parsedPackageJson.js.map +0 -1
  162. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.d.ts +0 -5
  163. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js +0 -74
  164. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js.map +0 -1
  165. package/bin/tools/NpmModuleVersion.d.ts +0 -22
  166. package/bin/tools/NpmModuleVersion.js.map +0 -1
  167. package/src/bin/keycloakify/BuildOptions.ts +0 -157
  168. package/src/bin/keycloakify/ftlValuesGlobalName.ts +0 -1
  169. package/src/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.ts +0 -101
  170. package/src/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.ts +0 -141
  171. package/src/bin/keycloakify/generateJavaStackFiles/index.ts +0 -1
  172. package/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +0 -76
  173. package/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts +0 -51
  174. package/src/bin/tools/NpmModuleVersion.ts +0 -73
  175. /package/bin/{getSrcDirPath.d.ts → getThemeSrcDirPath.d.ts} +0 -0
  176. /package/src/bin/{getSrcDirPath.ts → getThemeSrcDirPath.ts} +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { downloadKeycloakStaticResources } from "./keycloakify/generateTheme/downloadKeycloakStaticResources";
4
4
  import { join as pathJoin, relative as pathRelative } from "path";
5
- import { readBuildOptions } from "./keycloakify/BuildOptions";
5
+ import { readBuildOptions } from "./keycloakify/buildOptions";
6
6
  import { themeTypes, keycloak_resources, lastKeycloakVersionWithAccountV1 } from "./constants";
7
7
  import * as fs from "fs";
8
8
 
@@ -28,7 +28,6 @@ import * as fs from "fs";
28
28
  })(),
29
29
  themeType,
30
30
  "themeDirPath": reservedDirPath,
31
- "usedResources": undefined,
32
31
  buildOptions
33
32
  });
34
33
  }
@@ -44,7 +43,7 @@ import * as fs from "fs";
44
43
  )
45
44
  );
46
45
 
47
- fs.writeFileSync(pathJoin(buildOptions.publicDirPath, "keycloak-resources", ".gitignore"), Buffer.from("*", "utf8"));
46
+ fs.writeFileSync(pathJoin(buildOptions.publicDirPath, keycloak_resources, ".gitignore"), Buffer.from("*", "utf8"));
48
47
 
49
48
  console.log(`${pathRelative(reactAppRootDirPath, reservedDirPath)} directory created.`);
50
49
  })();
@@ -3,11 +3,13 @@ import { join as pathJoin } from "path";
3
3
  import { downloadAndUnzip } from "./tools/downloadAndUnzip";
4
4
  import { promptKeycloakVersion } from "./promptKeycloakVersion";
5
5
  import { getLogger } from "./tools/logger";
6
- import { readBuildOptions } from "./keycloakify/BuildOptions";
6
+ import { readBuildOptions, type BuildOptions } from "./keycloakify/buildOptions";
7
7
  import { assert } from "tsafe/assert";
8
- import type { BuildOptions } from "./keycloakify/BuildOptions";
9
8
  import * as child_process from "child_process";
10
9
  import * as fs from "fs";
10
+ import { rmSync } from "./tools/fs.rmSync";
11
+ import { lastKeycloakVersionWithAccountV1 } from "./constants";
12
+ import { transformCodebase } from "./tools/transformCodebase";
11
13
 
12
14
  export type BuildOptionsLike = {
13
15
  cacheDirPath: string;
@@ -27,51 +29,6 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
27
29
  "preCacheTransform": {
28
30
  "actionCacheId": "npm install and build",
29
31
  "action": async ({ destDirPath }) => {
30
- fix_account_css: {
31
- const accountCssFilePath = pathJoin(destDirPath, "keycloak", "account", "resources", "css", "account.css");
32
-
33
- if (!fs.existsSync(accountCssFilePath)) {
34
- break fix_account_css;
35
- }
36
-
37
- fs.writeFileSync(
38
- accountCssFilePath,
39
- Buffer.from(fs.readFileSync(accountCssFilePath).toString("utf8").replace("top: -34px;", "top: -34px !important;"), "utf8")
40
- );
41
- }
42
-
43
- fix_account_topt: {
44
- const totpFtlFilePath = pathJoin(destDirPath, "base", "account", "totp.ftl");
45
-
46
- if (!fs.existsSync(totpFtlFilePath)) {
47
- break fix_account_topt;
48
- }
49
-
50
- fs.writeFileSync(
51
- totpFtlFilePath,
52
- Buffer.from(
53
- fs
54
- .readFileSync(totpFtlFilePath)
55
- .toString("utf8")
56
- .replace(
57
- [
58
- " <#list totp.policy.supportedApplications as app>",
59
- " <li>${app}</li>",
60
- " </#list>"
61
- ].join("\n"),
62
- [
63
- " <#if totp.policy.supportedApplications?has_content>",
64
- " <#list totp.policy.supportedApplications as app>",
65
- " <li>${app}</li>",
66
- " </#list>",
67
- " </#if>"
68
- ].join("\n")
69
- ),
70
- "utf8"
71
- )
72
- );
73
- }
74
-
75
32
  install_common_node_modules: {
76
33
  const commonResourcesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources");
77
34
 
@@ -93,43 +50,174 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
93
50
  });
94
51
  }
95
52
 
96
- install_and_move_to_common_resources_generated_in_keycloak_v2: {
97
- const accountV2DirSrcDirPath = pathJoin(destDirPath, "keycloak.v2", "account", "src");
53
+ remove_keycloak_v2: {
54
+ const keycloakV2DirPath = pathJoin(destDirPath, "keycloak.v2");
98
55
 
99
- if (!fs.existsSync(accountV2DirSrcDirPath)) {
100
- break install_and_move_to_common_resources_generated_in_keycloak_v2;
56
+ if (!fs.existsSync(keycloakV2DirPath)) {
57
+ break remove_keycloak_v2;
101
58
  }
102
59
 
103
- const packageManager = fs.existsSync(pathJoin(accountV2DirSrcDirPath, "pnpm-lock.yaml")) ? "pnpm" : "npm";
104
-
105
- if (packageManager === "pnpm") {
106
- try {
107
- child_process.execSync(`which pnpm`);
108
- } catch {
109
- console.log(`Installing pnpm globally`);
110
- child_process.execSync(`npm install -g pnpm`);
111
- }
112
- }
113
-
114
- child_process.execSync(`${packageManager} install`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
60
+ rmSync(keycloakV2DirPath, { "recursive": true });
61
+ }
115
62
 
116
- const packageJsonFilePath = pathJoin(accountV2DirSrcDirPath, "package.json");
63
+ // Note, this is an optimization for reducing the size of the jar
64
+ remove_unused_node_modules: {
65
+ const pathOfNodeModules = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
117
66
 
118
- const packageJsonRaw = fs.readFileSync(packageJsonFilePath);
67
+ if (!fs.existsSync(pathOfNodeModules)) {
68
+ break remove_unused_node_modules;
69
+ }
119
70
 
120
- const parsedPackageJson = JSON.parse(packageJsonRaw.toString("utf8"));
71
+ const toDeletePerfixes = [
72
+ "angular",
73
+ "bootstrap",
74
+ "rcue",
75
+ "font-awesome",
76
+ "ng-file-upload",
77
+ pathJoin("patternfly", "dist", "sass"),
78
+ pathJoin("patternfly", "dist", "less"),
79
+ pathJoin("patternfly", "dist", "js"),
80
+ "d3",
81
+ pathJoin("jquery", "src"),
82
+ "c3",
83
+ "core-js",
84
+ "eonasdan-bootstrap-datetimepicker",
85
+ "moment",
86
+ "react",
87
+ "patternfly-bootstrap-treeview",
88
+ "popper.js",
89
+ "tippy.js",
90
+ "jquery-match-height",
91
+ "google-code-prettify",
92
+ "patternfly-bootstrap-combobox",
93
+ "focus-trap",
94
+ "tabbable",
95
+ "scheduler",
96
+ "@types",
97
+ "datatables.net",
98
+ "datatables.net-colreorder",
99
+ "tslib",
100
+ "prop-types",
101
+ "file-selector",
102
+ "datatables.net-colreorder-bs",
103
+ "object-assign",
104
+ "warning",
105
+ "js-tokens",
106
+ "loose-envify",
107
+ "prop-types-extra",
108
+ "attr-accept",
109
+ "datatables.net-select",
110
+ "drmonty-datatables-colvis",
111
+ "datatables.net-bs",
112
+ pathJoin("@patternfly", "react"),
113
+ pathJoin("@patternfly", "patternfly", "docs")
114
+ ];
115
+
116
+ transformCodebase({
117
+ "srcDirPath": pathOfNodeModules,
118
+ "destDirPath": pathOfNodeModules,
119
+ "transformSourceCode": ({ sourceCode, fileRelativePath }) => {
120
+ if (fileRelativePath.endsWith(".map")) {
121
+ return undefined;
122
+ }
123
+
124
+ if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
125
+ return undefined;
126
+ }
127
+
128
+ if (fileRelativePath.startsWith(pathJoin("patternfly", "dist", "fonts"))) {
129
+ if (
130
+ !fileRelativePath.endsWith(".woff2") &&
131
+ !fileRelativePath.endsWith(".woff") &&
132
+ !fileRelativePath.endsWith(".ttf")
133
+ ) {
134
+ return undefined;
135
+ }
136
+ }
137
+
138
+ return { "modifiedSourceCode": sourceCode };
139
+ }
140
+ });
141
+ }
121
142
 
122
- parsedPackageJson.scripts.build = parsedPackageJson.scripts.build
123
- .replace(`${packageManager} run check-types`, "true")
124
- .replace(`${packageManager} run babel`, "true");
143
+ last_account_v1_transformations: {
144
+ if (lastKeycloakVersionWithAccountV1 !== keycloakVersion) {
145
+ break last_account_v1_transformations;
146
+ }
125
147
 
126
- fs.writeFileSync(packageJsonFilePath, Buffer.from(JSON.stringify(parsedPackageJson, null, 2), "utf8"));
148
+ {
149
+ const accountCssFilePath = pathJoin(destDirPath, "keycloak", "account", "resources", "css", "account.css");
127
150
 
128
- child_process.execSync(`${packageManager} run build`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
151
+ fs.writeFileSync(
152
+ accountCssFilePath,
153
+ Buffer.from(fs.readFileSync(accountCssFilePath).toString("utf8").replace("top: -34px;", "top: -34px !important;"), "utf8")
154
+ );
155
+ }
129
156
 
130
- fs.writeFileSync(packageJsonFilePath, packageJsonRaw);
157
+ {
158
+ const totpFtlFilePath = pathJoin(destDirPath, "base", "account", "totp.ftl");
159
+
160
+ fs.writeFileSync(
161
+ totpFtlFilePath,
162
+ Buffer.from(
163
+ fs
164
+ .readFileSync(totpFtlFilePath)
165
+ .toString("utf8")
166
+ .replace(
167
+ [
168
+ " <#list totp.policy.supportedApplications as app>",
169
+ " <li>${app}</li>",
170
+ " </#list>"
171
+ ].join("\n"),
172
+ [
173
+ " <#if totp.policy.supportedApplications?has_content>",
174
+ " <#list totp.policy.supportedApplications as app>",
175
+ " <li>${app}</li>",
176
+ " </#list>",
177
+ " </#if>"
178
+ ].join("\n")
179
+ ),
180
+ "utf8"
181
+ )
182
+ );
183
+ }
131
184
 
132
- fs.rmSync(pathJoin(accountV2DirSrcDirPath, "node_modules"), { "recursive": true });
185
+ // Note, this is an optimization for reducing the size of the jar
186
+ {
187
+ const nodeModulesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources");
188
+
189
+ const usedCommonResourceRelativeFilePaths = [
190
+ ...["patternfly.min.css", "patternfly-additions.min.css", "patternfly-additions.min.css"].map(fileBasename =>
191
+ pathJoin("patternfly", "dist", "css", fileBasename)
192
+ ),
193
+ ...[
194
+ "OpenSans-Light-webfont.woff2",
195
+ "OpenSans-Regular-webfont.woff2",
196
+ "OpenSans-Bold-webfont.woff2",
197
+ "OpenSans-Semibold-webfont.woff2",
198
+ "OpenSans-Bold-webfont.woff",
199
+ "OpenSans-Light-webfont.woff",
200
+ "OpenSans-Regular-webfont.woff",
201
+ "OpenSans-Semibold-webfont.woff",
202
+ "OpenSans-Regular-webfont.ttf",
203
+ "OpenSans-Light-webfont.ttf",
204
+ "OpenSans-Semibold-webfont.ttf",
205
+ "OpenSans-Bold-webfont.ttf"
206
+ ].map(fileBasename => pathJoin("patternfly", "dist", "fonts", fileBasename))
207
+ ];
208
+
209
+ transformCodebase({
210
+ "srcDirPath": nodeModulesDirPath,
211
+ "destDirPath": nodeModulesDirPath,
212
+ "transformSourceCode": ({ sourceCode, fileRelativePath }) => {
213
+ if (!usedCommonResourceRelativeFilePaths.includes(fileRelativePath)) {
214
+ return undefined;
215
+ }
216
+
217
+ return { "modifiedSourceCode": sourceCode };
218
+ }
219
+ });
220
+ }
133
221
  }
134
222
  }
135
223
  }
@@ -9,7 +9,7 @@ import { existsSync } from "fs";
9
9
  import { join as pathJoin, relative as pathRelative } from "path";
10
10
  import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
11
11
  import { assert, Equals } from "tsafe/assert";
12
- import { getThemeSrcDirPath } from "./getSrcDirPath";
12
+ import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
13
13
  import { themeTypes, type ThemeType } from "./constants";
14
14
 
15
15
  (async () => {
@@ -4,10 +4,11 @@ import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme"
4
4
  import { join as pathJoin, relative as pathRelative } from "path";
5
5
  import { transformCodebase } from "./tools/transformCodebase";
6
6
  import { promptKeycloakVersion } from "./promptKeycloakVersion";
7
- import { readBuildOptions } from "./keycloakify/BuildOptions";
7
+ import { readBuildOptions } from "./keycloakify/buildOptions";
8
8
  import * as fs from "fs";
9
9
  import { getLogger } from "./tools/logger";
10
- import { getThemeSrcDirPath } from "./getSrcDirPath";
10
+ import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
11
+ import { rmSync } from "./tools/fs.rmSync";
11
12
 
12
13
  export async function main() {
13
14
  const reactAppRootDirPath = process.cwd();
@@ -54,7 +55,7 @@ export async function main() {
54
55
 
55
56
  logger.log(`${pathRelative(process.cwd(), emailThemeSrcDirPath)} ready to be customized, feel free to remove every file you do not customize`);
56
57
 
57
- fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
58
+ rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
58
59
  }
59
60
 
60
61
  if (require.main === module) {
@@ -0,0 +1,185 @@
1
+ import { parse as urlParse } from "url";
2
+ import { readParsedPackageJson } from "./parsedPackageJson";
3
+ import { join as pathJoin } from "path";
4
+ import parseArgv from "minimist";
5
+ import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
6
+ import { readResolvedViteConfig } from "./resolvedViteConfig";
7
+ import { getKeycloakifyBuildDirPath } from "./getKeycloakifyBuildDirPath";
8
+
9
+ /** Consolidated build option gathered form CLI arguments and config in package.json */
10
+ export type BuildOptions = {
11
+ bundler: "vite" | "webpack";
12
+ isSilent: boolean;
13
+ themeVersion: string;
14
+ themeNames: string[];
15
+ extraThemeProperties: string[] | undefined;
16
+ groupId: string;
17
+ artifactId: string;
18
+ doCreateJar: boolean;
19
+ loginThemeResourcesFromKeycloakVersion: string;
20
+ reactAppRootDirPath: string;
21
+ reactAppBuildDirPath: string;
22
+ /** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
23
+ keycloakifyBuildDirPath: string;
24
+ publicDirPath: string;
25
+ cacheDirPath: string;
26
+ /** If your app is hosted under a subpath, it's the case in CRA if you have "homepage": "https://example.com/my-app" in your package.json
27
+ * In this case the urlPathname will be "/my-app/" */
28
+ urlPathname: string | undefined;
29
+ assetsDirPath: string;
30
+ doBuildRetrocompatAccountTheme: boolean;
31
+ };
32
+
33
+ export function readBuildOptions(params: { reactAppRootDirPath: string; processArgv: string[] }): BuildOptions {
34
+ const { reactAppRootDirPath, processArgv } = params;
35
+
36
+ const parsedPackageJson = readParsedPackageJson({ reactAppRootDirPath });
37
+
38
+ const { resolvedViteConfig } =
39
+ readResolvedViteConfig({
40
+ "parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
41
+ reactAppRootDirPath
42
+ }) ?? {};
43
+
44
+ const themeNames = (() => {
45
+ if (parsedPackageJson.keycloakify?.themeName === undefined) {
46
+ return [
47
+ parsedPackageJson.name
48
+ .replace(/^@(.*)/, "$1")
49
+ .split("/")
50
+ .join("-")
51
+ ];
52
+ }
53
+
54
+ if (typeof parsedPackageJson.keycloakify.themeName === "string") {
55
+ return [parsedPackageJson.keycloakify.themeName];
56
+ }
57
+
58
+ return parsedPackageJson.keycloakify.themeName;
59
+ })();
60
+
61
+ const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({
62
+ "parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
63
+ reactAppRootDirPath,
64
+ "bundler": resolvedViteConfig !== undefined ? "vite" : "webpack"
65
+ });
66
+
67
+ const reactAppBuildDirPath = (() => {
68
+ webpack: {
69
+ if (resolvedViteConfig !== undefined) {
70
+ break webpack;
71
+ }
72
+
73
+ if (parsedPackageJson.keycloakify?.reactAppBuildDirPath !== undefined) {
74
+ return getAbsoluteAndInOsFormatPath({
75
+ "pathIsh": parsedPackageJson.keycloakify?.reactAppBuildDirPath,
76
+ "cwd": reactAppRootDirPath
77
+ });
78
+ }
79
+
80
+ return pathJoin(reactAppRootDirPath, "build");
81
+ }
82
+
83
+ return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
84
+ })();
85
+
86
+ return {
87
+ "bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
88
+ "isSilent": (() => {
89
+ const argv = parseArgv(processArgv);
90
+
91
+ return typeof argv["silent"] === "boolean" ? argv["silent"] : false;
92
+ })(),
93
+ "themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
94
+ themeNames,
95
+ "extraThemeProperties": parsedPackageJson.keycloakify?.extraThemeProperties,
96
+ "groupId": (() => {
97
+ const fallbackGroupId = `${themeNames[0]}.keycloak`;
98
+
99
+ return (
100
+ process.env.KEYCLOAKIFY_GROUP_ID ??
101
+ parsedPackageJson.keycloakify?.groupId ??
102
+ (parsedPackageJson.homepage === undefined
103
+ ? fallbackGroupId
104
+ : urlParse(parsedPackageJson.homepage)
105
+ .host?.replace(/:[0-9]+$/, "")
106
+ ?.split(".")
107
+ .reverse()
108
+ .join(".") ?? fallbackGroupId) + ".keycloak"
109
+ );
110
+ })(),
111
+ "artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? parsedPackageJson.keycloakify?.artifactId ?? `${themeNames[0]}-keycloak-theme`,
112
+ "doCreateJar": parsedPackageJson.keycloakify?.doCreateJar ?? true,
113
+ "loginThemeResourcesFromKeycloakVersion": parsedPackageJson.keycloakify?.loginThemeResourcesFromKeycloakVersion ?? "11.0.3",
114
+ reactAppRootDirPath,
115
+ reactAppBuildDirPath,
116
+ keycloakifyBuildDirPath,
117
+ "publicDirPath": (() => {
118
+ webpack: {
119
+ if (resolvedViteConfig !== undefined) {
120
+ break webpack;
121
+ }
122
+
123
+ if (process.env.PUBLIC_DIR_PATH !== undefined) {
124
+ return getAbsoluteAndInOsFormatPath({
125
+ "pathIsh": process.env.PUBLIC_DIR_PATH,
126
+ "cwd": reactAppRootDirPath
127
+ });
128
+ }
129
+
130
+ return pathJoin(reactAppRootDirPath, "public");
131
+ }
132
+
133
+ return pathJoin(reactAppRootDirPath, resolvedViteConfig.publicDir);
134
+ })(),
135
+ "cacheDirPath": pathJoin(
136
+ (() => {
137
+ if (process.env.XDG_CACHE_HOME !== undefined) {
138
+ return getAbsoluteAndInOsFormatPath({
139
+ "pathIsh": process.env.XDG_CACHE_HOME,
140
+ "cwd": reactAppRootDirPath
141
+ });
142
+ }
143
+
144
+ return pathJoin(reactAppRootDirPath, "node_modules", ".cache");
145
+ })(),
146
+ "keycloakify"
147
+ ),
148
+ "urlPathname": (() => {
149
+ webpack: {
150
+ if (resolvedViteConfig !== undefined) {
151
+ break webpack;
152
+ }
153
+
154
+ const { homepage } = parsedPackageJson;
155
+
156
+ let url: URL | undefined = undefined;
157
+
158
+ if (homepage !== undefined) {
159
+ url = new URL(homepage);
160
+ }
161
+
162
+ if (url === undefined) {
163
+ return undefined;
164
+ }
165
+
166
+ const out = url.pathname.replace(/([^/])$/, "$1/");
167
+ return out === "/" ? undefined : out;
168
+ }
169
+
170
+ return resolvedViteConfig.urlPathname;
171
+ })(),
172
+ "assetsDirPath": (() => {
173
+ webpack: {
174
+ if (resolvedViteConfig !== undefined) {
175
+ break webpack;
176
+ }
177
+
178
+ return pathJoin(reactAppBuildDirPath, "static");
179
+ }
180
+
181
+ return pathJoin(reactAppBuildDirPath, resolvedViteConfig.assetsDir);
182
+ })(),
183
+ "doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true
184
+ };
185
+ }
@@ -0,0 +1,33 @@
1
+ import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
2
+ import { join as pathJoin } from "path";
3
+
4
+ export function getKeycloakifyBuildDirPath(params: {
5
+ reactAppRootDirPath: string;
6
+ parsedPackageJson_keycloakify_keycloakifyBuildDirPath: string | undefined;
7
+ bundler: "vite" | "webpack";
8
+ }) {
9
+ const { reactAppRootDirPath, parsedPackageJson_keycloakify_keycloakifyBuildDirPath, bundler } = params;
10
+
11
+ const keycloakifyBuildDirPath = (() => {
12
+ if (parsedPackageJson_keycloakify_keycloakifyBuildDirPath !== undefined) {
13
+ getAbsoluteAndInOsFormatPath({
14
+ "pathIsh": parsedPackageJson_keycloakify_keycloakifyBuildDirPath,
15
+ "cwd": reactAppRootDirPath
16
+ });
17
+ }
18
+
19
+ return pathJoin(
20
+ reactAppRootDirPath,
21
+ `${(() => {
22
+ switch (bundler) {
23
+ case "vite":
24
+ return "dist";
25
+ case "webpack":
26
+ return "build";
27
+ }
28
+ })()}_keycloak`
29
+ );
30
+ })();
31
+
32
+ return { keycloakifyBuildDirPath };
33
+ }
@@ -0,0 +1 @@
1
+ export * from "./buildOptions";
@@ -2,7 +2,7 @@ import * as fs from "fs";
2
2
  import { assert } from "tsafe";
3
3
  import type { Equals } from "tsafe";
4
4
  import { z } from "zod";
5
- import { pathJoin } from "../tools/pathJoin";
5
+ import { join as pathJoin } from "path";
6
6
 
7
7
  export type ParsedPackageJson = {
8
8
  name: string;
@@ -10,7 +10,6 @@ export type ParsedPackageJson = {
10
10
  homepage?: string;
11
11
  keycloakify?: {
12
12
  extraThemeProperties?: string[];
13
- areAppAndKeycloakServerSharingSameDomain?: boolean;
14
13
  artifactId?: string;
15
14
  groupId?: string;
16
15
  doCreateJar?: boolean;
@@ -22,14 +21,13 @@ export type ParsedPackageJson = {
22
21
  };
23
22
  };
24
23
 
25
- export const zParsedPackageJson = z.object({
24
+ const zParsedPackageJson = z.object({
26
25
  "name": z.string(),
27
26
  "version": z.string().optional(),
28
27
  "homepage": z.string().optional(),
29
28
  "keycloakify": z
30
29
  .object({
31
30
  "extraThemeProperties": z.array(z.string()).optional(),
32
- "areAppAndKeycloakServerSharingSameDomain": z.boolean().optional(),
33
31
  "artifactId": z.string().optional(),
34
32
  "groupId": z.string().optional(),
35
33
  "doCreateJar": z.boolean().optional(),
@@ -44,8 +42,8 @@ export const zParsedPackageJson = z.object({
44
42
 
45
43
  assert<Equals<ReturnType<(typeof zParsedPackageJson)["parse"]>, ParsedPackageJson>>();
46
44
 
47
- let parsedPackageJson: undefined | ReturnType<(typeof zParsedPackageJson)["parse"]>;
48
- export function getParsedPackageJson(params: { reactAppRootDirPath: string }) {
45
+ let parsedPackageJson: undefined | ParsedPackageJson;
46
+ export function readParsedPackageJson(params: { reactAppRootDirPath: string }) {
49
47
  const { reactAppRootDirPath } = params;
50
48
  if (parsedPackageJson) {
51
49
  return parsedPackageJson;