keycloakify 10.0.0-rc.15 → 10.0.0-rc.17

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.
@@ -2,15 +2,19 @@ import { readBuildOptions } from "./shared/buildOptions";
2
2
  import type { CliCommandOptions as CliCommandOptions_common } from "./main";
3
3
  import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
4
4
  import { readMetaInfKeycloakThemes } from "./shared/metaInfKeycloakThemes";
5
- import { accountV1ThemeName } from "./shared/constants";
5
+ import { accountV1ThemeName, skipBuildJarsEnvName } from "./shared/constants";
6
6
  import { SemVer } from "./tools/SemVer";
7
7
  import type { KeycloakVersionRange } from "./shared/KeycloakVersionRange";
8
8
  import { getJarFileBasename } from "./shared/getJarFileBasename";
9
9
  import { assert, type Equals } from "tsafe/assert";
10
10
  import * as fs from "fs";
11
- import { join as pathJoin, posix as pathPosix } from "path";
11
+ import { join as pathJoin, relative as pathRelative, sep as pathSep, posix as pathPosix } from "path";
12
12
  import * as child_process from "child_process";
13
13
  import chalk from "chalk";
14
+ import chokidar from "chokidar";
15
+ import { waitForDebounceFactory } from "powerhooks/tools/waitForDebounce";
16
+ import { getThemeSrcDirPath } from "./shared/getThemeSrcDirPath";
17
+ import { Deferred } from "evt/tools/Deferred";
14
18
 
15
19
  export type CliCommandOptions = CliCommandOptions_common & {
16
20
  port: number;
@@ -91,13 +95,15 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
91
95
  };
92
96
  }
93
97
 
94
- console.log("On which version of Keycloak do you want to test your theme?");
98
+ console.log(chalk.cyan("On which version of Keycloak do you want to test your theme?"));
95
99
 
96
100
  const { keycloakVersion } = await promptKeycloakVersion({
97
101
  "startingFromMajor": 17,
98
102
  "cacheDirPath": buildOptions.cacheDirPath
99
103
  });
100
104
 
105
+ console.log(`→ ${keycloakVersion}`);
106
+
101
107
  const keycloakMajorNumber = SemVer.parse(keycloakVersion).major;
102
108
 
