keycloakify 6.0.3 → 6.1.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 (39) hide show
  1. package/README.md +8 -1
  2. package/bin/create-keycloak-email-directory.js +9 -4
  3. package/bin/create-keycloak-email-directory.js.map +1 -1
  4. package/bin/download-builtin-keycloak-theme.d.ts +1 -0
  5. package/bin/download-builtin-keycloak-theme.js +13 -6
  6. package/bin/download-builtin-keycloak-theme.js.map +1 -1
  7. package/bin/generate-i18n-messages.js +8 -3
  8. package/bin/generate-i18n-messages.js.map +1 -1
  9. package/bin/keycloakify/BuildOptions.d.ts +2 -0
  10. package/bin/keycloakify/BuildOptions.js +3 -2
  11. package/bin/keycloakify/BuildOptions.js.map +1 -1
  12. package/bin/keycloakify/generateKeycloakThemeResources.d.ts +1 -0
  13. package/bin/keycloakify/generateKeycloakThemeResources.js +5 -2
  14. package/bin/keycloakify/generateKeycloakThemeResources.js.map +1 -1
  15. package/bin/keycloakify/keycloakify.js +8 -4
  16. package/bin/keycloakify/keycloakify.js.map +1 -1
  17. package/bin/tools/cliOptions.d.ts +5 -0
  18. package/bin/tools/cliOptions.js +16 -0
  19. package/bin/tools/cliOptions.js.map +1 -0
  20. package/bin/tools/downloadAndUnzip.d.ts +1 -0
  21. package/bin/tools/downloadAndUnzip.js +1 -1
  22. package/bin/tools/downloadAndUnzip.js.map +1 -1
  23. package/bin/tools/logger.d.ts +12 -0
  24. package/bin/tools/logger.js +23 -0
  25. package/bin/tools/logger.js.map +1 -0
  26. package/bin/tsconfig.tsbuildinfo +1 -1
  27. package/lib/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +12 -2
  29. package/src/bin/create-keycloak-email-directory.ts +8 -3
  30. package/src/bin/download-builtin-keycloak-theme.ts +11 -5
  31. package/src/bin/generate-i18n-messages.ts +9 -3
  32. package/src/bin/keycloakify/BuildOptions.ts +5 -2
  33. package/src/bin/keycloakify/generateKeycloakThemeResources.ts +6 -2
  34. package/src/bin/keycloakify/keycloakify.ts +8 -3
  35. package/src/bin/tools/cliOptions.ts +15 -0
  36. package/src/bin/tools/downloadAndUnzip.ts +8 -2
  37. package/src/bin/tools/logger.ts +27 -0
  38. package/src/test/bin/generateKeycloakThemeResources.ts +2 -1
  39. package/src/test/bin/setupSampleReactProject.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycloakify",
3
- "version": "6.0.3",
3
+ "version": "6.1.0",
4
4
  "description": "Keycloak theme generator for Reacts app",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,11 +46,13 @@
46
46
  "src/bin/mockTestingResourcesPath.ts",
47
47
  "src/bin/promptKeycloakVersion.ts",
48
48
  "src/bin/tools/NpmModuleVersion.ts",
49
+ "src/bin/tools/cliOptions.ts",
49
50
  "src/bin/tools/crawl.ts",
50
51
  "src/bin/tools/downloadAndUnzip.ts",
51
52
  "src/bin/tools/getProjectRoot.ts",
52
53
  "src/bin/tools/grant-exec-perms.ts",
53
54
  "src/bin/tools/isInside.ts",
55
+ "src/bin/tools/logger.ts",
54
56
  "src/bin/tools/octokit-addons/getLatestsSemVersionedTag.ts",
55
57
  "src/bin/tools/octokit-addons/listTags.ts",
56
58
  "src/bin/tools/pathJoin.ts",
@@ -391,6 +393,9 @@
391
393
  "bin/tools/NpmModuleVersion.d.ts",
392
394
  "bin/tools/NpmModuleVersion.js",
393
395
  "bin/tools/NpmModuleVersion.js.map",
