keycloakify 7.7.1 → 7.9.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/account/kcContext/createGetKcContext.js +3 -6
- package/account/kcContext/createGetKcContext.js.map +1 -1
- package/account/kcContext/kcContextMocks.js +3 -3
- package/account/kcContext/kcContextMocks.js.map +1 -1
- package/bin/copy-keycloak-resources-to-public.d.ts +2 -0
- package/bin/copy-keycloak-resources-to-public.js +140 -0
- package/bin/copy-keycloak-resources-to-public.js.map +1 -0
- package/bin/download-builtin-keycloak-theme.js +8 -10
- package/bin/download-builtin-keycloak-theme.js.map +1 -1
- package/bin/initialize-email-theme.js +5 -2
- package/bin/initialize-email-theme.js.map +1 -1
- package/bin/keycloakify/BuildOptions.d.ts +1 -2
- package/bin/keycloakify/BuildOptions.js +13 -2
- package/bin/keycloakify/BuildOptions.js.map +1 -1
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts +7 -0
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js +101 -0
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map +1 -0
- package/bin/keycloakify/{generateKeycloakThemeResources.d.ts → generateTheme/generateTheme.d.ts} +2 -2
- package/bin/keycloakify/{generateKeycloakThemeResources.js → generateTheme/generateTheme.js} +20 -38
- package/bin/keycloakify/generateTheme/generateTheme.js.map +1 -0
- package/bin/keycloakify/generateTheme/index.d.ts +1 -0
- package/bin/keycloakify/generateTheme/index.js +18 -0
- package/bin/keycloakify/generateTheme/index.js.map +1 -0
- package/bin/keycloakify/keycloakify.js +13 -17
- package/bin/keycloakify/keycloakify.js.map +1 -1
- package/bin/keycloakify/parsedPackageJson.d.ts +5 -5
- package/bin/mockTestingResourcesPath.d.ts +3 -3
- package/bin/mockTestingResourcesPath.js +4 -4
- package/bin/mockTestingResourcesPath.js.map +1 -1
- package/bin/tools/grant-exec-perms.js +2 -1
- package/bin/tools/grant-exec-perms.js.map +1 -1
- package/bin/tools/walk.js +1 -1
- package/lib/usePrepareTemplate.js +27 -15
- package/lib/usePrepareTemplate.js.map +1 -1
- package/login/kcContext/createGetKcContext.js +3 -6
- package/login/kcContext/createGetKcContext.js.map +1 -1
- package/login/kcContext/kcContextMocks.js +3 -3
- package/login/kcContext/kcContextMocks.js.map +1 -1
- package/login/pages/LoginOtp.js +8 -4
- package/login/pages/LoginOtp.js.map +1 -1
- package/package.json +20 -11
- package/src/account/kcContext/createGetKcContext.ts +3 -9
- package/src/account/kcContext/kcContextMocks.ts +3 -3
- package/src/bin/copy-keycloak-resources-to-public.ts +48 -0
- package/src/bin/download-builtin-keycloak-theme.ts +8 -15
- package/src/bin/initialize-email-theme.ts +6 -2
- package/src/bin/keycloakify/BuildOptions.ts +13 -3
- package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +47 -0
- package/src/bin/keycloakify/{generateKeycloakThemeResources.ts → generateTheme/generateTheme.ts} +19 -55
- package/src/bin/keycloakify/generateTheme/index.ts +1 -0
- package/src/bin/keycloakify/keycloakify.ts +6 -10
- package/src/bin/mockTestingResourcesPath.ts +3 -3
- package/src/lib/usePrepareTemplate.ts +29 -16
- package/src/login/kcContext/createGetKcContext.ts +3 -9
- package/src/login/kcContext/kcContextMocks.ts +3 -3
- package/src/login/pages/LoginOtp.tsx +11 -4
- package/src/tools/headInsert.ts +5 -2
- package/tools/headInsert.d.ts +4 -1
- package/tools/headInsert.js +4 -1
- package/tools/headInsert.js.map +1 -1
- package/bin/keycloakify/generateKeycloakThemeResources.js.map +0 -1
- package/bin/tools/cliOptions.d.ts +0 -5
- package/bin/tools/cliOptions.js +0 -16
- package/bin/tools/cliOptions.js.map +0 -1
- package/src/bin/tools/cliOptions.ts +0 -15
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "keycloakify",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.9.0-rc.0",
|
4
4
|
"description": "Create Keycloak themes using React",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -10,6 +10,7 @@
|
|
10
10
|
"types": "index.d.ts",
|
11
11
|
"bin": {
|
12
12
|
"keycloakify": "bin/keycloakify/index.js",
|
13
|
+
"copy-keycloak-resources-to-public": "bin/copy-keycloak-resources-to-public.js",
|
13
14
|
"initialize-email-theme": "bin/initialize-email-theme.js",
|
14
15
|
"download-builtin-keycloak-theme": "bin/download-builtin-keycloak-theme.js",
|
15
16
|
"eject-keycloak-page": "bin/eject-keycloak-page.js"
|
@@ -67,6 +68,7 @@
|
|
67
68
|
"src/account/pages/Account.tsx",
|
68
69
|
"src/account/pages/PageProps.ts",
|
69
70
|
"src/account/pages/Password.tsx",
|
71
|
+
"src/bin/copy-keycloak-resources-to-public.ts",
|
70
72
|
"src/bin/download-builtin-keycloak-theme.ts",
|
71
73
|
"src/bin/eject-keycloak-page.ts",
|
72
74
|
"src/bin/getSrcDirPath.ts",
|
@@ -78,8 +80,10 @@
|
|
78
80
|
"src/bin/keycloakify/generateFtl/index.ts",
|
79
81
|
"src/bin/keycloakify/generateFtl/pageId.ts",
|
80
82
|
"src/bin/keycloakify/generateJavaStackFiles.ts",
|
81
|
-
"src/bin/keycloakify/generateKeycloakThemeResources.ts",
|
82
83
|
"src/bin/keycloakify/generateStartKeycloakTestingContainer.ts",
|
84
|
+
"src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts",
|
85
|
+
"src/bin/keycloakify/generateTheme/generateTheme.ts",
|
86
|
+
"src/bin/keycloakify/generateTheme/index.ts",
|
83
87
|
"src/bin/keycloakify/index.ts",
|
84
88
|
"src/bin/keycloakify/keycloakify.ts",
|
85
89
|
"src/bin/keycloakify/parsedPackageJson.ts",
|
@@ -89,7 +93,6 @@
|
|
89
93
|
"src/bin/mockTestingResourcesPath.ts",
|
90
94
|
"src/bin/promptKeycloakVersion.ts",
|
91
95
|
"src/bin/tools/NpmModuleVersion.ts",
|
92
|
-
"src/bin/tools/cliOptions.ts",
|
93
96
|
"src/bin/tools/crawl.ts",
|
94
97
|
"src/bin/tools/crc32.ts",
|
95
98
|
"src/bin/tools/deflate.ts",
|
@@ -314,6 +317,9 @@
|
|
314
317
|
"account/pages/Password.d.ts",
|
315
318
|
"account/pages/Password.js",
|
316
319
|
"account/pages/Password.js.map",
|
320
|
+
"bin/copy-keycloak-resources-to-public.d.ts",
|
321
|
+
"bin/copy-keycloak-resources-to-public.js",
|
322
|
+
"bin/copy-keycloak-resources-to-public.js.map",
|
317
323
|
"bin/download-builtin-keycloak-theme.d.ts",
|
318
324
|
"bin/download-builtin-keycloak-theme.js",
|
319
325
|
"bin/download-builtin-keycloak-theme.js.map",
|
@@ -345,12 +351,18 @@
|
|
345
351
|
"bin/keycloakify/generateJavaStackFiles.d.ts",
|
346
352
|
"bin/keycloakify/generateJavaStackFiles.js",
|
347
353
|
"bin/keycloakify/generateJavaStackFiles.js.map",
|
348
|
-
"bin/keycloakify/generateKeycloakThemeResources.d.ts",
|
349
|
-
"bin/keycloakify/generateKeycloakThemeResources.js",
|
350
|
-
"bin/keycloakify/generateKeycloakThemeResources.js.map",
|
351
354
|
"bin/keycloakify/generateStartKeycloakTestingContainer.d.ts",
|
352
355
|
"bin/keycloakify/generateStartKeycloakTestingContainer.js",
|
353
356
|
"bin/keycloakify/generateStartKeycloakTestingContainer.js.map",
|
357
|
+
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts",
|
358
|
+
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js",
|
359
|
+
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map",
|
360
|
+
"bin/keycloakify/generateTheme/generateTheme.d.ts",
|
361
|
+
"bin/keycloakify/generateTheme/generateTheme.js",
|
362
|
+
"bin/keycloakify/generateTheme/generateTheme.js.map",
|
363
|
+
"bin/keycloakify/generateTheme/index.d.ts",
|
364
|
+
"bin/keycloakify/generateTheme/index.js",
|
365
|
+
"bin/keycloakify/generateTheme/index.js.map",
|
354
366
|
"bin/keycloakify/index.d.ts",
|
355
367
|
"bin/keycloakify/index.js",
|
356
368
|
"bin/keycloakify/index.js.map",
|
@@ -378,9 +390,6 @@
|
|
378
390
|
"bin/tools/NpmModuleVersion.d.ts",
|
379
391
|
"bin/tools/NpmModuleVersion.js",
|
380
392
|
"bin/tools/NpmModuleVersion.js.map",
|
381
|
-
"bin/tools/cliOptions.d.ts",
|
382
|
-
"bin/tools/cliOptions.js",
|
383
|
-
"bin/tools/cliOptions.js.map",
|
384
393
|
"bin/tools/crawl.d.ts",
|
385
394
|
"bin/tools/crawl.js",
|
386
395
|
"bin/tools/crawl.js.map",
|
@@ -719,7 +728,7 @@
|
|
719
728
|
"@types/react": "^18.0.35",
|
720
729
|
"@types/react-dom": "^18.0.11",
|
721
730
|
"@types/yauzl": "^2.10.0",
|
722
|
-
"concurrently": "^
|
731
|
+
"concurrently": "^8.0.1",
|
723
732
|
"copyfiles": "^2.4.1",
|
724
733
|
"eslint-plugin-storybook": "^0.6.7",
|
725
734
|
"husky": "^4.3.8",
|
@@ -733,7 +742,7 @@
|
|
733
742
|
"storybook-dark-mode": "^1.1.2",
|
734
743
|
"ts-node": "^10.9.1",
|
735
744
|
"tsc-alias": "^1.8.3",
|
736
|
-
"typescript": "^
|
745
|
+
"typescript": "^4.9.1-beta",
|
737
746
|
"vitest": "^0.29.8",
|
738
747
|
"zod-to-json-schema": "^3.20.4"
|
739
748
|
},
|
@@ -4,7 +4,7 @@ import type { ExtendKcContext } from "./getKcContextFromWindow";
|
|
4
4
|
import { getKcContextFromWindow } from "./getKcContextFromWindow";
|
5
5
|
import { pathJoin } from "keycloakify/bin/tools/pathJoin";
|
6
6
|
import { pathBasename } from "keycloakify/tools/pathBasename";
|
7
|
-
import {
|
7
|
+
import { resourcesCommonDirPathRelativeToPublicDir } from "keycloakify/bin/mockTestingResourcesPath";
|
8
8
|
import { symToStr } from "tsafe/symToStr";
|
9
9
|
import { kcContextMocks, kcContextCommonMock } from "keycloakify/account/kcContext/kcContextMocks";
|
10
10
|
import { id } from "tsafe/id";
|
@@ -30,13 +30,7 @@ export function createGetKcContext<KcContextExtension extends { pageId: string }
|
|
30
30
|
if (mockPageId !== undefined && realKcContext === undefined) {
|
31
31
|
//TODO maybe trow if no mock fo custom page
|
32
32
|
|
33
|
-
console.log(
|
34
|
-
[
|
35
|
-
`%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`,
|
36
|
-
`If assets are missing make sure you have built your Keycloak theme at least once.`
|
37
|
-
].join(" "),
|
38
|
-
"background: red; color: yellow; font-size: medium"
|
39
|
-
);
|
33
|
+
console.log(`%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, "background: red; color: yellow; font-size: medium");
|
40
34
|
|
41
35
|
const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId);
|
42
36
|
|
@@ -100,7 +94,7 @@ export function createGetKcContext<KcContextExtension extends { pageId: string }
|
|
100
94
|
{
|
101
95
|
const { url } = realKcContext;
|
102
96
|
|
103
|
-
url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(
|
97
|
+
url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(resourcesCommonDirPathRelativeToPublicDir));
|
104
98
|
}
|
105
99
|
|
106
100
|
return { "kcContext": realKcContext as any };
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import "minimal-polyfills/Object.fromEntries";
|
2
|
-
import {
|
2
|
+
import { resourcesCommonDirPathRelativeToPublicDir, resourcesDirPathRelativeToPublicDir } from "keycloakify/bin/mockTestingResourcesPath";
|
3
3
|
import { pathJoin } from "keycloakify/bin/tools/pathJoin";
|
4
4
|
import { id } from "tsafe/id";
|
5
5
|
import type { KcContext } from "./KcContext";
|
@@ -9,8 +9,8 @@ const PUBLIC_URL = process.env["PUBLIC_URL"] ?? "/";
|
|
9
9
|
export const kcContextCommonMock: KcContext.Common = {
|
10
10
|
"keycloakifyVersion": "0.0.0",
|
11
11
|
"url": {
|
12
|
-
"resourcesPath": pathJoin(PUBLIC_URL,
|
13
|
-
"resourcesCommonPath": pathJoin(PUBLIC_URL,
|
12
|
+
"resourcesPath": pathJoin(PUBLIC_URL, resourcesDirPathRelativeToPublicDir),
|
13
|
+
"resourcesCommonPath": pathJoin(PUBLIC_URL, resourcesCommonDirPathRelativeToPublicDir),
|
14
14
|
"resourceUrl": "#",
|
15
15
|
"accountUrl": "#",
|
16
16
|
"applicationsUrl": "#",
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
import { downloadKeycloakStaticResources } from "./keycloakify/generateTheme/downloadKeycloakStaticResources";
|
4
|
+
import { join as pathJoin, relative as pathRelative } from "path";
|
5
|
+
import { basenameOfKeycloakDirInPublicDir } from "./mockTestingResourcesPath";
|
6
|
+
import { readBuildOptions } from "./keycloakify/BuildOptions";
|
7
|
+
import { themeTypes } from "./keycloakify/generateFtl";
|
8
|
+
import * as fs from "fs";
|
9
|
+
|
10
|
+
(async () => {
|
11
|
+
const projectDirPath = process.cwd();
|
12
|
+
|
13
|
+
const buildOptions = readBuildOptions({
|
14
|
+
"processArgv": process.argv.slice(2),
|
15
|
+
"projectDirPath": process.cwd()
|
16
|
+
});
|
17
|
+
|
18
|
+
const keycloakDirInPublicDir = pathJoin(process.env["PUBLIC_DIR_PATH"] || pathJoin(projectDirPath, "public"), basenameOfKeycloakDirInPublicDir);
|
19
|
+
|
20
|
+
if (fs.existsSync(keycloakDirInPublicDir)) {
|
21
|
+
console.log(`${pathRelative(projectDirPath, keycloakDirInPublicDir)} already exists.`);
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
for (const themeType of themeTypes) {
|
26
|
+
await downloadKeycloakStaticResources({
|
27
|
+
"isSilent": false,
|
28
|
+
"keycloakVersion": buildOptions.keycloakVersionDefaultAssets,
|
29
|
+
"themeType": themeType,
|
30
|
+
"themeDirPath": keycloakDirInPublicDir
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
fs.writeFileSync(
|
35
|
+
pathJoin(keycloakDirInPublicDir, "README.txt"),
|
36
|
+
Buffer.from(
|
37
|
+
// prettier-ignore
|
38
|
+
[
|
39
|
+
"This is just a test folder that helps develop",
|
40
|
+
"the login and register page without having to run a Keycloak container"
|
41
|
+
].join(" ")
|
42
|
+
)
|
43
|
+
);
|
44
|
+
|
45
|
+
fs.writeFileSync(pathJoin(keycloakDirInPublicDir, ".gitignore"), Buffer.from("*", "utf8"));
|
46
|
+
|
47
|
+
console.log(`${pathRelative(projectDirPath, keycloakDirInPublicDir)} directory created.`);
|
48
|
+
})();
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import { join as pathJoin } from "path";
|
3
3
|
import { downloadAndUnzip } from "./tools/downloadAndUnzip";
|
4
4
|
import { promptKeycloakVersion } from "./promptKeycloakVersion";
|
5
|
-
import { getCliOptions } from "./tools/cliOptions";
|
6
5
|
import { getLogger } from "./tools/logger";
|
7
6
|
import { readBuildOptions } from "./keycloakify/BuildOptions";
|
8
7
|
|
@@ -21,28 +20,22 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
|
|
21
20
|
}
|
22
21
|
|
23
22
|
async function main() {
|
24
|
-
const
|
25
|
-
|
23
|
+
const buildOptions = readBuildOptions({
|
24
|
+
"projectDirPath": process.cwd(),
|
25
|
+
"processArgv": process.argv.slice(2)
|
26
|
+
});
|
27
|
+
|
28
|
+
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
26
29
|
const { keycloakVersion } = await promptKeycloakVersion();
|
27
30
|
|
28
|
-
const destDirPath = pathJoin(
|
29
|
-
readBuildOptions({
|
30
|
-
"isSilent": true,
|
31
|
-
"isExternalAssetsCliParamProvided": false,
|
32
|
-
"projectDirPath": process.cwd()
|
33
|
-
}).keycloakifyBuildDirPath,
|
34
|
-
"src",
|
35
|
-
"main",
|
36
|
-
"resources",
|
37
|
-
"theme"
|
38
|
-
);
|
31
|
+
const destDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme");
|
39
32
|
|
40
33
|
logger.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
|
41
34
|
|
42
35
|
await downloadBuiltinKeycloakTheme({
|
43
36
|
keycloakVersion,
|
44
37
|
destDirPath,
|
45
|
-
isSilent
|
38
|
+
"isSilent": buildOptions.isSilent
|
46
39
|
});
|
47
40
|
}
|
48
41
|
|
@@ -4,13 +4,17 @@ import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme"
|
|
4
4
|
import { join as pathJoin, relative as pathRelative } from "path";
|
5
5
|
import { transformCodebase } from "./tools/transformCodebase";
|
6
6
|
import { promptKeycloakVersion } from "./promptKeycloakVersion";
|
7
|
+
import { readBuildOptions } from "./keycloakify/BuildOptions";
|
7
8
|
import * as fs from "fs";
|
8
|
-
import { getCliOptions } from "./tools/cliOptions";
|
9
9
|
import { getLogger } from "./tools/logger";
|
10
10
|
import { getEmailThemeSrcDirPath } from "./getSrcDirPath";
|
11
11
|
|
12
12
|
export async function main() {
|
13
|
-
const { isSilent } =
|
13
|
+
const { isSilent } = readBuildOptions({
|
14
|
+
"projectDirPath": process.cwd(),
|
15
|
+
"processArgv": process.argv.slice(2)
|
16
|
+
});
|
17
|
+
|
14
18
|
const logger = getLogger({ isSilent });
|
15
19
|
|
16
20
|
const { emailThemeSrcDirPath } = getEmailThemeSrcDirPath({
|
@@ -6,6 +6,7 @@ import { symToStr } from "tsafe/symToStr";
|
|
6
6
|
import { bundlers, getParsedPackageJson, type Bundler } from "./parsedPackageJson";
|
7
7
|
import * as fs from "fs";
|
8
8
|
import { join as pathJoin, sep as pathSep } from "path";
|
9
|
+
import parseArgv from "minimist";
|
9
10
|
|
10
11
|
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
11
12
|
export type BuildOptions = BuildOptions.Standalone | BuildOptions.ExternalAssets;
|
@@ -53,8 +54,17 @@ export namespace BuildOptions {
|
|
53
54
|
}
|
54
55
|
}
|
55
56
|
|
56
|
-
export function readBuildOptions(params: { projectDirPath: string;
|
57
|
-
const { projectDirPath,
|
57
|
+
export function readBuildOptions(params: { projectDirPath: string; processArgv: string[] }): BuildOptions {
|
58
|
+
const { projectDirPath, processArgv } = params;
|
59
|
+
|
60
|
+
const { isExternalAssetsCliParamProvided, isSilentCliParamProvided } = (() => {
|
61
|
+
const argv = parseArgv(processArgv);
|
62
|
+
|
63
|
+
return {
|
64
|
+
"isSilentCliParamProvided": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
65
|
+
"isExternalAssetsCliParamProvided": typeof argv["external-assets"] === "boolean" ? argv["external-assets"] : false
|
66
|
+
};
|
67
|
+
})();
|
58
68
|
|
59
69
|
const parsedPackageJson = getParsedPackageJson({ projectDirPath });
|
60
70
|
|
@@ -143,7 +153,7 @@ export function readBuildOptions(params: { projectDirPath: string; isExternalAss
|
|
143
153
|
"extraLoginPages": [...(extraPages ?? []), ...(extraLoginPages ?? [])],
|
144
154
|
extraAccountPages,
|
145
155
|
extraThemeProperties,
|
146
|
-
isSilent,
|
156
|
+
"isSilent": isSilentCliParamProvided,
|
147
157
|
"keycloakVersionDefaultAssets": keycloakVersionDefaultAssets ?? "11.0.3",
|
148
158
|
"reactAppBuildDirPath": (() => {
|
149
159
|
let { reactAppBuildDirPath = undefined } = parsedPackageJson.keycloakify ?? {};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { transformCodebase } from "../../tools/transformCodebase";
|
2
|
+
import * as fs from "fs";
|
3
|
+
import { join as pathJoin, relative as pathRelative } from "path";
|
4
|
+
import type { ThemeType } from "../generateFtl";
|
5
|
+
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
6
|
+
import {
|
7
|
+
resourcesCommonDirPathRelativeToPublicDir,
|
8
|
+
resourcesDirPathRelativeToPublicDir,
|
9
|
+
basenameOfKeycloakDirInPublicDir
|
10
|
+
} from "../../mockTestingResourcesPath";
|
11
|
+
import * as crypto from "crypto";
|
12
|
+
|
13
|
+
export async function downloadKeycloakStaticResources(
|
14
|
+
// prettier-ignore
|
15
|
+
params: {
|
16
|
+
themeType: ThemeType;
|
17
|
+
themeDirPath: string;
|
18
|
+
isSilent: boolean;
|
19
|
+
keycloakVersion: string;
|
20
|
+
}
|
21
|
+
) {
|
22
|
+
const { themeType, isSilent, themeDirPath, keycloakVersion } = params;
|
23
|
+
|
24
|
+
const tmpDirPath = pathJoin(
|
25
|
+
themeDirPath,
|
26
|
+
"..",
|
27
|
+
`tmp_suLeKsxId_${crypto.createHash("sha256").update(`${themeType}-${keycloakVersion}`).digest("hex").slice(0, 8)}`
|
28
|
+
);
|
29
|
+
|
30
|
+
await downloadBuiltinKeycloakTheme({
|
31
|
+
keycloakVersion,
|
32
|
+
"destDirPath": tmpDirPath,
|
33
|
+
isSilent
|
34
|
+
});
|
35
|
+
|
36
|
+
transformCodebase({
|
37
|
+
"srcDirPath": pathJoin(tmpDirPath, "keycloak", themeType, "resources"),
|
38
|
+
"destDirPath": pathJoin(themeDirPath, pathRelative(basenameOfKeycloakDirInPublicDir, resourcesDirPathRelativeToPublicDir))
|
39
|
+
});
|
40
|
+
|
41
|
+
transformCodebase({
|
42
|
+
"srcDirPath": pathJoin(tmpDirPath, "keycloak", "common", "resources"),
|
43
|
+
"destDirPath": pathJoin(themeDirPath, pathRelative(basenameOfKeycloakDirInPublicDir, resourcesCommonDirPathRelativeToPublicDir))
|
44
|
+
});
|
45
|
+
|
46
|
+
fs.rmSync(tmpDirPath, { "recursive": true, "force": true });
|
47
|
+
}
|
package/src/bin/keycloakify/{generateKeycloakThemeResources.ts → generateTheme/generateTheme.ts}
RENAMED
@@ -1,14 +1,14 @@
|
|
1
|
-
import { transformCodebase } from "
|
1
|
+
import { transformCodebase } from "../../tools/transformCodebase";
|
2
2
|
import * as fs from "fs";
|
3
|
-
import { join as pathJoin
|
4
|
-
import { replaceImportsFromStaticInJsCode } from "
|
5
|
-
import { replaceImportsInCssCode } from "
|
6
|
-
import { generateFtlFilesCodeFactory, loginThemePageIds, accountThemePageIds, themeTypes, type ThemeType } from "
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
import type { BuildOptions } from "./BuildOptions";
|
3
|
+
import { join as pathJoin } from "path";
|
4
|
+
import { replaceImportsFromStaticInJsCode } from "../replacers/replaceImportsFromStaticInJsCode";
|
5
|
+
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
6
|
+
import { generateFtlFilesCodeFactory, loginThemePageIds, accountThemePageIds, themeTypes, type ThemeType } from "../generateFtl";
|
7
|
+
import { basenameOfKeycloakDirInPublicDir } from "../../mockTestingResourcesPath";
|
8
|
+
import { isInside } from "../../tools/isInside";
|
9
|
+
import type { BuildOptions } from "../BuildOptions";
|
11
10
|
import { assert } from "tsafe/assert";
|
11
|
+
import { downloadKeycloakStaticResources } from "./downloadKeycloakStaticResources";
|
12
12
|
|
13
13
|
export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.ExternalAssets;
|
14
14
|
|
@@ -21,6 +21,7 @@ export namespace BuildOptionsLike {
|
|
21
21
|
isSilent: boolean;
|
22
22
|
customUserAttributes: string[];
|
23
23
|
themeVersion: string;
|
24
|
+
keycloakVersionDefaultAssets: string;
|
24
25
|
};
|
25
26
|
|
26
27
|
export type Standalone = Common & {
|
@@ -49,15 +50,14 @@ export namespace BuildOptionsLike {
|
|
49
50
|
|
50
51
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
51
52
|
|
52
|
-
export async function
|
53
|
+
export async function generateTheme(params: {
|
53
54
|
reactAppBuildDirPath: string;
|
54
55
|
keycloakThemeBuildingDirPath: string;
|
55
56
|
emailThemeSrcDirPath: string | undefined;
|
56
|
-
keycloakVersion: string;
|
57
57
|
buildOptions: BuildOptionsLike;
|
58
58
|
keycloakifyVersion: string;
|
59
59
|
}): Promise<{ doBundlesEmailTemplate: boolean }> {
|
60
|
-
const { reactAppBuildDirPath, keycloakThemeBuildingDirPath, emailThemeSrcDirPath,
|
60
|
+
const { reactAppBuildDirPath, keycloakThemeBuildingDirPath, emailThemeSrcDirPath, buildOptions, keycloakifyVersion } = params;
|
61
61
|
|
62
62
|
const getThemeDirPath = (themeType: ThemeType | "email") =>
|
63
63
|
pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", buildOptions.themeName, themeType);
|
@@ -84,7 +84,7 @@ export async function generateKeycloakThemeResources(params: {
|
|
84
84
|
if (
|
85
85
|
buildOptions.isStandalone &&
|
86
86
|
isInside({
|
87
|
-
"dirPath": pathJoin(reactAppBuildDirPath,
|
87
|
+
"dirPath": pathJoin(reactAppBuildDirPath, basenameOfKeycloakDirInPublicDir),
|
88
88
|
filePath
|
89
89
|
})
|
90
90
|
) {
|
@@ -172,48 +172,12 @@ export async function generateKeycloakThemeResources(params: {
|
|
172
172
|
fs.writeFileSync(pathJoin(themeDirPath, pageId), Buffer.from(ftlCode, "utf8"));
|
173
173
|
});
|
174
174
|
|
175
|
-
{
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
isSilent: buildOptions.isSilent
|
182
|
-
});
|
183
|
-
|
184
|
-
const themeResourcesDirPath = pathJoin(themeDirPath, "resources");
|
185
|
-
|
186
|
-
transformCodebase({
|
187
|
-
"srcDirPath": pathJoin(tmpDirPath, "keycloak", themeType, "resources"),
|
188
|
-
"destDirPath": themeResourcesDirPath
|
189
|
-
});
|
190
|
-
|
191
|
-
const reactAppPublicDirPath = pathJoin(reactAppBuildDirPath, "..", "public");
|
192
|
-
|
193
|
-
transformCodebase({
|
194
|
-
"srcDirPath": pathJoin(tmpDirPath, "keycloak", "common", "resources"),
|
195
|
-
"destDirPath": pathJoin(themeResourcesDirPath, pathBasename(mockTestingResourcesCommonPath))
|
196
|
-
});
|
197
|
-
|
198
|
-
transformCodebase({
|
199
|
-
"srcDirPath": themeResourcesDirPath,
|
200
|
-
"destDirPath": pathJoin(reactAppPublicDirPath, mockTestingResourcesPath)
|
201
|
-
});
|
202
|
-
|
203
|
-
const keycloakResourcesWithinPublicDirPath = pathJoin(reactAppPublicDirPath, mockTestingSubDirOfPublicDirBasename);
|
204
|
-
|
205
|
-
fs.writeFileSync(
|
206
|
-
pathJoin(keycloakResourcesWithinPublicDirPath, "README.txt"),
|
207
|
-
Buffer.from(
|
208
|
-
["This is just a test folder that helps develop", "the login and register page without having to run a Keycloak container"].join(
|
209
|
-
" "
|
210
|
-
)
|
211
|
-
)
|
212
|
-
);
|
213
|
-
|
214
|
-
fs.writeFileSync(pathJoin(keycloakResourcesWithinPublicDirPath, ".gitignore"), Buffer.from("*", "utf8"));
|
215
|
-
fs.rmSync(tmpDirPath, { recursive: true, force: true });
|
216
|
-
}
|
175
|
+
await downloadKeycloakStaticResources({
|
176
|
+
"isSilent": buildOptions.isSilent,
|
177
|
+
"keycloakVersion": buildOptions.keycloakVersionDefaultAssets,
|
178
|
+
themeDirPath,
|
179
|
+
themeType
|
180
|
+
});
|
217
181
|
|
218
182
|
fs.writeFileSync(
|
219
183
|
pathJoin(themeDirPath, "theme.properties"),
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./generateTheme";
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { generateTheme } from "./generateTheme";
|
2
2
|
import { generateJavaStackFiles } from "./generateJavaStackFiles";
|
3
3
|
import { join as pathJoin, relative as pathRelative, basename as pathBasename, sep as pathSep } from "path";
|
4
4
|
import * as child_process from "child_process";
|
@@ -6,7 +6,6 @@ import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTe
|
|
6
6
|
import * as fs from "fs";
|
7
7
|
import { readBuildOptions } from "./BuildOptions";
|
8
8
|
import { getLogger } from "../tools/logger";
|
9
|
-
import { getCliOptions } from "../tools/cliOptions";
|
10
9
|
import jar from "../tools/jar";
|
11
10
|
import { assert } from "tsafe/assert";
|
12
11
|
import { Equals } from "tsafe";
|
@@ -14,19 +13,17 @@ import { getEmailThemeSrcDirPath } from "../getSrcDirPath";
|
|
14
13
|
import { getProjectRoot } from "../tools/getProjectRoot";
|
15
14
|
|
16
15
|
export async function main() {
|
17
|
-
const { isSilent, hasExternalAssets } = getCliOptions(process.argv.slice(2));
|
18
|
-
const logger = getLogger({ isSilent });
|
19
|
-
logger.log("🔏 Building the keycloak theme...⌚");
|
20
|
-
|
21
16
|
const projectDirPath = process.cwd();
|
22
17
|
|
23
18
|
const buildOptions = readBuildOptions({
|
24
19
|
projectDirPath,
|
25
|
-
"
|
26
|
-
"isSilent": isSilent
|
20
|
+
"processArgv": process.argv.slice(2)
|
27
21
|
});
|
28
22
|
|
29
|
-
const
|
23
|
+
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
24
|
+
logger.log("🔏 Building the keycloak theme...⌚");
|
25
|
+
|
26
|
+
const { doBundlesEmailTemplate } = await generateTheme({
|
30
27
|
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
31
28
|
"emailThemeSrcDirPath": (() => {
|
32
29
|
const { emailThemeSrcDirPath } = getEmailThemeSrcDirPath({ projectDirPath });
|
@@ -39,7 +36,6 @@ export async function main() {
|
|
39
36
|
})(),
|
40
37
|
"reactAppBuildDirPath": buildOptions.reactAppBuildDirPath,
|
41
38
|
buildOptions,
|
42
|
-
"keycloakVersion": buildOptions.keycloakVersionDefaultAssets,
|
43
39
|
"keycloakifyVersion": (() => {
|
44
40
|
const version = JSON.parse(fs.readFileSync(pathJoin(getProjectRoot(), "package.json")).toString("utf8"))["version"];
|
45
41
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { pathJoin } from "./tools/pathJoin";
|
2
2
|
|
3
|
-
export const
|
4
|
-
export const
|
5
|
-
export const
|
3
|
+
export const basenameOfKeycloakDirInPublicDir = "keycloak-resources";
|
4
|
+
export const resourcesDirPathRelativeToPublicDir = pathJoin(basenameOfKeycloakDirInPublicDir, "resources");
|
5
|
+
export const resourcesCommonDirPathRelativeToPublicDir = pathJoin(basenameOfKeycloakDirInPublicDir, "resources_common");
|
@@ -15,7 +15,7 @@ export function usePrepareTemplate(params: {
|
|
15
15
|
htmlClassName: string | undefined;
|
16
16
|
bodyClassName: string | undefined;
|
17
17
|
}) {
|
18
|
-
const { doFetchDefaultThemeResources, stylesCommon, styles, url, scripts, htmlClassName, bodyClassName } = params;
|
18
|
+
const { doFetchDefaultThemeResources, stylesCommon = [], styles = [], url, scripts = [], htmlClassName, bodyClassName } = params;
|
19
19
|
|
20
20
|
const [isReady, setReady] = useReducer(() => true, !doFetchDefaultThemeResources);
|
21
21
|
|
@@ -26,36 +26,49 @@ export function usePrepareTemplate(params: {
|
|
26
26
|
|
27
27
|
let isUnmounted = false;
|
28
28
|
|
29
|
-
|
29
|
+
const removeArray: (() => void)[] = [];
|
30
|
+
|
31
|
+
(async () => {
|
32
|
+
const prLoadedArray: Promise<void>[] = [];
|
33
|
+
|
30
34
|
[
|
31
|
-
...
|
32
|
-
...
|
35
|
+
...stylesCommon.map(relativePath => pathJoin(url.resourcesCommonPath, relativePath)),
|
36
|
+
...styles.map(relativePath => pathJoin(url.resourcesPath, relativePath))
|
33
37
|
]
|
34
38
|
.reverse()
|
35
|
-
.
|
36
|
-
headInsert({
|
39
|
+
.forEach(href => {
|
40
|
+
const { prLoaded, remove } = headInsert({
|
37
41
|
"type": "css",
|
38
|
-
|
39
|
-
|
40
|
-
})
|
41
|
-
|
42
|
-
|
42
|
+
"position": "prepend",
|
43
|
+
href
|
44
|
+
});
|
45
|
+
|
46
|
+
removeArray.push(remove);
|
47
|
+
|
48
|
+
prLoadedArray.push(prLoaded);
|
49
|
+
});
|
50
|
+
|
51
|
+
await Promise.all(prLoadedArray);
|
52
|
+
|
43
53
|
if (isUnmounted) {
|
44
54
|
return;
|
45
55
|
}
|
46
56
|
|
47
57
|
setReady();
|
48
|
-
});
|
58
|
+
})();
|
49
59
|
|
50
|
-
|
51
|
-
headInsert({
|
60
|
+
scripts.forEach(relativePath => {
|
61
|
+
const { remove } = headInsert({
|
52
62
|
"type": "javascript",
|
53
63
|
"src": pathJoin(url.resourcesPath, relativePath)
|
54
|
-
})
|
55
|
-
|
64
|
+
});
|
65
|
+
|
66
|
+
removeArray.push(remove);
|
67
|
+
});
|
56
68
|
|
57
69
|
return () => {
|
58
70
|
isUnmounted = true;
|
71
|
+
removeArray.forEach(remove => remove());
|
59
72
|
};
|
60
73
|
}, []);
|
61
74
|
|
@@ -9,7 +9,7 @@ import type { ExtendKcContext } from "./getKcContextFromWindow";
|
|
9
9
|
import { getKcContextFromWindow } from "./getKcContextFromWindow";
|
10
10
|
import { pathJoin } from "keycloakify/bin/tools/pathJoin";
|
11
11
|
import { pathBasename } from "keycloakify/tools/pathBasename";
|
12
|
-
import {
|
12
|
+
import { resourcesCommonDirPathRelativeToPublicDir } from "keycloakify/bin/mockTestingResourcesPath";
|
13
13
|
import { symToStr } from "tsafe/symToStr";
|
14
14
|
import { loginThemePageIds } from "keycloakify/bin/keycloakify/generateFtl/pageId";
|
15
15
|
|
@@ -33,13 +33,7 @@ export function createGetKcContext<KcContextExtension extends { pageId: string }
|
|
33
33
|
if (mockPageId !== undefined && realKcContext === undefined) {
|
34
34
|
//TODO maybe trow if no mock fo custom page
|
35
35
|
|
36
|
-
console.log(
|
37
|
-
[
|
38
|
-
`%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`,
|
39
|
-
`If assets are missing make sure you have built your Keycloak theme at least once.`
|
40
|
-
].join(" "),
|
41
|
-
"background: red; color: yellow; font-size: medium"
|
42
|
-
);
|
36
|
+
console.log(`%cKeycloakify: ${symToStr({ mockPageId })} set to ${mockPageId}.`, "background: red; color: yellow; font-size: medium");
|
43
37
|
|
44
38
|
const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId);
|
45
39
|
|
@@ -158,7 +152,7 @@ export function createGetKcContext<KcContextExtension extends { pageId: string }
|
|
158
152
|
{
|
159
153
|
const { url } = realKcContext;
|
160
154
|
|
161
|
-
url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(
|
155
|
+
url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(resourcesCommonDirPathRelativeToPublicDir));
|
162
156
|
}
|
163
157
|
|
164
158
|
return { "kcContext": realKcContext as any };
|