103
109
  if (doesImplementAccountTheme && keycloakMajorNumber === 22) {
@@ -149,6 +155,8 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
149
155
 
150
156
  const { jarFileBasename } = getJarFileBasename({ keycloakVersionRange });
151
157
 
158
+ console.log(`Using Keycloak ${chalk.bold(jarFileBasename)}`);
159
+
152
160
  const mountTargets = buildOptions.themeNames
153
161
  .map(themeName => {
154
162
  const themeEntry = metaInfKeycloakThemes.themes.find(({ name }) => name === themeName);
@@ -182,10 +190,10 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
182
190
  const containerName = "keycloak-keycloakify";
183
191
 
184
192
  try {
185
- child_process.execSync(`docker rm ${containerName}`, { "stdio": "ignore" });
193
+ child_process.execSync(`docker rm --force ${containerName}`, { "stdio": "ignore" });
186
194
  } catch {}
187
195
 
188
- const child = child_process.spawn(
196
+ const spawnParams = [
189
197
  "docker",
190
198
  [
191
199
  "run",
@@ -203,12 +211,18 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
203
211
  {
204
212
  "cwd": buildOptions.keycloakifyBuildDirPath
205
213
  }
206
- );
214
+ ] as const;
215
+
216
+ const child = child_process.spawn(...spawnParams);
207
217
 
208
218
  child.stdout.on("data", data => process.stdout.write(data));
209
219
 
210
220
  child.stderr.on("data", data => process.stderr.write(data));
211
221
 
222
+ child.on("exit", process.exit);
223
+
224
+ const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
225
+
212
226
  {
213
227
  const handler = async (data: Buffer) => {
214
228
  if (!data.toString("utf8").includes("Listening on: http://0.0.0.0:8080")) {
@@ -224,7 +238,12 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
224
238
  "",
225
239
  `${chalk.green("Your theme is accessible at:")}`,
226
240
  `${chalk.green("➜")} ${chalk.cyan.bold("https://test.keycloakify.dev/")}`,
227
- ""
241
+ "",
242
+ `Keycloak Admin console: ${chalk.cyan.bold(`http://localhost:${cliCommandOptions.port}`)}`,
243
+ `- user: ${chalk.cyan.bold("admin")}`,
244
+ `- password: ${chalk.cyan.bold("admin")}`,
245
+ "",
246
+ `Watching for changes in ${chalk.bold(`.${pathSep}${pathRelative(process.cwd(), themeSrcDirPath)}`)} ...`
228
247
  ].join("\n")
229
248
  );
230
249
  };
@@ -232,5 +251,59 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
232
251
  child.stdout.on("data", handler);
233
252
  }
234
253
 
235
- child.on("exit", process.exit);
254
+ {
255
+ const { waitForDebounce } = waitForDebounceFactory({ "delay": 400 });
256
+
257
+ chokidar.watch(themeSrcDirPath, { "ignoreInitial": true }).on("all", async (...eventArgs) => {
258
+ console.log({ eventArgs });
259
+
260
+ await waitForDebounce();
261
+
262
+ console.log(chalk.cyan("Detected changes in the theme. Rebuilding ..."));
263
+
264
+ const dViteBuildDone = new Deferred<void>();
265
+
266
+ {
267
+ const child = child_process.spawn("npx", ["vite", "build"], {
268
+ "cwd": buildOptions.reactAppRootDirPath,
269
+ "env": process.env
270
+ });
271
+
272
+ child.stdout.on("data", data => process.stdout.write(data));
273
+
274
+ child.stderr.on("data", data => process.stderr.write(data));
275
+
276
+ child.on("exit", code => {
277
+ if (code === 0) {
278
+ dViteBuildDone.resolve();
279
+ }
280
+ });
281
+ }
282
+
283
+ await dViteBuildDone.pr;
284
+
285
+ {
286
+ const child = child_process.spawn("npx", ["keycloakify", "build"], {
287
+ "cwd": buildOptions.reactAppRootDirPath,
288
+ "env": {
289
+ ...process.env,
290
+ [skipBuildJarsEnvName]: "true"
291
+ }
292
+ });
293
+
294
+ child.stdout.on("data", data => process.stdout.write(data));
295
+
296
+ child.stderr.on("data", data => process.stderr.write(data));
297
+
298
+ child.on("exit", code => {
299
+ if (code !== 0) {
300
+ console.log(chalk.yellow("Theme not updated, build failed"));
301
+ return;
302
+ }
303
+
304
+ console.log(chalk.green("Rebuild done"));
305
+ });
306
+ }
307
+ });
308
+ }
236
309
  }
@@ -1,9 +1,10 @@
1
1
  import * as child_process from "child_process";
2
2
  import { join as pathJoin, resolve as pathResolve, sep as pathSep } from "path";
3
3
  import { assert } from "tsafe/assert";
4
+ import * as fs from "fs";
4
5
 
5
- export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string }) {
6
- const { reactAppRootDirPath } = params;
6
+ export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string; dependencyExpected: string }) {
7
+ const { reactAppRootDirPath, dependencyExpected } = params;
7
8
 
8
9
  const npmWorkspaceRootDirPath = (function callee(depth: number): string {
9
10
  const cwd = pathResolve(pathJoin(...[reactAppRootDirPath, ...Array(depth).fill("..")]));
@@ -20,6 +21,38 @@ export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string
20
21
  throw error;
21
22
  }
22
23
 
24
+ const { isExpectedDependencyFound } = (() => {
25
+ const packageJsonFilePath = pathJoin(cwd, "package.json");
26
+
27
+ assert(fs.existsSync(packageJsonFilePath));
28
+
29
+ const parsedPackageJson = JSON.parse(fs.readFileSync(packageJsonFilePath).toString("utf8"));
30
+
31
+ let isExpectedDependencyFound = false;
32
+
33
+ for (const dependenciesOrDevDependencies of ["dependencies", "devDependencies"] as const) {
34
+ const dependencies = parsedPackageJson[dependenciesOrDevDependencies];
35
+
36
+ if (dependencies === undefined) {
37
+ continue;
38
+ }
39
+
40
+ assert(dependencies instanceof Object);
41
+
42
+ if (dependencies[dependencyExpected] === undefined) {
43
+ continue;
44
+ }
45
+
46
+ isExpectedDependencyFound = true;
47
+ }
48
+
49
+ return { isExpectedDependencyFound };
50
+ })();
51
+
52
+ if (!isExpectedDependencyFound) {
53
+ return callee(depth + 1);
54
+ }
55
+
23
56
  return cwd;
24
57
  })(0);