396
+ "bin/tools/cliOptions.d.ts",
397
+ "bin/tools/cliOptions.js",
398
+ "bin/tools/cliOptions.js.map",
394
399
  "bin/tools/crawl.d.ts",
395
400
  "bin/tools/crawl.js",
396
401
  "bin/tools/crawl.js.map",
@@ -406,6 +411,9 @@
406
411
  "bin/tools/isInside.d.ts",
407
412
  "bin/tools/isInside.js",
408
413
  "bin/tools/isInside.js.map",
414
+ "bin/tools/logger.d.ts",
415
+ "bin/tools/logger.js",
416
+ "bin/tools/logger.js.map",
409
417
  "bin/tools/octokit-addons/getLatestsSemVersionedTag.d.ts",
410
418
  "bin/tools/octokit-addons/getLatestsSemVersionedTag.js",
411
419
  "bin/tools/octokit-addons/getLatestsSemVersionedTag.js.map",
@@ -1237,6 +1245,7 @@
1237
1245
  "devDependencies": {
1238
1246
  "@emotion/react": "^11.4.1",
1239
1247
  "@types/memoizee": "^0.4.7",
1248
+ "@types/minimist": "^1.2.2",
1240
1249
  "@types/node": "^17.0.25",
1241
1250
  "@types/react": "18.0.9",
1242
1251
  "copyfiles": "^2.4.1",
@@ -1255,12 +1264,13 @@
1255
1264
  "evt": "^2.4.0",
1256
1265
  "memoizee": "^0.4.15",
1257
1266
  "minimal-polyfills": "^2.2.2",
1267
+ "minimist": "^1.2.6",
1258
1268
  "path-browserify": "^1.0.1",
1259
1269
  "powerhooks": "^0.20.15",
1260
1270
  "react-markdown": "^5.0.3",
1261
1271
  "scripting-tools": "^0.19.13",
1262
1272
  "tsafe": "^1.0.1",
1263
- "tss-react": "^4.1.1",
1273
+ "tss-react": "^4.1.3",
1264
1274
  "zod": "^3.17.10"
1265
1275
  }
1266
1276
  }
@@ -6,11 +6,15 @@ import { join as pathJoin, basename as pathBasename } from "path";
6
6
  import { transformCodebase } from "./tools/transformCodebase";
7
7
  import { promptKeycloakVersion } from "./promptKeycloakVersion";
8
8
  import * as fs from "fs";
9
+ import { getCliOptions } from "./tools/cliOptions";
10
+ import { getLogger } from "./tools/logger";
9
11
 
10
12
  if (require.main === module) {
11
13
  (async () => {
14
+ const { isSilent } = getCliOptions(process.argv.slice(2));
15
+ const logger = getLogger({ isSilent });
12
16
  if (fs.existsSync(keycloakThemeEmailDirPath)) {
13
- console.log(`There is already a ./${pathBasename(keycloakThemeEmailDirPath)} directory in your project. Aborting.`);
17
+ logger.warn(`There is already a ./${pathBasename(keycloakThemeEmailDirPath)} directory in your project. Aborting.`);
14
18
 
15
19
  process.exit(-1);
16
20
  }
@@ -21,7 +25,8 @@ if (require.main === module) {
21
25
 
22
26
  downloadBuiltinKeycloakTheme({
23
27
  keycloakVersion,
24
- "destDirPath": builtinKeycloakThemeTmpDirPath
28
+ "destDirPath": builtinKeycloakThemeTmpDirPath,
29
+ isSilent
25
30
  });
26
31
 
27
32
  transformCodebase({
@@ -29,7 +34,7 @@ if (require.main === module) {
29
34
  "destDirPath": keycloakThemeEmailDirPath
30
35
  });
31
36
 
32
- console.log(`./${pathBasename(keycloakThemeEmailDirPath)} ready to be customized`);
37
+ logger.log(`./${pathBasename(keycloakThemeEmailDirPath)} ready to be customized`);
33
38
 
34
39
  fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
35
40
  })();
@@ -4,31 +4,37 @@ import { keycloakThemeBuildingDirPath } from "./keycloakify";
4
4
  import { join as pathJoin } from "path";
5
5
  import { downloadAndUnzip } from "./tools/downloadAndUnzip";
6
6
  import { promptKeycloakVersion } from "./promptKeycloakVersion";
7
+ import { getCliOptions } from "./tools/cliOptions";
8
+ import { getLogger } from "./tools/logger";
7
9
 
8
- export function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string }) {
9
- const { keycloakVersion, destDirPath } = params;
10
+ export function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string; isSilent: boolean }) {
11
+ const { keycloakVersion, destDirPath, isSilent } = params;
10
12
 
11
13
  for (const ext of ["", "-community"]) {
12
14
  downloadAndUnzip({
13
15
  "destDirPath": destDirPath,
14
16
  "url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`,
15
17
  "pathOfDirToExtractInArchive": `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`,
16
- "cacheDirPath": pathJoin(keycloakThemeBuildingDirPath, ".cache")
18
+ "cacheDirPath": pathJoin(keycloakThemeBuildingDirPath, ".cache"),
19
+ isSilent
17
20
  });
18
21
  }
19
22
  }
