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.
Files changed (182) hide show
  1. package/README.md +5 -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 +98 -31
  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 +30 -19
  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/login/lib/useGetClassName.js +1 -1
  97. package/login/lib/useGetClassName.js.map +1 -1
  98. package/login/pages/LoginOtp.js +5 -43
  99. package/login/pages/LoginOtp.js.map +1 -1
  100. package/package.json +104 -53
  101. package/src/account/kcContext/getKcContextFromWindow.ts +2 -2
  102. package/src/bin/constants.ts +4 -1
  103. package/src/bin/copy-keycloak-resources-to-public.ts +2 -3
  104. package/src/bin/download-builtin-keycloak-theme.ts +96 -48
  105. package/src/bin/eject-keycloak-page.ts +1 -1
  106. package/src/bin/initialize-email-theme.ts +4 -3
  107. package/src/bin/keycloakify/buildOptions/buildOptions.ts +185 -0
  108. package/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +33 -0
  109. package/src/bin/keycloakify/buildOptions/index.ts +1 -0
  110. package/src/bin/keycloakify/{parsedPackageJson.ts → buildOptions/parsedPackageJson.ts} +4 -6
  111. package/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts +85 -0
  112. package/src/bin/keycloakify/generateFtl/generateFtl.ts +12 -8
  113. package/src/bin/keycloakify/generatePom.ts +70 -0
  114. package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +1 -1
  115. package/src/bin/keycloakify/generateTheme/bringInAccountV1.ts +83 -0
  116. package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +11 -52
  117. package/src/bin/keycloakify/generateTheme/generateTheme.ts +141 -51
  118. package/src/bin/keycloakify/keycloakify.ts +11 -58
  119. package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +3 -2
  120. package/src/bin/keycloakify/replacers/replaceImportsInInlineCssCode.ts +3 -2
  121. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/index.ts +1 -0
  122. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +66 -0
  123. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +85 -0
  124. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +90 -0
  125. package/src/bin/promptKeycloakVersion.ts +0 -1
  126. package/src/bin/tools/OptionalIfCanBeUndefined.ts +12 -0
  127. package/src/bin/tools/SemVer.ts +99 -0
  128. package/src/bin/tools/String.prototype.replaceAll.ts +30 -0
  129. package/src/bin/tools/crawl.ts +8 -8
  130. package/src/bin/tools/downloadAndUnzip.ts +11 -4
  131. package/src/bin/tools/fs.rm.ts +43 -0
  132. package/src/bin/tools/fs.rmSync.ts +34 -0
  133. package/src/bin/tools/getAbsoluteAndInOsFormatPath.ts +2 -0
  134. package/src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts +9 -9
  135. package/src/bin/tools/transformCodebase.ts +35 -14
  136. package/src/login/kcContext/getKcContextFromWindow.ts +2 -2
  137. package/src/login/lib/useGetClassName.ts +1 -1
  138. package/src/login/pages/LoginOtp.tsx +64 -94
  139. package/src/tsconfig.json +1 -1
  140. package/src/vite-plugin/config.json +232 -0
  141. package/src/vite-plugin/index.ts +1 -0
  142. package/src/vite-plugin/tsconfig.json +18 -0
  143. package/src/vite-plugin/vite-plugin.ts +128 -0
  144. package/vite-plugin/index.d.ts +1 -0
  145. package/vite-plugin/index.js +18 -0
  146. package/vite-plugin/index.js.map +1 -0
  147. package/vite-plugin/tsconfig.tsbuildinfo +1 -0
  148. package/vite-plugin/vite-plugin.d.ts +2 -0
  149. package/vite-plugin/vite-plugin.js +118 -0
  150. package/vite-plugin/vite-plugin.js.map +1 -0
  151. package/bin/getSrcDirPath.js.map +0 -1
  152. package/bin/keycloakify/BuildOptions.js +0 -113
  153. package/bin/keycloakify/BuildOptions.js.map +0 -1
  154. package/bin/keycloakify/ftlValuesGlobalName.d.ts +0 -1
  155. package/bin/keycloakify/ftlValuesGlobalName.js +0 -5
  156. package/bin/keycloakify/ftlValuesGlobalName.js.map +0 -1
  157. package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js.map +0 -1
  158. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.d.ts +0 -16
  159. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js +0 -205
  160. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js.map +0 -1
  161. package/bin/keycloakify/generateJavaStackFiles/index.d.ts +0 -1
  162. package/bin/keycloakify/generateJavaStackFiles/index.js.map +0 -1
  163. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.d.ts +0 -15
  164. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js +0 -158
  165. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js.map +0 -1
  166. package/bin/keycloakify/parsedPackageJson.d.ts +0 -108
  167. package/bin/keycloakify/parsedPackageJson.js.map +0 -1
  168. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.d.ts +0 -5
  169. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js +0 -74
  170. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js.map +0 -1
  171. package/bin/tools/NpmModuleVersion.d.ts +0 -22
  172. package/bin/tools/NpmModuleVersion.js.map +0 -1
  173. package/src/bin/keycloakify/BuildOptions.ts +0 -157
  174. package/src/bin/keycloakify/ftlValuesGlobalName.ts +0 -1
  175. package/src/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.ts +0 -101
  176. package/src/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.ts +0 -141
  177. package/src/bin/keycloakify/generateJavaStackFiles/index.ts +0 -1
  178. package/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +0 -76
  179. package/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts +0 -51
  180. package/src/bin/tools/NpmModuleVersion.ts +0 -73
  181. /package/bin/{getSrcDirPath.d.ts → getThemeSrcDirPath.d.ts} +0 -0
  182. /package/src/bin/{getSrcDirPath.ts → getThemeSrcDirPath.ts} +0 -0
