keycloakify 11.7.4 → 11.8.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 (38) hide show
  1. package/bin/{33.index.js → 226.index.js} +2 -19
  2. package/bin/{911.index.js → 297.index.js} +18918 -11359
  3. package/bin/355.index.js +41 -703
  4. package/bin/363.index.js +115 -93
  5. package/bin/369.index.js +968 -0
  6. package/bin/{288.index.js → 502.index.js} +123 -227
  7. package/bin/656.index.js +111 -0
  8. package/bin/{880.index.js → 712.index.js} +227 -216
  9. package/bin/780.index.js +9 -7
  10. package/bin/932.index.js +965 -0
  11. package/bin/97.index.js +2099 -769
  12. package/bin/main.js +66 -49
  13. package/bin/shared/buildContext.d.ts +11 -3
  14. package/bin/start-keycloak/realmConfig/prepareRealmConfig.d.ts +5 -6
  15. package/bin/start-keycloak/realmConfig/realmConfig.d.ts +6 -2
  16. package/package.json +12 -17
  17. package/src/bin/initialize-account-theme/initialize-account-theme.ts +29 -27
  18. package/src/bin/initialize-email-theme.ts +103 -53
  19. package/src/bin/keycloakify/buildJars/buildJar.ts +45 -20
  20. package/src/bin/keycloakify/generateResources/generateResources.ts +263 -217
  21. package/src/bin/shared/{initializeSpa/addSyncExtensionsToPostinstallScript.ts → addSyncExtensionsToPostinstallScript.ts} +1 -1
  22. package/src/bin/shared/buildContext.ts +69 -24
  23. package/src/bin/shared/{initializeSpa/initializeSpa.ts → initializeSpa.ts} +3 -3
  24. package/src/bin/start-keycloak/realmConfig/prepareRealmConfig.ts +12 -23
  25. package/src/bin/start-keycloak/realmConfig/realmConfig.ts +14 -12
  26. package/src/bin/start-keycloak/start-keycloak.ts +55 -28
  27. package/src/bin/sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.ts +6 -0
  28. package/vite-plugin/index.js +48 -20
  29. package/bin/313.index.js +0 -377
  30. package/bin/678.index.js +0 -7565
  31. package/bin/9.index.js +0 -850
  32. package/bin/947.index.js +0 -1565
  33. package/bin/shared/initializeSpa/index.d.ts +0 -1
  34. package/bin/shared/metaInfKeycloakThemes.d.ts +0 -13
  35. package/src/bin/shared/initializeSpa/index.ts +0 -1
  36. package/src/bin/shared/metaInfKeycloakThemes.ts +0 -40
  37. /package/bin/shared/{initializeSpa/addSyncExtensionsToPostinstallScript.d.ts → addSyncExtensionsToPostinstallScript.d.ts} +0 -0
  38. /package/bin/shared/{initializeSpa/initializeSpa.d.ts → initializeSpa.d.ts} +0 -0
package/bin/main.js CHANGED
@@ -8693,24 +8693,6 @@ const id = (x) => x;
8693
8693
  //# sourceMappingURL=id.mjs.map
8694
8694
 
8695
8695
 
8696
- /***/ }),
8697
-
8698
- /***/ 91040:
8699
- /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
8700
-
8701
- "use strict";
8702
- /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
8703
- /* harmony export */ "q": () => (/* binding */ objectEntries)
8704
- /* harmony export */ });
8705
- /** https://docs.tsafe.dev/objectentries */
8706
- function objectEntries(o) {
8707
- return Object.entries(o);
8708
- }
8709
-
8710
-
8711
- //# sourceMappingURL=objectEntries.mjs.map
8712
-
8713
-
8714
8696
  /***/ }),
8715
8697
 
8716
8698
  /***/ 52300:
@@ -15400,8 +15382,15 @@ var exclude = __nccwpck_require__(83101);
15400
15382
 
15401
15383
  // EXTERNAL MODULE: ./dist/bin/tools/crawl.js
15402
15384
  var crawl = __nccwpck_require__(73036);