20
23
 
21
24
  if (require.main === module) {
22
25
  (async () => {
26
+ const { isSilent } = getCliOptions(process.argv.slice(2));
27
+ const logger = getLogger({ isSilent });
23
28
  const { keycloakVersion } = await promptKeycloakVersion();
24
29
 
25
30
  const destDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme");
26
31
 
27
- console.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
32
+ logger.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
28
33
 
29
34
  downloadBuiltinKeycloakTheme({
30
35
  keycloakVersion,
31
- destDirPath
36
+ destDirPath,
37
+ isSilent
32
38
  });
33
39
  })();
34
40
  }
@@ -5,6 +5,8 @@ import { crawl } from "./tools/crawl";
5
5
  import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme";
6
6
  import { getProjectRoot } from "./tools/getProjectRoot";
7
7
  import { rm_rf, rm_r } from "./tools/rm";
8
+ import { getCliOptions } from "./tools/cliOptions";
9
+ import { getLogger } from "./tools/logger";
8
10
 
9
11
  //NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files,
10
12
  // update the version array for generating for newer version.
@@ -12,8 +14,11 @@ import { rm_rf, rm_r } from "./tools/rm";
12
14
  //@ts-ignore
13
15
  const propertiesParser = require("properties-parser");
14
16
 
17
+ const { isSilent } = getCliOptions(process.argv.slice(2));
18
+ const logger = getLogger({ isSilent });
19
+
15
20
  for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
16
- console.log({ keycloakVersion });
21
+ logger.log(JSON.stringify({ keycloakVersion }));
17
22
 
18
23
  const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44");
19
24
 
@@ -21,7 +26,8 @@ for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
21
26
 
22
27
  downloadBuiltinKeycloakTheme({
23
28
  keycloakVersion,
24
- "destDirPath": tmpDirPath
29
+ "destDirPath": tmpDirPath,
30
+ isSilent
25
31
  });
26
32
 
27
33
  type Dictionary = { [idiomId: string]: string };
@@ -75,7 +81,7 @@ for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
75
81
  )
76
82
  );
77
83
 
78
- console.log(`${filePath} wrote`);
84
+ logger.log(`${filePath} wrote`);
79
85
  });
80
86
  });
81
87
  }
@@ -35,6 +35,7 @@ export type BuildOptions = BuildOptions.Standalone | BuildOptions.ExternalAssets
35
35
 
36
36
  export namespace BuildOptions {
37
37
  export type Common = {
38
+ isSilent: boolean;
38
39
  version: string;
39
40
  themeName: string;
40
41
  extraPages?: string[];
@@ -71,8 +72,9 @@ export function readBuildOptions(params: {
71
72
  packageJson: string;
72
73
  CNAME: string | undefined;
73
74
  isExternalAssetsCliParamProvided: boolean;
75
+ isSilent: boolean;
74
76
  }): BuildOptions {
75
- const { packageJson, CNAME, isExternalAssetsCliParamProvided } = params;
77
+ const { packageJson, CNAME, isExternalAssetsCliParamProvided, isSilent } = params;
76
78
 
77
79
  const parsedPackageJson = zParsedPackageJson.parse(JSON.parse(packageJson));
78
80
 
@@ -130,7 +132,8 @@ export function readBuildOptions(params: {
130
132
  })(),
131
133
  "version": version,
132
134
  extraPages,
133
- extraThemeProperties
135
+ extraThemeProperties,
136
+ isSilent
134
137
  };
135
138
  })();