25
58
 
@@ -133,7 +133,10 @@ function readBuildOptions(params) {
133
133
  }
134
134
  return (0, path_1.join)(reactAppRootDirPath, resolvedViteConfig.buildDir);
135
135
  })();
136
- var npmWorkspaceRootDirPath = (0, getNpmWorkspaceRootDirPath_1.getNpmWorkspaceRootDirPath)({ reactAppRootDirPath: reactAppRootDirPath }).npmWorkspaceRootDirPath;
136
+ var npmWorkspaceRootDirPath = (0, getNpmWorkspaceRootDirPath_1.getNpmWorkspaceRootDirPath)({
137
+ reactAppRootDirPath: reactAppRootDirPath,
138
+ "dependencyExpected": "keycloakify"
139
+ }).npmWorkspaceRootDirPath;
137
140
  return {
138
141
  "bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
139
142
  "themeVersion": (_b = (_a = process.env.KEYCLOAKIFY_THEME_VERSION) !== null && _a !== void 0 ? _a : parsedPackageJson.version) !== null && _b !== void 0 ? _b : "0.0.0",
@@ -228,7 +231,7 @@ exports.readBuildOptions = readBuildOptions;
228
231
  "use strict";
229
232
 
230
233
  Object.defineProperty(exports, "__esModule", ({ value: true }));
231
- exports.accountThemePageIds = exports.loginThemePageIds = exports.vitePluginSubScriptEnvNames = exports.accountV1ThemeName = exports.themeTypes = exports.basenameOfTheKeycloakifyResourcesDir = exports.lastKeycloakVersionWithAccountV1 = exports.resources_common = exports.keycloak_resources = exports.nameOfTheGlobal = void 0;
234
+ exports.accountThemePageIds = exports.loginThemePageIds = exports.skipBuildJarsEnvName = exports.vitePluginSubScriptEnvNames = exports.accountV1ThemeName = exports.themeTypes = exports.basenameOfTheKeycloakifyResourcesDir = exports.lastKeycloakVersionWithAccountV1 = exports.resources_common = exports.keycloak_resources = exports.nameOfTheGlobal = void 0;
232
235
  exports.nameOfTheGlobal = "kcContext";
233
236
  exports.keycloak_resources = "keycloak-resources";
234
237
  exports.resources_common = "resources-common";
@@ -240,6 +243,7 @@ exports.vitePluginSubScriptEnvNames = {
240
243
  "runPostBuildScript": "KEYCLOAKIFY_RUN_POST_BUILD_SCRIPT",
241
244
  "resolveViteConfig": "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
242
245
  };
246
+ exports.skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
243
247
  exports.loginThemePageIds = [
244
248
  "login.ftl",
245
249
  "login-username.ftl",
@@ -660,10 +664,10 @@ function downloadAndUnzip(params) {
660
664
  return [4 /*yield*/, (0, fs_rm_1.rm)(extractDirPath, { "recursive": true })];
661
665
  case 13:
662
666
  _d.sent();
663
- upload_to_remot_cache_if_admin: {
667
+ upload_to_remote_cache_if_admin: {
664
668
  githubToken = process.env["KEYCLOAKIFY_ADMIN_GITHUB_PERSONAL_ACCESS_TOKEN"];
665
- if (githubToken === undefined) {
666
- break upload_to_remot_cache_if_admin;
669
+ if (!githubToken) {
670
+ break upload_to_remote_cache_if_admin;
667
671
  }
668
672
  console.log("uploading to remote cache");
669
673
  try {
@@ -735,7 +739,7 @@ function generateFileNameFromURL(params) {
735
739
 
736
740
  /***/ }),
737
741
 
738
- /***/ 6800:
742
+ /***/ 597:
739
743
  /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
740
744
 
741
745
  "use strict";
@@ -825,7 +829,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
825
829
  return to.concat(ar || Array.prototype.slice.call(from));
826
830
  };
827
831
  Object.defineProperty(exports, "__esModule", ({ value: true }));
828
- exports.downloadBuiltinKeycloakTheme = void 0;
832
+ exports.downloadKeycloakDefaultTheme = void 0;
829
833
  var path_1 = __nccwpck_require__(1017);
830
834
  var downloadAndUnzip_1 = __nccwpck_require__(8469);
831
835
  var assert_1 = __nccwpck_require__(8078);
@@ -835,7 +839,7 @@ var fs_rmSync_1 = __nccwpck_require__(9693);
835
839
  var constants_1 = __nccwpck_require__(173);
836
840
  var transformCodebase_1 = __nccwpck_require__(332);
837
841
  (0, assert_1.assert)();
838
- function downloadBuiltinKeycloakTheme(params) {
842
+ function downloadKeycloakDefaultTheme(params) {
839
843
  return __awaiter(this, void 0, void 0, function () {
840
844
  var keycloakVersion, destDirPath, buildOptions;
841
845
  var _this = this;
@@ -1053,8 +1057,8 @@ function downloadBuiltinKeycloakTheme(params) {
1053
1057
  });
1054
1058
  });
1055
1059
  }
1056
- exports.downloadBuiltinKeycloakTheme = downloadBuiltinKeycloakTheme;
1057
- //# sourceMappingURL=downloadBuiltinKeycloakTheme.js.map
1060
+ exports.downloadKeycloakDefaultTheme = downloadKeycloakDefaultTheme;
1061
+ //# sourceMappingURL=downloadKeycloakDefaultTheme.js.map
1058
1062
 
1059
1063
  /***/ }),
1060
1064
 
@@ -1126,7 +1130,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
1126
1130
  exports.downloadKeycloakStaticResources = void 0;
1127
1131
  var transformCodebase_1 = __nccwpck_require__(332);
1128
1132
  var path_1 = __nccwpck_require__(1017);
1129
- var downloadBuiltinKeycloakTheme_1 = __nccwpck_require__(6800);
1133
+ var downloadKeycloakDefaultTheme_1 = __nccwpck_require__(597);
1130
1134
  var constants_1 = __nccwpck_require__(173);
1131
1135
  var assert_1 = __nccwpck_require__(8078);
1132
1136
  var crypto = __importStar(__nccwpck_require__(6113));
@@ -1140,7 +1144,7 @@ function downloadKeycloakStaticResources(params) {
1140
1144
  case 0:
1141
1145
  themeType = params.themeType, themeDirPath = params.themeDirPath, keycloakVersion = params.keycloakVersion, buildOptions = params.buildOptions;
1142
1146
  tmpDirPath = (0, path_1.join)(buildOptions.cacheDirPath, "downloadKeycloakStaticResources_tmp_".concat(crypto.createHash("sha256").update("".concat(themeType, "-").concat(keycloakVersion)).digest("hex").slice(0, 8)));
1143
- return [4 /*yield*/, (0, downloadBuiltinKeycloakTheme_1.downloadBuiltinKeycloakTheme)({
1147
+ return [4 /*yield*/, (0, downloadKeycloakDefaultTheme_1.downloadKeycloakDefaultTheme)({
1144
1148
  keycloakVersion: keycloakVersion,
1145
1149
  "destDirPath": tmpDirPath,
1146
1150
  buildOptions: buildOptions
@@ -1973,13 +1977,25 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
1973
1977
  }
1974
1978
  return to.concat(ar || Array.prototype.slice.call(from));
1975
1979
  };
1980
+ var __values = (this && this.__values) || function(o) {
1981
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
1982
+ if (m) return m.call(o);
1983
+ if (o && typeof o.length === "number") return {
1984
+ next: function () {
1985
+ if (o && i >= o.length) o = void 0;
1986
+ return { value: o && o[i++], done: !o };
1987
+ }
1988
+ };
1989
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
1990
+ };
1976
1991
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1977
1992
  exports.getNpmWorkspaceRootDirPath = void 0;
1978
1993
  var child_process = __importStar(__nccwpck_require__(2081));
1979
1994
  var path_1 = __nccwpck_require__(1017);
1980
1995
  var assert_1 = __nccwpck_require__(8078);
1996
+ var fs = __importStar(__nccwpck_require__(7147));
1981
1997
  function getNpmWorkspaceRootDirPath(params) {
1982
- var reactAppRootDirPath = params.reactAppRootDirPath;
1998
+ var reactAppRootDirPath = params.reactAppRootDirPath, dependencyExpected = params.dependencyExpected;
1983
1999
  var npmWorkspaceRootDirPath = (function callee(depth) {
1984
2000
  var cwd = (0, path_1.resolve)(path_1.join.apply(void 0, __spreadArray([], __read(__spreadArray([reactAppRootDirPath], __read(Array(depth).fill("..")), false)), false)));
1985
2001
  try {
@@ -1992,6 +2008,38 @@ function getNpmWorkspaceRootDirPath(params) {
1992
2008
  }
1993
2009
  throw error;
1994
2010
  }
2011
+ var isExpectedDependencyFound = (function () {
2012
+ var e_1, _a;
2013
+ var packageJsonFilePath = (0, path_1.join)(cwd, "package.json");
2014
+ (0, assert_1.assert)(fs.existsSync(packageJsonFilePath));
2015
+ var parsedPackageJson = JSON.parse(fs.readFileSync(packageJsonFilePath).toString("utf8"));
2016
+ var isExpectedDependencyFound = false;
2017
+ try {
2018
+ for (var _b = __values(["dependencies", "devDependencies"]), _c = _b.next(); !_c.done; _c = _b.next()) {
2019
+ var dependenciesOrDevDependencies = _c.value;
2020
+ var dependencies = parsedPackageJson[dependenciesOrDevDependencies];
2021
+ if (dependencies === undefined) {
2022
+ continue;
2023
+ }
2024
+ (0, assert_1.assert)(dependencies instanceof Object);
2025
+ if (dependencies[dependencyExpected] === undefined) {
2026
+ continue;
2027
+ }
2028
+ isExpectedDependencyFound = true;
2029
+ }
2030
+ }
2031
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2032
+ finally {
2033
+ try {
2034
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2035
+ }
2036
+ finally { if (e_1) throw e_1.error; }
2037
+ }
2038
+ return { isExpectedDependencyFound: isExpectedDependencyFound };
2039
+ })().isExpectedDependencyFound;
2040
+ if (!isExpectedDependencyFound) {
2041
+ return callee(depth + 1);
2042
+ }
1995
2043
  return cwd;
1996
2044
  })(0);
1997
2045
  return { npmWorkspaceRootDirPath: npmWorkspaceRootDirPath };
@@ -1,30 +0,0 @@
1
- import { join as pathJoin } from "path";
2
- import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
3
- import { readBuildOptions } from "./shared/buildOptions";
4
- import { downloadBuiltinKeycloakTheme } from "./shared/downloadBuiltinKeycloakTheme";
5
- import type { CliCommandOptions } from "./main";
6
-
7
- export async function command(params: { cliCommandOptions: CliCommandOptions }) {
8
- const { cliCommandOptions } = params;
9
-
10
- const buildOptions = readBuildOptions({
11
- cliCommandOptions
12
- });
13
-
14
- console.log("Select the Keycloak version from which you want to download the builtins theme:");
15
-
16
- const { keycloakVersion } = await promptKeycloakVersion({
17
- "startingFromMajor": undefined,
18
- "cacheDirPath": buildOptions.cacheDirPath
19
- });
20
-
21
- const destDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme");
22
-
23
- console.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
24
-
25
- await downloadBuiltinKeycloakTheme({
26
- keycloakVersion,
27
- destDirPath,
28
- buildOptions
29
- });
30
- }