15403
- // EXTERNAL MODULE: ./node_modules/tsafe/esm/objectEntries.mjs
15404
- var objectEntries = __nccwpck_require__(91040);
15385
+ ;// CONCATENATED MODULE: ./node_modules/tsafe/esm/objectEntries.mjs
15386
+ /** https://docs.tsafe.dev/objectentries */
15387
+ function objectEntries(o) {
15388
+ return Object.entries(o);
15389
+ }
15390
+
15391
+
15392
+ //# sourceMappingURL=objectEntries.mjs.map
15393
+
15405
15394
  // EXTERNAL MODULE: ./node_modules/tsafe/esm/id.mjs
15406
15395
  var id = __nccwpck_require__(38469);
15407
15396
  ;// CONCATENATED MODULE: ./dist/bin/tools/fetchProxyOptions.js
@@ -15698,26 +15687,54 @@ function getBuildContext(params) {
15698
15687
  }
15699
15688
  (0,assert/* assert */.h)(false);
15700
15689
  })();
15701
- const implementedThemeTypes = {
15702
- login: {
15703
- isImplemented: external_fs_.existsSync((0,external_path_.join)(themeSrcDirPath, "login"))
15704
- },
15705
- email: {
15706
- isImplemented: external_fs_.existsSync((0,external_path_.join)(themeSrcDirPath, "email"))
15707
- },
15708
- account: (() => {
15709
- if (buildOptions.accountThemeImplementation === "none") {
15710
- return { isImplemented: false };
15711
- }
15712
- return {
15713
- isImplemented: true,
15714
- type: buildOptions.accountThemeImplementation
15715
- };
15716
- })(),
15717
- admin: {
15718
- isImplemented: external_fs_.existsSync((0,external_path_.join)(themeSrcDirPath, "admin"))
15719
- }
15720
- };
15690
+ const implementedThemeTypes = (() => {
15691
+ const getIsNative = (dirPath) => external_fs_.existsSync((0,external_path_.join)(dirPath, "theme.properties"));
15692
+ return {
15693
+ login: (() => {
15694
+ const dirPath = (0,external_path_.join)(themeSrcDirPath, "login");
15695
+ if (!external_fs_.existsSync(dirPath)) {
15696
+ return { isImplemented: false, isImplemented_native: false };
15697
+ }
15698
+ if (getIsNative(dirPath)) {
15699
+ return { isImplemented: false, isImplemented_native: true };
15700
+ }
15701
+ return { isImplemented: true };
15702
+ })(),
15703
+ email: (() => {
15704
+ const dirPath = (0,external_path_.join)(themeSrcDirPath, "email");
15705
+ if (!external_fs_.existsSync(dirPath) || !getIsNative(dirPath)) {
15706
+ return { isImplemented: false, isImplemented_native: false };
15707
+ }
15708
+ return { isImplemented: false, isImplemented_native: true };
15709
+ })(),
15710
+ account: (() => {
15711
+ const dirPath = (0,external_path_.join)(themeSrcDirPath, "account");
15712
+ if (!external_fs_.existsSync(dirPath)) {
15713
+ return { isImplemented: false, isImplemented_native: false };
15714
+ }
15715
+ if (getIsNative(dirPath)) {
15716
+ return { isImplemented: false, isImplemented_native: true };
15717
+ }
15718
+ if (buildOptions.accountThemeImplementation === "none") {
15719
+ return { isImplemented: false, isImplemented_native: false };
15720
+ }
15721
+ return {
15722
+ isImplemented: true,
15723
+ type: buildOptions.accountThemeImplementation
15724
+ };
15725
+ })(),
15726
+ admin: (() => {
15727
+ const dirPath = (0,external_path_.join)(themeSrcDirPath, "admin");
15728
+ if (!external_fs_.existsSync(dirPath)) {
15729
+ return { isImplemented: false, isImplemented_native: false };
15730
+ }
15731
+ if (getIsNative(dirPath)) {
15732
+ return { isImplemented: false, isImplemented_native: true };
15733
+ }
15734
+ return { isImplemented: true };
15735
+ })()
15736
+ };
15737
+ })();
15721
15738
  if (implementedThemeTypes.account.isImplemented &&
15722
15739
  !external_fs_.existsSync((0,external_path_.join)(themeSrcDirPath, "account"))) {
15723
15740
  console.error(source_default().red([
@@ -15975,7 +15992,7 @@ function getBuildContext(params) {
15975
15992
  if (keycloakVersionTargets === undefined) {
15976
15993
  break use_custom_jar_basename;
15977
15994
  }
15978
- const entry = (0,objectEntries/* objectEntries */.q)(keycloakVersionTargets).find(([keycloakVersionRange_entry]) => keycloakVersionRange_entry === keycloakVersionRange);
15995
+ const entry = objectEntries(keycloakVersionTargets).find(([keycloakVersionRange_entry]) => keycloakVersionRange_entry === keycloakVersionRange);
15979
15996
  if (entry === undefined) {
15980
15997
  break use_custom_jar_basename;
15981
15998
  }
@@ -16030,7 +16047,7 @@ function getBuildContext(params) {
16030
16047
  return jarTargets_default;
16031
16048
  }
16032
16049
  const jarTargets = [];
16033
- for (const [keycloakVersionRange, jarNameOrBoolean] of (0,objectEntries/* objectEntries */.q)((() => {
16050
+ for (const [keycloakVersionRange, jarNameOrBoolean] of objectEntries((() => {
16034
16051
  const { keycloakVersionTargets } = buildOptions;
16035
16052
  (0,assert/* assert */.h)((0,assert.is)(keycloakVersionTargets));
16036
16053
  return keycloakVersionTargets;
@@ -16153,7 +16170,7 @@ program
16153
16170
  .task({
16154
16171
  skip,
16155
16172
  handler: async ({ projectDirPath }) => {
16156
- const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(783), __nccwpck_require__.e(880)]).then(__nccwpck_require__.bind(__nccwpck_require__, 59880));
16173
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(783), __nccwpck_require__.e(712)]).then(__nccwpck_require__.bind(__nccwpck_require__, 35712));
16157
16174
  await command({ buildContext: getBuildContext({ projectDirPath }) });
16158
16175
  }
16159
16176
  });
@@ -16201,7 +16218,7 @@ program
16201
16218
  .task({
16202
16219
  skip,
16203
16220
  handler: async ({ projectDirPath, keycloakVersion, port, realmJsonFilePath }) => {
16204
- const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(33), __nccwpck_require__.e(911), __nccwpck_require__.e(678), __nccwpck_require__.e(9), __nccwpck_require__.e(947)]).then(__nccwpck_require__.bind(__nccwpck_require__, 32947));
16221
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(226), __nccwpck_require__.e(297), __nccwpck_require__.e(97)]).then(__nccwpck_require__.bind(__nccwpck_require__, 64097));
16205
16222
  await command({
16206
16223
  buildContext: getBuildContext({ projectDirPath }),
16207
16224
  cliCommandOptions: {
@@ -16232,7 +16249,7 @@ program
16232
16249
  .task({
16233
16250
  skip,
16234
16251
  handler: async ({ projectDirPath }) => {
16235
- const { command } = await __nccwpck_require__.e(/* import() */ 97).then(__nccwpck_require__.bind(__nccwpck_require__, 98097));
16252
+ const { command } = await __nccwpck_require__.e(/* import() */ 369).then(__nccwpck_require__.bind(__nccwpck_require__, 98097));
16236
16253
  await command({ buildContext: getBuildContext({ projectDirPath }) });
16237
16254
  }
16238
16255
  });
@@ -16244,7 +16261,7 @@ program
16244
16261
  .task({
16245
16262
  skip,
16246
16263
  handler: async ({ projectDirPath }) => {
16247
- const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(911), __nccwpck_require__.e(9), __nccwpck_require__.e(313)]).then(__nccwpck_require__.bind(__nccwpck_require__, 16932));
16264
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(502), __nccwpck_require__.e(932)]).then(__nccwpck_require__.bind(__nccwpck_require__, 16932));
16248
16265
  await command({ buildContext: getBuildContext({ projectDirPath }) });
16249
16266
  }
16250
16267
  });
@@ -16268,7 +16285,7 @@ program
16268
16285
  .task({
16269
16286
  skip,
16270
16287
  handler: async ({ projectDirPath }) => {
16271
- const { command } = await __nccwpck_require__.e(/* import() */ 355).then(__nccwpck_require__.bind(__nccwpck_require__, 60355));
16288
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(502), __nccwpck_require__.e(355)]).then(__nccwpck_require__.bind(__nccwpck_require__, 60355));
16272
16289
  await command({ buildContext: getBuildContext({ projectDirPath }) });
16273
16290
  }
16274
16291
  });
@@ -16321,7 +16338,7 @@ program
16321
16338
  .task({
16322
16339
  skip,
16323
16340
  handler: async ({ projectDirPath }) => {
16324
- const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(33), __nccwpck_require__.e(363), __nccwpck_require__.e(946)]).then(__nccwpck_require__.bind(__nccwpck_require__, 74946));
16341
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(226), __nccwpck_require__.e(363), __nccwpck_require__.e(946)]).then(__nccwpck_require__.bind(__nccwpck_require__, 74946));
16325
16342
  await command({ buildContext: getBuildContext({ projectDirPath }) });
16326
16343
  }
16327
16344
  });
@@ -16375,7 +16392,7 @@ program
16375
16392
  .task({
16376
16393
  skip,
16377
16394
  handler: async ({ projectDirPath, path, revert }) => {
16378
- const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(33), __nccwpck_require__.e(363), __nccwpck_require__.e(930)]).then(__nccwpck_require__.bind(__nccwpck_require__, 71930));
16395
+ const { command } = await Promise.all(/* import() */[__nccwpck_require__.e(226), __nccwpck_require__.e(363), __nccwpck_require__.e(930)]).then(__nccwpck_require__.bind(__nccwpck_require__, 71930));
16379
16396
  await command({
16380
16397
  buildContext: getBuildContext({ projectDirPath }),
16381
16398
  cliCommandOptions: { path, isRevert: revert }
@@ -25,19 +25,27 @@ export type BuildContext = {
25
25
  themeSrcDirPath: string;
26
26
  implementedThemeTypes: {
27
27
  login: {
28
- isImplemented: boolean;
28
+ isImplemented: true;
29
+ } | {
30
+ isImplemented: false;
31
+ isImplemented_native: boolean;
29
32
  };
30
33
  email: {
31
- isImplemented: boolean;
34
+ isImplemented: false;
35
+ isImplemented_native: boolean;
32
36
  };
33
37
  account: {
34
38
  isImplemented: false;
39
+ isImplemented_native: boolean;
35
40
  } | {
36
41
  isImplemented: true;
37
42
  type: "Single-Page" | "Multi-Page";
38
43
  };
39
44
  admin: {
40
- isImplemented: boolean;
45
+ isImplemented: true;
46
+ } | {
47
+ isImplemented: false;
48
+ isImplemented_native: boolean;
41
49
  };
42
50
  };
43
51
  packageJsonFilePath: string;
@@ -1,13 +1,12 @@
1
1
  import type { ParsedRealmJson } from "./ParsedRealmJson";
2
- import type { BuildContext } from "../../shared/buildContext";
3
- export type BuildContextLike = {
4
- themeNames: BuildContext["themeNames"];
5
- implementedThemeTypes: BuildContext["implementedThemeTypes"];
6
- };
2
+ import { type ThemeType } from "../../shared/constants";
7
3
  export declare function prepareRealmConfig(params: {
8
4
  parsedRealmJson: ParsedRealmJson;
9
5
  keycloakMajorVersionNumber: number;
10
- buildContext: BuildContextLike;
6
+ parsedKeycloakThemesJsonEntry: {
7
+ name: string;
8
+ types: (ThemeType | "email")[];
9
+ };
11
10
  }): {
12
11
  realmName: string;
13
12
  clientName: string;
@@ -1,11 +1,15 @@
1
- import { type BuildContextLike as BuildContextLike_prepareRealmConfig } from "./prepareRealmConfig";
2
1
  import { type BuildContextLike as BuildContextLike_dumpContainerConfig } from "./dumpContainerConfig";
3
- export type BuildContextLike = BuildContextLike_dumpContainerConfig & BuildContextLike_prepareRealmConfig & {
2
+ import type { ThemeType } from "../../shared/constants";
3
+ export type BuildContextLike = BuildContextLike_dumpContainerConfig & {
4
4
  projectDirPath: string;
5
5
  };
6
6
  export declare function getRealmConfig(params: {
7
7
  keycloakMajorVersionNumber: number;
8
8
  realmJsonFilePath_userProvided: string | undefined;
9
+ parsedKeycloakThemesJsonEntry: {
10
+ name: string;
11
+ types: (ThemeType | "email")[];
12
+ };
9
13
  buildContext: BuildContextLike;
10
14
  }): Promise<{
11
15
  realmJsonFilePath: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycloakify",
3
- "version": "11.7.4",
3
+ "version": "11.8.1",
4
4
  "description": "Framework to create custom Keycloak UIs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -681,15 +681,13 @@
681
681
  "src/bin/main.ts",
682
682
  "src/bin/own.ts",
683
683
  "src/bin/shared/KeycloakVersionRange.ts",
684
+ "src/bin/shared/addSyncExtensionsToPostinstallScript.ts",
684
685
  "src/bin/shared/buildContext.ts",
685
686
  "src/bin/shared/constants.ts",
686
687
  "src/bin/shared/customHandler.ts",
687
688
  "src/bin/shared/customHandler_delegate.ts",
688
689
  "src/bin/shared/exitIfUncommittedChanges.ts",
689
- "src/bin/shared/initializeSpa/addSyncExtensionsToPostinstallScript.ts",
690
- "src/bin/shared/initializeSpa/index.ts",
691
- "src/bin/shared/initializeSpa/initializeSpa.ts",
692
- "src/bin/shared/metaInfKeycloakThemes.ts",
690
+ "src/bin/shared/initializeSpa.ts",
693
691
  "src/bin/start-keycloak/appBuild.ts",
694
692
  "src/bin/start-keycloak/getSupportedDockerImageTags.ts",
695
693
  "src/bin/start-keycloak/index.ts",
@@ -1053,16 +1051,14 @@
1053
1051
  "bin/keycloakify/replacers/replaceImportsInJsCode/webpack.d.ts",
1054
1052
  "bin/main.d.ts",
1055
1053
  "bin/own.d.ts",
1054
+ "bin/shared/addSyncExtensionsToPostinstallScript.d.ts",
1056
1055
  "bin/shared/buildContext.d.ts",
1057
1056
  "bin/shared/constants.d.ts",
1058
1057
  "bin/shared/customHandler_delegate.d.ts",
1059
1058
  "bin/shared/customHandler.d.ts",
1060
1059
  "bin/shared/exitIfUncommittedChanges.d.ts",
1061
- "bin/shared/initializeSpa/addSyncExtensionsToPostinstallScript.d.ts",
1062
- "bin/shared/initializeSpa/index.d.ts",
1063
- "bin/shared/initializeSpa/initializeSpa.d.ts",
1060
+ "bin/shared/initializeSpa.d.ts",
1064
1061
  "bin/shared/KeycloakVersionRange.d.ts",
1065
- "bin/shared/metaInfKeycloakThemes.d.ts",
1066
1062
  "bin/start-keycloak/appBuild.d.ts",
1067
1063
  "bin/start-keycloak/getSupportedDockerImageTags.d.ts",
1068
1064
  "bin/start-keycloak/index.d.ts",
@@ -1117,28 +1113,27 @@
1117
1113
  "bin/tools/untrackFromGit.d.ts",
1118
1114
  "bin/update-kc-gen.d.ts",
1119
1115
  "bin/main.js",
1116
+ "bin/226.index.js",
1120
1117
  "bin/266.index.js",
1121
- "bin/288.index.js",
1118
+ "bin/297.index.js",
1122
1119
  "bin/304.index.js",
1123
- "bin/313.index.js",
1124
- "bin/33.index.js",
1125
1120
  "bin/355.index.js",
1126
1121
  "bin/363.index.js",
1122
+ "bin/369.index.js",
1127
1123
  "bin/40.index.js",
1128
1124
  "bin/453.index.js",
1125
+ "bin/502.index.js",
1126
+ "bin/656.index.js",
1129
1127
  "bin/658.index.js",
1130
- "bin/678.index.js",
1128
+ "bin/712.index.js",
1131
1129
  "bin/720.index.js",
1132
1130
  "bin/780.index.js",
1133
1131
  "bin/783.index.js",
1134
1132
  "bin/786.index.js",
1135
1133
  "bin/877.index.js",
1136
- "bin/880.index.js",
1137
- "bin/9.index.js",
1138
- "bin/911.index.js",
1139
1134
  "bin/930.index.js",
1135
+ "bin/932.index.js",
1140
1136
  "bin/946.index.js",
1141
- "bin/947.index.js",
1142
1137
  "bin/97.index.js",
1143
1138
  "bin/shared/constants.js",
1144
1139
  "bin/shared/constants.js.map",
@@ -23,22 +23,6 @@ export async function command(params: { buildContext: BuildContext }) {
23
23
 
24
24
  const accountThemeSrcDirPath = pathJoin(buildContext.themeSrcDirPath, "account");
25
25
 
26
- if (
27
- fs.existsSync(accountThemeSrcDirPath) &&
28
- fs.readdirSync(accountThemeSrcDirPath).length > 0
29
- ) {
30
- console.warn(
31
- chalk.red(
32
- `There is already a ${pathRelative(
33
- process.cwd(),
34
- accountThemeSrcDirPath
35
- )} directory in your project. Aborting.`
36
- )
37
- );
38
-
39
- process.exit(-1);
40
- }
41
-
42
26
  exitIfUncommittedChanges({
43
27
  projectDirPath: buildContext.projectDirPath
44
28
  });
@@ -51,17 +35,35 @@ export async function command(params: { buildContext: BuildContext }) {
51
35
 
52
36
  switch (accountThemeType) {
53
37
  case "Multi-Page":
54
- fs.cpSync(
55
- pathJoin(
56
- getThisCodebaseRootDirPath(),
57
- "src",
58
- "bin",
59
- "initialize-account-theme",
60
- "multi-page-boilerplate"
61
- ),
62
- accountThemeSrcDirPath,
63
- { recursive: true }
64
- );
38
+ {
39
+ if (
40
+ fs.existsSync(accountThemeSrcDirPath) &&
41
+ fs.readdirSync(accountThemeSrcDirPath).length > 0
42
+ ) {
43
+ console.warn(
44
+ chalk.red(
45
+ `There is already a ${pathRelative(
46
+ process.cwd(),
47
+ accountThemeSrcDirPath
48
+ )} directory in your project. Aborting.`
49
+ )
50
+ );
51
+
52
+ process.exit(-1);
53
+ }
54
+
55
+ fs.cpSync(
56
+ pathJoin(
57
+ getThisCodebaseRootDirPath(),
58
+ "src",
59
+ "bin",
60
+ "initialize-account-theme",
61
+ "multi-page-boilerplate"
62
+ ),
63
+ accountThemeSrcDirPath,
64
+ { recursive: true }
65
+ );
66
+ }
65
67
  break;
66
68
  case "Single-Page":
67
69
  {
@@ -1,17 +1,24 @@
1
- import { join as pathJoin, relative as pathRelative } from "path";
2
- import { transformCodebase } from "./tools/transformCodebase";
3
1
  import type { BuildContext } from "./shared/buildContext";
4
- import * as fs from "fs";
5
- import { downloadAndExtractArchive } from "./tools/downloadAndExtractArchive";
2
+ import cliSelect from "cli-select";
6
3
  import { maybeDelegateCommandToCustomHandler } from "./shared/customHandler_delegate";
7
- import { assert } from "tsafe/assert";
8
- import { getSupportedDockerImageTags } from "./start-keycloak/getSupportedDockerImageTags";
4
+ import { exitIfUncommittedChanges } from "./shared/exitIfUncommittedChanges";
5
+
6
+ import { dirname as pathDirname, join as pathJoin, relative as pathRelative } from "path";
7
+ import * as fs from "fs";
8
+ import { assert, is, type Equals } from "tsafe/assert";
9
+ import { id } from "tsafe/id";
10
+ import { addSyncExtensionsToPostinstallScript } from "./shared/addSyncExtensionsToPostinstallScript";
11
+ import { getIsPrettierAvailable, runPrettier } from "./tools/runPrettier";
12
+ import { npmInstall } from "./tools/npmInstall";
13
+ import * as child_process from "child_process";
14
+ import { z } from "zod";
15
+ import chalk from "chalk";
9
16
 
10
17
  export async function command(params: { buildContext: BuildContext }) {
11
18
  const { buildContext } = params;
12
19
 
13
20
  const { hasBeenHandled } = maybeDelegateCommandToCustomHandler({
14
- commandName: "initialize-email-theme",
21
+ commandName: "initialize-account-theme",
15
22
  buildContext
16
23
  });
17
24
 
@@ -19,6 +26,10 @@ export async function command(params: { buildContext: BuildContext }) {
19
26
  return;
20
27
  }
21
28
 
29
+ exitIfUncommittedChanges({
30
+ projectDirPath: buildContext.projectDirPath
31
+ });
32
+
22
33
  const emailThemeSrcDirPath = pathJoin(buildContext.themeSrcDirPath, "email");
23
34
 
24
35
  if (
@@ -26,71 +37,110 @@ export async function command(params: { buildContext: BuildContext }) {
26
37
  fs.readdirSync(emailThemeSrcDirPath).length > 0
27
38
  ) {
28
39
  console.warn(
29
- `There is already a non empty ${pathRelative(
30
- process.cwd(),
31
- emailThemeSrcDirPath
32
- )} directory in your project. Aborting.`
40
+ chalk.red(
41
+ `There is already a ${pathRelative(
42
+ process.cwd(),
43
+ emailThemeSrcDirPath
44
+ )} directory in your project. Aborting.`
45
+ )
33
46
  );
34
47
 
35
48
  process.exit(-1);
36
49
  }
37
50
 
38
- console.log("Initialize with the base email theme from which version of Keycloak?");
51
+ const { value: emailThemeType } = await cliSelect({
52
+ values: ["native (FreeMarker)" as const, "jsx-email (React)" as const]
53
+ }).catch(() => {
54
+ process.exit(-1);
55
+ });
39
56
 
40
- const { extractedDirPath } = await downloadAndExtractArchive({
41
- url: await (async () => {
42
- const { latestMajorTags } = await getSupportedDockerImageTags({
43
- buildContext
57
+ if (emailThemeType === "jsx-email (React)") {
58
+ console.log(
59
+ [
60
+ "There is currently no automated support for keycloakify-email, it has to be done manually, see documentation:",
61
+ "https://docs.keycloakify.dev/theme-types/email-theme"
62
+ ].join("\n")
63
+ );
64
+
65
+ process.exit(0);
66
+ }
67
+
68
+ const parsedPackageJson = (() => {
69
+ type ParsedPackageJson = {
70
+ scripts?: Record<string, string | undefined>;
71
+ dependencies?: Record<string, string | undefined>;
72
+ devDependencies?: Record<string, string | undefined>;
73
+ };
74
+
75
+ const zParsedPackageJson = (() => {
76
+ type TargetType = ParsedPackageJson;
77
+
78
+ const zTargetType = z.object({
79
+ scripts: z.record(z.union([z.string(), z.undefined()])).optional(),
80
+ dependencies: z.record(z.union([z.string(), z.undefined()])).optional(),
81
+ devDependencies: z.record(z.union([z.string(), z.undefined()])).optional()
44
82
  });
45
83
 
46
- const keycloakVersion = latestMajorTags[0];
84
+ assert<Equals<z.infer<typeof zTargetType>, TargetType>>;
85
+
86
+ return id<z.ZodType<TargetType>>(zTargetType);
87
+ })();
88
+ const parsedPackageJson = JSON.parse(
89
+ fs.readFileSync(buildContext.packageJsonFilePath).toString("utf8")
90
+ );
47
91
 
48
- assert(keycloakVersion !== undefined);
92
+ zParsedPackageJson.parse(parsedPackageJson);
49
93
 
50
- return `https://repo1.maven.org/maven2/org/keycloak/keycloak-themes/${keycloakVersion}/keycloak-themes-${keycloakVersion}.jar`;
51
- })(),
52
- cacheDirPath: buildContext.cacheDirPath,
53
- fetchOptions: buildContext.fetchOptions,
54
- uniqueIdOfOnArchiveFile: "extractOnlyEmailTheme",
55
- onArchiveFile: async ({ fileRelativePath, writeFile }) => {
56
- const fileRelativePath_target = pathRelative(
57
- pathJoin("theme", "base", "email"),
58
- fileRelativePath
59
- );
94
+ assert(is<ParsedPackageJson>(parsedPackageJson));
60
95
 
61
- if (fileRelativePath_target.startsWith("..")) {
62
- return;
63
- }
96
+ return parsedPackageJson;
97
+ })();
64
98
 
65
- await writeFile({ fileRelativePath: fileRelativePath_target });
66
- }
99
+ addSyncExtensionsToPostinstallScript({
100
+ parsedPackageJson,
101
+ buildContext
67
102
  });
68
103
 
69
- transformCodebase({
70
- srcDirPath: extractedDirPath,
71
- destDirPath: emailThemeSrcDirPath
72
- });
104
+ const moduleName = `@keycloakify/email-native`;
105
+
106
+ const [version] = (
107
+ JSON.parse(
108
+ child_process
109
+ .execSync(`npm show ${moduleName} versions --json`)
110
+ .toString("utf8")
111
+ .trim()
112
+ ) as string[]
113
+ )
114
+ .reverse()
115
+ .filter(version => !version.includes("-"));
116
+
117
+ assert(version !== undefined);
118
+
119
+ (parsedPackageJson.dependencies ??= {})[moduleName] = `~${version}`;
120
+
121
+ if (parsedPackageJson.devDependencies !== undefined) {
122
+ delete parsedPackageJson.devDependencies[moduleName];
123
+ }
73
124
 
74
125
  {
75
- const themePropertyFilePath = pathJoin(emailThemeSrcDirPath, "theme.properties");
126
+ let sourceCode = JSON.stringify(parsedPackageJson, undefined, 2);
127
+
128
+ if (await getIsPrettierAvailable()) {
129
+ sourceCode = await runPrettier({
130
+ sourceCode,
131
+ filePath: buildContext.packageJsonFilePath
132
+ });
133
+ }
76
134
 
77
135
  fs.writeFileSync(
78
- themePropertyFilePath,
79
- Buffer.from(
80
- [
81
- `parent=base`,
82
- fs.readFileSync(themePropertyFilePath).toString("utf8")
83
- ].join("\n"),
84
- "utf8"
85
- )
136
+ buildContext.packageJsonFilePath,
137
+ Buffer.from(sourceCode, "utf8")
86
138
  );
87
139
  }
88
140
 
89
- console.log(
90
- `The \`${pathJoin(
91
- ".",
92
- pathRelative(process.cwd(), emailThemeSrcDirPath)
93
- )}\` directory have been created.`
94
- );
95
- console.log("You can delete any file you don't modify.");
141
+ await npmInstall({
142
+ packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath)
143
+ });
144
+
145
+ console.log(chalk.green("Email theme initialized."));
96
146
  }