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
@@ -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,14 @@
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
- import { dirname as pathDirname, join as pathJoin, resolve as pathResolve, sep as pathSep } from "path";
5
+ import { dirname as pathDirname, join as pathJoin, resolve as pathResolve, sep as pathSep, basename as pathBasename } 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";
11
+ import * as child_process from "child_process";
10
12
 
11
13
  const exec = promisify(execCallback);
12
14
 
@@ -187,10 +189,31 @@ export async function downloadAndUnzip(
187
189
  const zipFilePath = pathJoin(cacheDirPath, `${zipFileBasename}.zip`);
188
190
  const extractDirPath = pathJoin(cacheDirPath, `tmp_unzip_${zipFileBasename}`);
189
191
 
190
- if (!(await exists(zipFilePath))) {
192
+ download_zip_and_transform: {
193
+ if (await exists(zipFilePath)) {
194
+ break download_zip_and_transform;
195
+ }
196
+
191
197
  const opts = await getFetchOptions();
192
- const response = await fetch(url, opts);
198
+
199
+ const { response, isFromRemoteCache } = await (async () => {
200
+ const response = await fetch(`https://github.com/keycloakify/keycloakify/releases/download/v0.0.1/${pathBasename(zipFilePath)}`, opts);
201
+
202
+ if (response.status === 200) {
203
+ return {
204
+ response,
205
+ "isFromRemoteCache": true
206
+ };
207
+ }
208
+
209
+ return {
210
+ "response": await fetch(url, opts),
211
+ "isFromRemoteCache": false
212
+ };
213
+ })();
214
+
193
215
  await mkdir(pathDirname(zipFilePath), { "recursive": true });
216
+
194
217
  /**
195
218
  * The correct way to fix this is to upgrade node-fetch beyond 3.2.5
196
219
  * (see https://github.com/node-fetch/node-fetch/issues/1295#issuecomment-1144061991.)
@@ -200,20 +223,66 @@ export async function downloadAndUnzip(
200
223
  */
201
224
  response.body?.setMaxListeners(Number.MAX_VALUE);
202
225
  assert(typeof response.body !== "undefined" && response.body != null);
226
+
203
227
  await writeFile(zipFilePath, response.body);
204
228
 
205
- if (specificDirsToExtract !== undefined || preCacheTransform !== undefined) {
206
- await unzip(zipFilePath, extractDirPath, specificDirsToExtract);
229
+ if (isFromRemoteCache) {
230
+ break download_zip_and_transform;
231
+ }
207
232
 
233
+ if (specificDirsToExtract === undefined && preCacheTransform === undefined) {
234
+ break download_zip_and_transform;
235
+ }
236
+
237
+ await unzip(zipFilePath, extractDirPath, specificDirsToExtract);
238
+
239
+ try {
208
240
  await preCacheTransform?.action({
209
241
  "destDirPath": extractDirPath
210
242
  });
243
+ } catch (error) {
244
+ await Promise.all([rm(extractDirPath, { "recursive": true }), unlink(zipFilePath)]);
245
+
246
+ throw error;
247
+ }
211
248
 
212
- await unlink(zipFilePath);
249
+ await unlink(zipFilePath);
250
+
251
+ await zip(extractDirPath, zipFilePath);
252
+
253
+ await rm(extractDirPath, { "recursive": true });
213
254
 
214
- await zip(extractDirPath, zipFilePath);
255
+ upload_to_remot_cache_if_admin: {
256
+ const githubToken = process.env["KEYCLOAKIFY_ADMIN_GITHUB_PERSONAL_ACCESS_TOKEN"];
215
257
 
216
- await rm(extractDirPath, { "recursive": true });
258
+ if (githubToken === undefined) {
259
+ break upload_to_remot_cache_if_admin;
260
+ }
261
+
262
+ console.log("uploading to remote cache");
263
+
264
+ try {
265
+ child_process.execSync(`which putasset`);
266
+ } catch {
267
+ child_process.execSync(`npm install -g putasset`);
268
+ }
269
+
270
+ try {
271
+ child_process.execFileSync("putasset", [
272
+ "--owner",
273
+ "keycloakify",
274
+ "--repo",
275
+ "keycloakify",
276
+ "--tag",
277
+ "v0.0.1",
278
+ "--filename",
279
+ zipFilePath,
280
+ "--token",
281
+ githubToken
282
+ ]);
283
+ } catch {
284
+ console.log("upload failed, asset probably already exists in remote cache");
285
+ }
217
286
  }
218
287
  }
219
288
 
@@ -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
  }
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"