keycloakify 10.0.0-rc.16 → 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.
- package/bin/main.js +10804 -940
- package/bin/shared/constants.d.ts +1 -0
- package/bin/shared/constants.js +2 -1
- package/bin/shared/constants.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/download-keycloak-default-theme.ts +5 -1
- package/src/bin/keycloakify/buildJars/buildJar.ts +88 -39
- package/src/bin/keycloakify/keycloakify.ts +8 -2
- package/src/bin/shared/buildOptions.ts +4 -1
- package/src/bin/shared/constants.ts +2 -0
- package/src/bin/shared/metaInfKeycloakThemes.ts +3 -3
- package/src/bin/start-keycloak.ts +81 -8
- package/src/bin/tools/getNpmWorkspaceRootDirPath.ts +35 -2
- package/vite-plugin/index.js +51 -3
@@ -10,6 +10,7 @@ export declare const vitePluginSubScriptEnvNames: {
|
|
10
10
|
readonly runPostBuildScript: "KEYCLOAKIFY_RUN_POST_BUILD_SCRIPT";
|
11
11
|
readonly resolveViteConfig: "KEYCLOAKIFY_RESOLVE_VITE_CONFIG";
|
12
12
|
};
|
13
|
+
export declare const skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
|
13
14
|
export declare const loginThemePageIds: readonly ["login.ftl", "login-username.ftl", "login-password.ftl", "webauthn-authenticate.ftl", "webauthn-register.ftl", "register.ftl", "info.ftl", "error.ftl", "login-reset-password.ftl", "login-verify-email.ftl", "terms.ftl", "login-oauth2-device-verify-user-code.ftl", "login-oauth-grant.ftl", "login-otp.ftl", "login-update-profile.ftl", "login-update-password.ftl", "login-idp-link-confirm.ftl", "login-idp-link-email.ftl", "login-page-expired.ftl", "login-config-totp.ftl", "logout-confirm.ftl", "idp-review-user-profile.ftl", "update-email.ftl", "select-authenticator.ftl", "saml-post-form.ftl", "delete-credential.ftl", "code.ftl", "delete-account-confirm.ftl", "frontchannel-logout.ftl", "login-recovery-authn-code-config.ftl", "login-recovery-authn-code-input.ftl", "login-reset-otp.ftl", "login-x509-info.ftl", "webauthn-error.ftl"];
|
14
15
|
export declare const accountThemePageIds: readonly ["password.ftl", "account.ftl", "sessions.ftl", "totp.ftl", "applications.ftl", "log.ftl", "federatedIdentity.ftl"];
|
15
16
|
export type LoginThemePageId = (typeof loginThemePageIds)[number];
|
package/bin/shared/constants.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.accountThemePageIds = exports.loginThemePageIds = exports.vitePluginSubScriptEnvNames = exports.accountV1ThemeName = exports.themeTypes = exports.basenameOfTheKeycloakifyResourcesDir = exports.lastKeycloakVersionWithAccountV1 = exports.resources_common = exports.keycloak_resources = exports.nameOfTheGlobal = void 0;
|
3
|
+
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;
|
4
4
|
exports.nameOfTheGlobal = "kcContext";
|
5
5
|
exports.keycloak_resources = "keycloak-resources";
|
6
6
|
exports.resources_common = "resources-common";
|
@@ -12,6 +12,7 @@ exports.vitePluginSubScriptEnvNames = {
|
|
12
12
|
"runPostBuildScript": "KEYCLOAKIFY_RUN_POST_BUILD_SCRIPT",
|
13
13
|
"resolveViteConfig": "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
|
14
14
|
};
|
15
|
+
exports.skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
|
15
16
|
exports.loginThemePageIds = [
|
16
17
|
"login.ftl",
|
17
18
|
"login-username.ftl",
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/bin/shared/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,WAAW,CAAC;AAC9B,QAAA,kBAAkB,GAAG,oBAAoB,CAAC;AAC1C,QAAA,gBAAgB,GAAG,kBAAkB,CAAC;AACtC,QAAA,gCAAgC,GAAG,QAAQ,CAAC;AAC5C,QAAA,oCAAoC,GAAG,OAAO,CAAC;AAE/C,QAAA,UAAU,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAC;AAC3C,QAAA,kBAAkB,GAAG,YAAY,CAAC;AAIlC,QAAA,2BAA2B,GAAG;IACvC,oBAAoB,EAAE,mCAAmC;IACzD,mBAAmB,EAAE,iCAAiC;CAChD,CAAC;AAEE,QAAA,iBAAiB,GAAG;IAC7B,WAAW;IACX,oBAAoB;IACpB,oBAAoB;IACpB,2BAA2B;IAC3B,uBAAuB;IACvB,cAAc;IACd,UAAU;IACV,WAAW;IACX,0BAA0B;IAC1B,wBAAwB;IACxB,WAAW;IACX,0CAA0C;IAC1C,uBAAuB;IACvB,eAAe;IACf,0BAA0B;IAC1B,2BAA2B;IAC3B,4BAA4B;IAC5B,0BAA0B;IAC1B,wBAAwB;IACxB,uBAAuB;IACvB,oBAAoB;IACpB,6BAA6B;IAC7B,kBAAkB;IAClB,0BAA0B;IAC1B,oBAAoB;IACpB,uBAAuB;IACvB,UAAU;IACV,4BAA4B;IAC5B,yBAAyB;IACzB,sCAAsC;IACtC,qCAAqC;IACrC,qBAAqB;IACrB,qBAAqB;IACrB,oBAAoB;CACd,CAAC;AAEE,QAAA,mBAAmB,GAAG;IAC/B,cAAc;IACd,aAAa;IACb,cAAc;IACd,UAAU;IACV,kBAAkB;IAClB,SAAS;IACT,uBAAuB;CACjB,CAAC"}
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/bin/shared/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,WAAW,CAAC;AAC9B,QAAA,kBAAkB,GAAG,oBAAoB,CAAC;AAC1C,QAAA,gBAAgB,GAAG,kBAAkB,CAAC;AACtC,QAAA,gCAAgC,GAAG,QAAQ,CAAC;AAC5C,QAAA,oCAAoC,GAAG,OAAO,CAAC;AAE/C,QAAA,UAAU,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAC;AAC3C,QAAA,kBAAkB,GAAG,YAAY,CAAC;AAIlC,QAAA,2BAA2B,GAAG;IACvC,oBAAoB,EAAE,mCAAmC;IACzD,mBAAmB,EAAE,iCAAiC;CAChD,CAAC;AAEE,QAAA,oBAAoB,GAAG,4BAA4B,CAAC;AAEpD,QAAA,iBAAiB,GAAG;IAC7B,WAAW;IACX,oBAAoB;IACpB,oBAAoB;IACpB,2BAA2B;IAC3B,uBAAuB;IACvB,cAAc;IACd,UAAU;IACV,WAAW;IACX,0BAA0B;IAC1B,wBAAwB;IACxB,WAAW;IACX,0CAA0C;IAC1C,uBAAuB;IACvB,eAAe;IACf,0BAA0B;IAC1B,2BAA2B;IAC3B,4BAA4B;IAC5B,0BAA0B;IAC1B,wBAAwB;IACxB,uBAAuB;IACvB,oBAAoB;IACpB,6BAA6B;IAC7B,kBAAkB;IAClB,0BAA0B;IAC1B,oBAAoB;IACpB,uBAAuB;IACvB,UAAU;IACV,4BAA4B;IAC5B,yBAAyB;IACzB,sCAAsC;IACtC,qCAAqC;IACrC,qBAAqB;IACrB,qBAAqB;IACrB,oBAAoB;CACd,CAAC;AAEE,QAAA,mBAAmB,GAAG;IAC/B,cAAc;IACd,aAAa;IACb,cAAc;IACd,UAAU;IACV,kBAAkB;IAClB,SAAS;IACT,uBAAuB;CACjB,CAAC"}
|
package/package.json
CHANGED
@@ -24,7 +24,11 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
24
24
|
const destDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme");
|
25
25
|
|
26
26
|
console.log(
|
27
|
-
|
27
|
+
[
|
28
|
+
`Downloading builtins theme of Keycloak ${keycloakVersion} here:`,
|
29
|
+
`- ${chalk.bold(`.${pathSep}${pathJoin(pathRelative(process.cwd(), destDirPath), "base")}`)}`,
|
30
|
+
`- ${chalk.bold(`.${pathSep}${pathJoin(pathRelative(process.cwd(), destDirPath), "keycloak")}`)}`
|
31
|
+
].join("\n")
|
28
32
|
);
|
29
33
|
|
30
34
|
await downloadKeycloakDefaultTheme({
|
@@ -10,7 +10,8 @@ import { readFileSync } from "fs";
|
|
10
10
|
import { isInside } from "../../tools/isInside";
|
11
11
|
import child_process from "child_process";
|
12
12
|
import { rmSync } from "../../tools/fs.rmSync";
|
13
|
-
import {
|
13
|
+
import { getMetaInfKeycloakThemesJsonFilePath } from "../../shared/metaInfKeycloakThemes";
|
14
|
+
import type { Param0 } from "tsafe";
|
14
15
|
|
15
16
|
export type BuildOptionsLike = BuildOptionsLike_generatePom & {
|
16
17
|
keycloakifyBuildDirPath: string;
|
@@ -35,50 +36,98 @@ export async function buildJar(params: {
|
|
35
36
|
rmSync(keycloakifyBuildTmpDirPath, { "recursive": true, "force": true });
|
36
37
|
|
37
38
|
{
|
38
|
-
const
|
39
|
+
const metaInfKeycloakThemesJsonRelativePath = getMetaInfKeycloakThemesJsonFilePath({ "keycloakifyBuildDirPath": "" });
|
39
40
|
|
40
|
-
const
|
41
|
-
...buildOptions.themeNames
|
42
|
-
|
41
|
+
const { transformCodebase_common } = (() => {
|
42
|
+
const includingAccountV1ThemeNames = [...buildOptions.themeNames, accountV1ThemeName];
|
43
|
+
|
44
|
+
const transformCodebase_common: Param0<typeof transformCodebase>["transformSourceCode"] = ({ fileRelativePath, sourceCode }) => {
|
45
|
+
if (metaInfKeycloakThemesJsonRelativePath === fileRelativePath) {
|
46
|
+
return { "modifiedSourceCode": sourceCode };
|
47
|
+
}
|
48
|
+
|
49
|
+
for (const themeName of includingAccountV1ThemeNames) {
|
50
|
+
if (isInside({ "dirPath": pathJoin("src", "main", "resources", "theme", themeName), "filePath": fileRelativePath })) {
|
51
|
+
return { "modifiedSourceCode": sourceCode };
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
return undefined;
|
56
|
+
};
|
57
|
+
|
58
|
+
return { transformCodebase_common };
|
59
|
+
})();
|
60
|
+
|
61
|
+
const { transformCodebase_patchForUsingBuiltinAccountV1 } = (() => {
|
62
|
+
if (keycloakAccountV1Version !== null) {
|
63
|
+
return { "transformCodebase_patchForUsingBuiltinAccountV1": undefined };
|
64
|
+
}
|
65
|
+
|
66
|
+
const themePropertiesFileRelativePathSet = new Set(
|
67
|
+
...buildOptions.themeNames.map(themeName => pathJoin("src", "main", "resources", "theme", themeName, "account", "theme.properties"))
|
68
|
+
);
|
69
|
+
|
70
|
+
const accountV1RelativeDirPath = pathJoin("src", "main", "resources", "theme", accountV1ThemeName);
|
71
|
+
|
72
|
+
const transformCodebase_patchForUsingBuiltinAccountV1: Param0<typeof transformCodebase>["transformSourceCode"] = ({
|
73
|
+
fileRelativePath,
|
74
|
+
sourceCode
|
75
|
+
}) => {
|
76
|
+
if (isInside({ "dirPath": accountV1RelativeDirPath, "filePath": fileRelativePath })) {
|
77
|
+
return undefined;
|
78
|
+
}
|
79
|
+
|
80
|
+
if (fileRelativePath === metaInfKeycloakThemesJsonRelativePath) {
|
81
|
+
const keycloakThemesJsonParsed = JSON.parse(sourceCode.toString("utf8")) as {
|
82
|
+
themes: { name: string; types: string[] }[];
|
83
|
+
};
|
43
84
|
|
44
|
-
|
85
|
+
keycloakThemesJsonParsed.themes = keycloakThemesJsonParsed.themes.filter(({ name }) => name !== accountV1ThemeName);
|
86
|
+
|
87
|
+
return { "modifiedSourceCode": Buffer.from(JSON.stringify(keycloakThemesJsonParsed, null, 2), "utf8") };
|
88
|
+
}
|
89
|
+
|
90
|
+
if (themePropertiesFileRelativePathSet.has(fileRelativePath)) {
|
91
|
+
const modifiedSourceCode = Buffer.from(
|
92
|
+
sourceCode.toString("utf8").replace(`parent=${accountV1ThemeName}`, "parent=keycloak"),
|
93
|
+
"utf8"
|
94
|
+
);
|
95
|
+
|
96
|
+
// assert modifiedSourceCode !== sourceCode
|
97
|
+
assert(Buffer.compare(modifiedSourceCode, sourceCode) !== 0);
|
98
|
+
|
99
|
+
return { modifiedSourceCode };
|
100
|
+
}
|
101
|
+
|
102
|
+
return { "modifiedSourceCode": sourceCode };
|
103
|
+
};
|
104
|
+
|
105
|
+
return { transformCodebase_patchForUsingBuiltinAccountV1 };
|
106
|
+
})();
|
45
107
|
|
46
108
|
transformCodebase({
|
47
109
|
"srcDirPath": buildOptions.keycloakifyBuildDirPath,
|
48
110
|
"destDirPath": keycloakifyBuildTmpDirPath,
|
49
|
-
"transformSourceCode":
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
}
|
70
|
-
|
71
|
-
if (themePropertiesFilePathSet.has(fileRelativePath)) {
|
72
|
-
return {
|
73
|
-
"modifiedSourceCode": Buffer.from(
|
74
|
-
sourceCode.toString("utf8").replace(`parent=${accountV1ThemeName}`, "parent=keycloak"),
|
75
|
-
"utf8"
|
76
|
-
)
|
77
|
-
};
|
78
|
-
}
|
79
|
-
|
80
|
-
return { "modifiedSourceCode": sourceCode };
|
81
|
-
}
|
111
|
+
"transformSourceCode": params => {
|
112
|
+
const resultCommon = transformCodebase_common(params);
|
113
|
+
|
114
|
+
if (resultCommon === undefined) {
|
115
|
+
return undefined;
|
116
|
+
}
|
117
|
+
|
118
|
+
if (transformCodebase_patchForUsingBuiltinAccountV1 === undefined) {
|
119
|
+
return resultCommon;
|
120
|
+
}
|
121
|
+
|
122
|
+
const { modifiedSourceCode, newFileName } = resultCommon;
|
123
|
+
|
124
|
+
assert(newFileName === undefined);
|
125
|
+
|
126
|
+
return transformCodebase_patchForUsingBuiltinAccountV1?.({
|
127
|
+
...params,
|
128
|
+
"sourceCode": modifiedSourceCode
|
129
|
+
});
|
130
|
+
}
|
82
131
|
});
|
83
132
|
}
|
84
133
|
|
@@ -3,7 +3,7 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path
|
|
3
3
|
import * as child_process from "child_process";
|
4
4
|
import * as fs from "fs";
|
5
5
|
import { readBuildOptions } from "../shared/buildOptions";
|
6
|
-
import { vitePluginSubScriptEnvNames } from "../shared/constants";
|
6
|
+
import { vitePluginSubScriptEnvNames, skipBuildJarsEnvName } from "../shared/constants";
|
7
7
|
import { buildJars } from "./buildJars";
|
8
8
|
import type { CliCommandOptions } from "../main";
|
9
9
|
import chalk from "chalk";
|
@@ -76,7 +76,13 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
76
76
|
});
|
77
77
|
}
|
78
78
|
|
79
|
-
|
79
|
+
build_jars: {
|
80
|
+
if (process.env[skipBuildJarsEnvName]) {
|
81
|
+
break build_jars;
|
82
|
+
}
|
83
|
+
|
84
|
+
await buildJars({ buildOptions });
|
85
|
+
}
|
80
86
|
|
81
87
|
console.log(chalk.green(`✓ built in ${((Date.now() - startTime) / 1000).toFixed(2)}s`));
|
82
88
|
}
|
@@ -163,7 +163,10 @@ export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions
|
|
163
163
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
164
164
|
})();
|
165
165
|
|
166
|
-
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({
|
166
|
+
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({
|
167
|
+
reactAppRootDirPath,
|
168
|
+
"dependencyExpected": "keycloakify"
|
169
|
+
});
|
167
170
|
|
168
171
|
return {
|
169
172
|
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
@@ -14,6 +14,8 @@ export const vitePluginSubScriptEnvNames = {
|
|
14
14
|
"resolveViteConfig": "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
|
15
15
|
} as const;
|
16
16
|
|
17
|
+
export const skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
|
18
|
+
|
17
19
|
export const loginThemePageIds = [
|
18
20
|
"login.ftl",
|
19
21
|
"login-username.ftl",
|
@@ -6,7 +6,7 @@ export type MetaInfKeycloakTheme = {
|
|
6
6
|
themes: { name: string; types: (ThemeType | "email")[] }[];
|
7
7
|
};
|
8
8
|
|
9
|
-
export function
|
9
|
+
export function getMetaInfKeycloakThemesJsonFilePath(params: { keycloakifyBuildDirPath: string }) {
|
10
10
|
const { keycloakifyBuildDirPath } = params;
|
11
11
|
|
12
12
|
return pathJoin(keycloakifyBuildDirPath, "src", "main", "resources", "META-INF", "keycloak-themes.json");
|
@@ -15,13 +15,13 @@ export function getMetaInfKeycloakThemesJsonPath(params: { keycloakifyBuildDirPa
|
|
15
15
|
export function readMetaInfKeycloakThemes(params: { keycloakifyBuildDirPath: string }): MetaInfKeycloakTheme {
|
16
16
|
const { keycloakifyBuildDirPath } = params;
|
17
17
|
|
18
|
-
return JSON.parse(fs.readFileSync(
|
18
|
+
return JSON.parse(fs.readFileSync(getMetaInfKeycloakThemesJsonFilePath({ keycloakifyBuildDirPath })).toString("utf8")) as MetaInfKeycloakTheme;
|
19
19
|
}
|
20
20
|
|
21
21
|
export function writeMetaInfKeycloakThemes(params: { keycloakifyBuildDirPath: string; metaInfKeycloakThemes: MetaInfKeycloakTheme }) {
|
22
22
|
const { keycloakifyBuildDirPath, metaInfKeycloakThemes } = params;
|
23
23
|
|
24
|
-
const metaInfKeycloakThemesJsonPath =
|
24
|
+
const metaInfKeycloakThemesJsonPath = getMetaInfKeycloakThemesJsonFilePath({ keycloakifyBuildDirPath });
|
25
25
|
|
26
26
|
{
|
27
27
|
const dirPath = pathDirname(metaInfKeycloakThemesJsonPath);
|
@@ -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
|
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
|
-
|
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
|
|
package/vite-plugin/index.js
CHANGED
@@ -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)({
|
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",
|
@@ -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 };
|