136
139
 
@@ -11,6 +11,7 @@ import { isInside } from "../tools/isInside";
11
11
  import type { BuildOptions } from "./BuildOptions";
12
12
  import { assert } from "tsafe/assert";
13
13
  import { Reflect } from "tsafe/Reflect";
14
+ import { getLogger } from "../tools/logger";
14
15
 
15
16
  export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.ExternalAssets;
16
17
 
@@ -19,6 +20,7 @@ export namespace BuildOptionsLike {
19
20
  themeName: string;
20
21
  extraPages?: string[];
21
22
  extraThemeProperties?: string[];
23
+ isSilent: boolean;
22
24
  };
23
25
 
24
26
  export type Standalone = Common & {
@@ -60,6 +62,7 @@ export function generateKeycloakThemeResources(params: {
60
62
  }): { doBundlesEmailTemplate: boolean } {
61
63
  const { reactAppBuildDirPath, keycloakThemeBuildingDirPath, keycloakThemeEmailDirPath, keycloakVersion, buildOptions } = params;
62
64
 
65
+ const logger = getLogger({ isSilent: buildOptions.isSilent });
63
66
  const themeDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", buildOptions.themeName, "login");
64
67
 
65
68
  let allCssGlobalsToDefine: Record<string, string> = {};
@@ -117,7 +120,7 @@ export function generateKeycloakThemeResources(params: {
117
120
 
118
121
  email: {
119
122
  if (!fs.existsSync(keycloakThemeEmailDirPath)) {
120
- console.log(
123
+ logger.log(
121
124
  [
122
125
  `Not bundling email template because ${pathBasename(keycloakThemeEmailDirPath)} does not exist`,
123
126
  `To start customizing the email template, run: 👉 npx create-keycloak-email-directory 👈`
@@ -154,7 +157,8 @@ export function generateKeycloakThemeResources(params: {
154
157
 
155
158
  downloadBuiltinKeycloakTheme({
156
159
  keycloakVersion,
157
- "destDirPath": tmpDirPath
160
+ "destDirPath": tmpDirPath,
161
+ isSilent: buildOptions.isSilent
158
162
  });
159
163
 
160
164
  const themeResourcesDirPath = pathJoin(themeDirPath, "resources");
@@ -5,6 +5,8 @@ import * as child_process from "child_process";
5
5
  import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
6
6
  import * as fs from "fs";
7
7
  import { readBuildOptions } from "./BuildOptions";
8
+ import { getLogger } from "../tools/logger";
9
+ import { getCliOptions } from "../tools/cliOptions";
8
10
 
9
11
  const reactProjectDirPath = process.cwd();
10
12
 
@@ -12,7 +14,9 @@ export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build
12
14
  export const keycloakThemeEmailDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "keycloak_email");
13
15
 
14
16
  export function main() {
15
- console.log("🔏 Building the keycloak theme...⌚");
17
+ const { isSilent, hasExternalAssets } = getCliOptions(process.argv.slice(2));
18
+ const logger = getLogger({ isSilent });
19
+ logger.log("🔏 Building the keycloak theme...⌚");
16
20
 
17
21
  const buildOptions = readBuildOptions({
18
22
  "packageJson": fs.readFileSync(pathJoin(reactProjectDirPath, "package.json")).toString("utf8"),
@@ -25,7 +29,8 @@ export function main() {
25
29
 
26
30
  return fs.readFileSync(cnameFilePath).toString("utf8");
27
31
  })(),
28
- "isExternalAssetsCliParamProvided": process.argv[2]?.toLowerCase() === "--external-assets"
32
+ "isExternalAssetsCliParamProvided": hasExternalAssets,
33
+ "isSilent": isSilent
29
34
  });
30
35
 
31
36
  const { doBundlesEmailTemplate } = generateKeycloakThemeResources({
@@ -59,7 +64,7 @@ export function main() {
59
64
  buildOptions
60
65
  });
61
66
 
62
- console.log(
67
+ logger.log(
63
68
  [
64
69
  "",
65
70
  `✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
@@ -0,0 +1,15 @@
1
+ import parseArgv from "minimist";
2
+
3
+ export type CliOptions = {
4
+ isSilent: boolean;
5
+ hasExternalAssets: boolean;
6
+ };
7
+
8
+ export const getCliOptions = (processArgv: string[]): CliOptions => {
9
+ const argv = parseArgv(processArgv);
10
+
11
+ return {
12
+ isSilent: typeof argv["silent"] === "boolean" ? argv["silent"] : false,
13
+ hasExternalAssets: typeof argv["external-assets"] === "boolean" ? argv["external-assets"] : false
14
+ };
15
+ };
@@ -6,7 +6,13 @@ import { rm, rm_rf } from "./rm";
6
6
  import * as crypto from "crypto";
7
7
 
8
8
  /** assert url ends with .zip */
9
- export function downloadAndUnzip(params: { url: string; destDirPath: string; pathOfDirToExtractInArchive?: string; cacheDirPath: string }) {
9
+ export function downloadAndUnzip(params: {
10
+ isSilent: boolean;
11
+ url: string;
12
+ destDirPath: string;
13
+ pathOfDirToExtractInArchive?: string;
14
+ cacheDirPath: string;
15
+ }) {
10
16
  const { url, destDirPath, pathOfDirToExtractInArchive, cacheDirPath } = params;
11
17
 
12
18
  const extractDirPath = pathJoin(
@@ -54,7 +60,7 @@ export function downloadAndUnzip(params: { url: string; destDirPath: string; pat
54
60
 
55
61
  const zipFileBasename = pathBasename(url);
56
62
 
57
- execSync(`curl -L ${url} -o ${zipFileBasename}`, { "cwd": extractDirPath });
63
+ execSync(`curl -L ${url} -o ${zipFileBasename} ${params.isSilent ? "-s" : ""}`, { "cwd": extractDirPath });
58
64
 
59
65
  execSync(`unzip -o ${zipFileBasename}${pathOfDirToExtractInArchive === undefined ? "" : ` "${pathOfDirToExtractInArchive}/**/*"`}`, {
60
66
  "cwd": extractDirPath
@@ -0,0 +1,27 @@
1
+ type LoggerOpts = {
2
+ force?: boolean;
3
+ };
4
+
5
+ type Logger = {
6
+ log: (message: string, opts?: LoggerOpts) => void;
7
+ warn: (message: string) => void;
8
+ error: (message: string) => void;
9
+ };
10
+
11
+ export const getLogger = ({ isSilent }: { isSilent?: boolean } = {}): Logger => {
12
+ return {
13
+ log: (message, { force } = {}) => {
14
+ if (isSilent && !force) {
15
+ return;
16
+ }
17
+
18
+ console.log(message);
19
+ },
20
+ warn: message => {
21
+ console.warn(message);
22
+ },
23
+ error: message => {
24
+ console.error(message);
25
+ }
26
+ };
27
+ };
@@ -14,6 +14,7 @@ generateKeycloakThemeResources({
14
14
  "extraPages": ["my-custom-page.ftl"],
15
15
  "extraThemeProperties": ["env=test"],
16
16
  "isStandalone": true,
17
- "urlPathname": "/keycloakify-demo-app/"
17
+ "urlPathname": "/keycloakify-demo-app/",
18
+ "isSilent": false
18
19
  }
19
20
  });
@@ -8,6 +8,7 @@ export function setupSampleReactProject() {
8
8
  downloadAndUnzip({
9
9
  "url": "https://github.com/InseeFrLab/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip",
10
10
  "destDirPath": sampleReactProjectDirPath,
11
- "cacheDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak", ".cache")
11
+ "cacheDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak", ".cache"),
12
+ "isSilent": false
12
13
  });
13
14
  }