@@ -23,7 +23,6 @@ export async function promptKeycloakVersion() {
23
23
  const tags = [
24
24
  ...(await getLatestsSemVersionedTag({
25
25
  "count": 10,
26
- "doIgnoreBeta": true,
27
26
  "owner": "keycloak",
28
27
  "repo": "keycloak"
29
28
  }).then(arr => arr.map(({ tag }) => tag))),
@@ -0,0 +1,12 @@
1
+ type PropertiesThatCanBeUndefined<T extends Record<string, unknown>> = {
2
+ [Key in keyof T]: undefined extends T[Key] ? Key : never;
3
+ }[keyof T];
4
+
5
+ /**
6
+ * OptionalIfCanBeUndefined<{ p1: string | undefined; p2: string; }>
7
+ * is
8
+ * { p1?: string | undefined; p2: string }
9
+ */
10
+ export type OptionalIfCanBeUndefined<T extends Record<string, unknown>> = {
11
+ [K in PropertiesThatCanBeUndefined<T>]?: T[K];
12
+ } & { [K in Exclude<keyof T, PropertiesThatCanBeUndefined<T>>]: T[K] };
@@ -0,0 +1,99 @@
1
+ export type SemVer = {
2
+ major: number;
3
+ minor: number;
4
+ patch: number;
5
+ rc?: number;
6
+ parsedFrom: string;
7
+ };
8
+
9
+ export namespace SemVer {
10
+ const bumpTypes = ["major", "minor", "patch", "rc", "no bump"] as const;
11
+
12
+ export type BumpType = (typeof bumpTypes)[number];
13
+
14
+ export function parse(versionStr: string): SemVer {
15
+ const match = versionStr.match(/^v?([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-rc.([0-9]+))?$/);
16
+
17
+ if (!match) {
18
+ throw new Error(`${versionStr} is not a valid semantic version`);
19
+ }
20
+
21
+ const semVer: Omit<SemVer, "parsedFrom"> = {
22
+ "major": parseInt(match[1]),
23
+ "minor": parseInt(match[2]),
24
+ "patch": (() => {
25
+ const str = match[3];
26
+
27
+ return str === undefined ? 0 : parseInt(str);
28
+ })(),
29
+ ...(() => {
30
+ const str = match[4];
31
+ return str === undefined ? {} : { "rc": parseInt(str) };
32
+ })()
33
+ };
34
+
35
+ const initialStr = stringify(semVer);
36
+
37
+ Object.defineProperty(semVer, "parsedFrom", {
38
+ "enumerable": true,
39
+ "get": function () {
40
+ const currentStr = stringify(this);
41
+
42
+ if (currentStr !== initialStr) {
43
+ throw new Error(`SemVer.parsedFrom can't be read anymore, the version have been modified from ${initialStr} to ${currentStr}`);
44
+ }
45
+
46
+ return versionStr;
47
+ }
48
+ });
49
+
50
+ return semVer as any;
51
+ }
52
+
53
+ export function stringify(v: Omit<SemVer, "parsedFrom">): string {
54
+ return `${v.major}.${v.minor}.${v.patch}${v.rc === undefined ? "" : `-rc.${v.rc}`}`;
55
+ }
56
+
57
+ /**
58
+ *
59
+ * v1 < v2 => -1
60
+ * v1 === v2 => 0
61
+ * v1 > v2 => 1
62
+ *
63
+ */
64
+ export function compare(v1: SemVer, v2: SemVer): -1 | 0 | 1 {
65
+ const sign = (diff: number): -1 | 0 | 1 => (diff === 0 ? 0 : diff < 0 ? -1 : 1);
66
+ const noUndefined = (n: number | undefined) => n ?? Infinity;
67
+
68
+ for (const level of ["major", "minor", "patch", "rc"] as const) {
69
+ if (noUndefined(v1[level]) !== noUndefined(v2[level])) {
70
+ return sign(noUndefined(v1[level]) - noUndefined(v2[level]));
71
+ }
72
+ }
73
+
74
+ return 0;
75
+ }
76
+
77
+ /*
78
+ console.log(compare(parse("3.0.0-rc.3"), parse("3.0.0")) === -1 )
79
+ console.log(compare(parse("3.0.0-rc.3"), parse("3.0.0-rc.4")) === -1 )
80
+ console.log(compare(parse("3.0.0-rc.3"), parse("4.0.0")) === -1 )
81
+ */
82
+
83
+ export function bumpType(params: { versionBehind: string | SemVer; versionAhead: string | SemVer }): BumpType | "no bump" {
84
+ const versionAhead = typeof params.versionAhead === "string" ? parse(params.versionAhead) : params.versionAhead;
85
+ const versionBehind = typeof params.versionBehind === "string" ? parse(params.versionBehind) : params.versionBehind;
86
+
87
+ if (compare(versionBehind, versionAhead) === 1) {
88
+ throw new Error(`Version regression ${stringify(versionBehind)} -> ${stringify(versionAhead)}`);
89
+ }
90
+
91
+ for (const level of ["major", "minor", "patch", "rc"] as const) {
92
+ if (versionBehind[level] !== versionAhead[level]) {
93
+ return level;
94
+ }
95
+ }
96
+
97
+ return "no bump";
98
+ }
99
+ }
@@ -0,0 +1,30 @@
1
+ export function replaceAll(string: string, searchValue: string | RegExp, replaceValue: string): string {
2
+ if ((string as any).replaceAll !== undefined) {
3
+ return (string as any).replaceAll(searchValue, replaceValue);
4
+ }
5
+
6
+ // If the searchValue is a string
7
+ if (typeof searchValue === "string") {
8
+ // Escape special characters in the string to be used in a regex
9
+ var escapedSearchValue = searchValue.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10
+ var regex = new RegExp(escapedSearchValue, "g");
11
+
12
+ return string.replace(regex, replaceValue);
13
+ }
14
+
15
+ // If the searchValue is a global RegExp, use it directly
16
+ if (searchValue instanceof RegExp && searchValue.global) {
17
+ return string.replace(searchValue, replaceValue);
18
+ }
19
+
20
+ // If the searchValue is a non-global RegExp, throw an error
21
+ if (searchValue instanceof RegExp) {
22
+ throw new TypeError("replaceAll must be called with a global RegExp");
23
+ }
24
+
25
+ // Convert searchValue to string if it's not a string or RegExp
26
+ var searchString = String(searchValue);
27
+ var regexFromString = new RegExp(searchString.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
28
+
29
+ return string.replace(regexFromString, replaceValue);
30
+ }
@@ -1,17 +1,17 @@
1
1
  import * as fs from "fs";
2
- import * as path from "path";
2
+ import { join as pathJoin, relative as pathRelative } from "path";
3
3
 
4
- const crawlRec = (dir_path: string, paths: string[]) => {
5
- for (const file_name of fs.readdirSync(dir_path)) {
6
- const file_path = path.join(dir_path, file_name);
4
+ const crawlRec = (dirPath: string, filePaths: string[]) => {
5
+ for (const basename of fs.readdirSync(dirPath)) {
6
+ const fileOrDirPath = pathJoin(dirPath, basename);
7
7
 
8
- if (fs.lstatSync(file_path).isDirectory()) {
9
- crawlRec(file_path, paths);
8
+ if (fs.lstatSync(fileOrDirPath).isDirectory()) {
9
+ crawlRec(fileOrDirPath, filePaths);
10
10
 
11
11
  continue;
12
12
  }
13
13
 
14
- paths.push(file_path);
14
+ filePaths.push(fileOrDirPath);
15
15
  }
16
16
  };
17
17
 
@@ -27,6 +27,6 @@ export function crawl(params: { dirPath: string; returnedPathsType: "absolute" |
27
27
  case "absolute":
28
28
  return filePaths;
29
29
  case "relative to dirPath":
30
- return filePaths.map(filePath => path.relative(dirPath, filePath));
30
+ return filePaths.map(filePath => pathRelative(dirPath, filePath));
31
31
  }
32
32
  }
@@ -1,12 +1,13 @@
1
1
  import { exec as execCallback } from "child_process";
2
2
  import { createHash } from "crypto";
3
- import { mkdir, readFile, stat, writeFile, unlink, rm } from "fs/promises";
3
+ import { mkdir, readFile, stat, writeFile, unlink } from "fs/promises";
4
4
  import fetch, { type FetchOptions } from "make-fetch-happen";
5
5
  import { dirname as pathDirname, join as pathJoin, resolve as pathResolve, sep as pathSep } from "path";
6
6
  import { assert } from "tsafe/assert";
7
7
  import { promisify } from "util";
8
8
  import { transformCodebase } from "./transformCodebase";
9
9
  import { unzip, zip } from "./unzip";
10
+ import { rm } from "../tools/fs.rm";
10
11
 
11
12
  const exec = promisify(execCallback);
12
13
 
@@ -205,9 +206,15 @@ export async function downloadAndUnzip(
205
206
  if (specificDirsToExtract !== undefined || preCacheTransform !== undefined) {
206
207
  await unzip(zipFilePath, extractDirPath, specificDirsToExtract);
207
208
 
208
- await preCacheTransform?.action({
209
- "destDirPath": extractDirPath
210
- });
209
+ try {
210
+ await preCacheTransform?.action({
211
+ "destDirPath": extractDirPath
212
+ });
213
+ } catch (error) {
214
+ await Promise.all([rm(extractDirPath, { "recursive": true }), unlink(zipFilePath)]);
215
+
216
+ throw error;
217
+ }
211
218
 
212
219
  await unlink(zipFilePath);
213
220
 
@@ -0,0 +1,43 @@
1
+ import * as fs from "fs/promises";
2
+ import { join as pathJoin } from "path";
3
+ import { SemVer } from "./SemVer";
4
+
5
+ /**
6
+ * Polyfill of fs.rm(dirPath, { "recursive": true })
7
+ * For older version of Node
8
+ */
9
+ export async function rm(dirPath: string, options: { recursive: true; force?: true }) {
10
+ if (SemVer.compare(SemVer.parse(process.version), SemVer.parse("14.14.0")) > 0) {
11
+ return fs.rm(dirPath, options);
12
+ }
13
+
14
+ const { force = true } = options;
15
+
16
+ if (force && !(await checkDirExists(dirPath))) {
17
+ return;
18
+ }
19
+
20
+ const removeDir_rec = async (dirPath: string) =>
21
+ Promise.all(
22
+ (await fs.readdir(dirPath)).map(async basename => {
23
+ const fileOrDirpath = pathJoin(dirPath, basename);
24
+
25
+ if ((await fs.lstat(fileOrDirpath)).isDirectory()) {
26
+ await removeDir_rec(fileOrDirpath);
27
+ } else {
28
+ await fs.unlink(fileOrDirpath);
29
+ }
30
+ })
31
+ );
32
+
33
+ await removeDir_rec(dirPath);
34
+ }
35
+
36
+ async function checkDirExists(dirPath: string) {
37
+ try {
38
+ await fs.access(dirPath, fs.constants.F_OK);
39
+ return true;
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
@@ -0,0 +1,34 @@
1
+ import * as fs from "fs";
2
+ import { join as pathJoin } from "path";
3
+ import { SemVer } from "./SemVer";
4
+
5
+ /**
6
+ * Polyfill of fs.rmSync(dirPath, { "recursive": true })
7
+ * For older version of Node
8
+ */
9
+ export function rmSync(dirPath: string, options: { recursive: true; force?: true }) {
10
+ if (SemVer.compare(SemVer.parse(process.version), SemVer.parse("14.14.0")) > 0) {
11
+ fs.rmSync(dirPath, options);
12
+ return;
13
+ }
14
+
15
+ const { force = true } = options;
16
+
17
+ if (force && !fs.existsSync(dirPath)) {
18
+ return;
19
+ }
20
+
21
+ const removeDir_rec = (dirPath: string) =>
22
+ fs.readdirSync(dirPath).forEach(basename => {
23
+ const fileOrDirpath = pathJoin(dirPath, basename);
24
+
25
+ if (fs.lstatSync(fileOrDirpath).isDirectory()) {
26
+ removeDir_rec(fileOrDirpath);
27
+ return;
28
+ } else {
29
+ fs.unlinkSync(fileOrDirpath);
30
+ }
31
+ });
32
+
33
+ removeDir_rec(dirPath);
34
+ }
@@ -7,6 +7,8 @@ export function getAbsoluteAndInOsFormatPath(params: { pathIsh: string; cwd: str
7
7
 
8
8
  pathOut = pathOut.replace(/\//g, pathSep);
9
9
 
10
+ pathOut = pathOut.endsWith(pathSep) ? pathOut.slice(0, -1) : pathOut;
11
+
10
12
  if (!pathIsAbsolute(pathOut)) {
11
13
  pathOut = pathJoin(cwd, pathOut);
12
14
  }
@@ -1,39 +1,39 @@
1
1
  import { listTagsFactory } from "./listTags";
2
2
  import type { Octokit } from "@octokit/rest";
3
- import { NpmModuleVersion } from "../NpmModuleVersion";
3
+ import { SemVer } from "../SemVer";
4
4
 
5
5
  export function getLatestsSemVersionedTagFactory(params: { octokit: Octokit }) {
6
6
  const { octokit } = params;
7
7
 
8
- async function getLatestsSemVersionedTag(params: { owner: string; repo: string; doIgnoreBeta: boolean; count: number }): Promise<
8
+ async function getLatestsSemVersionedTag(params: { owner: string; repo: string; count: number }): Promise<
9
9
  {
10
10
  tag: string;
11
- version: NpmModuleVersion;
11
+ version: SemVer;
12
12
  }[]
13
13
  > {
14
- const { owner, repo, doIgnoreBeta, count } = params;
14
+ const { owner, repo, count } = params;
15
15
 
16
- const semVersionedTags: { tag: string; version: NpmModuleVersion }[] = [];
16
+ const semVersionedTags: { tag: string; version: SemVer }[] = [];
17
17
 
18
18
  const { listTags } = listTagsFactory({ octokit });
19
19
 
20
20
  for await (const tag of listTags({ owner, repo })) {
21
- let version: NpmModuleVersion;
21
+ let version: SemVer;
22
22
 
23
23
  try {
24
- version = NpmModuleVersion.parse(tag.replace(/^[vV]?/, ""));
24
+ version = SemVer.parse(tag.replace(/^[vV]?/, ""));
25
25
  } catch {
26
26
  continue;
27
27
  }
28
28
 
29
- if (doIgnoreBeta && version.betaPreRelease !== undefined) {
29
+ if (version.rc !== undefined) {
30
30
  continue;
31
31
  }
32
32
 
33
33
  semVersionedTags.push({ tag, version });
34
34
  }
35
35
 
36
- return semVersionedTags.sort(({ version: vX }, { version: vY }) => NpmModuleVersion.compare(vY, vX)).slice(0, count);
36
+ return semVersionedTags.sort(({ version: vX }, { version: vY }) => SemVer.compare(vY, vX)).slice(0, count);
37
37
  }
38
38
 
39
39
  return { getLatestsSemVersionedTag };
@@ -1,7 +1,7 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { crawl } from "./crawl";
4
- import { id } from "tsafe/id";
4
+ import { rmSync } from "../tools/fs.rmSync";
5
5
 
6
6
  type TransformSourceCode = (params: { sourceCode: Buffer; filePath: string; fileRelativePath: string }) =>
7
7
  | {
@@ -10,18 +10,36 @@ type TransformSourceCode = (params: { sourceCode: Buffer; filePath: string; file
10
10
  }
11
11
  | undefined;
12
12
 
13
- /** Apply a transformation function to every file of directory */
13
+ /**
14
+ * Apply a transformation function to every file of directory
15
+ * If source and destination are the same this function can be used to apply the transformation in place
16
+ * like filtering out some files or modifying them.
17
+ * */
14
18
  export function transformCodebase(params: { srcDirPath: string; destDirPath: string; transformSourceCode?: TransformSourceCode }) {
15
- const {
16
- srcDirPath,
17
- destDirPath,
18
- transformSourceCode = id<TransformSourceCode>(({ sourceCode }) => ({
19
- "modifiedSourceCode": sourceCode
20
- }))
21
- } = params;
19
+ const { srcDirPath, transformSourceCode } = params;
20
+ let { destDirPath } = params;
21
+
22
+ const isTargetSameAsSource = path.relative(srcDirPath, destDirPath) === "";
23
+
24
+ if (isTargetSameAsSource) {
25
+ destDirPath = path.join(srcDirPath, "..", "tmp_xOsPdkPsTdzPs34sOkHs");
26
+ }
22
27
 
23
28
  for (const fileRelativePath of crawl({ "dirPath": srcDirPath, "returnedPathsType": "relative to dirPath" })) {
24
29
  const filePath = path.join(srcDirPath, fileRelativePath);
30
+ const destFilePath = path.join(destDirPath, fileRelativePath);
31
+
32
+ // NOTE: Optimization, if we don't need to transform the file, just copy
33
+ // it using the lower level implementation.
34
+ if (transformSourceCode === undefined) {
35
+ fs.mkdirSync(path.dirname(destFilePath), {
36
+ "recursive": true
37
+ });
38
+
39
+ fs.copyFileSync(filePath, destFilePath);
40
+
41
+ continue;
42
+ }
25
43
 
26
44
  const transformSourceCodeResult = transformSourceCode({
27
45
  "sourceCode": fs.readFileSync(filePath),
@@ -33,15 +51,18 @@ export function transformCodebase(params: { srcDirPath: string; destDirPath: str
33
51
  continue;
34
52
  }
35
53
 
36
- fs.mkdirSync(path.dirname(path.join(destDirPath, fileRelativePath)), {
54
+ fs.mkdirSync(path.dirname(destFilePath), {
37
55
  "recursive": true
38
56
  });
39
57
 
40
58
  const { newFileName, modifiedSourceCode } = transformSourceCodeResult;
41
59
 
42
- fs.writeFileSync(
43
- path.join(path.dirname(path.join(destDirPath, fileRelativePath)), newFileName ?? path.basename(fileRelativePath)),
44
- modifiedSourceCode
45
- );
60
+ fs.writeFileSync(path.join(path.dirname(destFilePath), newFileName ?? path.basename(destFilePath)), modifiedSourceCode);
61
+ }
62
+
63
+ if (isTargetSameAsSource) {
64
+ rmSync(srcDirPath, { "recursive": true });
65
+
66
+ fs.renameSync(destDirPath, srcDirPath);
46
67
  }
47
68
  }
@@ -1,11 +1,11 @@
1
1
  import type { KcContext } from "./KcContext";
2
2
  import type { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
3
- import { ftlValuesGlobalName } from "keycloakify/bin/keycloakify/ftlValuesGlobalName";
3
+ import { nameOfTheGlobal } from "keycloakify/bin/constants";
4
4
 
5
5
  export type ExtendKcContext<KcContextExtension extends { pageId: string }> = [KcContextExtension] extends [never]
6
6
  ? KcContext
7
7
  : AndByDiscriminatingKey<"pageId", KcContextExtension & KcContext.Common, KcContext>;
8
8
 
9
9
  export function getKcContextFromWindow<KcContextExtension extends { pageId: string } = never>(): ExtendKcContext<KcContextExtension> | undefined {
10
- return typeof window === "undefined" ? undefined : (window as any)[ftlValuesGlobalName];
10
+ return typeof window === "undefined" ? undefined : (window as any)[nameOfTheGlobal];
11
11
  }
@@ -94,7 +94,7 @@ export const { useGetClassName } = createUseClassName<ClassKey>({
94
94
  "kcAuthenticatorWebAuthnPasswordlessClass": "fa fa-key list-view-pf-icon-lg",
95
95
 
96
96
  //css classes for the OTP Login Form
97
- "kcSelectOTPListClass": "card-pf card-pf-view card-pf-view-select card-pf-view-single-select",
97
+ "kcSelectOTPListClass": "card-pf card-pf-view card-pf-view-select card-pf-view-single-select col-xs-12",
98
98
  "kcSelectOTPListItemClass": "card-pf-body card-pf-top-element",
99
99
  "kcAuthenticatorOtpCircleClass": "fa fa-mobile card-pf-icon-circle",
100
100
  "kcSelectOTPItemHeadingClass": "card-pf-title text-center",
@@ -1,5 +1,3 @@
1
- import { useEffect } from "react";
2
- import { headInsert } from "keycloakify/tools/headInsert";
3
1
  import { clsx } from "keycloakify/tools/clsx";
4
2
  import type { PageProps } from "keycloakify/login/pages/PageProps";
5
3
  import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
@@ -18,105 +16,77 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "
18
16
 
19
17
  const { msg, msgStr } = i18n;
20
18
 
21
- useEffect(() => {
22
- let isCleanedUp = false;
23
-
24
- const { prLoaded, remove } = headInsert({
25
- "type": "javascript",
26
- "src": `${kcContext.url.resourcesCommonPath}/node_modules/jquery/dist/jquery.min.js`
27
- });
28
-
29
- (async () => {
30
- await prLoaded;
31
-
32
- if (isCleanedUp) {
33
- return;
34
- }
35
-
36
- evaluateInlineScript();
37
- })();
38
-
39
- return () => {
40
- isCleanedUp = true;
41
- remove();
42
- };
43
- }, []);
44
-
45
19
  return (
46
- <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}>
47
- <form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
48
- {otpLogin.userOtpCredentials.length > 1 && (
49
- <div className={getClassName("kcFormGroupClass")}>
50
- <div className={getClassName("kcInputWrapperClass")}>
51
- {otpLogin.userOtpCredentials.map(otpCredential => (
52
- <div key={otpCredential.id} className={getClassName("kcSelectOTPListClass")}>
53
- <input type="hidden" value="${otpCredential.id}" />
54
- <div className={getClassName("kcSelectOTPListItemClass")}>
55
- <span className={getClassName("kcAuthenticatorOtpCircleClass")} />
56
- <h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2>
20
+ <>
21
+ <style>
22
+ {`
23
+ input[type="radio"]:checked~label.kcSelectOTPListClass{
24
+ border: 2px solid #39a5dc;
25
+ }`}
26
+ </style>
27
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}>
28
+ <form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
29
+ {otpLogin.userOtpCredentials.length > 1 && (
30
+ <div className={getClassName("kcFormGroupClass")}>
31
+ <div className={getClassName("kcInputWrapperClass")}>
32
+ {otpLogin.userOtpCredentials.map((otpCredential, index) => (
33
+ <div key={otpCredential.id}>
34
+ <input
35
+ id={`kc-otp-credential-${index}`}
36
+ name="selectedCredentialId"
37
+ type="radio"
38
+ value={otpCredential.id}
39
+ style={{ display: "none" }}
40
+ />
41
+ <label
42
+ htmlFor={`kc-otp-credential-${index}`}
43
+ key={otpCredential.id}
44
+ className={getClassName("kcSelectOTPListClass")}
45
+ >
46
+ <div className={getClassName("kcSelectOTPListItemClass")}>
47
+ <span className={getClassName("kcAuthenticatorOtpCircleClass")} />
48
+ <h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2>
49
+ </div>
50
+ </label>
57
51
  </div>
58
- </div>
59
- ))}
52
+ ))}
53
+ </div>
54
+ </div>
55
+ )}
56
+ <div className={getClassName("kcFormGroupClass")}>
57
+ <div className={getClassName("kcLabelWrapperClass")}>
58
+ <label htmlFor="otp" className={getClassName("kcLabelClass")}>
59
+ {msg("loginOtpOneTime")}
60
+ </label>
60
61
  </div>
61
- </div>
62
- )}
63
- <div className={getClassName("kcFormGroupClass")}>
64
- <div className={getClassName("kcLabelWrapperClass")}>
65
- <label htmlFor="otp" className={getClassName("kcLabelClass")}>
66
- {msg("loginOtpOneTime")}
67
- </label>
68
- </div>
69
62
 
70
- <div className={getClassName("kcInputWrapperClass")}>
71
- <input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus />
63
+ <div className={getClassName("kcInputWrapperClass")}>
64
+ <input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus />
65
+ </div>
72
66
  </div>
73
- </div>
74
67
 
75
- <div className={getClassName("kcFormGroupClass")}>
76
- <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
77
- <div className={getClassName("kcFormOptionsWrapperClass")} />
78
- </div>
68
+ <div className={getClassName("kcFormGroupClass")}>
69
+ <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
70
+ <div className={getClassName("kcFormOptionsWrapperClass")} />
71
+ </div>
79
72
 
80
- <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
81
- <input
82
- className={clsx(
83
- getClassName("kcButtonClass"),
84
- getClassName("kcButtonPrimaryClass"),
85
- getClassName("kcButtonBlockClass"),
86
- getClassName("kcButtonLargeClass")
87
- )}
88
- name="login"
89
- id="kc-login"
90
- type="submit"
91
- value={msgStr("doLogIn")}
92
- />
73
+ <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
74
+ <input
75
+ className={clsx(
76
+ getClassName("kcButtonClass"),
77
+ getClassName("kcButtonPrimaryClass"),
78
+ getClassName("kcButtonBlockClass"),
79
+ getClassName("kcButtonLargeClass")
80
+ )}
81
+ name="login"
82
+ id="kc-login"
83
+ type="submit"
84
+ value={msgStr("doLogIn")}
85
+ />
86
+ </div>
93
87
  </div>
94
- </div>
95
- </form>
96
- </Template>
88
+ </form>
89
+ </Template>
90
+ </>
97
91
  );
98
92
  }
99
-
100
- declare const $: any;
101
-
102
- function evaluateInlineScript() {
103
- $(document).ready(function () {
104
- // Card Single Select
105
- $(".card-pf-view-single-select").click(function (this: any) {
106
- if ($(this).hasClass("active")) {
107
- $(this).removeClass("active");
108
- $(this).children().removeAttr("name");
109
- } else {
110
- $(".card-pf-view-single-select").removeClass("active");
111
- $(".card-pf-view-single-select").children().removeAttr("name");
112
- $(this).addClass("active");
113
- $(this).children().attr("name", "selectedCredentialId");
114
- }
115
- });
116
-
117
- var defaultCred = $(".card-pf-view-single-select")[0];
118
- if (defaultCred) {
119
- defaultCred.click();
120
- }
121
- });
122
- }
package/src/tsconfig.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "jsx": "react-jsx",
15
15
  "allowSyntheticDefaultImports": true
16
16
  },
17
- "exclude": ["./bin"],
17
+ "exclude": ["./bin", "./vite-plugin"],
18
18
  "references": [
19
19
  {
20
20
  "path": "./bin"